diff --git a/.gn b/.gn index 8fb99ced..6f277297 100644 --- a/.gn +++ b/.gn
@@ -323,7 +323,6 @@ "//third_party/accessibility_test_framework/*", "//third_party/adobe/*", "//third_party/afl/*", - "//third_party/analytics/*", "//third_party/android_build_tools/*", "//third_party/android_crazy_linker/*", "//third_party/android_data_chart/*",
diff --git a/DEPS b/DEPS index 034d32ea..f40187f 100644 --- a/DEPS +++ b/DEPS
@@ -116,7 +116,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': '73bc258c965df798cbae6c86d1d543bd51c1c084', + 'v8_revision': 'ab168019ec9085b4e6c0c1e4fee8f3b763682eaf', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other. @@ -124,7 +124,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': '4f2b94cb9a6bb640110ea65a7637872b83acbba8', + 'angle_revision': '752d220a5f31c68ecba0fc845493dcc36bc40eb4', # 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. @@ -136,7 +136,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': 'adb9e705092bbf03eebe0edaf687090266b64fcc', + 'pdfium_revision': '3e2cdea95cd8803638194a51aefe57f16dba55df', # 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. @@ -651,7 +651,7 @@ # Build tools for Chrome OS. Note: This depends on third_party/pyelftools. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'bd884bbd838523f137e7493248b08ccbb3d28ad7', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '36900aad7d961f0efd79da61cff67075758ac9c7', 'condition': 'checkout_linux', }, @@ -957,7 +957,7 @@ 'src/third_party/nasm': { 'url': Var('chromium_git') + '/chromium/deps/nasm.git' + '@' + - 'a0a6951e259bd347c133969740348bb5ebb468c4' + '4ee6a69ce33be1e96fd3c44a6e3ae3d8177453da' }, 'src/third_party/netty-tcnative/src': { @@ -1008,7 +1008,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + '1561e23284f165220888a9f6ea36c77c952344e8', + Var('android_git') + '/platform/external/perfetto.git' + '@' + 'fb903439b2138e98d4e4de3c2850134cec0cd35b', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + 'ac0d98b5cee6c024b0cffeb4f8f45b6fc5ccdb78', @@ -1171,7 +1171,7 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '5b6cbd789b9b91b4e46dde883c9f2ecb31eddade', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '6b3d18164b4ac2eb954663d162644a12eeb13ea6', + Var('webrtc_git') + '/src.git' + '@' + '59cfd35438753acd69859e8a2f98f6490e68d6a0', 'src/third_party/xdg-utils': { 'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d', @@ -1202,7 +1202,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@af1cdca8c14045c56c5ca603878997e9ffbfcea2', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@7f2a2ae33b386bbbed06a86263b9273d93259e1b', 'condition': 'checkout_src_internal', },
diff --git a/android_webview/browser/aw_contents.cc b/android_webview/browser/aw_contents.cc index 0cf07c5c..7003b2d 100644 --- a/android_webview/browser/aw_contents.cc +++ b/android_webview/browser/aw_contents.cc
@@ -235,7 +235,6 @@ AwContents::AwContents(std::unique_ptr<WebContents> web_contents) : content::WebContentsObserver(web_contents.get()), - functor_(nullptr), browser_view_renderer_( this, base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::UI})), @@ -395,16 +394,8 @@ } void AwContents::SetAwGLFunctor(AwGLFunctor* functor) { - if (functor == functor_) { - return; - } - functor_ = functor; - if (functor_) { - browser_view_renderer_.SetCurrentCompositorFrameConsumer( - functor_->GetCompositorFrameConsumer()); - } else { - browser_view_renderer_.SetCurrentCompositorFrameConsumer(nullptr); - } + browser_view_renderer_.SetCurrentCompositorFrameConsumer( + functor ? functor->GetCompositorFrameConsumer() : nullptr); } void AwContents::SetAwGLFunctor(JNIEnv* env,
diff --git a/android_webview/browser/aw_contents.h b/android_webview/browser/aw_contents.h index 5abbceb..6dbeb700 100644 --- a/android_webview/browser/aw_contents.h +++ b/android_webview/browser/aw_contents.h
@@ -374,7 +374,6 @@ void SetAwGLFunctor(AwGLFunctor* functor); JavaObjectWeakGlobalRef java_ref_; - AwGLFunctor* functor_; BrowserViewRenderer browser_view_renderer_; // Must outlive |web_contents_|. std::unique_ptr<content::WebContents> web_contents_; std::unique_ptr<AwWebContentsDelegate> web_contents_delegate_;
diff --git a/android_webview/common/aw_content_client.cc b/android_webview/common/aw_content_client.cc index 1514c944..babb0fe 100644 --- a/android_webview/common/aw_content_client.cc +++ b/android_webview/common/aw_content_client.cc
@@ -45,6 +45,7 @@ schemes->local_schemes.push_back(url::kContentScheme); schemes->secure_schemes.push_back( android_webview::kAndroidWebViewVideoPosterScheme); + schemes->allow_non_standard_schemes_in_origins = true; } std::string AwContentClient::GetProduct() const {
diff --git a/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromium.java b/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromium.java index d77fc1c..e34c01d 100644 --- a/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromium.java +++ b/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromium.java
@@ -265,7 +265,7 @@ || mAppTargetSdkVersion < Build.VERSION_CODES.LOLLIPOP); mAwContents = new AwContents(mFactory.getBrowserContextOnUiThread(), mWebView, mContext, - new InternalAccessAdapter(), new WebViewNativeDrawGLFunctorFactory(), + new InternalAccessAdapter(), new WebViewNativeDrawFunctorFactory(), mContentsClientAdapter, mWebSettings.getAwSettings(), new AwContents.DependencyFactory() { @Override @@ -2275,11 +2275,10 @@ checkThread(); return new AwPrintDocumentAdapter(mAwContents.getPdfExporter(), documentName); } - // AwContents.NativeDrawGLFunctorFactory implementation ---------------------------------- - private class WebViewNativeDrawGLFunctorFactory - implements AwContents.NativeDrawGLFunctorFactory { + // AwContents.NativeDrawFunctorFactory implementation ---------------------------------- + private class WebViewNativeDrawFunctorFactory implements AwContents.NativeDrawFunctorFactory { @Override - public AwContents.NativeDrawGLFunctor createFunctor(long context) { + public AwContents.NativeDrawGLFunctor createGLFunctor(long context) { return new DrawGLFunctor(context, mFactory.getWebViewDelegate()); } }
diff --git a/android_webview/java/src/org/chromium/android_webview/AwContents.java b/android_webview/java/src/org/chromium/android_webview/AwContents.java index 85b9d55..58871c3 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwContents.java +++ b/android_webview/java/src/org/chromium/android_webview/AwContents.java
@@ -255,11 +255,11 @@ * calling back into Chromium code to render the the contents of a Chromium frame into * an Android view. */ - public interface NativeDrawGLFunctorFactory { + public interface NativeDrawFunctorFactory { /** - * Create a functor associated with native context |context|. + * Create a GL functor associated with native context |context|. */ - NativeDrawGLFunctor createFunctor(long context); + NativeDrawGLFunctor createGLFunctor(long context); } /** @@ -360,7 +360,7 @@ private final AwContentsIoThreadClient mIoThreadClient; private final InterceptNavigationDelegateImpl mInterceptNavigationDelegate; private InternalAccessDelegate mInternalAccessAdapter; - private final NativeDrawGLFunctorFactory mNativeDrawGLFunctorFactory; + private final NativeDrawFunctorFactory mNativeDrawFunctorFactory; private final AwLayoutSizer mLayoutSizer; private final AwZoomControls mZoomControls; private final AwScrollOffsetManager mScrollOffsetManager; @@ -816,7 +816,7 @@ * @param containerView the view-hierarchy item this object will be bound to. * @param context the context to use, usually containerView.getContext(). * @param internalAccessAdapter to access private methods on containerView. - * @param nativeGLDelegate to access the GL functor provided by the WebView. + * @param nativeDrawFunctorFactory to access the functor provided by the WebView. * @param contentsClient will receive API callbacks from this WebView Contents. * @param awSettings AwSettings instance used to configure the AwContents. * @@ -824,10 +824,10 @@ */ public AwContents(AwBrowserContext browserContext, ViewGroup containerView, Context context, InternalAccessDelegate internalAccessAdapter, - NativeDrawGLFunctorFactory nativeDrawGLFunctorFactory, AwContentsClient contentsClient, + NativeDrawFunctorFactory nativeDrawFunctorFactory, AwContentsClient contentsClient, AwSettings awSettings) { this(browserContext, containerView, context, internalAccessAdapter, - nativeDrawGLFunctorFactory, contentsClient, awSettings, new DependencyFactory()); + nativeDrawFunctorFactory, contentsClient, awSettings, new DependencyFactory()); } /** @@ -839,7 +839,7 @@ */ public AwContents(AwBrowserContext browserContext, ViewGroup containerView, Context context, InternalAccessDelegate internalAccessAdapter, - NativeDrawGLFunctorFactory nativeDrawGLFunctorFactory, AwContentsClient contentsClient, + NativeDrawFunctorFactory nativeDrawFunctorFactory, AwContentsClient contentsClient, AwSettings settings, DependencyFactory dependencyFactory) { try (ScopedSysTraceEvent e1 = ScopedSysTraceEvent.scoped("AwContents.constructor")) { mRendererPriority = RendererPriority.HIGH; @@ -859,7 +859,7 @@ mAutofillProvider = dependencyFactory.createAutofillProvider(context, mContainerView); mAppTargetSdkVersion = mContext.getApplicationInfo().targetSdkVersion; mInternalAccessAdapter = internalAccessAdapter; - mNativeDrawGLFunctorFactory = nativeDrawGLFunctorFactory; + mNativeDrawFunctorFactory = nativeDrawFunctorFactory; mContentsClient = contentsClient; mContentsClient.getCallbackHelper().setCancelCallbackPoller( () -> AwContents.this.isDestroyedOrNoOperation(NO_WARN)); @@ -3381,7 +3381,7 @@ } if (canvas.isHardwareAccelerated() && mDrawFunctor == null) { - setFunctor(new AwGLFunctor(mNativeDrawGLFunctorFactory, mContainerView)); + setFunctor(new AwGLFunctor(mNativeDrawFunctorFactory, mContainerView)); } mScrollOffsetManager.syncScrollOffsetFromOnDraw();
diff --git a/android_webview/java/src/org/chromium/android_webview/AwGLFunctor.java b/android_webview/java/src/org/chromium/android_webview/AwGLFunctor.java index c067cc4..2893030 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwGLFunctor.java +++ b/android_webview/java/src/org/chromium/android_webview/AwGLFunctor.java
@@ -27,10 +27,10 @@ // Counts outstanding requestDrawGL calls as well as window attach count. private int mRefCount; - public AwGLFunctor(AwContents.NativeDrawGLFunctorFactory nativeDrawGLFunctorFactory, - ViewGroup containerView) { + public AwGLFunctor( + AwContents.NativeDrawFunctorFactory nativeDrawFunctorFactory, ViewGroup containerView) { mNativeAwGLFunctor = nativeCreate(this); - mNativeDrawGLFunctor = nativeDrawGLFunctorFactory.createFunctor( + mNativeDrawGLFunctor = nativeDrawFunctorFactory.createGLFunctor( nativeGetAwDrawGLViewContext(mNativeAwGLFunctor)); mContainerView = containerView; if (mNativeDrawGLFunctor.supportsDrawGLFunctorReleasedCallback()) {
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwActivityTestRule.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwActivityTestRule.java index 314ebe7..b2701be 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/AwActivityTestRule.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwActivityTestRule.java
@@ -21,7 +21,7 @@ import org.chromium.android_webview.AwContents; import org.chromium.android_webview.AwContents.DependencyFactory; import org.chromium.android_webview.AwContents.InternalAccessDelegate; -import org.chromium.android_webview.AwContents.NativeDrawGLFunctorFactory; +import org.chromium.android_webview.AwContents.NativeDrawFunctorFactory; import org.chromium.android_webview.AwContentsClient; import org.chromium.android_webview.AwSettings; import org.chromium.android_webview.test.util.GraphicsTestUtils; @@ -360,7 +360,7 @@ AwContents awContents = testDependencyFactory.createAwContents(mBrowserContext, testContainerView, testContainerView.getContext(), testContainerView.getInternalAccessDelegate(), - testContainerView.getNativeDrawGLFunctorFactory(), awContentsClient, awSettings, + testContainerView.getNativeDrawFunctorFactory(), awContentsClient, awSettings, testDependencyFactory); testContainerView.initialize(awContents); return testContainerView; @@ -608,11 +608,10 @@ public AwContents createAwContents(AwBrowserContext browserContext, ViewGroup containerView, Context context, InternalAccessDelegate internalAccessAdapter, - NativeDrawGLFunctorFactory nativeDrawGLFunctorFactory, - AwContentsClient contentsClient, AwSettings settings, - DependencyFactory dependencyFactory) { + NativeDrawFunctorFactory nativeDrawFunctorFactory, AwContentsClient contentsClient, + AwSettings settings, DependencyFactory dependencyFactory) { return new AwContents(browserContext, containerView, context, internalAccessAdapter, - nativeDrawGLFunctorFactory, contentsClient, settings, dependencyFactory); + nativeDrawFunctorFactory, contentsClient, settings, dependencyFactory); } }
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/LoadDataWithBaseUrlTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/LoadDataWithBaseUrlTest.java index 4d604258..4d1380f 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/LoadDataWithBaseUrlTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/LoadDataWithBaseUrlTest.java
@@ -570,8 +570,7 @@ AwSettings contentSettings = mActivityTestRule.getAwSettingsOnUiThread(mAwContents); contentSettings.setJavaScriptEnabled(true); loadDataWithBaseUrlSync("", "text/html", false, baseUri, null); - // TODO(dcheng): https://crbug.com/896059 this should be fixed as "x-thread://". - Assert.assertEquals("\"null\"", + Assert.assertEquals("\"x-thread://\"", mActivityTestRule.executeJavaScriptAndWaitForResult( mAwContents, mContentsClient, "window.origin;")); } @@ -588,8 +587,7 @@ @Feature({"AndroidWebView"}) // https://crbug.com/900528 public void testXhrForCustomSchemeUrl() throws Throwable { - // TODO(dcheng): this should be fixed by https://crbug.com/900528. - Assert.assertFalse(verifyXhrForUrls("myscheme://mydomain/1", "myscheme://mydomain/2")); + Assert.assertTrue(verifyXhrForUrls("myscheme://mydomain/1", "myscheme://mydomain/2")); } /**
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/SafeBrowsingTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/SafeBrowsingTest.java index eba1882..7b871f7 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/SafeBrowsingTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/SafeBrowsingTest.java
@@ -27,7 +27,7 @@ import org.chromium.android_webview.AwContents; import org.chromium.android_webview.AwContents.DependencyFactory; import org.chromium.android_webview.AwContents.InternalAccessDelegate; -import org.chromium.android_webview.AwContents.NativeDrawGLFunctorFactory; +import org.chromium.android_webview.AwContents.NativeDrawFunctorFactory; import org.chromium.android_webview.AwContentsClient; import org.chromium.android_webview.AwContentsStatics; import org.chromium.android_webview.AwSafeBrowsingConfigHelper; @@ -233,11 +233,10 @@ public MockAwContents(AwBrowserContext browserContext, ViewGroup containerView, Context context, InternalAccessDelegate internalAccessAdapter, - NativeDrawGLFunctorFactory nativeDrawGLFunctorFactory, - AwContentsClient contentsClient, AwSettings settings, - DependencyFactory dependencyFactory) { + NativeDrawFunctorFactory nativeDrawFunctorFactory, AwContentsClient contentsClient, + AwSettings settings, DependencyFactory dependencyFactory) { super(browserContext, containerView, context, internalAccessAdapter, - nativeDrawGLFunctorFactory, contentsClient, settings, dependencyFactory); + nativeDrawFunctorFactory, contentsClient, settings, dependencyFactory); mCanShowInterstitial = true; mCanShowBigInterstitial = true; } @@ -300,11 +299,10 @@ @Override public AwContents createAwContents(AwBrowserContext browserContext, ViewGroup containerView, Context context, InternalAccessDelegate internalAccessAdapter, - NativeDrawGLFunctorFactory nativeDrawGLFunctorFactory, - AwContentsClient contentsClient, AwSettings settings, - DependencyFactory dependencyFactory) { + NativeDrawFunctorFactory nativeDrawFunctorFactory, AwContentsClient contentsClient, + AwSettings settings, DependencyFactory dependencyFactory) { return new MockAwContents(browserContext, containerView, context, internalAccessAdapter, - nativeDrawGLFunctorFactory, contentsClient, settings, dependencyFactory); + nativeDrawFunctorFactory, contentsClient, settings, dependencyFactory); } }
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/TestAwContents.java b/android_webview/javatests/src/org/chromium/android_webview/test/TestAwContents.java index af2d2c3..bfaf711 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/TestAwContents.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/TestAwContents.java
@@ -45,10 +45,10 @@ public TestAwContents(AwBrowserContext browserContext, ViewGroup containerView, Context context, InternalAccessDelegate internalAccessAdapter, - NativeDrawGLFunctorFactory nativeDrawGLFunctorFactory, AwContentsClient contentsClient, + NativeDrawFunctorFactory nativeDrawFunctorFactory, AwContentsClient contentsClient, AwSettings settings, DependencyFactory dependencyFactory) { super(browserContext, containerView, context, internalAccessAdapter, - nativeDrawGLFunctorFactory, contentsClient, settings, dependencyFactory); + nativeDrawFunctorFactory, contentsClient, settings, dependencyFactory); mRenderProcessGoneHelper = new RenderProcessGoneHelper(); mRenderProcessGoneObservers = new ArrayList<RenderProcessGoneObserver>();
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/services/VisualStateCallbackTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/services/VisualStateCallbackTest.java index b78b3f23..d534e50 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/services/VisualStateCallbackTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/services/VisualStateCallbackTest.java
@@ -20,7 +20,7 @@ import org.chromium.android_webview.AwContents; import org.chromium.android_webview.AwContents.DependencyFactory; import org.chromium.android_webview.AwContents.InternalAccessDelegate; -import org.chromium.android_webview.AwContents.NativeDrawGLFunctorFactory; +import org.chromium.android_webview.AwContents.NativeDrawFunctorFactory; import org.chromium.android_webview.AwContentsClient; import org.chromium.android_webview.AwRenderProcessGoneDetail; import org.chromium.android_webview.AwSettings; @@ -78,11 +78,10 @@ public VisualStateCallbackTestAwContents(AwBrowserContext browserContext, ViewGroup containerView, Context context, InternalAccessDelegate internalAccessAdapter, - NativeDrawGLFunctorFactory nativeDrawGLFunctorFactory, - AwContentsClient contentsClient, AwSettings settings, - DependencyFactory dependencyFactory) { + NativeDrawFunctorFactory nativeDrawFunctorFactory, AwContentsClient contentsClient, + AwSettings settings, DependencyFactory dependencyFactory) { super(browserContext, containerView, context, internalAccessAdapter, - nativeDrawGLFunctorFactory, contentsClient, settings, dependencyFactory); + nativeDrawFunctorFactory, contentsClient, settings, dependencyFactory); mVisualStateCallbackHelper = new VisualStateCallbackHelper(); } @@ -113,11 +112,10 @@ @Override public AwContents createAwContents(AwBrowserContext browserContext, ViewGroup containerView, Context context, InternalAccessDelegate internalAccessAdapter, - NativeDrawGLFunctorFactory nativeDrawGLFunctorFactory, - AwContentsClient contentsClient, AwSettings settings, - DependencyFactory dependencyFactory) { + NativeDrawFunctorFactory nativeDrawFunctorFactory, AwContentsClient contentsClient, + AwSettings settings, DependencyFactory dependencyFactory) { return new VisualStateCallbackTestAwContents(browserContext, containerView, context, - internalAccessAdapter, nativeDrawGLFunctorFactory, contentsClient, settings, + internalAccessAdapter, nativeDrawFunctorFactory, contentsClient, settings, dependencyFactory); } }
diff --git a/android_webview/test/shell/src/org/chromium/android_webview/shell/AwShellActivity.java b/android_webview/test/shell/src/org/chromium/android_webview/shell/AwShellActivity.java index 653679e..0d97cef 100644 --- a/android_webview/test/shell/src/org/chromium/android_webview/shell/AwShellActivity.java +++ b/android_webview/test/shell/src/org/chromium/android_webview/shell/AwShellActivity.java
@@ -219,7 +219,7 @@ testContainerView.initialize(new AwContents(mBrowserContext, testContainerView, testContainerView.getContext(), testContainerView.getInternalAccessDelegate(), - testContainerView.getNativeDrawGLFunctorFactory(), awContentsClient, awSettings)); + testContainerView.getNativeDrawFunctorFactory(), awContentsClient, awSettings)); testContainerView.getAwContents().getSettings().setJavaScriptEnabled(true); if (mDevToolsServer == null) { mDevToolsServer = new AwDevToolsServer();
diff --git a/android_webview/test/shell/src/org/chromium/android_webview/test/AwTestContainerView.java b/android_webview/test/shell/src/org/chromium/android_webview/test/AwTestContainerView.java index 8d79205c..39284c4 100644 --- a/android_webview/test/shell/src/org/chromium/android_webview/test/AwTestContainerView.java +++ b/android_webview/test/shell/src/org/chromium/android_webview/test/AwTestContainerView.java
@@ -277,8 +277,8 @@ return mAwContents; } - public AwContents.NativeDrawGLFunctorFactory getNativeDrawGLFunctorFactory() { - return new NativeDrawGLFunctorFactory(); + public AwContents.NativeDrawFunctorFactory getNativeDrawFunctorFactory() { + return new NativeDrawFunctorFactory(); } public AwContents.InternalAccessDelegate getInternalAccessDelegate() { @@ -436,9 +436,9 @@ return mAwContents.performAccessibilityAction(action, arguments); } - private class NativeDrawGLFunctorFactory implements AwContents.NativeDrawGLFunctorFactory { + private class NativeDrawFunctorFactory implements AwContents.NativeDrawFunctorFactory { @Override - public NativeDrawGLFunctor createFunctor(long context) { + public NativeDrawGLFunctor createGLFunctor(long context) { return new NativeDrawGLFunctor(context); } }
diff --git a/ash/app_list/views/app_list_view_unittest.cc b/ash/app_list/views/app_list_view_unittest.cc index 4bf33f9..14d8924 100644 --- a/ash/app_list/views/app_list_view_unittest.cc +++ b/ash/app_list/views/app_list_view_unittest.cc
@@ -518,8 +518,8 @@ focused_view()); // Clean up - textfield->SetText(base::UTF8ToUTF16("")); textfield->RequestFocus(); + textfield->SetText(base::UTF8ToUTF16("")); } AppListView* app_list_view() { return view_; }
diff --git a/ash/app_list/views/folder_header_view.cc b/ash/app_list/views/folder_header_view.cc index 7665d4f..488b390 100644 --- a/ash/app_list/views/folder_header_view.cc +++ b/ash/app_list/views/folder_header_view.cc
@@ -43,6 +43,7 @@ ~FolderNameView() override = default; void OnFocus() override { + SetText(base::UTF8ToUTF16(folder_header_view_->folder_item_->name())); SelectAll(false); Textfield::OnFocus(); }
diff --git a/ash/app_list/views/search_box_view.cc b/ash/app_list/views/search_box_view.cc index 19ad49b..41fa4b35 100644 --- a/ash/app_list/views/search_box_view.cc +++ b/ash/app_list/views/search_box_view.cc
@@ -28,6 +28,7 @@ #include "base/macros.h" #include "base/metrics/histogram_macros.h" #include "chromeos/chromeos_switches.h" +#include "ui/base/ime/composition_text.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h" #include "ui/chromeos/search_box/search_box_constants.h" @@ -361,7 +362,7 @@ } void SearchBoxView::ProcessAutocomplete() { - if (!is_app_list_search_autocomplete_enabled_) + if (!ShouldProcessAutocomplete()) return; SearchResult* const first_visible_result = @@ -425,25 +426,14 @@ } void SearchBoxView::AcceptAutocompleteText() { - if (!is_app_list_search_autocomplete_enabled_) + if (!ShouldProcessAutocomplete()) return; - if (HasAutocompleteText()) - ContentsChanged(search_box(), search_box()->text()); -} - -void SearchBoxView::AcceptOneCharInAutocompleteText() { - if (!is_app_list_search_autocomplete_enabled_) - return; - - highlight_range_.set_start(highlight_range_.start() + 1); - highlight_range_.set_end(search_box()->text().length()); - const base::string16 original_text = search_box()->text(); - search_box()->SetText( - search_box()->text().substr(0, highlight_range_.start())); - ContentsChanged(search_box(), search_box()->text()); - search_box()->SetText(original_text); - search_box()->SetSelectionRange(highlight_range_); + // Do not trigger another search here in case the user is left clicking to + // select existing autocomplete text. (This also matches omnibox behavior.) + DCHECK(HasAutocompleteText()); + search_box()->ClearSelection(); + ResetHighlightRange(); } bool SearchBoxView::HasAutocompleteText() { @@ -451,23 +441,28 @@ // autocomplete or selected by the user. If the recorded autocomplete // |highlight_range_| matches the selection range, this text is suggested by // autocomplete. - return search_box()->GetSelectedRange() == highlight_range_ && + return search_box()->GetSelectedRange().EqualsIgnoringDirection( + highlight_range_) && highlight_range_.length() > 0; } void SearchBoxView::ClearAutocompleteText() { - if (!is_app_list_search_autocomplete_enabled_) + if (!ShouldProcessAutocomplete()) return; - search_box()->SetText( - search_box()->text().substr(0, highlight_range_.start())); + // Avoid triggering subsequent query by temporarily setting controller to + // nullptr. + search_box()->set_controller(nullptr); + search_box()->ClearCompositionText(); + search_box()->set_controller(this); + ResetHighlightRange(); } void SearchBoxView::ContentsChanged(views::Textfield* sender, const base::string16& new_contents) { // Update autocomplete text highlight range to track user typed text. - if (is_app_list_search_autocomplete_enabled_) - highlight_range_.set_start(search_box()->text().length()); + if (ShouldProcessAutocomplete()) + ResetHighlightRange(); search_box::SearchBoxViewBase::ContentsChanged(sender, new_contents); app_list_view_->SetStateFromSearchBoxView( IsSearchBoxTrimmedQueryEmpty(), true /*triggered_by_contents_change*/); @@ -475,7 +470,7 @@ void SearchBoxView::SetAutocompleteText( const base::string16& autocomplete_text) { - if (!is_app_list_search_autocomplete_enabled_) + if (!ShouldProcessAutocomplete()) return; const base::string16& current_text = search_box()->text(); @@ -486,27 +481,37 @@ if (autocomplete_text.length() == current_text.length()) return; - const base::string16& user_typed_text = - current_text.substr(0, highlight_range_.start()); const base::string16& highlighted_text = autocomplete_text.substr(highlight_range_.start()); - search_box()->SetText(user_typed_text + highlighted_text); + + // Don't set autocomplete text if the highlighted text is the same as before. + if (highlighted_text == search_box()->GetSelectedText()) + return; + highlight_range_.set_end(autocomplete_text.length()); - search_box()->SelectRange(highlight_range_); + ui::CompositionText composition_text; + composition_text.text = highlighted_text; + composition_text.selection = gfx::Range(0, highlighted_text.length()); + + // Avoid triggering subsequent query by temporarily setting controller to + // nullptr. + search_box()->set_controller(nullptr); + search_box()->SetCompositionText(composition_text); + search_box()->set_controller(this); } bool SearchBoxView::HandleKeyEvent(views::Textfield* sender, const ui::KeyEvent& key_event) { if (search_box()->HasFocus() && is_search_box_active() && - !search_box()->text().empty() && - is_app_list_search_autocomplete_enabled_) { + !search_box()->text().empty() && ShouldProcessAutocomplete()) { // If the search box has no text in it currently, autocomplete should not // work. last_key_pressed_ = key_event.key_code(); if (key_event.type() == ui::ET_KEY_PRESSED && key_event.key_code() != ui::VKEY_BACK) { - if (key_event.key_code() == ui::VKEY_TAB) { + if (key_event.key_code() == ui::VKEY_TAB && HasAutocompleteText()) { AcceptAutocompleteText(); + return true; } else if ((key_event.key_code() == ui::VKEY_UP || key_event.key_code() == ui::VKEY_DOWN || key_event.key_code() == ui::VKEY_LEFT || @@ -514,17 +519,6 @@ HasAutocompleteText()) { ClearAutocompleteText(); return true; - } else { - const base::string16 pending_text = search_box()->GetSelectedText(); - // Hitting the next key in the autocompete suggestion continues - // autocomplete suggestion. If the selected range doesn't match the - // recorded highlight range, the selection should be overwritten. - if (!pending_text.empty() && - key_event.GetCharacter() == pending_text[0] && - pending_text.length() == highlight_range_.length()) { - AcceptOneCharInAutocompleteText(); - return true; - } } } } @@ -609,6 +603,20 @@ } } +bool SearchBoxView::ShouldProcessAutocomplete() { + // IME sets composition text while the user is typing, so avoid handle + // autocomplete in this case to avoid conflicts. + return is_app_list_search_autocomplete_enabled_ && + !(search_box()->IsIMEComposing() && highlight_range_.is_empty()); +} + +void SearchBoxView::ResetHighlightRange() { + DCHECK(ShouldProcessAutocomplete()); + const uint32_t text_length = search_box()->text().length(); + highlight_range_.set_start(text_length); + highlight_range_.set_end(text_length); +} + void SearchBoxView::SetupAssistantButton() { if (search_model_ && !search_model_->search_box()->show_assistant_button()) { return;
diff --git a/ash/app_list/views/search_box_view.h b/ash/app_list/views/search_box_view.h index 57695030..dfbafed 100644 --- a/ash/app_list/views/search_box_view.h +++ b/ash/app_list/views/search_box_view.h
@@ -92,6 +92,10 @@ } ContentsView* contents_view() { return contents_view_; } + void set_highlight_range_for_test(const gfx::Range& range) { + highlight_range_ = range; + } + private: // Gets the wallpaper prominent colors. void GetWallpaperProminentColors( @@ -105,9 +109,6 @@ // Notifies SearchBoxViewDelegate that the autocomplete text is valid. void AcceptAutocompleteText(); - // Accepts one character in the autocomplete text and fires query. - void AcceptOneCharInAutocompleteText(); - // Returns true if there is currently an autocomplete suggestion in // search_box(). bool HasAutocompleteText(); @@ -136,6 +137,12 @@ void SearchEngineChanged() override; void ShowAssistantChanged() override; + // Returns true if the event to trigger autocomplete should be handled. + bool ShouldProcessAutocomplete(); + + // Clear highlight range. + void ResetHighlightRange(); + // The range of highlighted text for autocomplete. gfx::Range highlight_range_;
diff --git a/ash/app_list/views/search_box_view_unittest.cc b/ash/app_list/views/search_box_view_unittest.cc index 249b2e14..50826b06 100644 --- a/ash/app_list/views/search_box_view_unittest.cc +++ b/ash/app_list/views/search_box_view_unittest.cc
@@ -18,6 +18,7 @@ #include "base/macros.h" #include "base/strings/utf_string_conversions.h" #include "base/test/scoped_feature_list.h" +#include "ui/base/ime/composition_text.h" #include "ui/chromeos/search_box/search_box_constants.h" #include "ui/chromeos/search_box/search_box_view_delegate.h" #include "ui/events/base_event_utils.h" @@ -307,22 +308,22 @@ // expect only typed characters otherwise. void ExpectAutocompleteSuggestion(bool should_autocomplete) { if (should_autocomplete) { - // Search box autocomplete suggestion is accepted and reflected in Search - // Model. - EXPECT_EQ(view()->search_box()->text(), + // Search box autocomplete suggestion is accepted, but it should not + // trigger another query, thus it is not reflected in Search Model. + EXPECT_EQ(base::ASCIIToUTF16("hello world!"), + view()->search_box()->text()); + EXPECT_EQ(base::ASCIIToUTF16("he"), view_delegate()->GetSearchModel()->search_box()->text()); - EXPECT_EQ(view()->search_box()->text(), - base::ASCIIToUTF16("hello world!")); } else { // Search box autocomplete suggestion is removed and is reflected in // SearchModel. EXPECT_EQ(view()->search_box()->text(), view_delegate()->GetSearchModel()->search_box()->text()); - EXPECT_EQ(view()->search_box()->text(), base::ASCIIToUTF16("he")); + EXPECT_EQ(base::ASCIIToUTF16("he"), view()->search_box()->text()); // ProcessAutocomplete should be a no-op. view()->ProcessAutocomplete(); // The autocomplete suggestion should still not be present. - EXPECT_EQ(view()->search_box()->text(), base::ASCIIToUTF16("he")); + EXPECT_EQ(base::ASCIIToUTF16("he"), view()->search_box()->text()); } } @@ -530,15 +531,16 @@ KeyPress(ui::VKEY_H); KeyPress(ui::VKEY_E); view()->ProcessAutocomplete(); - // Forward the next key in the autocomplete suggestion to HandleKeyEvent(). We - // use HandleKeyEvent() because KeyPress() will replace the existing - // highlighted text and add a repeat character. - ui::KeyEvent event(ui::ET_KEY_PRESSED, ui::VKEY_L, ui::EF_NONE); - static_cast<views::TextfieldController*>(view())->HandleKeyEvent( - view()->search_box(), event); + + // After typing L, the highlighted text will be replaced by L. + KeyPress(ui::VKEY_L); base::string16 selected_text = view()->search_box()->GetSelectedText(); - // The autocomplete text should be preserved after hitting the next key in the - // suggestion. + EXPECT_EQ(view()->search_box()->text(), base::ASCIIToUTF16("hel")); + EXPECT_EQ(base::ASCIIToUTF16(""), selected_text); + + // After handling autocomplete, the highlighted text will show again. + view()->ProcessAutocomplete(); + selected_text = view()->search_box()->GetSelectedText(); EXPECT_EQ(view()->search_box()->text(), base::ASCIIToUTF16("hello world!")); EXPECT_EQ(base::ASCIIToUTF16("lo world!"), selected_text); } @@ -567,5 +569,33 @@ false); } +// Tests that autocomplete is not handled if IME is using composition text. +TEST_F(SearchBoxViewAutocompleteTest, SearchBoxAutocompletesNotHandledForIME) { + // Add a search result with a non-empty title field. + CreateSearchResult(ash::SearchResultDisplayType::kList, 1.0, + base::ASCIIToUTF16("hello world!"), base::string16()); + + // Simulate uncomposited text. The autocomplete should be handled. + view()->search_box()->SetText(base::ASCIIToUTF16("he")); + view()->set_highlight_range_for_test(gfx::Range(2, 2)); + view()->ProcessAutocomplete(); + + base::string16 selected_text = view()->search_box()->GetSelectedText(); + EXPECT_EQ(view()->search_box()->text(), base::ASCIIToUTF16("hello world!")); + EXPECT_EQ(base::ASCIIToUTF16("llo world!"), selected_text); + view()->search_box()->SetText(base::string16()); + + // Simulate IME composition text. The autocomplete should not be handled. + ui::CompositionText composition_text; + composition_text.text = base::ASCIIToUTF16("he"); + view()->search_box()->SetCompositionText(composition_text); + view()->set_highlight_range_for_test(gfx::Range(2, 2)); + view()->ProcessAutocomplete(); + + selected_text = view()->search_box()->GetSelectedText(); + EXPECT_EQ(view()->search_box()->text(), base::ASCIIToUTF16("he")); + EXPECT_EQ(base::ASCIIToUTF16(""), selected_text); +} + } // namespace test } // namespace app_list
diff --git a/ash/assistant/ui/assistant_web_view.cc b/ash/assistant/ui/assistant_web_view.cc index d8a09b4..bf7b63e 100644 --- a/ash/assistant/ui/assistant_web_view.cc +++ b/ash/assistant/ui/assistant_web_view.cc
@@ -182,7 +182,7 @@ contents_->AddObserver(this); // Navigate to the url associated with the received deep link. - contents_->Navigate(assistant::util::GetWebUrl(type).value()); + contents_->Navigate(assistant::util::GetWebUrl(type, params).value()); } void AssistantWebView::DidAutoResizeView(const gfx::Size& new_size) {
diff --git a/ash/assistant/util/deep_link_util.cc b/ash/assistant/util/deep_link_util.cc index 9f7c648b..ad6d7220 100644 --- a/ash/assistant/util/deep_link_util.cc +++ b/ash/assistant/util/deep_link_util.cc
@@ -23,6 +23,7 @@ // Supported deep link param keys. These values must be kept in sync with the // server. See more details at go/cros-assistant-deeplink. +constexpr char kIdParamKey[] = "id"; constexpr char kQueryParamKey[] = "q"; constexpr char kPageParamKey[] = "page"; constexpr char kRelaunchParamKey[] = "relaunch"; @@ -90,6 +91,7 @@ DeepLinkParam param) { // Map of supported deep link params to their keys. static const std::map<DeepLinkParam, std::string> kDeepLinkParamKeys = { + {DeepLinkParam::kId, kIdParamKey}, {DeepLinkParam::kPage, kPageParamKey}, {DeepLinkParam::kQuery, kQueryParamKey}, {DeepLinkParam::kRelaunch, kRelaunchParamKey}}; @@ -145,6 +147,17 @@ return GetDeepLinkType(url) != DeepLinkType::kUnsupported; } +GURL GetAssistantRemindersUrl(const base::Optional<std::string>& id) { + // TODO(b/113357196): Make these URLs configurable for development purposes. + static constexpr char kAssistantRemindersWebUrl[] = + "https://assistant.google.com/reminders/mainview"; + static constexpr char kAssistantRemindersByIdWebUrl[] = + "https://assistant.google.com/reminders/id/"; + return (id && !id.value().empty()) + ? CreateLocalizedGURL(kAssistantRemindersByIdWebUrl + id.value()) + : CreateLocalizedGURL(kAssistantRemindersWebUrl); +} + GURL GetChromeSettingsUrl(const base::Optional<std::string>& page) { static constexpr char kChromeSettingsUrl[] = "chrome://settings/"; @@ -161,13 +174,13 @@ } base::Optional<GURL> GetWebUrl(const GURL& deep_link) { - return GetWebUrl(GetDeepLinkType(deep_link)); + return GetWebUrl(GetDeepLinkType(deep_link), GetDeepLinkParams(deep_link)); } -base::Optional<GURL> GetWebUrl(DeepLinkType type) { +base::Optional<GURL> GetWebUrl( + DeepLinkType type, + const std::map<std::string, std::string>& params) { // TODO(b/113357196): Make these URLs configurable for development purposes. - static constexpr char kAssistantRemindersWebUrl[] = - "https://assistant.google.com/reminders/mainview"; static constexpr char kAssistantSettingsWebUrl[] = "https://assistant.google.com/settings/mainpage"; @@ -176,7 +189,8 @@ switch (type) { case DeepLinkType::kReminders: - return CreateLocalizedGURL(kAssistantRemindersWebUrl); + return GetAssistantRemindersUrl( + GetDeepLinkParam(params, DeepLinkParam::kId)); case DeepLinkType::kSettings: return CreateLocalizedGURL(kAssistantSettingsWebUrl); case DeepLinkType::kUnsupported:
diff --git a/ash/assistant/util/deep_link_util.h b/ash/assistant/util/deep_link_util.h index 30f4f50..4400724 100644 --- a/ash/assistant/util/deep_link_util.h +++ b/ash/assistant/util/deep_link_util.h
@@ -33,6 +33,7 @@ // Enumeration of deep link parameters. enum class DeepLinkParam { + kId, kPage, kQuery, kRelaunch, @@ -72,6 +73,10 @@ // Returns true if the specified |url| is a deep link, false otherwise. ASH_EXPORT bool IsDeepLinkUrl(const GURL& url); +// Returns the URL for the specified Assistant reminder |id|. If id is absent, +// the returned URL will be for top-level Assistant Reminders. +ASH_EXPORT GURL GetAssistantRemindersUrl(const base::Optional<std::string>& id); + // Returns the URL for the specified Chrome Settings |page|. If page is absent // or not allowed, the URL will be for top-level Chrome Settings. ASH_EXPORT GURL GetChromeSettingsUrl(const base::Optional<std::string>& page); @@ -81,10 +86,12 @@ // IsWebDeepLink(GURL) API. ASH_EXPORT base::Optional<GURL> GetWebUrl(const GURL& deep_link); -// Returns the web URL for a deep link of the specified |type|. A return value -// will only be present if the deep link type is a web deep link type as -// identified by the IsWebDeepLinkType(DeepLinkType) API. -ASH_EXPORT base::Optional<GURL> GetWebUrl(DeepLinkType type); +// Returns the web URL for a deep link of the specified |type| with the given +// |params|. A return value will only be present if the deep link type is a web +// deep link type as identified by the IsWebDeepLinkType(DeepLinkType) API. +ASH_EXPORT base::Optional<GURL> GetWebUrl( + DeepLinkType type, + const std::map<std::string, std::string>& params); // Returns true if the specified |deep_link| is a web deep link. ASH_EXPORT bool IsWebDeepLink(const GURL& deep_link);
diff --git a/ash/assistant/util/deep_link_util_unittest.cc b/ash/assistant/util/deep_link_util_unittest.cc index e4cacbe..2d4e034 100644 --- a/ash/assistant/util/deep_link_util_unittest.cc +++ b/ash/assistant/util/deep_link_util_unittest.cc
@@ -262,6 +262,22 @@ ASSERT_EQ(test_case.second, IsDeepLinkUrl(GURL(test_case.first))); } +TEST_F(DeepLinkUnitTest, GetAssistantRemindersUrl) { + const std::map<base::Optional<std::string>, std::string> test_cases = { + // OK: Absent/empty id. + {base::nullopt, + "https://assistant.google.com/reminders/mainview?hl=en-US"}, + {base::Optional<std::string>(std::string()), + "https://assistant.google.com/reminders/mainview?hl=en-US"}, + + // OK: Specified id. + {base::Optional<std::string>("123456"), + "https://assistant.google.com/reminders/id/123456?hl=en-US"}}; + + for (const auto& test_case : test_cases) + ASSERT_EQ(test_case.second, GetAssistantRemindersUrl(test_case.first)); +} + TEST_F(DeepLinkUnitTest, GetChromeSettingsUrl) { const std::map<base::Optional<std::string>, std::string> test_cases = { // OK: Absent/empty page. @@ -293,8 +309,8 @@ GURL("https://assistant.google.com/settings/mainpage?hl=en-US")}, // OK: Parameterized deep links. - {"googleassistant://reminders?param=true", - GURL("https://assistant.google.com/reminders/mainview?hl=en-US")}, + {"googleassistant://reminders?id=123456", + GURL("https://assistant.google.com/reminders/id/123456?hl=en-US")}, {"googleassistant://settings?param=true", GURL("https://assistant.google.com/settings/mainpage?hl=en-US")}, @@ -329,28 +345,51 @@ } TEST_F(DeepLinkUnitTest, GetWebUrlByType) { - const std::map<DeepLinkType, base::Optional<GURL>> test_cases = { + using DeepLinkParams = std::map<std::string, std::string>; + using TestCase = std::pair<DeepLinkType, DeepLinkParams>; + + // Creates a test case with a single parameter. + auto CreateTestCaseWithParam = + [](DeepLinkType type, + base::Optional<std::pair<std::string, std::string>> param = + base::nullopt) { + DeepLinkParams params; + if (param) + params.insert(param.value()); + return std::make_pair(type, params); + }; + + // Creates a test case with no parameters. + auto CreateTestCase = [&CreateTestCaseWithParam](DeepLinkType type) { + return CreateTestCaseWithParam(type); + }; + + const std::map<TestCase, base::Optional<GURL>> test_cases = { // OK: Supported web deep link types. - {DeepLinkType::kReminders, + {CreateTestCase(DeepLinkType::kReminders), GURL("https://assistant.google.com/reminders/mainview?hl=en-US")}, - {DeepLinkType::kSettings, + {CreateTestCaseWithParam(DeepLinkType::kReminders, + std::make_pair("id", "123456")), + GURL("https://assistant.google.com/reminders/id/123456?hl=en-US")}, + {CreateTestCase(DeepLinkType::kSettings), GURL("https://assistant.google.com/settings/mainpage?hl=en-US")}, // FAIL: Non-web deep link types. - {DeepLinkType::kChromeSettings, base::nullopt}, - {DeepLinkType::kFeedback, base::nullopt}, - {DeepLinkType::kOnboarding, base::nullopt}, - {DeepLinkType::kQuery, base::nullopt}, - {DeepLinkType::kScreenshot, base::nullopt}, - {DeepLinkType::kTaskManager, base::nullopt}, - {DeepLinkType::kWhatsOnMyScreen, base::nullopt}, + {CreateTestCase(DeepLinkType::kChromeSettings), base::nullopt}, + {CreateTestCase(DeepLinkType::kFeedback), base::nullopt}, + {CreateTestCase(DeepLinkType::kOnboarding), base::nullopt}, + {CreateTestCase(DeepLinkType::kQuery), base::nullopt}, + {CreateTestCase(DeepLinkType::kScreenshot), base::nullopt}, + {CreateTestCase(DeepLinkType::kTaskManager), base::nullopt}, + {CreateTestCase(DeepLinkType::kWhatsOnMyScreen), base::nullopt}, // FAIL: Unsupported deep link types. - {DeepLinkType::kUnsupported, base::nullopt}}; + {CreateTestCase(DeepLinkType::kUnsupported), base::nullopt}}; for (const auto& test_case : test_cases) { const base::Optional<GURL>& expected = test_case.second; - const base::Optional<GURL> actual = GetWebUrl(test_case.first); + const base::Optional<GURL> actual = GetWebUrl( + /*type=*/test_case.first.first, /*params=*/test_case.first.second); // Assert |has_value| equivalence. ASSERT_EQ(expected, actual);
diff --git a/ash/session/test_session_controller_client.cc b/ash/session/test_session_controller_client.cc index 9660f3f..1e783be 100644 --- a/ash/session/test_session_controller_client.cc +++ b/ash/session/test_session_controller_client.cc
@@ -184,6 +184,7 @@ void TestSessionControllerClient::RequestSignOut() { Reset(); + ++request_sign_out_count_; } void TestSessionControllerClient::SwitchActiveUser(
diff --git a/ash/session/test_session_controller_client.h b/ash/session/test_session_controller_client.h index cc466c2..07cfb39 100644 --- a/ash/session/test_session_controller_client.h +++ b/ash/session/test_session_controller_client.h
@@ -47,6 +47,8 @@ use_lower_case_user_id_ = value; } + int request_sign_out_count() const { return request_sign_out_count_; } + // Helpers to set SessionController state. void SetCanLockScreen(bool can_lock); void SetShouldLockScreenAutomatically(bool should_lock); @@ -100,6 +102,7 @@ mojom::SessionInfoPtr session_info_; bool use_lower_case_user_id_ = true; + int request_sign_out_count_ = 0; DISALLOW_COPY_AND_ASSIGN(TestSessionControllerClient); };
diff --git a/ash/system/locale/locale_detailed_view.cc b/ash/system/locale/locale_detailed_view.cc index 2c2741f0..e646e80 100644 --- a/ash/system/locale/locale_detailed_view.cc +++ b/ash/system/locale/locale_detailed_view.cc
@@ -4,14 +4,108 @@ #include "ash/system/locale/locale_detailed_view.h" +#include "ash/resources/vector_icons/vector_icons.h" #include "ash/shell.h" #include "ash/strings/grit/ash_strings.h" #include "ash/system/model/system_tray_model.h" -#include "ash/system/tray/hover_highlight_view.h" +#include "ash/system/tray/actionable_view.h" +#include "ash/system/tray/tray_popup_item_style.h" +#include "ash/system/tray/tray_popup_utils.h" +#include "base/i18n/case_conversion.h" #include "base/logging.h" +#include "base/strings/utf_string_conversions.h" +#include "ui/accessibility/ax_node_data.h" +#include "ui/base/l10n/l10n_util.h" +#include "ui/base/resource/resource_bundle.h" +#include "ui/gfx/color_palette.h" +#include "ui/gfx/paint_vector_icon.h" +#include "ui/views/controls/image_view.h" +#include "ui/views/controls/label.h" #include "ui/views/controls/scroll_view.h" +#include "ui/views/layout/fill_layout.h" namespace ash { + +namespace { + +// The item that corresponds to a single locale in the locale list. The language +// portion of |iso_code| is shown at the beginning of the row, and +// |display_name| is shown in the middle. A checkmark is shown in the end if +// |checked| is true. +class LocaleItem : public ActionableView { + public: + LocaleItem(tray::LocaleDetailedView* locale_detailed_view, + const std::string& iso_code, + const base::string16& display_name, + bool checked) + : ActionableView(TrayPopupInkDropStyle::FILL_BOUNDS), + locale_detailed_view_(locale_detailed_view), + checked_(checked) { + SetInkDropMode(InkDropMode::ON); + + TriView* tri_view = TrayPopupUtils::CreateDefaultRowView(); + AddChildView(tri_view); + SetLayoutManager(std::make_unique<views::FillLayout>()); + + views::Label* iso_code_label = TrayPopupUtils::CreateDefaultLabel(); + iso_code_label->SetEnabledColor(kUnifiedMenuTextColor); + iso_code_label->SetAutoColorReadabilityEnabled(false); + iso_code_label->SetText(base::i18n::ToUpper( + base::UTF8ToUTF16(l10n_util::GetLanguage(iso_code)))); + ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); + const gfx::FontList& base_font_list = + rb.GetFontList(ui::ResourceBundle::MediumBoldFont); + iso_code_label->SetFontList(base_font_list); + tri_view->AddView(TriView::Container::START, iso_code_label); + + auto* display_name_view = TrayPopupUtils::CreateDefaultLabel(); + display_name_view->SetText(display_name); + TrayPopupItemStyle style(TrayPopupItemStyle::FontStyle::DETAILED_VIEW_LABEL, + true /* use_unified_theme */); + style.SetupLabel(display_name_view); + + display_name_view->SetHorizontalAlignment(gfx::ALIGN_LEFT); + tri_view->AddView(TriView::Container::CENTER, display_name_view); + + if (checked_) { + views::ImageView* checked_image = TrayPopupUtils::CreateMainImageView(); + checked_image->SetImage(gfx::CreateVectorIcon( + kCheckCircleIcon, kMenuIconSize, gfx::kGoogleGreen700)); + tri_view->AddView(TriView::Container::END, checked_image); + } + SetAccessibleName(display_name_view->text()); + } + + ~LocaleItem() override = default; + + // ActionableView: + bool PerformAction(const ui::Event& event) override { + locale_detailed_view_->HandleViewClicked(this); + return true; + } + + // views::View: + void OnFocus() override { + ActionableView::OnFocus(); + ScrollViewToVisible(); + } + + void GetAccessibleNodeData(ui::AXNodeData* node_data) override { + ActionableView::GetAccessibleNodeData(node_data); + node_data->role = ax::mojom::Role::kCheckBox; + node_data->SetCheckedState(checked_ ? ax::mojom::CheckedState::kTrue + : ax::mojom::CheckedState::kFalse); + } + + private: + tray::LocaleDetailedView* locale_detailed_view_; + const bool checked_; + + DISALLOW_COPY_AND_ASSIGN(LocaleItem); +}; + +} // namespace + namespace tray { LocaleDetailedView::LocaleDetailedView(DetailedViewDelegate* delegate) @@ -32,16 +126,14 @@ const bool checked = entry->iso_code == Shell::Get()->system_tray_model()->current_locale_iso_code(); - HoverHighlightView* item = - AddScrollListCheckableItem(entry->display_name, checked); + LocaleItem* item = + new LocaleItem(this, entry->iso_code, entry->display_name, checked); + scroll_content()->AddChildView(item); item->set_id(id); id_to_locale_[id] = entry->iso_code; ++id; } - scroll_content()->SizeToPreferredSize(); - scroller()->Layout(); - // TODO(wzang): Show locale ISO codes at the beginning of each row, most - // likely by reusing the code in |ImeListItemView|. + Layout(); } void LocaleDetailedView::HandleViewClicked(views::View* view) {
diff --git a/ash/system/locale/locale_detailed_view.h b/ash/system/locale/locale_detailed_view.h index b6115b33..49fb7751 100644 --- a/ash/system/locale/locale_detailed_view.h +++ b/ash/system/locale/locale_detailed_view.h
@@ -20,12 +20,12 @@ explicit LocaleDetailedView(DetailedViewDelegate* delegate); ~LocaleDetailedView() override; - private: - void CreateItems(); - // TrayDetailedView: void HandleViewClicked(views::View* view) override; + private: + void CreateItems(); + // The map between the id of the view and the locale it corresponds to. base::flat_map<int, std::string> id_to_locale_;
diff --git a/ash/system/locale/locale_feature_pod_controller.cc b/ash/system/locale/locale_feature_pod_controller.cc index 9e4331bf..4f4bb97 100644 --- a/ash/system/locale/locale_feature_pod_controller.cc +++ b/ash/system/locale/locale_feature_pod_controller.cc
@@ -10,6 +10,7 @@ #include "ash/system/model/system_tray_model.h" #include "ash/system/unified/feature_pod_button.h" #include "ash/system/unified/unified_system_tray_controller.h" +#include "base/i18n/case_conversion.h" #include "base/strings/utf_string_conversions.h" #include "ui/base/l10n/l10n_util.h" @@ -33,8 +34,9 @@ button->SetLabel(l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_LOCALE)); button->ShowDetailedViewArrow(); button->DisableLabelButtonFocus(); - button->SetSubLabel(base::UTF8ToUTF16( - Shell::Get()->system_tray_model()->current_locale_iso_code())); + button->SetSubLabel( + base::i18n::ToUpper(base::UTF8ToUTF16(l10n_util::GetLanguage( + Shell::Get()->system_tray_model()->current_locale_iso_code())))); } return button; }
diff --git a/ash/system/message_center/unified_message_list_view.cc b/ash/system/message_center/unified_message_list_view.cc index 0a5f5aad..5dbea29 100644 --- a/ash/system/message_center/unified_message_list_view.cc +++ b/ash/system/message_center/unified_message_list_view.cc
@@ -485,6 +485,11 @@ DeleteRemovedNotifications(); UpdateBounds(); start_height_ = ideal_height_; + for (int i = 0; i < child_count(); ++i) { + auto* view = GetContainer(i); + view->set_start_bounds(view->ideal_bounds()); + } + PreferredSizeChanged(); state_ = State::CLEAR_ALL_STACKED;
diff --git a/ash/system/message_center/unified_message_list_view_unittest.cc b/ash/system/message_center/unified_message_list_view_unittest.cc index edf5131..7b2950c6 100644 --- a/ash/system/message_center/unified_message_list_view_unittest.cc +++ b/ash/system/message_center/unified_message_list_view_unittest.cc
@@ -443,8 +443,10 @@ message_list_view()->set_stacked_notification_count(1); int previous_height = message_list_view()->GetPreferredSize().height(); + gfx::Rect previous_bounds = GetMessageViewBounds(1); AnimateToMiddle(); EXPECT_EQ(previous_height, message_list_view()->GetPreferredSize().height()); + EXPECT_EQ(previous_bounds, GetMessageViewBounds(1)); AnimateToEnd(); EXPECT_EQ(1, message_list_view()->child_count()); @@ -455,7 +457,7 @@ AnimateToEnd(); EXPECT_EQ(1, message_list_view()->child_count()); - gfx::Rect previous_bounds = GetMessageViewBounds(0); + previous_bounds = GetMessageViewBounds(0); AnimateToMiddle(); EXPECT_LT(previous_bounds.x(), GetMessageViewBounds(0).x()); AnimateToEnd();
diff --git a/ash/system/session/logout_button_tray.cc b/ash/system/session/logout_button_tray.cc index eaca905..3f6fe02 100644 --- a/ash/system/session/logout_button_tray.cc +++ b/ash/system/session/logout_button_tray.cc
@@ -17,6 +17,7 @@ #include "ash/system/tray/tray_constants.h" #include "ash/system/tray/tray_container.h" #include "ash/system/user/login_status.h" +#include "base/metrics/user_metrics.h" #include "components/prefs/pref_change_registrar.h" #include "components/prefs/pref_registry_simple.h" #include "components/prefs/pref_service.h" @@ -72,11 +73,14 @@ DCHECK_EQ(button_, sender); if (dialog_duration_ <= base::TimeDelta()) { + if (Shell::Get()->session_controller()->IsDemoSession()) + base::RecordAction(base::UserMetricsAction("DemoMode.ExitFromShelf")); // Sign out immediately if |dialog_duration_| is non-positive. Shell::Get()->session_controller()->RequestSignOut(); } else if (Shell::Get()->logout_confirmation_controller()) { Shell::Get()->logout_confirmation_controller()->ConfirmLogout( - base::TimeTicks::Now() + dialog_duration_); + base::TimeTicks::Now() + dialog_duration_, + LogoutConfirmationController::Source::kShelfExitButton); } }
diff --git a/ash/system/session/logout_button_tray.h b/ash/system/session/logout_button_tray.h index 56f9155..7601a50 100644 --- a/ash/system/session/logout_button_tray.h +++ b/ash/system/session/logout_button_tray.h
@@ -48,6 +48,8 @@ // SessionObserver: void OnActiveUserPrefServiceChanged(PrefService* prefs) override; + views::MdTextButton* button_for_test() const { return button_; } + private: void UpdateShowLogoutButtonInTray(); void UpdateLogoutDialogDuration();
diff --git a/ash/system/session/logout_button_tray_unittest.cc b/ash/system/session/logout_button_tray_unittest.cc index d5fb2f5..5387399 100644 --- a/ash/system/session/logout_button_tray_unittest.cc +++ b/ash/system/session/logout_button_tray_unittest.cc
@@ -9,12 +9,16 @@ #include "ash/session/session_controller.h" #include "ash/session/test_session_controller_client.h" #include "ash/shell.h" +#include "ash/system/session/logout_confirmation_controller.h" #include "ash/system/status_area_widget.h" #include "ash/test/ash_test_base.h" #include "ash/test/ash_test_helper.h" #include "ash/test_shell_delegate.h" #include "base/macros.h" +#include "base/test/metrics/user_action_tester.h" #include "components/prefs/pref_service.h" +#include "ui/events/base_event_utils.h" +#include "ui/views/controls/button/md_text_button.h" namespace ash { namespace { @@ -70,5 +74,66 @@ EXPECT_FALSE(button->visible()); } +TEST_F(LogoutButtonTrayTest, ButtonPressed) { + constexpr char kUserEmail[] = "user1@test.com"; + constexpr char kUserAction[] = "DemoMode.ExitFromShelf"; + + LogoutButtonTray* const tray = Shell::GetPrimaryRootWindowController() + ->GetStatusAreaWidget() + ->logout_button_tray_for_testing(); + ASSERT_TRUE(tray); + views::MdTextButton* const button = tray->button_for_test(); + SessionController* const session_controller = + Shell::Get()->session_controller(); + TestSessionControllerClient* const session_client = + GetSessionControllerClient(); + base::UserActionTester user_action_tester; + const ui::MouseEvent event(ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(), + ui::EventTimeForNow(), 0, 0); + PrefService* const pref_service = + Shell::Get()->session_controller()->GetUserPrefServiceForUser( + AccountId::FromUserEmail(kUserEmail)); + + SimulateUserLogin(kUserEmail); + EXPECT_EQ(0, session_client->request_sign_out_count()); + EXPECT_EQ(0, user_action_tester.GetActionCount(kUserAction)); + EXPECT_EQ(0, Shell::Get() + ->logout_confirmation_controller() + ->confirm_logout_count_for_test()); + + // Sign out immediately when duration is zero. + pref_service->SetInteger(prefs::kLogoutDialogDurationMs, 0); + tray->ButtonPressed(button, event); + session_controller->FlushMojoForTest(); + EXPECT_EQ(1, session_client->request_sign_out_count()); + EXPECT_EQ(0, user_action_tester.GetActionCount(kUserAction)); + EXPECT_EQ(0, Shell::Get() + ->logout_confirmation_controller() + ->confirm_logout_count_for_test()); + + // Call |LogoutConfirmationController::ConfirmLogout| when duration is + // non-zero. + pref_service->SetInteger(prefs::kLogoutDialogDurationMs, 1000); + tray->ButtonPressed(button, event); + session_controller->FlushMojoForTest(); + EXPECT_EQ(1, session_client->request_sign_out_count()); + EXPECT_EQ(0, user_action_tester.GetActionCount(kUserAction)); + EXPECT_EQ(1, Shell::Get() + ->logout_confirmation_controller() + ->confirm_logout_count_for_test()); + + // Sign out immediately and record user action when duration is zero and it is + // demo session. + pref_service->SetInteger(prefs::kLogoutDialogDurationMs, 0); + session_client->SetIsDemoSession(); + tray->ButtonPressed(button, event); + session_controller->FlushMojoForTest(); + EXPECT_EQ(2, session_client->request_sign_out_count()); + EXPECT_EQ(1, user_action_tester.GetActionCount(kUserAction)); + EXPECT_EQ(1, Shell::Get() + ->logout_confirmation_controller() + ->confirm_logout_count_for_test()); +} + } // namespace } // namespace ash
diff --git a/ash/system/session/logout_confirmation_controller.cc b/ash/system/session/logout_confirmation_controller.cc index dc9fa3f..9d7bde1 100644 --- a/ash/system/session/logout_confirmation_controller.cc +++ b/ash/system/session/logout_confirmation_controller.cc
@@ -15,6 +15,7 @@ #include "ash/system/session/logout_confirmation_dialog.h" #include "base/callback.h" #include "base/location.h" +#include "base/metrics/user_metrics.h" #include "base/time/default_tick_clock.h" #include "base/time/tick_clock.h" #include "ui/aura/window.h" @@ -29,7 +30,11 @@ const int kLastWindowClosedContainerIds[] = { kShellWindowId_DefaultContainer, kShellWindowId_AlwaysOnTopContainer}; -void SignOut() { +void SignOut(LogoutConfirmationController::Source source) { + if (Shell::Get()->session_controller()->IsDemoSession() && + source == LogoutConfirmationController::Source::kShelfExitButton) { + base::RecordAction(base::UserMetricsAction("DemoMode.ExitFromShelf")); + } Shell::Get()->session_controller()->RequestSignOut(); } @@ -94,7 +99,8 @@ // No more windows except currently removing. Show logout time. Shell::Get()->logout_confirmation_controller()->ConfirmLogout( base::TimeTicks::Now() + - base::TimeDelta::FromSeconds(kLogoutConfirmationDelayInSeconds)); + base::TimeDelta::FromSeconds(kLogoutConfirmationDelayInSeconds), + Source::kCloseAllWindows); } // ShellObserver: @@ -120,7 +126,7 @@ LogoutConfirmationController::LogoutConfirmationController() : clock_(base::DefaultTickClock::GetInstance()), - logout_closure_(base::Bind(&SignOut)) { + logout_callback_(base::BindRepeating(&SignOut)) { if (Shell::HasInstance()) // Null in testing::Test. Shell::Get()->session_controller()->AddObserver(this); } @@ -133,7 +139,8 @@ Shell::Get()->session_controller()->RemoveObserver(this); } -void LogoutConfirmationController::ConfirmLogout(base::TimeTicks logout_time) { +void LogoutConfirmationController::ConfirmLogout(base::TimeTicks logout_time, + Source source) { if (!logout_time_.is_null() && logout_time >= logout_time_) { // If a confirmation dialog is already being shown and its countdown expires // no later than the |logout_time| requested now, keep the current dialog @@ -150,8 +157,10 @@ dialog_->Update(logout_time_); } + source_ = source; logout_timer_.Start(FROM_HERE, logout_time_ - clock_->NowTicks(), - logout_closure_); + base::BindOnce(logout_callback_, source)); + ++confirm_logout_count_for_test_; } void LogoutConfirmationController::OnLoginStatusChanged( @@ -178,7 +187,7 @@ void LogoutConfirmationController::OnLogoutConfirmed() { logout_timer_.Stop(); - logout_closure_.Run(); + logout_callback_.Run(source_); } void LogoutConfirmationController::OnDialogClosed() { @@ -192,9 +201,9 @@ clock_ = clock; } -void LogoutConfirmationController::SetLogoutClosureForTesting( - const base::Closure& logout_closure) { - logout_closure_ = logout_closure; +void LogoutConfirmationController::SetLogoutCallbackForTesting( + const base::RepeatingCallback<void(Source)>& logout_callback) { + logout_callback_ = logout_callback; } } // namespace ash
diff --git a/ash/system/session/logout_confirmation_controller.h b/ash/system/session/logout_confirmation_controller.h index 27b78bd..b28570a2 100644 --- a/ash/system/session/logout_confirmation_controller.h +++ b/ash/system/session/logout_confirmation_controller.h
@@ -34,6 +34,8 @@ // closed. class ASH_EXPORT LogoutConfirmationController : public SessionObserver { public: + enum class Source { kShelfExitButton, kCloseAllWindows }; + LogoutConfirmationController(); ~LogoutConfirmationController() override; @@ -42,7 +44,7 @@ // Shows a LogoutConfirmationDialog. If a confirmation dialog is already being // shown, it is closed and a new one opened if |logout_time| is earlier than // the current dialog's |logout_time_|. - void ConfirmLogout(base::TimeTicks logout_time); + void ConfirmLogout(base::TimeTicks logout_time, Source source); // SessionObserver: void OnLoginStatusChanged(LoginStatus login_status) override; @@ -58,20 +60,29 @@ // of the clock. |clock| must outlive the LogoutConfirmationController // instance. void SetClockForTesting(const base::TickClock* clock); - void SetLogoutClosureForTesting(const base::Closure& logout_closure); + void SetLogoutCallbackForTesting( + const base::RepeatingCallback<void(Source)>& logout_callback); LogoutConfirmationDialog* dialog_for_testing() const { return dialog_; } + int confirm_logout_count_for_test() const { + return confirm_logout_count_for_test_; + } + private: class LastWindowClosedObserver; std::unique_ptr<LastWindowClosedObserver> last_window_closed_observer_; const base::TickClock* clock_; - base::Closure logout_closure_; + + base::RepeatingCallback<void(Source)> logout_callback_; + Source source_; base::TimeTicks logout_time_; LogoutConfirmationDialog* dialog_ = nullptr; // Owned by the Views hierarchy. base::OneShotTimer logout_timer_; + int confirm_logout_count_for_test_ = 0; + DISALLOW_COPY_AND_ASSIGN(LogoutConfirmationController); };
diff --git a/ash/system/session/logout_confirmation_controller_unittest.cc b/ash/system/session/logout_confirmation_controller_unittest.cc index 3943568..fe2bd540 100644 --- a/ash/system/session/logout_confirmation_controller_unittest.cc +++ b/ash/system/session/logout_confirmation_controller_unittest.cc
@@ -26,7 +26,7 @@ LogoutConfirmationControllerTest(); ~LogoutConfirmationControllerTest() override; - void LogOut(); + void LogOut(LogoutConfirmationController::Source source); bool log_out_called_; @@ -44,20 +44,23 @@ runner_(new base::TestMockTimeTaskRunner), runner_handle_(runner_) { controller_.SetClockForTesting(runner_->GetMockTickClock()); - controller_.SetLogoutClosureForTesting(base::Bind( + controller_.SetLogoutCallbackForTesting(base::BindRepeating( &LogoutConfirmationControllerTest::LogOut, base::Unretained(this))); } LogoutConfirmationControllerTest::~LogoutConfirmationControllerTest() = default; -void LogoutConfirmationControllerTest::LogOut() { +void LogoutConfirmationControllerTest::LogOut( + LogoutConfirmationController::Source source) { log_out_called_ = true; } // Verifies that the user is logged out immediately if logout confirmation with // a zero-length countdown is requested. TEST_F(LogoutConfirmationControllerTest, ZeroDuration) { - controller_.ConfirmLogout(runner_->NowTicks()); + controller_.ConfirmLogout( + runner_->NowTicks(), + LogoutConfirmationController::Source::kShelfExitButton); EXPECT_FALSE(log_out_called_); runner_->FastForwardBy(base::TimeDelta()); EXPECT_TRUE(log_out_called_); @@ -65,8 +68,9 @@ // Verifies that the user is logged out when the countdown expires. TEST_F(LogoutConfirmationControllerTest, DurationExpired) { - controller_.ConfirmLogout(runner_->NowTicks() + - base::TimeDelta::FromSeconds(10)); + controller_.ConfirmLogout( + runner_->NowTicks() + base::TimeDelta::FromSeconds(10), + LogoutConfirmationController::Source::kShelfExitButton); EXPECT_FALSE(log_out_called_); runner_->FastForwardBy(base::TimeDelta::FromSeconds(9)); EXPECT_FALSE(log_out_called_); @@ -78,13 +82,15 @@ // request's countdown ends before the original request's, the user is logged // out when the new countdown expires. TEST_F(LogoutConfirmationControllerTest, DurationShortened) { - controller_.ConfirmLogout(runner_->NowTicks() + - base::TimeDelta::FromSeconds(30)); + controller_.ConfirmLogout( + runner_->NowTicks() + base::TimeDelta::FromSeconds(30), + LogoutConfirmationController::Source::kShelfExitButton); EXPECT_FALSE(log_out_called_); runner_->FastForwardBy(base::TimeDelta::FromSeconds(9)); EXPECT_FALSE(log_out_called_); - controller_.ConfirmLogout(runner_->NowTicks() + - base::TimeDelta::FromSeconds(10)); + controller_.ConfirmLogout( + runner_->NowTicks() + base::TimeDelta::FromSeconds(10), + LogoutConfirmationController::Source::kShelfExitButton); runner_->FastForwardBy(base::TimeDelta::FromSeconds(9)); EXPECT_FALSE(log_out_called_); runner_->FastForwardBy(base::TimeDelta::FromSeconds(2)); @@ -95,13 +101,15 @@ // request's countdown ends after the original request's, the user is logged // out when the original countdown expires. TEST_F(LogoutConfirmationControllerTest, DurationExtended) { - controller_.ConfirmLogout(runner_->NowTicks() + - base::TimeDelta::FromSeconds(10)); + controller_.ConfirmLogout( + runner_->NowTicks() + base::TimeDelta::FromSeconds(10), + LogoutConfirmationController::Source::kShelfExitButton); EXPECT_FALSE(log_out_called_); runner_->FastForwardBy(base::TimeDelta::FromSeconds(9)); EXPECT_FALSE(log_out_called_); - controller_.ConfirmLogout(runner_->NowTicks() + - base::TimeDelta::FromSeconds(10)); + controller_.ConfirmLogout( + runner_->NowTicks() + base::TimeDelta::FromSeconds(10), + LogoutConfirmationController::Source::kShelfExitButton); runner_->FastForwardBy(base::TimeDelta::FromSeconds(2)); EXPECT_TRUE(log_out_called_); } @@ -109,8 +117,9 @@ // Verifies that when the screen is locked while the countdown is running, the // user is not logged out, even when the original countdown expires. TEST_F(LogoutConfirmationControllerTest, Lock) { - controller_.ConfirmLogout(runner_->NowTicks() + - base::TimeDelta::FromSeconds(10)); + controller_.ConfirmLogout( + runner_->NowTicks() + base::TimeDelta::FromSeconds(10), + LogoutConfirmationController::Source::kShelfExitButton); EXPECT_FALSE(log_out_called_); controller_.OnLockStateChanged(true); runner_->FastForwardUntilNoTasksRemain(); @@ -120,8 +129,9 @@ // Verifies that when the user confirms the logout request, the user is logged // out immediately. TEST_F(LogoutConfirmationControllerTest, UserAccepted) { - controller_.ConfirmLogout(runner_->NowTicks() + - base::TimeDelta::FromSeconds(10)); + controller_.ConfirmLogout( + runner_->NowTicks() + base::TimeDelta::FromSeconds(10), + LogoutConfirmationController::Source::kShelfExitButton); EXPECT_FALSE(log_out_called_); controller_.OnLogoutConfirmed(); EXPECT_TRUE(log_out_called_); @@ -130,8 +140,9 @@ // Verifies that when the user denies the logout request, the user is not logged // out, even when the original countdown expires. TEST_F(LogoutConfirmationControllerTest, UserDenied) { - controller_.ConfirmLogout(runner_->NowTicks() + - base::TimeDelta::FromSeconds(10)); + controller_.ConfirmLogout( + runner_->NowTicks() + base::TimeDelta::FromSeconds(10), + LogoutConfirmationController::Source::kShelfExitButton); EXPECT_FALSE(log_out_called_); controller_.OnDialogClosed(); runner_->FastForwardUntilNoTasksRemain(); @@ -142,15 +153,17 @@ // request is handled correctly and the user is logged out when the countdown // expires. TEST_F(LogoutConfirmationControllerTest, DurationExpiredAfterDeniedRequest) { - controller_.ConfirmLogout(runner_->NowTicks() + - base::TimeDelta::FromSeconds(10)); + controller_.ConfirmLogout( + runner_->NowTicks() + base::TimeDelta::FromSeconds(10), + LogoutConfirmationController::Source::kShelfExitButton); EXPECT_FALSE(log_out_called_); controller_.OnDialogClosed(); runner_->FastForwardUntilNoTasksRemain(); EXPECT_FALSE(log_out_called_); - controller_.ConfirmLogout(runner_->NowTicks() + - base::TimeDelta::FromSeconds(10)); + controller_.ConfirmLogout( + runner_->NowTicks() + base::TimeDelta::FromSeconds(10), + LogoutConfirmationController::Source::kShelfExitButton); EXPECT_FALSE(log_out_called_); runner_->FastForwardBy(base::TimeDelta::FromSeconds(9)); EXPECT_FALSE(log_out_called_);
diff --git a/ash/system/unified/unified_system_tray_controller.cc b/ash/system/unified/unified_system_tray_controller.cc index 1bb9a42..388538eb 100644 --- a/ash/system/unified/unified_system_tray_controller.cc +++ b/ash/system/unified/unified_system_tray_controller.cc
@@ -119,6 +119,8 @@ void UnifiedSystemTrayController::HandleSignOutAction() { Shell::Get()->metrics()->RecordUserMetricsAction(UMA_STATUS_AREA_SIGN_OUT); + if (Shell::Get()->session_controller()->IsDemoSession()) + base::RecordAction(base::UserMetricsAction("DemoMode.ExitFromSystemTray")); Shell::Get()->session_controller()->RequestSignOut(); }
diff --git a/base/BUILD.gn b/base/BUILD.gn index 64f6fdbd..902e44c 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -100,16 +100,6 @@ } } -if (is_nacl_nonsfi) { - # Must be in a config because of how GN orders flags (otherwise -Wall will - # appear after this, and turn it back on). - config("nacl_nonsfi_warnings") { - # file_util_posix.cc contains a function which is not - # being used by nacl_helper_nonsfi. - cflags = [ "-Wno-unused-function" ] - } -} - if (is_android) { config("android_system_libs") { libs = [ @@ -132,14 +122,6 @@ # test code (test support and anything in the test directory) which should use # source_set as is recommended for GN targets). jumbo_component("base") { - if (is_nacl_nonsfi) { - # TODO(phosek) bug 570839: If field_trial.cc is in a static library, - # nacl_helper_nonsfi doesn't link properly on Linux in debug builds. The - # reasons for this seem to involve obscure toolchain bugs. This should be - # fixed and this target should always be a static_library in the - # non-component case. - static_component_type = "source_set" - } if (is_nacl || is_ios) { # Link errors related to malloc functions if libbase for nacl is # compiled with jumbo: https://crbug.com/775959. @@ -1553,7 +1535,6 @@ if (is_nacl_nonsfi) { sources -= [ "rand_util_nacl.cc" ] - configs += [ ":nacl_nonsfi_warnings" ] } else { sources -= [ "files/file_descriptor_watcher_posix.cc", @@ -2073,6 +2054,7 @@ "message_loop/message_loop_task_runner_perftest.cc", "message_loop/message_pump_perftest.cc", "observer_list_perftest.cc", + "strings/string_util_perftest.cc", "task/sequence_manager/sequence_manager_perftest.cc", "task/task_scheduler/task_scheduler_perftest.cc",
diff --git a/base/files/file_util_posix.cc b/base/files/file_util_posix.cc index 94e80c5..eabdaf3 100644 --- a/base/files/file_util_posix.cc +++ b/base/files/file_util_posix.cc
@@ -74,10 +74,12 @@ ScopedBlockingCall scoped_blocking_call(BlockingType::MAY_BLOCK); return stat(path, sb); } +#if !defined(OS_NACL_NONSFI) int CallLstat(const char* path, stat_wrapper_t* sb) { ScopedBlockingCall scoped_blocking_call(BlockingType::MAY_BLOCK); return lstat(path, sb); } +#endif #else int CallStat(const char* path, stat_wrapper_t* sb) { ScopedBlockingCall scoped_blocking_call(BlockingType::MAY_BLOCK);
diff --git a/base/pickle_fuzzer.cc b/base/pickle_fuzzer.cc index 26c5dbf..74abaadb 100644 --- a/base/pickle_fuzzer.cc +++ b/base/pickle_fuzzer.cc
@@ -102,7 +102,8 @@ } case 14: { const char* data_result = nullptr; - int read_length = data_provider.ConsumeInt32InRange(0, kMaxReadLength); + int read_length = + data_provider.ConsumeIntegralInRange(0, kMaxReadLength); ignore_result(iter.ReadBytes(&data_result, read_length)); break; } @@ -113,7 +114,7 @@ } case 16: { ignore_result(iter.SkipBytes( - data_provider.ConsumeInt32InRange(0, kMaxSkipBytes))); + data_provider.ConsumeIntegralInRange(0, kMaxSkipBytes))); break; } }
diff --git a/base/strings/string_util.cc b/base/strings/string_util.cc index f0c2197..5e2d0ee 100644 --- a/base/strings/string_util.cc +++ b/base/strings/string_util.cc
@@ -68,37 +68,32 @@ // Assuming that a pointer is the size of a "machine word", then // uintptr_t is an integer type that is also a machine word. -typedef uintptr_t MachineWord; -const uintptr_t kMachineWordAlignmentMask = sizeof(MachineWord) - 1; +using MachineWord = uintptr_t; -inline bool IsAlignedToMachineWord(const void* pointer) { - return !(reinterpret_cast<MachineWord>(pointer) & kMachineWordAlignmentMask); +inline bool IsMachineWordAligned(const void* pointer) { + return !(reinterpret_cast<MachineWord>(pointer) & (sizeof(MachineWord) - 1)); } -template<typename T> inline T* AlignToMachineWord(T* pointer) { - return reinterpret_cast<T*>(reinterpret_cast<MachineWord>(pointer) & - ~kMachineWordAlignmentMask); -} - -template<size_t size, typename CharacterType> struct NonASCIIMask; -template<> struct NonASCIIMask<4, char16> { - static inline uint32_t value() { return 0xFF80FF80U; } +template <typename CharacterType> +struct NonASCIIMask; +template <> +struct NonASCIIMask<char> { + static constexpr MachineWord value() { + return static_cast<MachineWord>(0x8080808080808080ULL); + } }; -template<> struct NonASCIIMask<4, char> { - static inline uint32_t value() { return 0x80808080U; } -}; -template<> struct NonASCIIMask<8, char16> { - static inline uint64_t value() { return 0xFF80FF80FF80FF80ULL; } -}; -template<> struct NonASCIIMask<8, char> { - static inline uint64_t value() { return 0x8080808080808080ULL; } +template <> +struct NonASCIIMask<char16> { + static constexpr MachineWord value() { + return static_cast<MachineWord>(0xFF80FF80FF80FF80ULL); + } }; #if defined(WCHAR_T_IS_UTF32) -template<> struct NonASCIIMask<4, wchar_t> { - static inline uint32_t value() { return 0xFFFFFF80U; } -}; -template<> struct NonASCIIMask<8, wchar_t> { - static inline uint64_t value() { return 0xFFFFFF80FFFFFF80ULL; } +template <> +struct NonASCIIMask<wchar_t> { + static constexpr MachineWord value() { + return static_cast<MachineWord>(0xFFFFFF80FFFFFF80ULL); + } }; #endif // WCHAR_T_IS_UTF32 @@ -458,31 +453,42 @@ template <class Char> inline bool DoIsStringASCII(const Char* characters, size_t length) { + if (!length) + return true; + constexpr MachineWord non_ascii_bit_mask = NonASCIIMask<Char>::value(); MachineWord all_char_bits = 0; const Char* end = characters + length; // Prologue: align the input. - while (!IsAlignedToMachineWord(characters) && characters != end) { - all_char_bits |= *characters; - ++characters; - } + while (!IsMachineWordAligned(characters) && characters < end) + all_char_bits |= *characters++; + if (all_char_bits & non_ascii_bit_mask) + return false; // Compare the values of CPU word size. - const Char* word_end = AlignToMachineWord(end); - const size_t loop_increment = sizeof(MachineWord) / sizeof(Char); - while (characters < word_end) { + constexpr size_t chars_per_word = sizeof(MachineWord) / sizeof(Char); + constexpr int batch_count = 16; + while (characters <= end - batch_count * chars_per_word) { + all_char_bits = 0; + for (int i = 0; i < batch_count; ++i) { + all_char_bits |= *(reinterpret_cast<const MachineWord*>(characters)); + characters += chars_per_word; + } + if (all_char_bits & non_ascii_bit_mask) + return false; + } + + // Process the remaining words. + all_char_bits = 0; + while (characters <= end - chars_per_word) { all_char_bits |= *(reinterpret_cast<const MachineWord*>(characters)); - characters += loop_increment; + characters += chars_per_word; } // Process the remaining bytes. - while (characters != end) { - all_char_bits |= *characters; - ++characters; - } + while (characters < end) + all_char_bits |= *characters++; - MachineWord non_ascii_bit_mask = - NonASCIIMask<sizeof(MachineWord), Char>::value(); return !(all_char_bits & non_ascii_bit_mask); }
diff --git a/base/strings/string_util_perftest.cc b/base/strings/string_util_perftest.cc new file mode 100644 index 0000000..17cdb05 --- /dev/null +++ b/base/strings/string_util_perftest.cc
@@ -0,0 +1,46 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/strings/string_util.h" + +#include <cinttypes> + +#include "base/time/time.h" +#include "build/build_config.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace base { + +template <typename String> +void MeasureIsStringASCII(size_t str_length, size_t non_ascii_pos) { + String str(str_length, 'A'); + if (non_ascii_pos < str_length) + str[non_ascii_pos] = '\xAF'; + + TimeTicks t0 = TimeTicks::Now(); + for (size_t i = 0; i < 10000000; ++i) + IsStringASCII(str); + TimeDelta time = TimeTicks::Now() - t0; + printf( + "char-size:\t%zu\tlength:\t%zu\tnon-ascii-pos:\t%zu\ttime-ms:\t%" PRIu64 + "\n", + sizeof(typename String::value_type), str_length, non_ascii_pos, + time.InMilliseconds()); +} + +TEST(StringUtilTest, DISABLED_IsStringASCIIPerf) { + for (size_t str_length = 4; str_length <= 1024; str_length *= 2) { + for (size_t non_ascii_loc = 0; non_ascii_loc < 3; ++non_ascii_loc) { + size_t non_ascii_pos = str_length * non_ascii_loc / 2 + 2; + MeasureIsStringASCII<std::string>(str_length, non_ascii_pos); + MeasureIsStringASCII<string16>(str_length, non_ascii_pos); +#if defined(WCHAR_T_IS_UTF32) + MeasureIsStringASCII<std::basic_string<wchar_t>>(str_length, + non_ascii_pos); +#endif + } + } +} + +} // namespace base
diff --git a/base/test/fuzzed_data_provider.h b/base/test/fuzzed_data_provider.h index b847a2d9..0e3da80 100644 --- a/base/test/fuzzed_data_provider.h +++ b/base/test/fuzzed_data_provider.h
@@ -151,24 +151,11 @@ return ConsumeBytesAsString(remaining_bytes_); } - // TODO(mmoroz): consider deprecating these methods. - uint32_t ConsumeUint32InRange(uint32_t min, uint32_t max) { - return ConsumeIntegralInRange(min, max); - } - - int32_t ConsumeInt32InRange(int32_t min, int32_t max) { - return ConsumeIntegralInRange(min, max); - } - - int ConsumeIntInRange(int min, int max) { - return ConsumeIntegralInRange(min, max); - } - // Reads one byte and returns a bool, or false when no data remains. bool ConsumeBool() { return 1 & ConsumeUint8(); } // Returns a uint8_t from the input or 0 if nothing remains. This is - // equivalent to ConsumeUint32InRange(0, 0xFF). + // equivalent to ConsumeIntegralInRange<uint8_t>(0, 0xFF). uint8_t ConsumeUint8() { return ConsumeIntegralInRange(std::numeric_limits<uint8_t>::min(), std::numeric_limits<uint8_t>::max()); @@ -176,16 +163,32 @@ // Returns a uint16_t from the input. If fewer than 2 bytes of data remain // will fill the most significant bytes with 0. This is equivalent to - // ConsumeUint32InRange(0, 0xFFFF). + // ConsumeIntegralInRange<uint16_t>(0, 0xFFFF). uint16_t ConsumeUint16() { return ConsumeIntegralInRange(std::numeric_limits<uint16_t>::min(), std::numeric_limits<uint16_t>::max()); } + // Returns a uint32_t from the input. If fewer than 4 bytes of data remain + // will fill the most significant bytes with 0. This is equivalent to + // ConsumeIntegralInRange<uint32_t>(0, 0xFFFFFFFF). + uint16_t ConsumeUint32() { + return ConsumeIntegralInRange(std::numeric_limits<uint32_t>::min(), + std::numeric_limits<uint32_t>::max()); + } + + // Returns a uint64_t from the input. If fewer than 8 bytes of data remain + // will fill the most significant bytes with 0. This is equivalent to + // ConsumeIntegralInRange<uint64_t>(0, 0xFFFFFFFFFFFFFFFF). + uint16_t ConsumeUint64() { + return ConsumeIntegralInRange(std::numeric_limits<uint64_t>::min(), + std::numeric_limits<uint64_t>::max()); + } + // Returns a value from |array|, consuming as many bytes as needed to do so. // |array| must be a fixed-size array. - template <typename Type, size_t size> - Type PickValueInArray(Type (&array)[size]) { + template <typename T, size_t size> + T PickValueInArray(T (&array)[size]) { return array[ConsumeIntegralInRange<size_t>(0, size - 1)]; }
diff --git a/cc/scheduler/scheduler.h b/cc/scheduler/scheduler.h index 65db622..06c3238 100644 --- a/cc/scheduler/scheduler.h +++ b/cc/scheduler/scheduler.h
@@ -40,6 +40,12 @@ const viz::BeginFrameArgs& args) = 0; virtual DrawResult ScheduledActionDrawIfPossible() = 0; virtual DrawResult ScheduledActionDrawForced() = 0; + + // The Commit step occurs when the client received the BeginFrame from the + // source and we perform at most one commit per BeginFrame. In this step the + // main thread collects all updates then blocks and gives control to the + // compositor thread, which allows Compositor thread to update its layer tree + // to match the state of the layer tree on the main thread. virtual void ScheduledActionCommit() = 0; virtual void ScheduledActionActivateSyncTree() = 0; virtual void ScheduledActionBeginLayerTreeFrameSinkCreation() = 0; @@ -90,10 +96,19 @@ void SetVisible(bool visible); bool visible() { return state_machine_.visible(); } void SetCanDraw(bool can_draw); + + // We have 2 copies of the layer trees on the compositor thread: pending_tree + // and active_tree. When we finish asynchronously rastering all tiles on + // pending_tree, call this method to notify that this pending tree is ready to + // be activated, that is to be copied to the active tree. void NotifyReadyToActivate(); void NotifyReadyToDraw(); void SetBeginFrameSource(viz::BeginFrameSource* source); + // Set |needs_begin_main_frame_| to true, which will cause the BeginFrame + // source to be told to send BeginFrames to this client so that this client + // can send a CompositorFrame to the display compositor with appropriate + // timing. void SetNeedsBeginMainFrame(); // Requests a single impl frame (after the current frame if there is one // active). @@ -125,12 +140,24 @@ void SetTreePrioritiesAndScrollState(TreePriority tree_priority, ScrollHandlerState scroll_handler_state); + // Commit step happens after the main thread has completed updating for a + // BeginMainFrame request from the compositor, and blocks the main thread + // to copy the layer tree to the compositor thread. Call this method when the + // main thread updates are completed to signal it is ready for the commmit. void NotifyReadyToCommit(); void BeginMainFrameAborted(CommitEarlyOutReason reason); void DidCommit(); + // In the PrepareTiles step, compositor thread divides the layers into tiles + // to reduce cost of raster large layers. Then, each tile is rastered by a + // dedicated thread. + // |WillPrepareTiles| is called before PrepareTiles step to have the scheduler + // track when PrepareTiles starts. void WillPrepareTiles(); + // |DidPrepareTiles| is called after PrepareTiles step to have the scheduler + // track how long PrepareTiles takes. void DidPrepareTiles(); + void DidLoseLayerTreeFrameSink(); void DidCreateAndInitializeLayerTreeFrameSink();
diff --git a/cc/tiles/tile_manager.h b/cc/tiles/tile_manager.h index 87fabafd..ac58ccf 100644 --- a/cc/tiles/tile_manager.h +++ b/cc/tiles/tile_manager.h
@@ -139,6 +139,9 @@ ~TileManager() override; // Assigns tile memory and schedules work to prepare tiles for drawing. + // This step occurs after Commit and at most once per BeginFrame. It can be + // called on its own, that is, outside of Commit. + // // - Runs client_->NotifyReadyToActivate() when all tiles required for // activation are prepared, or failed to prepare due to OOM. // - Runs client_->NotifyReadyToDraw() when all tiles required draw are
diff --git a/cc/trees/proxy.h b/cc/trees/proxy.h index 703d503e..b9bb0318 100644 --- a/cc/trees/proxy.h +++ b/cc/trees/proxy.h
@@ -36,6 +36,9 @@ virtual ~Proxy() {} virtual bool IsStarted() const = 0; + + // This function retruns true if the commits go directly to active tree by + // skipping commit to pending tree. virtual bool CommitToActiveTree() const = 0; virtual void SetLayerTreeFrameSink(
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index d2f7ca86..8ea43b1 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -423,7 +423,6 @@ java_cpp_enum("chrome_android_java_enums_srcjar") { sources = [ - "//chrome/browser/android/crash/crash_keys_android.h", "//chrome/browser/android/customtabs/detached_resource_request.h", "//chrome/browser/android/digital_asset_links/digital_asset_links_handler.h", "//chrome/browser/android/explore_sites/explore_sites_feature.h", @@ -646,6 +645,7 @@ "//components/background_task_scheduler:background_task_scheduler_javatests", "//components/background_task_scheduler:background_task_scheduler_task_ids_java", "//components/bookmarks/common/android:bookmarks_java", + "//components/crash/android:java", "//components/crash/android:javatests", "//components/dom_distiller/core/android:dom_distiller_core_java", "//components/download/internal/background_service:internal_java", @@ -1099,6 +1099,7 @@ "//base/test:test_support", "//chrome:chrome_android_core", "//chrome/browser/android/metrics:ukm_utils_for_test", + "//components/crash/android:crash_android", "//components/heap_profiling:test_support", "//components/minidump_uploader", "//components/sync",
diff --git a/chrome/android/java/res/layout/bottom_toolbar_browsing.xml b/chrome/android/java/res/layout/bottom_toolbar_browsing.xml index 70e4b116..432e7d9 100644 --- a/chrome/android/java/res/layout/bottom_toolbar_browsing.xml +++ b/chrome/android/java/res/layout/bottom_toolbar_browsing.xml
@@ -37,7 +37,7 @@ android:paddingStart="@dimen/bottom_toolbar_start_padding" android:paddingEnd="@dimen/bottom_toolbar_end_padding" > - <org.chromium.chrome.browser.toolbar.bottom.HomeButton + <org.chromium.chrome.browser.toolbar.HomeButton android:id="@+id/home_button" style="@style/BottomToolbarButton" android:contentDescription="@string/accessibility_toolbar_btn_home" />
diff --git a/chrome/android/java/res/layout/toolbar_phone.xml b/chrome/android/java/res/layout/toolbar_phone.xml index 104b864..f85c0c6d 100644 --- a/chrome/android/java/res/layout/toolbar_phone.xml +++ b/chrome/android/java/res/layout/toolbar_phone.xml
@@ -23,7 +23,7 @@ android:visibility="invisible" android:contentDescription="@string/accessibility_toolbar_btn_new_tab" /> - <org.chromium.chrome.browser.toolbar.HomePageButton + <org.chromium.chrome.browser.toolbar.HomeButton android:id="@+id/home_button" style="@style/ToolbarButton" android:src="@drawable/btn_toolbar_home"
diff --git a/chrome/android/java/res/layout/toolbar_tablet.xml b/chrome/android/java/res/layout/toolbar_tablet.xml index 6567426..87c5d19 100644 --- a/chrome/android/java/res/layout/toolbar_tablet.xml +++ b/chrome/android/java/res/layout/toolbar_tablet.xml
@@ -22,7 +22,7 @@ android:layout_height="match_parent" android:orientation="horizontal" > - <org.chromium.chrome.browser.toolbar.HomePageButton + <org.chromium.chrome.browser.toolbar.HomeButton android:id="@+id/home_button" style="@style/ToolbarButton" android:src="@drawable/btn_toolbar_home"
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantFacade.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantFacade.java index a8f1f27..5cbfd62 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantFacade.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantFacade.java
@@ -40,15 +40,11 @@ AutofillAssistantUiController controller = new AutofillAssistantUiController(activity, parameters); - AutofillAssistantUiDelegate uiDelegate = - new AutofillAssistantUiDelegate(activity, controller); - UiDelegateHolder delegateHolder = new UiDelegateHolder(controller, uiDelegate); - controller.setUiDelegateHolder(delegateHolder); + UiDelegateHolder delegateHolder = new UiDelegateHolder( + controller, new AutofillAssistantUiDelegate(activity, controller)); initTabObservers(activity, delegateHolder); - controller.maybeUpdateDetails(Details.makeFromParameters(parameters)); - - uiDelegate.startOrSkipInitScreen(); + controller.start(delegateHolder, Details.makeFromParameters(parameters)); } private static void initTabObservers(ChromeActivity activity, UiDelegateHolder delegateHolder) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiController.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiController.java index d219e2d..f382071ae 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiController.java
@@ -89,13 +89,17 @@ parameters.get(PARAMETER_USER_EMAIL), activity.getInitialIntent().getExtras()); } - void setUiDelegateHolder(UiDelegateHolder uiDelegateHolder) { + void start(UiDelegateHolder uiDelegateHolder, Details details) { mUiDelegateHolder = uiDelegateHolder; + // Do not show details until 'onInitOk'. + mCurrentDetails = details; + mUiDelegateHolder.startOrSkipInitScreen(); } @Override public void onInitOk() { assert mUiDelegateHolder != null; + mUiDelegateHolder.performUiOperation(uiDelegate -> uiDelegate.showDetails(mCurrentDetails)); nativeStart(mUiControllerAndroid, mInitialUrl); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiDelegate.java index cabdfc0..0683980 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiDelegate.java
@@ -315,6 +315,7 @@ public void showStatusMessage(@Nullable String message) { show(); mStatusMessageView.setText(message); + mStatusMessageView.announceForAccessibility(message); } /** @@ -435,6 +436,10 @@ mActivity.getActivityTab().getWebContents()); mFullContainer.setVisibility(View.VISIBLE); + // Announce Autofill Assistant is available for accessibility. + mBottomBar.announceForAccessibility( + mActivity.getString(R.string.autofill_assistant_available_accessibility)); + // Set the initial progress. It is OK to make multiple calls to this method as it will // have an effect only on the first one. mProgressBar.maybeIncreaseProgress(PROGRESS_BAR_INITIAL_PROGRESS); @@ -775,6 +780,8 @@ View initView = LayoutInflater.from(mActivity) .inflate(R.layout.init_screen, mCoordinatorView) .findViewById(R.id.init_screen); + // Set focusable for accessibility. + initView.findViewById(R.id.init).setFocusable(true); // Set default state to checked. ((CheckBox) initView.findViewById(R.id.checkbox_dont_show_init_again)).setChecked(true); @@ -782,6 +789,8 @@ .setOnClickListener(unusedView -> onInitClicked(true, initView)); initView.findViewById(R.id.button_init_not_ok) .setOnClickListener(unusedView -> onInitClicked(false, initView)); + initView.announceForAccessibility( + mActivity.getString(R.string.autofill_assistant_first_run_accessibility)); } private void onInitClicked(boolean accept, View initView) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/Details.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/Details.java index 2b0062e..f678f27 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/Details.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/Details.java
@@ -4,10 +4,13 @@ package org.chromium.chrome.browser.autofill_assistant; +import android.support.annotation.IntDef; import android.support.annotation.Nullable; import org.json.JSONObject; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Collections; @@ -22,7 +25,17 @@ * Java side equivalent of autofill_assistant::DetailsProto. */ class Details { - enum DetailsField { TITLE, URL, DATE, DESCRIPTION, MID, IS_FINAL } + @IntDef({DetailsField.TITLE, DetailsField.URL, DetailsField.DATE, DetailsField.DESCRIPTION, + DetailsField.MID, DetailsField.IS_FINAL}) + @Retention(RetentionPolicy.SOURCE) + public @interface DetailsField { + int TITLE = 0; + int URL = 1; + int DATE = 2; + int DESCRIPTION = 3; + int MID = 4; + int IS_FINAL = 5; + } private final String mTitle; private final String mUrl; @@ -32,7 +45,7 @@ private final String mMid; private final boolean mIsFinal; /** Contains the fields that have changed when merging with other Details object. */ - private final Set<DetailsField> mFieldsChanged; + private final Set<Integer> mFieldsChanged; // NOTE: When adding a new field, update the isEmpty and toJSONObject methods. static final Details EMPTY_DETAILS = @@ -41,7 +54,7 @@ private static final String RFC_3339_FORMAT_WITHOUT_TIMEZONE = "yyyy'-'MM'-'dd'T'HH':'mm':'ss"; Details(String title, String url, @Nullable Date date, String description, String mId, - boolean isFinal, Set<DetailsField> fieldsChanged) { + boolean isFinal, Set<Integer> fieldsChanged) { this.mTitle = title; this.mUrl = url; this.mDate = date; @@ -91,7 +104,7 @@ return mIsFinal; } - Set<DetailsField> getFieldsChanged() { + Set<Integer> getFieldsChanged() { return mFieldsChanged; } @@ -154,7 +167,7 @@ Collections.emptySet()); } - Set<DetailsField> changedFields = new HashSet<>(); + Set<Integer> changedFields = new HashSet<>(); String title = oldDetails.getTitle(); String mId = oldDetails.getMid(); @@ -186,4 +199,4 @@ boolean isFinal = newDetails.isFinal(); return new Details(title, url, date, description, mId, isFinal, changedFields); } -} \ No newline at end of file +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/UiDelegateHolder.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/UiDelegateHolder.java index 37bfea44..4ce86ac 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/UiDelegateHolder.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/UiDelegateHolder.java
@@ -36,6 +36,13 @@ } /** + * Starts the init screen unless it has been marked to be skipped. + */ + public void startOrSkipInitScreen() { + mUiDelegate.startOrSkipInitScreen(); + } + + /** * Perform a UI operation: * - directly if we are not in a pause state. * - later if the shutdown is cancelled.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/crash/ApplicationStatusTracker.java b/chrome/android/java/src/org/chromium/chrome/browser/crash/ApplicationStatusTracker.java index 29ea88a..00b5fdc 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/crash/ApplicationStatusTracker.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/crash/ApplicationStatusTracker.java
@@ -7,6 +7,8 @@ import org.chromium.base.ApplicationState; import org.chromium.base.ApplicationStatus; import org.chromium.base.ThreadUtils; +import org.chromium.components.crash.CrashKeyIndex; +import org.chromium.components.crash.CrashKeys; /** * This class updates crash keys when the application state changes.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/crash/PureJavaExceptionHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/crash/PureJavaExceptionHandler.java index 5cac3e6..75f710d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/crash/PureJavaExceptionHandler.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/crash/PureJavaExceptionHandler.java
@@ -6,6 +6,7 @@ import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.MainDex; +import org.chromium.components.crash.CrashKeys; /** * This UncaughtExceptionHandler will upload the stacktrace when there is an uncaught exception.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/crash/PureJavaExceptionReporter.java b/chrome/android/java/src/org/chromium/chrome/browser/crash/PureJavaExceptionReporter.java index 87b0e07a..66a0a9b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/crash/PureJavaExceptionReporter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/crash/PureJavaExceptionReporter.java
@@ -20,6 +20,7 @@ import org.chromium.base.VisibleForTesting; import org.chromium.base.annotations.MainDex; import org.chromium.chrome.browser.ChromeVersionInfo; +import org.chromium.components.crash.CrashKeys; import java.io.File; import java.io.FileNotFoundException;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/ModuleLoader.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/ModuleLoader.java index b993b40..285e821 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/ModuleLoader.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/ModuleLoader.java
@@ -22,9 +22,9 @@ import org.chromium.base.task.AsyncTask; import org.chromium.chrome.browser.ChromeApplication; import org.chromium.chrome.browser.ChromeFeatureList; -import org.chromium.chrome.browser.crash.CrashKeyIndex; -import org.chromium.chrome.browser.crash.CrashKeys; import org.chromium.chrome.browser.customtabs.dynamicmodule.ModuleMetrics.DestructionReason; +import org.chromium.components.crash.CrashKeyIndex; +import org.chromium.components.crash.CrashKeys; import java.util.ArrayList; import java.util.List;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/router/MediaRouteChooserDialogManager.java b/chrome/android/java/src/org/chromium/chrome/browser/media/router/MediaRouteChooserDialogManager.java index 9d6f7d0..25d826d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/media/router/MediaRouteChooserDialogManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/media/router/MediaRouteChooserDialogManager.java
@@ -13,6 +13,11 @@ import android.support.v7.app.MediaRouteChooserDialog; import android.support.v7.app.MediaRouteChooserDialogFragment; import android.support.v7.media.MediaRouteSelector; +import android.support.v7.media.MediaRouter; +import android.support.v7.mediarouter.R; +import android.view.View; +import android.widget.AdapterView; +import android.widget.ListView; /** * Manages the dialog responsible for selecting a {@link MediaSink}. @@ -34,7 +39,7 @@ private final Handler mHandler = new Handler(); private final SystemVisibilitySaver mVisibilitySaver = new SystemVisibilitySaver(); private BaseMediaRouteDialogManager mManager; - private boolean mCancelled; + private boolean mIsSinkSelected; public Fragment() { mHandler.post(new Runnable() { @@ -52,8 +57,7 @@ @Override public MediaRouteChooserDialog onCreateChooserDialog( Context context, Bundle savedInstanceState) { - MediaRouteChooserDialog dialog = - super.onCreateChooserDialog(context, savedInstanceState); + MediaRouteChooserDialog dialog = new DelayedSelectionDialog(context, getTheme()); dialog.setCanceledOnTouchOutside(true); return dialog; } @@ -71,26 +75,45 @@ } @Override - public void onCancel(DialogInterface dialog) { - mCancelled = true; - - mManager.delegate().onDialogCancelled(); - - super.onCancel(dialog); - } - - @Override public void onDismiss(DialogInterface dialog) { super.onDismiss(dialog); - if (mManager == null) return; - mManager.mDialogFragment = null; + if (!mIsSinkSelected) mManager.delegate().onDialogCancelled(); + } - if (mCancelled) return; + private class DelayedSelectionDialog extends MediaRouteChooserDialog { + public DelayedSelectionDialog(Context context) { + super(context); + } - MediaSink newSink = - MediaSink.fromRoute(mManager.androidMediaRouter().getSelectedRoute()); - mManager.delegate().onSinkSelected(mManager.sourceId(), newSink); + public DelayedSelectionDialog(Context context, int theme) { + super(context, theme); + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + ListView listView = (ListView) findViewById(R.id.mr_chooser_list); + if (listView != null) { + listView.setOnItemClickListener(Fragment.this::onItemClick); + } + } + } + + private void onItemClick(AdapterView<?> parent, View view, int position, long id) { + MediaRouter.RouteInfo routeInfo = + (MediaRouter.RouteInfo) parent.getItemAtPosition(position); + if (routeInfo != null && routeInfo.isEnabled()) { + MediaSink newSink = MediaSink.fromRoute(routeInfo); + + // When a item is clicked, the route is not selected right away. Instead, the route + // selection is postponed to the actual session launch. + mManager.delegate().onSinkSelected(mManager.sourceId(), newSink); + mIsSinkSelected = true; + + dismiss(); + } } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/router/caf/BaseSessionController.java b/chrome/android/java/src/org/chromium/chrome/browser/media/router/caf/BaseSessionController.java index 1250ffa8..e57a99f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/media/router/caf/BaseSessionController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/media/router/caf/BaseSessionController.java
@@ -6,7 +6,6 @@ import android.support.annotation.Nullable; import android.support.annotation.VisibleForTesting; -import android.support.v7.media.MediaRouter; import com.google.android.gms.cast.CastDevice; import com.google.android.gms.cast.framework.CastSession; @@ -31,7 +30,6 @@ private CastSession mCastSession; private final CafBaseMediaRouteProvider mProvider; - private final MediaRouter.Callback mMediaRouterCallbackForSessionLaunch; private CreateRouteRequestInfo mRouteCreationInfo; @VisibleForTesting CafNotificationController mNotificationController; @@ -39,7 +37,6 @@ public BaseSessionController(CafBaseMediaRouteProvider provider) { mProvider = provider; - mMediaRouterCallbackForSessionLaunch = new MediaRouterCallbackForSessionLaunch(); mNotificationController = new CafNotificationController(this); mRemoteMediaClientCallback = new RemoteMediaClientCallback(); } @@ -49,21 +46,10 @@ CastUtils.getCastContext().setReceiverApplicationId( mRouteCreationInfo.source.getApplicationId()); - if (mRouteCreationInfo.routeInfo.isSelected()) { - // If a route has just been selected, CAF might not be ready yet before setting the app - // ID. So unselect and select the route will let CAF be aware that the route has been - // selected thus it can start the session. - // - // An issue of this workaround is that if a route is unselected and selected in a very - // short time, the selection might be ignored by MediaRouter, so put the reselection in - // a callback. - mProvider.getAndroidMediaRouter().addCallback( - mRouteCreationInfo.source.buildRouteSelector(), - mMediaRouterCallbackForSessionLaunch); - mProvider.getAndroidMediaRouter().unselect(MediaRouter.UNSELECT_REASON_UNKNOWN); - } else { - mRouteCreationInfo.routeInfo.select(); - } + // When the user clicks a route on the MediaRouteChooserDialog, we intercept the click event + // and do not select the route. Instead the route selection is postponed to here. This will + // trigger CAF to launch the session. + mRouteCreationInfo.routeInfo.select(); } public MediaSource getSource() { @@ -173,20 +159,6 @@ } } - private class MediaRouterCallbackForSessionLaunch extends MediaRouter.Callback { - @Override - public void onRouteUnselected(MediaRouter mediaRouter, MediaRouter.RouteInfo routeInfo) { - if (mProvider.getPendingCreateRouteRequestInfo() == null) return; - - if (routeInfo.getId().equals( - mProvider.getPendingCreateRouteRequestInfo().routeInfo.getId())) { - routeInfo.select(); - mProvider.getAndroidMediaRouter().removeCallback( - mMediaRouterCallbackForSessionLaunch); - } - } - } - private class RemoteMediaClientCallback extends RemoteMediaClient.Callback { @Override public void onStatusUpdated() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/router/cast/BaseMediaRouteProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/media/router/cast/BaseMediaRouteProvider.java index cb598d90..ae9aea6 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/media/router/cast/BaseMediaRouteProvider.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/media/router/cast/BaseMediaRouteProvider.java
@@ -173,18 +173,32 @@ return; } - MediaSink sink = MediaSink.fromSinkId(sinkId, mAndroidMediaRouter); - if (sink == null) { + MediaRouter.RouteInfo targetRouteInfo = null; + for (MediaRouter.RouteInfo routeInfo : mAndroidMediaRouter.getRoutes()) { + if (routeInfo.getId().equals(sinkId)) { + targetRouteInfo = routeInfo; + break; + } + } + + if (targetRouteInfo == null) { mManager.onRouteRequestError("No sink", nativeRequestId); return; } + MediaSink sink = MediaSink.fromRoute(targetRouteInfo); + MediaSource source = getSourceFromId(sourceId); if (source == null) { mManager.onRouteRequestError("Unsupported source URL", nativeRequestId); return; } + // When the user clicks a route on the MediaRouteChooserDialog, we intercept the click event + // and do not select the route. Instead the route selection is postponed to here. This will + // make sure the MediaRouteControllerDialog show up properly. + targetRouteInfo.select(); + ChromeCastSessionManager.CastSessionLaunchRequest request = createSessionLaunchRequest( source, sink, presentationId, origin, tabId, isIncognito, nativeRequestId);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/net/spdyproxy/OWNERS b/chrome/android/java/src/org/chromium/chrome/browser/net/spdyproxy/OWNERS index 845f1d7b..be748d62 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/net/spdyproxy/OWNERS +++ b/chrome/android/java/src/org/chromium/chrome/browser/net/spdyproxy/OWNERS
@@ -1 +1,3 @@ -bengr@chromium.org +file://components/data_reduction_proxy/OWNERS + +# COMPONENT: Internals>Network>DataProxy
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/HomeButton.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/HomeButton.java new file mode 100644 index 0000000..ff726ad0 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/HomeButton.java
@@ -0,0 +1,77 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.toolbar; + +import android.content.Context; +import android.content.res.ColorStateList; +import android.support.v4.content.ContextCompat; +import android.util.AttributeSet; +import android.view.ContextMenu; +import android.view.ContextMenu.ContextMenuInfo; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.View.OnCreateContextMenuListener; + +import org.chromium.base.ApiCompatibilityUtils; +import org.chromium.chrome.R; +import org.chromium.chrome.browser.partnercustomizations.HomepageManager; +import org.chromium.chrome.browser.toolbar.ThemeColorProvider.ThemeColorObserver; +import org.chromium.chrome.browser.util.FeatureUtilities; +import org.chromium.ui.widget.ChromeImageButton; + +/** + * The home button. + */ +public class HomeButton extends ChromeImageButton implements ThemeColorObserver, + OnCreateContextMenuListener, + MenuItem.OnMenuItemClickListener { + private static final int ID_REMOVE = 0; + + /** A provider that notifies components when the theme color changes.*/ + private ThemeColorProvider mThemeColorProvider; + + public HomeButton(Context context, AttributeSet attrs) { + super(context, attrs); + + final int homeButtonIcon = FeatureUtilities.isNewTabPageButtonEnabled() + ? R.drawable.ic_home + : R.drawable.btn_toolbar_home; + setImageDrawable(ContextCompat.getDrawable(context, homeButtonIcon)); + if (!FeatureUtilities.isNewTabPageButtonEnabled() + && !FeatureUtilities.isBottomToolbarEnabled()) { + setOnCreateContextMenuListener(this); + } + } + + public void destroy() { + if (mThemeColorProvider != null) { + mThemeColorProvider.removeObserver(this); + mThemeColorProvider = null; + } + } + + public void setThemeColorProvider(ThemeColorProvider themeColorProvider) { + mThemeColorProvider = themeColorProvider; + mThemeColorProvider.addObserver(this); + } + + @Override + public void onThemeColorChanged(ColorStateList tint, int primaryColor) { + ApiCompatibilityUtils.setImageTintList(this, tint); + } + + @Override + public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { + menu.add(Menu.NONE, ID_REMOVE, Menu.NONE, R.string.remove).setOnMenuItemClickListener(this); + } + + @Override + public boolean onMenuItemClick(MenuItem item) { + assert item.getItemId() == ID_REMOVE; + HomepageManager.getInstance().setPrefHomepageEnabled(false); + return true; + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/HomePageButton.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/HomePageButton.java deleted file mode 100644 index e03afdd..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/HomePageButton.java +++ /dev/null
@@ -1,46 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.toolbar; - -import android.content.Context; -import android.util.AttributeSet; -import android.view.ContextMenu; -import android.view.ContextMenu.ContextMenuInfo; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.view.View.OnCreateContextMenuListener; - -import org.chromium.chrome.R; -import org.chromium.chrome.browser.partnercustomizations.HomepageManager; -import org.chromium.chrome.browser.util.FeatureUtilities; -import org.chromium.ui.widget.ChromeImageButton; - -/** - * View that displays the home page button. - */ -public class HomePageButton extends ChromeImageButton - implements OnCreateContextMenuListener, MenuItem.OnMenuItemClickListener { - private static final int ID_REMOVE = 0; - - /** Constructor inflating from XML. */ - public HomePageButton(Context context, AttributeSet attrs) { - super(context, attrs); - if (!FeatureUtilities.isNewTabPageButtonEnabled()) setOnCreateContextMenuListener(this); - } - - @Override - public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { - menu.add(Menu.NONE, ID_REMOVE, Menu.NONE, R.string.remove) - .setOnMenuItemClickListener(this); - } - - @Override - public boolean onMenuItemClick(MenuItem item) { - assert item.getItemId() == ID_REMOVE; - HomepageManager.getInstance().setPrefHomepageEnabled(false); - return true; - } -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/bottom/BrowsingModeBottomToolbarCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/bottom/BrowsingModeBottomToolbarCoordinator.java index 0f79804..b339876 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/bottom/BrowsingModeBottomToolbarCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/bottom/BrowsingModeBottomToolbarCoordinator.java
@@ -19,6 +19,7 @@ import org.chromium.chrome.browser.modelutil.PropertyModelChangeProcessor; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tabmodel.TabModelSelector; +import org.chromium.chrome.browser.toolbar.HomeButton; import org.chromium.chrome.browser.toolbar.MenuButton; import org.chromium.chrome.browser.toolbar.TabCountProvider; import org.chromium.chrome.browser.toolbar.TabSwitcherButtonCoordinator;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/bottom/HomeButton.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/bottom/HomeButton.java deleted file mode 100644 index fb84ab90..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/bottom/HomeButton.java +++ /dev/null
@@ -1,51 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.toolbar.bottom; - -import android.content.Context; -import android.content.res.ColorStateList; -import android.support.v4.content.ContextCompat; -import android.util.AttributeSet; - -import org.chromium.base.ApiCompatibilityUtils; -import org.chromium.chrome.R; -import org.chromium.chrome.browser.toolbar.ThemeColorProvider; -import org.chromium.chrome.browser.toolbar.ThemeColorProvider.ThemeColorObserver; -import org.chromium.chrome.browser.util.FeatureUtilities; -import org.chromium.ui.widget.ChromeImageButton; - -/** - * The home button. - */ -class HomeButton extends ChromeImageButton implements ThemeColorObserver { - /** A provider that notifies components when the theme color changes.*/ - private ThemeColorProvider mThemeColorProvider; - - public HomeButton(Context context, AttributeSet attrs) { - super(context, attrs); - - final int homeButtonIcon = FeatureUtilities.isNewTabPageButtonEnabled() - ? R.drawable.ic_home - : R.drawable.btn_toolbar_home; - setImageDrawable(ContextCompat.getDrawable(context, homeButtonIcon)); - } - - void setThemeColorProvider(ThemeColorProvider themeColorProvider) { - mThemeColorProvider = themeColorProvider; - mThemeColorProvider.addObserver(this); - } - - void destroy() { - if (mThemeColorProvider != null) { - mThemeColorProvider.removeObserver(this); - mThemeColorProvider = null; - } - } - - @Override - public void onThemeColorChanged(ColorStateList tint, int primaryColor) { - ApiCompatibilityUtils.setImageTintList(this, tint); - } -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarLayout.java index 5a680118..abe2582 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarLayout.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarLayout.java
@@ -45,7 +45,6 @@ import org.chromium.chrome.browser.toolbar.TabCountProvider; import org.chromium.chrome.browser.toolbar.ToolbarDataProvider; import org.chromium.chrome.browser.toolbar.ToolbarTabController; -import org.chromium.chrome.browser.util.FeatureUtilities; import org.chromium.chrome.browser.util.ViewUtils; import org.chromium.chrome.browser.widget.PulseDrawable; import org.chromium.chrome.browser.widget.ToolbarProgressBar; @@ -958,15 +957,4 @@ * it. */ void setTabModelSelector(TabModelSelector selector) {} - - /** - * Sets the icon drawable for the ntp button if the ntp button feature is enabled. - * Note: This method is called twice in ToolbarLayout's children - once in - * #onNativeLibraryReady() & once in #onFinishInflate() (see https://crbug.com/862887). - * @param ntpButton The button that needs to be changed. - */ - void changeIconToNTPIcon(ImageButton ntpButton) { - if (FeatureUtilities.isNewTabPageButtonEnabled()) - ntpButton.setImageResource(R.drawable.ic_home); - } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java index 90f20e90..63c2632f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java
@@ -382,7 +382,6 @@ mToolbarButtonsContainer = (ViewGroup) findViewById(R.id.toolbar_buttons); mHomeButton = findViewById(R.id.home_button); - changeIconToNTPIcon(mHomeButton); if (FeatureUtilities.isBottomToolbarEnabled()) { disableMenuButton(); if (mHomeButton != null) { @@ -510,7 +509,6 @@ if (!FeatureUtilities.isBottomToolbarEnabled()) enableTabSwitchingResources(); if (mHomeButton != null) { - changeIconToNTPIcon(mHomeButton); mHomeButton.setOnClickListener(this); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarTablet.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarTablet.java index eabd696..b0dc941 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarTablet.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarTablet.java
@@ -105,7 +105,6 @@ mLocationBar = (LocationBarTablet) findViewById(R.id.location_bar); mHomeButton = findViewById(R.id.home_button); - changeIconToNTPIcon(mHomeButton); mBackButton = findViewById(R.id.back_button); mForwardButton = findViewById(R.id.forward_button); mReloadButton = findViewById(R.id.refresh_button); @@ -163,7 +162,6 @@ public void onNativeLibraryReady() { super.onNativeLibraryReady(); mLocationBar.onNativeLibraryReady(); - changeIconToNTPIcon(mHomeButton); mHomeButton.setOnClickListener(this); mHomeButton.setOnKeyListener(new KeyboardNavigationListener() { @Override
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni index c04433c0..04084836 100644 --- a/chrome/android/java_sources.gni +++ b/chrome/android/java_sources.gni
@@ -404,7 +404,6 @@ "java/src/org/chromium/chrome/browser/crash/ApplicationStatusTracker.java", "java/src/org/chromium/chrome/browser/crash/ChromeMinidumpUploadJobService.java", "java/src/org/chromium/chrome/browser/crash/ChromeMinidumpUploaderDelegate.java", - "java/src/org/chromium/chrome/browser/crash/CrashKeys.java", "java/src/org/chromium/chrome/browser/crash/LogcatExtractionRunnable.java", "java/src/org/chromium/chrome/browser/crash/MinidumpLogcatPrepender.java", "java/src/org/chromium/chrome/browser/crash/MinidumpUploadRetry.java", @@ -1577,7 +1576,7 @@ "java/src/org/chromium/chrome/browser/tabmodel/document/StorageDelegate.java", "java/src/org/chromium/chrome/browser/tabmodel/document/TabDelegate.java", "java/src/org/chromium/chrome/browser/tasks/TasksUma.java", - "java/src/org/chromium/chrome/browser/toolbar/HomePageButton.java", + "java/src/org/chromium/chrome/browser/toolbar/HomeButton.java", "java/src/org/chromium/chrome/browser/toolbar/IncognitoStateProvider.java", "java/src/org/chromium/chrome/browser/toolbar/IncognitoToggleTabLayout.java", "java/src/org/chromium/chrome/browser/toolbar/KeyboardNavigationListener.java", @@ -1600,7 +1599,6 @@ "java/src/org/chromium/chrome/browser/toolbar/bottom/BrowsingModeBottomToolbarMediator.java", "java/src/org/chromium/chrome/browser/toolbar/bottom/BrowsingModeBottomToolbarModel.java", "java/src/org/chromium/chrome/browser/toolbar/bottom/BrowsingModeBottomToolbarViewBinder.java", - "java/src/org/chromium/chrome/browser/toolbar/bottom/HomeButton.java", "java/src/org/chromium/chrome/browser/toolbar/bottom/ScrollingBottomViewResourceFrameLayout.java", "java/src/org/chromium/chrome/browser/toolbar/bottom/SearchAccelerator.java", "java/src/org/chromium/chrome/browser/toolbar/bottom/ShareButton.java",
diff --git a/chrome/android/javatests/DEPS b/chrome/android/javatests/DEPS index f98022e6..4c30088 100644 --- a/chrome/android/javatests/DEPS +++ b/chrome/android/javatests/DEPS
@@ -3,6 +3,7 @@ "+components/autofill/android/java/src/org/chromium/components/autofill", "+components/background_task_scheduler/android/java", "+components/bookmarks/common/android/java/src/org/chromium/components/bookmarks", + "+components/crash/android", "+components/embedder_support/android", "+components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement", "+components/dom_distiller/core/android/java/src/org/chromium/components/dom_distiller/core",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/crash/PureJavaExceptionReporterTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/crash/PureJavaExceptionReporterTest.java index 5aadd64..b6b5a513 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/crash/PureJavaExceptionReporterTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/crash/PureJavaExceptionReporterTest.java
@@ -13,6 +13,8 @@ import org.chromium.base.ThreadUtils; import org.chromium.base.test.BaseJUnit4ClassRunner; +import org.chromium.components.crash.CrashKeyIndex; +import org.chromium.components.crash.CrashKeys; import org.chromium.components.minidump_uploader.CrashTestRule; import java.io.BufferedReader;
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/media/remote/CastNotificationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/media/remote/CastNotificationTest.java index 0de56d9..2382567 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/media/remote/CastNotificationTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/media/remote/CastNotificationTest.java
@@ -17,6 +17,7 @@ import org.chromium.base.ThreadUtils; import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.Restriction; import org.chromium.base.test.util.RetryOnFailure; @@ -44,6 +45,7 @@ * Test the pause button on the notification. */ @Test + @DisabledTest // crbug.com/907307 @Feature({"VideoFling"}) @LargeTest @RetryOnFailure
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/media/remote/CastPositionTransferTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/media/remote/CastPositionTransferTest.java index 2b2232c..e7cc0efa 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/media/remote/CastPositionTransferTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/media/remote/CastPositionTransferTest.java
@@ -19,6 +19,7 @@ import org.junit.runner.RunWith; import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.Restriction; import org.chromium.base.test.util.RetryOnFailure; @@ -83,6 +84,7 @@ /** Test for crbug.com/428409 */ @Test + @DisabledTest // crbug.com/907307 @Feature({"VideoFling"}) @LargeTest @Restriction(RESTRICTION_TYPE_NON_LOW_END_DEVICE) // crbug.com/652872 @@ -114,6 +116,7 @@ /** Test for crbug.com/428409 */ @Test + @DisabledTest // crbug.com/907307 @Feature({"VideoFling"}) @LargeTest @Restriction(RESTRICTION_TYPE_NON_LOW_END_DEVICE) // crbug.com/652872 @@ -163,6 +166,7 @@ /** Test for crbug.com/425105 */ @Test + @DisabledTest // crbug.com/907307 @Feature({"VideoFling"}) @LargeTest @Restriction(RESTRICTION_TYPE_NON_LOW_END_DEVICE) // crbug.com/593840, crbug.com/652872
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/media/remote/CastStartStopTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/media/remote/CastStartStopTest.java index 440a7f8..4c854b1 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/media/remote/CastStartStopTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/media/remote/CastStartStopTest.java
@@ -18,6 +18,7 @@ import org.chromium.base.ThreadUtils; import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.DisableIf; +import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.FlakyTest; import org.chromium.base.test.util.Restriction; @@ -45,6 +46,7 @@ * Test that we can cast a video, and that we get the ExpandedControllerActivity when we do. */ @Test + @DisabledTest // crbug.com/907307 @Feature({"VideoFling"}) @LargeTest @RetryOnFailure @@ -58,6 +60,7 @@ * Test that we can disconnect a cast session from the expanded controller activity overlay. */ @Test + @DisabledTest // crbug.com/907307 @Feature({"VideoFling"}) @LargeTest @RetryOnFailure @@ -76,6 +79,7 @@ * Test that we can stop a cast session from the notification. */ @Test + @DisabledTest // crbug.com/907307 @Feature({"VideoFling"}) @LargeTest @RetryOnFailure
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 cefd2dc..f3cd818f 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
@@ -20,6 +20,7 @@ import org.junit.runner.RunWith; import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.RetryOnFailure; import org.chromium.chrome.browser.ChromeSwitches; @@ -44,6 +45,7 @@ private static final String VIDEO_ELEMENT_2 = "video2"; @Test + @DisabledTest // crbug.com/907307 @Feature({"VideoFling"}) @LargeTest @RetryOnFailure // crbug.com/623526 @@ -63,6 +65,7 @@ } @Test + @DisabledTest // crbug.com/907307 @Feature({"VideoFling"}) @LargeTest @RetryOnFailure // crbug.com/623526 @@ -81,6 +84,7 @@ } @Test + @DisabledTest // crbug.com/907307 @Feature({"VideoFling"}) @LargeTest @RetryOnFailure // crbug.com/623526 @@ -98,6 +102,7 @@ } @Test + @DisabledTest // crbug.com/907307 @Feature({"VideoFling"}) @LargeTest @RetryOnFailure // crbug.com/623526 @@ -117,6 +122,7 @@ } @Test + @DisabledTest // crbug.com/907307 @Feature({"VideoFling"}) @LargeTest @RetryOnFailure // crbug.com/623526 @@ -135,6 +141,7 @@ } @Test + @DisabledTest // crbug.com/907307 @Feature({"VideoFling"}) @LargeTest @RetryOnFailure // crbug.com/623526
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/media/remote/CastVideoControlsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/media/remote/CastVideoControlsTest.java index 8ffb20740..113223b 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/media/remote/CastVideoControlsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/media/remote/CastVideoControlsTest.java
@@ -17,6 +17,7 @@ import org.junit.runner.RunWith; import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.Restriction; import org.chromium.base.test.util.RetryOnFailure; @@ -43,6 +44,7 @@ * Test the pause button. */ @Test + @DisabledTest // crbug.com/907307 @Feature({"VideoFling"}) @LargeTest @RetryOnFailure
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/media/router/caf/BaseSessionControllerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/media/router/caf/BaseSessionControllerTest.java index 28d649d..b44cf9a 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/media/router/caf/BaseSessionControllerTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/media/router/caf/BaseSessionControllerTest.java
@@ -13,7 +13,6 @@ import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.anyString; import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.eq; import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; @@ -115,51 +114,14 @@ assertNull(mController.getRouteCreationInfo()); } - /** - * Test the case of requesting a session launch while the requested route is not selected. The - * controller should set the receiver app ID and then select the route so CAF will start the - * session once observed the route selection. - */ @Test - public void testRequestSessionLaunch_routeNotSelected() { + public void testRequestSessionLaunch() { mController.requestSessionLaunch(); verify(mCastContext).setReceiverApplicationId(APP_ID); verify(mMediaRouterHelper.getCastRoute()).select(); assertSame(mRequestInfo, mController.getRouteCreationInfo()); } - /** - * Test the case of requesting a session launch while the requested route is already selected. - * The controller should first unselect the route, set the application ID and then select the - * route again to notify CAF to start the session. - */ - @Test - public void testRequestSessionLaunch_routeSelected() { - mMediaRouterHelper.selectRoute(mMediaRouterHelper.getCastRoute()); - - ArgumentCaptor<MediaRouter.Callback> callbackCaptor = - ArgumentCaptor.forClass(MediaRouter.Callback.class); - - mController.requestSessionLaunch(); - verify(mCastContext).setReceiverApplicationId(APP_ID); - verify(mMediaRouterHelper.getShadowImpl()) - .addCallback(eq(mMediaRouteSelector), callbackCaptor.capture()); - assertSame(mRequestInfo, mController.getRouteCreationInfo()); - verify(mMediaRouterHelper.getShadowImpl()).unselect(MediaRouter.UNSELECT_REASON_UNKNOWN); - - // Simulate another route has been unselected. - callbackCaptor.getValue().onRouteUnselected( - MediaRouter.getInstance(mContext), mMediaRouterHelper.getOtherCastRoute()); - - assertFalse(mMediaRouterHelper.getCastRoute().isSelected()); - - // Simulate the cast route has been unselected. - callbackCaptor.getValue().onRouteUnselected( - MediaRouter.getInstance(mContext), mMediaRouterHelper.getCastRoute()); - - assertTrue(mMediaRouterHelper.getCastRoute().isSelected()); - } - @Test public void testEndSession() { mController.endSession();
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index ca836d2f..28f5780 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -1473,8 +1473,9 @@ "speech/tts_mac.mm", "speech/tts_message_filter.cc", "speech/tts_message_filter.h", - "speech/tts_platform.cc", "speech/tts_platform.h", + "speech/tts_platform_impl.cc", + "speech/tts_platform_impl.h", "speech/tts_win.cc", "ssl/bad_clock_blocking_page.cc", "ssl/bad_clock_blocking_page.h", @@ -2114,8 +2115,6 @@ "android/contextualsearch/unhandled_tap_web_contents_observer.cc", "android/contextualsearch/unhandled_tap_web_contents_observer.h", "android/cookies/cookies_fetcher_util.cc", - "android/crash/crash_keys_android.cc", - "android/crash/crash_keys_android.h", "android/crash/pure_java_exception_handler.cc", "android/crash/pure_java_exception_handler.h", "android/customtabs/detached_resource_request.cc", @@ -2557,6 +2556,7 @@ "//chrome/services/media_gallery_util/public/cpp", "//components/autofill_assistant/browser", "//components/cdm/browser", + "//components/crash/android:crash_android", "//components/embedder_support/android:web_contents_delegate", "//components/feed:buildflags", "//components/feed:feature_list", @@ -2599,6 +2599,8 @@ "apps/app_service/app_service_proxy_factory.h", "background/background_contents.cc", "background/background_contents.h", + "badging/badge_service_impl.cc", + "badging/badge_service_impl.h", "banners/app_banner_infobar_delegate_desktop.cc", "banners/app_banner_infobar_delegate_desktop.h", "banners/app_banner_manager_desktop.cc", @@ -3111,8 +3113,6 @@ "apps/app_service/built_in_chromeos_apps.h", "ash_service_registry.cc", "ash_service_registry.h", - "badging/badge_service_impl.cc", - "badging/badge_service_impl.h", "component_updater/cros_component_installer_chromeos.cc", "component_updater/cros_component_installer_chromeos.h", "component_updater/cros_component_manager.h", @@ -4687,7 +4687,6 @@ "../android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchTabHelper.java", "../android/java/src/org/chromium/chrome/browser/contextualsearch/CtrSuppression.java", "../android/java/src/org/chromium/chrome/browser/cookies/CookiesFetcher.java", - "../android/java/src/org/chromium/chrome/browser/crash/CrashKeys.java", "../android/java/src/org/chromium/chrome/browser/crash/MinidumpUploadService.java", "../android/java/src/org/chromium/chrome/browser/crash/PureJavaExceptionHandler.java", "../android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java",
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index f75e3f7..f5e7150 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -335,7 +335,6 @@ #elif defined(OS_CHROMEOS) #include "ash/public/interfaces/constants.mojom.h" #include "chrome/browser/ash_service_registry.h" -#include "chrome/browser/badging/badge_service_impl.h" #include "chrome/browser/chromeos/apps/intent_helper/apps_navigation_throttle.h" #include "chrome/browser/chromeos/arc/fileapi/arc_content_file_system_backend_delegate.h" #include "chrome/browser/chromeos/arc/fileapi/arc_documents_provider_backend_delegate.h" @@ -400,6 +399,7 @@ #endif #if !defined(OS_ANDROID) +#include "chrome/browser/badging/badge_service_impl.h" #include "chrome/browser/devtools/chrome_devtools_manager_delegate.h" #include "chrome/browser/devtools/devtools_window.h" #include "chrome/browser/media/unified_autoplay_config.h" @@ -4340,7 +4340,7 @@ frame_interfaces_->AddInterface(base::Bind(&ShareServiceImpl::Create)); #endif -#if defined(OS_CHROMEOS) +#if !defined(OS_ANDROID) frame_interfaces_->AddInterface( base::BindRepeating(&BadgeServiceImpl::Create)); #endif
diff --git a/chrome/browser/chrome_resource_bundle_helper.cc b/chrome/browser/chrome_resource_bundle_helper.cc index cfe253d..4b1e3731 100644 --- a/chrome/browser/chrome_resource_bundle_helper.cc +++ b/chrome/browser/chrome_resource_bundle_helper.cc
@@ -42,19 +42,6 @@ // locale dll to load. This also causes local state prefs to be registered. PrefService* local_state = chrome_feature_list_creator->local_state(); DCHECK(local_state); -#if defined(OS_WIN) - if (first_run::IsChromeFirstRun()) { - // During first run we read the google_update registry key to find what - // language the user selected when downloading the installer. This - // becomes our default language in the prefs. - // Other platforms obey the system locale. - base::string16 install_lang; - if (GoogleUpdateSettings::GetLanguage(&install_lang)) { - local_state->SetString(language::prefs::kApplicationLocale, - base::UTF16ToASCII(install_lang)); - } - } -#endif // defined(OS_WIN) // If the local state file for the current profile doesn't exist and the // parent profile command line flag is present, then we should inherit some
diff --git a/chrome/browser/chromeos/accessibility/speech_monitor.cc b/chrome/browser/chromeos/accessibility/speech_monitor.cc index 4c0f3fb..b9a208c 100644 --- a/chrome/browser/chromeos/accessibility/speech_monitor.cc +++ b/chrome/browser/chromeos/accessibility/speech_monitor.cc
@@ -16,12 +16,12 @@ } // namespace SpeechMonitor::SpeechMonitor() { - TtsControllerDelegateImpl::GetInstance()->SetPlatformImpl(this); + TtsControllerDelegateImpl::GetInstance()->SetTtsPlatform(this); } SpeechMonitor::~SpeechMonitor() { - TtsControllerDelegateImpl::GetInstance()->SetPlatformImpl( - TtsPlatformImpl::GetInstance()); + TtsControllerDelegateImpl::GetInstance()->SetTtsPlatform( + TtsPlatform::GetInstance()); } std::string SpeechMonitor::GetNextUtterance() { @@ -99,10 +99,6 @@ voice.events.insert(content::TTS_EVENT_END); } -std::string SpeechMonitor::error() { - return ""; -} - void SpeechMonitor::WillSpeakUtteranceWithVoice( const content::Utterance* utterance, const content::VoiceData& voice_data) { @@ -120,4 +116,21 @@ loop_runner_->Quit(); } +bool SpeechMonitor::LoadBuiltInTtsExtension( + content::BrowserContext* browser_context) { + return false; +} + +std::string SpeechMonitor::GetError() { + return error_; +} + +void SpeechMonitor::ClearError() { + error_ = std::string(); +} + +void SpeechMonitor::SetError(const std::string& error) { + error_ = error; +} + } // namespace chromeos
diff --git a/chrome/browser/chromeos/accessibility/speech_monitor.h b/chrome/browser/chromeos/accessibility/speech_monitor.h index f434500507..9c31fe8 100644 --- a/chrome/browser/chromeos/accessibility/speech_monitor.h +++ b/chrome/browser/chromeos/accessibility/speech_monitor.h
@@ -18,10 +18,10 @@ // For testing purpose installs itself as the platform speech synthesis engine, // allowing it to intercept all speech calls, and then provides a method to // block until the next utterance is spoken. -class SpeechMonitor : public TtsPlatformImpl { +class SpeechMonitor : public TtsPlatform { public: SpeechMonitor(); - ~SpeechMonitor() override; + virtual ~SpeechMonitor(); // Blocks until the next utterance is spoken, and returns its text. std::string GetNextUtterance(); @@ -38,7 +38,7 @@ void BlockUntilStop(); private: - // TtsPlatformImpl implementation. + // TtsPlatform implementation. bool PlatformImplAvailable() override; bool Speak(int utterance_id, const std::string& utterance, @@ -50,16 +50,19 @@ void GetVoices(std::vector<content::VoiceData>* out_voices) override; void Pause() override {} void Resume() override {} - std::string error() override; - void clear_error() override {} - void set_error(const std::string& error) override {} void WillSpeakUtteranceWithVoice( const content::Utterance* utterance, const content::VoiceData& voice_data) override; + bool LoadBuiltInTtsExtension( + content::BrowserContext* browser_context) override; + std::string GetError() override; + void ClearError() override; + void SetError(const std::string& error) override; scoped_refptr<content::MessageLoopRunner> loop_runner_; base::circular_deque<std::string> utterance_queue_; bool did_stop_ = false; + std::string error_; DISALLOW_COPY_AND_ASSIGN(SpeechMonitor); };
diff --git a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc index b73fa03..893b7c66a 100644 --- a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc +++ b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
@@ -580,6 +580,7 @@ TestCase("shareFileTeamDrive"), TestCase("shareDirectoryTeamDrive"), TestCase("shareHostedFileTeamDrive"), + TestCase("shareTeamDrive"), TestCase("manageHostedFileTeamDrive"), TestCase("manageFileTeamDrive"), TestCase("manageDirectoryTeamDrive"),
diff --git a/chrome/browser/chromeos/file_manager/file_manager_jstest.cc b/chrome/browser/chromeos/file_manager/file_manager_jstest.cc index 700d596..d8ffb088 100644 --- a/chrome/browser/chromeos/file_manager/file_manager_jstest.cc +++ b/chrome/browser/chromeos/file_manager/file_manager_jstest.cc
@@ -39,8 +39,7 @@ } IN_PROC_BROWSER_TEST_F(FileManagerJsTest, FileOperationManagerTest) { - RunTest(base::FilePath( - FILE_PATH_LITERAL("background/js/file_operation_manager_unittest.html"))); + RunGeneratedTest("/background/js/file_operation_manager_unittest.html"); } IN_PROC_BROWSER_TEST_F(FileManagerJsTest, DriveSyncHandlerTest) {
diff --git a/chrome/browser/chromeos/file_manager/path_util.cc b/chrome/browser/chromeos/file_manager/path_util.cc index fb890cf..11100c6 100644 --- a/chrome/browser/chromeos/file_manager/path_util.cc +++ b/chrome/browser/chromeos/file_manager/path_util.cc
@@ -115,8 +115,12 @@ storage::ExternalMountPoints* const mount_points = storage::ExternalMountPoints::GetSystemInstance(); base::FilePath path; - if (mount_points->GetRegisteredPath(mount_point_name, &path)) + if (mount_points->GetRegisteredPath(mount_point_name, &path)) { + if (base::FeatureList::IsEnabled(chromeos::features::kMyFilesVolume)) + return path.AppendASCII(kFolderNameDownloads); + return path; + } // Return $HOME/Downloads as Download folder. if (ShouldMountPrimaryUserDownloads(profile))
diff --git a/chrome/browser/chromeos/file_manager/path_util_unittest.cc b/chrome/browser/chromeos/file_manager/path_util_unittest.cc index c19028a..bf53948 100644 --- a/chrome/browser/chromeos/file_manager/path_util_unittest.cc +++ b/chrome/browser/chromeos/file_manager/path_util_unittest.cc
@@ -87,10 +87,6 @@ base::test::ScopedFeatureList feature_list; feature_list.InitAndEnableFeature(chromeos::features::kMyFilesVolume); - base::FilePath myfiles_path = profile_path.AppendASCII("MyFiles"); - base::FilePath myfiles_downloads_path = - myfiles_path.AppendASCII("Downloads"); - EXPECT_EQ("/home/chronos/u-0123456789abcdef/MyFiles", GetMyFilesFolderForProfile(&profile).value()); EXPECT_EQ("/home/chronos/u-0123456789abcdef/MyFiles/Downloads", @@ -102,10 +98,39 @@ storage::kFileSystemTypeNativeLocal, storage::FileSystemMountOption(), profile_path.Append("MyFiles")); + // When returning from the mount_point Downloads should still point to + // MyFiles/Downloads. + EXPECT_EQ("/home/chronos/u-0123456789abcdef/MyFiles/Downloads", + GetDownloadsFolderForProfile(&profile).value()); + // Still the same: /home/u-{hash}/MyFiles. EXPECT_EQ("/home/chronos/u-0123456789abcdef/MyFiles", GetMyFilesFolderForProfile(&profile).value()); } + { + // Remove mount configured to MyFiles in the previous test. + storage::ExternalMountPoints::GetSystemInstance()->RevokeFileSystem( + GetDownloadsMountPointName(&profile)); + + // Add mount point for Downloads instead of MyFiles. + storage::ExternalMountPoints::GetSystemInstance()->RegisterFileSystem( + GetDownloadsMountPointName(&profile), + storage::kFileSystemTypeNativeLocal, storage::FileSystemMountOption(), + profile_path.Append("Downloads")); + + // Disable MyFilesVolume again to test returning from the mount_point. + base::test::ScopedFeatureList feature_list; + feature_list.InitAndDisableFeature(chromeos::features::kMyFilesVolume); + // When MyFilesVolume feature is disabled it will return the same as + // Downloads. + EXPECT_EQ(GetDownloadsFolderForProfile(&profile), + GetMyFilesFolderForProfile(&profile)); + EXPECT_EQ("/home/chronos/u-0123456789abcdef/Downloads", + GetDownloadsFolderForProfile(&profile).value()); + // Unmount Downloads because it was interfering with other tests. + storage::ExternalMountPoints::GetSystemInstance()->RevokeFileSystem( + GetDownloadsMountPointName(&profile)); + } } TEST(FileManagerPathUtilTest, GetPathDisplayTextForSettings) {
diff --git a/chrome/browser/chromeos/first_run/first_run.cc b/chrome/browser/chromeos/first_run/first_run.cc index b1922d8..19b9479 100644 --- a/chrome/browser/chromeos/first_run/first_run.cc +++ b/chrome/browser/chromeos/first_run/first_run.cc
@@ -18,7 +18,7 @@ #include "chrome/browser/policy/profile_policy_connector_factory.h" #include "chrome/browser/prefs/pref_service_syncable_util.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/signin/signin_manager_factory.h" +#include "chrome/browser/signin/identity_manager_factory.h" #include "chrome/browser/ui/ash/tablet_mode_client.h" #include "chrome/browser/ui/extensions/app_launch_params.h" #include "chrome/browser/ui/extensions/application_launch.h" @@ -32,7 +32,6 @@ #include "components/prefs/pref_service.h" #include "components/signin/core/browser/account_info.h" #include "components/signin/core/browser/account_tracker_service.h" -#include "components/signin/core/browser/signin_manager_base.h" #include "components/sync_preferences/pref_service_syncable.h" #include "components/user_manager/user_manager.h" #include "content/public/browser/notification_observer.h" @@ -41,6 +40,7 @@ #include "content/public/common/content_switches.h" #include "extensions/browser/extension_system.h" #include "extensions/common/constants.h" +#include "services/identity/public/cpp/identity_manager.h" #include "ui/gfx/geometry/rect.h" namespace chromeos { @@ -127,11 +127,11 @@ // Whether the account is supported for voice interaction. bool account_supported = false; - SigninManagerBase* signin_manager = - SigninManagerFactory::GetForProfileIfExists(profile_); - if (signin_manager) { + auto* identity_manager = + IdentityManagerFactory::GetForProfileIfExists(profile_); + if (identity_manager) { std::string hosted_domain = - signin_manager->GetAuthenticatedAccountInfo().hosted_domain; + identity_manager->GetPrimaryAccountInfo().hosted_domain; if (hosted_domain == AccountTrackerService::kNoHostedDomainFound || hosted_domain == "google.com") { account_supported = true;
diff --git a/chrome/browser/chromeos/login/session/user_session_manager.cc b/chrome/browser/chromeos/login/session/user_session_manager.cc index b6267431..b1b3d38b 100644 --- a/chrome/browser/chromeos/login/session/user_session_manager.cc +++ b/chrome/browser/chromeos/login/session/user_session_manager.cc
@@ -1448,7 +1448,7 @@ BootTimesRecorder::Get()->AddLoginTimeMarker("TPMOwn-Start", false); if (!tpm_util::TpmIsEnabled() || tpm_util::TpmIsBeingOwned()) { - FinalizePrepareProfile(profile); + ClearSigninProfileAndFinalizePrepareProfile(profile); return; } @@ -1475,7 +1475,13 @@ void UserSessionManager::OnCryptohomeOperationCompleted(Profile* profile, bool result) { DCHECK(result); - FinalizePrepareProfile(profile); + ClearSigninProfileAndFinalizePrepareProfile(profile); +} + +void UserSessionManager::ClearSigninProfileAndFinalizePrepareProfile( + Profile* profile) { + ProfileHelper::Get()->ClearSigninProfile(base::BindRepeating( + &UserSessionManager::FinalizePrepareProfile, AsWeakPtr(), profile)); } void UserSessionManager::FinalizePrepareProfile(Profile* profile) {
diff --git a/chrome/browser/chromeos/login/session/user_session_manager.h b/chrome/browser/chromeos/login/session/user_session_manager.h index 2e8e3d29..de89481 100644 --- a/chrome/browser/chromeos/login/session/user_session_manager.h +++ b/chrome/browser/chromeos/login/session/user_session_manager.h
@@ -389,6 +389,9 @@ // Called on UI thread once Cryptohome operation completes. void OnCryptohomeOperationCompleted(Profile* profile, bool result); + // Clears the sign-in profile, and initiates the user profile finalization. + void ClearSigninProfileAndFinalizePrepareProfile(Profile* profile); + // Finalized profile preparation. void FinalizePrepareProfile(Profile* profile);
diff --git a/chrome/browser/chromeos/power/auto_screen_brightness/adapter.h b/chrome/browser/chromeos/power/auto_screen_brightness/adapter.h index c1a7f8b..9da989c 100644 --- a/chrome/browser/chromeos/power/auto_screen_brightness/adapter.h +++ b/chrome/browser/chromeos/power/auto_screen_brightness/adapter.h
@@ -48,13 +48,13 @@ kMaxValue = kLatest }; - // TODO(jiameng): we currently use past 2 seconds of ambient values to + // TODO(jiameng): we currently use past 5 seconds of ambient values to // calculate average ambient when we predict optimal brightness. This is // shorter than the duration used for training data (10 seconds), because it's // important that we can quickly adjust the brightness when ambient value // changes. This duration should be revised. static constexpr base::TimeDelta kAmbientLightShortHorizon = - base::TimeDelta::FromSeconds(2); + base::TimeDelta::FromSeconds(5); // Size of |ambient_light_values_|. static constexpr int kNumberAmbientValuesToTrack = @@ -69,16 +69,16 @@ // from the current value before brightness could be changed: brightness // will actually be changed if |min_time_between_brightness_changes| has // passed from the previous change. - double brightening_lux_threshold_ratio = 0.1; - double darkening_lux_threshold_ratio = 0.2; + double brightening_lux_threshold_ratio = 0.3; + double darkening_lux_threshold_ratio = 0.4; // If average ambient value changes by more than the "immediate" thresholds // then brightness transition will happen immediately, without waiting for // |min_time_between_brightness_changes| to elapse. This value should be // greater than or equal to the max of brightening/darkening thresholds // above. - double immediate_brightening_lux_threshold_ratio = 0.3; - double immediate_darkening_lux_threshold_ratio = 0.4; + double immediate_brightening_lux_threshold_ratio = 0.4; + double immediate_darkening_lux_threshold_ratio = 0.5; // Whether brightness should be set to the predicted value when the first // ambient reading comes in. If false, we'll wait for
diff --git a/chrome/browser/chromeos/power/auto_screen_brightness/adapter_unittest.cc b/chrome/browser/chromeos/power/auto_screen_brightness/adapter_unittest.cc index 8e7d3eb..d9d3f39 100644 --- a/chrome/browser/chromeos/power/auto_screen_brightness/adapter_unittest.cc +++ b/chrome/browser/chromeos/power/auto_screen_brightness/adapter_unittest.cc
@@ -427,6 +427,7 @@ TEST_F(AdapterTest, BrightnessLuxThresholds) { Init(AlsReader::AlsInitStatus::kSuccess, BrightnessMonitor::Status::kSuccess, global_curve_, personal_curve_, default_params_); + EXPECT_EQ(Adapter::kNumberAmbientValuesToTrack, 5); EXPECT_EQ(adapter_->GetStatusForTesting(), Adapter::Status::kSuccess); EXPECT_TRUE(adapter_->GetGlobalCurveForTesting()); @@ -457,7 +458,8 @@ // A 3rd ALS comes in, but still not enough to trigger brightness change. fake_als_reader_.ReportAmbientLightUpdate(15); EXPECT_EQ(test_observer_.num_changes(), 1); - EXPECT_DOUBLE_EQ(adapter_->GetAverageAmbientForTesting(), (21 + 15) / 2.0); + EXPECT_DOUBLE_EQ(adapter_->GetAverageAmbientForTesting(), + (20 + 21 + 15) / 3.0); EXPECT_DOUBLE_EQ(adapter_->GetBrighteningThresholdForTesting(), 22); EXPECT_DOUBLE_EQ(adapter_->GetDarkeningThresholdForTesting(), 16); @@ -467,15 +469,26 @@ scoped_task_environment_.RunUntilIdle(); EXPECT_EQ(test_observer_.num_changes(), 2); - EXPECT_EQ(Adapter::kNumberAmbientValuesToTrack, 2); - const double expected_average_ambient = - (15.0 + 7.0) / Adapter::kNumberAmbientValuesToTrack; + const double expected_average_ambient = (20 + 21 + 15 + 7) / 4.0; EXPECT_DOUBLE_EQ(adapter_->GetAverageAmbientForTesting(), expected_average_ambient); EXPECT_DOUBLE_EQ(adapter_->GetBrighteningThresholdForTesting(), expected_average_ambient * 1.1); EXPECT_DOUBLE_EQ(adapter_->GetDarkeningThresholdForTesting(), expected_average_ambient * 0.8); + + // Next check |ambient_light_values_| has capacity + // |Adapter::kNumberAmbientValuesToTrack|. + fake_als_reader_.ReportAmbientLightUpdate(8); + scoped_task_environment_.RunUntilIdle(); + EXPECT_DOUBLE_EQ(adapter_->GetAverageAmbientForTesting(), + (20 + 21 + 15 + 7 + 8) / 5.0); + + fake_als_reader_.ReportAmbientLightUpdate(9); + scoped_task_environment_.RunUntilIdle(); + + EXPECT_DOUBLE_EQ(adapter_->GetAverageAmbientForTesting(), + (21 + 15 + 7 + 8 + 9) / 5.0); } TEST_F(AdapterTest, ImmediateBrightnessTransitionThresholds) { @@ -530,7 +543,7 @@ scoped_task_environment_.RunUntilIdle(); EXPECT_EQ(test_observer_.num_changes(), 0); - scoped_task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(2)); + scoped_task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(5)); EXPECT_EQ(test_observer_.num_changes(), 0); // 2nd ALS comes in so that we have |kAmbientLightShortHorizonSeconds| of
diff --git a/chrome/browser/chromeos/power/auto_screen_brightness/modeller_impl.cc b/chrome/browser/chromeos/power/auto_screen_brightness/modeller_impl.cc index 221309b..e2d1e371 100644 --- a/chrome/browser/chromeos/power/auto_screen_brightness/modeller_impl.cc +++ b/chrome/browser/chromeos/power/auto_screen_brightness/modeller_impl.cc
@@ -31,7 +31,8 @@ namespace { // Creates a global/default brightness curve. -// TODO(crbug.com/881215): add actual default curve and then add unit test too. +// TODO(crbug.com/881215): default curve may be revised, if so, need to update +// unit tests as well. MonotoneCubicSpline CreateGlobalCurve() { const std::string global_curve = GetFieldTrialParamValueByFeature( features::kAutoScreenBrightness, "global_curve"); @@ -43,8 +44,14 @@ // TODO(jiameng): log error to UMA. } - const std::vector<double> default_log_lux = {0, 100}; - const std::vector<double> default_brightness = {50, 100}; + const std::vector<double> default_log_lux = { + 3.69, 4.83, 6.54, 7.68, 8.25, 8.82, + }; + + const std::vector<double> default_brightness = { + 36.14, 47.62, 85.83, 93.27, 93.27, 100, + }; + return MonotoneCubicSpline(default_log_lux, default_brightness); }
diff --git a/chrome/browser/chromeos/power/auto_screen_brightness/modeller_impl_unittest.cc b/chrome/browser/chromeos/power/auto_screen_brightness/modeller_impl_unittest.cc index c809a22..d71dea1 100644 --- a/chrome/browser/chromeos/power/auto_screen_brightness/modeller_impl_unittest.cc +++ b/chrome/browser/chromeos/power/auto_screen_brightness/modeller_impl_unittest.cc
@@ -561,7 +561,13 @@ features::kAutoScreenBrightness, {{"global_curve", global_curve_spec}}); // Defined by default values. - const MonotoneCubicSpline expected_global_curve({0, 100}, {50, 100}); + const MonotoneCubicSpline expected_global_curve( + { + 3.69, 4.83, 6.54, 7.68, 8.25, 8.82, + }, + { + 36.14, 47.62, 85.83, 93.27, 93.27, 100, + }); Init(AlsReader::AlsInitStatus::kSuccess, BrightnessMonitor::Status::kSuccess); EXPECT_EQ(modeller_->GetGlobalCurveForTesting(), expected_global_curve);
diff --git a/chrome/browser/chromeos/profiles/profile_helper.cc b/chrome/browser/chromeos/profiles/profile_helper.cc index b5588626..e74d0a2 100644 --- a/chrome/browser/chromeos/profiles/profile_helper.cc +++ b/chrome/browser/chromeos/profiles/profile_helper.cc
@@ -20,6 +20,7 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/profiles/profiles_state.h" +#include "chrome/browser/ui/browser_list.h" #include "chrome/common/chrome_constants.h" #include "chrome/common/chrome_switches.h" #include "chromeos/chromeos_constants.h" @@ -52,6 +53,11 @@ user_id_hash != chrome::kTestUserProfileDir; } +void WrapAsBrowsersCloseCallback(const base::RepeatingClosure& callback, + const base::FilePath& path) { + callback.Run(); +} + class UsernameHashMatcher { public: explicit UsernameHashMatcher(const std::string& h) : username_hash(h) {} @@ -286,7 +292,7 @@ return; } on_clear_profile_stage_finished_ = - base::BarrierClosure(2, base::Bind(&ProfileHelper::OnSigninProfileCleared, + base::BarrierClosure(3, base::Bind(&ProfileHelper::OnSigninProfileCleared, weak_factory_.GetWeakPtr())); LOG_ASSERT(!browsing_data_remover_); browsing_data_remover_ = @@ -302,6 +308,16 @@ login::SigninPartitionManager::Factory::GetForBrowserContext( GetSigninProfile()) ->CloseCurrentSigninSession(on_clear_profile_stage_finished_); + + BrowserList::CloseAllBrowsersWithProfile( + GetSigninProfile(), + base::BindRepeating( + &WrapAsBrowsersCloseCallback, + on_clear_profile_stage_finished_) /* on_close_success */, + base::BindRepeating( + &WrapAsBrowsersCloseCallback, + on_clear_profile_stage_finished_) /* on_close_aborted */, + true /* skip_beforeunload */); } Profile* ProfileHelper::GetProfileByAccountId(const AccountId& account_id) {
diff --git a/chrome/browser/extensions/api/autofill_private/autofill_private_api.cc b/chrome/browser/extensions/api/autofill_private/autofill_private_api.cc index 77d452ba..6021e64 100644 --- a/chrome/browser/extensions/api/autofill_private/autofill_private_api.cc +++ b/chrome/browser/extensions/api/autofill_private/autofill_private_api.cc
@@ -439,6 +439,7 @@ personal_data->UpdateCreditCard(credit_card); } else { personal_data->AddCreditCard(credit_card); + base::RecordAction(base::UserMetricsAction("AutofillCreditCardsAdded")); } return RespondNow(NoArguments());
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index e644e53..878fa2a3 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -463,8 +463,8 @@ }, { "name": "dcheck-is-fatal", - // "owners": [ "your-team" ], - "expiry_milestone": 76 + "owners": [ "wez" ], + "expiry_milestone": -1 }, { "name": "debug-packed-apps",
diff --git a/chrome/browser/metrics/chrome_feature_list_creator.cc b/chrome/browser/metrics/chrome_feature_list_creator.cc index 3c6dd66..0bae50e 100644 --- a/chrome/browser/metrics/chrome_feature_list_creator.cc +++ b/chrome/browser/metrics/chrome_feature_list_creator.cc
@@ -13,6 +13,7 @@ #include "base/files/file_util.h" #include "base/memory/scoped_refptr.h" #include "base/path_service.h" +#include "base/strings/utf_string_conversions.h" #include "base/system/sys_info.h" #include "base/time/time.h" #include "base/trace_event/trace_event.h" @@ -26,6 +27,7 @@ #include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_result_codes.h" #include "chrome/common/pref_names.h" +#include "chrome/installer/util/google_update_settings.h" #include "components/flags_ui/flags_ui_pref_names.h" #include "components/flags_ui/pref_service_flags_storage.h" #include "components/language/core/browser/pref_names.h" @@ -147,6 +149,23 @@ local_state_file, browser_policy_connector_->GetPolicyService(), std::move(pref_registry), false, std::move(delegate), browser_policy_connector_.get()); + +// TODO(asvitkine): This is done here so that the pref is set before +// VariationsService queries the locale. This should potentially be moved to +// somewhere better, e.g. as a helper in first_run namespace. +#if defined(OS_WIN) + if (first_run::IsChromeFirstRun()) { + // During first run we read the google_update registry key to find what + // language the user selected when downloading the installer. This + // becomes our default language in the prefs. + // Other platforms obey the system locale. + base::string16 install_lang; + if (GoogleUpdateSettings::GetLanguage(&install_lang)) { + local_state_->SetString(language::prefs::kApplicationLocale, + base::UTF16ToASCII(install_lang)); + } + } +#endif // defined(OS_WIN) } void ChromeFeatureListCreator::ConvertFlagsToSwitches() {
diff --git a/chrome/browser/navigation_predictor/navigation_predictor.cc b/chrome/browser/navigation_predictor/navigation_predictor.cc index 24d98a9..e8ae0a9 100644 --- a/chrome/browser/navigation_predictor/navigation_predictor.cc +++ b/chrome/browser/navigation_predictor/navigation_predictor.cc
@@ -108,9 +108,14 @@ is_same_host_scale_ + contains_image_scale_ + is_url_incremented_scale_ + source_engagement_score_scale_ + target_engagement_score_scale_ + area_rank_scale_), - is_low_end_device_(base::SysInfo::IsLowEndDevice()) { + is_low_end_device_(base::SysInfo::IsLowEndDevice()), + prefetch_url_score_threshold_(base::GetFieldTrialParamByFeatureAsInt( + blink::features::kRecordAnchorMetricsVisible, + "prefetch_url_score_threshold", + 0)) { DCHECK(browser_context_); DETACH_FROM_SEQUENCE(sequence_checker_); + DCHECK_LE(0, prefetch_url_score_threshold_); if (render_frame_host != GetMainFrame(render_frame_host)) return; @@ -702,15 +707,22 @@ if (source_is_default_search_engine_page_) return base::nullopt; - // Return the same-origin URL that has the highest navigation score. - for (const auto& navigation_score : sorted_navigation_scores) { - // Currently, only same origin URLs can be prefetched. - if (url::Origin::Create(navigation_score->url) != document_origin) - continue; - return navigation_score->url; + if (sorted_navigation_scores.empty()) + return base::nullopt; + + // Only the same origin URLs are eligible for prefetching. If the URL with + // the highest score is from a different origin, then we skip prefetching + // since same origin URLs are not likely to be clicked. + if (url::Origin::Create(sorted_navigation_scores[0]->url) != + document_origin) { + return base::nullopt; } - return base::nullopt; + // If the prediction score of the highest scoring URL is less than the + // threshold, then return. + if (sorted_navigation_scores[0]->score < prefetch_url_score_threshold_) + return base::nullopt; + return sorted_navigation_scores[0]->url; } void NavigationPredictor::RecordMetricsOnLoad(
diff --git a/chrome/browser/navigation_predictor/navigation_predictor.h b/chrome/browser/navigation_predictor/navigation_predictor.h index a1a9927..bfacf2d 100644 --- a/chrome/browser/navigation_predictor/navigation_predictor.h +++ b/chrome/browser/navigation_predictor/navigation_predictor.h
@@ -82,6 +82,7 @@ }; protected: + // URL that we decided to prefetch. base::Optional<GURL> prefetch_url_; private: @@ -183,6 +184,9 @@ // True if device is a low end device. const bool is_low_end_device_; + // Minimum score that a URL should have for it to be prefetched. + const int prefetch_url_score_threshold_; + // Timing of document loaded and last click. base::TimeTicks document_loaded_timing_; base::TimeTicks last_click_timing_;
diff --git a/chrome/browser/navigation_predictor/navigation_predictor_unittest.cc b/chrome/browser/navigation_predictor/navigation_predictor_unittest.cc index 6eecddc..0a08c2e 100644 --- a/chrome/browser/navigation_predictor/navigation_predictor_unittest.cc +++ b/chrome/browser/navigation_predictor/navigation_predictor_unittest.cc
@@ -5,8 +5,10 @@ #include "chrome/browser/navigation_predictor/navigation_predictor.h" #include <map> +#include <string> #include "base/run_loop.h" +#include "base/strings/string_number_conversions.h" #include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_feature_list.h" #include "chrome/test/base/chrome_render_view_host_test_harness.h" @@ -64,6 +66,7 @@ ~NavigationPredictorTest() override = default; void SetUp() override { + SetupFieldTrial(base::nullopt /* prefetch_url_score_threshold */); ChromeRenderViewHostTestHarness::SetUp(); predictor_service_helper_ = std::make_unique<TestNavigationPredictor>( mojo::MakeRequest(&predictor_service_), main_rfh()); @@ -93,9 +96,25 @@ return predictor_service_helper_->prefetch_url(); } - private: + protected: + void SetupFieldTrial(base::Optional<int> prefetch_url_score_threshold) { + const std::string kTrialName = "TrialFoo2"; + const std::string kGroupName = "GroupFoo2"; // Value not used + + std::map<std::string, std::string> params; + if (prefetch_url_score_threshold.has_value()) { + params["prefetch_url_score_threshold"] = + base::IntToString(prefetch_url_score_threshold.value()); + } + scoped_feature_list.InitAndEnableFeatureWithParameters( + blink::features::kRecordAnchorMetricsVisible, params); + } + blink::mojom::AnchorElementMetricsHostPtr predictor_service_; std::unique_ptr<TestNavigationPredictor> predictor_service_helper_; + + private: + base::test::ScopedFeatureList scoped_feature_list; }; } // namespace @@ -265,16 +284,17 @@ EXPECT_FALSE(prefetch_url().has_value()); } +// URL with highest prefetch score is from the same origin. Prefetch is done. TEST_F(NavigationPredictorTest, ActionTaken_SameOrigin_Prefetch) { const std::string source = "https://example.com"; const std::string same_origin_href_small = "https://example.com/small"; const std::string same_origin_href_large = "https://example.com/large"; - const std::string diff_origin_href_xlarge = "https://example2.com/xlarge"; + const std::string diff_origin_href_xsmall = "https://example2.com/xsmall"; std::vector<blink::mojom::AnchorElementMetricsPtr> metrics; metrics.push_back(CreateMetricsPtr(source, same_origin_href_large, 1)); metrics.push_back(CreateMetricsPtr(source, same_origin_href_small, 0.01)); - metrics.push_back(CreateMetricsPtr(source, diff_origin_href_xlarge, 1)); + metrics.push_back(CreateMetricsPtr(source, diff_origin_href_xsmall, 0.01)); base::HistogramTester histogram_tester; predictor_service()->ReportAnchorElementMetricsOnLoad(std::move(metrics)); @@ -297,6 +317,38 @@ NavigationPredictor::ActionAccuracy::kPrefetchActionClickToSameOrigin, 1); } +// URL with highest prefetch score is from a different origin. So, prefetch is +// not done. +TEST_F(NavigationPredictorTest, ActionTaken_SameOrigin_Prefetch_NotSameOrigin) { + const std::string source = "https://example.com"; + const std::string same_origin_href_small = "https://example.com/small"; + const std::string same_origin_href_large = "https://example.com/large"; + const std::string diff_origin_href_xlarge = "https://example2.com/xlarge"; + + std::vector<blink::mojom::AnchorElementMetricsPtr> metrics; + metrics.push_back(CreateMetricsPtr(source, same_origin_href_large, 1)); + metrics.push_back(CreateMetricsPtr(source, same_origin_href_small, 0.01)); + metrics.push_back(CreateMetricsPtr(source, diff_origin_href_xlarge, 10)); + + base::HistogramTester histogram_tester; + predictor_service()->ReportAnchorElementMetricsOnLoad(std::move(metrics)); + base::RunLoop().RunUntilIdle(); + + histogram_tester.ExpectUniqueSample( + "NavigationPredictor.OnNonDSE.ActionTaken", + NavigationPredictor::Action::kNone, 1); + EXPECT_FALSE(prefetch_url().has_value()); + + auto metrics_clicked = CreateMetricsPtr(source, same_origin_href_small, 0.01); + predictor_service()->ReportAnchorElementMetricsOnClick( + std::move(metrics_clicked)); + base::RunLoop().RunUntilIdle(); + + histogram_tester.ExpectUniqueSample( + "NavigationPredictor.OnNonDSE.AccuracyActionTaken", + NavigationPredictor::ActionAccuracy::kNoActionTakenClickHappened, 1); +} + TEST_F(NavigationPredictorTest, ActionTaken_SameOrigin_DifferentScheme_Prefetch) { const std::string source = "https://example.com"; @@ -316,3 +368,49 @@ NavigationPredictor::Action::kNone, 1); EXPECT_FALSE(prefetch_url().has_value()); } + +// Framework for testing cases where prefetch is effectively +// disabled by setting |prefetch_url_score_threshold| to too high. +class NavigationPredictorPrefetchDisabledTest : public NavigationPredictorTest { + public: + void SetUp() override { + SetupFieldTrial(101 /* prefetch_url_score_threshold */); + + ChromeRenderViewHostTestHarness::SetUp(); + predictor_service_helper_ = std::make_unique<TestNavigationPredictor>( + mojo::MakeRequest(&predictor_service_), main_rfh()); + } +}; + +TEST_F(NavigationPredictorPrefetchDisabledTest, + ActionTaken_SameOrigin_Prefetch_BelowThreshold) { + const std::string source = "https://example.com"; + const std::string same_origin_href_small = "https://example.com/small"; + const std::string same_origin_href_large = "https://example.com/large"; + const std::string diff_origin_href_xsmall = "https://example2.com/xsmall"; + + std::vector<blink::mojom::AnchorElementMetricsPtr> metrics; + metrics.push_back(CreateMetricsPtr(source, same_origin_href_large, 1)); + metrics.push_back(CreateMetricsPtr(source, same_origin_href_small, 0.01)); + metrics.push_back(CreateMetricsPtr(source, diff_origin_href_xsmall, 0.0001)); + + base::HistogramTester histogram_tester; + predictor_service()->ReportAnchorElementMetricsOnLoad(std::move(metrics)); + base::RunLoop().RunUntilIdle(); + + histogram_tester.ExpectUniqueSample( + "NavigationPredictor.OnNonDSE.ActionTaken", + NavigationPredictor::Action::kNone, 1); + EXPECT_FALSE(prefetch_url().has_value()); + + auto metrics_clicked = CreateMetricsPtr(source, same_origin_href_small, 0.01); + predictor_service()->ReportAnchorElementMetricsOnClick( + std::move(metrics_clicked)); + base::RunLoop().RunUntilIdle(); + + histogram_tester.ExpectTotalCount( + "AnchorElementMetrics.Clicked.HrefEngagementScore2", 1); + histogram_tester.ExpectUniqueSample( + "NavigationPredictor.OnNonDSE.AccuracyActionTaken", + NavigationPredictor::ActionAccuracy::kNoActionTakenClickHappened, 1); +}
diff --git a/chrome/browser/policy/browser_dm_token_storage_mac.mm b/chrome/browser/policy/browser_dm_token_storage_mac.mm index 56fd4f97..9cf4945 100644 --- a/chrome/browser/policy/browser_dm_token_storage_mac.mm +++ b/chrome/browser/policy/browser_dm_token_storage_mac.mm
@@ -17,6 +17,7 @@ #include "base/mac/scoped_cftyperef.h" #include "base/mac/scoped_ioobject.h" #include "base/no_destructor.h" +#include "base/optional.h" #include "base/path_service.h" #include "base/sha1.h" #include "base/strings/string16.h" @@ -47,6 +48,18 @@ const char kEnrollmentTokenOldFilePath[] = FILE_PATH_LITERAL( "/Library/Google/Chrome/MachineLevelUserCloudPolicyEnrollmentToken"); +// Enrollment Mandatory Option +const CFStringRef kEnrollmentMandatoryOptionPolicyName = + CFSTR("CloudManagementEnrollmentMandatory"); +const char kEnrollmentOptionsFilePath[] = FILE_PATH_LITERAL( + "/Library/Google/Chrome/CloudManagementEnrollmentOptions"); +const char kEnrollmentMandatoryOption[] = "Mandatory"; + +// Explicitly access the "com.google.Chrome" bundle ID, no matter what this +// app's bundle ID actually is. All channels of Chrome should obey the same +// policies. +const CFStringRef kBundleId = CFSTR("com.google.Chrome"); + bool GetDmTokenFilePath(base::FilePath* token_file_path, const std::string& client_id, bool create_dir) { @@ -80,31 +93,21 @@ // Get the enrollment token from policy file: /Library/com.google.Chrome.plist. // Return true if policy is set, otherwise false. bool GetEnrollmentTokenFromPolicy(std::string* enrollment_token) { -// Since the configuration management infrastructure is not initialized when -// this code runs, read the policy preference directly. -#if defined(GOOGLE_CHROME_BUILD) - // Explicitly access the "com.google.Chrome" bundle ID, no matter what this - // app's bundle ID actually is. All channels of Chrome should obey the same - // policies. - CFStringRef bundle_id = CFSTR("com.google.Chrome"); -#else - base::ScopedCFTypeRef<CFStringRef> bundle_id( - base::SysUTF8ToCFStringRef(base::mac::BaseBundleID())); -#endif - + // Since the configuration management infrastructure is not initialized when + // this code runs, read the policy preference directly. base::ScopedCFTypeRef<CFPropertyListRef> value( - CFPreferencesCopyAppValue(kEnrollmentTokenPolicyName, bundle_id)); + CFPreferencesCopyAppValue(kEnrollmentTokenPolicyName, kBundleId)); // Read the enrollment token from the new location. If that fails, try the old // location (which will be deprecated soon). If that also fails, bail as there // is no token set. if (!value || - !CFPreferencesAppValueIsForced(kEnrollmentTokenPolicyName, bundle_id)) { + !CFPreferencesAppValueIsForced(kEnrollmentTokenPolicyName, kBundleId)) { // TODO(crbug.com/907589) : Remove once no longer in use. value.reset( - CFPreferencesCopyAppValue(kEnrollmentTokenOldPolicyName, bundle_id)); + CFPreferencesCopyAppValue(kEnrollmentTokenOldPolicyName, kBundleId)); if (!value || !CFPreferencesAppValueIsForced(kEnrollmentTokenOldPolicyName, - bundle_id)) { + kBundleId)) { return false; } } @@ -133,6 +136,31 @@ return true; } +base::Optional<bool> IsEnrollmentMandatoryByPolicy() { + base::ScopedCFTypeRef<CFPropertyListRef> value(CFPreferencesCopyAppValue( + kEnrollmentMandatoryOptionPolicyName, kBundleId)); + + if (!value || !CFPreferencesAppValueIsForced( + kEnrollmentMandatoryOptionPolicyName, kBundleId)) { + return base::Optional<bool>(); + } + + CFBooleanRef value_bool = base::mac::CFCast<CFBooleanRef>(value); + if (!value_bool) + return base::Optional<bool>(); + return value_bool == kCFBooleanTrue; +} + +base::Optional<bool> IsEnrollmentMandatoryByFile() { + std::string options; + if (!base::ReadFileToString(base::FilePath(kEnrollmentOptionsFilePath), + &options)) { + return base::Optional<bool>(); + } + return base::TrimWhitespaceASCII(options, base::TRIM_ALL).as_string() == + kEnrollmentMandatoryOption; +} + } // namespace // static @@ -197,8 +225,11 @@ } bool BrowserDMTokenStorageMac::InitEnrollmentErrorOption() { - // TODO(crbug/904983): Load the policy value for this option. - return true; + base::Optional<bool> is_mandatory = IsEnrollmentMandatoryByPolicy(); + if (is_mandatory) + return is_mandatory.value(); + + return IsEnrollmentMandatoryByFile().value_or(false); } void BrowserDMTokenStorageMac::SaveDMToken(const std::string& token) {
diff --git a/chrome/browser/prerender/prerender_browsertest.cc b/chrome/browser/prerender/prerender_browsertest.cc index e8a4ad01a..6ecd46e5 100644 --- a/chrome/browser/prerender/prerender_browsertest.cc +++ b/chrome/browser/prerender/prerender_browsertest.cc
@@ -3466,20 +3466,20 @@ // When instantiated, mocks out the global text-to-speech engine with something // that emulates speaking any phrase for the duration of 0ms. -class TtsPlatformMock : public TtsPlatformImpl { +class TtsPlatformMock : public TtsPlatform { public: TtsPlatformMock() : speaking_requested_(false) { - TtsControllerDelegateImpl::GetInstance()->SetPlatformImpl(this); + TtsControllerDelegateImpl::GetInstance()->SetTtsPlatform(this); } - ~TtsPlatformMock() override { - TtsControllerDelegateImpl::GetInstance()->SetPlatformImpl( - TtsPlatformImpl::GetInstance()); + virtual ~TtsPlatformMock() { + TtsControllerDelegateImpl::GetInstance()->SetTtsPlatform( + TtsPlatform::GetInstance()); } bool speaking_requested() { return speaking_requested_; } - // TtsPlatformImpl: + // TtsPlatform: bool PlatformImplAvailable() override { return true; } @@ -3512,6 +3512,21 @@ void Resume() override {} + bool LoadBuiltInTtsExtension( + content::BrowserContext* browser_context) override { + return false; + } + + void WillSpeakUtteranceWithVoice( + const content::Utterance* utterance, + const content::VoiceData& voice_data) override {} + + void SetError(const std::string& error) override {} + + std::string GetError() override { return std::string(); } + + void ClearError() override {} + private: bool speaking_requested_; };
diff --git a/chrome/browser/push_messaging/push_messaging_browsertest.cc b/chrome/browser/push_messaging/push_messaging_browsertest.cc index 3945233..660b312 100644 --- a/chrome/browser/push_messaging/push_messaging_browsertest.cc +++ b/chrome/browser/push_messaging/push_messaging_browsertest.cc
@@ -1652,13 +1652,7 @@ EXPECT_EQ("permission status - denied", script_result); } -// TODO(peter): Flaky on Win buildbots. https://crbug.com/838759 -#if defined(OS_WIN) -#define MAYBE_UnsubscribeSuccess DISABLED_UnsubscribeSuccess -#else -#define MAYBE_UnsubscribeSuccess UnsubscribeSucces -#endif -IN_PROC_BROWSER_TEST_F(PushMessagingBrowserTest, MAYBE_UnsubscribeSuccess) { +IN_PROC_BROWSER_TEST_F(PushMessagingBrowserTest, UnsubscribeSuccess) { std::string script_result; std::string token1;
diff --git a/chrome/browser/resources/md_history/history_item.js b/chrome/browser/resources/md_history/history_item.js index 78c71cd..f4af1cd 100644 --- a/chrome/browser/resources/md_history/history_item.js +++ b/chrome/browser/resources/md_history/history_item.js
@@ -160,16 +160,26 @@ }, /** + * @param {!Event} e The focus event * @private */ - onFocus_: function() { + onFocus_: function(e) { // Don't change the focus while the mouse is down, as it prevents text // selection. Not changing focus here is acceptable because the checkbox // will be focused in onItemClick_() anyway. if (this.mouseDown_) return; - if (this.lastFocused && !this.blurred_) + // If focus is being restored from outside the item and the event is fired + // by the list item itself, focus the first control so that the user can + // tab through all the controls. When the user shift-tabs back to the row, + // or focus is restored to the row from a dropdown on the last item, the + // last child item will be focused before the row itself. Since this is + // the desired behavior, do not shift focus to the first item in these + // cases. + const restoreFocusToFirst = this.blurred_ && e.composedPath()[0] === this; + + if (this.lastFocused && !restoreFocusToFirst) this.row_.getEquivalentElement(this.lastFocused).focus(); else this.row_.getFirstFocusable().focus();
diff --git a/chrome/browser/resources/omnibox/omnibox_output.js b/chrome/browser/resources/omnibox/omnibox_output.js index d77b4266..9d6123c8 100644 --- a/chrome/browser/resources/omnibox/omnibox_output.js +++ b/chrome/browser/resources/omnibox/omnibox_output.js
@@ -469,10 +469,15 @@ OutputMatch.displayedProperties(showDetails) .map(property => { const value = this.properties[property.propertyName]; - if (typeof value === 'object') - return OutputMatch.renderJsonProperty_(value); if (typeof value === 'boolean') return OutputMatch.renderBooleanProperty_(value); + if (typeof value === 'object') { + // We check if the first element has key and value properties. + if (value && value[0] && value[0].key && value[0].value) + return OutputMatch.renderKeyValueTuples_(value); + else + return OutputMatch.renderJsonProperty_(value); + } const LINK_REGEX = /^(http|https|ftp|chrome|file):\/\//; if (LINK_REGEX.test(value)) return OutputMatch.renderLinkProperty_(value); @@ -544,6 +549,21 @@ /** * @private + * @param {Array<{key: string, value: string}>} propertyValue + * @return {Element} + */ + static renderKeyValueTuples_(propertyValue) { + const cell = document.createElement('td'); + const pre = document.createElement('pre'); + const text = propertyValue.reduce( + (prev, current) => `${prev}${current.key}: ${current.value}\n`, ''); + pre.textContent = text; + cell.appendChild(pre); + return cell; + } + + /** + * @private * @param {boolean} showDetails * @param {boolean} showAdditionalHeader * @return {!Element}
diff --git a/chrome/browser/resources/print_preview/data/destination_store.js b/chrome/browser/resources/print_preview/data/destination_store.js index 3c05f722..f2baeaf 100644 --- a/chrome/browser/resources/print_preview/data/destination_store.js +++ b/chrome/browser/resources/print_preview/data/destination_store.js
@@ -1170,6 +1170,7 @@ this, DestinationStore.EventType.DESTINATION_SEARCH_DONE); if (type === print_preview.PrinterType.EXTENSION_PRINTER) this.endExtensionPrinterSearch_(); + this.sendNoPrinterEventIfNeeded_(); } /** @@ -1270,6 +1271,23 @@ } cr.dispatchSimpleEvent( this, DestinationStore.EventType.DESTINATION_SEARCH_DONE); + this.sendNoPrinterEventIfNeeded_(); + } + + /** + * Checks if the search is done and no printers are found. If so, fires a + * DestinationStore.EventType.NO_DESTINATIONS_FOUND event. + * @private + */ + sendNoPrinterEventIfNeeded_() { + if (this.isPrintDestinationSearchInProgress || + !this.selectFirstDestination_) { + return; + } + + this.selectFirstDestination_ = false; + cr.dispatchSimpleEvent( + this, DestinationStore.EventType.NO_DESTINATIONS_FOUND); } /** @@ -1397,6 +1415,8 @@ 'print_preview.DestinationStore.PROVISIONAL_DESTINATION_RESOLVED', CACHED_SELECTED_DESTINATION_INFO_READY: 'print_preview.DestinationStore.CACHED_SELECTED_DESTINATION_INFO_READY', + NO_DESTINATIONS_FOUND: + 'print_preview.DestinationStore.NO_DESTINATIONS_FOUND', SELECTED_DESTINATION_CAPABILITIES_READY: 'print_preview.DestinationStore' + '.SELECTED_DESTINATION_CAPABILITIES_READY', SELECTED_DESTINATION_INVALID:
diff --git a/chrome/browser/resources/print_preview/new/app.js b/chrome/browser/resources/print_preview/new/app.js index 1ba5afb..e8859d1 100644 --- a/chrome/browser/resources/print_preview/new/app.js +++ b/chrome/browser/resources/print_preview/new/app.js
@@ -194,6 +194,12 @@ this.destinationStore_, print_preview.DestinationStore.EventType.DESTINATION_SELECT, this.onDestinationSelect_.bind(this)); + // <if expr="chromeos"> + this.tracker_.add( + this.destinationStore_, + print_preview.DestinationStore.EventType.NO_DESTINATIONS_FOUND, + this.onNoDestinationsFound_.bind(this)); + // </if> this.tracker_.add( this.destinationStore_, print_preview.DestinationStore.EventType @@ -656,6 +662,15 @@ return this.settingsExpandedByUser_ || !this.shouldShowMoreSettings_; }, + // <if expr="chromeos"> + /** @private */ + onNoDestinationsFound_: function() { + this.$.state.transitTo(print_preview_new.State.INVALID_PRINTER); + this.$.previewArea.setNoDestinationsFound(); + this.$.destinationSettings.noDestinationsFound = true; + }, + // </if> + /** @private */ close_: function() { this.$.state.transitTo(print_preview_new.State.CLOSING);
diff --git a/chrome/browser/resources/print_preview/new/destination_settings.html b/chrome/browser/resources/print_preview/new/destination_settings.html index 8200b9db..f26075f9 100644 --- a/chrome/browser/resources/print_preview/new/destination_settings.html +++ b/chrome/browser/resources/print_preview/new/destination_settings.html
@@ -2,6 +2,7 @@ <link rel="import" href="chrome://resources/cr_elements/cr_lazy_render/cr_lazy_render.html"> <link rel="import" href="chrome://resources/cr_elements/hidden_style_css.html"> +<link rel="import" href="chrome://resources/cr_elements/icons.html"> <link rel="import" href="chrome://resources/cr_elements/paper_button_style_css.html"> <link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> <link rel="import" href="chrome://resources/html/event_tracker.html"> @@ -34,13 +35,15 @@ } .destination-settings-box, + .no-destinations-display, .throbber-container { align-items: center; display: flex; overflow: hidden; } - .destination-settings-box iron-icon { + .destination-settings-box iron-icon, + .no-destinations-display iron-icon { fill: var(--google-grey-600); flex: 0; margin-inline-end: 8px; @@ -63,7 +66,8 @@ } .destination-info-wrapper > div, - .destination-throbber-name { + .destination-throbber-name, + .no-destinations-message { flex: 1; overflow: hidden; text-overflow: ellipsis; @@ -77,10 +81,18 @@ <print-preview-settings-section> <span slot="title">$i18n{destinationLabel}</span> <div slot="controls"> - <div class="throbber-container" hidden="[[!loadingDestination_]]"> + <div class="throbber-container" + hidden="[[!shouldShowSpinner_( + loadingDestination_, noDestinationsFound)]]"> <div class="throbber"></div> <div class="destination-throbber-name"></div> </div> + <div class="no-destinations-display" hidden="[[!noDestinationsFound]]"> + <iron-icon icon="cr:error"></iron-icon> + <div class="no-destinations-message"> + $i18n{noDestinationsMessage} + </div> + </div> <div class="destination-settings-box" hidden="[[loadingDestination_]]"> <iron-icon icon$="[[destination.icon]]" hidden="[[!destination]]"> </iron-icon> @@ -100,7 +112,7 @@ <div slot="controls"> <paper-button disabled$="[[shouldDisableButton_(destinationStore, disabled, - state)]]" + state, noDestinationsFound)]]" on-click="onChangeButtonClick_"> $i18n{changeDestination} </paper-button>
diff --git a/chrome/browser/resources/print_preview/new/destination_settings.js b/chrome/browser/resources/print_preview/new/destination_settings.js index 0fb6bd5..25c2248 100644 --- a/chrome/browser/resources/print_preview/new/destination_settings.js +++ b/chrome/browser/resources/print_preview/new/destination_settings.js
@@ -31,6 +31,11 @@ /** @type {!print_preview_new.State} */ state: Number, + noDestinationsFound: { + type: Boolean, + value: false, + }, + /** @private {boolean} */ showCloudPrintPromo_: { type: Boolean, @@ -58,8 +63,8 @@ * @private */ shouldDisableButton_: function() { - return !this.destinationStore || - (this.disabled && this.state != print_preview_new.State.NOT_READY && + return !this.destinationStore || this.noDestinationsFound || + (this.disabled && this.state != print_preview_new.State.INVALID_PRINTER); }, @@ -69,6 +74,14 @@ }, /** + * @return {boolean} Whether to show the spinner. + * @private + */ + shouldShowSpinner_: function() { + return this.loadingDestination_ && !this.noDestinationsFound; + }, + + /** * @return {string} The connection status text to display. * @private */
diff --git a/chrome/browser/resources/print_preview/new/preview_area.js b/chrome/browser/resources/print_preview/new/preview_area.js index 8a53460..9b9d0ec2 100644 --- a/chrome/browser/resources/print_preview/new/preview_area.js +++ b/chrome/browser/resources/print_preview/new/preview_area.js
@@ -22,6 +22,9 @@ INVALID_SETTINGS: 'invalid-settings', PREVIEW_FAILED: 'preview-failed', UNSUPPORTED_CLOUD_PRINTER: 'unsupported-cloud-printer', + // <if expr="chromeos"> + NO_DESTINATIONS_FOUND: 'no-destinations-found', + // </if> }; Polymer({ @@ -260,15 +263,15 @@ currentMessage_: function() { switch (this.previewState) { case print_preview_new.PreviewAreaState.NO_PLUGIN: - return this.i18nAdvanced('noPlugin'); + return this.i18n('noPlugin'); case print_preview_new.PreviewAreaState.LOADING: - return this.i18nAdvanced('loading'); + return this.i18n('loading'); case print_preview_new.PreviewAreaState.DISPLAY_PREVIEW: return ''; // <if expr="is_macosx"> case print_preview_new.PreviewAreaState.OPEN_IN_PREVIEW_LOADING: case print_preview_new.PreviewAreaState.OPEN_IN_PREVIEW_LOADED: - return this.i18nAdvanced('openingPDFInPreview'); + return this.i18n('openingPDFInPreview'); // </if> case print_preview_new.PreviewAreaState.INVALID_SETTINGS: return this.i18nAdvanced('invalidPrinterSettings', { @@ -276,12 +279,16 @@ tags: ['BR'], }); case print_preview_new.PreviewAreaState.PREVIEW_FAILED: - return this.i18nAdvanced('previewFailed'); + return this.i18n('previewFailed'); case print_preview_new.PreviewAreaState.UNSUPPORTED_CLOUD_PRINTER: return this.i18nAdvanced('unsupportedCloudPrinter', { substitutions: [], tags: ['BR'], }); + // <if expr="chromeos"> + case print_preview_new.PreviewAreaState.NO_DESTINATIONS_FOUND: + return this.i18n('noDestinationsMessage'); + // </if> default: return ''; } @@ -317,6 +324,13 @@ } }, + // <if expr="chromeos"> + setNoDestinationsFound: function() { + this.previewState = + print_preview_new.PreviewAreaState.NO_DESTINATIONS_FOUND; + }, + // </if> + // <if expr="is_macosx"> /** Set the preview state to display the "opening in preview" message. */ setOpeningPdfInPreview: function() {
diff --git a/chrome/browser/resources/settings/focus_row_behavior.js b/chrome/browser/resources/settings/focus_row_behavior.js index 22afc7c..94d9d73 100644 --- a/chrome/browser/resources/settings/focus_row_behavior.js +++ b/chrome/browser/resources/settings/focus_row_behavior.js
@@ -221,15 +221,24 @@ /** * This function gets called when the row itself receives the focus event. + * @param {!Event} e The focus event * @private */ - onFocus_: function() { + onFocus_: function(e) { if (this.mouseFocused_) { this.mouseFocused_ = false; // Consume and reset flag. return; } - if (this.lastFocused && !this.blurred_) { + // If focus is being restored from outside the item and the event is fired + // by the list item itself, focus the first control so that the user can tab + // through all the controls. When the user shift-tabs back to the row, or + // focus is restored to the row from a dropdown on the last item, the last + // child item will be focused before the row itself. Since this is the + // desired behavior, do not shift focus to the first item in these cases. + const restoreFocusToFirst = this.blurred_ && e.composedPath()[0] === this; + + if (this.lastFocused && !restoreFocusToFirst) { this.row_.getEquivalentElement(this.lastFocused).focus(); } else { const firstFocusable = assert(this.firstControl_);
diff --git "a/chrome/browser/speech/\043tts_win.cc\043" "b/chrome/browser/speech/\043tts_win.cc\043" new file mode 100644 index 0000000..2f5a820 --- /dev/null +++ "b/chrome/browser/speech/\043tts_win.cc\043"
@@ -0,0 +1,335 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <math.h> +#include <objbase.h> +#include <sapi.h> +#include <stdint.h> +#include <wrl/client.h> + +#include "base/macros.h" +#include "base/memory/singleton.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/string_piece.h" +#include "base/strings/utf_string_conversions.h" +#include "base/values.h" +#include "base/win/scoped_co_mem.h" +#include "base/win/sphelper.h" +#include "chrome/browser/speech/tts_platform_impl.h" +#include "content/public/browser/tts_controller.h" + +namespace { + +// ISpObjectToken key and value names. +const wchar_t kAttributesKey[] = L"Attributes"; +const wchar_t kLanguageValue[] = L"Language"; + +} // anonymous namespace. + +// TODO(katie): Move to content/browser/speech. +class TtsPlatformImplWin : public TtsPlatformImpl { + public: + bool PlatformImplAvailable() override { + return true; + } + + bool Speak(int utterance_id, + const std::string& utterance, + const std::string& lang, + const content::VoiceData& voice, + const content::UtteranceContinuousParameters& params) override; + + bool StopSpeaking() override; + + void Pause() override; + + void Resume() override; + + bool IsSpeaking() override; + + void GetVoices(std::vector<content::VoiceData>* out_voices) override; + + // Get the single instance of this class. + static TtsPlatformImplWin* GetInstance(); + + static void __stdcall SpeechEventCallback(WPARAM w_param, LPARAM l_param); + + private: + TtsPlatformImplWin(); + ~TtsPlatformImplWin() override {} + + void OnSpeechEvent(); + + void SetVoiceFromName(const std::string& name); + + Microsoft::WRL::ComPtr<ISpVoice> speech_synthesizer_; + + // These apply to the current utterance only. + std::wstring utterance_; + int utterance_id_; + int prefix_len_; + ULONG stream_number_; + int char_position_; + bool paused_; + std::string last_voice_name_; + + friend struct base::DefaultSingletonTraits<TtsPlatformImplWin>; + + DISALLOW_COPY_AND_ASSIGN(TtsPlatformImplWin); +}; + +// static +TtsPlatform* TtsPlatform::GetInstance() { + return TtsPlatformImplWin::GetInstance(); +} + +bool TtsPlatformImplWin::Speak( + int utterance_id, + const std::string& src_utterance, + const std::string& lang, + const content::VoiceData& voice, + const content::UtteranceContinuousParameters& params) { + std::wstring prefix; + std::wstring suffix; + + if (!speech_synthesizer_.Get()) + return false; + + SetVoiceFromName(voice.name); + + if (params.rate >= 0.0) { + // Map our multiplicative range of 0.1x to 10.0x onto Microsoft's + // linear range of -10 to 10: + // 0.1 -> -10 + // 1.0 -> 0 + // 10.0 -> 10 + speech_synthesizer_->SetRate(static_cast<int32_t>(10 * log10(params.rate))); + } + + if (params.pitch >= 0.0) { + // The TTS api allows a range of -10 to 10 for speech pitch. + // TODO(dtseng): cleanup if we ever use any other properties that + // require xml. + std::wstring pitch_value = + base::IntToString16(static_cast<int>(params.pitch * 10 - 10)); + prefix = L"<pitch absmiddle=\"" + pitch_value + L"\">"; + suffix = L"</pitch>"; + } + + if (params.volume >= 0.0) { + // The TTS api allows a range of 0 to 100 for speech volume. + speech_synthesizer_->SetVolume(static_cast<uint16_t>(params.volume * 100)); + } + + // TODO(dmazzoni): convert SSML to SAPI xml. http://crbug.com/88072 + + utterance_ = base::UTF8ToWide(src_utterance); + utterance_id_ = utterance_id; + char_position_ = 0; + std::wstring merged_utterance = prefix + utterance_ + suffix; + prefix_len_ = prefix.size(); + + HRESULT result = speech_synthesizer_->Speak( + merged_utterance.c_str(), + SPF_ASYNC, + &stream_number_); + return (result == S_OK); +} + +bool TtsPlatformImplWin::StopSpeaking() { + if (speech_synthesizer_.Get()) { + // Clear the stream number so that any further events relating to this + // utterance are ignored. + stream_number_ = 0; + + if (IsSpeaking()) { + // Stop speech by speaking the empty string with the purge flag. + speech_synthesizer_->Speak(L"", SPF_ASYNC | SPF_PURGEBEFORESPEAK, NULL); + } + if (paused_) { + speech_synthesizer_->Resume(); + paused_ = false; + } + } + return true; +} + +void TtsPlatformImplWin::Pause() { + if (speech_synthesizer_.Get() && utterance_id_ && !paused_) { + speech_synthesizer_->Pause(); + paused_ = true; + content::TtsController::GetInstance()->OnTtsEvent( + utterance_id_, content::TTS_EVENT_PAUSE, char_position_, ""); + } +} + +void TtsPlatformImplWin::Resume() { + if (speech_synthesizer_.Get() && utterance_id_ && paused_) { + speech_synthesizer_->Resume(); + paused_ = false; + content::TtsController::GetInstance()->OnTtsEvent( + utterance_id_, content::TTS_EVENT_RESUME, char_position_, ""); + } +} + +bool TtsPlatformImplWin::IsSpeaking() { + if (speech_synthesizer_.Get()) { + SPVOICESTATUS status; + HRESULT result = speech_synthesizer_->GetStatus(&status, NULL); + if (result == S_OK) { + if (status.dwRunningState == 0 || // 0 == waiting to speak + status.dwRunningState == SPRS_IS_SPEAKING) { + return true; + } + } + } + return false; +} + +void TtsPlatformImplWin::GetVoices( + std::vector<content::VoiceData>* out_voices) { + Microsoft::WRL::ComPtr<IEnumSpObjectTokens> voice_tokens; + unsigned long voice_count; + if (S_OK != + SpEnumTokens(SPCAT_VOICES, NULL, NULL, voice_tokens.GetAddressOf())) + return; + if (S_OK != voice_tokens->GetCount(&voice_count)) + return; + + for (unsigned i = 0; i < voice_count; i++) { + content::VoiceData voice; + + Microsoft::WRL::ComPtr<ISpObjectToken> voice_token; + if (S_OK != voice_tokens->Next(1, voice_token.GetAddressOf(), NULL)) + return; + + base::win::ScopedCoMem<WCHAR> description; + if (S_OK != SpGetDescription(voice_token.Get(), &description)) + continue; + voice.name = base::WideToUTF8(description.get()); + + Microsoft::WRL::ComPtr<ISpDataKey> attributes; + if (S_OK != voice_token->OpenKey(kAttributesKey, attributes.GetAddressOf())) + continue; + + base::win::ScopedCoMem<WCHAR> language; + if (S_OK == attributes->GetStringValue(kLanguageValue, &language)) { + int lcid_value; + base::HexStringToInt(base::WideToUTF8(language.get()), &lcid_value); + LCID lcid = MAKELCID(lcid_value, SORT_DEFAULT); + WCHAR locale_name[LOCALE_NAME_MAX_LENGTH] = {0}; + LCIDToLocaleName(lcid, locale_name, LOCALE_NAME_MAX_LENGTH, 0); + voice.lang = base::WideToUTF8(locale_name); + } + + voice.native = true; + voice.events.insert(content::TTS_EVENT_START); + voice.events.insert(content::TTS_EVENT_END); + voice.events.insert(content::TTS_EVENT_MARKER); + voice.events.insert(content::TTS_EVENT_WORD); + voice.events.insert(content::TTS_EVENT_SENTENCE); + voice.events.insert(content::TTS_EVENT_PAUSE); + voice.events.insert(content::TTS_EVENT_RESUME); + out_voices->push_back(voice); + } +} + +void TtsPlatformImplWin::OnSpeechEvent() { + content::TtsController* controller = content::TtsController::GetInstance(); + SPEVENT event; + while (S_OK == speech_synthesizer_->GetEvents(1, &event, NULL)) { + if (event.ulStreamNum != stream_number_) + continue; + + switch (event.eEventId) { + case SPEI_START_INPUT_STREAM: + controller->OnTtsEvent(utterance_id_, content::TTS_EVENT_START, 0, + std::string()); + break; + case SPEI_END_INPUT_STREAM: + char_position_ = utterance_.size(); + controller->OnTtsEvent(utterance_id_, content::TTS_EVENT_END, + char_position_, std::string()); + break; + case SPEI_TTS_BOOKMARK: + controller->OnTtsEvent(utterance_id_, content::TTS_EVENT_MARKER, + char_position_, std::string()); + break; + case SPEI_WORD_BOUNDARY: + char_position_ = static_cast<ULONG>(event.lParam) - prefix_len_; + controller->OnTtsEvent(utterance_id_, content::TTS_EVENT_WORD, + char_position_, std::string()); + break; + case SPEI_SENTENCE_BOUNDARY: + char_position_ = static_cast<ULONG>(event.lParam) - prefix_len_; + controller->OnTtsEvent(utterance_id_, content::TTS_EVENT_SENTENCE, + char_position_, std::string()); + break; + default: + break; + } + } +} + +void TtsPlatformImplWin::SetVoiceFromName(const std::string& name) { + if (name.empty() || name == last_voice_name_) + return; + + last_voice_name_ = name; + + Microsoft::WRL::ComPtr<IEnumSpObjectTokens> voice_tokens; + unsigned long voice_count; + if (S_OK != + SpEnumTokens(SPCAT_VOICES, NULL, NULL, voice_tokens.GetAddressOf())) + return; + if (S_OK != voice_tokens->GetCount(&voice_count)) + return; + + for (unsigned i = 0; i < voice_count; i++) { + Microsoft::WRL::ComPtr<ISpObjectToken> voice_token; + if (S_OK != voice_tokens->Next(1, voice_token.GetAddressOf(), NULL)) + return; + + base::win::ScopedCoMem<WCHAR> description; + if (S_OK != SpGetDescription(voice_token.Get(), &description)) + continue; + if (name == base::WideToUTF8(description.get())) { + speech_synthesizer_->SetVoice(voice_token.Get()); + break; + } + } +} + +TtsPlatformImplWin::TtsPlatformImplWin() + : utterance_id_(0), + prefix_len_(0), + stream_number_(0), + char_position_(0), + paused_(false) { + ::CoCreateInstance(CLSID_SpVoice, nullptr, CLSCTX_ALL, + IID_PPV_ARGS(&speech_synthesizer_)); + if (speech_synthesizer_.Get()) { + ULONGLONG event_mask = + SPFEI(SPEI_START_INPUT_STREAM) | + SPFEI(SPEI_TTS_BOOKMARK) | + SPFEI(SPEI_WORD_BOUNDARY) | + SPFEI(SPEI_SENTENCE_BOUNDARY) | + SPFEI(SPEI_END_INPUT_STREAM); + speech_synthesizer_->SetInterest(event_mask, event_mask); + speech_synthesizer_->SetNotifyCallbackFunction( + TtsPlatformImplWin::SpeechEventCallback, 0, 0); + } +} + +// static +TtsPlatformImplWin* TtsPlatformImplWin::GetInstance() { + return base::Singleton<TtsPlatformImplWin, + base::LeakySingletonTraits<TtsPlatformImplWin>>::get(); +} + +// static +void TtsPlatformImplWin::SpeechEventCallback( + WPARAM w_param, LPARAM l_param) { + GetInstance()->OnSpeechEvent(); +}
diff --git a/chrome/browser/speech/extension_api/tts_extension_apitest.cc b/chrome/browser/speech/extension_api/tts_extension_apitest.cc index ecbf97d..9caf91c 100644 --- a/chrome/browser/speech/extension_api/tts_extension_apitest.cc +++ b/chrome/browser/speech/extension_api/tts_extension_apitest.cc
@@ -48,7 +48,7 @@ namespace extensions { -class MockTtsPlatformImpl : public TtsPlatformImpl { +class MockTtsPlatformImpl : public TtsPlatform { public: MockTtsPlatformImpl() : should_fake_get_voices_(false), @@ -56,6 +56,21 @@ bool PlatformImplAvailable() override { return true; } + void WillSpeakUtteranceWithVoice( + const content::Utterance* utterance, + const content::VoiceData& voice_data) override {} + + bool LoadBuiltInTtsExtension( + content::BrowserContext* browser_context) override { + return false; + } + + void ClearError() override { error_ = ""; } + + void SetError(const std::string& error) override { error_ = error; } + + std::string GetError() override { return error_; } + MOCK_METHOD5(Speak, bool(int utterance_id, const std::string& utterance, @@ -87,9 +102,7 @@ void set_should_fake_get_voices(bool val) { should_fake_get_voices_ = val; } - void SetErrorToEpicFail() { - set_error("epic fail"); - } + void SetErrorToEpicFail() { SetError("epic fail"); } void SendEndEventOnSavedUtteranceId() { base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( @@ -166,6 +179,7 @@ private: bool should_fake_get_voices_; + std::string error_; base::WeakPtrFactory<MockTtsPlatformImpl> ptr_factory_; }; @@ -215,7 +229,7 @@ public: void SetUpInProcessBrowserTestFixture() override { ExtensionApiTest::SetUpInProcessBrowserTestFixture(); - TtsControllerDelegateImpl::GetInstance()->SetPlatformImpl( + TtsControllerDelegateImpl::GetInstance()->SetTtsPlatform( &mock_platform_impl_); }
diff --git a/chrome/browser/speech/tts_android.cc b/chrome/browser/speech/tts_android.cc index e801e90a..04ffb344 100644 --- a/chrome/browser/speech/tts_android.cc +++ b/chrome/browser/speech/tts_android.cc
@@ -17,7 +17,7 @@ using base::android::JavaParamRef; // static -TtsPlatformImpl* TtsPlatformImpl::GetInstance() { +TtsPlatform* TtsPlatform::GetInstance() { return TtsPlatformImplAndroid::GetInstance(); }
diff --git a/chrome/browser/speech/tts_android.h b/chrome/browser/speech/tts_android.h index cec3838..81e9368 100644 --- a/chrome/browser/speech/tts_android.h +++ b/chrome/browser/speech/tts_android.h
@@ -7,8 +7,9 @@ #include "base/android/scoped_java_ref.h" #include "base/macros.h" -#include "chrome/browser/speech/tts_platform.h" +#include "chrome/browser/speech/tts_platform_impl.h" +// TODO(katie): Move to content/browser/speech. class TtsPlatformImplAndroid : public TtsPlatformImpl { public: // TtsPlatformImpl implementation.
diff --git a/chrome/browser/speech/tts_chromeos.cc b/chrome/browser/speech/tts_chromeos.cc index e1819e20..3e1469e 100644 --- a/chrome/browser/speech/tts_chromeos.cc +++ b/chrome/browser/speech/tts_chromeos.cc
@@ -11,9 +11,9 @@ // This class includes extension-based tts through LoadBuiltInTtsExtension and // native tts through ARC. -class TtsPlatformImplChromeOs : public TtsPlatformImpl { +class TtsPlatformImplChromeOs : public TtsPlatform { public: - // TtsPlatformImpl overrides: + // TtsPlatform overrides: bool PlatformImplAvailable() override { return arc::ArcServiceManager::Get() && arc::ArcServiceManager::Get() ->arc_bridge_service() @@ -76,25 +76,36 @@ voice.events.insert(content::TTS_EVENT_END); } + std::string GetError() override { return error_; } + + void ClearError() override { error_ = std::string(); } + + void SetError(const std::string& error) override { error_ = error; } + // Unimplemented. void Pause() override {} void Resume() override {} bool IsSpeaking() override { return false; } + void WillSpeakUtteranceWithVoice( + const content::Utterance* utterance, + const content::VoiceData& voice_data) override {} // Get the single instance of this class. static TtsPlatformImplChromeOs* GetInstance(); private: TtsPlatformImplChromeOs() {} - ~TtsPlatformImplChromeOs() override {} + virtual ~TtsPlatformImplChromeOs() {} friend struct base::DefaultSingletonTraits<TtsPlatformImplChromeOs>; + std::string error_; + DISALLOW_COPY_AND_ASSIGN(TtsPlatformImplChromeOs); }; // static -TtsPlatformImpl* TtsPlatformImpl::GetInstance() { +TtsPlatform* TtsPlatform::GetInstance() { return TtsPlatformImplChromeOs::GetInstance(); }
diff --git a/chrome/browser/speech/tts_controller_delegate_impl.cc b/chrome/browser/speech/tts_controller_delegate_impl.cc index 488266f4..b7463965 100644 --- a/chrome/browser/speech/tts_controller_delegate_impl.cc +++ b/chrome/browser/speech/tts_controller_delegate_impl.cc
@@ -80,7 +80,7 @@ TtsControllerDelegateImpl::TtsControllerDelegateImpl() : current_utterance_(nullptr), paused_(false), - platform_impl_(nullptr), + tts_platform_(nullptr), tts_engine_delegate_(nullptr) {} TtsControllerDelegateImpl::~TtsControllerDelegateImpl() { @@ -115,7 +115,7 @@ // Ensure we have all built-in voices loaded. This is a no-op if already // loaded. bool loaded_built_in = - GetPlatformImpl()->LoadBuiltInTtsExtension(utterance->browser_context()); + GetTtsPlatform()->LoadBuiltInTtsExtension(utterance->browser_context()); // Get all available voices and try to find a matching voice. std::vector<content::VoiceData> voices; @@ -132,7 +132,7 @@ UpdateUtteranceDefaults(utterance); - GetPlatformImpl()->WillSpeakUtteranceWithVoice(utterance, voice); + GetTtsPlatform()->WillSpeakUtteranceWithVoice(utterance, voice); base::RecordAction(base::UserMetricsAction("TextToSpeech.Speak")); UMA_HISTOGRAM_COUNTS_100000("TextToSpeech.Utterance.TextLength", @@ -171,10 +171,10 @@ // It's possible for certain platforms to send start events immediately // during |speak|. current_utterance_ = utterance; - GetPlatformImpl()->clear_error(); - bool success = GetPlatformImpl()->Speak(utterance->id(), utterance->text(), - utterance->lang(), voice, - utterance->continuous_parameters()); + GetTtsPlatform()->ClearError(); + bool success = GetTtsPlatform()->Speak(utterance->id(), utterance->text(), + utterance->lang(), voice, + utterance->continuous_parameters()); if (!success) current_utterance_ = nullptr; @@ -187,7 +187,7 @@ if (!success) { utterance->OnTtsEvent(content::TTS_EVENT_ERROR, kInvalidCharIndex, - GetPlatformImpl()->error()); + GetTtsPlatform()->GetError()); delete utterance; return; } @@ -202,8 +202,8 @@ if (tts_engine_delegate_) tts_engine_delegate_->Stop(current_utterance_); } else { - GetPlatformImpl()->clear_error(); - GetPlatformImpl()->StopSpeaking(); + GetTtsPlatform()->ClearError(); + GetTtsPlatform()->StopSpeaking(); } if (current_utterance_) @@ -221,8 +221,8 @@ if (tts_engine_delegate_) tts_engine_delegate_->Pause(current_utterance_); } else if (current_utterance_) { - GetPlatformImpl()->clear_error(); - GetPlatformImpl()->Pause(); + GetTtsPlatform()->ClearError(); + GetTtsPlatform()->Pause(); } } @@ -234,8 +234,8 @@ if (tts_engine_delegate_) tts_engine_delegate_->Resume(current_utterance_); } else if (current_utterance_) { - GetPlatformImpl()->clear_error(); - GetPlatformImpl()->Resume(); + GetTtsPlatform()->ClearError(); + GetTtsPlatform()->Resume(); } else { SpeakNextUtterance(); } @@ -302,13 +302,13 @@ void TtsControllerDelegateImpl::GetVoices( content::BrowserContext* browser_context, std::vector<content::VoiceData>* out_voices) { - TtsPlatformImpl* platform_impl = GetPlatformImpl(); - if (platform_impl) { + TtsPlatform* tts_platform = GetTtsPlatform(); + if (tts_platform) { // Ensure we have all built-in voices loaded. This is a no-op if already // loaded. - platform_impl->LoadBuiltInTtsExtension(browser_context); - if (platform_impl->PlatformImplAvailable()) - platform_impl->GetVoices(out_voices); + tts_platform->LoadBuiltInTtsExtension(browser_context); + if (tts_platform->PlatformImplAvailable()) + tts_platform->GetVoices(out_voices); } if (browser_context && tts_engine_delegate_) @@ -316,7 +316,7 @@ } bool TtsControllerDelegateImpl::IsSpeaking() { - return current_utterance_ != nullptr || GetPlatformImpl()->IsSpeaking(); + return current_utterance_ != nullptr || GetTtsPlatform()->IsSpeaking(); } void TtsControllerDelegateImpl::FinishCurrentUtterance() { @@ -355,19 +355,18 @@ } } -void TtsControllerDelegateImpl::SetPlatformImpl( - TtsPlatformImpl* platform_impl) { - platform_impl_ = platform_impl; +void TtsControllerDelegateImpl::SetTtsPlatform(TtsPlatform* tts_platform) { + tts_platform_ = tts_platform; } int TtsControllerDelegateImpl::QueueSize() { return static_cast<int>(utterance_queue_.size()); } -TtsPlatformImpl* TtsControllerDelegateImpl::GetPlatformImpl() { - if (!platform_impl_) - platform_impl_ = TtsPlatformImpl::GetInstance(); - return platform_impl_; +TtsPlatform* TtsControllerDelegateImpl::GetTtsPlatform() { + if (!tts_platform_) + tts_platform_ = TtsPlatform::GetInstance(); + return tts_platform_; } int TtsControllerDelegateImpl::GetMatchingVoice( @@ -546,7 +545,7 @@ void TtsControllerDelegateImpl::VoicesChanged() { // Existence of platform tts indicates explicit requests to tts. Since // |VoicesChanged| can occur implicitly, only send if needed. - if (!GetPlatformImpl()) + if (!GetTtsPlatform()) return; for (auto& delegate : voices_changed_delegates_) @@ -583,8 +582,8 @@ if (tts_engine_delegate_) tts_engine_delegate_->Stop(current_utterance_); } else { - GetPlatformImpl()->clear_error(); - GetPlatformImpl()->StopSpeaking(); + GetTtsPlatform()->ClearError(); + GetTtsPlatform()->StopSpeaking(); } FinishCurrentUtterance();
diff --git a/chrome/browser/speech/tts_controller_delegate_impl.h b/chrome/browser/speech/tts_controller_delegate_impl.h index 676ec8e2..8ea03d9 100644 --- a/chrome/browser/speech/tts_controller_delegate_impl.h +++ b/chrome/browser/speech/tts_controller_delegate_impl.h
@@ -49,7 +49,7 @@ void SetTtsEngineDelegate(content::TtsEngineDelegate* delegate) override; content::TtsEngineDelegate* GetTtsEngineDelegate() override; - void SetPlatformImpl(TtsPlatformImpl* platform_impl); + void SetTtsPlatform(TtsPlatform* tts_platform); int QueueSize(); protected: @@ -63,7 +63,7 @@ TestTtsControllerUtteranceDefaults); // Get the platform TTS implementation (or injected mock). - TtsPlatformImpl* GetPlatformImpl(); + TtsPlatform* GetTtsPlatform(); // Start speaking the given utterance. Will either take ownership of // |utterance| or delete it if there's an error. Returns true on success. @@ -108,7 +108,7 @@ // A pointer to the platform implementation of text-to-speech, for // dependency injection. - TtsPlatformImpl* platform_impl_; + TtsPlatform* tts_platform_; // The delegate that processes TTS requests with user-installed extensions. content::TtsEngineDelegate* tts_engine_delegate_;
diff --git a/chrome/browser/speech/tts_controller_unittest.cc b/chrome/browser/speech/tts_controller_unittest.cc index 2a09982..f09c8f1 100644 --- a/chrome/browser/speech/tts_controller_unittest.cc +++ b/chrome/browser/speech/tts_controller_unittest.cc
@@ -19,10 +19,10 @@ }; // Platform Tts implementation that does nothing. -class DummyTtsPlatformImpl : public TtsPlatformImpl { +class DummyTtsPlatformImpl : public TtsPlatform { public: DummyTtsPlatformImpl() {} - ~DummyTtsPlatformImpl() override {} + virtual ~DummyTtsPlatformImpl() {} bool PlatformImplAvailable() override { return true; } bool Speak(int utterance_id, const std::string& utterance, @@ -36,9 +36,16 @@ void Pause() override {} void Resume() override {} void GetVoices(std::vector<content::VoiceData>* out_voices) override {} - std::string error() override { return std::string(); } - void clear_error() override {} - void set_error(const std::string& error) override {} + bool LoadBuiltInTtsExtension( + content::BrowserContext* browser_context) override { + return false; + } + void WillSpeakUtteranceWithVoice( + const content::Utterance* utterance, + const content::VoiceData& voice_data) override {} + void SetError(const std::string& error) override {} + std::string GetError() override { return std::string(); } + void ClearError() override {} }; // Subclass of TtsController with a public ctor and dtor. @@ -61,7 +68,7 @@ TestableTtsController* controller = new TestableTtsController(); - controller->SetPlatformImpl(&platform_impl); + controller->SetTtsPlatform(&platform_impl); content::Utterance* utterance1 = new content::Utterance(nullptr); utterance1->set_can_enqueue(true);
diff --git a/chrome/browser/speech/tts_linux.cc b/chrome/browser/speech/tts_linux.cc index cfe920f..f35e974 100644 --- a/chrome/browser/speech/tts_linux.cc +++ b/chrome/browser/speech/tts_linux.cc
@@ -14,7 +14,7 @@ #include "base/memory/singleton.h" #include "base/synchronization/lock.h" #include "base/task/post_task.h" -#include "chrome/browser/speech/tts_platform.h" +#include "chrome/browser/speech/tts_platform_impl.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "content/public/common/content_switches.h" @@ -34,6 +34,7 @@ } // namespace +// TODO(katie): Move to content/browser/speech. class TtsPlatformImplLinux : public TtsPlatformImpl { public: bool PlatformImplAvailable() override; @@ -355,6 +356,6 @@ } // static -TtsPlatformImpl* TtsPlatformImpl::GetInstance() { +TtsPlatform* TtsPlatform::GetInstance() { return TtsPlatformImplLinux::GetInstance(); }
diff --git a/chrome/browser/speech/tts_mac.mm b/chrome/browser/speech/tts_mac.mm index c26cc77..9859905d 100644 --- a/chrome/browser/speech/tts_mac.mm +++ b/chrome/browser/speech/tts_mac.mm
@@ -9,7 +9,7 @@ #include "base/memory/singleton.h" #include "base/strings/sys_string_conversions.h" #include "base/values.h" -#include "chrome/browser/speech/tts_platform.h" +#include "chrome/browser/speech/tts_platform_impl.h" #include "content/public/browser/tts_controller.h" #import <Cocoa/Cocoa.h> @@ -48,6 +48,7 @@ @end +// TODO(katie): Move to content/browser/speech. class TtsPlatformImplMac : public TtsPlatformImpl { public: bool PlatformImplAvailable() override { return true; } @@ -95,7 +96,7 @@ }; // static -TtsPlatformImpl* TtsPlatformImpl::GetInstance() { +TtsPlatform* TtsPlatform::GetInstance() { return TtsPlatformImplMac::GetInstance(); }
diff --git a/chrome/browser/speech/tts_platform.h b/chrome/browser/speech/tts_platform.h index 341026ab..2c86f5d 100644 --- a/chrome/browser/speech/tts_platform.h +++ b/chrome/browser/speech/tts_platform.h
@@ -15,9 +15,9 @@ // TODO(katie): Move to content/public/browser and most implementations into // content/browser/speech. The tts_chromeos.cc implementation may need to remain // in chrome/ due to ARC++ dependencies. -class TtsPlatformImpl { +class TtsPlatform { public: - static TtsPlatformImpl* GetInstance(); + static TtsPlatform* GetInstance(); // Returns true if this platform implementation is supported and available. virtual bool PlatformImplAvailable() = 0; @@ -28,7 +28,7 @@ // Will call TtsController::RetrySpeakingQueuedUtterances when // the extension finishes loading. virtual bool LoadBuiltInTtsExtension( - content::BrowserContext* browser_context); + content::BrowserContext* browser_context) = 0; // Speak the given utterance with the given parameters if possible, // and return true on success. Utterance will always be nonempty. @@ -64,22 +64,11 @@ // for each one. virtual void WillSpeakUtteranceWithVoice( const content::Utterance* utterance, - const content::VoiceData& voice_data); + const content::VoiceData& voice_data) = 0; - virtual std::string error(); - virtual void clear_error(); - virtual void set_error(const std::string& error); - - protected: - TtsPlatformImpl() {} - - // On some platforms this may be a leaky singleton - do not rely on the - // destructor being called! http://crbug.com/122026 - virtual ~TtsPlatformImpl() {} - - std::string error_; - - DISALLOW_COPY_AND_ASSIGN(TtsPlatformImpl); + virtual std::string GetError() = 0; + virtual void ClearError() = 0; + virtual void SetError(const std::string& error) = 0; }; #endif // CHROME_BROWSER_SPEECH_TTS_PLATFORM_H_
diff --git a/chrome/browser/speech/tts_platform_fuzzer.cc b/chrome/browser/speech/tts_platform_fuzzer.cc index 71f0dca..38ec9e5 100644 --- a/chrome/browser/speech/tts_platform_fuzzer.cc +++ b/chrome/browser/speech/tts_platform_fuzzer.cc
@@ -88,7 +88,7 @@ while (i < size) utterance.append(1, data[i++]); - TtsPlatformImpl* tts = TtsPlatformImpl::GetInstance(); + TtsPlatform* tts = TtsPlatform::GetInstance(); CHECK(tts->PlatformImplAvailable()); VLOG(1) << "id=" << utterance_id << " lang='" << lang << "'"
diff --git a/chrome/browser/speech/tts_platform.cc b/chrome/browser/speech/tts_platform_impl.cc similarity index 63% rename from chrome/browser/speech/tts_platform.cc rename to chrome/browser/speech/tts_platform_impl.cc index c2b67007..725e55a 100644 --- a/chrome/browser/speech/tts_platform.cc +++ b/chrome/browser/speech/tts_platform_impl.cc
@@ -1,8 +1,8 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright (c) 2018 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/speech/tts_platform.h" +#include "chrome/browser/speech/tts_platform_impl.h" #include <string> @@ -11,18 +11,18 @@ return false; } -std::string TtsPlatformImpl::error() { - return error_; -} - -void TtsPlatformImpl::clear_error() { - error_ = std::string(); -} - -void TtsPlatformImpl::set_error(const std::string& error) { - error_ = error; -} - void TtsPlatformImpl::WillSpeakUtteranceWithVoice( const content::Utterance* utterance, const content::VoiceData& voice_data) {} + +std::string TtsPlatformImpl::GetError() { + return error_; +} + +void TtsPlatformImpl::ClearError() { + error_ = std::string(); +} + +void TtsPlatformImpl::SetError(const std::string& error) { + error_ = error; +}
diff --git a/chrome/browser/speech/tts_platform_impl.h b/chrome/browser/speech/tts_platform_impl.h new file mode 100644 index 0000000..f63e026 --- /dev/null +++ b/chrome/browser/speech/tts_platform_impl.h
@@ -0,0 +1,40 @@ +// Copyright (c) 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_SPEECH_TTS_PLATFORM_IMPL_H_ +#define CHROME_BROWSER_SPEECH_TTS_PLATFORM_IMPL_H_ + +#include <string> + +#include "base/macros.h" +#include "chrome/browser/speech/tts_platform.h" +#include "content/public/browser/tts_controller.h" + +// Abstract platform implementation. +// TODO(katie): Move to content/browser/speech. +class TtsPlatformImpl : public TtsPlatform { + public: + // TtsPlatform overrides. + bool LoadBuiltInTtsExtension( + content::BrowserContext* browser_context) override; + void WillSpeakUtteranceWithVoice( + const content::Utterance* utterance, + const content::VoiceData& voice_data) override; + std::string GetError() override; + void ClearError() override; + void SetError(const std::string& error) override; + + protected: + TtsPlatformImpl() {} + + // On some platforms this may be a leaky singleton - do not rely on the + // destructor being called! http://crbug.com/122026 + virtual ~TtsPlatformImpl() {} + + std::string error_; + + DISALLOW_COPY_AND_ASSIGN(TtsPlatformImpl); +}; + +#endif // CHROME_BROWSER_SPEECH_TTS_PLATFORM_IMPL_H_
diff --git a/chrome/browser/speech/tts_win.cc b/chrome/browser/speech/tts_win.cc index 36efc695..2f5a820 100644 --- a/chrome/browser/speech/tts_win.cc +++ b/chrome/browser/speech/tts_win.cc
@@ -16,7 +16,7 @@ #include "base/values.h" #include "base/win/scoped_co_mem.h" #include "base/win/sphelper.h" -#include "chrome/browser/speech/tts_platform.h" +#include "chrome/browser/speech/tts_platform_impl.h" #include "content/public/browser/tts_controller.h" namespace { @@ -27,6 +27,7 @@ } // anonymous namespace. +// TODO(katie): Move to content/browser/speech. class TtsPlatformImplWin : public TtsPlatformImpl { public: bool PlatformImplAvailable() override { @@ -79,7 +80,7 @@ }; // static -TtsPlatformImpl* TtsPlatformImpl::GetInstance() { +TtsPlatform* TtsPlatform::GetInstance() { return TtsPlatformImplWin::GetInstance(); }
diff --git a/chrome/browser/ui/cocoa/applescript/browsercrapplication+applescript_test.mm b/chrome/browser/ui/cocoa/applescript/browsercrapplication+applescript_test.mm index a11054a1..d276898 100644 --- a/chrome/browser/ui/cocoa/applescript/browsercrapplication+applescript_test.mm +++ b/chrome/browser/ui/cocoa/applescript/browsercrapplication+applescript_test.mm
@@ -99,9 +99,7 @@ } // Bookmark folders at the root level. -// http://code.google.com/p/chromium/issues/detail?id=84299 -IN_PROC_BROWSER_TEST_F(BrowserCrApplicationAppleScriptTest, - DISABLED_BookmarkFolders) { +IN_PROC_BROWSER_TEST_F(BrowserCrApplicationAppleScriptTest, BookmarkFolders) { NSArray* bookmarkFolders = [NSApp bookmarkFolders]; EXPECT_EQ(2U, [bookmarkFolders count]);
diff --git a/chrome/browser/ui/in_product_help/reopen_tab_in_product_help.cc b/chrome/browser/ui/in_product_help/reopen_tab_in_product_help.cc index 83f316eb..75f8cda4 100644 --- a/chrome/browser/ui/in_product_help/reopen_tab_in_product_help.cc +++ b/chrome/browser/ui/in_product_help/reopen_tab_in_product_help.cc
@@ -50,10 +50,6 @@ trigger_.NewTabOpened(); } -void ReopenTabInProductHelp::OmniboxFocused() { - trigger_.OmniboxFocused(); -} - void ReopenTabInProductHelp::TabReopened() { GetTracker()->NotifyEvent(feature_engagement::events::kTabReopened); }
diff --git a/chrome/browser/ui/in_product_help/reopen_tab_in_product_help.h b/chrome/browser/ui/in_product_help/reopen_tab_in_product_help.h index a18da10..473ae620 100644 --- a/chrome/browser/ui/in_product_help/reopen_tab_in_product_help.h +++ b/chrome/browser/ui/in_product_help/reopen_tab_in_product_help.h
@@ -35,12 +35,9 @@ ReopenTabInProductHelp(Profile* profile, const base::TickClock* clock); ~ReopenTabInProductHelp() override; - // Should be called when the user opens a blank new tab. - void NewTabOpened(); - - // Should be called when the user focuses on the omnibox. Possibly triggers + // Should be called when the user opens a blank new tab. Possibly triggers // IPH. - void OmniboxFocused(); + void NewTabOpened(); // Should be called when the user reopens a previously closed tab, either // through CTRL+SHIFT+T or through the recent tabs menu.
diff --git a/chrome/browser/ui/in_product_help/reopen_tab_in_product_help_trigger.cc b/chrome/browser/ui/in_product_help/reopen_tab_in_product_help_trigger.cc index 48d9437..aad9b39c 100644 --- a/chrome/browser/ui/in_product_help/reopen_tab_in_product_help_trigger.cc +++ b/chrome/browser/ui/in_product_help/reopen_tab_in_product_help_trigger.cc
@@ -16,9 +16,6 @@ // static const base::TimeDelta ReopenTabInProductHelpTrigger::kNewTabOpenedTimeout = base::TimeDelta::FromSeconds(10); -// static -const base::TimeDelta ReopenTabInProductHelpTrigger::kOmniboxFocusedTimeout = - base::TimeDelta::FromSeconds(10); ReopenTabInProductHelpTrigger::ReopenTabInProductHelpTrigger( feature_engagement::Tracker* tracker, @@ -27,9 +24,8 @@ DCHECK(tracker); DCHECK(clock); - // Timeouts must be non-zero. + // Timeout must be non-zero. DCHECK(!kNewTabOpenedTimeout.is_zero()); - DCHECK(!kOmniboxFocusedTimeout.is_zero()); } ReopenTabInProductHelpTrigger::~ReopenTabInProductHelpTrigger() = default; @@ -61,26 +57,14 @@ const base::TimeDelta elapsed_time = clock_->NowTicks() - time_of_last_step_; if (elapsed_time < kNewTabOpenedTimeout) { - trigger_state_ = NEW_TAB_OPENED; - time_of_last_step_ = clock_->NowTicks(); - } else { - ResetTriggerState(); - } -} - -void ReopenTabInProductHelpTrigger::OmniboxFocused() { - if (trigger_state_ != NEW_TAB_OPENED) - return; - - const base::TimeDelta elapsed_time = clock_->NowTicks() - time_of_last_step_; - - if (elapsed_time < kOmniboxFocusedTimeout) { tracker_->NotifyEvent(feature_engagement::events::kReopenTabConditionsMet); if (tracker_->ShouldTriggerHelpUI( feature_engagement::kIPHReopenTabFeature)) { DCHECK(cb_); cb_.Run(); } + } else { + ResetTriggerState(); } }
diff --git a/chrome/browser/ui/in_product_help/reopen_tab_in_product_help_trigger.h b/chrome/browser/ui/in_product_help/reopen_tab_in_product_help_trigger.h index d971d8a..40ee56f 100644 --- a/chrome/browser/ui/in_product_help/reopen_tab_in_product_help_trigger.h +++ b/chrome/browser/ui/in_product_help/reopen_tab_in_product_help_trigger.h
@@ -37,13 +37,10 @@ // Should be called when an active tab is closed. void ActiveTabClosed(base::TimeDelta active_duration); - // Should be called when a blank new tab is opened by user action. + // Should be called when a blank new tab is opened by user action. Possibly + // triggers IPH. void NewTabOpened(); - // Should be called when the user focuses on the omnibox. Possibly triggers - // IPH. - void OmniboxFocused(); - // Must be called once after IPH finishes. Must only be called after the // callback is called. void HelpDismissed(); @@ -51,7 +48,6 @@ // Timeout constants. Exposed for unit testing. static const base::TimeDelta kTabMinimumActiveDuration; static const base::TimeDelta kNewTabOpenedTimeout; - static const base::TimeDelta kOmniboxFocusedTimeout; private: // Sets state as if user has not performed any actions. @@ -65,7 +61,6 @@ enum TriggerState { NO_ACTIONS_SEEN, ACTIVE_TAB_CLOSED, - NEW_TAB_OPENED, }; TriggerState trigger_state_;
diff --git a/chrome/browser/ui/in_product_help/reopen_tab_in_product_help_trigger_unittest.cc b/chrome/browser/ui/in_product_help/reopen_tab_in_product_help_trigger_unittest.cc index a6cbdcb..33ca80c 100644 --- a/chrome/browser/ui/in_product_help/reopen_tab_in_product_help_trigger_unittest.cc +++ b/chrome/browser/ui/in_product_help/reopen_tab_in_product_help_trigger_unittest.cc
@@ -57,7 +57,6 @@ reopen_tab_iph.ActiveTabClosed( ReopenTabInProductHelpTrigger::kTabMinimumActiveDuration); reopen_tab_iph.NewTabOpened(); - reopen_tab_iph.OmniboxFocused(); } TEST(ReopenTabInProductHelpTriggerTest, RespectsBackendShouldTrigger) { @@ -77,7 +76,6 @@ reopen_tab_iph.ActiveTabClosed( ReopenTabInProductHelpTrigger::kTabMinimumActiveDuration); reopen_tab_iph.NewTabOpened(); - reopen_tab_iph.OmniboxFocused(); } TEST(ReopenTabInProductHelpTriggerTest, TabNotActiveLongEnough) { @@ -92,10 +90,9 @@ reopen_tab_iph.ActiveTabClosed( ReopenTabInProductHelpTrigger::kTabMinimumActiveDuration / 2); reopen_tab_iph.NewTabOpened(); - reopen_tab_iph.OmniboxFocused(); } -TEST(ReopenTabInProductHelpTriggerTest, RespectsTimeouts) { +TEST(ReopenTabInProductHelpTriggerTest, RespectsTimeout) { NiceMock<MockTracker> mock_tracker; EXPECT_CALL(mock_tracker, NotifyEvent(_)).Times(0); @@ -111,13 +108,6 @@ ReopenTabInProductHelpTrigger::kTabMinimumActiveDuration); clock.Advance(ReopenTabInProductHelpTrigger::kNewTabOpenedTimeout); reopen_tab_iph.NewTabOpened(); - reopen_tab_iph.OmniboxFocused(); - - reopen_tab_iph.ActiveTabClosed( - ReopenTabInProductHelpTrigger::kTabMinimumActiveDuration); - reopen_tab_iph.NewTabOpened(); - clock.Advance(ReopenTabInProductHelpTrigger::kOmniboxFocusedTimeout); - reopen_tab_iph.OmniboxFocused(); } TEST(ReopenTabInProductHelpTriggerTest, TriggersTwice) { @@ -142,7 +132,6 @@ reopen_tab_iph.ActiveTabClosed( ReopenTabInProductHelpTrigger::kTabMinimumActiveDuration); reopen_tab_iph.NewTabOpened(); - reopen_tab_iph.OmniboxFocused(); EXPECT_TRUE(triggered); triggered = false; @@ -150,7 +139,6 @@ reopen_tab_iph.ActiveTabClosed( ReopenTabInProductHelpTrigger::kTabMinimumActiveDuration); reopen_tab_iph.NewTabOpened(); - reopen_tab_iph.OmniboxFocused(); EXPECT_TRUE(triggered); }
diff --git a/chrome/browser/ui/in_product_help/reopen_tab_in_product_help_unittest.cc b/chrome/browser/ui/in_product_help/reopen_tab_in_product_help_unittest.cc index 5d688df..528226b 100644 --- a/chrome/browser/ui/in_product_help/reopen_tab_in_product_help_unittest.cc +++ b/chrome/browser/ui/in_product_help/reopen_tab_in_product_help_unittest.cc
@@ -74,5 +74,4 @@ tab_strip_model->CloseSelectedTabs(); reopen_tab_iph.NewTabOpened(); - reopen_tab_iph.OmniboxFocused(); }
diff --git a/chrome/browser/ui/location_bar/location_bar.h b/chrome/browser/ui/location_bar/location_bar.h index de39c740..cee5096 100644 --- a/chrome/browser/ui/location_bar/location_bar.h +++ b/chrome/browser/ui/location_bar/location_bar.h
@@ -53,9 +53,6 @@ // Updates the state of the images showing the content settings status. virtual void UpdateContentSettingsIcons() = 0; - // Updates the password icon and pops up a bubble from the icon if needed. - virtual void UpdateManagePasswordsIconAndBubble() = 0; - // Updates the visibility and toggled state of the save credit card icon. virtual void UpdateSaveCreditCardIcon() = 0;
diff --git a/chrome/browser/ui/media_router/media_router_ui_base.cc b/chrome/browser/ui/media_router/media_router_ui_base.cc index 791971f..301a438 100644 --- a/chrome/browser/ui/media_router/media_router_ui_base.cc +++ b/chrome/browser/ui/media_router/media_router_ui_base.cc
@@ -253,7 +253,7 @@ params = GetRouteParameters(sink_id, cast_mode); } if (!params) { - SendIssueForUnableToCast(cast_mode); + SendIssueForUnableToCast(cast_mode, sink_id); return false; } @@ -406,6 +406,10 @@ } current_route_request_.reset(); + if (result.result_code() == RouteRequestResult::TIMED_OUT) { + SendIssueForRouteTimeout(cast_mode, sink_id, + presentation_request_source_name); + } } void MediaRouterUIBase::HandleCreateSessionRequestRouteResponse( @@ -582,6 +586,7 @@ void MediaRouterUIBase::SendIssueForRouteTimeout( MediaCastMode cast_mode, + const MediaSink::Id& sink_id, const base::string16& presentation_request_source_name) { std::string issue_title; switch (cast_mode) { @@ -606,11 +611,14 @@ break; } - AddIssue(IssueInfo(issue_title, IssueInfo::Action::DISMISS, - IssueInfo::Severity::NOTIFICATION)); + IssueInfo issue_info(issue_title, IssueInfo::Action::DISMISS, + IssueInfo::Severity::NOTIFICATION); + issue_info.sink_id = sink_id; + AddIssue(issue_info); } -void MediaRouterUIBase::SendIssueForUnableToCast(MediaCastMode cast_mode) { +void MediaRouterUIBase::SendIssueForUnableToCast(MediaCastMode cast_mode, + const MediaSink::Id& sink_id) { // For a generic error, claim a tab error unless it was specifically desktop // mirroring. std::string issue_title = @@ -619,8 +627,10 @@ IDS_MEDIA_ROUTER_ISSUE_UNABLE_TO_CAST_DESKTOP) : l10n_util::GetStringUTF8( IDS_MEDIA_ROUTER_ISSUE_CREATE_ROUTE_TIMEOUT_FOR_TAB); - AddIssue(IssueInfo(issue_title, IssueInfo::Action::DISMISS, - IssueInfo::Severity::WARNING)); + IssueInfo issue_info(issue_title, IssueInfo::Action::DISMISS, + IssueInfo::Severity::WARNING); + issue_info.sink_id = sink_id; + AddIssue(issue_info); } IssueManager* MediaRouterUIBase::GetIssueManager() {
diff --git a/chrome/browser/ui/media_router/media_router_ui_base.h b/chrome/browser/ui/media_router/media_router_ui_base.h index 954c46b..99e2dd8 100644 --- a/chrome/browser/ui/media_router/media_router_ui_base.h +++ b/chrome/browser/ui/media_router/media_router_ui_base.h
@@ -197,10 +197,13 @@ // Creates and sends an issue if route creation timed out. void SendIssueForRouteTimeout( MediaCastMode cast_mode, + const MediaSink::Id& sink_id, const base::string16& presentation_request_source_name); - // Creates and sends an issue if casting fails for any other reason. - void SendIssueForUnableToCast(MediaCastMode cast_mode); + // Creates and sends an issue if casting fails for any reason other than + // timeout. + void SendIssueForUnableToCast(MediaCastMode cast_mode, + const MediaSink::Id& sink_id); // Returns the IssueManager associated with |router_|. IssueManager* GetIssueManager();
diff --git a/chrome/browser/ui/page_action/page_action_icon_container.h b/chrome/browser/ui/page_action/page_action_icon_container.h index 6e9af2f..68b359e2 100644 --- a/chrome/browser/ui/page_action/page_action_icon_container.h +++ b/chrome/browser/ui/page_action/page_action_icon_container.h
@@ -9,11 +9,14 @@ // TODO(https://crbug.com/788051): Migrate page action icon update methods out // of LocationBar to this interface. kFind, + kManagePasswords, kZoom, }; class PageActionIconContainer { public: + virtual ~PageActionIconContainer() {} + // Signals a page action icon to update its visual state if it is present in // the browser window. virtual void UpdatePageActionIcon(PageActionIconType type) = 0;
diff --git a/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc b/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc index dbc4329..5b5c0b3 100644 --- a/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc +++ b/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc
@@ -23,6 +23,7 @@ #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/chrome_pages.h" #include "chrome/browser/ui/location_bar/location_bar.h" +#include "chrome/browser/ui/page_action/page_action_icon_container.h" #include "chrome/browser/ui/passwords/manage_passwords_icon_view.h" #include "chrome/browser/ui/passwords/manage_passwords_view_utils.h" #include "chrome/browser/ui/passwords/password_dialog_controller_impl.h" @@ -531,9 +532,8 @@ if (!browser) return; - LocationBar* location_bar = browser->window()->GetLocationBar(); - DCHECK(location_bar); - location_bar->UpdateManagePasswordsIconAndBubble(); + browser->window()->GetPageActionIconContainer()->UpdatePageActionIcon( + PageActionIconType::kManagePasswords); } AccountChooserPrompt* ManagePasswordsUIController::CreateAccountChooser(
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash_browsertest.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash_browsertest.cc index 82b1703a..e5fcee3 100644 --- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash_browsertest.cc +++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash_browsertest.cc
@@ -45,6 +45,7 @@ #include "chrome/browser/ui/browser_tabstrip.h" #include "chrome/browser/ui/exclusive_access/fullscreen_controller.h" #include "chrome/browser/ui/exclusive_access/fullscreen_controller_test.h" +#include "chrome/browser/ui/passwords/passwords_client_ui_delegate.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/toolbar/browser_actions_bar_browsertest.h" #include "chrome/browser/ui/views/bookmarks/bookmark_bar_view.h" @@ -66,6 +67,7 @@ #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" #include "components/account_id/account_id.h" +#include "components/autofill/core/common/password_form.h" #include "components/keep_alive_registry/keep_alive_types.h" #include "components/keep_alive_registry/scoped_keep_alive.h" #include "content/public/browser/render_frame_host.h" @@ -912,6 +914,31 @@ hosted_app_button_container_); } +// Test that the manage passwords icon appears in the title bar for hosted app +// windows. +IN_PROC_BROWSER_TEST_P(HostedAppNonClientFrameViewAshTest, + ManagePasswordsIcon) { + SetUpHostedApp(); + content::WebContents* web_contents = + app_browser_->tab_strip_model()->GetActiveWebContents(); + PageActionIconView* manage_passwords_icon = + GetPageActionIcon(PageActionIconType::kManagePasswords); + + EXPECT_TRUE(manage_passwords_icon); + EXPECT_FALSE(manage_passwords_icon->visible()); + + autofill::PasswordForm password_form; + password_form.username_value = base::ASCIIToUTF16("test"); + password_form.origin = GetAppURL().GetOrigin(); + PasswordsClientUIDelegateFromWebContents(web_contents) + ->OnPasswordAutofilled({{password_form.username_value, &password_form}}, + password_form.origin, nullptr); + chrome::ManagePasswordsForPage(app_browser_); + base::RunLoop().RunUntilIdle(); + + EXPECT_TRUE(manage_passwords_icon->visible()); +} + // Test that the zoom icon appears in the title bar for hosted app windows. IN_PROC_BROWSER_TEST_P(HostedAppNonClientFrameViewAshTest, ZoomIcon) { SetUpHostedApp();
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc index 42034d9..b7123a1 100644 --- a/chrome/browser/ui/views/frame/browser_view.cc +++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -2275,7 +2275,7 @@ } gfx::Size BrowserView::GetMinimumSize() const { - return GetBrowserViewLayout()->GetMinimumSize(); + return GetBrowserViewLayout()->GetMinimumSize(this); } ///////////////////////////////////////////////////////////////////////////////
diff --git a/chrome/browser/ui/views/frame/browser_view_layout.cc b/chrome/browser/ui/views/frame/browser_view_layout.cc index 3869270..baba07e 100644 --- a/chrome/browser/ui/views/frame/browser_view_layout.cc +++ b/chrome/browser/ui/views/frame/browser_view_layout.cc
@@ -4,6 +4,8 @@ #include "chrome/browser/ui/views/frame/browser_view_layout.h" +#include <algorithm> + #include "base/macros.h" #include "base/observer_list.h" #include "build/build_config.h" @@ -168,7 +170,7 @@ return dialog_host_.get(); } -gfx::Size BrowserViewLayout::GetMinimumSize() { +gfx::Size BrowserViewLayout::GetMinimumSize(const views::View* host) const { gfx::Size tabstrip_size( browser()->SupportsWindowFeature(Browser::FEATURE_TABSTRIP) ? tab_strip_->GetMinimumSize() : gfx::Size()); @@ -184,7 +186,7 @@ bookmark_bar_size.Enlarge(0, -bookmark_bar_->GetToolbarOverlap()); } gfx::Size infobar_container_size(infobar_container_->GetMinimumSize()); - // TODO: Adjust the minimum height for the find bar. + // TODO(pkotwicz): Adjust the minimum height for the find bar. gfx::Size contents_size(contents_container_->GetMinimumSize()); // Prevent having a 0x0 sized-contents as this can allow the window to be
diff --git a/chrome/browser/ui/views/frame/browser_view_layout.h b/chrome/browser/ui/views/frame/browser_view_layout.h index 4de4cfe..42792f70 100644 --- a/chrome/browser/ui/views/frame/browser_view_layout.h +++ b/chrome/browser/ui/views/frame/browser_view_layout.h
@@ -28,6 +28,7 @@ namespace views { class ClientView; +class View; } namespace web_modal { @@ -66,9 +67,6 @@ web_modal::WebContentsModalDialogHost* GetWebContentsModalDialogHost(); - // Returns the minimum size of the browser view. - gfx::Size GetMinimumSize(); - // Returns the bounding box, in widget coordinates, for the find bar. gfx::Rect GetFindBarBoundingBox() const; @@ -80,6 +78,7 @@ // views::LayoutManager overrides: void Layout(views::View* host) override; + gfx::Size GetMinimumSize(const views::View* host) const override; gfx::Size GetPreferredSize(const views::View* host) const override; // Returns true if an infobar is showing. @@ -92,6 +91,7 @@ class WebContentsModalDialogHostViews; Browser* browser() { return browser_; } + const Browser* browser() const { return browser_; } // Layout the following controls, starting at |top|, returns the coordinate // of the bottom of the control, for laying out the next control.
diff --git a/chrome/browser/ui/views/frame/hosted_app_button_container.cc b/chrome/browser/ui/views/frame/hosted_app_button_container.cc index af0d37232..6cbeade 100644 --- a/chrome/browser/ui/views/frame/hosted_app_button_container.cc +++ b/chrome/browser/ui/views/frame/hosted_app_button_container.cc
@@ -7,6 +7,7 @@ #include "base/metrics/histogram_macros.h" #include "base/task_runner.h" #include "base/threading/sequenced_task_runner_handle.h" +#include "chrome/browser/ui/browser_command_controller.h" #include "chrome/browser/ui/browser_content_setting_bubble_model_delegate.h" #include "chrome/browser/ui/content_settings/content_setting_image_model.h" #include "chrome/browser/ui/extensions/hosted_app_browser_controller.h" @@ -184,10 +185,12 @@ hosted_app_origin_text_(new HostedAppOriginText(browser_view->browser())), content_settings_container_(new ContentSettingsContainer(this)), page_action_icon_container_view_(new PageActionIconContainerView( - {PageActionIconType::kFind, PageActionIconType::kZoom}, + {PageActionIconType::kManagePasswords, PageActionIconType::kFind, + PageActionIconType::kZoom}, GetLayoutConstant(HOSTED_APP_PAGE_ACTION_ICON_SIZE), HorizontalPaddingBetweenItems(), browser_view->browser(), + browser_view->browser()->command_controller(), this, nullptr)), browser_actions_container_( @@ -380,6 +383,10 @@ return this; } +views::View* HostedAppButtonContainer::GetAnchorView() { + return app_menu_button_; +} + void HostedAppButtonContainer::OnWidgetVisibilityChanged(views::Widget* widget, bool visibility) { if (!visibility || !pending_widget_visibility_)
diff --git a/chrome/browser/ui/views/frame/hosted_app_button_container.h b/chrome/browser/ui/views/frame/hosted_app_button_container.h index d37b89d..a014011 100644 --- a/chrome/browser/ui/views/frame/hosted_app_button_container.h +++ b/chrome/browser/ui/views/frame/hosted_app_button_container.h
@@ -116,6 +116,7 @@ gfx::Rect GetFindBarBoundingBox(int contents_height) const override; void FocusToolbar() override; views::AccessiblePaneView* GetAsAccessiblePaneView() override; + views::View* GetAnchorView() override; // views::WidgetObserver: void OnWidgetVisibilityChanged(views::Widget* widget, bool visible) override;
diff --git a/chrome/browser/ui/views/frame/opaque_browser_frame_view.cc b/chrome/browser/ui/views/frame/opaque_browser_frame_view.cc index d6bf4a4..7b608159 100644 --- a/chrome/browser/ui/views/frame/opaque_browser_frame_view.cc +++ b/chrome/browser/ui/views/frame/opaque_browser_frame_view.cc
@@ -4,6 +4,9 @@ #include "chrome/browser/ui/views/frame/opaque_browser_frame_view.h" +#include <algorithm> +#include <utility> + #include "build/build_config.h" #include "build/buildflag.h" #include "chrome/browser/themes/theme_properties.h" @@ -213,7 +216,7 @@ } gfx::Size OpaqueBrowserFrameView::GetMinimumSize() const { - return layout_->GetMinimumSize(width()); + return layout_->GetMinimumSize(this); } ///////////////////////////////////////////////////////////////////////////////
diff --git a/chrome/browser/ui/views/frame/opaque_browser_frame_view_layout.cc b/chrome/browser/ui/views/frame/opaque_browser_frame_view_layout.cc index f73f8183..aca0c67 100644 --- a/chrome/browser/ui/views/frame/opaque_browser_frame_view_layout.cc +++ b/chrome/browser/ui/views/frame/opaque_browser_frame_view_layout.cc
@@ -4,6 +4,10 @@ #include "chrome/browser/ui/views/frame/opaque_browser_frame_view_layout.h" +#include <algorithm> +#include <string> +#include <vector> + #include "base/command_line.h" #include "base/containers/adapters.h" #include "base/stl_util.h" @@ -93,7 +97,7 @@ } gfx::Size OpaqueBrowserFrameViewLayout::GetMinimumSize( - int available_width) const { + const views::View* host) const { gfx::Size min_size = delegate_->GetBrowserViewMinimumSize(); int border_thickness = FrameBorderThickness(false); min_size.Enlarge(2 * border_thickness,
diff --git a/chrome/browser/ui/views/frame/opaque_browser_frame_view_layout.h b/chrome/browser/ui/views/frame/opaque_browser_frame_view_layout.h index 4a3c1fca..c1130eba 100644 --- a/chrome/browser/ui/views/frame/opaque_browser_frame_view_layout.h +++ b/chrome/browser/ui/views/frame/opaque_browser_frame_view_layout.h
@@ -5,6 +5,8 @@ #ifndef CHROME_BROWSER_UI_VIEWS_FRAME_OPAQUE_BROWSER_FRAME_VIEW_LAYOUT_H_ #define CHROME_BROWSER_UI_VIEWS_FRAME_OPAQUE_BROWSER_FRAME_VIEW_LAYOUT_H_ +#include <vector> + #include "base/macros.h" #include "chrome/browser/ui/frame_button_display_types.h" #include "chrome/browser/ui/views/frame/opaque_browser_frame_view.h" @@ -52,8 +54,6 @@ gfx::Rect GetBoundsForTabStrip(const gfx::Size& tabstrip_preferred_size, int total_width) const; - gfx::Size GetMinimumSize(int available_width) const; - // Returns the bounds of the window required to display the content area at // the specified bounds. gfx::Rect GetWindowBoundsForClientBounds( @@ -128,6 +128,11 @@ // Returns the extra thickness of the area above the tabs. int GetNonClientRestoredExtraThickness() const; + // views::LayoutManager: + // Called explicitly from OpaqueBrowserFrameView so we can't group it with + // the other overrides. + gfx::Size GetMinimumSize(const views::View* host) const override; + protected: // Whether a specific button should be inserted on the leading or trailing // side.
diff --git a/chrome/browser/ui/views/frame/opaque_browser_frame_view_layout_unittest.cc b/chrome/browser/ui/views/frame/opaque_browser_frame_view_layout_unittest.cc index 655e3ba..9a7d348 100644 --- a/chrome/browser/ui/views/frame/opaque_browser_frame_view_layout_unittest.cc +++ b/chrome/browser/ui/views/frame/opaque_browser_frame_view_layout_unittest.cc
@@ -4,6 +4,10 @@ #include "chrome/browser/ui/views/frame/opaque_browser_frame_view_layout.h" +#include <memory> +#include <utility> +#include <vector> + #include "base/command_line.h" #include "base/macros.h" #include "base/strings/utf_string_conversions.h" @@ -266,7 +270,7 @@ gfx::Size browser_view_min_size(delegate_->GetBrowserViewMinimumSize()); const int min_width = browser_view_min_size.width() + tabstrip_min_size.width() + spacing; - gfx::Size min_size(layout_manager_->GetMinimumSize(kWindowWidth)); + gfx::Size min_size(layout_manager_->GetMinimumSize(root_view_)); EXPECT_EQ(min_width, min_size.width()); int restored_border_height = 2 * OpaqueBrowserFrameViewLayout::kFrameBorderThickness +
diff --git a/chrome/browser/ui/views/frame/toolbar_button_provider.h b/chrome/browser/ui/views/frame/toolbar_button_provider.h index d34fee41..e51a36e 100644 --- a/chrome/browser/ui/views/frame/toolbar_button_provider.h +++ b/chrome/browser/ui/views/frame/toolbar_button_provider.h
@@ -15,6 +15,7 @@ namespace views { class AccessiblePaneView; +class View; } // An interface implemented by a view contains and provides access to toolbar @@ -41,6 +42,9 @@ // Returns the toolbar as an AccessiblePaneView. virtual views::AccessiblePaneView* GetAsAccessiblePaneView() = 0; + // Returns the toolbar as an anchor point. + virtual views::View* GetAnchorView() = 0; + // TODO(calamity): Move other buttons and button actions into here. protected: virtual ~ToolbarButtonProvider() {}
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.cc b/chrome/browser/ui/views/location_bar/location_bar_view.cc index ed1284e..dbb9d0e 100644 --- a/chrome/browser/ui/views/location_bar/location_bar_view.cc +++ b/chrome/browser/ui/views/location_bar/location_bar_view.cc
@@ -213,22 +213,20 @@ } std::vector<PageActionIconType> page_action_icon_types; + page_action_icon_types.push_back(PageActionIconType::kManagePasswords); // |browser_| may be null when LocationBarView is used for non-Browser windows // such as PresentationReceiverWindowView, which do not support page actions. if (browser_) { - page_action_icon_types = {PageActionIconType::kFind, - PageActionIconType::kZoom}; + page_action_icon_types.push_back(PageActionIconType::kFind); + page_action_icon_types.push_back(PageActionIconType::kZoom); } + page_action_icon_container_view_ = new PageActionIconContainerView( page_action_icon_types, GetLayoutConstant(LOCATION_BAR_ICON_SIZE), 0, - browser_, this, delegate_); + browser_, command_updater(), this, delegate_); AddChildView(page_action_icon_container_view_); page_action_icon_container_view_->SetIconColor(icon_color); - manage_passwords_icon_view_ = - new ManagePasswordsIconViews(command_updater(), this); - page_action_icons_.push_back(manage_passwords_icon_view_); - if (browser_) { save_credit_card_icon_view_ = new autofill::SaveCardIconView( command_updater(), browser_, this, font_list); @@ -389,7 +387,6 @@ // Compute width of omnibox-trailing content. int trailing_width = IncrementalMinimumWidth(translate_icon_view_) + - IncrementalMinimumWidth(manage_passwords_icon_view_) + IncrementalMinimumWidth(page_action_icon_container_view_); if (star_view_) trailing_width += IncrementalMinimumWidth(star_view_); @@ -518,7 +515,6 @@ add_trailing_decoration(save_credit_card_icon_view_); if (local_card_migration_icon_view_) add_trailing_decoration(local_card_migration_icon_view_); - add_trailing_decoration(manage_passwords_icon_view_); for (ContentSettingViews::const_reverse_iterator i( content_setting_views_.rbegin()); i != content_setting_views_.rend(); ++i) { @@ -923,13 +919,6 @@ } } -void LocationBarView::UpdateManagePasswordsIconAndBubble() { - if (manage_passwords_icon_view_->Update()) { - Layout(); - SchedulePaint(); - } -} - void LocationBarView::UpdateSaveCreditCardIcon() { if (save_credit_card_icon_view_->Update()) { Layout();
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.h b/chrome/browser/ui/views/location_bar/location_bar_view.h index 1613556b..8d5d5e1 100644 --- a/chrome/browser/ui/views/location_bar/location_bar_view.h +++ b/chrome/browser/ui/views/location_bar/location_bar_view.h
@@ -43,7 +43,6 @@ class IntentPickerView; class KeywordHintView; class LocationIconView; -class ManagePasswordsIconViews; enum class OmniboxPart; class OmniboxPopupView; enum class OmniboxTint; @@ -142,11 +141,6 @@ // Returns the delegate. Delegate* delegate() const { return delegate_; } - // The passwords icon. It may not be visible. - ManagePasswordsIconViews* manage_passwords_icon_view() { - return manage_passwords_icon_view_; - } - // Toggles the star on or off. void SetStarToggled(bool on); @@ -321,7 +315,6 @@ void AcceptInput(base::TimeTicks match_selection_timestamp) override; void FocusSearch() override; void UpdateContentSettingsIcons() override; - void UpdateManagePasswordsIconAndBubble() override; void UpdateSaveCreditCardIcon() override; void UpdateLocalCardMigrationIcon() override; void UpdateBookmarkStarVisibility() override; @@ -409,9 +402,6 @@ // The page action icons. PageActionIconContainerView* page_action_icon_container_view_ = nullptr; - // The manage passwords icon. - ManagePasswordsIconViews* manage_passwords_icon_view_ = nullptr; - // The save credit card icon. It will be null when |browser_| is null. autofill::SaveCardIconView* save_credit_card_icon_view_ = nullptr;
diff --git a/chrome/browser/ui/views/media_router/cast_dialog_view.cc b/chrome/browser/ui/views/media_router/cast_dialog_view.cc index b8686c8..3b73347 100644 --- a/chrome/browser/ui/views/media_router/cast_dialog_view.cc +++ b/chrome/browser/ui/views/media_router/cast_dialog_view.cc
@@ -225,6 +225,11 @@ observers_.RemoveObserver(observer); } +void CastDialogView::KeepShownForTesting() { + keep_shown_for_testing_ = true; + set_close_on_deactivate(false); +} + // static void CastDialogView::ShowDialog(views::View* anchor_view, views::BubbleBorder::Arrow anchor_position, @@ -382,21 +387,22 @@ selected_sink_index_ = index; const UIMediaSink& sink = sink_buttons_.at(index)->sink(); if (sink.route) { - controller_->StopCasting(sink.route->media_route_id()); metrics_.OnStopCasting(sink.route->is_local()); + // StopCasting() may trigger a model update and invalidate |sink|. + controller_->StopCasting(sink.route->media_route_id()); } else { base::Optional<MediaCastMode> cast_mode = GetCastModeToUse(sink); if (cast_mode) { // Starting local file casting may open a new tab synchronously on the UI // thread, which deactivates the dialog. So we must prevent it from // closing and getting destroyed. - if (cast_mode == LOCAL_FILE) + if (cast_mode.value() == LOCAL_FILE) set_close_on_deactivate(false); controller_->StartCasting(sink.id, cast_mode.value()); // Re-enable close on deactivate so the user can click elsewhere to close // the dialog. - if (cast_mode == LOCAL_FILE) - set_close_on_deactivate(true); + if (cast_mode.value() == LOCAL_FILE) + set_close_on_deactivate(!keep_shown_for_testing_); metrics_.OnStartCasting(base::Time::Now(), index); } } @@ -454,7 +460,7 @@ void CastDialogView::OnFilePickerClosed(const ui::SelectedFileInfo* file_info) { // Re-enable the setting to close the dialog when it loses focus. - set_close_on_deactivate(true); + set_close_on_deactivate(!keep_shown_for_testing_); if (file_info) { #if defined(OS_WIN) local_file_name_ = file_info->display_name;
diff --git a/chrome/browser/ui/views/media_router/cast_dialog_view.h b/chrome/browser/ui/views/media_router/cast_dialog_view.h index 4457547..01ffc07 100644 --- a/chrome/browser/ui/views/media_router/cast_dialog_view.h +++ b/chrome/browser/ui/views/media_router/cast_dialog_view.h
@@ -100,6 +100,11 @@ void AddObserver(Observer* observer); void RemoveObserver(Observer* observer); + // If the dialog loses focus during a test and closes, the test can + // fail unexpectedly. This method prevents that by keeping the dialog from + // closing on blur. + void KeepShownForTesting(); + // Called by tests. const std::vector<CastDialogSinkButton*>& sink_buttons_for_test() const { return sink_buttons_; @@ -226,6 +231,9 @@ base::ObserverList<Observer> observers_; + // When this is set to true, the dialog does not close on blur. + bool keep_shown_for_testing_ = false; + base::WeakPtrFactory<CastDialogView> weak_factory_; DISALLOW_COPY_AND_ASSIGN(CastDialogView);
diff --git a/chrome/browser/ui/views/media_router/cast_toolbar_button.cc b/chrome/browser/ui/views/media_router/cast_toolbar_button.cc index be13c4aa3..518a2444 100644 --- a/chrome/browser/ui/views/media_router/cast_toolbar_button.cc +++ b/chrome/browser/ui/views/media_router/cast_toolbar_button.cc
@@ -70,25 +70,15 @@ ToolbarButton::Init(); IssuesObserver::Init(); - MediaRouterActionController* controller = - MediaRouterUIService::Get(profile_)->action_controller(); - controller->AddObserver(this); - SetVisible(controller->ShouldEnableAction()); + + DCHECK(GetActionController()); + GetActionController()->AddObserver(this); + SetVisible(GetActionController()->ShouldEnableAction()); } CastToolbarButton::~CastToolbarButton() { - MediaRouterUIService::Get(profile_)->action_controller()->RemoveObserver( - this); -} - -void CastToolbarButton::UpdateIcon() { - const gfx::VectorIcon& icon = GetCurrentIcon(); - SetImage(views::Button::STATE_NORMAL, - gfx::CreateVectorIcon(icon, GetIconColor(&icon))); - // This icon is smaller than the touchable-UI expected 24dp, so we need to pad - // the insets to match. - SetLayoutInsetDelta( - gfx::Insets(ui::MaterialDesignController::touch_ui() ? 4 : 0)); + if (GetActionController()) + GetActionController()->RemoveObserver(this); } const gfx::VectorIcon& CastToolbarButton::GetCurrentIcon() const { @@ -150,21 +140,15 @@ } bool CastToolbarButton::OnMousePressed(const ui::MouseEvent& event) { - if (event.IsRightMouseButton()) { - MediaRouterUIService::Get(profile_) - ->action_controller() - ->KeepIconOnRightMousePressed(); - } + if (event.IsRightMouseButton() && GetActionController()) + GetActionController()->KeepIconOnRightMousePressed(); return ToolbarButton::OnMousePressed(event); } void CastToolbarButton::OnMouseReleased(const ui::MouseEvent& event) { ToolbarButton::OnMouseReleased(event); - if (event.IsRightMouseButton()) { - MediaRouterUIService::Get(profile_) - ->action_controller() - ->MaybeHideIconOnRightMouseReleased(); - } + if (event.IsRightMouseButton() && GetActionController()) + GetActionController()->MaybeHideIconOnRightMouseReleased(); } void CastToolbarButton::ButtonPressed(views::Button* sender, @@ -181,4 +165,18 @@ } } +void CastToolbarButton::UpdateIcon() { + const gfx::VectorIcon& icon = GetCurrentIcon(); + SetImage(views::Button::STATE_NORMAL, + gfx::CreateVectorIcon(icon, GetIconColor(&icon))); + // This icon is smaller than the touchable-UI expected 24dp, so we need to pad + // the insets to match. + SetLayoutInsetDelta( + gfx::Insets(ui::MaterialDesignController::touch_ui() ? 4 : 0)); +} + +MediaRouterActionController* CastToolbarButton::GetActionController() const { + return MediaRouterUIService::Get(profile_)->action_controller(); +} + } // namespace media_router
diff --git a/chrome/browser/ui/views/media_router/cast_toolbar_button.h b/chrome/browser/ui/views/media_router/cast_toolbar_button.h index 62a6cc6..3663686 100644 --- a/chrome/browser/ui/views/media_router/cast_toolbar_button.h +++ b/chrome/browser/ui/views/media_router/cast_toolbar_button.h
@@ -70,6 +70,8 @@ private: const gfx::VectorIcon& GetCurrentIcon() const; + MediaRouterActionController* GetActionController() const; + Browser* const browser_; Profile* const profile_;
diff --git a/chrome/browser/ui/views/media_router/media_router_dialog_controller_views.cc b/chrome/browser/ui/views/media_router/media_router_dialog_controller_views.cc index 7daee94..30a98d4 100644 --- a/chrome/browser/ui/views/media_router/media_router_dialog_controller_views.cc +++ b/chrome/browser/ui/views/media_router/media_router_dialog_controller_views.cc
@@ -65,6 +65,8 @@ dialog_creation_time); } CastDialogView::GetCurrentDialogWidget()->AddObserver(this); + if (dialog_creation_callback_) + dialog_creation_callback_.Run(); } void MediaRouterDialogControllerViews::CloseMediaRouterDialog() { @@ -76,8 +78,11 @@ } void MediaRouterDialogControllerViews::Reset() { - MediaRouterDialogControllerImplBase::Reset(); - ui_.reset(); + // If |ui_| is null, Reset() has already been called. + if (ui_) { + MediaRouterDialogControllerImplBase::Reset(); + ui_.reset(); + } } void MediaRouterDialogControllerViews::OnWidgetClosing(views::Widget* widget) { @@ -90,6 +95,11 @@ widget->RemoveObserver(this); } +void MediaRouterDialogControllerViews::SetDialogCreationCallbackForTesting( + base::RepeatingClosure callback) { + dialog_creation_callback_ = std::move(callback); +} + MediaRouterDialogControllerViews::MediaRouterDialogControllerViews( content::WebContents* web_contents) : MediaRouterDialogControllerImplBase(web_contents) {}
diff --git a/chrome/browser/ui/views/media_router/media_router_dialog_controller_views.h b/chrome/browser/ui/views/media_router/media_router_dialog_controller_views.h index 93d604d..6362a275 100644 --- a/chrome/browser/ui/views/media_router/media_router_dialog_controller_views.h +++ b/chrome/browser/ui/views/media_router/media_router_dialog_controller_views.h
@@ -8,6 +8,7 @@ #include <memory> #include "base/macros.h" +#include "base/observer_list.h" #include "chrome/browser/ui/media_router/media_router_dialog_controller_impl_base.h" #include "chrome/browser/ui/views/media_router/media_router_views_ui.h" #include "ui/views/widget/widget_observer.h" @@ -35,6 +36,9 @@ void OnWidgetClosing(views::Widget* widget) override; void OnWidgetDestroying(views::Widget* widget) override; + // Sets a callback to be called whenever a dialog is created. + void SetDialogCreationCallbackForTesting(base::RepeatingClosure callback); + private: friend class content::WebContentsUserData<MediaRouterDialogControllerViews>; @@ -47,6 +51,8 @@ // closed. std::unique_ptr<MediaRouterViewsUI> ui_; + base::RepeatingClosure dialog_creation_callback_; + DISALLOW_COPY_AND_ASSIGN(MediaRouterDialogControllerViews); };
diff --git a/chrome/browser/ui/views/omnibox/omnibox_view_views.cc b/chrome/browser/ui/views/omnibox/omnibox_view_views.cc index 369471c5..e415cb7 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_view_views.cc +++ b/chrome/browser/ui/views/omnibox/omnibox_view_views.cc
@@ -17,8 +17,6 @@ #include "chrome/app/chrome_command_ids.h" #include "chrome/browser/command_updater.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/in_product_help/reopen_tab_in_product_help.h" -#include "chrome/browser/ui/in_product_help/reopen_tab_in_product_help_factory.h" #include "chrome/browser/ui/omnibox/clipboard_utils.h" #include "chrome/browser/ui/omnibox/omnibox_theme.h" #include "chrome/browser/ui/view_ids.h" @@ -1135,22 +1133,17 @@ location_bar_view_->Layout(); #if BUILDFLAG(ENABLE_DESKTOP_IN_PRODUCT_HELP) - if (location_bar_view_) { - // The user must be starting a session in the same tab as a previous one in - // order to display the new tab in-product help promo. While focusing the - // omnibox is not always a precursor to starting a new session, we don't - // want to wait until the user is in the middle of editing or navigating, - // because we'd like to show them the promo at the time when it would be - // immediately useful. - if (controller()->GetLocationBarModel()->ShouldDisplayURL()) { - feature_engagement::NewTabTrackerFactory::GetInstance() - ->GetForProfile(location_bar_view_->profile()) - ->OnOmniboxFocused(); - } - - auto* reopen_tab_iph = ReopenTabInProductHelpFactory::GetForProfile( - location_bar_view_->profile()); - reopen_tab_iph->OmniboxFocused(); + // The user must be starting a session in the same tab as a previous one in + // order to display the new tab in-product help promo. While focusing the + // omnibox is not always a precursor to starting a new session, we don't + // want to wait until the user is in the middle of editing or navigating, + // because we'd like to show them the promo at the time when it would be + // immediately useful. + if (location_bar_view_ && + controller()->GetLocationBarModel()->ShouldDisplayURL()) { + feature_engagement::NewTabTrackerFactory::GetInstance() + ->GetForProfile(location_bar_view_->profile()) + ->OnOmniboxFocused(); } #endif
diff --git a/chrome/browser/ui/views/page_action/page_action_icon_container_view.cc b/chrome/browser/ui/views/page_action/page_action_icon_container_view.cc index b5d733c..bca847b6 100644 --- a/chrome/browser/ui/views/page_action/page_action_icon_container_view.cc +++ b/chrome/browser/ui/views/page_action/page_action_icon_container_view.cc
@@ -8,6 +8,7 @@ #include "chrome/browser/ui/views/location_bar/find_bar_icon.h" #include "chrome/browser/ui/views/location_bar/zoom_bubble_view.h" #include "chrome/browser/ui/views/page_action/zoom_view.h" +#include "chrome/browser/ui/views/passwords/manage_passwords_icon_views.h" #include "ui/views/layout/box_layout.h" PageActionIconContainerView::PageActionIconContainerView( @@ -15,6 +16,7 @@ int icon_size, int between_icon_spacing, Browser* browser, + CommandUpdater* command_updater, PageActionIconView::Delegate* page_action_icon_delegate, LocationBarView::Delegate* location_bar_delegate) : zoom_observer_(this) { @@ -30,6 +32,11 @@ find_bar_icon_ = new FindBarIcon(browser, page_action_icon_delegate); page_action_icons_.push_back(find_bar_icon_); break; + case PageActionIconType::kManagePasswords: + manage_passwords_icon_ = new ManagePasswordsIconViews( + command_updater, page_action_icon_delegate); + page_action_icons_.push_back(manage_passwords_icon_); + break; case PageActionIconType::kZoom: zoom_view_ = new ZoomView(location_bar_delegate, page_action_icon_delegate); @@ -61,6 +68,8 @@ switch (type) { case PageActionIconType::kFind: return find_bar_icon_; + case PageActionIconType::kManagePasswords: + return manage_passwords_icon_; case PageActionIconType::kZoom: return zoom_view_; }
diff --git a/chrome/browser/ui/views/page_action/page_action_icon_container_view.h b/chrome/browser/ui/views/page_action/page_action_icon_container_view.h index 5f7cc9d..2096751 100644 --- a/chrome/browser/ui/views/page_action/page_action_icon_container_view.h +++ b/chrome/browser/ui/views/page_action/page_action_icon_container_view.h
@@ -15,7 +15,9 @@ #include "ui/views/view.h" class Browser; +class CommandUpdater; class FindBarIcon; +class ManagePasswordsIconViews; class ZoomView; class PageActionIconContainerView : public views::View, @@ -27,6 +29,7 @@ int icon_size, int between_icon_spacing, Browser* browser, + CommandUpdater* command_updater, PageActionIconView::Delegate* page_action_icon_delegate, LocationBarView::Delegate* location_bar_delegate); ~PageActionIconContainerView() override; @@ -60,6 +63,7 @@ ZoomView* zoom_view_ = nullptr; FindBarIcon* find_bar_icon_ = nullptr; + ManagePasswordsIconViews* manage_passwords_icon_ = nullptr; std::vector<PageActionIconView*> page_action_icons_; ScopedObserver<zoom::ZoomEventManager, zoom::ZoomEventManagerObserver>
diff --git a/chrome/browser/ui/views/passwords/manage_passwords_icon_view_interactive_uitest.cc b/chrome/browser/ui/views/passwords/manage_passwords_icon_view_interactive_uitest.cc index a6a6555..300b512 100644 --- a/chrome/browser/ui/views/passwords/manage_passwords_icon_view_interactive_uitest.cc +++ b/chrome/browser/ui/views/passwords/manage_passwords_icon_view_interactive_uitest.cc
@@ -7,6 +7,7 @@ #include "chrome/browser/ui/passwords/manage_passwords_test.h" #include "chrome/browser/ui/passwords/manage_passwords_ui_controller_mock.h" #include "chrome/browser/ui/views/frame/browser_view.h" +#include "chrome/browser/ui/views/page_action/page_action_icon_container_view.h" #include "chrome/browser/ui/views/passwords/manage_passwords_icon_views.h" #include "chrome/browser/ui/views/toolbar/toolbar_view.h" #include "chrome/grit/generated_resources.h" @@ -24,10 +25,13 @@ password_manager::ui::State ViewState() { return GetView()->state_; } ManagePasswordsIconViews* GetView() { - return BrowserView::GetBrowserViewForBrowser(browser()) - ->toolbar() - ->location_bar() - ->manage_passwords_icon_view(); + views::View* view = + BrowserView::GetBrowserViewForBrowser(browser()) + ->toolbar_button_provider() + ->GetPageActionIconContainerView() + ->GetPageActionIconView(PageActionIconType::kManagePasswords); + DCHECK_EQ(view->GetClassName(), ManagePasswordsIconViews::kClassName); + return static_cast<ManagePasswordsIconViews*>(view); } base::string16 GetTooltipText() {
diff --git a/chrome/browser/ui/views/passwords/manage_passwords_icon_views.cc b/chrome/browser/ui/views/passwords/manage_passwords_icon_views.cc index 9af753f5..5b370213 100644 --- a/chrome/browser/ui/views/passwords/manage_passwords_icon_views.cc +++ b/chrome/browser/ui/views/passwords/manage_passwords_icon_views.cc
@@ -14,6 +14,8 @@ #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h" +const char ManagePasswordsIconViews::kClassName[] = "ManagePasswordsIconViews"; + ManagePasswordsIconViews::ManagePasswordsIconViews( CommandUpdater* updater, PageActionIconView::Delegate* delegate) @@ -108,3 +110,7 @@ if (IsBubbleShowing()) PasswordBubbleViewBase::ActivateBubble(); } + +const char* ManagePasswordsIconViews::GetClassName() const { + return kClassName; +}
diff --git a/chrome/browser/ui/views/passwords/manage_passwords_icon_views.h b/chrome/browser/ui/views/passwords/manage_passwords_icon_views.h index 21d1b5e..06bfdc30 100644 --- a/chrome/browser/ui/views/passwords/manage_passwords_icon_views.h +++ b/chrome/browser/ui/views/passwords/manage_passwords_icon_views.h
@@ -18,6 +18,8 @@ class ManagePasswordsIconViews : public ManagePasswordsIconView, public PageActionIconView { public: + static const char kClassName[]; + ManagePasswordsIconViews(CommandUpdater* updater, PageActionIconView::Delegate* delegate); ~ManagePasswordsIconViews() override; @@ -36,6 +38,7 @@ // views::View: void AboutToRequestFocusFromTabTraversal(bool reverse) override; + const char* GetClassName() const override; private: friend class ManagePasswordsIconViewTest;
diff --git a/chrome/browser/ui/views/passwords/password_bubble_view_base.cc b/chrome/browser/ui/views/passwords/password_bubble_view_base.cc index b95493d..6757d524 100644 --- a/chrome/browser/ui/views/passwords/password_bubble_view_base.cc +++ b/chrome/browser/ui/views/passwords/password_bubble_view_base.cc
@@ -8,7 +8,9 @@ #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/passwords/passwords_model_delegate.h" #include "chrome/browser/ui/views/frame/browser_view.h" +#include "chrome/browser/ui/views/frame/toolbar_button_provider.h" #include "chrome/browser/ui/views/location_bar/location_bar_view.h" +#include "chrome/browser/ui/views/page_action/page_action_icon_container_view.h" #include "chrome/browser/ui/views/passwords/manage_passwords_icon_views.h" #include "chrome/browser/ui/views/passwords/password_auto_sign_in_view.h" #include "chrome/browser/ui/views/passwords/password_items_view.h" @@ -29,7 +31,8 @@ !g_manage_passwords_bubble_->GetWidget()->IsVisible()); BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser); - views::View* const anchor_view = browser_view->GetLocationBarView(); + views::View* const anchor_view = + browser_view->toolbar_button_provider()->GetAnchorView(); PasswordBubbleViewBase* bubble = CreateBubble(web_contents, anchor_view, gfx::Point(), reason); @@ -38,7 +41,9 @@ if (anchor_view) { g_manage_passwords_bubble_->SetHighlightedButton( - browser_view->GetLocationBarView()->manage_passwords_icon_view()); + browser_view->toolbar_button_provider() + ->GetPageActionIconContainerView() + ->GetPageActionIconView(PageActionIconType::kManagePasswords)); } else { g_manage_passwords_bubble_->set_parent_window( web_contents->GetNativeView());
diff --git a/chrome/browser/ui/views/quit_instruction_bubble.cc b/chrome/browser/ui/views/quit_instruction_bubble.cc index 66fd87dd..6fb9ce0 100644 --- a/chrome/browser/ui/views/quit_instruction_bubble.cc +++ b/chrome/browser/ui/views/quit_instruction_bubble.cc
@@ -60,9 +60,11 @@ // Set the bounds to that of the active browser window so that the widget // will be centered on the nearest monitor. - params.bounds = BrowserView::GetBrowserViewForBrowser( - BrowserList::GetInstance()->GetLastActive()) - ->GetBounds(); + const Browser* last_active = BrowserList::GetInstance()->GetLastActive(); + if (last_active) { + params.bounds = + BrowserView::GetBrowserViewForBrowser(last_active)->GetBounds(); + } params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; params.accept_events = false;
diff --git a/chrome/browser/ui/views/tabs/tab_icon.cc b/chrome/browser/ui/views/tabs/tab_icon.cc index 0f7627e..b77e6a27 100644 --- a/chrome/browser/ui/views/tabs/tab_icon.cc +++ b/chrome/browser/ui/views/tabs/tab_icon.cc
@@ -29,7 +29,7 @@ constexpr int kLoadingProgressTimeMs = 400; constexpr int kLoadingProgressFadeOutMs = 200; -constexpr int kFaviconFadeInMs = 200; +constexpr int kFaviconFadeInMs = 500; bool UseNewLoadingAnimation() { return base::FeatureList::IsEnabled(features::kNewTabLoadingAnimation); @@ -161,7 +161,7 @@ // If the last frame painted still displays the loading indicator or favicon // in less than full opacity we need to paint the last frame. - if (animation_state_.favicon_alpha < SK_AlphaOPAQUE || + if (animation_state_.favicon_fade_in_progress < 1.0 || animation_state_.loading_progress_alpha > 0) { return true; } @@ -257,16 +257,15 @@ } // In the waiting/loading state we initially show no favicon. - state.favicon_alpha = (network_state_ == TabNetworkState::kWaiting || - network_state_ == TabNetworkState::kLoading) - ? 0 - : SK_AlphaOPAQUE; + state.favicon_fade_in_progress = + (network_state_ == TabNetworkState::kWaiting || + network_state_ == TabNetworkState::kLoading) + ? 0.0 + : 1.0; if (favicon_fade_in_animation_) { base::TimeDelta favicon_fade_in_time = now - *favicon_fade_in_animation_; - state.favicon_alpha = - SK_AlphaOPAQUE * - std::min(favicon_fade_in_time.InMillisecondsF() / kFaviconFadeInMs, - 1.0); + state.favicon_fade_in_progress = std::min( + favicon_fade_in_time.InMillisecondsF() / kFaviconFadeInMs, 1.0); } return state; @@ -285,7 +284,7 @@ // Compare without |elapsed_time| as it's only used in the waiting state. auto tie = [](const LoadingAnimationState& state) { return std::tie(state.loading_progress, state.loading_progress_alpha, - state.favicon_alpha); + state.favicon_fade_in_progress); }; return tie(new_state) != tie(animation_state_); @@ -411,18 +410,21 @@ const gfx::Rect& bounds) { // While loading, the favicon (or placeholder) isn't drawn until it has // started fading in. - if (animation_state_.favicon_alpha == 0) + if (animation_state_.favicon_fade_in_progress == 0.0) return false; if (icon.isNull()) return false; cc::PaintFlags flags; - flags.setAlpha(animation_state_.favicon_alpha); + flags.setAlpha(animation_state_.favicon_fade_in_progress * SK_AlphaOPAQUE); + // Drop in the new favicon from the top while it's fading in. + const int offset = + round((animation_state_.favicon_fade_in_progress - 1.0) * 4.0); canvas->DrawImageInt(icon, 0, 0, bounds.width(), bounds.height(), bounds.x(), - bounds.y(), bounds.width(), bounds.height(), false, - flags); + bounds.y() + offset, bounds.width(), bounds.height(), + false, flags); return true; } @@ -461,15 +463,14 @@ } if (old_state == TabNetworkState::kLoading) { + // Rewind the progress timer back to currently displayed progress bar so + // we don't miss the end of the animation. + RewindLoadingProgressTimerIfNecessary(target_loading_progress_); target_loading_progress_ = 1.0; // Start fading in placeholder favicon if no favicon has loaded so far. const base::TimeTicks now = clock_->NowTicks(); if (!favicon_fade_in_animation_) favicon_fade_in_animation_ = now; - - // Rewind the progress timer back to 100% if necessary. This prevents - // parts of the fade-out animation to be skipped. - RewindLoadingProgressTimerIfNecessary(1.0f); } if (network_state_ == TabNetworkState::kWaiting) { @@ -480,15 +481,23 @@ SchedulePaint(); } - // The loading progress looks really weird if it ever jumps backwards, so make - // sure it only increases. - if (network_state_ == TabNetworkState::kLoading && - target_loading_progress_ < load_progress) { - DCHECK(loading_progress_timer_); + if (network_state_ == TabNetworkState::kLoading) { + // Interpolate loading progress to a narrower range to prevent us from + // looking stuck doing nothing at 0% or at 100% but still not finishing. + constexpr float kLoadingProgressStart = 0.3; + constexpr float kLoadingProgressEnd = 0.7; + load_progress = + kLoadingProgressStart + + load_progress * (kLoadingProgressEnd - kLoadingProgressStart); - RewindLoadingProgressTimerIfNecessary(target_loading_progress_); + // The loading progress looks really weird if it ever jumps backwards, so + // make sure it only increases. + if (target_loading_progress_ < load_progress) { + DCHECK(loading_progress_timer_); - target_loading_progress_ = load_progress; + RewindLoadingProgressTimerIfNecessary(target_loading_progress_); + target_loading_progress_ = load_progress; + } } }
diff --git a/chrome/browser/ui/views/tabs/tab_icon.h b/chrome/browser/ui/views/tabs/tab_icon.h index dd7379e..f4b439cd 100644 --- a/chrome/browser/ui/views/tabs/tab_icon.h +++ b/chrome/browser/ui/views/tabs/tab_icon.h
@@ -72,7 +72,7 @@ base::TimeDelta elapsed_time; double loading_progress; SkAlpha loading_progress_alpha; - SkAlpha favicon_alpha; + double favicon_fade_in_progress; }; // views::View:
diff --git a/chrome/browser/ui/views/tabs/tab_unittest.cc b/chrome/browser/ui/views/tabs/tab_unittest.cc index 101f67cd..f7654ea 100644 --- a/chrome/browser/ui/views/tabs/tab_unittest.cc +++ b/chrome/browser/ui/views/tabs/tab_unittest.cc
@@ -718,17 +718,22 @@ data.network_state = TabNetworkState::kLoading; data.load_progress = 0.2; tab.SetData(data); - EXPECT_FLOAT_EQ(0.2, GetLoadingProgress(icon)); + float initial_reported_progress = GetLoadingProgress(icon); + // Reported progress should interpolate to something between itself and 1.0. + EXPECT_GE(initial_reported_progress, 0.2); + EXPECT_LT(initial_reported_progress, 1.0); // Decrease load progress, icon's load progress should not change. data.load_progress = 0.1; tab.SetData(data); - EXPECT_FLOAT_EQ(0.2, GetLoadingProgress(icon)); + EXPECT_FLOAT_EQ(initial_reported_progress, GetLoadingProgress(icon)); // Though increasing it should be respected. data.load_progress = 0.5; tab.SetData(data); - EXPECT_FLOAT_EQ(0.5, GetLoadingProgress(icon)); + // A higher load progress should be interpolate to larger value (less than 1). + EXPECT_GT(GetLoadingProgress(icon), initial_reported_progress); + EXPECT_LT(GetLoadingProgress(icon), 1.0); } TEST_F(TabTest, LoadingProgressGoesTo100PercentAfterLoadingIsDone) { @@ -745,7 +750,9 @@ data.network_state = TabNetworkState::kLoading; data.load_progress = 0.2; tab.SetData(data); - EXPECT_FLOAT_EQ(0.2, GetLoadingProgress(icon)); + // Reported progress should interpolate to something between itself and 1.0. + EXPECT_GE(GetLoadingProgress(icon), 0.2); + EXPECT_LT(GetLoadingProgress(icon), 1.0); // Finish loading. Regardless of reported |data.load_progress|, load_progress // should be drawn at 100%.
diff --git a/chrome/browser/ui/views/toolbar/toolbar_view.cc b/chrome/browser/ui/views/toolbar/toolbar_view.cc index bae1555..999a6eb1 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_view.cc +++ b/chrome/browser/ui/views/toolbar/toolbar_view.cc
@@ -755,6 +755,10 @@ return this; } +views::View* ToolbarView::GetAnchorView() { + return location_bar_; +} + BrowserRootView::DropIndex ToolbarView::GetDropIndex( const ui::DropTargetEvent& event) { return {browser_->tab_strip_model()->active_index(), false};
diff --git a/chrome/browser/ui/views/toolbar/toolbar_view.h b/chrome/browser/ui/views/toolbar/toolbar_view.h index 6a89142..23b8a08 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_view.h +++ b/chrome/browser/ui/views/toolbar/toolbar_view.h
@@ -214,6 +214,7 @@ gfx::Rect GetFindBarBoundingBox(int contents_height) const override; void FocusToolbar() override; views::AccessiblePaneView* GetAsAccessiblePaneView() override; + views::View* GetAnchorView() override; // BrowserRootView::DropTarget BrowserRootView::DropIndex GetDropIndex(
diff --git a/chrome/browser/ui/webui/media_router/media_router_ui.cc b/chrome/browser/ui/webui/media_router/media_router_ui.cc index dbf07ce..0f8cf09 100644 --- a/chrome/browser/ui/webui/media_router/media_router_ui.cc +++ b/chrome/browser/ui/webui/media_router/media_router_ui.cc
@@ -102,7 +102,7 @@ base::Optional<RouteParameters> params = GetRouteParameters(sink_id, MediaCastMode::PRESENTATION); if (!params) { - SendIssueForUnableToCast(MediaCastMode::PRESENTATION); + SendIssueForUnableToCast(MediaCastMode::PRESENTATION, sink_id); return false; } GetIssueManager()->ClearNonBlockingIssues(); @@ -315,8 +315,6 @@ route_request_id, sink_id, cast_mode, presentation_request_source_name, result); handler_->OnCreateRouteResponseReceived(sink_id, result.route()); - if (result.result_code() == RouteRequestResult::TIMED_OUT) - SendIssueForRouteTimeout(cast_mode, presentation_request_source_name); } void MediaRouterUI::HandleCreateSessionRequestRouteResponse(
diff --git a/chrome/renderer/net/net_error_helper.cc b/chrome/renderer/net/net_error_helper.cc index cd688e7..0559e8909 100644 --- a/chrome/renderer/net/net_error_helper.cc +++ b/chrome/renderer/net/net_error_helper.cc
@@ -424,12 +424,8 @@ void NetErrorHelper::LoadErrorPage(const std::string& html, const GURL& failed_url) { - render_frame()->GetWebFrame()->CommitDataNavigation( - blink::WebURLRequest(GURL(kUnreachableWebDataURL)), blink::WebData(html), - blink::WebString::FromUTF8("text/html"), - blink::WebString::FromUTF8("UTF-8"), failed_url, - blink::WebFrameLoadType::kReplaceCurrentItem, blink::WebHistoryItem(), - false /* is_client_redirect */, nullptr, nullptr); + render_frame()->LoadHTMLString(html, GURL(kUnreachableWebDataURL), "UTF-8", + failed_url, true /* replace_current_item */); } void NetErrorHelper::EnablePageHelperFunctions(net::Error net_error) {
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index ff8e634..8b234a101 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -470,7 +470,6 @@ "//ui/file_manager/gallery/", "//ui/file_manager/image_loader/", "//ui/file_manager/integration_tests/", - "//third_party/analytics/", "//third_party/polymer/v1_0/components-chromium/polymer/", "$root_gen_dir/ui/file_manager/file_manager/", "$root_gen_dir/ui/login/login_resources.pak", @@ -2357,7 +2356,6 @@ # TODO(newt): move this to test_support_unit? "../browser/android/chrome_backup_agent_unittest.cc", - "../browser/android/crash/crash_keys_android_unittest.cc", "../browser/android/customtabs/detached_resource_request_unittest.cc", "../browser/android/favicon_helper_unittest.cc", "../browser/android/mock_location_settings.cc", @@ -4828,6 +4826,7 @@ "//third_party/libpng", "//third_party/zlib", "//ui/base:test_support", + "//ui/events:events_interactive_ui_tests", "//ui/resources:ui_test_pak", "//ui/web_dialogs:test_support", ] @@ -5793,12 +5792,13 @@ fuzzer_test("tts_platform_fuzzer") { sources = [ "../browser/speech/mock_tts_controller.cc", - "../browser/speech/tts_controller.h", "../browser/speech/tts_mac.mm", - "../browser/speech/tts_platform.cc", "../browser/speech/tts_platform.h", "../browser/speech/tts_platform_fuzzer.cc", + "../browser/speech/tts_platform_impl.cc", + "../browser/speech/tts_platform_impl.h", "../browser/speech/tts_win.cc", + "../content/public/browser/tts_controller.h", ] deps = [
diff --git a/chrome/test/base/test_browser_window.cc b/chrome/test/base/test_browser_window.cc index 7b9116b..568caec 100644 --- a/chrome/test/base/test_browser_window.cc +++ b/chrome/test/base/test_browser_window.cc
@@ -137,7 +137,7 @@ } PageActionIconContainer* TestBrowserWindow::GetPageActionIconContainer() { - return nullptr; + return &page_action_icon_container_; } ToolbarActionsBar* TestBrowserWindow::GetToolbarActionsBar() {
diff --git a/chrome/test/base/test_browser_window.h b/chrome/test/base/test_browser_window.h index d8d87490..b5beaab6 100644 --- a/chrome/test/base/test_browser_window.h +++ b/chrome/test/base/test_browser_window.h
@@ -194,7 +194,6 @@ void FocusLocation(bool select_all) override {} void FocusSearch() override {} void UpdateContentSettingsIcons() override {} - void UpdateManagePasswordsIconAndBubble() override {} void UpdateSaveCreditCardIcon() override {} void UpdateLocalCardMigrationIcon() override {} void UpdateBookmarkStarVisibility() override {} @@ -208,8 +207,21 @@ DISALLOW_COPY_AND_ASSIGN(TestLocationBar); }; + class TestPageActionIconContainer : public PageActionIconContainer { + public: + TestPageActionIconContainer() {} + ~TestPageActionIconContainer() override {} + + // PageActionIconContainer: + void UpdatePageActionIcon(PageActionIconType type) override {} + + private: + DISALLOW_COPY_AND_ASSIGN(TestPageActionIconContainer); + }; + TestDownloadShelf download_shelf_; TestLocationBar location_bar_; + TestPageActionIconContainer page_action_icon_container_; DISALLOW_COPY_AND_ASSIGN(TestBrowserWindow); };
diff --git a/chrome/test/data/webui/print_preview/destination_select_test.js b/chrome/test/data/webui/print_preview/destination_select_test.js index cf69324..d775850 100644 --- a/chrome/test/data/webui/print_preview/destination_select_test.js +++ b/chrome/test/data/webui/print_preview/destination_select_test.js
@@ -12,6 +12,7 @@ DefaultDestinationSelectionRules: 'default destination selection rules', SystemDefaultPrinterPolicy: 'system default printer policy', KioskModeSelectsFirstPrinter: 'kiosk mode selects first printer', + NoPrintersShowsError: 'no printers shows error', }; const suiteName = 'DestinationSelectTests'; @@ -42,10 +43,13 @@ /* * Sets the initial settings to the stored value and creates the page. - * @return {!Promise} Promise that resolves when initial settings and - * printer capabilities have been returned. + * @param {boolean=} opt_expectPrinterFailure Whether printer fetch is + * expected to fail + * @return {!Promise} Promise that resolves when initial settings and, + * if printer failure is not expected, printer capabilities have + * been returned. */ - function setInitialSettings() { + function setInitialSettings(opt_expectPrinterFailure) { nativeLayer.setInitialSettings(initialSettings); nativeLayer.setLocalDestinations(localDestinations); print_preview.NativeLayer.setInstance(nativeLayer); @@ -53,10 +57,10 @@ page = document.createElement('print-preview-app'); document.body.appendChild(page); - return Promise.all([ - nativeLayer.whenCalled('getInitialSettings'), - nativeLayer.whenCalled('getPrinterCapabilities') - ]); + const promises = [nativeLayer.whenCalled('getInitialSettings')]; + if (!opt_expectPrinterFailure) + promises.push(nativeLayer.whenCalled('getPrinterCapabilities')); + return Promise.all(promises); } /** @@ -247,6 +251,38 @@ assertPrinterDisplay(destinations[0].displayName); }); }); + + /** + * Tests that if there is no system default destination, the default + * selection rules and recent destinations are empty, the preview + * is in app kiosk mode (so no PDF printer), and there are no + * destinations found, the no destinations found error is displayed. + */ + test(assert(TestNames.NoPrintersShowsError), function() { + initialSettings.serializedDefaultDestinationSelectionRulesStr = ''; + initialSettings.serializedAppStateStr = ''; + initialSettings.isInAppKioskMode = true; + initialSettings.printerName = ''; + localDestinations = []; + + return Promise + .all([ + setInitialSettings(true), + test_util.eventToPromise( + print_preview.DestinationStore.EventType.NO_DESTINATIONS_FOUND, + page.destinationStore_), + ]) + .then(function() { + assertEquals(undefined, page.destination_); + const destinationSettings = + page.$$('print-preview-destination-settings'); + assertTrue(destinationSettings.$$('.throbber-container').hidden); + assertTrue( + destinationSettings.$$('.destination-settings-box').hidden); + assertFalse( + destinationSettings.$$('.no-destinations-display').hidden); + }); + }); }); return {
diff --git a/chrome/test/data/webui/print_preview/destination_settings_test.js b/chrome/test/data/webui/print_preview/destination_settings_test.js index 70c7e30..b94cb19 100644 --- a/chrome/test/data/webui/print_preview/destination_settings_test.js +++ b/chrome/test/data/webui/print_preview/destination_settings_test.js
@@ -20,9 +20,10 @@ print_preview.NativeLayer.setInstance(nativeLayer); destinationSettings = document.createElement('print-preview-destination-settings'); - destinationSettings.disabled = false; destinationSettings.destinationStore = null; destinationSettings.state = print_preview_new.State.NOT_READY; + // Disabled is true when state is NOT_READY. + destinationSettings.disabled = true; document.body.appendChild(destinationSettings); }); @@ -33,8 +34,8 @@ // Initial state: No destination store, button should be disabled. assertTrue(button.disabled); - // Set up the destination store, but no destination yet. Button is now - // enabled. + // Set up the destination store, but no destination yet. Button is + // disabled. const userInfo = new print_preview.UserInfo(); const destinationStore = new print_preview.DestinationStore( userInfo, new WebUIListenerTracker()); @@ -44,7 +45,7 @@ [] /* recentDestinations */); destinationSettings.destinationStore = destinationStore; destinationSettings.state = print_preview_new.State.NOT_READY; - assertFalse(button.disabled); + assertTrue(button.disabled); // Simulate loading a destination and setting state to ready. The button // is still enabled. @@ -53,6 +54,7 @@ print_preview.DestinationOrigin.LOCAL, 'FooName', true /* isRecent */, print_preview.DestinationConnectionStatus.ONLINE); destinationSettings.state = print_preview_new.State.READY; + destinationSettings.disabled = false; assertFalse(button.disabled); // Simulate setting a setting to an invalid value. Button is disabled due @@ -68,6 +70,13 @@ destinationSettings.state = print_preview_new.State.INVALID_PRINTER; destinationSettings.disabled = true; assertFalse(button.disabled); + + // Simulate the user having no printers. + destinationSettings.destination = null; + destinationSettings.state = print_preview_new.State.INVALID_PRINTER; + destinationSettings.disabled = true; + destinationSettings.noDestinationsFound = true; + assertTrue(button.disabled); }); });
diff --git a/chrome/test/data/webui/print_preview/native_layer_stub.js b/chrome/test/data/webui/print_preview/native_layer_stub.js index 4b9f366..c06ca7c 100644 --- a/chrome/test/data/webui/print_preview/native_layer_stub.js +++ b/chrome/test/data/webui/print_preview/native_layer_stub.js
@@ -87,7 +87,8 @@ /** @override */ getPrinters(type) { this.methodCalled('getPrinters', type); - if (type == print_preview.PrinterType.LOCAL_PRINTER) { + if (type == print_preview.PrinterType.LOCAL_PRINTER && + this.localDestinationInfos_.length > 0) { cr.webUIListenerCallback( 'printers-added', type, this.localDestinationInfos_); } else if (
diff --git a/chrome/test/data/webui/print_preview/new_print_preview_ui_browsertest.js b/chrome/test/data/webui/print_preview/new_print_preview_ui_browsertest.js index a8f19dc..65d9a5670 100644 --- a/chrome/test/data/webui/print_preview/new_print_preview_ui_browsertest.js +++ b/chrome/test/data/webui/print_preview/new_print_preview_ui_browsertest.js
@@ -618,6 +618,7 @@ /** @override */ get extraLibraries() { return super.extraLibraries.concat([ + '../settings/test_util.js', '../test_browser_proxy.js', 'native_layer_stub.js', 'print_preview_test_utils.js', @@ -675,6 +676,12 @@ destination_select_test.TestNames.KioskModeSelectsFirstPrinter); }); +GEN('#if defined(OS_CHROMEOS)'); +TEST_F('PrintPreviewDestinationSelectTest', 'NoPrintersShowsError', function() { + this.runMochaTest(destination_select_test.TestNames.NoPrintersShowsError); +}); +GEN('#endif'); + PrintPreviewDestinationDialogTest = class extends NewPrintPreviewTest { /** @override */ get browsePreload() {
diff --git a/chrome/test/media_router/media_router_base_browsertest.cc b/chrome/test/media_router/media_router_base_browsertest.cc index 3e6d7f4..03145cd5 100644 --- a/chrome/test/media_router/media_router_base_browsertest.cc +++ b/chrome/test/media_router/media_router_base_browsertest.cc
@@ -42,7 +42,7 @@ ParseCommandLine(); // The integration and E2E tests depend on the WebUI Cast dialog, so the Views // dialog must be disabled. - feature_list_.InitAndDisableFeature(features::kViewsCastDialog); + feature_list_.InitAndEnableFeature(features::kViewsCastDialog); ExtensionBrowserTest::SetUp(); }
diff --git a/chrome/test/media_router/media_router_e2e_browsertest.cc b/chrome/test/media_router/media_router_e2e_browsertest.cc index 275f4ad..1e616ec 100644 --- a/chrome/test/media_router/media_router_e2e_browsertest.cc +++ b/chrome/test/media_router/media_router_e2e_browsertest.cc
@@ -81,7 +81,7 @@ observer_.reset(new TestMediaSinksObserver(media_router_, source, origin)); observer_->Init(); - DVLOG(1) << "Receiver name: " << receiver(); + DVLOG(1) << "Receiver name: " << receiver_; // Wait for MediaSinks compatible with |source| to be discovered. ASSERT_TRUE(ConditionalWait( base::TimeDelta::FromSeconds(30), base::TimeDelta::FromSeconds(1), @@ -89,7 +89,7 @@ base::Unretained(this)))); const auto& sink_map = observer_->sink_map; - const auto it = sink_map.find(receiver()); + const auto it = sink_map.find(receiver_); const MediaSink& sink = it->second; // The callback will set route_id_ when invoked. @@ -112,7 +112,7 @@ } bool MediaRouterE2EBrowserTest::IsSinkDiscovered() const { - return base::ContainsKey(observer_->sink_map, receiver()); + return base::ContainsKey(observer_->sink_map, receiver_); } bool MediaRouterE2EBrowserTest::IsRouteCreated() const {
diff --git a/chrome/test/media_router/media_router_e2e_ui_browsertest.cc b/chrome/test/media_router/media_router_e2e_ui_browsertest.cc index 902b08aa..1c5191d 100644 --- a/chrome/test/media_router/media_router_e2e_ui_browsertest.cc +++ b/chrome/test/media_router/media_router_e2e_ui_browsertest.cc
@@ -29,22 +29,15 @@ content::WebContents* web_contents = browser()->tab_strip_model()->GetActiveWebContents(); - content::WebContents* dialog_contents = OpenMRDialog(web_contents); - ASSERT_TRUE(dialog_contents); - // Wait util the dialog finishes rendering. - WaitUntilDialogFullyLoaded(dialog_contents); - - // Get the media router UI - MediaRouterUI* media_router_ui = GetMediaRouterUI(dialog_contents); + test_ui_->ShowDialog(); + test_ui_->WaitForSinkAvailable(receiver_); // Mock out file dialog operations, as those can't be simulated. - FileDialogSelectsFile(media_router_ui, file_url); - // Open the Cast mode list. - ClickHeader(dialog_contents); + FileDialogSelectsFile(file_url); // Click on the desired mode. - ClickCastMode(dialog_contents, MediaCastMode::LOCAL_FILE); - WaitUntilSinkDiscoveredOnUI(); - ChooseSink(web_contents, receiver()); + test_ui_->ChooseSourceType(CastDialogView::kLocalFile); + test_ui_->WaitForSinkAvailable(receiver_); + test_ui_->StartCasting(receiver_); // Play the file for 10 seconds. Wait(base::TimeDelta::FromSeconds(10)); @@ -61,9 +54,8 @@ &is_fullscreen)); ASSERT_TRUE(is_fullscreen); - if (IsDialogClosed(web_contents)) - OpenMRDialog(web_contents); - CloseRouteOnUI(); + test_ui_->WaitForSink(receiver_); + test_ui_->StopCasting(receiver_); // Wait 15s for Chromecast to back to home screen and ready to use status. Wait(base::TimeDelta::FromSeconds(15)); } @@ -71,23 +63,18 @@ IN_PROC_BROWSER_TEST_F(MediaRouterE2EBrowserTest, MANUAL_MirrorHTML5Video) { content::WebContents* web_contents = browser()->tab_strip_model()->GetActiveWebContents(); - - content::WebContents* dialog_contents = OpenMRDialog(web_contents); - ASSERT_TRUE(dialog_contents); + test_ui_ = MediaRouterUiForTest::GetOrCreateForWebContents(web_contents); + test_ui_->ShowDialog(); // Wait until the dialog finishes rendering. - WaitUntilDialogFullyLoaded(dialog_contents); - WaitUntilSinkDiscoveredOnUI(); - ChooseSink(web_contents, receiver()); + test_ui_->WaitForSinkAvailable(receiver_); + test_ui_->StartCasting(receiver_); // Mirror tab for 10s. Wait(base::TimeDelta::FromSeconds(10)); - if (IsDialogClosed(web_contents)) - dialog_contents = OpenMRDialog(web_contents); - WaitUntilDialogFullyLoaded(dialog_contents); // Check the mirroring session has started successfully. - ASSERT_TRUE(!GetRouteId(receiver()).empty()); + ASSERT_FALSE(test_ui_->GetRouteIdForSink(receiver_).empty()); OpenMediaPage(); // Play the video on loop and wait 5s for it to play smoothly. @@ -101,16 +88,18 @@ "webkitRequestFullScreen();"; ExecuteScript(web_contents, script); Wait(base::TimeDelta::FromSeconds(5)); - if (IsDialogClosed(web_contents)) - dialog_contents = OpenMRDialog(web_contents); - WaitUntilDialogFullyLoaded(dialog_contents); + if (!test_ui_->IsDialogShown()) + test_ui_->ShowDialog(); // Check the mirroring session is still live. - ASSERT_TRUE(!GetRouteId(receiver()).empty()); + ASSERT_FALSE(test_ui_->GetRouteIdForSink(receiver_).empty()); Wait(base::TimeDelta::FromSeconds(20)); - if (IsDialogClosed(web_contents)) - OpenMRDialog(web_contents); - CloseRouteOnUI(); + if (!test_ui_->IsDialogShown()) + test_ui_->ShowDialog(); + test_ui_->WaitForSink(receiver_); + test_ui_->StopCasting(receiver_); + test_ui_->WaitUntilNoRoutes(); + test_ui_->HideDialog(); } } // namespace media_router
diff --git a/chrome/test/media_router/media_router_integration_browsertest.cc b/chrome/test/media_router/media_router_integration_browsertest.cc index 6c48cea..f228c411 100644 --- a/chrome/test/media_router/media_router_integration_browsertest.cc +++ b/chrome/test/media_router/media_router_integration_browsertest.cc
@@ -16,14 +16,11 @@ #include "base/threading/thread_restrictions.h" #include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" -#include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/media_router/media_cast_mode.h" #include "chrome/browser/ui/media_router/media_router_file_dialog.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/views/frame/browser_view.h" -#include "chrome/browser/ui/webui/media_router/media_router_dialog_controller_webui_impl.h" -#include "chrome/browser/ui/webui/media_router/media_router_ui.h" #include "chrome/common/media_router/issue.h" #include "chrome/common/url_constants.h" #include "chrome/test/base/ui_test_utils.h" @@ -63,66 +60,6 @@ "sendMessageAndExpectResponse('%s');"; const char kSendMessageAndExpectConnectionCloseOnErrorScript[] = "sendMessageAndExpectConnectionCloseOnError()"; -const char kChooseSinkScript[] = - "var sinks = Array.from(document.getElementById('media-router-container')." - " shadowRoot.getElementById('sink-list').getElementsByTagName('span'));" - "var sink = sinks.find(sink => sink.textContent.trim() == '%s');" - "if (sink) {" - " sink.click();" - "}"; -const char kClickCastModeScript[] = - "var mediaRouterContainer =" - " document.getElementById('media-router-container');" - "var modes = Array.from(mediaRouterContainer" - " .shadowRoot" - " .getElementById('cast-mode-list')" - " .getElementsByTagName('span'));" - "var mode = modes.find(mode => {" - " return mode.textContent.trim() == mediaRouterContainer" - " .castModeList.find(mode => mode.type == %d).description;" - " });" - "if (mode) {" - " mode.click();" - "}"; -const char kCloseRouteScript[] = - "window.document.getElementById('media-router-container').shadowRoot." - " getElementById('route-details').shadowRoot.getElementById(" - " 'close-route-button').click()"; -const char kClickDialog[] = - "window.document.getElementById('media-router-container').click();"; -const char kClickHeader[] = - "window.document.getElementById('media-router-container').shadowRoot" - ".getElementById('container-header').shadowRoot" - ".getElementById('header-text').click();"; -const char kGetSinkIdScript[] = - "var sinks = window.document.getElementById('media-router-container')." - " allSinks;" - "var sink = sinks.find(sink => sink.name == '%s');" - "window.domAutomationController.send(sink ? sink.id : '');"; -const char kGetRouteIdScript[] = - "var routes = window.document.getElementById('media-router-container')." - " routeList;" - "var route = routes.find(route => route.sinkId == '%s');" - "window.domAutomationController.send(route ? route.id : '');"; -const char kFindSinkScript[] = - "var sinkList = document.getElementById('media-router-container')." - " shadowRoot.getElementById('sink-list');" - "if (!sinkList) {" - " window.domAutomationController.send(false);" - "} else {" - " var sinks = Array.from(sinkList.getElementsByTagName('span'));" - " var result = sinks.some(sink => sink.textContent.trim() == '%s');" - " window.domAutomationController.send(result);" - "}"; -const char kCheckDialogLoadedScript[] = - "var container = document.getElementById('media-router-container');" - "/** Wait until media router container is not undefined and " - "* deviceMissingUrl is not undefined, " - "* once deviceMissingUrl is not undefined, which means " - "* the dialog is fully loaded." - "*/" - "window.domAutomationController.send(!!container && " - " !!container.deviceMissingUrl);"; std::string GetStartedConnectionId(WebContents* web_contents) { std::string session_id; @@ -141,7 +78,7 @@ return session_id; } -// File Dialog which fails on open +// File Dialog which fails on open. class TestFailMediaRouterFileDialog : public MediaRouterFileDialog { public: TestFailMediaRouterFileDialog(MediaRouterFileDialogDelegate* delegate, @@ -193,6 +130,13 @@ policy::BrowserPolicyConnector::SetPolicyProviderForTesting(&provider_); } +void MediaRouterIntegrationBrowserTest::SetUpOnMainThread() { + MediaRouterBaseBrowserTest::SetUpOnMainThread(); + // Dialogs created while MediaRouterUiForTest exists will not close on blur. + test_ui_ = + MediaRouterUiForTest::GetOrCreateForWebContents(GetActiveWebContents()); +} + void MediaRouterIntegrationBrowserTest::ExecuteJavaScriptAPI( WebContents* web_contents, const std::string& script) { @@ -221,11 +165,11 @@ OpenTestPage(FILE_PATH_LITERAL("basic_test.html")); WebContents* web_contents = GetActiveWebContents(); CHECK(web_contents); - StartSession(web_contents); + ExecuteJavaScriptAPI(web_contents, kStartSessionScript); - // Wait for any sinks to be displayed. + // Wait to simulate the user waiting for any sinks to be displayed. Wait(base::TimeDelta::FromSeconds(1)); - GetControllerForShownDialog(web_contents)->HideMediaRouterDialog(); + test_ui_->HideDialog(); CheckStartFailed(web_contents, "NotFoundError", "No screens found."); } @@ -235,19 +179,20 @@ WebContents* web_contents = GetActiveWebContents(); CHECK(web_contents); ExecuteJavaScriptAPI(web_contents, kWaitSinkScript); - StartSession(web_contents); + ExecuteJavaScriptAPI(web_contents, kStartSessionScript); + test_ui_->WaitForDialogShown(); return web_contents; } WebContents* MediaRouterIntegrationBrowserTest::StartSessionWithTestPageAndChooseSink() { WebContents* web_contents = StartSessionWithTestPageAndSink(); - WaitUntilSinkDiscoveredOnUI(); - ChooseSink(web_contents, receiver_); + test_ui_->WaitForSinkAvailable(receiver_); + test_ui_->StartCasting(receiver_); + // TODO(takumif): Remove the HideDialog() call once the dialog can close + // itself automatically after casting. + test_ui_->HideDialog(); - // Wait a few seconds for MediaRouter to receive updates containing the - // created route. - Wait(base::TimeDelta::FromSeconds(3)); return web_contents; } @@ -258,22 +203,15 @@ : SetTestData(FILE_PATH_LITERAL("local_media_sink_route_fail.json")); GURL file_url = net::FilePathToFileURL( media::GetTestDataFilePath("butterfly-853x480.webm")); - // Open the dialog, waits for it to load - WebContents* dialog_contents = OpenMRDialog(GetActiveWebContents()); - // Get the media router UI - MediaRouterUI* media_router_ui = GetMediaRouterUI(dialog_contents); + test_ui_->ShowDialog(); // Mock out file dialog operations, as those can't be simulated. - FileDialogSelectsFile(media_router_ui, file_url); - // Open the Cast mode list. - ClickHeader(dialog_contents); + FileDialogSelectsFile(file_url); // Click on the desired mode. - ClickCastMode(dialog_contents, MediaCastMode::LOCAL_FILE); + test_ui_->ChooseSourceType(CastDialogView::kLocalFile); // Wait for the sinks to load. - WaitUntilSinkDiscoveredOnUI(); + test_ui_->WaitForSinkAvailable(receiver_); // Click on sink. - ChooseSink(GetActiveWebContents(), receiver_); - // Give casting a few seconds to go through. - Wait(base::TimeDelta::FromSeconds(3)); + test_ui_->StartCasting(receiver_); // Expect that the current tab has the file open in it. ASSERT_EQ(file_url, GetActiveWebContents()->GetURL()); } @@ -282,18 +220,13 @@ SetTestData(FILE_PATH_LITERAL("local_media_sink.json")); GURL file_url = net::FilePathToFileURL( media::GetTestDataFilePath("butterfly-853x480.webm")); - // Open the dialog, waits for it to load - WebContents* dialog_contents = OpenMRDialog(GetActiveWebContents()); - // Get the media router UI - MediaRouterUI* media_router_ui = GetMediaRouterUI(dialog_contents); + test_ui_->ShowDialog(); // Mock out file dialog opperations, as those can't be simulated. - FileDialogSelectFails(media_router_ui, IssueInfo()); - // Open the Cast mode list. - ClickHeader(dialog_contents); + FileDialogSelectFails(IssueInfo()); // Click on the desired mode. - ClickCastMode(dialog_contents, MediaCastMode::LOCAL_FILE); + test_ui_->ChooseSourceType(CastDialogView::kLocalFile); // Wait for the issue to appear. - WaitUntilIssue(); + test_ui_->WaitForAnyIssue(); } void MediaRouterIntegrationBrowserTest::OpenTestPage( @@ -309,6 +242,10 @@ browser(), GetTestPageUrl(full_path), WindowOpenDisposition::NEW_FOREGROUND_TAB, ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); + // Opening a new tab creates new WebContents, so we must re-configure the + // test UI for it. + test_ui_ = + MediaRouterUiForTest::GetOrCreateForWebContents(GetActiveWebContents()); } GURL MediaRouterIntegrationBrowserTest::GetTestPageUrl( @@ -316,34 +253,6 @@ return net::FilePathToFileURL(full_path); } -void MediaRouterIntegrationBrowserTest::StartSession( - WebContents* web_contents) { - test_navigation_observer_.reset( - new content::TestNavigationObserver(web_contents, 1)); - test_navigation_observer_->StartWatchingNewWebContents(); - ExecuteJavaScriptAPI(web_contents, kStartSessionScript); - test_navigation_observer_->Wait(); - test_navigation_observer_->StopWatchingNewWebContents(); -} - -void MediaRouterIntegrationBrowserTest::ChooseSink( - WebContents* web_contents, - const std::string& sink_name) { - WebContents* dialog_contents = GetMRDialog(web_contents); - std::string script = base::StringPrintf( - kChooseSinkScript, sink_name.c_str()); - // Execute javascript to choose sink, but don't wait until it finishes. - dialog_contents->GetMainFrame()->ExecuteJavaScriptWithUserGestureForTests( - base::UTF8ToUTF16(script)); -} - -void MediaRouterIntegrationBrowserTest::ClickCastMode( - WebContents* dialog_contents, - MediaCastMode mode) { - std::string script = base::StringPrintf(kClickCastModeScript, mode); - ASSERT_TRUE(content::ExecuteScript(dialog_contents, script)); -} - void MediaRouterIntegrationBrowserTest::CheckStartFailed( WebContents* web_contents, const std::string& error_name, @@ -354,52 +263,6 @@ ExecuteJavaScriptAPI(web_contents, script); } -void MediaRouterIntegrationBrowserTest::ClickDialog() { - WebContents* web_contents = GetActiveWebContents(); - WebContents* dialog_contents = GetMRDialog(web_contents); - ASSERT_TRUE(content::ExecuteScript(dialog_contents, kClickDialog)); -} - -void MediaRouterIntegrationBrowserTest::ClickHeader( - WebContents* dialog_contents) { - ASSERT_TRUE(content::ExecuteScript(dialog_contents, kClickHeader)); -} - -WebContents* MediaRouterIntegrationBrowserTest::GetMRDialog( - WebContents* web_contents) { - MediaRouterDialogControllerWebUIImpl* controller = - MediaRouterDialogControllerWebUIImpl::GetOrCreateForWebContents( - web_contents); - WebContents* dialog_contents = controller->GetMediaRouterDialog(); - CHECK(dialog_contents); - WaitUntilDialogFullyLoaded(dialog_contents); - return dialog_contents; -} - -bool MediaRouterIntegrationBrowserTest::IsDialogClosed( - WebContents* web_contents) { - MediaRouterDialogControllerWebUIImpl* controller = - MediaRouterDialogControllerWebUIImpl::GetOrCreateForWebContents( - web_contents); - return !controller->GetMediaRouterDialog(); -} - -void MediaRouterIntegrationBrowserTest::WaitUntilDialogClosed( - WebContents* web_contents) { - ASSERT_TRUE(ConditionalWait( - base::TimeDelta::FromSeconds(5), base::TimeDelta::FromSeconds(1), - base::Bind(&MediaRouterIntegrationBrowserTest::IsDialogClosed, - base::Unretained(this), web_contents))); -} - -void MediaRouterIntegrationBrowserTest::CheckDialogRemainsOpen( - WebContents* web_contents) { - ASSERT_FALSE(ConditionalWait( - base::TimeDelta::FromSeconds(5), base::TimeDelta::FromSeconds(1), - base::Bind(&MediaRouterIntegrationBrowserTest::IsDialogClosed, - base::Unretained(this), web_contents))); -} - void MediaRouterIntegrationBrowserTest::SetTestData( base::FilePath::StringPieceType test_data_file) { base::FilePath full_path = GetResourceFile(test_data_file); @@ -421,23 +284,6 @@ test_data_str.c_str())); } -WebContents* MediaRouterIntegrationBrowserTest::OpenMRDialog( - WebContents* web_contents) { - MediaRouterDialogControllerWebUIImpl* controller = - MediaRouterDialogControllerWebUIImpl::GetOrCreateForWebContents( - web_contents); - test_navigation_observer_.reset( - new content::TestNavigationObserver(web_contents, 1)); - test_navigation_observer_->StartWatchingNewWebContents(); - CHECK(controller->ShowMediaRouterDialog()); - test_navigation_observer_->Wait(); - test_navigation_observer_->StopWatchingNewWebContents(); - WebContents* dialog_contents = controller->GetMediaRouterDialog(); - CHECK(dialog_contents); - WaitUntilDialogFullyLoaded(dialog_contents); - return dialog_contents; -} - base::FilePath MediaRouterIntegrationBrowserTest::GetResourceFile( base::FilePath::StringPieceType relative_path) const { base::FilePath base_dir; @@ -481,110 +327,22 @@ } bool MediaRouterIntegrationBrowserTest::IsRouteCreatedOnUI() { - return !GetRouteId(receiver()).empty(); -} - -std::string MediaRouterIntegrationBrowserTest::GetRouteId( - const std::string& sink_name) { - WebContents* web_contents = GetActiveWebContents(); - WebContents* dialog_contents = GetMRDialog(web_contents); - std::string script = base::StringPrintf(kGetSinkIdScript, sink_name.c_str()); - std::string sink_id = ExecuteScriptAndExtractString(dialog_contents, script); - DVLOG(0) << "sink id: " << sink_id; - script = base::StringPrintf(kGetRouteIdScript, sink_id.c_str()); - std::string route_id = ExecuteScriptAndExtractString(dialog_contents, script); - DVLOG(0) << "route id: " << route_id; - return route_id; -} - -void MediaRouterIntegrationBrowserTest::WaitUntilRouteCreated() { - ASSERT_TRUE(ConditionalWait( - base::TimeDelta::FromSeconds(10), base::TimeDelta::FromSeconds(1), - base::Bind(&MediaRouterIntegrationBrowserTest::IsRouteCreatedOnUI, - base::Unretained(this)))); + return !test_ui_->GetRouteIdForSink(receiver_).empty(); } bool MediaRouterIntegrationBrowserTest::IsUIShowingIssue() { - WebContents* web_contents = GetActiveWebContents(); - WebContents* dialog_contents = GetMRDialog(web_contents); - std::string script = base::StringPrintf( - "domAutomationController.send(window.document.getElementById(" - "'media-router-container').issue != undefined)"); - bool has_issue = false; - CHECK(content::ExecuteScriptAndExtractBool(dialog_contents, script, - &has_issue)); - return has_issue; -} - -void MediaRouterIntegrationBrowserTest::WaitUntilIssue() { - ASSERT_TRUE(ConditionalWait( - base::TimeDelta::FromSeconds(30), base::TimeDelta::FromSeconds(1), - base::Bind(&MediaRouterIntegrationBrowserTest::IsUIShowingIssue, - base::Unretained(this)))); -} - -std::string MediaRouterIntegrationBrowserTest::GetIssueTitle() { - WebContents* web_contents = GetActiveWebContents(); - WebContents* dialog_contents = GetMRDialog(web_contents); - std::string script = base::StringPrintf( - "domAutomationController.send(window.document.getElementById(" - "'media-router-container').issue.title)"); - return ExecuteScriptAndExtractString(dialog_contents, script); + std::string issue_text = test_ui_->GetIssueTextForSink(receiver_); + return !issue_text.empty(); } bool MediaRouterIntegrationBrowserTest::IsRouteClosedOnUI() { // After execute js script to close route on UI, the dialog will dispear // after 3s. But sometimes it takes more than 3s to close the route, so // we need to re-open the dialog if it is closed. - WebContents* web_contents = GetActiveWebContents(); - MediaRouterDialogControllerWebUIImpl* controller = - MediaRouterDialogControllerWebUIImpl::GetOrCreateForWebContents( - web_contents); - WebContents* dialog_contents = controller->GetMediaRouterDialog(); - if (!dialog_contents) { - VLOG(0) << "Media router dialog was closed, reopen it again."; - OpenMRDialog(web_contents); - } - return GetRouteId(receiver()).empty(); -} - -void MediaRouterIntegrationBrowserTest::CloseRouteOnUI() { - WebContents* web_contents = GetActiveWebContents(); - WebContents* dialog_contents = GetMRDialog(web_contents); - ASSERT_TRUE(content::ExecuteScript(dialog_contents, kCloseRouteScript)); - ASSERT_TRUE(ConditionalWait( - base::TimeDelta::FromSeconds(10), base::TimeDelta::FromSeconds(1), - base::Bind(&MediaRouterIntegrationBrowserTest::IsRouteClosedOnUI, - base::Unretained(this)))); -} - -bool MediaRouterIntegrationBrowserTest::IsSinkDiscoveredOnUI() { - WebContents* web_contents = GetActiveWebContents(); - WebContents* dialog_contents = GetMRDialog(web_contents); - std::string script = base::StringPrintf(kFindSinkScript, receiver().c_str()); - return ExecuteScriptAndExtractBool(dialog_contents, script); -} - -void MediaRouterIntegrationBrowserTest::WaitUntilSinkDiscoveredOnUI() { - DVLOG(0) << "Receiver name: " << receiver_; - // Wait for sink to show up in UI. - ASSERT_TRUE(ConditionalWait( - base::TimeDelta::FromSeconds(30), base::TimeDelta::FromSeconds(1), - base::Bind(&MediaRouterIntegrationBrowserTest::IsSinkDiscoveredOnUI, - base::Unretained(this)))); -} - -bool MediaRouterIntegrationBrowserTest::IsDialogLoaded( - WebContents* dialog_contents) { - return ExecuteScriptAndExtractBool(dialog_contents, kCheckDialogLoadedScript); -} - -void MediaRouterIntegrationBrowserTest::WaitUntilDialogFullyLoaded( - WebContents* dialog_contents) { - ASSERT_TRUE(ConditionalWait( - base::TimeDelta::FromSeconds(30), base::TimeDelta::FromSeconds(1), - base::Bind(&MediaRouterIntegrationBrowserTest::IsDialogLoaded, - base::Unretained(this), dialog_contents))); + if (!test_ui_->IsDialogShown()) + test_ui_->ShowDialog(); + test_ui_->WaitForSink(receiver_); + return test_ui_->GetRouteIdForSink(receiver_).empty(); } void MediaRouterIntegrationBrowserTest::ParseCommandLine() { @@ -606,49 +364,26 @@ EXPECT_EQ(session_id, default_request_session_id); } -MediaRouterDialogControllerWebUIImpl* -MediaRouterIntegrationBrowserTest::GetControllerForShownDialog( - WebContents* web_contents) { - MediaRouterDialogControllerWebUIImpl* controller = - MediaRouterDialogControllerWebUIImpl::GetOrCreateForWebContents( - web_contents); - EXPECT_TRUE(controller->IsShowingMediaRouterDialog()); - return controller; -} - WebContents* MediaRouterIntegrationBrowserTest::GetActiveWebContents() { return browser()->tab_strip_model()->GetActiveWebContents(); } -MediaRouterUI* MediaRouterIntegrationBrowserTest::GetMediaRouterUI( - content::WebContents* dialog_contents) { - content::WebUI* web_ui = dialog_contents->GetWebUI(); - CHECK(web_ui) << "Error getting MediaRouterUI, no WebUI at all"; - return static_cast<MediaRouterUI*>(web_ui->GetController()); -} - -void MediaRouterIntegrationBrowserTest::FileDialogSelectsFile( - MediaRouterUI* media_router_ui, - GURL file_url) { - // Ensure that the media_router_ui is set - DCHECK(media_router_ui); - media_router_ui->InitForTest( - std::make_unique<TestMediaRouterFileDialog>(media_router_ui, file_url)); +void MediaRouterIntegrationBrowserTest::FileDialogSelectsFile(GURL file_url) { + // TODO(https://crbug.com/900248): Implement this. + NOTIMPLEMENTED(); } void MediaRouterIntegrationBrowserTest::FileDialogSelectFails( - MediaRouterUI* media_router_ui, const IssueInfo& issue) { - // Ensure that the media_router_ui is set - DCHECK(media_router_ui); - media_router_ui->InitForTest( - std::make_unique<TestFailMediaRouterFileDialog>(media_router_ui, issue)); + // TODO(https://crbug.com/900248): Implement this. + NOTIMPLEMENTED(); } void MediaRouterIntegrationBrowserTest::RunBasicTest() { WebContents* web_contents = StartSessionWithTestPageAndChooseSink(); CheckSessionValidity(web_contents); ExecuteJavaScriptAPI(web_contents, kTerminateSessionScript); + test_ui_->WaitUntilNoRoutes(); } void MediaRouterIntegrationBrowserTest::RunSendMessageTest( @@ -690,6 +425,7 @@ ASSERT_EQ(session_id, reconnected_session_id); ExecuteJavaScriptAPI(web_contents, kTerminateSessionScript); + test_ui_->WaitUntilNoRoutes(); } void MediaRouterIntegrationBrowserTest::SetEnableMediaRouter(bool enable) { @@ -698,8 +434,7 @@ policy::POLICY_SCOPE_USER, policy::POLICY_SOURCE_CLOUD, std::make_unique<base::Value>(enable), nullptr); provider_.UpdateChromePolicy(policy); - base::RunLoop loop; - loop.RunUntilIdle(); + base::RunLoop().RunUntilIdle(); } void MediaRouterIntegrationBrowserTest::RunReconnectSessionSameTabTest() { @@ -718,15 +453,14 @@ ASSERT_EQ(session_id, reconnected_session_id); } -// TODO(crbug.com/822337): Flaky on Linux_CFI bot. -IN_PROC_BROWSER_TEST_F(MediaRouterIntegrationBrowserTest, MANUAL_Basic) { +IN_PROC_BROWSER_TEST_F(MediaRouterIntegrationBrowserTest, Basic) { RunBasicTest(); } // Tests that creating a route with a local file opens the file in a new tab. -// TODO(crbug.com/818767): Fails when run with Chromium component. +// TODO(https://crbug.com/900248): Make this test pass with the Views dialog. IN_PROC_BROWSER_TEST_F(MediaRouterIntegrationBrowserTest, - MANUAL_OpenLocalMediaFileInCurrentTab) { + DISABLED_OpenLocalMediaFileInCurrentTab) { // Start at a new tab, the file should open in the same tab. ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUINewTabURL)); // Make sure there is 1 tab. @@ -737,20 +471,18 @@ // Expect that no new tab has been opened. ASSERT_EQ(1, browser()->tab_strip_model()->count()); - // Open the dialog again to check for a route. - OpenMRDialog(GetActiveWebContents()); + test_ui_->ShowDialog(); // Wait for a route to be created. - WaitUntilRouteCreated(); + test_ui_->WaitForAnyRoute(); } -// TODO(crbug.com/849216): Disabled due to crashes and timeouts. -// // Tests that creating a route with a local file opens the file in a new tab. +// TODO(https://crbug.com/900248): Make this test pass with the Views dialog. IN_PROC_BROWSER_TEST_F(MediaRouterIntegrationBrowserTest, DISABLED_OpenLocalMediaFileInNewTab) { // Start at a tab with content in it, the file will open in a new tab. - ui_test_utils::NavigateToURL(browser(), GURL("http://google.com")); + ui_test_utils::NavigateToURL(browser(), GURL("https://google.com")); // Make sure there is 1 tab. ASSERT_EQ(1, browser()->tab_strip_model()->count()); @@ -759,25 +491,25 @@ // Expect that a new tab has been opened. ASSERT_EQ(2, browser()->tab_strip_model()->count()); - // Open the dialog again to check for a route. - OpenMRDialog(GetActiveWebContents()); + test_ui_->ShowDialog(); // Wait for a route to be created. - WaitUntilRouteCreated(); + test_ui_->WaitForAnyRoute(); } // Tests that failing to create a route with a local file shows an issue. +// TODO(https://crbug.com/900248): Make this test pass with the Views dialog. IN_PROC_BROWSER_TEST_F(MediaRouterIntegrationBrowserTest, - OpenLocalMediaFileFailsAndShowsIssue) { + DISABLED_OpenLocalMediaFileFailsAndShowsIssue) { OpenDialogAndCastFileFails(); // Expect that the issue is showing. ASSERT_TRUE(IsUIShowingIssue()); } // Tests that creating a route with a local file opens in fullscreen. -// TODO(crbug.com/822029): Fails on msan; fix and re-enable. +// TODO(https://crbug.com/900248): Make this test pass with the Views dialog. IN_PROC_BROWSER_TEST_F(MediaRouterIntegrationBrowserTest, - MANUAL_OpenLocalMediaFileFullscreen) { + DISABLED_OpenLocalMediaFileFullscreen) { // Start at a new tab, the file should open in the same tab. ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUINewTabURL)); // Make sure there is 1 tab. @@ -799,8 +531,9 @@ } // Tests that failed route creation of local file does not enter fullscreen. +// TODO(https://crbug.com/900248): Make this test pass with the Views dialog. IN_PROC_BROWSER_TEST_F(MediaRouterIntegrationBrowserTest, - OpenLocalMediaFileCastFailNoFullscreen) { + DISABLED_OpenLocalMediaFileCastFailNoFullscreen) { // Start at a new tab, the file should open in the same tab. ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUINewTabURL)); // Make sure there is 1 tab. @@ -836,8 +569,9 @@ RunFailToSendMessageTest(); } +// TODO(https://crbug.com/822231): Flaky in Chromium waterfall. IN_PROC_BROWSER_TEST_F(MediaRouterIntegrationBrowserTest, - DISABLED_Fail_NoProvider) { + MANUAL_Fail_NoProvider) { SetTestData(FILE_PATH_LITERAL("no_provider.json")); WebContents* web_contents = StartSessionWithTestPageAndChooseSink(); CheckStartFailed(web_contents, "UnknownError", @@ -850,20 +584,12 @@ CheckStartFailed(web_contents, "UnknownError", "Unknown sink"); } -// TODO(crbug.com/822231): Flaky in Chromium waterfall. -IN_PROC_BROWSER_TEST_F(MediaRouterIntegrationBrowserTest, - MANUAL_ReconnectSession) { +IN_PROC_BROWSER_TEST_F(MediaRouterIntegrationBrowserTest, ReconnectSession) { RunReconnectSessionTest(); } -// Flaky on Linux MSAN. https://crbug.com/840165 -#if defined(OS_LINUX) && defined(MEMORY_SANITIZER) -#define MAYBE_Fail_ReconnectSession DISABLED_Fail_ReconnectSession -#else -#define MAYBE_Fail_ReconnectSession Fail_ReconnectSession -#endif IN_PROC_BROWSER_TEST_F(MediaRouterIntegrationBrowserTest, - MAYBE_Fail_ReconnectSession) { + Fail_ReconnectSession) { WebContents* web_contents = StartSessionWithTestPageAndChooseSink(); CheckSessionValidity(web_contents); std::string session_id(GetStartedConnectionId(web_contents)); @@ -880,7 +606,7 @@ IN_PROC_BROWSER_TEST_F(MediaRouterIntegrationBrowserTest, Fail_StartCancelled) { WebContents* web_contents = StartSessionWithTestPageAndSink(); - GetControllerForShownDialog(web_contents)->HideMediaRouterDialog(); + test_ui_->HideDialog(); CheckStartFailed(web_contents, "NotAllowedError", "Dialog closed."); } @@ -914,21 +640,21 @@ return incognito_browser_; } -// Test is flaky on Linux. (https://crbug.com/853167) -#if defined(OS_LINUX) -#define MAYBE_Basic DISABLED_Basic -#else -#define MAYBE_Basic Basic -#endif -IN_PROC_BROWSER_TEST_F(MediaRouterIntegrationIncognitoBrowserTest, - MAYBE_Basic) { +IN_PROC_BROWSER_TEST_F(MediaRouterIntegrationIncognitoBrowserTest, Basic) { RunBasicTest(); + // If we tear down before route observers are notified of route termination, + // MediaRouter will create another TerminateRoute() request which will have a + // dangling Mojo callback at shutdown. So we must wait for the update. + test_ui_->WaitUntilNoRoutes(); } -// TODO(crbug.com/822300): Flaky in Chromium waterfall. IN_PROC_BROWSER_TEST_F(MediaRouterIntegrationIncognitoBrowserTest, - MANUAL_ReconnectSession) { + ReconnectSession) { RunReconnectSessionTest(); + // If we tear down before route observers are notified of route termination, + // MediaRouter will create another TerminateRoute() request which will have a + // dangling Mojo callback at shutdown. So we must wait for the update. + test_ui_->WaitUntilNoRoutes(); } } // namespace media_router
diff --git a/chrome/test/media_router/media_router_integration_browsertest.h b/chrome/test/media_router/media_router_integration_browsertest.h index db7f3e6..087039f4 100644 --- a/chrome/test/media_router/media_router_integration_browsertest.h +++ b/chrome/test/media_router/media_router_integration_browsertest.h
@@ -14,14 +14,13 @@ #include "chrome/browser/ui/media_router/media_cast_mode.h" #include "chrome/browser/ui/toolbar/media_router_action.h" #include "chrome/test/media_router/media_router_base_browsertest.h" +#include "chrome/test/media_router/media_router_ui_for_test.h" #include "components/policy/core/common/mock_configuration_policy_provider.h" #include "content/public/test/browser_test_utils.h" #include "content/public/test/test_navigation_observer.h" namespace media_router { -class MediaRouterDialogControllerWebUIImpl; -class MediaRouterUI; struct IssueInfo; class MediaRouterIntegrationBrowserTest : public MediaRouterBaseBrowserTest { @@ -33,23 +32,11 @@ // InProcessBrowserTest Overrides void TearDownOnMainThread() override; void SetUpInProcessBrowserTestFixture() override; + void SetUpOnMainThread() override; // MediaRouterBaseBrowserTest Overrides void ParseCommandLine() override; - // Simulate user action to choose one sink in the popup dialog. - // |web_contents|: The web contents of the test page which invokes the popup - // dialog. - // |sink_name|: The sink's human readable name. - void ChooseSink(content::WebContents* web_contents, - const std::string& sink_name); - - // Simulate user action to choose the local media cast mode in the popup - // dialog. This will not work unless the dialog is in the choose cast mode - // view. |dialog_contents|: The web contents of the popup dialog. - // |cast_mode_text|: The cast mode's dialog name. - void ClickCastMode(content::WebContents* dialog_contents, MediaCastMode mode); - // Checks that the request initiated from |web_contents| to start presentation // failed with expected |error_name| and |error_message_substring|. void CheckStartFailed(content::WebContents* web_contents, @@ -67,12 +54,6 @@ static std::string ExecuteScriptAndExtractString( const content::ToRenderFrameHost& adapter, const std::string& script); - void ClickDialog(); - - // Clicks on the header of the dialog. If in sinks view, will change to cast - // mode view, if in cast mode view, will change to sinks view. - void ClickHeader(content::WebContents* dialog_contents); - static bool ExecuteScriptAndExtractBool( const content::ToRenderFrameHost& adapter, const std::string& script); @@ -80,17 +61,6 @@ static void ExecuteScript(const content::ToRenderFrameHost& adapter, const std::string& script); - // Get the chrome modal dialog. - // |web_contents|: The web contents of the test page which invokes the popup - // dialog. - content::WebContents* GetMRDialog(content::WebContents* web_contents); - - // Checks that the chrome modal dialog does not exist. - bool IsDialogClosed(content::WebContents* web_contents); - void WaitUntilDialogClosed(content::WebContents* web_contents); - - void CheckDialogRemainsOpen(content::WebContents* web_contents); - // Opens "basic_test.html" and asserts that attempting to start a presentation // fails with NotFoundError due to no sinks available. void StartSessionAndAssertNotFoundError(); @@ -121,76 +91,30 @@ void SetTestData(base::FilePath::StringPieceType test_data_file); - // Start presentation and wait until the pop dialog shows up. - // |web_contents|: The web contents of the test page which invokes the popup - // dialog. - void StartSession(content::WebContents* web_contents); - - // Open the chrome modal dialog. - // |web_contents|: The web contents of the test page which invokes the popup - // dialog. - content::WebContents* OpenMRDialog(content::WebContents* web_contents); bool IsRouteCreatedOnUI(); bool IsRouteClosedOnUI(); - bool IsSinkDiscoveredOnUI(); - - // Close route through clicking 'Stop casting' button in route details dialog. - void CloseRouteOnUI(); - - // Wait for the route to show up in the UI with a timeout. Fails if the - // route did not show up before the timeout. - void WaitUntilRouteCreated(); - - // Wait until there is an issue showing in the UI. - void WaitUntilIssue(); - // Returns true if there is an issue showing in the UI. bool IsUIShowingIssue(); - // Returns the title of issue showing in UI. It is an error to call this if - // there are no issues showing in UI. - std::string GetIssueTitle(); - // Returns the route ID for the specific sink. std::string GetRouteId(const std::string& sink_id); - // Wait for the specific sink shows up in UI with a timeout. Fails if the sink - // doesn't show up before the timeout. - void WaitUntilSinkDiscoveredOnUI(); - - // Checks if media router dialog is fully loaded. - bool IsDialogLoaded(content::WebContents* dialog_contents); - - // Wait until media router dialog is fully loaded. - void WaitUntilDialogFullyLoaded(content::WebContents* dialog_contents); - // Checks that the presentation started for |web_contents| has connected and // is the default presentation. void CheckSessionValidity(content::WebContents* web_contents); - // Checks that a Media Router dialog is shown for |web_contents|, and returns - // its controller. - MediaRouterDialogControllerWebUIImpl* GetControllerForShownDialog( - content::WebContents* web_contents); - // Returns the active WebContents for the current window. content::WebContents* GetActiveWebContents(); - // Gets the MediaRouterUI that is associated with the open dialog. - // This is needed to bypass potential issues that may arise when trying to - // test code that uses the native file dialog. - MediaRouterUI* GetMediaRouterUI(content::WebContents* media_router_dialog); - // Sets the MediaRouterFileDialog to act like a valid file was selected on // opening the dialog. - void FileDialogSelectsFile(MediaRouterUI* media_router_ui, GURL file_url); + void FileDialogSelectsFile(GURL file_url); // Sets the MediaRouterFileDialog to act like a bad file was selected on // opening the dialog. - void FileDialogSelectFails(MediaRouterUI* media_router_ui, - const IssueInfo& issue); + void FileDialogSelectFails(const IssueInfo& issue); // Runs a basic test in which a presentation is created through the // MediaRouter dialog, then terminated. @@ -213,11 +137,15 @@ // Sets whether media router is enabled. void SetEnableMediaRouter(bool enable); - std::string receiver() const { return receiver_; } + // Test API for manipulating the UI. + MediaRouterUiForTest* test_ui_ = nullptr; - // Enabled features + // Enabled features. base::test::ScopedFeatureList scoped_feature_list_; + // Name of the test receiver to use. + std::string receiver_; + private: // Get the full path of the resource file. // |relative_path|: The relative path to @@ -228,14 +156,11 @@ std::unique_ptr<content::TestNavigationObserver> test_navigation_observer_; policy::MockConfigurationPolicyProvider provider_; - - // Fields - std::string receiver_; }; class MediaRouterIntegrationIncognitoBrowserTest : public MediaRouterIntegrationBrowserTest { - public: + protected: void InstallAndEnableMRExtension() override; void UninstallMRExtension() override; Browser* browser() override;
diff --git a/chrome/test/media_router/media_router_integration_ui_browsertest.cc b/chrome/test/media_router/media_router_integration_ui_browsertest.cc index 77b2a76e..33fc5bd 100644 --- a/chrome/test/media_router/media_router_integration_ui_browsertest.cc +++ b/chrome/test/media_router/media_router_integration_ui_browsertest.cc
@@ -17,150 +17,37 @@ namespace media_router { -namespace { -const char kTestSinkName[] = "test-sink-1"; -} - -// Disabled due to flakiness: https://crbug.com/873912. -#if defined(OS_CHROMEOS) && defined(MEMORY_SANITIZER) -#define MAYBE_Dialog_Basic DISABLED_Dialog_Basic -#else -#define MAYBE_Dialog_Basic Dialog_Basic -#endif -IN_PROC_BROWSER_TEST_F(MediaRouterIntegrationBrowserTest, MAYBE_Dialog_Basic) { +// TODO(https://crbug.com/822231): Flaky in Chromium waterfall. +IN_PROC_BROWSER_TEST_F(MediaRouterIntegrationBrowserTest, MANUAL_Dialog_Basic) { OpenTestPage(FILE_PATH_LITERAL("basic_test.html")); - content::WebContents* web_contents = - browser()->tab_strip_model()->GetActiveWebContents(); - content::WebContents* dialog_contents = OpenMRDialog(web_contents); - WaitUntilSinkDiscoveredOnUI(); - // Verify the sink list. - std::string sink_length_script = base::StringPrintf( - "domAutomationController.send(" - "window.document.getElementById('media-router-container')." - "sinksToShow_.length)"); - ASSERT_GT(ExecuteScriptAndExtractInt(dialog_contents, sink_length_script), 0); - LOG(INFO) << "Choose Sink"; - ChooseSink(web_contents, kTestSinkName); + test_ui_->ShowDialog(); + test_ui_->WaitForSinkAvailable(receiver_); + test_ui_->StartCasting(receiver_); + test_ui_->WaitForAnyRoute(); -// Linux and Windows bots run browser tests without a physical display, which -// is causing flaky event dispatching of mouseenter and mouseleave events. This -// causes the dialog to sometimes close prematurely even though a mouseenter -// event is explicitly dispatched in the test. -// Here, we still dispatch the mouseenter event for OSX, but close -// the dialog and reopen it on Linux and Windows. -// The test succeeds fine when run with a physical display. -// http://crbug.com/577943 http://crbug.com/591779 -#if defined(OS_MACOSX) - // Simulate keeping the mouse on the dialog to prevent it from automatically - // closing after the route has been created. Then, check that the dialog - // remains open. - std::string mouse_enter_script = base::StringPrintf( - "window.document.getElementById('media-router-container')" - " .dispatchEvent(new Event('mouseenter'));"); - ASSERT_TRUE(content::ExecuteScript(dialog_contents, mouse_enter_script)); -#endif - WaitUntilRouteCreated(); + if (!test_ui_->IsDialogShown()) + test_ui_->ShowDialog(); -#if defined(OS_MACOSX) - CheckDialogRemainsOpen(web_contents); -#elif defined(OS_LINUX) || defined(OS_WIN) - Wait(base::TimeDelta::FromSeconds(5)); - LOG(INFO) << "Waiting for dialog to be closed"; - WaitUntilDialogClosed(web_contents); - LOG(INFO) << "Reopen MR dialog"; - dialog_contents = OpenMRDialog(web_contents); -#endif + ASSERT_EQ("Test Route", test_ui_->GetStatusTextForSink(receiver_)); - LOG(INFO) << "Check route details dialog"; - std::string route_script; - // Verify the route details is not undefined. - route_script = base::StringPrintf( - "domAutomationController.send(" - "window.document.getElementById('media-router-container').shadowRoot." - "getElementById('route-details') != undefined)"); - ASSERT_TRUE(ConditionalWait( - base::TimeDelta::FromSeconds(30), base::TimeDelta::FromSeconds(1), - base::Bind( - &MediaRouterIntegrationBrowserTest::ExecuteScriptAndExtractBool, - dialog_contents, route_script))); - route_script = base::StringPrintf( - "domAutomationController.send(" - "window.document.getElementById('media-router-container').currentView_ " - "== media_router.MediaRouterView.ROUTE_DETAILS)"); - ASSERT_TRUE(ExecuteScriptAndExtractBool(dialog_contents, route_script)); - - // Verify the route details page. - route_script = base::StringPrintf( - "domAutomationController.send(" - "window.document.getElementById('media-router-container').shadowRoot." - "getElementById('route-details').shadowRoot.getElementById(" - "'route-description').innerText)"); - std::string route_information = ExecuteScriptAndExtractString( - dialog_contents, route_script); - ASSERT_EQ("Test Route", route_information); - - std::string sink_script; - // Verify the container header is not undefined. - sink_script = base::StringPrintf( - "domAutomationController.send(" - "window.document.getElementById('media-router-container').shadowRoot." - "getElementById('container-header') != undefined)"); - LOG(INFO) << "Checking container-header"; - ASSERT_TRUE(ConditionalWait( - base::TimeDelta::FromSeconds(30), base::TimeDelta::FromSeconds(1), - base::Bind( - &MediaRouterIntegrationBrowserTest::ExecuteScriptAndExtractBool, - dialog_contents, sink_script))); - - sink_script = base::StringPrintf( - "domAutomationController.send(" - "window.document.getElementById('media-router-container').shadowRoot." - "getElementById('container-header').shadowRoot.getElementById(" - "'header-text').innerText)"); - std::string sink_name = ExecuteScriptAndExtractString( - dialog_contents, sink_script); - ASSERT_EQ(kTestSinkName, sink_name); - LOG(INFO) << "Finish verification"; - -#if defined(OS_MACOSX) - // Simulate moving the mouse off the dialog. Confirm that the dialog closes - // automatically after the route is closed. - // In tests, it sometimes takes too long to CloseRouteOnUI() to finish so - // the timer started when the route is initially closed times out before the - // mouseleave event is dispatched. In that case, the dialog remains open. - std::string mouse_leave_script = base::StringPrintf( - "window.document.getElementById('media-router-container')" - " .dispatchEvent(new Event('mouseleave'));"); - ASSERT_TRUE(content::ExecuteScript(dialog_contents, mouse_leave_script)); -#endif - LOG(INFO) << "Closing route on UI"; - CloseRouteOnUI(); -#if defined(OS_MACOSX) - LOG(INFO) << "Waiting for dialog to be closed"; - WaitUntilDialogClosed(web_contents); -#endif - LOG(INFO) << "Closed dialog, end of test"; + test_ui_->StopCasting(receiver_); + test_ui_->WaitUntilNoRoutes(); + // TODO(takumif): Remove the HideDialog() call once the dialog can close on + // its own. + test_ui_->HideDialog(); } -// TODO(crbug.com/822301): Flaky in Chromium waterfall. +// TODO(https://crbug.com/822231): Flaky in Chromium waterfall. IN_PROC_BROWSER_TEST_F(MediaRouterIntegrationBrowserTest, MANUAL_Dialog_RouteCreationTimedOut) { SetTestData(FILE_PATH_LITERAL("route_creation_timed_out.json")); OpenTestPage(FILE_PATH_LITERAL("basic_test.html")); - content::WebContents* web_contents = - browser()->tab_strip_model()->GetActiveWebContents(); - content::WebContents* dialog_contents = OpenMRDialog(web_contents); - - // Verify the sink list. - std::string sink_length_script = base::StringPrintf( - "domAutomationController.send(" - "window.document.getElementById('media-router-container')." - "sinksToShow_.length)"); - ASSERT_GT(ExecuteScriptAndExtractInt(dialog_contents, sink_length_script), 0); + test_ui_->ShowDialog(); + test_ui_->WaitForSinkAvailable(receiver_); base::TimeTicks start_time(base::TimeTicks::Now()); - ChooseSink(web_contents, kTestSinkName); - WaitUntilIssue(); + test_ui_->StartCasting(receiver_); + test_ui_->WaitForAnyIssue(); base::TimeDelta elapsed(base::TimeTicks::Now() - start_time); // The hardcoded timeout route creation timeout for the UI. @@ -170,7 +57,7 @@ EXPECT_GE(elapsed, expected_timeout); EXPECT_LE(elapsed - expected_timeout, base::TimeDelta::FromSeconds(5)); - std::string issue_title = GetIssueTitle(); + std::string issue_title = test_ui_->GetIssueTextForSink(receiver_); // TODO(imcheng): Fix host name for file schemes (crbug.com/560576). ASSERT_EQ( l10n_util::GetStringFUTF8(IDS_MEDIA_ROUTER_ISSUE_CREATE_ROUTE_TIMEOUT, @@ -178,7 +65,8 @@ issue_title); // Route will still get created, it just takes longer than usual. - WaitUntilRouteCreated(); + test_ui_->WaitForAnyRoute(); + test_ui_->HideDialog(); } IN_PROC_BROWSER_TEST_F(MediaRouterIntegrationBrowserTest, @@ -191,33 +79,22 @@ // Enable media routing and open media router dialog. SetEnableMediaRouter(true); OpenTestPage(FILE_PATH_LITERAL("basic_test.html")); - content::WebContents* web_contents = - browser()->tab_strip_model()->GetActiveWebContents(); - OpenMRDialog(web_contents); - - MediaRouterDialogControllerWebUIImpl* controller = - MediaRouterDialogControllerWebUIImpl::GetOrCreateForWebContents( - web_contents); - ASSERT_TRUE(controller->IsShowingMediaRouterDialog()); + test_ui_->ShowDialog(); + ASSERT_TRUE(test_ui_->IsDialogShown()); + test_ui_->HideDialog(); } IN_PROC_BROWSER_TEST_F(MediaRouterIntegrationBrowserTest, DisableMediaRoutingWhenDialogIsOpened) { // Open media router dialog. OpenTestPage(FILE_PATH_LITERAL("basic_test.html")); - content::WebContents* web_contents = - browser()->tab_strip_model()->GetActiveWebContents(); - OpenMRDialog(web_contents); - - MediaRouterDialogControllerWebUIImpl* controller = - MediaRouterDialogControllerWebUIImpl::GetOrCreateForWebContents( - web_contents); - ASSERT_TRUE(controller->IsShowingMediaRouterDialog()); + test_ui_->ShowDialog(); + ASSERT_TRUE(test_ui_->IsDialogShown()); // Disable media routing. SetEnableMediaRouter(false); - ASSERT_FALSE(controller->IsShowingMediaRouterDialog()); + ASSERT_FALSE(test_ui_->IsDialogShown()); } } // namespace media_router
diff --git a/chrome/test/media_router/media_router_one_ua_integration_browsertest.cc b/chrome/test/media_router/media_router_one_ua_integration_browsertest.cc index 270e01a..aaf4ad6f 100644 --- a/chrome/test/media_router/media_router_one_ua_integration_browsertest.cc +++ b/chrome/test/media_router/media_router_one_ua_integration_browsertest.cc
@@ -41,18 +41,17 @@ } }; -// TODO(crbug.com/822231): Flaky in Chromium waterfall. -IN_PROC_BROWSER_TEST_F(MediaRouterIntegrationOneUABrowserTest, MANUAL_Basic) { +IN_PROC_BROWSER_TEST_F(MediaRouterIntegrationOneUABrowserTest, Basic) { RunBasicTest(); } -// TODO(crbug.com/822216): Flaky in Chromium waterfall. +// TODO(https://crbug.com/822231): Flaky in Chromium waterfall. IN_PROC_BROWSER_TEST_F(MediaRouterIntegrationOneUABrowserTest, MANUAL_SendAndOnMessage) { RunSendMessageTest("foo"); } -// TODO(crbug.com/821717): Flaky in Chromium waterfall. +// TODO(https://crbug.com/822231): Flaky in Chromium waterfall. IN_PROC_BROWSER_TEST_F(MediaRouterIntegrationOneUABrowserTest, MANUAL_ReceiverCloseConnection) { WebContents* web_contents = StartSessionWithTestPageAndChooseSink(); @@ -60,21 +59,18 @@ ExecuteJavaScriptAPI(web_contents, kInitiateCloseFromReceiverPageScript); } -// TODO(crbug.com/824889): Flaky in Chromium waterfall. IN_PROC_BROWSER_TEST_F(MediaRouterIntegrationOneUABrowserTest, - MANUAL_Fail_SendMessage) { + Fail_SendMessage) { RunFailToSendMessageTest(); } -// TODO(crbug.com/821717): Flaky in Chromium waterfall. IN_PROC_BROWSER_TEST_F(MediaRouterIntegrationOneUABrowserTest, - MANUAL_ReconnectSession) { + ReconnectSession) { RunReconnectSessionTest(); } -// TODO(crbug.com/821717): Flaky in Chromium waterfall. IN_PROC_BROWSER_TEST_F(MediaRouterIntegrationOneUABrowserTest, - MANUAL_ReconnectSessionSameTab) { + ReconnectSessionSameTab) { RunReconnectSessionSameTabTest(); } @@ -87,28 +83,23 @@ } }; -// TODO(crbug.com/822179,822337): Flaky in Chromium waterfall. IN_PROC_BROWSER_TEST_F(MediaRouterIntegrationOneUANoReceiverBrowserTest, - MANUAL_Basic) { + Basic) { RunBasicTest(); } -// TODO(crbug.com/821717): Flaky in Chromium waterfall. IN_PROC_BROWSER_TEST_F(MediaRouterIntegrationOneUANoReceiverBrowserTest, - MANUAL_Fail_SendMessage) { + Fail_SendMessage) { RunFailToSendMessageTest(); } -// TODO(crbug.com/822231): Flaky in Chromium waterfall. IN_PROC_BROWSER_TEST_F(MediaRouterIntegrationOneUANoReceiverBrowserTest, - MANUAL_ReconnectSession) { + ReconnectSession) { RunReconnectSessionTest(); } -// TODO(crbug.com/826016): Crashes on ASAN. -// TODO(crbug.com/834681): Crashes elsewhere too, flakily. IN_PROC_BROWSER_TEST_F(MediaRouterIntegrationOneUANoReceiverBrowserTest, - MANUAL_ReconnectSessionSameTab) { + ReconnectSessionSameTab) { RunReconnectSessionSameTabTest(); }
diff --git a/chrome/test/media_router/media_router_ui_for_test.cc b/chrome/test/media_router/media_router_ui_for_test.cc index f8a29f8..3a82446 100644 --- a/chrome/test/media_router/media_router_ui_for_test.cc +++ b/chrome/test/media_router/media_router_ui_for_test.cc
@@ -5,6 +5,8 @@ #include "chrome/test/media_router/media_router_ui_for_test.h" #include "base/strings/utf_string_conversions.h" +#include "chrome/browser/media/router/media_router_factory.h" +#include "chrome/browser/media/router/media_routes_observer.h" #include "chrome/browser/ui/views/media_router/cast_dialog_sink_button.h" #include "chrome/browser/ui/views/media_router/cast_dialog_view.h" #include "chrome/browser/ui/views/media_router/media_router_dialog_controller_views.h" @@ -30,6 +32,24 @@ ui::EF_LEFT_MOUSE_BUTTON, 0); } +// Routes observer that calls a callback once there are no routes. +class NoRoutesObserver : public MediaRoutesObserver { + public: + NoRoutesObserver(MediaRouter* router, base::OnceClosure callback) + : MediaRoutesObserver(router), callback_(std::move(callback)) {} + ~NoRoutesObserver() override = default; + + void OnRoutesUpdated( + const std::vector<MediaRoute>& routes, + const std::vector<MediaRoute::Id>& joinable_route_ids) override { + if (callback_ && routes.empty()) + std::move(callback_).Run(); + } + + private: + base::OnceClosure callback_; +}; + } // namespace // static @@ -80,15 +100,15 @@ dialog_view->sources_menu_model_for_test()->ActivatedAt(source_index); } -void MediaRouterUiForTest::StartCasting(const MediaSink::Id& sink_id) { - CastDialogSinkButton* sink_button = GetSinkButton(sink_id); +void MediaRouterUiForTest::StartCasting(const std::string& sink_name) { + CastDialogSinkButton* sink_button = GetSinkButton(sink_name); sink_button->OnMousePressed(CreateMousePressedEvent()); sink_button->OnMouseReleased(CreateMouseReleasedEvent()); base::RunLoop().RunUntilIdle(); } -void MediaRouterUiForTest::StopCasting(const MediaSink::Id& sink_id) { - CastDialogSinkButton* sink_button = GetSinkButton(sink_id); +void MediaRouterUiForTest::StopCasting(const std::string& sink_name) { + CastDialogSinkButton* sink_button = GetSinkButton(sink_name); sink_button->icon_view()->OnMousePressed(CreateMousePressedEvent()); sink_button->icon_view()->OnMouseReleased(CreateMouseReleasedEvent()); base::RunLoop().RunUntilIdle(); @@ -109,8 +129,12 @@ NOTREACHED() << "Sink was not found"; } -void MediaRouterUiForTest::WaitForSink(const MediaSink::Id& sink_id) { - ObserveDialog(WatchType::kSink, sink_id); +void MediaRouterUiForTest::WaitForSink(const std::string& sink_name) { + ObserveDialog(WatchType::kSink, sink_name); +} + +void MediaRouterUiForTest::WaitForSinkAvailable(const std::string& sink_name) { + ObserveDialog(WatchType::kSinkAvailable, sink_name); } void MediaRouterUiForTest::WaitForAnyIssue() { @@ -121,37 +145,53 @@ ObserveDialog(WatchType::kAnyRoute); } -void MediaRouterUiForTest::WaitForDialogClosed() { - ObserveDialog(WatchType::kDialogClosed); +void MediaRouterUiForTest::WaitForDialogShown() { + CHECK(!watch_sink_name_); + CHECK(!watch_callback_); + CHECK_EQ(watch_type_, WatchType::kNone); + if (IsDialogShown()) + return; + + base::RunLoop run_loop; + watch_callback_ = run_loop.QuitClosure(); + watch_type_ = WatchType::kDialogShown; + run_loop.Run(); } -std::string MediaRouterUiForTest::GetSinkName( - const MediaSink::Id& sink_id) const { - CastDialogSinkButton* sink_button = GetSinkButton(sink_id); - return base::UTF16ToUTF8(sink_button->sink().friendly_name); +void MediaRouterUiForTest::WaitForDialogHidden() { + ObserveDialog(WatchType::kDialogHidden); +} + +void MediaRouterUiForTest::WaitUntilNoRoutes() { + base::RunLoop run_loop; + NoRoutesObserver no_routes_observer( + MediaRouterFactory::GetApiForBrowserContext( + web_contents_->GetBrowserContext()), + run_loop.QuitClosure()); + run_loop.Run(); } MediaRoute::Id MediaRouterUiForTest::GetRouteIdForSink( - const MediaSink::Id& sink_id) const { - CastDialogSinkButton* sink_button = GetSinkButton(sink_id); + const std::string& sink_name) const { + CastDialogSinkButton* sink_button = GetSinkButton(sink_name); if (!sink_button->sink().route) { - NOTREACHED() << "Route not found for sink " << sink_id; + NOTREACHED() << "Route not found for sink " << sink_name; return ""; } return sink_button->sink().route->media_route_id(); } std::string MediaRouterUiForTest::GetStatusTextForSink( - const MediaSink::Id& sink_id) const { - CastDialogSinkButton* sink_button = GetSinkButton(sink_id); + const std::string& sink_name) const { + CastDialogSinkButton* sink_button = GetSinkButton(sink_name); return base::UTF16ToUTF8(sink_button->sink().status_text); } std::string MediaRouterUiForTest::GetIssueTextForSink( - const MediaSink::Id& sink_id) const { - CastDialogSinkButton* sink_button = GetSinkButton(sink_id); + const std::string& sink_name) const { + CastDialogSinkButton* sink_button = GetSinkButton(sink_name); if (!sink_button->sink().issue) { - NOTREACHED() << "Issue not found for sink " << sink_id; + NOTREACHED() << "Issue not found for sink " << sink_name; return ""; } return sink_button->sink().issue->info().title; @@ -161,11 +201,17 @@ : web_contents_(web_contents), dialog_controller_( MediaRouterDialogControllerViews::GetOrCreateForWebContents( - web_contents)) {} + web_contents)), + weak_factory_(this) { + dialog_controller_->SetDialogCreationCallbackForTesting(base::BindRepeating( + &MediaRouterUiForTest::OnDialogCreated, weak_factory_.GetWeakPtr())); +} void MediaRouterUiForTest::OnDialogModelUpdated(CastDialogView* dialog_view) { - if (!watch_callback_ || watch_type_ == WatchType::kDialogClosed) + if (!watch_callback_ || watch_type_ == WatchType::kDialogShown || + watch_type_ == WatchType::kDialogHidden) { return; + } const std::vector<CastDialogSinkButton*>& sink_buttons = dialog_view->sink_buttons_for_test(); @@ -173,27 +219,34 @@ [&, this](CastDialogSinkButton* sink_button) { switch (watch_type_) { case WatchType::kSink: - return sink_button->sink().id == *watch_sink_id_; + return sink_button->sink().friendly_name == + base::UTF8ToUTF16(*watch_sink_name_); + case WatchType::kSinkAvailable: + return sink_button->sink().friendly_name == + base::UTF8ToUTF16(*watch_sink_name_) && + sink_button->sink().state == + UIMediaSinkState::AVAILABLE; case WatchType::kAnyIssue: return sink_button->sink().issue.has_value(); case WatchType::kAnyRoute: return sink_button->sink().route.has_value(); case WatchType::kNone: - case WatchType::kDialogClosed: + case WatchType::kDialogShown: + case WatchType::kDialogHidden: NOTREACHED() << "Invalid WatchType"; return false; } }) != sink_buttons.end()) { std::move(*watch_callback_).Run(); watch_callback_.reset(); - watch_sink_id_.reset(); + watch_sink_name_.reset(); watch_type_ = WatchType::kNone; dialog_view->RemoveObserver(this); } } void MediaRouterUiForTest::OnDialogWillClose(CastDialogView* dialog_view) { - if (watch_type_ == WatchType::kDialogClosed) { + if (watch_type_ == WatchType::kDialogHidden) { std::move(*watch_callback_).Run(); watch_callback_.reset(); watch_type_ = WatchType::kNone; @@ -203,18 +256,28 @@ dialog_view->RemoveObserver(this); } +void MediaRouterUiForTest::OnDialogCreated() { + if (watch_type_ == WatchType::kDialogShown) { + std::move(*watch_callback_).Run(); + watch_callback_.reset(); + watch_type_ = WatchType::kNone; + } + CastDialogView::GetInstance()->KeepShownForTesting(); +} + CastDialogSinkButton* MediaRouterUiForTest::GetSinkButton( - const MediaSink::Id& sink_id) const { + const std::string& sink_name) const { CastDialogView* dialog_view = CastDialogView::GetInstance(); CHECK(dialog_view); const std::vector<CastDialogSinkButton*>& sink_buttons = dialog_view->sink_buttons_for_test(); auto it = std::find_if(sink_buttons.begin(), sink_buttons.end(), - [sink_id](CastDialogSinkButton* sink_button) { - return sink_button->sink().id == sink_id; + [sink_name](CastDialogSinkButton* sink_button) { + return sink_button->sink().friendly_name == + base::UTF8ToUTF16(sink_name); }); if (it == sink_buttons.end()) { - NOTREACHED() << "Sink button not found for sink ID: " << sink_id; + NOTREACHED() << "Sink button not found for sink: " << sink_name; return nullptr; } else { return *it; @@ -223,12 +286,12 @@ void MediaRouterUiForTest::ObserveDialog( WatchType watch_type, - base::Optional<MediaSink::Id> sink_id) { - CHECK(!watch_sink_id_); + base::Optional<std::string> sink_name) { + CHECK(!watch_sink_name_); CHECK(!watch_callback_); CHECK_EQ(watch_type_, WatchType::kNone); base::RunLoop run_loop; - watch_sink_id_ = std::move(sink_id); + watch_sink_name_ = std::move(sink_name); watch_callback_ = run_loop.QuitClosure(); watch_type_ = watch_type;
diff --git a/chrome/test/media_router/media_router_ui_for_test.h b/chrome/test/media_router/media_router_ui_for_test.h index 908afdc..3b51970 100644 --- a/chrome/test/media_router/media_router_ui_for_test.h +++ b/chrome/test/media_router/media_router_ui_for_test.h
@@ -7,8 +7,10 @@ #include "base/callback_forward.h" #include "base/macros.h" +#include "base/memory/weak_ptr.h" #include "base/optional.h" #include "chrome/browser/ui/views/media_router/cast_dialog_view.h" +#include "chrome/browser/ui/views/media_router/media_router_dialog_controller_views.h" #include "chrome/common/media_router/media_sink.h" #include "chrome/common/media_router/media_source.h" #include "content/public/browser/web_contents_user_data.h" @@ -19,8 +21,6 @@ namespace media_router { -class MediaRouterDialogControllerViews; - class MediaRouterUiForTest : public content::WebContentsUserData<MediaRouterUiForTest>, public CastDialogView::Observer { @@ -39,31 +39,41 @@ // These methods require that the dialog is shown and the specified sink is // shown in the dialog. - void StartCasting(const MediaSink::Id& sink_id); - void StopCasting(const MediaSink::Id& sink_id); + void StartCasting(const std::string& sink_name); + void StopCasting(const std::string& sink_name); // Stops casting to the first active sink found on the sink list. Requires // that such a sink exists. void StopCasting(); - // Waits until . Requires that the dialog is shown. - void WaitForSink(const MediaSink::Id& sink_id); + // Waits until a condition is met. Requires that the dialog is shown. + void WaitForSink(const std::string& sink_name); + void WaitForSinkAvailable(const std::string& sink_name); void WaitForAnyIssue(); void WaitForAnyRoute(); - void WaitForDialogClosed(); + void WaitForDialogShown(); + void WaitForDialogHidden(); + void WaitUntilNoRoutes(); // These methods require that the dialog is shown, and the sink specified by - // |sink_id| is in the dialog. - std::string GetSinkName(const MediaSink::Id& sink_id) const; - MediaRoute::Id GetRouteIdForSink(const MediaSink::Id& sink_id) const; - std::string GetStatusTextForSink(const MediaSink::Id& sink_id) const; - std::string GetIssueTextForSink(const MediaSink::Id& sink_id) const; + // |sink_name| is in the dialog. + MediaRoute::Id GetRouteIdForSink(const std::string& sink_name) const; + std::string GetStatusTextForSink(const std::string& sink_name) const; + std::string GetIssueTextForSink(const std::string& sink_name) const; content::WebContents* web_contents() const { return web_contents_; } private: friend class content::WebContentsUserData<MediaRouterUiForTest>; - enum class WatchType { kNone, kSink, kAnyIssue, kAnyRoute, kDialogClosed }; + enum class WatchType { + kNone, + kSink, // Sink is found in any state. + kSinkAvailable, // Sink is found in the "Available" state. + kAnyIssue, + kAnyRoute, + kDialogShown, + kDialogHidden + }; explicit MediaRouterUiForTest(content::WebContents* web_contents); @@ -71,21 +81,26 @@ void OnDialogModelUpdated(CastDialogView* dialog_view) override; void OnDialogWillClose(CastDialogView* dialog_view) override; - CastDialogSinkButton* GetSinkButton(const MediaSink::Id& sink_id) const; + // Called by MediaRouterDialogControllerViews. + void OnDialogCreated(); + + CastDialogSinkButton* GetSinkButton(const std::string& sink_name) const; // Registers itself as an observer to the dialog, and waits until an event - // of |watch_type| is observed. |sink_id| should be set only if observing for - // a sink. + // of |watch_type| is observed. |sink_name| should be set only if observing + // for a sink. void ObserveDialog(WatchType watch_type, - base::Optional<MediaSink::Id> sink_id = base::nullopt); + base::Optional<std::string> sink_name = base::nullopt); content::WebContents* web_contents_; MediaRouterDialogControllerViews* dialog_controller_; - base::Optional<MediaSink::Id> watch_sink_id_; + base::Optional<std::string> watch_sink_name_; base::Optional<base::OnceClosure> watch_callback_; WatchType watch_type_ = WatchType::kNone; + base::WeakPtrFactory<MediaRouterUiForTest> weak_factory_; + DISALLOW_COPY_AND_ASSIGN(MediaRouterUiForTest); };
diff --git a/chrome/test/media_router/resources/common.js b/chrome/test/media_router/resources/common.js index 48ce0d9..141a109a 100644 --- a/chrome/test/media_router/resources/common.js +++ b/chrome/test/media_router/resources/common.js
@@ -120,7 +120,7 @@ sendResult(false, 'start() unexpectedly succeeded.'); }).catch(function(e) { if (expectedErrorName != e.name) { - sendResult(false, 'Got unexpected error: ' + e.name); + sendResult(false, 'Got unexpected error. ' + e.name + ': ' + e.message); } else if (e.message.indexOf(expectedErrorMessageSubstring) == -1) { sendResult(false, 'Error message is not correct, it should contain "' + @@ -219,6 +219,12 @@ sendResult(false, 'startedConnection does not exist.'); return; } + if (startedConnection.state != 'connected') { + sendResult(false, + `Expected the connection state to be connected but it was \ + ${startedConnection.state}`); + return; + } startedConnection.onmessage = function(receivedMessage) { var expectedResponse = 'Pong: ' + message; var actualResponse = receivedMessage.data; @@ -241,6 +247,12 @@ sendResult(false, 'startedConnection does not exist.'); return; } + if (startedConnection.state != 'connected') { + sendResult(false, + `Expected the connection state to be connected but it was \ + ${startedConnection.state}`); + return; + } startedConnection.onclose = (event) => { const reason = event.reason; if (reason != 'closed') {
diff --git a/chromecast/base/chromecast_config_android.h b/chromecast/base/chromecast_config_android.h index 3b38e88..58fdeae 100644 --- a/chromecast/base/chromecast_config_android.h +++ b/chromecast/base/chromecast_config_android.h
@@ -18,8 +18,15 @@ // Returns whether or not the user has allowed sending usage stats and // crash reports. + // TODO(ziyangch): Remove CanSendUsageStats() and switch to pure callback + // style. virtual bool CanSendUsageStats() = 0; + // Set the the user's sending usage stats. + // TODO(ziyangch): Remove SetSendUsageStats() after switching to Crashpad on + // Android.(The CL which does this is at https://crrev.com/c/989401.) + virtual void SetSendUsageStats(bool enabled) = 0; + // Registers a handler to be notified when SendUsageStats is changed. virtual void SetSendUsageStatsChangedCallback( base::RepeatingCallback<void(bool)> callback) = 0;
diff --git a/chromecast/base/chromecast_config_android_dummy.cc b/chromecast/base/chromecast_config_android_dummy.cc index cc7e820..86982604 100644 --- a/chromecast/base/chromecast_config_android_dummy.cc +++ b/chromecast/base/chromecast_config_android_dummy.cc
@@ -16,6 +16,8 @@ bool CanSendUsageStats() override { return false; } + void SetSendUsageStats(bool enabled) override {} + void SetSendUsageStatsChangedCallback( base::RepeatingCallback<void(bool)> callback) override {}
diff --git a/components/BUILD.gn b/components/BUILD.gn index 0d27b5b..ff33f40 100644 --- a/components/BUILD.gn +++ b/components/BUILD.gn
@@ -279,6 +279,8 @@ "//base:base_java_unittest_support", "//components/autofill_assistant/browser:unit_tests", "//components/cdm/browser:unit_tests", + "//components/crash/android:java", + "//components/crash/android:unit_tests", "//components/gcm_driver/instance_id:test_support", "//components/gcm_driver/instance_id/android:instance_id_driver_java", "//components/gcm_driver/instance_id/android:instance_id_driver_test_support_java",
diff --git a/components/autofill/core/browser/BUILD.gn b/components/autofill/core/browser/BUILD.gn index 966a0b5..80959ab 100644 --- a/components/autofill/core/browser/BUILD.gn +++ b/components/autofill/core/browser/BUILD.gn
@@ -101,6 +101,8 @@ "credit_card_field.h", "credit_card_save_manager.cc", "credit_card_save_manager.h", + "credit_card_save_strike_database.cc", + "credit_card_save_strike_database.h", "email_field.cc", "email_field.h", "field_candidates.cc", @@ -351,6 +353,8 @@ "test_autofill_provider.h", "test_credit_card_save_manager.cc", "test_credit_card_save_manager.h", + "test_credit_card_save_strike_database.cc", + "test_credit_card_save_strike_database.h", "test_event_waiter.h", "test_form_data_importer.cc", "test_form_data_importer.h", @@ -484,6 +488,7 @@ "country_names_unittest.cc", "credit_card_field_unittest.cc", "credit_card_save_manager_unittest.cc", + "credit_card_save_strike_database_unittest.cc", "credit_card_unittest.cc", "field_candidates_unittest.cc", "field_filler_unittest.cc",
diff --git a/components/autofill/core/browser/credit_card_save_strike_database.cc b/components/autofill/core/browser/credit_card_save_strike_database.cc new file mode 100644 index 0000000..aca26ba3 --- /dev/null +++ b/components/autofill/core/browser/credit_card_save_strike_database.cc
@@ -0,0 +1,25 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/autofill/core/browser/credit_card_save_strike_database.h" + +#include "components/autofill/core/browser/proto/strike_data.pb.h" + +namespace autofill { + +CreditCardSaveStrikeDatabase::CreditCardSaveStrikeDatabase( + const base::FilePath& database_dir) + : StrikeDatabase(database_dir) {} + +CreditCardSaveStrikeDatabase::~CreditCardSaveStrikeDatabase() {} + +std::string CreditCardSaveStrikeDatabase::GetProjectPrefix() { + return "CreditCardSave"; +} + +int CreditCardSaveStrikeDatabase::GetMaxStrikesLimit() { + return 3; +} + +} // namespace autofill
diff --git a/components/autofill/core/browser/credit_card_save_strike_database.h b/components/autofill/core/browser/credit_card_save_strike_database.h new file mode 100644 index 0000000..fab05c6 --- /dev/null +++ b/components/autofill/core/browser/credit_card_save_strike_database.h
@@ -0,0 +1,27 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_CREDIT_CARD_SAVE_STRIKE_DATABASE_H_ +#define COMPONENTS_AUTOFILL_CORE_BROWSER_CREDIT_CARD_SAVE_STRIKE_DATABASE_H_ + +#include <string> + +#include "components/autofill/core/browser/strike_database.h" + +namespace autofill { + +// Implementation of StrikeDatabase for credit card saves (both local and +// upload). +class CreditCardSaveStrikeDatabase : public StrikeDatabase { + public: + CreditCardSaveStrikeDatabase(const base::FilePath& database_dir); + ~CreditCardSaveStrikeDatabase() override; + + std::string GetProjectPrefix() override; + int GetMaxStrikesLimit() override; +}; + +} // namespace autofill + +#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_CREDIT_CARD_SAVE_STRIKE_DATABASE_H_
diff --git a/components/autofill/core/browser/credit_card_save_strike_database_unittest.cc b/components/autofill/core/browser/credit_card_save_strike_database_unittest.cc new file mode 100644 index 0000000..cad6258 --- /dev/null +++ b/components/autofill/core/browser/credit_card_save_strike_database_unittest.cc
@@ -0,0 +1,105 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/autofill/core/browser/credit_card_save_strike_database.h" + +#include <utility> +#include <vector> + +#include "base/files/scoped_temp_dir.h" +#include "base/run_loop.h" +#include "base/test/metrics/histogram_tester.h" +#include "base/test/scoped_task_environment.h" +#include "base/threading/thread_task_runner_handle.h" +#include "components/autofill/core/browser/proto/strike_data.pb.h" +#include "components/autofill/core/browser/test_credit_card_save_strike_database.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace autofill { + +class CreditCardSaveStrikeDatabaseTest : public ::testing::Test { + public: + CreditCardSaveStrikeDatabaseTest() : strike_database_(InitFilePath()) {} + + protected: + base::HistogramTester* GetHistogramTester() { return &histogram_tester_; } + base::test::ScopedTaskEnvironment scoped_task_environment_; + TestCreditCardSaveStrikeDatabase strike_database_; + + private: + static const base::FilePath InitFilePath() { + base::ScopedTempDir temp_dir_; + EXPECT_TRUE(temp_dir_.CreateUniqueTempDir()); + const base::FilePath file_path = + temp_dir_.GetPath().AppendASCII("StrikeDatabaseTest"); + return file_path; + } + + base::HistogramTester histogram_tester_; +}; + +TEST_F(CreditCardSaveStrikeDatabaseTest, GetKeyForCreditCardSaveTest) { + const std::string last_four = "1234"; + EXPECT_EQ("CreditCardSave__1234", strike_database_.GetKey(last_four)); +} + +TEST_F(CreditCardSaveStrikeDatabaseTest, MaxStrikesLimitReachedTest) { + const std::string last_four = "1234"; + EXPECT_EQ(false, strike_database_.IsMaxStrikesLimitReached(last_four)); + // 1st strike added for |last_four|. + strike_database_.AddStrike(last_four); + EXPECT_EQ(false, strike_database_.IsMaxStrikesLimitReached(last_four)); + // 2nd strike added for |last_four|. + strike_database_.AddStrike(last_four); + EXPECT_EQ(false, strike_database_.IsMaxStrikesLimitReached(last_four)); + // 3rd strike added for |last_four|. + strike_database_.AddStrike(last_four); + EXPECT_EQ(true, strike_database_.IsMaxStrikesLimitReached(last_four)); +} + +TEST_F(CreditCardSaveStrikeDatabaseTest, + CreditCardSaveNthStrikeAddedHistogram) { + const std::string last_four1 = "1234"; + const std::string last_four2 = "9876"; + // 1st strike added for |last_four1|. + strike_database_.AddStrike(last_four1); + // 2nd strike added for |last_four1|. + strike_database_.AddStrike(last_four1); + // 1st strike added for |last_four2|. + strike_database_.AddStrike(last_four2); + std::vector<base::Bucket> buckets = GetHistogramTester()->GetAllSamples( + "Autofill.StrikeDatabase.NthStrikeAdded.CreditCardSave"); + // There should be two buckets, one for 1st strike, one for 2nd strike count. + ASSERT_EQ(2U, buckets.size()); + // Both |last_four1| and |last_four2| have 1st strikes recorded. + EXPECT_EQ(2, buckets[0].count); + // Only |last_four1| has 2nd strike recorded. + EXPECT_EQ(1, buckets[1].count); +} + +TEST_F(CreditCardSaveStrikeDatabaseTest, + AddStrikeForZeroAndNonZeroStrikesTest) { + const std::string last_four = "1234"; + EXPECT_EQ(0, strike_database_.GetStrikes(last_four)); + strike_database_.AddStrike(last_four); + EXPECT_EQ(1, strike_database_.GetStrikes(last_four)); + strike_database_.AddStrike(last_four); + EXPECT_EQ(2, strike_database_.GetStrikes(last_four)); +} + +TEST_F(CreditCardSaveStrikeDatabaseTest, ClearStrikesForNonZeroStrikesTest) { + const std::string last_four = "1234"; + strike_database_.AddStrike(last_four); + EXPECT_EQ(1, strike_database_.GetStrikes(last_four)); + strike_database_.ClearStrikes(last_four); + EXPECT_EQ(0, strike_database_.GetStrikes(last_four)); +} + +TEST_F(CreditCardSaveStrikeDatabaseTest, ClearStrikesForZeroStrikesTest) { + const std::string last_four = "1234"; + strike_database_.ClearStrikes(last_four); + EXPECT_EQ(0, strike_database_.GetStrikes(last_four)); +} + +} // namespace autofill
diff --git a/components/autofill/core/browser/strike_database.cc b/components/autofill/core/browser/strike_database.cc index 451af485..6e0e8b8 100644 --- a/components/autofill/core/browser/strike_database.cc +++ b/components/autofill/core/browser/strike_database.cc
@@ -39,6 +39,10 @@ StrikeDatabase::~StrikeDatabase() {} +bool StrikeDatabase::IsMaxStrikesLimitReached(const std::string id) { + return GetStrikes(id) >= GetMaxStrikesLimit(); +} + int StrikeDatabase::AddStrike(const std::string id) { std::string key = GetKey(id); int num_strikes = strike_map_cache_.count(key) // Cache has entry for |key|. @@ -50,6 +54,9 @@ base::Time::Now().ToDeltaSinceWindowsEpoch().InMicroseconds()); UpdateCache(key, data); SetProtoStrikeData(key, data, base::DoNothing()); + base::UmaHistogramCounts1000( + "Autofill.StrikeDatabase.NthStrikeAdded." + GetProjectPrefix(), + num_strikes); return num_strikes; }
diff --git a/components/autofill/core/browser/strike_database.h b/components/autofill/core/browser/strike_database.h index 6b79c564..5c69ace7 100644 --- a/components/autofill/core/browser/strike_database.h +++ b/components/autofill/core/browser/strike_database.h
@@ -43,7 +43,7 @@ explicit StrikeDatabase(const base::FilePath& database_dir); ~StrikeDatabase() override; - bool IsMaxStrikesLimitReached(); + bool IsMaxStrikesLimitReached(const std::string id); // Increments in-memory cache and updates underlying ProtoDatabase. int AddStrike(const std::string id); @@ -78,6 +78,8 @@ private: FRIEND_TEST_ALL_PREFIXES(ChromeBrowsingDataRemoverDelegateTest, StrikeDatabaseEmptyOnAutofillRemoveEverything); + FRIEND_TEST_ALL_PREFIXES(CreditCardSaveStrikeDatabaseTest, + GetKeyForCreditCardSaveTest); friend class StrikeDatabaseTest; friend class StrikeDatabaseTester;
diff --git a/components/autofill/core/browser/test_credit_card_save_strike_database.cc b/components/autofill/core/browser/test_credit_card_save_strike_database.cc new file mode 100644 index 0000000..da24bb6 --- /dev/null +++ b/components/autofill/core/browser/test_credit_card_save_strike_database.cc
@@ -0,0 +1,15 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/autofill/core/browser/test_credit_card_save_strike_database.h" + +namespace autofill { + +TestCreditCardSaveStrikeDatabase::TestCreditCardSaveStrikeDatabase( + const base::FilePath& database_dir) + : CreditCardSaveStrikeDatabase(database_dir) { + database_initialized_ = true; +} + +} // namespace autofill
diff --git a/components/autofill/core/browser/test_credit_card_save_strike_database.h b/components/autofill/core/browser/test_credit_card_save_strike_database.h new file mode 100644 index 0000000..21c33a5 --- /dev/null +++ b/components/autofill/core/browser/test_credit_card_save_strike_database.h
@@ -0,0 +1,19 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_TEST_CREDIT_CARD_SAVE_STRIKE_DATABASE_H_ +#define COMPONENTS_AUTOFILL_CORE_BROWSER_TEST_CREDIT_CARD_SAVE_STRIKE_DATABASE_H_ + +#include "components/autofill/core/browser/credit_card_save_strike_database.h" + +namespace autofill { + +class TestCreditCardSaveStrikeDatabase : public CreditCardSaveStrikeDatabase { + public: + TestCreditCardSaveStrikeDatabase(const base::FilePath& database_dir); +}; + +} // namespace autofill + +#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_CREDIT_CARD_SAVE_STRIKE_DATABASE_H_
diff --git a/components/autofill_assistant/browser/controller.cc b/components/autofill_assistant/browser/controller.cc index 164352f..3bc8872 100644 --- a/components/autofill_assistant/browser/controller.cc +++ b/components/autofill_assistant/browser/controller.cc
@@ -142,40 +142,7 @@ } } -void Controller::Start(const GURL& initialUrl) { - DCHECK(initialUrl.is_valid()); - GetOrCheckScripts(initialUrl); - if (allow_autostart_) { - auto iter = parameters_->find(kCallerScriptParameterName); - // TODO(crbug.com/806868): Put back an explicit AUTOSTART parameter so we - // don't need to know who calls us. - if (iter != parameters_->end() && iter->second == "1") { - should_fail_after_checking_scripts_ = true; - GetUiController()->ShowOverlay(); - GetUiController()->ShowStatusMessage(l10n_util::GetStringFUTF8( - IDS_AUTOFILL_ASSISTANT_LOADING, - base::UTF8ToUTF16(web_contents()->GetVisibleURL().host()))); - } - } - - touchable_element_area_.SetOnUpdate(base::BindRepeating( - &UiController::UpdateTouchableArea, - // Unretained is safe, since touchable_element_area_ is guaranteed to be - // deleted before the UI controller. - base::Unretained(GetUiController()))); -} - void Controller::GetOrCheckScripts(const GURL& url) { - if (IsCookieExperimentEnabled() && !started_) { - GetWebController()->HasCookie( - base::BindOnce(&Controller::OnGetCookie, - // WebController is owned by Controller. - base::Unretained(this), url)); - return; - } else { - started_ = true; - } - if (!started_ || script_tracker_->running()) { return; } @@ -364,11 +331,6 @@ return false; } -void Controller::OnClickOverlay() { - GetUiController()->HideOverlay(); - // TODO(crbug.com/806868): Stop executing scripts. -} - void Controller::OnGetCookie(const GURL& initial_url, bool has_cookie) { if (has_cookie) { // This code is only active with the experiment parameter. @@ -386,12 +348,56 @@ void Controller::OnSetCookie(const GURL& initial_url, bool result) { DCHECK(result) << "Setting cookie failed"; - // Failing to set the cookie should not be fatal since it would prevent - // checking for available scripts. - started_ = true; + FinishStart(initial_url); +} - // Kick off another check scripts run since we may have blocked the first one. +void Controller::FinishStart(const GURL& initial_url) { + started_ = true; GetOrCheckScripts(initial_url); + if (allow_autostart_) { + auto iter = parameters_->find(kCallerScriptParameterName); + // TODO(crbug.com/806868): Put back an explicit AUTOSTART parameter so we + // don't need to know who calls us. + if (iter != parameters_->end() && iter->second == "1") { + should_fail_after_checking_scripts_ = true; + GetUiController()->ShowOverlay(); + GetUiController()->ShowStatusMessage(l10n_util::GetStringFUTF8( + IDS_AUTOFILL_ASSISTANT_LOADING, + base::UTF8ToUTF16(web_contents()->GetVisibleURL().host()))); + } + } + + touchable_element_area_.SetOnUpdate(base::BindRepeating( + &UiController::UpdateTouchableArea, + // Unretained is safe, since touchable_element_area_ is guaranteed to be + // deleted before the UI controller. + base::Unretained(GetUiController()))); +} + +void Controller::Start(const GURL& initialUrl) { + DCHECK(initialUrl.is_valid()); + if (IsCookieExperimentEnabled()) { + GetWebController()->HasCookie( + base::BindOnce(&Controller::OnGetCookie, + // WebController is owned by Controller. + base::Unretained(this), initialUrl)); + } else { + FinishStart(initialUrl); + } +} + +void Controller::OnClickOverlay() { + GetUiController()->HideOverlay(); + // TODO(crbug.com/806868): Stop executing scripts. +} + +void Controller::OnDestroy() { + delete this; +} + +bool Controller::Terminate() { + StopPeriodicScriptChecks(); + return script_tracker_->Terminate(); } void Controller::OnScriptSelected(const std::string& script_path) { @@ -403,6 +409,15 @@ ExecuteScript(script_path); } +void Controller::ScrollBy(float distanceXRatio, float distanceYRatio) { + GetWebController()->ScrollBy(distanceXRatio, distanceYRatio); + touchable_element_area_.UpdatePositions(); +} + +void Controller::UpdateTouchableArea() { + touchable_element_area_.UpdatePositions(); +} + std::string Controller::GetDebugContext() { base::Value dict(base::Value::Type::DICTIONARY); @@ -420,43 +435,6 @@ return output_js; } -void Controller::OnDestroy() { - delete this; -} - -bool Controller::Terminate() { - StopPeriodicScriptChecks(); - return script_tracker_->Terminate(); -} - -void Controller::ScrollBy(float distanceXRatio, float distanceYRatio) { - GetWebController()->ScrollBy(distanceXRatio, distanceYRatio); - touchable_element_area_.UpdatePositions(); -} - -void Controller::UpdateTouchableArea() { - touchable_element_area_.UpdatePositions(); -} - -void Controller::DidAttachInterstitialPage() { - GetUiController()->Shutdown(); -} - -void Controller::DidGetUserInteraction(const blink::WebInputEvent::Type type) { - switch (type) { - case blink::WebInputEvent::kTouchStart: - case blink::WebInputEvent::kGestureTapDown: - if (!script_tracker_->running()) { - script_tracker_->CheckScripts(kPeriodicScriptCheckInterval); - StartPeriodicScriptChecks(); - } - break; - - default: - break; - } -} - void Controller::OnNoRunnableScriptsAnymore() { if (script_tracker_->running()) return; @@ -502,8 +480,23 @@ GetUiController()->UpdateScripts(scripts_to_update); } -void Controller::DocumentAvailableInMainFrame() { - GetOrCheckScripts(web_contents()->GetLastCommittedURL()); +void Controller::DidAttachInterstitialPage() { + GetUiController()->Shutdown(); +} + +void Controller::DidGetUserInteraction(const blink::WebInputEvent::Type type) { + switch (type) { + case blink::WebInputEvent::kTouchStart: + case blink::WebInputEvent::kGestureTapDown: + if (!script_tracker_->running()) { + script_tracker_->CheckScripts(kPeriodicScriptCheckInterval); + StartPeriodicScriptChecks(); + } + break; + + default: + break; + } } void Controller::DidFinishLoad(content::RenderFrameHost* render_frame_host, @@ -550,6 +543,10 @@ } } +void Controller::DocumentAvailableInMainFrame() { + GetOrCheckScripts(web_contents()->GetLastCommittedURL()); +} + void Controller::RenderProcessGone(base::TerminationStatus status) { GetUiController()->Shutdown(); }
diff --git a/components/autofill_assistant/browser/controller.h b/components/autofill_assistant/browser/controller.h index 3a7d99f6..57379f9 100644 --- a/components/autofill_assistant/browser/controller.h +++ b/components/autofill_assistant/browser/controller.h
@@ -97,8 +97,9 @@ // a script terminated with a Stop action. void OnGetCookie(const GURL& initial_url, bool has_cookie); void OnSetCookie(const GURL& initial_url, bool result); + void FinishStart(const GURL& initial_url); - // Overrides content::UiDelegate: + // Overrides autofill_assistant::UiDelegate: void Start(const GURL& initialUrl) override; void OnClickOverlay() override; void OnDestroy() override; @@ -158,6 +159,7 @@ // elements. ElementArea touchable_element_area_; + // Flag indicates whether it is ready to fetch and execute scripts. bool started_ = false; base::WeakPtrFactory<Controller> weak_ptr_factory_;
diff --git a/components/autofill_assistant_strings.grdp b/components/autofill_assistant_strings.grdp index 37275e3..77fcbc8c 100644 --- a/components/autofill_assistant_strings.grdp +++ b/components/autofill_assistant_strings.grdp
@@ -28,5 +28,11 @@ <message name="IDS_AUTOFILL_ASSISTANT_DETAILS_DIFFER_GO_BACK" desc="Shown on a button allowing going back when details differ." formatter_data="android_java"> Go back </message> + <message name="IDS_AUTOFILL_ASSISTANT_FIRST_RUN_ACCESSIBILITY" desc="Accessibility description of Autofill Assistant first run screen is shown." formatter_data="android_java"> + Autofill assistant first run screen is shown + </message> + <message name="IDS_AUTOFILL_ASSISTANT_AVAILABLE_ACCESSIBILITY" desc="Accessibility description of Autofill Assistant is available." formatter_data="android_java"> + Autofill assistant is available near bottom of the screen + </message> </if> </grit-part>
diff --git a/components/crash/android/BUILD.gn b/components/crash/android/BUILD.gn index 97b8d2b4..05cc295 100644 --- a/components/crash/android/BUILD.gn +++ b/components/crash/android/BUILD.gn
@@ -4,22 +4,43 @@ import("//build/config/android/rules.gni") -_jni_sources = - [ "java/src/org/chromium/components/crash/browser/ChildProcessCrashObserver.java", - "java/src/org/chromium/components/crash/browser/CrashDumpManager.java" ] +_jni_sources = [ + "java/src/org/chromium/components/crash/browser/ChildProcessCrashObserver.java", + "java/src/org/chromium/components/crash/browser/CrashDumpManager.java", + "java/src/org/chromium/components/crash/CrashKeys.java", +] generate_jni("jni_headers") { sources = _jni_sources jni_package = "crash" } +java_cpp_enum("java_enums_srcjar") { + sources = [ + "crash_keys_android.h", + ] +} + android_library("java") { deps = [ "//base:base_java", ] + srcjar_deps = [ ":java_enums_srcjar" ] java_files = _jni_sources } +source_set("crash_android") { + sources = [ + "crash_keys_android.cc", + "crash_keys_android.h", + ] + deps = [ + ":jni_headers", + "//base", + "//components/crash/core/common:crash_key", + ] +} + android_library("javatests") { testonly = true deps = [ @@ -31,3 +52,15 @@ ] java_files = [ "javatests/src/org/chromium/components/crash/browser/CrashDumpManagerTest.java" ] } + +source_set("unit_tests") { + testonly = true + sources = [ + "crash_keys_android_unittest.cc", + ] + deps = [ + ":crash_android", + "//components/crash/core/common:crash_key", + "//testing/gtest", + ] +}
diff --git a/chrome/browser/android/crash/crash_keys_android.cc b/components/crash/android/crash_keys_android.cc similarity index 96% rename from chrome/browser/android/crash/crash_keys_android.cc rename to components/crash/android/crash_keys_android.cc index dfd065c..6eaadc1 100644 --- a/chrome/browser/android/crash/crash_keys_android.cc +++ b/components/crash/android/crash_keys_android.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/android/crash/crash_keys_android.h" +#include "components/crash/android/crash_keys_android.h" #include "base/android/jni_android.h" #include "base/android/jni_string.h"
diff --git a/chrome/browser/android/crash/crash_keys_android.h b/components/crash/android/crash_keys_android.h similarity index 72% rename from chrome/browser/android/crash/crash_keys_android.h rename to components/crash/android/crash_keys_android.h index 25636e0..a545dcd 100644 --- a/chrome/browser/android/crash/crash_keys_android.h +++ b/components/crash/android/crash_keys_android.h
@@ -2,14 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_ANDROID_CRASH_CRASH_KEYS_ANDROID_H_ -#define CHROME_BROWSER_ANDROID_CRASH_CRASH_KEYS_ANDROID_H_ +#ifndef COMPONENTS_CRASH_ANDROID_CRASH_KEYS_ANDROID_H_ +#define COMPONENTS_CRASH_ANDROID_CRASH_KEYS_ANDROID_H_ #include <string> // See CrashKeys.java for how to add a new crash key. // A Java counterpart will be generated for this enum. -// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser.crash +// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.components.crash enum class CrashKeyIndex { LOADED_DYNAMIC_MODULE = 0, ACTIVE_DYNAMIC_MODULE, @@ -23,4 +23,4 @@ void ClearAndroidCrashKey(CrashKeyIndex index); void FlushAndroidCrashKeys(); -#endif // CHROME_BROWSER_ANDROID_CRASH_CRASH_KEYS_ANDROID_H_ +#endif // COMPONENTS_CRASH_ANDROID_CRASH_KEYS_ANDROID_H_
diff --git a/chrome/browser/android/crash/crash_keys_android_unittest.cc b/components/crash/android/crash_keys_android_unittest.cc similarity index 95% rename from chrome/browser/android/crash/crash_keys_android_unittest.cc rename to components/crash/android/crash_keys_android_unittest.cc index e407826..45bae4b 100644 --- a/chrome/browser/android/crash/crash_keys_android_unittest.cc +++ b/components/crash/android/crash_keys_android_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 "chrome/browser/android/crash/crash_keys_android.h" +#include "components/crash/android/crash_keys_android.h" #include "components/crash/core/common/crash_key.h" #include "testing/gtest/include/gtest/gtest.h"
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/crash/CrashKeys.java b/components/crash/android/java/src/org/chromium/components/crash/CrashKeys.java similarity index 91% rename from chrome/android/java/src/org/chromium/chrome/browser/crash/CrashKeys.java rename to components/crash/android/java/src/org/chromium/components/crash/CrashKeys.java index 79eae23..17279b30 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/crash/CrashKeys.java +++ b/components/crash/android/java/src/org/chromium/components/crash/CrashKeys.java
@@ -2,7 +2,7 @@ // 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.crash; +package org.chromium.components.crash; import android.support.annotation.Nullable; @@ -19,6 +19,7 @@ * <li>The CrashKeyString array in {@code crash_keys_android.cc}</li> * <li>The {@link #KEYS} array in this class.</li> * </ol> + * The crash keys will only be included in browser process crash reports. */ public class CrashKeys { private static final String[] KEYS = @@ -47,7 +48,7 @@ * @param keyIndex The index of a crash key. * @return The key for the given index. */ - static String getKey(@CrashKeyIndex int keyIndex) { + public static String getKey(@CrashKeyIndex int keyIndex) { return KEYS[keyIndex]; } @@ -56,7 +57,7 @@ * the values have been flushed to the native side. * @see #flushToNative */ - AtomicReferenceArray<String> getValues() { + public AtomicReferenceArray<String> getValues() { assert !mFlushed; return mValues; } @@ -75,7 +76,6 @@ nativeSet(keyIndex, value); return; } - mValues.set(keyIndex, value); } @@ -84,7 +84,7 @@ * pure-Java exception handling is disabled in favor of native crash reporting. */ @CalledByNative - void flushToNative() { + public void flushToNative() { ThreadUtils.assertOnUiThread(); assert !mFlushed;
diff --git a/components/crash/content/app/BUILD.gn b/components/crash/content/app/BUILD.gn index 542a231..732ae726 100644 --- a/components/crash/content/app/BUILD.gn +++ b/components/crash/content/app/BUILD.gn
@@ -126,6 +126,7 @@ deps = [ "//base", "//components/browser_watcher:crash_stability", + "//components/gwp_asan/crash_handler", "//third_party/crashpad/crashpad/client", "//third_party/crashpad/crashpad/handler", "//third_party/crashpad/crashpad/minidump",
diff --git a/components/crash/content/app/DEPS b/components/crash/content/app/DEPS index 9f77331..019cf70 100644 --- a/components/crash/content/app/DEPS +++ b/components/crash/content/app/DEPS
@@ -2,6 +2,7 @@ "+sandbox", "+components/browser_watcher/stability_report_user_stream_data_source.h", + "+components/gwp_asan/crash_handler/crash_handler.h", "+content/public/common/content_descriptors.h", "+content/public/common/result_codes.h", "+third_party/crashpad",
diff --git a/components/crash/content/app/run_as_crashpad_handler_win.cc b/components/crash/content/app/run_as_crashpad_handler_win.cc index 7013c90..2948156 100644 --- a/components/crash/content/app/run_as_crashpad_handler_win.cc +++ b/components/crash/content/app/run_as_crashpad_handler_win.cc
@@ -16,6 +16,7 @@ #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "components/browser_watcher/stability_report_user_stream_data_source.h" +#include "components/gwp_asan/crash_handler/crash_handler.h" #include "third_party/crashpad/crashpad/client/crashpad_info.h" #include "third_party/crashpad/crashpad/client/simple_string_dictionary.h" #include "third_party/crashpad/crashpad/handler/handler_main.h" @@ -83,6 +84,9 @@ user_data_dir)); } + user_stream_data_sources.push_back( + std::make_unique<gwp_asan::UserStreamDataSource>()); + return crashpad::HandlerMain(static_cast<int>(storage.size()), argv_as_utf8.get(), &user_stream_data_sources); }
diff --git a/components/plugins/renderer/webview_plugin.cc b/components/plugins/renderer/webview_plugin.cc index ebb72780..d4c9c8a 100644 --- a/components/plugins/renderer/webview_plugin.cc +++ b/components/plugins/renderer/webview_plugin.cc
@@ -25,6 +25,7 @@ #include "third_party/blink/public/web/web_element.h" #include "third_party/blink/public/web/web_frame_widget.h" #include "third_party/blink/public/web/web_local_frame.h" +#include "third_party/blink/public/web/web_navigation_control.h" #include "third_party/blink/public/web/web_plugin_container.h" #include "third_party/blink/public/web/web_view.h" @@ -66,7 +67,7 @@ const GURL& url) { DCHECK(url.is_valid()) << "Blink requires the WebView to have a valid URL."; WebViewPlugin* plugin = new WebViewPlugin(render_view, delegate, preferences); - plugin->main_frame()->LoadHTMLString(html_data, url); + plugin->web_view_helper_.main_frame()->LoadHTMLString(html_data, url); return plugin; } @@ -269,13 +270,6 @@ web_view_->MainFrameWidget()->Close(); } -blink::WebLocalFrame* WebViewPlugin::WebViewHelper::main_frame() { - // WebViewHelper doesn't support OOPIFs so the main frame will - // always be local. - DCHECK(web_view_->MainFrame()->IsWebLocalFrame()); - return static_cast<WebLocalFrame*>(web_view_->MainFrame()); -} - bool WebViewPlugin::WebViewHelper::AcceptsLoadDrops() { return false; } @@ -311,7 +305,7 @@ const SkBitmap&, const gfx::Point&) { // Immediately stop dragging. - main_frame()->FrameWidget()->DragSourceSystemDragEnded(); + frame_->FrameWidget()->DragSourceSystemDragEnded(); } bool WebViewPlugin::WebViewHelper::AllowsBrokenNullLayerTreeView() const { @@ -353,13 +347,18 @@ ->CreateURLLoaderFactory(); } +void WebViewPlugin::WebViewHelper::BindToFrame( + blink::WebNavigationControl* frame) { + frame_ = frame; +} + void WebViewPlugin::WebViewHelper::DidClearWindowObject() { if (!plugin_->delegate_) return; v8::Isolate* isolate = blink::MainThreadIsolate(); v8::HandleScope handle_scope(isolate); - v8::Local<v8::Context> context = main_frame()->MainWorldScriptContext(); + v8::Local<v8::Context> context = frame_->MainWorldScriptContext(); DCHECK(!context.IsEmpty()); v8::Context::Scope context_scope(context); @@ -370,15 +369,16 @@ } void WebViewPlugin::WebViewHelper::FrameDetached(DetachType type) { - main_frame()->FrameWidget()->Close(); - main_frame()->Close(); + frame_->FrameWidget()->Close(); + frame_->Close(); + frame_ = nullptr; } void WebViewPlugin::WebViewHelper::BeginNavigation( std::unique_ptr<blink::WebNavigationInfo> info) { // TODO(dgozman): remove this method and effectively disallow // content-inititated navigations in WebViewPlugin. - main_frame()->CommitNavigation( + frame_->CommitNavigation( info->url_request, info->frame_load_type, blink::WebHistoryItem(), info->is_client_redirect, base::UnguessableToken::Create(), nullptr /* navigation_params */, nullptr /* extra_data */);
diff --git a/components/plugins/renderer/webview_plugin.h b/components/plugins/renderer/webview_plugin.h index 015ed87..111fb708 100644 --- a/components/plugins/renderer/webview_plugin.h +++ b/components/plugins/renderer/webview_plugin.h
@@ -16,6 +16,7 @@ #include "third_party/blink/public/platform/web_url_response.h" #include "third_party/blink/public/web/blink.h" #include "third_party/blink/public/web/web_local_frame_client.h" +#include "third_party/blink/public/web/web_navigation_control.h" #include "third_party/blink/public/web/web_plugin.h" #include "third_party/blink/public/web/web_view_client.h" #include "third_party/blink/public/web/web_widget_client.h" @@ -157,7 +158,7 @@ ~WebViewHelper() override; blink::WebView* web_view() { return web_view_; } - blink::WebLocalFrame* main_frame(); + blink::WebNavigationControl* main_frame() { return frame_; } // WebViewClient methods: bool AcceptsLoadDrops() override; @@ -184,6 +185,7 @@ override; // WebLocalFrameClient methods: + void BindToFrame(blink::WebNavigationControl* frame) override; void DidClearWindowObject() override; void FrameDetached(DetachType) override; void BeginNavigation( @@ -191,6 +193,7 @@ private: WebViewPlugin* plugin_; + blink::WebNavigationControl* frame_ = nullptr; // Owned by us, deleted via |close()|. blink::WebView* web_view_;
diff --git a/components/printing/renderer/print_render_frame_helper.cc b/components/printing/renderer/print_render_frame_helper.cc index 3a91761..9fb226cd 100644 --- a/components/printing/renderer/print_render_frame_helper.cc +++ b/components/printing/renderer/print_render_frame_helper.cc
@@ -53,6 +53,7 @@ #include "third_party/blink/public/web/web_frame_widget.h" #include "third_party/blink/public/web/web_local_frame.h" #include "third_party/blink/public/web/web_local_frame_client.h" +#include "third_party/blink/public/web/web_navigation_control.h" #include "third_party/blink/public/web/web_plugin.h" #include "third_party/blink/public/web/web_plugin_document.h" #include "third_party/blink/public/web/web_print_params.h" @@ -670,7 +671,9 @@ class HeaderAndFooterClient final : public blink::WebLocalFrameClient { public: // WebLocalFrameClient: - void BindToFrame(blink::WebLocalFrame* frame) override { frame_ = frame; } + void BindToFrame(blink::WebNavigationControl* frame) override { + frame_ = frame; + } void FrameDetached(DetachType detach_type) override { frame_->FrameWidget()->Close(); frame_->Close(); @@ -685,7 +688,7 @@ } private: - blink::WebLocalFrame* frame_; + blink::WebNavigationControl* frame_ = nullptr; }; class NonCompositingWebWidgetClient : public blink::WebWidgetClient { @@ -788,6 +791,7 @@ WebWidgetClient* WidgetClient() override { return this; } // blink::WebLocalFrameClient: + void BindToFrame(blink::WebNavigationControl* frame) override; blink::WebLocalFrame* CreateChildFrame( blink::WebLocalFrame* parent, blink::WebTreeScopeType scope, @@ -807,6 +811,7 @@ void CopySelection(const WebPreferences& preferences); FrameReference frame_; + blink::WebNavigationControl* navigation_control_ = nullptr; blink::WebNode node_to_print_; bool owns_web_view_ = false; blink::WebPrintParams web_print_params_; @@ -939,8 +944,8 @@ // When loading is done this will call didStopLoading() and that will do the // actual printing. - frame()->LoadHTMLString(blink::WebData(html), - blink::WebURL(GURL(url::kAboutBlankURL))); + navigation_control_->LoadHTMLString(blink::WebData(html), + blink::WebURL(GURL(url::kAboutBlankURL))); } bool PrepareFrameAndViewForPrint::AllowsBrokenNullLayerTreeView() const { @@ -960,6 +965,11 @@ weak_ptr_factory_.GetWeakPtr())); } +void PrepareFrameAndViewForPrint::BindToFrame( + blink::WebNavigationControl* navigation_control) { + navigation_control_ = navigation_control; +} + blink::WebLocalFrame* PrepareFrameAndViewForPrint::CreateChildFrame( blink::WebLocalFrame* parent, blink::WebTreeScopeType scope, @@ -981,6 +991,7 @@ DCHECK(frame); frame->FrameWidget()->Close(); frame->Close(); + navigation_control_ = nullptr; frame_.Reset(nullptr); } @@ -988,7 +999,7 @@ std::unique_ptr<blink::WebNavigationInfo> info) { // TODO(dgozman): We disable javascript through WebPreferences, so perhaps // we want to disallow any navigations here by just removing this method? - frame()->CommitNavigation( + navigation_control_->CommitNavigation( info->url_request, info->frame_load_type, blink::WebHistoryItem(), info->is_client_redirect, base::UnguessableToken::Create(), nullptr /* navigation_params */, nullptr /* extra_data */); @@ -1039,6 +1050,7 @@ web_view->MainFrameWidget()->Close(); } } + navigation_control_ = nullptr; frame_.Reset(nullptr); on_ready_.Reset(); }
diff --git a/components/test/data/js_dialogs/render_tests/VrBrowserJavaScriptModalDialogTest.js_modal_view_vr_alert.Pixel_XL-25.png b/components/test/data/js_dialogs/render_tests/VrBrowserJavaScriptModalDialogTest.js_modal_view_vr_alert.Pixel_XL-25.png index fcb15074..7ca1ffac 100644 --- a/components/test/data/js_dialogs/render_tests/VrBrowserJavaScriptModalDialogTest.js_modal_view_vr_alert.Pixel_XL-25.png +++ b/components/test/data/js_dialogs/render_tests/VrBrowserJavaScriptModalDialogTest.js_modal_view_vr_alert.Pixel_XL-25.png Binary files differ
diff --git a/components/test/data/js_dialogs/render_tests/VrBrowserJavaScriptModalDialogTest.js_modal_view_vr_alert.Pixel_XL-26.png b/components/test/data/js_dialogs/render_tests/VrBrowserJavaScriptModalDialogTest.js_modal_view_vr_alert.Pixel_XL-26.png index 6d0c881..546724a 100644 --- a/components/test/data/js_dialogs/render_tests/VrBrowserJavaScriptModalDialogTest.js_modal_view_vr_alert.Pixel_XL-26.png +++ b/components/test/data/js_dialogs/render_tests/VrBrowserJavaScriptModalDialogTest.js_modal_view_vr_alert.Pixel_XL-26.png Binary files differ
diff --git a/components/test/data/js_dialogs/render_tests/VrBrowserJavaScriptModalDialogTest.js_modal_view_vr_confirm.Pixel_XL-25.png b/components/test/data/js_dialogs/render_tests/VrBrowserJavaScriptModalDialogTest.js_modal_view_vr_confirm.Pixel_XL-25.png index 7d69967..d545f85c 100644 --- a/components/test/data/js_dialogs/render_tests/VrBrowserJavaScriptModalDialogTest.js_modal_view_vr_confirm.Pixel_XL-25.png +++ b/components/test/data/js_dialogs/render_tests/VrBrowserJavaScriptModalDialogTest.js_modal_view_vr_confirm.Pixel_XL-25.png Binary files differ
diff --git a/components/test/data/js_dialogs/render_tests/VrBrowserJavaScriptModalDialogTest.js_modal_view_vr_confirm.Pixel_XL-26.png b/components/test/data/js_dialogs/render_tests/VrBrowserJavaScriptModalDialogTest.js_modal_view_vr_confirm.Pixel_XL-26.png index 50fc5eb3..5971b68 100644 --- a/components/test/data/js_dialogs/render_tests/VrBrowserJavaScriptModalDialogTest.js_modal_view_vr_confirm.Pixel_XL-26.png +++ b/components/test/data/js_dialogs/render_tests/VrBrowserJavaScriptModalDialogTest.js_modal_view_vr_confirm.Pixel_XL-26.png Binary files differ
diff --git a/components/test/data/js_dialogs/render_tests/VrBrowserJavaScriptModalDialogTest.js_modal_view_vr_prompt.Pixel_XL-25.png b/components/test/data/js_dialogs/render_tests/VrBrowserJavaScriptModalDialogTest.js_modal_view_vr_prompt.Pixel_XL-25.png index 39d529d..6b729e3 100644 --- a/components/test/data/js_dialogs/render_tests/VrBrowserJavaScriptModalDialogTest.js_modal_view_vr_prompt.Pixel_XL-25.png +++ b/components/test/data/js_dialogs/render_tests/VrBrowserJavaScriptModalDialogTest.js_modal_view_vr_prompt.Pixel_XL-25.png Binary files differ
diff --git a/components/test/data/js_dialogs/render_tests/VrBrowserJavaScriptModalDialogTest.js_modal_view_vr_prompt.Pixel_XL-26.png b/components/test/data/js_dialogs/render_tests/VrBrowserJavaScriptModalDialogTest.js_modal_view_vr_prompt.Pixel_XL-26.png index aec7f9973..ea29cb3d 100644 --- a/components/test/data/js_dialogs/render_tests/VrBrowserJavaScriptModalDialogTest.js_modal_view_vr_prompt.Pixel_XL-26.png +++ b/components/test/data/js_dialogs/render_tests/VrBrowserJavaScriptModalDialogTest.js_modal_view_vr_prompt.Pixel_XL-26.png Binary files differ
diff --git a/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_granted_browser_ui.Pixel_XL-25.png b/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_granted_browser_ui.Pixel_XL-25.png index 2168ff5..307c4e4 100644 --- a/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_granted_browser_ui.Pixel_XL-25.png +++ b/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_granted_browser_ui.Pixel_XL-25.png Binary files differ
diff --git a/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_granted_browser_ui.Pixel_XL-26.png b/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_granted_browser_ui.Pixel_XL-26.png index 41932e3..a25bffee 100644 --- a/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_granted_browser_ui.Pixel_XL-26.png +++ b/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_granted_browser_ui.Pixel_XL-26.png Binary files differ
diff --git a/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_visible_browser_ui.Pixel_XL-25.png b/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_visible_browser_ui.Pixel_XL-25.png index c20d6ad56..5769baa 100644 --- a/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_visible_browser_ui.Pixel_XL-25.png +++ b/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_visible_browser_ui.Pixel_XL-25.png Binary files differ
diff --git a/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_visible_browser_ui.Pixel_XL-26.png b/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_visible_browser_ui.Pixel_XL-26.png index 54d15f3..ba02734 100644 --- a/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_visible_browser_ui.Pixel_XL-26.png +++ b/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_visible_browser_ui.Pixel_XL-26.png Binary files differ
diff --git a/components/viz/host/hit_test/hit_test_query_fuzzer.cc b/components/viz/host/hit_test/hit_test_query_fuzzer.cc index 772637e5..89d2da18 100644 --- a/components/viz/host/hit_test/hit_test_query_fuzzer.cc +++ b/components/viz/host/hit_test/hit_test_query_fuzzer.cc
@@ -14,11 +14,6 @@ namespace { -uint32_t GetNextUInt32(base::FuzzedDataProvider* fuzz) { - return fuzz->ConsumeUint32InRange(std::numeric_limits<uint32_t>::min(), - std::numeric_limits<uint32_t>::max()); -} - void AddHitTestRegion(base::FuzzedDataProvider* fuzz, std::vector<viz::AggregatedHitTestRegion>* regions, std::vector<viz::FrameSinkId>* frame_sink_ids, @@ -26,17 +21,17 @@ constexpr uint32_t kMaxDepthAllowed = 25; if (fuzz->remaining_bytes() < sizeof(viz::AggregatedHitTestRegion)) return; - viz::FrameSinkId frame_sink_id(GetNextUInt32(fuzz), GetNextUInt32(fuzz)); - uint32_t flags = GetNextUInt32(fuzz); + viz::FrameSinkId frame_sink_id(fuzz->ConsumeUint32(), fuzz->ConsumeUint32()); + uint32_t flags = fuzz->ConsumeUint32(); // The reasons' value is kNotAsyncHitTest if the flag's value is kHitTestAsk. - uint32_t reasons = - (flags & viz::HitTestRegionFlags::kHitTestAsk) - ? fuzz->ConsumeUint32InRange(1, std::numeric_limits<uint32_t>::max()) - : viz::AsyncHitTestReasons::kNotAsyncHitTest; + uint32_t reasons = (flags & viz::HitTestRegionFlags::kHitTestAsk) + ? fuzz->ConsumeIntegralInRange<uint32_t>( + 1, std::numeric_limits<uint32_t>::max()) + : viz::AsyncHitTestReasons::kNotAsyncHitTest; gfx::Rect rect(fuzz->ConsumeUint8(), fuzz->ConsumeUint8(), fuzz->ConsumeUint16(), fuzz->ConsumeUint16()); int32_t child_count = - depth < kMaxDepthAllowed ? fuzz->ConsumeUint32InRange(0, 10) : 0; + depth < kMaxDepthAllowed ? fuzz->ConsumeIntegralInRange(0, 10) : 0; gfx::Transform transform; if (fuzz->ConsumeBool() && fuzz->remaining_bytes() >= sizeof(transform)) { std::vector<uint8_t> matrix_bytes =
diff --git a/components/viz/host/host_gpu_memory_buffer_manager_unittest.cc b/components/viz/host/host_gpu_memory_buffer_manager_unittest.cc index e534bb0..957fa0a 100644 --- a/components/viz/host/host_gpu_memory_buffer_manager_unittest.cc +++ b/components/viz/host/host_gpu_memory_buffer_manager_unittest.cc
@@ -15,6 +15,10 @@ #include "testing/gtest/include/gtest/gtest.h" #include "ui/gfx/client_native_pixmap_factory.h" +#if defined(USE_OZONE) +#include "ui/ozone/public/ozone_platform.h" +#endif + namespace viz { namespace { @@ -171,34 +175,6 @@ DISALLOW_COPY_AND_ASSIGN(TestGpuService); }; -// It is necessary to install a custom pixmap factory which claims to support -// all native configurations, so that code that deals with this can be tested -// correctly. -class FakeClientNativePixmapFactory : public gfx::ClientNativePixmapFactory { - public: - explicit FakeClientNativePixmapFactory(bool allow_native_buffers) - : allow_native_buffers_(allow_native_buffers) {} - ~FakeClientNativePixmapFactory() override {} - - // gfx::ClientNativePixmapFactory: - bool IsConfigurationSupported(gfx::BufferFormat format, - gfx::BufferUsage usage) const override { - return allow_native_buffers_; - } - std::unique_ptr<gfx::ClientNativePixmap> ImportFromHandle( - const gfx::NativePixmapHandle& handle, - const gfx::Size& size, - gfx::BufferUsage usage) override { - NOTREACHED(); - return nullptr; - } - - private: - bool allow_native_buffers_ = false; - - DISALLOW_COPY_AND_ASSIGN(FakeClientNativePixmapFactory); -}; - } // namespace class HostGpuMemoryBufferManagerTest : public ::testing::Test { @@ -232,32 +208,33 @@ DISALLOW_COPY_AND_ASSIGN(HostGpuMemoryBufferManagerTest); }; -std::unique_ptr<gpu::GpuMemoryBufferSupport> MakeGpuMemoryBufferSupport( - bool allow_native_buffers) { -#if defined(OS_LINUX) - return std::make_unique<gpu::GpuMemoryBufferSupport>( - std::make_unique<FakeClientNativePixmapFactory>(allow_native_buffers)); -#else - return std::make_unique<gpu::GpuMemoryBufferSupport>(); -#endif -} - // Tests that allocation requests from a client that goes away before allocation // completes are cleaned up correctly. TEST_F(HostGpuMemoryBufferManagerTest, AllocationRequestsForDestroyedClient) { -#if !defined(USE_OZONE) && !defined(OS_MACOSX) && !defined(OS_WIN) - // Not all platforms support native configurations (currently only ozone and - // mac support it). Abort the test in those platforms. - gpu::GpuMemoryBufferSupport support; - DCHECK(gpu::GetNativeGpuMemoryBufferConfigurations(&support).empty()); - return; -#else + // Not all platforms support native configurations (currently only Windows, + // Mac and some Ozone platforms). Abort the test in those platforms. + bool native_pixmap_supported = false; +#if defined(USE_OZONE) + native_pixmap_supported = + ui::OzonePlatform::GetInstance()->IsNativePixmapConfigSupported( + gfx::BufferFormat::RGBA_8888, gfx::BufferUsage::GPU_READ); +#elif defined(OS_MACOSX) || defined(OS_WIN) + native_pixmap_supported = true; +#endif + + if (!native_pixmap_supported) { + gpu::GpuMemoryBufferSupport support; + DCHECK(gpu::GetNativeGpuMemoryBufferConfigurations(&support).empty()); + return; + } + // Note: HostGpuMemoryBufferManager normally operates on a mojom::GpuService // implementation over mojo. Which means the communication from SGMBManager to // GpuService is asynchronous. In this test, the mojom::GpuService is not // bound to a mojo pipe, which means those calls are all synchronous. TestGpuService gpu_service; - auto gpu_memory_buffer_support = MakeGpuMemoryBufferSupport(true); + auto gpu_memory_buffer_support = + std::make_unique<gpu::GpuMemoryBufferSupport>(); HostGpuMemoryBufferManager manager(gpu_service.CreateProvider(), 1, std::move(gpu_memory_buffer_support), base::ThreadTaskRunnerHandle::Get()); @@ -282,12 +259,12 @@ // should request the allocated memory to be freed. gpu_service.SatisfyAllocationRequest(buffer_id, client_id); EXPECT_TRUE(gpu_service.HasDestructionRequest(buffer_id, client_id)); -#endif } TEST_F(HostGpuMemoryBufferManagerTest, RequestsFromUntrustedClientsValidated) { TestGpuService gpu_service; - auto gpu_memory_buffer_support = MakeGpuMemoryBufferSupport(false); + auto gpu_memory_buffer_support = + std::make_unique<gpu::GpuMemoryBufferSupport>(); HostGpuMemoryBufferManager manager(gpu_service.CreateProvider(), 1, std::move(gpu_memory_buffer_support), base::ThreadTaskRunnerHandle::Get()); @@ -332,7 +309,8 @@ TEST_F(HostGpuMemoryBufferManagerTest, GpuMemoryBufferDestroyed) { TestGpuService gpu_service; - auto gpu_memory_buffer_support = MakeGpuMemoryBufferSupport(false); + auto gpu_memory_buffer_support = + std::make_unique<gpu::GpuMemoryBufferSupport>(); HostGpuMemoryBufferManager manager(gpu_service.CreateProvider(), 1, std::move(gpu_memory_buffer_support), base::ThreadTaskRunnerHandle::Get()); @@ -344,7 +322,8 @@ TEST_F(HostGpuMemoryBufferManagerTest, GpuMemoryBufferDestroyedOnDifferentThread) { TestGpuService gpu_service; - auto gpu_memory_buffer_support = MakeGpuMemoryBufferSupport(false); + auto gpu_memory_buffer_support = + std::make_unique<gpu::GpuMemoryBufferSupport>(); HostGpuMemoryBufferManager manager(gpu_service.CreateProvider(), 1, std::move(gpu_memory_buffer_support), base::ThreadTaskRunnerHandle::Get());
diff --git a/components/viz/service/display/gl_renderer_unittest.cc b/components/viz/service/display/gl_renderer_unittest.cc index 06e64fe..35732a7 100644 --- a/components/viz/service/display/gl_renderer_unittest.cc +++ b/components/viz/service/display/gl_renderer_unittest.cc
@@ -4153,10 +4153,6 @@ /*secure_output_only=*/false, ui::ProtectedVideoType::kClear); EXPECT_CALL(overlay_scheduler, - Schedule(0, gfx::OVERLAY_TRANSFORM_NONE, kSurfaceOverlayTextureId, - gfx::Rect(viewport_size), _, _, kGpuFenceId)) - .Times(1); - EXPECT_CALL(overlay_scheduler, Schedule(1, gfx::OVERLAY_TRANSFORM_NONE, _, gfx::Rect(viewport_size), _, _, kGpuFenceId)) .Times(1);
diff --git a/components/viz/service/display/overlay_processor.cc b/components/viz/service/display/overlay_processor.cc index 20bd647..bc662fce 100644 --- a/components/viz/service/display/overlay_processor.cc +++ b/components/viz/service/display/overlay_processor.cc
@@ -9,6 +9,7 @@ #include "base/metrics/histogram_macros.h" #include "base/trace_event/trace_event.h" #include "build/build_config.h" +#include "components/viz/common/quads/solid_color_draw_quad.h" #include "components/viz/service/display/dc_layer_overlay.h" #include "components/viz/service/display/display_resource_provider.h" #include "components/viz/service/display/output_surface.h" @@ -251,4 +252,61 @@ damage_rect->Union(output_surface_overlay_damage_rect); } +namespace { + +bool DiscardableQuad(const DrawQuad* q) { + float opacity = q->shared_quad_state->opacity; + if (opacity < std::numeric_limits<float>::epsilon()) + return true; + + if (q->material == DrawQuad::SOLID_COLOR) { + if (SolidColorDrawQuad::MaterialCast(q)->color == SK_ColorBLACK || + SolidColorDrawQuad::MaterialCast(q)->color == SK_ColorTRANSPARENT) + return true; + + const SkColor color = SolidColorDrawQuad::MaterialCast(q)->color; + const float alpha = (SkColorGetA(color) * (1.0f / 255.0f)) * opacity; + return q->ShouldDrawWithBlending() && + alpha < std::numeric_limits<float>::epsilon(); + } + + return false; +} + +} // namespace + +// static +void OverlayProcessor::EliminateOrCropPrimary( + const QuadList& quad_list, + const QuadList::Iterator& candidate_iterator, + OverlayCandidate* primary, + OverlayCandidateList* candidate_list) { + gfx::RectF content_rect; + + for (auto it = quad_list.begin(); it != quad_list.end(); ++it) { + if (it == candidate_iterator) + continue; + if (!DiscardableQuad(*it)) { + auto& transform = it->shared_quad_state->quad_to_target_transform; + gfx::RectF display_rect = gfx::RectF(it->rect); + transform.TransformRect(&display_rect); + content_rect.Union(display_rect); + } + } + + if (!content_rect.IsEmpty()) { + // Sometimes the content quads extend past primary->display_rect, so first + // clip the content_rect to that. + content_rect.Intersect(primary->display_rect); + DCHECK_NE(0, primary->display_rect.width()); + DCHECK_NE(0, primary->display_rect.height()); + primary->uv_rect = gfx::ScaleRect( + content_rect, 1. / primary->resource_size_in_pixels.width(), + 1. / primary->resource_size_in_pixels.height()); + primary->display_rect = content_rect; + + candidate_list->push_back(*primary); + } +} + } // namespace viz
diff --git a/components/viz/service/display/overlay_processor.h b/components/viz/service/display/overlay_processor.h index e3f25e0..14797b4 100644 --- a/components/viz/service/display/overlay_processor.h +++ b/components/viz/service/display/overlay_processor.h
@@ -79,6 +79,15 @@ gfx::Rect* damage_rect, std::vector<gfx::Rect>* content_bounds); + // Determine if we can eliminate (all remaining quads are black or + // transparent) or crop (non-black content is a small sub-rectangle) the + // primary framebuffer. + static void EliminateOrCropPrimary( + const QuadList& quad_list, + const QuadList::Iterator& candidate_iterator, + OverlayCandidate* primary, + OverlayCandidateList* candidate_list); + protected: StrategyList strategies_; OutputSurface* surface_;
diff --git a/components/viz/service/display/overlay_strategy_single_on_top.cc b/components/viz/service/display/overlay_strategy_single_on_top.cc index ccfc620..100332f6 100644 --- a/components/viz/service/display/overlay_strategy_single_on_top.cc +++ b/components/viz/service/display/overlay_strategy_single_on_top.cc
@@ -44,29 +44,25 @@ if (best_quad_it == quad_list->end()) return false; - if (TryOverlay(quad_list, candidate_list, best_candidate, best_quad_it)) - return true; + OverlayCandidateList new_candidate_list; + if (candidate_list->size() == 1) { + OverlayCandidate primary(candidate_list->back()); + OverlayProcessor::EliminateOrCropPrimary(*quad_list, best_quad_it, &primary, + &new_candidate_list); + } else { + new_candidate_list = *candidate_list; + } - return false; -} - -bool OverlayStrategySingleOnTop::TryOverlay( - QuadList* quad_list, - OverlayCandidateList* candidate_list, - const OverlayCandidate& candidate, - QuadList::Iterator candidate_iterator) { // Add the overlay. - OverlayCandidateList new_candidate_list = *candidate_list; - new_candidate_list.push_back(candidate); + new_candidate_list.push_back(best_candidate); new_candidate_list.back().plane_z_order = 1; // Check for support. capability_checker_->CheckOverlaySupport(&new_candidate_list); - const OverlayCandidate& overlay_candidate = new_candidate_list.back(); // If the candidate can be handled by an overlay, create a pass for it. - if (overlay_candidate.overlay_handled) { - quad_list->EraseAndInvalidateAllPointers(candidate_iterator); + if (new_candidate_list.back().overlay_handled) { + quad_list->EraseAndInvalidateAllPointers(best_quad_it); candidate_list->swap(new_candidate_list); return true; }
diff --git a/components/viz/service/display/overlay_strategy_underlay.cc b/components/viz/service/display/overlay_strategy_underlay.cc index 2dd89a5..b0bf8355 100644 --- a/components/viz/service/display/overlay_strategy_underlay.cc +++ b/components/viz/service/display/overlay_strategy_underlay.cc
@@ -57,11 +57,19 @@ continue; } + OverlayCandidateList new_candidate_list; + if (candidate_list->size() == 1) { + OverlayCandidate primary(candidate_list->back()); + primary.is_opaque = false; + OverlayProcessor::EliminateOrCropPrimary(quad_list, it, &primary, + &new_candidate_list); + } else { + new_candidate_list = *candidate_list; + } + // Add the overlay. - OverlayCandidateList new_candidate_list = *candidate_list; new_candidate_list.push_back(candidate); new_candidate_list.back().plane_z_order = -1; - new_candidate_list.front().is_opaque = false; // Check for support. capability_checker_->CheckOverlaySupport(&new_candidate_list);
diff --git a/components/viz/service/display/overlay_unittest.cc b/components/viz/service/display/overlay_unittest.cc index 8a3c848..411b85f 100644 --- a/components/viz/service/display/overlay_unittest.cc +++ b/components/viz/service/display/overlay_unittest.cc
@@ -583,6 +583,18 @@ std::vector<gfx::Rect> content_bounds_; }; +OverlayCandidateList BackbufferOverlayList(const RenderPass* root_render_pass) { + OverlayCandidateList list; + OverlayCandidate output_surface_plane; + output_surface_plane.display_rect = gfx::RectF(root_render_pass->output_rect); + output_surface_plane.resource_size_in_pixels = + root_render_pass->output_rect.size(); + output_surface_plane.use_output_surface_for_resource = true; + output_surface_plane.overlay_handled = true; + list.push_back(output_surface_plane); + return list; +} + using FullscreenOverlayTest = OverlayTest<FullscreenOverlayValidator>; using SingleOverlayOnTopTest = OverlayTest<SingleOnTopOverlayValidator>; using UnderlayTest = OverlayTest<UnderlayOverlayValidator>; @@ -1544,6 +1556,25 @@ EXPECT_EQ(0U, candidate_list.size()); } +TEST_F(SingleOverlayOnTopTest, AllowVideoNormalTransform) { + std::unique_ptr<RenderPass> pass = CreateRenderPass(); + CreateFullscreenCandidateVideoQuad( + resource_provider_.get(), child_resource_provider_.get(), + child_provider_.get(), pass->shared_quad_state_list.back(), pass.get(), + kNormalTransform); + + OverlayCandidateList candidate_list; + OverlayProcessor::FilterOperationsMap render_pass_filters; + OverlayProcessor::FilterOperationsMap render_pass_background_filters; + RenderPassList pass_list; + pass_list.push_back(std::move(pass)); + overlay_processor_->ProcessForOverlays( + resource_provider_.get(), &pass_list, GetIdentityColorMatrix(), + render_pass_filters, render_pass_background_filters, &candidate_list, + nullptr, nullptr, &damage_rect_, &content_bounds_); + EXPECT_EQ(1U, candidate_list.size()); +} + TEST_F(SingleOverlayOnTopTest, RejectVideoSwapTransform) { std::unique_ptr<RenderPass> pass = CreateRenderPass(); CreateFullscreenCandidateVideoQuad( @@ -1563,6 +1594,33 @@ EXPECT_EQ(0U, candidate_list.size()); } +TEST_F(SingleOverlayOnTopTest, + AllowVideoNormalTransformWithOutputSurfaceOverlay) { + std::unique_ptr<RenderPass> pass = CreateRenderPass(); + CreateFullscreenCandidateQuad( + resource_provider_.get(), child_resource_provider_.get(), + child_provider_.get(), pass->shared_quad_state_list.back(), pass.get()); + + gfx::Rect video_rect = gfx::ScaleToEnclosingRect(pass->output_rect, .5); + CreateCandidateVideoQuadAt( + resource_provider_.get(), child_resource_provider_.get(), + child_provider_.get(), pass->shared_quad_state_list.back(), pass.get(), + video_rect, kNormalTransform); + + OverlayCandidateList candidate_list(BackbufferOverlayList(pass.get())); + OverlayProcessor::FilterOperationsMap render_pass_filters; + OverlayProcessor::FilterOperationsMap render_pass_background_filters; + RenderPassList pass_list; + pass_list.push_back(std::move(pass)); + overlay_processor_->ProcessForOverlays( + resource_provider_.get(), &pass_list, GetIdentityColorMatrix(), + render_pass_filters, render_pass_background_filters, &candidate_list, + nullptr, nullptr, &damage_rect_, &content_bounds_); + ASSERT_EQ(2U, candidate_list.size()); + EXPECT_EQ(candidate_list[0].uv_rect, gfx::RectF(.5, .5)); + EXPECT_EQ(candidate_list[1].uv_rect, gfx::RectF(.1, .2, .9, .8)); +} + TEST_F(UnderlayTest, AllowVideoXMirrorTransform) { std::unique_ptr<RenderPass> pass = CreateRenderPass(); CreateFullscreenCandidateVideoQuad( @@ -1928,6 +1986,7 @@ OverlayCandidateList candidate_list; OverlayCandidate candidate; + candidate.display_rect = gfx::RectF(pass->output_rect); candidate.use_output_surface_for_resource = true; candidate.is_opaque = true; candidate_list.push_back(candidate); @@ -2226,6 +2285,7 @@ OverlayCandidateList candidate_list; OverlayCandidate candidate; + candidate.display_rect = gfx::RectF(pass->output_rect); candidate.use_output_surface_for_resource = true; candidate.is_opaque = true; candidate_list.push_back(candidate); @@ -2265,16 +2325,6 @@ EXPECT_TRUE(content_bounds_.empty()); } -OverlayCandidateList BackbufferOverlayList(const RenderPass* root_render_pass) { - OverlayCandidateList list; - OverlayCandidate output_surface_plane; - output_surface_plane.display_rect = gfx::RectF(root_render_pass->output_rect); - output_surface_plane.use_output_surface_for_resource = true; - output_surface_plane.overlay_handled = true; - list.push_back(output_surface_plane); - return list; -} - TEST_F(CALayerOverlayTest, AllowNonAxisAlignedTransform) { std::unique_ptr<RenderPass> pass = CreateRenderPass(); CreateFullscreenCandidateQuad( @@ -2808,7 +2858,7 @@ OutputSurface* output_surface, DisplayResourceProvider* resource_provider) : GLRenderer(settings, output_surface, resource_provider, nullptr), - expect_overlays_(false) {} + expected_overlay_count_(0) {} MOCK_METHOD2(DoDrawQuad, void(const DrawQuad* quad, const gfx::QuadF* draw_region)); @@ -2822,21 +2872,17 @@ void FinishDrawingFrame() override { GLRenderer::FinishDrawingFrame(); - if (!expect_overlays_) { - EXPECT_EQ(0U, current_frame()->overlay_list.size()); - return; - } - - ASSERT_EQ(2U, current_frame()->overlay_list.size()); - EXPECT_GE(current_frame()->overlay_list.back().resource_id, 0U); + ASSERT_EQ(expected_overlay_count_, current_frame()->overlay_list.size()); + if (expected_overlay_count_ > 0) + EXPECT_GE(current_frame()->overlay_list.back().resource_id, 0U); } - void set_expect_overlays(bool expect_overlays) { - expect_overlays_ = expect_overlays; + void set_expected_overlay_count(unsigned int overlay_count) { + expected_overlay_count_ = overlay_count; } private: - bool expect_overlays_; + unsigned int expected_overlay_count_; }; class MockOverlayScheduler { @@ -2921,7 +2967,7 @@ TEST_F(GLRendererWithOverlaysTest, OverlayQuadNotDrawn) { bool use_validator = true; Init(use_validator); - renderer_->set_expect_overlays(true); + renderer_->set_expected_overlay_count(1); output_surface_->GetOverlayCandidateValidator()->AddExpectedRect( gfx::RectF(kOverlayBottomRightRect)); @@ -2942,10 +2988,6 @@ // Candidate pass was taken out and extra skipped pass added, // so only draw 2 quads. EXPECT_CALL(*renderer_, DoDrawQuad(_, _)).Times(2); - EXPECT_CALL(scheduler_, - Schedule(0, gfx::OVERLAY_TRANSFORM_NONE, _, - gfx::Rect(kDisplaySize), gfx::RectF(0, 0, 1, 1), _, _)) - .Times(1); EXPECT_CALL( scheduler_, Schedule(1, gfx::OVERLAY_TRANSFORM_NONE, _, kOverlayBottomRightRect, @@ -2963,7 +3005,7 @@ TEST_F(GLRendererWithOverlaysTest, OccludedQuadInUnderlay) { bool use_validator = true; Init(use_validator); - renderer_->set_expect_overlays(true); + renderer_->set_expected_overlay_count(1); std::unique_ptr<RenderPass> pass = CreateRenderPass(); @@ -2983,10 +3025,6 @@ // Expect to be replaced with transparent hole quad and placed in underlay. EXPECT_CALL(*renderer_, DoDrawQuad(_, _)).Times(3); EXPECT_CALL(scheduler_, - Schedule(0, gfx::OVERLAY_TRANSFORM_NONE, _, - gfx::Rect(kDisplaySize), gfx::RectF(0, 0, 1, 1), _, _)) - .Times(1); - EXPECT_CALL(scheduler_, Schedule(-1, gfx::OVERLAY_TRANSFORM_NONE, _, kOverlayRect, BoundingRect(kUVTopLeft, kUVBottomRight), _, _)) .Times(1); @@ -3002,7 +3040,7 @@ TEST_F(GLRendererWithOverlaysTest, NoValidatorNoOverlay) { bool use_validator = false; Init(use_validator); - renderer_->set_expect_overlays(false); + renderer_->set_expected_overlay_count(0); std::unique_ptr<RenderPass> pass = CreateRenderPass(); @@ -3029,13 +3067,14 @@ Mock::VerifyAndClearExpectations(&scheduler_); } -// GLRenderer skips drawing occluded quads when partial swap is enabled. +// GLRenderer skips drawing occluded quads when partial swap is enabled and +// turns off primary plane. TEST_F(GLRendererWithOverlaysTest, OccludedQuadNotDrawnWhenPartialSwapEnabled) { provider_->TestContextGL()->set_have_post_sub_buffer(true); settings_.partial_swap_enabled = true; bool use_validator = true; Init(use_validator); - renderer_->set_expect_overlays(true); + renderer_->set_expected_overlay_count(1); std::unique_ptr<RenderPass> pass = CreateRenderPass(); @@ -3052,7 +3091,8 @@ output_surface_->set_is_displayed_as_overlay_plane(true); EXPECT_CALL(*renderer_, DoDrawQuad(_, _)).Times(0); - EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _, _, _)).Times(2); + // Only the candidate quad gets scheduled + EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _, _, _)).Times(1); DrawFrame(&pass_list, kDisplaySize); EXPECT_EQ(0U, output_surface_->bind_framebuffer_count()); SwapBuffers(); @@ -3060,12 +3100,13 @@ Mock::VerifyAndClearExpectations(&scheduler_); } -// GLRenderer skips drawing occluded quads when empty swap is enabled. +// GLRenderer skips drawing occluded quads when empty swap is enabled and +// turns off primary plane. TEST_F(GLRendererWithOverlaysTest, OccludedQuadNotDrawnWhenEmptySwapAllowed) { provider_->TestContextGL()->set_have_commit_overlay_planes(true); bool use_validator = true; Init(use_validator); - renderer_->set_expect_overlays(true); + renderer_->set_expected_overlay_count(1); std::unique_ptr<RenderPass> pass = CreateRenderPass(); @@ -3083,7 +3124,8 @@ output_surface_->set_is_displayed_as_overlay_plane(true); EXPECT_CALL(*renderer_, DoDrawQuad(_, _)).Times(0); - EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _, _, _)).Times(2); + // Only the candidate quad gets scheduled + EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _, _, _)).Times(1); DrawFrame(&pass_list, kDisplaySize); EXPECT_EQ(0U, output_surface_->bind_framebuffer_count()); SwapBuffers(); @@ -3094,7 +3136,7 @@ TEST_F(GLRendererWithOverlaysTest, ResourcesExportedAndReturnedWithDelay) { bool use_validator = true; Init(use_validator); - renderer_->set_expect_overlays(true); + renderer_->set_expected_overlay_count(2); ResourceId resource1 = CreateResourceInLayerTree( child_resource_provider_.get(), gfx::Size(32, 32), true); @@ -3202,7 +3244,7 @@ EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _, _, _)).Times(0); DirectRenderer::DrawingFrame frame_no_overlays; frame_no_overlays.render_passes_in_draw_order = &pass_list; - renderer_->set_expect_overlays(false); + renderer_->set_expected_overlay_count(0); renderer_->SetCurrentFrame(frame_no_overlays); renderer_->BeginDrawingFrame(); renderer_->FinishDrawingFrame(); @@ -3221,7 +3263,7 @@ EXPECT_FALSE(resource_provider_->InUse(mapped_resource3)); // Use the same buffer twice. - renderer_->set_expect_overlays(true); + renderer_->set_expected_overlay_count(2); EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _, _, _)).Times(2); renderer_->SetCurrentFrame(frame1); renderer_->BeginDrawingFrame(); @@ -3259,7 +3301,7 @@ EXPECT_FALSE(resource_provider_->InUse(mapped_resource3)); EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _, _, _)).Times(0); - renderer_->set_expect_overlays(false); + renderer_->set_expected_overlay_count(0); renderer_->SetCurrentFrame(frame_no_overlays); renderer_->BeginDrawingFrame(); renderer_->FinishDrawingFrame(); @@ -3283,7 +3325,7 @@ bool use_validator = true; settings_.release_overlay_resources_after_gpu_query = true; Init(use_validator); - renderer_->set_expect_overlays(true); + renderer_->set_expected_overlay_count(2); ResourceId resource1 = CreateResourceInLayerTree( child_resource_provider_.get(), gfx::Size(32, 32), true);
diff --git a/components/viz/service/hit_test/hit_test_manager_fuzzer.cc b/components/viz/service/hit_test/hit_test_manager_fuzzer.cc index d53a3ac..e2f0268 100644 --- a/components/viz/service/hit_test/hit_test_manager_fuzzer.cc +++ b/components/viz/service/hit_test/hit_test_manager_fuzzer.cc
@@ -25,7 +25,8 @@ // TODO(riajiang): Move into common functions that can be used by the fuzzer // for HitTestQuery. uint32_t GetNextUInt32NonZero(base::FuzzedDataProvider* fuzz) { - return fuzz->ConsumeUint32InRange(1, std::numeric_limits<uint32_t>::max()); + return fuzz->ConsumeIntegralInRange<uint32_t>( + 1, std::numeric_limits<uint32_t>::max()); } gfx::Transform GetNextTransform(base::FuzzedDataProvider* fuzz) {
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index a1060f0..c5c7097 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -619,8 +619,6 @@ "cookie_store/cookie_store_host.h", "cookie_store/cookie_store_manager.cc", "cookie_store/cookie_store_manager.h", - "dedicated_worker/dedicated_worker_host.cc", - "dedicated_worker/dedicated_worker_host.h", "devtools/browser_devtools_agent_host.cc", "devtools/browser_devtools_agent_host.h", "devtools/devtools_agent_host_impl.cc", @@ -1692,24 +1690,6 @@ "service_worker/service_worker_version.h", "service_worker/service_worker_write_to_cache_job.cc", "service_worker/service_worker_write_to_cache_job.h", - "shared_worker/shared_worker_connector_impl.cc", - "shared_worker/shared_worker_connector_impl.h", - "shared_worker/shared_worker_content_settings_proxy_impl.cc", - "shared_worker/shared_worker_content_settings_proxy_impl.h", - "shared_worker/shared_worker_host.cc", - "shared_worker/shared_worker_host.h", - "shared_worker/shared_worker_instance.cc", - "shared_worker/shared_worker_instance.h", - "shared_worker/shared_worker_service_impl.cc", - "shared_worker/shared_worker_service_impl.h", - "shared_worker/worker_script_fetch_initiator.cc", - "shared_worker/worker_script_fetch_initiator.h", - "shared_worker/worker_script_fetcher.cc", - "shared_worker/worker_script_fetcher.h", - "shared_worker/worker_script_loader.cc", - "shared_worker/worker_script_loader.h", - "shared_worker/worker_script_loader_factory.cc", - "shared_worker/worker_script_loader_factory.h", "site_instance_impl.cc", "site_instance_impl.h", "speech/speech_recognition_dispatcher_host.cc", @@ -1877,6 +1857,26 @@ "webui/web_ui_message_handler.cc", "webui/web_ui_url_loader_factory.cc", "webui/web_ui_url_loader_factory_internal.h", + "worker_host/dedicated_worker_host.cc", + "worker_host/dedicated_worker_host.h", + "worker_host/shared_worker_connector_impl.cc", + "worker_host/shared_worker_connector_impl.h", + "worker_host/shared_worker_content_settings_proxy_impl.cc", + "worker_host/shared_worker_content_settings_proxy_impl.h", + "worker_host/shared_worker_host.cc", + "worker_host/shared_worker_host.h", + "worker_host/shared_worker_instance.cc", + "worker_host/shared_worker_instance.h", + "worker_host/shared_worker_service_impl.cc", + "worker_host/shared_worker_service_impl.h", + "worker_host/worker_script_fetch_initiator.cc", + "worker_host/worker_script_fetch_initiator.h", + "worker_host/worker_script_fetcher.cc", + "worker_host/worker_script_fetcher.h", + "worker_host/worker_script_loader.cc", + "worker_host/worker_script_loader.h", + "worker_host/worker_script_loader_factory.cc", + "worker_host/worker_script_loader_factory.h", ] if (toolkit_views) {
diff --git a/content/browser/accessibility/browser_accessibility_unittest.cc b/content/browser/accessibility/browser_accessibility_unittest.cc index af607ed..c67b3f37 100644 --- a/content/browser/accessibility/browser_accessibility_unittest.cc +++ b/content/browser/accessibility/browser_accessibility_unittest.cc
@@ -4,6 +4,7 @@ #include "content/browser/accessibility/browser_accessibility.h" +#include "base/test/scoped_task_environment.h" #include "build/build_config.h" #include "content/browser/accessibility/browser_accessibility_manager.h" #include "testing/gtest/include/gtest/gtest.h" @@ -16,6 +17,7 @@ ~BrowserAccessibilityTest() override; private: + base::test::ScopedTaskEnvironment task_environment_; DISALLOW_COPY_AND_ASSIGN(BrowserAccessibilityTest); };
diff --git a/content/browser/dedicated_worker/OWNERS b/content/browser/dedicated_worker/OWNERS deleted file mode 100644 index eb8bfba6..0000000 --- a/content/browser/dedicated_worker/OWNERS +++ /dev/null
@@ -1,4 +0,0 @@ -nhiroki@chromium.org - -# TEAM: worker-dev@chromium.org -# COMPONENT: Blink>Workers
diff --git a/content/browser/dedicated_worker/README.md b/content/browser/dedicated_worker/README.md deleted file mode 100644 index a11d35f..0000000 --- a/content/browser/dedicated_worker/README.md +++ /dev/null
@@ -1,8 +0,0 @@ -# Dedicated Worker Host - -`content/browser/dedicated_worker` implements the host side of dedicated worker. -It tracks the security principal of the worker in the renderer and uses it to -broker access to mojo interfaces providing powerful web APIs. See: [Design -doc]. - -[Design doc]: https://docs.google.com/document/d/1Bg84lQqeJ8D2J-_wOOLlRVAtZNMstEUHmVhJqCxpjUk/edit?usp=sharing
diff --git a/content/browser/devtools/protocol/storage_handler.cc b/content/browser/devtools/protocol/storage_handler.cc index 1a6a4d9..b044983b 100644 --- a/content/browser/devtools/protocol/storage_handler.cc +++ b/content/browser/devtools/protocol/storage_handler.cc
@@ -26,32 +26,32 @@ namespace content { namespace protocol { -namespace { -Storage::StorageType GetTypeName(storage::QuotaClient::ID id) { - switch (id) { - case storage::QuotaClient::kFileSystem: - return Storage::StorageTypeEnum::File_systems; - case storage::QuotaClient::kDatabase: - return Storage::StorageTypeEnum::Websql; - case storage::QuotaClient::kAppcache: - return Storage::StorageTypeEnum::Appcache; - case storage::QuotaClient::kIndexedDatabase: - return Storage::StorageTypeEnum::Indexeddb; - case storage::QuotaClient::kServiceWorkerCache: - return Storage::StorageTypeEnum::Cache_storage; - case storage::QuotaClient::kServiceWorker: - return Storage::StorageTypeEnum::Service_workers; - default: - return Storage::StorageTypeEnum::Other; - } -} +struct UsageListInitializer { + const char* type; + int64_t blink::mojom::UsageBreakdown::*usage_member; +}; +UsageListInitializer initializers[] = { + {Storage::StorageTypeEnum::File_systems, + &blink::mojom::UsageBreakdown::fileSystem}, + {Storage::StorageTypeEnum::Websql, &blink::mojom::UsageBreakdown::webSql}, + {Storage::StorageTypeEnum::Appcache, + &blink::mojom::UsageBreakdown::appcache}, + {Storage::StorageTypeEnum::Indexeddb, + &blink::mojom::UsageBreakdown::indexedDatabase}, + {Storage::StorageTypeEnum::Cache_storage, + &blink::mojom::UsageBreakdown::serviceWorkerCache}, + {Storage::StorageTypeEnum::Service_workers, + &blink::mojom::UsageBreakdown::serviceWorker}, +}; + +namespace { void ReportUsageAndQuotaDataOnUIThread( std::unique_ptr<StorageHandler::GetUsageAndQuotaCallback> callback, blink::mojom::QuotaStatusCode code, int64_t usage, int64_t quota, - base::flat_map<storage::QuotaClient::ID, int64_t> usage_breakdown) { + blink::mojom::UsageBreakdownPtr usage_breakdown) { DCHECK_CURRENTLY_ON(BrowserThread::UI); if (code != blink::mojom::QuotaStatusCode::kOk) { return callback->sendFailure( @@ -60,14 +60,17 @@ std::unique_ptr<Array<Storage::UsageForType>> usageList = Array<Storage::UsageForType>::create(); - for (const auto& specific_usage : usage_breakdown) { + + blink::mojom::UsageBreakdown* breakdown_ptr = usage_breakdown.get(); + for (const auto initializer : initializers) { std::unique_ptr<Storage::UsageForType> entry = Storage::UsageForType::Create() - .SetStorageType(GetTypeName(specific_usage.first)) - .SetUsage(specific_usage.second) + .SetStorageType(initializer.type) + .SetUsage(breakdown_ptr->*(initializer.usage_member)) .Build(); usageList->addItem(std::move(entry)); } + callback->sendSuccess(usage, quota, std::move(usageList)); } @@ -76,7 +79,7 @@ blink::mojom::QuotaStatusCode code, int64_t usage, int64_t quota, - base::flat_map<storage::QuotaClient::ID, int64_t> usage_breakdown) { + blink::mojom::UsageBreakdownPtr usage_breakdown) { DCHECK_CURRENTLY_ON(BrowserThread::IO); base::PostTaskWithTraits( FROM_HERE, {BrowserThread::UI},
diff --git a/content/browser/devtools/shared_worker_devtools_agent_host.cc b/content/browser/devtools/shared_worker_devtools_agent_host.cc index 7ff0a7d..a74e129 100644 --- a/content/browser/devtools/shared_worker_devtools_agent_host.cc +++ b/content/browser/devtools/shared_worker_devtools_agent_host.cc
@@ -12,9 +12,9 @@ #include "content/browser/devtools/protocol/schema_handler.h" #include "content/browser/devtools/protocol/target_handler.h" #include "content/browser/devtools/shared_worker_devtools_manager.h" -#include "content/browser/shared_worker/shared_worker_host.h" -#include "content/browser/shared_worker/shared_worker_instance.h" -#include "content/browser/shared_worker/shared_worker_service_impl.h" +#include "content/browser/worker_host/shared_worker_host.h" +#include "content/browser/worker_host/shared_worker_instance.h" +#include "content/browser/worker_host/shared_worker_service_impl.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/render_process_host.h" #include "third_party/blink/public/web/devtools_agent.mojom.h"
diff --git a/content/browser/devtools/shared_worker_devtools_manager.cc b/content/browser/devtools/shared_worker_devtools_manager.cc index 5731e4bb..d863a22f 100644 --- a/content/browser/devtools/shared_worker_devtools_manager.cc +++ b/content/browser/devtools/shared_worker_devtools_manager.cc
@@ -5,7 +5,7 @@ #include "content/browser/devtools/shared_worker_devtools_manager.h" #include "content/browser/devtools/shared_worker_devtools_agent_host.h" -#include "content/browser/shared_worker/shared_worker_host.h" +#include "content/browser/worker_host/shared_worker_host.h" #include "content/public/browser/browser_thread.h" namespace content {
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc index 60dac5f..3c9de03 100644 --- a/content/browser/frame_host/render_frame_host_impl.cc +++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -35,7 +35,6 @@ #include "content/browser/bluetooth/web_bluetooth_service_impl.h" #include "content/browser/browser_main_loop.h" #include "content/browser/child_process_security_policy_impl.h" -#include "content/browser/dedicated_worker/dedicated_worker_host.h" #include "content/browser/devtools/devtools_instrumentation.h" #include "content/browser/dom_storage/dom_storage_context_wrapper.h" #include "content/browser/download/mhtml_generation_manager.h" @@ -91,8 +90,6 @@ #include "content/browser/renderer_host/render_widget_host_view_child_frame.h" #include "content/browser/renderer_interface_binders.h" #include "content/browser/scoped_active_url.h" -#include "content/browser/shared_worker/shared_worker_connector_impl.h" -#include "content/browser/shared_worker/shared_worker_service_impl.h" #include "content/browser/speech/speech_recognition_dispatcher_host.h" #include "content/browser/storage_partition_impl.h" #include "content/browser/webauth/authenticator_impl.h" @@ -101,6 +98,9 @@ #include "content/browser/webui/url_data_manager_backend.h" #include "content/browser/webui/web_ui_controller_factory_registry.h" #include "content/browser/webui/web_ui_url_loader_factory_internal.h" +#include "content/browser/worker_host/dedicated_worker_host.h" +#include "content/browser/worker_host/shared_worker_connector_impl.h" +#include "content/browser/worker_host/shared_worker_service_impl.h" #include "content/common/accessibility_messages.h" #include "content/common/associated_interfaces.mojom.h" #include "content/common/content_security_policy/content_security_policy.h"
diff --git a/content/browser/media/audible_metrics.h b/content/browser/media/audible_metrics.h index 02d9867..67290c1d 100644 --- a/content/browser/media/audible_metrics.h +++ b/content/browser/media/audible_metrics.h
@@ -31,6 +31,10 @@ void SetClockForTest(const base::TickClock* test_clock); + int GetAudibleWebContentsSizeForTest() const { + return audible_web_contents_.size(); + } + private: void AddAudibleWebContents(const WebContents* web_contents); void RemoveAudibleWebContents(const WebContents* web_contents);
diff --git a/content/browser/media/audible_metrics_unittest.cc b/content/browser/media/audible_metrics_unittest.cc index a9f1b47..49006f7 100644 --- a/content/browser/media/audible_metrics_unittest.cc +++ b/content/browser/media/audible_metrics_unittest.cc
@@ -8,6 +8,10 @@ #include "base/test/metrics/histogram_tester.h" #include "base/test/metrics/user_action_tester.h" #include "base/test/simple_test_tick_clock.h" +#include "content/browser/media/media_web_contents_observer.h" +#include "content/public/test/test_browser_context.h" +#include "content/public/test/test_browser_thread_bundle.h" +#include "content/test/test_web_contents.h" #include "testing/gtest/include/gtest/gtest.h" namespace content { @@ -31,17 +35,23 @@ AudibleMetricsTest() = default; void SetUp() override { + audible_metrics_ = std::make_unique<AudibleMetrics>(); + browser_context_ = std::make_unique<TestBrowserContext>(); + // Set the clock to a value different than 0 so the time it gives is // recognized as initialized. clock_.Advance(base::TimeDelta::FromMilliseconds(1)); - audible_metrics_.SetClockForTest(&clock_); + audible_metrics_->SetClockForTest(&clock_); + } + + void TearDown() override { + audible_metrics_.reset(); + browser_context_.reset(); } base::SimpleTestTickClock* clock() { return &clock_; } - AudibleMetrics* audible_metrics() { - return &audible_metrics_; - }; + AudibleMetrics* audible_metrics() { return audible_metrics_.get(); }; const base::UserActionTester& user_action_tester() const { return user_action_tester_; @@ -52,9 +62,18 @@ return histogram_tester_.GetHistogramSamplesSinceCreation(name); } + std::unique_ptr<WebContentsImpl> CreateWebContents() { + return TestWebContents::Create( + browser_context_.get(), SiteInstance::Create(browser_context_.get())); + } + private: + TestBrowserThreadBundle test_browser_thread_bundle_; + + std::unique_ptr<AudibleMetrics> audible_metrics_; + std::unique_ptr<TestBrowserContext> browser_context_; + base::SimpleTestTickClock clock_; - AudibleMetrics audible_metrics_; base::HistogramTester histogram_tester_; base::UserActionTester user_action_tester_; @@ -352,4 +371,65 @@ } } +TEST_F(AudibleMetricsTest, MediaWebContentsObserver_Audible_Muted) { + std::unique_ptr<WebContentsImpl> web_contents(CreateWebContents()); + MediaWebContentsObserver media_observer(web_contents.get()); + media_observer.SetAudibleMetricsForTest(audible_metrics()); + + web_contents->SetAudioMuted(true); + web_contents->audio_stream_monitor()->set_is_currently_audible_for_testing( + true); + + EXPECT_TRUE(web_contents->audio_stream_monitor()->IsCurrentlyAudible()); + EXPECT_TRUE(web_contents->IsAudioMuted()); + + EXPECT_EQ(0, audible_metrics()->GetAudibleWebContentsSizeForTest()); + media_observer.MaybeUpdateAudibleState(); + EXPECT_EQ(0, audible_metrics()->GetAudibleWebContentsSizeForTest()); +} + +TEST_F(AudibleMetricsTest, MediaWebContentsObserver_Audible_NotMuted) { + std::unique_ptr<WebContentsImpl> web_contents(CreateWebContents()); + MediaWebContentsObserver media_observer(web_contents.get()); + media_observer.SetAudibleMetricsForTest(audible_metrics()); + + web_contents->audio_stream_monitor()->set_is_currently_audible_for_testing( + true); + + EXPECT_TRUE(web_contents->audio_stream_monitor()->IsCurrentlyAudible()); + EXPECT_FALSE(web_contents->IsAudioMuted()); + + EXPECT_EQ(0, audible_metrics()->GetAudibleWebContentsSizeForTest()); + media_observer.MaybeUpdateAudibleState(); + EXPECT_EQ(1, audible_metrics()->GetAudibleWebContentsSizeForTest()); +} + +TEST_F(AudibleMetricsTest, MediaWebContentsObserver_NotAudible_Muted) { + std::unique_ptr<WebContentsImpl> web_contents(CreateWebContents()); + MediaWebContentsObserver media_observer(web_contents.get()); + media_observer.SetAudibleMetricsForTest(audible_metrics()); + + web_contents->SetAudioMuted(true); + + EXPECT_FALSE(web_contents->audio_stream_monitor()->IsCurrentlyAudible()); + EXPECT_TRUE(web_contents->IsAudioMuted()); + + EXPECT_EQ(0, audible_metrics()->GetAudibleWebContentsSizeForTest()); + media_observer.MaybeUpdateAudibleState(); + EXPECT_EQ(0, audible_metrics()->GetAudibleWebContentsSizeForTest()); +} + +TEST_F(AudibleMetricsTest, MediaWebContentsObserver_NotAudible_NotMuted) { + std::unique_ptr<WebContentsImpl> web_contents(CreateWebContents()); + MediaWebContentsObserver media_observer(web_contents.get()); + media_observer.SetAudibleMetricsForTest(audible_metrics()); + + EXPECT_FALSE(web_contents->audio_stream_monitor()->IsCurrentlyAudible()); + EXPECT_FALSE(web_contents->IsAudioMuted()); + + EXPECT_EQ(0, audible_metrics()->GetAudibleWebContentsSizeForTest()); + media_observer.MaybeUpdateAudibleState(); + EXPECT_EQ(0, audible_metrics()->GetAudibleWebContentsSizeForTest()); +} + } // namespace content
diff --git a/content/browser/media/media_web_contents_observer.cc b/content/browser/media/media_web_contents_observer.cc index e636fca..a1e18f13 100644 --- a/content/browser/media/media_web_contents_observer.cc +++ b/content/browser/media/media_web_contents_observer.cc
@@ -58,12 +58,13 @@ MediaWebContentsObserver::MediaWebContentsObserver(WebContents* web_contents) : WebContentsObserver(web_contents), + audible_metrics_(GetAudibleMetrics()), session_controllers_manager_(this) {} MediaWebContentsObserver::~MediaWebContentsObserver() = default; void MediaWebContentsObserver::WebContentsDestroyed() { - GetAudibleMetrics()->UpdateAudibleWebContentsState(web_contents(), false); + audible_metrics_->UpdateAudibleWebContentsState(web_contents(), false); } void MediaWebContentsObserver::RenderFrameDeleted( @@ -92,8 +93,9 @@ else CancelAudioLock(); - GetAudibleMetrics()->UpdateAudibleWebContentsState( - web_contents(), audio_stream_monitor->IsCurrentlyAudible()); + audible_metrics_->UpdateAudibleWebContentsState( + web_contents(), audio_stream_monitor->IsCurrentlyAudible() && + !web_contents()->IsAudioMuted()); } bool MediaWebContentsObserver::HasActiveEffectivelyFullscreenVideo() const {
diff --git a/content/browser/media/media_web_contents_observer.h b/content/browser/media/media_web_contents_observer.h index 5994a56..70a646e 100644 --- a/content/browser/media/media_web_contents_observer.h +++ b/content/browser/media/media_web_contents_observer.h
@@ -40,6 +40,8 @@ namespace content { +class AudibleMetrics; + // This class manages all RenderFrame based media related managers at the // browser side. It receives IPC messages from media RenderFrameObservers and // forwards them to the corresponding managers. The managers are responsible @@ -106,6 +108,10 @@ bool has_video_wake_lock_for_testing() const { return has_video_wake_lock_; } + void SetAudibleMetricsForTest(AudibleMetrics* audible_metrics) { + audible_metrics_ = audible_metrics; + } + protected: MediaSessionControllersManager* session_controllers_manager() { return &session_controllers_manager_; @@ -181,6 +187,9 @@ // Convenience method that casts web_contents() to a WebContentsImpl*. WebContentsImpl* web_contents_impl() const; + // Helper class for recording audible metrics. + AudibleMetrics* audible_metrics_; + // Tracking variables and associated wake locks for media playback. ActiveMediaPlayerMap active_audio_players_; ActiveMediaPlayerMap active_video_players_;
diff --git a/content/browser/media/session/media_session_impl.cc b/content/browser/media/session/media_session_impl.cc index af197ce..41b32e8 100644 --- a/content/browser/media/session/media_session_impl.cc +++ b/content/browser/media/session/media_session_impl.cc
@@ -10,6 +10,7 @@ #include "base/numerics/ranges.h" #include "base/stl_util.h" #include "base/strings/string_util.h" +#include "build/build_config.h" #include "content/browser/media/session/audio_focus_delegate.h" #include "content/browser/media/session/media_session_controller.h" #include "content/browser/media/session/media_session_player_observer.h" @@ -177,6 +178,17 @@ services_[rfh]->DidFinishNavigation(); } +void MediaSessionImpl::OnWebContentsFocused( + RenderWidgetHost* render_widget_host) { +#if !defined(OS_ANDROID) + // If we have just gained focus and we have audio focus we should re-request + // system audio focus. This will ensure this media session is towards the top + // of the stack if we have multiple sessions active at the same time. + if (audio_focus_state_ == State::ACTIVE) + RequestSystemAudioFocus(desired_audio_focus_type_); +#endif +} + void MediaSessionImpl::AddObserver(MediaSessionObserver* observer) { observers_.AddObserver(observer); NotifyAddedObserver(observer);
diff --git a/content/browser/media/session/media_session_impl.h b/content/browser/media/session/media_session_impl.h index f649b57..a30cc23 100644 --- a/content/browser/media/session/media_session_impl.h +++ b/content/browser/media/session/media_session_impl.h
@@ -134,6 +134,7 @@ void WebContentsDestroyed() override; void RenderFrameDeleted(RenderFrameHost* rfh) override; void DidFinishNavigation(NavigationHandle* navigation_handle) override; + void OnWebContentsFocused(RenderWidgetHost* render_widget_host) override; // MediaSessionService-related methods
diff --git a/content/browser/media/session/media_session_impl_unittest.cc b/content/browser/media/session/media_session_impl_unittest.cc index 0ae5db3b..5dfb9f2 100644 --- a/content/browser/media/session/media_session_impl_unittest.cc +++ b/content/browser/media/session/media_session_impl_unittest.cc
@@ -43,9 +43,12 @@ ~MockAudioFocusDelegate() override = default; void AbandonAudioFocus() override {} + AudioFocusResult RequestAudioFocus(AudioFocusType type) override { + request_audio_focus_count_++; return AudioFocusResult::kSuccess; } + base::Optional<AudioFocusType> GetCurrentFocusType() const override { return AudioFocusType::kGain; } @@ -59,7 +62,11 @@ return session_info_->state; } + int request_audio_focus_count() const { return request_audio_focus_count_; } + private: + int request_audio_focus_count_ = 0; + MediaSessionInfoPtr session_info_; DISALLOW_COPY_AND_ASSIGN(MockAudioFocusDelegate); @@ -409,6 +416,60 @@ } } +TEST_F(MediaSessionImplTest, RequestAudioFocus_OnFocus_Active) { + std::unique_ptr<WebContents> web_contents(CreateWebContents()); + MediaSessionImpl* media_session = MediaSessionImpl::Get(web_contents.get()); + MockAudioFocusDelegate* delegate = new MockAudioFocusDelegate(); + SetDelegateForTests(media_session, delegate); + + { + MockMediaSessionMojoObserver observer(*media_session); + RequestAudioFocus(media_session, AudioFocusType::kGain); + FlushForTesting(media_session); + observer.WaitForState(MediaSessionInfo::SessionState::kActive); + } + + EXPECT_EQ(1, delegate->request_audio_focus_count()); + media_session->OnWebContentsFocused(nullptr); + EXPECT_EQ(2, delegate->request_audio_focus_count()); +} + +TEST_F(MediaSessionImplTest, RequestAudioFocus_OnFocus_Inactive) { + std::unique_ptr<WebContents> web_contents(CreateWebContents()); + MediaSessionImpl* media_session = MediaSessionImpl::Get(web_contents.get()); + MockAudioFocusDelegate* delegate = new MockAudioFocusDelegate(); + SetDelegateForTests(media_session, delegate); + EXPECT_EQ(MediaSessionInfo::SessionState::kInactive, GetState(media_session)); + + EXPECT_EQ(0, delegate->request_audio_focus_count()); + media_session->OnWebContentsFocused(nullptr); + EXPECT_EQ(0, delegate->request_audio_focus_count()); +} + +TEST_F(MediaSessionImplTest, RequestAudioFocus_OnFocus_Suspended) { + std::unique_ptr<WebContents> web_contents(CreateWebContents()); + MediaSessionImpl* media_session = MediaSessionImpl::Get(web_contents.get()); + MockAudioFocusDelegate* delegate = new MockAudioFocusDelegate(); + SetDelegateForTests(media_session, delegate); + + { + MockMediaSessionMojoObserver observer(*media_session); + RequestAudioFocus(media_session, AudioFocusType::kGain); + FlushForTesting(media_session); + observer.WaitForState(MediaSessionInfo::SessionState::kActive); + } + + { + MockMediaSessionMojoObserver observer(*media_session); + media_session->Suspend(MediaSession::SuspendType::kSystem); + observer.WaitForState(MediaSessionInfo::SessionState::kSuspended); + } + + EXPECT_EQ(1, delegate->request_audio_focus_count()); + media_session->OnWebContentsFocused(nullptr); + EXPECT_EQ(1, delegate->request_audio_focus_count()); +} + #endif // !defined(OS_ANDROID) } // namespace content
diff --git a/content/browser/quota_dispatcher_host.cc b/content/browser/quota_dispatcher_host.cc index 350bdf3b..f1626f3 100644 --- a/content/browser/quota_dispatcher_host.cc +++ b/content/browser/quota_dispatcher_host.cc
@@ -94,7 +94,7 @@ const url::Origin& origin, StorageType storage_type, QueryStorageUsageAndQuotaCallback callback) { - quota_manager_->GetUsageAndQuotaForWebApps( + quota_manager_->GetUsageAndQuotaWithBreakdown( origin, storage_type, base::BindOnce(&QuotaDispatcherHost::DidQueryStorageUsageAndQuota, weak_factory_.GetWeakPtr(), std::move(callback))); @@ -140,11 +140,12 @@ } void QuotaDispatcherHost::DidQueryStorageUsageAndQuota( - RequestStorageQuotaCallback callback, + QueryStorageUsageAndQuotaCallback callback, blink::mojom::QuotaStatusCode status, int64_t usage, - int64_t quota) { - std::move(callback).Run(status, usage, quota); + int64_t quota, + blink::mojom::UsageBreakdownPtr usage_breakdown) { + std::move(callback).Run(status, usage, quota, std::move(usage_breakdown)); } void QuotaDispatcherHost::DidGetPersistentUsageAndQuota(
diff --git a/content/browser/quota_dispatcher_host.h b/content/browser/quota_dispatcher_host.h index e42257d5..8029c9d 100644 --- a/content/browser/quota_dispatcher_host.h +++ b/content/browser/quota_dispatcher_host.h
@@ -7,6 +7,7 @@ #include "base/macros.h" #include "content/public/browser/quota_permission_context.h" +#include "storage/browser/quota/quota_manager.h" #include "third_party/blink/public/mojom/quota/quota_dispatcher_host.mojom.h" namespace storage { @@ -49,10 +50,11 @@ RequestStorageQuotaCallback callback) override; private: - void DidQueryStorageUsageAndQuota(RequestStorageQuotaCallback callback, + void DidQueryStorageUsageAndQuota(QueryStorageUsageAndQuotaCallback callback, blink::mojom::QuotaStatusCode status, int64_t usage, - int64_t quota); + int64_t quota, + blink::mojom::UsageBreakdownPtr); void DidGetPersistentUsageAndQuota(const url::Origin& origin, blink::mojom::StorageType storage_type, uint64_t requested_quota,
diff --git a/content/browser/sandbox_mac_unittest.mm b/content/browser/sandbox_mac_unittest.mm index 7ca9ec0..215964d 100644 --- a/content/browser/sandbox_mac_unittest.mm +++ b/content/browser/sandbox_mac_unittest.mm
@@ -16,6 +16,7 @@ #include "base/test/multiprocess_test.h" #include "base/test/test_timeouts.h" #include "content/browser/sandbox_parameters_mac.h" +#include "crypto/openssl_util.h" #include "sandbox/mac/seatbelt.h" #include "sandbox/mac/seatbelt_exec.h" #include "services/service_manager/sandbox/mac/audio.sb.h" @@ -30,6 +31,7 @@ #include "services/service_manager/sandbox/switches.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/multiprocess_func_list.h" +#include "third_party/boringssl/src/include/openssl/rand.h" #import "ui/base/clipboard/clipboard_util_mac.h" namespace content { @@ -141,7 +143,9 @@ for (ExecuteFuncT execute_func : kExecuteFuncs) { (this->*execute_func)(multiprocess_main); - after_each.Run(); + if (!after_each.is_null()) { + after_each.Run(); + } } } @@ -222,4 +226,18 @@ pb)); } +MULTIPROCESS_TEST_MAIN(SSLProcess) { + CheckCreateSeatbeltServer(); + + crypto::EnsureOpenSSLInit(); + // Ensure that RAND_bytes is functional within the sandbox. + uint8_t byte; + CHECK(RAND_bytes(&byte, 1) == 1); + return 0; +} + +TEST_F(SandboxMacTest, SSLInitTest) { + ExecuteInAllSandboxTypes("SSLProcess", base::RepeatingClosure()); +} + } // namespace content
diff --git a/content/browser/service_worker/service_worker_navigation_loader.cc b/content/browser/service_worker/service_worker_navigation_loader.cc index e7b2eda..840f2b8 100644 --- a/content/browser/service_worker/service_worker_navigation_loader.cc +++ b/content/browser/service_worker/service_worker_navigation_loader.cc
@@ -580,9 +580,9 @@ response_head_.load_timing.request_start); // Time spent for service worker startup. - UMA_HISTOGRAM_TIMES( + UMA_HISTOGRAM_MEDIUM_TIMES( "ServiceWorker.LoadTiming.MainFrame.MainResource." - "ForwardServiceWorkerToWorkerReady", + "ForwardServiceWorkerToWorkerReady2", response_head_.service_worker_ready_time - response_head_.service_worker_start_time);
diff --git a/content/browser/service_worker/service_worker_tls_browsertest.cc b/content/browser/service_worker/service_worker_tls_browsertest.cc index 42e9efd..79a6f995 100644 --- a/content/browser/service_worker/service_worker_tls_browsertest.cc +++ b/content/browser/service_worker/service_worker_tls_browsertest.cc
@@ -24,7 +24,7 @@ } // Tests TLS + service workers. Inspired by -// content/browser/shared_worker/worker_browsertest.cc. +// content/browser/worker_host/worker_browsertest.cc. class ServiceWorkerTlsTest : public ContentBrowserTest, public ::testing::WithParamInterface<ServicifiedFeatures> {
diff --git a/content/browser/storage_partition_impl.h b/content/browser/storage_partition_impl.h index b485cde..c9fd76a 100644 --- a/content/browser/storage_partition_impl.h +++ b/content/browser/storage_partition_impl.h
@@ -28,8 +28,8 @@ #include "content/browser/payments/payment_app_context_impl.h" #include "content/browser/push_messaging/push_messaging_context.h" #include "content/browser/service_worker/service_worker_context_wrapper.h" -#include "content/browser/shared_worker/shared_worker_service_impl.h" #include "content/browser/url_loader_factory_getter.h" +#include "content/browser/worker_host/shared_worker_service_impl.h" #include "content/common/content_export.h" #include "content/public/browser/storage_partition.h" #include "mojo/public/cpp/bindings/binding_set.h"
diff --git a/content/browser/web_package/signed_exchange_signature_verifier_unittest.cc b/content/browser/web_package/signed_exchange_signature_verifier_unittest.cc index 41cfa75..d99caa35 100644 --- a/content/browser/web_package/signed_exchange_signature_verifier_unittest.cc +++ b/content/browser/web_package/signed_exchange_signature_verifier_unittest.cc
@@ -18,7 +18,6 @@ // See content/testdata/sxg/README on how to generate these data. // clang-format off -constexpr char kSignatureHeaderRSA[] = R"(label; sig=*DDeXzJshGnPT+ei1rS1KmZx+QLwwLTbNKDVSmTb2HjGfgPngv+C+uMbjZiliOmGe0b514JcAlYAM57t0kZY2FPd9JdqwYPIiAWEwxByfV2iXBbsGZNWGtS/AAq1SaPwIMfrzdLXAFbKbtTRhS7B5LHCo/6hEIXu0TJJFbv5fKaLgTTLF0AK5dV0/En0uz+bnVARuBIH/ez2gPEFc6KbGnTTp8LYcCe/YjlHQy/Oac28ACBtn70rP1TerWEaYBwMMDckJ2gfsVyLqMcFtJqV0uGLT6Atb2wBSUZlZDTEZf228362r+EHLrADAuhz4bdSMKFsFgWyceOriDyHhc0PSwQ==*; validity-url="https://example.com/resource.validity.msg"; integrity="digest/mi-sha256-03"; cert-url="https://example.com/cert.msg"; cert-sha256=*tJGJP8ej7KCEW8VnVK3bKwpBza/oLrtWA75z5ZPptuc=*; date=1517892341; expires=1517895941)"; constexpr char kSignatureHeaderECDSAP256[] = R"(label; sig=*MEUCIQC7tM/B6YxVgrJmgfFawtwBKPev2vFCh7amR+JTDBMgTQIga9LkS51vteYr8NWPTCSZRy10lcLaFNN9m1G3OBS9lBs=*; validity-url="https://example.com/resource.validity.msg"; integrity="digest/mi-sha256-03"; cert-url="https://example.com/cert.msg"; cert-sha256=*KX+BYLSMgDOON8Ju65RoId39Qvajxa12HO+WnD4HpS0=*; date=1517892341; expires=1517895941)"; constexpr uint8_t kCborHeadersECDSAP256[] = { 0x82, 0xa1, 0x47, 0x3a, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x43, 0x47, @@ -56,31 +55,6 @@ "date=1517892341; expires=1518497142"; // clang-format on -constexpr char kCertPEMRSA[] = R"( ------BEGIN CERTIFICATE----- -MIIDyTCCArGgAwIBAgIBBDANBgkqhkiG9w0BAQsFADBjMQswCQYDVQQGEwJVUzET -MBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEQMA4G -A1UECgwHVGVzdCBDQTEVMBMGA1UEAwwMVGVzdCBSb290IENBMB4XDTE3MDYwNTE3 -MTA0NloXDTI3MDYwMzE3MTA0NlowYDELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNh -bGlmb3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxEDAOBgNVBAoMB1Rlc3Qg -Q0ExEjAQBgNVBAMMCTEyNy4wLjAuMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC -AQoCggEBANOUHzO0uxUyd3rYUArq33olXC0N1AYNM0wFTjUqUrElLiX48+5hERkG -hGwC8VG5Zr/2Jw/wtarLiDjg2OfPdwyMp3S7MBTgvXWZ989MUHpx6b0cWM298iOg -/VeinMphFLDfPDHFWZ7RXBqfk6MGLhI5GgvoooYw2jUmP+elnoizIL/OB08sIYra -AVrwasoRd+yOmyvQnzw3mZNKpWjeX7NhZCg2nG8B8u78agwAYVWupHnJS2GwhLzy -19AxU/HmaI9kyyMGmRtbRZ0roCyMDOgEEcWUSYNRP33KLi31uKYqOSblvzmC7kA7 -k5yca3VXlgqg4gnjr9tbOMzMcpeqeaMCAwEAAaOBijCBhzAMBgNVHRMBAf8EAjAA -MB0GA1UdDgQWBBQYDOtRudM2qckEr/kvFPCZZtJ21DAfBgNVHSMEGDAWgBSbJguK -mKm7HbkfHOMaQDPtjheIqzAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIw -GAYDVR0RBBEwD4INKi5leGFtcGxlLm9yZzANBgkqhkiG9w0BAQsFAAOCAQEAvXK0 -UF19i7JkSSdomQwB18WRFaKG8VZpSFsKbEECPRHoxktMl/Pd04wk+W0fZFq433j3 -4D+cjTB6OxAVdPIPSex8U40fYMl9C13K1tejf4o/+rcLxEDdVfv7PUkogrliXzSE -MCYdcTwruV7hjC2/Ib0t/kdxblRt4dD2I1jdntsFy/VfET/m0J2qRhJWlfYEzCFe -Hn8H/PZIiIsso5pm2RodTqi9w4/+1r8Yyfmk8TF+EoWDYtbZ+ScgtCH5fldS+onI -hHgjz/tniqjbY0MRFr9ZxrohmtgOBOvROEKH06c92oOmj2ahyFpM/yU9PL/JvNmF -SaMW1eOzjHemIWKTMw== ------END CERTIFICATE-----)"; - constexpr char kCertPEMECDSAP256[] = R"( -----BEGIN CERTIFICATE----- MIIC1TCCAb2gAwIBAgIBATANBgkqhkiG9w0BAQsFADBjMQswCQYDVQQGEwJVUzET @@ -249,34 +223,6 @@ } }; -TEST_F(SignedExchangeSignatureVerifierTest, VerifyRSA) { - auto signature = SignedExchangeSignatureHeaderField::ParseSignature( - kSignatureHeaderRSA, nullptr /* devtools_proxy */); - ASSERT_TRUE(signature.has_value()); - ASSERT_EQ(1u, signature->size()); - - net::CertificateList certlist = - net::X509Certificate::CreateCertificateListFromBytes( - kCertPEMRSA, base::size(kCertPEMRSA), - net::X509Certificate::FORMAT_AUTO); - ASSERT_EQ(1u, certlist.size()); - - SignedExchangeEnvelope envelope; - envelope.set_request_method("GET"); - envelope.set_request_url(GURL("https://test.example.org/test/")); - envelope.set_response_code(net::HTTP_OK); - envelope.AddResponseHeader("content-type", "text/html; charset=utf-8"); - envelope.AddResponseHeader("content-encoding", "mi-sha256-03"); - envelope.AddResponseHeader( - "digest", "mi-sha256-03=wmp4dRMYgxP3tSMCwV/I0CWOCiHZpAihKZk19bsN9RI="); - envelope.SetSignatureForTesting((*signature)[0]); - - EXPECT_EQ(SignedExchangeSignatureVerifier::Result::kErrUnsupportedCertType, - SignedExchangeSignatureVerifier::Verify( - envelope, certlist[0], VerificationTime(), - nullptr /* devtools_proxy */)); -} - TEST_F(SignedExchangeSignatureVerifierTest, VerifyECDSAP256) { auto signature = SignedExchangeSignatureHeaderField::ParseSignature( kSignatureHeaderECDSAP256, nullptr /* devtools_proxy */);
diff --git a/content/browser/shared_worker/DEPS b/content/browser/worker_host/DEPS similarity index 100% rename from content/browser/shared_worker/DEPS rename to content/browser/worker_host/DEPS
diff --git a/content/browser/shared_worker/OWNERS b/content/browser/worker_host/OWNERS similarity index 100% rename from content/browser/shared_worker/OWNERS rename to content/browser/worker_host/OWNERS
diff --git a/content/browser/worker_host/README.md b/content/browser/worker_host/README.md new file mode 100644 index 0000000..878337f --- /dev/null +++ b/content/browser/worker_host/README.md
@@ -0,0 +1,8 @@ +# Web Worker Host + +`content/browser/worker_host` implements the host side of web workers (dedicated +workers and shared workers). It tracks the security principal of the worker in +the renderer and uses it to broker access to mojo interfaces providing powerful +web APIs. See: [Design doc]. + +[Design doc]: https://docs.google.com/document/d/1Bg84lQqeJ8D2J-_wOOLlRVAtZNMstEUHmVhJqCxpjUk/edit?usp=sharing
diff --git a/content/browser/dedicated_worker/dedicated_worker_host.cc b/content/browser/worker_host/dedicated_worker_host.cc similarity index 98% rename from content/browser/dedicated_worker/dedicated_worker_host.cc rename to content/browser/worker_host/dedicated_worker_host.cc index 9c9271b..9eb741e 100644 --- a/content/browser/dedicated_worker/dedicated_worker_host.cc +++ b/content/browser/worker_host/dedicated_worker_host.cc
@@ -5,7 +5,7 @@ #include <string> #include <utility> -#include "content/browser/dedicated_worker/dedicated_worker_host.h" +#include "content/browser/worker_host/dedicated_worker_host.h" #include "content/browser/frame_host/render_frame_host_impl.h" #include "content/browser/interface_provider_filtering.h"
diff --git a/content/browser/dedicated_worker/dedicated_worker_host.h b/content/browser/worker_host/dedicated_worker_host.h similarity index 71% rename from content/browser/dedicated_worker/dedicated_worker_host.h rename to content/browser/worker_host/dedicated_worker_host.h index 587ab20..bde3fe59 100644 --- a/content/browser/dedicated_worker/dedicated_worker_host.h +++ b/content/browser/worker_host/dedicated_worker_host.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CONTENT_BROWSER_DEDICATED_WORKER_DEDICATED_WORKER_HOST_H_ -#define CONTENT_BROWSER_DEDICATED_WORKER_DEDICATED_WORKER_HOST_H_ +#ifndef CONTENT_BROWSER_WORKER_HOST_DEDICATED_WORKER_HOST_H_ +#define CONTENT_BROWSER_WORKER_HOST_DEDICATED_WORKER_HOST_H_ #include "third_party/blink/public/platform/dedicated_worker_factory.mojom.h" @@ -21,4 +21,4 @@ } // namespace content -#endif // CONTENT_BROWSER_DEDICATED_WORKER_DEDICATED_WORKER_HOST_H_ +#endif // CONTENT_BROWSER_WORKER_HOST_DEDICATED_WORKER_HOST_H_
diff --git a/content/browser/shared_worker/mock_shared_worker.cc b/content/browser/worker_host/mock_shared_worker.cc similarity index 98% rename from content/browser/shared_worker/mock_shared_worker.cc rename to content/browser/worker_host/mock_shared_worker.cc index 826bcb4..4a1a4ae2 100644 --- a/content/browser/shared_worker/mock_shared_worker.cc +++ b/content/browser/worker_host/mock_shared_worker.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/browser/shared_worker/mock_shared_worker.h" +#include "content/browser/worker_host/mock_shared_worker.h" #include "content/common/url_loader_factory_bundle.h" #include "mojo/public/cpp/test_support/test_utils.h"
diff --git a/content/browser/shared_worker/mock_shared_worker.h b/content/browser/worker_host/mock_shared_worker.h similarity index 94% rename from content/browser/shared_worker/mock_shared_worker.h rename to content/browser/worker_host/mock_shared_worker.h index 21f76e8..51af99a 100644 --- a/content/browser/shared_worker/mock_shared_worker.h +++ b/content/browser/worker_host/mock_shared_worker.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CONTENT_BROWSER_SHARED_WORKER_MOCK_SHARED_WORKER_H_ -#define CONTENT_BROWSER_SHARED_WORKER_MOCK_SHARED_WORKER_H_ +#ifndef CONTENT_BROWSER_WORKER_HOST_MOCK_SHARED_WORKER_H_ +#define CONTENT_BROWSER_WORKER_HOST_MOCK_SHARED_WORKER_H_ #include <memory> #include <queue> @@ -13,7 +13,7 @@ #include <vector> #include "base/macros.h" -#include "content/browser/shared_worker/shared_worker_host.h" +#include "content/browser/worker_host/shared_worker_host.h" #include "content/common/service_worker/service_worker_provider.mojom.h" #include "content/common/shared_worker/shared_worker_factory.mojom.h" #include "mojo/public/cpp/bindings/binding.h" @@ -137,4 +137,4 @@ } // namespace content -#endif // CONTENT_BROWSER_SHARED_WORKER_MOCK_SHARED_WORKER_H_ +#endif // CONTENT_BROWSER_WORKER_HOST_MOCK_SHARED_WORKER_H_
diff --git a/content/browser/shared_worker/shared_worker_connector_impl.cc b/content/browser/worker_host/shared_worker_connector_impl.cc similarity index 94% rename from content/browser/shared_worker/shared_worker_connector_impl.cc rename to content/browser/worker_host/shared_worker_connector_impl.cc index 454feba..69e9a94 100644 --- a/content/browser/shared_worker/shared_worker_connector_impl.cc +++ b/content/browser/worker_host/shared_worker_connector_impl.cc
@@ -2,11 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "content/browser/shared_worker/shared_worker_connector_impl.h" +#include "content/browser/worker_host/shared_worker_connector_impl.h" #include "base/memory/ptr_util.h" -#include "content/browser/shared_worker/shared_worker_service_impl.h" #include "content/browser/storage_partition_impl.h" +#include "content/browser/worker_host/shared_worker_service_impl.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/render_process_host.h"
diff --git a/content/browser/shared_worker/shared_worker_connector_impl.h b/content/browser/worker_host/shared_worker_connector_impl.h similarity index 83% rename from content/browser/shared_worker/shared_worker_connector_impl.h rename to content/browser/worker_host/shared_worker_connector_impl.h index bd85820d..2ec5150 100644 --- a/content/browser/shared_worker/shared_worker_connector_impl.h +++ b/content/browser/worker_host/shared_worker_connector_impl.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CONTENT_BROWSER_SHARED_WORKER_SHARED_WORKER_CONNECTOR_IMPL_H_ -#define CONTENT_BROWSER_SHARED_WORKER_SHARED_WORKER_CONNECTOR_IMPL_H_ +#ifndef CONTENT_BROWSER_WORKER_HOST_SHARED_WORKER_CONNECTOR_IMPL_H_ +#define CONTENT_BROWSER_WORKER_HOST_SHARED_WORKER_CONNECTOR_IMPL_H_ #include "content/common/content_export.h" #include "content/common/shared_worker/shared_worker_connector.mojom.h" @@ -36,4 +36,4 @@ } // namespace content -#endif // CONTENT_BROWSER_SHARED_WORKER_SHARED_WORKER_CONNECTOR_IMPL_H_ +#endif // CONTENT_BROWSER_WORKER_HOST_SHARED_WORKER_CONNECTOR_IMPL_H_
diff --git a/content/browser/shared_worker/shared_worker_content_settings_proxy_impl.cc b/content/browser/worker_host/shared_worker_content_settings_proxy_impl.cc similarity index 84% rename from content/browser/shared_worker/shared_worker_content_settings_proxy_impl.cc rename to content/browser/worker_host/shared_worker_content_settings_proxy_impl.cc index 952ef9ab..015618e 100644 --- a/content/browser/shared_worker/shared_worker_content_settings_proxy_impl.cc +++ b/content/browser/worker_host/shared_worker_content_settings_proxy_impl.cc
@@ -2,12 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "content/browser/shared_worker/shared_worker_content_settings_proxy_impl.h" +#include "content/browser/worker_host/shared_worker_content_settings_proxy_impl.h" #include <utility> -#include "content/browser/shared_worker/shared_worker_host.h" -#include "content/browser/shared_worker/shared_worker_service_impl.h" +#include "content/browser/worker_host/shared_worker_host.h" +#include "content/browser/worker_host/shared_worker_service_impl.h" #include "url/gurl.h" namespace content {
diff --git a/content/browser/shared_worker/shared_worker_content_settings_proxy_impl.h b/content/browser/worker_host/shared_worker_content_settings_proxy_impl.h similarity index 86% rename from content/browser/shared_worker/shared_worker_content_settings_proxy_impl.h rename to content/browser/worker_host/shared_worker_content_settings_proxy_impl.h index 083ddcb..0b68858 100644 --- a/content/browser/shared_worker/shared_worker_content_settings_proxy_impl.h +++ b/content/browser/worker_host/shared_worker_content_settings_proxy_impl.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CONTENT_BROWSER_SHARED_WORKER_SHARED_WORKER_CONTENT_SETTING_PROXY_IMPL_H_ -#define CONTENT_BROWSER_SHARED_WORKER_SHARED_WORKER_CONTENT_SETTING_PROXY_IMPL_H_ +#ifndef CONTENT_BROWSER_WORKER_HOST_SHARED_WORKER_CONTENT_SETTINGS_PROXY_IMPL_H_ +#define CONTENT_BROWSER_WORKER_HOST_SHARED_WORKER_CONTENT_SETTINGS_PROXY_IMPL_H_ #include "base/callback.h" #include "base/strings/string16.h" @@ -48,4 +48,4 @@ } // namespace content -#endif // CONTENT_BROWSER_SHARED_WORKER_SHARED_WORKER_CONTENT_SETTING_PROXY_IMPL_H_ +#endif // CONTENT_BROWSER_WORKER_HOST_SHARED_WORKER_CONTENT_SETTINGS_PROXY_IMPL_H_
diff --git a/content/browser/shared_worker/shared_worker_host.cc b/content/browser/worker_host/shared_worker_host.cc similarity index 98% rename from content/browser/shared_worker/shared_worker_host.cc rename to content/browser/worker_host/shared_worker_host.cc index 3d4a4b5..bef09c17 100644 --- a/content/browser/shared_worker/shared_worker_host.cc +++ b/content/browser/worker_host/shared_worker_host.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/browser/shared_worker/shared_worker_host.h" +#include "content/browser/worker_host/shared_worker_host.h" #include <utility> @@ -14,10 +14,10 @@ #include "content/browser/devtools/shared_worker_devtools_manager.h" #include "content/browser/interface_provider_filtering.h" #include "content/browser/renderer_interface_binders.h" -#include "content/browser/shared_worker/shared_worker_content_settings_proxy_impl.h" -#include "content/browser/shared_worker/shared_worker_instance.h" -#include "content/browser/shared_worker/shared_worker_service_impl.h" #include "content/browser/storage_partition_impl.h" +#include "content/browser/worker_host/shared_worker_content_settings_proxy_impl.h" +#include "content/browser/worker_host/shared_worker_instance.h" +#include "content/browser/worker_host/shared_worker_service_impl.h" #include "content/common/navigation_subresource_loader_params.h" #include "content/common/url_loader_factory_bundle.h" #include "content/public/browser/browser_context.h"
diff --git a/content/browser/shared_worker/shared_worker_host.h b/content/browser/worker_host/shared_worker_host.h similarity index 97% rename from content/browser/shared_worker/shared_worker_host.h rename to content/browser/worker_host/shared_worker_host.h index d93e5b4..272ba1b 100644 --- a/content/browser/shared_worker/shared_worker_host.h +++ b/content/browser/worker_host/shared_worker_host.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CONTENT_BROWSER_SHARED_WORKER_SHARED_WORKER_HOST_H_ -#define CONTENT_BROWSER_SHARED_WORKER_SHARED_WORKER_HOST_H_ +#ifndef CONTENT_BROWSER_WORKER_HOST_SHARED_WORKER_HOST_H_ +#define CONTENT_BROWSER_WORKER_HOST_SHARED_WORKER_HOST_H_ #include <list> #include <memory> @@ -217,4 +217,4 @@ } // namespace content -#endif // CONTENT_BROWSER_SHARED_WORKER_SHARED_WORKER_HOST_H_ +#endif // CONTENT_BROWSER_WORKER_HOST_SHARED_WORKER_HOST_H_
diff --git a/content/browser/shared_worker/shared_worker_host_unittest.cc b/content/browser/worker_host/shared_worker_host_unittest.cc similarity index 97% rename from content/browser/shared_worker/shared_worker_host_unittest.cc rename to content/browser/worker_host/shared_worker_host_unittest.cc index 583d83e..6d3eda4a 100644 --- a/content/browser/shared_worker/shared_worker_host_unittest.cc +++ b/content/browser/worker_host/shared_worker_host_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/browser/shared_worker/shared_worker_host.h" +#include "content/browser/worker_host/shared_worker_host.h" #include <memory> #include <string> @@ -12,10 +12,10 @@ #include "base/run_loop.h" #include "content/browser/appcache/chrome_appcache_service.h" #include "content/browser/service_worker/embedded_worker_test_helper.h" -#include "content/browser/shared_worker/mock_shared_worker.h" -#include "content/browser/shared_worker/shared_worker_connector_impl.h" -#include "content/browser/shared_worker/shared_worker_instance.h" -#include "content/browser/shared_worker/shared_worker_service_impl.h" +#include "content/browser/worker_host/mock_shared_worker.h" +#include "content/browser/worker_host/shared_worker_connector_impl.h" +#include "content/browser/worker_host/shared_worker_instance.h" +#include "content/browser/worker_host/shared_worker_service_impl.h" #include "content/common/navigation_subresource_loader_params.h" #include "content/public/test/mock_render_process_host.h" #include "content/public/test/test_browser_context.h"
diff --git a/content/browser/shared_worker/shared_worker_instance.cc b/content/browser/worker_host/shared_worker_instance.cc similarity index 96% rename from content/browser/shared_worker/shared_worker_instance.cc rename to content/browser/worker_host/shared_worker_instance.cc index 67e1d88..3c9a91e 100644 --- a/content/browser/shared_worker/shared_worker_instance.cc +++ b/content/browser/worker_host/shared_worker_instance.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/browser/shared_worker/shared_worker_instance.h" +#include "content/browser/worker_host/shared_worker_instance.h" #include "base/logging.h"
diff --git a/content/browser/shared_worker/shared_worker_instance.h b/content/browser/worker_host/shared_worker_instance.h similarity index 93% rename from content/browser/shared_worker/shared_worker_instance.h rename to content/browser/worker_host/shared_worker_instance.h index eb909da..0e03dfbb 100644 --- a/content/browser/shared_worker/shared_worker_instance.h +++ b/content/browser/worker_host/shared_worker_instance.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CONTENT_BROWSER_SHARED_WORKER_SHARED_WORKER_INSTANCE_H_ -#define CONTENT_BROWSER_SHARED_WORKER_SHARED_WORKER_INSTANCE_H_ +#ifndef CONTENT_BROWSER_WORKER_HOST_SHARED_WORKER_INSTANCE_H_ +#define CONTENT_BROWSER_WORKER_HOST_SHARED_WORKER_INSTANCE_H_ #include <string> @@ -74,5 +74,4 @@ } // namespace content - -#endif // CONTENT_BROWSER_SHARED_WORKER_SHARED_WORKER_INSTANCE_H_ +#endif // CONTENT_BROWSER_WORKER_HOST_SHARED_WORKER_INSTANCE_H_
diff --git a/content/browser/shared_worker/shared_worker_instance_unittest.cc b/content/browser/worker_host/shared_worker_instance_unittest.cc similarity index 99% rename from content/browser/shared_worker/shared_worker_instance_unittest.cc rename to content/browser/worker_host/shared_worker_instance_unittest.cc index 779d67f..ec5b6c05 100644 --- a/content/browser/shared_worker/shared_worker_instance_unittest.cc +++ b/content/browser/worker_host/shared_worker_instance_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/browser/shared_worker/shared_worker_instance.h" +#include "content/browser/worker_host/shared_worker_instance.h" #include <memory>
diff --git a/content/browser/shared_worker/shared_worker_service_impl.cc b/content/browser/worker_host/shared_worker_service_impl.cc similarity index 97% rename from content/browser/shared_worker/shared_worker_service_impl.cc rename to content/browser/worker_host/shared_worker_service_impl.cc index 34fe1ac..79464f48 100644 --- a/content/browser/shared_worker/shared_worker_service_impl.cc +++ b/content/browser/worker_host/shared_worker_service_impl.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/browser/shared_worker/shared_worker_service_impl.h" +#include "content/browser/worker_host/shared_worker_service_impl.h" #include <stddef.h> @@ -19,12 +19,12 @@ #include "content/browser/appcache/appcache_navigation_handle.h" #include "content/browser/appcache/appcache_navigation_handle_core.h" #include "content/browser/file_url_loader_factory.h" -#include "content/browser/shared_worker/shared_worker_host.h" -#include "content/browser/shared_worker/shared_worker_instance.h" -#include "content/browser/shared_worker/worker_script_fetch_initiator.h" #include "content/browser/storage_partition_impl.h" #include "content/browser/url_loader_factory_getter.h" #include "content/browser/web_contents/web_contents_impl.h" +#include "content/browser/worker_host/shared_worker_host.h" +#include "content/browser/worker_host/shared_worker_instance.h" +#include "content/browser/worker_host/worker_script_fetch_initiator.h" #include "content/common/content_constants_internal.h" #include "content/common/navigation_subresource_loader_params.h" #include "content/common/service_worker/service_worker_provider.mojom.h"
diff --git a/content/browser/shared_worker/shared_worker_service_impl.h b/content/browser/worker_host/shared_worker_service_impl.h similarity index 94% rename from content/browser/shared_worker/shared_worker_service_impl.h rename to content/browser/worker_host/shared_worker_service_impl.h index a1e7471..be02df4 100644 --- a/content/browser/shared_worker/shared_worker_service_impl.h +++ b/content/browser/worker_host/shared_worker_service_impl.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CONTENT_BROWSER_SHARED_WORKER_SHARED_WORKER_SERVICE_IMPL_H_ -#define CONTENT_BROWSER_SHARED_WORKER_SHARED_WORKER_SERVICE_IMPL_H_ +#ifndef CONTENT_BROWSER_WORKER_HOST_SHARED_WORKER_SERVICE_IMPL_H_ +#define CONTENT_BROWSER_WORKER_HOST_SHARED_WORKER_SERVICE_IMPL_H_ #include <memory> #include <set> @@ -13,7 +13,7 @@ #include "base/containers/unique_ptr_adapters.h" #include "base/macros.h" #include "content/browser/service_worker/service_worker_context_wrapper.h" -#include "content/browser/shared_worker/shared_worker_host.h" +#include "content/browser/worker_host/shared_worker_host.h" #include "content/common/service_worker/service_worker_provider.mojom.h" #include "content/common/shared_worker/shared_worker_connector.mojom.h" #include "content/common/shared_worker/shared_worker_factory.mojom.h" @@ -131,4 +131,4 @@ } // namespace content -#endif // CONTENT_BROWSER_SHARED_WORKER_SHARED_WORKER_SERVICE_IMPL_H_ +#endif // CONTENT_BROWSER_WORKER_HOST_SHARED_WORKER_SERVICE_IMPL_H_
diff --git a/content/browser/shared_worker/shared_worker_service_impl_unittest.cc b/content/browser/worker_host/shared_worker_service_impl_unittest.cc similarity index 99% rename from content/browser/shared_worker/shared_worker_service_impl_unittest.cc rename to content/browser/worker_host/shared_worker_service_impl_unittest.cc index 49aa62c3..7279216 100644 --- a/content/browser/shared_worker/shared_worker_service_impl_unittest.cc +++ b/content/browser/worker_host/shared_worker_service_impl_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/browser/shared_worker/shared_worker_service_impl.h" +#include "content/browser/worker_host/shared_worker_service_impl.h" #include <memory> #include <queue> @@ -11,9 +11,9 @@ #include "base/macros.h" #include "base/run_loop.h" -#include "content/browser/shared_worker/mock_shared_worker.h" -#include "content/browser/shared_worker/shared_worker_connector_impl.h" #include "content/browser/site_instance_impl.h" +#include "content/browser/worker_host/mock_shared_worker.h" +#include "content/browser/worker_host/shared_worker_connector_impl.h" #include "content/public/test/mock_render_process_host.h" #include "content/public/test/test_browser_context.h" #include "content/public/test/test_utils.h"
diff --git a/content/browser/shared_worker/worker_browsertest.cc b/content/browser/worker_host/worker_browsertest.cc similarity index 98% rename from content/browser/shared_worker/worker_browsertest.cc rename to content/browser/worker_host/worker_browsertest.cc index 1735688f..fa0792e 100644 --- a/content/browser/shared_worker/worker_browsertest.cc +++ b/content/browser/worker_host/worker_browsertest.cc
@@ -244,8 +244,8 @@ // Generate test URL. GURL::Replacements replacements; replacements.SetSchemeStr("http"); - GURL url = ws_server.GetURL( - "websocket_shared_worker.html").ReplaceComponents(replacements); + GURL url = ws_server.GetURL("websocket_shared_worker.html") + .ReplaceComponents(replacements); // Run test. Shell* window = shell();
diff --git a/content/browser/shared_worker/worker_script_fetch_initiator.cc b/content/browser/worker_host/worker_script_fetch_initiator.cc similarity index 97% rename from content/browser/shared_worker/worker_script_fetch_initiator.cc rename to content/browser/worker_host/worker_script_fetch_initiator.cc index 69aa6a20..cf47bcf 100644 --- a/content/browser/shared_worker/worker_script_fetch_initiator.cc +++ b/content/browser/worker_host/worker_script_fetch_initiator.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/browser/shared_worker/worker_script_fetch_initiator.h" +#include "content/browser/worker_host/worker_script_fetch_initiator.h" #include "base/bind.h" #include "base/callback.h" @@ -15,12 +15,12 @@ #include "content/browser/appcache/appcache_navigation_handle_core.h" #include "content/browser/file_url_loader_factory.h" #include "content/browser/service_worker/service_worker_context_wrapper.h" -#include "content/browser/shared_worker/worker_script_fetcher.h" -#include "content/browser/shared_worker/worker_script_loader.h" -#include "content/browser/shared_worker/worker_script_loader_factory.h" #include "content/browser/storage_partition_impl.h" #include "content/browser/url_loader_factory_getter.h" #include "content/browser/web_contents/web_contents_impl.h" +#include "content/browser/worker_host/worker_script_fetcher.h" +#include "content/browser/worker_host/worker_script_loader.h" +#include "content/browser/worker_host/worker_script_loader_factory.h" #include "content/common/content_constants_internal.h" #include "content/common/navigation_subresource_loader_params.h" #include "content/common/service_worker/service_worker_provider.mojom.h"
diff --git a/content/browser/shared_worker/worker_script_fetch_initiator.h b/content/browser/worker_host/worker_script_fetch_initiator.h similarity index 94% rename from content/browser/shared_worker/worker_script_fetch_initiator.h rename to content/browser/worker_host/worker_script_fetch_initiator.h index 304cd56..5d232b2 100644 --- a/content/browser/shared_worker/worker_script_fetch_initiator.h +++ b/content/browser/worker_host/worker_script_fetch_initiator.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CONTENT_BROWSER_SHARED_WORKER_WORKER_SCRIPT_FETCH_INITIATOR_H_ -#define CONTENT_BROWSER_SHARED_WORKER_WORKER_SCRIPT_FETCH_INITIATOR_H_ +#ifndef CONTENT_BROWSER_WORKER_HOST_WORKER_SCRIPT_FETCH_INITIATOR_H_ +#define CONTENT_BROWSER_WORKER_HOST_WORKER_SCRIPT_FETCH_INITIATOR_H_ #include <memory> #include <set> @@ -93,4 +93,4 @@ } // namespace content -#endif // CONTENT_BROWSER_SHARED_WORKER_WORKER_SCRIPT_FETCH_INITIATOR_H_ +#endif // CONTENT_BROWSER_WORKER_HOST_WORKER_SCRIPT_FETCH_INITIATOR_H_
diff --git a/content/browser/shared_worker/worker_script_fetcher.cc b/content/browser/worker_host/worker_script_fetcher.cc similarity index 97% rename from content/browser/shared_worker/worker_script_fetcher.cc rename to content/browser/worker_host/worker_script_fetcher.cc index 74e66ef5..1c686ee 100644 --- a/content/browser/shared_worker/worker_script_fetcher.cc +++ b/content/browser/worker_host/worker_script_fetcher.cc
@@ -2,11 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "content/browser/shared_worker/worker_script_fetcher.h" +#include "content/browser/worker_host/worker_script_fetcher.h" #include "base/feature_list.h" -#include "content/browser/shared_worker/worker_script_loader.h" -#include "content/browser/shared_worker/worker_script_loader_factory.h" +#include "content/browser/worker_host/worker_script_loader.h" +#include "content/browser/worker_host/worker_script_loader_factory.h" #include "content/common/throttling_url_loader.h" #include "content/public/browser/browser_thread.h" #include "content/public/common/url_loader_throttle.h"
diff --git a/content/browser/shared_worker/worker_script_fetcher.h b/content/browser/worker_host/worker_script_fetcher.h similarity index 95% rename from content/browser/shared_worker/worker_script_fetcher.h rename to content/browser/worker_host/worker_script_fetcher.h index ba14ffe..4021f50 100644 --- a/content/browser/shared_worker/worker_script_fetcher.h +++ b/content/browser/worker_host/worker_script_fetcher.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CONTENT_BROWSER_SHARED_WORKER_WORKER_SCRIPT_FETCHER_H_ -#define CONTENT_BROWSER_SHARED_WORKER_WORKER_SCRIPT_FETCHER_H_ +#ifndef CONTENT_BROWSER_WORKER_HOST_WORKER_SCRIPT_FETCHER_H_ +#define CONTENT_BROWSER_WORKER_HOST_WORKER_SCRIPT_FETCHER_H_ #include "base/callback.h" #include "base/optional.h" @@ -94,4 +94,4 @@ } // namespace content -#endif // CONTENT_BROWSER_SHARED_WORKER_WORKER_SCRIPT_FETCHER_H_ +#endif // CONTENT_BROWSER_WORKER_HOST_WORKER_SCRIPT_FETCHER_H_
diff --git a/content/browser/shared_worker/worker_script_loader.cc b/content/browser/worker_host/worker_script_loader.cc similarity index 99% rename from content/browser/shared_worker/worker_script_loader.cc rename to content/browser/worker_host/worker_script_loader.cc index 96e2bd74..60e2a6b 100644 --- a/content/browser/shared_worker/worker_script_loader.cc +++ b/content/browser/worker_host/worker_script_loader.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/browser/shared_worker/worker_script_loader.h" +#include "content/browser/worker_host/worker_script_loader.h" #include "content/browser/appcache/appcache_request_handler.h" #include "content/browser/loader/navigation_loader_interceptor.h"
diff --git a/content/browser/shared_worker/worker_script_loader.h b/content/browser/worker_host/worker_script_loader.h similarity index 96% rename from content/browser/shared_worker/worker_script_loader.h rename to content/browser/worker_host/worker_script_loader.h index 36ca6fb..a390e6d 100644 --- a/content/browser/shared_worker/worker_script_loader.h +++ b/content/browser/worker_host/worker_script_loader.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CONTENT_BROWSER_SHARED_WORKER_WORKER_SCRIPT_LOADER_H_ -#define CONTENT_BROWSER_SHARED_WORKER_WORKER_SCRIPT_LOADER_H_ +#ifndef CONTENT_BROWSER_WORKER_HOST_WORKER_SCRIPT_LOADER_H_ +#define CONTENT_BROWSER_WORKER_HOST_WORKER_SCRIPT_LOADER_H_ #include "base/macros.h" #include "content/common/navigation_subresource_loader_params.h" @@ -145,4 +145,4 @@ }; } // namespace content -#endif // CONTENT_BROWSER_SHARED_WORKER_WORKER_SCRIPT_LOADER_H_ +#endif // CONTENT_BROWSER_WORKER_HOST_WORKER_SCRIPT_LOADER_H_
diff --git a/content/browser/shared_worker/worker_script_loader_factory.cc b/content/browser/worker_host/worker_script_loader_factory.cc similarity index 96% rename from content/browser/shared_worker/worker_script_loader_factory.cc rename to content/browser/worker_host/worker_script_loader_factory.cc index b86fa924..729be651 100644 --- a/content/browser/shared_worker/worker_script_loader_factory.cc +++ b/content/browser/worker_host/worker_script_loader_factory.cc
@@ -2,14 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "content/browser/shared_worker/worker_script_loader_factory.h" +#include "content/browser/worker_host/worker_script_loader_factory.h" #include <memory> #include "base/feature_list.h" #include "content/browser/service_worker/service_worker_context_core.h" #include "content/browser/service_worker/service_worker_provider_host.h" #include "content/browser/service_worker/service_worker_version.h" -#include "content/browser/shared_worker/worker_script_loader.h" +#include "content/browser/worker_host/worker_script_loader.h" #include "content/public/browser/browser_thread.h" #include "mojo/public/cpp/bindings/strong_binding.h" #include "services/network/public/cpp/features.h"
diff --git a/content/browser/shared_worker/worker_script_loader_factory.h b/content/browser/worker_host/worker_script_loader_factory.h similarity index 93% rename from content/browser/shared_worker/worker_script_loader_factory.h rename to content/browser/worker_host/worker_script_loader_factory.h index 9ce2be1..b15edbd 100644 --- a/content/browser/shared_worker/worker_script_loader_factory.h +++ b/content/browser/worker_host/worker_script_loader_factory.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CONTENT_BROWSER_SHARED_WORKER_WORKER_SCRIPT_LOADER_FACTORY_H_ -#define CONTENT_BROWSER_SHARED_WORKER_WORKER_SCRIPT_LOADER_FACTORY_H_ +#ifndef CONTENT_BROWSER_WORKER_HOST_WORKER_SCRIPT_LOADER_FACTORY_H_ +#define CONTENT_BROWSER_WORKER_HOST_WORKER_SCRIPT_LOADER_FACTORY_H_ #include "base/macros.h" #include "content/common/navigation_subresource_loader_params.h" @@ -74,4 +74,4 @@ } // namespace content -#endif // CONTENT_BROWSER_SHARED_WORKER_WORKER_SCRIPT_LOADER_FACTORY_H_ +#endif // CONTENT_BROWSER_WORKER_HOST_WORKER_SCRIPT_LOADER_FACTORY_H_
diff --git a/content/common/sandbox_mac_system_access_unittest.mm b/content/common/sandbox_mac_system_access_unittest.mm deleted file mode 100644 index 9a4d64f..0000000 --- a/content/common/sandbox_mac_system_access_unittest.mm +++ /dev/null
@@ -1,43 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import <Cocoa/Cocoa.h> -#include <stdint.h> - -#include "base/files/file_util.h" -#include "base/files/scoped_file.h" -#include "base/logging.h" -#include "base/memory/ref_counted.h" -#include "base/strings/sys_string_conversions.h" -#include "content/common/sandbox_mac_unittest_helper.h" -#include "crypto/openssl_util.h" -#include "services/service_manager/sandbox/mac/sandbox_mac.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "third_party/boringssl/src/include/openssl/rand.h" -#import "ui/base/clipboard/clipboard_util_mac.h" - -namespace content { - -//--------------------- OpenSSL Sandboxing ---------------------- -// Test case for checking sandboxing of OpenSSL initialization. -class MacSandboxedOpenSSLTestCase : public MacSandboxTestCase { - public: - bool SandboxedTest() override; -}; - -REGISTER_SANDBOX_TEST_CASE(MacSandboxedOpenSSLTestCase); - -bool MacSandboxedOpenSSLTestCase::SandboxedTest() { - crypto::EnsureOpenSSLInit(); - - // Ensure that RAND_bytes is functional within the sandbox. - uint8_t byte; - return RAND_bytes(&byte, 1) == 1; -} - -TEST_F(MacSandboxTest, OpenSSLAccess) { - EXPECT_TRUE(RunTestInAllSandboxTypes("MacSandboxedOpenSSLTestCase", NULL)); -} - -} // namespace content
diff --git a/content/common/url_schemes.cc b/content/common/url_schemes.cc index c922d97..e532406 100644 --- a/content/common/url_schemes.cc +++ b/content/common/url_schemes.cc
@@ -10,6 +10,7 @@ #include "base/no_destructor.h" #include "base/strings/string_util.h" +#include "build/build_config.h" #include "content/public/common/content_client.h" #include "content/public/common/url_constants.h" #include "url/url_util.h" @@ -89,6 +90,11 @@ for (auto& scheme : schemes.empty_document_schemes) url::AddEmptyDocumentScheme(scheme.c_str()); +#if defined(OS_ANDROID) + if (schemes.allow_non_standard_schemes_in_origins) + url::EnableNonStandardSchemesForAndroidWebView(); +#endif + // Prevent future modification of the scheme lists. This is to prevent // accidental creation of data races in the program. Add*Scheme aren't // threadsafe so must be called when GURL isn't used on any other thread. This
diff --git a/content/public/common/content_client.h b/content/public/common/content_client.h index b939bc2a..618a328 100644 --- a/content/public/common/content_client.h +++ b/content/public/common/content_client.h
@@ -139,6 +139,11 @@ // Registers a URL scheme as strictly empty documents, allowing them to // commit synchronously. std::vector<std::string> empty_document_schemes; +#if defined(OS_ANDROID) + // Normally, non-standard schemes canonicalize to opaque origins. However, + // Android WebView requires non-standard schemes to still be preserved. + bool allow_non_standard_schemes_in_origins = false; +#endif }; virtual void AddAdditionalSchemes(Schemes* schemes) {}
diff --git a/content/public/renderer/render_frame.h b/content/public/renderer/render_frame.h index 77df96a..5af168d 100644 --- a/content/public/renderer/render_frame.h +++ b/content/public/renderer/render_frame.h
@@ -255,6 +255,17 @@ // Returns the current visibility of the frame. virtual blink::mojom::PageVisibilityState GetVisibilityState() const = 0; + // Loads specified |html| to this frame. |base_url| is used to resolve + // relative urls in the document. + // |replace_current_item| should be true if we load html instead of the + // existing page. In this case |unreachable_url| might be the original url + // which did fail loading. + virtual void LoadHTMLString(const std::string& html, + const GURL& base_url, + const std::string& text_encoding, + const GURL& unreachable_url, + bool replace_current_item) = 0; + // If PlzNavigate is enabled, returns true in between teh time that Blink // requests navigation until the browser responds with the result. virtual bool IsBrowserSideNavigationPending() = 0;
diff --git a/content/public/test/render_view_test.cc b/content/public/test/render_view_test.cc index 9c37de4c..3d29793 100644 --- a/content/public/test/render_view_test.cc +++ b/content/public/test/render_view_test.cc
@@ -221,8 +221,9 @@ void RenderViewTest::LoadHTML(const char* html) { std::string url_string = "data:text/html;charset=utf-8,"; url_string.append(net::EscapeQueryParamValue(html, false)); - GetMainFrame()->LoadHTMLString(std::string(html), - blink::WebURL(GURL(url_string))); + RenderFrame::FromWebFrame(GetMainFrame()) + ->LoadHTMLString(html, GURL(url_string), "UTF-8", GURL(), + false /* replace_current_item */); // The load actually happens asynchronously, so we pump messages to process // the pending continuation. FrameLoadWaiter(view_->GetMainRenderFrame()).Wait(); @@ -232,8 +233,9 @@ void RenderViewTest::LoadHTMLWithUrlOverride(const char* html, const char* url_override) { - GetMainFrame()->LoadHTMLString(std::string(html), - blink::WebURL(GURL(url_override))); + RenderFrame::FromWebFrame(GetMainFrame()) + ->LoadHTMLString(html, GURL(url_override), "UTF-8", GURL(), + false /* replace_current_item */); // The load actually happens asynchronously, so we pump messages to process // the pending continuation. FrameLoadWaiter(view_->GetMainRenderFrame()).Wait();
diff --git a/content/renderer/dom_serializer_browsertest.cc b/content/renderer/dom_serializer_browsertest.cc index 14e32bb5..34f6615 100644 --- a/content/renderer/dom_serializer_browsertest.cc +++ b/content/renderer/dom_serializer_browsertest.cc
@@ -131,19 +131,10 @@ const GURL& base_url, const WebString encoding_info) { FrameLoadWaiter waiter(GetRenderView()->GetMainRenderFrame()); - // If input encoding is empty, use UTF-8 as default encoding. - if (encoding_info.IsEmpty()) { - GetMainFrame()->LoadHTMLString(contents, base_url); - } else { - // Do not use WebFrame.LoadHTMLString because it assumes that input - // html contents use UTF-8 encoding. - WebData data(contents.data(), contents.length()); - GetMainFrame()->CommitDataNavigation( - blink::WebURLRequest(base_url), data, "text/html", encoding_info, - WebURL(), blink::WebFrameLoadType::kStandard, blink::WebHistoryItem(), - false /* is_client_redirect */, nullptr /* navigation_params */, - nullptr /* navigation_data */); - } + GetRenderView()->GetMainRenderFrame()->LoadHTMLString( + contents, base_url, + encoding_info.IsEmpty() ? "UTF-8" : encoding_info.Utf8(), GURL(), + false /* replace_current_item */); base::MessageLoopCurrent::ScopedNestableTaskAllower allow; waiter.Wait(); }
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index 4fef95c..84e89a6 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -204,6 +204,7 @@ #include "third_party/blink/public/web/web_frame_widget.h" #include "third_party/blink/public/web/web_input_method_controller.h" #include "third_party/blink/public/web/web_local_frame.h" +#include "third_party/blink/public/web/web_navigation_control.h" #include "third_party/blink/public/web/web_navigation_policy.h" #include "third_party/blink/public/web/web_navigation_timings.h" #include "third_party/blink/public/web/web_plugin.h" @@ -1298,7 +1299,7 @@ WebString::FromUTF8(replicated_state.name), replicated_state.frame_policy.sandbox_flags); if (has_committed_real_load) - web_frame->SetCommittedFirstRealLoad(); + render_frame->frame_->SetCommittedFirstRealLoad(); // The RenderViewImpl and its RenderWidget already exist by the time we get // here. @@ -1531,7 +1532,7 @@ } if (has_committed_real_load) - web_frame->SetCommittedFirstRealLoad(); + render_frame->frame_->SetCommittedFirstRealLoad(); render_frame->Initialize(); } @@ -2914,14 +2915,14 @@ pending_context_menus_.Remove(request_id); } -void RenderFrameImpl::BindToFrame(WebLocalFrame* web_frame) { +void RenderFrameImpl::BindToFrame(blink::WebNavigationControl* frame) { DCHECK(!frame_); std::pair<FrameMap::iterator, bool> result = - g_frame_map.Get().emplace(web_frame, this); + g_frame_map.Get().emplace(frame, this); CHECK(result.second) << "Inserting a duplicate item."; - frame_ = web_frame; + frame_ = frame; } blink::WebPlugin* RenderFrameImpl::CreatePlugin( @@ -3383,10 +3384,10 @@ // On load failure, a frame can ask its owner to render fallback content. // When that happens, don't load an error page. - WebLocalFrame::FallbackContentResult fallback_result = + blink::WebNavigationControl::FallbackContentResult fallback_result = frame_->MaybeRenderFallbackContent(error); - if (fallback_result != WebLocalFrame::NoFallbackContent) { - if (fallback_result == WebLocalFrame::NoLoadInProgress) { + if (fallback_result != blink::WebNavigationControl::NoFallbackContent) { + if (fallback_result == blink::WebNavigationControl::NoLoadInProgress) { // If the frame wasn't loading but was fallback-eligible, the fallback // content won't be shown. However, showing an error page isn't right // either, as the frame has already been populated with something @@ -7085,6 +7086,20 @@ return browser_side_navigation_pending_; } +void RenderFrameImpl::LoadHTMLString(const std::string& html, + const GURL& base_url, + const std::string& text_encoding, + const GURL& unreachable_url, + bool replace_current_item) { + frame_->CommitDataNavigation( + blink::WebURLRequest(base_url), WebData(html.data(), html.length()), + "text/html", WebString::FromUTF8(text_encoding), unreachable_url, + replace_current_item ? blink::WebFrameLoadType::kReplaceCurrentItem + : blink::WebFrameLoadType::kStandard, + blink::WebHistoryItem(), false /* is_client_redirect */, + nullptr /* navigation_params */, nullptr /* navigation_data */); +} + scoped_refptr<base::SingleThreadTaskRunner> RenderFrameImpl::GetTaskRunner( blink::TaskType task_type) { return GetWebFrame()->GetTaskRunner(task_type);
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h index 22e36a5..8359b31 100644 --- a/content/renderer/render_frame_impl.h +++ b/content/renderer/render_frame_impl.h
@@ -463,7 +463,7 @@ int ShowContextMenu(ContextMenuClient* client, const ContextMenuParams& params) override; void CancelContextMenu(int request_id) override; - void BindToFrame(blink::WebLocalFrame* frame) override; + void BindToFrame(blink::WebNavigationControl* frame) override; blink::WebPlugin* CreatePlugin( const WebPluginInfo& info, const blink::WebPluginParams& params, @@ -505,6 +505,11 @@ bool IsPasting() const override; blink::mojom::PageVisibilityState GetVisibilityState() const override; bool IsBrowserSideNavigationPending() override; + void LoadHTMLString(const std::string& html, + const GURL& base_url, + const std::string& text_encoding, + const GURL& unreachable_url, + bool replace_current_item) override; scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner( blink::TaskType task_type) override; int GetEnabledBindings() const override; @@ -1298,7 +1303,7 @@ // constructor until BindToFrame() is called, and it is null after // FrameDetached() is called until destruction (which is asynchronous in the // case of the main frame, but not subframes). - blink::WebLocalFrame* frame_; + blink::WebNavigationControl* frame_ = nullptr; // Boolean value indicating whether this RenderFrameImpl object is for the // main frame or not. It remains accurate during destruction, even when
diff --git a/content/renderer/render_view_browsertest.cc b/content/renderer/render_view_browsertest.cc index c3bc1e6..8decba47 100644 --- a/content/renderer/render_view_browsertest.cc +++ b/content/renderer/render_view_browsertest.cc
@@ -2212,8 +2212,8 @@ // recorded at an appropriate time and is passed in the corresponding message. TEST_F(RenderViewImplTest, RendererNavigationStartTransmittedToBrowser) { base::TimeTicks lower_bound_navigation_start(base::TimeTicks::Now()); - frame()->GetWebFrame()->LoadHTMLString( - "hello world", blink::WebURL(GURL("data:text/html,"))); + frame()->LoadHTMLString("hello world", GURL("data:text/html,"), "UTF-8", + GURL(), false /* replace_current_item */); NavigationState* navigation_state = NavigationState::FromDocumentLoader( frame()->GetWebFrame()->GetProvisionalDocumentLoader());
diff --git a/content/renderer/service_worker/service_worker_subresource_loader.cc b/content/renderer/service_worker/service_worker_subresource_loader.cc index 79e404a..649ef3b 100644 --- a/content/renderer/service_worker/service_worker_subresource_loader.cc +++ b/content/renderer/service_worker/service_worker_subresource_loader.cc
@@ -631,9 +631,9 @@ fetch_event_timing_->respond_with_settled_time); // Time spent reading response body. - UMA_HISTOGRAM_TIMES( + UMA_HISTOGRAM_MEDIUM_TIMES( "ServiceWorker.LoadTiming.Subresource." - "ResponseReceivedToCompleted", + "ResponseReceivedToCompleted2", completion_time - response_head_.load_timing.receive_headers_end); } else { // Mojo message delay (network fallback case). See above for the detail.
diff --git a/content/renderer/service_worker/service_worker_subresource_loader_unittest.cc b/content/renderer/service_worker/service_worker_subresource_loader_unittest.cc index 6366f8ff..f3d1ed7 100644 --- a/content/renderer/service_worker/service_worker_subresource_loader_unittest.cc +++ b/content/renderer/service_worker/service_worker_subresource_loader_unittest.cc
@@ -637,7 +637,7 @@ "ServiceWorker.LoadTiming.Subresource.ForwardServiceWorkerToWorkerReady", 1); histogram_tester.ExpectTotalCount( - "ServiceWorker.LoadTiming.Subresource.ResponseReceivedToCompleted", 1); + "ServiceWorker.LoadTiming.Subresource.ResponseReceivedToCompleted2", 1); } TEST_F(ServiceWorkerSubresourceLoaderTest, Abort) { @@ -665,7 +665,7 @@ "ServiceWorker.LoadTiming.Subresource.ForwardServiceWorkerToWorkerReady", 0); histogram_tester.ExpectTotalCount( - "ServiceWorker.LoadTiming.Subresource.ResponseReceivedToCompleted", 0); + "ServiceWorker.LoadTiming.Subresource.ResponseReceivedToCompleted2", 0); } TEST_F(ServiceWorkerSubresourceLoaderTest, DropController) { @@ -766,7 +766,7 @@ "ServiceWorker.LoadTiming.Subresource.ForwardServiceWorkerToWorkerReady", 0); histogram_tester.ExpectTotalCount( - "ServiceWorker.LoadTiming.Subresource.ResponseReceivedToCompleted", 0); + "ServiceWorker.LoadTiming.Subresource.ResponseReceivedToCompleted2", 0); } TEST_F(ServiceWorkerSubresourceLoaderTest, DropController_RestartFetchEvent) { @@ -829,7 +829,7 @@ "ServiceWorker.LoadTiming.Subresource.ForwardServiceWorkerToWorkerReady", 1); histogram_tester.ExpectTotalCount( - "ServiceWorker.LoadTiming.Subresource.ResponseReceivedToCompleted", 1); + "ServiceWorker.LoadTiming.Subresource.ResponseReceivedToCompleted2", 1); } TEST_F(ServiceWorkerSubresourceLoaderTest, DropController_TooManyRestart) { @@ -863,7 +863,7 @@ "ServiceWorker.LoadTiming.Subresource.ForwardServiceWorkerToWorkerReady", 0); histogram_tester.ExpectTotalCount( - "ServiceWorker.LoadTiming.Subresource.ResponseReceivedToCompleted", 0); + "ServiceWorker.LoadTiming.Subresource.ResponseReceivedToCompleted2", 0); } TEST_F(ServiceWorkerSubresourceLoaderTest, StreamResponse) { @@ -917,7 +917,7 @@ "ServiceWorker.LoadTiming.Subresource.ForwardServiceWorkerToWorkerReady", 1); histogram_tester.ExpectTotalCount( - "ServiceWorker.LoadTiming.Subresource.ResponseReceivedToCompleted", 1); + "ServiceWorker.LoadTiming.Subresource.ResponseReceivedToCompleted2", 1); } TEST_F(ServiceWorkerSubresourceLoaderTest, StreamResponse_Abort) { @@ -971,7 +971,7 @@ "ServiceWorker.LoadTiming.Subresource.ForwardServiceWorkerToWorkerReady", 0); histogram_tester.ExpectTotalCount( - "ServiceWorker.LoadTiming.Subresource.ResponseReceivedToCompleted", 0); + "ServiceWorker.LoadTiming.Subresource.ResponseReceivedToCompleted2", 0); } TEST_F(ServiceWorkerSubresourceLoaderTest, BlobResponse) { @@ -1022,7 +1022,7 @@ "ServiceWorker.LoadTiming.Subresource.ForwardServiceWorkerToWorkerReady", 1); histogram_tester.ExpectTotalCount( - "ServiceWorker.LoadTiming.Subresource.ResponseReceivedToCompleted", 1); + "ServiceWorker.LoadTiming.Subresource.ResponseReceivedToCompleted2", 1); } TEST_F(ServiceWorkerSubresourceLoaderTest, BlobResponseWithoutMetadata) { @@ -1065,7 +1065,7 @@ "ServiceWorker.LoadTiming.Subresource.ForwardServiceWorkerToWorkerReady", 1); histogram_tester.ExpectTotalCount( - "ServiceWorker.LoadTiming.Subresource.ResponseReceivedToCompleted", 1); + "ServiceWorker.LoadTiming.Subresource.ResponseReceivedToCompleted2", 1); } // Test when the service worker responds with network fallback. @@ -1125,7 +1125,7 @@ "ServiceWorker.LoadTiming.Subresource.ForwardServiceWorkerToWorkerReady", 0); histogram_tester.ExpectTotalCount( - "ServiceWorker.LoadTiming.Subresource.ResponseReceivedToCompleted", 0); + "ServiceWorker.LoadTiming.Subresource.ResponseReceivedToCompleted2", 0); } TEST_F(ServiceWorkerSubresourceLoaderTest, RedirectResponse) {
diff --git a/content/shell/renderer/layout_test/blink_test_runner.cc b/content/shell/renderer/layout_test/blink_test_runner.cc index f2970fe..d9bed3a4 100644 --- a/content/shell/renderer/layout_test/blink_test_runner.cc +++ b/content/shell/renderer/layout_test/blink_test_runner.cc
@@ -849,12 +849,9 @@ LayoutTestRenderThreadObserver::GetInstance()->test_interfaces()->ResetAll(); Reset(true /* for_new_test */); // Navigating to about:blank will make sure that no new loads are initiated - // by the renderer. - main_frame->CommitNavigation( - WebURLRequest(GURL(url::kAboutBlankURL)), - blink::WebFrameLoadType::kStandard, blink::WebHistoryItem(), false, - base::UnguessableToken::Create(), nullptr /* navigation_params */, - nullptr /* extra_data */); + // by the renderer. We know that about:blank navigation will finish + // without going to the network. + main_frame->StartNavigation(WebURLRequest(GURL(url::kAboutBlankURL))); Send(new ShellViewHostMsg_ResetDone(routing_id())); }
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index 081f9c8..41e349b3 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -865,7 +865,6 @@ "../browser/service_worker/service_worker_tls_browsertest.cc", "../browser/session_history_browsertest.cc", "../browser/shape_detection/shape_detection_browsertest.cc", - "../browser/shared_worker/worker_browsertest.cc", "../browser/site_per_process_browsertest.cc", "../browser/site_per_process_browsertest.h", "../browser/site_per_process_hit_test_browsertest.cc", @@ -910,6 +909,7 @@ "../browser/webrtc/webrtc_webcam_browsertest.cc", "../browser/webrtc/webrtc_webcam_browsertest.h", "../browser/webui/web_ui_mojo_browsertest.cc", + "../browser/worker_host/worker_browsertest.cc", "../renderer/accessibility/render_accessibility_impl_browsertest.cc", "../renderer/blink_platform_audio_hardware_browsertest.cc", "../renderer/gin_browsertest.cc", @@ -1612,11 +1612,6 @@ "../browser/service_worker/service_worker_version_unittest.cc", "../browser/service_worker/service_worker_write_to_cache_job_unittest.cc", "../browser/shareable_file_reference_unittest.cc", - "../browser/shared_worker/mock_shared_worker.cc", - "../browser/shared_worker/mock_shared_worker.h", - "../browser/shared_worker/shared_worker_host_unittest.cc", - "../browser/shared_worker/shared_worker_instance_unittest.cc", - "../browser/shared_worker/shared_worker_service_impl_unittest.cc", "../browser/site_instance_impl_unittest.cc", "../browser/startup_task_runner_unittest.cc", "../browser/storage_partition_impl_map_unittest.cc", @@ -1653,6 +1648,11 @@ "../browser/webui/url_data_manager_backend_unittest.cc", "../browser/webui/web_ui_data_source_unittest.cc", "../browser/webui/web_ui_message_handler_unittest.cc", + "../browser/worker_host/mock_shared_worker.cc", + "../browser/worker_host/mock_shared_worker.h", + "../browser/worker_host/shared_worker_host_unittest.cc", + "../browser/worker_host/shared_worker_instance_unittest.cc", + "../browser/worker_host/shared_worker_service_impl_unittest.cc", "../child/blink_platform_impl_unittest.cc", "../child/dwrite_font_proxy/dwrite_font_proxy_win_unittest.cc", "../child/dwrite_font_proxy/font_fallback_win_unittest.cc", @@ -1683,7 +1683,6 @@ "../common/page_zoom_unittest.cc", "../common/plugin_list_unittest.cc", "../common/sandbox_mac_fontloading_unittest.mm", - "../common/sandbox_mac_system_access_unittest.mm", "../common/sandbox_mac_unittest_helper.h", "../common/sandbox_mac_unittest_helper.mm", "../common/service_manager/service_manager_connection_impl_unittest.cc",
diff --git a/content/test/data/sxg/generate-test-certs.sh b/content/test/data/sxg/generate-test-certs.sh index deadbbd3..3d2021f 100755 --- a/content/test/data/sxg/generate-test-certs.sh +++ b/content/test/data/sxg/generate-test-certs.sh
@@ -43,10 +43,6 @@ echo "with the followings:" echo "====" -echo 'constexpr char kCertPEMRSA[] = R"(' -sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' \ - ../../../../net/data/ssl/certificates/wildcard.pem -echo ')";' echo 'constexpr char kCertPEMECDSAP256[] = R"(' cat ./prime256v1-sha256.public.pem echo ')";'
diff --git a/content/test/data/sxg/generate-test-sxgs.sh b/content/test/data/sxg/generate-test-sxgs.sh index ae694a81..50f82c4 100755 --- a/content/test/data/sxg/generate-test-sxgs.sh +++ b/content/test/data/sxg/generate-test-sxgs.sh
@@ -113,23 +113,6 @@ echo "signed_exchange_signature_verifier_unittest.cc with the followings:" echo "====" -sed -ne '/-BEGIN PRIVATE KEY-/,/-END PRIVATE KEY-/p' \ - ../../../../net/data/ssl/certificates/wildcard.pem \ - > $tmpdir/wildcard_example.org.private.pem -sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' \ - ../../../../net/data/ssl/certificates/wildcard.pem \ - > $tmpdir/wildcard_example.org.public.pem -gen-signedexchange \ - -version 1b2 \ - -uri https://test.example.org/test/ \ - -content test.html \ - -certificate $tmpdir/wildcard_example.org.public.pem \ - -privateKey $tmpdir/wildcard_example.org.private.pem \ - -date 2018-02-06T04:45:41Z \ - -o $tmpdir/out.htxg - -dumpSignature kSignatureHeaderRSA $tmpdir/out.htxg - gen-signedexchange \ -version 1b2 \ -uri https://test.example.org/test/ \
diff --git a/content/test/fuzzer/merkle_integrity_source_stream_fuzzer.cc b/content/test/fuzzer/merkle_integrity_source_stream_fuzzer.cc index 8e3a419..5b63bfd 100644 --- a/content/test/fuzzer/merkle_integrity_source_stream_fuzzer.cc +++ b/content/test/fuzzer/merkle_integrity_source_stream_fuzzer.cc
@@ -27,7 +27,7 @@ auto mi_stream = std::make_unique<content::MerkleIntegritySourceStream>( header, std::move(fuzzed_source_stream)); while (true) { - size_t read_size = data_provider.ConsumeUint32InRange(1, 1024); + size_t read_size = data_provider.ConsumeIntegralInRange(1, 1024); auto io_buffer = base::MakeRefCounted<net::IOBufferWithSize>(read_size); int result = mi_stream->Read(io_buffer.get(), io_buffer->size(), callback.callback());
diff --git a/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py b/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py index 06fbaea..3d4a1a1f99 100644 --- a/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py +++ b/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py
@@ -65,10 +65,6 @@ self.Fail('conformance2/textures/misc/tex-subimage3d-canvas-bug.html', ['win', 'opengl', 'passthrough'], bug=859400) - # Failing new test added in https://github.com/KhronosGroup/WebGL/pull/2658 - self.Fail('conformance2/transform_feedback/' + - 'same-buffer-two-binding-points.html', bug=866089) - # Too slow (take about one hour to run) self.Skip('deqp/functional/gles3/builtinprecision/*.html', bug=619403)
diff --git a/content/test/layouttest_support.cc b/content/test/layouttest_support.cc index b3537e5..dfc1222 100644 --- a/content/test/layouttest_support.cc +++ b/content/test/layouttest_support.cc
@@ -23,7 +23,7 @@ #include "content/browser/bluetooth/bluetooth_device_chooser_controller.h" #include "content/browser/renderer_host/render_process_host_impl.h" #include "content/browser/renderer_host/render_widget_host_impl.h" -#include "content/browser/shared_worker/shared_worker_service_impl.h" +#include "content/browser/worker_host/shared_worker_service_impl.h" #include "content/common/renderer.mojom.h" #include "content/common/unique_name_helper.h" #include "content/public/browser/storage_partition.h"
diff --git a/content/test/test_render_frame.cc b/content/test/test_render_frame.cc index 23282310..ffd6bb4d 100644 --- a/content/test/test_render_frame.cc +++ b/content/test/test_render_frame.cc
@@ -20,6 +20,7 @@ #include "services/network/public/cpp/resource_response.h" #include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h" #include "third_party/blink/public/web/web_local_frame.h" +#include "third_party/blink/public/web/web_navigation_control.h" namespace content { @@ -215,7 +216,7 @@ // frame. However if the loaded html has a subframe, // BeginNavigation will be called from Blink and we should avoid // going through browser process in this case. - GetWebFrame()->CommitNavigation( + frame_->CommitNavigation( info->url_request, info->frame_load_type, blink::WebHistoryItem(), info->is_client_redirect, base::UnguessableToken::Create(), nullptr /* navigation_params */, nullptr /* extra_data */);
diff --git a/docs/speed/benchmark/harnesses/blink_perf.md b/docs/speed/benchmark/harnesses/blink_perf.md index 107a4f7..f757799 100644 --- a/docs/speed/benchmark/harnesses/blink_perf.md +++ b/docs/speed/benchmark/harnesses/blink_perf.md
@@ -147,6 +147,28 @@ [simple-blob-measure-async.html](https://chromium.googlesource.com/chromium/src/+/master/third_party/blink/perf_tests/test_data/simple-blob-measure-async.html) +## Canvas Tests + +The sub-framework [canvas_runner.js](https://chromium.googlesource.com/chromium/src/+/master/third_party/blink/perf_tests/canvas/resources/canvas_runner.js) is used for +tests in the `canvas` directory. This can measure rasterization and GPU time +using requestAnimationFrame (RAF) and contains a callback framework for video. + +Normal tests using `runTest()` work similarly to the asynchronous test above, +but crucially wait for RAF after completing a single trial of +`MEASURE_DRAW_TIMES` runs. + +RAF tests are triggered by appending the query string `raf` (case insensitive) +to the test's url. These tests wait for RAF to return before making a +measurement. This way rasterization and GPU time are included in the +measurement. + +For example: + +The test [gpu-bound-shader.html](https://chromium.googlesource.com/chromium/src/+/master/third_party/blink/perf_tests/canvas/gpu-bound-shader.html) is just measuring +CPU, and thus looks extremely fast as the test is just one slow shader. + +The url `gpu-bound-shader.html?raf` will measure rasterization and GPU time as +well, thus giving a more realistic measurement of performance. ## Running Tests
diff --git a/extensions/browser/api/web_request/web_request_api.cc b/extensions/browser/api/web_request/web_request_api.cc index 9835eaf..582e35e 100644 --- a/extensions/browser/api/web_request/web_request_api.cc +++ b/extensions/browser/api/web_request/web_request_api.cc
@@ -935,7 +935,8 @@ } } request_time_tracker_->LogRequestStartTime( - request->id, base::TimeTicks::Now(), has_listener); + request->id, base::TimeTicks::Now(), has_listener, + HasExtraHeadersListener(browser_context, extension_info_map, request)); const bool is_incognito_context = IsIncognitoBrowserContext(browser_context);
diff --git a/extensions/browser/api/web_request/web_request_time_tracker.cc b/extensions/browser/api/web_request/web_request_time_tracker.cc index 326cb9b..b7662de8 100644 --- a/extensions/browser/api/web_request/web_request_time_tracker.cc +++ b/extensions/browser/api/web_request/web_request_time_tracker.cc
@@ -21,7 +21,8 @@ void ExtensionWebRequestTimeTracker::LogRequestStartTime( int64_t request_id, const base::TimeTicks& start_time, - bool has_listener) { + bool has_listener, + bool has_extra_headers_listener) { auto iter = request_time_logs_.find(request_id); if (iter != request_time_logs_.end()) return; @@ -29,6 +30,7 @@ RequestTimeLog& log = request_time_logs_[request_id]; log.request_start_time = start_time; log.has_listener = has_listener; + log.has_extra_headers_listener = has_extra_headers_listener; } void ExtensionWebRequestTimeTracker::LogRequestEndTime( @@ -53,6 +55,11 @@ request_duration); } + if (log.has_extra_headers_listener) { + UMA_HISTOGRAM_TIMES("Extensions.WebRequest.TotalExtraHeadersRequestTime", + request_duration); + } + if (log.block_duration.is_zero()) return;
diff --git a/extensions/browser/api/web_request/web_request_time_tracker.h b/extensions/browser/api/web_request/web_request_time_tracker.h index e26bc9c4..01e59ab 100644 --- a/extensions/browser/api/web_request/web_request_time_tracker.h +++ b/extensions/browser/api/web_request/web_request_time_tracker.h
@@ -21,10 +21,14 @@ ExtensionWebRequestTimeTracker(); ~ExtensionWebRequestTimeTracker(); - // Records the time that a request was created. + // Records the time that a request was created. |has_listener| will be true + // if there is at least one webRequest listener registered. + // |has_extra_headers_listener| will be true if there is at least one listener + // with 'extraHeaders' in the extraInfoSpec. void LogRequestStartTime(int64_t request_id, const base::TimeTicks& start_time, - bool has_listener); + bool has_listener, + bool has_extra_headers_listener); // Records the time that a request either completed or encountered an error. void LogRequestEndTime(int64_t request_id, const base::TimeTicks& end_time); @@ -48,6 +52,7 @@ base::TimeTicks request_start_time; base::TimeDelta block_duration; bool has_listener = false; + bool has_extra_headers_listener = false; RequestTimeLog(); ~RequestTimeLog();
diff --git a/extensions/browser/api/web_request/web_request_time_tracker_unittest.cc b/extensions/browser/api/web_request/web_request_time_tracker_unittest.cc index 11ef7d2..6d65cef 100644 --- a/extensions/browser/api/web_request/web_request_time_tracker_unittest.cc +++ b/extensions/browser/api/web_request/web_request_time_tracker_unittest.cc
@@ -26,10 +26,10 @@ ExtensionWebRequestTimeTracker tracker; base::TimeTicks start; - tracker.LogRequestStartTime(1, start, false); - tracker.LogRequestStartTime(2, start, true); - tracker.LogRequestStartTime(3, start, true); - tracker.LogRequestStartTime(4, start, true); + tracker.LogRequestStartTime(1, start, false, false); + tracker.LogRequestStartTime(2, start, true, false); + tracker.LogRequestStartTime(3, start, true, false); + tracker.LogRequestStartTime(4, start, true, true); tracker.IncrementTotalBlockTime(1, kTinyDelay); tracker.IncrementTotalBlockTime(2, kModerateDelay); tracker.IncrementTotalBlockTime(2, kModerateDelay); @@ -66,5 +66,11 @@ histogram_tester.ExpectTotalCount( "Extensions.WebRequest.TotalBlockingRequestTime", 3); + histogram_tester.ExpectTimeBucketCount( + "Extensions.WebRequest.TotalExtraHeadersRequestTime", kLongRequestDelta, + 1); + histogram_tester.ExpectTotalCount( + "Extensions.WebRequest.TotalExtraHeadersRequestTime", 1); + EXPECT_TRUE(tracker.request_time_logs_.empty()); }
diff --git a/extensions/renderer/script_context_browsertest.cc b/extensions/renderer/script_context_browsertest.cc index 411894a1..a545009 100644 --- a/extensions/renderer/script_context_browsertest.cc +++ b/extensions/renderer/script_context_browsertest.cc
@@ -45,7 +45,8 @@ WebLocalFrame* frame = GetMainFrame(); ASSERT_TRUE(frame); - frame->LoadHTMLString(frame_html, top_url); + content::RenderFrame::FromWebFrame(frame)->LoadHTMLString( + frame_html, top_url, "UTF-8", GURL(), false /* replace_current_item */); content::FrameLoadWaiter(content::RenderFrame::FromWebFrame(frame)).Wait(); WebLocalFrame* frame1 = frame->FirstChild()->ToWebLocalFrame(); @@ -68,7 +69,9 @@ ASSERT_EQ("frame3", frame3->AssignedName()); // Load a blank document in a frame from a different origin. - frame3->LoadHTMLString(frame3_html, different_url); + content::RenderFrame::FromWebFrame(frame3)->LoadHTMLString( + frame3_html, different_url, "UTF-8", GURL(), + false /* replace_current_item */); content::FrameLoadWaiter(content::RenderFrame::FromWebFrame(frame3)).Wait(); WebLocalFrame* frame3_1 = frame3->FirstChild()->ToWebLocalFrame();
diff --git a/gpu/command_buffer/service/buffer_manager.h b/gpu/command_buffer/service/buffer_manager.h index 72fdd60..c21ea415 100644 --- a/gpu/command_buffer/service/buffer_manager.h +++ b/gpu/command_buffer/service/buffer_manager.h
@@ -117,6 +117,10 @@ non_transform_feedback_binding_count_ > 0; } + bool IsDoubleBoundForTransformFeedback() const { + return transform_feedback_indexed_binding_count_ > 1; + } + void SetReadbackShadowAllocation(scoped_refptr<gpu::Buffer> shm, uint32_t shm_offset); scoped_refptr<gpu::Buffer> TakeReadbackShadowAllocation(void** data);
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index 5cbea96..e4be47a 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -6456,6 +6456,13 @@ LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, msg.c_str()); return; } + if (buffer->IsDoubleBoundForTransformFeedback()) { + std::string msg = base::StringPrintf( + "buffer at index %i is bound for multiple transform feedback outputs", + static_cast<int>(ii)); + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, msg.c_str()); + return; + } } transform_feedback->DoBeginTransformFeedback(primitive_mode); DCHECK(transform_feedback->active());
diff --git a/gpu/ipc/common/gpu_memory_buffer_support.cc b/gpu/ipc/common/gpu_memory_buffer_support.cc index 2aa7672c..66ac787 100644 --- a/gpu/ipc/common/gpu_memory_buffer_support.cc +++ b/gpu/ipc/common/gpu_memory_buffer_support.cc
@@ -20,6 +20,7 @@ #if defined(USE_OZONE) #include "ui/ozone/public/client_native_pixmap_factory_ozone.h" +#include "ui/ozone/public/ozone_platform.h" #endif #if defined(OS_WIN) @@ -42,13 +43,6 @@ #endif } -#if defined(OS_LINUX) || defined(USE_OZONE) -GpuMemoryBufferSupport::GpuMemoryBufferSupport( - std::unique_ptr<gfx::ClientNativePixmapFactory> - client_native_pixmap_factory) - : client_native_pixmap_factory_(std::move(client_native_pixmap_factory)) {} -#endif - GpuMemoryBufferSupport::~GpuMemoryBufferSupport() {} gfx::GpuMemoryBufferType @@ -113,7 +107,8 @@ NOTREACHED(); return false; #elif defined(USE_OZONE) - return client_native_pixmap_factory_->IsConfigurationSupported(format, usage); + return ui::OzonePlatform::EnsureInstance()->IsNativePixmapConfigSupported( + format, usage); #elif defined(OS_LINUX) return false; // TODO(julian.isorce): Add linux support. #elif defined(OS_WIN)
diff --git a/gpu/ipc/common/gpu_memory_buffer_support.h b/gpu/ipc/common/gpu_memory_buffer_support.h index aaddd9e..277ffd5a 100644 --- a/gpu/ipc/common/gpu_memory_buffer_support.h +++ b/gpu/ipc/common/gpu_memory_buffer_support.h
@@ -28,10 +28,6 @@ class GPU_EXPORT GpuMemoryBufferSupport { public: GpuMemoryBufferSupport(); -#if defined(OS_LINUX) || defined(USE_OZONE) - GpuMemoryBufferSupport(std::unique_ptr<gfx::ClientNativePixmapFactory> - client_native_pixmap_factory); -#endif ~GpuMemoryBufferSupport(); // Returns the native GPU memory buffer factory type. Returns EMPTY_BUFFER
diff --git a/ios/chrome/browser/ui/fullscreen/fullscreen_features.mm b/ios/chrome/browser/ui/fullscreen/fullscreen_features.mm index a4c7424b..247e7f1 100644 --- a/ios/chrome/browser/ui/fullscreen/fullscreen_features.mm +++ b/ios/chrome/browser/ui/fullscreen/fullscreen_features.mm
@@ -5,6 +5,7 @@ #import "ios/chrome/browser/ui/fullscreen/fullscreen_features.h" #include "base/command_line.h" +#include "base/feature_list.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -18,6 +19,11 @@ const char kSafeAreaChoiceValue[] = "safe-area"; const char kHybridChoiceValue[] = "hybrid"; const char kSmoothScrollingChoiceValue[] = "smooth"; + +// Feature used by finch config to enable smooth scrolling when the default +// viewport adjustment experiment is selected via command line switches. +const base::Feature kSmoothScrollingDefault{"FullscreenSmoothScrollingDefault", + base::FEATURE_ENABLED_BY_DEFAULT}; } namespace fullscreen { @@ -55,7 +61,9 @@ if (viewport_experiment == std::string(kFrameChoiceValue)) return ViewportAdjustmentExperiment::FRAME; } - return ViewportAdjustmentExperiment::SMOOTH_SCROLLING; + return base::FeatureList::IsEnabled(kSmoothScrollingDefault) + ? ViewportAdjustmentExperiment::SMOOTH_SCROLLING + : ViewportAdjustmentExperiment::FRAME; } } // namespace features
diff --git a/ios/web/download/download_task_impl.h b/ios/web/download/download_task_impl.h index 427f769..2c40468 100644 --- a/ios/web/download/download_task_impl.h +++ b/ios/web/download/download_task_impl.h
@@ -69,6 +69,7 @@ int64_t GetReceivedBytes() const override; int GetPercentComplete() const override; std::string GetContentDisposition() const override; + std::string GetOriginalMimeType() const override; std::string GetMimeType() const override; ui::PageTransition GetTransitionType() const override; base::string16 GetSuggestedFilename() const override; @@ -122,6 +123,7 @@ int64_t received_bytes_ = 0; int percent_complete_ = -1; std::string content_disposition_; + std::string original_mime_type_; std::string mime_type_; ui::PageTransition page_transition_ = ui::PAGE_TRANSITION_LINK; NSString* identifier_ = nil;
diff --git a/ios/web/download/download_task_impl.mm b/ios/web/download/download_task_impl.mm index 55dc87a1..f34ad4f 100644 --- a/ios/web/download/download_task_impl.mm +++ b/ios/web/download/download_task_impl.mm
@@ -172,6 +172,7 @@ : original_url_(original_url), total_bytes_(total_bytes), content_disposition_(content_disposition), + original_mime_type_(mime_type), mime_type_(mime_type), page_transition_(page_transition), identifier_([identifier copy]), @@ -292,6 +293,11 @@ return content_disposition_; } +std::string DownloadTaskImpl::GetOriginalMimeType() const { + DCHECK_CURRENTLY_ON(web::WebThread::UI); + return original_mime_type_; +} + std::string DownloadTaskImpl::GetMimeType() const { DCHECK_CURRENTLY_ON(web::WebThread::UI); return mime_type_;
diff --git a/ios/web/download/download_task_impl_unittest.mm b/ios/web/download/download_task_impl_unittest.mm index be044e2..450c074a 100644 --- a/ios/web/download/download_task_impl_unittest.mm +++ b/ios/web/download/download_task_impl_unittest.mm
@@ -238,6 +238,7 @@ EXPECT_EQ(-1, task_->GetPercentComplete()); EXPECT_EQ(kContentDisposition, task_->GetContentDisposition()); EXPECT_EQ(kMimeType, task_->GetMimeType()); + EXPECT_EQ(kMimeType, task_->GetOriginalMimeType()); EXPECT_TRUE(ui::PageTransitionTypeIncludingQualifiersIs( task_->GetTransitionType(), ui::PageTransition::PAGE_TRANSITION_TYPED)); EXPECT_EQ("file.test", base::UTF16ToUTF8(task_->GetSuggestedFilename())); @@ -623,7 +624,7 @@ ASSERT_TRUE(session_task); testing::Mock::VerifyAndClearExpectations(&task_observer_); - // Download has finished with a different MIME type. + ASSERT_EQ(kMimeType, task_->GetOriginalMimeType()); ASSERT_EQ(kMimeType, task_->GetMimeType()); EXPECT_CALL(task_observer_, OnDownloadUpdated(task_.get())); const char kOtherMimeType[] = "application/foo"; @@ -637,6 +638,7 @@ ASSERT_TRUE(WaitUntilConditionOrTimeout(kWaitForDownloadTimeout, ^{ return task_->IsDone(); })); + EXPECT_EQ(kMimeType, task_->GetOriginalMimeType()); EXPECT_EQ(kOtherMimeType, task_->GetMimeType()); EXPECT_CALL(task_delegate_, OnTaskDestroyed(task_.get())); @@ -649,8 +651,6 @@ ASSERT_TRUE(session_task); testing::Mock::VerifyAndClearExpectations(&task_observer_); - // Download has finished with a different MIME type. - ASSERT_EQ(kMimeType, task_->GetMimeType()); EXPECT_CALL(task_observer_, OnDownloadUpdated(task_.get())); int kHttpCode = 303; session_task.response =
diff --git a/ios/web/public/download/download_task.h b/ios/web/public/download/download_task.h index 189a419..423054a 100644 --- a/ios/web/public/download/download_task.h +++ b/ios/web/public/download/download_task.h
@@ -93,6 +93,9 @@ // Content-Disposition header value from HTTP response. virtual std::string GetContentDisposition() const = 0; + // MIME type that the download request originally attempted to fetch. + virtual std::string GetOriginalMimeType() const = 0; + // Effective MIME type of downloaded content. virtual std::string GetMimeType() const = 0;
diff --git a/ios/web/public/test/fakes/fake_download_task.h b/ios/web/public/test/fakes/fake_download_task.h index ce86e43..d9daae5 100644 --- a/ios/web/public/test/fakes/fake_download_task.h +++ b/ios/web/public/test/fakes/fake_download_task.h
@@ -34,6 +34,7 @@ int64_t GetReceivedBytes() const override; int GetPercentComplete() const override; std::string GetContentDisposition() const override; + std::string GetOriginalMimeType() const override; std::string GetMimeType() const override; ui::PageTransition GetTransitionType() const override; base::string16 GetSuggestedFilename() const override; @@ -69,6 +70,7 @@ int64_t total_bytes_ = -1; int64_t received_bytes_ = 0; int percent_complete_ = -1; + std::string original_mime_type_; std::string mime_type_; ui::PageTransition page_transition_ = ui::PAGE_TRANSITION_LINK; base::string16 suggested_file_name_;
diff --git a/ios/web/public/test/fakes/fake_download_task.mm b/ios/web/public/test/fakes/fake_download_task.mm index e54bffd0..33784f9 100644 --- a/ios/web/public/test/fakes/fake_download_task.mm +++ b/ios/web/public/test/fakes/fake_download_task.mm
@@ -15,7 +15,10 @@ FakeDownloadTask::FakeDownloadTask(const GURL& original_url, const std::string& mime_type) - : original_url_(original_url), mime_type_(mime_type), identifier_(@"") {} + : original_url_(original_url), + original_mime_type_(mime_type), + mime_type_(mime_type), + identifier_(@"") {} FakeDownloadTask::~FakeDownloadTask() { for (auto& observer : observers_) @@ -78,6 +81,10 @@ return content_disposition_; } +std::string FakeDownloadTask::GetOriginalMimeType() const { + return original_mime_type_; +} + std::string FakeDownloadTask::GetMimeType() const { return mime_type_; }
diff --git a/media/audio/BUILD.gn b/media/audio/BUILD.gn index 5f44a7f9..38e7bb1 100644 --- a/media/audio/BUILD.gn +++ b/media/audio/BUILD.gn
@@ -4,18 +4,42 @@ import("//build/config/linux/pkg_config.gni") import("//media/media_options.gni") -import("//tools/generate_stubs/rules.gni") # When libpulse is not directly linked, use stubs to allow for dlopening of the # binary. -if (use_pulseaudio && !link_pulseaudio) { - generate_stubs("libpulse_stubs") { +if (!link_pulseaudio) { + action("pulse_generate_stubs") { extra_header = "pulse/pulse_stub_header.fragment" - sigs = [ "pulse/pulse.sigs" ] - output_name = "pulse/pulse_stubs" - deps = [ - "//base", + + script = "../../tools/generate_stubs/generate_stubs.py" + sources = [ + "pulse/pulse.sigs", ] + inputs = [ + extra_header, + ] + stubs_filename_root = "pulse_stubs" + + outputs = [ + "$target_gen_dir/pulse/$stubs_filename_root.cc", + "$target_gen_dir/pulse/$stubs_filename_root.h", + ] + args = [ + "-i", + rebase_path("$target_gen_dir/pulse", root_build_dir), + "-o", + rebase_path("$target_gen_dir/pulse", root_build_dir), + "-t", + "posix_stubs", + "-e", + rebase_path(extra_header, root_build_dir), + "-s", + stubs_filename_root, + "-p", + "media/audio/pulse", + ] + + args += rebase_path(sources, root_build_dir) } } @@ -282,7 +306,9 @@ if (link_pulseaudio) { configs += [ ":libpulse" ] } else { - deps += [ ":libpulse_stubs" ] + libs += [ "dl" ] + deps += [ ":pulse_generate_stubs" ] + sources += get_target_outputs(":pulse_generate_stubs") } }
diff --git a/media/gpu/BUILD.gn b/media/gpu/BUILD.gn index 076a911..ac8e8c7 100644 --- a/media/gpu/BUILD.gn +++ b/media/gpu/BUILD.gn
@@ -8,7 +8,6 @@ import("//media/gpu/args.gni") import("//media/media_options.gni") import("//testing/test.gni") -import("//tools/generate_stubs/rules.gni") buildflag_header("buildflags") { header = "buildflags.h" @@ -25,13 +24,38 @@ } if (is_chromeos && use_v4lplugin) { - generate_stubs("libv4l2_stubs") { + action("libv4l2_generate_stubs") { extra_header = "v4l2/v4l2_stub_header.fragment" - sigs = [ "v4l2/v4l2.sig" ] - output_name = "v4l2_stubs" - deps = [ - "//base", + + script = "../../tools/generate_stubs/generate_stubs.py" + sources = [ + "v4l2/v4l2.sig", ] + inputs = [ + extra_header, + ] + stubs_filename_root = "v4l2_stubs" + + outputs = [ + "$target_gen_dir/v4l2/$stubs_filename_root.cc", + "$target_gen_dir/v4l2/$stubs_filename_root.h", + ] + args = [ + "-i", + rebase_path("$target_gen_dir/v4l2", root_build_dir), + "-o", + rebase_path("$target_gen_dir/v4l2", root_build_dir), + "-t", + "posix_stubs", + "-e", + rebase_path(extra_header, root_build_dir), + "-s", + stubs_filename_root, + "-p", + "media/gpu/v4l2", + ] + + args += rebase_path(sources, root_build_dir) } } @@ -192,7 +216,8 @@ } if (use_v4lplugin) { - deps += [ ":libv4l2_stubs" ] + sources += get_target_outputs(":libv4l2_generate_stubs") + deps += [ ":libv4l2_generate_stubs" ] } if (use_v4l2_codec) {
diff --git a/media/gpu/v4l2/v4l2_device.cc b/media/gpu/v4l2/v4l2_device.cc index 544f747..7296f0c 100644 --- a/media/gpu/v4l2/v4l2_device.cc +++ b/media/gpu/v4l2/v4l2_device.cc
@@ -855,6 +855,7 @@ return PIXEL_FORMAT_I420; case V4L2_PIX_FMT_YVU420: + case V4L2_PIX_FMT_YVU420M: return PIXEL_FORMAT_YV12; case V4L2_PIX_FMT_YUV422M: @@ -870,20 +871,18 @@ } // static -uint32_t V4L2Device::VideoPixelFormatToV4L2PixFmt(VideoPixelFormat format) { +uint32_t V4L2Device::VideoPixelFormatToV4L2PixFmt(const VideoPixelFormat format, + bool single_planar) { switch (format) { case PIXEL_FORMAT_NV12: - return V4L2_PIX_FMT_NV12M; - + return single_planar ? V4L2_PIX_FMT_NV12 : V4L2_PIX_FMT_NV12M; case PIXEL_FORMAT_MT21: - return V4L2_PIX_FMT_MT21C; - + // No single plane format for MT21. + return single_planar ? 0 : V4L2_PIX_FMT_MT21C; case PIXEL_FORMAT_I420: - return V4L2_PIX_FMT_YUV420M; - + return single_planar ? V4L2_PIX_FMT_YUV420 : V4L2_PIX_FMT_YUV420M; case PIXEL_FORMAT_YV12: - return V4L2_PIX_FMT_YVU420; - + return single_planar ? V4L2_PIX_FMT_YVU420 : V4L2_PIX_FMT_YVU420M; default: LOG(FATAL) << "Add more cases as needed"; return 0; @@ -891,6 +890,17 @@ } // static +uint32_t V4L2Device::VideoFrameLayoutToV4L2PixFmt( + const VideoFrameLayout& layout) { + if (layout.num_buffers() == 0) { + VLOGF(1) << "layout.num_buffers() must be more than 0: " << layout; + return 0; + } + return VideoPixelFormatToV4L2PixFmt(layout.format(), + layout.num_buffers() == 1); +} + +// static uint32_t V4L2Device::VideoCodecProfileToV4L2PixFmt(VideoCodecProfile profile, bool slice_based) { if (profile >= H264PROFILE_MIN && profile <= H264PROFILE_MAX) { @@ -1298,6 +1308,18 @@ std::move(buffer_sizes), buffer_alignment); } +// static +bool V4L2Device::IsMultiPlanarV4L2PixFmt(uint32_t pix_fmt) { + constexpr uint32_t kMultiV4L2PixFmts[] = { + V4L2_PIX_FMT_NV12M, + V4L2_PIX_FMT_MT21C, + V4L2_PIX_FMT_YUV420M, + V4L2_PIX_FMT_YVU420M, + }; + return std::find(std::cbegin(kMultiV4L2PixFmts), std::cend(kMultiV4L2PixFmts), + pix_fmt) != std::cend(kMultiV4L2PixFmts); +} + void V4L2Device::GetSupportedResolution(uint32_t pixelformat, gfx::Size* min_resolution, gfx::Size* max_resolution) {
diff --git a/media/gpu/v4l2/v4l2_device.h b/media/gpu/v4l2/v4l2_device.h index 33bcc88..5b8b3e5 100644 --- a/media/gpu/v4l2/v4l2_device.h +++ b/media/gpu/v4l2/v4l2_device.h
@@ -287,7 +287,12 @@ public: // Utility format conversion functions static VideoPixelFormat V4L2PixFmtToVideoPixelFormat(uint32_t format); - static uint32_t VideoPixelFormatToV4L2PixFmt(VideoPixelFormat format); + static uint32_t VideoPixelFormatToV4L2PixFmt(VideoPixelFormat format, + bool single_planar); + // Returns v4l2 pixel format from |layout|. If there is no corresponding + // single- or multi-planar format or |layout| is invalid, returns 0. + static uint32_t VideoFrameLayoutToV4L2PixFmt(const VideoFrameLayout& layout); + // If there is no corresponding single- or multi-planar format, returns 0. static uint32_t VideoCodecProfileToV4L2PixFmt(VideoCodecProfile profile, bool slice_based); static VideoCodecProfile V4L2VP9ProfileToVideoCodecProfile(uint32_t profile); @@ -310,6 +315,9 @@ static base::Optional<VideoFrameLayout> V4L2FormatToVideoFrameLayout( const struct v4l2_format& format); + // Returns whether |pix_fmt| is multi planar. + static bool IsMultiPlanarV4L2PixFmt(uint32_t pix_fmt); + enum class Type { kDecoder, kEncoder,
diff --git a/media/gpu/v4l2/v4l2_image_processor.cc b/media/gpu/v4l2/v4l2_image_processor.cc index 3b69f36..cb6f192 100644 --- a/media/gpu/v4l2/v4l2_image_processor.cc +++ b/media/gpu/v4l2/v4l2_image_processor.cc
@@ -186,7 +186,11 @@ return nullptr; } const uint32_t input_format_fourcc = - V4L2Device::VideoPixelFormatToV4L2PixFmt(input_layout.format()); + V4L2Device::VideoFrameLayoutToV4L2PixFmt(input_layout); + if (!input_format_fourcc) { + VLOGF(1) << "Invalid VideoFrameLayout: " << input_layout; + return nullptr; + } if (!device->Open(V4L2Device::Type::kImageProcessor, input_format_fourcc)) { VLOGF(1) << "Failed to open device for input format: " << VideoPixelFormatToString(input_layout.format()) @@ -223,13 +227,19 @@ return nullptr; } + const uint32_t output_format_fourcc = + V4L2Device::VideoFrameLayoutToV4L2PixFmt(output_layout); + if (!output_format_fourcc) { + VLOGF(1) << "Invalid VideoFrameLayout: " << output_layout; + return nullptr; + } + // Try to set output format. memset(&format, 0, sizeof(format)); format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; format.fmt.pix_mp.width = output_layout.coded_size().width(); format.fmt.pix_mp.height = output_layout.coded_size().height(); - format.fmt.pix_mp.pixelformat = - V4L2Device::VideoPixelFormatToV4L2PixFmt(output_layout.format()); + format.fmt.pix_mp.pixelformat = output_format_fourcc; if (device->Ioctl(VIDIOC_S_FMT, &format) != 0) { VLOGF(1) << "Failed to negotiate output format"; return nullptr;
diff --git a/media/gpu/v4l2/v4l2_video_decode_accelerator.cc b/media/gpu/v4l2/v4l2_video_decode_accelerator.cc index ae637e5..e947f42 100644 --- a/media/gpu/v4l2/v4l2_video_decode_accelerator.cc +++ b/media/gpu/v4l2/v4l2_video_decode_accelerator.cc
@@ -68,6 +68,18 @@ namespace media { +namespace { + +size_t GetNumPlanesOfV4L2PixFmt(uint32_t pix_fmt) { + if (V4L2Device::IsMultiPlanarV4L2PixFmt(pix_fmt)) { + return VideoFrame::NumPlanes( + V4L2Device::V4L2PixFmtToVideoPixelFormat(pix_fmt)); + } + return 1u; +} + +} // namespace + // static const uint32_t V4L2VideoDecodeAccelerator::supported_input_fourccs_[] = { V4L2_PIX_FMT_H264, V4L2_PIX_FMT_VP8, V4L2_PIX_FMT_VP9, @@ -2357,17 +2369,24 @@ (output_mode_ == Config::OutputMode::ALLOCATE ? ImageProcessor::OutputMode::ALLOCATE : ImageProcessor::OutputMode::IMPORT); - - auto input_layout = VideoFrameLayout::Create( + size_t num_planes = GetNumPlanesOfV4L2PixFmt(output_format_fourcc_); + // It is necessary to set strides and buffers even with dummy values, + // because VideoFrameLayout::num_buffers() specifies if + // |output_format_fourcc_| is single- or multi-planar. + auto input_layout = VideoFrameLayout::CreateWithStrides( V4L2Device::V4L2PixFmtToVideoPixelFormat(output_format_fourcc_), - coded_size_); + coded_size_, std::vector<int32_t>(num_planes) /* strides */, + std::vector<size_t>(num_planes) /* buffers */); if (!input_layout) { VLOGF(1) << "Invalid input layout"; return false; } - auto output_layout = VideoFrameLayout::Create( + + num_planes = GetNumPlanesOfV4L2PixFmt(egl_image_format_fourcc_); + auto output_layout = VideoFrameLayout::CreateWithStrides( V4L2Device::V4L2PixFmtToVideoPixelFormat(egl_image_format_fourcc_), - egl_image_size_); + egl_image_size_, std::vector<int32_t>(num_planes) /* strides */, + std::vector<size_t>(num_planes) /* buffers */); if (!output_layout) { VLOGF(1) << "Invalid output layout"; return false;
diff --git a/media/gpu/v4l2/v4l2_video_encode_accelerator.cc b/media/gpu/v4l2/v4l2_video_encode_accelerator.cc index d1fd481..98ffc5c 100644 --- a/media/gpu/v4l2/v4l2_video_encode_accelerator.cc +++ b/media/gpu/v4l2/v4l2_video_encode_accelerator.cc
@@ -210,14 +210,25 @@ return false; } - auto input_layout = - VideoFrameLayout::Create(config.input_format, visible_size_); + // It is necessary to set strides and buffers even with dummy values, + // because VideoFrameLayout::num_buffers() specifies v4l2 pix format + // associated with |config.input_format| is multi-planar. + auto input_layout = VideoFrameLayout::CreateWithStrides( + config.input_format, visible_size_, + std::vector<int32_t>( + VideoFrameLayout::NumPlanes(config.input_format)) /* strides */, + std::vector<size_t>( + VideoFrameLayout::NumPlanes(config.input_format)) /* buffers */); if (!input_layout) { VLOGF(1) << "Invalid image processor input layout"; return false; } - auto output_layout = - VideoFrameLayout::Create(device_input_format_, input_allocated_size_); + auto output_layout = VideoFrameLayout::CreateWithStrides( + device_input_format_, input_allocated_size_, + std::vector<int32_t>( + VideoFrameLayout::NumPlanes(device_input_format_)) /* strides */, + std::vector<size_t>( + VideoFrameLayout::NumPlanes(device_input_format_)) /* buffers */); if (!output_layout) { VLOGF(1) << "Invalid image processor output layout"; return false; @@ -1115,62 +1126,49 @@ device_input_format_ = PIXEL_FORMAT_UNKNOWN; input_planes_count_ = 0; - uint32_t input_format_fourcc = - V4L2Device::VideoPixelFormatToV4L2PixFmt(input_format); - if (!input_format_fourcc) { - VLOGF(1) << "Unsupported input format" << input_format_fourcc; - return false; - } + const std::vector<uint32_t> pix_fmt_candidates = { + // First see if the device can use the provided format directly. + // V4L2 VEA only supports multi plane input pixel format. + V4L2Device::VideoPixelFormatToV4L2PixFmt(input_format, false), + // Second try preferred input format. + device_->PreferredInputFormat(V4L2Device::Type::kEncoder), + }; - size_t input_planes_count = VideoFrame::NumPlanes(input_format); - DCHECK_LE(input_planes_count, static_cast<size_t>(VIDEO_MAX_PLANES)); + for (const auto pix_fmt : pix_fmt_candidates) { + auto trying_format = V4L2Device::V4L2PixFmtToVideoPixelFormat(pix_fmt); + DCHECK_NE(trying_format, PIXEL_FORMAT_UNKNOWN); + size_t planes_count = VideoFrame::NumPlanes(trying_format); + DCHECK_LE(planes_count, static_cast<size_t>(VIDEO_MAX_PLANES)); + VLOGF(2) << "Trying S_FMT with " << FourccToString(pix_fmt) << " (" + << trying_format << ")."; - // First see if we the device can use the provided input_format directly. - struct v4l2_format format; - memset(&format, 0, sizeof(format)); - format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - format.fmt.pix_mp.width = visible_size_.width(); - format.fmt.pix_mp.height = visible_size_.height(); - format.fmt.pix_mp.pixelformat = input_format_fourcc; - format.fmt.pix_mp.num_planes = input_planes_count; - if (device_->Ioctl(VIDIOC_S_FMT, &format) != 0) { - // Error or format unsupported by device, try to negotiate a fallback. - input_format_fourcc = - device_->PreferredInputFormat(V4L2Device::Type::kEncoder); - input_format = - V4L2Device::V4L2PixFmtToVideoPixelFormat(input_format_fourcc); - if (input_format == PIXEL_FORMAT_UNKNOWN) { - VLOGF(1) << "Unsupported input format: " - << FourccToString(input_format_fourcc); - return false; - } - - input_planes_count = VideoFrame::NumPlanes(input_format); - DCHECK_LE(input_planes_count, static_cast<size_t>(VIDEO_MAX_PLANES)); - - // Device might have adjusted parameters, reset them along with the format. + struct v4l2_format format; memset(&format, 0, sizeof(format)); format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; format.fmt.pix_mp.width = visible_size_.width(); format.fmt.pix_mp.height = visible_size_.height(); - format.fmt.pix_mp.pixelformat = input_format_fourcc; - format.fmt.pix_mp.num_planes = input_planes_count; - IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_S_FMT, &format); - DCHECK_EQ(format.fmt.pix_mp.num_planes, input_planes_count); + format.fmt.pix_mp.pixelformat = pix_fmt; + format.fmt.pix_mp.num_planes = planes_count; + if (device_->Ioctl(VIDIOC_S_FMT, &format) == 0) { + VLOGF(2) << "Success: S_FMT with" << FourccToString(pix_fmt); + // Take device-adjusted sizes for allocated size. If the size is adjusted + // down, it means the input is too big and the hardware does not support + // it. + auto adjusted_size = V4L2Device::CodedSizeFromV4L2Format(format); + if (!gfx::Rect(adjusted_size).Contains(gfx::Rect(visible_size_))) { + VLOGF(1) << "Input size too big " << visible_size_.ToString() + << ", adjusted to " << adjusted_size.ToString(); + return false; + } + + device_input_format_ = trying_format; + input_planes_count_ = planes_count; + input_allocated_size_ = adjusted_size; + return true; + } } - // Take device-adjusted sizes for allocated size. If the size is adjusted - // down, it means the input is too big and the hardware does not support it. - input_allocated_size_ = V4L2Device::CodedSizeFromV4L2Format(format); - if (!gfx::Rect(input_allocated_size_).Contains(gfx::Rect(visible_size_))) { - VLOGF(1) << "Input size too big " << visible_size_.ToString() - << ", adjusted to " << input_allocated_size_.ToString(); - return false; - } - - device_input_format_ = input_format; - input_planes_count_ = input_planes_count; - return true; + return false; } bool V4L2VideoEncodeAccelerator::SetFormats(VideoPixelFormat input_format,
diff --git a/media/gpu/vaapi/BUILD.gn b/media/gpu/vaapi/BUILD.gn index 679f629..df1051eb 100644 --- a/media/gpu/vaapi/BUILD.gn +++ b/media/gpu/vaapi/BUILD.gn
@@ -5,25 +5,49 @@ import("//build/config/features.gni") import("//build/config/ui.gni") import("//media/gpu/args.gni") -import("//tools/generate_stubs/rules.gni") import("//ui/gl/features.gni") import("//ui/ozone/ozone.gni") assert(use_vaapi) -generate_stubs("libva_stubs") { +action("libva_generate_stubs") { extra_header = "va_stub_header.fragment" - sigs = [ "va.sigs" ] + + script = "//tools/generate_stubs/generate_stubs.py" + sources = [ + "va.sigs", + ] + inputs = [ + extra_header, + ] if (use_x11) { - sigs += [ "va_x11.sigs" ] + sources += [ "va_x11.sigs" ] } if (is_linux) { - sigs += [ "va_drm.sigs" ] + sources += [ "va_drm.sigs" ] } - output_name = "va_stubs" - deps = [ - "//base", + stubs_filename_root = "va_stubs" + + outputs = [ + "$target_gen_dir/$stubs_filename_root.cc", + "$target_gen_dir/$stubs_filename_root.h", ] + args = [ + "-i", + rebase_path("$target_gen_dir", root_build_dir), + "-o", + rebase_path("$target_gen_dir", root_build_dir), + "-t", + "posix_stubs", + "-e", + rebase_path(extra_header, root_build_dir), + "-s", + stubs_filename_root, + "-p", + "media/gpu/vaapi", + ] + + args += rebase_path(sources, root_build_dir) } source_set("vaapi") { @@ -64,11 +88,12 @@ "vp8_encoder.cc", "vp8_encoder.h", ] + sources += get_target_outputs(":libva_generate_stubs") configs += [ "//third_party/libyuv:libyuv_config" ] deps = [ - ":libva_stubs", + ":libva_generate_stubs", "//gpu/ipc/service", "//media", "//media/gpu:common",
diff --git a/media/gpu/vp9_decoder.cc b/media/gpu/vp9_decoder.cc index 5b8e183..a16c6a9 100644 --- a/media/gpu/vp9_decoder.cc +++ b/media/gpu/vp9_decoder.cc
@@ -92,7 +92,10 @@ // Not kDecoding, so we need a resume point (a keyframe), as we are after // reset or at the beginning of the stream. Drop anything that is not // a keyframe in such case, and continue looking for a keyframe. - if (curr_frame_hdr_->IsKeyframe()) { + // Only exception is when the stream/sequence starts with an Intra only + // frame. + if (curr_frame_hdr_->IsKeyframe() || + (curr_frame_hdr_->IsIntra() && pic_size_.IsEmpty())) { state_ = kDecoding; } else { curr_frame_hdr_.reset(); @@ -136,11 +139,14 @@ if (new_pic_size != pic_size_) { DVLOG(1) << "New resolution: " << new_pic_size.ToString(); - if (!curr_frame_hdr_->IsKeyframe()) { + if (!curr_frame_hdr_->IsKeyframe() && + (curr_frame_hdr_->IsIntra() && pic_size_.IsEmpty())) { // TODO(posciak): This is doable, but requires a few modifications to // VDA implementations to allow multiple picture buffer sets in flight. // http://crbug.com/832264 - DVLOG(1) << "Resolution change currently supported for keyframes only"; + DVLOG(1) << "Resolution change currently supported for keyframes and " + "sequence begins with Intra only when there is no prior " + "frames in the context"; if (++size_change_failure_counter_ > kVPxMaxNumOfSizeChangeFailures) { SetError(); return kDecodeError;
diff --git a/net/data/fuzzer_dictionaries/net_http_server_fuzzer.dict b/net/data/fuzzer_dictionaries/net_http_server_fuzzer.dict index 89aea18..d28bae852 100644 --- a/net/data/fuzzer_dictionaries/net_http_server_fuzzer.dict +++ b/net/data/fuzzer_dictionaries/net_http_server_fuzzer.dict
@@ -46,6 +46,6 @@ # String terminator for FuzzedDataProvider::ConsumeRandomLengthString. "\\ " -# There is a lot of use of ConsumeUint32InRange clients, like ConsumeBool, +# There is a lot of use of ConsumeIntegralInRange clients, like ConsumeBool, # so try make it easy to produce lots of inputs for these. "\x00\x00\x00\x00"
diff --git a/net/dns/fuzzed_host_resolver.cc b/net/dns/fuzzed_host_resolver.cc index 8290c82a..587afd5 100644 --- a/net/dns/fuzzed_host_resolver.cc +++ b/net/dns/fuzzed_host_resolver.cc
@@ -168,14 +168,14 @@ DnsConfig config; // Fuzz name servers. - uint32_t num_nameservers = data_provider_->ConsumeUint32InRange(0, 4); + uint32_t num_nameservers = data_provider_->ConsumeIntegralInRange(0, 4); for (uint32_t i = 0; i < num_nameservers; ++i) { config.nameservers.push_back( IPEndPoint(FuzzIPAddress(data_provider_), FuzzPort(data_provider_))); } // Fuzz suffix search list. - switch (data_provider_->ConsumeUint32InRange(0, 3)) { + switch (data_provider_->ConsumeIntegralInRange(0, 3)) { case 3: config.search.push_back("foo.com"); FALLTHROUGH; @@ -204,8 +204,8 @@ config.unhandled_options = data_provider_->ConsumeBool(); config.append_to_multi_label_name = data_provider_->ConsumeBool(); config.randomize_ports = data_provider_->ConsumeBool(); - config.ndots = data_provider_->ConsumeInt32InRange(0, 3); - config.attempts = data_provider_->ConsumeInt32InRange(1, 3); + config.ndots = data_provider_->ConsumeIntegralInRange(0, 3); + config.attempts = data_provider_->ConsumeIntegralInRange(1, 3); // Timeouts don't really work for fuzzing. Even a timeout of 0 milliseconds // will be increased after the first timeout, resulting in inconsistent @@ -218,7 +218,7 @@ std::unique_ptr<DnsClient> dns_client = DnsClient::CreateClientForTesting( net_log_, &socket_factory_, - base::Bind(&base::FuzzedDataProvider::ConsumeInt32InRange, + base::Bind(&base::FuzzedDataProvider::ConsumeIntegralInRange<int32_t>, base::Unretained(data_provider_))); dns_client->SetConfig(config); SetDnsClient(std::move(dns_client));
diff --git a/net/dns/host_resolver_impl_fuzzer.cc b/net/dns/host_resolver_impl_fuzzer.cc index 06c87e7..2718106a 100644 --- a/net/dns/host_resolver_impl_fuzzer.cc +++ b/net/dns/host_resolver_impl_fuzzer.cc
@@ -64,8 +64,8 @@ std::vector<std::unique_ptr<DnsRequest>>* dns_requests) { if (dns_requests->empty()) return; - uint32_t index = - data_provider->ConsumeUint32InRange(0, dns_requests->size() - 1); + uint32_t index = data_provider->ConsumeIntegralInRange<uint32_t>( + 0, dns_requests->size() - 1); // Remove the request from the list before waiting on it - this prevents one // of the other callbacks from deleting the callback being waited on. @@ -83,8 +83,8 @@ std::vector<std::unique_ptr<DnsRequest>>* dns_requests) { if (dns_requests->empty()) return; - uint32_t index = - data_provider->ConsumeUint32InRange(0, dns_requests->size() - 1); + uint32_t index = data_provider->ConsumeIntegralInRange<uint32_t>( + 0, dns_requests->size() - 1); auto request = dns_requests->begin() + index; (*request)->Cancel(); dns_requests->erase(request); @@ -112,7 +112,7 @@ while (true) { bool done = false; - switch (data_provider_->ConsumeInt32InRange(0, 2)) { + switch (data_provider_->ConsumeIntegralInRange(0, 2)) { case 0: // Quit on 0, or when no data is left. done = true; @@ -141,9 +141,9 @@ if (data_provider_->ConsumeBool()) info.set_host_resolver_flags(net::HOST_RESOLVER_CANONNAME); - net::RequestPriority priority = - static_cast<net::RequestPriority>(data_provider_->ConsumeInt32InRange( - net::MINIMUM_PRIORITY, net::MAXIMUM_PRIORITY)); + net::RequestPriority priority = static_cast<net::RequestPriority>( + data_provider_->ConsumeIntegralInRange<int32_t>(net::MINIMUM_PRIORITY, + net::MAXIMUM_PRIORITY)); // Decide if should be a cache-only resolution. if (data_provider_->ConsumeBool()) { @@ -206,7 +206,8 @@ net::TestNetLog net_log; net::HostResolver::Options options; - options.max_concurrent_resolves = data_provider.ConsumeUint32InRange(1, 8); + options.max_concurrent_resolves = + data_provider.ConsumeIntegralInRange(1, 8); options.enable_caching = data_provider.ConsumeBool(); net::FuzzedHostResolver host_resolver(options, &net_log, &data_provider); host_resolver.SetDnsClientEnabled(data_provider.ConsumeBool()); @@ -214,7 +215,7 @@ std::vector<std::unique_ptr<DnsRequest>> dns_requests; bool done = false; while (!done) { - switch (data_provider.ConsumeInt32InRange(0, 3)) { + switch (data_provider.ConsumeIntegralInRange(0, 3)) { case 0: // Quit on 0, or when no data is left. done = true;
diff --git a/net/filter/fuzzed_source_stream.cc b/net/filter/fuzzed_source_stream.cc index 108d134..3d8e037 100644 --- a/net/filter/fuzzed_source_stream.cc +++ b/net/filter/fuzzed_source_stream.cc
@@ -40,7 +40,7 @@ DCHECK_LE(0, buf_len); bool sync = data_provider_->ConsumeBool(); - int result = data_provider_->ConsumeUint32InRange(0, buf_len); + int result = data_provider_->ConsumeIntegralInRange(0, buf_len); std::string data = data_provider_->ConsumeBytesAsString(result); result = data.size();
diff --git a/net/ntlm/ntlm_client_fuzzer.cc b/net/ntlm/ntlm_client_fuzzer.cc index 6be44099..e553ff3 100644 --- a/net/ntlm/ntlm_client_fuzzer.cc +++ b/net/ntlm/ntlm_client_fuzzer.cc
@@ -24,9 +24,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { base::FuzzedDataProvider fdp(data, size); bool is_v2 = fdp.ConsumeBool(); - uint64_t client_time = - (static_cast<uint64_t>(fdp.ConsumeUint32InRange(0, 0xffffffffu)) << 32) | - static_cast<uint64_t>(fdp.ConsumeUint32InRange(0, 0xffffffffu)); + uint64_t client_time = fdp.ConsumeUint64(); net::ntlm::NtlmClient client((net::ntlm::NtlmFeatures(is_v2))); // Generate the input strings and challenge message. The strings will have a
diff --git a/net/socket/fuzzed_datagram_client_socket.cc b/net/socket/fuzzed_datagram_client_socket.cc index 5dec51e..852bb1c 100644 --- a/net/socket/fuzzed_datagram_client_socket.cc +++ b/net/socket/fuzzed_datagram_client_socket.cc
@@ -140,7 +140,7 @@ // Get contents of response. std::string data = data_provider_->ConsumeRandomLengthString( - data_provider_->ConsumeUint32InRange(0, buf_len)); + data_provider_->ConsumeIntegralInRange(0, buf_len)); int result; if (data.size() > 0) {
diff --git a/net/socket/socks_client_socket_fuzzer.cc b/net/socket/socks_client_socket_fuzzer.cc index feaa182..cd44a023 100644 --- a/net/socket/socks_client_socket_fuzzer.cc +++ b/net/socket/socks_client_socket_fuzzer.cc
@@ -36,7 +36,7 @@ scoped_refptr<net::RuleBasedHostResolverProc> rules( new net::RuleBasedHostResolverProc(nullptr)); mock_host_resolver.set_synchronous_mode(data_provider.ConsumeBool()); - switch (data_provider.ConsumeInt32InRange(0, 2)) { + switch (data_provider.ConsumeIntegralInRange(0, 2)) { case 0: rules->AddRule("*", "127.0.0.1"); break;
diff --git a/net/third_party/http2/decoder/http2_frame_decoder_fuzzer.cc b/net/third_party/http2/decoder/http2_frame_decoder_fuzzer.cc index 27cb94c..7e8942e 100644 --- a/net/third_party/http2/decoder/http2_frame_decoder_fuzzer.cc +++ b/net/third_party/http2/decoder/http2_frame_decoder_fuzzer.cc
@@ -15,7 +15,7 @@ base::FuzzedDataProvider fuzzed_data_provider(data, size); http2::Http2FrameDecoder decoder; while (fuzzed_data_provider.remaining_bytes() > 0) { - size_t chunk_size = fuzzed_data_provider.ConsumeUint32InRange(1, 32); + size_t chunk_size = fuzzed_data_provider.ConsumeIntegralInRange(1, 32); std::vector<char> chunk = fuzzed_data_provider.ConsumeBytes<char>(chunk_size);
diff --git a/net/third_party/http2/hpack/decoder/hpack_decoder_fuzzer.cc b/net/third_party/http2/hpack/decoder/hpack_decoder_fuzzer.cc index e10f21d..2e1c09e 100644 --- a/net/third_party/http2/hpack/decoder/hpack_decoder_fuzzer.cc +++ b/net/third_party/http2/hpack/decoder/hpack_decoder_fuzzer.cc
@@ -18,12 +18,12 @@ base::FuzzedDataProvider fuzzed_data_provider(data, size); size_t max_string_size = - fuzzed_data_provider.ConsumeUint32InRange(1, 10 * size); + fuzzed_data_provider.ConsumeIntegralInRange<size_t>(1, 10 * size); http2::HpackDecoder decoder(http2::HpackDecoderNoOpListener::NoOpListener(), max_string_size); decoder.StartDecodingBlock(); while (fuzzed_data_provider.remaining_bytes() > 0) { - size_t chunk_size = fuzzed_data_provider.ConsumeUint32InRange(1, 32); + size_t chunk_size = fuzzed_data_provider.ConsumeIntegralInRange(1, 32); std::vector<char> chunk = fuzzed_data_provider.ConsumeBytes<char>(chunk_size);
diff --git a/net/third_party/quic/core/qpack/fuzzer/qpack_decoder_fuzzer.cc b/net/third_party/quic/core/qpack/fuzzer/qpack_decoder_fuzzer.cc index d10a561..2485805 100644 --- a/net/third_party/quic/core/qpack/fuzzer/qpack_decoder_fuzzer.cc +++ b/net/third_party/quic/core/qpack/fuzzer/qpack_decoder_fuzzer.cc
@@ -38,8 +38,9 @@ // Process up to 64 kB fragments at a time. Too small upper bound might not // provide enough coverage, too large would make fuzzing less efficient. - auto fragment_size_generator = std::bind( - &QuicFuzzedDataProvider::ConsumeUint32InRange, &provider, 1, 64 * 1024); + auto fragment_size_generator = + std::bind(&QuicFuzzedDataProvider::ConsumeIntegralInRange<uint32_t>, + &provider, 1, 64 * 1024); QpackDecode( &handler, fragment_size_generator,
diff --git a/net/third_party/quic/core/qpack/fuzzer/qpack_round_trip_fuzzer.cc b/net/third_party/quic/core/qpack/fuzzer/qpack_round_trip_fuzzer.cc index b39aede..3fe9de8 100644 --- a/net/third_party/quic/core/qpack/fuzzer/qpack_round_trip_fuzzer.cc +++ b/net/third_party/quic/core/qpack/fuzzer/qpack_round_trip_fuzzer.cc
@@ -119,8 +119,9 @@ // Process up to 64 kB fragments at a time. Too small upper bound might not // provide enough coverage, too large would make fuzzing less efficient. - auto fragment_size_generator = std::bind( - &QuicFuzzedDataProvider::ConsumeUint32InRange, &provider, 1, 64 * 1024); + auto fragment_size_generator = + std::bind(&QuicFuzzedDataProvider::ConsumeIntegralInRange<uint32_t>, + &provider, 1, 64 * 1024); // Encode header list. QuicString encoded_header_block =
diff --git a/net/url_request/url_request_data_job_fuzzer.cc b/net/url_request/url_request_data_job_fuzzer.cc index f83a94a..29d0ddb 100644 --- a/net/url_request/url_request_data_job_fuzzer.cc +++ b/net/url_request/url_request_data_job_fuzzer.cc
@@ -47,7 +47,7 @@ read_lengths_.clear(); // Allocate an IOBuffer with fuzzed size. - int buf_size = provider.ConsumeUint32InRange(1, 127); // 7 bits. + int buf_size = provider.ConsumeIntegralInRange(1, 127); // 7 bits. buf_ = base::MakeRefCounted<net::IOBufferWithSize>(buf_size); // Generate a range header, and a bool determining whether to use it. @@ -63,7 +63,7 @@ size_t simulated_bytes_read = 0; while (simulated_bytes_read < provider.remaining_bytes() && read_lengths_.size() < 20000u) { - size_t read_length = provider.ConsumeUint32InRange(1, buf_size); + size_t read_length = provider.ConsumeIntegralInRange(1, buf_size); read_lengths_.push_back(read_length); simulated_bytes_read += read_length; }
diff --git a/net/websockets/websocket_deflate_stream_fuzzer.cc b/net/websockets/websocket_deflate_stream_fuzzer.cc index 712804c..a3432ea2 100644 --- a/net/websockets/websocket_deflate_stream_fuzzer.cc +++ b/net/websockets/websocket_deflate_stream_fuzzer.cc
@@ -67,9 +67,10 @@ private: std::unique_ptr<WebSocketFrame> CreateFrame() { WebSocketFrameHeader::OpCode opcode = - fuzzed_data_provider_->ConsumeUint32InRange( - WebSocketFrameHeader::kOpCodeContinuation, - WebSocketFrameHeader::kOpCodeControlUnused); + fuzzed_data_provider_ + ->ConsumeIntegralInRange<WebSocketFrameHeader::OpCode>( + WebSocketFrameHeader::kOpCodeContinuation, + WebSocketFrameHeader::kOpCodeControlUnused); auto frame = std::make_unique<WebSocketFrame>(opcode); // Bad news: ConsumeBool actually consumes a whole byte per call, so do // something hacky to conserve precious bits. @@ -80,7 +81,7 @@ frame->header.reserved3 = (flags >> 3) & 0x1; frame->header.masked = (flags >> 4) & 0x1; uint64_t payload_length = - fuzzed_data_provider_->ConsumeUint32InRange(0, 64); + fuzzed_data_provider_->ConsumeIntegralInRange(0, 64); std::vector<char> payload = fuzzed_data_provider_->ConsumeBytes<char>(payload_length); frame->data = base::MakeRefCounted<IOBufferWithSize>(payload.size());
diff --git a/net/websockets/websocket_frame_parser_fuzzer.cc b/net/websockets/websocket_frame_parser_fuzzer.cc index 112a8db3..90c5d92bc 100644 --- a/net/websockets/websocket_frame_parser_fuzzer.cc +++ b/net/websockets/websocket_frame_parser_fuzzer.cc
@@ -16,7 +16,7 @@ net::WebSocketFrameParser parser; std::vector<std::unique_ptr<net::WebSocketFrameChunk>> frame_chunks; while (fuzzed_data_provider.remaining_bytes() > 0) { - size_t chunk_size = fuzzed_data_provider.ConsumeUint32InRange(1, 32); + size_t chunk_size = fuzzed_data_provider.ConsumeIntegralInRange(1, 32); std::vector<char> chunk = fuzzed_data_provider.ConsumeBytes<char>(chunk_size); parser.Decode(chunk.data(), chunk.size(), &frame_chunks);
diff --git a/services/network/network_service_proxy_delegate.cc b/services/network/network_service_proxy_delegate.cc index a1345bb..d377290f 100644 --- a/services/network/network_service_proxy_delegate.cc +++ b/services/network/network_service_proxy_delegate.cc
@@ -102,7 +102,12 @@ mojom::CustomProxyConfigClientRequest config_client_request) : proxy_config_(std::move(initial_config)), binding_(this, std::move(config_client_request)), - should_use_alternate_proxy_list_cache_(kMaxCacheSize) {} + should_use_alternate_proxy_list_cache_(kMaxCacheSize) { + // Make sure there is always a valid proxy config so we don't need to null + // check it. + if (!proxy_config_) + proxy_config_ = mojom::CustomProxyConfig::New(); +} void NetworkServiceProxyDelegate::OnBeforeStartTransaction( net::URLRequest* request,
diff --git a/services/network/network_service_proxy_delegate_unittest.cc b/services/network/network_service_proxy_delegate_unittest.cc index 47da01e..4815f44f 100644 --- a/services/network/network_service_proxy_delegate_unittest.cc +++ b/services/network/network_service_proxy_delegate_unittest.cc
@@ -50,6 +50,16 @@ base::test::ScopedTaskEnvironment scoped_task_environment_; }; +TEST_F(NetworkServiceProxyDelegateTest, NullConfigDoesNotCrash) { + mojom::CustomProxyConfigClientPtr client; + auto delegate = std::make_unique<NetworkServiceProxyDelegate>( + nullptr, mojo::MakeRequest(&client)); + + net::HttpRequestHeaders headers; + auto request = CreateRequest(GURL(kHttpUrl)); + delegate->OnBeforeStartTransaction(request.get(), &headers); +} + TEST_F(NetworkServiceProxyDelegateTest, AddsHeadersBeforeCache) { auto config = mojom::CustomProxyConfig::New(); config->rules.ParseFromString("http=proxy");
diff --git a/storage/browser/quota/quota_callbacks.h b/storage/browser/quota/quota_callbacks.h index ac33358..1d4025f 100644 --- a/storage/browser/quota/quota_callbacks.h +++ b/storage/browser/quota/quota_callbacks.h
@@ -14,7 +14,6 @@ #include <vector> #include "base/callback.h" -#include "base/containers/flat_map.h" #include "base/optional.h" #include "base/stl_util.h" #include "storage/browser/quota/quota_client.h" @@ -38,7 +37,7 @@ using UsageCallback = base::OnceCallback<void(int64_t usage)>; using UsageWithBreakdownCallback = base::OnceCallback<void(int64_t usage, - base::flat_map<QuotaClient::ID, int64_t>)>; + blink::mojom::UsageBreakdownPtr usage_breakdown)>; using AvailableSpaceCallback = base::OnceCallback<void(blink::mojom::QuotaStatusCode, int64_t)>; using StatusCallback = base::OnceCallback<void(blink::mojom::QuotaStatusCode)>; @@ -59,9 +58,7 @@ return (callbacks_.size() == 1); } - bool HasCallbacks() const { - return !callbacks_.empty(); - } + bool HasCallbacks() const { return !callbacks_.empty(); } // Runs the callbacks added to the queue and clears the queue. void Run(Args... args) { @@ -75,9 +72,7 @@ callbacks_.swap(other->callbacks_); } - size_t size() const { - return callbacks_.size(); - } + size_t size() const { return callbacks_.size(); } private: std::vector<CallbackType> callbacks_; @@ -98,9 +93,7 @@ return base::ContainsKey(callback_map_, key); } - bool HasAnyCallbacks() const { - return !callback_map_.empty(); - } + bool HasAnyCallbacks() const { return !callback_map_.empty(); } iterator Begin() { return callback_map_.begin(); } iterator End() { return callback_map_.end(); }
diff --git a/storage/browser/quota/quota_manager.cc b/storage/browser/quota/quota_manager.cc index 6384c7e..e46bb60 100644 --- a/storage/browser/quota/quota_manager.cc +++ b/storage/browser/quota/quota_manager.cc
@@ -208,7 +208,7 @@ blink::mojom::QuotaStatusCode status, int64_t usage, int64_t quota, - base::flat_map<QuotaClient::ID, int64_t> usage_breakdown) { + blink::mojom::UsageBreakdownPtr usage_breakdown) { std::move(callback).Run(status, usage, quota); } @@ -273,8 +273,11 @@ void Aborted() override { weak_factory_.InvalidateWeakPtrs(); - std::move(callback_).Run(blink::mojom::QuotaStatusCode::kErrorAbort, 0, 0, - base::flat_map<QuotaClient::ID, int64_t>()); + std::move(callback_).Run( + blink::mojom::QuotaStatusCode::kErrorAbort, /*status*/ + 0, /*usage*/ + 0, /*quota*/ + nullptr); /*usage_breakdown*/ DeleteSoon(); } @@ -327,10 +330,9 @@ barrier_closure.Run(); } - void OnGotHostUsage( - const base::Closure& barrier_closure, - int64_t usage, - base::flat_map<QuotaClient::ID, int64_t> usage_breakdown) { + void OnGotHostUsage(const base::Closure& barrier_closure, + int64_t usage, + blink::mojom::UsageBreakdownPtr usage_breakdown) { host_usage_ = usage; host_usage_breakdown_ = std::move(usage_breakdown); barrier_closure.Run(); @@ -355,7 +357,7 @@ int64_t total_space_ = 0; int64_t desired_host_quota_ = 0; int64_t host_usage_ = 0; - base::flat_map<QuotaClient::ID, int64_t> host_usage_breakdown_; + blink::mojom::UsageBreakdownPtr host_usage_breakdown_; QuotaSettings settings_; base::WeakPtrFactory<UsageAndQuotaHelper> weak_factory_; DISALLOW_COPY_AND_ASSIGN(UsageAndQuotaHelper); @@ -866,8 +868,11 @@ UsageAndQuotaWithBreakdownCallback callback) { if (!IsSupportedType(type) || (is_incognito_ && !IsSupportedIncognitoType(type))) { - std::move(callback).Run(blink::mojom::QuotaStatusCode::kErrorNotSupported, - 0, 0, base::flat_map<QuotaClient::ID, int64_t>()); + std::move(callback).Run( + blink::mojom::QuotaStatusCode::kErrorNotSupported, /*status*/ + 0, /*usage*/ + 0, /*quota*/ + nullptr); /*usage_breakdown*/ return; } LazyInitialize();
diff --git a/storage/browser/quota/quota_manager.h b/storage/browser/quota/quota_manager.h index 651a759..83e39d2 100644 --- a/storage/browser/quota/quota_manager.h +++ b/storage/browser/quota/quota_manager.h
@@ -17,7 +17,6 @@ #include <vector> #include "base/callback.h" -#include "base/containers/flat_map.h" #include "base/files/file_path.h" #include "base/macros.h" #include "base/memory/ref_counted.h" @@ -38,19 +37,18 @@ class SequencedTaskRunner; class SingleThreadTaskRunner; class TaskRunner; -} +} // namespace base namespace quota_internals { class QuotaInternalsProxy; -} +} // namespace quota_internals namespace content { class MockQuotaManager; class MockStorageClient; class QuotaManagerTest; class StorageMonitorTest; - -} +} // namespace content namespace storage { @@ -112,11 +110,12 @@ public: using UsageAndQuotaCallback = base::OnceCallback< void(blink::mojom::QuotaStatusCode, int64_t usage, int64_t quota)>; - using UsageAndQuotaWithBreakdownCallback = base::OnceCallback<void( - blink::mojom::QuotaStatusCode, - int64_t usage, - int64_t quota, - base::flat_map<QuotaClient::ID, int64_t> usage_breakdown)>; + + using UsageAndQuotaWithBreakdownCallback = + base::OnceCallback<void(blink::mojom::QuotaStatusCode, + int64_t usage, + int64_t quota, + blink::mojom::UsageBreakdownPtr usage_breakdown)>; static const int64_t kNoLimit; @@ -140,7 +139,6 @@ virtual void GetUsageAndQuotaForWebApps(const url::Origin& origin, blink::mojom::StorageType type, UsageAndQuotaCallback callback); - // Called by DevTools. // This method is declared as virtual to allow test code to override it. virtual void GetUsageAndQuotaWithBreakdown(
diff --git a/storage/browser/quota/quota_manager_unittest.cc b/storage/browser/quota/quota_manager_unittest.cc index 4f505de..4f24ca88 100644 --- a/storage/browser/quota/quota_manager_unittest.cc +++ b/storage/browser/quota/quota_manager_unittest.cc
@@ -76,7 +76,6 @@ url::Origin ToOrigin(const std::string& url) { return url::Origin::Create(GURL(url)); } - } // namespace class QuotaManagerTest : public testing::Test { @@ -152,7 +151,7 @@ quota_status_ = QuotaStatusCode::kUnknown; usage_ = -1; quota_ = -1; - usage_breakdown_.clear(); + usage_breakdown_ = nullptr; quota_manager_->GetUsageAndQuotaWithBreakdown( origin, type, base::BindOnce(&QuotaManagerTest::DidGetUsageAndQuotaWithBreakdown, @@ -361,7 +360,7 @@ QuotaStatusCode status, int64_t usage, int64_t quota, - base::flat_map<QuotaClient::ID, int64_t> usage_breakdown) { + blink::mojom::UsageBreakdownPtr usage_breakdown) { quota_status_ = status; usage_ = usage; quota_ = quota; @@ -397,7 +396,7 @@ void DidGetHostUsageBreakdown( int64_t usage, - base::flat_map<QuotaClient::ID, int64_t> usage_breakdown) { + blink::mojom::UsageBreakdownPtr usage_breakdown) { usage_ = usage; usage_breakdown_ = std::move(usage_breakdown); } @@ -456,8 +455,8 @@ QuotaStatusCode status() const { return quota_status_; } const UsageInfoEntries& usage_info() const { return usage_info_; } int64_t usage() const { return usage_; } - const base::flat_map<QuotaClient::ID, int64_t>& usage_breakdown() const { - return usage_breakdown_; + const blink::mojom::UsageBreakdown& usage_breakdown() const { + return *usage_breakdown_; } int64_t limited_usage() const { return limited_usage_; } int64_t unlimited_usage() const { return unlimited_usage_; } @@ -497,7 +496,7 @@ QuotaStatusCode quota_status_; UsageInfoEntries usage_info_; int64_t usage_; - base::flat_map<QuotaClient::ID, int64_t> usage_breakdown_; + blink::mojom::UsageBreakdownPtr usage_breakdown_; int64_t limited_usage_; int64_t unlimited_usage_; int64_t quota_; @@ -741,7 +740,8 @@ } TEST_F(QuotaManagerTest, GetUsageWithBreakdown_Simple) { - base::flat_map<QuotaClient::ID, int64_t> usage_breakdown_expected; + blink::mojom::UsageBreakdown usage_breakdown_expected = + blink::mojom::UsageBreakdown(); static const MockOriginData kData1[] = { {"http://foo.com/", kTemp, 1}, {"http://foo.com/", kPerm, 80}, }; @@ -765,58 +765,60 @@ scoped_task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(80, usage()); - usage_breakdown_expected[QuotaClient::kFileSystem] = 80; - usage_breakdown_expected[QuotaClient::kDatabase] = 0; - usage_breakdown_expected[QuotaClient::kAppcache] = 0; - EXPECT_EQ(usage_breakdown_expected, usage_breakdown()); + usage_breakdown_expected.fileSystem = 80; + usage_breakdown_expected.webSql = 0; + usage_breakdown_expected.appcache = 0; + EXPECT_TRUE(usage_breakdown_expected.Equals(usage_breakdown())); GetUsageAndQuotaWithBreakdown(ToOrigin("http://foo.com/"), kTemp); scoped_task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(1 + 4 + 8, usage()); - usage_breakdown_expected[QuotaClient::kFileSystem] = 1; - usage_breakdown_expected[QuotaClient::kDatabase] = 4; - usage_breakdown_expected[QuotaClient::kAppcache] = 8; - EXPECT_EQ(usage_breakdown_expected, usage_breakdown()); + usage_breakdown_expected.fileSystem = 1; + usage_breakdown_expected.webSql = 4; + usage_breakdown_expected.appcache = 8; + EXPECT_TRUE(usage_breakdown_expected.Equals(usage_breakdown())); GetUsageAndQuotaWithBreakdown(ToOrigin("http://bar.com/"), kTemp); scoped_task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(0, usage()); - usage_breakdown_expected[QuotaClient::kFileSystem] = 0; - usage_breakdown_expected[QuotaClient::kDatabase] = 0; - usage_breakdown_expected[QuotaClient::kAppcache] = 0; - EXPECT_EQ(usage_breakdown_expected, usage_breakdown()); + usage_breakdown_expected.fileSystem = 0; + usage_breakdown_expected.webSql = 0; + usage_breakdown_expected.appcache = 0; + EXPECT_TRUE(usage_breakdown_expected.Equals(usage_breakdown())); } TEST_F(QuotaManagerTest, GetUsageWithBreakdown_NoClient) { - base::flat_map<QuotaClient::ID, int64_t> usage_breakdown_expected; + blink::mojom::UsageBreakdown usage_breakdown_expected = + blink::mojom::UsageBreakdown(); GetUsageAndQuotaWithBreakdown(ToOrigin("http://foo.com/"), kTemp); scoped_task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(0, usage()); - EXPECT_EQ(usage_breakdown_expected, usage_breakdown()); + EXPECT_TRUE(usage_breakdown_expected.Equals(usage_breakdown())); GetUsageAndQuotaWithBreakdown(ToOrigin("http://foo.com/"), kPerm); scoped_task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(0, usage()); - EXPECT_EQ(usage_breakdown_expected, usage_breakdown()); + EXPECT_TRUE(usage_breakdown_expected.Equals(usage_breakdown())); GetHostUsageBreakdown("foo.com", kTemp); scoped_task_environment_.RunUntilIdle(); EXPECT_EQ(0, usage()); - EXPECT_EQ(usage_breakdown_expected, usage_breakdown()); + EXPECT_TRUE(usage_breakdown_expected.Equals(usage_breakdown())); GetHostUsageBreakdown("foo.com", kPerm); scoped_task_environment_.RunUntilIdle(); EXPECT_EQ(0, usage()); - EXPECT_EQ(usage_breakdown_expected, usage_breakdown()); + EXPECT_TRUE(usage_breakdown_expected.Equals(usage_breakdown())); } TEST_F(QuotaManagerTest, GetUsageWithBreakdown_MultiOrigins) { - base::flat_map<QuotaClient::ID, int64_t> usage_breakdown_expected; + blink::mojom::UsageBreakdown usage_breakdown_expected = + blink::mojom::UsageBreakdown(); static const MockOriginData kData[] = { {"http://foo.com/", kTemp, 10}, {"http://foo.com:8080/", kTemp, 20}, {"http://bar.com/", kTemp, 5}, {"https://bar.com/", kTemp, 7}, @@ -829,19 +831,20 @@ scoped_task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(10 + 20, usage()); - usage_breakdown_expected[QuotaClient::kFileSystem] = 10 + 20; - EXPECT_EQ(usage_breakdown_expected, usage_breakdown()); + usage_breakdown_expected.fileSystem = 10 + 20; + EXPECT_TRUE(usage_breakdown_expected.Equals(usage_breakdown())); GetUsageAndQuotaWithBreakdown(ToOrigin("http://bar.com/"), kTemp); scoped_task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(5 + 7, usage()); - usage_breakdown_expected[QuotaClient::kFileSystem] = 5 + 7; - EXPECT_EQ(usage_breakdown_expected, usage_breakdown()); + usage_breakdown_expected.fileSystem = 5 + 7; + EXPECT_TRUE(usage_breakdown_expected.Equals(usage_breakdown())); } TEST_F(QuotaManagerTest, GetUsageWithBreakdown_MultipleClients) { - base::flat_map<QuotaClient::ID, int64_t> usage_breakdown_expected; + blink::mojom::UsageBreakdown usage_breakdown_expected = + blink::mojom::UsageBreakdown(); static const MockOriginData kData1[] = { {"http://foo.com/", kTemp, 1}, {"http://bar.com/", kTemp, 2}, @@ -863,33 +866,33 @@ scoped_task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(1 + 128, usage()); - usage_breakdown_expected[QuotaClient::kFileSystem] = 1; - usage_breakdown_expected[QuotaClient::kDatabase] = 128; - EXPECT_EQ(usage_breakdown_expected, usage_breakdown()); + usage_breakdown_expected.fileSystem = 1; + usage_breakdown_expected.webSql = 128; + EXPECT_TRUE(usage_breakdown_expected.Equals(usage_breakdown())); GetUsageAndQuotaWithBreakdown(ToOrigin("http://bar.com/"), kPerm); scoped_task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(4, usage()); - usage_breakdown_expected[QuotaClient::kFileSystem] = 4; - usage_breakdown_expected[QuotaClient::kDatabase] = 0; - EXPECT_EQ(usage_breakdown_expected, usage_breakdown()); + usage_breakdown_expected.fileSystem = 4; + usage_breakdown_expected.webSql = 0; + EXPECT_TRUE(usage_breakdown_expected.Equals(usage_breakdown())); GetUsageAndQuotaWithBreakdown(ToOrigin("http://unlimited/"), kTemp); scoped_task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(512, usage()); - usage_breakdown_expected[QuotaClient::kFileSystem] = 0; - usage_breakdown_expected[QuotaClient::kDatabase] = 512; - EXPECT_EQ(usage_breakdown_expected, usage_breakdown()); + usage_breakdown_expected.fileSystem = 0; + usage_breakdown_expected.webSql = 512; + EXPECT_TRUE(usage_breakdown_expected.Equals(usage_breakdown())); GetUsageAndQuotaWithBreakdown(ToOrigin("http://unlimited/"), kPerm); scoped_task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(8, usage()); - usage_breakdown_expected[QuotaClient::kFileSystem] = 8; - usage_breakdown_expected[QuotaClient::kDatabase] = 0; - EXPECT_EQ(usage_breakdown_expected, usage_breakdown()); + usage_breakdown_expected.fileSystem = 8; + usage_breakdown_expected.webSql = 0; + EXPECT_TRUE(usage_breakdown_expected.Equals(usage_breakdown())); } void QuotaManagerTest::GetUsage_WithModifyTestBody(const StorageType type) {
diff --git a/storage/browser/quota/usage_tracker.cc b/storage/browser/quota/usage_tracker.cc index 8a0bb17..85a4072 100644 --- a/storage/browser/quota/usage_tracker.cc +++ b/storage/browser/quota/usage_tracker.cc
@@ -27,7 +27,7 @@ void StripUsageWithBreakdownCallback( UsageCallback callback, int64_t usage, - base::flat_map<QuotaClient::ID, int64_t> usage_breakdown) { + blink::mojom::UsageBreakdownPtr usage_breakdown) { std::move(callback).Run(usage); } @@ -245,7 +245,35 @@ if (info->usage < 0) info->usage = 0; - info->usage_breakdown[client] += usage; + switch (client) { + case QuotaClient::kUnknown: + break; + case QuotaClient::kFileSystem: + info->usage_breakdown->fileSystem += usage; + break; + case QuotaClient::kDatabase: + info->usage_breakdown->webSql += usage; + break; + case QuotaClient::kAppcache: + info->usage_breakdown->appcache += usage; + break; + case QuotaClient::kIndexedDatabase: + info->usage_breakdown->indexedDatabase += usage; + break; + case QuotaClient::kServiceWorkerCache: + info->usage_breakdown->serviceWorkerCache += usage; + break; + case QuotaClient::kServiceWorker: + info->usage_breakdown->serviceWorker += usage; + break; + case QuotaClient::kBackgroundFetch: + info->usage_breakdown->backgroundFetch += usage; + break; + case QuotaClient::kAllClientsMask: + NOTREACHED(); + break; + } + barrier.Run(); } @@ -261,8 +289,9 @@ << "host_usage_callbacks_ should only have non-empty callback lists"; host_usage_callbacks_.erase(host_it); - for (auto& callback : pending_callbacks) - std::move(callback).Run(info->usage, info->usage_breakdown); + for (auto& callback : pending_callbacks) { + std::move(callback).Run(info->usage, info->usage_breakdown->Clone()); + } } } // namespace storage
diff --git a/storage/browser/quota/usage_tracker.h b/storage/browser/quota/usage_tracker.h index 93a4f1e8..9bbd6c699 100644 --- a/storage/browser/quota/usage_tracker.h +++ b/storage/browser/quota/usage_tracker.h
@@ -14,7 +14,6 @@ #include <vector> #include "base/callback.h" -#include "base/containers/flat_map.h" #include "base/macros.h" #include "storage/browser/quota/quota_callbacks.h" #include "storage/browser/quota/quota_client.h" @@ -71,7 +70,8 @@ int pending_clients = 0; int64_t usage = 0; int64_t unlimited_usage = 0; - base::flat_map<QuotaClient::ID, int64_t> usage_breakdown; + blink::mojom::UsageBreakdownPtr usage_breakdown = + blink::mojom::UsageBreakdown::New(); }; friend class ClientUsageTracker;
diff --git a/storage/browser/quota/usage_tracker_unittest.cc b/storage/browser/quota/usage_tracker_unittest.cc index 4bb6162..dbb4897 100644 --- a/storage/browser/quota/usage_tracker_unittest.cc +++ b/storage/browser/quota/usage_tracker_unittest.cc
@@ -45,18 +45,6 @@ *usage_out = usage; } -void DidGetUsageBreakdown( - bool* done, - int64_t* usage_out, - base::flat_map<QuotaClient::ID, int64_t>* usage_breakdown_out, - int64_t usage, - base::flat_map<QuotaClient::ID, int64_t> usage_breakdown) { - EXPECT_FALSE(*done); - *done = true; - *usage_out = usage; - *usage_breakdown_out = usage_breakdown; -} - } // namespace class MockQuotaClient : public QuotaClient { @@ -149,6 +137,18 @@ return &usage_tracker_; } + static void DidGetUsageBreakdown( + bool* done, + int64_t* usage_out, + blink::mojom::UsageBreakdownPtr* usage_breakdown_out, + int64_t usage, + blink::mojom::UsageBreakdownPtr usage_breakdown) { + EXPECT_FALSE(*done); + *usage_out = usage; + *usage_breakdown_out = std::move(usage_breakdown); + *done = true; + } + void UpdateUsage(const url::Origin& origin, int64_t delta) { quota_client_.UpdateUsage(origin, delta); usage_tracker_.UpdateUsageCache(quota_client_.id(), origin, delta); @@ -187,17 +187,18 @@ EXPECT_TRUE(done); } - void GetHostUsageBreakdown( - const std::string& host, - int64_t* usage, - base::flat_map<QuotaClient::ID, int64_t>* usage_breakdown) { + std::pair<int64_t, blink::mojom::UsageBreakdownPtr> GetHostUsageBreakdown( + const std::string& host) { + int64_t usage; + blink::mojom::UsageBreakdownPtr usage_breakdown; bool done = false; - usage_tracker_.GetHostUsageWithBreakdown( - host, - base::BindOnce(&DidGetUsageBreakdown, &done, usage, usage_breakdown)); - base::RunLoop().RunUntilIdle(); + usage_tracker_.GetHostUsageWithBreakdown( + host, base::BindOnce(&UsageTrackerTest::DidGetUsageBreakdown, &done, + &usage, &usage_breakdown)); + base::RunLoop().RunUntilIdle(); EXPECT_TRUE(done); + return std::make_pair(usage, std::move(usage_breakdown)); } void GrantUnlimitedStoragePolicy(const url::Origin& origin) { @@ -241,8 +242,8 @@ int64_t usage = 0; int64_t unlimited_usage = 0; int64_t host_usage = 0; - base::flat_map<QuotaClient::ID, int64_t> host_usage_breakdown; - base::flat_map<QuotaClient::ID, int64_t> host_usage_breakdown_expected; + blink::mojom::UsageBreakdownPtr host_usage_breakdown_expected = + blink::mojom::UsageBreakdown::New(); GetGlobalUsage(&usage, &unlimited_usage); EXPECT_EQ(0, usage); EXPECT_EQ(0, unlimited_usage); @@ -257,9 +258,10 @@ EXPECT_EQ(100, usage); EXPECT_EQ(0, unlimited_usage); EXPECT_EQ(100, host_usage); - host_usage_breakdown_expected[QuotaClient::kFileSystem] = 100; - GetHostUsageBreakdown(host, &host_usage, &host_usage_breakdown); - EXPECT_EQ(host_usage_breakdown_expected, host_usage_breakdown); + host_usage_breakdown_expected->fileSystem = 100; + std::pair<int64_t, blink::mojom::UsageBreakdownPtr> host_usage_breakdown = + GetHostUsageBreakdown(host); + EXPECT_EQ(host_usage_breakdown_expected, host_usage_breakdown.second); GrantUnlimitedStoragePolicy(origin); GetGlobalUsage(&usage, &unlimited_usage); @@ -267,8 +269,8 @@ EXPECT_EQ(100, usage); EXPECT_EQ(100, unlimited_usage); EXPECT_EQ(100, host_usage); - GetHostUsageBreakdown(host, &host_usage, &host_usage_breakdown); - EXPECT_EQ(host_usage_breakdown_expected, host_usage_breakdown); + host_usage_breakdown = GetHostUsageBreakdown(host); + EXPECT_EQ(host_usage_breakdown_expected, host_usage_breakdown.second); RevokeUnlimitedStoragePolicy(origin); GetGlobalUsage(&usage, &unlimited_usage); @@ -276,16 +278,16 @@ EXPECT_EQ(100, usage); EXPECT_EQ(0, unlimited_usage); EXPECT_EQ(100, host_usage); - GetHostUsageBreakdown(host, &host_usage, &host_usage_breakdown); - EXPECT_EQ(host_usage_breakdown_expected, host_usage_breakdown); + GetHostUsageBreakdown(host); + EXPECT_EQ(host_usage_breakdown_expected, host_usage_breakdown.second); } TEST_F(UsageTrackerTest, CacheDisabledClientTest) { int64_t usage = 0; int64_t unlimited_usage = 0; int64_t host_usage = 0; - base::flat_map<QuotaClient::ID, int64_t> host_usage_breakdown; - base::flat_map<QuotaClient::ID, int64_t> host_usage_breakdown_expected; + blink::mojom::UsageBreakdownPtr host_usage_breakdown_expected = + blink::mojom::UsageBreakdown::New(); const url::Origin origin = url::Origin::Create(GURL("http://example.com")); const std::string host(net::GetHostOrSpecFromURL(origin.GetURL())); @@ -296,9 +298,10 @@ EXPECT_EQ(100, usage); EXPECT_EQ(0, unlimited_usage); EXPECT_EQ(100, host_usage); - host_usage_breakdown_expected[QuotaClient::kFileSystem] = 100; - GetHostUsageBreakdown(host, &host_usage, &host_usage_breakdown); - EXPECT_EQ(host_usage_breakdown_expected, host_usage_breakdown); + host_usage_breakdown_expected->fileSystem = 100; + std::pair<int64_t, blink::mojom::UsageBreakdownPtr> host_usage_breakdown = + GetHostUsageBreakdown(host); + EXPECT_EQ(host_usage_breakdown_expected, host_usage_breakdown.second); UpdateUsageWithoutNotification(origin, 100); GetGlobalUsage(&usage, &unlimited_usage); @@ -306,8 +309,8 @@ EXPECT_EQ(100, usage); EXPECT_EQ(0, unlimited_usage); EXPECT_EQ(100, host_usage); - GetHostUsageBreakdown(host, &host_usage, &host_usage_breakdown); - EXPECT_EQ(host_usage_breakdown_expected, host_usage_breakdown); + host_usage_breakdown = GetHostUsageBreakdown(host); + EXPECT_EQ(host_usage_breakdown_expected, host_usage_breakdown.second); GrantUnlimitedStoragePolicy(origin); UpdateUsageWithoutNotification(origin, 100); @@ -319,9 +322,9 @@ EXPECT_EQ(400, usage); EXPECT_EQ(400, unlimited_usage); EXPECT_EQ(400, host_usage); - GetHostUsageBreakdown(host, &host_usage, &host_usage_breakdown); - host_usage_breakdown_expected[QuotaClient::kFileSystem] = 400; - EXPECT_EQ(host_usage_breakdown_expected, host_usage_breakdown); + host_usage_breakdown = GetHostUsageBreakdown(host); + host_usage_breakdown_expected->fileSystem = 400; + EXPECT_EQ(host_usage_breakdown_expected, host_usage_breakdown.second); RevokeUnlimitedStoragePolicy(origin); GetGlobalUsage(&usage, &unlimited_usage); @@ -329,8 +332,8 @@ EXPECT_EQ(400, usage); EXPECT_EQ(0, unlimited_usage); EXPECT_EQ(400, host_usage); - GetHostUsageBreakdown(host, &host_usage, &host_usage_breakdown); - EXPECT_EQ(host_usage_breakdown_expected, host_usage_breakdown); + host_usage_breakdown = GetHostUsageBreakdown(host); + EXPECT_EQ(host_usage_breakdown_expected, host_usage_breakdown.second); SetUsageCacheEnabled(origin, true); UpdateUsage(origin, 100); @@ -340,9 +343,9 @@ EXPECT_EQ(500, usage); EXPECT_EQ(0, unlimited_usage); EXPECT_EQ(500, host_usage); - GetHostUsageBreakdown(host, &host_usage, &host_usage_breakdown); - host_usage_breakdown_expected[QuotaClient::kFileSystem] = 500; - EXPECT_EQ(host_usage_breakdown_expected, host_usage_breakdown); + host_usage_breakdown = GetHostUsageBreakdown(host); + host_usage_breakdown_expected->fileSystem = 500; + EXPECT_EQ(host_usage_breakdown_expected, host_usage_breakdown.second); } TEST_F(UsageTrackerTest, LimitedGlobalUsageTest) {
diff --git a/storage/browser/test/mock_quota_manager.h b/storage/browser/test/mock_quota_manager.h index 0c106ae7..f196ab1 100644 --- a/storage/browser/test/mock_quota_manager.h +++ b/storage/browser/test/mock_quota_manager.h
@@ -125,6 +125,7 @@ ~StorageInfo(); int64_t usage; int64_t quota; + blink::mojom::UsageBreakdownPtr usage_breakdown; }; // This must be called via MockQuotaManagerProxy.
diff --git a/third_party/analytics/OWNERS b/third_party/analytics/OWNERS deleted file mode 100644 index b7a2985..0000000 --- a/third_party/analytics/OWNERS +++ /dev/null
@@ -1 +0,0 @@ -smckay@chromium.org
diff --git a/third_party/analytics/README.chromium b/third_party/analytics/README.chromium deleted file mode 100644 index 27806bc..0000000 --- a/third_party/analytics/README.chromium +++ /dev/null
@@ -1,22 +0,0 @@ -Name: Chrome Platform Analytics -URL: https://github.com/GoogleChrome/chrome-platform-analytics -Version: 1.6.0c -Date: 3/24/2015 -License: Apache 2.0 -License File: NOT_SHIPPED -Security Critical: yes - -Description: -This package supports the use of Google Analytics (GA) in Chrome Platform -Applications and Extensions. - -The library is available from GitHub both as closure JS source and as a -"compiled" bundle (traditional JS). The bundle is included here so that -traditional JS apps (non-closure-compiled) can employ the library. - -The SHA1 hash for this version of GoogleChrome/chrome-platform-analytics is -472ed678a2322e9a18b10eadb5adba2cde68529a. - -Local Modifications: -Added externs.js allowing apps that do use closure compiler to compile code -referencing this library.
diff --git a/third_party/analytics/externs.js b/third_party/analytics/externs.js deleted file mode 100644 index d4bcce9..0000000 --- a/third_party/analytics/externs.js +++ /dev/null
@@ -1,281 +0,0 @@ -// Copyright (c) 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -var goog = {}; -goog.async = {}; - -/** - * @constructor - * @template VALUE - */ -goog.async.Deferred; - -/** - * @param {!function(this:T,VALUE):?} cb - * @param {T=} opt_scope - * @return {!goog.async.Deferred} - * @template T - */ -goog.async.Deferred.prototype.addCallback; - -/** @param {VALUE=} opt_result */ -goog.async.Deferred.prototype.callback; - -/** - * @param {?(function(this:THIS, VALUE): - * (RESULT|IThenable<RESULT>|Thenable))=} opt_onFulfilled - * @param {?(function(this:THIS, *): *)=} opt_onRejected - * @param {THIS=} opt_context - * @return {!Promise<RESULT>} - * @template RESULT,THIS - */ -goog.async.Deferred.prototype.then; - -var analytics = {}; - -/** @typedef {string} */ -analytics.HitType; - -/** @enum {analytics.HitType} */ -analytics.HitTypes = { - APPVIEW: 'appview', - EVENT: 'event', - SOCIAL: 'social', - TRANSACTION: 'transaction', - ITEM: 'item', - TIMING: 'timing', - EXCEPTION: 'exception' -}; - -/** - * @typedef {{ - * id: string, - * name: string, - * valueType: analytics.ValueType, - * maxLength: (number|undefined), - * defaultValue: (string|undefined) - * }} - */ -analytics.Parameter; - -/** @typedef {string|number|boolean} */ -analytics.Value; - -/** @typedef {string} */ -analytics.ValueType; - - -/** - * @param {string} appName - * @param {string=} opt_appVersion - * @return {!analytics.GoogleAnalytics} - */ -analytics.getService; - - -/** @interface */ -analytics.GoogleAnalytics; - -/** - * @param {string} trackingId - * @return {!analytics.Tracker} - */ -analytics.GoogleAnalytics.prototype.getTracker; - -/** @return {!goog.async.Deferred.<!analytics.Config>} */ -analytics.GoogleAnalytics.prototype.getConfig; - - -/** @interface */ -analytics.Tracker; - -/** @typedef {function(!analytics.Tracker.Hit)} */ -analytics.Tracker.Filter; - -/** - * @param {!analytics.HitType|!analytics.EventBuilder} hitType - * @param {(!analytics.ParameterMap| - * !Object.<string, !analytics.Value>)=} opt_extraParams - * @return {!goog.async.Deferred} - */ -analytics.Tracker.prototype.send; - -/** - * @param {string} description - * @return {!goog.async.Deferred} - */ -analytics.Tracker.prototype.sendAppView; - -/** - * @param {string} category - * @param {string} action - * @param {string=} opt_label - * @param {number=} opt_value - * @return {!goog.async.Deferred} - */ -analytics.Tracker.prototype.sendEvent; - -/** - * @param {string} network Specifies the social network, for example Facebook - * or Google Plus. - * @param {string} action Specifies the social interaction action. - * For example on Google Plus when a user clicks the +1 button, - * the social action is 'plus'. - * @param {string} target Specifies the target of a social interaction. - * This value is typically a URL but can be any text. - * @return {!goog.async.Deferred} - */ -analytics.Tracker.prototype.sendSocial; - -/** - * @param {string=} opt_description Specifies the description of an exception. - * @param {boolean=} opt_fatal Was the exception fatal. - * @return {!goog.async.Deferred} - */ -analytics.Tracker.prototype.sendException; - -/** - * @param {string} category Specifies the category of the timing. - * @param {string} variable Specifies the variable name of the timing. - * @param {number} value Specifies the value of the timing. - * @param {string=} opt_label Specifies the optional label of the timing. - * @param {number=} opt_sampleRate - * @return {!goog.async.Deferred} - */ -analytics.Tracker.prototype.sendTiming; - -analytics.Tracker.prototype.forceSessionStart; - -/** - * @param {string} category - * @param {string} variable - * @param {string=} opt_label - * @param {number=} opt_sampleRate - * @return {!analytics.Tracker.Timing} - */ -analytics.Tracker.prototype.startTiming; - -/** @interface */ -analytics.Tracker.Timing; - -/** @return {!goog.async.Deferred} */ -analytics.Tracker.Timing.prototype.send; - -/** @param {!analytics.Tracker.Filter} filter */ -analytics.Tracker.prototype.addFilter; - -/** @interface */ -analytics.Tracker.Hit; - -/** @return {!analytics.HitType} */ -analytics.Tracker.Hit.prototype.getHitType; - -/** @return {!analytics.ParameterMap} */ -analytics.Tracker.Hit.prototype.getParameters; - -analytics.Tracker.Hit.prototype.cancel; - - -/** @interface */ -analytics.Config = function() {}; - -/** @param {boolean} permitted */ -analytics.Config.prototype.setTrackingPermitted; - -/** @return {boolean} */ -analytics.Config.prototype.isTrackingPermitted; - -/** @param {number} sampleRate */ -analytics.Config.prototype.setSampleRate; - -/** @return {!goog.async.Deferred} Settles once the id has been reset. */ -analytics.Config.prototype.resetUserId; - - -/** @interface */ -analytics.ParameterMap; - -/** - * @typedef {{ - * key: !analytics.Parameter, - * value: !analytics.Value - * }} - */ -analytics.ParameterMap.Entry; - -/** - * @param {!analytics.Parameter} param - * @param {!analytics.Value} value - */ -analytics.ParameterMap.prototype.set; - -/** - * @param {!analytics.Parameter} param - * @return {?analytics.Value} - */ -analytics.ParameterMap.prototype.get; - -/** @param {!analytics.Parameter} param */ -analytics.ParameterMap.prototype.remove; - -/** @return {!Object.<string, analytics.Value>} */ -analytics.ParameterMap.prototype.toObject; - - -/** @interface */ -analytics.EventBuilder; - -/** @typedef {{ index: number, value: string }} */ -analytics.EventBuilder.Dimension; - -/** @typedef {{ index: number, value: number }} */ -analytics.EventBuilder.Metric; - -/** @return {!analytics.EventBuilder} */ -analytics.EventBuilder.builder; - -/** - * @param {string} category - * @return {!analytics.EventBuilder} - */ -analytics.EventBuilder.prototype.category; - -/** - * @param {string} action - * @return {!analytics.EventBuilder} - */ -analytics.EventBuilder.prototype.action; - -/** - * @param {string} label - * @return {!analytics.EventBuilder} - */ -analytics.EventBuilder.prototype.label; - -/** - * @param {number} value - * @return {!analytics.EventBuilder} - */ -analytics.EventBuilder.prototype.value; - -/** - * @param {!analytics.EventBuilder.Dimension} dimension - * @return {!analytics.EventBuilder} - */ -analytics.EventBuilder.prototype.dimension; - -/** - * @param {!analytics.EventBuilder.Metric} metric - * @return {!analytics.EventBuilder} - */ -analytics.EventBuilder.prototype.metric; - -/** - * @param {!analytics.Tracker} tracker - * @return {!goog.async.Deferred} - */ -analytics.EventBuilder.prototype.send; - -/** @param {!analytics.ParameterMap} parameters */ -analytics.EventBuilder.prototype.collect;
diff --git a/third_party/analytics/google-analytics-bundle.js b/third_party/analytics/google-analytics-bundle.js deleted file mode 100644 index dd825ac..0000000 --- a/third_party/analytics/google-analytics-bundle.js +++ /dev/null
@@ -1,90 +0,0 @@ -(function() { 'use strict';var h,aa=aa||{},k=this,m=function(a){return void 0!==a},ba=function(){},ca=function(a){var b=typeof a;if("object"==b)if(a){if(a instanceof Array)return"array";if(a instanceof Object)return b;var c=Object.prototype.toString.call(a);if("[object Window]"==c)return"object";if("[object Array]"==c||"number"==typeof a.length&&"undefined"!=typeof a.splice&&"undefined"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable("splice"))return"array";if("[object Function]"==c||"undefined"!=typeof a.call&& -"undefined"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable("call"))return"function"}else return"null";else if("function"==b&&"undefined"==typeof a.call)return"object";return b},n=function(a){return"array"==ca(a)},da=function(a){var b=ca(a);return"array"==b||"object"==b&&"number"==typeof a.length},p=function(a){return"string"==typeof a},ea=function(a){return"number"==typeof a},q=function(a){return"function"==ca(a)},r=function(a){var b=typeof a;return"object"==b&&null!=a||"function"==b},fa= -function(a,b,c){return a.call.apply(a.bind,arguments)},ga=function(a,b,c){if(!a)throw Error();if(2<arguments.length){var d=Array.prototype.slice.call(arguments,2);return function(){var c=Array.prototype.slice.call(arguments);Array.prototype.unshift.apply(c,d);return a.apply(b,c)}}return function(){return a.apply(b,arguments)}},t=function(a,b,c){t=Function.prototype.bind&&-1!=Function.prototype.bind.toString().indexOf("native code")?fa:ga;return t.apply(null,arguments)},ha=function(a,b){var c=Array.prototype.slice.call(arguments, -1);return function(){var b=c.slice();b.push.apply(b,arguments);return a.apply(this,b)}},u=Date.now||function(){return+new Date},v=function(a,b){var c=a.split("."),d=k;c[0]in d||!d.execScript||d.execScript("var "+c[0]);for(var e;c.length&&(e=c.shift());)!c.length&&m(b)?d[e]=b:d=d[e]?d[e]:d[e]={}},w=function(a,b){function c(){}c.prototype=b.prototype;a.P=b.prototype;a.prototype=new c;a.ie=function(a,c,f){for(var g=Array(arguments.length-2),l=2;l<arguments.length;l++)g[l-2]=arguments[l];return b.prototype[c].apply(a, -g)}};Function.prototype.bind=Function.prototype.bind||function(a,b){if(1<arguments.length){var c=Array.prototype.slice.call(arguments,1);c.unshift(this,a);return t.apply(null,c)}return t(this,a)};var x=function(a){if(Error.captureStackTrace)Error.captureStackTrace(this,x);else{var b=Error().stack;b&&(this.stack=b)}a&&(this.message=String(a))};w(x,Error);x.prototype.name="CustomError";var ia=String.prototype.trim?function(a){return a.trim()}:function(a){return a.replace(/^[\s\xa0]+|[\s\xa0]+$/g,"")},ja=function(a,b){return a<b?-1:a>b?1:0};var y=Array.prototype,ka=y.indexOf?function(a,b,c){return y.indexOf.call(a,b,c)}:function(a,b,c){c=null==c?0:0>c?Math.max(0,a.length+c):c;if(p(a))return p(b)&&1==b.length?a.indexOf(b,c):-1;for(;c<a.length;c++)if(c in a&&a[c]===b)return c;return-1},la=y.forEach?function(a,b,c){y.forEach.call(a,b,c)}:function(a,b,c){for(var d=a.length,e=p(a)?a.split(""):a,f=0;f<d;f++)f in e&&b.call(c,e[f],f,a)},ma=y.some?function(a,b,c){return y.some.call(a,b,c)}:function(a,b,c){for(var d=a.length,e=p(a)?a.split(""): -a,f=0;f<d;f++)if(f in e&&b.call(c,e[f],f,a))return!0;return!1},na=y.every?function(a,b,c){return y.every.call(a,b,c)}:function(a,b,c){for(var d=a.length,e=p(a)?a.split(""):a,f=0;f<d;f++)if(f in e&&!b.call(c,e[f],f,a))return!1;return!0},pa=function(a){var b;a:{b=oa;for(var c=a.length,d=p(a)?a.split(""):a,e=0;e<c;e++)if(e in d&&b.call(void 0,d[e],e,a)){b=e;break a}b=-1}return 0>b?null:p(a)?a.charAt(b):a[b]},qa=function(a,b){var c=ka(a,b),d;(d=0<=c)&&y.splice.call(a,c,1);return d},ra=function(a){return y.concat.apply(y, -arguments)},sa=function(a,b,c){return 2>=arguments.length?y.slice.call(a,b):y.slice.call(a,b,c)};var ta="StopIteration"in k?k.StopIteration:Error("StopIteration"),ua=function(){};ua.prototype.next=function(){throw ta;};ua.prototype.Sb=function(){return this};var va=function(a,b,c){for(var d in a)b.call(c,a[d],d,a)},wa=function(a){var b=[],c=0,d;for(d in a)b[c++]=a[d];return b},xa=function(a){var b=[],c=0,d;for(d in a)b[c++]=d;return b},ya=function(a,b){var c;a:{for(c in a)if(b.call(void 0,a[c],c,a))break a;c=void 0}return c&&a[c]},za="constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf".split(" "),Aa=function(a,b){for(var c,d,e=1;e<arguments.length;e++){d=arguments[e];for(c in d)a[c]=d[c];for(var f=0;f<za.length;f++)c= -za[f],Object.prototype.hasOwnProperty.call(d,c)&&(a[c]=d[c])}},Ba=function(a){var b=arguments.length;if(1==b&&n(arguments[0]))return Ba.apply(null,arguments[0]);for(var c={},d=0;d<b;d++)c[arguments[d]]=!0;return c};var z=function(a,b){this.p={};this.b=[];this.Ja=this.j=0;var c=arguments.length;if(1<c){if(c%2)throw Error("Uneven number of arguments");for(var d=0;d<c;d+=2)this.set(arguments[d],arguments[d+1])}else a&&this.ha(a)};z.prototype.t=function(){Ca(this);for(var a=[],b=0;b<this.b.length;b++)a.push(this.p[this.b[b]]);return a};z.prototype.H=function(){Ca(this);return this.b.concat()};z.prototype.T=function(a){return A(this.p,a)}; -z.prototype.remove=function(a){return A(this.p,a)?(delete this.p[a],this.j--,this.Ja++,this.b.length>2*this.j&&Ca(this),!0):!1};var Ca=function(a){if(a.j!=a.b.length){for(var b=0,c=0;b<a.b.length;){var d=a.b[b];A(a.p,d)&&(a.b[c++]=d);b++}a.b.length=c}if(a.j!=a.b.length){for(var e={},c=b=0;b<a.b.length;)d=a.b[b],A(e,d)||(a.b[c++]=d,e[d]=1),b++;a.b.length=c}};h=z.prototype;h.get=function(a,b){return A(this.p,a)?this.p[a]:b}; -h.set=function(a,b){A(this.p,a)||(this.j++,this.b.push(a),this.Ja++);this.p[a]=b};h.ha=function(a){var b;a instanceof z?(b=a.H(),a=a.t()):(b=xa(a),a=wa(a));for(var c=0;c<b.length;c++)this.set(b[c],a[c])};h.forEach=function(a,b){for(var c=this.H(),d=0;d<c.length;d++){var e=c[d],f=this.get(e);a.call(b,f,e,this)}};h.clone=function(){return new z(this)};h.Nb=function(){Ca(this);for(var a={},b=0;b<this.b.length;b++){var c=this.b[b];a[c]=this.p[c]}return a}; -h.Sb=function(a){Ca(this);var b=0,c=this.b,d=this.p,e=this.Ja,f=this,g=new ua;g.next=function(){for(;;){if(e!=f.Ja)throw Error("The map has changed since the iterator was created");if(b>=c.length)throw ta;var g=c[b++];return a?g:d[g]}};return g};var A=function(a,b){return Object.prototype.hasOwnProperty.call(a,b)};var Da,Ea,Fa={id:"hitType",name:"t",valueType:"text",maxLength:void 0,defaultValue:void 0},Ga={id:"sessionControl",name:"sc",valueType:"text",maxLength:void 0,defaultValue:void 0},Ha={id:"description",name:"cd",valueType:"text",maxLength:2048,defaultValue:void 0},Ia={id:"eventCategory",name:"ec",valueType:"text",maxLength:150,defaultValue:void 0},Ja={id:"eventAction",name:"ea",valueType:"text",maxLength:500,defaultValue:void 0},Ka={id:"eventLabel",name:"el",valueType:"text",maxLength:500,defaultValue:void 0}, -La={id:"eventValue",name:"ev",valueType:"integer",maxLength:void 0,defaultValue:void 0},Ma={zd:Fa,$c:{id:"anonymizeIp",name:"aip",valueType:"boolean",maxLength:void 0,defaultValue:void 0},Kd:{id:"queueTime",name:"qt",valueType:"integer",maxLength:void 0,defaultValue:void 0},fd:{id:"cacheBuster",name:"z",valueType:"text",maxLength:void 0,defaultValue:void 0},Qd:Ga,Rd:{id:"sessionGroup",name:"sg",valueType:"text",maxLength:void 0,defaultValue:void 0},ge:{id:"userId",name:"uid",valueType:"text",maxLength:void 0, -defaultValue:void 0},Hd:{id:"nonInteraction",name:"ni",valueType:"boolean",maxLength:void 0,defaultValue:void 0},qd:Ha,$d:{id:"title",name:"dt",valueType:"text",maxLength:1500,defaultValue:void 0},bd:{id:"appId",name:"aid",valueType:"text",maxLength:150,defaultValue:void 0},cd:{id:"appInstallerId",name:"aiid",valueType:"text",maxLength:150,defaultValue:void 0},td:Ia,sd:Ja,ud:Ka,vd:La,Td:{id:"socialNetwork",name:"sn",valueType:"text",maxLength:50,defaultValue:void 0},Sd:{id:"socialAction",name:"sa", -valueType:"text",maxLength:50,defaultValue:void 0},Ud:{id:"socialTarget",name:"st",valueType:"text",maxLength:2048,defaultValue:void 0},ce:{id:"transactionId",name:"ti",valueType:"text",maxLength:500,defaultValue:void 0},be:{id:"transactionAffiliation",name:"ta",valueType:"text",maxLength:500,defaultValue:void 0},de:{id:"transactionRevenue",name:"tr",valueType:"currency",maxLength:void 0,defaultValue:void 0},ee:{id:"transactionShipping",name:"ts",valueType:"currency",maxLength:void 0,defaultValue:void 0}, -fe:{id:"transactionTax",name:"tt",valueType:"currency",maxLength:void 0,defaultValue:void 0},od:{id:"currencyCode",name:"cu",valueType:"text",maxLength:10,defaultValue:void 0},Dd:{id:"itemPrice",name:"ip",valueType:"currency",maxLength:void 0,defaultValue:void 0},Ed:{id:"itemQuantity",name:"iq",valueType:"integer",maxLength:void 0,defaultValue:void 0},Bd:{id:"itemCode",name:"ic",valueType:"text",maxLength:500,defaultValue:void 0},Cd:{id:"itemName",name:"in",valueType:"text",maxLength:500,defaultValue:void 0}, -Ad:{id:"itemCategory",name:"iv",valueType:"text",maxLength:500,defaultValue:void 0},md:{id:"campaignSource",name:"cs",valueType:"text",maxLength:100,defaultValue:void 0},kd:{id:"campaignMedium",name:"cm",valueType:"text",maxLength:50,defaultValue:void 0},ld:{id:"campaignName",name:"cn",valueType:"text",maxLength:100,defaultValue:void 0},jd:{id:"campaignKeyword",name:"ck",valueType:"text",maxLength:500,defaultValue:void 0},gd:{id:"campaignContent",name:"cc",valueType:"text",maxLength:500,defaultValue:void 0}, -hd:{id:"campaignId",name:"ci",valueType:"text",maxLength:100,defaultValue:void 0},yd:{id:"gclid",name:"gclid",valueType:"text",maxLength:void 0,defaultValue:void 0},pd:{id:"dclid",name:"dclid",valueType:"text",maxLength:void 0,defaultValue:void 0},Jd:{id:"pageLoadTime",name:"plt",valueType:"integer",maxLength:void 0,defaultValue:void 0},rd:{id:"dnsTime",name:"dns",valueType:"integer",maxLength:void 0,defaultValue:void 0},Vd:{id:"tcpConnectTime",name:"tcp",valueType:"integer",maxLength:void 0,defaultValue:void 0}, -Pd:{id:"serverResponseTime",name:"srt",valueType:"integer",maxLength:void 0,defaultValue:void 0},Id:{id:"pageDownloadTime",name:"pdt",valueType:"integer",maxLength:void 0,defaultValue:void 0},Ld:{id:"redirectResponseTime",name:"rrt",valueType:"integer",maxLength:void 0,defaultValue:void 0},Wd:{id:"timingCategory",name:"utc",valueType:"text",maxLength:150,defaultValue:void 0},Zd:{id:"timingVar",name:"utv",valueType:"text",maxLength:500,defaultValue:void 0},Yd:{id:"timingValue",name:"utt",valueType:"integer", -maxLength:void 0,defaultValue:void 0},Xd:{id:"timingLabel",name:"utl",valueType:"text",maxLength:500,defaultValue:void 0},wd:{id:"exDescription",name:"exd",valueType:"text",maxLength:150,defaultValue:void 0},xd:{id:"exFatal",name:"exf",valueType:"boolean",maxLength:void 0,defaultValue:"1"}},Na=function(a){if(1>a||200<a)throw Error("Expected dimension index range 1-200, but was : "+a);return{id:"dimension"+a,name:"cd"+a,valueType:"text",maxLength:150,defaultValue:void 0}},Oa=function(a){if(1>a||200< -a)throw Error("Expected metric index range 1-200, but was : "+a);return{id:"metric"+a,name:"cm"+a,valueType:"integer",maxLength:void 0,defaultValue:void 0}};var Pa=function(a){if(1>a)return"0";if(3>a)return"1-2";a=Math.floor(Math.log(a-1)/Math.log(2));return Math.pow(2,a)+1+"-"+Math.pow(2,a+1)},Qa=function(a,b){for(var c=0,d=a.length-1,e=0;c<=d;){var f=Math.floor((c+d)/2),e=a[f];if(b<=e){d=0==f?0:a[f-1];if(b>d)return(d+1).toString()+"-"+e.toString();d=f-1}else if(b>e){if(f>=a.length-1)return(a[a.length-1]+1).toString()+"+";c=f+1}}return"<= 0"};var B=function(){this.gb=[]},Ra=function(){return new B};h=B.prototype;h.when=function(a){this.gb.push(a);return this};h.Rb=function(a){var b=arguments;this.when(function(a){return 0<=ka(b,a.ub())});return this};h.Yc=function(a,b){var c=sa(arguments,1);this.when(function(b){b=b.V().get(a);return 0<=ka(c,b)});return this};h.mb=function(a,b){if(r(this.e))throw Error("Filter has already been set.");this.e=r(b)?t(a,b):a;return this}; -h.ia=function(){if(0==this.gb.length)throw Error("Must specify at least one predicate using #when or a helper method.");if(!r(this.e))throw Error("Must specify a delegate filter using #applyFilter.");return t(function(a){na(this.gb,function(b){return b(a)})&&this.e(a)},this)};var C=function(){this.lb=!1;this.zb="";this.Kb=!1;this.ya=null};C.prototype.Wb=function(a){this.lb=!0;this.zb=a||" - ";return this};C.prototype.Sc=function(){this.Kb=!0;return this};C.prototype.Dc=function(){return Sa(this,Pa)};C.prototype.Ec=function(a){return Sa(this,ha(Qa,a))}; -var Sa=function(a,b){if(null!=a.ya)throw Error("LabelerBuilder: Only one labeling strategy may be used.");a.ya=t(function(a){var d=a.V().get(La),e=a.V().get(Ka);ea(d)&&(d=b(d),null!=e&&this.lb&&(d=e+this.zb+d),a.V().set(Ka,d))},a);return a};C.prototype.ia=function(){if(null==this.ya)throw Error("LabelerBuilder: a labeling strategy must be specified prior to calling build().");return Ra().Rb("event").mb(t(function(a){this.ya(a);this.Kb&&a.V().remove(La)},this)).ia()};var Ua=function(a,b){var c=Array.prototype.slice.call(arguments),d=c.shift();if("undefined"==typeof d)throw Error("[goog.string.format] Template required");return d.replace(/%([0\-\ \+]*)(\d+)?(\.(\d+))?([%sfdiu])/g,function(a,b,d,l,D,N,Y,Z){if("%"==N)return"%";var Nb=c.shift();if("undefined"==typeof Nb)throw Error("[goog.string.format] Not enough arguments");arguments[0]=Nb;return Ta[N].apply(null,arguments)})},Ta={s:function(a,b,c){return isNaN(c)||""==c||a.length>=c?a:a=-1<b.indexOf("-",0)?a+Array(c- -a.length+1).join(" "):Array(c-a.length+1).join(" ")+a},f:function(a,b,c,d,e){d=a.toString();isNaN(e)||""==e||(d=parseFloat(a).toFixed(e));var f;f=0>a?"-":0<=b.indexOf("+")?"+":0<=b.indexOf(" ")?" ":"";0<=a&&(d=f+d);if(isNaN(c)||d.length>=c)return d;d=isNaN(e)?Math.abs(a).toString():Math.abs(a).toFixed(e);a=c-d.length-f.length;return d=0<=b.indexOf("-",0)?f+d+Array(a+1).join(" "):f+Array(a+1).join(0<=b.indexOf("0",0)?"0":" ")+d},d:function(a,b,c,d,e,f,g,l){return Ta.f(parseInt(a,10),b,c,d,0,f,g,l)}}; -Ta.i=Ta.d;Ta.u=Ta.d;var Va=function(a){if("function"==typeof a.t)return a.t();if(p(a))return a.split("");if(da(a)){for(var b=[],c=a.length,d=0;d<c;d++)b.push(a[d]);return b}return wa(a)},Wa=function(a,b){if("function"==typeof a.forEach)a.forEach(b,void 0);else if(da(a)||p(a))la(a,b,void 0);else{var c;if("function"==typeof a.H)c=a.H();else if("function"!=typeof a.t)if(da(a)||p(a)){c=[];for(var d=a.length,e=0;e<d;e++)c.push(e)}else c=xa(a);else c=void 0;for(var d=Va(a),e=d.length,f=0;f<e;f++)b.call(void 0,d[f],c&&c[f], -a)}};var E=function(a){this.w=new z;if(0<arguments.length%2)throw Error("Uneven number of arguments to ParameterMap constructor.");for(var b=arguments,c=0;c<b.length;c+=2)this.set(b[c],b[c+1])};E.prototype.set=function(a,b){if(null==b)throw Error("undefined-or-null value for key: "+a.name);this.w.set(a.name,{key:a,value:b})};E.prototype.remove=function(a){this.w.remove(a.name)};E.prototype.get=function(a){a=this.w.get(a.name,null);return null===a?null:a.value};E.prototype.ha=function(a){this.w.ha(a.w)}; -var Xa=function(a,b){la(a.w.t(),function(a){b(a.key,a.value)})};E.prototype.Nb=function(){var a={};Xa(this,function(b,c){a[b.id]=c});return a};E.prototype.clone=function(){var a=new E;a.w=this.w.clone();return a};E.prototype.toString=function(){var a={};Xa(this,function(b,c){a[b.id]=c});return JSON.stringify(a)};var F=function(a){this.e=a};h=F.prototype;h.Yb=function(a){var b=new F(t(this.M,this));b.I=Ia;b.Q=a;return b};h.action=function(a){var b=new F(t(this.M,this));b.I=Ja;b.Q=a;return b};h.label=function(a){var b=new F(t(this.M,this));b.I=Ka;b.Q=a;return b};h.value=function(a){var b=new F(t(this.M,this));b.I=La;b.Q=a;return b};h.fc=function(a){var b=new F(t(this.M,this));b.I=Na(a.index);b.Q=a.value;return b};h.vc=function(a){var b=new F(t(this.M,this));b.I=Oa(a.index);b.Q=a.value;return b}; -h.send=function(a){var b=new E;this.M(b);return a.send("event",b)};h.M=function(a){null!=this.I&&null!=this.Q&&!a.w.T(this.I.name)&&a.set(this.I,this.Q);r(this.e)&&this.e(a)};var Ya=new F(ba);var G=function(){this.aa=this.aa;this.Ca=this.Ca};G.prototype.aa=!1;G.prototype.ma=function(){this.aa||(this.aa=!0,this.o())};G.prototype.o=function(){if(this.Ca)for(;this.Ca.length;)this.Ca.shift()()};var Za=function(a,b){this.type=a;this.currentTarget=this.target=b;this.defaultPrevented=this.X=!1;this.Hb=!0};Za.prototype.preventDefault=function(){this.defaultPrevented=!0;this.Hb=!1};var $a=function(a){$a[" "](a);return a};$a[" "]=ba;var H;a:{var ab=k.navigator;if(ab){var bb=ab.userAgent;if(bb){H=bb;break a}}H=""};var cb=function(){return-1!=H.indexOf("Edge")||-1!=H.indexOf("Trident")||-1!=H.indexOf("MSIE")};var I=function(){return-1!=H.indexOf("Edge")};var db=-1!=H.indexOf("Opera")||-1!=H.indexOf("OPR"),J=cb(),eb=-1!=H.indexOf("Gecko")&&!(-1!=H.toLowerCase().indexOf("webkit")&&!I())&&!(-1!=H.indexOf("Trident")||-1!=H.indexOf("MSIE"))&&!I(),fb=-1!=H.toLowerCase().indexOf("webkit")&&!I(),gb=function(){var a=H;if(eb)return/rv\:([^\);]+)(\)|;)/.exec(a);if(J&&I())return/Edge\/([\d\.]+)/.exec(a);if(J)return/\b(?:MSIE|rv)[: ]([^\);]+)(\)|;)/.exec(a);if(fb)return/WebKit\/(\S+)/.exec(a)},hb=function(){var a=k.document;return a?a.documentMode:void 0},ib= -function(){if(db&&k.opera){var a=k.opera.version;return q(a)?a():a}var a="",b=gb();b&&(a=b?b[1]:"");return J&&!I()&&(b=hb(),b>parseFloat(a))?String(b):a}(),jb={},K=function(a){var b;if(!(b=jb[a])){b=0;for(var c=ia(String(ib)).split("."),d=ia(String(a)).split("."),e=Math.max(c.length,d.length),f=0;0==b&&f<e;f++){var g=c[f]||"",l=d[f]||"",D=/(\d*)(\D*)/g,N=/(\d*)(\D*)/g;do{var Y=D.exec(g)||["","",""],Z=N.exec(l)||["","",""];if(0==Y[0].length&&0==Z[0].length)break;b=ja(0==Y[1].length?0:parseInt(Y[1], -10),0==Z[1].length?0:parseInt(Z[1],10))||ja(0==Y[2].length,0==Z[2].length)||ja(Y[2],Z[2])}while(0==b)}b=jb[a]=0<=b}return b},kb=k.document,lb=hb(),mb=!kb||!J||!lb&&I()?void 0:lb||("CSS1Compat"==kb.compatMode?parseInt(ib,10):5);var nb=!J||J&&(I()||9<=mb),ob=J&&!K("9"),pb=!fb||K("528"),qb=eb&&K("1.9b")||J&&K("8")||db&&K("9.5")||fb&&K("528"),rb=eb&&!K("8")||J&&!K("9");var sb=function(a,b){Za.call(this,a?a.type:"");this.relatedTarget=this.currentTarget=this.target=null;this.charCode=this.keyCode=this.button=this.screenY=this.screenX=this.clientY=this.clientX=this.offsetY=this.offsetX=0;this.metaKey=this.shiftKey=this.altKey=this.ctrlKey=!1;this.sb=this.state=null;if(a){var c=this.type=a.type;this.target=a.target||a.srcElement;this.currentTarget=b;var d=a.relatedTarget;if(d){if(eb){var e;a:{try{$a(d.nodeName);e=!0;break a}catch(f){}e=!1}e||(d=null)}}else"mouseover"== -c?d=a.fromElement:"mouseout"==c&&(d=a.toElement);this.relatedTarget=d;this.offsetX=fb||void 0!==a.offsetX?a.offsetX:a.layerX;this.offsetY=fb||void 0!==a.offsetY?a.offsetY:a.layerY;this.clientX=void 0!==a.clientX?a.clientX:a.pageX;this.clientY=void 0!==a.clientY?a.clientY:a.pageY;this.screenX=a.screenX||0;this.screenY=a.screenY||0;this.button=a.button;this.keyCode=a.keyCode||0;this.charCode=a.charCode||("keypress"==c?a.keyCode:0);this.ctrlKey=a.ctrlKey;this.altKey=a.altKey;this.shiftKey=a.shiftKey; -this.metaKey=a.metaKey;this.state=a.state;this.sb=a;a.defaultPrevented&&this.preventDefault()}};w(sb,Za);sb.prototype.preventDefault=function(){sb.P.preventDefault.call(this);var a=this.sb;if(a.preventDefault)a.preventDefault();else if(a.returnValue=!1,ob)try{if(a.ctrlKey||112<=a.keyCode&&123>=a.keyCode)a.keyCode=-1}catch(b){}};var tb="closure_listenable_"+(1E6*Math.random()|0),ub=function(a){return!(!a||!a[tb])},vb=0;var wb=function(a,b,c,d,e){this.O=a;this.proxy=null;this.src=b;this.type=c;this.ka=!!d;this.sa=e;this.key=++vb;this.removed=this.ja=!1},xb=function(a){a.removed=!0;a.O=null;a.proxy=null;a.src=null;a.sa=null};var L=function(a){this.src=a;this.k={};this.fa=0};L.prototype.add=function(a,b,c,d,e){var f=a.toString();a=this.k[f];a||(a=this.k[f]=[],this.fa++);var g=yb(a,b,d,e);-1<g?(b=a[g],c||(b.ja=!1)):(b=new wb(b,this.src,f,!!d,e),b.ja=c,a.push(b));return b};L.prototype.remove=function(a,b,c,d){a=a.toString();if(!(a in this.k))return!1;var e=this.k[a];b=yb(e,b,c,d);return-1<b?(xb(e[b]),y.splice.call(e,b,1),0==e.length&&(delete this.k[a],this.fa--),!0):!1}; -var zb=function(a,b){var c=b.type;if(!(c in a.k))return!1;var d=qa(a.k[c],b);d&&(xb(b),0==a.k[c].length&&(delete a.k[c],a.fa--));return d};L.prototype.removeAll=function(a){a=a&&a.toString();var b=0,c;for(c in this.k)if(!a||c==a){for(var d=this.k[c],e=0;e<d.length;e++)++b,xb(d[e]);delete this.k[c];this.fa--}return b};L.prototype.ba=function(a,b,c,d){a=this.k[a.toString()];var e=-1;a&&(e=yb(a,b,c,d));return-1<e?a[e]:null}; -var yb=function(a,b,c,d){for(var e=0;e<a.length;++e){var f=a[e];if(!f.removed&&f.O==b&&f.ka==!!c&&f.sa==d)return e}return-1};var Ab="closure_lm_"+(1E6*Math.random()|0),Bb={},Cb=0,Db=function(a,b,c,d,e){if(n(b)){for(var f=0;f<b.length;f++)Db(a,b[f],c,d,e);return null}c=Eb(c);return ub(a)?a.listen(b,c,d,e):Fb(a,b,c,!1,d,e)},Fb=function(a,b,c,d,e,f){if(!b)throw Error("Invalid event type");var g=!!e,l=Gb(a);l||(a[Ab]=l=new L(a));c=l.add(b,c,d,e,f);if(c.proxy)return c;d=Hb();c.proxy=d;d.src=a;d.O=c;a.addEventListener?a.addEventListener(b.toString(),d,g):a.attachEvent(Ib(b.toString()),d);Cb++;return c},Hb=function(){var a=Jb, -b=nb?function(c){return a.call(b.src,b.O,c)}:function(c){c=a.call(b.src,b.O,c);if(!c)return c};return b},Kb=function(a,b,c,d,e){if(n(b)){for(var f=0;f<b.length;f++)Kb(a,b[f],c,d,e);return null}c=Eb(c);return ub(a)?a.cb(b,c,d,e):Fb(a,b,c,!0,d,e)},Lb=function(a,b,c,d,e){if(n(b))for(var f=0;f<b.length;f++)Lb(a,b[f],c,d,e);else c=Eb(c),ub(a)?a.jb(b,c,d,e):a&&(a=Gb(a))&&(b=a.ba(b,c,!!d,e))&&Mb(b)},Mb=function(a){if(ea(a)||!a||a.removed)return!1;var b=a.src;if(ub(b))return zb(b.B,a);var c=a.type,d=a.proxy; -b.removeEventListener?b.removeEventListener(c,d,a.ka):b.detachEvent&&b.detachEvent(Ib(c),d);Cb--;(c=Gb(b))?(zb(c,a),0==c.fa&&(c.src=null,b[Ab]=null)):xb(a);return!0},Ib=function(a){return a in Bb?Bb[a]:Bb[a]="on"+a},Pb=function(a,b,c,d){var e=!0;if(a=Gb(a))if(b=a.k[b.toString()])for(b=b.concat(),a=0;a<b.length;a++){var f=b[a];f&&f.ka==c&&!f.removed&&(f=Ob(f,d),e=e&&!1!==f)}return e},Ob=function(a,b){var c=a.O,d=a.sa||a.src;a.ja&&Mb(a);return c.call(d,b)},Jb=function(a,b){if(a.removed)return!0;if(!nb){var c; -if(!(c=b))a:{c=["window","event"];for(var d=k,e;e=c.shift();)if(null!=d[e])d=d[e];else{c=null;break a}c=d}e=c;c=new sb(e,this);d=!0;if(!(0>e.keyCode||void 0!=e.returnValue)){a:{var f=!1;if(0==e.keyCode)try{e.keyCode=-1;break a}catch(g){f=!0}if(f||void 0==e.returnValue)e.returnValue=!0}e=[];for(f=c.currentTarget;f;f=f.parentNode)e.push(f);for(var f=a.type,l=e.length-1;!c.X&&0<=l;l--){c.currentTarget=e[l];var D=Pb(e[l],f,!0,c),d=d&&D}for(l=0;!c.X&&l<e.length;l++)c.currentTarget=e[l],D=Pb(e[l],f,!1, -c),d=d&&D}return d}return Ob(a,new sb(b,this))},Gb=function(a){a=a[Ab];return a instanceof L?a:null},Qb="__closure_events_fn_"+(1E9*Math.random()>>>0),Eb=function(a){if(q(a))return a;a[Qb]||(a[Qb]=function(b){return a.handleEvent(b)});return a[Qb]};var M=function(){G.call(this);this.B=new L(this);this.Tb=this;this.fb=null};w(M,G);M.prototype[tb]=!0;h=M.prototype;h.addEventListener=function(a,b,c,d){Db(this,a,b,c,d)};h.removeEventListener=function(a,b,c,d){Lb(this,a,b,c,d)}; -h.dispatchEvent=function(a){var b,c=this.fb;if(c){b=[];for(var d=1;c;c=c.fb)b.push(c),++d}c=this.Tb;d=a.type||a;if(p(a))a=new Za(a,c);else if(a instanceof Za)a.target=a.target||c;else{var e=a;a=new Za(d,c);Aa(a,e)}var e=!0,f;if(b)for(var g=b.length-1;!a.X&&0<=g;g--)f=a.currentTarget=b[g],e=Rb(f,d,!0,a)&&e;a.X||(f=a.currentTarget=c,e=Rb(f,d,!0,a)&&e,a.X||(e=Rb(f,d,!1,a)&&e));if(b)for(g=0;!a.X&&g<b.length;g++)f=a.currentTarget=b[g],e=Rb(f,d,!1,a)&&e;return e}; -h.o=function(){M.P.o.call(this);this.B&&this.B.removeAll(void 0);this.fb=null};h.listen=function(a,b,c,d){return this.B.add(String(a),b,!1,c,d)};h.cb=function(a,b,c,d){return this.B.add(String(a),b,!0,c,d)};h.jb=function(a,b,c,d){return this.B.remove(String(a),b,c,d)};var Rb=function(a,b,c,d){b=a.B.k[String(b)];if(!b)return!0;b=b.concat();for(var e=!0,f=0;f<b.length;++f){var g=b[f];if(g&&!g.removed&&g.ka==c){var l=g.O,D=g.sa||g.src;g.ja&&zb(a.B,g);e=!1!==l.call(D,d)&&e}}return e&&0!=d.Hb}; -M.prototype.ba=function(a,b,c,d){return this.B.ba(String(a),b,c,d)};var Sb=function(a,b,c){this.tc=c;this.dc=a;this.Gc=b;this.Ba=0;this.ta=null};Sb.prototype.get=function(){var a;0<this.Ba?(this.Ba--,a=this.ta,this.ta=a.next,a.next=null):a=this.dc();return a};Sb.prototype.put=function(a){this.Gc(a);this.Ba<this.tc&&(this.Ba++,a.next=this.ta,this.ta=a)};var Tb=function(a){k.setTimeout(function(){throw a;},0)},Ub,Vb=function(){var a=k.MessageChannel;"undefined"===typeof a&&"undefined"!==typeof window&&window.postMessage&&window.addEventListener&&-1==H.indexOf("Presto")&&(a=function(){var a=document.createElement("IFRAME");a.style.display="none";a.src="";document.documentElement.appendChild(a);var b=a.contentWindow,a=b.document;a.open();a.write("");a.close();var c="callImmediate"+Math.random(),d="file:"==b.location.protocol?"*":b.location.protocol+ -"//"+b.location.host,a=t(function(a){if(("*"==d||a.origin==d)&&a.data==c)this.port1.onmessage()},this);b.addEventListener("message",a,!1);this.port1={};this.port2={postMessage:function(){b.postMessage(c,d)}}});if("undefined"!==typeof a&&!cb()){var b=new a,c={},d=c;b.port1.onmessage=function(){if(m(c.next)){c=c.next;var a=c.ob;c.ob=null;a()}};return function(a){d.next={ob:a};d=d.next;b.port2.postMessage(0)}}return"undefined"!==typeof document&&"onreadystatechange"in document.createElement("SCRIPT")? -function(a){var b=document.createElement("SCRIPT");b.onreadystatechange=function(){b.onreadystatechange=null;b.parentNode.removeChild(b);b=null;a();a=null};document.documentElement.appendChild(b)}:function(a){k.setTimeout(a,0)}};var Wb=function(){this.Ka=this.Z=null},Yb=new Sb(function(){return new Xb},function(a){a.reset()},100);Wb.prototype.add=function(a,b){var c=Yb.get();c.set(a,b);this.Ka?this.Ka.next=c:this.Z=c;this.Ka=c};Wb.prototype.remove=function(){var a=null;this.Z&&(a=this.Z,this.Z=this.Z.next,this.Z||(this.Ka=null),a.next=null);return a};var Xb=function(){this.next=this.scope=this.Wa=null};Xb.prototype.set=function(a,b){this.Wa=a;this.scope=b;this.next=null}; -Xb.prototype.reset=function(){this.next=this.scope=this.Wa=null};var cc=function(a,b){Zb||$b();ac||(Zb(),ac=!0);bc.add(a,b)},Zb,$b=function(){if(k.Promise&&k.Promise.resolve){var a=k.Promise.resolve();Zb=function(){a.then(dc)}}else Zb=function(){var a=dc;!q(k.setImmediate)||k.Window&&k.Window.prototype&&k.Window.prototype.setImmediate==k.setImmediate?(Ub||(Ub=Vb()),Ub(a)):k.setImmediate(a)}},ac=!1,bc=new Wb,dc=function(){for(var a=null;a=bc.remove();){try{a.Wa.call(a.scope)}catch(b){Tb(b)}Yb.put(a)}ac=!1};var ec=function(a){a.prototype.then=a.prototype.then;a.prototype.$goog_Thenable=!0},fc=function(a){if(!a)return!1;try{return!!a.$goog_Thenable}catch(b){return!1}};var P=function(a,b){this.m=0;this.D=void 0;this.S=this.G=this.l=null;this.ra=this.Va=!1;if(a==gc)O(this,2,b);else try{var c=this;a.call(b,function(a){O(c,2,a)},function(a){O(c,3,a)})}catch(d){O(this,3,d)}},hc=function(){this.next=this.context=this.da=this.Da=this.L=null;this.Na=!1};hc.prototype.reset=function(){this.context=this.da=this.Da=this.L=null;this.Na=!1}; -var ic=new Sb(function(){return new hc},function(a){a.reset()},100),jc=function(a,b,c){var d=ic.get();d.Da=a;d.da=b;d.context=c;return d},gc=function(){};P.prototype.then=function(a,b,c){return kc(this,q(a)?a:null,q(b)?b:null,c)};ec(P);P.prototype.cancel=function(a){0==this.m&&cc(function(){var b=new lc(a);mc(this,b)},this)}; -var mc=function(a,b){if(0==a.m)if(a.l){var c=a.l;if(c.G){for(var d=0,e=null,f=null,g=c.G;g&&(g.Na||(d++,g.L==a&&(e=g),!(e&&1<d)));g=g.next)e||(f=g);e&&(0==c.m&&1==d?mc(c,b):(f?(d=f,d.next==c.S&&(c.S=d),d.next=d.next.next):nc(c),oc(c,e,3,b)))}a.l=null}else O(a,3,b)},qc=function(a,b){a.G||2!=a.m&&3!=a.m||pc(a);a.S?a.S.next=b:a.G=b;a.S=b},kc=function(a,b,c,d){var e=jc(null,null,null);e.L=new P(function(a,g){e.Da=b?function(c){try{var e=b.call(d,c);a(e)}catch(N){g(N)}}:a;e.da=c?function(b){try{var e= -c.call(d,b);!m(e)&&b instanceof lc?g(b):a(e)}catch(N){g(N)}}:g});e.L.l=a;qc(a,e);return e.L};P.prototype.Pb=function(a){this.m=0;O(this,2,a)};P.prototype.Qb=function(a){this.m=0;O(this,3,a)}; -var O=function(a,b,c){if(0==a.m){if(a==c)b=3,c=new TypeError("Promise cannot resolve to itself");else{if(fc(c)){a.m=1;b=c;c=a.Pb;var d=a.Qb;b instanceof P?qc(b,jc(c||ba,d||null,a)):b.then(c,d,a);return}if(r(c))try{if(d=c.then,q(d)){rc(a,c,d);return}}catch(e){b=3,c=e}}a.D=c;a.m=b;a.l=null;pc(a);3!=b||c instanceof lc||sc(a,c)}},rc=function(a,b,c){a.m=1;var d=!1,e=function(b){d||(d=!0,a.Pb(b))},f=function(b){d||(d=!0,a.Qb(b))};try{c.call(b,e,f)}catch(g){f(g)}},pc=function(a){a.Va||(a.Va=!0,cc(a.gc,a))}, -nc=function(a){var b=null;a.G&&(b=a.G,a.G=b.next,b.next=null);a.G||(a.S=null);return b};P.prototype.gc=function(){for(var a=null;a=nc(this);)oc(this,a,this.m,this.D);this.Va=!1};var oc=function(a,b,c,d){b.L&&(b.L.l=null);if(2==c)b.Da.call(b.context,d);else if(null!=b.da){if(!b.Na)for(;a&&a.ra;a=a.l)a.ra=!1;b.da.call(b.context,d)}ic.put(b)},sc=function(a,b){a.ra=!0;cc(function(){a.ra&&tc.call(null,b)})},tc=Tb,lc=function(a){x.call(this,a)};w(lc,x);lc.prototype.name="cancel";/* - Portions of this code are from MochiKit, received by - The Closure Authors under the MIT license. All other code is Copyright - 2005-2009 The Closure Authors. All Rights Reserved. -*/ -var Q=function(a,b){this.Fa=[];this.Cb=a;this.rb=b||null;this.ca=this.C=!1;this.D=void 0;this.hb=this.Xb=this.Oa=!1;this.Ia=0;this.l=null;this.Qa=0};Q.prototype.cancel=function(a){if(this.C)this.D instanceof Q&&this.D.cancel();else{if(this.l){var b=this.l;delete this.l;a?b.cancel(a):(b.Qa--,0>=b.Qa&&b.cancel())}this.Cb?this.Cb.call(this.rb,this):this.hb=!0;this.C||this.A(new uc)}};Q.prototype.qb=function(a,b){this.Oa=!1;vc(this,a,b)}; -var vc=function(a,b,c){a.C=!0;a.D=c;a.ca=!b;wc(a)},yc=function(a){if(a.C){if(!a.hb)throw new xc;a.hb=!1}};Q.prototype.v=function(a){yc(this);vc(this,!0,a)};Q.prototype.A=function(a){yc(this);vc(this,!1,a)};Q.prototype.n=function(a,b){return zc(this,a,null,b)};var zc=function(a,b,c,d){a.Fa.push([b,c,d]);a.C&&wc(a);return a};Q.prototype.then=function(a,b,c){var d,e,f=new P(function(a,b){d=a;e=b});zc(this,d,function(a){a instanceof uc?f.cancel():e(a)});return f.then(a,b,c)};ec(Q); -var Ac=function(a){var b=new Q;zc(a,b.v,b.A,b);return b},Bc=function(a){return ma(a.Fa,function(a){return q(a[1])})},wc=function(a){if(a.Ia&&a.C&&Bc(a)){var b=a.Ia,c=Cc[b];c&&(k.clearTimeout(c.ua),delete Cc[b]);a.Ia=0}a.l&&(a.l.Qa--,delete a.l);for(var b=a.D,d=c=!1;a.Fa.length&&!a.Oa;){var e=a.Fa.shift(),f=e[0],g=e[1],e=e[2];if(f=a.ca?g:f)try{var l=f.call(e||a.rb,b);m(l)&&(a.ca=a.ca&&(l==b||l instanceof Error),a.D=b=l);fc(b)&&(d=!0,a.Oa=!0)}catch(D){b=D,a.ca=!0,Bc(a)||(c=!0)}}a.D=b;d&&(l=t(a.qb,a, -!0),d=t(a.qb,a,!1),b instanceof Q?(zc(b,l,d),b.Xb=!0):b.then(l,d));c&&(b=new Dc(b),Cc[b.ua]=b,a.Ia=b.ua)},Ec=function(a){var b=new Q;b.v(a);return b},Gc=function(){var a=Fc,b=new Q;b.A(a);return b},xc=function(){x.call(this)};w(xc,x);xc.prototype.message="Deferred has already fired";xc.prototype.name="AlreadyCalledError";var uc=function(){x.call(this)};w(uc,x);uc.prototype.message="Deferred was canceled";uc.prototype.name="CanceledError"; -var Dc=function(a){this.ua=k.setTimeout(t(this.Tc,this),0);this.na=a};Dc.prototype.Tc=function(){delete Cc[this.ua];throw this.na;};var Cc={};var Hc=function(a){this.qa=[];this.e=a};Hc.prototype.R=function(a){if(!q(a))throw Error("Invalid filter. Must be a function.");this.qa.push(a)};Hc.prototype.send=function(a,b){if(0==this.qa.length)return this.e.send(a,b);var c=new R(a,b);return Ic(this,0,c).n(function(){if(!c.Sa)return this.e.send(a,b)},this)};var Ic=function(a,b,c){return Ec().n(function(){return this.qa[b](c)},a).n(function(){if(++b<this.qa.length&&!c.Sa)return Ic(this,b,c)},a)},R=function(a,b){this.Wc=a;this.Cc=b;this.Sa=!1}; -R.prototype.ub=function(){return this.Wc};R.prototype.V=function(){return this.Cc};R.prototype.cancel=function(){this.Sa=!0};Ba("area base br col command embed hr img input keygen link meta param source track wbr".split(" "));var Jc=function(a,b){this.width=a;this.height=b};Jc.prototype.clone=function(){return new Jc(this.width,this.height)};Jc.prototype.floor=function(){this.width=Math.floor(this.width);this.height=Math.floor(this.height);return this};!eb&&!J||J&&J&&(I()||9<=mb)||eb&&K("1.9.1");J&&K("9");var Kc={id:"apiVersion",name:"v",valueType:"text",maxLength:void 0,defaultValue:void 0},Lc={id:"appName",name:"an",valueType:"text",maxLength:100,defaultValue:void 0},Mc={id:"appVersion",name:"av",valueType:"text",maxLength:100,defaultValue:void 0},Nc={id:"clientId",name:"cid",valueType:"text",maxLength:void 0,defaultValue:void 0},Oc={id:"language",name:"ul",valueType:"text",maxLength:20,defaultValue:void 0},Pc={id:"libVersion",name:"_v",valueType:"text",maxLength:void 0,defaultValue:void 0},Qc={id:"sampleRateOverride", -name:"usro",valueType:"integer",maxLength:void 0,defaultValue:void 0},Rc={id:"screenColors",name:"sd",valueType:"text",maxLength:20,defaultValue:void 0},Sc={id:"screenResolution",name:"sr",valueType:"text",maxLength:20,defaultValue:void 0},Tc={id:"trackingId",name:"tid",valueType:"text",maxLength:void 0,defaultValue:void 0},Uc={id:"viewportSize",name:"vp",valueType:"text",maxLength:20,defaultValue:void 0},Vc={ad:Kc,dd:Lc,ed:Mc,nd:Nc,Fd:Oc,Gd:Pc,Md:Qc,Nd:Rc,Od:Sc,ae:Tc,he:Uc},Xc=function(a){if(!p(a))return a; -var b=Wc(a,Ma);if(r(b))return b;b=Wc(a,Vc);if(r(b))return b;b=/^dimension(\d+)$/.exec(a);if(null!==b)return Na(parseInt(b[1],10));b=/^metric(\d+)$/.exec(a);if(null!==b)return Oa(parseInt(b[1],10));throw Error(a+" is not a valid parameter name.");},Wc=function(a,b){var c=ya(b,function(b){return b.id==a&&"metric"!=a&&"dimension"!=a});return r(c)?c:null};var S=function(a,b){this.ac=b;this.q=b.Xa();this.Fb=new E;this.ib=!1};h=S.prototype;h.set=function(a,b){if(null==b)throw Error("Value must be defined and not null. Parameter="+a.id);var c=Xc(a);this.Fb.set(c,b)};h.R=function(a){this.ac.R(a)};h.send=function(a,b){if(a instanceof F)return a.send(this);var c=this.Fb.clone();b instanceof E?c.ha(b):r(b)&&va(b,function(a,b){null!=a&&c.set(Xc(b),a)},this);this.ib&&(this.ib=!1,c.set(Ga,"start"));return this.q.send(a,c)}; -h.Hc=function(a){var b={description:a};this.set(Ha,a);return this.send("appview",b)};h.Ic=function(a,b,c,d){return this.send("event",{eventCategory:a,eventAction:b,eventLabel:c,eventValue:d})};h.Kc=function(a,b,c){return this.send("social",{socialNetwork:a,socialAction:b,socialTarget:c})};h.Jc=function(a,b){return this.send("exception",{exDescription:a,exFatal:b})};h.Ib=function(a,b,c,d,e){return this.send("timing",{timingCategory:a,timingVar:b,timingLabel:d,timingValue:c,sampleRateOverride:e})}; -h.jc=function(){this.ib=!0};h.Rc=function(a,b,c,d){return new Yc(this,a,b,c,d)};var Yc=function(a,b,c,d,e){this.Ob=a;this.Zb=b;this.Xc=c;this.rc=d;this.Ea=e;this.Qc=u()};Yc.prototype.send=function(){var a=this.Ob.Ib(this.Zb,this.Xc,u()-this.Qc,this.rc,this.Ea);this.Ob=null;return a};var Zc=function(a,b,c,d,e){this.sc=a;this.Ub=b;this.Vb=c;this.g=d;this.$b=e}; -Zc.prototype.mc=function(a){var b=new S(0,this.$b.create());b.set(Pc,this.sc);b.set(Kc,1);b.set(Lc,this.Ub);b.set(Mc,this.Vb);b.set(Tc,a);(a=navigator.language||navigator.browserLanguage)&&b.set(Oc,a);(a=screen.colorDepth+"-bit")&&b.set(Rc,a);(a=[screen.width,screen.height].join("x"))&&b.set(Sc,a);a=window.document;a="CSS1Compat"==a.compatMode?a.documentElement:a.body;a=new Jc(a.clientWidth,a.clientHeight);(a=[a.width,a.height].join("x"))&&b.set(Uc,a);return b};Zc.prototype.kc=function(){return Ac(this.g.ea)};var $c=function(a,b,c,d,e,f){Q.call(this,e,f);this.bb=a;this.Ta=[];this.tb=!!b;this.ic=!!c;this.cc=!!d;for(b=this.Bb=0;b<a.length;b++)zc(a[b],t(this.vb,this,b,!0),t(this.vb,this,b,!1));0!=a.length||this.tb||this.v(this.Ta)};w($c,Q);$c.prototype.vb=function(a,b,c){this.Bb++;this.Ta[a]=[b,c];this.C||(this.tb&&b?this.v([a,c]):this.ic&&!b?this.A(c):this.Bb==this.bb.length&&this.v(this.Ta));this.cc&&!b&&(c=null);return c};$c.prototype.A=function(a){$c.P.A.call(this,a);for(a=0;a<this.bb.length;a++)this.bb[a].cancel()}; -var ad=function(a){return(new $c(a,!1,!0)).n(function(a){for(var c=[],d=0;d<a.length;d++)c[d]=a[d][1];return c})};var bd=function(){for(var a="xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".split(""),b=0,c=a.length;b<c;b++)switch(a[b]){case "x":a[b]=Math.floor(16*Math.random()).toString(16);break;case "y":a[b]=(Math.floor(4*Math.random())+8).toString(16)}return a.join("")};var T=function(a){this.J=a;this.Ea=100;this.pb=[];this.W=this.ga=null;this.ea=cd(this);this.ea.n(function(){this.Jb=Db(this.J,"a",t(this.nc,this))},this)},cd=function(a){return dd(a).n(function(){return this},a)},dd=function(a){return ad([ed(a),fd(a)])};T.prototype.nc=function(){U(this);var a=gd(this),b=this.xa();dd(this).n(function(){a!=gd(this)&&hd(this,"analytics.user-id");b!=this.xa()&&hd(this,"analytics.tracking-permitted")},this)};var id=function(a,b){U(a);a.pb.push(b)}; -T.prototype.Oc=function(a){U(this);var b=this.W!=a;this.W=a;this.J.set("analytics.tracking-permitted",a.toString());b&&hd(this,"analytics.tracking-permitted")};T.prototype.xa=function(){U(this);var a;if(a=this.W)a=k._gaUserPrefs,a=!(a&&a.ioo&&a.ioo());return a}; -var ed=function(a){return a.J.get("analytics.tracking-permitted").n(function(a){this.W=!0;if(m(a))switch(a){case "true":this.W=!0;break;case "false":this.W=!1}},a)},gd=function(a){U(a);if(!p(a.ga))throw Error("Invalid state. UserID is not a string.");return a.ga},fd=function(a){return a.J.get("analytics.user-id").n(function(a){m(a)?this.ga=a:jd(this)},a)},jd=function(a){a.ga=bd();return a.J.set("analytics.user-id",a.ga).n(function(){hd(this,"analytics.user-id")},a)}; -T.prototype.Nc=function(a){U(this);this.Ea=a};var kd=function(a){U(a);return a.Ea};T.prototype.Fc=function(){return jd(this)};var hd=function(a,b){la(a.pb,function(a){a(b)})};T.prototype.ma=function(){null!=this.Jb&&Mb(this.Jb)};var U=function(a){if(!Ac(a.ea).C)throw Error("Settings object accessed prior to entering ready state.");};var ld=function(){M.call(this);this.eb="google-analytics";this.J=chrome.storage.local;chrome.storage.onChanged.addListener(t(this.Ac,this))};w(ld,M);ld.prototype.Ac=function(a){md(this,a)&&this.dispatchEvent("a")};var md=function(a,b){return ma(xa(b),function(a){return 0==a.lastIndexOf(this.eb,0)},a)};ld.prototype.get=function(a){var b=new Q,c=this.eb+"."+a;this.J.get(c,function(a){chrome.runtime.lastError?b.A(chrome.runtime.lastError):(a=a[c],b.v(null!=a?a.toString():void 0))});return b}; -ld.prototype.set=function(a,b){var c=new Q,d={};d[this.eb+"."+a]=b;this.J.set(d,function(){chrome.runtime.lastError?c.A(chrome.runtime.lastError):c.v()});return c};var V=function(){};V.lc=function(){return V.yb?V.yb:V.yb=new V};V.prototype.send=function(){return Ec()};var nd=function(a){this.ec=a};nd.prototype.send=function(a,b){this.ec.push({pc:a,Bc:b});return Ec()};var od=function(a,b,c){this.g=a;this.U=[];this.K={enabled:new nd(this.U),disabled:c};this.q=this.K.enabled;zc(Ac(this.g.ea),ha(this.zc,b),this.yc,this)};od.prototype.zc=function(a){if(null===this.U)throw Error("Channel setup already completed.");this.K.enabled=a();pd(this);la(this.U,function(a){this.send(a.pc,a.Bc)},this);this.U=null;id(this.g,t(this.xc,this))}; -od.prototype.yc=function(){if(null===this.U)throw Error("Channel setup already completed.");this.q=this.K.enabled=this.K.disabled;this.U=null};od.prototype.send=function(a,b){return this.q.send(a,b)};var pd=function(a){a.q=a.g.xa()?a.K.enabled:a.K.disabled};od.prototype.xc=function(a){switch(a){case "analytics.tracking-permitted":pd(this)}};var qd=function(a,b){this.Ra=[];var c=t(function(){this.pa=new Hc(b.Xa());la(this.Ra,function(a){this.pa.R(a)},this);this.Ra=null;return this.pa},this);this.q=new od(a,c,V.lc())};qd.prototype.Xa=function(){return this.q};qd.prototype.R=function(a){this.pa?this.pa.R(a):this.Ra.push(a)};var rd=function(a,b){this.g=a;this.Pc=b};rd.prototype.create=function(){return new qd(this.g,this.Pc)};var sd=function(a,b){M.call(this);this.wa=a||1;this.Y=b||k;this.Pa=t(this.Uc,this);this.ab=u()};w(sd,M);h=sd.prototype;h.enabled=!1;h.h=null;h.Uc=function(){if(this.enabled){var a=u()-this.ab;0<a&&a<.8*this.wa?this.h=this.Y.setTimeout(this.Pa,this.wa-a):(this.h&&(this.Y.clearTimeout(this.h),this.h=null),this.dispatchEvent("tick"),this.enabled&&(this.h=this.Y.setTimeout(this.Pa,this.wa),this.ab=u()))}};h.start=function(){this.enabled=!0;this.h||(this.h=this.Y.setTimeout(this.Pa,this.wa),this.ab=u())}; -h.stop=function(){this.enabled=!1;this.h&&(this.Y.clearTimeout(this.h),this.h=null)};h.o=function(){sd.P.o.call(this);this.stop();delete this.Y};var td=function(a,b,c){if(q(a))c&&(a=t(a,c));else if(a&&"function"==typeof a.handleEvent)a=t(a.handleEvent,a);else throw Error("Invalid listener argument");return 2147483647<b?-1:k.setTimeout(a,b||0)};var W=function(a){G.call(this);this.Ya=a;this.b={}};w(W,G);var ud=[];W.prototype.listen=function(a,b,c,d){n(b)||(b&&(ud[0]=b.toString()),b=ud);for(var e=0;e<b.length;e++){var f=Db(a,b[e],c||this.handleEvent,d||!1,this.Ya||this);if(!f)break;this.b[f.key]=f}return this};W.prototype.cb=function(a,b,c,d){return vd(this,a,b,c,d)};var vd=function(a,b,c,d,e,f){if(n(c))for(var g=0;g<c.length;g++)vd(a,b,c[g],d,e,f);else{b=Kb(b,c,d||a.handleEvent,e,f||a.Ya||a);if(!b)return a;a.b[b.key]=b}return a}; -W.prototype.jb=function(a,b,c,d,e){if(n(b))for(var f=0;f<b.length;f++)this.jb(a,b[f],c,d,e);else c=c||this.handleEvent,e=e||this.Ya||this,c=Eb(c),d=!!d,b=ub(a)?a.ba(b,c,d,e):a?(a=Gb(a))?a.ba(b,c,d,e):null:null,b&&(Mb(b),delete this.b[b.key]);return this};W.prototype.removeAll=function(){va(this.b,Mb);this.b={}};W.prototype.o=function(){W.P.o.call(this);this.removeAll()};W.prototype.handleEvent=function(){throw Error("EventHandler.handleEvent not implemented");};var wd=function(){M.call(this);this.oa=new W(this);pb&&(qb?this.oa.listen(rb?document.body:window,["online","offline"],this.wb):(this.Eb=pb?navigator.onLine:!0,this.h=new sd(250),this.oa.listen(this.h,"tick",this.oc),this.h.start()))};w(wd,M);wd.prototype.oc=function(){var a=pb?navigator.onLine:!0;a!=this.Eb&&(this.Eb=a,this.wb())};wd.prototype.wb=function(){this.dispatchEvent((pb?navigator.onLine:1)?"online":"offline")}; -wd.prototype.o=function(){wd.P.o.call(this);this.oa.ma();this.oa=null;this.h&&(this.h.ma(),this.h=null)};var xd=function(a,b){this.g=a;this.e=b};xd.prototype.send=function(a,b){b.set(Nc,gd(this.g));return this.e.send(a,b)};var yd=function(a){this.e=a};yd.prototype.send=function(a,b){zd(b);Ad(b);return this.e.send(a,b)};var zd=function(a){Xa(a,function(b,c){m(b.maxLength)&&"text"==b.valueType&&0<b.maxLength&&c.length>b.maxLength&&a.set(b,c.substring(0,b.maxLength))})},Ad=function(a){Xa(a,function(b,c){m(b.defaultValue)&&c==b.defaultValue&&a.remove(b)})};var Fc={status:"device-offline",la:void 0},Bd={status:"rate-limited",la:void 0},Cd={status:"sampled-out",la:void 0},Dd={status:"sent",la:void 0};var Ed=function(a,b){this.Vc=a;this.e=b};Ed.prototype.send=function(a,b){var c;c=this.Vc;var d=c.Lb(),e=Math.floor((d-c.Ab)*c.hc);0<e&&(c.$=Math.min(c.$+e,c.uc),c.Ab=d);1>c.$?c=!1:(--c.$,c=!0);return c||"item"==a||"transaction"==a?this.e.send(a,b):Ec(Bd)};var Fd=function(){this.$=60;this.uc=500;this.hc=5E-4;this.Lb=function(){return(new Date).getTime()};this.Ab=this.Lb()};var Gd=function(a,b){this.g=a;this.e=b};Gd.prototype.send=function(a,b){var c=b.get(Nc),c=parseInt(c.split("-")[1],16),d;"timing"!=a?d=kd(this.g):((d=b.get(Qc))&&b.remove(Qc),d=d||kd(this.g));return c<655.36*d?this.e.send(a,b):Ec(Cd)};var Hd=/^(?:([^:/?#.]+):)?(?:\/\/(?:([^/?#]*)@)?([^/#?]*?)(?::([0-9]+))?(?=[/#?]|$))?([^?#]+)?(?:\?([^#]*))?(?:#(.*))?$/,Jd=function(a){if(Id){Id=!1;var b=k.location;if(b){var c=b.href;if(c&&(c=(c=Jd(c)[3]||null)?decodeURI(c):c)&&c!=b.hostname)throw Id=!0,Error();}}return a.match(Hd)},Id=fb,Kd=function(a,b){for(var c=a.split("&"),d=0;d<c.length;d++){var e=c[d].indexOf("="),f=null,g=null;0<=e?(f=c[d].substring(0,e),g=c[d].substring(e+1)):f=c[d];b(f,g?decodeURIComponent(g.replace(/\+/g," ")):"")}};var Ld=function(){};Ld.prototype.nb=null;var Nd=function(a){var b;(b=a.nb)||(b={},Md(a)&&(b[0]=!0,b[1]=!0),b=a.nb=b);return b};var Od,Pd=function(){};w(Pd,Ld);var Qd=function(a){return(a=Md(a))?new ActiveXObject(a):new XMLHttpRequest},Md=function(a){if(!a.xb&&"undefined"==typeof XMLHttpRequest&&"undefined"!=typeof ActiveXObject){for(var b=["MSXML2.XMLHTTP.6.0","MSXML2.XMLHTTP.3.0","MSXML2.XMLHTTP","Microsoft.XMLHTTP"],c=0;c<b.length;c++){var d=b[c];try{return new ActiveXObject(d),a.xb=d}catch(e){}}throw Error("Could not create ActiveXObject. ActiveX might be disabled, or MSXML might not be installed");}return a.xb};Od=new Pd;var X=function(a){M.call(this);this.headers=new z;this.Ma=a||null;this.F=!1;this.La=this.a=null;this.za=this.$a="";this.N=this.Za=this.va=this.Ua=!1;this.Ha=0;this.Ga=null;this.Gb="";this.kb=this.Zc=!1};w(X,M);var Rd=/^https?$/i,Sd=["POST","PUT"],Td=[],Ud=function(a,b,c){var d=new X;Td.push(d);b&&d.listen("complete",b);d.cb("ready",d.bc);d.send(a,"POST",c,void 0)};X.prototype.bc=function(){this.ma();qa(Td,this)}; -X.prototype.send=function(a,b,c,d){if(this.a)throw Error("[goog.net.XhrIo] Object is active with another request="+this.$a+"; newUri="+a);b=b?b.toUpperCase():"GET";this.$a=a;this.za="";this.Ua=!1;this.F=!0;this.a=this.Ma?Qd(this.Ma):Qd(Od);this.La=this.Ma?Nd(this.Ma):Nd(Od);this.a.onreadystatechange=t(this.Db,this);try{this.Za=!0,this.a.open(b,String(a),!0),this.Za=!1}catch(e){this.na(5,e);return}a=c||"";var f=this.headers.clone();d&&Wa(d,function(a,b){f.set(b,a)});d=pa(f.H());c=k.FormData&&a instanceof -k.FormData;!(0<=ka(Sd,b))||d||c||f.set("Content-Type","application/x-www-form-urlencoded;charset=utf-8");f.forEach(function(a,b){this.a.setRequestHeader(b,a)},this);this.Gb&&(this.a.responseType=this.Gb);"withCredentials"in this.a&&(this.a.withCredentials=this.Zc);try{Vd(this),0<this.Ha&&((this.kb=Wd(this.a))?(this.a.timeout=this.Ha,this.a.ontimeout=t(this.Mb,this)):this.Ga=td(this.Mb,this.Ha,this)),this.va=!0,this.a.send(a),this.va=!1}catch(g){this.na(5,g)}}; -var Wd=function(a){return J&&K(9)&&ea(a.timeout)&&m(a.ontimeout)},oa=function(a){return"content-type"==a.toLowerCase()};X.prototype.Mb=function(){"undefined"!=typeof aa&&this.a&&(this.za="Timed out after "+this.Ha+"ms, aborting",this.dispatchEvent("timeout"),this.abort(8))};X.prototype.na=function(a,b){this.F=!1;this.a&&(this.N=!0,this.a.abort(),this.N=!1);this.za=b;Xd(this);Yd(this)};var Xd=function(a){a.Ua||(a.Ua=!0,a.dispatchEvent("complete"),a.dispatchEvent("error"))}; -X.prototype.abort=function(){this.a&&this.F&&(this.F=!1,this.N=!0,this.a.abort(),this.N=!1,this.dispatchEvent("complete"),this.dispatchEvent("abort"),Yd(this))};X.prototype.o=function(){this.a&&(this.F&&(this.F=!1,this.N=!0,this.a.abort(),this.N=!1),Yd(this,!0));X.P.o.call(this)};X.prototype.Db=function(){this.aa||(this.Za||this.va||this.N?Zd(this):this.wc())};X.prototype.wc=function(){Zd(this)}; -var Zd=function(a){if(a.F&&"undefined"!=typeof aa&&(!a.La[1]||4!=$d(a)||2!=ae(a)))if(a.va&&4==$d(a))td(a.Db,0,a);else if(a.dispatchEvent("readystatechange"),4==$d(a)){a.F=!1;try{var b=ae(a),c;a:switch(b){case 200:case 201:case 202:case 204:case 206:case 304:case 1223:c=!0;break a;default:c=!1}var d;if(!(d=c)){var e;if(e=0===b){var f=Jd(String(a.$a))[1]||null;if(!f&&self.location)var g=self.location.protocol,f=g.substr(0,g.length-1);e=!Rd.test(f?f.toLowerCase():"")}d=e}if(d)a.dispatchEvent("complete"), -a.dispatchEvent("success");else{var l;try{l=2<$d(a)?a.a.statusText:""}catch(D){l=""}a.za=l+" ["+ae(a)+"]";Xd(a)}}finally{Yd(a)}}},Yd=function(a,b){if(a.a){Vd(a);var c=a.a,d=a.La[0]?ba:null;a.a=null;a.La=null;b||a.dispatchEvent("ready");try{c.onreadystatechange=d}catch(e){}}},Vd=function(a){a.a&&a.kb&&(a.a.ontimeout=null);ea(a.Ga)&&(k.clearTimeout(a.Ga),a.Ga=null)},$d=function(a){return a.a?a.a.readyState:0},ae=function(a){try{return 2<$d(a)?a.a.status:-1}catch(b){return-1}};var be=function(a,b,c){this.r=a||null;this.qc=!!c},ce=function(a){a.c||(a.c=new z,a.j=0,a.r&&Kd(a.r,function(b,c){a.add(decodeURIComponent(b.replace(/\+/g," ")),c)}))};h=be.prototype;h.c=null;h.j=null;h.add=function(a,b){ce(this);this.r=null;a=de(this,a);var c=this.c.get(a);c||this.c.set(a,c=[]);c.push(b);this.j++;return this};h.remove=function(a){ce(this);a=de(this,a);return this.c.T(a)?(this.r=null,this.j-=this.c.get(a).length,this.c.remove(a)):!1};h.T=function(a){ce(this);a=de(this,a);return this.c.T(a)}; -h.H=function(){ce(this);for(var a=this.c.t(),b=this.c.H(),c=[],d=0;d<b.length;d++)for(var e=a[d],f=0;f<e.length;f++)c.push(b[d]);return c};h.t=function(a){ce(this);var b=[];if(p(a))this.T(a)&&(b=ra(b,this.c.get(de(this,a))));else{a=this.c.t();for(var c=0;c<a.length;c++)b=ra(b,a[c])}return b};h.set=function(a,b){ce(this);this.r=null;a=de(this,a);this.T(a)&&(this.j-=this.c.get(a).length);this.c.set(a,[b]);this.j++;return this}; -h.get=function(a,b){var c=a?this.t(a):[];return 0<c.length?String(c[0]):b};h.toString=function(){if(this.r)return this.r;if(!this.c)return"";for(var a=[],b=this.c.H(),c=0;c<b.length;c++)for(var d=b[c],e=encodeURIComponent(String(d)),d=this.t(d),f=0;f<d.length;f++){var g=e;""!==d[f]&&(g+="="+encodeURIComponent(String(d[f])));a.push(g)}return this.r=a.join("&")};h.clone=function(){var a=new be;a.r=this.r;this.c&&(a.c=this.c.clone(),a.j=this.j);return a}; -var de=function(a,b){var c=String(b);a.qc&&(c=c.toLowerCase());return c};var ee=function(a,b){this.Mc=a;this.Aa=b};ee.prototype.send=function(a,b){if(pb&&!navigator.onLine)return Gc();var c=new Q,d=fe(a,b);d.length>this.Aa?c.A({status:"payload-too-big",la:Ua("Encoded hit length == %s, but should be <= %s.",d.length,this.Aa)}):Ud(this.Mc,function(){c.v(Dd)},d);return c};var fe=function(a,b){var c=new be;c.add(Fa.name,a);Xa(b,function(a,b){c.add(a.name,b.toString())});return c.toString()};var ge=function(a,b,c){this.g=a;this.Lc=b;this.Aa=c};ge.prototype.Xa=function(){if(!this.q){if(!Ac(this.g.ea).C)throw Error("Cannot construct shared channel prior to settings being ready.");new wd;var a=new yd(new ee(this.Lc,this.Aa)),b=new Fd;this.q=new xd(this.g,new Gd(this.g,new Ed(b,a)))}return this.q};var he=new z,ie=function(){Da||(Da=new T(new ld));return Da};v("goog.async.Deferred",Q);v("goog.async.Deferred.prototype.addCallback",Q.prototype.n);v("goog.async.Deferred.prototype.callback",Q.prototype.v);v("goog.async.Deferred.prototype.then",Q.prototype.then);v("goog.events.EventTarget",M);v("goog.events.EventTarget.prototype.listen",M.prototype.listen); -v("analytics.getService",function(a,b){var c=he.get(a,null),d=b||chrome.runtime.getManifest().version;if(null===c){c=ie();if(!Ea){var e=ie();Ea=new rd(e,new ge(e,"https://www.google-analytics.com/collect",8192))}c=new Zc("ca1.6.0",a,d,c,Ea);he.set(a,c)}return c});v("analytics.internal.GoogleAnalyticsService",Zc);v("analytics.internal.GoogleAnalyticsService.prototype.getTracker",Zc.prototype.mc);v("analytics.internal.GoogleAnalyticsService.prototype.getConfig",Zc.prototype.kc); -v("analytics.internal.ServiceSettings",T);v("analytics.internal.ServiceSettings.prototype.setTrackingPermitted",T.prototype.Oc);v("analytics.internal.ServiceSettings.prototype.isTrackingPermitted",T.prototype.xa);v("analytics.internal.ServiceSettings.prototype.setSampleRate",T.prototype.Nc);v("analytics.internal.ServiceSettings.prototype.resetUserId",T.prototype.Fc);v("analytics.internal.ServiceTracker",S);v("analytics.internal.ServiceTracker.prototype.send",S.prototype.send); -v("analytics.internal.ServiceTracker.prototype.sendAppView",S.prototype.Hc);v("analytics.internal.ServiceTracker.prototype.sendEvent",S.prototype.Ic);v("analytics.internal.ServiceTracker.prototype.sendSocial",S.prototype.Kc);v("analytics.internal.ServiceTracker.prototype.sendException",S.prototype.Jc);v("analytics.internal.ServiceTracker.prototype.sendTiming",S.prototype.Ib);v("analytics.internal.ServiceTracker.prototype.startTiming",S.prototype.Rc);v("analytics.internal.ServiceTracker.Timing",Yc); -v("analytics.internal.ServiceTracker.Timing.prototype.send",Yc.prototype.send);v("analytics.internal.ServiceTracker.prototype.forceSessionStart",S.prototype.jc);v("analytics.internal.ServiceTracker.prototype.addFilter",S.prototype.R);v("analytics.internal.FilterChannel.Hit",R);v("analytics.internal.FilterChannel.Hit.prototype.getHitType",R.prototype.ub);v("analytics.internal.FilterChannel.Hit.prototype.getParameters",R.prototype.V);v("analytics.internal.FilterChannel.Hit.prototype.cancel",R.prototype.cancel); -v("analytics.ParameterMap",E);v("analytics.ParameterMap.Entry",E.Entry);v("analytics.ParameterMap.prototype.set",E.prototype.set);v("analytics.ParameterMap.prototype.get",E.prototype.get);v("analytics.ParameterMap.prototype.remove",E.prototype.remove);v("analytics.ParameterMap.prototype.toObject",E.prototype.Nb);v("analytics.HitTypes.APPVIEW","appview");v("analytics.HitTypes.EVENT","event");v("analytics.HitTypes.SOCIAL","social");v("analytics.HitTypes.TRANSACTION","transaction"); -v("analytics.HitTypes.ITEM","item");v("analytics.HitTypes.TIMING","timing");v("analytics.HitTypes.EXCEPTION","exception");va(Ma,function(a){var b=a.id.replace(/[A-Z]/,"_$&").toUpperCase();v("analytics.Parameters."+b,a)});v("analytics.filters.EventLabelerBuilder",C);v("analytics.filters.EventLabelerBuilder.prototype.appendToExistingLabel",C.prototype.Wb);v("analytics.filters.EventLabelerBuilder.prototype.stripValue",C.prototype.Sc);v("analytics.filters.EventLabelerBuilder.prototype.powersOfTwo",C.prototype.Dc); -v("analytics.filters.EventLabelerBuilder.prototype.rangeBounds",C.prototype.Ec);v("analytics.filters.EventLabelerBuilder.prototype.build",C.prototype.ia);v("analytics.filters.FilterBuilder",B);v("analytics.filters.FilterBuilder.builder",Ra);v("analytics.filters.FilterBuilder.prototype.when",B.prototype.when);v("analytics.filters.FilterBuilder.prototype.whenHitType",B.prototype.Rb);v("analytics.filters.FilterBuilder.prototype.whenValue",B.prototype.Yc); -v("analytics.filters.FilterBuilder.prototype.applyFilter",B.prototype.mb);v("analytics.filters.FilterBuilder.prototype.build",B.prototype.ia);v("analytics.EventBuilder",F);v("analytics.EventBuilder.builder",function(){return Ya});v("analytics.EventBuilder.prototype.category",F.prototype.Yb);v("analytics.EventBuilder.prototype.action",F.prototype.action);v("analytics.EventBuilder.prototype.label",F.prototype.label);v("analytics.EventBuilder.prototype.value",F.prototype.value); -v("analytics.EventBuilder.prototype.dimension",F.prototype.fc);v("analytics.EventBuilder.prototype.metric",F.prototype.vc);v("analytics.EventBuilder.prototype.send",F.prototype.send); }).call(this);
diff --git a/third_party/blink/perf_tests/canvas/resources/canvas_runner.js b/third_party/blink/perf_tests/canvas/resources/canvas_runner.js index 34843e8..f585f33 100644 --- a/third_party/blink/perf_tests/canvas/resources/canvas_runner.js +++ b/third_party/blink/perf_tests/canvas/resources/canvas_runner.js
@@ -1,98 +1,171 @@ -// CanvasRunner is a wrapper of PerformanceTests/resources/runner.js for canvas tests. +/* +Runs canvas performance tests to calculate runs/sec for test.doRun(). +This module works in two different ways, depending on requestAnimationFrame +(RAF). The query string `RAF` in the url determines which test is run. +*/ (function () { - var MEASURE_DRAW_TIMES = 50; - var MAX_MEASURE_DRAW_TIMES = 1000; - var MAX_MEASURE_TIME_PER_FRAME = 1000; // 1 sec - var currentTest = null; - var isTestDone = false; + var MEASURE_DRAW_TIMES = 50; + var MAX_MEASURE_DRAW_TIMES = 1000; + var MAX_MEASURE_TIME_PER_FRAME = 1000; // 1 sec + var IS_RAF_TEST = ( + document.location.search.substr(1,).toUpperCase() === "RAF"); + var currentTest = null; + var isTestDone = false; - var CanvasRunner = {}; + var CanvasRunner = {}; - CanvasRunner.start = function (test) { - PerfTestRunner.startMeasureValuesAsync({ - unit: 'runs/s', - description: test.description, - done: testDone, - run: function() { - if (!test.doRun) { - CanvasRunner.logFatalError("doRun must be set."); - return; - } - currentTest = test; - runTest(); - }}); - } - - function runTest() { - try { - if (currentTest.preRun) - currentTest.preRun(); - - var start = PerfTestRunner.now(); - var count = 0; - while ((PerfTestRunner.now() - start <= MAX_MEASURE_TIME_PER_FRAME) && (count * MEASURE_DRAW_TIMES < MAX_MEASURE_DRAW_TIMES)) { - for (var i = 0; i < MEASURE_DRAW_TIMES; i++) { - currentTest.doRun(); - } - count++; - } - if (currentTest.ensureComplete) - currentTest.ensureComplete(); - var elapsedTime = PerfTestRunner.now() - start; - if (currentTest.postRun) - currentTest.postRun(); - - PerfTestRunner.measureValueAsync(MEASURE_DRAW_TIMES * count * 1000 / elapsedTime); - } catch(err) { - CanvasRunner.logFatalError("test fails due to GPU issue. " + err); - return; + CanvasRunner.start = function (test) { + PerfTestRunner.startMeasureValuesAsync({ + unit: 'runs/s', + description: test.description, + done: testDone, + run: function() { + if (!test.doRun) { + CanvasRunner.logFatalError("doRun must be set."); + return; } + currentTest = test; + if (IS_RAF_TEST === true) { + runTestRAF(); + } else { + runTest(); + } + }}); + } - if (!isTestDone) - requestAnimationFrame(runTest); + // Times the CPU on the main thread + function runTest() { + try { + if (currentTest.preRun) + currentTest.preRun(); + + var start = PerfTestRunner.now(); + var count = 0; + while ((PerfTestRunner.now() - start <= MAX_MEASURE_TIME_PER_FRAME) && + (count * MEASURE_DRAW_TIMES < MAX_MEASURE_DRAW_TIMES)) { + for (var i = 0; i < MEASURE_DRAW_TIMES; i++) { + currentTest.doRun(); + } + count++; + } + if (currentTest.ensureComplete) + currentTest.ensureComplete(); + var elapsedTime = PerfTestRunner.now() - start; + if (currentTest.postRun) + currentTest.postRun(); + + let runsPerSecond = MEASURE_DRAW_TIMES * count * 1000 / elapsedTime; + PerfTestRunner.measureValueAsync(runsPerSecond); + } catch(err) { + CanvasRunner.logFatalError("test fails due to GPU issue. " + err); + throw err; } - function testDone() { - isTestDone = true; + if (!isTestDone) + requestAnimationFrame(runTest); + } + + // Times CPU + raster + GPU for draw calls, invoked with the ?RAF query string + // All times in milliseconds + function runTestRAF() { + // How long in ms we want each trial to take + // Must be much greater than 16 (16ms is the v-sync rate) + const GOAL_TIME = 200; + + function runTrial(numRuns) { + if (currentTest.preRun) currentTest.preRun(); + let startTime = PerfTestRunner.now(); + for (var i = 0; i < numRuns; i++) { + currentTest.doRun(); + } + requestAnimationFrame(() => { + let elapsedTime = PerfTestRunner.now() - startTime; + let runsPerSecond = numRuns * 1000 / elapsedTime; + PerfTestRunner.measureValueAsync(runsPerSecond); + if (!isTestDone) runTrial(numRuns, startTime); + }); + if (currentTest.ensureComplete) currentTest.ensureComplete(); + if (currentTest.postRun) currentTest.postRun(); } - CanvasRunner.logFatalError = function (text) { - PerfTestRunner.logFatalError(text); + // Figure out how many times currentTest.doRun() + RAF will be required + // to last GOAL_TIME + function calculateNumberOfRuns(resolve, numRuns) { + numRuns = numRuns || 1; + if (currentTest.preRun) currentTest.preRun(); + const startTime = PerfTestRunner.now(); + + for (var i = 0; i < numRuns; i++) { + currentTest.doRun(); + } + + requestAnimationFrame(() => { + let elapsedTime = PerfTestRunner.now() - startTime; + if (elapsedTime >= GOAL_TIME) { + const timePerRun = elapsedTime / numRuns; + const numRunsFinal = Math.round(GOAL_TIME / timePerRun); + if (currentTest.ensureComplete) currentTest.ensureComplete(); + if (currentTest.postRun) currentTest.postRun(); + resolve(numRunsFinal); + } else { + calculateNumberOfRuns(resolve, numRuns * 2); + } + }); } - CanvasRunner.startPlayingAndWaitForVideo = function (video, callback) { - var gotPlaying = false; - var gotTimeUpdate = false; - - var maybeCallCallback = function() { - if (gotPlaying && gotTimeUpdate && callback) { - callback(video); - callback = undefined; - video.removeEventListener('playing', playingListener, true); - video.removeEventListener('timeupdate', timeupdateListener, true); - } - }; - - var playingListener = function() { - gotPlaying = true; - maybeCallCallback(); - }; - - var timeupdateListener = function() { - // Checking to make sure the current time has advanced beyond - // the start time seems to be a reliable heuristic that the - // video element has data that can be consumed. - if (video.currentTime > 0.0) { - gotTimeUpdate = true; - maybeCallCallback(); - } - }; - - video.addEventListener('playing', playingListener, true); - video.addEventListener('timeupdate', timeupdateListener, true); - video.loop = true; - video.play(); + try { + new Promise(function(resolve, reject) { + calculateNumberOfRuns(resolve); + }).then(function(numberOfRuns) { + runTrial(numberOfRuns); + }); + } catch(err) { + CanvasRunner.logFatalError("test fails due to GPU issue. " + err); + throw err; } + } - window.CanvasRunner = CanvasRunner; + function testDone() { + isTestDone = true; + } + + CanvasRunner.logFatalError = function (text) { + PerfTestRunner.logFatalError(text); + } + + CanvasRunner.startPlayingAndWaitForVideo = function (video, callback) { + var gotPlaying = false; + var gotTimeUpdate = false; + + var maybeCallCallback = function() { + if (gotPlaying && gotTimeUpdate && callback) { + callback(video); + callback = undefined; + video.removeEventListener('playing', playingListener, true); + video.removeEventListener('timeupdate', timeupdateListener, true); + } + }; + + var playingListener = function() { + gotPlaying = true; + maybeCallCallback(); + }; + + var timeupdateListener = function() { + // Checking to make sure the current time has advanced beyond + // the start time seems to be a reliable heuristic that the + // video element has data that can be consumed. + if (video.currentTime > 0.0) { + gotTimeUpdate = true; + maybeCallCallback(); + } + }; + + video.addEventListener('playing', playingListener, true); + video.addEventListener('timeupdate', timeupdateListener, true); + video.loop = true; + video.play(); + } + + window.CanvasRunner = CanvasRunner; })();
diff --git a/third_party/blink/perf_tests/canvas/upload-webgl-to-texture.html b/third_party/blink/perf_tests/canvas/upload-webgl-to-texture.html index 07a2cf97..d36e4291 100644 --- a/third_party/blink/perf_tests/canvas/upload-webgl-to-texture.html +++ b/third_party/blink/perf_tests/canvas/upload-webgl-to-texture.html
@@ -12,7 +12,9 @@ if (!sourceCtx || !destCtx) CanvasRunner.logFatalError("WebGL is not supported or enabled on this platform!"); var tex = null; - +const width = 1024; +const height = 1024; + function setSize(width, height) { sourceCanvas3D.width = width; sourceCanvas3D.height = height; @@ -28,7 +30,7 @@ gl.disable(gl.SCISSOR_TEST); gl.clear(gl.COLOR_BUFER_BIT); gl.enable(gl.SCISSOR_TEST); - gl.scissor(rand(1024), rand(1024), rand(1024), rand(1024)); + gl.scissor(rand(width), rand(height), rand(width), rand(height)); gl.clearColor(Math.random(), Math.random(), Math.random(), 1); gl.clear(gl.COLOR_BUFFER_BIT); } @@ -51,7 +53,7 @@ } window.onload = function () { - setSize(1024, 1024); + setSize(width, height); renderWebGL(sourceCtx); CanvasRunner.start({ description: "This benchmark checks the speed on uploading WebGL(1024x1024) to WebGL Texture(1024x1024).",
diff --git a/third_party/blink/public/BUILD.gn b/third_party/blink/public/BUILD.gn index 91496a97..52416c8 100644 --- a/third_party/blink/public/BUILD.gn +++ b/third_party/blink/public/BUILD.gn
@@ -455,6 +455,7 @@ "web/web_memory_statistics.h", "web/web_menu_item_info.h", "web/web_meta_element.h", + "web/web_navigation_control.h", "web/web_navigation_params.h", "web/web_navigation_policy.h", "web/web_navigation_type.h",
diff --git a/third_party/blink/public/mojom/quota/quota_dispatcher_host.mojom b/third_party/blink/public/mojom/quota/quota_dispatcher_host.mojom index 26b04e4c..e778a80b 100644 --- a/third_party/blink/public/mojom/quota/quota_dispatcher_host.mojom +++ b/third_party/blink/public/mojom/quota/quota_dispatcher_host.mojom
@@ -23,7 +23,8 @@ blink.mojom.StorageType storage_type) => (blink.mojom.QuotaStatusCode error, int64 current_usage, - int64 current_quota); + int64 current_quota, + UsageBreakdown usage_breakdown); // Renderer process requests a new quota size for the origin's storage from // the browser process. |requested_size| indicates how much storage space (in
diff --git a/third_party/blink/public/mojom/quota/quota_types.mojom b/third_party/blink/public/mojom/quota/quota_types.mojom index c000867a..77f41e0 100644 --- a/third_party/blink/public/mojom/quota/quota_types.mojom +++ b/third_party/blink/public/mojom/quota/quota_types.mojom
@@ -21,3 +21,13 @@ kErrorAbort = 20, // ABORT_ERR kUnknown = -1, }; + +struct UsageBreakdown { + int64 fileSystem = 0; + int64 webSql = 0; + int64 appcache = 0; + int64 indexedDatabase = 0; + int64 serviceWorkerCache = 0; + int64 serviceWorker = 0; + int64 backgroundFetch = 0; +};
diff --git a/third_party/blink/public/mojom/shared_worker/OWNERS b/third_party/blink/public/mojom/shared_worker/OWNERS index a9e7183..e1abbf3 100644 --- a/third_party/blink/public/mojom/shared_worker/OWNERS +++ b/third_party/blink/public/mojom/shared_worker/OWNERS
@@ -1,4 +1,4 @@ -file://content/browser/shared_worker/OWNERS +file://content/browser/worker_host/OWNERS per-file *.mojom=set noparent per-file *.mojom=file://ipc/SECURITY_OWNERS
diff --git a/third_party/blink/public/web/web_local_frame.h b/third_party/blink/public/web/web_local_frame.h index 449a339..4b680e1b 100644 --- a/third_party/blink/public/web/web_local_frame.h +++ b/third_party/blink/public/web/web_local_frame.h
@@ -9,7 +9,6 @@ #include <set> #include "base/callback.h" -#include "base/unguessable_token.h" #include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h" #include "third_party/blink/public/common/feature_policy/feature_policy.h" #include "third_party/blink/public/common/frame/sandbox_flags.h" @@ -24,7 +23,6 @@ #include "third_party/blink/public/web/web_document_loader.h" #include "third_party/blink/public/web/web_frame.h" #include "third_party/blink/public/web/web_frame_load_type.h" -#include "third_party/blink/public/web/web_history_item.h" #include "third_party/blink/public/web/web_ime_text_span.h" #include "third_party/blink/public/web/web_navigation_params.h" #include "third_party/blink/public/web/web_text_direction.h" @@ -37,7 +35,6 @@ class WebAssociatedURLLoader; class WebAutofillClient; class WebContentSettingsClient; -class WebData; class WebDocument; class WebDoubleSize; class WebDOMEvent; @@ -58,8 +55,8 @@ struct WebAssociatedURLLoaderOptions; struct WebConsoleMessage; struct WebContentSecurityPolicyViolation; -struct WebNavigationParams; struct WebMediaPlayerAction; +struct WebPoint; struct WebPrintParams; struct WebPrintPresetOptions; struct WebScriptSource; @@ -193,11 +190,6 @@ // Navigation ---------------------------------------------------------- - // Runs beforeunload handlers for this frame and returns the value returned - // by handlers. - // Note: this may lead to the destruction of the frame. - virtual bool DispatchBeforeUnloadEvent(bool is_reload) = 0; - // Start reloading the current document. // Note: StartReload() will be deprecated, use StartNavigation() instead. virtual void StartReload(WebFrameLoadType) = 0; @@ -205,62 +197,8 @@ // Start navigation to the given URL. virtual void StartNavigation(const WebURLRequest&) = 0; - // Commits a cross-document navigation in the frame. For history navigations, - // a valid WebHistoryItem should be provided. - // TODO(dgozman): return mojom::CommitResult. - virtual void CommitNavigation( - const WebURLRequest&, - WebFrameLoadType, - const WebHistoryItem&, - bool is_client_redirect, - const base::UnguessableToken& devtools_navigation_token, - std::unique_ptr<WebNavigationParams> navigation_params, - std::unique_ptr<WebDocumentLoader::ExtraData> extra_data) = 0; - - // Commits a same-document navigation in the frame. For history navigations, a - // valid WebHistoryItem should be provided. Returns CommitResult::Ok if the - // navigation has actually committed. - virtual mojom::CommitResult CommitSameDocumentNavigation( - const WebURL&, - WebFrameLoadType, - const WebHistoryItem&, - bool is_client_redirect, - std::unique_ptr<WebDocumentLoader::ExtraData> extra_data) = 0; - - // Loads a JavaScript URL in the frame. - virtual void LoadJavaScriptURL(const WebURL&) = 0; - - // This method is short-hand for calling CommitDataNavigation, where mime_type - // is "text/html" and text_encoding is "UTF-8". - // TODO(dgozman): rename to CommitHTMLStringNavigation. - virtual void LoadHTMLString(const WebData& html, - const WebURL& base_url, - const WebURL& unreachable_url = WebURL()) = 0; - - // Navigates to the given |data| with specified |mime_type| and optional - // |text_encoding|. - // - // If specified, |unreachable_url| is reported via - // WebDocumentLoader::UnreachableURL. - // - // If |replace| is false, then this data will be loaded as a normal - // navigation. Otherwise, the current history item will be replaced. - // - // Request's url indicates the security origin and is used as a base - // url to resolve links in the committed document. - virtual void CommitDataNavigation( - const WebURLRequest&, - const WebData&, - const WebString& mime_type, - const WebString& text_encoding, - const WebURL& unreachable_url, - WebFrameLoadType, - const WebHistoryItem&, - bool is_client_redirect, - std::unique_ptr<WebNavigationParams> navigation_params, - std::unique_ptr<WebDocumentLoader::ExtraData> navigation_data) = 0; - // Returns the document loader that is currently loading. May be null. + // TODO(dgozman): move this to WebNavigationControl. virtual WebDocumentLoader* GetProvisionalDocumentLoader() const = 0; // View-source rendering mode. Set this before loading an URL to cause @@ -271,23 +209,6 @@ // Returns the document loader that is currently loaded. virtual WebDocumentLoader* GetDocumentLoader() const = 0; - enum FallbackContentResult { - // An error page should be shown instead of fallback. - NoFallbackContent, - // Something else committed, no fallback content or error page needed. - NoLoadInProgress, - // Fallback content rendered, no error page needed. - FallbackRendered - }; - // On load failure, attempts to make frame's parent render fallback content. - virtual FallbackContentResult MaybeRenderFallbackContent( - const WebURLError&) const = 0; - - // When load failure is in a cross-process frame this notifies the frame here - // that its owner should render fallback content if any. Only called on owners - // that render their own content (i.e., <object>). - virtual void RenderFallbackContent() const = 0; - // Called when a navigation is blocked because a Content Security Policy (CSP) // is infringed. virtual void ReportContentSecurityPolicyViolation( @@ -317,11 +238,6 @@ virtual bool IsNavigationScheduledWithin( double interval_in_seconds) const = 0; - // Override the normal rules for whether a load has successfully committed - // in this frame. Used to propagate state when this frame has navigated - // cross process. - virtual void SetCommittedFirstRealLoad() = 0; - // Reports a list of unique blink::WebFeature values representing // Blink features used, performed or encountered by the browser during the // current page load happening on the frame. @@ -338,28 +254,6 @@ bool had_redirect, const WebSourceLocation&) = 0; - // Informs the frame that the navigation it asked the client to do was - // dropped. - virtual void ClientDroppedNavigation() = 0; - - // Marks the frame as loading, without performing any loading. Used for - // initial history navigations in child frames, which may actually happen - // in the other process. - virtual void MarkAsLoading() = 0; - - // Marks the frame as loading and creates a placeholder document loader. - // This placeholder informs Blink that the navigation is ongoing, while it - // is actually being handled by the client. - // TODO(dgozman): remove this together with placeholder document loader. - virtual bool CreatePlaceholderDocumentLoader( - const WebURLRequest&, - WebFrameLoadType, - WebNavigationType, - bool is_client_redirect, - const base::UnguessableToken& devtools_navigation_token, - std::unique_ptr<WebNavigationParams>, - std::unique_ptr<WebDocumentLoader::ExtraData>) = 0; - // Orientation Changes ---------------------------------------------------- // Notify the frame that the screen orientation has changed.
diff --git a/third_party/blink/public/web/web_local_frame_client.h b/third_party/blink/public/web/web_local_frame_client.h index e8f1ba9..2a46b3fab 100644 --- a/third_party/blink/public/web/web_local_frame_client.h +++ b/third_party/blink/public/web/web_local_frame_client.h
@@ -104,6 +104,7 @@ class WebMediaPlayerClient; class WebMediaPlayerEncryptedMediaClient; class WebMediaPlayerSource; +class WebNavigationControl; class WebServiceWorkerProvider; class WebPlugin; class WebPushClient; @@ -131,8 +132,9 @@ // Initialization ------------------------------------------------------ // Called exactly once during construction to notify the client about the // created WebLocalFrame. Guaranteed to be invoked before any other - // WebLocalFrameClient callbacks. - virtual void BindToFrame(WebLocalFrame*) {} + // WebLocalFrameClient callbacks. Note this takes WebNavigationControl + // to give the client full control over frame's navigation. + virtual void BindToFrame(WebNavigationControl*) {} // Factory methods ----------------------------------------------------- @@ -332,14 +334,15 @@ // Requests the client to begin a navigation for this frame. // - // The client can just call CommitNavigation() on this frame in response. - // This will effectively commit a navigation the frame has asked about. - // This usually happens for navigations which do not require a network - // request, e.g. about:blank or mhtml archive. + // The client can just call CommitNavigation() on this frame's + // WebNavigationControl in response. This will effectively commit a navigation + // the frame has asked about. This usually happens for navigations which + // do not require a network request, e.g. about:blank or mhtml archive. // // In the case of a navigation which requires network request and goes // to the browser process, client calls CreatePlaceholderDocumentLoader - // (see it for more details) and commits/cancels the navigation later. + // (see WebNavigationControl for more details) and commits/cancels + // the navigation later. // // It is also totally valid to ignore the request and abandon the // navigation entirely.
diff --git a/third_party/blink/public/web/web_navigation_control.h b/third_party/blink/public/web/web_navigation_control.h new file mode 100644 index 0000000..5c51fae --- /dev/null +++ b/third_party/blink/public/web/web_navigation_control.h
@@ -0,0 +1,147 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_NAVIGATION_CONTROL_H_ +#define THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_NAVIGATION_CONTROL_H_ + +#include <memory> + +#include "base/unguessable_token.h" +#include "third_party/blink/public/web/web_document_loader.h" +#include "third_party/blink/public/web/web_frame_load_type.h" +#include "third_party/blink/public/web/web_local_frame.h" + +namespace blink { + +class WebData; +class WebString; +class WebURL; +struct WebURLError; +class WebURLRequest; +class WebHistoryItem; +struct WebNavigationParams; + +// This interface gives control to navigation-related functionality of +// WebLocalFrame. It is separated from WebLocalFrame to give precise control +// over callers of navigation methods. +// WebLocalFrameClient gets a reference to this interface in BindToFrame. +class WebNavigationControl : public WebLocalFrame { + public: + ~WebNavigationControl() override {} + + // Runs beforeunload handlers for this frame and its local descendants. + // Returns |true| if all the frames agreed to proceed with unloading + // from their respective event handlers. + // Note: this may lead to the destruction of the frame. + virtual bool DispatchBeforeUnloadEvent(bool is_reload) = 0; + + // Commits a cross-document navigation in the frame. For history navigations, + // a valid WebHistoryItem should be provided. + // TODO(dgozman): return mojom::CommitResult. + virtual void CommitNavigation( + const WebURLRequest&, + WebFrameLoadType, + const WebHistoryItem&, + bool is_client_redirect, + const base::UnguessableToken& devtools_navigation_token, + std::unique_ptr<WebNavigationParams> navigation_params, + std::unique_ptr<WebDocumentLoader::ExtraData> extra_data) = 0; + + // Commits a same-document navigation in the frame. For history navigations, a + // valid WebHistoryItem should be provided. Returns CommitResult::Ok if the + // navigation has actually committed. + virtual mojom::CommitResult CommitSameDocumentNavigation( + const WebURL&, + WebFrameLoadType, + const WebHistoryItem&, + bool is_client_redirect, + std::unique_ptr<WebDocumentLoader::ExtraData> extra_data) = 0; + + // Loads a JavaScript URL in the frame. + // TODO(dgozman): this may replace the document, so perhaps we should + // return something meaningful? + virtual void LoadJavaScriptURL(const WebURL&) = 0; + + // This method is short-hand for calling CommitDataNavigation, where mime_type + // is "text/html" and text_encoding is "UTF-8". + // TODO(dgozman): rename to CommitHTMLStringNavigation. + virtual void LoadHTMLString(const WebData& html, + const WebURL& base_url, + const WebURL& unreachable_url = WebURL()) = 0; + + // Navigates to the given |data| with specified |mime_type| and optional + // |text_encoding|. + // + // If specified, |unreachable_url| is reported via + // WebDocumentLoader::UnreachableURL. + // + // If |replace| is false, then this data will be loaded as a normal + // navigation. Otherwise, the current history item will be replaced. + // + // Request's url indicates the security origin and is used as a base + // url to resolve links in the committed document. + virtual void CommitDataNavigation( + const WebURLRequest&, + const WebData&, + const WebString& mime_type, + const WebString& text_encoding, + const WebURL& unreachable_url, + WebFrameLoadType, + const WebHistoryItem&, + bool is_client_redirect, + std::unique_ptr<WebNavigationParams> navigation_params, + std::unique_ptr<WebDocumentLoader::ExtraData> navigation_data) = 0; + + enum FallbackContentResult { + // An error page should be shown instead of fallback. + NoFallbackContent, + // Something else committed, no fallback content or error page needed. + NoLoadInProgress, + // Fallback content rendered, no error page needed. + FallbackRendered + }; + // On load failure, attempts to make frame's parent render fallback content. + virtual FallbackContentResult MaybeRenderFallbackContent( + const WebURLError&) const = 0; + + // When load failure is in a cross-process frame this notifies the frame here + // that its owner should render fallback content if any. Only called on owners + // that render their own content (i.e., <object>). + virtual void RenderFallbackContent() const = 0; + + // Override the normal rules for whether a load has successfully committed + // in this frame. Used to propagate state when this frame has navigated + // cross process. + virtual void SetCommittedFirstRealLoad() = 0; + + // Informs the frame that the navigation it asked the client to do was + // dropped. + virtual void ClientDroppedNavigation() = 0; + + // Marks the frame as loading, without performing any loading. Used for + // initial history navigations in child frames, which may actually happen + // in another process. + virtual void MarkAsLoading() = 0; + + // Marks the frame as loading and creates a placeholder document loader. + // This placeholder informs Blink that the navigation is ongoing, while it + // is actually being handled by the client. + // TODO(dgozman): remove this together with placeholder document loader. + virtual bool CreatePlaceholderDocumentLoader( + const WebURLRequest&, + WebFrameLoadType, + WebNavigationType, + bool is_client_redirect, + const base::UnguessableToken& devtools_navigation_token, + std::unique_ptr<WebNavigationParams>, + std::unique_ptr<WebDocumentLoader::ExtraData>) = 0; + + protected: + explicit WebNavigationControl(WebTreeScopeType scope) + : WebLocalFrame(scope) {} +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_NAVIGATION_CONTROL_H_
diff --git a/third_party/blink/renderer/bindings/core/v8/custom/v8_window_custom.cc b/third_party/blink/renderer/bindings/core/v8/custom/v8_window_custom.cc index b084da30..cc746be 100644 --- a/third_party/blink/renderer/bindings/core/v8/custom/v8_window_custom.cc +++ b/third_party/blink/renderer/bindings/core/v8/custom/v8_window_custom.cc
@@ -58,7 +58,6 @@ #include "third_party/blink/renderer/platform/bindings/exception_messages.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/bindings/v8_private_property.h" -#include "third_party/blink/renderer/platform/layout_test_support.h" #include "third_party/blink/renderer/platform/wtf/assertions.h" namespace blink {
diff --git a/third_party/blink/renderer/build/scripts/templates/origin_trials.h.tmpl b/third_party/blink/renderer/build/scripts/templates/origin_trials.h.tmpl index b1ffe33..7f4ff3b 100644 --- a/third_party/blink/renderer/build/scripts/templates/origin_trials.h.tmpl +++ b/third_party/blink/renderer/build/scripts/templates/origin_trials.h.tmpl
@@ -11,6 +11,11 @@ #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" #include "third_party/blink/renderer/platform/wtf/vector.h" +#define ASSERT_ORIGIN_TRIAL(feature) \ +static_assert(std::is_same<decltype(::blink::origin_trials::feature##Enabled(\ + nullptr)), bool>(), \ + #feature " must be part of an origin trial"); + namespace blink { class ExecutionContext;
diff --git a/third_party/blink/renderer/core/css/parser/css_parser_fast_paths_fuzzer.cc b/third_party/blink/renderer/core/css/parser/css_parser_fast_paths_fuzzer.cc index b6174c1..7d1c0e3 100644 --- a/third_party/blink/renderer/core/css/parser/css_parser_fast_paths_fuzzer.cc +++ b/third_party/blink/renderer/core/css/parser/css_parser_fast_paths_fuzzer.cc
@@ -18,7 +18,7 @@ blink::FuzzedDataProvider provider(data, size); const auto property_id = - blink::convertToCSSPropertyID(provider.ConsumeInt32InRange( + blink::convertToCSSPropertyID(provider.ConsumeIntegralInRange<int>( blink::firstCSSProperty, blink::lastCSSProperty)); const auto data_string = provider.ConsumeRemainingBytes();
diff --git a/third_party/blink/renderer/core/editing/frame_caret_test.cc b/third_party/blink/renderer/core/editing/frame_caret_test.cc index 789bde3..44f12350 100644 --- a/third_party/blink/renderer/core/editing/frame_caret_test.cc +++ b/third_party/blink/renderer/core/editing/frame_caret_test.cc
@@ -11,21 +11,21 @@ #include "third_party/blink/renderer/core/frame/local_frame_view.h" #include "third_party/blink/renderer/core/layout/layout_theme.h" #include "third_party/blink/renderer/core/page/focus_controller.h" -#include "third_party/blink/renderer/platform/layout_test_support.h" #include "third_party/blink/renderer/platform/scheduler/test/fake_task_runner.h" +#include "third_party/blink/renderer/platform/web_test_support.h" namespace blink { class FrameCaretTest : public EditingTestBase { public: FrameCaretTest() - : was_running_layout_test_(LayoutTestSupport::IsRunningLayoutTest()) { - // The caret blink timer doesn't work if isRunningLayoutTest() because - // LayoutTheme::caretBlinkInterval() returns 0. - LayoutTestSupport::SetIsRunningLayoutTest(false); + : was_running_layout_test_(WebTestSupport::IsRunningWebTest()) { + // The caret blink timer doesn't work if IsRunningWebTest() because + // LayoutTheme::CaretBlinkInterval() returns 0. + WebTestSupport::SetIsRunningWebTest(false); } ~FrameCaretTest() override { - LayoutTestSupport::SetIsRunningLayoutTest(was_running_layout_test_); + WebTestSupport::SetIsRunningWebTest(was_running_layout_test_); } static bool ShouldBlinkCaret(const FrameCaret& caret) {
diff --git a/third_party/blink/renderer/core/exported/web_dev_tools_agent_impl.cc b/third_party/blink/renderer/core/exported/web_dev_tools_agent_impl.cc index 1a579cf..af0b1c6d 100644 --- a/third_party/blink/renderer/core/exported/web_dev_tools_agent_impl.cc +++ b/third_party/blink/renderer/core/exported/web_dev_tools_agent_impl.cc
@@ -86,7 +86,6 @@ #include "third_party/blink/renderer/platform/graphics/graphics_context.h" #include "third_party/blink/renderer/platform/graphics/paint/paint_controller.h" #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h" -#include "third_party/blink/renderer/platform/layout_test_support.h" #include "third_party/blink/renderer/platform/web_task_runner.h" #include "third_party/blink/renderer/platform/wtf/math_extras.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
diff --git a/third_party/blink/renderer/core/exported/web_frame_test.cc b/third_party/blink/renderer/core/exported/web_frame_test.cc index 31c018f..6a958b1 100644 --- a/third_party/blink/renderer/core/exported/web_frame_test.cc +++ b/third_party/blink/renderer/core/exported/web_frame_test.cc
@@ -2228,8 +2228,7 @@ EXPECT_EQ(0, child_document->FirstBodyElement()->GetIntegralAttribute( html_names::kMarginheightAttr)); - LocalFrameView* frame_view = - static_cast<WebLocalFrameImpl*>(local_frame)->GetFrameView(); + LocalFrameView* frame_view = local_frame->GetFrameView(); EXPECT_EQ(nullptr, frame_view->LayoutViewport()->HorizontalScrollbar()); EXPECT_EQ(nullptr, frame_view->LayoutViewport()->VerticalScrollbar()); } @@ -5144,7 +5143,7 @@ main_frame->EnsureTextFinder().ResetMatchCount(); for (WebLocalFrameImpl* frame = main_frame; frame; - frame = static_cast<WebLocalFrameImpl*>(frame->TraverseNext())) { + frame = ToWebLocalFrameImpl(frame->TraverseNext())) { frame->EnsureTextFinder().StartScopingStringMatches(kFindIdentifier, search_text, *options); } @@ -5216,7 +5215,7 @@ main_frame->EnsureTextFinder().ResetMatchCount(); for (WebLocalFrameImpl* frame = main_frame; frame; - frame = static_cast<WebLocalFrameImpl*>(frame->TraverseNext())) { + frame = ToWebLocalFrameImpl(frame->TraverseNext())) { frame->EnsureTextFinder().StartScopingStringMatches(kFindIdentifier, search_text, *options); } @@ -5228,7 +5227,7 @@ mojom::StopFindAction::kStopFindActionClearSelection); for (WebLocalFrameImpl* frame = main_frame; frame; - frame = static_cast<WebLocalFrameImpl*>(frame->TraverseNext())) { + frame = ToWebLocalFrameImpl(frame->TraverseNext())) { frame->EnsureTextFinder().StartScopingStringMatches(kFindIdentifier, search_text, *options); } @@ -5245,7 +5244,7 @@ main_frame->EnsureTextFinder().ResetMatchCount(); for (WebLocalFrameImpl* frame = main_frame; frame; - frame = static_cast<WebLocalFrameImpl*>(frame->TraverseNext())) { + frame = ToWebLocalFrameImpl(frame->TraverseNext())) { frame->EnsureTextFinder().StartScopingStringMatches( kFindIdentifier, search_text_new, *options); } @@ -5293,7 +5292,7 @@ main_frame->EnsureTextFinder().ResetMatchCount(); for (WebLocalFrameImpl* frame = main_frame; frame; - frame = static_cast<WebLocalFrameImpl*>(frame->TraverseNext())) { + frame = ToWebLocalFrameImpl(frame->TraverseNext())) { frame->EnsureTextFinder().StartScopingStringMatches(kFindIdentifier, search_text, *options); } @@ -5324,7 +5323,7 @@ find_in_page_client.SetFrame(main_frame); for (WebLocalFrameImpl* frame = main_frame; frame; - frame = static_cast<WebLocalFrameImpl*>(frame->TraverseNext())) { + frame = ToWebLocalFrameImpl(frame->TraverseNext())) { EXPECT_TRUE(frame->GetFindInPage()->FindInternal( kFindIdentifier, search_text, *options, false)); } @@ -5337,7 +5336,7 @@ main_frame->EnsureTextFinder().ResetMatchCount(); for (WebLocalFrameImpl* frame = main_frame; frame; - frame = static_cast<WebLocalFrameImpl*>(frame->TraverseNext())) { + frame = ToWebLocalFrameImpl(frame->TraverseNext())) { frame->EnsureTextFinder().StartScopingStringMatches(kFindIdentifier, search_text, *options); } @@ -5368,7 +5367,7 @@ find_in_page_client.SetFrame(main_frame); for (WebLocalFrameImpl* frame = main_frame; frame; - frame = static_cast<WebLocalFrameImpl*>(frame->TraverseNext())) { + frame = ToWebLocalFrameImpl(frame->TraverseNext())) { EXPECT_TRUE(frame->GetFindInPage()->FindInternal( kFindIdentifier, search_text, *options, false)); } @@ -5378,7 +5377,7 @@ main_frame->EnsureTextFinder().ResetMatchCount(); for (WebLocalFrameImpl* frame = main_frame; frame; - frame = static_cast<WebLocalFrameImpl*>(frame->TraverseNext())) { + frame = ToWebLocalFrameImpl(frame->TraverseNext())) { frame->EnsureTextFinder().StartScopingStringMatches(kFindIdentifier, search_text, *options); } @@ -5388,7 +5387,7 @@ RemoveElementById(main_frame, "frame"); for (WebLocalFrameImpl* frame = main_frame; frame; - frame = static_cast<WebLocalFrameImpl*>(frame->TraverseNext())) { + frame = ToWebLocalFrameImpl(frame->TraverseNext())) { frame->EnsureTextFinder().StartScopingStringMatches(kFindIdentifier, search_text, *options); } @@ -5420,7 +5419,7 @@ EXPECT_TRUE(!!main_frame->TraverseNext()); for (WebLocalFrameImpl* frame = main_frame; frame; - frame = static_cast<WebLocalFrameImpl*>(frame->TraverseNext())) { + frame = ToWebLocalFrameImpl(frame->TraverseNext())) { EXPECT_FALSE(frame->GetFindInPage()->FindInternal( kFindIdentifier, search_text, *options, false)); } @@ -9635,7 +9634,7 @@ ASSERT_EQ(MainFrame()->FirstChild(), remote_frame); RemoteToLocalSwapWebFrameClient client(remote_frame); - WebLocalFrame* local_frame = + WebLocalFrameImpl* local_frame = frame_test_helpers::CreateProvisional(*remote_frame, &client); local_frame->SetCommittedFirstRealLoad(); frame_test_helpers::LoadFrame(local_frame, base_url_ + "subframe-hello.html"); @@ -12551,9 +12550,9 @@ // content shouldn't crash. It should return NoLoadInProgress. This is so the // caller won't attempt to replace the correctly empty frame with an error // page. - EXPECT_EQ( - WebLocalFrame::NoLoadInProgress, - child->MaybeRenderFallbackContent(ResourceError::Failure(request.Url()))); + EXPECT_EQ(WebNavigationControl::NoLoadInProgress, + ToWebLocalFrameImpl(child)->MaybeRenderFallbackContent( + ResourceError::Failure(request.Url()))); } TEST_F(WebFrameTest, AltTextOnAboutBlankPage) {
diff --git a/third_party/blink/renderer/core/exported/web_page_popup_impl.cc b/third_party/blink/renderer/core/exported/web_page_popup_impl.cc index c7bd80c..7580b4f 100644 --- a/third_party/blink/renderer/core/exported/web_page_popup_impl.cc +++ b/third_party/blink/renderer/core/exported/web_page_popup_impl.cc
@@ -65,7 +65,7 @@ #include "third_party/blink/renderer/platform/graphics/graphics_layer.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h" -#include "third_party/blink/renderer/platform/layout_test_support.h" +#include "third_party/blink/renderer/platform/web_test_support.h" namespace blink { @@ -127,7 +127,7 @@ void ScheduleAnimation(const LocalFrameView*) override { // Calling scheduleAnimation on m_webView so WebViewTestProxy will call // beginFrame. - if (LayoutTestSupport::IsRunningLayoutTest()) { + if (WebTestSupport::IsRunningWebTest()) { popup_->web_view_->MainFrameImpl() ->FrameWidgetImpl() ->ScheduleAnimation();
diff --git a/third_party/blink/renderer/core/exported/web_view_test.cc b/third_party/blink/renderer/core/exported/web_view_test.cc index ce892e10..0776bb4 100644 --- a/third_party/blink/renderer/core/exported/web_view_test.cc +++ b/third_party/blink/renderer/core/exported/web_view_test.cc
@@ -4565,7 +4565,7 @@ { frame->ExecuteScript( WebScriptSource("addEventListener('beforeunload', function() {});")); - web_view->MainFrame()->ToWebLocalFrame()->DispatchBeforeUnloadEvent(false); + web_view->MainFrameImpl()->DispatchBeforeUnloadEvent(false); EXPECT_FALSE(UseCounter::IsCounted(*document, WebFeature::kSubFrameBeforeUnloadFired)); } @@ -4576,9 +4576,7 @@ frame->ExecuteScript(WebScriptSource( "document.getElementsByTagName('iframe')[0].contentWindow." "addEventListener('beforeunload', function() {});")); - web_view->MainFrame() - ->FirstChild() - ->ToWebLocalFrame() + ToWebLocalFrameImpl(web_view->MainFrame()->FirstChild()->ToWebLocalFrame()) ->DispatchBeforeUnloadEvent(false); Document* child_document = ToLocalFrame(web_view_helper_.GetWebView()
diff --git a/third_party/blink/renderer/core/feature_policy/feature_policy.cc b/third_party/blink/renderer/core/feature_policy/feature_policy.cc index 190a1c41..c3ec251 100644 --- a/third_party/blink/renderer/core/feature_policy/feature_policy.cc +++ b/third_party/blink/renderer/core/feature_policy/feature_policy.cc
@@ -7,6 +7,7 @@ #include "base/metrics/histogram_macros.h" #include "third_party/blink/renderer/core/dom/document.h" +#include "third_party/blink/renderer/core/origin_trials/origin_trials.h" #include "third_party/blink/renderer/platform/json/json_values.h" #include "third_party/blink/renderer/platform/network/http_parsers.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" @@ -272,6 +273,8 @@ mojom::FeaturePolicyFeature::kSyncXHR); // Under origin trial: Should be made conditional on WebVR and WebXR // runtime flags once it is out of trial. + ASSERT_ORIGIN_TRIAL(WebVR); + ASSERT_ORIGIN_TRIAL(WebXR); default_feature_name_map.Set("vr", mojom::FeaturePolicyFeature::kWebVr); if (RuntimeEnabledFeatures::ExperimentalProductivityFeaturesEnabled()) { default_feature_name_map.Set(
diff --git a/third_party/blink/renderer/core/frame/frame_test_helpers.cc b/third_party/blink/renderer/core/frame/frame_test_helpers.cc index d0cc186..27c7728 100644 --- a/third_party/blink/renderer/core/frame/frame_test_helpers.cc +++ b/third_party/blink/renderer/core/frame/frame_test_helpers.cc
@@ -113,11 +113,12 @@ } // namespace void LoadFrame(WebLocalFrame* frame, const std::string& url) { + WebLocalFrameImpl* impl = ToWebLocalFrameImpl(frame); WebURL web_url(url_test_helpers::ToKURL(url)); if (web_url.ProtocolIs("javascript")) { - frame->LoadJavaScriptURL(web_url); + impl->LoadJavaScriptURL(web_url); } else { - frame->CommitNavigation( + impl->CommitNavigation( WebURLRequest(web_url), blink::WebFrameLoadType::kStandard, blink::WebHistoryItem(), false, base::UnguessableToken::Create(), BuildDummyNavigationParams(), nullptr /* extra_data */); @@ -128,15 +129,17 @@ void LoadHTMLString(WebLocalFrame* frame, const std::string& html, const WebURL& base_url) { - frame->LoadHTMLString(WebData(html.data(), html.size()), base_url); + WebLocalFrameImpl* impl = ToWebLocalFrameImpl(frame); + impl->LoadHTMLString(WebData(html.data(), html.size()), base_url, WebURL()); PumpPendingRequestsForFrameToLoad(frame); } void LoadHistoryItem(WebLocalFrame* frame, const WebHistoryItem& item, mojom::FetchCacheMode cache_mode) { + WebLocalFrameImpl* impl = ToWebLocalFrameImpl(frame); HistoryItem* history_item = item; - frame->CommitNavigation( + impl->CommitNavigation( WrappedResourceRequest(history_item->GenerateResourceRequest(cache_mode)), WebFrameLoadType::kBackForward, item, false /* is_client_redirect */, base::UnguessableToken::Create(), BuildDummyNavigationParams(), @@ -429,7 +432,7 @@ std::unique_ptr<TestWebFrameClient> self_owned) { DCHECK(!frame_); DCHECK(!self_owned || self_owned.get() == this); - frame_ = frame; + frame_ = ToWebLocalFrameImpl(frame); self_owned_ = std::move(self_owned); }
diff --git a/third_party/blink/renderer/core/frame/frame_test_helpers.h b/third_party/blink/renderer/core/frame/frame_test_helpers.h index 0d3ddec..ccfbc32 100644 --- a/third_party/blink/renderer/core/frame/frame_test_helpers.h +++ b/third_party/blink/renderer/core/frame/frame_test_helpers.h
@@ -300,7 +300,7 @@ static bool IsLoading() { return loads_in_progress_ > 0; } - WebLocalFrame* Frame() const { return frame_; } + WebNavigationControl* Frame() const { return frame_; } // Pass ownership of the TestWebFrameClient to |self_owned| here if the // TestWebFrameClient should delete itself on frame detach. void Bind(WebLocalFrame*, @@ -344,7 +344,7 @@ // This is null from when the client is created until it is initialized with // Bind(). - WebLocalFrame* frame_ = nullptr; + WebNavigationControl* frame_ = nullptr; std::unique_ptr<WebWidgetClient> owned_widget_client_; };
diff --git a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc index f564f832..2c046e111 100644 --- a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc +++ b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
@@ -1744,7 +1744,7 @@ WebTreeScopeType scope, WebLocalFrameClient* client, blink::InterfaceRegistry* interface_registry) - : WebLocalFrame(scope), + : WebNavigationControl(scope), client_(client), local_frame_client_(LocalFrameClientImpl::Create(this)), autofill_client_(nullptr), @@ -2125,7 +2125,7 @@ std::move(navigation_params), std::move(navigation_data)); } -WebLocalFrame::FallbackContentResult +WebNavigationControl::FallbackContentResult WebLocalFrameImpl::MaybeRenderFallbackContent(const WebURLError& error) const { DCHECK(GetFrame());
diff --git a/third_party/blink/renderer/core/frame/web_local_frame_impl.h b/third_party/blink/renderer/core/frame/web_local_frame_impl.h index 281cf46..0f6a29e 100644 --- a/third_party/blink/renderer/core/frame/web_local_frame_impl.h +++ b/third_party/blink/renderer/core/frame/web_local_frame_impl.h
@@ -41,6 +41,7 @@ #include "third_party/blink/public/web/devtools_agent.mojom-blink.h" #include "third_party/blink/public/web/web_history_commit_type.h" #include "third_party/blink/public/web/web_local_frame.h" +#include "third_party/blink/public/web/web_navigation_control.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/editing/forward.h" #include "third_party/blink/renderer/core/exported/web_input_method_controller_impl.h" @@ -82,7 +83,7 @@ // Implementation of WebFrame, note that this is a reference counted object. class CORE_EXPORT WebLocalFrameImpl final : public GarbageCollectedFinalized<WebLocalFrameImpl>, - public WebLocalFrame { + public WebNavigationControl { public: // WebFrame methods: // TODO(dcheng): Fix sorting here; a number of method have been moved to @@ -262,6 +263,48 @@ WebLocalFrameImpl* LocalRoot() override; WebFrame* FindFrameByName(const WebString& name) override; void SendPings(const WebURL& destination_url) override; + void ReportContentSecurityPolicyViolation( + const blink::WebContentSecurityPolicyViolation&) override; + bool IsLoading() const override; + bool IsNavigationScheduledWithin(double interval) const override; + void NotifyUserActivation() override; + void BlinkFeatureUsageReport(const std::set<int>& features) override; + void MixedContentFound(const WebURL& main_resource_url, + const WebURL& mixed_content_url, + mojom::RequestContextType, + bool was_allowed, + bool had_redirect, + const WebSourceLocation&) override; + void SendOrientationChangeEvent() override; + WebSandboxFlags EffectiveSandboxFlags() const override; + void DidCallAddSearchProvider() override; + void DidCallIsSearchProviderInstalled() override; + void ReplaceSelection(const WebString&) override; + bool FindForTesting(int identifier, + const WebString& search_text, + bool match_case, + bool forward, + bool force, + bool find_next, + bool wrap_within_frame) override; + void SetTickmarks(const WebVector<WebRect>&) override; + WebNode ContextMenuNode() const override; + WebFrameWidget* FrameWidget() const override; + void CopyImageAt(const WebPoint&) override; + void SaveImageAt(const WebPoint&) override; + void UsageCountChromeLoadTimes(const WebString& metric) override; + FrameScheduler* Scheduler() const override; + scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner(TaskType) override; + WebInputMethodController* GetInputMethodController() override; + void ExtractSmartClipData(WebRect rect_in_viewport, + WebString& clip_text, + WebString& clip_html, + WebRect& clip_rect) override; + void AdvanceFocusInForm(WebFocusType) override; + void PerformMediaPlayerAction(const WebPoint&, + const WebMediaPlayerAction&) override; + + // WebNavigationControl methods: bool DispatchBeforeUnloadEvent(bool) override; void CommitNavigation( const WebURLRequest&, @@ -292,19 +335,7 @@ FallbackContentResult MaybeRenderFallbackContent( const WebURLError&) const override; void RenderFallbackContent() const override; - void ReportContentSecurityPolicyViolation( - const blink::WebContentSecurityPolicyViolation&) override; - bool IsLoading() const override; - bool IsNavigationScheduledWithin(double interval) const override; void SetCommittedFirstRealLoad() override; - void NotifyUserActivation() override; - void BlinkFeatureUsageReport(const std::set<int>& features) override; - void MixedContentFound(const WebURL& main_resource_url, - const WebURL& mixed_content_url, - mojom::RequestContextType, - bool was_allowed, - bool had_redirect, - const WebSourceLocation&) override; void ClientDroppedNavigation() override; void MarkAsLoading() override; bool CreatePlaceholderDocumentLoader( @@ -315,34 +346,6 @@ const base::UnguessableToken& devtools_navigation_token, std::unique_ptr<WebNavigationParams>, std::unique_ptr<WebDocumentLoader::ExtraData>) override; - void SendOrientationChangeEvent() override; - WebSandboxFlags EffectiveSandboxFlags() const override; - void DidCallAddSearchProvider() override; - void DidCallIsSearchProviderInstalled() override; - void ReplaceSelection(const WebString&) override; - bool FindForTesting(int identifier, - const WebString& search_text, - bool match_case, - bool forward, - bool force, - bool find_next, - bool wrap_within_frame) override; - void SetTickmarks(const WebVector<WebRect>&) override; - WebNode ContextMenuNode() const override; - WebFrameWidget* FrameWidget() const override; - void CopyImageAt(const WebPoint&) override; - void SaveImageAt(const WebPoint&) override; - void UsageCountChromeLoadTimes(const WebString& metric) override; - FrameScheduler* Scheduler() const override; - scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner(TaskType) override; - WebInputMethodController* GetInputMethodController() override; - void ExtractSmartClipData(WebRect rect_in_viewport, - WebString& clip_text, - WebString& clip_html, - WebRect& clip_rect) override; - void AdvanceFocusInForm(WebFocusType) override; - void PerformMediaPlayerAction(const WebPoint&, - const WebMediaPlayerAction&) override; void InitializeCoreFrame(Page&, FrameOwner*, const AtomicString& name); LocalFrame* GetFrame() const { return frame_.Get(); }
diff --git a/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.cc b/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.cc index 3d16585..c711d30 100644 --- a/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.cc +++ b/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.cc
@@ -88,13 +88,19 @@ GetOrCreateResourceDispatcher() ? GetOrCreateResourceDispatcher()->GetWeakPtr() : nullptr; - if (Is3d()) { - const CanvasResourceProvider::ResourceUsage usage = - SharedGpuContext::IsGpuCompositingEnabled() - ? CanvasResourceProvider::kAcceleratedCompositedResourceUsage - : CanvasResourceProvider::kSoftwareCompositedResourceUsage; - CanvasResourceProvider::PresentationMode presentation_mode = + if (Is3d()) { + CanvasResourceProvider::ResourceUsage usage; + if (SharedGpuContext::IsGpuCompositingEnabled()) { + if (LowLatencyEnabled()) + usage = CanvasResourceProvider::kAcceleratedDirectResourceUsage; + else + usage = CanvasResourceProvider::kAcceleratedCompositedResourceUsage; + } else { + usage = CanvasResourceProvider::kSoftwareCompositedResourceUsage; + } + + const CanvasResourceProvider::PresentationMode presentation_mode = RuntimeEnabledFeatures::WebGLImageChromiumEnabled() ? CanvasResourceProvider::kAllowImageChromiumPresentationMode : CanvasResourceProvider::kDefaultPresentationMode; @@ -111,10 +117,15 @@ const bool want_acceleration = hint == kPreferAcceleration && ShouldAccelerate2dContext(); - const CanvasResourceProvider::ResourceUsage usage = - want_acceleration - ? CanvasResourceProvider::kAcceleratedCompositedResourceUsage - : CanvasResourceProvider::kSoftwareCompositedResourceUsage; + CanvasResourceProvider::ResourceUsage usage; + if (want_acceleration) { + if (LowLatencyEnabled()) + usage = CanvasResourceProvider::kAcceleratedDirectResourceUsage; + else + usage = CanvasResourceProvider::kAcceleratedCompositedResourceUsage; + } else { + usage = CanvasResourceProvider::kSoftwareCompositedResourceUsage; + } const CanvasResourceProvider::PresentationMode presentation_mode = (RuntimeEnabledFeatures::Canvas2dImageChromiumEnabled() ||
diff --git a/third_party/blink/renderer/core/html/forms/picker_indicator_element.cc b/third_party/blink/renderer/core/html/forms/picker_indicator_element.cc index e21e5169..583d803 100644 --- a/third_party/blink/renderer/core/html/forms/picker_indicator_element.cc +++ b/third_party/blink/renderer/core/html/forms/picker_indicator_element.cc
@@ -37,8 +37,8 @@ #include "third_party/blink/renderer/core/layout/layout_details_marker.h" #include "third_party/blink/renderer/core/page/chrome_client.h" #include "third_party/blink/renderer/core/page/page.h" -#include "third_party/blink/renderer/platform/layout_test_support.h" #include "third_party/blink/renderer/platform/text/platform_locale.h" +#include "third_party/blink/renderer/platform/web_test_support.h" namespace blink { @@ -161,10 +161,10 @@ void PickerIndicatorElement::DidNotifySubtreeInsertionsToDocument() { if (!GetDocument().ExistingAXObjectCache()) return; - // Don't make this focusable if we are in layout tests in order to avoid + // Don't make this focusable if we are in web tests in order to avoid // breaking existing tests. - // FIXME: We should have a way to disable accessibility in layout tests. - if (LayoutTestSupport::IsRunningLayoutTest()) + // FIXME: We should have a way to disable accessibility in web tests. + if (WebTestSupport::IsRunningWebTest()) return; setAttribute(kTabindexAttr, "0"); setAttribute(kAriaHaspopupAttr, "menu");
diff --git a/third_party/blink/renderer/core/html/media/html_video_element.cc b/third_party/blink/renderer/core/html/media/html_video_element.cc index a250915..ae5e8ad 100644 --- a/third_party/blink/renderer/core/html/media/html_video_element.cc +++ b/third_party/blink/renderer/core/html/media/html_video_element.cc
@@ -56,8 +56,8 @@ #include "third_party/blink/renderer/platform/graphics/gpu/extensions_3d_util.h" #include "third_party/blink/renderer/platform/graphics/graphics_context.h" #include "third_party/blink/renderer/platform/histogram.h" -#include "third_party/blink/renderer/platform/layout_test_support.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" +#include "third_party/blink/renderer/platform/web_test_support.h" namespace blink { @@ -489,8 +489,8 @@ exitPictureInPicture(base::DoNothing()); if (GetWebMediaPlayer()) { - // FIXME: There is no embedder-side handling in layout test mode. - if (!LayoutTestSupport::IsRunningLayoutTest()) + // FIXME: There is no embedder-side handling in web test mode. + if (!WebTestSupport::IsRunningWebTest()) GetWebMediaPlayer()->EnteredFullscreen(); GetWebMediaPlayer()->OnDisplayTypeChanged(DisplayType()); }
diff --git a/third_party/blink/renderer/core/html/parser/text_resource_decoder_for_fuzzing.h b/third_party/blink/renderer/core/html/parser/text_resource_decoder_for_fuzzing.h index f407437c..d71506c 100644 --- a/third_party/blink/renderer/core/html/parser/text_resource_decoder_for_fuzzing.h +++ b/third_party/blink/renderer/core/html/parser/text_resource_decoder_for_fuzzing.h
@@ -22,7 +22,7 @@ static TextResourceDecoderOptions FuzzedOption( FuzzedDataProvider& fuzzed_data) { switch (static_cast<TextResourceDecoderOptions::EncodingDetectionOption>( - fuzzed_data.ConsumeInt32InRange( + fuzzed_data.ConsumeIntegralInRange<int32_t>( TextResourceDecoderOptions::kUseAllAutoDetection, TextResourceDecoderOptions::kAlwaysUseUTF8ForText))) { case TextResourceDecoderOptions::kUseAllAutoDetection: @@ -42,7 +42,7 @@ static TextResourceDecoderOptions::ContentType FuzzedContentType( FuzzedDataProvider& fuzzed_data) { return static_cast<TextResourceDecoderOptions::ContentType>( - fuzzed_data.ConsumeInt32InRange( + fuzzed_data.ConsumeIntegralInRange<int32_t>( TextResourceDecoderOptions::kPlainTextContent, TextResourceDecoderOptions::kMaxContentType)); }
diff --git a/third_party/blink/renderer/core/inspector/devtools_session.cc b/third_party/blink/renderer/core/inspector/devtools_session.cc index 35f13b7..a1a06e4 100644 --- a/third_party/blink/renderer/core/inspector/devtools_session.cc +++ b/third_party/blink/renderer/core/inspector/devtools_session.cc
@@ -17,8 +17,8 @@ #include "third_party/blink/renderer/core/probe/core_probes.h" #include "third_party/blink/renderer/platform/cross_thread_functional.h" #include "third_party/blink/renderer/platform/heap/persistent.h" -#include "third_party/blink/renderer/platform/layout_test_support.h" #include "third_party/blink/renderer/platform/web_task_runner.h" +#include "third_party/blink/renderer/platform/web_test_support.h" namespace blink { @@ -232,7 +232,7 @@ v8_session_state_json_.Set(ToCoreString(v8_session_->stateJSON())); // Make tests more predictable by flushing all sessions before sending // protocol response in any of them. - if (LayoutTestSupport::IsRunningLayoutTest()) + if (WebTestSupport::IsRunningWebTest()) agent_->FlushProtocolNotifications(); host_ptr_->DispatchProtocolResponse(message, call_id, session_state_.TakeUpdates());
diff --git a/third_party/blink/renderer/core/inspector/inspector_audits_agent.cc b/third_party/blink/renderer/core/inspector/inspector_audits_agent.cc index b6ac5a8..a0885223 100644 --- a/third_party/blink/renderer/core/inspector/inspector_audits_agent.cc +++ b/third_party/blink/renderer/core/inspector/inspector_audits_agent.cc
@@ -16,7 +16,7 @@ using protocol::Maybe; using protocol::Response; -namespace EncodingEnum = protocol::Audits::GetEncodedResponse::EncodingEnum; +namespace encoding_enum = protocol::Audits::GetEncodedResponse::EncodingEnum; namespace { @@ -82,8 +82,8 @@ Maybe<protocol::Binary>* out_body, int* out_original_size, int* out_encoded_size) { - DCHECK(encoding == EncodingEnum::Jpeg || encoding == EncodingEnum::Png || - encoding == EncodingEnum::Webp); + DCHECK(encoding == encoding_enum::Jpeg || encoding == encoding_enum::Png || + encoding == encoding_enum::Webp); String body; bool is_base64_encoded;
diff --git a/third_party/blink/renderer/core/inspector/inspector_highlight.cc b/third_party/blink/renderer/core/inspector/inspector_highlight.cc index 1c8b069d..a303dac 100644 --- a/third_party/blink/renderer/core/inspector/inspector_highlight.cc +++ b/third_party/blink/renderer/core/inspector/inspector_highlight.cc
@@ -19,7 +19,7 @@ #include "third_party/blink/renderer/core/page/page.h" #include "third_party/blink/renderer/core/style/computed_style_constants.h" #include "third_party/blink/renderer/platform/graphics/path.h" -#include "third_party/blink/renderer/platform/layout_test_support.h" +#include "third_party/blink/renderer/platform/web_test_support.h" namespace blink { @@ -437,10 +437,10 @@ // Just for testing, invert the content color for nodes rendered by LayoutNG. // TODO(layout-dev): Stop munging the color before NG ships. crbug.com/869866 - Color content_color = layout_object->IsLayoutNGObject() && - !LayoutTestSupport::IsRunningLayoutTest() - ? Color(highlight_config.content.Rgb() ^ 0x00ffffff) - : highlight_config.content; + Color content_color = + layout_object->IsLayoutNGObject() && !WebTestSupport::IsRunningWebTest() + ? Color(highlight_config.content.Rgb() ^ 0x00ffffff) + : highlight_config.content; Vector<FloatQuad> svg_quads; if (BuildSVGQuads(node, svg_quads)) {
diff --git a/third_party/blink/renderer/core/inspector/inspector_resource_content_loader.cc b/third_party/blink/renderer/core/inspector/inspector_resource_content_loader.cc index dfaef897..bb59c3a 100644 --- a/third_party/blink/renderer/core/inspector/inspector_resource_content_loader.cc +++ b/third_party/blink/renderer/core/inspector/inspector_resource_content_loader.cc
@@ -88,6 +88,7 @@ resource_request.SetCacheMode(mojom::FetchCacheMode::kOnlyIfCached); } resource_request.SetRequestContext(mojom::RequestContextType::INTERNAL); + resource_request.SetSkipServiceWorker(true); if (!resource_request.Url().GetString().IsEmpty()) { urls_to_fetch.insert(resource_request.Url().GetString());
diff --git a/third_party/blink/renderer/core/inspector/worker_inspector_controller.cc b/third_party/blink/renderer/core/inspector/worker_inspector_controller.cc index d163b7c8..9b47ddb 100644 --- a/third_party/blink/renderer/core/inspector/worker_inspector_controller.cc +++ b/third_party/blink/renderer/core/inspector/worker_inspector_controller.cc
@@ -45,7 +45,6 @@ #include "third_party/blink/renderer/core/workers/worker_backing_thread.h" #include "third_party/blink/renderer/core/workers/worker_global_scope.h" #include "third_party/blink/renderer/core/workers/worker_thread.h" -#include "third_party/blink/renderer/platform/layout_test_support.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/web_thread_supporting_gc.h"
diff --git a/third_party/blink/renderer/core/layout/layout_theme.cc b/third_party/blink/renderer/core/layout/layout_theme.cc index 9a66a2462..b5aee03 100644 --- a/third_party/blink/renderer/core/layout/layout_theme.cc +++ b/third_party/blink/renderer/core/layout/layout_theme.cc
@@ -58,10 +58,10 @@ #include "third_party/blink/renderer/platform/fonts/string_truncator.h" #include "third_party/blink/renderer/platform/graphics/color.h" #include "third_party/blink/renderer/platform/graphics/touch_action.h" -#include "third_party/blink/renderer/platform/layout_test_support.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/text/platform_locale.h" #include "third_party/blink/renderer/platform/theme.h" +#include "third_party/blink/renderer/platform/web_test_support.h" #include "third_party/blink/renderer/platform/wtf/text/string_builder.h" #include "ui/native_theme/native_theme.h" @@ -101,7 +101,7 @@ // Wrapper function defined in WebKit.h void SetMockThemeEnabledForTest(bool value) { - LayoutTestSupport::SetMockThemeEnabledForTest(value); + WebTestSupport::SetMockThemeEnabledForTest(value); LayoutTheme::GetTheme().DidChangeThemeEngine(); } @@ -682,8 +682,8 @@ TimeDelta LayoutTheme::CaretBlinkInterval() const { // Disable the blinking caret in layout test mode, as it introduces // a race condition for the pixel tests. http://b/1198440 - return LayoutTestSupport::IsRunningLayoutTest() ? TimeDelta() - : caret_blink_interval_; + return WebTestSupport::IsRunningWebTest() ? TimeDelta() + : caret_blink_interval_; } static FontDescription& GetCachedFontDescription(CSSValueID system_font_id) {
diff --git a/third_party/blink/renderer/core/layout/layout_theme_default.cc b/third_party/blink/renderer/core/layout/layout_theme_default.cc index d981319c..4010a8d 100644 --- a/third_party/blink/renderer/core/layout/layout_theme_default.cc +++ b/third_party/blink/renderer/core/layout/layout_theme_default.cc
@@ -32,7 +32,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" #include "third_party/blink/renderer/platform/data_resource_helper.h" #include "third_party/blink/renderer/platform/graphics/color.h" -#include "third_party/blink/renderer/platform/layout_test_support.h" +#include "third_party/blink/renderer/platform/web_test_support.h" #include "third_party/blink/renderer/platform/wtf/text/string_builder.h" namespace blink { @@ -44,7 +44,7 @@ static const float kMaxCancelButtonSize = 21; static bool UseMockTheme() { - return LayoutTestSupport::IsMockThemeEnabledForTest(); + return WebTestSupport::IsMockThemeEnabledForTest(); } unsigned LayoutThemeDefault::active_selection_background_color_ = 0xff1e90ff;
diff --git a/third_party/blink/renderer/core/layout/layout_theme_mac.mm b/third_party/blink/renderer/core/layout/layout_theme_mac.mm index d35622c..0e82ef5 100644 --- a/third_party/blink/renderer/core/layout/layout_theme_mac.mm +++ b/third_party/blink/renderer/core/layout/layout_theme_mac.mm
@@ -36,7 +36,6 @@ #import "third_party/blink/renderer/platform/data_resource_helper.h" #import "third_party/blink/renderer/platform/fonts/string_truncator.h" #import "third_party/blink/renderer/platform/graphics/bitmap_image.h" -#import "third_party/blink/renderer/platform/layout_test_support.h" #import "third_party/blink/renderer/platform/mac/color_mac.h" #import "third_party/blink/renderer/platform/mac/theme_mac.h" #import "third_party/blink/renderer/platform/mac/version_util_mac.h" @@ -44,6 +43,7 @@ #import "third_party/blink/renderer/platform/runtime_enabled_features.h" #import "third_party/blink/renderer/platform/text/platform_locale.h" #import "third_party/blink/renderer/platform/theme.h" +#import "third_party/blink/renderer/platform/web_test_support.h" // The methods in this file are specific to the Mac OS X platform. @@ -970,7 +970,7 @@ } bool LayoutThemeMac::UsesTestModeFocusRingColor() const { - return LayoutTestSupport::IsRunningLayoutTest(); + return WebTestSupport::IsRunningWebTest(); } NSView* LayoutThemeMac::DocumentView() const {
diff --git a/third_party/blink/renderer/core/layout/layout_theme_mobile.cc b/third_party/blink/renderer/core/layout/layout_theme_mobile.cc index f0b845c..0d602a5 100644 --- a/third_party/blink/renderer/core/layout/layout_theme_mobile.cc +++ b/third_party/blink/renderer/core/layout/layout_theme_mobile.cc
@@ -30,7 +30,7 @@ #include "third_party/blink/public/platform/web_theme_engine.h" #include "third_party/blink/renderer/core/style/computed_style.h" #include "third_party/blink/renderer/platform/data_resource_helper.h" -#include "third_party/blink/renderer/platform/layout_test_support.h" +#include "third_party/blink/renderer/platform/web_test_support.h" namespace blink { @@ -51,7 +51,7 @@ } void LayoutThemeMobile::AdjustInnerSpinButtonStyle(ComputedStyle& style) const { - if (LayoutTestSupport::IsRunningLayoutTest()) { + if (WebTestSupport::IsRunningWebTest()) { // Match Linux spin button style in layout tests. // FIXME: Consider removing the conditional if a future Android theme // matches this.
diff --git a/third_party/blink/renderer/core/page/chrome_client_impl.cc b/third_party/blink/renderer/core/page/chrome_client_impl.cc index 72f40ed9..f93003f 100644 --- a/third_party/blink/renderer/core/page/chrome_client_impl.cc +++ b/third_party/blink/renderer/core/page/chrome_client_impl.cc
@@ -97,8 +97,8 @@ #include "third_party/blink/renderer/platform/graphics/graphics_layer.h" #include "third_party/blink/renderer/platform/graphics/touch_action.h" #include "third_party/blink/renderer/platform/histogram.h" -#include "third_party/blink/renderer/platform/layout_test_support.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" +#include "third_party/blink/renderer/platform/web_test_support.h" #include "third_party/blink/renderer/platform/weborigin/security_origin.h" #include "third_party/blink/renderer/platform/wtf/text/character_names.h" #include "third_party/blink/renderer/platform/wtf/text/cstring.h" @@ -211,7 +211,7 @@ bool ChromeClientImpl::CanTakeFocus(WebFocusType) { // For now the browser can always take focus if we're not running layout // tests. - return !LayoutTestSupport::IsRunningLayoutTest(); + return !WebTestSupport::IsRunningWebTest(); } void ChromeClientImpl::TakeFocus(WebFocusType type) {
diff --git a/third_party/blink/renderer/core/page/validation_message_client_impl.cc b/third_party/blink/renderer/core/page/validation_message_client_impl.cc index c6623a5..2612a44 100644 --- a/third_party/blink/renderer/core/page/validation_message_client_impl.cc +++ b/third_party/blink/renderer/core/page/validation_message_client_impl.cc
@@ -36,7 +36,7 @@ #include "third_party/blink/renderer/core/frame/local_frame_view.h" #include "third_party/blink/renderer/core/page/chrome_client.h" #include "third_party/blink/renderer/core/page/validation_message_overlay_delegate.h" -#include "third_party/blink/renderer/platform/layout_test_support.h" +#include "third_party/blink/renderer/platform/web_test_support.h" namespace blink { @@ -94,7 +94,7 @@ } void ValidationMessageClientImpl::HideValidationMessage(const Element& anchor) { - if (LayoutTestSupport::IsRunningLayoutTest()) { + if (WebTestSupport::IsRunningWebTest()) { HideValidationMessageImmediately(anchor); return; } @@ -140,7 +140,7 @@ void ValidationMessageClientImpl::CheckAnchorStatus(TimerBase*) { DCHECK(current_anchor_); - if ((!LayoutTestSupport::IsRunningLayoutTest() && + if ((!WebTestSupport::IsRunningWebTest() && CurrentTimeTicks() >= finish_time_) || !CurrentView()) { HideValidationMessage(*current_anchor_);
diff --git a/third_party/blink/renderer/core/page/validation_message_overlay_delegate.cc b/third_party/blink/renderer/core/page/validation_message_overlay_delegate.cc index 0fd8a0f8..9fd5f4a 100644 --- a/third_party/blink/renderer/core/page/validation_message_overlay_delegate.cc +++ b/third_party/blink/renderer/core/page/validation_message_overlay_delegate.cc
@@ -16,8 +16,8 @@ #include "third_party/blink/renderer/core/page/page.h" #include "third_party/blink/renderer/core/page/page_popup_client.h" #include "third_party/blink/renderer/platform/graphics/paint/cull_rect.h" -#include "third_party/blink/renderer/platform/layout_test_support.h" #include "third_party/blink/renderer/platform/text/platform_locale.h" +#include "third_party/blink/renderer/platform/web_test_support.h" namespace blink { @@ -160,7 +160,7 @@ frame->ForceSynchronousDocumentInstall("text/html", data); Element& container = GetElementById("container"); - if (LayoutTestSupport::IsRunningLayoutTest()) { + if (WebTestSupport::IsRunningWebTest()) { container.SetInlineStyleProperty(CSSPropertyTransition, "none"); GetElementById("icon").SetInlineStyleProperty(CSSPropertyTransition, "none");
diff --git a/third_party/blink/renderer/core/paint/link_highlight_impl.cc b/third_party/blink/renderer/core/paint/link_highlight_impl.cc index 658b27b..748d83ec 100644 --- a/third_party/blink/renderer/core/paint/link_highlight_impl.cc +++ b/third_party/blink/renderer/core/paint/link_highlight_impl.cc
@@ -59,7 +59,7 @@ #include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h" #include "third_party/blink/renderer/platform/graphics/paint/paint_canvas.h" #include "third_party/blink/renderer/platform/graphics/paint/paint_recorder.h" -#include "third_party/blink/renderer/platform/layout_test_support.h" +#include "third_party/blink/renderer/platform/web_test_support.h" #include "third_party/blink/renderer/platform/wtf/vector.h" #include "third_party/skia/include/core/SkMatrix44.h" #include "ui/gfx/geometry/rect.h" @@ -310,11 +310,10 @@ curve->AddKeyframe(CompositorFloatKeyframe( extra_duration_required.InSecondsF(), kStartOpacity, timing_function)); } - // For layout tests we don't fade out. + // For web tests we don't fade out. curve->AddKeyframe(CompositorFloatKeyframe( (kFadeDuration + extra_duration_required).InSecondsF(), - LayoutTestSupport::IsRunningLayoutTest() ? kStartOpacity : 0, - timing_function)); + WebTestSupport::IsRunningWebTest() ? kStartOpacity : 0, timing_function)); std::unique_ptr<CompositorKeyframeModel> keyframe_model = CompositorKeyframeModel::Create(
diff --git a/third_party/blink/renderer/core/paint/paint_layer_clipper_test.cc b/third_party/blink/renderer/core/paint/paint_layer_clipper_test.cc index df01f76..341763c 100644 --- a/third_party/blink/renderer/core/paint/paint_layer_clipper_test.cc +++ b/third_party/blink/renderer/core/paint/paint_layer_clipper_test.cc
@@ -10,8 +10,8 @@ #include "third_party/blink/renderer/core/layout/layout_view.h" #include "third_party/blink/renderer/core/paint/paint_layer.h" #include "third_party/blink/renderer/core/testing/core_unit_test_helper.h" -#include "third_party/blink/renderer/platform/layout_test_support.h" #include "third_party/blink/renderer/platform/testing/unit_test_helpers.h" +#include "third_party/blink/renderer/platform/web_test_support.h" namespace blink { @@ -20,12 +20,12 @@ PaintLayerClipperTest() : RenderingTest(EmptyLocalFrameClient::Create()) {} void SetUp() override { - LayoutTestSupport::SetMockThemeEnabledForTest(true); + WebTestSupport::SetMockThemeEnabledForTest(true); RenderingTest::SetUp(); } void TearDown() override { - LayoutTestSupport::SetMockThemeEnabledForTest(false); + WebTestSupport::SetMockThemeEnabledForTest(false); RenderingTest::TearDown(); } };
diff --git a/third_party/blink/renderer/core/paint/theme_painter_default.cc b/third_party/blink/renderer/core/paint/theme_painter_default.cc index ed22010..d4f4e51b 100644 --- a/third_party/blink/renderer/core/paint/theme_painter_default.cc +++ b/third_party/blink/renderer/core/paint/theme_painter_default.cc
@@ -35,7 +35,7 @@ #include "third_party/blink/renderer/platform/graphics/color.h" #include "third_party/blink/renderer/platform/graphics/graphics_context.h" #include "third_party/blink/renderer/platform/graphics/graphics_context_state_saver.h" -#include "third_party/blink/renderer/platform/layout_test_support.h" +#include "third_party/blink/renderer/platform/web_test_support.h" namespace blink { @@ -44,7 +44,7 @@ const unsigned kDefaultButtonBackgroundColor = 0xffdddddd; bool UseMockTheme() { - return LayoutTestSupport::IsMockThemeEnabledForTest(); + return WebTestSupport::IsMockThemeEnabledForTest(); } WebThemeEngine::State GetWebThemeState(const Node* node) {
diff --git a/third_party/blink/renderer/core/scroll/scrollbar_theme_aura.cc b/third_party/blink/renderer/core/scroll/scrollbar_theme_aura.cc index 0d3b2ee..d7f792f5 100644 --- a/third_party/blink/renderer/core/scroll/scrollbar_theme_aura.cc +++ b/third_party/blink/renderer/core/scroll/scrollbar_theme_aura.cc
@@ -41,15 +41,15 @@ #include "third_party/blink/renderer/platform/geometry/int_rect_outsets.h" #include "third_party/blink/renderer/platform/graphics/graphics_context.h" #include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h" -#include "third_party/blink/renderer/platform/layout_test_support.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" +#include "third_party/blink/renderer/platform/web_test_support.h" namespace blink { namespace { static bool UseMockTheme() { - return LayoutTestSupport::IsRunningLayoutTest(); + return WebTestSupport::IsRunningWebTest(); } // Contains a flag indicating whether WebThemeEngine should paint a UI widget
diff --git a/third_party/blink/renderer/core/testing/sim/sim_test.cc b/third_party/blink/renderer/core/testing/sim/sim_test.cc index 8a3e27e6..ab8aff7c 100644 --- a/third_party/blink/renderer/core/testing/sim/sim_test.cc +++ b/third_party/blink/renderer/core/testing/sim/sim_test.cc
@@ -12,8 +12,8 @@ #include "third_party/blink/renderer/core/frame/local_dom_window.h" #include "third_party/blink/renderer/core/frame/web_local_frame_impl.h" #include "third_party/blink/renderer/core/scroll/scrollbar_theme.h" -#include "third_party/blink/renderer/platform/layout_test_support.h" #include "third_party/blink/renderer/platform/testing/unit_test_helpers.h" +#include "third_party/blink/renderer/platform/web_test_support.h" namespace blink { @@ -30,7 +30,7 @@ // updateScrollerStyleForNewRecommendedScrollerStyle which then does // FrameView::scrollbarStyleChanged and will adjust the scrollbar existence // in the middle of a test. - LayoutTestSupport::SetMockThemeEnabledForTest(true); + WebTestSupport::SetMockThemeEnabledForTest(true); ScrollbarTheme::SetMockScrollbarsEnabled(true); // Threaded animations are usually enabled for blink. However these tests use // synchronous compositing, which can not run threaded animations. @@ -46,7 +46,7 @@ test::RunPendingTasks(); Document::SetThreadedParsingEnabledForTesting(true); - LayoutTestSupport::SetMockThemeEnabledForTest(false); + WebTestSupport::SetMockThemeEnabledForTest(false); ScrollbarTheme::SetMockScrollbarsEnabled(false); content::TestBlinkWebUnitTestSupport::SetThreadedAnimationEnabled(true); WebCache::Clear();
diff --git a/third_party/blink/renderer/devtools/front_end/common/ResourceType.js b/third_party/blink/renderer/devtools/front_end/common/ResourceType.js index ebc106c1..5366548 100644 --- a/third_party/blink/renderer/devtools/front_end/common/ResourceType.js +++ b/third_party/blink/renderer/devtools/front_end/common/ResourceType.js
@@ -79,6 +79,19 @@ } /** + * @param {string} name + * @return {?Common.ResourceType} + */ + static fromName(name) { + for (const resourceTypeId in Common.resourceTypes) { + const resourceType = Common.resourceTypes[resourceTypeId]; + if (resourceType.name() === name) + return resourceType; + } + return null; + } + + /** * @param {string} url * @return {string|undefined} */
diff --git a/third_party/blink/renderer/devtools/front_end/har_importer/HARFormat.js b/third_party/blink/renderer/devtools/front_end/har_importer/HARFormat.js index 14cf5cd..07a39899 100644 --- a/third_party/blink/renderer/devtools/front_end/har_importer/HARFormat.js +++ b/third_party/blink/renderer/devtools/front_end/har_importer/HARFormat.js
@@ -163,6 +163,7 @@ if (data['_initiator']) this._initiator = new HARImporter.HARInitiator(data['_initiator']); this._priority = HARImporter.HARBase._optionalString(data['_priority']); + this._resourceType = HARImporter.HARBase._optionalString(data['_resourceType']); } };
diff --git a/third_party/blink/renderer/devtools/front_end/har_importer/HARImporter.js b/third_party/blink/renderer/devtools/front_end/har_importer/HARImporter.js index 081ac1a..aa982f44 100644 --- a/third_party/blink/renderer/devtools/front_end/har_importer/HARImporter.js +++ b/third_party/blink/renderer/devtools/front_end/har_importer/HARImporter.js
@@ -116,12 +116,7 @@ // Meta data. request.setRemoteAddress(entry.serverIPAddress || '', 80); // Har does not support port numbers. - let resourceType = (pageLoad && pageLoad.mainRequest === request) ? - Common.resourceTypes.Document : - Common.ResourceType.fromMimeType(entry.response.content.mimeType); - if (!resourceType) - resourceType = Common.ResourceType.fromURL(entry.request.url) || Common.resourceTypes.Other; - request.setResourceType(resourceType); + request.setResourceType(HARImporter.Importer._getResourceType(request, entry, pageLoad)); const priority = entry.customAsString('priority'); if (Protocol.Network.ResourcePriority.hasOwnProperty(priority)) @@ -132,6 +127,34 @@ /** * @param {!SDK.NetworkRequest} request + * @param {!HARImporter.HAREntry} entry + * @param {?SDK.NetworkLog.PageLoad} pageLoad + * @return {!Common.ResourceType} + */ + static _getResourceType(request, entry, pageLoad) { + const customResourceTypeName = entry.customAsString('resourceType'); + if (customResourceTypeName) { + const customResourceType = Common.ResourceType.fromName(customResourceTypeName); + if (customResourceType) + return customResourceType; + } + + if (pageLoad && pageLoad.mainRequest === request) + return Common.resourceTypes.Document; + + const resourceTypeFromMime = Common.ResourceType.fromMimeType(entry.response.content.mimeType); + if (resourceTypeFromMime !== Common.resourceTypes.Other) + return resourceTypeFromMime; + + const resourceTypeFromUrl = Common.ResourceType.fromURL(entry.request.url); + if (resourceTypeFromUrl) + return resourceTypeFromUrl; + + return Common.resourceTypes.Other; + } + + /** + * @param {!SDK.NetworkRequest} request * @param {number} issueTime * @param {number} entryTotalDuration * @param {!HARImporter.HARTimings} timings
diff --git a/third_party/blink/renderer/devtools/front_end/sdk/HARLog.js b/third_party/blink/renderer/devtools/front_end/sdk/HARLog.js index e39b3fe..6bc75d2 100644 --- a/third_party/blink/renderer/devtools/front_end/sdk/HARLog.js +++ b/third_party/blink/renderer/devtools/front_end/sdk/HARLog.js
@@ -169,7 +169,8 @@ // IPv6 address should not have square brackets per (https://tools.ietf.org/html/rfc2373#section-2.2). serverIPAddress: ipAddress.replace(/\[\]/g, ''), _initiator: exportedInitiator, - _priority: harEntry._request.priority() + _priority: harEntry._request.priority(), + _resourceType: harEntry._request.resourceType().name() }; // Chrome specific.
diff --git a/third_party/blink/renderer/modules/BUILD.gn b/third_party/blink/renderer/modules/BUILD.gn index 051ab3a..2202534 100644 --- a/third_party/blink/renderer/modules/BUILD.gn +++ b/third_party/blink/renderer/modules/BUILD.gn
@@ -346,6 +346,7 @@ "webaudio/audio_basic_processor_handler_test.cc", "webaudio/audio_context_autoplay_test.cc", "webaudio/audio_context_test.cc", + "webaudio/audio_node_input_test.cc", "webaudio/audio_worklet_global_scope_test.cc", "webaudio/audio_worklet_thread_test.cc", "webaudio/convolver_node_test.cc",
diff --git a/third_party/blink/renderer/modules/accessibility/ax_selection.cc b/third_party/blink/renderer/modules/accessibility/ax_selection.cc index 22d347f..71e240e 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_selection.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_selection.cc
@@ -248,7 +248,7 @@ DCHECK(selection.AssertValid()); Document* document = selection.Base().GetDocument(); if (!document) { - NOTREACHED(); + NOTREACHED() << "Valid DOM selections should have an attached document."; return false; }
diff --git a/third_party/blink/renderer/modules/accessibility/ax_selection_test.cc b/third_party/blink/renderer/modules/accessibility/ax_selection_test.cc index 068053c..3477e1d 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_selection_test.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_selection_test.cc
@@ -8,14 +8,18 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/renderer/core/dom/document.h" +#include "third_party/blink/renderer/core/dom/element.h" #include "third_party/blink/renderer/core/dom/node.h" +#include "third_party/blink/renderer/core/dom/range.h" #include "third_party/blink/renderer/core/editing/frame_selection.h" #include "third_party/blink/renderer/core/editing/position.h" #include "third_party/blink/renderer/core/editing/selection_template.h" -#include "third_party/blink/renderer/core/frame/local_frame.h" +#include "third_party/blink/renderer/core/frame/settings.h" +#include "third_party/blink/renderer/core/page/page.h" #include "third_party/blink/renderer/modules/accessibility/ax_object.h" #include "third_party/blink/renderer/modules/accessibility/ax_position.h" #include "third_party/blink/renderer/modules/accessibility/testing/accessibility_selection_test.h" +#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" namespace blink { namespace test { @@ -24,16 +28,180 @@ // Basic tests. // -TEST_F(AccessibilitySelectionTest, SetSelectionInText) { - SetBodyInnerHTML(R"HTML(<p id='paragraph'>Hello</p>)HTML"); +TEST_F(AccessibilitySelectionTest, FromCurrentSelection) { + GetPage().GetSettings().SetScriptEnabled(true); + SetBodyInnerHTML(R"HTML( + <p id="paragraph1">Hello.</p> + <p id="paragraph2">How are you?</p> + )HTML"); - const Node* text = GetElementById("paragraph")->firstChild(); + ASSERT_FALSE(AXSelection::FromCurrentSelection(GetDocument()).IsValid()); + + Element* const script_element = + GetDocument().CreateRawElement(html_names::kScriptTag); + ASSERT_NE(nullptr, script_element); + script_element->setTextContent(R"SCRIPT( + let text1 = document.querySelectorAll('p')[0].firstChild; + let paragraph2 = document.querySelectorAll('p')[1]; + let range = document.createRange(); + range.setStart(text1, 3); + range.setEnd(paragraph2, 1); + let selection = getSelection(); + selection.removeAllRanges(); + selection.addRange(range); + )SCRIPT"); + GetDocument().body()->AppendChild(script_element); + UpdateAllLifecyclePhasesForTest(); + + const AXObject* ax_static_text_1 = + GetAXObjectByElementId("paragraph1")->FirstChild(); + ASSERT_NE(nullptr, ax_static_text_1); + ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text_1->RoleValue()); + const AXObject* ax_paragraph_2 = GetAXObjectByElementId("paragraph2"); + ASSERT_NE(nullptr, ax_paragraph_2); + ASSERT_EQ(ax::mojom::Role::kParagraph, ax_paragraph_2->RoleValue()); + + const auto ax_selection = AXSelection::FromCurrentSelection(GetDocument()); + ASSERT_TRUE(ax_selection.IsValid()); + + EXPECT_TRUE(ax_selection.Base().IsTextPosition()); + EXPECT_EQ(ax_static_text_1, ax_selection.Base().ContainerObject()); + EXPECT_EQ(3, ax_selection.Base().TextOffset()); + + EXPECT_FALSE(ax_selection.Extent().IsTextPosition()); + EXPECT_EQ(ax_paragraph_2, ax_selection.Extent().ContainerObject()); + EXPECT_EQ(1, ax_selection.Extent().ChildIndex()); + + EXPECT_EQ( + "++<Paragraph>\n" + "++++<StaticText: Hel^lo.>\n" + "++<Paragraph>\n" + "++++<StaticText: How are you?>\n|", + GetSelectionText(ax_selection)); +} + +TEST_F(AccessibilitySelectionTest, ClearCurrentSelection) { + GetPage().GetSettings().SetScriptEnabled(true); + SetBodyInnerHTML(R"HTML( + <p>Hello.</p> + <p>How are you?</p> + )HTML"); + + Element* const script_element = + GetDocument().CreateRawElement(html_names::kScriptTag); + ASSERT_NE(nullptr, script_element); + script_element->setTextContent(R"SCRIPT( + let text1 = document.querySelectorAll('p')[0].firstChild; + let paragraph2 = document.querySelectorAll('p')[1]; + let range = document.createRange(); + range.setStart(text1, 3); + range.setEnd(paragraph2, 1); + let selection = getSelection(); + selection.removeAllRanges(); + selection.addRange(range); + )SCRIPT"); + GetDocument().body()->AppendChild(script_element); + UpdateAllLifecyclePhasesForTest(); + + SelectionInDOMTree selection = Selection().GetSelectionInDOMTree(); + ASSERT_FALSE(selection.IsNone()); + + AXSelection::ClearCurrentSelection(GetDocument()); + selection = Selection().GetSelectionInDOMTree(); + EXPECT_TRUE(selection.IsNone()); + + const auto ax_selection = AXSelection::FromCurrentSelection(GetDocument()); + EXPECT_FALSE(ax_selection.IsValid()); + EXPECT_EQ("", GetSelectionText(ax_selection)); +} + +TEST_F(AccessibilitySelectionTest, CancelSelect) { + GetPage().GetSettings().SetScriptEnabled(true); + SetBodyInnerHTML(R"HTML( + <p id="paragraph1">Hello.</p> + <p id="paragraph2">How are you?</p> + )HTML"); + + Element* const script_element = + GetDocument().CreateRawElement(html_names::kScriptTag); + ASSERT_NE(nullptr, script_element); + script_element->setTextContent(R"SCRIPT( + document.addEventListener("selectstart", (e) => { + e.preventDefault(); + }, false); + )SCRIPT"); + GetDocument().body()->AppendChild(script_element); + UpdateAllLifecyclePhasesForTest(); + + const AXObject* ax_static_text_1 = + GetAXObjectByElementId("paragraph1")->FirstChild(); + ASSERT_NE(nullptr, ax_static_text_1); + ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text_1->RoleValue()); + const AXObject* ax_paragraph_2 = GetAXObjectByElementId("paragraph2"); + ASSERT_NE(nullptr, ax_paragraph_2); + ASSERT_EQ(ax::mojom::Role::kParagraph, ax_paragraph_2->RoleValue()); + + AXSelection::Builder builder; + AXSelection ax_selection = + builder + .SetBase(AXPosition::CreatePositionInTextObject(*ax_static_text_1, 3)) + .SetExtent(AXPosition::CreateLastPositionInObject(*ax_paragraph_2)) + .Build(); + + EXPECT_FALSE(ax_selection.Select()) << "The operation has been cancelled."; + EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsNone()); + EXPECT_FALSE(AXSelection::FromCurrentSelection(GetDocument()).IsValid()); + + GetDocument().RemoveAllEventListeners(); + + EXPECT_TRUE(ax_selection.Select()) << "The operation should now go through."; + EXPECT_FALSE(Selection().GetSelectionInDOMTree().IsNone()); + EXPECT_EQ( + "++<Paragraph>\n" + "++++<StaticText: Hel^lo.>\n" + "++<Paragraph>\n" + "++++<StaticText: How are you?>\n|", + GetSelectionText(AXSelection::FromCurrentSelection(GetDocument()))); +} + +TEST_F(AccessibilitySelectionTest, DocumentRangeMatchesSelection) { + SetBodyInnerHTML(R"HTML( + <p id="paragraph1">Hello.</p> + <p id="paragraph2">How are you?</p> + )HTML"); + + const AXObject* ax_static_text_1 = + GetAXObjectByElementId("paragraph1")->FirstChild(); + ASSERT_NE(nullptr, ax_static_text_1); + ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text_1->RoleValue()); + const AXObject* ax_paragraph_2 = GetAXObjectByElementId("paragraph2"); + ASSERT_NE(nullptr, ax_paragraph_2); + ASSERT_EQ(ax::mojom::Role::kParagraph, ax_paragraph_2->RoleValue()); + + AXSelection::Builder builder; + AXSelection ax_selection = + builder + .SetBase(AXPosition::CreatePositionInTextObject(*ax_static_text_1, 3)) + .SetExtent(AXPosition::CreateLastPositionInObject(*ax_paragraph_2)) + .Build(); + EXPECT_TRUE(ax_selection.Select()); + ASSERT_FALSE(Selection().GetSelectionInDOMTree().IsNone()); + ASSERT_NE(nullptr, Selection().DocumentCachedRange()); + EXPECT_EQ(String("lo.\n How are you?"), + Selection().DocumentCachedRange()->toString()); +} + +TEST_F(AccessibilitySelectionTest, SetSelectionInText) { + SetBodyInnerHTML(R"HTML(<p id="paragraph">Hello</p>)HTML"); + + const Node* text = GetDocument().QuerySelector("p")->firstChild(); ASSERT_NE(nullptr, text); ASSERT_TRUE(text->IsTextNode()); const AXObject* ax_static_text = GetAXObjectByElementId("paragraph")->FirstChild(); ASSERT_NE(nullptr, ax_static_text); + ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text->RoleValue()); const auto ax_base = AXPosition::CreatePositionInTextObject(*ax_static_text, 3); @@ -54,15 +222,16 @@ } TEST_F(AccessibilitySelectionTest, SetSelectionInTextWithWhiteSpace) { - SetBodyInnerHTML(R"HTML(<p id='paragraph'> Hello</p>)HTML"); + SetBodyInnerHTML(R"HTML(<p id="paragraph"> Hello</p>)HTML"); - const Node* text = GetElementById("paragraph")->firstChild(); + const Node* text = GetDocument().QuerySelector("p")->firstChild(); ASSERT_NE(nullptr, text); ASSERT_TRUE(text->IsTextNode()); const AXObject* ax_static_text = GetAXObjectByElementId("paragraph")->FirstChild(); ASSERT_NE(nullptr, ax_static_text); + ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text->RoleValue()); const auto ax_base = AXPosition::CreatePositionInTextObject(*ax_static_text, 3); @@ -226,7 +395,7 @@ // first <li>. ax_selection.Select(AXSelectionBehavior::kShrinkToValidDOMRange); const SelectionInDOMTree shrunk_selection = - GetFrame().Selection().GetSelectionInDOMTree(); + Selection().GetSelectionInDOMTree(); EXPECT_EQ(item_1, shrunk_selection.Base().AnchorNode()); EXPECT_TRUE(shrunk_selection.Base().IsBeforeChildren()); @@ -238,7 +407,7 @@ // |AXSelection| should move the anchor to before the first <li>. ax_selection.Select(AXSelectionBehavior::kExtendToValidDOMRange); const SelectionInDOMTree extended_selection = - GetFrame().Selection().GetSelectionInDOMTree(); + Selection().GetSelectionInDOMTree(); ASSERT_TRUE(extended_selection.Base().IsOffsetInAnchor()); EXPECT_EQ(item_1->parentNode(), extended_selection.Base().AnchorNode());
diff --git a/third_party/blink/renderer/modules/locks/lock.idl b/third_party/blink/renderer/modules/locks/lock.idl index 24d444a..182914a 100644 --- a/third_party/blink/renderer/modules/locks/lock.idl +++ b/third_party/blink/renderer/modules/locks/lock.idl
@@ -5,8 +5,7 @@ // https://wicg.github.io/web-locks/#lock [ SecureContext, - Exposed=(Window,Worker), - RuntimeEnabled=WebLocksAPI + Exposed=(Window,Worker) ] interface Lock { readonly attribute DOMString name; readonly attribute LockMode mode;
diff --git a/third_party/blink/renderer/modules/locks/lock_manager.idl b/third_party/blink/renderer/modules/locks/lock_manager.idl index 8337d2b..dfa15d19 100644 --- a/third_party/blink/renderer/modules/locks/lock_manager.idl +++ b/third_party/blink/renderer/modules/locks/lock_manager.idl
@@ -8,8 +8,7 @@ // https://wicg.github.io/web-locks/#lockmanager [ SecureContext, - Exposed=(Window,Worker), - RuntimeEnabled=WebLocksAPI + Exposed=(Window,Worker) ] interface LockManager { [CallWith=ScriptState, RaisesException, Measure] Promise<Lock> request( DOMString name,
diff --git a/third_party/blink/renderer/modules/locks/navigator_locks.idl b/third_party/blink/renderer/modules/locks/navigator_locks.idl index 7b9ef29b..79d2709 100644 --- a/third_party/blink/renderer/modules/locks/navigator_locks.idl +++ b/third_party/blink/renderer/modules/locks/navigator_locks.idl
@@ -6,8 +6,7 @@ [ SecureContext, Exposed=Window, - ImplementedAs=NavigatorLocks, - RuntimeEnabled=WebLocksAPI + ImplementedAs=NavigatorLocks ] partial interface Navigator { [CallWith=ScriptState] readonly attribute LockManager locks; };
diff --git a/third_party/blink/renderer/modules/locks/worker_navigator_locks.idl b/third_party/blink/renderer/modules/locks/worker_navigator_locks.idl index c8d07dc..cbbccdf 100644 --- a/third_party/blink/renderer/modules/locks/worker_navigator_locks.idl +++ b/third_party/blink/renderer/modules/locks/worker_navigator_locks.idl
@@ -6,8 +6,7 @@ [ SecureContext, Exposed=Worker, - ImplementedAs=NavigatorLocks, - RuntimeEnabled=WebLocksAPI + ImplementedAs=NavigatorLocks ] partial interface WorkerNavigator { [CallWith=ScriptState] readonly attribute LockManager locks; };
diff --git a/third_party/blink/renderer/modules/media_controls/elements/media_control_panel_element.cc b/third_party/blink/renderer/modules/media_controls/elements/media_control_panel_element.cc index 388b039..3bfca89 100644 --- a/third_party/blink/renderer/modules/media_controls/elements/media_control_panel_element.cc +++ b/third_party/blink/renderer/modules/media_controls/elements/media_control_panel_element.cc
@@ -64,6 +64,9 @@ private: void Invoke(ExecutionContext* context, Event* event) override { + if (event->target() != element_) + return; + if (event->type() == event_type_names::kTransitionend) { callback_.Run(); return;
diff --git a/third_party/blink/renderer/modules/media_controls/elements/media_control_panel_element_test.cc b/third_party/blink/renderer/modules/media_controls/elements/media_control_panel_element_test.cc index 334b4a3..a6faf08 100644 --- a/third_party/blink/renderer/modules/media_controls/elements/media_control_panel_element_test.cc +++ b/third_party/blink/renderer/modules/media_controls/elements/media_control_panel_element_test.cc
@@ -33,8 +33,8 @@ } protected: - void SimulateTransitionEnd() { - TriggerEvent(event_type_names::kTransitionend); + void SimulateTransitionEnd(Element& element) { + TriggerEvent(element, event_type_names::kTransitionend); } void ExpectPanelIsDisplayed() { EXPECT_TRUE(GetPanel().IsWanted()); } @@ -55,9 +55,10 @@ HTMLMediaElement& GetMediaElement() { return *media_element_.Get(); } private: - void TriggerEvent(const AtomicString& name) { + void TriggerEvent(Element& element, const AtomicString& name) { Event* event = Event::Create(name); - GetPanel().DispatchEvent(*event); + event->SetTarget(&element); + GetPanel().FireEventListeners(*event); } Persistent<HTMLMediaElement> media_element_; @@ -66,6 +67,9 @@ }; TEST_F(MediaControlPanelElementTest, StateTransitions) { + Element* child_div = HTMLDivElement::Create(GetPanel().GetDocument()); + GetPanel().ParserAppendChild(child_div); + // Make sure we are displayed (we are already opaque). GetPanel().SetIsDisplayed(true); ExpectPanelIsDisplayed(); @@ -75,10 +79,15 @@ EventListenerNotCreated(); GetPanel().MakeTransparent(); - // The event listener should now be attached so we should simulate the - // transition end and the panel will be hidden. + // The event listener should now be attached EventListenerAttached(); - SimulateTransitionEnd(); + + // Simulate child div transition end and the panel should not be hidden + SimulateTransitionEnd(*child_div); + ExpectPanelIsDisplayed(); + + // Simulate panel transition end and the panel will be hidden + SimulateTransitionEnd(GetPanel()); ExpectPanelIsNotDisplayed(); // The event listener should be detached. We should now make the panel @@ -89,7 +98,7 @@ // The event listener should now be attached so we should simulate the // transition end event and the panel will be hidden. EventListenerAttached(); - SimulateTransitionEnd(); + SimulateTransitionEnd(GetPanel()); ExpectPanelIsDisplayed(); }
diff --git a/third_party/blink/renderer/modules/media_controls/media_controls_impl.cc b/third_party/blink/renderer/modules/media_controls/media_controls_impl.cc index 01104b6..94c9a25 100644 --- a/third_party/blink/renderer/modules/media_controls/media_controls_impl.cc +++ b/third_party/blink/renderer/modules/media_controls/media_controls_impl.cc
@@ -85,9 +85,9 @@ #include "third_party/blink/renderer/modules/remoteplayback/html_media_element_remote_playback.h" #include "third_party/blink/renderer/modules/remoteplayback/remote_playback.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" -#include "third_party/blink/renderer/platform/layout_test_support.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/text/platform_locale.h" +#include "third_party/blink/renderer/platform/web_test_support.h" namespace blink { @@ -2213,10 +2213,10 @@ void MediaControlsImpl::OpenVolumeSliderIfNecessary() { if (ShouldOpenVolumeSlider()) { - volume_slider_wanted_timer_.StartOneShot( - LayoutTestSupport::IsRunningLayoutTest() ? kTimeToShowVolumeSliderTest + volume_slider_wanted_timer_.StartOneShot(WebTestSupport::IsRunningWebTest() + ? kTimeToShowVolumeSliderTest : kTimeToShowVolumeSlider, - FROM_HERE); + FROM_HERE); } }
diff --git a/third_party/blink/renderer/modules/media_controls/media_controls_impl_test.cc b/third_party/blink/renderer/modules/media_controls/media_controls_impl_test.cc index 71648251..79dbba89 100644 --- a/third_party/blink/renderer/modules/media_controls/media_controls_impl_test.cc +++ b/third_party/blink/renderer/modules/media_controls/media_controls_impl_test.cc
@@ -42,11 +42,11 @@ #include "third_party/blink/renderer/modules/remoteplayback/html_media_element_remote_playback.h" #include "third_party/blink/renderer/modules/remoteplayback/remote_playback.h" #include "third_party/blink/renderer/platform/heap/handle.h" -#include "third_party/blink/renderer/platform/layout_test_support.h" #include "third_party/blink/renderer/platform/testing/empty_web_media_player.h" #include "third_party/blink/renderer/platform/testing/histogram_tester.h" #include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h" #include "third_party/blink/renderer/platform/testing/unit_test_helpers.h" +#include "third_party/blink/renderer/platform/web_test_support.h" // The MediaTimelineWidths histogram suffix expected to be encountered in these // tests. Depends on the OS, since Android sizes its timeline differently. @@ -1290,7 +1290,7 @@ SetHasAudio(true); SimulateLoadedMetadata(); - LayoutTestSupport::SetIsRunningLayoutTest(false); + WebTestSupport::SetIsRunningWebTest(false); Element* volume_slider = GetElementByShadowPseudoId( MediaControls(), "-webkit-media-controls-volume-slider");
diff --git a/third_party/blink/renderer/modules/media_controls/media_controls_orientation_lock_delegate_test.cc b/third_party/blink/renderer/modules/media_controls/media_controls_orientation_lock_delegate_test.cc index d4b84b5..12def00 100644 --- a/third_party/blink/renderer/modules/media_controls/media_controls_orientation_lock_delegate_test.cc +++ b/third_party/blink/renderer/modules/media_controls/media_controls_orientation_lock_delegate_test.cc
@@ -30,10 +30,10 @@ #include "third_party/blink/renderer/modules/screen_orientation/screen_orientation_controller_impl.h" #include "third_party/blink/renderer/modules/screen_orientation/web_lock_orientation_callback.h" #include "third_party/blink/renderer/platform/geometry/int_rect.h" -#include "third_party/blink/renderer/platform/layout_test_support.h" #include "third_party/blink/renderer/platform/testing/empty_web_media_player.h" #include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h" #include "third_party/blink/renderer/platform/testing/unit_test_helpers.h" +#include "third_party/blink/renderer/platform/web_test_support.h" using testing::_; using testing::AtLeast; @@ -298,8 +298,8 @@ void SetUp() override { // Unset this to fix ScreenOrientationControllerImpl::ComputeOrientation. // TODO(mlamouri): Refactor to avoid this (crbug.com/726817). - was_running_layout_test_ = LayoutTestSupport::IsRunningLayoutTest(); - LayoutTestSupport::SetIsRunningLayoutTest(false); + was_running_layout_test_ = WebTestSupport::IsRunningWebTest(); + WebTestSupport::SetIsRunningWebTest(false); MediaControlsOrientationLockDelegateTest::SetUp(); @@ -315,7 +315,7 @@ void TearDown() override { MediaControlsOrientationLockDelegateTest::TearDown(); - LayoutTestSupport::SetIsRunningLayoutTest(was_running_layout_test_); + WebTestSupport::SetIsRunningWebTest(was_running_layout_test_); } void SetIsAutoRotateEnabledByUser(bool enabled) {
diff --git a/third_party/blink/renderer/modules/modules_idl_files.gni b/third_party/blink/renderer/modules/modules_idl_files.gni index 35f32d6b..9877418 100644 --- a/third_party/blink/renderer/modules/modules_idl_files.gni +++ b/third_party/blink/renderer/modules/modules_idl_files.gni
@@ -652,6 +652,7 @@ "push_messaging/push_event_init.idl", "push_messaging/push_subscription_options_init.idl", "quota/storage_estimate.idl", + "quota/storage_usage_details.idl", "sensor/sensor_error_event_init.idl", "sensor/sensor_options.idl", "sensor/spatial_sensor_options.idl",
diff --git a/third_party/blink/renderer/modules/quota/deprecated_storage_quota.cc b/third_party/blink/renderer/modules/quota/deprecated_storage_quota.cc index a2dd03eb..9be70c87 100644 --- a/third_party/blink/renderer/modules/quota/deprecated_storage_quota.cc +++ b/third_party/blink/renderer/modules/quota/deprecated_storage_quota.cc
@@ -42,6 +42,7 @@ #include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/modules/quota/dom_error.h" #include "third_party/blink/renderer/modules/quota/quota_utils.h" +#include "third_party/blink/renderer/modules/quota/storage_estimate.h" #include "third_party/blink/renderer/platform/bindings/script_state.h" #include "third_party/blink/renderer/platform/weborigin/kurl.h" #include "third_party/blink/renderer/platform/weborigin/security_origin.h" @@ -49,6 +50,7 @@ namespace blink { using mojom::StorageType; +using mojom::blink::UsageBreakdownPtr; namespace { @@ -68,7 +70,8 @@ V8PersistentCallbackFunction<V8StorageErrorCallback>* error_callback, mojom::QuotaStatusCode status_code, int64_t usage_in_bytes, - int64_t quota_in_bytes) { + int64_t quota_in_bytes, + UsageBreakdownPtr usage_breakdown) { if (status_code != mojom::QuotaStatusCode::kOk) { if (error_callback) { error_callback->InvokeAndReportException(nullptr, @@ -156,7 +159,8 @@ .QueryStorageUsageAndQuota( WrapRefCounted(security_origin), storage_type, mojo::WrapCallbackWithDefaultInvokeIfNotRun( - std::move(callback), mojom::QuotaStatusCode::kErrorAbort, 0, 0)); + std::move(callback), mojom::QuotaStatusCode::kErrorAbort, 0, 0, + nullptr)); } void DeprecatedStorageQuota::requestQuota(
diff --git a/third_party/blink/renderer/modules/quota/storage_estimate.idl b/third_party/blink/renderer/modules/quota/storage_estimate.idl index 3b38d019..46b9a73 100644 --- a/third_party/blink/renderer/modules/quota/storage_estimate.idl +++ b/third_party/blink/renderer/modules/quota/storage_estimate.idl
@@ -7,4 +7,5 @@ dictionary StorageEstimate { unsigned long long usage; unsigned long long quota; + [RuntimeEnabled=StorageQuotaDetails] StorageUsageDetails usageDetails; };
diff --git a/third_party/blink/renderer/modules/quota/storage_manager.cc b/third_party/blink/renderer/modules/quota/storage_manager.cc index fff001f..764d93a 100644 --- a/third_party/blink/renderer/modules/quota/storage_manager.cc +++ b/third_party/blink/renderer/modules/quota/storage_manager.cc
@@ -6,6 +6,7 @@ #include "mojo/public/cpp/bindings/callback_helpers.h" #include "services/service_manager/public/cpp/interface_provider.h" +#include "third_party/blink/public/mojom/quota/quota_types.mojom-blink.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_storage_estimate.h" @@ -25,6 +26,7 @@ using mojom::blink::PermissionName; using mojom::blink::PermissionService; using mojom::blink::PermissionStatus; +using mojom::blink::UsageBreakdownPtr; namespace { @@ -34,7 +36,8 @@ void QueryStorageUsageAndQuotaCallback(ScriptPromiseResolver* resolver, mojom::QuotaStatusCode status_code, int64_t usage_in_bytes, - int64_t quota_in_bytes) { + int64_t quota_in_bytes, + UsageBreakdownPtr usage_breakdown) { if (status_code != mojom::QuotaStatusCode::kOk) { // TODO(sashab): Replace this with a switch statement, and remove the enum // values from QuotaStatusCode. @@ -46,6 +49,27 @@ StorageEstimate* estimate = StorageEstimate::Create(); estimate->setUsage(usage_in_bytes); estimate->setQuota(quota_in_bytes); + + // We only want to show usage details for systems that are used by the app, + // this way we do not create any web compatibility issues by unecessarily + // exposing obsoleted/proprietary storage systems, but also report when + // those systems are in use. + StorageUsageDetails* details = StorageUsageDetails::Create(); + if (usage_breakdown->appcache) { + details->setApplicationCache(usage_breakdown->appcache); + } + if (usage_breakdown->indexedDatabase) { + details->setIndexedDB(usage_breakdown->indexedDatabase); + } + if (usage_breakdown->serviceWorkerCache) { + details->setCaches(usage_breakdown->serviceWorkerCache); + } + if (usage_breakdown->serviceWorker) { + details->setServiceWorkerRegistrations(usage_breakdown->serviceWorker); + } + + estimate->setUsageDetails(details); + resolver->Resolve(estimate); } @@ -115,7 +139,8 @@ .QueryStorageUsageAndQuota( WrapRefCounted(security_origin), mojom::StorageType::kTemporary, mojo::WrapCallbackWithDefaultInvokeIfNotRun( - std::move(callback), mojom::QuotaStatusCode::kErrorAbort, 0, 0)); + std::move(callback), mojom::QuotaStatusCode::kErrorAbort, 0, 0, + nullptr)); return promise; }
diff --git a/third_party/blink/renderer/modules/quota/storage_usage_details.idl b/third_party/blink/renderer/modules/quota/storage_usage_details.idl new file mode 100644 index 0000000..4163a9a --- /dev/null +++ b/third_party/blink/renderer/modules/quota/storage_usage_details.idl
@@ -0,0 +1,13 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// https://storage.spec.whatwg.org/#api + +dictionary StorageUsageDetails { + unsigned long long applicationCache; + unsigned long long indexedDB; + unsigned long long caches; + unsigned long long serviceWorkerRegistrations; + unsigned long long websql; +};
diff --git a/third_party/blink/renderer/modules/screen_orientation/screen_orientation_controller_impl.cc b/third_party/blink/renderer/modules/screen_orientation/screen_orientation_controller_impl.cc index 92b9887..e533cab2 100644 --- a/third_party/blink/renderer/modules/screen_orientation/screen_orientation_controller_impl.cc +++ b/third_party/blink/renderer/modules/screen_orientation/screen_orientation_controller_impl.cc
@@ -18,7 +18,7 @@ #include "third_party/blink/renderer/core/page/page.h" #include "third_party/blink/renderer/modules/screen_orientation/screen_orientation.h" #include "third_party/blink/renderer/modules/screen_orientation/screen_orientation_dispatcher.h" -#include "third_party/blink/renderer/platform/layout_test_support.h" +#include "third_party/blink/renderer/platform/web_test_support.h" namespace blink { @@ -55,10 +55,10 @@ WebScreenOrientationType ScreenOrientationControllerImpl::ComputeOrientation( const IntRect& rect, uint16_t rotation) { - // Bypass orientation detection in layout tests to get consistent results. - // FIXME: The screen dimension should be fixed when running the layout tests + // Bypass orientation detection in web tests to get consistent results. + // FIXME: The screen dimension should be fixed when running the web tests // to avoid such issues. - if (LayoutTestSupport::IsRunningLayoutTest()) + if (WebTestSupport::IsRunningWebTest()) return kWebScreenOrientationPortraitPrimary; bool is_tall_display = rotation % 180 ? rect.Height() < rect.Width()
diff --git a/third_party/blink/renderer/modules/sensor/sensor.cc b/third_party/blink/renderer/modules/sensor/sensor.cc index 76953d0d..b4efc3b 100644 --- a/third_party/blink/renderer/modules/sensor/sensor.cc +++ b/third_party/blink/renderer/modules/sensor/sensor.cc
@@ -15,7 +15,7 @@ #include "third_party/blink/renderer/core/timing/window_performance.h" #include "third_party/blink/renderer/modules/sensor/sensor_error_event.h" #include "third_party/blink/renderer/modules/sensor/sensor_provider_proxy.h" -#include "third_party/blink/renderer/platform/layout_test_support.h" +#include "third_party/blink/renderer/platform/web_test_support.h" namespace blink { @@ -130,7 +130,7 @@ DCHECK(sensor_proxy_); is_null = false; - if (LayoutTestSupport::IsRunningLayoutTest()) { + if (WebTestSupport::IsRunningWebTest()) { // In layout tests performance.now() * 0.001 is passed to the shared buffer. return sensor_proxy_->GetReading().timestamp() * 1000; }
diff --git a/third_party/blink/renderer/modules/sensor/sensor_proxy.cc b/third_party/blink/renderer/modules/sensor/sensor_proxy.cc index ec5b6d7..9b3fed19 100644 --- a/third_party/blink/renderer/modules/sensor/sensor_proxy.cc +++ b/third_party/blink/renderer/modules/sensor/sensor_proxy.cc
@@ -13,7 +13,7 @@ #include "third_party/blink/renderer/core/page/focus_controller.h" #include "third_party/blink/renderer/modules/sensor/sensor_provider_proxy.h" #include "third_party/blink/renderer/modules/sensor/sensor_reading_remapper.h" -#include "third_party/blink/renderer/platform/layout_test_support.h" +#include "third_party/blink/renderer/platform/web_test_support.h" #include "third_party/blink/renderer/platform/weborigin/security_origin.h" namespace blink { @@ -67,7 +67,7 @@ namespace { uint16_t GetScreenOrientationAngleForPage(Page* page) { - if (LayoutTestSupport::IsRunningLayoutTest()) { + if (WebTestSupport::IsRunningWebTest()) { // Simulate that the device is turned 90 degrees on the right. // 'orientation_angle' must be 270 as per // https://w3c.github.io/screen-orientation/#dfn-update-the-orientation-information.
diff --git a/third_party/blink/renderer/modules/service_worker/wait_until_observer.cc b/third_party/blink/renderer/modules/service_worker/wait_until_observer.cc index 8d37624..1b06663 100644 --- a/third_party/blink/renderer/modules/service_worker/wait_until_observer.cc +++ b/third_party/blink/renderer/modules/service_worker/wait_until_observer.cc
@@ -13,8 +13,8 @@ #include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h" #include "third_party/blink/renderer/platform/bindings/microtask.h" -#include "third_party/blink/renderer/platform/layout_test_support.h" #include "third_party/blink/renderer/platform/scheduler/public/thread.h" +#include "third_party/blink/renderer/platform/web_test_support.h" #include "third_party/blink/renderer/platform/wtf/assertions.h" #include "v8/include/v8.h" @@ -28,7 +28,7 @@ const unsigned kWindowInteractionTimeoutForTest = 1; TimeDelta WindowInteractionTimeout() { - return TimeDelta::FromSeconds(LayoutTestSupport::IsRunningLayoutTest() + return TimeDelta::FromSeconds(WebTestSupport::IsRunningWebTest() ? kWindowInteractionTimeoutForTest : kWindowInteractionTimeout); }
diff --git a/third_party/blink/renderer/modules/webaudio/audio_node_input.cc b/third_party/blink/renderer/modules/webaudio/audio_node_input.cc index a85602e4..ab84b0e6 100644 --- a/third_party/blink/renderer/modules/webaudio/audio_node_input.cc +++ b/third_party/blink/renderer/modules/webaudio/audio_node_input.cc
@@ -33,7 +33,7 @@ namespace blink { -inline AudioNodeInput::AudioNodeInput(AudioHandler& handler) +AudioNodeInput::AudioNodeInput(AudioHandler& handler) : AudioSummingJunction(handler.Context()->GetDeferredTaskHandler()), handler_(handler) { // Set to mono by default. @@ -41,6 +41,18 @@ AudioBus::Create(1, audio_utilities::kRenderQuantumFrames); } +AudioNodeInput::~AudioNodeInput() { + GetDeferredTaskHandler().AssertGraphOwner(); + + for (AudioNodeOutput* output : outputs_) + output->RemoveInput(*this); + for (AudioNodeOutput* output : disabled_outputs_) + output->RemoveInput(*this); + outputs_.clear(); + disabled_outputs_.clear(); + ChangedOutputs(); +} + std::unique_ptr<AudioNodeInput> AudioNodeInput::Create(AudioHandler& handler) { return base::WrapUnique(new AudioNodeInput(handler)); }
diff --git a/third_party/blink/renderer/modules/webaudio/audio_node_input.h b/third_party/blink/renderer/modules/webaudio/audio_node_input.h index 85b5048..82d1092 100644 --- a/third_party/blink/renderer/modules/webaudio/audio_node_input.h +++ b/third_party/blink/renderer/modules/webaudio/audio_node_input.h
@@ -27,6 +27,7 @@ #define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBAUDIO_AUDIO_NODE_INPUT_H_ #include <memory> +#include "third_party/blink/renderer/modules/modules_export.h" #include "third_party/blink/renderer/modules/webaudio/audio_node.h" #include "third_party/blink/renderer/modules/webaudio/audio_summing_junction.h" #include "third_party/blink/renderer/platform/audio/audio_bus.h" @@ -43,11 +44,12 @@ // number of channels of the input's bus is the maximum of the number of // channels of all its connections. -class AudioNodeInput final : public AudioSummingJunction { +class MODULES_EXPORT AudioNodeInput final : public AudioSummingJunction { USING_FAST_MALLOC(AudioNodeInput); public: static std::unique_ptr<AudioNodeInput> Create(AudioHandler&); + ~AudioNodeInput() override; // AudioSummingJunction void DidUpdate() override;
diff --git a/third_party/blink/renderer/modules/webaudio/audio_node_input_test.cc b/third_party/blink/renderer/modules/webaudio/audio_node_input_test.cc new file mode 100644 index 0000000..072bf6f5 --- /dev/null +++ b/third_party/blink/renderer/modules/webaudio/audio_node_input_test.cc
@@ -0,0 +1,65 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/modules/webaudio/audio_node.h" + +#include <memory> +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/renderer/core/testing/dummy_page_holder.h" +#include "third_party/blink/renderer/modules/webaudio/audio_node_input.h" +#include "third_party/blink/renderer/modules/webaudio/audio_node_output.h" +#include "third_party/blink/renderer/modules/webaudio/delay_node.h" +#include "third_party/blink/renderer/modules/webaudio/offline_audio_context.h" + +namespace blink { + +TEST(AudioNodeInputTest, InputDestroyedBeforeOutput) { + auto page = DummyPageHolder::Create(); + OfflineAudioContext* context = OfflineAudioContext::Create( + &page->GetDocument(), 2, 1, 48000, ASSERT_NO_EXCEPTION); + DelayNode* node1 = context->createDelay(ASSERT_NO_EXCEPTION); + auto& handler1 = node1->Handler(); + DelayNode* node2 = context->createDelay(ASSERT_NO_EXCEPTION); + auto& handler2 = node2->Handler(); + + auto input = AudioNodeInput::Create(handler1); + auto output = AudioNodeOutput::Create(&handler2, 0); + + { + BaseAudioContext::GraphAutoLocker graph_lock(context); + input->Connect(*output); + ASSERT_TRUE(output->IsConnected()); + + // This should not crash. + input.reset(); + output->Dispose(); + output.reset(); + } +} + +TEST(AudioNodeInputTest, OutputDestroyedBeforeInput) { + auto page = DummyPageHolder::Create(); + OfflineAudioContext* context = OfflineAudioContext::Create( + &page->GetDocument(), 2, 1, 48000, ASSERT_NO_EXCEPTION); + DelayNode* node1 = context->createDelay(ASSERT_NO_EXCEPTION); + auto& handler1 = node1->Handler(); + DelayNode* node2 = context->createDelay(ASSERT_NO_EXCEPTION); + auto& handler2 = node2->Handler(); + + auto input = AudioNodeInput::Create(handler1); + auto output = AudioNodeOutput::Create(&handler2, 0); + + { + BaseAudioContext::GraphAutoLocker graph_lock(context); + input->Connect(*output); + ASSERT_TRUE(output->IsConnected()); + + // This should not crash. + output->Dispose(); + output.reset(); + input.reset(); + } +} + +} // namespace blink
diff --git a/third_party/blink/renderer/modules/webaudio/audio_node_output.h b/third_party/blink/renderer/modules/webaudio/audio_node_output.h index dd76a98..2dbe62c 100644 --- a/third_party/blink/renderer/modules/webaudio/audio_node_output.h +++ b/third_party/blink/renderer/modules/webaudio/audio_node_output.h
@@ -28,6 +28,7 @@ #include <memory> #include "base/memory/scoped_refptr.h" +#include "third_party/blink/renderer/modules/modules_export.h" #include "third_party/blink/renderer/modules/webaudio/audio_node.h" #include "third_party/blink/renderer/modules/webaudio/audio_param.h" #include "third_party/blink/renderer/platform/audio/audio_bus.h" @@ -39,7 +40,7 @@ // AudioNodeOutput represents a single output for an AudioNode. // It may be connected to one or more AudioNodeInputs. -class AudioNodeOutput final { +class MODULES_EXPORT AudioNodeOutput final { USING_FAST_MALLOC(AudioNodeOutput); public:
diff --git a/third_party/blink/renderer/platform/BUILD.gn b/third_party/blink/renderer/platform/BUILD.gn index fb433a44..d584c90 100644 --- a/third_party/blink/renderer/platform/BUILD.gn +++ b/third_party/blink/renderer/platform/BUILD.gn
@@ -1167,8 +1167,6 @@ "keyboard_codes.h", "language.cc", "language.h", - "layout_test_support.cc", - "layout_test_support.h", "lifecycle_notifier.h", "lifecycle_observer.h", "link_hash.cc", @@ -1366,6 +1364,8 @@ "web_mouse_wheel_event.cc", "web_pointer_event.cc", "web_task_runner.h", + "web_test_support.cc", + "web_test_support.h", "web_text_input_info.cc", "web_thread_supporting_gc.cc", "web_thread_supporting_gc.h", @@ -2113,6 +2113,7 @@ "graphics/test/fake_canvas_resource_host.h", "graphics/test/fake_gles2_interface.h", "graphics/test/fake_web_graphics_context_3d_provider.h", + "graphics/test/gpu_memory_buffer_test_platform.h", "graphics/test/mock_compositor_frame_sink.h", "graphics/test/mock_embedded_frame_sink_provider.h", "graphics/test/mock_image_decoder.h",
diff --git a/third_party/blink/renderer/platform/fonts/DEPS b/third_party/blink/renderer/platform/fonts/DEPS index 941f8cd..d859ec6 100644 --- a/third_party/blink/renderer/platform/fonts/DEPS +++ b/third_party/blink/renderer/platform/fonts/DEPS
@@ -13,7 +13,6 @@ "+third_party/blink/renderer/platform/histogram.h", "+third_party/blink/renderer/platform/instrumentation", "+third_party/blink/renderer/platform/language.h", - "+third_party/blink/renderer/platform/layout_test_support.h", "+third_party/blink/renderer/platform/mac/version_util_mac.h", "+third_party/blink/renderer/platform/platform_export.h", "+third_party/blink/renderer/platform/resolution_units.h", @@ -22,5 +21,6 @@ "+third_party/blink/renderer/platform/shared_buffer.h", "+third_party/blink/renderer/platform/testing", "+third_party/blink/renderer/platform/text", + "+third_party/blink/renderer/platform/web_test_support.h", "+third_party/blink/renderer/platform/wtf", ]
diff --git a/third_party/blink/renderer/platform/fonts/font_platform_data.cc b/third_party/blink/renderer/platform/fonts/font_platform_data.cc index e8529448..64dd821 100644 --- a/third_party/blink/renderer/platform/fonts/font_platform_data.cc +++ b/third_party/blink/renderer/platform/fonts/font_platform_data.cc
@@ -29,8 +29,8 @@ #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/renderer/platform/fonts/font_cache.h" #include "third_party/blink/renderer/platform/fonts/shaping/harfbuzz_face.h" -#include "third_party/blink/renderer/platform/layout_test_support.h" #include "third_party/blink/renderer/platform/text/character.h" +#include "third_party/blink/renderer/platform/web_test_support.h" #include "third_party/blink/renderer/platform/wtf/hash_map.h" #include "third_party/blink/renderer/platform/wtf/text/character_names.h" #include "third_party/blink/renderer/platform/wtf/text/string_hash.h" @@ -148,11 +148,11 @@ auto system_style = QuerySystemRenderStyle(family_, text_size_, typeface_->fontStyle()); - // In layout tests, ignore system preference for subpixel positioning, + // In web tests, ignore system preference for subpixel positioning, // or explicitly disable if requested. - if (LayoutTestSupport::IsRunningLayoutTest()) { + if (WebTestSupport::IsRunningWebTest()) { system_style.use_subpixel_positioning = - LayoutTestSupport::IsTextSubpixelPositioningAllowedForTest() + WebTestSupport::IsTextSubpixelPositioningAllowedForTest() ? WebFontRenderStyle::kNoPreference : 0; }
diff --git a/third_party/blink/renderer/platform/fonts/mac/font_cache_mac.mm b/third_party/blink/renderer/platform/fonts/mac/font_cache_mac.mm index 751e6c26..829170d 100644 --- a/third_party/blink/renderer/platform/fonts/mac/font_cache_mac.mm +++ b/third_party/blink/renderer/platform/fonts/mac/font_cache_mac.mm
@@ -39,9 +39,9 @@ #include "third_party/blink/renderer/platform/fonts/font_platform_data.h" #include "third_party/blink/renderer/platform/fonts/mac/font_matcher_mac.h" #include "third_party/blink/renderer/platform/fonts/simple_font_data.h" -#include "third_party/blink/renderer/platform/layout_test_support.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/scheduler/public/thread.h" +#include "third_party/blink/renderer/platform/web_test_support.h" #include "third_party/blink/renderer/platform/wtf/functional.h" #include "third_party/blink/renderer/platform/wtf/std_lib_extras.h" @@ -87,9 +87,9 @@ } static bool UseHinting() { - // Enable hinting only when antialiasing is disabled in layout tests. - return (LayoutTestSupport::IsRunningLayoutTest() && - !LayoutTestSupport::IsFontAntialiasingEnabledForTest()); + // Enable hinting only when antialiasing is disabled in web tests. + return (WebTestSupport::IsRunningWebTest() && + !WebTestSupport::IsFontAntialiasingEnabledForTest()); } void FontCache::PlatformInit() {
diff --git a/third_party/blink/renderer/platform/fonts/mac/font_platform_data_mac.mm b/third_party/blink/renderer/platform/fonts/mac/font_platform_data_mac.mm index cda5492..97bebbd 100644 --- a/third_party/blink/renderer/platform/fonts/mac/font_platform_data_mac.mm +++ b/third_party/blink/renderer/platform/fonts/mac/font_platform_data_mac.mm
@@ -30,7 +30,7 @@ #import "third_party/blink/renderer/platform/fonts/font.h" #import "third_party/blink/renderer/platform/fonts/opentype/font_settings.h" #import "third_party/blink/renderer/platform/fonts/shaping/harfbuzz_face.h" -#import "third_party/blink/renderer/platform/layout_test_support.h" +#import "third_party/blink/renderer/platform/web_test_support.h" #import "third_party/blink/renderer/platform/wtf/retain_ptr.h" #import "third_party/blink/renderer/platform/wtf/text/wtf_string.h" #import "third_party/skia/include/core/SkFont.h" @@ -137,12 +137,12 @@ } } - if (LayoutTestSupport::IsRunningLayoutTest()) { + if (WebTestSupport::IsRunningWebTest()) { should_smooth_fonts = false; - should_antialias = should_antialias && - LayoutTestSupport::IsFontAntialiasingEnabledForTest(); + should_antialias = + should_antialias && WebTestSupport::IsFontAntialiasingEnabledForTest(); should_subpixel_position = - LayoutTestSupport::IsTextSubpixelPositioningAllowedForTest(); + WebTestSupport::IsTextSubpixelPositioningAllowedForTest(); } paint->setAntiAlias(should_antialias); @@ -189,12 +189,12 @@ } } - if (LayoutTestSupport::IsRunningLayoutTest()) { + if (WebTestSupport::IsRunningWebTest()) { should_smooth_fonts = false; - should_antialias = should_antialias && - LayoutTestSupport::IsFontAntialiasingEnabledForTest(); + should_antialias = + should_antialias && WebTestSupport::IsFontAntialiasingEnabledForTest(); should_subpixel_position = - LayoutTestSupport::IsTextSubpixelPositioningAllowedForTest(); + WebTestSupport::IsTextSubpixelPositioningAllowedForTest(); } if (should_antialias && should_smooth_fonts) {
diff --git a/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper_test.cc b/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper_test.cc index a58d78c..35e0d66e 100644 --- a/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper_test.cc +++ b/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper_test.cc
@@ -16,11 +16,11 @@ #include "third_party/blink/renderer/platform/fonts/shaping/shape_result_inline_headers.h" #include "third_party/blink/renderer/platform/fonts/shaping/shape_result_spacing.h" #include "third_party/blink/renderer/platform/fonts/shaping/shape_result_test_info.h" -#include "third_party/blink/renderer/platform/layout_test_support.h" #include "third_party/blink/renderer/platform/testing/font_test_helpers.h" #include "third_party/blink/renderer/platform/testing/unit_test_helpers.h" #include "third_party/blink/renderer/platform/text/text_break_iterator.h" #include "third_party/blink/renderer/platform/text/text_run.h" +#include "third_party/blink/renderer/platform/web_test_support.h" #include "third_party/blink/renderer/platform/wtf/vector.h" using testing::ElementsAre; @@ -114,40 +114,40 @@ class ScopedSubpixelOverride { public: ScopedSubpixelOverride(bool b) { - prev_layout_test_ = LayoutTestSupport::IsRunningLayoutTest(); + prev_layout_test_ = WebTestSupport::IsRunningWebTest(); prev_subpixel_allowed_ = - LayoutTestSupport::IsTextSubpixelPositioningAllowedForTest(); - prev_antialias_ = LayoutTestSupport::IsFontAntialiasingEnabledForTest(); + WebTestSupport::IsTextSubpixelPositioningAllowedForTest(); + prev_antialias_ = WebTestSupport::IsFontAntialiasingEnabledForTest(); prev_fd_subpixel_ = FontDescription::SubpixelPositioning(); - // This is required for all LayoutTestSupport settings to have effects. - LayoutTestSupport::SetIsRunningLayoutTest(true); + // This is required for all WebTestSupport settings to have effects. + WebTestSupport::SetIsRunningWebTest(true); if (b) { // Allow subpixel positioning. - LayoutTestSupport::SetTextSubpixelPositioningAllowedForTest(true); + WebTestSupport::SetTextSubpixelPositioningAllowedForTest(true); // Now, enable subpixel positioning in platform-specific ways. // Mac always enables subpixel positioning. // On Windows, subpixel positioning also requires antialiasing. - LayoutTestSupport::SetFontAntialiasingEnabledForTest(true); + WebTestSupport::SetFontAntialiasingEnabledForTest(true); // On platforms other than Windows and Mac this needs to be set as // well. FontDescription::SetSubpixelPositioning(true); } else { // Explicitly disallow all subpixel positioning. - LayoutTestSupport::SetTextSubpixelPositioningAllowedForTest(false); + WebTestSupport::SetTextSubpixelPositioningAllowedForTest(false); } } ~ScopedSubpixelOverride() { FontDescription::SetSubpixelPositioning(prev_fd_subpixel_); - LayoutTestSupport::SetFontAntialiasingEnabledForTest(prev_antialias_); - LayoutTestSupport::SetTextSubpixelPositioningAllowedForTest( + WebTestSupport::SetFontAntialiasingEnabledForTest(prev_antialias_); + WebTestSupport::SetTextSubpixelPositioningAllowedForTest( prev_subpixel_allowed_); - LayoutTestSupport::SetIsRunningLayoutTest(prev_layout_test_); + WebTestSupport::SetIsRunningWebTest(prev_layout_test_); // Fonts cached with a different subpixel positioning state are not // automatically invalidated and need to be cleared between test
diff --git a/third_party/blink/renderer/platform/fonts/web_font_render_style.cc b/third_party/blink/renderer/platform/fonts/web_font_render_style.cc index a1f9b21b..b63f8a2 100644 --- a/third_party/blink/renderer/platform/fonts/web_font_render_style.cc +++ b/third_party/blink/renderer/platform/fonts/web_font_render_style.cc
@@ -7,7 +7,7 @@ #include "build/build_config.h" #include "third_party/blink/renderer/platform/fonts/font_cache.h" #include "third_party/blink/renderer/platform/fonts/font_description.h" -#include "third_party/blink/renderer/platform/layout_test_support.h" +#include "third_party/blink/renderer/platform/web_test_support.h" #include <SkFont.h> @@ -108,9 +108,9 @@ font.setLCDRenderText(use_subpixel_rendering); // Force-enable subpixel positioning, except when full hinting is requested on - // low-dpi screen or when running layout tests. + // low-dpi screen or when running web tests. bool force_subpixel_positioning = - !LayoutTestSupport::IsRunningLayoutTest() && + !WebTestSupport::IsRunningWebTest() && (sk_hint_style != SkFontHinting::kFull || device_scale_factor > 1.0f); font.setSubpixelText(force_subpixel_positioning || use_subpixel_positioning); @@ -131,9 +131,9 @@ } // Force-enable subpixel positioning, except when full hinting is requested on - // low-dpi screen or when running layout tests. + // low-dpi screen or when running web tests. bool force_subpixel_positioning = - !LayoutTestSupport::IsRunningLayoutTest() && + !WebTestSupport::IsRunningWebTest() && (sk_hint_style != SkFontHinting::kFull || device_scale_factor > 1.0f); font->setSubpixel(force_subpixel_positioning || use_subpixel_positioning);
diff --git a/third_party/blink/renderer/platform/fonts/win/font_platform_data_win.cc b/third_party/blink/renderer/platform/fonts/win/font_platform_data_win.cc index ed89ed8..4fc4b20d 100644 --- a/third_party/blink/renderer/platform/fonts/win/font_platform_data_win.cc +++ b/third_party/blink/renderer/platform/fonts/win/font_platform_data_win.cc
@@ -35,7 +35,7 @@ #include "SkFont.h" #include "SkTypeface.h" #include "third_party/blink/renderer/platform/fonts/font_cache.h" -#include "third_party/blink/renderer/platform/layout_test_support.h" +#include "third_party/blink/renderer/platform/web_test_support.h" namespace blink { @@ -61,8 +61,8 @@ if (text_flags & SkPaint::kAntiAlias_Flag) flags |= SkPaint::kSubpixelText_Flag; - if (LayoutTestSupport::IsRunningLayoutTest() && - !LayoutTestSupport::IsTextSubpixelPositioningAllowedForTest()) + if (WebTestSupport::IsRunningWebTest() && + !WebTestSupport::IsTextSubpixelPositioningAllowedForTest()) flags &= ~SkPaint::kSubpixelText_Flag; SkASSERT(!(text_flags & ~kTextFlagsMask)); @@ -98,8 +98,8 @@ if (text_flags & SkPaint::kAntiAlias_Flag) font->setSubpixel(true); - if (LayoutTestSupport::IsRunningLayoutTest() && - !LayoutTestSupport::IsTextSubpixelPositioningAllowedForTest()) + if (WebTestSupport::IsRunningWebTest() && + !WebTestSupport::IsTextSubpixelPositioningAllowedForTest()) font->setSubpixel(false); font->setEmbeddedBitmaps(!avoid_embedded_bitmaps_); @@ -114,8 +114,8 @@ } static int ComputePaintTextFlags(String font_family_name) { - if (LayoutTestSupport::IsRunningLayoutTest()) - return LayoutTestSupport::IsFontAntialiasingEnabledForTest() + if (WebTestSupport::IsRunningWebTest()) + return WebTestSupport::IsFontAntialiasingEnabledForTest() ? SkPaint::kAntiAlias_Flag : 0;
diff --git a/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge_test.cc b/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge_test.cc index f42c6f8..97e51b4 100644 --- a/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge_test.cc +++ b/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge_test.cc
@@ -53,11 +53,11 @@ #include "third_party/blink/renderer/platform/graphics/test/fake_canvas_resource_host.h" #include "third_party/blink/renderer/platform/graphics/test/fake_gles2_interface.h" #include "third_party/blink/renderer/platform/graphics/test/fake_web_graphics_context_3d_provider.h" +#include "third_party/blink/renderer/platform/graphics/test/gpu_memory_buffer_test_platform.h" #include "third_party/blink/renderer/platform/graphics/web_graphics_context_3d_provider_wrapper.h" #include "third_party/blink/renderer/platform/scheduler/public/thread.h" #include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h" #include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h" -#include "third_party/blink/renderer/platform/testing/testing_platform_support.h" #include "third_party/blink/renderer/platform/waitable_event.h" #include "third_party/skia/include/core/SkSurface.h" #include "third_party/skia/include/gpu/gl/GrGLTypes.h" @@ -91,20 +91,6 @@ } }; -class FakePlatformSupport : public TestingPlatformSupport { - public: - void RunUntilStop() const { base::RunLoop().Run(); } - - void StopRunning() const { base::RunLoop().Quit(); } - - private: - gpu::GpuMemoryBufferManager* GetGpuMemoryBufferManager() override { - return &test_gpu_memory_buffer_manager_; - } - - viz::TestGpuMemoryBufferManager test_gpu_memory_buffer_manager_; -}; - class ImageTrackingDecodeCache : public cc::StubDecodeCache { public: ImageTrackingDecodeCache() = default; @@ -421,7 +407,7 @@ TEST_F(Canvas2DLayerBridgeTest, DISABLED_HibernationLifeCycle) #endif { - ScopedTestingPlatformSupport<FakePlatformSupport> platform; + ScopedTestingPlatformSupport<GpuMemoryBufferTestPlatform> platform; std::unique_ptr<Canvas2DLayerBridge> bridge = MakeBridge(IntSize(300, 300), Canvas2DLayerBridge::kEnableAcceleration, CanvasColorParams()); @@ -467,7 +453,7 @@ TEST_F(Canvas2DLayerBridgeTest, DISABLED_HibernationReEntry) #endif { - ScopedTestingPlatformSupport<FakePlatformSupport> platform; + ScopedTestingPlatformSupport<GpuMemoryBufferTestPlatform> platform; std::unique_ptr<Canvas2DLayerBridge> bridge = MakeBridge(IntSize(300, 300), Canvas2DLayerBridge::kEnableAcceleration, CanvasColorParams()); @@ -517,7 +503,7 @@ DISABLED_HibernationLifeCycleWithDeferredRenderingDisabled) #endif { - ScopedTestingPlatformSupport<FakePlatformSupport> platform; + ScopedTestingPlatformSupport<GpuMemoryBufferTestPlatform> platform; std::unique_ptr<Canvas2DLayerBridge> bridge = MakeBridge(IntSize(300, 300), Canvas2DLayerBridge::kEnableAcceleration, @@ -566,7 +552,7 @@ TEST_F(Canvas2DLayerBridgeTest, DISABLED_BackgroundRenderingWhileHibernating) #endif { - ScopedTestingPlatformSupport<FakePlatformSupport> platform; + ScopedTestingPlatformSupport<GpuMemoryBufferTestPlatform> platform; std::unique_ptr<Canvas2DLayerBridge> bridge = MakeBridge(IntSize(300, 300), Canvas2DLayerBridge::kEnableAcceleration, CanvasColorParams()); @@ -619,7 +605,7 @@ DISABLED_BackgroundRenderingWhileHibernatingWithDeferredRenderingDisabled) #endif { - ScopedTestingPlatformSupport<FakePlatformSupport> platform; + ScopedTestingPlatformSupport<GpuMemoryBufferTestPlatform> platform; std::unique_ptr<Canvas2DLayerBridge> bridge = MakeBridge(IntSize(300, 300), Canvas2DLayerBridge::kEnableAcceleration, CanvasColorParams()); @@ -677,7 +663,7 @@ DISABLED_DisableDeferredRenderingWhileHibernating) #endif { - ScopedTestingPlatformSupport<FakePlatformSupport> platform; + ScopedTestingPlatformSupport<GpuMemoryBufferTestPlatform> platform; std::unique_ptr<Canvas2DLayerBridge> bridge = MakeBridge(IntSize(300, 300), Canvas2DLayerBridge::kEnableAcceleration, CanvasColorParams()); @@ -738,7 +724,7 @@ TEST_F(Canvas2DLayerBridgeTest, DISABLED_TeardownWhileHibernating) #endif { - ScopedTestingPlatformSupport<FakePlatformSupport> platform; + ScopedTestingPlatformSupport<GpuMemoryBufferTestPlatform> platform; std::unique_ptr<Canvas2DLayerBridge> bridge = MakeBridge(IntSize(300, 300), Canvas2DLayerBridge::kEnableAcceleration, CanvasColorParams()); @@ -776,7 +762,7 @@ TEST_F(Canvas2DLayerBridgeTest, DISABLED_SnapshotWhileHibernating) #endif { - ScopedTestingPlatformSupport<FakePlatformSupport> platform; + ScopedTestingPlatformSupport<GpuMemoryBufferTestPlatform> platform; std::unique_ptr<Canvas2DLayerBridge> bridge = MakeBridge(IntSize(300, 300), Canvas2DLayerBridge::kEnableAcceleration, CanvasColorParams()); @@ -825,7 +811,7 @@ TEST_F(Canvas2DLayerBridgeTest, DISABLED_TeardownWhileHibernationIsPending) #endif { - ScopedTestingPlatformSupport<FakePlatformSupport> platform; + ScopedTestingPlatformSupport<GpuMemoryBufferTestPlatform> platform; std::unique_ptr<Canvas2DLayerBridge> bridge = MakeBridge(IntSize(300, 300), Canvas2DLayerBridge::kEnableAcceleration, CanvasColorParams()); @@ -859,7 +845,7 @@ DISABLED_HibernationAbortedDueToVisibilityChange) #endif { - ScopedTestingPlatformSupport<FakePlatformSupport> platform; + ScopedTestingPlatformSupport<GpuMemoryBufferTestPlatform> platform; std::unique_ptr<Canvas2DLayerBridge> bridge = MakeBridge(IntSize(300, 300), Canvas2DLayerBridge::kEnableAcceleration, CanvasColorParams()); @@ -895,7 +881,7 @@ TEST_F(Canvas2DLayerBridgeTest, DISABLED_HibernationAbortedDueToLostContext) #endif { - ScopedTestingPlatformSupport<FakePlatformSupport> platform; + ScopedTestingPlatformSupport<GpuMemoryBufferTestPlatform> platform; std::unique_ptr<Canvas2DLayerBridge> bridge = MakeBridge(IntSize(300, 300), Canvas2DLayerBridge::kEnableAcceleration, CanvasColorParams()); @@ -930,7 +916,7 @@ TEST_F(Canvas2DLayerBridgeTest, DISABLED_PrepareMailboxWhileHibernating) #endif { - ScopedTestingPlatformSupport<FakePlatformSupport> platform; + ScopedTestingPlatformSupport<GpuMemoryBufferTestPlatform> platform; std::unique_ptr<Canvas2DLayerBridge> bridge = MakeBridge(IntSize(300, 300), Canvas2DLayerBridge::kEnableAcceleration, CanvasColorParams()); @@ -973,7 +959,7 @@ TEST_F(Canvas2DLayerBridgeTest, DISABLED_PrepareMailboxWhileBackgroundRendering) #endif { - ScopedTestingPlatformSupport<FakePlatformSupport> platform; + ScopedTestingPlatformSupport<GpuMemoryBufferTestPlatform> platform; std::unique_ptr<Canvas2DLayerBridge> bridge = MakeBridge(IntSize(300, 300), Canvas2DLayerBridge::kEnableAcceleration, CanvasColorParams()); @@ -1017,7 +1003,7 @@ TEST_F(Canvas2DLayerBridgeTest, GpuMemoryBufferRecycling) { InSequence s; ScopedCanvas2dImageChromiumForTest canvas_2d_image_chromium(true); - ScopedTestingPlatformSupport<FakePlatformSupport> platform; + ScopedTestingPlatformSupport<GpuMemoryBufferTestPlatform> platform; const_cast<gpu::Capabilities&>(SharedGpuContext::ContextProviderWrapper() ->ContextProvider() ->GetCapabilities()) @@ -1095,7 +1081,7 @@ TEST_F(Canvas2DLayerBridgeTest, NoGpuMemoryBufferRecyclingWhenPageHidden) { InSequence s; ScopedCanvas2dImageChromiumForTest canvas_2d_image_chromium(true); - ScopedTestingPlatformSupport<FakePlatformSupport> platform; + ScopedTestingPlatformSupport<GpuMemoryBufferTestPlatform> platform; const_cast<gpu::Capabilities&>(SharedGpuContext::ContextProviderWrapper() ->ContextProvider() ->GetCapabilities()) @@ -1173,7 +1159,7 @@ TEST_F(Canvas2DLayerBridgeTest, ReleaseGpuMemoryBufferAfterBridgeDestroyed) { InSequence s; ScopedCanvas2dImageChromiumForTest canvas_2d_image_chromium(true); - ScopedTestingPlatformSupport<FakePlatformSupport> platform; + ScopedTestingPlatformSupport<GpuMemoryBufferTestPlatform> platform; const_cast<gpu::Capabilities&>(SharedGpuContext::ContextProviderWrapper() ->ContextProvider() ->GetCapabilities())
diff --git a/third_party/blink/renderer/platform/graphics/canvas_resource.cc b/third_party/blink/renderer/platform/graphics/canvas_resource.cc index d9d91f3..69d5a9a 100644 --- a/third_party/blink/renderer/platform/graphics/canvas_resource.cc +++ b/third_party/blink/renderer/platform/graphics/canvas_resource.cc
@@ -426,6 +426,10 @@ return !gpu_mailbox_.IsZero(); } +GLuint CanvasResourceGpuMemoryBuffer::GetBackingTextureHandleForOverwrite() { + return texture_2d_id_for_copy_ ? texture_2d_id_for_copy_ : texture_id_; +} + const gpu::SyncToken CanvasResourceGpuMemoryBuffer::GetSyncToken() { if (mailbox_needs_new_sync_token_) { auto* gl = ContextGL(); @@ -467,8 +471,6 @@ } void CanvasResourceGpuMemoryBuffer::TakeSkImage(sk_sp<SkImage> image) { - TRACE_EVENT0("blink", "CanvasResourceGpuMemoryBuffer::CopyFromTexture"); - WillPaint(); if (!surface_) return;
diff --git a/third_party/blink/renderer/platform/graphics/canvas_resource.h b/third_party/blink/renderer/platform/graphics/canvas_resource.h index 32b1bfe..113d199 100644 --- a/third_party/blink/renderer/platform/graphics/canvas_resource.h +++ b/third_party/blink/renderer/platform/graphics/canvas_resource.h
@@ -86,6 +86,11 @@ // Only CanvasResourceProvider and derivatives should call this. virtual void TakeSkImage(sk_sp<SkImage> image) = 0; + virtual GLuint GetBackingTextureHandleForOverwrite() { + NOTREACHED(); + return 0; + } + protected: CanvasResource(base::WeakPtr<CanvasResourceProvider>, SkFilterQuality, @@ -208,6 +213,7 @@ GLenum format, GLenum type) override; scoped_refptr<StaticBitmapImage> Bitmap() override; + GLuint GetBackingTextureHandleForOverwrite() final; private: void TearDown() override;
diff --git a/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc b/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc index e1c788ae..1f949ee 100644 --- a/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc +++ b/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc
@@ -346,7 +346,97 @@ } }; +// * Renders to a GpuMemoryBuffer-backed texture used to create a SkSurface. +// * Layers are overlay candidates +class CanvasResourceProviderDirectGpuMemoryBuffer final + : public CanvasResourceProvider { + public: + CanvasResourceProviderDirectGpuMemoryBuffer( + const IntSize& size, + unsigned msaa_sample_count, + const CanvasColorParams color_params, + base::WeakPtr<WebGraphicsContext3DProviderWrapper> + context_provider_wrapper, + base::WeakPtr<CanvasResourceDispatcher> resource_dispatcher, + bool is_origin_top_left) + : CanvasResourceProvider(size, + color_params, + std::move(context_provider_wrapper), + std::move(resource_dispatcher)), + msaa_sample_count_(msaa_sample_count), + is_origin_top_left_(is_origin_top_left) { + constexpr bool is_accelerated = true; + resource_ = CanvasResourceGpuMemoryBuffer::Create( + Size(), ColorParams(), ContextProviderWrapper(), CreateWeakPtr(), + FilterQuality(), is_accelerated); + } + + ~CanvasResourceProviderDirectGpuMemoryBuffer() override = default; + bool IsValid() const final { return GetSkSurface() && !IsGpuContextLost(); } + bool IsAccelerated() const final { return true; } + bool SupportsDirectCompositing() const override { return true; } + bool SupportsSingleBuffering() const override { return true; } + + private: + GLuint GetBackingTextureHandleForOverwrite() override { + return resource_->GetBackingTextureHandleForOverwrite(); + } + + scoped_refptr<CanvasResource> CreateResource() final { + TRACE_EVENT0("blink", + "CanvasResourceProviderDirectGpuMemoryBuffer::CreateResource"); + DCHECK(resource_); + return resource_; + } + + scoped_refptr<CanvasResource> ProduceFrame() final { + TRACE_EVENT0("blink", + "CanvasResourceProviderDirectGpuMemoryBuffer::ProduceFrame"); + if (IsGpuContextLost()) + return nullptr; + FlushSkia(); + + auto* gl = ContextGL(); + DCHECK(gl); + gl->Flush(); + + return NewOrRecycledResource(); + } + + sk_sp<SkSurface> CreateSkSurface() const override { + if (IsGpuContextLost()) + return nullptr; + auto* gr = GetGrContext(); + DCHECK(gr); + + GrGLTextureInfo texture_info = {}; + texture_info.fID = resource_->GetBackingTextureHandleForOverwrite(); + texture_info.fTarget = GL_TEXTURE_2D; + // Skia requires a sized internal format. + texture_info.fFormat = ColorParams().GLSizedInternalFormat(); + + const GrBackendTexture backend_texture(Size().Width(), Size().Height(), + GrMipMapped::kNo, texture_info); + + const enum GrSurfaceOrigin surface_origin = + is_origin_top_left_ ? kTopLeft_GrSurfaceOrigin + : kBottomLeft_GrSurfaceOrigin; + + auto surface = SkSurface::MakeFromBackendTextureAsRenderTarget( + gr, backend_texture, surface_origin, msaa_sample_count_, + ColorParams().GetSkColorType(), + ColorParams().GetSkColorSpaceForSkSurfaces(), + ColorParams().GetSkSurfaceProps()); + return surface; + } + + const unsigned msaa_sample_count_; + const bool is_origin_top_left_; + scoped_refptr<CanvasResource> resource_; +}; + enum CanvasResourceType { + kDirectGpuMemoryBufferResourceType, kTextureGpuMemoryBufferResourceType, kRamGpuMemoryBufferResourceType, kSharedBitmapResourceType, @@ -378,6 +468,18 @@ kBitmapResourceType, }; +constexpr CanvasResourceType kAcceleratedDirectFallbackList[] = { + kDirectGpuMemoryBufferResourceType, + // The rest is equal to |kAcceleratedCompositedFallbackList|. + kTextureGpuMemoryBufferResourceType, + kTextureResourceType, + // Fallback to software composited + kRamGpuMemoryBufferResourceType, + kSharedBitmapResourceType, + // Fallback to no direct compositing support + kBitmapResourceType, +}; + std::unique_ptr<CanvasResourceProvider> CanvasResourceProvider::Create( const IntSize& size, ResourceUsage usage, @@ -407,15 +509,21 @@ resource_type_fallback_list = kAcceleratedCompositedFallbackList; list_length = arraysize(kAcceleratedCompositedFallbackList); break; + case kAcceleratedDirectResourceUsage: + resource_type_fallback_list = kAcceleratedDirectFallbackList; + list_length = arraysize(kAcceleratedDirectFallbackList); + break; } std::unique_ptr<CanvasResourceProvider> provider; for (size_t i = 0; i < list_length; ++i) { // Note: We are deliberately not using std::move() on - // context_provider_wrapper and resource_dispatcher to ensure that the + // |context_provider_wrapper| and |resource_dispatcher| to ensure that the // pointers remain valid for the next iteration of this loop if necessary. switch (resource_type_fallback_list[i]) { case kTextureGpuMemoryBufferResourceType: + FALLTHROUGH; + case kDirectGpuMemoryBufferResourceType: if (!SharedGpuContext::IsGpuCompositingEnabled()) continue; if (presentation_mode != kAllowImageChromiumPresentationMode) @@ -435,10 +543,20 @@ DCHECK_EQ(color_params.GLUnsizedInternalFormat(), gpu::InternalFormatForGpuMemoryBufferFormat( color_params.GetBufferFormat())); - provider = - std::make_unique<CanvasResourceProviderTextureGpuMemoryBuffer>( - size, msaa_sample_count, color_params, context_provider_wrapper, - resource_dispatcher, is_origin_top_left); + if (resource_type_fallback_list[i] == + kDirectGpuMemoryBufferResourceType) { + provider = + std::make_unique<CanvasResourceProviderDirectGpuMemoryBuffer>( + size, msaa_sample_count, color_params, + context_provider_wrapper, resource_dispatcher, + is_origin_top_left); + } else { + provider = + std::make_unique<CanvasResourceProviderTextureGpuMemoryBuffer>( + size, msaa_sample_count, color_params, + context_provider_wrapper, resource_dispatcher, + is_origin_top_left); + } break; case kRamGpuMemoryBufferResourceType: if (!SharedGpuContext::IsGpuCompositingEnabled()) @@ -476,11 +594,11 @@ size, color_params, context_provider_wrapper, resource_dispatcher); break; } - if (provider && provider->IsValid()) { - base::UmaHistogramBoolean("Blink.Canvas.ResourceProviderIsAccelerated", - provider->IsAccelerated()); - return provider; - } + if (!provider->IsValid()) + continue; + base::UmaHistogramBoolean("Blink.Canvas.ResourceProviderIsAccelerated", + provider->IsAccelerated()); + return provider; } return nullptr;
diff --git a/third_party/blink/renderer/platform/graphics/canvas_resource_provider.h b/third_party/blink/renderer/platform/graphics/canvas_resource_provider.h index d3894cb5..3a06967df 100644 --- a/third_party/blink/renderer/platform/graphics/canvas_resource_provider.h +++ b/third_party/blink/renderer/platform/graphics/canvas_resource_provider.h
@@ -55,6 +55,7 @@ kSoftwareCompositedResourceUsage, kAcceleratedResourceUsage, kAcceleratedCompositedResourceUsage, + kAcceleratedDirectResourceUsage, }; enum PresentationMode {
diff --git a/third_party/blink/renderer/platform/graphics/canvas_resource_provider_test.cc b/third_party/blink/renderer/platform/graphics/canvas_resource_provider_test.cc index 085187a..90bf30b 100644 --- a/third_party/blink/renderer/platform/graphics/canvas_resource_provider_test.cc +++ b/third_party/blink/renderer/platform/graphics/canvas_resource_provider_test.cc
@@ -4,6 +4,7 @@ #include "third_party/blink/renderer/platform/graphics/canvas_resource_provider.h" +#include "components/viz/test/test_gpu_memory_buffer_manager.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/renderer/platform/graphics/canvas_color_params.h" @@ -11,13 +12,31 @@ #include "third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.h" #include "third_party/blink/renderer/platform/graphics/test/fake_gles2_interface.h" #include "third_party/blink/renderer/platform/graphics/test/fake_web_graphics_context_3d_provider.h" +#include "third_party/blink/renderer/platform/graphics/test/gpu_memory_buffer_test_platform.h" #include "third_party/blink/renderer/platform/wtf/functional.h" +using testing::_; using testing::InSequence; +using testing::Return; using testing::Test; namespace blink { +namespace { + +class FakeGLES2InterfaceWithImageSupport : public FakeGLES2Interface { + public: + GLuint CreateImageCHROMIUM(ClientBuffer, GLsizei, GLsizei, GLenum) final { + return image_id_++; + } + void DestroyImageCHROMIUM(GLuint image_id) final { + EXPECT_LE(image_id, image_id_); + } + + private: + GLuint image_id_ = 3; +}; + class MockCanvasResourceDispatcherClient : public CanvasResourceDispatcherClient { public: @@ -26,6 +45,8 @@ MOCK_METHOD0(BeginFrame, void()); }; +} // anonymous namespace + class CanvasResourceProviderTest : public Test { public: void SetUp() override { @@ -43,9 +64,25 @@ void TearDown() override { SharedGpuContext::ResetForTesting(); } + // Adds |buffer_format| to the context capabilities if it's not supported. + void EnsureBufferFormatIsSupported(gfx::BufferFormat buffer_format) { + auto* context_provider = context_provider_wrapper_->ContextProvider(); + if (context_provider->GetCapabilities().gpu_memory_buffer_formats.Has( + buffer_format)) { + return; + } + + auto capabilities = context_provider->GetCapabilities(); + capabilities.gpu_memory_buffer_formats.Add(buffer_format); + + static_cast<FakeWebGraphicsContext3DProvider*>(context_provider) + ->SetCapabilities(capabilities); + } + protected: - FakeGLES2Interface gl_; + FakeGLES2InterfaceWithImageSupport gl_; base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_provider_wrapper_; + ScopedTestingPlatformSupport<GpuMemoryBufferTestPlatform> platform_; }; TEST_F(CanvasResourceProviderTest, @@ -53,18 +90,7 @@ const IntSize kSize(10, 10); const CanvasColorParams kColorParams(kSRGBCanvasColorSpace, kRGBA8CanvasPixelFormat, kNonOpaque); - - // Add the deduced gfx::BufferFormat if it's not supported. - auto* context_provider = context_provider_wrapper_->ContextProvider(); - const gfx::BufferFormat buffer_format = kColorParams.GetBufferFormat(); - if (!context_provider->GetCapabilities().gpu_memory_buffer_formats.Has( - buffer_format)) { - auto capabilities = context_provider->GetCapabilities(); - capabilities.gpu_memory_buffer_formats.Add(buffer_format); - - static_cast<FakeWebGraphicsContext3DProvider*>(context_provider) - ->SetCapabilities(capabilities); - } + EnsureBufferFormatIsSupported(kColorParams.GetBufferFormat()); auto provider = CanvasResourceProvider::Create( kSize, CanvasResourceProvider::kAcceleratedCompositedResourceUsage, @@ -126,8 +152,8 @@ EXPECT_EQ(provider->Size(), kSize); EXPECT_TRUE(provider->IsValid()); EXPECT_FALSE(provider->IsAccelerated()); - EXPECT_FALSE(provider->SupportsDirectCompositing()); - EXPECT_FALSE(provider->SupportsSingleBuffering()); + EXPECT_TRUE(provider->SupportsDirectCompositing()); + EXPECT_TRUE(provider->SupportsSingleBuffering()); EXPECT_EQ(provider->ColorParams().ColorSpace(), kColorParams.ColorSpace()); EXPECT_EQ(provider->ColorParams().PixelFormat(), kColorParams.PixelFormat()); EXPECT_EQ(provider->ColorParams().GetOpacityMode(), @@ -191,4 +217,32 @@ EXPECT_TRUE(provider->IsSingleBuffered()); } +TEST_F(CanvasResourceProviderTest, + CanvasResourceProviderDirectGpuMemoryBuffer) { + const IntSize kSize(10, 10); + const CanvasColorParams kColorParams(kSRGBCanvasColorSpace, + kRGBA8CanvasPixelFormat, kNonOpaque); + EnsureBufferFormatIsSupported(kColorParams.GetBufferFormat()); + + auto provider = CanvasResourceProvider::Create( + kSize, CanvasResourceProvider::kAcceleratedDirectResourceUsage, + context_provider_wrapper_, 0 /* msaa_sample_count */, kColorParams, + CanvasResourceProvider::kAllowImageChromiumPresentationMode, + nullptr /* resource_dispatcher */, true /* is_origin_top_left */); + + EXPECT_EQ(provider->Size(), kSize); + EXPECT_TRUE(provider->IsValid()); + EXPECT_TRUE(provider->IsAccelerated()); + EXPECT_TRUE(provider->SupportsDirectCompositing()); + EXPECT_TRUE(provider->SupportsSingleBuffering()); + EXPECT_EQ(provider->ColorParams().ColorSpace(), kColorParams.ColorSpace()); + EXPECT_EQ(provider->ColorParams().PixelFormat(), kColorParams.PixelFormat()); + EXPECT_EQ(provider->ColorParams().GetOpacityMode(), + kColorParams.GetOpacityMode()); + + EXPECT_FALSE(provider->IsSingleBuffered()); + provider->TryEnableSingleBuffering(); + EXPECT_TRUE(provider->IsSingleBuffered()); +} + } // namespace blink
diff --git a/third_party/blink/renderer/platform/graphics/canvas_resource_test.cc b/third_party/blink/renderer/platform/graphics/canvas_resource_test.cc index f27b5bf..3dc0a13 100644 --- a/third_party/blink/renderer/platform/graphics/canvas_resource_test.cc +++ b/third_party/blink/renderer/platform/graphics/canvas_resource_test.cc
@@ -16,7 +16,7 @@ #include "third_party/blink/renderer/platform/graphics/static_bitmap_image.h" #include "third_party/blink/renderer/platform/graphics/test/fake_gles2_interface.h" #include "third_party/blink/renderer/platform/graphics/test/fake_web_graphics_context_3d_provider.h" -#include "third_party/blink/renderer/platform/testing/testing_platform_support.h" +#include "third_party/blink/renderer/platform/graphics/test/gpu_memory_buffer_test_platform.h" #include "third_party/blink/renderer/platform/wtf/functional.h" #include "third_party/skia/include/core/SkSurface.h" @@ -39,20 +39,6 @@ MOCK_METHOD2(BindTexture, void(GLenum, GLuint)); }; -class FakeCanvasResourcePlatformSupport : public TestingPlatformSupport { - public: - void RunUntilStop() const { base::RunLoop().Run(); } - - void StopRunning() const { base::RunLoop().Quit(); } - - private: - gpu::GpuMemoryBufferManager* GetGpuMemoryBufferManager() override { - return &test_gpu_memory_buffer_manager_; - } - - viz::TestGpuMemoryBufferManager test_gpu_memory_buffer_manager_; -}; - class CanvasResourceTest : public Test { public: void SetUp() override { @@ -134,7 +120,7 @@ TEST_F(CanvasResourceTest, GpuMemoryBufferSyncTokenRefresh) { testing::InSequence s; - ScopedTestingPlatformSupport<FakeCanvasResourcePlatformSupport> platform; + ScopedTestingPlatformSupport<GpuMemoryBufferTestPlatform> platform; constexpr GLuint image_id = 1; const GLuint texture_target = gpu::GetPlatformSpecificTextureTarget(); @@ -204,7 +190,7 @@ } TEST_F(CanvasResourceTest, MakeAcceleratedFromAcceleratedResourceIsNoOp) { - ScopedTestingPlatformSupport<FakeCanvasResourcePlatformSupport> platform; + ScopedTestingPlatformSupport<GpuMemoryBufferTestPlatform> platform; SkImageInfo image_info = SkImageInfo::MakeN32(10, 10, kPremul_SkAlphaType, nullptr); @@ -232,7 +218,7 @@ } TEST_F(CanvasResourceTest, MakeAcceleratedFromRasterResource) { - ScopedTestingPlatformSupport<FakeCanvasResourcePlatformSupport> platform; + ScopedTestingPlatformSupport<GpuMemoryBufferTestPlatform> platform; SkImageInfo image_info = SkImageInfo::MakeN32(10, 10, kPremul_SkAlphaType, nullptr); @@ -258,7 +244,7 @@ } TEST_F(CanvasResourceTest, MakeUnacceleratedFromUnacceleratedResourceIsNoOp) { - ScopedTestingPlatformSupport<FakeCanvasResourcePlatformSupport> platform; + ScopedTestingPlatformSupport<GpuMemoryBufferTestPlatform> platform; SkImageInfo image_info = SkImageInfo::MakeN32(10, 10, kPremul_SkAlphaType, nullptr); @@ -277,7 +263,7 @@ } TEST_F(CanvasResourceTest, MakeUnacceleratedFromAcceleratedResource) { - ScopedTestingPlatformSupport<FakeCanvasResourcePlatformSupport> platform; + ScopedTestingPlatformSupport<GpuMemoryBufferTestPlatform> platform; SkImageInfo image_info = SkImageInfo::MakeN32(10, 10, kPremul_SkAlphaType, nullptr); @@ -315,7 +301,7 @@ TEST_F(CanvasResourceTest, RamGpuMemoryBuffer_ResourcePreparation) { testing::InSequence s; - ScopedTestingPlatformSupport<FakeCanvasResourcePlatformSupport> platform; + ScopedTestingPlatformSupport<GpuMemoryBufferTestPlatform> platform; EXPECT_TRUE(!!context_provider_wrapper_); constexpr GLuint image_id = 1; @@ -355,7 +341,7 @@ TEST_F(CanvasResourceTest, GpuMemoryBuffer_accelerated_8bit) { testing::InSequence s; - ScopedTestingPlatformSupport<FakeCanvasResourcePlatformSupport> platform; + ScopedTestingPlatformSupport<GpuMemoryBufferTestPlatform> platform; EXPECT_TRUE(!!context_provider_wrapper_); constexpr GLuint image_id = 1; @@ -381,7 +367,7 @@ TEST_F(CanvasResourceTest, GpuMemoryBuffer_accelerated_float16) { testing::InSequence s; - ScopedTestingPlatformSupport<FakeCanvasResourcePlatformSupport> platform; + ScopedTestingPlatformSupport<GpuMemoryBufferTestPlatform> platform; EXPECT_TRUE(!!context_provider_wrapper_); constexpr GLuint image_id = 1; @@ -409,7 +395,7 @@ TEST_F(CanvasResourceTest, PrepareTransferableResource_SharedBitmap) { testing::InSequence s; - ScopedTestingPlatformSupport<FakeCanvasResourcePlatformSupport> platform; + ScopedTestingPlatformSupport<GpuMemoryBufferTestPlatform> platform; scoped_refptr<CanvasResource> canvas_resource = CanvasResourceSharedBitmap::Create(IntSize(10, 10), CanvasColorParams(), nullptr, // CanvasResourceProvider
diff --git a/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer_test.cc b/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer_test.cc index c5f07c6..2fdde1208 100644 --- a/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer_test.cc +++ b/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer_test.cc
@@ -42,8 +42,8 @@ #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/renderer/platform/graphics/canvas_color_params.h" #include "third_party/blink/renderer/platform/graphics/gpu/drawing_buffer_test_helpers.h" +#include "third_party/blink/renderer/platform/graphics/test/gpu_memory_buffer_test_platform.h" #include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h" -#include "third_party/blink/renderer/platform/testing/testing_platform_support.h" #include "v8/include/v8.h" using testing::Test; @@ -51,19 +51,6 @@ namespace blink { -namespace { - -class FakePlatformSupport : public TestingPlatformSupport { - gpu::GpuMemoryBufferManager* GetGpuMemoryBufferManager() override { - return &test_gpu_memory_buffer_manager_; - } - - private: - viz::TestGpuMemoryBufferManager test_gpu_memory_buffer_manager_; -}; - -} // anonymous namespace - class DrawingBufferTest : public Test { protected: void SetUp() override { Init(kDisableMultisampling); } @@ -394,7 +381,8 @@ protected: void SetUp() override { - platform_.reset(new ScopedTestingPlatformSupport<FakePlatformSupport>); + platform_.reset( + new ScopedTestingPlatformSupport<GpuMemoryBufferTestPlatform>); IntSize initial_size(kInitialWidth, kInitialHeight); auto gl = std::make_unique<GLES2InterfaceForTests>(); @@ -418,7 +406,8 @@ } GLuint image_id0_; - std::unique_ptr<ScopedTestingPlatformSupport<FakePlatformSupport>> platform_; + std::unique_ptr<ScopedTestingPlatformSupport<GpuMemoryBufferTestPlatform>> + platform_; }; TEST_F(DrawingBufferImageChromiumTest, VerifyResizingReallocatesImages) {
diff --git a/third_party/blink/renderer/platform/graphics/high_contrast_image_classifier_test.cc b/third_party/blink/renderer/platform/graphics/high_contrast_image_classifier_test.cc index e225f5e..951146c 100644 --- a/third_party/blink/renderer/platform/graphics/high_contrast_image_classifier_test.cc +++ b/third_party/blink/renderer/platform/graphics/high_contrast_image_classifier_test.cc
@@ -43,7 +43,7 @@ protected: scoped_refptr<BitmapImage> LoadImage(const std::string& file_name) { - String file_path = test::BlinkLayoutTestsDir(); + String file_path = test::BlinkWebTestsDir(); file_path.append(file_name.c_str()); scoped_refptr<SharedBuffer> image_data = test::ReadFromFile(file_path); EXPECT_TRUE(image_data.get() && image_data.get()->size());
diff --git a/third_party/blink/renderer/platform/graphics/test/DEPS b/third_party/blink/renderer/platform/graphics/test/DEPS index 52a8536..3a676d7 100644 --- a/third_party/blink/renderer/platform/graphics/test/DEPS +++ b/third_party/blink/renderer/platform/graphics/test/DEPS
@@ -1,4 +1,5 @@ include_rules = [ + "+components/viz/test/test_gpu_memory_buffer_manager.h", "+gpu/command_buffer/client/gles2_interface_stub.h", "+gpu/config/gpu_feature_info.h" ]
diff --git a/third_party/blink/renderer/platform/graphics/test/gpu_memory_buffer_test_platform.h b/third_party/blink/renderer/platform/graphics/test/gpu_memory_buffer_test_platform.h new file mode 100644 index 0000000..226eb3e --- /dev/null +++ b/third_party/blink/renderer/platform/graphics/test/gpu_memory_buffer_test_platform.h
@@ -0,0 +1,20 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_TEST_GPU_MEMORY_BUFFER_TEST_PLATFORM_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_TEST_GPU_MEMORY_BUFFER_TEST_PLATFORM_H_ + +#include "components/viz/test/test_gpu_memory_buffer_manager.h" +#include "third_party/blink/renderer/platform/testing/testing_platform_support.h" + +class GpuMemoryBufferTestPlatform : public blink::TestingPlatformSupport { + private: + gpu::GpuMemoryBufferManager* GetGpuMemoryBufferManager() override { + return &test_gpu_memory_buffer_manager_; + } + + viz::TestGpuMemoryBufferManager test_gpu_memory_buffer_manager_; +}; + +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_TEST_GPU_MEMORY_BUFFER_TEST_PLATFORM_H_
diff --git a/third_party/blink/renderer/platform/heap/persistent.h b/third_party/blink/renderer/platform/heap/persistent.h index e8bf8c4a..52dc689 100644 --- a/third_party/blink/renderer/platform/heap/persistent.h +++ b/third_party/blink/renderer/platform/heap/persistent.h
@@ -197,13 +197,6 @@ region.FreePersistentNode(persistent_node_); } - protected: - NO_SANITIZE_ADDRESS - T* AtomicGet() { - return reinterpret_cast<T*>(AcquireLoad(reinterpret_cast<void* volatile*>( - const_cast<typename std::remove_const<T>::type**>(&raw_)))); - } - private: NO_SANITIZE_ADDRESS void Assign(T* ptr) { @@ -511,8 +504,6 @@ CrossThreadPersistent(const Member<U>& other) : Parent(other) {} CrossThreadPersistent(WTF::HashTableDeletedValueType x) : Parent(x) {} - T* AtomicGet() { return Parent::AtomicGet(); } - // Instead of using release(), assign then clear() instead. // Using release() with per thread heap enabled can cause the object to be // destroyed before assigning it to a new handle.
diff --git a/third_party/blink/renderer/platform/heap/persistent_node.cc b/third_party/blink/renderer/platform/heap/persistent_node.cc index 2ebb072..ce00cc36e 100644 --- a/third_party/blink/renderer/platform/heap/persistent_node.cc +++ b/third_party/blink/renderer/platform/heap/persistent_node.cc
@@ -182,7 +182,7 @@ reinterpret_cast<CrossThreadPersistent<DummyGCBase>*>( slots->slot_[i].Self()); DCHECK(persistent); - void* raw_object = persistent->AtomicGet(); + void* raw_object = persistent->Get(); if (!raw_object) continue; BasePage* page = PageFromObject(raw_object);
diff --git a/third_party/blink/renderer/platform/image-decoders/gif/gif_image_decoder_test.cc b/third_party/blink/renderer/platform/image-decoders/gif/gif_image_decoder_test.cc index bc794ff3..5e80c87 100644 --- a/third_party/blink/renderer/platform/image-decoders/gif/gif_image_decoder_test.cc +++ b/third_party/blink/renderer/platform/image-decoders/gif/gif_image_decoder_test.cc
@@ -42,7 +42,7 @@ namespace { -const char kLayoutTestResourcesDir[] = "web_tests/images/resources"; +const char kWebTestsResourcesDir[] = "web_tests/images/resources"; std::unique_ptr<ImageDecoder> CreateDecoder() { return std::make_unique<GIFImageDecoder>( @@ -66,7 +66,7 @@ std::unique_ptr<ImageDecoder> decoder = CreateDecoder(); scoped_refptr<SharedBuffer> data = - ReadFile(kLayoutTestResourcesDir, "animated.gif"); + ReadFile(kWebTestsResourcesDir, "animated.gif"); ASSERT_TRUE(data.get()); decoder->SetData(data.get(), true); @@ -90,7 +90,7 @@ TEST(GIFImageDecoderTest, crbug779261) { std::unique_ptr<ImageDecoder> decoder = CreateDecoder(); scoped_refptr<SharedBuffer> data = - ReadFile(kLayoutTestResourcesDir, "crbug779261.gif"); + ReadFile(kWebTestsResourcesDir, "crbug779261.gif"); ASSERT_TRUE(data.get()); decoder->SetData(data.get(), true); @@ -112,7 +112,7 @@ std::unique_ptr<ImageDecoder> decoder = CreateDecoder(); scoped_refptr<SharedBuffer> data = - ReadFile(kLayoutTestResourcesDir, "animated.gif"); + ReadFile(kWebTestsResourcesDir, "animated.gif"); ASSERT_TRUE(data.get()); decoder->SetData(data.get(), true); @@ -135,7 +135,7 @@ std::unique_ptr<ImageDecoder> decoder = CreateDecoder(); const Vector<char> data = - ReadFile(kLayoutTestResourcesDir, "animated.gif")->CopyAs<Vector<char>>(); + ReadFile(kWebTestsResourcesDir, "animated.gif")->CopyAs<Vector<char>>(); size_t frame_count = 0; @@ -157,7 +157,7 @@ } TEST(GIFImageDecoderTest, parseAndDecodeByteByByte) { - TestByteByByteDecode(&CreateDecoder, kLayoutTestResourcesDir, + TestByteByByteDecode(&CreateDecoder, kWebTestsResourcesDir, "animated-gif-with-offsets.gif", 5u, kAnimationLoopInfinite); } @@ -184,7 +184,7 @@ std::unique_ptr<ImageDecoder> decoder = CreateDecoder(); const Vector<char> data = - ReadFile(kLayoutTestResourcesDir, "animated.gif")->CopyAs<Vector<char>>(); + ReadFile(kWebTestsResourcesDir, "animated.gif")->CopyAs<Vector<char>>(); ASSERT_GE(data.size(), 10u); scoped_refptr<SharedBuffer> temp_data = @@ -204,7 +204,7 @@ std::unique_ptr<ImageDecoder> decoder = CreateDecoder(); scoped_refptr<SharedBuffer> data = - ReadFile(kLayoutTestResourcesDir, "animated.gif"); + ReadFile(kWebTestsResourcesDir, "animated.gif"); ASSERT_TRUE(data.get()); decoder->SetData(data.get(), true); @@ -219,7 +219,7 @@ std::unique_ptr<ImageDecoder> decoder = CreateDecoder(); scoped_refptr<SharedBuffer> data_buffer = - ReadFile(kLayoutTestResourcesDir, "animated.gif"); + ReadFile(kWebTestsResourcesDir, "animated.gif"); ASSERT_TRUE(data_buffer.get()); const Vector<char> data = data_buffer->CopyAs<Vector<char>>(); @@ -265,16 +265,16 @@ TEST(GIFImageDecoderTest, updateRequiredPreviousFrameAfterFirstDecode) { TestUpdateRequiredPreviousFrameAfterFirstDecode( - &CreateDecoder, kLayoutTestResourcesDir, "animated-10color.gif"); + &CreateDecoder, kWebTestsResourcesDir, "animated-10color.gif"); } TEST(GIFImageDecoderTest, randomFrameDecode) { // Single frame image. TestRandomFrameDecode(&CreateDecoder, kDecodersTestingDir, "radient.gif"); // Multiple frame images. - TestRandomFrameDecode(&CreateDecoder, kLayoutTestResourcesDir, + TestRandomFrameDecode(&CreateDecoder, kWebTestsResourcesDir, "animated-gif-with-offsets.gif"); - TestRandomFrameDecode(&CreateDecoder, kLayoutTestResourcesDir, + TestRandomFrameDecode(&CreateDecoder, kWebTestsResourcesDir, "animated-10color.gif"); } @@ -284,14 +284,14 @@ &CreateDecoder, kDecodersTestingDir, "radient.gif"); // Multiple frame images. TestRandomDecodeAfterClearFrameBufferCache( - &CreateDecoder, kLayoutTestResourcesDir, "animated-gif-with-offsets.gif"); + &CreateDecoder, kWebTestsResourcesDir, "animated-gif-with-offsets.gif"); TestRandomDecodeAfterClearFrameBufferCache( - &CreateDecoder, kLayoutTestResourcesDir, "animated-10color.gif"); + &CreateDecoder, kWebTestsResourcesDir, "animated-10color.gif"); } TEST(GIFImageDecoderTest, resumePartialDecodeAfterClearFrameBufferCache) { TestResumePartialDecodeAfterClearFrameBufferCache( - &CreateDecoder, kLayoutTestResourcesDir, "animated-10color.gif"); + &CreateDecoder, kWebTestsResourcesDir, "animated-10color.gif"); } // The first LZW codes in the image are invalid values that try to create a loop @@ -372,13 +372,13 @@ } TEST(GIFImageDecoderTest, verifyRepetitionCount) { - TestRepetitionCount(kLayoutTestResourcesDir, "full2loop.gif", 2); + TestRepetitionCount(kWebTestsResourcesDir, "full2loop.gif", 2); TestRepetitionCount(kDecodersTestingDir, "radient.gif", kAnimationNone); } TEST(GIFImageDecoderTest, repetitionCountChangesWhenSeen) { scoped_refptr<SharedBuffer> full_data_buffer = - ReadFile(kLayoutTestResourcesDir, "animated-10color.gif"); + ReadFile(kWebTestsResourcesDir, "animated-10color.gif"); ASSERT_TRUE(full_data_buffer.get()); const Vector<char> full_data = full_data_buffer->CopyAs<Vector<char>>(); @@ -462,7 +462,7 @@ // Ensure that calling SetMemoryAllocator does not short-circuit // InitializeNewFrame. TEST(GIFImageDecoderTest, externalAllocator) { - auto data = ReadFile(kLayoutTestResourcesDir, "boston.gif"); + auto data = ReadFile(kWebTestsResourcesDir, "boston.gif"); ASSERT_TRUE(data.get()); auto decoder = CreateDecoder(); @@ -480,7 +480,7 @@ } TEST(GIFImageDecoderTest, recursiveDecodeFailure) { - auto data = ReadFile(kLayoutTestResourcesDir, "count-down-color-test.gif"); + auto data = ReadFile(kWebTestsResourcesDir, "count-down-color-test.gif"); ASSERT_TRUE(data.get()); {
diff --git a/third_party/blink/renderer/platform/image-decoders/image_decoder_test_helpers.cc b/third_party/blink/renderer/platform/image-decoders/image_decoder_test_helpers.cc index d1d6578..e55f300 100644 --- a/third_party/blink/renderer/platform/image-decoders/image_decoder_test_helpers.cc +++ b/third_party/blink/renderer/platform/image-decoders/image_decoder_test_helpers.cc
@@ -15,7 +15,7 @@ namespace blink { scoped_refptr<SharedBuffer> ReadFile(const char* file_name) { - String file_path = test::BlinkLayoutTestsDir(); + String file_path = test::BlinkWebTestsDir(); file_path.append(file_name); return test::ReadFromFile(file_path); } @@ -23,7 +23,7 @@ scoped_refptr<SharedBuffer> ReadFile(const char* dir, const char* file_name) { StringBuilder file_path; if (strncmp(dir, "web_tests/", 10) == 0) { - file_path.Append(test::BlinkLayoutTestsDir()); + file_path.Append(test::BlinkWebTestsDir()); file_path.Append('/'); file_path.Append(dir + 10); } else {
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index bb2a284c..f774159 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -1212,6 +1212,10 @@ status: "experimental", }, { + name: "StorageQuotaDetails", + status: "experimental", + }, + { name: "TextUnderlinePositionLeftRight", status: "stable", }, @@ -1351,10 +1355,6 @@ status: "test", }, { - name: "WebLocksAPI", - status: "stable", - }, - { name: "WebNFC", status: "experimental", },
diff --git a/third_party/blink/renderer/platform/testing/fuzzed_data_provider.cc b/third_party/blink/renderer/platform/testing/fuzzed_data_provider.cc index 4420d63..dae0154 100644 --- a/third_party/blink/renderer/platform/testing/fuzzed_data_provider.cc +++ b/third_party/blink/renderer/platform/testing/fuzzed_data_provider.cc
@@ -11,8 +11,7 @@ CString FuzzedDataProvider::ConsumeBytesInRange(uint32_t min_bytes, uint32_t max_bytes) { - size_t num_bytes = - static_cast<size_t>(provider_.ConsumeUint32InRange(min_bytes, max_bytes)); + size_t num_bytes = provider_.ConsumeIntegralInRange(min_bytes, max_bytes); std::vector<char> bytes = provider_.ConsumeBytes<char>(num_bytes); return CString(bytes.data(), bytes.size()); } @@ -22,12 +21,4 @@ return CString(bytes.data(), bytes.size()); } -bool FuzzedDataProvider::ConsumeBool() { - return provider_.ConsumeBool(); -} - -int FuzzedDataProvider::ConsumeInt32InRange(int min, int max) { - return provider_.ConsumeInt32InRange(min, max); -} - } // namespace blink
diff --git a/third_party/blink/renderer/platform/testing/fuzzed_data_provider.h b/third_party/blink/renderer/platform/testing/fuzzed_data_provider.h index ee8897f..f3dac90 100644 --- a/third_party/blink/renderer/platform/testing/fuzzed_data_provider.h +++ b/third_party/blink/renderer/platform/testing/fuzzed_data_provider.h
@@ -28,19 +28,22 @@ CString ConsumeRemainingBytes(); // Returns a bool, or false when no data remains. - bool ConsumeBool(); + bool ConsumeBool() { return provider_.ConsumeBool(); } // Returns a number in the range [min, max] by consuming bytes from the input // data. The value might not be uniformly distributed in the given range. If // there's no input data left, always returns |min|. |min| must be less than // or equal to |max|. - int ConsumeInt32InRange(int min, int max); + template <typename T> + T ConsumeIntegralInRange(T min, T max) { + return provider_.ConsumeIntegralInRange<T>(min, max); + } // Returns a value from |array|, consuming as many bytes as needed to do so. // |array| must be a fixed-size array. - template <typename Type, size_t size> - Type PickValueInArray(Type (&array)[size]) { - return array[provider_.ConsumeUint32InRange(0, size - 1)]; + template <typename T, size_t size> + T PickValueInArray(T (&array)[size]) { + return array[provider_.ConsumeIntegralInRange<size_t>(0, size - 1)]; } // Reports the remaining bytes available for fuzzed input.
diff --git a/third_party/blink/renderer/platform/testing/unit_test_helpers.cc b/third_party/blink/renderer/platform/testing/unit_test_helpers.cc index 3fbeb71..5d18e76 100644 --- a/third_party/blink/renderer/platform/testing/unit_test_helpers.cc +++ b/third_party/blink/renderer/platform/testing/unit_test_helpers.cc
@@ -51,8 +51,7 @@ path.Append(FILE_PATH_LITERAL("third_party/blink"))); } -// TODO(tkent): Rename this function. crbug.com/843412. -base::FilePath LayoutTestsFilePath() { +base::FilePath WebTestsFilePath() { base::FilePath path; base::PathService::Get(base::DIR_SOURCE_ROOT, &path); return base::MakeAbsoluteFilePath( @@ -94,8 +93,8 @@ return FilePathToWebString(BlinkRootFilePath()); } -String BlinkLayoutTestsDir() { - return FilePathToWebString(LayoutTestsFilePath()); +String BlinkWebTestsDir() { + return FilePathToWebString(WebTestsFilePath()); } String ExecutableDir() {
diff --git a/third_party/blink/renderer/platform/testing/unit_test_helpers.h b/third_party/blink/renderer/platform/testing/unit_test_helpers.h index a04c53d..832b5d8 100644 --- a/third_party/blink/renderer/platform/testing/unit_test_helpers.h +++ b/third_party/blink/renderer/platform/testing/unit_test_helpers.h
@@ -52,9 +52,9 @@ // /src/third_party/blink. String BlinkRootDir(); -// Returns Blink LayoutTests directory as an absolute path, e.g. -// /src/third_party/WebKit/LayoutTests. -String BlinkLayoutTestsDir(); +// Returns Blink web_tests directory as an absolute path, e.g. +// /src/third_party/blink/web_tests. +String BlinkWebTestsDir(); // Returns directory containing the current executable as absolute path. String ExecutableDir();
diff --git a/third_party/blink/renderer/platform/text/DEPS b/third_party/blink/renderer/platform/text/DEPS index 9ab8273..05eb49a63 100644 --- a/third_party/blink/renderer/platform/text/DEPS +++ b/third_party/blink/renderer/platform/text/DEPS
@@ -10,10 +10,10 @@ "+third_party/blink/renderer/platform/heap", "+third_party/blink/renderer/platform/language.h", "+third_party/blink/renderer/platform/mac/version_util_mac.h", - "+third_party/blink/renderer/platform/layout_test_support.h", "+third_party/blink/renderer/platform/platform_export.h", "+third_party/blink/renderer/platform/runtime_enabled_features.h", "+third_party/blink/renderer/platform/testing", + "+third_party/blink/renderer/platform/web_test_support.h", "+third_party/blink/renderer/platform/weborigin", "+third_party/blink/renderer/platform/wtf", ]
diff --git a/third_party/blink/renderer/platform/text/locale_mac.mm b/third_party/blink/renderer/platform/text/locale_mac.mm index 6271af2..490dbff0 100644 --- a/third_party/blink/renderer/platform/text/locale_mac.mm +++ b/third_party/blink/renderer/platform/text/locale_mac.mm
@@ -35,7 +35,7 @@ #include <memory> #include "base/memory/ptr_util.h" #include "third_party/blink/renderer/platform/language.h" -#include "third_party/blink/renderer/platform/layout_test_support.h" +#include "third_party/blink/renderer/platform/web_test_support.h" #include "third_party/blink/renderer/platform/wtf/date_math.h" #include "third_party/blink/renderer/platform/wtf/retain_ptr.h" #include "third_party/blink/renderer/platform/wtf/text/string_builder.h" @@ -52,7 +52,7 @@ } static RetainPtr<NSLocale> DetermineLocale(const String& locale) { - if (!LayoutTestSupport::IsRunningLayoutTest()) { + if (!WebTestSupport::IsRunningWebTest()) { RetainPtr<NSLocale> current_locale = [NSLocale currentLocale]; String current_locale_language = LanguageFromLocale(String([current_locale.Get() localeIdentifier]));
diff --git a/third_party/blink/renderer/platform/text/locale_win.cc b/third_party/blink/renderer/platform/text/locale_win.cc index 2030fbf..8b5049f 100644 --- a/third_party/blink/renderer/platform/text/locale_win.cc +++ b/third_party/blink/renderer/platform/text/locale_win.cc
@@ -36,8 +36,8 @@ #include "base/memory/ptr_util.h" #include "third_party/blink/renderer/platform/date_components.h" #include "third_party/blink/renderer/platform/language.h" -#include "third_party/blink/renderer/platform/layout_test_support.h" #include "third_party/blink/renderer/platform/text/date_time_format.h" +#include "third_party/blink/renderer/platform/web_test_support.h" #include "third_party/blink/renderer/platform/wtf/date_math.h" #include "third_party/blink/renderer/platform/wtf/hash_map.h" #include "third_party/blink/renderer/platform/wtf/text/string_buffer.h" @@ -93,7 +93,7 @@ std::unique_ptr<Locale> Locale::Create(const String& locale) { // Whether the default settings for the locale should be used, ignoring user // overrides. - bool defaults_for_locale = LayoutTestSupport::IsRunningLayoutTest(); + bool defaults_for_locale = WebTestSupport::IsRunningWebTest(); return LocaleWin::Create(LCIDFromLocale(locale, defaults_for_locale), defaults_for_locale); }
diff --git a/third_party/blink/renderer/platform/layout_test_support.cc b/third_party/blink/renderer/platform/web_test_support.cc similarity index 74% rename from third_party/blink/renderer/platform/layout_test_support.cc rename to third_party/blink/renderer/platform/web_test_support.cc index a5c3688..66a26d6c 100644 --- a/third_party/blink/renderer/platform/layout_test_support.cc +++ b/third_party/blink/renderer/platform/web_test_support.cc
@@ -28,28 +28,28 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "third_party/blink/renderer/platform/layout_test_support.h" +#include "third_party/blink/renderer/platform/web_test_support.h" #include "third_party/blink/public/web/blink.h" #include "third_party/blink/renderer/platform/wtf/assertions.h" namespace blink { -// Wrapper functions defined in WebKit.h +// Wrapper functions defined in blink.h void SetLayoutTestMode(bool value) { - LayoutTestSupport::SetIsRunningLayoutTest(value); + WebTestSupport::SetIsRunningWebTest(value); } bool LayoutTestMode() { - return LayoutTestSupport::IsRunningLayoutTest(); + return WebTestSupport::IsRunningWebTest(); } void SetFontAntialiasingEnabledForTest(bool value) { - LayoutTestSupport::SetFontAntialiasingEnabledForTest(value); + WebTestSupport::SetFontAntialiasingEnabledForTest(value); } bool FontAntialiasingEnabledForTest() { - return LayoutTestSupport::IsFontAntialiasingEnabledForTest(); + return WebTestSupport::IsFontAntialiasingEnabledForTest(); } static bool g_is_running_layout_test = false; @@ -57,36 +57,36 @@ static bool g_is_font_antialiasing_enabled = false; static bool g_is_subpixel_positioning_allowed = true; -bool LayoutTestSupport::IsRunningLayoutTest() { +bool WebTestSupport::IsRunningWebTest() { return g_is_running_layout_test; } -void LayoutTestSupport::SetIsRunningLayoutTest(bool value) { +void WebTestSupport::SetIsRunningWebTest(bool value) { g_is_running_layout_test = value; } -bool LayoutTestSupport::IsMockThemeEnabledForTest() { +bool WebTestSupport::IsMockThemeEnabledForTest() { return g_is_mock_theme_enabled; } -void LayoutTestSupport::SetMockThemeEnabledForTest(bool value) { +void WebTestSupport::SetMockThemeEnabledForTest(bool value) { DCHECK(g_is_running_layout_test); g_is_mock_theme_enabled = value; } -bool LayoutTestSupport::IsFontAntialiasingEnabledForTest() { +bool WebTestSupport::IsFontAntialiasingEnabledForTest() { return g_is_font_antialiasing_enabled; } -void LayoutTestSupport::SetFontAntialiasingEnabledForTest(bool value) { +void WebTestSupport::SetFontAntialiasingEnabledForTest(bool value) { g_is_font_antialiasing_enabled = value; } -bool LayoutTestSupport::IsTextSubpixelPositioningAllowedForTest() { +bool WebTestSupport::IsTextSubpixelPositioningAllowedForTest() { return g_is_subpixel_positioning_allowed; } -void LayoutTestSupport::SetTextSubpixelPositioningAllowedForTest(bool value) { +void WebTestSupport::SetTextSubpixelPositioningAllowedForTest(bool value) { g_is_subpixel_positioning_allowed = value; }
diff --git a/third_party/blink/renderer/platform/layout_test_support.h b/third_party/blink/renderer/platform/web_test_support.h similarity index 85% rename from third_party/blink/renderer/platform/layout_test_support.h rename to third_party/blink/renderer/platform/web_test_support.h index 161819f..a3e5e5f 100644 --- a/third_party/blink/renderer/platform/layout_test_support.h +++ b/third_party/blink/renderer/platform/web_test_support.h
@@ -28,20 +28,20 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_LAYOUT_TEST_SUPPORT_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_LAYOUT_TEST_SUPPORT_H_ +#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_WEB_TEST_SUPPORT_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WEB_TEST_SUPPORT_H_ #include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/wtf/allocator.h" namespace blink { -class LayoutTestSupport { - STATIC_ONLY(LayoutTestSupport); +class WebTestSupport { + STATIC_ONLY(WebTestSupport); public: - PLATFORM_EXPORT static bool IsRunningLayoutTest(); - PLATFORM_EXPORT static void SetIsRunningLayoutTest(bool); + PLATFORM_EXPORT static bool IsRunningWebTest(); + PLATFORM_EXPORT static void SetIsRunningWebTest(bool); PLATFORM_EXPORT static bool IsMockThemeEnabledForTest(); PLATFORM_EXPORT static void SetMockThemeEnabledForTest(bool); PLATFORM_EXPORT static bool IsFontAntialiasingEnabledForTest(); @@ -52,4 +52,4 @@ } // namespace blink -#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_LAYOUT_TEST_SUPPORT_H_ +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_WEB_TEST_SUPPORT_H_
diff --git a/third_party/blink/renderer/platform/weborigin/security_origin.cc b/third_party/blink/renderer/platform/weborigin/security_origin.cc index 98500fb..81b8fa1 100644 --- a/third_party/blink/renderer/platform/weborigin/security_origin.cc +++ b/third_party/blink/renderer/platform/weborigin/security_origin.cc
@@ -47,6 +47,7 @@ #include "third_party/blink/renderer/platform/wtf/wtf.h" #include "url/url_canon.h" #include "url/url_canon_ip.h" +#include "url/url_util.h" namespace blink { @@ -121,13 +122,19 @@ return true; // Nonstandard schemes and unregistered schemes aren't known to contain hosts - // and/or ports, so they'll usually be placed in opaque origins. An exception - // is made for non-standard local schemes. - // TODO: Migrate "content:" and "externalfile:" to be standard schemes, and - // remove the local scheme exception. - if (!relevant_url.CanSetHostOrPort() && - !SchemeRegistry::ShouldTreatURLSchemeAsLocal(relevant_url.Protocol())) { - return true; + // and/or ports, so they'll usually be placed in opaque origins. + if (!relevant_url.CanSetHostOrPort()) { + // A temporary exception is made for non-standard local schemes. + // TODO: Migrate "content:" and "externalfile:" to be standard schemes, and + // remove the local scheme exception. + if (SchemeRegistry::ShouldTreatURLSchemeAsLocal(relevant_url.Protocol())) + return false; + + // Otherwise, treat non-standard origins as opaque, unless the Android + // WebView workaround is enabled. If the workaround is enabled, return false + // so that the scheme is retained, to avoid breaking XHRs on custom schemes, + // et cetera. + return !url::AllowNonStandardSchemesForAndroidWebView(); } // This is the common case.
diff --git a/third_party/blink/renderer/platform/weborigin/security_origin_test.cc b/third_party/blink/renderer/platform/weborigin/security_origin_test.cc index 8a95d1e..e77bd92 100644 --- a/third_party/blink/renderer/platform/weborigin/security_origin_test.cc +++ b/third_party/blink/renderer/platform/weborigin/security_origin_test.cc
@@ -790,4 +790,21 @@ } } +TEST_F(SecurityOriginTest, NonStandardScheme) { + scoped_refptr<const SecurityOrigin> origin = + SecurityOrigin::CreateFromString("cow://"); + EXPECT_TRUE(origin->IsOpaque()); +} + +TEST_F(SecurityOriginTest, NonStandardSchemeWithAndroidWebViewHack) { + url::EnableNonStandardSchemesForAndroidWebView(); + scoped_refptr<const SecurityOrigin> origin = + SecurityOrigin::CreateFromString("cow://"); + EXPECT_FALSE(origin->IsOpaque()); + EXPECT_EQ("cow", origin->Protocol()); + EXPECT_EQ("", origin->Host()); + EXPECT_EQ(0, origin->Port()); + url::Shutdown(); +} + } // namespace blink
diff --git a/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py b/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py index b035c8e..68a70e67 100755 --- a/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py +++ b/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py
@@ -231,6 +231,7 @@ 'css_parsing_utils::.+', 'cssvalue::.+', 'encoding::.+', + 'encoding_enum::.+', 'event_handling_util::.+', 'event_util::.+', 'file_error::.+',
diff --git a/third_party/blink/tools/blinkpy/web_tests/port/android.py b/third_party/blink/tools/blinkpy/web_tests/port/android.py index 52fad99..cb2b390 100644 --- a/third_party/blink/tools/blinkpy/web_tests/port/android.py +++ b/third_party/blink/tools/blinkpy/web_tests/port/android.py
@@ -37,6 +37,7 @@ from blinkpy.common import exit_codes from blinkpy.common.path_finder import RELATIVE_WEB_TESTS +from blinkpy.common.path_finder import WEB_TESTS_LAST_COMPONENT from blinkpy.common.path_finder import get_chromium_src_dir from blinkpy.common.system.executive import ScriptError from blinkpy.common.system.profiler import SingleFileOutputProfiler @@ -112,8 +113,11 @@ # but we use a file-to-http feature to bridge the file request to host's http # server to get the real test files and corresponding resources. # See webkit/support/platform_support_android.cc for the other side of this bridge. +# WEB_TEST_PATH_PREFIX should be matched to the local directory name of +# web_tests because some tests and test_runner find test root directory +# with it. PERF_TEST_PATH_PREFIX = '/PerformanceTests' -LAYOUT_TEST_PATH_PREFIX = '/LayoutTests' +WEB_TESTS_PATH_PREFIX = '/' + WEB_TESTS_LAST_COMPONENT # We start netcat processes for each of the three stdio streams. In doing so, # we attempt to use ports starting from 10201. This starting value is @@ -469,7 +473,7 @@ def start_http_server(self, additional_dirs, number_of_drivers): additional_dirs[PERF_TEST_PATH_PREFIX] = self._perf_tests_dir() - additional_dirs[LAYOUT_TEST_PATH_PREFIX] = self.layout_tests_dir() + additional_dirs[WEB_TESTS_PATH_PREFIX] = self.layout_tests_dir() super(AndroidPort, self).start_http_server(additional_dirs, number_of_drivers) def create_driver(self, worker_number, no_timeout=False):
diff --git a/third_party/blink/tools/blinkpy/web_tests/port/fuchsia.py b/third_party/blink/tools/blinkpy/web_tests/port/fuchsia.py index 617b881..88a1fde 100644 --- a/third_party/blink/tools/blinkpy/web_tests/port/fuchsia.py +++ b/third_party/blink/tools/blinkpy/web_tests/port/fuchsia.py
@@ -35,6 +35,7 @@ import threading from blinkpy.common import exit_codes +from blinkpy.common.path_finder import WEB_TESTS_LAST_COMPONENT from blinkpy.common.path_finder import get_chromium_src_dir from blinkpy.web_tests.port import base from blinkpy.web_tests.port import driver @@ -70,9 +71,12 @@ # Path to the content shell package relative to the build directory. CONTENT_SHELL_PACKAGE_PATH = 'gen/content/shell/content_shell/content_shell.far' -# HTTP path prefix for the HTTP server. +# HTTP path prefixes for the HTTP server. +# WEB_TEST_PATH_PREFIX should be matched to the local directory name of +# web_tests because some tests and test_runner find test root directory +# with it. PERF_TEST_PATH_PREFIX = '/PerformanceTests' -LAYOUT_TEST_PATH_PREFIX = '/LayoutTests' +WEB_TESTS_PATH_PREFIX = '/' + WEB_TESTS_LAST_COMPONENT # Paths to the directory where the fonts are copied to. Must match the path in # content/shell/app/blink_test_platform_support_fuchsia.cc . @@ -245,7 +249,7 @@ def start_http_server(self, additional_dirs, number_of_drivers): additional_dirs[PERF_TEST_PATH_PREFIX] = self._perf_tests_dir() - additional_dirs[LAYOUT_TEST_PATH_PREFIX] = self.layout_tests_dir() + additional_dirs[WEB_TESTS_PATH_PREFIX] = self.layout_tests_dir() super(FuchsiaPort, self).start_http_server( additional_dirs, number_of_drivers)
diff --git a/third_party/blink/web_tests/FlagExpectations/enable-features=NetworkService b/third_party/blink/web_tests/FlagExpectations/enable-features=NetworkService index 926cdd6..42616245 100644 --- a/third_party/blink/web_tests/FlagExpectations/enable-features=NetworkService +++ b/third_party/blink/web_tests/FlagExpectations/enable-features=NetworkService
@@ -17,9 +17,6 @@ crbug.com/896924 http/tests/inspector-protocol/network/interception-multiclient.js [ Pass ] crbug.com/899303 http/tests/inspector-protocol/fetch/fetch-basic.js [ Pass ] -# Flaky on non-NetworkService (disabled), consistent failing on NetworkService. Probably due to DCHECK. -crbug.com/849670 http/tests/devtools/service-workers/service-worker-v8-cache.js [ Pass Failure ] - # This passes in content_shell but not in chrome with network service disabled, # because content_shell does not add the about: handler. With network service # enabled this fails in both content_shell and chrome.
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 415302032..b6602b1c 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -4298,7 +4298,7 @@ crbug.com/688670 external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-cue-rendering-after-controls-removed.html [ Pass Failure ] -crbug.com/849670 http/tests/devtools/service-workers/service-worker-v8-cache.js [ Pass Crash Failure Timeout ] +crbug.com/849670 http/tests/devtools/service-workers/service-worker-v8-cache.js [ Pass Timeout ] crbug.com/664858 virtual/threaded/fast/scroll-behavior/overflow-scroll-animates.html [ Skip ] crbug.com/664858 virtual/threaded/fast/scroll-behavior/smooth-scroll/horizontal-smooth-scroll-in-rtl.html [ Skip ]
diff --git a/third_party/blink/web_tests/css-shadow-parts/double-forward.html b/third_party/blink/web_tests/css-shadow-parts/double-forward.html index 508f647..c938b12 100644 --- a/third_party/blink/web_tests/css-shadow-parts/double-forward.html +++ b/third_party/blink/web_tests/css-shadow-parts/double-forward.html
@@ -22,11 +22,11 @@ <template id="custom-element-outer-template"><custom-element-middle id="c-e-middle" exportparts="part-forwarded1: part-forwarded2"></custom-element-middle></template> The following text should be green: <custom-element-outer id="c-e-outer"></custom-element-outer> - <script type="text/javascript"> + <script> "use strict"; const colorGreen = "rgb(0, 128, 0)"; test(function() { - var el = getElementByShadowIds(document, ["c-e-outer", "c-e-middle", "c-e-inner", "green_part"]); + const el = getElementByShadowIds(document, ["c-e-outer", "c-e-middle", "c-e-inner", "green_part"]); assert_equals(window.getComputedStyle(el).color, colorGreen); }, "Part in inner host is forwarded through the middle host for styling by document style sheet"); </script>
diff --git a/third_party/blink/web_tests/css-shadow-parts/invalidation-change-part-name-forward.html b/third_party/blink/web_tests/css-shadow-parts/invalidation-change-part-name-forward.html index 0f29f263..87d5952 100644 --- a/third_party/blink/web_tests/css-shadow-parts/invalidation-change-part-name-forward.html +++ b/third_party/blink/web_tests/css-shadow-parts/invalidation-change-part-name-forward.html
@@ -20,13 +20,13 @@ <template id="custom-element-outer-template"><custom-element-inner id="c-e-inner" exportparts="partp: part-forwarded"></custom-element-inner></template> The following text should be green: <custom-element-outer id="c-e-outer"></custom-element-outer> - <script type="text/javascript"> + <script> "use strict"; test(function() { - var part = getElementByShadowIds(document, ["c-e-outer", "c-e-inner", "part"]); - var before = window.getComputedStyle(part).color; + const part = getElementByShadowIds(document, ["c-e-outer", "c-e-inner", "part"]); + const before = window.getComputedStyle(part).color; part.setAttribute("part", "new-partp"); - var after = window.getComputedStyle(part).color; + const after = window.getComputedStyle(part).color; assert_not_equals(before, after); }, "Part in selected host changed color"); </script>
diff --git a/third_party/blink/web_tests/css-shadow-parts/invalidation-complex-selector-forward.html b/third_party/blink/web_tests/css-shadow-parts/invalidation-complex-selector-forward.html index 51c8c91..cc374239 100644 --- a/third_party/blink/web_tests/css-shadow-parts/invalidation-complex-selector-forward.html +++ b/third_party/blink/web_tests/css-shadow-parts/invalidation-complex-selector-forward.html
@@ -20,13 +20,13 @@ <template id="custom-element-outer-template"><custom-element-inner id="c-e-inner" exportparts="partp: part-forwarded"></custom-element-inner></template> The following text should be green: <div id="elem"><custom-element-outer id="c-e-outer"></custom-element-outer></div> - <script type="text/javascript"> + <script> "use strict"; test(function() { - var part = getElementByShadowIds(document, ["c-e-outer", "c-e-inner", "part"]); - var before = window.getComputedStyle(part).color; + const part = getElementByShadowIds(document, ["c-e-outer", "c-e-inner", "part"]); + const before = window.getComputedStyle(part).color; document.getElementById("elem").setAttribute("id", "new-elem"); - var after = window.getComputedStyle(part).color; + const after = window.getComputedStyle(part).color; assert_not_equals(before, after); }, "Part in selected host changed color"); </script>
diff --git a/third_party/blink/web_tests/css-shadow-parts/precedence-part-vs-part.html b/third_party/blink/web_tests/css-shadow-parts/precedence-part-vs-part.html index 4be9756..bb12535 100644 --- a/third_party/blink/web_tests/css-shadow-parts/precedence-part-vs-part.html +++ b/third_party/blink/web_tests/css-shadow-parts/precedence-part-vs-part.html
@@ -23,11 +23,11 @@ </template> The following text should be green: <custom-element-outer id="c-e-outer"></custom-element-outer> - <script type="text/javascript"> + <script> "use strict"; const colorGreen = "rgb(0, 128, 0)"; test(function() { - var el = getElementByShadowIds(document, ["c-e-outer", "c-e-inner", "green_part"]); + const el = getElementByShadowIds(document, ["c-e-outer", "c-e-inner", "green_part"]); assert_equals(window.getComputedStyle(el).color, colorGreen); }, "Style from document overrides style from outer CE"); </script>
diff --git a/third_party/blink/web_tests/css-shadow-parts/simple-forward-shorthand.html b/third_party/blink/web_tests/css-shadow-parts/simple-forward-shorthand.html index 6dba9e8..720bdd0d 100644 --- a/third_party/blink/web_tests/css-shadow-parts/simple-forward-shorthand.html +++ b/third_party/blink/web_tests/css-shadow-parts/simple-forward-shorthand.html
@@ -20,11 +20,11 @@ <template id="custom-element-outer-template"><custom-element-inner id="c-e-inner" exportparts="partp"></custom-element-inner></template> The following text should be green: <custom-element-outer id="c-e-outer"></custom-element-outer> - <script type="text/javascript"> + <script> "use strict"; const colorGreen = "rgb(0, 128, 0)"; test(function() { - var el = getElementByShadowIds(document, ["c-e-outer", "c-e-inner", "green_part"]); + const el = getElementByShadowIds(document, ["c-e-outer", "c-e-inner", "green_part"]); assert_equals(window.getComputedStyle(el).color, colorGreen); }, "Part in inner host is forwarded, under the same name, for styling by document style sheet"); </script>
diff --git a/third_party/blink/web_tests/css-shadow-parts/simple-forward.html b/third_party/blink/web_tests/css-shadow-parts/simple-forward.html index 7f01f34..a41e0728 100644 --- a/third_party/blink/web_tests/css-shadow-parts/simple-forward.html +++ b/third_party/blink/web_tests/css-shadow-parts/simple-forward.html
@@ -20,11 +20,11 @@ <template id="custom-element-outer-template"><custom-element-inner id="c-e-inner" exportparts="partp: part-forwarded"></custom-element-inner></template> The following text should be green: <custom-element-outer id="c-e-outer"></custom-element-outer> - <script type="text/javascript"> + <script> "use strict"; const colorGreen = "rgb(0, 128, 0)"; test(function() { - var el = getElementByShadowIds(document, ["c-e-outer", "c-e-inner", "green_part"]); + const el = getElementByShadowIds(document, ["c-e-outer", "c-e-inner", "green_part"]); assert_equals(window.getComputedStyle(el).color, colorGreen); }, "Part in inner host is forwarded for styling by document style sheet"); </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-shadow-parts/all-hosts.html b/third_party/blink/web_tests/external/wpt/css/css-shadow-parts/all-hosts.html index e6646c0..218535d 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-shadow-parts/all-hosts.html +++ b/third_party/blink/web_tests/external/wpt/css/css-shadow-parts/all-hosts.html
@@ -20,15 +20,15 @@ <custom-element id="c-e-1"></custom-element> The following text should be green: <custom-element id="c-e-2"></custom-element> - <script type="text/javascript"> + <script> "use strict"; const colorGreen = "rgb(0, 128, 0)"; test(function() { - var el = getElementByShadowIds(document, ["c-e-1", "part"]); + const el = getElementByShadowIds(document, ["c-e-1", "part"]); assert_equals(window.getComputedStyle(el).color, colorGreen); }, "::part with host selector styles in first host"); test(function() { - var el = getElementByShadowIds(document, ["c-e-2", "part"]); + const el = getElementByShadowIds(document, ["c-e-2", "part"]); assert_equals(window.getComputedStyle(el).color, colorGreen); }, "::part with host selector styles in second host"); </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-shadow-parts/chaining-invalid-selector.html b/third_party/blink/web_tests/external/wpt/css/css-shadow-parts/chaining-invalid-selector.html index 1130932..cb34a7b 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-shadow-parts/chaining-invalid-selector.html +++ b/third_party/blink/web_tests/external/wpt/css/css-shadow-parts/chaining-invalid-selector.html
@@ -26,11 +26,11 @@ <custom-element-inner id="c-e-inner" part="c-e-part"></custom-element-inner> </template> <custom-element-outer id="c-e-outer"></custom-element-outer> - <script type="text/javascript"> + <script> "use strict"; const colorGreen = "rgb(0, 128, 0)"; test(function() { - var el = getElementByShadowIds(document, ["c-e-outer", "c-e-inner", "part"]); + const el = getElementByShadowIds(document, ["c-e-outer", "c-e-inner", "part"]); assert_equals(window.getComputedStyle(el).color, colorGreen); }, "::part cannot be chained to reach elements in the inner host"); test(function() {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-shadow-parts/complex-matching.html b/third_party/blink/web_tests/external/wpt/css/css-shadow-parts/complex-matching.html index 575edabc..f8f063d 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-shadow-parts/complex-matching.html +++ b/third_party/blink/web_tests/external/wpt/css/css-shadow-parts/complex-matching.html
@@ -18,11 +18,11 @@ </template> The following text should be green: <div><custom-element id="c-e"></custom-element></div> - <script type="text/javascript"> + <script> "use strict"; const colorGreen = "rgb(0, 128, 0)"; test(function() { - var el = getElementByShadowIds(document, ["c-e", "part"]); + const el = getElementByShadowIds(document, ["c-e", "part"]); assert_equals(window.getComputedStyle(el).color, colorGreen); }, "Complex selector for host works"); </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-shadow-parts/complex-non-matching.html b/third_party/blink/web_tests/external/wpt/css/css-shadow-parts/complex-non-matching.html index 036713f..6e5bc69c 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-shadow-parts/complex-non-matching.html +++ b/third_party/blink/web_tests/external/wpt/css/css-shadow-parts/complex-non-matching.html
@@ -18,11 +18,11 @@ </template> The following text should be green: <pre><custom-element id="c-e"></custom-element></pre> - <script type="text/javascript"> + <script> "use strict"; const colorGreen = "rgb(0, 128, 0)"; test(function() { - var el = getElementByShadowIds(document, ["c-e", "part"]); + const el = getElementByShadowIds(document, ["c-e", "part"]); assert_equals(window.getComputedStyle(el).color, colorGreen); }, "Non-matching complex selector for host does not style"); </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-shadow-parts/different-host.html b/third_party/blink/web_tests/external/wpt/css/css-shadow-parts/different-host.html index c8b5f863..7fe9744 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-shadow-parts/different-host.html +++ b/third_party/blink/web_tests/external/wpt/css/css-shadow-parts/different-host.html
@@ -18,11 +18,11 @@ </template> The following text should be green: <custom-element id="c-e"></custom-element> - <script type="text/javascript"> + <script> "use strict"; const colorGreen = "rgb(0, 128, 0)"; test(function() { - var el = getElementByShadowIds(document, ["c-e", "part"]); + const el = getElementByShadowIds(document, ["c-e", "part"]); assert_equals(window.getComputedStyle(el).color, colorGreen); }, "Part is not styled when host is not selected"); </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-shadow-parts/host-stylesheet.html b/third_party/blink/web_tests/external/wpt/css/css-shadow-parts/host-stylesheet.html index ee8f4e7..2e65c4b 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-shadow-parts/host-stylesheet.html +++ b/third_party/blink/web_tests/external/wpt/css/css-shadow-parts/host-stylesheet.html
@@ -20,11 +20,11 @@ </template> The following text should be green: <custom-element id="c-e"></custom-element> - <script type="text/javascript"> + <script> "use strict"; const colorGreen = "rgb(0, 128, 0)"; test(function() { - var el = getElementByShadowIds(document, ["c-e", "part"]); + const el = getElementByShadowIds(document, ["c-e", "part"]); assert_equals(window.getComputedStyle(el).color, colorGreen); }, "Part in selected host is not styled by ::part in a stylesheet inside the host"); </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-shadow-parts/inner-host.html b/third_party/blink/web_tests/external/wpt/css/css-shadow-parts/inner-host.html index 8c8cec7..2dfd4b0 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-shadow-parts/inner-host.html +++ b/third_party/blink/web_tests/external/wpt/css/css-shadow-parts/inner-host.html
@@ -25,16 +25,16 @@ </template> The following text should be green: <custom-element-outer id="c-e-outer"></custom-element-outer> - <script type="text/javascript"> + <script> "use strict"; const colorBlue = "rgb(0, 0, 255)"; const colorGreen = "rgb(0, 128, 0)"; test(function() { - var el = getElementByShadowIds(document, ["c-e-outer", "green_part"]); + const el = getElementByShadowIds(document, ["c-e-outer", "green_part"]); assert_equals(window.getComputedStyle(el).color, colorGreen); }, "Part in outer host is styled by document style sheet"); test(function() { - var el = getElementByShadowIds(document, ["c-e-outer", "c-e-inner", "blue_part"]); + const el = getElementByShadowIds(document, ["c-e-outer", "c-e-inner", "blue_part"]); assert_equals(window.getComputedStyle(el).color, colorBlue); }, "Part in inner host is not styled by document style sheet"); </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-shadow-parts/invalidation-change-part-name.html b/third_party/blink/web_tests/external/wpt/css/css-shadow-parts/invalidation-change-part-name.html index 7e7a310f..47630d9 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-shadow-parts/invalidation-change-part-name.html +++ b/third_party/blink/web_tests/external/wpt/css/css-shadow-parts/invalidation-change-part-name.html
@@ -18,13 +18,13 @@ </template> The following text should be green: <div><custom-element id="c-e"></custom-element></div> - <script type="text/javascript"> + <script> "use strict"; test(function() { - var part = getElementByShadowIds(document, ["c-e", "part"]); - var before = window.getComputedStyle(part).color; + const part = getElementByShadowIds(document, ["c-e", "part"]); + const before = window.getComputedStyle(part).color; part.setAttribute("part", "new-partp"); - var after = window.getComputedStyle(part).color; + const after = window.getComputedStyle(part).color; assert_not_equals(before, after); }, "Part in selected host changed color"); </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-shadow-parts/invalidation-complex-selector.html b/third_party/blink/web_tests/external/wpt/css/css-shadow-parts/invalidation-complex-selector.html index e1f10e5..5b1fd80 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-shadow-parts/invalidation-complex-selector.html +++ b/third_party/blink/web_tests/external/wpt/css/css-shadow-parts/invalidation-complex-selector.html
@@ -18,13 +18,13 @@ </template> The following text should be green: <div id="elem"><custom-element id="c-e"></custom-element></div> - <script type="text/javascript"> + <script> "use strict"; test(function() { - var part = getElementByShadowIds(document, ["c-e", "part"]); - var before = window.getComputedStyle(part).color; + const part = getElementByShadowIds(document, ["c-e", "part"]); + const before = window.getComputedStyle(part).color; document.getElementById("elem").setAttribute("id", "new-elem"); - var after = window.getComputedStyle(part).color; + const after = window.getComputedStyle(part).color; assert_not_equals(before, after); }, "Part in selected host changed color"); </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-shadow-parts/simple.html b/third_party/blink/web_tests/external/wpt/css/css-shadow-parts/simple.html index 3733669..a7f17d9 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-shadow-parts/simple.html +++ b/third_party/blink/web_tests/external/wpt/css/css-shadow-parts/simple.html
@@ -18,11 +18,11 @@ </template> The following text should be green: <custom-element id="c-e"></custom-element> - <script type="text/javascript"> + <script> "use strict"; const colorGreen = "rgb(0, 128, 0)"; test(function() { - var el = getElementByShadowIds(document, ["c-e", "part"]); + const el = getElementByShadowIds(document, ["c-e", "part"]); assert_equals(window.getComputedStyle(el).color, colorGreen); }, "Part in selected host is styled"); </script>
diff --git a/third_party/blink/web_tests/external/wpt/storage/estimate-usage-details-indexeddb.https.tentative.any.js b/third_party/blink/web_tests/external/wpt/storage/estimate-usage-details-indexeddb.https.tentative.any.js new file mode 100644 index 0000000..c854d5b --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/storage/estimate-usage-details-indexeddb.https.tentative.any.js
@@ -0,0 +1,59 @@ +// META: title=StorageManager: estimate() usage details for indexeddb +// META: script=helpers.js +// META: script=../IndexedDB/support-promises.js + +promise_test(async t => { + const estimate = await navigator.storage.estimate() + assert_equals(typeof estimate.usageDetails, 'object'); +}, 'estimate() resolves to dictionary with usageDetails member'); + +promise_test(async t => { + // We use 100KB here because db compaction usually happens every few MB + // 100KB is large enough to avoid a false positive (small amounts of metadata + // getting written for some random reason), and small enough to avoid + // compaction with a reasonably high probability. + const writeSize = 1024 * 100; + const objectStoreName = 'store'; + const dbname = self.location.pathname; + + await indexedDB.deleteDatabase(dbname); + let usageAfterWrite, usageBeforeWrite; + // TODO(crbug.com/906867): Refactor this test to better deal with db/log + // compaction flakiness + // The for loop here is to help make this test less flaky. The reason it is + // flaky is that database and/or log compaction could happen in the middle of + // this loop. The problem is that this test runs in a large batch of tests, + // and previous tests might have created a lot of garbage which could trigger + // compaction. Suppose the initial estimate shows 1MB usage before creating + // the db. Compaction could happen after this step and before we measure + // usage at the end, meaning the 1MB could be wiped to 0, an extra 1024 * 100 + // is put in, and the actual increase in usage does not reach our expected + // increase. Loop 10 times here to be safe (and reduce the number of bot + // builds that fail); all it takes is one iteration without compaction for + // this to pass. + for (let i = 0; i < 10; i++) { + const db = await createDB(dbname, objectStoreName, t); + let estimate = await navigator.storage.estimate(); + + // If usage is 0, usageDetails does not include the usage (undefined) + usageBeforeWrite = estimate.usageDetails.indexedDB || 0; + + const txn = db.transaction(objectStoreName, 'readwrite'); + const valueToStore = largeValue(writeSize, Math.random() * 255); + txn.objectStore(objectStoreName).add(valueToStore, 1); + + await transactionPromise(txn); + + estimate = await navigator.storage.estimate(); + usageAfterWrite = estimate.usageDetails.indexedDB; + db.close(); + + if (usageAfterWrite - usageBeforeWrite >= writeSize) { + break; + } + } + + assert_greater_than_equal(usageAfterWrite - usageBeforeWrite, + writeSize); +}, 'estimate() usage details reflects increase in indexedDB after large ' + + 'value is stored');
diff --git a/third_party/blink/web_tests/external/wpt/storage/helpers.js b/third_party/blink/web_tests/external/wpt/storage/helpers.js new file mode 100644 index 0000000..fbc746a --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/storage/helpers.js
@@ -0,0 +1,43 @@ +/** + * @description - Function will create a database with the supplied name + * and also create an object store with the specified name. + * If a db with the name dbName exists, this will raze the + * existing DB beforehand. + * @param {string} dbName + * @param {string} objectStoreName + * @param {testCase} t + * @returns {Promise} - A promise that resolves to an indexedDB open request + */ +function createDB(dbName, objectStoreName, t) { + return new Promise((resolve, reject) => { + const openRequest = indexedDB.open(dbName); + t.add_cleanup(() => { + indexedDB.deleteDatabase(dbName); + }); + + openRequest.onerror = () => { + reject(openRequest.error); + }; + openRequest.onsuccess = () => { + resolve(openRequest.result); + }; + openRequest.onupgradeneeded = event => { + openRequest.result.createObjectStore(objectStoreName); + }; + }); +} + +/** + * @description - This function will wrap an IDBTransaction in a promise, + * resolving in the oncomplete() method and rejecting with the + * transaction error in the onabort() case. + * @param {IDBTransaction} transaction - The transaction to wrap in a promise. + * @returns {Promise} - A promise that resolves when the transaction is either + * aborted or completed. + */ +function transactionPromise(transaction) { + return new Promise((resolve, reject) => { + transaction.onabort = () => { reject(transaction.error); }; + transaction.oncomplete = () => { resolve(); }; + }); +}
diff --git a/third_party/blink/web_tests/http/tests/devtools/har-importer-expected.txt b/third_party/blink/web_tests/http/tests/devtools/har-importer-expected.txt new file mode 100644 index 0000000..dc4385c --- /dev/null +++ b/third_party/blink/web_tests/http/tests/devtools/har-importer-expected.txt
@@ -0,0 +1,242 @@ +Verifies that imported HAR files create matching NetworkRequests +requests: [ + { + "url": "http://localhost:8000/", + "documentURL": "http://localhost:8000/", + "initiator": { + "type": "other" + }, + "requestFormData": null, + "connectionId": "2945", + "requestMethod": "GET", + "requestHeaders": [ + { + "name": "Host", + "value": "localhost:8000" + } + ], + "mimeType": "text/html", + "responseHeaders": [ + { + "name": "Content-Type", + "value": "text/html;charset=ISO-8859-1" + } + ], + "statusCode": 200, + "statusText": "OK", + "protocol": "http/1.1", + "resourceSize": 4633, + "transferSize": 4821, + "cached": false, + "cachedInMemory": false, + "contentData": { + "error": null, + "content": "fake page data", + "encoded": false + }, + "remoteAddress": "[::1]:80", + "resourceType": { + "_name": "document", + "_title": "Document", + "_category": { + "title": "Documents", + "shortTitle": "Doc" + }, + "_isTextType": true + }, + "priority": "VeryHigh", + "finished": true, + "timing": { + "proxyStart": 2.0154479999188335, + "proxyEnd": 2.4644479999188333, + "requestTime": 1542746587.755448, + "dnsStart": -1, + "dnsEnd": -1, + "connectStart": -1, + "connectEnd": -1, + "sslStart": -1, + "sslEnd": -1, + "workerStart": -1, + "workerReady": -1, + "sendStart": 2.4644479999188333, + "sendEnd": 2.534447999918833, + "pushStart": 0, + "pushEnd": 0, + "receiveHeadersEnd": 5.624447982991114 + }, + "endTime": 1542746587.7661417 + }, + { + "url": "http://localhost:8000/post-endpoint", + "documentURL": "http://localhost:8000/", + "initiator": { + "type": "parser", + "url": "http://localhost/", + "lineNumber": 1 + }, + "requestFormData": "one=urlencodedvalueone&two=urlencodedvaluetwo", + "connectionId": "2945", + "requestMethod": "POST", + "requestHeaders": [], + "mimeType": "image/x-icon", + "responseHeaders": [], + "statusCode": 200, + "statusText": "OK", + "protocol": "http/1.1", + "resourceSize": 1150, + "transferSize": 1417, + "cached": false, + "cachedInMemory": false, + "contentData": { + "error": null, + "content": null, + "encoded": false + }, + "remoteAddress": "[::1]:80", + "resourceType": { + "_name": "image", + "_title": "Image", + "_category": { + "title": "Images", + "shortTitle": "Img" + }, + "_isTextType": false + }, + "priority": "Low", + "finished": true, + "timing": { + "proxyStart": 1.7575360001232476, + "proxyEnd": 2.2485360001232477, + "requestTime": 1542746587.8705359, + "dnsStart": -1, + "dnsEnd": -1, + "connectStart": -1, + "connectEnd": -1, + "sslStart": -1, + "sslEnd": -1, + "workerStart": -1, + "workerReady": -1, + "sendStart": 2.2485360001232477, + "sendEnd": 2.3095360001232477, + "pushStart": 0, + "pushEnd": 0, + "receiveHeadersEnd": 2.828536113491282 + }, + "endTime": 1542746587.8738945 + }, + { + "url": "http://localhost:8000/js_file.js", + "documentURL": "http://localhost:8000/", + "initiator": { + "type": "parser", + "url": "http://localhost/", + "lineNumber": 1 + }, + "requestFormData": null, + "connectionId": "2945", + "requestMethod": "GET", + "requestHeaders": [], + "mimeType": "undefined", + "responseHeaders": [], + "statusCode": 200, + "statusText": "OK", + "protocol": "http/1.1", + "resourceSize": 1150, + "transferSize": 1417, + "cached": false, + "cachedInMemory": false, + "contentData": { + "error": null, + "content": null, + "encoded": false + }, + "remoteAddress": "[::1]:80", + "resourceType": { + "_name": "script", + "_title": "Script", + "_category": { + "title": "Scripts", + "shortTitle": "JS" + }, + "_isTextType": true + }, + "priority": "Low", + "finished": true, + "timing": { + "proxyStart": 1.7575360001232476, + "proxyEnd": 2.2485360001232477, + "requestTime": 1542746587.8705359, + "dnsStart": -1, + "dnsEnd": -1, + "connectStart": -1, + "connectEnd": -1, + "sslStart": -1, + "sslEnd": -1, + "workerStart": -1, + "workerReady": -1, + "sendStart": 2.2485360001232477, + "sendEnd": 2.3095360001232477, + "pushStart": 0, + "pushEnd": 0, + "receiveHeadersEnd": 2.828536113491282 + }, + "endTime": 1542746587.8738945 + }, + { + "url": "http://localhost:8000/endpoint", + "documentURL": "http://localhost:8000/", + "initiator": { + "type": "script" + }, + "requestFormData": null, + "connectionId": "2945", + "requestMethod": "GET", + "requestHeaders": [], + "mimeType": "undefined", + "responseHeaders": [], + "statusCode": 200, + "statusText": "OK", + "protocol": "http/1.1", + "resourceSize": 1150, + "transferSize": 1417, + "cached": false, + "cachedInMemory": false, + "contentData": { + "error": null, + "content": null, + "encoded": false + }, + "remoteAddress": "[::1]:80", + "resourceType": { + "_name": "fetch", + "_title": "Fetch", + "_category": { + "title": "XHR and Fetch", + "shortTitle": "XHR" + }, + "_isTextType": true + }, + "priority": "Low", + "finished": true, + "timing": { + "proxyStart": 1.7575360001232476, + "proxyEnd": 2.2485360001232477, + "requestTime": 1542746587.8705359, + "dnsStart": -1, + "dnsEnd": -1, + "connectStart": -1, + "connectEnd": -1, + "sslStart": -1, + "sslEnd": -1, + "workerStart": -1, + "workerReady": -1, + "sendStart": 2.2485360001232477, + "sendEnd": 2.3095360001232477, + "pushStart": 0, + "pushEnd": 0, + "receiveHeadersEnd": 2.828536113491282 + }, + "endTime": 1542746587.8738945 + } +] +
diff --git a/third_party/blink/web_tests/http/tests/devtools/har-importer.js b/third_party/blink/web_tests/http/tests/devtools/har-importer.js new file mode 100644 index 0000000..dd772218 --- /dev/null +++ b/third_party/blink/web_tests/http/tests/devtools/har-importer.js
@@ -0,0 +1,264 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +(async function() { + TestRunner.addResult( + 'Verifies that imported HAR files create matching NetworkRequests'); + await TestRunner.loadModule('application_test_runner'); + await TestRunner.loadModule('network_test_runner'); + const harRoot = new HARImporter.HARRoot(harJson); + const requests = HARImporter.Importer.requestsFromHARLog(harRoot.log); + const formattedRequests = await Promise.all(requests.map(async request => { + return { + url: request.url(), + documentURL: request.documentURL, + initiator: request.initiator(), + requestFormData: await(request.requestFormData()), + connectionId: request.connectionId, + requestMethod: request.requestMethod, + requestHeaders: request.requestHeaders(), + mimeType: request.mimeType, + responseHeaders: request.responseHeaders, + statusCode: request.statusCode, + statusText: request.statusText, + protocol: request.protocol, + resourceSize: request.resourceSize, + transferSize: request.transferSize, + cached: request.cached(), + cachedInMemory: request.cachedInMemory(), + contentData: await(request.contentData()), + remoteAddress: request.remoteAddress(), + resourceType: request.resourceType(), + priority: request.priority(), + finished: request.finished, + timing: request.timing, + endTime: request.endTime + }; + })); + TestRunner.addResult( + 'requests: ' + JSON.stringify(formattedRequests, null, 2)); + TestRunner.completeTest(); +})(); + +const harJson = { + 'log': { + 'version': '1.2', + 'creator': {'name': 'WebInspector', 'version': '537.36'}, + 'pages': [{ + 'startedDateTime': '2018-11-20T20:43:07.756Z', + 'id': 'page_1', + 'title': 'http://localhost:8000/', + 'pageTimings': + {'onContentLoad': 67.84599996171892, 'onLoad': 112.05600015819073} + }], + 'entries': [ + { + 'startedDateTime': '2018-11-20T20:43:07.755Z', + 'time': 11.14144808263518, + 'request': { + 'method': 'GET', + 'url': 'http://localhost:8000/', + 'httpVersion': 'HTTP/1.1', + 'headers': [{'name': 'Host', 'value': 'localhost:8000'}], + 'queryString': [], + 'cookies': [], + 'headersSize': 418, + 'bodySize': 0 + }, + 'response': { + 'status': 200, + 'statusText': 'OK', + 'httpVersion': 'HTTP/1.1', + 'headers': [ + {'name': 'Content-Type', 'value': 'text/html;charset=ISO-8859-1'} + ], + 'cookies': [{ + 'name': 'test-cookie-name', + 'value': '1', + 'path': '/', + 'domain': '.localhost', + 'expires': '2018-11-19T18:17:22.000Z', + 'httpOnly': false, + 'secure': false + }], + 'content': + {'size': 4633, 'mimeType': 'text/html', 'text': 'fake page data'}, + 'redirectURL': '', + 'headersSize': 188, + 'bodySize': 4633, + '_transferSize': 4821 + }, + 'cache': {}, + 'timings': { + 'blocked': 2.4644479999188333, + 'dns': -1, + 'ssl': -1, + 'connect': -1, + 'send': 0.06999999999999984, + 'wait': 3.089999983072281, + 'receive': 5.517000099644065, + '_blocked_queueing': 0.447999918833375, + '_blocked_proxy': 0.44899999999999984 + }, + 'serverIPAddress': '[::1]', + '_initiator': {'type': 'other'}, + '_priority': 'VeryHigh', + 'connection': '2945', + 'pageref': 'page_1' + }, + { + 'startedDateTime': '2018-11-20T20:43:07.870Z', + 'time': 3.8945360814686865, + 'request': { + 'method': 'POST', + 'url': 'http://localhost:8000/post-endpoint', + 'httpVersion': 'HTTP/1.1', + 'headers': [], + 'queryString': [], + 'cookies': [], + 'headersSize': 386, + 'bodySize': 0, + 'postData': { + 'mimeType': 'application/x-www-form-urlencoded', + 'text': 'one=urlencodedvalueone&two=urlencodedvaluetwo', + 'params': [ + {'name': 'one', 'value': 'urlencodedvalueone'}, + {'name': 'two', 'value': 'urlencodedvaluetwo'} + ] + } + }, + 'response': { + 'status': 200, + 'statusText': 'OK', + 'httpVersion': 'HTTP/1.1', + 'headers': [], + 'cookies': [], + 'content': + {'size': 1150, 'mimeType': 'image/x-icon', 'compression': 0}, + 'redirectURL': '', + 'headersSize': 267, + 'bodySize': 1150, + '_transferSize': 1417 + }, + 'cache': {}, + 'timings': { + 'blocked': 2.2485360001232477, + 'dns': -1, + 'ssl': -1, + 'connect': -1, + 'send': 0.06099999999999994, + 'wait': 0.5190001133680342, + 'receive': 1.0659999679774046, + '_blocked_queueing': 0.5360001232475042, + '_blocked_proxy': 0.4910000000000001 + }, + 'serverIPAddress': '[::1]', + '_initiator': + {'type': 'parser', 'url': 'http://localhost/', 'lineNumber': 1}, + '_priority': 'Low', + 'connection': '2945', + 'pageref': 'page_1' + }, + { + 'startedDateTime': '2018-11-20T20:43:07.870Z', + 'time': 3.8945360814686865, + 'request': { + 'method': 'GET', + 'url': 'http://localhost:8000/js_file.js', + 'httpVersion': 'HTTP/1.1', + 'headers': [], + 'queryString': [], + 'cookies': [], + 'headersSize': 386, + 'bodySize': 0 + }, + 'response': { + 'status': 200, + 'statusText': 'OK', + 'httpVersion': 'HTTP/1.1', + 'headers': [], + 'cookies': [], + 'content': {'size': 1150, 'compression': 0}, + 'redirectURL': '', + 'headersSize': 267, + 'bodySize': 1150, + '_transferSize': 1417 + }, + 'cache': {}, + 'timings': { + 'blocked': 2.2485360001232477, + 'dns': -1, + 'ssl': -1, + 'connect': -1, + 'send': 0.06099999999999994, + 'wait': 0.5190001133680342, + 'receive': 1.0659999679774046, + '_blocked_queueing': 0.5360001232475042, + '_blocked_proxy': 0.4910000000000001 + }, + 'serverIPAddress': '[::1]', + '_initiator': + {'type': 'parser', 'url': 'http://localhost/', 'lineNumber': 1}, + '_priority': 'Low', + 'connection': '2945', + 'pageref': 'page_1' + }, + { + 'startedDateTime': '2018-11-20T20:43:07.870Z', + 'time': 3.8945360814686865, + 'request': { + 'method': 'GET', + 'url': 'http://localhost:8000/endpoint', + 'httpVersion': 'HTTP/1.1', + 'headers': [], + 'queryString': [], + 'cookies': [], + 'headersSize': 386, + 'bodySize': 0 + }, + 'response': { + 'status': 200, + 'statusText': 'OK', + 'httpVersion': 'HTTP/1.1', + 'headers': [], + 'cookies': [], + 'content': {'size': 1150, 'compression': 0}, + 'redirectURL': '', + 'headersSize': 267, + 'bodySize': 1150, + '_transferSize': 1417 + }, + 'cache': {}, + 'timings': { + 'blocked': 2.2485360001232477, + 'dns': -1, + 'ssl': -1, + 'connect': -1, + 'send': 0.06099999999999994, + 'wait': 0.5190001133680342, + 'receive': 1.0659999679774046, + '_blocked_queueing': 0.5360001232475042, + '_blocked_proxy': 0.4910000000000001 + }, + 'serverIPAddress': '[::1]', + '_initiator': { + 'type': 'script', + 'stack': { + 'callFrames': { + 'functionName': '', + 'scriptId': '32', + 'url': 'http://localhost:8000/script.js', + 'lineNumber': 5, + 'colNumber': 2 + } + } + }, + '_priority': 'Low', + '_resourceType': 'fetch', + 'connection': '2945', + 'pageref': 'page_1' + } + ] + } +};
diff --git a/third_party/blink/web_tests/http/tests/devtools/resource-har-conversion-expected.txt b/third_party/blink/web_tests/http/tests/devtools/resource-har-conversion-expected.txt index 0922058..0547a8b 100644 --- a/third_party/blink/web_tests/http/tests/devtools/resource-har-conversion-expected.txt +++ b/third_party/blink/web_tests/http/tests/devtools/resource-har-conversion-expected.txt
@@ -10,6 +10,7 @@ { _initiator : <object> _priority : <string> + _resourceType : "document" cache : { } connection : <string> @@ -107,6 +108,7 @@ { _initiator : <object> _priority : <string> + _resourceType : "xhr" cache : { } connection : <string>
diff --git a/third_party/blink/web_tests/http/tests/devtools/resource-har-headers-expected.txt b/third_party/blink/web_tests/http/tests/devtools/resource-har-headers-expected.txt index c339d1bf..2faa442b 100644 --- a/third_party/blink/web_tests/http/tests/devtools/resource-har-headers-expected.txt +++ b/third_party/blink/web_tests/http/tests/devtools/resource-har-headers-expected.txt
@@ -31,6 +31,7 @@ url : "http://example.com/inspector-test.js" } _priority : "VeryHigh" + _resourceType : "fetch" cache : { } request : {
diff --git a/third_party/blink/web_tests/http/tests/devtools/resource-har-headers.js b/third_party/blink/web_tests/http/tests/devtools/resource-har-headers.js index 4d28d75a..f709eb5 100644 --- a/third_party/blink/web_tests/http/tests/devtools/resource-har-headers.js +++ b/third_party/blink/web_tests/http/tests/devtools/resource-har-headers.js
@@ -26,6 +26,7 @@ request.resourceSize = 1000; request._transferSize = 539; // 39 = header size at the end of the day request.setPriority('VeryHigh'); + request.setResourceType(Common.resourceTypes.Fetch); // sample timing values used here are copied from a real request request.setIssueTime(357904.060558);
diff --git a/third_party/blink/web_tests/http/tests/devtools/resource-parameters-expected.txt b/third_party/blink/web_tests/http/tests/devtools/resource-parameters-expected.txt index d8c758f..4e44c9d 100644 --- a/third_party/blink/web_tests/http/tests/devtools/resource-parameters-expected.txt +++ b/third_party/blink/web_tests/http/tests/devtools/resource-parameters-expected.txt
@@ -4,6 +4,7 @@ { _initiator : <object> _priority : <string> + _resourceType : "document" cache : { } connection : <string>
diff --git a/third_party/blink/web_tests/http/tests/devtools/resource-parameters-ipv6-expected.txt b/third_party/blink/web_tests/http/tests/devtools/resource-parameters-ipv6-expected.txt index 86b853a6..38c84c44 100644 --- a/third_party/blink/web_tests/http/tests/devtools/resource-parameters-ipv6-expected.txt +++ b/third_party/blink/web_tests/http/tests/devtools/resource-parameters-ipv6-expected.txt
@@ -4,6 +4,7 @@ { _initiator : <object> _priority : <string> + _resourceType : "document" cache : { } connection : <string>
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/service-worker/intercept-css-enable-fetch-expected.txt b/third_party/blink/web_tests/http/tests/inspector-protocol/service-worker/intercept-css-enable-fetch-expected.txt new file mode 100644 index 0000000..64638cd --- /dev/null +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/service-worker/intercept-css-enable-fetch-expected.txt
@@ -0,0 +1,3 @@ +Verifies that service workers do not throw errors from devtools css enable initiated fetch. +finished awaiting for css enable +
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/service-worker/intercept-css-enable-fetch.js b/third_party/blink/web_tests/http/tests/inspector-protocol/service-worker/intercept-css-enable-fetch.js new file mode 100644 index 0000000..a697d42 --- /dev/null +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/service-worker/intercept-css-enable-fetch.js
@@ -0,0 +1,30 @@ +(async function(testRunner) { + var {page, session, dp} = await testRunner.startURL( + 'resources/repeat-fetch-service-worker.html', + 'Verifies that service workers do not throw errors from devtools css enable initiated fetch.'); + + dp.ServiceWorker.onWorkerErrorReported(error => { + testRunner.log( + 'serivce worker reported error: ' + JSON.stringify(error, null, 2)); + testRunner.completeTest(); + }); + + await dp.Runtime.enable(); + await dp.ServiceWorker.enable(); + + let versions; + do { + const result = await dp.ServiceWorker.onceWorkerVersionUpdated(); + versions = result.params.versions; + } while (!versions.length || versions[0].status !== 'activated'); + await versions[0].registrationId; + + await dp.Page.enable(); + await dp.Page.reload(); + + await dp.DOM.enable(); + await dp.CSS.enable(); + + testRunner.log('finished awaiting for css enable'); + testRunner.completeTest(); +});
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/service-worker/resources/repeat-fetch-service-worker.html b/third_party/blink/web_tests/http/tests/inspector-protocol/service-worker/resources/repeat-fetch-service-worker.html new file mode 100644 index 0000000..d3dbd5ff --- /dev/null +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/service-worker/resources/repeat-fetch-service-worker.html
@@ -0,0 +1,12 @@ +<!DOCTYPE html> +<html> +<head> +<title>webpage for repeat-fetch-service-worker.js</title> +<script> +function installSW() { + navigator.serviceWorker.register('repeat-fetch-service-worker.js'); +} +</script> +</head> +<body onload="installSW()"></body> +</html>
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/service-worker/resources/repeat-fetch-service-worker.js b/third_party/blink/web_tests/http/tests/inspector-protocol/service-worker/resources/repeat-fetch-service-worker.js new file mode 100644 index 0000000..b52e19b --- /dev/null +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/service-worker/resources/repeat-fetch-service-worker.js
@@ -0,0 +1,4 @@ +self.addEventListener('fetch', fetchEvent => { + console.log('service worker making fetch for url: ' + fetchEvent.request.url); + fetch(fetchEvent.request); +});
diff --git a/third_party/blink/web_tests/http/tests/origin_trials/webexposed/resources/weblocksapi-origin-trial-interfaces-serviceworker-disabled.js b/third_party/blink/web_tests/http/tests/origin_trials/webexposed/resources/weblocksapi-origin-trial-interfaces-serviceworker-disabled.js deleted file mode 100644 index fb931a76..0000000 --- a/third_party/blink/web_tests/http/tests/origin_trials/webexposed/resources/weblocksapi-origin-trial-interfaces-serviceworker-disabled.js +++ /dev/null
@@ -1,15 +0,0 @@ -importScripts('/resources/testharness.js', - '/resources/origin-trials-helper.js'); - -test(t => { - OriginTrialsHelper.check_interfaces_missing( - self, - ['LockManager', 'Lock']); -}, 'Web Locks API interfaces in Origin-Trial disabled worker.'); - -test(t => { - assert_false('locks' in self.navigator, - 'locks property does not exist on navigator'); -}, 'Web Locks API entry point in Origin-Trial disabled worker.'); - -done();
diff --git a/third_party/blink/web_tests/http/tests/origin_trials/webexposed/resources/weblocksapi-origin-trial-interfaces-serviceworker-enabled.php b/third_party/blink/web_tests/http/tests/origin_trials/webexposed/resources/weblocksapi-origin-trial-interfaces-serviceworker-enabled.php deleted file mode 100644 index 6fccca8e5..0000000 --- a/third_party/blink/web_tests/http/tests/origin_trials/webexposed/resources/weblocksapi-origin-trial-interfaces-serviceworker-enabled.php +++ /dev/null
@@ -1,21 +0,0 @@ -<?php -// Generate token with the command: -// generate_token.py http://127.0.0.1:8000 WebLocksAPI --expire-timestamp=2000000000 -header("Origin-Trial: Aq40kr/ZTqxmfeh35cvBQcwBrmiL7pSDR6PrUZaVC7xxGe3ff4fECD/TdP+w+Ic9cXZ1ek6N4kg6oR876PQd/QoAAABTeyJvcmlnaW4iOiAiaHR0cDovLzEyNy4wLjAuMTo4MDAwIiwgImZlYXR1cmUiOiAiV2ViTG9ja3NBUEkiLCAiZXhwaXJ5IjogMjAwMDAwMDAwMH0="); -header('Content-Type: application/javascript'); -?> -importScripts('/resources/testharness.js', - '/resources/origin-trials-helper.js'); - -test(t => { - OriginTrialsHelper.check_properties(this, - {'LockManager': ['request', 'query'], - 'Lock': ['name', 'mode'], - }); -}, 'Web Locks API interfaces and properties in Origin-Trial enabled serviceworker.'); - -test(t => { - assert_true('locks' in self.navigator, 'locks property exists on navigator'); -}, 'Web Locks API entry point in Origin-Trial enabled serviceworker.'); - -done();
diff --git a/third_party/blink/web_tests/http/tests/origin_trials/webexposed/resources/weblocksapi-origin-trial-interfaces-worker.js b/third_party/blink/web_tests/http/tests/origin_trials/webexposed/resources/weblocksapi-origin-trial-interfaces-worker.js deleted file mode 100644 index 69b1248..0000000 --- a/third_party/blink/web_tests/http/tests/origin_trials/webexposed/resources/weblocksapi-origin-trial-interfaces-worker.js +++ /dev/null
@@ -1,15 +0,0 @@ -importScripts('/resources/testharness.js', - '/resources/origin-trials-helper.js'); - -test(t => { - OriginTrialsHelper.check_properties(this, - {'LockManager': ['request', 'query'], - 'Lock': ['name', 'mode'], - }); -}, 'Web Locks API interfaces and properties in Origin-Trial enabled worker.'); - -test(t => { - assert_true('locks' in self.navigator, 'locks property exists on navigator'); -}, 'Web Locks API entry point in Origin-Trial enabled worker.'); - -done();
diff --git a/third_party/blink/web_tests/http/tests/origin_trials/webexposed/weblocksapi-origin-trial-interfaces.html b/third_party/blink/web_tests/http/tests/origin_trials/webexposed/weblocksapi-origin-trial-interfaces.html deleted file mode 100644 index e4a5472..0000000 --- a/third_party/blink/web_tests/http/tests/origin_trials/webexposed/weblocksapi-origin-trial-interfaces.html +++ /dev/null
@@ -1,33 +0,0 @@ -<!DOCTYPE html> -<meta charset="utf-8"> -<!-- Generate token with the command: -generate_token.py http://127.0.0.1:8000 WebLocksAPI --expire-timestamp=2000000000 --- --> -<meta http-equiv="origin-trial" content="Aq40kr/ZTqxmfeh35cvBQcwBrmiL7pSDR6PrUZaVC7xxGe3ff4fECD/TdP+w+Ic9cXZ1ek6N4kg6oR876PQd/QoAAABTeyJvcmlnaW4iOiAiaHR0cDovLzEyNy4wLjAuMTo4MDAwIiwgImZlYXR1cmUiOiAiV2ViTG9ja3NBUEkiLCAiZXhwaXJ5IjogMjAwMDAwMDAwMH0=" /> -<title>Web Locks API - interfaces exposed by origin trial</title> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="/resources/origin-trials-helper.js"></script> -<script src="/serviceworker/resources/test-helpers.js"></script> -<script> -test(t => { - OriginTrialsHelper.check_properties(this, - {'LockManager': ['request', 'query'], - 'Lock': ['name', 'mode'], - }); -}, 'Web Locks API interfaces and properties in Origin-Trial enabled document.'); - -test(t => { - assert_true('locks' in self.navigator, 'locks property exists on navigator'); -}, 'Web Locks API entry point in Origin-Trial enabled document.'); - -fetch_tests_from_worker(new Worker('resources/weblocksapi-origin-trial-interfaces-worker.js')); - -// Only run "disabled" tests if the feature is not enabled via runtime flags. -if (!self.internals.runtimeFlags.webLocksAPIEnabled) { - service_worker_test('resources/weblocksapi-origin-trial-interfaces-serviceworker-disabled.js'); -} - -service_worker_test('resources/weblocksapi-origin-trial-interfaces-serviceworker-enabled.php'); - -</script>
diff --git a/third_party/blink/web_tests/platform/android/fast/events/simulated-click-on-anchor-with-target-blank-expected.txt b/third_party/blink/web_tests/platform/android/fast/events/simulated-click-on-anchor-with-target-blank-expected.txt index 110fc46a..f7065a5 100644 --- a/third_party/blink/web_tests/platform/android/fast/events/simulated-click-on-anchor-with-target-blank-expected.txt +++ b/third_party/blink/web_tests/platform/android/fast/events/simulated-click-on-anchor-with-target-blank-expected.txt
@@ -1,4 +1,4 @@ -Default policy for navigation to 'http://127.0.0.1:8000/LayoutTests/fast/events/blank' is 'new background tab' +Default policy for navigation to 'http://127.0.0.1:8000/web_tests/fast/events/blank' is 'new background tab' Tests that hitting ctrl-enter on a link with target=_blank still opens it in the background link
diff --git a/third_party/blink/web_tests/platform/fuchsia/fast/events/simulated-click-on-anchor-with-target-blank-expected.txt b/third_party/blink/web_tests/platform/fuchsia/fast/events/simulated-click-on-anchor-with-target-blank-expected.txt index 110fc46a..f7065a5 100644 --- a/third_party/blink/web_tests/platform/fuchsia/fast/events/simulated-click-on-anchor-with-target-blank-expected.txt +++ b/third_party/blink/web_tests/platform/fuchsia/fast/events/simulated-click-on-anchor-with-target-blank-expected.txt
@@ -1,4 +1,4 @@ -Default policy for navigation to 'http://127.0.0.1:8000/LayoutTests/fast/events/blank' is 'new background tab' +Default policy for navigation to 'http://127.0.0.1:8000/web_tests/fast/events/blank' is 'new background tab' Tests that hitting ctrl-enter on a link with target=_blank still opens it in the background link
diff --git a/third_party/blink/web_tests/virtual/stable/webexposed/storage-estimate-usage-details-expected.txt b/third_party/blink/web_tests/virtual/stable/webexposed/storage-estimate-usage-details-expected.txt new file mode 100644 index 0000000..3a3ee7ce --- /dev/null +++ b/third_party/blink/web_tests/virtual/stable/webexposed/storage-estimate-usage-details-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL usageDetails should be exposed by navigator.storage.estimate(). assert_true: expected true got false +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/webexposed/storage-estimate-usage-details.html b/third_party/blink/web_tests/webexposed/storage-estimate-usage-details.html new file mode 100644 index 0000000..9fdcdbbe --- /dev/null +++ b/third_party/blink/web_tests/webexposed/storage-estimate-usage-details.html
@@ -0,0 +1,9 @@ +<!doctype html> +<script src="../resources/testharness.js"></script> +<script src="../resources/testharnessreport.js"></script> +<script> +promise_test(async function() { + const estimate = await navigator.storage.estimate(); + assert_true('usageDetails' in estimate); +}, 'usageDetails should be exposed by navigator.storage.estimate().'); +</script>
diff --git a/third_party/ced/compact_enc_det_fuzzer.cc b/third_party/ced/compact_enc_det_fuzzer.cc index b0a73f2..9230b00 100644 --- a/third_party/ced/compact_enc_det_fuzzer.cc +++ b/third_party/ced/compact_enc_det_fuzzer.cc
@@ -21,11 +21,12 @@ CompactEncDet::TextCorpusType corpus = static_cast<CompactEncDet::TextCorpusType>( - data_provider.ConsumeInt32InRange(0, CompactEncDet::NUM_CORPA)); + data_provider.ConsumeIntegralInRange<int32_t>( + 0, CompactEncDet::NUM_CORPA)); Encoding encoding_hint = static_cast<Encoding>( - data_provider.ConsumeInt32InRange(0, NUM_ENCODINGS)); + data_provider.ConsumeIntegralInRange<int32_t>(0, NUM_ENCODINGS)); Language langauge_hint = static_cast<Language>( - data_provider.ConsumeInt32InRange(0, NUM_LANGUAGES)); + data_provider.ConsumeIntegralInRange<int32_t>(0, NUM_LANGUAGES)); bool ignore_7bit_mail_encodings = data_provider.ConsumeBool(); std::vector<char> text = data_provider.ConsumeRemainingBytes<char>();
diff --git a/third_party/gvr-android-sdk/test-apks/daydream_home/apk_version_history.txt b/third_party/gvr-android-sdk/test-apks/daydream_home/apk_version_history.txt index 0671774..a4b42cda 100644 --- a/third_party/gvr-android-sdk/test-apks/daydream_home/apk_version_history.txt +++ b/third_party/gvr-android-sdk/test-apks/daydream_home/apk_version_history.txt
@@ -15,3 +15,4 @@ v1.15 d56e9ff51188bab2bc9c843aae60bd15b2fcbb96 v1.16 a19b7e8feaa32a9d5e37de53414e8951e2b87ce7 v1.17 686bbb327b689972721953121295becb4f5389c6 +v1.19 53d6c9f8cd18d6b48f1b62884d019914f453dfb3
diff --git a/third_party/gvr-android-sdk/test-apks/daydream_home/daydream_home_current.apk.sha1 b/third_party/gvr-android-sdk/test-apks/daydream_home/daydream_home_current.apk.sha1 index 94bda82..4bbe003b 100644 --- a/third_party/gvr-android-sdk/test-apks/daydream_home/daydream_home_current.apk.sha1 +++ b/third_party/gvr-android-sdk/test-apks/daydream_home/daydream_home_current.apk.sha1
@@ -1 +1 @@ -686bbb327b689972721953121295becb4f5389c6 \ No newline at end of file +53d6c9f8cd18d6b48f1b62884d019914f453dfb3 \ No newline at end of file
diff --git a/third_party/gvr-android-sdk/test-apks/vr_services/apk_version_history.txt b/third_party/gvr-android-sdk/test-apks/vr_services/apk_version_history.txt index 98b252f1..124affd7 100644 --- a/third_party/gvr-android-sdk/test-apks/vr_services/apk_version_history.txt +++ b/third_party/gvr-android-sdk/test-apks/vr_services/apk_version_history.txt
@@ -19,3 +19,4 @@ v1.15 712140d07ac97444cf9d1407b2bafd497e7df1fa v1.16 96b849029526f7d980fe66e40ee0c5641774f897 v1.17 a8554dcd83afd1d9718bc7d341c82f3ffba2efbb +v1.19 7378cd3efa4386491df7b010b070470f936f2e9e
diff --git a/third_party/gvr-android-sdk/test-apks/vr_services/vr_services_current.apk.sha1 b/third_party/gvr-android-sdk/test-apks/vr_services/vr_services_current.apk.sha1 index b44a169..b86450f2 100644 --- a/third_party/gvr-android-sdk/test-apks/vr_services/vr_services_current.apk.sha1 +++ b/third_party/gvr-android-sdk/test-apks/vr_services/vr_services_current.apk.sha1
@@ -1 +1 @@ -a8554dcd83afd1d9718bc7d341c82f3ffba2efbb \ No newline at end of file +7378cd3efa4386491df7b010b070470f936f2e9e \ No newline at end of file
diff --git a/third_party/sfntly/fuzzers/subset_font_fuzzer.cc b/third_party/sfntly/fuzzers/subset_font_fuzzer.cc index 9bbe491..f434676 100644 --- a/third_party/sfntly/fuzzers/subset_font_fuzzer.cc +++ b/third_party/sfntly/fuzzers/subset_font_fuzzer.cc
@@ -16,10 +16,11 @@ constexpr int kMaxFontSize = 50 * 1024 * 1024; base::FuzzedDataProvider fuzzed_data(data, size); - size_t font_name_size = fuzzed_data.ConsumeUint32InRange(0, kMaxFontNameSize); + size_t font_name_size = + fuzzed_data.ConsumeIntegralInRange(0, kMaxFontNameSize); std::string font_name = fuzzed_data.ConsumeBytesAsString(font_name_size); - size_t font_str_size = fuzzed_data.ConsumeUint32InRange(0, kMaxFontSize); + size_t font_str_size = fuzzed_data.ConsumeIntegralInRange(0, kMaxFontSize); std::vector<unsigned char> font_str = fuzzed_data.ConsumeBytes<unsigned char>(font_str_size);
diff --git a/third_party/webdriver/README.chromium b/third_party/webdriver/README.chromium index 839fd44..17d67f4 100644 --- a/third_party/webdriver/README.chromium +++ b/third_party/webdriver/README.chromium
@@ -18,7 +18,7 @@ atoms.h, atoms.cc These atoms are generated by the webdriver team and are to be checked in manually. The current version was generated from revision - a3444b8f4dbb6e83b8710455e6d8352439ac1874. + 53f0818fe574877841c331e9647a35985fbfe957. To generate the atoms using the code found in selenium tree: $ git clone https://github.com/SeleniumHQ/selenium.git
diff --git a/third_party/webdriver/atoms.cc b/third_party/webdriver/atoms.cc index 6a8e9fc..ad0da6d 100644 --- a/third_party/webdriver/atoms.cc +++ b/third_party/webdriver/atoms.cc
@@ -689,17 +689,17 @@ "f]),c=Math.min(c,a[f+1]),e=Math.max(e,a[f+1]);return new U(b,c,d-b,e-c)", "}return new U(0,0,0,0)}function yc(a){a=tc(a);return new hc(a.top,a.lef", "t+a.width,a.top+a.height,a.left)}\nfunction wc(a){var b=1,c=W(a,\"opaci", - "ty\");c&&(b=Number(c));(a=qc(a))&&(b*=wc(a));return b};function Ac(){th", - "is.N=ka.document.documentElement;var a=Wa(x(this.N));a&&Bc(this,a)}func", - "tion Bc(a,b){a.N=b;A(b,\"OPTION\")&&Va(b,function(a){return A(a,\"SELEC", - "T\")})}function Cc(a){var b=Va(a.N,function(a){return!!a&&A(a)&&kc(a)},", - "!0),b=b||a.N;a=Wa(x(b));if(b!=a){if(a&&ea(a.blur)&&!A(a,\"BODY\"))try{a", - ".blur()}catch(c){throw c;}ea(b.focus)&&b.focus()}};Ma();Ma();function D", - "c(a,b,c){this.B=a;this.pa=b;this.qa=c}Dc.prototype.create=function(a){a", - "=x(a).createEvent(\"HTMLEvents\");a.initEvent(this.B,this.pa,this.qa);r", - "eturn a};Dc.prototype.toString=function(){return this.B};var Ec=new Dc(", - "\"blur\",!1,!1),Fc=new Dc(\"change\",!0,!1);function Gc(a,b){b=b.create", - "(a,void 0);\"isTrusted\"in b||(b.isTrusted=!1);a.dispatchEvent(b)};func", + "ty\");c&&(b=Number(c));(a=qc(a))&&(b*=wc(a));return b};Ma();Ma();functi", + "on Ac(a,b,c){this.B=a;this.pa=b;this.qa=c}Ac.prototype.create=function(", + "a){a=x(a).createEvent(\"HTMLEvents\");a.initEvent(this.B,this.pa,this.q", + "a);return a};Ac.prototype.toString=function(){return this.B};var Bc=new", + " Ac(\"blur\",!1,!1),Cc=new Ac(\"change\",!0,!1);function Dc(a,b){b=b.cr", + "eate(a,void 0);\"isTrusted\"in b||(b.isTrusted=!1);a.dispatchEvent(b)};", + "function Ec(){this.N=ka.document.documentElement;var a=Wa(x(this.N));a&", + "&Fc(this,a)}function Fc(a,b){a.N=b;A(b,\"OPTION\")&&Va(b,function(a){re", + "turn A(a,\"SELECT\")})}function Gc(a){var b=Va(a.N,function(a){return!!", + "a&&A(a)&&kc(a)},!0),b=b||a.N;a=Wa(x(b));if(b!=a){if(a&&ea(a.blur)&&!A(a", + ",\"BODY\"))try{a.blur()}catch(c){throw c;}ea(b.focus)&&b.focus()}};func", "tion Hc(a,b){this.w={};this.g=[];this.G=0;var c=arguments.length;if(1<c", "){if(c%2)throw Error(\"Uneven number of arguments\");for(var d=0;d<c;d+", "=2)this.set(arguments[d],arguments[d+1])}else a&&this.addAll(a)}functio", @@ -746,13 +746,13 @@ "\\\\\",\"|\");Y(221,\"]\",\"}\");Y({c:59,b:186},\";\",\":\");Y(222,\"'", "\",'\"');var Qc=new Hc;Qc.set(1,Mc);Qc.set(2,Nc);Qc.set(4,Oc);Qc.set(8,", "Pc);(function(a){var b=new Hc;q(Ic(a),function(c){b.set(a.get(c).code,c", - ")});return b})(Qc);function Z(){Ac.call(this)}p(Z,Ac);Z.W=void 0;Z.ra=f", - "unction(){return Z.W?Z.W:Z.W=new Z};function Rc(a){var b=Z.ra();Bc(b,a)", - ";Cc(b)};ba(\"_\",function(a){if(!xc(a)||!nc(a)||\"none\"==W(a,\"pointer", + ")});return b})(Qc);function Z(){Ec.call(this)}p(Z,Ec);Z.W=void 0;Z.ra=f", + "unction(){return Z.W?Z.W:Z.W=new Z};function Rc(a){var b=Z.ra();Fc(b,a)", + ";Gc(b)};ba(\"_\",function(a){if(!xc(a)||!nc(a)||\"none\"==W(a,\"pointer", "-events\"))throw new u(12,\"Element is not currently interactable and m", "ay not be manipulated\");if(!lc(a))throw new u(12,\"Element must be use", - "r-editable in order to clear it.\");if(a.value){Rc(a);a.value=\"\";Gc(a", - ",Fc);Gc(a,Ec);var b=ka.document.body;if(b)Rc(b);else throw new u(13,\"C", + "r-editable in order to clear it.\");if(a.value){Rc(a);a.value=\"\";Dc(a", + ",Cc);Dc(a,Bc);var b=ka.document.body;if(b)Rc(b);else throw new u(13,\"C", "annot unfocus element after clearing.\");}else A(a,\"INPUT\")&&a.getAtt", "ribute(\"type\")&&\"number\"==a.getAttribute(\"type\").toLowerCase()&&(", "Rc(a),a.value=\"\");pc(a)&&(Rc(a),a.innerHTML=\n\" \")});; return this.", @@ -1447,158 +1447,158 @@ ",a.top),a.bottom),a.right=Math.min(Math.max(a.left+b.width,a.left),a.ri", "ght),a.bottom=Math.min(Math.max(a.top+b.height,a.top),a.bottom));return", " a}function Ic(a){var b=1,c=T(a,\"opacity\");c&&(b=Number(c));(a=Cc(a))", - "&&(b*=Ic(a));return b};function Lc(a,b){this.g=ka.document.documentElem", - "ent;this.G=null;var c=ab(A(this.g));c&&Mc(this,c);this.$=a||new Nc;this", - ".pa=b||new Oc}Lc.prototype.I=function(){return this.g};function Mc(a,b)", - "{a.g=b;a.G=B(b,\"OPTION\")?$a(b,function(a){return B(a,\"SELECT\")}):nu", - "ll}\nLc.prototype.W=function(a,b,c,d,e,f,h,l){if(!f&&!tc(this.g))return", - "!1;if(d&&Pc!=a&&Qc!=a)throw new u(12,\"Event type does not allow relate", - "d target: \"+a);b={clientX:b.x,clientY:b.y,button:c,altKey:0!=(this.$.c", - "a&4),ctrlKey:0!=(this.$.ca&2),shiftKey:0!=(this.$.ca&1),metaKey:0!=(thi", - "s.$.ca&8),wheelDelta:e||0,relatedTarget:d||null,count:l||1};h=h||1;c=th", - "is.g;a!=Rc&&a!=Sc&&h in Tc?c=Tc[h]:this.G&&(c=Uc(this,a));return c?this", - ".pa.W(c,a,b):!0};\nLc.prototype.S=function(a,b,c,d,e,f,h,l){if(!l&&!tc(", - "this.g))return!1;if(h&&Vc!=a&&Wc!=a)throw new u(12,\"Event type does no", - "t allow related target: \"+a);b={clientX:b.x,clientY:b.y,button:c,altKe", - "y:!1,ctrlKey:!1,shiftKey:!1,metaKey:!1,relatedTarget:h||null,width:0,he", - "ight:0,pressure:0,rotation:0,pointerId:d,tiltX:0,tiltY:0,pointerType:e,", - "isPrimary:f};c=this.G?Uc(this,a):this.g;Tc[d]&&(c=Tc[d]);d=Sa(A(this.g)", - ");if(d&&a==Xc){var q=d.Element.prototype.msSetPointerCapture;d.Element.", - "prototype.msSetPointerCapture=\nfunction(a){Tc[a]=this}}a=c?this.pa.S(c", - ",a,b):!0;q&&(d.Element.prototype.msSetPointerCapture=q);return a};funct", - "ion Uc(a,b){switch(b){case Rc:case Yc:return a.G.multiple?a.g:a.G;defau", - "lt:return a.G.multiple?a.g:null}}function Zc(a){var b=$a(a.g,function(a", - "){return!!a&&B(a)&&xc(a)},!0),b=b||a.g;a=ab(A(b));if(b!=a){if(a&&ea(a.b", - "lur)&&!B(a,\"BODY\"))try{a.blur()}catch(c){throw c;}ea(b.focus)&&b.focu", - "s()}}function Nc(){this.ca=0}var Tc={};function Oc(){}Oc.prototype.W=fu", - "nction(a,b,c){return $c(a,b,c)};\nOc.prototype.S=function(a,b,c){return", - " $c(a,b,c)};Na();Na();function ad(a,b,c){this.B=a;this.la=b;this.ma=c}a", - "d.prototype.create=function(a){a=A(a).createEvent(\"HTMLEvents\");a.ini", - "tEvent(this.B,this.la,this.ma);return a};ad.prototype.toString=function", - "(){return this.B};function W(a,b,c){ad.call(this,a,b,c)}p(W,ad);\nW.pro", - "totype.create=function(a,b){if(this==bd)throw new u(9,\"Browser does no", - "t support a mouse pixel scroll event.\");var c=A(a);a=Sa(c);c=c.createE", - "vent(\"MouseEvents\");this==cd&&(c.wheelDelta=b.wheelDelta);c.initMouse", - "Event(this.B,this.la,this.ma,a,1,b.clientX,b.clientY,b.clientX,b.client", - "Y,b.ctrlKey,b.altKey,b.shiftKey,b.metaKey,b.button,b.relatedTarget);ret", - "urn c};function X(a,b,c){ad.call(this,a,b,c)}p(X,ad);X.prototype.create", - "=function(){throw new u(9,\"Browser does not support MSPointer events.", - "\");};\nvar dd=new ad(\"change\",!0,!1),Rc=new W(\"click\",!0,!0),ed=ne", - "w W(\"contextmenu\",!0,!0),fd=new W(\"dblclick\",!0,!0),Sc=new W(\"mous", - "edown\",!0,!0),gd=new W(\"mousemove\",!0,!1),Qc=new W(\"mouseout\",!0,!", - "0),Pc=new W(\"mouseover\",!0,!0),Yc=new W(\"mouseup\",!0,!0),cd=new W(", - "\"mousewheel\",!0,!0),bd=new W(\"MozMousePixelScroll\",!0,!0),hd=new X(", - "\"MSGotPointerCapture\",!0,!1),id=new X(\"MSLostPointerCapture\",!0,!1)", - ",Xc=new X(\"MSPointerDown\",!0,!0),jd=new X(\"MSPointerMove\",!0,!0),Vc", - "=new X(\"MSPointerOver\",!0,!0),Wc=new X(\"MSPointerOut\",\n!0,!0),kd=n", - "ew X(\"MSPointerUp\",!0,!0);function $c(a,b,c){b=b.create(a,c);\"isTrus", - "ted\"in b||(b.isTrusted=!1);return a.dispatchEvent(b)};function ld(a,b)", - "{this.D={};this.h=[];this.M=0;var c=arguments.length;if(1<c){if(c%2)thr", - "ow Error(\"Uneven number of arguments\");for(var d=0;d<c;d+=2)this.set(", - "arguments[d],arguments[d+1])}else a&&this.addAll(a)}function md(a){nd(a", - ");return a.h.concat()}g=ld.prototype;g.clear=function(){this.D={};this.", - "M=this.h.length=0};g.remove=function(a){return Object.prototype.hasOwnP", - "roperty.call(this.D,a)?(delete this.D[a],this.M--,this.h.length>2*this.", - "M&&nd(this),!0):!1};\nfunction nd(a){var b,c;if(a.M!=a.h.length){for(b=", - "c=0;c<a.h.length;){var d=a.h[c];Object.prototype.hasOwnProperty.call(a.", - "D,d)&&(a.h[b++]=d);c++}a.h.length=b}if(a.M!=a.h.length){var e={};for(b=", - "c=0;c<a.h.length;)d=a.h[c],Object.prototype.hasOwnProperty.call(e,d)||(", - "a.h[b++]=d,e[d]=1),c++;a.h.length=b}}g.get=function(a,b){return Object.", - "prototype.hasOwnProperty.call(this.D,a)?this.D[a]:b};g.set=function(a,b", - "){Object.prototype.hasOwnProperty.call(this.D,a)||(this.M++,this.h.push", - "(a));this.D[a]=b};\ng.addAll=function(a){if(a instanceof ld){var b=md(a", - ");nd(a);for(var c=[],d=0;d<a.h.length;d++)c.push(a.D[a.h[d]]);a=c}else{", - "b=[];var d=0;for(e in a)b[d++]=e;d=[];var e=0;for(c in a)d[e++]=a[c];a=", - "d}for(c=0;c<b.length;c++)this.set(b[c],a[c])};g.forEach=function(a,b){f", - "or(var c=md(this),d=0;d<c.length;d++){var e=c[d],f=this.get(e);a.call(b", - ",f,e,this)}};g.clone=function(){return new ld(this)};var od={};function", - " Y(a,b,c){fa(a)&&(a=a.b);a=new pd(a);!b||b in od&&!c||(od[b]={key:a,shi", - "ft:!1},c&&(od[c]={key:a,shift:!0}));return a}function pd(a){this.code=a", - "}Y(8);Y(9);Y(13);var qd=Y(16),rd=Y(17),sd=Y(18);Y(19);Y(20);Y(27);Y(32,", - "\" \");Y(33);Y(34);Y(35);Y(36);Y(37);Y(38);Y(39);Y(40);Y(44);Y(45);Y(46", - ");Y(48,\"0\",\")\");Y(49,\"1\",\"!\");Y(50,\"2\",\"@\");Y(51,\"3\",\"#", - "\");Y(52,\"4\",\"$\");Y(53,\"5\",\"%\");Y(54,\"6\",\"^\");Y(55,\"7\",\"", - "&\");Y(56,\"8\",\"*\");Y(57,\"9\",\"(\");Y(65,\"a\",\"A\");Y(66,\"b\",", - "\"B\");Y(67,\"c\",\"C\");Y(68,\"d\",\"D\");\nY(69,\"e\",\"E\");Y(70,\"f", - "\",\"F\");Y(71,\"g\",\"G\");Y(72,\"h\",\"H\");Y(73,\"i\",\"I\");Y(74,\"", - "j\",\"J\");Y(75,\"k\",\"K\");Y(76,\"l\",\"L\");Y(77,\"m\",\"M\");Y(78,", - "\"n\",\"N\");Y(79,\"o\",\"O\");Y(80,\"p\",\"P\");Y(81,\"q\",\"Q\");Y(82", - ",\"r\",\"R\");Y(83,\"s\",\"S\");Y(84,\"t\",\"T\");Y(85,\"u\",\"U\");Y(8", - "6,\"v\",\"V\");Y(87,\"w\",\"W\");Y(88,\"x\",\"X\");Y(89,\"y\",\"Y\");Y(", - "90,\"z\",\"Z\");var td=Y(Ja?{c:91,b:91}:Ia?{c:224,b:91}:{c:0,b:91});Y(J", - "a?{c:92,b:92}:Ia?{c:224,b:93}:{c:0,b:92});Y(Ja?{c:93,b:93}:Ia?{c:0,b:0}", - ":{c:93,b:null});Y({c:96,b:96},\"0\");Y({c:97,b:97},\"1\");\nY({c:98,b:9", - "8},\"2\");Y({c:99,b:99},\"3\");Y({c:100,b:100},\"4\");Y({c:101,b:101},", - "\"5\");Y({c:102,b:102},\"6\");Y({c:103,b:103},\"7\");Y({c:104,b:104},\"", - "8\");Y({c:105,b:105},\"9\");Y({c:106,b:106},\"*\");Y({c:107,b:107},\"+", - "\");Y({c:109,b:109},\"-\");Y({c:110,b:110},\".\");Y({c:111,b:111},\"/\"", - ");Y(144);Y(112);Y(113);Y(114);Y(115);Y(116);Y(117);Y(118);Y(119);Y(120)", - ";Y(121);Y(122);Y(123);Y({c:107,b:187},\"=\",\"+\");Y(108,\",\");Y({c:10", - "9,b:189},\"-\",\"_\");Y(188,\",\",\"<\");Y(190,\".\",\">\");Y(191,\"/\"", - ",\"?\");Y(192,\"`\",\"~\");Y(219,\"[\",\"{\");\nY(220,\"\\\\\",\"|\");Y", - "(221,\"]\",\"}\");Y({c:59,b:186},\";\",\":\");Y(222,\"'\",'\"');var ud=", - "new ld;ud.set(1,qd);ud.set(2,rd);ud.set(4,sd);ud.set(8,td);(function(a)", - "{var b=new ld;t(md(a),function(c){b.set(a.get(c).code,c)});return b})(u", - "d);function vd(a,b,c){Lc.call(this,b,c);this.K=this.j=null;this.C=new z", - "(0,0);this.Y=this.N=!1;if(a){n(a.buttonPressed)&&(this.j=a.buttonPresse", - "d);try{B(a.elementPressed)&&(this.K=a.elementPressed)}catch(d){this.j=n", - "ull}this.C=new z(a.clientXY.x,a.clientXY.y);this.N=!!a.nextClickIsDoubl", - "eClick;this.Y=!!a.hasEverInteracted;try{a.element&&B(a.element)&&Mc(thi", - "s,a.element)}catch(d){this.j=null}}}p(vd,Lc);var Z={};Z[Rc]=[0,1,2,null", - "];Z[ed]=[null,null,2,null];Z[Yc]=[0,1,2,null];Z[Qc]=[0,1,2,4];Z[gd]=[0,", - "1,2,4];\nQa&&(Z[Xc]=Z[Yc],Z[kd]=Z[Yc],Z[jd]=[-1,-1,-1,-1],Z[Wc]=Z[jd],Z", - "[Vc]=Z[jd]);Z[fd]=Z[Rc];Z[Sc]=Z[Yc];Z[Pc]=Z[Qc];var wd={};wd[Sc]=Xc;wd[", - "gd]=jd;wd[Qc]=Wc;wd[Pc]=Vc;wd[Yc]=kd;vd.prototype.move=function(a,b){va", - "r c=tc(a),d=Fc(a);this.C.x=b.x+d.left;this.C.y=b.y+d.top;b=this.I();if(", - "a!=b){try{Sa(A(b)).closed&&(b=null)}catch(e){b=null}b&&(d=b===ka.docume", - "nt.documentElement||b===ka.document.body,b=!this.Y&&d?null:b,xd(this,Qc", - ",a));Mc(this,a);xd(this,Pc,b,null,c)}xd(this,gd,null,null,c);this.N=!1}", - ";\nvd.prototype.scroll=function(a){if(0==a)throw new u(13,\"Must scroll", - " a non-zero number of ticks.\");for(var b=0<a?-120:120,c=0;c<Math.abs(a", - ");c++)xd(this,cd,null,b)};function xd(a,b,c,d,e,f){a.Y=!0;if(Qa){var h=", - "wd[b];if(h&&!a.S(h,a.C,yd(a,h),1,MSPointerEvent.MSPOINTER_TYPE_MOUSE,!0", - ",c,e))return!1}return a.W(b,a.C,yd(a,b),c,d,e,null,f)}function yd(a,b){", - "if(!(b in Z))return 0;a=Z[b][null===a.j?3:a.j];if(null===a)throw new u(", - "13,\"Event does not permit the specified mouse button.\");return a}\nvd", - ".prototype.getState=function(){return{buttonPressed:this.j,elementPress", - "ed:this.K,clientXY:{x:this.C.x,y:this.C.y},nextClickIsDoubleClick:this.", - "N,hasEverInteracted:this.Y,element:this.I()}};function zd(a,b){this.x=a", - ";this.y=b}p(zd,z);g=zd.prototype;g.clone=function(){return new zd(this.", - "x,this.y)};g.scale=z.prototype.scale;g.normalize=function(){return this", - ".scale(1/Math.sqrt(this.x*this.x+this.y*this.y))};g.add=function(a){thi", - "s.x+=a.x;this.y+=a.y;return this};g.rotate=function(a){var b=Math.cos(a", - ");a=Math.sin(a);var c=this.y*b+this.x*a;this.x=this.x*b-this.y*a;this.y", - "=c;return this};function Ad(a){var b;(b=qc(a,\"display\"))||(b=a.curren", - "tStyle?a.currentStyle.display:null);if(\"none\"!=(b||a.style&&a.style.d", - "isplay))b=rc(a);else{b=a.style;var c=b.display,d=b.visibility,e=b.posit", - "ion;b.visibility=\"hidden\";b.position=\"absolute\";b.display=\"inline", - "\";var f=rc(a);b.display=c;b.position=e;b.visibility=d;b=f}return 0<b.w", - "idth&&0<b.height||!a.offsetParent?b:Ad(a.offsetParent)};ba(\"_\",functi", - "on(a,b,c,d){if(!uc(a))throw new u(11,\"Element is not currently visible", - " and may not be manipulated\");b:{var e=b||void 0;if(\"scroll\"==Gc(a,e", - ")){if(a.scrollIntoView&&(a.scrollIntoView(),\"none\"==Gc(a,e)))break b;", - "for(var f=Jc(a,e),h=Cc(a);h;h=Cc(h)){var l=h,q=Fc(l);var y=l;var r=qc(y", - ",\"borderLeftWidth\");var v=qc(y,\"borderRightWidth\");var J=qc(y,\"bor", - "derTopWidth\");y=qc(y,\"borderBottomWidth\");v=new pc(parseFloat(J),par", - "seFloat(v),parseFloat(y),parseFloat(r));r=f.left-q.left-v.left;q=f.top-", - "q.top-\nv.top;v=l.clientHeight+f.top-f.bottom;l.scrollLeft+=Math.min(r,", - "Math.max(r-(l.clientWidth+f.left-f.right),0));l.scrollTop+=Math.min(q,M", - "ath.max(q-v,0))}Gc(a,e)}}b?b=new zd(b.x,b.y):(b=Ad(a),b=new zd(b.width/", - "2,b.height/2));c=c||new vd;c.move(a,b);if(null!==c.j)throw new u(13,\"C", - "annot press more than one button or an already pressed button.\");c.j=0", - ";c.K=c.I();if(B(c.I(),\"OPTION\")||B(c.I(),\"SELECT\")||xd(c,Sc,null,nu", - "ll,!1,void 0))Qa&&0==c.j&&B(c.K,\"OPTION\")&&c.S(hd,c.C,0,1,MSPointerEv", - "ent.MSPOINTER_TYPE_MOUSE,\n!0),Zc(c);if(null===c.j)throw new u(13,\"Can", - "not release a button when no button is pressed.\");c.G&&tc(c.g)&&(a=c.G", - ",b=gb(c.g),!b||a.multiple)&&(c.g.selected=!b,a.multiple&&!(0<=na(Pa,28)", - ")||$c(a,dd));a=tc(c.I());xd(c,Yc,null,null,d,void 0);try{if(0==c.j&&c.I", - "()==c.K){var U=c.C,ma=yd(c,Rc);if(a||tc(c.g))!c.G&&fb(c.g)&&gb(c.g),c.W", - "(Rc,U,ma,null,0,a,void 0);c.N&&xd(c,fd);c.N=!c.N;Qa&&0==c.j&&B(c.K,\"OP", - "TION\")&&c.S(id,new z(0,0),0,1,MSPointerEvent.MSPOINTER_TYPE_MOUSE,!1)}", - "else 2==c.j&&xd(c,ed)}catch(Bd){}Tc=\n{};c.j=null;c.K=null});; return t", - "his._.apply(null,arguments);}.apply({navigator:typeof window!='undefine", - "d'?window.navigator:null,document:typeof window!='undefined'?window.doc", - "ument:null}, arguments);}", + "&&(b*=Ic(a));return b};Na();Na();function Lc(a,b,c){this.B=a;this.la=b;", + "this.ma=c}Lc.prototype.create=function(a){a=A(a).createEvent(\"HTMLEven", + "ts\");a.initEvent(this.B,this.la,this.ma);return a};Lc.prototype.toStri", + "ng=function(){return this.B};function W(a,b,c){Lc.call(this,a,b,c)}p(W,", + "Lc);\nW.prototype.create=function(a,b){if(this==Mc)throw new u(9,\"Brow", + "ser does not support a mouse pixel scroll event.\");var c=A(a);a=Sa(c);", + "c=c.createEvent(\"MouseEvents\");this==Nc&&(c.wheelDelta=b.wheelDelta);", + "c.initMouseEvent(this.B,this.la,this.ma,a,1,b.clientX,b.clientY,b.clien", + "tX,b.clientY,b.ctrlKey,b.altKey,b.shiftKey,b.metaKey,b.button,b.related", + "Target);return c};function X(a,b,c){Lc.call(this,a,b,c)}p(X,Lc);X.proto", + "type.create=function(){throw new u(9,\"Browser does not support MSPoint", + "er events.\");};\nvar Oc=new Lc(\"change\",!0,!1),Pc=new W(\"click\",!0", + ",!0),Qc=new W(\"contextmenu\",!0,!0),Rc=new W(\"dblclick\",!0,!0),Sc=ne", + "w W(\"mousedown\",!0,!0),Tc=new W(\"mousemove\",!0,!1),Uc=new W(\"mouse", + "out\",!0,!0),Vc=new W(\"mouseover\",!0,!0),Wc=new W(\"mouseup\",!0,!0),", + "Nc=new W(\"mousewheel\",!0,!0),Mc=new W(\"MozMousePixelScroll\",!0,!0),", + "Xc=new X(\"MSGotPointerCapture\",!0,!1),Yc=new X(\"MSLostPointerCapture", + "\",!0,!1),Zc=new X(\"MSPointerDown\",!0,!0),$c=new X(\"MSPointerMove\",", + "!0,!0),ad=new X(\"MSPointerOver\",!0,!0),bd=new X(\"MSPointerOut\",\n!0", + ",!0),cd=new X(\"MSPointerUp\",!0,!0);function dd(a,b,c){b=b.create(a,c)", + ";\"isTrusted\"in b||(b.isTrusted=!1);return a.dispatchEvent(b)};functio", + "n ed(a,b){this.g=ka.document.documentElement;this.G=null;var c=ab(A(thi", + "s.g));c&&fd(this,c);this.$=a||new gd;this.pa=b||new hd}ed.prototype.I=f", + "unction(){return this.g};function fd(a,b){a.g=b;a.G=B(b,\"OPTION\")?$a(", + "b,function(a){return B(a,\"SELECT\")}):null}\ned.prototype.W=function(a", + ",b,c,d,e,f,h,l){if(!f&&!tc(this.g))return!1;if(d&&Vc!=a&&Uc!=a)throw ne", + "w u(12,\"Event type does not allow related target: \"+a);b={clientX:b.x", + ",clientY:b.y,button:c,altKey:0!=(this.$.ca&4),ctrlKey:0!=(this.$.ca&2),", + "shiftKey:0!=(this.$.ca&1),metaKey:0!=(this.$.ca&8),wheelDelta:e||0,rela", + "tedTarget:d||null,count:l||1};h=h||1;c=this.g;a!=Pc&&a!=Sc&&h in id?c=i", + "d[h]:this.G&&(c=jd(this,a));return c?this.pa.W(c,a,b):!0};\ned.prototyp", + "e.S=function(a,b,c,d,e,f,h,l){if(!l&&!tc(this.g))return!1;if(h&&ad!=a&&", + "bd!=a)throw new u(12,\"Event type does not allow related target: \"+a);", + "b={clientX:b.x,clientY:b.y,button:c,altKey:!1,ctrlKey:!1,shiftKey:!1,me", + "taKey:!1,relatedTarget:h||null,width:0,height:0,pressure:0,rotation:0,p", + "ointerId:d,tiltX:0,tiltY:0,pointerType:e,isPrimary:f};c=this.G?jd(this,", + "a):this.g;id[d]&&(c=id[d]);d=Sa(A(this.g));if(d&&a==Zc){var q=d.Element", + ".prototype.msSetPointerCapture;d.Element.prototype.msSetPointerCapture=", + "\nfunction(a){id[a]=this}}a=c?this.pa.S(c,a,b):!0;q&&(d.Element.prototy", + "pe.msSetPointerCapture=q);return a};function jd(a,b){switch(b){case Pc:", + "case Wc:return a.G.multiple?a.g:a.G;default:return a.G.multiple?a.g:nul", + "l}}function kd(a){var b=$a(a.g,function(a){return!!a&&B(a)&&xc(a)},!0),", + "b=b||a.g;a=ab(A(b));if(b!=a){if(a&&ea(a.blur)&&!B(a,\"BODY\"))try{a.blu", + "r()}catch(c){throw c;}ea(b.focus)&&b.focus()}}function gd(){this.ca=0}v", + "ar id={};function hd(){}hd.prototype.W=function(a,b,c){return dd(a,b,c)", + "};\nhd.prototype.S=function(a,b,c){return dd(a,b,c)};function ld(a,b){t", + "his.D={};this.h=[];this.M=0;var c=arguments.length;if(1<c){if(c%2)throw", + " Error(\"Uneven number of arguments\");for(var d=0;d<c;d+=2)this.set(ar", + "guments[d],arguments[d+1])}else a&&this.addAll(a)}function md(a){nd(a);", + "return a.h.concat()}g=ld.prototype;g.clear=function(){this.D={};this.M=", + "this.h.length=0};g.remove=function(a){return Object.prototype.hasOwnPro", + "perty.call(this.D,a)?(delete this.D[a],this.M--,this.h.length>2*this.M&", + "&nd(this),!0):!1};\nfunction nd(a){var b,c;if(a.M!=a.h.length){for(b=c=", + "0;c<a.h.length;){var d=a.h[c];Object.prototype.hasOwnProperty.call(a.D,", + "d)&&(a.h[b++]=d);c++}a.h.length=b}if(a.M!=a.h.length){var e={};for(b=c=", + "0;c<a.h.length;)d=a.h[c],Object.prototype.hasOwnProperty.call(e,d)||(a.", + "h[b++]=d,e[d]=1),c++;a.h.length=b}}g.get=function(a,b){return Object.pr", + "ototype.hasOwnProperty.call(this.D,a)?this.D[a]:b};g.set=function(a,b){", + "Object.prototype.hasOwnProperty.call(this.D,a)||(this.M++,this.h.push(a", + "));this.D[a]=b};\ng.addAll=function(a){if(a instanceof ld){var b=md(a);", + "nd(a);for(var c=[],d=0;d<a.h.length;d++)c.push(a.D[a.h[d]]);a=c}else{b=", + "[];var d=0;for(e in a)b[d++]=e;d=[];var e=0;for(c in a)d[e++]=a[c];a=d}", + "for(c=0;c<b.length;c++)this.set(b[c],a[c])};g.forEach=function(a,b){for", + "(var c=md(this),d=0;d<c.length;d++){var e=c[d],f=this.get(e);a.call(b,f", + ",e,this)}};g.clone=function(){return new ld(this)};var od={};function Y", + "(a,b,c){fa(a)&&(a=a.b);a=new pd(a);!b||b in od&&!c||(od[b]={key:a,shift", + ":!1},c&&(od[c]={key:a,shift:!0}));return a}function pd(a){this.code=a}Y", + "(8);Y(9);Y(13);var qd=Y(16),rd=Y(17),sd=Y(18);Y(19);Y(20);Y(27);Y(32,\"", + " \");Y(33);Y(34);Y(35);Y(36);Y(37);Y(38);Y(39);Y(40);Y(44);Y(45);Y(46);", + "Y(48,\"0\",\")\");Y(49,\"1\",\"!\");Y(50,\"2\",\"@\");Y(51,\"3\",\"#\")", + ";Y(52,\"4\",\"$\");Y(53,\"5\",\"%\");Y(54,\"6\",\"^\");Y(55,\"7\",\"&\"", + ");Y(56,\"8\",\"*\");Y(57,\"9\",\"(\");Y(65,\"a\",\"A\");Y(66,\"b\",\"B", + "\");Y(67,\"c\",\"C\");Y(68,\"d\",\"D\");\nY(69,\"e\",\"E\");Y(70,\"f\",", + "\"F\");Y(71,\"g\",\"G\");Y(72,\"h\",\"H\");Y(73,\"i\",\"I\");Y(74,\"j\"", + ",\"J\");Y(75,\"k\",\"K\");Y(76,\"l\",\"L\");Y(77,\"m\",\"M\");Y(78,\"n", + "\",\"N\");Y(79,\"o\",\"O\");Y(80,\"p\",\"P\");Y(81,\"q\",\"Q\");Y(82,\"", + "r\",\"R\");Y(83,\"s\",\"S\");Y(84,\"t\",\"T\");Y(85,\"u\",\"U\");Y(86,", + "\"v\",\"V\");Y(87,\"w\",\"W\");Y(88,\"x\",\"X\");Y(89,\"y\",\"Y\");Y(90", + ",\"z\",\"Z\");var td=Y(Ja?{c:91,b:91}:Ia?{c:224,b:91}:{c:0,b:91});Y(Ja?", + "{c:92,b:92}:Ia?{c:224,b:93}:{c:0,b:92});Y(Ja?{c:93,b:93}:Ia?{c:0,b:0}:{", + "c:93,b:null});Y({c:96,b:96},\"0\");Y({c:97,b:97},\"1\");\nY({c:98,b:98}", + ",\"2\");Y({c:99,b:99},\"3\");Y({c:100,b:100},\"4\");Y({c:101,b:101},\"5", + "\");Y({c:102,b:102},\"6\");Y({c:103,b:103},\"7\");Y({c:104,b:104},\"8\"", + ");Y({c:105,b:105},\"9\");Y({c:106,b:106},\"*\");Y({c:107,b:107},\"+\");", + "Y({c:109,b:109},\"-\");Y({c:110,b:110},\".\");Y({c:111,b:111},\"/\");Y(", + "144);Y(112);Y(113);Y(114);Y(115);Y(116);Y(117);Y(118);Y(119);Y(120);Y(1", + "21);Y(122);Y(123);Y({c:107,b:187},\"=\",\"+\");Y(108,\",\");Y({c:109,b:", + "189},\"-\",\"_\");Y(188,\",\",\"<\");Y(190,\".\",\">\");Y(191,\"/\",\"?", + "\");Y(192,\"`\",\"~\");Y(219,\"[\",\"{\");\nY(220,\"\\\\\",\"|\");Y(221", + ",\"]\",\"}\");Y({c:59,b:186},\";\",\":\");Y(222,\"'\",'\"');var ud=new ", + "ld;ud.set(1,qd);ud.set(2,rd);ud.set(4,sd);ud.set(8,td);(function(a){var", + " b=new ld;t(md(a),function(c){b.set(a.get(c).code,c)});return b})(ud);f", + "unction vd(a,b,c){ed.call(this,b,c);this.K=this.j=null;this.C=new z(0,0", + ");this.Y=this.N=!1;if(a){n(a.buttonPressed)&&(this.j=a.buttonPressed);t", + "ry{B(a.elementPressed)&&(this.K=a.elementPressed)}catch(d){this.j=null}", + "this.C=new z(a.clientXY.x,a.clientXY.y);this.N=!!a.nextClickIsDoubleCli", + "ck;this.Y=!!a.hasEverInteracted;try{a.element&&B(a.element)&&fd(this,a.", + "element)}catch(d){this.j=null}}}p(vd,ed);var Z={};Z[Pc]=[0,1,2,null];Z[", + "Qc]=[null,null,2,null];Z[Wc]=[0,1,2,null];Z[Uc]=[0,1,2,4];Z[Tc]=[0,1,2,", + "4];\nQa&&(Z[Zc]=Z[Wc],Z[cd]=Z[Wc],Z[$c]=[-1,-1,-1,-1],Z[bd]=Z[$c],Z[ad]", + "=Z[$c]);Z[Rc]=Z[Pc];Z[Sc]=Z[Wc];Z[Vc]=Z[Uc];var wd={};wd[Sc]=Zc;wd[Tc]=", + "$c;wd[Uc]=bd;wd[Vc]=ad;wd[Wc]=cd;vd.prototype.move=function(a,b){var c=", + "tc(a),d=Fc(a);this.C.x=b.x+d.left;this.C.y=b.y+d.top;b=this.I();if(a!=b", + "){try{Sa(A(b)).closed&&(b=null)}catch(e){b=null}b&&(d=b===ka.document.d", + "ocumentElement||b===ka.document.body,b=!this.Y&&d?null:b,xd(this,Uc,a))", + ";fd(this,a);xd(this,Vc,b,null,c)}xd(this,Tc,null,null,c);this.N=!1};\nv", + "d.prototype.scroll=function(a){if(0==a)throw new u(13,\"Must scroll a n", + "on-zero number of ticks.\");for(var b=0<a?-120:120,c=0;c<Math.abs(a);c+", + "+)xd(this,Nc,null,b)};function xd(a,b,c,d,e,f){a.Y=!0;if(Qa){var h=wd[b", + "];if(h&&!a.S(h,a.C,yd(a,h),1,MSPointerEvent.MSPOINTER_TYPE_MOUSE,!0,c,e", + "))return!1}return a.W(b,a.C,yd(a,b),c,d,e,null,f)}function yd(a,b){if(!", + "(b in Z))return 0;a=Z[b][null===a.j?3:a.j];if(null===a)throw new u(13,", + "\"Event does not permit the specified mouse button.\");return a}\nvd.pr", + "ototype.getState=function(){return{buttonPressed:this.j,elementPressed:", + "this.K,clientXY:{x:this.C.x,y:this.C.y},nextClickIsDoubleClick:this.N,h", + "asEverInteracted:this.Y,element:this.I()}};function zd(a,b){this.x=a;th", + "is.y=b}p(zd,z);g=zd.prototype;g.clone=function(){return new zd(this.x,t", + "his.y)};g.scale=z.prototype.scale;g.normalize=function(){return this.sc", + "ale(1/Math.sqrt(this.x*this.x+this.y*this.y))};g.add=function(a){this.x", + "+=a.x;this.y+=a.y;return this};g.rotate=function(a){var b=Math.cos(a);a", + "=Math.sin(a);var c=this.y*b+this.x*a;this.x=this.x*b-this.y*a;this.y=c;", + "return this};function Ad(a){var b;(b=qc(a,\"display\"))||(b=a.currentSt", + "yle?a.currentStyle.display:null);if(\"none\"!=(b||a.style&&a.style.disp", + "lay))b=rc(a);else{b=a.style;var c=b.display,d=b.visibility,e=b.position", + ";b.visibility=\"hidden\";b.position=\"absolute\";b.display=\"inline\";v", + "ar f=rc(a);b.display=c;b.position=e;b.visibility=d;b=f}return 0<b.width", + "&&0<b.height||!a.offsetParent?b:Ad(a.offsetParent)};ba(\"_\",function(a", + ",b,c,d){if(!uc(a))throw new u(11,\"Element is not currently visible and", + " may not be manipulated\");b:{var e=b||void 0;if(\"scroll\"==Gc(a,e)){i", + "f(a.scrollIntoView&&(a.scrollIntoView(),\"none\"==Gc(a,e)))break b;for(", + "var f=Jc(a,e),h=Cc(a);h;h=Cc(h)){var l=h,q=Fc(l);var y=l;var r=qc(y,\"b", + "orderLeftWidth\");var v=qc(y,\"borderRightWidth\");var J=qc(y,\"borderT", + "opWidth\");y=qc(y,\"borderBottomWidth\");v=new pc(parseFloat(J),parseFl", + "oat(v),parseFloat(y),parseFloat(r));r=f.left-q.left-v.left;q=f.top-q.to", + "p-\nv.top;v=l.clientHeight+f.top-f.bottom;l.scrollLeft+=Math.min(r,Math", + ".max(r-(l.clientWidth+f.left-f.right),0));l.scrollTop+=Math.min(q,Math.", + "max(q-v,0))}Gc(a,e)}}b?b=new zd(b.x,b.y):(b=Ad(a),b=new zd(b.width/2,b.", + "height/2));c=c||new vd;c.move(a,b);if(null!==c.j)throw new u(13,\"Canno", + "t press more than one button or an already pressed button.\");c.j=0;c.K", + "=c.I();if(B(c.I(),\"OPTION\")||B(c.I(),\"SELECT\")||xd(c,Sc,null,null,!", + "1,void 0))Qa&&0==c.j&&B(c.K,\"OPTION\")&&c.S(Xc,c.C,0,1,MSPointerEvent.", + "MSPOINTER_TYPE_MOUSE,\n!0),kd(c);if(null===c.j)throw new u(13,\"Cannot ", + "release a button when no button is pressed.\");c.G&&tc(c.g)&&(a=c.G,b=g", + "b(c.g),!b||a.multiple)&&(c.g.selected=!b,a.multiple&&!(0<=na(Pa,28))||d", + "d(a,Oc));a=tc(c.I());xd(c,Wc,null,null,d,void 0);try{if(0==c.j&&c.I()==", + "c.K){var U=c.C,ma=yd(c,Pc);if(a||tc(c.g))!c.G&&fb(c.g)&&gb(c.g),c.W(Pc,", + "U,ma,null,0,a,void 0);c.N&&xd(c,Rc);c.N=!c.N;Qa&&0==c.j&&B(c.K,\"OPTION", + "\")&&c.S(Yc,new z(0,0),0,1,MSPointerEvent.MSPOINTER_TYPE_MOUSE,!1)}else", + " 2==c.j&&xd(c,Qc)}catch(Bd){}id=\n{};c.j=null;c.K=null});; return this.", + "_.apply(null,arguments);}.apply({navigator:typeof window!='undefined'?w", + "indow.navigator:null,document:typeof window!='undefined'?window.documen", + "t:null}, arguments);}", NULL }; @@ -2554,10 +2554,10 @@ "xt:vc,\"partial link text\":vc,tagName:wc,\"tag name\":wc,xpath:U};ba(", "\"_\",function(a,b){a:{for(c in a)if(a.hasOwnProperty(c))break a;var c=", "null}if(c){var d=xc[c];if(d&&p(d.l))return d.l(a[c],b||ja.document)}thr", - "ow Error(\"Unsupported locator strategy: \"+c);});; return this._.apply", - "(null,arguments);}.apply({navigator:typeof window!='undefined'?window.n", - "avigator:null,document:typeof window!='undefined'?window.document:null}", - ", arguments);}", + "ow new t(61,\"Unsupported locator strategy: \"+c);});; return this._.ap", + "ply(null,arguments);}.apply({navigator:typeof window!='undefined'?windo", + "w.navigator:null,document:typeof window!='undefined'?window.document:nu", + "ll}, arguments);}", NULL }; @@ -4540,14 +4540,14 @@ "t&&a.Document.prototype||a.document;if(!c.evaluate||b)a.XPathResult=V,c", ".evaluate=function(a,b,c,h){return(new zb(a,c)).evaluate(b,h)},c.create", "Expression=function(a,b){return new zb(a,b)},c.createNSResolver=functio", - "n(a){return new Ab(a)}});function Bb(){this.$=ga.document.documentEleme", - "nt;a:{var a=za(this.$);try{var b=a&&a.activeElement;break a}catch(c){}b", - "=null}b&&Cb(this,b)}function Cb(a,b){a.$=b;x(b,\"OPTION\")&&Ba(b,functi", - "on(a){return x(a,\"SELECT\")})}function Db(a){return x(a,\"FORM\")};ua(", - ");ua();function Eb(a,b,c){this.A=a;this.la=b;this.ma=c}Eb.prototype.cre", - "ate=function(a){a=za(a).createEvent(\"HTMLEvents\");a.initEvent(this.A,", - "this.la,this.ma);return a};Eb.prototype.toString=function(){return this", - ".A};var Gb=new Eb(\"submit\",!0,!0);function W(a,b){this.v={};this.g=[]", + "n(a){return new Ab(a)}});ua();ua();function Bb(a,b,c){this.A=a;this.la=", + "b;this.ma=c}Bb.prototype.create=function(a){a=za(a).createEvent(\"HTMLE", + "vents\");a.initEvent(this.A,this.la,this.ma);return a};Bb.prototype.toS", + "tring=function(){return this.A};var Cb=new Bb(\"submit\",!0,!0);functio", + "n Db(){this.$=ga.document.documentElement;a:{var a=za(this.$);try{var b", + "=a&&a.activeElement;break a}catch(c){}b=null}b&&Eb(this,b)}function Eb(", + "a,b){a.$=b;x(b,\"OPTION\")&&Ba(b,function(a){return x(a,\"SELECT\")})}f", + "unction Gb(a){return x(a,\"FORM\")};function W(a,b){this.v={};this.g=[]", ";this.G=0;var c=arguments.length;if(1<c){if(c%2)throw Error(\"Uneven nu", "mber of arguments\");for(var d=0;d<c;d+=2)this.set(arguments[d],argumen", "ts[d+1])}else a&&this.addAll(a)}function Hb(a){Ib(a);return a.g.concat(", @@ -4594,11 +4594,11 @@ "\");X(220,\"\\\\\",\"|\");X(221,\"]\",\"}\");X({c:59,b:186},\";\",\":\"", ");X(222,\"'\",'\"');var Y=new W;Y.set(1,Lb);Y.set(2,Mb);Y.set(4,Nb);Y.s", "et(8,Ob);(function(a){var b=new W;p(Hb(a),function(c){b.set(a.get(c).co", - "de,c)});return b})(Y);function Z(){Bb.call(this)}n(Z,Bb);Z.U=void 0;Z.n", + "de,c)});return b})(Y);function Z(){Db.call(this)}n(Z,Db);Z.U=void 0;Z.n", "a=function(){return Z.U?Z.U:Z.U=new Z};aa(\"_\",function(a){var b=Ba(a,", - "Db,!0);if(!b)throw new t(7,\"Element was not in a form, so could not su", - "bmit.\");var c=Z.na();Cb(c,a);if(!Db(b))throw new t(12,\"Element is not", - " a form, so could not submit.\");a=Gb.create(b,void 0);\"isTrusted\"in ", + "Gb,!0);if(!b)throw new t(7,\"Element was not in a form, so could not su", + "bmit.\");var c=Z.na();Eb(c,a);if(!Gb(b))throw new t(12,\"Element is not", + " a form, so could not submit.\");a=Cb.create(b,void 0);\"isTrusted\"in ", "a||(a.isTrusted=!1);b.dispatchEvent(a)&&(x(b.submit)?b.constructor.prot", "otype.submit.call(b):b.submit())});; return this._.apply(null,arguments", ");}.apply({navigator:typeof window!='undefined'?window.navigator:null,d", @@ -5334,13 +5334,13 @@ "tion yc(a){for(var b in a)if(a.hasOwnProperty(b))return b;return null};", "var zc=\"function\"===typeof ShadowRoot;ba(\"_\",function(a,b){var c;a:", "{if(c=yc(a)){var d=xc[c];if(d&&p(d.u)){c=d.u(a[c],b||ja.document);break", - " a}}throw Error(\"Unsupported locator strategy: \"+c);}if(c)return c;if", - "(zc&&b){for(c=b;c.parentNode;)c=c.parentNode;if(c instanceof ShadowRoot", - "){a:{if((c=yc(a))&&(d=xc[c])&&p(d.l)){a=d.l(a[c],b||ja.document);break ", - "a}throw Error(\"Unsupported locator strategy: \"+c);}if(c=a[0])return c", - "}}return null});; return this._.apply(null,arguments);}.apply({navigato", - "r:typeof window!='undefined'?window.navigator:null,document:typeof wind", - "ow!='undefined'?window.document:null}, arguments);}", + " a}}throw new v(61,\"Unsupported locator strategy: \"+c);}if(c)return c", + ";if(zc&&b){for(c=b;c.parentNode;)c=c.parentNode;if(c instanceof ShadowR", + "oot){a:{if((c=yc(a))&&(d=xc[c])&&p(d.l)){a=d.l(a[c],b||ja.document);bre", + "ak a}throw new v(61,\"Unsupported locator strategy: \"+c);}if(c=a[0])re", + "turn c}}return null});; return this._.apply(null,arguments);}.apply({na", + "vigator:typeof window!='undefined'?window.navigator:null,document:typeo", + "f window!='undefined'?window.document:null}, arguments);}", NULL }; @@ -7771,62 +7771,61 @@ const char* const GET_ATTRIBUTE[] = { "function(){return function(){function d(a){return\"string\"==typeof a};", - "function g(a,b){this.code=a;this.state=h[a]||k;this.message=b||\"\";a=t", - "his.state.replace(/((?:^|\\s+)[a-z])/g,function(a){return a.toUpperCase", - "().replace(/^[\\s\\xa0]+/g,\"\")});b=a.length-5;if(0>b||a.indexOf(\"Err", - "or\",b)!=b)a+=\"Error\";this.name=a;a=Error(this.message);a.name=this.n", - "ame;this.stack=a.stack||\"\"}\n(function(){var a=Error;function b(){}b.", - "prototype=a.prototype;g.b=a.prototype;g.prototype=new b;g.prototype.con", - "structor=g;g.a=function(b,e,f){for(var c=Array(arguments.length-2),m=2;", - "m<arguments.length;m++)c[m-2]=arguments[m];return a.prototype[e].apply(", - "b,c)}})();var k=\"unknown error\",h={15:\"element not selectable\",11:", - "\"element not visible\"};h[31]=k;h[30]=k;h[24]=\"invalid cookie domain", - "\";h[29]=\"invalid element coordinates\";h[12]=\"invalid element state", - "\";h[32]=\"invalid selector\";h[51]=\"invalid selector\";\nh[52]=\"inva", - "lid selector\";h[17]=\"javascript error\";h[405]=\"unsupported operatio", - "n\";h[34]=\"move target out of bounds\";h[27]=\"no such alert\";h[7]=\"", - "no such element\";h[8]=\"no such frame\";h[23]=\"no such window\";h[28]", - "=\"script timeout\";h[33]=\"session not created\";h[10]=\"stale element", - " reference\";h[21]=\"timeout\";h[25]=\"unable to set cookie\";h[26]=\"u", - "nexpected alert open\";h[13]=k;h[9]=\"unknown command\";g.prototype.toS", - "tring=function(){return this.name+\": \"+this.message};function n(a,b){", - "for(var c=a.length,e=d(a)?a.split(\"\"):a,f=0;f<c;f++)f in e&&b.call(vo", - "id 0,e[f],f,a)};function p(a,b){b=b.toLowerCase();return\"style\"==b?q(", - "a.style.cssText):(a=a.getAttributeNode(b))&&a.specified?a.value:null}va", - "r r=/[;]+(?=(?:(?:[^\"]*\"){2})*[^\"]*$)(?=(?:(?:[^']*'){2})*[^']*$)(?=", - "(?:[^()]*\\([^()]*\\))*[^()]*$)/;function q(a){var b=[];n(a.split(r),fu", - "nction(a){var c=a.indexOf(\":\");0<c&&(a=[a.slice(0,c),a.slice(c+1)],2=", - "=a.length&&b.push(a[0].toLowerCase(),\":\",a[1],\";\"))});b=b.join(\"\"", - ");return b=\";\"==b.charAt(b.length-1)?b:b+\";\"}\nfunction t(a,b){b&&", - "\"string\"!==typeof b&&(b=b.toString());return!!a&&1==a.nodeType&&(!b||", - "a.tagName.toUpperCase()==b)}function u(a){return t(a,\"OPTION\")?!0:t(a", - ",\"INPUT\")?(a=a.type.toLowerCase(),\"checkbox\"==a||\"radio\"==a):!1};", - "var v={\"class\":\"className\",readonly:\"readOnly\"},w=\"allowfullscre", - "en allowpaymentrequest allowusermedia async autofocus autoplay checked ", - "compact complete controls declare default defaultchecked defaultselecte", - "d defer disabled ended formnovalidate hidden indeterminate iscontentedi", - "table ismap itemscope loop multiple muted nohref nomodule noresize nosh", - "ade novalidate nowrap open paused playsinline pubdate readonly required", - " reversed scoped seamless seeking selected truespeed typemustmatch will", - "validate\".split(\" \");function x(a,b){var c=b.toLowerCase();if(\"styl", - "e\"==c)return(b=a.style)&&!d(b)&&(b=b.cssText),b;if((\"selected\"==c||", - "\"checked\"==c)&&u(a)){if(!u(a))throw new g(15,\"Element is not selecta", - "ble\");b=\"selected\";var e=a.type&&a.type.toLowerCase();if(\"checkbox", - "\"==e||\"radio\"==e)b=\"checked\";return a[b]?\"true\":null}var f=t(a,", - "\"A\");if(t(a,\"IMG\")&&\"src\"==c||f&&\"href\"==c)return(b=p(a,c))&&(b", - "=a[c]),b;if(\"spellcheck\"==c){b=p(a,c);if(null!==b){if(\"false\"==b.to", - "LowerCase())return\"false\";if(\"true\"==b.toLowerCase())return\"true\"", - "}return a[c]+\n\"\"}f=v[b]||b;a:if(d(w))c=d(c)&&1==c.length?w.indexOf(c", - ",0):-1;else{for(var l=0;l<w.length;l++)if(l in w&&w[l]===c){c=l;break a", - "}c=-1}if(0<=c)return(b=null!==p(a,b)||a[f])?\"true\":null;try{e=a[f]}ca", - "tch(m){}(c=null==e)||(c=typeof e,c=\"object\"==c&&null!=e||\"function\"", - "==c);b=c?p(a,b):e;return null!=b?b.toString():null}var y=[\"_\"],z=this", - ";y[0]in z||!z.execScript||z.execScript(\"var \"+y[0]);\nfor(var A;y.len", - "gth&&(A=y.shift());){var B;if(B=!y.length)B=void 0!==x;B?z[A]=x:z=z[A]&", - "&z[A]!==Object.prototype[A]?z[A]:z[A]={}};; return this._.apply(null,ar", - "guments);}.apply({navigator:typeof window!='undefined'?window.navigator", - ":null,document:typeof window!='undefined'?window.document:null}, argume", - "nts);}", + "function g(a,b){for(var c=a.length,e=d(a)?a.split(\"\"):a,f=0;f<c;f++)f", + " in e&&b.call(void 0,e[f],f,a)};function h(a,b){this.code=a;this.state=", + "k[a]||n;this.message=b||\"\";a=this.state.replace(/((?:^|\\s+)[a-z])/g,", + "function(a){return a.toUpperCase().replace(/^[\\s\\xa0]+/g,\"\")});b=a.", + "length-5;if(0>b||a.indexOf(\"Error\",b)!=b)a+=\"Error\";this.name=a;a=E", + "rror(this.message);a.name=this.name;this.stack=a.stack||\"\"}\n(functio", + "n(){var a=Error;function b(){}b.prototype=a.prototype;h.b=a.prototype;h", + ".prototype=new b;h.prototype.constructor=h;h.a=function(b,e,f){for(var ", + "c=Array(arguments.length-2),m=2;m<arguments.length;m++)c[m-2]=arguments", + "[m];return a.prototype[e].apply(b,c)}})();var n=\"unknown error\",k={15", + ":\"element not selectable\",11:\"element not visible\"};k[31]=n;k[30]=n", + ";k[24]=\"invalid cookie domain\";k[29]=\"invalid element coordinates\";", + "k[12]=\"invalid element state\";k[32]=\"invalid selector\";k[51]=\"inva", + "lid selector\";\nk[52]=\"invalid selector\";k[17]=\"javascript error\";", + "k[405]=\"unsupported operation\";k[34]=\"move target out of bounds\";k[", + "27]=\"no such alert\";k[7]=\"no such element\";k[8]=\"no such frame\";k", + "[23]=\"no such window\";k[28]=\"script timeout\";k[33]=\"session not cr", + "eated\";k[10]=\"stale element reference\";k[21]=\"timeout\";k[25]=\"una", + "ble to set cookie\";k[26]=\"unexpected alert open\";k[13]=n;k[9]=\"unkn", + "own command\";h.prototype.toString=function(){return this.name+\": \"+t", + "his.message};function p(a,b){b=b.toLowerCase();return\"style\"==b?q(a.s", + "tyle.cssText):(a=a.getAttributeNode(b))&&a.specified?a.value:null}var r", + "=/[;]+(?=(?:(?:[^\"]*\"){2})*[^\"]*$)(?=(?:(?:[^']*'){2})*[^']*$)(?=(?:", + "[^()]*\\([^()]*\\))*[^()]*$)/;function q(a){var b=[];g(a.split(r),funct", + "ion(a){var c=a.indexOf(\":\");0<c&&(a=[a.slice(0,c),a.slice(c+1)],2==a.", + "length&&b.push(a[0].toLowerCase(),\":\",a[1],\";\"))});b=b.join(\"\");r", + "eturn b=\";\"==b.charAt(b.length-1)?b:b+\";\"}\nfunction t(a,b){b&&\"st", + "ring\"!==typeof b&&(b=b.toString());return!!a&&1==a.nodeType&&(!b||a.ta", + "gName.toUpperCase()==b)}function u(a){return t(a,\"OPTION\")?!0:t(a,\"I", + "NPUT\")?(a=a.type.toLowerCase(),\"checkbox\"==a||\"radio\"==a):!1};var ", + "v={\"class\":\"className\",readonly:\"readOnly\"},w=\"allowfullscreen a", + "llowpaymentrequest allowusermedia async autofocus autoplay checked comp", + "act complete controls declare default defaultchecked defaultselected de", + "fer disabled ended formnovalidate hidden indeterminate iscontenteditabl", + "e ismap itemscope loop multiple muted nohref nomodule noresize noshade ", + "novalidate nowrap open paused playsinline pubdate readonly required rev", + "ersed scoped seamless seeking selected truespeed typemustmatch willvali", + "date\".split(\" \");function x(a,b){var c=b.toLowerCase();if(\"style\"=", + "=c)return(b=a.style)&&!d(b)&&(b=b.cssText),b;if((\"selected\"==c||\"che", + "cked\"==c)&&u(a)){if(!u(a))throw new h(15,\"Element is not selectable\"", + ");b=\"selected\";var e=a.type&&a.type.toLowerCase();if(\"checkbox\"==e|", + "|\"radio\"==e)b=\"checked\";return a[b]?\"true\":null}var f=t(a,\"A\");", + "if(t(a,\"IMG\")&&\"src\"==c||f&&\"href\"==c)return(b=p(a,c))&&(b=a[c]),", + "b;if(\"spellcheck\"==c){b=p(a,c);if(null!==b){if(\"false\"==b.toLowerCa", + "se())return\"false\";if(\"true\"==b.toLowerCase())return\"true\"}return", + " a[c]+\n\"\"}f=v[b]||b;a:if(d(w))c=d(c)&&1==c.length?w.indexOf(c,0):-1;", + "else{for(var l=0;l<w.length;l++)if(l in w&&w[l]===c){c=l;break a}c=-1}i", + "f(0<=c)return(b=null!==p(a,b)||a[f])?\"true\":null;try{e=a[f]}catch(m){", + "}(c=null==e)||(c=typeof e,c=\"object\"==c&&null!=e||\"function\"==c);b=", + "c?p(a,b):e;return null!=b?b.toString():null}var y=[\"_\"],z=this;y[0]in", + " z||!z.execScript||z.execScript(\"var \"+y[0]);\nfor(var A;y.length&&(A", + "=y.shift());){var B;if(B=!y.length)B=void 0!==x;B?z[A]=x:z=z[A]&&z[A]!=", + "=Object.prototype[A]?z[A]:z[A]={}};; return this._.apply(null,arguments", + ");}.apply({navigator:typeof window!='undefined'?window.navigator:null,d", + "ocument:typeof window!='undefined'?window.document:null}, arguments);}", NULL };
diff --git a/tools/android/eclipse/.classpath b/tools/android/eclipse/.classpath index 155fec1..6d0b79a 100644 --- a/tools/android/eclipse/.classpath +++ b/tools/android/eclipse/.classpath
@@ -310,6 +310,7 @@ <classpathentry kind="lib" path="out/Debug/lib.java/third_party/robolectric/robolectric_utils_java.jar" sourcepath="third_party/robolectric/robolectric/robolectric-utils/src/main/java"/> <classpathentry kind="lib" path="out/Debug/lib.java/third_party/robolectric/shadows-core-3.2.jar" sourcepath="third_party/robolectric/robolectric/robolectric-shadows/shadows-core/src/main/java"/> <classpathentry kind="lib" path="out/Debug/lib.java/third_party/robolectric/shadows-multidex-3.0.jar" sourcepath="third_party/robolectric/robolectric/robolectric-shadows/shadows-multidex/src/main/java"/> + <classpathentry kind="lib" path="out/Debug/lib.java/third_party/android_deps/com_android_support_support_compat_java.jar"/> <classpathentry kind="lib" path="out/Debug/lib.java/third_party/android_support_test_runner/runner-0.5-release-no-dep.jar"/> <classpathentry kind="lib" path="out/Debug/lib.java/third_party/android_support_test_runner/rules_java.jar"/> <classpathentry kind="lib" path="out/Debug/lib.java/third_party/blink/public/blink_headers_java.jar"/>
diff --git a/tools/gdb/util/class_methods.py b/tools/gdb/util/class_methods.py index 2cb7e25..53bf5ef 100644 --- a/tools/gdb/util/class_methods.py +++ b/tools/gdb/util/class_methods.py
@@ -88,7 +88,7 @@ # Constructs a regular expression to match this type. self._class_regex = re.compile( '^' + re.escape(class_name) + - ('<.*>' if template_types > 0 else '') + '$') + ('<.*>' if len(template_types) > 0 else '') + '$') # Construct a dictionary and array of methods self.dict = {}
diff --git a/tools/generate_stubs/rules.gni b/tools/generate_stubs/rules.gni deleted file mode 100644 index 548efd6..0000000 --- a/tools/generate_stubs/rules.gni +++ /dev/null
@@ -1,88 +0,0 @@ -# Create a source_set with generated stubs for a POSIX shared library. -# -# Based on C-style signatures, it will generate a source and a header file -# and expose it as a source_set. -# -# See //tools/generate_stubs/generate_stubs.py for more info. -# -# Variables -# sigs: list of files with C-style signatures (*.sig) -# output_name: name of the generated files: $output_name.h and $output_name.cc -# extra_header: prepend the contents of this file to the generated .cc file -# logging_function: override the used logging function (default: VLOG(1)) -# logging_include: override the additional include (default: base/logging.h) -# -# Example -# generate_stubs("libfoo_stubs") { -# sigs = [ "foo/foo.sigs" ] -# extra_header = "foo/foo_stub_header.fragment" -# output_name = "foo/foo_stubs" -# deps = [ -# "//base", -# ] -# } -# -# Targets that depend on this target can `#include "path/to/foo/foo_stubs.h"` -template("generate_stubs") { - forward_variables_from(invoker, [ "testonly" ]) - - _gen_dir = get_path_info(invoker.output_name, "gen_dir") - - action("${target_name}__stubs_gen") { - script = "//tools/generate_stubs/generate_stubs.py" - sources = invoker.sigs - inputs = [ - invoker.extra_header, - ] - outputs = [ - "${target_gen_dir}/${invoker.output_name}.cc", - "${target_gen_dir}/${invoker.output_name}.h", - ] - args = [ - "--intermediate_dir", - rebase_path(_gen_dir, root_build_dir), - "--output", - rebase_path(_gen_dir, root_build_dir), - "--type", - "posix_stubs", - "--extra_stub_header", - rebase_path(invoker.extra_header, root_build_dir), - "--stubfile_name", - get_path_info(invoker.output_name, "name"), - "--path_from_source", - rebase_path(_gen_dir, root_gen_dir), - ] - if (defined(invoker.logging_function)) { - args += [ - "--logging-function", - invoker.logging_function, - ] - } - if (defined(invoker.logging_include)) { - args += [ - "--logging-include", - invoker.logging_include, - ] - } - args += rebase_path(invoker.sigs, root_build_dir) - } - - source_set(target_name) { - forward_variables_from(invoker, - [ - "deps", - "public_deps", - "visibility", - ]) - if (!defined(deps)) { - deps = [] - } - deps += [ ":${target_name}__stubs_gen" ] - sources = [ - "${target_gen_dir}/${invoker.output_name}.cc", - "${target_gen_dir}/${invoker.output_name}.h", - ] - libs = [ "dl" ] - include_dirs = [ target_gen_dir ] - } -}
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml index 00d99e9..e4325da 100644 --- a/tools/metrics/actions/actions.xml +++ b/tools/metrics/actions/actions.xml
@@ -2348,6 +2348,14 @@ </description> </action> +<action name="AutofillCreditCardsAdded"> + <owner>nikunjb@chromium.org</owner> + <owner>sebsg@chromium.org</owner> + <description> + Recorded when user adds card via chrome://settings/payments page. + </description> +</action> + <action name="AutofillCreditCardsViewed"> <owner>nikunjb@chromium.org</owner> <owner>sebsg@chromium.org</owner> @@ -4765,6 +4773,23 @@ <description>Please enter the description of this user action.</description> </action> +<action name="DemoMode.ExitFromShelf"> + <owner>michaelpg@chromium.org</owner> + <owner>wzang@chromium.org</owner> + <description> + Recorded when user exits Demo Mode from the logout button on the shelf. + </description> +</action> + +<action name="DemoMode.ExitFromSystemTray"> + <owner>michaelpg@chromium.org</owner> + <owner>wzang@chromium.org</owner> + <description> + Recorded when user exits Demo Mode from the logout button in the system + tray. + </description> +</action> + <action name="Desktop_SwitchTask"> <owner>bruthig@google.com</owner> <owner>tdanderson@google.com</owner>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 4ec96cd..7c641fd5 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -34218,6 +34218,18 @@ </summary> </histogram> +<histogram name="Extensions.WebRequest.TotalExtraHeadersRequestTime" units="ms" + expires_after="2019-05-27"> + <owner>karandeepb@chromium.org</owner> + <owner>rdevlin.cronin@chromium.org</owner> + <summary> + The total time a network request took when at least one Web Request listener + with 'extraHeaders' in the extraInfoSpec was registered at the start of the + request. Measures from onBeforeRequest to onCompleted/onErrorOccurred, and + does not include canceled or redirected requests. + </summary> +</histogram> + <histogram name="Extensions.WebRequest.TotalRequestTime" units="ms" expires_after="2019-05-13"> <owner>karandeepb@chromium.org</owner> @@ -71885,7 +71897,7 @@ </histogram> <histogram name="Omnibox.DocumentSuggest.ResultCount" units="count" - expires_after="M72"> + expires_after="M74"> <owner>skare@chromium.org</owner> <summary> Number of results returned in each document suggestion reply. Logged for @@ -99552,6 +99564,26 @@ <histogram name="ServiceWorker.LoadTiming.MainFrame.MainResource.ResponseReceivedToCompleted" units="ms" expires_after="2021-10-31"> + <obsolete> + Deprecated 2018-11 in favor of + ServiceWorker.LoadTiming.MainFrame.MainResource.ResponseReceivedToCompleted2. + </obsolete> + <owner>bashi@chromium.org</owner> + <owner>chrome-worker@google.com</owner> + <summary> + The time taken from (a) response headers from service worker are received, + to (b) reading response body is completed. Recorded when a fetch event + handler handled the request. + + Recorded for each navigation request (including redirects) where there is a + fetch event handler and the fetch event was successfully dispatched to the + service worker. + </summary> +</histogram> + +<histogram + name="ServiceWorker.LoadTiming.MainFrame.MainResource.ResponseReceivedToCompleted2" + units="ms" expires_after="2021-10-31"> <owner>bashi@chromium.org</owner> <owner>chrome-worker@google.com</owner> <summary> @@ -99634,6 +99666,25 @@ <histogram name="ServiceWorker.LoadTiming.Subresource.ForwardServiceWorkerToWorkerReady" units="ms" expires_after="2021-10-31"> + <obsolete> + Deprecated 2018-11 in favor of + ServiceWorker.LoadTiming.Subresource.ForwardServiceWorkerToWorkerReady2. + </obsolete> + <owner>bashi@chromium.org</owner> + <owner>chrome-worker@google.com</owner> + <summary> + The time taken from (a) a subresource request is routed to the URLLoader (on + a background thread) for service worker controlled loads starts handling a + subresource request, to (b) a service worker is ready to handle the request. + + Recorded for each subresource request where there is a fetch event handler + and the fetch event was successfully dispatched to the service worker. + </summary> +</histogram> + +<histogram + name="ServiceWorker.LoadTiming.Subresource.ForwardServiceWorkerToWorkerReady2" + units="ms" expires_after="2021-10-31"> <owner>bashi@chromium.org</owner> <owner>chrome-worker@google.com</owner> <summary>
diff --git a/tools/perf/benchmark.csv b/tools/perf/benchmark.csv index 825038e..5527f6c 100644 --- a/tools/perf/benchmark.csv +++ b/tools/perf/benchmark.csv
@@ -5,7 +5,7 @@ base_perftests,"skyostil@chromium.org, gab@chromium.org",Internals>SequenceManager,https://chromium.googlesource.com/chromium/src/+/HEAD/base/README.md#performance-testing, blink_perf.accessibility,dmazzoni@chromium.org,Blink>Accessibility,https://bit.ly/blink-perf-benchmarks, blink_perf.bindings,"jbroman@chromium.org, yukishiino@chromium.org, haraken@chromium.org",Blink>Bindings,https://bit.ly/blink-perf-benchmarks, -blink_perf.canvas,fserb@chromium.org,Blink>Canvas,https://bit.ly/blink-perf-benchmarks, +blink_perf.canvas,"aaronhk@chromium.org, fserb@chromium.org",Blink>Canvas,https://bit.ly/blink-perf-benchmarks, blink_perf.css,"futhark@chromium.org, andruud@chromium.org",Blink>CSS,https://bit.ly/blink-perf-benchmarks, blink_perf.dom,"hayato@chromium.org, tkent@chromium.org",Blink>DOM,https://bit.ly/blink-perf-benchmarks, blink_perf.events,hayato@chromium.org,Blink>DOM,https://bit.ly/blink-perf-benchmarks,
diff --git a/tools/perf/benchmarks/blink_perf.py b/tools/perf/benchmarks/blink_perf.py index 75b64cf..8c52292 100644 --- a/tools/perf/benchmarks/blink_perf.py +++ b/tools/perf/benchmarks/blink_perf.py
@@ -39,10 +39,18 @@ action_runner.ExecuteJavaScript('testRunner.scheduleTestRun()') action_runner.WaitForJavaScriptCondition('testRunner.isDone', timeout=600) +def StoryNameFromUrl(url, prefix): + filename = url[len(prefix):].strip('/') + baseName, extension = filename.split('.') + if extension.find('?') != -1: + query = extension.split('?')[1] + baseName += "_" + query # So that queried page-names don't collide + return "{b}.{e}".format(b=baseName, e=extension) def CreateStorySetFromPath(path, skipped_file, shared_page_state_class=( - shared_page_state.SharedPageState)): + shared_page_state.SharedPageState), + append_query=None): assert os.path.exists(path) page_urls = [] @@ -54,7 +62,11 @@ if '../' in open(path, 'r').read(): # If the page looks like it references its parent dir, include it. serving_dirs.add(os.path.dirname(os.path.dirname(path))) - page_urls.append('file://' + path.replace('\\', '/')) + page_url = 'file://' + path.replace('\\', '/') + if append_query: + page_url += '?' + append_query + page_urls.append(page_url) + def _AddDir(dir_path, skipped): for candidate_path in os.listdir(dir_path): @@ -85,7 +97,7 @@ all_urls = [p.rstrip('/') for p in page_urls] common_prefix = os.path.dirname(os.path.commonprefix(all_urls)) for url in sorted(page_urls): - name = url[len(common_prefix):].strip('/') + name = StoryNameFromUrl(url, common_prefix) ps.AddStory(_BlinkPerfPage( url, ps, ps.base_dir, shared_page_state_class=shared_page_state_class, @@ -349,7 +361,7 @@ test = _BlinkPerfMeasurement def CreateStorySet(self, options): - path = os.path.join(BLINK_PERF_BASE_DIR, self.subdir) + path = os.path.join(BLINK_PERF_BASE_DIR, self.SUBDIR) return CreateStorySetFromPath(path, SKIPPED_FILE) @@ -357,8 +369,7 @@ component='Blink>Accessibility', documentation_url='https://bit.ly/blink-perf-benchmarks') class BlinkPerfAccessibility(_BlinkPerfBenchmark): - tag = 'accessibility' - subdir = 'accessibility' + SUBDIR = 'accessibility' @classmethod def Name(cls): @@ -376,7 +387,7 @@ 'haraken@chromium.org'], documentation_url='https://bit.ly/blink-perf-benchmarks') class BlinkPerfBindings(_BlinkPerfBenchmark): - subdir = 'bindings' + SUBDIR = 'bindings' @classmethod def Name(cls): @@ -387,43 +398,47 @@ documentation_url='https://bit.ly/blink-perf-benchmarks', component='Blink>CSS') class BlinkPerfCSS(_BlinkPerfBenchmark): - subdir = 'css' + SUBDIR = 'css' @classmethod def Name(cls): return 'blink_perf.css' - - -@benchmark.Info(emails=['fserb@chromium.org'], +@benchmark.Info(emails=['aaronhk@chromium.org', 'fserb@chromium.org'], documentation_url='https://bit.ly/blink-perf-benchmarks', component='Blink>Canvas') class BlinkPerfCanvas(_BlinkPerfBenchmark): - subdir = 'canvas' + SUBDIR = 'canvas' @classmethod def Name(cls): return 'blink_perf.canvas' def CreateStorySet(self, options): - path = os.path.join(BLINK_PERF_BASE_DIR, self.subdir) + path = os.path.join(BLINK_PERF_BASE_DIR, self.SUBDIR) story_set = CreateStorySetFromPath( path, SKIPPED_FILE, shared_page_state_class=( webgl_supported_shared_state.WebGLSupportedSharedState)) + raf_story_set = CreateStorySetFromPath( + path, SKIPPED_FILE, + shared_page_state_class=( + webgl_supported_shared_state.WebGLSupportedSharedState), + append_query="RAF") + for raf_story in raf_story_set: + story_set.AddStory(raf_story) # WebGLSupportedSharedState requires the skipped_gpus property to # be set on each page. for page in story_set: page.skipped_gpus = [] return story_set - @benchmark.Info(emails=['hayato@chromium.org', 'tkent@chromium.org'], component='Blink>DOM', documentation_url='https://bit.ly/blink-perf-benchmarks') class BlinkPerfDOM(_BlinkPerfBenchmark): - subdir = 'dom' + SUBDIR = 'dom' @classmethod def Name(cls): @@ -434,7 +449,7 @@ component='Blink>DOM', documentation_url='https://bit.ly/blink-perf-benchmarks') class BlinkPerfEvents(_BlinkPerfBenchmark): - subdir = 'events' + SUBDIR = 'events' @classmethod def Name(cls): @@ -445,8 +460,7 @@ component='Internals>Images>Codecs', documentation_url='https://bit.ly/blink-perf-benchmarks') class BlinkPerfImageDecoder(_BlinkPerfBenchmark): - tag = 'image_decoder' - subdir = 'image_decoder' + SUBDIR = 'image_decoder' @classmethod def Name(cls): @@ -461,7 +475,7 @@ @benchmark.Info(emails=['eae@chromium.org'], documentation_url='https://bit.ly/blink-perf-benchmarks') class BlinkPerfLayout(_BlinkPerfBenchmark): - subdir = 'layout' + SUBDIR = 'layout' @classmethod def Name(cls): @@ -471,7 +485,7 @@ @benchmark.Info(emails=['dmurph@chromium.org'], documentation_url='https://bit.ly/blink-perf-benchmarks') class BlinkPerfOWPStorage(_BlinkPerfBenchmark): - subdir = 'owp_storage' + SUBDIR = 'owp_storage' @classmethod def Name(cls): @@ -491,7 +505,7 @@ component='Blink>Paint', documentation_url='https://bit.ly/blink-perf-benchmarks') class BlinkPerfPaint(_BlinkPerfBenchmark): - subdir = 'paint' + SUBDIR = 'paint' @classmethod def Name(cls): @@ -504,7 +518,7 @@ 'haraken@chromium.org'], documentation_url='https://bit.ly/blink-perf-benchmarks') class BlinkPerfParser(_BlinkPerfBenchmark): - subdir = 'parser' + SUBDIR = 'parser' @classmethod def Name(cls): @@ -515,7 +529,7 @@ component='Blink>SVG', documentation_url='https://bit.ly/blink-perf-benchmarks') class BlinkPerfSVG(_BlinkPerfBenchmark): - subdir = 'svg' + SUBDIR = 'svg' @classmethod def Name(cls): @@ -526,7 +540,7 @@ component='Blink>DOM>ShadowDOM', documentation_url='https://bit.ly/blink-perf-benchmarks') class BlinkPerfShadowDOM(_BlinkPerfBenchmark): - subdir = 'shadow_dom' + SUBDIR = 'shadow_dom' @classmethod def Name(cls):
diff --git a/tools/perf/contrib/blink_layoutng_perf/blink_layoutng_perf.py b/tools/perf/contrib/blink_layoutng_perf/blink_layoutng_perf.py index 87d1344..f916abf 100644 --- a/tools/perf/contrib/blink_layoutng_perf/blink_layoutng_perf.py +++ b/tools/perf/contrib/blink_layoutng_perf/blink_layoutng_perf.py
@@ -8,7 +8,7 @@ @benchmark.Info(emails=['cbiesinger@chromium.org'], documentation_url='https://bit.ly/blink-perf-benchmarks') class BlinkPerfLayoutNg(blink_perf._BlinkPerfBenchmark): - subdir = 'layout' + SUBDIR = 'layout' def SetExtraBrowserOptions(self, options): super(BlinkPerfLayoutNg, self).SetExtraBrowserOptions(options) @@ -22,7 +22,7 @@ @benchmark.Info(emails=['cbiesinger@chromium.org'], documentation_url='https://bit.ly/blink-perf-benchmarks') class BlinkPerfParserLayoutNg(blink_perf._BlinkPerfBenchmark): - subdir = 'parser' + SUBDIR = 'parser' def SetExtraBrowserOptions(self, options): super(BlinkPerfParserLayoutNg, self).SetExtraBrowserOptions(options) @@ -36,7 +36,7 @@ @benchmark.Info(emails=['cbiesinger@chromium.org'], documentation_url='https://bit.ly/blink-perf-benchmarks') class BlinkPerfPaintLayoutNg(blink_perf._BlinkPerfBenchmark): - subdir = 'paint' + SUBDIR = 'paint' def SetExtraBrowserOptions(self, options): super(BlinkPerfPaintLayoutNg, self).SetExtraBrowserOptions(options)
diff --git a/tools/perf/contrib/blink_perf_cmdline/blink_perf_cmdline.py b/tools/perf/contrib/blink_perf_cmdline/blink_perf_cmdline.py index d146e162..929321b 100644 --- a/tools/perf/contrib/blink_perf_cmdline/blink_perf_cmdline.py +++ b/tools/perf/contrib/blink_perf_cmdline/blink_perf_cmdline.py
@@ -19,8 +19,8 @@ default=blink_perf.BLINK_PERF_BASE_DIR, help=('Path to blink perf tests. Could be an absolute ' 'path, a relative path with respect to your ' - 'current directory, or a relative path with ' - 'respect to third_party/WebKit/PerformanceTest/)')) + 'current directory or a relative path with ' + 'respect to third_party/blink/perf_tests)')) def CreateStorySet(self, options): if os.path.exists(options.test_path):
diff --git a/tools/perf/contrib/blink_perf_xml_http_request/blink_perf_xml_http_request.py b/tools/perf/contrib/blink_perf_xml_http_request/blink_perf_xml_http_request.py index 1d0a8453..8da0de9 100644 --- a/tools/perf/contrib/blink_perf_xml_http_request/blink_perf_xml_http_request.py +++ b/tools/perf/contrib/blink_perf_xml_http_request/blink_perf_xml_http_request.py
@@ -6,5 +6,4 @@ # pylint: disable=protected-access class BlinkPerfXMLHttpRequest(blink_perf._BlinkPerfBenchmark): - tag = 'xml_http_request' - subdir = 'xml_http_request' + SUBDIR = 'xml_http_request'
diff --git a/tools/perf/generate_perf_sharding b/tools/perf/generate_perf_sharding index 898ca08..8414c55 100755 --- a/tools/perf/generate_perf_sharding +++ b/tools/perf/generate_perf_sharding
@@ -7,16 +7,34 @@ import json import multiprocessing import sys +import textwrap from core import benchmark_utils from core import bot_platforms from core import retrieve_story_timing from core import sharding_map_generator +_SCRIPT_USAGE = """ +Generate sharding maps for Telemetry benchmarks. + +Every performance benchmark should be run on a same machine as long as possible +to preserve high fidelity of data monitoring. Hence in order to shard the +Telemetry benchmarks on multiple machines, we generate a JSON map that +specifies how benchmarks should be distributed on machines. There is one +sharding JSON map for every builder in the perf & perf.fyi waterfalls which are +specified by PerfPlatform classes in //tools/perf/core/bot_platforms.py. + +Generating these JSON maps depends on how many Telemetry benchmarks +actually exist at the time. Because of this, CLs to generate the JSON maps +should never be automatically reverted, since the reverted state of the JSON map +files may not match with the true state of world. + +""" + def GetParser(): parser = argparse.ArgumentParser( - description='Generate perf test sharding map.') + description=_SCRIPT_USAGE, formatter_class=argparse.RawTextHelpFormatter) subparsers = parser.add_subparsers() parser_update = subparsers.add_parser('update') @@ -35,7 +53,7 @@ 'specified, use all perf builders by default')) parser.add_argument( '--debug', action='store_true', - help=('Whether to include detailed debug info of the sharding map in the' + help=('Whether to include detailed debug info of the sharding map in the ' 'shard maps.'), default=False) parser_update.set_defaults(func=_UpdateShardsForBuilders) @@ -117,16 +135,38 @@ json.dump(sharding_map, output_file, indent=4, separators=(',', ': ')) +def _PromptWarning(): + message = ('This will regenerate the sharding maps for all perf benchmarks. ' + 'Note that this will shuffle all the benchmarks on the shards, ' + 'which can cause false regressions. In general this operation ' + 'should only be done when the shards are too unbalanced or when ' + 'benchmarks are added/removed. ' + 'In addition, this a tricky operation and should ' + 'only be done by Telemetry or Chrome Client Infrastructure ' + 'team members. Upon landing the CL to update the shards maps, ' + 'please notify Chromium perf sheriffs in ' + 'perf-sheriffs@chromium.org and put a warning about expected ' + 'false regressions in your CL ' + 'description') + print textwrap.fill(message, 70), '\n' + answer = raw_input("Enter 'y' to continue: ") + if answer != 'y': + print 'Abort updating shard maps for benchmarks on perf waterfall' + sys.exit(0) + + def _UpdateShardsForBuilders(args): if args.builders: builders = {b for b in bot_platforms.ALL_PLATFORMS if b.name in args.builders} elif args.waterfall == 'perf': builders = bot_platforms.ALL_PERF_PLATFORMS + _PromptWarning() elif args.waterfall == 'perf-fyi': builders = bot_platforms.ALL_PERF_FYI_PLATFORMS else: builders = bot_platforms.ALL_PLATFORMS + _PromptWarning() if args.regenerate_timing_data: print 'Update shards timing data. May take a while...'
diff --git a/tools/traffic_annotation/summary/annotations.xml b/tools/traffic_annotation/summary/annotations.xml index a1a8b75..dff0137 100644 --- a/tools/traffic_annotation/summary/annotations.xml +++ b/tools/traffic_annotation/summary/annotations.xml
@@ -286,6 +286,6 @@ <item id="webstore_install_helper" hash_code="25921771" type="0" content_hash_code="10206361" os_list="linux,windows" file_path="chrome/browser/extensions/webstore_install_helper.cc"/> <item id="webstore_installer" hash_code="18764319" type="0" content_hash_code="11030110" os_list="linux,windows" file_path="chrome/browser/extensions/webstore_installer.cc"/> <item id="webui_content_scripts_download" hash_code="100545943" type="0" content_hash_code="119898059" os_list="linux,windows" file_path="extensions/browser/guest_view/web_view/web_ui/web_ui_url_fetcher.cc"/> - <item id="worker_script_load" hash_code="72087791" type="0" content_hash_code="24889169" os_list="linux,windows" file_path="content/browser/shared_worker/worker_script_fetcher.cc"/> + <item id="worker_script_load" hash_code="72087791" type="0" content_hash_code="24889169" os_list="linux,windows" file_path="content/browser/worker_host/worker_script_fetcher.cc"/> <item id="xmpp_signal_strategy" hash_code="88906454" type="0" content_hash_code="88958321" os_list="linux,windows" file_path="remoting/signaling/xmpp_signal_strategy.cc"/> </annotations>
diff --git a/ui/aura/window_tree_host_platform.cc b/ui/aura/window_tree_host_platform.cc index fb11cb1..a116ba0 100644 --- a/ui/aura/window_tree_host_platform.cc +++ b/ui/aura/window_tree_host_platform.cc
@@ -145,7 +145,7 @@ // problems with event routing (i.e. which Hook takes precedence) and // destruction ordering. DCHECK(!keyboard_hook_); - keyboard_hook_ = ui::KeyboardHook::Create( + keyboard_hook_ = ui::KeyboardHook::CreateModifierKeyboardHook( std::move(dom_codes), GetAcceleratedWidget(), base::BindRepeating( [](ui::PlatformWindowDelegate* delegate, ui::KeyEvent* event) {
diff --git a/ui/events/BUILD.gn b/ui/events/BUILD.gn index 27aee57..278550b 100644 --- a/ui/events/BUILD.gn +++ b/ui/events/BUILD.gn
@@ -211,8 +211,10 @@ "system_input_injector.cc", "win/events_win.cc", "win/events_win_utils.cc", - "win/keyboard_hook_win.cc", - "win/keyboard_hook_win.h", + "win/keyboard_hook_win_base.cc", + "win/keyboard_hook_win_base.h", + "win/media_keyboard_hook_win.cc", + "win/modifier_keyboard_hook_win.cc", "win/system_event_state_lookup.cc", ] @@ -509,7 +511,8 @@ "platform/platform_event_source_unittest.cc", "scoped_target_handler_unittest.cc", "win/event_utils_win_unittest.cc", - "win/keyboard_hook_win_unittest.cc", + "win/media_keyboard_hook_win_unittest.cc", + "win/modifier_keyboard_hook_win_unittest.cc", ] deps = [ @@ -631,3 +634,21 @@ classes = [ "android/view/KeyEvent.class" ] } } + +# This target is added as a dependency of browser interactive_ui_tests. It must +# be source_set, otherwise the linker will drop the tests as dead code. +source_set("events_interactive_ui_tests") { + testonly = true + if (is_win) { + sources = [ + "win/media_keyboard_hook_win_interactive_test.cc", + ] + + deps = [ + ":events", + ":test_support", + "//base/test:test_support", + "//testing/gtest", + ] + } +}
diff --git a/ui/events/android/keyboard_hook_android.cc b/ui/events/android/keyboard_hook_android.cc index be373af..31937535 100644 --- a/ui/events/android/keyboard_hook_android.cc +++ b/ui/events/android/keyboard_hook_android.cc
@@ -14,11 +14,17 @@ namespace ui { // static -std::unique_ptr<KeyboardHook> KeyboardHook::Create( +std::unique_ptr<KeyboardHook> KeyboardHook::CreateModifierKeyboardHook( base::Optional<base::flat_set<DomCode>> dom_codes, gfx::AcceleratedWidget accelerated_widget, KeyboardHook::KeyEventCallback callback) { return nullptr; } +// static +std::unique_ptr<KeyboardHook> KeyboardHook::CreateMediaKeyboardHook( + KeyboardHook::KeyEventCallback callback) { + return nullptr; +} + } // namespace ui
diff --git a/ui/events/keyboard_hook.h b/ui/events/keyboard_hook.h index 36e9b88..ca88fec 100644 --- a/ui/events/keyboard_hook.h +++ b/ui/events/keyboard_hook.h
@@ -32,11 +32,19 @@ // |callback| is called for each key which is intercepted. // Returns a valid instance if the hook was created and successfully // registered otherwise nullptr. - static std::unique_ptr<KeyboardHook> Create( + static std::unique_ptr<KeyboardHook> CreateModifierKeyboardHook( base::Optional<base::flat_set<DomCode>> dom_codes, gfx::AcceleratedWidget accelerated_widget, KeyEventCallback callback); + // Creates a platform-specific KeyboardHook implementation that captures the + // play/pause, stop, and next/previous track media keys. + // |callback| is called for each key which is intercepted. + // Returns a valid instance if the hook was created and successfully + // registered otherwise nullptr. + static std::unique_ptr<KeyboardHook> CreateMediaKeyboardHook( + KeyEventCallback callback); + // True if |dom_code| is reserved for an active KeyboardLock request. virtual bool IsKeyLocked(DomCode dom_code) const = 0; };
diff --git a/ui/events/keyboard_hook_base.cc b/ui/events/keyboard_hook_base.cc index 56381738..327c2d4 100644 --- a/ui/events/keyboard_hook_base.cc +++ b/ui/events/keyboard_hook_base.cc
@@ -34,9 +34,8 @@ return !dom_codes_ || base::ContainsKey(dom_codes_.value(), dom_code); } -void KeyboardHookBase::ForwardCapturedKeyEvent( - std::unique_ptr<KeyEvent> event) { - key_event_callback_.Run(event.get()); +void KeyboardHookBase::ForwardCapturedKeyEvent(KeyEvent* event) { + key_event_callback_.Run(event); } } // namespace ui
diff --git a/ui/events/keyboard_hook_base.h b/ui/events/keyboard_hook_base.h index 81ffae2..2974081 100644 --- a/ui/events/keyboard_hook_base.h +++ b/ui/events/keyboard_hook_base.h
@@ -29,7 +29,9 @@ bool ShouldCaptureKeyEvent(DomCode dom_code) const; // Forwards the key event using |key_event_callback_|. - void ForwardCapturedKeyEvent(std::unique_ptr<KeyEvent> event); + // |event| is owned by the calling method and will live until this method + // returns. + void ForwardCapturedKeyEvent(KeyEvent* event); const base::Optional<base::flat_set<DomCode>>& dom_codes() { return dom_codes_;
diff --git a/ui/events/mac/keyboard_hook_mac.mm b/ui/events/mac/keyboard_hook_mac.mm index e032b63..1da9d4ce 100644 --- a/ui/events/mac/keyboard_hook_mac.mm +++ b/ui/events/mac/keyboard_hook_mac.mm
@@ -9,11 +9,17 @@ namespace ui { // static -std::unique_ptr<KeyboardHook> KeyboardHook::Create( +std::unique_ptr<KeyboardHook> KeyboardHook::CreateModifierKeyboardHook( base::Optional<base::flat_set<DomCode>> dom_codes, gfx::AcceleratedWidget accelerated_widget, KeyEventCallback callback) { return nullptr; } +// static +std::unique_ptr<KeyboardHook> KeyboardHook::CreateMediaKeyboardHook( + KeyEventCallback callback) { + return nullptr; +} + } // namespace ui
diff --git a/ui/events/ozone/keyboard_hook_ozone.cc b/ui/events/ozone/keyboard_hook_ozone.cc index 04a190a3..991b7d720 100644 --- a/ui/events/ozone/keyboard_hook_ozone.cc +++ b/ui/events/ozone/keyboard_hook_ozone.cc
@@ -46,7 +46,7 @@ } // namespace // static -std::unique_ptr<KeyboardHook> KeyboardHook::Create( +std::unique_ptr<KeyboardHook> KeyboardHook::CreateModifierKeyboardHook( base::Optional<base::flat_set<DomCode>> dom_codes, gfx::AcceleratedWidget accelerated_widget, KeyEventCallback callback) { @@ -60,4 +60,10 @@ return keyboard_hook; } +// static +std::unique_ptr<KeyboardHook> KeyboardHook::CreateMediaKeyboardHook( + KeyEventCallback callback) { + return nullptr; +} + } // namespace ui
diff --git a/ui/events/win/keyboard_hook_win.h b/ui/events/win/keyboard_hook_win.h deleted file mode 100644 index 627ba313..0000000 --- a/ui/events/win/keyboard_hook_win.h +++ /dev/null
@@ -1,52 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef UI_EVENTS_WIN_KEYBOARD_HOOK_WIN_H_ -#define UI_EVENTS_WIN_KEYBOARD_HOOK_WIN_H_ - -#include <memory> - -#include <windows.h> - -#include "base/containers/flat_set.h" -#include "base/logging.h" -#include "base/macros.h" -#include "base/optional.h" -#include "ui/events/event.h" -#include "ui/events/events_export.h" -#include "ui/events/keyboard_hook_base.h" -#include "ui/events/keycodes/dom/dom_code.h" - -namespace ui { - -// Exposes a method to drive the Windows KeyboardHook implementation by feeding -// it key event data. This method is used by both the low-level keyboard hook -// and by unit tests which simulate the hooked behavior w/o actually installing -// a hook (doing so would cause problems with test parallelization). -class EVENTS_EXPORT KeyboardHookWin : public KeyboardHookBase { - public: - KeyboardHookWin(base::Optional<base::flat_set<DomCode>> dom_codes, - KeyEventCallback callback); - ~KeyboardHookWin() override; - - // Create a KeyboardHookWin instance which does not register a low-level hook. - static std::unique_ptr<KeyboardHookWin> CreateForTesting( - base::Optional<base::flat_set<DomCode>> dom_codes, - KeyEventCallback callback); - - // Called when a key event message is delivered via the low-level hook. - // Exposed here to allow for testing w/o engaging the low-level hook. - // Returns true if the message was handled. - virtual bool ProcessKeyEventMessage(WPARAM w_param, - DWORD vk, - DWORD scan_code, - DWORD time_stamp) = 0; - - private: - DISALLOW_COPY_AND_ASSIGN(KeyboardHookWin); -}; - -} // namespace ui - -#endif // UI_EVENTS_WIN_KEYBOARD_HOOK_WIN_H_
diff --git a/ui/events/win/keyboard_hook_win_base.cc b/ui/events/win/keyboard_hook_win_base.cc new file mode 100644 index 0000000..1841b06d --- /dev/null +++ b/ui/events/win/keyboard_hook_win_base.cc
@@ -0,0 +1,81 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/events/win/keyboard_hook_win_base.h" + +namespace ui { + +KeyboardHookWinBase::KeyboardHookWinBase( + base::Optional<base::flat_set<DomCode>> dom_codes, + KeyEventCallback callback, + bool enable_hook_registration) + : KeyboardHookBase(std::move(dom_codes), std::move(callback)), + enable_hook_registration_(enable_hook_registration) {} + +KeyboardHookWinBase::~KeyboardHookWinBase() { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + + if (!enable_hook_registration_) + return; + + if (!UnhookWindowsHookEx(hook_)) + DPLOG(ERROR) << "UnhookWindowsHookEx failed"; +} + +bool KeyboardHookWinBase::Register(HOOKPROC hook_proc) { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + + // If the hook was created for testing, |Register()| should not be called. + DCHECK(enable_hook_registration_); + + DCHECK(!hook_); + + // Don't register hooks when there is a debugger to avoid painful user input + // delays. + if (IsDebuggerPresent()) + return false; + + // Per MSDN this Hook procedure will be called in the context of the thread + // which installed it. + hook_ = SetWindowsHookEx(WH_KEYBOARD_LL, hook_proc, + /*hMod=*/nullptr, + /*dwThreadId=*/0); + DPLOG_IF(ERROR, !hook_) << "SetWindowsHookEx failed"; + + return hook_ != nullptr; +} + +// static +LRESULT CALLBACK +KeyboardHookWinBase::ProcessKeyEvent(KeyboardHookWinBase* instance, + int code, + WPARAM w_param, + LPARAM l_param) { + // If there is an error unhooking, this method could be called with a null + // |instance_|. Ensure we have a valid instance and that |code| is correct + // before proceeding. + if (!instance || code != HC_ACTION) + return CallNextHookEx(nullptr, code, w_param, l_param); + + DCHECK_CALLED_ON_VALID_THREAD(instance->thread_checker_); + + KBDLLHOOKSTRUCT* ll_hooks = reinterpret_cast<KBDLLHOOKSTRUCT*>(l_param); + + // This vkey represents both a vkey and a location on the keyboard such as + // VK_LCONTROL or VK_RCONTROL. + DWORD vk = ll_hooks->vkCode; + + // Apply the extended flag prior to passing |scan_code| since |instance_| does + // not have access to the low-level hook flags. + DWORD scan_code = ll_hooks->scanCode; + if (ll_hooks->flags & LLKHF_EXTENDED) + scan_code |= 0xE000; + + if (instance->ProcessKeyEventMessage(w_param, vk, scan_code, ll_hooks->time)) + return 1; + + return CallNextHookEx(nullptr, code, w_param, l_param); +} + +} // namespace ui
diff --git a/ui/events/win/keyboard_hook_win_base.h b/ui/events/win/keyboard_hook_win_base.h new file mode 100644 index 0000000..c9da794a --- /dev/null +++ b/ui/events/win/keyboard_hook_win_base.h
@@ -0,0 +1,74 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_EVENTS_WIN_KEYBOARD_HOOK_WIN_BASE_H_ +#define UI_EVENTS_WIN_KEYBOARD_HOOK_WIN_BASE_H_ + +#include <memory> + +#include <windows.h> + +#include "base/containers/flat_set.h" +#include "base/logging.h" +#include "base/macros.h" +#include "base/optional.h" +#include "base/threading/thread_checker.h" +#include "ui/events/event.h" +#include "ui/events/events_export.h" +#include "ui/events/keyboard_hook_base.h" +#include "ui/events/keycodes/dom/dom_code.h" + +namespace ui { + +// Exposes a method to drive the Windows KeyboardHook implementation by feeding +// it key event data. This method is used by both the low-level keyboard hook +// and by unit tests which simulate the hooked behavior w/o actually installing +// a hook (doing so would cause problems with test parallelization). +class EVENTS_EXPORT KeyboardHookWinBase : public KeyboardHookBase { + public: + KeyboardHookWinBase(base::Optional<base::flat_set<DomCode>> dom_codes, + KeyEventCallback callback, + bool enable_hook_registration); + ~KeyboardHookWinBase() override; + + // Create a KeyboardHookWinBase instance which does not register a + // low-level hook and captures modifier keys. + static std::unique_ptr<KeyboardHookWinBase> + CreateModifierKeyboardHookForTesting( + base::Optional<base::flat_set<DomCode>> dom_codes, + KeyEventCallback callback); + + // Create a KeyboardHookWinBase instance which does not register a + // low-level hook and captures media keys. + static std::unique_ptr<KeyboardHookWinBase> CreateMediaKeyboardHookForTesting( + KeyEventCallback callback); + + // Called when a key event message is delivered via the low-level hook. + // Exposed here to allow for testing w/o engaging the low-level hook. + // Returns true if the message was handled. + virtual bool ProcessKeyEventMessage(WPARAM w_param, + DWORD vk, + DWORD scan_code, + DWORD time_stamp) = 0; + + protected: + bool Register(HOOKPROC hook_proc); + bool enable_hook_registration() const { return enable_hook_registration_; } + + static LRESULT CALLBACK ProcessKeyEvent(KeyboardHookWinBase* instance, + int code, + WPARAM w_param, + LPARAM l_param); + + private: + const bool enable_hook_registration_ = true; + HHOOK hook_ = nullptr; + THREAD_CHECKER(thread_checker_); + + DISALLOW_COPY_AND_ASSIGN(KeyboardHookWinBase); +}; + +} // namespace ui + +#endif // UI_EVENTS_WIN_KEYBOARD_HOOK_WIN_BASE_H_
diff --git a/ui/events/win/media_keyboard_hook_win.cc b/ui/events/win/media_keyboard_hook_win.cc new file mode 100644 index 0000000..141ac572 --- /dev/null +++ b/ui/events/win/media_keyboard_hook_win.cc
@@ -0,0 +1,139 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/events/win/keyboard_hook_win_base.h" + +#include "ui/events/event.h" +#include "ui/events/keycodes/dom/dom_code.h" +#include "ui/events/win/events_win_utils.h" + +namespace ui { + +namespace { + +bool IsMediaKey(DWORD vk) { + return vk == VK_MEDIA_NEXT_TRACK || vk == VK_MEDIA_PREV_TRACK || + vk == VK_MEDIA_PLAY_PAUSE || vk == VK_MEDIA_STOP; +} + +class MediaKeyboardHookWinImpl : public KeyboardHookWinBase { + public: + MediaKeyboardHookWinImpl(KeyEventCallback callback, + bool enable_hook_registration); + ~MediaKeyboardHookWinImpl() override; + + // KeyboardHookWinBase implementation. + bool ProcessKeyEventMessage(WPARAM w_param, + DWORD vk, + DWORD scan_code, + DWORD time_stamp) override; + + bool Register(); + + private: + static LRESULT CALLBACK ProcessKeyEvent(int code, + WPARAM w_param, + LPARAM l_param); + + static MediaKeyboardHookWinImpl* instance_; + + // Tracks the last non-located key down seen in order to determine if the + // current key event should be marked as a repeated key press. + DWORD last_key_down_ = 0; + + DISALLOW_COPY_AND_ASSIGN(MediaKeyboardHookWinImpl); +}; + +// static +MediaKeyboardHookWinImpl* MediaKeyboardHookWinImpl::instance_ = nullptr; + +MediaKeyboardHookWinImpl::MediaKeyboardHookWinImpl( + KeyEventCallback callback, + bool enable_hook_registration) + : KeyboardHookWinBase( + base::Optional<base::flat_set<DomCode>>( + {DomCode::MEDIA_PLAY_PAUSE, DomCode::MEDIA_STOP, + DomCode::MEDIA_TRACK_NEXT, DomCode::MEDIA_TRACK_PREVIOUS}), + std::move(callback), + enable_hook_registration) {} + +MediaKeyboardHookWinImpl::~MediaKeyboardHookWinImpl() { + if (!enable_hook_registration()) + return; + + DCHECK_EQ(instance_, this); + instance_ = nullptr; +} + +bool MediaKeyboardHookWinImpl::Register() { + // Only one instance of this class can be registered at a time. + DCHECK(!instance_); + instance_ = this; + + return KeyboardHookWinBase::Register( + reinterpret_cast<HOOKPROC>(&MediaKeyboardHookWinImpl::ProcessKeyEvent)); +} + +// static +LRESULT CALLBACK MediaKeyboardHookWinImpl::ProcessKeyEvent(int code, + WPARAM w_param, + LPARAM l_param) { + return KeyboardHookWinBase::ProcessKeyEvent(instance_, code, w_param, + l_param); +} + +bool MediaKeyboardHookWinImpl::ProcessKeyEventMessage(WPARAM w_param, + DWORD vk, + DWORD scan_code, + DWORD time_stamp) { + if (!IsMediaKey(vk)) + return false; + + bool is_repeat = false; + MSG msg = {nullptr, w_param, vk, GetLParamFromScanCode(scan_code), + time_stamp}; + EventType event_type = EventTypeFromMSG(msg); + if (event_type == ET_KEY_PRESSED) { + is_repeat = (last_key_down_ == vk); + last_key_down_ = vk; + } else { + DCHECK_EQ(event_type, ET_KEY_RELEASED); + last_key_down_ = 0; + } + + std::unique_ptr<KeyEvent> key_event = + std::make_unique<KeyEvent>(KeyEventFromMSG(msg)); + if (is_repeat) + key_event->set_flags(key_event->flags() | EF_IS_REPEAT); + ForwardCapturedKeyEvent(key_event.get()); + + // If the event is handled, don't propagate to the OS. + return key_event->handled(); +} + +} // namespace + +// static +std::unique_ptr<KeyboardHook> KeyboardHook::CreateMediaKeyboardHook( + KeyEventCallback callback) { + std::unique_ptr<MediaKeyboardHookWinImpl> keyboard_hook = + std::make_unique<MediaKeyboardHookWinImpl>( + std::move(callback), + /*enable_hook_registration=*/true); + + if (!keyboard_hook->Register()) + return nullptr; + + return keyboard_hook; +} + +std::unique_ptr<KeyboardHookWinBase> +KeyboardHookWinBase::CreateMediaKeyboardHookForTesting( + KeyEventCallback callback) { + return std::make_unique<MediaKeyboardHookWinImpl>( + std::move(callback), + /*enable_hook_registration=*/false); +} + +} // namespace ui
diff --git a/ui/events/win/media_keyboard_hook_win_interactive_test.cc b/ui/events/win/media_keyboard_hook_win_interactive_test.cc new file mode 100644 index 0000000..18a2df9 --- /dev/null +++ b/ui/events/win/media_keyboard_hook_win_interactive_test.cc
@@ -0,0 +1,120 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/events/keyboard_hook.h" + +#include "base/bind.h" +#include "base/run_loop.h" +#include "base/test/scoped_task_environment.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/events/event.h" + +namespace ui { + +class MediaKeyboardHookWinInteractiveTest : public testing::Test { + public: + MediaKeyboardHookWinInteractiveTest() + : scoped_task_environment_( + base::test::ScopedTaskEnvironment::MainThreadType::UI) {} + + protected: + void SetUp() override { + keyboard_hook_ = KeyboardHook::CreateMediaKeyboardHook(base::BindRepeating( + &MediaKeyboardHookWinInteractiveTest::HandleKeyEvent, + base::Unretained(this))); + ASSERT_NE(nullptr, keyboard_hook_); + } + + // Loop until we've received |num_events| key events from the hook. + void WaitForKeyEvents(uint32_t num_events) { + if (key_events_.size() >= num_events) + return; + + num_key_events_to_wait_for_ = num_events; + key_event_wait_loop_.Run(); + } + + void SendKeyDown(KeyboardCode code) { + INPUT input; + input.type = INPUT_KEYBOARD; + input.ki.wVk = code; + input.ki.time = time_stamp_++; + input.ki.dwFlags = 0; + SendInput(1, &input, sizeof(INPUT)); + } + + void SendKeyUp(KeyboardCode code) { + INPUT input; + input.type = INPUT_KEYBOARD; + input.ki.wVk = code; + input.ki.time = time_stamp_++; + input.ki.dwFlags = KEYEVENTF_KEYUP; + SendInput(1, &input, sizeof(INPUT)); + } + + // Expect that we have received the correct number of key events. + void ExpectReceivedEventsCount(uint32_t count) { + EXPECT_EQ(count, key_events_.size()); + } + + // Expect that the key event received at |index| has the specified key code + // and type. + void ExpectReceivedEvent(uint32_t index, KeyboardCode code, EventType type) { + ASSERT_LT(index, key_events_.size()); + KeyEvent* key_event = &key_events_.at(index); + EXPECT_EQ(code, key_event->key_code()); + EXPECT_EQ(type, key_event->type()); + } + + private: + void HandleKeyEvent(KeyEvent* key_event) { + key_events_.push_back(*key_event); + key_event->SetHandled(); + + // If we've received the events we're waiting for, stop waiting. + if (key_event_wait_loop_.running() && + key_events_.size() >= num_key_events_to_wait_for_) { + key_event_wait_loop_.Quit(); + } + } + + std::vector<KeyEvent> key_events_; + std::unique_ptr<KeyboardHook> keyboard_hook_; + base::test::ScopedTaskEnvironment scoped_task_environment_; + base::RunLoop key_event_wait_loop_; + uint32_t num_key_events_to_wait_for_ = 0; + DWORD time_stamp_ = 0; + + DISALLOW_COPY_AND_ASSIGN(MediaKeyboardHookWinInteractiveTest); +}; + +// Test that we catch the different media key events. +TEST_F(MediaKeyboardHookWinInteractiveTest, AllMediaKeysAreCaught) { + SendKeyDown(ui::VKEY_MEDIA_PLAY_PAUSE); + SendKeyUp(ui::VKEY_MEDIA_PLAY_PAUSE); + SendKeyDown(ui::VKEY_MEDIA_STOP); + SendKeyUp(ui::VKEY_MEDIA_STOP); + SendKeyDown(ui::VKEY_MEDIA_NEXT_TRACK); + SendKeyUp(ui::VKEY_MEDIA_NEXT_TRACK); + SendKeyDown(ui::VKEY_MEDIA_PREV_TRACK); + SendKeyUp(ui::VKEY_MEDIA_PREV_TRACK); + + // We should receive 8 different key events. + WaitForKeyEvents(8); +} + +// Test that the received events have the proper state. +TEST_F(MediaKeyboardHookWinInteractiveTest, CallbackReceivesProperEvents) { + // Send a key down event and validate it when received through the hook. + SendKeyDown(ui::VKEY_MEDIA_PLAY_PAUSE); + WaitForKeyEvents(1); + ExpectReceivedEvent(/*index=*/0, ui::VKEY_MEDIA_PLAY_PAUSE, ET_KEY_PRESSED); + + // Send a key up event and validate it when received through the hook. + SendKeyUp(ui::VKEY_MEDIA_PLAY_PAUSE); + WaitForKeyEvents(2); + ExpectReceivedEvent(/*index=*/1, ui::VKEY_MEDIA_PLAY_PAUSE, ET_KEY_RELEASED); +} + +} // namespace ui \ No newline at end of file
diff --git a/ui/events/win/media_keyboard_hook_win_unittest.cc b/ui/events/win/media_keyboard_hook_win_unittest.cc new file mode 100644 index 0000000..d043877 --- /dev/null +++ b/ui/events/win/media_keyboard_hook_win_unittest.cc
@@ -0,0 +1,206 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <memory> +#include <vector> + +#include "base/bind.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/events/event.h" +#include "ui/events/keyboard_hook.h" +#include "ui/events/keycodes/dom/dom_code.h" +#include "ui/events/keycodes/dom/keycode_converter.h" +#include "ui/events/keycodes/keyboard_codes.h" +#include "ui/events/win/keyboard_hook_win_base.h" + +namespace ui { + +class MediaKeyboardHookWinTest : public testing::Test { + public: + MediaKeyboardHookWinTest(); + ~MediaKeyboardHookWinTest() override; + + // testing::Test overrides. + void SetUp() override; + + void HandleKeyPress(KeyEvent* key_event); + + protected: + KeyboardHookWinBase* keyboard_hook() { return keyboard_hook_.get(); } + + uint32_t next_time_stamp() { return time_stamp_++; } + + std::vector<KeyEvent>* key_events() { return &key_events_; } + + // Used for sending key events which are handled by the hook. + void SendMediaKeyDownEvent(KeyboardCode key_code, + DomCode dom_code, + int repeat_count = 1); + void SendMediaKeyUpEvent(KeyboardCode key_code, DomCode dom_code); + + // Set the return value for the HandleKeyPress callback. + void StartHandlingKeys() { should_handle_keys_ = true; } + void StopHandlingKeys() { should_handle_keys_ = false; } + + private: + uint32_t time_stamp_ = 0; + std::unique_ptr<KeyboardHookWinBase> keyboard_hook_; + std::vector<KeyEvent> key_events_; + bool should_handle_keys_ = true; + + DISALLOW_COPY_AND_ASSIGN(MediaKeyboardHookWinTest); +}; + +MediaKeyboardHookWinTest::MediaKeyboardHookWinTest() = default; + +MediaKeyboardHookWinTest::~MediaKeyboardHookWinTest() = default; + +void MediaKeyboardHookWinTest::SetUp() { + keyboard_hook_ = KeyboardHookWinBase::CreateMediaKeyboardHookForTesting( + base::BindRepeating(&MediaKeyboardHookWinTest::HandleKeyPress, + base::Unretained(this))); +} + +void MediaKeyboardHookWinTest::HandleKeyPress(KeyEvent* key_event) { + key_events_.push_back(*key_event); + if (should_handle_keys_) + key_event->SetHandled(); +} + +void MediaKeyboardHookWinTest::SendMediaKeyDownEvent(KeyboardCode key_code, + DomCode dom_code, + int repeat_count /*=1*/) { + ASSERT_GT(repeat_count, 0); + // This should only be used when we're handling keys. + ASSERT_TRUE(should_handle_keys_); + + for (int i = 0; i < repeat_count; i++) { + ASSERT_TRUE(keyboard_hook()->ProcessKeyEventMessage( + WM_KEYDOWN, key_code, + KeycodeConverter::DomCodeToNativeKeycode(dom_code), next_time_stamp())); + } +} + +void MediaKeyboardHookWinTest::SendMediaKeyUpEvent(KeyboardCode key_code, + DomCode dom_code) { + // This should only be used when we're handling keys. + ASSERT_TRUE(should_handle_keys_); + + ASSERT_TRUE(keyboard_hook()->ProcessKeyEventMessage( + WM_KEYUP, key_code, KeycodeConverter::DomCodeToNativeKeycode(dom_code), + next_time_stamp())); +} + +void VerifyKeyEvent(KeyEvent* key_event, + KeyboardCode non_located_key_code, + DomCode dom_code, + bool key_down, + bool is_repeat) { + if (key_down) { + ASSERT_EQ(key_event->type(), ET_KEY_PRESSED); + ASSERT_EQ(key_event->is_repeat(), is_repeat); + } else { + ASSERT_EQ(key_event->type(), ET_KEY_RELEASED); + ASSERT_FALSE(key_event->is_repeat()); + } + ASSERT_EQ(key_event->key_code(), non_located_key_code); + ASSERT_EQ(key_event->code(), dom_code); +} + +TEST_F(MediaKeyboardHookWinTest, SimpleKeypressTest) { + const KeyboardCode key_code = KeyboardCode::VKEY_MEDIA_PLAY_PAUSE; + const DomCode dom_code = DomCode::MEDIA_PLAY_PAUSE; + SendMediaKeyDownEvent(key_code, dom_code); + ASSERT_EQ(key_events()->size(), 1u); + SendMediaKeyUpEvent(key_code, dom_code); + ASSERT_EQ(key_events()->size(), 2u); + + KeyEvent down_event = key_events()->at(0); + ASSERT_NO_FATAL_FAILURE( + VerifyKeyEvent(&down_event, key_code, dom_code, true, false)); + + KeyEvent up_event = key_events()->at(1); + ASSERT_NO_FATAL_FAILURE( + VerifyKeyEvent(&up_event, key_code, dom_code, false, false)); +} + +TEST_F(MediaKeyboardHookWinTest, RepeatingKeypressTest) { + const int repeat_count = 10; + const KeyboardCode key_code = KeyboardCode::VKEY_MEDIA_PLAY_PAUSE; + const DomCode dom_code = DomCode::MEDIA_PLAY_PAUSE; + SendMediaKeyDownEvent(key_code, dom_code, repeat_count); + ASSERT_EQ(static_cast<int>(key_events()->size()), repeat_count); + SendMediaKeyUpEvent(key_code, dom_code); + ASSERT_EQ(static_cast<int>(key_events()->size()), repeat_count + 1); + + bool should_repeat = false; + for (int i = 0; i < repeat_count; i++) { + KeyEvent event = key_events()->at(i); + ASSERT_NO_FATAL_FAILURE( + VerifyKeyEvent(&event, key_code, dom_code, true, should_repeat)); + should_repeat = true; + } + + KeyEvent up_event = key_events()->at(repeat_count); + ASSERT_NO_FATAL_FAILURE( + VerifyKeyEvent(&up_event, key_code, dom_code, false, false)); +} + +TEST_F(MediaKeyboardHookWinTest, UnhandledKeysArePropagated) { + StopHandlingKeys(); + + // Ensure media keys are propagated to the OS. + ASSERT_FALSE(keyboard_hook()->ProcessKeyEventMessage( + WM_KEYDOWN, KeyboardCode::VKEY_MEDIA_STOP, + KeycodeConverter::DomCodeToNativeKeycode(DomCode::MEDIA_STOP), + next_time_stamp())); + ASSERT_FALSE(keyboard_hook()->ProcessKeyEventMessage( + WM_KEYUP, KeyboardCode::VKEY_MEDIA_STOP, + KeycodeConverter::DomCodeToNativeKeycode(DomCode::MEDIA_STOP), + next_time_stamp())); + + StartHandlingKeys(); + + // Ensure media keys are not propagated to the OS. + ASSERT_TRUE(keyboard_hook()->ProcessKeyEventMessage( + WM_KEYDOWN, KeyboardCode::VKEY_MEDIA_STOP, + KeycodeConverter::DomCodeToNativeKeycode(DomCode::MEDIA_STOP), + next_time_stamp())); + ASSERT_TRUE(keyboard_hook()->ProcessKeyEventMessage( + WM_KEYUP, KeyboardCode::VKEY_MEDIA_STOP, + KeycodeConverter::DomCodeToNativeKeycode(DomCode::MEDIA_STOP), + next_time_stamp())); +} + +TEST_F(MediaKeyboardHookWinTest, NonInterceptedKeysTest) { + // Here we try a few keys we do not expect to be intercepted / handled. + ASSERT_FALSE(keyboard_hook()->ProcessKeyEventMessage( + WM_KEYDOWN, KeyboardCode::VKEY_RSHIFT, + KeycodeConverter::DomCodeToNativeKeycode(DomCode::SHIFT_RIGHT), + next_time_stamp())); + ASSERT_FALSE(keyboard_hook()->ProcessKeyEventMessage( + WM_KEYUP, KeyboardCode::VKEY_RSHIFT, + KeycodeConverter::DomCodeToNativeKeycode(DomCode::SHIFT_RIGHT), + next_time_stamp())); + + ASSERT_FALSE(keyboard_hook()->ProcessKeyEventMessage( + WM_KEYDOWN, KeyboardCode::VKEY_ESCAPE, + KeycodeConverter::DomCodeToNativeKeycode(DomCode::ESCAPE), + next_time_stamp())); + ASSERT_FALSE(keyboard_hook()->ProcessKeyEventMessage( + WM_KEYUP, KeyboardCode::VKEY_ESCAPE, + KeycodeConverter::DomCodeToNativeKeycode(DomCode::ESCAPE), + next_time_stamp())); + + ASSERT_FALSE(keyboard_hook()->ProcessKeyEventMessage( + WM_KEYDOWN, KeyboardCode::VKEY_A, + KeycodeConverter::DomCodeToNativeKeycode(DomCode::US_A), + next_time_stamp())); + ASSERT_FALSE(keyboard_hook()->ProcessKeyEventMessage( + WM_KEYUP, KeyboardCode::VKEY_A, + KeycodeConverter::DomCodeToNativeKeycode(DomCode::US_A), + next_time_stamp())); +} + +} // namespace ui
diff --git a/ui/events/win/keyboard_hook_win.cc b/ui/events/win/modifier_keyboard_hook_win.cc similarity index 73% rename from ui/events/win/keyboard_hook_win.cc rename to ui/events/win/modifier_keyboard_hook_win.cc index 042e2956..f1f5af4 100644 --- a/ui/events/win/keyboard_hook_win.cc +++ b/ui/events/win/modifier_keyboard_hook_win.cc
@@ -2,14 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "ui/events/win/keyboard_hook_win.h" +#include "ui/events/win/keyboard_hook_win_base.h" #include <utility> #include "base/logging.h" #include "base/macros.h" #include "base/optional.h" -#include "base/threading/thread_checker.h" #include "ui/events/event.h" #include "ui/events/event_utils.h" #include "ui/events/keycodes/dom/dom_code.h" @@ -108,14 +107,14 @@ return IsAltKey(vk) || IsControlKey(vk) || IsWindowsKey(vk); } -class KeyboardHookWinImpl : public KeyboardHookWin { +class ModifierKeyboardHookWinImpl : public KeyboardHookWinBase { public: - KeyboardHookWinImpl(base::Optional<base::flat_set<DomCode>> dom_codes, - KeyEventCallback callback, - bool enable_hook_registration); - ~KeyboardHookWinImpl() override; + ModifierKeyboardHookWinImpl(base::Optional<base::flat_set<DomCode>> dom_codes, + KeyEventCallback callback, + bool enable_hook_registration); + ~ModifierKeyboardHookWinImpl() override; - // KeyboardHookWin implementation. + // KeyboardHookWinBase implementation. bool ProcessKeyEventMessage(WPARAM w_param, DWORD vk, DWORD scan_code, @@ -132,11 +131,7 @@ void ClearModifierStates(); - static KeyboardHookWinImpl* instance_; - - THREAD_CHECKER(thread_checker_); - - HHOOK hook_ = nullptr; + static ModifierKeyboardHookWinImpl* instance_; // Tracks the last non-located key down seen in order to determine if the // current key event should be marked as a repeated key press. @@ -148,59 +143,40 @@ // This sequence occurs on the initial keypress and every repeat. int altgr_sequence_count_ = 0; - const bool enable_hook_registration_ = true; - - DISALLOW_COPY_AND_ASSIGN(KeyboardHookWinImpl); + DISALLOW_COPY_AND_ASSIGN(ModifierKeyboardHookWinImpl); }; // static -KeyboardHookWinImpl* KeyboardHookWinImpl::instance_ = nullptr; +ModifierKeyboardHookWinImpl* ModifierKeyboardHookWinImpl::instance_ = nullptr; -KeyboardHookWinImpl::KeyboardHookWinImpl( +ModifierKeyboardHookWinImpl::ModifierKeyboardHookWinImpl( base::Optional<base::flat_set<DomCode>> dom_codes, KeyEventCallback callback, bool enable_hook_registration) - : KeyboardHookWin(std::move(dom_codes), std::move(callback)), - enable_hook_registration_(enable_hook_registration) {} + : KeyboardHookWinBase(std::move(dom_codes), + std::move(callback), + enable_hook_registration) {} -KeyboardHookWinImpl::~KeyboardHookWinImpl() { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - +ModifierKeyboardHookWinImpl::~ModifierKeyboardHookWinImpl() { ClearModifierStates(); - if (!enable_hook_registration_) + if (!enable_hook_registration()) return; DCHECK_EQ(instance_, this); instance_ = nullptr; - - if (!UnhookWindowsHookEx(hook_)) - DPLOG(ERROR) << "UnhookWindowsHookEx failed"; } -bool KeyboardHookWinImpl::Register() { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - - // If the hook was created for testing, |Register()| should not be called. - DCHECK(enable_hook_registration_); - +bool ModifierKeyboardHookWinImpl::Register() { // Only one instance of this class can be registered at a time. DCHECK(!instance_); instance_ = this; - // Per MSDN this Hook procedure will be called in the context of the thread - // which installed it. - hook_ = SetWindowsHookEx( - WH_KEYBOARD_LL, - reinterpret_cast<HOOKPROC>(&KeyboardHookWinImpl::ProcessKeyEvent), - /*hMod=*/nullptr, - /*dwThreadId=*/0); - DPLOG_IF(ERROR, !hook_) << "SetWindowsHookEx failed"; - - return hook_ != nullptr; + return KeyboardHookWinBase::Register(reinterpret_cast<HOOKPROC>( + &ModifierKeyboardHookWinImpl::ProcessKeyEvent)); } -void KeyboardHookWinImpl::ClearModifierStates() { +void ModifierKeyboardHookWinImpl::ClearModifierStates() { BYTE keyboard_state[kKeyboardStateArraySize] = {0}; if (!GetKeyboardState(keyboard_state)) { DPLOG(ERROR) << "GetKeyboardState() failed: "; @@ -221,10 +197,10 @@ DPLOG(ERROR) << "SetKeyboardState() failed: "; } -bool KeyboardHookWinImpl::ProcessKeyEventMessage(WPARAM w_param, - DWORD vk, - DWORD scan_code, - DWORD time_stamp) { +bool ModifierKeyboardHookWinImpl::ProcessKeyEventMessage(WPARAM w_param, + DWORD vk, + DWORD scan_code, + DWORD time_stamp) { // The |vk| delivered to the low-level hook includes a location which is // needed to track individual keystates such as when both left and right // control keys are pressed. Make sure that location information was retained @@ -288,12 +264,13 @@ std::make_unique<KeyEvent>(KeyEventFromMSG(msg)); if (is_repeat) key_event->set_flags(key_event->flags() | EF_IS_REPEAT); - ForwardCapturedKeyEvent(std::move(key_event)); + ForwardCapturedKeyEvent(key_event.get()); return true; } -void KeyboardHookWinImpl::UpdateModifierState(DWORD vk, bool is_key_down) { +void ModifierKeyboardHookWinImpl::UpdateModifierState(DWORD vk, + bool is_key_down) { BYTE keyboard_state[kKeyboardStateArraySize] = {0}; if (!GetKeyboardState(keyboard_state)) { DPLOG(ERROR) << "GetKeyboardState() failed: "; @@ -318,46 +295,24 @@ } // static -LRESULT CALLBACK KeyboardHookWinImpl::ProcessKeyEvent(int code, - WPARAM w_param, - LPARAM l_param) { - // If there is an error unhooking, this method could be called with a null - // |instance_|. Ensure we have a valid instance and that |code| is correct - // before proceeding. - if (!instance_ || code != HC_ACTION) - return CallNextHookEx(nullptr, code, w_param, l_param); - - DCHECK_CALLED_ON_VALID_THREAD(instance_->thread_checker_); - - KBDLLHOOKSTRUCT* ll_hooks = reinterpret_cast<KBDLLHOOKSTRUCT*>(l_param); - - // This vkey represents both a vkey and a location on the keyboard such as - // VK_LCONTROL or VK_RCONTROL. - DWORD vk = ll_hooks->vkCode; - - // Apply the extended flag prior to passing |scan_code| since |instance_| does - // not have access to the low-level hook flags. - DWORD scan_code = ll_hooks->scanCode; - if (ll_hooks->flags & LLKHF_EXTENDED) - scan_code |= 0xE000; - - if (instance_->ProcessKeyEventMessage(w_param, vk, scan_code, ll_hooks->time)) - return 1; - - return CallNextHookEx(nullptr, code, w_param, l_param); +LRESULT CALLBACK ModifierKeyboardHookWinImpl::ProcessKeyEvent(int code, + WPARAM w_param, + LPARAM l_param) { + return KeyboardHookWinBase::ProcessKeyEvent(instance_, code, w_param, + l_param); } } // namespace // static -std::unique_ptr<KeyboardHook> KeyboardHook::Create( +std::unique_ptr<KeyboardHook> KeyboardHook::CreateModifierKeyboardHook( base::Optional<base::flat_set<DomCode>> dom_codes, gfx::AcceleratedWidget accelerated_widget, KeyEventCallback callback) { - std::unique_ptr<KeyboardHookWinImpl> keyboard_hook = - std::make_unique<KeyboardHookWinImpl>(std::move(dom_codes), - std::move(callback), - /*enable_hook_registration=*/true); + std::unique_ptr<ModifierKeyboardHookWinImpl> keyboard_hook = + std::make_unique<ModifierKeyboardHookWinImpl>( + std::move(dom_codes), std::move(callback), + /*enable_hook_registration=*/true); if (!keyboard_hook->Register()) return nullptr; @@ -365,19 +320,13 @@ return keyboard_hook; } -std::unique_ptr<KeyboardHookWin> KeyboardHookWin::CreateForTesting( +std::unique_ptr<KeyboardHookWinBase> +KeyboardHookWinBase::CreateModifierKeyboardHookForTesting( base::Optional<base::flat_set<DomCode>> dom_codes, KeyEventCallback callback) { - return std::make_unique<KeyboardHookWinImpl>( + return std::make_unique<ModifierKeyboardHookWinImpl>( std::move(dom_codes), std::move(callback), /*enable_hook_registration=*/false); } -KeyboardHookWin::KeyboardHookWin( - base::Optional<base::flat_set<DomCode>> dom_codes, - KeyEventCallback callback) - : KeyboardHookBase(std::move(dom_codes), std::move(callback)) {} - -KeyboardHookWin::~KeyboardHookWin() = default; - } // namespace ui
diff --git a/ui/events/win/keyboard_hook_win_unittest.cc b/ui/events/win/modifier_keyboard_hook_win_unittest.cc similarity index 93% rename from ui/events/win/keyboard_hook_win_unittest.cc rename to ui/events/win/modifier_keyboard_hook_win_unittest.cc index d8f3dea..ff1dcf4a1 100644 --- a/ui/events/win/keyboard_hook_win_unittest.cc +++ b/ui/events/win/modifier_keyboard_hook_win_unittest.cc
@@ -15,15 +15,15 @@ #include "ui/events/keycodes/dom/keycode_converter.h" #include "ui/events/keycodes/keyboard_codes.h" #include "ui/events/test/keyboard_layout.h" -#include "ui/events/win/keyboard_hook_win.h" +#include "ui/events/win/keyboard_hook_win_base.h" #include "ui/events/win/system_event_state_lookup.h" namespace ui { -class KeyboardHookWinTest : public testing::Test { +class ModifierKeyboardHookWinTest : public testing::Test { public: - KeyboardHookWinTest(); - ~KeyboardHookWinTest() override; + ModifierKeyboardHookWinTest(); + ~ModifierKeyboardHookWinTest() override; // testing::Test overrides. void SetUp() override; @@ -31,7 +31,7 @@ void HandleKeyPress(KeyEvent* key_event); protected: - KeyboardHookWin* keyboard_hook() { return keyboard_hook_.get(); } + KeyboardHookWinBase* keyboard_hook() { return keyboard_hook_.get(); } uint32_t next_time_stamp() { return time_stamp_++; } @@ -47,34 +47,35 @@ private: uint32_t time_stamp_ = 0; - std::unique_ptr<KeyboardHookWin> keyboard_hook_; + std::unique_ptr<KeyboardHookWinBase> keyboard_hook_; std::vector<KeyEvent> key_events_; std::unique_ptr<ScopedKeyboardLayout> keyboard_layout_; - DISALLOW_COPY_AND_ASSIGN(KeyboardHookWinTest); + DISALLOW_COPY_AND_ASSIGN(ModifierKeyboardHookWinTest); }; -KeyboardHookWinTest::KeyboardHookWinTest() = default; +ModifierKeyboardHookWinTest::ModifierKeyboardHookWinTest() = default; -KeyboardHookWinTest::~KeyboardHookWinTest() = default; +ModifierKeyboardHookWinTest::~ModifierKeyboardHookWinTest() = default; -void KeyboardHookWinTest::SetUp() { - keyboard_hook_ = KeyboardHookWin::CreateForTesting( +void ModifierKeyboardHookWinTest::SetUp() { + keyboard_hook_ = KeyboardHookWinBase::CreateModifierKeyboardHookForTesting( base::Optional<base::flat_set<DomCode>>(), - base::BindRepeating(&KeyboardHookWinTest::HandleKeyPress, + base::BindRepeating(&ModifierKeyboardHookWinTest::HandleKeyPress, base::Unretained(this))); keyboard_layout_ = std::make_unique<ScopedKeyboardLayout>( KeyboardLayout::KEYBOARD_LAYOUT_ENGLISH_US); } -void KeyboardHookWinTest::HandleKeyPress(KeyEvent* key_event) { +void ModifierKeyboardHookWinTest::HandleKeyPress(KeyEvent* key_event) { key_events_.push_back(*key_event); } -void KeyboardHookWinTest::SendModifierKeyDownEvent(KeyboardCode key_code, - DomCode dom_code, - int repeat_count /*=1*/) { +void ModifierKeyboardHookWinTest::SendModifierKeyDownEvent( + KeyboardCode key_code, + DomCode dom_code, + int repeat_count /*=1*/) { // Ensure we have a valid repeat count and the modifer passed in contains // location information. DCHECK_GT(repeat_count, 0); @@ -88,8 +89,8 @@ } } -void KeyboardHookWinTest::SendModifierKeyUpEvent(KeyboardCode key_code, - DomCode dom_code) { +void ModifierKeyboardHookWinTest::SendModifierKeyUpEvent(KeyboardCode key_code, + DomCode dom_code) { // Ensure we have a valid repeat count and the modifer passed in contains // location information. DCHECK_NE(key_code, KeyboardCode::VKEY_CONTROL); @@ -116,7 +117,7 @@ ASSERT_EQ(key_event->code(), dom_code); } -TEST_F(KeyboardHookWinTest, SimpleLeftControlKeypressTest) { +TEST_F(ModifierKeyboardHookWinTest, SimpleLeftControlKeypressTest) { const KeyboardCode key_code = KeyboardCode::VKEY_LCONTROL; const DomCode dom_code = DomCode::CONTROL_LEFT; SendModifierKeyDownEvent(key_code, dom_code); @@ -136,7 +137,7 @@ ASSERT_FALSE(up_event.IsControlDown()); } -TEST_F(KeyboardHookWinTest, RepeatingLeftControlKeypressTest) { +TEST_F(ModifierKeyboardHookWinTest, RepeatingLeftControlKeypressTest) { const int repeat_count = 10; const KeyboardCode key_code = KeyboardCode::VKEY_LCONTROL; const DomCode dom_code = DomCode::CONTROL_LEFT; @@ -161,7 +162,7 @@ ASSERT_FALSE(up_event.IsControlDown()); } -TEST_F(KeyboardHookWinTest, SimpleRightControlKeypressTest) { +TEST_F(ModifierKeyboardHookWinTest, SimpleRightControlKeypressTest) { const KeyboardCode key_code = KeyboardCode::VKEY_RCONTROL; const DomCode dom_code = DomCode::CONTROL_RIGHT; SendModifierKeyDownEvent(key_code, dom_code); @@ -181,7 +182,7 @@ ASSERT_FALSE(up_event.IsControlDown()); } -TEST_F(KeyboardHookWinTest, RepeatingRightControlKeypressTest) { +TEST_F(ModifierKeyboardHookWinTest, RepeatingRightControlKeypressTest) { const int repeat_count = 10; const KeyboardCode key_code = KeyboardCode::VKEY_RCONTROL; const DomCode dom_code = DomCode::CONTROL_RIGHT; @@ -206,7 +207,7 @@ ASSERT_FALSE(up_event.IsControlDown()); } -TEST_F(KeyboardHookWinTest, SimpleLifoControlSequenceTest) { +TEST_F(ModifierKeyboardHookWinTest, SimpleLifoControlSequenceTest) { const KeyboardCode left_key_code = KeyboardCode::VKEY_LCONTROL; const DomCode left_dom_code = DomCode::CONTROL_LEFT; const KeyboardCode right_key_code = KeyboardCode::VKEY_RCONTROL; @@ -253,7 +254,7 @@ ASSERT_FALSE(event.IsControlDown()); } -TEST_F(KeyboardHookWinTest, SimpleFifoControlSequenceTest) { +TEST_F(ModifierKeyboardHookWinTest, SimpleFifoControlSequenceTest) { const KeyboardCode left_key_code = KeyboardCode::VKEY_LCONTROL; const DomCode left_dom_code = DomCode::CONTROL_LEFT; const KeyboardCode right_key_code = KeyboardCode::VKEY_RCONTROL; @@ -299,7 +300,7 @@ ASSERT_FALSE(event.IsControlDown()); } -TEST_F(KeyboardHookWinTest, SimpleLeftAltKeypressTest) { +TEST_F(ModifierKeyboardHookWinTest, SimpleLeftAltKeypressTest) { const KeyboardCode key_code = KeyboardCode::VKEY_LMENU; const DomCode dom_code = DomCode::ALT_LEFT; SendModifierKeyDownEvent(key_code, dom_code); @@ -318,7 +319,7 @@ ASSERT_FALSE(up_event.IsAltDown()); } -TEST_F(KeyboardHookWinTest, RepeatingLeftAltKeypressTest) { +TEST_F(ModifierKeyboardHookWinTest, RepeatingLeftAltKeypressTest) { const int repeat_count = 10; const KeyboardCode key_code = KeyboardCode::VKEY_LMENU; const DomCode dom_code = DomCode::ALT_LEFT; @@ -343,7 +344,7 @@ ASSERT_FALSE(up_event.IsAltDown()); } -TEST_F(KeyboardHookWinTest, SimpleRightAltKeypressTest) { +TEST_F(ModifierKeyboardHookWinTest, SimpleRightAltKeypressTest) { const KeyboardCode key_code = KeyboardCode::VKEY_RMENU; const DomCode dom_code = DomCode::ALT_LEFT; SendModifierKeyDownEvent(key_code, dom_code); @@ -362,7 +363,7 @@ ASSERT_FALSE(up_event.IsAltDown()); } -TEST_F(KeyboardHookWinTest, RepeatingRightAltKeypressTest) { +TEST_F(ModifierKeyboardHookWinTest, RepeatingRightAltKeypressTest) { const int repeat_count = 10; const KeyboardCode key_code = KeyboardCode::VKEY_RMENU; const DomCode dom_code = DomCode::ALT_RIGHT; @@ -387,7 +388,7 @@ ASSERT_FALSE(up_event.IsAltDown()); } -TEST_F(KeyboardHookWinTest, SimpleLifoAltSequenceTest) { +TEST_F(ModifierKeyboardHookWinTest, SimpleLifoAltSequenceTest) { const KeyboardCode left_key_code = KeyboardCode::VKEY_LMENU; const DomCode left_dom_code = DomCode::ALT_LEFT; const KeyboardCode right_key_code = KeyboardCode::VKEY_RMENU; @@ -429,7 +430,7 @@ ASSERT_FALSE(event.IsAltDown()); } -TEST_F(KeyboardHookWinTest, SimpleFifoAltSequenceTest) { +TEST_F(ModifierKeyboardHookWinTest, SimpleFifoAltSequenceTest) { const KeyboardCode left_key_code = KeyboardCode::VKEY_LMENU; const DomCode left_dom_code = DomCode::ALT_LEFT; const KeyboardCode right_key_code = KeyboardCode::VKEY_RMENU; @@ -471,7 +472,7 @@ ASSERT_FALSE(event.IsAltDown()); } -TEST_F(KeyboardHookWinTest, SimpleLeftWinKeypressTest) { +TEST_F(ModifierKeyboardHookWinTest, SimpleLeftWinKeypressTest) { const KeyboardCode key_code = KeyboardCode::VKEY_LWIN; const DomCode dom_code = DomCode::META_LEFT; SendModifierKeyDownEvent(key_code, dom_code); @@ -491,7 +492,7 @@ ASSERT_FALSE(up_event.IsCommandDown()); } -TEST_F(KeyboardHookWinTest, RepeatingLeftWinKeypressTest) { +TEST_F(ModifierKeyboardHookWinTest, RepeatingLeftWinKeypressTest) { const int repeat_count = 10; const KeyboardCode key_code = KeyboardCode::VKEY_LWIN; const DomCode dom_code = DomCode::META_LEFT; @@ -517,7 +518,7 @@ ASSERT_FALSE(up_event.IsCommandDown()); } -TEST_F(KeyboardHookWinTest, SimpleRightWinKeypressTest) { +TEST_F(ModifierKeyboardHookWinTest, SimpleRightWinKeypressTest) { const KeyboardCode key_code = KeyboardCode::VKEY_RWIN; const DomCode dom_code = DomCode::META_RIGHT; SendModifierKeyDownEvent(key_code, dom_code); @@ -537,7 +538,7 @@ ASSERT_FALSE(up_event.IsCommandDown()); } -TEST_F(KeyboardHookWinTest, RepeatingRightWinKeypressTest) { +TEST_F(ModifierKeyboardHookWinTest, RepeatingRightWinKeypressTest) { const int repeat_count = 10; const KeyboardCode key_code = KeyboardCode::VKEY_RWIN; const DomCode dom_code = DomCode::META_RIGHT; @@ -563,7 +564,7 @@ ASSERT_FALSE(up_event.IsCommandDown()); } -TEST_F(KeyboardHookWinTest, SimpleLifoWinSequenceTest) { +TEST_F(ModifierKeyboardHookWinTest, SimpleLifoWinSequenceTest) { const KeyboardCode left_key_code = KeyboardCode::VKEY_LWIN; const DomCode left_dom_code = DomCode::META_LEFT; const KeyboardCode right_key_code = KeyboardCode::VKEY_RWIN; @@ -605,7 +606,7 @@ ASSERT_FALSE(event.IsCommandDown()); } -TEST_F(KeyboardHookWinTest, SimpleFifoWinSequenceTest) { +TEST_F(ModifierKeyboardHookWinTest, SimpleFifoWinSequenceTest) { const KeyboardCode left_key_code = KeyboardCode::VKEY_LWIN; const DomCode left_dom_code = DomCode::META_LEFT; const KeyboardCode right_key_code = KeyboardCode::VKEY_RWIN; @@ -647,7 +648,7 @@ ASSERT_FALSE(event.IsCommandDown()); } -TEST_F(KeyboardHookWinTest, CombinedModifierLifoSequenceKeypressTest) { +TEST_F(ModifierKeyboardHookWinTest, CombinedModifierLifoSequenceKeypressTest) { const KeyboardCode first_key_code = KeyboardCode::VKEY_LCONTROL; const DomCode first_dom_code = DomCode::CONTROL_LEFT; const KeyboardCode second_key_code = KeyboardCode::VKEY_RWIN; @@ -730,7 +731,7 @@ ASSERT_FALSE(event.IsCommandDown()); } -TEST_F(KeyboardHookWinTest, CombinedModifierFifoSequenceKeypressTest) { +TEST_F(ModifierKeyboardHookWinTest, CombinedModifierFifoSequenceKeypressTest) { const KeyboardCode first_key_code = KeyboardCode::VKEY_RCONTROL; const DomCode first_dom_code = DomCode::CONTROL_RIGHT; const KeyboardCode second_key_code = KeyboardCode::VKEY_LWIN; @@ -813,7 +814,7 @@ ASSERT_FALSE(event.IsCommandDown()); } -TEST_F(KeyboardHookWinTest, VerifyPlatformModifierStateTest) { +TEST_F(ModifierKeyboardHookWinTest, VerifyPlatformModifierStateTest) { SendModifierKeyDownEvent(KeyboardCode::VKEY_LCONTROL, DomCode::CONTROL_LEFT); ASSERT_TRUE(win::IsCtrlPressed()); ASSERT_FALSE(win::IsAltPressed()); @@ -850,7 +851,7 @@ ASSERT_TRUE(win::IsAltRightPressed()); } -TEST_F(KeyboardHookWinTest, SimpleAltGrKeyPressTest) { +TEST_F(ModifierKeyboardHookWinTest, SimpleAltGrKeyPressTest) { ScopedKeyboardLayout keyboard_layout(KeyboardLayout::KEYBOARD_LAYOUT_GERMAN); // AltGr produces two events, an injected, modified scan code for VK_LCONTROL, @@ -909,7 +910,7 @@ ASSERT_FALSE(event.IsCommandDown()); } -TEST_F(KeyboardHookWinTest, RepeatingAltGrKeyPressTest) { +TEST_F(ModifierKeyboardHookWinTest, RepeatingAltGrKeyPressTest) { ScopedKeyboardLayout keyboard_layout(KeyboardLayout::KEYBOARD_LAYOUT_GERMAN); // AltGr produces two events, an injected, modified scan code for VK_LCONTROL, @@ -1010,7 +1011,7 @@ ASSERT_FALSE(event.IsCommandDown()); } -TEST_F(KeyboardHookWinTest, VerifyAltGrPlatformModifierStateTest) { +TEST_F(ModifierKeyboardHookWinTest, VerifyAltGrPlatformModifierStateTest) { ScopedKeyboardLayout keyboard_layout(KeyboardLayout::KEYBOARD_LAYOUT_GERMAN); // AltGr produces two events, an injected, modified scan code for VK_LCONTROL, @@ -1052,7 +1053,7 @@ ASSERT_FALSE(win::IsWindowsKeyPressed()); } -TEST_F(KeyboardHookWinTest, NonInterceptedKeysTest) { +TEST_F(ModifierKeyboardHookWinTest, NonInterceptedKeysTest) { // Here we try a few keys we do not expect to be intercepted / handled. ASSERT_FALSE(keyboard_hook()->ProcessKeyEventMessage( WM_KEYDOWN, KeyboardCode::VKEY_RSHIFT,
diff --git a/ui/events/x/keyboard_hook_x11.cc b/ui/events/x/keyboard_hook_x11.cc index 588124a..0df8bcb 100644 --- a/ui/events/x/keyboard_hook_x11.cc +++ b/ui/events/x/keyboard_hook_x11.cc
@@ -156,7 +156,7 @@ } // namespace // static -std::unique_ptr<KeyboardHook> KeyboardHook::Create( +std::unique_ptr<KeyboardHook> KeyboardHook::CreateModifierKeyboardHook( base::Optional<base::flat_set<DomCode>> dom_codes, gfx::AcceleratedWidget accelerated_widget, KeyboardHook::KeyEventCallback callback) { @@ -169,4 +169,10 @@ return keyboard_hook; } +// static +std::unique_ptr<KeyboardHook> KeyboardHook::CreateMediaKeyboardHook( + KeyEventCallback callback) { + return nullptr; +} + } // namespace ui
diff --git a/ui/file_manager/file_manager/background/js/BUILD.gn b/ui/file_manager/file_manager/background/js/BUILD.gn index 74c92999..4732f28 100644 --- a/ui/file_manager/file_manager/background/js/BUILD.gn +++ b/ui/file_manager/file_manager/background/js/BUILD.gn
@@ -92,7 +92,6 @@ "../../../externs/file_operation_progress_event.js", "../../../externs/launcher_search_provider.js", "../../../externs/platform.js", - "//third_party/analytics/externs.js", ] } @@ -243,6 +242,7 @@ testonly = true deps = [ ":file_operation_manager", + "//ui/webui/resources/js/cr:event_target", ] externs_list = [ "../../../externs/background/file_operation_manager.js" ] } @@ -254,6 +254,17 @@ "//ui/webui/resources/js:cr", "//ui/webui/resources/js/cr:event_target", ] + externs_list = [ "../../../externs/background/file_operation_manager.js" ] +} + +js_unittest("file_operation_manager_unittest") { + deps = [ + ":file_operation_manager", + ":metadata_proxy", + "//ui/file_manager/base/js:mock_chrome", + "//ui/file_manager/base/js:test_error_reporting", + "//ui/file_manager/file_manager/common/js:mock_entry", + ] } js_library("file_operation_util") { @@ -477,6 +488,7 @@ ":device_handler_unittest", ":drive_sync_handler_unittest", ":duplicate_finder_unittest", + ":file_operation_manager_unittest", ":import_history_unittest", ":media_scanner_unittest", ":task_queue_unittest",
diff --git a/ui/file_manager/file_manager/background/js/file_operation_manager_unittest.html b/ui/file_manager/file_manager/background/js/file_operation_manager_unittest.html deleted file mode 100644 index 7dd9c2b..0000000 --- a/ui/file_manager/file_manager/background/js/file_operation_manager_unittest.html +++ /dev/null
@@ -1,25 +0,0 @@ -<!DOCTYPE html> -<!-- Copyright 2014 The Chromium Authors. All rights reserved. - -- Use of this source code is governed by a BSD-style license that can be - -- found in the LICENSE file. - --> - -<html> -<body> - -<script src="../../../../../ui/webui/resources/js/cr.js"></script> -<script src="../../../../../ui/webui/resources/js/cr/event_target.js"></script> - -<script src="../../common/js/async_util.js"></script> -<script src="../../../base/js/test_error_reporting.js"></script> -<script src="../../common/js/util.js"></script> -<script src="../../common/js/lru_cache.js"></script> -<script src="../../common/js/mock_entry.js"></script> -<script src="metadata_proxy.js"></script> -<script src="file_operation_manager.js"></script> -<script src="file_operation_util.js"></script> - -<script src="file_operation_manager_unittest.js"></script> - -</body> -</html>
diff --git a/ui/file_manager/file_manager/background/js/file_operation_manager_unittest.js b/ui/file_manager/file_manager/background/js/file_operation_manager_unittest.js index 19fc3a2..5e0cad7 100644 --- a/ui/file_manager/file_manager/background/js/file_operation_manager_unittest.js +++ b/ui/file_manager/file_manager/background/js/file_operation_manager_unittest.js
@@ -4,50 +4,41 @@ 'use strict'; /** - * Mock of chrome.runtime. + * Mock chrome APIs. * @type {Object} - * @const */ -chrome.runtime = { +var mockChrome = {}; + +mockChrome.runtime = { lastError: null }; -/** - * Mock of chrome.power. - * @type {Object} - * @const - */ -chrome.power = { +mockChrome.power = { requestKeepAwake: function() { - chrome.power.keepAwakeRequested = true; + mockChrome.power.keepAwakeRequested = true; }, releaseKeepAwake: function() { - chrome.power.keepAwakeRequested = false; + mockChrome.power.keepAwakeRequested = false; }, keepAwakeRequested: false }; -/** - * Mock of chrome.fileManagerPrivate. - * @type {Object} - * @const - */ -chrome.fileManagerPrivate = { +mockChrome.fileManagerPrivate = { onCopyProgress: { addListener: function(callback) { - chrome.fileManagerPrivate.onCopyProgress.listener_ = callback; + mockChrome.fileManagerPrivate.onCopyProgress.listener_ = callback; }, removeListener: function() { - chrome.fileManagerPrivate.onCopyProgress.listener_ = null; + mockChrome.fileManagerPrivate.onCopyProgress.listener_ = null; }, listener_: null } }; /** - * Logs events of file operation manager. - * @param {!FileOperationManager} fileOperationManager A target file operation - * manager. + * Logs copy-progress events from a file operation manager. + * @param {!FileOperationManager} fileOperationManager The target file + * operation manager. * @constructor * @struct */ @@ -61,11 +52,12 @@ } /** - * Handles copy-progress event. + * Log file operation manager copy-progress event details. * @param {Event} event An event. * @private */ EventLogger.prototype.onCopyProgress_ = function(event) { + event = /** @type {FileOperationProgressEvent} */ (event); if (event.reason === 'BEGIN') { this.events.push(event); this.numberOfBeginEvents++; @@ -85,7 +77,7 @@ * @param {string} blockedDestination Destination url of an entry whose request * should be blocked. * @param {!Entry} sourceEntry Source entry. Single source entry is supported. - * @param {!Array<!FakeFileSystem>} fileSystems File systems. + * @param {!Array<!MockFileSystem>} fileSystems File systems array. * @constructor * @struct */ @@ -98,7 +90,7 @@ } /** - * A fake implemencation of startCopy function. + * Fake implementation of startCopy function. * @param {!Entry} source * @param {!Entry} destination * @param {string} newName @@ -118,7 +110,9 @@ var newPath = joinPath('/', newName); var fileSystem = getFileSystemForURL( this.fileSystems_, destination.toURL()); - fileSystem.entries[newPath] = this.sourceEntry_.clone(newPath); + var mockEntry = /** @type {!MockEntry} */ (this.sourceEntry_); + fileSystem.entries[newPath] = + /** @type {!MockEntry} */ (mockEntry.clone(newPath)); listener(copyId, makeStatus('end_copy_entry')); listener(copyId, makeStatus('success')); }.bind(this); @@ -126,7 +120,7 @@ this.startCopyId_++; callback(this.startCopyId_); - var listener = chrome.fileManagerPrivate.onCopyProgress.listener_; + var listener = mockChrome.fileManagerPrivate.onCopyProgress.listener_; listener(this.startCopyId_, makeStatus('begin_copy_entry')); listener(this.startCopyId_, makeStatus('progress')); @@ -141,14 +135,14 @@ /** * Fake volume manager. * @constructor - * @structs + * @struct */ function FakeVolumeManager() {} /** * Returns fake volume info. * @param {!Entry} entry - * @return {VolumeInfo} A fake volume info. + * @return {!Object} */ FakeVolumeManager.prototype.getVolumeInfo = function(entry) { return { volumeId: entry.filesystem.name }; @@ -156,16 +150,18 @@ /** * Returns file system of the url. - * @param {!Array<!FakeFileSystem>} fileSystems + * @param {!Array<!MockFileSystem>} fileSystems * @param {string} url - * @return {!FakeFileSystem} + * @return {!MockFileSystem} */ function getFileSystemForURL(fileSystems, url) { for (var i = 0; i < fileSystems.length; i++) { - if (new RegExp('^filesystem:' + fileSystems[i].name + '/').test(url)) + if (new RegExp('^filesystem:' + fileSystems[i].name + '/').test(url)) { return fileSystems[i]; + } } - throw new Error('Unexpected url: ' + url + '.'); + + throw new Error('Unexpected url: ' + url); } /** @@ -177,9 +173,10 @@ /** * Creates test file system. - * @param {string} id File system ID. - * @param {Object<number>} entries Map of entries' paths and their size. - * If the size is equals to DIRECTORY_SIZE, the entry is directory. + * @param {string} id File system Id. + * @param {Object<number>} entries Map of entry paths and their size. + * If the entry size is DIRECTORY_SIZE, the entry is a directory. + * @return {!MockFileSystem} */ function createTestFileSystem(id, entries) { var fileSystem = new MockFileSystem(id, 'filesystem:' + id); @@ -187,8 +184,8 @@ if (entries[path] === DIRECTORY_SIZE) { fileSystem.entries[path] = new MockDirectoryEntry(fileSystem, path); } else { - fileSystem.entries[path] = - new MockFileEntry(fileSystem, path, {size: entries[path]}); + var metadata = /** @type {!Metadata} */ ({size: entries[path]}); + fileSystem.entries[path] = new MockFileEntry(fileSystem, path, metadata); } } return fileSystem; @@ -196,12 +193,12 @@ /** * Resolves URL on the file system. - * @param {FakeFileSystem} fileSystem Fake file system. + * @param {!MockFileSystem} fileSystem File system. * @param {string} url URL. - * @param {function(MockEntry)} success Success callback. - * @param {function()} failure Failure callback. + * @param {function(!Entry)} success Success callback. + * @param {function(!FileError)=} opt_failure Failure callback. */ -function resolveTestFileSystemURL(fileSystem, url, success, failure) { +function resolveTestFileSystemURL(fileSystem, url, success, opt_failure) { for (var name in fileSystem.entries) { var entry = fileSystem.entries[name]; if (entry.toURL() == url) { @@ -209,7 +206,10 @@ return; } } - failure(); + + if (opt_failure) { + opt_failure(new FileError()); + } } /** @@ -221,14 +221,17 @@ return new Promise(function(fulfill) { var events = []; fileOperationManager.addEventListener('copy-progress', function(event) { + event = /** @type {FileOperationProgressEvent} */ (event); events.push(event); if (event.reason === 'SUCCESS') fulfill(events); }); fileOperationManager.addEventListener('entries-changed', function(event) { + event = /** @type {FileOperationProgressEvent} */ (event); events.push(event); }); fileOperationManager.addEventListener('delete', function(event) { + event = /** @type {FileOperationProgressEvent} */ (event); events.push(event); if (event.reason === 'SUCCESS') fulfill(events); @@ -245,9 +248,9 @@ var volumeManagerFactory = {}; /** - * Provide VolumeManager.getInstande() for FileOperationManager using mocked + * Provide VolumeManager.getInstance() for FileOperationManager using mocked * volume manager instance. - * @type {!Promise<(FakeVolumeManager|{getVolumeInfo: function()}?)>} + * @return {Promise} */ volumeManagerFactory.getInstance = function() { return Promise.resolve(volumeManager); @@ -263,12 +266,13 @@ * Initializes the test environment. */ function setUp() { + // Install mock chrome APIs. + installMockChrome(mockChrome); } /** * Tests the fileOperationUtil.resolvePath function. - * @param {function(boolean:hasError)} callback Callback to be passed true on - * error. + * @param {function(boolean)} callback Callback to be passed true on error. */ function testResolvePath(callback) { var fileSystem = createTestFileSystem('testVolume', { @@ -299,8 +303,7 @@ } /** - * @param {function(boolean)} callback Callback to be passed true on - * error. + * @param {function(boolean)} callback Callback to be passed true on error. */ function testFindEntriesRecursively(callback) { var fileSystem = createTestFileSystem('testVolume', { @@ -319,22 +322,24 @@ }); var foundFiles = []; - fileOperationUtil.findEntriesRecursively( - fileSystem.root, - function(fileEntry) { - foundFiles.push(fileEntry); - }) - .then( - function() { - assertEquals(12, foundFiles.length); - callback(false); + fileOperationUtil + .findEntriesRecursively( + fileSystem.root, + function(fileEntry) { + foundFiles.push(fileEntry); }) - .catch(callback); + .then(function() { + assertEquals(12, foundFiles.length); + callback(false); + }) + .catch(function() { + var error = true; + callback(error); + }); } /** - * @param {function(boolean)} callback Callback to be passed true on - * error. + * @param {function(boolean)} callback Callback to be passed true on error. */ function testFindFilesRecursively(callback) { var fileSystem = createTestFileSystem('testVolume', { @@ -353,11 +358,12 @@ }); var foundFiles = []; - fileOperationUtil.findFilesRecursively( - fileSystem.root, - function(fileEntry) { - foundFiles.push(fileEntry); - }) + fileOperationUtil + .findFilesRecursively( + fileSystem.root, + function(fileEntry) { + foundFiles.push(fileEntry); + }) .then( function() { assertEquals(10, foundFiles.length); @@ -367,12 +373,14 @@ }); callback(false); }) - .catch(callback); + .catch(function() { + var error = true; + callback(error); + }); } /** - * @param {function(boolean)} callback Callback to be passed true on - * error. + * @param {function(boolean)} callback Callback to be passed true on error. */ function testGatherEntriesRecursively(callback) { var fileSystem = createTestFileSystem('testVolume', { @@ -391,18 +399,19 @@ }); fileOperationUtil.gatherEntriesRecursively(fileSystem.root) - .then( - function(gatheredFiles) { - assertEquals(12, gatheredFiles.length); - callback(false); - }) - .catch(callback); + .then(function(gatheredFiles) { + assertEquals(12, gatheredFiles.length); + callback(false); + }) + .catch(function() { + var error = true; + callback(error); + }); } /** * Tests the fileOperationUtil.deduplicatePath - * @param {function(boolean:hasError)} callback Callback to be passed true on - * error. + * @param {function(boolean)} callback Callback to be passed true on error. */ function testDeduplicatePath(callback) { var fileSystem1 = createTestFileSystem('testVolume', {'/': DIRECTORY_SIZE}); @@ -449,9 +458,8 @@ } /** - * Tests the fileOperationUtil.paste. - * @param {function(boolean:hasError)} callback Callback to be passed true on - * error. + * Tests fileOperationManager copy. + * @param {function(boolean)} callback Callback to be passed true on error. */ function testCopy(callback) { // Prepare entries and their resolver. @@ -459,33 +467,36 @@ '/': DIRECTORY_SIZE, '/test.txt': 10, }); - window.webkitResolveLocalFileSystemURL = - resolveTestFileSystemURL.bind(null, fileSystem); + window.webkitResolveLocalFileSystemURL = function(url, success, failure) { + resolveTestFileSystemURL(fileSystem, url, success, failure); + }; - chrome.fileManagerPrivate.startCopy = - function(source, destination, newName, callback) { - var makeStatus = function(type) { - return { - type: type, - sourceUrl: source.toURL(), - destinationUrl: destination.toURL() - }; - }; - callback(1); - var listener = chrome.fileManagerPrivate.onCopyProgress.listener_; - listener(1, makeStatus('begin_copy_entry')); - listener(1, makeStatus('progress')); - var newPath = joinPath('/', newName); - fileSystem.entries[newPath] = - fileSystem.entries['/test.txt'].clone(newPath); - listener(1, makeStatus('end_copy_entry')); - listener(1, makeStatus('success')); + mockChrome.fileManagerPrivate.startCopy = function( + source, destination, newName, callback) { + var makeStatus = function(type) { + return { + type: type, + sourceUrl: source.toURL(), + destinationUrl: destination.toURL() }; + }; + callback(1); + var listener = mockChrome.fileManagerPrivate.onCopyProgress.listener_; + listener(1, makeStatus('begin_copy_entry')); + listener(1, makeStatus('progress')); + var newPath = joinPath('/', newName); + var entry = /** @type {!MockEntry} */ + (fileSystem.entries['/test.txt']); + fileSystem.entries[newPath] = + /** @type {!MockEntry} */ (entry.clone(newPath)); + listener(1, makeStatus('end_copy_entry')); + listener(1, makeStatus('success')); + }; volumeManager = new FakeVolumeManager(); fileOperationManager = new FileOperationManagerImpl(); - // Observing manager's events. + // Observe the file operation manager's events. var eventsPromise = waitForEvents(fileOperationManager); // Verify the events. @@ -515,40 +526,40 @@ fileOperationManager.paste( [fileSystem.entries['/test.txt']], - fileSystem.entries['/'], - false); + /** @type {!DirectoryEntry} */ (fileSystem.entries['/']), false); } /** - * Tests the fileOperationUtil.paste for copying files in sequential. When - * destination volumes are same, copy operations should run in sequential. + * Tests copying files when the destination volumes are same: the copy + * operations should be run sequentially. */ function testCopyInSequential(callback) { + // Prepare entries and their resolver. var fileSystem = createTestFileSystem('testVolume', { '/': DIRECTORY_SIZE, '/dest': DIRECTORY_SIZE, '/test.txt': 10 }); - - window.webkitResolveLocalFileSystemURL = - resolveTestFileSystemURL.bind(null, fileSystem); + window.webkitResolveLocalFileSystemURL = function(url, success, failure) { + resolveTestFileSystemURL(fileSystem, url, success, failure); + }; var blockableFakeStartCopy = new BlockableFakeStartCopy( - 'filesystem:testVolume/dest', - fileSystem.entries['/test.txt'], + 'filesystem:testVolume/dest', fileSystem.entries['/test.txt'], [fileSystem]); - chrome.fileManagerPrivate.startCopy = + mockChrome.fileManagerPrivate.startCopy = blockableFakeStartCopy.startCopyFunc.bind(blockableFakeStartCopy); volumeManager = new FakeVolumeManager(); fileOperationManager = new FileOperationManagerImpl(); + // Observe the file operation manager's events. var eventLogger = new EventLogger(fileOperationManager); - // Copy test.txt to /dest. This operation will be blocked. - fileOperationManager.paste([fileSystem.entries['/test.txt']], - fileSystem.entries['/dest'], - false); + // Copy test.txt to /dest. This operation should be blocked. + fileOperationManager.paste( + [fileSystem.entries['/test.txt']], + /** @type {!DirectoryEntry} */ (fileSystem.entries['/dest']), false); var firstOperationTaskId; reportPromise(waitUntil(function() { @@ -560,9 +571,9 @@ firstOperationTaskId = eventLogger.events[0].taskId; // Copy test.txt to /. This operation should be blocked. - fileOperationManager.paste([fileSystem.entries['/test.txt']], - fileSystem.entries['/'], - false); + fileOperationManager.paste( + [fileSystem.entries['/test.txt']], + /** @type {!DirectoryEntry} */ (fileSystem.entries['/']), false); return waitUntil(function() { return fileOperationManager.getPendingCopyTasksForTesting().length === 1; @@ -600,10 +611,11 @@ } /** - * Tests the fileOperationUtil.paste for copying files in paralell. When - * destination volumes are different, copy operations can run in paralell. + * Tests copying files when the destination volumes are different: the copy + * operations should be run in parallel. */ function testCopyInParallel(callback) { + // Prepare entries and their resolver. var fileSystemA = createTestFileSystem('volumeA', { '/': DIRECTORY_SIZE, '/test.txt': 10 @@ -614,26 +626,27 @@ var fileSystems = [fileSystemA, fileSystemB]; window.webkitResolveLocalFileSystemURL = function(url, success, failure) { - return resolveTestFileSystemURL( - getFileSystemForURL(fileSystems, url), url, success, failure); + var system = getFileSystemForURL(fileSystems, url); + resolveTestFileSystemURL(system, url, success, failure); }; var blockableFakeStartCopy = new BlockableFakeStartCopy( 'filesystem:volumeB/', fileSystemA.entries['/test.txt'], fileSystems); - chrome.fileManagerPrivate.startCopy = + mockChrome.fileManagerPrivate.startCopy = blockableFakeStartCopy.startCopyFunc.bind(blockableFakeStartCopy); volumeManager = new FakeVolumeManager(); fileOperationManager = new FileOperationManagerImpl(); + // Observe the file operation manager's events. var eventLogger = new EventLogger(fileOperationManager); // Copy test.txt from volume A to volume B. - fileOperationManager.paste([fileSystemA.entries['/test.txt']], - fileSystemB.entries['/'], - false); + fileOperationManager.paste( + [fileSystemA.entries['/test.txt']], + /** @type {!DirectoryEntry} */ (fileSystemB.entries['/']), false); var firstOperationTaskId; reportPromise(waitUntil(function() { @@ -645,9 +658,9 @@ // Copy test.txt from volume A to volume A. This should not be blocked by // the previous operation. - fileOperationManager.paste([fileSystemA.entries['/test.txt']], - fileSystemA.entries['/'], - false); + fileOperationManager.paste( + [fileSystemA.entries['/test.txt']], + /** @type {!DirectoryEntry} */ (fileSystemA.entries['/']), false); // Wait until the second operation is completed. return waitUntil(function() { @@ -681,9 +694,11 @@ } /** - * Test case that a copy fails since destination volume is not available. + * Tests that copy operations fail when the destination volume is not + * available. */ function testCopyFails(callback) { + // Prepare entries. var fileSystem = createTestFileSystem('testVolume', { '/': DIRECTORY_SIZE, '/test.txt': 10 @@ -692,18 +707,19 @@ volumeManager = { /* Mocking volume manager. */ getVolumeInfo: function() { - // Return null to simulate that the volume info is not available. + // Returns null to indicate that the volume is not available. return null; } }; fileOperationManager = new FileOperationManagerImpl(); + // Observe the file operation manager's events. var eventLogger = new EventLogger(fileOperationManager); - // Copy test.txt to /. - fileOperationManager.paste([fileSystem.entries['/test.txt']], - fileSystem.entries['/'], - false); + // Copy test.txt to /, which should fail. + fileOperationManager.paste( + [fileSystem.entries['/test.txt']], + /** @type {!DirectoryEntry} */ (fileSystem.entries['/']), false); reportPromise(waitUntil(function() { return eventLogger.numberOfErrorEvents === 1; @@ -723,8 +739,7 @@ /** * Tests the fileOperationUtil.paste for move. - * @param {function(boolean:hasError)} callback Callback to be passed true on - * error. + * @param {function(boolean)} callback Callback to be passed true on error. */ function testMove(callback) { // Prepare entries and their resolver. @@ -733,13 +748,14 @@ '/directory': DIRECTORY_SIZE, '/test.txt': 10, }); - window.webkitResolveLocalFileSystemURL = - resolveTestFileSystemURL.bind(null, fileSystem); + window.webkitResolveLocalFileSystemURL = function(url, success, failure) { + resolveTestFileSystemURL(fileSystem, url, success, failure); + }; volumeManager = new FakeVolumeManager(); fileOperationManager = new FileOperationManagerImpl(); - // Observing manager's events. + // Observe the file operation manager's events. var eventsPromise = waitForEvents(fileOperationManager); // Verify the events. @@ -775,14 +791,12 @@ fileOperationManager.paste( [fileSystem.entries['/test.txt']], - fileSystem.entries['/directory'], - true); + /** @type {!DirectoryEntry} */ (fileSystem.entries['/directory']), true); } /** - * Tests the fileOperationUtil.deleteEntries. - * @param {function(boolean:hasError)} callback Callback to be passed true on - * error. + * Tests fileOperationManager.deleteEntries. + * @param {function(boolean)} callback Callback to be passed true on error. */ function testDelete(callback) { // Prepare entries and their resolver. @@ -790,34 +804,36 @@ '/': DIRECTORY_SIZE, '/test.txt': 10, }); - window.webkitResolveLocalFileSystemURL = - resolveTestFileSystemURL.bind(null, fileSystem); + window.webkitResolveLocalFileSystemURL = function(url, success, failure) { + resolveTestFileSystemURL(fileSystem, url, success, failure); + }; // Observing manager's events. - reportPromise(waitForEvents(fileOperationManager).then(function(events) { - assertEquals('delete', events[0].type); - assertEquals('BEGIN', events[0].reason); - assertEquals(10, events[0].totalBytes); - assertEquals(0, events[0].processedBytes); + reportPromise( + waitForEvents(fileOperationManager).then(function(events) { + assertEquals('delete', events[0].type); + assertEquals('BEGIN', events[0].reason); + assertEquals(10, events[0].totalBytes); + assertEquals(0, events[0].processedBytes); - var lastEvent = events[events.length - 1]; - assertEquals('delete', lastEvent.type); - assertEquals('SUCCESS', lastEvent.reason); - assertEquals(10, lastEvent.totalBytes); - assertEquals(10, lastEvent.processedBytes); + var lastEvent = events[events.length - 1]; + assertEquals('delete', lastEvent.type); + assertEquals('SUCCESS', lastEvent.reason); + assertEquals(10, lastEvent.totalBytes); + assertEquals(10, lastEvent.processedBytes); - assertFalse(events.some(function(event) { - return event.type === 'copy-progress'; - })); - }), callback); + assertFalse(events.some(function(event) { + return event.type === 'copy-progress'; + })); + }), + callback); fileOperationManager.deleteEntries([fileSystem.entries['/test.txt']]); } /** - * Tests the fileOperationUtil.zipSelection. - * @param {function(boolean:hasError)} callback Callback to be passed true on - * error. + * Tests fileOperationManager.zipSelection. + * @param {function(boolean)} callback Callback to be passed true on error. */ function testZip(callback) { // Prepare entries and their resolver. @@ -825,12 +841,15 @@ '/': DIRECTORY_SIZE, '/test.txt': 10, }); - window.webkitResolveLocalFileSystemURL = - resolveTestFileSystemURL.bind(null, fileSystem); - chrome.fileManagerPrivate.zipSelection = function( + window.webkitResolveLocalFileSystemURL = function(url, success, failure) { + resolveTestFileSystemURL(fileSystem, url, success, failure); + }; + + mockChrome.fileManagerPrivate.zipSelection = function( sources, parent, newName, success, error) { var newPath = joinPath('/', newName); - var newEntry = new MockFileEntry(fileSystem, newPath, {size: 10}); + var newEntry = new MockFileEntry( + fileSystem, newPath, /** @type {!Metadata} */ ({size: 10})); fileSystem.entries[newPath] = newEntry; success(newEntry); }; @@ -862,5 +881,6 @@ }), callback); fileOperationManager.zipSelection( - [fileSystem.entries['/test.txt']], fileSystem.entries['/']); + [fileSystem.entries['/test.txt']], + /** @type {!DirectoryEntry} */ (fileSystem.entries['/'])); }
diff --git a/ui/file_manager/file_manager/background/js/media_import_handler_unittest.html b/ui/file_manager/file_manager/background/js/media_import_handler_unittest.html index 7726ddd..e669548 100644 --- a/ui/file_manager/file_manager/background/js/media_import_handler_unittest.html +++ b/ui/file_manager/file_manager/background/js/media_import_handler_unittest.html
@@ -11,7 +11,6 @@ <script src="../../../../../ui/webui/resources/js/cr/event_target.js"></script> <script src="../../../../../ui/webui/resources/js/cr/ui/array_data_model.js"></script> <script src="../../../../../ui/webui/resources/js/load_time_data.js"></script> - <script src="../../../../../third_party/analytics/google-analytics-bundle.js"></script> <script src="../../common/js/async_util.js"></script> <script src="../../common/js/metrics_base.js"></script>
diff --git a/ui/file_manager/file_manager/common/js/BUILD.gn b/ui/file_manager/file_manager/common/js/BUILD.gn index 9fcc526..6b93293 100644 --- a/ui/file_manager/file_manager/common/js/BUILD.gn +++ b/ui/file_manager/file_manager/common/js/BUILD.gn
@@ -87,7 +87,6 @@ "//ui/file_manager/base/js:volume_manager_types", ] externs_list = [ - "//third_party/analytics/externs.js", "../../../externs/background_window.js", "../../../externs/background/file_browser_background.js", ]
diff --git a/ui/file_manager/file_manager/common/js/metrics_unittest.html b/ui/file_manager/file_manager/common/js/metrics_unittest.html index 8e0ab645..7e1816d 100644 --- a/ui/file_manager/file_manager/common/js/metrics_unittest.html +++ b/ui/file_manager/file_manager/common/js/metrics_unittest.html
@@ -11,7 +11,6 @@ <script src="../../../../../ui/webui/resources/js/cr/event_target.js"></script> <script src="../../../../../ui/webui/resources/js/cr/ui/array_data_model.js"></script> <script src="../../../../../ui/webui/resources/js/load_time_data.js"></script> - <script src="../../../../../third_party/analytics/google-analytics-bundle.js"></script> <script src="../../../../file_manager/base/js/test_error_reporting.js"></script> <script src="util.js"></script> <script src="metrics_base.js"></script>
diff --git a/ui/file_manager/file_manager/foreground/js/actions_model.js b/ui/file_manager/file_manager/foreground/js/actions_model.js index 1a6bc3e9..9aa4979f 100644 --- a/ui/file_manager/file_manager/foreground/js/actions_model.js +++ b/ui/file_manager/file_manager/foreground/js/actions_model.js
@@ -120,7 +120,9 @@ const canShareItem = metadata[0].canShare !== false; return this.volumeManager_.getDriveConnectionState().type !== VolumeManagerCommon.DriveConnectionType.OFFLINE && - !util.isTeamDriveRoot(this.entry_) && canShareItem; + (loadTimeData.getBoolean('DRIVE_FS_ENABLED') || + !util.isTeamDriveRoot(this.entry_)) && + canShareItem; }; /**
diff --git a/ui/file_manager/file_manager/foreground/js/import_controller_unittest.html b/ui/file_manager/file_manager/foreground/js/import_controller_unittest.html index 43337a5f7..c7920e64 100644 --- a/ui/file_manager/file_manager/foreground/js/import_controller_unittest.html +++ b/ui/file_manager/file_manager/foreground/js/import_controller_unittest.html
@@ -6,8 +6,6 @@ <html> <body> - <script src="../../../../../third_party/analytics/google-analytics-bundle.js"></script> - <script src="../../../../../ui/webui/resources/js/cr.js"></script> <script src="../../../../../ui/webui/resources/js/assert.js"></script> <script src="../../../../../ui/webui/resources/js/cr/event_target.js"></script>
diff --git a/ui/file_manager/file_manager/foreground/js/ui/BUILD.gn b/ui/file_manager/file_manager/foreground/js/ui/BUILD.gn index fbcf6f7..c3cac15 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/BUILD.gn +++ b/ui/file_manager/file_manager/foreground/js/ui/BUILD.gn
@@ -73,7 +73,6 @@ "../../../../externs/paper_elements.js", "../../../../externs/platform.js", "../../../../externs/search_item.js", - "//third_party/analytics/externs.js", ] } @@ -185,9 +184,7 @@ "../metadata:metadata_model", "//ui/webui/resources/js/cr/ui:grid", ] - externs_list = [ - "../../../../externs/background/import_history.js", - ] + externs_list = [ "../../../../externs/background/import_history.js" ] } js_library("file_list_selection_model") { @@ -266,9 +263,7 @@ "//ui/webui/resources/js:cr", "//ui/webui/resources/js/cr/ui:table", ] - externs_list = [ - "../../../../externs/background/import_history.js", - ] + externs_list = [ "../../../../externs/background/import_history.js" ] } js_unittest("file_table_unittest") {
diff --git a/ui/file_manager/file_manager/test/BUILD.gn b/ui/file_manager/file_manager/test/BUILD.gn index 13fdd928..6f5cffa3 100644 --- a/ui/file_manager/file_manager/test/BUILD.gn +++ b/ui/file_manager/file_manager/test/BUILD.gn
@@ -63,7 +63,6 @@ "//ui/file_manager/externs/volume_info.js", "//ui/file_manager/externs/volume_info_list.js", "//ui/file_manager/externs/volume_manager.js", - "//third_party/analytics/externs.js", ] }
diff --git a/ui/file_manager/integration_tests/file_manager/share_and_manage_dialog.js b/ui/file_manager/integration_tests/file_manager/share_and_manage_dialog.js index f30664f4..872cab6 100644 --- a/ui/file_manager/integration_tests/file_manager/share_and_manage_dialog.js +++ b/ui/file_manager/integration_tests/file_manager/share_and_manage_dialog.js
@@ -24,18 +24,20 @@ // Navigate to the specified team drive if one is specified. function(results) { appId = results.windowId; - if (!teamDrive) { + if (teamDrive === undefined) { this.next(); return; } remoteCall .navigateWithDirectoryTree( - appId, `/team_drives/${teamDrive}`, 'Team Drives', 'drive') + appId, + teamDrive === '' ? '/team_drives' : `/team_drives/${teamDrive}`, + 'Team Drives', 'drive') .then(this.next); }, // Wait for the file list to update if we navigated. function() { - if (!teamDrive) { + if (teamDrive === undefined) { this.next(); return; } @@ -359,3 +361,12 @@ const URL = 'https://folder_alternate_link/Team%20Drive%20A'; manageWithDriveExpectBrowserURL('Team Drive A', URL, ''); }; + +/** + * Tests sharing a team drive. + */ +testcase.shareTeamDrive = function() { + const URL = + 'https://folder_alternate_link/Team%20Drive%20A?userstoinvite=%22%22'; + shareWithOthersExpectBrowserURL('Team Drive A', URL, ''); +};
diff --git a/ui/gfx/client_native_pixmap_factory.h b/ui/gfx/client_native_pixmap_factory.h index e17e984b..d7e3f65 100644 --- a/ui/gfx/client_native_pixmap_factory.h +++ b/ui/gfx/client_native_pixmap_factory.h
@@ -25,10 +25,6 @@ public: virtual ~ClientNativePixmapFactory() {} - // Returns true if format/usage configuration is supported. - virtual bool IsConfigurationSupported(gfx::BufferFormat format, - gfx::BufferUsage usage) const = 0; - // Import the native pixmap from |handle| to be used in non-GPU processes. // This function takes ownership of any file descriptors in |handle|. virtual std::unique_ptr<ClientNativePixmap> ImportFromHandle(
diff --git a/ui/gfx/linux/client_native_pixmap_dmabuf.cc b/ui/gfx/linux/client_native_pixmap_dmabuf.cc index 6611dcfef..0a8ecf0 100644 --- a/ui/gfx/linux/client_native_pixmap_dmabuf.cc +++ b/ui/gfx/linux/client_native_pixmap_dmabuf.cc
@@ -16,6 +16,7 @@ #include "base/process/memory.h" #include "base/strings/stringprintf.h" #include "base/trace_event/trace_event.h" +#include "build/build_config.h" #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) #include <linux/dma-buf.h> @@ -59,6 +60,68 @@ } // namespace // static +bool ClientNativePixmapDmaBuf::IsConfigurationSupported( + gfx::BufferFormat format, + gfx::BufferUsage usage) { + switch (usage) { + case gfx::BufferUsage::GPU_READ: + return format == gfx::BufferFormat::BGR_565 || + format == gfx::BufferFormat::RGBA_8888 || + format == gfx::BufferFormat::RGBX_8888 || + format == gfx::BufferFormat::BGRA_8888 || + format == gfx::BufferFormat::BGRX_8888 || + format == gfx::BufferFormat::YVU_420; + case gfx::BufferUsage::SCANOUT: + return format == gfx::BufferFormat::BGRX_8888 || + format == gfx::BufferFormat::RGBX_8888 || + format == gfx::BufferFormat::RGBA_8888 || + format == gfx::BufferFormat::BGRA_8888; + case gfx::BufferUsage::SCANOUT_CPU_READ_WRITE: + return +#if defined(ARCH_CPU_X86_FAMILY) + // Currently only Intel driver (i.e. minigbm and Mesa) supports R_8 + // RG_88, NV12 and XB30. https://crbug.com/356871 + format == gfx::BufferFormat::R_8 || + format == gfx::BufferFormat::RG_88 || + format == gfx::BufferFormat::YUV_420_BIPLANAR || + format == gfx::BufferFormat::RGBX_1010102 || +#endif + + format == gfx::BufferFormat::BGRX_8888 || + format == gfx::BufferFormat::BGRA_8888 || + format == gfx::BufferFormat::RGBX_8888 || + format == gfx::BufferFormat::RGBA_8888; + case gfx::BufferUsage::SCANOUT_VDA_WRITE: + return false; + + case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE: + case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE_PERSISTENT: + return +#if defined(ARCH_CPU_X86_FAMILY) + // Currently only Intel driver (i.e. minigbm and + // Mesa) supports R_8 RG_88 and NV12. + // https://crbug.com/356871 + format == gfx::BufferFormat::R_8 || + format == gfx::BufferFormat::RG_88 || + format == gfx::BufferFormat::YUV_420_BIPLANAR || +#endif + format == gfx::BufferFormat::BGRA_8888; + case gfx::BufferUsage::SCANOUT_CAMERA_READ_WRITE: + // Each platform only supports one camera buffer type. We list the + // supported buffer formats on all platforms here. When allocating a + // camera buffer the caller is responsible for making sure a buffer is + // successfully allocated. For example, allocating YUV420_BIPLANAR + // for SCANOUT_CAMERA_READ_WRITE may only work on Intel boards. + return format == gfx::BufferFormat::YUV_420_BIPLANAR; + case gfx::BufferUsage::CAMERA_AND_CPU_READ_WRITE: + // R_8 is used as the underlying pixel format for BLOB buffers. + return format == gfx::BufferFormat::R_8; + } + NOTREACHED(); + return false; +} + +// static std::unique_ptr<gfx::ClientNativePixmap> ClientNativePixmapDmaBuf::ImportFromDmabuf( const gfx::NativePixmapHandle& handle,
diff --git a/ui/gfx/linux/client_native_pixmap_dmabuf.h b/ui/gfx/linux/client_native_pixmap_dmabuf.h index b8f5630e..f5da2b3 100644 --- a/ui/gfx/linux/client_native_pixmap_dmabuf.h +++ b/ui/gfx/linux/client_native_pixmap_dmabuf.h
@@ -11,14 +11,19 @@ #include "base/files/scoped_file.h" #include "base/macros.h" +#include "ui/gfx/buffer_types.h" #include "ui/gfx/client_native_pixmap.h" #include "ui/gfx/geometry/size.h" +#include "ui/gfx/gfx_export.h" #include "ui/gfx/native_pixmap_handle.h" namespace gfx { class ClientNativePixmapDmaBuf : public gfx::ClientNativePixmap { public: + static GFX_EXPORT bool IsConfigurationSupported(gfx::BufferFormat format, + gfx::BufferUsage usage); + static std::unique_ptr<gfx::ClientNativePixmap> ImportFromDmabuf( const gfx::NativePixmapHandle& handle, const gfx::Size& size);
diff --git a/ui/gfx/linux/client_native_pixmap_factory_dmabuf.cc b/ui/gfx/linux/client_native_pixmap_factory_dmabuf.cc index 70c287b..6b0aaa84 100644 --- a/ui/gfx/linux/client_native_pixmap_factory_dmabuf.cc +++ b/ui/gfx/linux/client_native_pixmap_factory_dmabuf.cc
@@ -45,80 +45,9 @@ class ClientNativePixmapFactoryDmabuf : public ClientNativePixmapFactory { public: - explicit ClientNativePixmapFactoryDmabuf( - bool supports_native_pixmap_import_from_dmabuf) - : supports_native_pixmap_import_from_dmabuf_( - supports_native_pixmap_import_from_dmabuf) {} + explicit ClientNativePixmapFactoryDmabuf() {} ~ClientNativePixmapFactoryDmabuf() override {} - // ClientNativePixmapFactory: - bool IsConfigurationSupported(gfx::BufferFormat format, - gfx::BufferUsage usage) const override { - switch (usage) { - case gfx::BufferUsage::GPU_READ: - return format == gfx::BufferFormat::BGR_565 || - format == gfx::BufferFormat::RGBA_8888 || - format == gfx::BufferFormat::RGBX_8888 || - format == gfx::BufferFormat::BGRA_8888 || - format == gfx::BufferFormat::BGRX_8888 || - format == gfx::BufferFormat::YVU_420; - case gfx::BufferUsage::SCANOUT: - return format == gfx::BufferFormat::BGRX_8888 || - format == gfx::BufferFormat::RGBX_8888 || - format == gfx::BufferFormat::RGBA_8888 || - format == gfx::BufferFormat::BGRA_8888; - case gfx::BufferUsage::SCANOUT_CPU_READ_WRITE: - return -#if defined(ARCH_CPU_X86_FAMILY) - // Currently only Intel driver (i.e. minigbm and Mesa) supports R_8 - // RG_88, NV12 and XB30. https://crbug.com/356871 - format == gfx::BufferFormat::R_8 || - format == gfx::BufferFormat::RG_88 || - format == gfx::BufferFormat::YUV_420_BIPLANAR || - format == gfx::BufferFormat::RGBX_1010102 || -#endif - - format == gfx::BufferFormat::BGRX_8888 || - format == gfx::BufferFormat::BGRA_8888 || - format == gfx::BufferFormat::RGBX_8888 || - format == gfx::BufferFormat::RGBA_8888; - case gfx::BufferUsage::SCANOUT_VDA_WRITE: - return false; - case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE: - case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE_PERSISTENT: { - if (!supports_native_pixmap_import_from_dmabuf_) - return false; - return -#if defined(ARCH_CPU_X86_FAMILY) - // Currently only Intel driver (i.e. minigbm and - // Mesa) supports R_8 RG_88 and NV12. - // https://crbug.com/356871 - format == gfx::BufferFormat::R_8 || - format == gfx::BufferFormat::RG_88 || - format == gfx::BufferFormat::YUV_420_BIPLANAR || -#endif - format == gfx::BufferFormat::BGRA_8888; - } - case gfx::BufferUsage::SCANOUT_CAMERA_READ_WRITE: { - if (!supports_native_pixmap_import_from_dmabuf_) - return false; - // Each platform only supports one camera buffer type. We list the - // supported buffer formats on all platforms here. When allocating a - // camera buffer the caller is responsible for making sure a buffer is - // successfully allocated. For example, allocating YUV420_BIPLANAR - // for SCANOUT_CAMERA_READ_WRITE may only work on Intel boards. - return format == gfx::BufferFormat::YUV_420_BIPLANAR; - } - case gfx::BufferUsage::CAMERA_AND_CPU_READ_WRITE: { - if (!supports_native_pixmap_import_from_dmabuf_) - return false; - // R_8 is used as the underlying pixel format for BLOB buffers. - return format == gfx::BufferFormat::R_8; - } - } - NOTREACHED(); - return false; - } std::unique_ptr<ClientNativePixmap> ImportFromHandle( const gfx::NativePixmapHandle& handle, const gfx::Size& size, @@ -130,11 +59,7 @@ case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE_PERSISTENT: case gfx::BufferUsage::SCANOUT_CAMERA_READ_WRITE: case gfx::BufferUsage::CAMERA_AND_CPU_READ_WRITE: - if (supports_native_pixmap_import_from_dmabuf_) - return ClientNativePixmapDmaBuf::ImportFromDmabuf(handle, size); - NOTREACHED() - << "Native GpuMemoryBuffers are not supported on this platform"; - return nullptr; + return ClientNativePixmapDmaBuf::ImportFromDmabuf(handle, size); case gfx::BufferUsage::GPU_READ: case gfx::BufferUsage::SCANOUT: case gfx::BufferUsage::SCANOUT_VDA_WRITE: @@ -148,30 +73,11 @@ } private: - // Says if ClientNativePixmapDmaBuf can be used to import handle from dmabuf. - const bool supports_native_pixmap_import_from_dmabuf_ = false; - DISALLOW_COPY_AND_ASSIGN(ClientNativePixmapFactoryDmabuf); }; -ClientNativePixmapFactory* CreateClientNativePixmapFactoryDmabuf( - bool supports_native_pixmap_import_from_dmabuf) { -// |supports_native_pixmap_import_from_dmabuf| can be enabled on all linux but -// it is not a requirement to support glCreateImageChromium+Dmabuf since it uses -// gfx::BufferUsage::SCANOUT and the pixmap does not need to be mappable on the -// client side. -// -// At the moment, only Ozone/Wayland platform running on Linux is able to import -// handle from dmabuf in addition to the ChromeOS. This is set in the ozone -// level in the ClientNativePixmapFactoryWayland class. -// -// This is not ideal. The ozone platform should probably set this. -// TODO(rjkroege): do something better here. -#if defined(OS_CHROMEOS) - supports_native_pixmap_import_from_dmabuf = true; -#endif - return new ClientNativePixmapFactoryDmabuf( - supports_native_pixmap_import_from_dmabuf); +ClientNativePixmapFactory* CreateClientNativePixmapFactoryDmabuf() { + return new ClientNativePixmapFactoryDmabuf(); } } // namespace gfx
diff --git a/ui/gfx/linux/client_native_pixmap_factory_dmabuf.h b/ui/gfx/linux/client_native_pixmap_factory_dmabuf.h index 730b28d..7f802a6 100644 --- a/ui/gfx/linux/client_native_pixmap_factory_dmabuf.h +++ b/ui/gfx/linux/client_native_pixmap_factory_dmabuf.h
@@ -10,8 +10,7 @@ namespace gfx { -GFX_EXPORT ClientNativePixmapFactory* CreateClientNativePixmapFactoryDmabuf( - bool supports_import_from_dmabuf = false); +GFX_EXPORT ClientNativePixmapFactory* CreateClientNativePixmapFactoryDmabuf(); } // namespace gfx
diff --git a/ui/ozone/common/stub_client_native_pixmap_factory.cc b/ui/ozone/common/stub_client_native_pixmap_factory.cc index 93e5963..f5b33302 100644 --- a/ui/ozone/common/stub_client_native_pixmap_factory.cc +++ b/ui/ozone/common/stub_client_native_pixmap_factory.cc
@@ -15,10 +15,6 @@ ~StubClientNativePixmapFactory() override {} // ClientNativePixmapFactory: - bool IsConfigurationSupported(gfx::BufferFormat format, - gfx::BufferUsage usage) const override { - return false; - } std::unique_ptr<gfx::ClientNativePixmap> ImportFromHandle( const gfx::NativePixmapHandle& handle, const gfx::Size& size,
diff --git a/ui/ozone/platform/cast/client_native_pixmap_factory_cast.cc b/ui/ozone/platform/cast/client_native_pixmap_factory_cast.cc index 4aa44c7..84809836 100644 --- a/ui/ozone/platform/cast/client_native_pixmap_factory_cast.cc +++ b/ui/ozone/platform/cast/client_native_pixmap_factory_cast.cc
@@ -36,12 +36,6 @@ class ClientNativePixmapFactoryCast : public gfx::ClientNativePixmapFactory { public: // ClientNativePixmapFactoryCast implementation: - bool IsConfigurationSupported(gfx::BufferFormat format, - gfx::BufferUsage usage) const override { - return format == gfx::BufferFormat::BGRA_8888 && - usage == gfx::BufferUsage::SCANOUT; - } - std::unique_ptr<gfx::ClientNativePixmap> ImportFromHandle( const gfx::NativePixmapHandle& handle, const gfx::Size& size,
diff --git a/ui/ozone/platform/cast/ozone_platform_cast.cc b/ui/ozone/platform/cast/ozone_platform_cast.cc index 217b28c..594d0e63 100644 --- a/ui/ozone/platform/cast/ozone_platform_cast.cc +++ b/ui/ozone/platform/cast/ozone_platform_cast.cc
@@ -102,6 +102,11 @@ // On Cast platform the display is initialized by low-level non-Ozone code. return nullptr; } + bool IsNativePixmapConfigSupported(gfx::BufferFormat format, + gfx::BufferUsage usage) const override { + return format == gfx::BufferFormat::BGRA_8888 && + usage == gfx::BufferUsage::SCANOUT; + } void InitializeUI(const InitParams& params) override { device_manager_ = CreateDeviceManager();
diff --git a/ui/ozone/platform/drm/ozone_platform_gbm.cc b/ui/ozone/platform/drm/ozone_platform_gbm.cc index b7f7999..a2e555d 100644 --- a/ui/ozone/platform/drm/ozone_platform_gbm.cc +++ b/ui/ozone/platform/drm/ozone_platform_gbm.cc
@@ -23,6 +23,7 @@ #include "ui/events/ozone/device/device_manager.h" #include "ui/events/ozone/evdev/event_factory_evdev.h" #include "ui/events/ozone/layout/keyboard_layout_engine_manager.h" +#include "ui/gfx/linux/client_native_pixmap_dmabuf.h" #include "ui/ozone/platform/drm/common/drm_util.h" #include "ui/ozone/platform/drm/gpu/drm_device_generator.h" #include "ui/ozone/platform/drm/gpu/drm_device_manager.h" @@ -171,6 +172,12 @@ return std::make_unique<DrmNativeDisplayDelegate>(display_manager_.get()); } + bool IsNativePixmapConfigSupported(gfx::BufferFormat format, + gfx::BufferUsage usage) const override { + return gfx::ClientNativePixmapDmaBuf::IsConfigurationSupported(format, + usage); + } + void InitializeUI(const InitParams& args) override { // Ozone drm can operate in four modes configured at // runtime. Three process modes: @@ -184,12 +191,13 @@ // // and 2 connection modes // a. Viz is launched via content::GpuProcessHost and it notifies the - // ozone host when Viz becomes available. b. The ozone host uses a service - // manager to launch and connect to Viz. + // ozone host when Viz becomes available. b. The ozone host uses a + // service manager to launch and connect to Viz. // // Combinations 1a, 2b, and 3a, and 3b are supported and expected to work. // Combination 1a will hopefully be deprecated and replaced with 3a. - // Combination 2b adds undesirable code-debt and the intent is to remove it. + // Combination 2b adds undesirable code-debt and the intent is to remove + // it. single_process_ = args.single_process; using_mojo_ = args.using_mojo || args.connector != nullptr; @@ -198,6 +206,7 @@ device_manager_ = CreateDeviceManager(); window_manager_.reset(new DrmWindowHostManager()); cursor_.reset(new DrmCursor(window_manager_.get())); + #if BUILDFLAG(USE_XKBCOMMON) KeyboardLayoutEngineManager::SetKeyboardLayoutEngine( std::make_unique<XkbKeyboardLayoutEngine>(xkb_evdev_code_converter_));
diff --git a/ui/ozone/platform/scenic/ozone_platform_scenic.cc b/ui/ozone/platform/scenic/ozone_platform_scenic.cc index 2ad7f68..d4f4b838 100644 --- a/ui/ozone/platform/scenic/ozone_platform_scenic.cc +++ b/ui/ozone/platform/scenic/ozone_platform_scenic.cc
@@ -34,12 +34,11 @@ namespace { -const OzonePlatform::PlatformProperties kScenicPlatformProperties( - /*needs_view_owner_request=*/true, +constexpr OzonePlatform::PlatformProperties kScenicPlatformProperties{ + /*needs_view_token=*/true, /*custom_frame_pref_default=*/false, /*use_system_title_bar=*/false, - /*requires_mojo=*/false, - std::vector<gfx::BufferFormat>()); + /*requires_mojo=*/false}; class ScenicPlatformEventSource : public ui::PlatformEventSource { public:
diff --git a/ui/ozone/platform/wayland/client_native_pixmap_factory_wayland.cc b/ui/ozone/platform/wayland/client_native_pixmap_factory_wayland.cc index a57bfb8..7f839c8 100644 --- a/ui/ozone/platform/wayland/client_native_pixmap_factory_wayland.cc +++ b/ui/ozone/platform/wayland/client_native_pixmap_factory_wayland.cc
@@ -4,50 +4,15 @@ #include "ui/ozone/platform/wayland/client_native_pixmap_factory_wayland.h" -#include "ui/gfx/linux/client_native_pixmap_dmabuf.h" #include "ui/gfx/linux/client_native_pixmap_factory_dmabuf.h" #include "ui/ozone/common/stub_client_native_pixmap_factory.h" #include "ui/ozone/public/ozone_platform.h" namespace ui { -// Implements ClientNativePixmapFactory to provide a more accurate buffer format -// support when Wayland dmabuf is used. -class ClientNativePixmapFactoryWayland : public gfx::ClientNativePixmapFactory { - public: - ClientNativePixmapFactoryWayland() { - dmabuf_factory_.reset(gfx::CreateClientNativePixmapFactoryDmabuf( - true /* supports_native_pixmap_import_from_dmabuf */)); - } - ~ClientNativePixmapFactoryWayland() override {} - - // ClientNativePixmapFactory overrides: - bool IsConfigurationSupported(gfx::BufferFormat format, - gfx::BufferUsage usage) const override { - OzonePlatform::PlatformProperties properties = - OzonePlatform::GetInstance()->GetPlatformProperties(); - for (auto buffer_format : properties.supported_buffer_formats) { - if (buffer_format == format) - return dmabuf_factory_->IsConfigurationSupported(format, usage); - } - return false; - } - - std::unique_ptr<gfx::ClientNativePixmap> ImportFromHandle( - const gfx::NativePixmapHandle& handle, - const gfx::Size& size, - gfx::BufferUsage usage) override { - return dmabuf_factory_->ImportFromHandle(handle, size, usage); - } - - private: - std::unique_ptr<ClientNativePixmapFactory> dmabuf_factory_; - DISALLOW_COPY_AND_ASSIGN(ClientNativePixmapFactoryWayland); -}; - gfx::ClientNativePixmapFactory* CreateClientNativePixmapFactoryWayland() { #if defined(WAYLAND_GBM) - return new ClientNativePixmapFactoryWayland(); + return gfx::CreateClientNativePixmapFactoryDmabuf(); #else return CreateStubClientNativePixmapFactory(); #endif
diff --git a/ui/ozone/platform/wayland/ozone_platform_wayland.cc b/ui/ozone/platform/wayland/ozone_platform_wayland.cc index 642a276..0bba90d 100644 --- a/ui/ozone/platform/wayland/ozone_platform_wayland.cc +++ b/ui/ozone/platform/wayland/ozone_platform_wayland.cc
@@ -10,6 +10,7 @@ #include "ui/display/manager/fake_display_delegate.h" #include "ui/events/ozone/layout/keyboard_layout_engine_manager.h" #include "ui/events/system_input_injector.h" +#include "ui/gfx/linux/client_native_pixmap_dmabuf.h" #include "ui/ozone/common/stub_overlay_manager.h" #include "ui/ozone/platform/wayland/gpu/wayland_connection_proxy.h" #include "ui/ozone/platform/wayland/wayland_connection.h" @@ -41,21 +42,25 @@ namespace { -class OzonePlatformWayland : public OzonePlatform { - public: - OzonePlatformWayland() { +constexpr OzonePlatform::PlatformProperties kWaylandPlatformProperties = { + /*needs_view_token=*/false, + // Supporting server-side decorations requires a support of xdg-decorations. // But this protocol has been accepted into the upstream recently, and it // will take time before it is taken by compositors. For now, always use // custom frames and disallow switching to server-side frames. // https://github.com/wayland-project/wayland-protocols/commit/76d1ae8c65739eff3434ef219c58a913ad34e988 - properties_.custom_frame_pref_default = true; - properties_.use_system_title_bar = false; + /*custom_frame_pref_default=*/true, + /*use_system_title_bar=*/false, + // Ozone/Wayland relies on the mojo communication when running in // !single_process. // TODO(msisov, rjkroege): Remove after http://crbug.com/806092. - properties_.requires_mojo = true; - } + /*requires_mojo=*/true}; + +class OzonePlatformWayland : public OzonePlatform { + public: + OzonePlatformWayland() {} ~OzonePlatformWayland() override {} // OzonePlatform @@ -113,6 +118,18 @@ return connection_->wayland_output_manager()->CreateWaylandScreen(); } + bool IsNativePixmapConfigSupported(gfx::BufferFormat format, + gfx::BufferUsage usage) const override { + if (std::find(supported_buffer_formats_.begin(), + supported_buffer_formats_.end(), + format) == supported_buffer_formats_.end()) { + return false; + } + + return gfx::ClientNativePixmapDmaBuf::IsConfigurationSupported(format, + usage); + } + void InitializeUI(const InitParams& args) override { #if BUILDFLAG(USE_XKBCOMMON) KeyboardLayoutEngineManager::SetKeyboardLayoutEngine( @@ -135,6 +152,7 @@ overlay_manager_.reset(new StubOverlayManager); input_controller_ = CreateStubInputController(); gpu_platform_support_host_.reset(CreateStubGpuPlatformSupportHost()); + supported_buffer_formats_ = connection_->GetSupportedBufferFormats(); } void InitializeGPU(const InitParams& args) override { @@ -163,11 +181,7 @@ } const PlatformProperties& GetPlatformProperties() override { - if (connection_ && properties_.supported_buffer_formats.empty()) { - properties_.supported_buffer_formats = - connection_->GetSupportedBufferFormats(); - } - return properties_; + return kWaylandPlatformProperties; } void AddInterfaces(service_manager::BinderRegistry* registry) override { @@ -199,7 +213,7 @@ std::unique_ptr<WaylandConnectionProxy> proxy_; std::unique_ptr<WaylandConnectionConnector> connector_; - PlatformProperties properties_; + std::vector<gfx::BufferFormat> supported_buffer_formats_; DISALLOW_COPY_AND_ASSIGN(OzonePlatformWayland); };
diff --git a/ui/ozone/platform/wayland/wayland_surface_factory.cc b/ui/ozone/platform/wayland/wayland_surface_factory.cc index a5b1dec0..83fb59d 100644 --- a/ui/ozone/platform/wayland/wayland_surface_factory.cc +++ b/ui/ozone/platform/wayland/wayland_surface_factory.cc
@@ -11,6 +11,7 @@ #include "base/memory/ptr_util.h" #include "base/memory/shared_memory.h" #include "third_party/skia/include/core/SkSurface.h" +#include "ui/gfx/linux/client_native_pixmap_dmabuf.h" #include "ui/gfx/vsync_provider.h" #include "ui/ozone/common/egl_util.h" #include "ui/ozone/common/gl_ozone_egl.h"
diff --git a/ui/ozone/public/ozone_platform.cc b/ui/ozone/public/ozone_platform.cc index 8cba6bd..d9c5310 100644 --- a/ui/ozone/public/ozone_platform.cc +++ b/ui/ozone/public/ozone_platform.cc
@@ -35,25 +35,6 @@ } // namespace -OzonePlatform::PlatformProperties::PlatformProperties() = default; - -OzonePlatform::PlatformProperties::PlatformProperties( - bool needs_view_token, - bool custom_frame_default, - bool can_use_system_title_bar, - bool requires_mojo_for_ipc, - std::vector<gfx::BufferFormat> buffer_formats) - : needs_view_token(needs_view_token), - custom_frame_pref_default(custom_frame_default), - use_system_title_bar(can_use_system_title_bar), - requires_mojo(requires_mojo_for_ipc), - supported_buffer_formats(buffer_formats) {} - -OzonePlatform::PlatformProperties::~PlatformProperties() = default; - -OzonePlatform::PlatformProperties::PlatformProperties( - const PlatformProperties& other) = default; - OzonePlatform::OzonePlatform() { GetOzoneInstanceLock().AssertAcquired(); DCHECK(!g_instance) << "There should only be a single OzonePlatform."; @@ -141,6 +122,13 @@ return nullptr; } +bool OzonePlatform::IsNativePixmapConfigSupported( + gfx::BufferFormat format, + gfx::BufferUsage usage) const { + // Platform that support NativePixmap must override this method. + return false; +} + const OzonePlatform::PlatformProperties& OzonePlatform::GetPlatformProperties() { static const base::NoDestructor<OzonePlatform::PlatformProperties> properties;
diff --git a/ui/ozone/public/ozone_platform.h b/ui/ozone/public/ozone_platform.h index c6dbf1f..ceb28724 100644 --- a/ui/ozone/public/ozone_platform.h +++ b/ui/ozone/public/ozone_platform.h
@@ -87,15 +87,6 @@ // Struct used to indicate platform properties. struct PlatformProperties { - PlatformProperties(); - PlatformProperties(bool needs_request, - bool custom_frame_default, - bool can_use_system_title_bar, - bool requires_mojo_for_ipc, - std::vector<gfx::BufferFormat> buffer_formats); - ~PlatformProperties(); - PlatformProperties(const PlatformProperties& other); - // Fuchsia only: set to true when the platforms requires |view_token| field // in PlatformWindowInitProperties when creating a window. bool needs_view_token = false; @@ -111,9 +102,6 @@ // Determines if the platform requires mojo communication for the IPC. // Currently used only by the Ozone/Wayland platform. bool requires_mojo = false; - - // Wayland only: carries buffer formats supported by a Wayland server. - std::vector<gfx::BufferFormat> supported_buffer_formats; }; using StartupCallback = base::OnceCallback<void(OzonePlatform*)>; @@ -161,6 +149,10 @@ CreateNativeDisplayDelegate() = 0; virtual std::unique_ptr<PlatformScreen> CreateScreen(); + // Returns true if the specified buffer format is supported. + virtual bool IsNativePixmapConfigSupported(gfx::BufferFormat format, + gfx::BufferUsage usage) const; + // Returns a struct that contains configuration and requirements for the // current platform implementation. virtual const PlatformProperties& GetPlatformProperties();
diff --git a/ui/views/animation/ink_drop_host_view.cc b/ui/views/animation/ink_drop_host_view.cc index aa1f1e1..e0db84bb 100644 --- a/ui/views/animation/ink_drop_host_view.cc +++ b/ui/views/animation/ink_drop_host_view.cc
@@ -230,6 +230,12 @@ } void InkDropHostView::OnMouseEvent(ui::MouseEvent* event) { + auto weak_ptr = weak_factory_.GetWeakPtr(); + View::OnMouseEvent(event); + if (!weak_ptr) { + // Calling View::OnMouseEvent() might destroy |this|. + return; + } switch (event->type()) { case ui::ET_MOUSE_ENTERED: GetInkDrop()->SetHovered(true); @@ -243,7 +249,6 @@ default: break; } - View::OnMouseEvent(event); } std::unique_ptr<InkDropImpl> InkDropHostView::CreateDefaultInkDropImpl() {
diff --git a/ui/views/animation/ink_drop_host_view.h b/ui/views/animation/ink_drop_host_view.h index 572573c..8f8b8ea 100644 --- a/ui/views/animation/ink_drop_host_view.h +++ b/ui/views/animation/ink_drop_host_view.h
@@ -205,6 +205,8 @@ std::unique_ptr<views::InkDropMask> ink_drop_mask_; + base::WeakPtrFactory<InkDropHostView> weak_factory_{this}; + DISALLOW_COPY_AND_ASSIGN(InkDropHostView); };
diff --git a/ui/views/layout/layout_manager.cc b/ui/views/layout/layout_manager.cc index eb91c18..877a9f31 100644 --- a/ui/views/layout/layout_manager.cc +++ b/ui/views/layout/layout_manager.cc
@@ -14,6 +14,20 @@ void LayoutManager::Installed(View* host) { } +void LayoutManager::InvalidateLayout() {} + +gfx::Size LayoutManager::GetMinimumSize(const View* host) const { + // Fall back to using preferred size if no minimum size calculation is + // available (e.g. legacy layout managers). + // + // Ideally we'd just call GetPreferredSize() on ourselves here, but because + // some legacy views with layout managers override GetPreferredSize(), we need + // to call GetPreferredSize() on the host view instead. The default + // views::View behavior will be to call GetPreferredSize() on this layout + // manager, so the fallback behavior in all other cases is as expected. + return host->GetPreferredSize(); +} + int LayoutManager::GetPreferredHeightForWidth(const View* host, int width) const { return GetPreferredSize(host).height();
diff --git a/ui/views/layout/layout_manager.h b/ui/views/layout/layout_manager.h index 5e4a1e4..ee1bfda 100644 --- a/ui/views/layout/layout_manager.h +++ b/ui/views/layout/layout_manager.h
@@ -34,16 +34,27 @@ // Notification that this LayoutManager has been installed on |host|. virtual void Installed(View* host); + // For layout managers that can cache layout data, it's useful to let the + // layout manager know that its current layout might not be valid. + // TODO(dfried): consider if we should include some default behavior (like a + // rolling layout counter). + virtual void InvalidateLayout(); + // Called by View::Layout() to position and size the children of |host|. // Generally this queries |host| for its size and positions and sizes the // children in a LayoutManager specific way. virtual void Layout(View* host) = 0; - // Return the preferred size, which is typically the size needed to give each + // Returns the preferred size, which is typically the size needed to give each // child of |host| its preferred size. Generally this is calculated using the // View::CalculatePreferredSize() on each of the children of |host|. virtual gfx::Size GetPreferredSize(const View* host) const = 0; + // Returns the minimum size, which defaults to the preferred size. Layout + // managers with the ability to collapse or hide child views may override this + // behavior. + virtual gfx::Size GetMinimumSize(const View* host) const; + // Return the preferred height for a particular width. Generally this is // calculated using View::GetHeightForWidth() or // View::CalculatePreferredSize() on each of the children of |host|. Override
diff --git a/ui/views/view.cc b/ui/views/view.cc index bc6bf9d7..da506368 100644 --- a/ui/views/view.cc +++ b/ui/views/view.cc
@@ -423,6 +423,9 @@ } gfx::Size View::GetMinimumSize() const { + if (layout_manager_) + return layout_manager_->GetMinimumSize(this); + return GetPreferredSize(); } @@ -431,7 +434,7 @@ } int View::GetHeightForWidth(int w) const { - if (layout_manager_.get()) + if (layout_manager_) return layout_manager_->GetPreferredHeightForWidth(this, w); return GetPreferredSize().height(); } @@ -586,7 +589,7 @@ needs_layout_ = false; // If we have a layout manager, let it handle the layout for us. - if (layout_manager_.get()) + if (layout_manager_) layout_manager_->Layout(this); // Make sure to propagate the Layout() call to any children that haven't @@ -609,6 +612,9 @@ // Always invalidate up. This is needed to handle the case of us already being // valid, but not our parent. needs_layout_ = true; + if (layout_manager_) + layout_manager_->InvalidateLayout(); + if (parent_) parent_->InvalidateLayout(); } @@ -1496,7 +1502,7 @@ // Size and disposition -------------------------------------------------------- gfx::Size View::CalculatePreferredSize() const { - if (layout_manager_.get()) + if (layout_manager_) return layout_manager_->GetPreferredSize(this); return gfx::Size(); }
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc index 9ba7e7a..1332884 100644 --- a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc +++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
@@ -578,7 +578,7 @@ // problems with event routing (i.e. which Hook takes precedence) and // destruction ordering. DCHECK(!keyboard_hook_); - keyboard_hook_ = ui::KeyboardHook::Create( + keyboard_hook_ = ui::KeyboardHook::CreateModifierKeyboardHook( std::move(dom_codes), GetAcceleratedWidget(), base::BindRepeating(&DesktopWindowTreeHostWin::HandleKeyEvent, base::Unretained(this)));
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc index 9dd1a0dc..5e46a4f6 100644 --- a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc +++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
@@ -1318,7 +1318,7 @@ // problems with event routing (i.e. which Hook takes precedence) and // destruction ordering. DCHECK(!keyboard_hook_); - keyboard_hook_ = ui::KeyboardHook::Create( + keyboard_hook_ = ui::KeyboardHook::CreateModifierKeyboardHook( std::move(dom_codes), GetAcceleratedWidget(), base::BindRepeating(&DesktopWindowTreeHostX11::DispatchKeyEvent, base::Unretained(this)));
diff --git a/ui/webui/resources/PRESUBMIT.py b/ui/webui/resources/PRESUBMIT.py index d1933521..5252e6b 100644 --- a/ui/webui/resources/PRESUBMIT.py +++ b/ui/webui/resources/PRESUBMIT.py
@@ -61,8 +61,7 @@ cwd = input_api.PresubmitLocalPath() sys.path += [input_api.os_path.join(cwd, '..', '..', '..', 'tools')] from web_dev_style import presubmit_support - BLACKLIST = ['ui/webui/resources/js/analytics.js', - 'ui/webui/resources/js/jstemplate_compiled.js'] + BLACKLIST = ['ui/webui/resources/js/jstemplate_compiled.js'] file_filter = lambda f: f.LocalPath() not in BLACKLIST results += presubmit_support.CheckStyle(input_api, output_api, file_filter) finally:
diff --git a/ui/webui/resources/cr_components/chromeos/quick_unlock/setup_pin_keyboard.js b/ui/webui/resources/cr_components/chromeos/quick_unlock/setup_pin_keyboard.js index 918bb67..12eaf15b 100644 --- a/ui/webui/resources/cr_components/chromeos/quick_unlock/setup_pin_keyboard.js +++ b/ui/webui/resources/cr_components/chromeos/quick_unlock/setup_pin_keyboard.js
@@ -237,12 +237,11 @@ * Processes the message received from the quick unlock api and hides/shows * the problem based on the message. * @private - * @param {string} newPin * @param {chrome.quickUnlockPrivate.CredentialCheck} message The message * received from checkCredential. */ - processPinProblems_: function(newPin, message) { - if (newPin && !message.errors.length && !message.warnings.length) { + processPinProblems_: function(message) { + if (!message.errors.length && !message.warnings.length) { this.hideProblem_(); this.enableSubmit = true; this.pinHasPassedMinimumLength_ = true; @@ -281,9 +280,6 @@ break; } } - - if (!newPin) - this.enableSubmit = false; }, /** @@ -292,13 +288,13 @@ onPinChange_: function(e) { const newPin = /** @type {{pin: string}} */ (e.detail).pin; if (!this.isConfirmStep) { - if (this.quickUnlockPrivate) { + if (newPin) { this.quickUnlockPrivate.checkCredential( chrome.quickUnlockPrivate.QuickUnlockMode.PIN, newPin, - this.processPinProblems_.bind(this, newPin)); - } - if (!newPin) + this.processPinProblems_.bind(this)); + } else { this.enableSubmit = false; + } return; }
diff --git a/ui/webui/resources/js/analytics.js b/ui/webui/resources/js/analytics.js deleted file mode 100644 index b0893a6..0000000 --- a/ui/webui/resources/js/analytics.js +++ /dev/null
@@ -1,13 +0,0 @@ -// Copyright (c) 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// This file serves as a proxy to bring the included js file from /third_party -// into its correct location under the resources directory tree, whence it is -// delivered via a chrome://resources URL. See ../webui_resources.grd. - -// Note: this <include> is not behind a single-line comment because the first -// line of the file is source code (so the first line would be skipped) instead -// of a licence header. -// clang-format off -<include src="../../../../third_party/analytics/google-analytics-bundle.js">
diff --git a/ui/webui/resources/webui_resources.grd b/ui/webui/resources/webui_resources.grd index a2b2e2d..46c8b37 100644 --- a/ui/webui/resources/webui_resources.grd +++ b/ui/webui/resources/webui_resources.grd
@@ -15,7 +15,6 @@ <includes> <include name="IDR_WEBUI_I18N_TEMPLATE_JS" file="js/i18n_template.js" flattenhtml="true" type="BINDATA" /> <include name="IDR_WEBUI_JSTEMPLATE_JS" file="js/jstemplate_compiled.js" flattenhtml="true" type="BINDATA" /> - <include name="IDR_WEBUI_ANALYTICS_JS" file="js/analytics.js" flattenhtml="true" type="BINDATA" compress="gzip" /> <!-- Roboto Font. Roboto-Regular and Roboto-Light is already available on Android, and Roboto-Medium is not used on Android. All 6 weights of Roboto are available on Chrome OS.-->
diff --git a/url/origin.cc b/url/origin.cc index 1c78bc9..f6403f5 100644 --- a/url/origin.cc +++ b/url/origin.cc
@@ -42,7 +42,8 @@ // It's SchemeHostPort's responsibility to filter out unrecognized schemes; // sanity check that this is happening. DCHECK(tuple.IsInvalid() || url.IsStandard() || - base::ContainsValue(GetLocalSchemes(), url.scheme_piece())); + base::ContainsValue(GetLocalSchemes(), url.scheme_piece()) || + AllowNonStandardSchemesForAndroidWebView()); } if (tuple.IsInvalid())
diff --git a/url/origin_unittest.cc b/url/origin_unittest.cc index 0b57da0..5f889c09 100644 --- a/url/origin_unittest.cc +++ b/url/origin_unittest.cc
@@ -654,4 +654,18 @@ EXPECT_STREQ("https://foo.com", origin1_debug_alias); } +TEST_F(OriginTest, NonStandardScheme) { + Origin origin = Origin::Create(GURL("cow://")); + EXPECT_TRUE(origin.opaque()); +} +TEST_F(OriginTest, NonStandardSchemeWithAndroidWebViewHack) { + EnableNonStandardSchemesForAndroidWebView(); + Origin origin = Origin::Create(GURL("cow://")); + EXPECT_FALSE(origin.opaque()); + EXPECT_EQ("cow", origin.scheme()); + EXPECT_EQ("", origin.host()); + EXPECT_EQ(0, origin.port()); + Shutdown(); +} + } // namespace url
diff --git a/url/scheme_host_port.cc b/url/scheme_host_port.cc index 0d681f13..e588aece 100644 --- a/url/scheme_host_port.cc +++ b/url/scheme_host_port.cc
@@ -52,6 +52,10 @@ const base::StringPiece& host, uint16_t port, SchemeHostPort::ConstructPolicy policy) { + // Empty schemes are never valid. + if (scheme.empty()) + return false; + SchemeType scheme_type = SCHEME_WITH_HOST_PORT_AND_USER_INFORMATION; bool is_standard = GetStandardSchemeType( scheme.data(), @@ -67,7 +71,10 @@ if (base::ContainsValue(GetLocalSchemes(), scheme) && host.empty() && port == 0) return true; - return false; + + // Otherwise, allow non-standard schemes only if the Android WebView + // workaround is enabled. + return AllowNonStandardSchemesForAndroidWebView(); } switch (scheme_type) { @@ -135,7 +142,8 @@ scheme_ = std::move(scheme); host_ = std::move(host); port_ = port; - DCHECK(!IsInvalid()); + DCHECK(!IsInvalid()) << "Scheme: " << scheme_ << " Host: " << host_ + << " Port: " << port; } SchemeHostPort::SchemeHostPort(base::StringPiece scheme,
diff --git a/url/url_util.cc b/url/url_util.cc index a515231..29cebf96 100644 --- a/url/url_util.cc +++ b/url/url_util.cc
@@ -20,6 +20,8 @@ namespace { +bool g_allow_non_standard_schemes = false; + // Pass this enum through for methods which would like to know if whitespace // removal is necessary. enum WhitespaceRemovalPolicy { @@ -530,6 +532,7 @@ void Shutdown() { initialized = false; + g_allow_non_standard_schemes = false; delete standard_schemes; standard_schemes = nullptr; delete referrer_schemes; @@ -550,6 +553,14 @@ empty_document_schemes = nullptr; } +void EnableNonStandardSchemesForAndroidWebView() { + g_allow_non_standard_schemes = true; +} + +bool AllowNonStandardSchemesForAndroidWebView() { + return g_allow_non_standard_schemes; +} + void AddStandardScheme(const char* new_scheme, SchemeType type) { Initialize(); DoAddSchemeWithType(new_scheme, type, standard_schemes);
diff --git a/url/url_util.h b/url/url_util.h index d4b0d773..ee456a0 100644 --- a/url/url_util.h +++ b/url/url_util.h
@@ -39,6 +39,17 @@ // Schemes --------------------------------------------------------------------- +// Changes the behavior of SchemeHostPort / Origin to allow non-standard schemes +// to be specified, instead of canonicalizing them to an invalid SchemeHostPort +// or opaque Origin, respectively. This is used for Android WebView backwards +// compatibility, which allows the use of custom schemes: content hosted in +// Android WebView assumes that one URL with a non-standard scheme will be +// same-origin to another URL with the same non-standard scheme. +URL_EXPORT void EnableNonStandardSchemesForAndroidWebView(); + +// Whether or not SchemeHostPort and Origin allow non-standard schemes. +URL_EXPORT bool AllowNonStandardSchemesForAndroidWebView(); + // A pair for representing a standard scheme name and the SchemeType for it. struct URL_EXPORT SchemeWithType { const char* scheme;