diff --git a/.gitignore b/.gitignore index b312630..cf2aea2e 100644 --- a/.gitignore +++ b/.gitignore
@@ -62,23 +62,7 @@ /ash/ash_unittests_run.xml /base/base_unittests_run.xml /breakpad/src/ -/build/android/bin -/build/Debug -/build/Debug_x64 -/build/goma -/build/gomacc.lock -/build/ipch/ -/build/Release -/build/Release_x64 -/build/win_toolchain.json -/build/util/LASTCHANGE* -/build/util/support -/build/x64/ -/build/linux/bin/eu-strip -/build/linux/debian_*-sysroot/ -/build/linux/ubuntu_*-sysroot/ -/build/ios_files -/build/mac_files +# See build/.gitignore for entries covering src/build. /buildtools # The Chrome OS build creates a /c symlink due to http://crbug.com/54866. /c @@ -289,202 +273,7 @@ /tools/luci-go/linux64/isolate /tools/luci-go/mac64/isolate /tools/luci-go/win64/isolate.exe -/third_party/__START__ -/third_party/accessibility-developer-tools/ -/third_party/accessibility_test_framework/lib/*.jar -/third_party/adobe/flash/binaries -/third_party/adobe/flash/symbols -/third_party/amd/ -/third_party/android_protobuf/src -/third_party/android_support_test_runner/lib/*.aar -/third_party/android_support_test_runner/lib/*.jar -/third_party/android_tools/ -/third_party/android_tools_internal/ -/third_party/android_webview_glue/src -/third_party/angle -/third_party/angle_dx11 -/third_party/apache-portable-runtime/src -/third_party/apache_velocity/lib/*.jar -/third_party/apache-win32/bin/*.exe -/third_party/apache-win32/bin/*.dll -/third_party/apache-win32/bin/iconv/*.so -/third_party/apache-win32/modules/*.so -/third_party/apache-win32/modules/*.dll -/third_party/asan -/third_party/bidichecker -/third_party/bison -/third_party/boringssl/src -/third_party/bouncycastle/lib/*.jar -/third_party/byte_buddy/lib/*.jar -/third_party/cacheinvalidation/cacheinvalidation_unittests_run.xml -/third_party/cardboard-java/src -/third_party/catapult -/third_party/ced/src -/third_party/chromeos_login_manager -/third_party/chromeos_text_input -/third_party/chromite -/third_party/cld_2/src -/third_party/cld_3/src -/third_party/colorama/src -/third_party/cros -/third_party/cros_system_api -/third_party/custom_tabs_client/src -/third_party/cygwin -/third_party/deqp/src -/third_party/directxsdk -/third_party/dom_distiller_js/dist -/third_party/drmemory/drmemory-windows-sfx.exe -/third_party/drmemory/unpacked -/third_party/elfutils/src -/third_party/errorprone/lib -/third_party/espresso/lib/*.jar -/third_party/eyesfree/src -/third_party/ffmpeg -/third_party/findbugs -/third_party/flac -/third_party/flatbuffers/src -/third_party/fontconfig/src -/third_party/freetype-android/src -/third_party/freetype2/src -/third_party/gestures/gestures -/third_party/gles2_conform -/third_party/glslang/src -/third_party/glslang-angle/src -/third_party/gnu_binutils/ -/third_party/google_appengine_cloudstorage -/third_party/google_toolbox_for_mac/src -/third_party/googlemac -/third_party/gvr-android-sdk/common_library.aar -/third_party/gvr-android-sdk/libgvr_shim_static_arm.a -/third_party/gvr-android-sdk/libgvr_shim_static_arm64.a -/third_party/gvr-android-sdk/src -/third_party/gperf -/third_party/guava/lib/*.jar -/third_party/hamcrest/lib/*.jar -/third_party/hunspell_dictionaries -/third_party/icu -/third_party/icu4j/lib/*.jar -/third_party/intellij/lib/*.jar -/third_party/inspector_protocol -/third_party/javax_inject/lib/*.jar -/third_party/jsoncpp/source -/third_party/jsr-305/src -/third_party/junit/src -/third_party/khronos_glcts -/third_party/leakcanary/src -/third_party/leveldatabase/src -/third_party/leveldb -/third_party/libc++-static/libc++.a -/third_party/libaddressinput/src -/third_party/libdrm/src -/third_party/libevdev/src -/third_party/libexif/sources -/third_party/libFuzzer/src -/third_party/libjingle/source -/third_party/libjpeg_turbo -/third_party/liblouis/src -/third_party/libphonenumber/dist -/third_party/libsrtp -/third_party/libupnp -/third_party/libvpx/source/libvpx -/third_party/libwebm/source -/third_party/libyuv -/third_party/lighttpd -/third_party/llvm -/third_party/llvm-allocated-type -/third_party/llvm-bootstrap -/third_party/llvm-build -/third_party/lss -/third_party/mesa/src -/third_party/mingw-w64 -/third_party/minigbm/src -/third_party/mkl -/third_party/mocha -/third_party/mockito/src -/third_party/nacl_sdk_binaries/ -/third_party/netty-tcnative/src -/third_party/netty4/src -/third_party/node/linux -/third_party/node/mac -/third_party/node/node_modules -/third_party/node/*.tar.gz -/third_party/node/win -/third_party/nss -/third_party/objenesis/lib/*.jar -/third_party/omaha/src/omaha -/third_party/openmax_dl/ -/third_party/openh264/src -/third_party/ow2_asm/lib/*.jar -/third_party/pdfsqueeze -/third_party/pdfium -/third_party/pefile -/third_party/perl -/third_party/ppapi -/third_party/psyco_win32 -/third_party/pthreads-win32 -/third_party/py_trace_event/src -/third_party/pyelftools -/third_party/pyftpdlib/src -/third_party/pylib -/third_party/pymox/src -/third_party/python_24 -/third_party/python_26 -/third_party/pywebsocket/src -/third_party/pywebsocket/src -/third_party/re2/src -/third_party/requests/src -/third_party/retrolambda/*.jar -/third_party/robolectric/lib/*.jar -/third_party/robolectric/robolectric -/third_party/scan-build/src -/third_party/scons-2.0.1 -/third_party/sfntly/src -/third_party/shaderc/src -/third_party/skia -/third_party/smhasher/src -/third_party/snappy/src -/third_party/spirv-headers/src -/third_party/SPIRV-Tools/src -/third_party/spirv-tools-angle/src -/third_party/sqlite4java/lib/**/*.dll -/third_party/sqlite4java/lib/**/*.jar -/third_party/sqlite4java/lib/**/*.jnilib -/third_party/sqlite4java/lib/**/*.so -/third_party/swiftshader/ -/third_party/syzygy -/third_party/syzygy/binaries -/third_party/tsan/ -/third_party/ub-uiautomator/lib -/third_party/usb_ids -/third_party/usrsctp/usrsctplib -/third_party/v8-i18n -/third_party/valgrind -/third_party/vulkan-validation-layers/src -/third_party/visualmetrics -/third_party/wayland/src -/third_party/wayland-protocols/src -/third_party/wds/src -/third_party/webdriver/pylib -/third_party/webdriver/python/selenium -/third_party/webgl -/third_party/webgl/src -/third_party/webpagereplay/ -/third_party/webrtc -/third_party/widevine/cdm/chromeos -/third_party/widevine/cdm/linux -/third_party/widevine/cdm/mac -/third_party/widevine/cdm/win -/third_party/widevine/scripts -/third_party/widevine/test/license_server -/third_party/win_toolchain/.timestamps -/third_party/win_toolchain/files -/third_party/wix -/third_party/xdg-utils -/third_party/xulrunner-sdk -/third_party/yasm/binaries -/third_party/yasm/generate_files.xml -/third_party/yasm/source/patched-yasm -/third_party/yasm/yasm.xml +# See third_party/.gitignore for entries covering src/third_party. /tools/.bisect-builds-cache.json /tools/distcc /tools/gn/bin/linux
diff --git a/DEPS b/DEPS index 7a082e7..8ec3049 100644 --- a/DEPS +++ b/DEPS
@@ -40,7 +40,7 @@ # 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': '8a0bfc5201f14c994fe8062ecf1ca34a172de9d3', + 'skia_revision': 'ca70b59d8c83dda0a31915ab824995cf49c830a1', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. @@ -52,7 +52,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. - 'angle_revision': 'cde4f024e2d00a49c170a82a50aef31e17068d1e', + 'angle_revision': '0a17c92c292706bb818d8fed16f64a8708cddd0b', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling build tools # and whatever else without interference from each other. @@ -64,7 +64,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. - 'pdfium_revision': '60fd9fc63744419a760201af596515d411b7e194', + 'pdfium_revision': 'e3f237740fd8bea50b4a6f37f56455dfa0328546', # 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. @@ -88,7 +88,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling NaCl # and whatever else without interference from each other. - 'nacl_revision': 'ee10b35a44f89833c0048a2b242f1de734108411', + 'nacl_revision': '81142aef3ec03dbc554e1cb0e22e4243e8aa69af', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling freetype-android # 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': 'bbfc356b5b6ec0200b27805acef8486938522968', + 'catapult_revision': '42d9cffaa797712c58d7b5fb59820f0aa3e82138', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -154,7 +154,7 @@ Var('chromium_git') + '/external/colorama.git' + '@' + '799604a1041e9b3bc5d2789ecbd7e8db2e18e6b8', 'src/third_party/icu': - Var('chromium_git') + '/chromium/deps/icu.git' + '@' + '9cd2828740572ba6f694b9365236a8356fd06147', + Var('chromium_git') + '/chromium/deps/icu.git' + '@' + '450be73c9ee8ae29d43d4fdc82febb2a5f62bfb5', 'src/third_party/hunspell_dictionaries': Var('chromium_git') + '/chromium/deps/hunspell_dictionaries.git' + '@' + 'dc6e7c25bf47cbfb466e0701fd2728b4a12e79d5', @@ -202,7 +202,7 @@ Var('chromium_git') + '/external/selenium/py.git' + '@' + '5fd78261a75fe08d27ca4835fb6c5ce4b42275bd', 'src/third_party/libvpx/source/libvpx': - Var('chromium_git') + '/webm/libvpx.git' + '@' + '91f87e75135cc9722ee72daf5154424f628a906e', + Var('chromium_git') + '/webm/libvpx.git' + '@' + '4d4231352c8cefdae2e76b7bad4286ec21747c89', 'src/third_party/ffmpeg': Var('chromium_git') + '/chromium/third_party/ffmpeg.git' + '@' + '3f3ad2ea90df08f5907bd997e1ce22e1c19ce215', @@ -769,6 +769,28 @@ '-l', 'third_party/objenesis' ], }, + # Downloads the VR Services and Daydream Home APKs used for VR testing on + # Android. + { + 'name': 'vr_services_apks', + 'pattern': '.', + 'action': ['python', + 'src/build/android/update_deps/update_third_party_deps.py', + 'download', + '-b', 'chrome-vr-test-apks/vr_services', + '-l', 'third_party/gvr-android-sdk/test-apks/vr_services' + ], + }, + { + 'name': 'daydream_home_apks', + 'pattern': '.', + 'action': ['python', + 'src/build/android/update_deps/update_third_party_deps.py', + 'download', + '-b', 'chrome-vr-test-apks/daydream_home', + '-l', 'third_party/gvr-android-sdk/test-apks/daydream_home' + ], + }, { # Downloads the current stable linux sysroot to build/linux/ if needed. # This sysroot updates at about the same rate that the chrome build deps
diff --git a/PRESUBMIT.py b/PRESUBMIT.py index 6334c05..e56d4b3 100644 --- a/PRESUBMIT.py +++ b/PRESUBMIT.py
@@ -431,7 +431,7 @@ def _CheckDCHECK_IS_ONHasBraces(input_api, output_api): - """Checks to make sure DCHECK_IS_ON() does not skip the braces.""" + """Checks to make sure DCHECK_IS_ON() does not skip the parentheses.""" errors = [] pattern = input_api.re.compile(r'DCHECK_IS_ON(?!\(\))', input_api.re.MULTILINE) @@ -442,7 +442,7 @@ if input_api.re.search(pattern, line): errors.append(output_api.PresubmitError( ('%s:%d: Use of DCHECK_IS_ON() must be written as "#if ' + - 'DCHECK_IS_ON()", not forgetting the braces.') + 'DCHECK_IS_ON()", not forgetting the parentheses.') % (f.LocalPath(), lnum))) return errors
diff --git a/WATCHLISTS b/WATCHLISTS index 3a0cdb3a0..6712d66 100644 --- a/WATCHLISTS +++ b/WATCHLISTS
@@ -813,6 +813,13 @@ '|components/payments'\ '|third_party/WebKit/LayoutTests/payments/'\ '|third_party/WebKit/Source/modules/payments'\ + '|ios/web/payments/'\ + '|ios/web/public/payments/'\ + '|ios/chrome/browser/payments/' + }, + 'payments_ios': { + 'filepath': 'ios/web/payments/'\ + '|ios/web/public/payments/'\ '|ios/chrome/browser/payments/' }, 'pepper_api': { @@ -2024,7 +2031,9 @@ 'vabr+watchlistpasswordmanager@chromium.org'], 'payments': ['rouslan+payments@chromium.org', 'sebsg+paymentswatch@chromium.org', - 'gogerald+paymentswatch@chromium.org'], + 'gogerald+paymentswatch@chromium.org', + 'mahmadi+paymentswatch@chromium.org'], + 'payments_ios': ['mahmadi+paymentsioswatch@chromium.org'], 'pepper_api': ['binji+watch@chromium.org', 'bradnelson+warch@chromium.org', 'ihf+watch@chromium.org',
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientFullScreenTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientFullScreenTest.java index 7ea0f81d5..36a08c2 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientFullScreenTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientFullScreenTest.java
@@ -307,7 +307,7 @@ // Enter fullscreen and verify that the power save blocker is // still there. - DOMUtils.clickNode(this, mContentViewCore, CUSTOM_FULLSCREEN_CONTROL_ID); + DOMUtils.clickNode(mContentViewCore, CUSTOM_FULLSCREEN_CONTROL_ID); mContentsClient.waitForCustomViewShown(); assertKeepScreenOnActive(mTestContainerView, true); @@ -354,7 +354,7 @@ // (containing the fullscreen <video>) so we just rely on that fact here. TouchCommon.singleClickView(mContentsClient.getCustomView()); } else { - DOMUtils.clickNode(this, mContentViewCore, CUSTOM_PLAY_CONTROL_ID); + DOMUtils.clickNode(mContentViewCore, CUSTOM_PLAY_CONTROL_ID); } } @@ -472,7 +472,7 @@ private void loadTestPageAndClickFullscreen(String videoTestUrl) throws Exception { loadTestPage(videoTestUrl); - DOMUtils.clickNode(this, mContentViewCore, CUSTOM_FULLSCREEN_CONTROL_ID); + DOMUtils.clickNode(mContentViewCore, CUSTOM_FULLSCREEN_CONTROL_ID); } private void loadTestPage(String videoTestUrl) throws Exception {
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientGetVideoLoadingProgressViewTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientGetVideoLoadingProgressViewTest.java index fe74a78a..95d4d81 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientGetVideoLoadingProgressViewTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientGetVideoLoadingProgressViewTest.java
@@ -71,9 +71,9 @@ enableJavaScriptOnUiThread(awContents); loadUrlSync(awContents, contentsClient.getOnPageFinishedHelper(), VIDEO_TEST_URL); Thread.sleep(5 * 1000); - DOMUtils.clickNode(this, awContents.getContentViewCore(), CUSTOM_FULLSCREEN_CONTROL_ID); + DOMUtils.clickNode(awContents.getContentViewCore(), CUSTOM_FULLSCREEN_CONTROL_ID); Thread.sleep(1 * 1000); - DOMUtils.clickNode(this, awContents.getContentViewCore(), CUSTOM_PLAY_CONTROL_ID); + DOMUtils.clickNode(awContents.getContentViewCore(), CUSTOM_PLAY_CONTROL_ID); waitForViewAttached(); } }
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientShouldOverrideUrlLoadingTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientShouldOverrideUrlLoadingTest.java index 5ec6e32d6..95b1b9d 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientShouldOverrideUrlLoadingTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientShouldOverrideUrlLoadingTest.java
@@ -722,7 +722,7 @@ assertEquals(indirectLoadCallCount, mShouldOverrideUrlLoadingHelper.getCallCount()); // Simulate touch, hasUserGesture must be true only on the first call. - DOMUtils.clickNode(this, mAwContents.getContentViewCore(), "link"); + DOMUtils.clickNode(mAwContents.getContentViewCore(), "link"); mShouldOverrideUrlLoadingHelper.waitForCallback(indirectLoadCallCount, 1); assertEquals(redirectUrl, @@ -941,7 +941,7 @@ assertNull(getActivity().getLastSentIntent()); // Clicking on a link should create an intent. - DOMUtils.clickNode(this, mAwContents.getContentViewCore(), "link"); + DOMUtils.clickNode(mAwContents.getContentViewCore(), "link"); pollUiThread(new Callable<Boolean>() { @Override public Boolean call() { @@ -999,7 +999,7 @@ final String findContentJs = setupForContentClickTest(pageContent, true); // Clicking on the content should create an intent. - DOMUtils.clickNodeByJs(this, mAwContents.getContentViewCore(), findContentJs); + DOMUtils.clickNodeByJs(mAwContents.getContentViewCore(), findContentJs); pollUiThread(new Callable<Boolean>() { @Override public Boolean call() { @@ -1041,7 +1041,7 @@ final String findContentJs = setupForContentClickTest(pageContent, inMainFrame); int callCount = mShouldOverrideUrlLoadingHelper.getCallCount(); - DOMUtils.clickNodeByJs(this, mAwContents.getContentViewCore(), findContentJs); + DOMUtils.clickNodeByJs(mAwContents.getContentViewCore(), findContentJs); mShouldOverrideUrlLoadingHelper.waitForCallback(callCount); assertEquals(intentContent, mShouldOverrideUrlLoadingHelper.getShouldOverrideUrlLoadingUrl());
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwSettingsTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwSettingsTest.java index d1f8f36..cff6568 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/AwSettingsTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwSettingsTest.java
@@ -2111,7 +2111,7 @@ int count = callback.getCallCount(); loadDataSync(awContents, contentClient.getOnPageFinishedHelper(), pageHtml, "text/html", false); - DOMUtils.clickNode(this, testContainer.getContentViewCore(), "play"); + DOMUtils.clickNode(testContainer.getContentViewCore(), "play"); callback.waitForCallback(count, 1); assertEquals(0, webServer.getRequestCount(httpPath));
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/PlatformMediaCodecTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/PlatformMediaCodecTest.java index 2ddcd72..f499e073 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/PlatformMediaCodecTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/PlatformMediaCodecTest.java
@@ -37,7 +37,7 @@ public void testCanPlayPlatformMediaCodecs() throws Throwable { loadUrlSync(mTestContainerView.getAwContents(), mContentsClient.getOnPageFinishedHelper(), "file:///android_asset/platform-media-codec-test.html"); - DOMUtils.clickNode(this, mContentViewCore, "playButton"); + DOMUtils.clickNode(mContentViewCore, "playButton"); DOMUtils.waitForMediaPlay(getWebContentsOnUiThread(), "videoTag"); }
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/PopupWindowTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/PopupWindowTest.java index da92ce0..e9f0386c 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/PopupWindowTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/PopupWindowTest.java
@@ -122,7 +122,7 @@ enableJavaScriptOnUiThread(popupContents); // Now long press on some texts and see if the text handles show up. - DOMUtils.longPressNode(this, popupContents.getContentViewCore(), "plain_text"); + DOMUtils.longPressNode(popupContents.getContentViewCore(), "plain_text"); assertWaitForSelectActionBarStatus(true, popupContents.getContentViewCore()); assertTrue(runTestOnUiThreadAndGetResult(new Callable<Boolean>() { @Override
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/VisualStateTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/VisualStateTest.java index d1dbf00..37fae153 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/VisualStateTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/VisualStateTest.java
@@ -310,8 +310,7 @@ awContentsClient.getOnPageFinishedHelper(), WAIT_FOR_JS_TEST_URL); assertTrue(readyToUpdateColor.await(AwTestBase.WAIT_TIMEOUT_MS, TimeUnit.MILLISECONDS)); - DOMUtils.clickNode( - VisualStateTest.this, contentViewCore, UPDATE_COLOR_CONTROL_ID); + DOMUtils.clickNode(contentViewCore, UPDATE_COLOR_CONTROL_ID); assertTrue(jsObserver.waitForEvent(WAIT_TIMEOUT_MS)); runTestOnUiThread(new Runnable() { @@ -382,7 +381,7 @@ assertTrue(readyToEnterFullscreenSignal.await( AwTestBase.WAIT_TIMEOUT_MS, TimeUnit.MILLISECONDS)); - DOMUtils.clickNode(VisualStateTest.this, contentViewCore, ENTER_FULLSCREEN_CONTROL_ID); + DOMUtils.clickNode(contentViewCore, ENTER_FULLSCREEN_CONTROL_ID); assertTrue(jsObserver.waitForEvent(WAIT_TIMEOUT_MS)); runTestOnUiThread(new Runnable() {
diff --git a/ash/ash_chromeos_strings.grdp b/ash/ash_chromeos_strings.grdp index 2af26f2..bb1267c9 100644 --- a/ash/ash_chromeos_strings.grdp +++ b/ash/ash_chromeos_strings.grdp
@@ -505,6 +505,9 @@ <message name="IDS_ASH_STATUS_TRAY_NETWORK_WIFI" desc="The label used in the tray popup to separate Wi-Fi networks."> Wi-Fi </message> + <message name="IDS_ASH_STATUS_TRAY_NETWORK_TETHER" desc="The label used in the tray popup to separate Instant Tethering networks."> + Instant Tethering + </message> <message name="IDS_ASH_STATUS_TRAY_ADD_CONNECTION" desc="Title for control to add a new network connection." > Add connection </message>
diff --git a/ash/common/system/chromeos/network/network_info.h b/ash/common/system/chromeos/network/network_info.h index 758ac857..c321a837 100644 --- a/ash/common/system/chromeos/network/network_info.h +++ b/ash/common/system/chromeos/network/network_info.h
@@ -19,7 +19,7 @@ // Includes information necessary about a network for displaying the appropriate // UI to the user. struct NetworkInfo { - enum class Type { UNKNOWN, WIFI, CELLULAR }; + enum class Type { UNKNOWN, WIFI, TETHER, CELLULAR }; NetworkInfo(); NetworkInfo(const std::string& guid);
diff --git a/ash/common/system/chromeos/network/network_list_md.cc b/ash/common/system/chromeos/network/network_list_md.cc index dd12aa1..140071e 100644 --- a/ash/common/system/chromeos/network/network_list_md.cc +++ b/ash/common/system/chromeos/network/network_list_md.cc
@@ -182,6 +182,24 @@ DISALLOW_COPY_AND_ASSIGN(CellularHeaderRowView); }; +class TetherHeaderRowView : public NetworkListViewMd::SectionHeaderRowView { + public: + TetherHeaderRowView() + : SectionHeaderRowView(IDS_ASH_STATUS_TRAY_NETWORK_TETHER) {} + + ~TetherHeaderRowView() override {} + + const char* GetClassName() const override { return "TetherHeaderRowView"; } + + protected: + void OnToggleToggled(bool is_on) override { + // TODO (hansberry): Persist toggle to settings/preferences. + } + + private: + DISALLOW_COPY_AND_ASSIGN(TetherHeaderRowView); +}; + class WifiHeaderRowView : public NetworkListViewMd::SectionHeaderRowView { public: explicit WifiHeaderRowView(NetworkListDelegate* network_list_delegate) @@ -263,8 +281,10 @@ no_wifi_networks_view_(nullptr), no_cellular_networks_view_(nullptr), cellular_header_view_(nullptr), + tether_header_view_(nullptr), wifi_header_view_(nullptr), cellular_separator_view_(nullptr), + tether_separator_view_(nullptr), wifi_separator_view_(nullptr) { CHECK(delegate_); } @@ -275,10 +295,20 @@ void NetworkListViewMd::Update() { CHECK(container()); - NetworkStateHandler::NetworkStateList network_list; + NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler(); + + NetworkStateHandler::NetworkStateList network_list; handler->GetVisibleNetworkList(&network_list); UpdateNetworks(network_list); + + NetworkStateHandler::NetworkStateList tether_network_list; + handler->GetTetherNetworkList(0 /* no limit */, &tether_network_list); + for (const auto& tether_network : tether_network_list) { + network_list_.push_back( + base::MakeUnique<NetworkInfo>(tether_network->guid())); + } + UpdateNetworkIcons(); OrderNetworks(); UpdateNetworkListInternal(); @@ -376,6 +406,8 @@ info->type = NetworkInfo::Type::WIFI; else if (network->Matches(NetworkTypePattern::Cellular())) info->type = NetworkInfo::Type::CELLULAR; + else if (network->Matches(NetworkTypePattern::Tether())) + info->type = NetworkInfo::Type::TETHER; if (prohibited_by_policy) { info->tooltip = l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_NETWORK_PROHIBITED); @@ -464,6 +496,25 @@ new_guids->insert(new_cellular_guids->begin(), new_cellular_guids->end()); } + // TODO (hansberry): Audit existing usage of NonVirtual and consider changing + // it to include Tether. See crbug.com/693647. + if (handler->IsTechnologyAvailable(NetworkTypePattern::Tether())) { + index = UpdateSectionHeaderRow( + NetworkTypePattern::Tether(), + handler->IsTechnologyEnabled(NetworkTypePattern::Tether()), index, + &tether_header_view_, &tether_separator_view_); + + // TODO (hansberry): Should a message similar to + // IDS_ASH_STATUS_TRAY_NO_CELLULAR_NETWORKS be shown if Tether technology + // is enabled but no networks are around? + + // Add Tether networks. + std::unique_ptr<std::set<std::string>> new_tether_guids = + UpdateNetworkChildren(NetworkInfo::Type::TETHER, index); + index += new_tether_guids->size(); + new_guids->insert(new_tether_guids->begin(), new_tether_guids->end()); + } + if (pattern.MatchesPattern(NetworkTypePattern::WiFi())) { index = UpdateSectionHeaderRow( NetworkTypePattern::WiFi(), @@ -570,6 +621,8 @@ if (!*view) { if (pattern.Equals(NetworkTypePattern::Cellular())) *view = new CellularHeaderRowView(); + else if (pattern.Equals(NetworkTypePattern::Tether())) + *view = new TetherHeaderRowView(); else if (pattern.Equals(NetworkTypePattern::WiFi())) *view = new WifiHeaderRowView(delegate_); else
diff --git a/ash/common/system/chromeos/network/network_list_md.h b/ash/common/system/chromeos/network/network_list_md.h index 9180381..fea2365 100644 --- a/ash/common/system/chromeos/network/network_list_md.h +++ b/ash/common/system/chromeos/network/network_list_md.h
@@ -108,8 +108,10 @@ views::Label* no_wifi_networks_view_; views::Label* no_cellular_networks_view_; SectionHeaderRowView* cellular_header_view_; + SectionHeaderRowView* tether_header_view_; SectionHeaderRowView* wifi_header_view_; views::Separator* cellular_separator_view_; + views::Separator* tether_separator_view_; views::Separator* wifi_separator_view_; // An owned list of network info.
diff --git a/ash/common/system/chromeos/virtual_keyboard/virtual_keyboard_tray.cc b/ash/common/system/chromeos/virtual_keyboard/virtual_keyboard_tray.cc index 74040a8..5393679 100644 --- a/ash/common/system/chromeos/virtual_keyboard/virtual_keyboard_tray.cc +++ b/ash/common/system/chromeos/virtual_keyboard/virtual_keyboard_tray.cc
@@ -7,19 +7,14 @@ #include <algorithm> #include "ash/common/keyboard/keyboard_ui.h" -#include "ash/common/material_design/material_design_controller.h" #include "ash/common/shelf/shelf_constants.h" #include "ash/common/shelf/wm_shelf.h" -#include "ash/common/shelf/wm_shelf_util.h" #include "ash/common/system/tray/tray_constants.h" -#include "ash/common/system/tray/tray_utils.h" #include "ash/common/wm_shell.h" #include "ash/common/wm_window.h" -#include "ash/resources/grit/ash_resources.h" #include "ash/resources/vector_icons/vector_icons.h" #include "grit/ash_strings.h" #include "ui/base/l10n/l10n_util.h" -#include "ui/base/resource/resource_bundle.h" #include "ui/display/display.h" #include "ui/events/event.h" #include "ui/gfx/image/image_skia.h" @@ -33,22 +28,13 @@ : TrayBackgroundView(wm_shelf), icon_(new views::ImageView), wm_shelf_(wm_shelf) { - if (MaterialDesignController::IsShelfMaterial()) { - SetInkDropMode(InkDropMode::ON); - SetContentsBackground(false); - gfx::ImageSkia image_md = - CreateVectorIcon(kShelfKeyboardIcon, kShelfIconColor); - icon_->SetImage(image_md); - } else { - SetContentsBackground(true); - gfx::ImageSkia* image_non_md = - ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( - IDR_AURA_UBER_TRAY_VIRTUAL_KEYBOARD); - icon_->SetImage(image_non_md); - } + SetInkDropMode(InkDropMode::ON); + SetContentsBackground(false); + icon_->SetImage(gfx::CreateVectorIcon(kShelfKeyboardIcon, kShelfIconColor)); SetIconBorderForShelfAlignment(); tray_container()->AddChildView(icon_); + // The Shell may not exist in some unit tests. if (WmShell::HasInstance()) WmShell::Get()->keyboard_ui()->AddObserver(this); @@ -115,21 +101,9 @@ void VirtualKeyboardTray::OnKeyboardClosed() {} void VirtualKeyboardTray::SetIconBorderForShelfAlignment() { - // Every time shelf alignment is updated, StatusAreaWidgetDelegate resets the - // border to a non-null border. So, we need to remove it. - if (!ash::MaterialDesignController::IsShelfMaterial()) - tray_container()->SetBorder(views::NullBorder()); const gfx::ImageSkia& image = icon_->GetImage(); - const int size = GetTrayConstant(VIRTUAL_KEYBOARD_BUTTON_SIZE); - const int vertical_padding = (size - image.height()) / 2; - int horizontal_padding = (size - image.width()) / 2; - if (!ash::MaterialDesignController::IsShelfMaterial() && - IsHorizontalAlignment(shelf_alignment())) { - // Square up the padding if horizontally aligned. Avoid extra padding when - // vertically aligned as the button would violate the width constraint on - // the shelf. - horizontal_padding += std::max(0, vertical_padding - horizontal_padding); - } + const int vertical_padding = (kTrayItemSize - image.height()) / 2; + const int horizontal_padding = (kTrayItemSize - image.width()) / 2; icon_->SetBorder(views::CreateEmptyBorder( gfx::Insets(vertical_padding, horizontal_padding))); }
diff --git a/ash/common/system/overview/overview_button_tray.cc b/ash/common/system/overview/overview_button_tray.cc index c65942e..8bd5f85 100644 --- a/ash/common/system/overview/overview_button_tray.cc +++ b/ash/common/system/overview/overview_button_tray.cc
@@ -4,55 +4,28 @@ #include "ash/common/system/overview/overview_button_tray.h" -#include "ash/common/material_design/material_design_controller.h" #include "ash/common/session/session_state_delegate.h" #include "ash/common/shelf/shelf_constants.h" -#include "ash/common/shelf/wm_shelf_util.h" #include "ash/common/system/tray/system_tray_delegate.h" #include "ash/common/system/tray/tray_constants.h" -#include "ash/common/system/tray/tray_utils.h" #include "ash/common/wm/maximize_mode/maximize_mode_controller.h" #include "ash/common/wm/overview/window_selector_controller.h" #include "ash/common/wm_shell.h" -#include "ash/public/cpp/shelf_types.h" -#include "ash/resources/grit/ash_resources.h" #include "ash/resources/vector_icons/vector_icons.h" #include "grit/ash_strings.h" #include "ui/base/l10n/l10n_util.h" -#include "ui/base/resource/resource_bundle.h" #include "ui/gfx/paint_vector_icon.h" #include "ui/views/border.h" #include "ui/views/controls/image_view.h" -namespace { - -// Predefined padding for the icon used in this tray. These are to be set to the -// border of the icon, depending on the current shelf_alignment() -const int kHorizontalShelfHorizontalPadding = 8; -const int kHorizontalShelfVerticalPadding = 4; -const int kVerticalShelfHorizontalPadding = 2; -const int kVerticalShelfVerticalPadding = 5; - -} // namespace - namespace ash { OverviewButtonTray::OverviewButtonTray(WmShelf* wm_shelf) - : TrayBackgroundView(wm_shelf), icon_(nullptr) { - icon_ = new views::ImageView(); - if (MaterialDesignController::IsShelfMaterial()) { - SetInkDropMode(InkDropMode::ON); - SetContentsBackground(false); - gfx::ImageSkia image_md = - CreateVectorIcon(kShelfOverviewIcon, kShelfIconColor); - icon_->SetImage(image_md); - } else { - SetContentsBackground(true); - gfx::ImageSkia* image_non_md = - ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( - IDR_AURA_UBER_TRAY_OVERVIEW_MODE); - icon_->SetImage(image_non_md); - } + : TrayBackgroundView(wm_shelf), icon_(new views::ImageView()) { + SetInkDropMode(InkDropMode::ON); + SetContentsBackground(false); + + icon_->SetImage(CreateVectorIcon(kShelfOverviewIcon, kShelfIconColor)); SetIconBorderForShelfAlignment(); tray_container()->AddChildView(icon_); @@ -123,25 +96,16 @@ } void OverviewButtonTray::SetIconBorderForShelfAlignment() { - gfx::Insets insets; - if (ash::MaterialDesignController::IsShelfMaterial()) { - // Pad button size to align with other controls in the system tray. - const gfx::ImageSkia image = icon_->GetImage(); - const int vertical_padding = (kTrayItemSize - image.height()) / 2; - const int horizontal_padding = (kTrayItemSize - image.width()) / 2; - insets = gfx::Insets(vertical_padding, horizontal_padding); - } else { - insets = IsHorizontalAlignment(shelf_alignment()) - ? gfx::Insets(kHorizontalShelfVerticalPadding, - kHorizontalShelfHorizontalPadding) - : gfx::Insets(kVerticalShelfVerticalPadding, - kVerticalShelfHorizontalPadding); - } - icon_->SetBorder(views::CreateEmptyBorder(insets)); + // Pad button size to align with other controls in the system tray. + const gfx::ImageSkia& image = icon_->GetImage(); + const int vertical_padding = (kTrayItemSize - image.height()) / 2; + const int horizontal_padding = (kTrayItemSize - image.width()) / 2; + icon_->SetBorder(views::CreateEmptyBorder( + gfx::Insets(vertical_padding, horizontal_padding))); } void OverviewButtonTray::UpdateIconVisibility() { - // The visibility of the OverviewButtonTray has diverge from + // The visibility of the OverviewButtonTray has diverged from // WindowSelectorController::CanSelect. The visibility of the button should // not change during transient times in which CanSelect is false. Such as when // a modal dialog is present.
diff --git a/ash/common/system/tray/tray_constants.cc b/ash/common/system/tray/tray_constants.cc index 6bf56323..43f6a24 100644 --- a/ash/common/system/tray/tray_constants.cc +++ b/ash/common/system/tray/tray_constants.cc
@@ -119,7 +119,6 @@ const int kTrayPopupItemLeftInset[] = {0, 4, 4}; const int kTrayPopupItemMinStartWidth[] = {46, 48, 48}; const int kTrayPopupItemMinEndWidth[] = {40, 40, 40}; - const int kVirtualKeyboardButtonSize[] = {39, kTrayItemSize, kTrayItemSize}; const int kTrayImeMenuIcon[] = {40, kTrayItemSize, kTrayItemSize}; const int kTrayImageItemPadding[] = {1, 3, 3}; @@ -147,8 +146,6 @@ return kTrayPopupItemMinStartWidth[mode]; case TRAY_POPUP_ITEM_MIN_END_WIDTH: return kTrayPopupItemMinEndWidth[mode]; - case VIRTUAL_KEYBOARD_BUTTON_SIZE: - return kVirtualKeyboardButtonSize[mode]; case TRAY_IME_MENU_ICON: return kTrayImeMenuIcon[mode]; case TRAY_IMAGE_ITEM_PADDING:
diff --git a/ash/common/system/tray/tray_constants.h b/ash/common/system/tray/tray_constants.h index 1da6f92b..e457f1df 100644 --- a/ash/common/system/tray/tray_constants.h +++ b/ash/common/system/tray/tray_constants.h
@@ -171,12 +171,6 @@ // The minimum default width for the right container of the system menu rows. TRAY_POPUP_ITEM_MIN_END_WIDTH, - // The width and height of the virtual keyboard button in the status tray - // area. For non-MD, adjustments are made to the button dimensions based on - // the shelf orientation, so this constant does not specify the true - // user-visible button bounds. - VIRTUAL_KEYBOARD_BUTTON_SIZE, - // The icon size of opt-in IME menu tray. TRAY_IME_MENU_ICON,
diff --git a/ash/common/system/tray_accessibility.cc b/ash/common/system/tray_accessibility.cc index 1c641eb..1e643544 100644 --- a/ash/common/system/tray_accessibility.cc +++ b/ash/common/system/tray_accessibility.cc
@@ -6,7 +6,6 @@ #include "ash/common/accessibility_delegate.h" #include "ash/common/accessibility_types.h" -#include "ash/common/material_design/material_design_controller.h" #include "ash/common/session/session_state_delegate.h" #include "ash/common/system/tray/hover_highlight_view.h" #include "ash/common/system/tray/system_tray.h" @@ -39,10 +38,6 @@ namespace ash { namespace { -bool UseMdMenu() { - return MaterialDesignController::IsSystemTrayMenuMaterial(); -} - enum AccessibilityState { A11Y_NONE = 0, A11Y_SPOKEN_FEEDBACK = 1 << 0, @@ -160,14 +155,8 @@ virtual_keyboard_enabled_(false), login_(login) { Reset(); - AppendAccessibilityList(); - - if (!UseMdMenu()) - AppendHelpEntries(); - CreateTitleRow(IDS_ASH_STATUS_TRAY_ACCESSIBILITY_TITLE); - Layout(); } @@ -223,36 +212,30 @@ kSystemMenuKeyboardIcon); } -void AccessibilityDetailedView::AppendHelpEntries() { - DCHECK(!UseMdMenu()); -} - HoverHighlightView* AccessibilityDetailedView::AddScrollListItem( const base::string16& text, bool highlight, bool checked, const gfx::VectorIcon& icon) { HoverHighlightView* container = new HoverHighlightView(this); - if (UseMdMenu()) { - gfx::ImageSkia image = CreateVectorIcon(icon, kMenuIconColor); - const int padding = (kMenuButtonSize - image.width()) / 2; - container->AddIconAndLabelCustomSize( - image, text, highlight, - image.width() + kMenuSeparatorVerticalPadding * 2, padding, padding); - if (checked) { - gfx::ImageSkia check_mark = CreateVectorIcon( - gfx::VectorIconId::CHECK_CIRCLE, gfx::kGoogleGreen700); - container->AddRightIcon(check_mark, check_mark.width()); - container->SetRightViewVisible(true); - container->SetAccessiblityState( - HoverHighlightView::AccessibilityState::CHECKED_CHECKBOX); - } else { - container->SetAccessiblityState( - HoverHighlightView::AccessibilityState::UNCHECKED_CHECKBOX); - } + gfx::ImageSkia image = CreateVectorIcon(icon, kMenuIconColor); + const int padding = (kMenuButtonSize - image.width()) / 2; + container->AddIconAndLabelCustomSize( + image, text, highlight, image.width() + kMenuSeparatorVerticalPadding * 2, + padding, padding); + + if (checked) { + gfx::ImageSkia check_mark = + CreateVectorIcon(gfx::VectorIconId::CHECK_CIRCLE, gfx::kGoogleGreen700); + container->AddRightIcon(check_mark, check_mark.width()); + container->SetRightViewVisible(true); + container->SetAccessiblityState( + HoverHighlightView::AccessibilityState::CHECKED_CHECKBOX); } else { - container->AddCheckableLabel(text, highlight, checked); + container->SetAccessiblityState( + HoverHighlightView::AccessibilityState::UNCHECKED_CHECKBOX); } + scroll_content()->AddChildView(container); return container; } @@ -305,18 +288,16 @@ } void AccessibilityDetailedView::CreateExtraTitleRowButtons() { - if (UseMdMenu()) { - DCHECK(!help_view_); - DCHECK(!settings_view_); + DCHECK(!help_view_); + DCHECK(!settings_view_); - tri_view()->SetContainerVisible(TriView::Container::END, true); + tri_view()->SetContainerVisible(TriView::Container::END, true); - help_view_ = CreateHelpButton(login_); - settings_view_ = CreateSettingsButton( - login_, IDS_ASH_STATUS_TRAY_ACCESSIBILITY_SETTINGS); - tri_view()->AddView(TriView::Container::END, help_view_); - tri_view()->AddView(TriView::Container::END, settings_view_); - } + help_view_ = CreateHelpButton(login_); + settings_view_ = + CreateSettingsButton(login_, IDS_ASH_STATUS_TRAY_ACCESSIBILITY_SETTINGS); + tri_view()->AddView(TriView::Container::END, help_view_); + tri_view()->AddView(TriView::Container::END, settings_view_); } void AccessibilityDetailedView::ShowSettings() {
diff --git a/ash/common/system/tray_accessibility.h b/ash/common/system/tray_accessibility.h index 1b54962..79161797 100644 --- a/ash/common/system/tray_accessibility.h +++ b/ash/common/system/tray_accessibility.h
@@ -75,11 +75,7 @@ // Add the accessibility feature list. void AppendAccessibilityList(); - // Add help entries. Only used for non-MD. - void AppendHelpEntries(); - - // Helper function to create entries in the detailed accessibility view. The - // |icon| parameter is used to create button icons for MD only. + // Helper function to create entries in the detailed accessibility view. HoverHighlightView* AddScrollListItem(const base::string16& text, bool highlight, bool checked,
diff --git a/ash/mus/non_client_frame_controller.cc b/ash/mus/non_client_frame_controller.cc index c83c4ac..12b1639f 100644 --- a/ash/mus/non_client_frame_controller.cc +++ b/ash/mus/non_client_frame_controller.cc
@@ -298,8 +298,6 @@ widget_->Init(params); did_init_native_widget_ = true; - widget_->ShowInactive(); - WmWindow* wm_window = WmWindow::Get(window_); const gfx::Insets extended_hit_region = wm_window->ShouldUseExtendedHitRegion() ? GetExtendedHitRegion()
diff --git a/ash/mus/top_level_window_factory_unittest.cc b/ash/mus/top_level_window_factory_unittest.cc index 2e016c1..2fb98002 100644 --- a/ash/mus/top_level_window_factory_unittest.cc +++ b/ash/mus/top_level_window_factory_unittest.cc
@@ -2,10 +2,22 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "ash/mus/top_level_window_factory.h" + +#include <stdint.h> + +#include <map> +#include <string> +#include <vector> + #include "ash/common/test/ash_test.h" #include "ash/common/wm_shell.h" #include "ash/common/wm_window.h" #include "ash/mus/test/wm_test_base.h" +#include "ash/mus/window_manager.h" +#include "ash/mus/window_manager_application.h" +#include "ash/test/ash_test_base.h" +#include "ash/test/ash_test_helper.h" #include "ui/aura/window.h" #include "ui/display/screen.h" @@ -46,4 +58,15 @@ GetDisplayId(window_secondary_display.get())); } +using TopLevelWindowFactoryAshTest = test::AshTestBase; + +TEST_F(TopLevelWindowFactoryAshTest, TopLevelNotShownOnCreate) { + std::map<std::string, std::vector<uint8_t>> properties; + std::unique_ptr<aura::Window> window(mus::CreateAndParentTopLevelWindow( + ash_test_helper()->window_manager_app()->window_manager(), + ui::mojom::WindowType::WINDOW, &properties)); + ASSERT_TRUE(window); + EXPECT_FALSE(window->IsVisible()); +} + } // namespace ash
diff --git a/ash/resources/ash_resources.grd b/ash/resources/ash_resources.grd index b0882400..39588dd 100644 --- a/ash/resources/ash_resources.grd +++ b/ash/resources/ash_resources.grd
@@ -86,7 +86,6 @@ <structure type="chrome_scaled_image" name="IDR_AURA_UBER_TRAY_NETWORK_NOTIFICATION_LTE" file="cros/network/notification_lte.png" /> <structure type="chrome_scaled_image" name="IDR_AURA_UBER_TRAY_MORE" file="cros/status/status_more.png" /> - <structure type="chrome_scaled_image" name="IDR_AURA_UBER_TRAY_OVERVIEW_MODE" file="cros/status/status_overview_mode.png" /> <structure type="chrome_scaled_image" name="IDR_AURA_UBER_TRAY_SCREENSHARE" file="cros/status/status_screenshare.png" /> <structure type="chrome_scaled_image" name="IDR_AURA_UBER_TRAY_SCREENSHARE_DARK" file="cros/status/status_screenshare_dark.png" /> <structure type="chrome_scaled_image" name="IDR_AURA_UBER_TRAY_SHUTDOWN" file="cros/status/status_shutdown.png" /> @@ -123,7 +122,6 @@ <structure type="chrome_scaled_image" name="IDR_AURA_UBER_TRAY_RECORDING" file="cros/status/status_recording.png" /> <structure type="chrome_scaled_image" name="IDR_AURA_UBER_TRAY_RECORDING_RED" file="cros/status/status_recording_red.png" /> <structure type="chrome_scaled_image" name="IDR_AURA_UBER_TRAY_SETTINGS" file="cros/status/status_settings.png" /> - <structure type="chrome_scaled_image" name="IDR_AURA_UBER_TRAY_VIRTUAL_KEYBOARD" file="cros/status/status_virtual_keyboard.png" /> <structure type="chrome_scaled_image" name="IDR_AURA_UBER_TRAY_WIFI_DISABLED" file="cros/network/status_wifi_disabled.png" /> <structure type="chrome_scaled_image" name="IDR_AURA_UBER_TRAY_WIFI_DISABLED_HOVER" file="cros/network/status_wifi_disabled_hover.png" /> <structure type="chrome_scaled_image" name="IDR_AURA_UBER_TRAY_WIFI_ENABLED" file="cros/network/status_wifi_enabled.png" />
diff --git a/ash/resources/default_100_percent/cros/status/status_overview_mode.png b/ash/resources/default_100_percent/cros/status/status_overview_mode.png deleted file mode 100644 index d145a94..0000000 --- a/ash/resources/default_100_percent/cros/status/status_overview_mode.png +++ /dev/null Binary files differ
diff --git a/ash/resources/default_100_percent/cros/status/status_virtual_keyboard.png b/ash/resources/default_100_percent/cros/status/status_virtual_keyboard.png deleted file mode 100644 index 5cf6839..0000000 --- a/ash/resources/default_100_percent/cros/status/status_virtual_keyboard.png +++ /dev/null Binary files differ
diff --git a/ash/resources/default_200_percent/cros/status/status_overview_mode.png b/ash/resources/default_200_percent/cros/status/status_overview_mode.png deleted file mode 100644 index f684c7e..0000000 --- a/ash/resources/default_200_percent/cros/status/status_overview_mode.png +++ /dev/null Binary files differ
diff --git a/ash/resources/default_200_percent/cros/status/status_virtual_keyboard.png b/ash/resources/default_200_percent/cros/status/status_virtual_keyboard.png deleted file mode 100644 index a882f85f..0000000 --- a/ash/resources/default_200_percent/cros/status/status_virtual_keyboard.png +++ /dev/null Binary files differ
diff --git a/ash/test/ash_test_helper.h b/ash/test/ash_test_helper.h index 64e16eb3..0f0ba1e7 100644 --- a/ash/test/ash_test_helper.h +++ b/ash/test/ash_test_helper.h
@@ -86,6 +86,11 @@ display::Display GetSecondaryDisplay(); + // Null in classic ash. + mus::WindowManagerApplication* window_manager_app() { + return window_manager_app_.get(); + } + private: // Called when running in mash to create the WindowManager. void CreateMashWindowManager();
diff --git a/base/debug/stack_trace.cc b/base/debug/stack_trace.cc index 94ff7d07..af4a6ef 100644 --- a/base/debug/stack_trace.cc +++ b/base/debug/stack_trace.cc
@@ -20,6 +20,10 @@ #include "base/threading/platform_thread.h" #endif +#if defined(OS_MACOSX) +#include <pthread.h> +#endif + #if defined(OS_LINUX) && defined(__GLIBC__) extern "C" void* __libc_stack_end; #endif @@ -42,56 +46,6 @@ constexpr size_t kStackFrameAdjustment = 0; #endif -// Returns end of the stack, or 0 if we couldn't get it. -uintptr_t GetStackEnd() { -#if defined(OS_ANDROID) - // Bionic reads proc/maps on every call to pthread_getattr_np() when called - // from the main thread. So we need to cache end of stack in that case to get - // acceptable performance. - // For all other threads pthread_getattr_np() is fast enough as it just reads - // values from its pthread_t argument. - static uintptr_t main_stack_end = 0; - - bool is_main_thread = GetCurrentProcId() == PlatformThread::CurrentId(); - if (is_main_thread && main_stack_end) { - return main_stack_end; - } - - uintptr_t stack_begin = 0; - size_t stack_size = 0; - pthread_attr_t attributes; - int error = pthread_getattr_np(pthread_self(), &attributes); - if (!error) { - error = pthread_attr_getstack( - &attributes, - reinterpret_cast<void**>(&stack_begin), - &stack_size); - pthread_attr_destroy(&attributes); - } - DCHECK(!error); - - uintptr_t stack_end = stack_begin + stack_size; - if (is_main_thread) { - main_stack_end = stack_end; - } - return stack_end; // 0 in case of error - -#elif defined(OS_LINUX) && defined(__GLIBC__) - - if (GetCurrentProcId() == PlatformThread::CurrentId()) { - // For the main thread we have a shortcut. - return reinterpret_cast<uintptr_t>(__libc_stack_end); - } - - // No easy way to get end of the stack for non-main threads, - // see crbug.com/617730. - -#endif - - // Don't know how to get end of the stack. - return 0; -} - uintptr_t GetNextStackFrame(uintptr_t fp) { return reinterpret_cast<const uintptr_t*>(fp)[0] - kStackFrameAdjustment; } @@ -192,6 +146,56 @@ } // namespace +#if HAVE_TRACE_STACK_FRAME_POINTERS +uintptr_t GetStackEnd() { +#if defined(OS_ANDROID) + // Bionic reads proc/maps on every call to pthread_getattr_np() when called + // from the main thread. So we need to cache end of stack in that case to get + // acceptable performance. + // For all other threads pthread_getattr_np() is fast enough as it just reads + // values from its pthread_t argument. + static uintptr_t main_stack_end = 0; + + bool is_main_thread = GetCurrentProcId() == PlatformThread::CurrentId(); + if (is_main_thread && main_stack_end) { + return main_stack_end; + } + + uintptr_t stack_begin = 0; + size_t stack_size = 0; + pthread_attr_t attributes; + int error = pthread_getattr_np(pthread_self(), &attributes); + if (!error) { + error = pthread_attr_getstack( + &attributes, reinterpret_cast<void**>(&stack_begin), &stack_size); + pthread_attr_destroy(&attributes); + } + DCHECK(!error); + + uintptr_t stack_end = stack_begin + stack_size; + if (is_main_thread) { + main_stack_end = stack_end; + } + return stack_end; // 0 in case of error + +#elif defined(OS_LINUX) && defined(__GLIBC__) + + if (GetCurrentProcId() == PlatformThread::CurrentId()) { + // For the main thread we have a shortcut. + return reinterpret_cast<uintptr_t>(__libc_stack_end); + } + +// No easy way to get end of the stack for non-main threads, +// see crbug.com/617730. +#elif defined(OS_MACOSX) + return reinterpret_cast<uintptr_t>(pthread_get_stackaddr_np(pthread_self())); +#endif + + // Don't know how to get end of the stack. + return 0; +} +#endif // HAVE_TRACE_STACK_FRAME_POINTERS + StackTrace::StackTrace() : StackTrace(arraysize(trace_)) {} StackTrace::StackTrace(const void* const* trace, size_t count) {
diff --git a/base/debug/stack_trace.h b/base/debug/stack_trace.h index ba1937fe..4c9b73e 100644 --- a/base/debug/stack_trace.h +++ b/base/debug/stack_trace.h
@@ -45,6 +45,11 @@ // done in official builds because it has security implications). BASE_EXPORT bool EnableInProcessStackDumping(); +// Returns end of the stack, or 0 if we couldn't get it. +#if HAVE_TRACE_STACK_FRAME_POINTERS +BASE_EXPORT uintptr_t GetStackEnd(); +#endif + // A stacktrace can be helpful in debugging. For example, you can include a // stacktrace member in a object (probably around #ifndef NDEBUG) so that you // can later see where the given object was created from.
diff --git a/base/debug/stack_trace_unittest.cc b/base/debug/stack_trace_unittest.cc index 0f1b5ac5..560dc1d 100644 --- a/base/debug/stack_trace_unittest.cc +++ b/base/debug/stack_trace_unittest.cc
@@ -303,6 +303,16 @@ ExpectStackFramePointers<kDepth>(frames, kDepth); } +#if defined(OS_ANDROID) || defined(OS_MACOSX) +#define MAYBE_StackEnd StackEnd +#else +#define MAYBE_StackEnd DISABLED_StackEnd +#endif + +TEST_F(StackTraceTest, MAYBE_StackEnd) { + EXPECT_NE(0u, GetStackEnd()); +} + #endif // HAVE_TRACE_STACK_FRAME_POINTERS } // namespace debug
diff --git a/base/files/important_file_writer.cc b/base/files/important_file_writer.cc index cc0a616..b468462 100644 --- a/base/files/important_file_writer.cc +++ b/base/files/important_file_writer.cc
@@ -103,6 +103,7 @@ File tmp_file(tmp_file_path, File::FLAG_OPEN | File::FLAG_WRITE); if (!tmp_file.IsValid()) { LogFailure(path, FAILED_OPENING, "could not open temporary file"); + DeleteFile(tmp_file_path, false); return false; }
diff --git a/base/ios/ios_util.h b/base/ios/ios_util.h index 953a502..caa594dd 100644 --- a/base/ios/ios_util.h +++ b/base/ios/ios_util.h
@@ -13,9 +13,6 @@ namespace base { namespace ios { -// Returns whether the operating system is iOS 9 or later. -BASE_EXPORT bool IsRunningOnIOS9OrLater(); - // Returns whether the operating system is iOS 10 or later. BASE_EXPORT bool IsRunningOnIOS10OrLater();
diff --git a/base/ios/ios_util.mm b/base/ios/ios_util.mm index 4b702db..196d5ef 100644 --- a/base/ios/ios_util.mm +++ b/base/ios/ios_util.mm
@@ -28,10 +28,6 @@ namespace base { namespace ios { -bool IsRunningOnIOS9OrLater() { - return IsRunningOnOrLater(9, 0, 0); -} - bool IsRunningOnIOS10OrLater() { return IsRunningOnOrLater(10, 0, 0); }
diff --git a/base/test/scoped_task_scheduler.cc b/base/test/scoped_task_scheduler.cc index 7bcd88a..61ed2c7 100644 --- a/base/test/scoped_task_scheduler.cc +++ b/base/test/scoped_task_scheduler.cc
@@ -70,6 +70,16 @@ bool RunsTasksOnCurrentThread() const; private: + // Returns the TaskRunner to which this TaskScheduler forwards tasks. It may + // be |message_loop_->task_runner()| or a reference to it saved on entry to + // RunTask(). + scoped_refptr<SingleThreadTaskRunner> MessageLoopTaskRunner() const { + if (saved_task_runner_) + return saved_task_runner_; + DCHECK(message_loop_->task_runner()); + return message_loop_->task_runner(); + } + // |message_loop_owned_| will be non-null if this TestTaskScheduler owns the // MessageLoop (wasn't provided an external one at construction). // |message_loop_| will always be set and is used by this TestTaskScheduler to @@ -77,6 +87,15 @@ std::unique_ptr<MessageLoop> message_loop_owned_; MessageLoop* message_loop_; + // A reference to |message_loop_->task_runner()| saved on entry to RunTask(). + // This is required because RunTask() overrides + // |message_loop_->task_runner()|. + // + // Note: |message_loop_->task_runner()| is accessed directly outside of + // RunTask() to guarantee that ScopedTaskScheduler always uses the latest + // TaskRunner set by external code. + scoped_refptr<SingleThreadTaskRunner> saved_task_runner_; + // Handles shutdown behaviors and sets up the environment to run a task. internal::TaskTracker task_tracker_; @@ -182,7 +201,7 @@ if (!task_tracker_.WillPostTask(task.get())) return false; internal::Task* const task_ptr = task.get(); - return message_loop_->task_runner()->PostDelayedTask( + return MessageLoopTaskRunner()->PostDelayedTask( task_ptr->posted_from, Bind(&TestTaskScheduler::RunTask, Unretained(this), Passed(&task), sequence_token), task_ptr->delay); @@ -190,10 +209,11 @@ void TestTaskScheduler::RunTask(std::unique_ptr<internal::Task> task, const SequenceToken& sequence_token) { + DCHECK(!saved_task_runner_); + saved_task_runner_ = MessageLoop::current()->task_runner(); + // Clear the MessageLoop TaskRunner to allow TaskTracker to register its own // Thread/SequencedTaskRunnerHandle as appropriate. - scoped_refptr<SingleThreadTaskRunner> saved_task_runner = - MessageLoop::current()->task_runner(); MessageLoop::current()->ClearTaskRunnerForTesting(); // Run the task. @@ -201,12 +221,16 @@ ? sequence_token : SequenceToken::Create()); + // Make sure that any task runner that was registered was also cleaned up. + DCHECK(!MessageLoop::current()->task_runner()); + // Restore the MessageLoop TaskRunner. - MessageLoop::current()->SetTaskRunner(saved_task_runner); + MessageLoop::current()->SetTaskRunner(saved_task_runner_); + saved_task_runner_ = nullptr; } bool TestTaskScheduler::RunsTasksOnCurrentThread() const { - return message_loop_->task_runner()->RunsTasksOnCurrentThread(); + return MessageLoopTaskRunner()->RunsTasksOnCurrentThread(); } TestTaskSchedulerTaskRunner::TestTaskSchedulerTaskRunner(
diff --git a/base/test/scoped_task_scheduler_unittest.cc b/base/test/scoped_task_scheduler_unittest.cc index cc0ffbb..f2037e1 100644 --- a/base/test/scoped_task_scheduler_unittest.cc +++ b/base/test/scoped_task_scheduler_unittest.cc
@@ -297,5 +297,21 @@ EXPECT_TRUE(second_task_ran); } +// Verify that a task can be posted from a task running in ScopedTaskScheduler. +TEST(ScopedTaskSchedulerTest, ReentrantTaskRunner) { + bool task_ran = false; + ScopedTaskScheduler scoped_task_scheduler; + PostTask(FROM_HERE, Bind( + [](bool* task_ran) { + PostTask( + FROM_HERE, + Bind([](bool* task_ran) { *task_ran = true; }, + Unretained(task_ran))); + }, + Unretained(&task_ran))); + RunLoop().RunUntilIdle(); + EXPECT_TRUE(task_ran); +} + } // namespace test } // namespace base
diff --git a/build/.gitignore b/build/.gitignore new file mode 100644 index 0000000..103314c --- /dev/null +++ b/build/.gitignore
@@ -0,0 +1,20 @@ +# This file is needed for projects that has this directory as a separate Git +# mirror in DEPS. Without it, a lot is wiped and re-downloaded for each sync. +/android/bin +/Debug +/Debug_x64 +/goma +/gomacc.lock +/ipch/ +/Release +/Release_x64 +/win_toolchain.json +/util/LASTCHANGE* +/util/support +/x64/ +/linux/bin/eu-strip +/linux/debian_*-sysroot/ +/linux/ubuntu_*-sysroot/ +/ios_files +/mac_files +
diff --git a/build/android/gyp/javac.py b/build/android/gyp/javac.py index df5325f..0eacb3c 100755 --- a/build/android/gyp/javac.py +++ b/build/android/gyp/javac.py
@@ -420,9 +420,12 @@ java_files = _FilterJavaFiles(java_files, options.javac_includes) - javac_cmd = ['javac'] if options.use_errorprone_path: - javac_cmd = [options.use_errorprone_path] + ERRORPRONE_OPTIONS + javac_path = options.use_errorprone_path + javac_cmd = [javac_path] + ERRORPRONE_OPTIONS + else: + javac_path = distutils.spawn.find_executable('javac') + javac_cmd = [javac_path] javac_cmd.extend(( '-g', @@ -473,8 +476,10 @@ else: classpath_inputs.append(path) - # Compute the list of paths that when changed, we need to rebuild. - input_paths = classpath_inputs + options.java_srcjars + java_files + # GN already knows of java_files, so listing them just make things worse when + # they change. + depfile_deps = [javac_path] + classpath_inputs + options.java_srcjars + input_paths = depfile_deps + java_files output_paths = [ options.jar_path, @@ -493,6 +498,7 @@ lambda changes: _OnStaleMd5(changes, options, javac_cmd, java_files, classpath_inputs), options, + depfile_deps=depfile_deps, input_paths=input_paths, input_strings=javac_cmd, output_paths=output_paths,
diff --git a/build/android/lint/suppressions.xml b/build/android/lint/suppressions.xml index 0066fe24..33882a2 100644 --- a/build/android/lint/suppressions.xml +++ b/build/android/lint/suppressions.xml
@@ -21,12 +21,14 @@ Note: PRODUCT_DIR will be substituted at run-time with actual directory path (e.g. out/Debug) --> + <!-- AllowBackup defaults to true, and causes a lint warning if not explicitly set. --> <issue id="AllowBackup"> <ignore path="AndroidManifest.xml"/> </issue> + <!-- We use asserts in Chromium. See https://chromium.googlesource.com/chromium/src/+/master/styleguide/java/java.md#Asserts --> <issue id="Assert" severity="ignore"/> - <!-- TODO(crbug.com/635567): Fix this properly. --> <issue id="BadHostnameVerifier" severity="Error"> + <!-- Safe, used in test only. --> <ignore regexp="net/test/android/javatests/src/org/chromium/net/test/util/TestWebServer.java"/> </issue> <issue id="ButtonOrder" severity="Error"> @@ -73,12 +75,6 @@ </issue> <issue id="HandlerLeak"> <ignore regexp="android_webview/glue/java/src/com/android/webview/chromium/WebViewContentsClientAdapter.java" /> - <!-- TODO(crbug.com/635567): Fix this properly. --> - <ignore regexp="chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java"/> - <!-- TODO(crbug.com/635567): Fix this properly. --> - <ignore regexp="chrome/android/java/src/org/chromium/chrome/browser/gsa/GSAServiceClient.java"/> - <!-- TODO(crbug.com/635567): Fix this properly. --> - <ignore regexp="chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java"/> <ignore regexp="chromecast/internal" /> <ignore regexp="remoting/android/java/src/org/chromium/chromoting/TapGestureDetector.java" /> </issue>
diff --git a/build/android/pylib/OWNERS b/build/android/pylib/OWNERS index dbbbba7..f008c99 100644 --- a/build/android/pylib/OWNERS +++ b/build/android/pylib/OWNERS
@@ -2,3 +2,5 @@ klundberg@chromium.org navabi@chromium.org skyostil@chromium.org + +# COMPONENT: Test>Android
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn index 3b31bd7..8f57120 100644 --- a/build/config/compiler/BUILD.gn +++ b/build/config/compiler/BUILD.gn
@@ -1602,7 +1602,12 @@ # Full symbols. config("symbols") { if (is_win) { - cflags = [ "/Zi" ] # Produce PDB file, no edit and continue. + if (use_goma) { + # Note that this requires is_win_fastlink, enforced elsewhere. + cflags = [ "/Z7" ] # Debug information in the .obj files. + } else { + cflags = [ "/Zi" ] # Produce PDB file, no edit and continue. + } if (is_win_fastlink) { # Tell VS 2015+ to create a PDB that references debug
diff --git a/build/config/compiler/compiler.gni b/build/config/compiler/compiler.gni index b07a507..787990a 100644 --- a/build/config/compiler/compiler.gni +++ b/build/config/compiler/compiler.gni
@@ -98,6 +98,8 @@ # by visual studio (repeated in every .obj file) makes linker # memory consumption and link times unsustainable (crbug.com/630074). # Clang on windows does not have this issue. + # If you use is_win_fastlink = true then you can set symbol_level = 2 when + # using goma. symbol_level = 1 } else if ((!is_nacl && !is_linux) || is_debug || is_official_build || is_chromecast) { @@ -111,6 +113,12 @@ } else { symbol_level = 0 } +} else if (symbol_level == 2) { + if (is_win) { + # See crbug.com/630074 + assert(is_win_fastlink || !use_goma, + "Goma builds that use symbol_level 2 must use is_win_fastlink.") + } } # Assert that the configuration isn't going to hit https://crbug.com/648948.
diff --git a/build/install-build-deps.sh b/build/install-build-deps.sh index 67d7adf..32db1424 100755 --- a/build/install-build-deps.sh +++ b/build/install-build-deps.sh
@@ -223,7 +223,12 @@ fi fi ;; - *) + "precise") + arm_list="libc6-dev-armhf-cross + linux-libc-dev-armhf-cross + ${GPP_ARM_PACKAGE}" + ;; + "*") arm_list="binutils-aarch64-linux-gnu libc6-dev-armhf-cross linux-libc-dev-armhf-cross
diff --git a/cc/animation/animation_host_perftest.cc b/cc/animation/animation_host_perftest.cc index a7c6e898..776a687 100644 --- a/cc/animation/animation_host_perftest.cc +++ b/cc/animation/animation_host_perftest.cc
@@ -56,7 +56,7 @@ return layer_tree_host_->host_impl()->animation_host(); } - void CreatePlayers(const int num_players) { + void CreatePlayers(int num_players) { all_players_timeline_ = AnimationTimeline::Create(AnimationIdProvider::NextTimelineId()); host()->AddAnimationTimeline(all_players_timeline_); @@ -89,7 +89,7 @@ EXPECT_TRUE(timeline_impl->GetPlayerById(i)); } - void CreateTimelines(const int num_timelines) { + void CreateTimelines(int num_timelines) { first_timeline_id_ = AnimationIdProvider::NextTimelineId(); last_timeline_id_ = first_timeline_id_;
diff --git a/cc/debug/rasterize_and_record_benchmark_impl.cc b/cc/debug/rasterize_and_record_benchmark_impl.cc index 044992c..19b72bad 100644 --- a/cc/debug/rasterize_and_record_benchmark_impl.cc +++ b/cc/debug/rasterize_and_record_benchmark_impl.cc
@@ -70,7 +70,7 @@ public: FixedInvalidationPictureLayerTilingClient( PictureLayerTilingClient* base_client, - const Region invalidation) + const Region& invalidation) : base_client_(base_client), invalidation_(invalidation) {} std::unique_ptr<Tile> CreateTile(const Tile::CreateInfo& info) override {
diff --git a/cc/input/page_scale_animation.h b/cc/input/page_scale_animation.h index 4884098..b58f50b 100644 --- a/cc/input/page_scale_animation.h +++ b/cc/input/page_scale_animation.h
@@ -20,15 +20,14 @@ // Used in the CC to pass around a scale animation that hasn't yet been // initialized. struct PendingPageScaleAnimation { - PendingPageScaleAnimation( - const gfx::Vector2d _target_offset, - bool _use_anchor, - float _scale, - const base::TimeDelta& _duration) - : target_offset(_target_offset), - use_anchor(_use_anchor), - scale(_scale), - duration(_duration) {} + PendingPageScaleAnimation(const gfx::Vector2d& target_offset, + bool use_anchor, + float scale, + const base::TimeDelta& duration) + : target_offset(target_offset), + use_anchor(use_anchor), + scale(scale), + duration(duration) {} gfx::Vector2d target_offset; bool use_anchor; float scale;
diff --git a/cc/input/scroll_state.h b/cc/input/scroll_state.h index 6df0b74..384a934 100644 --- a/cc/input/scroll_state.h +++ b/cc/input/scroll_state.h
@@ -61,10 +61,11 @@ data_.is_direct_manipulation = is_direct_manipulation; } - void set_scroll_chain_and_layer_tree(std::list<ScrollNode*>* scroll_chain, - LayerTreeImpl* layer_tree_impl) { + void set_scroll_chain_and_layer_tree( + const std::list<ScrollNode*>& scroll_chain, + LayerTreeImpl* layer_tree_impl) { layer_tree_impl_ = layer_tree_impl; - scroll_chain_ = *scroll_chain; + scroll_chain_ = scroll_chain; } void set_current_native_scrolling_node(ScrollNode* scroll_node) {
diff --git a/cc/layers/scrollbar_layer_unittest.cc b/cc/layers/scrollbar_layer_unittest.cc index a454c4c..ce209fd 100644 --- a/cc/layers/scrollbar_layer_unittest.cc +++ b/cc/layers/scrollbar_layer_unittest.cc
@@ -1030,7 +1030,7 @@ class ScaledScrollbarLayerTestResourceCreation : public ScrollbarLayerTest { public: - void TestResourceUpload(const float test_scale) { + void TestResourceUpload(float test_scale) { gfx::Point scrollbar_location(0, 185); scoped_refptr<Layer> layer_tree_root = Layer::Create(); scoped_refptr<Layer> content_layer = Layer::Create(); @@ -1099,7 +1099,7 @@ class ScaledScrollbarLayerTestScaledRasterization : public ScrollbarLayerTest { public: - void TestScale(const gfx::Rect scrollbar_rect, const float test_scale) { + void TestScale(const gfx::Rect& scrollbar_rect, float test_scale) { bool paint_during_update = true; bool has_thumb = false; scoped_refptr<Layer> layer_tree_root = Layer::Create();
diff --git a/cc/output/gl_renderer.cc b/cc/output/gl_renderer.cc index 477a88a..60c09db 100644 --- a/cc/output/gl_renderer.cc +++ b/cc/output/gl_renderer.cc
@@ -2603,12 +2603,7 @@ FlippedRootFramebuffer() ? flipped_y_pos_of_rect_bottom : swap_buffer_rect_.y(), swap_buffer_rect_.width(), swap_buffer_rect_.height()); - } else { - // Expand the swap rect to the full surface unless it's empty, and empty - // swap is allowed. - if (!swap_buffer_rect_.IsEmpty() || !allow_empty_swap_) { - swap_buffer_rect_ = gfx::Rect(surface_size); - } + } else if (swap_buffer_rect_.IsEmpty() && allow_empty_swap_) { output_frame.sub_buffer_rect = swap_buffer_rect_; }
diff --git a/cc/output/output_surface_frame.h b/cc/output/output_surface_frame.h index 2306f2e..331496f 100644 --- a/cc/output/output_surface_frame.h +++ b/cc/output/output_surface_frame.h
@@ -8,6 +8,7 @@ #include <vector> #include "base/macros.h" +#include "base/optional.h" #include "cc/base/cc_export.h" #include "ui/events/latency_info.h" #include "ui/gfx/geometry/rect.h" @@ -26,7 +27,8 @@ OutputSurfaceFrame& operator=(OutputSurfaceFrame&& other); gfx::Size size; - gfx::Rect sub_buffer_rect; + // Optional rect for partial or empty swap; if not provided, use regular swap. + base::Optional<gfx::Rect> sub_buffer_rect; std::vector<ui::LatencyInfo> latency_info; private:
diff --git a/cc/test/fake_output_surface.cc b/cc/test/fake_output_surface.cc index cafd10b..07cd5b7 100644 --- a/cc/test/fake_output_surface.cc +++ b/cc/test/fake_output_surface.cc
@@ -45,15 +45,6 @@ last_sent_frame_.reset(new OutputSurfaceFrame(std::move(frame))); ++num_sent_frames_; - if (context_provider()) { - last_swap_rect_ = last_sent_frame_->sub_buffer_rect; - last_swap_rect_valid_ = true; - } else { - // Unknown for direct software frames. - last_swap_rect_ = gfx::Rect(); - last_swap_rect_valid_ = false; - } - base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::Bind(&FakeOutputSurface::SwapBuffersAck, weak_ptr_factory_.GetWeakPtr()));
diff --git a/cc/test/fake_output_surface.h b/cc/test/fake_output_surface.h index 4a83f8d..bf8ef86 100644 --- a/cc/test/fake_output_surface.h +++ b/cc/test/fake_output_surface.h
@@ -93,11 +93,6 @@ suspended_for_recycle_ = suspended; } - gfx::Rect last_swap_rect() const { - DCHECK(last_swap_rect_valid_); - return last_swap_rect_; - } - const gfx::ColorSpace& last_reshape_color_space() { return last_reshape_color_space_; } @@ -115,8 +110,6 @@ GLint framebuffer_ = 0; GLenum framebuffer_format_ = 0; OverlayCandidateValidator* overlay_candidate_validator_ = nullptr; - bool last_swap_rect_valid_ = false; - gfx::Rect last_swap_rect_; gfx::ColorSpace last_reshape_color_space_; private:
diff --git a/cc/test/pixel_comparator.h b/cc/test/pixel_comparator.h index 7228858..c711673 100644 --- a/cc/test/pixel_comparator.h +++ b/cc/test/pixel_comparator.h
@@ -40,12 +40,12 @@ // computes average and maximum absolute errors per color channel. class FuzzyPixelComparator : public PixelComparator { public: - FuzzyPixelComparator(const bool discard_alpha, - const float error_pixels_percentage_limit, - const float small_error_pixels_percentage_limit, - const float avg_abs_error_limit, - const int max_abs_error_limit, - const int small_error_threshold); + FuzzyPixelComparator(bool discard_alpha, + float error_pixels_percentage_limit, + float small_error_pixels_percentage_limit, + float avg_abs_error_limit, + int max_abs_error_limit, + int small_error_threshold); ~FuzzyPixelComparator() override {} // Computes error metrics and returns true if the errors don't exceed the
diff --git a/cc/tiles/gpu_image_decode_cache.cc b/cc/tiles/gpu_image_decode_cache.cc index 1dcc40c..d5b3148d4 100644 --- a/cc/tiles/gpu_image_decode_cache.cc +++ b/cc/tiles/gpu_image_decode_cache.cc
@@ -614,14 +614,13 @@ MemoryAllocatorDump* dump = image_data->decode.data()->CreateMemoryAllocatorDump( discardable_dump_name.c_str(), pmd); - // If our image is locked, dump the "locked_size" as an additional - // column. + // Dump the "locked_size" as an additional column. // This lets us see the amount of discardable which is contributing to // memory pressure. - if (image_data->decode.is_locked()) { - dump->AddScalar("locked_size", MemoryAllocatorDump::kUnitsBytes, - image_data->size); - } + size_t locked_size = + image_data->decode.is_locked() ? image_data->size : 0u; + dump->AddScalar("locked_size", MemoryAllocatorDump::kUnitsBytes, + locked_size); } // If we have an uploaded image (that is actually on the GPU, not just a
diff --git a/cc/tiles/image_controller.cc b/cc/tiles/image_controller.cc index 5de6e348..6fb503aa 100644 --- a/cc/tiles/image_controller.cc +++ b/cc/tiles/image_controller.cc
@@ -77,9 +77,10 @@ ImageDecodeRequestId id = request_to_complete.first; ImageDecodeRequest& request = request_to_complete.second; - // The task (if one exists) would have run already, so we just need to - // complete it. - if (request.task) + // The task (if one exists) would have run already, we just need to make + // sure it was completed. Multiple requests for the same image use the same + // task so it could have already been completed. + if (request.task && !request.task->HasCompleted()) request.task->DidComplete(); // Issue the callback, and unref the image immediately. This is so that any @@ -106,7 +107,9 @@ // several different image deque requests for the same image. if (request.task->state().IsNew()) request.task->state().DidCancel(); - request.task->DidComplete(); + + if (!request.task->HasCompleted()) + request.task->DidComplete(); } // Run the callback and unref the image. request.callback.Run(id); @@ -116,11 +119,14 @@ } void ImageController::SetImageDecodeCache(ImageDecodeCache* cache) { + DCHECK(!cache_ || !cache); + if (!cache) { SetPredecodeImages(std::vector<DrawImage>(), ImageDecodeCache::TracingInfo()); StopWorkerTasks(); } + cache_ = cache; }
diff --git a/cc/tiles/image_controller_unittest.cc b/cc/tiles/image_controller_unittest.cc index ddd5376..cd34155 100644 --- a/cc/tiles/image_controller_unittest.cc +++ b/cc/tiles/image_controller_unittest.cc
@@ -447,5 +447,31 @@ EXPECT_EQ(0, cache()->number_of_refs()); } +TEST_F(ImageControllerTest, DispatchesDecodeCallbacksAfterCacheChanged) { + scoped_refptr<SimpleTask> task(new SimpleTask); + cache()->SetTaskToUse(task); + + base::RunLoop run_loop1; + DecodeClient decode_client1; + base::RunLoop run_loop2; + DecodeClient decode_client2; + + controller()->QueueImageDecode( + image(), + base::Bind(&DecodeClient::Callback, base::Unretained(&decode_client1), + run_loop1.QuitClosure())); + controller()->QueueImageDecode( + image(), + base::Bind(&DecodeClient::Callback, base::Unretained(&decode_client2), + run_loop2.QuitClosure())); + + // Now reset the image cache before decode completed callbacks are posted to + // the compositor thread. Ensure that the completion callbacks for the decode + // is still run. + controller()->SetImageDecodeCache(nullptr); + RunOrTimeout(&run_loop1); + RunOrTimeout(&run_loop2); +} + } // namespace } // namespace cc
diff --git a/cc/tiles/prioritized_tile.cc b/cc/tiles/prioritized_tile.cc index 37da3a98..a76963d3 100644 --- a/cc/tiles/prioritized_tile.cc +++ b/cc/tiles/prioritized_tile.cc
@@ -13,7 +13,7 @@ PrioritizedTile::PrioritizedTile(Tile* tile, const PictureLayerTiling* source_tiling, - const TilePriority priority, + const TilePriority& priority, bool is_occluded, bool is_process_for_images_only) : tile_(tile),
diff --git a/cc/tiles/prioritized_tile.h b/cc/tiles/prioritized_tile.h index 30159784..db7967e 100644 --- a/cc/tiles/prioritized_tile.h +++ b/cc/tiles/prioritized_tile.h
@@ -22,7 +22,7 @@ PrioritizedTile(); PrioritizedTile(Tile* tile, const PictureLayerTiling* source_tiling, - const TilePriority priority, + const TilePriority& priority, bool is_occluded, bool is_process_for_images_only); ~PrioritizedTile();
diff --git a/cc/tiles/software_image_decode_cache.cc b/cc/tiles/software_image_decode_cache.cc index 0169819..e5d3319c 100644 --- a/cc/tiles/software_image_decode_cache.cc +++ b/cc/tiles/software_image_decode_cache.cc
@@ -97,7 +97,7 @@ ImageDecodeTaskImpl(SoftwareImageDecodeCache* cache, const SoftwareImageDecodeCache::ImageKey& image_key, const DrawImage& image, - const SoftwareImageDecodeCache::DecodeTaskType task_type, + SoftwareImageDecodeCache::DecodeTaskType task_type, const ImageDecodeCache::TracingInfo& tracing_info) : TileTask(true), cache_(cache), @@ -864,15 +864,15 @@ reinterpret_cast<uintptr_t>(this), cache_name, image_pair.second->tracing_id(), image_pair.first.image_id()); // CreateMemoryAllocatorDump will automatically add tracking values for the - // total size. If locked, we also add a "locked_size" below. + // total size. We also add a "locked_size" below. MemoryAllocatorDump* dump = image_pair.second->memory()->CreateMemoryAllocatorDump( dump_name.c_str(), pmd); DCHECK(dump); - if (image_pair.second->is_locked()) { - dump->AddScalar("locked_size", MemoryAllocatorDump::kUnitsBytes, - image_pair.first.locked_bytes()); - } + size_t locked_bytes = + image_pair.second->is_locked() ? image_pair.first.locked_bytes() : 0u; + dump->AddScalar("locked_size", MemoryAllocatorDump::kUnitsBytes, + locked_bytes); } }
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc index 50b04fb..fc53daf9 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc
@@ -2568,7 +2568,7 @@ // Walk up the hierarchy and look for a scrollable layer. ScrollTree& scroll_tree = active_tree_->property_trees()->scroll_tree; - LayerImpl* potentially_scrolling_layer_impl = nullptr; + ScrollNode* impl_scroll_node = nullptr; if (layer_impl) { ScrollNode* scroll_node = scroll_tree.Node(layer_impl->scroll_tree_index()); for (; scroll_tree.parent(scroll_node); @@ -2584,9 +2584,8 @@ } if (status.thread == InputHandler::SCROLL_ON_IMPL_THREAD && - !potentially_scrolling_layer_impl) { - potentially_scrolling_layer_impl = - active_tree_->LayerById(scroll_node->owning_layer_id); + !impl_scroll_node) { + impl_scroll_node = scroll_node; } } } @@ -2594,25 +2593,34 @@ // Falling back to the viewport layer ensures generation of root overscroll // notifications. We use the viewport's main scroll layer to represent the // viewport in scrolling code. - if (!potentially_scrolling_layer_impl || - potentially_scrolling_layer_impl == OuterViewportScrollLayer() || - potentially_scrolling_layer_impl == InnerViewportScrollLayer()) { - potentially_scrolling_layer_impl = viewport()->MainScrollLayer(); + bool scrolls_inner_viewport = + impl_scroll_node && InnerViewportScrollLayer() && + InnerViewportScrollLayer()->scroll_tree_index() == impl_scroll_node->id; + bool scrolls_outer_viewport = + impl_scroll_node && OuterViewportScrollLayer() && + OuterViewportScrollLayer()->scroll_tree_index() == impl_scroll_node->id; + if (!impl_scroll_node || scrolls_inner_viewport || scrolls_outer_viewport) { + if (auto* mainScrollLayer = viewport()->MainScrollLayer()) + impl_scroll_node = scroll_tree.Node(mainScrollLayer->scroll_tree_index()); + else + impl_scroll_node = nullptr; } - if (potentially_scrolling_layer_impl) { + if (impl_scroll_node) { // Ensure that final layer scrolls on impl thread (crbug.com/625100) - ScrollNode* scroll_node = - scroll_tree.Node(potentially_scrolling_layer_impl->scroll_tree_index()); ScrollStatus status = - TryScroll(device_viewport_point, type, scroll_tree, scroll_node); - if (IsMainThreadScrolling(status, scroll_node)) { + TryScroll(device_viewport_point, type, scroll_tree, impl_scroll_node); + if (IsMainThreadScrolling(status, impl_scroll_node)) { *scroll_on_main_thread = true; *main_thread_scrolling_reasons = status.main_thread_scrolling_reasons; } } - return potentially_scrolling_layer_impl; + // TODO(pdr): Refactor this function to directly return |impl_scroll_node| + // instead of using ScrollNode's owning_layer_id to return a LayerImpl. + if (!impl_scroll_node) + return nullptr; + return active_tree_->LayerById(impl_scroll_node->owning_layer_id); } static bool IsClosestScrollAncestor(LayerImpl* child, @@ -2864,33 +2872,32 @@ // that ScrollBy uses for non-animated wheel scrolls. scroll_status = ScrollBegin(&scroll_state, WHEEL); scroll_node = scroll_tree.CurrentlyScrollingNode(); - if (scroll_status.thread == SCROLL_ON_IMPL_THREAD) { + if (scroll_status.thread == SCROLL_ON_IMPL_THREAD && scroll_node) { gfx::Vector2dF pending_delta = scroll_delta; - if (scroll_node) { - for (; scroll_tree.parent(scroll_node); - scroll_node = scroll_tree.parent(scroll_node)) { - if (!scroll_node->scrollable) - continue; + for (; scroll_tree.parent(scroll_node); + scroll_node = scroll_tree.parent(scroll_node)) { + if (!scroll_node->scrollable) + continue; - if (viewport()->MainScrollLayer() && - scroll_node->owning_layer_id == - viewport()->MainScrollLayer()->id()) { - gfx::Vector2dF scrolled = - viewport()->ScrollAnimated(pending_delta, delayed_by); - // Viewport::ScrollAnimated returns pending_delta as long as it - // starts an animation. - if (scrolled == pending_delta) - return scroll_status; - break; - } - - gfx::Vector2dF scroll_delta = - ComputeScrollDelta(scroll_node, pending_delta); - if (ScrollAnimationCreate(scroll_node, scroll_delta, delayed_by)) + bool scrolls_main_viewport_scroll_layer = + viewport()->MainScrollLayer() && + viewport()->MainScrollLayer()->scroll_tree_index() == scroll_node->id; + if (scrolls_main_viewport_scroll_layer) { + gfx::Vector2dF scrolled = + viewport()->ScrollAnimated(pending_delta, delayed_by); + // Viewport::ScrollAnimated returns pending_delta as long as it starts + // an animation. + if (scrolled == pending_delta) return scroll_status; - - pending_delta -= scroll_delta; + break; } + + gfx::Vector2dF scroll_delta = + ComputeScrollDelta(scroll_node, pending_delta); + if (ScrollAnimationCreate(scroll_node, scroll_delta, delayed_by)) + return scroll_status; + + pending_delta -= scroll_delta; } } scroll_state.set_is_ending(true); @@ -3020,23 +3027,23 @@ // details. const float kEpsilon = 0.1f; - bool is_viewport_scroll_layer = + bool scrolls_main_viewport_scroll_layer = viewport()->MainScrollLayer() && - scroll_node->owning_layer_id == viewport()->MainScrollLayer()->id(); + viewport()->MainScrollLayer()->scroll_tree_index() == scroll_node->id; // This is needed if the scroll chains up to the viewport without going - // through the outer viewport scroll layer. This can happen if we scroll an + // through the outer viewport scroll node. This can happen if we scroll an // element that's not a descendant of the document.rootScroller. In that case // we want to scroll the inner viewport -- to allow panning while zoomed -- // but also move browser controls if needed. - bool is_inner_viewport_scroll_layer = + bool scrolls_inner_viewport_layer = InnerViewportScrollLayer() && - scroll_node->owning_layer_id == InnerViewportScrollLayer()->id(); + InnerViewportScrollLayer()->scroll_tree_index() == scroll_node->id; - if (is_viewport_scroll_layer || is_inner_viewport_scroll_layer) { + if (scrolls_main_viewport_scroll_layer || scrolls_inner_viewport_layer) { Viewport::ScrollResult result = viewport()->ScrollBy( delta, viewport_point, scroll_state->is_direct_manipulation(), - !wheel_scrolling_, is_viewport_scroll_layer); + !wheel_scrolling_, scrolls_main_viewport_scroll_layer); applied_delta = result.consumed_delta; delta_applied_to_content = result.content_scrolled_delta; @@ -3054,12 +3061,12 @@ // TODO(bokan): This preserves existing behavior by not allowing tiny // scrolls to produce overscroll but is inconsistent in how delta gets // chained up. We need to clean this up. - if (is_viewport_scroll_layer) + if (scrolls_main_viewport_scroll_layer) scroll_state->ConsumeDelta(applied_delta.x(), applied_delta.y()); return; } - if (!is_viewport_scroll_layer && !is_inner_viewport_scroll_layer) { + if (!scrolls_main_viewport_scroll_layer && !scrolls_inner_viewport_layer) { // If the applied delta is within 45 degrees of the input // delta, bail out to make it easier to scroll just one layer // in one direction without affecting any of its parents. @@ -3115,7 +3122,7 @@ current_scroll_chain.push_front(scroll_node); } } - scroll_state->set_scroll_chain_and_layer_tree(¤t_scroll_chain, + scroll_state->set_scroll_chain_and_layer_tree(current_scroll_chain, active_tree()); scroll_state->DistributeToScrollChainDescendant(); }
diff --git a/cc/trees/layer_tree_host_unittest_scroll.cc b/cc/trees/layer_tree_host_unittest_scroll.cc index 8cb13e9..9f545a5 100644 --- a/cc/trees/layer_tree_host_unittest_scroll.cc +++ b/cc/trees/layer_tree_host_unittest_scroll.cc
@@ -1865,7 +1865,7 @@ PostSetNeedsCommitToMainThread(); } - void BindInputHandler(const base::WeakPtr<InputHandler> input_handler) { + void BindInputHandler(base::WeakPtr<InputHandler> input_handler) { DCHECK(task_runner_provider()->IsImplThread()); input_handler->BindToClient(&input_handler_client_); scroll_elasticity_helper_ = input_handler->CreateScrollElasticityHelper();
diff --git a/chrome/android/java/res/menu/chrome_context_menu.xml b/chrome/android/java/res/menu/chrome_context_menu.xml index 4591cdce..fd64b75 100644 --- a/chrome/android/java/res/menu/chrome_context_menu.xml +++ b/chrome/android/java/res/menu/chrome_context_menu.xml
@@ -4,6 +4,14 @@ found in the LICENSE file. --> <menu xmlns:android="http://schemas.android.com/apk/res/android"> + <group android:id="@+id/contextmenu_group_tab_cct"> + <item android:id="@+id/contextmenu_open_in_new_chrome_tab" + android:title="@string/contextmenu_open_in_new_chrome_tab"/> + <item android:id="@+id/contextmenu_open_in_chrome_incognito_tab" + android:title="@string/contextmenu_open_in_chrome_incognito_tab"/> + <item android:id="@+id/contextmenu_open_in_browser_id" + android:title=""/> + </group> <group android:id="@+id/contextmenu_group_anchor"> <item android:id="@+id/contextmenu_load_images" android:title="@string/contextmenu_load_images"/>
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 ada13e5..a186f87 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java
@@ -151,7 +151,9 @@ import org.chromium.ui.base.WindowAndroid; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; import java.util.concurrent.TimeUnit; import javax.annotation.Nullable; @@ -254,7 +256,7 @@ // A set of views obscuring all tabs. When this set is nonempty, // all tab content will be hidden from the accessibility tree. - private List<View> mViewsObscuringAllTabs = new ArrayList<>(); + private Set<View> mViewsObscuringAllTabs = new HashSet<>(); // See enableHardwareAcceleration() private boolean mSetWindowHWA;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/DefaultBrowserInfo.java b/chrome/android/java/src/org/chromium/chrome/browser/DefaultBrowserInfo.java new file mode 100644 index 0000000..16f7b1ed --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/DefaultBrowserInfo.java
@@ -0,0 +1,104 @@ +// 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; + +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.net.Uri; +import android.os.AsyncTask; + +import org.chromium.base.BuildInfo; +import org.chromium.base.ContextUtils; +import org.chromium.chrome.R; +import org.chromium.chrome.browser.preferences.ChromePreferenceManager; + +import java.util.ArrayList; +import java.util.concurrent.ExecutionException; + +/** + * A utility class for querying information about the default browser setting. + */ +public class DefaultBrowserInfo { + private static final String SAMPLE_URL = "http://www.madeupdomainforcheck123.com/"; + + /** A lock to synchronize background tasks to retrieve browser information. */ + private static final Object sDirCreationLock = new Object(); + + private static AsyncTask<Void, Void, ArrayList<String>> sDefaultBrowserFetcher; + + /** + * Initialize an AsyncTask for getting menu title of opening a link in default browser. + */ + public static void initBrowserFetcher() { + synchronized (sDirCreationLock) { + if (sDefaultBrowserFetcher == null) { + sDefaultBrowserFetcher = new AsyncTask<Void, Void, ArrayList<String>>() { + @Override + protected ArrayList<String> doInBackground(Void... params) { + Context context = ContextUtils.getApplicationContext(); + ArrayList<String> menuTitles = new ArrayList<String>(2); + // Store the package label of current application. + menuTitles.add(BuildInfo.getPackageLabel(context)); + + PackageManager pm = context.getPackageManager(); + ResolveInfo info = getResolveInfoForViewIntent(pm); + + // Caches whether Chrome is set as a default browser on the device. + boolean isDefault = (info != null && info.match != 0 + && context.getPackageName().equals(info.activityInfo.packageName)); + ChromePreferenceManager.getInstance().setCachedChromeDefaultBrowser( + isDefault); + + // Check if there is a default handler for the Intent. If so, store its + // label. + String packageLabel = null; + if (info != null && info.match != 0 && info.loadLabel(pm) != null) { + packageLabel = info.loadLabel(pm).toString(); + } + if (packageLabel == null) { + menuTitles.add( + context.getString(R.string.menu_open_in_product_default)); + } else { + menuTitles.add( + context.getString(R.string.menu_open_in_product, packageLabel)); + } + return menuTitles; + } + }; + sDefaultBrowserFetcher.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + } + } + } + + /** + * @return Default ResolveInfo to handle a VIEW intent for a url. + * @param pm The PackageManager of current context. + */ + public static ResolveInfo getResolveInfoForViewIntent(PackageManager pm) { + Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(SAMPLE_URL)); + return pm.resolveActivity(intent, 0); + } + + /** + * @return Title of the menu item for opening a link in the default browser. + * @param forceChromeAsDefault Whether the Custom Tab is created by Chrome. + */ + public static String getTitleOpenInDefaultBrowser(final boolean forceChromeAsDefault) { + if (sDefaultBrowserFetcher == null) { + initBrowserFetcher(); + } + try { + // If the Custom Tab was created by Chrome, Chrome should handle the action for the + // overflow menu. + return forceChromeAsDefault ? sDefaultBrowserFetcher.get().get(0) + : sDefaultBrowserFetcher.get().get(1); + } catch (InterruptedException | ExecutionException e) { + return ContextUtils.getApplicationContext().getString( + R.string.menu_open_in_product_default); + } + } +}
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 e713649..d6ea4b3 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/DeferredStartupHandler.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/DeferredStartupHandler.java
@@ -5,10 +5,7 @@ package org.chromium.chrome.browser; import android.content.Context; -import android.content.Intent; import android.content.SharedPreferences; -import android.content.pm.ResolveInfo; -import android.net.Uri; import android.os.AsyncTask; import android.os.Looper; import android.os.MessageQueue; @@ -176,6 +173,8 @@ // Punt all tasks that may block on disk off onto a background thread. initAsyncDiskTask(); + DefaultBrowserInfo.initBrowserFetcher(); + AfterStartupTaskUtils.setStartupComplete(); PartnerBrowserCustomizations.setOnInitializeAsyncFinished(new Runnable() { @@ -283,8 +282,6 @@ removeSnapshotDatabase(); - cacheIsChromeDefaultBrowser(); - // Warm up all web app shared prefs. This must be run after the WebappRegistry // instance is initialized. WebappRegistry.warmUpSharedPrefs(); @@ -320,20 +317,6 @@ } /** - * Caches whether Chrome is set as a default browser on the device. - */ - @WorkerThread - private void cacheIsChromeDefaultBrowser() { - // Retrieve whether Chrome is default in background to avoid strict mode checks. - Intent intent = new Intent(Intent.ACTION_VIEW, - Uri.parse("http://www.madeupdomainforcheck123.com/")); - ResolveInfo info = mAppContext.getPackageManager().resolveActivity(intent, 0); - boolean isDefault = (info != null && info.match != 0 - && mAppContext.getPackageName().equals(info.activityInfo.packageName)); - ChromePreferenceManager.getInstance().setCachedChromeDefaultBrowser(isDefault); - } - - /** * Deletes the snapshot database which is no longer used because the feature has been removed * in Chrome M41. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ShortcutHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/ShortcutHelper.java index dac0669..769b930 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ShortcutHelper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ShortcutHelper.java
@@ -587,15 +587,17 @@ @CalledByNative public static String getScopeFromUrl(String url) { // Scope URL is generated by: - // - Removing last component of the URL. + // - Removing last component of the URL if it does not end with a slash. // - Clearing the URL's query and fragment. Uri uri = Uri.parse(url); List<String> path = uri.getPathSegments(); int endIndex = path.size(); - // If there is at least one path element, remove the last one. - if (endIndex > 0) { + // Remove the last path element if there is at least one path element, *and* the path does + // not end with a slash. This means that URLs to specific files have the file component + // removed, but URLs to directories retain the directory. + if (endIndex > 0 && !uri.getPath().endsWith("/")) { endIndex -= 1; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java index bf752e3ea..78d80e75 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java
@@ -18,6 +18,7 @@ import org.chromium.chrome.browser.UrlConstants; import org.chromium.chrome.browser.firstrun.FirstRunStatus; import org.chromium.chrome.browser.net.spdyproxy.DataReductionProxySettings; +import org.chromium.chrome.browser.preferences.ChromePreferenceManager; import org.chromium.chrome.browser.preferences.datareduction.DataReductionProxyUma; import org.chromium.chrome.browser.search_engines.TemplateUrlService; import org.chromium.chrome.browser.util.UrlUtilities; @@ -76,8 +77,9 @@ // Additional items for custom tabs mode. private static final int[] CUSTOM_TAB_MODE_WHITELIST = { - R.id.contextmenu_open_image, - R.id.contextmenu_search_by_image + R.id.contextmenu_open_image, R.id.contextmenu_search_by_image, + R.id.contextmenu_open_in_new_chrome_tab, R.id.contextmenu_open_in_chrome_incognito_tab, + R.id.contextmenu_open_in_browser_id, }; // Additional items for fullscreen tabs mode. @@ -319,6 +321,14 @@ removeUnsupportedItems(menu, FULLSCREEN_TAB_MODE_WHITELIST); } else if (mMode == CUSTOM_TAB_MODE) { removeUnsupportedItems(menu, CUSTOM_TAB_MODE_WHITELIST); + MenuItem defaultOpenMenuItem = menu.findItem(R.id.contextmenu_open_in_browser_id); + if (ChromePreferenceManager.getInstance().getCachedChromeDefaultBrowser()) { + defaultOpenMenuItem.setVisible(false); + } else { + menu.findItem(R.id.contextmenu_open_in_new_chrome_tab).setVisible(false); + menu.findItem(R.id.contextmenu_open_in_chrome_incognito_tab).setVisible(false); + defaultOpenMenuItem.setTitle(mDelegate.getTitleForOpenTabInExternalApp()); + } } else { removeUnsupportedItems(menu, NORMAL_MODE_WHITELIST); } @@ -427,6 +437,12 @@ helper.shareImage(); } else if (itemId == R.id.menu_id_open_in_chrome) { mDelegate.onOpenInChrome(params.getLinkUrl(), params.getPageUrl()); + } else if (itemId == R.id.contextmenu_open_in_new_chrome_tab) { + mDelegate.onOpenInNewChromeTabFromCCT(params.getLinkUrl(), false); + } else if (itemId == R.id.contextmenu_open_in_chrome_incognito_tab) { + mDelegate.onOpenInNewChromeTabFromCCT(params.getLinkUrl(), true); + } else if (itemId == R.id.contextmenu_open_in_browser_id) { + mDelegate.onOpenInDefaultBrowser(params.getLinkUrl()); } else { assert false; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuItemDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuItemDelegate.java index 1e622413..8832c6f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuItemDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuItemDelegate.java
@@ -153,4 +153,22 @@ * @param pageUrl URL of the current page. */ void onOpenInChrome(String linkUrl, String pageUrl); + + /** + * Called when the {@code url} should be opened in a new Chrome tab from CCT. + * @param url The URL to open. + * @param isIncognito true if the {@code url} should be opened in a new incognito tab. + */ + void onOpenInNewChromeTabFromCCT(String linkUrl, boolean isIncognito); + + /** + * @return title of the context menu to open a page in external apps. + */ + String getTitleForOpenTabInExternalApp(); + + /** + * Called when the current Chrome app is not the default to handle a View Intent. + * @param url The URL to open. + */ + void onOpenInDefaultBrowser(String url); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabAppMenuPropertiesDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabAppMenuPropertiesDelegate.java index e55fee0..d4c720db 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabAppMenuPropertiesDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabAppMenuPropertiesDelegate.java
@@ -4,18 +4,13 @@ package org.chromium.chrome.browser.customtabs; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.net.Uri; -import android.os.AsyncTask; import android.view.Menu; import android.view.MenuItem; -import org.chromium.base.BuildInfo; import org.chromium.base.VisibleForTesting; import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeActivity; +import org.chromium.chrome.browser.DefaultBrowserInfo; import org.chromium.chrome.browser.UrlConstants; import org.chromium.chrome.browser.appmenu.AppMenuPropertiesDelegate; import org.chromium.chrome.browser.banners.AppBannerManager; @@ -27,7 +22,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.concurrent.ExecutionException; /** * App menu properties delegate for {@link CustomTabActivity}. @@ -39,10 +33,10 @@ private final boolean mIsMediaViewer; private final boolean mShowStar; private final boolean mShowDownload; + private final boolean mIsOpenedByChrome; private final List<String> mMenuEntries; private final Map<MenuItem, Integer> mItemToIndexMap = new HashMap<MenuItem, Integer>(); - private final AsyncTask<Void, Void, String> mDefaultBrowserFetcher; private boolean mIsCustomEntryAdded; @@ -58,29 +52,7 @@ mIsMediaViewer = isMediaViewer; mShowStar = showStar; mShowDownload = showDownload; - - mDefaultBrowserFetcher = new AsyncTask<Void, Void, String>() { - @Override - protected String doInBackground(Void... params) { - String packageLabel = null; - if (isOpenedByChrome) { - // If the Custom Tab was created by Chrome, Chrome should open it. - packageLabel = BuildInfo.getPackageLabel(activity); - } else { - // Check if there is a default handler for the Intent. If so, grab its label. - Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(SAMPLE_URL)); - PackageManager pm = activity.getPackageManager(); - ResolveInfo info = pm.resolveActivity(intent, 0); - if (info != null && info.match != 0) { - packageLabel = info.loadLabel(pm).toString(); - } - } - - return packageLabel == null - ? activity.getString(R.string.menu_open_in_product_default) - : activity.getString(R.string.menu_open_in_product, packageLabel); - } - }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + mIsOpenedByChrome = isOpenedByChrome; } @Override @@ -122,13 +94,8 @@ menu.findItem(R.id.request_desktop_site_id).setVisible(false); addToHomeScreenItem.setVisible(false); } else { - try { - openInChromeItem.setTitle(mDefaultBrowserFetcher.get()); - } catch (InterruptedException | ExecutionException e) { - openInChromeItem.setTitle( - mActivity.getString(R.string.menu_open_in_product_default)); - } - updateBookmarkMenuItem(bookmarkItem, currentTab); + openInChromeItem.setTitle( + DefaultBrowserInfo.getTitleOpenInDefaultBrowser(mIsOpenedByChrome)); } bookmarkItem.setVisible(mShowStar); downloadItem.setVisible(mShowDownload);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/gsa/GSAAccountChangeListener.java b/chrome/android/java/src/org/chromium/chrome/browser/gsa/GSAAccountChangeListener.java index 12bc7c1..cfec713 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/gsa/GSAAccountChangeListener.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/gsa/GSAAccountChangeListener.java
@@ -16,6 +16,7 @@ import org.chromium.base.ApiCompatibilityUtils; import org.chromium.base.Callback; import org.chromium.base.ContextUtils; +import org.chromium.base.VisibleForTesting; import org.chromium.base.metrics.RecordHistogram; /** @@ -32,11 +33,13 @@ public class GSAAccountChangeListener { // These are GSA constants. private static final String GSA_PACKAGE_NAME = "com.google.android.googlequicksearchbox"; - private static final String ACCOUNT_UPDATE_BROADCAST_INTENT = + @VisibleForTesting + static final String ACCOUNT_UPDATE_BROADCAST_INTENT = "com.google.android.apps.now.account_update_broadcast"; private static final String KEY_SSB_BROADCASTS_ACCOUNT_CHANGE_TO_CHROME = "ssb_service:ssb_broadcasts_account_change_to_chrome"; - private static final String BROADCAST_INTENT_ACCOUNT_NAME_EXTRA = "account_name"; + @VisibleForTesting + static final String BROADCAST_INTENT_ACCOUNT_NAME_EXTRA = "account_name"; public static final String ACCOUNT_UPDATE_BROADCAST_PERMISSION = "com.google.android.apps.now.CURRENT_ACCOUNT_ACCESS"; @@ -48,6 +51,19 @@ private boolean mAlreadyReportedHistogram; + @VisibleForTesting + static class AccountChangeBroadcastReceiver extends BroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent) { + if (!ACCOUNT_UPDATE_BROADCAST_INTENT.equals(intent.getAction())) return; + String accountName = intent.getStringExtra(BROADCAST_INTENT_ACCOUNT_NAME_EXTRA); + RecordHistogram.recordEnumeratedHistogram(GSAServiceClient.ACCOUNT_CHANGE_HISTOGRAM, + GSAServiceClient.ACCOUNT_CHANGE_SOURCE_BROADCAST, + GSAServiceClient.ACCOUNT_CHANGE_SOURCE_COUNT); + GSAState.getInstance(context.getApplicationContext()).setGsaAccount(accountName); + } + } + /** @return the instance of GSAAccountChangeListener. */ public static GSAAccountChangeListener getInstance() { if (sInstance == null) { @@ -70,18 +86,7 @@ private GSAAccountChangeListener(Context context) { Context applicationContext = context.getApplicationContext(); - BroadcastReceiver accountChangeReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - if (!ACCOUNT_UPDATE_BROADCAST_INTENT.equals(intent.getAction())) return; - String accountName = intent.getStringExtra(BROADCAST_INTENT_ACCOUNT_NAME_EXTRA); - RecordHistogram.recordEnumeratedHistogram(GSAServiceClient.ACCOUNT_CHANGE_HISTOGRAM, - GSAServiceClient.ACCOUNT_CHANGE_SOURCE_BROADCAST, - GSAServiceClient.ACCOUNT_CHANGE_SOURCE_COUNT); - GSAState.getInstance(context.getApplicationContext()).setGsaAccount(accountName); - } - }; - applicationContext.registerReceiver(accountChangeReceiver, + applicationContext.registerReceiver(new AccountChangeBroadcastReceiver(), new IntentFilter(ACCOUNT_UPDATE_BROADCAST_INTENT), ACCOUNT_UPDATE_BROADCAST_PERMISSION, null);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/invalidation/InvalidationController.java b/chrome/android/java/src/org/chromium/chrome/browser/invalidation/InvalidationController.java index d74996a..80fcc158 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/invalidation/InvalidationController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/invalidation/InvalidationController.java
@@ -14,7 +14,9 @@ import org.chromium.base.ApplicationState; import org.chromium.base.ApplicationStatus; +import org.chromium.base.BuildInfo; import org.chromium.base.FieldTrialList; +import org.chromium.base.Log; import org.chromium.base.VisibleForTesting; import org.chromium.chrome.browser.ChromeFeatureList; import org.chromium.chrome.browser.sync.ProfileSyncService; @@ -31,6 +33,8 @@ * client library used by Sync. */ public class InvalidationController implements ApplicationStatus.ApplicationStateListener { + private static final String TAG = "cr_invalidation"; + /** * Timer which can be paused. When the timer is paused, the execution of its scheduled task is * delayed till the timer is resumed. @@ -194,6 +198,11 @@ typesToRegister); registerIntent.setClass( mContext, InvalidationClientService.getRegisteredClass()); + + if (shouldRestrictBackgroundServices()) { + Log.e(TAG, "Failed to register types"); + return; + } mContext.startService(registerIntent); } @@ -221,6 +230,11 @@ * Starts the invalidation client without updating the registered invalidation types. */ private void start() { + if (shouldRestrictBackgroundServices()) { + Log.e(TAG, "Failed to start invalidation client"); + return; + } + mStarted = true; mEnableSessionInvalidationsTimer.resume(); Intent intent = new Intent( @@ -232,6 +246,11 @@ * Stops the invalidation client. */ public void stop() { + if (shouldRestrictBackgroundServices()) { + Log.e(TAG, "Failed to stop invalidation client"); + return; + } + mStarted = false; mEnableSessionInvalidationsTimer.pause(); Intent intent = new Intent( @@ -339,6 +358,11 @@ ApplicationStatus.registerApplicationStateListener(this); } + private boolean shouldRestrictBackgroundServices() { + // Restricts the use of background services when not in foreground. See crbug.com/680812. + return BuildInfo.isGreaterThanN() && !ApplicationStatus.hasVisibleActivities(); + } + @Override public void onApplicationStateChange(int newState) { // The isSyncEnabled() check is used to check whether the InvalidationController would be
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBar.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBar.java index c42cc3a..775d3d6b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBar.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBar.java
@@ -171,4 +171,12 @@ */ void setDefaultTextEditActionModeCallback(ToolbarActionModeCallback callback); + /** + * Returns whether the {@link UrlBar} must be queried for its location on screen when + * suggestions are being laid out by {@link SuggestionView}. + * TODO(dfalcantara): Revisit this after M58. + * + * @return Whether or not the {@link UrlBar} has to be explicitly checked for its location. + */ + boolean mustQueryUrlBarLocationForSuggestions(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java index 7dd644a..5dd73e0c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java
@@ -1989,7 +1989,8 @@ } } - private void backKeyPressed() { + // TODO(dfalcantara): Make private again after M58. + protected void backKeyPressed() { hideSuggestions(); UiUtils.hideKeyboard(mUrlBar); // Revert the URL to match the current page. @@ -2462,4 +2463,9 @@ @Override public void setShowTitle(boolean showTitle) { } + + @Override + public boolean mustQueryUrlBarLocationForSuggestions() { + return DeviceFormFactor.isTablet(getContext()); + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/SuggestionView.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/SuggestionView.java index c5253338..531a761 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/SuggestionView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/SuggestionView.java
@@ -861,7 +861,7 @@ } private int getUrlBarLeftOffset() { - if (DeviceFormFactor.isTablet(getContext())) { + if (mLocationBar.mustQueryUrlBarLocationForSuggestions()) { mUrlBar.getLocationInWindow(mViewPositionHolder); return mViewPositionHolder[0]; } else {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabContextMenuItemDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabContextMenuItemDelegate.java index 9dbaa3f..3490476c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabContextMenuItemDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabContextMenuItemDelegate.java
@@ -8,12 +8,15 @@ import android.content.Intent; import android.net.MailTo; import android.net.Uri; +import android.provider.Browser; import android.provider.ContactsContract; import org.chromium.base.metrics.RecordUserAction; +import org.chromium.chrome.browser.DefaultBrowserInfo; import org.chromium.chrome.browser.IntentHandler; import org.chromium.chrome.browser.UrlConstants; import org.chromium.chrome.browser.contextmenu.ContextMenuItemDelegate; +import org.chromium.chrome.browser.document.ChromeLauncherActivity; import org.chromium.chrome.browser.multiwindow.MultiWindowUtils; import org.chromium.chrome.browser.net.spdyproxy.DataReductionProxySettings; import org.chromium.chrome.browser.preferences.PrefServiceBridge; @@ -232,6 +235,33 @@ } } + @Override + public void onOpenInNewChromeTabFromCCT(String linkUrl, boolean isIncognito) { + Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(linkUrl)); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.setPackage(mTab.getApplicationContext().getPackageName()); + intent.putExtra(ChromeLauncherActivity.EXTRA_IS_ALLOWED_TO_RETURN_TO_PARENT, false); + if (isIncognito) { + intent.putExtra(IntentHandler.EXTRA_OPEN_NEW_INCOGNITO_TAB, true); + intent.putExtra( + Browser.EXTRA_APPLICATION_ID, mTab.getApplicationContext().getPackageName()); + IntentHandler.addTrustedIntentExtras(intent); + } + IntentUtils.safeStartActivity(mTab.getActivity(), intent); + } + + @Override + public String getTitleForOpenTabInExternalApp() { + return DefaultBrowserInfo.getTitleOpenInDefaultBrowser(false); + } + + @Override + public void onOpenInDefaultBrowser(String url) { + Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + IntentUtils.safeStartActivity(mTab.getActivity(), intent); + } + /** * Checks if spdy proxy is enabled for input url. * @param url Input url to check for spdy setting.
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 40a13bf..1716d7c2 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
@@ -10,16 +10,22 @@ import org.chromium.chrome.R; import org.chromium.chrome.browser.widget.BottomSheet; +import org.chromium.chrome.browser.widget.BottomSheetObserver; /** * Phone specific toolbar that exists at the bottom of the screen. */ -public class BottomToolbarPhone extends ToolbarPhone { - +public class BottomToolbarPhone extends ToolbarPhone implements BottomSheetObserver { /** A handle to the bottom sheet. */ private BottomSheet mBottomSheet; /** + * Whether the end toolbar buttons should be hidden regardless of whether the URL bar is + * focused. + */ + private boolean mShouldHideEndToolbarButtons; + + /** * Constructs a BottomToolbarPhone object. * @param context The Context in which this View object is created. * @param attrs The AttributeSet that was specified with this View. @@ -46,8 +52,11 @@ @Override public void setBottomSheet(BottomSheet sheet) { + assert mBottomSheet == null; + mBottomSheet = sheet; getLocationBar().setBottomSheet(mBottomSheet); + mBottomSheet.addObserver(this); } @Override @@ -65,4 +74,34 @@ coordinator.addView(mProgressBar); mProgressBar.setProgressBarContainer(coordinator); } + + @Override + protected boolean shouldHideEndToolbarButtons() { + return mShouldHideEndToolbarButtons; + } + + @Override + public void onSheetOpened() {} + + @Override + public void onSheetClosed() {} + + @Override + public void onLoadUrl(String url) {} + + @Override + public void onTransitionPeekToHalf(float transitionFraction) { + // TODO(twellington): animate end toolbar button appearance/disappearance. + if (transitionFraction >= 0.5 && !mShouldHideEndToolbarButtons) { + mShouldHideEndToolbarButtons = true; + updateUrlExpansionAnimation(); + } else if (transitionFraction < 0.5 && mShouldHideEndToolbarButtons) { + mShouldHideEndToolbarButtons = false; + updateUrlExpansionAnimation(); + } + + boolean buttonsClickable = transitionFraction == 0.f; + mToggleTabStackButton.setClickable(buttonsClickable); + mMenuButton.setClickable(buttonsClickable); + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/CustomTabToolbar.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/CustomTabToolbar.java index ae93dacf..e06bba2d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/CustomTabToolbar.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/CustomTabToolbar.java
@@ -759,4 +759,9 @@ // This class has no menu button wrapper, so return the menu button instead. return mMenuButton; } + + @Override + public boolean mustQueryUrlBarLocationForSuggestions() { + return false; + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/OWNERS b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/OWNERS index f47a3405..8efec3b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/OWNERS +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/OWNERS
@@ -1,2 +1,4 @@ tedchoc@chromium.org yusufo@chromium.org + +per-file BottomToolbarPhone.java=mdjones@chromium.org
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarPhone.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarPhone.java index d9a93b58..f3cac87 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarPhone.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarPhone.java
@@ -114,7 +114,7 @@ private LocationBarPhone mLocationBar; private ViewGroup mToolbarButtonsContainer; - private ImageView mToggleTabStackButton; + protected ImageView mToggleTabStackButton; private NewTabButton mNewTabButton; private TintedImageButton mHomeButton; private TextView mUrlBar; @@ -625,8 +625,9 @@ if (visualState == VisualState.NEW_TAB_NORMAL) { return 0; } else if (ApiCompatibilityUtils.isLayoutRtl(this)) { - return Math.max( - mToolbarSidePadding, mToolbarButtonsContainer.getMeasuredWidth()); + return Math.max(mToolbarSidePadding, + shouldHideEndToolbarButtons() ? 0 + : mToolbarButtonsContainer.getMeasuredWidth()); } else { return getBoundsAfterAccountingForLeftButton(); } @@ -646,8 +647,9 @@ } else if (ApiCompatibilityUtils.isLayoutRtl(this)) { return getMeasuredWidth() - getBoundsAfterAccountingForLeftButton(); } else { - int margin = Math.max( - mToolbarSidePadding, mToolbarButtonsContainer.getMeasuredWidth()); + int margin = Math.max(mToolbarSidePadding, + shouldHideEndToolbarButtons() ? 0 + : mToolbarButtonsContainer.getMeasuredWidth()); return getMeasuredWidth() - margin; } } @@ -781,7 +783,7 @@ * Updates the parameters relating to expanding the location bar, as the result of either a * focus change or scrolling the New Tab Page. */ - private void updateUrlExpansionAnimation() { + protected void updateUrlExpansionAnimation() { if (mTabSwitcherState != STATIC_TAB) { mToolbarButtonsContainer.setVisibility(VISIBLE); return; @@ -844,6 +846,24 @@ } else { urlActionsTranslationX += mLocationBarNtpOffsetRight - mLocationBarNtpOffsetLeft; } + + if (shouldHideEndToolbarButtons()) { + // When the end toolbar buttons are not hidden, url actions are shown and hidden due to + // a change in location bar's width. When the end toolbar buttons are hidden, the + // location bar's width does not change by as much, causing the end location for the url + // actions to be immediately visible. Translate the url action container so that their + // appearance is animated. + // TODO(twellington): polish the url action button animation when end toolbar buttons + // are hidden. + float urlActionsTranslationXOffset = + mUrlActionContainer.getWidth() * (1 - mUrlExpansionPercent); + if (isLocationBarRtl) { + urlActionsTranslationX -= urlActionsTranslationXOffset; + } else { + urlActionsTranslationX += urlActionsTranslationXOffset; + } + } + mUrlActionContainer.setTranslationX(urlActionsTranslationX); mLocationBar.setUrlFocusChangePercent(mUrlExpansionPercent); @@ -851,7 +871,8 @@ // Ensure the buttons are invisible after focusing the omnibox to prevent them from // accepting click events. int toolbarButtonVisibility = mUrlExpansionPercent == 1f ? INVISIBLE : VISIBLE; - mToolbarButtonsContainer.setVisibility(toolbarButtonVisibility); + mToolbarButtonsContainer.setVisibility( + shouldHideEndToolbarButtons() ? INVISIBLE : toolbarButtonVisibility); if (mHomeButton.getVisibility() != GONE) { mHomeButton.setVisibility(toolbarButtonVisibility); } @@ -1336,6 +1357,15 @@ } } + /** + * @return Whether the end toolbar buttons (tab switcher and menu) are currently hidden + * regardless of URL bar focus. Sub-classes that hide these buttons should override + * this method. + */ + protected boolean shouldHideEndToolbarButtons() { + return false; + } + private ObjectAnimator createEnterTabSwitcherModeAnimation() { ObjectAnimator enterAnimation = ObjectAnimator.ofFloat(this, mTabSwitcherModePercentProperty, 1.f);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/FadingBackgroundView.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/FadingBackgroundView.java index 9135e60..3a65612 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/FadingBackgroundView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/FadingBackgroundView.java
@@ -82,10 +82,31 @@ super.setAlpha(alpha); int newVisibility = alpha <= 0f ? View.GONE : View.VISIBLE; - setVisibility(newVisibility); - for (FadingViewObserver o : mObservers) { - o.onFadingViewVisibilityChanged(newVisibility == View.VISIBLE); + } + + @Override + public void setVisibility(int visibility) { + if (getAlpha() <= 0f && visibility == View.VISIBLE) return; + super.setVisibility(visibility); + } + + @Override + protected void dispatchVisibilityChanged(View view, int visibility) { + if (getAlpha() <= 0f && visibility == View.VISIBLE) return; + super.dispatchVisibilityChanged(view, visibility); + } + + @Override + public void onVisibilityChanged(View view, int visibility) { + super.onVisibilityChanged(view, visibility); + + // This check is added for the exclusive purpose of testing on Android K. Later versions + // of Android do not run into the problem of the observer list being null. + if (mObservers != null) { + for (FadingViewObserver o : mObservers) { + o.onFadingViewVisibilityChanged(visibility == View.VISIBLE); + } } } @@ -107,15 +128,13 @@ * Triggers a fade out of the omnibox results background creating a new animation if necessary. */ public void hideFadingOverlay(boolean fadeOut) { - // If the overlay is already invisible, do nothing. - if (getVisibility() != VISIBLE) return; - if (mOverlayFadeOutAnimator == null) { mOverlayFadeOutAnimator = ObjectAnimator.ofFloat(this, ALPHA, 0f); mOverlayFadeOutAnimator.setDuration(FADE_DURATION_MS); mOverlayFadeOutAnimator.setInterpolator(BakedBezierInterpolator.FADE_OUT_CURVE); } + mOverlayFadeOutAnimator.setFloatValues(getAlpha(), 0f); runFadeOverlayAnimation(mOverlayFadeOutAnimator); if (!fadeOut) mOverlayFadeOutAnimator.end(); }
diff --git a/chrome/android/java/strings/android_chrome_strings.grd b/chrome/android/java/strings/android_chrome_strings.grd index cd1dbd04..3d2e897a 100644 --- a/chrome/android/java/strings/android_chrome_strings.grd +++ b/chrome/android/java/strings/android_chrome_strings.grd
@@ -1512,7 +1512,12 @@ <message name="IDS_CONTEXTMENU_SAVE_VIDEO" desc="Context sensitive menu item for saving the selected video. [CHAR-LIMIT=30]"> Download video </message> - + <message name="IDS_CONTEXTMENU_OPEN_IN_NEW_CHROME_TAB" desc="Context sensitive menu item to open the selected link in a new Chrome tab from Chrome Custom Tab. [CHAR-LIMIT=30]"> + Open in new Chrome tab + </message> + <message name="IDS_CONTEXTMENU_OPEN_IN_CHROME_INCOGNITO_TAB" desc="Context sensitive menu item to open the selected link in a Chrome incognito tab from Chrome Custom Tab. [CHAR-LIMIT=30]"> + Open in Chrome incognito tab + </message> <!-- Swipe refresh --> <message name="IDS_ACCESSIBILITY_SWIPE_REFRESH" desc="Content description for the swipe refresh action."> Refreshing page
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni index 83abfcf..d42512ff 100644 --- a/chrome/android/java_sources.gni +++ b/chrome/android/java_sources.gni
@@ -30,6 +30,7 @@ "java/src/org/chromium/chrome/browser/ChromeTabbedActivity2.java", "java/src/org/chromium/chrome/browser/ChromeVersionInfo.java", "java/src/org/chromium/chrome/browser/ChromeWindow.java", + "java/src/org/chromium/chrome/browser/DefaultBrowserInfo.java", "java/src/org/chromium/chrome/browser/DeferredStartupHandler.java", "java/src/org/chromium/chrome/browser/DevToolsServer.java", "java/src/org/chromium/chrome/browser/FileProviderHelper.java", @@ -1293,6 +1294,7 @@ "javatests/src/org/chromium/chrome/browser/fullscreen/FullscreenManagerTest.java", "javatests/src/org/chromium/chrome/browser/gcore/MockConnectedTask.java", "javatests/src/org/chromium/chrome/browser/gcore/MockConnectedTaskTest.java", + "javatests/src/org/chromium/chrome/browser/gsa/GSAAccountChangeListenerTest.java", "javatests/src/org/chromium/chrome/browser/gsa/GSAServiceClientTest.java", "javatests/src/org/chromium/chrome/browser/hardware_acceleration/ChromeTabbedActivityHWATest.java", "javatests/src/org/chromium/chrome/browser/hardware_acceleration/CustomTabActivityHWATest.java",
diff --git a/chrome/android/javatests/OWNERS b/chrome/android/javatests/OWNERS index a1e57466..8391a687 100644 --- a/chrome/android/javatests/OWNERS +++ b/chrome/android/javatests/OWNERS
@@ -5,3 +5,5 @@ skyostil@chromium.org tedchoc@chromium.org yfriedman@chromium.org + +# COMPONENT: Test>Android
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/AudioTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/AudioTest.java index ddb35a0..2465227c 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/AudioTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/AudioTest.java
@@ -51,7 +51,7 @@ assertEquals("ready_to_play", tab.getTitle()); titleObserver = new TabTitleObserver(tab, "ended"); - DOMUtils.clickNode(this, tab.getContentViewCore(), "button1"); + DOMUtils.clickNode(tab.getContentViewCore(), "button1"); // Make sure that the audio playback "ended" and title is changed. titleObserver.waitForTitleUpdate(15);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/FocusedEditableTextFieldZoomTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/FocusedEditableTextFieldZoomTest.java index 82e1604..faa46e0 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/FocusedEditableTextFieldZoomTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/FocusedEditableTextFieldZoomTest.java
@@ -81,7 +81,7 @@ final ContentViewCore contentViewCore = tab.getContentViewCore(); float initialZoomLevel = contentViewCore.getScale(); - DOMUtils.clickNode(this, contentViewCore, TEXTFIELD_DOM_ID); + DOMUtils.clickNode(contentViewCore, TEXTFIELD_DOM_ID); // Wait for the zoom in to complete. waitForZoomIn(contentViewCore, initialZoomLevel); @@ -98,7 +98,7 @@ final float initialZoomLevel = contentViewCore.getScale(); // This should focus the text field and initiate a zoom in. - DOMUtils.clickNode(this, contentViewCore, TEXTFIELD_DOM_ID); + DOMUtils.clickNode(contentViewCore, TEXTFIELD_DOM_ID); // Wait for the zoom in to complete. waitForZoomIn(contentViewCore, initialZoomLevel);
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 2b1cce4..a7f403a 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/NavigateTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/NavigateTest.java
@@ -218,7 +218,7 @@ Tab tab = getActivity().getActivityTab(); - DOMUtils.clickNode(this, tab.getContentViewCore(), "aboutLink"); + DOMUtils.clickNode(tab.getContentViewCore(), "aboutLink"); ChromeTabUtils.waitForTabPageLoaded(tab, url2); assertEquals("Desired Link not open", url2, getActivity().getActivityTab().getUrl()); } @@ -246,7 +246,7 @@ }; Tab tab = getActivity().getActivityTab(); tab.addObserver(onPageLoadStartedObserver); - DOMUtils.clickNode(this, tab.getContentViewCore(), "aboutLink"); + DOMUtils.clickNode(tab.getContentViewCore(), "aboutLink"); ChromeTabUtils.waitForTabPageLoaded(tab, url2); assertEquals("Desired Link not open", url2, getActivity().getActivityTab().getUrl()); } @@ -417,7 +417,7 @@ assertWaitForPageScaleFactorMatch(0.5f); // Click the page, which triggers the URL load. - DOMUtils.clickNode(this, getActivity().getCurrentContentViewCore(), "body"); + DOMUtils.clickNode(getActivity().getCurrentContentViewCore(), "body"); // Wait for the proper URL to be served. assertTrue(urlServedSemaphore.tryAcquire(5, TimeUnit.SECONDS));
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/OSKOverscrollTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/OSKOverscrollTest.java index 77977d02f..5192e81 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/OSKOverscrollTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/OSKOverscrollTest.java
@@ -136,7 +136,7 @@ // Click on the unfocused input element for the first time to focus on it. This brings up // the OSK. - DOMUtils.clickNode(this, viewCoreRef.get(), "fn"); + DOMUtils.clickNode(viewCoreRef.get(), "fn"); waitForKeyboard();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/SelectFileDialogTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/SelectFileDialogTest.java index add8ecc..ac8125f 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/SelectFileDialogTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/SelectFileDialogTest.java
@@ -108,7 +108,7 @@ @RetryOnFailure public void testSelectFileAndCancelRequest() throws Throwable { { - DOMUtils.clickNode(this, mContentViewCore, "input_file"); + DOMUtils.clickNode(mContentViewCore, "input_file"); CriteriaHelper.pollInstrumentationThread(new IntentSentCriteria()); assertEquals( Intent.ACTION_CHOOSER, mActivityWindowAndroidForTest.lastIntent.getAction()); @@ -121,7 +121,7 @@ } { - DOMUtils.clickNode(this, mContentViewCore, "input_text"); + DOMUtils.clickNode(mContentViewCore, "input_text"); CriteriaHelper.pollInstrumentationThread(new IntentSentCriteria()); assertEquals( Intent.ACTION_CHOOSER, mActivityWindowAndroidForTest.lastIntent.getAction()); @@ -134,7 +134,7 @@ } { - DOMUtils.clickNode(this, mContentViewCore, "input_any"); + DOMUtils.clickNode(mContentViewCore, "input_any"); CriteriaHelper.pollInstrumentationThread(new IntentSentCriteria()); assertEquals( Intent.ACTION_CHOOSER, mActivityWindowAndroidForTest.lastIntent.getAction()); @@ -147,7 +147,7 @@ } { - DOMUtils.clickNode(this, mContentViewCore, "input_file_multiple"); + DOMUtils.clickNode(mContentViewCore, "input_file_multiple"); CriteriaHelper.pollInstrumentationThread(new IntentSentCriteria()); assertEquals( Intent.ACTION_CHOOSER, mActivityWindowAndroidForTest.lastIntent.getAction()); @@ -162,13 +162,13 @@ resetActivityWindowAndroidForTest(); } - DOMUtils.clickNode(this, mContentViewCore, "input_image"); + DOMUtils.clickNode(mContentViewCore, "input_image"); CriteriaHelper.pollInstrumentationThread(new IntentSentCriteria()); assertEquals(MediaStore.ACTION_IMAGE_CAPTURE, mActivityWindowAndroidForTest.lastIntent.getAction()); resetActivityWindowAndroidForTest(); - DOMUtils.clickNode(this, mContentViewCore, "input_audio"); + DOMUtils.clickNode(mContentViewCore, "input_audio"); CriteriaHelper.pollInstrumentationThread(new IntentSentCriteria()); assertEquals(MediaStore.Audio.Media.RECORD_SOUND_ACTION, mActivityWindowAndroidForTest.lastIntent.getAction());
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/TabsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/TabsTest.java index 9448ee1..390137ea 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/TabsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/TabsTest.java
@@ -305,7 +305,7 @@ getInstrumentation(), getActivity(), mTestServer.getURL(TEST_FILE_PATH), false); assertEquals("Failed to click node.", true, DOMUtils.clickNode( - this, getActivity().getActivityTab().getContentViewCore(), "input_text")); + getActivity().getActivityTab().getContentViewCore(), "input_text")); assertWaitForKeyboardStatus(true); // Open a new tab(the 2nd tab). @@ -314,7 +314,7 @@ assertWaitForKeyboardStatus(false); // Click node in the 2nd tab. - DOMUtils.clickNode(this, getActivity().getActivityTab().getContentViewCore(), "input_text"); + DOMUtils.clickNode(getActivity().getActivityTab().getContentViewCore(), "input_text"); assertWaitForKeyboardStatus(true); // Switch to the 1st tab. @@ -322,7 +322,7 @@ assertWaitForKeyboardStatus(false); // Click node in the 1st tab. - DOMUtils.clickNode(this, getActivity().getActivityTab().getContentViewCore(), "input_text"); + DOMUtils.clickNode(getActivity().getActivityTab().getContentViewCore(), "input_text"); assertWaitForKeyboardStatus(true); // Close current tab(the 1st tab). @@ -343,13 +343,12 @@ getInstrumentation(), getActivity(), mTestServer.getURL(TEST_FILE_PATH), false); assertEquals("Failed to click textarea.", true, DOMUtils.clickNode( - this, getActivity().getActivityTab().getContentViewCore(), "textarea")); + getActivity().getActivityTab().getContentViewCore(), "textarea")); assertWaitForKeyboardStatus(true); // Click the button to open a new window. assertEquals("Failed to click button.", true, - DOMUtils.clickNode( - this, getActivity().getActivityTab().getContentViewCore(), "button")); + DOMUtils.clickNode(getActivity().getActivityTab().getContentViewCore(), "button")); assertWaitForKeyboardStatus(false); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillKeyboardAccessoryTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillKeyboardAccessoryTest.java index eb38ed0..be60094 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillKeyboardAccessoryTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillKeyboardAccessoryTest.java
@@ -125,7 +125,7 @@ public void testTapInputFieldShowsKeyboardAccessory() throws ExecutionException, InterruptedException, TimeoutException { loadTestPage(false); - DOMUtils.clickNode(this, mViewCoreRef.get(), "fn"); + DOMUtils.clickNode(mViewCoreRef.get(), "fn"); CriteriaHelper.pollUiThread(new Criteria("Keyboard should be showing.") { @Override public boolean isSatisfied() { @@ -152,7 +152,7 @@ public void testSwitchFieldsRescrollsKeyboardAccessory() throws ExecutionException, InterruptedException, TimeoutException { loadTestPage(false); - DOMUtils.clickNode(this, mViewCoreRef.get(), "fn"); + DOMUtils.clickNode(mViewCoreRef.get(), "fn"); CriteriaHelper.pollUiThread(new Criteria("Keyboard should be showing.") { @Override public boolean isSatisfied() { @@ -179,7 +179,7 @@ } } }); - DOMUtils.clickNode(this, mViewCoreRef.get(), "ln"); + DOMUtils.clickNode(mViewCoreRef.get(), "ln"); CriteriaHelper.pollUiThread( new Criteria("First suggestion should be on the screen after switching fields.") { @Override @@ -203,7 +203,7 @@ public void testSwitchFieldsRescrollsKeyboardAccessoryRtl() throws ExecutionException, InterruptedException, TimeoutException { loadTestPage(true); - DOMUtils.clickNode(this, mViewCoreRef.get(), "fn"); + DOMUtils.clickNode(mViewCoreRef.get(), "fn"); CriteriaHelper.pollUiThread(new Criteria("Keyboard should be showing.") { @Override public boolean isSatisfied() { @@ -230,7 +230,7 @@ } } }); - DOMUtils.clickNode(this, mViewCoreRef.get(), "ln"); + DOMUtils.clickNode(mViewCoreRef.get(), "ln"); CriteriaHelper.pollUiThread( new Criteria("Last suggestion should be off the screen after switching fields.") { @Override @@ -256,7 +256,7 @@ public void testSelectSuggestionHidesKeyboardAccessory() throws ExecutionException, InterruptedException, TimeoutException { loadTestPage(false); - DOMUtils.clickNode(this, mViewCoreRef.get(), "fn"); + DOMUtils.clickNode(mViewCoreRef.get(), "fn"); CriteriaHelper.pollUiThread(new Criteria("Keyboard should be showing.") { @Override public boolean isSatisfied() {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillPopupTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillPopupTest.java index fc92e88..6f193c5 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillPopupTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillPopupTest.java
@@ -172,7 +172,7 @@ // Click the input field for the first name. DOMUtils.waitForNonZeroNodeBounds(webContents, "fn"); - DOMUtils.clickNode(this, viewCore, "fn"); + DOMUtils.clickNode(viewCore, "fn"); waitForKeyboardShowRequest(immw, 1);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillPopupWithKeyboardTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillPopupWithKeyboardTest.java index f8f8abd..3d29ccf 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillPopupWithKeyboardTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillPopupWithKeyboardTest.java
@@ -89,7 +89,7 @@ // Click on the unfocused input element for the first time to focus on it. This brings up // the autofill popup and shows the keyboard at the same time. Showing the keyboard should // not hide the autofill popup. - DOMUtils.clickNode(this, viewCoreRef.get(), "fn"); + DOMUtils.clickNode(viewCoreRef.get(), "fn"); // Wait until the keyboard is showing. CriteriaHelper.pollUiThread(new Criteria("Keyboard was never shown.") {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/overlays/strip/TabStripTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/overlays/strip/TabStripTest.java index 58dd3863..8fd60aa 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/overlays/strip/TabStripTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/overlays/strip/TabStripTest.java
@@ -746,7 +746,7 @@ public void testSwitchingTabsHidesKeyboard() throws Throwable { loadUrl("data:text/html;charset=utf-8,<html><head></head><body><form>" + "<input type='text' id='input0'></form></body></html>"); - DOMUtils.clickNode(this, getActivity().getActivityTab().getContentViewCore(), "input0"); + DOMUtils.clickNode(getActivity().getActivityTab().getContentViewCore(), "input0"); assertWaitForKeyboardStatus(true); getInstrumentation().waitForIdleSync();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ContextMenuTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ContextMenuTest.java index 2cd9ec8e..be2cf7e 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ContextMenuTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ContextMenuTest.java
@@ -203,7 +203,7 @@ @RetryOnFailure public void testDismissContextMenuOnBack() throws InterruptedException, TimeoutException { Tab tab = getActivity().getActivityTab(); - ContextMenu menu = ContextMenuUtils.openContextMenu(this, tab, "testImage"); + ContextMenu menu = ContextMenuUtils.openContextMenu(tab, "testImage"); assertNotNull("Context menu was not properly created", menu); CriteriaHelper.pollUiThread(new Criteria("Context menu did not have window focus") { @Override @@ -226,7 +226,7 @@ @RetryOnFailure public void testDismissContextMenuOnClick() throws InterruptedException, TimeoutException { Tab tab = getActivity().getActivityTab(); - ContextMenu menu = ContextMenuUtils.openContextMenu(this, tab, "testImage"); + ContextMenu menu = ContextMenuUtils.openContextMenu(tab, "testImage"); assertNotNull("Context menu was not properly created", menu); CriteriaHelper.pollUiThread(new Criteria("Context menu did not have window focus") { @Override @@ -291,7 +291,7 @@ public void testSaveVideo() throws InterruptedException, TimeoutException, SecurityException, IOException { // Click the video to enable playback - DOMUtils.clickNode(this, getActivity().getCurrentContentViewCore(), "videoDOMElement"); + DOMUtils.clickNode(getActivity().getCurrentContentViewCore(), "videoDOMElement"); saveMediaFromContextMenu("videoDOMElement", R.id.contextmenu_save_video, FILENAME_WEBM); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java index 4733aa1..096b76b 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java
@@ -201,7 +201,7 @@ public void longPressNodeWithoutWaiting(String nodeId) throws InterruptedException, TimeoutException { Tab tab = getActivity().getActivityTab(); - DOMUtils.longPressNode(this, tab.getContentViewCore(), nodeId); + DOMUtils.longPressNode(tab.getContentViewCore(), nodeId); } /** @@ -219,7 +219,7 @@ */ public void clickNode(String nodeId) throws InterruptedException, TimeoutException { Tab tab = getActivity().getActivityTab(); - DOMUtils.clickNode(this, tab.getContentViewCore(), nodeId); + DOMUtils.clickNode(tab.getContentViewCore(), nodeId); } /**
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java index 69286cae..4c239b6 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java
@@ -306,7 +306,7 @@ startCustomTabActivityWithIntent(createMinimalCustomTabIntent()); final int expectedMenuSize = 12; - Menu menu = ContextMenuUtils.openContextMenu(this, getActivity().getActivityTab(), "logo"); + Menu menu = ContextMenuUtils.openContextMenu(getActivity().getActivityTab(), "logo"); assertEquals(expectedMenuSize, menu.size()); assertNotNull(menu.findItem(R.id.contextmenu_copy_link_address)); @@ -347,8 +347,7 @@ startCustomTabActivityWithIntent(createMinimalCustomTabIntent()); final int expectedMenuSize = 12; - Menu menu = ContextMenuUtils.openContextMenu(this, getActivity().getActivityTab(), - "aboutLink"); + Menu menu = ContextMenuUtils.openContextMenu(getActivity().getActivityTab(), "aboutLink"); assertEquals(expectedMenuSize, menu.size()); assertNotNull(menu.findItem(R.id.contextmenu_copy_link_address)); @@ -388,7 +387,7 @@ startCustomTabActivityWithIntent(createMinimalCustomTabIntent()); final int expectedMenuSize = 12; - Menu menu = ContextMenuUtils.openContextMenu(this, getActivity().getActivityTab(), "email"); + Menu menu = ContextMenuUtils.openContextMenu(getActivity().getActivityTab(), "email"); assertEquals(expectedMenuSize, menu.size()); assertNotNull(menu.findItem(R.id.contextmenu_copy_link_address)); @@ -428,7 +427,7 @@ startCustomTabActivityWithIntent(createMinimalCustomTabIntent()); final int expectedMenuSize = 12; - Menu menu = ContextMenuUtils.openContextMenu(this, getActivity().getActivityTab(), "tel"); + Menu menu = ContextMenuUtils.openContextMenu(getActivity().getActivityTab(), "tel"); assertEquals(expectedMenuSize, menu.size()); assertNotNull(menu.findItem(R.id.contextmenu_copy_link_address)); @@ -672,8 +671,7 @@ } }); try { - DOMUtils.clickNode(CustomTabActivityTest.this, - getActivity().getActivityTab().getContentViewCore(), "select"); + DOMUtils.clickNode(getActivity().getActivityTab().getContentViewCore(), "select"); } catch (TimeoutException e) { fail(); } @@ -903,7 +901,7 @@ }); } }); - DOMUtils.clickNode(this, getActivity().getActivityTab().getContentViewCore(), "new_window"); + DOMUtils.clickNode(getActivity().getActivityTab().getContentViewCore(), "new_window"); openTabHelper.waitForCallback(0, 1); assertEquals("A new tab should have been created.", 2,
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/gsa/GSAAccountChangeListenerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/gsa/GSAAccountChangeListenerTest.java new file mode 100644 index 0000000..9e9aad4 --- /dev/null +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/gsa/GSAAccountChangeListenerTest.java
@@ -0,0 +1,78 @@ +// 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.gsa; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.support.test.filters.SmallTest; +import android.test.InstrumentationTestCase; + +import junit.framework.AssertionFailedError; + +import org.chromium.base.metrics.RecordHistogram; +import org.chromium.content.browser.test.util.Criteria; +import org.chromium.content.browser.test.util.CriteriaHelper; + +/** Tests for GSAAccountChangeListener. */ +public class GSAAccountChangeListenerTest extends InstrumentationTestCase { + private static final String ACCOUNT_NAME = "me@gmail.com"; + private static final String ACCOUNT_NAME2 = "you@gmail.com"; + private static final String PERMISSION = "permission.you.dont.have"; + + @Override + protected void setUp() throws Exception { + super.setUp(); + RecordHistogram.setDisabledForTests(true); + } + + @SmallTest + public void testReceivesBroadcastIntents() throws Exception { + final Context context = getInstrumentation().getTargetContext(); + BroadcastReceiver receiver = new GSAAccountChangeListener.AccountChangeBroadcastReceiver(); + context.registerReceiver(receiver, + new IntentFilter(GSAAccountChangeListener.ACCOUNT_UPDATE_BROADCAST_INTENT)); + + // Send a broadcast without the permission, should be received. + Intent intent = new Intent(); + intent.setPackage(context.getPackageName()); + intent.setAction(GSAAccountChangeListener.ACCOUNT_UPDATE_BROADCAST_INTENT); + intent.putExtra(GSAAccountChangeListener.BROADCAST_INTENT_ACCOUNT_NAME_EXTRA, ACCOUNT_NAME); + context.sendBroadcast(intent); + + CriteriaHelper.pollUiThread(new Criteria() { + @Override + public boolean isSatisfied() { + String currentAccount = + GSAState.getInstance(context.getApplicationContext()).getGsaAccount(); + return ACCOUNT_NAME.equals(currentAccount); + } + }); + + // A broadcast with a permission that Chrome doesn't hold should not be received. + context.registerReceiver(receiver, + new IntentFilter(GSAAccountChangeListener.ACCOUNT_UPDATE_BROADCAST_INTENT), + PERMISSION, null); + intent.putExtra( + GSAAccountChangeListener.BROADCAST_INTENT_ACCOUNT_NAME_EXTRA, ACCOUNT_NAME2); + context.sendBroadcast(intent, "permission.you.dont.have"); + + // This is ugly, but so is checking that some asynchronous call was never received. + try { + CriteriaHelper.pollUiThread(new Criteria() { + @Override + public boolean isSatisfied() { + String currentAccount = + GSAState.getInstance(context.getApplicationContext()).getGsaAccount(); + return ACCOUNT_NAME2.equals(currentAccount); + } + }, 1000, 100); + } catch (AssertionFailedError e) { + return; + } + fail("The broadcast was received."); + } +}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/input/SelectPopupOtherContentViewTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/input/SelectPopupOtherContentViewTest.java index 32415fab..3bb348c 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/input/SelectPopupOtherContentViewTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/input/SelectPopupOtherContentViewTest.java
@@ -78,7 +78,7 @@ final ContentViewCore viewCore = getActivity().getCurrentContentViewCore(); // Once clicked, the popup should show up. - DOMUtils.clickNode(this, viewCore, "select"); + DOMUtils.clickNode(viewCore, "select"); CriteriaHelper.pollInstrumentationThread(new PopupShowingCriteria()); // Now create and destroy a different ContentView.
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/media/remote/CastSwitchVideoTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/media/remote/CastSwitchVideoTest.java index 1833ea7..9f67628 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/media/remote/CastSwitchVideoTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/media/remote/CastSwitchVideoTest.java
@@ -174,7 +174,7 @@ waitUntilVideoReady(videoElement, webContents); // Need to click on the video first to overcome the user gesture requirement. - DOMUtils.clickNode(this, tab.getContentViewCore(), videoElement); + DOMUtils.clickNode(tab.getContentViewCore(), videoElement); DOMUtils.playMedia(webContents, videoElement); DOMUtils.waitForMediaPlay(webContents, videoElement); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestTestBase.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestTestBase.java index 9ad1f91c..9c3bbac 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestTestBase.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestTestBase.java
@@ -183,7 +183,7 @@ protected void clickNodeAndWait(String nodeId, CallbackHelper helper) throws InterruptedException, ExecutionException, TimeoutException { int callCount = helper.getCallCount(); - DOMUtils.clickNode(this, mViewCoreRef.get(), nodeId); + DOMUtils.clickNode(mViewCoreRef.get(), nodeId); helper.waitForCallback(callCount); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/datareduction/DataReductionPromoUtilsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/datareduction/DataReductionPromoUtilsTest.java index 8923d213..e24fb8a 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/datareduction/DataReductionPromoUtilsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/datareduction/DataReductionPromoUtilsTest.java
@@ -10,6 +10,7 @@ import org.chromium.base.ContextUtils; import org.chromium.base.test.util.AdvancedMockContext; +import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.Feature; import org.chromium.chrome.browser.net.spdyproxy.DataReductionProxySettings; import org.chromium.chrome.browser.preferences.PrefServiceBridge; @@ -40,8 +41,11 @@ */ @UiThreadTest @SmallTest + @CommandLineFlags.Add("force-fieldtrials=DataCompressionProxyPromoVisibility/Enabled") @Feature({"DataReduction"}) public void testCanShowPromos() { + if (DataReductionProxySettings.getInstance().isDataReductionProxyManaged()) return; + assertFalse(DataReductionProxySettings.getInstance().isDataReductionProxyEnabled()); assertTrue(DataReductionPromoUtils.canShowPromos()); DataReductionProxySettings.getInstance().setDataReductionProxyEnabled(mContext, true); assertFalse(DataReductionPromoUtils.canShowPromos());
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/tab/InterceptNavigationDelegateTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/tab/InterceptNavigationDelegateTest.java index 7a7791d..e4ac29c6 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/tab/InterceptNavigationDelegateTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/tab/InterceptNavigationDelegateTest.java
@@ -133,7 +133,7 @@ loadUrl(mTestServer.getURL(NAVIGATION_FROM_USER_GESTURE_PAGE)); assertEquals(1, mNavParamHistory.size()); - DOMUtils.clickNode(this, mActivity.getActivityTab().getContentViewCore(), "first"); + DOMUtils.clickNode(mActivity.getActivityTab().getContentViewCore(), "first"); waitTillExpectedCallsComplete(2, DEFAULT_MAX_TIME_TO_WAIT_IN_MS); assertTrue(mNavParamHistory.get(1).hasUserGesture); assertFalse(mNavParamHistory.get(1).hasUserGestureCarryover); @@ -144,7 +144,7 @@ loadUrl(mTestServer.getURL(NAVIGATION_FROM_XHR_CALLBACK_PAGE)); assertEquals(1, mNavParamHistory.size()); - DOMUtils.clickNode(this, mActivity.getActivityTab().getContentViewCore(), "first"); + DOMUtils.clickNode(mActivity.getActivityTab().getContentViewCore(), "first"); waitTillExpectedCallsComplete(2, DEFAULT_MAX_TIME_TO_WAIT_IN_MS); assertFalse(mNavParamHistory.get(1).hasUserGesture); assertTrue(mNavParamHistory.get(1).hasUserGestureCarryover); @@ -156,7 +156,7 @@ loadUrl(mTestServer.getURL(NAVIGATION_FROM_XHR_CALLBACK_AND_SHORT_TIMEOUT_PAGE)); assertEquals(1, mNavParamHistory.size()); - DOMUtils.clickNode(this, mActivity.getActivityTab().getContentViewCore(), "first"); + DOMUtils.clickNode(mActivity.getActivityTab().getContentViewCore(), "first"); waitTillExpectedCallsComplete(2, DEFAULT_MAX_TIME_TO_WAIT_IN_MS); assertFalse(mNavParamHistory.get(1).hasUserGesture); assertTrue(mNavParamHistory.get(1).hasUserGestureCarryover); @@ -169,7 +169,7 @@ mTestServer.getURL(NAVIGATION_FROM_XHR_CALLBACK_AND_LONG_TIMEOUT_PAGE)); assertEquals(1, mNavParamHistory.size()); - DOMUtils.clickNode(this, mActivity.getActivityTab().getContentViewCore(), "first"); + DOMUtils.clickNode(mActivity.getActivityTab().getContentViewCore(), "first"); waitTillExpectedCallsComplete(2, LONG_MAX_TIME_TO_WAIT_IN_MS); assertFalse(mNavParamHistory.get(1).hasUserGesture); assertFalse(mNavParamHistory.get(1).hasUserGestureCarryover); @@ -180,7 +180,7 @@ loadUrl(mTestServer.getURL(NAVIGATION_FROM_IMAGE_ONLOAD_PAGE)); assertEquals(1, mNavParamHistory.size()); - DOMUtils.clickNode(this, mActivity.getActivityTab().getContentViewCore(), "first"); + DOMUtils.clickNode(mActivity.getActivityTab().getContentViewCore(), "first"); waitTillExpectedCallsComplete(2, DEFAULT_MAX_TIME_TO_WAIT_IN_MS); assertFalse(mNavParamHistory.get(1).hasUserGesture); assertTrue(mNavParamHistory.get(1).hasUserGestureCarryover); @@ -191,7 +191,7 @@ loadUrl(mTestServer.getURL(NAVIGATION_FROM_USER_GESTURE_IFRAME_PAGE)); assertEquals(1, mNavParamHistory.size()); - DOMUtils.clickNode(this, mActivity.getActivityTab().getContentViewCore(), "first"); + DOMUtils.clickNode(mActivity.getActivityTab().getContentViewCore(), "first"); waitTillExpectedCallsComplete(3, DEFAULT_MAX_TIME_TO_WAIT_IN_MS); assertEquals(3, mExternalNavParamHistory.size());
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/tab/UndoIntegrationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/tab/UndoIntegrationTest.java index 974832d..1a36cf1 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/tab/UndoIntegrationTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/tab/UndoIntegrationTest.java
@@ -64,7 +64,7 @@ final Tab tab = TabModelUtils.getCurrentTab(model); // Clock on the link that will trigger a delayed window popup. - DOMUtils.clickNode(this, tab.getContentViewCore(), "link"); + DOMUtils.clickNode(tab.getContentViewCore(), "link"); // Attempt to close the tab, which will delay closing until the undo timeout goes away. ThreadUtils.runOnUiThreadBlocking(new Runnable() {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/video/VideoTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/video/VideoTest.java index 336ae01..75169f3 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/video/VideoTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/video/VideoTest.java
@@ -42,7 +42,7 @@ assertEquals("ready_to_play", tab.getTitle()); titleObserver = new TabTitleObserver(tab, "ended"); - DOMUtils.clickNode(this, tab.getContentViewCore(), "button1"); + DOMUtils.clickNode(tab.getContentViewCore(), "button1"); // Now the video will play for 5 secs. // Makes sure that the video ends and title was changed. titleObserver.waitForTitleUpdate(15);
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/ShortcutHelperTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/ShortcutHelperTest.java index 5cb75ee..aaec6160 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/ShortcutHelperTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/ShortcutHelperTest.java
@@ -6,11 +6,12 @@ import static org.junit.Assert.assertEquals; -import org.chromium.testing.local.LocalRobolectricTestRunner; import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.annotation.Config; +import org.chromium.testing.local.LocalRobolectricTestRunner; + /** * Unit tests for {@link org.chromium.chrome.browser.ShortcutHelper}. */ @@ -25,7 +26,7 @@ public void testGetScopeFromUrl() { String url1 = "https://www.google.com"; String url2 = "https://www.google.com/"; - String url3 = "https://www.google.com/maps"; + String url3 = "https://www.google.com/maps.htm"; String url4 = "https://www.google.com/maps/"; String url5 = "https://www.google.com/index.html"; String url6 = "https://www.google.com/index.html?q=maps"; @@ -35,22 +36,28 @@ String url10 = "https://www.google.com/maps/au/north/"; String url11 = "https://www.google.com/maps/au/index.html?q=maps#fragment/"; String url12 = "http://www.google.com:8000/maps/au/index.html?q=maps#fragment/"; + String url13 = "https://www.google.com/maps/au/north/?q=maps#fragment"; + String url14 = "https://www.google.com/maps/au/north?q=maps#fragment"; String url2_scope = "https://www.google.com/"; + String url4_scope = "https://www.google.com/maps/"; String url8_scope = "https://www.google.com/maps/au/"; + String url10_scope = "https://www.google.com/maps/au/north/"; String url12_scope = "http://www.google.com:8000/maps/au/"; assertEquals(url2_scope, ShortcutHelper.getScopeFromUrl(url1)); assertEquals(url2_scope, ShortcutHelper.getScopeFromUrl(url2)); assertEquals(url2_scope, ShortcutHelper.getScopeFromUrl(url3)); - assertEquals(url2_scope, ShortcutHelper.getScopeFromUrl(url4)); + assertEquals(url4_scope, ShortcutHelper.getScopeFromUrl(url4)); assertEquals(url2_scope, ShortcutHelper.getScopeFromUrl(url5)); assertEquals(url2_scope, ShortcutHelper.getScopeFromUrl(url6)); assertEquals(url2_scope, ShortcutHelper.getScopeFromUrl(url7)); assertEquals(url8_scope, ShortcutHelper.getScopeFromUrl(url8)); assertEquals(url8_scope, ShortcutHelper.getScopeFromUrl(url9)); - assertEquals(url8_scope, ShortcutHelper.getScopeFromUrl(url10)); + assertEquals(url10_scope, ShortcutHelper.getScopeFromUrl(url10)); assertEquals(url8_scope, ShortcutHelper.getScopeFromUrl(url11)); assertEquals(url12_scope, ShortcutHelper.getScopeFromUrl(url12)); + assertEquals(url10_scope, ShortcutHelper.getScopeFromUrl(url13)); + assertEquals(url8_scope, ShortcutHelper.getScopeFromUrl(url14)); } }
diff --git a/chrome/app/chrome_crash_reporter_client_win.cc b/chrome/app/chrome_crash_reporter_client_win.cc index b8d8e78..4cf02c7 100644 --- a/chrome/app/chrome_crash_reporter_client_win.cc +++ b/chrome/app/chrome_crash_reporter_client_win.cc
@@ -48,7 +48,6 @@ constexpr char kGPUPixelShaderVersion[] = "gpu-psver"; constexpr char kGPUVertexShaderVersion[] = "gpu-vsver"; -constexpr char kHungAudioThreadDetails[] = "hung-audio-thread-details"; constexpr char kHungRendererOutstandingAckCount[] = "hung-outstanding-acks"; constexpr char kHungRendererOutstandingEventType[] = "hung-outstanding-event-type"; @@ -127,7 +126,6 @@ {kInputEventFilterSendFailure, kSmallSize}, // media/: - {kHungAudioThreadDetails, kSmallSize}, {kZeroEncodeDetails, kSmallSize}, // gin/:
diff --git a/chrome/browser/app_controller_mac.mm b/chrome/browser/app_controller_mac.mm index 4f24834..84165c5d9 100644 --- a/chrome/browser/app_controller_mac.mm +++ b/chrome/browser/app_controller_mac.mm
@@ -799,7 +799,7 @@ // downloads page if the user chooses to wait. Browser* browser = chrome::FindBrowserWithProfile(profiles[i]); if (!browser) { - browser = new Browser(Browser::CreateParams(profiles[i])); + browser = new Browser(Browser::CreateParams(profiles[i], true)); browser->window()->Show(); } DCHECK(browser); @@ -1282,7 +1282,7 @@ Browser* browser = chrome::GetLastActiveBrowser(); // if no browser window exists then create one with no tabs to be filled in if (!browser) { - browser = new Browser(Browser::CreateParams([self lastProfile])); + browser = new Browser(Browser::CreateParams([self lastProfile], true)); browser->window()->Show(); }
diff --git a/chrome/browser/captive_portal/captive_portal_browsertest.cc b/chrome/browser/captive_portal/captive_portal_browsertest.cc index 57b22bd..74f4586 100644 --- a/chrome/browser/captive_portal/captive_portal_browsertest.cc +++ b/chrome/browser/captive_portal/captive_portal_browsertest.cc
@@ -2673,7 +2673,8 @@ // the background one. // Disabled: http://crbug.com/134357 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, DISABLED_TwoWindows) { - Browser* browser2 = new Browser(Browser::CreateParams(browser()->profile())); + Browser* browser2 = + new Browser(Browser::CreateParams(browser()->profile(), true)); // Navigate the new browser window so it'll be shown and we can pick the // active window. ui_test_utils::NavigateToURL(browser2, GURL(url::kAboutBlankURL));
diff --git a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc index 46883134..7681210 100644 --- a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc +++ b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
@@ -141,6 +141,7 @@ #include "components/version_info/version_info.h" #include "components/wallpaper/wallpaper_manager_base.h" #include "content/public/browser/browser_thread.h" +#include "content/public/browser/media_capture_devices.h" #include "content/public/browser/notification_service.h" #include "content/public/common/content_switches.h" #include "content/public/common/main_function_params.h" @@ -429,6 +430,9 @@ CrasAudioHandler::Initialize( new AudioDevicesPrefHandlerImpl(g_browser_process->local_state())); + content::MediaCaptureDevices::GetInstance()->AddVideoCaptureObserver( + CrasAudioHandler::Get()); + quirks::QuirksManager::Initialize( std::unique_ptr<quirks::QuirksManager::Delegate>( new quirks::QuirksManagerDelegateImpl()), @@ -930,6 +934,8 @@ // Stops all in-flight OAuth2 token fetchers before the IO thread stops. DeviceOAuth2TokenServiceFactory::Shutdown(); + content::MediaCaptureDevices::GetInstance()->RemoveAllVideoCaptureObservers(); + // Shutdown after PostMainMessageLoopRun() which should destroy all observers. CrasAudioHandler::Shutdown();
diff --git a/chrome/browser/chromeos/extensions/default_app_order.cc b/chrome/browser/chromeos/extensions/default_app_order.cc index 5d692b4d..8c6aa89 100644 --- a/chrome/browser/chromeos/extensions/default_app_order.cc +++ b/chrome/browser/chromeos/extensions/default_app_order.cc
@@ -13,13 +13,13 @@ #include "base/json/json_file_value_serializer.h" #include "base/macros.h" #include "base/path_service.h" +#include "base/task_scheduler/post_task.h" #include "base/time/time.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/chromeos/genius_app/app_id.h" #include "chrome/browser/ui/app_list/arc/arc_app_utils.h" #include "chrome/common/extensions/extension_constants.h" #include "chromeos/chromeos_paths.h" -#include "content/public/browser/browser_thread.h" #include "extensions/common/constants.h" namespace chromeos { @@ -132,7 +132,9 @@ loader_instance = this; if (async) { - content::BrowserThread::PostBlockingPoolTask(FROM_HERE, + base::PostTaskWithTraits( + FROM_HERE, base::TaskTraits().MayBlock().WithPriority( + base::TaskPriority::USER_VISIBLE), base::Bind(&ExternalLoader::Load, base::Unretained(this))); } else { Load();
diff --git a/chrome/browser/chromeos/extensions/info_private_api.cc b/chrome/browser/chromeos/extensions/info_private_api.cc index 3eb609e..c023ece9a 100644 --- a/chrome/browser/chromeos/extensions/info_private_api.cc +++ b/chrome/browser/chromeos/extensions/info_private_api.cc
@@ -135,6 +135,15 @@ // JS. const char kPlayStoreStatusEnabled[] = "enabled"; +// Key which corresponds to the managedDeviceStatus property in JS. +const char kPropertyManagedDeviceStatus[] = "managedDeviceStatus"; + +// Value to which managedDeviceStatus property is set for unmanaged devices. +const char kManagedDeviceStatusNotManaged[] = "not managed"; + +// Value to which managedDeviceStatus property is set for managed devices. +const char kManagedDeviceStatusManaged[] = "managed"; + const struct { const char* api_name; const char* preference_name; @@ -268,6 +277,15 @@ return new base::StringValue(kPlayStoreStatusNotAvailable); } + if (property_name == kPropertyManagedDeviceStatus) { + policy::BrowserPolicyConnectorChromeOS* connector = + g_browser_process->platform_part()->browser_policy_connector_chromeos(); + if (connector->IsEnterpriseManaged()) { + return new base::StringValue(kManagedDeviceStatusManaged); + } + return new base::StringValue(kManagedDeviceStatusNotManaged); + } + if (property_name == kPropertyClientId) { return new base::StringValue(GetClientId()); }
diff --git a/chrome/browser/chromeos/extensions/info_private_apitest.cc b/chrome/browser/chromeos/extensions/info_private_apitest.cc index 10fc352..7036c32 100644 --- a/chrome/browser/chromeos/extensions/info_private_apitest.cc +++ b/chrome/browser/chromeos/extensions/info_private_apitest.cc
@@ -4,7 +4,9 @@ #include "base/values.h" #include "chrome/browser/chromeos/arc/arc_util.h" +#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" #include "chrome/browser/chromeos/settings/cros_settings.h" +#include "chrome/browser/chromeos/settings/stub_install_attributes.h" #include "chrome/browser/extensions/extension_apitest.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/pref_names.h" @@ -112,3 +114,29 @@ "arc available")) << message_; } + +class ChromeOSManagedDeviceInfoPrivateTest : public ChromeOSInfoPrivateTest { + public: + ChromeOSManagedDeviceInfoPrivateTest() = default; + ~ChromeOSManagedDeviceInfoPrivateTest() override = default; + + protected: + void SetUpInProcessBrowserTestFixture() override { + // Set up fake install attributes. + std::unique_ptr<chromeos::StubInstallAttributes> attributes = + base::MakeUnique<chromeos::StubInstallAttributes>(); + attributes->SetEnterprise("fake-domain", "fake-id"); + policy::BrowserPolicyConnectorChromeOS::SetInstallAttributesForTesting( + attributes.release()); + ChromeOSInfoPrivateTest::SetUpInProcessBrowserTestFixture(); + } + + private: + DISALLOW_COPY_AND_ASSIGN(ChromeOSManagedDeviceInfoPrivateTest); +}; + +IN_PROC_BROWSER_TEST_F(ChromeOSManagedDeviceInfoPrivateTest, Managed) { + ASSERT_TRUE( + RunPlatformAppTestWithArg("chromeos_info_private/extended", "managed")) + << message_; +}
diff --git a/chrome/browser/chromeos/first_run/goodies_displayer_browsertest.cc b/chrome/browser/chromeos/first_run/goodies_displayer_browsertest.cc index cf849b1..e19be6e 100644 --- a/chrome/browser/chromeos/first_run/goodies_displayer_browsertest.cc +++ b/chrome/browser/chromeos/first_run/goodies_displayer_browsertest.cc
@@ -33,7 +33,7 @@ // Create a new browser and wait for completion. ui_test_utils::BrowserAddedObserver browser_added_observer; Browser* browser = new Browser( - Browser::CreateParams(ProfileManager::GetActiveUserProfile())); + Browser::CreateParams(ProfileManager::GetActiveUserProfile(), true)); browser_added_observer.WaitForSingleNewBrowser(); // Set up Goodies Displayer and set fake age of device. @@ -124,8 +124,8 @@ ASSERT_EQ(1u, chrome::GetTotalBrowserCount()); // Shouldn't show Goodies tab in incognito mode. - Browser* incognito_browser = new Browser( - Browser::CreateParams(browser->profile()->GetOffTheRecordProfile())); + Browser* incognito_browser = new Browser(Browser::CreateParams( + browser->profile()->GetOffTheRecordProfile(), true)); ASSERT_EQ(2u, chrome::GetTotalBrowserCount()); AddBlankTabAndShow(incognito_browser); ExpectTabCounts(incognito_browser, 1, 0);
diff --git a/chrome/browser/chromeos/login/quick_unlock/quick_unlock_notification_controller.cc b/chrome/browser/chromeos/login/quick_unlock/quick_unlock_notification_controller.cc index d3b7cc16..c4750353 100644 --- a/chrome/browser/chromeos/login/quick_unlock/quick_unlock_notification_controller.cc +++ b/chrome/browser/chromeos/login/quick_unlock/quick_unlock_notification_controller.cc
@@ -10,6 +10,7 @@ #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/chromeos/login/quick_unlock/pin_storage.h" #include "chrome/browser/chromeos/login/quick_unlock/pin_storage_factory.h" +#include "chrome/browser/chromeos/login/quick_unlock/quick_unlock_utils.h" #include "chrome/browser/notifications/notification.h" #include "chrome/browser/notifications/notification_ui_manager.h" #include "chrome/browser/profiles/profile.h" @@ -24,22 +25,15 @@ #include "ui/base/resource/resource_bundle.h" #include "ui/strings/grit/ui_strings.h" -namespace { - -const char kDelegateId[] = "quickunlock_delegate"; -const char kNotificationId[] = "quickunlock_notification"; -const char kChromeAuthenticationSettingsURL[] = - "chrome://md-settings/quickUnlock/authenticate"; - -void UpdatePreferenceForProfile(Profile* profile) { - PrefService* pref_service = profile->GetPrefs(); - pref_service->SetBoolean(prefs::kQuickUnlockFeatureNotificationShown, true); -} - -} // namespace - namespace chromeos { namespace quick_unlock { +namespace { + +constexpr char kPinDelegateId[] = "pinunlock_delegate"; +constexpr char kPinNotificationId[] = "pinunlock_notification"; +constexpr char kPinSetupUrl[] = "chrome://md-settings/lockScreen"; + +} // namespace QuickUnlockNotificationController::QuickUnlockNotificationController( Profile* profile) @@ -53,9 +47,34 @@ } // static -// TODO(http://crbug.com/291747): Add check for a policy that might disable -// quick unlock. -bool QuickUnlockNotificationController::ShouldShow(Profile* profile) { +QuickUnlockNotificationController* +QuickUnlockNotificationController::CreateForPin(Profile* profile) { + QuickUnlockNotificationController* controller = + new QuickUnlockNotificationController(profile); + + // Set the PIN notification parameters. + controller->params_.delegate_id = kPinDelegateId; + controller->params_.title_message_id = + IDS_ASH_QUICK_UNLOCK_NOTIFICATION_TITLE; + controller->params_.body_message_id = IDS_ASH_QUICK_UNLOCK_NOTIFICATION_BODY; + controller->params_.icon_id = IDR_SCREENSHOT_NOTIFICATION_ICON; + controller->params_.notifier = ash::system_notifier::kNotifierQuickUnlock; + controller->params_.feature_name_id = + IDS_MESSAGE_CENTER_NOTIFIER_QUICK_UNLOCK_FEATURE_NAME; + controller->params_.notification_id = kPinNotificationId; + controller->params_.url = GURL(kPinSetupUrl); + controller->params_.was_shown_pref_id = + prefs::kQuickUnlockFeatureNotificationShown; + + controller->should_show_notification_callback_ = + base::Bind(&QuickUnlockNotificationController::ShouldShowPinNotification); + + return controller; +} + +// static +bool QuickUnlockNotificationController::ShouldShowPinNotification( + Profile* profile) { // Do not show notification if this is a guest session. if (profile->IsGuestSession()) return false; @@ -66,6 +85,11 @@ return false; } + // Do not show notification if policy does not allow PIN, or if user is + // supervised. + if (!IsPinEnabled(profile->GetPrefs())) + return false; + // Do not show the notification if the pin is already set. PinStorage* pin_storage = PinStorageFactory::GetForProfile(profile); if (pin_storage->IsPinSet()) @@ -77,7 +101,7 @@ // NotificationDelegate override: std::string QuickUnlockNotificationController::id() const { - return kDelegateId; + return params_.delegate_id; } void QuickUnlockNotificationController::Observe( @@ -98,38 +122,42 @@ // The user may have enabled the quick unlock feature during the current // session and after the notificaiton controller has already been initialized. - if (!ShouldShow(profile_)) { - UpdatePreferenceForProfile(profile_); + DCHECK(!should_show_notification_callback_.is_null()); + if (should_show_notification_callback_.Run(profile_)) { + SetNotificationPreferenceWasShown(); return; } - // Create and add notification to notification manager. - std::unique_ptr<Notification> notification(CreateNotification()); + std::unique_ptr<Notification> notification = CreateNotification(); g_browser_process->notification_ui_manager()->Add(*notification, profile_); } // message_center::NotificationDelegate override: void QuickUnlockNotificationController::Close(bool by_user) { if (by_user) - UpdatePreferenceForProfile(profile_); + SetNotificationPreferenceWasShown(); } // message_center::NotificationDelegate override: void QuickUnlockNotificationController::Click() { - chrome::NavigateParams params(profile_, - GURL(kChromeAuthenticationSettingsURL), + chrome::NavigateParams params(profile_, params_.url, ui::PAGE_TRANSITION_LINK); params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB; params.window_action = chrome::NavigateParams::SHOW_WINDOW; chrome::Navigate(¶ms); - UpdatePreferenceForProfile(profile_); + SetNotificationPreferenceWasShown(); // Remove the notification from tray. g_browser_process->notification_ui_manager()->CancelById( id(), NotificationUIManager::GetProfileID(profile_)); } +void QuickUnlockNotificationController::SetNotificationPreferenceWasShown() { + PrefService* pref_service = profile_->GetPrefs(); + pref_service->SetBoolean(params_.was_shown_pref_id, true); +} + void QuickUnlockNotificationController::UnregisterObserver() { if (registrar_.IsRegistered(this, chrome::NOTIFICATION_SCREEN_LOCK_STATE_CHANGED, @@ -139,21 +167,24 @@ } } -Notification* QuickUnlockNotificationController::CreateNotification() { - return new Notification( +std::unique_ptr<Notification> +QuickUnlockNotificationController::CreateNotification() { + return base::MakeUnique<Notification>( message_center::NOTIFICATION_TYPE_SIMPLE, - l10n_util::GetStringUTF16(IDS_ASH_QUICK_UNLOCK_NOTIFICATION_TITLE), - l10n_util::GetStringUTF16(IDS_ASH_QUICK_UNLOCK_NOTIFICATION_BODY), + l10n_util::GetStringUTF16(params_.title_message_id), + l10n_util::GetStringUTF16(params_.body_message_id), // TODO(http://crbug.com/291747): Change this to actual icon for // quick unlock feature notification. - ui::ResourceBundle::GetSharedInstance().GetImageNamed( - IDR_SCREENSHOT_NOTIFICATION_ICON), + ui::ResourceBundle::GetSharedInstance().GetImageNamed(params_.icon_id), message_center::NotifierId(message_center::NotifierId::SYSTEM_COMPONENT, - ash::system_notifier::kNotifierQuickUnlock), - l10n_util::GetStringUTF16( - IDS_MESSAGE_CENTER_NOTIFIER_QUICK_UNLOCK_FEATURE_NAME), - GURL(), kNotificationId, message_center::RichNotificationData(), this); + params_.notifier), + l10n_util::GetStringUTF16(params_.feature_name_id), GURL(), + params_.notification_id, message_center::RichNotificationData(), this); } -} // namespace quick_unlock +QuickUnlockNotificationController::NotificationParams::NotificationParams() {} + +QuickUnlockNotificationController::NotificationParams::~NotificationParams() {} + +} // quick_unlock } // namespace chromeos
diff --git a/chrome/browser/chromeos/login/quick_unlock/quick_unlock_notification_controller.h b/chrome/browser/chromeos/login/quick_unlock/quick_unlock_notification_controller.h index d72eaa1..eb93f6b 100644 --- a/chrome/browser/chromeos/login/quick_unlock/quick_unlock_notification_controller.h +++ b/chrome/browser/chromeos/login/quick_unlock/quick_unlock_notification_controller.h
@@ -10,9 +10,10 @@ #include "chrome/browser/notifications/notification_delegate.h" #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_registrar.h" +#include "url/gurl.h" -class Profile; class Notification; +class Profile; namespace chromeos { namespace quick_unlock { @@ -22,30 +23,54 @@ class QuickUnlockNotificationController : public NotificationDelegate, public content::NotificationObserver { public: - explicit QuickUnlockNotificationController(Profile* profile); + static QuickUnlockNotificationController* CreateForPin(Profile* profile); // Returns true if the notification needs to be displayed for the given // |profile|. - static bool ShouldShow(Profile* profile); + static bool ShouldShowPinNotification(Profile* profile); - // content::NotificationObserver implementation. + // content::NotificationObserver: void Observe(int type, const content::NotificationSource& source, const content::NotificationDetails& details) override; private: + // Parameters that differ between two quick unlock notifications. + struct NotificationParams { + NotificationParams(); + ~NotificationParams(); + + std::string delegate_id; + int title_message_id; + int body_message_id; + int icon_id; + std::string notifier; + int feature_name_id; + std::string notification_id; + GURL url; + std::string was_shown_pref_id; + + private: + DISALLOW_COPY_AND_ASSIGN(NotificationParams); + }; + + explicit QuickUnlockNotificationController(Profile* profile); ~QuickUnlockNotificationController() override; - // NotificationDelegate overrides: + // NotificationDelegate: void Close(bool by_user) override; void Click() override; std::string id() const override; - Notification* CreateNotification(); + std::unique_ptr<Notification> CreateNotification(); + void SetNotificationPreferenceWasShown(); void UnregisterObserver(); Profile* profile_; content::NotificationRegistrar registrar_; + NotificationParams params_; + // Function that determines whether this notification should be shown or not. + base::Callback<bool(Profile*)> should_show_notification_callback_; DISALLOW_COPY_AND_ASSIGN(QuickUnlockNotificationController); };
diff --git a/chrome/browser/chromeos/login/saml/saml_browsertest.cc b/chrome/browser/chromeos/login/saml/saml_browsertest.cc index 630b1d2..8b7336e9a 100644 --- a/chrome/browser/chromeos/login/saml/saml_browsertest.cc +++ b/chrome/browser/chromeos/login/saml/saml_browsertest.cc
@@ -41,6 +41,8 @@ #include "chrome/browser/chromeos/policy/proto/chrome_device_policy.pb.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/chromeos/settings/cros_settings.h" +#include "chrome/browser/content_settings/host_content_settings_map_factory.h" +#include "chrome/browser/media/webrtc/media_permission.h" #include "chrome/browser/policy/test/local_policy_test_server.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/webui/signin/signin_utils.h" @@ -61,6 +63,8 @@ #include "chromeos/dbus/shill_manager_client.h" #include "chromeos/login/auth/key.h" #include "chromeos/settings/cros_settings_names.h" +#include "components/content_settings/core/browser/host_content_settings_map.h" +#include "components/content_settings/core/common/content_settings_types.h" #include "components/guest_view/browser/test_guest_view_manager.h" #include "components/policy/core/browser/browser_policy_connector.h" #include "components/policy/core/common/mock_configuration_policy_provider.h" @@ -960,6 +964,7 @@ void SetSAMLOfflineSigninTimeLimitPolicy(int limit); void EnableTransferSAMLCookiesPolicy(); void SetLoginBehaviorPolicyToSAMLInterstitial(); + void SetLoginVideoCaptureAllowedUrls(const std::vector<GURL>& allowed); void ShowGAIALoginForm(); void ShowSAMLInterstitial(); @@ -1095,6 +1100,23 @@ run_loop.Run(); } +void SAMLPolicyTest::SetLoginVideoCaptureAllowedUrls( + const std::vector<GURL>& allowed) { + em::ChromeDeviceSettingsProto& proto(device_policy_->payload()); + for (const GURL& url : allowed) + proto.mutable_login_video_capture_allowed_urls()->add_urls(url.spec()); + + base::RunLoop run_loop; + std::unique_ptr<CrosSettings::ObserverSubscription> observer = + CrosSettings::Get()->AddSettingsObserver(kLoginVideoCaptureAllowedUrls, + run_loop.QuitClosure()); + device_policy_->SetDefaultSigningKey(); + device_policy_->Build(); + fake_session_manager_client_->set_device_policy(device_policy_->GetBlob()); + fake_session_manager_client_->OnPropertyChangeComplete(true); + run_loop.Run(); +} + void SAMLPolicyTest::ShowGAIALoginForm() { login_screen_load_observer_->Wait(); ASSERT_TRUE(content::ExecuteScript( @@ -1406,4 +1428,61 @@ session_start_waiter.Wait(); } +// Ensure that the permission status of getUserMedia requests from SAML login +// pages is controlled by the kLoginVideoCaptureAllowedUrls pref rather than the +// underlying user content setting. +IN_PROC_BROWSER_TEST_F(SAMLPolicyTest, TestLoginMediaPermission) { + fake_saml_idp()->SetLoginHTMLTemplate("saml_login.html"); + + const GURL url1("https://google.com"); + const GURL url2("https://example.com"); + const GURL url3("https://not-allowed.com"); + SetLoginVideoCaptureAllowedUrls({url1, url2}); + WaitForSigninScreen(); + + content::WebContents* web_contents = GetLoginUI()->GetWebContents(); + Profile* profile = + Profile::FromBrowserContext(web_contents->GetBrowserContext()); + content::MediaStreamRequestResult reason; + + // Mic should always be blocked. + { + MediaPermission permission(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC, url1, + url1, profile, web_contents); + EXPECT_EQ(CONTENT_SETTING_BLOCK, permission.GetPermissionStatus(&reason)); + } + + // Camera should be allowed if allowed by the whitelist, otherwise blocked. + { + MediaPermission permission(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, url1, + url1, profile, web_contents); + EXPECT_EQ(CONTENT_SETTING_ALLOW, permission.GetPermissionStatus(&reason)); + } + + { + MediaPermission permission(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, url2, + url2, profile, web_contents); + EXPECT_EQ(CONTENT_SETTING_ALLOW, permission.GetPermissionStatus(&reason)); + } + + { + MediaPermission permission(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, url3, + url3, profile, web_contents); + EXPECT_EQ(CONTENT_SETTING_BLOCK, permission.GetPermissionStatus(&reason)); + } + + // Camera should be blocked in the login screen, even if it's allowed via + // content setting. + { + HostContentSettingsMapFactory::GetForProfile(profile) + ->SetContentSettingDefaultScope( + url3, url3, CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, std::string(), + CONTENT_SETTING_ALLOW); + + MediaPermission permission(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, url3, + url3, profile, web_contents); + EXPECT_EQ(CONTENT_SETTING_BLOCK, permission.GetPermissionStatus(&reason)); + } +} + } // namespace chromeos
diff --git a/chrome/browser/chromeos/login/session/user_session_manager.cc b/chrome/browser/chromeos/login/session/user_session_manager.cc index 2a78309..b304a280 100644 --- a/chrome/browser/chromeos/login/session/user_session_manager.cc +++ b/chrome/browser/chromeos/login/session/user_session_manager.cc
@@ -1775,11 +1775,12 @@ if (HatsNotificationController::ShouldShowSurveyToProfile(profile)) hats_notification_controller_ = new HatsNotificationController(profile); - if (quick_unlock::QuickUnlockNotificationController::ShouldShow(profile) && + if (quick_unlock::QuickUnlockNotificationController:: + ShouldShowPinNotification(profile) && quick_unlock_notification_handler_.find(profile) == quick_unlock_notification_handler_.end()) { auto* qu_feature_notification_controller = - new quick_unlock::QuickUnlockNotificationController(profile); + quick_unlock::QuickUnlockNotificationController::CreateForPin(profile); quick_unlock_notification_handler_.insert( std::make_pair(profile, qu_feature_notification_controller)); }
diff --git a/chrome/browser/chromeos/login/ui/webui_login_view.cc b/chrome/browser/chromeos/login/ui/webui_login_view.cc index 83d3f302..dd302079 100644 --- a/chrome/browser/chromeos/login/ui/webui_login_view.cc +++ b/chrome/browser/chromeos/login/ui/webui_login_view.cc
@@ -27,7 +27,6 @@ #include "chrome/browser/chromeos/login/ui/web_contents_set_background_color.h" #include "chrome/browser/chromeos/login/ui/webui_login_display.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" -#include "chrome/browser/chromeos/settings/cros_settings.h" #include "chrome/browser/extensions/chrome_extension_web_contents_observer.h" #include "chrome/browser/media/webrtc/media_capture_devices_dispatcher.h" #include "chrome/browser/media/webrtc/media_stream_devices_controller.h" @@ -42,7 +41,6 @@ #include "chromeos/dbus/session_manager_client.h" #include "chromeos/network/network_state.h" #include "chromeos/network/network_state_handler.h" -#include "chromeos/settings/cros_settings_names.h" #include "components/content_settings/core/common/content_settings_pattern.h" #include "components/password_manager/core/browser/password_manager.h" #include "components/web_modal/web_contents_modal_dialog_manager.h" @@ -478,46 +476,9 @@ WebContents* web_contents, const content::MediaStreamRequest& request, const content::MediaResponseCallback& callback) { + // Note: This is only needed for SAML logins. MediaStreamDevicesController controller(web_contents, request, callback); - if (!controller.IsAskingForAudio() && !controller.IsAskingForVideo()) - return; - - if (controller.IsAskingForAudio()) { - controller.PermissionDenied(); - return; - } - - const CrosSettings* const settings = CrosSettings::Get(); - if (!settings) { - controller.PermissionDenied(); - return; - } - - const base::Value* const raw_list_value = - settings->GetPref(kLoginVideoCaptureAllowedUrls); - if (!raw_list_value) { - controller.PermissionDenied(); - return; - } - - const base::ListValue* list_value; - CHECK(raw_list_value->GetAsList(&list_value)); - for (const auto& base_value : *list_value) { - std::string value; - if (base_value->GetAsString(&value)) { - ContentSettingsPattern pattern = - ContentSettingsPattern::FromString(value); - if (pattern == ContentSettingsPattern::Wildcard()) { - LOG(WARNING) << "Ignoring wildcard URL pattern: " << value; - continue; - } - if (pattern.IsValid() && pattern.Matches(request.security_origin)) { - controller.PermissionGranted(); - return; - } - } - } - controller.PermissionDenied(); + DCHECK(!controller.IsAskingForAudio() && !controller.IsAskingForVideo()); } bool WebUILoginView::CheckMediaAccessPermission(
diff --git a/chrome/browser/chromeos/printing/cups_print_job_manager_impl.cc b/chrome/browser/chromeos/printing/cups_print_job_manager_impl.cc index 875592b..468adc4 100644 --- a/chrome/browser/chromeos/printing/cups_print_job_manager_impl.cc +++ b/chrome/browser/chromeos/printing/cups_print_job_manager_impl.cc
@@ -120,33 +120,14 @@ DCHECK(document); CreatePrintJob(base::UTF16ToUTF8(document->settings().device_name()), base::UTF16ToUTF8(document->settings().title()), - document->page_count()); + job_details->job_id(), document->page_count()); } } bool CupsPrintJobManagerImpl::CreatePrintJob(const std::string& printer_name, const std::string& title, + int job_id, int total_page_number) { - // Of the current jobs, find the new one for the printer. - ::printing::CupsJob* new_job = nullptr; - std::vector<::printing::CupsJob> cups_jobs = cups_connection_.GetJobs(); - for (auto& job : cups_jobs) { - if (printer_name == job.printer_id && - !JobFinished(ConvertState(job.state)) && - !base::ContainsKey(jobs_, - CupsPrintJob::GetUniqueId(printer_name, job.id))) { - // We found an untracked job. It should be ours. - new_job = &job; - break; - } - } - - // The started job cannot be found in the queue. - if (!new_job) { - LOG(WARNING) << "Could not track print job."; - return false; - } - auto printer = chromeos::PrintersManagerFactory::GetForBrowserContext(profile_) ->GetPrinter(printer_name); @@ -157,25 +138,35 @@ } // Create a new print job. - auto cpj = base::MakeUnique<CupsPrintJob>(*printer, new_job->id, title, + auto cpj = base::MakeUnique<CupsPrintJob>(*printer, job_id, title, total_page_number); std::string key = cpj->GetUniqueId(); jobs_[key] = std::move(cpj); - NotifyJobCreated(jobs_[key].get()); + CupsPrintJob* job = jobs_[key].get(); + NotifyJobCreated(job); - JobStateUpdated(jobs_[key].get(), ConvertState(new_job->state)); + // Always start jobs in the waiting state. + job->set_state(CupsPrintJob::State::STATE_WAITING); + NotifyJobUpdated(job); - ScheduleQuery(); + ScheduleQuery(base::TimeDelta()); return true; } void CupsPrintJobManagerImpl::ScheduleQuery() { - content::BrowserThread::PostDelayedTask( - content::BrowserThread::FILE_USER_BLOCKING, FROM_HERE, - base::Bind(&CupsPrintJobManagerImpl::QueryCups, - weak_ptr_factory_.GetWeakPtr()), - base::TimeDelta::FromMilliseconds(kPollRate)); + ScheduleQuery(base::TimeDelta::FromMilliseconds(kPollRate)); +} + +void CupsPrintJobManagerImpl::ScheduleQuery(const base::TimeDelta& delay) { + if (!in_query_) { + in_query_ = true; + content::BrowserThread::PostDelayedTask( + content::BrowserThread::FILE_USER_BLOCKING, FROM_HERE, + base::Bind(&CupsPrintJobManagerImpl::QueryCups, + weak_ptr_factory_.GetWeakPtr()), + base::TimeDelta::FromMilliseconds(kPollRate)); + } } // Query CUPS asynchronously. Post results back to UI thread. @@ -193,6 +184,9 @@ // after they are completed. void CupsPrintJobManagerImpl::UpdateJobs( const std::vector<::printing::CupsJob>& jobs) { + in_query_ = false; + + std::vector<std::string> active_jobs; for (auto& job : jobs) { std::string key = CupsPrintJob::GetUniqueId(job.printer_id, job.id); const auto& entry = jobs_.find(key); @@ -205,13 +199,26 @@ // Cleanup completed jobs. if (JobFinished(print_job->state())) { jobs_.erase(entry); + } else { + active_jobs.push_back(key); } } } // Keep polling until all jobs complete or error. - if (!jobs_.empty()) + if (!active_jobs.empty()) { ScheduleQuery(); + } else if (!jobs_.empty()) { + // We're tracking jobs that we didn't receive an update for. Something bad + // has happened. + LOG(ERROR) << "Lost track of (" << jobs_.size() << ") jobs"; + for (const auto& entry : jobs_) { + // Declare all lost jobs errors. + JobStateUpdated(entry.second.get(), CupsPrintJob::State::STATE_ERROR); + } + + jobs_.clear(); + } } void CupsPrintJobManagerImpl::JobStateUpdated(CupsPrintJob* job,
diff --git a/chrome/browser/chromeos/printing/cups_print_job_manager_impl.h b/chrome/browser/chromeos/printing/cups_print_job_manager_impl.h index 04f0cdb..afd64c9 100644 --- a/chrome/browser/chromeos/printing/cups_print_job_manager_impl.h +++ b/chrome/browser/chromeos/printing/cups_print_job_manager_impl.h
@@ -44,10 +44,13 @@ // |title| with the pages |total_page_number|. bool CreatePrintJob(const std::string& printer_name, const std::string& title, + int job_id, int total_page_number); - // Schedule a query of CUPS for print job status. + // Schedule a query of CUPS for print job status with the default delay. void ScheduleQuery(); + // Schedule a query of CUPS for print job status with a delay of |delay|. + void ScheduleQuery(const base::TimeDelta& delay); // Query CUPS for print job status. void QueryCups(); @@ -61,6 +64,9 @@ // Ongoing print jobs. std::map<std::string, std::unique_ptr<CupsPrintJob>> jobs_; + // Prevents multiple queries from being scheduled simultaneously. + bool in_query_ = false; + ::printing::CupsConnection cups_connection_; content::NotificationRegistrar registrar_; base::WeakPtrFactory<CupsPrintJobManagerImpl> weak_ptr_factory_;
diff --git a/chrome/browser/devtools/devtools_ui_bindings.cc b/chrome/browser/devtools/devtools_ui_bindings.cc index 2e4b828..f0e0d5f 100644 --- a/chrome/browser/devtools/devtools_ui_bindings.cc +++ b/chrome/browser/devtools/devtools_ui_bindings.cc
@@ -1262,6 +1262,14 @@ if (extensions::chrome_manifest_urls::GetDevToolsPage(extension.get()) .is_empty()) continue; + + // Each devtools extension will need to be able to run in the devtools + // process. Grant each specific extension's origin permission to load + // documents. + content::ChildProcessSecurityPolicy::GetInstance()->GrantOrigin( + web_contents_->GetMainFrame()->GetProcess()->GetID(), + url::Origin(extension->url())); + std::unique_ptr<base::DictionaryValue> extension_info( new base::DictionaryValue()); extension_info->Set( @@ -1275,14 +1283,6 @@ extensions::APIPermission::kExperimental))); results.Append(std::move(extension_info)); } - if (!results.empty()) { - // At least one devtools extension exists; it will need to run in the - // devtools process. Grant it permission to load documents with - // chrome-extension:// origins. - content::ChildProcessSecurityPolicy::GetInstance()->GrantScheme( - web_contents_->GetMainFrame()->GetProcess()->GetID(), - extensions::kExtensionScheme); - } CallClientFunction("DevToolsAPI.addExtensions", &results, NULL, NULL);
diff --git a/chrome/browser/download/download_browsertest.cc b/chrome/browser/download/download_browsertest.cc index 98193c9..a8f8f84 100644 --- a/chrome/browser/download/download_browsertest.cc +++ b/chrome/browser/download/download_browsertest.cc
@@ -3425,9 +3425,7 @@ sb_service->download_protection_service(); download_protection_service->feedback_service()->MaybeStorePingsForDownload( safe_browsing::DownloadProtectionService::UNCOMMON, - downloads[0], - ping_request, - ping_response); + true /* upload_requested */, downloads[0], ping_request, ping_response); ASSERT_TRUE(safe_browsing::DownloadFeedbackService::IsEnabledForDownload( *(downloads[0]))); @@ -3478,8 +3476,8 @@ safe_browsing::DownloadProtectionService* download_protection_service = sb_service->download_protection_service(); download_protection_service->feedback_service()->MaybeStorePingsForDownload( - safe_browsing::DownloadProtectionService::UNCOMMON, downloads[0], - ping_request, ping_response); + safe_browsing::DownloadProtectionService::UNCOMMON, + true /* upload_requested */, downloads[0], ping_request, ping_response); ASSERT_TRUE(safe_browsing::DownloadFeedbackService::IsEnabledForDownload( *(downloads[0])));
diff --git a/chrome/browser/download/download_crx_util.cc b/chrome/browser/download/download_crx_util.cc index a7fa2a7..c2fcb83 100644 --- a/chrome/browser/download/download_crx_util.cc +++ b/chrome/browser/download/download_crx_util.cc
@@ -49,9 +49,10 @@ content::WebContents* web_contents = download_item.GetWebContents(); if (!web_contents) { Browser* browser = chrome::FindLastActiveWithProfile(profile); - if (!browser) - browser = - new Browser(Browser::CreateParams(Browser::TYPE_TABBED, profile)); + if (!browser) { + browser = new Browser( + Browser::CreateParams(Browser::TYPE_TABBED, profile, true)); + } web_contents = browser->tab_strip_model()->GetActiveWebContents(); } return std::unique_ptr<ExtensionInstallPrompt>(
diff --git a/chrome/browser/extensions/api/autofill_private/autofill_util.cc b/chrome/browser/extensions/api/autofill_private/autofill_util.cc index dc02e19..aebbb40 100644 --- a/chrome/browser/extensions/api/autofill_private/autofill_util.cc +++ b/chrome/browser/extensions/api/autofill_private/autofill_util.cc
@@ -7,6 +7,7 @@ #include <stddef.h> #include <utility> +#include <vector> #include "base/memory/ptr_util.h" #include "base/strings/string_split.h" @@ -14,12 +15,12 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/extensions/api/settings_private/prefs_util.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/autofill/country_combobox_model.h" #include "chrome/common/extensions/api/autofill_private.h" #include "chrome/common/pref_names.h" #include "components/autofill/core/browser/autofill_country.h" #include "components/autofill/core/browser/autofill_profile.h" #include "components/autofill/core/browser/autofill_type.h" +#include "components/autofill/core/browser/country_combobox_model.h" #include "components/autofill/core/browser/credit_card.h" #include "components/autofill/core/browser/field_types.h" #include "components/prefs/pref_service.h" @@ -190,7 +191,8 @@ CountryEntryList GenerateCountryList( const autofill::PersonalDataManager& personal_data) { autofill::CountryComboboxModel model; - model.SetCountries(personal_data, base::Callback<bool(const std::string&)>()); + model.SetCountries(personal_data, base::Callback<bool(const std::string&)>(), + g_browser_process->GetApplicationLocale()); const std::vector<std::unique_ptr<autofill::AutofillCountry>>& countries = model.countries();
diff --git a/chrome/browser/extensions/api/browser/browser_api.cc b/chrome/browser/extensions/api/browser/browser_api.cc index 205d583..f9f133b 100644 --- a/chrome/browser/extensions/api/browser/browser_api.cc +++ b/chrome/browser/extensions/api/browser/browser_api.cc
@@ -24,7 +24,7 @@ std::string error; std::unique_ptr<base::DictionaryValue> result( - ExtensionTabUtil::OpenTab(this, options, &error)); + ExtensionTabUtil::OpenTab(this, options, user_gesture(), &error)); if (!result) return RespondNow(Error(error));
diff --git a/chrome/browser/extensions/api/debugger/debugger_apitest.cc b/chrome/browser/extensions/api/debugger/debugger_apitest.cc index acf5b62..b2447222 100644 --- a/chrome/browser/extensions/api/debugger/debugger_apitest.cc +++ b/chrome/browser/extensions/api/debugger/debugger_apitest.cc
@@ -195,7 +195,8 @@ scoped_refptr<DebuggerAttachFunction> attach_function; scoped_refptr<DebuggerDetachFunction> detach_function; - Browser* another_browser = new Browser(Browser::CreateParams(profile())); + Browser* another_browser = + new Browser(Browser::CreateParams(profile(), true)); AddBlankTabAndShow(another_browser); AddBlankTabAndShow(another_browser); int tab_id2 = SessionTabHelper::IdForTab(
diff --git a/chrome/browser/extensions/api/developer_private/developer_private_api_unittest.cc b/chrome/browser/extensions/api/developer_private/developer_private_api_unittest.cc index a03451c..5e70782d 100644 --- a/chrome/browser/extensions/api/developer_private/developer_private_api_unittest.cc +++ b/chrome/browser/extensions/api/developer_private/developer_private_api_unittest.cc
@@ -304,7 +304,7 @@ InitializeExtensionService(init_params); browser_window_.reset(new TestBrowserWindow()); - Browser::CreateParams params(profile()); + Browser::CreateParams params(profile(), true); params.type = Browser::TYPE_TABBED; params.window = browser_window_.get(); browser_.reset(new Browser(params));
diff --git a/chrome/browser/extensions/api/extension_action/browser_action_apitest.cc b/chrome/browser/extensions/api/extension_action/browser_action_apitest.cc index 876abcc..2d57dda 100644 --- a/chrome/browser/extensions/api/extension_action/browser_action_apitest.cc +++ b/chrome/browser/extensions/api/extension_action/browser_action_apitest.cc
@@ -542,7 +542,7 @@ Profile* incognito_profile = browser()->profile()->GetOffTheRecordProfile(); base::RunLoop().RunUntilIdle(); // Wait for profile initialization. Browser* incognito_browser = - new Browser(Browser::CreateParams(incognito_profile)); + new Browser(Browser::CreateParams(incognito_profile, true)); ASSERT_EQ(0, BrowserActionTestUtil(incognito_browser).NumberOfBrowserActions()); @@ -576,7 +576,7 @@ // Open an incognito window. Profile* incognito_profile = browser()->profile()->GetOffTheRecordProfile(); Browser* incognito_browser = - new Browser(Browser::CreateParams(incognito_profile)); + new Browser(Browser::CreateParams(incognito_profile, true)); base::RunLoop().RunUntilIdle(); // Wait for profile initialization. // Navigate just to have a tab in this window, otherwise wonky things happen. OpenURLOffTheRecord(browser()->profile(), GURL("about:blank"));
diff --git a/chrome/browser/extensions/api/gcd_private/gcd_private_apitest.cc b/chrome/browser/extensions/api/gcd_private/gcd_private_apitest.cc index 52a6820..d948ac1e 100644 --- a/chrome/browser/extensions/api/gcd_private/gcd_private_apitest.cc +++ b/chrome/browser/extensions/api/gcd_private/gcd_private_apitest.cc
@@ -90,6 +90,7 @@ command_line->AppendSwitchASCII( extensions::switches::kWhitelistedExtensionID, "ddchlicdkolnonkihahngkmmmjnjlkkf"); + command_line->AppendSwitch(switches::kDisableDeviceDiscoveryNotifications); } std::unique_ptr<net::FakeURLFetcher> CreateFakeURLFetcher( @@ -142,8 +143,7 @@ test_service_discovery_client_; }; -// Flaky on Linux(dbg). https://crbug.com/689305 -IN_PROC_BROWSER_TEST_F(GcdPrivateWithMdnsAPITest, DISABLED_DeviceInfo) { +IN_PROC_BROWSER_TEST_F(GcdPrivateWithMdnsAPITest, DeviceInfo) { test_service_discovery_client_->SimulateReceive(kAnnouncePacket, sizeof(kAnnouncePacket)); url_fetcher_factory_.SetFakeResponse(GURL("http://1.2.3.4:8888/privet/info"),
diff --git a/chrome/browser/extensions/api/log_private/log_private_apitest_chromeos.cc b/chrome/browser/extensions/api/log_private/log_private_apitest_chromeos.cc index 6a9d490..245cff89 100644 --- a/chrome/browser/extensions/api/log_private/log_private_apitest_chromeos.cc +++ b/chrome/browser/extensions/api/log_private/log_private_apitest_chromeos.cc
@@ -7,11 +7,11 @@ #include "base/files/file_path.h" #include "base/files/file_util.h" +#include "base/task_scheduler/post_task.h" #include "chrome/browser/extensions/extension_apitest.h" #include "chrome/common/chrome_switches.h" #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/fake_debug_daemon_client.h" -#include "content/public/browser/browser_thread.h" #include "extensions/common/extension_builder.h" #include "net/dns/mock_host_resolver.h" #include "net/test/embedded_test_server/embedded_test_server.h" @@ -36,9 +36,10 @@ const GetDebugLogsCallback& callback) override { // dup() is needed as the file descriptor will be closed on the client side. base::File* file_param = new base::File(dup(file_descriptor)); - content::BrowserThread::PostBlockingPoolTaskAndReply( - FROM_HERE, base::Bind(&GenerateTestLogDumpFile, test_file_, - base::Owned(file_param)), + base::PostTaskWithTraitsAndReply( + FROM_HERE, base::TaskTraits().MayBlock(), + base::Bind(&GenerateTestLogDumpFile, test_file_, + base::Owned(file_param)), base::Bind(callback, true)); }
diff --git a/chrome/browser/extensions/api/management/management_api_unittest.cc b/chrome/browser/extensions/api/management/management_api_unittest.cc index 26b4f6a..59d0593 100644 --- a/chrome/browser/extensions/api/management/management_api_unittest.cc +++ b/chrome/browser/extensions/api/management/management_api_unittest.cc
@@ -93,7 +93,7 @@ &BuildEventRouter); browser_window_.reset(new TestBrowserWindow()); - Browser::CreateParams params(profile()); + Browser::CreateParams params(profile(), true); params.type = Browser::TYPE_TABBED; params.window = browser_window_.get(); browser_.reset(new Browser(params));
diff --git a/chrome/browser/extensions/api/permissions/permissions_api_unittest.cc b/chrome/browser/extensions/api/permissions/permissions_api_unittest.cc index caa46e7..28b9010 100644 --- a/chrome/browser/extensions/api/permissions/permissions_api_unittest.cc +++ b/chrome/browser/extensions/api/permissions/permissions_api_unittest.cc
@@ -74,7 +74,7 @@ ExtensionServiceTestWithInstall::SetUp(); InitializeEmptyExtensionService(); browser_window_.reset(new TestBrowserWindow()); - Browser::CreateParams params(profile()); + Browser::CreateParams params(profile(), true); params.type = Browser::TYPE_TABBED; params.window = browser_window_.get(); browser_.reset(new Browser(params));
diff --git a/chrome/browser/extensions/api/runtime/chrome_runtime_api_delegate.cc b/chrome/browser/extensions/api/runtime/chrome_runtime_api_delegate.cc index 1f9948c2..54395bd 100644 --- a/chrome/browser/extensions/api/runtime/chrome_runtime_api_delegate.cc +++ b/chrome/browser/extensions/api/runtime/chrome_runtime_api_delegate.cc
@@ -258,7 +258,7 @@ Profile* profile = Profile::FromBrowserContext(browser_context_); Browser* browser = chrome::FindLastActiveWithProfile(profile); if (!browser) - browser = new Browser(Browser::CreateParams(profile)); + browser = new Browser(Browser::CreateParams(profile, false)); chrome::NavigateParams params( browser, uninstall_url, ui::PAGE_TRANSITION_CLIENT_REDIRECT);
diff --git a/chrome/browser/extensions/api/sessions/sessions_apitest.cc b/chrome/browser/extensions/api/sessions/sessions_apitest.cc index 9abe2ef..a0e02b7 100644 --- a/chrome/browser/extensions/api/sessions/sessions_apitest.cc +++ b/chrome/browser/extensions/api/sessions/sessions_apitest.cc
@@ -235,7 +235,7 @@ EXPECT_CALL(*service, AddObserver(testing::_)).Times(testing::AnyNumber()); EXPECT_CALL(*service, RemoveObserver(testing::_)).Times(testing::AnyNumber()); - browser_ = new Browser(Browser::CreateParams(profile)); + browser_ = new Browser(Browser::CreateParams(profile, true)); service->Initialize(); }
diff --git a/chrome/browser/extensions/api/tabs/tabs_api.cc b/chrome/browser/extensions/api/tabs/tabs_api.cc index 325a624..0f50871 100644 --- a/chrome/browser/extensions/api/tabs/tabs_api.cc +++ b/chrome/browser/extensions/api/tabs/tabs_api.cc
@@ -589,13 +589,15 @@ #endif // defined(USE_ASH) // Create a new BrowserWindow. - Browser::CreateParams create_params(window_type, window_profile); + Browser::CreateParams create_params(window_type, window_profile, + user_gesture()); if (extension_id.empty()) { create_params.initial_bounds = window_bounds; } else { create_params = Browser::CreateParams::CreateForApp( web_app::GenerateApplicationNameFromExtensionId(extension_id), - false /* trusted_source */, window_bounds, window_profile); + false /* trusted_source */, window_bounds, window_profile, + user_gesture()); } create_params.initial_show_state = ui::SHOW_STATE_NORMAL; if (create_data && create_data->state) { @@ -1004,7 +1006,7 @@ std::string error; std::unique_ptr<base::DictionaryValue> result( - ExtensionTabUtil::OpenTab(this, options, &error)); + ExtensionTabUtil::OpenTab(this, options, user_gesture(), &error)); if (!result) return RespondNow(Error(error));
diff --git a/chrome/browser/extensions/api/tabs/tabs_api_unittest.cc b/chrome/browser/extensions/api/tabs/tabs_api_unittest.cc index 1128010..26a3e9c 100644 --- a/chrome/browser/extensions/api/tabs/tabs_api_unittest.cc +++ b/chrome/browser/extensions/api/tabs/tabs_api_unittest.cc
@@ -68,7 +68,7 @@ content::BrowserSideNavigationSetUp(); browser_window_.reset(new TestBrowserWindow()); - Browser::CreateParams params(profile()); + Browser::CreateParams params(profile(), true); params.type = Browser::TYPE_TABBED; params.window = browser_window_.get(); browser_.reset(new Browser(params));
diff --git a/chrome/browser/extensions/api/tabs/tabs_test.cc b/chrome/browser/extensions/api/tabs/tabs_test.cc index 5df6a2a4..c519fd0 100644 --- a/chrome/browser/extensions/api/tabs/tabs_test.cc +++ b/chrome/browser/extensions/api/tabs/tabs_test.cc
@@ -173,7 +173,7 @@ // Popup. Browser* popup_browser = new Browser( - Browser::CreateParams(Browser::TYPE_POPUP, browser()->profile())); + Browser::CreateParams(Browser::TYPE_POPUP, browser()->profile(), true)); function = new WindowsGetFunction(); function->set_extension(extension.get()); result.reset(utils::ToDictionary( @@ -644,7 +644,7 @@ // a new tab in it. Tab should not be opened in the popup window, but in a // tabbed browser window. Browser* popup_browser = new Browser( - Browser::CreateParams(Browser::TYPE_POPUP, browser()->profile())); + Browser::CreateParams(Browser::TYPE_POPUP, browser()->profile(), true)); int window_id = ExtensionTabUtil::GetWindowId(popup_browser); chrome::CloseWindow(popup_browser); @@ -868,9 +868,10 @@ Browser* new_browser; if (as_popup) new_browser = new Browser( - Browser::CreateParams(Browser::TYPE_POPUP, browser()->profile())); + Browser::CreateParams(Browser::TYPE_POPUP, browser()->profile(), true)); else - new_browser = new Browser(Browser::CreateParams(browser()->profile())); + new_browser = + new Browser(Browser::CreateParams(browser()->profile(), true)); AddBlankTabAndShow(new_browser); return new_browser; } @@ -1255,7 +1256,7 @@ " \"maxWidth\": 400, \"maxHeight\": 400}}"); Browser* browser_window = - new Browser(Browser::CreateParams(browser()->profile())); + new Browser(Browser::CreateParams(browser()->profile(), true)); AddBlankTabAndShow(browser_window); DevToolsWindow* devtools_window =
diff --git a/chrome/browser/extensions/api/web_navigation/web_navigation_api.cc b/chrome/browser/extensions/api/web_navigation/web_navigation_api.cc index 3feaa460..2616a756 100644 --- a/chrome/browser/extensions/api/web_navigation/web_navigation_api.cc +++ b/chrome/browser/extensions/api/web_navigation/web_navigation_api.cc
@@ -383,7 +383,8 @@ const GURL& url, const content::Referrer& referrer, WindowOpenDisposition disposition, - ui::PageTransition transition) { + ui::PageTransition transition, + bool started_from_context_menu) { if (!navigation_state_.CanSendEvents(source_render_frame_host)) return;
diff --git a/chrome/browser/extensions/api/web_navigation/web_navigation_api.h b/chrome/browser/extensions/api/web_navigation/web_navigation_api.h index c663e68..e467d996 100644 --- a/chrome/browser/extensions/api/web_navigation/web_navigation_api.h +++ b/chrome/browser/extensions/api/web_navigation/web_navigation_api.h
@@ -68,7 +68,8 @@ const GURL& url, const content::Referrer& referrer, WindowOpenDisposition disposition, - ui::PageTransition transition) override; + ui::PageTransition transition, + bool started_from_context_menu) override; void WebContentsDestroyed() override; // This method dispatches the already created onBeforeNavigate event.
diff --git a/chrome/browser/extensions/extension_context_menu_model_unittest.cc b/chrome/browser/extensions/extension_context_menu_model_unittest.cc index fe073222..93b27ce 100644 --- a/chrome/browser/extensions/extension_context_menu_model_unittest.cc +++ b/chrome/browser/extensions/extension_context_menu_model_unittest.cc
@@ -183,7 +183,7 @@ Browser* ExtensionContextMenuModelTest::GetBrowser() { if (!browser_) { - Browser::CreateParams params(profile()); + Browser::CreateParams params(profile(), true); test_window_.reset(new TestBrowserWindow()); params.window = test_window_.get(); browser_.reset(new Browser(params));
diff --git a/chrome/browser/extensions/extension_tab_util.cc b/chrome/browser/extensions/extension_tab_util.cc index 9e28e8c..602c473 100644 --- a/chrome/browser/extensions/extension_tab_util.cc +++ b/chrome/browser/extensions/extension_tab_util.cc
@@ -95,8 +95,11 @@ return NULL; } -Browser* CreateBrowser(Profile* profile, int window_id, std::string* error) { - Browser::CreateParams params(Browser::TYPE_TABBED, profile); +Browser* CreateBrowser(Profile* profile, + int window_id, + bool user_gesture, + std::string* error) { + Browser::CreateParams params(Browser::TYPE_TABBED, profile, user_gesture); Browser* browser = new Browser(params); browser->window()->Show(); return browser; @@ -126,6 +129,7 @@ base::DictionaryValue* ExtensionTabUtil::OpenTab( UIThreadExtensionFunction* function, const OpenTabParams& params, + bool user_gesture, std::string* error) { ChromeExtensionFunctionDetails chrome_details(function); Profile* profile = chrome_details.GetProfile(); @@ -139,7 +143,7 @@ if (!params.create_browser_if_needed) { return NULL; } - browser = CreateBrowser(profile, window_id, error); + browser = CreateBrowser(profile, window_id, user_gesture, error); if (!browser) return NULL; } @@ -215,8 +219,9 @@ browser = chrome::FindTabbedBrowser(profile, false); if (!browser) { - browser = - new Browser(Browser::CreateParams(Browser::TYPE_TABBED, profile)); + Browser::CreateParams params = + Browser::CreateParams(Browser::TYPE_TABBED, profile, user_gesture); + browser = new Browser(params); browser->window()->Show(); } } @@ -583,8 +588,10 @@ Profile::FromBrowserContext(web_contents->GetBrowserContext()); Browser* browser = chrome::FindTabbedBrowser(profile, false); const bool browser_created = !browser; - if (!browser) - browser = new Browser(Browser::CreateParams(profile)); + if (!browser) { + Browser::CreateParams params = Browser::CreateParams(profile, user_gesture); + browser = new Browser(params); + } chrome::NavigateParams params(browser, web_contents); // The extension_app_id parameter ends up as app_name in the Browser @@ -636,7 +643,7 @@ DCHECK(!profile->IsOffTheRecord() || IncognitoInfo::IsSplitMode(extension)); Browser* browser = chrome::FindBrowserWithProfile(profile); if (!browser) - browser = new Browser(Browser::CreateParams(profile)); + browser = new Browser(Browser::CreateParams(profile, true)); return extensions::ExtensionTabUtil::OpenOptionsPage(extension, browser); }
diff --git a/chrome/browser/extensions/extension_tab_util.h b/chrome/browser/extensions/extension_tab_util.h index 06dac73a..40107b3 100644 --- a/chrome/browser/extensions/extension_tab_util.h +++ b/chrome/browser/extensions/extension_tab_util.h
@@ -58,6 +58,7 @@ // optionally sets |error| if an error occurs. static base::DictionaryValue* OpenTab(UIThreadExtensionFunction* function, const OpenTabParams& params, + bool user_gesture, std::string* error); static int GetWindowId(const Browser* browser);
diff --git a/chrome/browser/icon_loader_chromeos.cc b/chrome/browser/icon_loader_chromeos.cc index 52ae44d7..30f0005 100644 --- a/chrome/browser/icon_loader_chromeos.cc +++ b/chrome/browser/icon_loader_chromeos.cc
@@ -192,7 +192,9 @@ // static content::BrowserThread::ID IconLoader::ReadIconThreadID() { - return content::BrowserThread::FILE; + // ReadIcon touches non thread safe ResourceBundle images, so it must be on + // the UI thread. + return content::BrowserThread::UI; } void IconLoader::ReadIcon() {
diff --git a/chrome/browser/media/webrtc/media_permission.cc b/chrome/browser/media/webrtc/media_permission.cc index 278f7ed..064d4ae 100644 --- a/chrome/browser/media/webrtc/media_permission.cc +++ b/chrome/browser/media/webrtc/media_permission.cc
@@ -11,18 +11,32 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/common/pref_names.h" #include "content/public/browser/permission_manager.h" +#include "content/public/browser/web_contents.h" #include "content/public/common/url_constants.h" #include "extensions/common/constants.h" #include "third_party/WebKit/public/platform/modules/permissions/permission_status.mojom.h" +#if defined(OS_CHROMEOS) +#include "chrome/browser/chromeos/login/ui/login_display_host.h" +#include "chrome/browser/chromeos/login/ui/webui_login_view.h" +#include "chrome/browser/chromeos/settings/cros_settings.h" +#include "chromeos/settings/cros_settings_names.h" +#endif + MediaPermission::MediaPermission(ContentSettingsType content_type, const GURL& requesting_origin, const GURL& embedding_origin, - Profile* profile) + Profile* profile, + content::WebContents* web_contents) : content_type_(content_type), requesting_origin_(requesting_origin), embedding_origin_(embedding_origin), - profile_(profile) {} + profile_(profile), + web_contents_(web_contents) { + // Currently |web_contents_| is only used on ChromeOS but it's not worth + // #ifdef'ing out all its usage, so just mark it used here. + (void)web_contents_; +} ContentSetting MediaPermission::GetPermissionStatus( content::MediaStreamRequestResult* denial_reason) const { @@ -41,6 +55,56 @@ return CONTENT_SETTING_BLOCK; } +#if defined(OS_CHROMEOS) + // Special permissions if the request is coming from a ChromeOS login page. + chromeos::LoginDisplayHost* login_display_host = + chromeos::LoginDisplayHost::default_host(); + chromeos::WebUILoginView* webui_login_view = + login_display_host ? login_display_host->GetWebUILoginView() : nullptr; + content::WebContents* login_web_contents = + webui_login_view ? webui_login_view->GetWebContents() : nullptr; + if (web_contents_ == login_web_contents) { + if (content_type_ == CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC) { + *denial_reason = content::MEDIA_DEVICE_PERMISSION_DENIED; + return CONTENT_SETTING_BLOCK; + } + + const chromeos::CrosSettings* const settings = + chromeos::CrosSettings::Get(); + if (!settings) { + *denial_reason = content::MEDIA_DEVICE_PERMISSION_DENIED; + return CONTENT_SETTING_BLOCK; + } + + const base::Value* const raw_list_value = + settings->GetPref(chromeos::kLoginVideoCaptureAllowedUrls); + if (!raw_list_value) { + *denial_reason = content::MEDIA_DEVICE_PERMISSION_DENIED; + return CONTENT_SETTING_BLOCK; + } + + const base::ListValue* list_value; + const bool is_list = raw_list_value->GetAsList(&list_value); + DCHECK(is_list); + for (const auto& base_value : *list_value) { + std::string value; + if (base_value->GetAsString(&value)) { + const ContentSettingsPattern pattern = + ContentSettingsPattern::FromString(value); + if (pattern == ContentSettingsPattern::Wildcard()) { + LOG(WARNING) << "Ignoring wildcard URL pattern: " << value; + continue; + } + if (pattern.IsValid() && pattern.Matches(requesting_origin_)) + return CONTENT_SETTING_ALLOW; + } + } + + *denial_reason = content::MEDIA_DEVICE_PERMISSION_DENIED; + return CONTENT_SETTING_BLOCK; + } +#endif // defined(OS_CHROMEOS) + // Check policy and content settings. blink::mojom::PermissionStatus status = permission_manager->GetPermissionStatus(
diff --git a/chrome/browser/media/webrtc/media_permission.h b/chrome/browser/media/webrtc/media_permission.h index 708ae39..1ab5471 100644 --- a/chrome/browser/media/webrtc/media_permission.h +++ b/chrome/browser/media/webrtc/media_permission.h
@@ -15,13 +15,18 @@ class Profile; +namespace content { +class WebContents; +} + // Represents a permission for microphone/camera access. class MediaPermission { public: MediaPermission(ContentSettingsType content_type, const GURL& requesting_origin, const GURL& embedding_origin, - Profile* profile); + Profile* profile, + content::WebContents* web_contents); // Returns the status of the permission. If the setting is // CONTENT_SETTING_BLOCK, |denial_reason| will output the reason for it being @@ -43,6 +48,7 @@ const GURL embedding_origin_; const std::string device_id_; Profile* const profile_; + content::WebContents* const web_contents_; DISALLOW_COPY_AND_ASSIGN(MediaPermission); };
diff --git a/chrome/browser/media/webrtc/media_stream_devices_controller.cc b/chrome/browser/media/webrtc/media_stream_devices_controller.cc index cccf4f8..bd1228f 100644 --- a/chrome/browser/media/webrtc/media_stream_devices_controller.cc +++ b/chrome/browser/media/webrtc/media_stream_devices_controller.cc
@@ -546,7 +546,8 @@ DCHECK(content::IsOriginSecure(request_.security_origin) || request_.request_type == content::MEDIA_OPEN_DEVICE_PEPPER_ONLY); MediaPermission permission(content_type, request.security_origin, - web_contents_->GetLastCommittedURL().GetOrigin(), profile_); + web_contents_->GetLastCommittedURL().GetOrigin(), + profile_, web_contents_); return permission.GetPermissionStatusWithDeviceRequired(requested_device_id, denial_reason); }
diff --git a/chrome/browser/media/webrtc/permission_bubble_media_access_handler.cc b/chrome/browser/media/webrtc/permission_bubble_media_access_handler.cc index 0f68772..6911a3a3 100644 --- a/chrome/browser/media/webrtc/permission_bubble_media_access_handler.cc +++ b/chrome/browser/media/webrtc/permission_bubble_media_access_handler.cc
@@ -104,7 +104,7 @@ MediaPermission permission(content_settings_type, security_origin, web_contents->GetLastCommittedURL().GetOrigin(), - profile); + profile, web_contents); content::MediaStreamRequestResult unused; return permission.GetPermissionStatus(&unused) == CONTENT_SETTING_ALLOW; }
diff --git a/chrome/browser/media/webrtc/tab_desktop_media_list_unittest.cc b/chrome/browser/media/webrtc/tab_desktop_media_list_unittest.cc index 5f5d501e..3ad2de00 100644 --- a/chrome/browser/media/webrtc/tab_desktop_media_list_unittest.cc +++ b/chrome/browser/media/webrtc/tab_desktop_media_list_unittest.cc
@@ -171,7 +171,7 @@ ASSERT_TRUE(profile_); // Create browser. - Browser::CreateParams profile_params(profile_); + Browser::CreateParams profile_params(profile_, true); browser_ = chrome::CreateBrowserWithTestWindowForParams(&profile_params); ASSERT_TRUE(browser_); for (int i = 0; i < kDefaultSourceCount; i++) {
diff --git a/chrome/browser/media_galleries/chromeos/mtp_device_delegate_impl_chromeos.cc b/chrome/browser/media_galleries/chromeos/mtp_device_delegate_impl_chromeos.cc index cc07c690..f7bf8fb 100644 --- a/chrome/browser/media_galleries/chromeos/mtp_device_delegate_impl_chromeos.cc +++ b/chrome/browser/media_galleries/chromeos/mtp_device_delegate_impl_chromeos.cc
@@ -23,6 +23,7 @@ #include "base/strings/string_number_conversions.h" #include "base/strings/string_split.h" #include "base/strings/string_util.h" +#include "base/task_scheduler/post_task.h" #include "chrome/browser/media_galleries/chromeos/mtp_device_task_helper_map_service.h" #include "chrome/browser/media_galleries/chromeos/snapshot_file_details.h" #include "net/base/io_buffer.h" @@ -349,9 +350,11 @@ // Deletes a temporary file |file_path|. void DeleteTemporaryFile(const base::FilePath& file_path) { - content::BrowserThread::PostBlockingPoolTask( - FROM_HERE, base::Bind(base::IgnoreResult(base::DeleteFile), file_path, - false /* not recursive*/)); + base::PostTaskWithTraits(FROM_HERE, + base::TaskTraits().MayBlock().WithPriority( + base::TaskPriority::BACKGROUND), + base::Bind(base::IgnoreResult(base::DeleteFile), + file_path, false /* not recursive*/)); } // A fake callback to be passed as CopyFileProgressCallback.
diff --git a/chrome/browser/metrics/metrics_service_browsertest.cc b/chrome/browser/metrics/metrics_service_browsertest.cc index a51ede4..c371d73 100644 --- a/chrome/browser/metrics/metrics_service_browsertest.cc +++ b/chrome/browser/metrics/metrics_service_browsertest.cc
@@ -58,6 +58,15 @@ } // namespace #endif // OS_MACOSX || OS_LINUX +// This test class verifies that metrics reporting works correctly for various +// renderer behaviors such as page loads, recording crashed tabs, and browser +// starts. It also verifies that if a renderer process crashes, the correct exit +// code is recorded. +// +// TODO(isherman): We should also verify that +// metrics::prefs::kStabilityExitedCleanly is set correctly after each of these +// tests, but this preference isn't set until the browser exits... it's not +// clear to me how to test that. class MetricsServiceBrowserTest : public InProcessBrowserTest { public: void SetUpCommandLine(base::CommandLine* command_line) override { @@ -65,8 +74,39 @@ command_line->AppendSwitch(switches::kMetricsRecordingOnly); } + // Open three tabs then navigate to |crashy_url| and wait for the renderer to + // crash. + void OpenTabsAndNavigateToCrashyUrl(const std::string& crashy_url) { + // Opens three tabs. + OpenThreeTabs(); + + // Kill the process for one of the tabs by navigating to |crashy_url|. + content::RenderProcessHostWatcher observer( + browser()->tab_strip_model()->GetActiveWebContents(), + content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT); + // Opens one tab. + ui_test_utils::NavigateToURL(browser(), GURL(crashy_url)); + observer.Wait(); + + // The MetricsService listens for the same notification, so the |observer| + // might finish waiting before the MetricsService has a chance to process + // the notification. To avoid racing here, we repeatedly run the message + // loop until the MetricsService catches up. This should happen "real soon + // now", since the notification is posted to all observers essentially + // simultaneously... so busy waiting here shouldn't be too bad. + const PrefService* prefs = g_browser_process->local_state(); + while (!prefs->GetInteger(metrics::prefs::kStabilityRendererCrashCount)) { + content::RunAllPendingInMessageLoop(); + } + } + // Open a couple of tabs of random content. - void OpenTabs() { + // + // Calling this method causes three page load events: + // 1. title2.html + // 2. iframe.html + // 3. title1.html (iframed by iframe.html) + void OpenThreeTabs() { const int kBrowserTestFlags = ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB | ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION; @@ -87,17 +127,13 @@ }; IN_PROC_BROWSER_TEST_F(MetricsServiceBrowserTest, CloseRenderersNormally) { - OpenTabs(); + OpenThreeTabs(); // Verify that the expected stability metrics were recorded. const PrefService* prefs = g_browser_process->local_state(); EXPECT_EQ(1, prefs->GetInteger(metrics::prefs::kStabilityLaunchCount)); EXPECT_EQ(3, prefs->GetInteger(metrics::prefs::kStabilityPageLoadCount)); EXPECT_EQ(0, prefs->GetInteger(metrics::prefs::kStabilityRendererCrashCount)); - // TODO(isherman): We should also verify that - // metrics::prefs::kStabilityExitedCleanly - // is set to true, but this preference isn't set until the browser - // exits... it's not clear to me how to test that. } // Flaky on Linux. See http://crbug.com/131094 @@ -105,44 +141,23 @@ // crbug.com/368525). #if defined(OS_LINUX) || defined(ADDRESS_SANITIZER) #define MAYBE_CrashRenderers DISABLED_CrashRenderers +#define MAYBE_CheckCrashRenderers DISABLED_CheckCrashRenderers #else #define MAYBE_CrashRenderers CrashRenderers +#define MAYBE_CheckCrashRenderers CheckCrashRenderers #endif + IN_PROC_BROWSER_TEST_F(MetricsServiceBrowserTest, MAYBE_CrashRenderers) { base::HistogramTester histogram_tester; - OpenTabs(); - // Kill the process for one of the tabs. - content::RenderProcessHostWatcher observer( - browser()->tab_strip_model()->GetActiveWebContents(), - content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT); - ui_test_utils::NavigateToURL(browser(), GURL(content::kChromeUICrashURL)); - observer.Wait(); - - // The MetricsService listens for the same notification, so the |observer| - // might finish waiting before the MetricsService has a chance to process the - // notification. To avoid racing here, we repeatedly run the message loop - // until the MetricsService catches up. This should happen "real soon now", - // since the notification is posted to all observers essentially - // simultaneously... so busy waiting here shouldn't be too bad. - const PrefService* prefs = g_browser_process->local_state(); - while (!prefs->GetInteger(metrics::prefs::kStabilityRendererCrashCount)) { - content::RunAllPendingInMessageLoop(); - } + OpenTabsAndNavigateToCrashyUrl(content::kChromeUICrashURL); // Verify that the expected stability metrics were recorded. + const PrefService* prefs = g_browser_process->local_state(); EXPECT_EQ(1, prefs->GetInteger(metrics::prefs::kStabilityLaunchCount)); - // Expect four page loads: - // 1. title2.html - // 2. iframe.html - // 3. title1.html (iframed by iframe.html) - // 4. chrome://crash + // The three tabs from OpenTabs() and the one tab to open chrome://crash/. EXPECT_EQ(4, prefs->GetInteger(metrics::prefs::kStabilityPageLoadCount)); EXPECT_EQ(1, prefs->GetInteger(metrics::prefs::kStabilityRendererCrashCount)); - // TODO(isherman): We should also verify that - // metrics::prefs::kStabilityExitedCleanly - // is set to true, but this preference isn't set until the browser - // exits... it's not clear to me how to test that. #if defined(OS_WIN) histogram_tester.ExpectUniqueSample( @@ -154,33 +169,41 @@ histogram_tester.ExpectUniqueSample("Tabs.SadTab.CrashCreated", 1, 1); } +IN_PROC_BROWSER_TEST_F(MetricsServiceBrowserTest, MAYBE_CheckCrashRenderers) { + base::HistogramTester histogram_tester; + + OpenTabsAndNavigateToCrashyUrl(content::kChromeUICheckCrashURL); + + // Verify that the expected stability metrics were recorded. + const PrefService* prefs = g_browser_process->local_state(); + EXPECT_EQ(1, prefs->GetInteger(metrics::prefs::kStabilityLaunchCount)); + // The three tabs from OpenTabs() and the one tab to open + // chrome://checkcrash/. + EXPECT_EQ(4, prefs->GetInteger(metrics::prefs::kStabilityPageLoadCount)); + EXPECT_EQ(1, prefs->GetInteger(metrics::prefs::kStabilityRendererCrashCount)); + +#if defined(OS_WIN) + histogram_tester.ExpectUniqueSample( + "CrashExitCodes.Renderer", + std::abs(static_cast<int32_t>(STATUS_BREAKPOINT)), 1); +#elif defined(OS_MACOSX) || defined(OS_LINUX) + VerifyRendererExitCodeIsSignal(histogram_tester, SIGTRAP); +#endif + histogram_tester.ExpectUniqueSample("Tabs.SadTab.CrashCreated", 1, 1); +} + // OOM code only works on Windows. #if defined(OS_WIN) && !defined(ADDRESS_SANITIZER) IN_PROC_BROWSER_TEST_F(MetricsServiceBrowserTest, OOMRenderers) { base::HistogramTester histogram_tester; - OpenTabs(); - // Kill the process for one of the tabs. - content::RenderProcessHostWatcher observer( - browser()->tab_strip_model()->GetActiveWebContents(), - content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT); - ui_test_utils::NavigateToURL(browser(), - GURL(content::kChromeUIMemoryExhaustURL)); - observer.Wait(); - - // The MetricsService listens for the same notification, so the |observer| - // might finish waiting before the MetricsService has a chance to process the - // notification. To avoid racing here, we repeatedly run the message loop - // until the MetricsService catches up. This should happen "real soon now", - // since the notification is posted to all observers essentially - // simultaneously... so busy waiting here shouldn't be too bad. - const PrefService* prefs = g_browser_process->local_state(); - while (!prefs->GetInteger(metrics::prefs::kStabilityRendererCrashCount)) { - content::RunAllPendingInMessageLoop(); - } + OpenTabsAndNavigateToCrashyUrl(content::kChromeUIMemoryExhaustURL); // Verify that the expected stability metrics were recorded. + const PrefService* prefs = g_browser_process->local_state(); EXPECT_EQ(1, prefs->GetInteger(metrics::prefs::kStabilityLaunchCount)); + // The three tabs from OpenTabs() and the one tab to open + // chrome://memory-exhaust/. EXPECT_EQ(4, prefs->GetInteger(metrics::prefs::kStabilityPageLoadCount)); EXPECT_EQ(1, prefs->GetInteger(metrics::prefs::kStabilityRendererCrashCount));
diff --git a/chrome/browser/net/sdch_browsertest.cc b/chrome/browser/net/sdch_browsertest.cc index 257f7a78..74ad70d 100644 --- a/chrome/browser/net/sdch_browsertest.cc +++ b/chrome/browser/net/sdch_browsertest.cc
@@ -441,7 +441,7 @@ second_profile_data_dir_.GetPath()); if (!second_profile_) return false; - second_browser_ = new Browser(Browser::CreateParams(second_profile_)); + second_browser_ = new Browser(Browser::CreateParams(second_profile_, true)); if (!second_browser_) return false; chrome::AddSelectedTabWithURL(second_browser_,
diff --git a/chrome/browser/prefetch/prefetch_browsertest.cc b/chrome/browser/prefetch/prefetch_browsertest.cc index 9adb78d..19112909 100644 --- a/chrome/browser/prefetch/prefetch_browsertest.cc +++ b/chrome/browser/prefetch/prefetch_browsertest.cc
@@ -135,7 +135,7 @@ IN_PROC_BROWSER_TEST_F(PrefetchBrowserTestPrediction, IncognitoTest) { Profile* incognito_profile = browser()->profile()->GetOffTheRecordProfile(); Browser* incognito_browser = - new Browser(Browser::CreateParams(incognito_profile)); + new Browser(Browser::CreateParams(incognito_profile, true)); // Navigate just to have a tab in this window, otherwise there is no // WebContents for the incognito browser.
diff --git a/chrome/browser/printing/cloud_print/privet_url_fetcher.cc b/chrome/browser/printing/cloud_print/privet_url_fetcher.cc index 1135e21..7575feb 100644 --- a/chrome/browser/printing/cloud_print/privet_url_fetcher.cc +++ b/chrome/browser/printing/cloud_print/privet_url_fetcher.cc
@@ -11,7 +11,6 @@ #include <memory> #include "base/bind.h" -#include "base/debug/dump_without_crashing.h" #include "base/json/json_reader.h" #include "base/location.h" #include "base/memory/singleton.h" @@ -202,8 +201,6 @@ DCHECK_EQ(tries_, 0); // We haven't called |Start()| yet. if (!url_.is_valid()) { - // Not yet clear why it's possible. crbug.com/513505 - base::debug::DumpWithoutCrashing(); return delegate_->OnError(this, UNKNOWN_ERROR); }
diff --git a/chrome/browser/profiles/avatar_menu_actions_desktop.cc b/chrome/browser/profiles/avatar_menu_actions_desktop.cc index 1d22aa30..6db41b6 100644 --- a/chrome/browser/profiles/avatar_menu_actions_desktop.cc +++ b/chrome/browser/profiles/avatar_menu_actions_desktop.cc
@@ -27,7 +27,8 @@ Browser* settings_browser = browser_; if (!settings_browser) { - const Browser::CreateParams params(ProfileManager::GetLastUsedProfile()); + const Browser::CreateParams params(ProfileManager::GetLastUsedProfile(), + true); settings_browser = new Browser(params); } chrome::ShowSettingsSubPage(settings_browser, chrome::kCreateProfileSubPage); @@ -37,7 +38,7 @@ void AvatarMenuActionsDesktop::EditProfile(Profile* profile) { Browser* settings_browser = browser_; if (!settings_browser) { - settings_browser = new Browser(Browser::CreateParams(profile)); + settings_browser = new Browser(Browser::CreateParams(profile, true)); } // TODO(davidben): The manageProfile page only allows editting the profile // associated with the browser it is opened in. AvatarMenuActionsDesktop
diff --git a/chrome/browser/profiles/profile_manager_unittest.cc b/chrome/browser/profiles/profile_manager_unittest.cc index 6a66ac55..f5c4ef1 100644 --- a/chrome/browser/profiles/profile_manager_unittest.cc +++ b/chrome/browser/profiles/profile_manager_unittest.cc
@@ -713,7 +713,7 @@ ASSERT_EQ(0U, last_opened_profiles.size()); // Create a browser for profile1. - Browser::CreateParams profile1_params(profile1); + Browser::CreateParams profile1_params(profile1, true); std::unique_ptr<Browser> browser1a( chrome::CreateBrowserWithTestWindowForParams(&profile1_params)); @@ -722,7 +722,7 @@ EXPECT_EQ(profile1, last_opened_profiles[0]); // And for profile2. - Browser::CreateParams profile2_params(profile2); + Browser::CreateParams profile2_params(profile2, true); std::unique_ptr<Browser> browser2( chrome::CreateBrowserWithTestWindowForParams(&profile2_params)); @@ -775,12 +775,12 @@ ASSERT_TRUE(profile2); // Create a browser for profile1. - Browser::CreateParams profile1_params(profile1); + Browser::CreateParams profile1_params(profile1, true); std::unique_ptr<Browser> browser1( chrome::CreateBrowserWithTestWindowForParams(&profile1_params)); // And for profile2. - Browser::CreateParams profile2_params(profile2); + Browser::CreateParams profile2_params(profile2, true); std::unique_ptr<Browser> browser2( chrome::CreateBrowserWithTestWindowForParams(&profile2_params)); @@ -825,7 +825,7 @@ ASSERT_EQ(0U, last_opened_profiles.size()); // Create a browser for profile1. - Browser::CreateParams profile1_params(profile1); + Browser::CreateParams profile1_params(profile1, true); std::unique_ptr<Browser> browser1( chrome::CreateBrowserWithTestWindowForParams(&profile1_params)); @@ -834,7 +834,8 @@ EXPECT_EQ(profile1, last_opened_profiles[0]); // And for profile2. - Browser::CreateParams profile2_params(profile1->GetOffTheRecordProfile()); + Browser::CreateParams profile2_params(profile1->GetOffTheRecordProfile(), + true); std::unique_ptr<Browser> browser2a( chrome::CreateBrowserWithTestWindowForParams(&profile2_params)); @@ -884,7 +885,7 @@ EXPECT_NE(profile, last_used_profile); // Create a browser for the profile. - Browser::CreateParams profile_params(profile); + Browser::CreateParams profile_params(profile, true); std::unique_ptr<Browser> browser( chrome::CreateBrowserWithTestWindowForParams(&profile_params)); last_used_profile = profile_manager->GetLastUsedProfile(); @@ -926,16 +927,16 @@ ASSERT_TRUE(ephemeral_profile2); // Create a browser for profile1. - Browser::CreateParams profile1_params(normal_profile); + Browser::CreateParams profile1_params(normal_profile, true); std::unique_ptr<Browser> browser1( chrome::CreateBrowserWithTestWindowForParams(&profile1_params)); // Create browsers for the ephemeral profile. - Browser::CreateParams profile2_params(ephemeral_profile1); + Browser::CreateParams profile2_params(ephemeral_profile1, true); std::unique_ptr<Browser> browser2( chrome::CreateBrowserWithTestWindowForParams(&profile2_params)); - Browser::CreateParams profile3_params(ephemeral_profile2); + Browser::CreateParams profile3_params(ephemeral_profile2, true); std::unique_ptr<Browser> browser3( chrome::CreateBrowserWithTestWindowForParams(&profile3_params));
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu.cc b/chrome/browser/renderer_context_menu/render_view_context_menu.cc index c2f9143..f86db71 100644 --- a/chrome/browser/renderer_context_menu/render_view_context_menu.cc +++ b/chrome/browser/renderer_context_menu/render_view_context_menu.cc
@@ -49,7 +49,6 @@ #include "chrome/browser/search/search.h" #include "chrome/browser/search_engines/template_url_service_factory.h" #include "chrome/browser/spellchecker/spellcheck_service.h" -#include "chrome/browser/tab_contents/retargeting_details.h" #include "chrome/browser/translate/chrome_translate_client.h" #include "chrome/browser/translate/translate_service.h" #include "chrome/browser/ui/browser_commands.h" @@ -1966,24 +1965,6 @@ content::NotificationService::NoDetails()); } -void RenderViewContextMenu::NotifyURLOpened( - const GURL& url, - content::WebContents* new_contents) { - RetargetingDetails details; - details.source_web_contents = source_web_contents_; - // Don't use GetRenderFrameHost() as it may be NULL. crbug.com/399789 - details.source_render_process_id = render_process_id_; - details.source_render_frame_id = render_frame_id_; - details.target_url = url; - details.target_web_contents = new_contents; - details.not_yet_in_tabstrip = false; - - content::NotificationService::current()->Notify( - chrome::NOTIFICATION_RETARGETING, - content::Source<Profile>(GetProfile()), - content::Details<RetargetingDetails>(&details)); -} - base::string16 RenderViewContextMenu::PrintableSelectionText() { return gfx::TruncateString(params_.selection_text, kMaxSelectionTextLength,
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu.h b/chrome/browser/renderer_context_menu/render_view_context_menu.h index ef8b1a8..0239d2c 100644 --- a/chrome/browser/renderer_context_menu/render_view_context_menu.h +++ b/chrome/browser/renderer_context_menu/render_view_context_menu.h
@@ -121,8 +121,6 @@ void HandleAuthorizeAllPlugins() override; #endif void NotifyMenuShown() override; - void NotifyURLOpened(const GURL& url, - content::WebContents* new_contents) override; // Gets the extension (if any) associated with the WebContents that we're in. const extensions::Extension* GetExtension() const;
diff --git a/chrome/browser/resources/extensions/extension_list.js b/chrome/browser/resources/extensions/extension_list.js index 610515a..df40e77 100644 --- a/chrome/browser/resources/extensions/extension_list.js +++ b/chrome/browser/resources/extensions/extension_list.js
@@ -464,8 +464,7 @@ var extensionId = extension.id; assert(this.extensions_.length > 0); var newEx = this.extensions_.filter(function(e) { - return e.state == chrome.developerPrivate.ExtensionState.ENABLED && - e.id == extensionId; + return e.id == extensionId; })[0]; var errors = newEx.manifestErrors.concat(newEx.runtimeErrors); extensions.ExtensionErrorOverlay.getInstance().setErrorsAndShowOverlay(
diff --git a/chrome/browser/resources/settings/a11y_page/manage_a11y_page.js b/chrome/browser/resources/settings/a11y_page/manage_a11y_page.js index 5d5f101b..605336d0 100644 --- a/chrome/browser/resources/settings/a11y_page/manage_a11y_page.js +++ b/chrome/browser/resources/settings/a11y_page/manage_a11y_page.js
@@ -60,22 +60,30 @@ /** @private */ onDisplayTap_: function() { - settings.navigateTo(settings.Route.DISPLAY); + settings.navigateTo( + settings.Route.DISPLAY, + /* dynamicParams */ null, /* removeSearch */ true); }, /** @private */ onAppearanceTap_: function() { - settings.navigateTo(settings.Route.APPEARANCE); + settings.navigateTo( + settings.Route.APPEARANCE, + /* dynamicParams */ null, /* removeSearch */ true); }, /** @private */ onKeyboardTap_: function() { - settings.navigateTo(settings.Route.KEYBOARD); + settings.navigateTo( + settings.Route.KEYBOARD, + /* dynamicParams */ null, /* removeSearch */ true); }, /** @private */ onMouseTap_: function() { - settings.navigateTo(settings.Route.POINTERS); + settings.navigateTo( + settings.Route.POINTERS, + /* dynamicParams */ null, /* removeSearch */ true); }, /** @private */
diff --git a/chrome/browser/resources/settings/on_startup_page/startup_url_dialog.js b/chrome/browser/resources/settings/on_startup_page/startup_url_dialog.js index 5dbfd54..3b57658 100644 --- a/chrome/browser/resources/settings/on_startup_page/startup_url_dialog.js +++ b/chrome/browser/resources/settings/on_startup_page/startup_url_dialog.js
@@ -36,7 +36,7 @@ if (this.model) { this.dialogTitle_ = loadTimeData.getString('onStartupEditPage'); - this.actionButtonText_ = loadTimeData.getString('edit'); + this.actionButtonText_ = loadTimeData.getString('save'); this.$.actionButton.disabled = false; // Pre-populate the input field. this.url_ = this.model.url;
diff --git a/chrome/browser/resources/settings/settings_menu/settings_menu.js b/chrome/browser/resources/settings/settings_menu/settings_menu.js index 306f691..122f10a 100644 --- a/chrome/browser/resources/settings/settings_menu/settings_menu.js +++ b/chrome/browser/resources/settings/settings_menu/settings_menu.js
@@ -9,6 +9,8 @@ Polymer({ is: 'settings-menu', + behaviors: [settings.RouteObserverBehavior], + properties: { advancedOpened: { type: Boolean, @@ -29,18 +31,20 @@ 'subMenu.tap': 'onLinkTap_', }, - /** @override */ - attached: function() { - var currentPath = settings.getCurrentRoute().path; + /** @param {!settings.Route} newRoute */ + currentRouteChanged: function(newRoute) { + var currentPath = newRoute.path; // Focus the initially selected path. var anchors = this.root.querySelectorAll('a'); for (var i = 0; i < anchors.length; ++i) { if (anchors[i].getAttribute('href') == currentPath) { this.setSelectedUrl_(anchors[i].href); - break; + return; } } + + this.setSelectedUrl_(''); // Nothing is selected. }, /**
diff --git a/chrome/browser/safe_browsing/download_feedback_service.cc b/chrome/browser/safe_browsing/download_feedback_service.cc index 656c804..adebf92 100644 --- a/chrome/browser/safe_browsing/download_feedback_service.cc +++ b/chrome/browser/safe_browsing/download_feedback_service.cc
@@ -91,19 +91,19 @@ // static void DownloadFeedbackService::MaybeStorePingsForDownload( DownloadProtectionService::DownloadCheckResult result, + bool upload_requested, content::DownloadItem* download, const std::string& ping, const std::string& response) { - switch (result) { - case DownloadProtectionService::UNKNOWN: - case DownloadProtectionService::SAFE: - case DownloadProtectionService::DANGEROUS: - return; - case DownloadProtectionService::UNCOMMON: - case DownloadProtectionService::DANGEROUS_HOST: - case DownloadProtectionService::POTENTIALLY_UNWANTED: - break; // Fall through. - } + // We never upload SAFE files. + if (result == DownloadProtectionService::SAFE) + return; + + UMA_HISTOGRAM_BOOLEAN("SBDownloadFeedback.UploadRequestedByServer", + upload_requested); + if (!upload_requested) + return; + UMA_HISTOGRAM_COUNTS("SBDownloadFeedback.SizeEligibleKB", download->GetReceivedBytes() / 1024); if (download->GetReceivedBytes() > DownloadFeedback::kMaxUploadSize)
diff --git a/chrome/browser/safe_browsing/download_feedback_service.h b/chrome/browser/safe_browsing/download_feedback_service.h index 474e4d8..ae87ad3 100644 --- a/chrome/browser/safe_browsing/download_feedback_service.h +++ b/chrome/browser/safe_browsing/download_feedback_service.h
@@ -42,10 +42,13 @@ // Stores the request and response ping data from the download check, if the // check result and file size are eligible. This must be called after a - // download has been flagged as malicious in order for the download to be - // enabled for uploading. + // download has been flagged as un-SAFE in order for the download to be + // enabled for uploading. Some un-SAFE downloads can be marked for + // upload by the server with |upload_requested| if it's needed for better + // classification. static void MaybeStorePingsForDownload( DownloadProtectionService::DownloadCheckResult result, + bool upload_requested, content::DownloadItem* download, const std::string& ping, const std::string& response);
diff --git a/chrome/browser/safe_browsing/download_feedback_service_unittest.cc b/chrome/browser/safe_browsing/download_feedback_service_unittest.cc index c4cdd824..9779a0d 100644 --- a/chrome/browser/safe_browsing/download_feedback_service_unittest.cc +++ b/chrome/browser/safe_browsing/download_feedback_service_unittest.cc
@@ -113,12 +113,14 @@ }; bool WillStorePings(DownloadProtectionService::DownloadCheckResult result, + bool upload_requested, int64_t size) { content::MockDownloadItem item; EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(size)); EXPECT_FALSE(DownloadFeedbackService::IsEnabledForDownload(item)); - DownloadFeedbackService::MaybeStorePingsForDownload(result, &item, "a", "b"); + DownloadFeedbackService::MaybeStorePingsForDownload(result, upload_requested, + &item, "a", "b"); return DownloadFeedbackService::IsEnabledForDownload(item); } @@ -172,21 +174,42 @@ const int64_t ok_size = DownloadFeedback::kMaxUploadSize; const int64_t bad_size = DownloadFeedback::kMaxUploadSize + 1; - EXPECT_FALSE(WillStorePings(DownloadProtectionService::SAFE, ok_size)); - EXPECT_FALSE(WillStorePings(DownloadProtectionService::DANGEROUS, ok_size)); - EXPECT_TRUE(WillStorePings(DownloadProtectionService::UNCOMMON, ok_size)); - EXPECT_TRUE( - WillStorePings(DownloadProtectionService::DANGEROUS_HOST, ok_size)); - EXPECT_TRUE( - WillStorePings(DownloadProtectionService::POTENTIALLY_UNWANTED, ok_size)); + std::vector<bool> upload_requests = {false, true}; + for (bool upload_requested : upload_requests) { + // SAFE will never upload + EXPECT_FALSE(WillStorePings(DownloadProtectionService::SAFE, + upload_requested, ok_size)); + // Others will upload if requested. + EXPECT_EQ(upload_requested, + WillStorePings(DownloadProtectionService::UNKNOWN, + upload_requested, ok_size)); + EXPECT_EQ(upload_requested, + WillStorePings(DownloadProtectionService::DANGEROUS, + upload_requested, ok_size)); + EXPECT_EQ(upload_requested, + WillStorePings(DownloadProtectionService::UNCOMMON, + upload_requested, ok_size)); + EXPECT_EQ(upload_requested, + WillStorePings(DownloadProtectionService::DANGEROUS_HOST, + upload_requested, ok_size)); + EXPECT_EQ(upload_requested, + WillStorePings(DownloadProtectionService::POTENTIALLY_UNWANTED, + upload_requested, ok_size)); - EXPECT_FALSE(WillStorePings(DownloadProtectionService::SAFE, bad_size)); - EXPECT_FALSE(WillStorePings(DownloadProtectionService::DANGEROUS, bad_size)); - EXPECT_FALSE(WillStorePings(DownloadProtectionService::UNCOMMON, bad_size)); - EXPECT_FALSE( - WillStorePings(DownloadProtectionService::DANGEROUS_HOST, bad_size)); - EXPECT_FALSE(WillStorePings(DownloadProtectionService::POTENTIALLY_UNWANTED, - bad_size)); + // Bad sizes never upload + EXPECT_FALSE(WillStorePings(DownloadProtectionService::SAFE, + upload_requested, bad_size)); + EXPECT_FALSE(WillStorePings(DownloadProtectionService::UNKNOWN, + upload_requested, bad_size)); + EXPECT_FALSE(WillStorePings(DownloadProtectionService::DANGEROUS, + upload_requested, bad_size)); + EXPECT_FALSE(WillStorePings(DownloadProtectionService::UNCOMMON, + upload_requested, bad_size)); + EXPECT_FALSE(WillStorePings(DownloadProtectionService::DANGEROUS_HOST, + upload_requested, bad_size)); + EXPECT_FALSE(WillStorePings(DownloadProtectionService::POTENTIALLY_UNWANTED, + upload_requested, bad_size)); + } } TEST_F(DownloadFeedbackServiceTest, SingleFeedbackCompleteAndDiscardDownload) { @@ -206,8 +229,9 @@ DownloadFeedbackService service(request_context_getter_.get(), file_task_runner_.get()); - service.MaybeStorePingsForDownload( - DownloadProtectionService::UNCOMMON, &item, ping_request, ping_response); + service.MaybeStorePingsForDownload(DownloadProtectionService::UNCOMMON, + true /* upload_requested */, &item, + ping_request, ping_response); ASSERT_TRUE(DownloadFeedbackService::IsEnabledForDownload(item)); service.BeginFeedbackForDownload(&item, DownloadCommands::DISCARD); ASSERT_FALSE(download_discarded_callback.is_null()); @@ -247,7 +271,8 @@ DownloadFeedbackService service(request_context_getter_.get(), file_task_runner_.get()); - service.MaybeStorePingsForDownload(DownloadProtectionService::UNCOMMON, &item, + service.MaybeStorePingsForDownload(DownloadProtectionService::UNCOMMON, + true /* upload_requested */, &item, ping_request, ping_response); ASSERT_TRUE(DownloadFeedbackService::IsEnabledForDownload(item)); service.BeginFeedbackForDownload(&item, DownloadCommands::KEEP); @@ -286,8 +311,8 @@ EXPECT_CALL(item[i], StealDangerousDownload(true, _)) .WillOnce(SaveArg<1>(&download_discarded_callback[i])); DownloadFeedbackService::MaybeStorePingsForDownload( - DownloadProtectionService::UNCOMMON, &item[i], ping_request, - ping_response); + DownloadProtectionService::UNCOMMON, true /* upload_requested */, + &item[i], ping_request, ping_response); ASSERT_TRUE(DownloadFeedbackService::IsEnabledForDownload(item[i])); } @@ -355,8 +380,8 @@ EXPECT_CALL(item[i], StealDangerousDownload(true, _)) .WillOnce(SaveArg<1>(&download_discarded_callback[i])); DownloadFeedbackService::MaybeStorePingsForDownload( - DownloadProtectionService::UNCOMMON, &item[i], ping_request, - ping_response); + DownloadProtectionService::UNCOMMON, true /* upload_requested */, + &item[i], ping_request, ping_response); ASSERT_TRUE(DownloadFeedbackService::IsEnabledForDownload(item[i])); }
diff --git a/chrome/browser/safe_browsing/download_protection_service.cc b/chrome/browser/safe_browsing/download_protection_service.cc index cdd7d73..c9f6953 100644 --- a/chrome/browser/safe_browsing/download_protection_service.cc +++ b/chrome/browser/safe_browsing/download_protection_service.cc
@@ -597,8 +597,9 @@ if (!token.empty()) SetDownloadPingToken(item_, token); + bool upload_requested = response.upload(); DownloadFeedbackService::MaybeStorePingsForDownload( - result, item_, client_download_request_data_, data); + result, upload_requested, item_, client_download_request_data_, data); } // We don't need the fetcher anymore. fetcher_.reset();
diff --git a/chrome/browser/safe_browsing/download_protection_service_unittest.cc b/chrome/browser/safe_browsing/download_protection_service_unittest.cc index 04a4657..5c40564 100644 --- a/chrome/browser/safe_browsing/download_protection_service_unittest.cc +++ b/chrome/browser/safe_browsing/download_protection_service_unittest.cc
@@ -395,9 +395,11 @@ void PrepareResponse(net::FakeURLFetcherFactory* factory, ClientDownloadResponse::Verdict verdict, net::HttpStatusCode response_code, - net::URLRequestStatus::Status status) { + net::URLRequestStatus::Status status, + bool upload_requested = false) { ClientDownloadResponse response; response.set_verdict(verdict); + response.set_upload(upload_requested); factory->SetFakeResponse( DownloadProtectionService::GetDownloadRequestUrl(), response.SerializeAsString(), @@ -1041,11 +1043,11 @@ MatchDownloadWhitelistUrl(_)) .WillRepeatedly(Return(false)); EXPECT_CALL(*binary_feature_extractor_.get(), CheckSignature(tmp_path_, _)) - .Times(7); + .Times(8); EXPECT_CALL(*binary_feature_extractor_.get(), ExtractImageFeatures( tmp_path_, BinaryFeatureExtractor::kDefaultOptions, _, _)) - .Times(7); + .Times(8); std::string feedback_ping; std::string feedback_response; ClientDownloadResponse expected_response; @@ -1079,9 +1081,10 @@ } { // If the response is dangerous the result should also be marked as - // dangerous. + // dangerous, and should not upload if not requested. PrepareResponse(&factory, ClientDownloadResponse::DANGEROUS, net::HTTP_OK, - net::URLRequestStatus::SUCCESS); + net::URLRequestStatus::SUCCESS, + false /* upload_requested */); RunLoop run_loop; download_service_->CheckClientDownload( &item, base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback, @@ -1094,9 +1097,27 @@ ClearClientDownloadRequest(); } { + // If the response is dangerous and the server requests an upload, + // we should upload. + PrepareResponse(&factory, ClientDownloadResponse::DANGEROUS, net::HTTP_OK, + net::URLRequestStatus::SUCCESS, + true /* upload_requested */); + RunLoop run_loop; + download_service_->CheckClientDownload( + &item, base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback, + base::Unretained(this), run_loop.QuitClosure())); + run_loop.Run(); + EXPECT_TRUE(DownloadFeedbackService::GetPingsForDownloadForTesting( + item, &feedback_ping, &feedback_response)); + EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS)); + EXPECT_TRUE(HasClientDownloadRequest()); + ClearClientDownloadRequest(); + } + { // If the response is uncommon the result should also be marked as uncommon. PrepareResponse(&factory, ClientDownloadResponse::UNCOMMON, net::HTTP_OK, - net::URLRequestStatus::SUCCESS); + net::URLRequestStatus::SUCCESS, + true /* upload_requested */); RunLoop run_loop; download_service_->CheckClientDownload( &item, base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback, @@ -1109,6 +1130,7 @@ EXPECT_TRUE(decoded_request.ParseFromString(feedback_ping)); EXPECT_EQ(url_chain_.back().spec(), decoded_request.url()); expected_response.set_verdict(ClientDownloadResponse::UNCOMMON); + expected_response.set_upload(true); EXPECT_EQ(expected_response.SerializeAsString(), feedback_response); EXPECT_TRUE(HasClientDownloadRequest()); ClearClientDownloadRequest(); @@ -1117,7 +1139,8 @@ // If the response is dangerous_host the result should also be marked as // dangerous_host. PrepareResponse(&factory, ClientDownloadResponse::DANGEROUS_HOST, - net::HTTP_OK, net::URLRequestStatus::SUCCESS); + net::HTTP_OK, net::URLRequestStatus::SUCCESS, + true /* upload_requested */); RunLoop run_loop; download_service_->CheckClientDownload( &item, base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback, @@ -1127,6 +1150,7 @@ EXPECT_TRUE(DownloadFeedbackService::GetPingsForDownloadForTesting( item, &feedback_ping, &feedback_response)); expected_response.set_verdict(ClientDownloadResponse::DANGEROUS_HOST); + expected_response.set_upload(true); EXPECT_EQ(expected_response.SerializeAsString(), feedback_response); EXPECT_TRUE(HasClientDownloadRequest()); ClearClientDownloadRequest();
diff --git a/chrome/browser/safe_browsing/srt_fetcher_win.cc b/chrome/browser/safe_browsing/srt_fetcher_win.cc index 6a3ca19..58c8d59 100644 --- a/chrome/browser/safe_browsing/srt_fetcher_win.cc +++ b/chrome/browser/safe_browsing/srt_fetcher_win.cc
@@ -528,7 +528,7 @@ if (browser->type() != Browser::TYPE_TABBED) { browser = chrome::FindTabbedBrowser(profile, false); if (!browser) - browser = new Browser(Browser::CreateParams(profile)); + browser = new Browser(Browser::CreateParams(profile, false)); } GlobalErrorService* global_error_service = GlobalErrorServiceFactory::GetForProfile(profile);
diff --git a/chrome/browser/sessions/better_session_restore_browsertest.cc b/chrome/browser/sessions/better_session_restore_browsertest.cc index 96809f7..a753866 100644 --- a/chrome/browser/sessions/better_session_restore_browsertest.cc +++ b/chrome/browser/sessions/better_session_restore_browsertest.cc
@@ -547,7 +547,7 @@ // which stores a session cookie. StoreDataWithPage("session_cookies.html"); Browser* popup = new Browser( - Browser::CreateParams(Browser::TYPE_POPUP, browser()->profile())); + Browser::CreateParams(Browser::TYPE_POPUP, browser()->profile(), true)); popup->window()->Show(); Browser* new_browser = QuitBrowserAndRestore(browser(), false); @@ -826,7 +826,7 @@ SessionCookiesBrowserCloseWithPopupOpen) { StoreDataWithPage("session_cookies.html"); Browser* popup = new Browser( - Browser::CreateParams(Browser::TYPE_POPUP, browser()->profile())); + Browser::CreateParams(Browser::TYPE_POPUP, browser()->profile(), true)); popup->window()->Show(); Browser* new_browser = QuitBrowserAndRestore(browser(), false); NavigateAndCheckStoredData(new_browser, "session_cookies.html"); @@ -838,7 +838,7 @@ SessionCookiesBrowserClosePopupLast) { StoreDataWithPage("session_cookies.html"); Browser* popup = new Browser( - Browser::CreateParams(Browser::TYPE_POPUP, browser()->profile())); + Browser::CreateParams(Browser::TYPE_POPUP, browser()->profile(), true)); popup->window()->Show(); CloseBrowserSynchronously(browser()); Browser* new_browser = QuitBrowserAndRestore(popup, false);
diff --git a/chrome/browser/sessions/session_restore.cc b/chrome/browser/sessions/session_restore.cc index 0e4d121..eeafc2d 100644 --- a/chrome/browser/sessions/session_restore.cc +++ b/chrome/browser/sessions/session_restore.cc
@@ -213,10 +213,9 @@ bool use_new_window = disposition == WindowOpenDisposition::NEW_WINDOW; - Browser* browser = - use_new_window - ? new Browser(Browser::CreateParams(profile_)) - : browser_; + Browser* browser = use_new_window + ? new Browser(Browser::CreateParams(profile_, true)) + : browser_; RecordAppLaunchForTab(browser, tab, selected_index); @@ -293,7 +292,7 @@ std::vector<RestoredTab>* contents_created) { Browser* browser = nullptr; if (!created_tabbed_browser && always_create_tabbed_browser_) { - browser = new Browser(Browser::CreateParams(profile_)); + browser = new Browser(Browser::CreateParams(profile_, false)); if (urls_to_open_.empty()) { // No tab browsers were created and no URLs were supplied on the command // line. Open the new tab page. @@ -630,11 +629,11 @@ const std::string& workspace, ui::WindowShowState show_state, const std::string& app_name) { - Browser::CreateParams params(type, profile_); + Browser::CreateParams params(type, profile_, false); if (!app_name.empty()) { const bool trusted_source = true; // We only store trusted app windows. params = Browser::CreateParams::CreateForApp(app_name, trusted_source, - bounds, profile_); + bounds, profile_, false); } else { params.initial_bounds = bounds; }
diff --git a/chrome/browser/sessions/session_restore_browsertest.cc b/chrome/browser/sessions/session_restore_browsertest.cc index c3a0a36..eece71e7 100644 --- a/chrome/browser/sessions/session_restore_browsertest.cc +++ b/chrome/browser/sessions/session_restore_browsertest.cc
@@ -487,7 +487,7 @@ // Create a new popup. Profile* profile = browser()->profile(); Browser* popup = - new Browser(Browser::CreateParams(Browser::TYPE_POPUP, profile)); + new Browser(Browser::CreateParams(Browser::TYPE_POPUP, profile, true)); popup->window()->Show(); // Close the browser.
diff --git a/chrome/browser/sessions/session_restore_browsertest_chromeos.cc b/chrome/browser/sessions/session_restore_browsertest_chromeos.cc index 8ffe884d..de48f66 100644 --- a/chrome/browser/sessions/session_restore_browsertest_chromeos.cc +++ b/chrome/browser/sessions/session_restore_browsertest_chromeos.cc
@@ -69,7 +69,7 @@ Browser::CreateParams CreateParamsForApp(const std::string name, bool trusted) { return Browser::CreateParams::CreateForApp(name, trusted, gfx::Rect(), - profile()); + profile(), true); } // Turn on session restore before we restart. @@ -91,10 +91,10 @@ // One browser window is always created by default. EXPECT_TRUE(browser()); // Create a second normal browser window. - CreateBrowserWithParams(Browser::CreateParams(profile())); + CreateBrowserWithParams(Browser::CreateParams(profile(), true)); // Create a third incognito browser window which should not get restored. CreateBrowserWithParams( - Browser::CreateParams(profile()->GetOffTheRecordProfile())); + Browser::CreateParams(profile()->GetOffTheRecordProfile(), true)); TurnOnSessionRestore(); } @@ -142,7 +142,8 @@ // One browser window is always created by default. ASSERT_TRUE(browser()); // Create a second browser window and maximize it. - Browser* browser2 = CreateBrowserWithParams(Browser::CreateParams(profile())); + Browser* browser2 = + CreateBrowserWithParams(Browser::CreateParams(profile(), true)); browser2->window()->Maximize(); // Create two app popup windows and maximize the second one. @@ -178,7 +179,8 @@ ASSERT_TRUE(browser()); browser()->window()->Minimize(); - Browser* browser2 = CreateBrowserWithParams(Browser::CreateParams(profile())); + Browser* browser2 = + CreateBrowserWithParams(Browser::CreateParams(profile(), true)); browser2->window()->Minimize(); EXPECT_TRUE(browser()->window()->IsMinimized());
diff --git a/chrome/browser/ssl/security_state_tab_helper_browser_tests.cc b/chrome/browser/ssl/security_state_tab_helper_browser_tests.cc index f809ba1..e0a50dd 100644 --- a/chrome/browser/ssl/security_state_tab_helper_browser_tests.cc +++ b/chrome/browser/ssl/security_state_tab_helper_browser_tests.cc
@@ -1289,7 +1289,7 @@ IN_PROC_BROWSER_TEST_F(SecurityStateTabHelperTestWithPasswordCcSwitch, ConsoleMessage) { ConsoleWebContentsDelegate* delegate = new ConsoleWebContentsDelegate( - Browser::CreateParams(browser()->profile())); + Browser::CreateParams(browser()->profile(), true)); content::WebContents* original_contents = browser()->tab_strip_model()->GetActiveWebContents(); content::WebContents* contents = @@ -1359,7 +1359,7 @@ ASSERT_TRUE(embedded_test_server()->Start()); host_resolver()->AddRule("*", embedded_test_server()->GetURL("/").host()); ConsoleWebContentsDelegate* delegate = new ConsoleWebContentsDelegate( - Browser::CreateParams(browser()->profile())); + Browser::CreateParams(browser()->profile(), true)); content::WebContents* original_contents = browser()->tab_strip_model()->GetActiveWebContents(); content::WebContents* contents = @@ -1448,7 +1448,7 @@ IN_PROC_BROWSER_TEST_F(SecurityStateTabHelperTestWithPasswordCcSwitch, ConsoleMessageNotPrintedForFrameNavigation) { ConsoleWebContentsDelegate* delegate = new ConsoleWebContentsDelegate( - Browser::CreateParams(browser()->profile())); + Browser::CreateParams(browser()->profile(), true)); content::WebContents* original_contents = browser()->tab_strip_model()->GetActiveWebContents(); content::WebContents* contents = @@ -1529,7 +1529,7 @@ IN_PROC_BROWSER_TEST_F(SecurityStateTabHelperTestWithPasswordCcSwitch, ConsoleMessageNotPrintedForPushStateNavigation) { ConsoleWebContentsDelegate* delegate = new ConsoleWebContentsDelegate( - Browser::CreateParams(browser()->profile())); + Browser::CreateParams(browser()->profile(), true)); content::WebContents* original_contents = browser()->tab_strip_model()->GetActiveWebContents(); content::WebContents* contents =
diff --git a/chrome/browser/sync/test/integration/sync_test.cc b/chrome/browser/sync/test/integration/sync_test.cc index 74d6549..782c4f5 100644 --- a/chrome/browser/sync/test/integration/sync_test.cc +++ b/chrome/browser/sync/test/integration/sync_test.cc
@@ -531,7 +531,8 @@ profiles_[index] = profile; // CheckInitialState() assumes that no windows are open at startup. - browsers_[index] = new Browser(Browser::CreateParams(GetProfile(index))); + browsers_[index] = + new Browser(Browser::CreateParams(GetProfile(index), true)); EXPECT_NE(nullptr, GetBrowser(index)) << "Could not create Browser " << index;
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 0737826..09f800b5 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -54,8 +54,6 @@ "autofill/autofill_popup_view_delegate.h", "autofill/chrome_autofill_client.cc", "autofill/chrome_autofill_client.h", - "autofill/country_combobox_model.cc", - "autofill/country_combobox_model.h", "autofill/create_card_unmask_prompt_view.h", "autofill/credit_card_scanner_controller.cc", "autofill/credit_card_scanner_controller.h", @@ -1518,6 +1516,8 @@ "views/payments/payment_request_dialog_view.cc", "views/payments/payment_request_dialog_view.h", "views/payments/payment_request_dialog_view_ids.h", + "views/payments/payment_request_item_list.cc", + "views/payments/payment_request_item_list.h", "views/payments/payment_request_row_view.cc", "views/payments/payment_request_row_view.h", "views/payments/payment_request_sheet_controller.cc",
diff --git a/chrome/browser/ui/ash/accelerator_commands_browsertest.cc b/chrome/browser/ui/ash/accelerator_commands_browsertest.cc index bb8a461d..40d7547 100644 --- a/chrome/browser/ui/ash/accelerator_commands_browsertest.cc +++ b/chrome/browser/ui/ash/accelerator_commands_browsertest.cc
@@ -149,7 +149,8 @@ // 3) Hosted apps. Browser::CreateParams browser_create_params( Browser::CreateParams::CreateForApp("Test", true /* trusted_source */, - gfx::Rect(), browser()->profile())); + gfx::Rect(), browser()->profile(), + true)); Browser* app_host_browser = new Browser(browser_create_params); ASSERT_TRUE(app_host_browser->is_app()); @@ -169,7 +170,7 @@ // 4) Popup browser windows. browser_create_params = - Browser::CreateParams(Browser::TYPE_POPUP, browser()->profile()); + Browser::CreateParams(Browser::TYPE_POPUP, browser()->profile(), true); Browser* popup_browser = new Browser(browser_create_params); ASSERT_TRUE(popup_browser->is_type_popup()); ASSERT_FALSE(popup_browser->is_app());
diff --git a/chrome/browser/ui/ash/chrome_shell_delegate.cc b/chrome/browser/ui/ash/chrome_shell_delegate.cc index e6017cf..f7b2d75 100644 --- a/chrome/browser/ui/ash/chrome_shell_delegate.cc +++ b/chrome/browser/ui/ash/chrome_shell_delegate.cc
@@ -507,7 +507,7 @@ Browser* browser = chrome::FindTabbedBrowser(profile, false); if (!browser) { - browser = new Browser(Browser::CreateParams(profile)); + browser = new Browser(Browser::CreateParams(profile, true)); browser->window()->Show(); }
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_impl_browsertest.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_impl_browsertest.cc index 35323e0..b204f527 100644 --- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_impl_browsertest.cc +++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_impl_browsertest.cc
@@ -1717,7 +1717,7 @@ ash::ShelfID shortcut_id = CreateShortcut("app1"); // Create a new browser - without activating it - and load an "app" into it. - Browser::CreateParams params = Browser::CreateParams(profile()); + Browser::CreateParams params = Browser::CreateParams(profile(), true); params.initial_show_state = ui::SHOW_STATE_INACTIVE; Browser* browser2 = new Browser(params); controller_->SetRefocusURLPatternForTest(
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_impl_unittest.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_impl_unittest.cc index b8b6181..ac40fa9 100644 --- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_impl_unittest.cc +++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_impl_unittest.cc
@@ -993,7 +993,7 @@ gfx::Rect(10, 10, 20, 30)); Browser::CreateParams params = Browser::CreateParams::CreateForApp( kCrxAppPrefix + app_name, true /* trusted_source */, gfx::Rect(), - profile); + profile, true); params.window = this; browser_.reset(new Browser(params)); chrome::AddTabAt(browser_.get(), GURL(), 0, true); @@ -2312,7 +2312,7 @@ multi_user_util::GetAccountIdFromProfile(profile()); // Create a browser window with a native window for the current user. - Browser::CreateParams params(profile()); + Browser::CreateParams params(profile(), true); std::unique_ptr<Browser> browser( chrome::CreateBrowserWithAuraTestWindowForParams(nullptr, ¶ms)); BrowserWindow* browser_window = browser->window();
diff --git a/chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos.cc b/chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos.cc index f32a91d..d30eb2d 100644 --- a/chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos.cc +++ b/chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos.cc
@@ -56,47 +56,6 @@ // The animation time in ms for a window which get teleported to another screen. const int kTeleportAnimationTimeMS = 300; -// Checks if a given event is a user event. -bool IsUserEvent(const ui::Event* e) { - if (e) { - ui::EventType type = e->type(); - if (type != ui::ET_CANCEL_MODE && - type != ui::ET_UMA_DATA && - type != ui::ET_UNKNOWN) - return true; - } - return false; -} - -// Test if we are currently processing a user event which might lead to a -// browser / app creation. -bool IsProcessingUserEvent() { - // When there is a nested message loop (e.g. active menu or drag and drop - // operation) - we are in a nested loop and can ignore this. - // Note: Unit tests might not have a message loop. - base::MessageLoop* message_loop = base::MessageLoop::current(); - if (message_loop && message_loop->is_running() && message_loop->IsNested()) - return false; - - // TODO(skuhne): "Open link in new window" will come here after the menu got - // closed, executing the command from the nested menu loop. However at that - // time there is no active event processed. A solution for that need to be - // found past M-32. A global event handler filter (pre and post) might fix - // that problem in conjunction with a depth counter - but - for the menu - // execution we come here after the loop was finished (so it's not nested - // anymore) and the root window should therefore still have the event which - // lead to the menu invocation, but it is not. By fixing that problem this - // would "magically work". - aura::Window::Windows root_window_list = ash::Shell::GetAllRootWindows(); - for (aura::Window::Windows::iterator it = root_window_list.begin(); - it != root_window_list.end(); - ++it) { - if (IsUserEvent((*it)->GetHost()->dispatcher()->current_event())) - return true; - } - return false; -} - // Records the type of window which was transferred to another desktop. void RecordUMAForTransferredWindowType(aura::Window* window) { // We need to figure out what kind of window this is to record the transfer. @@ -317,7 +276,7 @@ // Check if this window was created due to a user interaction. If it was, // transfer it to the current user. - if (IsProcessingUserEvent()) + if (window->GetProperty(aura::client::kCreatedByUserGesture)) window_to_entry_[window]->set_show_for_user(current_account_id_); // Add all transient children to our set of windows. Note that the function
diff --git a/chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos_unittest.cc b/chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos_unittest.cc index 2114633..38ff3b9 100644 --- a/chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos_unittest.cc +++ b/chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos_unittest.cc
@@ -1561,7 +1561,7 @@ aura::client::GetActivationClient(window(0)->GetRootWindow()); multi_user_window_manager()->SetWindowOwner(window(0), account_id_A); Profile* profile = multi_user_util::GetProfileFromAccountId(account_id_A); - Browser::CreateParams params(profile); + Browser::CreateParams params(profile, true); std::unique_ptr<Browser> browser(CreateTestBrowser( CreateTestWindowInShellWithId(0), gfx::Rect(16, 32, 640, 320), ¶ms)); aura::Window* browser_native_window = browser->window()->GetNativeWindow();
diff --git a/chrome/browser/ui/ash/window_positioner_unittest.cc b/chrome/browser/ui/ash/window_positioner_unittest.cc index d983dea..a71dd18 100644 --- a/chrome/browser/ui/ash/window_positioner_unittest.cc +++ b/chrome/browser/ui/ash/window_positioner_unittest.cc
@@ -66,12 +66,12 @@ dummy_popup->SetBounds(gfx::Rect(16, 32, 128, 256)); // Create a browser for the window. - Browser::CreateParams window_params(&profile_); + Browser::CreateParams window_params(&profile_, true); browser_ = chrome::CreateBrowserWithAuraTestWindowForParams( std::move(dummy_window), &window_params); // Creating a browser for the popup. - Browser::CreateParams popup_params(Browser::TYPE_POPUP, &profile_); + Browser::CreateParams popup_params(Browser::TYPE_POPUP, &profile_, true); browser_popup_ = chrome::CreateBrowserWithAuraTestWindowForParams( std::move(dummy_popup), &popup_params);
diff --git a/chrome/browser/ui/bookmarks/bookmark_bubble_sign_in_delegate.cc b/chrome/browser/ui/bookmarks/bookmark_bubble_sign_in_delegate.cc index 21c9118..3f8e2c5 100644 --- a/chrome/browser/ui/bookmarks/bookmark_bubble_sign_in_delegate.cc +++ b/chrome/browser/ui/bookmarks/bookmark_bubble_sign_in_delegate.cc
@@ -38,7 +38,7 @@ Profile* original_profile = profile_->GetOriginalProfile(); browser_ = chrome::FindLastActiveWithProfile(original_profile); if (!browser_) { - browser_ = new Browser(Browser::CreateParams(original_profile)); + browser_ = new Browser(Browser::CreateParams(original_profile, true)); } } }
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc index 6d268b3..e27fd84 100644 --- a/chrome/browser/ui/browser.cc +++ b/chrome/browser/ui/browser.cc
@@ -250,8 +250,8 @@ // How long we wait before updating the browser chrome while loading a page. const int kUIUpdateCoalescingTimeMS = 200; -BrowserWindow* CreateBrowserWindow(Browser* browser) { - return BrowserWindow::CreateBrowserWindow(browser); +BrowserWindow* CreateBrowserWindow(Browser* browser, bool user_gesture) { + return BrowserWindow::CreateBrowserWindow(browser, user_gesture); } // Is the fast tab unload experiment enabled? @@ -282,20 +282,24 @@ //////////////////////////////////////////////////////////////////////////////// // Browser, CreateParams: -Browser::CreateParams::CreateParams(Profile* profile) +Browser::CreateParams::CreateParams(Profile* profile, bool user_gesture) : type(TYPE_TABBED), profile(profile), trusted_source(false), initial_show_state(ui::SHOW_STATE_DEFAULT), is_session_restore(false), + user_gesture(user_gesture), window(NULL) {} -Browser::CreateParams::CreateParams(Type type, Profile* profile) +Browser::CreateParams::CreateParams(Type type, + Profile* profile, + bool user_gesture) : type(type), profile(profile), trusted_source(false), initial_show_state(ui::SHOW_STATE_DEFAULT), is_session_restore(false), + user_gesture(user_gesture), window(NULL) {} Browser::CreateParams::CreateParams(const CreateParams& other) = default; @@ -305,10 +309,11 @@ const std::string& app_name, bool trusted_source, const gfx::Rect& window_bounds, - Profile* profile) { + Profile* profile, + bool user_gesture) { DCHECK(!app_name.empty()); - CreateParams params(TYPE_POPUP, profile); + CreateParams params(TYPE_POPUP, profile, user_gesture); params.app_name = app_name; params.trusted_source = trusted_source; params.initial_bounds = window_bounds; @@ -319,7 +324,7 @@ // static Browser::CreateParams Browser::CreateParams::CreateForDevTools( Profile* profile) { - CreateParams params(TYPE_POPUP, profile); + CreateParams params(TYPE_POPUP, profile, true); params.app_name = DevToolsWindow::kDevToolsApp; params.trusted_source = true; return params; @@ -438,7 +443,8 @@ ProfileMetrics::LogProfileLaunch(profile_); - window_ = params.window ? params.window : CreateBrowserWindow(this); + window_ = params.window ? params.window + : CreateBrowserWindow(this, params.user_gesture); if (hosted_app_controller_) hosted_app_controller_->UpdateLocationBarVisibility(false);
diff --git a/chrome/browser/ui/browser.h b/chrome/browser/ui/browser.h index 59da095..cd6244a 100644 --- a/chrome/browser/ui/browser.h +++ b/chrome/browser/ui/browser.h
@@ -156,14 +156,15 @@ }; struct CreateParams { - explicit CreateParams(Profile* profile); - CreateParams(Type type, Profile* profile); + explicit CreateParams(Profile* profile, bool user_gesture); + CreateParams(Type type, Profile* profile, bool user_gesture); CreateParams(const CreateParams& other); static CreateParams CreateForApp(const std::string& app_name, bool trusted_source, const gfx::Rect& window_bounds, - Profile* profile); + Profile* profile, + bool user_gesture); static CreateParams CreateForDevTools(Profile* profile); @@ -186,6 +187,12 @@ bool is_session_restore; + // Whether this browser was created by a user gesture. We track this + // specifically for the multi-user case in chromeos where we can place + // windows generated by user gestures differently from ones + // programmatically created. + bool user_gesture; + // Supply a custom BrowserWindow implementation, to be used instead of the // default. Intended for testing. BrowserWindow* window;
diff --git a/chrome/browser/ui/browser_browsertest.cc b/chrome/browser/ui/browser_browsertest.cc index 13c514b..5ce38f3 100644 --- a/chrome/browser/ui/browser_browsertest.cc +++ b/chrome/browser/ui/browser_browsertest.cc
@@ -1636,7 +1636,7 @@ IN_PROC_BROWSER_TEST_F(BrowserTest, StartMaximized) { Browser::Type types[] = { Browser::TYPE_TABBED, Browser::TYPE_POPUP }; for (size_t i = 0; i < arraysize(types); ++i) { - Browser::CreateParams params(types[i], browser()->profile()); + Browser::CreateParams params(types[i], browser()->profile(), true); params.initial_show_state = ui::SHOW_STATE_MAXIMIZED; AddBlankTabAndShow(new Browser(params)); } @@ -1647,7 +1647,7 @@ IN_PROC_BROWSER_TEST_F(BrowserTest, StartMinimized) { Browser::Type types[] = { Browser::TYPE_TABBED, Browser::TYPE_POPUP }; for (size_t i = 0; i < arraysize(types); ++i) { - Browser::CreateParams params(types[i], browser()->profile()); + Browser::CreateParams params(types[i], browser()->profile(), true); params.initial_show_state = ui::SHOW_STATE_MINIMIZED; AddBlankTabAndShow(new Browser(params)); } @@ -1712,8 +1712,8 @@ EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_NEW_INCOGNITO_WINDOW)); // Create a new browser. - Browser* new_browser = new Browser( - Browser::CreateParams(browser()->profile()->GetOffTheRecordProfile())); + Browser* new_browser = new Browser(Browser::CreateParams( + browser()->profile()->GetOffTheRecordProfile(), true)); CommandUpdater* new_command_updater = new_browser->command_controller()->command_updater(); // It should have Bookmarks & Settings commands disabled by default. @@ -1746,7 +1746,7 @@ // Create a new browser. Browser* new_browser = - new Browser(Browser::CreateParams(browser()->profile())); + new Browser(Browser::CreateParams(browser()->profile(), true)); CommandUpdater* new_command_updater = new_browser->command_controller()->command_updater(); EXPECT_FALSE(new_command_updater->IsCommandEnabled(IDC_NEW_INCOGNITO_WINDOW)); @@ -1779,7 +1779,7 @@ // Create a popup (non-main-UI-type) browser. Settings command as well // as Extensions should be disabled. Browser* popup_browser = new Browser( - Browser::CreateParams(Browser::TYPE_POPUP, browser()->profile())); + Browser::CreateParams(Browser::TYPE_POPUP, browser()->profile(), true)); CommandUpdater* popup_command_updater = popup_browser->command_controller()->command_updater(); EXPECT_FALSE(popup_command_updater->IsCommandEnabled(IDC_MANAGE_EXTENSIONS)); @@ -1795,7 +1795,7 @@ DisableOptionsAndImportMenuItemsConsistently) { // Create a popup browser. Browser* popup_browser = new Browser( - Browser::CreateParams(Browser::TYPE_POPUP, browser()->profile())); + Browser::CreateParams(Browser::TYPE_POPUP, browser()->profile(), true)); CommandUpdater* command_updater = popup_browser->command_controller()->command_updater(); // OPTIONS and IMPORT_SETTINGS are disabled for a non-normal UI. @@ -2860,7 +2860,8 @@ // Creates an untrusted popup window and asserts that the eventual height is // padded with the toolbar and title bar height (initial height is content // height). - Browser::CreateParams params(Browser::TYPE_POPUP, browser()->profile()); + Browser::CreateParams params(Browser::TYPE_POPUP, browser()->profile(), + true); params.initial_bounds = gfx::Rect(0, 0, 100, 122); Browser* browser = new Browser(params); gfx::Rect bounds = browser->window()->GetBounds(); @@ -2877,7 +2878,8 @@ { // Creates a trusted popup window and asserts that the eventual height // doesn't change (initial height is window height). - Browser::CreateParams params(Browser::TYPE_POPUP, browser()->profile()); + Browser::CreateParams params(Browser::TYPE_POPUP, browser()->profile(), + true); params.initial_bounds = gfx::Rect(0, 0, 100, 122); params.trusted_source = true; Browser* browser = new Browser(params); @@ -2894,7 +2896,8 @@ // Creates an untrusted app window and asserts that the eventual height // doesn't change. Browser::CreateParams params = Browser::CreateParams::CreateForApp( - "app-name", false, gfx::Rect(0, 0, 100, 122), browser()->profile()); + "app-name", false, gfx::Rect(0, 0, 100, 122), browser()->profile(), + true); Browser* browser = new Browser(params); gfx::Rect bounds = browser->window()->GetBounds(); @@ -2909,7 +2912,8 @@ // Creates a trusted app window and asserts that the eventual height // doesn't change. Browser::CreateParams params = Browser::CreateParams::CreateForApp( - "app-name", true, gfx::Rect(0, 0, 100, 122), browser()->profile()); + "app-name", true, gfx::Rect(0, 0, 100, 122), browser()->profile(), + true); Browser* browser = new Browser(params); gfx::Rect bounds = browser->window()->GetBounds();
diff --git a/chrome/browser/ui/browser_close_unittest.cc b/chrome/browser/ui/browser_close_unittest.cc index d605184..1cd55e20 100644 --- a/chrome/browser/ui/browser_close_unittest.cc +++ b/chrome/browser/ui/browser_close_unittest.cc
@@ -156,7 +156,7 @@ std::vector<Browser*> browsers; for (int i = 0; i < num_windows; ++i) { TestBrowserWindow* window = new TestBrowserWindow(); - Browser::CreateParams params(profile); + Browser::CreateParams params(profile, true); params.type = Browser::TYPE_TABBED; params.window = window; Browser* browser = new Browser(params);
diff --git a/chrome/browser/ui/browser_command_controller_unittest.cc b/chrome/browser/ui/browser_command_controller_unittest.cc index ee63765f..53bce11 100644 --- a/chrome/browser/ui/browser_command_controller_unittest.cc +++ b/chrome/browser/ui/browser_command_controller_unittest.cc
@@ -231,7 +231,7 @@ // Create a new browser based on the off the record profile. Browser::CreateParams profile_params( - original_profile->GetOffTheRecordProfile()); + original_profile->GetOffTheRecordProfile(), true); std::unique_ptr<Browser> otr_browser( chrome::CreateBrowserWithTestWindowForParams(&profile_params)); @@ -456,7 +456,8 @@ EXPECT_EQ(profile2->GetOriginalProfile(), profile1.get()); // Create a new browser based on the off the record profile. - Browser::CreateParams profile_params(profile1->GetOffTheRecordProfile()); + Browser::CreateParams profile_params(profile1->GetOffTheRecordProfile(), + true); std::unique_ptr<Browser> browser2( chrome::CreateBrowserWithTestWindowForParams(&profile_params));
diff --git a/chrome/browser/ui/browser_commands.cc b/chrome/browser/ui/browser_commands.cc index dd93505c..5beb96d4 100644 --- a/chrome/browser/ui/browser_commands.cc +++ b/chrome/browser/ui/browser_commands.cc
@@ -234,7 +234,7 @@ case WindowOpenDisposition::NEW_WINDOW: { WebContents* new_tab = current_tab->Clone(); Browser* new_browser = - new Browser(Browser::CreateParams(browser->profile())); + new Browser(Browser::CreateParams(browser->profile(), true)); new_browser->tab_strip_model()->AddWebContents( new_tab, -1, ui::PAGE_TRANSITION_LINK, TabStripModel::ADD_ACTIVE); @@ -393,7 +393,7 @@ Browser* OpenEmptyWindow(Profile* profile) { Browser* browser = - new Browser(Browser::CreateParams(Browser::TYPE_TABBED, profile)); + new Browser(Browser::CreateParams(Browser::TYPE_TABBED, profile, true)); AddTabAt(browser, GURL(), -1, true); browser->window()->Show(); return browser; @@ -705,10 +705,10 @@ if (browser->is_app() && !browser->is_type_popup()) { new_browser = new Browser(Browser::CreateParams::CreateForApp( browser->app_name(), browser->is_trusted_source(), gfx::Rect(), - browser->profile())); + browser->profile(), true)); } else { new_browser = new Browser( - Browser::CreateParams(browser->type(), browser->profile())); + Browser::CreateParams(browser->type(), browser->profile(), true)); } // Preserve the size of the original window. The new window has already // been given an offset by the OS, so we shouldn't copy the old bounds. @@ -748,7 +748,7 @@ TabStripModel* tab_strip = browser->tab_strip_model(); WebContents* contents = tab_strip->DetachWebContentsAt(tab_strip->active_index()); - Browser* b = new Browser(Browser::CreateParams(browser->profile())); + Browser* b = new Browser(Browser::CreateParams(browser->profile(), true)); b->tab_strip_model()->AppendWebContents(contents, true); b->window()->Show(); } @@ -1265,7 +1265,7 @@ add_types); } else { Browser* b = new Browser( - Browser::CreateParams(Browser::TYPE_TABBED, browser->profile())); + Browser::CreateParams(Browser::TYPE_TABBED, browser->profile(), true)); // Preserve the size of the original window. The new window has already // been given an offset by the OS, so we shouldn't copy the old bounds. @@ -1336,7 +1336,8 @@ browser->tab_strip_model()->DetachWebContentsAt(index); Browser* app_browser = new Browser(Browser::CreateParams::CreateForApp( - app_name, true /* trusted_source */, gfx::Rect(), browser->profile())); + app_name, true /* trusted_source */, gfx::Rect(), browser->profile(), + true)); app_browser->tab_strip_model()->AppendWebContents(contents, true); contents->GetMutableRendererPrefs()->can_accept_load_drops = false;
diff --git a/chrome/browser/ui/browser_finder_chromeos_unittest.cc b/chrome/browser/ui/browser_finder_chromeos_unittest.cc index c9802e2b..00e9400 100644 --- a/chrome/browser/ui/browser_finder_chromeos_unittest.cc +++ b/chrome/browser/ui/browser_finder_chromeos_unittest.cc
@@ -116,7 +116,7 @@ set_browser(nullptr); // Create an incognito browser. - Browser::CreateParams params(profile()->GetOffTheRecordProfile()); + Browser::CreateParams params(profile()->GetOffTheRecordProfile(), true); std::unique_ptr<Browser> incognito_browser( chrome::CreateBrowserWithAuraTestWindowForParams(nullptr, ¶ms)); // Incognito windows are excluded in GetBrowserCount() because kMatchAll @@ -129,7 +129,7 @@ TEST_F(BrowserFinderChromeOSTest, FindBrowserOwnedByAnotherProfile) { set_browser(nullptr); - Browser::CreateParams params(profile()->GetOriginalProfile()); + Browser::CreateParams params(profile()->GetOriginalProfile(), true); std::unique_ptr<Browser> browser( chrome::CreateBrowserWithAuraTestWindowForParams(nullptr, ¶ms)); GetUserWindowManager()->SetWindowOwner(browser->window()->GetNativeWindow(),
diff --git a/chrome/browser/ui/browser_focus_uitest.cc b/chrome/browser/ui/browser_focus_uitest.cc index f46298a5..17d0c468 100644 --- a/chrome/browser/ui/browser_focus_uitest.cc +++ b/chrome/browser/ui/browser_focus_uitest.cc
@@ -372,7 +372,8 @@ ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser())); // Open a new browser window. - Browser* browser2 = new Browser(Browser::CreateParams(browser()->profile())); + Browser* browser2 = + new Browser(Browser::CreateParams(browser()->profile(), true)); ASSERT_TRUE(browser2); chrome::AddTabAt(browser2, GURL(), -1, true);
diff --git a/chrome/browser/ui/browser_instant_controller_unittest.cc b/chrome/browser/ui/browser_instant_controller_unittest.cc index fe12849..0db9e7e 100644 --- a/chrome/browser/ui/browser_instant_controller_unittest.cc +++ b/chrome/browser/ui/browser_instant_controller_unittest.cc
@@ -223,7 +223,7 @@ TEST_F(BrowserInstantControllerTest, BrowserWindowLifecycle) { std::unique_ptr<BrowserWindow> window(CreateBrowserWindow()); - Browser::CreateParams params(profile()); + Browser::CreateParams params(profile(), true); params.window = window.get(); std::unique_ptr<Browser> browser(new Browser(params)); InstantServiceObserver* bic;
diff --git a/chrome/browser/ui/browser_live_tab_context.cc b/chrome/browser/ui/browser_live_tab_context.cc index 40892e2..c6ee3f0 100644 --- a/chrome/browser/ui/browser_live_tab_context.cc +++ b/chrome/browser/ui/browser_live_tab_context.cc
@@ -108,11 +108,11 @@ const std::string& app_name) { Browser* browser; if (app_name.empty()) { - browser = new Browser(Browser::CreateParams(profile)); + browser = new Browser(Browser::CreateParams(profile, true)); } else { // Only trusted app popup windows should ever be restored. browser = new Browser(Browser::CreateParams::CreateForApp( - app_name, true /* trusted_source */, gfx::Rect(), profile)); + app_name, true /* trusted_source */, gfx::Rect(), profile, true)); } if (browser) return browser->live_tab_context();
diff --git a/chrome/browser/ui/browser_mac.cc b/chrome/browser/ui/browser_mac.cc index 319b318..9719eba 100644 --- a/chrome/browser/ui/browser_mac.cc +++ b/chrome/browser/ui/browser_mac.cc
@@ -11,56 +11,55 @@ namespace chrome { void OpenAboutWindow(Profile* profile) { - Browser* browser = new Browser(Browser::CreateParams(profile)); + Browser* browser = new Browser(Browser::CreateParams(profile, true)); ShowAboutChrome(browser); browser->window()->Show(); } void OpenHistoryWindow(Profile* profile) { - Browser* browser = - new Browser(Browser::CreateParams(profile)); + Browser* browser = new Browser(Browser::CreateParams(profile, true)); ShowHistory(browser); browser->window()->Show(); } void OpenDownloadsWindow(Profile* profile) { - Browser* browser = new Browser(Browser::CreateParams(profile)); + Browser* browser = new Browser(Browser::CreateParams(profile, true)); ShowDownloads(browser); browser->window()->Show(); } void OpenHelpWindow(Profile* profile, HelpSource source) { - Browser* browser = new Browser(Browser::CreateParams(profile)); + Browser* browser = new Browser(Browser::CreateParams(profile, true)); ShowHelp(browser, source); browser->window()->Show(); } void OpenOptionsWindow(Profile* profile) { - Browser* browser = new Browser(Browser::CreateParams(profile)); + Browser* browser = new Browser(Browser::CreateParams(profile, true)); ShowSettings(browser); browser->window()->Show(); } void OpenClearBrowsingDataDialogWindow(Profile* profile) { - Browser* browser = new Browser(Browser::CreateParams(profile)); + Browser* browser = new Browser(Browser::CreateParams(profile, true)); ShowClearBrowsingDataDialog(browser); browser->window()->Show(); } void OpenImportSettingsDialogWindow(Profile* profile) { - Browser* browser = new Browser(Browser::CreateParams(profile)); + Browser* browser = new Browser(Browser::CreateParams(profile, true)); ShowImportDialog(browser); browser->window()->Show(); } void OpenBookmarkManagerWindow(Profile* profile) { - Browser* browser = new Browser(Browser::CreateParams(profile)); + Browser* browser = new Browser(Browser::CreateParams(profile, true)); ShowBookmarkManager(browser); browser->window()->Show(); } void OpenExtensionsWindow(Profile* profile) { - Browser* browser = new Browser(Browser::CreateParams(profile)); + Browser* browser = new Browser(Browser::CreateParams(profile, true)); ShowExtensions(browser, std::string()); browser->window()->Show(); }
diff --git a/chrome/browser/ui/browser_navigator.cc b/chrome/browser/ui/browser_navigator.cc index f7714d42..4197fba 100644 --- a/chrome/browser/ui/browser_navigator.cc +++ b/chrome/browser/ui/browser_navigator.cc
@@ -81,9 +81,10 @@ // Finds an existing Browser compatible with |profile|, making a new one if no // such Browser is located. -Browser* GetOrCreateBrowser(Profile* profile) { +Browser* GetOrCreateBrowser(Profile* profile, bool user_gesture) { Browser* browser = chrome::FindTabbedBrowser(profile, false); - return browser ? browser : new Browser(Browser::CreateParams(profile)); + return browser ? browser + : new Browser(Browser::CreateParams(profile, user_gesture)); } // Change some of the navigation parameters based on the particular URL. @@ -114,7 +115,7 @@ } params->disposition = WindowOpenDisposition::SINGLETON_TAB; - params->browser = GetOrCreateBrowser(profile); + params->browser = GetOrCreateBrowser(profile, params->user_gesture); params->window_action = chrome::NavigateParams::SHOW_WINDOW; } @@ -142,7 +143,7 @@ return params->browser; // Find a compatible window and re-execute this command in it. Otherwise // re-run with NEW_WINDOW. - return GetOrCreateBrowser(profile); + return GetOrCreateBrowser(profile, params->user_gesture); case WindowOpenDisposition::SINGLETON_TAB: case WindowOpenDisposition::NEW_FOREGROUND_TAB: case WindowOpenDisposition::NEW_BACKGROUND_TAB: @@ -151,7 +152,7 @@ return params->browser; // Find a compatible window and re-execute this command in it. Otherwise // re-run with NEW_WINDOW. - return GetOrCreateBrowser(profile); + return GetOrCreateBrowser(profile, params->user_gesture); case WindowOpenDisposition::NEW_POPUP: { // Make a new popup window. // Coerce app-style if |source| represents an app. @@ -172,22 +173,25 @@ } #endif if (app_name.empty()) { - Browser::CreateParams browser_params(Browser::TYPE_POPUP, profile); + Browser::CreateParams browser_params(Browser::TYPE_POPUP, profile, + params->user_gesture); browser_params.trusted_source = params->trusted_source; browser_params.initial_bounds = params->window_bounds; return new Browser(browser_params); } return new Browser(Browser::CreateParams::CreateForApp( - app_name, params->trusted_source, params->window_bounds, profile)); + app_name, params->trusted_source, params->window_bounds, profile, + params->user_gesture)); } case WindowOpenDisposition::NEW_WINDOW: { // Make a new normal browser window. - return new Browser(Browser::CreateParams(profile)); + return new Browser(Browser::CreateParams(profile, params->user_gesture)); } case WindowOpenDisposition::OFF_THE_RECORD: // Make or find an incognito window. - return GetOrCreateBrowser(profile->GetOffTheRecordProfile()); + return GetOrCreateBrowser(profile->GetOffTheRecordProfile(), + params->user_gesture); // The following types result in no navigation. case WindowOpenDisposition::SAVE_TO_DISK: case WindowOpenDisposition::IGNORE_ACTION:
diff --git a/chrome/browser/ui/browser_navigator_browsertest.cc b/chrome/browser/ui/browser_navigator_browsertest.cc index 37c4be3..adf0321 100644 --- a/chrome/browser/ui/browser_navigator_browsertest.cc +++ b/chrome/browser/ui/browser_navigator_browsertest.cc
@@ -121,14 +121,14 @@ Browser* BrowserNavigatorTest::CreateEmptyBrowserForType(Browser::Type type, Profile* profile) { - Browser* browser = new Browser(Browser::CreateParams(type, profile)); + Browser* browser = new Browser(Browser::CreateParams(type, profile, true)); chrome::AddTabAt(browser, GURL(), -1, true); return browser; } Browser* BrowserNavigatorTest::CreateEmptyBrowserForApp(Profile* profile) { Browser* browser = new Browser(Browser::CreateParams::CreateForApp( - "Test", false /* trusted_source */, gfx::Rect(), profile)); + "Test", false /* trusted_source */, gfx::Rect(), profile, true)); chrome::AddTabAt(browser, GURL(), -1, true); return browser; }
diff --git a/chrome/browser/ui/browser_tab_strip_model_delegate.cc b/chrome/browser/ui/browser_tab_strip_model_delegate.cc index 52d1a020..8788e4a8 100644 --- a/chrome/browser/ui/browser_tab_strip_model_delegate.cc +++ b/chrome/browser/ui/browser_tab_strip_model_delegate.cc
@@ -57,7 +57,7 @@ DCHECK(browser_->CanSupportWindowFeature(Browser::FEATURE_TABSTRIP)); // Create an empty new browser window the same size as the old one. - Browser::CreateParams params(browser_->profile()); + Browser::CreateParams params(browser_->profile(), true); params.initial_bounds = window_bounds; params.initial_show_state = maximize ? ui::SHOW_STATE_MAXIMIZED : ui::SHOW_STATE_NORMAL;
diff --git a/chrome/browser/ui/browser_window.h b/chrome/browser/ui/browser_window.h index 136dd3e..58f4c448 100644 --- a/chrome/browser/ui/browser_window.h +++ b/chrome/browser/ui/browser_window.h
@@ -348,7 +348,8 @@ const gfx::Size& new_size) {} // Construct a BrowserWindow implementation for the specified |browser|. - static BrowserWindow* CreateBrowserWindow(Browser* browser); + static BrowserWindow* CreateBrowserWindow(Browser* browser, + bool user_gesture); // Shows the avatar bubble on the window frame off of the avatar button with // the given mode. The Service Type specified by GAIA is provided as well.
diff --git a/chrome/browser/ui/chrome_pages.cc b/chrome/browser/ui/chrome_pages.cc index 6dea3c41..95ad166 100644 --- a/chrome/browser/ui/chrome_pages.cc +++ b/chrome/browser/ui/chrome_pages.cc
@@ -335,7 +335,7 @@ } Browser* browser = chrome::FindTabbedBrowser(profile, false); if (!browser) { - browser = new Browser(Browser::CreateParams(profile)); + browser = new Browser(Browser::CreateParams(profile, true)); } ShowSettingsSubPageInTabbedBrowser(browser, sub_page_path); }
diff --git a/chrome/browser/ui/cocoa/applescript/browsercrapplication+applescript_test.mm b/chrome/browser/ui/cocoa/applescript/browsercrapplication+applescript_test.mm index d77411d8..a11054a1 100644 --- a/chrome/browser/ui/cocoa/applescript/browsercrapplication+applescript_test.mm +++ b/chrome/browser/ui/cocoa/applescript/browsercrapplication+applescript_test.mm
@@ -27,9 +27,9 @@ // Create additional |Browser*| objects of different type. Profile* profile = browser()->profile(); Browser* b1 = - new Browser(Browser::CreateParams(Browser::TYPE_POPUP, profile)); + new Browser(Browser::CreateParams(Browser::TYPE_POPUP, profile, true)); Browser* b2 = new Browser(Browser::CreateParams::CreateForApp( - "Test", true /* trusted_source */, gfx::Rect(), profile)); + "Test", true /* trusted_source */, gfx::Rect(), profile, true)); EXPECT_EQ(3U, [[NSApp appleScriptWindows] count]); for (WindowAppleScript* window in [NSApp appleScriptWindows]) {
diff --git a/chrome/browser/ui/cocoa/applescript/window_applescript.mm b/chrome/browser/ui/cocoa/applescript/window_applescript.mm index e77835b..9cbb85cb 100644 --- a/chrome/browser/ui/cocoa/applescript/window_applescript.mm +++ b/chrome/browser/ui/cocoa/applescript/window_applescript.mm
@@ -77,7 +77,7 @@ } if ((self = [super init])) { - browser_ = new Browser(Browser::CreateParams(aProfile)); + browser_ = new Browser(Browser::CreateParams(aProfile, false)); chrome::NewTab(browser_); browser_->window()->Show(); base::scoped_nsobject<NSNumber> numID(
diff --git a/chrome/browser/ui/cocoa/apps/app_shim_menu_controller_mac_interactive_uitest.mm b/chrome/browser/ui/cocoa/apps/app_shim_menu_controller_mac_interactive_uitest.mm index 72f333e..97ea6f6 100644 --- a/chrome/browser/ui/cocoa/apps/app_shim_menu_controller_mac_interactive_uitest.mm +++ b/chrome/browser/ui/cocoa/apps/app_shim_menu_controller_mac_interactive_uitest.mm
@@ -48,7 +48,7 @@ app1_ = GetFirstAppWindow(); app2_ = CreateAppWindow(browser()->profile(), extension); browser1_ = browser()->window(); - browser2_ = (new Browser(Browser::CreateParams(profile())))->window(); + browser2_ = (new Browser(Browser::CreateParams(profile(), true)))->window(); browser2_->Show(); // Since a pending key status change on any window could cause the test to
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_editor_base_controller_unittest.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_editor_base_controller_unittest.mm index f4282078..98d5d3b 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_editor_base_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_editor_base_controller_unittest.mm
@@ -102,7 +102,7 @@ } Browser* CreateBrowser() override { - Browser::CreateParams params(profile()); + Browser::CreateParams params(profile(), true); return chrome::CreateBrowserWithTestWindowForParams(¶ms).release(); } };
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_menu_cocoa_controller.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_menu_cocoa_controller.mm index 88b94229..bac5b5f 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_menu_cocoa_controller.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_menu_cocoa_controller.mm
@@ -93,7 +93,7 @@ - (void)openURLForNode:(const BookmarkNode*)node { Browser* browser = chrome::FindTabbedBrowser(bridge_->GetProfile(), true); if (!browser) { - browser = new Browser(Browser::CreateParams(bridge_->GetProfile())); + browser = new Browser(Browser::CreateParams(bridge_->GetProfile(), true)); } WindowOpenDisposition disposition = ui::WindowOpenDispositionFromNSEvent([NSApp currentEvent]); @@ -113,7 +113,7 @@ Browser* browser = chrome::FindTabbedBrowser(bridge_->GetProfile(), true); if (!browser) { - browser = new Browser(Browser::CreateParams(bridge_->GetProfile())); + browser = new Browser(Browser::CreateParams(bridge_->GetProfile(), true)); } DCHECK(browser);
diff --git a/chrome/browser/ui/cocoa/browser_window_controller_unittest.mm b/chrome/browser/ui/cocoa/browser_window_controller_unittest.mm index a22fc45..b99bc47 100644 --- a/chrome/browser/ui/cocoa/browser_window_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/browser_window_controller_unittest.mm
@@ -127,7 +127,7 @@ // And make sure a controller for a pop-up window is not normal. // popup_browser will be owned by its window. Browser* popup_browser( - new Browser(Browser::CreateParams(Browser::TYPE_POPUP, profile()))); + new Browser(Browser::CreateParams(Browser::TYPE_POPUP, profile(), true))); NSWindow* cocoaWindow = popup_browser->window()->GetNativeWindow(); BrowserWindowController* controller = static_cast<BrowserWindowController*>([cocoaWindow windowController]); @@ -141,7 +141,7 @@ TEST_F(BrowserWindowControllerTest, TestSetBounds) { // Create a normal browser with bounds smaller than the minimum. - Browser::CreateParams params(Browser::TYPE_TABBED, profile()); + Browser::CreateParams params(Browser::TYPE_TABBED, profile(), true); params.initial_bounds = gfx::Rect(0, 0, 50, 50); Browser* browser = new Browser(params); NSWindow* cocoaWindow = browser->window()->GetNativeWindow(); @@ -166,7 +166,7 @@ TEST_F(BrowserWindowControllerTest, TestSetBoundsPopup) { // Create a popup with bounds smaller than the minimum. - Browser::CreateParams params(Browser::TYPE_POPUP, profile()); + Browser::CreateParams params(Browser::TYPE_POPUP, profile(), true); params.initial_bounds = gfx::Rect(0, 0, 50, 50); Browser* browser = new Browser(params); NSWindow* cocoaWindow = browser->window()->GetNativeWindow(); @@ -206,7 +206,7 @@ } TEST_F(BrowserWindowControllerTest, BookmarkBarToggleRespectMinWindowHeight) { - Browser::CreateParams params(Browser::TYPE_TABBED, profile()); + Browser::CreateParams params(Browser::TYPE_TABBED, profile(), true); params.initial_bounds = gfx::Rect(0, 0, 50, 280); Browser* browser = new Browser(params); NSWindow* cocoaWindow = browser->window()->GetNativeWindow(); @@ -233,7 +233,7 @@ std::unique_ptr<TestingProfile> incognito_profile(new TestingProfile()); incognito_profile->set_off_the_record(true); std::unique_ptr<Browser> browser( - new Browser(Browser::CreateParams(incognito_profile.get()))); + new Browser(Browser::CreateParams(incognito_profile.get(), true))); controller_.reset([[BrowserWindowController alloc] initWithBrowser:browser.get() takeOwnership:NO]);
diff --git a/chrome/browser/ui/cocoa/browser_window_factory_cocoa.mm b/chrome/browser/ui/cocoa/browser_window_factory_cocoa.mm index 5ba5199..d18e12f2 100644 --- a/chrome/browser/ui/cocoa/browser_window_factory_cocoa.mm +++ b/chrome/browser/ui/cocoa/browser_window_factory_cocoa.mm
@@ -9,7 +9,8 @@ // Create the controller for the Browser, which handles loading the browser // window from the nib. The controller takes ownership of |browser|. // static -BrowserWindow* BrowserWindow::CreateBrowserWindow(Browser* browser) { +BrowserWindow* BrowserWindow::CreateBrowserWindow(Browser* browser, + bool user_gesture) { BrowserWindowController* controller = [[BrowserWindowController alloc] initWithBrowser:browser]; return [controller browserWindow];
diff --git a/chrome/browser/ui/cocoa/l10n_util.h b/chrome/browser/ui/cocoa/l10n_util.h index a7d8a80..8457c7f 100644 --- a/chrome/browser/ui/cocoa/l10n_util.h +++ b/chrome/browser/ui/cocoa/l10n_util.h
@@ -49,4 +49,8 @@ // OSes would make Chrome stick out. bool ShouldFlipWindowControlsInRTL(); +// Returns an autoreleased image containing |image| flipped +// across the x axis. +NSImage* FlippedImage(NSImage* image); + } // namespace cocoa_l10n_util
diff --git a/chrome/browser/ui/cocoa/l10n_util.mm b/chrome/browser/ui/cocoa/l10n_util.mm index 73db01d..1479c172 100644 --- a/chrome/browser/ui/cocoa/l10n_util.mm +++ b/chrome/browser/ui/cocoa/l10n_util.mm
@@ -96,4 +96,28 @@ return ShouldDoExperimentalRTLLayout() && base::mac::IsAtLeastOS10_12(); } +// Adapted from Apple's RTL docs (goo.gl/cBaFnT) +NSImage* FlippedImage(NSImage* image) { + const NSSize size = [image size]; + NSImage* flipped_image = [[[NSImage alloc] initWithSize:size] autorelease]; + + [flipped_image lockFocus]; + [[NSGraphicsContext currentContext] + setImageInterpolation:NSImageInterpolationHigh]; + + NSAffineTransform* transform = [NSAffineTransform transform]; + [transform translateXBy:size.width yBy:0]; + [transform scaleXBy:-1 yBy:1]; + [transform concat]; + + [image drawAtPoint:NSZeroPoint + fromRect:NSMakeRect(0, 0, size.width, size.height) + operation:NSCompositeSourceOver + fraction:1.0]; + + [flipped_image unlockFocus]; + + return flipped_image; +} + } // namespace cocoa_l10n_util
diff --git a/chrome/browser/ui/cocoa/location_bar/content_setting_decoration.mm b/chrome/browser/ui/cocoa/location_bar/content_setting_decoration.mm index 8225147..20ff012 100644 --- a/chrome/browser/ui/cocoa/location_bar/content_setting_decoration.mm +++ b/chrome/browser/ui/cocoa/location_bar/content_setting_decoration.mm
@@ -262,7 +262,14 @@ } NSPoint ContentSettingDecoration::GetBubblePointInFrame(NSRect frame) { - + // Compute the frame as if there is no animation pill in the Omnibox. Place + // the bubble where the icon would be without animation, so when the animation + // ends, the bubble is pointing in the right place. + CGFloat final_width = ImageDecoration::GetWidthForSpace(NSWidth(frame)); + NSSize image_size = NSMakeSize(final_width, NSHeight(frame)); + if (!cocoa_l10n_util::ShouldDoExperimentalRTLLayout()) + frame.origin.x += frame.size.width - image_size.width; + frame.size = image_size; const NSRect draw_frame = GetDrawRectInFrame(frame); return NSMakePoint(NSMidX(draw_frame), NSMaxY(draw_frame) + kPageBubblePointYOffset);
diff --git a/chrome/browser/ui/cocoa/profiles/avatar_icon_controller_unittest.mm b/chrome/browser/ui/cocoa/profiles/avatar_icon_controller_unittest.mm index e5170950..18fe91c 100644 --- a/chrome/browser/ui/cocoa/profiles/avatar_icon_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/profiles/avatar_icon_controller_unittest.mm
@@ -49,8 +49,8 @@ }; TEST_F(AvatarIconControllerTest, ShowingAvatarIconInIncognito) { - Browser* browser = - new Browser(Browser::CreateParams(profile()->GetOffTheRecordProfile())); + Browser* browser = new Browser( + Browser::CreateParams(profile()->GetOffTheRecordProfile(), true)); BrowserWindowCocoa* window = static_cast<BrowserWindowCocoa*>(browser->window()); AvatarBaseController* icon_controller =
diff --git a/chrome/browser/ui/cocoa/profiles/profile_menu_controller_unittest.mm b/chrome/browser/ui/cocoa/profiles/profile_menu_controller_unittest.mm index 98dc739..05cd5b29 100644 --- a/chrome/browser/ui/cocoa/profiles/profile_menu_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/profiles/profile_menu_controller_unittest.mm
@@ -204,7 +204,7 @@ ASSERT_EQ(7, [menu numberOfItems]); // Create a browser and "show" it. - Browser::CreateParams profile2_params(profile2); + Browser::CreateParams profile2_params(profile2, true); std::unique_ptr<Browser> p2_browser( chrome::CreateBrowserWithTestWindowForParams(&profile2_params)); BrowserList::SetLastActive(p2_browser.get()); @@ -215,7 +215,7 @@ VerifyProfileNamedIsActive(@"Profile 2", __LINE__); // Open a new browser and make sure it takes effect. - Browser::CreateParams profile3_params(profile3); + Browser::CreateParams profile3_params(profile3, true); std::unique_ptr<Browser> p3_browser( chrome::CreateBrowserWithTestWindowForParams(&profile3_params)); BrowserList::SetLastActive(p3_browser.get()); @@ -282,7 +282,7 @@ EXPECT_TRUE([controller() validateMenuItem:item]); // Open a new browser for the supervised user and switch to it. - Browser::CreateParams supervised_profile_params(supervised_profile); + Browser::CreateParams supervised_profile_params(supervised_profile, true); std::unique_ptr<Browser> supervised_browser( chrome::CreateBrowserWithTestWindowForParams(&supervised_profile_params)); BrowserList::SetLastActive(supervised_browser.get());
diff --git a/chrome/browser/ui/cocoa/test/cocoa_profile_test.mm b/chrome/browser/ui/cocoa/test/cocoa_profile_test.mm index 707f143..4362c46 100644 --- a/chrome/browser/ui/cocoa/test/cocoa_profile_test.mm +++ b/chrome/browser/ui/cocoa/test/cocoa_profile_test.mm
@@ -94,5 +94,5 @@ } Browser* CocoaProfileTest::CreateBrowser() { - return new Browser(Browser::CreateParams(profile())); + return new Browser(Browser::CreateParams(profile(), true)); }
diff --git a/chrome/browser/ui/cocoa/toolbar/toolbar_button_cocoa.mm b/chrome/browser/ui/cocoa/toolbar/toolbar_button_cocoa.mm index 6e7e612..2640313 100644 --- a/chrome/browser/ui/cocoa/toolbar/toolbar_button_cocoa.mm +++ b/chrome/browser/ui/cocoa/toolbar/toolbar_button_cocoa.mm
@@ -207,12 +207,11 @@ } - (const gfx::VectorIcon*)vectorIcon { - BOOL isRTL = cocoa_l10n_util::ShouldDoExperimentalRTLLayout(); switch ([self viewID]) { case VIEW_ID_BACK_BUTTON: - return isRTL ? &ui::kForwardArrowIcon : &ui::kBackArrowIcon; + return &ui::kBackArrowIcon; case VIEW_ID_FORWARD_BUTTON: - return isRTL ? &ui::kBackArrowIcon : &ui::kForwardArrowIcon; + return &ui::kForwardArrowIcon; case VIEW_ID_HOME_BUTTON: return &kNavigateHomeIcon; case VIEW_ID_APP_MENU: @@ -312,17 +311,21 @@ normalIcon = [self browserToolsIconForFillColor:normalColor]; disabledIcon = [self browserToolsIconForFillColor:disabledColor]; } else { + BOOL isRTL = cocoa_l10n_util::ShouldDoExperimentalRTLLayout(); normalIcon = NSImageFromImageSkia( gfx::CreateVectorIcon(*icon, kMDButtonIconSize.width, normalColor)); - + if (isRTL) + normalIcon = cocoa_l10n_util::FlippedImage(normalIcon); // The home button has no icon for its disabled state. if (icon != &kNavigateReloadIcon) { disabledIcon = NSImageFromImageSkia( gfx::CreateVectorIcon(*icon, kMDButtonIconSize.width, disabledColor)); + if (isRTL) + disabledIcon = cocoa_l10n_util::FlippedImage(disabledIcon); } } }
diff --git a/chrome/browser/ui/extensions/application_launch.cc b/chrome/browser/ui/extensions/application_launch.cc index 56d65659..e159943 100644 --- a/chrome/browser/ui/extensions/application_launch.cc +++ b/chrome/browser/ui/extensions/application_launch.cc
@@ -194,8 +194,10 @@ extensions::AppLaunchInfo::GetLaunchHeight(extension)); } + // TODO(erg): AppLaunchParams should pass through the user_gesture from the + // extension system here. Browser::CreateParams browser_params(Browser::CreateParams::CreateForApp( - app_name, true /* trusted_source */, initial_bounds, profile)); + app_name, true /* trusted_source */, initial_bounds, profile, true)); browser_params.initial_show_state = DetermineWindowShowState(profile, params.container, @@ -230,7 +232,11 @@ WebContents* contents = NULL; if (!browser) { // No browser for this profile, need to open a new one. - browser = new Browser(Browser::CreateParams(Browser::TYPE_TABBED, profile)); + // + // TODO(erg): AppLaunchParams should pass user_gesture from the extension + // system to here. + browser = + new Browser(Browser::CreateParams(Browser::TYPE_TABBED, profile, true)); browser->window()->Show(); // There's no current tab in this browser window, so add a new one. disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
diff --git a/chrome/browser/ui/extensions/extension_message_bubble_bridge_unittest.cc b/chrome/browser/ui/extensions/extension_message_bubble_bridge_unittest.cc index aa206d63..bbf6f6f0 100644 --- a/chrome/browser/ui/extensions/extension_message_bubble_bridge_unittest.cc +++ b/chrome/browser/ui/extensions/extension_message_bubble_bridge_unittest.cc
@@ -65,7 +65,7 @@ InitializeEmptyExtensionService(); browser_window_.reset(new TestBrowserWindow()); - Browser::CreateParams params(profile()); + Browser::CreateParams params(profile(), true); params.type = Browser::TYPE_TABBED; params.window = browser_window_.get(); browser_.reset(new Browser(params));
diff --git a/chrome/browser/ui/extensions/extension_message_bubble_browsertest.cc b/chrome/browser/ui/extensions/extension_message_bubble_browsertest.cc index 887fc11..6e76c1aa 100644 --- a/chrome/browser/ui/extensions/extension_message_bubble_browsertest.cc +++ b/chrome/browser/ui/extensions/extension_message_bubble_browsertest.cc
@@ -108,7 +108,7 @@ extensions::Manifest::UNPACKED); extension_service()->AddExtension(action_extension.get()); - Browser* second_browser = new Browser(Browser::CreateParams(profile())); + Browser* second_browser = new Browser(Browser::CreateParams(profile(), true)); ASSERT_TRUE(second_browser); second_browser->window()->Show(); base::RunLoop().RunUntilIdle(); @@ -124,7 +124,7 @@ extensions::extension_action_test_util::NO_ACTION, extensions::Manifest::UNPACKED); extension_service()->AddExtension(no_action_extension.get()); - Browser* second_browser = new Browser(Browser::CreateParams(profile())); + Browser* second_browser = new Browser(Browser::CreateParams(profile(), true)); ASSERT_TRUE(second_browser); second_browser->window()->Show(); base::RunLoop().RunUntilIdle(); @@ -148,7 +148,7 @@ extensions::Manifest::INTERNAL); extension_service()->AddExtension(action_extension.get()); - Browser* second_browser = new Browser(Browser::CreateParams(profile())); + Browser* second_browser = new Browser(Browser::CreateParams(profile(), true)); ASSERT_TRUE(second_browser); second_browser->window()->Show(); base::RunLoop().RunUntilIdle(); @@ -169,7 +169,7 @@ // Create a second browser with the extension installed - the bubble will be // set to show. - Browser* second_browser = new Browser(Browser::CreateParams(profile())); + Browser* second_browser = new Browser(Browser::CreateParams(profile(), true)); ASSERT_TRUE(second_browser); second_browser->window()->Show(); // Uninstall the extension before the bubble is shown. This should not crash, @@ -199,7 +199,7 @@ extensions::Manifest::UNPACKED); extension_service()->AddExtension(action_extension.get()); - Browser* second_browser = new Browser(Browser::CreateParams(profile())); + Browser* second_browser = new Browser(Browser::CreateParams(profile(), true)); ASSERT_TRUE(second_browser); second_browser->window()->Show(); base::RunLoop().RunUntilIdle(); @@ -209,7 +209,7 @@ base::RunLoop().RunUntilIdle(); // The bubble was already shown, so it shouldn't be shown again. - Browser* third_browser = new Browser(Browser::CreateParams(profile())); + Browser* third_browser = new Browser(Browser::CreateParams(profile(), true)); ASSERT_TRUE(third_browser); third_browser->window()->Show(); base::RunLoop().RunUntilIdle(); @@ -297,13 +297,13 @@ void ExtensionMessageBubbleBrowserTest::TestBubbleWithMultipleWindows() { CheckBubbleIsNotPresent(browser(), false, false); LoadExtension(test_data_dir_.AppendASCII("good_unpacked")); - Browser* second_browser = new Browser(Browser::CreateParams(profile())); + Browser* second_browser = new Browser(Browser::CreateParams(profile(), true)); ASSERT_TRUE(second_browser); second_browser->window()->Show(); - Browser* third_browser = new Browser(Browser::CreateParams(profile())); + Browser* third_browser = new Browser(Browser::CreateParams(profile(), true)); ASSERT_TRUE(third_browser); third_browser->window()->Show(); - Browser* fourth_browser = new Browser(Browser::CreateParams(profile())); + Browser* fourth_browser = new Browser(Browser::CreateParams(profile(), true)); ASSERT_TRUE(fourth_browser); fourth_browser->window()->Show(); base::RunLoop().RunUntilIdle(); @@ -319,7 +319,7 @@ void ExtensionMessageBubbleBrowserTest::TestClickingLearnMoreButton() { CheckBubbleIsNotPresent(browser(), false, false); LoadExtension(test_data_dir_.AppendASCII("good_unpacked")); - Browser* second_browser = new Browser(Browser::CreateParams(profile())); + Browser* second_browser = new Browser(Browser::CreateParams(profile(), true)); ASSERT_TRUE(second_browser); second_browser->window()->Show(); base::RunLoop().RunUntilIdle(); @@ -344,7 +344,7 @@ extensions::ExtensionRegistry::Get(profile()); std::string id = extension->id(); EXPECT_TRUE(registry->enabled_extensions().GetByID(id)); - Browser* second_browser = new Browser(Browser::CreateParams(profile())); + Browser* second_browser = new Browser(Browser::CreateParams(profile(), true)); ASSERT_TRUE(second_browser); second_browser->window()->Show(); base::RunLoop().RunUntilIdle(); @@ -364,7 +364,7 @@ extensions::ExtensionRegistry::Get(profile()); std::string id = extension->id(); EXPECT_TRUE(registry->enabled_extensions().GetByID(id)); - Browser* second_browser = new Browser(Browser::CreateParams(profile())); + Browser* second_browser = new Browser(Browser::CreateParams(profile(), true)); ASSERT_TRUE(second_browser); second_browser->window()->Show(); base::RunLoop().RunUntilIdle();
diff --git a/chrome/browser/ui/find_bar/find_bar_host_browsertest.cc b/chrome/browser/ui/find_bar/find_bar_host_browsertest.cc index 27e3404..1a1b9ffd 100644 --- a/chrome/browser/ui/find_bar/find_bar_host_browsertest.cc +++ b/chrome/browser/ui/find_bar/find_bar_host_browsertest.cc
@@ -1333,7 +1333,7 @@ // Open a new incognito window and navigate to the same page. Profile* incognito_profile = browser()->profile()->GetOffTheRecordProfile(); Browser* incognito_browser = - new Browser(Browser::CreateParams(incognito_profile)); + new Browser(Browser::CreateParams(incognito_profile, true)); content::WindowedNotificationObserver observer( content::NOTIFICATION_LOAD_STOP, content::NotificationService::AllSources()); @@ -1394,7 +1394,7 @@ } IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, FitWindow) { - Browser::CreateParams params(Browser::TYPE_POPUP, browser()->profile()); + Browser::CreateParams params(Browser::TYPE_POPUP, browser()->profile(), true); params.initial_bounds = gfx::Rect(0, 0, 250, 500); Browser* popup = new Browser(params); content::WindowedNotificationObserver observer(
diff --git a/chrome/browser/ui/libgtkui/app_indicator_icon.cc b/chrome/browser/ui/libgtkui/app_indicator_icon.cc index 3aafd0a..eddbddd 100644 --- a/chrome/browser/ui/libgtkui/app_indicator_icon.cc +++ b/chrome/browser/ui/libgtkui/app_indicator_icon.cc
@@ -72,14 +72,15 @@ bool g_opened = false; // Retrieved functions from libappindicator. -app_indicator_new_func app_indicator_new = NULL; -app_indicator_new_with_path_func app_indicator_new_with_path = NULL; -app_indicator_set_status_func app_indicator_set_status = NULL; +app_indicator_new_func app_indicator_new = nullptr; +app_indicator_new_with_path_func app_indicator_new_with_path = nullptr; +app_indicator_set_status_func app_indicator_set_status = nullptr; app_indicator_set_attention_icon_full_func - app_indicator_set_attention_icon_full = NULL; -app_indicator_set_menu_func app_indicator_set_menu = NULL; -app_indicator_set_icon_full_func app_indicator_set_icon_full = NULL; -app_indicator_set_icon_theme_path_func app_indicator_set_icon_theme_path = NULL; + app_indicator_set_attention_icon_full = nullptr; +app_indicator_set_menu_func app_indicator_set_menu = nullptr; +app_indicator_set_icon_full_func app_indicator_set_icon_full = nullptr; +app_indicator_set_icon_theme_path_func app_indicator_set_icon_theme_path = + nullptr; void EnsureMethodsLoaded() { if (g_attempted_load) @@ -177,8 +178,8 @@ const gfx::ImageSkia& image, const base::string16& tool_tip) : id_(id), - icon_(NULL), - menu_model_(NULL), + icon_(nullptr), + menu_model_(nullptr), icon_change_count_(0), weak_factory_(this) { std::unique_ptr<base::Environment> env(base::Environment::Create());
diff --git a/chrome/browser/ui/libgtkui/app_indicator_icon_menu.cc b/chrome/browser/ui/libgtkui/app_indicator_icon_menu.cc index 91674b9..40399a35 100644 --- a/chrome/browser/ui/libgtkui/app_indicator_icon_menu.cc +++ b/chrome/browser/ui/libgtkui/app_indicator_icon_menu.cc
@@ -16,7 +16,7 @@ AppIndicatorIconMenu::AppIndicatorIconMenu(ui::MenuModel* model) : menu_model_(model), click_action_replacement_menu_item_added_(false), - gtk_menu_(NULL), + gtk_menu_(nullptr), block_activation_(false) { { ANNOTATE_SCOPED_MEMORY_LEAK; // http://crbug.com/378770 @@ -47,7 +47,7 @@ GList* children = gtk_container_get_children(GTK_CONTAINER(gtk_menu_)); for (GList* child = children; child; child = g_list_next(child)) { if (g_object_get_data(G_OBJECT(child->data), "click-action-item") != - NULL) { + nullptr) { gtk_menu_item_set_label(GTK_MENU_ITEM(child->data), label); break; }
diff --git a/chrome/browser/ui/libgtkui/chrome_gtk_frame.cc b/chrome/browser/ui/libgtkui/chrome_gtk_frame.cc index 9d23718..6820a47 100644 --- a/chrome/browser/ui/libgtkui/chrome_gtk_frame.cc +++ b/chrome/browser/ui/libgtkui/chrome_gtk_frame.cc
@@ -147,9 +147,8 @@ } GtkWidget* chrome_gtk_frame_new(void) { - return GTK_WIDGET(g_object_new(chrome_gtk_frame_get_type(), - "type", GTK_WINDOW_TOPLEVEL, - NULL)); + return GTK_WIDGET(g_object_new(chrome_gtk_frame_get_type(), "type", + GTK_WINDOW_TOPLEVEL, nullptr)); } G_END_DECLS
diff --git a/chrome/browser/ui/libgtkui/chrome_gtk_menu_subclasses.cc b/chrome/browser/ui/libgtkui/chrome_gtk_menu_subclasses.cc index a6705a6..33944bb 100644 --- a/chrome/browser/ui/libgtkui/chrome_gtk_menu_subclasses.cc +++ b/chrome/browser/ui/libgtkui/chrome_gtk_menu_subclasses.cc
@@ -13,7 +13,7 @@ } GtkWidget* gtk_custom_menu_new() { - return GTK_WIDGET(g_object_new(gtk_custom_menu_get_type(), NULL)); + return GTK_WIDGET(g_object_new(gtk_custom_menu_get_type(), nullptr)); } G_DEFINE_TYPE(GtkCustomMenuItem, gtk_custom_menu_item, GTK_TYPE_MENU_ITEM) @@ -25,5 +25,5 @@ } GtkWidget* gtk_custom_menu_item_new() { - return GTK_WIDGET(g_object_new(gtk_custom_menu_item_get_type(), NULL)); + return GTK_WIDGET(g_object_new(gtk_custom_menu_item_get_type(), nullptr)); }
diff --git a/chrome/browser/ui/libgtkui/gconf_listener.cc b/chrome/browser/ui/libgtkui/gconf_listener.cc index 7a3fac7..9beea250 100644 --- a/chrome/browser/ui/libgtkui/gconf_listener.cc +++ b/chrome/browser/ui/libgtkui/gconf_listener.cc
@@ -43,7 +43,7 @@ // Public interface: GConfListener::GConfListener(GtkUi* delegate) - : delegate_(delegate), client_(NULL) { + : delegate_(delegate), client_(nullptr) { std::unique_ptr<base::Environment> env(base::Environment::Create()); base::nix::DesktopEnvironment de = base::nix::GetDesktopEnvironment(env.get()); @@ -55,7 +55,7 @@ // not receiving gconf keys. if (client_) { // Register that we're interested in the values of this directory. - GError* error = NULL; + GError* error = nullptr; gconf_client_add_dir(client_, kMetacityGeneral, GCONF_CLIENT_PRELOAD_ONELEVEL, &error); if (HandleGError(error, kMetacityGeneral)) @@ -80,7 +80,7 @@ void GConfListener::GetAndRegister( const char* key_to_subscribe, const base::Callback<void(GConfValue*)>& initial_setter) { - GError* error = NULL; + GError* error = nullptr; GConfValue* gconf_value = gconf_client_get(client_, key_to_subscribe, &error); if (HandleGError(error, key_to_subscribe)) @@ -94,7 +94,7 @@ client_, key_to_subscribe, reinterpret_cast<void (*)(GConfClient*, guint, GConfEntry*, void*)>( OnChangeNotificationThunk), - this, NULL, &error); + this, nullptr, &error); if (HandleGError(error, key_to_subscribe)) return; } @@ -112,11 +112,11 @@ } bool GConfListener::HandleGError(GError* error, const char* key) { - if (error != NULL) { + if (error != nullptr) { LOG(ERROR) << "Error with gconf key '" << key << "': " << error->message; g_error_free(error); g_object_unref(client_); - client_ = NULL; + client_ = nullptr; return true; } return false;
diff --git a/chrome/browser/ui/libgtkui/gconf_listener.h b/chrome/browser/ui/libgtkui/gconf_listener.h index 25b60ecc..75d33696 100644 --- a/chrome/browser/ui/libgtkui/gconf_listener.h +++ b/chrome/browser/ui/libgtkui/gconf_listener.h
@@ -46,7 +46,7 @@ GtkUi* delegate_; - // Pointer to our gconf context. NULL if we aren't on a desktop that uses + // Pointer to our gconf context. nullptr if we aren't on a desktop that uses // gconf. GConfClient* client_;
diff --git a/chrome/browser/ui/libgtkui/gtk_event_loop.cc b/chrome/browser/ui/libgtkui/gtk_event_loop.cc index ccf4742..1862918e 100644 --- a/chrome/browser/ui/libgtkui/gtk_event_loop.cc +++ b/chrome/browser/ui/libgtkui/gtk_event_loop.cc
@@ -21,12 +21,12 @@ } Gtk2EventLoop::Gtk2EventLoop() { - gdk_event_handler_set(DispatchGdkEvent, NULL, NULL); + gdk_event_handler_set(DispatchGdkEvent, nullptr, nullptr); } Gtk2EventLoop::~Gtk2EventLoop() { - gdk_event_handler_set(reinterpret_cast<GdkEventFunc>(gtk_main_do_event), NULL, - NULL); + gdk_event_handler_set(reinterpret_cast<GdkEventFunc>(gtk_main_do_event), + nullptr, nullptr); } // static
diff --git a/chrome/browser/ui/libgtkui/gtk_key_bindings_handler.cc b/chrome/browser/ui/libgtkui/gtk_key_bindings_handler.cc index 1a56802..59244f4 100644 --- a/chrome/browser/ui/libgtkui/gtk_key_bindings_handler.cc +++ b/chrome/browser/ui/libgtkui/gtk_key_bindings_handler.cc
@@ -81,7 +81,7 @@ GtkWidget* Gtk2KeyBindingsHandler::CreateNewHandler() { Handler* handler = - static_cast<Handler*>(g_object_new(HandlerGetType(), NULL)); + static_cast<Handler*>(g_object_new(HandlerGetType(), nullptr)); handler->owner = this; @@ -133,7 +133,7 @@ gdk_keymap_translate_keyboard_state( keymap, gdk_event->hardware_keycode, static_cast<GdkModifierType>(gdk_event->state), gdk_event->group, - &gdk_event->keyval, NULL, NULL, &consumed); + &gdk_event->keyval, nullptr, nullptr, &consumed); state = static_cast<GdkModifierType>(gdk_event->state & ~consumed); gdk_keymap_add_virtual_modifiers(keymap, &state); @@ -141,7 +141,7 @@ } void Gtk2KeyBindingsHandler::HandlerInit(Handler* self) { - self->owner = NULL; + self->owner = nullptr; } void Gtk2KeyBindingsHandler::HandlerClassInit(HandlerClass* klass) {
diff --git a/chrome/browser/ui/libgtkui/gtk_key_bindings_handler.h b/chrome/browser/ui/libgtkui/gtk_key_bindings_handler.h index 4c0cf02..6794cc22d 100644 --- a/chrome/browser/ui/libgtkui/gtk_key_bindings_handler.h +++ b/chrome/browser/ui/libgtkui/gtk_key_bindings_handler.h
@@ -46,7 +46,7 @@ // Matches a key event against predefined gtk key bindings, false will be // returned if the key event doesn't correspond to a predefined key binding. // Edit commands matched with |event| will be stored in |edit_commands|, if - // non-NULL. + // non-nullptr. bool MatchEvent(const ui::Event& event, std::vector<ui::TextEditCommandAuraLinux>* commands);
diff --git a/chrome/browser/ui/libgtkui/gtk_status_icon.cc b/chrome/browser/ui/libgtkui/gtk_status_icon.cc index c42da502..5c8357b 100644 --- a/chrome/browser/ui/libgtkui/gtk_status_icon.cc +++ b/chrome/browser/ui/libgtkui/gtk_status_icon.cc
@@ -75,7 +75,7 @@ guint button, guint32 activate_time) { if (menu_.get()) { - gtk_menu_popup(menu_->GetGtkMenu(), NULL, NULL, + gtk_menu_popup(menu_->GetGtkMenu(), nullptr, nullptr, gtk_status_icon_position_menu, gtk_status_icon_, button, activate_time); }
diff --git a/chrome/browser/ui/libgtkui/gtk_ui.cc b/chrome/browser/ui/libgtkui/gtk_ui.cc index 02add34d..3423149 100644 --- a/chrome/browser/ui/libgtkui/gtk_ui.cc +++ b/chrome/browser/ui/libgtkui/gtk_ui.cc
@@ -82,13 +82,6 @@ // - Render and inject the omnibox background. // - Make sure to test with a light on dark theme, too. -// Work around a header bug: -// linux/debian_wheezy_i386-sysroot/usr/include/linux/stddef.h redefines NULL -// to 0, which breaks -Wsentinel. Get back the normal definition of NULL. -// TODO(thakis): Remove this once we update sysroots. -#define __need_NULL -#include <stddef.h> - namespace libgtkui { namespace { @@ -155,13 +148,13 @@ { // http://crbug.com/346740 ANNOTATE_SCOPED_MEMORY_LEAK; - pixmap = gtk_widget_get_snapshot(button, NULL); + pixmap = gtk_widget_get_snapshot(button, nullptr); } gdk_drawable_get_size(GDK_DRAWABLE(pixmap), &w, &h); GdkColormap* colormap = gdk_drawable_get_colormap(pixmap); GdkPixbuf* pixbuf = gdk_pixbuf_get_from_drawable( - NULL, GDK_DRAWABLE(pixmap), colormap, 0, 0, 0, 0, w, h); + nullptr, GDK_DRAWABLE(pixmap), colormap, 0, 0, 0, 0, w, h); gdk_cairo_set_source_pixbuf(cr, pixbuf, 0, 0); cairo_paint(cr); @@ -302,11 +295,11 @@ CHECK(gtk_settings); gint antialias = 0; gint hinting = 0; - gchar* hint_style = NULL; - gchar* rgba = NULL; + gchar* hint_style = nullptr; + gchar* rgba = nullptr; g_object_get(gtk_settings, "gtk-xft-antialias", &antialias, "gtk-xft-hinting", &hinting, "gtk-xft-hintstyle", &hint_style, "gtk-xft-rgba", - &rgba, NULL); + &rgba, nullptr); gfx::FontRenderParams params; params.antialiasing = antialias != 0; @@ -352,7 +345,7 @@ GtkSettings* gtk_settings = gtk_settings_get_default(); CHECK(gtk_settings); gint gtk_dpi = -1; - g_object_get(gtk_settings, "gtk-xft-dpi", >k_dpi, NULL); + g_object_get(gtk_settings, "gtk-xft-dpi", >k_dpi, nullptr); // GTK multiplies the DPI by 1024 before storing it. return (gtk_dpi > 0) ? gtk_dpi / 1024.0 : kDefaultDPI; @@ -559,12 +552,12 @@ gint cursor_blink_time = kGtkDefaultCursorBlinkTime; gboolean cursor_blink = TRUE; g_object_get(gtk_settings_get_default(), "gtk-cursor-blink-time", - &cursor_blink_time, "gtk-cursor-blink", &cursor_blink, NULL); + &cursor_blink_time, "gtk-cursor-blink", &cursor_blink, nullptr); return cursor_blink ? (cursor_blink_time / kGtkCursorBlinkCycleFactor) : 0.0; } ui::NativeTheme* GtkUi::GetNativeTheme(aura::Window* window) const { - ui::NativeTheme* native_theme_override = NULL; + ui::NativeTheme* native_theme_override = nullptr; if (!native_theme_overrider_.is_null()) native_theme_override = native_theme_overrider_.Run(window); @@ -639,7 +632,7 @@ static_cast<GtkIconLookupFlags>(GTK_ICON_LOOKUP_FORCE_SIZE))); if (!icon_info) continue; - ScopedGdkPixbuf pixbuf(gtk_icon_info_load_icon(icon_info.get(), NULL)); + ScopedGdkPixbuf pixbuf(gtk_icon_info_load_icon(icon_info.get(), nullptr)); if (!pixbuf) continue;
diff --git a/chrome/browser/ui/libgtkui/gtk_ui.h b/chrome/browser/ui/libgtkui/gtk_ui.h index f58d943..627aab5 100644 --- a/chrome/browser/ui/libgtkui/gtk_ui.h +++ b/chrome/browser/ui/libgtkui/gtk_ui.h
@@ -178,7 +178,7 @@ NonClientMiddleClickAction middle_click_action_; // Used to override the native theme for a window. If no override is provided - // or the callback returns NULL, GtkUi will default to a NativeThemeGtk2 + // or the callback returns nullptr, GtkUi will default to a NativeThemeGtk2 // instance. NativeThemeGetter native_theme_overrider_;
diff --git a/chrome/browser/ui/libgtkui/gtk_util.cc b/chrome/browser/ui/libgtkui/gtk_util.cc index a17fd4b..9463d533 100644 --- a/chrome/browser/ui/libgtkui/gtk_util.cc +++ b/chrome/browser/ui/libgtkui/gtk_util.cc
@@ -40,7 +40,7 @@ // here. argv[i] = strdup(args[i].c_str()); } - argv[argc] = NULL; + argv[argc] = nullptr; char** argv_pointer = argv.get(); { @@ -203,7 +203,7 @@ } void ClearAuraTransientParent(GtkWidget* dialog) { - g_object_set_data(G_OBJECT(dialog), kAuraTransientParent, NULL); + g_object_set_data(G_OBJECT(dialog), kAuraTransientParent, nullptr); } #if GTK_MAJOR_VERSION > 2
diff --git a/chrome/browser/ui/libgtkui/gtk_util.h b/chrome/browser/ui/libgtkui/gtk_util.h index 167a54c4f..322974a 100644 --- a/chrome/browser/ui/libgtkui/gtk_util.h +++ b/chrome/browser/ui/libgtkui/gtk_util.h
@@ -66,7 +66,7 @@ void TurnButtonBlue(GtkWidget* button); // Sets |dialog| as transient for |parent|, which will keep it on top and center -// it above |parent|. Do nothing if |parent| is NULL. +// it above |parent|. Do nothing if |parent| is nullptr. void SetGtkTransientForAura(GtkWidget* dialog, aura::Window* parent); // Gets the transient parent aura window for |dialog|. @@ -177,7 +177,7 @@ typedef ScopedGObject<GtkStyleContext> ScopedStyleContext; typedef ScopedGObject<GtkCssProvider> ScopedCssProvider; -// If |context| is NULL, creates a new top-level style context +// If |context| is nullptr, creates a new top-level style context // specified by parsing |css_node|. Otherwise, creates the child // context with |context| as the parent. ScopedStyleContext AppendCssNodeToStyleContext(GtkStyleContext* context,
diff --git a/chrome/browser/ui/libgtkui/menu_util.cc b/chrome/browser/ui/libgtkui/menu_util.cc index e2c95e9..5ce8aaf 100644 --- a/chrome/browser/ui/libgtkui/menu_util.cc +++ b/chrome/browser/ui/libgtkui/menu_util.cc
@@ -73,7 +73,7 @@ bool GetMenuItemID(GtkWidget* menu_item, int* menu_id) { gpointer id_ptr = g_object_get_data(G_OBJECT(menu_item), "menu-id"); - if (id_ptr != NULL) { + if (id_ptr != nullptr) { *menu_id = GPOINTER_TO_INT(id_ptr) - 1; return true; } @@ -99,7 +99,7 @@ bool* block_activation, void* this_ptr) { std::map<int, GtkWidget*> radio_groups; - GtkWidget* menu_item = NULL; + GtkWidget* menu_item = nullptr; for (int i = 0; i < model->GetItemCount(); ++i) { gfx::Image icon; std::string label = ui::ConvertAcceleratorsFromWindowsStyle( @@ -122,7 +122,7 @@ if (iter == radio_groups.end()) { menu_item = - gtk_radio_menu_item_new_with_mnemonic(NULL, label.c_str()); + gtk_radio_menu_item_new_with_mnemonic(nullptr, label.c_str()); radio_groups[model->GetGroupIdAt(i)] = menu_item; } else { menu_item = gtk_radio_menu_item_new_with_mnemonic_from_widget( @@ -170,9 +170,7 @@ ui::Accelerator accelerator; if (model->GetAcceleratorAt(i, &accelerator)) { - gtk_widget_add_accelerator(menu_item, - "activate", - NULL, + gtk_widget_add_accelerator(menu_item, "activate", nullptr, GetGdkKeyCodeForAccelerator(accelerator), GetGdkModifierForAccelerator(accelerator), GTK_ACCEL_VISIBLE); @@ -187,7 +185,7 @@ item_activated_cb, this_ptr); - menu_item = NULL; + menu_item = nullptr; } } @@ -243,7 +241,7 @@ gtk_image_new_from_pixbuf(pixbuf)); g_object_unref(pixbuf); } else { - gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(widget), NULL); + gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(widget), nullptr); } } }
diff --git a/chrome/browser/ui/libgtkui/native_theme_gtk2.cc b/chrome/browser/ui/libgtkui/native_theme_gtk2.cc index a4d40f1..1ae5b7b 100644 --- a/chrome/browser/ui/libgtkui/native_theme_gtk2.cc +++ b/chrome/browser/ui/libgtkui/native_theme_gtk2.cc
@@ -362,7 +362,7 @@ } GtkWidget* NativeThemeGtk2::GetWindow() const { - static GtkWidget* fake_window = NULL; + static GtkWidget* fake_window = nullptr; if (!fake_window) { fake_window = chrome_gtk_frame_new(); @@ -373,7 +373,7 @@ } GtkWidget* NativeThemeGtk2::GetEntry() const { - static GtkWidget* fake_entry = NULL; + static GtkWidget* fake_entry = nullptr; if (!fake_entry) { fake_entry = gtk_entry_new(); @@ -388,7 +388,7 @@ } GtkWidget* NativeThemeGtk2::GetLabel() const { - static GtkWidget* fake_label = NULL; + static GtkWidget* fake_label = nullptr; if (!fake_label) fake_label = gtk_label_new(""); @@ -397,7 +397,7 @@ } GtkWidget* NativeThemeGtk2::GetButton() const { - static GtkWidget* fake_button = NULL; + static GtkWidget* fake_button = nullptr; if (!fake_button) fake_button = gtk_button_new(); @@ -406,7 +406,7 @@ } GtkWidget* NativeThemeGtk2::GetBlueButton() const { - static GtkWidget* fake_bluebutton = NULL; + static GtkWidget* fake_bluebutton = nullptr; if (!fake_bluebutton) { fake_bluebutton = gtk_button_new(); @@ -417,7 +417,7 @@ } GtkWidget* NativeThemeGtk2::GetTree() const { - static GtkWidget* fake_tree = NULL; + static GtkWidget* fake_tree = nullptr; if (!fake_tree) fake_tree = gtk_tree_view_new(); @@ -426,7 +426,7 @@ } GtkWidget* NativeThemeGtk2::GetTooltip() const { - static GtkWidget* fake_tooltip = NULL; + static GtkWidget* fake_tooltip = nullptr; if (!fake_tooltip) { fake_tooltip = gtk_window_new(GTK_WINDOW_TOPLEVEL); @@ -438,7 +438,7 @@ } GtkWidget* NativeThemeGtk2::GetMenu() const { - static GtkWidget* fake_menu = NULL; + static GtkWidget* fake_menu = nullptr; if (!fake_menu) fake_menu = gtk_custom_menu_new(); @@ -447,7 +447,7 @@ } GtkWidget* NativeThemeGtk2::GetMenuItem() const { - static GtkWidget* fake_menu_item = NULL; + static GtkWidget* fake_menu_item = nullptr; if (!fake_menu_item) { fake_menu_item = gtk_custom_menu_item_new(); @@ -458,7 +458,7 @@ } GtkWidget* NativeThemeGtk2::GetSeparator() const { - static GtkWidget* fake_separator = NULL; + static GtkWidget* fake_separator = nullptr; if (!fake_separator) fake_separator = gtk_hseparator_new();
diff --git a/chrome/browser/ui/libgtkui/native_theme_gtk3.cc b/chrome/browser/ui/libgtkui/native_theme_gtk3.cc index 7b8028a2..113951a2 100644 --- a/chrome/browser/ui/libgtkui/native_theme_gtk3.cc +++ b/chrome/browser/ui/libgtkui/native_theme_gtk3.cc
@@ -539,7 +539,7 @@ gtk_style_context_get_border(context, state, &border); gtk_style_context_get_padding(context, state, &padding); int min_height = 1; - gtk_style_context_get(context, state, "min-height", &min_height, NULL); + gtk_style_context_get(context, state, "min-height", &min_height, nullptr); int w = rect.width() - margin.left - margin.right; int h = std::max( min_height + padding.top + padding.bottom + border.top + border.bottom,
diff --git a/chrome/browser/ui/libgtkui/print_dialog_gtk.cc b/chrome/browser/ui/libgtkui/print_dialog_gtk.cc index 0b64072..9e4a97a 100644 --- a/chrome/browser/ui/libgtkui/print_dialog_gtk.cc +++ b/chrome/browser/ui/libgtkui/print_dialog_gtk.cc
@@ -72,11 +72,11 @@ } // Looks up a paper size matching (in terms of PaperSizeMatch) the user selected -// media in the paper size list reported by GTK. Returns NULL if there's no +// media in the paper size list reported by GTK. Returns nullptr if there's no // match found. GtkPaperSize* FindPaperSizeMatch(GList* gtk_paper_sizes, const PrintSettings::RequestedMedia& media) { - GtkPaperSize* first_fuzzy_match = NULL; + GtkPaperSize* first_fuzzy_match = nullptr; for (GList* p = gtk_paper_sizes; p && p->data; p = g_list_next(p)) { GtkPaperSize* gtk_paper_size = static_cast<GtkPaperSize*>(p->data); if (PaperSizeMatch(gtk_paper_size, media, false)) { @@ -116,8 +116,8 @@ // Helper class to track GTK printers. class GtkPrinterList { public: - GtkPrinterList() : default_printer_(NULL) { - gtk_enumerate_printers(SetPrinter, this, NULL, TRUE); + GtkPrinterList() : default_printer_(nullptr) { + gtk_enumerate_printers(SetPrinter, this, nullptr, TRUE); } ~GtkPrinterList() { @@ -127,16 +127,16 @@ } } - // Can return NULL if there's no default printer. E.g. Printer on a laptop + // Can return nullptr if there's no default printer. E.g. Printer on a laptop // is "home_printer", but the laptop is at work. GtkPrinter* default_printer() { return default_printer_; } - // Can return NULL if the printer cannot be found due to: + // Can return nullptr if the printer cannot be found due to: // - Printer list out of sync with printer dialog UI. // - Querying for non-existant printers like 'Print to PDF'. GtkPrinter* GetPrinterWithName(const std::string& name) { if (name.empty()) - return NULL; + return nullptr; for (std::vector<GtkPrinter*>::iterator it = printers_.begin(); it < printers_.end(); ++it) { @@ -145,7 +145,7 @@ } } - return NULL; + return nullptr; } private: @@ -176,10 +176,10 @@ PrintDialogGtk2::PrintDialogGtk2(PrintingContextLinux* context) : context_(context), - dialog_(NULL), - gtk_settings_(NULL), - page_setup_(NULL), - printer_(NULL) {} + dialog_(nullptr), + gtk_settings_(nullptr), + page_setup_(nullptr), + printer_(nullptr) {} PrintDialogGtk2::~PrintDialogGtk2() { DCHECK_CURRENTLY_ON(BrowserThread::UI); @@ -191,19 +191,19 @@ libgtkui::ClearAuraTransientParent(dialog_); } gtk_widget_destroy(dialog_); - dialog_ = NULL; + dialog_ = nullptr; } if (gtk_settings_) { g_object_unref(gtk_settings_); - gtk_settings_ = NULL; + gtk_settings_ = nullptr; } if (page_setup_) { g_object_unref(page_setup_); - page_setup_ = NULL; + page_setup_ = nullptr; } if (printer_) { g_object_unref(printer_); - printer_ = NULL; + printer_ = nullptr; } } @@ -250,7 +250,7 @@ color_value.c_str()); if (settings->duplex_mode() != printing::UNKNOWN_DUPLEX_MODE) { - const char* cups_duplex_mode = NULL; + const char* cups_duplex_mode = nullptr; switch (settings->duplex_mode()) { case printing::LONG_EDGE: cups_duplex_mode = kDuplexNoTumble; @@ -302,7 +302,7 @@ reinterpret_cast<GDestroyNotify>(gtk_paper_size_free)); #else g_list_foreach(gtk_paper_sizes, - reinterpret_cast<GFunc>(gtk_paper_size_free), NULL); + reinterpret_cast<GFunc>(gtk_paper_size_free), nullptr); g_list_free(gtk_paper_sizes); #endif } @@ -326,12 +326,12 @@ callback_ = callback; DCHECK(!callback_.is_null()); - dialog_ = gtk_print_unix_dialog_new(NULL, NULL); + dialog_ = gtk_print_unix_dialog_new(nullptr, nullptr); libgtkui::SetGtkTransientForAura(dialog_, parent_view); if (parent_view) parent_view->AddObserver(this); g_signal_connect(dialog_, "delete-event", - G_CALLBACK(gtk_widget_hide_on_delete), NULL); + G_CALLBACK(gtk_widget_hide_on_delete), nullptr); // Handle the case when the existing |gtk_settings_| has "selection" selected // as the page range, but |has_selection| is false. @@ -504,8 +504,8 @@ const base::string16& document_name) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - // If |printer_| is NULL then somehow the GTK printer list changed out under - // us. In which case, just bail out. + // If |printer_| is nullptr then somehow the GTK printer list changed out + // under us. In which case, just bail out. if (!printer_) { // Matches AddRef() in PrintDocument(); Release(); @@ -518,8 +518,9 @@ GtkPrintJob* print_job = gtk_print_job_new(base::UTF16ToUTF8(document_name).c_str(), printer_, gtk_settings_, page_setup_); - gtk_print_job_set_source_file(print_job, path_to_pdf_.value().c_str(), NULL); - gtk_print_job_send(print_job, OnJobCompletedThunk, this, NULL); + gtk_print_job_set_source_file(print_job, path_to_pdf_.value().c_str(), + nullptr); + gtk_print_job_send(print_job, OnJobCompletedThunk, this, nullptr); } void PrintDialogGtk2::OnJobCompleted(GtkPrintJob* print_job,
diff --git a/chrome/browser/ui/libgtkui/select_file_dialog_impl.cc b/chrome/browser/ui/libgtkui/select_file_dialog_impl.cc index 6a95ee0..d1bc797 100644 --- a/chrome/browser/ui/libgtkui/select_file_dialog_impl.cc +++ b/chrome/browser/ui/libgtkui/select_file_dialog_impl.cc
@@ -28,8 +28,8 @@ namespace libgtkui { -base::FilePath* SelectFileDialogImpl::last_saved_path_ = NULL; -base::FilePath* SelectFileDialogImpl::last_opened_path_ = NULL; +base::FilePath* SelectFileDialogImpl::last_saved_path_ = nullptr; +base::FilePath* SelectFileDialogImpl::last_opened_path_ = nullptr; // static ui::SelectFileDialog* SelectFileDialogImpl::Create( @@ -81,7 +81,7 @@ SelectFileDialogImpl::~SelectFileDialogImpl() { } void SelectFileDialogImpl::ListenerDestroyed() { - listener_ = NULL; + listener_ = nullptr; } bool SelectFileDialogImpl::CallDirectoryExistsOnUIThread(
diff --git a/chrome/browser/ui/libgtkui/select_file_dialog_impl_gtk.cc b/chrome/browser/ui/libgtkui/select_file_dialog_impl_gtk.cc index 0671241d..b3bb164 100644 --- a/chrome/browser/ui/libgtkui/select_file_dialog_impl_gtk.cc +++ b/chrome/browser/ui/libgtkui/select_file_dialog_impl_gtk.cc
@@ -76,7 +76,7 @@ SelectFileDialogImplGTK::SelectFileDialogImplGTK(Listener* listener, ui::SelectFilePolicy* policy) - : SelectFileDialogImpl(listener, policy), preview_(NULL) {} + : SelectFileDialogImpl(listener, policy), preview_(nullptr) {} SelectFileDialogImplGTK::~SelectFileDialogImplGTK() { for (std::set<aura::Window*>::iterator iter = parents_.begin(); @@ -134,7 +134,7 @@ if (file_types) file_types_ = *file_types; - GtkWidget* dialog = NULL; + GtkWidget* dialog = nullptr; switch (type) { case SELECT_FOLDER: case SELECT_UPLOAD_FOLDER: @@ -156,7 +156,7 @@ return; } g_signal_connect(dialog, "delete-event", - G_CALLBACK(gtk_widget_hide_on_delete), NULL); + G_CALLBACK(gtk_widget_hide_on_delete), nullptr); dialogs_.insert(dialog); preview_ = gtk_image_new(); @@ -197,7 +197,7 @@ void SelectFileDialogImplGTK::AddFilters(GtkFileChooser* chooser) { for (size_t i = 0; i < file_types_.extensions.size(); ++i) { - GtkFileFilter* filter = NULL; + GtkFileFilter* filter = nullptr; std::set<std::string> fallback_labels; for (size_t j = 0; j < file_types_.extensions[i].size(); ++j) { @@ -296,7 +296,7 @@ const base::FilePath& default_path, gfx::NativeWindow parent) { GtkWidget* dialog = gtk_file_chooser_dialog_new( - title.c_str(), NULL, GTK_FILE_CHOOSER_ACTION_OPEN, "_Cancel", + title.c_str(), nullptr, GTK_FILE_CHOOSER_ACTION_OPEN, "_Cancel", GTK_RESPONSE_CANCEL, "_Open", GTK_RESPONSE_ACCEPT, nullptr); SetGtkTransientForAura(dialog, parent); AddFilters(GTK_FILE_CHOOSER(dialog)); @@ -337,7 +337,7 @@ : "_Open"; GtkWidget* dialog = gtk_file_chooser_dialog_new( - title_string.c_str(), NULL, GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, + title_string.c_str(), nullptr, GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, "_Cancel", GTK_RESPONSE_CANCEL, accept_button_label.c_str(), GTK_RESPONSE_ACCEPT, nullptr); SetGtkTransientForAura(dialog, parent); @@ -394,7 +394,7 @@ : l10n_util::GetStringUTF8(IDS_SAVE_AS_DIALOG_TITLE); GtkWidget* dialog = gtk_file_chooser_dialog_new( - title_string.c_str(), NULL, GTK_FILE_CHOOSER_ACTION_SAVE, "_Cancel", + title_string.c_str(), nullptr, GTK_FILE_CHOOSER_ACTION_SAVE, "_Cancel", GTK_RESPONSE_CANCEL, "_Save", GTK_RESPONSE_ACCEPT, nullptr); SetGtkTransientForAura(dialog, parent); @@ -498,7 +498,7 @@ } std::vector<base::FilePath> filenames_fp; - for (GSList* iter = filenames; iter != NULL; iter = g_slist_next(iter)) { + for (GSList* iter = filenames; iter != nullptr; iter = g_slist_next(iter)) { base::FilePath path(static_cast<char*>(iter->data)); g_free(iter->data); if (CallDirectoryExistsOnUIThread(path)) @@ -517,7 +517,7 @@ void SelectFileDialogImplGTK::OnFileChooserDestroy(GtkWidget* dialog) { dialogs_.erase(dialog); - // |parent| can be NULL when closing the host window + // |parent| can be nullptr when closing the host window // while opening the file-picker. aura::Window* parent = GetAuraTransientParent(dialog); if (!parent) @@ -552,7 +552,7 @@ // This will preserve the image's aspect ratio. GdkPixbuf* pixbuf = gdk_pixbuf_new_from_file_at_size(filename, kPreviewWidth, - kPreviewHeight, NULL); + kPreviewHeight, nullptr); g_free(filename); if (pixbuf) { gtk_image_set_from_pixbuf(GTK_IMAGE(preview_), pixbuf);
diff --git a/chrome/browser/ui/libgtkui/skia_utils_gtk.cc b/chrome/browser/ui/libgtkui/skia_utils_gtk.cc index 989b4a6..f4a2dd9 100644 --- a/chrome/browser/ui/libgtkui/skia_utils_gtk.cc +++ b/chrome/browser/ui/libgtkui/skia_utils_gtk.cc
@@ -86,7 +86,7 @@ GdkPixbuf* GdkPixbufFromSkBitmap(const SkBitmap& bitmap) { if (bitmap.isNull()) - return NULL; + return nullptr; SkAutoLockPixels lock_pixels(bitmap);
diff --git a/chrome/browser/ui/libgtkui/unity_service.cc b/chrome/browser/ui/libgtkui/unity_service.cc index 78abe9b1..9903568 100644 --- a/chrome/browser/ui/libgtkui/unity_service.cc +++ b/chrome/browser/ui/libgtkui/unity_service.cc
@@ -38,18 +38,18 @@ bool attempted_load = false; // Unity has a singleton object that we can ask whether the unity is running. -UnityInspector* inspector = NULL; +UnityInspector* inspector = nullptr; // A link to the desktop entry in the panel. -UnityLauncherEntry* chrome_entry = NULL; +UnityLauncherEntry* chrome_entry = nullptr; // Retrieved functions from libunity. -unity_inspector_get_unity_running_func get_unity_running = NULL; -unity_launcher_entry_set_count_func entry_set_count = NULL; -unity_launcher_entry_set_count_visible_func entry_set_count_visible = NULL; -unity_launcher_entry_set_progress_func entry_set_progress = NULL; +unity_inspector_get_unity_running_func get_unity_running = nullptr; +unity_launcher_entry_set_count_func entry_set_count = nullptr; +unity_launcher_entry_set_count_visible_func entry_set_count_visible = nullptr; +unity_launcher_entry_set_progress_func entry_set_progress = nullptr; unity_launcher_entry_set_progress_visible_func entry_set_progress_visible = - NULL; + nullptr; void EnsureMethodsLoaded() { using base::nix::GetDesktopEnvironment;
diff --git a/chrome/browser/ui/libgtkui/x11_input_method_context_impl_gtk.cc b/chrome/browser/ui/libgtkui/x11_input_method_context_impl_gtk.cc index cfd6ede..f40654b 100644 --- a/chrome/browser/ui/libgtkui/x11_input_method_context_impl_gtk.cc +++ b/chrome/browser/ui/libgtkui/x11_input_method_context_impl_gtk.cc
@@ -31,8 +31,8 @@ ui::LinuxInputMethodContextDelegate* delegate, bool is_simple) : delegate_(delegate), - gtk_context_(NULL), - gdk_last_set_client_window_(NULL) { + gtk_context_(nullptr), + gdk_last_set_client_window_(nullptr) { CHECK(delegate_); ResetXModifierKeycodesCache(); @@ -55,7 +55,7 @@ X11InputMethodContextImplGtk2::~X11InputMethodContextImplGtk2() { if (gtk_context_) { g_object_unref(gtk_context_); - gtk_context_ = NULL; + gtk_context_ = nullptr; } } @@ -188,15 +188,15 @@ } if (!display) { LOG(ERROR) << "Cannot get a GdkDisplay for a key event."; - return NULL; + return nullptr; } // Get a keysym and group. KeySym keysym = NoSymbol; guint8 keyboard_group = 0; - XLookupString(&xkey, NULL, 0, &keysym, NULL); + XLookupString(&xkey, nullptr, 0, &keysym, nullptr); GdkKeymap* keymap = gdk_keymap_get_for_display(display); - GdkKeymapKey* keys = NULL; - guint* keyvals = NULL; + GdkKeymapKey* keys = nullptr; + guint* keyvals = nullptr; gint n_entries = 0; if (keymap && gdk_keymap_get_entries_for_keycode(keymap, xkey.keycode, &keys, &keyvals, &n_entries)) { @@ -208,9 +208,9 @@ } } g_free(keys); - keys = NULL; + keys = nullptr; g_free(keyvals); - keyvals = NULL; + keyvals = nullptr; // Get a GdkWindow. #if GTK_CHECK_VERSION(2, 24, 0) GdkWindow* window = gdk_x11_window_lookup_for_display(display, xkey.window); @@ -227,7 +227,7 @@ #endif if (!window) { LOG(ERROR) << "Cannot get a GdkWindow for a key event."; - return NULL; + return nullptr; } // Create a GdkEvent. @@ -242,7 +242,7 @@ event->key.state = xkey.state; event->key.keyval = keysym; event->key.length = 0; - event->key.string = NULL; + event->key.string = nullptr; event->key.hardware_keycode = xkey.keycode; event->key.group = keyboard_group; event->key.is_modifier = IsKeycodeModifierKey(xkey.keycode); @@ -292,8 +292,8 @@ if (context != gtk_context_) return; - gchar* str = NULL; - PangoAttrList* attrs = NULL; + gchar* str = nullptr; + PangoAttrList* attrs = nullptr; gint cursor_pos = 0; gtk_im_context_get_preedit_string(context, &str, &attrs, &cursor_pos); ui::CompositionText composition_text;
diff --git a/chrome/browser/ui/libgtkui/x11_input_method_context_impl_gtk.h b/chrome/browser/ui/libgtkui/x11_input_method_context_impl_gtk.h index db4011a..d3733a8 100644 --- a/chrome/browser/ui/libgtkui/x11_input_method_context_impl_gtk.h +++ b/chrome/browser/ui/libgtkui/x11_input_method_context_impl_gtk.h
@@ -43,7 +43,7 @@ void ResetXModifierKeycodesCache(); // Constructs a GdkEventKey from a XKeyEvent and returns it. Otherwise, - // returns NULL. The returned GdkEvent must be freed by gdk_event_free. + // returns nullptr. The returned GdkEvent must be freed by gdk_event_free. GdkEvent* GdkEventFromNativeEvent(const base::NativeEvent& native_event); // Returns true if the hardware |keycode| is assigned to a modifier key. @@ -76,7 +76,7 @@ OnPreeditStart, GtkIMContext*); - // A set of callback functions. Must not be NULL. + // A set of callback functions. Must not be nullptr. ui::LinuxInputMethodContextDelegate* delegate_; // IME's input GTK context.
diff --git a/chrome/browser/ui/scoped_tabbed_browser_displayer.cc b/chrome/browser/ui/scoped_tabbed_browser_displayer.cc index 6f09f0b..9ad5bffb 100644 --- a/chrome/browser/ui/scoped_tabbed_browser_displayer.cc +++ b/chrome/browser/ui/scoped_tabbed_browser_displayer.cc
@@ -13,7 +13,7 @@ ScopedTabbedBrowserDisplayer::ScopedTabbedBrowserDisplayer(Profile* profile) { browser_ = FindTabbedBrowser(profile, false); if (!browser_) - browser_ = new Browser(Browser::CreateParams(profile)); + browser_ = new Browser(Browser::CreateParams(profile, true)); } ScopedTabbedBrowserDisplayer::~ScopedTabbedBrowserDisplayer() {
diff --git a/chrome/browser/ui/startup/session_crashed_infobar_delegate_unittest.cc b/chrome/browser/ui/startup/session_crashed_infobar_delegate_unittest.cc index 49f3756..cb8f2584 100644 --- a/chrome/browser/ui/startup/session_crashed_infobar_delegate_unittest.cc +++ b/chrome/browser/ui/startup/session_crashed_infobar_delegate_unittest.cc
@@ -57,7 +57,7 @@ browser()->profile())))); // Create a browser which we can close during the test. - Browser::CreateParams params(browser()->profile()); + Browser::CreateParams params(browser()->profile(), true); std::unique_ptr<Browser> first_browser( chrome::CreateBrowserWithTestWindowForParams(¶ms)); AddTab(first_browser.get(), GURL(chrome::kChromeUINewTabURL));
diff --git a/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc b/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc index 1cdbcaf..cfe7120 100644 --- a/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc +++ b/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc
@@ -229,7 +229,7 @@ BrowserList::AddObserver(&observer); Browser* popup = new Browser( - Browser::CreateParams(Browser::TYPE_POPUP, browser()->profile())); + Browser::CreateParams(Browser::TYPE_POPUP, browser()->profile(), true)); ASSERT_TRUE(popup->is_type_popup()); ASSERT_EQ(popup, observer.added_browser_); @@ -526,14 +526,14 @@ // Open some urls with the browsers, and close them. Browser* browser1 = - new Browser(Browser::CreateParams(Browser::TYPE_TABBED, profile1)); + new Browser(Browser::CreateParams(Browser::TYPE_TABBED, profile1, true)); chrome::NewTab(browser1); ui_test_utils::NavigateToURL(browser1, embedded_test_server()->GetURL("/empty.html")); CloseBrowserSynchronously(browser1); - Browser* browser2 = new Browser( - Browser::CreateParams(Browser::TYPE_TABBED, profile2)); + Browser* browser2 = + new Browser(Browser::CreateParams(Browser::TYPE_TABBED, profile2, true)); chrome::NewTab(browser2); ui_test_utils::NavigateToURL(browser2, embedded_test_server()->GetURL("/form.html")); @@ -667,7 +667,7 @@ // Open a page with profile_last. Browser* browser_last = new Browser( - Browser::CreateParams(Browser::TYPE_TABBED, profile_last)); + Browser::CreateParams(Browser::TYPE_TABBED, profile_last, true)); chrome::NewTab(browser_last); ui_test_utils::NavigateToURL(browser_last, embedded_test_server()->GetURL("/empty.html")); @@ -911,7 +911,14 @@ policy::BrowserPolicyConnector::SetPolicyProviderForTesting(&provider_); } -IN_PROC_BROWSER_TEST_F(StartupBrowserCreatorFirstRunTest, AddFirstRunTab) { +// http://crbug.com/691707 +#if defined(OS_MACOSX) +#define MAYBE_AddFirstRunTab DISABLED_AddFirstRunTab +#else +#define MAYBE_AddFirstRunTab AddFirstRunTab +#endif +IN_PROC_BROWSER_TEST_F(StartupBrowserCreatorFirstRunTest, + MAYBE_AddFirstRunTab) { ASSERT_TRUE(embedded_test_server()->Start()); StartupBrowserCreator browser_creator; browser_creator.AddFirstRunTab( @@ -1047,7 +1054,13 @@ tab_strip->GetWebContentsAt(0)->GetURL().ExtractFileName()); } -IN_PROC_BROWSER_TEST_F(StartupBrowserCreatorFirstRunTest, WelcomePages) { +// http://crbug.com/691707 +#if defined(OS_MACOSX) +#define MAYBE_WelcomePages DISABLED_WelcomePages +#else +#define MAYBE_WelcomePages WelcomePages +#endif +IN_PROC_BROWSER_TEST_F(StartupBrowserCreatorFirstRunTest, MAYBE_WelcomePages) { ASSERT_TRUE(embedded_test_server()->Start()); ProfileManager* profile_manager = g_browser_process->profile_manager();
diff --git a/chrome/browser/ui/startup/startup_browser_creator_impl.cc b/chrome/browser/ui/startup/startup_browser_creator_impl.cc index d3f1d623..7a2e089 100644 --- a/chrome/browser/ui/startup/startup_browser_creator_impl.cc +++ b/chrome/browser/ui/startup/startup_browser_creator_impl.cc
@@ -447,8 +447,15 @@ if (!profile_ && browser) profile_ = browser->profile(); - if (!browser || !browser->is_type_tabbed()) - browser = new Browser(Browser::CreateParams(profile_)); + if (!browser || !browser->is_type_tabbed()) { + // Startup browsers are not counted as being created by a user_gesture + // because of historical accident, even though the startup browser was + // created in response to the user clicking on chrome. There was an + // incomplete check on whether a user gesture created a window which looked + // at the state of the MessageLoop. + Browser::CreateParams params = Browser::CreateParams(profile_, false); + browser = new Browser(params); + } bool first_tab = true; ProtocolHandlerRegistry* registry = profile_ ?
diff --git a/chrome/browser/ui/sync/one_click_signin_sync_starter.cc b/chrome/browser/ui/sync/one_click_signin_sync_starter.cc index 4933765..6f89100 100644 --- a/chrome/browser/ui/sync/one_click_signin_sync_starter.cc +++ b/chrome/browser/ui/sync/one_click_signin_sync_starter.cc
@@ -565,7 +565,7 @@ // create a new one. browser = chrome::FindLastActiveWithProfile(profile); if (!browser) { - browser = new Browser(Browser::CreateParams(profile)); + browser = new Browser(Browser::CreateParams(profile, true)); chrome::AddTabAt(browser, GURL(), -1, true); } browser->window()->Show();
diff --git a/chrome/browser/ui/tab_contents/tab_contents_iterator_unittest.cc b/chrome/browser/ui/tab_contents/tab_contents_iterator_unittest.cc index 7c71a2f0..a1398fe 100644 --- a/chrome/browser/ui/tab_contents/tab_contents_iterator_unittest.cc +++ b/chrome/browser/ui/tab_contents/tab_contents_iterator_unittest.cc
@@ -48,12 +48,12 @@ EXPECT_EQ(0U, CountAllTabs()); // Create more browsers/windows. - Browser::CreateParams native_params(profile()); + Browser::CreateParams native_params(profile(), true); std::unique_ptr<Browser> browser2( chrome::CreateBrowserWithTestWindowForParams(&native_params)); // Create browser 3 and 4 on the Ash desktop (the TabContentsIterator // shouldn't see the difference). - Browser::CreateParams ash_params(profile()); + Browser::CreateParams ash_params(profile(), true); std::unique_ptr<Browser> browser3( chrome::CreateBrowserWithTestWindowForParams(&ash_params)); std::unique_ptr<Browser> browser4( @@ -94,12 +94,12 @@ EXPECT_EQ(1U, BrowserList::GetInstance()->size()); // Create more browsers/windows. - Browser::CreateParams native_params(profile()); + Browser::CreateParams native_params(profile(), true); std::unique_ptr<Browser> browser2( chrome::CreateBrowserWithTestWindowForParams(&native_params)); // Create browser 3 on the Ash desktop (the TabContentsIterator shouldn't see // the difference). - Browser::CreateParams ash_params(profile()); + Browser::CreateParams ash_params(profile(), true); std::unique_ptr<Browser> browser3( chrome::CreateBrowserWithTestWindowForParams(&ash_params));
diff --git a/chrome/browser/ui/tabs/pinned_tab_service_unittest.cc b/chrome/browser/ui/tabs/pinned_tab_service_unittest.cc index 7ba1521..e851160 100644 --- a/chrome/browser/ui/tabs/pinned_tab_service_unittest.cc +++ b/chrome/browser/ui/tabs/pinned_tab_service_unittest.cc
@@ -57,7 +57,7 @@ browser()->tab_strip_model()->SetTabPinned(0, true); // Create a popup. - Browser::CreateParams params(Browser::TYPE_POPUP, profile()); + Browser::CreateParams params(Browser::TYPE_POPUP, profile(), true); std::unique_ptr<Browser> popup( chrome::CreateBrowserWithTestWindowForParams(¶ms));
diff --git a/chrome/browser/ui/toolbar/back_forward_menu_model_unittest.cc b/chrome/browser/ui/toolbar/back_forward_menu_model_unittest.cc index 48395cb..4ff581c 100644 --- a/chrome/browser/ui/toolbar/back_forward_menu_model_unittest.cc +++ b/chrome/browser/ui/toolbar/back_forward_menu_model_unittest.cc
@@ -502,7 +502,7 @@ TEST_F(BackFwdMenuModelTest, FaviconLoadTest) { ASSERT_TRUE(profile()->CreateHistoryService(true, false)); profile()->CreateFaviconService(); - Browser::CreateParams native_params(profile()); + Browser::CreateParams native_params(profile(), true); std::unique_ptr<Browser> browser( chrome::CreateBrowserWithTestWindowForParams(&native_params)); FaviconDelegate favicon_delegate;
diff --git a/chrome/browser/ui/toolbar/browser_actions_bar_browsertest.cc b/chrome/browser/ui/toolbar/browser_actions_bar_browsertest.cc index 7c0e3f8..9ea5488 100644 --- a/chrome/browser/ui/toolbar/browser_actions_bar_browsertest.cc +++ b/chrome/browser/ui/toolbar/browser_actions_bar_browsertest.cc
@@ -657,7 +657,7 @@ test_data_dir_.AppendASCII("api_test/browser_action_with_icon")); ASSERT_TRUE(extension); Browser* second_browser = - new Browser(Browser::CreateParams(profile()->GetOriginalProfile())); + new Browser(Browser::CreateParams(profile()->GetOriginalProfile(), true)); base::RunLoop().RunUntilIdle(); EXPECT_FALSE(second_browser->profile()->IsOffTheRecord());
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bar_view_test.cc b/chrome/browser/ui/views/bookmarks/bookmark_bar_view_test.cc index c5e3931..6f2584e 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_bar_view_test.cc +++ b/chrome/browser/ui/views/bookmarks/bookmark_bar_view_test.cc
@@ -292,7 +292,7 @@ bookmarks::test::WaitForBookmarkModelToLoad(model_); profile_->GetPrefs()->SetBoolean(bookmarks::prefs::kShowBookmarkBar, true); - Browser::CreateParams native_params(profile_.get()); + Browser::CreateParams native_params(profile_.get(), true); browser_ = chrome::CreateBrowserWithTestWindowForParams(&native_params); local_state_.reset(new ScopedTestingLocalState(
diff --git a/chrome/browser/ui/views/frame/browser_frame_ash_browsertest.cc b/chrome/browser/ui/views/frame/browser_frame_ash_browsertest.cc index 5c7ca15..9ef7ea98 100644 --- a/chrome/browser/ui/views/frame/browser_frame_ash_browsertest.cc +++ b/chrome/browser/ui/views/frame/browser_frame_ash_browsertest.cc
@@ -39,8 +39,8 @@ Browser::CreateParams params = test_app ? Browser::CreateParams::CreateForApp( "test_browser_app", true /* trusted_source */, gfx::Rect(), - browser()->profile()) - : Browser::CreateParams(browser()->profile()); + browser()->profile(), true) + : Browser::CreateParams(browser()->profile(), true); params.initial_show_state = ui::SHOW_STATE_DEFAULT; Browser* browser = new Browser(params); gfx::NativeWindow window = browser->window()->GetNativeWindow();
diff --git a/chrome/browser/ui/views/frame/browser_view_browsertest.cc b/chrome/browser/ui/views/frame/browser_view_browsertest.cc index f12840b..fcf78786 100644 --- a/chrome/browser/ui/views/frame/browser_view_browsertest.cc +++ b/chrome/browser/ui/views/frame/browser_view_browsertest.cc
@@ -85,7 +85,8 @@ // Additionally when one of the tabs is destroyed NotifyNavigationStateChanged() // is invoked on the other. IN_PROC_BROWSER_TEST_F(BrowserViewTest, CloseWithTabs) { - Browser* browser2 = new Browser(Browser::CreateParams(browser()->profile())); + Browser* browser2 = + new Browser(Browser::CreateParams(browser()->profile(), true)); chrome::AddTabAt(browser2, GURL(), -1, true); chrome::AddTabAt(browser2, GURL(), -1, true); TestWebContentsObserver observer( @@ -97,7 +98,8 @@ // Same as CloseWithTabs, but activates the first tab, which is the first tab // BrowserView will destroy. IN_PROC_BROWSER_TEST_F(BrowserViewTest, CloseWithTabsStartWithActive) { - Browser* browser2 = new Browser(Browser::CreateParams(browser()->profile())); + Browser* browser2 = + new Browser(Browser::CreateParams(browser()->profile(), true)); chrome::AddTabAt(browser2, GURL(), -1, true); chrome::AddTabAt(browser2, GURL(), -1, true); browser2->tab_strip_model()->ActivateTabAt(0, true);
diff --git a/chrome/browser/ui/views/frame/browser_view_focus_uitest.cc b/chrome/browser/ui/views/frame/browser_view_focus_uitest.cc index 9fbc0bc..21314ed 100644 --- a/chrome/browser/ui/views/frame/browser_view_focus_uitest.cc +++ b/chrome/browser/ui/views/frame/browser_view_focus_uitest.cc
@@ -56,7 +56,8 @@ // of Activate() is not well defined and can vary by window manager. #if defined(OS_WIN) // Open a new browser window. - Browser* browser2 = new Browser(Browser::CreateParams(browser()->profile())); + Browser* browser2 = + new Browser(Browser::CreateParams(browser()->profile(), true)); ASSERT_TRUE(browser2); chrome::AddTabAt(browser2, GURL(), -1, true); browser2->window()->Show();
diff --git a/chrome/browser/ui/views/frame/browser_view_interactive_uitest.cc b/chrome/browser/ui/views/frame/browser_view_interactive_uitest.cc index 9226bf3e..6dbcc82e 100644 --- a/chrome/browser/ui/views/frame/browser_view_interactive_uitest.cc +++ b/chrome/browser/ui/views/frame/browser_view_interactive_uitest.cc
@@ -74,8 +74,8 @@ Browser::CreateParams params = test_app ? Browser::CreateParams::CreateForApp( "test_browser_app", true /* trusted_source */, gfx::Rect(), - browser()->profile()) - : Browser::CreateParams(browser()->profile()); + browser()->profile(), true) + : Browser::CreateParams(browser()->profile(), true); params.initial_show_state = ui::SHOW_STATE_DEFAULT; // Default |browser()| is not used by this test.
diff --git a/chrome/browser/ui/views/frame/browser_window_factory.cc b/chrome/browser/ui/views/frame/browser_window_factory.cc index 1f66083..f8b524f 100644 --- a/chrome/browser/ui/views/frame/browser_window_factory.cc +++ b/chrome/browser/ui/views/frame/browser_window_factory.cc
@@ -6,11 +6,14 @@ #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/frame/native_browser_frame_factory.h" #include "chrome/grit/chromium_strings.h" +#include "ui/aura/client/aura_constants.h" +#include "ui/aura/window.h" #include "ui/base/l10n/l10n_util.h" #include "ui/views/widget/widget.h" // static -BrowserWindow* BrowserWindow::CreateBrowserWindow(Browser* browser) { +BrowserWindow* BrowserWindow::CreateBrowserWindow(Browser* browser, + bool user_gesture) { // Create the view and the frame. The frame will attach itself via the view // so we don't need to do anything with the pointer. BrowserView* view = new BrowserView(); @@ -18,5 +21,8 @@ (new BrowserFrame(view))->InitBrowserFrame(); view->GetWidget()->non_client_view()->SetAccessibleName( l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)); + // For now, all browser windows are true. + view->GetWidget()->GetNativeWindow()->SetProperty( + aura::client::kCreatedByUserGesture, user_gesture); return view; }
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 6504936..22fa553 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
@@ -92,11 +92,11 @@ CreditCardEditorViewController::CreateHeaderView() { std::unique_ptr<views::View> view = base::MakeUnique<views::View>(); - // 9dp is required between the first and second row. - constexpr int kRowVerticalInset = 9; + // 9dp is required between the first row (label) and second row (icons). + constexpr int kRowVerticalSpacing = 9; views::BoxLayout* layout = new views::BoxLayout( views::BoxLayout::kVertical, payments::kPaymentRequestRowHorizontalInsets, - payments::kPaymentRequestRowVerticalInsets, kRowVerticalInset); + 0, kRowVerticalSpacing); layout->set_main_axis_alignment(views::BoxLayout::MAIN_AXIS_ALIGNMENT_START); layout->set_cross_axis_alignment( views::BoxLayout::CROSS_AXIS_ALIGNMENT_START); @@ -136,12 +136,12 @@ std::vector<EditorField> CreditCardEditorViewController::GetFieldDefinitions() { return std::vector<EditorField>{ - {autofill::CREDIT_CARD_NAME_FULL, - l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_NAME_ON_CARD), - EditorField::LengthHint::HINT_LONG, /* required= */ true}, {autofill::CREDIT_CARD_NUMBER, l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_CREDIT_CARD_NUMBER), EditorField::LengthHint::HINT_LONG, /* required= */ true}, + {autofill::CREDIT_CARD_NAME_FULL, + l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_NAME_ON_CARD), + EditorField::LengthHint::HINT_LONG, /* required= */ true}, {autofill::CREDIT_CARD_EXP_MONTH, l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_EXPIRATION_MONTH), EditorField::LengthHint::HINT_SHORT, /* required= */ true, @@ -190,7 +190,8 @@ CreditCardEditorViewController::CreateValidationDelegate( const EditorField& field) { return base::MakeUnique< - CreditCardEditorViewController::CreditCardValidationDelegate>(field); + CreditCardEditorViewController::CreditCardValidationDelegate>(field, + this); } std::unique_ptr<ui::ComboboxModel> @@ -215,8 +216,9 @@ } CreditCardEditorViewController::CreditCardValidationDelegate:: - CreditCardValidationDelegate(const EditorField& field) - : field_(field) {} + CreditCardValidationDelegate(const EditorField& field, + EditorViewController* controller) + : field_(field), controller_(controller) {} CreditCardEditorViewController::CreditCardValidationDelegate:: ~CreditCardValidationDelegate() {} @@ -234,12 +236,19 @@ ValidateValue(const base::string16& value) { if (!value.empty()) { base::string16 error_message; - // TODO(mathp): Display |error_message| around |textfield|. - return autofill::IsValidForType(value, field_.type, &error_message); + bool is_valid = + autofill::IsValidForType(value, field_.type, &error_message); + controller_->DisplayErrorMessageForField(field_, error_message); + return is_valid; } - // TODO(mathp): Display "required" error if applicable. - return !field_.required; + bool is_required_valid = !field_.required; + const base::string16 displayed_message = + is_required_valid ? base::ASCIIToUTF16("") + : l10n_util::GetStringUTF16( + IDS_PAYMENTS_FIELD_REQUIRED_VALIDATION_MESSAGE); + controller_->DisplayErrorMessageForField(field_, displayed_message); + return is_required_valid; } } // namespace payments
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 4ea2ef7..c13e8f7 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
@@ -35,7 +35,8 @@ private: class CreditCardValidationDelegate : public ValidationDelegate { public: - explicit CreditCardValidationDelegate(const EditorField& field); + CreditCardValidationDelegate(const EditorField& field, + EditorViewController* controller); ~CreditCardValidationDelegate() override; // ValidationDelegate: @@ -47,6 +48,8 @@ bool ValidateValue(const base::string16& value); EditorField field_; + // Outlives this class. + EditorViewController* controller_; DISALLOW_COPY_AND_ASSIGN(CreditCardValidationDelegate); };
diff --git a/chrome/browser/ui/views/payments/editor_view_controller.cc b/chrome/browser/ui/views/payments/editor_view_controller.cc index 2b4c1efce..2d6710ab 100644 --- a/chrome/browser/ui/views/payments/editor_view_controller.cc +++ b/chrome/browser/ui/views/payments/editor_view_controller.cc
@@ -61,14 +61,13 @@ layout->set_cross_axis_alignment( views::BoxLayout::CROSS_AXIS_ALIGNMENT_STRETCH); content_view->SetLayoutManager(layout); + // No insets. Child views below are responsible for their padding. + // An editor can optionally have a header view specific to it. content_view->AddChildView(CreateHeaderView().release()); - // Create an input label/textfield for each field definition. - std::vector<EditorField> fields = GetFieldDefinitions(); - for (const auto& field : fields) { - content_view->AddChildView(CreateInputField(field).release()); - } + // The heart of the editor dialog: all the input fields with their labels. + content_view->AddChildView(CreateEditorView().release()); return CreatePaymentView( CreateSheetHeaderView( @@ -102,6 +101,16 @@ return content_view; } +void EditorViewController::DisplayErrorMessageForField( + const EditorField& field, + const base::string16& error_message) { + const auto& label_it = error_labels_.find(field); + DCHECK(label_it != error_labels_.end()); + label_it->second->SetText(error_message); + label_it->second->SchedulePaint(); + dialog()->Layout(); +} + std::unique_ptr<views::Button> EditorViewController::CreatePrimaryButton() { std::unique_ptr<views::Button> button( views::MdTextButton::CreateSecondaryUiBlueButton( @@ -133,31 +142,59 @@ static_cast<ValidatingCombobox*>(sender)->OnContentsChanged(); } -std::unique_ptr<views::View> EditorViewController::CreateInputField( - const EditorField& field) { - std::unique_ptr<views::View> row = base::MakeUnique<views::View>(); +std::unique_ptr<views::View> EditorViewController::CreateEditorView() { + std::unique_ptr<views::View> editor_view = base::MakeUnique<views::View>(); - row->SetBorder(payments::CreatePaymentRequestRowBorder()); + views::GridLayout* editor_layout = new views::GridLayout(editor_view.get()); - views::GridLayout* layout = new views::GridLayout(row.get()); + // The editor grid layout is padded vertically from the top and bottom, and + // horizontally inset like other content views. The top padding needs to be + // added to the top padding of the first row. + constexpr int kEditorVerticalInset = 16; + editor_layout->SetInsets( + kEditorVerticalInset, payments::kPaymentRequestRowHorizontalInsets, + kEditorVerticalInset, payments::kPaymentRequestRowHorizontalInsets); - // The vertical spacing for these rows is slightly different than the spacing - // spacing for clickable rows, so don't use kPaymentRequestRowVerticalInsets. - constexpr int kRowVerticalInset = 12; - layout->SetInsets( - kRowVerticalInset, payments::kPaymentRequestRowHorizontalInsets, - kRowVerticalInset, payments::kPaymentRequestRowHorizontalInsets); - - row->SetLayoutManager(layout); - views::ColumnSet* columns = layout->AddColumnSet(0); + editor_view->SetLayoutManager(editor_layout); + views::ColumnSet* columns = editor_layout->AddColumnSet(0); columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::CENTER, 0, views::GridLayout::USE_PREF, 0, 0); - columns->AddPaddingColumn(1, 0); - columns->AddColumn(views::GridLayout::TRAILING, views::GridLayout::CENTER, 0, + + // This is the horizontal padding between the label and the input field. + constexpr int kLabelInputFieldHorizontalPadding = 16; + columns->AddPaddingColumn(0, kLabelInputFieldHorizontalPadding); + + columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::CENTER, 0, views::GridLayout::USE_PREF, 0, 0); - layout->StartRow(0, 0); - layout->AddView(new views::Label(field.label)); + std::vector<EditorField> fields = GetFieldDefinitions(); + for (const auto& field : fields) { + CreateInputField(editor_layout, field); + } + + return editor_view; +} + +// Each input field is a 4-quadrant grid. +// +----------------------------------------------------------+ +// | Field Label | Input field (textfield/combobox) | +// |_______________________|__________________________________| +// | (empty) | Error label | +// +----------------------------------------------------------+ +void EditorViewController::CreateInputField(views::GridLayout* layout, + const EditorField& field) { + // This is the top padding for every row. + constexpr int kInputRowSpacing = 6; + layout->StartRowWithPadding(0, 0, 0, kInputRowSpacing); + + std::unique_ptr<views::Label> label = base::MakeUnique<views::Label>( + field.required ? field.label + base::ASCIIToUTF16("*") : field.label); + // A very long label will wrap. Value picked so that left + right label + // padding bring the label to half-way in the dialog (~225). + constexpr int kMaximumLabelWidth = 192; + label->SetMultiLine(true); + label->SetMaximumWidth(kMaximumLabelWidth); + layout->AddView(label.release()); if (field.control_type == EditorField::ControlType::TEXTFIELD) { ValidatingTextfield* text_field = @@ -186,7 +223,22 @@ NOTREACHED(); } - return row; + // This is the vertical space between the input field and its error label. + constexpr int kInputErrorLabelPadding = 6; + layout->StartRowWithPadding(0, 0, 0, kInputErrorLabelPadding); + layout->SkipColumns(1); + // Error label is initially empty. + std::unique_ptr<views::Label> error_label = + base::MakeUnique<views::Label>(base::ASCIIToUTF16("")); + error_label->set_id(static_cast<int>(DialogViewID::ERROR_LABEL_OFFSET) + + field.type); + error_label->SetFontList( + error_label->GetDefaultFontList().DeriveWithSizeDelta(-1)); + error_label->SetEnabledColor(error_label->GetNativeTheme()->GetSystemColor( + ui::NativeTheme::kColorId_AlertSeverityHigh)); + error_labels_[field] = error_label.get(); + + layout->AddView(error_label.release()); } } // 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 3001efd..8788199 100644 --- a/chrome/browser/ui/views/payments/editor_view_controller.h +++ b/chrome/browser/ui/views/payments/editor_view_controller.h
@@ -6,6 +6,7 @@ #define CHROME_BROWSER_UI_VIEWS_PAYMENTS_EDITOR_VIEW_CONTROLLER_H_ #include <memory> +#include <tuple> #include <unordered_map> #include <vector> @@ -25,6 +26,8 @@ } namespace views { +class GridLayout; +class Label; class Textfield; class View; } // namespace views @@ -52,6 +55,12 @@ required(required), control_type(control_type) {} + struct Compare { + bool operator()(const EditorField& lhs, const EditorField& rhs) const { + return std::tie(lhs.type, lhs.label) < std::tie(rhs.type, rhs.label); + } + }; + // Data type in the field. const autofill::ServerFieldType type; // Label to be shown alongside the field. @@ -74,6 +83,8 @@ std::unordered_map<ValidatingTextfield*, const EditorField>; using ComboboxMap = std::unordered_map<ValidatingCombobox*, const EditorField>; + using ErrorLabelMap = + std::map<const EditorField, views::Label*, EditorField::Compare>; // Does not take ownership of the arguments, which should outlive this object. EditorViewController(PaymentRequest* request, @@ -96,6 +107,11 @@ virtual std::unique_ptr<ui::ComboboxModel> GetComboboxModelForType( const autofill::ServerFieldType& type) = 0; + // Will display |error_message| alongside the input field represented by + // |field|. + void DisplayErrorMessageForField(const EditorField& field, + const base::string16& error_message); + const ComboboxMap& comboboxes() const { return comboboxes_; } const TextFieldsMap& text_fields() const { return text_fields_; } @@ -114,10 +130,15 @@ // views::ComboboxListener: void OnPerformAction(views::Combobox* combobox) override; - // Creates a view for an input field to be added in the editor sheet. |field| - // is the field definition, which contains the label and the hint about - // the length of the input field. - std::unique_ptr<views::View> CreateInputField(const EditorField& field); + // Creates the whole editor view to go within the editor dialog. It + // encompasses all the input fields created by CreateInputField(). + std::unique_ptr<views::View> CreateEditorView(); + + // Adds some views to |layout|, to represent an input field and its labels. + // |field| is the field definition, which contains the label and the hint + // about the length of the input field. A placeholder error label is also + // added (see implementation). + void CreateInputField(views::GridLayout* layout, const EditorField& field); // Used to remember the association between the input field UI element and the // original field definition. The ValidatingTextfield* and ValidatingCombobox* @@ -125,6 +146,8 @@ // long as the input field is visible. TextFieldsMap text_fields_; ComboboxMap comboboxes_; + // Tracks the relationship between a field and its error label. + ErrorLabelMap error_labels_; DISALLOW_COPY_AND_ASSIGN(EditorViewController); };
diff --git a/chrome/browser/ui/views/payments/payment_method_view_controller.cc b/chrome/browser/ui/views/payments/payment_method_view_controller.cc index 0c98740..8b29bc31 100644 --- a/chrome/browser/ui/views/payments/payment_method_view_controller.cc +++ b/chrome/browser/ui/views/payments/payment_method_view_controller.cc
@@ -8,16 +8,24 @@ #include <utility> #include "base/memory/ptr_util.h" +#include "chrome/browser/browser_process.h" #include "chrome/browser/ui/views/payments/payment_request_dialog_view.h" #include "chrome/browser/ui/views/payments/payment_request_dialog_view_ids.h" +#include "chrome/browser/ui/views/payments/payment_request_row_view.h" #include "chrome/browser/ui/views/payments/payment_request_views_util.h" #include "chrome/grit/generated_resources.h" +#include "components/autofill/core/browser/autofill_type.h" +#include "components/autofill/core/browser/credit_card.h" #include "components/payments/payment_request.h" #include "components/strings/grit/components_strings.h" +#include "third_party/skia/include/core/SkColor.h" #include "ui/base/l10n/l10n_util.h" +#include "ui/gfx/paint_vector_icon.h" #include "ui/views/controls/button/label_button.h" #include "ui/views/controls/button/md_text_button.h" -#include "ui/views/layout/fill_layout.h" +#include "ui/views/layout/box_layout.h" +#include "ui/views/layout/grid_layout.h" +#include "ui/views/vector_icons.h" namespace payments { @@ -32,36 +40,129 @@ ADD_CREDIT_CARD_BUTTON = kFirstTagValue, }; +class PaymentMethodListItem : public payments::PaymentRequestItemList::Item, + public views::ButtonListener { + public: + // Does not take ownership of |card|, which should not be null and should + // outlive this object. + explicit PaymentMethodListItem(autofill::CreditCard* card) : card_(card) {} + ~PaymentMethodListItem() override {} + + private: + // payments::PaymentRequestItemList::Item: + std::unique_ptr<views::View> CreateItemView() override { + std::unique_ptr<PaymentRequestRowView> row = + base::MakeUnique<PaymentRequestRowView>(this); + views::GridLayout* layout = new views::GridLayout(row.get()); + layout->SetInsets( + kPaymentRequestRowVerticalInsets, kPaymentRequestRowHorizontalInsets, + kPaymentRequestRowVerticalInsets, kPaymentRequestRowHorizontalInsets); + row->SetLayoutManager(layout); + views::ColumnSet* columns = layout->AddColumnSet(0); + + // A column for the masked number and name on card + columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::CENTER, 0, + views::GridLayout::USE_PREF, 0, 0); + + // A padding column that resizes to take up the empty space between the + // leading and trailing parts. + columns->AddPaddingColumn(1, 0); + + // A column for the checkmark when the row is selected. + columns->AddColumn(views::GridLayout::TRAILING, views::GridLayout::CENTER, + 0, views::GridLayout::USE_PREF, 0, 0); + + // A column for the card icon + columns->AddColumn(views::GridLayout::TRAILING, views::GridLayout::CENTER, + 0, views::GridLayout::USE_PREF, 0, 0); + + // A column for the edit button + columns->AddColumn(views::GridLayout::TRAILING, views::GridLayout::CENTER, + 0, views::GridLayout::USE_PREF, 0, 0); + + layout->StartRow(0, 0); + std::unique_ptr<views::View> card_info_container = + base::MakeUnique<views::View>(); + card_info_container->set_can_process_events_within_subtree(false); + + std::unique_ptr<views::BoxLayout> box_layout = + base::MakeUnique<views::BoxLayout>(views::BoxLayout::kVertical, 0, + kPaymentRequestRowVerticalInsets, 0); + box_layout->set_cross_axis_alignment( + views::BoxLayout::CROSS_AXIS_ALIGNMENT_START); + card_info_container->SetLayoutManager(box_layout.release()); + + card_info_container->AddChildView( + new views::Label(card_->TypeAndLastFourDigits())); + card_info_container->AddChildView(new views::Label( + card_->GetInfo(autofill::AutofillType(autofill::CREDIT_CARD_NAME_FULL), + g_browser_process->GetApplicationLocale()))); + layout->AddView(card_info_container.release()); + + std::unique_ptr<views::ImageView> checkmark = + base::MakeUnique<views::ImageView>(); + checkmark->set_interactive(false); + checkmark->SetImage( + gfx::CreateVectorIcon(views::kMenuCheckIcon, 0xFF609265)); + layout->AddView(checkmark.release()); + + std::unique_ptr<views::ImageView> card_icon_view = + CreateCardIconView(card_->type()); + card_icon_view->SetImageSize(gfx::Size(32, 20)); + layout->AddView(card_icon_view.release()); + + return std::move(row); + } + + // views::ButtonListener: + void ButtonPressed(views::Button* sender, const ui::Event& event) override {} + + autofill::CreditCard* card_; + + DISALLOW_COPY_AND_ASSIGN(PaymentMethodListItem); +}; + } // namespace PaymentMethodViewController::PaymentMethodViewController( PaymentRequest* request, PaymentRequestDialogView* dialog) - : PaymentRequestSheetController(request, dialog) {} + : PaymentRequestSheetController(request, dialog) { + const std::vector<autofill::CreditCard*>& available_cards = + request->credit_cards(); + + for (autofill::CreditCard* card : available_cards) { + payment_method_list_.AddItem(base::MakeUnique<PaymentMethodListItem>(card)); + } +} PaymentMethodViewController::~PaymentMethodViewController() {} std::unique_ptr<views::View> PaymentMethodViewController::CreateView() { - std::unique_ptr<views::View> content_view = base::MakeUnique<views::View>(); + return CreatePaymentView( + CreateSheetHeaderView( + true, l10n_util::GetStringUTF16( + IDS_PAYMENT_REQUEST_PAYMENT_METHOD_SECTION_NAME), + this), + payment_method_list_.CreateListView()); +} - views::FillLayout* layout = new views::FillLayout(); - content_view->SetLayoutManager(layout); +std::unique_ptr<views::View> PaymentMethodViewController::CreateExtraView() { + std::unique_ptr<views::View> extra_view = base::MakeUnique<views::View>(); - // Create the "Add a card" button. + extra_view->SetLayoutManager(new views::BoxLayout( + views::BoxLayout::kHorizontal, kPaymentRequestRowHorizontalInsets, + kPaymentRequestRowVerticalInsets, kPaymentRequestButtonSpacing)); + views::LabelButton* button = views::MdTextButton::CreateSecondaryUiButton( this, l10n_util::GetStringUTF16(IDS_AUTOFILL_ADD_CREDITCARD_CAPTION)); button->set_tag(static_cast<int>( PaymentMethodViewControllerTags::ADD_CREDIT_CARD_BUTTON)); button->set_id( static_cast<int>(DialogViewID::PAYMENT_METHOD_ADD_CARD_BUTTON)); - content_view->AddChildView(button); + extra_view->AddChildView(button); - return CreatePaymentView(CreateSheetHeaderView( - true, - l10n_util::GetStringUTF16( - IDS_PAYMENT_REQUEST_PAYMENT_METHOD_SECTION_NAME), - this), - std::move(content_view)); + return extra_view; } void PaymentMethodViewController::ButtonPressed(views::Button* sender,
diff --git a/chrome/browser/ui/views/payments/payment_method_view_controller.h b/chrome/browser/ui/views/payments/payment_method_view_controller.h index 8abb216..4662d27 100644 --- a/chrome/browser/ui/views/payments/payment_method_view_controller.h +++ b/chrome/browser/ui/views/payments/payment_method_view_controller.h
@@ -6,6 +6,7 @@ #define CHROME_BROWSER_UI_VIEWS_PAYMENTS_PAYMENT_METHOD_VIEW_CONTROLLER_H_ #include "base/macros.h" +#include "chrome/browser/ui/views/payments/payment_request_item_list.h" #include "chrome/browser/ui/views/payments/payment_request_sheet_controller.h" namespace payments { @@ -27,8 +28,11 @@ private: // PaymentRequestSheetController: + std::unique_ptr<views::View> CreateExtraView() override; void ButtonPressed(views::Button* sender, const ui::Event& event) override; + PaymentRequestItemList payment_method_list_; + DISALLOW_COPY_AND_ASSIGN(PaymentMethodViewController); };
diff --git a/chrome/browser/ui/views/payments/payment_request_credit_card_editor_interactive_uitest.cc b/chrome/browser/ui/views/payments/payment_request_credit_card_editor_interactive_uitest.cc index 3e7b5f3..d41a30e 100644 --- a/chrome/browser/ui/views/payments/payment_request_credit_card_editor_interactive_uitest.cc +++ b/chrome/browser/ui/views/payments/payment_request_credit_card_editor_interactive_uitest.cc
@@ -15,9 +15,11 @@ #include "components/autofill/core/browser/personal_data_manager_observer.h" #include "components/autofill/core/browser/test_autofill_clock.h" #include "components/payments/payment_request.h" +#include "components/strings/grit/components_strings.h" #include "content/public/test/browser_test_utils.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +#include "ui/base/l10n/l10n_util.h" namespace payments { @@ -130,6 +132,42 @@ } IN_PROC_BROWSER_TEST_F(PaymentRequestCreditCardEditorTest, + EnteringNothingInARequiredField) { + autofill::TestAutofillClock test_clock; + test_clock.SetNow(kJune2017); + + InvokePaymentRequestUI(); + + OpenPaymentMethodScreen(); + + OpenCreditCardEditorScreen(); + + // This field is required. Entering nothing and blurring out will show + // "Required field". + SetEditorTextfieldValue(base::ASCIIToUTF16(""), autofill::CREDIT_CARD_NUMBER); + EXPECT_TRUE(IsEditorTextfieldInvalid(autofill::CREDIT_CARD_NUMBER)); + EXPECT_EQ( + l10n_util::GetStringUTF16(IDS_PAYMENTS_FIELD_REQUIRED_VALIDATION_MESSAGE), + GetErrorLabelForType(autofill::CREDIT_CARD_NUMBER)); + + // Set the value to something which is not a valid card number. The "invalid + // card number" string takes precedence over "required field" + SetEditorTextfieldValue(base::ASCIIToUTF16("41111111invalidcard"), + autofill::CREDIT_CARD_NUMBER); + EXPECT_TRUE(IsEditorTextfieldInvalid(autofill::CREDIT_CARD_NUMBER)); + EXPECT_EQ(l10n_util::GetStringUTF16( + IDS_PAYMENTS_CARD_NUMBER_INVALID_VALIDATION_MESSAGE), + GetErrorLabelForType(autofill::CREDIT_CARD_NUMBER)); + + // Set the value to a valid number now. No more errors! + SetEditorTextfieldValue(base::ASCIIToUTF16("4111111111111111"), + autofill::CREDIT_CARD_NUMBER); + EXPECT_FALSE(IsEditorTextfieldInvalid(autofill::CREDIT_CARD_NUMBER)); + EXPECT_EQ(base::ASCIIToUTF16(""), + GetErrorLabelForType(autofill::CREDIT_CARD_NUMBER)); +} + +IN_PROC_BROWSER_TEST_F(PaymentRequestCreditCardEditorTest, EnteringInvalidCardNumber) { autofill::TestAutofillClock test_clock; test_clock.SetNow(kJune2017); @@ -144,6 +182,9 @@ autofill::CREDIT_CARD_NAME_FULL); SetEditorTextfieldValue(base::ASCIIToUTF16("41111111invalidcard"), autofill::CREDIT_CARD_NUMBER); + EXPECT_EQ(l10n_util::GetStringUTF16( + IDS_PAYMENTS_CARD_NUMBER_INVALID_VALIDATION_MESSAGE), + GetErrorLabelForType(autofill::CREDIT_CARD_NUMBER)); SetComboboxValue(base::ASCIIToUTF16("05"), autofill::CREDIT_CARD_EXP_MONTH); SetComboboxValue(base::ASCIIToUTF16("2026"), autofill::CREDIT_CARD_EXP_4_DIGIT_YEAR); @@ -160,6 +201,66 @@ EXPECT_EQ(0u, personal_data_manager->GetCreditCards().size()); } +IN_PROC_BROWSER_TEST_F(PaymentRequestCreditCardEditorTest, + EnteringInvalidCardNumber_AndFixingIt) { + autofill::TestAutofillClock test_clock; + test_clock.SetNow(kJune2017); + + InvokePaymentRequestUI(); + + OpenPaymentMethodScreen(); + + OpenCreditCardEditorScreen(); + + SetEditorTextfieldValue(base::ASCIIToUTF16("Bob Jones"), + autofill::CREDIT_CARD_NAME_FULL); + SetEditorTextfieldValue(base::ASCIIToUTF16("41111111invalidcard"), + autofill::CREDIT_CARD_NUMBER); + EXPECT_EQ(l10n_util::GetStringUTF16( + IDS_PAYMENTS_CARD_NUMBER_INVALID_VALIDATION_MESSAGE), + GetErrorLabelForType(autofill::CREDIT_CARD_NUMBER)); + SetComboboxValue(base::ASCIIToUTF16("05"), autofill::CREDIT_CARD_EXP_MONTH); + SetComboboxValue(base::ASCIIToUTF16("2026"), + autofill::CREDIT_CARD_EXP_4_DIGIT_YEAR); + + ClickOnDialogViewAndWait(DialogViewID::EDITOR_SAVE_BUTTON); + + EXPECT_FALSE(IsEditorTextfieldInvalid(autofill::CREDIT_CARD_NAME_FULL)); + EXPECT_TRUE(IsEditorTextfieldInvalid(autofill::CREDIT_CARD_NUMBER)); + EXPECT_FALSE(IsEditorComboboxInvalid(autofill::CREDIT_CARD_EXP_MONTH)); + EXPECT_FALSE(IsEditorComboboxInvalid(autofill::CREDIT_CARD_EXP_4_DIGIT_YEAR)); + + // Fixing the card number. + SetEditorTextfieldValue(base::ASCIIToUTF16("4111111111111111"), + autofill::CREDIT_CARD_NUMBER); + // The error message has gone. + EXPECT_EQ(base::ASCIIToUTF16(""), + GetErrorLabelForType(autofill::CREDIT_CARD_NUMBER)); + + // Verifying the data is in the DB. + autofill::PersonalDataManager* personal_data_manager = + GetPaymentRequests(GetActiveWebContents())[0]->personal_data_manager(); + personal_data_manager->AddObserver(&personal_data_observer_); + + ResetEventObserver(DialogEvent::BACK_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(5, credit_card->expiration_month()); + EXPECT_EQ(2026, credit_card->expiration_year()); + EXPECT_EQ(base::ASCIIToUTF16("1111"), credit_card->LastFourDigits()); + EXPECT_EQ(base::ASCIIToUTF16("Bob Jones"), + credit_card->GetRawInfo(autofill::CREDIT_CARD_NAME_FULL)); +} + IN_PROC_BROWSER_TEST_F(PaymentRequestCreditCardEditorTest, EnteringEmptyData) { InvokePaymentRequestUI();
diff --git a/chrome/browser/ui/views/payments/payment_request_dialog_view_ids.h b/chrome/browser/ui/views/payments/payment_request_dialog_view_ids.h index a7f0843..e3de7b51 100644 --- a/chrome/browser/ui/views/payments/payment_request_dialog_view_ids.h +++ b/chrome/browser/ui/views/payments/payment_request_dialog_view_ids.h
@@ -5,13 +5,15 @@ #ifndef CHROME_BROWSER_UI_VIEWS_PAYMENTS_PAYMENT_REQUEST_DIALOG_VIEW_IDS_H_ #define CHROME_BROWSER_UI_VIEWS_PAYMENTS_PAYMENT_REQUEST_DIALOG_VIEW_IDS_H_ +#include "components/autofill/core/browser/field_types.h" + // This defines an enumeration of IDs that can uniquely identify a view within // the scope of the Payment Request Dialog. namespace payments { enum class DialogViewID : int { - VIEW_ID_NONE, + VIEW_ID_NONE = autofill::MAX_VALID_FIELD_TYPE, // The following are views::Button (clickable). PAYMENT_SHEET_CONTACT_INFO_SECTION, @@ -26,6 +28,10 @@ ORDER_SUMMARY_LINE_ITEM_1, ORDER_SUMMARY_LINE_ITEM_2, ORDER_SUMMARY_LINE_ITEM_3, + + // Used to label the error labels with an offset, which gets added to + // the Autofill type value they represent (for tests). + ERROR_LABEL_OFFSET, }; } // namespace payments
diff --git a/chrome/browser/ui/views/payments/payment_request_interactive_uitest_base.cc b/chrome/browser/ui/views/payments/payment_request_interactive_uitest_base.cc index 02f114e..991adf4 100644 --- a/chrome/browser/ui/views/payments/payment_request_interactive_uitest_base.cc +++ b/chrome/browser/ui/views/payments/payment_request_interactive_uitest_base.cc
@@ -30,6 +30,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/test/ui_controls.h" #include "ui/gfx/animation/test_animation_delegate.h" +#include "ui/views/controls/label.h" #include "ui/views/controls/styled_label.h" namespace payments { @@ -243,6 +244,14 @@ return static_cast<views::StyledLabel*>(view)->text(); } +const base::string16& PaymentRequestInteractiveTestBase::GetErrorLabelForType( + autofill::ServerFieldType type) { + views::View* view = dialog_view()->GetViewByID( + static_cast<int>(DialogViewID::ERROR_LABEL_OFFSET) + type); + DCHECK(view); + return static_cast<views::Label*>(view)->text(); +} + PaymentRequestInteractiveTestBase::DialogEventObserver::DialogEventObserver( PaymentRequestInteractiveTestBase::DialogEvent event) : event_(event), seen_(false) {}
diff --git a/chrome/browser/ui/views/payments/payment_request_interactive_uitest_base.h b/chrome/browser/ui/views/payments/payment_request_interactive_uitest_base.h index b111131d..3b718a8 100644 --- a/chrome/browser/ui/views/payments/payment_request_interactive_uitest_base.h +++ b/chrome/browser/ui/views/payments/payment_request_interactive_uitest_base.h
@@ -101,6 +101,8 @@ // Returns the text of the StyledLabel with the specific |view_id| that is a // child of the Payment Request dialog view. const base::string16& GetStyledLabelText(DialogViewID view_id); + // Returns the error label text associated with a given field |type|. + const base::string16& GetErrorLabelForType(autofill::ServerFieldType type); net::EmbeddedTestServer* https_server() { return https_server_.get(); }
diff --git a/chrome/browser/ui/views/payments/payment_request_item_list.cc b/chrome/browser/ui/views/payments/payment_request_item_list.cc new file mode 100644 index 0000000..0cb3ce87 --- /dev/null +++ b/chrome/browser/ui/views/payments/payment_request_item_list.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 "chrome/browser/ui/views/payments/payment_request_item_list.h" + +#include "chrome/browser/ui/views/payments/payment_request_views_util.h" +#include "ui/views/layout/box_layout.h" +#include "ui/views/view.h" + +namespace payments { + +PaymentRequestItemList::Item::Item() {} + +PaymentRequestItemList::Item::~Item() {} + +views::View* PaymentRequestItemList::Item::GetItemView() { + if (!item_view_) { + item_view_ = CreateItemView(); + item_view_->set_owned_by_client(); + } + + return item_view_.get(); +} + +PaymentRequestItemList::PaymentRequestItemList() {} + +PaymentRequestItemList::~PaymentRequestItemList() {} + +void PaymentRequestItemList::AddItem( + std::unique_ptr<PaymentRequestItemList::Item> item) { + items_.push_back(std::move(item)); +} + +std::unique_ptr<views::View> PaymentRequestItemList::CreateListView() { + std::unique_ptr<views::View> content_view = base::MakeUnique<views::View>(); + + views::BoxLayout* layout = new views::BoxLayout( + views::BoxLayout::kVertical, 0, kPaymentRequestRowVerticalInsets, 0); + content_view->SetLayoutManager(layout); + + for (auto& item : items_) { + content_view->AddChildView(item->GetItemView()); + } + + return content_view; +} + +} // namespace payments
diff --git a/chrome/browser/ui/views/payments/payment_request_item_list.h b/chrome/browser/ui/views/payments/payment_request_item_list.h new file mode 100644 index 0000000..71f4c04 --- /dev/null +++ b/chrome/browser/ui/views/payments/payment_request_item_list.h
@@ -0,0 +1,66 @@ +// 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_VIEWS_PAYMENTS_PAYMENT_REQUEST_ITEM_LIST_H_ +#define CHROME_BROWSER_UI_VIEWS_PAYMENTS_PAYMENT_REQUEST_ITEM_LIST_H_ + +#include <memory> +#include <vector> + +#include "base/macros.h" + +namespace views { +class View; +} + +namespace payments { + +// A control representing a list of selectable items in the PaymentRequest +// dialog. These lists enforce that only one of their elements be selectable at +// a time and that "incomplete" items (for example, a credit card with no known +// expriration date) behave differently when selected. Most of the time, this +// behavior is to show an editor screen. +class PaymentRequestItemList { + public: + // Represents an item in the item list. + class Item { + public: + Item(); + virtual ~Item(); + + // Gets the view associated with this item. It's owned by this object so + // that it can listen to any changes to the underlying model and update the + // view. + views::View* GetItemView(); + + protected: + // Creates and returns the view associated with this list item. + virtual std::unique_ptr<views::View> CreateItemView() = 0; + + private: + std::unique_ptr<views::View> item_view_; + + DISALLOW_COPY_AND_ASSIGN(Item); + }; + + PaymentRequestItemList(); + ~PaymentRequestItemList(); + + // Adds an item to this list. + void AddItem(std::unique_ptr<Item> item); + + // Creates and returns the UI representation of this list. It iterates over + // the items it contains, creates their associated views, and adds them to the + // hierarchy. + std::unique_ptr<views::View> CreateListView(); + + private: + std::vector<std::unique_ptr<Item>> items_; + + DISALLOW_COPY_AND_ASSIGN(PaymentRequestItemList); +}; + +} // namespace payments + +#endif // CHROME_BROWSER_UI_VIEWS_PAYMENTS_PAYMENT_REQUEST_ITEM_LIST_H_
diff --git a/chrome/browser/ui/views/payments/payment_request_sheet_controller.cc b/chrome/browser/ui/views/payments/payment_request_sheet_controller.cc index 09c3050f..ae91215 100644 --- a/chrome/browser/ui/views/payments/payment_request_sheet_controller.cc +++ b/chrome/browser/ui/views/payments/payment_request_sheet_controller.cc
@@ -25,6 +25,10 @@ return nullptr; } +std::unique_ptr<views::View> PaymentRequestSheetController::CreateExtraView() { + return nullptr; +} + void PaymentRequestSheetController::ButtonPressed( views::Button* sender, const ui::Event& event) { switch (static_cast<PaymentRequestCommonTags>(sender->tag())) { @@ -86,25 +90,19 @@ columns->AddColumn(views::GridLayout::TRAILING, views::GridLayout::CENTER, 0, views::GridLayout::USE_PREF, 0, 0); - // The horizontal distance between the right/left edges of the dialog and the - // elements. - constexpr int kFooterHorizontalInset = 16; - // The vertical distance between footer elements and the top/bottom border - // (the bottom border is the edge of the dialog). - constexpr int kFooterVerticalInset = 16; - layout->SetInsets(kFooterVerticalInset, kFooterHorizontalInset, - kFooterVerticalInset, kFooterHorizontalInset); - layout->StartRow(0, 0); - - layout->AddView(CreateLeadingFooterView().release()); + std::unique_ptr<views::View> extra_view = CreateExtraView(); + if (extra_view) + layout->AddView(extra_view.release()); + else + layout->SkipColumns(1); std::unique_ptr<views::View> trailing_buttons_container = base::MakeUnique<views::View>(); - constexpr int kButtonSpacing = 10; trailing_buttons_container->SetLayoutManager(new views::BoxLayout( - views::BoxLayout::kHorizontal, 0, 0, kButtonSpacing)); + views::BoxLayout::kHorizontal, kPaymentRequestRowHorizontalInsets, + kPaymentRequestRowVerticalInsets, kPaymentRequestButtonSpacing)); std::unique_ptr<views::Button> primary_button = CreatePrimaryButton(); if (primary_button)
diff --git a/chrome/browser/ui/views/payments/payment_request_sheet_controller.h b/chrome/browser/ui/views/payments/payment_request_sheet_controller.h index d7c73e7..fbe3339 100644 --- a/chrome/browser/ui/views/payments/payment_request_sheet_controller.h +++ b/chrome/browser/ui/views/payments/payment_request_sheet_controller.h
@@ -55,6 +55,17 @@ // enabled state). virtual std::unique_ptr<views::Button> CreatePrimaryButton(); + // Creates and returns the view to be displayed next to the "Pay" and "Cancel" + // buttons. May return an empty std::unique_ptr (nullptr) to indicate that no + // extra view is to be displayed.The caller takes ownership of the view but + // the view is guaranteed to be outlived by the controller so subclasses may + // retain a raw pointer to the returned view (for example to control its + // enabled state). + // +---------------------------+ + // | EXTRA VIEW | PAY | CANCEL | + // +---------------------------+ + virtual std::unique_ptr<views::View> CreateExtraView(); + // views::VectorIconButtonDelegate: void ButtonPressed(views::Button* sender, const ui::Event& event) override; @@ -71,7 +82,7 @@ // | CONTENT | // | VIEW | // +---------------------------+ - // | | CANCEL | PAY | <-- footer + // | EXTRA VIEW | PAY | CANCEL | <-- footer // +---------------------------+ std::unique_ptr<views::View> CreatePaymentView( std::unique_ptr<views::View> header_view,
diff --git a/chrome/browser/ui/views/payments/payment_request_views_util.h b/chrome/browser/ui/views/payments/payment_request_views_util.h index 424771b..10e23be 100644 --- a/chrome/browser/ui/views/payments/payment_request_views_util.h +++ b/chrome/browser/ui/views/payments/payment_request_views_util.h
@@ -25,9 +25,11 @@ constexpr int kPaymentRequestRowHorizontalInsets = 16; constexpr int kPaymentRequestRowVerticalInsets = 8; + // Extra inset relative to the header when a right edge should line up with the // close button's X rather than its invisible right edge. constexpr int kPaymentRequestRowExtraRightInset = 8; +constexpr int kPaymentRequestButtonSpacing = 10; enum class PaymentRequestCommonTags { BACK_BUTTON_TAG = 0,
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 21129d6..32ecb4b8 100644 --- a/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc +++ b/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc
@@ -19,7 +19,6 @@ #include "chrome/browser/ui/views/payments/payment_request_row_view.h" #include "chrome/browser/ui/views/payments/payment_request_views_util.h" #include "chrome/grit/generated_resources.h" -#include "components/autofill/core/browser/autofill_data_util.h" #include "components/autofill/core/browser/autofill_type.h" #include "components/autofill/core/browser/credit_card.h" #include "components/autofill/core/browser/field_types.h" @@ -301,8 +300,7 @@ // +----------------------------------------------+ std::unique_ptr<views::Button> PaymentSheetViewController::CreatePaymentMethodRow() { - autofill::CreditCard* selected_card = - request()->GetCurrentlySelectedCreditCard(); + autofill::CreditCard* selected_card = request()->selected_credit_card(); std::unique_ptr<views::View> content_view; std::unique_ptr<views::ImageView> card_icon_view;
diff --git a/chrome/browser/ui/views/tabs/tab_drag_controller.cc b/chrome/browser/ui/views/tabs/tab_drag_controller.cc index 1997b873..7e52331 100644 --- a/chrome/browser/ui/views/tabs/tab_drag_controller.cc +++ b/chrome/browser/ui/views/tabs/tab_drag_controller.cc
@@ -1733,7 +1733,7 @@ Profile* profile = Profile::FromBrowserContext(drag_data_[0].contents->GetBrowserContext()); - Browser::CreateParams create_params(Browser::TYPE_TABBED, profile); + Browser::CreateParams create_params(Browser::TYPE_TABBED, profile, true); create_params.initial_bounds = new_bounds; Browser* browser = new Browser(create_params); is_dragging_new_browser_ = true;
diff --git a/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc b/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc index ebfe232..244c71de 100644 --- a/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc +++ b/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc
@@ -2015,7 +2015,7 @@ ->GetDisplayNearestWindow(second_root) .work_area(); work_area.Inset(20, 20, 20, 60); - Browser::CreateParams params(browser()->profile()); + Browser::CreateParams params(browser()->profile(), true); params.initial_show_state = ui::SHOW_STATE_NORMAL; params.initial_bounds = work_area; Browser* browser2 = new Browser(params);
diff --git a/chrome/browser/ui/views/toolbar/browser_actions_container_browsertest.cc b/chrome/browser/ui/views/toolbar/browser_actions_container_browsertest.cc index ceabb1c..4822be7 100644 --- a/chrome/browser/ui/views/toolbar/browser_actions_container_browsertest.cc +++ b/chrome/browser/ui/views/toolbar/browser_actions_container_browsertest.cc
@@ -153,7 +153,7 @@ browser_actions(); // Create a second browser. - Browser* second_browser = new Browser(Browser::CreateParams(profile())); + Browser* second_browser = new Browser(Browser::CreateParams(profile(), true)); BrowserActionsContainer* second = BrowserView::GetBrowserViewForBrowser(second_browser)->toolbar()-> browser_actions();
diff --git a/chrome/browser/ui/webui/chrome_web_contents_handler.cc b/chrome/browser/ui/webui/chrome_web_contents_handler.cc index 7f5fd4d08..419cc8b 100644 --- a/chrome/browser/ui/webui/chrome_web_contents_handler.cc +++ b/chrome/browser/ui/webui/chrome_web_contents_handler.cc
@@ -39,8 +39,12 @@ Browser* browser = chrome::FindTabbedBrowser(profile, false); const bool browser_created = !browser; - if (!browser) - browser = new Browser(Browser::CreateParams(Browser::TYPE_TABBED, profile)); + if (!browser) { + // TODO(erg): OpenURLParams should pass a user_gesture flag, pass it to + // CreateParams, and pass the real value to nav_params below. + browser = + new Browser(Browser::CreateParams(Browser::TYPE_TABBED, profile, true)); + } chrome::NavigateParams nav_params(browser, params.url, params.transition); nav_params.referrer = params.referrer; if (source && source->IsCrashed() && @@ -82,14 +86,16 @@ Browser* browser = chrome::FindTabbedBrowser(profile, false); const bool browser_created = !browser; - if (!browser) - browser = new Browser(Browser::CreateParams(Browser::TYPE_TABBED, profile)); + if (!browser) { + browser = new Browser( + Browser::CreateParams(Browser::TYPE_TABBED, profile, user_gesture)); + } chrome::NavigateParams params(browser, new_contents); params.source_contents = source; params.disposition = disposition; params.window_bounds = initial_rect; params.window_action = chrome::NavigateParams::SHOW_WINDOW; - params.user_gesture = true; + params.user_gesture = user_gesture; chrome::Navigate(¶ms); // Close the browser if chrome::Navigate created a new one.
diff --git a/chrome/browser/ui/webui/chromeos/login/app_launch_splash_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/app_launch_splash_screen_handler.cc index bf074962..5dcdd4fc 100644 --- a/chrome/browser/ui/webui/chromeos/login/app_launch_splash_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/app_launch_splash_screen_handler.cc
@@ -39,9 +39,9 @@ AppLaunchSplashScreenHandler::AppLaunchSplashScreenHandler( const scoped_refptr<NetworkStateInformer>& network_state_informer, ErrorScreen* error_screen) - : BaseScreenHandler(kJsScreenPath), - network_state_informer_(network_state_informer), + : network_state_informer_(network_state_informer), error_screen_(error_screen) { + set_call_js_prefix(kJsScreenPath); network_state_informer_->AddObserver(this); }
diff --git a/chrome/browser/ui/webui/chromeos/login/arc_kiosk_splash_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/arc_kiosk_splash_screen_handler.cc index eca3ab8..6533113 100644 --- a/chrome/browser/ui/webui/chromeos/login/arc_kiosk_splash_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/arc_kiosk_splash_screen_handler.cc
@@ -24,8 +24,9 @@ namespace chromeos { -ArcKioskSplashScreenHandler::ArcKioskSplashScreenHandler() - : BaseScreenHandler(kJsScreenPath) {} +ArcKioskSplashScreenHandler::ArcKioskSplashScreenHandler() { + set_call_js_prefix(kJsScreenPath); +} ArcKioskSplashScreenHandler::~ArcKioskSplashScreenHandler() = default;
diff --git a/chrome/browser/ui/webui/chromeos/login/arc_terms_of_service_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/arc_terms_of_service_screen_handler.cc index 7e0c9a7..0c149ae 100644 --- a/chrome/browser/ui/webui/chromeos/login/arc_terms_of_service_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/arc_terms_of_service_screen_handler.cc
@@ -26,8 +26,8 @@ namespace chromeos { -ArcTermsOfServiceScreenHandler::ArcTermsOfServiceScreenHandler() - : BaseScreenHandler(kJsScreenPath) { +ArcTermsOfServiceScreenHandler::ArcTermsOfServiceScreenHandler() { + set_call_js_prefix(kJsScreenPath); } ArcTermsOfServiceScreenHandler::~ArcTermsOfServiceScreenHandler() {
diff --git a/chrome/browser/ui/webui/chromeos/login/auto_enrollment_check_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/auto_enrollment_check_screen_handler.cc index e100f8e..9bcf4f2 100644 --- a/chrome/browser/ui/webui/chromeos/login/auto_enrollment_check_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/auto_enrollment_check_screen_handler.cc
@@ -16,10 +16,8 @@ namespace chromeos { -AutoEnrollmentCheckScreenHandler::AutoEnrollmentCheckScreenHandler() - : BaseScreenHandler(kJsScreenPath), - delegate_(NULL), - show_on_init_(false) { +AutoEnrollmentCheckScreenHandler::AutoEnrollmentCheckScreenHandler() { + set_call_js_prefix(kJsScreenPath); } AutoEnrollmentCheckScreenHandler::~AutoEnrollmentCheckScreenHandler() {
diff --git a/chrome/browser/ui/webui/chromeos/login/auto_enrollment_check_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/auto_enrollment_check_screen_handler.h index 4517e1b..db480ba 100644 --- a/chrome/browser/ui/webui/chromeos/login/auto_enrollment_check_screen_handler.h +++ b/chrome/browser/ui/webui/chromeos/login/auto_enrollment_check_screen_handler.h
@@ -33,10 +33,10 @@ void RegisterMessages() override; private: - Delegate* delegate_; + Delegate* delegate_ = nullptr; // Keeps whether screen should be shown right after initialization. - bool show_on_init_; + bool show_on_init_ = false; DISALLOW_COPY_AND_ASSIGN(AutoEnrollmentCheckScreenHandler); };
diff --git a/chrome/browser/ui/webui/chromeos/login/base_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/base_screen_handler.cc index 52b76a7..db8cd34 100644 --- a/chrome/browser/ui/webui/chromeos/login/base_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/base_screen_handler.cc
@@ -19,16 +19,7 @@ const char kMethodContextChanged[] = "contextChanged"; } // namespace -BaseScreenHandler::BaseScreenHandler() - : page_is_ready_(false), base_screen_(nullptr) { -} - -BaseScreenHandler::BaseScreenHandler(const std::string& js_screen_path) - : page_is_ready_(false), - base_screen_(nullptr), - js_screen_path_prefix_(js_screen_path + ".") { - CHECK(!js_screen_path.empty()); -} +BaseScreenHandler::BaseScreenHandler() = default; BaseScreenHandler::~BaseScreenHandler() { if (base_screen_)
diff --git a/chrome/browser/ui/webui/chromeos/login/base_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/base_screen_handler.h index 4c485f58..2e46198 100644 --- a/chrome/browser/ui/webui/chromeos/login/base_screen_handler.h +++ b/chrome/browser/ui/webui/chromeos/login/base_screen_handler.h
@@ -36,12 +36,7 @@ class BaseScreenHandler : public content::WebUIMessageHandler, public ModelViewChannel { public: - // C-tor used when JS screen prefix is not needed. BaseScreenHandler(); - - // C-tor used when JS screen prefix is needed. - explicit BaseScreenHandler(const std::string& js_screen_path); - ~BaseScreenHandler() override; // Gets localized strings to be used on the page. @@ -65,6 +60,13 @@ return async_assets_load_id_; } + // Set the prefix used when running CallJs with a method. For example, + // set_call_js_prefix("Oobe") + // CallJs("lock") -> Invokes JS global named "Oobe.lock" + void set_call_js_prefix(const std::string& prefix) { + js_screen_path_prefix_ = prefix + "."; + } + protected: // All subclasses should implement this method to provide localized values. virtual void DeclareLocalizedValues( @@ -178,9 +180,9 @@ void HandleContextChanged(const base::DictionaryValue* diff); // Keeps whether page is ready. - bool page_is_ready_; + bool page_is_ready_ = false; - BaseScreen* base_screen_; + BaseScreen* base_screen_ = nullptr; // Full name of the corresponding JS screen object. Can be empty, if // there are no corresponding screen object or several different
diff --git a/chrome/browser/ui/webui/chromeos/login/controller_pairing_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/controller_pairing_screen_handler.cc index 43c3b89c..4446044 100644 --- a/chrome/browser/ui/webui/chromeos/login/controller_pairing_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/controller_pairing_screen_handler.cc
@@ -30,8 +30,8 @@ } // namespace -ControllerPairingScreenHandler::ControllerPairingScreenHandler() - : BaseScreenHandler(kJsScreenPath), delegate_(NULL), show_on_init_(false) { +ControllerPairingScreenHandler::ControllerPairingScreenHandler() { + set_call_js_prefix(kJsScreenPath); } ControllerPairingScreenHandler::~ControllerPairingScreenHandler() {
diff --git a/chrome/browser/ui/webui/chromeos/login/controller_pairing_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/controller_pairing_screen_handler.h index ea1038ee..a2c3e8f 100644 --- a/chrome/browser/ui/webui/chromeos/login/controller_pairing_screen_handler.h +++ b/chrome/browser/ui/webui/chromeos/login/controller_pairing_screen_handler.h
@@ -36,8 +36,8 @@ void OnContextChanged(const base::DictionaryValue& diff) override; content::BrowserContext* GetBrowserContext() override; - ControllerPairingScreenActor::Delegate* delegate_; - bool show_on_init_; + ControllerPairingScreenActor::Delegate* delegate_ = nullptr; + bool show_on_init_ = false; DISALLOW_COPY_AND_ASSIGN(ControllerPairingScreenHandler); };
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 6f5f7d2..0d6cac5 100644 --- a/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc
@@ -56,9 +56,8 @@ // Note that show_oobe_ui_ defaults to false because WizardController assumes // OOBE UI is not visible by default. CoreOobeHandler::CoreOobeHandler(OobeUI* oobe_ui) - : BaseScreenHandler(kJsScreenPath), - oobe_ui_(oobe_ui), - version_info_updater_(this) { + : oobe_ui_(oobe_ui), version_info_updater_(this) { + set_call_js_prefix(kJsScreenPath); if (!chrome::IsRunningInMash()) { AccessibilityManager* accessibility_manager = AccessibilityManager::Get(); CHECK(accessibility_manager);
diff --git a/chrome/browser/ui/webui/chromeos/login/device_disabled_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/device_disabled_screen_handler.cc index 2bd4bf4..2062b454 100644 --- a/chrome/browser/ui/webui/chromeos/login/device_disabled_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/device_disabled_screen_handler.cc
@@ -17,10 +17,8 @@ namespace chromeos { -DeviceDisabledScreenHandler::DeviceDisabledScreenHandler() - : BaseScreenHandler(kJsScreenPath), - delegate_(NULL), - show_on_init_(false) { +DeviceDisabledScreenHandler::DeviceDisabledScreenHandler() { + set_call_js_prefix(kJsScreenPath); } DeviceDisabledScreenHandler::~DeviceDisabledScreenHandler() {
diff --git a/chrome/browser/ui/webui/chromeos/login/device_disabled_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/device_disabled_screen_handler.h index f69d0af..5aebbed 100644 --- a/chrome/browser/ui/webui/chromeos/login/device_disabled_screen_handler.h +++ b/chrome/browser/ui/webui/chromeos/login/device_disabled_screen_handler.h
@@ -33,10 +33,10 @@ // WebUIMessageHandler: void RegisterMessages() override; - Delegate* delegate_; + Delegate* delegate_ = nullptr; // Indicates whether the screen should be shown right after initialization. - bool show_on_init_; + bool show_on_init_ = false; DISALLOW_COPY_AND_ASSIGN(DeviceDisabledScreenHandler); };
diff --git a/chrome/browser/ui/webui/chromeos/login/enable_debugging_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/enable_debugging_screen_handler.cc index 6b37f0aa..da2f76f 100644 --- a/chrome/browser/ui/webui/chromeos/login/enable_debugging_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/enable_debugging_screen_handler.cc
@@ -35,10 +35,8 @@ namespace chromeos { EnableDebuggingScreenHandler::EnableDebuggingScreenHandler() - : BaseScreenHandler(kJsScreenPath), - delegate_(NULL), - show_on_init_(false), - weak_ptr_factory_(this) { + : weak_ptr_factory_(this) { + set_call_js_prefix(kJsScreenPath); } EnableDebuggingScreenHandler::~EnableDebuggingScreenHandler() {
diff --git a/chrome/browser/ui/webui/chromeos/login/enable_debugging_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/enable_debugging_screen_handler.h index da45fc5f..51a87da 100644 --- a/chrome/browser/ui/webui/chromeos/login/enable_debugging_screen_handler.h +++ b/chrome/browser/ui/webui/chromeos/login/enable_debugging_screen_handler.h
@@ -76,10 +76,10 @@ // Updates UI state. void UpdateUIState(UIState state); - Delegate* delegate_; + Delegate* delegate_ = nullptr; // Keeps whether screen should be shown right after initialization. - bool show_on_init_; + bool show_on_init_ = false; base::WeakPtrFactory<EnableDebuggingScreenHandler> weak_ptr_factory_;
diff --git a/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.cc index 17e6e0e..00ae028 100644 --- a/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.cc
@@ -123,11 +123,11 @@ EnrollmentScreenHandler::EnrollmentScreenHandler( const scoped_refptr<NetworkStateInformer>& network_state_informer, ErrorScreen* error_screen) - : BaseScreenHandler(kJsScreenPath), - network_state_informer_(network_state_informer), + : network_state_informer_(network_state_informer), error_screen_(error_screen), histogram_helper_(new ErrorScreensHistogramHelper("Enrollment")), weak_ptr_factory_(this) { + set_call_js_prefix(kJsScreenPath); set_async_assets_load_id( GetOobeScreenName(OobeScreen::SCREEN_OOBE_ENROLLMENT)); DCHECK(network_state_informer_.get());
diff --git a/chrome/browser/ui/webui/chromeos/login/error_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/error_screen_handler.cc index f8b7e674..5f0d589 100644 --- a/chrome/browser/ui/webui/chromeos/login/error_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/error_screen_handler.cc
@@ -21,9 +21,8 @@ namespace chromeos { -ErrorScreenHandler::ErrorScreenHandler() - : BaseScreenHandler(kJsScreenPath), - weak_ptr_factory_(this) { +ErrorScreenHandler::ErrorScreenHandler() : weak_ptr_factory_(this) { + set_call_js_prefix(kJsScreenPath); } ErrorScreenHandler::~ErrorScreenHandler() {
diff --git a/chrome/browser/ui/webui/chromeos/login/eula_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/eula_screen_handler.cc index 7f15ab01..d8bcff6 100644 --- a/chrome/browser/ui/webui/chromeos/login/eula_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/eula_screen_handler.cc
@@ -83,8 +83,8 @@ namespace chromeos { EulaScreenHandler::EulaScreenHandler(CoreOobeActor* core_oobe_actor) - : BaseScreenHandler(kJsScreenPath), - core_oobe_actor_(core_oobe_actor) { + : core_oobe_actor_(core_oobe_actor) { + set_call_js_prefix(kJsScreenPath); } EulaScreenHandler::~EulaScreenHandler() {
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 2304809..4fadb2b 100644 --- a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc
@@ -228,11 +228,11 @@ GaiaScreenHandler::GaiaScreenHandler( CoreOobeActor* core_oobe_actor, const scoped_refptr<NetworkStateInformer>& network_state_informer) - : BaseScreenHandler(kJsScreenPath), - network_state_informer_(network_state_informer), + : network_state_informer_(network_state_informer), core_oobe_actor_(core_oobe_actor), weak_factory_(this) { DCHECK(network_state_informer_.get()); + set_call_js_prefix(kJsScreenPath); } GaiaScreenHandler::~GaiaScreenHandler() {
diff --git a/chrome/browser/ui/webui/chromeos/login/hid_detection_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/hid_detection_screen_handler.cc index 66faf84d..b6d5803 100644 --- a/chrome/browser/ui/webui/chromeos/login/hid_detection_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/hid_detection_screen_handler.cc
@@ -30,7 +30,9 @@ HIDDetectionScreenHandler::HIDDetectionScreenHandler( CoreOobeActor* core_oobe_actor) - : BaseScreenHandler(kJsScreenPath), core_oobe_actor_(core_oobe_actor) {} + : core_oobe_actor_(core_oobe_actor) { + set_call_js_prefix(kJsScreenPath); +} HIDDetectionScreenHandler::~HIDDetectionScreenHandler() { if (screen_)
diff --git a/chrome/browser/ui/webui/chromeos/login/host_pairing_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/host_pairing_screen_handler.cc index 30acb8e..420d76a 100644 --- a/chrome/browser/ui/webui/chromeos/login/host_pairing_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/host_pairing_screen_handler.cc
@@ -26,11 +26,8 @@ } // namespace -HostPairingScreenHandler::HostPairingScreenHandler() - : BaseScreenHandler(kJsScreenPath), - delegate_(NULL), - show_on_init_(false), - js_context_ready_(false) { +HostPairingScreenHandler::HostPairingScreenHandler() { + set_call_js_prefix(kJsScreenPath); } HostPairingScreenHandler::~HostPairingScreenHandler() {
diff --git a/chrome/browser/ui/webui/chromeos/login/host_pairing_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/host_pairing_screen_handler.h index cfe7d111..26df3e4 100644 --- a/chrome/browser/ui/webui/chromeos/login/host_pairing_screen_handler.h +++ b/chrome/browser/ui/webui/chromeos/login/host_pairing_screen_handler.h
@@ -35,9 +35,9 @@ void SetDelegate(Delegate* delegate) override; void OnContextChanged(const base::DictionaryValue& diff) override; - HostPairingScreenActor::Delegate* delegate_; - bool show_on_init_; - bool js_context_ready_; + HostPairingScreenActor::Delegate* delegate_ = nullptr; + bool show_on_init_ = false; + bool js_context_ready_ = false; // Caches context changes while JS part is not ready to receive messages. ::login::ScreenContext context_cache_;
diff --git a/chrome/browser/ui/webui/chromeos/login/kiosk_autolaunch_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/kiosk_autolaunch_screen_handler.cc index 409dc18..d71d260 100644 --- a/chrome/browser/ui/webui/chromeos/login/kiosk_autolaunch_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/kiosk_autolaunch_screen_handler.cc
@@ -32,11 +32,8 @@ namespace chromeos { -KioskAutolaunchScreenHandler::KioskAutolaunchScreenHandler() - : BaseScreenHandler(kJsScreenPath), - delegate_(NULL), - show_on_init_(false), - is_visible_(false) { +KioskAutolaunchScreenHandler::KioskAutolaunchScreenHandler() { + set_call_js_prefix(kJsScreenPath); KioskAppManager::Get()->AddObserver(this); }
diff --git a/chrome/browser/ui/webui/chromeos/login/kiosk_autolaunch_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/kiosk_autolaunch_screen_handler.h index 01be4a23..3f1d51fd 100644 --- a/chrome/browser/ui/webui/chromeos/login/kiosk_autolaunch_screen_handler.h +++ b/chrome/browser/ui/webui/chromeos/login/kiosk_autolaunch_screen_handler.h
@@ -47,11 +47,11 @@ void HandleOnConfirm(); void HandleOnVisible(); - Delegate* delegate_; + Delegate* delegate_ = nullptr; // Keeps whether screen should be shown right after initialization. - bool show_on_init_; - bool is_visible_; + bool show_on_init_ = false; + bool is_visible_ = false; DISALLOW_COPY_AND_ASSIGN(KioskAutolaunchScreenHandler); };
diff --git a/chrome/browser/ui/webui/chromeos/login/kiosk_enable_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/kiosk_enable_screen_handler.cc index 81cbff3..2046082 100644 --- a/chrome/browser/ui/webui/chromeos/login/kiosk_enable_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/kiosk_enable_screen_handler.cc
@@ -24,12 +24,8 @@ namespace chromeos { -KioskEnableScreenHandler::KioskEnableScreenHandler() - : BaseScreenHandler(kJsScreenPath), - delegate_(NULL), - show_on_init_(false), - is_configurable_(false), - weak_ptr_factory_(this) { +KioskEnableScreenHandler::KioskEnableScreenHandler() : weak_ptr_factory_(this) { + set_call_js_prefix(kJsScreenPath); } KioskEnableScreenHandler::~KioskEnableScreenHandler() {
diff --git a/chrome/browser/ui/webui/chromeos/login/kiosk_enable_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/kiosk_enable_screen_handler.h index 5498785..9d1b9bb 100644 --- a/chrome/browser/ui/webui/chromeos/login/kiosk_enable_screen_handler.h +++ b/chrome/browser/ui/webui/chromeos/login/kiosk_enable_screen_handler.h
@@ -45,13 +45,13 @@ void OnGetConsumerKioskAutoLaunchStatus( KioskAppManager::ConsumerKioskAutoLaunchStatus status); - Delegate* delegate_; + Delegate* delegate_ = nullptr; // Keeps whether screen should be shown right after initialization. - bool show_on_init_; + bool show_on_init_ = false; // True if machine's consumer kiosk mode is in a configurable state. - bool is_configurable_; + bool is_configurable_ = false; base::WeakPtrFactory<KioskEnableScreenHandler> weak_ptr_factory_;
diff --git a/chrome/browser/ui/webui/chromeos/login/network_dropdown_handler.cc b/chrome/browser/ui/webui/chromeos/login/network_dropdown_handler.cc index 42b46c7c..fdfbf203 100644 --- a/chrome/browser/ui/webui/chromeos/login/network_dropdown_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/network_dropdown_handler.cc
@@ -30,8 +30,8 @@ namespace chromeos { -NetworkDropdownHandler::NetworkDropdownHandler() - : BaseScreenHandler(kJsScreenPath) { +NetworkDropdownHandler::NetworkDropdownHandler() { + set_call_js_prefix(kJsScreenPath); } NetworkDropdownHandler::~NetworkDropdownHandler() {
diff --git a/chrome/browser/ui/webui/chromeos/login/network_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/network_screen_handler.cc index 5d6e079..79f1ad63 100644 --- a/chrome/browser/ui/webui/chromeos/login/network_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/network_screen_handler.cc
@@ -55,7 +55,8 @@ // NetworkScreenHandler, public: ----------------------------------------------- NetworkScreenHandler::NetworkScreenHandler(CoreOobeActor* core_oobe_actor) - : BaseScreenHandler(kJsScreenPath), core_oobe_actor_(core_oobe_actor) { + : core_oobe_actor_(core_oobe_actor) { + set_call_js_prefix(kJsScreenPath); DCHECK(core_oobe_actor_); }
diff --git a/chrome/browser/ui/webui/chromeos/login/reset_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/reset_screen_handler.cc index bbd56c3..3906059 100644 --- a/chrome/browser/ui/webui/chromeos/login/reset_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/reset_screen_handler.cc
@@ -27,7 +27,9 @@ namespace chromeos { -ResetScreenHandler::ResetScreenHandler() : BaseScreenHandler(kJsScreenPath) {} +ResetScreenHandler::ResetScreenHandler() { + set_call_js_prefix(kJsScreenPath); +} ResetScreenHandler::~ResetScreenHandler() { if (screen_)
diff --git a/chrome/browser/ui/webui/chromeos/login/supervised_user_creation_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/supervised_user_creation_screen_handler.cc index d8b2768..fb5dfbd4 100644 --- a/chrome/browser/ui/webui/chromeos/login/supervised_user_creation_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/supervised_user_creation_screen_handler.cc
@@ -36,9 +36,8 @@ namespace chromeos { -SupervisedUserCreationScreenHandler::SupervisedUserCreationScreenHandler() - : BaseScreenHandler(kJsScreenPath), - delegate_(NULL) { +SupervisedUserCreationScreenHandler::SupervisedUserCreationScreenHandler() { + set_call_js_prefix(kJsScreenPath); ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); media::SoundsManager* manager = media::SoundsManager::Get(); manager->Initialize(SOUND_OBJECT_DELETE,
diff --git a/chrome/browser/ui/webui/chromeos/login/supervised_user_creation_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/supervised_user_creation_screen_handler.h index 313eb3f..345541c 100644 --- a/chrome/browser/ui/webui/chromeos/login/supervised_user_creation_screen_handler.h +++ b/chrome/browser/ui/webui/chromeos/login/supervised_user_creation_screen_handler.h
@@ -132,7 +132,7 @@ void UpdateText(const std::string& element_id, const base::string16& text); - Delegate* delegate_; + Delegate* delegate_ = nullptr; DISALLOW_COPY_AND_ASSIGN(SupervisedUserCreationScreenHandler); };
diff --git a/chrome/browser/ui/webui/chromeos/login/terms_of_service_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/terms_of_service_screen_handler.cc index 79f2b10..ef316de01 100644 --- a/chrome/browser/ui/webui/chromeos/login/terms_of_service_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/terms_of_service_screen_handler.cc
@@ -38,11 +38,8 @@ TermsOfServiceScreenHandler::TermsOfServiceScreenHandler( CoreOobeActor* core_oobe_actor) - : BaseScreenHandler(kJsScreenPath), - screen_(NULL), - core_oobe_actor_(core_oobe_actor), - show_on_init_(false), - load_error_(false) { + : core_oobe_actor_(core_oobe_actor) { + set_call_js_prefix(kJsScreenPath); } TermsOfServiceScreenHandler::~TermsOfServiceScreenHandler() {
diff --git a/chrome/browser/ui/webui/chromeos/login/terms_of_service_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/terms_of_service_screen_handler.h index adf55e37..88d1b47 100644 --- a/chrome/browser/ui/webui/chromeos/login/terms_of_service_screen_handler.h +++ b/chrome/browser/ui/webui/chromeos/login/terms_of_service_screen_handler.h
@@ -68,18 +68,18 @@ // and continue" button. void HandleAccept(); - TermsOfServiceScreenHandler::Delegate* screen_; + TermsOfServiceScreenHandler::Delegate* screen_ = nullptr; - CoreOobeActor* core_oobe_actor_; + CoreOobeActor* core_oobe_actor_ = nullptr; // Whether the screen should be shown right after initialization. - bool show_on_init_; + bool show_on_init_ = false; // The domain name whose Terms of Service are being shown. std::string domain_; // Set to |true| when the download of the Terms of Service fails. - bool load_error_; + bool load_error_ = false; // Set to the Terms of Service when the download is successful. std::string terms_of_service_;
diff --git a/chrome/browser/ui/webui/chromeos/login/update_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/update_screen_handler.cc index 955022e4..24be021c 100644 --- a/chrome/browser/ui/webui/chromeos/login/update_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/update_screen_handler.cc
@@ -21,7 +21,9 @@ namespace chromeos { -UpdateScreenHandler::UpdateScreenHandler() : BaseScreenHandler(kJsScreenPath) {} +UpdateScreenHandler::UpdateScreenHandler() { + set_call_js_prefix(kJsScreenPath); +} UpdateScreenHandler::~UpdateScreenHandler() { if (screen_)
diff --git a/chrome/browser/ui/webui/chromeos/login/user_image_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/user_image_screen_handler.cc index ad0dc0e75..c1d4841 100644 --- a/chrome/browser/ui/webui/chromeos/login/user_image_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/user_image_screen_handler.cc
@@ -38,8 +38,8 @@ namespace chromeos { -UserImageScreenHandler::UserImageScreenHandler() - : BaseScreenHandler(kJsScreenPath) { +UserImageScreenHandler::UserImageScreenHandler() { + set_call_js_prefix(kJsScreenPath); ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); media::SoundsManager* manager = media::SoundsManager::Get(); manager->Initialize(SOUND_OBJECT_DELETE,
diff --git a/chrome/browser/ui/webui/chromeos/login/wrong_hwid_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/wrong_hwid_screen_handler.cc index 38d82a1..7767ab9c 100644 --- a/chrome/browser/ui/webui/chromeos/login/wrong_hwid_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/wrong_hwid_screen_handler.cc
@@ -16,10 +16,8 @@ namespace chromeos { -WrongHWIDScreenHandler::WrongHWIDScreenHandler() - : BaseScreenHandler(kJsScreenPath), - delegate_(NULL), - show_on_init_(false) { +WrongHWIDScreenHandler::WrongHWIDScreenHandler() { + set_call_js_prefix(kJsScreenPath); } WrongHWIDScreenHandler::~WrongHWIDScreenHandler() {
diff --git a/chrome/browser/ui/webui/chromeos/login/wrong_hwid_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/wrong_hwid_screen_handler.h index 0865850..6dfdae54 100644 --- a/chrome/browser/ui/webui/chromeos/login/wrong_hwid_screen_handler.h +++ b/chrome/browser/ui/webui/chromeos/login/wrong_hwid_screen_handler.h
@@ -37,10 +37,10 @@ // JS messages handlers. void HandleOnSkip(); - Delegate* delegate_; + Delegate* delegate_ = nullptr; // Keeps whether screen should be shown right after initialization. - bool show_on_init_; + bool show_on_init_ = false; DISALLOW_COPY_AND_ASSIGN(WrongHWIDScreenHandler); };
diff --git a/chrome/browser/ui/webui/extensions/extension_loader_handler.cc b/chrome/browser/ui/webui/extensions/extension_loader_handler.cc index db2adde..88c7485 100644 --- a/chrome/browser/ui/webui/extensions/extension_loader_handler.cc +++ b/chrome/browser/ui/webui/extensions/extension_loader_handler.cc
@@ -14,12 +14,11 @@ #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" -#include "base/threading/sequenced_worker_pool.h" +#include "base/task_scheduler/post_task.h" #include "chrome/browser/extensions/path_util.h" #include "chrome/browser/extensions/unpacked_installer.h" #include "chrome/browser/profiles/profile.h" #include "chrome/grit/generated_resources.h" -#include "content/public/browser/browser_thread.h" #include "content/public/browser/navigation_handle.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_ui.h" @@ -160,15 +159,13 @@ // This will read the manifest and call AddFailure with the read manifest // contents. - base::PostTaskAndReplyWithResult( - content::BrowserThread::GetBlockingPool(), + base::PostTaskWithTraitsAndReplyWithResult( FROM_HERE, + base::TaskTraits().MayBlock().WithPriority( + base::TaskPriority::USER_BLOCKING), base::Bind(&ReadFileToString, file_path.Append(kManifestFilename)), base::Bind(&ExtensionLoaderHandler::AddFailure, - weak_ptr_factory_.GetWeakPtr(), - file_path, - error, - line)); + weak_ptr_factory_.GetWeakPtr(), file_path, error, line)); } void ExtensionLoaderHandler::DidStartNavigation(
diff --git a/chrome/browser/ui/webui/local_discovery/local_discovery_ui_browsertest.cc b/chrome/browser/ui/webui/local_discovery/local_discovery_ui_browsertest.cc index 2081f93..9971504 100644 --- a/chrome/browser/ui/webui/local_discovery/local_discovery_ui_browsertest.cc +++ b/chrome/browser/ui/webui/local_discovery/local_discovery_ui_browsertest.cc
@@ -447,6 +447,7 @@ command_line->AppendSwitchASCII(chromeos::switches::kLoginProfile, chrome::kTestUserProfileDir); #endif + command_line->AppendSwitch(switches::kDisableDeviceDiscoveryNotifications); WebUIBrowserTest::SetUpCommandLine(command_line); } @@ -516,7 +517,7 @@ } // Flaky: http://crbug.com/660669. -IN_PROC_BROWSER_TEST_F(LocalDiscoveryUITest, DISABLED_RegisterTest) { +IN_PROC_BROWSER_TEST_F(LocalDiscoveryUITest, RegisterTest) { TestMessageLoopCondition condition_token_claimed; ui_test_utils::NavigateToURL(browser(), GURL(
diff --git a/chrome/browser/ui/webui/options/autofill_options_handler.cc b/chrome/browser/ui/webui/options/autofill_options_handler.cc index 8b8044f..8241b38 100644 --- a/chrome/browser/ui/webui/options/autofill_options_handler.cc +++ b/chrome/browser/ui/webui/options/autofill_options_handler.cc
@@ -25,13 +25,13 @@ #include "chrome/browser/autofill/personal_data_manager_factory.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/autofill/country_combobox_model.h" #include "chrome/common/url_constants.h" #include "chrome/grit/chromium_strings.h" #include "chrome/grit/generated_resources.h" #include "components/autofill/core/browser/autofill_country.h" #include "components/autofill/core/browser/autofill_data_util.h" #include "components/autofill/core/browser/autofill_profile.h" +#include "components/autofill/core/browser/country_combobox_model.h" #include "components/autofill/core/browser/credit_card.h" #include "components/autofill/core/browser/payments/payments_service_url.h" #include "components/autofill/core/browser/personal_data_manager.h" @@ -168,9 +168,11 @@ // Sets data related to the country <select>. void SetCountryData(const PersonalDataManager& manager, - base::DictionaryValue* localized_strings) { + base::DictionaryValue* localized_strings, + const std::string& ui_language_code) { autofill::CountryComboboxModel model; - model.SetCountries(manager, base::Callback<bool(const std::string&)>()); + model.SetCountries(manager, base::Callback<bool(const std::string&)>(), + ui_language_code); const std::vector<std::unique_ptr<autofill::AutofillCountry>>& countries = model.countries(); localized_strings->SetString("defaultCountryCode", @@ -192,8 +194,7 @@ std::unique_ptr<base::ListValue> default_country_components( new base::ListValue); std::string default_country_language_code; - GetAddressComponents(countries.front()->country_code(), - g_browser_process->GetApplicationLocale(), + GetAddressComponents(countries.front()->country_code(), ui_language_code, default_country_components.get(), &default_country_language_code); localized_strings->Set("autofillDefaultCountryComponents", @@ -312,7 +313,8 @@ l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_PHONE)); localized_strings->SetString("autofillEmailLabel", l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_EMAIL)); - SetCountryData(*personal_data_, localized_strings); + SetCountryData(*personal_data_, localized_strings, + g_browser_process->GetApplicationLocale()); } void AutofillOptionsHandler::SetCreditCardOverlayStrings(
diff --git a/chrome/browser/ui/webui/options/sync_setup_handler.cc b/chrome/browser/ui/webui/options/sync_setup_handler.cc index d9f8054..c24a5fe 100644 --- a/chrome/browser/ui/webui/options/sync_setup_handler.cc +++ b/chrome/browser/ui/webui/options/sync_setup_handler.cc
@@ -363,8 +363,8 @@ bool force_new_tab = false; if (!browser) { // Settings is not displayed in a browser window. Open a new window. - browser = - new Browser(Browser::CreateParams(Browser::TYPE_TABBED, GetProfile())); + browser = new Browser( + Browser::CreateParams(Browser::TYPE_TABBED, GetProfile(), true)); force_new_tab = true; }
diff --git a/chrome/browser/ui/webui/settings/people_handler.cc b/chrome/browser/ui/webui/settings/people_handler.cc index b86c221e..823dd2b 100644 --- a/chrome/browser/ui/webui/settings/people_handler.cc +++ b/chrome/browser/ui/webui/settings/people_handler.cc
@@ -269,8 +269,8 @@ bool force_new_tab = false; if (!browser) { // Settings is not displayed in a browser window. Open a new window. - browser = - new Browser(Browser::CreateParams(Browser::TYPE_TABBED, profile_)); + browser = new Browser( + Browser::CreateParams(Browser::TYPE_TABBED, profile_, true)); force_new_tab = true; }
diff --git a/chrome/browser/ui/webui/signin/signin_supervised_user_import_handler.cc b/chrome/browser/ui/webui/signin/signin_supervised_user_import_handler.cc index 5cb3448..1a53687 100644 --- a/chrome/browser/ui/webui/signin/signin_supervised_user_import_handler.cc +++ b/chrome/browser/ui/webui/signin/signin_supervised_user_import_handler.cc
@@ -125,8 +125,8 @@ // it doesn't exist. Browser* browser = chrome::FindLastActiveWithProfile(last_used_profile); if (!browser) - browser = new Browser(Browser::CreateParams(Browser::TYPE_TABBED, - last_used_profile)); + browser = new Browser( + Browser::CreateParams(Browser::TYPE_TABBED, last_used_profile, true)); browser->OpenURL(params); } }
diff --git a/chrome/browser/ui/window_sizer/window_sizer_ash_unittest.cc b/chrome/browser/ui/window_sizer/window_sizer_ash_unittest.cc index ed672f45..09f8b85 100644 --- a/chrome/browser/ui/window_sizer/window_sizer_ash_unittest.cc +++ b/chrome/browser/ui/window_sizer/window_sizer_ash_unittest.cc
@@ -416,25 +416,25 @@ std::unique_ptr<TestingProfile> profile(new TestingProfile()); // Creating a popup handler here to make sure it does not interfere with the // existing windows. - Browser::CreateParams native_params(profile.get()); + Browser::CreateParams native_params(profile.get(), true); std::unique_ptr<Browser> browser( chrome::CreateBrowserWithTestWindowForParams(&native_params)); // Creating a popup handler here to make sure it does not interfere with the // existing windows. - Browser::CreateParams params2(profile.get()); + Browser::CreateParams params2(profile.get(), true); std::unique_ptr<Browser> browser2(CreateTestBrowser( CreateTestWindowInShellWithId(0), gfx::Rect(16, 32, 640, 320), ¶ms2)); BrowserWindow* browser_window = browser2->window(); // Creating a popup to make sure it does not interfere with the positioning. - Browser::CreateParams params_popup(Browser::TYPE_POPUP, profile.get()); + Browser::CreateParams params_popup(Browser::TYPE_POPUP, profile.get(), true); std::unique_ptr<Browser> browser_popup( CreateTestBrowser(CreateTestWindowInShellWithId(1), gfx::Rect(16, 32, 128, 256), ¶ms_popup)); // Creating a panel to make sure it does not interfere with the positioning. - Browser::CreateParams params_panel(Browser::TYPE_POPUP, profile.get()); + Browser::CreateParams params_panel(Browser::TYPE_POPUP, profile.get(), true); std::unique_ptr<Browser> browser_panel( CreateTestBrowser(CreateTestWindowInShellWithId(2), gfx::Rect(32, 48, 256, 512), ¶ms_panel)); @@ -482,7 +482,7 @@ TEST_F(WindowSizerAshTest, PlaceNewBrowserWindowOnEmptyDesktop) { // Create a browser to pass into the GetWindowBoundsAndShowState function. std::unique_ptr<TestingProfile> profile(new TestingProfile()); - Browser::CreateParams native_params(profile.get()); + Browser::CreateParams native_params(profile.get(), true); std::unique_ptr<Browser> browser( chrome::CreateBrowserWithTestWindowForParams(&native_params)); @@ -567,7 +567,7 @@ std::unique_ptr<TestingProfile> profile(new TestingProfile()); // Create browser windows that are used as reference. - Browser::CreateParams params(profile.get()); + Browser::CreateParams params(profile.get(), true); std::unique_ptr<Browser> browser(CreateTestBrowser( CreateTestWindowInShellWithId(0), gfx::Rect(10, 10, 200, 200), ¶ms)); BrowserWindow* browser_window = browser->window(); @@ -575,7 +575,7 @@ browser_window->Show(); EXPECT_EQ(native_window->GetRootWindow(), ash::Shell::GetTargetRootWindow()); - Browser::CreateParams another_params(profile.get()); + Browser::CreateParams another_params(profile.get(), true); std::unique_ptr<Browser> another_browser( CreateTestBrowser(CreateTestWindowInShellWithId(1), gfx::Rect(400, 10, 300, 300), &another_params)); @@ -585,7 +585,7 @@ another_browser_window->Show(); // Creating a new window to verify the new placement. - Browser::CreateParams new_params(profile.get()); + Browser::CreateParams new_params(profile.get(), true); std::unique_ptr<Browser> new_browser(CreateTestBrowser( CreateTestWindowInShellWithId(0), gfx::Rect(), &new_params)); @@ -654,12 +654,12 @@ std::unique_ptr<TestingProfile> profile(new TestingProfile()); // Creating a browser & window to play with. - Browser::CreateParams params(Browser::TYPE_TABBED, profile.get()); + Browser::CreateParams params(Browser::TYPE_TABBED, profile.get(), true); std::unique_ptr<Browser> browser(CreateTestBrowser( CreateTestWindowInShellWithId(0), gfx::Rect(16, 32, 640, 320), ¶ms)); // Create also a popup browser since that behaves different. - Browser::CreateParams params_popup(Browser::TYPE_POPUP, profile.get()); + Browser::CreateParams params_popup(Browser::TYPE_POPUP, profile.get(), true); std::unique_ptr<Browser> browser_popup( CreateTestBrowser(CreateTestWindowInShellWithId(1), gfx::Rect(16, 32, 640, 320), ¶ms_popup)); @@ -691,7 +691,7 @@ // Now create a top level window and check again for both. Only the tabbed // window should follow the top level window's state. // Creating a browser & window to play with. - Browser::CreateParams params2(Browser::TYPE_TABBED, profile.get()); + Browser::CreateParams params2(Browser::TYPE_TABBED, profile.get(), true); std::unique_ptr<Browser> browser2(CreateTestBrowser( CreateTestWindowInShellWithId(3), gfx::Rect(16, 32, 640, 320), ¶ms2)); @@ -727,13 +727,13 @@ // Creating a browser & window to play with. std::unique_ptr<TestingProfile> profile(new TestingProfile()); - Browser::CreateParams params(Browser::TYPE_TABBED, profile.get()); + Browser::CreateParams params(Browser::TYPE_TABBED, profile.get(), true); std::unique_ptr<Browser> browser(CreateTestBrowser( CreateTestWindowInShellWithId(0), gfx::Rect(16, 32, 640, 320), ¶ms)); // Create also a popup browser since that behaves slightly different for // defaults. - Browser::CreateParams params_popup(Browser::TYPE_POPUP, profile.get()); + Browser::CreateParams params_popup(Browser::TYPE_POPUP, profile.get(), true); std::unique_ptr<Browser> browser_popup( CreateTestBrowser(CreateTestWindowInShellWithId(1), gfx::Rect(16, 32, 128, 256), ¶ms_popup)); @@ -784,7 +784,7 @@ TEST_F(WindowSizerAshTest, DefaultStateBecomesMaximized) { // Create a browser to pass into the GetWindowBounds function. std::unique_ptr<TestingProfile> profile(new TestingProfile()); - Browser::CreateParams native_params(profile.get()); + Browser::CreateParams native_params(profile.get(), true); std::unique_ptr<Browser> browser( chrome::CreateBrowserWithTestWindowForParams(&native_params)); @@ -850,7 +850,7 @@ TEST_F(WindowSizerAshTest, TrustedPopupBehavior) { std::unique_ptr<TestingProfile> profile(new TestingProfile()); Browser::CreateParams trusted_popup_create_params(Browser::TYPE_POPUP, - profile.get()); + profile.get(), true); trusted_popup_create_params.trusted_source = true; std::unique_ptr<Browser> trusted_popup(CreateTestBrowser(
diff --git a/chrome/common/crash_keys.cc b/chrome/common/crash_keys.cc index 937dee5..f370fd87 100644 --- a/chrome/common/crash_keys.cc +++ b/chrome/common/crash_keys.cc
@@ -50,8 +50,6 @@ #endif #if defined(OS_WIN) -const char kHungAudioThreadDetails[] = "hung-audio-thread-details"; - const char kHungRendererOutstandingAckCount[] = "hung-outstanding-acks"; const char kHungRendererOutstandingEventType[] = "hung-outstanding-event-type"; const char kHungRendererLastEventType[] = "hung-last-event-type"; @@ -177,9 +175,6 @@ { kViewCount, kSmallSize }, // media/: -#if defined(OS_WIN) - { kHungAudioThreadDetails, kSmallSize }, -#endif { kZeroEncodeDetails, kSmallSize }, // gin/:
diff --git a/chrome/common/extensions/api/chromeos_info_private.json b/chrome/common/extensions/api/chromeos_info_private.json index 55d86a71..c084542 100644 --- a/chrome/common/extensions/api/chromeos_info_private.json +++ b/chrome/common/extensions/api/chromeos_info_private.json
@@ -40,6 +40,12 @@ "type": "string", "enum": ["not available", "available", "enabled"], "description": "Status of the play store. Note: 'available' means that the device supports the playstore but it is not enabled." + }, + { + "id": "ManagedDeviceStatus", + "type": "string", + "enum": ["managed", "not managed"], + "description": "Status of enterprise enrollment." } ], "functions": [ @@ -71,6 +77,7 @@ "isOwner" : {"type": "boolean", "optional": true, "description": "True if current logged in user is device owner"}, "sessionType": {"$ref": "SessionType", "optional": true}, "playStoreStatus": {"$ref": "PlayStoreStatus", "optional": true}, + "managedDeviceStatus": {"$ref": "ManagedDeviceStatus", "optional": true}, "clientId" : {"type": "string", "optional": true, "description": "Device client id"}, "timezone" : {"type": "string", "optional": true, "description": "Timezone"}, "a11yLargeCursorEnabled" : {"type": "boolean", "optional": true, "description": "If true, ChromeOS is showing enlarged cursor."},
diff --git a/chrome/common/extensions/api/commands/commands_handler.cc b/chrome/common/extensions/api/commands/commands_handler.cc index 818e6041..b9c7d794 100644 --- a/chrome/common/extensions/api/commands/commands_handler.cc +++ b/chrome/common/extensions/api/commands/commands_handler.cc
@@ -64,8 +64,7 @@ if (!extension->manifest()->HasKey(keys::kCommands)) { std::unique_ptr<CommandsInfo> commands_info(new CommandsInfo); MaybeSetBrowserActionDefault(extension, commands_info.get()); - extension->SetManifestData(keys::kCommands, - commands_info.release()); + extension->SetManifestData(keys::kCommands, std::move(commands_info)); return true; } @@ -126,8 +125,7 @@ MaybeSetBrowserActionDefault(extension, commands_info.get()); - extension->SetManifestData(keys::kCommands, - commands_info.release()); + extension->SetManifestData(keys::kCommands, std::move(commands_info)); return true; }
diff --git a/chrome/common/extensions/api/extension_action/action_info.cc b/chrome/common/extensions/api/extension_action/action_info.cc index 767eb6e..aa8376b0 100644 --- a/chrome/common/extensions/api/extension_action/action_info.cc +++ b/chrome/common/extensions/api/extension_action/action_info.cc
@@ -6,6 +6,7 @@ #include <memory> +#include "base/memory/ptr_util.h" #include "base/strings/utf_string_conversions.h" #include "chrome/common/extensions/api/commands/commands_handler.h" #include "extensions/common/constants.h" @@ -198,19 +199,20 @@ // static void ActionInfo::SetBrowserActionInfo(Extension* extension, ActionInfo* info) { extension->SetManifestData(keys::kBrowserAction, - new ActionInfoData(info)); + base::MakeUnique<ActionInfoData>(info)); } // static void ActionInfo::SetPageActionInfo(Extension* extension, ActionInfo* info) { extension->SetManifestData(keys::kPageAction, - new ActionInfoData(info)); + base::MakeUnique<ActionInfoData>(info)); } // static void ActionInfo::SetSystemIndicatorInfo(Extension* extension, ActionInfo* info) { - extension->SetManifestData(keys::kSystemIndicator, new ActionInfoData(info)); + extension->SetManifestData(keys::kSystemIndicator, + base::MakeUnique<ActionInfoData>(info)); } // static
diff --git a/chrome/common/extensions/api/file_browser_handlers/file_browser_handler.cc b/chrome/common/extensions/api/file_browser_handlers/file_browser_handler.cc index d41a9ee..c30b117a 100644 --- a/chrome/common/extensions/api/file_browser_handlers/file_browser_handler.cc +++ b/chrome/common/extensions/api/file_browser_handlers/file_browser_handler.cc
@@ -299,7 +299,7 @@ return false; // Failed to parse file browser actions definition. } - extension->SetManifestData(keys::kFileBrowserHandlers, info.release()); + extension->SetManifestData(keys::kFileBrowserHandlers, std::move(info)); return true; }
diff --git a/chrome/common/extensions/api/file_system_provider_capabilities/file_system_provider_capabilities_handler.cc b/chrome/common/extensions/api/file_system_provider_capabilities/file_system_provider_capabilities_handler.cc index ce676d40..2416f9975 100644 --- a/chrome/common/extensions/api/file_system_provider_capabilities/file_system_provider_capabilities_handler.cc +++ b/chrome/common/extensions/api/file_system_provider_capabilities/file_system_provider_capabilities_handler.cc
@@ -113,7 +113,7 @@ source)); extension->SetManifestData(manifest_keys::kFileSystemProviderCapabilities, - capabilities.release()); + std::move(capabilities)); return true; }
diff --git a/chrome/common/extensions/api/input_ime/input_components_handler.cc b/chrome/common/extensions/api/input_ime/input_components_handler.cc index 036a253..89b4d61f 100644 --- a/chrome/common/extensions/api/input_ime/input_components_handler.cc +++ b/chrome/common/extensions/api/input_ime/input_components_handler.cc
@@ -232,7 +232,7 @@ info->input_components.back().options_page_url = options_page_url; info->input_components.back().input_view_url = input_view_url; } - extension->SetManifestData(keys::kInputComponents, info.release()); + extension->SetManifestData(keys::kInputComponents, std::move(info)); return true; }
diff --git a/chrome/common/extensions/api/omnibox/omnibox_handler.cc b/chrome/common/extensions/api/omnibox/omnibox_handler.cc index 872ea125..f0d392d 100644 --- a/chrome/common/extensions/api/omnibox/omnibox_handler.cc +++ b/chrome/common/extensions/api/omnibox/omnibox_handler.cc
@@ -45,7 +45,7 @@ *error = base::ASCIIToUTF16(manifest_errors::kInvalidOmniboxKeyword); return false; } - extension->SetManifestData(manifest_keys::kOmnibox, info.release()); + extension->SetManifestData(manifest_keys::kOmnibox, std::move(info)); return true; }
diff --git a/chrome/common/extensions/api/plugins/plugins_handler.cc b/chrome/common/extensions/api/plugins/plugins_handler.cc index f88cbe9..dedf995 100644 --- a/chrome/common/extensions/api/plugins/plugins_handler.cc +++ b/chrome/common/extensions/api/plugins/plugins_handler.cc
@@ -113,7 +113,7 @@ } if (!plugins_data->plugins.empty()) { - extension->SetManifestData(keys::kPlugins, plugins_data.release()); + extension->SetManifestData(keys::kPlugins, std::move(plugins_data)); PermissionsParser::AddAPIPermission(extension, APIPermission::kPlugin); }
diff --git a/chrome/common/extensions/api/speech/tts_engine_manifest_handler.cc b/chrome/common/extensions/api/speech/tts_engine_manifest_handler.cc index ccc891be2..7ee2968 100644 --- a/chrome/common/extensions/api/speech/tts_engine_manifest_handler.cc +++ b/chrome/common/extensions/api/speech/tts_engine_manifest_handler.cc
@@ -145,7 +145,7 @@ info->voices.push_back(voice_data); } - extension->SetManifestData(keys::kTtsVoices, info.release()); + extension->SetManifestData(keys::kTtsVoices, std::move(info)); return true; }
diff --git a/chrome/common/extensions/api/spellcheck/spellcheck_handler.cc b/chrome/common/extensions/api/spellcheck/spellcheck_handler.cc index f7e7867e..0a903fe 100644 --- a/chrome/common/extensions/api/spellcheck/spellcheck_handler.cc +++ b/chrome/common/extensions/api/spellcheck/spellcheck_handler.cc
@@ -59,7 +59,7 @@ *error = base::ASCIIToUTF16(errors::kInvalidSpellcheckDictionaryPath); return false; } - extension->SetManifestData(keys::kSpellcheck, spellcheck_info.release()); + extension->SetManifestData(keys::kSpellcheck, std::move(spellcheck_info)); return true; }
diff --git a/chrome/common/extensions/api/url_handlers/url_handlers_parser.cc b/chrome/common/extensions/api/url_handlers/url_handlers_parser.cc index a5829a2..61dc4998 100644 --- a/chrome/common/extensions/api/url_handlers/url_handlers_parser.cc +++ b/chrome/common/extensions/api/url_handlers/url_handlers_parser.cc
@@ -159,7 +159,7 @@ } } - extension->SetManifestData(mkeys::kUrlHandlers, info.release()); + extension->SetManifestData(mkeys::kUrlHandlers, std::move(info)); return true; }
diff --git a/chrome/common/extensions/chrome_manifest_url_handlers.cc b/chrome/common/extensions/chrome_manifest_url_handlers.cc index 3d13dd9..96246f53 100644 --- a/chrome/common/extensions/chrome_manifest_url_handlers.cc +++ b/chrome/common/extensions/chrome_manifest_url_handlers.cc
@@ -77,7 +77,7 @@ return false; } manifest_url->url_ = extension->GetResourceURL(devtools_str); - extension->SetManifestData(keys::kDevToolsPage, manifest_url.release()); + extension->SetManifestData(keys::kDevToolsPage, std::move(manifest_url)); PermissionsParser::AddAPIPermission(extension, APIPermission::kDevtools); return true; } @@ -143,7 +143,7 @@ return false; } extension->SetManifestData(keys::kChromeURLOverrides, - url_overrides.release()); + std::move(url_overrides)); return true; }
diff --git a/chrome/common/extensions/manifest_handlers/app_icon_color_info.cc b/chrome/common/extensions/manifest_handlers/app_icon_color_info.cc index 26822b2..a03a5db 100644 --- a/chrome/common/extensions/manifest_handlers/app_icon_color_info.cc +++ b/chrome/common/extensions/manifest_handlers/app_icon_color_info.cc
@@ -75,7 +75,7 @@ } extension->SetManifestData(keys::kAppIconColor, - app_icon_color_info.release()); + std::move(app_icon_color_info)); return true; }
diff --git a/chrome/common/extensions/manifest_handlers/app_launch_info.cc b/chrome/common/extensions/manifest_handlers/app_launch_info.cc index 6ee7e34..8f1316f8 100644 --- a/chrome/common/extensions/manifest_handlers/app_launch_info.cc +++ b/chrome/common/extensions/manifest_handlers/app_launch_info.cc
@@ -305,7 +305,7 @@ std::unique_ptr<AppLaunchInfo> info(new AppLaunchInfo); if (!info->Parse(extension, error)) return false; - extension->SetManifestData(keys::kLaunch, info.release()); + extension->SetManifestData(keys::kLaunch, std::move(info)); return true; }
diff --git a/chrome/common/extensions/manifest_handlers/automation.cc b/chrome/common/extensions/manifest_handlers/automation.cc index c1f5a3ff..b8db260 100644 --- a/chrome/common/extensions/manifest_handlers/automation.cc +++ b/chrome/common/extensions/manifest_handlers/automation.cc
@@ -174,7 +174,7 @@ if (!info) return true; - extension->SetManifestData(keys::kAutomation, info.release()); + extension->SetManifestData(keys::kAutomation, std::move(info)); return true; }
diff --git a/chrome/common/extensions/manifest_handlers/content_scripts_handler.cc b/chrome/common/extensions/manifest_handlers/content_scripts_handler.cc index 8fa6823..affae04 100644 --- a/chrome/common/extensions/manifest_handlers/content_scripts_handler.cc +++ b/chrome/common/extensions/manifest_handlers/content_scripts_handler.cc
@@ -418,7 +418,7 @@ content_scripts_info->content_scripts.push_back(std::move(user_script)); } extension->SetManifestData(keys::kContentScripts, - content_scripts_info.release()); + std::move(content_scripts_info)); PermissionsParser::SetScriptableHosts( extension, ContentScriptsInfo::GetScriptableHosts(extension)); return true;
diff --git a/chrome/common/extensions/manifest_handlers/linked_app_icons.cc b/chrome/common/extensions/manifest_handlers/linked_app_icons.cc index b1f089c..5fcc5a7 100644 --- a/chrome/common/extensions/manifest_handlers/linked_app_icons.cc +++ b/chrome/common/extensions/manifest_handlers/linked_app_icons.cc
@@ -101,7 +101,8 @@ } } - extension->SetManifestData(keys::kLinkedAppIcons, linked_app_icons.release()); + extension->SetManifestData(keys::kLinkedAppIcons, + std::move(linked_app_icons)); return true; }
diff --git a/chrome/common/extensions/manifest_handlers/settings_overrides_handler.cc b/chrome/common/extensions/manifest_handlers/settings_overrides_handler.cc index 4f05e00..10c4a5c7 100644 --- a/chrome/common/extensions/manifest_handlers/settings_overrides_handler.cc +++ b/chrome/common/extensions/manifest_handlers/settings_overrides_handler.cc
@@ -174,8 +174,7 @@ PermissionsInfo::GetInstance()->GetByID(APIPermission::kHomepage), FormatUrlForDisplay(*(info->homepage)))); } - extension->SetManifestData(manifest_keys::kSettingsOverride, - info.release()); + extension->SetManifestData(manifest_keys::kSettingsOverride, std::move(info)); return true; }
diff --git a/chrome/common/extensions/manifest_handlers/theme_handler.cc b/chrome/common/extensions/manifest_handlers/theme_handler.cc index 99106c9..f4359117 100644 --- a/chrome/common/extensions/manifest_handlers/theme_handler.cc +++ b/chrome/common/extensions/manifest_handlers/theme_handler.cc
@@ -185,7 +185,7 @@ if (!LoadDisplayProperties(theme_value, error, theme_info.get())) return false; - extension->SetManifestData(keys::kTheme, theme_info.release()); + extension->SetManifestData(keys::kTheme, std::move(theme_info)); return true; }
diff --git a/chrome/common/extensions/manifest_handlers/ui_overrides_handler.cc b/chrome/common/extensions/manifest_handlers/ui_overrides_handler.cc index 7620516..4566738 100644 --- a/chrome/common/extensions/manifest_handlers/ui_overrides_handler.cc +++ b/chrome/common/extensions/manifest_handlers/ui_overrides_handler.cc
@@ -143,7 +143,7 @@ } info->manifest_permission.reset(new ManifestPermissionImpl( info->bookmarks_ui.get() != NULL)); - extension->SetManifestData(manifest_keys::kUIOverride, info.release()); + extension->SetManifestData(manifest_keys::kUIOverride, std::move(info)); return true; }
diff --git a/chrome/common/safe_browsing/csd.proto b/chrome/common/safe_browsing/csd.proto index 902ea1b..9e3b5e5b 100644 --- a/chrome/common/safe_browsing/csd.proto +++ b/chrome/common/safe_browsing/csd.proto
@@ -468,6 +468,9 @@ // An arbitrary token that should be sent along for further server requests. optional bytes token = 3; + + // Whether the server requests that this binary be uploaded. + optional bool upload = 5; } // The following protocol buffer holds the feedback report gathered
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 87875d24..356dd92 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -3792,7 +3792,6 @@ "../browser/lifetime/keep_alive_registry_unittest.cc", "../browser/renderer_context_menu/render_view_context_menu_test_util.cc", "../browser/renderer_context_menu/render_view_context_menu_test_util.h", - "../browser/ui/autofill/country_combobox_model_unittest.cc", "../browser/ui/autofill/save_card_bubble_controller_impl_unittest.cc", "../browser/ui/bluetooth/bluetooth_chooser_controller_unittest.cc", "../browser/ui/passwords/manage_passwords_ui_controller_unittest.cc",
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/contextmenu/ContextMenuUtils.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/contextmenu/ContextMenuUtils.java index 8ecb7ba..3df0201 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/contextmenu/ContextMenuUtils.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/contextmenu/ContextMenuUtils.java
@@ -43,22 +43,20 @@ /** * Opens a context menu. - * @param testCase The test harness. * @param tab The tab to open a context menu for. * @param openerDOMNodeId The DOM node to long press to open the context menu for. * @return The {@link ContextMenu} that was opened. * @throws InterruptedException * @throws TimeoutException */ - public static ContextMenu openContextMenu(ActivityInstrumentationTestCase2<?> testCase, - Tab tab, String openerDOMNodeId) throws InterruptedException, TimeoutException { + public static ContextMenu openContextMenu(Tab tab, String openerDOMNodeId) + throws InterruptedException, TimeoutException { String jsCode = "document.getElementById('" + openerDOMNodeId + "')"; - return openContextMenuByJs(testCase, tab, jsCode); + return openContextMenuByJs(tab, jsCode); } /** * Opens a context menu. - * @param testCase The test harness. * @param tab The tab to open a context menu for. * @param jsCode The javascript to get the DOM node to long press to * open the context menu for. @@ -66,8 +64,8 @@ * @throws InterruptedException * @throws TimeoutException */ - public static ContextMenu openContextMenuByJs(ActivityInstrumentationTestCase2<?> testCase, - Tab tab, String jsCode) throws InterruptedException, TimeoutException { + public static ContextMenu openContextMenuByJs(Tab tab, String jsCode) + throws InterruptedException, TimeoutException { final OnContextMenuShownHelper helper = new OnContextMenuShownHelper(); tab.addObserver(new EmptyTabObserver() { @Override @@ -77,7 +75,7 @@ } }); int callCount = helper.getCallCount(); - DOMUtils.longPressNodeByJs(testCase, tab.getContentViewCore(), jsCode); + DOMUtils.longPressNodeByJs(tab.getContentViewCore(), jsCode); helper.waitForCallback(callCount); return helper.getContextMenu(); @@ -112,7 +110,7 @@ public static void selectContextMenuItemByJs(ActivityInstrumentationTestCase2<?> testCase, Tab tab, String jsCode, final int itemId) throws InterruptedException, TimeoutException { - ContextMenu menu = openContextMenuByJs(testCase, tab, jsCode); + ContextMenu menu = openContextMenuByJs(tab, jsCode); Assert.assertNotNull("Failed to open context menu", menu); selectOpenContextMenuItem(testCase, menu, itemId); @@ -130,7 +128,7 @@ public static void selectContextMenuItemByTitle(ActivityInstrumentationTestCase2<?> testCase, Tab tab, String openerDOMNodeId, String itemTitle) throws InterruptedException, TimeoutException { - ContextMenu menu = openContextMenu(testCase, tab, openerDOMNodeId); + ContextMenu menu = openContextMenu(tab, openerDOMNodeId); Assert.assertNotNull("Failed to open context menu", menu); Integer itemId = null;
diff --git a/chrome/test/base/browser_with_test_window_test.cc b/chrome/test/base/browser_with_test_window_test.cc index 883b6ff7..08a9dd7 100644 --- a/chrome/test/base/browser_with_test_window_test.cc +++ b/chrome/test/base/browser_with_test_window_test.cc
@@ -198,10 +198,10 @@ Browser::Type browser_type, bool hosted_app, BrowserWindow* browser_window) { - Browser::CreateParams params(profile); + Browser::CreateParams params(profile, true); if (hosted_app) { params = Browser::CreateParams::CreateForApp( - "Test", true /* trusted_source */, gfx::Rect(), profile); + "Test", true /* trusted_source */, gfx::Rect(), profile, true); } else { params.type = browser_type; }
diff --git a/chrome/test/base/in_process_browser_test.cc b/chrome/test/base/in_process_browser_test.cc index 99651be2..11abd4407 100644 --- a/chrome/test/base/in_process_browser_test.cc +++ b/chrome/test/base/in_process_browser_test.cc
@@ -446,22 +446,22 @@ // Creates a browser with a single tab (about:blank), waits for the tab to // finish loading and shows the browser. Browser* InProcessBrowserTest::CreateBrowser(Profile* profile) { - Browser* browser = new Browser(Browser::CreateParams(profile)); + Browser* browser = new Browser(Browser::CreateParams(profile, true)); AddBlankTabAndShow(browser); return browser; } Browser* InProcessBrowserTest::CreateIncognitoBrowser() { // Create a new browser with using the incognito profile. - Browser* incognito = new Browser( - Browser::CreateParams(browser()->profile()->GetOffTheRecordProfile())); + Browser* incognito = new Browser(Browser::CreateParams( + browser()->profile()->GetOffTheRecordProfile(), true)); AddBlankTabAndShow(incognito); return incognito; } Browser* InProcessBrowserTest::CreateBrowserForPopup(Profile* profile) { Browser* browser = - new Browser(Browser::CreateParams(Browser::TYPE_POPUP, profile)); + new Browser(Browser::CreateParams(Browser::TYPE_POPUP, profile, true)); AddBlankTabAndShow(browser); return browser; } @@ -469,9 +469,8 @@ Browser* InProcessBrowserTest::CreateBrowserForApp( const std::string& app_name, Profile* profile) { - Browser* browser = new Browser( - Browser::CreateParams::CreateForApp( - app_name, false /* trusted_source */, gfx::Rect(), profile)); + Browser* browser = new Browser(Browser::CreateParams::CreateForApp( + app_name, false /* trusted_source */, gfx::Rect(), profile, true)); AddBlankTabAndShow(browser); return browser; }
diff --git a/chrome/test/base/in_process_browser_test_mac.cc b/chrome/test/base/in_process_browser_test_mac.cc index c25cc90b..85ccd74 100644 --- a/chrome/test/base/in_process_browser_test_mac.cc +++ b/chrome/test/base/in_process_browser_test_mac.cc
@@ -46,7 +46,7 @@ // autorelease pool. Flush the pool when this function returns. base::mac::ScopedNSAutoreleasePool pool; - Browser* browser = new Browser(Browser::CreateParams(profile)); + Browser* browser = new Browser(Browser::CreateParams(profile, true)); AddBlankTabAndShow(browser); return browser; } @@ -57,8 +57,8 @@ base::mac::ScopedNSAutoreleasePool pool; // Create a new browser with using the incognito profile. - Browser* incognito = new Browser( - Browser::CreateParams(browser()->profile()->GetOffTheRecordProfile())); + Browser* incognito = new Browser(Browser::CreateParams( + browser()->profile()->GetOffTheRecordProfile(), true)); AddBlankTabAndShow(incognito); return incognito; } @@ -69,7 +69,7 @@ base::mac::ScopedNSAutoreleasePool pool; Browser* browser = - new Browser(Browser::CreateParams(Browser::TYPE_POPUP, profile)); + new Browser(Browser::CreateParams(Browser::TYPE_POPUP, profile, true)); AddBlankTabAndShow(browser); return browser; } @@ -82,7 +82,7 @@ base::mac::ScopedNSAutoreleasePool pool; Browser* browser = new Browser(Browser::CreateParams::CreateForApp( - app_name, false /* trusted_source */, gfx::Rect(), profile)); + app_name, false /* trusted_source */, gfx::Rect(), profile, true)); AddBlankTabAndShow(browser); return browser; }
diff --git a/chrome/test/chromedriver/test/run_py_tests.py b/chrome/test/chromedriver/test/run_py_tests.py index 27c492c6..1adb0e2d 100755 --- a/chrome/test/chromedriver/test/run_py_tests.py +++ b/chrome/test/chromedriver/test/run_py_tests.py
@@ -83,6 +83,8 @@ # https://bugs.chromium.org/p/chromedriver/issues/detail?id=1673 'ChromeDownloadDirTest.testFileDownloadWithGet', 'ChromeDriverPageLoadTimeoutTest.*', + # https://bugs.chromium.org/p/chromedriver/issues/detail?id=1683 + 'ChromeDriverTest.testShadowDomClick', ] _VERSION_SPECIFIC_FILTER['57'] = [ # https://code.google.com/p/chromedriver/issues/detail?id=992
diff --git a/chrome/test/chromedriver/test/test_expectations b/chrome/test/chromedriver/test/test_expectations index 1e15157a..fb8da8e5 100644 --- a/chrome/test/chromedriver/test/test_expectations +++ b/chrome/test/chromedriver/test/test_expectations
@@ -147,15 +147,23 @@ ] _SPECIFIC_OS_REVISION_NEGATIVE_FILTER = {} -_SPECIFIC_OS_REVISION_NEGATIVE_FILTER['linux_53'] = [ - # Flaky on Linux32 against v53: - # https://bugs.chromium.org/p/chromedriver/issues/detail?id=1418 - 'ClickTest.testShouldOnlyFollowHrefOnce', - 'JavascriptEnabledDriverTest.*', - 'WindowSwitchingTest.testCanCloseWindowWhenMultipleWindowsAreOpen', - 'WindowSwitchingTest.testCanCallGetWindowHandlesAfterClosingAWindow', - 'WindowSwitchingTest.testCanCloseWindowAndSwitchBackToMainWindow', - 'XPathElementFindingTest.testShouldFindElementsByXPath', +_SPECIFIC_OS_REVISION_NEGATIVE_FILTER['linux_HEAD'] = [ + # https://bugs.chromium.org/p/chromedriver/issues/detail?id=1683 + 'ClickScrollingTest.testShouldBeAbleToClickElementInAFrameThatIsOutOfView', + 'ClickScrollingTest.testShouldBeAbleToClickElementThatIsOutOfViewInAFrameThatIsOutOfView', + 'ClickTest.testClickingLabelShouldSetCheckbox', + 'ElementFindingTest.testRemovingAnElementDynamicallyFromTheDomShouldCauseAStaleRefException', + 'FrameSwitchingTest.testShouldBeAbleToSwitchToTheTopIfTheFrameIsDeletedFromUnderUs', +] +_SPECIFIC_OS_REVISION_NEGATIVE_FILTER['win_HEAD'] = [ + # https://bugs.chromium.org/p/chromedriver/issues/detail?id=1683 + 'RenderedWebElementTest.testMoveRelativeToBody', + 'RenderedWebElementTest.testCanClickOnSuckerFishMenuItem', + 'BasicKeyboardInterfaceTest.testBasicKeyboardInput', +] +_SPECIFIC_OS_REVISION_NEGATIVE_FILTER['mac_HEAD'] = [ + # https://bugs.chromium.org/p/chromedriver/issues/detail?id=1683 + 'AlertsTest.testShouldHandleAlertOnPageLoad', ] _OS_NEGATIVE_FILTER['android:chrome'] = [
diff --git a/chrome/test/data/extensions/api_test/chromeos_info_private/basic/background.js b/chrome/test/data/extensions/api_test/chromeos_info_private/basic/background.js index f0808fc..60f4c82 100644 --- a/chrome/test/data/extensions/api_test/chromeos_info_private/basic/background.js +++ b/chrome/test/data/extensions/api_test/chromeos_info_private/basic/background.js
@@ -23,6 +23,9 @@ if (keys[i] == 'playStoreStatus') { chrome.test.assertEq('not available', values[keys[i]]); } + if (keys[i] == 'managedDeviceStatus') { + chrome.test.assertEq('not managed', values[keys[i]]); + } // Debug if (keys[i] in values) { console.log(' values["' + keys[i] + '"] = ' + @@ -117,6 +120,7 @@ 'isOwner', 'sessionType', 'playStoreStatus', + 'managedDeviceStatus', 'clientId', 'a11yLargeCursorEnabled', 'a11yStickyKeysEnabled',
diff --git a/chrome/test/data/extensions/api_test/chromeos_info_private/extended/background.js b/chrome/test/data/extensions/api_test/chromeos_info_private/extended/background.js index 9297957..b4e2c74 100644 --- a/chrome/test/data/extensions/api_test/chromeos_info_private/extended/background.js +++ b/chrome/test/data/extensions/api_test/chromeos_info_private/extended/background.js
@@ -9,18 +9,27 @@ chrome.test.fail("Missing test name."); return; } - chrome.chromeosInfoPrivate.get(['sessionType', 'playStoreStatus'], - function (values) { - if (testName == 'kiosk') { - chrome.test.assertEq('kiosk', values['sessionType']); - } else if (testName == 'arc not-available') { - chrome.test.assertEq('not available', values['playStoreStatus']); - } else if (testName == 'arc available') { - chrome.test.assertEq('available', values['playStoreStatus']); - } else if (testName == 'arc enabled') { - chrome.test.assertEq('enabled', values['playStoreStatus']); - } - chrome.test.succeed(); - }); + chrome.chromeosInfoPrivate.get([ + 'sessionType', + 'playStoreStatus', + 'managedDeviceStatus' + ], chrome.test.callbackPass(function(values) { + switch (testName) { + case 'kiosk': + chrome.test.assertEq('kiosk', values['sessionType']); + break; + case 'arc not-available': + chrome.test.assertEq('not available', values['playStoreStatus']); + break; + case 'arc available': + chrome.test.assertEq('available', values['playStoreStatus']); + break; + case 'arc enabled': + chrome.test.assertEq('enabled', values['playStoreStatus']); + break; + case 'managed': + chrome.test.assertEq('managed', values['managedDeviceStatus']); + } + })); }); });
diff --git a/chrome/test/data/webui/settings/settings_menu_test.js b/chrome/test/data/webui/settings/settings_menu_test.js index 3f5d5e6..9752927 100644 --- a/chrome/test/data/webui/settings/settings_menu_test.js +++ b/chrome/test/data/webui/settings/settings_menu_test.js
@@ -87,6 +87,30 @@ var path = new window.URL(selector.selected).pathname; assertEquals('/reset', path); }); + + test('navigateToAnotherSection', function() { + var selector = settingsMenu.$.subMenu; + var path = new window.URL(selector.selected).pathname; + assertEquals('/reset', path); + + settings.navigateTo(settings.Route.PEOPLE, ''); + Polymer.dom.flush(); + + path = new window.URL(selector.selected).pathname; + assertEquals('/people', path); + }); + + test('navigateToBasic', function() { + var selector = settingsMenu.$.subMenu; + var path = new window.URL(selector.selected).pathname; + assertEquals('/reset', path); + + settings.navigateTo(settings.Route.BASIC, ''); + Polymer.dom.flush(); + + // BASIC has no sub page selected. + assertFalse(!!selector.selected); + }); }); }
diff --git a/chrome/test/media_router/telemetry/benchmarks/media_router_benchmark.py b/chrome/test/media_router/telemetry/benchmarks/media_router_benchmark.py index 04892f09..82ae9da 100644 --- a/chrome/test/media_router/telemetry/benchmarks/media_router_benchmark.py +++ b/chrome/test/media_router/telemetry/benchmarks/media_router_benchmark.py
@@ -80,7 +80,7 @@ class CPUMemoryCastBenckmark(_BaseCastBenchmark): """Benchmark for CPU and memory usage with Media Router.""" - options = {'page_repeat': 1} + options = {'pageset_repeat': 1} page_set = media_router_perf_pages.MediaRouterCPUMemoryPageSet @@ -95,7 +95,7 @@ class CPUMemoryBenckmark(perf_benchmark.PerfBenchmark): """Benchmark for CPU and memory usage without Media Router.""" - options = {'page_repeat': 1} + options = {'pageset_repeat': 1} page_set = media_router_perf_pages.CPUMemoryPageSet
diff --git a/chromecast/BUILD.gn b/chromecast/BUILD.gn index 6e0581f8..aff4184 100644 --- a/chromecast/BUILD.gn +++ b/chromecast/BUILD.gn
@@ -309,6 +309,10 @@ "//chromecast/app:test_support", "//chromecast/browser:browsertests", ] + + data_deps = [ + ":chromecast_locales_pak", + ] } group("cast_shell_lib") {
diff --git a/chromeos/BUILD.gn b/chromeos/BUILD.gn index cd535eb..9d4883c 100644 --- a/chromeos/BUILD.gn +++ b/chromeos/BUILD.gn
@@ -45,6 +45,7 @@ "//crypto", "//crypto:platform", "//google_apis", + "//media/base:video_facing", "//net", "//skia", # For components/user_manager "//third_party/icu",
diff --git a/chromeos/DEPS b/chromeos/DEPS index 512e62d..85d0d21 100644 --- a/chromeos/DEPS +++ b/chromeos/DEPS
@@ -10,6 +10,7 @@ "+components/signin/core/account_id/account_id.h", "+components/user_manager/known_user.h", "+crypto", + "+media/base/video_facing.h", "+net", "+third_party/cros_system_api", "+third_party/libxml",
diff --git a/chromeos/audio/cras_audio_handler.cc b/chromeos/audio/cras_audio_handler.cc index a6cd9f0..444eab6 100644 --- a/chromeos/audio/cras_audio_handler.cc +++ b/chromeos/audio/cras_audio_handler.cc
@@ -126,6 +126,14 @@ return g_cras_audio_handler; } +void CrasAudioHandler::OnVideoCaptureStarted(media::VideoFacingMode facing) { + // TODO(jennyz): Switch active audio device according to video facing. +} + +void CrasAudioHandler::OnVideoCaptureStopped(media::VideoFacingMode facing) { + // TODO(jennyz): Switch active audio device according to video facing. +} + void CrasAudioHandler::AddAudioObserver(AudioObserver* observer) { observers_.AddObserver(observer); }
diff --git a/chromeos/audio/cras_audio_handler.h b/chromeos/audio/cras_audio_handler.h index 1408f06..ac8a756 100644 --- a/chromeos/audio/cras_audio_handler.h +++ b/chromeos/audio/cras_audio_handler.h
@@ -21,6 +21,7 @@ #include "chromeos/dbus/cras_audio_client.h" #include "chromeos/dbus/session_manager_client.h" #include "chromeos/dbus/volume_state.h" +#include "media/base/video_facing.h" namespace chromeos { @@ -28,11 +29,12 @@ class CHROMEOS_EXPORT CrasAudioHandler : public CrasAudioClient::Observer, public AudioPrefObserver, - public SessionManagerClient::Observer { + public SessionManagerClient::Observer, + public media::VideoCaptureObserver { public: - typedef std::priority_queue<AudioDevice, - std::vector<AudioDevice>, - AudioDeviceCompare> AudioDevicePriorityQueue; + typedef std:: + priority_queue<AudioDevice, std::vector<AudioDevice>, AudioDeviceCompare> + AudioDevicePriorityQueue; typedef std::vector<uint64_t> NodeIdList; // Volume change reasons that are not user-initiated. @@ -103,6 +105,10 @@ // Gets the global instance. Initialize must be called first. static CrasAudioHandler* Get(); + // Overrides media::VideoCaptureObserver. + void OnVideoCaptureStarted(media::VideoFacingMode facing) override; + void OnVideoCaptureStopped(media::VideoFacingMode facing) override; + // Adds an audio observer. void AddAudioObserver(AudioObserver* observer);
diff --git a/chromeos/network/network_state_handler.cc b/chromeos/network/network_state_handler.cc index eaed6e9c..d8af06c 100644 --- a/chromeos/network/network_state_handler.cc +++ b/chromeos/network/network_state_handler.cc
@@ -7,6 +7,7 @@ #include <stddef.h> #include "base/bind.h" +#include "base/command_line.h" #include "base/format_macros.h" #include "base/guid.h" #include "base/json/json_string_value_serializer.h" @@ -19,6 +20,7 @@ #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "base/values.h" +#include "chromeos/chromeos_switches.h" #include "chromeos/network/device_state.h" #include "chromeos/network/network_event_log.h" #include "chromeos/network/network_state.h" @@ -122,6 +124,13 @@ NetworkStateHandler::TechnologyState NetworkStateHandler::GetTechnologyState( const NetworkTypePattern& type) const { std::string technology = GetTechnologyForType(type); + + if (technology == kTypeTether) { + bool is_tether_enabled = base::CommandLine::ForCurrentProcess()->HasSwitch( + chromeos::switches::kEnableTether); + return is_tether_enabled ? TECHNOLOGY_ENABLED : TECHNOLOGY_UNAVAILABLE; + } + TechnologyState state; if (shill_property_handler_->IsTechnologyEnabled(technology)) state = TECHNOLOGY_ENABLED; @@ -307,6 +316,20 @@ } } +void NetworkStateHandler::GetTetherNetworkList(int limit, + NetworkStateList* list) { + DCHECK(list); + list->clear(); + int count = 0; + + for (auto iter = tether_network_list_.begin(); + iter != tether_network_list_.end(); ++iter) { + list->push_back((*iter)->AsNetworkState()); + if (limit > 0 && ++count >= limit) + return; + } +} + const NetworkState* NetworkStateHandler::GetNetworkStateFromServicePath( const std::string& service_path, bool configured_only) const { @@ -343,9 +366,19 @@ return nullptr; } -const std::string NetworkStateHandler::CreateTetherNetworkState( - const std::string& name) { - const std::string& guid = base::GenerateGUID(); +void NetworkStateHandler::AddTetherNetworkState(const std::string& guid, + const std::string& name) { + DCHECK(!guid.empty()); + + // If the network already exists, do nothing. + for (auto iter = tether_network_list_.begin(); + iter != tether_network_list_.end(); ++iter) { + if (iter->get()->AsNetworkState()->guid() == guid) { + NET_LOG(ERROR) << "AddTetherNetworkState: " << name + << " called with existing guid:" << guid; + return; + } + } std::unique_ptr<NetworkState> tether_managed_state = base::MakeUnique<NetworkState>(base::GenerateGUID()); @@ -357,8 +390,6 @@ tether_network_list_.push_back(std::move(tether_managed_state)); NotifyNetworkListChanged(); - - return guid; } void NetworkStateHandler::RemoveTetherNetworkState(const std::string& guid) { @@ -1028,6 +1059,9 @@ if (type.MatchesType(shill::kTypeCellular)) return shill::kTypeCellular; + if (type.MatchesType(kTypeTether)) + return kTypeTether; + NOTREACHED(); return std::string(); }
diff --git a/chromeos/network/network_state_handler.h b/chromeos/network/network_state_handler.h index 99398bc..2866d3c 100644 --- a/chromeos/network/network_state_handler.h +++ b/chromeos/network/network_state_handler.h
@@ -91,7 +91,8 @@ const tracked_objects::Location& from_here); // Returns the state for technology |type|. Only - // NetworkTypePattern::Primitive, ::Mobile and ::Ethernet are supported. + // NetworkTypePattern::Primitive, ::Mobile, ::Ethernet, and ::Tether are + // supported. TechnologyState GetTechnologyState(const NetworkTypePattern& type) const; bool IsTechnologyAvailable(const NetworkTypePattern& type) const { return GetTechnologyState(type) != TECHNOLOGY_UNAVAILABLE; @@ -181,6 +182,15 @@ int limit, NetworkStateList* list); + // Sets |list| to contain the list of "tether" networks. If |limit| > 0, that + // will determine the number of results; pass 0 for no limit. The returned + // list contains a copy of NetworkState pointers which should not be stored or + // used beyond the scope of the calling function (i.e. they may later become + // invalid, but only on the UI thread). + // NOTE: See AddTetherNetworkState for more information about "tether" + // networks. + void GetTetherNetworkList(int limit, NetworkStateList* list); + // Finds and returns the NetworkState associated with |service_path| or NULL // if not found. If |configured_only| is true, only returns saved entries // (IsInProfile is true). @@ -194,14 +204,15 @@ // Creates a "tether" NetworkState that has no underlying shill type or // service. When initially created, it does not actually represent a real - // network. Generates and returns a guid to be used to refer to and fetch this - // NetworkState in the future. + // network. The |guid| provided must be non-empty. If a network with |guid| + // already exists, this method will do nothing. Use the provided |guid| to + // refer to and fetch this NetworkState in the future. // NOTE: only GetNetworkStateFromGuid is supported to fetch "tether" // NetworkStates. - const std::string CreateTetherNetworkState(const std::string& name); + void AddTetherNetworkState(const std::string& guid, const std::string& name); - // Remove a "tether" NetworkState, using the same guid that was returned by - // CreateTetherNetworkState. + // Remove a "tether" NetworkState, using the same |guid| passed to + // AddTetherNetworkState. void RemoveTetherNetworkState(const std::string& guid); // Sets |list| to contain the list of devices. The returned list contains
diff --git a/chromeos/network/network_state_handler_unittest.cc b/chromeos/network/network_state_handler_unittest.cc index 8f48ef2e..056f58e 100644 --- a/chromeos/network/network_state_handler_unittest.cc +++ b/chromeos/network/network_state_handler_unittest.cc
@@ -12,10 +12,12 @@ #include <string> #include "base/bind.h" +#include "base/command_line.h" #include "base/macros.h" #include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "base/values.h" +#include "chromeos/chromeos_switches.h" #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/shill_device_client.h" #include "chromeos/dbus/shill_ipconfig_client.h" @@ -45,7 +47,10 @@ const char kShillManagerClientStubWifi2[] = "/service/wifi2"; const char kShillManagerClientStubCellular[] = "/service/cellular1"; -const char kTetherName[] = "Device"; +const char kTetherGuid1[] = "tether1"; +const char kTetherGuid2[] = "tether2"; +const char kTetherName1[] = "Device1"; +const char kTetherName2[] = "Device2"; using chromeos::DeviceState; using chromeos::NetworkState; @@ -371,6 +376,30 @@ EXPECT_EQ(1u, networks.size()); } +TEST_F(NetworkStateHandlerTest, GetTetherNetworkList) { + NetworkStateHandler::NetworkStateList tether_networks; + + network_state_handler_->GetTetherNetworkList(0 /* no limit */, + &tether_networks); + EXPECT_EQ(0u, tether_networks.size()); + + network_state_handler_->AddTetherNetworkState(kTetherGuid1, kTetherName1); + + network_state_handler_->GetTetherNetworkList(0 /* no limit */, + &tether_networks); + EXPECT_EQ(1u, tether_networks.size()); + + network_state_handler_->AddTetherNetworkState(kTetherGuid2, kTetherName2); + + network_state_handler_->GetTetherNetworkList(0 /* no limit */, + &tether_networks); + EXPECT_EQ(2u, tether_networks.size()); + + network_state_handler_->GetTetherNetworkList(1 /* no limit */, + &tether_networks); + EXPECT_EQ(1u, tether_networks.size()); +} + TEST_F(NetworkStateHandlerTest, NetworkListChanged) { size_t stub_network_count = test_observer_->network_count(); // Set up two additional visible networks. @@ -497,6 +526,19 @@ network_state_handler_->GetTechnologyState(NetworkTypePattern::Wimax())); } +TEST_F(NetworkStateHandlerTest, TetherTechnologyState) { + EXPECT_EQ( + NetworkStateHandler::TECHNOLOGY_UNAVAILABLE, + network_state_handler_->GetTechnologyState(NetworkTypePattern::Tether())); + + base::CommandLine::ForCurrentProcess()->AppendSwitch( + chromeos::switches::kEnableTether); + + EXPECT_EQ( + NetworkStateHandler::TECHNOLOGY_ENABLED, + network_state_handler_->GetTechnologyState(NetworkTypePattern::Tether())); +} + TEST_F(NetworkStateHandlerTest, ServicePropertyChanged) { // Set a service property. const std::string eth1 = kShillManagerClientStubDefaultService; @@ -547,21 +589,20 @@ TEST_F(NetworkStateHandlerTest, TetherNetworkState) { EXPECT_EQ(0u, test_observer_->network_list_changed_count()); - const std::string& guid = - network_state_handler_->CreateTetherNetworkState(kTetherName); + network_state_handler_->AddTetherNetworkState(kTetherGuid1, kTetherName1); EXPECT_EQ(1u, test_observer_->network_list_changed_count()); const NetworkState* tether_network = - network_state_handler_->GetNetworkStateFromGuid(guid); + network_state_handler_->GetNetworkStateFromGuid(kTetherGuid1); ASSERT_TRUE(tether_network); - EXPECT_EQ(kTetherName, tether_network->name()); + EXPECT_EQ(kTetherName1, tether_network->name()); - network_state_handler_->RemoveTetherNetworkState(guid); + network_state_handler_->RemoveTetherNetworkState(kTetherGuid1); EXPECT_EQ(2u, test_observer_->network_list_changed_count()); - ASSERT_FALSE(network_state_handler_->GetNetworkStateFromGuid(guid)); + ASSERT_FALSE(network_state_handler_->GetNetworkStateFromGuid(kTetherGuid1)); } TEST_F(NetworkStateHandlerTest, NetworkConnectionStateChanged) {
diff --git a/cloud_print/OWNERS b/cloud_print/OWNERS index 8a47a27..e04ac0f 100644 --- a/cloud_print/OWNERS +++ b/cloud_print/OWNERS
@@ -5,3 +5,4 @@ # vitalybuka is not on the Chrome project use only as a last resort! vitalybuka@chromium.org +# COMPONENT: Services>CloudPrint
diff --git a/components/OWNERS b/components/OWNERS index ffa8c1d..1dbc3891 100644 --- a/components/OWNERS +++ b/components/OWNERS
@@ -21,6 +21,7 @@ per-file payments_strings.grdp=file://components/payments/OWNERS per-file pdf_strings.grdp=raymes@chromium.org per-file pdf_strings.grdp=tsergeant@chromium.org +per-file physical_web_ui_strings.grdp=file://components/physical_web/OWNERS per-file policy_strings.grdp=file://components/policy/OWNERS per-file security_interstitials_strings.grdp=file://components/security_interstitials/OWNERS per-file security_state_strings.grdp=file://components/security_state/OWNERS
diff --git a/components/arc/common/notifications.mojom b/components/arc/common/notifications.mojom index 37268d20..b1b07b72 100644 --- a/components/arc/common/notifications.mojom +++ b/components/arc/common/notifications.mojom
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Next MinVersion: 9 +// Next MinVersion: 10 module arc.mojom; @@ -131,10 +131,20 @@ SendNotificationEventToAndroid@1(string key, ArcNotificationEvent event); // Requests to Android side to create the notification window. + // |key| is the identifier of the notification which is generated by Android + // side. [MinVersion=7] CreateNotificationWindow@2(string key); // Requests to Android side to close the notification window. + // |key| is the identifier of the notification which is generated by Android + // side. [MinVersion=7] CloseNotificationWindow@3(string key); + + // Requests to Android side to open notification settings. + // |key| is the identifier of the notification which is generated by Android + // side. + [MinVersion=9] + OpenNotificationSettings@4(string key); };
diff --git a/components/arc/test/fake_notifications_instance.cc b/components/arc/test/fake_notifications_instance.cc index 3a9f631..67ec0bd 100644 --- a/components/arc/test/fake_notifications_instance.cc +++ b/components/arc/test/fake_notifications_instance.cc
@@ -21,6 +21,9 @@ void FakeNotificationsInstance::CloseNotificationWindow( const std::string& key) {} +void FakeNotificationsInstance::OpenNotificationSettings( + const std::string& key) {} + void FakeNotificationsInstance::Init(mojom::NotificationsHostPtr host_ptr) {} const std::vector<std::pair<std::string, mojom::ArcNotificationEvent>>&
diff --git a/components/arc/test/fake_notifications_instance.h b/components/arc/test/fake_notifications_instance.h index a615a4d..320dc79 100644 --- a/components/arc/test/fake_notifications_instance.h +++ b/components/arc/test/fake_notifications_instance.h
@@ -25,6 +25,7 @@ mojom::ArcNotificationEvent event) override; void CreateNotificationWindow(const std::string& key) override; void CloseNotificationWindow(const std::string& key) override; + void OpenNotificationSettings(const std::string& key) override; const std::vector<std::pair<std::string, mojom::ArcNotificationEvent>>& events() const;
diff --git a/components/autofill/content/browser/content_autofill_driver_factory.cc b/components/autofill/content/browser/content_autofill_driver_factory.cc index 8dc6d34..3865c03 100644 --- a/components/autofill/content/browser/content_autofill_driver_factory.cc +++ b/components/autofill/content/browser/content_autofill_driver_factory.cc
@@ -4,21 +4,32 @@ #include "components/autofill/content/browser/content_autofill_driver_factory.h" +#include <utility> #include <vector> +#include "base/bind.h" #include "base/memory/ptr_util.h" -#include "base/stl_util.h" #include "components/autofill/content/browser/content_autofill_driver.h" -#include "components/autofill/core/browser/autofill_client.h" #include "components/autofill/core/browser/autofill_manager.h" -#include "components/autofill/core/browser/form_structure.h" -#include "components/autofill/core/common/autofill_switches.h" #include "content/public/browser/navigation_handle.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/web_contents.h" namespace autofill { +namespace { + +std::unique_ptr<AutofillDriver> CreateDriver( + content::RenderFrameHost* render_frame_host, + AutofillClient* client, + const std::string& app_locale, + AutofillManager::AutofillDownloadManagerState enable_download_manager) { + return base::MakeUnique<ContentAutofillDriver>( + render_frame_host, client, app_locale, enable_download_manager); +} + +} // namespace + const char ContentAutofillDriverFactory:: kContentAutofillDriverFactoryWebContentsUserDataKey[] = "web_contents_autofill_driver_factory"; @@ -83,31 +94,29 @@ AutofillClient* client, const std::string& app_locale, AutofillManager::AutofillDownloadManagerState enable_download_manager) - : content::WebContentsObserver(web_contents), - client_(client), + : AutofillDriverFactory(client), + content::WebContentsObserver(web_contents), app_locale_(app_locale), enable_download_manager_(enable_download_manager) {} ContentAutofillDriver* ContentAutofillDriverFactory::DriverForFrame( content::RenderFrameHost* render_frame_host) { - auto mapping = frame_driver_map_.find(render_frame_host); - return mapping == frame_driver_map_.end() ? nullptr : mapping->second.get(); + // This cast is safe because AutofillDriverFactory::AddForKey is protected + // and always called with ContentAutofillDriver instances within + // ContentAutofillDriverFactory. + return static_cast<ContentAutofillDriver*>(DriverForKey(render_frame_host)); } void ContentAutofillDriverFactory::RenderFrameCreated( content::RenderFrameHost* render_frame_host) { - auto insertion_result = - frame_driver_map_.insert(std::make_pair(render_frame_host, nullptr)); - // This is called twice for the main frame. - if (insertion_result.second) { // This was the first time. - insertion_result.first->second = base::MakeUnique<ContentAutofillDriver>( - render_frame_host, client_, app_locale_, enable_download_manager_); - } + AddForKey(render_frame_host, + base::Bind(CreateDriver, render_frame_host, client(), app_locale_, + enable_download_manager_)); } void ContentAutofillDriverFactory::RenderFrameDeleted( content::RenderFrameHost* render_frame_host) { - frame_driver_map_.erase(render_frame_host); + DeleteForKey(render_frame_host); } void ContentAutofillDriverFactory::DidFinishNavigation( @@ -115,13 +124,13 @@ if (!navigation_handle->HasCommitted()) return; - client_->HideAutofillPopup(); - frame_driver_map_[navigation_handle->GetRenderFrameHost()]-> - DidNavigateFrame(navigation_handle); + NavigationFinished(); + DriverForFrame(navigation_handle->GetRenderFrameHost()) + ->DidNavigateFrame(navigation_handle); } void ContentAutofillDriverFactory::WasHidden() { - client_->HideAutofillPopup(); + TabHidden(); } } // namespace autofill
diff --git a/components/autofill/content/browser/content_autofill_driver_factory.h b/components/autofill/content/browser/content_autofill_driver_factory.h index 63e168f6..df2d8bc 100644 --- a/components/autofill/content/browser/content_autofill_driver_factory.h +++ b/components/autofill/content/browser/content_autofill_driver_factory.h
@@ -5,12 +5,11 @@ #ifndef COMPONENTS_AUTOFILL_CONTENT_BROWSER_CONTENT_AUTOFILL_DRIVER_FACTORY_H_ #define COMPONENTS_AUTOFILL_CONTENT_BROWSER_CONTENT_AUTOFILL_DRIVER_FACTORY_H_ -#include <map> -#include <memory> #include <string> #include "base/supports_user_data.h" #include "components/autofill/content/common/autofill_driver.mojom.h" +#include "components/autofill/core/browser/autofill_driver_factory.h" #include "components/autofill/core/browser/autofill_manager.h" #include "content/public/browser/web_contents_observer.h" @@ -24,7 +23,8 @@ // Manages lifetime of ContentAutofillDriver. One Factory per WebContents // creates one Driver per RenderFrame. -class ContentAutofillDriverFactory : public content::WebContentsObserver, +class ContentAutofillDriverFactory : public AutofillDriverFactory, + public content::WebContentsObserver, public base::SupportsUserData::Data { public: ~ContentAutofillDriverFactory() override; @@ -53,20 +53,15 @@ static const char kContentAutofillDriverFactoryWebContentsUserDataKey[]; - protected: + private: ContentAutofillDriverFactory( content::WebContents* web_contents, AutofillClient* client, const std::string& app_locale, AutofillManager::AutofillDownloadManagerState enable_download_manager); - private: - AutofillClient* client_; std::string app_locale_; AutofillManager::AutofillDownloadManagerState enable_download_manager_; - - std::map<content::RenderFrameHost*, std::unique_ptr<ContentAutofillDriver>> - frame_driver_map_; }; } // namespace autofill
diff --git a/components/autofill/core/browser/BUILD.gn b/components/autofill/core/browser/BUILD.gn index 30ec621..fb237cad 100644 --- a/components/autofill/core/browser/BUILD.gn +++ b/components/autofill/core/browser/BUILD.gn
@@ -28,6 +28,8 @@ "autofill_download_manager.cc", "autofill_download_manager.h", "autofill_driver.h", + "autofill_driver_factory.cc", + "autofill_driver_factory.h", "autofill_experiments.cc", "autofill_experiments.h", "autofill_external_delegate.cc", @@ -60,6 +62,8 @@ "card_unmask_delegate.h", "contact_info.cc", "contact_info.h", + "country_combobox_model.cc", + "country_combobox_model.h", "country_data.cc", "country_data.h", "country_names.cc", @@ -297,6 +301,7 @@ "autofill_data_model_unittest.cc", "autofill_data_util_unittest.cc", "autofill_download_manager_unittest.cc", + "autofill_driver_factory_unittest.cc", "autofill_external_delegate_unittest.cc", "autofill_field_unittest.cc", "autofill_ie_toolbar_import_win_unittest.cc", @@ -307,6 +312,7 @@ "autofill_profile_unittest.cc", "autofill_type_unittest.cc", "contact_info_unittest.cc", + "country_combobox_model_unittest.cc", "country_names_unittest.cc", "credit_card_field_unittest.cc", "credit_card_unittest.cc",
diff --git a/components/autofill/core/browser/autofill_driver_factory.cc b/components/autofill/core/browser/autofill_driver_factory.cc new file mode 100644 index 0000000..19d369bb1 --- /dev/null +++ b/components/autofill/core/browser/autofill_driver_factory.cc
@@ -0,0 +1,44 @@ +// 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/autofill/core/browser/autofill_driver_factory.h" + +#include "base/callback.h" +#include "components/autofill/core/browser/autofill_client.h" +#include "components/autofill/core/browser/autofill_driver.h" + +namespace autofill { + +AutofillDriverFactory::AutofillDriverFactory(AutofillClient* client) + : client_(client) {} + +AutofillDriverFactory::~AutofillDriverFactory() {} + +AutofillDriver* AutofillDriverFactory::DriverForKey(void* key) { + auto mapping = driver_map_.find(key); + return mapping == driver_map_.end() ? nullptr : mapping->second.get(); +} + +void AutofillDriverFactory::AddForKey( + void* key, + base::Callback<std::unique_ptr<AutofillDriver>()> factory_method) { + auto insertion_result = driver_map_.insert(std::make_pair(key, nullptr)); + // This can be called twice for the key representing the main frame. + if (insertion_result.second) + insertion_result.first->second = factory_method.Run(); +} + +void AutofillDriverFactory::DeleteForKey(void* key) { + driver_map_.erase(key); +} + +void AutofillDriverFactory::NavigationFinished() { + client_->HideAutofillPopup(); +} + +void AutofillDriverFactory::TabHidden() { + client_->HideAutofillPopup(); +} + +} // namespace autofill
diff --git a/components/autofill/core/browser/autofill_driver_factory.h b/components/autofill/core/browser/autofill_driver_factory.h new file mode 100644 index 0000000..8446d7a --- /dev/null +++ b/components/autofill/core/browser/autofill_driver_factory.h
@@ -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. + +#ifndef AUTOFILL_CORE_BROWSER_AUTOFILL_DRIVER_FACTORY_H_ +#define AUTOFILL_CORE_BROWSER_AUTOFILL_DRIVER_FACTORY_H_ + +#include <memory> +#include <unordered_map> + +#include "base/callback_forward.h" +#include "base/macros.h" + +namespace autofill { + +class AutofillClient; +class AutofillDriver; + +// Manages the lifetime of AutofillDrivers for a particular AutofillClient by +// creating, retrieveing and deleting on demand. +class AutofillDriverFactory { + // The API is protected to guarantee subclasses that nothing else can + // interfere with the map of drivers. + protected: + explicit AutofillDriverFactory(AutofillClient* client); + + ~AutofillDriverFactory(); + + // A convenience function to retrieve an AutofillDriver for the given key or + // null if there is none. + AutofillDriver* DriverForKey(void* key); + + // Adds a driver, constructed by calling |factory_method|, for |key|. If there + // already is a driver for |key|, |factory_method| is not called. + void AddForKey( + void* key, + base::Callback<std::unique_ptr<AutofillDriver>()> factory_method); + + // Deletes the AutofillDriver for |key|. + void DeleteForKey(void* key); + + // Handles finished navigation in any of the frames. + void NavigationFinished(); + + // Handles hiding of the corresponding tab. + void TabHidden(); + + AutofillClient* client() { return client_; }; + + private: + AutofillClient* const client_; + + std::unordered_map<void*, std::unique_ptr<AutofillDriver>> driver_map_; + + DISALLOW_COPY_AND_ASSIGN(AutofillDriverFactory); +}; + +} // namespace autofill + +#endif // AUTOFILL_CORE_BROWSER_AUTOFILL_DRIVER_FACTORY_H_
diff --git a/components/autofill/core/browser/autofill_driver_factory_unittest.cc b/components/autofill/core/browser/autofill_driver_factory_unittest.cc new file mode 100644 index 0000000..e79c4716 --- /dev/null +++ b/components/autofill/core/browser/autofill_driver_factory_unittest.cc
@@ -0,0 +1,176 @@ +// 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/autofill/core/browser/autofill_driver_factory.h" + +#include <memory> +#include <utility> + +#include "base/bind_helpers.h" +#include "base/memory/ptr_util.h" +#include "base/message_loop/message_loop.h" +#include "components/autofill/core/browser/test_autofill_client.h" +#include "components/autofill/core/browser/test_autofill_driver.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace autofill { + +namespace { + +class MockAutofillClient : public TestAutofillClient { + public: + MOCK_METHOD0(HideAutofillPopup, void()); +}; + +// Just a stub AutofillDriver implementation which announces its construction +// and desctruction by updating the passed |instance_counter|. +class CountingAutofillDriver : public TestAutofillDriver { + public: + CountingAutofillDriver(int* instance_counter) + : instance_counter_(instance_counter) { + ++*instance_counter; + } + + ~CountingAutofillDriver() override { --*instance_counter_; } + + private: + int* const instance_counter_; + + DISALLOW_COPY_AND_ASSIGN(CountingAutofillDriver); +}; + +// Code-wise this class is identitcal to AutofillDriverFactory, but exposes the +// protected API to the test. Do not modify any of the methods, only include +// "using" declarations to make the AutofillDriverFactory methods public. +class PublicAutofillDriverFactory : public AutofillDriverFactory { + public: + explicit PublicAutofillDriverFactory(AutofillClient* client) + : AutofillDriverFactory(client) {} + + ~PublicAutofillDriverFactory() {} + + using AutofillDriverFactory::DriverForKey; + using AutofillDriverFactory::AddForKey; + using AutofillDriverFactory::DeleteForKey; + using AutofillDriverFactory::NavigationFinished; + using AutofillDriverFactory::TabHidden; +}; + +// Wrapper around an integer, checking that the integer is 0 on desctruction. +class CheckedInt { + public: + CheckedInt() {} + + ~CheckedInt() { EXPECT_EQ(0, val_); } + + int* val() { return &val_; } + + private: + int val_ = 0; +}; + +} // namespace + +class AutofillDriverFactoryTest : public testing::Test { + public: + AutofillDriverFactoryTest() : factory_(&client_) {} + + ~AutofillDriverFactoryTest() override {} + + // AutofillDriverFactory stores drivers in a map with keys, which are void* + // pointers. The factory never dereferences them, so their value does not + // matter. This is a handy function to create such pointers from integer + // constants. + void* KeyFrom(int x) { return reinterpret_cast<void*>(x); } + + std::unique_ptr<AutofillDriver> CreateDriver() { + ++drivers_created_; + return base::MakeUnique<CountingAutofillDriver>(instance_counter_.val()); + } + + base::Callback<std::unique_ptr<AutofillDriver>()> CreateDriverCallback() { + return base::Bind(&AutofillDriverFactoryTest::CreateDriver, + base::Unretained(this)); + } + + protected: + base::MessageLoop message_loop_; // For TestAutofillDriver. + + MockAutofillClient client_; + + CheckedInt instance_counter_; + + PublicAutofillDriverFactory factory_; + + // How many AutofillDriver instances were created with CreateDriver(). + int drivers_created_ = 0; +}; + +TEST_F(AutofillDriverFactoryTest, DriverForKey_NoKey) { + EXPECT_FALSE(factory_.DriverForKey(nullptr)); + EXPECT_FALSE(factory_.DriverForKey(KeyFrom(1))); +} + +TEST_F(AutofillDriverFactoryTest, DriverForKey_OneKey) { + factory_.AddForKey(KeyFrom(1), CreateDriverCallback()); + EXPECT_FALSE(factory_.DriverForKey(nullptr)); + EXPECT_TRUE(factory_.DriverForKey(KeyFrom(1))); +} + +TEST_F(AutofillDriverFactoryTest, DriverForKey_TwoKeys) { + factory_.AddForKey(KeyFrom(1), CreateDriverCallback()); + EXPECT_FALSE(factory_.DriverForKey(nullptr)); + EXPECT_TRUE(factory_.DriverForKey(KeyFrom(1))); + EXPECT_EQ(1, *instance_counter_.val()); + + factory_.AddForKey(nullptr, CreateDriverCallback()); + EXPECT_TRUE(factory_.DriverForKey(nullptr)); + EXPECT_TRUE(factory_.DriverForKey(KeyFrom(1))); + EXPECT_EQ(2, *instance_counter_.val()); +} + +TEST_F(AutofillDriverFactoryTest, AddForKey_Duplicated) { + EXPECT_FALSE(factory_.DriverForKey(KeyFrom(1))); + + factory_.AddForKey(KeyFrom(1), CreateDriverCallback()); + EXPECT_TRUE(factory_.DriverForKey(KeyFrom(1))); + EXPECT_EQ(1, drivers_created_); + EXPECT_EQ(1, *instance_counter_.val()); + + factory_.AddForKey(KeyFrom(1), CreateDriverCallback()); + EXPECT_TRUE(factory_.DriverForKey(KeyFrom(1))); + EXPECT_EQ(1, drivers_created_); + EXPECT_EQ(1, *instance_counter_.val()); +} + +TEST_F(AutofillDriverFactoryTest, DeleteForKey) { + EXPECT_FALSE(factory_.DriverForKey(KeyFrom(1))); + EXPECT_EQ(0, *instance_counter_.val()); + + factory_.AddForKey(KeyFrom(1), CreateDriverCallback()); + EXPECT_TRUE(factory_.DriverForKey(KeyFrom(1))); + EXPECT_EQ(1, *instance_counter_.val()); + + factory_.DeleteForKey(KeyFrom(1)); + EXPECT_FALSE(factory_.DriverForKey(KeyFrom(1))); + EXPECT_EQ(0, *instance_counter_.val()); + + // Duplicated calls should raise no errors. + factory_.DeleteForKey(KeyFrom(1)); + EXPECT_FALSE(factory_.DriverForKey(KeyFrom(1))); + EXPECT_EQ(0, *instance_counter_.val()); +} + +TEST_F(AutofillDriverFactoryTest, NavigationFinished) { + EXPECT_CALL(client_, HideAutofillPopup()); + factory_.NavigationFinished(); +} + +TEST_F(AutofillDriverFactoryTest, TabHidden) { + EXPECT_CALL(client_, HideAutofillPopup()); + factory_.TabHidden(); +} + +} // namespace autofill
diff --git a/chrome/browser/ui/autofill/country_combobox_model.cc b/components/autofill/core/browser/country_combobox_model.cc similarity index 89% rename from chrome/browser/ui/autofill/country_combobox_model.cc rename to components/autofill/core/browser/country_combobox_model.cc index 9a2c147e..c9f8a47 100644 --- a/chrome/browser/ui/autofill/country_combobox_model.cc +++ b/components/autofill/core/browser/country_combobox_model.cc
@@ -2,16 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/autofill/country_combobox_model.h" +#include "components/autofill/core/browser/country_combobox_model.h" #include <algorithm> #include <iterator> +#include <utility> #include "base/logging.h" #include "base/memory/ptr_util.h" #include "base/strings/utf_string_conversions.h" -#include "build/build_config.h" -#include "chrome/browser/browser_process.h" #include "components/autofill/core/browser/autofill_country.h" #include "components/autofill/core/browser/country_data.h" #include "components/autofill/core/browser/personal_data_manager.h" @@ -27,7 +26,8 @@ void CountryComboboxModel::SetCountries( const PersonalDataManager& manager, - const base::Callback<bool(const std::string&)>& filter) { + const base::Callback<bool(const std::string&)>& filter, + const std::string& app_locale) { countries_.clear(); // Insert the default country at the top as well as in the ordered list. @@ -35,7 +35,6 @@ manager.GetDefaultCountryCodeForNewAddress(); DCHECK(!default_country_code.empty()); - const std::string& app_locale = g_browser_process->GetApplicationLocale(); if (filter.is_null() || filter.Run(default_country_code)) { countries_.push_back( base::MakeUnique<AutofillCountry>(default_country_code, app_locale)); @@ -69,8 +68,7 @@ base::MakeUnique<AutofillCountry>(country_code, app_locale)); } - l10n_util::SortStringsUsingMethod(app_locale, - &sorted_countries, + l10n_util::SortStringsUsingMethod(app_locale, &sorted_countries, &AutofillCountry::name); std::move(sorted_countries.begin(), sorted_countries.end(), std::back_inserter(countries_));
diff --git a/chrome/browser/ui/autofill/country_combobox_model.h b/components/autofill/core/browser/country_combobox_model.h similarity index 83% rename from chrome/browser/ui/autofill/country_combobox_model.h rename to components/autofill/core/browser/country_combobox_model.h index d7e25a6a..b3d90c3a 100644 --- a/chrome/browser/ui/autofill/country_combobox_model.h +++ b/components/autofill/core/browser/country_combobox_model.h
@@ -2,18 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_UI_AUTOFILL_COUNTRY_COMBOBOX_MODEL_H_ -#define CHROME_BROWSER_UI_AUTOFILL_COUNTRY_COMBOBOX_MODEL_H_ +#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_COUNTRY_COMBOBOX_MODEL_H_ +#define COMPONENTS_AUTOFILL_CORE_BROWSER_COUNTRY_COMBOBOX_MODEL_H_ #include <memory> -#include <set> #include <string> #include <vector> #include "base/callback.h" -#include "base/compiler_specific.h" #include "base/macros.h" -#include "base/memory/scoped_vector.h" #include "ui/base/models/combobox_model.h" namespace autofill { @@ -33,7 +30,8 @@ // true, an item for that country is added to the model (else it's omitted). // |manager| determines the default choice. void SetCountries(const PersonalDataManager& manager, - const base::Callback<bool(const std::string&)>& filter); + const base::Callback<bool(const std::string&)>& filter, + const std::string& app_locale); // ui::ComboboxModel implementation: int GetItemCount() const override; @@ -55,4 +53,4 @@ } // namespace autofill -#endif // CHROME_BROWSER_UI_AUTOFILL_COUNTRY_COMBOBOX_MODEL_H_ +#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_COUNTRY_COMBOBOX_MODEL_H_
diff --git a/chrome/browser/ui/autofill/country_combobox_model_unittest.cc b/components/autofill/core/browser/country_combobox_model_unittest.cc similarity index 60% rename from chrome/browser/ui/autofill/country_combobox_model_unittest.cc rename to components/autofill/core/browser/country_combobox_model_unittest.cc index 43883538..ca3e9f0 100644 --- a/chrome/browser/ui/autofill/country_combobox_model_unittest.cc +++ b/components/autofill/core/browser/country_combobox_model_unittest.cc
@@ -2,19 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/autofill/country_combobox_model.h" +#include "components/autofill/core/browser/country_combobox_model.h" #include <memory> -#include "chrome/browser/browser_process.h" -#include "chrome/browser/signin/account_tracker_service_factory.h" -#include "chrome/browser/signin/signin_manager_factory.h" -#include "chrome/test/base/testing_profile.h" #include "components/autofill/core/browser/autofill_country.h" +#include "components/autofill/core/browser/autofill_test_utils.h" #include "components/autofill/core/browser/test_personal_data_manager.h" -#include "components/signin/core/browser/account_tracker_service.h" -#include "components/signin/core/browser/signin_manager.h" -#include "content/public/test/test_browser_thread_bundle.h" +#include "components/prefs/pref_service.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_ui.h" #include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_ui_component.h" @@ -24,24 +19,23 @@ class CountryComboboxModelTest : public testing::Test { public: - CountryComboboxModelTest() { - manager_.Init( - NULL, profile_.GetPrefs(), - AccountTrackerServiceFactory::GetForProfile(&profile_), - SigninManagerFactory::GetForProfile(&profile_), false); + CountryComboboxModelTest() + : pref_service_(autofill::test::PrefServiceForTesting()) { + manager_.SetTestingPrefService(pref_service_.get()); manager_.set_timezone_country_code("KR"); model_.reset(new CountryComboboxModel()); - model_->SetCountries(manager_, base::Callback<bool(const std::string&)>()); + model_->SetCountries(manager_, base::Callback<bool(const std::string&)>(), + "en-US"); } + void TearDown() override { manager_.SetTestingPrefService(nullptr); } + TestPersonalDataManager* manager() { return &manager_; } CountryComboboxModel* model() { return model_.get(); } private: - // NB: order is important here - |profile_| must go down after |manager_|. - content::TestBrowserThreadBundle thread_bundle_; - TestingProfile profile_; TestPersonalDataManager manager_; + std::unique_ptr<PrefService> pref_service_; std::unique_ptr<CountryComboboxModel> model_; }; @@ -49,8 +43,7 @@ std::string default_country = model()->GetDefaultCountryCode(); EXPECT_EQ(manager()->GetDefaultCountryCodeForNewAddress(), default_country); - AutofillCountry country(default_country, - g_browser_process->GetApplicationLocale()); + AutofillCountry country(default_country, "en-US"); EXPECT_EQ(country.name(), model()->GetItemAt(0)); } @@ -62,9 +55,9 @@ continue; std::string country_code = model()->countries()[i]->country_code(); - std::vector< ::i18n::addressinput::AddressUiComponent> components = - ::i18n::addressinput::BuildComponents( - country_code, localization, std::string(), &unused); + std::vector<::i18n::addressinput::AddressUiComponent> components = + ::i18n::addressinput::BuildComponents(country_code, localization, + std::string(), &unused); EXPECT_FALSE(components.empty()) << " for country " << country_code; } }
diff --git a/components/autofill/core/browser/form_structure.cc b/components/autofill/core/browser/form_structure.cc index ff24fce0..addf89f 100644 --- a/components/autofill/core/browser/form_structure.cc +++ b/components/autofill/core/browser/form_structure.cc
@@ -628,7 +628,7 @@ // Map from field signatures to cached fields. std::map<std::string, const AutofillField*> cached_fields; for (size_t i = 0; i < cached_form.field_count(); ++i) { - const auto& field = cached_form.field(i); + auto* const field = cached_form.field(i); cached_fields[field->FieldSignatureAsStr()] = field; } @@ -681,7 +681,7 @@ bool did_autofill_all_possible_fields = true; bool did_autofill_some_possible_fields = false; for (size_t i = 0; i < field_count(); ++i) { - const auto& field = this->field(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
diff --git a/components/autofill/core/browser/personal_data_manager.cc b/components/autofill/core/browser/personal_data_manager.cc index 5cc15a1e..590f814d 100644 --- a/components/autofill/core/browser/personal_data_manager.cc +++ b/components/autofill/core/browser/personal_data_manager.cc
@@ -1815,7 +1815,7 @@ C -> D */ - for (auto& credit_card : GetCreditCards()) { + for (auto* credit_card : GetCreditCards()) { // If the credit card is not associated with a billing address, skip it. if (credit_card->billing_address_id().empty()) break;
diff --git a/components/bookmarks/browser/typed_count_sorter.cc b/components/bookmarks/browser/typed_count_sorter.cc index 311f1383..19576106 100644 --- a/components/bookmarks/browser/typed_count_sorter.cc +++ b/components/bookmarks/browser/typed_count_sorter.cc
@@ -56,7 +56,7 @@ if (client_->SupportsTypedCountForUrls()) { UrlNodeMap url_node_map; UrlTypedCountMap url_typed_count_map; - for (auto node : matches) { + for (auto* node : matches) { const GURL& url = node->GetTitledUrlNodeUrl(); url_node_map.insert(std::make_pair(&url, node)); url_typed_count_map.insert(std::make_pair(&url, 0));
diff --git a/components/component_updater/component_updater_service.cc b/components/component_updater/component_updater_service.cc index 15886783..9be0f5c 100644 --- a/components/component_updater/component_updater_service.cc +++ b/components/component_updater/component_updater_service.cc
@@ -200,7 +200,7 @@ const auto it = component_ids_by_mime_type_.find(mime_type); if (it == component_ids_by_mime_type_.end()) return nullptr; - const auto component = GetComponent(it->second); + auto* const component = GetComponent(it->second); if (!component) return nullptr; return base::MakeUnique<ComponentInfo>(GetCrxComponentID(*component),
diff --git a/components/cryptauth/ble/bluetooth_low_energy_weave_client_connection.cc b/components/cryptauth/ble/bluetooth_low_energy_weave_client_connection.cc index d75f27d..8afc502 100644 --- a/components/cryptauth/ble/bluetooth_low_energy_weave_client_connection.cc +++ b/components/cryptauth/ble/bluetooth_low_energy_weave_client_connection.cc
@@ -610,7 +610,7 @@ if (remote_service_.id.empty()) { std::vector<device::BluetoothRemoteGattService*> services = bluetooth_device->GetGattServices(); - for (const auto& service : services) + for (auto* service : services) if (service->GetUUID() == remote_service_.uuid) { remote_service_.id = service->GetIdentifier(); break;
diff --git a/components/data_use_measurement/core/data_use_measurement.cc b/components/data_use_measurement/core/data_use_measurement.cc index 85b3f66b..3a80307 100644 --- a/components/data_use_measurement/core/data_use_measurement.cc +++ b/components/data_use_measurement/core/data_use_measurement.cc
@@ -88,6 +88,16 @@ { DCHECK(ascriber_); DCHECK(url_request_classifier_); + +#if defined(OS_ANDROID) + int64_t bytes = 0; + // Query Android traffic stats. + if (net::android::traffic_stats::GetCurrentUidRxBytes(&bytes)) + rx_bytes_os_ = bytes; + + if (net::android::traffic_stats::GetCurrentUidTxBytes(&bytes)) + tx_bytes_os_ = bytes; +#endif } DataUseMeasurement::~DataUseMeasurement(){}; @@ -312,7 +322,10 @@ if (net::android::traffic_stats::GetCurrentUidRxBytes(&bytes)) { if (rx_bytes_os_ != 0) { DCHECK_GE(bytes, rx_bytes_os_); - UMA_HISTOGRAM_COUNTS("DataUse.BytesReceived.OS", bytes - rx_bytes_os_); + if (bytes > rx_bytes_os_) { + // Do not record samples with value 0. + UMA_HISTOGRAM_COUNTS("DataUse.BytesReceived.OS", bytes - rx_bytes_os_); + } } rx_bytes_os_ = bytes; } @@ -320,7 +333,10 @@ if (net::android::traffic_stats::GetCurrentUidTxBytes(&bytes)) { if (tx_bytes_os_ != 0) { DCHECK_GE(bytes, tx_bytes_os_); - UMA_HISTOGRAM_COUNTS("DataUse.BytesSent.OS", bytes - tx_bytes_os_); + if (bytes > tx_bytes_os_) { + // Do not record samples with value 0. + UMA_HISTOGRAM_COUNTS("DataUse.BytesSent.OS", bytes - tx_bytes_os_); + } } tx_bytes_os_ = bytes; }
diff --git a/components/invalidation/impl/android/java/src/org/chromium/components/invalidation/InvalidationClientService.java b/components/invalidation/impl/android/java/src/org/chromium/components/invalidation/InvalidationClientService.java index 82edfcbf..5d908c90 100644 --- a/components/invalidation/impl/android/java/src/org/chromium/components/invalidation/InvalidationClientService.java +++ b/components/invalidation/impl/android/java/src/org/chromium/components/invalidation/InvalidationClientService.java
@@ -22,6 +22,7 @@ import com.google.protos.ipc.invalidation.Types.ClientType; import org.chromium.base.ApplicationStatus; +import org.chromium.base.BuildInfo; import org.chromium.base.CollectionUtil; import org.chromium.base.ContextUtils; import org.chromium.base.Log; @@ -317,12 +318,21 @@ private void startClient() { byte[] clientName = InvalidationClientNameProvider.get().getInvalidatorClientName(); Intent startIntent = AndroidListener.createStartIntent(this, CLIENT_TYPE, clientName); + + if (shouldRestrictBackgroundServices()) { + Log.e(TAG, "Failed to start client"); + return; + } startService(startIntent); setIsClientStarted(true); } /** Stops the notification client. */ private void stopClient() { + if (shouldRestrictBackgroundServices()) { + Log.e(TAG, "Failed to stop client"); + return; + } startService(AndroidListener.createStopIntent(this)); setIsClientStarted(false); setClientId(null); @@ -540,4 +550,9 @@ private static void setIsClientStarted(boolean isStarted) { sIsClientStarted = isStarted; } + + private boolean shouldRestrictBackgroundServices() { + // Restricts the use of background services when not in foreground. See crbug.com/680812. + return BuildInfo.isGreaterThanN() && !isChromeInForeground(); + } }
diff --git a/components/invalidation/impl/android/java/src/org/chromium/components/invalidation/InvalidationService.java b/components/invalidation/impl/android/java/src/org/chromium/components/invalidation/InvalidationService.java index 92c017a..170681bd 100644 --- a/components/invalidation/impl/android/java/src/org/chromium/components/invalidation/InvalidationService.java +++ b/components/invalidation/impl/android/java/src/org/chromium/components/invalidation/InvalidationService.java
@@ -10,6 +10,9 @@ import com.google.protos.ipc.invalidation.Types; +import org.chromium.base.ApplicationStatus; +import org.chromium.base.BuildInfo; +import org.chromium.base.Log; import org.chromium.base.ThreadUtils; import org.chromium.base.VisibleForTesting; import org.chromium.base.annotations.CalledByNative; @@ -29,6 +32,8 @@ private final long mNativeInvalidationServiceAndroid; + private static final String TAG = "cr_invalidation"; + private InvalidationService(Context context, long nativeInvalidationServiceAndroid) { mContext = context.getApplicationContext(); if (mContext == null) { @@ -71,9 +76,19 @@ account, objectSources, objectNames); registerIntent.setClass( mContext, InvalidationClientService.getRegisteredClass()); + + if (shouldRestrictBackgroundServices()) { + Log.e(TAG, "Failed to register objects"); + return; + } mContext.startService(registerIntent); } + private boolean shouldRestrictBackgroundServices() { + // Restricts the use of background services when not in foreground. See crbug.com/680812. + return BuildInfo.isGreaterThanN() && !ApplicationStatus.hasVisibleActivities(); + } + /** * Fetches the Invalidator client name. *
diff --git a/components/metrics/BUILD.gn b/components/metrics/BUILD.gn index 300bb1d..129f1fe 100644 --- a/components/metrics/BUILD.gn +++ b/components/metrics/BUILD.gn
@@ -27,6 +27,8 @@ "drive_metrics_provider_win.cc", "enabled_state_provider.cc", "enabled_state_provider.h", + "environment_recorder.cc", + "environment_recorder.h", "execution_phase.cc", "execution_phase.h", "file_metrics_provider.cc", @@ -73,6 +75,8 @@ "persisted_logs_metrics_impl.h", "stability_metrics_helper.cc", "stability_metrics_helper.h", + "stability_metrics_provider.cc", + "stability_metrics_provider.h", "system_memory_stats_recorder.h", "system_memory_stats_recorder_linux.cc", "system_memory_stats_recorder_win.cc", @@ -311,6 +315,7 @@ "daily_event_unittest.cc", "data_use_tracker_unittest.cc", "drive_metrics_provider_unittest.cc", + "environment_recorder_unittest.cc", "file_metrics_provider_unittest.cc", "histogram_encoder_unittest.cc", "machine_id_provider_win_unittest.cc", @@ -325,6 +330,7 @@ "profiler/profiler_metrics_provider_unittest.cc", "profiler/tracking_synchronizer_unittest.cc", "stability_metrics_helper_unittest.cc", + "stability_metrics_provider_unittest.cc", "ui/screen_info_metrics_provider_unittest.cc", ]
diff --git a/components/metrics/clean_exit_beacon.cc b/components/metrics/clean_exit_beacon.cc index 8868e0f..4bca5d1c 100644 --- a/components/metrics/clean_exit_beacon.cc +++ b/components/metrics/clean_exit_beacon.cc
@@ -7,6 +7,7 @@ #include "base/logging.h" #include "build/build_config.h" #include "components/metrics/metrics_pref_names.h" +#include "components/prefs/pref_registry_simple.h" #include "components/prefs/pref_service.h" #if defined(OS_WIN) @@ -62,6 +63,11 @@ CleanExitBeacon::~CleanExitBeacon() { } +// static +void CleanExitBeacon::RegisterPrefs(PrefRegistrySimple* registry) { + registry->RegisterBooleanPref(prefs::kStabilityExitedCleanly, true); +} + void CleanExitBeacon::WriteBeaconValue(bool value) { local_state_->SetBoolean(prefs::kStabilityExitedCleanly, value);
diff --git a/components/metrics/clean_exit_beacon.h b/components/metrics/clean_exit_beacon.h index 6b896fa1..e863e41e 100644 --- a/components/metrics/clean_exit_beacon.h +++ b/components/metrics/clean_exit_beacon.h
@@ -8,6 +8,7 @@ #include "base/macros.h" #include "base/strings/string16.h" +class PrefRegistrySimple; class PrefService; namespace metrics { @@ -32,6 +33,9 @@ // Writes the provided beacon value. void WriteBeaconValue(bool exited_cleanly); + // Registers local state prefs used by this class. + static void RegisterPrefs(PrefRegistrySimple* registry); + private: PrefService* const local_state_; const bool initial_value_;
diff --git a/components/metrics/environment_recorder.cc b/components/metrics/environment_recorder.cc new file mode 100644 index 0000000..07ead8c --- /dev/null +++ b/components/metrics/environment_recorder.cc
@@ -0,0 +1,96 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/metrics/environment_recorder.h" + +#include "base/base64.h" +#include "base/sha1.h" +#include "base/strings/string_number_conversions.h" +#include "components/metrics/metrics_pref_names.h" +#include "components/metrics/proto/system_profile.pb.h" +#include "components/prefs/pref_registry_simple.h" +#include "components/prefs/pref_service.h" + +namespace metrics { + +namespace { + +// Computes a SHA-1 hash of |data| and returns it as a hex string. +std::string ComputeSHA1(const std::string& data) { + const std::string sha1 = base::SHA1HashString(data); + return base::HexEncode(sha1.data(), sha1.size()); +} + +} // namespace + +EnvironmentRecorder::EnvironmentRecorder(PrefService* local_state) + : local_state_(local_state) {} + +EnvironmentRecorder::~EnvironmentRecorder() = default; + +std::string EnvironmentRecorder::SerializeAndRecordEnvironmentToPrefs( + const SystemProfileProto& system_profile) { + std::string serialized_system_profile; + std::string base64_system_profile; + if (system_profile.SerializeToString(&serialized_system_profile)) { + // Persist the system profile to disk. In the event of an unclean shutdown, + // it will be used as part of the initial stability report. + base::Base64Encode(serialized_system_profile, &base64_system_profile); + local_state_->SetString(prefs::kStabilitySavedSystemProfile, + base64_system_profile); + local_state_->SetString(prefs::kStabilitySavedSystemProfileHash, + ComputeSHA1(serialized_system_profile)); + } + + return serialized_system_profile; +} + +bool EnvironmentRecorder::LoadEnvironmentFromPrefs( + SystemProfileProto* system_profile) { + DCHECK(system_profile); + + const std::string base64_system_profile = + local_state_->GetString(prefs::kStabilitySavedSystemProfile); + if (base64_system_profile.empty()) + return false; + const std::string system_profile_hash = + local_state_->GetString(prefs::kStabilitySavedSystemProfileHash); + + std::string serialized_system_profile; + return base::Base64Decode(base64_system_profile, + &serialized_system_profile) && + ComputeSHA1(serialized_system_profile) == system_profile_hash && + system_profile->ParseFromString(serialized_system_profile); +} + +void EnvironmentRecorder::ClearEnvironmentFromPrefs() { + local_state_->ClearPref(prefs::kStabilitySavedSystemProfile); + local_state_->ClearPref(prefs::kStabilitySavedSystemProfileHash); +} + +int64_t EnvironmentRecorder::GetLastBuildtime() { + return local_state_->GetInt64(prefs::kStabilityStatsBuildTime); +} + +std::string EnvironmentRecorder::GetLastVersion() { + return local_state_->GetString(prefs::kStabilityStatsVersion); +} + +void EnvironmentRecorder::SetBuildtimeAndVersion(int64_t buildtime, + const std::string& version) { + local_state_->SetInt64(prefs::kStabilityStatsBuildTime, buildtime); + local_state_->SetString(prefs::kStabilityStatsVersion, version); +} + +// static +void EnvironmentRecorder::RegisterPrefs(PrefRegistrySimple* registry) { + registry->RegisterStringPref(prefs::kStabilitySavedSystemProfile, + std::string()); + registry->RegisterStringPref(prefs::kStabilitySavedSystemProfileHash, + std::string()); + registry->RegisterStringPref(prefs::kStabilityStatsVersion, std::string()); + registry->RegisterInt64Pref(prefs::kStabilityStatsBuildTime, 0); +} + +} // namespace metrics
diff --git a/components/metrics/environment_recorder.h b/components/metrics/environment_recorder.h new file mode 100644 index 0000000..0042d2e --- /dev/null +++ b/components/metrics/environment_recorder.h
@@ -0,0 +1,59 @@ +// 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_METRICS_ENVIRONMENT_RECORDER_H_ +#define COMPONENTS_METRICS_ENVIRONMENT_RECORDER_H_ + +#include <string> + +#include "base/macros.h" + +class PrefService; +class PrefRegistrySimple; + +namespace metrics { + +class SystemProfileProto; + +// Stores system profile information to prefs for creating stability logs +// in the next launch of chrome, and reads data from previous launches. +class EnvironmentRecorder { + public: + explicit EnvironmentRecorder(PrefService* local_state); + ~EnvironmentRecorder(); + + // Serializes the system profile and records it in prefs for the next + // session. Returns the uncompressed serialized proto for passing to crash + // reports, or the empty string if the proto can't be serialized. + std::string SerializeAndRecordEnvironmentToPrefs( + const SystemProfileProto& system_profile); + + // Loads the system_profile data stored in a previous chrome session, and + // stores it in the |system_profile| object. + // Returns true iff a system profile was successfully read. + bool LoadEnvironmentFromPrefs(SystemProfileProto* system_profile); + + // Deletes system profile data from prefs. + void ClearEnvironmentFromPrefs(); + + // Stores the buildtime of the current binary and version in prefs. + void SetBuildtimeAndVersion(int64_t buildtime, const std::string& version); + + // Gets the buildtime stored in prefs. + int64_t GetLastBuildtime(); + + // Gets the version stored in prefs. + std::string GetLastVersion(); + + static void RegisterPrefs(PrefRegistrySimple* registry); + + private: + PrefService* local_state_; + + DISALLOW_COPY_AND_ASSIGN(EnvironmentRecorder); +}; + +} // namespace metrics + +#endif // COMPONENTS_METRICS_ENVIRONMENT_RECORDER_H_
diff --git a/components/metrics/environment_recorder_unittest.cc b/components/metrics/environment_recorder_unittest.cc new file mode 100644 index 0000000..5c2ae8b --- /dev/null +++ b/components/metrics/environment_recorder_unittest.cc
@@ -0,0 +1,75 @@ +// 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/metrics/environment_recorder.h" + +#include "components/metrics/metrics_pref_names.h" +#include "components/metrics/proto/system_profile.pb.h" +#include "components/prefs/testing_pref_service.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace metrics { + +class EnvironmentRecorderTest : public testing::Test { + public: + EnvironmentRecorderTest() { + EnvironmentRecorder::RegisterPrefs(prefs_.registry()); + } + + ~EnvironmentRecorderTest() override {} + + protected: + TestingPrefServiceSimple prefs_; + + private: + DISALLOW_COPY_AND_ASSIGN(EnvironmentRecorderTest); +}; + +TEST_F(EnvironmentRecorderTest, LoadEnvironmentFromPrefs) { + const char* kSystemProfilePref = prefs::kStabilitySavedSystemProfile; + const char* kSystemProfileHashPref = prefs::kStabilitySavedSystemProfileHash; + + // The pref value is empty, so loading it from prefs should fail. + { + EnvironmentRecorder recorder(&prefs_); + SystemProfileProto system_profile; + EXPECT_FALSE(recorder.LoadEnvironmentFromPrefs(&system_profile)); + EXPECT_FALSE(system_profile.has_app_version()); + } + + // Do a RecordEnvironment() call and check whether the pref is recorded. + { + EnvironmentRecorder recorder(&prefs_); + SystemProfileProto system_profile; + system_profile.set_app_version("bogus version"); + std::string serialized_profile = + recorder.SerializeAndRecordEnvironmentToPrefs(system_profile); + EXPECT_FALSE(serialized_profile.empty()); + EXPECT_FALSE(prefs_.GetString(kSystemProfilePref).empty()); + EXPECT_FALSE(prefs_.GetString(kSystemProfileHashPref).empty()); + } + + // Load it and check that it has the right value. + { + EnvironmentRecorder recorder(&prefs_); + SystemProfileProto system_profile; + EXPECT_TRUE(recorder.LoadEnvironmentFromPrefs(&system_profile)); + EXPECT_EQ("bogus version", system_profile.app_version()); + // Ensure that the call did not clear the prefs. + EXPECT_FALSE(prefs_.GetString(kSystemProfilePref).empty()); + EXPECT_FALSE(prefs_.GetString(kSystemProfileHashPref).empty()); + } + + // Ensure that a non-matching hash results in the pref being invalid. + { + // Set the hash to a bad value. + prefs_.SetString(kSystemProfileHashPref, "deadbeef"); + EnvironmentRecorder recorder(&prefs_); + SystemProfileProto system_profile; + EXPECT_FALSE(recorder.LoadEnvironmentFromPrefs(&system_profile)); + EXPECT_FALSE(system_profile.has_app_version()); + } +} + +} // namespace metrics
diff --git a/components/metrics/metrics_log.cc b/components/metrics/metrics_log.cc index e2740cb..ac35ce3 100644 --- a/components/metrics/metrics_log.cc +++ b/components/metrics/metrics_log.cc
@@ -9,19 +9,15 @@ #include <algorithm> #include <string> -#include "base/base64.h" #include "base/build_time.h" #include "base/cpu.h" #include "base/metrics/histogram_macros.h" #include "base/metrics/histogram_samples.h" #include "base/metrics/metrics_hashes.h" -#include "base/sha1.h" -#include "base/strings/string_number_conversions.h" -#include "base/strings/string_util.h" -#include "base/strings/utf_string_conversions.h" #include "base/sys_info.h" #include "base/time/time.h" #include "build/build_config.h" +#include "components/metrics/environment_recorder.h" #include "components/metrics/histogram_encoder.h" #include "components/metrics/metrics_pref_names.h" #include "components/metrics/metrics_provider.h" @@ -53,12 +49,6 @@ return id.size() < 16; } -// Computes a SHA-1 hash of |data| and returns it as a hex string. -std::string ComputeSHA1(const std::string& data) { - const std::string sha1 = base::SHA1HashString(data); - return base::HexEncode(sha1.data(), sha1.size()); -} - void WriteFieldTrials(const std::vector<ActiveGroupId>& field_trial_ids, SystemProfileProto* system_profile) { for (std::vector<ActiveGroupId>::const_iterator it = @@ -109,21 +99,7 @@ // static void MetricsLog::RegisterPrefs(PrefRegistrySimple* registry) { - registry->RegisterIntegerPref(prefs::kStabilityCrashCount, 0); - registry->RegisterIntegerPref(prefs::kStabilityIncompleteSessionEndCount, 0); - registry->RegisterIntegerPref(prefs::kStabilityLaunchCount, 0); - registry->RegisterIntegerPref(prefs::kStabilityBreakpadRegistrationFail, 0); - registry->RegisterIntegerPref( - prefs::kStabilityBreakpadRegistrationSuccess, 0); - registry->RegisterIntegerPref(prefs::kStabilityDebuggerPresent, 0); - registry->RegisterIntegerPref(prefs::kStabilityDebuggerNotPresent, 0); - registry->RegisterStringPref(prefs::kStabilitySavedSystemProfile, - std::string()); - registry->RegisterStringPref(prefs::kStabilitySavedSystemProfileHash, - std::string()); - registry->RegisterIntegerPref(prefs::kStabilityDeferredCount, 0); - registry->RegisterIntegerPref(prefs::kStabilityDiscardCount, 0); - registry->RegisterIntegerPref(prefs::kStabilityVersionMismatchCount, 0); + EnvironmentRecorder::RegisterPrefs(registry); } // static @@ -210,20 +186,11 @@ DCHECK(HasEnvironment()); DCHECK(!HasStabilityMetrics()); - PrefService* pref = local_state_; - DCHECK(pref); - - // Get stability attributes out of Local State, zeroing out stored values. - // NOTE: This could lead to some data loss if this report isn't successfully - // sent, but that's true for all the metrics. - - WriteRequiredStabilityAttributes(pref); - // Record recent delta for critical stability metrics. We can't wait for a // restart to gather these, as that delay biases our observation away from // users that run happily for a looooong time. We send increments with each // uma log upload, just as we send histogram data. - WriteRealtimeStabilityAttributes(pref, incremental_uptime, uptime); + WriteRealtimeStabilityAttributes(incremental_uptime, uptime); SystemProfileProto* system_profile = uma_proto()->mutable_system_profile(); for (size_t i = 0; i < metrics_providers.size(); ++i) { @@ -231,71 +198,6 @@ metrics_providers[i]->ProvideInitialStabilityMetrics(system_profile); metrics_providers[i]->ProvideStabilityMetrics(system_profile); } - - SystemProfileProto::Stability* stability = - system_profile->mutable_stability(); - - int incomplete_shutdown_count = - pref->GetInteger(prefs::kStabilityIncompleteSessionEndCount); - if (incomplete_shutdown_count) { - pref->SetInteger(prefs::kStabilityIncompleteSessionEndCount, 0); - stability->set_incomplete_shutdown_count(incomplete_shutdown_count); - } - - int breakpad_registration_success_count = - pref->GetInteger(prefs::kStabilityBreakpadRegistrationSuccess); - if (breakpad_registration_success_count) { - pref->SetInteger(prefs::kStabilityBreakpadRegistrationSuccess, 0); - stability->set_breakpad_registration_success_count( - breakpad_registration_success_count); - } - - int breakpad_registration_failure_count = - pref->GetInteger(prefs::kStabilityBreakpadRegistrationFail); - if (breakpad_registration_failure_count) { - pref->SetInteger(prefs::kStabilityBreakpadRegistrationFail, 0); - stability->set_breakpad_registration_failure_count( - breakpad_registration_failure_count); - } - - int debugger_present_count = - pref->GetInteger(prefs::kStabilityDebuggerPresent); - if (debugger_present_count) { - pref->SetInteger(prefs::kStabilityDebuggerPresent, 0); - stability->set_debugger_present_count(debugger_present_count); - } - - int debugger_not_present_count = - pref->GetInteger(prefs::kStabilityDebuggerNotPresent); - if (debugger_not_present_count) { - pref->SetInteger(prefs::kStabilityDebuggerNotPresent, 0); - stability->set_debugger_not_present_count(debugger_not_present_count); - } - - // Note: only logging the following histograms for non-zero values. - - int deferred_count = pref->GetInteger(prefs::kStabilityDeferredCount); - if (deferred_count) { - local_state_->SetInteger(prefs::kStabilityDeferredCount, 0); - UMA_STABILITY_HISTOGRAM_COUNTS_100( - "Stability.Internals.InitialStabilityLogDeferredCount", deferred_count); - } - - int discard_count = local_state_->GetInteger(prefs::kStabilityDiscardCount); - if (discard_count) { - local_state_->SetInteger(prefs::kStabilityDiscardCount, 0); - UMA_STABILITY_HISTOGRAM_COUNTS_100("Stability.Internals.DataDiscardCount", - discard_count); - } - - int version_mismatch_count = - local_state_->GetInteger(prefs::kStabilityVersionMismatchCount); - if (version_mismatch_count) { - local_state_->SetInteger(prefs::kStabilityVersionMismatchCount, 0); - UMA_STABILITY_HISTOGRAM_COUNTS_100( - "Stability.Internals.VersionMismatchCount", - version_mismatch_count); - } } void MetricsLog::RecordGeneralMetrics( @@ -344,26 +246,7 @@ return uma_proto()->system_profile().stability().has_launch_count(); } -// The server refuses data that doesn't have certain values. crashcount and -// launchcount are currently "required" in the "stability" group. -// TODO(isherman): Stop writing these attributes specially once the migration to -// protobufs is complete. -void MetricsLog::WriteRequiredStabilityAttributes(PrefService* pref) { - int launch_count = pref->GetInteger(prefs::kStabilityLaunchCount); - if (launch_count) - pref->SetInteger(prefs::kStabilityLaunchCount, 0); - int crash_count = pref->GetInteger(prefs::kStabilityCrashCount); - if (crash_count) - pref->SetInteger(prefs::kStabilityCrashCount, 0); - - SystemProfileProto::Stability* stability = - uma_proto()->mutable_system_profile()->mutable_stability(); - stability->set_launch_count(launch_count); - stability->set_crash_count(crash_count); -} - void MetricsLog::WriteRealtimeStabilityAttributes( - PrefService* pref, base::TimeDelta incremental_uptime, base::TimeDelta uptime) { // Update the stats which are critical for real-time stability monitoring. @@ -419,41 +302,17 @@ for (size_t i = 0; i < metrics_providers.size(); ++i) metrics_providers[i]->ProvideSystemProfileMetrics(system_profile); - std::string serialized_system_profile; - std::string base64_system_profile; - if (system_profile->SerializeToString(&serialized_system_profile)) { - // Persist the system profile to disk. In the event of an unclean shutdown, - // it will be used as part of the initial stability report. - base::Base64Encode(serialized_system_profile, &base64_system_profile); - PrefService* local_state = local_state_; - local_state->SetString(prefs::kStabilitySavedSystemProfile, - base64_system_profile); - local_state->SetString(prefs::kStabilitySavedSystemProfileHash, - ComputeSHA1(serialized_system_profile)); - } - - return serialized_system_profile; + EnvironmentRecorder recorder(local_state_); + return recorder.SerializeAndRecordEnvironmentToPrefs(*system_profile); } bool MetricsLog::LoadSavedEnvironmentFromPrefs(std::string* app_version) { DCHECK(app_version); app_version->clear(); - PrefService* local_state = local_state_; - const std::string base64_system_profile = - local_state->GetString(prefs::kStabilitySavedSystemProfile); - if (base64_system_profile.empty()) - return false; - const std::string system_profile_hash = - local_state->GetString(prefs::kStabilitySavedSystemProfileHash); - SystemProfileProto* system_profile = uma_proto()->mutable_system_profile(); - std::string serialized_system_profile; - - bool success = - base::Base64Decode(base64_system_profile, &serialized_system_profile) && - ComputeSHA1(serialized_system_profile) == system_profile_hash && - system_profile->ParseFromString(serialized_system_profile); + EnvironmentRecorder recorder(local_state_); + bool success = recorder.LoadEnvironmentFromPrefs(system_profile); if (success) *app_version = system_profile->app_version(); return success;
diff --git a/components/metrics/metrics_log.h b/components/metrics/metrics_log.h index 5a01964a..4f28b43 100644 --- a/components/metrics/metrics_log.h +++ b/components/metrics/metrics_log.h
@@ -19,7 +19,6 @@ #include "components/metrics/metrics_service_client.h" #include "components/metrics/proto/chrome_user_metrics_extension.pb.h" -class PrefRegistrySimple; class PrefService; namespace base { @@ -173,15 +172,11 @@ // call to RecordStabilityMetrics(). bool HasStabilityMetrics() const; - // Within the stability group, write required attributes. - void WriteRequiredStabilityAttributes(PrefService* pref); - // Within the stability group, write attributes that need to be updated asap // and can't be delayed until the user decides to restart chromium. // Delaying these stats would bias metrics away from happy long lived // chromium processes (ones that don't crash, and keep on running). - void WriteRealtimeStabilityAttributes(PrefService* pref, - base::TimeDelta incremental_uptime, + void WriteRealtimeStabilityAttributes(base::TimeDelta incremental_uptime, base::TimeDelta uptime); // closed_ is true when record has been packed up for sending, and should
diff --git a/components/metrics/metrics_log_unittest.cc b/components/metrics/metrics_log_unittest.cc index 0d0274a..f1a7792 100644 --- a/components/metrics/metrics_log_unittest.cc +++ b/components/metrics/metrics_log_unittest.cc
@@ -17,6 +17,7 @@ #include "base/strings/string_number_conversions.h" #include "base/sys_info.h" #include "base/time/time.h" +#include "components/metrics/environment_recorder.h" #include "components/metrics/metrics_pref_names.h" #include "components/metrics/metrics_state_manager.h" #include "components/metrics/proto/chrome_user_metrics_extension.pb.h" @@ -103,7 +104,7 @@ class MetricsLogTest : public testing::Test { public: MetricsLogTest() { - MetricsLog::RegisterPrefs(prefs_.registry()); + EnvironmentRecorder::RegisterPrefs(prefs_.registry()); MetricsStateManager::RegisterPrefs(prefs_.registry()); } @@ -295,83 +296,12 @@ CheckSystemProfile(log.system_profile()); // Check that the system profile has also been written to prefs. - const std::string base64_system_profile = - prefs_.GetString(prefs::kStabilitySavedSystemProfile); - EXPECT_FALSE(base64_system_profile.empty()); - std::string serialied_system_profile; - EXPECT_TRUE(base::Base64Decode(base64_system_profile, - &serialied_system_profile)); SystemProfileProto decoded_system_profile; - EXPECT_TRUE(decoded_system_profile.ParseFromString(serialied_system_profile)); + EnvironmentRecorder recorder(&prefs_); + EXPECT_TRUE(recorder.LoadEnvironmentFromPrefs(&decoded_system_profile)); CheckSystemProfile(decoded_system_profile); } -TEST_F(MetricsLogTest, LoadSavedEnvironmentFromPrefs) { - const char* kSystemProfilePref = prefs::kStabilitySavedSystemProfile; - const char* kSystemProfileHashPref = - prefs::kStabilitySavedSystemProfileHash; - - TestMetricsServiceClient client; - client.set_version_string("bogus version"); - - // The pref value is empty, so loading it from prefs should fail. - { - TestMetricsLog log( - kClientId, kSessionId, MetricsLog::ONGOING_LOG, &client, &prefs_); - std::string app_version; - EXPECT_FALSE(log.LoadSavedEnvironmentFromPrefs(&app_version)); - EXPECT_TRUE(app_version.empty()); - } - - // Do a RecordEnvironment() call and check whether the pref is recorded. - { - TestMetricsLog log( - kClientId, kSessionId, MetricsLog::ONGOING_LOG, &client, &prefs_); - log.RecordEnvironment(std::vector<std::unique_ptr<MetricsProvider>>(), - std::vector<variations::ActiveGroupId>(), - kInstallDate, kEnabledDate); - EXPECT_FALSE(prefs_.GetString(kSystemProfilePref).empty()); - EXPECT_FALSE(prefs_.GetString(kSystemProfileHashPref).empty()); - } - - { - TestMetricsLog log( - kClientId, kSessionId, MetricsLog::ONGOING_LOG, &client, &prefs_); - std::string app_version; - EXPECT_TRUE(log.LoadSavedEnvironmentFromPrefs(&app_version)); - EXPECT_EQ("bogus version", app_version); - // Check some values in the system profile. - EXPECT_EQ(kInstallDateExpected, log.system_profile().install_date()); - EXPECT_EQ(kEnabledDateExpected, log.system_profile().uma_enabled_date()); - // Ensure that the call did not clear the prefs. - EXPECT_FALSE(prefs_.GetString(kSystemProfilePref).empty()); - EXPECT_FALSE(prefs_.GetString(kSystemProfileHashPref).empty()); - } - - // Ensure that a non-matching hash results in the pref being invalid. - { - TestMetricsLog log( - kClientId, kSessionId, MetricsLog::ONGOING_LOG, &client, &prefs_); - // Call RecordEnvironment() to record the pref again. - log.RecordEnvironment(std::vector<std::unique_ptr<MetricsProvider>>(), - std::vector<variations::ActiveGroupId>(), - kInstallDate, kEnabledDate); - } - - { - // Set the hash to a bad value. - prefs_.SetString(kSystemProfileHashPref, "deadbeef"); - TestMetricsLog log( - kClientId, kSessionId, MetricsLog::ONGOING_LOG, &client, &prefs_); - std::string app_version; - EXPECT_FALSE(log.LoadSavedEnvironmentFromPrefs(&app_version)); - EXPECT_TRUE(app_version.empty()); - // Ensure that the prefs are not cleared, even if the call failed. - EXPECT_FALSE(prefs_.GetString(kSystemProfilePref).empty()); - EXPECT_FALSE(prefs_.GetString(kSystemProfileHashPref).empty()); - } -} - TEST_F(MetricsLogTest, RecordEnvironmentEnableDefault) { TestMetricsServiceClient client; TestMetricsLog log_unknown(kClientId, kSessionId, MetricsLog::ONGOING_LOG, @@ -426,17 +356,6 @@ kEnabledDate); log.RecordStabilityMetrics(metrics_providers, base::TimeDelta(), base::TimeDelta()); - const SystemProfileProto_Stability& stability = - log.system_profile().stability(); - // Required metrics: - EXPECT_TRUE(stability.has_launch_count()); - EXPECT_TRUE(stability.has_crash_count()); - // Initial log metrics: only expected if non-zero. - EXPECT_FALSE(stability.has_incomplete_shutdown_count()); - EXPECT_FALSE(stability.has_breakpad_registration_success_count()); - EXPECT_FALSE(stability.has_breakpad_registration_failure_count()); - EXPECT_FALSE(stability.has_debugger_present_count()); - EXPECT_FALSE(stability.has_debugger_not_present_count()); // The test provider should have been called upon to provide initial // stability and regular stability metrics. @@ -456,17 +375,6 @@ kEnabledDate); log.RecordStabilityMetrics(metrics_providers, base::TimeDelta(), base::TimeDelta()); - const SystemProfileProto_Stability& stability = - log.system_profile().stability(); - // Required metrics: - EXPECT_TRUE(stability.has_launch_count()); - EXPECT_TRUE(stability.has_crash_count()); - // Initial log metrics: only expected if non-zero. - EXPECT_FALSE(stability.has_incomplete_shutdown_count()); - EXPECT_FALSE(stability.has_breakpad_registration_success_count()); - EXPECT_FALSE(stability.has_breakpad_registration_failure_count()); - EXPECT_FALSE(stability.has_debugger_present_count()); - EXPECT_FALSE(stability.has_debugger_not_present_count()); // The test provider should have been called upon to provide regular but not // initial stability metrics.
diff --git a/components/metrics/metrics_pref_names.cc b/components/metrics/metrics_pref_names.cc index c5ad9c6..ea3fd38 100644 --- a/components/metrics/metrics_pref_names.cc +++ b/components/metrics/metrics_pref_names.cc
@@ -128,19 +128,10 @@ const char kStabilityIncompleteSessionEndCount[] = "user_experience_metrics.stability.incomplete_session_end_count"; -// Time when the app was last known to be running, in seconds since -// the epoch. -const char kStabilityLastTimestampSec[] = - "user_experience_metrics.stability.last_timestamp_sec"; - // Number of times the application was launched since last report. const char kStabilityLaunchCount[] = "user_experience_metrics.stability.launch_count"; -// Time when the app was last launched, in seconds since the epoch. -const char kStabilityLaunchTimeSec[] = - "user_experience_metrics.stability.launch_time_sec"; - // Number of times a page load event occurred since the last report. const char kStabilityPageLoadCount[] = "user_experience_metrics.stability.page_load_count";
diff --git a/components/metrics/metrics_pref_names.h b/components/metrics/metrics_pref_names.h index df25e38..a918802 100644 --- a/components/metrics/metrics_pref_names.h +++ b/components/metrics/metrics_pref_names.h
@@ -30,6 +30,8 @@ extern const char kMetricsReportingEnabledTimestamp[]; extern const char kMetricsSessionID[]; extern const char kMetricsLastSeenPrefix[]; + +// Preferences for recording stability logs. extern const char kStabilityBreakpadRegistrationSuccess[]; extern const char kStabilityBreakpadRegistrationFail[]; extern const char kStabilityChildProcessCrashCount[]; @@ -44,9 +46,7 @@ extern const char kStabilityExtensionRendererLaunchCount[]; extern const char kStabilityExitedCleanly[]; extern const char kStabilityIncompleteSessionEndCount[]; -extern const char kStabilityLastTimestampSec[]; extern const char kStabilityLaunchCount[]; -extern const char kStabilityLaunchTimeSec[]; extern const char kStabilityPageLoadCount[]; extern const char kStabilityRendererCrashCount[]; extern const char kStabilityRendererFailedLaunchCount[]; @@ -58,6 +58,8 @@ extern const char kStabilityStatsBuildTime[]; extern const char kStabilityStatsVersion[]; extern const char kStabilityVersionMismatchCount[]; + +// Preferences for generating metrics at uninstall time. extern const char kUninstallLaunchCount[]; extern const char kUninstallMetricsPageLoadCount[]; extern const char kUninstallMetricsUptimeSec[];
diff --git a/components/metrics/metrics_service.cc b/components/metrics/metrics_service.cc index 26c0d9b1..d7b5027 100644 --- a/components/metrics/metrics_service.cc +++ b/components/metrics/metrics_service.cc
@@ -148,6 +148,7 @@ #include "base/tracked_objects.h" #include "build/build_config.h" #include "components/metrics/data_use_tracker.h" +#include "components/metrics/environment_recorder.h" #include "components/metrics/metrics_log.h" #include "components/metrics/metrics_log_manager.h" #include "components/metrics/metrics_log_uploader.h" @@ -157,6 +158,7 @@ #include "components/metrics/metrics_service_client.h" #include "components/metrics/metrics_state_manager.h" #include "components/metrics/metrics_upload_scheduler.h" +#include "components/metrics/stability_metrics_provider.h" #include "components/metrics/url_constants.h" #include "components/prefs/pref_registry_simple.h" #include "components/prefs/pref_service.h" @@ -235,19 +237,15 @@ // static void MetricsService::RegisterPrefs(PrefRegistrySimple* registry) { + CleanExitBeacon::RegisterPrefs(registry); MetricsStateManager::RegisterPrefs(registry); MetricsLog::RegisterPrefs(registry); + StabilityMetricsProvider::RegisterPrefs(registry); DataUseTracker::RegisterPrefs(registry); + ExecutionPhaseManager::RegisterPrefs(registry); registry->RegisterInt64Pref(prefs::kInstallDate, 0); - registry->RegisterInt64Pref(prefs::kStabilityLaunchTimeSec, 0); - registry->RegisterInt64Pref(prefs::kStabilityLastTimestampSec, 0); - registry->RegisterStringPref(prefs::kStabilityStatsVersion, std::string()); - registry->RegisterInt64Pref(prefs::kStabilityStatsBuildTime, 0); - registry->RegisterBooleanPref(prefs::kStabilityExitedCleanly, true); - ExecutionPhaseManager::RegisterPrefs(registry); - registry->RegisterBooleanPref(prefs::kStabilitySessionEndCompleted, true); registry->RegisterIntegerPref(prefs::kMetricsSessionID, -1); registry->RegisterListPref(prefs::kMetricsInitialLogs); @@ -284,6 +282,9 @@ int64_t install_date = local_state_->GetInt64(prefs::kInstallDate); if (install_date == 0) local_state_->SetInt64(prefs::kInstallDate, base::Time::Now().ToTimeT()); + + RegisterMetricsProvider(std::unique_ptr<metrics::MetricsProvider>( + new StabilityMetricsProvider(local_state_))); } MetricsService::~MetricsService() { @@ -505,36 +506,17 @@ } void MetricsService::RecordBreakpadRegistration(bool success) { - if (!success) - IncrementPrefValue(prefs::kStabilityBreakpadRegistrationFail); - else - IncrementPrefValue(prefs::kStabilityBreakpadRegistrationSuccess); + StabilityMetricsProvider(local_state_).RecordBreakpadRegistration(success); } void MetricsService::RecordBreakpadHasDebugger(bool has_debugger) { - if (!has_debugger) - IncrementPrefValue(prefs::kStabilityDebuggerNotPresent); - else - IncrementPrefValue(prefs::kStabilityDebuggerPresent); + StabilityMetricsProvider(local_state_) + .RecordBreakpadHasDebugger(has_debugger); } void MetricsService::ClearSavedStabilityMetrics() { for (auto& provider : metrics_providers_) provider->ClearSavedStabilityMetrics(); - - // Reset the prefs that are managed by MetricsService/MetricsLog directly. - local_state_->SetInteger(prefs::kStabilityBreakpadRegistrationSuccess, 0); - local_state_->SetInteger(prefs::kStabilityBreakpadRegistrationFail, 0); - local_state_->SetInteger(prefs::kStabilityCrashCount, 0); - local_state_->SetInteger(prefs::kStabilityDebuggerPresent, 0); - local_state_->SetInteger(prefs::kStabilityDebuggerNotPresent, 0); - local_state_->SetInteger(prefs::kStabilityIncompleteSessionEndCount, 0); - local_state_->SetInteger(prefs::kStabilityLaunchCount, 0); - local_state_->SetBoolean(prefs::kStabilitySessionEndCompleted, true); - local_state_->SetInteger(prefs::kStabilityDeferredCount, 0); - // Note: kStabilityDiscardCount is not cleared as its intent is to measure - // the number of times data is discarded, even across versions. - local_state_->SetInteger(prefs::kStabilityVersionMismatchCount, 0); } void MetricsService::PushExternalLog(const std::string& log) { @@ -564,19 +546,12 @@ const int64_t buildtime = MetricsLog::GetBuildTime(); const std::string version = client_->GetVersionString(); - // Delete deprecated prefs - // TODO(holte): Remove these in M58 - local_state_->ClearPref(prefs::kStabilityLaunchTimeSec); - local_state_->ClearPref(prefs::kStabilityLastTimestampSec); - bool version_changed = false; - int64_t previous_buildtime = - local_state_->GetInt64(prefs::kStabilityStatsBuildTime); - std::string previous_version = - local_state_->GetString(prefs::kStabilityStatsVersion); + EnvironmentRecorder recorder(local_state_); + int64_t previous_buildtime = recorder.GetLastBuildtime(); + std::string previous_version = recorder.GetLastVersion(); if (previous_buildtime != buildtime || previous_version != version) { - local_state_->SetString(prefs::kStabilityStatsVersion, version); - local_state_->SetInt64(prefs::kStabilityStatsBuildTime, buildtime); + recorder.SetBuildtimeAndVersion(buildtime, version); version_changed = true; } @@ -584,8 +559,9 @@ session_id_ = local_state_->GetInteger(prefs::kMetricsSessionID); + StabilityMetricsProvider provider(local_state_); if (!clean_exit_beacon_.exited_cleanly()) { - IncrementPrefValue(prefs::kStabilityCrashCount); + provider.LogCrash(); // Reset flag, and wait until we call LogNeedForCleanShutdown() before // monitoring. clean_exit_beacon_.WriteBeaconValue(true); @@ -608,7 +584,7 @@ if (state_manager_->IsMetricsReportingEnabled()) { has_initial_stability_log = PrepareInitialStabilityLog(previous_version); if (!has_initial_stability_log) - IncrementPrefValue(prefs::kStabilityDeferredCount); + provider.LogStabilityLogDeferred(); } } @@ -620,7 +596,7 @@ // normally results in stats being accumulated). if (version_changed && !has_initial_stability_log) { ClearSavedStabilityMetrics(); - IncrementPrefValue(prefs::kStabilityDiscardCount); + provider.LogStabilityDataDiscarded(); } // If the version changed, the system profile is obsolete and needs to be @@ -630,25 +606,17 @@ // stability log, an operation that requires the previous version's system // profile. At this point, stability metrics pertaining to the previous // version have been cleared. - if (version_changed) { - local_state_->ClearPref(prefs::kStabilitySavedSystemProfile); - local_state_->ClearPref(prefs::kStabilitySavedSystemProfileHash); - } + if (version_changed) + recorder.ClearEnvironmentFromPrefs(); // Update session ID. ++session_id_; local_state_->SetInteger(prefs::kMetricsSessionID, session_id_); - // Stability bookkeeping - IncrementPrefValue(prefs::kStabilityLaunchCount); - + // Notify stability metrics providers about the launch. + provider.LogLaunch(); SetExecutionPhase(ExecutionPhase::START_METRICS_RECORDING, local_state_); - - if (!local_state_->GetBoolean(prefs::kStabilitySessionEndCompleted)) { - IncrementPrefValue(prefs::kStabilityIncompleteSessionEndCount); - // This is marked false when we get a WM_ENDSESSION. - local_state_->SetBoolean(prefs::kStabilitySessionEndCompleted, true); - } + provider.CheckLastSessionEndCompleted(); // Call GetUptimes() for the first time, thus allowing all later calls // to record incremental uptimes accurately. @@ -965,7 +933,7 @@ return false; } if (system_profile_app_version != prefs_previous_version) - IncrementPrefValue(prefs::kStabilityVersionMismatchCount); + StabilityMetricsProvider(local_state_).LogStabilityVersionMismatch(); log_manager_.PauseCurrentLog(); log_manager_.BeginLoggingWithLog(std::move(initial_stability_log)); @@ -1096,11 +1064,6 @@ } } -void MetricsService::IncrementPrefValue(const char* path) { - int value = local_state_->GetInteger(path); - local_state_->SetInteger(path, value + 1); -} - void MetricsService::IncrementLongPrefsValue(const char* path) { int64_t value = local_state_->GetInt64(path); local_state_->SetInt64(path, value + 1); @@ -1252,7 +1215,7 @@ client_->OnLogCleanShutdown(); clean_exit_beacon_.WriteBeaconValue(true); SetExecutionPhase(ExecutionPhase::SHUTDOWN_COMPLETE, local_state_); - local_state_->SetBoolean(prefs::kStabilitySessionEndCompleted, end_completed); + StabilityMetricsProvider(local_state_).MarkSessionEndCompleted(end_completed); } } // namespace metrics
diff --git a/components/metrics/metrics_service.h b/components/metrics/metrics_service.h index f283b23..42f311f 100644 --- a/components/metrics/metrics_service.h +++ b/components/metrics/metrics_service.h
@@ -332,9 +332,6 @@ // Called after transmission completes (either successfully or with failure). void OnLogUploadComplete(int response_code); - // Reads, increments and then sets the specified integer preference. - void IncrementPrefValue(const char* path); - // Reads, increments and then sets the specified long preference that is // stored as a string. void IncrementLongPrefsValue(const char* path);
diff --git a/components/metrics/metrics_service_unittest.cc b/components/metrics/metrics_service_unittest.cc index f4a264ca..2d5e32fd 100644 --- a/components/metrics/metrics_service_unittest.cc +++ b/components/metrics/metrics_service_unittest.cc
@@ -20,6 +20,7 @@ #include "base/threading/platform_thread.h" #include "base/threading/thread_task_runner_handle.h" #include "components/metrics/client_info.h" +#include "components/metrics/environment_recorder.h" #include "components/metrics/metrics_log.h" #include "components/metrics/metrics_pref_names.h" #include "components/metrics/metrics_state_manager.h" @@ -212,10 +213,9 @@ // Record stability build time and version from previous session, so that // stability metrics (including exited cleanly flag) won't be cleared. - GetLocalState()->SetInt64(prefs::kStabilityStatsBuildTime, - MetricsLog::GetBuildTime()); - GetLocalState()->SetString(prefs::kStabilityStatsVersion, - client.GetVersionString()); + EnvironmentRecorder(GetLocalState()) + .SetBuildtimeAndVersion(MetricsLog::GetBuildTime(), + client.GetVersionString()); // Set the clean exit flag, as that will otherwise cause a stabilty // log to be produced, irrespective provider requests. @@ -284,10 +284,9 @@ // Record stability build time and version from previous session, so that // stability metrics (including exited cleanly flag) won't be cleared. - GetLocalState()->SetInt64(prefs::kStabilityStatsBuildTime, - MetricsLog::GetBuildTime()); - GetLocalState()->SetString(prefs::kStabilityStatsVersion, - client.GetVersionString()); + EnvironmentRecorder(GetLocalState()) + .SetBuildtimeAndVersion(MetricsLog::GetBuildTime(), + client.GetVersionString()); GetLocalState()->SetBoolean(prefs::kStabilityExitedCleanly, false);
diff --git a/components/metrics/stability_metrics_provider.cc b/components/metrics/stability_metrics_provider.cc new file mode 100644 index 0000000..a4b5280 --- /dev/null +++ b/components/metrics/stability_metrics_provider.cc
@@ -0,0 +1,179 @@ +// 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/metrics/stability_metrics_provider.h" + +#include "base/metrics/histogram_macros.h" +#include "components/metrics/metrics_pref_names.h" +#include "components/metrics/proto/system_profile.pb.h" +#include "components/prefs/pref_registry_simple.h" +#include "components/prefs/pref_service.h" + +namespace metrics { + +StabilityMetricsProvider::StabilityMetricsProvider(PrefService* local_state) + : local_state_(local_state) {} + +StabilityMetricsProvider::~StabilityMetricsProvider() = default; + +// static +void StabilityMetricsProvider::RegisterPrefs(PrefRegistrySimple* registry) { + registry->RegisterIntegerPref(prefs::kStabilityCrashCount, 0); + registry->RegisterIntegerPref(prefs::kStabilityIncompleteSessionEndCount, 0); + registry->RegisterBooleanPref(prefs::kStabilitySessionEndCompleted, true); + registry->RegisterIntegerPref(prefs::kStabilityLaunchCount, 0); + registry->RegisterIntegerPref(prefs::kStabilityBreakpadRegistrationFail, 0); + registry->RegisterIntegerPref(prefs::kStabilityBreakpadRegistrationSuccess, + 0); + registry->RegisterIntegerPref(prefs::kStabilityDebuggerPresent, 0); + registry->RegisterIntegerPref(prefs::kStabilityDebuggerNotPresent, 0); + registry->RegisterIntegerPref(prefs::kStabilityDeferredCount, 0); + registry->RegisterIntegerPref(prefs::kStabilityDiscardCount, 0); + registry->RegisterIntegerPref(prefs::kStabilityVersionMismatchCount, 0); +} + +void StabilityMetricsProvider::ClearSavedStabilityMetrics() { + local_state_->SetInteger(prefs::kStabilityCrashCount, 0); + local_state_->SetInteger(prefs::kStabilityIncompleteSessionEndCount, 0); + local_state_->SetInteger(prefs::kStabilityBreakpadRegistrationSuccess, 0); + local_state_->SetInteger(prefs::kStabilityBreakpadRegistrationFail, 0); + local_state_->SetInteger(prefs::kStabilityDebuggerPresent, 0); + local_state_->SetInteger(prefs::kStabilityDebuggerNotPresent, 0); + local_state_->SetInteger(prefs::kStabilityLaunchCount, 0); + local_state_->SetBoolean(prefs::kStabilitySessionEndCompleted, true); + local_state_->SetInteger(prefs::kStabilityDeferredCount, 0); + // Note: kStabilityDiscardCount is not cleared as its intent is to measure + // the number of times data is discarded, even across versions. + local_state_->SetInteger(prefs::kStabilityVersionMismatchCount, 0); +} + +void StabilityMetricsProvider::ProvideStabilityMetrics( + SystemProfileProto* system_profile) { + SystemProfileProto::Stability* stability = + system_profile->mutable_stability(); + + int launch_count = local_state_->GetInteger(prefs::kStabilityLaunchCount); + if (launch_count) { + local_state_->SetInteger(prefs::kStabilityLaunchCount, 0); + stability->set_launch_count(launch_count); + } + int crash_count = local_state_->GetInteger(prefs::kStabilityCrashCount); + if (crash_count) { + local_state_->SetInteger(prefs::kStabilityCrashCount, 0); + stability->set_crash_count(crash_count); + } + + int incomplete_shutdown_count = + local_state_->GetInteger(prefs::kStabilityIncompleteSessionEndCount); + if (incomplete_shutdown_count) { + local_state_->SetInteger(prefs::kStabilityIncompleteSessionEndCount, 0); + stability->set_incomplete_shutdown_count(incomplete_shutdown_count); + } + + int breakpad_registration_success_count = + local_state_->GetInteger(prefs::kStabilityBreakpadRegistrationSuccess); + if (breakpad_registration_success_count) { + local_state_->SetInteger(prefs::kStabilityBreakpadRegistrationSuccess, 0); + stability->set_breakpad_registration_success_count( + breakpad_registration_success_count); + } + + int breakpad_registration_failure_count = + local_state_->GetInteger(prefs::kStabilityBreakpadRegistrationFail); + if (breakpad_registration_failure_count) { + local_state_->SetInteger(prefs::kStabilityBreakpadRegistrationFail, 0); + stability->set_breakpad_registration_failure_count( + breakpad_registration_failure_count); + } + + int debugger_present_count = + local_state_->GetInteger(prefs::kStabilityDebuggerPresent); + if (debugger_present_count) { + local_state_->SetInteger(prefs::kStabilityDebuggerPresent, 0); + stability->set_debugger_present_count(debugger_present_count); + } + + int debugger_not_present_count = + local_state_->GetInteger(prefs::kStabilityDebuggerNotPresent); + if (debugger_not_present_count) { + local_state_->SetInteger(prefs::kStabilityDebuggerNotPresent, 0); + stability->set_debugger_not_present_count(debugger_not_present_count); + } + + // Note: only logging the following histograms for non-zero values. + int deferred_count = local_state_->GetInteger(prefs::kStabilityDeferredCount); + if (deferred_count) { + local_state_->SetInteger(prefs::kStabilityDeferredCount, 0); + UMA_STABILITY_HISTOGRAM_COUNTS_100( + "Stability.Internals.InitialStabilityLogDeferredCount", deferred_count); + } + + int discard_count = local_state_->GetInteger(prefs::kStabilityDiscardCount); + if (discard_count) { + local_state_->SetInteger(prefs::kStabilityDiscardCount, 0); + UMA_STABILITY_HISTOGRAM_COUNTS_100("Stability.Internals.DataDiscardCount", + discard_count); + } + + int version_mismatch_count = + local_state_->GetInteger(prefs::kStabilityVersionMismatchCount); + if (version_mismatch_count) { + local_state_->SetInteger(prefs::kStabilityVersionMismatchCount, 0); + UMA_STABILITY_HISTOGRAM_COUNTS_100( + "Stability.Internals.VersionMismatchCount", version_mismatch_count); + } +} + +void StabilityMetricsProvider::RecordBreakpadRegistration(bool success) { + if (!success) + IncrementPrefValue(prefs::kStabilityBreakpadRegistrationFail); + else + IncrementPrefValue(prefs::kStabilityBreakpadRegistrationSuccess); +} + +void StabilityMetricsProvider::RecordBreakpadHasDebugger(bool has_debugger) { + if (!has_debugger) + IncrementPrefValue(prefs::kStabilityDebuggerNotPresent); + else + IncrementPrefValue(prefs::kStabilityDebuggerPresent); +} + +void StabilityMetricsProvider::CheckLastSessionEndCompleted() { + if (!local_state_->GetBoolean(prefs::kStabilitySessionEndCompleted)) { + IncrementPrefValue(prefs::kStabilityIncompleteSessionEndCount); + // This is marked false when we get a WM_ENDSESSION. + MarkSessionEndCompleted(true); + } +} + +void StabilityMetricsProvider::MarkSessionEndCompleted(bool end_completed) { + local_state_->SetBoolean(prefs::kStabilitySessionEndCompleted, end_completed); +} + +void StabilityMetricsProvider::LogCrash() { + IncrementPrefValue(prefs::kStabilityCrashCount); +} + +void StabilityMetricsProvider::LogStabilityLogDeferred() { + IncrementPrefValue(prefs::kStabilityDeferredCount); +} + +void StabilityMetricsProvider::LogStabilityDataDiscarded() { + IncrementPrefValue(prefs::kStabilityDiscardCount); +} + +void StabilityMetricsProvider::LogLaunch() { + IncrementPrefValue(prefs::kStabilityLaunchCount); +} + +void StabilityMetricsProvider::LogStabilityVersionMismatch() { + IncrementPrefValue(prefs::kStabilityVersionMismatchCount); +} + +void StabilityMetricsProvider::IncrementPrefValue(const char* path) { + int value = local_state_->GetInteger(path); + local_state_->SetInteger(path, value + 1); +} + +} // namespace metrics
diff --git a/components/metrics/stability_metrics_provider.h b/components/metrics/stability_metrics_provider.h new file mode 100644 index 0000000..4e16ed67 --- /dev/null +++ b/components/metrics/stability_metrics_provider.h
@@ -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. + +#ifndef COMPONENTS_METRICS_STABILITY_METRICS_PROVIDER_H_ +#define COMPONENTS_METRICS_STABILITY_METRICS_PROVIDER_H_ + +#include "components/metrics/metrics_provider.h" + +class PrefService; +class PrefRegistrySimple; + +namespace metrics { + +class SystemProfileProto; + +// Stores and loads system information to prefs for stability logs. +class StabilityMetricsProvider : public MetricsProvider { + public: + StabilityMetricsProvider(PrefService* local_state); + ~StabilityMetricsProvider() override; + + static void RegisterPrefs(PrefRegistrySimple* registry); + + void RecordBreakpadRegistration(bool success); + void RecordBreakpadHasDebugger(bool has_debugger); + + void CheckLastSessionEndCompleted(); + void MarkSessionEndCompleted(bool end_completed); + + void LogCrash(); + void LogStabilityLogDeferred(); + void LogStabilityDataDiscarded(); + void LogLaunch(); + void LogStabilityVersionMismatch(); + + private: + // Increments an Integer pref value specified by |path|. + void IncrementPrefValue(const char* path); + + // MetricsProvider: + void ClearSavedStabilityMetrics() override; + void ProvideStabilityMetrics( + SystemProfileProto* system_profile_proto) override; + + PrefService* local_state_; + + DISALLOW_COPY_AND_ASSIGN(StabilityMetricsProvider); +}; + +} // namespace metrics + +#endif // COMPONENTS_METRICS_STABILITY_METRICS_PROVIDER_H_
diff --git a/components/metrics/stability_metrics_provider_unittest.cc b/components/metrics/stability_metrics_provider_unittest.cc new file mode 100644 index 0000000..7b2cb61 --- /dev/null +++ b/components/metrics/stability_metrics_provider_unittest.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 "components/metrics/stability_metrics_provider.h" + +#include "components/metrics/proto/system_profile.pb.h" +#include "components/prefs/testing_pref_service.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace metrics { + +class StabilityMetricsProviderTest : public testing::Test { + public: + StabilityMetricsProviderTest() { + StabilityMetricsProvider::RegisterPrefs(prefs_.registry()); + } + + ~StabilityMetricsProviderTest() override {} + + protected: + TestingPrefServiceSimple prefs_; + + private: + DISALLOW_COPY_AND_ASSIGN(StabilityMetricsProviderTest); +}; + +TEST_F(StabilityMetricsProviderTest, ProvideStabilityMetrics) { + StabilityMetricsProvider stability_provider(&prefs_); + MetricsProvider* provider = &stability_provider; + SystemProfileProto system_profile; + provider->ProvideStabilityMetrics(&system_profile); + + const SystemProfileProto_Stability& stability = system_profile.stability(); + // Initial log metrics: only expected if non-zero. + EXPECT_FALSE(stability.has_launch_count()); + EXPECT_FALSE(stability.has_crash_count()); + EXPECT_FALSE(stability.has_incomplete_shutdown_count()); + EXPECT_FALSE(stability.has_breakpad_registration_success_count()); + EXPECT_FALSE(stability.has_breakpad_registration_failure_count()); + EXPECT_FALSE(stability.has_debugger_present_count()); + EXPECT_FALSE(stability.has_debugger_not_present_count()); +} + +TEST_F(StabilityMetricsProviderTest, RecordStabilityMetrics) { + { + StabilityMetricsProvider recorder(&prefs_); + recorder.LogLaunch(); + recorder.LogCrash(); + recorder.MarkSessionEndCompleted(false); + recorder.CheckLastSessionEndCompleted(); + recorder.RecordBreakpadRegistration(true); + recorder.RecordBreakpadRegistration(false); + recorder.RecordBreakpadHasDebugger(true); + recorder.RecordBreakpadHasDebugger(false); + } + + { + StabilityMetricsProvider stability_provider(&prefs_); + MetricsProvider* provider = &stability_provider; + SystemProfileProto system_profile; + provider->ProvideStabilityMetrics(&system_profile); + + const SystemProfileProto_Stability& stability = system_profile.stability(); + // Initial log metrics: only expected if non-zero. + EXPECT_EQ(1, stability.launch_count()); + EXPECT_EQ(1, stability.crash_count()); + EXPECT_EQ(1, stability.incomplete_shutdown_count()); + EXPECT_EQ(1, stability.breakpad_registration_success_count()); + EXPECT_EQ(1, stability.breakpad_registration_failure_count()); + EXPECT_EQ(1, stability.debugger_present_count()); + EXPECT_EQ(1, stability.debugger_not_present_count()); + } +} + +} // namespace metrics
diff --git a/components/ntp_snippets/remote/remote_suggestion_unittest.cc b/components/ntp_snippets/remote/remote_suggestion_unittest.cc index e28cf28..433dd40 100644 --- a/components/ntp_snippets/remote/remote_suggestion_unittest.cc +++ b/components/ntp_snippets/remote/remote_suggestion_unittest.cc
@@ -433,7 +433,7 @@ proto.set_score(0.1f); proto.set_dismissed(false); proto.set_remote_category_id(1); - auto source = proto.add_sources(); + auto* source = proto.add_sources(); source->set_url("http://cool-suggestions.com/"); source->set_publisher_name("Great Suggestions Inc."); source->set_amp_url("http://cdn.ampproject.org/c/foo/");
diff --git a/components/ntp_snippets/remote/scheduling_remote_suggestions_provider.cc b/components/ntp_snippets/remote/scheduling_remote_suggestions_provider.cc index deb218a..d4ec38e 100644 --- a/components/ntp_snippets/remote/scheduling_remote_suggestions_provider.cc +++ b/components/ntp_snippets/remote/scheduling_remote_suggestions_provider.cc
@@ -539,8 +539,8 @@ std::set<TriggerType> enabled_types; for (const auto& token : tokens) { - auto it = std::find(std::begin(kTriggerTypeNames), - std::end(kTriggerTypeNames), token); + auto** it = std::find(std::begin(kTriggerTypeNames), + std::end(kTriggerTypeNames), token); if (it == std::end(kTriggerTypeNames)) { DLOG(WARNING) << "Failed to parse variation param " << kTriggerTypesParamName << " with string value "
diff --git a/components/ntp_tiles/webui/ntp_tiles_internals_message_handler.cc b/components/ntp_tiles/webui/ntp_tiles_internals_message_handler.cc index e87440e2..43a90e9 100644 --- a/components/ntp_tiles/webui/ntp_tiles_internals_message_handler.cc +++ b/components/ntp_tiles/webui/ntp_tiles_internals_message_handler.cc
@@ -177,7 +177,7 @@ } if (most_visited_sites_->DoesSourceExist(NTPTileSource::POPULAR)) { - auto popular_sites = most_visited_sites_->popular_sites(); + auto* popular_sites = most_visited_sites_->popular_sites(); value.SetString("popular.url", popular_sites->GetURLToFetch().spec()); value.SetString("popular.country", popular_sites->GetCountryToFetch()); value.SetString("popular.version", popular_sites->GetVersionToFetch());
diff --git a/components/omnibox/browser/history_quick_provider_performance_unittest.cc b/components/omnibox/browser/history_quick_provider_performance_unittest.cc index a682703..f15f305 100644 --- a/components/omnibox/browser/history_quick_provider_performance_unittest.cc +++ b/components/omnibox/browser/history_quick_provider_performance_unittest.cc
@@ -148,7 +148,7 @@ void HQPPerfTestOnePopularURL::PrintMeasurements( const std::string& trace_name, const std::vector<base::TimeDelta>& measurements) { - auto test_info = ::testing::UnitTest::GetInstance()->current_test_info(); + auto* test_info = ::testing::UnitTest::GetInstance()->current_test_info(); std::string durations; for (const auto& measurement : measurements)
diff --git a/components/password_manager/content/browser/credential_manager_impl.cc b/components/password_manager/content/browser/credential_manager_impl.cc index 7c01bea..fcd6940a 100644 --- a/components/password_manager/content/browser/credential_manager_impl.cc +++ b/components/password_manager/content/browser/credential_manager_impl.cc
@@ -104,8 +104,7 @@ // If this is a federated credential, check it against the federated matches // produced by the PasswordFormManager. If a match is found, update it and // return. - for (const auto& match : - form_manager_->form_fetcher()->GetFederatedMatches()) { + for (auto* match : form_manager_->form_fetcher()->GetFederatedMatches()) { if (match->username_value == form.username_value && match->federation_origin.IsSameOriginWith(form.federation_origin)) { form_manager_->Update(*match);
diff --git a/components/password_manager/core/browser/password_form_manager.cc b/components/password_manager/core/browser/password_form_manager.cc index f6670796..8c6eb9e2 100644 --- a/components/password_manager/core/browser/password_form_manager.cc +++ b/components/password_manager/core/browser/password_form_manager.cc
@@ -1288,7 +1288,7 @@ DCHECK(best_matches_.end() != updated_password_it); const base::string16& old_password = updated_password_it->second->password_value; - for (const auto& not_best_match : not_best_matches_) { + for (auto* not_best_match : not_best_matches_) { if (not_best_match->username_value == pending_credentials_.username_value && not_best_match->password_value == old_password) {
diff --git a/components/payments/payment_request.cc b/components/payments/payment_request.cc index 9ea28a8..0ad6167 100644 --- a/components/payments/payment_request.cc +++ b/components/payments/payment_request.cc
@@ -31,7 +31,8 @@ manager_(manager), binding_(this, std::move(request)), selected_shipping_profile_(nullptr), - selected_contact_profile_(nullptr) { + selected_contact_profile_(nullptr), + selected_credit_card_(nullptr) { // OnConnectionTerminated will be called when the Mojo pipe is closed. This // will happen as a result of many renderer-side events (both successful and // erroneous in nature). @@ -128,20 +129,8 @@ return contact_profiles_; } -autofill::CreditCard* PaymentRequest::GetCurrentlySelectedCreditCard() { - // TODO(anthonyvd): Change this code to prioritize server cards and implement - // a way to modify this function's return value. - const std::vector<autofill::CreditCard*> cards = - personal_data_manager()->GetCreditCardsToSuggest(); - - auto first_complete_card = std::find_if( - cards.begin(), - cards.end(), - [] (autofill::CreditCard* card) { - return card->IsValid(); - }); - - return first_complete_card == cards.end() ? nullptr : *first_complete_card; +const std::vector<autofill::CreditCard*>& PaymentRequest::credit_cards() { + return credit_cards_; } void PaymentRequest::PopulateProfileCache() { @@ -150,7 +139,7 @@ // PaymentRequest may outlive the Profiles returned by the Data Manager. // Thus, we store copies, and return a vector of pointers to these copies - // whenever Profiles are requested. + // whenever Profiles are requested. The same is true for credit cards. for (size_t i = 0; i < profiles.size(); i++) { profile_cache_.push_back( base::MakeUnique<autofill::AutofillProfile>(*profiles[i])); @@ -160,6 +149,13 @@ shipping_profiles_.push_back(profile_cache_[i].get()); contact_profiles_.push_back(profile_cache_[i].get()); } + + const std::vector<autofill::CreditCard*>& cards = + personal_data_manager()->GetCreditCardsToSuggest(); + for (autofill::CreditCard* card : cards) { + card_cache_.push_back(base::MakeUnique<autofill::CreditCard>(*card)); + credit_cards_.push_back(card_cache_.back().get()); + } } void PaymentRequest::SetDefaultProfileSelections() { @@ -168,6 +164,16 @@ if (!contact_profiles().empty()) set_selected_contact_profile(contact_profiles()[0]); + + // TODO(anthonyvd): Change this code to prioritize server cards and implement + // a way to modify this function's return value. + const std::vector<autofill::CreditCard*> cards = credit_cards(); + auto first_complete_card = + std::find_if(cards.begin(), cards.end(), + [](autofill::CreditCard* card) { return card->IsValid(); }); + + selected_credit_card_ = + first_complete_card == cards.end() ? nullptr : *first_complete_card; } void PaymentRequest::PopulateValidatedMethodData(
diff --git a/components/payments/payment_request.h b/components/payments/payment_request.h index bde05954..fcb58203 100644 --- a/components/payments/payment_request.h +++ b/components/payments/payment_request.h
@@ -91,10 +91,12 @@ selected_contact_profile_ = profile; } + const std::vector<autofill::CreditCard*>& credit_cards(); + // Returns the currently selected credit card for this PaymentRequest flow. // It's not guaranteed to be complete. Returns nullptr if there is no selected // card. - autofill::CreditCard* GetCurrentlySelectedCreditCard(); + autofill::CreditCard* selected_credit_card() { return selected_credit_card_; } autofill::PersonalDataManager* personal_data_manager() { return delegate_->GetPersonalDataManager(); @@ -111,7 +113,8 @@ // and stores copies of them, owned by this Request, in profile_cache_. void PopulateProfileCache(); - // Sets the default values for the selected Shipping and Contact profiles. + // Sets the default values for the selected Shipping and Contact profiles, as + // well as the selected Credit Card. void SetDefaultProfileSelections(); // Validates the |method_data| and fills |supported_card_networks_|. @@ -137,6 +140,9 @@ std::vector<autofill::AutofillProfile*> contact_profiles_; autofill::AutofillProfile* selected_shipping_profile_; autofill::AutofillProfile* selected_contact_profile_; + std::vector<std::unique_ptr<autofill::CreditCard>> card_cache_; + std::vector<autofill::CreditCard*> credit_cards_; + autofill::CreditCard* selected_credit_card_; DISALLOW_COPY_AND_ASSIGN(PaymentRequest); };
diff --git a/components/payments_strings.grdp b/components/payments_strings.grdp index a1d35c8..77b7791 100644 --- a/components/payments_strings.grdp +++ b/components/payments_strings.grdp
@@ -184,6 +184,9 @@ <message name="IDS_PAYMENTS_UNSUPPORTED_SHIPPING_ADDRESS" desc="Text implying that a user needs to pick a different shipping address, because the currently selected address is not supported. Shipping is typically used for packages." formatter_data="android_java"> Unsupported shipping address. Select a different address. </message> + <message name="IDS_PAYMENTS_UNSUPPORTED_SHIPPING_OPTION" desc="Text implying that a user needs to pick a different shipping option, because the currently selected option is not supported. Shipping is typically used for packages." formatter_data="android_java"> + That shipping option isn’t available. Try a different option. + </message> <!-- Delivery address in web payments API --> <message name="IDS_PAYMENTS_DELIVERY_SUMMARY_LABEL" desc="The title for the section of delivery information. Delivery is commonly faster than shipping. For example, it might be used for food delivery." formatter_data="android_java"> @@ -201,6 +204,9 @@ <message name="IDS_PAYMENTS_UNSUPPORTED_DELIVERY_ADDRESS" desc="Text implying that a user needs to pick a different delivery address, because the currently selected address is not supported. Delivery is commonly faster than shipping. For example, it might be used for food delivery." formatter_data="android_java"> Unsupported delivery address. Select a different address. </message> + <message name="IDS_PAYMENTS_UNSUPPORTED_DELIVERY_OPTION" desc="Text implying that a user needs to pick a different delivery option, because the currently selected option is not supported. Delivery is commonly faster than shipping. For example, it might be used for food delivery." formatter_data="android_java"> + That delivery option isn’t available. Try a different option. + </message> <!-- Pickup address in web payments API --> <message name="IDS_PAYMENTS_PICKUP_SUMMARY_LABEL" desc="The title for the section of pickup information. For example, this could be the address for laundry pickup." formatter_data="android_java"> @@ -218,6 +224,9 @@ <message name="IDS_PAYMENTS_UNSUPPORTED_PICKUP_ADDRESS" desc="Text implying that a user needs to choose a different pickup address, because the currently selected address is not supported. This address can be used, for example, for laundry pickup." formatter_data="android_java"> Unsupported pickup address. Select a different address. </message> + <message name="IDS_PAYMENTS_UNSUPPORTED_PICKUP_OPTION" desc="Text implying that a user needs to choose a different pickup option, because the currently selected option is not supported. This option can be used, for example, for laundry pickup." formatter_data="android_java"> + That pickup option isn’t available. Try a different option. + </message> <message name="IDS_PAYMENTS_ANDROID_APP_ERROR" desc="Error message that is shown when an Android payment application fails to start." formatter_data="android_java"> Unable to launch payment app. </message>
diff --git a/components/physical_web_ui_strings.grdp b/components/physical_web_ui_strings.grdp index cc34d51..cc5e09f 100644 --- a/components/physical_web_ui_strings.grdp +++ b/components/physical_web_ui_strings.grdp
@@ -3,4 +3,10 @@ <message name="IDS_PHYSICAL_WEB_UI_TITLE" desc="Title of a built-in page that displays a list of Physical Web URLs (URLs broadcast by nearby devices)."> Physical Web </message> + <message name="IDS_PHYSICAL_WEB_UI_EMPTY_MESSAGE" desc="The message displayed in place of a list of nearby URLs when there are no URLs to display."> + No Physical Web pages to show + </message> + <message name="IDS_PHYSICAL_WEB_UI_SCANNING_MESSAGE" desc="The message displayed in place of a list of nearby URLs while still scanning for nearby URLs."> + Looking for nearby Physical Web pages + </message> </grit-part>
diff --git a/components/policy/core/common/policy_service_impl.cc b/components/policy/core/common/policy_service_impl.cc index afdcffb0..53cdc09 100644 --- a/components/policy/core/common/policy_service_impl.cc +++ b/components/policy/core/common/policy_service_impl.cc
@@ -78,7 +78,7 @@ for (int domain = 0; domain < POLICY_DOMAIN_SIZE; ++domain) initialization_complete_[domain] = true; providers_ = providers; - for (auto provider : providers) { + for (auto* provider : providers) { provider->AddObserver(this); for (int domain = 0; domain < POLICY_DOMAIN_SIZE; ++domain) { initialization_complete_[domain] &= @@ -92,7 +92,7 @@ PolicyServiceImpl::~PolicyServiceImpl() { DCHECK(thread_checker_.CalledOnValidThread()); - for (auto provider : providers_) + for (auto* provider : providers_) provider->RemoveObserver(this); } @@ -147,9 +147,9 @@ } else { // Some providers might invoke OnUpdatePolicy synchronously while handling // RefreshPolicies. Mark all as pending before refreshing. - for (auto provider : providers_) + for (auto* provider : providers_) refresh_pending_.insert(provider); - for (auto provider : providers_) + for (auto* provider : providers_) provider->RefreshPolicies(); } } @@ -188,7 +188,7 @@ // Merge from each provider in their order of priority. const PolicyNamespace chrome_namespace(POLICY_DOMAIN_CHROME, std::string()); PolicyBundle bundle; - for (auto provider : providers_) { + for (auto* provider : providers_) { PolicyBundle provided_bundle; provided_bundle.CopyFrom(provider->policies()); RemapProxyPolicies(&provided_bundle.Get(chrome_namespace)); @@ -248,7 +248,7 @@ PolicyDomain policy_domain = static_cast<PolicyDomain>(domain); bool all_complete = true; - for (auto provider : providers_) { + for (auto* provider : providers_) { if (!provider->IsInitializationComplete(policy_domain)) { all_complete = false; break;
diff --git a/components/precache/core/precache_fetcher.cc b/components/precache/core/precache_fetcher.cc index 0bc2e1b..e84c4d5 100644 --- a/components/precache/core/precache_fetcher.cc +++ b/components/precache/core/precache_fetcher.cc
@@ -486,12 +486,12 @@ unfinished_work_->add_top_host()->set_hostname(top_host.hostname); } for (const auto& resource : resources_fetching_) { - auto new_resource = unfinished_work_->add_resource(); + auto* new_resource = unfinished_work_->add_resource(); new_resource->set_url(resource.url.spec()); new_resource->set_top_host_name(resource.referrer); } for (const auto& resource : resources_to_fetch_) { - auto new_resource = unfinished_work_->add_resource(); + auto* new_resource = unfinished_work_->add_resource(); new_resource->set_url(resource.url.spec()); new_resource->set_top_host_name(resource.referrer); }
diff --git a/components/renderer_context_menu/render_view_context_menu_base.cc b/components/renderer_context_menu/render_view_context_menu_base.cc index a3e0e50..2b7e0ca 100644 --- a/components/renderer_context_menu/render_view_context_menu_base.cc +++ b/components/renderer_context_menu/render_view_context_menu_base.cc
@@ -393,11 +393,10 @@ if (!extra_headers.empty()) open_url_params.extra_headers = extra_headers; - WebContents* new_contents = source_web_contents_->OpenURL(open_url_params); - if (!new_contents) - return; + open_url_params.source_render_process_id = render_process_id_; + open_url_params.source_render_frame_id = render_frame_id_; - NotifyURLOpened(url, new_contents); + source_web_contents_->OpenURL(open_url_params); } bool RenderViewContextMenuBase::IsCustomItemChecked(int id) const {
diff --git a/components/renderer_context_menu/render_view_context_menu_base.h b/components/renderer_context_menu/render_view_context_menu_base.h index 84fcfe5..849b29c3 100644 --- a/components/renderer_context_menu/render_view_context_menu_base.h +++ b/components/renderer_context_menu/render_view_context_menu_base.h
@@ -142,8 +142,6 @@ // Subclasses should send notification. virtual void NotifyMenuShown() = 0; - virtual void NotifyURLOpened(const GURL& url, - content::WebContents* new_contents) = 0; // TODO(oshima): Remove this. virtual void AppendPlatformEditableItems() {}
diff --git a/components/search_engines/default_search_policy_handler_unittest.cc b/components/search_engines/default_search_policy_handler_unittest.cc index 6db8390..70d8a83 100644 --- a/components/search_engines/default_search_policy_handler_unittest.cc +++ b/components/search_engines/default_search_policy_handler_unittest.cc
@@ -167,7 +167,7 @@ PolicyMap policy; BuildDefaultSearchPolicy(&policy); - for (auto policy_name : kPolicyNamesToCheck) { + for (auto* policy_name : kPolicyNamesToCheck) { // Check that policy can be successfully applied first. UpdateProviderPolicy(policy); const base::Value* temp = nullptr;
diff --git a/components/subresource_filter/content/browser/content_subresource_filter_driver_factory_unittest.cc b/components/subresource_filter/content/browser/content_subresource_filter_driver_factory_unittest.cc index 7bdebd6..231c7aef 100644 --- a/components/subresource_filter/content/browser/content_subresource_filter_driver_factory_unittest.cc +++ b/components/subresource_filter/content/browser/content_subresource_filter_driver_factory_unittest.cc
@@ -733,7 +733,7 @@ "chrome-extension://some-extension", "file:///var/www/index.html"}; const char* supported_urls[] = {"http://example.test", "https://example.test"}; - for (const auto url : unsupported_urls) { + for (auto* url : unsupported_urls) { SCOPED_TRACE(url); RedirectChainMatchPattern expected_pattern = EMPTY; NavigateAndExpectActivation( @@ -742,7 +742,7 @@ ? ActivationDecision::ACTIVATION_DISABLED : ActivationDecision::UNSUPPORTED_SCHEME); } - for (const auto url : supported_urls) { + for (auto* url : supported_urls) { SCOPED_TRACE(url); RedirectChainMatchPattern expected_pattern = test_data.url_matches_activation_list ? NO_REDIRECTS_HIT : EMPTY;
diff --git a/components/subresource_filter/core/common/first_party_origin_unittest.cc b/components/subresource_filter/core/common/first_party_origin_unittest.cc index 02ba302..b8f02e1 100644 --- a/components/subresource_filter/core/common/first_party_origin_unittest.cc +++ b/components/subresource_filter/core/common/first_party_origin_unittest.cc
@@ -72,7 +72,7 @@ }; FirstPartyOrigin first_party(url::Origin(GURL("https://example.com"))); - for (const auto& url_string : kUrls) { + for (auto* url_string : kUrls) { GURL url(url_string); EXPECT_TRUE(FirstPartyOrigin::IsThirdParty(url, first_party.origin())); EXPECT_TRUE(first_party.IsThirdParty(url));
diff --git a/components/subresource_filter/core/common/test_ruleset_creator.cc b/components/subresource_filter/core/common/test_ruleset_creator.cc index 81aabf8..d87cf1b4 100644 --- a/components/subresource_filter/core/common/test_ruleset_creator.cc +++ b/components/subresource_filter/core/common/test_ruleset_creator.cc
@@ -41,7 +41,7 @@ ruleset_writer.AddUrlRule(rule); ruleset_writer.Finish(); - auto data = reinterpret_cast<const uint8_t*>(ruleset_contents.data()); + auto* data = reinterpret_cast<const uint8_t*>(ruleset_contents.data()); return std::vector<uint8_t>(data, data + ruleset_contents.size()); }
diff --git a/components/toolbar/toolbar_model_impl.cc b/components/toolbar/toolbar_model_impl.cc index d2041ee..017c5a9c 100644 --- a/components/toolbar/toolbar_model_impl.cc +++ b/components/toolbar/toolbar_model_impl.cc
@@ -73,7 +73,7 @@ const gfx::VectorIcon& ToolbarModelImpl::GetVectorIcon() const { #if !defined(OS_ANDROID) && !defined(OS_IOS) - const auto icon_override = delegate_->GetVectorIconOverride(); + auto* const icon_override = delegate_->GetVectorIconOverride(); if (icon_override) return *icon_override;
diff --git a/components/tracing/test/proto_zero_generation_unittest.cc b/components/tracing/test/proto_zero_generation_unittest.cc index f34b71b..75c4b210 100644 --- a/components/tracing/test/proto_zero_generation_unittest.cc +++ b/components/tracing/test/proto_zero_generation_unittest.cc
@@ -67,7 +67,7 @@ }; TEST_F(ProtoZeroConformanceTest, SimpleFieldsNoNesting) { - auto msg = CreateMessage<pbtest::EveryField>(); + auto* msg = CreateMessage<pbtest::EveryField>(); msg->set_field_int32(-1); msg->set_field_int64(-333123456789ll); @@ -126,7 +126,7 @@ } TEST_F(ProtoZeroConformanceTest, NestedMessages) { - auto msg_a = CreateMessage<pbtest::NestedA>(); + auto* msg_a = CreateMessage<pbtest::NestedA>(); pbtest::NestedA::NestedB* msg_b = msg_a->add_repeated_a(); pbtest::NestedA::NestedB::NestedC* msg_c = msg_b->set_value_b();
diff --git a/components/update_client/update_response.cc b/components/update_client/update_response.cc index f9eefe8..7f621298 100644 --- a/components/update_client/update_response.cc +++ b/components/update_client/update_response.cc
@@ -302,7 +302,7 @@ static const char* attrs[] = {UpdateResponse::Result::kCohort, UpdateResponse::Result::kCohortHint, UpdateResponse::Result::kCohortName}; - for (const auto& attr : attrs) { + for (auto* attr : attrs) { auto value = GetAttributePtr(app, attr); if (value) result->cohort_attrs.insert({attr, *value});
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index 51ca75f..968260b 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -1928,6 +1928,8 @@ "compositor/gpu_process_transport_factory.h", "compositor/gpu_surfaceless_browser_compositor_output_surface.cc", "compositor/gpu_surfaceless_browser_compositor_output_surface.h", + "compositor/gpu_vsync_begin_frame_source.cc", + "compositor/gpu_vsync_begin_frame_source.h", "compositor/image_transport_factory.cc", "compositor/image_transport_factory.h", "compositor/offscreen_browser_compositor_output_surface.cc",
diff --git a/content/browser/accessibility/ax_platform_position.cc b/content/browser/accessibility/ax_platform_position.cc index 9b90de31..3c8c460c 100644 --- a/content/browser/accessibility/ax_platform_position.cc +++ b/content/browser/accessibility/ax_platform_position.cc
@@ -87,7 +87,7 @@ return nullptr; } - auto manager = BrowserAccessibilityManager::FromID(tree_id); + auto* manager = BrowserAccessibilityManager::FromID(tree_id); if (!manager) return nullptr; return manager->GetFromID(node_id);
diff --git a/content/browser/android/OWNERS b/content/browser/android/OWNERS index 70bfe8db..482db7f 100644 --- a/content/browser/android/OWNERS +++ b/content/browser/android/OWNERS
@@ -1,3 +1,5 @@ skyostil@chromium.org tedchoc@chromium.org yfriedman@chromium.org + +# COMPONENT: Content>WebApps
diff --git a/content/browser/android/content_view_core_impl.cc b/content/browser/android/content_view_core_impl.cc index 41f7930..b1f3ee5 100644 --- a/content/browser/android/content_view_core_impl.cc +++ b/content/browser/android/content_view_core_impl.cc
@@ -966,22 +966,20 @@ : rwhv->OnTouchEvent(event); } -jboolean ContentViewCoreImpl::SendMouseEvent( - JNIEnv* env, - const JavaParamRef<jobject>& obj, - jlong time_ms, - jint android_action, - jfloat x, - jfloat y, - jint pointer_id, - jfloat pressure, - jfloat orientation, - jfloat tilt, - jint android_changed_button, - jint android_button_state, - jint android_meta_state, - jint android_tool_type) { - +jboolean ContentViewCoreImpl::SendMouseEvent(JNIEnv* env, + const JavaParamRef<jobject>& obj, + jlong time_ms, + jint android_action, + jfloat x, + jfloat y, + jint pointer_id, + jfloat pressure, + jfloat orientation, + jfloat tilt, + jint android_action_button, + jint android_button_state, + jint android_meta_state, + jint android_tool_type) { RenderWidgetHostViewAndroid* rwhv = GetRenderWidgetHostViewAndroid(); if (!rwhv) return false; @@ -1012,7 +1010,7 @@ // Note: This relies on identical button enum values in MotionEvent and // MotionEventAndroid. - rwhv->SendMouseEvent(motion_event, android_changed_button); + rwhv->SendMouseEvent(motion_event, android_action_button); return true; }
diff --git a/content/browser/android/content_view_core_impl.h b/content/browser/android/content_view_core_impl.h index 603fd441..1241f11 100644 --- a/content/browser/android/content_view_core_impl.h +++ b/content/browser/android/content_view_core_impl.h
@@ -130,7 +130,7 @@ jfloat pressure, jfloat orientation, jfloat tilt, - jint android_changed_button, + jint android_action_button, jint android_button_state, jint android_meta_state, jint tool_type);
diff --git a/content/browser/compositor/gpu_browser_compositor_output_surface.cc b/content/browser/compositor/gpu_browser_compositor_output_surface.cc index 8ad8384..d663726 100644 --- a/content/browser/compositor/gpu_browser_compositor_output_surface.cc +++ b/content/browser/compositor/gpu_browser_compositor_output_surface.cc
@@ -42,6 +42,14 @@ UpdateVSyncParametersCallback()); } +void GpuBrowserCompositorOutputSurface::SetNeedsVSync(bool needs_vsync) { +#if defined(OS_WIN) + GetCommandBufferProxy()->SetNeedsVSync(needs_vsync); +#else + NOTREACHED(); +#endif // defined(OS_WIN) +} + void GpuBrowserCompositorOutputSurface::OnGpuSwapBuffersCompleted( const std::vector<ui::LatencyInfo>& latency_info, gfx::SwapResult result, @@ -96,22 +104,23 @@ cc::OutputSurfaceFrame frame) { GetCommandBufferProxy()->SetLatencyInfo(frame.latency_info); - gfx::Rect swap_rect = frame.sub_buffer_rect; gfx::Size surface_size = frame.size; if (reflector_) { - if (swap_rect == gfx::Rect(surface_size)) { + if (frame.sub_buffer_rect) { + reflector_texture_->CopyTextureSubImage(*frame.sub_buffer_rect); + reflector_->OnSourcePostSubBuffer(*frame.sub_buffer_rect, surface_size); + } else { reflector_texture_->CopyTextureFullImage(surface_size); reflector_->OnSourceSwapBuffers(surface_size); - } else { - reflector_texture_->CopyTextureSubImage(swap_rect); - reflector_->OnSourcePostSubBuffer(swap_rect, surface_size); } } - if (swap_rect == gfx::Rect(frame.size)) + if (frame.sub_buffer_rect) { + context_provider_->ContextSupport()->PartialSwapBuffers( + *frame.sub_buffer_rect); + } else { context_provider_->ContextSupport()->Swap(); - else - context_provider_->ContextSupport()->PartialSwapBuffers(swap_rect); + } } uint32_t GpuBrowserCompositorOutputSurface::GetFramebufferCopyTextureFormat() {
diff --git a/content/browser/compositor/gpu_browser_compositor_output_surface.h b/content/browser/compositor/gpu_browser_compositor_output_surface.h index c2505264..09fd1ef8 100644 --- a/content/browser/compositor/gpu_browser_compositor_output_surface.h +++ b/content/browser/compositor/gpu_browser_compositor_output_surface.h
@@ -11,6 +11,7 @@ #include "base/memory/weak_ptr.h" #include "build/build_config.h" #include "content/browser/compositor/browser_compositor_output_surface.h" +#include "content/browser/compositor/gpu_vsync_begin_frame_source.h" #include "ui/gfx/swap_result.h" namespace display_compositor { @@ -33,8 +34,8 @@ // Adapts a WebGraphicsContext3DCommandBufferImpl into a // cc::OutputSurface that also handles vsync parameter updates // arriving from the GPU process. -class GpuBrowserCompositorOutputSurface - : public BrowserCompositorOutputSurface { +class GpuBrowserCompositorOutputSurface : public BrowserCompositorOutputSurface, + public GpuVSyncControl { public: GpuBrowserCompositorOutputSurface( scoped_refptr<ui::ContextProviderCommandBuffer> context, @@ -76,6 +77,9 @@ unsigned GetOverlayTextureId() const override; bool SurfaceIsSuspendForRecycle() const override; + // GpuVSyncControl implementation. + void SetNeedsVSync(bool needs_vsync) override; + protected: gpu::CommandBufferProxyImpl* GetCommandBufferProxy();
diff --git a/content/browser/compositor/gpu_process_transport_factory.cc b/content/browser/compositor/gpu_process_transport_factory.cc index ffe7e05..50a66bb 100644 --- a/content/browser/compositor/gpu_process_transport_factory.cc +++ b/content/browser/compositor/gpu_process_transport_factory.cc
@@ -58,6 +58,7 @@ #include "ui/display/types/display_snapshot.h" #include "ui/gfx/geometry/size.h" #include "ui/gfx/switches.h" +#include "ui/gl/gl_switches.h" #if defined(USE_AURA) #include "content/browser/compositor/mus_browser_compositor_output_surface.h" @@ -66,6 +67,7 @@ #endif #if defined(OS_WIN) +#include "base/win/windows_version.h" #include "components/display_compositor/compositor_overlay_candidate_validator_win.h" #include "content/browser/compositor/software_output_device_win.h" #include "ui/gfx/win/rendering_window_manager.h" @@ -111,6 +113,17 @@ return service_manager::ServiceManagerIsRemote(); } +bool IsGpuVSyncSignalSupported() { +#if defined(OS_WIN) + // TODO(stanisc): http://crbug.com/467617 Limit to Windows 8+ for now because + // of locking issue caused by waiting for VSync on Win7. + return base::win::GetVersion() >= base::win::VERSION_WIN8 && + base::FeatureList::IsEnabled(features::kD3DVsync); +#else + return false; +#endif // defined(OS_WIN) +} + scoped_refptr<ui::ContextProviderCommandBuffer> CreateContextCommon( scoped_refptr<gpu::GpuChannelHost> gpu_channel_host, gpu::SurfaceHandle surface_handle, @@ -171,7 +184,10 @@ struct GpuProcessTransportFactory::PerCompositorData { gpu::SurfaceHandle surface_handle = gpu::kNullSurfaceHandle; BrowserCompositorOutputSurface* display_output_surface = nullptr; - std::unique_ptr<cc::SyntheticBeginFrameSource> begin_frame_source; + // Either |synthetic_begin_frame_source| or |gpu_vsync_begin_frame_source| is + // valid but not both at the same time. + std::unique_ptr<cc::SyntheticBeginFrameSource> synthetic_begin_frame_source; + std::unique_ptr<GpuVSyncBeginFrameSource> gpu_vsync_begin_frame_source; ReflectorImpl* reflector = nullptr; std::unique_ptr<cc::Display> display; bool output_is_secure = false; @@ -464,20 +480,10 @@ } } - std::unique_ptr<cc::SyntheticBeginFrameSource> synthetic_begin_frame_source; - if (!compositor->GetRendererSettings().disable_display_vsync) { - synthetic_begin_frame_source.reset(new cc::DelayBasedBeginFrameSource( - base::MakeUnique<cc::DelayBasedTimeSource>( - compositor->task_runner().get()))); - } else { - synthetic_begin_frame_source.reset(new cc::BackToBackBeginFrameSource( - base::MakeUnique<cc::DelayBasedTimeSource>( - compositor->task_runner().get()))); - } - cc::BeginFrameSource* begin_frame_source = synthetic_begin_frame_source.get(); - BrowserCompositorOutputSurface::UpdateVSyncParametersCallback vsync_callback = base::Bind(&ui::Compositor::SetDisplayVSyncParameters, compositor); + cc::BeginFrameSource* begin_frame_source = nullptr; + GpuVSyncControl* gpu_vsync_control = nullptr; std::unique_ptr<BrowserCompositorOutputSurface> display_output_surface; #if defined(ENABLE_VULKAN) @@ -517,13 +523,15 @@ CreateOverlayCandidateValidator(compositor->widget()), GetGpuMemoryBufferManager()); #else - display_output_surface = + auto gpu_output_surface = base::MakeUnique<GpuSurfacelessBrowserCompositorOutputSurface>( context_provider, data->surface_handle, vsync_callback, CreateOverlayCandidateValidator(compositor->widget()), GL_TEXTURE_2D, GL_RGB, display::DisplaySnapshot::PrimaryFormat(), GetGpuMemoryBufferManager()); + gpu_vsync_control = gpu_output_surface.get(); + display_output_surface = std::move(gpu_output_surface); #endif } else { std::unique_ptr<display_compositor::CompositorOverlayCandidateValidator> @@ -535,22 +543,22 @@ validator = CreateOverlayCandidateValidator(compositor->widget()); #endif if (!use_mus) { - display_output_surface = + auto gpu_output_surface = base::MakeUnique<GpuBrowserCompositorOutputSurface>( context_provider, vsync_callback, std::move(validator)); + gpu_vsync_control = gpu_output_surface.get(); + display_output_surface = std::move(gpu_output_surface); } else { #if defined(USE_AURA) - std::unique_ptr<MusBrowserCompositorOutputSurface> mus_output_surface; aura::WindowTreeHost* host = aura::WindowTreeHost::GetForAcceleratedWidget( compositor->widget()); - mus_output_surface = + auto mus_output_surface = base::MakeUnique<MusBrowserCompositorOutputSurface>( host->window(), context_provider, GetGpuMemoryBufferManager(), vsync_callback, std::move(validator)); // We use the ExternalBeginFrameSource provided by the output surface // instead of our own synthetic one. - synthetic_begin_frame_source.reset(); begin_frame_source = mus_output_surface->GetBeginFrameSource(); DCHECK(begin_frame_source); display_output_surface = std::move(mus_output_surface); @@ -562,7 +570,31 @@ } } - data->display_output_surface = display_output_surface.get(); + std::unique_ptr<cc::SyntheticBeginFrameSource> synthetic_begin_frame_source; + std::unique_ptr<GpuVSyncBeginFrameSource> gpu_vsync_begin_frame_source; + + if (!begin_frame_source) { + if (!compositor->GetRendererSettings().disable_display_vsync) { + if (gpu_vsync_control && IsGpuVSyncSignalSupported()) { + gpu_vsync_begin_frame_source = + base::MakeUnique<GpuVSyncBeginFrameSource>(gpu_vsync_control); + begin_frame_source = gpu_vsync_begin_frame_source.get(); + } else { + synthetic_begin_frame_source = + base::MakeUnique<cc::DelayBasedBeginFrameSource>( + base::MakeUnique<cc::DelayBasedTimeSource>( + compositor->task_runner().get())); + begin_frame_source = synthetic_begin_frame_source.get(); + } + } else { + synthetic_begin_frame_source = + base::MakeUnique<cc::BackToBackBeginFrameSource>( + base::MakeUnique<cc::DelayBasedTimeSource>( + compositor->task_runner().get())); + begin_frame_source = synthetic_begin_frame_source.get(); + } + } + if (data->reflector) data->reflector->OnSourceSurfaceReady(data->display_output_surface); @@ -582,9 +614,10 @@ begin_frame_source, std::move(display_output_surface), std::move(scheduler), base::MakeUnique<cc::TextureMailboxDeleter>( compositor->task_runner().get())); - // Note that we are careful not to destroy a prior |data->begin_frame_source| + // Note that we are careful not to destroy prior BeginFrameSource objects // until we have reset |data->display|. - data->begin_frame_source = std::move(synthetic_begin_frame_source); + data->synthetic_begin_frame_source = std::move(synthetic_begin_frame_source); + data->gpu_vsync_begin_frame_source = std::move(gpu_vsync_begin_frame_source); // The |delegated_output_surface| is given back to the compositor, it // delegates to the Display as its root surface. Importantly, it shares the @@ -742,8 +775,8 @@ return; PerCompositorData* data = it->second.get(); DCHECK(data); - if (data->begin_frame_source) - data->begin_frame_source->SetAuthoritativeVSyncInterval(interval); + if (data->synthetic_begin_frame_source) + data->synthetic_begin_frame_source->SetAuthoritativeVSyncInterval(interval); } void GpuProcessTransportFactory::SetDisplayVSyncParameters( @@ -755,8 +788,12 @@ return; PerCompositorData* data = it->second.get(); DCHECK(data); - if (data->begin_frame_source) - data->begin_frame_source->OnUpdateVSyncParameters(timebase, interval); + if (data->synthetic_begin_frame_source) { + data->synthetic_begin_frame_source->OnUpdateVSyncParameters(timebase, + interval); + } else if (data->gpu_vsync_begin_frame_source) { + data->gpu_vsync_begin_frame_source->OnVSync(timebase, interval); + } } void GpuProcessTransportFactory::SetOutputIsSecure(ui::Compositor* compositor,
diff --git a/content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.cc b/content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.cc index a6e74153..e0464b67 100644 --- a/content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.cc +++ b/content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.cc
@@ -73,7 +73,8 @@ // TODO(ccameron): What if a swap comes again before OnGpuSwapBuffersCompleted // happens, we'd see the wrong swap size there? swap_size_ = reshape_size_; - buffer_queue_->SwapBuffers(frame.sub_buffer_rect); + buffer_queue_->SwapBuffers(frame.sub_buffer_rect ? *frame.sub_buffer_rect + : gfx::Rect(swap_size_)); GpuBrowserCompositorOutputSurface::SwapBuffers(std::move(frame)); }
diff --git a/content/browser/compositor/gpu_vsync_begin_frame_source.cc b/content/browser/compositor/gpu_vsync_begin_frame_source.cc new file mode 100644 index 0000000..f941410 --- /dev/null +++ b/content/browser/compositor/gpu_vsync_begin_frame_source.cc
@@ -0,0 +1,44 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/compositor/gpu_vsync_begin_frame_source.h" + +namespace content { + +GpuVSyncBeginFrameSource::GpuVSyncBeginFrameSource( + GpuVSyncControl* vsync_control) + : cc::ExternalBeginFrameSource(this), + vsync_control_(vsync_control), + needs_begin_frames_(false), + next_sequence_number_(cc::BeginFrameArgs::kStartingFrameNumber) { + DCHECK(vsync_control); +} + +GpuVSyncBeginFrameSource::~GpuVSyncBeginFrameSource() = default; + +void GpuVSyncBeginFrameSource::OnVSync(base::TimeTicks timestamp, + base::TimeDelta interval) { + if (!needs_begin_frames_) + return; + + base::TimeTicks now = base::TimeTicks::Now(); + base::TimeTicks deadline = now.SnappedToNextTick(timestamp, interval); + + TRACE_EVENT1("cc", "GpuVSyncBeginFrameSource::OnVSync", "latency", + (now - timestamp).ToInternalValue()); + + next_sequence_number_++; + OnBeginFrame(cc::BeginFrameArgs::Create( + BEGINFRAME_FROM_HERE, source_id(), next_sequence_number_, timestamp, + deadline, interval, cc::BeginFrameArgs::NORMAL)); +} + +void GpuVSyncBeginFrameSource::OnNeedsBeginFrames(bool needs_begin_frames) { + needs_begin_frames_ = needs_begin_frames; + vsync_control_->SetNeedsVSync(needs_begin_frames); +} + +void GpuVSyncBeginFrameSource::OnDidFinishFrame(const cc::BeginFrameAck& ack) {} + +} // namespace content
diff --git a/content/browser/compositor/gpu_vsync_begin_frame_source.h b/content/browser/compositor/gpu_vsync_begin_frame_source.h new file mode 100644 index 0000000..a701f98 --- /dev/null +++ b/content/browser/compositor/gpu_vsync_begin_frame_source.h
@@ -0,0 +1,44 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_COMPOSITOR_GPU_VSYNC_BEGIN_FRAME_SOURCE_H_ +#define CONTENT_BROWSER_COMPOSITOR_GPU_VSYNC_BEGIN_FRAME_SOURCE_H_ + +#include "base/memory/weak_ptr.h" +#include "base/time/time.h" +#include "cc/scheduler/begin_frame_source.h" + +namespace content { + +// This class is used to control VSync production on GPU side. +class GpuVSyncControl { + public: + virtual void SetNeedsVSync(bool needs_vsync) = 0; +}; + +// This is a type of ExternalBeginFrameSource where VSync signals are +// generated externally on GPU side. +class GpuVSyncBeginFrameSource : public cc::ExternalBeginFrameSource, + cc::ExternalBeginFrameSourceClient { + public: + explicit GpuVSyncBeginFrameSource(GpuVSyncControl* vsync_control); + ~GpuVSyncBeginFrameSource() override; + + // cc::ExternalBeginFrameSourceClient implementation. + void OnNeedsBeginFrames(bool needs_begin_frames) override; + void OnDidFinishFrame(const cc::BeginFrameAck& ack) override; + + void OnVSync(base::TimeTicks timestamp, base::TimeDelta interval); + + private: + GpuVSyncControl* const vsync_control_; + bool needs_begin_frames_; + uint64_t next_sequence_number_; + + DISALLOW_COPY_AND_ASSIGN(GpuVSyncBeginFrameSource); +}; + +} // namespace content + +#endif // CONTENT_BROWSER_COMPOSITOR_GPU_VSYNC_BEGIN_FRAME_SOURCE_H_
diff --git a/content/browser/compositor/offscreen_browser_compositor_output_surface.cc b/content/browser/compositor/offscreen_browser_compositor_output_surface.cc index 8c7581c..bf2f877 100644 --- a/content/browser/compositor/offscreen_browser_compositor_output_surface.cc +++ b/content/browser/compositor/offscreen_browser_compositor_output_surface.cc
@@ -136,13 +136,12 @@ cc::OutputSurfaceFrame frame) { gfx::Size surface_size = frame.size; DCHECK(surface_size == reshape_size_); - gfx::Rect swap_rect = frame.sub_buffer_rect; if (reflector_) { - if (swap_rect == gfx::Rect(surface_size)) - reflector_->OnSourceSwapBuffers(surface_size); + if (frame.sub_buffer_rect) + reflector_->OnSourcePostSubBuffer(*frame.sub_buffer_rect, surface_size); else - reflector_->OnSourcePostSubBuffer(swap_rect, surface_size); + reflector_->OnSourceSwapBuffers(surface_size); } // TODO(oshima): sync with the reflector's SwapBuffersComplete
diff --git a/content/browser/devtools/render_frame_devtools_agent_host.cc b/content/browser/devtools/render_frame_devtools_agent_host.cc index fbd7c4a..90b18f1 100644 --- a/content/browser/devtools/render_frame_devtools_agent_host.cc +++ b/content/browser/devtools/render_frame_devtools_agent_host.cc
@@ -504,7 +504,7 @@ void RenderFrameDevToolsAgentHost::AttachSession(DevToolsSession* session) { session->SetFallThroughForNotFound(true); session->SetRenderFrameHost(handlers_frame_host_); - if (!frame_tree_node_->parent()) { + if (frame_tree_node_ && !frame_tree_node_->parent()) { session->AddHandler(base::WrapUnique(new protocol::EmulationHandler())); session->AddHandler(base::WrapUnique(new protocol::PageHandler())); session->AddHandler(base::WrapUnique(new protocol::SecurityHandler())); @@ -521,7 +521,7 @@ session->AddHandler(base::WrapUnique(new protocol::TargetHandler())); session->AddHandler(base::WrapUnique(new protocol::TracingHandler( protocol::TracingHandler::Renderer, - frame_tree_node_->frame_tree_node_id(), + frame_tree_node_ ? frame_tree_node_->frame_tree_node_id() : 0, GetIOContext()))); if (current_)
diff --git a/content/browser/frame_host/debug_urls.cc b/content/browser/frame_host/debug_urls.cc index 22e0a15c..c693078 100644 --- a/content/browser/frame_host/debug_urls.cc +++ b/content/browser/frame_host/debug_urls.cc
@@ -212,7 +212,8 @@ if (url.SchemeIs(url::kJavaScriptScheme)) return true; - return url == kChromeUIBadCastCrashURL || + return url == kChromeUICheckCrashURL || + url == kChromeUIBadCastCrashURL || url == kChromeUICrashURL || url == kChromeUIDumpURL || url == kChromeUIKillURL ||
diff --git a/content/browser/frame_host/interstitial_page_impl.cc b/content/browser/frame_host/interstitial_page_impl.cc index c3b0abb..12676d4 100644 --- a/content/browser/frame_host/interstitial_page_impl.cc +++ b/content/browser/frame_host/interstitial_page_impl.cc
@@ -526,6 +526,11 @@ } } +WebContents* InterstitialPageImpl::OpenURL(const OpenURLParams& params) { + NOTREACHED(); + return nullptr; +} + RendererPreferences InterstitialPageImpl::GetRendererPrefs( BrowserContext* browser_context) const { delegate_->OverrideRendererPrefs(&renderer_preferences_);
diff --git a/content/browser/frame_host/interstitial_page_impl.h b/content/browser/frame_host/interstitial_page_impl.h index aaf77bb5..19361d6 100644 --- a/content/browser/frame_host/interstitial_page_impl.h +++ b/content/browser/frame_host/interstitial_page_impl.h
@@ -95,6 +95,9 @@ RenderViewHost* render_view_host, const FrameHostMsg_DidCommitProvisionalLoad_Params& params); + // NavigatorDelegate implementation. + WebContents* OpenURL(const OpenURLParams& params) override; + protected: // NotificationObserver method: void Observe(int type,
diff --git a/content/browser/frame_host/navigator_delegate.h b/content/browser/frame_host/navigator_delegate.h index 101a929..c3db7d1 100644 --- a/content/browser/frame_host/navigator_delegate.h +++ b/content/browser/frame_host/navigator_delegate.h
@@ -94,9 +94,8 @@ ReloadType reload_type) {} // Opens a URL with the given parameters. See PageNavigator::OpenURL, which - // this forwards to. - virtual void RequestOpenURL(RenderFrameHostImpl* render_frame_host, - const OpenURLParams& params) {} + // this is an alias of. + virtual WebContents* OpenURL(const OpenURLParams& params) = 0; // Returns whether to continue a navigation that needs to transfer to a // different process between the load start and commit.
diff --git a/content/browser/frame_host/navigator_impl.cc b/content/browser/frame_host/navigator_impl.cc index 72bbe28..07f3cc9 100644 --- a/content/browser/frame_host/navigator_impl.cc +++ b/content/browser/frame_host/navigator_impl.cc
@@ -798,6 +798,9 @@ // RequestOpenURL and go through RequestTransferURL instead. params.source_site_instance = current_site_instance; + params.source_render_frame_id = render_frame_host->GetRoutingID(); + params.source_render_process_id = render_frame_host->GetProcess()->GetID(); + if (render_frame_host->web_ui()) { // Note that we hide the referrer for Web UI pages. We don't really want // web sites to see a referrer of "chrome://blah" (and some chrome: URLs @@ -814,7 +817,7 @@ ¶ms.referrer); if (delegate_) - delegate_->RequestOpenURL(render_frame_host, params); + delegate_->OpenURL(params); } void NavigatorImpl::RequestTransferURL(
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc index 9677e350..ce81fb1 100644 --- a/content/browser/frame_host/render_frame_host_impl.cc +++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -10,7 +10,6 @@ #include "base/bind.h" #include "base/command_line.h" #include "base/containers/hash_tables.h" -#include "base/debug/dump_without_crashing.h" #include "base/lazy_instance.h" #include "base/memory/ptr_util.h" #include "base/metrics/histogram_macros.h" @@ -1354,12 +1353,6 @@ void RenderFrameHostImpl::SetNavigationHandle( std::unique_ptr<NavigationHandleImpl> navigation_handle) { navigation_handle_ = std::move(navigation_handle); - - // TODO(clamy): Remove this debug code once we understand better how we get to - // the point of attempting to transfer a navigation from a RFH that is no - // longer active. - if (navigation_handle_ && !is_active()) - base::debug::DumpWithoutCrashing(); } std::unique_ptr<NavigationHandleImpl>
diff --git a/content/browser/indexed_db/indexed_db_transaction_coordinator.cc b/content/browser/indexed_db/indexed_db_transaction_coordinator.cc index 51ae028..83acd3e 100644 --- a/content/browser/indexed_db/indexed_db_transaction_coordinator.cc +++ b/content/browser/indexed_db/indexed_db_transaction_coordinator.cc
@@ -106,7 +106,7 @@ // data. ("Version change" transactions are exclusive, but handled by the // connection sequencing in IndexedDBDatabase.) std::set<int64_t> locked_scope; - for (const auto& transaction : started_transactions_) { + for (auto* transaction : started_transactions_) { if (transaction->mode() == blink::WebIDBTransactionModeReadWrite) { // Started read/write transactions have exclusive access to the object // stores within their scopes.
diff --git a/content/browser/loader/resource_loader.cc b/content/browser/loader/resource_loader.cc index 0a76d9c..7c707c09 100644 --- a/content/browser/loader/resource_loader.cc +++ b/content/browser/loader/resource_loader.cc
@@ -113,8 +113,8 @@ request->ssl_info().cert->os_cert_handle(), &encoded); DCHECK(rv); response->head.certificate.push_back(encoded); - for (auto& cert : - request->ssl_info().cert->GetIntermediateCertificates()) { + for (auto* cert : + request->ssl_info().cert->GetIntermediateCertificates()) { rv = net::X509Certificate::GetDEREncoded(cert, &encoded); DCHECK(rv); response->head.certificate.push_back(encoded);
diff --git a/content/browser/loader/resource_scheduler.cc b/content/browser/loader/resource_scheduler.cc index 6d68cf1c..5f8c5743 100644 --- a/content/browser/loader/resource_scheduler.cc +++ b/content/browser/loader/resource_scheduler.cc
@@ -13,6 +13,7 @@ #include "base/feature_list.h" #include "base/macros.h" #include "base/metrics/field_trial.h" +#include "base/metrics/field_trial_params.h" #include "base/metrics/histogram_macros.h" #include "base/stl_util.h" #include "base/supports_user_data.h" @@ -39,6 +40,16 @@ const base::Feature kPrioritySupportedRequestsDelayable{ "PrioritySupportedRequestsDelayable", base::FEATURE_DISABLED_BY_DEFAULT}; +// In the event that many resource requests are started quickly, this feature +// will periodically yield (e.g., delaying starting of requests) by posting a +// task and waiting for the task to run to resume. This allows other +// operations that rely on the IO thread (e.g., already running network +// requests) to make progress. +const base::Feature kNetworkSchedulerYielding{ + "NetworkSchedulerYielding", base::FEATURE_DISABLED_BY_DEFAULT}; +const char kMaxRequestsBeforeYieldingParam[] = "MaxRequestsBeforeYieldingParam"; +const int kMaxRequestsBeforeYieldingDefault = 5; + enum StartMode { START_SYNC, START_ASYNC @@ -61,6 +72,7 @@ CLIENT_KILL, SPDY_PROXY_DETECTED, REQUEST_REPRIORITIZED, + START_WAS_YIELDED, }; const char* RequestStartTriggerString(RequestStartTrigger trigger) { @@ -79,6 +91,8 @@ return "SPDY_PROXY_DETECTED"; case RequestStartTrigger::REQUEST_REPRIORITIZED: return "REQUEST_REPRIORITIZED"; + case RequestStartTrigger::START_WAS_YIELDED: + return "START_WAS_YIELDED"; } NOTREACHED(); return "Unknown"; @@ -348,7 +362,9 @@ // Each client represents a tab. class ResourceScheduler::Client { public: - explicit Client(bool priority_requests_delayable) + Client(bool priority_requests_delayable, + bool yielding_scheduler_enabled, + int max_requests_before_yielding) : is_loaded_(false), has_html_body_(false), using_spdy_proxy_(false), @@ -356,6 +372,10 @@ total_layout_blocking_count_(0), priority_requests_delayable_(priority_requests_delayable), has_pending_start_task_(false), + started_requests_since_yielding_(0), + did_scheduler_yield_(false), + yielding_scheduler_enabled_(yielding_scheduler_enabled), + max_requests_before_yielding_(max_requests_before_yielding), weak_ptr_factory_(this) {} ~Client() {} @@ -363,11 +383,14 @@ void ScheduleRequest(net::URLRequest* url_request, ScheduledResourceRequest* request) { SetRequestAttributes(request, DetermineRequestAttributes(request)); - if (ShouldStartRequest(request) == START_REQUEST) { + ShouldStartReqResult should_start = ShouldStartRequest(request); + if (should_start == START_REQUEST) { // New requests can be started synchronously without issue. StartRequest(request, START_SYNC, RequestStartTrigger::NONE); } else { pending_requests_.Insert(request); + if (should_start == YIELD_SCHEDULER) + did_scheduler_yield_ = true; } } @@ -464,6 +487,7 @@ DO_NOT_START_REQUEST_AND_STOP_SEARCHING, DO_NOT_START_REQUEST_AND_KEEP_SEARCHING, START_REQUEST, + YIELD_SCHEDULER }; void InsertInFlightRequest(ScheduledResourceRequest* request) { @@ -603,6 +627,17 @@ void StartRequest(ScheduledResourceRequest* request, StartMode start_mode, RequestStartTrigger trigger) { + started_requests_since_yielding_ += 1; + if (started_requests_since_yielding_ == 1) { + // This is the first started request since last yielding. Post a task to + // reset the counter and start any yielded tasks if necessary. We post + // this now instead of when we first yield so that if there is a pause + // between requests the counter is reset. + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, + base::Bind(&Client::ResumeIfYielded, weak_ptr_factory_.GetWeakPtr())); + } + // Only log on requests that were blocked by the ResourceScheduler. if (start_mode == START_ASYNC) { DCHECK_NE(RequestStartTrigger::NONE, trigger); @@ -666,7 +701,7 @@ if (!priority_requests_delayable_) { if (using_spdy_proxy_ && url_request.url().SchemeIs(url::kHttpScheme)) - return START_REQUEST; + return ShouldStartOrYieldRequest(); url::SchemeHostPort scheme_host_port(url_request.url()); @@ -677,12 +712,12 @@ // crbug.com/164101. Also, theoretically we should not count a // request-priority capable request against the delayable requests limit. if (http_server_properties.SupportsRequestPriority(scheme_host_port)) - return START_REQUEST; + return ShouldStartOrYieldRequest(); } // Non-delayable requests. if (!RequestAttributesAreSet(request->attributes(), kAttributeDelayable)) - return START_REQUEST; + return ShouldStartOrYieldRequest(); if (in_flight_delayable_count_ >= kMaxNumDelayableRequestsPerClient) return DO_NOT_START_REQUEST_AND_STOP_SEARCHING; @@ -717,7 +752,7 @@ } } - return START_REQUEST; + return ShouldStartOrYieldRequest(); } // It is common for a burst of messages to come from the renderer which @@ -738,6 +773,27 @@ weak_ptr_factory_.GetWeakPtr(), trigger)); } + void ResumeIfYielded() { + bool yielded = did_scheduler_yield_; + started_requests_since_yielding_ = 0; + did_scheduler_yield_ = false; + + if (yielded) + LoadAnyStartablePendingRequests(RequestStartTrigger::START_WAS_YIELDED); + } + + // For a request that is ready to start, return START_REQUEST if the + // scheduler doesn't need to yield, else YIELD_SCHEDULER. + ShouldStartReqResult ShouldStartOrYieldRequest() const { + DCHECK_GE(started_requests_since_yielding_, 0); + + if (!yielding_scheduler_enabled_ || + started_requests_since_yielding_ < max_requests_before_yielding_) { + return START_REQUEST; + } + return YIELD_SCHEDULER; + } + void LoadAnyStartablePendingRequests(RequestStartTrigger trigger) { // We iterate through all the pending requests, starting with the highest // priority one. For each entry, one of three things can happen: @@ -769,6 +825,9 @@ } else if (query_result == DO_NOT_START_REQUEST_AND_KEEP_SEARCHING) { ++request_iter; continue; + } else if (query_result == YIELD_SCHEDULER) { + did_scheduler_yield_ = true; + break; } else { DCHECK(query_result == DO_NOT_START_REQUEST_AND_STOP_SEARCHING); break; @@ -794,12 +853,32 @@ bool has_pending_start_task_; + // The number of started requests since the last ResumeIfYielded task was + // run. + int started_requests_since_yielding_; + + // If the scheduler had to yield the start of a request since the last + // ResumeIfYielded task was run. + bool did_scheduler_yield_; + + // Whether or not to periodically yield when starting lots of requests. + bool yielding_scheduler_enabled_; + + // The number of requests that can start before yielding. + int max_requests_before_yielding_; + base::WeakPtrFactory<ResourceScheduler::Client> weak_ptr_factory_; }; ResourceScheduler::ResourceScheduler() : priority_requests_delayable_( - base::FeatureList::IsEnabled(kPrioritySupportedRequestsDelayable)) {} + base::FeatureList::IsEnabled(kPrioritySupportedRequestsDelayable)), + yielding_scheduler_enabled_( + base::FeatureList::IsEnabled(kNetworkSchedulerYielding)), + max_requests_before_yielding_(base::GetFieldTrialParamByFeatureAsInt( + kNetworkSchedulerYielding, + kMaxRequestsBeforeYieldingParam, + kMaxRequestsBeforeYieldingDefault)) {} ResourceScheduler::~ResourceScheduler() { DCHECK(unowned_requests_.empty()); @@ -856,7 +935,9 @@ ClientId client_id = MakeClientId(child_id, route_id); DCHECK(!base::ContainsKey(client_map_, client_id)); - Client* client = new Client(priority_requests_delayable_); + Client* client = + new Client(priority_requests_delayable_, yielding_scheduler_enabled_, + max_requests_before_yielding_); client_map_[client_id] = client; }
diff --git a/content/browser/loader/resource_scheduler.h b/content/browser/loader/resource_scheduler.h index 76b455c4..bcb3213a3 100644 --- a/content/browser/loader/resource_scheduler.h +++ b/content/browser/loader/resource_scheduler.h
@@ -140,6 +140,11 @@ // be delayed. bool priority_requests_delayable_; + // True if the scheduler should yield between several successive calls to + // start resource requests. + bool yielding_scheduler_enabled_; + int max_requests_before_yielding_; + DISALLOW_COPY_AND_ASSIGN(ResourceScheduler); };
diff --git a/content/browser/loader/resource_scheduler_unittest.cc b/content/browser/loader/resource_scheduler_unittest.cc index fb88161..52f77cda 100644 --- a/content/browser/loader/resource_scheduler_unittest.cc +++ b/content/browser/loader/resource_scheduler_unittest.cc
@@ -9,8 +9,11 @@ #include <vector> #include "base/memory/ptr_util.h" +#include "base/metrics/field_trial.h" +#include "base/metrics/field_trial_param_associator.h" #include "base/run_loop.h" #include "base/strings/string_number_conversions.h" +#include "base/test/mock_entropy_provider.h" #include "base/test/scoped_feature_list.h" #include "base/timer/mock_timer.h" #include "base/timer/timer.h" @@ -48,6 +51,9 @@ const char kPrioritySupportedRequestsDelayable[] = "PrioritySupportedRequestsDelayable"; +const char kNetworkSchedulerYielding[] = "NetworkSchedulerYielding"; +const int kMaxRequestsBeforeYielding = 5; // sync with .cc. + class TestRequest : public ResourceThrottle::Delegate { public: TestRequest(std::unique_ptr<net::URLRequest> url_request, @@ -317,6 +323,117 @@ EXPECT_TRUE(lowest2->started()); } +TEST_F(ResourceSchedulerTest, SchedulerYieldsWithFeatureEnabled) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitFromCommandLine(kNetworkSchedulerYielding, ""); + InitializeScheduler(); + + // Use spdy so that we don't throttle. + http_server_properties_.SetSupportsSpdy( + url::SchemeHostPort("https", "spdyhost", 443), true); + + // Add enough async requests that the last one should yield. + std::vector<std::unique_ptr<TestRequest>> requests; + for (int i = 0; i < kMaxRequestsBeforeYielding + 1; ++i) + requests.push_back(NewRequest("http://host/higher", net::HIGHEST)); + + // Verify that the number of requests before yielding started. + for (int i = 0; i < kMaxRequestsBeforeYielding; ++i) + EXPECT_TRUE(requests[i]->started()); + + // The next async request should have yielded. + EXPECT_FALSE(requests[kMaxRequestsBeforeYielding]->started()); + + // Verify that with time the yielded request eventually runs. + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(requests[kMaxRequestsBeforeYielding]->started()); +} + +TEST_F(ResourceSchedulerTest, SchedulerDoesNotYieldForSyncRequests) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitFromCommandLine(kNetworkSchedulerYielding, ""); + InitializeScheduler(); + + // Use spdy so that we don't throttle. + http_server_properties_.SetSupportsSpdy( + url::SchemeHostPort("https", "spdyhost", 443), true); + + // Add enough async requests that the last one should yield. + std::vector<std::unique_ptr<TestRequest>> requests; + for (int i = 0; i < kMaxRequestsBeforeYielding + 1; ++i) + requests.push_back(NewRequest("http://host/higher", net::HIGHEST)); + + // Add a sync requests. + requests.push_back(NewSyncRequest("http://host/higher", net::HIGHEST)); + + // Verify that the number of requests before yielding started. + for (int i = 0; i < kMaxRequestsBeforeYielding; ++i) + EXPECT_TRUE(requests[i]->started()); + + // The next async request should have yielded. + EXPECT_FALSE(requests[kMaxRequestsBeforeYielding]->started()); + + // The next sync request should have started even though async is yielding. + EXPECT_TRUE(requests[kMaxRequestsBeforeYielding + 1]->started()); + + // Verify that with time the yielded request eventually runs. + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(requests[kMaxRequestsBeforeYielding]->started()); +} + +TEST_F(ResourceSchedulerTest, SchedulerDoesNotYieldForAlternativeSchemes) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitFromCommandLine(kNetworkSchedulerYielding, ""); + InitializeScheduler(); + + // Use spdy so that we don't throttle. + http_server_properties_.SetSupportsSpdy( + url::SchemeHostPort("https", "spdyhost", 443), true); + + // Add enough async requests that the last one should yield. + std::vector<std::unique_ptr<TestRequest>> requests; + for (int i = 0; i < kMaxRequestsBeforeYielding + 1; ++i) + requests.push_back(NewRequest("http://host/higher", net::HIGHEST)); + + // Add a non-http request. + requests.push_back(NewRequest("zzz://host/higher", net::HIGHEST)); + + // Verify that the number of requests before yielding started. + for (int i = 0; i < kMaxRequestsBeforeYielding; ++i) + EXPECT_TRUE(requests[i]->started()); + + // The next async request should have yielded. + EXPECT_FALSE(requests[kMaxRequestsBeforeYielding]->started()); + + // The non-http(s) request should have started even though async is + // yielding. + EXPECT_TRUE(requests[kMaxRequestsBeforeYielding + 1]->started()); + + // Verify that with time the yielded request eventually runs. + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(requests[kMaxRequestsBeforeYielding]->started()); +} + +TEST_F(ResourceSchedulerTest, SchedulerDoesNotYieldWithFeatureDisabled) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitFromCommandLine("", kNetworkSchedulerYielding); + InitializeScheduler(); + + // Use spdy so that we don't throttle. + http_server_properties_.SetSupportsSpdy( + url::SchemeHostPort("https", "spdyhost", 443), true); + + // Add enough async requests that the last one would yield if yielding were + // enabled. + std::vector<std::unique_ptr<TestRequest>> requests; + for (int i = 0; i < kMaxRequestsBeforeYielding + 1; ++i) + requests.push_back(NewRequest("http://host/higher", net::HIGHEST)); + + // Verify that none of the requests yield. + for (int i = 0; i < kMaxRequestsBeforeYielding + 1; ++i) + EXPECT_TRUE(requests[i]->started()); +} + TEST_F(ResourceSchedulerTest, OneLowLoadsUntilBodyInsertedExceptSpdy) { base::test::ScopedFeatureList scoped_feature_list; scoped_feature_list.InitFromCommandLine("", @@ -459,6 +576,11 @@ } TEST_F(ResourceSchedulerTest, LimitedNumberOfDelayableRequestsInFlight) { + // The yielding feature will sometimes yield requests before they get a + // chance to start, which conflicts this test. So disable the feature. + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitFromCommandLine("", kNetworkSchedulerYielding); + // We only load low priority resources if there's a body. scheduler()->OnWillInsertBody(kChildId, kRouteId);
diff --git a/content/browser/media/session/audio_focus_manager.cc b/content/browser/media/session/audio_focus_manager.cc index 48f6dcce..92cee28 100644 --- a/content/browser/media/session/audio_focus_manager.cc +++ b/content/browser/media/session/audio_focus_manager.cc
@@ -34,11 +34,11 @@ // up the relation between AudioFocusManager and MediaSessionImpl. // See https://crbug.com/651069 if (type == AudioFocusType::GainTransientMayDuck) { - for (const auto old_session : audio_focus_stack_) { + for (auto* old_session : audio_focus_stack_) { old_session->StartDucking(); } } else { - for (const auto old_session : audio_focus_stack_) { + for (auto* old_session : audio_focus_stack_) { if (old_session->IsActive()) { if (old_session->HasPepper()) old_session->StartDucking();
diff --git a/content/browser/memory/memory_coordinator_impl_unittest.cc b/content/browser/memory/memory_coordinator_impl_unittest.cc index 63edb99..a0e1b31 100644 --- a/content/browser/memory/memory_coordinator_impl_unittest.cc +++ b/content/browser/memory/memory_coordinator_impl_unittest.cc
@@ -199,7 +199,7 @@ } TEST_F(MemoryCoordinatorImplTest, SetMemoryStateFailsInvalidState) { - auto cmc1 = coordinator_->CreateChildMemoryCoordinator(1); + auto* cmc1 = coordinator_->CreateChildMemoryCoordinator(1); EXPECT_FALSE( coordinator_->SetChildMemoryState(1, MemoryState::UNKNOWN)); @@ -207,7 +207,7 @@ } TEST_F(MemoryCoordinatorImplTest, SetMemoryStateFailsInvalidRenderer) { - auto cmc1 = coordinator_->CreateChildMemoryCoordinator(1); + auto* cmc1 = coordinator_->CreateChildMemoryCoordinator(1); EXPECT_FALSE( coordinator_->SetChildMemoryState(2, MemoryState::THROTTLED)); @@ -215,7 +215,7 @@ } TEST_F(MemoryCoordinatorImplTest, SetMemoryStateNotDeliveredNop) { - auto cmc1 = coordinator_->CreateChildMemoryCoordinator(1); + auto* cmc1 = coordinator_->CreateChildMemoryCoordinator(1); EXPECT_FALSE( coordinator_->SetChildMemoryState(2, MemoryState::NORMAL)); @@ -223,8 +223,8 @@ } TEST_F(MemoryCoordinatorImplTest, SetMemoryStateDelivered) { - auto cmc1 = coordinator_->CreateChildMemoryCoordinator(1); - auto cmc2 = coordinator_->CreateChildMemoryCoordinator(2); + auto* cmc1 = coordinator_->CreateChildMemoryCoordinator(1); + auto* cmc2 = coordinator_->CreateChildMemoryCoordinator(2); EXPECT_TRUE( coordinator_->SetChildMemoryState(1, MemoryState::THROTTLED)); @@ -248,7 +248,7 @@ } TEST_F(MemoryCoordinatorImplTest, SetChildMemoryState) { - auto cmc = coordinator_->CreateChildMemoryCoordinator(1); + auto* cmc = coordinator_->CreateChildMemoryCoordinator(1); auto iter = coordinator_->children().find(1); auto* render_process_host = coordinator_->GetMockRenderProcessHost(1); ASSERT_TRUE(iter != coordinator_->children().end());
diff --git a/content/browser/renderer_host/compositor_impl_android.cc b/content/browser/renderer_host/compositor_impl_android.cc index 49abcb2..eda8fc5 100644 --- a/content/browser/renderer_host/compositor_impl_android.cc +++ b/content/browser/renderer_host/compositor_impl_android.cc
@@ -157,10 +157,10 @@ void SwapBuffers(cc::OutputSurfaceFrame frame) override { GetCommandBufferProxy()->SetLatencyInfo(frame.latency_info); - if (frame.sub_buffer_rect.IsEmpty()) { + if (frame.sub_buffer_rect) { + DCHECK(frame.sub_buffer_rect->IsEmpty()); context_provider_->ContextSupport()->CommitOverlayPlanes(); } else { - DCHECK(frame.sub_buffer_rect == gfx::Rect(frame.size)); context_provider_->ContextSupport()->Swap(); } }
diff --git a/content/browser/renderer_host/ime_adapter_android.cc b/content/browser/renderer_host/ime_adapter_android.cc index 3a7d18b..0c852a3 100644 --- a/content/browser/renderer_host/ime_adapter_android.cc +++ b/content/browser/renderer_host/ime_adapter_android.cc
@@ -14,11 +14,8 @@ #include "base/android/scoped_java_ref.h" #include "base/strings/utf_string_conversions.h" #include "base/time/time.h" -#include "content/browser/frame_host/frame_tree.h" -#include "content/browser/frame_host/frame_tree_node.h" #include "content/browser/frame_host/render_frame_host_impl.h" #include "content/browser/renderer_host/render_view_host_delegate.h" -#include "content/browser/renderer_host/render_view_host_impl.h" #include "content/browser/renderer_host/render_widget_host_impl.h" #include "content/browser/renderer_host/render_widget_host_view_android.h" #include "content/common/input_messages.h" @@ -110,6 +107,7 @@ ImeAdapterAndroid::ImeAdapterAndroid(RenderWidgetHostViewAndroid* rwhva) : rwhva_(rwhva) { + DCHECK(rwhva_); } ImeAdapterAndroid::~ImeAdapterAndroid() { @@ -142,7 +140,7 @@ const JavaParamRef<jobject>& text, const JavaParamRef<jstring>& text_str, int relative_cursor_pos) { - RenderWidgetHostImpl* rwhi = GetRenderWidgetHostImpl(); + RenderWidgetHostImpl* rwhi = GetFocusedWidget(); if (!rwhi) return; @@ -172,7 +170,7 @@ const JavaParamRef<jobject>& text, const JavaParamRef<jstring>& text_str, int relative_cursor_pos) { - RenderWidgetHostImpl* rwhi = GetRenderWidgetHostImpl(); + RenderWidgetHostImpl* rwhi = GetFocusedWidget(); if (!rwhi) return; @@ -195,7 +193,7 @@ void ImeAdapterAndroid::FinishComposingText(JNIEnv* env, const JavaParamRef<jobject>&) { - RenderWidgetHostImpl* rwhi = GetRenderWidgetHostImpl(); + RenderWidgetHostImpl* rwhi = GetFocusedWidget(); if (!rwhi) return; @@ -288,7 +286,7 @@ bool ImeAdapterAndroid::RequestTextInputStateUpdate( JNIEnv* env, const JavaParamRef<jobject>&) { - RenderWidgetHostImpl* rwhi = GetRenderWidgetHostImpl(); + RenderWidgetHostImpl* rwhi = GetFocusedWidget(); if (!rwhi) return false; rwhi->Send(new InputMsg_RequestTextInputStateUpdate(rwhi->GetRoutingID())); @@ -300,7 +298,7 @@ const base::android::JavaParamRef<jobject>& obj, bool immediate_request, bool monitor_request) { - RenderWidgetHostImpl* rwhi = GetRenderWidgetHostImpl(); + RenderWidgetHostImpl* rwhi = GetFocusedWidget(); if (!rwhi) return; rwhi->Send(new InputMsg_RequestCompositionUpdate( @@ -312,36 +310,25 @@ java_ime_adapter_.reset(); } -RenderWidgetHostImpl* ImeAdapterAndroid::GetRenderWidgetHostImpl() { +RenderWidgetHostImpl* ImeAdapterAndroid::GetFocusedWidget() { DCHECK_CURRENTLY_ON(BrowserThread::UI); - DCHECK(rwhva_); - RenderWidgetHost* rwh = rwhva_->GetRenderWidgetHost(); - if (!rwh) - return nullptr; - - return RenderWidgetHostImpl::From(rwh); + return rwhva_->GetFocusedWidget(); } RenderFrameHost* ImeAdapterAndroid::GetFocusedFrame() { - RenderWidgetHostImpl* rwh = GetRenderWidgetHostImpl(); - if (!rwh) - return nullptr; - RenderViewHost* rvh = RenderViewHost::From(rwh); - if (!rvh) - return nullptr; - FrameTreeNode* focused_frame = - rvh->GetDelegate()->GetFrameTree()->GetFocusedFrame(); - if (!focused_frame) + DCHECK_CURRENTLY_ON(BrowserThread::UI); + // We get the focused frame from the WebContents of the page. Although + // |rwhva_->GetFocusedWidget()| does a similar thing, there is no direct way + // to get a RenderFrameHost from its RWH. + RenderWidgetHostImpl* rwh = + RenderWidgetHostImpl::From(rwhva_->GetRenderWidgetHost()); + if (!rwh || !rwh->delegate()) return nullptr; - return focused_frame->current_frame_host(); -} + if (auto* contents = rwh->delegate()->GetAsWebContents()) + return contents->GetFocusedFrame(); -WebContents* ImeAdapterAndroid::GetWebContents() { - RenderWidgetHostImpl* rwh = GetRenderWidgetHostImpl(); - if (!rwh) - return nullptr; - return WebContents::FromRenderViewHost(RenderViewHost::From(rwh)); + return nullptr; } std::vector<blink::WebCompositionUnderline>
diff --git a/content/browser/renderer_host/ime_adapter_android.h b/content/browser/renderer_host/ime_adapter_android.h index 57610c066..288f4402 100644 --- a/content/browser/renderer_host/ime_adapter_android.h +++ b/content/browser/renderer_host/ime_adapter_android.h
@@ -11,6 +11,7 @@ #include "base/android/jni_weak_ref.h" #include "base/strings/string16.h" +#include "content/common/content_export.h" #include "ui/gfx/geometry/rect_f.h" namespace blink { @@ -24,14 +25,13 @@ class RenderFrameHost; class RenderWidgetHostImpl; class RenderWidgetHostViewAndroid; -class WebContents; // This class is in charge of dispatching key events from the java side // and forward to renderer along with input method results via // corresponding host view. // Ownership of these objects remains on the native side (see // RenderWidgetHostViewAndroid). -class ImeAdapterAndroid { +class CONTENT_EXPORT ImeAdapterAndroid { public: explicit ImeAdapterAndroid(RenderWidgetHostViewAndroid* rwhva); ~ImeAdapterAndroid(); @@ -86,10 +86,14 @@ void FocusedNodeChanged(bool is_editable_node); void SetCharacterBounds(const std::vector<gfx::RectF>& rects); + base::android::ScopedJavaLocalRef<jobject> java_ime_adapter_for_testing( + JNIEnv* env) { + return java_ime_adapter_.get(env); + } + private: - RenderWidgetHostImpl* GetRenderWidgetHostImpl(); + RenderWidgetHostImpl* GetFocusedWidget(); RenderFrameHost* GetFocusedFrame(); - WebContents* GetWebContents(); std::vector<blink::WebCompositionUnderline> GetUnderlinesFromSpans( JNIEnv* env, const base::android::JavaParamRef<jobject>& obj,
diff --git a/content/browser/renderer_host/input/web_input_event_builders_android.cc b/content/browser/renderer_host/input/web_input_event_builders_android.cc index 9bdd73f..059192e 100644 --- a/content/browser/renderer_host/input/web_input_event_builders_android.cc +++ b/content/browser/renderer_host/input/web_input_event_builders_android.cc
@@ -10,6 +10,7 @@ #include "ui/events/android/key_event_utils.h" #include "ui/events/android/motion_event_android.h" #include "ui/events/blink/blink_event_util.h" +#include "ui/events/event_constants.h" #include "ui/events/keycodes/dom/dom_code.h" #include "ui/events/keycodes/dom/keycode_converter.h" #include "ui/events/keycodes/keyboard_code_conversion.h" @@ -110,20 +111,18 @@ return result; } -WebMouseEvent WebMouseEventBuilder::Build( - WebInputEvent::Type type, - double time_sec, - int window_x, - int window_y, - int modifiers, - int click_count, - int pointer_id, - float pressure, - float orientation_rad, - float tilt_rad, - int changed_button, - int tool_type) { - +WebMouseEvent WebMouseEventBuilder::Build(WebInputEvent::Type type, + double time_sec, + int window_x, + int window_y, + int modifiers, + int click_count, + int pointer_id, + float pressure, + float orientation_rad, + float tilt_rad, + int action_button, + int tool_type) { DCHECK(WebInputEvent::isMouseEventType(type)); WebMouseEvent result(type, ui::EventFlagsToWebEventModifiers(modifiers), time_sec); @@ -134,14 +133,23 @@ result.windowY = window_y; result.clickCount = click_count; - ui::SetWebPointerPropertiesFromMotionEventData( - result, - pointer_id, - pressure, - orientation_rad, - tilt_rad, - changed_button, - tool_type); + int button = action_button; + // For events other than MouseDown/Up, action_button is not defined. So we are + // determining |button| value from |modifiers| as is done in other platforms. + if (type != WebInputEvent::MouseDown && type != WebInputEvent::MouseUp) { + if (modifiers & ui::EF_LEFT_MOUSE_BUTTON) + button = ui::MotionEvent::BUTTON_PRIMARY; + else if (modifiers & ui::EF_MIDDLE_MOUSE_BUTTON) + button = ui::MotionEvent::BUTTON_TERTIARY; + else if (modifiers & ui::EF_RIGHT_MOUSE_BUTTON) + button = ui::MotionEvent::BUTTON_SECONDARY; + else + button = 0; + } + + ui::SetWebPointerPropertiesFromMotionEventData(result, pointer_id, pressure, + orientation_rad, tilt_rad, + button, tool_type); return result; }
diff --git a/content/browser/renderer_host/input/web_input_event_builders_android.h b/content/browser/renderer_host/input/web_input_event_builders_android.h index 6860d70..8dded19c 100644 --- a/content/browser/renderer_host/input/web_input_event_builders_android.h +++ b/content/browser/renderer_host/input/web_input_event_builders_android.h
@@ -18,19 +18,18 @@ class WebMouseEventBuilder { public: - static blink::WebMouseEvent Build( - blink::WebInputEvent::Type type, - double time_sec, - int window_x, - int window_y, - int modifiers, - int click_count, - int pointer_id, - float pressure, - float orientation_rad, - float tilt_rad, - int changed_button, - int tool_type); + static blink::WebMouseEvent Build(blink::WebInputEvent::Type type, + double time_sec, + int window_x, + int window_y, + int modifiers, + int click_count, + int pointer_id, + float pressure, + float orientation_rad, + float tilt_rad, + int action_button, + int tool_type); }; class WebMouseWheelEventBuilder {
diff --git a/content/browser/renderer_host/media/media_capture_devices_impl.cc b/content/browser/renderer_host/media/media_capture_devices_impl.cc index 9847d95..10825692 100644 --- a/content/browser/renderer_host/media/media_capture_devices_impl.cc +++ b/content/browser/renderer_host/media/media_capture_devices_impl.cc
@@ -51,6 +51,33 @@ return video_devices_; } +void MediaCaptureDevicesImpl::AddVideoCaptureObserver( + media::VideoCaptureObserver* observer) { + MediaStreamManager* media_stream_manager = + BrowserMainLoop::GetInstance()->media_stream_manager(); + if (media_stream_manager != nullptr) { + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + base::Bind(&MediaStreamManager::AddVideoCaptureObserver, + base::Unretained(media_stream_manager), observer)); + } else { + DVLOG(3) << "media_stream_manager is null."; + } +} + +void MediaCaptureDevicesImpl::RemoveAllVideoCaptureObservers() { + MediaStreamManager* media_stream_manager = + BrowserMainLoop::GetInstance()->media_stream_manager(); + if (media_stream_manager != nullptr) { + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + base::Bind(&MediaStreamManager::RemoveAllVideoCaptureObservers, + base::Unretained(media_stream_manager))); + } else { + DVLOG(3) << "media_stream_manager is null."; + } +} + void MediaCaptureDevicesImpl::OnAudioCaptureDevicesChanged( const MediaStreamDevices& devices) { if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
diff --git a/content/browser/renderer_host/media/media_capture_devices_impl.h b/content/browser/renderer_host/media/media_capture_devices_impl.h index 28d155c..d251ab59d 100644 --- a/content/browser/renderer_host/media/media_capture_devices_impl.h +++ b/content/browser/renderer_host/media/media_capture_devices_impl.h
@@ -8,6 +8,7 @@ #include "base/macros.h" #include "base/memory/singleton.h" #include "content/public/browser/media_capture_devices.h" +#include "media/base/video_facing.h" namespace content { @@ -18,6 +19,8 @@ // Overriden from MediaCaptureDevices const MediaStreamDevices& GetAudioCaptureDevices() override; const MediaStreamDevices& GetVideoCaptureDevices() override; + void AddVideoCaptureObserver(media::VideoCaptureObserver* observer) override; + void RemoveAllVideoCaptureObservers() override; // Called by MediaStreamManager to notify the change of media capture // devices, these 2 methods are called in IO thread.
diff --git a/content/browser/renderer_host/media/media_devices_manager.cc b/content/browser/renderer_host/media/media_devices_manager.cc index e8d7f7de..2910ecd 100644 --- a/content/browser/renderer_host/media/media_devices_manager.cc +++ b/content/browser/renderer_host/media/media_devices_manager.cc
@@ -520,7 +520,7 @@ DCHECK_CURRENTLY_ON(BrowserThread::IO); DCHECK(IsValidMediaDeviceType(type)); - for (const auto& subscriber : device_change_subscribers_[type]) { + for (auto* subscriber : device_change_subscribers_[type]) { subscriber->OnDevicesChanged(type, snapshot); } }
diff --git a/content/browser/renderer_host/media/media_stream_manager.cc b/content/browser/renderer_host/media/media_stream_manager.cc index 1665fe3..12d5f829 100644 --- a/content/browser/renderer_host/media/media_stream_manager.cc +++ b/content/browser/renderer_host/media/media_stream_manager.cc
@@ -450,6 +450,21 @@ return media_devices_manager_.get(); } +void MediaStreamManager::AddVideoCaptureObserver( + media::VideoCaptureObserver* capture_observer) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + if (video_capture_manager_) { + video_capture_manager_->AddVideoCaptureObserver(capture_observer); + } +} + +void MediaStreamManager::RemoveAllVideoCaptureObservers() { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + if (video_capture_manager_) { + video_capture_manager_->RemoveAllVideoCaptureObservers(); + } +} + std::string MediaStreamManager::MakeMediaAccessRequest( int render_process_id, int render_frame_id,
diff --git a/content/browser/renderer_host/media/media_stream_manager.h b/content/browser/renderer_host/media/media_stream_manager.h index 6b4c3c45..d152fe1 100644 --- a/content/browser/renderer_host/media/media_stream_manager.h +++ b/content/browser/renderer_host/media/media_stream_manager.h
@@ -45,6 +45,7 @@ #include "content/common/media/media_devices.h" #include "content/common/media/media_stream_options.h" #include "content/public/browser/media_request_state.h" +#include "media/base/video_facing.h" namespace media { class AudioManager; @@ -97,6 +98,16 @@ // Used to access MediaDevicesManager. MediaDevicesManager* media_devices_manager(); + // AddVideoCaptureObserver() and RemoveAllVideoCaptureObservers() must be + // called after InitializeDeviceManagersOnIOThread() and before + // WillDestroyCurrentMessageLoop(). They can be called more than once and it's + // ok to not call at all if the client is not interested in receiving + // media::VideoCaptureObserver callbacks. + // The methods must be called on BrowserThread::IO threads. The callbacks of + // media::VideoCaptureObserver also arrive on BrowserThread::IO threads. + void AddVideoCaptureObserver(media::VideoCaptureObserver* capture_observer); + void RemoveAllVideoCaptureObservers(); + // Creates a new media access request which is identified by a unique string // that's returned to the caller. This will trigger the infobar and ask users // for access to the device. |render_process_id| and |render_frame_id| are
diff --git a/content/browser/renderer_host/media/video_capture_manager.cc b/content/browser/renderer_host/media/video_capture_manager.cc index 44094c7..651aef8 100644 --- a/content/browser/renderer_host/media/video_capture_manager.cc +++ b/content/browser/renderer_host/media/video_capture_manager.cc
@@ -34,6 +34,7 @@ #include "content/public/common/media_stream_request.h" #include "media/base/bind_to_current_loop.h" #include "media/base/media_switches.h" +#include "media/base/video_facing.h" #include "media/capture/video/video_capture_buffer_pool_impl.h" #include "media/capture/video/video_capture_buffer_tracker_factory_impl.h" #include "media/capture/video/video_capture_device.h" @@ -339,6 +340,18 @@ DCHECK(device_start_queue_.empty()); } +void VideoCaptureManager::AddVideoCaptureObserver( + media::VideoCaptureObserver* observer) { + DCHECK(observer); + DCHECK_CURRENTLY_ON(BrowserThread::IO); + capture_observers_.AddObserver(observer); +} + +void VideoCaptureManager::RemoveAllVideoCaptureObservers() { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + capture_observers_.Clear(); +} + void VideoCaptureManager::RegisterListener( MediaStreamProviderListener* listener) { DCHECK_CURRENTLY_ON(BrowserThread::IO); @@ -468,6 +481,12 @@ } } + const DeviceInfo* device_info = GetDeviceInfoById(entry->id); + if (device_info != nullptr) { + for (auto& observer : capture_observers_) + observer.OnVideoCaptureStopped(device_info->descriptor.facing); + } + DVLOG(3) << "DoStopDevice. Send stop request for device = " << entry->id << " serial_id = " << entry->serial_id << "."; entry->video_capture_controller.OnLog( @@ -524,6 +543,9 @@ found->descriptor.GetNameAndModel().c_str(), found->descriptor.GetCaptureApiTypeString())); + for (auto& observer : capture_observers_) + observer.OnVideoCaptureStarted(found->descriptor.facing); + start_capture_function = base::Bind(&VideoCaptureManager::DoStartDeviceCaptureOnDeviceThread, this, found->descriptor, request->params(),
diff --git a/content/browser/renderer_host/media/video_capture_manager.h b/content/browser/renderer_host/media/video_capture_manager.h index 569910d0..a1d96a1 100644 --- a/content/browser/renderer_host/media/video_capture_manager.h +++ b/content/browser/renderer_host/media/video_capture_manager.h
@@ -21,6 +21,7 @@ #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" #include "base/message_loop/message_loop.h" +#include "base/observer_list.h" #include "base/process/process_handle.h" #include "base/threading/thread_checker.h" #include "base/timer/elapsed_timer.h" @@ -29,6 +30,7 @@ #include "content/browser/renderer_host/media/video_capture_controller_event_handler.h" #include "content/common/content_export.h" #include "content/common/media/media_stream_options.h" +#include "media/base/video_facing.h" #include "media/capture/video/video_capture_device.h" #include "media/capture/video/video_capture_device_factory.h" #include "media/capture/video_capture_types.h" @@ -54,6 +56,16 @@ std::unique_ptr<media::VideoCaptureDeviceFactory> factory, scoped_refptr<base::SingleThreadTaskRunner> device_task_runner); + // AddVideoCaptureObserver() can be called only before any devices are opened. + // RemoveAllVideoCaptureObservers() can be called only after all devices + // are closed. + // They can be called more than once and it's ok to not call at all if the + // client is not interested in receiving media::VideoCaptureObserver callacks. + // This methods can be called on whatever thread. The callbacks of + // media::VideoCaptureObserver arrive on browser IO thread. + void AddVideoCaptureObserver(media::VideoCaptureObserver* observer); + void RemoveAllVideoCaptureObservers(); + // Implements MediaStreamProvider. void RegisterListener(MediaStreamProviderListener* listener) override; void UnregisterListener() override; @@ -341,6 +353,8 @@ std::unique_ptr<media::VideoCaptureDeviceFactory> video_capture_device_factory_; + base::ObserverList<media::VideoCaptureObserver> capture_observers_; + // Local cache of the enumerated video capture devices' names and capture // supported formats. A snapshot of the current devices and their capabilities // is composed in VideoCaptureDeviceFactory::EnumerateDeviceNames() and
diff --git a/content/browser/renderer_host/media/video_capture_manager_unittest.cc b/content/browser/renderer_host/media/video_capture_manager_unittest.cc index 8525a34..e5e8e82 100644 --- a/content/browser/renderer_host/media/video_capture_manager_unittest.cc +++ b/content/browser/renderer_host/media/video_capture_manager_unittest.cc
@@ -94,6 +94,9 @@ DISALLOW_COPY_AND_ASSIGN(WrappedDevice); }; + static const media::VideoFacingMode DEFAULT_FACING = + media::VideoFacingMode::MEDIA_VIDEO_FACING_USER; + WrappedDeviceFactory() : FakeVideoCaptureDeviceFactory() {} ~WrappedDeviceFactory() final {} @@ -103,6 +106,16 @@ FakeVideoCaptureDeviceFactory::CreateDevice(device_descriptor), this); } + void GetDeviceDescriptors( + media::VideoCaptureDeviceDescriptors* device_descriptors) override { + media::FakeVideoCaptureDeviceFactory::GetDeviceDescriptors( + device_descriptors); + for (auto& descriptor : *device_descriptors) { + if (descriptor.facing == media::VideoFacingMode::MEDIA_VIDEO_FACING_NONE) + descriptor.facing = DEFAULT_FACING; + } + } + MOCK_METHOD0(WillSuspendDevice, void()); MOCK_METHOD0(WillResumeDevice, void()); @@ -150,6 +163,13 @@ void OnGotControllerCallback(VideoCaptureControllerID) {} }; +// Input argument for testing AddVideoCaptureObserver(). +class MockVideoCaptureObserver : public media::VideoCaptureObserver { + public: + MOCK_METHOD1(OnVideoCaptureStarted, void(media::VideoFacingMode)); + MOCK_METHOD1(OnVideoCaptureStopped, void(media::VideoFacingMode)); +}; + } // namespace // Test class @@ -331,6 +351,27 @@ vcm_->UnregisterListener(); } +TEST_F(VideoCaptureManagerTest, AddObserver) { + InSequence s; + MockVideoCaptureObserver observer; + vcm_->AddVideoCaptureObserver(&observer); + + EXPECT_CALL(observer, + OnVideoCaptureStarted(WrappedDeviceFactory::DEFAULT_FACING)); + EXPECT_CALL(observer, + OnVideoCaptureStopped(WrappedDeviceFactory::DEFAULT_FACING)); + + int video_session_id = vcm_->Open(devices_.front()); + VideoCaptureControllerID client_id = StartClient(video_session_id, true); + + StopClient(client_id); + vcm_->Close(video_session_id); + + // Wait to check callbacks before removing the listener. + base::RunLoop().RunUntilIdle(); + vcm_->UnregisterListener(); +} + // Open the same device twice. TEST_F(VideoCaptureManagerTest, OpenTwice) { InSequence s;
diff --git a/content/browser/renderer_host/render_widget_host_input_event_router.cc b/content/browser/renderer_host/render_widget_host_input_event_router.cc index 1f226d8..ffa31e6b 100644 --- a/content/browser/renderer_host/render_widget_host_input_event_router.cc +++ b/content/browser/renderer_host/render_widget_host_input_event_router.cc
@@ -483,7 +483,7 @@ gfx::Point transformed_point; // Send MouseLeaves. - for (auto view : exited_views) { + for (auto* view : exited_views) { blink::WebMouseEvent mouse_leave(*event); mouse_leave.setType(blink::WebInputEvent::MouseLeave); // There is a chance of a race if the last target has recently created a @@ -512,7 +512,7 @@ } // Send MouseMoves to trigger MouseEnter handlers. - for (auto view : entered_views) { + for (auto* view : entered_views) { if (view == target) continue; blink::WebMouseEvent mouse_enter(*event); @@ -702,7 +702,7 @@ // TODO(wjmaclean,kenrb,tdresser): When scroll latching lands, we can // revisit how this code should work. // https://crbug.com/526463 - auto rwhi = + auto* rwhi = static_cast<RenderWidgetHostImpl*>(root_view->GetRenderWidgetHost()); // If the root view is the current gesture target, then we explicitly don't // send a GestureScrollBegin, as by the time we see GesturePinchBegin there @@ -720,7 +720,7 @@ in_touchscreen_gesture_pinch_ = false; // If the root view wasn't already receiving the gesture stream, then we // need to wrap the diverted pinch events in a GestureScrollBegin/End. - auto rwhi = + auto* rwhi = static_cast<RenderWidgetHostImpl*>(root_view->GetRenderWidgetHost()); if (root_view != touchscreen_gesture_target_.target && gesture_pinch_did_send_scroll_begin_ &&
diff --git a/content/browser/renderer_host/render_widget_host_unittest.cc b/content/browser/renderer_host/render_widget_host_unittest.cc index 005ab9ca..972f340 100644 --- a/content/browser/renderer_host/render_widget_host_unittest.cc +++ b/content/browser/renderer_host/render_widget_host_unittest.cc
@@ -814,7 +814,7 @@ screen_info.orientation_angle = 0; screen_info.orientation_type = SCREEN_ORIENTATION_VALUES_PORTRAIT_PRIMARY; - auto host_delegate = + auto* host_delegate = static_cast<MockRenderWidgetHostDelegate*>(host_->delegate()); host_delegate->SetScreenInfo(screen_info);
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 3d1d70d..260407d6 100644 --- a/content/browser/renderer_host/render_widget_host_view_android.cc +++ b/content/browser/renderer_host/render_widget_host_view_android.cc
@@ -1592,7 +1592,7 @@ void RenderWidgetHostViewAndroid::SendMouseEvent( const ui::MotionEventAndroid& motion_event, - int changed_button) { + int action_button) { blink::WebInputEvent::Type webMouseEventType = ui::ToWebMouseEventType(motion_event.GetAction()); @@ -1607,7 +1607,7 @@ motion_event.GetPressure(0), motion_event.GetOrientation(0), motion_event.GetTilt(0), - changed_button, + action_button, motion_event.GetToolType(0)); if (host_)
diff --git a/content/browser/renderer_host/render_widget_host_view_android.h b/content/browser/renderer_host/render_widget_host_view_android.h index a52a7a1..9ac9184 100644 --- a/content/browser/renderer_host/render_widget_host_view_android.h +++ b/content/browser/renderer_host/render_widget_host_view_android.h
@@ -198,7 +198,7 @@ void SetContentViewCore(ContentViewCoreImpl* content_view_core); SkColor GetCachedBackgroundColor() const; void SendKeyEvent(const NativeWebKeyboardEvent& event); - void SendMouseEvent(const ui::MotionEventAndroid&, int changed_button); + void SendMouseEvent(const ui::MotionEventAndroid&, int action_button); void SendMouseWheelEvent(const blink::WebMouseWheelEvent& event); void SendGestureEvent(const blink::WebGestureEvent& event); @@ -250,6 +250,8 @@ void OnTextSelectionChanged(TextInputManager* text_input_manager, RenderWidgetHostViewBase* updated_view) override; + ImeAdapterAndroid* ime_adapter_for_testing() { return &ime_adapter_android_; } + private: void RunAckCallbacks();
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 36665017..5dcdbe3 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
@@ -1593,7 +1593,7 @@ // which sends a ViewMsg_Resize::ID message to the renderer. EXPECT_EQ(1u, sink_->message_count()); EXPECT_EQ(ViewMsg_Resize::ID, sink_->GetMessageAt(0)->type()); - auto view_delegate = static_cast<MockRenderWidgetHostDelegate*>( + auto* view_delegate = static_cast<MockRenderWidgetHostDelegate*>( static_cast<RenderWidgetHostImpl*>(view_->GetRenderWidgetHost()) ->delegate()); EXPECT_EQ(2.0f, view_delegate->get_last_device_scale_factor());
diff --git a/content/browser/service_worker/foreign_fetch_request_handler.cc b/content/browser/service_worker/foreign_fetch_request_handler.cc index da962d6..58675b0 100644 --- a/content/browser/service_worker/foreign_fetch_request_handler.cc +++ b/content/browser/service_worker/foreign_fetch_request_handler.cc
@@ -259,7 +259,7 @@ return; } - auto request_info = ResourceRequestInfo::ForRequest(job->request()); + auto* request_info = ResourceRequestInfo::ForRequest(job->request()); base::Callback<WebContents*(void)> web_contents_getter; if (request_info) web_contents_getter = request_info->GetWebContentsGetterForRequest();
diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc index 00bbf733..2d497d5 100644 --- a/content/browser/site_per_process_browsertest.cc +++ b/content/browser/site_per_process_browsertest.cc
@@ -93,6 +93,14 @@ #include "ui/base/test/scoped_preferred_scroller_style_mac.h" #endif +#if defined(OS_ANDROID) +#include "base/android/jni_android.h" +#include "base/android/jni_string.h" +#include "base/android/scoped_java_ref.h" +#include "content/browser/renderer_host/ime_adapter_android.h" +#include "content/browser/renderer_host/render_widget_host_view_android.h" +#endif + namespace content { namespace { @@ -9410,4 +9418,135 @@ EXPECT_TRUE(result); } +#if defined(OS_ANDROID) +class TextSelectionObserver : public TextInputManager::Observer { + public: + explicit TextSelectionObserver(TextInputManager* text_input_manager) + : text_input_manager_(text_input_manager) { + text_input_manager->AddObserver(this); + } + + ~TextSelectionObserver() { text_input_manager_->RemoveObserver(this); } + + void WaitForSelectedText(const std::string& expected_text) { + if (last_selected_text_ == expected_text) + return; + expected_text_ = expected_text; + loop_runner_ = new MessageLoopRunner(); + loop_runner_->Run(); + } + + private: + void OnTextSelectionChanged(TextInputManager* text_input_manager, + RenderWidgetHostViewBase* updated_view) override { + base::string16 text; + if (text_input_manager->GetTextSelection(updated_view) + ->GetSelectedText(&text)) { + last_selected_text_ = base::UTF16ToUTF8(text); + if (last_selected_text_ == expected_text_ && loop_runner_) + loop_runner_->Quit(); + } + } + TextInputManager* const text_input_manager_; + std::string last_selected_text_; + std::string expected_text_; + scoped_refptr<MessageLoopRunner> loop_runner_; + + DISALLOW_COPY_AND_ASSIGN(TextSelectionObserver); +}; + +class SitePerProcessAndroidImeTest : public SitePerProcessBrowserTest { + public: + SitePerProcessAndroidImeTest() : SitePerProcessBrowserTest() {} + ~SitePerProcessAndroidImeTest() override {} + + protected: + ImeAdapterAndroid* ime_adapter() { + return static_cast<RenderWidgetHostViewAndroid*>( + web_contents()->GetRenderWidgetHostView()) + ->ime_adapter_for_testing(); + } + + std::string GetInputValue(RenderFrameHostImpl* frame) { + std::string result; + EXPECT_TRUE(ExecuteScriptAndExtractString( + frame, "window.domAutomationController.send(input.value);", &result)); + return result; + } + + void FocusInputInFrame(RenderFrameHostImpl* frame) { + ASSERT_TRUE(ExecuteScript(frame, "window.focus(); input.focus();")); + } + + // Creates a page with multiple (nested) OOPIFs and populates all of them + // with an <input> element along with the required handlers for the test. + void LoadPage() { + ASSERT_TRUE(NavigateToURL( + shell(), + GURL(embedded_test_server()->GetURL( + "a.com", "/cross_site_iframe_factory.html?a(b,c(a(b)))")))); + FrameTreeNode* root = web_contents()->GetFrameTree()->root(); + frames_.push_back(root->current_frame_host()); + frames_.push_back(root->child_at(0)->current_frame_host()); + frames_.push_back(root->child_at(1)->current_frame_host()); + frames_.push_back(root->child_at(1)->child_at(0)->current_frame_host()); + frames_.push_back( + root->child_at(1)->child_at(0)->child_at(0)->current_frame_host()); + + // Adds an <input> to frame and sets up a handler for |window.oninput|. When + // the input event is fired (by changing the value of <input> element), the + // handler will select all the text so that the corresponding text selection + // update on the browser side notifies the test about input insertion. + std::string add_input_script = + "var input = document.createElement('input');" + "document.body.appendChild(input);" + "window.oninput = function() {" + " input.select();" + "};"; + + for (auto* frame : frames_) + ASSERT_TRUE(ExecuteScript(frame, add_input_script)); + } + + // This methods tries to commit |text| by simulating a native call from Java. + void CommitText(const char* text) { + JNIEnv* env = base::android::AttachCurrentThread(); + + // A valid caller is needed for ImeAdapterAndroid::GetUnderlinesFromSpans. + base::android::ScopedJavaLocalRef<jobject> caller = + ime_adapter()->java_ime_adapter_for_testing(env); + + // Input string from Java side. + base::android::ScopedJavaLocalRef<jstring> jtext = + base::android::ConvertUTF8ToJavaString(env, text); + + // Simulating a native call from Java side. + ime_adapter()->CommitText( + env, base::android::JavaParamRef<jobject>(env, caller.obj()), + base::android::JavaParamRef<jobject>(env, jtext.obj()), + base::android::JavaParamRef<jstring>(env, jtext.obj()), 0); + } + + std::vector<RenderFrameHostImpl*> frames_; + + private: + DISALLOW_COPY_AND_ASSIGN(SitePerProcessAndroidImeTest); +}; + +// This test verifies that committing text will be applied on the focused +// RenderWidgetHost. +IN_PROC_BROWSER_TEST_F(SitePerProcessAndroidImeTest, + CommitTextForFocusedWidget) { + LoadPage(); + TextSelectionObserver selection_observer( + web_contents()->GetTextInputManager()); + for (size_t index = 0; index < frames_.size(); ++index) { + std::string text = base::StringPrintf("text%zu", index); + FocusInputInFrame(frames_[index]); + CommitText(text.c_str()); + selection_observer.WaitForSelectedText(text); + } +} +#endif // OS_ANDROID + } // namespace content
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index 2daf76a0..244b5d4 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc
@@ -930,7 +930,7 @@ RenderWidgetHostView* WebContentsImpl::GetFullscreenRenderWidgetHostView() const { - if (auto widget_host = GetFullscreenRenderWidgetHost()) + if (auto* widget_host = GetFullscreenRenderWidgetHost()) return widget_host->GetView(); return nullptr; } @@ -2587,6 +2587,24 @@ return NULL; WebContents* new_contents = delegate_->OpenURLFromTab(this, params); + + RenderFrameHost* source_render_frame_host = RenderFrameHost::FromID( + params.source_render_process_id, params.source_render_frame_id); + + if (source_render_frame_host && params.source_site_instance) { + CHECK_EQ(source_render_frame_host->GetSiteInstance(), + params.source_site_instance.get()); + } + + if (new_contents && source_render_frame_host && new_contents != this) { + for (auto& observer : observers_) { + observer.DidOpenRequestedURL(new_contents, source_render_frame_host, + params.url, params.referrer, + params.disposition, params.transition, + params.started_from_context_menu); + } + } + return new_contents; } @@ -3380,25 +3398,6 @@ observer.DidStartNavigationToPendingEntry(url, reload_type); } -void WebContentsImpl::RequestOpenURL(RenderFrameHostImpl* render_frame_host, - const OpenURLParams& params) { - // OpenURL can blow away the source RFH. Use the process/frame routing ID as a - // weak pointer of sorts. - const int32_t process_id = render_frame_host->GetProcess()->GetID(); - const int32_t frame_id = render_frame_host->GetRoutingID(); - - WebContents* new_contents = OpenURL(params); - - if (new_contents && RenderFrameHost::FromID(process_id, frame_id)) { - // Notify observers. - for (auto& observer : observers_) { - observer.DidOpenRequestedURL(new_contents, render_frame_host, params.url, - params.referrer, params.disposition, - params.transition); - } - } -} - bool WebContentsImpl::ShouldTransferNavigation(bool is_main_frame_navigation) { if (!delegate_) return true;
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h index c325f5a..813e35e 100644 --- a/content/browser/web_contents/web_contents_impl.h +++ b/content/browser/web_contents/web_contents_impl.h
@@ -599,8 +599,6 @@ void NotifyChangedNavigationState(InvalidateTypes changed_flags) override; void DidStartNavigationToPendingEntry(const GURL& url, ReloadType reload_type) override; - void RequestOpenURL(RenderFrameHostImpl* render_frame_host, - const OpenURLParams& params) override; bool ShouldTransferNavigation(bool is_main_frame_navigation) override; bool ShouldPreserveAbortedURLs() override; void DidStartLoading(FrameTreeNode* frame_tree_node,
diff --git a/content/browser/web_contents/web_contents_view_child_frame.cc b/content/browser/web_contents/web_contents_view_child_frame.cc index 60b0f56b..74a587a9 100644 --- a/content/browser/web_contents/web_contents_view_child_frame.cc +++ b/content/browser/web_contents/web_contents_view_child_frame.cc
@@ -152,7 +152,7 @@ } void WebContentsViewChildFrame::UpdateDragCursor(WebDragOperation operation) { - if (auto view = GetOuterDelegateView()) + if (auto* view = GetOuterDelegateView()) view->UpdateDragCursor(operation); } @@ -187,7 +187,7 @@ const gfx::Vector2d& image_offset, const DragEventSourceInfo& event_info, RenderWidgetHostImpl* source_rwh) { - if (auto view = GetOuterDelegateView()) { + if (auto* view = GetOuterDelegateView()) { view->StartDragging( drop_data, ops, image, image_offset, event_info, source_rwh); } else {
diff --git a/content/browser/websockets/websocket_manager.cc b/content/browser/websockets/websocket_manager.cc index 4d0e743c..87ef048 100644 --- a/content/browser/websockets/websocket_manager.cc +++ b/content/browser/websockets/websocket_manager.cc
@@ -115,7 +115,7 @@ if (!context_destroyed_ && url_request_context_getter_) url_request_context_getter_->RemoveObserver(this); - for (auto impl : impls_) { + for (auto* impl : impls_) { impl->GoAway(); delete impl; } @@ -225,7 +225,7 @@ void WebSocketManager::OnContextShuttingDown() { context_destroyed_ = true; url_request_context_getter_ = nullptr; - for (const auto& impl : impls_) { + for (auto* impl : impls_) { impl->GoAway(); delete impl; }
diff --git a/content/common/media/media_stream_messages.h b/content/common/media/media_stream_messages.h index 904cb26..c888f8c 100644 --- a/content/common/media/media_stream_messages.h +++ b/content/common/media/media_stream_messages.h
@@ -21,7 +21,7 @@ content::NUM_MEDIA_TYPES - 1) IPC_ENUM_TRAITS_MAX_VALUE(media::VideoFacingMode, - media::NUM_MEDIA_VIDEO_FACING_MODE - 1) + media::NUM_MEDIA_VIDEO_FACING_MODES - 1) IPC_ENUM_TRAITS_MAX_VALUE(content::MediaStreamRequestResult, content::NUM_MEDIA_REQUEST_RESULTS - 1)
diff --git a/content/common/url_schemes.cc b/content/common/url_schemes.cc index e2a9a2e..29a3c85 100644 --- a/content/common/url_schemes.cc +++ b/content/common/url_schemes.cc
@@ -79,7 +79,7 @@ // Combine the default savable schemes with the additional ones given. delete savable_schemes; savable_schemes = new std::vector<std::string>; - for (auto& default_scheme : kDefaultSavableSchemes) + for (auto* default_scheme : kDefaultSavableSchemes) savable_schemes->push_back(default_scheme); savable_schemes->insert(savable_schemes->end(), schemes.savable_schemes.begin(),
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java index 843b399..ac344eb 100644 --- a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java +++ b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
@@ -40,6 +40,7 @@ import android.view.inputmethod.InputConnection; import android.view.inputmethod.InputMethodManager; +import org.chromium.base.CommandLine; import org.chromium.base.ObserverList; import org.chromium.base.ObserverList.RewindableIterator; import org.chromium.base.TraceEvent; @@ -59,6 +60,7 @@ import org.chromium.content.browser.input.SelectPopupDialog; import org.chromium.content.browser.input.SelectPopupDropdown; import org.chromium.content.browser.input.SelectPopupItem; +import org.chromium.content.common.ContentSwitches; import org.chromium.content_public.browser.AccessibilitySnapshotCallback; import org.chromium.content_public.browser.AccessibilitySnapshotNode; import org.chromium.content_public.browser.ActionModeCallbackHelper; @@ -353,6 +355,9 @@ private float mCurrentTouchOffsetX; private float mCurrentTouchOffsetY; + // True if we want to disable Android native event batching and use compositor event queue. + private boolean mShouldRequestUnbufferedDispatch; + // Whether the ContentViewCore requires the WebContents to be fullscreen in order to lock the // screen orientation. private boolean mFullscreenRequiredForOrientationLock = true; @@ -584,6 +589,9 @@ mSelectionPopupController.setContainerView(getContainerView()); mWebContentsObserver = new ContentViewWebContentsObserver(this); + + mShouldRequestUnbufferedDispatch = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP + && CommandLine.getInstance().hasSwitch(ContentSwitches.REQUEST_UNBUFFERED_DISPATCH); } /** @@ -996,6 +1004,9 @@ int eventAction = event.getActionMasked(); if (eventAction == MotionEvent.ACTION_DOWN) { + if (mShouldRequestUnbufferedDispatch) { + requestUnbufferedDispatch(event); + } cancelRequestToScrollFocusedEditableNodeIntoView(); } @@ -2457,6 +2468,11 @@ viewNode.asyncCommit(); } + @TargetApi(Build.VERSION_CODES.LOLLIPOP) + private void requestUnbufferedDispatch(MotionEvent touchDownEvent) { + mContainerView.requestUnbufferedDispatch(touchDownEvent); + } + @TargetApi(Build.VERSION_CODES.KITKAT) @Override public void onSystemCaptioningChanged(TextTrackSettings settings) { @@ -2762,7 +2778,7 @@ private native int nativeSendMouseEvent(long nativeContentViewCoreImpl, long timeMs, int action, float x, float y, int pointerId, float pressure, float orientaton, float tilt, - int changedButton, int buttonState, int metaState, int toolType); + int actionButton, int buttonState, int metaState, int toolType); private native int nativeSendMouseWheelEvent(long nativeContentViewCoreImpl, long timeMs, float x, float y, float ticksX, float ticksY, float pixelsPerTick);
diff --git a/content/public/android/java/src/org/chromium/content/common/ContentSwitches.java b/content/public/android/java/src/org/chromium/content/common/ContentSwitches.java index a356d08..528f6df 100644 --- a/content/public/android/java/src/org/chromium/content/common/ContentSwitches.java +++ b/content/public/android/java/src/org/chromium/content/common/ContentSwitches.java
@@ -78,6 +78,9 @@ public static final String USE_FAKE_DEVICE_FOR_MEDIA_STREAM = "use-fake-device-for-media-stream"; + // Disable motion event batching through View.requestUnbufferedDispatch(). + public static final String REQUEST_UNBUFFERED_DISPATCH = "request-unbuffered-dispatch"; + // Prevent instantiation. private ContentSwitches() {}
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/ContentDetectionTestBase.java b/content/public/android/javatests/src/org/chromium/content/browser/ContentDetectionTestBase.java index 3ecf1a2..4a6fa245 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/ContentDetectionTestBase.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/ContentDetectionTestBase.java
@@ -67,7 +67,7 @@ callbackHelperContainer.getOnStartContentIntentHelper(); int currentCallCount = onStartContentIntentHelper.getCallCount(); - DOMUtils.clickNode(this, getContentViewCore(), id); + DOMUtils.clickNode(getContentViewCore(), id); onStartContentIntentHelper.waitForCallback(currentCallCount, 1, WAIT_TIMEOUT_SECONDS, TimeUnit.SECONDS); @@ -87,7 +87,7 @@ callbackHelperContainer.getOnPageFinishedHelper(); int currentCallCount = onPageFinishedHelper.getCallCount(); - DOMUtils.clickNode(this, getContentViewCore(), id); + DOMUtils.clickNode(getContentViewCore(), id); onPageFinishedHelper.waitForCallback(currentCallCount, 1, WAIT_TIMEOUT_SECONDS, TimeUnit.SECONDS);
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/ContentViewCoreSelectionTest.java b/content/public/android/javatests/src/org/chromium/content/browser/ContentViewCoreSelectionTest.java index 95126f44..4e061d8 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/ContentViewCoreSelectionTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/ContentViewCoreSelectionTest.java
@@ -62,7 +62,7 @@ public void testSelectionClearedAfterLossOfFocus() throws Throwable { requestFocusOnUiThread(true); - DOMUtils.longPressNode(this, mContentViewCore, "textarea"); + DOMUtils.longPressNode(mContentViewCore, "textarea"); waitForSelectActionBarVisible(true); requestFocusOnUiThread(false); @@ -80,7 +80,7 @@ public void testSelectionPreservedAfterLossOfFocusIfRequested() throws Throwable { requestFocusOnUiThread(true); - DOMUtils.longPressNode(this, mContentViewCore, "textarea"); + DOMUtils.longPressNode(mContentViewCore, "textarea"); waitForSelectActionBarVisible(true); assertTrue(mSelectionPopupController.hasSelection()); @@ -103,7 +103,7 @@ @Feature({"TextSelection"}) @DisabledTest(message = "crbug.com/592428") public void testSelectionPreservedAfterReshown() throws Throwable { - DOMUtils.longPressNode(this, mContentViewCore, "textarea"); + DOMUtils.longPressNode(mContentViewCore, "textarea"); waitForSelectActionBarVisible(true); assertTrue(mSelectionPopupController.hasSelection()); @@ -120,7 +120,7 @@ @Feature({"TextSelection"}) @DisabledTest(message = "crbug.com/592428") public void testSelectionPreservedAfterReattached() throws Throwable { - DOMUtils.longPressNode(this, mContentViewCore, "textarea"); + DOMUtils.longPressNode(mContentViewCore, "textarea"); waitForSelectActionBarVisible(true); assertTrue(mSelectionPopupController.hasSelection()); @@ -140,9 +140,9 @@ @DisabledTest(message = "https://crbug.com/592428") public void testPastePopupNotShownOnLongPressingNonEmptyInput() throws Throwable { copyStringToClipboard("SampleTextToCopy"); - DOMUtils.longPressNode(this, mContentViewCore, "empty_input_text"); + DOMUtils.longPressNode(mContentViewCore, "empty_input_text"); waitForPastePopupStatus(true); - DOMUtils.longPressNode(this, mContentViewCore, "input_text"); + DOMUtils.longPressNode(mContentViewCore, "input_text"); waitForSelectActionBarVisible(true); waitForPastePopupStatus(false); } @@ -151,9 +151,9 @@ @Feature({"TextInput"}) public void testPastePopupClearedOnTappingEmptyInput() throws Throwable { copyStringToClipboard("SampleTextToCopy"); - DOMUtils.longPressNode(this, mContentViewCore, "empty_input_text"); + DOMUtils.longPressNode(mContentViewCore, "empty_input_text"); waitForPastePopupStatus(true); - DOMUtils.clickNode(this, mContentViewCore, "empty_input_text"); + DOMUtils.clickNode(mContentViewCore, "empty_input_text"); waitForPastePopupStatus(false); } @@ -161,9 +161,9 @@ @Feature({"TextInput"}) public void testPastePopupClearedOnTappingNonEmptyInput() throws Throwable { copyStringToClipboard("SampleTextToCopy"); - DOMUtils.longPressNode(this, mContentViewCore, "empty_input_text"); + DOMUtils.longPressNode(mContentViewCore, "empty_input_text"); waitForPastePopupStatus(true); - DOMUtils.clickNode(this, mContentViewCore, "input_text"); + DOMUtils.clickNode(mContentViewCore, "input_text"); waitForPastePopupStatus(false); } @@ -171,9 +171,9 @@ @Feature({"TextInput"}) public void testPastePopupClearedOnTappingOutsideInput() throws Throwable { copyStringToClipboard("SampleTextToCopy"); - DOMUtils.longPressNode(this, mContentViewCore, "empty_input_text"); + DOMUtils.longPressNode(mContentViewCore, "empty_input_text"); waitForPastePopupStatus(true); - DOMUtils.clickNode(this, mContentViewCore, "plain_text_2"); + DOMUtils.clickNode(mContentViewCore, "plain_text_2"); waitForPastePopupStatus(false); } @@ -181,9 +181,9 @@ @Feature({"TextInput"}) public void testPastePopupClearedOnLongPressingOutsideInput() throws Throwable { copyStringToClipboard("SampleTextToCopy"); - DOMUtils.longPressNode(this, mContentViewCore, "empty_input_text"); + DOMUtils.longPressNode(mContentViewCore, "empty_input_text"); waitForPastePopupStatus(true); - DOMUtils.longPressNode(this, mContentViewCore, "plain_text_2"); + DOMUtils.longPressNode(mContentViewCore, "plain_text_2"); waitForPastePopupStatus(false); } @@ -191,10 +191,10 @@ @Feature({"TextInput"}) public void testPastePopupNotShownOnLongPressingDisabledInput() throws Throwable { copyStringToClipboard("SampleTextToCopy"); - DOMUtils.longPressNode(this, mContentViewCore, "empty_input_text"); + DOMUtils.longPressNode(mContentViewCore, "empty_input_text"); waitForPastePopupStatus(true); waitForInsertion(true); - DOMUtils.longPressNode(this, mContentViewCore, "disabled_text"); + DOMUtils.longPressNode(mContentViewCore, "disabled_text"); waitForPastePopupStatus(false); waitForInsertion(false); } @@ -206,7 +206,7 @@ @DisabledTest(message = "https://crbug.com/592428") public void testPastePopupDismissedOnDestroy() throws Throwable { copyStringToClipboard("SampleTextToCopy"); - DOMUtils.longPressNode(this, mContentViewCore, "empty_input_text"); + DOMUtils.longPressNode(mContentViewCore, "empty_input_text"); waitForPastePopupStatus(true); ThreadUtils.runOnUiThreadBlocking(new Runnable() { @Override @@ -221,7 +221,7 @@ @Feature({"TextInput"}) @DisabledTest(message = "crbug.com/592428") public void testActionBarConfiguredCorrectlyForInput() throws Throwable { - DOMUtils.longPressNode(this, mContentViewCore, "input_text"); + DOMUtils.longPressNode(mContentViewCore, "input_text"); waitForSelectActionBarVisible(true); assertTrue(mSelectionPopupController.hasSelection()); assertTrue(mSelectionPopupController.isActionModeValid()); @@ -233,7 +233,7 @@ @Feature({"TextInput"}) @DisabledTest(message = "crbug.com/592428") public void testActionBarConfiguredCorrectlyForPassword() throws Throwable { - DOMUtils.longPressNode(this, mContentViewCore, "password"); + DOMUtils.longPressNode(mContentViewCore, "password"); waitForSelectActionBarVisible(true); assertTrue(mSelectionPopupController.hasSelection()); assertTrue(mSelectionPopupController.isActionModeValid()); @@ -245,7 +245,7 @@ @Feature({"TextInput"}) @DisabledTest(message = "crbug.com/592428") public void testActionBarConfiguredCorrectlyForPlainText() throws Throwable { - DOMUtils.longPressNode(this, mContentViewCore, "plain_text_1"); + DOMUtils.longPressNode(mContentViewCore, "plain_text_1"); waitForSelectActionBarVisible(true); assertTrue(mSelectionPopupController.hasSelection()); assertTrue(mSelectionPopupController.isActionModeValid()); @@ -257,7 +257,7 @@ @Feature({"TextInput"}) @DisabledTest(message = "crbug.com/592428") public void testActionBarConfiguredCorrectlyForTextArea() throws Throwable { - DOMUtils.longPressNode(this, mContentViewCore, "textarea"); + DOMUtils.longPressNode(mContentViewCore, "textarea"); waitForSelectActionBarVisible(true); assertTrue(mSelectionPopupController.hasSelection()); assertTrue(mSelectionPopupController.isActionModeValid()); @@ -269,7 +269,7 @@ @Feature({"TextInput"}) @DisabledTest(message = "crbug.com/592428") public void testSelectActionBarPlainTextCopy() throws Exception { - DOMUtils.longPressNode(this, mContentViewCore, "plain_text_1"); + DOMUtils.longPressNode(mContentViewCore, "plain_text_1"); waitForSelectActionBarVisible(true); assertTrue(mSelectionPopupController.hasSelection()); assertTrue(mSelectionPopupController.isActionModeValid()); @@ -281,7 +281,7 @@ @Feature({"TextInput"}) @DisabledTest(message = "crbug.com/592428") public void testSelectActionBarInputCopy() throws Exception { - DOMUtils.longPressNode(this, mContentViewCore, "input_text"); + DOMUtils.longPressNode(mContentViewCore, "input_text"); waitForSelectActionBarVisible(true); assertTrue(mSelectionPopupController.hasSelection()); assertTrue(mSelectionPopupController.isActionModeValid()); @@ -293,13 +293,13 @@ @Feature({"TextInput"}) @DisabledTest(message = "crbug.com/592428") public void testSelectActionBarPasswordCopy() throws Exception { - DOMUtils.longPressNode(this, mContentViewCore, "plain_text_1"); + DOMUtils.longPressNode(mContentViewCore, "plain_text_1"); waitForSelectActionBarVisible(true); assertTrue(mSelectionPopupController.hasSelection()); assertTrue(mSelectionPopupController.isActionModeValid()); selectActionBarCopy(); waitForClipboardContents(mContentViewCore.getContext(), "SamplePlainTextOne"); - DOMUtils.longPressNode(this, mContentViewCore, "password"); + DOMUtils.longPressNode(mContentViewCore, "password"); waitForSelectActionBarVisible(true); assertTrue(mSelectionPopupController.hasSelection()); assertTrue(mSelectionPopupController.isActionModeValid()); @@ -313,7 +313,7 @@ @Feature({"TextInput"}) @DisabledTest(message = "crbug.com/592428") public void testSelectActionBarTextAreaCopy() throws Exception { - DOMUtils.longPressNode(this, mContentViewCore, "textarea"); + DOMUtils.longPressNode(mContentViewCore, "textarea"); waitForSelectActionBarVisible(true); assertTrue(mSelectionPopupController.hasSelection()); assertTrue(mSelectionPopupController.isActionModeValid()); @@ -326,7 +326,7 @@ @DisabledTest(message = "crbug.com/592428") public void testSelectActionBarPlainTextCut() throws Exception { copyStringToClipboard("SampleTextToCopy"); - DOMUtils.longPressNode(this, mContentViewCore, "plain_text_1"); + DOMUtils.longPressNode(mContentViewCore, "plain_text_1"); waitForSelectActionBarVisible(true); assertTrue(mSelectionPopupController.hasSelection()); assertEquals(mSelectionPopupController.getSelectedText(), "SamplePlainTextOne"); @@ -343,7 +343,7 @@ @Feature({"TextInput"}) @DisabledTest(message = "crbug.com/592428") public void testSelectActionBarInputCut() throws Exception { - DOMUtils.longPressNode(this, mContentViewCore, "input_text"); + DOMUtils.longPressNode(mContentViewCore, "input_text"); waitForSelectActionBarVisible(true); assertTrue(mSelectionPopupController.hasSelection()); assertEquals(mSelectionPopupController.getSelectedText(), "SampleInputText"); @@ -360,7 +360,7 @@ @DisabledTest(message = "crbug.com/592428") public void testSelectActionBarPasswordCut() throws Exception { copyStringToClipboard("SampleTextToCopy"); - DOMUtils.longPressNode(this, mContentViewCore, "password"); + DOMUtils.longPressNode(mContentViewCore, "password"); waitForSelectActionBarVisible(true); assertTrue(mSelectionPopupController.hasSelection()); assertTrue(mSelectionPopupController.isActionModeValid()); @@ -376,7 +376,7 @@ @Feature({"TextInput"}) @DisabledTest(message = "crbug.com/592428") public void testSelectActionBarTextAreaCut() throws Exception { - DOMUtils.longPressNode(this, mContentViewCore, "textarea"); + DOMUtils.longPressNode(mContentViewCore, "textarea"); waitForSelectActionBarVisible(true); assertTrue(mSelectionPopupController.hasSelection()); assertEquals(mSelectionPopupController.getSelectedText(), "SampleTextArea"); @@ -392,7 +392,7 @@ @Feature({"TextSelection"}) @DisabledTest(message = "crbug.com/592428") public void testSelectActionBarPlainTextSelectAll() throws Exception { - DOMUtils.longPressNode(this, mContentViewCore, "plain_text_1"); + DOMUtils.longPressNode(mContentViewCore, "plain_text_1"); waitForSelectActionBarVisible(true); assertTrue(mSelectionPopupController.hasSelection()); assertTrue(mSelectionPopupController.isActionModeValid()); @@ -405,7 +405,7 @@ @Feature({"TextInput"}) @DisabledTest(message = "crbug.com/592428") public void testSelectActionBarInputSelectAll() throws Exception { - DOMUtils.longPressNode(this, mContentViewCore, "input_text"); + DOMUtils.longPressNode(mContentViewCore, "input_text"); waitForSelectActionBarVisible(true); assertTrue(mSelectionPopupController.hasSelection()); assertTrue(mSelectionPopupController.isActionModeValid()); @@ -419,7 +419,7 @@ @Feature({"TextInput"}) @DisabledTest(message = "crbug.com/592428") public void testSelectActionBarPasswordSelectAll() throws Exception { - DOMUtils.longPressNode(this, mContentViewCore, "password"); + DOMUtils.longPressNode(mContentViewCore, "password"); waitForSelectActionBarVisible(true); assertTrue(mSelectionPopupController.hasSelection()); assertTrue(mSelectionPopupController.isActionModeValid()); @@ -432,7 +432,7 @@ @Feature({"TextInput"}) @DisabledTest(message = "crbug.com/592428") public void testSelectActionBarTextAreaSelectAll() throws Exception { - DOMUtils.longPressNode(this, mContentViewCore, "textarea"); + DOMUtils.longPressNode(mContentViewCore, "textarea"); waitForSelectActionBarVisible(true); assertTrue(mSelectionPopupController.hasSelection()); assertTrue(mSelectionPopupController.isActionModeValid()); @@ -460,7 +460,7 @@ */ @DisabledTest(message = "http://crbug.com/606942") public void testCursorPositionAfterHidingActionMode() throws Exception { - DOMUtils.longPressNode(this, mContentViewCore, "textarea"); + DOMUtils.longPressNode(mContentViewCore, "textarea"); waitForSelectActionBarVisible(true); assertTrue(mSelectionPopupController.hasSelection()); assertTrue(mSelectionPopupController.isActionModeValid()); @@ -484,12 +484,12 @@ @DisabledTest(message = "crbug.com/592428") public void testSelectActionBarPlainTextPaste() throws Exception { copyStringToClipboard("SampleTextToCopy"); - DOMUtils.longPressNode(this, mContentViewCore, "plain_text_1"); + DOMUtils.longPressNode(mContentViewCore, "plain_text_1"); waitForSelectActionBarVisible(true); assertTrue(mSelectionPopupController.hasSelection()); assertTrue(mSelectionPopupController.isActionModeValid()); selectActionBarPaste(); - DOMUtils.longPressNode(this, mContentViewCore, "plain_text_1"); + DOMUtils.longPressNode(mContentViewCore, "plain_text_1"); waitForSelectActionBarVisible(true); assertTrue(mSelectionPopupController.hasSelection()); // Paste option won't be available for plain text. @@ -504,7 +504,7 @@ copyStringToClipboard("SampleTextToCopy"); // Select the input field. - DOMUtils.longPressNode(this, mContentViewCore, "input_text"); + DOMUtils.longPressNode(mContentViewCore, "input_text"); waitForSelectActionBarVisible(true); assertTrue(mSelectionPopupController.hasSelection()); @@ -515,7 +515,7 @@ assertFalse(mSelectionPopupController.hasSelection()); // Ensure the new text matches the pasted text. - DOMUtils.longPressNode(this, mContentViewCore, "input_text"); + DOMUtils.longPressNode(mContentViewCore, "input_text"); waitForSelectActionBarVisible(true); assertTrue(mSelectionPopupController.hasSelection()); assertEquals("SampleTextToCopy", mSelectionPopupController.getSelectedText()); @@ -530,7 +530,7 @@ copyStringToClipboard("SamplePassword2"); // Select the password field. - DOMUtils.longPressNode(this, mContentViewCore, "password"); + DOMUtils.longPressNode(mContentViewCore, "password"); waitForSelectActionBarVisible(true); assertTrue(mSelectionPopupController.hasSelection()); assertEquals(mSelectionPopupController.getSelectedText().length(), @@ -546,7 +546,7 @@ // Ensure the new text matches the pasted text. Note that we can't // actually compare strings as password field selections only provide // a placeholder with the correct length. - DOMUtils.longPressNode(this, mContentViewCore, "password"); + DOMUtils.longPressNode(mContentViewCore, "password"); waitForSelectActionBarVisible(true); assertTrue(mSelectionPopupController.hasSelection()); assertEquals(mSelectionPopupController.getSelectedText().length(), @@ -558,13 +558,13 @@ @DisabledTest(message = "crbug.com/592428") public void testSelectActionBarTextAreaPaste() throws Exception { copyStringToClipboard("SampleTextToCopy"); - DOMUtils.longPressNode(this, mContentViewCore, "textarea"); + DOMUtils.longPressNode(mContentViewCore, "textarea"); waitForSelectActionBarVisible(true); assertTrue(mSelectionPopupController.hasSelection()); assertTrue(mSelectionPopupController.isActionModeValid()); selectActionBarPaste(); - DOMUtils.clickNode(this, mContentViewCore, "plain_text_1"); - DOMUtils.longPressNode(this, mContentViewCore, "textarea"); + DOMUtils.clickNode(mContentViewCore, "plain_text_1"); + DOMUtils.longPressNode(mContentViewCore, "textarea"); waitForSelectActionBarVisible(true); assertTrue(mSelectionPopupController.hasSelection()); assertEquals(mSelectionPopupController.getSelectedText(), "SampleTextToCopy"); @@ -574,7 +574,7 @@ @Feature({"TextInput"}) @DisabledTest(message = "crbug.com/592428") public void testSelectActionBarSearchAndShareLaunchesNewTask() throws Exception { - DOMUtils.longPressNode(this, mContentViewCore, "textarea"); + DOMUtils.longPressNode(mContentViewCore, "textarea"); waitForSelectActionBarVisible(true); assertTrue(mSelectionPopupController.hasSelection()); assertTrue(mSelectionPopupController.isActionModeValid());
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/ContentViewPopupZoomerTest.java b/content/public/android/javatests/src/org/chromium/content/browser/ContentViewPopupZoomerTest.java index bf6c9db..a2ad3824 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/ContentViewPopupZoomerTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/ContentViewPopupZoomerTest.java
@@ -98,7 +98,7 @@ CriteriaHelper.pollInstrumentationThread(new PopupShowingCriteria(view, false)); // Once clicked, the popup should show up. - DOMUtils.clickNode(this, viewCore, "clickme"); + DOMUtils.clickNode(viewCore, "clickme"); CriteriaHelper.pollInstrumentationThread(new PopupShowingCriteria(view, true)); // The shown popup should have valid dimensions eventually. @@ -119,7 +119,7 @@ final ViewGroup view = viewCore.getContainerView(); CriteriaHelper.pollInstrumentationThread(new PopupShowingCriteria(view, false)); - DOMUtils.clickNode(this, viewCore, "clickme"); + DOMUtils.clickNode(viewCore, "clickme"); CriteriaHelper.pollInstrumentationThread(new PopupShowingCriteria(view, true)); sendKeys(KeyEvent.KEYCODE_BACK); // When device key is pressed, popup zoomer should hide if already showing.
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/GestureDetectorResetTest.java b/content/public/android/javatests/src/org/chromium/content/browser/GestureDetectorResetTest.java index c935edd..497299d 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/GestureDetectorResetTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/GestureDetectorResetTest.java
@@ -78,7 +78,7 @@ "test", "not clicked")); // Click the button. - DOMUtils.clickNode(this, contentViewCore, "button"); + DOMUtils.clickNode(contentViewCore, "button"); // After the click, the text on the page should say "clicked". CriteriaHelper.pollInstrumentationThread(new NodeContentsIsEqualToCriteria(
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/VideoFullscreenOrientationLockTest.java b/content/public/android/javatests/src/org/chromium/content/browser/VideoFullscreenOrientationLockTest.java index 4b56c75..642f5666 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/VideoFullscreenOrientationLockTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/VideoFullscreenOrientationLockTest.java
@@ -139,7 +139,7 @@ DOMUtils.waitForMediaPlay(getWebContents(), VIDEO_ID); // Trigger requestFullscreen() via a click on a button. - assertTrue(DOMUtils.clickNode(this, getContentViewCore(), "fullscreen")); + assertTrue(DOMUtils.clickNode(getContentViewCore(), "fullscreen")); waitForContentsFullscreenState(true); // Should be landscape now, `waitForLandscapeOrientation` will throw otherwise.
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/input/ImeTest.java b/content/public/android/javatests/src/org/chromium/content/browser/input/ImeTest.java index c129157c..41f43d8b 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/input/ImeTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/input/ImeTest.java
@@ -110,7 +110,7 @@ mCallbackContainer = new TestCallbackHelperContainer(mContentViewCore); DOMUtils.waitForNonZeroNodeBounds(mWebContents, "input_text"); - boolean result = DOMUtils.clickNode(this, mContentViewCore, "input_text"); + boolean result = DOMUtils.clickNode(mContentViewCore, "input_text"); assertEquals("Failed to dispatch touch event.", true, result); assertWaitForKeyboardStatus(true); @@ -148,7 +148,7 @@ fullyLoadUrl(UrlUtils.getIsolatedTestFileUrl(INPUT_FORM_HTML)); assertWaitForKeyboardStatus(false); - DOMUtils.clickNode(this, mContentViewCore, "input_text"); + DOMUtils.clickNode(mContentViewCore, "input_text"); assertWaitForKeyboardStatus(true); // Hide keyboard when navigating. @@ -257,7 +257,7 @@ waitAndVerifyUpdateSelection(2, 3, 3, 2, 3); // Unexpected selection change occurs, e.g., the user clicks on an area. - DOMUtils.clickNode(this, mContentViewCore, "textarea"); + DOMUtils.clickNode(mContentViewCore, "textarea"); waitAndVerifyUpdateSelection(3, 5, 5, 2, 3); // Keyboard app finishes composition. We emulate this in TestInputMethodManagerWrapper. waitAndVerifyUpdateSelection(4, 5, 5, -1, -1); @@ -452,7 +452,7 @@ commitText("hello", 1); waitAndVerifyUpdateSelection(0, 5, 5, -1, -1); restartInput(); - DOMUtils.clickNode(this, mContentViewCore, "input_text"); + DOMUtils.clickNode(mContentViewCore, "input_text"); assertWaitForKeyboardStatus(true); assertEquals(5, mConnectionFactory.getOutAttrs().initialSelStart); @@ -577,7 +577,7 @@ waitAndVerifyUpdateSelection(0, 11, 11, -1, -1); // Select 'text' part. - DOMUtils.longPressNode(this, mContentViewCore, "input_text"); + DOMUtils.longPressNode(mContentViewCore, "input_text"); assertWaitForSelectActionBarStatus(true); @@ -593,7 +593,7 @@ public void testImeNotDismissedAfterCutSelection() throws Exception { commitText("Sample Text", 1); waitAndVerifyUpdateSelection(0, 11, 11, -1, -1); - DOMUtils.longPressNode(this, mContentViewCore, "input_text"); + DOMUtils.longPressNode(mContentViewCore, "input_text"); assertWaitForSelectActionBarStatus(true); assertWaitForKeyboardStatus(true); cut(); @@ -605,20 +605,20 @@ @Feature({"TextInput"}) public void testImeNotShownOnLongPressingEmptyInput() throws Exception { DOMUtils.focusNode(mWebContents, "input_radio"); - DOMUtils.longPressNode(this, mContentViewCore, "input_text"); + DOMUtils.longPressNode(mContentViewCore, "input_text"); assertWaitForKeyboardStatus(false); commitText("Sample Text", 1); - DOMUtils.longPressNode(this, mContentViewCore, "input_text"); + DOMUtils.longPressNode(mContentViewCore, "input_text"); assertWaitForKeyboardStatus(true); } @SmallTest @Feature({"TextInput"}) public void testSelectActionBarShownOnLongPressingInput() throws Exception { - DOMUtils.longPressNode(this, mContentViewCore, "input_text"); + DOMUtils.longPressNode(mContentViewCore, "input_text"); assertWaitForSelectActionBarStatus(false); commitText("Sample Text", 1); - DOMUtils.longPressNode(this, mContentViewCore, "input_text"); + DOMUtils.longPressNode(mContentViewCore, "input_text"); assertWaitForSelectActionBarStatus(true); } @@ -628,7 +628,7 @@ assertWaitForSelectActionBarStatus(false); setComposingText("Sample Text", 1); waitAndVerifyUpdateSelection(0, 11, 11, 0, 11); - DOMUtils.longPressNode(this, mContentViewCore, "input_text"); + DOMUtils.longPressNode(mContentViewCore, "input_text"); assertWaitForSelectActionBarStatus(true); @@ -650,14 +650,14 @@ commitText("Sample Text", 1); int showCount = mInputMethodManagerWrapper.getShowSoftInputCounter(); - DOMUtils.longPressNode(this, mContentViewCore, "input_text"); + DOMUtils.longPressNode(mContentViewCore, "input_text"); assertWaitForSelectActionBarStatus(true); assertEquals(showCount + 1, mInputMethodManagerWrapper.getShowSoftInputCounter()); // Now long press again. Selection region remains the same, but the logic // should trigger IME to show up. Note that Android does not provide show / // hide status of IME, so we will just check whether showIme() has been triggered. - DOMUtils.longPressNode(this, mContentViewCore, "input_text"); + DOMUtils.longPressNode(mContentViewCore, "input_text"); final int newCount = showCount + 2; CriteriaHelper.pollUiThread(Criteria.equals(newCount, new Callable<Integer>() { @Override @@ -738,10 +738,10 @@ @Feature({"TextInput"}) public void testSelectActionBarClearedOnTappingInput() throws Exception { commitText("Sample Text", 1); - DOMUtils.longPressNode(this, mContentViewCore, "input_text"); + DOMUtils.longPressNode(mContentViewCore, "input_text"); assertWaitForKeyboardStatus(true); assertWaitForSelectActionBarStatus(true); - DOMUtils.clickNode(this, mContentViewCore, "input_text"); + DOMUtils.clickNode(mContentViewCore, "input_text"); assertWaitForSelectActionBarStatus(false); } @@ -749,10 +749,10 @@ @Feature({"TextInput"}) public void testSelectActionBarClearedOnTappingOutsideInput() throws Exception { commitText("Sample Text", 1); - DOMUtils.longPressNode(this, mContentViewCore, "input_text"); + DOMUtils.longPressNode(mContentViewCore, "input_text"); assertWaitForKeyboardStatus(true); assertWaitForSelectActionBarStatus(true); - DOMUtils.clickNode(this, mContentViewCore, "input_radio"); + DOMUtils.clickNode(mContentViewCore, "input_radio"); assertWaitForKeyboardStatus(false); assertWaitForSelectActionBarStatus(false); } @@ -761,9 +761,9 @@ @Feature({"TextInput"}) public void testImeNotShownOnLongPressingDifferentEmptyInputs() throws Exception { DOMUtils.focusNode(mWebContents, "input_radio"); - DOMUtils.longPressNode(this, mContentViewCore, "input_text"); + DOMUtils.longPressNode(mContentViewCore, "input_text"); assertWaitForKeyboardStatus(false); - DOMUtils.longPressNode(this, mContentViewCore, "textarea"); + DOMUtils.longPressNode(mContentViewCore, "textarea"); assertWaitForKeyboardStatus(false); } @@ -783,11 +783,11 @@ commitText("Sample Text", 1); waitAndVerifyUpdateSelection(2, 11, 11, -1, -1); - DOMUtils.longPressNode(this, mContentViewCore, "input_text"); + DOMUtils.longPressNode(mContentViewCore, "input_text"); assertWaitForKeyboardStatus(true); assertWaitForSelectActionBarStatus(true); - DOMUtils.longPressNode(this, mContentViewCore, "textarea"); + DOMUtils.longPressNode(mContentViewCore, "textarea"); assertWaitForKeyboardStatus(true); } @@ -1215,7 +1215,7 @@ waitAndVerifyUpdateSelection(2, 0, 0, -1, -1); assertTextsAroundCursor("", null, ""); - DOMUtils.longPressNode(this, mContentViewCore, "input_text"); + DOMUtils.longPressNode(mContentViewCore, "input_text"); CriteriaHelper.pollUiThread(new Criteria() { @Override public boolean isSatisfied() { @@ -1240,7 +1240,7 @@ commitText("Sample Text", 1); waitAndVerifyUpdateSelection(0, 11, 11, -1, -1); - DOMUtils.longPressNode(this, mContentViewCore, "input_text"); + DOMUtils.longPressNode(mContentViewCore, "input_text"); assertWaitForSelectActionBarStatus(true); setComposingText("h", 1); @@ -1251,7 +1251,7 @@ @SmallTest @Feature({"TextInput"}) public void testTextHandlesPreservedWithDpadNavigation() throws Throwable { - DOMUtils.longPressNode(this, mContentViewCore, "plain_text"); + DOMUtils.longPressNode(mContentViewCore, "plain_text"); assertWaitForSelectActionBarStatus(true); assertTrue(mSelectionPopupController.hasSelection());
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/input/SelectPopupTest.java b/content/public/android/javatests/src/org/chromium/content/browser/input/SelectPopupTest.java index 98dc29a..380b99f 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/input/SelectPopupTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/input/SelectPopupTest.java
@@ -87,7 +87,7 @@ final OnPageFinishedHelper onPageFinishedHelper = viewClient.getOnPageFinishedHelper(); // Once clicked, the popup should show up. - DOMUtils.clickNode(this, viewCore, "select"); + DOMUtils.clickNode(viewCore, "select"); CriteriaHelper.pollInstrumentationThread(new PopupShowingCriteria()); // Reload the test page. @@ -106,7 +106,7 @@ CriteriaHelper.pollInstrumentationThread(new PopupHiddenCriteria()); // Click the select and wait for the popup to show. - DOMUtils.clickNode(this, viewCore, "select"); + DOMUtils.clickNode(viewCore, "select"); CriteriaHelper.pollInstrumentationThread(new PopupShowingCriteria()); } }
diff --git a/content/public/browser/media_capture_devices.h b/content/public/browser/media_capture_devices.h index 925fff6..9ed92c2a 100644 --- a/content/public/browser/media_capture_devices.h +++ b/content/public/browser/media_capture_devices.h
@@ -6,6 +6,7 @@ #define CONTENT_PUBLIC_BROWSER_MEDIA_CAPTURE_DEVICES_H_ #include "content/public/common/media_stream_request.h" +#include "media/base/video_facing.h" namespace content { @@ -20,6 +21,10 @@ virtual const MediaStreamDevices& GetAudioCaptureDevices() = 0; virtual const MediaStreamDevices& GetVideoCaptureDevices() = 0; + virtual void AddVideoCaptureObserver( + media::VideoCaptureObserver* observer) = 0; + virtual void RemoveAllVideoCaptureObservers() = 0; + private: // This interface should only be implemented inside content. friend class MediaCaptureDevicesImpl;
diff --git a/content/public/browser/page_navigator.h b/content/public/browser/page_navigator.h index 945c96e..eb9e6a8 100644 --- a/content/public/browser/page_navigator.h +++ b/content/public/browser/page_navigator.h
@@ -15,8 +15,10 @@ #include "content/common/content_export.h" #include "content/public/browser/global_request_id.h" #include "content/public/browser/site_instance.h" +#include "content/public/common/child_process_host.h" #include "content/public/common/referrer.h" #include "content/public/common/resource_request_body.h" +#include "ipc/ipc_message.h" #include "ui/base/page_transition_types.h" #include "ui/base/window_open_disposition.h" #include "url/gurl.h" @@ -71,6 +73,12 @@ // The browser-global FrameTreeNode ID or -1 to indicate the main frame. int frame_tree_node_id; + // Routing id of the source RenderFrameHost. + int source_render_frame_id = MSG_ROUTING_NONE; + + // Process id of the source RenderFrameHost. + int source_render_process_id = ChildProcessHost::kInvalidUniqueID; + // The disposition requested by the navigation source. WindowOpenDisposition disposition;
diff --git a/content/public/browser/web_contents_observer.h b/content/public/browser/web_contents_observer.h index df27b290..374ad4b8 100644 --- a/content/public/browser/web_contents_observer.h +++ b/content/public/browser/web_contents_observer.h
@@ -274,7 +274,8 @@ const GURL& url, const Referrer& referrer, WindowOpenDisposition disposition, - ui::PageTransition transition) {} + ui::PageTransition transition, + bool started_from_context_menu) {} // This method is invoked when the renderer process has completed its first // paint after a non-empty layout.
diff --git a/content/public/common/url_constants.cc b/content/public/common/url_constants.cc index bd9d6147..067355d4 100644 --- a/content/public/common/url_constants.cc +++ b/content/public/common/url_constants.cc
@@ -46,6 +46,7 @@ const char kChromeUIWebRTCInternalsHost[] = "webrtc-internals"; const char kChromeUIBadCastCrashURL[] = "chrome://badcastcrash/"; +const char kChromeUICheckCrashURL[] = "chrome://checkcrash/"; const char kChromeUIBrowserCrashURL[] = "chrome://inducebrowsercrashforrealz/"; const char kChromeUIBrowserUIHang[] = "chrome://uithreadhang/"; const char kChromeUICrashURL[] = "chrome://crash/";
diff --git a/content/public/common/url_constants.h b/content/public/common/url_constants.h index cda43044..561265d 100644 --- a/content/public/common/url_constants.h +++ b/content/public/common/url_constants.h
@@ -55,6 +55,7 @@ // Full about URLs (including schemes). CONTENT_EXPORT extern const char kChromeUIBadCastCrashURL[]; +CONTENT_EXPORT extern const char kChromeUICheckCrashURL[]; CONTENT_EXPORT extern const char kChromeUIBrowserCrashURL[]; CONTENT_EXPORT extern const char kChromeUIBrowserUIHang[]; CONTENT_EXPORT extern const char kChromeUICrashURL[];
diff --git a/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/DOMUtils.java b/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/DOMUtils.java index 48e2f95..1d87d5c 100644 --- a/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/DOMUtils.java +++ b/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/DOMUtils.java
@@ -7,7 +7,6 @@ import static org.chromium.base.test.util.ScalableTimeout.scaleTimeout; import android.graphics.Rect; -import android.test.ActivityInstrumentationTestCase2; import android.util.JsonReader; import junit.framework.Assert; @@ -225,12 +224,10 @@ /** * Click a DOM node by its id, scrolling it into view first. - * @param activityTestCase The ActivityInstrumentationTestCase2 to instrument. * @param viewCore The ContentViewCore in which the node lives. * @param nodeId The id of the node. */ - public static boolean clickNode(ActivityInstrumentationTestCase2 activityTestCase, - final ContentViewCore viewCore, String nodeId) + public static boolean clickNode(final ContentViewCore viewCore, String nodeId) throws InterruptedException, TimeoutException { scrollNodeIntoView(viewCore.getWebContents(), nodeId); int[] clickTarget = getClickTargetForNode(viewCore, nodeId); @@ -240,12 +237,10 @@ /** * Click a DOM node returned by JS code, scrolling it into view first. - * @param activityTestCase The ActivityInstrumentationTestCase2 to instrument. * @param viewCore The ContentViewCore in which the node lives. * @param jsCode The JS code to find the node. */ - public static void clickNodeByJs(ActivityInstrumentationTestCase2 activityTestCase, - final ContentViewCore viewCore, String jsCode) + public static void clickNodeByJs(final ContentViewCore viewCore, String jsCode) throws InterruptedException, TimeoutException { scrollNodeIntoViewByJs(viewCore.getWebContents(), jsCode); int[] clickTarget = getClickTargetForNodeByJs(viewCore, jsCode); @@ -266,28 +261,24 @@ /** * Long-press a DOM node by its id, scrolling it into view first. - * @param activityTestCase The ActivityInstrumentationTestCase2 to instrument. * @param viewCore The ContentViewCore in which the node lives. * @param nodeId The id of the node. */ - public static void longPressNode(ActivityInstrumentationTestCase2 activityTestCase, - final ContentViewCore viewCore, String nodeId) + public static void longPressNode(final ContentViewCore viewCore, String nodeId) throws InterruptedException, TimeoutException { scrollNodeIntoView(viewCore.getWebContents(), nodeId); String jsCode = "document.getElementById('" + nodeId + "')"; - longPressNodeByJs(activityTestCase, viewCore, jsCode); + longPressNodeByJs(viewCore, jsCode); } /** * Long-press a DOM node by its id. * <p>Note that content view should be located in the current position for a foreseeable * amount of time because this involves sleep to simulate touch to long press transition. - * @param activityTestCase The ActivityInstrumentationTestCase2 to instrument. * @param viewCore The ContentViewCore in which the node lives. * @param nodeId The id of the node. */ - public static void longPressNodeByJs(ActivityInstrumentationTestCase2 activityTestCase, - final ContentViewCore viewCore, String jsCode) + public static void longPressNodeByJs(final ContentViewCore viewCore, String jsCode) throws InterruptedException, TimeoutException { int[] clickTarget = getClickTargetForNodeByJs(viewCore, jsCode); TouchCommon.longPressView(viewCore.getContainerView(), clickTarget[0], clickTarget[1]);
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn index a5fa46e..70b0c78 100644 --- a/content/renderer/BUILD.gn +++ b/content/renderer/BUILD.gn
@@ -607,12 +607,6 @@ "media/media_stream_video_track.h", "media/peer_connection_tracker.cc", "media/peer_connection_tracker.h", - "media/recorder/audio_track_recorder.cc", - "media/recorder/audio_track_recorder.h", - "media/recorder/media_recorder_handler.cc", - "media/recorder/media_recorder_handler.h", - "media/recorder/video_track_recorder.cc", - "media/recorder/video_track_recorder.h", "media/remote_media_stream_impl.cc", "media/remote_media_stream_impl.h", "media/rtc_certificate.cc", @@ -674,6 +668,12 @@ "media/webrtc_logging.h", "media/webrtc_uma_histograms.cc", "media/webrtc_uma_histograms.h", + "media_recorder/audio_track_recorder.cc", + "media_recorder/audio_track_recorder.h", + "media_recorder/media_recorder_handler.cc", + "media_recorder/media_recorder_handler.h", + "media_recorder/video_track_recorder.cc", + "media_recorder/video_track_recorder.h", "p2p/empty_network_manager.cc", "p2p/empty_network_manager.h", "p2p/filtering_network_manager.cc",
diff --git a/content/renderer/image_downloader/image_downloader_base.cc b/content/renderer/image_downloader/image_downloader_base.cc index e1aa9f5..fffdeb3e 100644 --- a/content/renderer/image_downloader/image_downloader_base.cc +++ b/content/renderer/image_downloader/image_downloader_base.cc
@@ -123,7 +123,7 @@ } void ImageDownloaderBase::OnDestruct() { - for (auto fetchers : image_fetchers_) { + for (auto* fetchers : image_fetchers_) { // Will run callbacks with an empty image vector. fetchers->OnRenderFrameDestruct(); }
diff --git a/content/renderer/input/main_thread_event_queue.cc b/content/renderer/input/main_thread_event_queue.cc index b629b40..d7337c6 100644 --- a/content/renderer/input/main_thread_event_queue.cc +++ b/content/renderer/input/main_thread_event_queue.cc
@@ -42,13 +42,16 @@ EventWithDispatchType::~EventWithDispatchType() {} void EventWithDispatchType::CoalesceWith(const EventWithDispatchType& other) { - if (other.dispatch_type_ == DISPATCH_TYPE_BLOCKING) { + // If this event was blocking push the event id to the blocking + // list before updating the dispatch_type of this event. + if (dispatch_type_ == DISPATCH_TYPE_BLOCKING) { blocking_coalesced_event_ids_.push_back( - ui::WebInputEventTraits::GetUniqueTouchEventId(other.event())); + ui::WebInputEventTraits::GetUniqueTouchEventId(event())); } else { non_blocking_coalesced_count_++; } ScopedWebInputEventWithLatencyInfo::CoalesceWith(other); + dispatch_type_ = other.dispatch_type_; last_coalesced_timestamp_ = base::TimeTicks::Now(); }
diff --git a/content/renderer/input/main_thread_event_queue_unittest.cc b/content/renderer/input/main_thread_event_queue_unittest.cc index cda96df..2cdd7c4 100644 --- a/content/renderer/input/main_thread_event_queue_unittest.cc +++ b/content/renderer/input/main_thread_event_queue_unittest.cc
@@ -343,8 +343,13 @@ EXPECT_EQ(0u, event_queue().size()); EXPECT_EQ(2u, additional_acked_events_.size()); - EXPECT_EQ(kEvents[2].uniqueTouchEventId, additional_acked_events_.at(0)); - EXPECT_EQ(kEvents[3].uniqueTouchEventId, additional_acked_events_.at(1)); + EXPECT_EQ(kEvents[1].uniqueTouchEventId, additional_acked_events_.at(0)); + EXPECT_EQ(kEvents[2].uniqueTouchEventId, additional_acked_events_.at(1)); + + const WebTouchEvent* last_touch_event = + static_cast<const WebTouchEvent*>(handled_events_.at(1).eventPointer()); + EXPECT_EQ(kEvents[3].uniqueTouchEventId, + last_touch_event->uniqueTouchEventId); HandleEvent(kEvents[1], INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING); HandleEvent(kEvents[2], INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING); @@ -532,14 +537,14 @@ EXPECT_FALSE(main_task_runner_->HasPendingTask()); EXPECT_EQ(0u, event_queue().size()); - // Send a continuous input event (ack required) and then - // a discrete event. The events should coalesce together + // Send a discrete input event and then a continuous + // (ack required) event. The events should coalesce together // and a post task should be on the queue at the end. - HandleEvent(kEvents[0], INPUT_EVENT_ACK_STATE_NOT_CONSUMED); + HandleEvent(kEvents[1], INPUT_EVENT_ACK_STATE_NOT_CONSUMED); EXPECT_EQ(1u, event_queue().size()); EXPECT_FALSE(main_task_runner_->HasPendingTask()); EXPECT_TRUE(needs_main_frame_); - HandleEvent(kEvents[1], INPUT_EVENT_ACK_STATE_NOT_CONSUMED); + HandleEvent(kEvents[0], INPUT_EVENT_ACK_STATE_NOT_CONSUMED); EXPECT_EQ(1u, event_queue().size()); EXPECT_FALSE(main_task_runner_->HasPendingTask()); EXPECT_TRUE(needs_main_frame_);
diff --git a/content/renderer/media/DEPS b/content/renderer/media/DEPS index 3702908..3dfd058 100644 --- a/content/renderer/media/DEPS +++ b/content/renderer/media/DEPS
@@ -1,7 +1,4 @@ include_rules = [ - "+third_party/libvpx", "+third_party/libyuv", - '+third_party/openh264/src/codec/api/svc', - '+third_party/opus', '+third_party/webrtc_overrides', ]
diff --git a/content/renderer/media_recorder/DEPS b/content/renderer/media_recorder/DEPS new file mode 100644 index 0000000..59fe857 --- /dev/null +++ b/content/renderer/media_recorder/DEPS
@@ -0,0 +1,6 @@ +include_rules = [ + "+third_party/libvpx", + "+third_party/libyuv", + '+third_party/openh264/src/codec/api/svc', + '+third_party/opus', +]
diff --git a/content/renderer/media/recorder/OWNERS b/content/renderer/media_recorder/OWNERS similarity index 100% rename from content/renderer/media/recorder/OWNERS rename to content/renderer/media_recorder/OWNERS
diff --git a/content/renderer/media/recorder/audio_track_recorder.cc b/content/renderer/media_recorder/audio_track_recorder.cc similarity index 99% rename from content/renderer/media/recorder/audio_track_recorder.cc rename to content/renderer/media_recorder/audio_track_recorder.cc index 874c78c..9f7fc67 100644 --- a/content/renderer/media/recorder/audio_track_recorder.cc +++ b/content/renderer/media_recorder/audio_track_recorder.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 "content/renderer/media/recorder/audio_track_recorder.h" +#include "content/renderer/media_recorder/audio_track_recorder.h" #include <stdint.h> #include <utility>
diff --git a/content/renderer/media/recorder/audio_track_recorder.h b/content/renderer/media_recorder/audio_track_recorder.h similarity index 100% rename from content/renderer/media/recorder/audio_track_recorder.h rename to content/renderer/media_recorder/audio_track_recorder.h
diff --git a/content/renderer/media/recorder/audio_track_recorder_unittest.cc b/content/renderer/media_recorder/audio_track_recorder_unittest.cc similarity index 99% rename from content/renderer/media/recorder/audio_track_recorder_unittest.cc rename to content/renderer/media_recorder/audio_track_recorder_unittest.cc index b7c9bea2b..6929364c 100644 --- a/content/renderer/media/recorder/audio_track_recorder_unittest.cc +++ b/content/renderer/media_recorder/audio_track_recorder_unittest.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 "content/renderer/media/recorder/audio_track_recorder.h" +#include "content/renderer/media_recorder/audio_track_recorder.h" #include <stdint.h>
diff --git a/content/renderer/media/recorder/media_recorder_handler.cc b/content/renderer/media_recorder/media_recorder_handler.cc similarity index 98% rename from content/renderer/media/recorder/media_recorder_handler.cc rename to content/renderer/media_recorder/media_recorder_handler.cc index 9fcd2b9c..1055b153 100644 --- a/content/renderer/media/recorder/media_recorder_handler.cc +++ b/content/renderer/media_recorder/media_recorder_handler.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 "content/renderer/media/recorder/media_recorder_handler.h" +#include "content/renderer/media_recorder/media_recorder_handler.h" #include <utility> @@ -14,8 +14,8 @@ #include "base/strings/string_util.h" #include "content/renderer/media/media_stream_audio_track.h" #include "content/renderer/media/media_stream_track.h" -#include "content/renderer/media/recorder/audio_track_recorder.h" #include "content/renderer/media/webrtc_uma_histograms.h" +#include "content/renderer/media_recorder/audio_track_recorder.h" #include "media/base/audio_bus.h" #include "media/base/audio_parameters.h" #include "media/base/bind_to_current_loop.h" @@ -98,7 +98,7 @@ video ? arraysize(kVideoCodecs) : arraysize(kAudioCodecs); std::vector<std::string> codecs_list; - media::ParseCodecString(web_codecs.utf8(), &codecs_list, true /* strip */); + media::SplitCodecsToVector(web_codecs.utf8(), &codecs_list, true /* strip */); for (const auto& codec : codecs_list) { auto* const* found = std::find_if( &codecs[0], &codecs[codecs_count], [&codec](const char* name) {
diff --git a/content/renderer/media/recorder/media_recorder_handler.h b/content/renderer/media_recorder/media_recorder_handler.h similarity index 98% rename from content/renderer/media/recorder/media_recorder_handler.h rename to content/renderer/media_recorder/media_recorder_handler.h index d7cf39da..30a7637 100644 --- a/content/renderer/media/recorder/media_recorder_handler.h +++ b/content/renderer/media_recorder/media_recorder_handler.h
@@ -13,7 +13,7 @@ #include "base/strings/string_piece.h" #include "base/threading/thread_checker.h" #include "content/common/content_export.h" -#include "content/renderer/media/recorder/video_track_recorder.h" +#include "content/renderer/media_recorder/video_track_recorder.h" #include "third_party/WebKit/public/platform/WebMediaRecorderHandler.h" #include "third_party/WebKit/public/platform/WebMediaStream.h"
diff --git a/content/renderer/media/recorder/media_recorder_handler_unittest.cc b/content/renderer/media_recorder/media_recorder_handler_unittest.cc similarity index 99% rename from content/renderer/media/recorder/media_recorder_handler_unittest.cc rename to content/renderer/media_recorder/media_recorder_handler_unittest.cc index fa90e65..f0be4d1 100644 --- a/content/renderer/media/recorder/media_recorder_handler_unittest.cc +++ b/content/renderer/media_recorder/media_recorder_handler_unittest.cc
@@ -12,7 +12,7 @@ #include "base/time/time.h" #include "content/child/child_process.h" #include "content/renderer/media/mock_media_stream_registry.h" -#include "content/renderer/media/recorder/media_recorder_handler.h" +#include "content/renderer/media_recorder/media_recorder_handler.h" #include "media/audio/simple_sources.h" #include "media/base/audio_bus.h" #include "media/base/video_frame.h"
diff --git a/content/renderer/media/recorder/video_track_recorder.cc b/content/renderer/media_recorder/video_track_recorder.cc similarity index 99% rename from content/renderer/media/recorder/video_track_recorder.cc rename to content/renderer/media_recorder/video_track_recorder.cc index a792511..d699e7e 100644 --- a/content/renderer/media/recorder/video_track_recorder.cc +++ b/content/renderer/media_recorder/video_track_recorder.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 "content/renderer/media/recorder/video_track_recorder.h" +#include "content/renderer/media_recorder/video_track_recorder.h" #include <utility>
diff --git a/content/renderer/media/recorder/video_track_recorder.h b/content/renderer/media_recorder/video_track_recorder.h similarity index 100% rename from content/renderer/media/recorder/video_track_recorder.h rename to content/renderer/media_recorder/video_track_recorder.h
diff --git a/content/renderer/media/recorder/video_track_recorder_unittest.cc b/content/renderer/media_recorder/video_track_recorder_unittest.cc similarity index 98% rename from content/renderer/media/recorder/video_track_recorder_unittest.cc rename to content/renderer/media_recorder/video_track_recorder_unittest.cc index 3eb455e..3440bd7d 100644 --- a/content/renderer/media/recorder/video_track_recorder_unittest.cc +++ b/content/renderer/media_recorder/video_track_recorder_unittest.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 "content/renderer/media/recorder/video_track_recorder.h" +#include "content/renderer/media_recorder/video_track_recorder.h" #include <stddef.h>
diff --git a/content/renderer/presentation/presentation_dispatcher_unittest.cc b/content/renderer/presentation/presentation_dispatcher_unittest.cc index 5cf22a0..8cf4429 100644 --- a/content/renderer/presentation/presentation_dispatcher_unittest.cc +++ b/content/renderer/presentation/presentation_dispatcher_unittest.cc
@@ -716,7 +716,7 @@ // Set up |availability_set_| and |listening_status_| base::RunLoop run_loop; - for (auto& mock_observer : mock_observers_) { + for (auto* mock_observer : mock_observers_) { client()->getAvailability( mock_observer->urls(), base::MakeUnique<WebPresentationAvailabilityCallbacks>());
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index 632baad..c224627 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -549,6 +549,11 @@ << "Intentionally exhausting renderer memory because user navigated to " << url.spec(); ExhaustMemory(); + } else if (url == kChromeUICheckCrashURL) { + LOG(ERROR) + << "Intentionally causing CHECK because user navigated to " + << url.spec(); + CHECK(false); } #if defined(ADDRESS_SANITIZER) || defined(SYZYASAN)
diff --git a/content/renderer/renderer_blink_platform_impl.cc b/content/renderer/renderer_blink_platform_impl.cc index ed61cd8..40c87d7 100644 --- a/content/renderer/renderer_blink_platform_impl.cc +++ b/content/renderer/renderer_blink_platform_impl.cc
@@ -60,9 +60,9 @@ #include "content/renderer/media/capturefromelement/html_audio_element_capturer_source.h" #include "content/renderer/media/capturefromelement/html_video_element_capturer_source.h" #include "content/renderer/media/image_capture_frame_grabber.h" -#include "content/renderer/media/recorder/media_recorder_handler.h" #include "content/renderer/media/renderer_webaudiodevice_impl.h" #include "content/renderer/media/renderer_webmidiaccessor_impl.h" +#include "content/renderer/media_recorder/media_recorder_handler.h" #include "content/renderer/mojo/blink_interface_provider_impl.h" #include "content/renderer/render_thread_impl.h" #include "content/renderer/renderer_clipboard_delegate.h"
diff --git a/content/renderer/scheduler/OWNERS b/content/renderer/scheduler/OWNERS index 6dc4cb4..9bf4416 100644 --- a/content/renderer/scheduler/OWNERS +++ b/content/renderer/scheduler/OWNERS
@@ -1,3 +1,6 @@ alexclarke@chromium.org rmcilroy@chromium.org skyostil@chromium.org + +# TEAM: scheduler-dev@chromium.org +# COMPONENT: Blink>Scheduling
diff --git a/content/shell/test_runner/mock_web_speech_recognizer.cc b/content/shell/test_runner/mock_web_speech_recognizer.cc index 062f0e26..56c35ae 100644 --- a/content/shell/test_runner/mock_web_speech_recognizer.cc +++ b/content/shell/test_runner/mock_web_speech_recognizer.cc
@@ -319,7 +319,7 @@ } bool MockWebSpeechRecognizer::HasPendingNewContextTasks() const { - for (const auto& task : task_queue_) { + for (auto* task : task_queue_) { if (task->isNewContextTask()) return true; }
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index bb8c09f..db2a88e 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -1592,9 +1592,6 @@ "../renderer/media/mock_media_stream_video_source.cc", "../renderer/media/mock_media_stream_video_source.h", "../renderer/media/peer_connection_tracker_unittest.cc", - "../renderer/media/recorder/audio_track_recorder_unittest.cc", - "../renderer/media/recorder/media_recorder_handler_unittest.cc", - "../renderer/media/recorder/video_track_recorder_unittest.cc", "../renderer/media/rtc_data_channel_handler_unittest.cc", "../renderer/media/rtc_peer_connection_handler_unittest.cc", "../renderer/media/speech_recognition_audio_sink_unittest.cc", @@ -1611,6 +1608,9 @@ "../renderer/media/webrtc_audio_renderer_unittest.cc", "../renderer/media/webrtc_local_audio_source_provider_unittest.cc", "../renderer/media/webrtc_uma_histograms_unittest.cc", + "../renderer/media_recorder/audio_track_recorder_unittest.cc", + "../renderer/media_recorder/media_recorder_handler_unittest.cc", + "../renderer/media_recorder/video_track_recorder_unittest.cc", "../renderer/p2p/filtering_network_manager_unittest.cc", "../renderer/p2p/ipc_network_manager_unittest.cc", "//third_party/webrtc/base/task_queue_unittest.cc", @@ -1637,9 +1637,9 @@ if (is_chromecast) { sources -= [ - "../renderer/media/recorder/audio_track_recorder_unittest.cc", - "../renderer/media/recorder/media_recorder_handler_unittest.cc", - "../renderer/media/recorder/video_track_recorder_unittest.cc", + "../renderer/media_recorder/audio_track_recorder_unittest.cc", + "../renderer/media_recorder/media_recorder_handler_unittest.cc", + "../renderer/media_recorder/video_track_recorder_unittest.cc", ] } }
diff --git a/content/test/gpu/gpu_tests/context_lost_integration_test.py b/content/test/gpu/gpu_tests/context_lost_integration_test.py index 3c97ca5..670f850 100644 --- a/content/test/gpu/gpu_tests/context_lost_integration_test.py +++ b/content/test/gpu/gpu_tests/context_lost_integration_test.py
@@ -97,8 +97,8 @@ return context_lost_expectations.ContextLostExpectations() @classmethod - def setUpClass(cls): - super(cls, ContextLostIntegrationTest).setUpClass() + def SetUpProcess(cls): + super(cls, ContextLostIntegrationTest).SetUpProcess() cls.CustomizeOptions() cls.SetBrowserOptions(cls._finder_options) cls.StartBrowser()
diff --git a/content/test/gpu/gpu_tests/depth_capture_integration_test.py b/content/test/gpu/gpu_tests/depth_capture_integration_test.py index b2a40b7..9f3b6693 100644 --- a/content/test/gpu/gpu_tests/depth_capture_integration_test.py +++ b/content/test/gpu/gpu_tests/depth_capture_integration_test.py
@@ -88,8 +88,8 @@ return depth_capture_expectations.DepthCaptureExpectations() @classmethod - def setUpClass(cls): - super(cls, DepthCaptureIntegrationTest).setUpClass() + def SetUpProcess(cls): + super(cls, DepthCaptureIntegrationTest).SetUpProcess() cls.CustomizeOptions() cls.SetBrowserOptions(cls._finder_options) cls.StartBrowser()
diff --git a/content/test/gpu/gpu_tests/gpu_integration_test_unittest.py b/content/test/gpu/gpu_tests/gpu_integration_test_unittest.py index 4946255..2c924f66 100644 --- a/content/test/gpu/gpu_tests/gpu_integration_test_unittest.py +++ b/content/test/gpu/gpu_tests/gpu_integration_test_unittest.py
@@ -3,240 +3,104 @@ # found in the LICENSE file. import json -import logging -import mock import os +import shutil import tempfile import unittest -from telemetry.testing import fakes from telemetry.testing import browser_test_runner -import gpu_project_config +from gpu_tests import path_util -from gpu_tests import gpu_integration_test -from gpu_tests import gpu_test_expectations - -class SimpleIntegrationUnittest(gpu_integration_test.GpuIntegrationTest): - # Must be class-scoped since instances aren't reused across runs. - _num_flaky_runs_to_fail = 2 - - _num_browser_starts = 0 - - @classmethod - def Name(cls): - return 'simple_integration_unittest' - - def setUp(self): - super(SimpleIntegrationUnittest, self).setUp() - - @classmethod - def setUpClass(cls): - finder_options = fakes.CreateBrowserFinderOptions() - finder_options.browser_options.platform = fakes.FakeLinuxPlatform() - finder_options.output_formats = ['none'] - finder_options.suppress_gtest_report = True - finder_options.output_dir = None - finder_options.upload_bucket = 'public' - finder_options.upload_results = False - cls._finder_options = finder_options - cls.platform = None - cls.browser = None - cls.SetBrowserOptions(cls._finder_options) - cls.StartBrowser() - - @classmethod - def GenerateGpuTests(cls, options): - yield ('expected_failure', 'failure.html', ()) - yield ('expected_flaky', 'flaky.html', ()) - yield ('expected_skip', 'failure.html', ()) - yield ('unexpected_failure', 'failure.html', ()) - yield ('unexpected_error', 'error.html', ()) - - @classmethod - def _CreateExpectations(cls): - expectations = gpu_test_expectations.GpuTestExpectations() - expectations.Fail('expected_failure') - expectations.Flaky('expected_flaky', max_num_retries=3) - expectations.Skip('expected_skip') - return expectations - - @classmethod - def StartBrowser(cls): - super(SimpleIntegrationUnittest, cls).StartBrowser() - cls._num_browser_starts += 1 - - def RunActualGpuTest(self, file_path, *args): - logging.warn('Running ' + file_path) - if file_path == 'failure.html': - self.fail('Expected failure') - elif file_path == 'flaky.html': - if self.__class__._num_flaky_runs_to_fail > 0: - self.__class__._num_flaky_runs_to_fail -= 1 - self.fail('Expected flaky failure') - elif file_path == 'error.html': - raise Exception('Expected exception') - - -class BrowserStartFailureIntegrationUnittest( - gpu_integration_test.GpuIntegrationTest): - - _num_browser_crashes = 0 - _num_browser_starts = 0 - - @classmethod - def setUpClass(cls): - cls._fake_browser_options = \ - fakes.CreateBrowserFinderOptions(execute_on_startup=cls.CrashOnStart) - cls._fake_browser_options.browser_options.platform = \ - fakes.FakeLinuxPlatform() - cls._fake_browser_options.output_formats = ['none'] - cls._fake_browser_options.suppress_gtest_report = True - cls._fake_browser_options.output_dir = None - cls._fake_browser_options .upload_bucket = 'public' - cls._fake_browser_options .upload_results = False - cls._finder_options = cls._fake_browser_options - cls.platform = None - cls.browser = None - cls.SetBrowserOptions(cls._finder_options) - cls.StartBrowser() - - @classmethod - def _CreateExpectations(cls): - return gpu_test_expectations.GpuTestExpectations() - - @classmethod - def CrashOnStart(cls): - cls._num_browser_starts += 1 - if cls._num_browser_crashes < 2: - cls._num_browser_crashes += 1 - raise - - @classmethod - def Name(cls): - return 'browser_start_failure_integration_unittest' - - @classmethod - def GenerateGpuTests(cls, options): - # This test causes the browser to try and restart the browser 3 times. - yield ('restart', 'restart.html', ()) - - def RunActualGpuTest(self, file_path, *args): - # The logic of this test is run when the browser starts, it fails twice - # and then succeeds on the third time so we are just testing that this - # is successful based on the parameters. - pass - - -class BrowserCrashAfterStartIntegrationUnittest( - gpu_integration_test.GpuIntegrationTest): - - _num_browser_crashes = 0 - _num_browser_starts = 0 - - @classmethod - def setUpClass(cls): - cls._fake_browser_options = fakes.CreateBrowserFinderOptions( - execute_after_browser_creation=cls.CrashAfterStart) - cls._fake_browser_options.browser_options.platform = \ - fakes.FakeLinuxPlatform() - cls._fake_browser_options.output_formats = ['none'] - cls._fake_browser_options.suppress_gtest_report = True - cls._fake_browser_options.output_dir = None - cls._fake_browser_options .upload_bucket = 'public' - cls._fake_browser_options .upload_results = False - cls._finder_options = cls._fake_browser_options - cls.platform = None - cls.browser = None - cls.SetBrowserOptions(cls._finder_options) - cls.StartBrowser() - - @classmethod - def _CreateExpectations(cls): - return gpu_test_expectations.GpuTestExpectations() - - @classmethod - def CrashAfterStart(cls, browser): - cls._num_browser_starts += 1 - if cls._num_browser_crashes < 2: - cls._num_browser_crashes += 1 - # This simulates the first tab's renderer process crashing upon - # startup. The try/catch forces the GpuIntegrationTest's first - # fetch of this tab to fail. crbug.com/682819 - try: - browser.tabs[0].Navigate('chrome://crash') - except Exception: - pass - - @classmethod - def Name(cls): - return 'browser_crash_after_start_integration_unittest' - - @classmethod - def GenerateGpuTests(cls, options): - # This test causes the browser to try and restart the browser 3 times. - yield ('restart', 'restart.html', ()) - - def RunActualGpuTest(self, file_path, *args): - # The logic of this test is run when the browser starts, it fails twice - # and then succeeds on the third time so we are just testing that this - # is successful based on the parameters. - pass +path_util.AddDirToPathIfNeeded(path_util.GetChromiumSrcDir(), 'tools', 'perf') +from chrome_telemetry_build import chromium_config class GpuIntegrationTestUnittest(unittest.TestCase): - @mock.patch('telemetry.internal.util.binary_manager.InitDependencyManager') - def testSimpleIntegrationUnittest(self, mockInitDependencyManager): + def setUp(self): + self._test_state = {} + + def testSimpleIntegrationTest(self): self._RunIntegrationTest( - 'simple_integration_unittest', [ - 'unexpected_error', - 'unexpected_failure' - ], [ - 'expected_failure', - 'expected_flaky', - ]) + 'simple_integration_unittest', + ['unittest_data.integration_tests.SimpleTest.unexpected_error', + 'unittest_data.integration_tests.SimpleTest.unexpected_failure'], + ['unittest_data.integration_tests.SimpleTest.expected_flaky', + 'unittest_data.integration_tests.SimpleTest.expected_failure'], + ['unittest_data.integration_tests.SimpleTest.expected_skip']) # It might be nice to be more precise about the order of operations # with these browser restarts, but this is at least a start. - self.assertEquals(SimpleIntegrationUnittest._num_browser_starts, 6) + self.assertEquals(self._test_state['num_browser_starts'], 6) - @mock.patch('telemetry.internal.util.binary_manager.InitDependencyManager') - def testIntegrationUnittestWithBrowserFailure( - self, mockInitDependencyManager): + def testIntegrationTesttWithBrowserFailure(self): self._RunIntegrationTest( - 'browser_start_failure_integration_unittest', [], ['restart']) - self.assertEquals( \ - BrowserStartFailureIntegrationUnittest._num_browser_crashes, 2) - self.assertEquals( \ - BrowserStartFailureIntegrationUnittest._num_browser_starts, 3) + 'browser_start_failure_integration_unittest', [], + ['unittest_data.integration_tests.BrowserStartFailureTest.restart'], + []) + self.assertEquals(self._test_state['num_browser_crashes'], 2) + self.assertEquals(self._test_state['num_browser_starts'], 3) - @mock.patch('telemetry.internal.util.binary_manager.InitDependencyManager') - def testIntegrationUnittestWithBrowserCrashUponStart( - self, mockInitDependencyManager): + def testIntegrationTestWithBrowserCrashUponStart(self): self._RunIntegrationTest( - 'browser_crash_after_start_integration_unittest', [], ['restart']) - self.assertEquals( \ - BrowserCrashAfterStartIntegrationUnittest._num_browser_crashes, 2) - self.assertEquals( \ - BrowserCrashAfterStartIntegrationUnittest._num_browser_starts, 3) + 'browser_crash_after_start_integration_unittest', [], + [('unittest_data.integration_tests.BrowserCrashAfterStartTest.restart')], + []) + self.assertEquals(self._test_state['num_browser_crashes'], 2) + self.assertEquals(self._test_state['num_browser_starts'], 3) - def _RunIntegrationTest(self, test_name, failures, successes): - options = browser_test_runner.TestRunOptions() - # Suppress printing out information for passing tests. - options.verbosity = 0 - config = gpu_project_config.CONFIG - temp_file = tempfile.NamedTemporaryFile(delete=False) - temp_file.close() - temp_file_name = temp_file.name + def _RunIntegrationTest(self, test_name, failures, successes, skips): + config = chromium_config.ChromiumConfig( + top_level_dir=path_util.GetGpuTestDir(), + benchmark_dirs=[ + os.path.join(path_util.GetGpuTestDir(), 'unittest_data')]) + temp_dir = tempfile.mkdtemp() + test_results_path = os.path.join(temp_dir, 'test_results.json') + test_state_path = os.path.join(temp_dir, 'test_state.json') try: browser_test_runner.Run( - config, options, + config, [test_name, - '--write-abbreviated-json-results-to=%s' % temp_file_name]) - with open(temp_file_name) as f: + '--write-full-results-to=%s' % test_results_path, + '--test-state-json-path=%s' % test_state_path]) + with open(test_results_path) as f: test_result = json.load(f) - self.assertEquals(test_result['failures'], failures) - self.assertEquals(test_result['successes'], successes) - self.assertEquals(test_result['valid'], True) - + with open(test_state_path) as f: + self._test_state = json.load(f) + actual_successes, actual_failures, actual_skips = ( + self._ExtracTestResults(test_result)) + self.assertEquals(actual_failures, failures) + self.assertEquals(actual_successes, successes) + self.assertEquals(actual_skips, skips) finally: - os.remove(temp_file_name) + shutil.rmtree(temp_dir) + + def _ExtracTestResults(self, test_result): + delimiter = test_result['path_delimiter'] + failures = [] + successes = [] + skips = [] + def _IsLeafNode(node): + test_dict = node[1] + return ('expected' in test_dict and + isinstance(test_dict['expected'], basestring)) + node_queues = [] + for t in test_result['tests']: + node_queues.append((t, test_result['tests'][t])) + while node_queues: + node = node_queues.pop() + full_test_name, test_dict = node + if _IsLeafNode(node): + if all(res not in test_dict['expected'].split() for res in + test_dict['actual'].split()): + failures.append(full_test_name) + elif test_dict['expected'] == test_dict['actual'] == 'SKIP': + skips.append(full_test_name) + else: + successes.append(full_test_name) + else: + for k in test_dict: + node_queues.append( + ('%s%s%s' % (full_test_name, delimiter, k), + test_dict[k])) + return successes, failures, skips +
diff --git a/content/test/gpu/gpu_tests/gpu_process_integration_test.py b/content/test/gpu/gpu_tests/gpu_process_integration_test.py index adf3878..fa9b3c5 100644 --- a/content/test/gpu/gpu_tests/gpu_process_integration_test.py +++ b/content/test/gpu/gpu_tests/gpu_process_integration_test.py
@@ -50,8 +50,8 @@ return 'gpu_process' @classmethod - def setUpClass(cls): - super(cls, GpuProcessIntegrationTest).setUpClass() + def SetUpProcess(cls): + super(cls, GpuProcessIntegrationTest).SetUpProcess() cls._original_finder_options = cls._finder_options.Copy() cls.CustomizeBrowserArgs([]) cls.StartBrowser()
diff --git a/content/test/gpu/gpu_tests/hardware_accelerated_feature_integration_test.py b/content/test/gpu/gpu_tests/hardware_accelerated_feature_integration_test.py index 413c63b..2d192fb8d 100644 --- a/content/test/gpu/gpu_tests/hardware_accelerated_feature_integration_test.py +++ b/content/test/gpu/gpu_tests/hardware_accelerated_feature_integration_test.py
@@ -37,8 +37,8 @@ return 'hardware_accelerated_feature' @classmethod - def setUpClass(cls): - super(cls, HardwareAcceleratedFeatureIntegrationTest).setUpClass() + def SetUpProcess(cls): + super(cls, HardwareAcceleratedFeatureIntegrationTest).SetUpProcess() cls.SetBrowserOptions(cls._finder_options) cls.StartBrowser() cls.SetStaticServerDirs([])
diff --git a/content/test/gpu/gpu_tests/maps_integration_test.py b/content/test/gpu/gpu_tests/maps_integration_test.py index 891421c..8284ffc 100644 --- a/content/test/gpu/gpu_tests/maps_integration_test.py +++ b/content/test/gpu/gpu_tests/maps_integration_test.py
@@ -60,16 +60,16 @@ return maps_expectations.MapsExpectations() @classmethod - def setUpClass(cls): - super(cls, MapsIntegrationTest).setUpClass() + def SetUpProcess(cls): + super(cls, MapsIntegrationTest).SetUpProcess() cls.SetBrowserOptions(cls._finder_options) cls.StartWPRServer(os.path.join(data_path, 'maps_004.wpr.updated'), cloud_storage.PUBLIC_BUCKET) cls.StartBrowser() @classmethod - def tearDownClass(cls): - super(cls, MapsIntegrationTest).tearDownClass() + def TearDownProcess(cls): + super(cls, MapsIntegrationTest).TearDownProcess() cls.StopWPRServer() @classmethod
diff --git a/content/test/gpu/gpu_tests/pixel_integration_test.py b/content/test/gpu/gpu_tests/pixel_integration_test.py index 66b6c339..d7b5c66 100644 --- a/content/test/gpu/gpu_tests/pixel_integration_test.py +++ b/content/test/gpu/gpu_tests/pixel_integration_test.py
@@ -63,8 +63,8 @@ return 'pixel' @classmethod - def setUpClass(cls): - super(cls, PixelIntegrationTest).setUpClass() + def SetUpProcess(cls): + super(cls, PixelIntegrationTest).SetUpProcess() cls._original_finder_options = cls._finder_options.Copy() cls.CustomizeBrowserArgs([]) cls.StartBrowser()
diff --git a/content/test/gpu/gpu_tests/screenshot_sync_integration_test.py b/content/test/gpu/gpu_tests/screenshot_sync_integration_test.py index 76f1a6e..ec0efe1 100644 --- a/content/test/gpu/gpu_tests/screenshot_sync_integration_test.py +++ b/content/test/gpu/gpu_tests/screenshot_sync_integration_test.py
@@ -39,8 +39,8 @@ return 'screenshot_sync' @classmethod - def setUpClass(cls): - super(cls, ScreenshotSyncIntegrationTest).setUpClass() + def SetUpProcess(cls): + super(cls, ScreenshotSyncIntegrationTest).SetUpProcess() cls._original_finder_options = cls._finder_options.Copy() cls.CustomizeBrowserArgs([]) cls.StartBrowser()
diff --git a/content/test/gpu/gpu_tests/trace_integration_test.py b/content/test/gpu/gpu_tests/trace_integration_test.py index 6dfa2cd..9f7e44a 100644 --- a/content/test/gpu/gpu_tests/trace_integration_test.py +++ b/content/test/gpu/gpu_tests/trace_integration_test.py
@@ -120,8 +120,8 @@ return trace_test_expectations.TraceTestExpectations() @classmethod - def setUpClass(cls): - super(cls, TraceIntegrationTest).setUpClass() + def SetUpProcess(cls): + super(cls, TraceIntegrationTest).SetUpProcess() path_util.SetupTelemetryPaths() cls.CustomizeOptions() cls.SetBrowserOptions(cls._finder_options)
diff --git a/content/test/gpu/gpu_tests/webgl_conformance_integration_test.py b/content/test/gpu/gpu_tests/webgl_conformance_integration_test.py index a593790..ba31b00 100644 --- a/content/test/gpu/gpu_tests/webgl_conformance_integration_test.py +++ b/content/test/gpu/gpu_tests/webgl_conformance_integration_test.py
@@ -313,8 +313,8 @@ is_asan=cls._is_asan) @classmethod - def setUpClass(cls): - super(WebGLConformanceIntegrationTest, cls).setUpClass() + def SetUpProcess(cls): + super(WebGLConformanceIntegrationTest, cls).SetUpProcess() cls.CustomizeOptions() cls.SetBrowserOptions(cls._finder_options) cls.StartBrowser() @@ -399,6 +399,7 @@ return test_paths + def load_tests(loader, tests, pattern): del loader, tests, pattern # Unused. return gpu_integration_test.LoadAllTestsInModule(sys.modules[__name__])
diff --git a/content/test/gpu/run_gpu_integration_test.py b/content/test/gpu/run_gpu_integration_test.py index 27bf30cf..16deb3ae 100755 --- a/content/test/gpu/run_gpu_integration_test.py +++ b/content/test/gpu/run_gpu_integration_test.py
@@ -26,10 +26,9 @@ json.dump(test_result, f) def main(): - options = browser_test_runner.TestRunOptions() rest_args = sys.argv[1:] retval = browser_test_runner.Run( - gpu_project_config.CONFIG, options, rest_args) + gpu_project_config.CONFIG, rest_args) # Postprocess the outputted JSON to trim all of the prefixes from # the test names, to keep them as similar to the old form as # possible -- and keep them from getting crazily long.
diff --git a/content/test/gpu/unittest_data/__init__.py b/content/test/gpu/unittest_data/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/content/test/gpu/unittest_data/__init__.py
diff --git a/content/test/gpu/unittest_data/integration_tests.py b/content/test/gpu/unittest_data/integration_tests.py new file mode 100644 index 0000000..bc0589b4e --- /dev/null +++ b/content/test/gpu/unittest_data/integration_tests.py
@@ -0,0 +1,213 @@ +# 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. + + +import json +import logging +import mock +import os +import sys +import tempfile +import unittest + +from telemetry.testing import fakes +from telemetry.testing import browser_test_runner +from telemetry.testing import browser_test_context + +import gpu_project_config + +from gpu_tests import gpu_integration_test +from gpu_tests import gpu_test_expectations + + +class _BaseSampleIntegrationTest(gpu_integration_test.GpuIntegrationTest): + _test_state = {} + @classmethod + def AddCommandlineArgs(cls, parser): + parser.add_option('--test-state-json-path', + help=('Where to dump the test state json (this is used by ' + 'gpu_integration_test_unittest)')) + + @classmethod + def TearDownProcess(cls): + actual_finder_options = browser_test_context.GetCopy().finder_options + test_state_json_path = actual_finder_options.test_state_json_path + with open(test_state_json_path, 'w') as f: + json.dump(cls._test_state, f) + super(_BaseSampleIntegrationTest, cls).TearDownProcess() + + +class SimpleTest(_BaseSampleIntegrationTest): + _test_state = { + 'num_flaky_runs_to_fail': 2, + 'num_browser_starts': 0 + } + + + @classmethod + def Name(cls): + return 'simple_integration_unittest' + + def setUp(self): + super(SimpleTest, self).setUp() + + @classmethod + def SetUpProcess(cls): + finder_options = fakes.CreateBrowserFinderOptions() + finder_options.browser_options.platform = fakes.FakeLinuxPlatform() + finder_options.output_formats = ['none'] + finder_options.suppress_gtest_report = True + finder_options.output_dir = None + finder_options.upload_bucket = 'public' + finder_options.upload_results = False + cls._finder_options = finder_options + cls.platform = None + cls.browser = None + cls.SetBrowserOptions(cls._finder_options) + cls.StartBrowser() + + @classmethod + def GenerateGpuTests(cls, options): + yield ('expected_failure', 'failure.html', ()) + yield ('expected_flaky', 'flaky.html', ()) + yield ('expected_skip', 'failure.html', ()) + yield ('unexpected_failure', 'failure.html', ()) + yield ('unexpected_error', 'error.html', ()) + + @classmethod + def _CreateExpectations(cls): + expectations = gpu_test_expectations.GpuTestExpectations() + expectations.Fail('expected_failure') + expectations.Flaky('expected_flaky', max_num_retries=3) + expectations.Skip('expected_skip') + return expectations + + @classmethod + def StartBrowser(cls): + super(SimpleTest, cls).StartBrowser() + cls._test_state['num_browser_starts'] += 1 + + def RunActualGpuTest(self, file_path, *args): + logging.warn('Running ' + file_path) + if file_path == 'failure.html': + self.fail('Expected failure') + elif file_path == 'flaky.html': + if self._test_state['num_flaky_runs_to_fail'] > 0: + self._test_state['num_flaky_runs_to_fail'] -= 1 + self.fail('Expected flaky failure') + elif file_path == 'error.html': + raise Exception('Expected exception') + + +class BrowserStartFailureTest(_BaseSampleIntegrationTest): + + _test_state = { + 'num_browser_crashes': 0, + 'num_browser_starts': 0 + } + + @classmethod + def SetUpProcess(cls): + cls._fake_browser_options = \ + fakes.CreateBrowserFinderOptions(execute_on_startup=cls.CrashOnStart) + cls._fake_browser_options.browser_options.platform = \ + fakes.FakeLinuxPlatform() + cls._fake_browser_options.output_formats = ['none'] + cls._fake_browser_options.suppress_gtest_report = True + cls._fake_browser_options.output_dir = None + cls._fake_browser_options .upload_bucket = 'public' + cls._fake_browser_options .upload_results = False + cls._finder_options = cls._fake_browser_options + cls.platform = None + cls.browser = None + cls.SetBrowserOptions(cls._finder_options) + cls.StartBrowser() + + @classmethod + def _CreateExpectations(cls): + return gpu_test_expectations.GpuTestExpectations() + + @classmethod + def CrashOnStart(cls): + cls._test_state['num_browser_starts'] += 1 + if cls._test_state['num_browser_crashes'] < 2: + cls._test_state['num_browser_crashes'] += 1 + raise + + @classmethod + def Name(cls): + return 'browser_start_failure_integration_unittest' + + @classmethod + def GenerateGpuTests(cls, options): + # This test causes the browser to try and restart the browser 3 times. + yield ('restart', 'restart.html', ()) + + def RunActualGpuTest(self, file_path, *args): + # The logic of this test is run when the browser starts, it fails twice + # and then succeeds on the third time so we are just testing that this + # is successful based on the parameters. + pass + + +class BrowserCrashAfterStartTest(_BaseSampleIntegrationTest): + + _test_state = { + 'num_browser_crashes': 0, + 'num_browser_starts': 0, + } + + @classmethod + def SetUpProcess(cls): + cls._fake_browser_options = fakes.CreateBrowserFinderOptions( + execute_after_browser_creation=cls.CrashAfterStart) + cls._fake_browser_options.browser_options.platform = \ + fakes.FakeLinuxPlatform() + cls._fake_browser_options.output_formats = ['none'] + cls._fake_browser_options.suppress_gtest_report = True + cls._fake_browser_options.output_dir = None + cls._fake_browser_options .upload_bucket = 'public' + cls._fake_browser_options .upload_results = False + cls._finder_options = cls._fake_browser_options + cls.platform = None + cls.browser = None + cls.SetBrowserOptions(cls._finder_options) + cls.StartBrowser() + + @classmethod + def _CreateExpectations(cls): + return gpu_test_expectations.GpuTestExpectations() + + @classmethod + def CrashAfterStart(cls, browser): + cls._test_state['num_browser_starts'] += 1 + if cls._test_state['num_browser_crashes'] < 2: + cls._test_state['num_browser_crashes'] += 1 + # This simulates the first tab's renderer process crashing upon + # startup. The try/catch forces the GpuIntegrationTest's first + # fetch of this tab to fail. crbug.com/682819 + try: + browser.tabs[0].Navigate('chrome://crash') + except Exception: + pass + + @classmethod + def Name(cls): + return 'browser_crash_after_start_integration_unittest' + + @classmethod + def GenerateGpuTests(cls, options): + # This test causes the browser to try and restart the browser 3 times. + yield ('restart', 'restart.html', ()) + + def RunActualGpuTest(self, file_path, *args): + # The logic of this test is run when the browser starts, it fails twice + # and then succeeds on the third time so we are just testing that this + # is successful based on the parameters. + pass + + +def load_tests(loader, tests, pattern): + del loader, tests, pattern # Unused. + return gpu_integration_test.LoadAllTestsInModule(sys.modules[__name__])
diff --git a/content/test/web_contents_observer_sanity_checker.cc b/content/test/web_contents_observer_sanity_checker.cc index 66c371c..e522297b 100644 --- a/content/test/web_contents_observer_sanity_checker.cc +++ b/content/test/web_contents_observer_sanity_checker.cc
@@ -243,7 +243,8 @@ const GURL& url, const Referrer& referrer, WindowOpenDisposition disposition, - ui::PageTransition transition) { + ui::PageTransition transition, + bool started_from_context_menu) { AssertRenderFrameExists(source_render_frame_host); }
diff --git a/content/test/web_contents_observer_sanity_checker.h b/content/test/web_contents_observer_sanity_checker.h index 867706c..7bb576f0 100644 --- a/content/test/web_contents_observer_sanity_checker.h +++ b/content/test/web_contents_observer_sanity_checker.h
@@ -61,7 +61,8 @@ const GURL& url, const Referrer& referrer, WindowOpenDisposition disposition, - ui::PageTransition transition) override; + ui::PageTransition transition, + bool started_from_context_menu) override; void MediaStartedPlaying(const MediaPlayerInfo& media_info, const MediaPlayerId& id) override; void MediaStoppedPlaying(const MediaPlayerInfo& media_info,
diff --git a/device/battery/battery_status_manager_linux_unittest.cc b/device/battery/battery_status_manager_linux_unittest.cc index 68e28ac..6387af8 100644 --- a/device/battery/battery_status_manager_linux_unittest.cc +++ b/device/battery/battery_status_manager_linux_unittest.cc
@@ -325,7 +325,7 @@ dbus::MessageWriter array_writer(nullptr); dbus::MessageWriter dict_entry_writer(nullptr); writer->OpenArray("{sv}", &array_writer); - for (auto property_name : + for (auto* property_name : {kUPowerDevicePropertyIsPresent, kUPowerDevicePropertyState, kUPowerDevicePropertyTimeToEmpty, kUPowerDevicePropertyTimeToFull, kUPowerDevicePropertyType}) {
diff --git a/device/gamepad/gamepad_data_fetcher_manager.cc b/device/gamepad/gamepad_data_fetcher_manager.cc index cb91e16..3cc662fb 100644 --- a/device/gamepad/gamepad_data_fetcher_manager.cc +++ b/device/gamepad/gamepad_data_fetcher_manager.cc
@@ -53,7 +53,7 @@ DCHECK(!provider_); provider_ = provider; - for (const auto& it : factories_) { + for (auto* it : factories_) { provider_->AddGamepadDataFetcher(it->CreateDataFetcher()); } }
diff --git a/device/usb/usb_device_win.cc b/device/usb/usb_device_win.cc index e54d1c88..18e83ef8 100644 --- a/device/usb/usb_device_win.cc +++ b/device/usb/usb_device_win.cc
@@ -18,10 +18,12 @@ const std::string& device_path, const std::string& hub_path, int port_number, + const std::string& driver_name, scoped_refptr<base::SequencedTaskRunner> blocking_task_runner) : device_path_(device_path), hub_path_(hub_path), port_number_(port_number), + driver_name_(driver_name), task_runner_(base::ThreadTaskRunnerHandle::Get()), blocking_task_runner_(std::move(blocking_task_runner)) {}
diff --git a/device/usb/usb_device_win.h b/device/usb/usb_device_win.h index 2c43a52..dd17683 100644 --- a/device/usb/usb_device_win.h +++ b/device/usb/usb_device_win.h
@@ -32,12 +32,14 @@ UsbDeviceWin(const std::string& device_path, const std::string& hub_path, int port_number, + const std::string& driver_name, scoped_refptr<base::SequencedTaskRunner> task_runner); ~UsbDeviceWin() override; const std::string& device_path() const { return device_path_; } int port_number() const { return port_number_; } + const std::string& driver_name() const { return driver_name_; } // Opens the device's parent hub in order to read the device, configuration // and string descriptors. @@ -59,6 +61,7 @@ const std::string device_path_; const std::string hub_path_; const int port_number_; + const std::string driver_name_; scoped_refptr<base::SequencedTaskRunner> task_runner_; scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_;
diff --git a/device/usb/usb_service_unittest.cc b/device/usb/usb_service_unittest.cc index d5714ff..4013fbe 100644 --- a/device/usb/usb_service_unittest.cc +++ b/device/usb/usb_service_unittest.cc
@@ -8,7 +8,9 @@ #include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "base/strings/utf_string_conversions.h" +#include "base/test/scoped_feature_list.h" #include "base/test/test_io_thread.h" +#include "device/base/features.h" #include "device/test/test_device_client.h" #include "device/test/usb_test_gadget.h" #include "device/usb/usb_device.h" @@ -50,6 +52,19 @@ } } +#if defined(OS_WIN) +TEST_F(UsbServiceTest, GetDevicesNewBackend) { + base::test::ScopedFeatureList features; + features.InitAndEnableFeature(device::kNewUsbBackend); + UsbService* service = device_client_->GetUsbService(); + if (service) { + base::RunLoop loop; + service->GetDevices(base::Bind(&OnGetDevices, loop.QuitClosure())); + loop.Run(); + } +} +#endif // defined(OS_WIN) + TEST_F(UsbServiceTest, ClaimGadget) { if (!UsbTestGadget::IsTestEnabled()) return;
diff --git a/device/usb/usb_service_win.cc b/device/usb/usb_service_win.cc index 65de4b0..8cc9c0c 100644 --- a/device/usb/usb_service_win.cc +++ b/device/usb/usb_service_win.cc
@@ -83,8 +83,9 @@ SP_DEVICE_INTERFACE_DATA* device_interface_data, std::string* device_path, uint32_t* port_number, - std::string* parent_instance_id) { - DWORD required_size; + std::string* parent_instance_id, + std::string* service_name) { + DWORD required_size = 0; if (SetupDiGetDeviceInterfaceDetail(dev_info, device_interface_data, nullptr, 0, &required_size, nullptr) || GetLastError() != ERROR_INSUFFICIENT_BUFFER) { @@ -127,6 +128,20 @@ } } + if (service_name) { + if (!GetDeviceStringProperty(dev_info, &dev_info_data, + DEVPKEY_Device_Service, service_name)) { + USB_PLOG(ERROR) << "Failed to get device driver name"; + return false; + } + + // Windows pads this string with a variable number of NUL bytes for no + // discernible reason. + size_t end = service_name->find_last_not_of('\0'); + if (end != std::string::npos) + service_name->erase(end + 1); + } + return true; } @@ -150,7 +165,7 @@ } return GetDeviceInterfaceDetails(dev_info.get(), &device_interface_data, - device_path, nullptr, nullptr); + device_path, nullptr, nullptr, nullptr); } } // namespace @@ -182,9 +197,10 @@ std::string device_path; uint32_t port_number; std::string parent_instance_id; + std::string service_name; if (!GetDeviceInterfaceDetails(dev_info.get(), &device_interface_data, &device_path, &port_number, - &parent_instance_id)) { + &parent_instance_id, &service_name)) { continue; } @@ -198,8 +214,9 @@ } service_task_runner_->PostTask( - FROM_HERE, base::Bind(&UsbServiceWin::CreateDeviceObject, service_, - device_path, hub_path, port_number)); + FROM_HERE, + base::Bind(&UsbServiceWin::CreateDeviceObject, service_, device_path, + hub_path, port_number, service_name)); } if (GetLastError() != ERROR_NO_MORE_ITEMS) @@ -228,9 +245,10 @@ uint32_t port_number; std::string parent_instance_id; + std::string service_name; if (!GetDeviceInterfaceDetails(dev_info.get(), &device_interface_data, - nullptr, &port_number, - &parent_instance_id)) { + nullptr, &port_number, &parent_instance_id, + &service_name)) { return; } @@ -244,8 +262,9 @@ } service_task_runner_->PostTask( - FROM_HERE, base::Bind(&UsbServiceWin::CreateDeviceObject, service_, - device_path, hub_path, port_number)); + FROM_HERE, + base::Bind(&UsbServiceWin::CreateDeviceObject, service_, device_path, + hub_path, port_number, service_name)); } private: @@ -327,15 +346,16 @@ void UsbServiceWin::CreateDeviceObject(const std::string& device_path, const std::string& hub_path, - int port_number) { + int port_number, + const std::string& driver_name) { // Devices that appear during initial enumeration are gathered into the first // result returned by GetDevices() and prevent device add/remove notifications // from being sent. if (!enumeration_ready()) ++first_enumeration_countdown_; - scoped_refptr<UsbDeviceWin> device( - new UsbDeviceWin(device_path, hub_path, port_number, task_runner())); + scoped_refptr<UsbDeviceWin> device(new UsbDeviceWin( + device_path, hub_path, port_number, driver_name, blocking_task_runner())); devices_by_path_[device->device_path()] = device; device->ReadDescriptors(base::Bind(&UsbServiceWin::DeviceReady, weak_factory_.GetWeakPtr(), device)); @@ -367,7 +387,8 @@ << device->manufacturer_string() << "\", product=" << device->product_id() << " \"" << device->product_string() << "\", serial=\"" - << device->serial_number() << "\", guid=" << device->guid(); + << device->serial_number() << "\", driver=\"" + << device->driver_name() << "\", guid=" << device->guid(); } else { devices_by_path_.erase(it); }
diff --git a/device/usb/usb_service_win.h b/device/usb/usb_service_win.h index a915577..58f4bb2 100644 --- a/device/usb/usb_service_win.h +++ b/device/usb/usb_service_win.h
@@ -41,7 +41,8 @@ void HelperStarted(); void CreateDeviceObject(const std::string& device_path, const std::string& hub_path, - int port_number); + int port_number, + const std::string& driver_name); void DeviceReady(scoped_refptr<UsbDeviceWin> device, bool success);
diff --git a/docs/ios_infra.md b/docs/ios_infra.md index cd423126..3ab0d7f 100644 --- a/docs/ios_infra.md +++ b/docs/ios_infra.md
@@ -118,14 +118,239 @@ determined not to affect a certain test target, compilation and execution of the test target will be skipped. +## Configuring the bots + +See the [configs code location](#Configs) for where to find the config files for +the bots. The config files are JSON which describe how the bot should compile +and which tests it should run. The config files are located in the configs +directory. The configs directory contains a named directory for each master. For +example: +```shell +$ ls ios/build/bots +OWNERS scripts tests chromium.fyi chromium.mac +``` +In this case, configs are defined for iOS bots on [chromium.fyi] and +[chromium.mac]. Inside each master-specific directory are JSON config files +named after each bot. For example: +```shell +$ ls ios/build/bots/chromium.mac +ios-device.json ios-simulator.json +``` +The `ios-device` bot on [chromium.mac] will read its configuration from +`chromium.mac/ios-device.json` in the configs directory. + +### Example + +```json +{ + "comments": [ + "Sample config for a bot." + ], + "gn_args": [ + "is_debug=true", + "target_cpu=\"x64\"" + ], + "tests": [ + { + "app": "ios_chrome_unittests", + "device type": "iPhone 5s", + "os": "10.0", + "xcode version": "8.0" + } + ] +} +``` +The `comments` key is optional and defines a list of strings which can be used +to annotate the config. You may want to explain why the bot exists and what it's +doing, particularly if there are extensive and atypical `gn_args`. + +The `gn_args` key is a required list of arguments to pass to [GN] to generate +the build files. Two GN args are required, `is_debug` and `target_cpu`. Use +`is_debug` to define whether to compile for Debug or Release, and `target_cpu` +to define whether to compile for x86, x64, arm, or arm64. The iOS bots typically +perform Debug builds for x86 and x64, and Release builds for arm and arm64. An +x86/x64 build can only be tested on the [iOS simulator], while an arm/arm64 +build can only be tested on a physical device. + +Since Chromium for iOS is shipped as a [universal binary], it's also fairly +common to set `additional_target_cpus`. For simulator builds, we typically set: +```json +"gn_args": [ + "additional_target_cpus=[\"x86\"]", + "is_debug=true", + "target_cpu=\"x64\"" +] +``` +This builds universal binaries which run in 32-bit mode on 32-bit simulators and +64-bit mode on 64-bit simulators. For device builds we typically set: +```json +"gn_args": [ + "additional_target_cpus=[\"arm\"]", + "is_debug=false", + "target_cpu=\"arm64\"" +] +``` +In order to build universal binaries which run in 32-bit mode on 32-bit devices +and 64-bit mode on 64-bit devices. + +The `tests` key is an optional list of dictionaries defining tests to run. There +are two types of test dictionary, `app` and `include`. An `app` dict defines a +specific compiled app to run, for example: +```json +"tests": [ + { + "app": "ios_chrome_unittests", + "device type": "iPhone 5s", + "os": "10.0", + "xcode version": "8.0" + } +] +``` +This dict says to run `ios_chrome_unittests` on an `iPhone 5s` running iOS +`10.0` using Xcode `8.0`. A test dict may optionally define a list of `test +args`, which are arguments to pass directly to the test on the command line, +and it may define a boolean value `xctest` to indicate whether the test is an +[xctest] \(default if unspecified is `false`\). For example: +```json +"tests": [ + { + "app": "ios_chrome_unittests", + "device type": "iPhone 5s", + "os": "10.0", + "test args": [ + "--foo", + "--bar" + ], + "xcode version": "8.0" + }, + { + "app": "ios_chrome_integration_egtests", + "device type": "iPhone 5s", + "os": "10.0", + "xcode version": "8.0", + "xctest": true + } +] +``` +This defines two tests to run, first `ios_chrome_unittests` will be run with +`--foo` and `--bar` passed directly to the test on the command line. Next, +`ios_chrome_integration_egtests` will be run as an xctest. `"xctest": true` +must be specified for all xctests, it is an error to try and launch an xctest as +a regular test. + +An `include` dict defines a list of tests to import from the `tests` +subdirectory in the configs directory. For example: +```json +"tests": [ + { + "include": "common_tests.json", + "device type": "iPhone 5s", + "os": "10.0", + "xcode version": "8.0" + } +] +``` +This dict says to import the list of tests from the `tests` subdirectory and run +each one on an `iPhone 5s` running iOS `10.0` using Xcode `8.0`. Here's what +`common_tests.json` might look like: +```json +"tests": [ + { + "app": "ios_chrome_unittests" + }, + { + "app": "ios_net_unittests" + }, + { + "app": "ios_web_unittests" + }, +] +``` +Includes may contain other keys besides `app` which can then be omitted in the +bot config. For example if `common_tests.json` specifies: +```json +"tests": [ + { + "app": "ios_chrome_integration_egtests", + "xctest": true, + "xcode version": "8.0" + } +] +``` +Then the bot config may omit the `xctest` or `xcode version` keys, for example: +```json +{ + "comments": [ + "Sample config for a bot." + ], + "gn_args": [ + "is_debug=true", + "target_cpu=\"x64\"" + ], + "tests": [ + { + "include": "common_tests.json", + "device type": "iPhone 5s", + "os": "10.0" + } + ] +} +``` +Includes are not recursive, so `common_tests.json` may not itself include any +`include` dicts. + +### Uploading compiled artifacts from a bot + +A bot may be configured to upload compiled artifacts. This is defined by the +`upload` key. For example: +```json +{ + "comments": [ + "Sample config for a bot which uploads artifacts." + ], + "gn_args": [ + "is_debug=true", + "target_cpu=\"x64\"" + ], + "upload": [ + { + "artifact": "Chromium.breakpad", + "bucket": "my-gcs-bucket", + }, + { + "artifact": "Chromium.app", + "bucket": "my-gcs-bucket", + "compress": true, + }, + { + "artifact": "Chromium.breakpad", + "symupload": true, + } + ] +} +``` +After compilation, the bot will upload three artifacts. First the +`Chromium.breakpad` symbols will be uploaded to +`gs://my-gcs-bucket/<buildername>/<buildnumber>/Chromium.breakpad`. Next +`Chromium.app` will be tarred, gzipped, and uploaded to +`gs://my-gcs-bucket/<buildername>/<buildnumber>/Chromium.tar.gz`. Finally +the `Chromium.breakpad` symbols will be uploaded to the [breakpad] crash +reporting server where they can be used to symbolicate stack traces. + +If `artifact` is a directory, you must specify `"compress": true`. + [analyzer]: ../tools/mb +[breakpad]: https://chromium.googlesource.com/breakpad/breakpad [buildbucket]: https://cr-buildbucket.appspot.com +[chromium.fyi]: https://build.chromium.org/p/chromium.fyi/waterfall [chromium.mac]: https://build.chromium.org/p/chromium.mac [clang]: ../tools/clang [commit queue]: https://dev.chromium.org/developers/testing/commit-queue [gitiles]: https://gerrit.googlesource.com/gitiles +[GN]: ../tools/gn [instructions]: ./ios_build_instructions.md [iOS recipes]: https://chromium.googlesource.com/chromium/tools/build/+/master/scripts/slave/recipes/ios +[iOS simulator]: ../testing/iossim [recipe module]: https://chromium.googlesource.com/chromium/tools/build/+/master/scripts/slave/recipe_modules/ios [recipes]: https://chromium.googlesource.com/infra/infra/+/HEAD/doc/users/recipes.md [simulator]: https://developer.apple.com/library/content/documentation/IDEs/Conceptual/iOS_Simulator_Guide/Introduction/Introduction.html @@ -138,3 +363,5 @@ [try job access]: https://www.chromium.org/getting-involved/become-a-committer#TOC-Try-job-access [try server]: https://build.chromium.org/p/tryserver.chromium.mac/waterfall [tryserver.chromium.mac]: https://build.chromium.org/p/tryserver.chromium.mac/waterfall +[universal binary]: https://en.wikipedia.org/wiki/Universal_binary +[xctest]: https://developer.apple.com/reference/xctest
diff --git a/extensions/browser/api/declarative/rules_registry_service.cc b/extensions/browser/api/declarative/rules_registry_service.cc index 8fac461..3d8e5ba 100644 --- a/extensions/browser/api/declarative/rules_registry_service.cc +++ b/extensions/browser/api/declarative/rules_registry_service.cc
@@ -20,6 +20,8 @@ #include "extensions/browser/api/web_request/web_request_api.h" #include "extensions/browser/extension_registry.h" #include "extensions/common/extension.h" +#include "extensions/common/features/feature_channel.h" +#include "extensions/common/features/feature_provider.h" namespace extensions { @@ -74,24 +76,31 @@ if (ContainsKey(rule_registries_, key)) return; - // Only cache rules for regular pages. - RulesCacheDelegate* web_request_cache_delegate = NULL; - if (rules_registry_id == kDefaultRulesRegistryID) { - // Create a RulesCacheDelegate. - web_request_cache_delegate = - new RulesCacheDelegate(true /*log_storage_init_delay*/); - cache_delegates_.push_back(base::WrapUnique(web_request_cache_delegate)); - } - scoped_refptr<WebRequestRulesRegistry> web_request_rules_registry( - new WebRequestRulesRegistry(browser_context_, web_request_cache_delegate, - rules_registry_id)); + // Create a web request rules registry if declarative web request is enabled + // on the current channel. + const Feature* declarative_web_request = + FeatureProvider::GetAPIFeature("declarativeWebRequest"); + if (declarative_web_request->IsAvailableToChannel(GetCurrentChannel()) + .is_available()) { + // Only cache rules for regular pages. + RulesCacheDelegate* web_request_cache_delegate = nullptr; + if (rules_registry_id == kDefaultRulesRegistryID) { + // Create a RulesCacheDelegate. + web_request_cache_delegate = + new RulesCacheDelegate(true /*log_storage_init_delay*/); + cache_delegates_.push_back(base::WrapUnique(web_request_cache_delegate)); + } + scoped_refptr<WebRequestRulesRegistry> web_request_rules_registry( + new WebRequestRulesRegistry( + browser_context_, web_request_cache_delegate, rules_registry_id)); - RegisterRulesRegistry(web_request_rules_registry); - content::BrowserThread::PostTask( - content::BrowserThread::IO, FROM_HERE, - base::Bind(&RegisterToExtensionWebRequestEventRouterOnIO, - browser_context_, rules_registry_id, - web_request_rules_registry)); + RegisterRulesRegistry(web_request_rules_registry); + content::BrowserThread::PostTask( + content::BrowserThread::IO, FROM_HERE, + base::Bind(&RegisterToExtensionWebRequestEventRouterOnIO, + browser_context_, rules_registry_id, + web_request_rules_registry)); + } // Only create a ContentRulesRegistry for regular pages. if (rules_registry_id == kDefaultRulesRegistryID) {
diff --git a/extensions/browser/api/file_handlers/directory_util.cc b/extensions/browser/api/file_handlers/directory_util.cc index 516be8f..96d8faa 100644 --- a/extensions/browser/api/file_handlers/directory_util.cc +++ b/extensions/browser/api/file_handlers/directory_util.cc
@@ -6,9 +6,9 @@ #include "base/files/file_path.h" #include "base/files/file_util.h" +#include "base/task_scheduler/post_task.h" #include "base/threading/thread_task_runner_handle.h" #include "content/public/browser/browser_context.h" -#include "content/public/browser/browser_thread.h" #include "net/base/filename_util.h" #include "storage/browser/fileapi/file_system_url.h" @@ -22,16 +22,9 @@ namespace { -void GetIsDirectoryFromFileInfo(const base::FilePath& path, - bool* is_directory) { +bool GetIsDirectoryFromFileInfo(const base::FilePath& path) { base::File::Info file_info; - *is_directory = GetFileInfo(path, &file_info) && file_info.is_directory; -} - -void OnGetIsDirectoryFromFileInfoCompleted( - std::unique_ptr<bool> is_directory, - const base::Callback<void(bool)>& callback) { - callback.Run(*is_directory); + return GetFileInfo(path, &file_info) && file_info.is_directory; } // The callback parameter contains the result and is required to support @@ -49,14 +42,9 @@ } #endif - std::unique_ptr<bool> is_directory(new bool); - bool* const is_directory_ptr = is_directory.get(); - - content::BrowserThread::PostBlockingPoolTaskAndReply( - FROM_HERE, - base::Bind(&GetIsDirectoryFromFileInfo, path, is_directory_ptr), - base::Bind(&OnGetIsDirectoryFromFileInfoCompleted, - base::Passed(&is_directory), callback)); + base::PostTaskWithTraitsAndReplyWithResult( + FROM_HERE, base::TaskTraits().MayBlock(), + base::Bind(&GetIsDirectoryFromFileInfo, path), callback); } } // namespace
diff --git a/extensions/browser/api/printer_provider/OWNERS b/extensions/browser/api/printer_provider/OWNERS index 0fa42c6a4..d038a71 100644 --- a/extensions/browser/api/printer_provider/OWNERS +++ b/extensions/browser/api/printer_provider/OWNERS
@@ -1,2 +1,4 @@ tbarzic@chromium.org vitalybuka@chromium.org + +# COMPONENT: Internals>Printing
diff --git a/extensions/browser/api/printer_provider_internal/OWNERS b/extensions/browser/api/printer_provider_internal/OWNERS index 0fa42c6a4..d038a71 100644 --- a/extensions/browser/api/printer_provider_internal/OWNERS +++ b/extensions/browser/api/printer_provider_internal/OWNERS
@@ -1,2 +1,4 @@ tbarzic@chromium.org vitalybuka@chromium.org + +# COMPONENT: Internals>Printing
diff --git a/extensions/browser/api/system_display/system_display_api.cc b/extensions/browser/api/system_display/system_display_api.cc index a12d237..820e2fb 100644 --- a/extensions/browser/api/system_display/system_display_api.cc +++ b/extensions/browser/api/system_display/system_display_api.cc
@@ -142,7 +142,7 @@ if (!create) return nullptr; auto owned_observer = base::MakeUnique<OverscanWebObserver>(web_contents); - auto observer_ptr = owned_observer.get(); + auto* observer_ptr = owned_observer.get(); observers_[web_contents] = std::move(owned_observer); return observer_ptr; }
diff --git a/extensions/browser/content_verify_job.cc b/extensions/browser/content_verify_job.cc index 56552f8..e2f9f7eb 100644 --- a/extensions/browser/content_verify_job.cc +++ b/extensions/browser/content_verify_job.cc
@@ -8,10 +8,8 @@ #include "base/metrics/histogram_macros.h" #include "base/stl_util.h" -#include "base/task_runner_util.h" -#include "base/threading/sequenced_worker_pool.h" +#include "base/task_scheduler/post_task.h" #include "base/timer/elapsed_timer.h" -#include "content/public/browser/browser_thread.h" #include "crypto/secure_hash.h" #include "crypto/sha2.h" #include "extensions/browser/content_hash_reader.h" @@ -67,9 +65,10 @@ if (g_test_observer) g_test_observer->JobStarted(hash_reader_->extension_id(), hash_reader_->relative_path()); - base::PostTaskAndReplyWithResult( - content::BrowserThread::GetBlockingPool(), + base::PostTaskWithTraitsAndReplyWithResult( FROM_HERE, + base::TaskTraits().MayBlock().WithPriority( + base::TaskPriority::USER_VISIBLE), base::Bind(&ContentHashReader::Init, hash_reader_), base::Bind(&ContentVerifyJob::OnHashesReady, this)); }
diff --git a/extensions/browser/image_loader.cc b/extensions/browser/image_loader.cc index c2b1fff..038e8be 100644 --- a/extensions/browser/image_loader.cc +++ b/extensions/browser/image_loader.cc
@@ -244,7 +244,7 @@ scales.insert(ui::GetScaleForScaleFactor(scale)); // There may not be a screen in unit tests. - auto screen = display::Screen::GetScreen(); + auto* screen = display::Screen::GetScreen(); if (screen) { for (const auto& display : screen->GetAllDisplays()) scales.insert(display.device_scale_factor());
diff --git a/extensions/browser/sandboxed_unpacker.cc b/extensions/browser/sandboxed_unpacker.cc index 649a48c..043dcd6 100644 --- a/extensions/browser/sandboxed_unpacker.cc +++ b/extensions/browser/sandboxed_unpacker.cc
@@ -36,7 +36,7 @@ #include "extensions/common/manifest_constants.h" #include "extensions/common/manifest_handlers/icons_handler.h" #include "extensions/common/switches.h" -#include "grit/extensions_strings.h" +#include "extensions/strings/grit/extensions_strings.h" #include "third_party/skia/include/core/SkBitmap.h" #include "ui/base/l10n/l10n_util.h" #include "ui/gfx/codec/png_codec.h"
diff --git a/extensions/browser/updater/safe_manifest_parser.cc b/extensions/browser/updater/safe_manifest_parser.cc index 3bc3aee0..08f22a1 100644 --- a/extensions/browser/updater/safe_manifest_parser.cc +++ b/extensions/browser/updater/safe_manifest_parser.cc
@@ -12,8 +12,8 @@ #include "content/public/browser/utility_process_host.h" #include "content/public/common/content_switches.h" #include "extensions/common/extension_utility_messages.h" +#include "extensions/strings/grit/extensions_strings.h" #include "ipc/ipc_message_macros.h" -#include "grit/extensions_strings.h" #include "ui/base/l10n/l10n_util.h" using content::BrowserThread;
diff --git a/extensions/common/api/bluetooth/bluetooth_manifest_handler.cc b/extensions/common/api/bluetooth/bluetooth_manifest_handler.cc index 6a666d9..e2ffb520 100644 --- a/extensions/common/api/bluetooth/bluetooth_manifest_handler.cc +++ b/extensions/common/api/bluetooth/bluetooth_manifest_handler.cc
@@ -24,7 +24,7 @@ if (!data) return false; - extension->SetManifestData(manifest_keys::kBluetooth, data.release()); + extension->SetManifestData(manifest_keys::kBluetooth, std::move(data)); return true; }
diff --git a/extensions/common/api/bluetooth/bluetooth_manifest_permission.cc b/extensions/common/api/bluetooth/bluetooth_manifest_permission.cc index bb6e314..4b67edf 100644 --- a/extensions/common/api/bluetooth/bluetooth_manifest_permission.cc +++ b/extensions/common/api/bluetooth/bluetooth_manifest_permission.cc
@@ -16,7 +16,7 @@ #include "extensions/common/features/behavior_feature.h" #include "extensions/common/features/feature_provider.h" #include "extensions/common/manifest_constants.h" -#include "grit/extensions_strings.h" +#include "extensions/strings/grit/extensions_strings.h" #include "ipc/ipc_message.h" #include "ui/base/l10n/l10n_util.h"
diff --git a/extensions/common/api/declarative/declarative_manifest_handler.cc b/extensions/common/api/declarative/declarative_manifest_handler.cc index 28b0482..6ff2a318 100644 --- a/extensions/common/api/declarative/declarative_manifest_handler.cc +++ b/extensions/common/api/declarative/declarative_manifest_handler.cc
@@ -25,7 +25,7 @@ if (!data) return false; - extension->SetManifestData(manifest_keys::kEventRules, data.release()); + extension->SetManifestData(manifest_keys::kEventRules, std::move(data)); return true; }
diff --git a/extensions/common/api/printer_provider/usb_printer_manifest_handler.cc b/extensions/common/api/printer_provider/usb_printer_manifest_handler.cc index eb6468f..d4fd8ee4 100644 --- a/extensions/common/api/printer_provider/usb_printer_manifest_handler.cc +++ b/extensions/common/api/printer_provider/usb_printer_manifest_handler.cc
@@ -26,7 +26,7 @@ return false; } - extension->SetManifestData(manifest_keys::kUsbPrinters, data.release()); + extension->SetManifestData(manifest_keys::kUsbPrinters, std::move(data)); return true; }
diff --git a/extensions/common/api/sockets/sockets_manifest_handler.cc b/extensions/common/api/sockets/sockets_manifest_handler.cc index cad731ef..d678b7e 100644 --- a/extensions/common/api/sockets/sockets_manifest_handler.cc +++ b/extensions/common/api/sockets/sockets_manifest_handler.cc
@@ -24,7 +24,7 @@ if (!data) return false; - extension->SetManifestData(manifest_keys::kSockets, data.release()); + extension->SetManifestData(manifest_keys::kSockets, std::move(data)); return true; }
diff --git a/extensions/common/api/sockets/sockets_manifest_permission.cc b/extensions/common/api/sockets/sockets_manifest_permission.cc index aa90412..3380173 100644 --- a/extensions/common/api/sockets/sockets_manifest_permission.cc +++ b/extensions/common/api/sockets/sockets_manifest_permission.cc
@@ -14,7 +14,7 @@ #include "extensions/common/api/sockets/sockets_manifest_data.h" #include "extensions/common/error_utils.h" #include "extensions/common/manifest_constants.h" -#include "grit/extensions_strings.h" +#include "extensions/strings/grit/extensions_strings.h" #include "ipc/ipc_message.h" #include "ui/base/l10n/l10n_util.h"
diff --git a/extensions/common/event_filter.cc b/extensions/common/event_filter.cc index b91f25f..7130238 100644 --- a/extensions/common/event_filter.cc +++ b/extensions/common/event_filter.cc
@@ -87,13 +87,14 @@ bool EventFilter::CreateConditionSets( EventMatcher* matcher, URLMatcherConditionSet::Vector* condition_sets) { - if (matcher->GetURLFilterCount() == 0) { + int url_filter_count = matcher->GetURLFilterCount(); + if (url_filter_count == 0) { // If there are no URL filters then we want to match all events, so create a // URLFilter from an empty dictionary. base::DictionaryValue empty_dict; return AddDictionaryAsConditionSet(&empty_dict, condition_sets); } - for (int i = 0; i < matcher->GetURLFilterCount(); i++) { + for (int i = 0; i < url_filter_count; i++) { base::DictionaryValue* url_filter; if (!matcher->GetURLFilter(i, &url_filter)) return false; @@ -176,7 +177,7 @@ return matchers; } -int EventFilter::GetMatcherCountForEvent(const std::string& name) { +int EventFilter::GetMatcherCountForEventForTesting(const std::string& name) { EventMatcherMultiMap::const_iterator it = event_matchers_.find(name); if (it == event_matchers_.end()) return 0;
diff --git a/extensions/common/event_filter.h b/extensions/common/event_filter.h index 288c4a1d..55b85b9 100644 --- a/extensions/common/event_filter.h +++ b/extensions/common/event_filter.h
@@ -48,12 +48,9 @@ const EventFilteringInfo& event_info, int routing_id); - int GetMatcherCountForEvent(const std::string& event_name); + int GetMatcherCountForEventForTesting(const std::string& event_name); - // For testing. - bool IsURLMatcherEmpty() const { - return url_matcher_.IsEmpty(); - } + bool IsURLMatcherEmptyForTesting() const { return url_matcher_.IsEmpty(); } private: class EventMatcherEntry {
diff --git a/extensions/common/event_filter_unittest.cc b/extensions/common/event_filter_unittest.cc index 1d88d0e7..6e96c991 100644 --- a/extensions/common/event_filter_unittest.cc +++ b/extensions/common/event_filter_unittest.cc
@@ -192,15 +192,15 @@ } TEST_F(EventFilterUnittest, TestGetMatcherCountForEvent) { - ASSERT_EQ(0, event_filter_.GetMatcherCountForEvent("event1")); + ASSERT_EQ(0, event_filter_.GetMatcherCountForEventForTesting("event1")); int id1 = event_filter_.AddEventMatcher("event1", AllURLs()); - ASSERT_EQ(1, event_filter_.GetMatcherCountForEvent("event1")); + ASSERT_EQ(1, event_filter_.GetMatcherCountForEventForTesting("event1")); int id2 = event_filter_.AddEventMatcher("event1", AllURLs()); - ASSERT_EQ(2, event_filter_.GetMatcherCountForEvent("event1")); + ASSERT_EQ(2, event_filter_.GetMatcherCountForEventForTesting("event1")); event_filter_.RemoveEventMatcher(id1); - ASSERT_EQ(1, event_filter_.GetMatcherCountForEvent("event1")); + ASSERT_EQ(1, event_filter_.GetMatcherCountForEventForTesting("event1")); event_filter_.RemoveEventMatcher(id2); - ASSERT_EQ(0, event_filter_.GetMatcherCountForEvent("event1")); + ASSERT_EQ(0, event_filter_.GetMatcherCountForEventForTesting("event1")); } TEST_F(EventFilterUnittest, RemoveEventMatcherReturnsEventName) { @@ -220,7 +220,7 @@ std::unique_ptr<EventMatcher> matcher( MatcherFromURLFilterList(std::move(filter_list))); int id1 = event_filter_.AddEventMatcher("event1", std::move(matcher)); - EXPECT_TRUE(event_filter_.IsURLMatcherEmpty()); + EXPECT_TRUE(event_filter_.IsURLMatcherEmptyForTesting()); ASSERT_EQ(-1, id1); } @@ -237,12 +237,12 @@ TEST_F(EventFilterUnittest, InternalURLMatcherShouldBeEmptyWhenThereAreNoEventMatchers) { - ASSERT_TRUE(event_filter_.IsURLMatcherEmpty()); + ASSERT_TRUE(event_filter_.IsURLMatcherEmptyForTesting()); int id = event_filter_.AddEventMatcher("event1", HostSuffixMatcher("google.com")); - ASSERT_FALSE(event_filter_.IsURLMatcherEmpty()); + ASSERT_FALSE(event_filter_.IsURLMatcherEmptyForTesting()); event_filter_.RemoveEventMatcher(id); - ASSERT_TRUE(event_filter_.IsURLMatcherEmpty()); + ASSERT_TRUE(event_filter_.IsURLMatcherEmptyForTesting()); } TEST_F(EventFilterUnittest, EmptyURLsShouldBeMatchedByEmptyURLFilters) {
diff --git a/extensions/common/event_matcher.cc b/extensions/common/event_matcher.cc index 25d23ab9..3876b899 100644 --- a/extensions/common/event_matcher.cc +++ b/extensions/common/event_matcher.cc
@@ -32,11 +32,13 @@ } if (event_info.has_window_type()) { - for (int i = 0; i < GetWindowTypeCount(); i++) { + int window_type_count = GetWindowTypeCount(); + for (int i = 0; i < window_type_count; i++) { std::string window_type; if (GetWindowType(i, &window_type) && - window_type == event_info.window_type()) + window_type == event_info.window_type()) { return true; + } } return false; }
diff --git a/extensions/common/event_matcher.h b/extensions/common/event_matcher.h index e775398..802aa68 100644 --- a/extensions/common/event_matcher.h +++ b/extensions/common/event_matcher.h
@@ -55,9 +55,9 @@ // {url: [{hostSuffix: 'google.com'}]} // // The valid filter keys are event-specific. - std::unique_ptr<base::DictionaryValue> filter_; + const std::unique_ptr<base::DictionaryValue> filter_; - int routing_id_; + const int routing_id_; DISALLOW_COPY_AND_ASSIGN(EventMatcher); };
diff --git a/extensions/common/extension.cc b/extensions/common/extension.cc index 6e86d9e..2022263d 100644 --- a/extensions/common/extension.cc +++ b/extensions/common/extension.cc
@@ -379,9 +379,9 @@ } void Extension::SetManifestData(const std::string& key, - Extension::ManifestData* data) { + std::unique_ptr<Extension::ManifestData> data) { DCHECK(!finished_parsing_manifest_ && thread_checker_.CalledOnValidThread()); - manifest_data_[key] = std::unique_ptr<ManifestData>(data); + manifest_data_[key] = std::move(data); } Manifest::Location Extension::location() const {
diff --git a/extensions/common/extension.h b/extensions/common/extension.h index a5c2702..97c0ca6eb 100644 --- a/extensions/common/extension.h +++ b/extensions/common/extension.h
@@ -258,10 +258,11 @@ // Can only be called after InitValue is finished. ManifestData* GetManifestData(const std::string& key) const; - // Sets |data| to be associated with the key. Takes ownership of |data|. + // Sets |data| to be associated with the key. // Can only be called before InitValue is finished. Not thread-safe; // all SetManifestData calls should be on only one thread. - void SetManifestData(const std::string& key, ManifestData* data); + void SetManifestData(const std::string& key, + std::unique_ptr<ManifestData> data); // Accessors:
diff --git a/extensions/common/features/complex_feature.cc b/extensions/common/features/complex_feature.cc index ed129da..35680d1 100644 --- a/extensions/common/features/complex_feature.cc +++ b/extensions/common/features/complex_feature.cc
@@ -98,6 +98,24 @@ return false; } +Feature::Availability ComplexFeature::IsAvailableToChannel( + version_info::Channel channel) const { + Feature::Availability first_availability = + features_[0]->IsAvailableToChannel(channel); + if (first_availability.is_available()) + return first_availability; + + for (FeatureList::const_iterator it = features_.begin() + 1; + it != features_.end(); ++it) { + Availability availability = (*it)->IsAvailableToChannel(channel); + if (availability.is_available()) + return availability; + } + // If none of the SimpleFeatures are available, we return the availability + // info of the first SimpleFeature that was not available. + return first_availability; +} + bool ComplexFeature::IsInternal() const { // Constructor verifies that composed features are consistent, thus we can // return just the first feature's value.
diff --git a/extensions/common/features/complex_feature.h b/extensions/common/features/complex_feature.h index 9ccbd4f..c331901 100644 --- a/extensions/common/features/complex_feature.h +++ b/extensions/common/features/complex_feature.h
@@ -41,6 +41,8 @@ bool IsIdInBlacklist(const std::string& extension_id) const override; bool IsIdInWhitelist(const std::string& extension_id) const override; + Availability IsAvailableToChannel( + version_info::Channel channel) const override; protected: // Feature:
diff --git a/extensions/common/features/feature.h b/extensions/common/features/feature.h index d3179bb9..0664e173 100644 --- a/extensions/common/features/feature.h +++ b/extensions/common/features/feature.h
@@ -10,6 +10,7 @@ #include "base/strings/string_piece.h" #include "base/values.h" +#include "components/version_info/version_info.h" #include "extensions/common/manifest.h" class GURL; @@ -136,6 +137,12 @@ const GURL& url, Platform platform) const = 0; + // Returns the availability of the feature on the given |channel|. The + // availability result will either be IS_AVAILABLE, UNSUPPORTED_CHANNEL or + // NOT_PRESENT. + virtual Availability IsAvailableToChannel( + version_info::Channel channel) const = 0; + // Returns true if the feature is available to the current environment, // without needing to know information about an Extension or any other // contextual information. Typically used when the Feature is purely
diff --git a/extensions/common/features/simple_feature.cc b/extensions/common/features/simple_feature.cc index d901cd9..0f7675b1 100644 --- a/extensions/common/features/simple_feature.cc +++ b/extensions/common/features/simple_feature.cc
@@ -53,6 +53,11 @@ return feature->IsAvailableToContext(extension, context, url, platform); } +Feature::Availability IsAvailableToChannelForBind(version_info::Channel channel, + const Feature* feature) { + return feature->IsAvailableToChannel(channel); +} + // Gets a human-readable name for the given extension type, suitable for giving // to developers in an error message. std::string GetDisplayName(Manifest::Type type) { @@ -455,6 +460,13 @@ return IsIdInList(extension_id, whitelist_); } +Feature::Availability SimpleFeature::IsAvailableToChannel( + version_info::Channel channel) const { + if (channel_ && *channel_ < channel) + return CreateAvailability(UNSUPPORTED_CHANNEL, *channel_); + return CheckDependencies(base::Bind(&IsAvailableToChannelForBind, channel)); +} + // static bool SimpleFeature::IsIdInArray(const std::string& extension_id, const char* const array[],
diff --git a/extensions/common/features/simple_feature.h b/extensions/common/features/simple_feature.h index 343282e..117da20a 100644 --- a/extensions/common/features/simple_feature.h +++ b/extensions/common/features/simple_feature.h
@@ -76,6 +76,8 @@ bool IsInternal() const override; bool IsIdInBlacklist(const std::string& extension_id) const override; bool IsIdInWhitelist(const std::string& extension_id) const override; + Availability IsAvailableToChannel( + version_info::Channel channel) const override; static bool IsIdInArray(const std::string& extension_id, const char* const array[],
diff --git a/extensions/common/features/simple_feature_unittest.cc b/extensions/common/features/simple_feature_unittest.cc index a570248..e8f4c3c 100644 --- a/extensions/common/features/simple_feature_unittest.cc +++ b/extensions/common/features/simple_feature_unittest.cc
@@ -45,15 +45,9 @@ Feature::AvailabilityResult IsAvailableInChannel(Channel channel_for_feature, Channel channel_for_testing) { - ScopedCurrentChannel current_channel(channel_for_testing); - SimpleFeature feature; feature.set_channel(channel_for_feature); - return feature - .IsAvailableToManifest("random-extension", Manifest::TYPE_UNKNOWN, - Manifest::INVALID_LOCATION, -1, - Feature::GetCurrentPlatform()) - .result(); + return feature.IsAvailableToChannel(channel_for_testing).result(); } } // namespace @@ -762,56 +756,6 @@ IsAvailableInChannel(Channel::UNKNOWN, Channel::STABLE)); } -// Tests simple feature availability across channels. -TEST_F(SimpleFeatureTest, SimpleFeatureAvailability) { - std::unique_ptr<ComplexFeature> complex_feature; - { - std::unique_ptr<SimpleFeature> feature1(new SimpleFeature()); - feature1->channel_.reset(new Channel(Channel::BETA)); - feature1->extension_types_.push_back(Manifest::TYPE_EXTENSION); - std::unique_ptr<SimpleFeature> feature2(new SimpleFeature()); - feature2->channel_.reset(new Channel(Channel::BETA)); - feature2->extension_types_.push_back(Manifest::TYPE_LEGACY_PACKAGED_APP); - std::vector<Feature*> list; - list.push_back(feature1.release()); - list.push_back(feature2.release()); - complex_feature.reset(new ComplexFeature(&list)); - } - - Feature* feature = static_cast<Feature*>(complex_feature.get()); - // Make sure both rules are applied correctly. - { - ScopedCurrentChannel current_channel(Channel::BETA); - EXPECT_EQ( - Feature::IS_AVAILABLE, - feature->IsAvailableToManifest("1", - Manifest::TYPE_EXTENSION, - Manifest::INVALID_LOCATION, - Feature::UNSPECIFIED_PLATFORM).result()); - EXPECT_EQ( - Feature::IS_AVAILABLE, - feature->IsAvailableToManifest("2", - Manifest::TYPE_LEGACY_PACKAGED_APP, - Manifest::INVALID_LOCATION, - Feature::UNSPECIFIED_PLATFORM).result()); - } - { - ScopedCurrentChannel current_channel(Channel::STABLE); - EXPECT_NE( - Feature::IS_AVAILABLE, - feature->IsAvailableToManifest("1", - Manifest::TYPE_EXTENSION, - Manifest::INVALID_LOCATION, - Feature::UNSPECIFIED_PLATFORM).result()); - EXPECT_NE( - Feature::IS_AVAILABLE, - feature->IsAvailableToManifest("2", - Manifest::TYPE_LEGACY_PACKAGED_APP, - Manifest::INVALID_LOCATION, - Feature::UNSPECIFIED_PLATFORM).result()); - } -} - // Tests complex feature availability across channels. TEST_F(SimpleFeatureTest, ComplexFeatureAvailability) { std::unique_ptr<ComplexFeature> complex_feature; @@ -821,8 +765,8 @@ feature1->channel_.reset(new Channel(Channel::UNKNOWN)); feature1->extension_types_.push_back(Manifest::TYPE_EXTENSION); std::unique_ptr<SimpleFeature> feature2(new SimpleFeature()); - // Rule: "legacy_packaged_app", channel stable. - feature2->channel_.reset(new Channel(Channel::STABLE)); + // Rule: "legacy_packaged_app", channel beta. + feature2->channel_.reset(new Channel(Channel::BETA)); feature2->extension_types_.push_back(Manifest::TYPE_LEGACY_PACKAGED_APP); std::vector<Feature*> list; list.push_back(feature1.release()); @@ -830,7 +774,18 @@ complex_feature.reset(new ComplexFeature(&list)); } - Feature* feature = static_cast<Feature*>(complex_feature.get()); + Feature* feature = complex_feature.get(); + EXPECT_EQ(Feature::IS_AVAILABLE, + feature->IsAvailableToChannel(Channel::UNKNOWN).result()); + EXPECT_EQ(Feature::IS_AVAILABLE, + feature->IsAvailableToChannel(Channel::CANARY).result()); + EXPECT_EQ(Feature::IS_AVAILABLE, + feature->IsAvailableToChannel(Channel::DEV).result()); + EXPECT_EQ(Feature::IS_AVAILABLE, + feature->IsAvailableToChannel(Channel::BETA).result()); + EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL, + feature->IsAvailableToChannel(Channel::STABLE).result()); + { ScopedCurrentChannel current_channel(Channel::UNKNOWN); EXPECT_EQ(Feature::IS_AVAILABLE, @@ -839,6 +794,12 @@ Manifest::INVALID_LOCATION, Feature::UNSPECIFIED_PLATFORM) .result()); + EXPECT_EQ(Feature::IS_AVAILABLE, + feature + ->IsAvailableToManifest( + "1", Manifest::TYPE_LEGACY_PACKAGED_APP, + Manifest::INVALID_LOCATION, Feature::UNSPECIFIED_PLATFORM) + .result()); } { ScopedCurrentChannel current_channel(Channel::BETA); @@ -848,9 +809,21 @@ "2", Manifest::TYPE_LEGACY_PACKAGED_APP, Manifest::INVALID_LOCATION, Feature::UNSPECIFIED_PLATFORM) .result()); + EXPECT_NE(Feature::IS_AVAILABLE, + feature + ->IsAvailableToManifest("1", Manifest::TYPE_EXTENSION, + Manifest::INVALID_LOCATION, + Feature::UNSPECIFIED_PLATFORM) + .result()); } { - ScopedCurrentChannel current_channel(Channel::BETA); + ScopedCurrentChannel current_channel(Channel::STABLE); + EXPECT_NE(Feature::IS_AVAILABLE, + feature + ->IsAvailableToManifest( + "2", Manifest::TYPE_LEGACY_PACKAGED_APP, + Manifest::INVALID_LOCATION, Feature::UNSPECIFIED_PLATFORM) + .result()); EXPECT_NE(Feature::IS_AVAILABLE, feature ->IsAvailableToManifest("1", Manifest::TYPE_EXTENSION,
diff --git a/extensions/common/file_util.cc b/extensions/common/file_util.cc index 2e986c430..7821e35 100644 --- a/extensions/common/file_util.cc +++ b/extensions/common/file_util.cc
@@ -38,7 +38,7 @@ #include "extensions/common/manifest_handler.h" #include "extensions/common/manifest_handlers/default_locale_handler.h" #include "extensions/common/manifest_handlers/icons_handler.h" -#include "grit/extensions_strings.h" +#include "extensions/strings/grit/extensions_strings.h" #include "net/base/escape.h" #include "net/base/filename_util.h" #include "ui/base/l10n/l10n_util.h"
diff --git a/extensions/common/file_util_unittest.cc b/extensions/common/file_util_unittest.cc index 5be68fa..4aea12c 100644 --- a/extensions/common/file_util_unittest.cc +++ b/extensions/common/file_util_unittest.cc
@@ -21,7 +21,7 @@ #include "extensions/common/extension_paths.h" #include "extensions/common/manifest.h" #include "extensions/common/manifest_constants.h" -#include "grit/extensions_strings.h" +#include "extensions/strings/grit/extensions_strings.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/l10n/l10n_util.h"
diff --git a/extensions/common/manifest_handlers/action_handlers_handler.cc b/extensions/common/manifest_handlers/action_handlers_handler.cc index 967db22..2d30318 100644 --- a/extensions/common/manifest_handlers/action_handlers_handler.cc +++ b/extensions/common/manifest_handlers/action_handlers_handler.cc
@@ -59,7 +59,7 @@ info->action_handlers.insert(action_type); } - extension->SetManifestData(keys::kActionHandlers, info.release()); + extension->SetManifestData(keys::kActionHandlers, std::move(info)); return true; }
diff --git a/extensions/common/manifest_handlers/app_isolation_info.cc b/extensions/common/manifest_handlers/app_isolation_info.cc index 3242ca2..94be889 100644 --- a/extensions/common/manifest_handlers/app_isolation_info.cc +++ b/extensions/common/manifest_handlers/app_isolation_info.cc
@@ -8,6 +8,7 @@ #include <memory> +#include "base/memory/ptr_util.h" #include "base/strings/string16.h" #include "base/strings/string_number_conversions.h" #include "base/strings/utf_string_conversions.h" @@ -44,7 +45,8 @@ bool AppIsolationHandler::Parse(Extension* extension, base::string16* error) { // Platform apps always get isolated storage. if (extension->is_platform_app()) { - extension->SetManifestData(keys::kIsolation, new AppIsolationInfo(true)); + extension->SetManifestData(keys::kIsolation, + base::MakeUnique<AppIsolationInfo>(true)); return true; } @@ -84,7 +86,8 @@ } if (has_isolated_storage) - extension->SetManifestData(keys::kIsolation, new AppIsolationInfo(true)); + extension->SetManifestData(keys::kIsolation, + base::MakeUnique<AppIsolationInfo>(true)); return true; }
diff --git a/extensions/common/manifest_handlers/background_info.cc b/extensions/common/manifest_handlers/background_info.cc index 3cd0bc4..0466dcd 100644 --- a/extensions/common/manifest_handlers/background_info.cc +++ b/extensions/common/manifest_handlers/background_info.cc
@@ -21,7 +21,7 @@ #include "extensions/common/manifest_handlers/permissions_parser.h" #include "extensions/common/permissions/api_permission_set.h" #include "extensions/common/switches.h" -#include "grit/extensions_strings.h" +#include "extensions/strings/grit/extensions_strings.h" #include "ui/base/l10n/l10n_util.h" using base::ASCIIToUTF16; @@ -267,7 +267,7 @@ return false; } - extension->SetManifestData(kBackground, info.release()); + extension->SetManifestData(kBackground, std::move(info)); return true; }
diff --git a/extensions/common/manifest_handlers/content_capabilities_handler.cc b/extensions/common/manifest_handlers/content_capabilities_handler.cc index d304017..c994dea3 100644 --- a/extensions/common/manifest_handlers/content_capabilities_handler.cc +++ b/extensions/common/manifest_handlers/content_capabilities_handler.cc
@@ -106,7 +106,7 @@ } } - extension->SetManifestData(keys::kContentCapabilities, info.release()); + extension->SetManifestData(keys::kContentCapabilities, std::move(info)); return true; }
diff --git a/extensions/common/manifest_handlers/csp_info.cc b/extensions/common/manifest_handlers/csp_info.cc index 6fe6294..48c655b 100644 --- a/extensions/common/manifest_handlers/csp_info.cc +++ b/extensions/common/manifest_handlers/csp_info.cc
@@ -6,6 +6,7 @@ #include <memory> +#include "base/memory/ptr_util.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "base/values.h" @@ -116,8 +117,9 @@ SanitizeContentSecurityPolicy(content_security_policy, GetValidatorOptions(extension), NULL)); - extension->SetManifestData(keys::kContentSecurityPolicy, - new CSPInfo(content_security_policy)); + extension->SetManifestData( + keys::kContentSecurityPolicy, + base::MakeUnique<CSPInfo>(content_security_policy)); } return true; } @@ -141,8 +143,9 @@ extension->AddInstallWarnings(warnings); } - extension->SetManifestData(keys::kContentSecurityPolicy, - new CSPInfo(content_security_policy)); + extension->SetManifestData( + keys::kContentSecurityPolicy, + base::MakeUnique<CSPInfo>(content_security_policy)); return true; }
diff --git a/extensions/common/manifest_handlers/default_locale_handler.cc b/extensions/common/manifest_handlers/default_locale_handler.cc index 47fde82..2fa21c29 100644 --- a/extensions/common/manifest_handlers/default_locale_handler.cc +++ b/extensions/common/manifest_handlers/default_locale_handler.cc
@@ -16,7 +16,7 @@ #include "extensions/common/extension_l10n_util.h" #include "extensions/common/manifest.h" #include "extensions/common/manifest_constants.h" -#include "grit/extensions_strings.h" +#include "extensions/strings/grit/extensions_strings.h" #include "ui/base/l10n/l10n_util.h" namespace extensions { @@ -45,7 +45,7 @@ *error = base::ASCIIToUTF16(manifest_errors::kInvalidDefaultLocale); return false; } - extension->SetManifestData(keys::kDefaultLocale, info.release()); + extension->SetManifestData(keys::kDefaultLocale, std::move(info)); return true; }
diff --git a/extensions/common/manifest_handlers/externally_connectable.cc b/extensions/common/manifest_handlers/externally_connectable.cc index e5942514..871ea0c 100644 --- a/extensions/common/manifest_handlers/externally_connectable.cc +++ b/extensions/common/manifest_handlers/externally_connectable.cc
@@ -82,7 +82,7 @@ APIPermission::kWebConnectable); } extension->AddInstallWarnings(install_warnings); - extension->SetManifestData(keys::kExternallyConnectable, info.release()); + extension->SetManifestData(keys::kExternallyConnectable, std::move(info)); return true; }
diff --git a/extensions/common/manifest_handlers/file_handler_info.cc b/extensions/common/manifest_handlers/file_handler_info.cc index 8ee9960..2e802553 100644 --- a/extensions/common/manifest_handlers/file_handler_info.cc +++ b/extensions/common/manifest_handlers/file_handler_info.cc
@@ -205,7 +205,7 @@ return false; } - extension->SetManifestData(keys::kFileHandlers, info.release()); + extension->SetManifestData(keys::kFileHandlers, std::move(info)); extension->AddInstallWarnings(install_warnings); return true; }
diff --git a/extensions/common/manifest_handlers/icons_handler.cc b/extensions/common/manifest_handlers/icons_handler.cc index dd599e68..90cdbddb 100644 --- a/extensions/common/manifest_handlers/icons_handler.cc +++ b/extensions/common/manifest_handlers/icons_handler.cc
@@ -16,7 +16,7 @@ #include "extensions/common/file_util.h" #include "extensions/common/manifest_constants.h" #include "extensions/common/manifest_handler_helpers.h" -#include "grit/extensions_strings.h" +#include "extensions/strings/grit/extensions_strings.h" #include "ui/gfx/geometry/size.h" namespace extensions { @@ -69,7 +69,7 @@ return false; } - extension->SetManifestData(keys::kIcons, icons_info.release()); + extension->SetManifestData(keys::kIcons, std::move(icons_info)); return true; }
diff --git a/extensions/common/manifest_handlers/incognito_info.cc b/extensions/common/manifest_handlers/incognito_info.cc index 0bae1df..74af1f0 100644 --- a/extensions/common/manifest_handlers/incognito_info.cc +++ b/extensions/common/manifest_handlers/incognito_info.cc
@@ -6,6 +6,7 @@ #include <memory> +#include "base/memory/ptr_util.h" #include "base/strings/utf_string_conversions.h" #include "base/values.h" #include "extensions/common/extension.h" @@ -48,7 +49,8 @@ ? IncognitoInfo::Mode::SPLIT : IncognitoInfo::Mode::SPANNING; if (!extension->manifest()->HasKey(keys::kIncognito)) { - extension->SetManifestData(keys::kIncognito, new IncognitoInfo(mode)); + extension->SetManifestData(keys::kIncognito, + base::MakeUnique<IncognitoInfo>(mode)); return true; } @@ -69,7 +71,8 @@ return false; } - extension->SetManifestData(keys::kIncognito, new IncognitoInfo(mode)); + extension->SetManifestData(keys::kIncognito, + base::MakeUnique<IncognitoInfo>(mode)); return true; }
diff --git a/extensions/common/manifest_handlers/kiosk_mode_info.cc b/extensions/common/manifest_handlers/kiosk_mode_info.cc index b9baf4bda..b9947e28c 100644 --- a/extensions/common/manifest_handlers/kiosk_mode_info.cc +++ b/extensions/common/manifest_handlers/kiosk_mode_info.cc
@@ -6,6 +6,7 @@ #include <memory> +#include "base/memory/ptr_util.h" #include "base/strings/string16.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" @@ -149,8 +150,8 @@ extension->SetManifestData( keys::kKioskMode, - new KioskModeInfo(kiosk_status, ids, required_platform_version, - always_update)); + base::MakeUnique<KioskModeInfo>( + kiosk_status, ids, required_platform_version, always_update)); return true; }
diff --git a/extensions/common/manifest_handlers/launcher_page_info.cc b/extensions/common/manifest_handlers/launcher_page_info.cc index d782145..9c6450d 100644 --- a/extensions/common/manifest_handlers/launcher_page_info.cc +++ b/extensions/common/manifest_handlers/launcher_page_info.cc
@@ -8,7 +8,7 @@ #include "base/strings/utf_string_conversions.h" #include "extensions/common/manifest.h" #include "extensions/common/manifest_constants.h" -#include "grit/extensions_strings.h" +#include "extensions/strings/grit/extensions_strings.h" #include "ui/base/l10n/l10n_util.h" namespace extensions { @@ -50,7 +50,7 @@ launcher_page_info->page = launcher_page_page; extension->SetManifestData(manifest_keys::kLauncherPage, - launcher_page_info.release()); + std::move(launcher_page_info)); return true; }
diff --git a/extensions/common/manifest_handlers/mime_types_handler.cc b/extensions/common/manifest_handlers/mime_types_handler.cc index 364305a..365d71c 100644 --- a/extensions/common/manifest_handlers/mime_types_handler.cc +++ b/extensions/common/manifest_handlers/mime_types_handler.cc
@@ -120,7 +120,7 @@ info->handler_.set_handler_url(mime_types_handler); } - extension->SetManifestData(keys::kMimeTypesHandler, info.release()); + extension->SetManifestData(keys::kMimeTypesHandler, std::move(info)); return true; }
diff --git a/extensions/common/manifest_handlers/nacl_modules_handler.cc b/extensions/common/manifest_handlers/nacl_modules_handler.cc index 148caca6..74244f02 100644 --- a/extensions/common/manifest_handlers/nacl_modules_handler.cc +++ b/extensions/common/manifest_handlers/nacl_modules_handler.cc
@@ -81,7 +81,7 @@ nacl_module_data->nacl_modules_.back().mime_type = mime_type; } - extension->SetManifestData(keys::kNaClModules, nacl_module_data.release()); + extension->SetManifestData(keys::kNaClModules, std::move(nacl_module_data)); return true; }
diff --git a/extensions/common/manifest_handlers/oauth2_manifest_handler.cc b/extensions/common/manifest_handlers/oauth2_manifest_handler.cc index 7d381b5..2e99bf2 100644 --- a/extensions/common/manifest_handlers/oauth2_manifest_handler.cc +++ b/extensions/common/manifest_handlers/oauth2_manifest_handler.cc
@@ -90,7 +90,7 @@ info->scopes.push_back(scope); } - extension->SetManifestData(keys::kOAuth2, info.release()); + extension->SetManifestData(keys::kOAuth2, std::move(info)); return true; }
diff --git a/extensions/common/manifest_handlers/offline_enabled_info.cc b/extensions/common/manifest_handlers/offline_enabled_info.cc index fd73099..684048f 100644 --- a/extensions/common/manifest_handlers/offline_enabled_info.cc +++ b/extensions/common/manifest_handlers/offline_enabled_info.cc
@@ -6,6 +6,7 @@ #include <memory> +#include "base/memory/ptr_util.h" #include "base/strings/string16.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" @@ -48,8 +49,9 @@ const bool has_webview_permission = PermissionsParser::HasAPIPermission(extension, APIPermission::kWebView); - extension->SetManifestData(keys::kOfflineEnabled, - new OfflineEnabledInfo(!has_webview_permission)); + extension->SetManifestData( + keys::kOfflineEnabled, + base::MakeUnique<OfflineEnabledInfo>(!has_webview_permission)); return true; } @@ -61,8 +63,9 @@ return false; } - extension->SetManifestData(keys::kOfflineEnabled, - new OfflineEnabledInfo(offline_enabled)); + extension->SetManifestData( + keys::kOfflineEnabled, + base::MakeUnique<OfflineEnabledInfo>(offline_enabled)); return true; }
diff --git a/extensions/common/manifest_handlers/options_page_info.cc b/extensions/common/manifest_handlers/options_page_info.cc index 7e1d1df..b81159f 100644 --- a/extensions/common/manifest_handlers/options_page_info.cc +++ b/extensions/common/manifest_handlers/options_page_info.cc
@@ -198,7 +198,7 @@ return false; extension->AddInstallWarnings(install_warnings); - extension->SetManifestData(keys::kOptionsUI, info.release()); + extension->SetManifestData(keys::kOptionsUI, std::move(info)); return true; }
diff --git a/extensions/common/manifest_handlers/permissions_parser.cc b/extensions/common/manifest_handlers/permissions_parser.cc index 14a2e19..af8ba0c 100644 --- a/extensions/common/manifest_handlers/permissions_parser.cc +++ b/extensions/common/manifest_handlers/permissions_parser.cc
@@ -7,6 +7,7 @@ #include <utility> #include "base/command_line.h" +#include "base/memory/ptr_util.h" #include "base/memory/ref_counted.h" #include "base/strings/utf_string_conversions.h" #include "base/values.h" @@ -275,7 +276,7 @@ initial_required_permissions_->scriptable_hosts)); extension->SetManifestData( keys::kPermissions, - new ManifestPermissions(std::move(required_permissions))); + base::MakeUnique<ManifestPermissions>(std::move(required_permissions))); std::unique_ptr<const PermissionSet> optional_permissions(new PermissionSet( initial_optional_permissions_->api_permissions, @@ -283,7 +284,7 @@ initial_optional_permissions_->host_permissions, URLPatternSet())); extension->SetManifestData( keys::kOptionalPermissions, - new ManifestPermissions(std::move(optional_permissions))); + base::MakeUnique<ManifestPermissions>(std::move(optional_permissions))); } // static
diff --git a/extensions/common/manifest_handlers/requirements_info.cc b/extensions/common/manifest_handlers/requirements_info.cc index c89d974..d73af89 100644 --- a/extensions/common/manifest_handlers/requirements_info.cc +++ b/extensions/common/manifest_handlers/requirements_info.cc
@@ -66,7 +66,7 @@ new RequirementsInfo(extension->manifest())); if (!extension->manifest()->HasKey(keys::kRequirements)) { - extension->SetManifestData(keys::kRequirements, requirements.release()); + extension->SetManifestData(keys::kRequirements, std::move(requirements)); return true; } @@ -153,7 +153,7 @@ } } - extension->SetManifestData(keys::kRequirements, requirements.release()); + extension->SetManifestData(keys::kRequirements, std::move(requirements)); return true; }
diff --git a/extensions/common/manifest_handlers/sandboxed_page_info.cc b/extensions/common/manifest_handlers/sandboxed_page_info.cc index c8ad586..11d97dc7 100644 --- a/extensions/common/manifest_handlers/sandboxed_page_info.cc +++ b/extensions/common/manifest_handlers/sandboxed_page_info.cc
@@ -120,7 +120,7 @@ CHECK(csp_validator::ContentSecurityPolicyIsSandboxed( sandboxed_info->content_security_policy, extension->GetType())); - extension->SetManifestData(keys::kSandboxedPages, sandboxed_info.release()); + extension->SetManifestData(keys::kSandboxedPages, std::move(sandboxed_info)); return true; }
diff --git a/extensions/common/manifest_handlers/shared_module_info.cc b/extensions/common/manifest_handlers/shared_module_info.cc index b8f6229..90280e85 100644 --- a/extensions/common/manifest_handlers/shared_module_info.cc +++ b/extensions/common/manifest_handlers/shared_module_info.cc
@@ -210,7 +210,7 @@ std::unique_ptr<SharedModuleInfo> info(new SharedModuleInfo); if (!info->Parse(extension, error)) return false; - extension->SetManifestData(kSharedModule, info.release()); + extension->SetManifestData(kSharedModule, std::move(info)); return true; }
diff --git a/extensions/common/manifest_handlers/web_accessible_resources_info.cc b/extensions/common/manifest_handlers/web_accessible_resources_info.cc index 1a9dc2aa..2d4b393 100644 --- a/extensions/common/manifest_handlers/web_accessible_resources_info.cc +++ b/extensions/common/manifest_handlers/web_accessible_resources_info.cc
@@ -92,7 +92,7 @@ pattern.SetPath(pattern.path() + relative_path); info->web_accessible_resources_.AddPattern(pattern); } - extension->SetManifestData(keys::kWebAccessibleResources, info.release()); + extension->SetManifestData(keys::kWebAccessibleResources, std::move(info)); return true; }
diff --git a/extensions/common/manifest_handlers/webview_info.cc b/extensions/common/manifest_handlers/webview_info.cc index 989df76..57a5aa01 100644 --- a/extensions/common/manifest_handlers/webview_info.cc +++ b/extensions/common/manifest_handlers/webview_info.cc
@@ -166,7 +166,8 @@ info->AddPartitionItem(std::move(partition_item)); } - extension->SetManifestData(keys::kWebviewAccessibleResources, info.release()); + extension->SetManifestData(keys::kWebviewAccessibleResources, + std::move(info)); return true; }
diff --git a/extensions/common/manifest_url_handlers.cc b/extensions/common/manifest_url_handlers.cc index c3bcaba..f58f1fb 100644 --- a/extensions/common/manifest_url_handlers.cc +++ b/extensions/common/manifest_url_handlers.cc
@@ -103,7 +103,7 @@ errors::kInvalidHomepageURL, homepage_url_str); return false; } - extension->SetManifestData(keys::kHomepageURL, manifest_url.release()); + extension->SetManifestData(keys::kHomepageURL, std::move(manifest_url)); return true; } @@ -135,7 +135,7 @@ return false; } - extension->SetManifestData(keys::kUpdateURL, manifest_url.release()); + extension->SetManifestData(keys::kUpdateURL, std::move(manifest_url)); return true; } @@ -167,7 +167,7 @@ *error = base::ASCIIToUTF16(errors::kInvalidAboutPage); return false; } - extension->SetManifestData(keys::kAboutPage, manifest_url.release()); + extension->SetManifestData(keys::kAboutPage, std::move(manifest_url)); return true; }
diff --git a/extensions/common/permissions/extensions_api_permissions.cc b/extensions/common/permissions/extensions_api_permissions.cc index a0f7fea..f8cd038 100644 --- a/extensions/common/permissions/extensions_api_permissions.cc +++ b/extensions/common/permissions/extensions_api_permissions.cc
@@ -13,7 +13,7 @@ #include "extensions/common/permissions/api_permission.h" #include "extensions/common/permissions/socket_permission.h" #include "extensions/common/permissions/usb_device_permission.h" -#include "grit/extensions_strings.h" +#include "extensions/strings/grit/extensions_strings.h" namespace extensions {
diff --git a/extensions/common/permissions/media_galleries_permission.cc b/extensions/common/permissions/media_galleries_permission.cc index d3b245f..10fb24c 100644 --- a/extensions/common/permissions/media_galleries_permission.cc +++ b/extensions/common/permissions/media_galleries_permission.cc
@@ -12,7 +12,7 @@ #include "base/logging.h" #include "base/strings/utf_string_conversions.h" #include "extensions/common/permissions/permissions_info.h" -#include "grit/extensions_strings.h" +#include "extensions/strings/grit/extensions_strings.h" #include "ui/base/l10n/l10n_util.h" namespace extensions {
diff --git a/extensions/common/permissions/settings_override_permission.cc b/extensions/common/permissions/settings_override_permission.cc index afa14db..df5b073 100644 --- a/extensions/common/permissions/settings_override_permission.cc +++ b/extensions/common/permissions/settings_override_permission.cc
@@ -9,7 +9,7 @@ #include "base/memory/ptr_util.h" #include "base/strings/utf_string_conversions.h" #include "extensions/common/permissions/api_permission_set.h" -#include "grit/extensions_strings.h" +#include "extensions/strings/grit/extensions_strings.h" #include "ui/base/l10n/l10n_util.h" namespace extensions {
diff --git a/extensions/common/permissions/socket_permission.cc b/extensions/common/permissions/socket_permission.cc index cee281b..33c3b29 100644 --- a/extensions/common/permissions/socket_permission.cc +++ b/extensions/common/permissions/socket_permission.cc
@@ -12,7 +12,7 @@ #include "extensions/common/api/sockets/sockets_manifest_permission.h" #include "extensions/common/permissions/permissions_info.h" #include "extensions/common/permissions/set_disjunction_permission.h" -#include "grit/extensions_strings.h" +#include "extensions/strings/grit/extensions_strings.h" #include "ui/base/l10n/l10n_util.h" namespace extensions {
diff --git a/extensions/common/permissions/usb_device_permission.cc b/extensions/common/permissions/usb_device_permission.cc index 4e2f2d5..d6238ca13 100644 --- a/extensions/common/permissions/usb_device_permission.cc +++ b/extensions/common/permissions/usb_device_permission.cc
@@ -22,7 +22,7 @@ #include "extensions/common/features/feature.h" #include "extensions/common/features/feature_provider.h" #include "extensions/common/permissions/permissions_info.h" -#include "grit/extensions_strings.h" +#include "extensions/strings/grit/extensions_strings.h" #include "ui/base/l10n/l10n_util.h" namespace extensions {
diff --git a/extensions/renderer/native_extension_bindings_system_unittest.cc b/extensions/renderer/native_extension_bindings_system_unittest.cc index a7708e6..a192c38 100644 --- a/extensions/renderer/native_extension_bindings_system_unittest.cc +++ b/extensions/renderer/native_extension_bindings_system_unittest.cc
@@ -99,7 +99,7 @@ } void TearDown() override { - for (const auto& context : raw_script_contexts_) + for (auto* context : raw_script_contexts_) script_context_set_->Remove(context); base::RunLoop().RunUntilIdle(); script_context_set_.reset();
diff --git a/extensions/strings/BUILD.gn b/extensions/strings/BUILD.gn index b32b998..23d0c2a2 100644 --- a/extensions/strings/BUILD.gn +++ b/extensions/strings/BUILD.gn
@@ -9,6 +9,7 @@ grit("strings") { source = "extensions_strings.grd" + use_qualified_include = true outputs = [ "grit/extensions_strings.h", "extensions_strings_am.pak",
diff --git a/extensions/test/data/api_test/printer_provider/OWNERS b/extensions/test/data/api_test/printer_provider/OWNERS index 0fa42c6a4..d038a71 100644 --- a/extensions/test/data/api_test/printer_provider/OWNERS +++ b/extensions/test/data/api_test/printer_provider/OWNERS
@@ -1,2 +1,4 @@ tbarzic@chromium.org vitalybuka@chromium.org + +# COMPONENT: Internals>Printing
diff --git a/gin/v8_platform.cc b/gin/v8_platform.cc index 4fe7c7c..276dd77c 100644 --- a/gin/v8_platform.cc +++ b/gin/v8_platform.cc
@@ -204,14 +204,14 @@ void OnTraceLogEnabled() final { base::AutoLock lock(mutex_); - for (auto o : observers_) { + for (auto* o : observers_) { o->OnTraceEnabled(); } } void OnTraceLogDisabled() final { base::AutoLock lock(mutex_); - for (auto o : observers_) { + for (auto* o : observers_) { o->OnTraceDisabled(); } }
diff --git a/gpu/ipc/client/command_buffer_proxy_impl.cc b/gpu/ipc/client/command_buffer_proxy_impl.cc index 033507e..233df39 100644 --- a/gpu/ipc/client/command_buffer_proxy_impl.cc +++ b/gpu/ipc/client/command_buffer_proxy_impl.cc
@@ -335,6 +335,15 @@ update_vsync_parameters_completion_callback_ = callback; } +void CommandBufferProxyImpl::SetNeedsVSync(bool needs_vsync) { + CheckLock(); + base::AutoLock lock(last_state_lock_); + if (last_state_.error != gpu::error::kNoError) + return; + + Send(new GpuCommandBufferMsg_SetNeedsVSync(route_id_, needs_vsync)); +} + gpu::CommandBuffer::State CommandBufferProxyImpl::WaitForTokenInRange( int32_t start, int32_t end) {
diff --git a/gpu/ipc/client/command_buffer_proxy_impl.h b/gpu/ipc/client/command_buffer_proxy_impl.h index 5a7199b4..c35b7009 100644 --- a/gpu/ipc/client/command_buffer_proxy_impl.h +++ b/gpu/ipc/client/command_buffer_proxy_impl.h
@@ -152,6 +152,8 @@ void SetUpdateVSyncParametersCallback( const UpdateVSyncParametersCallback& callback); + void SetNeedsVSync(bool needs_vsync); + int32_t route_id() const { return route_id_; } const scoped_refptr<GpuChannelHost>& channel() const { return channel_; }
diff --git a/gpu/ipc/service/gpu_command_buffer_stub.cc b/gpu/ipc/service/gpu_command_buffer_stub.cc index 1375acb..1cbea32 100644 --- a/gpu/ipc/service/gpu_command_buffer_stub.cc +++ b/gpu/ipc/service/gpu_command_buffer_stub.cc
@@ -600,23 +600,38 @@ // only a single context. See crbug.com/510243 for details. use_virtualized_gl_context_ |= channel_->mailbox_manager()->UsesSync(); - gl::GLSurfaceFormat surface_format = gl::GLSurfaceFormat(); bool offscreen = (surface_handle_ == kNullSurfaceHandle); gl::GLSurface* default_surface = manager->GetDefaultOffscreenSurface(); if (!default_surface) { DLOG(ERROR) << "Failed to create default offscreen surface."; return false; } + // On low-spec Android devices, the default offscreen surface is + // RGB565, but WebGL rendering contexts still ask for RGBA8888 mode. + // That combination works for offscreen rendering, we can still use + // a virtualized context with the RGB565 backing surface since we're + // not drawing to that. Explicitly set that as the desired surface + // format to ensure it's treated as compatible where applicable. + gl::GLSurfaceFormat surface_format = + offscreen ? default_surface->GetFormat() : gl::GLSurfaceFormat(); #if defined(OS_ANDROID) if (init_params.attribs.red_size <= 5 && init_params.attribs.green_size <= 6 && init_params.attribs.blue_size <= 5 && - init_params.attribs.alpha_size == 0) + init_params.attribs.alpha_size == 0) { + // We hit this code path when creating the onscreen render context + // used for compositing on low-end Android devices. + // + // TODO(klausw): explicitly copy rgba sizes? Currently the formats + // supported are only RGB565 and default (RGBA8888). surface_format.SetRGB565(); - // TODO(klausw): explicitly copy rgba sizes? + DVLOG(1) << __FUNCTION__ << ": Choosing RGB565 mode."; + } // We can only use virtualized contexts for onscreen command buffers if their // config is compatible with the offscreen ones - otherwise MakeCurrent fails. + // Example use case is a client requesting an onscreen RGBA8888 buffer for + // fullscreen video on a low-spec device with RGB565 default format. if (!surface_format.IsCompatible(default_surface->GetFormat()) && !offscreen) use_virtualized_gl_context_ = false; #endif
diff --git a/gpu/ipc/service/image_transport_surface_win.cc b/gpu/ipc/service/image_transport_surface_win.cc index 7d484e90..5fcaf7f59 100644 --- a/gpu/ipc/service/image_transport_surface_win.cc +++ b/gpu/ipc/service/image_transport_surface_win.cc
@@ -6,19 +6,32 @@ #include <memory> +#include "base/win/windows_version.h" #include "gpu/ipc/service/child_window_surface_win.h" #include "gpu/ipc/service/direct_composition_surface_win.h" +#include "gpu/ipc/service/gpu_vsync_provider_win.h" #include "gpu/ipc/service/pass_through_image_transport_surface.h" #include "gpu/ipc/service/switches.h" #include "ui/gfx/native_widget_types.h" #include "ui/gl/gl_bindings.h" #include "ui/gl/gl_implementation.h" #include "ui/gl/gl_surface_egl.h" +#include "ui/gl/gl_switches.h" #include "ui/gl/init/gl_factory.h" #include "ui/gl/vsync_provider_win.h" namespace gpu { +namespace { +bool IsGpuVSyncSignalSupported() { + // TODO(stanisc): http://crbug.com/467617 Limit to Windows 8+ for now because + // of locking issue caused by waiting for VSync on Win7. + return base::win::GetVersion() >= base::win::VERSION_WIN8 && + base::FeatureList::IsEnabled(features::kD3DVsync); +} + +} // namespace + // static scoped_refptr<gl::GLSurface> ImageTransportSurface::CreateNativeSurface( base::WeakPtr<ImageTransportSurfaceDelegate> delegate, @@ -29,8 +42,13 @@ scoped_refptr<gl::GLSurface> surface; if (gl::GetGLImplementation() == gl::kGLImplementationEGLGLES2 && gl::GLSurfaceEGL::IsDirectCompositionSupported()) { - std::unique_ptr<gfx::VSyncProvider> vsync_provider( - new gl::VSyncProviderWin(surface_handle)); + std::unique_ptr<gfx::VSyncProvider> vsync_provider; + + if (IsGpuVSyncSignalSupported()) + vsync_provider.reset(new GpuVSyncProviderWin(delegate, surface_handle)); + else + vsync_provider.reset(new gl::VSyncProviderWin(surface_handle)); + if (base::FeatureList::IsEnabled(switches::kDirectCompositionOverlays)) { scoped_refptr<DirectCompositionSurfaceWin> egl_surface = make_scoped_refptr(
diff --git a/headless/OWNERS b/headless/OWNERS index d11af97..bfb2bee 100644 --- a/headless/OWNERS +++ b/headless/OWNERS
@@ -1,4 +1,5 @@ skyostil@chromium.org alexclarke@chromium.org altimin@chromium.org -eseckler@chromium.org + +# TEAM: headless-dev@chromium.org
diff --git a/headless/lib/browser/headless_content_browser_client.cc b/headless/lib/browser/headless_content_browser_client.cc index a6db422..e993fc1 100644 --- a/headless/lib/browser/headless_content_browser_client.cc +++ b/headless/lib/browser/headless_content_browser_client.cc
@@ -119,7 +119,7 @@ void HeadlessContentBrowserClient::OverrideWebkitPrefs( content::RenderViewHost* render_view_host, content::WebPreferences* prefs) { - auto browser_context = HeadlessBrowserContextImpl::From( + auto* browser_context = HeadlessBrowserContextImpl::From( render_view_host->GetProcess()->GetBrowserContext()); const base::Callback<void(headless::WebPreferences*)>& callback = browser_context->options()->override_web_preferences_callback();
diff --git a/infra/config/cq.cfg b/infra/config/cq.cfg index f53bd79..7cfb95a 100644 --- a/infra/config/cq.cfg +++ b/infra/config/cq.cfg
@@ -4,9 +4,11 @@ version: 1 cq_name: "chromium" cq_status_url: "https://chromium-cq-status.appspot.com" +git_repo_url: "https://chromium.googlesource.com/chromium/src" commit_burst_delay: 60 max_commit_burst: 2 +gerrit {} rietveld { url: "https://codereview.chromium.org" } @@ -17,6 +19,11 @@ dry_run_access_list: "project-chromium-tryjob-access" } + gerrit_cq_ability { + committer_list: "project-chromium-committers" + dry_run_access_list: "project-chromium-tryjob-access" + } + tree_status { tree_status_url: "https://chromium-status.appspot.com" }
diff --git a/ios/chrome/app/strings/ios_strings.grd b/ios/chrome/app/strings/ios_strings.grd index 88bdcef..aef2da7 100644 --- a/ios/chrome/app/strings/ios_strings.grd +++ b/ios/chrome/app/strings/ios_strings.grd
@@ -951,24 +951,12 @@ <message name="IDS_IOS_PAYMENT_REQUEST_PAYMENT_ITEMS_TOTAL_FORMAT" desc="The format specifier of the Total label in the payment items in a payment request [iOS only]."> <ph name="FORMATTED_CURRENCY_CODE">$1<ex>USD</ex></ph> <ph name="FORMATTED_TOTAL_AMOUNT">$2<ex>$ 12.34</ex></ph> </message> - <message name="IDS_IOS_PAYMENT_REQUEST_SHIPPING_ADDRESS_HEADER" desc="Label of the header of the section which displays the currently selected shipping address and the available shipping options for satisfying a payment request [iOS only]."> - Shipping - </message> <message name="IDS_IOS_PAYMENT_REQUEST_ADD_SHIPPING_ADDRESS_BUTTON" desc="Label of the button to add a shipping address [iOS only]."> Add </message> - <message name="IDS_IOS_PAYMENT_REQUEST_SHIPPING_ADDRESS_SELECTION_TITLE" desc="Title of the view that allows the user to select the shipping address for satisfying a payment request [iOS only]."> - Shipping Address - </message> - <message name="IDS_IOS_PAYMENT_REQUEST_SHIPPING_ADDRESS_SELECTION_MESSAGE" desc="Message instructing the user to select a shipping address for satisfying a payment request [iOS only]."> - Select a shipping address to check shipping methods and requirements. - </message> <message name="IDS_IOS_PAYMENT_REQUEST_CHECKING_LABEL" desc="Label showing that the new shipping address or the shipping option is being verified. [iOS only]"> Checking </message> - <message name="IDS_IOS_PAYMENT_REQUEST_SHIPPING_OPTION_SELECTION_TITLE" desc="Title of the view that allows the user to select the shipping option for satisfying a payment request [iOS only]."> - Shipping Method - </message> <message name="IDS_IOS_PAYMENT_REQUEST_SHIPPING_ADDRESS_SELECTION_ADD_BUTTON" desc="Label of the button to add a new shipping address [iOS only]."> Add Address... </message>
diff --git a/ios/chrome/browser/payments/BUILD.gn b/ios/chrome/browser/payments/BUILD.gn index 9109cc2..9fd2b10 100644 --- a/ios/chrome/browser/payments/BUILD.gn +++ b/ios/chrome/browser/payments/BUILD.gn
@@ -93,6 +93,7 @@ "//components/autofill/core/browser", "//components/autofill/core/browser:test_support", "//components/payments:payment_validation", + "//components/strings", "//ios/chrome/app/strings", "//ios/chrome/browser", "//ios/chrome/browser/payments/cells",
diff --git a/ios/chrome/browser/payments/payment_request.h b/ios/chrome/browser/payments/payment_request.h index 966fb2a..5b4cea2 100644 --- a/ios/chrome/browser/payments/payment_request.h +++ b/ios/chrome/browser/payments/payment_request.h
@@ -39,6 +39,11 @@ return web_payment_request_->details; } + // Returns the payment options from |web_payment_request_|. + const web::PaymentOptions& payment_options() const { + return web_payment_request_->options; + } + // Updates the payment details of the |web_payment_request_|. It also updates // the cached references to the shipping options in |web_payment_request_| as // well as the reference to the selected shipping option.
diff --git a/ios/chrome/browser/payments/payment_request_coordinator.mm b/ios/chrome/browser/payments/payment_request_coordinator.mm index 29e293a..6205c4b 100644 --- a/ios/chrome/browser/payments/payment_request_coordinator.mm +++ b/ios/chrome/browser/payments/payment_request_coordinator.mm
@@ -235,7 +235,7 @@ (_paymentRequest->payment_details().total != paymentDetails.total); _paymentRequest->set_payment_details(paymentDetails); - if (!paymentDetails.error.empty()) { + if (_paymentRequest->shipping_options().empty()) { // Display error in the shipping address/option selection view. if (_shippingAddressSelectionCoordinator) { _paymentRequest->set_selected_shipping_profile(nil);
diff --git a/ios/chrome/browser/payments/payment_request_util.h b/ios/chrome/browser/payments/payment_request_util.h index 59ae03f9..008fb50 100644 --- a/ios/chrome/browser/payments/payment_request_util.h +++ b/ios/chrome/browser/payments/payment_request_util.h
@@ -13,6 +13,8 @@ class AutofillProfile; } // namespace autofill +class PaymentRequest; + namespace payment_request_util { // Helper function to get the name label from an autofill profile. @@ -30,6 +32,31 @@ web::PaymentAddress PaymentAddressFromAutofillProfile( autofill::AutofillProfile* profile); +// Returns the title for the shipping section of the payment summary view given +// the shipping type specified in |payment_request|. +NSString* GetShippingSectionTitle(PaymentRequest* payment_request); + +// Returns the title for the shipping address selection view given the shipping +// type specified in |payment_request|. +NSString* GetShippingAddressSelectorTitle(PaymentRequest* payment_request); + +// Returns the informational message to be displayed in the shipping address +// selection view given the shipping type specified in |payment_request|. +NSString* GetShippingAddressSelectorInfoMessage(PaymentRequest* paymentRequest); + +// Returns the error message to be displayed in the shipping address selection +// view given the shipping type specified in |payment_request|. +NSString* GetShippingAddressSelectorErrorMessage( + PaymentRequest* paymentRequest); + +// Returns the title for the shipping option selection view given the shipping +// type specified in |payment_request|. +NSString* GetShippingOptionSelectorTitle(PaymentRequest* payment_request); + +// Returns the error message to be displayed in the shipping option selection +// view given the shipping type specified in |payment_request|. +NSString* GetShippingOptionSelectorErrorMessage(PaymentRequest* paymentRequest); + } // namespace payment_request_util #endif // IOS_CHROME_BROWSER_PAYMENTS_PAYMENT_REQUEST_UTIL_H_
diff --git a/ios/chrome/browser/payments/payment_request_util.mm b/ios/chrome/browser/payments/payment_request_util.mm index cdab2816..5bdf315 100644 --- a/ios/chrome/browser/payments/payment_request_util.mm +++ b/ios/chrome/browser/payments/payment_request_util.mm
@@ -8,7 +8,10 @@ #include "base/strings/utf_string_conversions.h" #include "components/autofill/core/browser/autofill_profile.h" #include "components/autofill/core/browser/field_types.h" +#include "components/strings/grit/components_strings.h" #include "ios/chrome/browser/application_context.h" +#include "ios/chrome/browser/payments/payment_request.h" +#include "ui/base/l10n/l10n_util.h" namespace payment_request_util { @@ -68,4 +71,100 @@ return address; } +NSString* GetShippingSectionTitle(PaymentRequest* payment_request) { + switch (payment_request->payment_options().shipping_type) { + case web::PaymentShippingType::SHIPPING: + return l10n_util::GetNSString(IDS_PAYMENTS_SHIPPING_SUMMARY_LABEL); + case web::PaymentShippingType::DELIVERY: + return l10n_util::GetNSString(IDS_PAYMENTS_DELIVERY_SUMMARY_LABEL); + case web::PaymentShippingType::PICKUP: + return l10n_util::GetNSString(IDS_PAYMENTS_PICKUP_SUMMARY_LABEL); + default: + NOTREACHED(); + return @""; + } +} + +NSString* GetShippingAddressSelectorTitle(PaymentRequest* payment_request) { + switch (payment_request->payment_options().shipping_type) { + case web::PaymentShippingType::SHIPPING: + return l10n_util::GetNSString(IDS_PAYMENTS_SHIPPING_ADDRESS_LABEL); + case web::PaymentShippingType::DELIVERY: + return l10n_util::GetNSString(IDS_PAYMENTS_DELIVERY_ADDRESS_LABEL); + case web::PaymentShippingType::PICKUP: + return l10n_util::GetNSString(IDS_PAYMENTS_PICKUP_ADDRESS_LABEL); + default: + NOTREACHED(); + return @""; + } +} + +NSString* GetShippingAddressSelectorInfoMessage( + PaymentRequest* payment_request) { + switch (payment_request->payment_options().shipping_type) { + case web::PaymentShippingType::SHIPPING: + return l10n_util::GetNSString( + IDS_PAYMENTS_SELECT_SHIPPING_ADDRESS_FOR_SHIPPING_METHODS); + case web::PaymentShippingType::DELIVERY: + return l10n_util::GetNSString( + IDS_PAYMENTS_SELECT_DELIVERY_ADDRESS_FOR_DELIVERY_METHODS); + case web::PaymentShippingType::PICKUP: + return l10n_util::GetNSString( + IDS_PAYMENTS_SELECT_PICKUP_ADDRESS_FOR_PICKUP_METHODS); + default: + NOTREACHED(); + return @""; + } +} + +NSString* GetShippingAddressSelectorErrorMessage( + PaymentRequest* payment_request) { + if (!payment_request->payment_details().error.empty()) + return base::SysUTF16ToNSString(payment_request->payment_details().error); + + switch (payment_request->payment_options().shipping_type) { + case web::PaymentShippingType::SHIPPING: + return l10n_util::GetNSString(IDS_PAYMENTS_UNSUPPORTED_SHIPPING_ADDRESS); + case web::PaymentShippingType::DELIVERY: + return l10n_util::GetNSString(IDS_PAYMENTS_UNSUPPORTED_DELIVERY_ADDRESS); + case web::PaymentShippingType::PICKUP: + return l10n_util::GetNSString(IDS_PAYMENTS_UNSUPPORTED_PICKUP_ADDRESS); + default: + NOTREACHED(); + return @""; + } +} + +NSString* GetShippingOptionSelectorTitle(PaymentRequest* payment_request) { + switch (payment_request->payment_options().shipping_type) { + case web::PaymentShippingType::SHIPPING: + return l10n_util::GetNSString(IDS_PAYMENTS_SHIPPING_OPTION_LABEL); + case web::PaymentShippingType::DELIVERY: + return l10n_util::GetNSString(IDS_PAYMENTS_DELIVERY_OPTION_LABEL); + case web::PaymentShippingType::PICKUP: + return l10n_util::GetNSString(IDS_PAYMENTS_PICKUP_OPTION_LABEL); + default: + NOTREACHED(); + return @""; + } +} + +NSString* GetShippingOptionSelectorErrorMessage( + PaymentRequest* payment_request) { + if (!payment_request->payment_details().error.empty()) + return base::SysUTF16ToNSString(payment_request->payment_details().error); + + switch (payment_request->payment_options().shipping_type) { + case web::PaymentShippingType::SHIPPING: + return l10n_util::GetNSString(IDS_PAYMENTS_UNSUPPORTED_SHIPPING_OPTION); + case web::PaymentShippingType::DELIVERY: + return l10n_util::GetNSString(IDS_PAYMENTS_UNSUPPORTED_DELIVERY_OPTION); + case web::PaymentShippingType::PICKUP: + return l10n_util::GetNSString(IDS_PAYMENTS_UNSUPPORTED_PICKUP_OPTION); + default: + NOTREACHED(); + return @""; + } +} + } // namespace payment_request_util
diff --git a/ios/chrome/browser/payments/payment_request_view_controller.mm b/ios/chrome/browser/payments/payment_request_view_controller.mm index 3daa2ca..8d9f78a 100644 --- a/ios/chrome/browser/payments/payment_request_view_controller.mm +++ b/ios/chrome/browser/payments/payment_request_view_controller.mm
@@ -223,7 +223,7 @@ CollectionViewTextItem* shippingTitle = [[[CollectionViewTextItem alloc] initWithType:ItemTypeShippingTitle] autorelease]; shippingTitle.text = - l10n_util::GetNSString(IDS_IOS_PAYMENT_REQUEST_SHIPPING_ADDRESS_HEADER); + payment_request_util::GetShippingSectionTitle(_paymentRequest); [model setHeader:shippingTitle forSectionWithIdentifier:SectionIdentifierShipping]; @@ -242,8 +242,8 @@ [[[CollectionViewDetailItem alloc] initWithType:ItemTypeAddShippingAddress] autorelease]; shippingAddressItem = addAddressItem; - addAddressItem.text = l10n_util::GetNSString( - IDS_IOS_PAYMENT_REQUEST_SHIPPING_ADDRESS_SELECTION_TITLE); + addAddressItem.text = + payment_request_util::GetShippingAddressSelectorTitle(_paymentRequest); addAddressItem.detailText = [l10n_util::GetNSString( IDS_IOS_PAYMENT_REQUEST_ADD_SHIPPING_ADDRESS_BUTTON) uppercaseStringWithLocale:[NSLocale currentLocale]]; @@ -266,8 +266,8 @@ [[[CollectionViewDetailItem alloc] initWithType:ItemTypeSelectShippingOption] autorelease]; shippingOptionItem = selectShippingOptionItem; - selectShippingOptionItem.text = l10n_util::GetNSString( - IDS_IOS_PAYMENT_REQUEST_SHIPPING_OPTION_SELECTION_TITLE); + selectShippingOptionItem.text = + payment_request_util::GetShippingOptionSelectorTitle(_paymentRequest); selectShippingOptionItem.accessoryType = MDCCollectionViewCellAccessoryDisclosureIndicator; }
diff --git a/ios/chrome/browser/payments/resources/payment_request_manager.js b/ios/chrome/browser/payments/resources/payment_request_manager.js index f5a136bb..d2a779c 100644 --- a/ios/chrome/browser/payments/resources/payment_request_manager.js +++ b/ios/chrome/browser/payments/resources/payment_request_manager.js
@@ -417,22 +417,58 @@ // TODO(crbug.com/602666): Perform other validation per spec. + // TODO(crbug.com/602666): Process payment methods then set parsedMethodData + // instead of methodData on this instance. + // /** + // * @type {!Object<!Array<string>, ?string>} + // * @private + // */ + // this.parsedMethodData = ...; + /** * @type {!Array<!window.PaymentMethodData>} + * @private */ this.methodData = methodData; /** * @type {!window.PaymentDetails} + * @private */ this.details = details; /** * @type {?window.PaymentOptions} + * @private */ this.options = opt_options || null; /** + * The state of this request, used to govern its lifecycle. + * TODO(crbug.com/602666): Implement state transitions per spec. + * @type {string} + * @private + */ + this.state = 'created'; + + /** + * True if there is a pending updateWith call to update the payment request + * and false otherwise. + * TODO(crbug.com/602666): Implement changes in the value of this property per + * spec. + * @type {boolean} + * @private + */ + this.updating = false; + + /** + * A provided or generated ID for the this Payment Request instance. + * TODO(crbug.com/602666): Generate an ID if one is not provided. + * @type {?string} + */ + this.paymentRequestID = null; + + /** * Shipping address selected by the user. * @type {?window.PaymentAddress} */ @@ -445,12 +481,19 @@ this.shippingOption = null; /** - * The state of this request, used to govern its lifecycle. - * TODO(crbug.com/602666): Implement state transitions per spec. - * @type {string} - * @private + * Set to the value of shippingType property of |opt_options| if it is a valid + * PaymentShippingType. Otherwise set to PaymentShippingType.SHIPPING. + * @type {?PaymentShippingType} */ - this.state = 'created'; + this.shippingType = null; + + if (opt_options && opt_options.requestShipping) { + if (opt_options.shippingType != PaymentShippingType.SHIPPING && + opt_options.shippingType != PaymentShippingType.DELIVERY && + opt_options.shippingType != PaymentShippingType.PICKUP) { + this.shippingType = PaymentShippingType.SHIPPING; + } + } }; window.PaymentRequest.prototype = { @@ -518,10 +561,24 @@ window.PaymentDetailsModifier; /** + * Contains the possible values for affecting the payment request user interface + * for gathering the shipping address if window.PaymentOptions.requestShipping + * is set to true. + * @enum {string} + */ +var PaymentShippingType = { + SHIPPING: 'shipping', + DELIVERY: 'delivery', + PICKUP: 'pickup' +}; + +/** * @typedef {{ + * requestPayerName: (boolean|undefined), * requestPayerEmail: (boolean|undefined), * requestPayerPhone: (boolean|undefined), - * requestShipping: (boolean|undefined) + * requestShipping: (boolean|undefined), + * shippingType: (!PaymentShippingType|undefined) * }} */ window.PaymentOptions;
diff --git a/ios/chrome/browser/payments/shipping_address_selection_coordinator.mm b/ios/chrome/browser/payments/shipping_address_selection_coordinator.mm index b7f2cf5..e3dfcb5 100644 --- a/ios/chrome/browser/payments/shipping_address_selection_coordinator.mm +++ b/ios/chrome/browser/payments/shipping_address_selection_coordinator.mm
@@ -9,6 +9,7 @@ #include "base/strings/sys_string_conversions.h" #include "components/autofill/core/browser/autofill_profile.h" #include "ios/chrome/browser/payments/payment_request.h" +#import "ios/chrome/browser/payments/payment_request_util.h" @interface ShippingAddressSelectionCoordinator () { base::WeakNSProtocol<id<ShippingAddressSelectionCoordinatorDelegate>> @@ -60,9 +61,10 @@ _viewController.get().view.userInteractionEnabled = YES; [_viewController setIsLoading:NO]; - [_viewController - setErrorMessage:base::SysUTF16ToNSString( - _paymentRequest->payment_details().error)]; + NSString* errorMessage = + payment_request_util::GetShippingAddressSelectorErrorMessage( + _paymentRequest); + [_viewController setErrorMessage:errorMessage]; [_viewController loadModel]; [[_viewController collectionView] reloadData]; }
diff --git a/ios/chrome/browser/payments/shipping_address_selection_view_controller.mm b/ios/chrome/browser/payments/shipping_address_selection_view_controller.mm index 9e411e72..19a7041 100644 --- a/ios/chrome/browser/payments/shipping_address_selection_view_controller.mm +++ b/ios/chrome/browser/payments/shipping_address_selection_view_controller.mm
@@ -6,7 +6,6 @@ #import "base/ios/weak_nsobject.h" #include "base/mac/foundation_util.h" -#include "base/mac/scoped_nsobject.h" #include "base/strings/sys_string_conversions.h" #include "components/autofill/core/browser/autofill_profile.h" #include "components/strings/grit/components_strings.h" @@ -76,8 +75,8 @@ - (instancetype)initWithPaymentRequest:(PaymentRequest*)paymentRequest { DCHECK(paymentRequest); if ((self = [super initWithStyle:CollectionViewControllerStyleAppBar])) { - self.title = l10n_util::GetNSString( - IDS_IOS_PAYMENT_REQUEST_SHIPPING_ADDRESS_SELECTION_TITLE); + self.title = + payment_request_util::GetShippingAddressSelectorTitle(paymentRequest); UIBarButtonItem* returnButton = [ChromeIcon templateBarButtonItemWithImage:[ChromeIcon backIcon] @@ -129,8 +128,9 @@ messageItem.text = _errorMessage; messageItem.image = NativeImage(IDR_IOS_PAYMENTS_WARNING); } else { - messageItem.text = l10n_util::GetNSString( - IDS_IOS_PAYMENT_REQUEST_SHIPPING_ADDRESS_SELECTION_MESSAGE); + messageItem.text = + payment_request_util::GetShippingAddressSelectorInfoMessage( + _paymentRequest); } [model addItem:messageItem toSectionWithIdentifier:SectionIdentifierShippingAddress];
diff --git a/ios/chrome/browser/payments/shipping_address_selection_view_controller_unittest.mm b/ios/chrome/browser/payments/shipping_address_selection_view_controller_unittest.mm index 80c31b1..50b0705 100644 --- a/ios/chrome/browser/payments/shipping_address_selection_view_controller_unittest.mm +++ b/ios/chrome/browser/payments/shipping_address_selection_view_controller_unittest.mm
@@ -8,13 +8,13 @@ #include "base/memory/ptr_util.h" #include "components/autofill/core/browser/autofill_profile.h" #include "components/autofill/core/browser/test_personal_data_manager.h" +#include "components/strings/grit/components_strings.h" #import "ios/chrome/browser/payments/cells/payments_text_item.h" #import "ios/chrome/browser/payments/cells/shipping_address_item.h" #include "ios/chrome/browser/payments/payment_request.h" #include "ios/chrome/browser/payments/payment_request_test_util.h" #import "ios/chrome/browser/ui/autofill/cells/status_item.h" #import "ios/chrome/browser/ui/collection_view/collection_view_controller_test.h" -#include "ios/chrome/grit/ios_strings.h" #include "ios/web/public/payments/payment_request.h" #include "testing/gtest/include/gtest/gtest.h" @@ -59,7 +59,7 @@ TEST_F(ShippingAddressSelectionViewControllerTest, TestModel) { CreateController(); CheckController(); - CheckTitleWithId(IDS_IOS_PAYMENT_REQUEST_SHIPPING_ADDRESS_SELECTION_TITLE); + CheckTitleWithId(IDS_PAYMENTS_SHIPPING_ADDRESS_LABEL); [GetShippingAddressSelectionViewController() loadModel];
diff --git a/ios/chrome/browser/payments/shipping_option_selection_coordinator.mm b/ios/chrome/browser/payments/shipping_option_selection_coordinator.mm index 5645a2a3..c30c6bed 100644 --- a/ios/chrome/browser/payments/shipping_option_selection_coordinator.mm +++ b/ios/chrome/browser/payments/shipping_option_selection_coordinator.mm
@@ -7,6 +7,7 @@ #import "base/ios/weak_nsobject.h" #include "base/mac/scoped_nsobject.h" #include "base/strings/sys_string_conversions.h" +#import "ios/chrome/browser/payments/payment_request_util.h" @interface ShippingOptionSelectionCoordinator () { base::WeakNSProtocol<id<ShippingOptionSelectionCoordinatorDelegate>> @@ -58,9 +59,10 @@ _viewController.get().view.userInteractionEnabled = YES; [_viewController setIsLoading:NO]; - [_viewController - setErrorMessage:base::SysUTF16ToNSString( - _paymentRequest->payment_details().error)]; + NSString* errorMessage = + payment_request_util::GetShippingOptionSelectorErrorMessage( + _paymentRequest); + [_viewController setErrorMessage:errorMessage]; [_viewController loadModel]; [[_viewController collectionView] reloadData]; }
diff --git a/ios/chrome/browser/payments/shipping_option_selection_view_controller.mm b/ios/chrome/browser/payments/shipping_option_selection_view_controller.mm index e0fca858..1620902 100644 --- a/ios/chrome/browser/payments/shipping_option_selection_view_controller.mm +++ b/ios/chrome/browser/payments/shipping_option_selection_view_controller.mm
@@ -12,6 +12,7 @@ #include "components/strings/grit/components_strings.h" #import "ios/chrome/browser/payments/cells/payments_text_item.h" #include "ios/chrome/browser/payments/payment_request.h" +#import "ios/chrome/browser/payments/payment_request_util.h" #import "ios/chrome/browser/ui/autofill/cells/status_item.h" #import "ios/chrome/browser/ui/collection_view/cells/MDCCollectionViewCell+Chrome.h" #import "ios/chrome/browser/ui/collection_view/cells/collection_view_item.h" @@ -22,7 +23,6 @@ #include "ios/chrome/browser/ui/uikit_ui_util.h" #include "ios/chrome/grit/ios_strings.h" #include "ios/chrome/grit/ios_theme_resources.h" -#import "ios/third_party/material_components_ios/src/components/Palettes/src/MaterialPalettes.h" #import "ios/third_party/material_components_ios/src/components/Typography/src/MaterialTypography.h" #include "ui/base/l10n/l10n_util.h" @@ -71,8 +71,8 @@ - (instancetype)initWithPaymentRequest:(PaymentRequest*)paymentRequest { DCHECK(paymentRequest); if ((self = [super initWithStyle:CollectionViewControllerStyleAppBar])) { - self.title = l10n_util::GetNSString( - IDS_IOS_PAYMENT_REQUEST_SHIPPING_OPTION_SELECTION_TITLE); + self.title = + payment_request_util::GetShippingOptionSelectorTitle(paymentRequest); UIBarButtonItem* returnButton = [ChromeIcon templateBarButtonItemWithImage:[ChromeIcon backIcon]
diff --git a/ios/chrome/browser/payments/shipping_option_selection_view_controller_unittest.mm b/ios/chrome/browser/payments/shipping_option_selection_view_controller_unittest.mm index a3f3b21..e9470272 100644 --- a/ios/chrome/browser/payments/shipping_option_selection_view_controller_unittest.mm +++ b/ios/chrome/browser/payments/shipping_option_selection_view_controller_unittest.mm
@@ -8,13 +8,13 @@ #include "base/memory/ptr_util.h" #include "base/strings/utf_string_conversions.h" #include "components/autofill/core/browser/test_personal_data_manager.h" +#include "components/strings/grit/components_strings.h" #import "ios/chrome/browser/payments/cells/payments_text_item.h" #include "ios/chrome/browser/payments/payment_request.h" #import "ios/chrome/browser/payments/payment_request_test_util.h" #import "ios/chrome/browser/ui/autofill/cells/status_item.h" #import "ios/chrome/browser/ui/collection_view/cells/collection_view_text_item.h" #import "ios/chrome/browser/ui/collection_view/collection_view_controller_test.h" -#include "ios/chrome/grit/ios_strings.h" #include "ios/web/public/payments/payment_request.h" #include "testing/gtest/include/gtest/gtest.h" @@ -51,7 +51,7 @@ TEST_F(ShippingOptionSelectionViewControllerTest, TestModel) { CreateController(); CheckController(); - CheckTitleWithId(IDS_IOS_PAYMENT_REQUEST_SHIPPING_OPTION_SELECTION_TITLE); + CheckTitleWithId(IDS_PAYMENTS_SHIPPING_OPTION_LABEL); [GetShippingOptionSelectionViewController() loadModel];
diff --git a/ios/chrome/browser/tabs/tab.mm b/ios/chrome/browser/tabs/tab.mm index a6eda18..484c358 100644 --- a/ios/chrome/browser/tabs/tab.mm +++ b/ios/chrome/browser/tabs/tab.mm
@@ -1494,20 +1494,16 @@ base::WeakNSObject<Tab> weakSelf(self); // TODO(crbug.com/692117): Remove |window_name| from constructor. web::BlockedPopupInfo poupInfo(popupURL, referrer, nil /* window_name */, ^{ - base::scoped_nsobject<Tab> strongSelf([weakSelf retain]); - if (!strongSelf) { - return; + web::WebState* webState = [weakSelf webState]; + if (webState) { + web::WebState::OpenURLParams params( + localPopupURL, referrer, WindowOpenDisposition::NEW_POPUP, + ui::PAGE_TRANSITION_LINK, true /* is_renderer_initiated */); + params.url = localPopupURL; + params.referrer = referrer; + params.transition = ui::PAGE_TRANSITION_LINK; + webState->OpenURL(params); } - [strongSelf updateSnapshotWithOverlay:YES visibleFrameOnly:YES]; - [strongSelf.get()->parentTabModel_ - insertOrUpdateTabWithURL:localPopupURL - referrer:referrer - transition:ui::PAGE_TRANSITION_LINK - windowName:nil - opener:self - openedByDOM:YES - atIndex:TabModelConstants::kTabPositionAutomatically - inBackground:NO]; }); BlockedPopupTabHelper::FromWebState(self.webState)->HandlePopup(poupInfo); }
diff --git a/ios/chrome/browser/ui/DEPS b/ios/chrome/browser/ui/DEPS index fa03c9a..0a1586ac 100644 --- a/ios/chrome/browser/ui/DEPS +++ b/ios/chrome/browser/ui/DEPS
@@ -8,7 +8,6 @@ # TODO(crbug.com/620489): Remove these exceptions. "^browser_view_controller\.mm$": [ "+ios/web/navigation/crw_session_controller.h", - "+ios/web/navigation/crw_session_entry.h", "+ios/web/navigation/navigation_manager_impl.h", "+ios/web/web_state/ui/crw_web_controller.h", ],
diff --git a/ios/chrome/browser/ui/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view_controller.mm index 102e29ed..89b97b29 100644 --- a/ios/chrome/browser/ui/browser_view_controller.mm +++ b/ios/chrome/browser/ui/browser_view_controller.mm
@@ -171,7 +171,6 @@ #include "ios/public/provider/chrome/browser/voice/voice_search_controller_delegate.h" #include "ios/public/provider/chrome/browser/voice/voice_search_provider.h" #import "ios/web/navigation/crw_session_controller.h" -#import "ios/web/navigation/crw_session_entry.h" #include "ios/web/navigation/navigation_manager_impl.h" #include "ios/web/public/active_state_manager.h" #include "ios/web/public/navigation_item.h" @@ -1917,11 +1916,10 @@ // Hide the toolbar if displaying phone NTP. if (!IsIPadIdiom()) { - CRWSessionEntry* entry = - [[tab navigationManager]->GetSessionController() currentEntry]; + web::NavigationItem* item = [tab navigationManager]->GetVisibleItem(); BOOL hideToolbar = NO; - if (entry) { - GURL url = [entry navigationItem]->GetURL(); + if (item) { + GURL url = item->GetURL(); BOOL isNTP = url.GetOrigin() == GURL(kChromeUINewTabURL); hideToolbar = isNTP && !_isOffTheRecord && ![_toolbarController isOmniboxFirstResponder] && @@ -2376,6 +2374,18 @@ webState->GetNavigationManager()->LoadURLWithParams(loadParams); return webState; } + case WindowOpenDisposition::NEW_POPUP: { + Tab* tab = [[self tabModel] + insertOrUpdateTabWithURL:params.url + referrer:params.referrer + transition:params.transition + windowName:nil + opener:LegacyTabHelper::GetTabForWebState(webState) + openedByDOM:YES + atIndex:TabModelConstants::kTabPositionAutomatically + inBackground:NO]; + return tab.webState; + } default: NOTIMPLEMENTED(); return nullptr; @@ -3361,7 +3371,7 @@ DCHECK([tab navigationManager]); CRWSessionController* sc = [tab navigationManager]->GetSessionController(); [_toolbarController showTabHistoryPopupInView:[self view] - withSessionEntries:[sc backwardEntries] + withItems:[sc backwardItems] forBackHistory:YES]; } @@ -3377,14 +3387,14 @@ DCHECK([tab navigationManager]); CRWSessionController* sc = [tab navigationManager]->GetSessionController(); [_toolbarController showTabHistoryPopupInView:[self view] - withSessionEntries:[sc forwardEntries] + withItems:[sc forwardItems] forBackHistory:NO]; } - (void)navigateToSelectedEntry:(id)sender { DCHECK([sender isKindOfClass:[TabHistoryCell class]]); TabHistoryCell* selectedCell = (TabHistoryCell*)sender; - [[_model currentTab] goToItem:selectedCell.entry.navigationItem]; + [[_model currentTab] goToItem:selectedCell.item]; [_toolbarController dismissTabHistoryPopup]; } @@ -4805,13 +4815,6 @@ return [_model currentTab].useDesktopUserAgent; } -- (CRWSessionEntry*)currentSessionEntry { - Tab* tab = [_model currentTab]; - if (![tab navigationManager]) - return nil; - return [[tab navigationManager]->GetSessionController() currentEntry]; -} - #pragma mark - BookmarkBridgeMethods // If an added or removed bookmark is the same as the current url, update the
diff --git a/ios/chrome/browser/ui/history/BUILD.gn b/ios/chrome/browser/ui/history/BUILD.gn index 8926439..74da394 100644 --- a/ios/chrome/browser/ui/history/BUILD.gn +++ b/ios/chrome/browser/ui/history/BUILD.gn
@@ -210,6 +210,7 @@ "//components/browsing_data/core", "//components/prefs", "//components/strings", + "//components/url_formatter:url_formatter", "//ios/chrome/app/strings", "//ios/chrome/browser", "//ios/chrome/browser/browser_state",
diff --git a/ios/chrome/browser/ui/history/DEPS b/ios/chrome/browser/ui/history/DEPS deleted file mode 100644 index cb80df7..0000000 --- a/ios/chrome/browser/ui/history/DEPS +++ /dev/null
@@ -1,15 +0,0 @@ -specific_include_rules = { - # TODO(crbug.com/620907): Remove these exceptions. - "^tab_history_cell\.mm$": [ - "+ios/web/navigation/crw_session_entry.h", - ], - "tab_history_popup_controller.mm": [ - "+ios/web/navigation/crw_session_entry.h", - ], - "tab_history_popup_controller_unittest.mm": [ - "+ios/web/navigation/crw_session_entry.h", - ], - "tab_history_view_controller.mm": [ - "+ios/web/navigation/crw_session_entry.h", - ], -}
diff --git a/ios/chrome/browser/ui/history/tab_history_cell.h b/ios/chrome/browser/ui/history/tab_history_cell.h index 745a9d5d..590e037f 100644 --- a/ios/chrome/browser/ui/history/tab_history_cell.h +++ b/ios/chrome/browser/ui/history/tab_history_cell.h
@@ -7,18 +7,20 @@ #import <UIKit/UIKit.h> -@class CRWSessionEntry; +namespace web { +class NavigationItem; +} // Table cell used in TabHistoryViewController. @interface TabHistoryCell : UICollectionViewCell -@property(strong, nonatomic) CRWSessionEntry* entry; -@property(weak, nonatomic, readonly) UILabel* titleLabel; +@property(assign, nonatomic) const web::NavigationItem* item; +@property(strong, nonatomic, readonly) UILabel* titleLabel; @end // Header for a section of TabHistoryCells. @interface TabHistorySectionHeader : UICollectionReusableView -@property(weak, nonatomic, readonly) UIImageView* iconView; -@property(weak, nonatomic, readonly) UIView* lineView; +@property(strong, nonatomic, readonly) UIImageView* iconView; +@property(strong, nonatomic, readonly) UIView* lineView; @end // Footer for a section of TabHistoryCells.
diff --git a/ios/chrome/browser/ui/history/tab_history_cell.mm b/ios/chrome/browser/ui/history/tab_history_cell.mm index 2d34024..b2d708a 100644 --- a/ios/chrome/browser/ui/history/tab_history_cell.mm +++ b/ios/chrome/browser/ui/history/tab_history_cell.mm
@@ -8,7 +8,6 @@ #include "ios/chrome/browser/ui/ui_util.h" #import "ios/chrome/browser/ui/uikit_ui_util.h" #import "ios/third_party/material_roboto_font_loader_ios/src/src/MaterialRobotoFontLoader.h" -#import "ios/web/navigation/crw_session_entry.h" #include "ios/web/public/navigation_item.h" #if !defined(__has_feature) || !__has_feature(objc_arc) @@ -42,10 +41,10 @@ } } -@implementation TabHistoryCell { - CRWSessionEntry* _entry; - UILabel* _titleLabel; -} +@implementation TabHistoryCell + +@synthesize item = _item; +@synthesize titleLabel = _titleLabel; - (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; @@ -73,59 +72,34 @@ - (void)layoutSubviews { [super layoutSubviews]; - - CGRect bounds = [[self contentView] bounds]; - CGRect frame = AlignRectOriginAndSizeToPixels(bounds); - [_titleLabel setFrame:frame]; + self.titleLabel.frame = + AlignRectOriginAndSizeToPixels(self.contentView.bounds); } -- (CRWSessionEntry*)entry { - return _entry; -} +#pragma mark Accessors -- (void)setEntry:(CRWSessionEntry*)entry { - _entry = entry; +- (void)setItem:(const web::NavigationItem*)item { + _item = item; - NSString* title = nil; - web::NavigationItem* navigationItem = [_entry navigationItem]; - if (navigationItem) { - // TODO(rohitrao): Can this use GetTitleForDisplay() instead? - if (navigationItem->GetTitle().empty()) - title = base::SysUTF8ToNSString(navigationItem->GetURL().spec()); - else - title = base::SysUTF16ToNSString(navigationItem->GetTitle()); - } - - [_titleLabel setText:title]; - [self setAccessibilityLabel:title]; + self.titleLabel.text = + _item ? base::SysUTF16ToNSString(_item->GetTitleForDisplay()) : nil; + [self setAccessibilityLabel:self.titleLabel.text]; [self setNeedsLayout]; } -- (UILabel*)titleLabel { - return _titleLabel; -} +#pragma mark UICollectionViewCell - (void)prepareForReuse { [super prepareForReuse]; - _entry = nil; - [_titleLabel setText:nil]; - [self setAccessibilityLabel:nil]; + self.item = nullptr; } @end -@implementation TabHistorySectionHeader { - UIImageView* _iconView; - UIView* _lineView; -} +@implementation TabHistorySectionHeader -- (UIImageView*)iconView { - return _iconView; -} - -- (UIView*)lineView { - return _lineView; -} +@synthesize iconView = _iconView; +@synthesize lineView = _lineView; - (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; @@ -134,17 +108,17 @@ _iconView = [[UIImageView alloc] initWithFrame:iconFrame]; [self addSubview:_iconView]; - UIColor* lineColor = UIColorFromRGB(kHeaderLineRGB); - _lineView = [[UIView alloc] initWithFrame:CGRectZero]; - [[_lineView layer] setCornerRadius:HeaderLineRadius()]; - [_lineView setBackgroundColor:lineColor]; + _lineView.layer.cornerRadius = HeaderLineRadius(); + _lineView.backgroundColor = UIColorFromRGB(kHeaderLineRGB); [self addSubview:_lineView]; } return self; } +#pragma mark UIView + - (void)layoutSubviews { [super layoutSubviews]; @@ -153,7 +127,7 @@ CGRect iconViewFrame = AlignRectToPixel(bounds); iconViewFrame.size = CGSizeMake(kSiteIconViewWidth, kSiteIconViewWidth); - [_iconView setFrame:iconViewFrame]; + self.iconView.frame = iconViewFrame; CGFloat iconViewMaxY = CGRectGetMaxY(iconViewFrame); CGFloat height = @@ -167,8 +141,7 @@ lineViewFrame.size.width = HeaderLineWidth(); lineViewFrame.size.height = height; lineViewFrame = AlignRectOriginAndSizeToPixels(lineViewFrame); - - [_lineView setFrame:lineViewFrame]; + self.lineView.frame = lineViewFrame; } @end @@ -178,7 +151,7 @@ - (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) - [self setBackgroundColor:UIColorFromRGB(kFooterRGB)]; + self.backgroundColor = UIColorFromRGB(kFooterRGB); return self; }
diff --git a/ios/chrome/browser/ui/history/tab_history_popup_controller.h b/ios/chrome/browser/ui/history/tab_history_popup_controller.h index 293447f..8cd8a6294 100644 --- a/ios/chrome/browser/ui/history/tab_history_popup_controller.h +++ b/ios/chrome/browser/ui/history/tab_history_popup_controller.h
@@ -7,20 +7,19 @@ #import "ios/chrome/browser/ui/popup_menu/popup_menu_controller.h" -@class TabHistoryViewController; +#include "ios/web/public/navigation_item_list.h" // The view controller for the tab history menu that appears when the user long // presses the back or forward button. @interface TabHistoryPopupController : PopupMenuController -// Initializes the popup to display |entries| with the given |origin| that is +// Initializes the popup to display |items| with the given |origin| that is // relevant to the |parent|'s coordinate system. // |entries| is an array of CRWSessionEntries. -// TODO(crbug.com/546355): Convert this class to use an array of -// NavigationEntries - (id)initWithOrigin:(CGPoint)origin parentView:(UIView*)parent - entries:(NSArray*)entries; + items:(const web::NavigationItemList&)items + NS_DESIGNATED_INITIALIZER; @end
diff --git a/ios/chrome/browser/ui/history/tab_history_popup_controller.mm b/ios/chrome/browser/ui/history/tab_history_popup_controller.mm index 832de03..5c6c124 100644 --- a/ios/chrome/browser/ui/history/tab_history_popup_controller.mm +++ b/ios/chrome/browser/ui/history/tab_history_popup_controller.mm
@@ -15,20 +15,22 @@ #include "ios/chrome/browser/ui/ui_util.h" #import "ios/chrome/common/material_timing.h" #import "ios/third_party/material_roboto_font_loader_ios/src/src/MaterialRobotoFontLoader.h" -#import "ios/web/navigation/crw_session_entry.h" #include "ios/web/public/navigation_item.h" #import "ui/gfx/ios/NSString+CrStringDrawing.h" #include "ui/gfx/ios/uikit_util.h" +#include "url/gurl.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." #endif namespace { -static const CGFloat kTabHistoryMinWidth = 250.0; -static const CGFloat kTabHistoryMaxWidthLandscapePhone = 350.0; +const CGFloat kTabHistoryMinWidth = 250.0; +const CGFloat kTabHistoryMaxWidthLandscapePhone = 350.0; // x coordinate for the textLabel in a default table cell with an image. -static const CGFloat kCellTextXCoordinate = 60.0; +const CGFloat kCellTextXCoordinate = 60.0; +// The corner radius for the popover container view. +const CGFloat kPopoverCornerRadius = 2.0; // Inset for the shadows of the contained views. NS_INLINE UIEdgeInsets TabHistoryPopupMenuInsets() { return UIEdgeInsetsMakeDirected(9, 11, 12, 11); @@ -41,91 +43,90 @@ static const CGFloat kHeightPercentage = 0.85; } // anonymous namespace -@interface TabHistoryPopupController () { - // TableViewController for the table displaying tab history entries. - TabHistoryViewController* tabHistoryTableViewController_; +@interface TabHistoryPopupController () - // Container view of the history entries table. - UIView* tabHistoryTableViewContainer_; -} - -// Determines the width for the popup depending on the device, orientation, and -// CRWSessionEntrys to display. -- (CGFloat)calculatePopupWidth:(NSArray*)entries; - +// The UITableViewController displaying Tab history items. @property(nonatomic, strong) TabHistoryViewController* tabHistoryTableViewController; +// The container view that displays |tabHistoryTableViewController|. @property(nonatomic, strong) UIView* tabHistoryTableViewContainer; +// Determines the width for the popup depending on the device, orientation, and +// number of NavigationItems to display. ++ (CGFloat)popupWidthForItems:(const web::NavigationItemList)items; + @end @implementation TabHistoryPopupController -@synthesize tabHistoryTableViewController = tabHistoryTableViewController_; -@synthesize tabHistoryTableViewContainer = tabHistoryTableViewContainer_; +@synthesize tabHistoryTableViewController = _tabHistoryTableViewController; +@synthesize tabHistoryTableViewContainer = _tabHistoryTableViewContainer; - (id)initWithOrigin:(CGPoint)origin parentView:(UIView*)parent - entries:(NSArray*)entries { + items:(const web::NavigationItemList&)items { DCHECK(parent); - self = [super initWithParentView:parent]; - if (self) { - tabHistoryTableViewController_ = [[TabHistoryViewController alloc] init]; - [tabHistoryTableViewController_ setSessionEntries:entries]; + if ((self = [super initWithParentView:parent])) { + // Create the table view controller. + _tabHistoryTableViewController = + [[TabHistoryViewController alloc] initWithItems:items]; - UICollectionView* collectionView = - [tabHistoryTableViewController_ collectionView]; - [collectionView setAccessibilityIdentifier:@"Tab History"]; + // Set up the container view. + _tabHistoryTableViewContainer = [[UIView alloc] initWithFrame:CGRectZero]; + _tabHistoryTableViewContainer.layer.cornerRadius = kPopoverCornerRadius; + _tabHistoryTableViewContainer.layer.masksToBounds = YES; + [_tabHistoryTableViewContainer + addSubview:_tabHistoryTableViewController.view]; - tabHistoryTableViewContainer_ = [[UIView alloc] initWithFrame:CGRectZero]; - [tabHistoryTableViewContainer_ layer].cornerRadius = 2; - [tabHistoryTableViewContainer_ layer].masksToBounds = YES; - [tabHistoryTableViewContainer_ addSubview:collectionView]; - + // Calculate the optimal popup size. LayoutOffset originOffset = kHistoryPopupLeadingOffset - TabHistoryPopupMenuInsets().left; CGPoint newOrigin = CGPointLayoutOffset(origin, originOffset); newOrigin.y += kHistoryPopupYOffset; - CGFloat availableHeight = (CGRectGetHeight([parent bounds]) - origin.y) * kHeightPercentage; CGFloat optimalHeight = - [tabHistoryTableViewController_ optimalHeight:availableHeight]; - CGFloat popupWidth = [self calculatePopupWidth:entries]; + [_tabHistoryTableViewController optimalHeight:availableHeight]; + CGFloat popupWidth = [[self class] popupWidthForItems:items]; [self setOptimalSize:CGSizeMake(popupWidth, optimalHeight) atOrigin:newOrigin]; - - CGRect bounds = [[self popupContainer] bounds]; - CGRect frame = UIEdgeInsetsInsetRect(bounds, TabHistoryPopupMenuInsets()); - - [tabHistoryTableViewContainer_ setFrame:frame]; - [collectionView setFrame:[tabHistoryTableViewContainer_ bounds]]; - - [[self popupContainer] addSubview:tabHistoryTableViewContainer_]; - CGRect containerFrame = [[self popupContainer] frame]; - CGPoint destination = CGPointMake(CGRectGetLeadingEdge(containerFrame), - CGRectGetMinY(containerFrame)); - [self fadeInPopupFromSource:origin toDestination:destination]; } return self; } +- (void)dealloc { + [_tabHistoryTableViewContainer removeFromSuperview]; +} + +#pragma mark - PopupMenuController + - (void)fadeInPopupFromSource:(CGPoint)source toDestination:(CGPoint)destination { - [tabHistoryTableViewContainer_ setAlpha:0]; + // Add the container view to the popup view and resize. + if (!_tabHistoryTableViewContainer.superview) + [self.popupContainer addSubview:_tabHistoryTableViewContainer]; + _tabHistoryTableViewContainer.frame = UIEdgeInsetsInsetRect( + self.popupContainer.bounds, TabHistoryPopupMenuInsets()); + _tabHistoryTableViewController.view.frame = + _tabHistoryTableViewContainer.bounds; + + // Set up the animation. + [_tabHistoryTableViewContainer setAlpha:0]; [UIView animateWithDuration:ios::material::kDuration1 animations:^{ - [tabHistoryTableViewContainer_ setAlpha:1]; + [_tabHistoryTableViewContainer setAlpha:1]; }]; [super fadeInPopupFromSource:source toDestination:destination]; } - (void)dismissAnimatedWithCompletion:(void (^)(void))completion { - [tabHistoryTableViewContainer_ setAlpha:0]; + [_tabHistoryTableViewContainer setAlpha:0]; [super dismissAnimatedWithCompletion:completion]; } -- (CGFloat)calculatePopupWidth:(NSArray*)entries { +#pragma mark - + ++ (CGFloat)popupWidthForItems:(const web::NavigationItemList)items { CGFloat maxWidth; // Determine the maximum width for the device and orientation. @@ -145,8 +146,7 @@ // Increase the width to fit the text to display but don't exceed maxWidth. CGFloat cellWidth = kTabHistoryMinWidth; UIFont* font = [[MDFRobotoFontLoader sharedInstance] regularFontOfSize:16]; - for (CRWSessionEntry* sessionEntry in entries) { - web::NavigationItem* item = sessionEntry.navigationItem; + for (web::NavigationItem* item : items) { // TODO(rohitrao): Can this be replaced with GetTitleForDisplay()? NSString* cellText = item->GetTitle().empty() ? base::SysUTF8ToNSString(item->GetURL().spec()) @@ -155,7 +155,7 @@ kCellTextXCoordinate; // If contentWidth is larger than maxWidth, return maxWidth instead of - // checking the rest of the entries. + // checking the rest of the items. if (contentWidth > maxWidth) return maxWidth; if (contentWidth > cellWidth) @@ -164,8 +164,4 @@ return cellWidth; } -- (void)dealloc { - [tabHistoryTableViewContainer_ removeFromSuperview]; -} - @end
diff --git a/ios/chrome/browser/ui/history/tab_history_popup_controller_egtest.mm b/ios/chrome/browser/ui/history/tab_history_popup_controller_egtest.mm index 1881fe80..3ef29aba 100644 --- a/ios/chrome/browser/ui/history/tab_history_popup_controller_egtest.mm +++ b/ios/chrome/browser/ui/history/tab_history_popup_controller_egtest.mm
@@ -6,6 +6,7 @@ #include "base/strings/sys_string_conversions.h" #include "components/strings/grit/components_strings.h" +#include "components/url_formatter/url_formatter.h" #import "ios/chrome/test/earl_grey/chrome_earl_grey.h" #import "ios/chrome/test/earl_grey/chrome_matchers.h" #import "ios/chrome/test/earl_grey/chrome_test_case.h" @@ -16,6 +17,13 @@ #error "This file requires ARC support." #endif +namespace { +// Formats |url| for display and returns an NSString representation. +NSString* GetFormattedURLString(const GURL& url) { + return base::SysUTF16ToNSString(url_formatter::FormatUrl(url)); +} +} + // Tests for tab history popup. @interface TabHistoryPopupControllerTestCase : ChromeTestCase @end @@ -31,10 +39,10 @@ const GURL URL3 = web::test::HttpServer::MakeUrl("http://page3"); const GURL URL4 = web::test::HttpServer::MakeUrl("http://page4"); NSString* entry0 = @"New Tab"; - NSString* entry1 = base::SysUTF8ToNSString(URL1.spec()); - NSString* entry2 = base::SysUTF8ToNSString(URL2.spec()); - NSString* entry3 = base::SysUTF8ToNSString(URL3.spec()); - NSString* entry4 = base::SysUTF8ToNSString(URL4.spec()); + NSString* entry1 = GetFormattedURLString(URL1); + NSString* entry2 = GetFormattedURLString(URL2); + NSString* entry3 = GetFormattedURLString(URL3); + NSString* entry4 = GetFormattedURLString(URL4); // Create map of canned responses and set up the test HTML server. std::map<GURL, std::string> responses;
diff --git a/ios/chrome/browser/ui/history/tab_history_popup_controller_unittest.mm b/ios/chrome/browser/ui/history/tab_history_popup_controller_unittest.mm index 3782087..6f1e9e7 100644 --- a/ios/chrome/browser/ui/history/tab_history_popup_controller_unittest.mm +++ b/ios/chrome/browser/ui/history/tab_history_popup_controller_unittest.mm
@@ -11,7 +11,6 @@ #include "components/sessions/core/session_types.h" #import "ios/chrome/browser/ui/history/tab_history_view_controller.h" #include "ios/chrome/browser/ui/ui_util.h" -#import "ios/web/navigation/crw_session_entry.h" #include "ios/web/public/navigation_item.h" #include "ios/web/public/referrer.h" #include "testing/gtest/include/gtest/gtest.h" @@ -20,7 +19,7 @@ #include "ui/gfx/ios/uikit_util.h" @interface TabHistoryPopupController (Testing) -- (CGFloat)calculatePopupWidth:(NSArray*)entries; ++ (CGFloat)popupWidthForItems:(const web::NavigationItemList)items; @property(nonatomic, retain) TabHistoryViewController* tabHistoryTableViewController; @end @@ -32,36 +31,26 @@ class TabHistoryPopupControllerTest : public PlatformTest { protected: void SetUp() override { + web::Referrer referrer(GURL("http://www.example.com"), + web::ReferrerPolicyDefault); + items_.push_back(web::NavigationItem::Create()); + items_.back()->SetURL(GURL("http://www.example.com/0")); + items_.back()->SetReferrer(referrer); + items_.push_back(web::NavigationItem::Create()); + items_.back()->SetURL(GURL("http://www.example.com/1")); + items_.back()->SetReferrer(referrer); + items_.push_back(web::NavigationItem::Create()); + items_.back()->SetURL(GURL("http://www.example.com/0")); + items_.back()->SetReferrer(referrer); + parent_.reset([[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds]); popup_.reset([[TabHistoryPopupController alloc] initWithOrigin:CGPointZero parentView:parent_ - entries:testEntriesArray()]); + items:web::CreateRawNavigationItemList(items_)]); } - void TearDown() override { - parent_.reset(); - popup_.reset(); - } - NSArray* testEntriesArray() { - web::Referrer referrer(GURL("http://www.example.com"), - web::ReferrerPolicyDefault); - std::unique_ptr<web::NavigationItem> item0 = web::NavigationItem::Create(); - item0->SetURL(GURL("http://www.example.com/0")); - item0->SetReferrer(referrer); - CRWSessionEntry* entry0 = - [[CRWSessionEntry alloc] initWithNavigationItem:std::move(item0)]; - std::unique_ptr<web::NavigationItem> item1 = web::NavigationItem::Create(); - item1->SetURL(GURL("http://www.example.com/1")); - item1->SetReferrer(referrer); - CRWSessionEntry* entry1 = - [[CRWSessionEntry alloc] initWithNavigationItem:std::move(item1)]; - std::unique_ptr<web::NavigationItem> item2 = web::NavigationItem::Create(); - item2->SetURL(GURL("http://www.example.com/2")); - item2->SetReferrer(referrer); - CRWSessionEntry* entry2 = - [[CRWSessionEntry alloc] initWithNavigationItem:std::move(item2)]; - return [NSArray arrayWithObjects:entry0, entry1, entry2, nil]; - } + + web::ScopedNavigationItemList items_; base::scoped_nsobject<UIView> parent_; base::scoped_nsobject<TabHistoryPopupController> popup_; }; @@ -81,30 +70,6 @@ } TEST_F(TabHistoryPopupControllerTest, TestCalculatePopupWidth) { - web::Referrer referrer(GURL("http://www.example.com"), - web::ReferrerPolicyDefault); - std::unique_ptr<web::NavigationItem> itemShort = - web::NavigationItem::Create(); - itemShort->SetURL(GURL("http://foo.com/")); - itemShort->SetReferrer(referrer); - CRWSessionEntry* entryShort = - [[CRWSessionEntry alloc] initWithNavigationItem:std::move(itemShort)]; - std::unique_ptr<web::NavigationItem> itemMedium = - web::NavigationItem::Create(); - itemMedium->SetURL(GURL("http://www.example.com/mediumurl")); - itemMedium->SetReferrer(referrer); - CRWSessionEntry* entryMedium = - [[CRWSessionEntry alloc] initWithNavigationItem:std::move(itemMedium)]; - std::string longURL = - "http://www.example.com/this/is/areally/long/url/that/" - "is/larger/than/the/maximum/table/width/so/its/text/will/get/cut/off/and/" - "the/max/width/is/used/"; - std::unique_ptr<web::NavigationItem> itemLong = web::NavigationItem::Create(); - itemLong->SetURL(GURL(longURL)); - itemLong->SetReferrer(referrer); - CRWSessionEntry* entryLong = - [[CRWSessionEntry alloc] initWithNavigationItem:std::move(itemLong)]; - CGFloat minWidth = kTabHistoryMinWidth; CGFloat maxWidth = kTabHistoryMinWidth; if (!IsIPadIdiom()) { @@ -117,19 +82,37 @@ [UIApplication sharedApplication].keyWindow.frame.size.width * .85); } - CGFloat width = - [popup_ calculatePopupWidth:[NSArray arrayWithObjects:entryShort, nil]]; + // Add an item with a short URL and verify that the minimum width is returned. + web::ScopedNavigationItemList items; + web::Referrer referrer(GURL("http://www.example.com"), + web::ReferrerPolicyDefault); + items.push_back(web::NavigationItem::Create()); + items.back()->SetURL(GURL("http://foo.com/")); + items.back()->SetReferrer(referrer); + web::NavigationItemList raw_items = web::CreateRawNavigationItemList(items); + CGFloat width = [TabHistoryPopupController popupWidthForItems:raw_items]; EXPECT_EQ(minWidth, width); - width = - [popup_ calculatePopupWidth:[NSArray arrayWithObjects:entryShort, - entryMedium, nil]]; + // Add an item with a medium URL and verify that the returned width is between + // the minimum and maximum. + items.push_back(web::NavigationItem::Create()); + items.back()->SetURL(GURL("http://www.example.com/mediumurl")); + items.back()->SetReferrer(referrer); + raw_items.push_back(items.back().get()); + width = [TabHistoryPopupController popupWidthForItems:raw_items]; EXPECT_GE(width, minWidth); EXPECT_LE(width, maxWidth); - width = [popup_ - calculatePopupWidth:[NSArray arrayWithObjects:entryShort, entryLong, - entryMedium, nil]]; + // Add an item with a long URL and verify that the maximum width is returned. + std::string long_url = + "http://www.example.com/this/is/areally/long/url/that/" + "is/larger/than/the/maximum/table/width/so/its/text/will/get/cut/off/and/" + "the/max/width/is/used/"; + items.push_back(web::NavigationItem::Create()); + items.back()->SetURL(GURL(long_url)); + items.back()->SetReferrer(referrer); + raw_items.push_back(items.back().get()); + width = [TabHistoryPopupController popupWidthForItems:raw_items]; EXPECT_EQ(maxWidth, width); }
diff --git a/ios/chrome/browser/ui/history/tab_history_view_controller.h b/ios/chrome/browser/ui/history/tab_history_view_controller.h index cc7877e..5343bc2 100644 --- a/ios/chrome/browser/ui/history/tab_history_view_controller.h +++ b/ios/chrome/browser/ui/history/tab_history_view_controller.h
@@ -7,12 +7,21 @@ #import <UIKit/UIKit.h> -// View controller for displaying a list of CRWSessionEntry objects in a table. +#include "ios/web/public/navigation_item_list.h" + +// View controller for displaying a list of NavigationItems in a table. @interface TabHistoryViewController : UICollectionViewController -// TODO(crbug.com/546355): Convert this class to use an array of -// NavigationEntries. -@property(nonatomic, strong) NSArray* sessionEntries; +// Designated initializer that takes a NavigationItemList. +- (instancetype)initWithItems:(const web::NavigationItemList&)items + NS_DESIGNATED_INITIALIZER; + +// TabHistoryViewControllers must be initialized with |-initWithItems:|. +- (instancetype)initWithCoder:(NSCoder*)aDecoder NS_UNAVAILABLE; +- (instancetype)initWithCollectionViewLayout:(UICollectionViewLayout*)layout + NS_UNAVAILABLE; +- (instancetype)initWithNibName:(NSString*)nibNameOrNil + bundle:(NSBundle*)nibBundleOrNil NS_UNAVAILABLE; // Returns the optimal height needed to display the session entries. // The height returned is usually less than the |suggestedHeight| unless
diff --git a/ios/chrome/browser/ui/history/tab_history_view_controller.mm b/ios/chrome/browser/ui/history/tab_history_view_controller.mm index 954ea175..5f84835 100644 --- a/ios/chrome/browser/ui/history/tab_history_view_controller.mm +++ b/ios/chrome/browser/ui/history/tab_history_view_controller.mm
@@ -12,7 +12,6 @@ #import "ios/chrome/browser/ui/history/tab_history_cell.h" #include "ios/chrome/browser/ui/rtl_geometry.h" #import "ios/third_party/material_components_ios/src/components/Ink/src/MaterialInk.h" -#import "ios/web/navigation/crw_session_entry.h" #include "ios/web/public/favicon_status.h" #include "ios/web/public/navigation_item.h" #include "ui/gfx/image/image.h" @@ -27,9 +26,11 @@ // Tools menu is scrollable. const CGFloat kLastRowVisiblePercentage = 0.6; // Reuse identifier for cells. -NSString* cellIdentifier = @"TabHistoryCell"; -NSString* footerIdentifier = @"Footer"; -NSString* headerIdentifier = @"Header"; +NSString* const kCellIdentifier = @"TabHistoryCell"; +NSString* const kFooterIdentifier = @"Footer"; +NSString* const kHeaderIdentifier = @"Header"; +// The collection view's a11y label. +NSString* const kCollectionViewLabel = @"Tab History"; // Height of rows. const CGFloat kCellHeight = 48.0; // Fraction height for partially visible row. @@ -71,6 +72,36 @@ return 1.0 / [[UIScreen mainScreen] scale]; } +// Returns a vector of of NavigationItemLists where the NavigationItems in +// |items| are separated by host. +NS_INLINE std::vector<web::NavigationItemList> PartitionItemsByHost( + const web::NavigationItemList& items) { + std::vector<web::NavigationItemList> partitionedItems; + // Used to store the previous host when partitioning NavigationItems. + std::string previousHost; + // The NavigationItemList containing NavigationItems with the same host. + web::NavigationItemList itemsWithSameHostname; + // Separate the items in |items| by host. + for (web::NavigationItem* item : items) { + std::string currentHost = item->GetURL().host(); + if (previousHost.empty()) + previousHost = currentHost; + // TODO: This should use some sort of Top Level Domain matching instead of + // explicit host match so that images.googe.com matches shopping.google.com. + if (previousHost == currentHost) { + itemsWithSameHostname.push_back(item); + } else { + partitionedItems.push_back(itemsWithSameHostname); + itemsWithSameHostname = web::NavigationItemList(1, item); + previousHost = currentHost; + } + } + // Add the last list contiaining the same host. + if (!itemsWithSameHostname.empty()) + partitionedItems.push_back(itemsWithSameHostname); + return partitionedItems; +} + } // namespace @interface TabHistoryViewControllerLayout : UICollectionViewLayout @@ -219,15 +250,50 @@ @interface TabHistoryViewController ()<MDCInkTouchControllerDelegate> { MDCInkTouchController* _inkTouchController; - NSArray* _partitionedEntries; - NSArray* _sessionEntries; + // A vector of NavigationItemLists where the NavigationItems are separated + // by hostname. + std::vector<web::NavigationItemList> _partitionedItems; } + +// Returns the NavigationItem corresponding with |indexPath|. +- (const web::NavigationItem*)itemAtIndexPath:(NSIndexPath*)indexPath; + +// Removes all NavigationItem pointers from this class. Tapping a cell that +// triggers a navigation may delete NavigationItems, so NavigationItem +// references should be reset to avoid use-after-free errors. +- (void)clearNavigationItems; + @end @implementation TabHistoryViewController -- (NSArray*)sessionEntries { - return _sessionEntries; +- (instancetype)initWithItems:(const web::NavigationItemList&)items { + TabHistoryViewControllerLayout* layout = + [[TabHistoryViewControllerLayout alloc] init]; + if ((self = [super initWithCollectionViewLayout:layout])) { + // Populate |_partitionedItems|. + _partitionedItems = PartitionItemsByHost(items); + + // Set up the UICollectionView. + UICollectionView* collectionView = [self collectionView]; + collectionView.accessibilityLabel = kCollectionViewLabel; + collectionView.backgroundColor = [UIColor whiteColor]; + [collectionView registerClass:[TabHistoryCell class] + forCellWithReuseIdentifier:kCellIdentifier]; + [collectionView registerClass:[TabHistorySectionHeader class] + forSupplementaryViewOfKind:UICollectionElementKindSectionHeader + withReuseIdentifier:kHeaderIdentifier]; + [collectionView registerClass:[TabHistorySectionFooter class] + forSupplementaryViewOfKind:UICollectionElementKindSectionFooter + withReuseIdentifier:kFooterIdentifier]; + + // Set up the ink controller. + _inkTouchController = + [[MDCInkTouchController alloc] initWithView:collectionView]; + [_inkTouchController setDelegate:self]; + [_inkTouchController addInkView]; + } + return self; } #pragma mark Public Methods @@ -236,9 +302,8 @@ DCHECK(suggestedHeight >= kCellHeight); CGFloat optimalHeight = 0; - for (NSArray* sectionArray in _partitionedEntries) { - NSUInteger sectionItemCount = [sectionArray count]; - for (NSUInteger i = 0; i < sectionItemCount; ++i) { + for (web::NavigationItemList& itemsWithSameHost : _partitionedItems) { + for (size_t count = 0; count < itemsWithSameHost.size(); ++count) { CGFloat proposedHeight = optimalHeight + kCellHeight; if (proposedHeight > suggestedHeight) { @@ -263,153 +328,67 @@ return optimalHeight; } -- (instancetype)init { - TabHistoryViewControllerLayout* layout = - [[TabHistoryViewControllerLayout alloc] init]; - - return [self initWithCollectionViewLayout:layout]; -} - -- (instancetype)initWithCollectionViewLayout:(UICollectionViewLayout*)layout { - self = [super initWithCollectionViewLayout:layout]; - if (self) { - UICollectionView* collectionView = [self collectionView]; - [collectionView setBackgroundColor:[UIColor whiteColor]]; - - [collectionView registerClass:[TabHistoryCell class] - forCellWithReuseIdentifier:cellIdentifier]; - - [collectionView registerClass:[TabHistorySectionHeader class] - forSupplementaryViewOfKind:UICollectionElementKindSectionHeader - withReuseIdentifier:headerIdentifier]; - - [collectionView registerClass:[TabHistorySectionFooter class] - forSupplementaryViewOfKind:UICollectionElementKindSectionFooter - withReuseIdentifier:footerIdentifier]; - - _inkTouchController = - [[MDCInkTouchController alloc] initWithView:collectionView]; - [_inkTouchController setDelegate:self]; - [_inkTouchController addInkView]; - } - - return self; -} - #pragma mark UICollectionViewDelegate - (void)collectionView:(UICollectionView*)collectionView didSelectItemAtIndexPath:(NSIndexPath*)indexPath { - UICollectionViewCell* cell = - [collectionView cellForItemAtIndexPath:indexPath]; + TabHistoryCell* cell = base::mac::ObjCCastStrict<TabHistoryCell>( + [collectionView cellForItemAtIndexPath:indexPath]); [collectionView chromeExecuteCommand:cell]; + [self clearNavigationItems]; } #pragma mark UICollectionViewDataSource -- (CRWSessionEntry*)entryForIndexPath:(NSIndexPath*)indexPath { - NSInteger section = [indexPath section]; - NSInteger item = [indexPath item]; - - DCHECK(section < (NSInteger)[_partitionedEntries count]); - DCHECK(item < (NSInteger)[[_partitionedEntries objectAtIndex:section] count]); - NSArray* sectionedArray = [_partitionedEntries objectAtIndex:section]; - - return [sectionedArray objectAtIndex:item]; -} - - (NSInteger)collectionView:(UICollectionView*)collectionView numberOfItemsInSection:(NSInteger)section { - DCHECK(section < (NSInteger)[_partitionedEntries count]); - return [[_partitionedEntries objectAtIndex:section] count]; + size_t sectionIdx = static_cast<size_t>(section); + DCHECK_LT(sectionIdx, _partitionedItems.size()); + return _partitionedItems[sectionIdx].size(); } - (UICollectionViewCell*)collectionView:(UICollectionView*)collectionView cellForItemAtIndexPath:(NSIndexPath*)indexPath { TabHistoryCell* cell = - [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier + [collectionView dequeueReusableCellWithReuseIdentifier:kCellIdentifier forIndexPath:indexPath]; - - [cell setEntry:[self entryForIndexPath:indexPath]]; - [cell setTag:IDC_BACK_FORWARD_IN_TAB_HISTORY]; - + cell.item = [self itemAtIndexPath:indexPath]; + cell.tag = IDC_BACK_FORWARD_IN_TAB_HISTORY; return cell; } - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView*)view { - return [_partitionedEntries count]; + return _partitionedItems.size(); } - (UICollectionReusableView*)collectionView:(UICollectionView*)view viewForSupplementaryElementOfKind:(NSString*)kind atIndexPath:(NSIndexPath*)indexPath { + // Return a footer cell if requested. if ([kind isEqualToString:UICollectionElementKindSectionFooter]) { return [view dequeueReusableSupplementaryViewOfKind:kind - withReuseIdentifier:footerIdentifier + withReuseIdentifier:kFooterIdentifier forIndexPath:indexPath]; } - DCHECK([kind isEqualToString:UICollectionElementKindSectionHeader]); - CRWSessionEntry* sessionEntry = [self entryForIndexPath:indexPath]; - web::NavigationItem* navigationItem = [sessionEntry navigationItem]; + // Dequeue a header cell and populate its favicon image. TabHistorySectionHeader* header = [view dequeueReusableSupplementaryViewOfKind:kind - withReuseIdentifier:headerIdentifier + withReuseIdentifier:kHeaderIdentifier forIndexPath:indexPath]; - UIImage* iconImage = nil; - const gfx::Image& image = navigationItem->GetFavicon().image; + const gfx::Image& image = + [self itemAtIndexPath:indexPath]->GetFavicon().image; if (!image.IsEmpty()) iconImage = image.ToUIImage(); else iconImage = [UIImage imageNamed:@"default_favicon"]; - [[header iconView] setImage:iconImage]; return header; } -- (void)setSessionEntries:(NSArray*)sessionEntries { - _sessionEntries = sessionEntries; - - std::string previousHost; - - NSMutableArray* sectionArray = [NSMutableArray array]; - NSMutableArray* partitionedEntries = [NSMutableArray array]; - - NSInteger numberOfEntries = [_sessionEntries count]; - for (NSInteger index = 0; index < numberOfEntries; ++index) { - CRWSessionEntry* sessionEntry = [_sessionEntries objectAtIndex:index]; - web::NavigationItem* navigationItem = [sessionEntry navigationItem]; - - std::string currentHost; - if (navigationItem) - currentHost = navigationItem->GetURL().host(); - - if (previousHost.empty()) - previousHost = currentHost; - - // TODO: This should use some sort of Top Level Domain matching instead of - // explicit host match so that images.googe.com matches shopping.google.com. - if (previousHost == currentHost) { - [sectionArray addObject:sessionEntry]; - } else { - [partitionedEntries addObject:sectionArray]; - sectionArray = [NSMutableArray arrayWithObject:sessionEntry]; - previousHost = currentHost; - } - } - - if ([sectionArray count]) - [partitionedEntries addObject:sectionArray]; - - if (![partitionedEntries count]) - partitionedEntries = nil; - - _partitionedEntries = partitionedEntries; -} - #pragma mark MDCInkTouchControllerDelegate - (BOOL)inkTouchController:(MDCInkTouchController*)inkTouchController @@ -431,4 +410,22 @@ return YES; } +#pragma mark - + +- (const web::NavigationItem*)itemAtIndexPath:(NSIndexPath*)indexPath { + size_t section = static_cast<size_t>([indexPath section]); + size_t item = static_cast<size_t>([indexPath item]); + DCHECK_LT(section, _partitionedItems.size()); + DCHECK_LT(item, _partitionedItems[section].size()); + return _partitionedItems[section][item]; +} + +- (void)clearNavigationItems { + _partitionedItems.clear(); + for (UICollectionViewCell* cell in self.collectionView.visibleCells) { + TabHistoryCell* historyCell = base::mac::ObjCCast<TabHistoryCell>(cell); + historyCell.item = nullptr; + } +} + @end
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 d449366..659afd7 100644 --- a/ios/chrome/browser/ui/omnibox/omnibox_text_field_ios.mm +++ b/ios/chrome/browser/ui/omnibox/omnibox_text_field_ios.mm
@@ -7,7 +7,6 @@ #import <CoreText/CoreText.h> #include "base/command_line.h" -#include "base/ios/ios_util.h" #include "base/logging.h" #include "base/mac/foundation_util.h" #include "base/mac/objc_property_releaser.h" @@ -278,7 +277,7 @@ } - (NSTextAlignment)bestTextAlignment { - if (!base::ios::IsRunningOnIOS9OrLater() || [self isFirstResponder]) { + if ([self isFirstResponder]) { return [self bestAlignmentForText:[self text]]; } return NSTextAlignmentNatural;
diff --git a/ios/chrome/browser/ui/preload_controller_delegate.h b/ios/chrome/browser/ui/preload_controller_delegate.h index e23302e903..46e08c56 100644 --- a/ios/chrome/browser/ui/preload_controller_delegate.h +++ b/ios/chrome/browser/ui/preload_controller_delegate.h
@@ -7,16 +7,11 @@ #import <UIKit/UIKit.h> -@class CRWSessionEntry; - // A protocol implemented by a delegate of PreloadController @protocol PreloadControllerDelegate // Should preload controller request a desktop site. - (BOOL)shouldUseDesktopUserAgent; -// Return the current sessionEntry from the delegate. -// TODO(crbug.com/546348): See if this can return a NavigationItem instead. -- (CRWSessionEntry*)currentSessionEntry; @end #endif // IOS_CHROME_BROWSER_UI_PRELOAD_CONTROLLER_DELEGATE_H_
diff --git a/ios/chrome/browser/ui/toolbar/web_toolbar_controller.h b/ios/chrome/browser/ui/toolbar/web_toolbar_controller.h index 16732f5..66febd2 100644 --- a/ios/chrome/browser/ui/toolbar/web_toolbar_controller.h +++ b/ios/chrome/browser/ui/toolbar/web_toolbar_controller.h
@@ -12,6 +12,7 @@ #include "ios/chrome/browser/ui/qr_scanner/qr_scanner_view_controller.h" #import "ios/chrome/browser/ui/toolbar/toolbar_controller.h" #include "ios/public/provider/chrome/browser/voice/voice_search_controller_delegate.h" +#include "ios/web/public/navigation_item_list.h" @protocol PreloadProvider; @class Tab; @@ -150,7 +151,7 @@ // Shows the tab history popup inside |view|. - (void)showTabHistoryPopupInView:(UIView*)view - withSessionEntries:(NSArray*)sessionEntries + withItems:(const web::NavigationItemList&)items forBackHistory:(BOOL)isBackHistory; // Dismisses the tab history popup.
diff --git a/ios/chrome/browser/ui/toolbar/web_toolbar_controller.mm b/ios/chrome/browser/ui/toolbar/web_toolbar_controller.mm index 498ce10..ee215e35 100644 --- a/ios/chrome/browser/ui/toolbar/web_toolbar_controller.mm +++ b/ios/chrome/browser/ui/toolbar/web_toolbar_controller.mm
@@ -805,7 +805,7 @@ } - (void)showTabHistoryPopupInView:(UIView*)view - withSessionEntries:(NSArray*)sessionEntries + withItems:(const web::NavigationItemList&)items forBackHistory:(BOOL)isBackHistory { if (_tabHistoryPopupController) return; @@ -826,9 +826,15 @@ _tabHistoryPopupController.reset([[TabHistoryPopupController alloc] initWithOrigin:convertedOrigin parentView:view - entries:sessionEntries]); + items:items]); [_tabHistoryPopupController setDelegate:self]; + // Fade in the popup and notify observers. + CGRect containerFrame = [[_tabHistoryPopupController popupContainer] frame]; + CGPoint destination = CGPointMake(CGRectGetLeadingEdge(containerFrame), + CGRectGetMinY(containerFrame)); + [_tabHistoryPopupController fadeInPopupFromSource:convertedOrigin + toDestination:destination]; [[NSNotificationCenter defaultCenter] postNotificationName:kTabHistoryPopupWillShowNotification object:nil];
diff --git a/ios/clean/OWNERS b/ios/clean/OWNERS new file mode 100644 index 0000000..d5d7f59 --- /dev/null +++ b/ios/clean/OWNERS
@@ -0,0 +1,2 @@ +lpromero@chromium.org +marq@chromium.org
diff --git a/ios/clean/DEPS b/ios/clean/chrome/DEPS similarity index 66% rename from ios/clean/DEPS rename to ios/clean/chrome/DEPS index e06ba51..e6eb2ee 100644 --- a/ios/clean/DEPS +++ b/ios/clean/chrome/DEPS
@@ -5,4 +5,7 @@ "+ios/shared", "+ios/third_party", "+ios/web", + + # Strings and resources. + "+components/strings/grit", ]
diff --git a/ios/clean/chrome/app/steps/launch_to_foreground.mm b/ios/clean/chrome/app/steps/launch_to_foreground.mm index e8a7247..f8e6950e 100644 --- a/ios/clean/chrome/app/steps/launch_to_foreground.mm +++ b/ios/clean/chrome/app/steps/launch_to_foreground.mm
@@ -69,7 +69,7 @@ if (motion == UIEventSubtypeMotionShake) { UIApplication* app = [UIApplication sharedApplication]; [app.delegate application:app - openURL:[NSURL URLWithString:@"https://www.google.com"] + openURL:[NSURL URLWithString:@"chrome://newtab"] options:@{}]; } [super motionEnded:motion withEvent:event];
diff --git a/ios/clean/chrome/browser/ui/ntp/BUILD.gn b/ios/clean/chrome/browser/ui/ntp/BUILD.gn new file mode 100644 index 0000000..609b8fb2 --- /dev/null +++ b/ios/clean/chrome/browser/ui/ntp/BUILD.gn
@@ -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. + +source_set("ntp") { + sources = [ + "new_tab_page_coordinator.h", + "new_tab_page_coordinator.mm", + ] + + configs += [ "//build/config/compiler:enable_arc" ] + + deps = [ + ":ntp_ui", + "//ios/clean/chrome/browser", + "//ios/shared/chrome/browser/coordinator_context", + ] +} + +source_set("ntp_ui") { + sources = [ + "new_tab_page_view_controller.h", + "new_tab_page_view_controller.mm", + ] + + configs += [ "//build/config/compiler:enable_arc" ] + + deps = [ + "//base", + "//components/strings:components_strings_grit", + "//ios/chrome/app/strings:ios_strings_grit", + "//ios/chrome/browser/ui/ntp:ntp_internal", + "//ios/clean/chrome/browser/ui", + "//ui/base:base", + ] +}
diff --git a/ios/clean/chrome/browser/ui/ntp/new_tab_page_coordinator.h b/ios/clean/chrome/browser/ui/ntp/new_tab_page_coordinator.h new file mode 100644 index 0000000..ec6381b9 --- /dev/null +++ b/ios/clean/chrome/browser/ui/ntp/new_tab_page_coordinator.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 IOS_CLEAN_CHROME_BROWSER_UI_NTP_NEW_TAB_PAGE_COORDINATOR_H_ +#define IOS_CLEAN_CHROME_BROWSER_UI_NTP_NEW_TAB_PAGE_COORDINATOR_H_ + +#import <UIKit/UIKit.h> +#import "ios/clean/chrome/browser/browser_coordinator.h" + +// Coordinator that runs a "New Tab Page" : The UI displayed instead of a web +// page when a new tab is created. +@interface NTPCoordinator : BrowserCoordinator +@end + +#endif // IOS_CLEAN_CHROME_BROWSER_UI_NTP_NEW_TAB_PAGE_COORDINATOR_H_
diff --git a/ios/clean/chrome/browser/ui/ntp/new_tab_page_coordinator.mm b/ios/clean/chrome/browser/ui/ntp/new_tab_page_coordinator.mm new file mode 100644 index 0000000..4e61776 --- /dev/null +++ b/ios/clean/chrome/browser/ui/ntp/new_tab_page_coordinator.mm
@@ -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. + +#import "ios/clean/chrome/browser/ui/ntp/new_tab_page_coordinator.h" + +#import "ios/clean/chrome/browser/ui/ntp/new_tab_page_view_controller.h" +#import "ios/shared/chrome/browser/coordinator_context/coordinator_context.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +@interface NTPCoordinator () +@property(nonatomic, strong) NTPViewController* viewController; +@end + +@implementation NTPCoordinator +@synthesize viewController = _viewController; + +- (void)start { + self.viewController = [[NTPViewController alloc] init]; + [self.context.baseViewController presentViewController:self.viewController + animated:self.context.animated + completion:nil]; +} + +@end
diff --git a/ios/clean/chrome/browser/ui/ntp/new_tab_page_view_controller.h b/ios/clean/chrome/browser/ui/ntp/new_tab_page_view_controller.h new file mode 100644 index 0000000..c2b5f34 --- /dev/null +++ b/ios/clean/chrome/browser/ui/ntp/new_tab_page_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 IOS_CLEAN_CHROME_BROWSER_UI_NTP_NEW_TAB_PAGE_VIEW_CONTROLLER_H_ +#define IOS_CLEAN_CHROME_BROWSER_UI_NTP_NEW_TAB_PAGE_VIEW_CONTROLLER_H_ + +#import <UIKit/UIKit.h> + +// View controller that displays a new tab page. +@interface NTPViewController : UIViewController +@end + +#endif // IOS_CLEAN_CHROME_BROWSER_UI_NTP_NEW_TAB_PAGE_VIEW_CONTROLLER_H_
diff --git a/ios/clean/chrome/browser/ui/ntp/new_tab_page_view_controller.mm b/ios/clean/chrome/browser/ui/ntp/new_tab_page_view_controller.mm new file mode 100644 index 0000000..7e9eee5a --- /dev/null +++ b/ios/clean/chrome/browser/ui/ntp/new_tab_page_view_controller.mm
@@ -0,0 +1,79 @@ +// 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/clean/chrome/browser/ui/ntp/new_tab_page_view_controller.h" + +#import "base/ios/crb_protocol_observers.h" +#include "components/strings/grit/components_strings.h" +#import "ios/chrome/browser/ui/ntp/new_tab_page_bar.h" +#import "ios/chrome/browser/ui/ntp/new_tab_page_bar_item.h" +#import "ios/chrome/browser/ui/ntp/new_tab_page_controller.h" +#import "ios/chrome/browser/ui/ntp/new_tab_page_view.h" +#include "ios/chrome/grit/ios_strings.h" +#include "ui/base/l10n/l10n_util.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +@implementation NTPViewController + +#pragma mark - UIViewController + +- (void)viewDidLoad { + self.title = l10n_util::GetNSString(IDS_NEW_TAB_TITLE); + self.view.backgroundColor = [UIColor whiteColor]; + + UIScrollView* scrollView = [[UIScrollView alloc] initWithFrame:CGRectZero]; + [scrollView setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | + UIViewAutoresizingFlexibleHeight)]; + scrollView.pagingEnabled = YES; + scrollView.showsHorizontalScrollIndicator = NO; + scrollView.showsVerticalScrollIndicator = NO; + scrollView.contentMode = UIViewContentModeScaleAspectFit; + scrollView.bounces = YES; + scrollView.scrollsToTop = NO; + + NewTabPageBar* tabBar = [[NewTabPageBar alloc] initWithFrame:CGRectZero]; + NewTabPageView* ntpView = [[NewTabPageView alloc] initWithFrame:CGRectZero + andScrollView:scrollView + andTabBar:tabBar]; + ntpView.translatesAutoresizingMaskIntoConstraints = NO; + [self.view addSubview:ntpView]; + + [NSLayoutConstraint activateConstraints:@[ + [ntpView.topAnchor constraintEqualToAnchor:self.view.topAnchor], + [ntpView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor], + [ntpView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor], + [ntpView.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor], + ]]; + + // PLACEHOLDER: this logic should move out of the UIVC. + NSString* mostVisited = l10n_util::GetNSString(IDS_IOS_NEW_TAB_MOST_VISITED); + NSString* bookmarks = + l10n_util::GetNSString(IDS_IOS_NEW_TAB_BOOKMARKS_PAGE_TITLE_MOBILE); + NSString* openTabs = l10n_util::GetNSString(IDS_IOS_NEW_TAB_RECENT_TABS); + + NSMutableArray* tabBarItems = [NSMutableArray array]; + + NewTabPageBarItem* mostVisitedItem = [NewTabPageBarItem + newTabPageBarItemWithTitle:mostVisited + identifier:NewTabPage::kMostVisitedPanel + image:[UIImage imageNamed:@"ntp_mv_search"]]; + NewTabPageBarItem* bookmarksItem = [NewTabPageBarItem + newTabPageBarItemWithTitle:bookmarks + identifier:NewTabPage::kBookmarksPanel + image:[UIImage imageNamed:@"ntp_bookmarks"]]; + [tabBarItems addObject:bookmarksItem]; + [tabBarItems addObject:mostVisitedItem]; + + NewTabPageBarItem* openTabsItem = [NewTabPageBarItem + newTabPageBarItemWithTitle:openTabs + identifier:NewTabPage::kOpenTabsPanel + image:[UIImage imageNamed:@"ntp_opentabs"]]; + [tabBarItems addObject:openTabsItem]; + tabBar.items = tabBarItems; +} + +@end
diff --git a/ios/clean/chrome/browser/ui/tab/BUILD.gn b/ios/clean/chrome/browser/ui/tab/BUILD.gn index 6e256bc..a341ea1 100644 --- a/ios/clean/chrome/browser/ui/tab/BUILD.gn +++ b/ios/clean/chrome/browser/ui/tab/BUILD.gn
@@ -18,6 +18,7 @@ "//ios/clean/chrome/browser/ui", "//ios/clean/chrome/browser/ui/actions", "//ios/clean/chrome/browser/ui/animators", + "//ios/clean/chrome/browser/ui/ntp", "//ios/clean/chrome/browser/ui/presenters", "//ios/clean/chrome/browser/ui/toolbar", "//ios/clean/chrome/browser/ui/web_contents",
diff --git a/ios/clean/chrome/browser/ui/tab/tab_coordinator.mm b/ios/clean/chrome/browser/ui/tab/tab_coordinator.mm index 4afcb23..9139cc9 100644 --- a/ios/clean/chrome/browser/ui/tab/tab_coordinator.mm +++ b/ios/clean/chrome/browser/ui/tab/tab_coordinator.mm
@@ -15,10 +15,13 @@ #import "ios/clean/chrome/browser/browser_coordinator+internal.h" #import "ios/clean/chrome/browser/ui/actions/tab_grid_actions.h" #import "ios/clean/chrome/browser/ui/animators/zoom_transition_animator.h" +#import "ios/clean/chrome/browser/ui/ntp/new_tab_page_coordinator.h" #import "ios/clean/chrome/browser/ui/tab/tab_container_view_controller.h" #import "ios/clean/chrome/browser/ui/toolbar/toolbar_coordinator.h" #import "ios/clean/chrome/browser/ui/web_contents/web_coordinator.h" #import "ios/shared/chrome/browser/coordinator_context/coordinator_context.h" +#import "ios/web/public/web_state/web_state.h" +#import "ios/web/public/web_state/web_state_observer_bridge.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -30,11 +33,15 @@ const BOOL kUseBottomToolbar = NO; } // namespace -@interface TabCoordinator ()<UIViewControllerTransitioningDelegate> +@interface TabCoordinator ()<CRWWebStateObserver, + UIViewControllerTransitioningDelegate> @property(nonatomic, strong) TabContainerViewController* viewController; @end -@implementation TabCoordinator +@implementation TabCoordinator { + std::unique_ptr<web::WebStateObserverBridge> _webStateObserver; +} + @synthesize presentationKey = _presentationKey; @synthesize viewController = _viewController; @synthesize webState = _webState; @@ -43,6 +50,8 @@ self.viewController = [self newTabContainer]; self.viewController.transitioningDelegate = self; self.viewController.modalPresentationStyle = UIModalPresentationCustom; + _webStateObserver = + base::MakeUnique<web::WebStateObserverBridge>(self.webState, self); WebCoordinator* webCoordinator = [[WebCoordinator alloc] init]; webCoordinator.webState = self.webState; @@ -87,6 +96,7 @@ [self.viewController.presentingViewController dismissViewControllerAnimated:self.context.animated completion:nil]; + _webStateObserver.reset(); } - (BOOL)canAddOverlayCoordinator:(BrowserCoordinator*)overlayCoordinator { @@ -106,6 +116,21 @@ return [[TopToolbarTabViewController alloc] init]; } +#pragma mark - CRWWebStateObserver + +// This will eventually be called in -didFinishNavigation and perhaps as an +// optimization in some equivalent to loadURL. +- (void)webState:(web::WebState*)webState + didCommitNavigationWithDetails:(const web::LoadCommittedDetails&)details { + if (webState->GetLastCommittedURL() == GURL("chrome://newtab/")) { + NTPCoordinator* ntpCoordinator = [[NTPCoordinator alloc] init]; + [self addChildCoordinator:ntpCoordinator]; + ntpCoordinator.context.baseViewController = nil; + [ntpCoordinator start]; + self.viewController.contentViewController = ntpCoordinator.viewController; + } +} + #pragma mark - UIViewControllerTransitioningDelegate - (id<UIViewControllerAnimatedTransitioning>)
diff --git a/ios/web/navigation/crw_session_certificate_policy_manager.h b/ios/web/navigation/crw_session_certificate_policy_manager.h index 72553c1..2d33f388 100644 --- a/ios/web/navigation/crw_session_certificate_policy_manager.h +++ b/ios/web/navigation/crw_session_certificate_policy_manager.h
@@ -11,8 +11,6 @@ #include "base/memory/ref_counted.h" #include "net/cert/cert_status_flags.h" -@class CRWSessionEntry; - namespace net { class X509Certificate; }
diff --git a/ios/web/navigation/navigation_item_storage_builder.mm b/ios/web/navigation/navigation_item_storage_builder.mm index 1b166724..286501c 100644 --- a/ios/web/navigation/navigation_item_storage_builder.mm +++ b/ios/web/navigation/navigation_item_storage_builder.mm
@@ -34,7 +34,12 @@ NavigationItemStorageBuilder::BuildNavigationItemImpl( CRWNavigationItemStorage* navigation_item_storage) const { std::unique_ptr<NavigationItemImpl> item(new web::NavigationItemImpl()); - item->virtual_url_ = navigation_item_storage.virtualURL; + // While the virtual URL is persisted, we still need the original request URL + // and the non-virtual URL to be set upon NavigationItem creation. Since + // GetVirtualURL() returns |url_| for the non-overridden case, this will also + // update the virtual URL reported by this object. + item->original_request_url_ = navigation_item_storage.virtualURL; + item->url_ = navigation_item_storage.virtualURL; item->referrer_ = navigation_item_storage.referrer; item->timestamp_ = navigation_item_storage.timestamp; item->title_ = navigation_item_storage.title;
diff --git a/ios/web/payments/payment_request.cc b/ios/web/payments/payment_request.cc index fdfdb56c..5d56b31 100644 --- a/ios/web/payments/payment_request.cc +++ b/ios/web/payments/payment_request.cc
@@ -32,8 +32,10 @@ static const char kMethodData[] = "methodData"; static const char kMethodDataData[] = "data"; static const char kMethodName[] = "methodName"; -static const char kPaymentCurrencyAmountCurrencySystem[] = "currencySystem"; static const char kPaymentCurrencyAmountCurrency[] = "currency"; +static const char kPaymentCurrencyAmountCurrencySystem[] = "currencySystem"; +static const char kPaymentCurrencyAmountCurrencySystemISO4217[] = + "urn:iso:std:iso:4217"; static const char kPaymentCurrencyAmountValue[] = "value"; static const char kPaymentDetails[] = "details"; static const char kPaymentDetailsDisplayItems[] = "displayItems"; @@ -43,6 +45,14 @@ static const char kPaymentItemAmount[] = "amount"; static const char kPaymentItemLabel[] = "label"; static const char kPaymentItemPending[] = "pending"; +static const char kPaymentOptions[] = "options"; +static const char kPaymentOptionsRequestPayerEmail[] = "requestPayerEmail"; +static const char kPaymentOptionsRequestPayerName[] = "requestPayerName"; +static const char kPaymentOptionsRequestPayerPhone[] = "requestPayerPhone"; +static const char kPaymentOptionsRequestShipping[] = "requestShipping"; +static const char kPaymentOptionsShippingType[] = "shippingType"; +static const char kPaymentOptionsShippingTypeDelivery[] = "delivery"; +static const char kPaymentOptionsShippingTypePickup[] = "pickup"; static const char kPaymentShippingOptionAmount[] = "amount"; static const char kPaymentShippingOptionId[] = "id"; static const char kPaymentShippingOptionLabel[] = "label"; @@ -149,9 +159,10 @@ } PaymentCurrencyAmount::PaymentCurrencyAmount() - // By default, the value is urn:iso:std:iso:4217 indicating that currency is - // defined by [ISO4217] (for example, USD for US Dollars). - : currency_system(base::ASCIIToUTF16("urn:iso:std:iso:4217")) {} + // By default, the currency is defined by [ISO4217]. For example, USD for + // US Dollars. + : currency_system( + base::ASCIIToUTF16(kPaymentCurrencyAmountCurrencySystemISO4217)) {} PaymentCurrencyAmount::~PaymentCurrencyAmount() = default; @@ -334,21 +345,51 @@ } PaymentOptions::PaymentOptions() - : request_payer_email(false), + : request_payer_name(false), + request_payer_email(false), request_payer_phone(false), - request_shipping(false) {} + request_shipping(false), + shipping_type(PaymentShippingType::SHIPPING) {} PaymentOptions::~PaymentOptions() = default; bool PaymentOptions::operator==(const PaymentOptions& other) const { - return this->request_payer_email == other.request_payer_email && + return this->request_payer_name == other.request_payer_name && + this->request_payer_email == other.request_payer_email && this->request_payer_phone == other.request_payer_phone && - this->request_shipping == other.request_shipping; + this->request_shipping == other.request_shipping && + this->shipping_type == other.shipping_type; } bool PaymentOptions::operator!=(const PaymentOptions& other) const { return !(*this == other); } +bool PaymentOptions::FromDictionaryValue(const base::DictionaryValue& value) { + value.GetBoolean(kPaymentOptionsRequestPayerName, &this->request_payer_name); + + value.GetBoolean(kPaymentOptionsRequestPayerEmail, + &this->request_payer_email); + + value.GetBoolean(kPaymentOptionsRequestPayerPhone, + &this->request_payer_phone); + + value.GetBoolean(kPaymentOptionsRequestShipping, &this->request_shipping); + + base::string16 shipping_type; + value.GetString(kPaymentOptionsShippingType, &shipping_type); + if (shipping_type == + base::ASCIIToUTF16(kPaymentOptionsShippingTypeDelivery)) { + this->shipping_type = PaymentShippingType::DELIVERY; + } else if (shipping_type == + base::ASCIIToUTF16(kPaymentOptionsShippingTypePickup)) { + this->shipping_type = PaymentShippingType::PICKUP; + } else { + this->shipping_type = PaymentShippingType::SHIPPING; + } + + return true; +} + PaymentRequest::PaymentRequest() {} PaymentRequest::PaymentRequest(const PaymentRequest& other) = default; PaymentRequest::~PaymentRequest() = default; @@ -387,11 +428,17 @@ // Parse the payment details. const base::DictionaryValue* payment_details_dict = nullptr; - if (value.GetDictionary(kPaymentDetails, &payment_details_dict)) - if (!this->details.FromDictionaryValue(*payment_details_dict)) - return false; + if (!value.GetDictionary(kPaymentDetails, &payment_details_dict) || + !this->details.FromDictionaryValue(*payment_details_dict)) { + return false; + } - // TODO(crbug.com/602666): Parse the remaining elements. + // Parse the payment options. + const base::DictionaryValue* payment_options = nullptr; + // Options field is optional. + if (value.GetDictionary(kPaymentOptions, &payment_options)) + if (!this->options.FromDictionaryValue(*payment_options)) + return false; return true; }
diff --git a/ios/web/payments/payment_request_unittest.cc b/ios/web/payments/payment_request_unittest.cc index 44962be..529c8590 100644 --- a/ios/web/payments/payment_request_unittest.cc +++ b/ios/web/payments/payment_request_unittest.cc
@@ -236,6 +236,11 @@ base::DictionaryValue request_dict; // Add the expected values to expected_request. + expected_request.details.total.label = base::ASCIIToUTF16("TOTAL"); + expected_request.details.total.amount.currency = base::ASCIIToUTF16("GBP"); + expected_request.details.total.amount.value = base::ASCIIToUTF16("6.66"); + expected_request.details.error = base::ASCIIToUTF16("Error in details"); + PaymentMethodData method_data; std::vector<base::string16> supported_methods; supported_methods.push_back(base::ASCIIToUTF16("Visa")); @@ -243,6 +248,18 @@ expected_request.method_data.push_back(method_data); // Add the same values to the dictionary to be parsed. + std::unique_ptr<base::DictionaryValue> details_dict( + new base::DictionaryValue); + std::unique_ptr<base::DictionaryValue> total_dict(new base::DictionaryValue); + total_dict->SetString("label", "TOTAL"); + std::unique_ptr<base::DictionaryValue> amount_dict(new base::DictionaryValue); + amount_dict->SetString("currency", "GBP"); + amount_dict->SetString("value", "6.66"); + total_dict->Set("amount", std::move(amount_dict)); + details_dict->Set("total", std::move(total_dict)); + details_dict->SetString("error", "Error in details"); + request_dict.Set("details", std::move(details_dict)); + std::unique_ptr<base::ListValue> method_data_list(new base::ListValue); std::unique_ptr<base::DictionaryValue> method_data_dict( new base::DictionaryValue); @@ -256,23 +273,19 @@ EXPECT_TRUE(output_request.FromDictionaryValue(request_dict)); EXPECT_EQ(expected_request, output_request); - // If payment details are present, parse those as well. - expected_request.details.total.label = base::ASCIIToUTF16("TOTAL"); - expected_request.details.total.amount.currency = base::ASCIIToUTF16("GBP"); - expected_request.details.total.amount.value = base::ASCIIToUTF16("6.66"); - expected_request.details.error = base::ASCIIToUTF16("Error in details"); - - std::unique_ptr<base::DictionaryValue> details_dict( + // If payment options are present, parse those as well. + std::unique_ptr<base::DictionaryValue> options_dict( new base::DictionaryValue); - std::unique_ptr<base::DictionaryValue> total_dict(new base::DictionaryValue); - total_dict->SetString("label", "TOTAL"); - std::unique_ptr<base::DictionaryValue> amount_dict(new base::DictionaryValue); - amount_dict->SetString("currency", "GBP"); - amount_dict->SetString("value", "6.66"); - total_dict->Set("amount", std::move(amount_dict)); - details_dict->Set("total", std::move(total_dict)); - details_dict->SetString("error", "Error in details"); - request_dict.Set("details", std::move(details_dict)); + options_dict->SetBoolean("requestPayerPhone", true); + options_dict->SetBoolean("requestShipping", true); + options_dict->SetString("shippingType", "delivery"); + request_dict.Set("options", std::move(options_dict)); + + PaymentOptions payment_options; + payment_options.request_payer_phone = true; + payment_options.request_shipping = true; + payment_options.shipping_type = PaymentShippingType::DELIVERY; + expected_request.options = payment_options; EXPECT_TRUE(output_request.FromDictionaryValue(request_dict)); EXPECT_EQ(expected_request, output_request); @@ -647,6 +660,11 @@ PaymentOptions options2; EXPECT_EQ(options1, options2); + options1.request_payer_name = true; + EXPECT_NE(options1, options2); + options2.request_payer_name = true; + EXPECT_EQ(options1, options2); + options1.request_payer_email = true; EXPECT_NE(options1, options2); options2.request_payer_email = true; @@ -661,6 +679,14 @@ EXPECT_NE(options1, options2); options2.request_shipping = true; EXPECT_EQ(options1, options2); + + // PaymentShippingType::SHIPPING is the default value for shipping_type. + options1.shipping_type = PaymentShippingType::SHIPPING; + EXPECT_EQ(options1, options2); + options1.shipping_type = PaymentShippingType::PICKUP; + EXPECT_NE(options1, options2); + options2.shipping_type = PaymentShippingType::PICKUP; + EXPECT_EQ(options1, options2); } // Tests that two payment request objects are not equal if their property values
diff --git a/ios/web/public/payments/payment_request.h b/ios/web/public/payments/payment_request.h index c2a8baa..a12c289 100644 --- a/ios/web/public/payments/payment_request.h +++ b/ios/web/public/payments/payment_request.h
@@ -248,6 +248,14 @@ base::string16 error; }; +// Possible values for affecting the payment request user interface for +// gathering the shipping address. +enum class PaymentShippingType : int { + SHIPPING = 0, + DELIVERY = 1, + PICKUP = 2, +}; + // Information describing a shipping option. class PaymentOptions { public: @@ -257,6 +265,15 @@ bool operator==(const PaymentOptions& other) const; bool operator!=(const PaymentOptions& other) const; + // Populates the properties of this PaymentOptions from |value|. Returns true + // if the required values are present. + bool FromDictionaryValue(const base::DictionaryValue& value); + + // Indicates whether the user agent should collect and return the payer's name + // as part of the payment request. For example, this would be set to true to + // allow a merchant to make a booking in the payer's name. + bool request_payer_name; + // Indicates whether the user agent should collect and return the payer's // email address as part of the payment request. For example, this would be // set to true to allow a merchant to email a receipt. @@ -273,6 +290,11 @@ // This would be set to false for an online-only electronic purchase // transaction. bool request_shipping; + + // If request_shipping is set to true, then this field may only be used to + // influence the way the user agent presents the user interface for gathering + // the shipping address. + PaymentShippingType shipping_type; }; // All of the information provided by a page making a request for payment.
diff --git a/ios/web/web_state/ui/crw_web_controller.mm b/ios/web/web_state/ui/crw_web_controller.mm index bfcc3f98..45a5e8b 100644 --- a/ios/web/web_state/ui/crw_web_controller.mm +++ b/ios/web/web_state/ui/crw_web_controller.mm
@@ -2006,6 +2006,11 @@ _containerView.get().frame = containerViewFrame; DCHECK(!CGRectIsEmpty(_containerView.get().frame)); + // TODO(crbug.com/691116): Remove this workaround once tests are no longer + // dependent upon this accessibility ID. + if (!base::ios::IsRunningOnIOS10OrLater()) + [_containerView setAccessibilityIdentifier:@"Container View"]; + [_containerView addGestureRecognizer:[self touchTrackingRecognizer]]; // Is |currentUrl| a web scheme or native chrome scheme. web::NavigationItem* item = [self currentNavItem];
diff --git a/mash/simple_wm/simple_wm.cc b/mash/simple_wm/simple_wm.cc index b8f98a75..e8c4b45 100644 --- a/mash/simple_wm/simple_wm.cc +++ b/mash/simple_wm/simple_wm.cc
@@ -46,7 +46,7 @@ } ~WindowListModel() override { window_container_->RemoveObserver(this); - for (auto window : windows_) + for (auto* window : windows_) window->RemoveObserver(this); }
diff --git a/media/audio/audio_manager.cc b/media/audio/audio_manager.cc index 47f3ec84..3906b70 100644 --- a/media/audio/audio_manager.cc +++ b/media/audio/audio_manager.cc
@@ -11,9 +11,6 @@ #include "base/bind.h" #include "base/bind_helpers.h" #include "base/command_line.h" -#include "base/debug/alias.h" -#include "base/debug/crash_logging.h" -#include "base/debug/dump_without_crashing.h" #include "base/logging.h" #include "base/macros.h" #include "base/message_loop/message_loop.h" @@ -101,8 +98,6 @@ const std::string& app_name() const { return app_name_; } #endif - void enable_crash_key_logging() { enable_crash_key_logging_ = true; } - private: // base::PowerObserver overrides. // Disable hang detection when the system goes into the suspend state. @@ -159,8 +154,6 @@ successful_pings_ = 0; if (++failed_pings_ >= kMaxFailedPingsCount && audio_thread_status_ < THREAD_HUNG) { - if (enable_crash_key_logging_) - LogAudioDriverCrashKeys(); HistogramThreadStatus(THREAD_HUNG); } } else { @@ -215,25 +208,6 @@ THREAD_MAX + 1); } - void LogAudioDriverCrashKeys() { - DCHECK(monitor_task_runner_->BelongsToCurrentThread()); - DCHECK(enable_crash_key_logging_); - -#if defined(OS_WIN) - std::string driver_name, driver_version; - if (!CoreAudioUtil::GetDxDiagDetails(&driver_name, &driver_version)) - return; - - base::debug::ScopedCrashKey crash_key( - "hung-audio-thread-details", - base::StringPrintf("%s:%s", driver_name.c_str(), - driver_version.c_str())); - - // Please forward crash reports to http://crbug.com/422522 - base::debug::DumpWithoutCrashing(); -#endif - } - FakeAudioLogFactory fake_log_factory_; const base::TimeDelta max_hung_task_time_ = base::TimeDelta::FromMinutes(1); @@ -247,7 +221,6 @@ bool io_task_running_ = false; bool audio_task_running_ = false; ThreadStatus audio_thread_status_ = THREAD_NONE; - bool enable_crash_key_logging_ = false; uint32_t successful_pings_ = 0; #if defined(OS_WIN) @@ -363,12 +336,6 @@ GetHelper()->StartHangTimer(std::move(task_runner)); } -// static -void AudioManager::EnableCrashKeyLoggingForAudioThreadHangs() { - CHECK(!g_last_created); - GetHelper()->enable_crash_key_logging(); -} - #if defined(OS_LINUX) // static void AudioManager::SetGlobalAppName(const std::string& app_name) {
diff --git a/media/audio/audio_manager.h b/media/audio/audio_manager.h index 2826bcd..613df4d 100644 --- a/media/audio/audio_manager.h +++ b/media/audio/audio_manager.h
@@ -39,9 +39,7 @@ // the need to provide iterators over the existing streams. // // Except on OSX, a hang monitor for the audio thread is always created. When a -// thread hang is detected, it is reported to UMA. Optionally, if called prior, -// EnableCrashKeyLoggingForAudioThreadHangs() will cause a non-crash dump to be -// logged on Windows (this allows us to report driver hangs to Microsoft). +// thread hang is detected, it is reported to UMA. class MEDIA_EXPORT AudioManager { public: // Construct the audio manager; only one instance is allowed. @@ -77,13 +75,6 @@ static void StartHangMonitorIfNeeded( scoped_refptr<base::SingleThreadTaskRunner> task_runner); - // Enables non-crash dumps when audio thread hangs are detected. - // TODO(dalecurtis): There are no callers to this function at present. A list - // of bad drivers has been given to Microsoft. This should be re-enabled in - // the future if Microsoft is able to triage third party drivers. - // See http://crbug.com/422522 - static void EnableCrashKeyLoggingForAudioThreadHangs(); - #if defined(OS_LINUX) // Sets the name of the audio source as seen by external apps. Only actually // used with PulseAudio as of this writing.
diff --git a/media/base/BUILD.gn b/media/base/BUILD.gn index 098adc6..b629cada 100644 --- a/media/base/BUILD.gn +++ b/media/base/BUILD.gn
@@ -264,6 +264,7 @@ allow_circular_includes_from = [] defines = [] public_deps = [ + "//media/base:video_facing", "//ppapi/features", "//ui/gfx:color_space", ] @@ -337,6 +338,19 @@ } } +source_set("video_facing") { + visibility = [ + "//chromeos", + "//content/browser", + "//content/public/common:common_sources", + "//media/base", + "//media/capture", + ] + sources = [ + "video_facing.h", + ] +} + static_library("test_support") { testonly = true sources = [
diff --git a/media/base/mime_util.cc b/media/base/mime_util.cc index ba5905d..b21b045 100644 --- a/media/base/mime_util.cc +++ b/media/base/mime_util.cc
@@ -29,10 +29,10 @@ return GetMimeUtil()->IsSupportedMediaFormat(mime_type, codecs, true); } -void ParseCodecString(const std::string& codecs, - std::vector<std::string>* codecs_out, - bool strip) { - GetMimeUtil()->ParseCodecString(codecs, codecs_out, strip); +void SplitCodecsToVector(const std::string& codecs, + std::vector<std::string>* codecs_out, + bool strip) { + GetMimeUtil()->SplitCodecsToVector(codecs, codecs_out, strip); } void RemoveProprietaryMediaTypesAndCodecsForTests() {
diff --git a/media/base/mime_util.h b/media/base/mime_util.h index 6a49eba..d7a39f4 100644 --- a/media/base/mime_util.h +++ b/media/base/mime_util.h
@@ -16,14 +16,14 @@ // supported/recognized MIME types. MEDIA_EXPORT bool IsSupportedMediaMimeType(const std::string& mime_type); -// Parses a codec string, populating |codecs_out| with the prefix of each codec -// in the string |codecs_in|. For example, passed "aaa.b.c,dd.eee", if +// Splits various codecs into |codecs_out|, conditionally stripping the profile +// and level info when |strip| == true. For example, passed "aaa.b.c,dd.eee", if // |strip| == true |codecs_out| will contain {"aaa", "dd"}, if |strip| == false // |codecs_out| will contain {"aaa.b.c", "dd.eee"}. // See http://www.ietf.org/rfc/rfc4281.txt. -MEDIA_EXPORT void ParseCodecString(const std::string& codecs, - std::vector<std::string>* codecs_out, - bool strip); +MEDIA_EXPORT void SplitCodecsToVector(const std::string& codecs, + std::vector<std::string>* codecs_out, + bool strip); // Indicates that the MIME type and (possible codec string) are supported. enum SupportsType {
diff --git a/media/base/mime_util_internal.cc b/media/base/mime_util_internal.cc index 7370198..2172a63 100644 --- a/media/base/mime_util_internal.cc +++ b/media/base/mime_util_internal.cc
@@ -4,6 +4,8 @@ #include "media/base/mime_util_internal.h" +#include <map> + #include "base/command_line.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_split.h" @@ -23,17 +25,11 @@ namespace media { namespace internal { -struct CodecIDMappings { - const char* const codec_id; - MimeUtil::Codec codec; -}; - -// List of codec IDs that provide enough information to determine the -// codec and profile being requested. -// -// The "mp4a" strings come from RFC 6381. -static const CodecIDMappings kUnambiguousCodecStringMap[] = { - {"1", MimeUtil::PCM}, // We only allow this for WAV so it isn't ambiguous. +// Wrapped to avoid static initializer startup cost. +const std::map<std::string, MimeUtil::Codec>& GetStringToCodecMap() { + static const std::map<std::string, MimeUtil::Codec> kStringToCodecMap = { + // We only allow this for WAV so it isn't ambiguous. + {"1", MimeUtil::PCM}, // avc1/avc3.XXXXXX may be unambiguous; handled by ParseAVCCodecId(). // hev1/hvc1.XXXXXX may be unambiguous; handled by ParseHEVCCodecID(). // vp9, vp9.0, vp09.xx.xx.xx.xx.xx.xx.xx may be unambiguous; handled by @@ -48,8 +44,8 @@ // mp4a.40.2 - MPEG-4 AAC LC // mp4a.40.02 - MPEG-4 AAC LC (leading 0 in aud-oti for compatibility) // mp4a.40.5 - MPEG-4 HE-AAC v1 (AAC LC + SBR) - // mp4a.40.05 - MPEG-4 HE-AAC v1 (AAC LC + SBR) (leading 0 in aud-oti for - // compatibility) + // mp4a.40.05 - MPEG-4 HE-AAC v1 (AAC LC + SBR) (leading 0 in aud-oti + // for compatibility) // mp4a.40.29 - MPEG-4 HE-AAC v2 (AAC LC + SBR + PS) {"mp4a.66", MimeUtil::MPEG2_AAC}, {"mp4a.67", MimeUtil::MPEG2_AAC}, @@ -63,10 +59,10 @@ {"mp4a.40.29", MimeUtil::MPEG4_AAC}, #if BUILDFLAG(ENABLE_AC3_EAC3_AUDIO_DEMUXING) // TODO(servolk): Strictly speaking only mp4a.A5 and mp4a.A6 codec ids are - // valid according to RFC 6381 section 3.3, 3.4. Lower-case oti (mp4a.a5 and - // mp4a.a6) should be rejected. But we used to allow those in older versions - // of Chromecast firmware and some apps (notably MPL) depend on those codec - // types being supported, so they should be allowed for now + // valid according to RFC 6381 section 3.3, 3.4. Lower-case oti (mp4a.a5 + // and mp4a.a6) should be rejected. But we used to allow those in older + // versions of Chromecast firmware and some apps (notably MPL) depend on + // those codec types being supported, so they should be allowed for now // (crbug.com/564960). {"ac-3", MimeUtil::AC3}, {"mp4a.a5", MimeUtil::AC3}, @@ -80,18 +76,11 @@ {"flac", MimeUtil::FLAC}, {"vp8", MimeUtil::VP8}, {"vp8.0", MimeUtil::VP8}, - {"theora", MimeUtil::THEORA}}; + {"theora", MimeUtil::THEORA} + }; -// List of codec IDs that are ambiguous and don't provide -// enough information to determine the codec and profile. -// The codec in these entries indicate the codec and profile -// we assume the user is trying to indicate. -static const CodecIDMappings kAmbiguousCodecStringMap[] = { - {"mp4a.40", MimeUtil::MPEG4_AAC}, - {"avc1", MimeUtil::H264}, - {"avc3", MimeUtil::H264}, - // avc1/avc3.XXXXXX may be ambiguous; handled by ParseAVCCodecId(). -}; + return kStringToCodecMap; +} static bool ParseVp9CodecID(const std::string& mime_type_lower_case, const std::string& codec_id, @@ -164,36 +153,56 @@ bool is_encrypted) const { DCHECK(!supported_codecs.empty()); DCHECK(!codecs.empty()); + DCHECK_EQ(base::ToLowerASCII(mime_type_lower_case), mime_type_lower_case); - SupportsType result = IsSupported; + SupportsType combined_result = IsSupported; + for (size_t i = 0; i < codecs.size(); ++i) { - bool is_ambiguous = true; + // Parse the string. + bool ambiguous_codec_string = false; Codec codec = INVALID_CODEC; VideoCodecProfile video_profile = VIDEO_CODEC_PROFILE_UNKNOWN; uint8_t video_level = 0; - if (!StringToCodec(mime_type_lower_case, codecs[i], &codec, &is_ambiguous, - &video_profile, &video_level, is_encrypted)) { + if (!ParseCodecString(mime_type_lower_case, codecs[i], &codec, + &ambiguous_codec_string, &video_profile, + &video_level)) { return IsNotSupported; } - VideoCodec video_codec = MimeUtilToVideoCodec(codec); - - if (GetMediaClient() && video_codec != kUnknownVideoCodec && - !GetMediaClient()->IsSupportedVideoConfig(video_codec, video_profile, - video_level)) { + // Bail if codec not in supported list for given container. + if (supported_codecs.find(codec) == supported_codecs.end()) return IsNotSupported; + + // Make conservative guesses to resolve ambiguity before checking platform + // support. H264 and VP9 are the only allowed ambiguous video codec. DO NOT + // ADD SUPPORT FOR MORE AMIBIGUOUS STRINGS. + if (codec == MimeUtil::H264 && ambiguous_codec_string) { + if (video_profile == VIDEO_CODEC_PROFILE_UNKNOWN) + video_profile = H264PROFILE_BASELINE; + if (!IsValidH264Level(video_level)) + video_level = 10; + } else if (codec == MimeUtil::VP9 && video_level == 0) { + // Original VP9 content type (codecs="vp9") does not specify the level. + // TODO(chcunningham): Mark this string as ambiguous when new multi-part + // VP9 content type is published. + video_level = 10; } - if (!IsCodecSupported(codec, mime_type_lower_case, is_encrypted) || - supported_codecs.find(codec) == supported_codecs.end()) { + // Check platform support. + SupportsType result = IsCodecSupported( + mime_type_lower_case, codec, video_profile, video_level, is_encrypted); + if (result == IsNotSupported) return IsNotSupported; - } - if (is_ambiguous) - result = MayBeSupported; + // If any codec is "MayBeSupported", return Maybe for the combined result. + // Downgrade to MayBeSupported if we had to guess the meaning of one of the + // codec strings. + if (result == MayBeSupported || + (result == IsSupported && ambiguous_codec_string)) + combined_result = MayBeSupported; } - return result; + return combined_result; } void MimeUtil::InitializeMimeTypeMaps() { @@ -201,16 +210,6 @@ allow_proprietary_codecs_ = true; #endif - for (size_t i = 0; i < arraysize(kUnambiguousCodecStringMap); ++i) { - string_to_codec_map_[kUnambiguousCodecStringMap[i].codec_id] = - CodecEntry(kUnambiguousCodecStringMap[i].codec, false); - } - - for (size_t i = 0; i < arraysize(kAmbiguousCodecStringMap); ++i) { - string_to_codec_map_[kAmbiguousCodecStringMap[i].codec_id] = - CodecEntry(kAmbiguousCodecStringMap[i].codec, true); - } - AddSupportedMediaFormats(); } @@ -339,9 +338,9 @@ media_format_map_.end(); } -void MimeUtil::ParseCodecString(const std::string& codecs, - std::vector<std::string>* codecs_out, - bool strip) { +void MimeUtil::SplitCodecsToVector(const std::string& codecs, + std::vector<std::string>* codecs_out, + bool strip) { *codecs_out = base::SplitString(base::TrimString(codecs, "\"", base::TRIM_ALL), ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); @@ -374,10 +373,11 @@ if (it_media_format_map->second.empty()) { // We get here if the mimetype does not expect a codecs parameter. - return (codecs.empty() && IsDefaultCodecSupportedLowerCase( - mime_type_lower_case, is_encrypted)) - ? IsSupported - : IsNotSupported; + if (codecs.empty()) { + return IsDefaultCodecSupported(mime_type_lower_case, is_encrypted); + } else { + return IsNotSupported; + } } if (codecs.empty()) { @@ -386,12 +386,11 @@ // codec the best we can do is say "maybe" because we don't have enough // information. Codec default_codec = INVALID_CODEC; - if (!GetDefaultCodecLowerCase(mime_type_lower_case, &default_codec)) + if (!GetDefaultCodec(mime_type_lower_case, &default_codec)) return MayBeSupported; - return IsCodecSupported(default_codec, mime_type_lower_case, is_encrypted) - ? IsSupported - : IsNotSupported; + return IsSimpleCodecSupported(mime_type_lower_case, default_codec, + is_encrypted); } #if BUILDFLAG(ENABLE_MSE_MPEG2TS_STREAM_PARSER) @@ -416,7 +415,7 @@ } // static -bool MimeUtil::IsCodecSupportedOnPlatform( +bool MimeUtil::IsCodecSupportedOnAndroid( Codec codec, const std::string& mime_type_lower_case, bool is_encrypted, @@ -542,99 +541,156 @@ return false; } -bool MimeUtil::StringToCodec(const std::string& mime_type_lower_case, - const std::string& codec_id, - Codec* codec, - bool* is_ambiguous, - VideoCodecProfile* out_profile, - uint8_t* out_level, - bool is_encrypted) const { +bool MimeUtil::ParseCodecString(const std::string& mime_type_lower_case, + const std::string& codec_id, + Codec* codec, + bool* ambiguous_codec_string, + VideoCodecProfile* out_profile, + uint8_t* out_level) const { + DCHECK_EQ(base::ToLowerASCII(mime_type_lower_case), mime_type_lower_case); + DCHECK(codec); DCHECK(out_profile); DCHECK(out_level); + + *codec = INVALID_CODEC; + *ambiguous_codec_string = false; *out_profile = VIDEO_CODEC_PROFILE_UNKNOWN; *out_level = 0; - StringToCodecMappings::const_iterator itr = - string_to_codec_map_.find(codec_id); - if (itr != string_to_codec_map_.end()) { - *codec = itr->second.codec; - *is_ambiguous = itr->second.is_ambiguous; + std::map<std::string, Codec>::const_iterator itr = + GetStringToCodecMap().find(codec_id); + if (itr != GetStringToCodecMap().end()) { + *codec = itr->second; + return true; } - // If |codec_id| is not in |string_to_codec_map_|, then we assume that it is + // Check codec string against short list of allowed ambiguous codecs. + // Hard-coded to discourage expansion. DO NOT ADD TO THIS LIST. DO NOT + // INCREASE PLACES WHERE |ambiguous_codec_string| = true. + // NOTE: avc1/avc3.XXXXXX may be ambiguous handled after ParseAVCCodecId(). + if (codec_id == "avc1" || codec_id == "avc3") { + *codec = MimeUtil::H264; + *ambiguous_codec_string = true; + return true; + } else if (codec_id == "mp4a.40") { + *codec = MimeUtil::MPEG4_AAC; + *ambiguous_codec_string = true; + return true; + } + + // If |codec_id| is not in |kStringToCodecMap|, then we assume that it is // either VP9, H.264 or HEVC/H.265 codec ID because currently those are the - // only ones that are not added to the |string_to_codec_map_| and require + // only ones that are not added to the |kStringToCodecMap| and require // parsing. if (ParseVp9CodecID(mime_type_lower_case, codec_id, out_profile, out_level)) { *codec = MimeUtil::VP9; - switch (*out_profile) { - case VP9PROFILE_PROFILE0: - // Profile 0 should always be supported if VP9 is supported. - *is_ambiguous = false; - break; - default: - // We don't know if the underlying platform supports these profiles. - // Need to add platform level querying to get supported profiles - // (crbug/604566). - *is_ambiguous = true; - break; - } return true; } if (ParseAVCCodecId(codec_id, out_profile, out_level)) { *codec = MimeUtil::H264; - switch (*out_profile) { -// HIGH10PROFILE is supported through fallback to the ffmpeg decoder -// which is not available on Android, or if FFMPEG is not used. -#if !defined(MEDIA_DISABLE_FFMPEG) && !defined(OS_ANDROID) - case H264PROFILE_HIGH10PROFILE: - if (is_encrypted) { - // FFmpeg is not generally used for encrypted videos, so we do not - // know whether 10-bit is supported. - *is_ambiguous = true; - break; - } -// Fall through. -#endif - - case H264PROFILE_BASELINE: - case H264PROFILE_MAIN: - case H264PROFILE_HIGH: - *is_ambiguous = !IsValidH264Level(*out_level); - break; - default: - *is_ambiguous = true; - } + // Allowed string ambiguity since 2014. DO NOT ADD NEW CASES FOR AMBIGUITY. + *ambiguous_codec_string = !IsValidH264Level(*out_level); return true; } #if BUILDFLAG(ENABLE_HEVC_DEMUXING) if (ParseHEVCCodecId(codec_id, out_profile, out_level)) { *codec = MimeUtil::HEVC; - *is_ambiguous = false; return true; } #endif - DVLOG(4) << __func__ << ": Unrecognized codec id " << codec_id; + DVLOG(2) << __func__ << ": Unrecognized codec id " << codec_id; return false; } -bool MimeUtil::IsCodecSupported(Codec codec, - const std::string& mime_type_lower_case, - bool is_encrypted) const { +SupportsType MimeUtil::IsSimpleCodecSupported( + const std::string& mime_type_lower_case, + Codec codec, + bool is_encrypted) const { + // Video codecs are not "simple" because they require a profile and level to + // be specified. There is no "default" video codec for a given container. + DCHECK_EQ(MimeUtilToVideoCodec(codec), kUnknownVideoCodec); + + SupportsType result = + IsCodecSupported(mime_type_lower_case, codec, VIDEO_CODEC_PROFILE_UNKNOWN, + 0 /* video_level */, is_encrypted); + + // Platform support should never be ambiguous for simple codecs (no range of + // profiles to consider). + DCHECK_NE(result, MayBeSupported); + return result; +} + +SupportsType MimeUtil::IsCodecSupported(const std::string& mime_type_lower_case, + Codec codec, + VideoCodecProfile video_profile, + uint8_t video_level, + bool is_encrypted) const { + DCHECK_EQ(base::ToLowerASCII(mime_type_lower_case), mime_type_lower_case); DCHECK_NE(codec, INVALID_CODEC); + VideoCodec video_codec = MimeUtilToVideoCodec(codec); + if (video_codec != kUnknownVideoCodec && + // Theora and VP8 do not have profiles/levels. + video_codec != kCodecTheora && video_codec != kCodecVP8) { + DCHECK_NE(video_profile, VIDEO_CODEC_PROFILE_UNKNOWN); + DCHECK_GT(video_level, 0); + } + + // Bail early for disabled proprietary codecs + if (!allow_proprietary_codecs_ && IsCodecProprietary(codec)) { + return IsNotSupported; + } + + // Check for cases of ambiguous platform support. + // TODO(chcunningham): DELETE THIS. Platform should know its capabilities. + // Answer should come from MediaClient. + bool ambiguous_platform_support = false; + if (codec == MimeUtil::H264) { + switch (video_profile) { + // Always supported + case H264PROFILE_BASELINE: + case H264PROFILE_MAIN: + case H264PROFILE_HIGH: + break; +// HIGH10PROFILE is supported through fallback to the ffmpeg decoder +// which is not available on Android, or if FFMPEG is not used. +#if !defined(MEDIA_DISABLE_FFMPEG) && !defined(OS_ANDROID) + case H264PROFILE_HIGH10PROFILE: + // FFmpeg is not generally used for encrypted videos, so we do not + // know whether 10-bit is supported. + ambiguous_platform_support = is_encrypted; + break; +#endif + default: + ambiguous_platform_support = true; + } + } else if (codec == MimeUtil::VP9 && video_profile != VP9PROFILE_PROFILE0) { + // We don't know if the underlying platform supports these profiles. Need + // to add platform level querying to get supported profiles. + // https://crbug.com/604566 + ambiguous_platform_support = true; + } + + if (GetMediaClient() && video_codec != kUnknownVideoCodec && + !GetMediaClient()->IsSupportedVideoConfig(video_codec, video_profile, + video_level)) { + return IsNotSupported; + } + #if defined(OS_ANDROID) - if (!IsCodecSupportedOnPlatform(codec, mime_type_lower_case, is_encrypted, - platform_info_)) { - return false; + // TODO(chcunningham): Delete this. Android platform support should be + // handled by (android specific) MediaClient. + if (!IsCodecSupportedOnAndroid(codec, mime_type_lower_case, is_encrypted, + platform_info_)) { + return IsNotSupported; } #endif - return allow_proprietary_codecs_ || !IsCodecProprietary(codec); + return ambiguous_platform_support ? MayBeSupported : IsSupported; } bool MimeUtil::IsCodecProprietary(Codec codec) const { @@ -662,21 +718,20 @@ return true; } -bool MimeUtil::GetDefaultCodecLowerCase(const std::string& mime_type_lower_case, - Codec* default_codec) const { - if (mime_type_lower_case == "audio/mpeg" || - mime_type_lower_case == "audio/mp3" || - mime_type_lower_case == "audio/x-mp3") { +bool MimeUtil::GetDefaultCodec(const std::string& mime_type, + Codec* default_codec) const { + if (mime_type == "audio/mpeg" || mime_type == "audio/mp3" || + mime_type == "audio/x-mp3") { *default_codec = MimeUtil::MP3; return true; } - if (mime_type_lower_case == "audio/aac") { + if (mime_type == "audio/aac") { *default_codec = MimeUtil::MPEG4_AAC; return true; } - if (mime_type_lower_case == "audio/flac") { + if (mime_type == "audio/flac") { *default_codec = MimeUtil::FLAC; return true; } @@ -684,13 +739,12 @@ return false; } -bool MimeUtil::IsDefaultCodecSupportedLowerCase( - const std::string& mime_type_lower_case, - bool is_encrypted) const { +SupportsType MimeUtil::IsDefaultCodecSupported(const std::string& mime_type, + bool is_encrypted) const { Codec default_codec = Codec::INVALID_CODEC; - if (!GetDefaultCodecLowerCase(mime_type_lower_case, &default_codec)) - return false; - return IsCodecSupported(default_codec, mime_type_lower_case, is_encrypted); + if (!GetDefaultCodec(mime_type, &default_codec)) + return IsNotSupported; + return IsSimpleCodecSupported(mime_type, default_codec, is_encrypted); } } // namespace internal
diff --git a/media/base/mime_util_internal.h b/media/base/mime_util_internal.h index e853b89..b0f724e1 100644 --- a/media/base/mime_util_internal.h +++ b/media/base/mime_util_internal.h
@@ -56,36 +56,28 @@ // See mime_util.h for more information on these methods. bool IsSupportedMediaMimeType(const std::string& mime_type) const; - void ParseCodecString(const std::string& codecs, - std::vector<std::string>* codecs_out, - bool strip); + void SplitCodecsToVector(const std::string& codecs, + std::vector<std::string>* codecs_out, + bool strip); SupportsType IsSupportedMediaFormat(const std::string& mime_type, const std::vector<std::string>& codecs, bool is_encrypted) const; void RemoveProprietaryMediaTypesAndCodecs(); - // Checks special platform specific codec restrictions. Returns true if + // Checks android platform specific codec restrictions. Returns true if // |codec| is supported when contained in |mime_type_lower_case|. // |is_encrypted| means the codec will be used with encrypted blocks. // |platform_info| describes the availability of various platform features; // see PlatformInfo for more details. - static bool IsCodecSupportedOnPlatform( - Codec codec, - const std::string& mime_type_lower_case, - bool is_encrypted, - const PlatformInfo& platform_info); + static bool IsCodecSupportedOnAndroid(Codec codec, + const std::string& mime_type_lower_case, + bool is_encrypted, + const PlatformInfo& platform_info); private: typedef base::hash_set<int> CodecSet; typedef std::map<std::string, CodecSet> MediaFormatMappings; - struct CodecEntry { - CodecEntry() : codec(INVALID_CODEC), is_ambiguous(true) {} - CodecEntry(Codec c, bool ambiguous) : codec(c), is_ambiguous(ambiguous) {} - Codec codec; - bool is_ambiguous; - }; - typedef std::map<std::string, CodecEntry> StringToCodecMappings; // Initializes the supported media types into hash sets for faster lookup. void InitializeMimeTypeMaps(); @@ -109,48 +101,60 @@ const std::string& mime_type_lower_case, bool is_encrypted) const; - // Converts a codec ID into an Codec enum value and indicates - // whether the conversion was ambiguous. + // Converts a codec ID into an Codec enum value and attempts to output the + // |out_profile| and |out_level|. // Returns true if this method was able to map |codec_id| with - // |mime_type_lower_case| to a specific Codec enum value. |codec| and - // |is_ambiguous| are only valid if true is returned. Otherwise their value is - // undefined after the call. - // |is_ambiguous| is true if |codec_id| did not have enough information to - // unambiguously determine the proper Codec enum value. If |is_ambiguous| - // is true |codec| contains the best guess for the intended Codec enum value. + // |mime_type_lower_case| to a specific Codec enum value. |codec| is only + // valid if true is returned. + // |ambiguous_codec_string| will be set to true when the codec string matches + // one of a small number of non-RFC compliant strings (e.g. "avc"). // |profile| and |level| indicate video codec profile and level (unused for - // audio codecs). + // audio codecs). These will be VIDEO_CODEC_PROFILE_UNKNOWN and 0 respectively + // whenever |codec_id| is incomplete/invalid, or in some cases when + // |ambiguous_codec_string| is set to true. // |is_encrypted| means the codec will be used with encrypted blocks. - bool StringToCodec(const std::string& mime_type_lower_case, - const std::string& codec_id, - Codec* codec, - bool* is_ambiguous, - VideoCodecProfile* out_profile, - uint8_t* out_level, - bool is_encrypted) const; + bool ParseCodecString(const std::string& mime_type_lower_case, + const std::string& codec_id, + Codec* codec, + bool* ambiguous_codec_string, + VideoCodecProfile* out_profile, + uint8_t* out_level) const; - // Returns true if |codec| is supported when contained in - // |mime_type_lower_case|. Note: This method will always return false for - // proprietary codecs if |allow_proprietary_codecs_| is set to false. - // |is_encrypted| means the codec will be used with encrypted blocks. - bool IsCodecSupported(Codec codec, - const std::string& mime_type_lower_case, - bool is_encrypted) const; + // Returns IsSupported if |codec| when platform supports codec contained in + // |mime_type_lower_case|. Returns MayBeSupported when platform support is + // unclear. Otherwise returns NotSupported. Note: This method will always + // return NotSupported for proprietary codecs if |allow_proprietary_codecs_| + // is set to false. |is_encrypted| means the codec will be used with encrypted + // blocks. + // TODO(chcunningham): Make this method return a bool. Platform support should + // always be knowable for a fully specified codec. + SupportsType IsCodecSupported(const std::string& mime_type_lower_case, + Codec codec, + VideoCodecProfile video_profile, + uint8_t video_level, + bool is_encrypted) const; + + // Wrapper around IsCodecSupported for simple codecs that are entirely + // described (or implied) by the container mime-type. + SupportsType IsSimpleCodecSupported(const std::string& mime_type_lower_case, + Codec codec, + bool is_encrypted) const; // Returns true if |codec| refers to a proprietary codec. bool IsCodecProprietary(Codec codec) const; - // Returns true and sets |*default_codec| if |mime_type| has a default codec - // associated with it. Returns false otherwise and the value of + // Returns true and sets |*default_codec| if |mime_type_lower_case| has a + // default codec associated with it. Returns false otherwise and the value of // |*default_codec| is undefined. - bool GetDefaultCodecLowerCase(const std::string& mime_type_lower_case, - Codec* default_codec) const; + bool GetDefaultCodec(const std::string& mime_type_lower_case, + Codec* default_codec) const; - // Returns true if |mime_type_lower_case| has a default codec associated with - // it and IsCodecSupported() returns true for that particular codec. - // |is_encrypted| means the codec will be used with encrypted blocks. - bool IsDefaultCodecSupportedLowerCase(const std::string& mime_type_lower_case, - bool is_encrypted) const; + // Returns IsSupported if |mime_type_lower_case| has a default codec + // associated with it and IsCodecSupported() returns IsSupported for that + // particular codec. |is_encrypted| means the codec will be used with + // encrypted blocks. + SupportsType IsDefaultCodecSupported(const std::string& mime_type_lower_case, + bool is_encrypted) const; #if defined(OS_ANDROID) // Indicates the support of various codecs within the platform. @@ -165,9 +169,6 @@ // Whether proprietary codec support should be advertised to callers. bool allow_proprietary_codecs_; - // Lookup table for string compare based string -> Codec mappings. - StringToCodecMappings string_to_codec_map_; - DISALLOW_COPY_AND_ASSIGN(MimeUtil); };
diff --git a/media/base/mime_util_unittest.cc b/media/base/mime_util_unittest.cc index 99be40b5..280e9e08 100644 --- a/media/base/mime_util_unittest.cc +++ b/media/base/mime_util_unittest.cc
@@ -20,7 +20,7 @@ namespace media { namespace internal { -// MIME type for use with IsCodecSupportedOnPlatform() test; type is ignored in +// MIME type for use with IsCodecSupportedOnAndroid() test; type is ignored in // all cases except for when paired with the Opus codec. const char kTestMimeType[] = "foo/foo"; @@ -35,7 +35,7 @@ return std::vector<bool>(1, single_value); } -// Helper method for running IsCodecSupportedOnPlatform() tests that will +// Helper method for running IsCodecSupportedOnAndroid() tests that will // iterate over all possible field values for a MimeUtil::PlatformInfo struct. // // To request a field be varied, set its value to true in the |states_to_vary| @@ -179,7 +179,7 @@ // Note: codecs should only be a list of 2 or fewer; hence the restriction of // results' length to 2. -TEST(MimeUtilTest, ParseCodecString) { +TEST(MimeUtilTest, SplitCodecsToVector) { const struct { const char* const original; size_t expected_size; @@ -199,7 +199,7 @@ for (size_t i = 0; i < arraysize(tests); ++i) { std::vector<std::string> codecs_out; - ParseCodecString(tests[i].original, &codecs_out, true); + SplitCodecsToVector(tests[i].original, &codecs_out, true); ASSERT_EQ(tests[i].expected_size, codecs_out.size()); for (size_t j = 0; j < tests[i].expected_size; ++j) EXPECT_EQ(tests[i].results[j], codecs_out[j]); @@ -207,14 +207,13 @@ // Test without stripping the codec type. std::vector<std::string> codecs_out; - ParseCodecString("avc1.42E01E, mp4a.40.2", &codecs_out, false); + SplitCodecsToVector("avc1.42E01E, mp4a.40.2", &codecs_out, false); ASSERT_EQ(2u, codecs_out.size()); EXPECT_EQ("avc1.42E01E", codecs_out[0]); EXPECT_EQ("mp4a.40.2", codecs_out[1]); } -TEST(IsCodecSupportedOnPlatformTest, - EncryptedCodecsFailWithoutPlatformSupport) { +TEST(IsCodecSupportedOnAndroidTest, EncryptedCodecsFailWithoutPlatformSupport) { // Vary all parameters except |has_platform_decoders|. MimeUtil::PlatformInfo states_to_vary = VaryAllFields(); states_to_vary.has_platform_decoders = false; @@ -228,12 +227,12 @@ RunCodecSupportTest( states_to_vary, test_states, [](const MimeUtil::PlatformInfo& info, MimeUtil::Codec codec) { - EXPECT_FALSE(MimeUtil::IsCodecSupportedOnPlatform(codec, kTestMimeType, - true, info)); + EXPECT_FALSE(MimeUtil::IsCodecSupportedOnAndroid(codec, kTestMimeType, + true, info)); }); } -TEST(IsCodecSupportedOnPlatformTest, EncryptedCodecBehavior) { +TEST(IsCodecSupportedOnAndroidTest, EncryptedCodecBehavior) { // Vary all parameters except |has_platform_decoders|. MimeUtil::PlatformInfo states_to_vary = VaryAllFields(); states_to_vary.has_platform_decoders = false; @@ -245,7 +244,7 @@ RunCodecSupportTest( states_to_vary, test_states, [](const MimeUtil::PlatformInfo& info, MimeUtil::Codec codec) { - const bool result = MimeUtil::IsCodecSupportedOnPlatform( + const bool result = MimeUtil::IsCodecSupportedOnAndroid( codec, kTestMimeType, true, info); switch (codec) { // These codecs are never supported by the Android platform. @@ -288,7 +287,7 @@ }); } -TEST(IsCodecSupportedOnPlatformTest, ClearCodecBehavior) { +TEST(IsCodecSupportedOnAndroidTest, ClearCodecBehavior) { MimeUtil::PlatformInfo states_to_vary = VaryAllFields(); MimeUtil::PlatformInfo test_states; @@ -296,7 +295,7 @@ RunCodecSupportTest( states_to_vary, test_states, [](const MimeUtil::PlatformInfo& info, MimeUtil::Codec codec) { - const bool result = MimeUtil::IsCodecSupportedOnPlatform( + const bool result = MimeUtil::IsCodecSupportedOnAndroid( codec, kTestMimeType, false, info); switch (codec) { // These codecs are never supported by the Android platform. @@ -332,7 +331,7 @@ }); } -TEST(IsCodecSupportedOnPlatformTest, OpusOggSupport) { +TEST(IsCodecSupportedOnAndroidTest, OpusOggSupport) { // Vary all parameters; thus use default initial state. MimeUtil::PlatformInfo states_to_vary = VaryAllFields(); MimeUtil::PlatformInfo test_states; @@ -340,12 +339,12 @@ RunCodecSupportTest( states_to_vary, test_states, [](const MimeUtil::PlatformInfo& info, MimeUtil::Codec codec) { - EXPECT_TRUE(MimeUtil::IsCodecSupportedOnPlatform( + EXPECT_TRUE(MimeUtil::IsCodecSupportedOnAndroid( MimeUtil::OPUS, "audio/ogg", false, info)); }); } -TEST(IsCodecSupportedOnPlatformTest, HLSDoesNotSupportMPEG2AAC) { +TEST(IsCodecSupportedOnAndroidTest, HLSDoesNotSupportMPEG2AAC) { // Vary all parameters; thus use default initial state. MimeUtil::PlatformInfo states_to_vary = VaryAllFields(); MimeUtil::PlatformInfo test_states; @@ -353,13 +352,13 @@ RunCodecSupportTest( states_to_vary, test_states, [](const MimeUtil::PlatformInfo& info, MimeUtil::Codec codec) { - EXPECT_FALSE(MimeUtil::IsCodecSupportedOnPlatform( + EXPECT_FALSE(MimeUtil::IsCodecSupportedOnAndroid( MimeUtil::MPEG2_AAC, "application/x-mpegurl", false, info)); - EXPECT_FALSE(MimeUtil::IsCodecSupportedOnPlatform( + EXPECT_FALSE(MimeUtil::IsCodecSupportedOnAndroid( MimeUtil::MPEG2_AAC, "application/vnd.apple.mpegurl", false, info)); - EXPECT_FALSE(MimeUtil::IsCodecSupportedOnPlatform( + EXPECT_FALSE(MimeUtil::IsCodecSupportedOnAndroid( MimeUtil::MPEG2_AAC, "audio/mpegurl", false, info)); - EXPECT_FALSE(MimeUtil::IsCodecSupportedOnPlatform( + EXPECT_FALSE(MimeUtil::IsCodecSupportedOnAndroid( MimeUtil::MPEG2_AAC, "audio/x-mpegurl", false, info)); }); }
diff --git a/media/base/video_facing.h b/media/base/video_facing.h index 9bd0b50e..bf354c2 100644 --- a/media/base/video_facing.h +++ b/media/base/video_facing.h
@@ -13,7 +13,16 @@ MEDIA_VIDEO_FACING_USER, MEDIA_VIDEO_FACING_ENVIRONMENT, - NUM_MEDIA_VIDEO_FACING_MODE + NUM_MEDIA_VIDEO_FACING_MODES +}; + +// Clients interested in video capture events can implement this interface +// and register the observers to MediaStreamManager or VideoCaptureManager. +class VideoCaptureObserver { + public: + virtual ~VideoCaptureObserver() {} + virtual void OnVideoCaptureStarted(VideoFacingMode facing) = 0; + virtual void OnVideoCaptureStopped(VideoFacingMode facing) = 0; }; } // namespace media
diff --git a/media/blink/key_system_config_selector.cc b/media/blink/key_system_config_selector.cc index 5799869..7f35733 100644 --- a/media/blink/key_system_config_selector.cc +++ b/media/blink/key_system_config_selector.cc
@@ -299,7 +299,7 @@ const std::string& codecs, bool use_aes_decryptor) { std::vector<std::string> codec_vector; - ParseCodecString(codecs, &codec_vector, false); + SplitCodecsToVector(codecs, &codec_vector, false); // AesDecryptor decrypts the stream in the demuxer before it reaches the // decoder so check whether the media format is supported when clear. SupportsType support_result = @@ -339,7 +339,7 @@ // This check does not handle extended codecs, so extended codec information // is stripped (extended codec information was checked above). std::vector<std::string> stripped_codec_vector; - ParseCodecString(codecs, &stripped_codec_vector, true); + SplitCodecsToVector(codecs, &stripped_codec_vector, true); EmeConfigRule codecs_rule = key_systems_->GetContentTypeConfigRule( key_system, media_type, container_lower, stripped_codec_vector); if (!config_state->IsRuleSupported(codecs_rule))
diff --git a/media/capture/video/fake_video_capture_device_unittest.cc b/media/capture/video/fake_video_capture_device_unittest.cc index 5a6974ca..67e67e7 100644 --- a/media/capture/video/fake_video_capture_device_unittest.cc +++ b/media/capture/video/fake_video_capture_device_unittest.cc
@@ -89,7 +89,7 @@ VideoCaptureDevice::Client::Buffer CreateStubBuffer(int buffer_id, size_t mapped_size) { - auto buffer = new uint8_t[mapped_size]; + auto* buffer = new uint8_t[mapped_size]; const int arbitrary_frame_feedback_id = 0; return VideoCaptureDevice::Client::Buffer( buffer_id, arbitrary_frame_feedback_id,
diff --git a/media/capture/video/video_capture_device_descriptor.cc b/media/capture/video/video_capture_device_descriptor.cc index 3a259543..7011608 100644 --- a/media/capture/video/video_capture_device_descriptor.cc +++ b/media/capture/video/video_capture_device_descriptor.cc
@@ -45,7 +45,7 @@ bool VideoCaptureDeviceDescriptor::operator<( const VideoCaptureDeviceDescriptor& other) const { - static constexpr int kFacingMapping[NUM_MEDIA_VIDEO_FACING_MODE] = {0, 2, 1}; + static constexpr int kFacingMapping[NUM_MEDIA_VIDEO_FACING_MODES] = {0, 2, 1}; static_assert(kFacingMapping[MEDIA_VIDEO_FACING_NONE] == 0, "FACING_NONE has a wrong value"); static_assert(kFacingMapping[MEDIA_VIDEO_FACING_ENVIRONMENT] == 1,
diff --git a/media/filters/chunk_demuxer.cc b/media/filters/chunk_demuxer.cc index 177a8194..42cafad 100644 --- a/media/filters/chunk_demuxer.cc +++ b/media/filters/chunk_demuxer.cc
@@ -587,7 +587,7 @@ return kReachedIdLimit; std::vector<std::string> parsed_codec_ids; - media::ParseCodecString(codecs, &parsed_codec_ids, false); + media::SplitCodecsToVector(codecs, &parsed_codec_ids, false); std::unique_ptr<media::StreamParser> stream_parser( StreamParserFactory::Create(type, parsed_codec_ids, media_log_)); @@ -711,7 +711,7 @@ stream->set_enabled(false, currTime); } } - for (const auto& stream : enabled_streams) { + for (auto* stream : enabled_streams) { DVLOG(1) << __func__ << ": enabling stream " << stream; stream->set_enabled(true, currTime); }
diff --git a/media/filters/ffmpeg_demuxer.cc b/media/filters/ffmpeg_demuxer.cc index d714603..424fce8 100644 --- a/media/filters/ffmpeg_demuxer.cc +++ b/media/filters/ffmpeg_demuxer.cc
@@ -1654,7 +1654,7 @@ stream->set_enabled(false, currTime); } } - for (const auto& stream : enabled_streams) { + for (auto* stream : enabled_streams) { DCHECK(stream); DVLOG(1) << __func__ << ": enabling stream " << stream; stream->set_enabled(true, currTime);
diff --git a/media/filters/gpu_video_decoder.cc b/media/filters/gpu_video_decoder.cc index 6a2420a..627d54c 100644 --- a/media/filters/gpu_video_decoder.cc +++ b/media/filters/gpu_video_decoder.cc
@@ -361,6 +361,7 @@ vda_config.encryption_scheme = config_.encryption_scheme(); vda_config.is_deferred_initialization_allowed = true; vda_config.initial_expected_coded_size = config_.coded_size(); + vda_config.color_space = config_.color_space_info(); #if defined(OS_ANDROID) && BUILDFLAG(USE_PROPRIETARY_CODECS) // We pass the SPS and PPS on Android because it lets us initialize @@ -897,14 +898,12 @@ bool is_encrypted) { DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); for (const auto& supported_profile : capabilities.supported_profiles) { - if (profile == supported_profile.profile) { - if (supported_profile.encrypted_only && !is_encrypted) - continue; - - return IsCodedSizeSupported(coded_size, - supported_profile.min_resolution, - supported_profile.max_resolution); - } + if (profile != supported_profile.profile || + (supported_profile.encrypted_only && !is_encrypted) || + !IsCodedSizeSupported(coded_size, supported_profile.min_resolution, + supported_profile.max_resolution)) + continue; + return true; } return false; }
diff --git a/media/filters/h264_parser.cc b/media/filters/h264_parser.cc index c0887fd..b5ebf48 100644 --- a/media/filters/h264_parser.cc +++ b/media/filters/h264_parser.cc
@@ -130,12 +130,7 @@ video_full_range_flag ? gfx::ColorSpace::RangeID::FULL : gfx::ColorSpace::RangeID::LIMITED); } else { - // TODO(ccameron/hubbe): Add a uniform way to handle default video frames. - return gfx::ColorSpace( - gfx::ColorSpace::PrimaryID::BT709, gfx::ColorSpace::TransferID::BT709, - gfx::ColorSpace::MatrixID::BT709, - video_full_range_flag ? gfx::ColorSpace::RangeID::FULL - : gfx::ColorSpace::RangeID::LIMITED); + return gfx::ColorSpace(); } }
diff --git a/media/filters/source_buffer_state.cc b/media/filters/source_buffer_state.cc index 868abd7..30436e8b 100644 --- a/media/filters/source_buffer_state.cc +++ b/media/filters/source_buffer_state.cc
@@ -146,7 +146,7 @@ init_cb_ = init_cb; std::vector<std::string> expected_codecs_parsed; - ParseCodecString(expected_codecs, &expected_codecs_parsed, false); + SplitCodecsToVector(expected_codecs, &expected_codecs_parsed, false); std::vector<AudioCodec> expected_acodecs; std::vector<VideoCodec> expected_vcodecs; @@ -795,7 +795,7 @@ } void SourceBufferState::SetStreamMemoryLimits() { - auto cmd_line = base::CommandLine::ForCurrentProcess(); + auto* cmd_line = base::CommandLine::ForCurrentProcess(); std::string audio_buf_limit_switch = cmd_line->GetSwitchValueASCII(switches::kMSEAudioBufferSizeLimit);
diff --git a/media/gpu/dxva_video_decode_accelerator_win.cc b/media/gpu/dxva_video_decode_accelerator_win.cc index a3ebb2d1..7d0963b1 100644 --- a/media/gpu/dxva_video_decode_accelerator_win.cc +++ b/media/gpu/dxva_video_decode_accelerator_win.cc
@@ -2130,7 +2130,10 @@ // Attempt to retrieve an output frame from the decoder. If we have one, // return and proceed when the output frame is processed. If we don't have a // frame then we are done. - DoDecode(config_change_detector_->current_color_space()); + gfx::ColorSpace color_space = config_change_detector_->current_color_space(); + if (!color_space.IsValid()) + color_space = config_.color_space; + DoDecode(color_space); if (OutputSamplesPresent()) return; @@ -2180,6 +2183,8 @@ } gfx::ColorSpace color_space = config_change_detector_->current_color_space(); + if (!color_space.IsValid()) + color_space = config_.color_space; if (!inputs_before_decode_) { TRACE_EVENT_ASYNC_BEGIN0("gpu", "DXVAVideoDecodeAccelerator.Decoding",
diff --git a/media/gpu/ipc/common/media_param_traits_macros.h b/media/gpu/ipc/common/media_param_traits_macros.h index 6904202..b77189c 100644 --- a/media/gpu/ipc/common/media_param_traits_macros.h +++ b/media/gpu/ipc/common/media_param_traits_macros.h
@@ -12,6 +12,7 @@ #include "media/video/jpeg_decode_accelerator.h" #include "media/video/video_decode_accelerator.h" #include "media/video/video_encode_accelerator.h" +#include "ui/gfx/ipc/color/gfx_param_traits.h" #include "ui/gfx/ipc/geometry/gfx_param_traits.h" IPC_ENUM_TRAITS_MAX_VALUE(media::JpegDecodeAccelerator::Error, @@ -29,6 +30,7 @@ IPC_STRUCT_TRAITS_MEMBER(supported_output_formats) IPC_STRUCT_TRAITS_MEMBER(sps) IPC_STRUCT_TRAITS_MEMBER(pps) + IPC_STRUCT_TRAITS_MEMBER(color_space) IPC_STRUCT_TRAITS_END() IPC_STRUCT_TRAITS_BEGIN(media::CreateVideoEncoderParams)
diff --git a/media/remoting/proto_utils.cc b/media/remoting/proto_utils.cc index 30114d0..3431f3e 100644 --- a/media/remoting/proto_utils.cc +++ b/media/remoting/proto_utils.cc
@@ -358,7 +358,7 @@ void ConvertCdmKeyInfoToProto( const CdmKeysInfo& keys_information, pb::CdmClientOnSessionKeysChange* key_change_message) { - for (const auto& info : keys_information) { + for (auto* info : keys_information) { pb::CdmKeyInformation* key = key_change_message->add_key_information(); key->set_key_id(info->key_id.data(), info->key_id.size()); key->set_status(ToProtoCdmKeyInformation(info->status).value());
diff --git a/media/video/video_decode_accelerator.h b/media/video/video_decode_accelerator.h index ff180076..97af30bb 100644 --- a/media/video/video_decode_accelerator.h +++ b/media/video/video_decode_accelerator.h
@@ -169,6 +169,9 @@ // Each SPS and PPS is prefixed with the Annex B framing bytes: 0, 0, 0, 1. std::vector<uint8_t> sps; std::vector<uint8_t> pps; + + // Color space specified by the container. + gfx::ColorSpace color_space; }; // Interface for collaborating with picture interface to provide memory for
diff --git a/mojo/public/cpp/bindings/lib/message.cc b/mojo/public/cpp/bindings/lib/message.cc index be19cf3..68337d1 100644 --- a/mojo/public/cpp/bindings/lib/message.cc +++ b/mojo/public/cpp/bindings/lib/message.cc
@@ -106,13 +106,13 @@ } uint32_t Message::payload_num_interface_ids() const { - auto array_pointer = + auto* array_pointer = version() < 2 ? nullptr : header_v2()->payload_interface_ids.Get(); return array_pointer ? static_cast<uint32_t>(array_pointer->size()) : 0; } const uint32_t* Message::payload_interface_ids() const { - auto array_pointer = + auto* array_pointer = version() < 2 ? nullptr : header_v2()->payload_interface_ids.Get(); return array_pointer ? array_pointer->storage() : nullptr; } @@ -174,7 +174,7 @@ DCHECK(header_v2()->payload_interface_ids.is_null()); size_t size = associated_endpoint_handles_.size(); - auto data = internal::Array_Data<uint32_t>::New(size, buffer()); + auto* data = internal::Array_Data<uint32_t>::New(size, buffer()); header_v2()->payload_interface_ids.Set(data); for (size_t i = 0; i < size; ++i) {
diff --git a/mojo/public/cpp/bindings/lib/message_header_validator.cc b/mojo/public/cpp/bindings/lib/message_header_validator.cc index 56be241..9f8c6278 100644 --- a/mojo/public/cpp/bindings/lib/message_header_validator.cc +++ b/mojo/public/cpp/bindings/lib/message_header_validator.cc
@@ -64,7 +64,7 @@ if (header->version < 2) return true; - auto header_v2 = static_cast<const internal::MessageHeaderV2*>(header); + auto* header_v2 = static_cast<const internal::MessageHeaderV2*>(header); // For the payload pointer: // - Check that the pointer can be safely decoded. // - Claim one byte that the pointer points to. It makes sure not only the
diff --git a/net/cookies/cookie_monster.cc b/net/cookies/cookie_monster.cc index 59a9924..2272d7b0 100644 --- a/net/cookies/cookie_monster.cc +++ b/net/cookies/cookie_monster.cc
@@ -1099,7 +1099,7 @@ CookieList cookie_list; cookie_list.reserve(cookie_ptrs.size()); - for (const auto& cookie_ptr : cookie_ptrs) + for (auto* cookie_ptr : cookie_ptrs) cookie_list.push_back(*cookie_ptr); return cookie_list;
diff --git a/net/cookies/cookie_util_unittest.cc b/net/cookies/cookie_util_unittest.cc index 8ca3acaf..384527a0 100644 --- a/net/cookies/cookie_util_unittest.cc +++ b/net/cookies/cookie_util_unittest.cc
@@ -158,7 +158,7 @@ "2039 April 15 21:01:22", "2038 April 15 21:01:22", }; - for (const auto& test : kTests) { + for (auto* test : kTests) { base::Time parsed_time = cookie_util::ParseCookieExpirationTime(test); EXPECT_FALSE(parsed_time.is_null()); @@ -183,7 +183,7 @@ "1969 March 3 21:01:22", "1600 April 15 21:01:22", }; - for (const auto& test : kTests) { + for (auto* test : kTests) { base::Time parsed_time = cookie_util::ParseCookieExpirationTime(test); EXPECT_FALSE(parsed_time.is_null());
diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc index edc71ff..c7a93f0 100644 --- a/net/http/http_network_transaction_unittest.cc +++ b/net/http/http_network_transaction_unittest.cc
@@ -136,7 +136,7 @@ void UnthrottleAllRequests() { std::set<TestThrottle*> outstanding_throttles_copy(outstanding_throttles_); - for (auto& throttle : outstanding_throttles_copy) { + for (auto* throttle : outstanding_throttles_copy) { if (throttle->IsBlocked()) throttle->Unthrottle(); }
diff --git a/net/http/http_response_headers_unittest.cc b/net/http/http_response_headers_unittest.cc index 0c960af..3e0c251 100644 --- a/net/http/http_response_headers_unittest.cc +++ b/net/http/http_response_headers_unittest.cc
@@ -1819,7 +1819,7 @@ new HttpResponseHeaders(orig_headers)); std::unordered_set<std::string> to_remove; - for (const auto& header : test.to_remove) { + for (auto* header : test.to_remove) { if (header) to_remove.insert(header); }
diff --git a/net/http/http_stream_factory_impl_job_controller_unittest.cc b/net/http/http_stream_factory_impl_job_controller_unittest.cc index bb55d6ea..4fc8545c 100644 --- a/net/http/http_stream_factory_impl_job_controller_unittest.cc +++ b/net/http/http_stream_factory_impl_job_controller_unittest.cc
@@ -115,12 +115,6 @@ class JobControllerPeer { public: - static void VerifyWaitingTimeForMainJob( - HttpStreamFactoryImpl::JobController* job_controller, - const base::TimeDelta& delay) { - EXPECT_EQ(delay, job_controller->main_job_wait_time_); - } - static bool main_job_is_blocked( HttpStreamFactoryImpl::JobController* job_controller) { return job_controller->main_job_is_blocked_; @@ -940,7 +934,7 @@ job_controller_->OnStreamFailed(job_factory_.alternative_job(), ERR_NETWORK_CHANGED, SSLConfig()); EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount()); - test_task_runner->RunUntilIdle(); + test_task_runner->FastForwardUntilNoTasksRemain(); } // Test that main job is blocked for kMaxDelayTimeForMainJob(3s) if @@ -1117,6 +1111,10 @@ // Verifies that the main job is resumed properly after a delay when the // alternative proxy server job hangs. TEST_F(HttpStreamFactoryImplJobControllerTest, DelayedTCPAlternativeProxy) { + // Overrides the main thread's message loop with a mock tick clock so that we + // could verify the main job is resumed with appropriate delay. + base::ScopedMockTimeMessageLoopTaskRunner test_task_runner; + // Using hanging resolver will cause the alternative job to hang indefinitely. HangingResolver* resolver = new HangingResolver(); session_deps_.host_resolver.reset(resolver); @@ -1146,38 +1144,32 @@ EXPECT_TRUE(job_controller_->alternative_job()); EXPECT_TRUE(JobControllerPeer::main_job_is_blocked(job_controller_)); - // The alternative proxy server job stalls when connecting to the alternative - // proxy server, and controller should resume the main job after delay. - // Verify the waiting time for delayed main job. - EXPECT_CALL(*job_factory_.main_job(), Resume()) - .WillOnce(Invoke(testing::CreateFunctor( - &JobControllerPeer::VerifyWaitingTimeForMainJob, job_controller_, - base::TimeDelta::FromMicroseconds(15)))); + // Alternative proxy server job will start in the next message loop. + EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount()); - // This message loop should cause the alternative proxy server job to start, - // and schedule resumption of the main job. - base::RunLoop().RunUntilIdle(); + EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(0); + // Run tasks with no remaining delay, this will start the alternative proxy + // server job. The alternative proxy server job stalls when connecting to the + // alternative proxy server, and should schedule a task to resume the main job + // after delay. That task will be queued. + test_task_runner->RunUntilIdle(); + EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount()); + + // Move forward the delay and verify the main job is resumed. + EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1); + test_task_runner->FastForwardBy(base::TimeDelta::FromMicroseconds(15)); EXPECT_FALSE(JobControllerPeer::main_job_is_blocked(job_controller_)); - // Wait for the Resume to post. - base::PlatformThread::Sleep(base::TimeDelta::FromSeconds(1)); - - // This message loop should cause the main job to resume. - base::RunLoop().RunUntilIdle(); - EXPECT_FALSE(JobControllerPeer::main_job_is_blocked(job_controller_)); - - JobControllerPeer::VerifyWaitingTimeForMainJob( - job_controller_, base::TimeDelta::FromMicroseconds(0)); - - // Since the main job did not complete successfully, the alternative proxy - // server should not be marked as bad. + test_task_runner->RunUntilIdle(); EXPECT_TRUE(test_proxy_delegate()->alternative_proxy_server().is_valid()); EXPECT_EQ(1, test_proxy_delegate()->get_alternative_proxy_invocations()); + EXPECT_FALSE(test_task_runner->HasPendingTask()); } // Verifies that the alternative proxy server job fails immediately, and the // main job is not blocked. TEST_F(HttpStreamFactoryImplJobControllerTest, FailAlternativeProxy) { + base::ScopedMockTimeMessageLoopTaskRunner test_task_runner; // Using failing resolver will cause the alternative job to fail. FailingHostResolver* resolver = new FailingHostResolver(); session_deps_.host_resolver.reset(resolver); @@ -1204,23 +1196,25 @@ EXPECT_TRUE(job_controller_->main_job()->is_waiting()); EXPECT_TRUE(job_controller_->alternative_job()); + EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount()); + EXPECT_CALL(request_delegate_, OnStreamReady(_, _, _)).Times(0); // Since the alternative proxy server job is started in the next message loop, // the main job would remain blocked until the alternative proxy starts, and // fails. - EXPECT_CALL(*job_factory_.main_job(), Resume()) - .WillOnce(Invoke(testing::CreateFunctor( - &JobControllerPeer::VerifyWaitingTimeForMainJob, job_controller_, - base::TimeDelta::FromMicroseconds(0)))); + EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1); - base::RunLoop().RunUntilIdle(); + // Run tasks with no remaining delay. + test_task_runner->RunUntilIdle(); + EXPECT_FALSE(job_controller_->alternative_job()); EXPECT_TRUE(job_controller_->main_job()->is_waiting()); // Since the main job did not complete successfully, the alternative proxy // server should not be marked as bad. EXPECT_TRUE(test_proxy_delegate()->alternative_proxy_server().is_valid()); EXPECT_EQ(1, test_proxy_delegate()->get_alternative_proxy_invocations()); + EXPECT_FALSE(test_task_runner->HasPendingTask()); } TEST_F(HttpStreamFactoryImplJobControllerTest,
diff --git a/net/http2/decoder/payload_decoders/ping_payload_decoder.cc b/net/http2/decoder/payload_decoders/ping_payload_decoder.cc index abe43d0a..d8edbb0 100644 --- a/net/http2/decoder/payload_decoders/ping_payload_decoder.cc +++ b/net/http2/decoder/payload_decoders/ping_payload_decoder.cc
@@ -34,7 +34,7 @@ // This supports the claim that this decoder is (mostly) non-buffering. static_assert(sizeof(Http2PingFields) == kOpaqueSize, "If not, then can't enter this block!"); - auto ping = reinterpret_cast<const Http2PingFields*>(db->cursor()); + auto* ping = reinterpret_cast<const Http2PingFields*>(db->cursor()); if (frame_header.IsAck()) { state->listener()->OnPingAck(frame_header, *ping); } else {
diff --git a/net/http2/hpack/decoder/hpack_decoder_tables.cc b/net/http2/hpack/decoder/hpack_decoder_tables.cc index fb8f47b4..61e7970 100644 --- a/net/http2/hpack/decoder/hpack_decoder_tables.cc +++ b/net/http2/hpack/decoder/hpack_decoder_tables.cc
@@ -10,7 +10,7 @@ namespace { std::vector<HpackStringPair>* MakeStaticTable() { - auto ptr = new std::vector<HpackStringPair>(); + auto* ptr = new std::vector<HpackStringPair>(); ptr->reserve(kFirstDynamicTableIndex); ptr->emplace_back("", "");
diff --git a/net/http2/hpack/huffman/http2_hpack_huffman_decoder.cc b/net/http2/hpack/huffman/http2_hpack_huffman_decoder.cc index 45c32c08..189d34a 100644 --- a/net/http2/hpack/huffman/http2_hpack_huffman_decoder.cc +++ b/net/http2/hpack/huffman/http2_hpack_huffman_decoder.cc
@@ -368,7 +368,7 @@ // Top up |accumulator_| until there isn't room for a whole byte. size_t bytes_used = 0; - auto ptr = reinterpret_cast<const uint8_t*>(input.data()); + auto* ptr = reinterpret_cast<const uint8_t*>(input.data()); do { auto b = static_cast<HuffmanAccumulator>(*ptr++); free_cnt -= 8;
diff --git a/net/proxy/mojo_proxy_resolver_impl_unittest.cc b/net/proxy/mojo_proxy_resolver_impl_unittest.cc index 87a6427..0565a1a 100644 --- a/net/proxy/mojo_proxy_resolver_impl_unittest.cc +++ b/net/proxy/mojo_proxy_resolver_impl_unittest.cc
@@ -170,7 +170,7 @@ std::unique_ptr<ProxyResolver::Request>* request, std::unique_ptr<Bindings> bindings) { pending_jobs_.push_back(base::WrapUnique(new Job())); - auto pending_job = pending_jobs_.back().get(); + auto* pending_job = pending_jobs_.back().get(); pending_job->url = url; pending_job->results = results; pending_job->SetCallback(callback);
diff --git a/net/quic/core/quic_stream_sequencer_buffer_test.cc b/net/quic/core/quic_stream_sequencer_buffer_test.cc index fa71edf..e3be181 100644 --- a/net/quic/core/quic_stream_sequencer_buffer_test.cc +++ b/net/quic/core/quic_stream_sequencer_buffer_test.cc
@@ -128,7 +128,7 @@ std::list<Gap> gaps = helper_->GetGaps(); EXPECT_EQ(800u, gaps.front().end_offset); EXPECT_EQ(1824u, gaps.back().begin_offset); - auto frame_map = helper_->frame_arrival_time_map(); + auto* frame_map = helper_->frame_arrival_time_map(); EXPECT_EQ(1u, frame_map->size()); EXPECT_EQ(800u, frame_map->begin()->first); EXPECT_EQ(t, (*frame_map)[800].timestamp); @@ -167,7 +167,7 @@ buffer_->OnStreamData(0, source, t2, &written, &error_details_)); EXPECT_EQ(QUIC_OVERLAPPING_STREAM_DATA, buffer_->OnStreamData(1024, source, t2, &written, &error_details_)); - auto frame_map = helper_->frame_arrival_time_map(); + auto* frame_map = helper_->frame_arrival_time_map(); EXPECT_EQ(1u, frame_map->size()); EXPECT_EQ(t1, (*frame_map)[800].timestamp); } @@ -198,7 +198,7 @@ EXPECT_EQ(QUIC_NO_ERROR, buffer_->OnStreamData(1824, one_byte, clock_.ApproximateNow(), &written, &error_details_)); - auto frame_map = helper_->frame_arrival_time_map(); + auto* frame_map = helper_->frame_arrival_time_map(); EXPECT_EQ(3u, frame_map->size()); EXPECT_TRUE(helper_->CheckBufferInvariants()); }
diff --git a/net/quic/platform/api/quic_text_utils_test.cc b/net/quic/platform/api/quic_text_utils_test.cc index 06b25620..758ad54 100644 --- a/net/quic/platform/api/quic_text_utils_test.cc +++ b/net/quic/platform/api/quic_text_utils_test.cc
@@ -43,8 +43,8 @@ TEST(QuicTextUtilsText, RemoveLeadingAndTrailingWhitespace) { string input; - for (auto input : {"text", " text", " text", "text ", "text ", " text ", - " text ", "\r\n\ttext", "text\n\r\t"}) { + for (auto* input : {"text", " text", " text", "text ", "text ", " text ", + " text ", "\r\n\ttext", "text\n\r\t"}) { StringPiece piece(input); QuicTextUtils::RemoveLeadingAndTrailingWhitespace(&piece); EXPECT_EQ("text", piece);
diff --git a/net/socket/ssl_client_socket_impl.cc b/net/socket/ssl_client_socket_impl.cc index 77f3059..929607d 100644 --- a/net/socket/ssl_client_socket_impl.cc +++ b/net/socket/ssl_client_socket_impl.cc
@@ -82,7 +82,7 @@ // Token Binding ProtocolVersions supported. const uint8_t kTbProtocolVersionMajor = 0; -const uint8_t kTbProtocolVersionMinor = 10; +const uint8_t kTbProtocolVersionMinor = 13; const uint8_t kTbMinProtocolVersionMajor = 0; const uint8_t kTbMinProtocolVersionMinor = 10;
diff --git a/net/spdy/spdy_framer_test.cc b/net/spdy/spdy_framer_test.cc index 11bb432f..442b548b 100644 --- a/net/spdy/spdy_framer_test.cc +++ b/net/spdy/spdy_framer_test.cc
@@ -248,7 +248,7 @@ SpdySerializedFrame serialized_headers_old_version = framer->SerializeHeaders(headers); framer->hpack_encoder_.reset(nullptr); - auto saved_debug_visitor = framer->debug_visitor_; + auto* saved_debug_visitor = framer->debug_visitor_; framer->debug_visitor_ = nullptr; std::vector<SpdySerializedFrame> frame_list;
diff --git a/net/spdy/spdy_header_block.cc b/net/spdy/spdy_header_block.cc index a51532cf..32481174 100644 --- a/net/spdy/spdy_header_block.cc +++ b/net/spdy/spdy_header_block.cc
@@ -270,7 +270,7 @@ } else { DVLOG(1) << "Updating key: " << iter->first << " with value: " << value.second; - auto storage = GetStorage(); + auto* storage = GetStorage(); iter->second = HeaderValue(storage, iter->first, storage->Write(value.second)); } @@ -313,7 +313,7 @@ void SpdyHeaderBlock::AppendHeader(const StringPiece key, const StringPiece value) { - auto storage = GetStorage(); + auto* storage = GetStorage(); auto backed_key = storage->Write(key); block_.emplace(make_pair( backed_key, HeaderValue(storage, backed_key, storage->Write(value)))); @@ -382,7 +382,7 @@ if (fragments.empty()) { return 0; } - auto original_dst = dst; + auto* original_dst = dst; auto it = fragments.begin(); memcpy(dst, it->data(), it->size()); dst += it->size();
diff --git a/net/spdy/spdy_session_pool.cc b/net/spdy/spdy_session_pool.cc index b014e51..1b469f48 100644 --- a/net/spdy/spdy_session_pool.cc +++ b/net/spdy/spdy_session_pool.cc
@@ -382,7 +382,7 @@ size_t cert_count = 0; size_t serialized_cert_size = 0; size_t num_active_sessions = 0; - for (const auto& session : sessions_) { + for (auto* session : sessions_) { StreamSocket::SocketMemoryStats stats; bool is_session_active = false; total_size += session->DumpMemoryStats(&stats, &is_session_active);
diff --git a/net/tools/quic/end_to_end_test.cc b/net/tools/quic/end_to_end_test.cc index 4995021c..106d80f 100644 --- a/net/tools/quic/end_to_end_test.cc +++ b/net/tools/quic/end_to_end_test.cc
@@ -439,7 +439,7 @@ FLAGS_quic_reloadable_flag_quic_use_cheap_stateless_rejects = GetParam().use_cheap_stateless_reject; - auto test_server = new QuicTestServer( + auto* test_server = new QuicTestServer( crypto_test_utils::ProofSourceForTesting(), server_config_, server_supported_versions_, &response_cache_); server_thread_.reset(new ServerThread(test_server, server_address_)); @@ -1824,7 +1824,7 @@ QuicSpdySession* const client_session = client_->client()->session(); QuicDispatcher* dispatcher = QuicServerPeer::GetDispatcher(server_thread_->server()); - auto server_session = static_cast<QuicSpdySession*>( + auto* server_session = static_cast<QuicSpdySession*>( dispatcher->session_map().begin()->second.get()); ExpectFlowControlsSynced(client_session->flow_controller(), server_session->flow_controller());
diff --git a/net/url_request/url_request_context_getter.cc b/net/url_request/url_request_context_getter.cc index 0bad748..7163f48 100644 --- a/net/url_request/url_request_context_getter.cc +++ b/net/url_request/url_request_context_getter.cc
@@ -40,8 +40,10 @@ // Can't force-delete the object here, because some derived classes // can only be deleted on the owning thread, so just emit a warning to // aid in debugging. +#if !defined(NDEBUG) DLOG(WARNING) << "URLRequestContextGetter leaking due to no owning" - << " thread."; + << " thread. Created at: " << created_at.ToString(); +#endif // !defined(NDEBUG) // Let LSan know we know this is a leak. https://crbug.com/594130 ANNOTATE_LEAKING_OBJECT_PTR(this); }
diff --git a/net/url_request/url_request_context_getter.h b/net/url_request/url_request_context_getter.h index 081c97c..5a41526 100644 --- a/net/url_request/url_request_context_getter.h +++ b/net/url_request/url_request_context_getter.h
@@ -5,6 +5,7 @@ #ifndef NET_URL_REQUEST_URL_REQUEST_CONTEXT_GETTER_H_ #define NET_URL_REQUEST_URL_REQUEST_CONTEXT_GETTER_H_ +#include "base/debug/stack_trace.h" #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/observer_list.h" @@ -70,6 +71,10 @@ base::ObserverList<URLRequestContextGetterObserver> observer_list_; +#if !defined(NDEBUG) + base::debug::StackTrace created_at; +#endif // !defined(NDEBUG) + DISALLOW_COPY_AND_ASSIGN(URLRequestContextGetter); };
diff --git a/remoting/host/host_extension_session_manager.cc b/remoting/host/host_extension_session_manager.cc index ac06b4f..07f0a1ef 100644 --- a/remoting/host/host_extension_session_manager.cc +++ b/remoting/host/host_extension_session_manager.cc
@@ -23,7 +23,7 @@ std::string HostExtensionSessionManager::GetCapabilities() const { std::string capabilities; - for (const auto& extension : extensions_) { + for (auto* extension : extensions_) { const std::string& capability = extension->capability(); if (capability.empty()) { continue; @@ -44,7 +44,7 @@ client_stub_ = client_stub; - for (const auto& extension : extensions_) { + for (auto* extension : extensions_) { // If the extension requires a capability that was not negotiated then do // not instantiate it. if (!extension->capability().empty() &&
diff --git a/remoting/protocol/jingle_session.cc b/remoting/protocol/jingle_session.cc index bb3eb73f..1b1343f7 100644 --- a/remoting/protocol/jingle_session.cc +++ b/remoting/protocol/jingle_session.cc
@@ -769,14 +769,14 @@ if (!message.attachments) { return; } - for (const auto& plugin : plugins_) { + for (auto* plugin : plugins_) { plugin->OnIncomingMessage(*(message.attachments)); } } void JingleSession::AddPluginAttachments(JingleMessage* message) { DCHECK(message); - for (const auto& plugin : plugins_) { + for (auto* plugin : plugins_) { std::unique_ptr<XmlElement> attachment = plugin->GetNextMessage(); if (attachment) { message->AddAttachment(std::move(attachment));
diff --git a/sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.cc b/sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.cc index 00e9085d..e6c64de 100644 --- a/sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.cc +++ b/sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.cc
@@ -167,7 +167,7 @@ size_t crash_key_length = nr.length() + arg1.length() + arg2.length() + arg3.length() + arg4.length(); - for (const auto& prefix : prefixes) { + for (auto* prefix : prefixes) { crash_key_length += strlen(prefix); } ++crash_key_length; // For the trailing NUL byte. @@ -178,7 +178,7 @@ size_t offset = 0; for (size_t i = 0; i < arraysize(values); ++i) { const char* strings[2] = { prefixes[i], values[i] }; - for (const auto& string : strings) { + for (auto* string : strings) { size_t string_len = strlen(string); memmove(&crash_key[offset], string, string_len); offset += string_len;
diff --git a/services/service_manager/public/cpp/lib/interface_registry.cc b/services/service_manager/public/cpp/lib/interface_registry.cc index ba2ea2f9..9fb605d8 100644 --- a/services/service_manager/public/cpp/lib/interface_registry.cc +++ b/services/service_manager/public/cpp/lib/interface_registry.cc
@@ -214,7 +214,7 @@ std::stringstream details; Serialize(&details); - LOG(WARNING) << details.str(); + DVLOG(1) << details.str(); } } else { std::stringstream error; @@ -226,7 +226,7 @@ std::stringstream details; Serialize(&details); - LOG(WARNING) << details.str(); + DVLOG(1) << details.str(); } }
diff --git a/services/ui/public/cpp/gpu/client_gpu_memory_buffer_manager.cc b/services/ui/public/cpp/gpu/client_gpu_memory_buffer_manager.cc index d981ba1..827fd4e 100644 --- a/services/ui/public/cpp/gpu/client_gpu_memory_buffer_manager.cc +++ b/services/ui/public/cpp/gpu/client_gpu_memory_buffer_manager.cc
@@ -66,7 +66,7 @@ if (!gpu_.is_bound()) return; gpu_.reset(); - for (auto& waiter : pending_allocation_waiters_) + for (auto* waiter : pending_allocation_waiters_) waiter->Signal(); pending_allocation_waiters_.clear(); }
diff --git a/services/ui/public/cpp/window_compositor_frame_sink.cc b/services/ui/public/cpp/window_compositor_frame_sink.cc index 84a1419..01944e98 100644 --- a/services/ui/public/cpp/window_compositor_frame_sink.cc +++ b/services/ui/public/cpp/window_compositor_frame_sink.cc
@@ -70,7 +70,7 @@ gfx::Size frame_size = last_submitted_frame_size_; if (!frame.render_pass_list.empty()) - frame_size = frame.render_pass_list[0]->output_rect.size(); + frame_size = frame.render_pass_list.back()->output_rect.size(); if (!local_surface_id_.is_valid() || frame_size != last_submitted_frame_size_) local_surface_id_ = id_allocator_.GenerateId();
diff --git a/services/ui/surfaces/display_output_surface.cc b/services/ui/surfaces/display_output_surface.cc index e635a42..37604e7 100644 --- a/services/ui/surfaces/display_output_surface.cc +++ b/services/ui/surfaces/display_output_surface.cc
@@ -65,11 +65,11 @@ void DisplayOutputSurface::SwapBuffers(cc::OutputSurfaceFrame frame) { DCHECK(context_provider_); - if (frame.sub_buffer_rect == gfx::Rect(frame.size)) { - context_provider_->ContextSupport()->Swap(); - } else { + if (frame.sub_buffer_rect) { context_provider_->ContextSupport()->PartialSwapBuffers( - frame.sub_buffer_rect); + *frame.sub_buffer_rect); + } else { + context_provider_->ContextSupport()->Swap(); } }
diff --git a/services/ui/surfaces/display_output_surface_ozone.cc b/services/ui/surfaces/display_output_surface_ozone.cc index ea218b2..e63a2e88 100644 --- a/services/ui/surfaces/display_output_surface_ozone.cc +++ b/services/ui/surfaces/display_output_surface_ozone.cc
@@ -83,7 +83,8 @@ DCHECK(reshape_size_ == frame.size); swap_size_ = reshape_size_; - buffer_queue_->SwapBuffers(frame.sub_buffer_rect); + buffer_queue_->SwapBuffers(frame.sub_buffer_rect ? *frame.sub_buffer_rect + : gfx::Rect(swap_size_)); DisplayOutputSurface::SwapBuffers(std::move(frame)); }
diff --git a/services/ui/ws/server_window.cc b/services/ui/ws/server_window.cc index 654b40aa..800cdd2 100644 --- a/services/ui/ws/server_window.cc +++ b/services/ui/ws/server_window.cc
@@ -57,7 +57,7 @@ // parent, as destroying an active transient child may otherwise attempt to // refocus us. Windows transient_children(transient_children_); - for (auto window : transient_children) + for (auto* window : transient_children) delete window; DCHECK(transient_children_.empty());
diff --git a/services/ui/ws/window_server.cc b/services/ui/ws/window_server.cc index 7dfcf12..00f45758 100644 --- a/services/ui/ws/window_server.cc +++ b/services/ui/ws/window_server.cc
@@ -782,7 +782,7 @@ // FrameGenerator will add an appropriate reference for the new surface. DCHECK(display_manager_->GetDisplayContaining(window)); - auto display = display_manager_->GetDisplayContaining(window); + auto* display = display_manager_->GetDisplayContaining(window); if (window == display->GetActiveRootWindow()) { display->platform_display()->GetFrameGenerator()->OnSurfaceCreated( surface_info);
diff --git a/skia/config/SkUserConfig.h b/skia/config/SkUserConfig.h index 0038c73..8545bb3 100644 --- a/skia/config/SkUserConfig.h +++ b/skia/config/SkUserConfig.h
@@ -224,6 +224,10 @@ # define SK_SUPPORT_LEGACY_CLIPOP_EXOTIC_NAMES #endif +#ifndef SK_SUPPORT_LEGACY_CANVAS_HELPERS +#define SK_SUPPORT_LEGACY_CANVAS_HELPERS +#endif + ///////////////////////// Imported from BUILD.gn and skia_common.gypi /* In some places Skia can use static initializers for global initialization,
diff --git a/testing/scripts/run_gpu_integration_test_as_googletest.py b/testing/scripts/run_gpu_integration_test_as_googletest.py index fd48e06..765bdd1d 100755 --- a/testing/scripts/run_gpu_integration_test_as_googletest.py +++ b/testing/scripts/run_gpu_integration_test_as_googletest.py
@@ -87,7 +87,7 @@ rc = 0 try: rc = common.run_command([sys.executable] + rest_args + sharding_args + [ - '--write-abbreviated-json-results-to', args.isolated_script_test_output, + '--write-full-results-to', args.isolated_script_test_output ], env=env) except Exception: traceback.print_exc()
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index ec877c7..34a2cda 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -470,7 +470,10 @@ ], "experiments": [ { - "name": "Enabled" + "name": "Enabled_Warmup", + "params": { + "enable_warmup": "true" + } } ] } @@ -1391,6 +1394,25 @@ ] } ], + "NetworkSchedulerYielding": [ + { + "platforms": [ + "chromeos", + "linux", + "mac", + "win", + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "NetworkSchedulerYielding" + ] + } + ] + } + ], "NetworkTimeQueries": [ { "platforms": [ @@ -1507,6 +1529,22 @@ ] } ], + "OmniboxBundledExperimentV1": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Beta_Android_PhysWeb_QuerySuggest_Experiment", + "params": { + "PhysicalWebAfterTyping": "true", + "PhysicalWebZeroSuggest": "true" + } + } + ] + } + ], "OutOfProcessPac": [ { "platforms": [
diff --git a/third_party/.gitignore b/third_party/.gitignore new file mode 100644 index 0000000..6686cc2 --- /dev/null +++ b/third_party/.gitignore
@@ -0,0 +1,199 @@ +# This file is needed for projects that has this directory as a separate Git +# mirror in DEPS. Without it, a lot is wiped and re-downloaded for each sync. +/__START__ +/accessibility-developer-tools/ +/accessibility_test_framework/lib/*.jar +/adobe/flash/binaries +/adobe/flash/symbols +/amd/ +/android_protobuf/src +/android_support_test_runner/lib/*.aar +/android_support_test_runner/lib/*.jar +/android_tools/ +/android_tools_internal/ +/android_webview_glue/src +/angle +/angle_dx11 +/apache-portable-runtime/src +/apache_velocity/lib/*.jar +/apache-win32/bin/*.exe +/apache-win32/bin/*.dll +/apache-win32/bin/iconv/*.so +/apache-win32/modules/*.so +/apache-win32/modules/*.dll +/asan +/bidichecker +/bison +/boringssl/src +/bouncycastle/lib/*.jar +/byte_buddy/lib/*.jar +/cacheinvalidation/cacheinvalidation_unittests_run.xml +/cardboard-java/src +/catapult +/ced/src +/chromeos_login_manager +/chromeos_text_input +/chromite +/cld_2/src +/cld_3/src +/colorama/src +/cros +/cros_system_api +/custom_tabs_client/src +/cygwin +/deqp/src +/directxsdk +/dom_distiller_js/dist +/drmemory/drmemory-windows-sfx.exe +/drmemory/unpacked +/elfutils/src +/errorprone/lib +/espresso/lib/*.jar +/eyesfree/src +/ffmpeg +/findbugs +/flac +/flatbuffers/src +/fontconfig/src +/freetype-android/src +/freetype2/src +/gestures/gestures +/gles2_conform +/glslang/src +/glslang-angle/src +/gnu_binutils/ +/google_appengine_cloudstorage +/google_toolbox_for_mac/src +/googlemac +/gvr-android-sdk/common_library.aar +/gvr-android-sdk/libgvr_shim_static_arm.a +/gvr-android-sdk/libgvr_shim_static_arm64.a +/gvr-android-sdk/src +/gperf +/guava/lib/*.jar +/hamcrest/lib/*.jar +/hunspell_dictionaries +/icu +/icu4j/lib/*.jar +/intellij/lib/*.jar +/inspector_protocol +/javax_inject/lib/*.jar +/jsoncpp/source +/jsr-305/src +/junit/src +/khronos_glcts +/leakcanary/src +/leveldatabase/src +/leveldb +/libc++-static/libc++.a +/libaddressinput/src +/libdrm/src +/libevdev/src +/libexif/sources +/libFuzzer/src +/libjingle/source +/libjpeg_turbo +/liblouis/src +/libphonenumber/dist +/libsrtp +/libupnp +/libvpx/source/libvpx +/libwebm/source +/libyuv +/lighttpd +/llvm +/llvm-allocated-type +/llvm-bootstrap +/llvm-build +/lss +/mesa/src +/mingw-w64 +/minigbm/src +/mkl +/mocha +/mockito/src +/nacl_sdk_binaries/ +/netty-tcnative/src +/netty4/src +/node/linux +/node/mac +/node/node_modules +/node/*.tar.gz +/node/win +/nss +/objenesis/lib/*.jar +/omaha/src/omaha +/openmax_dl/ +/openh264/src +/ow2_asm/lib/*.jar +/pdfsqueeze +/pdfium +/pefile +/perl +/ppapi +/psyco_win32 +/pthreads-win32 +/py_trace_event/src +/pyelftools +/pyftpdlib/src +/pylib +/pymox/src +/python_24 +/python_26 +/pywebsocket/src +/pywebsocket/src +/re2/src +/requests/src +/retrolambda/*.jar +/robolectric/lib/*.jar +/robolectric/robolectric +/scan-build/src +/scons-2.0.1 +/sfntly/src +/shaderc/src +/skia +/smhasher/src +/snappy/src +/spirv-headers/src +/SPIRV-Tools/src +/spirv-tools-angle/src +/sqlite4java/lib/**/*.dll +/sqlite4java/lib/**/*.jar +/sqlite4java/lib/**/*.jnilib +/sqlite4java/lib/**/*.so +/swiftshader/ +/syzygy +/syzygy/binaries +/tsan/ +/ub-uiautomator/lib +/usb_ids +/usrsctp/usrsctplib +/v8-i18n +/valgrind +/vulkan-validation-layers/src +/visualmetrics +/wayland/src +/wayland-protocols/src +/wds/src +/webdriver/pylib +/webdriver/python/selenium +/webgl +/webgl/src +/webpagereplay/ +/webrtc +/widevine/cdm/chromeos +/widevine/cdm/linux +/widevine/cdm/mac +/widevine/cdm/win +/widevine/scripts +/widevine/test/license_server +/win_toolchain/.timestamps +/win_toolchain/files +/wix +/xdg-utils +/xulrunner-sdk +/yasm/binaries +/yasm/generate_files.xml +/yasm/source/patched-yasm +/yasm/yasm.xml +
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/site-per-process b/third_party/WebKit/LayoutTests/FlagExpectations/site-per-process index 500bbcb..81f62a3 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/site-per-process +++ b/third_party/WebKit/LayoutTests/FlagExpectations/site-per-process
@@ -10,8 +10,8 @@ crbug.com/669083 virtual/mojo-loading/http/tests/security/frameNavigation/xss-DENIED-top-navigation-without-user-gesture.html [ Failure ] # https://crbug.com/661725 - Propagating user gesture via postMessage doesn't work for OOPIFs -crbug.com/661725 http/tests/security/frameNavigation/xss-ALLOWED-top-navigation-after-postMessage.html [ Timeout ] -crbug.com/661725 virtual/mojo-loading/http/tests/security/frameNavigation/xss-ALLOWED-top-navigation-after-postMessage.html [ Timeout ] +crbug.com/661725 http/tests/security/frameNavigation/xss-ALLOWED-top-navigation-after-postMessage.html [ Failure Timeout ] +crbug.com/661725 virtual/mojo-loading/http/tests/security/frameNavigation/xss-ALLOWED-top-navigation-after-postMessage.html [ Failure Timeout ] # https://crbug.com/582245 - no exception, b/c BindingSecurity::shouldAllowAccessTo exits early when |!target|. crbug.com/582245 http/tests/security/xss-DENIED-getSVGDocument-iframe.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index 822cf3a..bdacc30 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -135,6 +135,12 @@ crbug.com/664852 virtual/gpu/fast/canvas/canvas-lost-gpu-context.html [ Pass Failure ] crbug.com/664852 virtual/gpu/fast/canvas/OffscreenCanvas-2d-drawImage.html [ Pass Failure ] +# Added 2016-12-14 +crbug.com/674396 [ Win ] compositing/reflections/nested-reflection-transition.html [ Pass Failure ] + +# Added 2016-12-15 +crbug.com/674468 [ Trusty ] compositing/reflections/nested-reflection-transition.html [ Pass Failure ] + # Added 2017-01-16 crbug.com/681471 paint/invalidation/media-audio-no-spurious-repaints.html [ Failure Pass Timeout ] crbug.com/681471 virtual/disable-spinvalidation/paint/invalidation/media-audio-no-spurious-repaints.html [ Failure Pass Timeout ] @@ -1663,6 +1669,10 @@ crbug.com/618082 [ Win10 ] printing/thead-repeats-at-top-of-each-page.html [ Failure ] crbug.com/618082 [ Win10 ] virtual/threaded/printing/thead-repeats-at-top-of-each-page.html [ Failure ] +crbug.com/695203 inspector/sources/debugger-breakpoints/debugger-reload-breakpoints-with-source-maps.html [ NeedsManualRebaseline ] +crbug.com/695203 inspector/sources/debugger-breakpoints/possible-breakpoints.html [ NeedsManualRebaseline ] +crbug.com/695203 inspector/sources/debugger/source-frame-inline-breakpoint-decorations.html [ NeedsManualRebaseline ] + crbug.com/690486 fast/css3-text/css3-text-decoration/text-underline-position/text-underline-position-cjk.html [ Failure Pass ] crbug.com/474759 fast/writing-mode/vertical-rl-replaced-selection.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/fast/events/inputevents/inputevent-cancelable.html b/third_party/WebKit/LayoutTests/fast/events/inputevents/inputevent-cancelable.html new file mode 100644 index 0000000..94dda10 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/events/inputevents/inputevent-cancelable.html
@@ -0,0 +1,138 @@ +<!DOCTYPE html> +<html> +<head> +<title>InputEvent: cancelable</title> +<script src="../../../resources/testharness.js"></script> +<script src="../../../resources/testharnessreport.js"></script> +<style> +div { + width: 100px; + height: 100px; +} +</style> +</head> +<body> +<div id="editable" contenteditable></div> +<div id="editable1" contenteditable>EditableText</div> +<div id="editable2" contenteditable></div> +<script> +function simulateDragDrop(dragElement, dropElement) { + if (dragElement.select) { + dragElement.select(); + } else { + var selection = window.getSelection(); + selection.collapse(dragElement, 0); + selection.extend(dragElement, 1); + } + + eventSender.mouseMoveTo(dragElement.offsetLeft + dragElement.offsetWidth / 2, + dragElement.offsetTop + dragElement.offsetHeight / 2); + eventSender.mouseDown(); + eventSender.leapForward(600); + eventSender.mouseMoveTo(dropElement.offsetLeft + dropElement.offsetWidth / 2, + dropElement.offsetTop + dropElement.offsetHeight / 2); + eventSender.mouseUp(); +} + +async_test(t => { + assert_not_equals(window.eventSender, undefined, 'This test requires eventSender.'); + assert_not_equals(window.testRunner, undefined, 'This test requires testRunner.'); + assert_not_equals(internals, undefined, 'This test requires internals.'); + assert_not_equals(textInputController, undefined, 'This test requires textInputController.'); + + const editable = document.getElementById('editable'); + const editable1 = document.getElementById('editable1'); + const editable2 = document.getElementById('editable2'); + const kNoncancelableInputTypes = [ + 'insertText', 'insertLineBreak', 'insertParagraph', + 'insertCompositionText', 'insertReplacementText', + 'deleteWordBackward', 'deleteWordForward', + 'deleteLineBackward', 'deleteLineForward', + 'deleteContentBackward', 'deleteContentForward', + ]; + + let lastBeforeInputType = ''; + document.addEventListener('beforeinput', t.step_func(event => { + lastBeforeInputType = event.inputType; + assert_equals(kNoncancelableInputTypes.indexOf(event.inputType) === -1, event.cancelable); + })); + + function testKeyDown(key, modifiers, inputType) { + lastBeforeInputType = ''; + eventSender.keyDown(key, modifiers); + assert_equals(inputType, lastBeforeInputType, `${modifiers.toString()}+${key} should produce input type: ${inputType}`); + } + + function testCommand(command, inputType) { + lastBeforeInputType = ''; + testRunner.execCommand(command); + assert_equals(inputType, lastBeforeInputType, `${command} should produce input type: ${inputType}`); + } + + // Typing + editable.focus(); + testKeyDown('a', [], 'insertText'); + testKeyDown('6', [], 'insertText'); + testKeyDown('l', ['shiftKey'], 'insertText'); + testKeyDown('w', ['shiftKey'], 'insertText'); + testKeyDown('Enter', [], 'insertParagraph'); + testKeyDown('Enter', ['shiftKey'], 'insertLineBreak'); + + // Deletion + const isMacOS = navigator.platform.indexOf('Mac') === 0; + const deleteWordModifier = isMacOS ? 'altKey' : 'ctrlKey'; + editable.innerHTML = 'abc def</br>123 456'; + const selection = window.getSelection(); + selection.collapse(editable, 1); // End of first line. + testKeyDown('Backspace', [], 'deleteContentBackward'); + testKeyDown('Delete', [], 'deleteContentForward'); + testKeyDown('Backspace', [deleteWordModifier], 'deleteWordBackward'); + testKeyDown('Delete', [deleteWordModifier], 'deleteWordForward'); + + // Format + editable.innerHTML = 'abc'; + selection.collapse(editable, 0); + selection.extend(editable, 1); + testCommand('bold', 'formatBold'); + testCommand('italic', 'formatItalic'); + testCommand('underline', 'formatUnderline'); + testCommand('strikeThrough', 'formatStrikeThrough'); + testCommand('superscript', 'formatSuperscript'); + testCommand('subscript', 'formatSubscript'); + + // Cut and paste + editable.innerHTML = 'abc'; + selection.collapse(editable, 0); + selection.extend(editable, 1); + testKeyDown('Cut', [], 'deleteByCut'); + testKeyDown('Paste', [], 'insertFromPaste'); + + // Drag and drop + simulateDragDrop(editable1, editable2); + assert_equals('insertFromDrop', lastBeforeInputType); + + // Undo and redo + testCommand('undo', 'historyUndo'); + testCommand('redo', 'historyRedo'); + + // Spell-checker + editable.innerHTML = 'appla'; + selection.collapse(editable, 0); + selection.extend(editable, 1); + internals.setMarker(document, selection.getRangeAt(0), 'Spelling'); + internals.replaceMisspelled(document, 'apple'); + assert_equals('insertReplacementText', lastBeforeInputType); + + // IME + editable.innerHTML = 'wo'; + selection.collapse(editable, 0); + selection.extend(editable, 1); + textInputController.setComposition('word'); + assert_equals('insertCompositionText', lastBeforeInputType); + + t.done(); +}, 'Text input and IME related input types are non-cancelable.'); + +</script> +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/fast/mediacapturefromelement/CanvasCaptureMediaStream-capture-out-of-DOM-element.html b/third_party/WebKit/LayoutTests/fast/mediacapturefromelement/CanvasCaptureMediaStream-capture-out-of-DOM-element.html index bed039a2..aef33f31 100644 --- a/third_party/WebKit/LayoutTests/fast/mediacapturefromelement/CanvasCaptureMediaStream-capture-out-of-DOM-element.html +++ b/third_party/WebKit/LayoutTests/fast/mediacapturefromelement/CanvasCaptureMediaStream-capture-out-of-DOM-element.html
@@ -5,35 +5,51 @@ async_test(t => { var canvas = document.createElement('canvas'); - - var recorder = new MediaRecorder(canvas.captureStream()); - recorder.ondataavailable = function() { - t.step_func_done(function() { - assert_true(event.data.size > 0, 'Recorded data size should be > 0'); - })(); - recorder.stop(); - } - recorder.start(0); - var ctx = canvas.getContext('2d'); ctx.fillStyle = 'green'; + var recorder = new MediaRecorder(canvas.captureStream()); + var frameCount = 0; + + recorder.ondataavailable = function() { + t.step(function() { + assert_true(event.data.size > 0, 'Recorded data size should be > 0'); + }); + + frameCount = frameCount + 1; + if (frameCount > 3) { + recorder.stop(); + t.done(); + } else { + ctx.fillRect(0, 0, canvas.width, canvas.height); + } + } + + recorder.start(0); ctx.fillRect(0, 0, canvas.width, canvas.height); -}, "Verify that drawing to a 2D canvas that is not attached to the DOM dispatches a frame to an attached MediaRecorder." ); +}, "Verify that drawing to a 2D canvas that is not attached to the DOM dispatches frames to an attached MediaRecorder." ); async_test(t => { var canvas = document.createElement('canvas'); - + var gl = canvas.getContext('webgl'); + gl.clearColor(0, 1, 0, 1); var recorder = new MediaRecorder(canvas.captureStream()); + var frameCount = 0; + recorder.ondataavailable = function() { - t.step_func_done(function() { + t.step(function() { assert_true(event.data.size > 0, 'Recorded data size should be > 0'); - })(); - recorder.stop(); + }); + + frameCount = frameCount + 1; + if (frameCount > 3) { + recorder.stop(); + t.done(); + } else { + gl.clear(gl.COLOR_BUFFER_BIT); + } } recorder.start(0); - var gl = canvas.getContext('webgl'); - gl.clearColor(0, 1, 0, 1); gl.clear(gl.COLOR_BUFFER_BIT); -}, "Verify that drawing to a webgl canvas that is not attached to the DOM dispatches a frame to an attached MediaRecorder." ); +}, "Verify that drawing to a webgl canvas that is not attached to the DOM dispatches frames to an attached MediaRecorder." ); </script> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/search/sources-search-scope-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector/search/sources-search-scope-expected.txt index 05e795b..350ba2a6 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector/search/sources-search-scope-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/inspector/search/sources-search-scope-expected.txt
@@ -1,5 +1,22 @@ +Running: testIgnoreCaseAndIgnoreDynamicScript +Search result #1: uiSourceCode.url = http://127.0.0.1:8000/inspector/search/resources/search.css + search match #1: lineNumber = 0, lineContent = 'div.searchTestUniqueString {' + search match #2: lineNumber = 4, lineContent = 'div.searchTestUniqueString:hover {' + search match #3: lineNumber = 5, lineContent = ' /* another searchTestUniqueString occurence */' +Search result #2: uiSourceCode.url = http://127.0.0.1:8000/inspector/search/resources/search.html + search match #1: lineNumber = 4, lineContent = '<script>window.eval("function searchTestUniqueString() {}");</script>' + search match #2: lineNumber = 6, lineContent = '<div>searchTestUniqueString</div>' + search match #3: lineNumber = 8, lineContent = '<!-- searchTestUniqueString -->' + search match #4: lineNumber = 10, lineContent = '<div id="searchTestUniqueString">div text</div>' +Search result #3: uiSourceCode.url = http://127.0.0.1:8000/inspector/search/resources/search.js + search match #1: lineNumber = 0, lineContent = 'function searchTestUniqueString()' + search match #2: lineNumber = 3, lineContent = ' // searchTestUniqueString two occurences on the same line searchTestUniqueString' + search match #3: lineNumber = 4, lineContent = ' // searchTestUniqueString on the next line.' + search match #4: lineNumber = 10, lineContent = ' searchTestUniqueString();' + search match #5: lineNumber = 11, lineContent = ' // SEARCHTestUniqueString();' + Running: testIgnoreCase Search result #1: uiSourceCode.url = debugger:///VMXX search match #1: lineNumber = 0, lineContent = 'function searchTestUniqueString() {}'
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/search/sources-search-scope.html b/third_party/WebKit/LayoutTests/http/tests/inspector/search/sources-search-scope.html index 97077f3..658c791 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector/search/sources-search-scope.html +++ b/third_party/WebKit/LayoutTests/http/tests/inspector/search/sources-search-scope.html
@@ -20,13 +20,22 @@ function step2() { InspectorTest.runTestSuite([ - function testIgnoreCase(next) + function testIgnoreCaseAndIgnoreDynamicScript(next) { var query = "searchTest" + "UniqueString"; var searchConfig = new Workspace.SearchConfig(query, true, false); InspectorTest.runSearchAndDumpResults(scope, searchConfig, next); }, + function testIgnoreCase(next) + { + Common.settingForTest('searchInAnonymousAndContentScripts').set(true); + var query = "searchTest" + "UniqueString"; + var searchConfig = new Workspace.SearchConfig(query, true, false); + InspectorTest.runSearchAndDumpResults(scope, searchConfig, next); + }, + + function testCaseSensitive(next) { var query = "searchTest" + "UniqueString";
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/navigator-view-content-scripts-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector/sources/navigator-view-content-scripts-expected.txt new file mode 100644 index 0000000..936351fe --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/inspector/sources/navigator-view-content-scripts-expected.txt
@@ -0,0 +1,29 @@ +Verify that removal of one of the multiple projects, all of which are associated with the same frame, doesn't lead navigator to discard the frame treenode. + + + +================================================ +Adding urls +top + 127.0.0.1:8000 + inspector + sources + navigator-view-content-scripts.html + inspector-test.js + localhost:8080 + LayoutTests/inspector/debugger/foo/bar + script.js + + +================================================ +Removing contentScripts project +top + 127.0.0.1:8000 + inspector + sources + navigator-view-content-scripts.html + inspector-test.js + localhost:8080 + LayoutTests/inspector/debugger/foo/bar + script.js +
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/sources/navigator-view-content-scripts.html b/third_party/WebKit/LayoutTests/http/tests/inspector/sources/navigator-view-content-scripts.html new file mode 100644 index 0000000..a3f4835 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/inspector/sources/navigator-view-content-scripts.html
@@ -0,0 +1,41 @@ +<html> +<head> +<script src="../inspector-test.js"></script> + +<script> +function test() +{ + function addUISourceCode(url, isContentScript) + { + var contentProvider = Common.StaticContentProvider.fromString(url, Common.resourceTypes.Script, ""); + var networkProject = Bindings.NetworkProject.forTarget(InspectorTest.mainTarget); + var uiSourceCode = networkProject.addFile(contentProvider, InspectorTest.mainFrame(), isContentScript); + return uiSourceCode; + } + + var rootURL = "http://localhost:8080/LayoutTests/inspector/debugger/"; + var sourcesNavigatorView = new Sources.SourcesNavigatorView(); + sourcesNavigatorView.show(UI.inspectorView.element); + + InspectorTest.addResult("\n\n================================================"); + InspectorTest.addResult("Adding urls"); + addUISourceCode(rootURL + "foo/bar/script.js", false); + var contentUISourceCode = addUISourceCode(rootURL + "foo/bar/contentScript2.js?a=1", true); + InspectorTest.dumpNavigatorView(sourcesNavigatorView); + + InspectorTest.addResult("\n\n================================================"); + InspectorTest.addResult("Removing contentScripts project"); + contentUISourceCode.project().removeProject(); + InspectorTest.dumpNavigatorView(sourcesNavigatorView); + InspectorTest.completeTest(); +} +</script> + +</head> +<body onload="runTest()"> +<p>Verify that removal of one of the multiple projects, all of which are associated with the same +frame, doesn't lead navigator to discard the frame treenode.</p> +</p> +</body> + +</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/usb/insecure-context.html b/third_party/WebKit/LayoutTests/http/tests/usb/insecure-context.html new file mode 100644 index 0000000..06afc29e --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/usb/insecure-context.html
@@ -0,0 +1,17 @@ +<!DOCTYPE html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/get-host-info.js"></script> +<script> +'use strict'; + +if (window.location.origin != get_host_info().UNAUTHENTICATED_ORIGIN) { + window.location = get_host_info().UNAUTHENTICATED_ORIGIN + + window.location.pathname; +} else { + test(t => { + assert_false(window.isSecureContext); + assert_true(navigator.usb == undefined); + }, 'navigator.usb is not present in an insecure context'); +} +</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/usb/secure-context.html b/third_party/WebKit/LayoutTests/http/tests/usb/secure-context.html new file mode 100644 index 0000000..242f704 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/usb/secure-context.html
@@ -0,0 +1,17 @@ +<!DOCTYPE html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/get-host-info.js"></script> +<script> +'use strict'; + +if (window.location.origin != get_host_info().AUTHENTICATED_ORIGIN) { + window.location = get_host_info().AUTHENTICATED_ORIGIN + + window.location.pathname; +} else { + test(t => { + assert_true(window.isSecureContext); + assert_true(navigator.usb instanceof USB); + }, 'navigator.usb is present in an insecure context'); +} +</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/wasm/incrementer.wasm b/third_party/WebKit/LayoutTests/http/tests/wasm/incrementer.wasm index eba6007..47afcde 100644 --- a/third_party/WebKit/LayoutTests/http/tests/wasm/incrementer.wasm +++ b/third_party/WebKit/LayoutTests/http/tests/wasm/incrementer.wasm Binary files differ
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/debugger-breakpoints/debugger-reload-breakpoints-with-source-maps-expected.txt b/third_party/WebKit/LayoutTests/inspector/sources/debugger-breakpoints/debugger-reload-breakpoints-with-source-maps-expected.txt deleted file mode 100644 index bd15332..0000000 --- a/third_party/WebKit/LayoutTests/inspector/sources/debugger-breakpoints/debugger-reload-breakpoints-with-source-maps-expected.txt +++ /dev/null
@@ -1,11 +0,0 @@ -Tests "reload" from within inspector window while on pause. - - -Breakpoint sidebar pane before reload: -source1.js:15 var handler = new ClickHandler(); -source1.js:17} -Page reloaded. -Breakpoint sidebar pane after reload: -source1.js:15 var handler = new ClickHandler(); -source1.js:17} -
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/debugger-breakpoints/possible-breakpoints-expected.txt b/third_party/WebKit/LayoutTests/inspector/sources/debugger-breakpoints/possible-breakpoints-expected.txt index 14bac31c..16d03a1 100644 --- a/third_party/WebKit/LayoutTests/inspector/sources/debugger-breakpoints/possible-breakpoints-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector/sources/debugger-breakpoints/possible-breakpoints-expected.txt
@@ -3,11 +3,15 @@ Locations for first line All locations location(2, 2) +location(2, 10) +location(2, 20) location(2, 31) location(2, 34) +location(2, 36) location(2, 47) location(2, 49) location(3, 2) +location(3, 10) location(4, 2) location(5, 0) Existing location by position
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/debugger/source-frame-inline-breakpoint-decorations-expected.txt b/third_party/WebKit/LayoutTests/inspector/sources/debugger/source-frame-inline-breakpoint-decorations-expected.txt index 6070515..afae367 100644 --- a/third_party/WebKit/LayoutTests/inspector/sources/debugger/source-frame-inline-breakpoint-decorations-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector/sources/debugger/source-frame-inline-breakpoint-decorations-expected.txt
@@ -4,7 +4,9 @@ Running: testAddRemoveBreakpoint Setting breakpoint breakpoint at 3 - inline breakpoint at (3, 49) + inline breakpoint at (3, 20) + inline breakpoint at (3, 30) disabled + inline breakpoint at (3, 49) disabled inline breakpoint at (3, 56) disabled Toggle breakpoint @@ -16,16 +18,22 @@ Running: clickByInlineBreakpoint Setting breakpoint breakpoint at 3 - inline breakpoint at (3, 49) + inline breakpoint at (3, 20) + inline breakpoint at (3, 30) disabled + inline breakpoint at (3, 49) disabled inline breakpoint at (3, 56) disabled Click by second breakpoint breakpoint at 3 - inline breakpoint at (3, 49) - inline breakpoint at (3, 56) + inline breakpoint at (3, 20) + inline breakpoint at (3, 30) + inline breakpoint at (3, 49) disabled + inline breakpoint at (3, 56) disabled Click by first breakpoint breakpoint at 3 + inline breakpoint at (3, 20) disabled + inline breakpoint at (3, 30) inline breakpoint at (3, 49) disabled - inline breakpoint at (3, 56) + inline breakpoint at (3, 56) disabled Click by second breakpoint Running: toggleBreakpointInAnotherLineWontRemoveExisting @@ -36,7 +44,9 @@ inline breakpoint at (4, 36) disabled Setting breakpoint in line 3 breakpoint at 3 - inline breakpoint at (3, 49) + inline breakpoint at (3, 20) + inline breakpoint at (3, 30) disabled + inline breakpoint at (3, 49) disabled inline breakpoint at (3, 56) disabled breakpoint at 4 inline breakpoint at (4, 9)
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-network/timeline-network-resource-details.html b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-network/timeline-network-resource-details.html index 8edd25c..42de865 100644 --- a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-network/timeline-network-resource-details.html +++ b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-network/timeline-network-resource-details.html
@@ -35,7 +35,11 @@ var rows = element.querySelectorAll(".timeline-details-view-row"); for (var i = 0; i < rows.length; ++i) { var title = rows[i].firstChild.firstChild.textContent; - var value = rows[i].lastChild.firstChild.textContent; + var value = rows[i].lastChild.firstChild; + if (value.children && value.children.length) + value = Array.from(value.children, element => element.textContent).slice(1).join(''); + else + value = value.textContent; if (title === "Duration" || title === "Mime Type") value = typeof value; if (/^file:\/\//.test(value))
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/box-sizing-expected.txt b/third_party/WebKit/LayoutTests/paint/invalidation/box-sizing-expected.txt index 363e3a4..d1b55da 100644 --- a/third_party/WebKit/LayoutTests/paint/invalidation/box-sizing-expected.txt +++ b/third_party/WebKit/LayoutTests/paint/invalidation/box-sizing-expected.txt
@@ -8,8 +8,8 @@ "paintInvalidations": [ { "object": "LayoutBlockFlow (positioned) DIV id='target2' class='border-box'", - "rect": [0, 200, 440, 140], - "reason": "content box change" + "rect": [0, 280, 440, 60], + "reason": "incremental" }, { "object": "LayoutBlockFlow (positioned) DIV id='target1' class='content-box'", @@ -17,6 +17,11 @@ "reason": "incremental" }, { + "object": "LayoutBlockFlow (positioned) DIV id='target2' class='border-box'", + "rect": [380, 200, 60, 140], + "reason": "incremental" + }, + { "object": "LayoutBlockFlow (positioned) DIV id='target1' class='content-box'", "rect": [380, 0, 60, 140], "reason": "incremental" @@ -31,7 +36,7 @@ }, { "object": "LayoutBlockFlow (positioned) DIV id='target2' class='border-box'", - "reason": "content box change" + "reason": "incremental" } ] }
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/box-sizing-padding-keeping-size-expected.txt b/third_party/WebKit/LayoutTests/paint/invalidation/box-sizing-padding-keeping-size-expected.txt index f700373f..0ba51d1 100644 --- a/third_party/WebKit/LayoutTests/paint/invalidation/box-sizing-padding-keeping-size-expected.txt +++ b/third_party/WebKit/LayoutTests/paint/invalidation/box-sizing-padding-keeping-size-expected.txt
@@ -4,7 +4,29 @@ "name": "LayoutView #document", "bounds": [800, 600], "contentsOpaque": true, - "drawsContent": true + "drawsContent": true, + "paintInvalidations": [ + { + "object": "LayoutBlockFlow (positioned) DIV id='target2' class='border-box'", + "rect": [0, 200, 100, 100], + "reason": "style change" + }, + { + "object": "LayoutBlockFlow (positioned) DIV id='target1' class='content-box'", + "rect": [0, 0, 100, 100], + "reason": "style change" + } + ] + } + ], + "objectPaintInvalidations": [ + { + "object": "LayoutBlockFlow (positioned) DIV id='target1' class='content-box'", + "reason": "style change" + }, + { + "object": "LayoutBlockFlow (positioned) DIV id='target2' class='border-box'", + "reason": "style change" } ] }
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/padding-keeping-content-size-expected.txt b/third_party/WebKit/LayoutTests/paint/invalidation/padding-keeping-content-size-expected.txt index f90b469..c4d681d 100644 --- a/third_party/WebKit/LayoutTests/paint/invalidation/padding-keeping-content-size-expected.txt +++ b/third_party/WebKit/LayoutTests/paint/invalidation/padding-keeping-content-size-expected.txt
@@ -9,12 +9,12 @@ { "object": "LayoutBlockFlow (positioned) DIV id='target2' class='outer'", "rect": [0, 200, 140, 140], - "reason": "background obscuration change" + "reason": "style change" }, { "object": "LayoutBlockFlow (positioned) DIV id='target1' class='outer'", - "rect": [0, 100, 140, 40], - "reason": "incremental" + "rect": [0, 0, 140, 140], + "reason": "style change" }, { "object": "LayoutBlockFlow DIV class='inner'", @@ -25,11 +25,6 @@ "object": "LayoutBlockFlow DIV class='inner'", "rect": [0, 200, 100, 100], "reason": "bounds change" - }, - { - "object": "LayoutBlockFlow (positioned) DIV id='target1' class='outer'", - "rect": [100, 0, 40, 140], - "reason": "incremental" } ] } @@ -37,11 +32,11 @@ "objectPaintInvalidations": [ { "object": "LayoutBlockFlow (positioned) DIV id='target1' class='outer'", - "reason": "incremental" + "reason": "style change" }, { "object": "LayoutBlockFlow (positioned) DIV id='target2' class='outer'", - "reason": "background obscuration change" + "reason": "style change" }, { "object": "LayoutBlockFlow DIV class='inner'",
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/padding-keeping-visual-size-expected.txt b/third_party/WebKit/LayoutTests/paint/invalidation/padding-keeping-visual-size-expected.txt index 608272df..7263731 100644 --- a/third_party/WebKit/LayoutTests/paint/invalidation/padding-keeping-visual-size-expected.txt +++ b/third_party/WebKit/LayoutTests/paint/invalidation/padding-keeping-visual-size-expected.txt
@@ -9,20 +9,29 @@ { "object": "LayoutBlockFlow (positioned) DIV id='target2' class='outer'", "rect": [0, 200, 100, 100], - "reason": "background obscuration change" + "reason": "style change" }, { "object": "LayoutBlockFlow DIV class='inner'", "rect": [0, 200, 100, 100], "reason": "bounds change" + }, + { + "object": "LayoutBlockFlow (positioned) DIV id='target1' class='outer'", + "rect": [0, 0, 100, 100], + "reason": "style change" } ] } ], "objectPaintInvalidations": [ { + "object": "LayoutBlockFlow (positioned) DIV id='target1' class='outer'", + "reason": "style change" + }, + { "object": "LayoutBlockFlow (positioned) DIV id='target2' class='outer'", - "reason": "background obscuration change" + "reason": "style change" }, { "object": "LayoutBlockFlow DIV class='inner'",
diff --git a/third_party/WebKit/LayoutTests/presentation/presentation-onreceiverconnection.html b/third_party/WebKit/LayoutTests/presentation/presentation-onreceiverconnection.html new file mode 100644 index 0000000..b7f550a --- /dev/null +++ b/third_party/WebKit/LayoutTests/presentation/presentation-onreceiverconnection.html
@@ -0,0 +1,36 @@ +<!DOCTYPE html> +<html> +<body> +<script src="../resources/testharness.js"></script> +<script src="../resources/testharnessreport.js"></script> +<script src="../resources/mojo-helpers.js"></script> +<script src="resources/presentation-service-mock.js"></script> +<script> + +async_test(t => { + internals.settings.setPresentationReceiver(true); + t.add_cleanup(_ => { internals.settings.setPresentationReceiver(false); }); + + presentationServiceMock.then(mockService => { + // Invoke mockService.setClient(). + const receiver = navigator.presentation.receiver; + + // Make sure it is invoked after calling setClient(). + setTimeout(() => { + const url = 'http://example.com/a.html'; + const id = 'fakeSessionId'; + mockService.onReceiverConnectionAvailable(url, id); + + receiver.connectionList.then( + t.step_func_done(list => { + assert_equals(list.connections.length, 1); + assert_equals(list.connections[0].url, url); + assert_equals(list.connections[0].id, id); + })); + }); + }); +}, "Test presentation.receiver.connectionList resolves with incoming connection."); + +</script> +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/presentation/resources/presentation-service-mock.js b/third_party/WebKit/LayoutTests/presentation/resources/presentation-service-mock.js index 3db3d1e..15007fe 100644 --- a/third_party/WebKit/LayoutTests/presentation/resources/presentation-service-mock.js +++ b/third_party/WebKit/LayoutTests/presentation/resources/presentation-service-mock.js
@@ -8,9 +8,13 @@ 'presentationServiceMock', [ 'third_party/WebKit/public/platform/modules/presentation/presentation.mojom', + 'url/mojo/url.mojom', 'mojo/public/js/bindings', ]).then(mojo => { - let [ presentationService, bindings ] = mojo.modules; + let [ presentationService, url, bindings ] = mojo.modules; + + class MockPresentationConnection { + }; class PresentationServiceMock { constructor(interfaceProvider) { @@ -23,6 +27,10 @@ presentationService.PresentationService); } + setClient(client) { + this.client_ = client; + } + startSession(urls) { return Promise.resolve({ sessionInfo: { url: urls[0], id: 'fakesession' }, @@ -36,6 +44,22 @@ error: null, }); } + + onReceiverConnectionAvailable(strUrl, id) { + const mojoUrl = new url.Url(); + mojoUrl.url = strUrl; + const controllerConnectionPtr = new presentationService.PresentationConnectionPtr(); + const connectionBinding = new bindings.Binding( + presentationService.PresentationConnection, + new MockPresentationConnection(), + bindings.makeRequest(controllerConnectionPtr)); + const receiverConnectionPtr = new presentationService.PresentationConnectionPtr(); + + this.client_.onReceiverConnectionAvailable( + { url: mojoUrl, id: id }, + controllerConnectionPtr, + bindings.makeRequest(receiverConnectionPtr)); + } } return new PresentationServiceMock(mojo.frameInterfaces); @@ -47,9 +71,9 @@ if (!('eventSender' in window)) return; - var boundingRect = button.getBoundingClientRect(); - var x = boundingRect.left + boundingRect.width / 2; - var y = boundingRect.top + boundingRect.height / 2; + const boundingRect = button.getBoundingClientRect(); + const x = boundingRect.left + boundingRect.width / 2; + const y = boundingRect.top + boundingRect.height / 2; eventSender.mouseMoveTo(x, y); eventSender.mouseDown();
diff --git a/third_party/WebKit/LayoutTests/webaudio/Panner/distance-exponential-expected.txt b/third_party/WebKit/LayoutTests/webaudio/Panner/distance-exponential-expected.txt deleted file mode 100644 index 34420e2..0000000 --- a/third_party/WebKit/LayoutTests/webaudio/Panner/distance-exponential-expected.txt +++ /dev/null
@@ -1,11 +0,0 @@ -Test exponential distance model of AudioPannerNode. - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - -PASS Number of impulses found matches number of panner nodes. -PASS Distance gains are correct. -PASS Distance test passed for distance model exponential -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/WebKit/LayoutTests/webaudio/Panner/distance-exponential.html b/third_party/WebKit/LayoutTests/webaudio/Panner/distance-exponential.html index b1a07da2..37cc0c3f 100644 --- a/third_party/WebKit/LayoutTests/webaudio/Panner/distance-exponential.html +++ b/third_party/WebKit/LayoutTests/webaudio/Panner/distance-exponential.html
@@ -1,36 +1,27 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> +<!doctype html> <html> <head> - <script src="../../resources/js-test.js"></script> + <script src="../../resources/testharness.js"></script> + <script src="../../resources/testharnessreport.js"></script> <script src="../resources/audit-util.js"></script> - <script src="../resources/audio-testing.js"></script> + <script src="../resources/audit.js"></script> <script src="../resources/distance-model-testing.js"></script> </head> <body> - <div id="description"></div> - <div id="console"></div> - <script> - description("Test exponential distance model of AudioPannerNode."); + let audit = Audit.createTaskRunner(); - function runTest() { - if (window.testRunner) { - testRunner.dumpAsText(); - testRunner.waitUntilDone(); - } - - window.jsTestIsAsync = true; - + audit.define("test", (task, should) => { + task.describe("Exponential distance model for PannerNode"); // Create offline audio context. context = new OfflineAudioContext(2, sampleRate * renderLengthSeconds, sampleRate); - createTestAndRun(context, "exponential"); - } + createTestAndRun(context, "exponential", should) + .then(() => task.done()); + }); - runTest(); - successfullyParsed = true; - + audit.run(); </script> </body>
diff --git a/third_party/WebKit/LayoutTests/webaudio/Panner/distance-inverse-expected.txt b/third_party/WebKit/LayoutTests/webaudio/Panner/distance-inverse-expected.txt deleted file mode 100644 index 5f35cdfc..0000000 --- a/third_party/WebKit/LayoutTests/webaudio/Panner/distance-inverse-expected.txt +++ /dev/null
@@ -1,11 +0,0 @@ -Test inverse distance model of AudioPannerNode. - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - -PASS Number of impulses found matches number of panner nodes. -PASS Distance gains are correct. -PASS Distance test passed for distance model inverse -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/WebKit/LayoutTests/webaudio/Panner/distance-inverse.html b/third_party/WebKit/LayoutTests/webaudio/Panner/distance-inverse.html index 49b7c3fe..3afb2a3 100644 --- a/third_party/WebKit/LayoutTests/webaudio/Panner/distance-inverse.html +++ b/third_party/WebKit/LayoutTests/webaudio/Panner/distance-inverse.html
@@ -1,36 +1,26 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> +<!doctype html> <html> <head> - <script src="../../resources/js-test.js"></script> + <script src="../../resources/testharness.js"></script> + <script src="../../resources/testharnessreport.js"></script> <script src="../resources/audit-util.js"></script> - <script src="../resources/audio-testing.js"></script> + <script src="../resources/audit.js"></script> <script src="../resources/distance-model-testing.js"></script> </head> <body> - <div id="description"></div> - <div id="console"></div> - <script> - description("Test inverse distance model of AudioPannerNode."); + let audit = Audit.createTaskRunner(); - function runTest() { - if (window.testRunner) { - testRunner.dumpAsText(); - testRunner.waitUntilDone(); - } - - window.jsTestIsAsync = true; - + audit.define("test", (task, should) => { // Create offline audio context. context = new OfflineAudioContext(2, sampleRate * renderLengthSeconds, sampleRate); - createTestAndRun(context, "inverse"); - } + createTestAndRun(context, "inverse", should) + .then(() => task.done()); + }); - runTest(); - successfullyParsed = true; - + audit.run(); </script> </body>
diff --git a/third_party/WebKit/LayoutTests/webaudio/Panner/distance-linear-expected.txt b/third_party/WebKit/LayoutTests/webaudio/Panner/distance-linear-expected.txt deleted file mode 100644 index adbde13..0000000 --- a/third_party/WebKit/LayoutTests/webaudio/Panner/distance-linear-expected.txt +++ /dev/null
@@ -1,11 +0,0 @@ -Test linear distance model of AudioPannerNode. - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - -PASS Number of impulses found matches number of panner nodes. -PASS Distance gains are correct. -PASS Distance test passed for distance model linear -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/WebKit/LayoutTests/webaudio/Panner/distance-linear.html b/third_party/WebKit/LayoutTests/webaudio/Panner/distance-linear.html index 335bf11..fb285a0f 100644 --- a/third_party/WebKit/LayoutTests/webaudio/Panner/distance-linear.html +++ b/third_party/WebKit/LayoutTests/webaudio/Panner/distance-linear.html
@@ -1,36 +1,27 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> +<!doctype html> <html> <head> - <script src="../../resources/js-test.js"></script> + <script src="../../resources/testharness.js"></script> + <script src="../../resources/testharnessreport.js"></script> <script src="../resources/audit-util.js"></script> - <script src="../resources/audio-testing.js"></script> + <script src="../resources/audit.js"></script> <script src="../resources/distance-model-testing.js"></script> </head> <body> - <div id="description"></div> - <div id="console"></div> - <script> - description("Test linear distance model of AudioPannerNode."); + let audit = Audit.createTaskRunner(); - function runTest() { - if (window.testRunner) { - testRunner.dumpAsText(); - testRunner.waitUntilDone(); - } - - window.jsTestIsAsync = true; - + audit.define("test", (task, should) => { + task.describe("Linear distance model PannerNode"); // Create offline audio context. context = new OfflineAudioContext(2, sampleRate * renderLengthSeconds, sampleRate); - createTestAndRun(context, "linear"); - } + createTestAndRun(context, "linear", should) + .then(() => task.done()); + }); - runTest(); - successfullyParsed = true; - + audit.run(); </script> </body>
diff --git a/third_party/WebKit/LayoutTests/webaudio/WaveShaper/waveshaper-expected.txt b/third_party/WebKit/LayoutTests/webaudio/WaveShaper/waveshaper-expected.txt deleted file mode 100644 index d815493..0000000 --- a/third_party/WebKit/LayoutTests/webaudio/WaveShaper/waveshaper-expected.txt +++ /dev/null
@@ -1,9 +0,0 @@ -Tests that WaveShaperNode applies proper non-linear distortion. - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - -PASS WaveShaperNode properly applied non-linear distortion. -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/WebKit/LayoutTests/webaudio/WaveShaper/waveshaper-limits-expected.txt b/third_party/WebKit/LayoutTests/webaudio/WaveShaper/waveshaper-limits-expected.txt deleted file mode 100644 index 3c8dd60..0000000 --- a/third_party/WebKit/LayoutTests/webaudio/WaveShaper/waveshaper-limits-expected.txt +++ /dev/null
@@ -1,32 +0,0 @@ -Test WaveShaperNode including values outside the range of [-1,1] - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - -PASS -1.100000 -> 0.000000. -PASS -1.000000 -> 0.000000. -PASS -0.900000 -> 0.100000. -PASS -0.800000 -> 0.200000. -PASS -0.700000 -> 0.300000. -PASS -0.600000 -> 0.400000. -PASS -0.500000 -> 0.500000. -PASS -0.400000 -> 0.600000. -PASS -0.300000 -> 0.700000. -PASS -0.200000 -> 0.800000. -PASS -0.100000 -> 0.900000. -PASS 0.000000 -> 1.000000. -PASS 0.100000 -> 0.900000. -PASS 0.200000 -> 0.800000. -PASS 0.300000 -> 0.700000. -PASS 0.400000 -> 0.600000. -PASS 0.500000 -> 0.500000. -PASS 0.600000 -> 0.400000. -PASS 0.700000 -> 0.300000. -PASS 0.800000 -> 0.200000. -PASS 0.900000 -> 0.100000. -PASS 1.000000 -> 0.000000. -PASS 1.100000 -> 0.000000. -PASS All outputs matched expected results. -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/WebKit/LayoutTests/webaudio/WaveShaper/waveshaper-limits.html b/third_party/WebKit/LayoutTests/webaudio/WaveShaper/waveshaper-limits.html index eb9d4ff3..d49fa57 100644 --- a/third_party/WebKit/LayoutTests/webaudio/WaveShaper/waveshaper-limits.html +++ b/third_party/WebKit/LayoutTests/webaudio/WaveShaper/waveshaper-limits.html
@@ -1,15 +1,15 @@ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> - <script src="../../resources/js-test.js"></script> + <script src="../../resources/testharness.js"></script> + <script src="../../resources/testharnessreport.js"></script> + <script src="../resources/audit-util.js"></script> + <script src="../resources/audit.js"></script> </head> <body> - <div id="description"></div> - <div id="console"></div> - <script> - description("Test WaveShaperNode including values outside the range of [-1,1]"); + var audit = Audit.createTaskRunner(); var context; var bufferData; @@ -48,37 +48,22 @@ return ref; } - function checkResult (event) { - outputData = event.renderedBuffer.getChannelData(0); + function checkResult (renderedBuffer, should) { + outputData = renderedBuffer.getChannelData(0); reference = generateReference(); var success = true; // Verify that every output value matches our expected reference value. for (var k = 0; k < outputData.length; ++k) { var diff = outputData[k] - reference[k]; - if (Math.abs(diff) <= diffThreshold) { - testPassed(bufferData[k].toFixed(decimals) + " -> " + outputData[k].toFixed(decimals) + "."); - } else { - testFailed(bufferData[k].toFixed(decimals) + " -> " + outputData[k].toFixed(decimals) + ", but expected " + reference[k].toFixed(decimals) + "."); - success = false; - } + should(Math.abs(diff), + "Max error mapping " + bufferData[k].toFixed(decimals) + " to " + + outputData[k].toFixed(decimals)) + .beLessThanOrEqualTo(diffThreshold); } - - if (success) - testPassed("All outputs matched expected results."); - else - testFailed("Some outputs did not match expected results."); - - finishJSTest(); } - function runTest () { - if (window.testRunner) { - testRunner.dumpAsText(); - testRunner.waitUntilDone(); - } - - window.jsTestIsAsync = true; - + audit.define("test", function (task, should) { + task.describe("Test WaveShaperNode including values outside the range of [-1,1]"); context = new OfflineAudioContext(1, testFrames, sampleRate); // Create input values between -1.1 and 1.1 var buffer = context.createBuffer(1, testFrames, context.sampleRate); @@ -103,12 +88,12 @@ shaper.connect(context.destination); source.start(); - context.oncomplete = checkResult; - context.startRendering(); - } + context.startRendering() + .then(buffer => checkResult(buffer, should)) + .then(() => task.done()); + }); - runTest(); - successfullyParsed = true; + audit.run(); </script> </body> </html>
diff --git a/third_party/WebKit/LayoutTests/webaudio/WaveShaper/waveshaper-oversample-2x-expected.txt b/third_party/WebKit/LayoutTests/webaudio/WaveShaper/waveshaper-oversample-2x-expected.txt deleted file mode 100644 index ffa3eab4..0000000 --- a/third_party/WebKit/LayoutTests/webaudio/WaveShaper/waveshaper-oversample-2x-expected.txt +++ /dev/null
@@ -1,9 +0,0 @@ -Tests 2x WaveShaperNode oversampling. - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - -PASS 2x WaveShaperNode oversampling within acceptable tolerance. -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/WebKit/LayoutTests/webaudio/WaveShaper/waveshaper-oversample-2x.html b/third_party/WebKit/LayoutTests/webaudio/WaveShaper/waveshaper-oversample-2x.html index b023d1f..e34a33c 100644 --- a/third_party/WebKit/LayoutTests/webaudio/WaveShaper/waveshaper-oversample-2x.html +++ b/third_party/WebKit/LayoutTests/webaudio/WaveShaper/waveshaper-oversample-2x.html
@@ -2,21 +2,16 @@ <html> <head> -<script src="../../resources/js-test.js"></script> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> <script src="../resources/audit-util.js"></script> -<script src="../resources/audio-testing.js"></script> +<script src="../resources/audit.js"></script> <script type="text/javascript" src="../resources/mix-testing.js"></script> <script type="text/javascript" src="../resources/waveshaper-testing.js"></script> </head> <body> - -<div id="description"></div> -<div id="console"></div> - <script> -description("Tests 2x WaveShaperNode oversampling."); - var testParams = { "sampleRate": 44100, "oversample": "2x", @@ -24,7 +19,8 @@ // Should generate harmonics at 9000, 18000, 27000, 36000 // The last two should be filtered out with the 2x oversampling. "fundamentalFrequency": 9000, - "acceptableAliasingThresholdDecibels": -75.3 + "acceptableAliasingThresholdDecibels": -75.3, + description: "2x WaveShaperNode oversampling" }; runWaveShaperOversamplingTest(testParams);
diff --git a/third_party/WebKit/LayoutTests/webaudio/WaveShaper/waveshaper-oversample-4x-expected.txt b/third_party/WebKit/LayoutTests/webaudio/WaveShaper/waveshaper-oversample-4x-expected.txt deleted file mode 100644 index c67d8215..0000000 --- a/third_party/WebKit/LayoutTests/webaudio/WaveShaper/waveshaper-oversample-4x-expected.txt +++ /dev/null
@@ -1,9 +0,0 @@ -Tests 4x WaveShaperNode oversampling. - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - -PASS 4x WaveShaperNode oversampling within acceptable tolerance. -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/WebKit/LayoutTests/webaudio/WaveShaper/waveshaper-oversample-4x.html b/third_party/WebKit/LayoutTests/webaudio/WaveShaper/waveshaper-oversample-4x.html index ac9b299..68a095f 100644 --- a/third_party/WebKit/LayoutTests/webaudio/WaveShaper/waveshaper-oversample-4x.html +++ b/third_party/WebKit/LayoutTests/webaudio/WaveShaper/waveshaper-oversample-4x.html
@@ -2,21 +2,16 @@ <html> <head> -<script src="../../resources/js-test.js"></script> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> <script src="../resources/audit-util.js"></script> -<script src="../resources/audio-testing.js"></script> +<script src="../resources/audit.js"></script> <script type="text/javascript" src="../resources/mix-testing.js"></script> <script type="text/javascript" src="../resources/waveshaper-testing.js"></script> </head> <body> - -<div id="description"></div> -<div id="console"></div> - <script> -description("Tests 4x WaveShaperNode oversampling."); - var testParams = { "sampleRate": 44100, "oversample": "4x", @@ -24,7 +19,8 @@ // Should generate harmonics at 18000, 36000, 54000, 72000 // All except for 18000 should be filtered out with the 4x oversampling. "fundamentalFrequency": 18000, - "acceptableAliasingThresholdDecibels": -79.9 + "acceptableAliasingThresholdDecibels": -79.9, + description: "4x WaveShaperNode oversampling" }; runWaveShaperOversamplingTest(testParams);
diff --git a/third_party/WebKit/LayoutTests/webaudio/WaveShaper/waveshaper.html b/third_party/WebKit/LayoutTests/webaudio/WaveShaper/waveshaper.html index 1330a23..3a42391 100644 --- a/third_party/WebKit/LayoutTests/webaudio/WaveShaper/waveshaper.html +++ b/third_party/WebKit/LayoutTests/webaudio/WaveShaper/waveshaper.html
@@ -2,19 +2,16 @@ <html> <head> -<script src="../../resources/js-test.js"></script> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> <script src="../resources/audit-util.js"></script> -<script src="../resources/audio-testing.js"></script> +<script src="../resources/audit.js"></script> <script type="text/javascript" src="../resources/buffer-loader.js"></script> </head> <body> - -<div id="description"></div> -<div id="console"></div> - <script> -description("Tests that WaveShaperNode applies proper non-linear distortion."); +var audit = Audit.createTaskRunner(); var sampleRate = 44100; var lengthInSeconds = 4; @@ -60,9 +57,7 @@ return curve; } -function checkShapedCurve(event) { - var buffer = event.renderedBuffer; - +function checkShapedCurve(buffer, should) { var inputData = inputBuffer.getChannelData(0); var outputData = buffer.getChannelData(0); @@ -90,23 +85,11 @@ } } - if (success) { - testPassed("WaveShaperNode properly applied non-linear distortion."); - } else { - testFailed("WaveShaperNode did not properly apply non-linear distortion."); - } - - finishJSTest(); + should(success, "WaveShaperNode applied non-linear distortion correctly") + .beTrue(); } -function runTest() { - if (window.testRunner) { - testRunner.dumpAsText(); - testRunner.waitUntilDone(); - } - - window.jsTestIsAsync = true; - +audit.define("test", function (task, should) { // Create offline audio context. context = new OfflineAudioContext(1, numberOfRenderFrames, sampleRate); @@ -126,11 +109,12 @@ source.start(0); - context.oncomplete = checkShapedCurve; - context.startRendering(); -} + context.startRendering() + .then(buffer => checkShapedCurve(buffer, should)) + .then(task.done.bind(task)); +}); -runTest(); +audit.run(); </script>
diff --git a/third_party/WebKit/LayoutTests/webaudio/audioworklet/audioworklet-testing.js b/third_party/WebKit/LayoutTests/webaudio/audioworklet/audioworklet-testing.js index 4553fa30..f239ff3 100644 --- a/third_party/WebKit/LayoutTests/webaudio/audioworklet/audioworklet-testing.js +++ b/third_party/WebKit/LayoutTests/webaudio/audioworklet/audioworklet-testing.js
@@ -1,27 +1,19 @@ -/* @global internals, Should */ - -// Check if |internals| and its |runtimeFlags.AudioWorklet| are available. -// -// The content_shell driven by run-webkit-tests.py is supposed to enable -// all the experimental web platform features. The flags are exposed via -// |internals.runtimeFlag|. -// -// See: https://www.chromium.org/blink/runtime-enabled-features -function checkInternalsAndAudioWorkletRuntimeFlag(taskDone) { - - var isInternals = Should('window.internals', window.internals).exist(); - - if (!isInternals) { - taskDone(); - return false; - } - - var isFlag = Should('window.internals.runtimeFlags.audioWorkletEnabled', - window.internals.runtimeFlags.audioWorkletEnabled).beEqualTo(true); - - if (!isFlag) { - taskDone(); - } - - return isFlag; +/** + * Check if |window.internals| and |window.internals.runtimeFlags.AudioWorklet| + * are available. + * + * The content_shell driven by run-webkit-tests.py is supposed to enable all the + * experimental web platform features. The flags are exposed via + * |internals.runtimeFlag|. + * + * See: https://www.chromium.org/blink/runtime-enabled-features + * + * @return {Boolean} + */ +function isAudioWorkletEnabled() { + return { + onContentShell: Boolean(window.internals) && + Boolean(window.internals.runtimeFlags.audioWorkletEnabled), + onBrowser: Boolean(window.Worklet) && Boolean(window.audioWorklet) + }; }
diff --git a/third_party/WebKit/LayoutTests/webaudio/audioworklet/window-audioworklet.html b/third_party/WebKit/LayoutTests/webaudio/audioworklet/window-audioworklet.html index 9efda23..181e6ba5 100644 --- a/third_party/WebKit/LayoutTests/webaudio/audioworklet/window-audioworklet.html +++ b/third_party/WebKit/LayoutTests/webaudio/audioworklet/window-audioworklet.html
@@ -4,28 +4,35 @@ <title>Checking window.audioWorklet</title> <script src="../../resources/testharness.js"></script> <script src="../../resources/testharnessreport.js"></script> - <script src="../resources/audit-util.js"></script> - <script src="../resources/audio-testing.js"></script> + <script src="../resources/audit.js"></script> <script src="audioworklet-testing.js"></script> </head> <body> <script> - var audit = Audit.createTaskRunner(); + // This test requires AudioWorklet. + let audioWorkletStatus = isAudioWorkletEnabled(); - audit.defineTask('window-audioworklet', function (taskDone) { + let audit = Audit.createTaskRunner(); - // TODO: remove this check if AudioWorklet ships to the stable. - if (!checkInternalsAndAudioWorkletRuntimeFlag(taskDone)) - return; + // Test if AudioWorklet exists. + audit.define({ + label: 'window-audioworklet', + description: 'Test if AudioWorklet exists.', + }, (task, should) => { + // TODO(hongchan): remove this assertion when AudioWorklet is shipped. + should(audioWorkletStatus.onContentShell || + audioWorkletStatus.onBrowser, + 'AudioWorklet is available on ContentShell or Browser') + .beTrue(); - Should('window.audioWorklet is an instance of Worklet', - window.audioWorklet instanceof Worklet).beEqualTo(true); + should(window.audioWorklet instanceof Worklet, + 'window.audioWorklet is an instance of Worklet') + .beTrue(); - taskDone(); + task.done(); }); - - audit.runTasks(); + audit.run(); </script> </body> </html>
diff --git a/third_party/WebKit/LayoutTests/webaudio/dom-exceptions-expected.txt b/third_party/WebKit/LayoutTests/webaudio/dom-exceptions-expected.txt index 87c61261..17b4c0c9 100644 --- a/third_party/WebKit/LayoutTests/webaudio/dom-exceptions-expected.txt +++ b/third_party/WebKit/LayoutTests/webaudio/dom-exceptions-expected.txt
@@ -1,193 +1,239 @@ -CONSOLE WARNING: line 1: The provided value 'fancy' is not a valid enum value of type ChannelCountMode. -CONSOLE WARNING: line 1: The provided value 'undefined' is not a valid enum value of type ChannelInterpretation. -CONSOLE WARNING: line 1: The provided value '9x' is not a valid enum value of type OverSampleType. -CONSOLE WARNING: line 1: The provided value 'junk' is not a valid enum value of type ChannelCountMode. -CONSOLE WARNING: line 1: The provided value 'junk' is not a valid enum value of type ChannelCountMode. -Tests DOM exception messages - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - -PASS context.createBuffer(99, 1, context.sampleRate) threw exception NotSupportedError: Failed to execute 'createBuffer' on 'BaseAudioContext': The number of channels provided (99) is outside the range [1, 32].. -PASS context.createBuffer(0, 1, context.sampleRate) threw exception NotSupportedError: Failed to execute 'createBuffer' on 'BaseAudioContext': The number of channels provided (0) is outside the range [1, 32].. -PASS context.createBuffer(1, 1, 1) threw exception NotSupportedError: Failed to execute 'createBuffer' on 'BaseAudioContext': The sample rate provided (1) is outside the range [3000, 384000].. -PASS context.createBuffer(1, 1, 2999) threw exception NotSupportedError: Failed to execute 'createBuffer' on 'BaseAudioContext': The sample rate provided (2999) is outside the range [3000, 384000].. -PASS context.createBuffer(1, 1, 384001) threw exception NotSupportedError: Failed to execute 'createBuffer' on 'BaseAudioContext': The sample rate provided (384001) is outside the range [3000, 384000].. -PASS context.createBuffer(1, 1, 1e6) threw exception NotSupportedError: Failed to execute 'createBuffer' on 'BaseAudioContext': The sample rate provided (1.00000e+6) is outside the range [3000, 384000].. -PASS context.createBuffer(1, 1, 3000) did not throw exception. -PASS context.createBuffer(1, 1, 192000) did not throw exception. -PASS context.createBuffer(1, 1, 384000) did not throw exception. -PASS context.createBuffer(1, 0, context.sampleRate) threw exception NotSupportedError: Failed to execute 'createBuffer' on 'BaseAudioContext': The number of frames provided (0) is less than or equal to the minimum bound (0).. -PASS context.createBuffer(new ArrayBuffer(100), true) threw exception TypeError: Failed to execute 'createBuffer' on 'BaseAudioContext': 3 arguments required, but only 2 present.. -PASS context.createMediaElementSource(null) threw exception TypeError: Failed to execute 'createMediaElementSource' on 'BaseAudioContext': parameter 1 is not of type 'HTMLMediaElement'.. -PASS context.createMediaStreamSource(null) threw exception TypeError: Failed to execute 'createMediaStreamSource' on 'BaseAudioContext': parameter 1 is not of type 'MediaStream'.. -PASS context.createScriptProcessor(1, 1, 1) threw exception IndexSizeError: Failed to execute 'createScriptProcessor' on 'BaseAudioContext': buffer size (1) must be 0 or a power of two between 256 and 16384.. -PASS context.createScriptProcessor(4096, 100, 1) threw exception IndexSizeError: Failed to execute 'createScriptProcessor' on 'BaseAudioContext': number of input channels (100) exceeds maximum (32).. -PASS context.createScriptProcessor(4096, 1, 100) threw exception IndexSizeError: Failed to execute 'createScriptProcessor' on 'BaseAudioContext': number of output channels (100) exceeds maximum (32).. -PASS context.createScriptProcessor() did not throw exception. -PASS context.createScriptProcessor(0) did not throw exception. -PASS context.createChannelSplitter(0) threw exception IndexSizeError: Failed to execute 'createChannelSplitter' on 'BaseAudioContext': The number of outputs provided (0) is outside the range [1, 32].. -PASS context.createChannelSplitter(99) threw exception IndexSizeError: Failed to execute 'createChannelSplitter' on 'BaseAudioContext': The number of outputs provided (99) is outside the range [1, 32].. -PASS context.createChannelMerger(0) threw exception IndexSizeError: Failed to execute 'createChannelMerger' on 'BaseAudioContext': The number of inputs provided (0) is outside the range [1, 32].. -PASS context.createChannelMerger(99) threw exception IndexSizeError: Failed to execute 'createChannelMerger' on 'BaseAudioContext': The number of inputs provided (99) is outside the range [1, 32].. -PASS context.createPeriodicWave(null, null) threw exception TypeError: Failed to execute 'createPeriodicWave' on 'BaseAudioContext': parameter 1 is not of type 'Float32Array'.. -PASS context.createPeriodicWave(new Float32Array(10), null) threw exception TypeError: Failed to execute 'createPeriodicWave' on 'BaseAudioContext': parameter 2 is not of type 'Float32Array'.. -PASS context.createPeriodicWave(new Float32Array(4100), new Float32Array(4100)) did not throw exception. -PASS context.createPeriodicWave(new Float32Array(8192), new Float32Array(8192)) did not throw exception. -PASS context.createPeriodicWave(new Float32Array(10000), new Float32Array(10000)) did not throw exception. -PASS context.createPeriodicWave(new Float32Array(10), new Float32Array(7)) threw exception IndexSizeError: Failed to execute 'createPeriodicWave' on 'BaseAudioContext': length of real array (10) and length of imaginary array (7) must match.. -PASS node.fftSize = 42 threw exception IndexSizeError: Failed to set the 'fftSize' property on 'AnalyserNode': The value provided (42) is not a power of two.. -PASS node.fftSize is not 42 -PASS node.fftSize = 16 threw exception IndexSizeError: Failed to set the 'fftSize' property on 'AnalyserNode': The FFT size provided (16) is outside the range [32, 32768].. -PASS node.fftSize is not 16 -PASS node.fftSize = 32768 did not throw exception. -PASS node.fftSize = 65536 threw exception IndexSizeError: Failed to set the 'fftSize' property on 'AnalyserNode': The FFT size provided (65536) is outside the range [32, 32768].. -PASS node.fftSize is not 65536 -PASS node.minDecibels = -10 threw exception IndexSizeError: Failed to set the 'minDecibels' property on 'AnalyserNode': The minDecibels provided (-10) is greater than the maximum bound (-30).. -PASS node.minDecibels is not -10 -PASS node.maxDecibels = -150 threw exception IndexSizeError: Failed to set the 'maxDecibels' property on 'AnalyserNode': The maxDecibels provided (-150) is less than the minimum bound (-100).. -PASS node.maxDecibels is not -150 -PASS node.minDecibels = -30 threw exception IndexSizeError: Failed to set the 'minDecibels' property on 'AnalyserNode': The minDecibels provided (-30) is greater than or equal to the maximum bound (-30).. -PASS node.minDecibels is not -30 -PASS node.maxDecibels = -100 threw exception IndexSizeError: Failed to set the 'maxDecibels' property on 'AnalyserNode': The maxDecibels provided (-100) is less than or equal to the minimum bound (-100).. -PASS node.maxDecibels is not -100 -PASS node.smoothingTimeConstant = -0.1 threw exception IndexSizeError: Failed to set the 'smoothingTimeConstant' property on 'AnalyserNode': The smoothing value provided (-0.1) is outside the range [0, 1].. -PASS node.smoothingTimeConstant is not -0.1 -PASS node.smoothingTimeConstant = 1.5 threw exception IndexSizeError: Failed to set the 'smoothingTimeConstant' property on 'AnalyserNode': The smoothing value provided (1.5) is outside the range [0, 1].. -PASS node.smoothingTimeConstant is not 1.5 -PASS node.getFloatFrequencyData(null) threw exception TypeError: Failed to execute 'getFloatFrequencyData' on 'AnalyserNode': parameter 1 is not of type 'Float32Array'.. -PASS node.getByteFrequencyData(null) threw exception TypeError: Failed to execute 'getByteFrequencyData' on 'AnalyserNode': parameter 1 is not of type 'Uint8Array'.. -PASS node.getFloatTimeDomainData(null) threw exception TypeError: Failed to execute 'getFloatTimeDomainData' on 'AnalyserNode': parameter 1 is not of type 'Float32Array'.. -PASS node.getByteTimeDomainData(null) threw exception TypeError: Failed to execute 'getByteTimeDomainData' on 'AnalyserNode': parameter 1 is not of type 'Uint8Array'.. -PASS node.getChannelData(2) threw exception IndexSizeError: Failed to execute 'getChannelData' on 'AudioBuffer': channel index (2) exceeds number of channels (1). -PASS node.connect(null, 0, 0) threw exception TypeError: Failed to execute 'connect' on 'AudioNode': parameter 1 is not of type 'AudioNode'.. -PASS node.connect(context.destination, 100, 0) threw exception IndexSizeError: Failed to execute 'connect' on 'AudioNode': output index (100) exceeds number of outputs (1).. -PASS node.connect(context.destination, 0, 100) threw exception IndexSizeError: Failed to execute 'connect' on 'AudioNode': input index (100) exceeds number of inputs (1).. -PASS node.connect(node2.gain, 100) threw exception IndexSizeError: Failed to execute 'connect' on 'AudioNode': output index (100) exceeds number of outputs (1).. -PASS node.disconnect(99) threw exception IndexSizeError: Failed to execute 'disconnect' on 'AudioNode': The output index provided (99) is outside the range [0, 0].. -PASS node.connect(otherContext.destination) threw exception InvalidAccessError: Failed to execute 'connect' on 'AudioNode': cannot connect to a destination belonging to a different audio context.. -PASS node.channelCount = 99 threw exception NotSupportedError: Failed to set the 'channelCount' property on 'AudioNode': The channel count provided (99) is outside the range [1, 32].. -PASS node.channelCount is not 99 -PASS node.channelCountMode = 'fancy' did not throw exception. -PASS Invalid channelCountMode value did not change mode -PASS node.channelInterpretation = mode did not throw exception. -PASS Invalid channelInterpration value did not change mode -PASS context.destination.channelCount = 99 threw IndexSizeError exception on invalid channel count. -PASS param.setValueCurveAtTime(null, 0, 0) threw exception TypeError: Failed to execute 'setValueCurveAtTime' on 'AudioParam': parameter 1 is not of type 'Float32Array'.. -PASS node.getFrequencyResponse(new Float32Array(1), new Float32Array(1), new Float32Array(1)) did not throw exception. -PASS node.getFrequencyResponse(null, new Float32Array(1), new Float32Array(1)) threw exception TypeError: Failed to execute 'getFrequencyResponse' on 'BiquadFilterNode': parameter 1 is not of type 'Float32Array'.. -PASS node.getFrequencyResponse(new Float32Array(1), null, new Float32Array(1)) threw exception TypeError: Failed to execute 'getFrequencyResponse' on 'BiquadFilterNode': parameter 2 is not of type 'Float32Array'.. -PASS node.getFrequencyResponse(new Float32Array(1), new Float32Array(1), null) threw exception TypeError: Failed to execute 'getFrequencyResponse' on 'BiquadFilterNode': parameter 3 is not of type 'Float32Array'.. -PASS new OfflineAudioContext(32, 100, context.sampleRate) did not throw exception. -PASS new OfflineAudioContext(99, 100, context.sampleRate) threw exception IndexSizeError: Failed to construct 'OfflineAudioContext': The number of channels provided (99) is outside the range [0, 32].. -PASS new OfflineAudioContext(1, 100, 1) threw exception IndexSizeError: Failed to construct 'OfflineAudioContext': The sampleRate provided (1) is outside the range [3000, 384000].. -PASS new OfflineAudioContext(1, 100, 1e6) threw exception IndexSizeError: Failed to construct 'OfflineAudioContext': The sampleRate provided (1.00000e+6) is outside the range [3000, 384000].. -PASS new OfflineAudioContext(1, -88200000000000, 44100) threw exception NotSupportedError: Failed to construct 'OfflineAudioContext': OfflineAudioContext(1, 1448390656, 44100). -PASS node.oversample = '9x' did not throw exception. -PASS Invalid oversample value did not change node.oversample -PASS node.curve = {} threw exception TypeError: Failed to set the 'curve' property on 'WaveShaperNode': The provided value is not of type 'Float32Array'.. -PASS node.curve = new Float32Array(1) threw exception InvalidAccessError: Failed to set the 'curve' property on 'WaveShaperNode': The curve length provided (1) is less than the minimum bound (2).. -PASS node.curve is null -PASS node.curve = new Float32Array(2) did not throw exception. -PASS node.curve = null did not throw exception. -PASS source = context.createBufferSource() did not throw exception. -PASS source.buffer = buffer did not throw exception. -PASS source.buffer = context.createBuffer(1, 10, context.sampleRate) threw exception InvalidStateError: Failed to set the 'buffer' property on 'AudioBufferSourceNode': Cannot set buffer after it has been already been set. -PASS source.start(-1) threw exception InvalidAccessError: Failed to execute 'start' on 'AudioBufferSourceNode': The start time provided (-1) is less than the minimum bound (0).. -PASS source.start(Infinity) threw exception TypeError: Failed to execute 'start' on 'AudioBufferSourceNode': The provided double value is non-finite.. -PASS source.start(-Infinity) threw exception TypeError: Failed to execute 'start' on 'AudioBufferSourceNode': The provided double value is non-finite.. -PASS source.start(NaN) threw exception TypeError: Failed to execute 'start' on 'AudioBufferSourceNode': The provided double value is non-finite.. -PASS source.start(1, Infinity) threw exception TypeError: Failed to execute 'start' on 'AudioBufferSourceNode': The provided double value is non-finite.. -PASS source.start(1, -Infinity) threw exception TypeError: Failed to execute 'start' on 'AudioBufferSourceNode': The provided double value is non-finite.. -PASS source.start(1, NaN) threw exception TypeError: Failed to execute 'start' on 'AudioBufferSourceNode': The provided double value is non-finite.. -PASS source.start(1, -1) threw exception InvalidStateError: Failed to execute 'start' on 'AudioBufferSourceNode': The offset provided (-1) is less than the minimum bound (0).. -PASS source.start(1, -Number.MIN_VALUE) threw exception InvalidStateError: Failed to execute 'start' on 'AudioBufferSourceNode': The offset provided (-4.94066e-324) is less than the minimum bound (0).. -PASS source.start(1, 1, Infinity) threw exception TypeError: Failed to execute 'start' on 'AudioBufferSourceNode': The provided double value is non-finite.. -PASS source.start(1, 1, -Infinity) threw exception TypeError: Failed to execute 'start' on 'AudioBufferSourceNode': The provided double value is non-finite.. -PASS source.start(1, 1, NaN) threw exception TypeError: Failed to execute 'start' on 'AudioBufferSourceNode': The provided double value is non-finite.. -PASS source.start(1, 1, -1) threw exception InvalidStateError: Failed to execute 'start' on 'AudioBufferSourceNode': The duration provided (-1) is less than the minimum bound (0).. -PASS source.start(1, 1, -Number.MIN_VALUE) threw exception InvalidStateError: Failed to execute 'start' on 'AudioBufferSourceNode': The duration provided (-4.94066e-324) is less than the minimum bound (0).. -PASS source.start() did not throw exception. -PASS source.stop(-Number.MIN_VALUE) threw exception InvalidAccessError: Failed to execute 'stop' on 'AudioScheduledSourceNode': The stop time provided (-4.94066e-324) is less than the minimum bound (0).. -PASS source.stop(Infinity) threw exception TypeError: Failed to execute 'stop' on 'AudioScheduledSourceNode': The provided double value is non-finite.. -PASS source.stop(-Infinity) threw exception TypeError: Failed to execute 'stop' on 'AudioScheduledSourceNode': The provided double value is non-finite.. -PASS source.stop(NaN) threw exception TypeError: Failed to execute 'stop' on 'AudioScheduledSourceNode': The provided double value is non-finite.. -PASS source.stop() did not throw exception. -PASS source = context.createBufferSource() did not throw exception. -PASS source.buffer = buffer did not throw exception. -PASS source.start(0, 0) did not throw exception. -PASS source = context.createBufferSource() did not throw exception. -PASS source.buffer = buffer did not throw exception. -PASS source.start(0, -1/Infinity) did not throw exception. -PASS source = context.createBufferSource() did not throw exception. -PASS source.start() did not throw exception. -PASS source = context.createBufferSource() did not throw exception. -PASS source.buffer = buffer did not throw exception. -PASS source.stop() threw exception InvalidStateError: Failed to execute 'stop' on 'AudioScheduledSourceNode': cannot call stop without calling start first.. -PASS source = context.createBufferSource() did not throw exception. -PASS source.buffer = buffer did not throw exception. -PASS source.start() did not throw exception. -PASS source.start() threw exception InvalidStateError: Failed to execute 'start' on 'AudioBufferSourceNode': cannot call start more than once.. -PASS source = context.createBufferSource() did not throw exception. -PASS source.buffer = buffer did not throw exception. -PASS source.start() did not throw exception. -PASS source.stop() did not throw exception. -PASS source = context.createOscillator() did not throw exception. -PASS source.start(-Number.MIN_VALUE) threw exception InvalidAccessError: Failed to execute 'start' on 'AudioScheduledSourceNode': The start time provided (-4.94066e-324) is less than the minimum bound (0).. -PASS source.start(Infinity) threw exception TypeError: Failed to execute 'start' on 'AudioScheduledSourceNode': The provided double value is non-finite.. -PASS source.start(-Infinity) threw exception TypeError: Failed to execute 'start' on 'AudioScheduledSourceNode': The provided double value is non-finite.. -PASS source.start(NaN) threw exception TypeError: Failed to execute 'start' on 'AudioScheduledSourceNode': The provided double value is non-finite.. -PASS source.start() did not throw exception. -PASS source.stop(-Number.MIN_VALUE) threw exception InvalidAccessError: Failed to execute 'stop' on 'AudioScheduledSourceNode': The stop time provided (-4.94066e-324) is less than the minimum bound (0).. -PASS source.stop(Infinity) threw exception TypeError: Failed to execute 'stop' on 'AudioScheduledSourceNode': The provided double value is non-finite.. -PASS source.stop(-Infinity) threw exception TypeError: Failed to execute 'stop' on 'AudioScheduledSourceNode': The provided double value is non-finite.. -PASS source.stop(NaN) threw exception TypeError: Failed to execute 'stop' on 'AudioScheduledSourceNode': The provided double value is non-finite.. -PASS source.stop() did not throw exception. -PASS osc = context.createOscillator() did not throw exception. -PASS osc.stop() threw exception InvalidStateError: Failed to execute 'stop' on 'AudioScheduledSourceNode': cannot call stop without calling start first.. -PASS osc1 = context.createOscillator() did not throw exception. -PASS osc1.start() did not throw exception. -PASS osc1.stop() did not throw exception. -PASS osc.setPeriodicWave(null) threw exception TypeError: Failed to execute 'setPeriodicWave' on 'OscillatorNode': parameter 1 is not of type 'PeriodicWave'.. -PASS node.gain.exponentialRampToValueAtTime(-1, 0.1) did not throw exception. -PASS node.gain.exponentialRampToValueAtTime(0, 0.1) threw exception InvalidAccessError: Failed to execute 'exponentialRampToValueAtTime' on 'AudioParam': The float target value provided (0) should not be in the range (-1.40130e-45, 1.40130e-45).. -PASS node.gain.exponentialRampToValueAtTime(1e-100, 0.1) threw exception InvalidAccessError: Failed to execute 'exponentialRampToValueAtTime' on 'AudioParam': The float target value provided (0) should not be in the range (-1.40130e-45, 1.40130e-45).. -PASS node.gain.exponentialRampToValueAtTime(Math.pow(2, -149), 0.1) did not throw exception. -PASS node.gain.exponentialRampToValueAtTime(Math.pow(2, -150), 0.1) threw exception InvalidAccessError: Failed to execute 'exponentialRampToValueAtTime' on 'AudioParam': The float target value provided (0) should not be in the range (-1.40130e-45, 1.40130e-45).. -PASS oc = new OfflineAudioContext(1, 44100, 44100) did not throw exception. -PASS conv = oc.createConvolver() did not throw exception. -PASS conv.buffer = {} threw exception TypeError: Failed to set the 'buffer' property on 'ConvolverNode': The provided value is not of type 'AudioBuffer'.. -PASS conv.buffer = oc.createBuffer(1, 100, 22050) threw exception NotSupportedError: Failed to set the 'buffer' property on 'ConvolverNode': The buffer sample rate of 22050 does not match the context rate of 44100 Hz.. -PASS conv.buffer is null -PASS panner.channelCount = 1 did not throw exception. -PASS panner.channelCount = 2 did not throw exception. -PASS panner.channelCount = 0 threw exception NotSupportedError: Failed to set the 'channelCount' property on 'AudioNode': The channelCount provided (0) is outside the range [1, 2].. -PASS panner.channelCount is not 0 -PASS panner.channelCount = 3 threw exception NotSupportedError: Failed to set the 'channelCount' property on 'AudioNode': The channelCount provided (3) is outside the range [1, 2].. -PASS panner.channelCount is not 3 -PASS panner.channelCountMode = 'max' threw exception NotSupportedError: Failed to set the 'channelCountMode' property on 'AudioNode': Panner: 'max' is not allowed. -PASS panner.channelCountMode is not 'max' -PASS panner.channelCountMode = 'explicit' did not throw exception. -PASS panner.channelCountMode = 'clamped-max' did not throw exception. -PASS panner.channelCountMode = 'junk' did not throw exception. -PASS script = context.createScriptProcessor(256, 3) did not throw exception. -PASS script.channelCount is 3 -PASS script.channelCountMode is "explicit" -PASS script.channelCount = 3 did not throw exception. -PASS script.channelCount = 1 threw exception NotSupportedError: Failed to set the 'channelCount' property on 'AudioNode': channelCount cannot be changed from 3 to 1. -PASS script.channelCount is not 1 -PASS script.channelCount = 7 threw exception NotSupportedError: Failed to set the 'channelCount' property on 'AudioNode': channelCount cannot be changed from 3 to 7. -PASS script.channelCount is not 7 -PASS script.channelCountMode = 'explicit' did not throw exception. -PASS script.channelCountMode = 'max' threw exception NotSupportedError: Failed to set the 'channelCountMode' property on 'AudioNode': channelCountMode cannot be changed from 'explicit' to 'max'. -PASS script.channelCountMode is not 'max' -PASS script.channelCountMode = 'clamped-max' threw exception NotSupportedError: Failed to set the 'channelCountMode' property on 'AudioNode': channelCountMode cannot be changed from 'explicit' to 'clamped-max'. -PASS script.channelCountMode is not 'clamped-max' -PASS script.channelCountMode = 'junk' did not throw exception. -PASS osc.noteOn is undefined. -PASS osc.noteOff is undefined. -PASS source.noteOn is undefined. -PASS source.noteOff is undefined. -PASS successfullyParsed is true - -TEST COMPLETE +CONSOLE ERROR: line 39: [audit.js] this test requires the explicit comparison with the expected result when it runs with run-webkit-tests. +CONSOLE WARNING: line 308: The provided value 'fancy' is not a valid enum value of type ChannelCountMode. +CONSOLE WARNING: line 312: The provided value 'undefined' is not a valid enum value of type ChannelInterpretation. +CONSOLE WARNING: line 442: The provided value '9x' is not a valid enum value of type OverSampleType. +CONSOLE WARNING: line 645: The provided value 'junk' is not a valid enum value of type ChannelCountMode. +CONSOLE WARNING: line 676: The provided value 'junk' is not a valid enum value of type ChannelCountMode. +This is a testharness.js-based test. +PASS # AUDIT TASK RUNNER STARTED. +PASS > [initialize] +PASS context = new AudioContext() did not throw an exception. +PASS otherContext = new AudioContext() did not throw an exception. +PASS < [initialize] All assertions passed. (total 2 assertions) +PASS > [createBuffer] +PASS context.createBuffer(99, 1, context.sampleRate) threw NotSupportedError: "Failed to execute 'createBuffer' on 'BaseAudioContext': The number of channels provided (99) is outside the range [1, 32].". +PASS context.createBuffer(0, 1, context.sampleRate) threw NotSupportedError: "Failed to execute 'createBuffer' on 'BaseAudioContext': The number of channels provided (0) is outside the range [1, 32].". +PASS context.createBuffer(1, 1, 1) threw NotSupportedError: "Failed to execute 'createBuffer' on 'BaseAudioContext': The sample rate provided (1) is outside the range [3000, 384000].". +PASS context.createBuffer(1, 1, 2999) threw NotSupportedError: "Failed to execute 'createBuffer' on 'BaseAudioContext': The sample rate provided (2999) is outside the range [3000, 384000].". +PASS context.createBuffer(1, 1, 384001) threw NotSupportedError: "Failed to execute 'createBuffer' on 'BaseAudioContext': The sample rate provided (384001) is outside the range [3000, 384000].". +PASS context.createBuffer(1, 1, 1e6) threw NotSupportedError: "Failed to execute 'createBuffer' on 'BaseAudioContext': The sample rate provided (1.00000e+6) is outside the range [3000, 384000].". +PASS context.createBuffer(1, 1, 3000) did not throw an exception. +PASS context.createBuffer(1, 1, 192000) did not throw an exception. +PASS context.createBuffer(1, 1, 384000) did not throw an exception. +PASS context.createBuffer(1, 0, context.sampleRate) threw NotSupportedError: "Failed to execute 'createBuffer' on 'BaseAudioContext': The number of frames provided (0) is less than or equal to the minimum bound (0).". +PASS context.createBuffer(new ArrayBuffer(100), true) threw TypeError: "Failed to execute 'createBuffer' on 'BaseAudioContext': 3 arguments required, but only 2 present.". +PASS < [createBuffer] All assertions passed. (total 11 assertions) +PASS > [createMediaElementSource] +PASS context.createMediaElementSource(null) threw TypeError: "Failed to execute 'createMediaElementSource' on 'BaseAudioContext': parameter 1 is not of type 'HTMLMediaElement'.". +PASS < [createMediaElementSource] All assertions passed. (total 1 assertions) +PASS > [createMediaStreamSource] +PASS context.createMediaStreamSource(null) threw TypeError: "Failed to execute 'createMediaStreamSource' on 'BaseAudioContext': parameter 1 is not of type 'MediaStream'.". +PASS < [createMediaStreamSource] All assertions passed. (total 1 assertions) +PASS > [createScriptProcessor] +PASS context.createScriptProcessor(1, 1, 1) threw IndexSizeError: "Failed to execute 'createScriptProcessor' on 'BaseAudioContext': buffer size (1) must be 0 or a power of two between 256 and 16384.". +PASS context.createScriptProcessor(4096, 100, 1) threw IndexSizeError: "Failed to execute 'createScriptProcessor' on 'BaseAudioContext': number of input channels (100) exceeds maximum (32).". +PASS context.createScriptProcessor(4096, 1, 100) threw IndexSizeError: "Failed to execute 'createScriptProcessor' on 'BaseAudioContext': number of output channels (100) exceeds maximum (32).". +PASS context.createScriptProcessor() did not throw an exception. +PASS context.createScriptProcessor(0) did not throw an exception. +PASS < [createScriptProcessor] All assertions passed. (total 5 assertions) +PASS > [createChannelSplitter] +PASS context.createChannelSplitter(0) threw IndexSizeError: "Failed to execute 'createChannelSplitter' on 'BaseAudioContext': The number of outputs provided (0) is outside the range [1, 32].". +PASS context.createChannelSplitter(99) threw IndexSizeError: "Failed to execute 'createChannelSplitter' on 'BaseAudioContext': The number of outputs provided (99) is outside the range [1, 32].". +PASS context.createChannelMerger(0) threw IndexSizeError: "Failed to execute 'createChannelMerger' on 'BaseAudioContext': The number of inputs provided (0) is outside the range [1, 32].". +PASS < [createChannelSplitter] All assertions passed. (total 3 assertions) +PASS > [createChannelMerger] +PASS context.createChannelMerger(99) threw IndexSizeError: "Failed to execute 'createChannelMerger' on 'BaseAudioContext': The number of inputs provided (99) is outside the range [1, 32].". +PASS < [createChannelMerger] All assertions passed. (total 1 assertions) +PASS > [createPeriodicWave] +PASS context.createPeriodicWave(null, null) threw TypeError: "Failed to execute 'createPeriodicWave' on 'BaseAudioContext': parameter 1 is not of type 'Float32Array'.". +PASS context.createPeriodicWave(new Float32Array(10), null) threw TypeError: "Failed to execute 'createPeriodicWave' on 'BaseAudioContext': parameter 2 is not of type 'Float32Array'.". +PASS context.createPeriodicWave(new Float32Array(4100), new Float32Array(4100)) did not throw an exception. +PASS context.createPeriodicWave(new Float32Array(8192), new Float32Array(8192)) did not throw an exception. +PASS context.createPeriodicWave(new Float32Array(10000), new Float32Array(10000)) did not throw an exception. +PASS context.createPeriodicWave(new Float32Array(10), new Float32Array(7)) threw IndexSizeError: "Failed to execute 'createPeriodicWave' on 'BaseAudioContext': length of real array (10) and length of imaginary array (7) must match.". +PASS < [createPeriodicWave] All assertions passed. (total 6 assertions) +PASS > [createAnalyser] +PASS AnalyserNode.fftSize = 42 threw IndexSizeError: "Failed to set the 'fftSize' property on 'AnalyserNode': The value provided (42) is not a power of two.". +PASS AnalyserNode.fftSize is not equal to 42. +PASS AnalyserNode.fftSize = 16 threw IndexSizeError: "Failed to set the 'fftSize' property on 'AnalyserNode': The FFT size provided (16) is outside the range [32, 32768].". +PASS AnalyserNode.fftSize is not equal to 16. +PASS AnalyserNode.fftSize = 32768 did not throw an exception. +PASS AnalyserNode.fftSize = 65536 threw IndexSizeError: "Failed to set the 'fftSize' property on 'AnalyserNode': The FFT size provided (65536) is outside the range [32, 32768].". +PASS AnalyserNode.fftSize is not equal to 65536. +PASS AnalyserNode.minDecibels = -10 threw IndexSizeError: "Failed to set the 'minDecibels' property on 'AnalyserNode': The minDecibels provided (-10) is greater than the maximum bound (-30).". +PASS AnalyserNode.minDecibels is not equal to -10. +PASS AnalyserNode.maxDecibels = -150 threw IndexSizeError: "Failed to set the 'maxDecibels' property on 'AnalyserNode': The maxDecibels provided (-150) is less than the minimum bound (-100).". +PASS AnalyserNode.maxDecibels is not equal to -150. +PASS AnalyserNode.minDecibels = -30 threw IndexSizeError: "Failed to set the 'minDecibels' property on 'AnalyserNode': The minDecibels provided (-30) is greater than or equal to the maximum bound (-30).". +PASS AnalyserNode.minDecibels is not equal to -30. +PASS AnalyserNode.maxDecibels = -100 threw IndexSizeError: "Failed to set the 'maxDecibels' property on 'AnalyserNode': The maxDecibels provided (-100) is less than or equal to the minimum bound (-100).". +PASS AnalyserNode.maxDecibels is not equal to -100. +PASS AnalyserNode.smoothingTimeConstant = -0.1 threw IndexSizeError: "Failed to set the 'smoothingTimeConstant' property on 'AnalyserNode': The smoothing value provided (-0.1) is outside the range [0, 1].". +PASS AnalyserNode.smoothingTimeConstant is not equal to -0.1. +PASS AnalyserNode.smoothingTimeConstant = 1.5 threw IndexSizeError: "Failed to set the 'smoothingTimeConstant' property on 'AnalyserNode': The smoothing value provided (1.5) is outside the range [0, 1].". +PASS AnalyserNode.smoothingTimeConstant is not equal to 1.5. +PASS AnalyserNode.getFloatFrequencyData(null) threw TypeError: "Failed to execute 'getFloatFrequencyData' on 'AnalyserNode': parameter 1 is not of type 'Float32Array'.". +PASS AnalyserNode.getByteFrequencyData(null) threw TypeError: "Failed to execute 'getByteFrequencyData' on 'AnalyserNode': parameter 1 is not of type 'Uint8Array'.". +PASS AnalyserNode.getFloatTimeDomainData(null) threw TypeError: "Failed to execute 'getFloatTimeDomainData' on 'AnalyserNode': parameter 1 is not of type 'Float32Array'.". +PASS AnalyserNode.getByteTimeDomainData(null) threw TypeError: "Failed to execute 'getByteTimeDomainData' on 'AnalyserNode': parameter 1 is not of type 'Uint8Array'.". +PASS AudioBuffer.getChannelData(2) threw IndexSizeError: "Failed to execute 'getChannelData' on 'AudioBuffer': channel index (2) exceeds number of channels (1)". +PASS < [createAnalyser] All assertions passed. (total 24 assertions) +PASS > [Init test nodes] +PASS node = context.createGain() did not throw an exception. +PASS node2 = context.createGain() did not throw an exception. +PASS < [Init test nodes] All assertions passed. (total 2 assertions) +PASS > [connections] +PASS node.connect(null, 0, 0) threw TypeError: "Failed to execute 'connect' on 'AudioNode': parameter 1 is not of type 'AudioNode'.". +PASS node.connect(context.destination, 100, 0) threw IndexSizeError: "Failed to execute 'connect' on 'AudioNode': output index (100) exceeds number of outputs (1).". +PASS node.connect(context.destination, 0, 100) threw IndexSizeError: "Failed to execute 'connect' on 'AudioNode': input index (100) exceeds number of inputs (1).". +PASS node.connect(node2.gain, 100) threw IndexSizeError: "Failed to execute 'connect' on 'AudioNode': output index (100) exceeds number of outputs (1).". +PASS node.disconnect(99) threw IndexSizeError: "Failed to execute 'disconnect' on 'AudioNode': The output index provided (99) is outside the range [0, 0].". +PASS node.connect(otherContext.destination) threw InvalidAccessError: "Failed to execute 'connect' on 'AudioNode': cannot connect to a destination belonging to a different audio context.". +PASS < [connections] All assertions passed. (total 6 assertions) +PASS > [channel-stuff] +PASS GainNode.channelCount = 99 threw NotSupportedError: "Failed to set the 'channelCount' property on 'AudioNode': The channel count provided (99) is outside the range [1, 32].". +PASS GainNode.channelCount is not equal to 99. +PASS node.channelCountMode = "fancy" did not throw an exception. +PASS node.channelCountMode is equal to max. +PASS node.channelInterpretation = mode did not throw an exception. +PASS node.channelInterpretation is equal to speakers. +PASS context.destination.channelCount = 99 threw IndexSizeError: "Failed to set the 'channelCount' property on 'AudioNode': The channel count provided (99) is outside the range [1, 2].". +PASS < [channel-stuff] All assertions passed. (total 7 assertions) +PASS > [audioparam] +PASS param.setValueCurveAtTime(null, 0, 0) threw TypeError: "Failed to execute 'setValueCurveAtTime' on 'AudioParam': parameter 1 is not of type 'Float32Array'.". +PASS node.gain.exponentialRampToValueAtTime(-1, 0.1) did not throw an exception. +PASS node.gain.exponentialRampToValueAtTime(0, 0.1) threw InvalidAccessError: "Failed to execute 'exponentialRampToValueAtTime' on 'AudioParam': The float target value provided (0) should not be in the range (-1.40130e-45, 1.40130e-45).". +PASS node.gain.exponentialRampToValueAtTime(1e-100, 0.1) threw InvalidAccessError: "Failed to execute 'exponentialRampToValueAtTime' on 'AudioParam': The float target value provided (0) should not be in the range (-1.40130e-45, 1.40130e-45).". +PASS node.gain.exponentialRampToValueAtTime(Math.pow(2, -149), 0.1) did not throw an exception. +PASS node.gain.exponentialRampToValueAtTime(Math.pow(2, -150), 0.1) threw InvalidAccessError: "Failed to execute 'exponentialRampToValueAtTime' on 'AudioParam': The float target value provided (0) should not be in the range (-1.40130e-45, 1.40130e-45).". +PASS < [audioparam] All assertions passed. (total 6 assertions) +PASS > [biquad] +PASS node.getFrequencyResponse(new Float32Array(1), new Float32Array(1), new Float32Array(1)) did not throw an exception. +PASS node.getFrequencyResponse(null, new Float32Array(1), new Float32Array(1)) threw TypeError: "Failed to execute 'getFrequencyResponse' on 'BiquadFilterNode': parameter 1 is not of type 'Float32Array'.". +PASS node.getFrequencyResponse(new Float32Array(1), null, new Float32Array(1)) threw TypeError: "Failed to execute 'getFrequencyResponse' on 'BiquadFilterNode': parameter 2 is not of type 'Float32Array'.". +PASS node.getFrequencyResponse(new Float32Array(1), new Float32Array(1), null) threw TypeError: "Failed to execute 'getFrequencyResponse' on 'BiquadFilterNode': parameter 3 is not of type 'Float32Array'.". +PASS < [biquad] All assertions passed. (total 4 assertions) +PASS > [offline-audio-context] +PASS new OfflineAudioContext(32, 100, context.sampleRate) did not throw an exception. +PASS new OfflineAudioContext(99, 100, context.sampleRate) threw IndexSizeError: "Failed to construct 'OfflineAudioContext': The number of channels provided (99) is outside the range [0, 32].". +PASS new OfflineAudioContext(1, 100, 1) threw IndexSizeError: "Failed to construct 'OfflineAudioContext': The sampleRate provided (1) is outside the range [3000, 384000].". +PASS new OfflineAudioContext(1, 100, 1e6) threw IndexSizeError: "Failed to construct 'OfflineAudioContext': The sampleRate provided (1.00000e+6) is outside the range [3000, 384000].". +PASS new OfflineAudioContext(1, -88200000000000, 44100) threw NotSupportedError: "Failed to construct 'OfflineAudioContext': OfflineAudioContext(1, 1448390656, 44100)". +PASS < [offline-audio-context] All assertions passed. (total 5 assertions) +PASS > [waveshaper] +PASS node.oversample = "9x" did not throw an exception. +PASS node.oversample is equal to none. +PASS node.curve = {} threw TypeError: "Failed to set the 'curve' property on 'WaveShaperNode': The provided value is not of type 'Float32Array'.". +PASS node.curve = new Float32Array(1) threw InvalidAccessError: "Failed to set the 'curve' property on 'WaveShaperNode': The curve length provided (1) is less than the minimum bound (2).". +PASS node.curve is equal to ${expected}. +PASS node.curve = new Float32Array(2) did not throw an exception. +PASS node.curve = null did not throw an exception. +PASS < [waveshaper] All assertions passed. (total 7 assertions) +PASS > [audio-buffer-source] +PASS source = context.createBufferSource() did not throw an exception. +PASS source.buffer = buffer did not throw an exception. +PASS source.buffer = context.createBuffer(1, 10, context.sampleRate) threw InvalidStateError: "Failed to set the 'buffer' property on 'AudioBufferSourceNode': Cannot set buffer after it has been already been set". +PASS source.start(-1) threw InvalidAccessError: "Failed to execute 'start' on 'AudioBufferSourceNode': The start time provided (-1) is less than the minimum bound (0).". +PASS source.start(Infinity) threw TypeError: "Failed to execute 'start' on 'AudioBufferSourceNode': The provided double value is non-finite.". +PASS source.start(-Infinity) threw TypeError: "Failed to execute 'start' on 'AudioBufferSourceNode': The provided double value is non-finite.". +PASS source.start(NaN) threw TypeError: "Failed to execute 'start' on 'AudioBufferSourceNode': The provided double value is non-finite.". +PASS source.start(1, Infinity) threw TypeError: "Failed to execute 'start' on 'AudioBufferSourceNode': The provided double value is non-finite.". +PASS source.start(1, -Infinity) threw TypeError: "Failed to execute 'start' on 'AudioBufferSourceNode': The provided double value is non-finite.". +PASS source.start(1, NaN) threw TypeError: "Failed to execute 'start' on 'AudioBufferSourceNode': The provided double value is non-finite.". +PASS source.start(1, -1) threw InvalidStateError: "Failed to execute 'start' on 'AudioBufferSourceNode': The offset provided (-1) is less than the minimum bound (0).". +PASS source.start(1, -Number.MIN_VALUE) threw InvalidStateError: "Failed to execute 'start' on 'AudioBufferSourceNode': The offset provided (-4.94066e-324) is less than the minimum bound (0).". +PASS source.start(1, 1, Infinity) threw TypeError: "Failed to execute 'start' on 'AudioBufferSourceNode': The provided double value is non-finite.". +PASS source.start(1, 1, -Infinity) threw TypeError: "Failed to execute 'start' on 'AudioBufferSourceNode': The provided double value is non-finite.". +PASS source.start(1, 1, NaN) threw TypeError: "Failed to execute 'start' on 'AudioBufferSourceNode': The provided double value is non-finite.". +PASS source.start(1, 1, -1) threw InvalidStateError: "Failed to execute 'start' on 'AudioBufferSourceNode': The duration provided (-1) is less than the minimum bound (0).". +PASS source.start(1, 1, -Number.MIN_VALUE) threw InvalidStateError: "Failed to execute 'start' on 'AudioBufferSourceNode': The duration provided (-4.94066e-324) is less than the minimum bound (0).". +PASS source.start() did not throw an exception. +PASS source.stop(-Number.MIN_VALUE) threw InvalidAccessError: "Failed to execute 'stop' on 'AudioScheduledSourceNode': The stop time provided (-4.94066e-324) is less than the minimum bound (0).". +PASS source.stop(Infinity) threw TypeError: "Failed to execute 'stop' on 'AudioScheduledSourceNode': The provided double value is non-finite.". +PASS source.stop(-Infinity) threw TypeError: "Failed to execute 'stop' on 'AudioScheduledSourceNode': The provided double value is non-finite.". +PASS source.stop(NaN) threw TypeError: "Failed to execute 'stop' on 'AudioScheduledSourceNode': The provided double value is non-finite.". +PASS source.stop() did not throw an exception. +PASS source = context.createBufferSource() did not throw an exception. +PASS source.buffer = buffer did not throw an exception. +PASS source.start(0, 0) did not throw an exception. +PASS source = context.createBufferSource() did not throw an exception. +PASS source.buffer = buffer did not throw an exception. +PASS source.start(0, -1/Infinity) did not throw an exception. +PASS source = context.createBufferSource() did not throw an exception. +PASS source.start() did not throw an exception. +PASS source = context.createBufferSource() did not throw an exception. +PASS source.buffer = buffer did not throw an exception. +PASS source.stop() threw InvalidStateError: "Failed to execute 'stop' on 'AudioScheduledSourceNode': cannot call stop without calling start first.". +PASS source = context.createBufferSource() did not throw an exception. +PASS source.buffer = buffer did not throw an exception. +PASS source.start() did not throw an exception. +PASS source.start() threw InvalidStateError: "Failed to execute 'start' on 'AudioBufferSourceNode': cannot call start more than once.". +PASS source = context.createBufferSource() did not throw an exception. +PASS source.buffer = buffer did not throw an exception. +PASS source.start() did not throw an exception. +PASS source.stop() did not throw an exception. +PASS < [audio-buffer-source] All assertions passed. (total 42 assertions) +PASS > [oscillator] +PASS source = context.createOscillator() did not throw an exception. +PASS source.start(-Number.MIN_VALUE) threw InvalidAccessError: "Failed to execute 'start' on 'AudioScheduledSourceNode': The start time provided (-4.94066e-324) is less than the minimum bound (0).". +PASS source.start(Infinity) threw TypeError: "Failed to execute 'start' on 'AudioScheduledSourceNode': The provided double value is non-finite.". +PASS source.start(-Infinity) threw TypeError: "Failed to execute 'start' on 'AudioScheduledSourceNode': The provided double value is non-finite.". +PASS source.start(NaN) threw TypeError: "Failed to execute 'start' on 'AudioScheduledSourceNode': The provided double value is non-finite.". +PASS source.start() did not throw an exception. +PASS source.stop(-Number.MIN_VALUE) threw InvalidAccessError: "Failed to execute 'stop' on 'AudioScheduledSourceNode': The stop time provided (-4.94066e-324) is less than the minimum bound (0).". +PASS source.stop(Infinity) threw TypeError: "Failed to execute 'stop' on 'AudioScheduledSourceNode': The provided double value is non-finite.". +PASS source.stop(-Infinity) threw TypeError: "Failed to execute 'stop' on 'AudioScheduledSourceNode': The provided double value is non-finite.". +PASS source.stop(NaN) threw TypeError: "Failed to execute 'stop' on 'AudioScheduledSourceNode': The provided double value is non-finite.". +PASS source.stop() did not throw an exception. +PASS osc = context.createOscillator() did not throw an exception. +PASS osc.stop() threw InvalidStateError: "Failed to execute 'stop' on 'AudioScheduledSourceNode': cannot call stop without calling start first.". +PASS osc1 = context.createOscillator() did not throw an exception. +PASS osc1.start() did not throw an exception. +PASS osc1.stop() did not throw an exception. +PASS osc.setPeriodicWave(null) threw TypeError: "Failed to execute 'setPeriodicWave' on 'OscillatorNode': parameter 1 is not of type 'PeriodicWave'.". +PASS < [oscillator] All assertions passed. (total 17 assertions) +PASS > [convolver] +PASS oc = new OfflineAudioContext(1, 44100, 44100) did not throw an exception. +PASS conv = oc.createConvolver() did not throw an exception. +PASS conv.buffer = {} threw TypeError: "Failed to set the 'buffer' property on 'ConvolverNode': The provided value is not of type 'AudioBuffer'.". +PASS conv.buffer = oc.createBuffer(1, 100, 22050) threw NotSupportedError: "Failed to set the 'buffer' property on 'ConvolverNode': The buffer sample rate of 22050 does not match the context rate of 44100 Hz.". +PASS conv.buffer is equal to ${expected}. +PASS < [convolver] All assertions passed. (total 5 assertions) +PASS > [panner] +PASS panner.channelCount = 1 did not throw an exception. +PASS panner.channelCount = 2 did not throw an exception. +PASS PannerNode.channelCount = 0 threw NotSupportedError: "Failed to set the 'channelCount' property on 'AudioNode': The channelCount provided (0) is outside the range [1, 2].". +PASS PannerNode.channelCount is not equal to 0. +PASS PannerNode.channelCount = 3 threw NotSupportedError: "Failed to set the 'channelCount' property on 'AudioNode': The channelCount provided (3) is outside the range [1, 2].". +PASS PannerNode.channelCount is not equal to 3. +PASS PannerNode.channelCountMode = max threw NotSupportedError: "Failed to set the 'channelCountMode' property on 'AudioNode': Panner: 'max' is not allowed". +PASS PannerNode.channelCountMode is not equal to max. +PASS panner.channelCountMode = "explicit" did not throw an exception. +PASS panner.channelCountMode = "clamped-max" did not throw an exception. +PASS panner.channelCountMode = "junk" did not throw an exception. +PASS < [panner] All assertions passed. (total 11 assertions) +PASS > [script-processor] +PASS script = context.createScriptProcessor(256, 3) did not throw an exception. +PASS script.channelCount is equal to 3. +PASS script.channelCountMode is equal to explicit. +PASS script.channelCount = 3 did not throw an exception. +PASS ScriptProcessorNode.channelCount = 1 threw NotSupportedError: "Failed to set the 'channelCount' property on 'AudioNode': channelCount cannot be changed from 3 to 1". +PASS ScriptProcessorNode.channelCount is not equal to 1. +PASS ScriptProcessorNode.channelCount = 7 threw NotSupportedError: "Failed to set the 'channelCount' property on 'AudioNode': channelCount cannot be changed from 3 to 7". +PASS ScriptProcessorNode.channelCount is not equal to 7. +PASS script.channelCountMode = "explicit" did not throw an exception. +PASS ScriptProcessorNode.channelCountMode = max threw NotSupportedError: "Failed to set the 'channelCountMode' property on 'AudioNode': channelCountMode cannot be changed from 'explicit' to 'max'". +PASS ScriptProcessorNode.channelCountMode is not equal to max. +PASS ScriptProcessorNode.channelCountMode = clamped-max threw NotSupportedError: "Failed to set the 'channelCountMode' property on 'AudioNode': channelCountMode cannot be changed from 'explicit' to 'clamped-max'". +PASS ScriptProcessorNode.channelCountMode is not equal to clamped-max. +PASS script.channelCountMode = "junk" did not throw an exception. +PASS < [script-processor] All assertions passed. (total 14 assertions) +PASS > [misc] +PASS osc.noteOn is equal to undefined. +PASS osc.noteOff is equal to undefined. +PASS source.noteOn is equal to undefined. +PASS source.noteOff is equal to undefined. +PASS < [misc] All assertions passed. (total 4 assertions) +PASS # AUDIT TASK RUNNER FINISHED: 22 tasks ran successfully. +Harness: the test ran to completion.
diff --git a/third_party/WebKit/LayoutTests/webaudio/dom-exceptions.html b/third_party/WebKit/LayoutTests/webaudio/dom-exceptions.html index b1c8667..1ed09766 100644 --- a/third_party/WebKit/LayoutTests/webaudio/dom-exceptions.html +++ b/third_party/WebKit/LayoutTests/webaudio/dom-exceptions.html
@@ -1,336 +1,698 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> +<!doctype html> <html> <head> -<script src="../resources/js-test.js"></script> +<script src="../resources/testharness.js"></script> +<script src="../resources/testharnessreport.js"></script> <script src="resources/audit-util.js"></script> -<script src="resources/audio-testing.js"></script> +<script src="resources/audit.js"></script> <script src="resources/biquad-testing.js"></script> </head> <body> - -<div id="description"></div> -<div id="console"></div> <script> -description("Tests DOM exception messages"); +let audit = Audit.createTaskRunner({requireResultFile: true}); -var context; -var otherContext; -var node; -var node2; -var mode; -var panner; -var script; +let otherContext; +let node; +let node2; +let mode; +let panner; +let script; -function shouldThrowAndBeUnchanged(attr, value) { - shouldThrow(attr + " = " + value); - shouldNotBe(attr, value); +function shouldThrowAndBeUnchanged(should, node, attr, value) { + should( + () => node[attr] = value, + node.constructor.name + '.' + attr + ' = ' + value) + .throw(); + should(node[attr], node.constructor.name + '.' + attr).notBeEqualTo(value); } -function runTest() { - if (window.testRunner) { - testRunner.dumpAsText(); - } +audit.define('initialize', (task, should) => { + task.describe('Initialize contexts for testing'); + should(() => { context = new AudioContext(); - otherContext = new AudioContext(); + }, 'context = new AudioContext()').notThrow(); - // Test creation of various objects + should(() => { + otherContext = new AudioContext(); }, + 'otherContext = new AudioContext()') + .notThrow(); - // Invalid number of channels: NotSupportedError - shouldThrow("context.createBuffer(99, 1, context.sampleRate)"); - shouldThrow("context.createBuffer(0, 1, context.sampleRate)"); - // Invalid sample rate: NotSupportedError - shouldThrow("context.createBuffer(1, 1, 1)"); - shouldThrow("context.createBuffer(1, 1, 2999)"); - shouldThrow("context.createBuffer(1, 1, 384001)"); - shouldThrow("context.createBuffer(1, 1, 1e6)"); - // Check valid values from crbug.com/344375 - shouldNotThrow("context.createBuffer(1, 1, 3000)"); - shouldNotThrow("context.createBuffer(1, 1, 192000)"); - shouldNotThrow("context.createBuffer(1, 1, 384000)"); - // Invalid number of frames: NotSupportedError - shouldThrow("context.createBuffer(1, 0, context.sampleRate)"); - // 2-arg createBuffer not allowed. - shouldThrow("context.createBuffer(new ArrayBuffer(100), true)"); - // Invalid sources (unspecified error) - shouldThrow("context.createMediaElementSource(null)"); - shouldThrow("context.createMediaStreamSource(null)"); - // Invalid buffer size: IndexSizeError - shouldThrow("context.createScriptProcessor(1, 1, 1)"); - // Invalid number of inputs and outputs: IndexSizeError - shouldThrow("context.createScriptProcessor(4096, 100, 1)"); - shouldThrow("context.createScriptProcessor(4096, 1, 100)"); - shouldNotThrow("context.createScriptProcessor()"); - shouldNotThrow("context.createScriptProcessor(0)"); + task.done(); +}); - // Invalid number of channels: IndexSizeError - shouldThrow("context.createChannelSplitter(0)"); - shouldThrow("context.createChannelSplitter(99)"); - shouldThrow("context.createChannelMerger(0)"); - shouldThrow("context.createChannelMerger(99)"); - // Invalid real/imag arrays: IndexSizeError - shouldThrow("context.createPeriodicWave(null, null)"); - shouldThrow("context.createPeriodicWave(new Float32Array(10), null)"); - // Verify that we can use large arrays with no limit. Roughly. - shouldNotThrow("context.createPeriodicWave(new Float32Array(4100), new Float32Array(4100))"); - shouldNotThrow("context.createPeriodicWave(new Float32Array(8192), new Float32Array(8192))"); - shouldNotThrow("context.createPeriodicWave(new Float32Array(10000), new Float32Array(10000))"); - // Real and imaginary arrays must have the same size: IndexSizeError - shouldThrow("context.createPeriodicWave(new Float32Array(10), new Float32Array(7))"); +audit.define('createBuffer', (task, should) => { + task.describe('createBuffer'); + + // Invalid number of channels: NotSupportedError + should( + () => context.createBuffer(99, 1, context.sampleRate), + 'context.createBuffer(99, 1, context.sampleRate)') + .throw('NotSupportedError'); + should( + () => context.createBuffer(0, 1, context.sampleRate), + 'context.createBuffer(0, 1, context.sampleRate)') + .throw('NotSupportedError'); + // Invalid sample rate: NotSupportedError + should(() => context.createBuffer(1, 1, 1), 'context.createBuffer(1, 1, 1)') + .throw('NotSupportedError'); + should( + () => context.createBuffer(1, 1, 2999), + 'context.createBuffer(1, 1, 2999)') + .throw('NotSupportedError'); + should( + () => context.createBuffer(1, 1, 384001), + 'context.createBuffer(1, 1, 384001)') + .throw('NotSupportedError'); + should( + () => context.createBuffer(1, 1, 1e6), 'context.createBuffer(1, 1, 1e6)') + .throw('NotSupportedError'); + // Check valid values from crbug.com/344375 + should( + () => context.createBuffer(1, 1, 3000), + 'context.createBuffer(1, 1, 3000)') + .notThrow(); + should( + () => context.createBuffer(1, 1, 192000), + 'context.createBuffer(1, 1, 192000)') + .notThrow(); + should( + () => context.createBuffer(1, 1, 384000), + 'context.createBuffer(1, 1, 384000)') + .notThrow(); + // Invalid number of frames: NotSupportedError + should( + () => context.createBuffer(1, 0, context.sampleRate), + 'context.createBuffer(1, 0, context.sampleRate)') + .throw('NotSupportedError'); + // 2-arg createBuffer not allowed. + should( + () => context.createBuffer(new ArrayBuffer(100), true), + 'context.createBuffer(new ArrayBuffer(100), true)') + .throw('TypeError'); + + task.done(); +}); + +audit.define('createMediaElementSource', (task, should) => { + task.describe('createMediaElementSource'); + + // Invalid sources (unspecified error) + should( + () => context.createMediaElementSource(null), + 'context.createMediaElementSource(null)') + .throw(); + task.done(); +}); + +audit.define('createMediaStreamSource', (task, should) => { + task.describe('createMediaStreamSource'); + + // Invalid sources (unspecified error) + should( + () => context.createMediaStreamSource(null), + 'context.createMediaStreamSource(null)') + .throw(); + + task.done(); +}); + +audit.define('createScriptProcessor', (task, should) => { + task.describe('createScriptProcessor'); + + // Invalid buffer size: IndexSizeError + should( + () => context.createScriptProcessor(1, 1, 1), + 'context.createScriptProcessor(1, 1, 1)') + .throw('IndexSizeError'); + // Invalid number of inputs and outputs: IndexSizeError + should( + () => context.createScriptProcessor(4096, 100, 1), + 'context.createScriptProcessor(4096, 100, 1)') + .throw('IndexSizeError'); + should( + () => context.createScriptProcessor(4096, 1, 100), + 'context.createScriptProcessor(4096, 1, 100)') + .throw('IndexSizeError'); + should( + () => context.createScriptProcessor(), 'context.createScriptProcessor()') + .notThrow(); + should( + () => context.createScriptProcessor(0), + 'context.createScriptProcessor(0)') + .notThrow(); + + task.done(); +}); + +audit.define('createChannelSplitter', (task, should) => { + task.describe('createChannelSplitter'); + + // Invalid number of channels: IndexSizeError + should( + () => context.createChannelSplitter(0), + 'context.createChannelSplitter(0)') + .throw('IndexSizeError'); + should( + () => context.createChannelSplitter(99), + 'context.createChannelSplitter(99)') + .throw('IndexSizeError'); + should(() => context.createChannelMerger(0), 'context.createChannelMerger(0)') + .throw('IndexSizeError'); + + task.done(); +}); + +audit.define('createChannelMerger', (task, should) => { + task.describe('createChannelMerger'); + + // Invalid number of channels: IndexSizeError + should( + () => context.createChannelMerger(99), 'context.createChannelMerger(99)') + .throw('IndexSizeError'); + + task.done(); +}); + +audit.define('createPeriodicWave', (task, should) => { + task.describe('createPeriodicWave'); + + // Invalid real/imag arrays: IndexSizeError + should( + () => context.createPeriodicWave(null, null), + 'context.createPeriodicWave(null, null)') + .throw('TypeError'); + should( + () => context.createPeriodicWave(new Float32Array(10), null), + 'context.createPeriodicWave(new Float32Array(10), null)') + .throw('TypeError'); + // Verify that we can use large arrays with no limit. Roughly. + should( + () => context.createPeriodicWave( + new Float32Array(4100), new Float32Array(4100)), + 'context.createPeriodicWave(new Float32Array(4100), new Float32Array(4100))') + .notThrow(); + should( + () => context.createPeriodicWave( + new Float32Array(8192), new Float32Array(8192)), + 'context.createPeriodicWave(new Float32Array(8192), new Float32Array(8192))') + .notThrow(); + should( + () => context.createPeriodicWave( + new Float32Array(10000), new Float32Array(10000)), + 'context.createPeriodicWave(new Float32Array(10000), new Float32Array(10000))') + .notThrow(); + // Real and imaginary arrays must have the same size: IndexSizeError + should( + () => + context.createPeriodicWave(new Float32Array(10), new Float32Array(7)), + 'context.createPeriodicWave(new Float32Array(10), new Float32Array(7))') + .throw('IndexSizeError'); + + task.done(); +}); + +audit.define('createAnalyser', (task, should) => { + task.describe('createAnalyser'); + + // Analysers + node = context.createAnalyser(); + // Invalid fftSize: IndexSizeError + shouldThrowAndBeUnchanged(should, node, 'fftSize', '42'); + shouldThrowAndBeUnchanged(should, node, 'fftSize', '16'); + should(() => node.fftSize = 32768, 'AnalyserNode.fftSize = 32768').notThrow(); + shouldThrowAndBeUnchanged(should, node, 'fftSize', '65536'); + + shouldThrowAndBeUnchanged(should, node, 'minDecibels', '-10'); + shouldThrowAndBeUnchanged(should, node, 'maxDecibels', '-150'); + shouldThrowAndBeUnchanged(should, node, 'minDecibels', '-30'); + shouldThrowAndBeUnchanged(should, node, 'maxDecibels', '-100'); + + shouldThrowAndBeUnchanged(should, node, 'smoothingTimeConstant', '-0.1'); + shouldThrowAndBeUnchanged(should, node, 'smoothingTimeConstant', '1.5'); + + should( + () => node.getFloatFrequencyData(null), + 'AnalyserNode.getFloatFrequencyData(null)') + .throw(); + should( + () => node.getByteFrequencyData(null), node.constructor.name + '.getByteFrequencyData(null)') + .throw(); + should( + () => node.getFloatTimeDomainData(null), + node.constructor.name + '.getFloatTimeDomainData(null)') + .throw(); + should( + () => node.getByteTimeDomainData(null), + node.constructor.name + '.getByteTimeDomainData(null)') + .throw(); + + // AudioBuffers + node = context.createBuffer(1, 1, context.sampleRate); + // Invalid channel index: IndexSizeError + should(() => node.getChannelData(2), node.constructor.name + '.getChannelData(2)').throw(); + + task.done(); +}); + +audit.define('Init test nodes', (task, should) => { + task.describe('Create test nodes'); + should(() => { node = context.createGain(); }, + 'node = context.createGain()') + .notThrow(); + should(() => { node2 = context.createGain(); }, + 'node2 = context.createGain()') + .notThrow(); + + task.done(); +}); + +audit.define('connections', (task, should) => { + task.describe('AudioNode connections'); + + // AudioNode connections + // Invalid destination node (unspecified error) + should(() => node.connect(null, 0, 0), 'node.connect(null, 0, 0)').throw(); + // Invalid input or output index: IndexSizeError + should( + () => node.connect(context.destination, 100, 0), + 'node.connect(context.destination, 100, 0)') + .throw('IndexSizeError'); + should( + () => node.connect(context.destination, 0, 100), + 'node.connect(context.destination, 0, 100)') + .throw('IndexSizeError'); + should(() => node.connect(node2.gain, 100), 'node.connect(node2.gain, 100)') + .throw('IndexSizeError'); + should(() => node.disconnect(99), 'node.disconnect(99)') + .throw('IndexSizeError'); + // Can't connect to a different context (unspecified error) + should( + () => node.connect(otherContext.destination), + 'node.connect(otherContext.destination)') + .throw(); + + task.done(); +}); + +audit.define('channel-stuff', (task, should) => { + task.describe('channelCount, channelCountMode, channelInterpretation'); + + // Invalid channel count: NotSupportedError + shouldThrowAndBeUnchanged(should, node, 'channelCount', '99'); + // Invalid mode or interpretation (unspecified error) + currentMode = node.channelCountMode; + currentInterpretation = node.channelInterpretation; + should( + () => node.channelCountMode = 'fancy', 'node.channelCountMode = "fancy"') + .notThrow(); + should(node.channelCountMode, 'node.channelCountMode').beEqualTo(currentMode); + should( + () => node.channelInterpretation = mode, + 'node.channelInterpretation = mode') + .notThrow(); + should(node.channelInterpretation, 'node.channelInterpretation') + .beEqualTo(currentInterpretation); + // Destination node channel count: should throw IndexSizeError on invalid + // channel count. shouldNotThrow() method cannot be used because the error + // message includes the number of channels, which can change depending on + // the actual attached hardware. + should( + () => context.destination.channelCount = 99, + 'context.destination.channelCount = 99') + .throw('IndexSizeError'); + + task.done(); +}); + +audit.define('audioparam', (task, should) => { + task.describe('Simple AudioParam'); + + // AudioParams + param = context.createGain().gain; + should( + () => param.setValueCurveAtTime(null, 0, 0), + 'param.setValueCurveAtTime(null, 0, 0)') + .throw(); + + // exponentialRampToValue should throw only for "zero" target values. + should( + () => node.gain.exponentialRampToValueAtTime(-1, 0.1), + 'node.gain.exponentialRampToValueAtTime(-1, 0.1)') + .notThrow(); + should( + () => node.gain.exponentialRampToValueAtTime(0, 0.1), + 'node.gain.exponentialRampToValueAtTime(0, 0.1)') + .throw(); + // 1e-100 is 0 when converted to a single precision float. + should( + () => node.gain.exponentialRampToValueAtTime(1e-100, 0.1), + 'node.gain.exponentialRampToValueAtTime(1e-100, 0.1)') + .throw(); + // See crbug.com/459391. + // Math.pow(2, -149) = 1.401298464324817e-45 is the double-float value of the + // least positive single float number. We do it this way to make sure no + // round-off or conversion + // errors happen when reading 1.401298464324817e-45. + should( + () => node.gain.exponentialRampToValueAtTime(Math.pow(2, -149), 0.1), + 'node.gain.exponentialRampToValueAtTime(Math.pow(2, -149), 0.1)') + .notThrow(); + // Math.pow(2, -150) = 7.006492321624085d-46 is the largest double float value + // such that + // conversion to a float produces 0. Any larger value would produce a + // non-zero value when + // converted to a single float. + should( + () => node.gain.exponentialRampToValueAtTime(Math.pow(2, -150), 0.1), + 'node.gain.exponentialRampToValueAtTime(Math.pow(2, -150), 0.1)') + .throw(); + + task.done(); +}); + +audit.define('biquad', (task, should) => { + task.describe('BiquadFilter'); + + // BiquadFilterNode + node = context.createBiquadFilter(); + should( + () => node.getFrequencyResponse( + new Float32Array(1), new Float32Array(1), new Float32Array(1)), + 'node.getFrequencyResponse(new Float32Array(1), new Float32Array(1), new Float32Array(1))') + .notThrow(); + should( + () => node.getFrequencyResponse( + null, new Float32Array(1), new Float32Array(1)), + 'node.getFrequencyResponse(null, new Float32Array(1), new Float32Array(1))') + .throw(); + should( + () => node.getFrequencyResponse( + new Float32Array(1), null, new Float32Array(1)), + 'node.getFrequencyResponse(new Float32Array(1), null, new Float32Array(1))') + .throw(); + should( + () => node.getFrequencyResponse( + new Float32Array(1), new Float32Array(1), null), + 'node.getFrequencyResponse(new Float32Array(1), new Float32Array(1), null)') + .throw(); + + task.done(); +}); + +audit.define('offline-audio-context', (task, should) => { + task.describe('OfflineAudioContext'); + + // OfflineAudioContext + // Max supported channels + should( + () => new OfflineAudioContext(32, 100, context.sampleRate), + 'new OfflineAudioContext(32, 100, context.sampleRate)') + .notThrow(); + // Invalid number of channels (unspecified error) + should( + () => new OfflineAudioContext(99, 100, context.sampleRate), + 'new OfflineAudioContext(99, 100, context.sampleRate)') + .throw(); + // Invalid sample rate. (unspecified error) + should( + () => new OfflineAudioContext(1, 100, 1), + 'new OfflineAudioContext(1, 100, 1)') + .throw(); + should( + () => new OfflineAudioContext(1, 100, 1e6), + 'new OfflineAudioContext(1, 100, 1e6)') + .throw(); + // Invalid frame length (crbug.com/351277) + should( + () => new OfflineAudioContext(1, -88200000000000, 44100), + 'new OfflineAudioContext(1, -88200000000000, 44100)') + .throw(); + + task.done(); +}); + +audit.define('waveshaper', (task, should) => { + task.describe('WaveShaper'); + + // WaveShaper types + node = context.createWaveShaper(); + currentOversample = node.oversample; + should(() => node.oversample = '9x', 'node.oversample = "9x"').notThrow(); + should(node.oversample, 'node.oversample').beEqualTo(currentOversample); + should(() => node.curve = {}, 'node.curve = {}').throw(); + should( + () => node.curve = new Float32Array(1), + 'node.curve = new Float32Array(1)') + .throw(); + should(node.curve, 'node.curve').beEqualTo(null); + should( + () => node.curve = new Float32Array(2), + 'node.curve = new Float32Array(2)') + .notThrow(); + should(() => node.curve = null, 'node.curve = null').notThrow(); + + task.done(); +}); + +audit.define('audio-buffer-source', (task, should) => { + task.describe('AudioBufferSource start/stop'); + + // Start/stop for AudioBufferSourceNodes + buffer = context.createBuffer(1, 1, context.sampleRate); + should( + () => source = context.createBufferSource(), + 'source = context.createBufferSource()') + .notThrow(); + should(() => source.buffer = buffer, 'source.buffer = buffer').notThrow(); + should( + () => source.buffer = context.createBuffer(1, 10, context.sampleRate), + 'source.buffer = context.createBuffer(1, 10, context.sampleRate)') + .throw(); + should(() => source.start(-1), 'source.start(-1)').throw(); + should(() => source.start(Infinity), 'source.start(Infinity)').throw(); + should(() => source.start(-Infinity), 'source.start(-Infinity)').throw(); + should(() => source.start(NaN), 'source.start(NaN)').throw(); + should(() => source.start(1, Infinity), 'source.start(1, Infinity)').throw(); + should(() => source.start(1, -Infinity), 'source.start(1, -Infinity)') + .throw(); + should(() => source.start(1, NaN), 'source.start(1, NaN)').throw(); + should(() => source.start(1, -1), 'source.start(1, -1)').throw(); + should( + () => source.start(1, -Number.MIN_VALUE), + 'source.start(1, -Number.MIN_VALUE)') + .throw(); + should(() => source.start(1, 1, Infinity), 'source.start(1, 1, Infinity)') + .throw(); + should(() => source.start(1, 1, -Infinity), 'source.start(1, 1, -Infinity)') + .throw(); + should(() => source.start(1, 1, NaN), 'source.start(1, 1, NaN)').throw(); + should(() => source.start(1, 1, -1), 'source.start(1, 1, -1)').throw(); + should( + () => source.start(1, 1, -Number.MIN_VALUE), + 'source.start(1, 1, -Number.MIN_VALUE)') + .throw(); + should(() => source.start(), 'source.start()').notThrow(); + should(() => source.stop(-Number.MIN_VALUE), 'source.stop(-Number.MIN_VALUE)') + .throw(); + should(() => source.stop(Infinity), 'source.stop(Infinity)').throw(); + should(() => source.stop(-Infinity), 'source.stop(-Infinity)').throw(); + should(() => source.stop(NaN), 'source.stop(NaN)').throw(); + should(() => source.stop(), 'source.stop()').notThrow(); + + // Verify that start(0, 0) doesn't signal. + should( + () => source = context.createBufferSource(), + 'source = context.createBufferSource()') + .notThrow(); + should(() => source.buffer = buffer, 'source.buffer = buffer').notThrow(); + should(() => source.start(0, 0), 'source.start(0, 0)').notThrow(); + + // Verify that start(0, -0.0) doesn't signal. + should( + () => source = context.createBufferSource(), + 'source = context.createBufferSource()') + .notThrow(); + should(() => source.buffer = buffer, 'source.buffer = buffer').notThrow(); + should(() => source.start(0, -1 / Infinity), 'source.start(0, -1/Infinity)') + .notThrow(); + + // It's not clear from the spec, but I think it's valid to call start(). The + // spec is silent on + // what happens if we call stop() afterwards, so don't call it. + should( + () => source = context.createBufferSource(), + 'source = context.createBufferSource()') + .notThrow(); + should(() => source.start(), 'source.start()').notThrow(); + + buffer = context.createBuffer(1, 1, context.sampleRate); + should( + () => source = context.createBufferSource(), + 'source = context.createBufferSource()') + .notThrow(); + should(() => source.buffer = buffer, 'source.buffer = buffer').notThrow(); + should(() => source.stop(), 'source.stop()').throw(); + + buffer = context.createBuffer(1, 1, context.sampleRate); + should( + () => source = context.createBufferSource(), + 'source = context.createBufferSource()') + .notThrow(); + should(() => source.buffer = buffer, 'source.buffer = buffer').notThrow(); + should(() => source.start(), 'source.start()').notThrow(); + should(() => source.start(), 'source.start()').throw(); + + buffer = context.createBuffer(1, 1, context.sampleRate); + should( + () => source = context.createBufferSource(), + 'source = context.createBufferSource()') + .notThrow(); + should(() => source.buffer = buffer, 'source.buffer = buffer').notThrow(); + should(() => source.start(), 'source.start()').notThrow(); + should(() => source.stop(), 'source.stop()').notThrow(); + + task.done(); +}); + +audit.define('oscillator', (task, should) => { + task.describe('Oscillator start/stop'); + + // Start/stop for OscillatorNodes + should( + () => source = context.createOscillator(), + 'source = context.createOscillator()') + .notThrow(); + should( + () => source.start(-Number.MIN_VALUE), 'source.start(-Number.MIN_VALUE)') + .throw(); + should(() => source.start(Infinity), 'source.start(Infinity)').throw(); + should(() => source.start(-Infinity), 'source.start(-Infinity)').throw(); + should(() => source.start(NaN), 'source.start(NaN)').throw(); + should(() => source.start(), 'source.start()').notThrow(); + should(() => source.stop(-Number.MIN_VALUE), 'source.stop(-Number.MIN_VALUE)') + .throw(); + should(() => source.stop(Infinity), 'source.stop(Infinity)').throw(); + should(() => source.stop(-Infinity), 'source.stop(-Infinity)').throw(); + should(() => source.stop(NaN), 'source.stop(NaN)').throw(); + should(() => source.stop(), 'source.stop()').notThrow(); + + should( + () => osc = context.createOscillator(), + 'osc = context.createOscillator()') + .notThrow(); + should(() => osc.stop(), 'osc.stop()').throw(); + should( + () => osc1 = context.createOscillator(), + 'osc1 = context.createOscillator()') + .notThrow(); + should(() => osc1.start(), 'osc1.start()').notThrow(); + should(() => osc1.stop(), 'osc1.stop()').notThrow(); + + should(() => osc.setPeriodicWave(null), 'osc.setPeriodicWave(null)').throw(); - // Analysers - node = context.createAnalyser(); - // Invalid fftSize: IndexSizeError - shouldThrowAndBeUnchanged("node.fftSize", "42"); - shouldThrowAndBeUnchanged("node.fftSize", "16"); - shouldNotThrow("node.fftSize = 32768"); - shouldThrowAndBeUnchanged("node.fftSize", "65536"); + task.done(); +}); - shouldThrowAndBeUnchanged("node.minDecibels", "-10"); - shouldThrowAndBeUnchanged("node.maxDecibels", "-150"); - shouldThrowAndBeUnchanged("node.minDecibels", "-30"); - shouldThrowAndBeUnchanged("node.maxDecibels", "-100"); +audit.define('convolver', (task, should) => { + task.describe('Convolver'); - shouldThrowAndBeUnchanged("node.smoothingTimeConstant", "-0.1"); - shouldThrowAndBeUnchanged("node.smoothingTimeConstant", "1.5"); + // Convolver buffer rate must match context rate. Create on offline context so + // we + // specify the context rate exactly, in case the test is run on platforms with + // different + // HW sample rates. + should( + () => oc = new OfflineAudioContext(1, 44100, 44100), + 'oc = new OfflineAudioContext(1, 44100, 44100)') + .notThrow(); + should(() => conv = oc.createConvolver(), 'conv = oc.createConvolver()') + .notThrow(); + should(() => conv.buffer = {}, 'conv.buffer = {}').throw(); + should( + () => conv.buffer = oc.createBuffer(1, 100, 22050), + 'conv.buffer = oc.createBuffer(1, 100, 22050)') + .throw(); + // conv.buffer should be unchanged (null) because the above failed. + should(conv.buffer, 'conv.buffer').beEqualTo(null); - shouldThrow("node.getFloatFrequencyData(null)"); - shouldThrow("node.getByteFrequencyData(null)"); - shouldThrow("node.getFloatTimeDomainData(null)"); - shouldThrow("node.getByteTimeDomainData(null)"); + task.done(); +}); - // AudioBuffers - node = context.createBuffer(1,1, context.sampleRate); - // Invalid channel index: IndexSizeError - shouldThrow("node.getChannelData(2)"); +audit.define('panner', (task, should) => { + task.describe('Panner'); - // AudioNode connections - node = context.createGain(); - node2 = context.createGain(); - // Invalid destination node (unspecified error) - shouldThrow("node.connect(null, 0, 0)"); - // Invalid input or output index: IndexSizeError - shouldThrow("node.connect(context.destination, 100, 0)"); - shouldThrow("node.connect(context.destination, 0, 100)"); - shouldThrow("node.connect(node2.gain, 100)"); - shouldThrow("node.disconnect(99)"); - // Can't connect to a different context (unspecified error) - shouldThrow("node.connect(otherContext.destination)"); + // PannerNode channel count and mode + panner = context.createPanner(); + // Channel count can only be set to 1 or 2. + should(() => panner.channelCount = 1, 'panner.channelCount = 1').notThrow(); + should(() => panner.channelCount = 2, 'panner.channelCount = 2').notThrow(); + shouldThrowAndBeUnchanged(should, panner, 'channelCount', 0); + shouldThrowAndBeUnchanged(should, panner, 'channelCount', 3); + // It is illegal to set the mode to 'max' + shouldThrowAndBeUnchanged(should, panner, 'channelCountMode', 'max'); + should( + () => panner.channelCountMode = 'explicit', + 'panner.channelCountMode = "explicit"') + .notThrow(); + should( + () => panner.channelCountMode = 'clamped-max', + 'panner.channelCountMode = "clamped-max"') + .notThrow(); + should( + () => panner.channelCountMode = 'junk', + 'panner.channelCountMode = "junk"') + .notThrow(); - // Invalid channel count: NotSupportedError - shouldThrowAndBeUnchanged("node.channelCount", "99"); - // Invalid mode or interpretation (unspecified error) - currentMode = node.channelCountMode; - currentInterpretation = node.channelInterpretation; - shouldNotThrow("node.channelCountMode = 'fancy'"); - if (node.channelCountMode == currentMode) - testPassed("Invalid channelCountMode value did not change mode"); - else - testFailed("node.channelCountMode incorrectly changed to invalid value " + node.channelCountMode); - shouldNotThrow("node.channelInterpretation = mode"); - if (node.channelInterpretation == currentInterpretation) - testPassed("Invalid channelInterpration value did not change mode"); - else - testFailed("node.channelInterpretation incorrectly changed to invalid value " + node.channelInterpreation); + task.done(); +}); - // Destination node channel count: should throw IndexSizeError on invalid - // channel count. shouldNotThrow() method cannot be used because the error - // message includes the number of channels, which can change depending on - // the actual attached hardware. - try { - eval("context.destination.channelCount = 99"); - } catch (e) { - if (e.message === "Failed to set the 'channelCount' property on 'AudioNode': The channel count provided (99) is outside the range [1, " + context.destination.maxChannelCount + "]." && e.name === "IndexSizeError") - testPassed("context.destination.channelCount = 99 threw IndexSizeError exception on invalid channel count."); - else - testFailed("context.destination.channelCount = 99 should throw IndexSizeError exception on invalid channel count."); - } +audit.define('script-processor', (task, should) => { + task.describe('ScriptProcessor'); - // AudioParams - param = context.createGain().gain; - shouldThrow("param.setValueCurveAtTime(null, 0, 0)"); + // Test channel count and mode for a ScriptProcessor. + should( + () => script = context.createScriptProcessor(256, 3), + 'script = context.createScriptProcessor(256, 3)') + .notThrow(); + // Make sure the channelCount and mode are set correctly. + should(script.channelCount, 'script.channelCount').beEqualTo(3); + should(script.channelCountMode, 'script.channelCountMode') + .beEqualTo('explicit'); + // Cannot change the channelCount or mode to anything else + should(() => script.channelCount = 3, 'script.channelCount = 3').notThrow(); + shouldThrowAndBeUnchanged(should, script, 'channelCount', 1); - // BiquadFilterNode - node = context.createBiquadFilter(); - shouldNotThrow("node.getFrequencyResponse(new Float32Array(1), new Float32Array(1), new Float32Array(1))"); - shouldThrow("node.getFrequencyResponse(null, new Float32Array(1), new Float32Array(1))"); - shouldThrow("node.getFrequencyResponse(new Float32Array(1), null, new Float32Array(1))"); - shouldThrow("node.getFrequencyResponse(new Float32Array(1), new Float32Array(1), null)"); + shouldThrowAndBeUnchanged(should, script, 'channelCount', 7); + should( + () => script.channelCountMode = 'explicit', + 'script.channelCountMode = "explicit"') + .notThrow(); + shouldThrowAndBeUnchanged(should, script, 'channelCountMode', 'max'); + shouldThrowAndBeUnchanged(should, script, 'channelCountMode', 'clamped-max'); + should( + () => script.channelCountMode = 'junk', + 'script.channelCountMode = "junk"') + .notThrow(); - // Delay nodes are tested elsewhere, so don't duplicate that work here. + task.done(); +}); - // OfflineAudioContext - // Max supported channels - shouldNotThrow("new OfflineAudioContext(32, 100, context.sampleRate)"); - // Invalid number of channels (unspecified error) - shouldThrow("new OfflineAudioContext(99, 100, context.sampleRate)"); - // Invalid sample rate. (unspecified error) - shouldThrow("new OfflineAudioContext(1, 100, 1)"); - shouldThrow("new OfflineAudioContext(1, 100, 1e6)"); - // Invalid frame length (crbug.com/351277) - shouldThrow("new OfflineAudioContext(1, -88200000000000, 44100)"); +audit.define('misc', (task, should) => { + task.describe('Miscellaneous'); - // WaveShaper types - node = context.createWaveShaper(); - currentOversample = node.oversample; - shouldNotThrow("node.oversample = '9x'"); - if (node.oversample == currentOversample) - testPassed("Invalid oversample value did not change node.oversample"); - else - testFailed("node.oversample incorrectly changed to invalid value " + node.oversample); - shouldThrow("node.curve = {}"); - shouldThrow("node.curve = new Float32Array(1)"); - shouldBeNull("node.curve"); - shouldNotThrow("node.curve = new Float32Array(2)"); - shouldNotThrow("node.curve = null"); + // noteOn and noteOff don't exist anymore + should(osc.noteOn, 'osc.noteOn').beEqualTo(undefined); + should(osc.noteOff, 'osc.noteOff').beEqualTo(undefined); + should(source.noteOn, 'source.noteOn').beEqualTo(undefined); + should(source.noteOff, 'source.noteOff').beEqualTo(undefined); - // Start/stop for AudioBufferSourceNodes - buffer = context.createBuffer(1,1, context.sampleRate); - shouldNotThrow("source = context.createBufferSource()"); - shouldNotThrow("source.buffer = buffer"); - shouldThrow("source.buffer = context.createBuffer(1, 10, context.sampleRate)"); - shouldThrow("source.start(-1)"); - shouldThrow("source.start(Infinity)"); - shouldThrow("source.start(-Infinity)"); - shouldThrow("source.start(NaN)"); - shouldThrow("source.start(1, Infinity)"); - shouldThrow("source.start(1, -Infinity)"); - shouldThrow("source.start(1, NaN)"); - shouldThrow("source.start(1, -1)"); - shouldThrow("source.start(1, -Number.MIN_VALUE)"); - shouldThrow("source.start(1, 1, Infinity)"); - shouldThrow("source.start(1, 1, -Infinity)"); - shouldThrow("source.start(1, 1, NaN)"); - shouldThrow("source.start(1, 1, -1)"); - shouldThrow("source.start(1, 1, -Number.MIN_VALUE)"); - shouldNotThrow("source.start()"); - shouldThrow("source.stop(-Number.MIN_VALUE)"); - shouldThrow("source.stop(Infinity)"); - shouldThrow("source.stop(-Infinity)"); - shouldThrow("source.stop(NaN)"); - shouldNotThrow("source.stop()"); + task.done(); +}); - // Verify that start(0, 0) doesn't signal. - shouldNotThrow("source = context.createBufferSource()"); - shouldNotThrow("source.buffer = buffer"); - shouldNotThrow("source.start(0, 0)"); - - // Verify that start(0, -0.0) doesn't signal. - shouldNotThrow("source = context.createBufferSource()"); - shouldNotThrow("source.buffer = buffer"); - shouldNotThrow("source.start(0, -1/Infinity)"); - - // It's not clear from the spec, but I think it's valid to call start(). The spec is silent on - // what happens if we call stop() afterwards, so don't call it. - shouldNotThrow("source = context.createBufferSource()"); - shouldNotThrow("source.start()"); - - buffer = context.createBuffer(1,1, context.sampleRate); - shouldNotThrow("source = context.createBufferSource()"); - shouldNotThrow("source.buffer = buffer"); - shouldThrow("source.stop()"); - - buffer = context.createBuffer(1,1, context.sampleRate); - shouldNotThrow("source = context.createBufferSource()"); - shouldNotThrow("source.buffer = buffer"); - shouldNotThrow("source.start()"); - shouldThrow("source.start()"); - - buffer = context.createBuffer(1,1, context.sampleRate); - shouldNotThrow("source = context.createBufferSource()"); - shouldNotThrow("source.buffer = buffer"); - shouldNotThrow("source.start()"); - shouldNotThrow("source.stop()"); - - - // Start/stop for OscillatorNodes - shouldNotThrow("source = context.createOscillator()"); - shouldThrow("source.start(-Number.MIN_VALUE)"); - shouldThrow("source.start(Infinity)"); - shouldThrow("source.start(-Infinity)"); - shouldThrow("source.start(NaN)"); - shouldNotThrow("source.start()"); - shouldThrow("source.stop(-Number.MIN_VALUE)"); - shouldThrow("source.stop(Infinity)"); - shouldThrow("source.stop(-Infinity)"); - shouldThrow("source.stop(NaN)"); - shouldNotThrow("source.stop()"); - - shouldNotThrow("osc = context.createOscillator()"); - shouldThrow("osc.stop()"); - shouldNotThrow("osc1 = context.createOscillator()"); - shouldNotThrow("osc1.start()"); - shouldNotThrow("osc1.stop()"); - - shouldThrow("osc.setPeriodicWave(null)"); - - // exponentialRampToValue should throw only for "zero" target values. - node = context.createGain(); - node.connect(context.destination); - shouldNotThrow("node.gain.exponentialRampToValueAtTime(-1, 0.1)"); - shouldThrow("node.gain.exponentialRampToValueAtTime(0, 0.1)"); - // 1e-100 is 0 when converted to a single precision float. - shouldThrow("node.gain.exponentialRampToValueAtTime(1e-100, 0.1)"); - // See crbug.com/459391. - // Math.pow(2, -149) = 1.401298464324817e-45 is the double-float value of the - // least positive single float number. We do it this way to make sure no round-off or conversion - // errors happen when reading 1.401298464324817e-45. - shouldNotThrow("node.gain.exponentialRampToValueAtTime(Math.pow(2, -149), 0.1)"); - // Math.pow(2, -150) = 7.006492321624085d-46 is the largest double float value such that - // conversion to a float produces 0. Any larger value would produce a non-zero value when - // converted to a single float. - shouldThrow("node.gain.exponentialRampToValueAtTime(Math.pow(2, -150), 0.1)"); - - // Convolver buffer rate must match context rate. Create on offline context so we - // specify the context rate exactly, in case the test is run on platforms with different - // HW sample rates. - shouldNotThrow("oc = new OfflineAudioContext(1, 44100, 44100)"); - shouldNotThrow("conv = oc.createConvolver()"); - shouldThrow("conv.buffer = {}"); - shouldThrow("conv.buffer = oc.createBuffer(1, 100, 22050)"); - // conv.buffer should be unchanged (null) because the above failed. - shouldBeNull("conv.buffer"); - - // PannerNode channel count and mode - panner = context.createPanner(); - // Channel count can only be set to 1 or 2. - shouldNotThrow("panner.channelCount = 1"); - shouldNotThrow("panner.channelCount = 2"); - shouldThrowAndBeUnchanged("panner.channelCount", "0"); - shouldThrowAndBeUnchanged("panner.channelCount", "3"); - // It is illegal to set the mode to 'max' - shouldThrowAndBeUnchanged("panner.channelCountMode", "'max'"); - shouldNotThrow("panner.channelCountMode = 'explicit'"); - shouldNotThrow("panner.channelCountMode = 'clamped-max'"); - shouldNotThrow("panner.channelCountMode = 'junk'"); - - // Test channel count and mode for a ScriptProcessor. - shouldNotThrow("script = context.createScriptProcessor(256, 3)"); - // Make sure the channelCount and mode are set correctly. - shouldBeEqualToNumber("script.channelCount", 3); - shouldBeEqualToString("script.channelCountMode", "explicit"); - // Cannot change the channelCount or mode to anything else - shouldNotThrow("script.channelCount = 3"); - shouldThrowAndBeUnchanged("script.channelCount", "1"); - - shouldThrowAndBeUnchanged("script.channelCount", "7"); - shouldNotThrow("script.channelCountMode = 'explicit'"); - shouldThrowAndBeUnchanged("script.channelCountMode", "'max'"); - shouldThrowAndBeUnchanged("script.channelCountMode", "'clamped-max'"); - shouldNotThrow("script.channelCountMode = 'junk'"); - - // noteOn and noteOff don't exist anymore - shouldBeUndefined("osc.noteOn"); - shouldBeUndefined("osc.noteOff"); - shouldBeUndefined("source.noteOn"); - shouldBeUndefined("source.noteOff"); -} - -runTest(); -successfullyParsed = true; - +audit.run(); </script> </body> </html>
diff --git a/third_party/WebKit/LayoutTests/webaudio/resources/distance-model-testing.js b/third_party/WebKit/LayoutTests/webaudio/resources/distance-model-testing.js index 933cc14..baff5d48c 100644 --- a/third_party/WebKit/LayoutTests/webaudio/resources/distance-model-testing.js +++ b/third_party/WebKit/LayoutTests/webaudio/resources/distance-model-testing.js
@@ -101,7 +101,7 @@ // distanceModel should be the distance model string like // "linear", "inverse", or "exponential". -function createTestAndRun(context, distanceModel) { +function createTestAndRun(context, distanceModel, should) { // To test the distance models, we create a number of panners at // uniformly spaced intervals on the z-axis. Each of these are // started at equally spaced time intervals. After rendering the @@ -111,8 +111,8 @@ createGraph(context, distanceModel, nodesToCreate); - context.oncomplete = checkDistanceResult(distanceModel); - context.startRendering(); + return context.startRendering() + .then(buffer => checkDistanceResult(buffer, distanceModel, should)); } // The gain caused by the EQUALPOWER panning model, if we stay on the @@ -121,86 +121,72 @@ return Math.SQRT1_2; } -function checkDistanceResult(model) { - return function(event) { - renderedBuffer = event.renderedBuffer; - renderedData = renderedBuffer.getChannelData(0); +function checkDistanceResult(renderedBuffer, model, should) { + renderedData = renderedBuffer.getChannelData(0); - // The max allowed error between the actual gain and the expected - // value. This is determined experimentally. Set to 0 to see what - // the actual errors are. - var maxAllowedError = 3.3e-6; + // The max allowed error between the actual gain and the expected + // value. This is determined experimentally. Set to 0 to see + // what the actual errors are. + var maxAllowedError = 3.3e-6; - var success = true; + var success = true; - // Number of impulses we found in the rendered result. - var impulseCount = 0; + // Number of impulses we found in the rendered result. + var impulseCount = 0; - // Maximum relative error in the gain of the impulses. - var maxError = 0; + // Maximum relative error in the gain of the impulses. + var maxError = 0; - // Array of locations of the impulses that were not at the - // expected location. (Contains the actual and expected frame - // of the impulse.) - var impulsePositionErrors = new Array(); + // Array of locations of the impulses that were not at the + // expected location. (Contains the actual and expected frame + // of the impulse.) + var impulsePositionErrors = new Array(); - // Step through the rendered data to find all the non-zero points - // so we can find where our distance-attenuated impulses are. - // These are tested against the expected attenuations at that - // distance. - for (var k = 0; k < renderedData.length; ++k) { - if (renderedData[k] != 0) { - // Convert from string to index. - var distanceFunction = distanceModelFunction[model]; - var expected = distanceFunction(panner[impulseCount], 0, 0, position[impulseCount]); + // Step through the rendered data to find all the non-zero points + // so we can find where our distance-attenuated impulses are. + // These are tested against the expected attenuations at that + // distance. + for (var k = 0; k < renderedData.length; ++k) { + if (renderedData[k] != 0) { + // Convert from string to index. + var distanceFunction = distanceModelFunction[model]; + var expected = + distanceFunction(panner[impulseCount], 0, 0, + position[impulseCount]); - // Adjust for the center-panning of the EQUALPOWER panning - // model that we're using. - expected *= equalPowerGain(); + // Adjust for the center-panning of the EQUALPOWER panning + // model that we're using. + expected *= equalPowerGain(); - var error = Math.abs(renderedData[k] - expected) / Math.abs(expected); + var error = + Math.abs(renderedData[k] - expected) / Math.abs(expected); - maxError = Math.max(maxError, Math.abs(error)); + maxError = Math.max(maxError, Math.abs(error)); - // Keep track of any impulses that aren't where we expect them - // to be. - var expectedOffset = timeToSampleFrame(time[impulseCount], sampleRate); - if (k != expectedOffset) { - impulsePositionErrors.push({ actual : k, expected : expectedOffset}); - } - ++impulseCount; + // Keep track of any impulses that aren't where we expect them + // to be. + var expectedOffset = timeToSampleFrame(time[impulseCount], + sampleRate); + if (k != expectedOffset) { + impulsePositionErrors.push({ + actual: k, + expected: expectedOffset + }); } + ++impulseCount; } + } + should(impulseCount, "Number of impulses") + .beEqualTo(nodesToCreate); - if (impulseCount == nodesToCreate) { - testPassed("Number of impulses found matches number of panner nodes."); - } else { - testFailed("Number of impulses is incorrect. Found " + impulseCount + " but expected " + nodesToCreate + "."); - success = false; - } + should(maxError, "Max error in distance gains") + .beLessThanOrEqualTo(maxAllowedError); - if (maxError <= maxAllowedError) { - testPassed("Distance gains are correct."); - } else { - testFailed("Distance gains are incorrect. Max rel error = " + maxError + " (maxAllowedError = " + maxAllowedError + ")"); - success = false; - } - - // Display any timing errors that we found. - if (impulsePositionErrors.length > 0) { - success = false; - testFailed(impulsePositionErrors.length + " timing errors found"); - for (var k = 0; k < impulsePositionErrors.length; ++k) { - testFailed("Sample at frame " + impulsePositionErrors[k].actual + " but expected " + impulsePositionErrors[k].expected); - } - } - - if (success) { - testPassed("Distance test passed for distance model " + model); - } else { - testFailed("Distance test failed for distance model " + model); - } - - finishJSTest(); + // Display any timing errors that we found. + if (impulsePositionErrors.length > 0) { + let actual = impulsePositionErrors.map(x => x.actual); + let expected = impulsePositionErrors.map(x => x.expected); + should(actual, "Actual impulse positions found") + .beEqualToArray(expected); } }
diff --git a/third_party/WebKit/LayoutTests/webaudio/resources/waveshaper-testing.js b/third_party/WebKit/LayoutTests/webaudio/resources/waveshaper-testing.js index 923bb7d..b8b866fb 100644 --- a/third_party/WebKit/LayoutTests/webaudio/resources/waveshaper-testing.js +++ b/third_party/WebKit/LayoutTests/webaudio/resources/waveshaper-testing.js
@@ -51,9 +51,7 @@ return curve; } -function checkShapedCurve(event) { - var buffer = event.renderedBuffer; - +function checkShapedCurve(buffer, should) { var outputData = buffer.getChannelData(0); var n = buffer.length; @@ -114,15 +112,9 @@ // console.log("worstDeltaInDecibels: " + worstDeltaInDecibels); - var success = worstDeltaInDecibels < acceptableAliasingThresholdDecibels; - - if (success) { - testPassed(oversample + " WaveShaperNode oversampling within acceptable tolerance."); - } else { - testFailed(oversample + " WaveShaperNode oversampling not within acceptable tolerance. Error = " + worstDeltaInDecibels + " dBFS"); - } - - finishJSTest(); + should(worstDeltaInDecibels, oversample + + " WaveshaperNode oversampling error (in dBFS)") + .beLessThan(acceptableAliasingThresholdDecibels); } function createImpulseBuffer(context, sampleFrameLength) { @@ -145,31 +137,33 @@ fundamentalFrequency = testParams.fundamentalFrequency; acceptableAliasingThresholdDecibels = testParams.acceptableAliasingThresholdDecibels; - if (window.testRunner) { - testRunner.dumpAsText(); - testRunner.waitUntilDone(); - } + let audit = Audit.createTaskRunner(); - window.jsTestIsAsync = true; + audit.define("test", function (task, should) { + task.describe(testParams.description); - // Create offline audio context. - var numberOfRenderFrames = sampleRate * lengthInSeconds; - context = new OfflineAudioContext(1, numberOfRenderFrames, sampleRate); + // Create offline audio context. + var numberOfRenderFrames = sampleRate * lengthInSeconds; + context = new OfflineAudioContext(1, numberOfRenderFrames, sampleRate); - // source -> waveshaper -> destination - var source = context.createBufferSource(); - source.buffer = createToneBuffer(context, fundamentalFrequency, lengthInSeconds, 1); + // source -> waveshaper -> destination + var source = context.createBufferSource(); + source.buffer = createToneBuffer(context, fundamentalFrequency, lengthInSeconds, 1); - // Apply a non-linear distortion curve. - waveshaper = context.createWaveShaper(); - waveshaper.curve = generateWaveShapingCurve(); - waveshaper.oversample = oversample; + // Apply a non-linear distortion curve. + waveshaper = context.createWaveShaper(); + waveshaper.curve = generateWaveShapingCurve(); + waveshaper.oversample = oversample; - source.connect(waveshaper); - waveshaper.connect(context.destination); + source.connect(waveshaper); + waveshaper.connect(context.destination); - source.start(0); + source.start(0); - context.oncomplete = checkShapedCurve; - context.startRendering(); + context.startRendering() + .then(buffer => checkShapedCurve(buffer, should)) + .then(() => task.done()); + }); + + audit.run(); }
diff --git a/third_party/WebKit/Source/bindings/core/v8/SerializationTag.h b/third_party/WebKit/Source/bindings/core/v8/SerializationTag.h index 81b9b9a2..0c4e5438 100644 --- a/third_party/WebKit/Source/bindings/core/v8/SerializationTag.h +++ b/third_party/WebKit/Source/bindings/core/v8/SerializationTag.h
@@ -12,6 +12,8 @@ // begins with a complete VersionTag. If the stream does not begin with a // VersionTag, we assume that the stream is in format 0. +// Tags which are not interpreted by Blink (but instead by V8) are omitted here. + // This format is private to the implementation of SerializedScriptValue. Do not // rely on it externally. It is safe to persist a SerializedScriptValue as a // binary blob, but this code should always be used to interpret it. @@ -35,20 +37,8 @@ // GenerateFreshObjectTag/GenerateFreshArrayTag); these reference IDs are then // used with ObjectReferenceTag to tie the recursive knot. enum SerializationTag { - InvalidTag = '!', // Causes deserialization to fail. - PaddingTag = '\0', // Is ignored (but consumed). - UndefinedTag = '_', // -> <undefined> - NullTag = '0', // -> <null> - TrueTag = 'T', // -> <true> - FalseTag = 'F', // -> <false> - StringTag = 'S', // string:RawString -> string - StringUCharTag = 'c', // string:RawUCharString -> string - Int32Tag = 'I', // value:ZigZag-encoded int32 -> Integer - Uint32Tag = 'U', // value:uint32_t -> Integer - DateTag = 'D', // value:double -> Date (ref) MessagePortTag = 'M', // index:int -> MessagePort. Fills the result with // transferred MessagePort. - NumberTag = 'N', // value:double -> Number BlobTag = 'b', // uuid:WebCoreString, type:WebCoreString, size:uint64_t -> // Blob (ref) BlobIndexTag = 'i', // index:int32_t -> Blob (ref) @@ -63,36 +53,12 @@ ImageDataTag = '#', // width:uint32_t, height:uint32_t, // pixelDataLength:uint32_t, data:byte[pixelDataLength] // -> ImageData (ref) - // numProperties:uint32_t -> pops the last object from the open stack; fills - // it with the last numProperties name,value pairs pushed onto the - // deserialization stack - ObjectTag = '{', - // numProperties:uint32_t, length:uint32_t -> pops the last object from the - // open stack; fills it with the last numProperties name,value pairs pushed - // onto the deserialization stack - SparseArrayTag = '@', - // numProperties:uint32_t, length:uint32_t -> pops the last object from the - // open stack; fills it with the last length elements and numProperties - // name,value pairs pushed onto deserialization stack - DenseArrayTag = '$', - RegExpTag = 'R', // pattern:RawString, flags:uint32_t -> RegExp (ref) - ArrayBufferTag = - 'B', // byteLength:uint32_t, data:byte[byteLength] -> ArrayBuffer (ref) - ArrayBufferTransferTag = - 't', // index:uint32_t -> ArrayBuffer. For ArrayBuffer transfer ImageBitmapTag = 'g', // size:uint32_t, data:byte[size] -> ImageBitmap (ref) ImageBitmapTransferTag = 'G', // index:uint32_t -> ImageBitmap. For ImageBitmap transfer OffscreenCanvasTransferTag = 'H', // index, width, height, id:uint32_t -> // OffscreenCanvas. For OffscreenCanvas // transfer - // subtag:byte, byteOffset:uint32_t, byteLength:uint32_t -> ArrayBufferView - // (ref). Consumes an ArrayBuffer from the top of the deserialization stack. - ArrayBufferViewTag = 'V', - SharedArrayBufferTransferTag = 'u', // index:uint32_t -> SharedArrayBuffer. - // For SharedArrayBuffer transfer - WasmModuleTag = 'W', - RawBytesTag = 'y', CryptoKeyTag = 'K', // subtag:byte, props, usages:uint32_t, // keyDataLength:uint32_t, keyData:byte[keyDataLength] // If subtag=AesKeyTag: @@ -110,54 +76,11 @@ // namedCurve:uint32_t RTCCertificateTag = 'k', // length:uint32_t, pemPrivateKey:WebCoreString, // pemCertificate:WebCoreString - ObjectReferenceTag = '^', // ref:uint32_t -> reference table[ref] - GenerateFreshObjectTag = 'o', // -> empty object allocated an object ID and - // pushed onto the open stack (ref) - GenerateFreshSparseArrayTag = 'a', // length:uint32_t -> empty array[length] - // allocated an object ID and pushed onto - // the open stack (ref) - GenerateFreshDenseArrayTag = 'A', // length:uint32_t -> empty array[length] - // allocated an object ID and pushed onto - // the open stack (ref) - ReferenceCountTag = '?', // refTableSize:uint32_t -> If the reference table - // is not refTableSize big, fails. - StringObjectTag = 's', // string:RawString -> new String(string) (ref) - NumberObjectTag = 'n', // value:double -> new Number(value) (ref) - TrueObjectTag = 'y', // new Boolean(true) (ref) - FalseObjectTag = 'x', // new Boolean(false) (ref) CompositorProxyTag = 'C', // elementId:uint64_t, bitfields:uint32_t -> CompositorProxy (ref) - MapTag = ':', // length:uint32_t -> pops the last object from the open stack - // (it will be a Map); - // fills it with the last length elements pushed - // onto the deserialization stack, treating them - // as key/value pairs and passing them to - // Map::Set; - // length must be an even number. - SetTag = ',', // length:uint32_t -> pops the last object from the open stack - // (it will be a Set); - // fills it with the last length elements pushed - // onto the deserialization stack, using Set::Add - GenerateFreshMapTag = ';', // -> empty Map allocated an object ID and pushed - // onto the open stack (ref) - GenerateFreshSetTag = '\'', // -> empty Set allocated an object ID and pushed - // onto the open stack (ref) VersionTag = 0xFF // version:uint32_t -> Uses this as the file version. }; -enum ArrayBufferViewSubTag { - ByteArrayTag = 'b', - UnsignedByteArrayTag = 'B', - UnsignedByteClampedArrayTag = 'C', - ShortArrayTag = 'w', - UnsignedShortArrayTag = 'W', - IntArrayTag = 'd', - UnsignedIntArrayTag = 'D', - FloatArrayTag = 'f', - DoubleArrayTag = 'F', - DataViewTag = '?' -}; - } // namespace blink #endif
diff --git a/third_party/WebKit/Source/bindings/core/v8/serialization/V8ScriptValueDeserializer.cpp b/third_party/WebKit/Source/bindings/core/v8/serialization/V8ScriptValueDeserializer.cpp index 68a6afc8..44b9806b2 100644 --- a/third_party/WebKit/Source/bindings/core/v8/serialization/V8ScriptValueDeserializer.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/serialization/V8ScriptValueDeserializer.cpp
@@ -319,7 +319,7 @@ ExceptionState exceptionState(isolate, ExceptionState::UnknownContext, nullptr, nullptr); ScriptWrappable* wrappable = nullptr; - SerializationTag tag = PaddingTag; + SerializationTag tag = VersionTag; if (readTag(&tag)) wrappable = readDOMObject(tag); if (!wrappable) {
diff --git a/third_party/WebKit/Source/bindings/modules/v8/ConditionalFeaturesForModules.cpp b/third_party/WebKit/Source/bindings/modules/v8/ConditionalFeaturesForModules.cpp index d2e318c..e2dfd25 100644 --- a/third_party/WebKit/Source/bindings/modules/v8/ConditionalFeaturesForModules.cpp +++ b/third_party/WebKit/Source/bindings/modules/v8/ConditionalFeaturesForModules.cpp
@@ -57,7 +57,9 @@ v8::Local<v8::Object>(), prototypeObject, interfaceObject); } - if (OriginTrials::webUSBEnabled(executionContext)) { + // Mimics the [SecureContext] extended attribute. + if (OriginTrials::webUSBEnabled(executionContext) && + executionContext->isSecureContext()) { V8NavigatorPartial::installWebUSB(isolate, world, v8::Local<v8::Object>(), prototypeObject, interfaceObject); } @@ -71,7 +73,9 @@ V8WindowPartial::installImageCapture(isolate, world, instanceObject, prototypeObject, interfaceObject); } - if (OriginTrials::webUSBEnabled(executionContext)) { + // Mimics the [SecureContext] extended attribute. + if (OriginTrials::webUSBEnabled(executionContext) && + executionContext->isSecureContext()) { V8WindowPartial::installWebUSB(isolate, world, instanceObject, prototypeObject, interfaceObject); }
diff --git a/third_party/WebKit/Source/core/css/CSSGlobalRuleSet.h b/third_party/WebKit/Source/core/css/CSSGlobalRuleSet.h index 0284812..93b230c 100644 --- a/third_party/WebKit/Source/core/css/CSSGlobalRuleSet.h +++ b/third_party/WebKit/Source/core/css/CSSGlobalRuleSet.h
@@ -34,7 +34,10 @@ bool isDirty() const { return m_isDirty; } void update(Document&); - const RuleFeatureSet& ruleFeatureSet() const { return m_features; } + const RuleFeatureSet& ruleFeatureSet() const { + RELEASE_ASSERT(m_features.isAlive()); + return m_features; + } RuleSet* siblingRuleSet() const { return m_siblingRuleSet; } RuleSet* uncommonAttributeRuleSet() const { return m_uncommonAttributeRuleSet;
diff --git a/third_party/WebKit/Source/core/css/RuleFeature.cpp b/third_party/WebKit/Source/core/css/RuleFeature.cpp index 9a9dffcd..7dd11cba 100644 --- a/third_party/WebKit/Source/core/css/RuleFeature.cpp +++ b/third_party/WebKit/Source/core/css/RuleFeature.cpp
@@ -248,6 +248,7 @@ void extractInvalidationSets(InvalidationSet* invalidationSet, DescendantInvalidationSet*& descendants, SiblingInvalidationSet*& siblings) { + RELEASE_ASSERT(invalidationSet->isAlive()); if (invalidationSet->type() == InvalidateDescendants) { descendants = toDescendantInvalidationSet(invalidationSet); siblings = nullptr; @@ -271,17 +272,33 @@ visitor->trace(rule); } +RuleFeatureSet::RuleFeatureSet() : m_isAlive(true) {} + +RuleFeatureSet::~RuleFeatureSet() { + RELEASE_ASSERT(m_isAlive); + + m_metadata.clear(); + m_classInvalidationSets.clear(); + m_attributeInvalidationSets.clear(); + m_idInvalidationSets.clear(); + m_pseudoInvalidationSets.clear(); + m_universalSiblingInvalidationSet.clear(); + m_nthInvalidationSet.clear(); + + m_isAlive = false; +} + ALWAYS_INLINE InvalidationSet& RuleFeatureSet::ensureClassInvalidationSet( const AtomicString& className, InvalidationType type) { - DCHECK(!className.isEmpty()); + RELEASE_ASSERT(!className.isEmpty()); return ensureInvalidationSet(m_classInvalidationSets, className, type); } ALWAYS_INLINE InvalidationSet& RuleFeatureSet::ensureAttributeInvalidationSet( const AtomicString& attributeName, InvalidationType type) { - DCHECK(!attributeName.isEmpty()); + RELEASE_ASSERT(!attributeName.isEmpty()); return ensureInvalidationSet(m_attributeInvalidationSets, attributeName, type); } @@ -289,14 +306,14 @@ ALWAYS_INLINE InvalidationSet& RuleFeatureSet::ensureIdInvalidationSet( const AtomicString& id, InvalidationType type) { - DCHECK(!id.isEmpty()); + RELEASE_ASSERT(!id.isEmpty()); return ensureInvalidationSet(m_idInvalidationSets, id, type); } ALWAYS_INLINE InvalidationSet& RuleFeatureSet::ensurePseudoInvalidationSet( CSSSelector::PseudoType pseudoType, InvalidationType type) { - DCHECK(pseudoType != CSSSelector::PseudoUnknown); + RELEASE_ASSERT(pseudoType != CSSSelector::PseudoUnknown); return ensureInvalidationSet(m_pseudoInvalidationSets, pseudoType, type); } @@ -785,6 +802,7 @@ RuleFeatureSet::SelectorPreMatch RuleFeatureSet::collectFeaturesFromRuleData( const RuleData& ruleData) { + RELEASE_ASSERT(m_isAlive); FeatureMetadata metadata; if (collectFeaturesFromSelector(ruleData.selector(), metadata) == SelectorNeverMatches) @@ -901,7 +919,9 @@ } void RuleFeatureSet::add(const RuleFeatureSet& other) { - DCHECK(&other != this); + RELEASE_ASSERT(m_isAlive); + RELEASE_ASSERT(other.m_isAlive); + RELEASE_ASSERT(&other != this); for (const auto& entry : other.m_classInvalidationSets) ensureInvalidationSet(m_classInvalidationSets, entry.key, entry.value->type()) @@ -935,6 +955,7 @@ } void RuleFeatureSet::clear() { + RELEASE_ASSERT(m_isAlive); m_siblingRules.clear(); m_uncommonAttributeRules.clear(); m_metadata.clear();
diff --git a/third_party/WebKit/Source/core/css/RuleFeature.h b/third_party/WebKit/Source/core/css/RuleFeature.h index f0f4fee2..92804c8 100644 --- a/third_party/WebKit/Source/core/css/RuleFeature.h +++ b/third_party/WebKit/Source/core/css/RuleFeature.h
@@ -68,7 +68,8 @@ WTF_MAKE_NONCOPYABLE(RuleFeatureSet); public: - RuleFeatureSet() {} + RuleFeatureSet(); + ~RuleFeatureSet(); void add(const RuleFeatureSet&); void clear(); @@ -159,6 +160,8 @@ DECLARE_TRACE(); + bool isAlive() const { return m_isAlive; } + protected: InvalidationSet* invalidationSetForSimpleSelector(const CSSSelector&, InvalidationType); @@ -295,6 +298,9 @@ MediaQueryResultList m_viewportDependentMediaQueryResults; MediaQueryResultList m_deviceDependentMediaQueryResults; + // If true, the RuleFeatureSet is alive and can be used. + unsigned m_isAlive : 1; + friend class RuleFeatureSetTest; };
diff --git a/third_party/WebKit/Source/core/css/invalidation/InvalidationSet.cpp b/third_party/WebKit/Source/core/css/invalidation/InvalidationSet.cpp index c9831e7..7f62a35 100644 --- a/third_party/WebKit/Source/core/css/invalidation/InvalidationSet.cpp +++ b/third_party/WebKit/Source/core/css/invalidation/InvalidationSet.cpp
@@ -62,7 +62,8 @@ m_customPseudoInvalid(false), m_treeBoundaryCrossing(false), m_insertionPointCrossing(false), - m_invalidatesSlotted(false) {} + m_invalidatesSlotted(false), + m_isAlive(true) {} bool InvalidationSet::invalidatesElement(Element& element) const { if (m_allDescendantsMightBeInvalid) @@ -108,8 +109,10 @@ } void InvalidationSet::combine(const InvalidationSet& other) { - DCHECK(&other != this); - DCHECK(type() == other.type()); + RELEASE_ASSERT(m_isAlive); + RELEASE_ASSERT(other.m_isAlive); + RELEASE_ASSERT(&other != this); + RELEASE_ASSERT(type() == other.type()); if (type() == InvalidateSiblings) { SiblingInvalidationSet& siblings = toSiblingInvalidationSet(*this); const SiblingInvalidationSet& otherSiblings = @@ -204,28 +207,28 @@ void InvalidationSet::addClass(const AtomicString& className) { if (wholeSubtreeInvalid()) return; - DCHECK(!className.isEmpty()); + RELEASE_ASSERT(!className.isEmpty()); ensureClassSet().insert(className); } void InvalidationSet::addId(const AtomicString& id) { if (wholeSubtreeInvalid()) return; - DCHECK(!id.isEmpty()); + RELEASE_ASSERT(!id.isEmpty()); ensureIdSet().insert(id); } void InvalidationSet::addTagName(const AtomicString& tagName) { if (wholeSubtreeInvalid()) return; - DCHECK(!tagName.isEmpty()); + RELEASE_ASSERT(!tagName.isEmpty()); ensureTagNameSet().insert(tagName); } void InvalidationSet::addAttribute(const AtomicString& attribute) { if (wholeSubtreeInvalid()) return; - DCHECK(!attribute.isEmpty()); + RELEASE_ASSERT(!attribute.isEmpty()); ensureAttributeSet().insert(attribute); }
diff --git a/third_party/WebKit/Source/core/css/invalidation/InvalidationSet.h b/third_party/WebKit/Source/core/css/invalidation/InvalidationSet.h index e6f0d35..b47bb0c 100644 --- a/third_party/WebKit/Source/core/css/invalidation/InvalidationSet.h +++ b/third_party/WebKit/Source/core/css/invalidation/InvalidationSet.h
@@ -127,6 +127,8 @@ !m_invalidatesSlotted; } + bool isAlive() const { return m_isAlive; } + void toTracedValue(TracedValue*) const; #ifndef NDEBUG @@ -163,6 +165,11 @@ protected: explicit InvalidationSet(InvalidationType); + ~InvalidationSet() { + RELEASE_ASSERT(m_isAlive); + m_isAlive = false; + } + private: void destroy(); @@ -205,6 +212,9 @@ // If true, distributed nodes of <slot> elements need to be invalidated. unsigned m_invalidatesSlotted : 1; + + // If true, the instance is alive and can be used. + unsigned m_isAlive : 1; }; class CORE_EXPORT DescendantInvalidationSet final : public InvalidationSet {
diff --git a/third_party/WebKit/Source/core/css/invalidation/StyleInvalidator.cpp b/third_party/WebKit/Source/core/css/invalidation/StyleInvalidator.cpp index 79c4df3..ed0fa52c 100644 --- a/third_party/WebKit/Source/core/css/invalidation/StyleInvalidator.cpp +++ b/third_party/WebKit/Source/core/css/invalidation/StyleInvalidator.cpp
@@ -286,15 +286,19 @@ m_pendingInvalidationMap.get(&node); DCHECK(pendingInvalidations); - for (const auto& invalidationSet : pendingInvalidations->siblings()) + for (const auto& invalidationSet : pendingInvalidations->siblings()) { + RELEASE_ASSERT(invalidationSet->isAlive()); siblingData.pushInvalidationSet(toSiblingInvalidationSet(*invalidationSet)); + } if (node.getStyleChangeType() >= SubtreeStyleChange) return; if (!pendingInvalidations->descendants().isEmpty()) { - for (const auto& invalidationSet : pendingInvalidations->descendants()) + for (const auto& invalidationSet : pendingInvalidations->descendants()) { + RELEASE_ASSERT(invalidationSet->isAlive()); recursionData.pushInvalidationSet(*invalidationSet); + } if (UNLIKELY(*s_tracingEnabled)) { TRACE_EVENT_INSTANT1( TRACE_DISABLED_BY_DEFAULT("devtools.timeline.invalidationTracking"),
diff --git a/third_party/WebKit/Source/core/editing/EditingUtilities.cpp b/third_party/WebKit/Source/core/editing/EditingUtilities.cpp index 319324f..84465a9 100644 --- a/third_party/WebKit/Source/core/editing/EditingUtilities.cpp +++ b/third_party/WebKit/Source/core/editing/EditingUtilities.cpp
@@ -79,6 +79,27 @@ return os << *it; } +InputEvent::EventCancelable inputTypeIsCancelable( + InputEvent::InputType inputType) { + using InputType = InputEvent::InputType; + switch (inputType) { + case InputType::InsertText: + case InputType::InsertLineBreak: + case InputType::InsertParagraph: + case InputType::InsertCompositionText: + case InputType::InsertReplacementText: + case InputType::DeleteWordBackward: + case InputType::DeleteWordForward: + case InputType::DeleteLineBackward: + case InputType::DeleteLineForward: + case InputType::DeleteContentBackward: + case InputType::DeleteContentForward: + return InputEvent::EventCancelable::NotCancelable; + default: + return InputEvent::EventCancelable::IsCancelable; + } +} + } // namespace static bool needsLayoutTreeUpdate(const Node& node) { @@ -2060,11 +2081,11 @@ return DispatchEventResult::NotCanceled; // TODO(chongz): Pass appropriate |ranges| after it's defined on spec. // http://w3c.github.io/editing/input-events.html#dom-inputevent-inputtype - InputEvent* beforeInputEvent = - InputEvent::createBeforeInput(InputEvent::InputType::InsertText, data, - InputEvent::EventCancelable::IsCancelable, - InputEvent::EventIsComposing::NotComposing, - targetRangesForInputEvent(*target)); + InputEvent* beforeInputEvent = InputEvent::createBeforeInput( + InputEvent::InputType::InsertText, data, + inputTypeIsCancelable(InputEvent::InputType::InsertText), + InputEvent::EventIsComposing::NotComposing, + targetRangesForInputEvent(*target)); return target->dispatchEvent(beforeInputEvent); } @@ -2077,7 +2098,7 @@ if (!target) return DispatchEventResult::NotCanceled; InputEvent* beforeInputEvent = InputEvent::createBeforeInput( - inputType, nullAtom, InputEvent::EventCancelable::IsCancelable, + inputType, nullAtom, inputTypeIsCancelable(inputType), InputEvent::EventIsComposing::NotComposing, ranges); return target->dispatchEvent(beforeInputEvent); } @@ -2101,7 +2122,7 @@ if (hasRichlyEditableStyle(*(target->toNode())) || !dataTransfer) { beforeInputEvent = InputEvent::createBeforeInput( - inputType, dataTransfer, InputEvent::EventCancelable::IsCancelable, + inputType, dataTransfer, inputTypeIsCancelable(inputType), InputEvent::EventIsComposing::NotComposing, targetRangesForInputEvent(*target)); } else { @@ -2109,7 +2130,7 @@ // TODO(chongz): Pass appropriate |ranges| after it's defined on spec. // http://w3c.github.io/editing/input-events.html#dom-inputevent-inputtype beforeInputEvent = InputEvent::createBeforeInput( - inputType, data, InputEvent::EventCancelable::IsCancelable, + inputType, data, inputTypeIsCancelable(inputType), InputEvent::EventIsComposing::NotComposing, targetRangesForInputEvent(*target)); }
diff --git a/third_party/WebKit/Source/core/editing/FrameCaret.cpp b/third_party/WebKit/Source/core/editing/FrameCaret.cpp index 640f161..f45bead8 100644 --- a/third_party/WebKit/Source/core/editing/FrameCaret.cpp +++ b/third_party/WebKit/Source/core/editing/FrameCaret.cpp
@@ -69,7 +69,7 @@ const PositionWithAffinity FrameCaret::caretPosition() const { const VisibleSelection& selection = - m_selectionEditor->visibleSelection<EditingStrategy>(); + m_selectionEditor->computeVisibleSelectionInDOMTree(); if (!selection.isCaret()) return PositionWithAffinity(); return PositionWithAffinity(selection.start(), selection.affinity()); @@ -149,7 +149,7 @@ bool shouldPaintCaret = m_shouldPaintCaret && isActive() && m_caretVisibility == CaretVisibility::Visible && - m_selectionEditor->visibleSelection<EditingStrategy>().hasEditableStyle(); + m_selectionEditor->computeVisibleSelectionInDOMTree().hasEditableStyle(); m_displayItemClient->updateStyleAndLayoutIfNeeded( shouldPaintCaret ? caretPosition() : PositionWithAffinity());
diff --git a/third_party/WebKit/Source/core/editing/FrameSelectionTest.cpp b/third_party/WebKit/Source/core/editing/FrameSelectionTest.cpp index 50a58635..09d6169 100644 --- a/third_party/WebKit/Source/core/editing/FrameSelectionTest.cpp +++ b/third_party/WebKit/Source/core/editing/FrameSelectionTest.cpp
@@ -204,27 +204,6 @@ EXPECT_EQ_SELECTED_TEXT("Foo Bar"); } -// TODO(yosin): We should move |SelectionControllerTest" to -// "SelectionControllerTest.cpp" -class SelectionControllerTest : public EditingTestBase { - protected: - SelectionControllerTest() = default; - - const VisibleSelection& visibleSelectionInDOMTree() const { - return selection().computeVisibleSelectionInDOMTreeDeprecated(); - } - - const VisibleSelectionInFlatTree& visibleSelectionInFlatTree() const { - return selection().selectionInFlatTree(); - } - - void setNonDirectionalSelectionIfNeeded(const VisibleSelectionInFlatTree&, - TextGranularity); - - private: - DISALLOW_COPY_AND_ASSIGN(SelectionControllerTest); -}; - TEST_F(FrameSelectionTest, SelectAllWithUnselectableRoot) { Element* select = document().createElement("select"); document().replaceChild(select, document().documentElement());
diff --git a/third_party/WebKit/Source/core/editing/SelectionEditor.cpp b/third_party/WebKit/Source/core/editing/SelectionEditor.cpp index 3835d067..04dd0915 100644 --- a/third_party/WebKit/Source/core/editing/SelectionEditor.cpp +++ b/third_party/WebKit/Source/core/editing/SelectionEditor.cpp
@@ -71,18 +71,6 @@ return *lifecycleContext(); } -template <> -const VisibleSelection& SelectionEditor::visibleSelection<EditingStrategy>() - const { - return computeVisibleSelectionInDOMTree(); -} - -template <> -const VisibleSelectionInFlatTree& -SelectionEditor::visibleSelection<EditingInFlatTreeStrategy>() const { - return computeVisibleSelectionInFlatTree(); -} - const VisibleSelection& SelectionEditor::computeVisibleSelectionInDOMTree() const { DCHECK_EQ(frame()->document(), document());
diff --git a/third_party/WebKit/Source/core/editing/SelectionEditor.h b/third_party/WebKit/Source/core/editing/SelectionEditor.h index e2f7f6e..cde5ee9 100644 --- a/third_party/WebKit/Source/core/editing/SelectionEditor.h +++ b/third_party/WebKit/Source/core/editing/SelectionEditor.h
@@ -53,8 +53,6 @@ bool isContentEditable() const; bool isContentRichlyEditable() const; - template <typename Strategy> - const VisibleSelectionTemplate<Strategy>& visibleSelection() const; const SelectionInDOMTree& selectionInDOMTree() const; const VisibleSelection& computeVisibleSelectionInDOMTree() const;
diff --git a/third_party/WebKit/Source/core/editing/VisibleSelection.cpp b/third_party/WebKit/Source/core/editing/VisibleSelection.cpp index 3fbaa8b..60dde507 100644 --- a/third_party/WebKit/Source/core/editing/VisibleSelection.cpp +++ b/third_party/WebKit/Source/core/editing/VisibleSelection.cpp
@@ -138,14 +138,6 @@ template <typename Strategy> void VisibleSelectionTemplate<Strategy>::setBase( - const PositionTemplate<Strategy>& position) { - DCHECK(!needsLayoutTreeUpdate(position)); - m_base = position; - validate(); -} - -template <typename Strategy> -void VisibleSelectionTemplate<Strategy>::setBase( const VisiblePositionTemplate<Strategy>& visiblePosition) { DCHECK(visiblePosition.isValid()); m_base = visiblePosition.deepEquivalent(); @@ -154,14 +146,6 @@ template <typename Strategy> void VisibleSelectionTemplate<Strategy>::setExtent( - const PositionTemplate<Strategy>& position) { - DCHECK(!needsLayoutTreeUpdate(position)); - m_extent = position; - validate(); -} - -template <typename Strategy> -void VisibleSelectionTemplate<Strategy>::setExtent( const VisiblePositionTemplate<Strategy>& visiblePosition) { DCHECK(visiblePosition.isValid()); m_extent = visiblePosition.deepEquivalent();
diff --git a/third_party/WebKit/Source/core/editing/VisibleSelection.h b/third_party/WebKit/Source/core/editing/VisibleSelection.h index 6da5081c..d5b0fab 100644 --- a/third_party/WebKit/Source/core/editing/VisibleSelection.h +++ b/third_party/WebKit/Source/core/editing/VisibleSelection.h
@@ -69,9 +69,7 @@ // TODO(yosin): To make |VisibleSelection| as immutable object, we should // get rid of |setBase()| and |setExtent()| by replacing them with // |createVisibleSelection()|. - void setBase(const PositionTemplate<Strategy>&); void setBase(const VisiblePositionTemplate<Strategy>&); - void setExtent(const PositionTemplate<Strategy>&); void setExtent(const VisiblePositionTemplate<Strategy>&); SelectionTemplate<Strategy> asSelection() const;
diff --git a/third_party/WebKit/Source/core/frame/FrameView.cpp b/third_party/WebKit/Source/core/frame/FrameView.cpp index 29ddba6..552536d 100644 --- a/third_party/WebKit/Source/core/frame/FrameView.cpp +++ b/third_party/WebKit/Source/core/frame/FrameView.cpp
@@ -183,7 +183,9 @@ m_stickyPositionObjectCount(0), m_inputEventsScaleFactorForEmulation(1), m_layoutSizeFixedToFrameSize(true), - m_didScrollTimer(this, &FrameView::didScrollTimerFired), + m_didScrollTimer(TaskRunnerHelper::get(TaskType::UnspecedTimer, &frame), + this, + &FrameView::didScrollTimerFired), m_needsUpdateWidgetGeometries(false), m_horizontalScrollbarMode(ScrollbarAuto), m_verticalScrollbarMode(ScrollbarAuto), @@ -830,6 +832,12 @@ if (needsLayout()) return; + // If the visualViewport supplies scrollbars, we won't get a paint + // invalidation from computeScrollbarExistence so we need to force one + // TODO(bokan): We should avoid computeScrollbarExistence otherwise. + if (visualViewportSuppliesScrollbars()) + layoutViewItem.setMayNeedPaintInvalidation(); + // TODO(pdr): This should be refactored to just block scrollbar updates as // we are not in a scrollbar update here and m_inUpdateScrollbars has other // side effects. This scope is only for preventing a synchronous layout from
diff --git a/third_party/WebKit/Source/core/frame/FrameView.h b/third_party/WebKit/Source/core/frame/FrameView.h index 924c7807..c042f64 100644 --- a/third_party/WebKit/Source/core/frame/FrameView.h +++ b/third_party/WebKit/Source/core/frame/FrameView.h
@@ -1104,7 +1104,7 @@ IntSize m_initialViewportSize; bool m_layoutSizeFixedToFrameSize; - Timer<FrameView> m_didScrollTimer; + TaskRunnerTimer<FrameView> m_didScrollTimer; Vector<IntRect> m_tickmarks;
diff --git a/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp b/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp index a55d1e43..d8baa35f 100644 --- a/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp +++ b/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp
@@ -328,7 +328,6 @@ void HTMLCanvasElement::finalizeFrame() { if (hasImageBuffer()) m_imageBuffer->finalizeFrame(); - m_context->incrementFrameCount(); notifyListenersCanvasChanged(); }
diff --git a/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp b/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp index a3a195c2..ee9fcef 100644 --- a/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp +++ b/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp
@@ -262,7 +262,7 @@ if (contentMIMEType.isEmpty()) return true; - // 4.8.10.3 MIME types - In the absence of a specification to the contrary, + // 4.8.12.3 MIME types - In the absence of a specification to the contrary, // the MIME type "application/octet-stream" when used with parameters, e.g. // "application/octet-stream;codecs=theora", is a type that the user agent // knows it cannot render. @@ -337,7 +337,7 @@ if (type.isEmpty()) return MIMETypeRegistry::IsNotSupported; - // 4.8.10.3 MIME types - The canPlayType(type) method must return the empty + // 4.8.12.3 MIME types - The canPlayType(type) method must return the empty // string if type is a type that the user agent knows it cannot render or is // the type "application/octet-stream" if (type == "application/octet-stream") @@ -739,7 +739,7 @@ MIMETypeRegistry::SupportsType support = supportsType(ContentType(mimeType)); String canPlay; - // 4.8.10.3 + // 4.8.12.3 switch (support) { case MIMETypeRegistry::IsNotSupported: canPlay = emptyString; @@ -1227,7 +1227,8 @@ } void HTMLMediaElement::deferLoad() { - // This implements the "optional" step 3 from the resource fetch algorithm. + // This implements the "optional" step 4 from the resource fetch algorithm + // "If mode is remote". DCHECK(!m_deferredLoadTimer.isActive()); DCHECK_EQ(m_deferredLoadState, NotDeferred); // 1. Set the networkState to NETWORK_IDLE. @@ -1249,7 +1250,7 @@ void HTMLMediaElement::executeDeferredLoad() { DCHECK_GE(m_deferredLoadState, WaitingForTrigger); - // resource fetch algorithm step 3 - continued from deferLoad(). + // resource fetch algorithm step 4 - continued from deferLoad(). // 5. Wait for an implementation-defined event (e.g. the user requesting that // the media element begin playback). This is assumed to be whatever 'event' @@ -1300,7 +1301,7 @@ } bool HTMLMediaElement::textTracksAreReady() const { - // 4.8.10.12.1 Text track model + // 4.8.12.11.1 Text track model // ... // The text tracks of a media element are ready if all the text tracks whose // mode was not in the disabled state when the element's resource selection @@ -1434,7 +1435,7 @@ m_loadState = WaitingForSource; m_currentSourceNode = nullptr; - // 4.8.13.5 + // 4.8.12.5 // The dedicated media source failure steps are the following steps: // 1 - Set the error attribute to a new MediaError object whose code attribute @@ -1651,14 +1652,14 @@ return; if (m_seeking) { - // 4.8.10.9, step 9 note: If the media element was potentially playing + // 4.8.12.9, step 9 note: If the media element was potentially playing // immediately before it started seeking, but seeking caused its readyState // attribute to change to a value lower than kHaveFutureData, then a waiting // will be fired at the element. if (wasPotentiallyPlaying && m_readyState < kHaveFutureData) scheduleEvent(EventTypeNames::waiting); - // 4.8.10.9 steps 12-14 + // 4.8.12.9 steps 12-14 if (m_readyState >= kHaveCurrentData) finishSeek(); } else { @@ -1670,7 +1671,7 @@ // media time at the moment we ran out of data to play. setOfficialPlaybackPosition(currentPlaybackPosition()); - // 4.8.10.8 + // 4.8.12.8 scheduleTimeupdateEvent(false); scheduleEvent(EventTypeNames::waiting); } @@ -2113,7 +2114,7 @@ } bool HTMLMediaElement::ended() const { - // 4.8.10.8 Playing the media resource + // 4.8.12.8 Playing the media resource // The ended attribute must return true if the media element has ended // playback and the direction of playback is forwards, and false otherwise. return endedPlayback() && getDirectionOfPlayback() == Forward; @@ -2295,7 +2296,7 @@ webMediaPlayer()->setBufferingStrategy( WebMediaPlayer::BufferingStrategy::Normal); - // 4.8.10.9. Playing the media resource + // 4.8.12.8. Playing the media resource if (m_networkState == kNetworkEmpty) invokeResourceSelectionAlgorithm(); @@ -2681,7 +2682,7 @@ } void HTMLMediaElement::addTextTrack(WebInbandTextTrack* webTrack) { - // 4.8.10.12.2 Sourcing in-band text tracks + // 4.8.12.11.2 Sourcing in-band text tracks // 1. Associate the relevant data with a new text track and its corresponding // new TextTrack object. InbandTextTrack* textTrack = InbandTextTrack::create(webTrack); @@ -2792,7 +2793,7 @@ } void HTMLMediaElement::didAddTrackElement(HTMLTrackElement* trackElement) { - // 4.8.10.12.3 Sourcing out-of-band text tracks + // 4.8.12.11.3 Sourcing out-of-band text tracks // When a track element's parent element changes and the new parent is a media // element, then the user agent must add the track element's corresponding // text track to the media element's list of text tracks ... [continues in @@ -2823,7 +2824,7 @@ if (!m_textTracks) return; - // 4.8.10.12.3 Sourcing out-of-band text tracks + // 4.8.12.11.3 Sourcing out-of-band text tracks // When a track element's parent element changes and the old parent was a // media element, then the user agent must remove the track element's // corresponding text track from the media element's list of text tracks. @@ -3060,7 +3061,7 @@ cueTimeline().updateActiveCues(currentTime()); - // 4.8.10.9 steps 12-14. Needed if no ReadyState change is associated with the + // 4.8.12.9 steps 12-14. Needed if no ReadyState change is associated with the // seek. if (m_seeking && m_readyState >= kHaveCurrentData && !webMediaPlayer()->seeking()) @@ -3311,7 +3312,7 @@ if (std::isnan(dur)) return false; - // 4.8.10.8 Playing the media resource + // 4.8.12.8 Playing the media resource // A media element is said to have ended playback when the element's // readyState attribute is HAVE_METADATA or greater,
diff --git a/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.cpp b/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.cpp index ce4019c1..5db6d54 100644 --- a/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.cpp +++ b/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.cpp
@@ -160,12 +160,11 @@ Platform::current()->currentThread()->removeTaskObserver(this); m_finalizeFrameScheduled = false; - if (!canvas()) - return; - // The end of a script task that drew content to the canvas is the point // at which the current frame may be considered complete. - canvas()->finalizeFrame(); + if (canvas()) + canvas()->finalizeFrame(); + finalizeFrame(); } CanvasRenderingContext::ContextType CanvasRenderingContext::contextTypeFromId(
diff --git a/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.h b/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.h index b420788..a7bc7ddc 100644 --- a/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.h +++ b/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.h
@@ -134,6 +134,11 @@ }; virtual void loseContext(LostContextMode) {} + // This method gets called at the end of script tasks that modified + // the contents of the canvas (called didDraw). It marks the completion + // of a presentable frame. + virtual void finalizeFrame() {} + // WebThread::TaskObserver implementation void didProcessTask() override; void willProcessTask() final {} @@ -157,7 +162,6 @@ virtual String getIdFromControl(const Element* element) { return String(); } virtual bool isAccelerationOptimalForCanvasContent() const { return true; } virtual void resetUsageTracking(){}; - virtual void incrementFrameCount(){}; // WebGL-specific interface virtual bool is3d() const { return false; }
diff --git a/third_party/WebKit/Source/core/layout/BUILD.gn b/third_party/WebKit/Source/core/layout/BUILD.gn index a39c79d..30352db 100644 --- a/third_party/WebKit/Source/core/layout/BUILD.gn +++ b/third_party/WebKit/Source/core/layout/BUILD.gn
@@ -312,6 +312,8 @@ "ng/ng_layout_opportunity_iterator.h", "ng/ng_layout_opportunity_tree_node.cc", "ng/ng_layout_opportunity_tree_node.h", + "ng/ng_layout_result.cc", + "ng/ng_layout_result.h", "ng/ng_length_utils.cc", "ng/ng_length_utils.h", "ng/ng_line_builder.cc",
diff --git a/third_party/WebKit/Source/core/layout/ng/layout_ng_block_flow.cc b/third_party/WebKit/Source/core/layout/ng/layout_ng_block_flow.cc index 2f6e37c7b..7eb001cc 100644 --- a/third_party/WebKit/Source/core/layout/ng/layout_ng_block_flow.cc +++ b/third_party/WebKit/Source/core/layout/ng/layout_ng_block_flow.cc
@@ -27,7 +27,7 @@ // passes (probably FirstChild(), etc). m_box = new NGBlockNode(this); - RefPtr<NGPhysicalFragment> fragment = m_box->Layout(constraint_space); + RefPtr<NGLayoutResult> result = m_box->Layout(constraint_space); if (isOutOfFlowPositioned()) { // In legacy layout, abspos differs from regular blocks in that abspos @@ -44,7 +44,7 @@ setLogicalTop(computedValues.m_position); } - for (auto& descendant : fragment->OutOfFlowDescendants()) + for (auto& descendant : result->OutOfFlowDescendants()) descendant->UseOldOutOfFlowPositioning(); clearNeedsLayout(); }
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc index 96ed873..9a7fda3 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc
@@ -210,7 +210,9 @@ // Calculate the float offset if needed. LayoutUnit float_offset; if (floating_object->exclusion_type == NGExclusion::kFloatRight) { - float_offset = opportunity.size.inline_size - float_fragment.InlineSize(); + LayoutUnit float_margin_box_inline_size = + float_fragment.InlineSize() + floating_object->margins.InlineSum(); + float_offset = opportunity.size.inline_size - float_margin_box_inline_size; } // Add the float as an exclusion. @@ -227,12 +229,13 @@ // and {@code floating_object}'s space and margins. void UpdateFloatingObjectLeftOffset( const NGConstraintSpace& new_parent_space, - const Persistent<NGFloatingObject>& floating_object) { - const auto& float_space = floating_object->space; + const Persistent<NGFloatingObject>& floating_object, + const NGLogicalOffset& float_logical_offset) { // TODO(glebl): We should use physical offset here. - floating_object->left_offset = float_space->BfcOffset().inline_offset - - new_parent_space.BfcOffset().inline_offset + - floating_object->margins.inline_start; + floating_object->left_offset = + floating_object->original_parent_space->BfcOffset().inline_offset - + new_parent_space.BfcOffset().inline_offset + + float_logical_offset.inline_offset; } // Positions pending floats stored on the fragment builder starting from @@ -245,18 +248,19 @@ for (auto& floating_object : builder->UnpositionedFloats()) { Member<NGConstraintSpace> float_space = floating_object->space; - Member<const NGConstraintSpace> float_parent_space = - floating_object->parent_space; + Member<const NGConstraintSpace> original_parent_space = + floating_object->original_parent_space; NGLogicalOffset origin_point = {float_space->BfcOffset().inline_offset, origin_point_block_offset}; NGLogicalOffset from_offset = { - float_parent_space->BfcOffset().inline_offset, bfc_block_offset}; + original_parent_space->BfcOffset().inline_offset, bfc_block_offset}; NGLogicalOffset float_fragment_offset = PositionFloat(origin_point, from_offset, floating_object); builder->AddFloatingObject(floating_object, float_fragment_offset); - UpdateFloatingObjectLeftOffset(new_parent_space, floating_object); + UpdateFloatingObjectLeftOffset(new_parent_space, floating_object, + float_fragment_offset); } builder->MutableUnpositionedFloats().clear(); } @@ -352,7 +356,7 @@ return {inline_offset, block_offset}; } -RefPtr<NGPhysicalFragment> NGBlockLayoutAlgorithm::Layout() { +RefPtr<NGLayoutResult> NGBlockLayoutAlgorithm::Layout() { WTF::Optional<MinAndMaxContentSizes> sizes; if (NeedMinAndMaxContentSizes(ConstraintSpace(), Style())) sizes = ComputeMinAndMaxContentSizes(); @@ -449,12 +453,13 @@ continue; } - RefPtr<NGPhysicalFragment> physical_fragment = + RefPtr<NGLayoutResult> layout_result = current_child_->Layout(space_for_current_child_); - FinishCurrentChildLayout(toNGPhysicalBoxFragment(physical_fragment.get())); + FinishCurrentChildLayout(layout_result); - if (!ProceedToNextUnfinishedSibling(physical_fragment.get())) + if (!ProceedToNextUnfinishedSibling( + layout_result->PhysicalFragment().get())) break; } @@ -512,30 +517,31 @@ NGFragmentBuilder wrapper_fragment_builder(NGPhysicalFragment::kFragmentBox, current_child); line_builder.CreateFragments(&wrapper_fragment_builder); - RefPtr<NGPhysicalBoxFragment> child_fragment = + RefPtr<NGLayoutResult> child_result = wrapper_fragment_builder.ToBoxFragment(); line_builder.CopyFragmentDataToLayoutBlockFlow(); - FinishCurrentChildLayout(child_fragment.get()); + FinishCurrentChildLayout(child_result); current_child_ = nullptr; } void NGBlockLayoutAlgorithm::FinishCurrentChildLayout( - RefPtr<NGPhysicalBoxFragment> physical_fragment) { - NGBoxFragment fragment(ConstraintSpace().WritingMode(), - physical_fragment.get()); + RefPtr<NGLayoutResult> layout_result) { + NGBoxFragment fragment( + ConstraintSpace().WritingMode(), + toNGPhysicalBoxFragment(layout_result->PhysicalFragment().get())); // Pull out unpositioned floats to the current fragment. This may needed if // for example the child fragment could not position its floats because it's // empty and therefore couldn't determine its position in space. builder_->MutableUnpositionedFloats().appendVector( - physical_fragment->UnpositionedFloats()); + layout_result->UnpositionedFloats()); if (current_child_->Type() == NGLayoutInputNode::kLegacyBlock && CurrentChildStyle().isFloating()) { - NGFloatingObject* floating_object = - new NGFloatingObject(physical_fragment.get(), space_for_current_child_, - constraint_space_, toNGBlockNode(current_child_), - CurrentChildStyle(), curr_child_margins_); + NGFloatingObject* floating_object = new NGFloatingObject( + layout_result->PhysicalFragment().get(), space_for_current_child_, + constraint_space_, toNGBlockNode(current_child_), CurrentChildStyle(), + curr_child_margins_); builder_->AddUnpositionedFloat(floating_object); // No need to postpone the positioning if we know the correct offset. if (builder_->BfcOffset()) { @@ -600,7 +606,7 @@ curr_child_margins_.InlineSum() + border_and_padding_.InlineSum()); - builder_->AddChild(std::move(physical_fragment), logical_offset); + builder_->AddChild(layout_result, logical_offset); } bool NGBlockLayoutAlgorithm::ProceedToNextUnfinishedSibling(
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.h b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.h index 74365e48..4eaeda5 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.h +++ b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.h
@@ -21,6 +21,7 @@ class NGConstraintSpace; class NGConstraintSpaceBuilder; class NGInlineNode; +class NGLayoutResult; class NGPhysicalFragment; // A class for general block layout (e.g. a <div> with no special style). @@ -37,7 +38,7 @@ NGBreakToken* break_token = nullptr); Optional<MinAndMaxContentSizes> ComputeMinAndMaxContentSizes() const override; - RefPtr<NGPhysicalFragment> Layout() override; + RefPtr<NGLayoutResult> Layout() override; private: NGBoxStrut CalculateMargins(const NGConstraintSpace& space, @@ -45,7 +46,7 @@ // Creates a new constraint space for the current child. NGConstraintSpace* CreateConstraintSpaceForCurrentChild(); - void FinishCurrentChildLayout(RefPtr<NGPhysicalBoxFragment>); + void FinishCurrentChildLayout(RefPtr<NGLayoutResult>); // Layout inline children. void LayoutInlineChildren(NGInlineNode*);
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm_test.cc b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm_test.cc index 518eaef..8b3ba8b 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm_test.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm_test.cc
@@ -63,10 +63,10 @@ NGBlockNode* node = new NGBlockNode(style_.get()); node->SetFirstChild(first_child); - RefPtr<NGPhysicalFragment> fragment = + RefPtr<NGLayoutResult> result = NGBlockLayoutAlgorithm(node, space).Layout(); - return toNGPhysicalBoxFragment(fragment.get()); + return toNGPhysicalBoxFragment(result->PhysicalFragment().get()); } std::pair<RefPtr<NGPhysicalBoxFragment>, NGConstraintSpace*> @@ -77,9 +77,10 @@ NGConstraintSpace* space = NGConstraintSpace::CreateFromLayoutObject(*block_flow); - RefPtr<NGPhysicalFragment> fragment = + RefPtr<NGLayoutResult> result = NGBlockLayoutAlgorithm(node, space).Layout(); - return std::make_pair(toNGPhysicalBoxFragment(fragment.get()), space); + return std::make_pair( + toNGPhysicalBoxFragment(result->PhysicalFragment().get()), space); } MinAndMaxContentSizes RunComputeMinAndMax(NGBlockNode* first_child) { @@ -815,8 +816,9 @@ setBodyInnerHTML(R"HTML( <style> #container { - height: 200px; - width: 200px; + height: 300px; + width: 300px; + outline: blue solid; } #empty1 { margin: 20px; @@ -826,7 +828,7 @@ margin: 15px; padding: 0 15px; } - #float { + #left-float { float: left; height: 5px; width: 5px; @@ -834,11 +836,19 @@ margin: 10px; background-color: green; } + #right-float { + float: right; + height: 15px; + width: 15px; + margin: 15px 10px; + background-color: red; + } </style> <div id='container'> <div id='empty1'> <div id='empty2'> - <div id='float'></div> + <div id='left-float'></div> + <div id='right-float'></div> </div> </div> </div> @@ -876,16 +886,26 @@ int empty2_inline_offset = 35; EXPECT_THAT(LayoutUnit(empty2_inline_offset), empty2_fragment->LeftOffset()); - ASSERT_EQ(1UL, container_fragment->PositionedFloats().size()); - auto float_fragment = container_fragment->PositionedFloats().at(0)->fragment; - // 10 = float's padding - EXPECT_THAT(LayoutUnit(10), float_fragment->TopOffset()); - // 25 = empty2's padding(15) + float's padding(10) - int float_inline_offset = 25; - EXPECT_THAT(float_fragment->LeftOffset(), LayoutUnit(float_inline_offset)); + ASSERT_EQ(2UL, container_fragment->PositionedFloats().size()); + RefPtr<NGPhysicalFragment> left_float_fragment = + container_fragment->PositionedFloats().at(0)->fragment; + // inline 25 = empty2's padding(15) + left float's margin(10) + // block 10 = left float's margin + EXPECT_THAT(NGPhysicalOffset(LayoutUnit(25), LayoutUnit(10)), + left_float_fragment->Offset()); + + auto right_float_fragment = + container_fragment->PositionedFloats().at(1)->fragment; + LayoutUnit right_float_offset = LayoutUnit(125); + // inline offset 150 = empty2's padding(15) + right float's margin(10) + right + // float offset(125) + // block offset 15 = right float's margin + EXPECT_THAT( + NGPhysicalOffset(LayoutUnit(25) + right_float_offset, LayoutUnit(15)), + right_float_fragment->Offset()); // ** Verify layout tree ** - Element* left_float = document().getElementById("float"); + Element* left_float = document().getElementById("left-float"); // 88 = body's margin(8) + // empty1's padding and margin + empty2's padding and margins + float's // padding @@ -894,18 +914,28 @@ EXPECT_THAT(body_top_offset + 10, left_float->offsetTop()); // ** Legacy Floating objects ** - Element* body = document().getElementsByTagName("body")->item(0); + // #container is the 1st non-empty block so floats are attached to it. + Element* container = document().getElementById("container"); auto& floating_objects = const_cast<FloatingObjects*>( - toLayoutBlockFlow(body->layoutObject())->floatingObjects()) + toLayoutBlockFlow(container->layoutObject())->floatingObjects()) ->mutableSet(); - ASSERT_EQ(1UL, floating_objects.size()); - auto floating_object = floating_objects.takeFirst(); - ASSERT_TRUE(floating_object->isPlaced()); + ASSERT_EQ(2UL, floating_objects.size()); + auto left_floating_object = floating_objects.takeFirst(); + ASSERT_TRUE(left_floating_object->isPlaced()); // 80 = float_inline_offset(25) + accumulative offset of empty blocks(35 + 20) - EXPECT_THAT(LayoutUnit(80), floating_object->x()); - // 10 = float's padding - EXPECT_THAT(LayoutUnit(10), floating_object->y()); + EXPECT_THAT(LayoutUnit(80), left_floating_object->x()); + // 10 = left float's margin + EXPECT_THAT(LayoutUnit(10), left_floating_object->y()); + + auto right_floating_object = floating_objects.takeFirst(); + ASSERT_TRUE(right_floating_object->isPlaced()); + // 205 = float_inline_offset(25) + + // accumulative offset of empty blocks(35 + 20) + // + right float offset(125) + EXPECT_THAT(LayoutUnit(80) + right_float_offset, right_floating_object->x()); + // 15 = right float's margin + EXPECT_THAT(LayoutUnit(15), right_floating_object->y()); } // Verifies that left/right floating and regular blocks can be positioned @@ -2034,10 +2064,11 @@ <div id="empty-block2"></div> </div> )HTML"); - Element* body = document().getElementsByTagName("body")->item(0); + // #container is the new parent for our float because it's height != 0. + Element* container = document().getElementById("container"); auto& floating_objects = const_cast<FloatingObjects*>( - toLayoutBlockFlow(body->layoutObject())->floatingObjects()) + toLayoutBlockFlow(container->layoutObject())->floatingObjects()) ->mutableSet(); ASSERT_EQ(1UL, floating_objects.size()); auto floating_object = floating_objects.takeFirst();
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 3ba94b6..0d36522 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
@@ -14,6 +14,7 @@ #include "core/layout/ng/ng_constraint_space_builder.h" #include "core/layout/ng/ng_fragment_builder.h" #include "core/layout/ng/ng_inline_node.h" +#include "core/layout/ng/ng_layout_result.h" #include "core/layout/ng/ng_length_utils.h" #include "core/layout/ng/ng_writing_mode.h" #include "core/paint/PaintLayer.h" @@ -24,15 +25,15 @@ namespace { // Copies data back to the legacy layout tree for a given child fragment. -void FragmentPositionUpdated(const NGPhysicalBoxFragment& box_fragment) { - LayoutBox* layout_box = toLayoutBox(box_fragment.GetLayoutObject()); +void FragmentPositionUpdated(const NGPhysicalFragment& fragment) { + LayoutBox* layout_box = toLayoutBox(fragment.GetLayoutObject()); if (!layout_box) return; DCHECK(layout_box->parent()) << "Should be called on children only."; - layout_box->setX(box_fragment.LeftOffset()); - layout_box->setY(box_fragment.TopOffset()); + layout_box->setX(fragment.LeftOffset()); + layout_box->setY(fragment.TopOffset()); } // Similar to FragmentPositionUpdated but for floats. @@ -76,22 +77,21 @@ // included from a compilation unit that lacks the ComputedStyle definition. NGBlockNode::~NGBlockNode() {} -RefPtr<NGPhysicalFragment> NGBlockNode::Layout( +RefPtr<NGLayoutResult> NGBlockNode::Layout( NGConstraintSpace* constraint_space) { // Use the old layout code and synthesize a fragment. if (!CanUseNewLayout()) { DCHECK(layout_box_); - fragment_ = RunOldLayout(*constraint_space); - return fragment_; + layout_result_ = RunOldLayout(*constraint_space); + return layout_result_; } - RefPtr<NGPhysicalFragment> fragment = + layout_result_ = NGBlockLayoutAlgorithm(this, constraint_space, CurrentBreakToken()) .Layout(); - fragment_ = toNGPhysicalBoxFragment(fragment.get()); CopyFragmentDataToLayoutBox(*constraint_space); - return fragment_; + return layout_result_; } MinAndMaxContentSizes NGBlockNode::ComputeMinAndMaxContentSizes() { @@ -127,9 +127,11 @@ return *maybe_sizes; // Have to synthesize this value. - RefPtr<NGPhysicalFragment> physical_fragment = Layout(constraint_space); + RefPtr<NGLayoutResult> layout_result = Layout(constraint_space); + NGPhysicalFragment* physical_fragment = + layout_result->PhysicalFragment().get(); NGBoxFragment min_fragment(FromPlatformWritingMode(Style().getWritingMode()), - toNGPhysicalBoxFragment(physical_fragment.get())); + toNGPhysicalBoxFragment(physical_fragment)); sizes.min_content = min_fragment.InlineOverflow(); // Now, redo with infinite space for max_content @@ -141,9 +143,10 @@ .SetPercentageResolutionSize({LayoutUnit(), LayoutUnit()}) .ToConstraintSpace(FromPlatformWritingMode(Style().getWritingMode())); - physical_fragment = Layout(constraint_space); + layout_result = Layout(constraint_space); + physical_fragment = layout_result->PhysicalFragment().get(); NGBoxFragment max_fragment(FromPlatformWritingMode(Style().getWritingMode()), - toNGPhysicalBoxFragment(physical_fragment.get())); + toNGPhysicalBoxFragment(physical_fragment)); sizes.max_content = max_fragment.InlineOverflow(); return sizes; } @@ -196,7 +199,8 @@ } NGBreakToken* NGBlockNode::CurrentBreakToken() const { - return fragment_ ? fragment_->BreakToken() : nullptr; + return layout_result_ ? layout_result_->PhysicalFragment()->BreakToken() + : nullptr; } DEFINE_TRACE(NGBlockNode) { @@ -237,20 +241,23 @@ if (!layout_box_) return; - layout_box_->setWidth(fragment_->Width()); - layout_box_->setHeight(fragment_->Height()); + NGPhysicalBoxFragment* fragment = + toNGPhysicalBoxFragment(layout_result_->PhysicalFragment().get()); + + layout_box_->setWidth(fragment->Width()); + layout_box_->setHeight(fragment->Height()); NGBoxStrut border_and_padding = ComputeBorders(Style()) + ComputePadding(constraint_space, Style()); LayoutUnit intrinsic_logical_height = layout_box_->style()->isHorizontalWritingMode() - ? fragment_->HeightOverflow() - : fragment_->WidthOverflow(); + ? fragment->HeightOverflow() + : fragment->WidthOverflow(); intrinsic_logical_height -= border_and_padding.BlockSum(); layout_box_->setIntrinsicContentLogicalHeight(intrinsic_logical_height); // We may still have unpositioned floats when we reach the root box. if (!layout_box_->parent()) { - for (const auto& floating_object : fragment_->PositionedFloats()) { + for (const auto& floating_object : fragment->PositionedFloats()) { FloatingObjectPositionedUpdated(floating_object, layout_box_); } } @@ -269,12 +276,14 @@ // Ensure the position of the children are copied across to the // LayoutObject tree. } else { - for (const auto& child_fragment : fragment_->Children()) { + for (const auto& child_fragment : fragment->Children()) { if (child_fragment->IsPlaced()) FragmentPositionUpdated(toNGPhysicalBoxFragment(*child_fragment)); - for (const auto& floating_object : child_fragment->PositionedFloats()) { - FloatingObjectPositionedUpdated(floating_object, layout_box_); + for (const auto& floating_object : + toNGPhysicalBoxFragment(child_fragment.get())->PositionedFloats()) { + FloatingObjectPositionedUpdated( + floating_object, toLayoutBox(child_fragment->GetLayoutObject())); } } } @@ -287,7 +296,7 @@ } } -RefPtr<NGPhysicalBoxFragment> NGBlockNode::RunOldLayout( +RefPtr<NGLayoutResult> NGBlockNode::RunOldLayout( const NGConstraintSpace& constraint_space) { NGLogicalSize available_size = constraint_space.PercentageResolutionSize(); LayoutObject* containing_block = layout_box_->containingBlock();
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_node.h b/third_party/WebKit/Source/core/layout/ng/ng_block_node.h index c25506c..1893195 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_block_node.h +++ b/third_party/WebKit/Source/core/layout/ng/ng_block_node.h
@@ -8,6 +8,7 @@ #include "core/CoreExport.h" #include "core/layout/LayoutBox.h" #include "core/layout/ng/ng_layout_input_node.h" +#include "core/layout/ng/ng_layout_result.h" #include "core/layout/ng/ng_physical_box_fragment.h" #include "platform/heap/Handle.h" @@ -17,8 +18,8 @@ class LayoutObject; class NGBreakToken; class NGConstraintSpace; +class NGLayoutResult; struct NGLogicalOffset; -class NGPhysicalFragment; struct MinAndMaxContentSizes; // Represents a node to be laid out. @@ -33,8 +34,7 @@ ~NGBlockNode() override; - RefPtr<NGPhysicalFragment> Layout( - NGConstraintSpace* constraint_space) override; + RefPtr<NGLayoutResult> Layout(NGConstraintSpace* constraint_space) override; NGLayoutInputNode* NextSibling() override; LayoutObject* GetLayoutObject() override; @@ -53,17 +53,16 @@ void SetNextSibling(NGLayoutInputNode*); void SetFirstChild(NGLayoutInputNode*); - void SetFragment(NGPhysicalBoxFragment* fragment) { fragment_ = fragment; } NGBreakToken* CurrentBreakToken() const; bool IsLayoutFinished() const { - return fragment_ && !fragment_->BreakToken(); + return layout_result_ && !layout_result_->PhysicalFragment()->BreakToken(); } DECLARE_VIRTUAL_TRACE(); // Runs layout on layout_box_ and creates a fragment for the resulting // geometry. - RefPtr<NGPhysicalBoxFragment> RunOldLayout(const NGConstraintSpace&); + RefPtr<NGLayoutResult> RunOldLayout(const NGConstraintSpace&); // Called if this is an out-of-flow block which needs to be // positioned with legacy layout. @@ -87,9 +86,9 @@ Member<NGLayoutInputNode> next_sibling_; Member<NGLayoutInputNode> first_child_; // TODO(mstensho): An input node may produce multiple fragments, so this - // should probably be renamed to last_fragment_ or something like that, since + // should probably be renamed to last_result_ or something like that, since // the last fragment is all we care about when resuming layout. - RefPtr<NGPhysicalBoxFragment> fragment_; + RefPtr<NGLayoutResult> layout_result_; }; DEFINE_TYPE_CASTS(NGBlockNode,
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_floating_object.h b/third_party/WebKit/Source/core/layout/ng/ng_floating_object.h index d55ea63a..0792952 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_floating_object.h +++ b/third_party/WebKit/Source/core/layout/ng/ng_floating_object.h
@@ -27,7 +27,7 @@ const NGBoxStrut& margins) : fragment(fragment), space(space), - parent_space(parent_space), + original_parent_space(parent_space), node(node), margins(margins) { exclusion_type = NGExclusion::kFloatLeft; @@ -42,7 +42,7 @@ // Parent space is used so we can calculate the inline offset relative to // the original parent of this float. - Member<const NGConstraintSpace> parent_space; + Member<const NGConstraintSpace> original_parent_space; Member<NGBlockNode> node; NGExclusion::Type exclusion_type; EClear clear_type; @@ -59,7 +59,7 @@ DEFINE_INLINE_TRACE() { visitor->trace(space); - visitor->trace(parent_space); + visitor->trace(original_parent_space); visitor->trace(node); } };
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.cc b/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.cc index 4b69057..eb08d9a 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.cc
@@ -52,7 +52,7 @@ } NGFragmentBuilder& NGFragmentBuilder::AddChild( - RefPtr<NGPhysicalFragment> child, + RefPtr<NGLayoutResult> child, const NGLogicalOffset& child_offset) { DCHECK_EQ(type_, NGPhysicalFragment::kFragmentBox) << "Only box fragments can have children"; @@ -67,6 +67,15 @@ OutOfFlowPlacement{child_offset, oof_position}); } + return AddChild(child->PhysicalFragment(), child_offset); +} + +NGFragmentBuilder& NGFragmentBuilder::AddChild( + RefPtr<NGPhysicalFragment> child, + const NGLogicalOffset& child_offset) { + DCHECK_EQ(type_, NGPhysicalFragment::kFragmentBox) + << "Only box fragments can have children"; + children_.push_back(std::move(child)); offsets_.push_back(child_offset); @@ -143,7 +152,7 @@ return *this; } -RefPtr<NGPhysicalBoxFragment> NGFragmentBuilder::ToBoxFragment() { +RefPtr<NGLayoutResult> NGFragmentBuilder::ToBoxFragment() { // TODO(layout-ng): Support text fragments DCHECK_EQ(type_, NGPhysicalFragment::kFragmentBox); DCHECK_EQ(offsets_.size(), children_.size()); @@ -170,11 +179,14 @@ positioned_floats.push_back(floating_object); } - return adoptRef(new NGPhysicalBoxFragment( + RefPtr<NGPhysicalBoxFragment> fragment = adoptRef(new NGPhysicalBoxFragment( node_->GetLayoutObject(), physical_size, - overflow_.ConvertToPhysical(writing_mode_), children_, - out_of_flow_descendants_, out_of_flow_positions_, unpositioned_floats_, - positioned_floats_, bfc_offset_, end_margin_strut_, break_token)); + overflow_.ConvertToPhysical(writing_mode_), children_, positioned_floats_, + bfc_offset_, end_margin_strut_, break_token)); + + return adoptRef( + new NGLayoutResult(std::move(fragment), out_of_flow_descendants_, + out_of_flow_positions_, unpositioned_floats_)); } RefPtr<NGPhysicalTextFragment> NGFragmentBuilder::ToTextFragment( @@ -191,9 +203,7 @@ return adoptRef(new NGPhysicalTextFragment( node_->GetLayoutObject(), toNGInlineNode(node_), index, start_offset, end_offset, size_.ConvertToPhysical(writing_mode_), - overflow_.ConvertToPhysical(writing_mode_), out_of_flow_descendants_, - out_of_flow_positions_, empty_unpositioned_floats, - empty_positioned_floats)); + overflow_.ConvertToPhysical(writing_mode_))); } } // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.h b/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.h index 31926de8..7e9338c 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.h +++ b/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.h
@@ -13,7 +13,7 @@ namespace blink { -class NGPhysicalBoxFragment; +class NGLayoutResult; class NGPhysicalTextFragment; class CORE_EXPORT NGFragmentBuilder final { @@ -32,6 +32,7 @@ NGFragmentBuilder& SetInlineOverflow(LayoutUnit); NGFragmentBuilder& SetBlockOverflow(LayoutUnit); + NGFragmentBuilder& AddChild(RefPtr<NGLayoutResult>, const NGLogicalOffset&); NGFragmentBuilder& AddChild(RefPtr<NGPhysicalFragment>, const NGLogicalOffset&); NGFragmentBuilder& AddFloatingObject(NGFloatingObject*, @@ -89,7 +90,7 @@ // do not provide a setter here. // Creates the fragment. Can only be called once. - RefPtr<NGPhysicalBoxFragment> ToBoxFragment(); + RefPtr<NGLayoutResult> ToBoxFragment(); RefPtr<NGPhysicalTextFragment> ToTextFragment(unsigned index, unsigned start_offset, unsigned end_offset);
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_inline_node.cc b/third_party/WebKit/Source/core/layout/ng/ng_inline_node.cc index 017ffc4..9fa7c643 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_inline_node.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_inline_node.cc
@@ -241,7 +241,7 @@ } } -RefPtr<NGPhysicalFragment> NGInlineNode::Layout(NGConstraintSpace*) { +RefPtr<NGLayoutResult> NGInlineNode::Layout(NGConstraintSpace*) { ASSERT_NOT_REACHED(); return nullptr; }
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_inline_node.h b/third_party/WebKit/Source/core/layout/ng/ng_inline_node.h index 023f36cc..392ddc2 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_inline_node.h +++ b/third_party/WebKit/Source/core/layout/ng/ng_inline_node.h
@@ -26,8 +26,8 @@ class NGLayoutInlineItem; class NGLayoutInlineItemRange; class NGLayoutInlineItemsBuilder; +class NGLayoutResult; class NGLineBuilder; -class NGPhysicalFragment; // Represents an inline node to be laid out. class CORE_EXPORT NGInlineNode : public NGLayoutInputNode { @@ -37,7 +37,7 @@ const ComputedStyle* BlockStyle() const { return block_style_.get(); } - RefPtr<NGPhysicalFragment> Layout(NGConstraintSpace*) override; + RefPtr<NGLayoutResult> Layout(NGConstraintSpace*) override; void LayoutInline(NGConstraintSpace*, NGLineBuilder*); NGInlineNode* NextSibling() override; LayoutObject* GetLayoutObject() override;
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_inline_node_test.cc b/third_party/WebKit/Source/core/layout/ng/ng_inline_node_test.cc index 874ce41..2568b2c 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_inline_node_test.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_inline_node_test.cc
@@ -75,8 +75,10 @@ NGFragmentBuilder fragment_builder(NGPhysicalFragment::kFragmentBox, node); line_builder.CreateFragments(&fragment_builder); - RefPtr<NGPhysicalBoxFragment> fragment = fragment_builder.ToBoxFragment(); - for (const auto& child : fragment->Children()) { + RefPtr<NGLayoutResult> result = fragment_builder.ToBoxFragment(); + for (const auto& child : + toNGPhysicalBoxFragment(result->PhysicalFragment().get()) + ->Children()) { fragments_out->push_back(toNGPhysicalTextFragment(child.get())); } }
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_layout_algorithm.h b/third_party/WebKit/Source/core/layout/ng/ng_layout_algorithm.h index 99b8da2..bc2250c 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_layout_algorithm.h +++ b/third_party/WebKit/Source/core/layout/ng/ng_layout_algorithm.h
@@ -14,7 +14,7 @@ namespace blink { struct MinAndMaxContentSizes; -class NGPhysicalFragment; +class NGLayoutResult; // Base class for all LayoutNG algorithms. class CORE_EXPORT NGLayoutAlgorithm { @@ -24,10 +24,10 @@ virtual ~NGLayoutAlgorithm() {} // Actual layout function. Lays out the children and descendents within the - // constraints given by the NGConstraintSpace. Returns a fragment with the - // resulting layout information. + // constraints given by the NGConstraintSpace. Returns a layout result with + // the resulting layout information. // TODO(layout-dev): attempt to make this function const. - virtual RefPtr<NGPhysicalFragment> Layout() = 0; + virtual RefPtr<NGLayoutResult> Layout() = 0; // Computes the min-content and max-content intrinsic sizes for the given box. // The result will not take any min-width, max-width or width properties into
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_layout_input_node.h b/third_party/WebKit/Source/core/layout/ng/ng_layout_input_node.h index ed282c81..0c36cde 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_layout_input_node.h +++ b/third_party/WebKit/Source/core/layout/ng/ng_layout_input_node.h
@@ -12,7 +12,7 @@ class LayoutObject; class NGConstraintSpace; -class NGPhysicalFragment; +class NGLayoutResult; // Represents the input to a layout algorithm for a given node. The layout // engine should use the style, node type to determine which type of layout @@ -24,8 +24,8 @@ virtual ~NGLayoutInputNode(){}; - // Performs layout on this input node, will return a new fragment. - virtual RefPtr<NGPhysicalFragment> Layout(NGConstraintSpace*) = 0; + // Performs layout on this input node, will return the layout result. + virtual RefPtr<NGLayoutResult> Layout(NGConstraintSpace*) = 0; // Returns the next sibling. virtual NGLayoutInputNode* NextSibling() = 0;
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_layout_result.cc b/third_party/WebKit/Source/core/layout/ng/ng_layout_result.cc new file mode 100644 index 0000000..5a45423 --- /dev/null +++ b/third_party/WebKit/Source/core/layout/ng/ng_layout_result.cc
@@ -0,0 +1,22 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "core/layout/ng/ng_layout_result.h" + +#include "core/layout/ng/ng_floating_object.h" + +namespace blink { + +NGLayoutResult::NGLayoutResult( + PassRefPtr<NGPhysicalFragment> physical_fragment, + PersistentHeapLinkedHashSet<WeakMember<NGBlockNode>>& + out_of_flow_descendants, + Vector<NGStaticPosition> out_of_flow_positions, + Vector<Persistent<NGFloatingObject>>& unpositioned_floats) + : physical_fragment_(physical_fragment), + out_of_flow_descendants_(out_of_flow_descendants), + out_of_flow_positions_(out_of_flow_positions), + unpositioned_floats_(unpositioned_floats) {} + +} // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_layout_result.h b/third_party/WebKit/Source/core/layout/ng/ng_layout_result.h new file mode 100644 index 0000000..49d206a --- /dev/null +++ b/third_party/WebKit/Source/core/layout/ng/ng_layout_result.h
@@ -0,0 +1,73 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef NGLayoutResult_h +#define NGLayoutResult_h + +#include "core/CoreExport.h" +#include "core/layout/ng/ng_physical_fragment.h" +#include "core/layout/ng/ng_units.h" +#include "platform/LayoutUnit.h" +#include "platform/heap/Handle.h" +#include "wtf/Vector.h" + +namespace blink { + +class LayoutObject; +class NGPhysicalFragment; +class NGBlockNode; +struct NGFloatingObject; + +// The NGLayoutResult stores the resulting data from layout. This includes +// geometry information in form of a NGPhysicalFragment, which is kept around +// for painting, hit testing, etc., as well as additional data which is only +// necessary during layout and stored on this object. +// Layout code should access the NGPhysicalFragment through the wrappers in +// NGFragment et al. +class CORE_EXPORT NGLayoutResult : public RefCounted<NGLayoutResult> { + public: + RefPtr<NGPhysicalFragment> PhysicalFragment() const { + return physical_fragment_; + } + + const HeapLinkedHashSet<WeakMember<NGBlockNode>>& OutOfFlowDescendants() + const { + return out_of_flow_descendants_; + } + + const Vector<NGStaticPosition>& OutOfFlowPositions() const { + return out_of_flow_positions_; + } + + // List of floats that need to be positioned by the next in-flow child that + // can determine its position in space. + // Use case example where it may be needed: + // <div><float></div> + // <div style="margin-top: 10px; height: 20px"></div> + // The float cannot be positioned right away inside of the 1st div because + // the vertical position is not known at that moment. It will be known only + // after the 2nd div collapses its margin with its parent. + const Vector<Persistent<NGFloatingObject>>& UnpositionedFloats() const { + return unpositioned_floats_; + } + + private: + friend class NGFragmentBuilder; + + NGLayoutResult(PassRefPtr<NGPhysicalFragment> physical_fragment, + PersistentHeapLinkedHashSet<WeakMember<NGBlockNode>>& + out_of_flow_descendants, + Vector<NGStaticPosition> out_of_flow_positions, + Vector<Persistent<NGFloatingObject>>& unpositioned_floats); + + RefPtr<NGPhysicalFragment> physical_fragment_; + LayoutObject* layout_object_; + PersistentHeapLinkedHashSet<WeakMember<NGBlockNode>> out_of_flow_descendants_; + Vector<NGStaticPosition> out_of_flow_positions_; + Vector<Persistent<NGFloatingObject>> unpositioned_floats_; +}; + +} // namespace blink + +#endif // NGLayoutResult_h
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part.cc b/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part.cc index edf7f11..da091be 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part.cc
@@ -78,10 +78,10 @@ if (IsContainingBlockForAbsoluteDescendant(container_style_, descendant->Style())) { NGLogicalOffset offset; - RefPtr<NGPhysicalFragment> physical_fragment = + RefPtr<NGLayoutResult> result = LayoutDescendant(*descendant, static_position, &offset); // TODO(atotic) Need to adjust size of overflow rect per spec. - container_builder_->AddChild(std::move(physical_fragment), offset); + container_builder_->AddChild(std::move(result), offset); } else { container_builder_->AddOutOfFlowDescendant(descendant, static_position); } @@ -95,7 +95,7 @@ } } -RefPtr<NGPhysicalFragment> NGOutOfFlowLayoutPart::LayoutDescendant( +RefPtr<NGLayoutResult> NGOutOfFlowLayoutPart::LayoutDescendant( NGBlockNode& descendant, NGStaticPosition static_position, NGLogicalOffset* offset) { @@ -104,7 +104,7 @@ // relative to the container's padding box. static_position.offset -= container_border_physical_offset_; - RefPtr<NGPhysicalFragment> physical_fragment = nullptr; + RefPtr<NGLayoutResult> layout_result = nullptr; Optional<MinAndMaxContentSizes> inline_estimate; Optional<LayoutUnit> block_estimate; @@ -118,12 +118,12 @@ inline_estimate); if (AbsoluteNeedsChildBlockSize(descendant.Style())) { - physical_fragment = - GenerateFragment(descendant, block_estimate, node_position); + layout_result = GenerateFragment(descendant, block_estimate, node_position); // TODO(ikilpatrick): the writing mode switching here looks wrong. - NGBoxFragment fragment(container_space_->WritingMode(), - toNGPhysicalBoxFragment(physical_fragment.get())); + NGBoxFragment fragment( + container_space_->WritingMode(), + toNGPhysicalBoxFragment(layout_result->PhysicalFragment().get())); block_estimate = fragment.BlockSize(); } @@ -133,12 +133,11 @@ &node_position); // Skip this step if we produced a fragment when estimating the block size. - if (!physical_fragment) { + if (!layout_result) { block_estimate = node_position.size.ConvertToLogical(container_space_->WritingMode()) .block_size; - physical_fragment = - GenerateFragment(descendant, block_estimate, node_position); + layout_result = GenerateFragment(descendant, block_estimate, node_position); } // Compute logical offset, NGAbsolutePhysicalPosition is calculated relative @@ -150,10 +149,10 @@ offset->block_offset = inset.block_start + container_border_offset_.block_offset; - return physical_fragment; + return layout_result; } -RefPtr<NGPhysicalFragment> NGOutOfFlowLayoutPart::GenerateFragment( +RefPtr<NGLayoutResult> NGOutOfFlowLayoutPart::GenerateFragment( NGBlockNode& descendant, const Optional<LayoutUnit>& block_estimate, const NGAbsolutePhysicalPosition node_position) {
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part.h b/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part.h index daf91ef2..284f7b34 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part.h +++ b/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part.h
@@ -20,6 +20,7 @@ class NGBlockNode; class NGFragmentBuilder; class NGConstraintSpace; +class NGLayoutResult; // Helper class for positioning of out-of-flow blocks. // It should be used together with NGFragmentBuilder. @@ -34,11 +35,11 @@ void Run(); private: - RefPtr<NGPhysicalFragment> LayoutDescendant(NGBlockNode& descendant, - NGStaticPosition static_position, - NGLogicalOffset* offset); + RefPtr<NGLayoutResult> LayoutDescendant(NGBlockNode& descendant, + NGStaticPosition static_position, + NGLogicalOffset* offset); - RefPtr<NGPhysicalFragment> GenerateFragment( + RefPtr<NGLayoutResult> GenerateFragment( NGBlockNode& node, const Optional<LayoutUnit>& block_estimate, const NGAbsolutePhysicalPosition node_position);
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part_test.cc b/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part_test.cc index 1af3ab533..d4a1a11 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part_test.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part_test.cc
@@ -67,8 +67,8 @@ NGConstraintSpace* space = NGConstraintSpace::CreateFromLayoutObject(*block_flow); NGBlockNode* node = new NGBlockNode(block_flow); - RefPtr<NGPhysicalFragment> fragment = node->Layout(space); - EXPECT_EQ(fragment->OutOfFlowDescendants().size(), (size_t)2); + RefPtr<NGLayoutResult> result = node->Layout(space); + EXPECT_EQ(result->OutOfFlowDescendants().size(), (size_t)2); // Test the final result. Element* fixed_1 = document().getElementById("fixed1");
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_physical_box_fragment.cc b/third_party/WebKit/Source/core/layout/ng/ng_physical_box_fragment.cc index ad9d2fcd..04d247bf 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_physical_box_fragment.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_physical_box_fragment.cc
@@ -4,6 +4,8 @@ #include "core/layout/ng/ng_physical_box_fragment.h" +#include "core/layout/ng/ng_floating_object.h" + namespace blink { NGPhysicalBoxFragment::NGPhysicalBoxFragment( @@ -11,10 +13,6 @@ NGPhysicalSize size, NGPhysicalSize overflow, Vector<RefPtr<NGPhysicalFragment>>& children, - PersistentHeapLinkedHashSet<WeakMember<NGBlockNode>>& - out_of_flow_descendants, - Vector<NGStaticPosition>& out_of_flow_positions, - Vector<Persistent<NGFloatingObject>>& unpositioned_floats, Vector<Persistent<NGFloatingObject>>& positioned_floats, const WTF::Optional<NGLogicalOffset>& bfc_offset, const NGMarginStrut& end_margin_strut, @@ -23,11 +21,8 @@ size, overflow, kFragmentBox, - out_of_flow_descendants, - out_of_flow_positions, - unpositioned_floats, - positioned_floats, break_token), + positioned_floats_(positioned_floats), bfc_offset_(bfc_offset), end_margin_strut_(end_margin_strut) { children_.swap(children);
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_physical_box_fragment.h b/third_party/WebKit/Source/core/layout/ng/ng_physical_box_fragment.h index 5326966..1a259c1a 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_physical_box_fragment.h +++ b/third_party/WebKit/Source/core/layout/ng/ng_physical_box_fragment.h
@@ -13,7 +13,6 @@ namespace blink { -class NGBlockNode; struct NGFloatingObject; class CORE_EXPORT NGPhysicalBoxFragment final : public NGPhysicalFragment { @@ -24,10 +23,6 @@ NGPhysicalSize size, NGPhysicalSize overflow, Vector<RefPtr<NGPhysicalFragment>>& children, - PersistentHeapLinkedHashSet<WeakMember<NGBlockNode>>& - out_of_flow_descendants, - Vector<NGStaticPosition>& out_of_flow_positions, - Vector<Persistent<NGFloatingObject>>& unpositioned_floats, Vector<Persistent<NGFloatingObject>>& positioned_floats, const WTF::Optional<NGLogicalOffset>& bfc_offset, const NGMarginStrut& end_margin_strut, @@ -37,6 +32,13 @@ return children_; } + // List of positioned float that need to be copied to the old layout tree. + // TODO(layout-ng): remove this once we change painting code to handle floats + // differently. + const Vector<Persistent<NGFloatingObject>>& PositionedFloats() const { + return positioned_floats_; + } + const WTF::Optional<NGLogicalOffset>& BfcOffset() const { return bfc_offset_; } @@ -45,6 +47,7 @@ private: Vector<RefPtr<NGPhysicalFragment>> children_; + Vector<Persistent<NGFloatingObject>> positioned_floats_; const WTF::Optional<NGLogicalOffset> bfc_offset_; const NGMarginStrut end_margin_strut_; };
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_physical_fragment.cc b/third_party/WebKit/Source/core/layout/ng/ng_physical_fragment.cc index b0491072..291a8f7 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_physical_fragment.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_physical_fragment.cc
@@ -10,28 +10,17 @@ namespace blink { -NGPhysicalFragment::NGPhysicalFragment( - LayoutObject* layout_object, - NGPhysicalSize size, - NGPhysicalSize overflow, - NGFragmentType type, - PersistentHeapLinkedHashSet<WeakMember<NGBlockNode>>& - out_of_flow_descendants, - Vector<NGStaticPosition> out_of_flow_positions, - Vector<Persistent<NGFloatingObject>>& unpositioned_floats, - Vector<Persistent<NGFloatingObject>>& positioned_floats, - NGBreakToken* break_token) +NGPhysicalFragment::NGPhysicalFragment(LayoutObject* layout_object, + NGPhysicalSize size, + NGPhysicalSize overflow, + NGFragmentType type, + NGBreakToken* break_token) : layout_object_(layout_object), size_(size), overflow_(overflow), break_token_(break_token), type_(type), - is_placed_(false) { - out_of_flow_descendants_.swap(out_of_flow_descendants); - out_of_flow_positions_.swap(out_of_flow_positions); - unpositioned_floats_.swap(unpositioned_floats); - positioned_floats_.swap(positioned_floats); -} + is_placed_(false) {} void NGPhysicalFragment::destroy() const { if (Type() == kFragmentText)
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_physical_fragment.h b/third_party/WebKit/Source/core/layout/ng/ng_physical_fragment.h index 2ccd3e5..2d014c50 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_physical_fragment.h +++ b/third_party/WebKit/Source/core/layout/ng/ng_physical_fragment.h
@@ -14,11 +14,9 @@ namespace blink { class LayoutObject; -class NGBlockNode; class NGBreakToken; -struct NGFloatingObject; -// The NGPhysicalFragment contains the output information from layout. The +// The NGPhysicalFragment contains the output geometry from layout. The // fragment stores all of its information in the physical coordinate system for // use by paint, hit-testing etc. // @@ -26,8 +24,8 @@ // Once we have transitioned fully to LayoutNG it should be a const pointer // such that paint/hit-testing/etc don't modify it. // -// Layout code should only access output layout information through the -// NGFragmentBase classes which transforms information into the logical +// Layout code should only access geometry information through the +// NGFragment wrapper classes which transforms information into the logical // coordinate system. class CORE_EXPORT NGPhysicalFragment : public RefCounted<NGPhysicalFragment> { public: @@ -82,46 +80,13 @@ LayoutObject* GetLayoutObject() const { return layout_object_; } - const HeapLinkedHashSet<WeakMember<NGBlockNode>>& OutOfFlowDescendants() - const { - return out_of_flow_descendants_; - } - - const Vector<NGStaticPosition>& OutOfFlowPositions() const { - return out_of_flow_positions_; - } - bool IsPlaced() const { return is_placed_; } - // List of floats that need to be positioned by the next in-flow child that - // can determine its position in space. - // Use case example where it may be needed: - // <div><float></div> - // <div style="margin-top: 10px; height: 20px"></div> - // The float cannot be positioned right away inside of the 1st div because - // the vertical position is not known at that moment. It will be known only - // after the 2nd div collapses its margin with its parent. - const Vector<Persistent<NGFloatingObject>>& UnpositionedFloats() const { - return unpositioned_floats_; - } - - // List of positioned float that need to be copied to the old layout tree. - // TODO(layout-ng): remove this once we change painting code to handle floats - // differently. - const Vector<Persistent<NGFloatingObject>>& PositionedFloats() const { - return positioned_floats_; - } - protected: NGPhysicalFragment(LayoutObject* layout_object, NGPhysicalSize size, NGPhysicalSize overflow, NGFragmentType type, - PersistentHeapLinkedHashSet<WeakMember<NGBlockNode>>& - out_of_flow_descendants, - Vector<NGStaticPosition> out_of_flow_positions, - Vector<Persistent<NGFloatingObject>>& unpositioned_floats, - Vector<Persistent<NGFloatingObject>>& positioned_floats, NGBreakToken* break_token = nullptr); LayoutObject* layout_object_; @@ -129,10 +94,6 @@ NGPhysicalSize overflow_; NGPhysicalOffset offset_; Persistent<NGBreakToken> break_token_; - PersistentHeapLinkedHashSet<WeakMember<NGBlockNode>> out_of_flow_descendants_; - Vector<NGStaticPosition> out_of_flow_positions_; - Vector<Persistent<NGFloatingObject>> unpositioned_floats_; - Vector<Persistent<NGFloatingObject>> positioned_floats_; unsigned type_ : 1; unsigned is_placed_ : 1;
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_physical_text_fragment.h b/third_party/WebKit/Source/core/layout/ng/ng_physical_text_fragment.h index bb33b0f1..ad9540e 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_physical_text_fragment.h +++ b/third_party/WebKit/Source/core/layout/ng/ng_physical_text_fragment.h
@@ -16,27 +16,14 @@ class CORE_EXPORT NGPhysicalTextFragment final : public NGPhysicalFragment { public: - NGPhysicalTextFragment( - LayoutObject* layout_object, - const NGInlineNode* node, - unsigned item_index, - unsigned start_offset, - unsigned end_offset, - NGPhysicalSize size, - NGPhysicalSize overflow, - PersistentHeapLinkedHashSet<WeakMember<NGBlockNode>>& - out_of_flow_descendants, - Vector<NGStaticPosition> out_of_flow_positions, - Vector<Persistent<NGFloatingObject>>& unpositioned_floats, - Vector<Persistent<NGFloatingObject>>& positioned_floats) - : NGPhysicalFragment(layout_object, - size, - overflow, - kFragmentText, - out_of_flow_descendants, - out_of_flow_positions, - unpositioned_floats, - positioned_floats), + NGPhysicalTextFragment(LayoutObject* layout_object, + const NGInlineNode* node, + unsigned item_index, + unsigned start_offset, + unsigned end_offset, + NGPhysicalSize size, + NGPhysicalSize overflow) + : NGPhysicalFragment(layout_object, size, overflow, kFragmentText), node_(node), item_index_(item_index), start_offset_(start_offset),
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_text_layout_algorithm.cc b/third_party/WebKit/Source/core/layout/ng/ng_text_layout_algorithm.cc index 1f1e593..ab37fec 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_text_layout_algorithm.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_text_layout_algorithm.cc
@@ -26,7 +26,7 @@ DCHECK(inline_box_); } -RefPtr<NGPhysicalFragment> NGTextLayoutAlgorithm::Layout() { +RefPtr<NGLayoutResult> NGTextLayoutAlgorithm::Layout() { ASSERT_NOT_REACHED(); return nullptr; }
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_text_layout_algorithm.h b/third_party/WebKit/Source/core/layout/ng/ng_text_layout_algorithm.h index fec586d21..7107769 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_text_layout_algorithm.h +++ b/third_party/WebKit/Source/core/layout/ng/ng_text_layout_algorithm.h
@@ -32,7 +32,7 @@ NGConstraintSpace* space, NGBreakToken* break_token = nullptr); - RefPtr<NGPhysicalFragment> Layout() override; + RefPtr<NGLayoutResult> Layout() override; void LayoutInline(NGLineBuilder*); private:
diff --git a/third_party/WebKit/Source/core/paint/BoxPaintInvalidator.cpp b/third_party/WebKit/Source/core/paint/BoxPaintInvalidator.cpp index 23d2efb..a7c502c1 100644 --- a/third_party/WebKit/Source/core/paint/BoxPaintInvalidator.cpp +++ b/third_party/WebKit/Source/core/paint/BoxPaintInvalidator.cpp
@@ -117,8 +117,7 @@ const ComputedStyle& style = m_box.styleRef(); if ((style.backgroundLayers().thisOrNextLayersUseContentBox() || - style.maskLayers().thisOrNextLayersUseContentBox() || - style.boxSizing() == EBoxSizing::kBorderBox) && + style.maskLayers().thisOrNextLayersUseContentBox()) && previousContentBoxRect() != m_box.contentBoxRect()) return PaintInvalidationContentBoxChange; @@ -319,11 +318,6 @@ const ComputedStyle& style = m_box.styleRef(); - // If we use border-box sizing we need to track changes in the size of the - // content box. - if (style.boxSizing() == EBoxSizing::kBorderBox) - return true; - // Background and mask layers can depend on other boxes than border box. See // crbug.com/490533 if (style.backgroundLayers().thisOrNextLayersUseContentBox() ||
diff --git a/third_party/WebKit/Source/core/style/ComputedStyle.cpp b/third_party/WebKit/Source/core/style/ComputedStyle.cpp index e4544c51..4318b01 100644 --- a/third_party/WebKit/Source/core/style/ComputedStyle.cpp +++ b/third_party/WebKit/Source/core/style/ComputedStyle.cpp
@@ -640,6 +640,9 @@ borderBottomWidth() != other.borderBottomWidth() || borderRightWidth() != other.borderRightWidth()) return true; + + if (m_surround->padding != other.m_surround->padding) + return true; } if (m_rareNonInheritedData.get() != other.m_rareNonInheritedData.get()) { @@ -884,11 +887,6 @@ position() != other.position()) return true; - if (m_surround.get() != other.m_surround.get()) { - if (m_surround->padding != other.m_surround->padding) - return true; - } - if (m_rareNonInheritedData.get() != other.m_rareNonInheritedData.get()) { if (m_rareNonInheritedData->m_alignContent != other.m_rareNonInheritedData->m_alignContent ||
diff --git a/third_party/WebKit/Source/core/svg/SVGElement.cpp b/third_party/WebKit/Source/core/svg/SVGElement.cpp index 20449ab..b1890ab 100644 --- a/third_party/WebKit/Source/core/svg/SVGElement.cpp +++ b/third_party/WebKit/Source/core/svg/SVGElement.cpp
@@ -111,36 +111,8 @@ void SVGElement::buildPendingResourcesIfNeeded() { if (!needsPendingResourceHandling() || !isConnected() || inUseShadowTree()) return; - - SVGTreeScopeResources& treeScopeResources = - treeScope().ensureSVGTreeScopedResources(); - AtomicString resourceId = getIdAttribute(); - if (!treeScopeResources.hasPendingResource(resourceId)) - return; - // Guaranteed by hasPendingResource. - DCHECK(!resourceId.isEmpty()); - - // Get pending elements for this id. - SVGTreeScopeResources::SVGPendingElements* pendingElements = - treeScopeResources.removePendingResource(resourceId); - if (!pendingElements || pendingElements->isEmpty()) - return; - - // Rebuild pending resources for each client of a pending resource that is - // being removed. - for (Element* clientElement : *pendingElements) { - DCHECK(clientElement->hasPendingResources()); - if (!clientElement->hasPendingResources()) - continue; - // TODO(fs): Ideally we'd always resolve pending resources async instead of - // inside insertedInto and svgAttributeChanged. For now we only do it for - // <use> since that would stamp out DOM. - if (isSVGUseElement(clientElement)) - toSVGUseElement(clientElement)->invalidateShadowTree(); - else - clientElement->buildPendingResource(); - treeScopeResources.clearHasPendingResourcesIfPossible(clientElement); - } + treeScope().ensureSVGTreeScopedResources().notifyResourceAvailable( + getIdAttribute()); } SVGElementRareData* SVGElement::ensureSVGRareData() {
diff --git a/third_party/WebKit/Source/core/svg/SVGTreeScopeResources.cpp b/third_party/WebKit/Source/core/svg/SVGTreeScopeResources.cpp index 4cb6f3c..9617851 100644 --- a/third_party/WebKit/Source/core/svg/SVGTreeScopeResources.cpp +++ b/third_party/WebKit/Source/core/svg/SVGTreeScopeResources.cpp
@@ -8,6 +8,7 @@ #include "core/dom/TreeScope.h" #include "core/layout/svg/LayoutSVGResourceContainer.h" #include "core/layout/svg/SVGResourcesCache.h" +#include "core/svg/SVGUseElement.h" #include "wtf/text/AtomicString.h" namespace blink { @@ -152,6 +153,31 @@ return m_pendingResources.take(id); } +void SVGTreeScopeResources::notifyResourceAvailable(const AtomicString& id) { + if (id.isEmpty()) + return; + // Get pending elements for this id. + SVGPendingElements* pendingElements = m_pendingResources.take(id); + if (!pendingElements) + return; + // Rebuild pending resources for each client of a pending resource that is + // being removed. + for (Element* clientElement : *pendingElements) { + DCHECK(clientElement->hasPendingResources()); + if (!clientElement->hasPendingResources()) + continue; + // TODO(fs): Ideally we'd always resolve pending resources async instead of + // inside insertedInto and svgAttributeChanged. For now we only do it for + // <use> since that would stamp out DOM. + if (isSVGUseElement(clientElement)) + toSVGUseElement(clientElement)->invalidateShadowTree(); + else + clientElement->buildPendingResource(); + + clearHasPendingResourcesIfPossible(clientElement); + } +} + DEFINE_TRACE(SVGTreeScopeResources) { visitor->trace(m_pendingResources); }
diff --git a/third_party/WebKit/Source/core/svg/SVGTreeScopeResources.h b/third_party/WebKit/Source/core/svg/SVGTreeScopeResources.h index 9529a4ad..c5a54a22 100644 --- a/third_party/WebKit/Source/core/svg/SVGTreeScopeResources.h +++ b/third_party/WebKit/Source/core/svg/SVGTreeScopeResources.h
@@ -41,6 +41,7 @@ bool hasPendingResource(const AtomicString& id) const; bool isElementPendingResources(Element*) const; bool isElementPendingResource(Element*, const AtomicString& id) const; + void notifyResourceAvailable(const AtomicString& id); void clearHasPendingResourcesIfPossible(Element*); void removeElementFromPendingResources(Element*); SVGPendingElements* removePendingResource(const AtomicString& id);
diff --git a/third_party/WebKit/Source/devtools/BUILD.gn b/third_party/WebKit/Source/devtools/BUILD.gn index 8f29630..c06c6405 100644 --- a/third_party/WebKit/Source/devtools/BUILD.gn +++ b/third_party/WebKit/Source/devtools/BUILD.gn
@@ -122,6 +122,7 @@ "front_end/components/DOMBreakpointsSidebarPane.js", "front_end/components/DOMPresentationUtils.js", "front_end/components/domUtils.css", + "front_end/components/imagePreview.css", "front_end/components/Linkifier.js", "front_end/components/module.json", "front_end/components/Reload.js", @@ -306,6 +307,7 @@ "front_end/network/networkPanel.css", "front_end/network/NetworkPanel.js", "front_end/network/NetworkTimeCalculator.js", + "front_end/network/networkTimingTable.css", "front_end/network/NetworkWaterfallColumn.js", "front_end/network/requestCookiesView.css", "front_end/network/RequestCookiesView.js", @@ -331,6 +333,7 @@ "front_end/object_ui/CustomPreviewComponent.js", "front_end/object_ui/JavaScriptAutocomplete.js", "front_end/object_ui/module.json", + "front_end/object_ui/objectPopover.css", "front_end/object_ui/ObjectPopoverHelper.js", "front_end/object_ui/objectPropertiesSection.css", "front_end/object_ui/ObjectPropertiesSection.js", @@ -490,6 +493,7 @@ "front_end/source_frame/FontView.js", "front_end/source_frame/imageView.css", "front_end/source_frame/ImageView.js", + "front_end/source_frame/messagesPopover.css", "front_end/source_frame/module.json", "front_end/source_frame/ResourceSourceFrame.js", "front_end/source_frame/SourceCodeDiff.js",
diff --git a/third_party/WebKit/Source/devtools/front_end/common/Settings.js b/third_party/WebKit/Source/devtools/front_end/common/Settings.js index 0c5f8d8..28a3087 100644 --- a/third_party/WebKit/Source/devtools/front_end/common/Settings.js +++ b/third_party/WebKit/Source/devtools/front_end/common/Settings.js
@@ -731,6 +731,13 @@ // This update is no-op. } + _updateVersionFrom23To24() { + var oldSetting = Common.settings.createSetting('searchInContentScripts', false); + var newSetting = Common.settings.createSetting('searchInAnonymousAndContentScripts', false); + newSetting.set(oldSetting.get()); + oldSetting.remove(); + } + _migrateSettingsFromLocalStorage() { // This step migrates all the settings except for the ones below into the browser profile. var localSettings = new Set([ @@ -763,7 +770,7 @@ }; Common.VersionController._currentVersionName = 'inspectorVersion'; -Common.VersionController.currentVersion = 23; +Common.VersionController.currentVersion = 24; /** * @type {!Common.Settings}
diff --git a/third_party/WebKit/Source/devtools/front_end/components/DOMPresentationUtils.js b/third_party/WebKit/Source/devtools/front_end/components/DOMPresentationUtils.js index 7eec38f..9e8c620 100644 --- a/third_party/WebKit/Source/devtools/front_end/components/DOMPresentationUtils.js +++ b/third_party/WebKit/Source/devtools/front_end/components/DOMPresentationUtils.js
@@ -189,6 +189,7 @@ function buildContent() { var container = createElement('table'); + UI.appendStyle(container, 'components/imagePreview.css'); container.className = 'image-preview-container'; var naturalWidth = precomputedFeatures ? precomputedFeatures.naturalWidth : imageElement.naturalWidth; var naturalHeight = precomputedFeatures ? precomputedFeatures.naturalHeight : imageElement.naturalHeight;
diff --git a/third_party/WebKit/Source/devtools/front_end/components/imagePreview.css b/third_party/WebKit/Source/devtools/front_end/components/imagePreview.css new file mode 100644 index 0000000..08020e5b --- /dev/null +++ b/third_party/WebKit/Source/devtools/front_end/components/imagePreview.css
@@ -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. + */ + +.image-preview-container { + background: transparent; + text-align: center; + border-spacing: 0; +} + +.image-preview-container img { + margin: 2px auto; + max-width: 100px; + max-height: 100px; + background-image: url(Images/checker.png); + -webkit-user-select: text; + -webkit-user-drag: auto; +} + +.image-container { + padding: 0; +}
diff --git a/third_party/WebKit/Source/devtools/front_end/components/module.json b/third_party/WebKit/Source/devtools/front_end/components/module.json index 4167aa2..8a494f5 100644 --- a/third_party/WebKit/Source/devtools/front_end/components/module.json +++ b/third_party/WebKit/Source/devtools/front_end/components/module.json
@@ -25,6 +25,7 @@ ], "resources": [ "breakpointsList.css", - "domUtils.css" + "domUtils.css", + "imagePreview.css" ] }
diff --git a/third_party/WebKit/Source/devtools/front_end/elements/elementsPanel.css b/third_party/WebKit/Source/devtools/front_end/elements/elementsPanel.css index f7a6eb5e..7d6a78c 100644 --- a/third_party/WebKit/Source/devtools/front_end/elements/elementsPanel.css +++ b/third_party/WebKit/Source/devtools/front_end/elements/elementsPanel.css
@@ -379,20 +379,6 @@ cursor: text; } -.image-preview-container { - background: transparent; - text-align: center; -} - -.image-preview-container img { - margin: 2px auto; - max-width: 100px; - max-height: 100px; - background-image: url(Images/checker.png); - -webkit-user-select: text; - -webkit-user-drag: auto; -} - .metrics { border-bottom: 1px solid #ccc; }
diff --git a/third_party/WebKit/Source/devtools/front_end/network/RequestTimingView.js b/third_party/WebKit/Source/devtools/front_end/network/RequestTimingView.js index f7e137f..fd29015 100644 --- a/third_party/WebKit/Source/devtools/front_end/network/RequestTimingView.js +++ b/third_party/WebKit/Source/devtools/front_end/network/RequestTimingView.js
@@ -180,6 +180,7 @@ */ static createTimingTable(request, calculator) { var tableElement = createElementWithClass('table', 'network-timing-table'); + UI.appendStyle(tableElement, 'network/networkTimingTable.css'); var colgroup = tableElement.createChild('colgroup'); colgroup.createChild('col', 'labels'); colgroup.createChild('col', 'bars'); @@ -212,10 +213,10 @@ if (rangeName === Network.RequestTimeRangeNames.Push) { createHeader(Common.UIString('Server Push')); } else if (rangeName === Network.RequestTimeRangeNames.Queueing) { - queueingHeader = tableElement.createChild('tr', 'network-timing-table-header'); - queueingHeader.createChild('td').createTextChild(Common.UIString('Resource Scheduling')); - queueingHeader.createChild('td').createTextChild(''); - queueingHeader.createChild('td').createTextChild(Common.UIString('TIME')); + queueingHeader = tableElement.createChild('tr', 'network-timing-table-header'); + queueingHeader.createChild('td').createTextChild(Common.UIString('Resource Scheduling')); + queueingHeader.createChild('td').createTextChild(''); + queueingHeader.createChild('td').createTextChild(Common.UIString('TIME')); } else if (Network.RequestTimingView.ConnectionSetupRangeNames.has(rangeName)) { if (!connectionHeader) connectionHeader = createHeader(Common.UIString('Connection Start')); @@ -339,6 +340,7 @@ this._tableElement.remove(); this._tableElement = Network.RequestTimingView.createTimingTable(this._request, this._calculator); + this._tableElement.classList.add('resource-timing-table'); this.element.appendChild(this._tableElement); } };
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 f58c2d8..9aa74b46 100644 --- a/third_party/WebKit/Source/devtools/front_end/network/module.json +++ b/third_party/WebKit/Source/devtools/front_end/network/module.json
@@ -144,6 +144,7 @@ "networkLogView.css", "networkManageCustomHeadersView.css", "networkPanel.css", + "networkTimingTable.css", "networkWaterfallColumn.css", "requestCookiesView.css", "requestHeadersTree.css",
diff --git a/third_party/WebKit/Source/devtools/front_end/network/networkPanel.css b/third_party/WebKit/Source/devtools/front_end/network/networkPanel.css index 03a4cbe1..80f149b 100644 --- a/third_party/WebKit/Source/devtools/front_end/network/networkPanel.css +++ b/third_party/WebKit/Source/devtools/front_end/network/networkPanel.css
@@ -56,144 +56,8 @@ color: rgb(30%, 30%, 30%); } -/* Network timing is shared between popover and network item view pane */ - -.network-timing-table { - width: 380px; - border-spacing: 0; - padding-left: 10px; - padding-right: 10px; - line-height: initial; -} - -.network-timing-start { - border-top: 5px solid transparent; -} -.network-timing-table-header td, .network-timing-footer td { - border-top: 10px solid transparent; -} - -.network-timing-table-header td { - color: #bbb; -} - -.network-timing-table-header td:last-child { - text-align: right; -} - -.network-timing-table col.labels { - width: 156px; -} - -.network-timing-table col.duration { - width: 80px; -} - -.network-timing-table td { - padding: 2px 0; -} - -.network-timing-table td.caution { - font-weight: bold; - color: rgb(255, 128, 0); - padding: 2px 0; -} - -.network-timing-table hr.break { - border: 0; - height: 1px; - background-image: linear-gradient(to right, #eee, #bbb, #eee); -} - -.network-timing-footer td:last-child { - font-weight: bold; - text-align: right; -} - -.network-timing-row { - position: relative; - height: 15px; -} - -.network-timing-bar { - position: absolute; - min-width: 1px; - top: 0; - bottom: 0; -} - -.network-timing-bar-title { - color: #222; - white-space: nowrap; - text-align: right; -} - -.network-timing-bar.queueing, -.network-timing-bar.total { - border: 1px solid rgba(0, 0, 0, 0.1); -} - -.network-timing-bar.blocking, -theme-preserve { - background-color: #AAAAAA; -} - -.network-timing-bar.proxy, -theme-preserve { - background-color: #A1887F; -} - -.network-timing-bar.dns, -theme-preserve { - background-color: #009688; -} - -.network-timing-bar.connecting, -.network-timing-bar.serviceworker, -.network-timing-bar.serviceworker-preparation, -theme-preserve { - background-color: #FF9800; -} - -.network-timing-bar.ssl, -theme-preserve { - background-color: #9C27B0; -} - -.network-timing-bar.sending, -theme-preserve { - background-color: #B0BEC5; -} - -.network-timing-bar.waiting, -theme-preserve { - background-color: #00C853; -} - -.network-timing-bar.receiving, -theme-preserve, -.network-timing-bar.receiving-push, -theme-preserve { - background-color: #03A9F4; -} - -.network-timing-bar.push, -theme-preserve { - background-color: #8CDBff; -} - -.network-timing-bar.server-timing, -theme-preserve { - background-color: #ddd; -} - -.network-timing-table td.network-timing-metric { - white-space: nowrap; - max-width: 150px; - overflow-x: hidden; - text-overflow: ellipsis; -} - -.network-timing-bar.proxy, -.network-timing-bar.dns, -.network-timing-bar.ssl, -.network-timing-bar.connecting, -.network-timing-bar.blocking { - height: 10px; - margin: auto; -} - -.resource-timing-view .network-timing-table { - width: 100%; +.resource-timing-table { + width: 100% !important; } #network-overview-panel {
diff --git a/third_party/WebKit/Source/devtools/front_end/network/networkTimingTable.css b/third_party/WebKit/Source/devtools/front_end/network/networkTimingTable.css new file mode 100644 index 0000000..a0a4c22 --- /dev/null +++ b/third_party/WebKit/Source/devtools/front_end/network/networkTimingTable.css
@@ -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. + */ + +.network-timing-table { + width: 380px; + border-spacing: 0; + padding-left: 10px; + padding-right: 10px; + line-height: initial; +} + +.network-timing-start { + border-top: 5px solid transparent; +} +.network-timing-table-header td, .network-timing-footer td { + border-top: 10px solid transparent; +} + +.network-timing-table-header td { + color: #bbb; +} + +.network-timing-table-header td:last-child { + text-align: right; +} + +.network-timing-table col.labels { + width: 156px; +} + +.network-timing-table col.duration { + width: 80px; +} + +.network-timing-table td { + padding: 2px 0; +} + +.network-timing-table td.caution { + font-weight: bold; + color: rgb(255, 128, 0); + padding: 2px 0; +} + +.network-timing-table hr.break { + border: 0; + height: 1px; + background-image: linear-gradient(to right, #eee, #bbb, #eee); +} + +.network-timing-footer td:last-child { + font-weight: bold; + text-align: right; +} + +.network-timing-row { + position: relative; + height: 15px; +} + +.network-timing-bar { + position: absolute; + min-width: 1px; + top: 0; + bottom: 0; +} + +.network-timing-bar-title { + color: #222; + white-space: nowrap; + text-align: right; +} + +.network-timing-bar.queueing, +.network-timing-bar.total { + border: 1px solid rgba(0, 0, 0, 0.1); +} + +.network-timing-bar.blocking, -theme-preserve { + background-color: #AAAAAA; +} + +.network-timing-bar.proxy, -theme-preserve { + background-color: #A1887F; +} + +.network-timing-bar.dns, -theme-preserve { + background-color: #009688; +} + +.network-timing-bar.connecting, +.network-timing-bar.serviceworker, +.network-timing-bar.serviceworker-preparation, -theme-preserve { + background-color: #FF9800; +} + +.network-timing-bar.ssl, -theme-preserve { + background-color: #9C27B0; +} + +.network-timing-bar.sending, -theme-preserve { + background-color: #B0BEC5; +} + +.network-timing-bar.waiting, -theme-preserve { + background-color: #00C853; +} + +.network-timing-bar.receiving, -theme-preserve, +.network-timing-bar.receiving-push, -theme-preserve { + background-color: #03A9F4; +} + +.network-timing-bar.push, -theme-preserve { + background-color: #8CDBff; +} + +.network-timing-bar.server-timing, -theme-preserve { + background-color: #ddd; +} + +.network-timing-table td.network-timing-metric { + white-space: nowrap; + max-width: 150px; + overflow-x: hidden; + text-overflow: ellipsis; +} + +.network-timing-bar.proxy, +.network-timing-bar.dns, +.network-timing-bar.ssl, +.network-timing-bar.connecting, +.network-timing-bar.blocking { + height: 10px; + margin: auto; +}
diff --git a/third_party/WebKit/Source/devtools/front_end/object_ui/ObjectPopoverHelper.js b/third_party/WebKit/Source/devtools/front_end/object_ui/ObjectPopoverHelper.js index 29773797..7617975 100644 --- a/third_party/WebKit/Source/devtools/front_end/object_ui/ObjectPopoverHelper.js +++ b/third_party/WebKit/Source/devtools/front_end/object_ui/ObjectPopoverHelper.js
@@ -128,6 +128,7 @@ if (result.type !== 'object') { popoverContentElement = createElement('span'); UI.appendStyle(popoverContentElement, 'object_ui/objectValue.css'); + UI.appendStyle(popoverContentElement, 'object_ui/objectPopover.css'); var valueElement = popoverContentElement.createChild('span', 'monospace object-value-' + result.type); valueElement.style.whiteSpace = 'pre'; @@ -155,10 +156,11 @@ popoverContentElement = customPreviewComponent.element; } else { popoverContentElement = createElement('div'); + UI.appendStyle(popoverContentElement, 'object_ui/objectPopover.css'); this._titleElement = popoverContentElement.createChild('div', 'monospace'); - this._titleElement.createChild('span', 'source-frame-popover-title').textContent = description; + this._titleElement.createChild('span', 'object-popover-title').textContent = description; var section = new ObjectUI.ObjectPropertiesSection(result, '', this._lazyLinkifier()); - section.element.classList.add('source-frame-popover-tree'); + section.element.classList.add('object-popover-tree'); section.titleLessMode(); popoverContentElement.appendChild(section.element); }
diff --git a/third_party/WebKit/Source/devtools/front_end/object_ui/module.json b/third_party/WebKit/Source/devtools/front_end/object_ui/module.json index e8c50c1d..b47310c 100644 --- a/third_party/WebKit/Source/devtools/front_end/object_ui/module.json +++ b/third_party/WebKit/Source/devtools/front_end/object_ui/module.json
@@ -13,8 +13,8 @@ ], "resources": [ "customPreviewComponent.css", - "objectValue.css", - "objectValue.css", - "objectPropertiesSection.css" + "objectPopover.css", + "objectPropertiesSection.css", + "objectValue.css" ] }
diff --git a/third_party/WebKit/Source/devtools/front_end/object_ui/objectPopover.css b/third_party/WebKit/Source/devtools/front_end/object_ui/objectPopover.css new file mode 100644 index 0000000..37f4c0e --- /dev/null +++ b/third_party/WebKit/Source/devtools/front_end/object_ui/objectPopover.css
@@ -0,0 +1,54 @@ +/* + * Copyright 2017 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +.object-popover-title { + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; + font-weight: bold; + padding-left: 18px; +} + +.object-popover-tree { + border-top: 1px solid rgb(184, 184, 184); + overflow: auto; + position: absolute; + top: 21px; + bottom: 5px; + left: 5px; + right: 5px; + margin-top: 1px; +} + +.object-popover-container { + display: inline-block; +} + +.function-popover-title { + border-bottom: 1px solid #AAA; + margin-bottom: 3px; + padding-bottom: 2px; + display: flex; + justify-content: space-between; + align-items: center; +} + +.function-popover-title .function-name { + font-weight: bold; +} + +.function-title-link-container { + display: flex; + align-items: center; + position: relative; + margin-left: 10px; +} + +.function-location-step-into { + position: relative; + height: 14px; + transform: rotate(-90deg); +}
diff --git a/third_party/WebKit/Source/devtools/front_end/profiler/HeapSnapshotView.js b/third_party/WebKit/Source/devtools/front_end/profiler/HeapSnapshotView.js index 8580781..b9aa382 100644 --- a/third_party/WebKit/Source/devtools/front_end/profiler/HeapSnapshotView.js +++ b/third_party/WebKit/Source/devtools/front_end/profiler/HeapSnapshotView.js
@@ -260,8 +260,6 @@ willHide() { this._currentSearchResultIndex = -1; this._popoverHelper.hidePopover(); - if (this.helpPopover && this.helpPopover.isShowing()) - this.helpPopover.hide(); } /** @@ -2000,7 +1998,7 @@ Profiler.HeapSnapshotStatisticsView = class extends UI.VBox { constructor() { super(); - this.setMinimumSize(50, 25); + this.element.classList.add('heap-snapshot-statistics-view'); this._pieChart = new PerfUI.PieChart(150, Profiler.HeapSnapshotStatisticsView._valueFormatter, true); this._pieChart.element.classList.add('heap-snapshot-stats-pie-chart'); this.element.appendChild(this._pieChart.element);
diff --git a/third_party/WebKit/Source/devtools/front_end/profiler/heapProfiler.css b/third_party/WebKit/Source/devtools/front_end/profiler/heapProfiler.css index 2280acf..b60620d 100644 --- a/third_party/WebKit/Source/devtools/front_end/profiler/heapProfiler.css +++ b/third_party/WebKit/Source/devtools/front_end/profiler/heapProfiler.css
@@ -138,12 +138,18 @@ bottom: 0; } +.heap-snapshot-statistics-view { + overflow: auto; +} + .heap-snapshot-stats-pie-chart { margin: 12px 30px; + flex-shrink: 0; } .heap-snapshot-stats-legend { margin-left: 24px; + flex-shrink: 0; } .heap-snapshot-stats-legend > div {
diff --git a/third_party/WebKit/Source/devtools/front_end/source_frame/UISourceCodeFrame.js b/third_party/WebKit/Source/devtools/front_end/source_frame/UISourceCodeFrame.js index 1046c64..c9f57c9 100644 --- a/third_party/WebKit/Source/devtools/front_end/source_frame/UISourceCodeFrame.js +++ b/third_party/WebKit/Source/devtools/front_end/source_frame/UISourceCodeFrame.js
@@ -494,9 +494,10 @@ this.element = createElementWithClass('div', 'text-editor-row-message'); this._icon = this.element.createChild('label', '', 'dt-icon-label'); this._icon.type = SourceFrame.UISourceCodeFrame._iconClassPerLevel[message.level()]; - this._repeatCountElement = this.element.createChild('label', 'message-repeat-count hidden', 'dt-small-bubble'); + this._repeatCountElement = + this.element.createChild('label', 'text-editor-row-message-repeat-count hidden', 'dt-small-bubble'); this._repeatCountElement.type = SourceFrame.UISourceCodeFrame._bubbleTypePerLevel[message.level()]; - var linesContainer = this.element.createChild('div', 'text-editor-row-message-lines'); + var linesContainer = this.element.createChild('div'); var lines = this._message.text().split('\n'); for (var i = 0; i < lines.length; ++i) { var messageLine = linesContainer.createChild('div'); @@ -579,6 +580,7 @@ */ messagesDescription() { this._messagesDescriptionElement.removeChildren(); + UI.appendStyle(this._messagesDescriptionElement, 'source_frame/messagesPopover.css'); for (var i = 0; i < this._messages.length; ++i) this._messagesDescriptionElement.appendChild(this._messages[i].element);
diff --git a/third_party/WebKit/Source/devtools/front_end/source_frame/messagesPopover.css b/third_party/WebKit/Source/devtools/front_end/source_frame/messagesPopover.css new file mode 100644 index 0000000..f083c46 --- /dev/null +++ b/third_party/WebKit/Source/devtools/front_end/source_frame/messagesPopover.css
@@ -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. + */ + +.text-editor-messages-description-container { + display: inline-block; +} + +.text-editor-row-message:first-child { + border-top-width: 0; +} + +.text-editor-row-message { + line-height: 1.2; + white-space: nowrap; + display: flex; + align-items: center; + justify-content: flex-start; + margin-top: 2px; +} + +.text-editor-row-message-repeat-count { + margin-right: 0.5em; +}
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 ca4f0e5..9d5e607a 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
@@ -49,6 +49,7 @@ ], "resources": [ "fontView.css", - "imageView.css" + "imageView.css", + "messagesPopover.css" ] }
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/AdvancedSearchView.js b/third_party/WebKit/Source/devtools/front_end/sources/AdvancedSearchView.js index bfc38df..513ca1c 100644 --- a/third_party/WebKit/Source/devtools/front_end/sources/AdvancedSearchView.js +++ b/third_party/WebKit/Source/devtools/front_end/sources/AdvancedSearchView.js
@@ -154,7 +154,7 @@ if (!searchResult.searchMatches.length) return; if (!this._searchResultsPane) - this._searchResultsPane = this._searchScope.createSearchResultsPane(this._searchConfig); + this._searchResultsPane = new Sources.FileBasedSearchResultsPane(this._searchConfig); this._resetResults(); this._searchResultsElement.appendChild(this._searchResultsPane.element); this._searchResultsPane.addSearchResult(searchResult); @@ -435,11 +435,5 @@ */ performIndexing(progress) {}, - stopSearch() {}, - - /** - * @param {!Workspace.ProjectSearchConfig} searchConfig - * @return {!Sources.SearchResultsPane} - */ - createSearchResultsPane(searchConfig) {} + stopSearch() {} };
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/NavigatorView.js b/third_party/WebKit/Source/devtools/front_end/sources/NavigatorView.js index 0a517f82..fc433ab 100644 --- a/third_party/WebKit/Source/devtools/front_end/sources/NavigatorView.js +++ b/third_party/WebKit/Source/devtools/front_end/sources/NavigatorView.js
@@ -317,10 +317,6 @@ _projectRemoved(event) { var project = /** @type {!Workspace.Project} */ (event.data); - var frame = Bindings.NetworkProject.frameForProject(project); - if (frame) - this._discardFrame(frame); - var uiSourceCodes = project.uiSourceCodes(); for (var i = 0; i < uiSourceCodes.length; ++i) this._removeUISourceCode(uiSourceCodes[i]); @@ -548,8 +544,10 @@ break; if (!(node instanceof Sources.NavigatorGroupTreeNode || node instanceof Sources.NavigatorFolderTreeNode)) break; - if (node._type === Sources.NavigatorView.Types.Frame) + if (node._type === Sources.NavigatorView.Types.Frame) { + this._discardFrame(/** @type {!SDK.ResourceTreeFrame} */ (frame)); break; + } var folderId = this._folderNodeId(project, target, frame, uiSourceCode.origin(), node._folderPath); this._subfolderNodes.delete(folderId);
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/SourcesSearchScope.js b/third_party/WebKit/Source/devtools/front_end/sources/SourcesSearchScope.js index 641d357..42ea08e 100644 --- a/third_party/WebKit/Source/devtools/front_end/sources/SourcesSearchScope.js +++ b/third_party/WebKit/Source/devtools/front_end/sources/SourcesSearchScope.js
@@ -74,24 +74,17 @@ * @return {!Array.<!Workspace.Project>} */ _projects() { - /** - * @param {!Workspace.Project} project - * @return {boolean} - */ - function filterOutServiceProjects(project) { - return project.type() !== Workspace.projectTypes.Service; - } + var searchInAnonymousAndContentScripts = Common.moduleSetting('searchInAnonymousAndContentScripts').get(); - /** - * @param {!Workspace.Project} project - * @return {boolean} - */ - function filterOutContentScriptsIfNeeded(project) { - return Common.moduleSetting('searchInContentScripts').get() || - project.type() !== Workspace.projectTypes.ContentScripts; - } - - return Workspace.workspace.projects().filter(filterOutServiceProjects).filter(filterOutContentScriptsIfNeeded); + return Workspace.workspace.projects().filter(project => { + if (project.type() === Workspace.projectTypes.Service) + return false; + if (!searchInAnonymousAndContentScripts && project.isServiceProject()) + return false; + if (!searchInAnonymousAndContentScripts && project.type() === Workspace.projectTypes.ContentScripts) + return false; + return true; + }); } /** @@ -283,13 +276,4 @@ stopSearch() { ++this._searchId; } - - /** - * @override - * @param {!Workspace.ProjectSearchConfig} searchConfig - * @return {!Sources.FileBasedSearchResultsPane} - */ - createSearchResultsPane(searchConfig) { - return new Sources.FileBasedSearchResultsPane(searchConfig); - } };
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/module.json b/third_party/WebKit/Source/devtools/front_end/sources/module.json index 64fc1ab..134d954ac 100644 --- a/third_party/WebKit/Source/devtools/front_end/sources/module.json +++ b/third_party/WebKit/Source/devtools/front_end/sources/module.json
@@ -375,8 +375,8 @@ { "type": "setting", "category": "Sources", - "title": "Search in content scripts", - "settingName": "searchInContentScripts", + "title": "Search in anonymous and content scripts", + "settingName": "searchInAnonymousAndContentScripts", "settingType": "boolean", "defaultValue": false },
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/sourcesPanel.css b/third_party/WebKit/Source/devtools/front_end/sources/sourcesPanel.css index e22f46b..17fd3c63 100644 --- a/third_party/WebKit/Source/devtools/front_end/sources/sourcesPanel.css +++ b/third_party/WebKit/Source/devtools/front_end/sources/sourcesPanel.css
@@ -55,41 +55,6 @@ height: 28px; } -.function-location-link { - float: right; - margin-left: 10px; -} - -.function-location-step-into { - position: relative; - height: 14px; - transform: rotate(-90deg); -} - -.object-popover-container { - display: inline-block; -} - -.function-popover-title { - border-bottom: 1px solid #AAA; - margin-bottom: 3px; - padding-bottom: 2px; - display: flex; - justify-content: space-between; - align-items: center; -} - -.function-title-link-container { - display: flex; - align-items: center; - position: relative; - margin-left: 10px; -} - -.function-popover-title .function-name { - font-weight: bold; -} - .panel.sources .sidebar-pane-stack { overflow: auto; }
diff --git a/third_party/WebKit/Source/devtools/front_end/text_editor/cmdevtools.css b/third_party/WebKit/Source/devtools/front_end/text_editor/cmdevtools.css index 6d76f00..73c39ff 100644 --- a/third_party/WebKit/Source/devtools/front_end/text_editor/cmdevtools.css +++ b/third_party/WebKit/Source/devtools/front_end/text_editor/cmdevtools.css
@@ -368,27 +368,6 @@ opacity: 0.5; } -.text-editor-messages-description-container { - display: inline-block; -} - -.text-editor-row-message:first-child { - border-top-width: 0; -} - -.text-editor-row-message { - border-top: 1px solid rgb(215, 215, 215); - line-height: 1.2; - white-space: nowrap; - display: flex; - align-items: center; - justify-content: flex-start; -} - -.text-editor-row-message .message-repeat-count { - margin-right: 0.5em; -} - .CodeMirror .text-editor-line-decoration-icon { position: absolute; cursor: pointer;
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineUIUtils.js b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineUIUtils.js index ee40700..c257246 100644 --- a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineUIUtils.js +++ b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineUIUtils.js
@@ -1403,6 +1403,7 @@ return; } var container = createElement('div'); + UI.appendStyle(container, 'components/imagePreview.css'); container.classList.add('image-preview-container', 'vbox', 'link'); var img = container.createChild('img'); img.src = imageURL;
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/timelinePanel.css b/third_party/WebKit/Source/devtools/front_end/timeline/timelinePanel.css index 5def207..8fbe22a 100644 --- a/third_party/WebKit/Source/devtools/front_end/timeline/timelinePanel.css +++ b/third_party/WebKit/Source/devtools/front_end/timeline/timelinePanel.css
@@ -284,25 +284,6 @@ line-height: 18px; } -.image-preview-container { - background: transparent; - text-align: left; - border-spacing: 0; - margin: 4px; -} - -.image-preview-container img { - max-width: 100px; - max-height: 100px; - background-image: url(Images/checker.png); - -webkit-user-select: text; - -webkit-user-drag: auto; -} - -.image-container { - padding: 0; -} - .timeline-filters-header { overflow: hidden; flex: none;
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline_model/TimelineModel.js b/third_party/WebKit/Source/devtools/front_end/timeline_model/TimelineModel.js index 05663d9b..b960a62 100644 --- a/third_party/WebKit/Source/devtools/front_end/timeline_model/TimelineModel.js +++ b/third_party/WebKit/Source/devtools/front_end/timeline_model/TimelineModel.js
@@ -122,15 +122,23 @@ /** * @param {!SDK.TracingModel.Event} event + * @param {string} field + * @return {string} + */ + static globalEventId(event, field) { + var data = event.args['data'] || event.args['beginData']; + var id = data && data[field]; + if (!id) + return ''; + return `${event.thread.process().id()}.${id}`; + } + + /** + * @param {!SDK.TracingModel.Event} event * @return {string} */ static eventFrameId(event) { - var data = event.args['data'] || event.args['beginData']; - var frame = data && data['frame']; - if (!frame) - return ''; - var processId = event.thread.process().id(); - return `${processId}.${frame}`; + return TimelineModel.TimelineModel.globalEventId(event, 'frame'); } /** @@ -1008,7 +1016,7 @@ var e = events[i]; if (!resourceTypes.has(e.name)) continue; - var id = e.args['data']['requestId']; + var id = TimelineModel.TimelineModel.globalEventId(e, 'requestId'); var request = requests.get(id); if (request) { request.addEvent(e); @@ -1709,15 +1717,20 @@ var initiatorInfo = TimelineModel.TimelineAsyncEventTracker._asyncEvents.get(initiatorType); if (!initiatorInfo) return; - var id = event.args['data'][initiatorInfo.joinBy]; + var id = TimelineModel.TimelineModel.globalEventId(event, initiatorInfo.joinBy); if (!id) return; /** @type {!Map<string, !SDK.TracingModel.Event>|undefined} */ var initiatorMap = this._initiatorByType.get(initiatorType); - if (isInitiator) + if (isInitiator) { initiatorMap.set(id, event); - else - TimelineModel.TimelineData.forEvent(event).setInitiator(initiatorMap.get(id) || null); + return; + } + var initiator = initiatorMap.get(id) || null; + var timelineData = TimelineModel.TimelineData.forEvent(event); + timelineData.setInitiator(initiator); + if (!timelineData.frameId && initiator) + timelineData.frameId = TimelineModel.TimelineModel.eventFrameId(initiator); } };
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/popover.css b/third_party/WebKit/Source/devtools/front_end/ui/popover.css index 82c82046..b060c7a 100644 --- a/third_party/WebKit/Source/devtools/front_end/ui/popover.css +++ b/third_party/WebKit/Source/devtools/front_end/ui/popover.css
@@ -67,22 +67,3 @@ margin-bottom: -19px; background-position: 0 -19px; } - -.source-frame-popover-title { - text-overflow: ellipsis; - overflow: hidden; - white-space: nowrap; - font-weight: bold; - padding-left: 18px; -} - -.source-frame-popover-tree { - border-top: 1px solid rgb(184, 184, 184); - overflow: auto; - position: absolute; - top: 21px; - bottom: 5px; - left: 5px; - right: 5px; - margin-top: 1px; -}
diff --git a/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.h b/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.h index 919bc97..5ee91880 100644 --- a/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.h +++ b/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.h
@@ -192,7 +192,7 @@ void resetUsageTracking(); - void incrementFrameCount() { m_usageCounters.numFramesSinceReset++; } + void finalizeFrame() override { m_usageCounters.numFramesSinceReset++; } bool isPaintable() const final { return hasImageBuffer(); }
diff --git a/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2DUsageTrackingTest.cpp b/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2DUsageTrackingTest.cpp index f4abf45..ea8e2a2 100644 --- a/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2DUsageTrackingTest.cpp +++ b/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2DUsageTrackingTest.cpp
@@ -637,11 +637,11 @@ createContext(NonOpaque); EXPECT_EQ(0, context2d()->getUsage().numFramesSinceReset); - context2d()->incrementFrameCount(); + context2d()->finalizeFrame(); EXPECT_EQ(1, context2d()->getUsage().numFramesSinceReset); - context2d()->incrementFrameCount(); - context2d()->incrementFrameCount(); + context2d()->finalizeFrame(); + context2d()->finalizeFrame(); EXPECT_EQ(3, context2d()->getUsage().numFramesSinceReset); } @@ -649,8 +649,8 @@ createContext(NonOpaque); EXPECT_EQ(0, context2d()->getUsage().numFramesSinceReset); - context2d()->incrementFrameCount(); - context2d()->incrementFrameCount(); + context2d()->finalizeFrame(); + context2d()->finalizeFrame(); EXPECT_EQ(2, context2d()->getUsage().numFramesSinceReset); const int numReps = 100;
diff --git a/third_party/WebKit/Source/modules/presentation/PresentationReceiver.cpp b/third_party/WebKit/Source/modules/presentation/PresentationReceiver.cpp index bbefd94..14aea21 100644 --- a/third_party/WebKit/Source/modules/presentation/PresentationReceiver.cpp +++ b/third_party/WebKit/Source/modules/presentation/PresentationReceiver.cpp
@@ -49,14 +49,15 @@ // receiver.connectionList property not accessed if (!m_connectionListProperty) - return nullptr; + return connection; if (m_connectionListProperty->getState() == - ScriptPromisePropertyBase::Pending) + ScriptPromisePropertyBase::Pending) { m_connectionListProperty->resolve(m_connectionList); - else if (m_connectionListProperty->getState() == - ScriptPromisePropertyBase::Resolved) + } else if (m_connectionListProperty->getState() == + ScriptPromisePropertyBase::Resolved) { m_connectionList->dispatchConnectionAvailableEvent(connection); + } return connection; }
diff --git a/third_party/WebKit/Source/modules/presentation/PresentationReceiverTest.cpp b/third_party/WebKit/Source/modules/presentation/PresentationReceiverTest.cpp index a57a899b..94ef5791 100644 --- a/third_party/WebKit/Source/modules/presentation/PresentationReceiverTest.cpp +++ b/third_party/WebKit/Source/modules/presentation/PresentationReceiverTest.cpp
@@ -202,9 +202,12 @@ WebPresentationSessionInfo sessionInfo(KURL(KURL(), "http://example.com"), "id"); // Receive first connection. - receiver->onReceiverConnectionAvailable(sessionInfo); + auto* connection1 = receiver->onReceiverConnectionAvailable(sessionInfo); + EXPECT_TRUE(connection1); + // Receive second connection. - receiver->onReceiverConnectionAvailable(sessionInfo); + auto* connection2 = receiver->onReceiverConnectionAvailable(sessionInfo); + EXPECT_TRUE(connection2); receiver->connectionList(scope.getScriptState()); verifyConnectionListPropertyState(ScriptPromisePropertyBase::Resolved,
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp index 6158955..449c7e9 100644 --- a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp +++ b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
@@ -1204,6 +1204,7 @@ ASSERT(drawingBuffer()); m_markedCanvasDirty = false; + m_animationFrameInProgress = false; m_activeTextureUnit = 0; m_packAlignment = 4; m_unpackAlignment = 4; @@ -1419,17 +1420,23 @@ if (!canvas()) return; - LayoutBox* layoutBox = canvas()->layoutBox(); - if (layoutBox && layoutBox->hasAcceleratedCompositing()) { - layoutBox->contentChanged(changeType); - } - if (!m_markedCanvasDirty) { - m_markedCanvasDirty = true; + m_markedCanvasDirty = true; + + if (!m_animationFrameInProgress) { + m_animationFrameInProgress = true; + LayoutBox* layoutBox = canvas()->layoutBox(); + if (layoutBox && layoutBox->hasAcceleratedCompositing()) { + layoutBox->contentChanged(changeType); + } IntSize canvasSize = clampedCanvasSize(); didDraw(SkIRect::MakeXYWH(0, 0, canvasSize.width(), canvasSize.height())); } } +void WebGLRenderingContextBase::finalizeFrame() { + m_animationFrameInProgress = false; +} + void WebGLRenderingContextBase::onErrorMessage(const char* message, int32_t id) { if (m_synthesizedErrorsToConsole)
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h index 4853119..fbde1a8 100644 --- a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h +++ b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h
@@ -625,6 +625,7 @@ bool paintRenderingResultsToCanvas(SourceDrawingBuffer) override; WebLayer* platformLayer() const override; void stop() override; + void finalizeFrame() override; // DrawingBuffer::Client implementation. bool DrawingBufferClientIsBoundForDraw() override; @@ -687,6 +688,7 @@ TaskRunnerTimer<WebGLRenderingContextBase> m_restoreTimer; bool m_markedCanvasDirty; + bool m_animationFrameInProgress; // List of bound VBO's. Used to maintain info about sizes for ARRAY_BUFFER and // stored values for ELEMENT_ARRAY_BUFFER
diff --git a/third_party/WebKit/Source/modules/webusb/NavigatorUSB.idl b/third_party/WebKit/Source/modules/webusb/NavigatorUSB.idl index 581358f..e9a8522 100644 --- a/third_party/WebKit/Source/modules/webusb/NavigatorUSB.idl +++ b/third_party/WebKit/Source/modules/webusb/NavigatorUSB.idl
@@ -4,6 +4,9 @@ // https://wicg.github.io/webusb/#enumeration +// The [SecureContext] and [OriginTrialEnabled] extended attributes don't mix. +// Once this is out of origin trial and the secure context logic is removed from +// ConditionalFeaturesForModules.cpp add [SecureContext] here. partial interface Navigator { [OriginTrialEnabled=WebUSB] readonly attribute USB usb; };
diff --git a/third_party/WebKit/Source/modules/webusb/USB.cpp b/third_party/WebKit/Source/modules/webusb/USB.cpp index 847a4aa..3100af6f8 100644 --- a/third_party/WebKit/Source/modules/webusb/USB.cpp +++ b/third_party/WebKit/Source/modules/webusb/USB.cpp
@@ -80,16 +80,11 @@ if (!m_deviceManager) { resolver->reject(DOMException::create(NotSupportedError)); } else { - String errorMessage; - if (!scriptState->getExecutionContext()->isSecureContext(errorMessage)) { - resolver->reject(DOMException::create(SecurityError, errorMessage)); - } else { - m_deviceManagerRequests.insert(resolver); - m_deviceManager->GetDevices( - nullptr, convertToBaseCallback(WTF::bind(&USB::onGetDevices, - wrapPersistent(this), - wrapPersistent(resolver)))); - } + m_deviceManagerRequests.insert(resolver); + m_deviceManager->GetDevices( + nullptr, convertToBaseCallback(WTF::bind(&USB::onGetDevices, + wrapPersistent(this), + wrapPersistent(resolver)))); } return promise; } @@ -116,10 +111,7 @@ wrapWeakPersistent(this)))); } - String errorMessage; - if (!executionContext->isSecureContext(errorMessage)) { - resolver->reject(DOMException::create(SecurityError, errorMessage)); - } else if (!UserGestureIndicator::consumeUserGesture()) { + if (!UserGestureIndicator::consumeUserGesture()) { resolver->reject(DOMException::create( SecurityError, "Must be handling a user gesture to show a permission request."));
diff --git a/third_party/WebKit/Source/platform/network/mime/MIMETypeRegistry.cpp b/third_party/WebKit/Source/platform/network/mime/MIMETypeRegistry.cpp index d3ba4637..33b0169 100644 --- a/third_party/WebKit/Source/platform/network/mime/MIMETypeRegistry.cpp +++ b/third_party/WebKit/Source/platform/network/mime/MIMETypeRegistry.cpp
@@ -140,7 +140,7 @@ const String& codecs) { const std::string asciiMimeType = ToLowerASCIIOrEmpty(mimeType); std::vector<std::string> codecVector; - media::ParseCodecString(ToASCIIOrEmpty(codecs), &codecVector, false); + media::SplitCodecsToVector(ToASCIIOrEmpty(codecs), &codecVector, false); return static_cast<SupportsType>( media::IsSupportedMediaFormat(asciiMimeType, codecVector)); } @@ -151,7 +151,7 @@ if (asciiMimeType.empty()) return false; std::vector<std::string> parsedCodecIds; - media::ParseCodecString(ToASCIIOrEmpty(codecs), &parsedCodecIds, false); + media::SplitCodecsToVector(ToASCIIOrEmpty(codecs), &parsedCodecIds, false); return static_cast<MIMETypeRegistry::SupportsType>( media::StreamParserFactory::IsTypeSupported(asciiMimeType, parsedCodecIds));
diff --git a/third_party/WebKit/Source/platform/scheduler/child/OWNERS b/third_party/WebKit/Source/platform/scheduler/child/OWNERS index 6dc4cb4..9bf4416 100644 --- a/third_party/WebKit/Source/platform/scheduler/child/OWNERS +++ b/third_party/WebKit/Source/platform/scheduler/child/OWNERS
@@ -1,3 +1,6 @@ alexclarke@chromium.org rmcilroy@chromium.org skyostil@chromium.org + +# TEAM: scheduler-dev@chromium.org +# COMPONENT: Blink>Scheduling
diff --git a/third_party/WebKit/Source/web/WebFrameSerializer.cpp b/third_party/WebKit/Source/web/WebFrameSerializer.cpp index 4434b29..6d2110f4 100644 --- a/third_party/WebKit/Source/web/WebFrameSerializer.cpp +++ b/third_party/WebKit/Source/web/WebFrameSerializer.cpp
@@ -131,7 +131,7 @@ return false; if (isHTMLHeadElement(element) || isHTMLMetaElement(element) || isHTMLStyleElement(element) || isHTMLDataListElement(element) || - isHTMLOptionElement(element)) { + isHTMLOptionElement(element) || isHTMLLinkElement(element)) { return false; } Element* parent = element.parentElement();
diff --git a/third_party/WebKit/Source/web/tests/NGInlineLayoutTest.cpp b/third_party/WebKit/Source/web/tests/NGInlineLayoutTest.cpp index 8528b8b..8e6a9c3 100644 --- a/third_party/WebKit/Source/web/tests/NGInlineLayoutTest.cpp +++ b/third_party/WebKit/Source/web/tests/NGInlineLayoutTest.cpp
@@ -48,9 +48,9 @@ NGConstraintSpace* constraintSpace = constraintSpaceForElement(blockFlow); NGBlockNode* node = new NGBlockNode(blockFlow); - RefPtr<NGPhysicalFragment> fragment = + RefPtr<NGLayoutResult> result = NGBlockLayoutAlgorithm(node, constraintSpace).Layout(); - EXPECT_TRUE(fragment); + EXPECT_TRUE(result); String expectedText("Hello World!"); EXPECT_EQ(expectedText, toNGInlineNode(node->FirstChild())->Text(0, 12)); @@ -72,9 +72,9 @@ NGConstraintSpace* constraintSpace = constraintSpaceForElement(blockFlow); NGBlockNode* node = new NGBlockNode(blockFlow); - RefPtr<NGPhysicalFragment> fragment = + RefPtr<NGLayoutResult> result = NGBlockLayoutAlgorithm(node, constraintSpace).Layout(); - EXPECT_TRUE(fragment); + EXPECT_TRUE(result); String expectedText("Hello "); expectedText.append(objectReplacementCharacter);
diff --git a/third_party/WebKit/Source/web/tests/WebFrameSerializerTest.cpp b/third_party/WebKit/Source/web/tests/WebFrameSerializerTest.cpp index 9459bfc..84b9eff 100644 --- a/third_party/WebKit/Source/web/tests/WebFrameSerializerTest.cpp +++ b/third_party/WebKit/Source/web/tests/WebFrameSerializerTest.cpp
@@ -283,13 +283,14 @@ EXPECT_NE(WTF::kNotFound, mhtml.find("<head")); EXPECT_NE(WTF::kNotFound, mhtml.find("<style")); EXPECT_NE(WTF::kNotFound, mhtml.find("<title")); - EXPECT_NE(WTF::kNotFound, mhtml.find("<link")); EXPECT_NE(WTF::kNotFound, mhtml.find("<datalist")); EXPECT_NE(WTF::kNotFound, mhtml.find("<option")); // One for meta in head and another for meta in body. EXPECT_EQ(2, matchSubstring(mhtml, "<meta", 5)); // One for style in head and another for style in body. EXPECT_EQ(2, matchSubstring(mhtml, "<style", 6)); + // One for link in head and another for link in body. + EXPECT_EQ(2, matchSubstring(mhtml, "<link", 5)); // These hidden elements that affect layout should remain intact. EXPECT_NE(WTF::kNotFound, mhtml.find("<h2"));
diff --git a/third_party/WebKit/Source/web/tests/data/frameserialization/hidden_elements.html b/third_party/WebKit/Source/web/tests/data/frameserialization/hidden_elements.html index 465fc7a..a12892aec 100644 --- a/third_party/WebKit/Source/web/tests/data/frameserialization/hidden_elements.html +++ b/third_party/WebKit/Source/web/tests/data/frameserialization/hidden_elements.html
@@ -27,5 +27,6 @@ </style> <meta itemprop="name" content="value"> </div> +<link rel="next2" href="next2.html"> </body> </html>
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/diff_parser_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/diff_parser_unittest.py index f31ab9b..6ea84b6d 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/diff_parser_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/diff_parser_unittest.py
@@ -27,10 +27,10 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import cStringIO as StringIO -import diff_parser import re import unittest +from webkitpy.common.checkout import diff_parser from webkitpy.common.checkout.diff_test_data import DIFF_TEST_DATA
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/find_files_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/find_files_unittest.py index a904b4d..15e1f4e 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/find_files_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/find_files_unittest.py
@@ -29,8 +29,8 @@ import sys import unittest +from webkitpy.common import find_files from webkitpy.common.system.filesystem import FileSystem -import find_files class MockWinFileSystem(object):
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/style/checker.py b/third_party/WebKit/Tools/Scripts/webkitpy/style/checker.py index 212b0a8..f305755 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/style/checker.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/style/checker.py
@@ -35,21 +35,21 @@ import re import sys -from checkers.common import categories as CommonCategories -from checkers.common import CarriageReturnChecker -from checkers.cpp import CppChecker -from checkers.jsonchecker import JSONChecker -from checkers.png import PNGChecker -from checkers.python import PythonChecker -from checkers.test_expectations import TestExpectationsChecker -from checkers.text import TextChecker -from checkers.xcodeproj import XcodeProjectFileChecker -from checkers.xml import XMLChecker -from error_handlers import DefaultStyleErrorHandler -from filter import FilterConfiguration -from optparser import ArgumentParser -from optparser import DefaultCommandOptionValues from webkitpy.common.system.log_utils import configure_logging as _configure_logging +from webkitpy.style.checkers.common import CarriageReturnChecker +from webkitpy.style.checkers.common import categories as CommonCategories +from webkitpy.style.checkers.cpp import CppChecker +from webkitpy.style.checkers.jsonchecker import JSONChecker +from webkitpy.style.checkers.png import PNGChecker +from webkitpy.style.checkers.python import PythonChecker +from webkitpy.style.checkers.test_expectations import TestExpectationsChecker +from webkitpy.style.checkers.text import TextChecker +from webkitpy.style.checkers.xcodeproj import XcodeProjectFileChecker +from webkitpy.style.checkers.xml import XMLChecker +from webkitpy.style.error_handlers import DefaultStyleErrorHandler +from webkitpy.style.filter import FilterConfiguration +from webkitpy.style.optparser import ArgumentParser +from webkitpy.style.optparser import DefaultCommandOptionValues _log = logging.getLogger(__name__)
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/style/checkers/common_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/style/checkers/common_unittest.py index 6200acc..bda749a 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/style/checkers/common_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/style/checkers/common_unittest.py
@@ -24,8 +24,8 @@ import unittest -from common import CarriageReturnChecker -from common import TabChecker +from webkitpy.style.checkers.common import CarriageReturnChecker +from webkitpy.style.checkers.common import TabChecker # FIXME: The unit tests for the cpp, text, and common checkers should # share supporting test code. This can include, for example, the
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/style/checkers/cpp_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/style/checkers/cpp_unittest.py index 51ce750..810bfbe2 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/style/checkers/cpp_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/style/checkers/cpp_unittest.py
@@ -40,10 +40,10 @@ import re import unittest -import cpp as cpp_style -from cpp import CppChecker -from ..filter import FilterConfiguration from webkitpy.common.system.filesystem import FileSystem +from webkitpy.style.checkers import cpp as cpp_style +from webkitpy.style.checkers.cpp import CppChecker +from webkitpy.style.filter import FilterConfiguration # This class works as an error collector and replaces cpp_style.Error # function for the unit tests. We also verify each category we see
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/style/checkers/jsonchecker_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/style/checkers/jsonchecker_unittest.py index 11b9d16..ac83a11 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/style/checkers/jsonchecker_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/style/checkers/jsonchecker_unittest.py
@@ -24,7 +24,7 @@ import unittest -import jsonchecker +from webkitpy.style.checkers import jsonchecker class MockErrorHandler(object):
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/style/checkers/png_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/style/checkers/png_unittest.py index 636df7d7..c0aeb0c 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/style/checkers/png_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/style/checkers/png_unittest.py
@@ -25,7 +25,7 @@ import unittest -from png import PNGChecker +from webkitpy.style.checkers.png import PNGChecker from webkitpy.common.system.filesystem_mock import MockFileSystem from webkitpy.common.system.system_host_mock import MockSystemHost
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/style/checkers/python_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/style/checkers/python_unittest.py index d4c35d6e..abad796 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/style/checkers/python_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/style/checkers/python_unittest.py
@@ -25,7 +25,7 @@ import os import unittest -from python import PythonChecker +from webkitpy.style.checkers.python import PythonChecker class PythonCheckerTest(unittest.TestCase):
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/style/checkers/test_expectations.py b/third_party/WebKit/Tools/Scripts/webkitpy/style/checkers/test_expectations.py index c8b8051..6ca9699 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/style/checkers/test_expectations.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/style/checkers/test_expectations.py
@@ -30,9 +30,9 @@ import logging -from common import TabChecker from webkitpy.common.host import Host from webkitpy.layout_tests.models.test_expectations import TestExpectationParser +from webkitpy.style.checkers.common import TabChecker class TestExpectationsChecker(object):
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/style/checkers/test_expectations_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/style/checkers/test_expectations_unittest.py index c5ff9e5..c2d4e29 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/style/checkers/test_expectations_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/style/checkers/test_expectations_unittest.py
@@ -28,7 +28,7 @@ import unittest -from test_expectations import TestExpectationsChecker +from webkitpy.style.checkers.test_expectations import TestExpectationsChecker from webkitpy.common.host_mock import MockHost
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/style/checkers/text.py b/third_party/WebKit/Tools/Scripts/webkitpy/style/checkers/text.py index c85d9e61..9526f12 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/style/checkers/text.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/style/checkers/text.py
@@ -29,11 +29,10 @@ """Checks WebKit style for text files.""" -from common import TabChecker +from webkitpy.style.checkers.common import TabChecker class TextChecker(object): - """Processes text lines for checking style.""" def __init__(self, file_path, handle_style_error):
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/style/checkers/text_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/style/checkers/text_unittest.py index a9b9433..beeffb6 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/style/checkers/text_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/style/checkers/text_unittest.py
@@ -26,12 +26,9 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -"""Unit test for text_style.py.""" - import unittest -import text as text_style -from text import TextChecker +from webkitpy.style.checkers.text import process_file_data, TextChecker class TextStyleTestCase(unittest.TestCase): @@ -45,7 +42,7 @@ """Records if an error occurs.""" self.had_error = True - text_style.process_file_data('', lines, error_for_test) + process_file_data('', lines, error_for_test) self.assertFalse(self.had_error, '%s should not have any errors.' % lines) def assertError(self, lines, expected_line_number): @@ -58,7 +55,7 @@ self.assertEqual('whitespace/tab', category) self.had_error = True - text_style.process_file_data('', lines, error_for_test) + process_file_data('', lines, error_for_test) self.assertTrue(self.had_error, '%s should have an error [whitespace/tab].' % lines) def test_no_error(self):
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/style/checkers/xcodeproj_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/style/checkers/xcodeproj_unittest.py index e36c93d..00de7f3 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/style/checkers/xcodeproj_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/style/checkers/xcodeproj_unittest.py
@@ -22,9 +22,10 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. """Unit test for xcodeproj.py.""" + import unittest -import xcodeproj +from webkitpy.style.checkers import xcodeproj class TestErrorHandler(object):
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/style/checkers/xml_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/style/checkers/xml_unittest.py index 8d4505f..8127142 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/style/checkers/xml_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/style/checkers/xml_unittest.py
@@ -23,7 +23,8 @@ """Unit test for xml.py.""" import unittest -import xml + +from webkitpy.style.checkers import xml class MockErrorHandler(object):
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/style/error_handlers_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/style/error_handlers_unittest.py index e9b3b32..6c93eb2 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/style/error_handlers_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/style/error_handlers_unittest.py
@@ -24,9 +24,9 @@ import unittest -from checker import StyleProcessorConfiguration -from error_handlers import DefaultStyleErrorHandler -from filter import FilterConfiguration +from webkitpy.style.checker import StyleProcessorConfiguration +from webkitpy.style.error_handlers import DefaultStyleErrorHandler +from webkitpy.style.filter import FilterConfiguration class DefaultStyleErrorHandlerTest(unittest.TestCase):
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/style/filter_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/style/filter_unittest.py index 0567c8d..a6a93bd 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/style/filter_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/style/filter_unittest.py
@@ -24,9 +24,9 @@ import unittest -from filter import _CategoryFilter as CategoryFilter -from filter import validate_filter_rules -from filter import FilterConfiguration +from webkitpy.style.filter import _CategoryFilter as CategoryFilter +from webkitpy.style.filter import validate_filter_rules +from webkitpy.style.filter import FilterConfiguration # On Testing __eq__() and __ne__(): #
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/style/optparser.py b/third_party/WebKit/Tools/Scripts/webkitpy/style/optparser.py index d2141eb8..12cd4ff 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/style/optparser.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/style/optparser.py
@@ -26,7 +26,7 @@ from optparse import OptionParser import sys -from filter import validate_filter_rules +from webkitpy.style.filter import validate_filter_rules # This module should not import anything from checker.py. _log = logging.getLogger(__name__)
diff --git a/third_party/WebKit/public/platform/WebPointerProperties.h b/third_party/WebKit/public/platform/WebPointerProperties.h index 49a142e..ad2704ae 100644 --- a/third_party/WebKit/public/platform/WebPointerProperties.h +++ b/third_party/WebKit/public/platform/WebPointerProperties.h
@@ -80,7 +80,13 @@ // degrees in the range [0,359]. Always 0 if the device does not support it. int twist; + // - For pointerup/down events, the button of pointing device that triggered + // the event. + // - For other events, the button that was depressed during the move event. If + // multiple buttons were depressed, one of the depressed buttons (platform + // dependent). Button button; + PointerType pointerType; int movementX;
diff --git a/third_party/cacheinvalidation/src/java/com/google/ipc/invalidation/external/client/contrib/AndroidListener.java b/third_party/cacheinvalidation/src/java/com/google/ipc/invalidation/external/client/contrib/AndroidListener.java index f15a9f135..fa51de8 100644 --- a/third_party/cacheinvalidation/src/java/com/google/ipc/invalidation/external/client/contrib/AndroidListener.java +++ b/third_party/cacheinvalidation/src/java/com/google/ipc/invalidation/external/client/contrib/AndroidListener.java
@@ -269,7 +269,11 @@ Preconditions.checkNotNull(objectIds); Context context = getApplicationContext(); - context.startService(createRegisterIntent(context, clientId, objectIds)); + try { + context.startService(createRegisterIntent(context, clientId, objectIds)); + } catch (IllegalStateException exception) { + logger.info("Unable to deliver `register` intent: %s", exception); + } } /** @@ -318,7 +322,11 @@ Preconditions.checkNotNull(objectIds); Context context = getApplicationContext(); - context.startService(createUnregisterIntent(context, clientId, objectIds)); + try { + context.startService(createUnregisterIntent(context, clientId, objectIds)); + } catch (IllegalStateException exception) { + logger.info("Unable to deliver `unregister` intent: %s", exception); + } } /** See specs for {@link InvalidationClient#acknowledge}. */ @@ -334,7 +342,11 @@ Preconditions.checkNotNull(ackHandle); Context context = getApplicationContext(); - context.startService(createAcknowledgeIntent(context, ackHandle)); + try { + context.startService(createAcknowledgeIntent(context, ackHandle)); + } catch (IllegalStateException exception) { + logger.info("Unable to deliver `acknowledge` intent: %s", exception); + } } /**
diff --git a/third_party/cacheinvalidation/src/java/com/google/ipc/invalidation/external/client/contrib/AndroidListenerIntents.java b/third_party/cacheinvalidation/src/java/com/google/ipc/invalidation/external/client/contrib/AndroidListenerIntents.java index d734f6c..9f3433f 100644 --- a/third_party/cacheinvalidation/src/java/com/google/ipc/invalidation/external/client/contrib/AndroidListenerIntents.java +++ b/third_party/cacheinvalidation/src/java/com/google/ipc/invalidation/external/client/contrib/AndroidListenerIntents.java
@@ -46,7 +46,7 @@ /** Key of Intent byte[] holding a {@link RegistrationCommand} protocol buffer. */ static final String EXTRA_REGISTRATION = "com.google.ipc.invalidation.android_listener.REGISTRATION"; - + /** Key of Intent boolean indicating whether scheduled tasks should be flushed. */ static final String EXTRA_SCHEDULED_TASK = "com.google.ipc.invalidation.android_listener.SCHEDULED_TASK"; @@ -67,8 +67,12 @@ * Issues the given {@code intent} to the TICL service class registered in the {@code context}. */ static void issueTiclIntent(Context context, Intent intent) { - context.startService(intent.setClassName(context, - new AndroidTiclManifest(context).getTiclServiceClass())); + try { + context.startService(intent.setClassName(context, + new AndroidTiclManifest(context).getTiclServiceClass())); + } catch (IllegalStateException exception) { + logger.info("Unable to deliver ticl intent: %s", exception); + } } /** @@ -76,7 +80,11 @@ * {@code context}. */ static void issueAndroidListenerIntent(Context context, Intent intent) { - context.startService(setAndroidListenerClass(context, intent)); + try { + context.startService(setAndroidListenerClass(context, intent)); + } catch (IllegalStateException exception) { + logger.info("Unable to deliver listener intent: %s", exception); + } } /** @@ -106,7 +114,7 @@ return null; } } - + /** * Returns {@link StartCommand} extra from the given intent or null if no valid start command * exists. @@ -131,12 +139,12 @@ static boolean isStopIntent(Intent intent) { return intent.hasExtra(EXTRA_STOP); } - + /** Returns {@code true} if the intent has the 'scheduled-task' extra. */ static boolean isScheduledTaskIntent(Intent intent) { return intent.hasExtra(EXTRA_SCHEDULED_TASK); } - + /** * Uses {@link AlarmManager} to schedule an intent that will cause scheduled tasks to be executed. * Replaces any existing scheduled-task intent, so the provided execute time should be for the @@ -144,11 +152,11 @@ */ static void issueScheduledTaskIntent(Context context, long executeMs) { Intent intent = createScheduledTaskintent(context); - + // Create a pending intent that will cause the AlarmManager to fire the above intent. PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); - + // Schedule the pending intent after the appropriate delay. AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); try { @@ -195,7 +203,7 @@ intent.putExtra(EXTRA_REGISTRATION, command.toByteArray()); return setAndroidListenerClass(context, intent); } - + /** Constructs an intent indicating that scheduled tasks should run. */ static Intent createScheduledTaskintent(Context context) { return new Intent()
diff --git a/third_party/cacheinvalidation/src/java/com/google/ipc/invalidation/ticl/android2/AndroidInternalScheduler.java b/third_party/cacheinvalidation/src/java/com/google/ipc/invalidation/ticl/android2/AndroidInternalScheduler.java index 8eb63d0..17d00c4a 100644 --- a/third_party/cacheinvalidation/src/java/com/google/ipc/invalidation/ticl/android2/AndroidInternalScheduler.java +++ b/third_party/cacheinvalidation/src/java/com/google/ipc/invalidation/ticl/android2/AndroidInternalScheduler.java
@@ -19,6 +19,7 @@ import com.google.ipc.invalidation.external.client.SystemResources; import com.google.ipc.invalidation.external.client.SystemResources.Logger; import com.google.ipc.invalidation.external.client.SystemResources.Scheduler; +import com.google.ipc.invalidation.external.client.android.service.AndroidLogger; import com.google.ipc.invalidation.ticl.RecurringTask; import com.google.ipc.invalidation.ticl.proto.AndroidService.AndroidSchedulerEvent; import com.google.ipc.invalidation.ticl.proto.AndroidService.ScheduledTask; @@ -57,6 +58,8 @@ public final class AndroidInternalScheduler implements Scheduler { /** Class that receives AlarmManager broadcasts and reissues them as intents for this service. */ public static final class AlarmReceiver extends BroadcastReceiver { + private static final Logger logger = AndroidLogger.forTag("AlarmReceiver"); + /* * This class needs to be public so that it can be instantiated by the Android runtime. * Additionally, it should be declared as a broadcast receiver in the application manifest: @@ -69,7 +72,11 @@ // Resend the intent to the service so that it's processed on the handler thread and with // the automatic shutdown logic provided by IntentService. intent.setClassName(context, new AndroidTiclManifest(context).getTiclServiceClass()); - context.startService(intent); + try { + context.startService(intent); + } catch (IllegalStateException exception) { + logger.warning("Unable to handle alarm: %s", exception); + } } }
diff --git a/third_party/cacheinvalidation/src/java/com/google/ipc/invalidation/ticl/android2/AndroidInvalidationClientImpl.java b/third_party/cacheinvalidation/src/java/com/google/ipc/invalidation/ticl/android2/AndroidInvalidationClientImpl.java index a6cecb1..748394b 100644 --- a/third_party/cacheinvalidation/src/java/com/google/ipc/invalidation/ticl/android2/AndroidInvalidationClientImpl.java +++ b/third_party/cacheinvalidation/src/java/com/google/ipc/invalidation/ticl/android2/AndroidInvalidationClientImpl.java
@@ -19,6 +19,7 @@ import com.google.ipc.invalidation.external.client.InvalidationListener; import com.google.ipc.invalidation.external.client.SystemResources; import com.google.ipc.invalidation.external.client.SystemResources.Logger; +import com.google.ipc.invalidation.external.client.android.service.AndroidLogger; import com.google.ipc.invalidation.external.client.types.AckHandle; import com.google.ipc.invalidation.external.client.types.ErrorInfo; import com.google.ipc.invalidation.external.client.types.Invalidation; @@ -58,6 +59,9 @@ * */ class AndroidInvalidationClientImpl extends InvalidationClientCore { + /** Logger from Ticl resources. */ + private static final Logger staticLogger = AndroidLogger.forTag("InvClientImpl"); + /** Class implementing the application listener stub (allows overriding default for tests). */ static Class<? extends Service> listenerServiceClassForTest = null; @@ -156,7 +160,11 @@ intent.setClassName(context, (listenerServiceClassForTest != null) ? listenerServiceClassForTest.getName() : new AndroidTiclManifest(context).getListenerServiceClass()); - context.startService(intent); + try { + context.startService(intent); + } catch (IllegalStateException exception) { + staticLogger.warning("Unable to deliver intent: %s", exception); + } } /**
diff --git a/third_party/cacheinvalidation/src/java/com/google/ipc/invalidation/ticl/android2/AndroidInvalidationClientStub.java b/third_party/cacheinvalidation/src/java/com/google/ipc/invalidation/ticl/android2/AndroidInvalidationClientStub.java index 6a54f9d1..66f5418 100644 --- a/third_party/cacheinvalidation/src/java/com/google/ipc/invalidation/ticl/android2/AndroidInvalidationClientStub.java +++ b/third_party/cacheinvalidation/src/java/com/google/ipc/invalidation/ticl/android2/AndroidInvalidationClientStub.java
@@ -17,6 +17,8 @@ package com.google.ipc.invalidation.ticl.android2; import com.google.ipc.invalidation.external.client.InvalidationClient; +import com.google.ipc.invalidation.external.client.SystemResources.Logger; +import com.google.ipc.invalidation.external.client.android.service.AndroidLogger; import com.google.ipc.invalidation.external.client.types.AckHandle; import com.google.ipc.invalidation.external.client.types.ObjectId; import com.google.ipc.invalidation.ticl.ProtoWrapperConverter; @@ -36,6 +38,8 @@ * */ class AndroidInvalidationClientStub implements InvalidationClient { + private final Logger logger = AndroidLogger.forTag("InvClientStub"); + /** Android system context. */ private final Context context; @@ -98,6 +102,10 @@ /** Sends {@code intent} to the service implemented by {@link #serviceClass}. */ private void issueIntent(Intent intent) { intent.setClassName(context, serviceClass); - context.startService(intent); + try { + context.startService(intent); + } catch (IllegalStateException exception) { + logger.warning("Unable to issue intent: %s", exception); + } } }
diff --git a/third_party/cacheinvalidation/src/java/com/google/ipc/invalidation/ticl/android2/TiclService.java b/third_party/cacheinvalidation/src/java/com/google/ipc/invalidation/ticl/android2/TiclService.java index 175a64d..b3bd1fb 100644 --- a/third_party/cacheinvalidation/src/java/com/google/ipc/invalidation/ticl/android2/TiclService.java +++ b/third_party/cacheinvalidation/src/java/com/google/ipc/invalidation/ticl/android2/TiclService.java
@@ -329,6 +329,9 @@ } } catch (ValidationException exception) { resources.getLogger().info("Failed to parse message: %s", exception.getMessage()); + } catch (IllegalStateException exception) { + resources.getLogger().info( + "Unable to send background invalidation intent: %s", exception.getMessage()); } } }
diff --git a/third_party/cacheinvalidation/src/java/com/google/ipc/invalidation/ticl/android2/TiclStateManager.java b/third_party/cacheinvalidation/src/java/com/google/ipc/invalidation/ticl/android2/TiclStateManager.java index 0789d6e..11db5fa 100644 --- a/third_party/cacheinvalidation/src/java/com/google/ipc/invalidation/ticl/android2/TiclStateManager.java +++ b/third_party/cacheinvalidation/src/java/com/google/ipc/invalidation/ticl/android2/TiclStateManager.java
@@ -75,6 +75,9 @@ AndroidInvalidationClientImpl ticl = new AndroidInvalidationClientImpl(context, resources, random, state); initScheduler(resources, ticl, state.getScheduledTask()); + AndroidInternalScheduler scheduler = + (AndroidInternalScheduler) resources.getInternalScheduler(); + scheduler.handleImplicitSchedulerEvent(); return ticl; }
diff --git a/third_party/cacheinvalidation/src/java/com/google/ipc/invalidation/ticl/android2/channel/AndroidGcmController.java b/third_party/cacheinvalidation/src/java/com/google/ipc/invalidation/ticl/android2/channel/AndroidGcmController.java index 3a224487..3149de9 100644 --- a/third_party/cacheinvalidation/src/java/com/google/ipc/invalidation/ticl/android2/channel/AndroidGcmController.java +++ b/third_party/cacheinvalidation/src/java/com/google/ipc/invalidation/ticl/android2/channel/AndroidGcmController.java
@@ -58,7 +58,7 @@ * A getter method for AndroidGcmController singleton which also initializes it if it wasn't * already initialized. * - * @param context, the application context. + * @param context the application context. * @return a singleton instance of the AndroidGcmController */ public static AndroidGcmController get(Context context) { @@ -75,8 +75,8 @@ * Override AndroidGcmController with a custom GcmNetworkManager in tests. This overrides the * existing instance of AndroidGcmController if any. * - * @param context, the application context. - * @param gcmNetworkManager, the custom GcmNetworkManager to use. + * @param context the application context. + * @param gcmNetworkManager the custom GcmNetworkManager to use. */ public static void overrideAndroidGcmControllerForTests( Context context, GcmNetworkManager gcmNetworkManager) { @@ -106,7 +106,7 @@ * GCM channel. Sets the {@link AndroidChannelPreferences.GcmChannelType} and fetches the * registration token from GCM if no token is stored or if the application has been updated. * - * @param useGcmUpstream, if true, the upstream messages from the client to the data center are + * @param useGcmUpstream if true, the upstream messages from the client to the data center are * sent using GCM. */ public void initializeGcm(boolean useGcmUpstream) { @@ -170,7 +170,7 @@ /** * Used by the client to forward downstream messages received from GCM. * - * @param data, the data bundle of the downstream message. + * @param data the data bundle of the downstream message. */ public void onMessageReceived(Bundle data) { String content = data.getString(C2dmConstants.CONTENT_PARAM); @@ -186,6 +186,8 @@ context.startService(msgIntent); } catch (ValidationException exception) { logger.warning("Failed parsing inbound message: %s", exception); + } catch (IllegalStateException exception) { + logger.warning("Unable to handle inbound message: %s", exception); } } else { logger.warning("GCM Intent has no message content: %s", data);
diff --git a/third_party/cacheinvalidation/src/java/com/google/ipc/invalidation/ticl/android2/channel/AndroidMessageReceiverService.java b/third_party/cacheinvalidation/src/java/com/google/ipc/invalidation/ticl/android2/channel/AndroidMessageReceiverService.java index 54d0fb9..aa3938ce 100644 --- a/third_party/cacheinvalidation/src/java/com/google/ipc/invalidation/ticl/android2/channel/AndroidMessageReceiverService.java +++ b/third_party/cacheinvalidation/src/java/com/google/ipc/invalidation/ticl/android2/channel/AndroidMessageReceiverService.java
@@ -75,6 +75,8 @@ startService(msgIntent); } catch (ValidationException exception) { logger.warning("Failed parsing inbound message: %s", exception); + } catch (IllegalStateException exception) { + logger.warning("Unable to handle inbound message: %s", exception); } } else { logger.fine("GCM Intent has no message content: %s", intent); @@ -96,13 +98,21 @@ final String ignoredData = ""; sendBuffered.putExtra(AndroidChannelConstants.MESSAGE_SENDER_SVC_GCM_REGID_CHANGE, ignoredData); sendBuffered.setClass(this, AndroidMessageSenderService.class); - startService(sendBuffered); + try { + startService(sendBuffered); + } catch (IllegalStateException exception) { + logger.warning("Unable to send buffered message(s): %s", exception); + } // Inform the Ticl service that the registration id has changed. This will cause it to send // a message to the data center and update the GCM registration id stored at the data center. Intent updateServer = ProtocolIntents.InternalDowncalls.newNetworkAddrChangeIntent(); updateServer.setClassName(this, new AndroidTiclManifest(this).getTiclServiceClass()); - startService(updateServer); + try { + startService(updateServer); + } catch (IllegalStateException exception) { + logger.warning("Unable to handle new registration id: %s", exception); + } } @Override
diff --git a/third_party/cacheinvalidation/src/java/com/google/ipc/invalidation/ticl/android2/channel/AndroidMessageSenderService.java b/third_party/cacheinvalidation/src/java/com/google/ipc/invalidation/ticl/android2/channel/AndroidMessageSenderService.java index 81882a7..22a168c7 100644 --- a/third_party/cacheinvalidation/src/java/com/google/ipc/invalidation/ticl/android2/channel/AndroidMessageSenderService.java +++ b/third_party/cacheinvalidation/src/java/com/google/ipc/invalidation/ticl/android2/channel/AndroidMessageSenderService.java
@@ -171,7 +171,7 @@ requestTokenIntent.setClassName(getApplicationContext(), simpleListenerClass); try { startService(requestTokenIntent); - } catch (SecurityException exception) { + } catch (SecurityException | IllegalStateException exception) { logger.warning("unable to request auth token: %s", exception); } }
diff --git a/third_party/cacheinvalidation/src/java/com/google/ipc/invalidation/ticl/android2/channel/AndroidNetworkChannel.java b/third_party/cacheinvalidation/src/java/com/google/ipc/invalidation/ticl/android2/channel/AndroidNetworkChannel.java index 4a3adefd..377ad73b9 100644 --- a/third_party/cacheinvalidation/src/java/com/google/ipc/invalidation/ticl/android2/channel/AndroidNetworkChannel.java +++ b/third_party/cacheinvalidation/src/java/com/google/ipc/invalidation/ticl/android2/channel/AndroidNetworkChannel.java
@@ -58,7 +58,11 @@ } else { intent.setClassName(context, AndroidMessageSenderService.class.getName()); } - context.startService(intent); + try { + context.startService(intent); + } catch (IllegalStateException exception) { + logger.warning("Unable to send message: %s", exception); + } } @Override
diff --git a/third_party/cacheinvalidation/src/java/com/google/ipc/invalidation/ticl/android2/channel/GcmRegistrationTaskService.java b/third_party/cacheinvalidation/src/java/com/google/ipc/invalidation/ticl/android2/channel/GcmRegistrationTaskService.java index e6f4b4214..06c9d2f 100644 --- a/third_party/cacheinvalidation/src/java/com/google/ipc/invalidation/ticl/android2/channel/GcmRegistrationTaskService.java +++ b/third_party/cacheinvalidation/src/java/com/google/ipc/invalidation/ticl/android2/channel/GcmRegistrationTaskService.java
@@ -37,14 +37,14 @@ * started by the {@link GcmNetworkManager} when a Task scheduled using the GcmNetworkManager is * ready to be executed. The task to start this service is scheduled in * {@link AndroidGcmController#fetchToken}. - * + * * <p>The service fetches a token from GCM, stores it and sends an update to the server. In case of * failure to fetch the token, the task is rescheduled using the GcmNetworkManager which uses * exponential back-offs to control when the task is executed. */ public class GcmRegistrationTaskService extends GcmTaskService { private static final Logger logger = AndroidLogger.forTag("RegistrationTaskService"); - + public InstanceID getInstanceID(Context context) { return InstanceID.getInstance(context); } @@ -52,7 +52,7 @@ /** * Called when the task is ready to be executed. Registers with GCM using * {@link InstanceID#getToken} and stores the registration token. - * + * * <p>Returns {@link GcmNetworkManager#RESULT_SUCCESS} when the token is successfully retrieved. * On failure {@link GcmNetworkManager#RESULT_RESCHEDULE} is used which reschedules the service * to be executed again using exponential back-off. @@ -110,12 +110,20 @@ } else { sendBuffered.setClass(this, AndroidMessageSenderService.class); } - startService(sendBuffered); + try { + startService(sendBuffered); + } catch (IllegalStateException exception) { + logger.warning("Unable to send buffered message(s): %s", exception); + } // Inform the Ticl service that the registration id has changed. This will cause it to send // a message to the data center and update the GCM registration id stored at the data center. Intent updateServer = ProtocolIntents.InternalDowncalls.newNetworkAddrChangeIntent(); updateServer.setClassName(this, new AndroidTiclManifest(this).getTiclServiceClass()); - startService(updateServer); + try { + startService(updateServer); + } catch (IllegalStateException exception) { + logger.warning("Unable to inform server about new registration id: %s", exception); + } } }
diff --git a/third_party/libvpx/README.chromium b/third_party/libvpx/README.chromium index 1b819f9f..3d82e58 100644 --- a/third_party/libvpx/README.chromium +++ b/third_party/libvpx/README.chromium
@@ -5,9 +5,9 @@ License File: source/libvpx/LICENSE Security Critical: yes -Date: Saturday February 11 2017 +Date: Tuesday February 21 2017 Branch: master -Commit: 91f87e75135cc9722ee72daf5154424f628a906e +Commit: 4d4231352c8cefdae2e76b7bad4286ec21747c89 Description: Contains the sources used to compile libvpx binaries used by Google Chrome and
diff --git a/third_party/libvpx/libvpx_srcs.gni b/third_party/libvpx/libvpx_srcs.gni index 1a7345b..8ff29f3 100644 --- a/third_party/libvpx/libvpx_srcs.gni +++ b/third_party/libvpx/libvpx_srcs.gni
@@ -316,6 +316,7 @@ "//third_party/libvpx/source/libvpx/vpx_dsp/vpx_dsp_common.h", "//third_party/libvpx/source/libvpx/vpx_dsp/vpx_dsp_rtcd.c", "//third_party/libvpx/source/libvpx/vpx_dsp/vpx_filter.h", + "//third_party/libvpx/source/libvpx/vpx_dsp/x86/bitdepth_conversion_avx2.h", "//third_party/libvpx/source/libvpx/vpx_dsp/x86/bitdepth_conversion_sse2.h", "//third_party/libvpx/source/libvpx/vpx_dsp/x86/convolve.h", "//third_party/libvpx/source/libvpx/vpx_dsp/x86/fwd_dct32x32_impl_avx2.h", @@ -758,6 +759,7 @@ "//third_party/libvpx/source/libvpx/vpx_dsp/vpx_dsp_common.h", "//third_party/libvpx/source/libvpx/vpx_dsp/vpx_dsp_rtcd.c", "//third_party/libvpx/source/libvpx/vpx_dsp/vpx_filter.h", + "//third_party/libvpx/source/libvpx/vpx_dsp/x86/bitdepth_conversion_avx2.h", "//third_party/libvpx/source/libvpx/vpx_dsp/x86/bitdepth_conversion_sse2.h", "//third_party/libvpx/source/libvpx/vpx_dsp/x86/convolve.h", "//third_party/libvpx/source/libvpx/vpx_dsp/x86/fwd_dct32x32_impl_avx2.h", @@ -828,7 +830,6 @@ "//third_party/libvpx/source/libvpx/vpx_dsp/x86/highbd_variance_impl_sse2.asm", "//third_party/libvpx/source/libvpx/vpx_dsp/x86/intrapred_sse2.asm", "//third_party/libvpx/source/libvpx/vpx_dsp/x86/intrapred_ssse3.asm", - "//third_party/libvpx/source/libvpx/vpx_dsp/x86/inv_txfm_ssse3_x86_64.asm", "//third_party/libvpx/source/libvpx/vpx_dsp/x86/inv_wht_sse2.asm", "//third_party/libvpx/source/libvpx/vpx_dsp/x86/quantize_avx_x86_64.asm", "//third_party/libvpx/source/libvpx/vpx_dsp/x86/quantize_ssse3_x86_64.asm",
diff --git a/third_party/libvpx/source/config/linux/generic/vpx_dsp_rtcd.h b/third_party/libvpx/source/config/linux/generic/vpx_dsp_rtcd.h index 18f79e2..3f920cc2a4 100644 --- a/third_party/libvpx/source/config/linux/generic/vpx_dsp_rtcd.h +++ b/third_party/libvpx/source/config/linux/generic/vpx_dsp_rtcd.h
@@ -910,6 +910,9 @@ void vpx_highbd_idct16x16_256_add_c(const tran_low_t *input, uint8_t *dest, int stride, int bd); #define vpx_highbd_idct16x16_256_add vpx_highbd_idct16x16_256_add_c +void vpx_highbd_idct16x16_38_add_c(const tran_low_t *input, uint8_t *dest, int stride, int bd); +#define vpx_highbd_idct16x16_38_add vpx_highbd_idct16x16_38_add_c + void vpx_highbd_idct32x32_1024_add_c(const tran_low_t *input, uint8_t *dest, int stride, int bd); #define vpx_highbd_idct32x32_1024_add vpx_highbd_idct32x32_1024_add_c
diff --git a/third_party/libvpx/source/config/linux/ia32/vp9_rtcd.h b/third_party/libvpx/source/config/linux/ia32/vp9_rtcd.h index 3770dd3..ac968a9 100644 --- a/third_party/libvpx/source/config/linux/ia32/vp9_rtcd.h +++ b/third_party/libvpx/source/config/linux/ia32/vp9_rtcd.h
@@ -30,7 +30,8 @@ #endif int64_t vp9_block_error_c(const tran_low_t *coeff, const tran_low_t *dqcoeff, intptr_t block_size, int64_t *ssz); -#define vp9_block_error vp9_block_error_c +int64_t vp9_block_error_avx2(const tran_low_t *coeff, const tran_low_t *dqcoeff, intptr_t block_size, int64_t *ssz); +RTCD_EXTERN int64_t (*vp9_block_error)(const tran_low_t *coeff, const tran_low_t *dqcoeff, intptr_t block_size, int64_t *ssz); int64_t vp9_block_error_fp_c(const tran_low_t *coeff, const tran_low_t *dqcoeff, int block_size); int64_t vp9_block_error_fp_sse2(const tran_low_t *coeff, const tran_low_t *dqcoeff, int block_size); @@ -138,7 +139,8 @@ RTCD_EXTERN void (*vp9_iht8x8_64_add)(const tran_low_t *input, uint8_t *dest, int stride, int tx_type); void vp9_quantize_fp_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan); -#define vp9_quantize_fp vp9_quantize_fp_c +void vp9_quantize_fp_sse2(const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan); +RTCD_EXTERN void (*vp9_quantize_fp)(const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan); void vp9_quantize_fp_32x32_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan); #define vp9_quantize_fp_32x32 vp9_quantize_fp_32x32_c @@ -157,6 +159,8 @@ (void)flags; + vp9_block_error = vp9_block_error_c; + if (flags & HAS_AVX2) vp9_block_error = vp9_block_error_avx2; vp9_block_error_fp = vp9_block_error_fp_c; if (flags & HAS_SSE2) vp9_block_error_fp = vp9_block_error_fp_sse2; vp9_denoiser_filter = vp9_denoiser_filter_c; @@ -191,6 +195,8 @@ if (flags & HAS_SSE2) vp9_iht4x4_16_add = vp9_iht4x4_16_add_sse2; vp9_iht8x8_64_add = vp9_iht8x8_64_add_c; if (flags & HAS_SSE2) vp9_iht8x8_64_add = vp9_iht8x8_64_add_sse2; + vp9_quantize_fp = vp9_quantize_fp_c; + if (flags & HAS_SSE2) vp9_quantize_fp = vp9_quantize_fp_sse2; vp9_temporal_filter_apply = vp9_temporal_filter_apply_c; if (flags & HAS_SSE2) vp9_temporal_filter_apply = vp9_temporal_filter_apply_sse2; }
diff --git a/third_party/libvpx/source/config/linux/ia32/vpx_dsp_rtcd.h b/third_party/libvpx/source/config/linux/ia32/vpx_dsp_rtcd.h index 727a39e..20ab4d2 100644 --- a/third_party/libvpx/source/config/linux/ia32/vpx_dsp_rtcd.h +++ b/third_party/libvpx/source/config/linux/ia32/vpx_dsp_rtcd.h
@@ -1095,6 +1095,10 @@ void vpx_highbd_idct16x16_256_add_sse2(const tran_low_t *input, uint8_t *dest, int stride, int bd); RTCD_EXTERN void (*vpx_highbd_idct16x16_256_add)(const tran_low_t *input, uint8_t *dest, int stride, int bd); +void vpx_highbd_idct16x16_38_add_c(const tran_low_t *input, uint8_t *dest, int stride, int bd); +void vpx_highbd_idct16x16_256_add_sse2(const tran_low_t *input, uint8_t *dest, int stride, int bd); +RTCD_EXTERN void (*vpx_highbd_idct16x16_38_add)(const tran_low_t *input, uint8_t *dest, int stride, int bd); + void vpx_highbd_idct32x32_1024_add_c(const tran_low_t *input, uint8_t *dest, int stride, int bd); #define vpx_highbd_idct32x32_1024_add vpx_highbd_idct32x32_1024_add_c @@ -2443,6 +2447,8 @@ if (flags & HAS_SSE2) vpx_highbd_idct16x16_10_add = vpx_highbd_idct16x16_10_add_sse2; vpx_highbd_idct16x16_256_add = vpx_highbd_idct16x16_256_add_c; if (flags & HAS_SSE2) vpx_highbd_idct16x16_256_add = vpx_highbd_idct16x16_256_add_sse2; + vpx_highbd_idct16x16_38_add = vpx_highbd_idct16x16_38_add_c; + if (flags & HAS_SSE2) vpx_highbd_idct16x16_38_add = vpx_highbd_idct16x16_256_add_sse2; vpx_highbd_idct32x32_1_add = vpx_highbd_idct32x32_1_add_c; if (flags & HAS_SSE2) vpx_highbd_idct32x32_1_add = vpx_highbd_idct32x32_1_add_sse2; vpx_highbd_idct4x4_16_add = vpx_highbd_idct4x4_16_add_c;
diff --git a/third_party/libvpx/source/config/linux/x64/vp9_rtcd.h b/third_party/libvpx/source/config/linux/x64/vp9_rtcd.h index f8c2110..b102039 100644 --- a/third_party/libvpx/source/config/linux/x64/vp9_rtcd.h +++ b/third_party/libvpx/source/config/linux/x64/vp9_rtcd.h
@@ -30,7 +30,8 @@ #endif int64_t vp9_block_error_c(const tran_low_t *coeff, const tran_low_t *dqcoeff, intptr_t block_size, int64_t *ssz); -#define vp9_block_error vp9_block_error_c +int64_t vp9_block_error_avx2(const tran_low_t *coeff, const tran_low_t *dqcoeff, intptr_t block_size, int64_t *ssz); +RTCD_EXTERN int64_t (*vp9_block_error)(const tran_low_t *coeff, const tran_low_t *dqcoeff, intptr_t block_size, int64_t *ssz); int64_t vp9_block_error_fp_c(const tran_low_t *coeff, const tran_low_t *dqcoeff, int block_size); int64_t vp9_block_error_fp_sse2(const tran_low_t *coeff, const tran_low_t *dqcoeff, int block_size); @@ -138,10 +139,13 @@ #define vp9_iht8x8_64_add vp9_iht8x8_64_add_sse2 void vp9_quantize_fp_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan); -#define vp9_quantize_fp vp9_quantize_fp_c +void vp9_quantize_fp_sse2(const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan); +void vp9_quantize_fp_ssse3(const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan); +RTCD_EXTERN void (*vp9_quantize_fp)(const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan); void vp9_quantize_fp_32x32_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan); -#define vp9_quantize_fp_32x32 vp9_quantize_fp_32x32_c +void vp9_quantize_fp_32x32_ssse3(const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan); +RTCD_EXTERN void (*vp9_quantize_fp_32x32)(const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan); void vp9_temporal_filter_apply_c(uint8_t *frame1, unsigned int stride, uint8_t *frame2, unsigned int block_width, unsigned int block_height, int strength, int filter_weight, unsigned int *accumulator, uint16_t *count); void vp9_temporal_filter_apply_sse2(uint8_t *frame1, unsigned int stride, uint8_t *frame2, unsigned int block_width, unsigned int block_height, int strength, int filter_weight, unsigned int *accumulator, uint16_t *count); @@ -157,6 +161,8 @@ (void)flags; + vp9_block_error = vp9_block_error_c; + if (flags & HAS_AVX2) vp9_block_error = vp9_block_error_avx2; vp9_diamond_search_sad = vp9_diamond_search_sad_c; if (flags & HAS_AVX) vp9_diamond_search_sad = vp9_diamond_search_sad_avx; vp9_fdct8x8_quant = vp9_fdct8x8_quant_c; @@ -166,6 +172,10 @@ if (flags & HAS_SSE4_1) vp9_full_search_sad = vp9_full_search_sadx8; vp9_highbd_block_error_8bit = vp9_highbd_block_error_8bit_sse2; if (flags & HAS_AVX) vp9_highbd_block_error_8bit = vp9_highbd_block_error_8bit_avx; + vp9_quantize_fp = vp9_quantize_fp_sse2; + if (flags & HAS_SSSE3) vp9_quantize_fp = vp9_quantize_fp_ssse3; + vp9_quantize_fp_32x32 = vp9_quantize_fp_32x32_c; + if (flags & HAS_SSSE3) vp9_quantize_fp_32x32 = vp9_quantize_fp_32x32_ssse3; } #endif
diff --git a/third_party/libvpx/source/config/linux/x64/vpx_dsp_rtcd.h b/third_party/libvpx/source/config/linux/x64/vpx_dsp_rtcd.h index 9fbfef8f..ac714cab 100644 --- a/third_party/libvpx/source/config/linux/x64/vpx_dsp_rtcd.h +++ b/third_party/libvpx/source/config/linux/x64/vpx_dsp_rtcd.h
@@ -1102,6 +1102,10 @@ void vpx_highbd_idct16x16_256_add_sse2(const tran_low_t *input, uint8_t *dest, int stride, int bd); #define vpx_highbd_idct16x16_256_add vpx_highbd_idct16x16_256_add_sse2 +void vpx_highbd_idct16x16_38_add_c(const tran_low_t *input, uint8_t *dest, int stride, int bd); +void vpx_highbd_idct16x16_256_add_sse2(const tran_low_t *input, uint8_t *dest, int stride, int bd); +#define vpx_highbd_idct16x16_38_add vpx_highbd_idct16x16_256_add_sse2 + void vpx_highbd_idct32x32_1024_add_c(const tran_low_t *input, uint8_t *dest, int stride, int bd); #define vpx_highbd_idct32x32_1024_add vpx_highbd_idct32x32_1024_add_c
diff --git a/third_party/libvpx/source/config/mac/ia32/vp9_rtcd.h b/third_party/libvpx/source/config/mac/ia32/vp9_rtcd.h index 3770dd3..ac968a9 100644 --- a/third_party/libvpx/source/config/mac/ia32/vp9_rtcd.h +++ b/third_party/libvpx/source/config/mac/ia32/vp9_rtcd.h
@@ -30,7 +30,8 @@ #endif int64_t vp9_block_error_c(const tran_low_t *coeff, const tran_low_t *dqcoeff, intptr_t block_size, int64_t *ssz); -#define vp9_block_error vp9_block_error_c +int64_t vp9_block_error_avx2(const tran_low_t *coeff, const tran_low_t *dqcoeff, intptr_t block_size, int64_t *ssz); +RTCD_EXTERN int64_t (*vp9_block_error)(const tran_low_t *coeff, const tran_low_t *dqcoeff, intptr_t block_size, int64_t *ssz); int64_t vp9_block_error_fp_c(const tran_low_t *coeff, const tran_low_t *dqcoeff, int block_size); int64_t vp9_block_error_fp_sse2(const tran_low_t *coeff, const tran_low_t *dqcoeff, int block_size); @@ -138,7 +139,8 @@ RTCD_EXTERN void (*vp9_iht8x8_64_add)(const tran_low_t *input, uint8_t *dest, int stride, int tx_type); void vp9_quantize_fp_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan); -#define vp9_quantize_fp vp9_quantize_fp_c +void vp9_quantize_fp_sse2(const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan); +RTCD_EXTERN void (*vp9_quantize_fp)(const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan); void vp9_quantize_fp_32x32_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan); #define vp9_quantize_fp_32x32 vp9_quantize_fp_32x32_c @@ -157,6 +159,8 @@ (void)flags; + vp9_block_error = vp9_block_error_c; + if (flags & HAS_AVX2) vp9_block_error = vp9_block_error_avx2; vp9_block_error_fp = vp9_block_error_fp_c; if (flags & HAS_SSE2) vp9_block_error_fp = vp9_block_error_fp_sse2; vp9_denoiser_filter = vp9_denoiser_filter_c; @@ -191,6 +195,8 @@ if (flags & HAS_SSE2) vp9_iht4x4_16_add = vp9_iht4x4_16_add_sse2; vp9_iht8x8_64_add = vp9_iht8x8_64_add_c; if (flags & HAS_SSE2) vp9_iht8x8_64_add = vp9_iht8x8_64_add_sse2; + vp9_quantize_fp = vp9_quantize_fp_c; + if (flags & HAS_SSE2) vp9_quantize_fp = vp9_quantize_fp_sse2; vp9_temporal_filter_apply = vp9_temporal_filter_apply_c; if (flags & HAS_SSE2) vp9_temporal_filter_apply = vp9_temporal_filter_apply_sse2; }
diff --git a/third_party/libvpx/source/config/mac/ia32/vpx_dsp_rtcd.h b/third_party/libvpx/source/config/mac/ia32/vpx_dsp_rtcd.h index 727a39e..20ab4d2 100644 --- a/third_party/libvpx/source/config/mac/ia32/vpx_dsp_rtcd.h +++ b/third_party/libvpx/source/config/mac/ia32/vpx_dsp_rtcd.h
@@ -1095,6 +1095,10 @@ void vpx_highbd_idct16x16_256_add_sse2(const tran_low_t *input, uint8_t *dest, int stride, int bd); RTCD_EXTERN void (*vpx_highbd_idct16x16_256_add)(const tran_low_t *input, uint8_t *dest, int stride, int bd); +void vpx_highbd_idct16x16_38_add_c(const tran_low_t *input, uint8_t *dest, int stride, int bd); +void vpx_highbd_idct16x16_256_add_sse2(const tran_low_t *input, uint8_t *dest, int stride, int bd); +RTCD_EXTERN void (*vpx_highbd_idct16x16_38_add)(const tran_low_t *input, uint8_t *dest, int stride, int bd); + void vpx_highbd_idct32x32_1024_add_c(const tran_low_t *input, uint8_t *dest, int stride, int bd); #define vpx_highbd_idct32x32_1024_add vpx_highbd_idct32x32_1024_add_c @@ -2443,6 +2447,8 @@ if (flags & HAS_SSE2) vpx_highbd_idct16x16_10_add = vpx_highbd_idct16x16_10_add_sse2; vpx_highbd_idct16x16_256_add = vpx_highbd_idct16x16_256_add_c; if (flags & HAS_SSE2) vpx_highbd_idct16x16_256_add = vpx_highbd_idct16x16_256_add_sse2; + vpx_highbd_idct16x16_38_add = vpx_highbd_idct16x16_38_add_c; + if (flags & HAS_SSE2) vpx_highbd_idct16x16_38_add = vpx_highbd_idct16x16_256_add_sse2; vpx_highbd_idct32x32_1_add = vpx_highbd_idct32x32_1_add_c; if (flags & HAS_SSE2) vpx_highbd_idct32x32_1_add = vpx_highbd_idct32x32_1_add_sse2; vpx_highbd_idct4x4_16_add = vpx_highbd_idct4x4_16_add_c;
diff --git a/third_party/libvpx/source/config/mac/x64/vp9_rtcd.h b/third_party/libvpx/source/config/mac/x64/vp9_rtcd.h index f8c2110..b102039 100644 --- a/third_party/libvpx/source/config/mac/x64/vp9_rtcd.h +++ b/third_party/libvpx/source/config/mac/x64/vp9_rtcd.h
@@ -30,7 +30,8 @@ #endif int64_t vp9_block_error_c(const tran_low_t *coeff, const tran_low_t *dqcoeff, intptr_t block_size, int64_t *ssz); -#define vp9_block_error vp9_block_error_c +int64_t vp9_block_error_avx2(const tran_low_t *coeff, const tran_low_t *dqcoeff, intptr_t block_size, int64_t *ssz); +RTCD_EXTERN int64_t (*vp9_block_error)(const tran_low_t *coeff, const tran_low_t *dqcoeff, intptr_t block_size, int64_t *ssz); int64_t vp9_block_error_fp_c(const tran_low_t *coeff, const tran_low_t *dqcoeff, int block_size); int64_t vp9_block_error_fp_sse2(const tran_low_t *coeff, const tran_low_t *dqcoeff, int block_size); @@ -138,10 +139,13 @@ #define vp9_iht8x8_64_add vp9_iht8x8_64_add_sse2 void vp9_quantize_fp_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan); -#define vp9_quantize_fp vp9_quantize_fp_c +void vp9_quantize_fp_sse2(const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan); +void vp9_quantize_fp_ssse3(const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan); +RTCD_EXTERN void (*vp9_quantize_fp)(const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan); void vp9_quantize_fp_32x32_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan); -#define vp9_quantize_fp_32x32 vp9_quantize_fp_32x32_c +void vp9_quantize_fp_32x32_ssse3(const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan); +RTCD_EXTERN void (*vp9_quantize_fp_32x32)(const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan); void vp9_temporal_filter_apply_c(uint8_t *frame1, unsigned int stride, uint8_t *frame2, unsigned int block_width, unsigned int block_height, int strength, int filter_weight, unsigned int *accumulator, uint16_t *count); void vp9_temporal_filter_apply_sse2(uint8_t *frame1, unsigned int stride, uint8_t *frame2, unsigned int block_width, unsigned int block_height, int strength, int filter_weight, unsigned int *accumulator, uint16_t *count); @@ -157,6 +161,8 @@ (void)flags; + vp9_block_error = vp9_block_error_c; + if (flags & HAS_AVX2) vp9_block_error = vp9_block_error_avx2; vp9_diamond_search_sad = vp9_diamond_search_sad_c; if (flags & HAS_AVX) vp9_diamond_search_sad = vp9_diamond_search_sad_avx; vp9_fdct8x8_quant = vp9_fdct8x8_quant_c; @@ -166,6 +172,10 @@ if (flags & HAS_SSE4_1) vp9_full_search_sad = vp9_full_search_sadx8; vp9_highbd_block_error_8bit = vp9_highbd_block_error_8bit_sse2; if (flags & HAS_AVX) vp9_highbd_block_error_8bit = vp9_highbd_block_error_8bit_avx; + vp9_quantize_fp = vp9_quantize_fp_sse2; + if (flags & HAS_SSSE3) vp9_quantize_fp = vp9_quantize_fp_ssse3; + vp9_quantize_fp_32x32 = vp9_quantize_fp_32x32_c; + if (flags & HAS_SSSE3) vp9_quantize_fp_32x32 = vp9_quantize_fp_32x32_ssse3; } #endif
diff --git a/third_party/libvpx/source/config/mac/x64/vpx_dsp_rtcd.h b/third_party/libvpx/source/config/mac/x64/vpx_dsp_rtcd.h index 9fbfef8f..ac714cab 100644 --- a/third_party/libvpx/source/config/mac/x64/vpx_dsp_rtcd.h +++ b/third_party/libvpx/source/config/mac/x64/vpx_dsp_rtcd.h
@@ -1102,6 +1102,10 @@ void vpx_highbd_idct16x16_256_add_sse2(const tran_low_t *input, uint8_t *dest, int stride, int bd); #define vpx_highbd_idct16x16_256_add vpx_highbd_idct16x16_256_add_sse2 +void vpx_highbd_idct16x16_38_add_c(const tran_low_t *input, uint8_t *dest, int stride, int bd); +void vpx_highbd_idct16x16_256_add_sse2(const tran_low_t *input, uint8_t *dest, int stride, int bd); +#define vpx_highbd_idct16x16_38_add vpx_highbd_idct16x16_256_add_sse2 + void vpx_highbd_idct32x32_1024_add_c(const tran_low_t *input, uint8_t *dest, int stride, int bd); #define vpx_highbd_idct32x32_1024_add vpx_highbd_idct32x32_1024_add_c
diff --git a/third_party/libvpx/source/config/nacl/vpx_dsp_rtcd.h b/third_party/libvpx/source/config/nacl/vpx_dsp_rtcd.h index 18f79e2..3f920cc2a4 100644 --- a/third_party/libvpx/source/config/nacl/vpx_dsp_rtcd.h +++ b/third_party/libvpx/source/config/nacl/vpx_dsp_rtcd.h
@@ -910,6 +910,9 @@ void vpx_highbd_idct16x16_256_add_c(const tran_low_t *input, uint8_t *dest, int stride, int bd); #define vpx_highbd_idct16x16_256_add vpx_highbd_idct16x16_256_add_c +void vpx_highbd_idct16x16_38_add_c(const tran_low_t *input, uint8_t *dest, int stride, int bd); +#define vpx_highbd_idct16x16_38_add vpx_highbd_idct16x16_38_add_c + void vpx_highbd_idct32x32_1024_add_c(const tran_low_t *input, uint8_t *dest, int stride, int bd); #define vpx_highbd_idct32x32_1024_add vpx_highbd_idct32x32_1024_add_c
diff --git a/third_party/libvpx/source/config/vpx_version.h b/third_party/libvpx/source/config/vpx_version.h index 8b6f918b..d38bf2ad 100644 --- a/third_party/libvpx/source/config/vpx_version.h +++ b/third_party/libvpx/source/config/vpx_version.h
@@ -1,7 +1,7 @@ #define VERSION_MAJOR 1 #define VERSION_MINOR 6 #define VERSION_PATCH 1 -#define VERSION_EXTRA "149-g91f87e751" +#define VERSION_EXTRA "235-g4d4231352" #define VERSION_PACKED ((VERSION_MAJOR<<16)|(VERSION_MINOR<<8)|(VERSION_PATCH)) -#define VERSION_STRING_NOSP "v1.6.1-149-g91f87e751" -#define VERSION_STRING " v1.6.1-149-g91f87e751" +#define VERSION_STRING_NOSP "v1.6.1-235-g4d4231352" +#define VERSION_STRING " v1.6.1-235-g4d4231352"
diff --git a/third_party/libvpx/source/config/win/ia32/vp9_rtcd.h b/third_party/libvpx/source/config/win/ia32/vp9_rtcd.h index 3770dd3..ac968a9 100644 --- a/third_party/libvpx/source/config/win/ia32/vp9_rtcd.h +++ b/third_party/libvpx/source/config/win/ia32/vp9_rtcd.h
@@ -30,7 +30,8 @@ #endif int64_t vp9_block_error_c(const tran_low_t *coeff, const tran_low_t *dqcoeff, intptr_t block_size, int64_t *ssz); -#define vp9_block_error vp9_block_error_c +int64_t vp9_block_error_avx2(const tran_low_t *coeff, const tran_low_t *dqcoeff, intptr_t block_size, int64_t *ssz); +RTCD_EXTERN int64_t (*vp9_block_error)(const tran_low_t *coeff, const tran_low_t *dqcoeff, intptr_t block_size, int64_t *ssz); int64_t vp9_block_error_fp_c(const tran_low_t *coeff, const tran_low_t *dqcoeff, int block_size); int64_t vp9_block_error_fp_sse2(const tran_low_t *coeff, const tran_low_t *dqcoeff, int block_size); @@ -138,7 +139,8 @@ RTCD_EXTERN void (*vp9_iht8x8_64_add)(const tran_low_t *input, uint8_t *dest, int stride, int tx_type); void vp9_quantize_fp_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan); -#define vp9_quantize_fp vp9_quantize_fp_c +void vp9_quantize_fp_sse2(const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan); +RTCD_EXTERN void (*vp9_quantize_fp)(const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan); void vp9_quantize_fp_32x32_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan); #define vp9_quantize_fp_32x32 vp9_quantize_fp_32x32_c @@ -157,6 +159,8 @@ (void)flags; + vp9_block_error = vp9_block_error_c; + if (flags & HAS_AVX2) vp9_block_error = vp9_block_error_avx2; vp9_block_error_fp = vp9_block_error_fp_c; if (flags & HAS_SSE2) vp9_block_error_fp = vp9_block_error_fp_sse2; vp9_denoiser_filter = vp9_denoiser_filter_c; @@ -191,6 +195,8 @@ if (flags & HAS_SSE2) vp9_iht4x4_16_add = vp9_iht4x4_16_add_sse2; vp9_iht8x8_64_add = vp9_iht8x8_64_add_c; if (flags & HAS_SSE2) vp9_iht8x8_64_add = vp9_iht8x8_64_add_sse2; + vp9_quantize_fp = vp9_quantize_fp_c; + if (flags & HAS_SSE2) vp9_quantize_fp = vp9_quantize_fp_sse2; vp9_temporal_filter_apply = vp9_temporal_filter_apply_c; if (flags & HAS_SSE2) vp9_temporal_filter_apply = vp9_temporal_filter_apply_sse2; }
diff --git a/third_party/libvpx/source/config/win/ia32/vpx_dsp_rtcd.h b/third_party/libvpx/source/config/win/ia32/vpx_dsp_rtcd.h index 727a39e..20ab4d2 100644 --- a/third_party/libvpx/source/config/win/ia32/vpx_dsp_rtcd.h +++ b/third_party/libvpx/source/config/win/ia32/vpx_dsp_rtcd.h
@@ -1095,6 +1095,10 @@ void vpx_highbd_idct16x16_256_add_sse2(const tran_low_t *input, uint8_t *dest, int stride, int bd); RTCD_EXTERN void (*vpx_highbd_idct16x16_256_add)(const tran_low_t *input, uint8_t *dest, int stride, int bd); +void vpx_highbd_idct16x16_38_add_c(const tran_low_t *input, uint8_t *dest, int stride, int bd); +void vpx_highbd_idct16x16_256_add_sse2(const tran_low_t *input, uint8_t *dest, int stride, int bd); +RTCD_EXTERN void (*vpx_highbd_idct16x16_38_add)(const tran_low_t *input, uint8_t *dest, int stride, int bd); + void vpx_highbd_idct32x32_1024_add_c(const tran_low_t *input, uint8_t *dest, int stride, int bd); #define vpx_highbd_idct32x32_1024_add vpx_highbd_idct32x32_1024_add_c @@ -2443,6 +2447,8 @@ if (flags & HAS_SSE2) vpx_highbd_idct16x16_10_add = vpx_highbd_idct16x16_10_add_sse2; vpx_highbd_idct16x16_256_add = vpx_highbd_idct16x16_256_add_c; if (flags & HAS_SSE2) vpx_highbd_idct16x16_256_add = vpx_highbd_idct16x16_256_add_sse2; + vpx_highbd_idct16x16_38_add = vpx_highbd_idct16x16_38_add_c; + if (flags & HAS_SSE2) vpx_highbd_idct16x16_38_add = vpx_highbd_idct16x16_256_add_sse2; vpx_highbd_idct32x32_1_add = vpx_highbd_idct32x32_1_add_c; if (flags & HAS_SSE2) vpx_highbd_idct32x32_1_add = vpx_highbd_idct32x32_1_add_sse2; vpx_highbd_idct4x4_16_add = vpx_highbd_idct4x4_16_add_c;
diff --git a/third_party/libvpx/source/config/win/x64/vp9_rtcd.h b/third_party/libvpx/source/config/win/x64/vp9_rtcd.h index f8c2110..b102039 100644 --- a/third_party/libvpx/source/config/win/x64/vp9_rtcd.h +++ b/third_party/libvpx/source/config/win/x64/vp9_rtcd.h
@@ -30,7 +30,8 @@ #endif int64_t vp9_block_error_c(const tran_low_t *coeff, const tran_low_t *dqcoeff, intptr_t block_size, int64_t *ssz); -#define vp9_block_error vp9_block_error_c +int64_t vp9_block_error_avx2(const tran_low_t *coeff, const tran_low_t *dqcoeff, intptr_t block_size, int64_t *ssz); +RTCD_EXTERN int64_t (*vp9_block_error)(const tran_low_t *coeff, const tran_low_t *dqcoeff, intptr_t block_size, int64_t *ssz); int64_t vp9_block_error_fp_c(const tran_low_t *coeff, const tran_low_t *dqcoeff, int block_size); int64_t vp9_block_error_fp_sse2(const tran_low_t *coeff, const tran_low_t *dqcoeff, int block_size); @@ -138,10 +139,13 @@ #define vp9_iht8x8_64_add vp9_iht8x8_64_add_sse2 void vp9_quantize_fp_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan); -#define vp9_quantize_fp vp9_quantize_fp_c +void vp9_quantize_fp_sse2(const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan); +void vp9_quantize_fp_ssse3(const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan); +RTCD_EXTERN void (*vp9_quantize_fp)(const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan); void vp9_quantize_fp_32x32_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan); -#define vp9_quantize_fp_32x32 vp9_quantize_fp_32x32_c +void vp9_quantize_fp_32x32_ssse3(const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan); +RTCD_EXTERN void (*vp9_quantize_fp_32x32)(const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan); void vp9_temporal_filter_apply_c(uint8_t *frame1, unsigned int stride, uint8_t *frame2, unsigned int block_width, unsigned int block_height, int strength, int filter_weight, unsigned int *accumulator, uint16_t *count); void vp9_temporal_filter_apply_sse2(uint8_t *frame1, unsigned int stride, uint8_t *frame2, unsigned int block_width, unsigned int block_height, int strength, int filter_weight, unsigned int *accumulator, uint16_t *count); @@ -157,6 +161,8 @@ (void)flags; + vp9_block_error = vp9_block_error_c; + if (flags & HAS_AVX2) vp9_block_error = vp9_block_error_avx2; vp9_diamond_search_sad = vp9_diamond_search_sad_c; if (flags & HAS_AVX) vp9_diamond_search_sad = vp9_diamond_search_sad_avx; vp9_fdct8x8_quant = vp9_fdct8x8_quant_c; @@ -166,6 +172,10 @@ if (flags & HAS_SSE4_1) vp9_full_search_sad = vp9_full_search_sadx8; vp9_highbd_block_error_8bit = vp9_highbd_block_error_8bit_sse2; if (flags & HAS_AVX) vp9_highbd_block_error_8bit = vp9_highbd_block_error_8bit_avx; + vp9_quantize_fp = vp9_quantize_fp_sse2; + if (flags & HAS_SSSE3) vp9_quantize_fp = vp9_quantize_fp_ssse3; + vp9_quantize_fp_32x32 = vp9_quantize_fp_32x32_c; + if (flags & HAS_SSSE3) vp9_quantize_fp_32x32 = vp9_quantize_fp_32x32_ssse3; } #endif
diff --git a/third_party/libvpx/source/config/win/x64/vpx_dsp_rtcd.h b/third_party/libvpx/source/config/win/x64/vpx_dsp_rtcd.h index 9fbfef8f..ac714cab 100644 --- a/third_party/libvpx/source/config/win/x64/vpx_dsp_rtcd.h +++ b/third_party/libvpx/source/config/win/x64/vpx_dsp_rtcd.h
@@ -1102,6 +1102,10 @@ void vpx_highbd_idct16x16_256_add_sse2(const tran_low_t *input, uint8_t *dest, int stride, int bd); #define vpx_highbd_idct16x16_256_add vpx_highbd_idct16x16_256_add_sse2 +void vpx_highbd_idct16x16_38_add_c(const tran_low_t *input, uint8_t *dest, int stride, int bd); +void vpx_highbd_idct16x16_256_add_sse2(const tran_low_t *input, uint8_t *dest, int stride, int bd); +#define vpx_highbd_idct16x16_38_add vpx_highbd_idct16x16_256_add_sse2 + void vpx_highbd_idct32x32_1024_add_c(const tran_low_t *input, uint8_t *dest, int stride, int bd); #define vpx_highbd_idct32x32_1024_add vpx_highbd_idct32x32_1024_add_c
diff --git a/tools/cr/OWNERS b/tools/cr/OWNERS index fa6851a..852aadf 100644 --- a/tools/cr/OWNERS +++ b/tools/cr/OWNERS
@@ -1,3 +1,5 @@ miguelg@chromium.org petrcermak@chromium.org skyostil@chromium.org + +# COMPONENT: Tools
diff --git a/tools/gn/analyzer.cc b/tools/gn/analyzer.cc index 06f9336..559287ef 100644 --- a/tools/gn/analyzer.cc +++ b/tools/gn/analyzer.cc
@@ -51,13 +51,13 @@ LabelSet LabelsFor(const TargetSet& targets) { LabelSet labels; - for (const auto& target : targets) + for (auto* target : targets) labels.insert(target->label()); return labels; } bool AnyBuildFilesWereModified(const SourceFileSet& source_files) { - for (const auto& file : source_files) { + for (auto* file : source_files) { if (base::EndsWith(file->value(), ".gn", base::CompareCase::SENSITIVE) || base::EndsWith(file->value(), ".gni", base::CompareCase::SENSITIVE)) return true; @@ -287,7 +287,7 @@ TargetSet compile_targets = TargetsFor(inputs.compile_labels); if (inputs.compile_included_all) { - for (auto& root : roots_) + for (auto* root : roots_) compile_targets.insert(root); } TargetSet filtered_targets = Filter(compile_targets); @@ -307,10 +307,10 @@ TargetSet Analyzer::AllAffectedTargets( const SourceFileSet& source_files) const { TargetSet direct_matches; - for (const auto& source_file : source_files) + for (auto* source_file : source_files) AddTargetsDirectlyReferringToFileTo(source_file, &direct_matches); TargetSet all_matches; - for (const auto& match : direct_matches) + for (auto* match : direct_matches) AddAllRefsTo(match, &all_matches); return all_matches; } @@ -392,7 +392,7 @@ void Analyzer::AddTargetsDirectlyReferringToFileTo(const SourceFile* file, TargetSet* matches) const { - for (const auto& target : all_targets_) { + for (auto* target : all_targets_) { // Only handles targets in the default toolchain. if ((target->label().GetToolchainLabel() == default_toolchain_) && TargetRefersToFile(target, file))
diff --git a/tools/gn/import_manager.cc b/tools/gn/import_manager.cc index 0213c33..c9a44d4 100644 --- a/tools/gn/import_manager.cc +++ b/tools/gn/import_manager.cc
@@ -111,7 +111,7 @@ base::TimeDelta::FromMilliseconds(20); if (TracingEnabled() && import_block_end - import_block_begin > kImportBlockTraceThreshold) { - auto import_block_trace = + auto* import_block_trace = new TraceItem(TraceItem::TRACE_IMPORT_BLOCK, file.value(), base::PlatformThread::CurrentId()); import_block_trace->set_begin(import_block_begin);
diff --git a/tools/grit/grit/format/html_inline.py b/tools/grit/grit/format/html_inline.py index 9e5ec6a8..3c8e21b 100755 --- a/tools/grit/grit/format/html_inline.py +++ b/tools/grit/grit/format/html_inline.py
@@ -48,7 +48,23 @@ '(\s*</include>)?', re.DOTALL) _SRC_RE = lazy_re.compile( - r'<(?!script)(?:[^>]+?\s)src=(?P<quote>")(?!\[\[|{{)(?P<filename>[^"\']*)\1', + r'<(?!script)(?:[^>]+?\s)src="(?!\[\[|{{)(?P<filename>[^"\']*)"', + re.MULTILINE) +# This re matches '<img srcset="..."' +_SRCSET_RE = lazy_re.compile( + r'<img\b(?:[^>]*?\s)srcset="(?!\[\[|{{)(?P<srcset>[^"\']*)"', + re.MULTILINE) +# This re is for splitting srcset value string into "image candidate strings". +# Notes: +# - HTML 5.2 states that URL cannot start with comma. +# - the "descriptor" is either "width descriptor" or "pixel density descriptor". +# The first one consists of "valid non-negative integer + letter 'x'", +# the second one is formed of "positive valid floating-point number + +# letter 'w'". As a reasonable compromise, we match a list of characters +# that form both of them. +# Matches for example "img2.png 2x" or "img9.png 11E-2w". +_SRCSET_ENTRY_RE = lazy_re.compile( + r'\s*(?P<url>[^,]\S+)\s+(?P<descriptor>[\deE.-]+[wx])\s*', re.MULTILINE) _ICON_RE = lazy_re.compile( r'<link rel="icon"\s(?:[^>]+?\s)?' @@ -69,20 +85,17 @@ distribution = distribution[1:].lower() return distribution +def ConvertFileToDataURL(filename, base_path, distribution, inlined_files, + names_only): + """Convert filename to inlined data URI. -def SrcInlineAsDataURL( - src_match, base_path, distribution, inlined_files, names_only=False, - filename_expansion_function=None): - """regex replace function. - - Takes a regex match for src="filename", attempts to read the file - at 'filename' and returns the src attribute with the file inlined - as a data URI. If it finds DIST_SUBSTR string in file name, replaces - it with distribution. + Takes a filename from ether "src" or "srcset", and attempts to read the file + at 'filename'. Returns data URI as string with given file inlined. + If it finds DIST_SUBSTR string in file name, replaces it with distribution. + If filename contains ':', it is considered URL and not translated. Args: - src_match: regex match object with 'filename' and 'quote' named capturing - groups + filename: filename string from ether src or srcset attributes. base_path: path that to look for files in distribution: string that should replace DIST_SUBSTR inlined_files: The name of the opened file is appended to this list. @@ -92,14 +105,9 @@ Returns: string """ - filename = src_match.group('filename') - if filename_expansion_function: - filename = filename_expansion_function(filename) - quote = src_match.group('quote') - if filename.find(':') != -1: # filename is probably a URL, which we don't want to bother inlining - return src_match.group(0) + return filename filename = filename.replace(DIST_SUBSTR , distribution) filepath = os.path.normpath(os.path.join(base_path, filename)) @@ -113,11 +121,122 @@ raise Exception('%s is of an an unknown type and ' 'cannot be stored in a data url.' % filename) inline_data = base64.standard_b64encode(util.ReadFile(filepath, util.BINARY)) + return 'data:%s;base64,%s' % (mimetype, inline_data) + + +def SrcInlineAsDataURL( + src_match, base_path, distribution, inlined_files, names_only=False, + filename_expansion_function=None): + """regex replace function. + + Takes a regex match for src="filename", attempts to read the file + at 'filename' and returns the src attribute with the file inlined + as a data URI. If it finds DIST_SUBSTR string in file name, replaces + it with distribution. + + Args: + src_match: regex match object with 'filename' named capturing group + base_path: path that to look for files in + distribution: string that should replace DIST_SUBSTR + inlined_files: The name of the opened file is appended to this list. + names_only: If true, the function will not read the file but just return "". + It will still add the filename to |inlined_files|. + + Returns: + string + """ + filename = src_match.group('filename') + if filename_expansion_function: + filename = filename_expansion_function(filename) + + data_url = ConvertFileToDataURL(filename, base_path, distribution, + inlined_files, names_only) + + if not data_url: + return data_url prefix = src_match.string[src_match.start():src_match.start('filename')] suffix = src_match.string[src_match.end('filename'):src_match.end()] - return '%sdata:%s;base64,%s%s' % (prefix, mimetype, inline_data, suffix) + return prefix + data_url + suffix +def SrcsetInlineAsDataURL( + srcset_match, base_path, distribution, inlined_files, names_only=False, + filename_expansion_function=None): + """regex replace function to inline files in srcset="..." attributes + + Takes a regex match for srcset="filename 1x, filename 2x, ...", attempts to + read the files referenced by filenames and returns the srcset attribute with + the files inlined as a data URI. If it finds DIST_SUBSTR string in file name, + replaces it with distribution. + + Args: + srcset_match: regex match object with 'srcset' named capturing group + base_path: path that to look for files in + distribution: string that should replace DIST_SUBSTR + inlined_files: The name of the opened file is appended to this list. + names_only: If true, the function will not read the file but just return "". + It will still add the filename to |inlined_files|. + + Returns: + string + """ + srcset = srcset_match.group('srcset') + + if not srcset: + return srcset_match.group(0) + + # HTML 5.2 defines srcset as a list of "image candidate strings". + # Each of them consists of URL and descriptor. + # _SRCSET_ENTRY_RE splits srcset into a list of URLs, descriptors and + # commas. + parts = _SRCSET_ENTRY_RE.split(srcset) + + if not parts: + return srcset_match.group(0) + + # List of image candidate strings that will form new srcset="..." + new_candidates = [] + + # When iterating over split srcset we fill this parts of a single image + # candidate string: [url, descriptor] + candidate = []; + + for part in parts: + if not part: + continue + + if part == ',': + # There must be no URL without a descriptor. + assert not candidate, "Bad srcset format in '%s'" % srcset_match.group(0) + continue + + if candidate: + # descriptor found + if candidate[0]: + # This is not "names_only" mode. + candidate.append(part) + new_candidates.append(" ".join(candidate)) + + candidate = [] + continue + + if filename_expansion_function: + filename = filename_expansion_function(part) + else: + filename = part + + data_url = ConvertFileToDataURL(filename, base_path, distribution, + inlined_files, names_only) + + candidate.append(data_url) + + # There must be no URL without a descriptor + assert not candidate, "Bad srcset ending in '%s' " % srcset_match.group(0) + + prefix = srcset_match.string[srcset_match.start(): + srcset_match.start('srcset')] + suffix = srcset_match.string[srcset_match.end('srcset'):srcset_match.end()] + return prefix + ','.join(new_candidates) + suffix class InlinedData: """Helper class holding the results from DoInline(). @@ -168,6 +287,16 @@ src_match, filepath, distribution, inlined_files, names_only=names_only, filename_expansion_function=filename_expansion_function) + def SrcsetReplace(srcset_match, filepath=input_filepath, + inlined_files=inlined_files): + """Helper function to provide SrcsetInlineAsDataURL with the base file + path. + """ + return SrcsetInlineAsDataURL( + srcset_match, filepath, distribution, inlined_files, + names_only=names_only, + filename_expansion_function=filename_expansion_function) + def GetFilepath(src_match, base_path = input_filepath): matches = src_match.groupdict().iteritems() filename = [v for k, v in matches if k.startswith('file') and v][0] @@ -369,6 +498,7 @@ if rewrite_function: flat_text = rewrite_function(input_filepath, flat_text, distribution) flat_text = _SRC_RE.sub(SrcReplace, flat_text) + flat_text = _SRCSET_RE.sub(SrcsetReplace, flat_text) # TODO(arv): Only do this inside <style> tags. flat_text = InlineCSSImages(flat_text)
diff --git a/tools/grit/grit/format/html_inline_unittest.py b/tools/grit/grit/format/html_inline_unittest.py index d049b1ef..062296c 100755 --- a/tools/grit/grit/format/html_inline_unittest.py +++ b/tools/grit/grit/format/html_inline_unittest.py
@@ -506,6 +506,60 @@ self.failUnlessEqual(expected_inlined, util.FixLineEnd(result.inlined_data, '\n')) + def testImgSrcset(self): + '''Tests that img srcset="" attributes are converted.''' + + # Note that there is no space before "img10.png" + files = { + 'index.html': ''' + <html> + <img src="img1.png" srcset="img2.png 1x, img3.png 2x"> + <img src="img4.png" srcset=" img5.png 1x , img6.png 2x "> + <img src="chrome://theme/img11.png" srcset="img7.png 1x, '''\ + '''chrome://theme/img13.png 2x"> + <img srcset="img8.png 300w, img9.png 11E-2w,img10.png -1e2w"> + </html> + ''', + 'img1.png': '''a1''', + 'img2.png': '''a2''', + 'img3.png': '''a3''', + 'img4.png': '''a4''', + 'img5.png': '''a5''', + 'img6.png': '''a6''', + 'img7.png': '''a7''', + 'img8.png': '''a8''', + 'img9.png': '''a9''', + 'img10.png': '''a10''', + } + + expected_inlined = ''' + <html> + <img src="data:image/png;base64,YTE=" srcset="data:image/png;base64,'''\ + '''YTI= 1x,data:image/png;base64,YTM= 2x"> + <img src="data:image/png;base64,YTQ=" srcset="data:image/png;base64,'''\ + '''YTU= 1x,data:image/png;base64,YTY= 2x"> + <img src="chrome://theme/img11.png" srcset="data:image/png;base64,'''\ + '''YTc= 1x,chrome://theme/img13.png 2x"> + <img srcset="data:image/png;base64,YTg= 300w,data:image/png;base64,'''\ + '''YTk= 11E-2w,data:image/png;base64,YTEw -1e2w"> + </html> + ''' + + source_resources = set() + tmp_dir = util.TempDir(files) + for filename in files: + source_resources.add(tmp_dir.GetPath(filename)) + + # Test normal inlining. + result = html_inline.DoInline( + tmp_dir.GetPath('index.html'), + None) + resources = result.inlined_files + resources.add(tmp_dir.GetPath('index.html')) + self.failUnlessEqual(resources, source_resources) + self.failUnlessEqual(expected_inlined, + util.FixLineEnd(result.inlined_data, '\n')) + if __name__ == '__main__': unittest.main()
diff --git a/tools/ipc_fuzzer/message_replay/replay_process.cc b/tools/ipc_fuzzer/message_replay/replay_process.cc index d69f9c1..f812995 100644 --- a/tools/ipc_fuzzer/message_replay/replay_process.cc +++ b/tools/ipc_fuzzer/message_replay/replay_process.cc
@@ -11,7 +11,6 @@ #include "base/command_line.h" #include "base/files/file_path.h" #include "base/logging.h" -#include "base/posix/global_descriptors.h" #include "base/run_loop.h" #include "build/build_config.h" #include "chrome/common/chrome_switches.h" @@ -24,6 +23,7 @@ #include "mojo/edk/embedder/scoped_ipc_support.h" #if defined(OS_POSIX) +#include "base/posix/global_descriptors.h" #include "content/public/common/content_descriptors.h" #endif
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 10a462f..6ffdf566 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -58641,6 +58641,17 @@ </summary> </histogram> +<histogram name="SBDownloadFeedback.UploadRequestedByServer" + enum="DownloadUploadRequestedByServer"> + <owner>nparker@chromium.org</owner> + <summary> + For each non-SAFE file, records whether the server requested that that file + be uploaded. + + Logged before checking the file size, so it may be dropped there. + </summary> +</histogram> + <histogram name="SBDownloadFeedback.UploadResult" enum="SBDownloadFeedbackUploadResult"> <owner>mattm@chromium.org</owner> @@ -85997,6 +86008,11 @@ <int value="6" label="Initiated by Automatic Resumption"/> </enum> +<enum name="DownloadUploadRequestedByServer" type="int"> + <int value="0" label="No Upload"/> + <int value="1" label="Upload Requested"/> +</enum> + <enum name="DragDropEventSource" type="int"> <int value="0" label="Mouse"/> <int value="1" label="Touch"/>
diff --git a/tools/perf/OWNERS b/tools/perf/OWNERS index ac6816ed..596f984 100644 --- a/tools/perf/OWNERS +++ b/tools/perf/OWNERS
@@ -23,3 +23,6 @@ # petrcermak@chromium.org # qyearsley@chromium.org # tonyg@chromium.org + +# TEAM: benchmarking-dev@chromium.org +# COMPONENT: Speed>Benchmarking
diff --git a/ui/android/BUILD.gn b/ui/android/BUILD.gn index bc9223a5..243e57f 100644 --- a/ui/android/BUILD.gn +++ b/ui/android/BUILD.gn
@@ -42,10 +42,6 @@ "ui_android_jni_registrar.h", "view_android.cc", "view_android.h", - "view_client.cc", - "view_client.h", - "view_root.cc", - "view_root.h", "window_android.cc", "window_android.h", "window_android_compositor.h", @@ -85,7 +81,6 @@ sources = [ "java/src/org/chromium/ui/OverscrollRefreshHandler.java", "java/src/org/chromium/ui/base/ViewAndroidDelegate.java", - "java/src/org/chromium/ui/base/ViewRoot.java", "java/src/org/chromium/ui/base/WindowAndroid.java", "java/src/org/chromium/ui/display/DisplayAndroidManager.java", "java/src/org/chromium/ui/resources/ResourceManager.java", @@ -181,7 +176,6 @@ "java/src/org/chromium/ui/base/SelectFileDialog.java", "java/src/org/chromium/ui/base/TouchDevice.java", "java/src/org/chromium/ui/base/ViewAndroidDelegate.java", - "java/src/org/chromium/ui/base/ViewRoot.java", "java/src/org/chromium/ui/base/WindowAndroid.java", "java/src/org/chromium/ui/display/DisplayAndroid.java", "java/src/org/chromium/ui/display/DisplayAndroidManager.java", @@ -252,7 +246,6 @@ "overscroll_refresh_unittest.cc", "resources/resource_manager_impl_unittest.cc", "run_all_unittests.cc", - "view_android_unittest.cc", ] deps = [ ":android",
diff --git a/ui/android/java/src/org/chromium/ui/base/ViewRoot.java b/ui/android/java/src/org/chromium/ui/base/ViewRoot.java deleted file mode 100644 index 291c3af..0000000 --- a/ui/android/java/src/org/chromium/ui/base/ViewRoot.java +++ /dev/null
@@ -1,104 +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. - -package org.chromium.ui.base; - -import android.view.MotionEvent; - -import org.chromium.base.annotations.JNINamespace; - -/** - * Class used to forward view, input events down to native. - * TODO(jinsukkim): Hook this up to UI event forwarding flow and substitute WindowAndroid. - */ -@JNINamespace("ui") -public class ViewRoot { - - private final WindowAndroid mWindowAndroid; - - // The corresponding native instance. This class can only be used while - // the native instance is alive. - // This is initialized lazily. Use {@link getNativePtr()} rather than - // accessing it directly. - private long mNativeView; - - public static ViewRoot create(WindowAndroid window) { - if (window == null) throw new IllegalArgumentException("WindowAndroid should not be null"); - return new ViewRoot(window); - } - - private ViewRoot(WindowAndroid window) { - mWindowAndroid = window; - } - - public WindowAndroid getWindowAndroid() { - return mWindowAndroid; - } - - public boolean onTouchEvent(MotionEvent event, boolean isTouchHandleEvent) { - final int pointerCount = event.getPointerCount(); - - float[] touchMajor = {event.getTouchMajor(), - pointerCount > 1 ? event.getTouchMajor(1) : 0}; - float[] touchMinor = {event.getTouchMinor(), - pointerCount > 1 ? event.getTouchMinor(1) : 0}; - - for (int i = 0; i < 2; i++) { - if (touchMajor[i] < touchMinor[i]) { - float tmp = touchMajor[i]; - touchMajor[i] = touchMinor[i]; - touchMinor[i] = tmp; - } - } - - return nativeOnTouchEvent(getNativePtr(), event, - event.getEventTime(), event.getActionMasked(), - pointerCount, event.getHistorySize(), event.getActionIndex(), - event.getX(), event.getY(), - pointerCount > 1 ? event.getX(1) : 0, - pointerCount > 1 ? event.getY(1) : 0, - event.getPointerId(0), pointerCount > 1 ? event.getPointerId(1) : -1, - touchMajor[0], touchMajor[1], - touchMinor[0], touchMinor[1], - event.getOrientation(), pointerCount > 1 ? event.getOrientation(1) : 0, - event.getAxisValue(MotionEvent.AXIS_TILT), - pointerCount > 1 ? event.getAxisValue(MotionEvent.AXIS_TILT, 1) : 0, - event.getRawX(), event.getRawY(), - event.getToolType(0), - pointerCount > 1 ? event.getToolType(1) : MotionEvent.TOOL_TYPE_UNKNOWN, - event.getButtonState(), - event.getMetaState(), - isTouchHandleEvent); - } - - public long getNativePtr() { - if (mNativeView == 0) mNativeView = nativeInit(mWindowAndroid.getNativePointer()); - return mNativeView; - } - - public void destroy() { - if (mNativeView != 0) { - nativeDestroy(mNativeView); - mNativeView = 0; - } - } - - private native long nativeInit(long windowNativePointer); - private native void nativeDestroy(long nativeViewRoot); - - // All touch events (including flings, scrolls etc) accept coordinates in physical pixels. - private native boolean nativeOnTouchEvent( - long nativeViewRoot, MotionEvent event, - long timeMs, int action, int pointerCount, int historySize, int actionIndex, - float x0, float y0, float x1, float y1, - int pointerId0, int pointerId1, - float touchMajor0, float touchMajor1, - float touchMinor0, float touchMinor1, - float orientation0, float orientation1, - float tilt0, float tilt1, - float rawX, float rawY, - int androidToolType0, int androidToolType1, - int androidButtonState, int androidMetaState, - boolean isTouchHandleEvent); -}
diff --git a/ui/android/ui_android_jni_registrar.cc b/ui/android/ui_android_jni_registrar.cc index 1534cd5..3c02c50 100644 --- a/ui/android/ui_android_jni_registrar.cc +++ b/ui/android/ui_android_jni_registrar.cc
@@ -10,7 +10,6 @@ #include "ui/android/resources/resource_manager_impl.h" #include "ui/android/screen_android.h" #include "ui/android/view_android.h" -#include "ui/android/view_root.h" #include "ui/android/window_android.h" namespace ui { @@ -18,7 +17,6 @@ static base::android::RegistrationMethod kAndroidRegisteredMethods[] = { {"DisplayAndroidManager", ui::RegisterScreenAndroid}, {"ResourceManager", ui::ResourceManagerImpl::RegisterResourceManager}, - {"ViewRoot", ui::RegisterViewRoot}, {"WindowAndroid", WindowAndroid::RegisterWindowAndroid}, };
diff --git a/ui/android/view_android.cc b/ui/android/view_android.cc index 43f084f..251c165 100644 --- a/ui/android/view_android.cc +++ b/ui/android/view_android.cc
@@ -18,7 +18,6 @@ using base::android::JavaRef; using base::android::ScopedJavaLocalRef; -// ViewAndroid::ScopedAndroidView ViewAndroid::ScopedAnchorView::ScopedAnchorView( JNIEnv* env, const JavaRef<jobject>& jview, @@ -69,65 +68,43 @@ return view_.get(env); } -// ViewAndroid -ViewAndroid::ViewAndroid(ViewClient* client) : parent_(nullptr), - client_(client) {} -ViewAndroid::ViewAndroid() : ViewAndroid(nullptr) {} +ViewAndroid::ViewAndroid(const JavaRef<jobject>& delegate) + : parent_(nullptr), + delegate_(base::android::AttachCurrentThread(), delegate.obj()) {} + +ViewAndroid::ViewAndroid() : parent_(nullptr) {} ViewAndroid::~ViewAndroid() { RemoveFromParent(); - auto children_copy = std::list<ViewAndroid*>(children_); - for (auto& child : children_copy) - RemoveChild(child); + for (std::list<ViewAndroid*>::iterator it = children_.begin(); + it != children_.end(); it++) { + DCHECK_EQ((*it)->parent_, this); + (*it)->parent_ = nullptr; + } } void ViewAndroid::SetDelegate(const JavaRef<jobject>& delegate) { - // A ViewAndroid may have its own delegate or otherwise will - // use the next available parent's delegate. JNIEnv* env = base::android::AttachCurrentThread(); delegate_ = JavaObjectWeakGlobalRef(env, delegate); } void ViewAndroid::AddChild(ViewAndroid* child) { DCHECK(child); - DCHECK(!child->IsViewRoot()); // ViewRoot cannot be a child. DCHECK(std::find(children_.begin(), children_.end(), child) == children_.end()); - // The new child goes to the top, which is the end of the list. children_.push_back(child); if (child->parent_) child->RemoveFromParent(); child->parent_ = this; } -void ViewAndroid::MoveToTop(ViewAndroid* child) { - DCHECK(child); - auto it = std::find(children_.begin(), children_.end(), child); - DCHECK(it != children_.end()); - - // Top element is placed at the end of the list. - if (*it != children_.back()) - children_.splice(children_.rbegin().base(), children_, it); -} - void ViewAndroid::RemoveFromParent() { if (parent_) parent_->RemoveChild(this); } -void ViewAndroid::SetLayout(int x, - int y, - int width, - int height, - bool match_parent) { - DCHECK(!match_parent || (x == 0 && y == 0 && width == 0 && height == 0)); - origin_.SetPoint(x, y); - size_.SetSize(width, height); - match_parent_ = match_parent; -} - ViewAndroid::ScopedAnchorView ViewAndroid::AcquireAnchorView() { ScopedJavaLocalRef<jobject> delegate(GetViewAndroidDelegate()); if (delegate.is_null()) @@ -138,19 +115,15 @@ env, Java_ViewAndroidDelegate_acquireView(env, delegate), delegate); } -float ViewAndroid::GetDipScale() { - return display::Screen::GetScreen() - ->GetDisplayNearestWindow(this) - .device_scale_factor(); -} - void ViewAndroid::SetAnchorRect(const JavaRef<jobject>& anchor, const gfx::RectF& bounds) { ScopedJavaLocalRef<jobject> delegate(GetViewAndroidDelegate()); if (delegate.is_null()) return; - float scale = GetDipScale(); + float scale = display::Screen::GetScreen() + ->GetDisplayNearestWindow(this) + .device_scale_factor(); int left_margin = std::round(bounds.x() * scale); int top_margin = std::round((content_offset().y() + bounds.y()) * scale); JNIEnv* env = base::android::AttachCurrentThread(); @@ -201,14 +174,6 @@ layer_ = layer; } -ViewAndroid* ViewAndroid::GetViewRoot() { - return parent_ ? parent_->GetViewRoot() : nullptr; -} - -bool ViewAndroid::IsViewRoot() { - return GetViewRoot() == this; -} - bool ViewAndroid::StartDragAndDrop(const JavaRef<jstring>& jtext, const JavaRef<jobject>& jimage) { ScopedJavaLocalRef<jobject> delegate(GetViewAndroidDelegate()); @@ -219,26 +184,4 @@ jimage); } -bool ViewAndroid::OnTouchEventInternal(const MotionEventData& event) { - if (!children_.empty()) { - const MotionEventData& e = - origin_.IsOrigin() ? event : event.Offset(-origin_.x(), -origin_.y()); - - for (auto it = children_.rbegin(); it != children_.rend(); ++it) { - bool matched = (*it)->match_parent_; - if (!matched) { - gfx::Rect bound((*it)->origin_, (*it)->size_); - matched = bound.Contains(e.GetX(), e.GetY()); - } - if (matched && (*it)->OnTouchEventInternal(e)) - return true; - } - } - - if (client_ && client_->OnTouchEvent(event)) - return true; - - return false; -} - } // namespace ui
diff --git a/ui/android/view_android.h b/ui/android/view_android.h index e446048..68adf34 100644 --- a/ui/android/view_android.h +++ b/ui/android/view_android.h
@@ -10,7 +10,6 @@ #include "base/android/jni_weak_ref.h" #include "base/memory/ref_counted.h" #include "ui/android/ui_android_export.h" -#include "ui/android/view_client.h" #include "ui/gfx/geometry/rect_f.h" namespace cc { @@ -23,8 +22,6 @@ // A simple container for a UI layer. // At the root of the hierarchy is a WindowAndroid, when attached. -// TODO(jinsukkim): Replace WindowAndroid with ViewRoot for the root of the -// view hierarchy. See https://crbug.com/671401 class UI_ANDROID_EXPORT ViewAndroid { public: // Stores an anchored view to delete itself at the end of its lifetime @@ -57,7 +54,9 @@ // Default copy/assign disabled by move constructor. }; - explicit ViewAndroid(ViewClient* client); + // A ViewAndroid may have its own delegate or otherwise will + // use the next available parent's delegate. + ViewAndroid(const base::android::JavaRef<jobject>& delegate); ViewAndroid(); virtual ~ViewAndroid(); @@ -76,29 +75,18 @@ // if disconnected. virtual WindowAndroid* GetWindowAndroid() const; - // Returns |ViewRoot| of this hierarchy. |null| if the hierarchy isn't - // attached to a |ViewRoot|. - virtual ViewAndroid* GetViewRoot(); - // Used to return and set the layer for this view. May be |null|. cc::Layer* GetLayer() const; void SetLayer(scoped_refptr<cc::Layer> layer); void SetDelegate(const base::android::JavaRef<jobject>& delegate); - // Adds a child to this view. + // Adds this view as a child of another view. void AddChild(ViewAndroid* child); - // Move the give child ViewAndroid to the top of the list - // so that it can be the first responder of events. - void MoveToTop(ViewAndroid* child); - // Detaches this view from its parent. void RemoveFromParent(); - // Set the layout relative to parent. Used to do hit testing against events. - void SetLayout(int x, int y, int width, int height, bool match_parent); - bool StartDragAndDrop(const base::android::JavaRef<jstring>& jtext, const base::android::JavaRef<jobject>& jimage); @@ -110,18 +98,9 @@ base::android::ScopedJavaLocalRef<jobject> GetContainerView(); protected: - // Internal implementation of ViewClient forwarding calls to the interface. - bool OnTouchEventInternal(const MotionEventData& event); - - // Virtual for testing. - virtual float GetDipScale(); - ViewAndroid* parent_; private: - // Returns true only if this is of type |ViewRoot|. - bool IsViewRoot(); - void RemoveChild(ViewAndroid* child); // Returns the Java delegate for this view. This is used to delegate work @@ -130,19 +109,10 @@ const base::android::ScopedJavaLocalRef<jobject> GetViewAndroidDelegate() const; - // The child view at the back of the list receives event first. std::list<ViewAndroid*> children_; scoped_refptr<cc::Layer> layer_; JavaObjectWeakGlobalRef delegate_; - ViewClient* const client_; - - // Basic view layout information. Used to do hit testing deciding whether - // the passed events should be processed by the view. - gfx::Point origin_; // In parent's coordinate space. - gfx::Size size_; - bool match_parent_; // Bounds matches that of the parent if true. - - gfx::Vector2dF content_offset_; // In CSS pixel. + gfx::Vector2dF content_offset_; // in CSS pixel DISALLOW_COPY_AND_ASSIGN(ViewAndroid); };
diff --git a/ui/android/view_android_unittest.cc b/ui/android/view_android_unittest.cc deleted file mode 100644 index e4500b5..0000000 --- a/ui/android/view_android_unittest.cc +++ /dev/null
@@ -1,167 +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 "testing/gtest/include/gtest/gtest.h" -#include "ui/android/view_root.h" - -namespace ui { - -using base::android::JavaParamRef; - -class TestViewRoot : public ViewRoot { - public: - TestViewRoot() : ViewRoot(0L) {} - float GetDipScale() override { return 1.f; } -}; - -class TestViewClient : public ViewClient { - public: - TestViewClient() : handle_event_(true), - called_(false) {} - - void SetHandleEvent(bool handle_event) { handle_event_ = handle_event; } - bool OnTouchEvent(const MotionEventData& event) override { - called_ = true; - return handle_event_; - } - - bool EventHandled() { return called_ && handle_event_; } - void Reset() { called_ = false; } - - private: - bool handle_event_; // Marks as event was consumed. True by default. - bool called_; -}; - -class ViewAndroidBoundsTest : public testing::Test { - public: - ViewAndroidBoundsTest() : view1_(&client1_), - view2_(&client2_), - view3_(&client3_) {} - void Reset() { - client1_.Reset(); - client2_.Reset(); - client3_.Reset(); - } - - void GenerateTouchEventAt(float x, float y) { - root_.OnTouchEvent(nullptr, - JavaParamRef<jobject>(nullptr), - JavaParamRef<jobject>(nullptr), - 0L, // time - 0, 1, 0, 0, - x, y, 0.f, 0.f, // pos - 0, 0, // pointer_id - 0.f, 0.f, 0.f, 0.f, // touch - 0.f, 0.f, 0.f, 0.f, - 0.f, 0.f, - 0, 0, 0, 0, - false); - } - - void ExpectHit(const TestViewClient& hitClient) { - TestViewClient* clients[3] = { &client1_, &client2_, &client3_ }; - for (auto& client : clients) { - if (&hitClient == client) - EXPECT_TRUE(client->EventHandled()); - else - EXPECT_FALSE(client->EventHandled()); - } - Reset(); - } - - TestViewRoot root_; - TestViewClient client1_; - TestViewClient client2_; - TestViewClient client3_; - ViewAndroid view1_; - ViewAndroid view2_; - ViewAndroid view3_; -}; - -TEST_F(ViewAndroidBoundsTest, MatchesViewInFront) { - view1_.SetLayout(50, 50, 400, 600, false); - view2_.SetLayout(50, 50, 400, 600, false); - root_.AddChild(&view2_); - root_.AddChild(&view1_); - - GenerateTouchEventAt(100.f, 100.f); - ExpectHit(client1_); - - // View 2 moves up to the top, and events should hit it from now. - root_.MoveToTop(&view2_); - GenerateTouchEventAt(100.f, 100.f); - ExpectHit(client2_); -} - -TEST_F(ViewAndroidBoundsTest, MatchesViewArea) { - view1_.SetLayout(50, 50, 200, 200, false); - view2_.SetLayout(20, 20, 400, 600, false); - - root_.AddChild(&view2_); - root_.AddChild(&view1_); - - // Falls within |view1_|'s bounds - GenerateTouchEventAt(100.f, 100.f); - ExpectHit(client1_); - - // Falls within |view2_|'s bounds - GenerateTouchEventAt(300.f, 400.f); - ExpectHit(client2_); -} - -TEST_F(ViewAndroidBoundsTest, MatchesViewAfterMove) { - view1_.SetLayout(50, 50, 200, 200, false); - view2_.SetLayout(20, 20, 400, 600, false); - root_.AddChild(&view2_); - root_.AddChild(&view1_); - - GenerateTouchEventAt(100.f, 100.f); - ExpectHit(client1_); - - view1_.SetLayout(150, 150, 200, 200, false); - GenerateTouchEventAt(100.f, 100.f); - ExpectHit(client2_); -} - -TEST_F(ViewAndroidBoundsTest, MatchesViewSizeOfkMatchParent) { - view1_.SetLayout(20, 20, 400, 600, false); - view3_.SetLayout(0, 0, 0, 0, true); // match parent - view2_.SetLayout(50, 50, 200, 200, false); - - root_.AddChild(&view1_); - root_.AddChild(&view2_); - view1_.AddChild(&view3_); - - GenerateTouchEventAt(100.f, 100.f); - ExpectHit(client2_); - - GenerateTouchEventAt(300.f, 400.f); - ExpectHit(client3_); - - client3_.SetHandleEvent(false); - GenerateTouchEventAt(300.f, 400.f); - ExpectHit(client1_); -} - -TEST_F(ViewAndroidBoundsTest, MatchesViewsWithOffset) { - view1_.SetLayout(10, 20, 150, 100, false); - view2_.SetLayout(20, 30, 40, 30, false); - view3_.SetLayout(70, 30, 40, 30, false); - - root_.AddChild(&view1_); - view1_.AddChild(&view2_); - view1_.AddChild(&view3_); - - GenerateTouchEventAt(70, 30); - ExpectHit(client1_); - - GenerateTouchEventAt(40, 60); - ExpectHit(client2_); - - GenerateTouchEventAt(100, 70); - ExpectHit(client3_); -} - -} // namespace ui
diff --git a/ui/android/view_client.cc b/ui/android/view_client.cc deleted file mode 100644 index b2442b1..0000000 --- a/ui/android/view_client.cc +++ /dev/null
@@ -1,129 +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 "ui/android/view_client.h" - -namespace ui { - -MotionEventData::MotionEventData(float dip_scale, - jobject jevent, - long time, - int action, - int pointer_count, - int history_size, - int action_index, - float pos_x0, - float pos_y0, - float pos_x1, - float pos_y1, - int pointer_id_0, - int pointer_id_1, - float touch_major_0, - float touch_major_1, - float touch_minor_0, - float touch_minor_1, - float orientation_0, - float orientation_1, - float tilt_0, - float tilt_1, - float raw_pos_x, - float raw_pos_y, - int tool_type_0, - int tool_type_1, - int button_state, - int meta_state, - bool is_touch_handle_event) : - dip_scale_(dip_scale), - jevent_(jevent), - time_(time), - action_(action), - pointer_count_(pointer_count), - history_size_(history_size), - action_index_(action_index), - pos_x0_(pos_x0), - pos_y0_(pos_y0), - pos_x1_(pos_x1), - pos_y1_(pos_y1), - pointer_id_0_(pointer_id_0), - pointer_id_1_(pointer_id_1), - touch_major_0_(touch_major_0), - touch_major_1_(touch_major_1), - touch_minor_0_(touch_minor_0), - touch_minor_1_(touch_minor_1), - orientation_0_(orientation_0), - orientation_1_(orientation_1), - tilt_0_(tilt_0), - tilt_1_(tilt_1), - raw_pos_x_(raw_pos_x), - raw_pos_y_(raw_pos_y), - tool_type_0_(tool_type_0), - tool_type_1_(tool_type_1), - button_state_(button_state), - meta_state_(meta_state), - is_touch_handle_event_(is_touch_handle_event) {} - -MotionEventData::MotionEventData(const MotionEventData& other) : - dip_scale_(other.dip_scale_), - jevent_(other.jevent_), - time_(other.time_), - action_(other.action_), - pointer_count_(other.pointer_count_), - history_size_(other.history_size_), - action_index_(other.action_index_), - pos_x0_(other.pos_x0_), - pos_y0_(other.pos_y0_), - pos_x1_(other.pos_x1_), - pos_y1_(other.pos_y1_), - pointer_id_0_(other.pointer_id_0_), - pointer_id_1_(other.pointer_id_1_), - touch_major_0_(other.touch_major_0_), - touch_major_1_(other.touch_major_1_), - touch_minor_0_(other.touch_minor_0_), - touch_minor_1_(other.touch_minor_1_), - orientation_0_(other.orientation_0_), - orientation_1_(other.orientation_1_), - tilt_0_(other.tilt_0_), - tilt_1_(other.tilt_1_), - raw_pos_x_(other.raw_pos_x_), - raw_pos_y_(other.raw_pos_y_), - tool_type_0_(other.tool_type_0_), - tool_type_1_(other.tool_type_1_), - button_state_(other.button_state_), - meta_state_(other.meta_state_), - is_touch_handle_event_(other.is_touch_handle_event_) {} - -MotionEventData MotionEventData::Offset(float delta_x, float delta_y) const { - return MotionEventData(dip_scale_, - jevent_, - time_, - action_, - pointer_count_, - history_size_, - action_index_, - pos_x0_ + delta_x, - pos_y0_ + delta_y, - pos_x1_ + delta_x, - pos_y1_ + delta_y, - pointer_id_0_, - pointer_id_1_, - touch_major_0_, - touch_major_1_, - touch_minor_0_, - touch_minor_1_, - orientation_0_, - orientation_1_, - tilt_0_, - tilt_1_, - raw_pos_x_, - raw_pos_y_, - tool_type_0_, - tool_type_1_, - button_state_, - meta_state_, - is_touch_handle_event_); -} - -bool ViewClient::OnTouchEvent(const MotionEventData& event) { return false; } - -} // namespace ui
diff --git a/ui/android/view_client.h b/ui/android/view_client.h deleted file mode 100644 index fb7f79c..0000000 --- a/ui/android/view_client.h +++ /dev/null
@@ -1,103 +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 UI_ANDROID_VIEW_CLIENT_H_ -#define UI_ANDROID_VIEW_CLIENT_H_ - -#include <jni.h> - -#include "ui/android/ui_android_export.h" - -namespace ui { - -// Container of motion event data. Used when traversing views along their -// hierarchy. Actual motion event object will be constructed right before -// it is used in the |ViewClient| implementation to avoid creating multiple -// |MotionEventAndroid| instances. -struct MotionEventData { - MotionEventData(float dip_scale, - jobject jevent, - long time, - int action, - int pointer_count, - int history_size, - int action_index, - float pos_x0, - float pos_y0, - float pos_x1, - float pos_y1, - int pointer_id_0, - int pointer_id_1, - float touch_major_0, - float touch_major_1, - float touch_minor_0, - float touch_minor_1, - float orientation_0, - float orientation_1, - float tilt_0, - float tilt_1, - float raw_pos_x, - float raw_pos_y, - int tool_type_0, - int tool_type_1, - int button_state, - int meta_state, - bool is_touch_handle_event); - - MotionEventData(const MotionEventData& other); - - // Returns a new |MotionEventData| object whose position is offset - // by a given delta. - MotionEventData Offset(float delta_x, float delta_y) const; - - float GetX() const { return pos_x0_ / dip_scale_; } - float GetY() const { return pos_y0_ / dip_scale_; } - - const float dip_scale_; - const jobject jevent_; - const long time_; // ms - const int action_; - const int pointer_count_; - const int history_size_; - const int action_index_; - - const float pos_x0_; // in pixel unit - const float pos_y0_; - const float pos_x1_; - const float pos_y1_; - - const int pointer_id_0_; - const int pointer_id_1_; - const float touch_major_0_; - const float touch_major_1_; - const float touch_minor_0_; - const float touch_minor_1_; - const float orientation_0_; - const float orientation_1_; - const float tilt_0_; - const float tilt_1_; - const float raw_pos_x_; - const float raw_pos_y_; - const int tool_type_0_; - const int tool_type_1_; - const int button_state_; - const int meta_state_; - const bool is_touch_handle_event_; -}; - -// Client interface used to forward events from Java to native views. -// Calls are dispatched to its children along the hierarchy of ViewAndroid. -// Use bool return type to stop propagating the call i.e. overriden method -// should return true to indicate that the event was handled and stop -// the processing. -// Note: Not in use yet. Will be hooked up together with ViewRoot. -// See https://crbug.com/671401. -class UI_ANDROID_EXPORT ViewClient { - public: - virtual bool OnTouchEvent(const MotionEventData& event); -}; - -} // namespace ui - -#endif // UI_ANDROID_VIEW_CLIENT_H_
diff --git a/ui/android/view_root.cc b/ui/android/view_root.cc deleted file mode 100644 index 1a1f977..0000000 --- a/ui/android/view_root.cc +++ /dev/null
@@ -1,106 +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 "ui/android/view_root.h" - -#include "jni/ViewRoot_jni.h" - -namespace ui { - -using base::android::JavaParamRef; - -ViewRoot::ViewRoot(jlong window_android_ptr) { - WindowAndroid* window_android = - reinterpret_cast<WindowAndroid*>(window_android_ptr); - window_ = window_android; - - // ViewRoot simply accepts all events and lets the hit testing - // start from its children. - SetLayout(0, 0, 0, 0, true); -} - -ViewAndroid* ViewRoot::GetViewRoot() { - return this; -} - -WindowAndroid* ViewRoot::GetWindowAndroid() const { - return window_; -} - -void ViewRoot::Destroy(JNIEnv* env, const JavaParamRef<jobject>& obj) { - delete this; -} - -jboolean ViewRoot::OnTouchEvent(JNIEnv* env, - const JavaParamRef<jobject>& obj, - const JavaParamRef<jobject>& motion_event, - jlong time_ms, - jint android_action, - jint pointer_count, - jint history_size, - jint action_index, - jfloat pos_x_0, - jfloat pos_y_0, - jfloat pos_x_1, - jfloat pos_y_1, - jint pointer_id_0, - jint pointer_id_1, - jfloat touch_major_0, - jfloat touch_major_1, - jfloat touch_minor_0, - jfloat touch_minor_1, - jfloat orientation_0, - jfloat orientation_1, - jfloat tilt_0, - jfloat tilt_1, - jfloat raw_pos_x, - jfloat raw_pos_y, - jint android_tool_type_0, - jint android_tool_type_1, - jint android_button_state, - jint android_meta_state, - jboolean is_touch_handle_event) { - MotionEventData event(GetDipScale(), - motion_event.obj(), - time_ms, - android_action, - pointer_count, - history_size, - action_index, - pos_x_0, - pos_y_0, - pos_x_1, - pos_y_1, - pointer_id_0, - pointer_id_1, - touch_major_0, - touch_major_1, - touch_minor_0, - touch_minor_1, - orientation_0, - orientation_1, - tilt_0, - tilt_1, - raw_pos_x, - raw_pos_y, - android_tool_type_0, - android_tool_type_1, - android_button_state, - android_meta_state, - is_touch_handle_event); - return OnTouchEventInternal(event); -} - -// static -jlong Init(JNIEnv* env, - const JavaParamRef<jobject>& obj, - jlong window_android_ptr) { - return reinterpret_cast<intptr_t>(new ViewRoot(window_android_ptr)); -} - -bool RegisterViewRoot(JNIEnv* env) { - return RegisterNativesImpl(env); -} - -} // namespace ui
diff --git a/ui/android/view_root.h b/ui/android/view_root.h deleted file mode 100644 index 49007fa4..0000000 --- a/ui/android/view_root.h +++ /dev/null
@@ -1,71 +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 UI_ANDROID_VIEW_ROOT_H_ -#define UI_ANDROID_VIEW_ROOT_H_ - -#include <jni.h> - -#include "base/android/scoped_java_ref.h" -#include "ui/android/ui_android_export.h" -#include "ui/android/view_android.h" - -namespace ui { - -// ViewRoot is the root of a ViewAndroid tree. -// TODO(jinsukkim): Hook this up to UI event forwarding flow and -// substitute WindowAndroid. See https://crbug.com/671401 -class UI_ANDROID_EXPORT ViewRoot : public ViewAndroid { - public: - explicit ViewRoot(jlong window_android_ptr); - - // ViewAndroid overrides. - WindowAndroid* GetWindowAndroid() const override; - ViewAndroid* GetViewRoot() override; - - void Destroy(JNIEnv* env, - const base::android::JavaParamRef<jobject>& obj); - - jboolean OnTouchEvent( - JNIEnv* env, - const base::android::JavaParamRef<jobject>& obj, - const base::android::JavaParamRef<jobject>& motion_event, - jlong time_ms, - jint android_action, - jint pointer_count, - jint history_size, - jint action_index, - jfloat pos_x_0, - jfloat pos_y_0, - jfloat pos_x_1, - jfloat pos_y_1, - jint pointer_id_0, - jint pointer_id_1, - jfloat touch_major_0, - jfloat touch_major_1, - jfloat touch_minor_0, - jfloat touch_minor_1, - jfloat orientation_0, - jfloat orientation_1, - jfloat tilt_0, - jfloat tilt_1, - jfloat raw_pos_x, - jfloat raw_pos_y, - jint android_tool_type_0, - jint android_tool_type_1, - jint android_button_state, - jint android_meta_state, - jboolean is_touch_handle_event); - - private: - WindowAndroid* window_; - - DISALLOW_COPY_AND_ASSIGN(ViewRoot); -}; - -bool RegisterViewRoot(JNIEnv* env); - -} // namespace ui - -#endif // UI_ANDROID_VIEW_ROOT_H_
diff --git a/ui/arc/notification/arc_notification_item.cc b/ui/arc/notification/arc_notification_item.cc index f67f33a..88cda841 100644 --- a/ui/arc/notification/arc_notification_item.cc +++ b/ui/arc/notification/arc_notification_item.cc
@@ -271,6 +271,10 @@ notification_key_, button_index); } +void ArcNotificationItem::OpenSettings() { + manager_->OpenNotificationSettings(notification_key_); +} + // Converts from Android notification priority to Chrome notification priority. // On Android, PRIORITY_DEFAULT does not pop up, so this maps PRIORITY_DEFAULT // to Chrome's -1 to adapt that behavior. Also, this maps PRIORITY_LOW and _HIGH
diff --git a/ui/arc/notification/arc_notification_item.h b/ui/arc/notification/arc_notification_item.h index b98632f..3df5e6a 100644 --- a/ui/arc/notification/arc_notification_item.h +++ b/ui/arc/notification/arc_notification_item.h
@@ -38,6 +38,7 @@ void Close(bool by_user); void Click(); void ButtonClick(int button_index); + void OpenSettings(); const std::string& notification_key() const { return notification_key_; }
diff --git a/ui/arc/notification/arc_notification_manager.cc b/ui/arc/notification/arc_notification_manager.cc index 2d368ff..b4619203 100644 --- a/ui/arc/notification/arc_notification_manager.cc +++ b/ui/arc/notification/arc_notification_manager.cc
@@ -115,7 +115,7 @@ auto* notifications_instance = ARC_GET_INSTANCE_FOR_METHOD( arc_bridge_service()->notifications(), SendNotificationEventToAndroid); - // On shutdown, the ARC channel may quit earlier then notifications. + // On shutdown, the ARC channel may quit earlier than notifications. if (!notifications_instance) { VLOG(2) << "ARC Notification (key: " << key << ") is closed, but the ARC channel has already gone."; @@ -137,7 +137,7 @@ auto* notifications_instance = ARC_GET_INSTANCE_FOR_METHOD( arc_bridge_service()->notifications(), SendNotificationEventToAndroid); - // On shutdown, the ARC channel may quit earlier then notifications. + // On shutdown, the ARC channel may quit earlier than notifications. if (!notifications_instance) { VLOG(2) << "ARC Notification (key: " << key << ") is clicked, but the ARC channel has already gone."; @@ -160,7 +160,7 @@ auto* notifications_instance = ARC_GET_INSTANCE_FOR_METHOD( arc_bridge_service()->notifications(), SendNotificationEventToAndroid); - // On shutdown, the ARC channel may quit earlier then notifications. + // On shutdown, the ARC channel may quit earlier than notifications. if (!notifications_instance) { VLOG(2) << "ARC Notification (key: " << key << ")'s button is clicked, but the ARC channel has already gone."; @@ -223,6 +223,23 @@ notifications_instance->CloseNotificationWindow(key); } +void ArcNotificationManager::OpenNotificationSettings(const std::string& key) { + if (items_.find(key) == items_.end()) { + DVLOG(3) << "Chrome requests to fire a click event on the notification " + << "settings button (key: " << key << "), but it is gone."; + return; + } + + auto* notifications_instance = ARC_GET_INSTANCE_FOR_METHOD( + arc_bridge_service()->notifications(), OpenNotificationSettings); + + // On shutdown, the ARC channel may quit earlier than notifications. + if (!notifications_instance) + return; + + notifications_instance->OpenNotificationSettings(key); +} + void ArcNotificationManager::OnToastPosted(mojom::ArcToastDataPtr data) { const base::string16 text16( base::UTF8ToUTF16(data->text.has_value() ? *data->text : std::string()));
diff --git a/ui/arc/notification/arc_notification_manager.h b/ui/arc/notification/arc_notification_manager.h index c05ce10..c0a886ab 100644 --- a/ui/arc/notification/arc_notification_manager.h +++ b/ui/arc/notification/arc_notification_manager.h
@@ -52,6 +52,7 @@ int button_index); void CreateNotificationWindow(const std::string& key); void CloseNotificationWindow(const std::string& key); + void OpenNotificationSettings(const std::string& key); private: const AccountId main_profile_id_;
diff --git a/ui/aura/client/aura_constants.cc b/ui/aura/client/aura_constants.cc index b8e7cf7b..52f9cdfc 100644 --- a/ui/aura/client/aura_constants.cc +++ b/ui/aura/client/aura_constants.cc
@@ -35,6 +35,7 @@ DEFINE_OWNED_UI_CLASS_PROPERTY_KEY(std::string, kAppIdKey, nullptr); DEFINE_UI_CLASS_PROPERTY_KEY(int, kAppType, 0); DEFINE_UI_CLASS_PROPERTY_KEY(bool, kConstrainedWindowKey, false); +DEFINE_UI_CLASS_PROPERTY_KEY(bool, kCreatedByUserGesture, false); DEFINE_UI_CLASS_PROPERTY_KEY(bool, kDrawAttentionKey, false); DEFINE_UI_CLASS_PROPERTY_KEY(Window*, kHostWindowKey, nullptr); DEFINE_UI_CLASS_PROPERTY_KEY(bool, kImmersiveFullscreenKey, false);
diff --git a/ui/aura/client/aura_constants.h b/ui/aura/client/aura_constants.h index 3c02cdd..664de048 100644 --- a/ui/aura/client/aura_constants.h +++ b/ui/aura/client/aura_constants.h
@@ -49,6 +49,9 @@ // A property key to store if a window is a constrained window or not. AURA_EXPORT extern const WindowProperty<bool>* const kConstrainedWindowKey; +// A property key to store if a window was created by a user gesture. +AURA_EXPORT extern const WindowProperty<bool>* const kCreatedByUserGesture; + // A property key to indicate that a window should show that it deserves // attention. AURA_EXPORT extern const aura::WindowProperty<bool>* const kDrawAttentionKey;
diff --git a/ui/aura/mus/property_converter.cc b/ui/aura/mus/property_converter.cc index 7a452e5..9787d57 100644 --- a/ui/aura/mus/property_converter.cc +++ b/ui/aura/mus/property_converter.cc
@@ -70,7 +70,7 @@ if (transport_name->empty()) return false; - auto image_key = static_cast<const WindowProperty<gfx::ImageSkia*>*>(key); + auto* image_key = static_cast<const WindowProperty<gfx::ImageSkia*>*>(key); if (image_properties_.count(image_key) > 0) { const gfx::ImageSkia* value = window->GetProperty(image_key); if (value) { @@ -84,25 +84,25 @@ return true; } - auto rect_key = static_cast<const WindowProperty<gfx::Rect*>*>(key); + auto* rect_key = static_cast<const WindowProperty<gfx::Rect*>*>(key); if (rect_properties_.count(rect_key) > 0) { *transport_value = GetArray(window, rect_key); return true; } - auto size_key = static_cast<const WindowProperty<gfx::Size*>*>(key); + auto* size_key = static_cast<const WindowProperty<gfx::Size*>*>(key); if (size_properties_.count(size_key) > 0) { *transport_value = GetArray(window, size_key); return true; } - auto string_key = static_cast<const WindowProperty<std::string*>*>(key); + auto* string_key = static_cast<const WindowProperty<std::string*>*>(key); if (string_properties_.count(string_key) > 0) { *transport_value = GetArray(window, string_key); return true; } - auto string16_key = static_cast<const WindowProperty<base::string16*>*>(key); + auto* string16_key = static_cast<const WindowProperty<base::string16*>*>(key); if (string16_properties_.count(string16_key) > 0) { *transport_value = GetArray(window, string16_key); return true; @@ -122,23 +122,23 @@ if (primitive_properties_.count(key) > 0) return primitive_properties_[key].transport_name; - auto image_key = static_cast<const WindowProperty<gfx::ImageSkia*>*>(key); + auto* image_key = static_cast<const WindowProperty<gfx::ImageSkia*>*>(key); if (image_properties_.count(image_key) > 0) return image_properties_[image_key]; - auto rect_key = static_cast<const WindowProperty<gfx::Rect*>*>(key); + auto* rect_key = static_cast<const WindowProperty<gfx::Rect*>*>(key); if (rect_properties_.count(rect_key) > 0) return rect_properties_[rect_key]; - auto size_key = static_cast<const WindowProperty<gfx::Size*>*>(key); + auto* size_key = static_cast<const WindowProperty<gfx::Size*>*>(key); if (size_properties_.count(size_key) > 0) return size_properties_[size_key]; - auto string_key = static_cast<const WindowProperty<std::string*>*>(key); + auto* string_key = static_cast<const WindowProperty<std::string*>*>(key); if (string_properties_.count(string_key) > 0) return string_properties_[string_key]; - auto string16_key = static_cast<const WindowProperty<base::string16*>*>(key); + auto* string16_key = static_cast<const WindowProperty<base::string16*>*>(key); if (string16_properties_.count(string16_key) > 0) return string16_properties_[string16_key];
diff --git a/ui/compositor/layer_unittest.cc b/ui/compositor/layer_unittest.cc index b1870ecb..f52ae02 100644 --- a/ui/compositor/layer_unittest.cc +++ b/ui/compositor/layer_unittest.cc
@@ -1895,8 +1895,8 @@ l1->SetAnimator(LayerAnimator::CreateImplicitAnimator()); l2->SetAnimator(LayerAnimator::CreateImplicitAnimator()); - auto player1 = l1->GetAnimator()->GetAnimationPlayerForTesting(); - auto player2 = l2->GetAnimator()->GetAnimationPlayerForTesting(); + auto* player1 = l1->GetAnimator()->GetAnimationPlayerForTesting(); + auto* player2 = l2->GetAnimator()->GetAnimationPlayerForTesting(); EXPECT_FALSE(player1->has_any_animation());
diff --git a/ui/compositor/test/in_process_context_factory.cc b/ui/compositor/test/in_process_context_factory.cc index 4f0faf9..12ae29dc 100644 --- a/ui/compositor/test/in_process_context_factory.cc +++ b/ui/compositor/test/in_process_context_factory.cc
@@ -82,11 +82,11 @@ } void SwapBuffers(cc::OutputSurfaceFrame frame) override { DCHECK(context_provider_.get()); - if (frame.sub_buffer_rect == gfx::Rect(frame.size)) { - context_provider_->ContextSupport()->Swap(); - } else { + if (frame.sub_buffer_rect) { context_provider_->ContextSupport()->PartialSwapBuffers( - frame.sub_buffer_rect); + *frame.sub_buffer_rect); + } else { + context_provider_->ContextSupport()->Swap(); } gpu::gles2::GLES2Interface* gl = context_provider_->ContextGL(); const uint64_t fence_sync = gl->InsertFenceSyncCHROMIUM();
diff --git a/ui/events/gestures/gesture_recognizer_impl.cc b/ui/events/gestures/gesture_recognizer_impl.cc index 9f708fc..9be2e418 100644 --- a/ui/events/gestures/gesture_recognizer_impl.cc +++ b/ui/events/gestures/gesture_recognizer_impl.cc
@@ -114,7 +114,7 @@ consumers.push_back(entry.first); } - for (auto consumer : consumers) + for (auto* consumer : consumers) CancelActiveTouches(consumer); }
diff --git a/ui/gfx/android/OWNERS b/ui/gfx/android/OWNERS index 1849050..0fc82371 100644 --- a/ui/gfx/android/OWNERS +++ b/ui/gfx/android/OWNERS
@@ -1,2 +1,4 @@ aelias@chromium.org skyostil@chromium.org + +# COMPONENT: UI>GFX
diff --git a/ui/gfx/color_transform_unittest.cc b/ui/gfx/color_transform_unittest.cc index 1ccfe75..09d5dce0 100644 --- a/ui/gfx/color_transform_unittest.cc +++ b/ui/gfx/color_transform_unittest.cc
@@ -259,6 +259,51 @@ EXPECT_GT(tmp.z(), tmp.y()); } +TEST(SimpleColorSpace, ToUndefined) { + ColorSpace null; + ColorSpace nonnull = gfx::ColorSpace::CreateSRGB(); + // Video should have 1 step: YUV to RGB. + // Anything else should have 0 steps. + ColorSpace video = gfx::ColorSpace::CreateREC709(); + std::unique_ptr<ColorTransform> video_to_null( + ColorTransform::NewColorTransform( + video, null, ColorTransform::Intent::INTENT_PERCEPTUAL)); + EXPECT_EQ(video_to_null->NumberOfStepsForTesting(), 1u); + + // Test with an ICC profile that can't be represented as matrix+transfer. + ColorSpace luttrcicc = ICCProfileForTestingNoAnalyticTrFn().GetColorSpace(); + std::unique_ptr<ColorTransform> luttrcicc_to_null( + ColorTransform::NewColorTransform( + luttrcicc, null, ColorTransform::Intent::INTENT_PERCEPTUAL)); + EXPECT_EQ(luttrcicc_to_null->NumberOfStepsForTesting(), 0u); + std::unique_ptr<ColorTransform> luttrcicc_to_nonnull( + ColorTransform::NewColorTransform( + luttrcicc, nonnull, ColorTransform::Intent::INTENT_PERCEPTUAL)); + EXPECT_GT(luttrcicc_to_nonnull->NumberOfStepsForTesting(), 0u); + + // Test with an ICC profile that can. + ColorSpace adobeicc = ICCProfileForTestingAdobeRGB().GetColorSpace(); + std::unique_ptr<ColorTransform> adobeicc_to_null( + ColorTransform::NewColorTransform( + adobeicc, null, ColorTransform::Intent::INTENT_PERCEPTUAL)); + EXPECT_EQ(adobeicc_to_null->NumberOfStepsForTesting(), 0u); + std::unique_ptr<ColorTransform> adobeicc_to_nonnull( + ColorTransform::NewColorTransform( + adobeicc, nonnull, ColorTransform::Intent::INTENT_PERCEPTUAL)); + EXPECT_GT(adobeicc_to_nonnull->NumberOfStepsForTesting(), 0u); + + // And with something analytic. + ColorSpace srgb = gfx::ColorSpace::CreateXYZD50(); + std::unique_ptr<ColorTransform> srgb_to_null( + ColorTransform::NewColorTransform( + srgb, null, ColorTransform::Intent::INTENT_PERCEPTUAL)); + EXPECT_EQ(srgb_to_null->NumberOfStepsForTesting(), 0u); + std::unique_ptr<ColorTransform> srgb_to_nonnull( + ColorTransform::NewColorTransform( + srgb, nonnull, ColorTransform::Intent::INTENT_PERCEPTUAL)); + EXPECT_GT(srgb_to_nonnull->NumberOfStepsForTesting(), 0u); +} + TEST(SimpleColorSpace, DefaultToSRGB) { // The default value should do no transformation, regardless of destination. ColorSpace unknown;
diff --git a/ui/gfx/icc_profile.cc b/ui/gfx/icc_profile.cc index 9f04bd8..9390da6 100644 --- a/ui/gfx/icc_profile.cc +++ b/ui/gfx/icc_profile.cc
@@ -18,6 +18,7 @@ const uint64_t ICCProfile::test_id_color_spin_ = 2; const uint64_t ICCProfile::test_id_generic_rgb_ = 3; const uint64_t ICCProfile::test_id_srgb_ = 4; +const uint64_t ICCProfile::test_id_no_analytic_tr_fn_ = 5; namespace { const size_t kMinProfileLength = 128; @@ -33,7 +34,7 @@ ~Cache() {} // Start from-ICC-data IDs at the end of the hard-coded test id list above. - uint64_t next_unused_id = 5; + uint64_t next_unused_id = 10; base::MRUCache<uint64_t, ICCProfile> id_to_icc_profile_mru; base::Lock lock; };
diff --git a/ui/gfx/icc_profile.h b/ui/gfx/icc_profile.h index a07edf6..95ae024 100644 --- a/ui/gfx/icc_profile.h +++ b/ui/gfx/icc_profile.h
@@ -75,10 +75,12 @@ friend ICCProfile ICCProfileForTestingColorSpin(); friend ICCProfile ICCProfileForTestingGenericRGB(); friend ICCProfile ICCProfileForTestingSRGB(); + friend ICCProfile ICCProfileForTestingNoAnalyticTrFn(); static const uint64_t test_id_adobe_rgb_; static const uint64_t test_id_color_spin_; static const uint64_t test_id_generic_rgb_; static const uint64_t test_id_srgb_; + static const uint64_t test_id_no_analytic_tr_fn_; // Populate |icc_profile| with the ICCProfile corresponding to id |id|. Return // false if |id| is not in the cache. If |only_if_needed| is true, then return
diff --git a/ui/gfx/image/image_skia_operations.cc b/ui/gfx/image/image_skia_operations.cc index 4f23d5601..f469b3c8 100644 --- a/ui/gfx/image/image_skia_operations.cc +++ b/ui/gfx/image/image_skia_operations.cc
@@ -594,7 +594,7 @@ ImageSkia ImageSkiaOperations::CreateHorizontalShadow( const std::vector<ShadowValue>& shadows, bool fades_down) { - auto source = new HorizontalShadowSource(shadows, fades_down); + auto* source = new HorizontalShadowSource(shadows, fades_down); return ImageSkia(source, source->size()); }
diff --git a/ui/gfx/shadow_util.cc b/ui/gfx/shadow_util.cc index 88b19fae0..04360f9 100644 --- a/ui/gfx/shadow_util.cc +++ b/ui/gfx/shadow_util.cc
@@ -106,7 +106,7 @@ // To see what this looks like for elevation 24, try this CSS: // box-shadow: 0 24px 48px rgba(0, 0, 0, .24), // 0 0 24px rgba(0, 0, 0, .12); - auto source = new ShadowNineboxSource(shadow->values, corner_radius); + auto* source = new ShadowNineboxSource(shadow->values, corner_radius); shadow->ninebox_image = ImageSkia(source, source->size()); return *shadow; }
diff --git a/ui/gfx/test/icc_profiles.cc b/ui/gfx/test/icc_profiles.cc index 459ad54..ee7130f 100644 --- a/ui/gfx/test/icc_profiles.cc +++ b/ui/gfx/test/icc_profiles.cc
@@ -535,6 +535,175 @@ 0x00, 0x00, 0x10, 0x2f, 0x00, 0x00, 0xbe, 0x9c}; } +unsigned char no_analytic_tr_fn_profile_data[] = { + 0x00, 0x00, 0x07, 0xd4, 0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, + 0x6d, 0x6e, 0x74, 0x72, 0x52, 0x47, 0x42, 0x20, 0x58, 0x59, 0x5a, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x61, 0x63, 0x73, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xf6, 0xd6, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x2d, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, + 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x34, + 0x72, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x01, 0x24, 0x00, 0x00, 0x00, 0x14, + 0x67, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x01, 0x38, 0x00, 0x00, 0x00, 0x14, + 0x62, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x01, 0x4c, 0x00, 0x00, 0x00, 0x14, + 0x72, 0x54, 0x52, 0x43, 0x00, 0x00, 0x01, 0x60, 0x00, 0x00, 0x02, 0x0c, + 0x67, 0x54, 0x52, 0x43, 0x00, 0x00, 0x03, 0x6c, 0x00, 0x00, 0x02, 0x0c, + 0x62, 0x54, 0x52, 0x43, 0x00, 0x00, 0x05, 0x78, 0x00, 0x00, 0x02, 0x0c, + 0x77, 0x74, 0x70, 0x74, 0x00, 0x00, 0x07, 0x84, 0x00, 0x00, 0x00, 0x14, + 0x63, 0x70, 0x72, 0x74, 0x00, 0x00, 0x07, 0x98, 0x00, 0x00, 0x00, 0x3c, + 0x6d, 0x6c, 0x75, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x0c, 0x65, 0x6e, 0x55, 0x53, 0x00, 0x00, 0x00, 0x18, + 0x00, 0x00, 0x00, 0x1c, 0x00, 0x47, 0x00, 0x6f, 0x00, 0x6f, 0x00, 0x67, + 0x00, 0x6c, 0x00, 0x65, 0x00, 0x20, 0x00, 0x53, 0x00, 0x6b, 0x00, 0x69, + 0x00, 0x61, 0x00, 0x20, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x73, 0x04, 0x00, 0x00, 0x39, 0x77, 0x00, 0x00, 0x00, 0x4a, + 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0xf1, + 0x00, 0x00, 0xb8, 0xec, 0x00, 0x00, 0x0d, 0xb6, 0x58, 0x59, 0x5a, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0xe1, 0x00, 0x00, 0x0d, 0x9d, + 0x00, 0x00, 0xc5, 0x2d, 0x63, 0x75, 0x72, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x06, 0x00, 0x09, + 0x00, 0x0c, 0x00, 0x0f, 0x00, 0x12, 0x00, 0x15, 0x00, 0x18, 0x00, 0x1b, + 0x00, 0x1f, 0x00, 0x24, 0x00, 0x2b, 0x00, 0x34, 0x00, 0x3e, 0x00, 0x4a, + 0x00, 0x58, 0x00, 0x68, 0x00, 0x79, 0x00, 0x8c, 0x00, 0xa1, 0x00, 0xb8, + 0x00, 0xd1, 0x00, 0xeb, 0x01, 0x08, 0x01, 0x27, 0x01, 0x47, 0x01, 0x69, + 0x01, 0x8e, 0x01, 0xb4, 0x01, 0xdd, 0x02, 0x07, 0x02, 0x33, 0x02, 0x62, + 0x02, 0x92, 0x02, 0xc4, 0x02, 0xf9, 0x03, 0x2f, 0x03, 0x68, 0x03, 0xa2, + 0x03, 0xdf, 0x04, 0x1d, 0x04, 0x5e, 0x04, 0xa0, 0x04, 0xe5, 0x05, 0x2c, + 0x05, 0x75, 0x05, 0xbf, 0x06, 0x0c, 0x06, 0x5a, 0x06, 0xab, 0x06, 0xfd, + 0x07, 0x51, 0x07, 0xa8, 0x08, 0x00, 0x08, 0x5a, 0x08, 0xb6, 0x09, 0x14, + 0x09, 0x74, 0x09, 0xd5, 0x0a, 0x39, 0x0a, 0x9e, 0x0b, 0x05, 0x0b, 0x6e, + 0x0b, 0xd9, 0x0c, 0x46, 0x0c, 0xb4, 0x0d, 0x24, 0x0d, 0x96, 0x0e, 0x0a, + 0x0e, 0x7f, 0x0e, 0xf7, 0x0f, 0x6f, 0x0f, 0xea, 0x10, 0x65, 0x10, 0xe3, + 0x11, 0x62, 0x11, 0xe2, 0x12, 0x65, 0x12, 0xe8, 0x13, 0x6d, 0x13, 0xf4, + 0x14, 0x7c, 0x15, 0x05, 0x15, 0x90, 0x16, 0x1c, 0x16, 0xaa, 0x17, 0x39, + 0x17, 0xca, 0x18, 0x5c, 0x18, 0xf1, 0x19, 0x86, 0x1a, 0x1d, 0x1a, 0xb7, + 0x1b, 0x52, 0x1b, 0xf0, 0x1c, 0x8f, 0x1d, 0x31, 0x1d, 0xd6, 0x1e, 0x7d, + 0x1f, 0x26, 0x1f, 0xd2, 0x20, 0x80, 0x21, 0x31, 0x21, 0xe4, 0x22, 0x9a, + 0x23, 0x52, 0x24, 0x0d, 0x24, 0xca, 0x25, 0x8b, 0x26, 0x4e, 0x27, 0x14, + 0x27, 0xde, 0x28, 0xaa, 0x29, 0x7a, 0x2a, 0x4c, 0x2b, 0x22, 0x2b, 0xfc, + 0x2c, 0xd9, 0x2d, 0xb8, 0x2e, 0x9b, 0x2f, 0x81, 0x30, 0x69, 0x31, 0x54, + 0x32, 0x42, 0x33, 0x32, 0x34, 0x25, 0x35, 0x1a, 0x36, 0x12, 0x37, 0x0d, + 0x38, 0x09, 0x39, 0x07, 0x3a, 0x07, 0x3b, 0x09, 0x3c, 0x0d, 0x3d, 0x12, + 0x3e, 0x19, 0x3f, 0x22, 0x40, 0x2e, 0x41, 0x3a, 0x42, 0x47, 0x43, 0x56, + 0x44, 0x67, 0x45, 0x79, 0x46, 0x8d, 0x47, 0xa3, 0x48, 0xbb, 0x49, 0xd7, + 0x4a, 0xf5, 0x4c, 0x13, 0x4d, 0x34, 0x4e, 0x58, 0x4f, 0x80, 0x50, 0xab, + 0x51, 0xda, 0x53, 0x0c, 0x54, 0x44, 0x55, 0x7f, 0x56, 0xbe, 0x58, 0x02, + 0x59, 0x4b, 0x5a, 0x99, 0x5b, 0xec, 0x5d, 0x45, 0x5e, 0xa2, 0x60, 0x03, + 0x61, 0x67, 0x62, 0xcf, 0x64, 0x3b, 0x65, 0xab, 0x67, 0x1e, 0x68, 0x93, + 0x6a, 0x05, 0x6b, 0x77, 0x6c, 0xe7, 0x6e, 0x57, 0x6f, 0xc7, 0x71, 0x38, + 0x72, 0xaa, 0x74, 0x1b, 0x75, 0x8c, 0x76, 0xfe, 0x78, 0x71, 0x79, 0xe6, + 0x7b, 0x5d, 0x7c, 0xd4, 0x7e, 0x4c, 0x7f, 0xc6, 0x81, 0x42, 0x82, 0xc2, + 0x84, 0x48, 0x85, 0xd2, 0x87, 0x61, 0x88, 0xf4, 0x8a, 0x8c, 0x8c, 0x28, + 0x8d, 0xc8, 0x8f, 0x6c, 0x91, 0x12, 0x92, 0xbd, 0x94, 0x6a, 0x96, 0x19, + 0x97, 0xcb, 0x99, 0x80, 0x9b, 0x36, 0x9c, 0xee, 0x9e, 0xa7, 0xa0, 0x61, + 0xa2, 0x1c, 0xa3, 0xda, 0xa5, 0x9a, 0xa7, 0x5f, 0xa9, 0x28, 0xaa, 0xf5, + 0xac, 0xc5, 0xae, 0x95, 0xb0, 0x66, 0xb2, 0x38, 0xb4, 0x0c, 0xb5, 0xe5, + 0xb7, 0xc5, 0xb9, 0xac, 0xbb, 0x9b, 0xbd, 0x90, 0xbf, 0x8a, 0xc1, 0x8a, + 0xc3, 0x8f, 0xc5, 0x98, 0xc7, 0xa8, 0xc9, 0xbe, 0xcb, 0xdd, 0xce, 0x01, + 0xd0, 0x23, 0xd2, 0x42, 0xd4, 0x63, 0xd6, 0x84, 0xd8, 0xa5, 0xda, 0xc7, + 0xdc, 0xe9, 0xdf, 0x09, 0xe1, 0x26, 0xe3, 0x40, 0xe5, 0x58, 0xe7, 0x6c, + 0xe9, 0x81, 0xeb, 0x94, 0xed, 0xa5, 0xef, 0xb5, 0xf1, 0xc4, 0xf3, 0xd1, + 0xf5, 0xdd, 0xf7, 0xe6, 0xf9, 0xef, 0xfb, 0xf6, 0xfd, 0xfb, 0xff, 0xff, + 0x63, 0x75, 0x72, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x05, 0x00, 0x07, 0x00, 0x09, 0x00, 0x0c, + 0x00, 0x0f, 0x00, 0x13, 0x00, 0x18, 0x00, 0x1f, 0x00, 0x26, 0x00, 0x30, + 0x00, 0x3a, 0x00, 0x46, 0x00, 0x54, 0x00, 0x63, 0x00, 0x73, 0x00, 0x85, + 0x00, 0x99, 0x00, 0xae, 0x00, 0xc5, 0x00, 0xdd, 0x00, 0xf7, 0x01, 0x12, + 0x01, 0x30, 0x01, 0x4e, 0x01, 0x6f, 0x01, 0x91, 0x01, 0xb5, 0x01, 0xdb, + 0x02, 0x02, 0x02, 0x2b, 0x02, 0x56, 0x02, 0x83, 0x02, 0xb2, 0x02, 0xe2, + 0x03, 0x14, 0x03, 0x48, 0x03, 0x7e, 0x03, 0xb6, 0x03, 0xef, 0x04, 0x2a, + 0x04, 0x68, 0x04, 0xa7, 0x04, 0xe8, 0x05, 0x2b, 0x05, 0x70, 0x05, 0xb7, + 0x06, 0x00, 0x06, 0x4b, 0x06, 0x98, 0x06, 0xe6, 0x07, 0x37, 0x07, 0x8a, + 0x07, 0xdf, 0x08, 0x36, 0x08, 0x90, 0x08, 0xeb, 0x09, 0x48, 0x09, 0xa7, + 0x0a, 0x08, 0x0a, 0x6c, 0x0a, 0xd1, 0x0b, 0x39, 0x0b, 0xa3, 0x0c, 0x0e, + 0x0c, 0x7c, 0x0c, 0xed, 0x0d, 0x5f, 0x0d, 0xd4, 0x0e, 0x4a, 0x0e, 0xc3, + 0x0f, 0x3e, 0x0f, 0xbc, 0x10, 0x3c, 0x10, 0xbd, 0x11, 0x42, 0x11, 0xc8, + 0x12, 0x51, 0x12, 0xdc, 0x13, 0x69, 0x13, 0xf9, 0x14, 0x8b, 0x15, 0x20, + 0x15, 0xb6, 0x16, 0x50, 0x16, 0xeb, 0x17, 0x88, 0x18, 0x28, 0x18, 0xca, + 0x19, 0x6e, 0x1a, 0x16, 0x1a, 0xbe, 0x1b, 0x69, 0x1c, 0x16, 0x1c, 0xc6, + 0x1d, 0x77, 0x1e, 0x2a, 0x1e, 0xdf, 0x1f, 0x96, 0x20, 0x4e, 0x21, 0x08, + 0x21, 0xc4, 0x22, 0x81, 0x23, 0x3f, 0x23, 0xff, 0x24, 0xc0, 0x25, 0x82, + 0x26, 0x47, 0x27, 0x0e, 0x27, 0xd6, 0x28, 0xa1, 0x29, 0x6d, 0x2a, 0x3b, + 0x2b, 0x0d, 0x2b, 0xdf, 0x2c, 0xb2, 0x2d, 0x87, 0x2e, 0x5e, 0x2f, 0x37, + 0x30, 0x11, 0x30, 0xed, 0x31, 0xcb, 0x32, 0xaa, 0x33, 0x8c, 0x34, 0x6f, + 0x35, 0x56, 0x36, 0x3f, 0x37, 0x2a, 0x38, 0x18, 0x39, 0x09, 0x39, 0xfd, + 0x3a, 0xf4, 0x3b, 0xf0, 0x3c, 0xef, 0x3d, 0xf1, 0x3e, 0xf7, 0x40, 0x00, + 0x41, 0x0d, 0x42, 0x1d, 0x43, 0x31, 0x44, 0x49, 0x45, 0x64, 0x46, 0x82, + 0x47, 0xa4, 0x48, 0xc9, 0x49, 0xf1, 0x4b, 0x1a, 0x4c, 0x46, 0x4d, 0x75, + 0x4e, 0xa4, 0x4f, 0xd6, 0x51, 0x0a, 0x52, 0x40, 0x53, 0x78, 0x54, 0xb2, + 0x55, 0xee, 0x57, 0x2d, 0x58, 0x6f, 0x59, 0xb3, 0x5a, 0xfa, 0x5c, 0x44, + 0x5d, 0x91, 0x5e, 0xe2, 0x60, 0x35, 0x61, 0x8b, 0x62, 0xe4, 0x64, 0x3e, + 0x65, 0x9c, 0x66, 0xfb, 0x68, 0x5b, 0x69, 0xbb, 0x6b, 0x1b, 0x6c, 0x7b, + 0x6d, 0xda, 0x6f, 0x3a, 0x70, 0x9b, 0x71, 0xfd, 0x73, 0x61, 0x74, 0xc8, + 0x76, 0x32, 0x77, 0x9f, 0x79, 0x0e, 0x7a, 0x7f, 0x7b, 0xf3, 0x7d, 0x6a, + 0x7e, 0xe3, 0x80, 0x5f, 0x81, 0xdd, 0x83, 0x61, 0x84, 0xe9, 0x86, 0x75, + 0x88, 0x06, 0x89, 0x9d, 0x8b, 0x37, 0x8c, 0xd8, 0x8e, 0x7d, 0x90, 0x28, + 0x91, 0xd6, 0x93, 0x87, 0x95, 0x38, 0x96, 0xe9, 0x98, 0x9a, 0x9a, 0x4b, + 0x9b, 0xfd, 0x9d, 0xb2, 0x9f, 0x69, 0xa1, 0x22, 0xa2, 0xde, 0xa4, 0x98, + 0xa6, 0x53, 0xa8, 0x0d, 0xa9, 0xc7, 0xab, 0x80, 0xad, 0x3d, 0xae, 0xfe, + 0xb0, 0xc3, 0xb2, 0x8d, 0xb4, 0x5d, 0xb6, 0x30, 0xb8, 0x0a, 0xb9, 0xec, + 0xbb, 0xd8, 0xbd, 0xce, 0xbf, 0xcf, 0xc1, 0xd9, 0xc3, 0xed, 0xc6, 0x0d, + 0xc8, 0x36, 0xca, 0x66, 0xcc, 0x9c, 0xce, 0xd6, 0xd1, 0x11, 0xd3, 0x4d, + 0xd5, 0x89, 0xd7, 0xc2, 0xd9, 0xf9, 0xdc, 0x2d, 0xde, 0x5b, 0xe0, 0x83, + 0xe2, 0xa1, 0xe4, 0xb6, 0xe6, 0xc7, 0xe8, 0xd1, 0xea, 0xd8, 0xec, 0xda, + 0xee, 0xd8, 0xf0, 0xd1, 0xf2, 0xc6, 0xf4, 0xb6, 0xf6, 0xa2, 0xf8, 0x8b, + 0xfa, 0x6e, 0xfc, 0x4e, 0xfe, 0x28, 0xff, 0xff, 0x63, 0x75, 0x72, 0x76, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x03, 0x00, 0x05, 0x00, 0x07, 0x00, 0x0a, 0x00, 0x0e, 0x00, 0x13, + 0x00, 0x19, 0x00, 0x20, 0x00, 0x28, 0x00, 0x31, 0x00, 0x3c, 0x00, 0x47, + 0x00, 0x54, 0x00, 0x63, 0x00, 0x72, 0x00, 0x83, 0x00, 0x95, 0x00, 0xa9, + 0x00, 0xbe, 0x00, 0xd4, 0x00, 0xec, 0x01, 0x06, 0x01, 0x21, 0x01, 0x3d, + 0x01, 0x5b, 0x01, 0x7a, 0x01, 0x9b, 0x01, 0xbe, 0x01, 0xe2, 0x02, 0x08, + 0x02, 0x2f, 0x02, 0x58, 0x02, 0x83, 0x02, 0xb0, 0x02, 0xde, 0x03, 0x0e, + 0x03, 0x3f, 0x03, 0x72, 0x03, 0xa8, 0x03, 0xde, 0x04, 0x17, 0x04, 0x52, + 0x04, 0x8e, 0x04, 0xcc, 0x05, 0x0c, 0x05, 0x4e, 0x05, 0x92, 0x05, 0xd8, + 0x06, 0x1f, 0x06, 0x69, 0x06, 0xb5, 0x07, 0x02, 0x07, 0x52, 0x07, 0xa3, + 0x07, 0xf7, 0x08, 0x4d, 0x08, 0xa5, 0x08, 0xff, 0x09, 0x5b, 0x09, 0xb9, + 0x0a, 0x19, 0x0a, 0x7c, 0x0a, 0xe0, 0x0b, 0x47, 0x0b, 0xb0, 0x0c, 0x1c, + 0x0c, 0x8a, 0x0c, 0xfa, 0x0d, 0x6c, 0x0d, 0xe1, 0x0e, 0x58, 0x0e, 0xd1, + 0x0f, 0x4d, 0x0f, 0xcb, 0x10, 0x4c, 0x10, 0xcf, 0x11, 0x55, 0x11, 0xdd, + 0x12, 0x68, 0x12, 0xf5, 0x13, 0x85, 0x14, 0x17, 0x14, 0xac, 0x15, 0x44, + 0x15, 0xe0, 0x16, 0x7c, 0x17, 0x1a, 0x17, 0xba, 0x18, 0x5c, 0x19, 0x00, + 0x19, 0xa6, 0x1a, 0x4d, 0x1a, 0xf7, 0x1b, 0xa2, 0x1c, 0x50, 0x1d, 0x00, + 0x1d, 0xb1, 0x1e, 0x65, 0x1f, 0x1a, 0x1f, 0xd1, 0x20, 0x89, 0x21, 0x43, + 0x21, 0xfe, 0x22, 0xba, 0x23, 0x78, 0x24, 0x37, 0x24, 0xf6, 0x25, 0xb7, + 0x26, 0x7a, 0x27, 0x3d, 0x28, 0x02, 0x28, 0xc8, 0x29, 0x8f, 0x2a, 0x58, + 0x2b, 0x22, 0x2b, 0xee, 0x2c, 0xbc, 0x2d, 0x8e, 0x2e, 0x62, 0x2f, 0x38, + 0x30, 0x12, 0x30, 0xee, 0x31, 0xce, 0x32, 0xb0, 0x33, 0x95, 0x34, 0x7d, + 0x35, 0x67, 0x36, 0x54, 0x37, 0x44, 0x38, 0x37, 0x39, 0x2c, 0x3a, 0x25, + 0x3b, 0x21, 0x3c, 0x20, 0x3d, 0x23, 0x3e, 0x2a, 0x3f, 0x34, 0x40, 0x42, + 0x41, 0x52, 0x42, 0x64, 0x43, 0x78, 0x44, 0x8e, 0x45, 0xa6, 0x46, 0xc0, + 0x47, 0xdb, 0x48, 0xf9, 0x4a, 0x17, 0x4b, 0x37, 0x4c, 0x58, 0x4d, 0x7b, + 0x4e, 0x9f, 0x4f, 0xc5, 0x50, 0xee, 0x52, 0x18, 0x53, 0x45, 0x54, 0x74, + 0x55, 0xa4, 0x56, 0xd9, 0x58, 0x12, 0x59, 0x50, 0x5a, 0x93, 0x5b, 0xdb, + 0x5d, 0x28, 0x5e, 0x7b, 0x5f, 0xd3, 0x61, 0x31, 0x62, 0x93, 0x63, 0xf9, + 0x65, 0x64, 0x66, 0xd3, 0x68, 0x46, 0x69, 0xbb, 0x6b, 0x34, 0x6c, 0xab, + 0x6e, 0x21, 0x6f, 0x95, 0x71, 0x08, 0x72, 0x7a, 0x73, 0xeb, 0x75, 0x5d, + 0x76, 0xce, 0x78, 0x3e, 0x79, 0xae, 0x7b, 0x1e, 0x7c, 0x8c, 0x7d, 0xfa, + 0x7f, 0x67, 0x80, 0xd5, 0x82, 0x4a, 0x83, 0xc6, 0x85, 0x4a, 0x86, 0xd6, + 0x88, 0x6a, 0x8a, 0x07, 0x8b, 0xac, 0x8d, 0x5c, 0x8f, 0x14, 0x90, 0xd6, + 0x92, 0xa0, 0x94, 0x73, 0x96, 0x4e, 0x98, 0x2b, 0x9a, 0x09, 0x9b, 0xe7, + 0x9d, 0xc6, 0x9f, 0xa4, 0xa1, 0x82, 0xa3, 0x5e, 0xa5, 0x35, 0xa7, 0x09, + 0xa8, 0xd9, 0xaa, 0xa5, 0xac, 0x71, 0xae, 0x40, 0xb0, 0x12, 0xb1, 0xe8, + 0xb3, 0xc1, 0xb5, 0x9f, 0xb7, 0x83, 0xb9, 0x6f, 0xbb, 0x61, 0xbd, 0x5c, + 0xbf, 0x60, 0xc1, 0x6c, 0xc3, 0x7b, 0xc5, 0x8c, 0xc7, 0xa1, 0xc9, 0xb7, + 0xcb, 0xcd, 0xcd, 0xe4, 0xcf, 0xf7, 0xd2, 0x07, 0xd4, 0x12, 0xd6, 0x18, + 0xd8, 0x21, 0xda, 0x2f, 0xdc, 0x41, 0xde, 0x57, 0xe0, 0x6f, 0xe2, 0x88, + 0xe4, 0xa1, 0xe6, 0xbd, 0xe8, 0xdc, 0xeb, 0x03, 0xed, 0x29, 0xef, 0x4c, + 0xf1, 0x6c, 0xf3, 0x89, 0xf5, 0xa4, 0xf7, 0xbc, 0xf9, 0xd1, 0xfb, 0xe3, + 0xfd, 0xf2, 0xff, 0xff, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xf6, 0xd6, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x2d, + 0x6d, 0x6c, 0x75, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x0c, 0x65, 0x6e, 0x55, 0x53, 0x00, 0x00, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x1c, 0x00, 0x47, 0x00, 0x6f, 0x00, 0x6f, 0x00, 0x67, + 0x00, 0x6c, 0x00, 0x65, 0x00, 0x20, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x63, + 0x00, 0x2e, 0x00, 0x20, 0x00, 0x32, 0x00, 0x30, 0x00, 0x31, 0x00, 0x36}; + ICCProfile ICCProfileForTestingAdobeRGB() { return ICCProfile::FromDataWithId( reinterpret_cast<const char*>(adobe_rgb_profile_data), @@ -559,4 +728,11 @@ arraysize(colorspin_profile_data), ICCProfile::test_id_color_spin_); } +ICCProfile ICCProfileForTestingNoAnalyticTrFn() { + return ICCProfile::FromDataWithId( + reinterpret_cast<const char*>(no_analytic_tr_fn_profile_data), + arraysize(no_analytic_tr_fn_profile_data), + ICCProfile::test_id_no_analytic_tr_fn_); +} + } // namespace gfx
diff --git a/ui/gfx/test/icc_profiles.h b/ui/gfx/test/icc_profiles.h index 5eb9bd3..464f107 100644 --- a/ui/gfx/test/icc_profiles.h +++ b/ui/gfx/test/icc_profiles.h
@@ -11,4 +11,7 @@ ICCProfile ICCProfileForTestingGenericRGB(); ICCProfile ICCProfileForTestingSRGB(); +// A profile that does not have an analytic transfer function. +ICCProfile ICCProfileForTestingNoAnalyticTrFn(); + } // namespace gfx
diff --git a/ui/gl/gl_switches.cc b/ui/gl/gl_switches.cc index 8171048..2eccfc3 100644 --- a/ui/gl/gl_switches.cc +++ b/ui/gl/gl_switches.cc
@@ -135,3 +135,13 @@ arraysize(kGLSwitchesCopiedFromGpuProcessHost); } // namespace switches + +namespace features { + +#if defined(OS_WIN) +// Wait for D3D VSync signals in GPU process (as opposed to delay based VSync +// generated in Browser process based on VSync parameters). +const base::Feature kD3DVsync{"D3DVsync", base::FEATURE_DISABLED_BY_DEFAULT}; +#endif // defined(OS_WIN) + +} // namespace features
diff --git a/ui/gl/gl_switches.h b/ui/gl/gl_switches.h index 270b3fc..945783b7 100644 --- a/ui/gl/gl_switches.h +++ b/ui/gl/gl_switches.h
@@ -7,6 +7,7 @@ // Defines all the command-line switches used by ui/gl. +#include "base/feature_list.h" #include "ui/gl/gl_export.h" namespace gl { @@ -64,4 +65,12 @@ } // namespace switches +namespace features { + +#if defined(OS_WIN) +GL_EXPORT extern const base::Feature kD3DVsync; +#endif // defined(OS_WIN) + +} // namespace features + #endif // UI_GL_GL_SWITCHES_H_
diff --git a/ui/message_center/notification_list.cc b/ui/message_center/notification_list.cc index 3bac9c1b..9a9ed0f 100644 --- a/ui/message_center/notification_list.cc +++ b/ui/message_center/notification_list.cc
@@ -24,7 +24,7 @@ bool ShouldShowNotificationAsPopup( const Notification& notification, const NotificationBlockers& blockers) { - for (const auto& blocker : blockers) { + for (auto* blocker : blockers) { if (!blocker->ShouldShowNotificationAsPopup(notification)) return false; }
diff --git a/ui/message_center/views/message_list_view.cc b/ui/message_center/views/message_list_view.cc index 51158fd..92d5d7f 100644 --- a/ui/message_center/views/message_list_view.cc +++ b/ui/message_center/views/message_list_view.cc
@@ -188,7 +188,7 @@ has_deferred_task_ = false; // cancel cause OnBoundsAnimatorDone which deletes |deleted_when_done_|. animator_.Cancel(); - for (auto view : deleting_views_) + for (auto* view : deleting_views_) delete view; deleting_views_.clear(); adding_views_.clear(); @@ -230,7 +230,7 @@ void MessageListView::OnBoundsAnimatorProgressed( views::BoundsAnimator* animator) { DCHECK_EQ(&animator_, animator); - for (auto view : deleted_when_done_) { + for (auto* view : deleted_when_done_) { const gfx::SlideAnimation* animation = animator->GetAnimationForView(view); if (animation) view->layer()->SetOpacity(animation->CurrentValueBetween(1.0, 0.0)); @@ -238,7 +238,7 @@ } void MessageListView::OnBoundsAnimatorDone(views::BoundsAnimator* animator) { - for (auto view : deleted_when_done_) + for (auto* view : deleted_when_done_) delete view; deleted_when_done_.clear();
diff --git a/ui/message_center/views/message_list_view_unittest.cc b/ui/message_center/views/message_list_view_unittest.cc index 96c54cd..dd534b2 100644 --- a/ui/message_center/views/message_list_view_unittest.cc +++ b/ui/message_center/views/message_list_view_unittest.cc
@@ -187,7 +187,7 @@ TEST_F(MessageListViewTest, AddNotification) { // Create a dummy notification. - auto notification_view = CreateNotificationView( + auto* notification_view = CreateNotificationView( Notification(NOTIFICATION_TYPE_SIMPLE, std::string(kNotificationId1), base::UTF8ToUTF16("title"), base::UTF8ToUTF16("message1"), gfx::Image(), base::UTF8ToUTF16("display source"), GURL(),
diff --git a/ui/message_center/views/notification_view.cc b/ui/message_center/views/notification_view.cc index c7bdce4..7d880e7 100644 --- a/ui/message_center/views/notification_view.cc +++ b/ui/message_center/views/notification_view.cc
@@ -542,7 +542,7 @@ void NotificationView::CreateOrUpdateListItemViews( const Notification& notification) { - for (auto item_view : item_views_) + for (auto* item_view : item_views_) delete item_view; item_views_.clear(); @@ -623,10 +623,10 @@ bool new_buttons = action_buttons_.size() != buttons.size(); if (new_buttons || buttons.size() == 0) { - for (auto item : separators_) + for (auto* item : separators_) delete item; separators_.clear(); - for (auto item : action_buttons_) + for (auto* item : action_buttons_) delete item; action_buttons_.clear(); }
diff --git a/ui/views/border.cc b/ui/views/border.cc index 14e6d302..61b3b4a 100644 --- a/ui/views/border.cc +++ b/ui/views/border.cc
@@ -10,8 +10,10 @@ #include "base/macros.h" #include "base/memory/ptr_util.h" #include "cc/paint/paint_flags.h" +#include "ui/compositor/dip_util.h" #include "ui/gfx/canvas.h" #include "ui/gfx/geometry/rect_f.h" +#include "ui/gfx/scoped_canvas.h" #include "ui/views/painter.h" #include "ui/views/view.h" @@ -42,18 +44,26 @@ } void SolidSidedBorder::Paint(const View& view, gfx::Canvas* canvas) { - // Top border. - canvas->FillRect(gfx::Rect(0, 0, view.width(), insets_.top()), color_); - // Left border. - canvas->FillRect(gfx::Rect(0, insets_.top(), insets_.left(), - view.height() - insets_.height()), color_); - // Bottom border. - canvas->FillRect(gfx::Rect(0, view.height() - insets_.bottom(), view.width(), - insets_.bottom()), color_); - // Right border. - canvas->FillRect(gfx::Rect(view.width() - insets_.right(), insets_.top(), - insets_.right(), view.height() - insets_.height()), - color_); + // Undo DSF so that we can be sure to draw an integral number of pixels for + // the border. Integral scale factors should be unaffected by this, but for + // fractional scale factors this ensures sharp lines. + gfx::ScopedCanvas scoped(canvas); + float dsf = canvas->UndoDeviceScaleFactor(); + + gfx::RectF scaled_bounds; + if (view.layer()) { + scaled_bounds = + gfx::RectF(ui::ConvertRectToPixel(view.layer(), view.GetLocalBounds())); + } else { + scaled_bounds = gfx::RectF(view.GetLocalBounds()); + scaled_bounds.Scale(dsf); + } + + // This scaling operation floors the inset values. + scaled_bounds.Inset(insets_.Scale(dsf)); + canvas->sk_canvas()->clipRect(gfx::RectFToSkRect(scaled_bounds), + SkClipOp::kDifference, true); + canvas->DrawColor(color_); } gfx::Insets SolidSidedBorder::GetInsets() const {
diff --git a/ui/views/border_unittest.cc b/ui/views/border_unittest.cc index ab428df..09d2b4e 100644 --- a/ui/views/border_unittest.cc +++ b/ui/views/border_unittest.cc
@@ -72,6 +72,12 @@ draw_rrect_calls_.end()); } + const std::vector<SkPaint>& draw_paint_calls() const { + return draw_paint_calls_; + } + + const SkRect& last_clip_bounds() const { return last_clip_bounds_; } + // SkCanvas overrides: void onDrawRect(const SkRect& rect, const SkPaint& paint) override { draw_rect_calls_.insert(DrawRectCall(rect, paint)); @@ -81,11 +87,25 @@ draw_rrect_calls_.insert(DrawRRectCall(rrect, paint)); } + void onDrawPaint(const SkPaint& paint) override { + draw_paint_calls_.push_back(paint); + } + + void onClipRect(const SkRect& rect, + SkClipOp op, + ClipEdgeStyle edge_style) override { + last_clip_bounds_ = rect; + } + private: // Stores all the calls for querying by the test, in sorted order. std::set<DrawRectCall> draw_rect_calls_; std::set<DrawRRectCall> draw_rrect_calls_; + // Stores the onDrawPaint calls in chronological order. + std::vector<SkPaint> draw_paint_calls_; + SkRect last_clip_bounds_; + DISALLOW_COPY_AND_ASSIGN(MockCanvas); }; @@ -155,24 +175,19 @@ } TEST_F(BorderTest, SolidBorder) { - std::unique_ptr<Border> border(CreateSolidBorder(3, SK_ColorBLUE)); + const SkColor kBorderColor = SK_ColorMAGENTA; + std::unique_ptr<Border> border(CreateSolidBorder(3, kBorderColor)); EXPECT_EQ(gfx::Size(6, 6), border->GetMinimumSize()); EXPECT_EQ(gfx::Insets(3, 3, 3, 3), border->GetInsets()); border->Paint(*view_, canvas_.get()); - std::vector<MockCanvas::DrawRectCall> draw_rect_calls = - sk_canvas_->draw_rect_calls(); - ASSERT_EQ(4u, draw_rect_calls.size()); - EXPECT_EQ(SkRect::MakeLTRB(0, 0, 100, 3), draw_rect_calls[0].rect); - EXPECT_EQ(SK_ColorBLUE, draw_rect_calls[0].paint.getColor()); - EXPECT_EQ(SkRect::MakeLTRB(0, 3, 3, 47), draw_rect_calls[1].rect); - EXPECT_EQ(SK_ColorBLUE, draw_rect_calls[1].paint.getColor()); - EXPECT_EQ(SkRect::MakeLTRB(0, 47, 100, 50), draw_rect_calls[2].rect); - EXPECT_EQ(SK_ColorBLUE, draw_rect_calls[2].paint.getColor()); - EXPECT_EQ(SkRect::MakeLTRB(97, 3, 100, 47), draw_rect_calls[3].rect); - EXPECT_EQ(SK_ColorBLUE, draw_rect_calls[3].paint.getColor()); + gfx::Rect bounds = view_->GetLocalBounds(); + bounds.Inset(border->GetInsets()); - EXPECT_TRUE(sk_canvas_->draw_rrect_calls().empty()); + ASSERT_EQ(1u, sk_canvas_->draw_paint_calls().size()); + EXPECT_EQ(kBorderColor, sk_canvas_->draw_paint_calls()[0].getColor()); + EXPECT_EQ(gfx::RectF(bounds), + gfx::SkRectToRectF(sk_canvas_->last_clip_bounds())); } TEST_F(BorderTest, RoundedRectBorder) { @@ -210,28 +225,23 @@ } TEST_F(BorderTest, SolidSidedBorder) { + const SkColor kBorderColor = SK_ColorMAGENTA; const gfx::Insets kInsets(1, 2, 3, 4); std::unique_ptr<Border> border( CreateSolidSidedBorder(kInsets.top(), kInsets.left(), kInsets.bottom(), - kInsets.right(), SK_ColorBLUE)); + kInsets.right(), kBorderColor)); EXPECT_EQ(gfx::Size(6, 4), border->GetMinimumSize()); EXPECT_EQ(kInsets, border->GetInsets()); border->Paint(*view_, canvas_.get()); - std::vector<MockCanvas::DrawRectCall> draw_rect_calls = - sk_canvas_->draw_rect_calls(); - ASSERT_EQ(4u, draw_rect_calls.size()); - EXPECT_EQ(SkRect::MakeLTRB(0, 0, 100, 1), draw_rect_calls[0].rect); - EXPECT_EQ(SK_ColorBLUE, draw_rect_calls[0].paint.getColor()); - EXPECT_EQ(SkRect::MakeLTRB(0, 1, 2, 47), draw_rect_calls[1].rect); - EXPECT_EQ(SK_ColorBLUE, draw_rect_calls[1].paint.getColor()); - EXPECT_EQ(SkRect::MakeLTRB(0, 47, 100, 50), draw_rect_calls[2].rect); - EXPECT_EQ(SK_ColorBLUE, draw_rect_calls[2].paint.getColor()); - EXPECT_EQ(SkRect::MakeLTRB(96, 1, 100, 47), draw_rect_calls[3].rect); - EXPECT_EQ(SK_ColorBLUE, draw_rect_calls[3].paint.getColor()); + gfx::Rect bounds = view_->GetLocalBounds(); + bounds.Inset(border->GetInsets()); - EXPECT_TRUE(sk_canvas_->draw_rrect_calls().empty()); + ASSERT_EQ(1u, sk_canvas_->draw_paint_calls().size()); + EXPECT_EQ(kBorderColor, sk_canvas_->draw_paint_calls()[0].getColor()); + EXPECT_EQ(gfx::RectF(bounds), + gfx::SkRectToRectF(sk_canvas_->last_clip_bounds())); } TEST_F(BorderTest, BorderPainter) {
diff --git a/ui/views/controls/menu/menu_item_view.cc b/ui/views/controls/menu/menu_item_view.cc index def3514..450cf5ac 100644 --- a/ui/views/controls/menu/menu_item_view.cc +++ b/ui/views/controls/menu/menu_item_view.cc
@@ -524,7 +524,7 @@ } } - for (auto item : removed_items_) + for (auto* item : removed_items_) delete item; removed_items_.clear(); } @@ -599,7 +599,7 @@ MenuItemView::~MenuItemView() { delete submenu_; - for (auto item : removed_items_) + for (auto* item : removed_items_) delete item; }
diff --git a/ui/views/controls/scrollbar/overlay_scroll_bar.cc b/ui/views/controls/scrollbar/overlay_scroll_bar.cc index 4c0a6d5..83d7a58 100644 --- a/ui/views/controls/scrollbar/overlay_scroll_bar.cc +++ b/ui/views/controls/scrollbar/overlay_scroll_bar.cc
@@ -110,7 +110,7 @@ OverlayScrollBar::OverlayScrollBar(bool horizontal) : BaseScrollBar(horizontal), hide_timer_(false, false) { - auto thumb = new Thumb(this); + auto* thumb = new Thumb(this); SetThumb(thumb); thumb->Init(); set_notify_enter_exit_on_child(true);
diff --git a/ui/views/examples/BUILD.gn b/ui/views/examples/BUILD.gn index ef70dd3..3f27518f 100644 --- a/ui/views/examples/BUILD.gn +++ b/ui/views/examples/BUILD.gn
@@ -18,6 +18,8 @@ "checkbox_example.h", "combobox_example.cc", "combobox_example.h", + "dialog_example.cc", + "dialog_example.h", "example_base.cc", "example_base.h", "example_combobox_model.cc",
diff --git a/ui/views/examples/button_sticker_sheet.cc b/ui/views/examples/button_sticker_sheet.cc index dc98a83..9b32de4f 100644 --- a/ui/views/examples/button_sticker_sheet.cc +++ b/ui/views/examples/button_sticker_sheet.cc
@@ -56,7 +56,7 @@ const int kPaddingRowHeight = 8; layout->StartRow(kRowDoesNotResizeVertically, kStretchyGridColumnSetId); layout->AddView(MakePlainLabel(label_text)); - for (const auto& view : views) + for (auto* view : views) layout->AddView(view); // This gets added extraneously after the last row, but it doesn't hurt and // means there's no need to keep track of whether to add it or not.
diff --git a/ui/views/examples/dialog_example.cc b/ui/views/examples/dialog_example.cc new file mode 100644 index 0000000..637c6da --- /dev/null +++ b/ui/views/examples/dialog_example.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 "ui/views/examples/dialog_example.h" + +#include "base/macros.h" +#include "base/strings/utf_string_conversions.h" +#include "ui/views/bubble/bubble_dialog_delegate.h" +#include "ui/views/controls/button/checkbox.h" +#include "ui/views/controls/button/label_button.h" +#include "ui/views/controls/button/md_text_button.h" +#include "ui/views/controls/combobox/combobox.h" +#include "ui/views/controls/label.h" +#include "ui/views/controls/textfield/textfield.h" +#include "ui/views/layout/fill_layout.h" +#include "ui/views/layout/grid_layout.h" +#include "ui/views/layout/layout_constants.h" +#include "ui/views/views_delegate.h" +#include "ui/views/widget/widget.h" +#include "ui/views/window/dialog_client_view.h" + +using base::ASCIIToUTF16; + +namespace views { +namespace examples { +namespace { + +constexpr int kFieldsColumnId = 0; +constexpr int kButtonsColumnId = 1; +constexpr int kFakeModeless = ui::MODAL_TYPE_SYSTEM + 1; + +} // namespace + +template <class DialogType> +class DialogExample::Delegate : public virtual DialogType { + public: + explicit Delegate(DialogExample* parent) : parent_(parent) {} + + void InitDelegate() { + LayoutManager* fill_layout = new FillLayout(); + this->SetLayoutManager(fill_layout); + Label* body = new Label(parent_->body_->text()); + body->SetMultiLine(true); + body->SetHorizontalAlignment(gfx::ALIGN_LEFT); + body->set_background(Background::CreateSolidBackground(0, 255, 255)); + this->AddChildView(body); + + // Give the example code a way to change the body text. + parent_->last_body_label_ = body; + } + + protected: + // WidgetDelegate: + ui::ModalType GetModalType() const override { + return parent_->GetModalType(); + } + + base::string16 GetWindowTitle() const override { + return parent_->title_->text(); + } + + // DialogDelegate: + View* CreateExtraView() { + if (!parent_->has_extra_button_->checked()) + return nullptr; + return MdTextButton::CreateSecondaryUiButton( + nullptr, parent_->extra_button_label_->text()); + } + + bool Cancel() override { return parent_->AllowDialogClose(false); } + bool Accept() override { return parent_->AllowDialogClose(true); } + int GetDialogButtons() const override { return parent_->GetDialogButtons(); } + base::string16 GetDialogButtonLabel(ui::DialogButton button) const override { + if (button == ui::DIALOG_BUTTON_OK) + return parent_->ok_button_label_->text(); + if (button == ui::DIALOG_BUTTON_CANCEL) + return parent_->cancel_button_label_->text(); + return base::string16(); + } + + private: + DialogExample* parent_; + + DISALLOW_COPY_AND_ASSIGN(Delegate); +}; + +class DialogExample::Bubble : public Delegate<BubbleDialogDelegateView> { + public: + Bubble(DialogExample* parent, View* anchor) + : BubbleDialogDelegateView(anchor, BubbleBorder::TOP_LEFT), + Delegate(parent) { + set_close_on_deactivate(!parent->persistent_bubble_->checked()); + } + + // BubbleDialogDelegateView: + void Init() override { InitDelegate(); } + + private: + DISALLOW_COPY_AND_ASSIGN(Bubble); +}; + +class DialogExample::Dialog : public Delegate<DialogDelegateView> { + public: + explicit Dialog(DialogExample* parent) : Delegate(parent) {} + + // WidgetDelegate: + bool CanResize() const override { + // Mac supports resizing of modal dialogs (parent or window-modal). On other + // platforms this will be weird unless the modal type is "none", but helps + // test layout. + return true; + } + + private: + DISALLOW_COPY_AND_ASSIGN(Dialog); +}; + +DialogExample::DialogExample() + : ExampleBase("Dialog"), + mode_model_({ + base::ASCIIToUTF16("Modeless"), base::ASCIIToUTF16("Window Modal"), + base::ASCIIToUTF16("Child Modal"), base::ASCIIToUTF16("System Modal"), + base::ASCIIToUTF16("Fake Modeless (non-bubbles)"), + }) {} + +DialogExample::~DialogExample() {} + +void DialogExample::CreateExampleView(View* container) { + // GridLayout |resize_percent| constants. + const float kFixed = 0.f; + const float kStretchy = 1.f; + + const int horizontal_spacing = + ViewsDelegate::GetInstance()->GetDialogRelatedButtonHorizontalSpacing(); + GridLayout* layout = GridLayout::CreatePanel(container); + container->SetLayoutManager(layout); + ColumnSet* column_set = layout->AddColumnSet(kFieldsColumnId); + column_set->AddColumn(GridLayout::LEADING, GridLayout::FILL, kFixed, + GridLayout::USE_PREF, 0, 0); + column_set->AddPaddingColumn(kFixed, horizontal_spacing); + column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, kStretchy, + GridLayout::USE_PREF, 0, 0); + column_set->AddPaddingColumn(kFixed, horizontal_spacing); + column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, kFixed, + GridLayout::USE_PREF, 0, 0); + StartTextfieldRow(layout, &title_, "Dialog Title", "Title"); + StartTextfieldRow(layout, &body_, "Dialog Body Text", "Body Text"); + + StartTextfieldRow(layout, &ok_button_label_, "OK Button Label", "Done"); + AddCheckbox(layout, &has_ok_button_); + + StartTextfieldRow(layout, &cancel_button_label_, "Cancel Button Label", + "Cancel"); + AddCheckbox(layout, &has_cancel_button_); + + StartTextfieldRow(layout, &extra_button_label_, "Extra Button Label", "Edit"); + AddCheckbox(layout, &has_extra_button_); + + StartRowWithLabel(layout, "Modal Type"); + mode_ = new Combobox(&mode_model_); + mode_->set_listener(this); + mode_->SetSelectedIndex(ui::MODAL_TYPE_CHILD); + layout->AddView(mode_); + + StartRowWithLabel(layout, "Bubble"); + AddCheckbox(layout, &bubble_); + AddCheckbox(layout, &persistent_bubble_); + persistent_bubble_->SetText(base::ASCIIToUTF16("Persistent")); + + column_set = layout->AddColumnSet(kButtonsColumnId); + column_set->AddColumn(GridLayout::CENTER, GridLayout::CENTER, kStretchy, + GridLayout::USE_PREF, 0, 0); + layout->StartRowWithPadding(kFixed, kButtonsColumnId, kFixed, + kUnrelatedControlVerticalSpacing); + show_ = + MdTextButton::CreateSecondaryUiButton(this, base::ASCIIToUTF16("Show")); + layout->AddView(show_); + + // Grow the dialog a bit when this example is first selected, so it all fits. + gfx::Size dialog_size = container->GetWidget()->GetRestoredBounds().size(); + dialog_size.set_height(dialog_size.height() + 80); + container->GetWidget()->SetSize(dialog_size); +} + +void DialogExample::StartRowWithLabel(GridLayout* layout, const char* label) { + const float kFixedVerticalResize = 0.f; + layout->StartRowWithPadding( + kFixedVerticalResize, kFieldsColumnId, kFixedVerticalResize, + ViewsDelegate::GetInstance()->GetDialogRelatedControlVerticalSpacing()); + layout->AddView(new Label(base::ASCIIToUTF16(label))); +} + +void DialogExample::StartTextfieldRow(GridLayout* layout, + Textfield** member, + const char* label, + const char* value) { + StartRowWithLabel(layout, label); + Textfield* textfield = new Textfield(); + layout->AddView(textfield); + textfield->set_controller(this); + textfield->SetText(base::ASCIIToUTF16(value)); + *member = textfield; +} + +void DialogExample::AddCheckbox(GridLayout* layout, Checkbox** member) { + Checkbox* checkbox = new Checkbox(base::string16()); + checkbox->set_listener(this); + checkbox->SetChecked(true); + layout->AddView(checkbox); + *member = checkbox; +} + +ui::ModalType DialogExample::GetModalType() const { + // "Fake" modeless happens when a DialogDelegate specifies window-modal, but + // doesn't provide a parent window. + if (mode_->selected_index() == kFakeModeless) + return ui::MODAL_TYPE_WINDOW; + + return static_cast<ui::ModalType>(mode_->selected_index()); +} + +int DialogExample::GetDialogButtons() const { + int buttons = 0; + if (has_ok_button_->checked()) + buttons |= ui::DIALOG_BUTTON_OK; + if (has_cancel_button_->checked()) + buttons |= ui::DIALOG_BUTTON_CANCEL; + return buttons; +} + +bool DialogExample::AllowDialogClose(bool accept) { + PrintStatus("Dialog closed with %s.", accept ? "Accept" : "Cancel"); + last_dialog_ = nullptr; + last_body_label_ = nullptr; + return true; +} + +void DialogExample::ResizeDialog() { + DCHECK(last_dialog_); + Widget* widget = last_dialog_->GetWidget(); + gfx::Rect preferred_bounds(widget->GetRestoredBounds()); + preferred_bounds.set_size(widget->non_client_view()->GetPreferredSize()); + + // Q: Do we need NonClientFrameView::GetWindowBoundsForClientBounds() here? + // A: When DialogCientView properly feeds back sizes, we do not. + widget->SetBoundsConstrained(preferred_bounds); +} + +void DialogExample::ButtonPressed(Button* sender, const ui::Event& event) { + if (sender == show_) { + if (bubble_->checked()) { + Bubble* bubble = new Bubble(this, sender); + last_dialog_ = bubble; + BubbleDialogDelegateView::CreateBubble(bubble); + } else { + Dialog* dialog = new Dialog(this); + last_dialog_ = dialog; + dialog->InitDelegate(); + + // constrained_window::CreateBrowserModalDialogViews() allows dialogs to + // be created as MODAL_TYPE_WINDOW without specifying a parent. + gfx::NativeView parent = nullptr; + if (mode_->selected_index() != kFakeModeless) + parent = container()->GetWidget()->GetNativeView(); + + DialogDelegate::CreateDialogWidget( + dialog, container()->GetWidget()->GetNativeWindow(), parent); + } + last_dialog_->GetWidget()->Show(); + return; + } + + if (sender == bubble_) { + if (bubble_->checked() && GetModalType() != ui::MODAL_TYPE_CHILD) { + mode_->SetSelectedIndex(ui::MODAL_TYPE_CHILD); + PrintStatus("You nearly always want Child Modal for bubbles."); + } + persistent_bubble_->SetEnabled(bubble_->checked()); + OnPerformAction(mode_); // Validate the modal type. + + if (!bubble_->checked() && GetModalType() == ui::MODAL_TYPE_CHILD) { + // Do something reasonable when simply unchecking bubble and re-enable. + mode_->SetSelectedIndex(ui::MODAL_TYPE_WINDOW); + OnPerformAction(mode_); + } + return; + } + + // Other buttons are all checkboxes. Update the dialog if there is one. + if (last_dialog_) { + last_dialog_->GetDialogClientView()->UpdateDialogButtons(); + ResizeDialog(); + } +} + +void DialogExample::ContentsChanged(Textfield* sender, + const base::string16& new_contents) { + if (!last_dialog_) + return; + + if (sender == extra_button_label_) + PrintStatus("DialogClientView can never refresh the extra view."); + + if (sender == title_) { + last_dialog_->GetWidget()->UpdateWindowTitle(); + } else if (sender == body_) { + last_body_label_->SetText(new_contents); + } else { + last_dialog_->GetDialogClientView()->UpdateDialogButtons(); + } + + ResizeDialog(); +} + +void DialogExample::OnPerformAction(Combobox* combobox) { + bool enable = bubble_->checked() || GetModalType() != ui::MODAL_TYPE_CHILD; +#if defined(OS_MACOSX) + enable = enable && GetModalType() != ui::MODAL_TYPE_SYSTEM; +#endif + show_->SetEnabled(enable); + if (!enable && GetModalType() == ui::MODAL_TYPE_CHILD) + PrintStatus("MODAL_TYPE_CHILD can't be used with non-bubbles."); + if (!enable && GetModalType() == ui::MODAL_TYPE_SYSTEM) + PrintStatus("MODAL_TYPE_SYSTEM isn't supported on Mac."); +} + +} // namespace examples +} // namespace views
diff --git a/ui/views/examples/dialog_example.h b/ui/views/examples/dialog_example.h new file mode 100644 index 0000000..3731846 --- /dev/null +++ b/ui/views/examples/dialog_example.h
@@ -0,0 +1,96 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_VIEWS_EXAMPLES_DIALOG_EXAMPLE_H_ +#define UI_VIEWS_EXAMPLES_DIALOG_EXAMPLE_H_ + +#include "base/macros.h" +#include "ui/base/models/simple_combobox_model.h" +#include "ui/views/controls/button/button.h" +#include "ui/views/controls/combobox/combobox_listener.h" +#include "ui/views/controls/textfield/textfield_controller.h" +#include "ui/views/examples/example_base.h" + +namespace views { + +class Checkbox; +class Combobox; +class DialogDelegate; +class GridLayout; +class Label; +class LabelButton; +class Textfield; + +namespace examples { + +// An example that exercises BubbleDialogDelegateView or DialogDelegateView. +class VIEWS_EXAMPLES_EXPORT DialogExample : public ExampleBase, + public ButtonListener, + public TextfieldController, + public ComboboxListener { + public: + DialogExample(); + ~DialogExample() override; + + // ExampleBase: + void CreateExampleView(View* container) override; + + private: + template <class> + class Delegate; + class Bubble; + class Dialog; + + // Helper methods to setup the configuration Views. + void StartRowWithLabel(GridLayout* layout, const char* label); + void StartTextfieldRow(GridLayout* layout, + Textfield** member, + const char* label, + const char* value); + void AddCheckbox(GridLayout* layout, Checkbox** member); + + // Interrogates the configuration Views for DialogDelegate. + ui::ModalType GetModalType() const; + int GetDialogButtons() const; + + // Invoked when the dialog is closing. + bool AllowDialogClose(bool accept); + + // Resize the dialog Widget to match the preferred size. Triggers Layout(). + void ResizeDialog(); + + // ButtonListener: + void ButtonPressed(Button* sender, const ui::Event& event) override; + + // TextfieldController: + void ContentsChanged(Textfield* sender, + const base::string16& new_contents) override; + + // ComboboxListener: + void OnPerformAction(Combobox* combobox) override; + + DialogDelegate* last_dialog_ = nullptr; + Label* last_body_label_ = nullptr; + + Textfield* title_; + Textfield* body_; + Textfield* ok_button_label_; + Checkbox* has_ok_button_; + Textfield* cancel_button_label_; + Checkbox* has_cancel_button_; + Textfield* extra_button_label_; + Checkbox* has_extra_button_; + Combobox* mode_; + Checkbox* bubble_; + Checkbox* persistent_bubble_; + LabelButton* show_; + ui::SimpleComboboxModel mode_model_; + + DISALLOW_COPY_AND_ASSIGN(DialogExample); +}; + +} // namespace examples +} // namespace views + +#endif // UI_VIEWS_EXAMPLES_DIALOG_EXAMPLE_H_
diff --git a/ui/views/examples/examples_window.cc b/ui/views/examples/examples_window.cc index 0cd2669..f6a1707 100644 --- a/ui/views/examples/examples_window.cc +++ b/ui/views/examples/examples_window.cc
@@ -23,6 +23,7 @@ #include "ui/views/examples/button_sticker_sheet.h" #include "ui/views/examples/checkbox_example.h" #include "ui/views/examples/combobox_example.h" +#include "ui/views/examples/dialog_example.h" #include "ui/views/examples/label_example.h" #include "ui/views/examples/link_example.h" #include "ui/views/examples/menu_example.h" @@ -61,6 +62,7 @@ examples.push_back(base::MakeUnique<ButtonStickerSheet>()); examples.push_back(base::MakeUnique<CheckboxExample>()); examples.push_back(base::MakeUnique<ComboboxExample>()); + examples.push_back(base::MakeUnique<DialogExample>()); examples.push_back(base::MakeUnique<LabelExample>()); examples.push_back(base::MakeUnique<LinkExample>()); examples.push_back(base::MakeUnique<MenuExample>());
diff --git a/ui/views/layout/grid_layout.cc b/ui/views/layout/grid_layout.cc index eb4dd9d1..8c7dcfb 100644 --- a/ui/views/layout/grid_layout.cc +++ b/ui/views/layout/grid_layout.cc
@@ -236,11 +236,11 @@ // Accumulate the size first. int size = 0; - for (auto column : same_size_columns_) + for (auto* column : same_size_columns_) size = std::max(size, column->Size()); // Then apply it. - for (auto column : same_size_columns_) + for (auto* column : same_size_columns_) column->SetSize(size); } @@ -496,7 +496,7 @@ } void ColumnSet::UnifySameSizedColumnSizes() { - for (auto column : master_columns_) + for (auto* column : master_columns_) column->UnifySameSizedColumnSizes(); } @@ -583,7 +583,7 @@ void ColumnSet::CalculateSize() { gfx::Size pref; // Reset the preferred and remaining sizes. - for (const auto& view_state : view_states_) { + for (auto* view_state : view_states_) { if (!view_state->pref_width_fixed || !view_state->pref_height_fixed) { pref = view_state->view->GetPreferredSize(); if (!view_state->pref_width_fixed)
diff --git a/ui/views/test/ui_controls_factory_desktop_aurax11.cc b/ui/views/test/ui_controls_factory_desktop_aurax11.cc index d7b41b1..117a268 100644 --- a/ui/views/test/ui_controls_factory_desktop_aurax11.cc +++ b/ui/views/test/ui_controls_factory_desktop_aurax11.cc
@@ -146,7 +146,7 @@ aura::test::QueryLatestMousePositionRequestInHost(host); host->ConvertPixelsToDIP(&root_current_location); - auto screen = views::test::TestDesktopScreenX11::GetInstance(); + auto* screen = views::test::TestDesktopScreenX11::GetInstance(); DCHECK_EQ(screen, display::Screen::GetScreen()); screen->set_cursor_screen_point(gfx::Point(screen_x, screen_y));
diff --git a/url/origin_unittest.cc b/url/origin_unittest.cc index a5c3042..4e1139c 100644 --- a/url/origin_unittest.cc +++ b/url/origin_unittest.cc
@@ -262,7 +262,7 @@ "https-so://.", "https-so://foo", "https-so://.foo", "https-so://foo.", }; - for (const auto& test_case : failure_cases) { + for (auto* test_case : failure_cases) { SCOPED_TRACE(test_case); GURL url(test_case); EXPECT_TRUE(url.is_valid());