diff --git a/AUTHORS b/AUTHORS index 13b54ae..1bb897b 100644 --- a/AUTHORS +++ b/AUTHORS
@@ -370,6 +370,7 @@ Jonathan Frazer <listedegarde@gmail.com> Jonathan Garbee <jonathan@garbee.me> Jonathan Hacker <jhacker@arcanefour.com> +JongKwon Lee <jongkwon.lee@navercorp.com> Jongsoo Lee <leejongsoo@gmail.com> Joone Hur <joone.hur@intel.com> Jorge Villatoro <jorge@tomatocannon.com>
diff --git a/BUILD.gn b/BUILD.gn index 549429e..fe5071b2 100644 --- a/BUILD.gn +++ b/BUILD.gn
@@ -217,6 +217,8 @@ ] } else if (is_ios) { deps += [ "//ios:all" ] + } else if (is_fuchsia) { + deps += [ ":d8_fuchsia" ] } deps += root_extra_deps @@ -729,6 +731,14 @@ ] } +if (is_fuchsia) { + # TODO(https://crbug.com/731217): This can't practically be in //v8 without + # duplicating all the Fuchsia running infrastructure there. + fuchsia_executable_runner("d8_fuchsia") { + exe_name = "d8" + } +} + # TODO(GYP_GONE): Figure out if we really need this target or if there's # some better way to specify things. if (is_win) {
diff --git a/DEPS b/DEPS index 4aa53b0..9ba70c6 100644 --- a/DEPS +++ b/DEPS
@@ -40,11 +40,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': '634624a1850b335aa7cdfd6aec02e687ee8571a5', + 'skia_revision': '228276dabf8461ba8be7a0dc744cb3374e3c4f1e', # 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': 'cc764848c8dff30d6075981f947754f7f665af61', + 'v8_revision': '2375796ad59425a0a4d53606037e728cfc657014', # 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. @@ -56,7 +56,7 @@ # 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. - 'buildtools_revision': 'ceb050498e43dd0a1c8489022bf21fe687394366', + 'buildtools_revision': 'f90f6a5af3e8cf843395bfe6243cf606f71b5344', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -64,7 +64,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. - 'pdfium_revision': 'ae9c5cacce885fd6622689ecc8aab7571fb23938', + 'pdfium_revision': 'eb14e04c79c575146fe96c025dbf56b7440870c7', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling openmax_dl # and whatever else without interference from each other. @@ -96,7 +96,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': 'd27175a0446ec55e6b496d27ec64338f039eb2d1', + 'catapult_revision': 'b520c76271ee18fd3ecf9a914ac2968961c0f5c7', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -151,13 +151,13 @@ Var('chromium_git') + '/external/colorama.git' + '@' + '799604a1041e9b3bc5d2789ecbd7e8db2e18e6b8', 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '6d0d04458d9c345bc7d77681996d89d6e5fc742c', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'e081cbe5aae6b131955b6c3bd7308d95d650948f', 'src/third_party/googletest/src': Var('chromium_git') + '/external/github.com/google/googletest.git' + '@' + '42bc671f47b122fad36db5eccbc06868afdf7862', 'src/third_party/icu': - Var('chromium_git') + '/chromium/deps/icu.git' + '@' + '98218d1e92b919412ac4b27e5af8e37138d7e347', + Var('chromium_git') + '/chromium/deps/icu.git' + '@' + '08cb956852a5ccdba7f9c941728bb833529ba3c6', 'src/third_party/hunspell_dictionaries': Var('chromium_git') + '/chromium/deps/hunspell_dictionaries.git' + '@' + 'dc6e7c25bf47cbfb466e0701fd2728b4a12e79d5', @@ -258,9 +258,6 @@ 'src/third_party/libphonenumber/dist': Var('chromium_git') + '/external/libphonenumber.git' + '@' + 'a4da30df63a097d67e3c429ead6790ad91d36cf4', - 'src/third_party/webpagereplay': - Var('chromium_git') + '/external/github.com/chromium/web-page-replay.git' + '@' + '3cd3a3f6f06a1b87b14b9162c7eb16d23d141241', - 'src/third_party/pywebsocket/src': Var('chromium_git') + '/external/github.com/google/pywebsocket.git' + '@' + '2d7b73c3acbd0f41dcab487ae5c97c6feae06ce2',
diff --git a/WATCHLISTS b/WATCHLISTS index e9fb9ff..ec3f896b 100644 --- a/WATCHLISTS +++ b/WATCHLISTS
@@ -43,7 +43,8 @@ 'filepath': 'chrome/android/java/src/org/chromium/chrome/browser/infobar/' }, 'android_infra': { - 'filepath': 'build/android/' \ + 'filepath': 'build/config/android/' \ + 'build/android/' \ '|testing/android/' \ '|tools/android/' }, @@ -51,9 +52,6 @@ 'filepath': 'chrome/android/java/src/org/chromium/chrome/browser/.*ChooserDialog.java|'\ 'chrome/android/javatests/src/org/chromium/chrome/browser/.*ChooserDialogTest.java' }, - 'android_java': { - 'filepath': '/java/' - }, 'android_loading': { 'filepath': 'tools/android/loading/' }, @@ -148,12 +146,10 @@ 'autofill': { 'filepath': 'chrome/android/java/src/org/chromium/chrome/browser/autofill/|'\ 'chrome/browser/autofill/|'\ - 'chrome/browser/resources/options/autofill_|'\ 'chrome/browser/ui/android/autofill/|'\ 'chrome/browser/ui/autofill/|'\ 'chrome/browser/ui/cocoa/autofill/|'\ 'chrome/browser/ui/views/autofill/|'\ - 'chrome/browser/ui/webui/options/autofill_|'\ 'chrome/renderer/autofill/|'\ 'chrome/test/data/autofill/|'\ 'components/autofill/|'\ @@ -1223,10 +1219,6 @@ 'components/omnibox/|'\ 'ios/chrome/browser/ui/omnibox/' }, - 'options': { - 'filepath': 'chrome/browser/resources/options/|'\ - 'chrome/browser/ui/webui/options/', - }, 'origin_trials': { 'filepath': 'origin_trials'\ '|OriginTrial'\ @@ -1490,10 +1482,7 @@ '|chrome/browser/chromeos/status/input_method'\ '|chrome/browser/extensions/extension_input_'\ '|chrome/browser/resources/keyboard'\ - '|chrome/browser/resources/options/language'\ - '|chrome/browser/ui/webui/options/'\ 'chromeos/.*(language|keyboard)'\ - '|chrome/browser/ui/webui/options/language'\ '|chromeos/ime/*' }, 'timers': { @@ -1626,19 +1615,16 @@ 'je_julie.kim@chromium.org', 'nektar+watch@chromium.org', 'yuzo+watch@chromium.org'], - 'add_to_homescreen': ['agrieve+watch@chromium.org', - 'dominickn+watch@chromium.org', + 'add_to_homescreen': ['dominickn+watch@chromium.org', 'hanxi+watch@chromium.org', 'pkotwicz+watch@chromium.org'], 'android_crash_reporting': ['asvitkine+watch@chromium.org'], 'android_crazy_linker': ['johnmaguire+watch@google.com'], 'android_infobars': ['dfalcantara+watch@chromium.org'], 'android_infra': ['agrieve+watch@chromium.org', - 'jbudorick+watch@chromium.org', - 'mikecase+watch@chromium.org'], + 'jbudorick+watch@chromium.org'], 'android_item_chooser_dialogs': ['juncai+watch@chromium.org', 'ortuno+watch@chromium.org'], - 'android_java': ['agrieve+watch@chromium.org'], 'android_loading': ['gabadie+watch@chromium.org', 'lizeb+watch-android-loading@chromium.org'], 'android_media': ['avayvod+watch@chromium.org', @@ -2161,7 +2147,6 @@ 'petewil+watch@chromium.org', 'romax+watch@chromium.org'], 'omnibox': ['jdonnelly+watch@chromium.org'], - 'options': ['michaelpg+watch-options@chromium.org'], 'origin_trials': ['chasej+watch@chromium.org', 'iclelland+watch@chromium.org'], 'ozone': ['kalyan.kondapally@intel.com',
diff --git a/android_webview/browser/net/aw_network_delegate.cc b/android_webview/browser/net/aw_network_delegate.cc index 144f5e5..77bc59e5 100644 --- a/android_webview/browser/net/aw_network_delegate.cc +++ b/android_webview/browser/net/aw_network_delegate.cc
@@ -56,14 +56,8 @@ url_blacklist_manager_ = AwBrowserContext::GetDefault()->GetURLBlacklistManager(); } - // Ignore blob scheme for two reasons: - // 1) PlzNavigate uses it to deliver the response to the renderer. - // 2) A whitelisted page can use blob URLs internally. - if (!request->url().SchemeIs(url::kBlobScheme) && - url_blacklist_manager_->IsURLBlocked(request->url())) { + if (url_blacklist_manager_->IsURLBlocked(request->url())) return net::ERR_BLOCKED_BY_ADMINISTRATOR; - } - return net::OK; }
diff --git a/android_webview/browser/parent_output_surface.h b/android_webview/browser/parent_output_surface.h index 0b9a413..7c04ee16 100644 --- a/android_webview/browser/parent_output_surface.h +++ b/android_webview/browser/parent_output_surface.h
@@ -11,7 +11,7 @@ namespace android_webview { class AwRenderThreadContextProvider; -class ParentOutputSurface : NON_EXPORTED_BASE(public cc::OutputSurface) { +class ParentOutputSurface : public cc::OutputSurface { public: explicit ParentOutputSurface( scoped_refptr<AwRenderThreadContextProvider> context_provider);
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwSettingsTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwSettingsTest.java index 59116076..9d1c9a7 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/AwSettingsTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwSettingsTest.java
@@ -4,6 +4,7 @@ package org.chromium.android_webview.test; +import static org.chromium.android_webview.test.AwActivityTestRule.WAIT_TIMEOUT_MS; import static org.chromium.base.test.util.ScalableTimeout.scaleTimeout; import android.content.Context; @@ -11,6 +12,7 @@ import android.net.http.SslError; import android.os.Build; import android.os.SystemClock; +import android.support.test.InstrumentationRegistry; import android.support.test.filters.LargeTest; import android.support.test.filters.MediumTest; import android.support.test.filters.SmallTest; @@ -20,9 +22,16 @@ import android.webkit.WebSettings; import android.webkit.WebSettings.LayoutAlgorithm; +import org.junit.After; +import org.junit.Assert; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + import org.chromium.android_webview.AwContents; import org.chromium.android_webview.AwSettings; import org.chromium.android_webview.AwWebResourceResponse; +import org.chromium.android_webview.test.AwTestBase.TestDependencyFactory; import org.chromium.android_webview.test.TestAwContentsClient.DoUpdateVisitedHistoryHelper; import org.chromium.android_webview.test.util.CommonResources; import org.chromium.android_webview.test.util.ImagePageGenerator; @@ -54,7 +63,21 @@ * settings applies either to each individual view or to all views of the * application */ -public class AwSettingsTest extends AwTestBase { +@RunWith(AwJUnit4ClassRunner.class) +public class AwSettingsTest { + @Rule + public AwActivityTestRule mActivityTestRule = + new AwActivityTestRule() { + @Override + public TestDependencyFactory createTestDependencyFactory() { + if (mOverridenFactory == null) { + return new TestDependencyFactory(); + } else { + return mOverridenFactory; + } + } + }; + private static final boolean ENABLED = true; private static final boolean DISABLED = false; @@ -78,7 +101,7 @@ mAwContents = containerView.getAwContents(); mContext = containerView.getContext(); mContentViewClient = contentViewClient; - mAwSettings = AwSettingsTest.this.getAwSettingsOnUiThread(mAwContents); + mAwSettings = mActivityTestRule.getAwSettingsOnUiThread(mAwContents); if (requiresJsEnabled) { mAwSettings.setJavaScriptEnabled(true); } @@ -111,40 +134,32 @@ protected abstract void doEnsureSettingHasValue(T value) throws Throwable; protected String getTitleOnUiThread() throws Exception { - return AwSettingsTest.this.getTitleOnUiThread(mAwContents); + return mActivityTestRule.getTitleOnUiThread(mAwContents); } protected void loadDataSync(String data) throws Throwable { - AwSettingsTest.this.loadDataSync( - mAwContents, - mContentViewClient.getOnPageFinishedHelper(), - data, - "text/html", - false); + mActivityTestRule.loadDataSync(mAwContents, + mContentViewClient.getOnPageFinishedHelper(), data, "text/html", false); } protected void loadUrlSync(String url) throws Throwable { - AwSettingsTest.this.loadUrlSync( - mAwContents, - mContentViewClient.getOnPageFinishedHelper(), - url); + mActivityTestRule.loadUrlSync( + mAwContents, mContentViewClient.getOnPageFinishedHelper(), url); } protected void loadUrlSyncAndExpectError(String url) throws Throwable { - AwSettingsTest.this.loadUrlSyncAndExpectError( - mAwContents, + mActivityTestRule.loadUrlSyncAndExpectError(mAwContents, mContentViewClient.getOnPageFinishedHelper(), - mContentViewClient.getOnReceivedErrorHelper(), - url); + mContentViewClient.getOnReceivedErrorHelper(), url); } protected String executeJavaScriptAndWaitForResult(String script) throws Exception { - return AwSettingsTest.this.executeJavaScriptAndWaitForResult( + return mActivityTestRule.executeJavaScriptAndWaitForResult( mAwContents, mContentViewClient, script); } private void ensureSettingHasValue(T value) throws Throwable { - assertEquals(value, getCurrentValue()); + Assert.assertEquals(value, getCurrentValue()); doEnsureSettingHasValue(value); } } @@ -181,8 +196,7 @@ @Override protected void doEnsureSettingHasValue(Boolean value) throws Throwable { loadDataSync(getData()); - assertEquals( - value == ENABLED ? JS_ENABLED_STRING : JS_DISABLED_STRING, + Assert.assertEquals(value == ENABLED ? JS_ENABLED_STRING : JS_DISABLED_STRING, getTitleOnUiThread()); } @@ -209,7 +223,7 @@ String oldTitle = getTitleOnUiThread(); String newTitle = oldTitle + "_modified"; executeJavaScriptAndWaitForResult(getScript(newTitle)); - assertEquals(value == ENABLED ? newTitle : oldTitle, getTitleOnUiThread()); + Assert.assertEquals(value == ENABLED ? newTitle : oldTitle, getTitleOnUiThread()); } private String getScript(String title) { @@ -249,8 +263,7 @@ @Override protected void doEnsureSettingHasValue(Boolean value) throws Throwable { loadDataSync(getData()); - assertEquals( - value == ENABLED ? PLUGINS_ENABLED_STRING : PLUGINS_DISABLED_STRING, + Assert.assertEquals(value == ENABLED ? PLUGINS_ENABLED_STRING : PLUGINS_DISABLED_STRING, getTitleOnUiThread()); } @@ -290,7 +303,7 @@ @Override protected void doEnsureSettingHasValue(String value) throws Throwable { loadDataSync(getData()); - assertEquals(value, getTitleOnUiThread()); + Assert.assertEquals(value, getTitleOnUiThread()); } private String getData() { @@ -330,7 +343,7 @@ @Override protected void doEnsureSettingHasValue(Integer value) throws Throwable { loadDataSync(getData()); - assertEquals(value.toString() + "px", getTitleOnUiThread()); + Assert.assertEquals(value.toString() + "px", getTitleOnUiThread()); } private String getData() { @@ -374,9 +387,8 @@ @Override protected void doEnsureSettingHasValue(Boolean value) throws Throwable { loadDataSync(mGenerator.getPageSource()); - assertEquals(value == ENABLED - ? ImagePageGenerator.IMAGE_LOADED_STRING - : ImagePageGenerator.IMAGE_NOT_LOADED_STRING, + Assert.assertEquals(value == ENABLED ? ImagePageGenerator.IMAGE_LOADED_STRING + : ImagePageGenerator.IMAGE_NOT_LOADED_STRING, getTitleOnUiThread()); } } @@ -417,13 +429,10 @@ @Override protected void doEnsureSettingHasValue(Boolean value) throws Throwable { final String httpImageUrl = mGenerator.getPageUrl(mWebServer); - AwSettingsTest.this.loadUrlSync( - mAwContents, - mContentViewClient.getOnPageFinishedHelper(), - httpImageUrl); - assertEquals(value == ENABLED - ? ImagePageGenerator.IMAGE_LOADED_STRING - : ImagePageGenerator.IMAGE_NOT_LOADED_STRING, + mActivityTestRule.loadUrlSync( + mAwContents, mContentViewClient.getOnPageFinishedHelper(), httpImageUrl); + Assert.assertEquals(value == ENABLED ? ImagePageGenerator.IMAGE_LOADED_STRING + : ImagePageGenerator.IMAGE_NOT_LOADED_STRING, getTitleOnUiThread()); } @@ -461,7 +470,7 @@ @Override protected void doEnsureSettingHasValue(String value) throws Throwable { loadDataSync(getData()); - assertEquals(value, getTitleOnUiThread()); + Assert.assertEquals(value, getTitleOnUiThread()); } private String getData() { @@ -510,9 +519,8 @@ @Override protected void doEnsureSettingHasValue(String value) throws Throwable { loadDataSync(getData()); - assertEquals( - DEFAULT_UA.equals(value) ? mDefaultUa : value, - getTitleOnUiThread()); + Assert.assertEquals( + DEFAULT_UA.equals(value) ? mDefaultUa : value, getTitleOnUiThread()); } private String getData() { @@ -557,9 +565,8 @@ // It is not permitted to access localStorage from data URLs in WebKit, // that is why a standalone page must be used. loadUrlSync(UrlUtils.getIsolatedTestFileUrl(TEST_FILE)); - assertEquals( - value == ENABLED ? HAS_LOCAL_STORAGE : NO_LOCAL_STORAGE, - getTitleOnUiThread()); + Assert.assertEquals( + value == ENABLED ? HAS_LOCAL_STORAGE : NO_LOCAL_STORAGE, getTitleOnUiThread()); } } @@ -601,9 +608,8 @@ // supported, and fails with a DOM exception (likely a cross-domain // violation). loadUrlSync(UrlUtils.getIsolatedTestFileUrl(TEST_FILE)); - assertEquals( - value == ENABLED ? HAS_DATABASE : NO_DATABASE, - getTitleOnUiThread()); + Assert.assertEquals( + value == ENABLED ? HAS_DATABASE : NO_DATABASE, getTitleOnUiThread()); } } @@ -653,9 +659,8 @@ @Override protected void doEnsureSettingHasValue(Boolean value) throws Throwable { loadUrlSync(mIframeContainerUrl); - assertEquals( - value == ENABLED ? mIframeUrl : ACCESS_DENIED_TITLE, - getTitleOnUiThread()); + Assert.assertEquals( + value == ENABLED ? mIframeUrl : ACCESS_DENIED_TITLE, getTitleOnUiThread()); } private final String mIframeContainerUrl; @@ -705,9 +710,8 @@ @Override protected void doEnsureSettingHasValue(Boolean value) throws Throwable { loadUrlSync(mIframeContainerUrl); - assertEquals( - value == ENABLED ? mIframeUrl : ACCESS_DENIED_TITLE, - getTitleOnUiThread()); + Assert.assertEquals( + value == ENABLED ? mIframeUrl : ACCESS_DENIED_TITLE, getTitleOnUiThread()); } private final String mIframeContainerUrl; @@ -753,8 +757,7 @@ @Override protected void doEnsureSettingHasValue(Boolean value) throws Throwable { loadUrlSync(mXhrContainerUrl); - assertEquals( - value == ENABLED ? ACCESS_GRANTED_TITLE : ACCESS_DENIED_TITLE, + Assert.assertEquals(value == ENABLED ? ACCESS_GRANTED_TITLE : ACCESS_DENIED_TITLE, getTitleOnUiThread()); } @@ -801,7 +804,7 @@ mIndex += 2; if (value == ENABLED) { loadUrlSync(fileUrl); - assertEquals(ACCESS_GRANTED_TITLE, getTitleOnUiThread()); + Assert.assertEquals(ACCESS_GRANTED_TITLE, getTitleOnUiThread()); } else { loadUrlSyncAndExpectError(fileUrl); } @@ -842,17 +845,17 @@ @Override protected void doEnsureSettingHasValue(Boolean value) throws Throwable { - AwSettingsTest.this.resetResourceRequestCountInContentProvider(mTarget); + resetResourceRequestCountInContentProvider(mTarget); if (value == ENABLED) { - loadUrlSync(AwSettingsTest.this.createContentUrl(mTarget)); + loadUrlSync(createContentUrl(mTarget)); String title = getTitleOnUiThread(); - assertNotNull(title); - assertTrue("[" + mTarget + "] Actual title: \"" + title + "\"", + Assert.assertNotNull(title); + Assert.assertTrue("[" + mTarget + "] Actual title: \"" + title + "\"", title.contains(mTarget)); - AwSettingsTest.this.ensureResourceRequestCountInContentProvider(mTarget, 1); + ensureResourceRequestCountInContentProvider(mTarget, 1); } else { - loadUrlSyncAndExpectError(AwSettingsTest.this.createContentUrl(mTarget)); - AwSettingsTest.this.ensureResourceRequestCountInContentProvider(mTarget, 0); + loadUrlSyncAndExpectError(createContentUrl(mTarget)); + ensureResourceRequestCountInContentProvider(mTarget, 0); } } @@ -868,7 +871,10 @@ int index) throws Throwable { super(containerView, contentViewClient, true); mIndex = index; - mTempDir = getInstrumentation().getTargetContext().getCacheDir().getPath(); + mTempDir = InstrumentationRegistry.getInstrumentation() + .getTargetContext() + .getCacheDir() + .getPath(); } @Override @@ -893,22 +899,21 @@ @Override protected void doEnsureSettingHasValue(Boolean value) throws Throwable { - AwSettingsTest.this.resetResourceRequestCountInContentProvider(TARGET); + resetResourceRequestCountInContentProvider(TARGET); final String fileName = mTempDir + "/" + TARGET + ".html"; try { - TestFileUtil.createNewHtmlFile(fileName, - TARGET, + TestFileUtil.createNewHtmlFile(fileName, TARGET, "<img src=\"" - // Adding a query avoids hitting a cached image, and also verifies - // that content URL query parameters are ignored when accessing - // a content provider. - + AwSettingsTest.this.createContentUrl(TARGET + "?id=" + mIndex) + "\">"); + // Adding a query avoids hitting a cached image, and also verifies + // that content URL query parameters are ignored when accessing + // a content provider. + + createContentUrl(TARGET + "?id=" + mIndex) + "\">"); mIndex += 2; loadUrlSync("file://" + fileName); if (value == ENABLED) { - AwSettingsTest.this.ensureResourceRequestCountInContentProvider(TARGET, 1); + ensureResourceRequestCountInContentProvider(TARGET, 1); } else { - AwSettingsTest.this.ensureResourceRequestCountInContentProvider(TARGET, 0); + ensureResourceRequestCountInContentProvider(TARGET, 0); } } finally { TestFileUtil.deleteFile(fileName); @@ -946,7 +951,7 @@ executeJavaScriptAndWaitForResult("setTitleToActualFontSize()"); } else { final float oldFontSize = mOldFontSize; - pollInstrumentationThread(new Callable<Boolean>() { + AwActivityTestRule.pollInstrumentationThread(new Callable<Boolean>() { @Override public Boolean call() throws Exception { executeJavaScriptAndWaitForResult("setTitleToActualFontSize()"); @@ -1029,10 +1034,10 @@ protected void doEnsureSettingHasValue(LayoutAlgorithm value) throws Throwable { final float actualFontSize = getActualFontSize(); if (value == LayoutAlgorithm.TEXT_AUTOSIZING) { - assertFalse("Actual font size: " + actualFontSize, + Assert.assertFalse("Actual font size: " + actualFontSize, actualFontSize == PARAGRAPH_FONT_SIZE); } else { - assertTrue("Actual font size: " + actualFontSize, + Assert.assertTrue("Actual font size: " + actualFontSize, actualFontSize == PARAGRAPH_FONT_SIZE); } } @@ -1078,9 +1083,8 @@ final float ratiosDelta = Math.abs( (actualFontSize / mInitialActualFontSize) - (value / (float) INITIAL_TEXT_ZOOM)); - assertTrue( - "|(" + actualFontSize + " / " + mInitialActualFontSize + ") - (" - + value + " / " + INITIAL_TEXT_ZOOM + ")| = " + ratiosDelta, + Assert.assertTrue("|(" + actualFontSize + " / " + mInitialActualFontSize + ") - (" + + value + " / " + INITIAL_TEXT_ZOOM + ")| = " + ratiosDelta, ratiosDelta <= 0.2f); } } @@ -1129,9 +1133,8 @@ final float ratiosDelta = Math.abs( (actualFontSize / mInitialActualFontSize) - (value / (float) INITIAL_TEXT_ZOOM)); - assertTrue( - "|(" + actualFontSize + " / " + mInitialActualFontSize + ") - (" - + value + " / " + INITIAL_TEXT_ZOOM + ")| = " + ratiosDelta, + Assert.assertTrue("|(" + actualFontSize + " / " + mInitialActualFontSize + ") - (" + + value + " / " + INITIAL_TEXT_ZOOM + ")| = " + ratiosDelta, ratiosDelta <= 0.2f); } } @@ -1170,7 +1173,7 @@ protected void doEnsureSettingHasValue(Boolean value) throws Throwable { loadDataSync(getData()); final boolean expectPopupEnabled = value; - pollInstrumentationThread(new Callable<Boolean>() { + AwActivityTestRule.pollInstrumentationThread(new Callable<Boolean>() { @Override public Boolean call() throws Exception { String title = getTitleOnUiThread(); @@ -1178,7 +1181,7 @@ POPUP_BLOCKED.equals(title); } }); - assertEquals(value ? POPUP_ENABLED : POPUP_BLOCKED, getTitleOnUiThread()); + Assert.assertEquals(value ? POPUP_ENABLED : POPUP_BLOCKED, getTitleOnUiThread()); } private String getData() { @@ -1241,13 +1244,13 @@ final String htmlPath = "/cache_mode_" + mIndex + ".html"; mIndex += 2; final String url = mWebServer.setResponse(htmlPath, "response", null); - assertEquals(0, mWebServer.getRequestCount(htmlPath)); + Assert.assertEquals(0, mWebServer.getRequestCount(htmlPath)); if (value == WebSettings.LOAD_DEFAULT) { loadUrlSync(url); - assertEquals(1, mWebServer.getRequestCount(htmlPath)); + Assert.assertEquals(1, mWebServer.getRequestCount(htmlPath)); } else { loadUrlSyncAndExpectError(url); - assertEquals(0, mWebServer.getRequestCount(htmlPath)); + Assert.assertEquals(0, mWebServer.getRequestCount(htmlPath)); } } @@ -1294,9 +1297,9 @@ loadDataSync(getData()); final String bodyWidth = getTitleOnUiThread(); if (value) { - assertTrue(bodyWidth, VIEWPORT_TAG_LAYOUT_WIDTH.equals(bodyWidth)); + Assert.assertTrue(bodyWidth, VIEWPORT_TAG_LAYOUT_WIDTH.equals(bodyWidth)); } else { - assertFalse(bodyWidth, VIEWPORT_TAG_LAYOUT_WIDTH.equals(bodyWidth)); + Assert.assertFalse(bodyWidth, VIEWPORT_TAG_LAYOUT_WIDTH.equals(bodyWidth)); } } @@ -1353,12 +1356,12 @@ .waitForCallback(mOnScaleChangedCallCount); mExpectScaleChange = false; } - float currentScale = AwSettingsTest.this.getScaleOnUiThread(mAwContents); + float currentScale = mActivityTestRule.getScaleOnUiThread(mAwContents); if (value) { - assertTrue("Expected: " + currentScale + " < " + DEFAULT_PAGE_SCALE, + Assert.assertTrue("Expected: " + currentScale + " < " + DEFAULT_PAGE_SCALE, currentScale < DEFAULT_PAGE_SCALE); } else { - assertEquals(DEFAULT_PAGE_SCALE, currentScale); + Assert.assertEquals(DEFAULT_PAGE_SCALE, currentScale, 0); } } @@ -1415,9 +1418,9 @@ loadDataSync(getData()); int height = Integer.parseInt(getTitleOnUiThread()); if (value) { - assertEquals(0, height); + Assert.assertEquals(0, height); } else { - assertTrue("Div should be at least 50px high, was: " + height, height >= 50); + Assert.assertTrue("Div should be at least 50px high, was: " + height, height >= 50); } } @@ -1479,9 +1482,9 @@ // The clientWidth is subject to pixel snapping. final int displayWidth = (int) Math.ceil( displayAndroid.getDisplayWidth() / displayAndroid.getDipScale()); - assertEquals(displayWidth, reportedClientWidth); + Assert.assertEquals(displayWidth, reportedClientWidth); } else { - assertEquals(3000, reportedClientWidth); + Assert.assertEquals(3000, reportedClientWidth); } } @@ -1507,6 +1510,7 @@ // is applied on WebView creation. JS state is used, because it is // enabled by default in Chrome, but must be disabled by default // in WebView. + @Test @SmallTest @Feature({"AndroidWebView", "Preferences"}) public void testJavaScriptDisabledByDefault() throws Throwable { @@ -1518,17 +1522,14 @@ + "';\"></body></html>"; final TestAwContentsClient contentClient = new TestAwContentsClient(); final AwTestContainerView testContainerView = - createAwTestContainerViewOnMainSync(contentClient); + mActivityTestRule.createAwTestContainerViewOnMainSync(contentClient); final AwContents awContents = testContainerView.getAwContents(); - loadDataSync( - awContents, - contentClient.getOnPageFinishedHelper(), - testPageHtml, - "text/html", - false); - assertEquals(jsDisabledString, getTitleOnUiThread(awContents)); + mActivityTestRule.loadDataSync(awContents, contentClient.getOnPageFinishedHelper(), + testPageHtml, "text/html", false); + Assert.assertEquals(jsDisabledString, mActivityTestRule.getTitleOnUiThread(awContents)); } + @Test @SmallTest @Feature({"AndroidWebView", "Preferences"}) public void testJavaScriptEnabledWithTwoViews() throws Throwable { @@ -1538,6 +1539,7 @@ new AwSettingsJavaScriptTestHelper(views.getContainer1(), views.getClient1())); } + @Test @SmallTest @Feature({"AndroidWebView", "Preferences"}) public void testJavaScriptEnabledDynamicWithTwoViews() throws Throwable { @@ -1549,6 +1551,7 @@ views.getContainer1(), views.getClient1())); } + @Test @SmallTest @Feature({"AndroidWebView", "Preferences"}) public void testPluginsEnabledWithTwoViews() throws Throwable { @@ -1558,6 +1561,7 @@ new AwSettingsPluginsTestHelper(views.getContainer1(), views.getClient1())); } + @Test @SmallTest @Feature({"AndroidWebView", "Preferences"}) public void testStandardFontFamilyWithTwoViews() throws Throwable { @@ -1569,6 +1573,7 @@ views.getContainer1(), views.getClient1())); } + @Test @SmallTest @Feature({"AndroidWebView", "Preferences"}) public void testDefaultFontSizeWithTwoViews() throws Throwable { @@ -1583,35 +1588,35 @@ // The test verifies that after changing the LoadsImagesAutomatically // setting value from false to true previously skipped images are // automatically loaded. + @Test @SmallTest @Feature({"AndroidWebView", "Preferences"}) public void testLoadsImagesAutomaticallyNoPageReload() throws Throwable { final TestAwContentsClient contentClient = new TestAwContentsClient(); final AwTestContainerView testContainerView = - createAwTestContainerViewOnMainSync(contentClient); + mActivityTestRule.createAwTestContainerViewOnMainSync(contentClient); final AwContents awContents = testContainerView.getAwContents(); - AwSettings settings = getAwSettingsOnUiThread(awContents); + AwSettings settings = mActivityTestRule.getAwSettingsOnUiThread(awContents); settings.setJavaScriptEnabled(true); ImagePageGenerator generator = new ImagePageGenerator(0, false); settings.setLoadsImagesAutomatically(false); - loadDataSync(awContents, - contentClient.getOnPageFinishedHelper(), - generator.getPageSource(), - "text/html", false); - assertEquals(ImagePageGenerator.IMAGE_NOT_LOADED_STRING, - getTitleOnUiThread(awContents)); + mActivityTestRule.loadDataSync(awContents, contentClient.getOnPageFinishedHelper(), + generator.getPageSource(), "text/html", false); + Assert.assertEquals(ImagePageGenerator.IMAGE_NOT_LOADED_STRING, + mActivityTestRule.getTitleOnUiThread(awContents)); settings.setLoadsImagesAutomatically(true); - pollInstrumentationThread(new Callable<Boolean>() { + AwActivityTestRule.pollInstrumentationThread(new Callable<Boolean>() { @Override public Boolean call() throws Exception { return !ImagePageGenerator.IMAGE_NOT_LOADED_STRING.equals( - getTitleOnUiThread(awContents)); + mActivityTestRule.getTitleOnUiThread(awContents)); } }); - assertEquals(ImagePageGenerator.IMAGE_LOADED_STRING, getTitleOnUiThread(awContents)); + Assert.assertEquals(ImagePageGenerator.IMAGE_LOADED_STRING, + mActivityTestRule.getTitleOnUiThread(awContents)); } - + @Test @SmallTest @Feature({"AndroidWebView", "Preferences"}) public void testLoadsImagesAutomaticallyWithTwoViews() throws Throwable { @@ -1627,6 +1632,7 @@ * @SmallTest * @Feature({"AndroidWebView", "Preferences"}) */ + @Test @DisabledTest(message = "Disabled due to document.defaultCharset removal. crbug.com/587484") public void testDefaultTextEncodingWithTwoViews() throws Throwable { ViewPair views = createViews(); @@ -1643,16 +1649,17 @@ // Mozilla/5.0 (Linux;[ U;] Android <version>;[ <language>-<country>;] // [<devicemodel>;] Build/<buildID>; wv) AppleWebKit/<major>.<minor> (KHTML, like Gecko) // Version/<major>.<minor>[ Mobile] Safari/<major>.<minor> + @Test @SmallTest @Feature({"AndroidWebView", "Preferences"}) public void testUserAgentStringDefault() throws Throwable { final TestAwContentsClient contentClient = new TestAwContentsClient(); final AwTestContainerView testContainerView = - createAwTestContainerViewOnMainSync(contentClient); + mActivityTestRule.createAwTestContainerViewOnMainSync(contentClient); final AwContents awContents = testContainerView.getAwContents(); - AwSettings settings = getAwSettingsOnUiThread(awContents); + AwSettings settings = mActivityTestRule.getAwSettingsOnUiThread(awContents); final String actualUserAgentString = settings.getUserAgentString(); - assertEquals(actualUserAgentString, AwSettings.getDefaultUserAgent()); + Assert.assertEquals(actualUserAgentString, AwSettings.getDefaultUserAgent()); final String patternString = "Mozilla/5\\.0 \\(Linux;( U;)? Android ([^;]+);( (\\w+)-(\\w+);)?" + "\\s?(.*)\\sBuild/(.+); wv\\) " @@ -1661,60 +1668,64 @@ + "( Mobile)? Safari/(\\d+)\\.(\\d+)"; final Pattern userAgentExpr = Pattern.compile(patternString); Matcher patternMatcher = userAgentExpr.matcher(actualUserAgentString); - assertTrue(String.format("User agent string did not match expected pattern. %nExpected " - + "pattern:%n%s%nActual:%n%s", patternString, actualUserAgentString), - patternMatcher.find()); + Assert.assertTrue( + String.format("User agent string did not match expected pattern. %nExpected " + + "pattern:%n%s%nActual:%n%s", + patternString, actualUserAgentString), + patternMatcher.find()); // No country-language code token. - assertEquals(null, patternMatcher.group(3)); + Assert.assertEquals(null, patternMatcher.group(3)); if ("REL".equals(Build.VERSION.CODENAME)) { // Model is only added in release builds - assertEquals(Build.MODEL, patternMatcher.group(6)); + Assert.assertEquals(Build.MODEL, patternMatcher.group(6)); // Release version is valid only in release builds - assertEquals(Build.VERSION.RELEASE, patternMatcher.group(2)); + Assert.assertEquals(Build.VERSION.RELEASE, patternMatcher.group(2)); } - assertEquals(Build.ID, patternMatcher.group(7)); + Assert.assertEquals(Build.ID, patternMatcher.group(7)); } + @Test @SmallTest @Feature({"AndroidWebView", "Preferences"}) public void testUserAgentStringOverride() throws Throwable { final TestAwContentsClient contentClient = new TestAwContentsClient(); final AwTestContainerView testContainerView = - createAwTestContainerViewOnMainSync(contentClient); + mActivityTestRule.createAwTestContainerViewOnMainSync(contentClient); final AwContents awContents = testContainerView.getAwContents(); - AwSettings settings = getAwSettingsOnUiThread(awContents); + AwSettings settings = mActivityTestRule.getAwSettingsOnUiThread(awContents); final String defaultUserAgentString = settings.getUserAgentString(); // Check that an attempt to reset the default UA string has no effect. settings.setUserAgentString(null); - assertEquals(defaultUserAgentString, settings.getUserAgentString()); + Assert.assertEquals(defaultUserAgentString, settings.getUserAgentString()); settings.setUserAgentString(""); - assertEquals(defaultUserAgentString, settings.getUserAgentString()); + Assert.assertEquals(defaultUserAgentString, settings.getUserAgentString()); // Check that we can also set the default value. settings.setUserAgentString(defaultUserAgentString); - assertEquals(defaultUserAgentString, settings.getUserAgentString()); + Assert.assertEquals(defaultUserAgentString, settings.getUserAgentString()); // Set a custom UA string, verify that it can be reset back to default. final String customUserAgentString = "AwSettingsTest"; settings.setUserAgentString(customUserAgentString); - assertEquals(customUserAgentString, settings.getUserAgentString()); + Assert.assertEquals(customUserAgentString, settings.getUserAgentString()); settings.setUserAgentString(null); - assertEquals(defaultUserAgentString, settings.getUserAgentString()); + Assert.assertEquals(defaultUserAgentString, settings.getUserAgentString()); } // Verify that the current UA override setting has a priority over UA // overrides in navigation history entries. + @Test @SmallTest @Feature({"AndroidWebView", "Preferences"}) public void testUserAgentStringOverrideForHistory() throws Throwable { final TestAwContentsClient contentClient = new TestAwContentsClient(); final AwTestContainerView testContainerView = - createAwTestContainerViewOnMainSync(contentClient); + mActivityTestRule.createAwTestContainerViewOnMainSync(contentClient); final AwContents awContents = testContainerView.getAwContents(); final WebContents webContents = awContents.getWebContents(); CallbackHelper onPageFinishedHelper = contentClient.getOnPageFinishedHelper(); - AwSettings settings = getAwSettingsOnUiThread(awContents); + AwSettings settings = mActivityTestRule.getAwSettingsOnUiThread(awContents); settings.setJavaScriptEnabled(true); final String defaultUserAgentString = settings.getUserAgentString(); final String customUserAgentString = "AwSettingsTest"; @@ -1729,22 +1740,27 @@ final String page1 = String.format(pageTemplate, page1Title); final String page2 = String.format(pageTemplate, page2Title); settings.setUserAgentString(customUserAgentString); - loadDataSync( - awContents, onPageFinishedHelper, page1, "text/html", false); - assertEquals(page1Title + customUserAgentString, getTitleOnUiThread(awContents)); - loadDataSync( - awContents, onPageFinishedHelper, page2, "text/html", false); - assertEquals(page2Title + customUserAgentString, getTitleOnUiThread(awContents)); + mActivityTestRule.loadDataSync(awContents, onPageFinishedHelper, page1, "text/html", false); + Assert.assertEquals(page1Title + customUserAgentString, + mActivityTestRule.getTitleOnUiThread(awContents)); + mActivityTestRule.loadDataSync(awContents, onPageFinishedHelper, page2, "text/html", false); + Assert.assertEquals(page2Title + customUserAgentString, + mActivityTestRule.getTitleOnUiThread(awContents)); settings.setUserAgentString(null); // Must not cause any changes until the next page loading. - assertEquals(page2Title + customUserAgentString, getTitleOnUiThread(awContents)); - HistoryUtils.goBackSync(getInstrumentation(), webContents, onPageFinishedHelper); - assertEquals(page1Title + defaultUserAgentString, getTitleOnUiThread(awContents)); - HistoryUtils.goForwardSync(getInstrumentation(), webContents, - onPageFinishedHelper); - assertEquals(page2Title + defaultUserAgentString, getTitleOnUiThread(awContents)); + Assert.assertEquals(page2Title + customUserAgentString, + mActivityTestRule.getTitleOnUiThread(awContents)); + HistoryUtils.goBackSync( + InstrumentationRegistry.getInstrumentation(), webContents, onPageFinishedHelper); + Assert.assertEquals(page1Title + defaultUserAgentString, + mActivityTestRule.getTitleOnUiThread(awContents)); + HistoryUtils.goForwardSync( + InstrumentationRegistry.getInstrumentation(), webContents, onPageFinishedHelper); + Assert.assertEquals(page2Title + defaultUserAgentString, + mActivityTestRule.getTitleOnUiThread(awContents)); } + @Test @SmallTest @Feature({"AndroidWebView", "Preferences"}) public void testUserAgentStringWithTwoViews() throws Throwable { @@ -1754,35 +1770,36 @@ new AwSettingsUserAgentStringTestHelper(views.getContainer1(), views.getClient1())); } + @Test @SmallTest @Feature({"AndroidWebView", "Preferences"}) public void testUserAgentWithTestServer() throws Throwable { final TestAwContentsClient contentClient = new TestAwContentsClient(); final AwTestContainerView testContainerView = - createAwTestContainerViewOnMainSync(contentClient); + mActivityTestRule.createAwTestContainerViewOnMainSync(contentClient); final String customUserAgentString = "testUserAgentWithTestServerUserAgent"; AwContents awContents = testContainerView.getAwContents(); - AwSettings settings = getAwSettingsOnUiThread(awContents); - EmbeddedTestServer testServer = - EmbeddedTestServer.createAndStartServer(getInstrumentation().getContext()); + AwSettings settings = mActivityTestRule.getAwSettingsOnUiThread(awContents); + EmbeddedTestServer testServer = EmbeddedTestServer.createAndStartServer( + InstrumentationRegistry.getInstrumentation().getContext()); - enableJavaScriptOnUiThread(awContents); + mActivityTestRule.enableJavaScriptOnUiThread(awContents); try { // Create url with echoheader echoing the User-Agent header in the the html body. String url = testServer.getURL("/echoheader?User-Agent"); settings.setUserAgentString(customUserAgentString); - loadUrlSync(awContents, - contentClient.getOnPageFinishedHelper(), - url); - String userAgent = getJavaScriptResultBodyTextContent(awContents, contentClient); - assertEquals(customUserAgentString, userAgent); + mActivityTestRule.loadUrlSync(awContents, contentClient.getOnPageFinishedHelper(), url); + String userAgent = + mActivityTestRule.getJavaScriptResultBodyTextContent(awContents, contentClient); + Assert.assertEquals(customUserAgentString, userAgent); } finally { testServer.stopAndDestroyServer(); } } + @Test @SmallTest @Feature({"AndroidWebView", "Preferences"}) public void testDomStorageEnabledWithTwoViews() throws Throwable { @@ -1797,41 +1814,45 @@ // Ideally, these three tests below should be combined into one, or tested using // runPerViewSettingsTest. However, it seems the database setting cannot be toggled // once set. Filed b/8186497. + @Test @SmallTest @Feature({"AndroidWebView", "Preferences"}) public void testDatabaseInitialValue() throws Throwable { TestAwContentsClient client = new TestAwContentsClient(); final AwTestContainerView testContainerView = - createAwTestContainerViewOnMainSync(client); + mActivityTestRule.createAwTestContainerViewOnMainSync(client); AwSettingsDatabaseTestHelper helper = new AwSettingsDatabaseTestHelper(testContainerView, client); helper.ensureSettingHasInitialValue(); } + @Test @SmallTest @Feature({"AndroidWebView", "Preferences"}) public void testDatabaseEnabled() throws Throwable { TestAwContentsClient client = new TestAwContentsClient(); final AwTestContainerView testContainerView = - createAwTestContainerViewOnMainSync(client); + mActivityTestRule.createAwTestContainerViewOnMainSync(client); AwSettingsDatabaseTestHelper helper = new AwSettingsDatabaseTestHelper(testContainerView, client); helper.setAlteredSettingValue(); helper.ensureSettingHasAlteredValue(); } + @Test @SmallTest @Feature({"AndroidWebView", "Preferences"}) public void testDatabaseDisabled() throws Throwable { TestAwContentsClient client = new TestAwContentsClient(); final AwTestContainerView testContainerView = - createAwTestContainerViewOnMainSync(client); + mActivityTestRule.createAwTestContainerViewOnMainSync(client); AwSettingsDatabaseTestHelper helper = new AwSettingsDatabaseTestHelper(testContainerView, client); helper.setInitialSettingValue(); helper.ensureSettingHasInitialValue(); } + @Test @SmallTest @Feature({"AndroidWebView", "Preferences"}) public void testUniversalAccessFromFilesWithTwoViews() throws Throwable { @@ -1845,6 +1866,7 @@ // This test verifies that local image resources can be loaded from file: // URLs regardless of file access state. + @Test @SmallTest @Feature({"AndroidWebView", "Preferences"}) public void testFileAccessFromFilesImage() throws Throwable { @@ -1854,16 +1876,18 @@ final String imageHeight = "16"; final TestAwContentsClient contentClient = new TestAwContentsClient(); final AwTestContainerView testContainerView = - createAwTestContainerViewOnMainSync(contentClient); + mActivityTestRule.createAwTestContainerViewOnMainSync(contentClient); final AwContents awContents = testContainerView.getAwContents(); - AwSettings settings = getAwSettingsOnUiThread(awContents); + AwSettings settings = mActivityTestRule.getAwSettingsOnUiThread(awContents); settings.setJavaScriptEnabled(true); settings.setAllowUniversalAccessFromFileURLs(false); settings.setAllowFileAccessFromFileURLs(false); - loadUrlSync(awContents, contentClient.getOnPageFinishedHelper(), imageContainerUrl); - assertEquals(imageHeight, getTitleOnUiThread(awContents)); + mActivityTestRule.loadUrlSync( + awContents, contentClient.getOnPageFinishedHelper(), imageContainerUrl); + Assert.assertEquals(imageHeight, mActivityTestRule.getTitleOnUiThread(awContents)); } + @Test @SmallTest @Feature({"AndroidWebView", "Preferences"}) public void testFileAccessFromFilesIframeWithTwoViews() throws Throwable { @@ -1875,6 +1899,7 @@ views.getContainer1(), views.getClient1())); } + @Test @SmallTest @Feature({"AndroidWebView", "Preferences"}) public void testFileAccessFromFilesXhrWithTwoViews() throws Throwable { @@ -1886,6 +1911,7 @@ views.getContainer1(), views.getClient1())); } + @Test @SmallTest @Feature({"AndroidWebView", "Preferences"}) @RetryOnFailure @@ -1898,6 +1924,7 @@ views.getContainer1(), views.getClient1(), 1)); } + @Test @SmallTest @Feature({"AndroidWebView", "Preferences"}) public void testContentUrlAccessWithTwoViews() throws Throwable { @@ -1909,12 +1936,13 @@ views.getContainer1(), views.getClient1(), 1)); } + @Test @SmallTest @Feature({"AndroidWebView", "Preferences", "Navigation"}) public void testBlockingContentUrlsFromDataUrls() throws Throwable { final TestAwContentsClient contentClient = new TestAwContentsClient(); final AwTestContainerView testContainerView = - createAwTestContainerViewOnMainSync(contentClient); + mActivityTestRule.createAwTestContainerViewOnMainSync(contentClient); final AwContents awContents = testContainerView.getAwContents(); final String target = "content_from_data"; final String page = "<html><body>" @@ -1922,15 +1950,12 @@ + createContentUrl(target) + "\">" + "</body></html>"; resetResourceRequestCountInContentProvider(target); - loadDataSync( - awContents, - contentClient.getOnPageFinishedHelper(), - page, - "text/html", - false); + mActivityTestRule.loadDataSync( + awContents, contentClient.getOnPageFinishedHelper(), page, "text/html", false); ensureResourceRequestCountInContentProvider(target, 0); } + @Test @SmallTest @Feature({"AndroidWebView", "Preferences", "Navigation"}) public void testContentUrlFromFileWithTwoViews() throws Throwable { @@ -1942,34 +1967,34 @@ views.getContainer1(), views.getClient1(), 1)); } + @Test @SmallTest @Feature({"AndroidWebView", "Preferences"}) public void testBlockNetworkImagesDoesNotBlockDataUrlImage() throws Throwable { final TestAwContentsClient contentClient = new TestAwContentsClient(); final AwTestContainerView testContainerView = - createAwTestContainerViewOnMainSync(contentClient); + mActivityTestRule.createAwTestContainerViewOnMainSync(contentClient); final AwContents awContents = testContainerView.getAwContents(); - final AwSettings settings = getAwSettingsOnUiThread(awContents); + final AwSettings settings = mActivityTestRule.getAwSettingsOnUiThread(awContents); ImagePageGenerator generator = new ImagePageGenerator(0, false); settings.setJavaScriptEnabled(true); settings.setImagesEnabled(false); - loadDataSync(awContents, - contentClient.getOnPageFinishedHelper(), - generator.getPageSource(), - "text/html", - false); - assertEquals(ImagePageGenerator.IMAGE_LOADED_STRING, getTitleOnUiThread(awContents)); + mActivityTestRule.loadDataSync(awContents, contentClient.getOnPageFinishedHelper(), + generator.getPageSource(), "text/html", false); + Assert.assertEquals(ImagePageGenerator.IMAGE_LOADED_STRING, + mActivityTestRule.getTitleOnUiThread(awContents)); } + @Test @SmallTest @Feature({"AndroidWebView", "Preferences"}) public void testBlockNetworkImagesBlocksNetworkImageAndReloadInPlace() throws Throwable { final TestAwContentsClient contentClient = new TestAwContentsClient(); final AwTestContainerView testContainerView = - createAwTestContainerViewOnMainSync(contentClient); + mActivityTestRule.createAwTestContainerViewOnMainSync(contentClient); final AwContents awContents = testContainerView.getAwContents(); - final AwSettings settings = getAwSettingsOnUiThread(awContents); + final AwSettings settings = mActivityTestRule.getAwSettingsOnUiThread(awContents); settings.setJavaScriptEnabled(true); ImagePageGenerator generator = new ImagePageGenerator(0, false); @@ -1978,16 +2003,17 @@ final String httpImageUrl = generator.getPageUrl(webServer); settings.setImagesEnabled(false); - loadUrlSync(awContents, contentClient.getOnPageFinishedHelper(), httpImageUrl); - assertEquals(ImagePageGenerator.IMAGE_NOT_LOADED_STRING, - getTitleOnUiThread(awContents)); + mActivityTestRule.loadUrlSync( + awContents, contentClient.getOnPageFinishedHelper(), httpImageUrl); + Assert.assertEquals(ImagePageGenerator.IMAGE_NOT_LOADED_STRING, + mActivityTestRule.getTitleOnUiThread(awContents)); settings.setImagesEnabled(true); - pollInstrumentationThread(new Callable<Boolean>() { + AwActivityTestRule.pollInstrumentationThread(new Callable<Boolean>() { @Override public Boolean call() throws Exception { return ImagePageGenerator.IMAGE_LOADED_STRING.equals( - getTitleOnUiThread(awContents)); + mActivityTestRule.getTitleOnUiThread(awContents)); } }); } finally { @@ -1995,6 +2021,7 @@ } } + @Test @SmallTest @Feature({"AndroidWebView", "Preferences"}) public void testBlockNetworkImagesWithTwoViews() throws Throwable { @@ -2017,14 +2044,15 @@ } } + @Test @SmallTest @Feature({"AndroidWebView", "Preferences"}) public void testBlockNetworkLoadsWithHttpResources() throws Throwable { final TestAwContentsClient contentClient = new TestAwContentsClient(); final AwTestContainerView testContainer = - createAwTestContainerViewOnMainSync(contentClient); + mActivityTestRule.createAwTestContainerViewOnMainSync(contentClient); final AwContents awContents = testContainer.getAwContents(); - final AwSettings awSettings = getAwSettingsOnUiThread(awContents); + final AwSettings awSettings = mActivityTestRule.getAwSettingsOnUiThread(awContents); awSettings.setJavaScriptEnabled(true); ImagePageGenerator generator = new ImagePageGenerator(0, false); @@ -2041,28 +2069,26 @@ String pageHtml = "<img src='" + imageUrl + "' " + "onload=\"document.title='img_onload_fired';\" " + "onerror=\"document.title='img_onerror_fired';\" />"; - Context context = getInstrumentation().getTargetContext(); + Context context = InstrumentationRegistry.getInstrumentation().getTargetContext(); fileName = context.getCacheDir() + "/block_network_loads_test.html"; TestFileUtil.deleteFile(fileName); // Remove leftover file if any. TestFileUtil.createNewHtmlFile(fileName, "unset", pageHtml); // Actual test. Blocking should trigger onerror handler. awSettings.setBlockNetworkLoads(true); - loadUrlSync( - awContents, - contentClient.getOnPageFinishedHelper(), - "file:///" + fileName); - assertEquals(0, webServer.getRequestCount(httpPath)); - assertEquals("img_onerror_fired", getTitleOnUiThread(awContents)); + mActivityTestRule.loadUrlSync( + awContents, contentClient.getOnPageFinishedHelper(), "file:///" + fileName); + Assert.assertEquals(0, webServer.getRequestCount(httpPath)); + Assert.assertEquals( + "img_onerror_fired", mActivityTestRule.getTitleOnUiThread(awContents)); // Unblock should load normally. awSettings.setBlockNetworkLoads(false); - loadUrlSync( - awContents, - contentClient.getOnPageFinishedHelper(), - "file:///" + fileName); - assertEquals(1, webServer.getRequestCount(httpPath)); - assertEquals("img_onload_fired", getTitleOnUiThread(awContents)); + mActivityTestRule.loadUrlSync( + awContents, contentClient.getOnPageFinishedHelper(), "file:///" + fileName); + Assert.assertEquals(1, webServer.getRequestCount(httpPath)); + Assert.assertEquals( + "img_onload_fired", mActivityTestRule.getTitleOnUiThread(awContents)); } finally { webServer.shutdown(); if (fileName != null) TestFileUtil.deleteFile(fileName); @@ -2086,14 +2112,15 @@ } } + @Test @SmallTest @Feature({"AndroidWebView", "Preferences"}) public void testBlockNetworkLoadsWithAudio() throws Throwable { final TestAwContentsClient contentClient = new TestAwContentsClient(); final AwTestContainerView testContainer = - createAwTestContainerViewOnMainSync(contentClient); + mActivityTestRule.createAwTestContainerViewOnMainSync(contentClient); final AwContents awContents = testContainer.getAwContents(); - final AwSettings awSettings = getAwSettingsOnUiThread(awContents); + final AwSettings awSettings = mActivityTestRule.getAwSettingsOnUiThread(awContents); final CallbackHelper callback = new CallbackHelper(); awSettings.setJavaScriptEnabled(true); @@ -2112,18 +2139,18 @@ + "</body></html>"; // Actual test. Blocking should trigger onerror handler. awSettings.setBlockNetworkLoads(true); - runTestOnUiThread(new Runnable() { + InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() { @Override public void run() { awContents.addJavascriptInterface(new AudioEvent(callback), "AudioEvent"); } }); int count = callback.getCallCount(); - loadDataSync(awContents, contentClient.getOnPageFinishedHelper(), pageHtml, - "text/html", false); + mActivityTestRule.loadDataSync(awContents, contentClient.getOnPageFinishedHelper(), + pageHtml, "text/html", false); DOMUtils.clickNode(testContainer.getContentViewCore(), "play"); callback.waitForCallback(count, 1); - assertEquals(0, webServer.getRequestCount(httpPath)); + Assert.assertEquals(0, webServer.getRequestCount(httpPath)); // The below test failed in Nexus Galaxy. // See https://code.google.com/p/chromium/issues/detail?id=313463 @@ -2142,6 +2169,7 @@ } // Test an assert URL (file:///android_asset/) + @Test @SmallTest @Feature({"AndroidWebView", "Navigation"}) public void testAssetUrl() throws Throwable { @@ -2150,15 +2178,15 @@ final String expectedTitle = "Asset File"; final TestAwContentsClient contentClient = new TestAwContentsClient(); final AwTestContainerView testContainerView = - createAwTestContainerViewOnMainSync(contentClient); + mActivityTestRule.createAwTestContainerViewOnMainSync(contentClient); final AwContents awContents = testContainerView.getAwContents(); - loadUrlSync(awContents, - contentClient.getOnPageFinishedHelper(), - "file:///android_asset/asset_file.html"); - assertEquals(expectedTitle, getTitleOnUiThread(awContents)); + mActivityTestRule.loadUrlSync(awContents, contentClient.getOnPageFinishedHelper(), + "file:///android_asset/asset_file.html"); + Assert.assertEquals(expectedTitle, mActivityTestRule.getTitleOnUiThread(awContents)); } // Test a resource URL (file:///android_res/). + @Test @SmallTest @Feature({"AndroidWebView", "Navigation"}) public void testResourceUrl() throws Throwable { @@ -2167,15 +2195,15 @@ final String expectedTitle = "Resource File"; final TestAwContentsClient contentClient = new TestAwContentsClient(); final AwTestContainerView testContainerView = - createAwTestContainerViewOnMainSync(contentClient); + mActivityTestRule.createAwTestContainerViewOnMainSync(contentClient); final AwContents awContents = testContainerView.getAwContents(); - loadUrlSync(awContents, - contentClient.getOnPageFinishedHelper(), - "file:///android_res/raw/resource_file.html"); - assertEquals(expectedTitle, getTitleOnUiThread(awContents)); + mActivityTestRule.loadUrlSync(awContents, contentClient.getOnPageFinishedHelper(), + "file:///android_res/raw/resource_file.html"); + Assert.assertEquals(expectedTitle, mActivityTestRule.getTitleOnUiThread(awContents)); } // Test that the file URL access toggle does not affect asset URLs. + @Test @SmallTest @Feature({"AndroidWebView", "Navigation"}) public void testFileUrlAccessToggleDoesNotBlockAssetUrls() throws Throwable { @@ -2184,17 +2212,17 @@ final String expectedTitle = "Asset File"; final TestAwContentsClient contentClient = new TestAwContentsClient(); final AwTestContainerView testContainerView = - createAwTestContainerViewOnMainSync(contentClient); + mActivityTestRule.createAwTestContainerViewOnMainSync(contentClient); final AwContents awContents = testContainerView.getAwContents(); - final AwSettings settings = getAwSettingsOnUiThread(awContents); + final AwSettings settings = mActivityTestRule.getAwSettingsOnUiThread(awContents); settings.setAllowFileAccess(false); - loadUrlSync(awContents, - contentClient.getOnPageFinishedHelper(), + mActivityTestRule.loadUrlSync(awContents, contentClient.getOnPageFinishedHelper(), "file:///android_asset/asset_file.html"); - assertEquals(expectedTitle, getTitleOnUiThread(awContents)); + Assert.assertEquals(expectedTitle, mActivityTestRule.getTitleOnUiThread(awContents)); } // Test that the file URL access toggle does not affect resource URLs. + @Test @SmallTest @Feature({"AndroidWebView", "Navigation"}) public void testFileUrlAccessToggleDoesNotBlockResourceUrls() throws Throwable { @@ -2203,16 +2231,16 @@ final String expectedTitle = "Resource File"; final TestAwContentsClient contentClient = new TestAwContentsClient(); final AwTestContainerView testContainerView = - createAwTestContainerViewOnMainSync(contentClient); + mActivityTestRule.createAwTestContainerViewOnMainSync(contentClient); final AwContents awContents = testContainerView.getAwContents(); - final AwSettings settings = getAwSettingsOnUiThread(awContents); + final AwSettings settings = mActivityTestRule.getAwSettingsOnUiThread(awContents); settings.setAllowFileAccess(false); - loadUrlSync(awContents, - contentClient.getOnPageFinishedHelper(), - "file:///android_res/raw/resource_file.html"); - assertEquals(expectedTitle, getTitleOnUiThread(awContents)); + mActivityTestRule.loadUrlSync(awContents, contentClient.getOnPageFinishedHelper(), + "file:///android_res/raw/resource_file.html"); + Assert.assertEquals(expectedTitle, mActivityTestRule.getTitleOnUiThread(awContents)); } + @Test @SmallTest @Feature({"AndroidWebView", "Preferences"}) public void testLayoutAlgorithmWithTwoViews() throws Throwable { @@ -2222,6 +2250,7 @@ new AwSettingsLayoutAlgorithmTestHelper(views.getContainer1(), views.getClient1())); } + @Test @SmallTest @Feature({"AndroidWebView", "Preferences"}) public void testTextZoomWithTwoViews() throws Throwable { @@ -2231,6 +2260,7 @@ new AwSettingsTextZoomTestHelper(views.getContainer1(), views.getClient1())); } + @Test @SmallTest @Feature({"AndroidWebView", "Preferences"}) public void testTextZoomAutosizingWithTwoViews() throws Throwable { @@ -2242,6 +2272,7 @@ views.getContainer1(), views.getClient1())); } + @Test @SmallTest @Feature({"AndroidWebView", "Preferences"}) public void testJavaScriptPopupsWithTwoViews() throws Throwable { @@ -2252,11 +2283,12 @@ views.getContainer1(), views.getClient1())); } + @Test @SmallTest @Feature({"AndroidWebView", "Preferences"}) public void testJavaScriptPopupsAndMultiWindowsWithTwoViews() throws Throwable { final ViewPair views = createViews(); - getInstrumentation().runOnMainSync(new Runnable() { + InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() { @Override public void run() { AwSettings awSettings = views.getContents0().getSettings(); @@ -2273,51 +2305,53 @@ views.getContainer1(), views.getClient1())); } + @Test @SmallTest @Feature({"AndroidWebView", "Preferences"}) public void testCacheMode() throws Throwable { final TestAwContentsClient contentClient = new TestAwContentsClient(); final AwTestContainerView testContainer = - createAwTestContainerViewOnMainSync(contentClient); + mActivityTestRule.createAwTestContainerViewOnMainSync(contentClient); final AwContents awContents = testContainer.getAwContents(); - final AwSettings awSettings = getAwSettingsOnUiThread(testContainer.getAwContents()); - clearCacheOnUiThread(awContents, true); + final AwSettings awSettings = + mActivityTestRule.getAwSettingsOnUiThread(testContainer.getAwContents()); + mActivityTestRule.clearCacheOnUiThread(awContents, true); - assertEquals(WebSettings.LOAD_DEFAULT, awSettings.getCacheMode()); + Assert.assertEquals(WebSettings.LOAD_DEFAULT, awSettings.getCacheMode()); TestWebServer webServer = TestWebServer.start(); try { final String htmlPath = "/testCacheMode.html"; final String url = webServer.setResponse(htmlPath, "response", null); awSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); - loadUrlSync(awContents, contentClient.getOnPageFinishedHelper(), url); - assertEquals(1, webServer.getRequestCount(htmlPath)); - loadUrlSync(awContents, contentClient.getOnPageFinishedHelper(), url); - assertEquals(1, webServer.getRequestCount(htmlPath)); + mActivityTestRule.loadUrlSync(awContents, contentClient.getOnPageFinishedHelper(), url); + Assert.assertEquals(1, webServer.getRequestCount(htmlPath)); + mActivityTestRule.loadUrlSync(awContents, contentClient.getOnPageFinishedHelper(), url); + Assert.assertEquals(1, webServer.getRequestCount(htmlPath)); awSettings.setCacheMode(WebSettings.LOAD_NO_CACHE); - loadUrlSync(awContents, contentClient.getOnPageFinishedHelper(), url); - assertEquals(2, webServer.getRequestCount(htmlPath)); - loadUrlSync(awContents, contentClient.getOnPageFinishedHelper(), url); - assertEquals(3, webServer.getRequestCount(htmlPath)); + mActivityTestRule.loadUrlSync(awContents, contentClient.getOnPageFinishedHelper(), url); + Assert.assertEquals(2, webServer.getRequestCount(htmlPath)); + mActivityTestRule.loadUrlSync(awContents, contentClient.getOnPageFinishedHelper(), url); + Assert.assertEquals(3, webServer.getRequestCount(htmlPath)); awSettings.setCacheMode(WebSettings.LOAD_CACHE_ONLY); - loadUrlSync(awContents, contentClient.getOnPageFinishedHelper(), url); - assertEquals(3, webServer.getRequestCount(htmlPath)); - loadUrlSync(awContents, contentClient.getOnPageFinishedHelper(), url); - assertEquals(3, webServer.getRequestCount(htmlPath)); + mActivityTestRule.loadUrlSync(awContents, contentClient.getOnPageFinishedHelper(), url); + Assert.assertEquals(3, webServer.getRequestCount(htmlPath)); + mActivityTestRule.loadUrlSync(awContents, contentClient.getOnPageFinishedHelper(), url); + Assert.assertEquals(3, webServer.getRequestCount(htmlPath)); final String htmlNotInCachePath = "/testCacheMode-not-in-cache.html"; final String urlNotInCache = webServer.setResponse(htmlNotInCachePath, "", null); - loadUrlSyncAndExpectError(awContents, + mActivityTestRule.loadUrlSyncAndExpectError(awContents, contentClient.getOnPageFinishedHelper(), - contentClient.getOnReceivedErrorHelper(), - urlNotInCache); - assertEquals(0, webServer.getRequestCount(htmlNotInCachePath)); + contentClient.getOnReceivedErrorHelper(), urlNotInCache); + Assert.assertEquals(0, webServer.getRequestCount(htmlNotInCachePath)); } finally { webServer.shutdown(); } } + @Test @SmallTest @Feature({"AndroidWebView", "Preferences"}) // As our implementation of network loads blocking uses the same net::URLRequest settings, make @@ -2326,48 +2360,46 @@ public void testCacheModeWithBlockedNetworkLoads() throws Throwable { final TestAwContentsClient contentClient = new TestAwContentsClient(); final AwTestContainerView testContainer = - createAwTestContainerViewOnMainSync(contentClient); + mActivityTestRule.createAwTestContainerViewOnMainSync(contentClient); final AwContents awContents = testContainer.getAwContents(); - final AwSettings awSettings = getAwSettingsOnUiThread(testContainer.getAwContents()); - clearCacheOnUiThread(awContents, true); + final AwSettings awSettings = + mActivityTestRule.getAwSettingsOnUiThread(testContainer.getAwContents()); + mActivityTestRule.clearCacheOnUiThread(awContents, true); - assertEquals(WebSettings.LOAD_DEFAULT, awSettings.getCacheMode()); + Assert.assertEquals(WebSettings.LOAD_DEFAULT, awSettings.getCacheMode()); awSettings.setBlockNetworkLoads(true); TestWebServer webServer = TestWebServer.start(); try { final String htmlPath = "/testCacheModeWithBlockedNetworkLoads.html"; final String url = webServer.setResponse(htmlPath, "response", null); - loadUrlSyncAndExpectError(awContents, + mActivityTestRule.loadUrlSyncAndExpectError(awContents, contentClient.getOnPageFinishedHelper(), - contentClient.getOnReceivedErrorHelper(), - url); - assertEquals(0, webServer.getRequestCount(htmlPath)); + contentClient.getOnReceivedErrorHelper(), url); + Assert.assertEquals(0, webServer.getRequestCount(htmlPath)); awSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); - loadUrlSyncAndExpectError(awContents, + mActivityTestRule.loadUrlSyncAndExpectError(awContents, contentClient.getOnPageFinishedHelper(), - contentClient.getOnReceivedErrorHelper(), - url); - assertEquals(0, webServer.getRequestCount(htmlPath)); + contentClient.getOnReceivedErrorHelper(), url); + Assert.assertEquals(0, webServer.getRequestCount(htmlPath)); awSettings.setCacheMode(WebSettings.LOAD_NO_CACHE); - loadUrlSyncAndExpectError(awContents, + mActivityTestRule.loadUrlSyncAndExpectError(awContents, contentClient.getOnPageFinishedHelper(), - contentClient.getOnReceivedErrorHelper(), - url); - assertEquals(0, webServer.getRequestCount(htmlPath)); + contentClient.getOnReceivedErrorHelper(), url); + Assert.assertEquals(0, webServer.getRequestCount(htmlPath)); awSettings.setCacheMode(WebSettings.LOAD_CACHE_ONLY); - loadUrlSyncAndExpectError(awContents, + mActivityTestRule.loadUrlSyncAndExpectError(awContents, contentClient.getOnPageFinishedHelper(), - contentClient.getOnReceivedErrorHelper(), - url); - assertEquals(0, webServer.getRequestCount(htmlPath)); + contentClient.getOnReceivedErrorHelper(), url); + Assert.assertEquals(0, webServer.getRequestCount(htmlPath)); } finally { webServer.shutdown(); } } + @Test @SmallTest @Feature({"AndroidWebView", "Preferences"}) public void testCacheModeWithTwoViews() throws Throwable { @@ -2425,7 +2457,7 @@ private int waitUntilResourceIsRequested( final String path, final int initialRequestCount) throws Exception { - pollInstrumentationThread(new Callable<Boolean>() { + AwActivityTestRule.pollInstrumentationThread(new Callable<Boolean>() { @Override public Boolean call() throws Exception { return mWebServer.getRequestCount(path) > initialRequestCount; @@ -2435,14 +2467,15 @@ } } + @Test @SmallTest @Feature({"AndroidWebView", "Preferences", "AppCache"}) public void testAppCache() throws Throwable { final TestAwContentsClient contentClient = new TestAwContentsClient(); final AwTestContainerView testContainer = - createAwTestContainerViewOnMainSync(contentClient); + mActivityTestRule.createAwTestContainerViewOnMainSync(contentClient); final AwContents awContents = testContainer.getAwContents(); - final AwSettings settings = getAwSettingsOnUiThread(awContents); + final AwSettings settings = mActivityTestRule.getAwSettingsOnUiThread(awContents); settings.setJavaScriptEnabled(true); // Note that the cache isn't actually enabled until the call to setAppCachePath. settings.setAppCacheEnabled(true); @@ -2451,26 +2484,23 @@ try { ManifestTestHelper helper = new ManifestTestHelper( webServer, "testAppCache.html", "appcache.manifest"); - loadUrlSync( - awContents, - contentClient.getOnPageFinishedHelper(), - helper.getHtmlUrl()); + mActivityTestRule.loadUrlSync( + awContents, contentClient.getOnPageFinishedHelper(), helper.getHtmlUrl()); helper.waitUntilHtmlIsRequested(0); // Unfortunately, there is no other good way of verifying that AppCache is // disabled, other than checking that it didn't try to fetch the manifest. Thread.sleep(1000); - assertEquals(0, webServer.getRequestCount(helper.getManifestPath())); + Assert.assertEquals(0, webServer.getRequestCount(helper.getManifestPath())); settings.setAppCachePath("whatever"); // Enables AppCache. - loadUrlSync( - awContents, - contentClient.getOnPageFinishedHelper(), - helper.getHtmlUrl()); + mActivityTestRule.loadUrlSync( + awContents, contentClient.getOnPageFinishedHelper(), helper.getHtmlUrl()); helper.waitUntilManifestIsRequested(0); } finally { webServer.shutdown(); } } + @Test @SmallTest @Feature({"AndroidWebView", "Preferences", "AppCache"}) @RetryOnFailure @@ -2480,11 +2510,11 @@ // will take about 20 seconds. ViewPair views = createViews(); - AwSettings settings0 = getAwSettingsOnUiThread(views.getContents0()); + AwSettings settings0 = mActivityTestRule.getAwSettingsOnUiThread(views.getContents0()); settings0.setJavaScriptEnabled(true); settings0.setAppCachePath("whatever"); settings0.setAppCacheEnabled(true); - AwSettings settings1 = getAwSettingsOnUiThread(views.getContents1()); + AwSettings settings1 = mActivityTestRule.getAwSettingsOnUiThread(views.getContents1()); settings1.setJavaScriptEnabled(true); // AppCachePath setting is global, no need to set it for the second view. settings1.setAppCacheEnabled(true); @@ -2493,42 +2523,35 @@ try { ManifestTestHelper helper0 = new ManifestTestHelper( webServer, "testAppCache_0.html", "appcache.manifest_0"); - loadUrlSync( - views.getContents0(), - views.getClient0().getOnPageFinishedHelper(), - helper0.getHtmlUrl()); + mActivityTestRule.loadUrlSync(views.getContents0(), + views.getClient0().getOnPageFinishedHelper(), helper0.getHtmlUrl()); int manifestRequests0 = helper0.waitUntilManifestIsRequested(0); ManifestTestHelper helper1 = new ManifestTestHelper( webServer, "testAppCache_1.html", "appcache.manifest_1"); - loadUrlSync( - views.getContents1(), - views.getClient1().getOnPageFinishedHelper(), - helper1.getHtmlUrl()); + mActivityTestRule.loadUrlSync(views.getContents1(), + views.getClient1().getOnPageFinishedHelper(), helper1.getHtmlUrl()); helper1.waitUntilManifestIsRequested(0); settings1.setAppCacheEnabled(false); - loadUrlSync( - views.getContents0(), - views.getClient0().getOnPageFinishedHelper(), - helper0.getHtmlUrl()); + mActivityTestRule.loadUrlSync(views.getContents0(), + views.getClient0().getOnPageFinishedHelper(), helper0.getHtmlUrl()); helper0.waitUntilManifestIsRequested(manifestRequests0); final int prevManifestRequestCount = webServer.getRequestCount(helper1.getManifestPath()); int htmlRequests1 = webServer.getRequestCount(helper1.getHtmlPath()); - loadUrlSync( - views.getContents1(), - views.getClient1().getOnPageFinishedHelper(), - helper1.getHtmlUrl()); + mActivityTestRule.loadUrlSync(views.getContents1(), + views.getClient1().getOnPageFinishedHelper(), helper1.getHtmlUrl()); helper1.waitUntilHtmlIsRequested(htmlRequests1); // Unfortunately, there is no other good way of verifying that AppCache is // disabled, other than checking that it didn't try to fetch the manifest. Thread.sleep(1000); - assertEquals( + Assert.assertEquals( prevManifestRequestCount, webServer.getRequestCount(helper1.getManifestPath())); } finally { webServer.shutdown(); } } + @Test @SmallTest @Feature({"AndroidWebView", "Preferences"}) public void testUseWideViewportWithTwoViews() throws Throwable { @@ -2538,6 +2561,7 @@ new AwSettingsUseWideViewportTestHelper(views.getContainer1(), views.getClient1())); } + @Test @SmallTest @Feature({"AndroidWebView", "Preferences"}) public void testUseWideViewportWithTwoViewsNoQuirks() throws Throwable { @@ -2551,7 +2575,7 @@ AwTestContainerView testContainer, CallbackHelper onPageFinishedHelper) throws Throwable { final AwContents awContents = testContainer.getAwContents(); - AwSettings settings = getAwSettingsOnUiThread(awContents); + AwSettings settings = mActivityTestRule.getAwSettingsOnUiThread(awContents); final String pageTemplate = "<html><head>%s</head>" + "<body onload='document.title=document.body.clientWidth'></body></html>"; @@ -2569,72 +2593,79 @@ int displayWidth = (int) (displayAndroid.getDisplayWidth() / displayAndroid.getDipScale()); settings.setJavaScriptEnabled(true); - assertFalse(settings.getUseWideViewPort()); + Assert.assertFalse(settings.getUseWideViewPort()); // When UseWideViewPort is off, "width" setting of "meta viewport" // tags is ignored, and the layout width is set to device width in CSS pixels. // Thus, all 3 pages will have the same body width. - loadDataSync(awContents, onPageFinishedHelper, pageNoViewport, "text/html", false); - int actualWidth = Integer.parseInt(getTitleOnUiThread(awContents)); + mActivityTestRule.loadDataSync( + awContents, onPageFinishedHelper, pageNoViewport, "text/html", false); + int actualWidth = Integer.parseInt(mActivityTestRule.getTitleOnUiThread(awContents)); // Avoid rounding errors. - assertTrue("Expected: " + displayWidth + ", Actual: " + actualWidth, + Assert.assertTrue("Expected: " + displayWidth + ", Actual: " + actualWidth, Math.abs(displayWidth - actualWidth) <= 1); - loadDataSync(awContents, onPageFinishedHelper, pageViewportDeviceWidth, "text/html", false); - actualWidth = Integer.parseInt(getTitleOnUiThread(awContents)); - assertTrue("Expected: " + displayWidth + ", Actual: " + actualWidth, + mActivityTestRule.loadDataSync( + awContents, onPageFinishedHelper, pageViewportDeviceWidth, "text/html", false); + actualWidth = Integer.parseInt(mActivityTestRule.getTitleOnUiThread(awContents)); + Assert.assertTrue("Expected: " + displayWidth + ", Actual: " + actualWidth, Math.abs(displayWidth - actualWidth) <= 1); - loadDataSync( + mActivityTestRule.loadDataSync( awContents, onPageFinishedHelper, pageViewportSpecifiedWidth, "text/html", false); - actualWidth = Integer.parseInt(getTitleOnUiThread(awContents)); - assertTrue("Expected: " + displayWidth + ", Actual: " + actualWidth, + actualWidth = Integer.parseInt(mActivityTestRule.getTitleOnUiThread(awContents)); + Assert.assertTrue("Expected: " + displayWidth + ", Actual: " + actualWidth, Math.abs(displayWidth - actualWidth) <= 1); settings.setUseWideViewPort(true); // When UseWideViewPort is on, "meta viewport" tag is used. // If there is no viewport tag, or width isn't specified, // then layout width is set to max(980, <device-width-in-DIP-pixels>) - loadDataSync(awContents, onPageFinishedHelper, pageNoViewport, "text/html", false); - actualWidth = Integer.parseInt(getTitleOnUiThread(awContents)); - assertTrue("Expected: >= 980 , Actual: " + actualWidth, actualWidth >= 980); - loadDataSync(awContents, onPageFinishedHelper, pageViewportDeviceWidth, "text/html", false); - actualWidth = Integer.parseInt(getTitleOnUiThread(awContents)); - assertTrue("Expected: " + displayWidth + ", Actual: " + actualWidth, + mActivityTestRule.loadDataSync( + awContents, onPageFinishedHelper, pageNoViewport, "text/html", false); + actualWidth = Integer.parseInt(mActivityTestRule.getTitleOnUiThread(awContents)); + Assert.assertTrue("Expected: >= 980 , Actual: " + actualWidth, actualWidth >= 980); + mActivityTestRule.loadDataSync( + awContents, onPageFinishedHelper, pageViewportDeviceWidth, "text/html", false); + actualWidth = Integer.parseInt(mActivityTestRule.getTitleOnUiThread(awContents)); + Assert.assertTrue("Expected: " + displayWidth + ", Actual: " + actualWidth, Math.abs(displayWidth - actualWidth) <= 1); - loadDataSync( + mActivityTestRule.loadDataSync( awContents, onPageFinishedHelper, pageViewportSpecifiedWidth, "text/html", false); - assertEquals(viewportTagSpecifiedWidth, getTitleOnUiThread(awContents)); + Assert.assertEquals( + viewportTagSpecifiedWidth, mActivityTestRule.getTitleOnUiThread(awContents)); } // WebView layout width tests are flaky: http://crbug.com/746264 - @RetryOnFailure + @Test @SmallTest @Feature({"AndroidWebView", "Preferences"}) public void testUseWideViewportLayoutWidth() throws Throwable { TestAwContentsClient contentClient = new TestAwContentsClient(); AwTestContainerView testContainerView = - createAwTestContainerViewOnMainSync(contentClient); + mActivityTestRule.createAwTestContainerViewOnMainSync(contentClient); useWideViewportLayoutWidthTest(testContainerView, contentClient.getOnPageFinishedHelper()); } // WebView layout width tests are flaky: http://crbug.com/746264 @RetryOnFailure + @Test @SmallTest @Feature({"AndroidWebView", "Preferences"}) public void testUseWideViewportLayoutWidthNoQuirks() throws Throwable { TestAwContentsClient contentClient = new TestAwContentsClient(); AwTestContainerView testContainerView = - createAwTestContainerViewOnMainSync(contentClient, false); + mActivityTestRule.createAwTestContainerViewOnMainSync(contentClient, false); useWideViewportLayoutWidthTest(testContainerView, contentClient.getOnPageFinishedHelper()); } + @Test @MediumTest @Feature({"AndroidWebView", "Preferences"}) public void testUseWideViewportControlsDoubleTabToZoom() throws Throwable { final TestAwContentsClient contentClient = new TestAwContentsClient(); final AwTestContainerView testContainerView = - createAwTestContainerViewOnMainSync(contentClient); + mActivityTestRule.createAwTestContainerViewOnMainSync(contentClient); final AwContents awContents = testContainerView.getAwContents(); CallbackHelper onPageFinishedHelper = contentClient.getOnPageFinishedHelper(); - AwSettings settings = getAwSettingsOnUiThread(awContents); + AwSettings settings = mActivityTestRule.getAwSettingsOnUiThread(awContents); settings.setBuiltInZoomControls(true); DisplayAndroid displayAndroid = @@ -2646,25 +2677,26 @@ + "<style> body { width: " + layoutWidth + "px; }</style></head>" + "<body>Page Text</body></html>"; - assertFalse(settings.getUseWideViewPort()); + Assert.assertFalse(settings.getUseWideViewPort()); // Without wide viewport the <meta viewport> tag will be ignored by WebView, // but it doesn't really matter as we don't expect double tap to change the scale. - loadDataSync(awContents, onPageFinishedHelper, page, "text/html", false); - final float initialScale = getScaleOnUiThread(awContents); + mActivityTestRule.loadDataSync(awContents, onPageFinishedHelper, page, "text/html", false); + final float initialScale = mActivityTestRule.getScaleOnUiThread(awContents); simulateDoubleTapCenterOfWebViewOnUiThread(testContainerView); Thread.sleep(1000); - assertEquals(initialScale, getScaleOnUiThread(awContents)); + Assert.assertEquals(initialScale, mActivityTestRule.getScaleOnUiThread(awContents), 0); settings.setUseWideViewPort(true); - loadDataSync(awContents, onPageFinishedHelper, page, "text/html", false); + mActivityTestRule.loadDataSync(awContents, onPageFinishedHelper, page, "text/html", false); int onScaleChangedCallCount = contentClient.getOnScaleChangedHelper().getCallCount(); simulateDoubleTapCenterOfWebViewOnUiThread(testContainerView); contentClient.getOnScaleChangedHelper().waitForCallback(onScaleChangedCallCount); - final float zoomedOutScale = getScaleOnUiThread(awContents); - assertTrue("zoomedOut: " + zoomedOutScale + ", initial: " + initialScale, + final float zoomedOutScale = mActivityTestRule.getScaleOnUiThread(awContents); + Assert.assertTrue("zoomedOut: " + zoomedOutScale + ", initial: " + initialScale, zoomedOutScale < initialScale); } + @Test @SmallTest @Feature({"AndroidWebView", "Preferences"}) public void testForceZeroLayoutHeightWithTwoViews() throws Throwable { @@ -2676,6 +2708,7 @@ views.getContainer1(), views.getClient1(), false)); } + @Test @SmallTest @Feature({"AndroidWebView", "Preferences"}) @RetryOnFailure @@ -2688,6 +2721,7 @@ views.getContainer1(), views.getClient1(), true)); } + @Test @SmallTest @Feature({"AndroidWebView", "Preferences"}) public void testZeroLayoutHeightDisablesViewportQuirkWithTwoViews() throws Throwable { @@ -2699,6 +2733,7 @@ views.getContainer1(), views.getClient1())); } + @Test @SmallTest @Feature({"AndroidWebView", "Preferences"}) public void testLoadWithOverviewModeWithTwoViews() throws Throwable { @@ -2710,6 +2745,7 @@ views.getContainer1(), views.getClient1(), false)); } + @Test @SmallTest @Feature({"AndroidWebView", "Preferences"}) public void testLoadWithOverviewModeViewportTagWithTwoViews() throws Throwable { @@ -2725,17 +2761,19 @@ * @SmallTest * @Feature({"AndroidWebView", "Preferences"}) */ + @Test @DisabledTest(message = "crbug.com/644894") public void testSetInitialScale() throws Throwable { final TestAwContentsClient contentClient = new TestAwContentsClient(); final AwTestContainerView testContainerView = - createAwTestContainerViewOnMainSync(contentClient); + mActivityTestRule.createAwTestContainerViewOnMainSync(contentClient); final AwContents awContents = testContainerView.getAwContents(); - final AwSettings awSettings = getAwSettingsOnUiThread(awContents); + final AwSettings awSettings = mActivityTestRule.getAwSettingsOnUiThread(awContents); CallbackHelper onPageFinishedHelper = contentClient.getOnPageFinishedHelper(); - WindowManager wm = (WindowManager) getInstrumentation().getTargetContext() - .getSystemService(Context.WINDOW_SERVICE); + WindowManager wm = (WindowManager) InstrumentationRegistry.getInstrumentation() + .getTargetContext() + .getSystemService(Context.WINDOW_SERVICE); Point screenSize = new Point(); wm.getDefaultDisplay().getSize(screenSize); // Make sure after 50% scale, page width still larger than screen. @@ -2744,47 +2782,58 @@ final String page = "<html><body>" + "<p style='height:" + height + "px;width:" + width + "px'>" + "testSetInitialScale</p></body></html>"; - final float defaultScale = - getInstrumentation().getTargetContext().getResources().getDisplayMetrics().density; + final float defaultScale = InstrumentationRegistry.getInstrumentation() + .getTargetContext() + .getResources() + .getDisplayMetrics() + .density; - assertEquals(defaultScale, getPixelScaleOnUiThread(awContents), .01f); - loadDataSync(awContents, onPageFinishedHelper, page, "text/html", false); - assertEquals(defaultScale, getPixelScaleOnUiThread(awContents), .01f); + Assert.assertEquals( + defaultScale, mActivityTestRule.getPixelScaleOnUiThread(awContents), .01f); + mActivityTestRule.loadDataSync(awContents, onPageFinishedHelper, page, "text/html", false); + Assert.assertEquals( + defaultScale, mActivityTestRule.getPixelScaleOnUiThread(awContents), .01f); int onScaleChangedCallCount = contentClient.getOnScaleChangedHelper().getCallCount(); awSettings.setInitialPageScale(50); - loadDataSync(awContents, onPageFinishedHelper, page, "text/html", false); + mActivityTestRule.loadDataSync(awContents, onPageFinishedHelper, page, "text/html", false); contentClient.getOnScaleChangedHelper().waitForCallback(onScaleChangedCallCount); - assertEquals(0.5f, getPixelScaleOnUiThread(awContents), .01f); + Assert.assertEquals(0.5f, mActivityTestRule.getPixelScaleOnUiThread(awContents), .01f); onScaleChangedCallCount = contentClient.getOnScaleChangedHelper().getCallCount(); awSettings.setInitialPageScale(500); - loadDataSync(awContents, onPageFinishedHelper, page, "text/html", false); + mActivityTestRule.loadDataSync(awContents, onPageFinishedHelper, page, "text/html", false); contentClient.getOnScaleChangedHelper().waitForCallback(onScaleChangedCallCount); - assertEquals(5.0f, getPixelScaleOnUiThread(awContents), .01f); + Assert.assertEquals(5.0f, mActivityTestRule.getPixelScaleOnUiThread(awContents), .01f); onScaleChangedCallCount = contentClient.getOnScaleChangedHelper().getCallCount(); awSettings.setInitialPageScale(0); - loadDataSync(awContents, onPageFinishedHelper, page, "text/html", false); + mActivityTestRule.loadDataSync(awContents, onPageFinishedHelper, page, "text/html", false); contentClient.getOnScaleChangedHelper().waitForCallback(onScaleChangedCallCount); - assertEquals(defaultScale, getPixelScaleOnUiThread(awContents), .01f); + Assert.assertEquals( + defaultScale, mActivityTestRule.getPixelScaleOnUiThread(awContents), .01f); } + @Test @DisableHardwareAccelerationForTest @LargeTest @Feature({"AndroidWebView", "Preferences"}) public void testMediaPlaybackWithoutUserGesture() throws Throwable { - assertTrue(VideoTestUtil.runVideoTest(this, false, WAIT_TIMEOUT_MS)); + Assert.assertTrue(VideoTestUtil.runVideoTest(InstrumentationRegistry.getInstrumentation(), + mActivityTestRule, false, WAIT_TIMEOUT_MS)); } + @Test @DisableHardwareAccelerationForTest @SmallTest @Feature({"AndroidWebView", "Preferences"}) public void testMediaPlaybackWithUserGesture() throws Throwable { // Wait for 5 second to see if video played. - assertFalse(VideoTestUtil.runVideoTest(this, true, scaleTimeout(5000))); + Assert.assertFalse(VideoTestUtil.runVideoTest(InstrumentationRegistry.getInstrumentation(), + mActivityTestRule, true, scaleTimeout(5000))); } + @Test @SmallTest @Feature({"AndroidWebView", "Preferences"}) public void testDefaultVideoPosterURL() throws Throwable { @@ -2799,8 +2848,9 @@ return null; } }; - final AwContents awContents = createAwTestContainerViewOnMainSync(client).getAwContents(); - getInstrumentation().runOnMainSync(new Runnable() { + final AwContents awContents = + mActivityTestRule.createAwTestContainerViewOnMainSync(client).getAwContents(); + InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() { @Override public void run() { AwSettings awSettings = awContents.getSettings(); @@ -2812,7 +2862,7 @@ String data = "<html><head><body>" + "<video id='video' control src='" + webServer.getOnePixelOneFrameWebmURL() + "' /> </body></html>"; - loadDataAsync(awContents, data, "text/html", false); + mActivityTestRule.loadDataAsync(awContents, data, "text/html", false); videoPosterAccessedCallbackHelper.waitForCallback(0, 1, 20, TimeUnit.SECONDS); } finally { if (webServer.getTestWebServer() != null) { @@ -2821,6 +2871,7 @@ } } + @Test @SmallTest @Feature({"AndroidWebView", "Preferences"}) public void testAllowMixedMode() throws Throwable { @@ -2831,9 +2882,9 @@ } }; final AwTestContainerView testContainerView = - createAwTestContainerViewOnMainSync(contentClient); + mActivityTestRule.createAwTestContainerViewOnMainSync(contentClient); final AwContents awContents = testContainerView.getAwContents(); - final AwSettings awSettings = getAwSettingsOnUiThread(awContents); + final AwSettings awSettings = mActivityTestRule.getAwSettingsOnUiThread(awContents); awSettings.setJavaScriptEnabled(true); @@ -2857,22 +2908,25 @@ String fullSecureUrl = httpsServer.setResponse(secureUrl, secureHtml, null); awSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_NEVER_ALLOW); - loadUrlSync(awContents, contentClient.getOnPageFinishedHelper(), fullSecureUrl); - assertEquals(1, httpsServer.getRequestCount(secureUrl)); - assertEquals(0, httpServer.getRequestCount(jsUrl)); - assertEquals(0, httpServer.getRequestCount(imageUrl)); + mActivityTestRule.loadUrlSync( + awContents, contentClient.getOnPageFinishedHelper(), fullSecureUrl); + Assert.assertEquals(1, httpsServer.getRequestCount(secureUrl)); + Assert.assertEquals(0, httpServer.getRequestCount(jsUrl)); + Assert.assertEquals(0, httpServer.getRequestCount(imageUrl)); awSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW); - loadUrlSync(awContents, contentClient.getOnPageFinishedHelper(), fullSecureUrl); - assertEquals(2, httpsServer.getRequestCount(secureUrl)); - assertEquals(1, httpServer.getRequestCount(jsUrl)); - assertEquals(1, httpServer.getRequestCount(imageUrl)); + mActivityTestRule.loadUrlSync( + awContents, contentClient.getOnPageFinishedHelper(), fullSecureUrl); + Assert.assertEquals(2, httpsServer.getRequestCount(secureUrl)); + Assert.assertEquals(1, httpServer.getRequestCount(jsUrl)); + Assert.assertEquals(1, httpServer.getRequestCount(imageUrl)); awSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_COMPATIBILITY_MODE); - loadUrlSync(awContents, contentClient.getOnPageFinishedHelper(), fullSecureUrl); - assertEquals(3, httpsServer.getRequestCount(secureUrl)); - assertEquals(1, httpServer.getRequestCount(jsUrl)); - assertEquals(2, httpServer.getRequestCount(imageUrl)); + mActivityTestRule.loadUrlSync( + awContents, contentClient.getOnPageFinishedHelper(), fullSecureUrl); + Assert.assertEquals(3, httpsServer.getRequestCount(secureUrl)); + Assert.assertEquals(1, httpServer.getRequestCount(jsUrl)); + Assert.assertEquals(2, httpServer.getRequestCount(imageUrl)); } finally { if (httpServer != null) { httpServer.shutdown(); @@ -2883,14 +2937,15 @@ } } + @Test @SmallTest @Feature({"AndroidWebView", "Preferences"}) public void testUpdatingUserAgentWhileLoadingCausesReload() throws Throwable { final TestAwContentsClient contentClient = new TestAwContentsClient(); final AwTestContainerView testContainerView = - createAwTestContainerViewOnMainSync(contentClient); + mActivityTestRule.createAwTestContainerViewOnMainSync(contentClient); final AwContents awContents = testContainerView.getAwContents(); - final AwSettings awSettings = getAwSettingsOnUiThread(awContents); + final AwSettings awSettings = mActivityTestRule.getAwSettingsOnUiThread(awContents); TestWebServer httpServer = null; try { @@ -2910,10 +2965,10 @@ DoUpdateVisitedHistoryHelper doUpdateVisitedHistoryHelper = contentClient.getDoUpdateVisitedHistoryHelper(); int callCount = doUpdateVisitedHistoryHelper.getCallCount(); - loadUrlAsync(awContents, url); + mActivityTestRule.loadUrlAsync(awContents, url); doUpdateVisitedHistoryHelper.waitForCallback(callCount); - assertEquals(url, doUpdateVisitedHistoryHelper.getUrl()); - assertEquals(true, doUpdateVisitedHistoryHelper.getIsReload()); + Assert.assertEquals(url, doUpdateVisitedHistoryHelper.getUrl()); + Assert.assertEquals(true, doUpdateVisitedHistoryHelper.getIsReload()); } finally { if (httpServer != null) { httpServer.shutdown(); @@ -2923,19 +2978,9 @@ private TestDependencyFactory mOverridenFactory; - @Override + @After public void tearDown() throws Exception { mOverridenFactory = null; - super.tearDown(); - } - - @Override - public TestDependencyFactory createTestDependencyFactory() { - if (mOverridenFactory == null) { - return new TestDependencyFactory(); - } else { - return mOverridenFactory; - } } private static class EmptyDocumentPeristenceTestDependencyFactory @@ -2957,40 +3002,46 @@ mOverridenFactory = new EmptyDocumentPeristenceTestDependencyFactory(allow); final TestAwContentsClient client = new TestAwContentsClient(); - final AwTestContainerView mContainerView = createAwTestContainerViewOnMainSync(client); + final AwTestContainerView mContainerView = + mActivityTestRule.createAwTestContainerViewOnMainSync(client); final AwContents awContents = mContainerView.getAwContents(); - enableJavaScriptOnUiThread(awContents); - JSUtils.executeJavaScriptAndWaitForResult(getInstrumentation(), awContents, - client.getOnEvaluateJavaScriptResultHelper(), + mActivityTestRule.enableJavaScriptOnUiThread(awContents); + JSUtils.executeJavaScriptAndWaitForResult(InstrumentationRegistry.getInstrumentation(), + awContents, client.getOnEvaluateJavaScriptResultHelper(), "window.emptyDocumentPersistenceTest = true;"); - loadUrlSync(awContents, client.getOnPageFinishedHelper(), + mActivityTestRule.loadUrlSync(awContents, client.getOnPageFinishedHelper(), ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL); - String result = JSUtils.executeJavaScriptAndWaitForResult(getInstrumentation(), awContents, + String result = JSUtils.executeJavaScriptAndWaitForResult( + InstrumentationRegistry.getInstrumentation(), awContents, client.getOnEvaluateJavaScriptResultHelper(), "window.emptyDocumentPersistenceTest ? 'set' : 'not set';"); - assertEquals(allow ? "\"set\"" : "\"not set\"", result); + Assert.assertEquals(allow ? "\"set\"" : "\"not set\"", result); } + @Test @SmallTest @Feature({"AndroidWebView", "Preferences"}) public void testAllowEmptyDocumentPersistence() throws Throwable { doAllowEmptyDocumentPersistenceTest(true); } + @Test @SmallTest @Feature({"AndroidWebView", "Preferences"}) public void testDisallowEmptyDocumentPersistence() throws Throwable { doAllowEmptyDocumentPersistenceTest(false); } + @Test @SmallTest @Feature({"AndroidWebView", "Preferences"}) public void testCSSHexAlphaColorEnabled() throws Throwable { final TestAwContentsClient client = new TestAwContentsClient(); - final AwTestContainerView view = createAwTestContainerViewOnMainSync(client); + final AwTestContainerView view = + mActivityTestRule.createAwTestContainerViewOnMainSync(client); final AwContents awContents = view.getAwContents(); CallbackHelper onPageFinishedHelper = client.getOnPageFinishedHelper(); - enableJavaScriptOnUiThread(awContents); + mActivityTestRule.enableJavaScriptOnUiThread(awContents); final String expectedTitle = "false"; // https://crbug.com/618472 final String page = "<!doctype html>" + "<script>" @@ -2998,9 +3049,9 @@ + " document.title = CSS.supports('color', '#AABBCCDD');" + "};" + "</script>"; - loadDataSync(awContents, onPageFinishedHelper, page, "text/html", false); - String actualTitle = getTitleOnUiThread(awContents); - assertEquals(expectedTitle, actualTitle); + mActivityTestRule.loadDataSync(awContents, onPageFinishedHelper, page, "text/html", false); + String actualTitle = mActivityTestRule.getTitleOnUiThread(awContents); + Assert.assertEquals(expectedTitle, actualTitle); } private static class SelectionRangeTestDependencyFactory extends TestDependencyFactory { @@ -3022,9 +3073,10 @@ mOverridenFactory = new SelectionRangeTestDependencyFactory(doNotUpdate); final TestAwContentsClient client = new TestAwContentsClient(); - final AwTestContainerView mContainerView = createAwTestContainerViewOnMainSync(client); + final AwTestContainerView mContainerView = + mActivityTestRule.createAwTestContainerViewOnMainSync(client); final AwContents awContents = mContainerView.getAwContents(); - enableJavaScriptOnUiThread(awContents); + mActivityTestRule.enableJavaScriptOnUiThread(awContents); final String testPageHtml = "<html><head></head><body><div id='a' contenteditable></div><script>" + "var cnt = 0;" @@ -3034,17 +3086,17 @@ + " cnt++;" + "}" + "</script></body></html>"; - loadDataSync( + mActivityTestRule.loadDataSync( awContents, client.getOnPageFinishedHelper(), testPageHtml, "text/html", false); // Focus on an empty DIV. - JSUtils.executeJavaScriptAndWaitForResult(getInstrumentation(), awContents, - client.getOnEvaluateJavaScriptResultHelper(), "window.a.focus();"); - assertEquals(1, getSelectionChangeCountForSelectionUpdateTest(awContents, client)); + JSUtils.executeJavaScriptAndWaitForResult(InstrumentationRegistry.getInstrumentation(), + awContents, client.getOnEvaluateJavaScriptResultHelper(), "window.a.focus();"); + Assert.assertEquals(1, getSelectionChangeCountForSelectionUpdateTest(awContents, client)); // Create and delete a zero-width space. See crbug.com/698752 for details. - JSUtils.executeJavaScriptAndWaitForResult(getInstrumentation(), awContents, - client.getOnEvaluateJavaScriptResultHelper(), + JSUtils.executeJavaScriptAndWaitForResult(InstrumentationRegistry.getInstrumentation(), + awContents, client.getOnEvaluateJavaScriptResultHelper(), "(function() {" + "var sel = window.getSelection();" + "var range = sel.getRangeAt(0);" @@ -3056,15 +3108,15 @@ + "range.deleteContents();" + "}) ();"); int expectedResult = doNotUpdate ? 0 : 1; - assertEquals( + Assert.assertEquals( expectedResult, getSelectionChangeCountForSelectionUpdateTest(awContents, client)); } private void pollTitleAs(final String title, final AwContents awContents) throws Exception { - pollInstrumentationThread(new Callable<Boolean>() { + AwActivityTestRule.pollInstrumentationThread(new Callable<Boolean>() { @Override public Boolean call() throws Exception { - return title.equals(getTitleOnUiThread(awContents)); + return title.equals(mActivityTestRule.getTitleOnUiThread(awContents)); } }); } @@ -3075,25 +3127,28 @@ String expectedTitle = Integer.toString(mTitleIdx); // Since selectionchange event is posted on a message loop, we run another message loop // before we get the result. On Chromium both run on the same message loop. - JSUtils.executeJavaScriptAndWaitForResult(getInstrumentation(), awContents, - client.getOnEvaluateJavaScriptResultHelper(), + JSUtils.executeJavaScriptAndWaitForResult(InstrumentationRegistry.getInstrumentation(), + awContents, client.getOnEvaluateJavaScriptResultHelper(), "setTimeout(function() { document.title = '" + expectedTitle + "'; });"); pollTitleAs(expectedTitle, awContents); - String result = JSUtils.executeJavaScriptAndWaitForResult(getInstrumentation(), awContents, + String result = JSUtils.executeJavaScriptAndWaitForResult( + InstrumentationRegistry.getInstrumentation(), awContents, client.getOnEvaluateJavaScriptResultHelper(), "window.cnt"); // Clean up - JSUtils.executeJavaScriptAndWaitForResult(getInstrumentation(), awContents, - client.getOnEvaluateJavaScriptResultHelper(), "window.cnt = 0;"); + JSUtils.executeJavaScriptAndWaitForResult(InstrumentationRegistry.getInstrumentation(), + awContents, client.getOnEvaluateJavaScriptResultHelper(), "window.cnt = 0;"); return Integer.parseInt(result); } + @Test @SmallTest @Feature({"AndroidWebView", "Selection"}) public void testDoNotUpdateSelectionOnMutatingSelectionRange() throws Throwable { selectionUpdateOnMutatingSelectionRangeTest(true); } + @Test @SmallTest @Feature({"AndroidWebView", "Selection"}) public void testUpdateSelectionOnMutatingSelectionRange() throws Throwable { @@ -3150,8 +3205,8 @@ * @param helper1 Test helper for the second ContentView * @throws Throwable */ - private void runPerViewSettingsTest(AwSettingsTestHelper helper0, - AwSettingsTestHelper helper1) throws Throwable { + private void runPerViewSettingsTest( + AwSettingsTestHelper<?> helper0, AwSettingsTestHelper<?> helper1) throws Throwable { helper0.ensureSettingHasInitialValue(); helper1.ensureSettingHasInitialValue(); @@ -3195,22 +3250,24 @@ private ViewPair createViews(boolean supportsLegacyQuirks) throws Throwable { TestAwContentsClient client0 = new TestAwContentsClient(); TestAwContentsClient client1 = new TestAwContentsClient(); - return new ViewPair( - createAwTestContainerViewOnMainSync(client0, supportsLegacyQuirks), - client0, - createAwTestContainerViewOnMainSync(client1, supportsLegacyQuirks), - client1); + return new ViewPair(mActivityTestRule.createAwTestContainerViewOnMainSync( + client0, supportsLegacyQuirks), + client0, + mActivityTestRule.createAwTestContainerViewOnMainSync( + client1, supportsLegacyQuirks), + client1); } static void assertFileIsReadable(String filePath) { File file = new File(filePath); try { - assertTrue("Test file \"" + filePath + "\" is not readable." - + "Please make sure that files from android_webview/test/data/device_files/ " - + "has been pushed to the device before testing", + Assert.assertTrue("Test file \"" + filePath + "\" is not readable." + + "Please make sure that files from " + + "android_webview/test/data/device_files/ has been pushed to the " + + "device before testing", file.canRead()); } catch (SecurityException e) { - fail("Got a SecurityException for \"" + filePath + "\": " + e.toString()); + Assert.fail("Got a SecurityException for \"" + filePath + "\": " + e.toString()); } } @@ -3220,13 +3277,13 @@ * @param expectedCount Expected resource requests count */ private void ensureResourceRequestCountInContentProvider(String resource, int expectedCount) { - Context context = getInstrumentation().getTargetContext(); + Context context = InstrumentationRegistry.getInstrumentation().getTargetContext(); int actualCount = TestContentProvider.getResourceRequestCount(context, resource); - assertEquals(expectedCount, actualCount); + Assert.assertEquals(expectedCount, actualCount); } private void resetResourceRequestCountInContentProvider(String resource) { - Context context = getInstrumentation().getTargetContext(); + Context context = InstrumentationRegistry.getInstrumentation().getTargetContext(); TestContentProvider.resetResourceRequestCount(context, resource); } @@ -3239,7 +3296,7 @@ final int x = (webView.getRight() - webView.getLeft()) / 2; final int y = (webView.getBottom() - webView.getTop()) / 2; final AwContents awContents = webView.getAwContents(); - runTestOnUiThread(new Runnable() { + InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() { @Override public void run() { awContents.getContentViewCore().sendDoubleTapForTest(
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/util/VideoTestUtil.java b/android_webview/javatests/src/org/chromium/android_webview/test/util/VideoTestUtil.java index 696edc2c..6098ede1 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/util/VideoTestUtil.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/util/VideoTestUtil.java
@@ -4,9 +4,11 @@ package org.chromium.android_webview.test.util; +import android.app.Instrumentation; + import org.chromium.android_webview.AwContents; import org.chromium.android_webview.AwSettings; -import org.chromium.android_webview.test.AwTestBase; +import org.chromium.android_webview.test.AwActivityTestRule; import org.chromium.android_webview.test.TestAwContentsClient; /** @@ -15,18 +17,21 @@ public class VideoTestUtil { /** * Run video test. - * @param testCase the test case instance we're going to run the test in. + * @param instr the test instrumentation + * @param testRule the test rule instance we're going to run the test in. * @param requiredUserGesture the settings of MediaPlaybackRequiresUserGesture. * @return true if the event happened, * @throws Throwable throw exception if timeout. */ - public static boolean runVideoTest(final AwTestBase testCase, final boolean requiredUserGesture, + public static boolean runVideoTest(final Instrumentation instr, + final AwActivityTestRule testRule, + final boolean requiredUserGesture, long waitTime) throws Throwable { final JavascriptEventObserver observer = new JavascriptEventObserver(); TestAwContentsClient client = new TestAwContentsClient(); final AwContents awContents = - testCase.createAwTestContainerViewOnMainSync(client).getAwContents(); - testCase.getInstrumentation().runOnMainSync(() -> { + testRule.createAwTestContainerViewOnMainSync(client).getAwContents(); + instr.runOnMainSync(() -> { AwSettings awSettings = awContents.getSettings(); awSettings.setJavaScriptEnabled(true); awSettings.setMediaPlaybackRequiresUserGesture(requiredUserGesture); @@ -43,7 +48,7 @@ + "</script></head><body>" + "<video id='video' autoplay control src='" + webServer.getOnePixelOneFrameWebmURL() + "' /> </body></html>"; - testCase.loadDataAsync(awContents, data, "text/html", false); + testRule.loadDataAsync(awContents, data, "text/html", false); return observer.waitForEvent(waitTime); } finally { if (webServer != null && webServer.getTestWebServer() != null) {
diff --git a/android_webview/test/embedded_test_server/BUILD.gn b/android_webview/test/embedded_test_server/BUILD.gn index e0c46b3..7faed41 100644 --- a/android_webview/test/embedded_test_server/BUILD.gn +++ b/android_webview/test/embedded_test_server/BUILD.gn
@@ -32,14 +32,10 @@ source_set("aw_java_test_native_support") { testonly = true sources = [ - "../../../net/test/android/net_test_jni_onload.cc", - "../../../net/test/android/net_test_jni_onload.h", "../../../net/test/embedded_test_server/android/embedded_test_server_android.cc", "../../../net/test/embedded_test_server/android/embedded_test_server_android.h", "aw_embedded_test_server.cc", "aw_test_entry_point.cc", - "aw_test_jni_onload.cc", - "aw_test_jni_onload.h", ] deps = [ "//net:test_support",
diff --git a/android_webview/test/embedded_test_server/aw_embedded_test_server.cc b/android_webview/test/embedded_test_server/aw_embedded_test_server.cc index 21757c6..e7994c2 100644 --- a/android_webview/test/embedded_test_server/aw_embedded_test_server.cc +++ b/android_webview/test/embedded_test_server/aw_embedded_test_server.cc
@@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "android_webview/test/embedded_test_server/aw_embedded_test_server.h" - #include <jni.h> #include "android_webview/test/jni/AwEmbeddedTestServerImpl_jni.h"
diff --git a/android_webview/test/embedded_test_server/aw_embedded_test_server.h b/android_webview/test/embedded_test_server/aw_embedded_test_server.h deleted file mode 100644 index 77fd9445..0000000 --- a/android_webview/test/embedded_test_server/aw_embedded_test_server.h +++ /dev/null
@@ -1,18 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef ANDROID_WEBVIEW_TEST_EMBEDDED_TEST_SERVER_AW_EMBEDDED_TEST_SERVER_H_ -#define ANDROID_WEBVIEW_TEST_EMBEDDED_TEST_SERVER_AW_EMBEDDED_TEST_SERVER_H_ - -#include <jni.h> - -namespace android_webview { -namespace test { - -bool RegisterCustomHandlers(JNIEnv* env); - -} // namespace test -} // namespace android_webview - -#endif // ANDROID_WEBVIEW_TEST_EMBEDDED_TEST_SERVER_AW_EMBEDDED_TEST_SERVER_H_
diff --git a/android_webview/test/embedded_test_server/aw_test_entry_point.cc b/android_webview/test/embedded_test_server/aw_test_entry_point.cc index 824382e..620abbd9 100644 --- a/android_webview/test/embedded_test_server/aw_test_entry_point.cc +++ b/android_webview/test/embedded_test_server/aw_test_entry_point.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 "android_webview/test/embedded_test_server/aw_test_jni_onload.h" +#include "base/android/base_jni_onload.h" #include "base/android/jni_android.h" // This is called by the VM when the shared library is first loaded. JNI_EXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) { base::android::InitVM(vm); - if (!android_webview::test::OnJNIOnLoadInit()) { + if (!base::android::OnJNIOnLoadInit()) return -1; - } return JNI_VERSION_1_4; }
diff --git a/android_webview/test/embedded_test_server/aw_test_jni_onload.cc b/android_webview/test/embedded_test_server/aw_test_jni_onload.cc deleted file mode 100644 index 27dc849..0000000 --- a/android_webview/test/embedded_test_server/aw_test_jni_onload.cc +++ /dev/null
@@ -1,17 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "android_webview/test/embedded_test_server/aw_test_jni_onload.h" - -#include "base/android/base_jni_onload.h" - -namespace android_webview { -namespace test { - -bool OnJNIOnLoadInit() { - return base::android::OnJNIOnLoadInit(); -} - -} // namespace test -} // namespace android_webview
diff --git a/android_webview/test/embedded_test_server/aw_test_jni_onload.h b/android_webview/test/embedded_test_server/aw_test_jni_onload.h deleted file mode 100644 index d20fceb..0000000 --- a/android_webview/test/embedded_test_server/aw_test_jni_onload.h +++ /dev/null
@@ -1,16 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef ANDROID_WEBVIEW_TEST_EMBEDDED_TEST_SERVER_AW_TEST_JNI_ONLOAD_H_ -#define ANDROID_WEBVIEW_TEST_EMBEDDED_TEST_SERVER_AW_TEST_JNI_ONLOAD_H_ - -namespace android_webview { -namespace test { - -bool OnJNIOnLoadInit(); - -} // namespace test -} // namespace android_webview - -#endif // ANDROID_WEBVIEW_TEST_EMBEDDED_TEST_SERVER_AW_TEST_JNI_ONLOAD_H_
diff --git a/android_webview/tools/system_webview_shell/test/data/webexposed/global-interface-listing-expected.txt b/android_webview/tools/system_webview_shell/test/data/webexposed/global-interface-listing-expected.txt index 61af0d1..b7c4564 100644 --- a/android_webview/tools/system_webview_shell/test/data/webexposed/global-interface-listing-expected.txt +++ b/android_webview/tools/system_webview_shell/test/data/webexposed/global-interface-listing-expected.txt
@@ -31,10 +31,6 @@ getter animationName getter elapsedTime method constructor -interface AppBannerPromptResult - getter outcome - getter platform - method constructor interface ApplicationCache : EventTarget attribute CHECKING attribute DOWNLOADING
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index 1a88e52..3743cc8 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -363,8 +363,6 @@ "system/date/system_info_default_view.h", "system/date/tray_system_info.cc", "system/date/tray_system_info.h", - "system/devicetype_utils.cc", - "system/devicetype_utils.h", "system/display_scale/scale_detailed_view.cc", "system/display_scale/scale_detailed_view.h", "system/display_scale/scale_view.cc", @@ -1078,8 +1076,6 @@ "content/display/screen_orientation_controller_chromeos_unittest.cc", "content/keyboard_overlay/keyboard_overlay_delegate_unittest.cc", "content/keyboard_overlay/keyboard_overlay_view_unittest.cc", - "test/ash_test_suite.cc", - "test/ash_test_suite.h", "test/ash_unittests.cc", ] configs += [ @@ -1100,7 +1096,6 @@ "//components/quirks", "//components/signin/core/account_id", "//components/user_manager", - "//components/viz/test:test_support", "//content/public/browser", "//content/test:test_support", "//device/bluetooth", @@ -1125,9 +1120,7 @@ ] data_deps = [ - "//ash/strings:ash_test_strings", "//ash/resources:ash_test_resources_with_content_100_percent", - "//ash/resources:ash_test_resources_200_percent", ] } @@ -1314,6 +1307,7 @@ "//ui/aura:test_support", "//ui/base", "//ui/base:test_support", + "//ui/chromeos/events", "//ui/compositor:test_support", "//ui/display", "//ui/events:test_support", @@ -1381,8 +1375,6 @@ # TODO: fails as ScreenLayoutObserver is not installed in mash, # http://crbug.com/696752. "system/screen_layout_observer_unittest.cc", - "test/ash_test_suite.cc", - "test/ash_test_suite.h", "test/ash_unittests.cc", # TODO(riajiang): port to work with mash. http://crbug.com/698032. @@ -1450,13 +1442,11 @@ "//ash/touch_hud", "//base", "//base/test:test_support", - "//cc:test_support", "//chromeos", "//chromeos:test_support_without_gmock", "//components/quirks", "//components/signin/core/account_id", "//components/user_manager", - "//components/viz/test:test_support", "//device/bluetooth", "//mojo/edk/system", "//net:net", @@ -1500,9 +1490,7 @@ ] data_deps = [ - "//ash/strings:ash_test_strings", "//ash/resources:ash_test_resources_100_percent", - "//ash/resources:ash_test_resources_200_percent", "//testing/buildbot/filters:ash_unittests_filters", ] @@ -1517,17 +1505,13 @@ sources = [ "perftests/ash_background_filter_blur_perftest.cc", "test/ash_perftests.cc", - "test/ash_test_suite.cc", - "test/ash_test_suite.h", ] deps = [ ":test_support_without_content", "//ash/public/cpp:ash_public_cpp", "//base/test:test_support", - "//cc:test_support", "//cc/base", - "//components/viz/test:test_support", "//mojo/edk/embedder:headers", "//testing/gtest", "//testing/perf", @@ -1556,9 +1540,7 @@ ] data_deps = [ - "//ash/strings:ash_test_strings", "//ash/resources:ash_test_resources_with_content_100_percent", - "//ash/resources:ash_test_resources_200_percent", ] } @@ -1659,6 +1641,8 @@ "test/ash_test_environment.h", "test/ash_test_helper.cc", "test/ash_test_helper.h", + "test/ash_test_suite.cc", + "test/ash_test_suite.h", "test/ash_test_views_delegate.cc", "test/ash_test_views_delegate.h", @@ -1710,10 +1694,12 @@ "//base", "//base:i18n", "//base/test:test_support", + "//cc:test_support", "//chromeos", "//components/prefs:test_support", "//components/signin/core/account_id", "//components/user_manager:user_manager", + "//components/viz/test:test_support", "//device/bluetooth", "//services/ui/public/cpp/input_devices", "//services/ui/public/interfaces", @@ -1741,6 +1727,12 @@ "//ui/wm", "//ui/wm/public", ] + + data_deps = [ + "//ash/strings:ash_test_strings", + "//ash/resources:ash_test_resources_100_percent", + "//ash/resources:ash_test_resources_200_percent", + ] } static_library("interactive_ui_test_support") {
diff --git a/ash/DEPS b/ash/DEPS index 6336781..4d63140 100644 --- a/ash/DEPS +++ b/ash/DEPS
@@ -64,6 +64,7 @@ "+ui/events/devices/input_device.h", "+ui/events/devices/input_device_event_observer.h", "+ui/events/devices/stylus_state.h", + "+ui/events/devices/touch_device_transform.h", "+ui/events/devices/touchscreen_device.h", # TODO: This is temporary, ash should not use these. http://crbug.com/747415.
diff --git a/ash/accelerators/accelerator_controller.h b/ash/accelerators/accelerator_controller.h index 9cc79cc..cf1a5f04 100644 --- a/ash/accelerators/accelerator_controller.h +++ b/ash/accelerators/accelerator_controller.h
@@ -37,9 +37,8 @@ // AcceleratorController provides functions for registering or unregistering // global keyboard accelerators, which are handled earlier than any windows. It // also implements several handlers as an accelerator target. -class ASH_EXPORT AcceleratorController - : public ui::AcceleratorTarget, - NON_EXPORTED_BASE(public mojom::AcceleratorController) { +class ASH_EXPORT AcceleratorController : public ui::AcceleratorTarget, + public mojom::AcceleratorController { public: AcceleratorController(AcceleratorControllerDelegate* delegate, ui::AcceleratorManagerDelegate* manager_delegate);
diff --git a/ash/accelerators/accelerator_delegate.h b/ash/accelerators/accelerator_delegate.h index 18775a4..61545045 100644 --- a/ash/accelerators/accelerator_delegate.h +++ b/ash/accelerators/accelerator_delegate.h
@@ -16,8 +16,7 @@ class AcceleratorRouter; -class ASH_EXPORT AcceleratorDelegate - : NON_EXPORTED_BASE(public ::wm::AcceleratorDelegate) { +class ASH_EXPORT AcceleratorDelegate : public ::wm::AcceleratorDelegate { public: AcceleratorDelegate(); ~AcceleratorDelegate() override;
diff --git a/ash/ash_strings.grd b/ash/ash_strings.grd index c7da7a2..f6b3ef6c 100644 --- a/ash/ash_strings.grd +++ b/ash/ash_strings.grd
@@ -470,23 +470,6 @@ Toggle window overview </message> - <!-- Device types --> - <message name="IDS_ASH_CHROMEBASE" desc="The device name for a Chromebase (versus say Chromebox)"> - Chromebase - </message> - <message name="IDS_ASH_CHROMEBIT" desc="The device name for a Chromebit (versus say Chromebox)"> - Chromebit - </message> - <message name="IDS_ASH_CHROMEBOOK" desc="The device name for a Chromebook (versus say Chromebox)"> - Chromebook - </message> - <message name="IDS_ASH_CHROMEBOX" desc="The device name for a Chromebox (versus say Chromebook)"> - Chromebox - </message> - <message name="IDS_ASH_CHROMEDEVICE" desc="The device name for a generic Chrome device"> - Chrome device - </message> - <!-- Status tray charging strings. --> <message name="IDS_ASH_STATUS_TRAY_LOW_POWER_CHARGER_TITLE" desc="The title of a notification indicating that a low-current USB charger has been connected."> Low-power charger connected
diff --git a/ash/display/display_error_observer_chromeos.cc b/ash/display/display_error_observer_chromeos.cc index cc55d1e..52f9de2 100644 --- a/ash/display/display_error_observer_chromeos.cc +++ b/ash/display/display_error_observer_chromeos.cc
@@ -6,9 +6,9 @@ #include "ash/display/display_util.h" #include "ash/strings/grit/ash_strings.h" -#include "ash/system/devicetype_utils.h" #include "base/strings/string_number_conversions.h" #include "ui/base/l10n/l10n_util.h" +#include "ui/chromeos/devicetype_utils.h" #include "ui/display/types/display_snapshot.h" namespace ash { @@ -31,7 +31,7 @@ base::string16 message = (new_state == display::MULTIPLE_DISPLAY_STATE_DUAL_MIRROR) ? l10n_util::GetStringUTF16(IDS_ASH_DISPLAY_FAILURE_ON_MIRRORING) - : ash::SubstituteChromeOSDeviceType( + : ui::SubstituteChromeOSDeviceType( IDS_ASH_DISPLAY_FAILURE_ON_NON_MIRRORING); ShowDisplayErrorNotification(message, true); }
diff --git a/ash/display/display_error_observer_chromeos_unittest.cc b/ash/display/display_error_observer_chromeos_unittest.cc index d47ddaa..dad907d 100644 --- a/ash/display/display_error_observer_chromeos_unittest.cc +++ b/ash/display/display_error_observer_chromeos_unittest.cc
@@ -7,10 +7,10 @@ #include "ash/display/display_util.h" #include "ash/shell.h" #include "ash/strings/grit/ash_strings.h" -#include "ash/system/devicetype_utils.h" #include "ash/test/ash_test_base.h" #include "ui/aura/window.h" #include "ui/base/l10n/l10n_util.h" +#include "ui/chromeos/devicetype_utils.h" #include "ui/views/controls/label.h" #include "ui/views/view.h" #include "ui/views/widget/widget.h" @@ -77,7 +77,7 @@ observer()->OnDisplayModeChangeFailed( display::DisplayConfigurator::DisplayStateList(), display::MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED); - EXPECT_EQ(ash::SubstituteChromeOSDeviceType( + EXPECT_EQ(ui::SubstituteChromeOSDeviceType( IDS_ASH_DISPLAY_FAILURE_ON_NON_MIRRORING), GetMessageContents()); }
diff --git a/ash/fast_ink/fast_ink_view.cc b/ash/fast_ink/fast_ink_view.cc index c732dcbf5..a881911 100644 --- a/ash/fast_ink/fast_ink_view.cc +++ b/ash/fast_ink/fast_ink_view.cc
@@ -11,6 +11,7 @@ #include "ash/public/cpp/shell_window_ids.h" #include "ash/shell.h" #include "base/threading/thread_task_runner_handle.h" +#include "cc/base/math_util.h" #include "cc/output/compositor_frame.h" #include "cc/output/layer_tree_frame_sink.h" #include "cc/output/layer_tree_frame_sink_client.h" @@ -20,6 +21,7 @@ #include "gpu/command_buffer/client/gpu_memory_buffer_manager.h" #include "ui/aura/env.h" #include "ui/aura/window.h" +#include "ui/aura/window_tree_host.h" #include "ui/base/layout.h" #include "ui/gfx/canvas.h" #include "ui/gfx/gpu_memory_buffer.h" @@ -110,7 +112,14 @@ widget_->SetBounds(root_window->GetBoundsInScreen()); set_owned_by_client(); - scale_factor_ = ui::GetScaleFactorForNativeView(widget_->GetNativeView()); + // Take the root transform and apply this during buffer update instead of + // leaving this up to the compositor. The benefit is that HW requirements + // for being able to take advantage of overlays and direct scanout are + // reduced significantly. Frames are submitted to the compositor with the + // inverse transform to cancel out the transformation that would otherwise + // be done by the compositor. + screen_to_buffer_transform_ = + widget_->GetNativeWindow()->GetHost()->GetRootTransform(); frame_sink_holder_ = base::MakeUnique<FastInkLayerTreeFrameSinkHolder>( this, widget_->GetNativeView()->CreateLayerTreeFrameSink()); @@ -181,7 +190,11 @@ ->context_factory() ->GetGpuMemoryBufferManager() ->CreateGpuMemoryBuffer( - gfx::ScaleToCeiledSize(screen_bounds.size(), scale_factor_), + gfx::ToEnclosedRect(cc::MathUtil::MapClippedRect( + screen_to_buffer_transform_, + gfx::RectF(screen_bounds.width(), + screen_bounds.height()))) + .size(), SK_B32_SHIFT ? gfx::BufferFormat::RGBA_8888 : gfx::BufferFormat::BGRA_8888, gfx::BufferUsage::SCANOUT_CPU_READ_WRITE, @@ -195,9 +208,13 @@ update_rect = gfx::Rect(screen_bounds.size()); } - // Constrain update rectangle to buffer size and early out if empty. - update_rect.Intersect(gfx::Rect(screen_bounds.size())); - if (update_rect.IsEmpty()) + // Convert update rectangle to pixel coordinates. + gfx::Rect pixel_rect = cc::MathUtil::MapEnclosingClippedRect( + screen_to_buffer_transform_, update_rect); + + // Constrain pixel rectangle to buffer size and early out if empty. + pixel_rect.Intersect(gfx::Rect(gpu_memory_buffer_->GetSize())); + if (pixel_rect.IsEmpty()) return; // Map buffer for writing. @@ -207,21 +224,17 @@ } // Create a temporary canvas for update rectangle. - gfx::Canvas canvas(update_rect.size(), scale_factor_, false); + gfx::Canvas canvas(pixel_rect.size(), 1.0f, false); + canvas.Translate(-pixel_rect.OffsetFromOrigin()); + canvas.Transform(screen_to_buffer_transform_); { - TRACE_EVENT1("ui", "FastInkView::UpdateBuffer::Paint", "update_rect", - update_rect.ToString()); + TRACE_EVENT1("ui", "FastInkView::UpdateBuffer::Paint", "pixel_rect", + pixel_rect.ToString()); - gfx::Vector2d offset = - widget_->GetNativeView()->GetBoundsInRootWindow().OffsetFromOrigin() + - update_rect.OffsetFromOrigin(); - OnRedraw(canvas, offset); + OnRedraw(canvas); } - // Convert update rectangle to pixel coordinates. - gfx::Rect pixel_rect = gfx::ScaleToEnclosingRect(update_rect, scale_factor_); - // Copy result to GPU memory buffer. This is effectively a memcpy and unlike // drawing to the buffer directly this ensures that the buffer is never in a // state that would result in flicker. @@ -330,23 +343,37 @@ gpu::MailboxHolder(resource->mailbox, sync_token, GL_TEXTURE_2D); transferable_resource.is_overlay_candidate = true; - gfx::Rect quad_rect(widget_->GetNativeView()->GetBoundsInScreen().size()); + gfx::Transform buffer_to_screen_transform; + bool rv = screen_to_buffer_transform_.GetInverse(&buffer_to_screen_transform); + DCHECK(rv); + + gfx::Rect output_rect(widget_->GetNativeView()->GetBoundsInScreen().size()); + // |quad_rect| is under normal cricumstances equal to |buffer_size| but to + // be more resilient to rounding errors in the compositor that might cause + // off-by-one problems when the transform is non-trivial we compute this rect + // by mapping the output rect back into buffer space and intersecting by + // buffer bounds. This avoids some corner cases where one row or column + // would end up outside the screen and we would fail to take advantage of HW + // overlays. + gfx::Rect quad_rect = gfx::ToEnclosedRect(cc::MathUtil::MapClippedRect( + screen_to_buffer_transform_, gfx::RectF(output_rect))); + quad_rect.Intersect(gfx::Rect(buffer_size)); const int kRenderPassId = 1; std::unique_ptr<cc::RenderPass> render_pass = cc::RenderPass::Create(); - render_pass->SetNew(kRenderPassId, quad_rect, surface_damage_rect_, - gfx::Transform()); + render_pass->SetNew(kRenderPassId, output_rect, surface_damage_rect_, + buffer_to_screen_transform); surface_damage_rect_ = gfx::Rect(); cc::SharedQuadState* quad_state = render_pass->CreateAndAppendSharedQuadState(); - quad_state->SetAll( - /*quad_to_target_transform=*/gfx::Transform(), - /*quad_layer_rect=*/quad_rect, - /*visible_quad_layer_rect=*/quad_rect, - /*clip_rect=*/gfx::Rect(), - /*is_clipped=*/false, /*opacity=*/1.f, - /*blend_mode=*/SkBlendMode::kSrcOver, /*sorting_context_id=*/0); + quad_state->SetAll(buffer_to_screen_transform, + /*quad_layer_rect=*/output_rect, + /*visible_quad_layer_rect=*/output_rect, + /*clip_rect=*/gfx::Rect(), + /*is_clipped=*/false, /*opacity=*/1.f, + /*blend_mode=*/SkBlendMode::kSrcOver, + /*sorting_context_id=*/0); cc::CompositorFrame frame; // TODO(eseckler): FastInkView should use BeginFrames and set the ack
diff --git a/ash/fast_ink/fast_ink_view.h b/ash/fast_ink/fast_ink_view.h index cfa8c32..f295165 100644 --- a/ash/fast_ink/fast_ink_view.h +++ b/ash/fast_ink/fast_ink_view.h
@@ -50,7 +50,7 @@ void RequestRedraw(); // Draw the contents of the view in the provided canvas. - virtual void OnRedraw(gfx::Canvas& canvas, const gfx::Vector2d& offset) = 0; + virtual void OnRedraw(gfx::Canvas& canvas) = 0; private: friend class FastInkLayerTreeFrameSinkHolder; @@ -66,7 +66,7 @@ void OnDidDrawSurface(); std::unique_ptr<views::Widget> widget_; - float scale_factor_ = 1.0f; + gfx::Transform screen_to_buffer_transform_; std::unique_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer_; gfx::Rect buffer_damage_rect_; bool pending_update_buffer_ = false;
diff --git a/ash/highlighter/highlighter_view.cc b/ash/highlighter/highlighter_view.cc index 587c5c7..784e31e 100644 --- a/ash/highlighter/highlighter_view.cc +++ b/ash/highlighter/highlighter_view.cc
@@ -155,8 +155,7 @@ animation_timer_->Start(FROM_HERE, duration, done); } -void HighlighterView::OnRedraw(gfx::Canvas& canvas, - const gfx::Vector2d& offset) { +void HighlighterView::OnRedraw(gfx::Canvas& canvas) { const int num_points = points_.GetNumberOfPoints() + predicted_points_.GetNumberOfPoints(); if (num_points < 2) @@ -184,11 +183,10 @@ for (int i = 0; i < num_points; ++i) { gfx::PointF current_point; if (i < points_.GetNumberOfPoints()) { - current_point = points_.points()[i].location - offset; + current_point = points_.points()[i].location; } else { current_point = - predicted_points_.points()[i - points_.GetNumberOfPoints()].location - - offset; + predicted_points_.points()[i - points_.GetNumberOfPoints()].location; } if (i != 0) {
diff --git a/ash/highlighter/highlighter_view.h b/ash/highlighter/highlighter_view.h index 409c819..8b5c9fae 100644 --- a/ash/highlighter/highlighter_view.h +++ b/ash/highlighter/highlighter_view.h
@@ -50,7 +50,7 @@ private: friend class HighlighterControllerTestApi; - void OnRedraw(gfx::Canvas& canvas, const gfx::Vector2d& offset) override; + void OnRedraw(gfx::Canvas& canvas) override; void FadeOut(const gfx::PointF& pivot, AnimationMode animation_mode,
diff --git a/ash/ime/ime_controller.h b/ash/ime/ime_controller.h index 80c9412..595815a 100644 --- a/ash/ime/ime_controller.h +++ b/ash/ime/ime_controller.h
@@ -21,8 +21,7 @@ // Connects ash IME users (e.g. the system tray) to the IME implementation, // which might live in Chrome browser or in a separate mojo service. -class ASH_EXPORT ImeController - : public NON_EXPORTED_BASE(mojom::ImeController) { +class ASH_EXPORT ImeController : public mojom::ImeController { public: ImeController(); ~ImeController() override;
diff --git a/ash/laser/laser_pointer_view.cc b/ash/laser/laser_pointer_view.cc index a1266af6..6323a51 100644 --- a/ash/laser/laser_pointer_view.cc +++ b/ash/laser/laser_pointer_view.cc
@@ -247,8 +247,7 @@ return bounding_box; } -void LaserPointerView::OnRedraw(gfx::Canvas& canvas, - const gfx::Vector2d& offset) { +void LaserPointerView::OnRedraw(gfx::Canvas& canvas) { cc::PaintFlags flags; flags.setStyle(cc::PaintFlags::kFill_Style); flags.setAntiAlias(true); @@ -266,11 +265,11 @@ gfx::PointF current_point; float fadeout_factor; if (i < laser_points_.GetNumberOfPoints()) { - current_point = laser_points_.points()[i].location - offset; + current_point = laser_points_.points()[i].location; fadeout_factor = laser_points_.GetFadeoutFactor(i); } else { int index = i - laser_points_.GetNumberOfPoints(); - current_point = predicted_laser_points_.points()[index].location - offset; + current_point = predicted_laser_points_.points()[index].location; fadeout_factor = predicted_laser_points_.GetFadeoutFactor(index); }
diff --git a/ash/laser/laser_pointer_view.h b/ash/laser/laser_pointer_view.h index a45e5e6..3ce0065 100644 --- a/ash/laser/laser_pointer_view.h +++ b/ash/laser/laser_pointer_view.h
@@ -38,7 +38,7 @@ void UpdateTime(); // FastInkView: - void OnRedraw(gfx::Canvas& canvas, const gfx::Vector2d& offset) override; + void OnRedraw(gfx::Canvas& canvas) override; FastInkPoints laser_points_; FastInkPoints predicted_laser_points_;
diff --git a/ash/login/lock_screen_controller.h b/ash/login/lock_screen_controller.h index b832563..b5714443 100644 --- a/ash/login/lock_screen_controller.h +++ b/ash/login/lock_screen_controller.h
@@ -17,8 +17,7 @@ // LockScreenClient, which we will dispatch to if one has been provided to us. // This could send requests to LockScreenClient and also handle requests from // LockScreenClient through mojo. -class ASH_EXPORT LockScreenController - : NON_EXPORTED_BASE(public mojom::LockScreen) { +class ASH_EXPORT LockScreenController : public mojom::LockScreen { public: using OnShownCallback = base::OnceCallback<void(bool did_show)>;
diff --git a/ash/mus/BUILD.gn b/ash/mus/BUILD.gn index f990801f6..85dfb68 100644 --- a/ash/mus/BUILD.gn +++ b/ash/mus/BUILD.gn
@@ -82,7 +82,7 @@ "//ui/app_list/presenter:mojom", "//ui/chromeos", "//ui/display/manager", - "//ui/display/manager/chromeos/mojo:interfaces", + "//ui/events/devices/mojo", "//ui/keyboard", "//ui/keyboard:mojom", "//ui/message_center",
diff --git a/ash/mus/display_synchronizer_unittest.cc b/ash/mus/display_synchronizer_unittest.cc index 10f1a3e..152d1d9 100644 --- a/ash/mus/display_synchronizer_unittest.cc +++ b/ash/mus/display_synchronizer_unittest.cc
@@ -59,5 +59,28 @@ test_window_manager_client->last_internal_display_id()); } +TEST_F(DisplaySynchronizerTest, + FrameDecorationsInstalledBeforeDisplayConfiguration) { + aura::TestWindowManagerClient* test_window_manager_client = + ash_test_helper() + ->window_tree_client_setup() + ->test_window_manager_client(); + ASSERT_NE( + 0u, test_window_manager_client->GetChangeCountForType( + aura::WindowManagerClientChangeType::SET_DISPLAY_CONFIGURATION)); + ASSERT_NE(0u, + test_window_manager_client->GetChangeCountForType( + aura::WindowManagerClientChangeType::SET_FRAME_DECORATIONS)); + const size_t frame_decoration_change_index = + test_window_manager_client->IndexOfFirstChangeOfType( + aura::WindowManagerClientChangeType::SET_FRAME_DECORATIONS); + const size_t display_config_change_index = + test_window_manager_client->IndexOfFirstChangeOfType( + aura::WindowManagerClientChangeType::SET_DISPLAY_CONFIGURATION); + // Frame decorations must be installed before the display configuration is + // set, otherwise clients are notified of bogus window manager frame values. + EXPECT_LT(frame_decoration_change_index, display_config_change_index); +} + } // namespace mus } // namespace ash
diff --git a/ash/mus/manifest.json b/ash/mus/manifest.json index 7ec57572..6b38cbe9 100644 --- a/ash/mus/manifest.json +++ b/ash/mus/manifest.json
@@ -33,7 +33,7 @@ }, "requires": { "*": [ "accessibility", "app" ], - "preferences_forwarder": [ "pref_client" ], + "ash_pref_connector": [ "pref_connector" ], "local_state": [ "pref_client" ], "ui": [ "display_test", "window_manager" ], "touch_hud": [ "mash:launchable" ]
diff --git a/ash/mus/shell_delegate_mus.cc b/ash/mus/shell_delegate_mus.cc index f5b3253..7f95c23f 100644 --- a/ash/mus/shell_delegate_mus.cc +++ b/ash/mus/shell_delegate_mus.cc
@@ -124,14 +124,6 @@ return gfx::Image(); } -PrefService* ShellDelegateMus::GetActiveUserPrefService() const { - // This code should never be called in the case of Config::MASH. Rather, the - // PrefService instance is stored by Shell when it manages to connect to the - // pref service in Chrome. - NOTREACHED(); - return nullptr; -} - bool ShellDelegateMus::IsTouchscreenEnabledInPrefs(bool use_local_state) const { NOTIMPLEMENTED(); return true;
diff --git a/ash/mus/shell_delegate_mus.h b/ash/mus/shell_delegate_mus.h index ecd4156..8dd05e9 100644 --- a/ash/mus/shell_delegate_mus.h +++ b/ash/mus/shell_delegate_mus.h
@@ -44,7 +44,6 @@ GPUSupport* CreateGPUSupport() override; base::string16 GetProductName() const override; gfx::Image GetDeprecatedAcceleratorImage() const override; - PrefService* GetActiveUserPrefService() const override; bool IsTouchscreenEnabledInPrefs(bool use_local_state) const override; void SetTouchscreenEnabledInPrefs(bool enabled, bool use_local_state) override;
diff --git a/ash/mus/touch_transform_setter_mus.cc b/ash/mus/touch_transform_setter_mus.cc index f84ade9..952dd1d5 100644 --- a/ash/mus/touch_transform_setter_mus.cc +++ b/ash/mus/touch_transform_setter_mus.cc
@@ -6,8 +6,7 @@ #include "services/service_manager/public/cpp/connector.h" #include "services/ui/public/interfaces/constants.mojom.h" -#include "ui/display/manager/chromeos/mojo/touch_device_transform_struct_traits.h" -#include "ui/display/manager/chromeos/touch_device_transform.h" +#include "ui/events/devices/touch_device_transform.h" namespace ash { @@ -22,14 +21,11 @@ TouchTransformSetterMus::~TouchTransformSetterMus() {} void TouchTransformSetterMus::ConfigureTouchDevices( - const std::map<int32_t, double>& scales, - const std::vector<display::TouchDeviceTransform>& transforms) { + const std::vector<ui::TouchDeviceTransform>& transforms) { if (!touch_device_server_) return; // May be null in tests. - std::unordered_map<int32_t, double> scales_transport(scales.begin(), - scales.end()); - touch_device_server_->ConfigureTouchDevices(scales_transport, transforms); + touch_device_server_->ConfigureTouchDevices(transforms); } } // namespace ash
diff --git a/ash/mus/touch_transform_setter_mus.h b/ash/mus/touch_transform_setter_mus.h index 9fa73d8..3b098dd 100644 --- a/ash/mus/touch_transform_setter_mus.h +++ b/ash/mus/touch_transform_setter_mus.h
@@ -24,8 +24,7 @@ // TouchTransformSetter: void ConfigureTouchDevices( - const std::map<int32_t, double>& scales, - const std::vector<display::TouchDeviceTransform>& transforms) override; + const std::vector<ui::TouchDeviceTransform>& transforms) override; private: ui::mojom::TouchDeviceServerPtr touch_device_server_;
diff --git a/ash/mus/window_manager.cc b/ash/mus/window_manager.cc index e4826728..270ba86 100644 --- a/ash/mus/window_manager.cc +++ b/ash/mus/window_manager.cc
@@ -298,10 +298,13 @@ } void WindowManager::OnWmConnected() { + // InstallFrameDecorationValues() must be called before the shell is created, + // otherwise Mus attempts to notify clients with no frame decorations, which + // triggers validation errors. + InstallFrameDecorationValues(); CreateShell(); if (show_primary_host_on_connect_) Shell::GetPrimaryRootWindow()->GetHost()->Show(); - InstallFrameDecorationValues(); } void WindowManager::OnWmSetBounds(aura::Window* window,
diff --git a/ash/public/cpp/shelf_prefs.cc b/ash/public/cpp/shelf_prefs.cc index 9679923..7cdd3dc 100644 --- a/ash/public/cpp/shelf_prefs.cc +++ b/ash/public/cpp/shelf_prefs.cc
@@ -171,7 +171,11 @@ bool CanUserModifyShelfAutoHideBehavior(PrefService* prefs) { const std::string& pref = prefs::kShelfAutoHideBehaviorLocal; - return prefs->FindPreference(pref)->IsUserModifiable(); + auto* preference = prefs->FindPreference(pref); + if (!preference) + return true; + + return preference->IsUserModifiable(); } ShelfAutoHideBehavior GetShelfAutoHideBehaviorPref(PrefService* prefs, @@ -201,6 +205,14 @@ } } +bool AreShelfPrefsAvailable(PrefService* prefs) { + return prefs->FindPreference(prefs::kShelfAlignmentLocal) && + prefs->FindPreference(prefs::kShelfAlignment) && + prefs->FindPreference(prefs::kShelfAutoHideBehaviorLocal) && + prefs->FindPreference(prefs::kShelfAutoHideBehavior) && + prefs->FindPreference(prefs::kShelfPreferences); +} + ShelfAlignment GetShelfAlignmentPref(PrefService* prefs, int64_t display_id) { DCHECK_NE(display_id, display::kInvalidDisplayId);
diff --git a/ash/public/cpp/shelf_prefs.h b/ash/public/cpp/shelf_prefs.h index a5f7d56..760519fb 100644 --- a/ash/public/cpp/shelf_prefs.h +++ b/ash/public/cpp/shelf_prefs.h
@@ -34,6 +34,10 @@ int64_t display_id, ShelfAutoHideBehavior behavior); +// Returns whether Ash's shelf preferences have been registered with Chrome yet. +// Prefs owned by Ash are registered asynchronously after |prefs| init. +ASH_PUBLIC_EXPORT bool AreShelfPrefsAvailable(PrefService* prefs); + // Get the shelf alignment preference for a particular display. ASH_PUBLIC_EXPORT ShelfAlignment GetShelfAlignmentPref(PrefService* prefs, int64_t display_id);
diff --git a/ash/public/interfaces/BUILD.gn b/ash/public/interfaces/BUILD.gn index 9c7c601..7c4af94 100644 --- a/ash/public/interfaces/BUILD.gn +++ b/ash/public/interfaces/BUILD.gn
@@ -25,6 +25,7 @@ "media.mojom", "new_window.mojom", "night_light_controller.mojom", + "pref_connector.mojom", "session_controller.mojom", "shelf.mojom", "shutdown.mojom", @@ -44,6 +45,7 @@ "//components/proximity_auth/public/interfaces", "//components/signin/public/interfaces", "//mojo/common:common_custom_types", + "//services/preferences/public/interfaces", "//skia/public/interfaces", "//ui/events/mojo:interfaces", "//ui/gfx/image/mojo:interfaces",
diff --git a/ash/public/interfaces/pref_connector.mojom b/ash/public/interfaces/pref_connector.mojom new file mode 100644 index 0000000..a451224 --- /dev/null +++ b/ash/public/interfaces/pref_connector.mojom
@@ -0,0 +1,19 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +module ash.mojom; + +import "components/signin/public/interfaces/account_id.mojom"; +import "services/preferences/public/interfaces/preferences.mojom"; + +const string kPrefConnectorServiceName = "ash_pref_connector"; + +// A connector of PrefStoreConnectors. Provides ash with access to per-profile +// prefs. +interface PrefConnector { + // Provides, via |connector|, a PrefStoreConnector for |account_id|. If + // |account_id| is invalid or unknown, |connector| will be closed. + GetPrefStoreConnectorForUser(signin.mojom.AccountId account_id, + prefs.mojom.PrefStoreConnector& connector); +};
diff --git a/ash/root_window_controller.cc b/ash/root_window_controller.cc index 3be01f98..af083b9c 100644 --- a/ash/root_window_controller.cc +++ b/ash/root_window_controller.cc
@@ -778,7 +778,8 @@ aura::Window* lock_container = GetContainer(kShellWindowId_LockScreenContainer); DCHECK(lock_container); - lock_container->SetLayoutManager(new LockLayoutManager(lock_container)); + lock_container->SetLayoutManager( + new LockLayoutManager(lock_container, shelf_.get())); aura::Window* always_on_top_container = GetContainer(kShellWindowId_AlwaysOnTopContainer);
diff --git a/ash/session/session_controller.cc b/ash/session/session_controller.cc index 9683d32b..747a8d5b 100644 --- a/ash/session/session_controller.cc +++ b/ash/session/session_controller.cc
@@ -7,6 +7,7 @@ #include <algorithm> #include <utility> +#include "ash/public/interfaces/pref_connector.mojom.h" #include "ash/public/interfaces/user_info.mojom.h" #include "ash/session/session_observer.h" #include "ash/shell.h" @@ -19,8 +20,12 @@ #include "base/bind_helpers.h" #include "base/command_line.h" #include "chromeos/chromeos_switches.h" +#include "components/prefs/pref_registry_simple.h" +#include "components/prefs/pref_service.h" #include "components/signin/core/account_id/account_id.h" #include "components/user_manager/user_type.h" +#include "services/preferences/public/cpp/pref_service_factory.h" +#include "services/preferences/public/interfaces/preferences.mojom.h" #include "services/service_manager/public/cpp/connector.h" using session_manager::SessionState; @@ -48,8 +53,10 @@ } // namespace -SessionController::SessionController() - : state_(GetDefaultSessionState()), weak_ptr_factory_(this) {} +SessionController::SessionController(service_manager::Connector* connector) + : state_(GetDefaultSessionState()), + connector_(connector), + weak_ptr_factory_(this) {} SessionController::~SessionController() { // Abort pending start lock request. @@ -189,6 +196,19 @@ client_->ShowMultiProfileLogin(); } +PrefService* SessionController::GetUserPrefServiceForUser( + const AccountId& account_id) { + auto it = per_user_prefs_.find(account_id); + if (it != per_user_prefs_.end()) + return it->second.get(); + + return nullptr; +} + +PrefService* SessionController::GetLastActiveUserPrefService() { + return last_active_user_prefs_; +} + void SessionController::AddObserver(SessionObserver* observer) { observers_.AddObserver(observer); } @@ -252,10 +272,21 @@ if (user_sessions_[0]->session_id != active_session_id_) { active_session_id_ = user_sessions_[0]->session_id; + // When switching to a user for whose PrefService is not ready, + // |last_active_user_prefs_| continues to point to the PrefService of the + // most-recently active user with a loaded PrefService. + auto it = per_user_prefs_.find(user_sessions_[0]->user_info->account_id); + if (it != per_user_prefs_.end()) + last_active_user_prefs_ = it->second.get(); + for (auto& observer : observers_) { observer.OnActiveUserSessionChanged( user_sessions_[0]->user_info->account_id); } + if (it != per_user_prefs_.end()) { + for (auto& observer : observers_) + observer.OnActiveUserPrefServiceChanged(last_active_user_prefs_); + } UpdateLoginStatus(); } @@ -318,6 +349,7 @@ void SessionController::ClearUserSessionsForTest() { user_sessions_.clear(); + last_active_user_prefs_ = nullptr; } void SessionController::FlushMojoForTest() { @@ -329,6 +361,12 @@ FlushMojoForTest(); } +void SessionController::ProvideUserPrefServiceForTest( + const AccountId& account_id, + std::unique_ptr<PrefService> pref_service) { + OnProfilePrefServiceInitialized(account_id, std::move(pref_service)); +} + void SessionController::SetSessionState(SessionState state) { if (state_ == state) return; @@ -355,6 +393,22 @@ user_sessions_.push_back(std::move(user_session)); + if (connector_) { + auto pref_registry = base::MakeRefCounted<PrefRegistrySimple>(); + Shell::RegisterProfilePrefs(pref_registry.get()); + ash::mojom::PrefConnectorPtr pref_connector_connector; + connector_->BindInterface(mojom::kPrefConnectorServiceName, + &pref_connector_connector); + prefs::mojom::PrefStoreConnectorPtr pref_connector; + pref_connector_connector->GetPrefStoreConnectorForUser( + account_id, mojo::MakeRequest(&pref_connector)); + + prefs::ConnectToPrefService( + std::move(pref_connector), std::move(pref_registry), + base::Bind(&SessionController::OnProfilePrefServiceInitialized, + weak_ptr_factory_.GetWeakPtr(), account_id)); + } + for (auto& observer : observers_) observer.OnUserSessionAdded(account_id); } @@ -432,4 +486,23 @@ std::move(start_lock_callback_).Run(true /* locked */); } +void SessionController::OnProfilePrefServiceInitialized( + const AccountId& account_id, + std::unique_ptr<PrefService> pref_service) { + // |pref_service| can be null when running standalone without chrome. + if (!pref_service) + return; + + PrefService* pref_service_ptr = pref_service.get(); + bool inserted = + per_user_prefs_.emplace(account_id, std::move(pref_service)).second; + DCHECK(inserted); + DCHECK(!user_sessions_.empty()); + if (account_id == user_sessions_[0]->user_info->account_id) { + last_active_user_prefs_ = pref_service_ptr; + for (auto& observer : observers_) + observer.OnActiveUserPrefServiceChanged(pref_service_ptr); + } +} + } // namespace ash
diff --git a/ash/session/session_controller.h b/ash/session/session_controller.h index 2b10d43..36bf970 100644 --- a/ash/session/session_controller.h +++ b/ash/session/session_controller.h
@@ -21,6 +21,11 @@ #include "mojo/public/cpp/bindings/binding_set.h" class AccountId; +class PrefService; + +namespace service_manager { +class Connector; +} namespace ash { @@ -29,10 +34,13 @@ // Implements mojom::SessionController to cache session related info such as // session state, meta data about user sessions to support synchronous // queries for ash. -class ASH_EXPORT SessionController - : NON_EXPORTED_BASE(public mojom::SessionController) { +class ASH_EXPORT SessionController : public mojom::SessionController { public: - SessionController(); + // |connector| is used to connect to other services for connecting to per-user + // PrefServices. If |connector| is null, no per-user PrefService instances + // will be created. In tests, ProvideUserPrefServiceForTest() can be used to + // inject a PrefService for a user when |connector| is null. + explicit SessionController(service_manager::Connector* connector); ~SessionController() override; base::TimeDelta session_length_limit() const { return session_length_limit_; } @@ -116,6 +124,14 @@ // Show the multi-profile login UI to add another user to this session. void ShowMultiProfileLogin(); + // Returns the PrefService for |account_id| or null if one does not exist. + PrefService* GetUserPrefServiceForUser(const AccountId& account_id); + + // Returns the PrefService for the last active user that had one or null if no + // PrefService connection has been successfully established, for example, + // during login before the first user is active. + PrefService* GetLastActiveUserPrefService(); + void AddObserver(SessionObserver* observer); void RemoveObserver(SessionObserver* observer); @@ -142,6 +158,8 @@ void ClearUserSessionsForTest(); void FlushMojoForTest(); void LockScreenAndFlushForTest(); + void ProvideUserPrefServiceForTest(const AccountId& account_id, + std::unique_ptr<PrefService> pref_service); private: void SetSessionState(session_manager::SessionState state); @@ -161,6 +179,10 @@ // run |start_lock_callback_| to indicate ash is locked successfully. void OnLockAnimationFinished(); + void OnProfilePrefServiceInitialized( + const AccountId& account_id, + std::unique_ptr<PrefService> pref_service); + // Bindings for mojom::SessionController interface. mojo::BindingSet<mojom::SessionController> bindings_; @@ -204,6 +226,11 @@ base::ObserverList<ash::SessionObserver> observers_; + service_manager::Connector* const connector_; + + std::map<AccountId, std::unique_ptr<PrefService>> per_user_prefs_; + PrefService* last_active_user_prefs_ = nullptr; + base::WeakPtrFactory<SessionController> weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(SessionController);
diff --git a/ash/session/session_controller_unittest.cc b/ash/session/session_controller_unittest.cc index 52c5d280..82071d8 100644 --- a/ash/session/session_controller_unittest.cc +++ b/ash/session/session_controller_unittest.cc
@@ -13,9 +13,13 @@ #include "ash/public/interfaces/session_controller.mojom.h" #include "ash/session/session_controller.h" #include "ash/session/session_observer.h" +#include "ash/session/test_session_controller_client.h" +#include "ash/shell.h" +#include "ash/test/ash_test_base.h" #include "base/callback.h" #include "base/macros.h" #include "base/memory/ptr_util.h" +#include "components/prefs/testing_pref_service.h" #include "components/user_manager/user_type.h" #include "testing/gtest/include/gtest/gtest.h" @@ -40,6 +44,10 @@ void OnSessionStateChanged(SessionState state) override { state_ = state; } + void OnActiveUserPrefServiceChanged(PrefService* pref_service) override { + last_user_pref_service_ = pref_service; + } + std::string GetUserSessionEmails() const { std::string emails; for (const auto& account_id : user_session_account_ids_) { @@ -53,11 +61,16 @@ const std::vector<AccountId>& user_session_account_ids() const { return user_session_account_ids_; } + PrefService* last_user_pref_service() const { + return last_user_pref_service_; + } + void clear_last_user_pref_service() { last_user_pref_service_ = nullptr; } private: SessionState state_ = SessionState::UNKNOWN; AccountId active_account_id_; std::vector<AccountId> user_session_account_ids_; + PrefService* last_user_pref_service_ = nullptr; DISALLOW_COPY_AND_ASSIGN(TestSessionObserver); }; @@ -77,7 +90,7 @@ // testing::Test: void SetUp() override { - controller_ = base::MakeUnique<SessionController>(); + controller_ = base::MakeUnique<SessionController>(nullptr); controller_->AddObserver(&observer_); } @@ -381,5 +394,75 @@ EXPECT_TRUE(controller()->IsUserSupervised()); } +using SessionControllerPrefsTest = NoSessionAshTestBase; + +// Verifies that ShellObserver is notified for PrefService changes. +TEST_F(SessionControllerPrefsTest, Observer) { + constexpr char kUser1[] = "user1@test.com"; + constexpr char kUser2[] = "user2@test.com"; + const AccountId kUserAccount1 = AccountId::FromUserEmail(kUser1); + const AccountId kUserAccount2 = AccountId::FromUserEmail(kUser2); + + TestSessionObserver observer; + SessionController* controller = Shell::Get()->session_controller(); + controller->AddObserver(&observer); + + // Setup 2 users. + TestSessionControllerClient* session = GetSessionControllerClient(); + // Disable auto-provision of PrefService for each user. + constexpr bool kEnableSettings = true; + constexpr bool kProvidePrefService = false; + session->AddUserSession(kUser1, user_manager::USER_TYPE_REGULAR, + kEnableSettings, kProvidePrefService); + session->AddUserSession(kUser2, user_manager::USER_TYPE_REGULAR, + kEnableSettings, kProvidePrefService); + + // The observer is not notified because the PrefService for kUser1 is not yet + // ready. + session->SwitchActiveUser(kUserAccount1); + EXPECT_EQ(nullptr, observer.last_user_pref_service()); + + auto pref_service = base::MakeUnique<TestingPrefServiceSimple>(); + Shell::RegisterProfilePrefs(pref_service->registry()); + controller->ProvideUserPrefServiceForTest(kUserAccount1, + std::move(pref_service)); + EXPECT_EQ(controller->GetUserPrefServiceForUser(kUserAccount1), + observer.last_user_pref_service()); + EXPECT_EQ(controller->GetUserPrefServiceForUser(kUserAccount1), + controller->GetLastActiveUserPrefService()); + + observer.clear_last_user_pref_service(); + + // Switching to a user for which prefs are not ready does not notify and + // GetLastActiveUserPrefService() returns the old PrefService. + session->SwitchActiveUser(AccountId::FromUserEmail(kUser2)); + EXPECT_EQ(nullptr, observer.last_user_pref_service()); + EXPECT_EQ(controller->GetUserPrefServiceForUser(kUserAccount1), + controller->GetLastActiveUserPrefService()); + + session->SwitchActiveUser(AccountId::FromUserEmail(kUser1)); + EXPECT_EQ(controller->GetUserPrefServiceForUser(kUserAccount1), + observer.last_user_pref_service()); + EXPECT_EQ(controller->GetUserPrefServiceForUser(kUserAccount1), + controller->GetLastActiveUserPrefService()); + + // There should be no notification about a PrefService for an inactive user + // becoming initialized. + observer.clear_last_user_pref_service(); + pref_service = base::MakeUnique<TestingPrefServiceSimple>(); + Shell::RegisterProfilePrefs(pref_service->registry()); + controller->ProvideUserPrefServiceForTest(kUserAccount2, + std::move(pref_service)); + EXPECT_EQ(nullptr, observer.last_user_pref_service()); + + session->SwitchActiveUser(AccountId::FromUserEmail(kUser2)); + EXPECT_EQ(controller->GetUserPrefServiceForUser(kUserAccount2), + observer.last_user_pref_service()); + EXPECT_EQ(controller->GetUserPrefServiceForUser(kUserAccount2), + controller->GetLastActiveUserPrefService()); + + controller->RemoveObserver(&observer); +} + } // namespace } // namespace ash
diff --git a/ash/session/session_observer.h b/ash/session/session_observer.h index f87a0544..0217b5f7 100644 --- a/ash/session/session_observer.h +++ b/ash/session/session_observer.h
@@ -10,6 +10,7 @@ #include "components/session_manager/session_manager_types.h" class AccountId; +class PrefService; namespace ash { @@ -41,6 +42,12 @@ // Called when the limit becomes available and when it changes. virtual void OnSessionLengthLimitChanged() {} + // Called when the PrefService for the active user session changes. This can + // be due to the active user session changing or the PrefService for the + // currently-active user session becoming initialized. This is never called + // with null. + virtual void OnActiveUserPrefServiceChanged(PrefService* pref_service) {} + protected: virtual ~SessionObserver() {} };
diff --git a/ash/session/test_session_controller_client.cc b/ash/session/test_session_controller_client.cc index 5c88c226..47080ae 100644 --- a/ash/session/test_session_controller_client.cc +++ b/ash/session/test_session_controller_client.cc
@@ -12,6 +12,7 @@ #include "ash/shell.h" #include "base/logging.h" #include "base/strings/stringprintf.h" +#include "components/prefs/testing_pref_service.h" #include "components/session_manager/session_manager_types.h" #include "components/signin/core/account_id/account_id.h" #include "components/user_manager/user_type.h" @@ -99,18 +100,28 @@ void TestSessionControllerClient::AddUserSession( const std::string& display_email, user_manager::UserType user_type, - bool enable_settings) { + bool enable_settings, + bool provide_pref_service) { + auto account_id = AccountId::FromUserEmail(GetUserIdFromEmail(display_email)); mojom::UserSessionPtr session = mojom::UserSession::New(); session->session_id = ++fake_session_id_; session->user_info = mojom::UserInfo::New(); session->user_info->type = user_type; - session->user_info->account_id = - AccountId::FromUserEmail(GetUserIdFromEmail(display_email)); + session->user_info->account_id = account_id; session->user_info->display_name = "Über tray Über tray Über tray Über tray"; session->user_info->display_email = display_email; session->should_enable_settings = enable_settings; session->should_show_notification_tray = true; controller_->UpdateUserSession(std::move(session)); + + if (provide_pref_service && + !Shell::Get()->session_controller()->GetUserPrefServiceForUser( + account_id)) { + auto pref_service = base::MakeUnique<TestingPrefServiceSimple>(); + Shell::RegisterProfilePrefs(pref_service->registry()); + Shell::Get()->session_controller()->ProvideUserPrefServiceForTest( + account_id, std::move(pref_service)); + } } void TestSessionControllerClient::UnlockScreen() {
diff --git a/ash/session/test_session_controller_client.h b/ash/session/test_session_controller_client.h index 97824f03..e8b45e3 100644 --- a/ash/session/test_session_controller_client.h +++ b/ash/session/test_session_controller_client.h
@@ -50,11 +50,13 @@ // Adds a user session from a given display email. The display email will be // canonicalized and used to construct an AccountId. |enable_settings| sets - // whether web UI settings are allowed. + // whether web UI settings are allowed. If |provide_pref_service| is true, + // eagerly inject a PrefService for this user. void AddUserSession( const std::string& display_email, user_manager::UserType user_type = user_manager::USER_TYPE_REGULAR, - bool enable_settings = true); + bool enable_settings = true, + bool provide_pref_service = true); // Simulates screen unlocking. It is virtual so that test cases can override // it. The default implementation sets the session state of SessionController
diff --git a/ash/shelf/app_list_button_unittest.cc b/ash/shelf/app_list_button_unittest.cc index f59bc87..9d8dee6 100644 --- a/ash/shelf/app_list_button_unittest.cc +++ b/ash/shelf/app_list_button_unittest.cc
@@ -39,7 +39,7 @@ app_list_button_ = GetPrimaryShelf()->GetShelfViewForTesting()->GetAppListButton(); - controller_ = base::MakeUnique<SessionController>(); + controller_ = base::MakeUnique<SessionController>(nullptr); controller_->AddObserver(app_list_button_); user_manager_ = base::MakeUnique<user_manager::FakeUserManager>(); user_manager_->Initialize();
diff --git a/ash/shelf/shelf.cc b/ash/shelf/shelf.cc index df6ade6f..c68ea77 100644 --- a/ash/shelf/shelf.cc +++ b/ash/shelf/shelf.cc
@@ -221,6 +221,11 @@ : SHELF_HIDDEN; } +int Shelf::GetAccessibilityPanelHeight() const { + return shelf_layout_manager_ ? shelf_layout_manager_->chromevox_panel_height() + : 0; +} + gfx::Rect Shelf::GetIdealBounds() { return shelf_layout_manager_->GetIdealBounds(); }
diff --git a/ash/shelf/shelf.h b/ash/shelf/shelf.h index 9c673a5..f7de0e5 100644 --- a/ash/shelf/shelf.h +++ b/ash/shelf/shelf.h
@@ -95,6 +95,8 @@ ShelfVisibilityState GetVisibilityState() const; + int GetAccessibilityPanelHeight() const; + // Returns the ideal bounds of the shelf assuming it is visible. gfx::Rect GetIdealBounds();
diff --git a/ash/shelf/shelf_alignment_menu.cc b/ash/shelf/shelf_alignment_menu.cc index 270e114..bc799528 100644 --- a/ash/shelf/shelf_alignment_menu.cc +++ b/ash/shelf/shelf_alignment_menu.cc
@@ -8,6 +8,7 @@ #include "ash/metrics/user_metrics_recorder.h" #include "ash/public/cpp/shelf_prefs.h" #include "ash/public/cpp/shelf_types.h" +#include "ash/session/session_controller.h" #include "ash/shelf/shelf.h" #include "ash/shelf/shelf_widget.h" #include "ash/shell.h" @@ -49,8 +50,9 @@ } void ShelfAlignmentMenu::ExecuteCommand(int command_id, int event_flags) { - PrefService* prefs = Shell::Get()->GetActiveUserPrefService(); - if (!prefs) // Null during startup, user switch and tests. + PrefService* prefs = + Shell::Get()->session_controller()->GetLastActiveUserPrefService(); + if (!prefs) // Null during startup. return; int64_t display_id =
diff --git a/ash/shelf/shelf_controller.cc b/ash/shelf/shelf_controller.cc index 93bcbf32..be74793 100644 --- a/ash/shelf/shelf_controller.cc +++ b/ash/shelf/shelf_controller.cc
@@ -43,7 +43,7 @@ // otherwise this wrongly tries to set the alignment on a secondary display // during login before the ShelfLockingManager is created. SessionController* session_controller = Shell::Get()->session_controller(); - PrefService* prefs = Shell::Get()->GetActiveUserPrefService(); + PrefService* prefs = session_controller->GetLastActiveUserPrefService(); if (!prefs || !session_controller->IsActiveUserSessionStarted()) return; @@ -64,7 +64,7 @@ // otherwise this wrongly tries to set the alignment on a secondary display // during login before the ShelfLockingManager is created. SessionController* session_controller = Shell::Get()->session_controller(); - PrefService* prefs = Shell::Get()->GetActiveUserPrefService(); + PrefService* prefs = session_controller->GetLastActiveUserPrefService(); if (!prefs || !session_controller->IsActiveUserSessionStarted()) return; @@ -94,13 +94,13 @@ model_.Set(0, item); model_.AddObserver(this); - Shell::Get()->AddShellObserver(this); + Shell::Get()->session_controller()->AddObserver(this); Shell::Get()->window_tree_host_manager()->AddObserver(this); } ShelfController::~ShelfController() { Shell::Get()->window_tree_host_manager()->RemoveObserver(this); - Shell::Get()->RemoveShellObserver(this); + Shell::Get()->session_controller()->RemoveObserver(this); model_.RemoveObserver(this); } @@ -278,9 +278,6 @@ void ShelfController::OnActiveUserPrefServiceChanged( PrefService* pref_service) { - pref_change_registrar_.reset(); - if (!pref_service) // Null during startup, user switch and tests. - return; SetShelfBehaviorsFromPrefs(); pref_change_registrar_ = base::MakeUnique<PrefChangeRegistrar>(); pref_change_registrar_->Init(pref_service);
diff --git a/ash/shelf/shelf_controller.h b/ash/shelf/shelf_controller.h index a596cf3..28da3c27 100644 --- a/ash/shelf/shelf_controller.h +++ b/ash/shelf/shelf_controller.h
@@ -11,7 +11,7 @@ #include "ash/public/cpp/shelf_model_observer.h" #include "ash/public/cpp/shelf_types.h" #include "ash/public/interfaces/shelf.mojom.h" -#include "ash/shell_observer.h" +#include "ash/session/session_observer.h" #include "mojo/public/cpp/bindings/binding_set.h" #include "mojo/public/cpp/bindings/interface_ptr_set.h" @@ -24,7 +24,7 @@ // that allow Chrome to modify and observe the Shelf and ShelfModel state. class ShelfController : public mojom::ShelfController, public ShelfModelObserver, - public ShellObserver, + public SessionObserver, public WindowTreeHostManager::Observer { public: ShelfController(); @@ -55,7 +55,7 @@ ShelfItemDelegate* delegate) override; private: - // ShellObserver: + // SessionObserver: void OnActiveUserPrefServiceChanged(PrefService* pref_service) override; // WindowTreeHostManager::Observer:
diff --git a/ash/shelf/shelf_controller_unittest.cc b/ash/shelf/shelf_controller_unittest.cc index 852c688..af6d1fb 100644 --- a/ash/shelf/shelf_controller_unittest.cc +++ b/ash/shelf/shelf_controller_unittest.cc
@@ -13,13 +13,14 @@ #include "ash/public/cpp/shelf_prefs.h" #include "ash/public/interfaces/shelf.mojom.h" #include "ash/root_window_controller.h" +#include "ash/session/session_controller.h" #include "ash/session/test_session_controller_client.h" #include "ash/shelf/shelf.h" #include "ash/shell.h" #include "ash/test/ash_test_base.h" #include "ash/test/ash_test_helper.h" #include "ash/test_shell_delegate.h" -#include "components/prefs/testing_pref_service.h" +#include "components/prefs/pref_service.h" #include "mojo/public/cpp/bindings/associated_binding.h" namespace ash { @@ -161,11 +162,6 @@ ~ShelfControllerPrefsTest() override = default; void SetUp() override { - // TODO(crbug.com/753149): Refine apis to use TestPrefService in mash. - Shell::RegisterProfilePrefs(prefs_.registry()); - TestShellDelegate* delegate = new TestShellDelegate(); - delegate->set_active_user_pref_service(&prefs_); - ash_test_helper()->set_test_shell_delegate(delegate); AshTestBase::SetUp(); TestSessionControllerClient* session = GetSessionControllerClient(); session->AddUserSession("user1@test.com"); @@ -174,8 +170,6 @@ } private: - TestingPrefServiceSimple prefs_; - DISALLOW_COPY_AND_ASSIGN(ShelfControllerPrefsTest); }; @@ -185,12 +179,8 @@ EXPECT_EQ(SHELF_ALIGNMENT_BOTTOM, shelf->alignment()); EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_NEVER, shelf->auto_hide_behavior()); - PrefService* prefs = Shell::Get()->GetActiveUserPrefService(); - // TODO(crbug.com/753149): Enable with Mash GetActiveUserPrefService support. - EXPECT_EQ(Shell::GetAshConfig() == Config::MASH, prefs == nullptr); - if (Shell::GetAshConfig() == Config::MASH) - return; - + PrefService* prefs = + Shell::Get()->session_controller()->GetLastActiveUserPrefService(); prefs->SetString(prefs::kShelfAlignmentLocal, "Left"); prefs->SetString(prefs::kShelfAutoHideBehaviorLocal, "Always"); @@ -212,12 +202,8 @@ EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_NEVER, shelf1->auto_hide_behavior()); EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_NEVER, shelf2->auto_hide_behavior()); - PrefService* prefs = Shell::Get()->GetActiveUserPrefService(); - // TODO(crbug.com/753149): Enable with Mash GetActiveUserPrefService support. - EXPECT_EQ(Shell::GetAshConfig() == Config::MASH, prefs == nullptr); - if (Shell::GetAshConfig() == Config::MASH) - return; - + PrefService* prefs = + Shell::Get()->session_controller()->GetLastActiveUserPrefService(); SetShelfAlignmentPref(prefs, id1, SHELF_ALIGNMENT_LEFT); SetShelfAlignmentPref(prefs, id2, SHELF_ALIGNMENT_RIGHT); SetShelfAutoHideBehaviorPref(prefs, id1, SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); @@ -242,12 +228,8 @@ EXPECT_EQ(GetPrimaryShelf(), GetShelfForDisplay(internal_display_id)); EXPECT_NE(GetPrimaryShelf(), GetShelfForDisplay(external_display_id)); - PrefService* prefs = Shell::Get()->GetActiveUserPrefService(); - // TODO(crbug.com/753149): Enable with Mash GetActiveUserPrefService support. - EXPECT_EQ(Shell::GetAshConfig() == Config::MASH, prefs == nullptr); - if (Shell::GetAshConfig() == Config::MASH) - return; - + PrefService* prefs = + Shell::Get()->session_controller()->GetLastActiveUserPrefService(); // Check for the default shelf preferences. EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_NEVER, GetShelfAutoHideBehaviorPref(prefs, internal_display_id));
diff --git a/ash/shelf/shelf_layout_manager.h b/ash/shelf/shelf_layout_manager.h index afe6863..03125e2c 100644 --- a/ash/shelf/shelf_layout_manager.h +++ b/ash/shelf/shelf_layout_manager.h
@@ -114,6 +114,8 @@ } ShelfAutoHideState auto_hide_state() const { return state_.auto_hide_state; } + int chromevox_panel_height() const { return chromevox_panel_height_; } + ShelfWidget* shelf_widget() { return shelf_widget_; } // Sets whether any windows overlap the shelf. If a window overlaps the shelf
diff --git a/ash/shelf/voice_interaction_overlay.cc b/ash/shelf/voice_interaction_overlay.cc index 2495e28..ff9f47e 100644 --- a/ash/shelf/voice_interaction_overlay.cc +++ b/ash/shelf/voice_interaction_overlay.cc
@@ -87,8 +87,6 @@ constexpr float kBackgroundCornerRadiusDip = 12.f; constexpr float kBackgroundPaddingDip = 6.f; constexpr int kBackgroundMorphDurationMs = 150; -constexpr SkColor kBackgroundColor = SK_ColorWHITE; -constexpr SkColor kBackgroundFinalColor = static_cast<SkColor>(0xFFF5F5F5); constexpr int kHideDurationMs = 200; @@ -228,26 +226,18 @@ center_point_( gfx::PointF(kBackgroundSizeDip / 2, kBackgroundSizeDip / 2)), circle_layer_delegate_(base::MakeUnique<views::CircleLayerDelegate>( - kBackgroundColor, - kBackgroundSizeDip / 2)), - bg_circle_layer_delegate_(base::MakeUnique<views::CircleLayerDelegate>( - kBackgroundFinalColor, + SK_ColorWHITE, kBackgroundSizeDip / 2)), rect_layer_delegate_(base::MakeUnique<views::RectangleLayerDelegate>( - kBackgroundColor, - gfx::SizeF(small_size_))), - bg_rect_layer_delegate_(base::MakeUnique<views::RectangleLayerDelegate>( - kBackgroundFinalColor, + SK_ColorWHITE, gfx::SizeF(small_size_))) { set_name("VoiceInteractionOverlay:BACKGROUND_LAYER"); SetBounds(gfx::Rect(0, 0, kBackgroundInitSizeDip, kBackgroundInitSizeDip)); SetFillsBoundsOpaquely(false); SetMasksToBounds(false); - for (int i = 0; i < PAINTED_SHAPE_COUNT; ++i) { - AddPaintLayer(static_cast<PaintedShape>(i), true); - AddPaintLayer(static_cast<PaintedShape>(i), false); - } + for (int i = 0; i < PAINTED_SHAPE_COUNT; ++i) + AddPaintLayer(static_cast<PaintedShape>(i)); shadow_values_ = gfx::ShadowValue::MakeMdShadowValues(kBackgroundShadowElevationDip); @@ -327,26 +317,18 @@ typedef gfx::Transform PaintedShapeTransforms[PAINTED_SHAPE_COUNT]; - void AddPaintLayer(PaintedShape painted_shape, bool is_background) { + void AddPaintLayer(PaintedShape painted_shape) { ui::LayerDelegate* delegate = nullptr; switch (painted_shape) { case TOP_LEFT_CIRCLE: case TOP_RIGHT_CIRCLE: case BOTTOM_RIGHT_CIRCLE: case BOTTOM_LEFT_CIRCLE: - if (is_background) { - delegate = bg_circle_layer_delegate_.get(); - } else { - delegate = circle_layer_delegate_.get(); - } + delegate = circle_layer_delegate_.get(); break; case HORIZONTAL_RECT: case VERTICAL_RECT: - if (is_background) { - delegate = bg_rect_layer_delegate_.get(); - } else { - delegate = rect_layer_delegate_.get(); - } + delegate = rect_layer_delegate_.get(); break; case PAINTED_SHAPE_COUNT: NOTREACHED() << "PAINTED_SHAPE_COUNT is not an actual shape type."; @@ -364,27 +346,17 @@ layer->SetMasksToBounds(false); layer->set_name("PAINTED_SHAPE_COUNT:" + ToLayerName(painted_shape)); - if (is_background) { - bg_painted_layers_[static_cast<int>(painted_shape)].reset(layer); - } else { - painted_layers_[static_cast<int>(painted_shape)].reset(layer); - } + painted_layers_[static_cast<int>(painted_shape)].reset(layer); } void SetTransforms(const PaintedShapeTransforms transforms) { - for (int i = 0; i < PAINTED_SHAPE_COUNT; ++i) { + for (int i = 0; i < PAINTED_SHAPE_COUNT; ++i) painted_layers_[i]->SetTransform(transforms[i]); - bg_painted_layers_[i]->SetTransform(transforms[i]); - } } void SetPaintedLayersVisible(bool visible) { - for (int i = 0; i < PAINTED_SHAPE_COUNT; ++i) { + for (int i = 0; i < PAINTED_SHAPE_COUNT; ++i) painted_layers_[i]->SetVisible(visible); - painted_layers_[i]->SetOpacity(1); - bg_painted_layers_[i]->SetVisible(visible); - bg_painted_layers_[i]->SetOpacity(1); - } } void CalculateCircleTransforms(const gfx::Size& size, @@ -487,25 +459,6 @@ ui::ScopedLayerAnimationSettings animation(animator); animation.SetPreemptionStrategy(preemption_strategy); animation.SetTweenType(tween); - animation.SetTransitionDuration(duration); - painted_layers_[i]->SetOpacity(0); - std::unique_ptr<ui::LayerAnimationElement> element = - ui::LayerAnimationElement::CreateTransformElement(transforms[i], - duration); - ui::LayerAnimationSequence* sequence = - new ui::LayerAnimationSequence(std::move(element)); - - if (animation_observer) - sequence->AddObserver(animation_observer); - - animator->StartAnimation(sequence); - } - - for (int i = 0; i < PAINTED_SHAPE_COUNT; ++i) { - ui::LayerAnimator* animator = bg_painted_layers_[i]->GetAnimator(); - ui::ScopedLayerAnimationSettings animation(animator); - animation.SetPreemptionStrategy(preemption_strategy); - animation.SetTweenType(tween); std::unique_ptr<ui::LayerAnimationElement> element = ui::LayerAnimationElement::CreateTransformElement(transforms[i], duration); @@ -549,7 +502,7 @@ gfx::Canvas* canvas = recorder.canvas(); cc::PaintFlags flags; - flags.setColor(kBackgroundColor); + flags.setColor(SK_ColorWHITE); flags.setAntiAlias(true); flags.setStyle(cc::PaintFlags::kFill_Style); flags.setLooper(gfx::CreateShadowDrawLooper(shadow_values_)); @@ -564,11 +517,8 @@ void OnDeviceScaleFactorChanged(float device_scale_factor) override {} // ui::Layers for all of the painted shape layers that compose the morphing - // shape. We have two sets, one is rendered in the foreground, the other set - // behind. We use them to create an animated transition between two colors by - // fading out one set during transformation. + // shape. std::unique_ptr<ui::Layer> painted_layers_[PAINTED_SHAPE_COUNT]; - std::unique_ptr<ui::Layer> bg_painted_layers_[PAINTED_SHAPE_COUNT]; const gfx::Size large_size_; @@ -579,11 +529,9 @@ // ui::LayerDelegate to paint circles for all the circle layers. std::unique_ptr<views::CircleLayerDelegate> circle_layer_delegate_; - std::unique_ptr<views::CircleLayerDelegate> bg_circle_layer_delegate_; // ui::LayerDelegate to paint rectangles for all the rectangle layers. std::unique_ptr<views::RectangleLayerDelegate> rect_layer_delegate_; - std::unique_ptr<views::RectangleLayerDelegate> bg_rect_layer_delegate_; gfx::ShadowValues shadow_values_;
diff --git a/ash/shell.cc b/ash/shell.cc index b2f7edf4..0c68f9a9 100644 --- a/ash/shell.cc +++ b/ash/shell.cc
@@ -341,6 +341,10 @@ LogoutButtonTray::RegisterProfilePrefs(registry); NightLightController::RegisterProfilePrefs(registry); ShelfController::RegisterProfilePrefs(registry); + + // Request access to prefs used by ash but owned by chrome. + // See //services/preferences/README.md + TrayCapsLock::RegisterForeignPrefs(registry); } views::NonClientFrameView* Shell::CreateDefaultNonClientFrameView( @@ -425,13 +429,6 @@ Shelf::ForWindow(root)->UpdateVisibilityState(); } -PrefService* Shell::GetActiveUserPrefService() const { - if (shell_port_->GetAshConfig() == Config::MASH) - return profile_pref_service_mash_.get(); - - return shell_delegate_->GetActiveUserPrefService(); -} - PrefService* Shell::GetLocalStatePrefService() const { if (shell_port_->GetAshConfig() == Config::MASH) return local_state_mash_.get(); @@ -642,7 +639,8 @@ lock_screen_controller_(base::MakeUnique<LockScreenController>()), media_controller_(base::MakeUnique<MediaController>()), new_window_controller_(base::MakeUnique<NewWindowController>()), - session_controller_(base::MakeUnique<SessionController>()), + session_controller_(base::MakeUnique<SessionController>( + shell_delegate->GetShellConnector())), shell_delegate_(std::move(shell_delegate)), shutdown_controller_(base::MakeUnique<ShutdownController>()), system_tray_controller_(base::MakeUnique<SystemTrayController>()), @@ -861,7 +859,6 @@ // NightLightController depeneds on the PrefService and must be destructed // before it. crbug.com/724231. night_light_controller_ = nullptr; - profile_pref_service_mash_.reset(); local_state_mash_.reset(); local_state_non_mash_ = nullptr; shell_delegate_.reset(); @@ -1254,28 +1251,6 @@ root_window_for_new_windows_ = gained_active->GetRootWindow(); } -void Shell::OnActiveUserSessionChanged(const AccountId& account_id) { - if (GetAshConfig() == Config::MASH && shell_delegate_->GetShellConnector()) { - // NOTE: |profile_pref_service_| will point to the previous user's profile - // while the connection is being made. - auto pref_registry = base::MakeRefCounted<PrefRegistrySimple>(); - RegisterProfilePrefs(pref_registry.get()); - RegisterForeignPrefs(pref_registry.get()); - prefs::ConnectToPrefService( - shell_delegate_->GetShellConnector(), pref_registry, - base::Bind(&Shell::OnProfilePrefServiceInitialized, - weak_factory_.GetWeakPtr()), - prefs::mojom::kForwarderServiceName); - return; - } - - // On classic ash user profile prefs are available immediately after login. - // The login screen temporary profile is never available. - PrefService* profile_prefs = shell_delegate_->GetActiveUserPrefService(); - for (auto& observer : shell_observers_) - observer.OnActiveUserPrefServiceChanged(profile_prefs); -} - void Shell::OnSessionStateChanged(session_manager::SessionState state) { // Initialize the shelf when a session becomes active. It's safe to do this // multiple times (e.g. initial login vs. multiprofile add session). @@ -1331,29 +1306,6 @@ root->InitializeShelf(); } -// static -void Shell::RegisterForeignPrefs(PrefRegistrySimple* registry) { - DCHECK_EQ(GetAshConfig(), Config::MASH); - // Request access to prefs used by ash but owned by chrome. - // See //services/preferences/README.md - TrayCapsLock::RegisterForeignPrefs(registry); -} - -void Shell::OnProfilePrefServiceInitialized( - std::unique_ptr<PrefService> pref_service) { - DCHECK(GetAshConfig() == Config::MASH); - // Keep the old PrefService object alive so OnActiveUserPrefServiceChanged() - // clients can unregister pref observers on the old service. - std::unique_ptr<PrefService> old_service = - std::move(profile_pref_service_mash_); - profile_pref_service_mash_ = std::move(pref_service); - // |pref_service| can be null if can't connect to Chrome (as happens when - // running mash outside of chrome --mash and chrome isn't built). - for (auto& observer : shell_observers_) - observer.OnActiveUserPrefServiceChanged(profile_pref_service_mash_.get()); - // |old_service| is deleted. -} - void Shell::OnLocalStatePrefServiceInitialized( std::unique_ptr<::PrefService> pref_service) { DCHECK(GetAshConfig() == Config::MASH);
diff --git a/ash/shell.h b/ash/shell.h index 5518b0361..15bf047 100644 --- a/ash/shell.h +++ b/ash/shell.h
@@ -429,16 +429,6 @@ // TODO(jamescook): Move to Shelf. void UpdateShelfVisibility(); - // Gets the current active user pref service. - // In classic ash, it will be null if there's no active user. - // In the case of mash, it can be null if it failed to or hasn't yet - // connected to the pref service. - // - // NOTE: Code that uses PrefChangeRegistrar or otherwise observes the - // PrefService must use ShellObserver::OnActiveUserPrefServiceChanged() to - // reset its observers on user switch. - PrefService* GetActiveUserPrefService() const; - // Gets the local state pref service. It can be null in mash if connecting to // local state pref service has not completed successfully. PrefService* GetLocalStatePrefService() const; @@ -660,7 +650,6 @@ aura::Window* lost_active) override; // SessionObserver: - void OnActiveUserSessionChanged(const AccountId& account_id) override; void OnSessionStateChanged(session_manager::SessionState state) override; void OnLoginStatusChanged(LoginStatus login_status) override; void OnLockStateChanged(bool locked) override; @@ -669,12 +658,7 @@ // the profile is available. void InitializeShelf(); - // Registers preferences owned by other services (e.g. chrome). Used in mash. - static void RegisterForeignPrefs(PrefRegistrySimple* registry); - - // Callbacks for prefs::ConnectToPrefService. - void OnProfilePrefServiceInitialized( - std::unique_ptr<::PrefService> pref_service); + // Callback for prefs::ConnectToPrefService. void OnLocalStatePrefServiceInitialized( std::unique_ptr<::PrefService> pref_service); @@ -738,11 +722,6 @@ std::unique_ptr<::wm::WindowModalityController> window_modality_controller_; std::unique_ptr<app_list::AppList> app_list_; - // Only initialized for mash. Can be null in ash_standalone (when chrome is - // not running) or when reconnecting to the mojo pref service after - // multiuser profile switch. - std::unique_ptr<PrefService> profile_pref_service_mash_; - // Used in non-mash. Owned by chrome. PrefService* local_state_non_mash_ = nullptr;
diff --git a/ash/shell/shell_delegate_impl.cc b/ash/shell/shell_delegate_impl.cc index 7c76c75..78edd57 100644 --- a/ash/shell/shell_delegate_impl.cc +++ b/ash/shell/shell_delegate_impl.cc
@@ -147,10 +147,6 @@ return gfx::Image(); } -PrefService* ShellDelegateImpl::GetActiveUserPrefService() const { - return nullptr; -} - bool ShellDelegateImpl::IsTouchscreenEnabledInPrefs( bool use_local_state) const { return true;
diff --git a/ash/shell/shell_delegate_impl.h b/ash/shell/shell_delegate_impl.h index fa4e693..687ef8f 100644 --- a/ash/shell/shell_delegate_impl.h +++ b/ash/shell/shell_delegate_impl.h
@@ -46,7 +46,6 @@ GPUSupport* CreateGPUSupport() override; base::string16 GetProductName() const override; gfx::Image GetDeprecatedAcceleratorImage() const override; - PrefService* GetActiveUserPrefService() const override; bool IsTouchscreenEnabledInPrefs(bool use_local_state) const override; void SetTouchscreenEnabledInPrefs(bool enabled, bool use_local_state) override;
diff --git a/ash/shell_delegate.h b/ash/shell_delegate.h index 6f013d0..8b81480 100644 --- a/ash/shell_delegate.h +++ b/ash/shell_delegate.h
@@ -13,7 +13,6 @@ #include "base/strings/string16.h" class GURL; -class PrefService; namespace aura { class Window; @@ -122,9 +121,6 @@ virtual gfx::Image GetDeprecatedAcceleratorImage() const = 0; - // Not used in mash because ash owns the PrefService. - virtual PrefService* GetActiveUserPrefService() const = 0; - // If |use_local_state| is true, returns the touchscreen status from local // state, otherwise from user prefs. virtual bool IsTouchscreenEnabledInPrefs(bool use_local_state) const = 0;
diff --git a/ash/shell_observer.h b/ash/shell_observer.h index 5e4f2561..c137bd87 100644 --- a/ash/shell_observer.h +++ b/ash/shell_observer.h
@@ -84,14 +84,6 @@ // amount of time after Shell initialization. Only called once. virtual void OnLocalStatePrefServiceInitialized(PrefService* pref_service) {} - // Called when the user profile pref service is available. Also called after - // multiprofile user switch. Never called with the login screen profile. - // May be called with null in tests. - // TODO(jamescook): Either maintain pref service connections for all multiuser - // profiles or make the pref service switch atomic with active user switch. - // http://crbug.com/705347 - virtual void OnActiveUserPrefServiceChanged(PrefService* pref_service) {} - protected: virtual ~ShellObserver() {} };
diff --git a/ash/shell_unittest.cc b/ash/shell_unittest.cc index 367974a..d418c79 100644 --- a/ash/shell_unittest.cc +++ b/ash/shell_unittest.cc
@@ -146,12 +146,8 @@ void OnLocalStatePrefServiceInitialized(PrefService* pref_service) override { last_local_state_ = pref_service; } - void OnActiveUserPrefServiceChanged(PrefService* pref_service) override { - last_user_pref_service_ = pref_service; - } PrefService* last_local_state_ = nullptr; - PrefService* last_user_pref_service_ = nullptr; private: DISALLOW_COPY_AND_ASSIGN(TestShellObserver); @@ -557,51 +553,6 @@ window_->Init(ui::LAYER_NOT_DRAWN); } -class ShellPrefsTest : public NoSessionAshTestBase { - public: - ShellPrefsTest() = default; - ~ShellPrefsTest() override = default; - - // testing::Test: - void SetUp() override { - NoSessionAshTestBase::SetUp(); - Shell::RegisterProfilePrefs(pref_service1_.registry()); - Shell::RegisterProfilePrefs(pref_service2_.registry()); - } - - // Must outlive Shell. - TestingPrefServiceSimple pref_service1_; - TestingPrefServiceSimple pref_service2_; - - private: - DISALLOW_COPY_AND_ASSIGN(ShellPrefsTest); -}; - -// Verifies that ShellObserver is notified for PrefService changes. -TEST_F(ShellPrefsTest, Observer) { - TestShellObserver observer; - Shell::Get()->AddShellObserver(&observer); - - // Setup 2 users. - TestSessionControllerClient* session = GetSessionControllerClient(); - session->AddUserSession("user1@test.com"); - session->AddUserSession("user2@test.com"); - - // Login notifies observers of the user pref service. - ash_test_helper()->test_shell_delegate()->set_active_user_pref_service( - &pref_service1_); - session->SwitchActiveUser(AccountId::FromUserEmail("user1@test.com")); - EXPECT_EQ(&pref_service1_, observer.last_user_pref_service_); - - // Switching users notifies observers of the new user pref service. - ash_test_helper()->test_shell_delegate()->set_active_user_pref_service( - &pref_service2_); - session->SwitchActiveUser(AccountId::FromUserEmail("user2@test.com")); - EXPECT_EQ(&pref_service2_, observer.last_user_pref_service_); - - Shell::Get()->RemoveShellObserver(&observer); -} - // Tests the local state code path used with Config::CLASSIC and Config::MUS. class ShellLocalStateTestNonMash : public NoSessionAshTestBase { public:
diff --git a/ash/shutdown_controller.h b/ash/shutdown_controller.h index 0e46284..437dcd27 100644 --- a/ash/shutdown_controller.h +++ b/ash/shutdown_controller.h
@@ -17,8 +17,7 @@ // Handles actual device shutdown by making requests to powerd over D-Bus. // Caches the DeviceRebootOnShutdown device policy sent from Chrome over mojo. -class ASH_EXPORT ShutdownController - : NON_EXPORTED_BASE(public mojom::ShutdownController) { +class ASH_EXPORT ShutdownController : public mojom::ShutdownController { public: ShutdownController(); ~ShutdownController() override;
diff --git a/ash/system/devicetype_utils.cc b/ash/system/devicetype_utils.cc deleted file mode 100644 index fed5504..0000000 --- a/ash/system/devicetype_utils.cc +++ /dev/null
@@ -1,37 +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. - -#include "ash/system/devicetype_utils.h" - -#include "ash/strings/grit/ash_strings.h" -#include "chromeos/system/devicetype.h" -#include "ui/base/l10n/l10n_util.h" - -namespace ash { - -base::string16 SubstituteChromeOSDeviceType(int resource_id) { - return l10n_util::GetStringFUTF16(resource_id, GetChromeOSDeviceName()); -} - -base::string16 GetChromeOSDeviceName() { - return l10n_util::GetStringUTF16(GetChromeOSDeviceTypeResourceId()); -} - -int GetChromeOSDeviceTypeResourceId() { - switch (chromeos::GetDeviceType()) { - case chromeos::DeviceType::kChromebase: - return IDS_ASH_CHROMEBASE; - case chromeos::DeviceType::kChromebook: - return IDS_ASH_CHROMEBOOK; - case chromeos::DeviceType::kChromebox: - return IDS_ASH_CHROMEBOX; - case chromeos::DeviceType::kChromebit: - return IDS_ASH_CHROMEBIT; - case chromeos::DeviceType::kUnknown: - default: - return IDS_ASH_CHROMEDEVICE; - } -} - -} // namespace ash
diff --git a/ash/system/devicetype_utils.h b/ash/system/devicetype_utils.h deleted file mode 100644 index d958864..0000000 --- a/ash/system/devicetype_utils.h +++ /dev/null
@@ -1,26 +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. - -#ifndef ASH_SYSTEM_DEVICETYPE_UTILS_H_ -#define ASH_SYSTEM_DEVICETYPE_UTILS_H_ - -#include "ash/ash_export.h" -#include "base/strings/string16.h" - -namespace ash { - -// Assuming the given localization resources takes a device type parameter, this -// will substitute the appropriate device in (e.g. Chromebook, Chromebox). -ASH_EXPORT base::string16 SubstituteChromeOSDeviceType(int resource_id); - -// Returns the name of the Chrome device type (e.g. Chromebook, Chromebox). -ASH_EXPORT base::string16 GetChromeOSDeviceName(); - -// Returns the resource ID for the current Chrome device type (e.g. Chromebook, -// Chromebox). -ASH_EXPORT int GetChromeOSDeviceTypeResourceId(); - -} // namespace ash - -#endif // ASH_SYSTEM_DEVICETYPE_UTILS_H_
diff --git a/ash/system/night_light/night_light_controller.cc b/ash/system/night_light/night_light_controller.cc index d3e7cab..99671431 100644 --- a/ash/system/night_light/night_light_controller.cc +++ b/ash/system/night_light/night_light_controller.cc
@@ -119,11 +119,11 @@ NightLightController::NightLightController() : delegate_(base::MakeUnique<NightLightControllerDelegateImpl>()), binding_(this) { - Shell::Get()->AddShellObserver(this); + Shell::Get()->session_controller()->AddObserver(this); } NightLightController::~NightLightController() { - Shell::Get()->RemoveShellObserver(this); + Shell::Get()->session_controller()->RemoveObserver(this); } // static @@ -134,15 +134,19 @@ // static void NightLightController::RegisterProfilePrefs(PrefRegistrySimple* registry) { - registry->RegisterBooleanPref(prefs::kNightLightEnabled, false); + registry->RegisterBooleanPref(prefs::kNightLightEnabled, false, + PrefRegistry::PUBLIC); registry->RegisterDoublePref(prefs::kNightLightTemperature, - kDefaultColorTemperature); + kDefaultColorTemperature, PrefRegistry::PUBLIC); registry->RegisterIntegerPref(prefs::kNightLightScheduleType, - static_cast<int>(ScheduleType::kNone)); + static_cast<int>(ScheduleType::kNone), + PrefRegistry::PUBLIC); registry->RegisterIntegerPref(prefs::kNightLightCustomStartTime, - kDefaultStartTimeOffsetMinutes); + kDefaultStartTimeOffsetMinutes, + PrefRegistry::PUBLIC); registry->RegisterIntegerPref(prefs::kNightLightCustomEndTime, - kDefaultEndTimeOffsetMinutes); + kDefaultEndTimeOffsetMinutes, + PrefRegistry::PUBLIC); } void NightLightController::BindRequest( @@ -316,12 +320,6 @@ } void NightLightController::InitFromUserPrefs() { - pref_change_registrar_.reset(); - - // Pref service can be null during multiprofile switch and in tests. - if (!active_user_pref_service_) - return; - StartWatchingPrefsChanges(); Refresh(true /* did_schedule_change */); NotifyStatusChanged();
diff --git a/ash/system/night_light/night_light_controller.h b/ash/system/night_light/night_light_controller.h index 21b30b0b..e1e0656e 100644 --- a/ash/system/night_light/night_light_controller.h +++ b/ash/system/night_light/night_light_controller.h
@@ -9,7 +9,7 @@ #include "ash/ash_export.h" #include "ash/public/interfaces/night_light_controller.mojom.h" -#include "ash/shell_observer.h" +#include "ash/session/session_observer.h" #include "ash/system/night_light/time_of_day.h" #include "base/observer_list.h" #include "base/time/time.h" @@ -24,9 +24,8 @@ // Controls the NightLight feature that adjusts the color temperature of the // screen. -class ASH_EXPORT NightLightController - : public NON_EXPORTED_BASE(mojom::NightLightController), - public ShellObserver { +class ASH_EXPORT NightLightController : public mojom::NightLightController, + public SessionObserver { public: using ScheduleType = mojom::NightLightController::ScheduleType; @@ -107,7 +106,7 @@ // AnimationDurationType::kShort. void Toggle(); - // ShellObserver: + // SessionObserver: void OnActiveUserPrefServiceChanged(PrefService* pref_service) override; // ash::mojom::NightLightController:
diff --git a/ash/system/night_light/night_light_controller_unittest.cc b/ash/system/night_light/night_light_controller_unittest.cc index 6024ced..91b71ca 100644 --- a/ash/system/night_light/night_light_controller_unittest.cc +++ b/ash/system/night_light/night_light_controller_unittest.cc
@@ -11,6 +11,7 @@ #include "ash/public/cpp/ash_pref_names.h" #include "ash/public/cpp/config.h" #include "ash/public/cpp/session_types.h" +#include "ash/session/session_controller.h" #include "ash/session/test_session_controller_client.h" #include "ash/shell.h" #include "ash/test/ash_test_base.h" @@ -20,7 +21,7 @@ #include "base/callback_forward.h" #include "base/command_line.h" #include "base/macros.h" -#include "components/prefs/testing_pref_service.h" +#include "components/prefs/pref_service.h" #include "ui/compositor/layer.h" namespace ash { @@ -116,11 +117,14 @@ NightLightTest() = default; ~NightLightTest() override = default; - TestingPrefServiceSimple* user1_pref_service() { - return &user1_pref_service_; + PrefService* user1_pref_service() { + return Shell::Get()->session_controller()->GetUserPrefServiceForUser( + AccountId::FromUserEmail(kUser1Email)); } - TestingPrefServiceSimple* user2_pref_service() { - return &user2_pref_service_; + + PrefService* user2_pref_service() { + return Shell::Get()->session_controller()->GetUserPrefServiceForUser( + AccountId::FromUserEmail(kUser2Email)); } TestDelegate* delegate() const { return delegate_; } @@ -133,11 +137,8 @@ AshTestBase::SetUp(); CreateTestUserSessions(); - Shell::RegisterProfilePrefs(user1_pref_service_.registry()); - Shell::RegisterProfilePrefs(user2_pref_service_.registry()); // Simulate user 1 login. - InjectTestPrefService(&user1_pref_service_); SwitchActiveUser(kUser1Email); delegate_ = new TestDelegate; @@ -155,19 +156,12 @@ AccountId::FromUserEmail(email)); } - void InjectTestPrefService(PrefService* pref_service) { - ash_test_helper()->test_shell_delegate()->set_active_user_pref_service( - pref_service); - } - void SetNightLightEnabled(bool enabled) { GetController()->SetEnabled( enabled, NightLightController::AnimationDuration::kShort); } private: - TestingPrefServiceSimple user1_pref_service_; - TestingPrefServiceSimple user2_pref_service_; TestDelegate* delegate_ = nullptr; @@ -250,7 +244,6 @@ EXPECT_TRUE(TestLayersTemperature(user1_temperature)); // Switch to user 2, and expect NightLight to be disabled. - InjectTestPrefService(user2_pref_service()); SwitchActiveUser(kUser2Email); EXPECT_FALSE(controller->GetEnabled()); // Changing user_2's color temperature shouldn't affect user_1's settings. @@ -264,7 +257,6 @@ // Switch back to user 1, to find NightLight is still enabled, and the same // user's color temperature are re-applied. - InjectTestPrefService(user1_pref_service()); SwitchActiveUser(kUser1Email); EXPECT_TRUE(controller->GetEnabled()); EXPECT_EQ(user1_temperature, controller->GetColorTemperature());
diff --git a/ash/system/night_light/tray_night_light_unittest.cc b/ash/system/night_light/tray_night_light_unittest.cc index 9fbc2df..9c0f08b 100644 --- a/ash/system/night_light/tray_night_light_unittest.cc +++ b/ash/system/night_light/tray_night_light_unittest.cc
@@ -36,17 +36,11 @@ AshTestBase::SetUp(); GetSessionControllerClient()->Reset(); GetSessionControllerClient()->AddUserSession(kFakeUserEmail); - Shell::RegisterProfilePrefs(pref_service_.registry()); - - ash_test_helper()->test_shell_delegate()->set_active_user_pref_service( - &pref_service_); GetSessionControllerClient()->SwitchActiveUser( AccountId::FromUserEmail(kFakeUserEmail)); } private: - TestingPrefServiceSimple pref_service_; - DISALLOW_COPY_AND_ASSIGN(TrayNightLightTest); };
diff --git a/ash/system/palette/common_palette_tool.cc b/ash/system/palette/common_palette_tool.cc index c734883..91a864fa 100644 --- a/ash/system/palette/common_palette_tool.cc +++ b/ash/system/palette/common_palette_tool.cc
@@ -64,7 +64,8 @@ DCHECK(!enabled()); delegate()->RecordPaletteOptionsUsage( - PaletteToolIdToPaletteTrayOptions(GetToolId())); + PaletteToolIdToPaletteTrayOptions(GetToolId()), + PaletteInvocationMethod::MENU); delegate()->EnableTool(GetToolId()); }
diff --git a/ash/system/palette/mock_palette_tool_delegate.h b/ash/system/palette/mock_palette_tool_delegate.h index b9626cb..b89f0d6a 100644 --- a/ash/system/palette/mock_palette_tool_delegate.h +++ b/ash/system/palette/mock_palette_tool_delegate.h
@@ -21,7 +21,8 @@ MOCK_METHOD0(HidePalette, void()); MOCK_METHOD0(HidePaletteImmediately, void()); MOCK_METHOD0(GetWindow, aura::Window*()); - MOCK_METHOD1(RecordPaletteOptionsUsage, void(PaletteTrayOptions option)); + MOCK_METHOD2(RecordPaletteOptionsUsage, + void(PaletteTrayOptions option, PaletteInvocationMethod method)); MOCK_METHOD1(RecordPaletteModeCancellation, void(PaletteModeCancelType type)); };
diff --git a/ash/system/palette/palette_ids.h b/ash/system/palette/palette_ids.h index 5bfd47f..7b61b8b 100644 --- a/ash/system/palette/palette_ids.h +++ b/ash/system/palette/palette_ids.h
@@ -53,6 +53,12 @@ PALETTE_MODE_CANCEL_TYPE_COUNT }; +// Type of palette option invocation method. +enum class PaletteInvocationMethod { + MENU, + SHORTCUT, +}; + // Helper functions that convert PaletteToolIds and PaletteGroups to strings. ASH_EXPORT std::string PaletteToolIdToString(PaletteToolId tool_id); ASH_EXPORT std::string PaletteGroupToString(PaletteGroup group);
diff --git a/ash/system/palette/palette_tool.h b/ash/system/palette/palette_tool.h index fa1b8a8..0e4dce3 100644 --- a/ash/system/palette/palette_tool.h +++ b/ash/system/palette/palette_tool.h
@@ -56,7 +56,8 @@ virtual aura::Window* GetWindow() = 0; // Record usage of each pen palette option. - virtual void RecordPaletteOptionsUsage(PaletteTrayOptions option) = 0; + virtual void RecordPaletteOptionsUsage(PaletteTrayOptions option, + PaletteInvocationMethod method) = 0; // Record mode cancellation of pen palette. virtual void RecordPaletteModeCancellation(PaletteModeCancelType type) = 0;
diff --git a/ash/system/palette/palette_tool_manager.cc b/ash/system/palette/palette_tool_manager.cc index 0f40a6d3..eb84e75 100644 --- a/ash/system/palette/palette_tool_manager.cc +++ b/ash/system/palette/palette_tool_manager.cc
@@ -132,8 +132,10 @@ return delegate_->GetWindow(); } -void PaletteToolManager::RecordPaletteOptionsUsage(PaletteTrayOptions option) { - return delegate_->RecordPaletteOptionsUsage(option); +void PaletteToolManager::RecordPaletteOptionsUsage( + PaletteTrayOptions option, + PaletteInvocationMethod method) { + return delegate_->RecordPaletteOptionsUsage(option, method); } void PaletteToolManager::RecordPaletteModeCancellation(
diff --git a/ash/system/palette/palette_tool_manager.h b/ash/system/palette/palette_tool_manager.h index ed0cf2c5..967dc17 100644 --- a/ash/system/palette/palette_tool_manager.h +++ b/ash/system/palette/palette_tool_manager.h
@@ -52,7 +52,8 @@ virtual aura::Window* GetWindow() = 0; // Record usage of each pen palette option. - virtual void RecordPaletteOptionsUsage(PaletteTrayOptions option) = 0; + virtual void RecordPaletteOptionsUsage(PaletteTrayOptions option, + PaletteInvocationMethod method) = 0; // Record mode cancellation of pen palette. virtual void RecordPaletteModeCancellation(PaletteModeCancelType type) = 0; @@ -103,7 +104,8 @@ void HidePalette() override; void HidePaletteImmediately() override; aura::Window* GetWindow() override; - void RecordPaletteOptionsUsage(ash::PaletteTrayOptions option) override; + void RecordPaletteOptionsUsage(ash::PaletteTrayOptions option, + PaletteInvocationMethod method) override; void RecordPaletteModeCancellation(PaletteModeCancelType type) override; PaletteTool* FindToolById(PaletteToolId tool_id) const;
diff --git a/ash/system/palette/palette_tool_manager_unittest.cc b/ash/system/palette/palette_tool_manager_unittest.cc index cebd8cb..76ea7f0 100644 --- a/ash/system/palette/palette_tool_manager_unittest.cc +++ b/ash/system/palette/palette_tool_manager_unittest.cc
@@ -59,7 +59,8 @@ NOTREACHED(); return nullptr; } - void RecordPaletteOptionsUsage(PaletteTrayOptions option) override {} + void RecordPaletteOptionsUsage(PaletteTrayOptions option, + PaletteInvocationMethod method) override {} void RecordPaletteModeCancellation(PaletteModeCancelType type) override {} // PaletteTool::Delegate:
diff --git a/ash/system/palette/palette_tray.cc b/ash/system/palette/palette_tray.cc index 39ed70a..552eca22 100644 --- a/ash/system/palette/palette_tray.cc +++ b/ash/system/palette/palette_tray.cc
@@ -124,12 +124,14 @@ void ButtonPressed(views::Button* sender, const ui::Event& event) override { if (sender == settings_button_) { palette_tray_->RecordPaletteOptionsUsage( - PaletteTrayOptions::PALETTE_SETTINGS_BUTTON); + PaletteTrayOptions::PALETTE_SETTINGS_BUTTON, + PaletteInvocationMethod::MENU); Shell::Get()->system_tray_controller()->ShowPaletteSettings(); palette_tray_->HidePalette(); } else if (sender == help_button_) { palette_tray_->RecordPaletteOptionsUsage( - PaletteTrayOptions::PALETTE_HELP_BUTTON); + PaletteTrayOptions::PALETTE_HELP_BUTTON, + PaletteInvocationMethod::MENU); Shell::Get()->system_tray_controller()->ShowPaletteHelp(); palette_tray_->HidePalette(); } else { @@ -262,8 +264,10 @@ } void PaletteTray::ClickedOutsideBubble() { - if (num_actions_in_bubble_ == 0) - RecordPaletteOptionsUsage(PaletteTrayOptions::PALETTE_CLOSED_NO_ACTION); + if (num_actions_in_bubble_ == 0) { + RecordPaletteOptionsUsage(PaletteTrayOptions::PALETTE_CLOSED_NO_ACTION, + PaletteInvocationMethod::MENU); + } HidePalette(); } @@ -356,10 +360,14 @@ HidePalette(); } -void PaletteTray::RecordPaletteOptionsUsage(PaletteTrayOptions option) { +void PaletteTray::RecordPaletteOptionsUsage(PaletteTrayOptions option, + PaletteInvocationMethod method) { DCHECK_NE(option, PaletteTrayOptions::PALETTE_OPTIONS_COUNT); - if (is_bubble_auto_opened_) { + if (method == PaletteInvocationMethod::SHORTCUT) { + UMA_HISTOGRAM_ENUMERATION("Ash.Shelf.Palette.Usage.Shortcut", option, + PaletteTrayOptions::PALETTE_OPTIONS_COUNT); + } else if (is_bubble_auto_opened_) { UMA_HISTOGRAM_ENUMERATION("Ash.Shelf.Palette.Usage.AutoOpened", option, PaletteTrayOptions::PALETTE_OPTIONS_COUNT); } else { @@ -415,8 +423,10 @@ bool PaletteTray::PerformAction(const ui::Event& event) { if (bubble_) { - if (num_actions_in_bubble_ == 0) - RecordPaletteOptionsUsage(PaletteTrayOptions::PALETTE_CLOSED_NO_ACTION); + if (num_actions_in_bubble_ == 0) { + RecordPaletteOptionsUsage(PaletteTrayOptions::PALETTE_CLOSED_NO_ACTION, + PaletteInvocationMethod::MENU); + } HidePalette(); return true; }
diff --git a/ash/system/palette/palette_tray.h b/ash/system/palette/palette_tray.h index affbfc1..c9b4385 100644 --- a/ash/system/palette/palette_tray.h +++ b/ash/system/palette/palette_tray.h
@@ -92,7 +92,8 @@ // PaletteToolManager::Delegate: void HidePalette() override; void HidePaletteImmediately() override; - void RecordPaletteOptionsUsage(PaletteTrayOptions option) override; + void RecordPaletteOptionsUsage(PaletteTrayOptions option, + PaletteInvocationMethod method) override; void RecordPaletteModeCancellation(PaletteModeCancelType type) override; // Returns true if the palette tray contains the given point. This is useful
diff --git a/ash/system/palette/tools/metalayer_mode.cc b/ash/system/palette/tools/metalayer_mode.cc index 754fe92ba..6e4640f2 100644 --- a/ash/system/palette/tools/metalayer_mode.cc +++ b/ash/system/palette/tools/metalayer_mode.cc
@@ -91,7 +91,8 @@ return; delegate()->RecordPaletteOptionsUsage( - PaletteToolIdToPaletteTrayOptions(GetToolId())); + PaletteToolIdToPaletteTrayOptions(GetToolId()), + PaletteInvocationMethod::SHORTCUT); delegate()->EnableTool(GetToolId()); event->StopPropagation(); }
diff --git a/ash/system/power/tray_power.cc b/ash/system/power/tray_power.cc index cf85c16..0d90316 100644 --- a/ash/system/power/tray_power.cc +++ b/ash/system/power/tray_power.cc
@@ -11,7 +11,6 @@ #include "ash/resources/grit/ash_resources.h" #include "ash/strings/grit/ash_strings.h" #include "ash/system/date/date_view.h" -#include "ash/system/devicetype_utils.h" #include "ash/system/power/battery_notification.h" #include "ash/system/power/dual_role_notification.h" #include "ash/system/system_notifier.h" @@ -25,6 +24,7 @@ #include "base/time/time.h" #include "ui/accessibility/ax_node_data.h" #include "ui/base/resource/resource_bundle.h" +#include "ui/chromeos/devicetype_utils.h" #include "ui/gfx/image/image_skia_source.h" #include "ui/message_center/message_center.h" #include "ui/message_center/notification.h" @@ -224,7 +224,7 @@ std::unique_ptr<Notification> notification(new Notification( message_center::NOTIFICATION_TYPE_SIMPLE, kUsbNotificationId, rb.GetLocalizedString(IDS_ASH_STATUS_TRAY_LOW_POWER_CHARGER_TITLE), - ash::SubstituteChromeOSDeviceType( + ui::SubstituteChromeOSDeviceType( IDS_ASH_STATUS_TRAY_LOW_POWER_CHARGER_MESSAGE_SHORT), rb.GetImageNamed(IDR_AURA_NOTIFICATION_LOW_POWER_CHARGER), base::string16(), GURL(),
diff --git a/ash/system/screen_layout_observer.cc b/ash/system/screen_layout_observer.cc index 2457397..10e43753 100644 --- a/ash/system/screen_layout_observer.cc +++ b/ash/system/screen_layout_observer.cc
@@ -15,7 +15,6 @@ #include "ash/session/session_controller.h" #include "ash/shell.h" #include "ash/strings/grit/ash_strings.h" -#include "ash/system/devicetype_utils.h" #include "ash/system/system_notifier.h" #include "ash/system/tray/system_tray_controller.h" #include "ash/system/tray/tray_constants.h" @@ -25,6 +24,7 @@ #include "base/strings/utf_string_conversions.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h" +#include "ui/chromeos/devicetype_utils.h" #include "ui/display/display.h" #include "ui/display/manager/display_manager.h" #include "ui/display/types/display_constants.h"
diff --git a/ash/system/screen_layout_observer_unittest.cc b/ash/system/screen_layout_observer_unittest.cc index b315d51..769ec11 100644 --- a/ash/system/screen_layout_observer_unittest.cc +++ b/ash/system/screen_layout_observer_unittest.cc
@@ -6,7 +6,6 @@ #include "ash/shell.h" #include "ash/strings/grit/ash_strings.h" -#include "ash/system/devicetype_utils.h" #include "ash/system/tray/system_tray.h" #include "ash/test/ash_test_base.h" #include "ash/wm/tablet_mode/tablet_mode_controller.h" @@ -15,6 +14,7 @@ #include "base/strings/utf_string_conversions.h" #include "ui/accessibility/ax_node_data.h" #include "ui/base/l10n/l10n_util.h" +#include "ui/chromeos/devicetype_utils.h" #include "ui/display/display.h" #include "ui/display/display_layout_builder.h" #include "ui/display/manager/display_manager.h"
diff --git a/ash/system/session/logout_button_tray.cc b/ash/system/session/logout_button_tray.cc index 928cc19..8bf55842 100644 --- a/ash/system/session/logout_button_tray.cc +++ b/ash/system/session/logout_button_tray.cc
@@ -36,7 +36,7 @@ CONTEXT_LAUNCHER_BUTTON)), show_logout_button_in_tray_(false) { DCHECK(shelf); - Shell::Get()->AddShellObserver(this); + Shell::Get()->session_controller()->AddObserver(this); SetLayoutManager(new views::FillLayout); AddChildView(container_); @@ -48,13 +48,15 @@ } LogoutButtonTray::~LogoutButtonTray() { - Shell::Get()->RemoveShellObserver(this); + Shell::Get()->session_controller()->RemoveObserver(this); } // static void LogoutButtonTray::RegisterProfilePrefs(PrefRegistrySimple* registry) { - registry->RegisterBooleanPref(prefs::kShowLogoutButtonInTray, false); - registry->RegisterIntegerPref(prefs::kLogoutDialogDurationMs, 20000); + registry->RegisterBooleanPref(prefs::kShowLogoutButtonInTray, false, + PrefRegistry::PUBLIC); + registry->RegisterIntegerPref(prefs::kLogoutDialogDurationMs, 20000, + PrefRegistry::PUBLIC); } void LogoutButtonTray::UpdateAfterShelfAlignmentChange() { @@ -79,8 +81,6 @@ void LogoutButtonTray::OnActiveUserPrefServiceChanged(PrefService* prefs) { pref_change_registrar_.reset(); - if (!prefs) // Null during startup, user switch and tests. - return; pref_change_registrar_ = base::MakeUnique<PrefChangeRegistrar>(); pref_change_registrar_->Init(prefs); pref_change_registrar_->Add(
diff --git a/ash/system/session/logout_button_tray.h b/ash/system/session/logout_button_tray.h index d80bbc49..8fd0cf9 100644 --- a/ash/system/session/logout_button_tray.h +++ b/ash/system/session/logout_button_tray.h
@@ -8,7 +8,7 @@ #include <memory> #include "ash/ash_export.h" -#include "ash/shell_observer.h" +#include "ash/session/session_observer.h" #include "base/macros.h" #include "base/time/time.h" #include "ui/views/controls/button/button.h" @@ -29,7 +29,7 @@ // kShowLogoutButtonInTray pref. class ASH_EXPORT LogoutButtonTray : public views::View, public views::ButtonListener, - public ShellObserver { + public SessionObserver { public: explicit LogoutButtonTray(Shelf* shelf); ~LogoutButtonTray() override; @@ -45,7 +45,7 @@ // views::ButtonListener: void ButtonPressed(views::Button* sender, const ui::Event& event) override; - // ShellObserver: + // SessionObserver: void OnActiveUserPrefServiceChanged(PrefService* prefs) override; private:
diff --git a/ash/system/session/logout_button_tray_unittest.cc b/ash/system/session/logout_button_tray_unittest.cc index 8f0dc6c3..620084d 100644 --- a/ash/system/session/logout_button_tray_unittest.cc +++ b/ash/system/session/logout_button_tray_unittest.cc
@@ -7,6 +7,7 @@ #include "ash/public/cpp/ash_pref_names.h" #include "ash/public/cpp/config.h" #include "ash/root_window_controller.h" +#include "ash/session/session_controller.h" #include "ash/session/test_session_controller_client.h" #include "ash/shell.h" #include "ash/system/status_area_widget.h" @@ -14,11 +15,13 @@ #include "ash/test/ash_test_helper.h" #include "ash/test_shell_delegate.h" #include "base/macros.h" -#include "components/prefs/testing_pref_service.h" +#include "components/prefs/pref_service.h" namespace ash { namespace { +constexpr char kUserEmail[] = "user1@test.com"; + class LogoutButtonTrayTest : public NoSessionAshTestBase { public: LogoutButtonTrayTest() = default; @@ -27,12 +30,13 @@ // NoSessionAshTestBase: void SetUp() override { NoSessionAshTestBase::SetUp(); - Shell::RegisterProfilePrefs(pref_service_.registry()); - ash_test_helper()->test_shell_delegate()->set_active_user_pref_service( - &pref_service_); + GetSessionControllerClient()->AddUserSession(kUserEmail); } - TestingPrefServiceSimple pref_service_; // Must outlive Shell. + PrefService* pref_service() { + return Shell::Get()->session_controller()->GetUserPrefServiceForUser( + AccountId::FromUserEmail(kUserEmail)); + } private: DISALLOW_COPY_AND_ASSIGN(LogoutButtonTrayTest); @@ -48,13 +52,12 @@ // Button is not visible after simulated login. TestSessionControllerClient* session = GetSessionControllerClient(); - session->AddUserSession("user1@test.com"); session->SetSessionState(session_manager::SessionState::ACTIVE); - session->SwitchActiveUser(AccountId::FromUserEmail("user1@test.com")); + session->SwitchActiveUser(AccountId::FromUserEmail(kUserEmail)); EXPECT_FALSE(button->visible()); // Setting the pref makes the button visible. - pref_service_.SetBoolean(prefs::kShowLogoutButtonInTray, true); + pref_service()->SetBoolean(prefs::kShowLogoutButtonInTray, true); EXPECT_TRUE(button->visible()); // Locking the screen hides the button. @@ -66,7 +69,7 @@ EXPECT_TRUE(button->visible()); // Resetting the pref hides the button. - pref_service_.SetBoolean(prefs::kShowLogoutButtonInTray, false); + pref_service()->SetBoolean(prefs::kShowLogoutButtonInTray, false); EXPECT_FALSE(button->visible()); }
diff --git a/ash/system/tray/system_tray_controller.h b/ash/system/tray/system_tray_controller.h index d1fb062..367e8ec 100644 --- a/ash/system/tray/system_tray_controller.h +++ b/ash/system/tray/system_tray_controller.h
@@ -23,8 +23,7 @@ // // TODO: Consider renaming this to SystemTrayClient or renaming the current // SystemTray to SystemTrayView and making this class SystemTray. -class ASH_EXPORT SystemTrayController - : NON_EXPORTED_BASE(public mojom::SystemTray) { +class ASH_EXPORT SystemTrayController : public mojom::SystemTray { public: SystemTrayController(); ~SystemTrayController() override;
diff --git a/ash/system/tray_caps_lock.cc b/ash/system/tray_caps_lock.cc index 884d327..f90bbb9 100644 --- a/ash/system/tray_caps_lock.cc +++ b/ash/system/tray_caps_lock.cc
@@ -8,6 +8,7 @@ #include "ash/metrics/user_metrics_recorder.h" #include "ash/public/cpp/config.h" #include "ash/resources/vector_icons/vector_icons.h" +#include "ash/session/session_controller.h" #include "ash/shell.h" #include "ash/strings/grit/ash_strings.h" #include "ash/system/system_notifier.h" @@ -56,8 +57,9 @@ } bool IsSearchKeyMappedToCapsLock() { - PrefService* prefs = Shell::Get()->GetActiveUserPrefService(); - // Null in tests and early in mash startup. + PrefService* prefs = + Shell::Get()->session_controller()->GetLastActiveUserPrefService(); + // Null early in mash startup. if (!prefs) return false; // Don't bother to observe for the pref changing because the system tray @@ -201,7 +203,6 @@ // static void TrayCapsLock::RegisterForeignPrefs(PrefRegistrySimple* registry) { - DCHECK_EQ(Shell::GetAshConfig(), Config::MASH); // Pref is owned by chrome and flagged as PUBLIC. registry->RegisterForeignPref(prefs::kLanguageRemapSearchKeyTo); }
diff --git a/ash/system/tray_caps_lock_unittest.cc b/ash/system/tray_caps_lock_unittest.cc index 7c998ac..f98f77e 100644 --- a/ash/system/tray_caps_lock_unittest.cc +++ b/ash/system/tray_caps_lock_unittest.cc
@@ -4,9 +4,14 @@ #include "ash/system/tray_caps_lock.h" +#include "ash/session/session_controller.h" +#include "ash/shell.h" #include "ash/system/tray/system_tray.h" #include "ash/system/tray/system_tray_test_api.h" #include "ash/test/ash_test_base.h" +#include "components/prefs/pref_registry_simple.h" +#include "components/prefs/pref_service.h" +#include "ui/chromeos/events/pref_names.h" namespace ash { namespace { @@ -15,6 +20,17 @@ // Tests that the icon becomes visible when the tray controller toggles it. TEST_F(TrayCapsLockTest, Visibility) { + // prefs::kLanguageRemapSearchKeyTo is owned by chrome and shared with ash + // when it connects. In unit tests, a TestingPrefServiceSimple is used + // instead so only ash-owned prefs are registered by default. Manually + // register prefs::kLanguageRemapSearchKeyTo so TrayCapsLock can be tested. + static_cast<PrefRegistrySimple*>(Shell::Get() + ->session_controller() + ->GetLastActiveUserPrefService() + ->DeprecatedGetPrefRegistry()) + ->RegisterIntegerPref(prefs::kLanguageRemapSearchKeyTo, + chromeos::input_method::kSearchKey); + SystemTray* tray = GetPrimarySystemTray(); TrayCapsLock* caps_lock = SystemTrayTestApi(tray).tray_caps_lock();
diff --git a/ash/test_shell_delegate.cc b/ash/test_shell_delegate.cc index b6920eb..ce3d791 100644 --- a/ash/test_shell_delegate.cc +++ b/ash/test_shell_delegate.cc
@@ -135,10 +135,6 @@ return gfx::Image(); } -PrefService* TestShellDelegate::GetActiveUserPrefService() const { - return active_user_pref_service_; -} - bool TestShellDelegate::IsTouchscreenEnabledInPrefs( bool use_local_state) const { return use_local_state ? touchscreen_enabled_in_local_pref_ : true;
diff --git a/ash/test_shell_delegate.h b/ash/test_shell_delegate.h index ebbe439..87a6b85 100644 --- a/ash/test_shell_delegate.h +++ b/ash/test_shell_delegate.h
@@ -11,8 +11,6 @@ #include "ash/shell_delegate.h" #include "base/macros.h" -class PrefService; - namespace keyboard { class KeyboardUI; } @@ -30,10 +28,6 @@ multi_profiles_enabled_ = multi_profiles_enabled; } - void set_active_user_pref_service(PrefService* pref_service) { - active_user_pref_service_ = pref_service; - } - // Overridden from ShellDelegate: ::service_manager::Connector* GetShellConnector() const override; bool IsIncognitoAllowed() const override; @@ -57,7 +51,6 @@ GPUSupport* CreateGPUSupport() override; base::string16 GetProductName() const override; gfx::Image GetDeprecatedAcceleratorImage() const override; - PrefService* GetActiveUserPrefService() const override; bool IsTouchscreenEnabledInPrefs(bool use_local_state) const override; void SetTouchscreenEnabledInPrefs(bool enabled, bool use_local_state) override; @@ -80,7 +73,6 @@ bool touchscreen_enabled_in_local_pref_ = true; bool media_sessions_suspended_ = false; std::unique_ptr<ShelfInitializer> shelf_initializer_; - PrefService* active_user_pref_service_ = nullptr; // Not owned. DISALLOW_COPY_AND_ASSIGN(TestShellDelegate); };
diff --git a/ash/tray_action/tray_action.h b/ash/tray_action/tray_action.h index 718730a..0a25041 100644 --- a/ash/tray_action/tray_action.h +++ b/ash/tray_action/tray_action.h
@@ -24,7 +24,7 @@ // Currently, only single action is supported - creating new note on the lock // screen - Chrome handles this action by launching an app (if any) that is // registered as a lock screen enabled action handler for the new note action. -class ASH_EXPORT TrayAction : public NON_EXPORTED_BASE(mojom::TrayAction) { +class ASH_EXPORT TrayAction : public mojom::TrayAction { public: TrayAction(); ~TrayAction() override;
diff --git a/ash/wallpaper/wallpaper_controller.h b/ash/wallpaper/wallpaper_controller.h index 955d858..895d8b1 100644 --- a/ash/wallpaper/wallpaper_controller.h +++ b/ash/wallpaper/wallpaper_controller.h
@@ -49,13 +49,13 @@ // hide the user desktop and move it to unlocked container when session // state is ACTIVE; class ASH_EXPORT WallpaperController - : public NON_EXPORTED_BASE(mojom::WallpaperController), + : public mojom::WallpaperController, public WindowTreeHostManager::Observer, public ShellObserver, public wallpaper::WallpaperResizerObserver, public wallpaper::WallpaperColorCalculatorObserver, public SessionObserver, - public NON_EXPORTED_BASE(ui::CompositorLockClient) { + public ui::CompositorLockClient { public: enum WallpaperMode { WALLPAPER_NONE, WALLPAPER_IMAGE };
diff --git a/ash/wm/lock_action_handler_layout_manager.cc b/ash/wm/lock_action_handler_layout_manager.cc index 23f4eec..5ade412 100644 --- a/ash/wm/lock_action_handler_layout_manager.cc +++ b/ash/wm/lock_action_handler_layout_manager.cc
@@ -8,7 +8,6 @@ #include "ash/public/cpp/shell_window_ids.h" #include "ash/public/interfaces/tray_action.mojom.h" -#include "ash/shelf/shelf.h" #include "ash/shell.h" #include "ash/tray_action/tray_action.h" #include "ash/wm/lock_window_state.h" @@ -22,12 +21,9 @@ LockActionHandlerLayoutManager::LockActionHandlerLayoutManager( aura::Window* window, Shelf* shelf) - : LockLayoutManager(window), - shelf_observer_(this), - tray_action_observer_(this) { + : LockLayoutManager(window, shelf), tray_action_observer_(this) { TrayAction* tray_action = Shell::Get()->tray_action(); tray_action_observer_.Add(tray_action); - shelf_observer_.Add(shelf); } LockActionHandlerLayoutManager::~LockActionHandlerLayoutManager() = default; @@ -51,16 +47,6 @@ child->Hide(); } -void LockActionHandlerLayoutManager::WillChangeVisibilityState( - ShelfVisibilityState visibility) { - // Unlike LockLayoutManager, LockActionHandlerLayoutManager windows' bounds - // depend on the user work area bounds defined by shelf layout (see - // ScreenUtil::GetDisplayWorkAreaBoundsInParentForLockScreen) - when shelf - // bounds change, the windows in this layout manager should be updated, too. - const wm::WMEvent event(wm::WM_EVENT_WORKAREA_BOUNDS_CHANGED); - AdjustWindowsForWorkAreaChange(&event); -} - void LockActionHandlerLayoutManager::OnLockScreenNoteStateChanged( mojom::TrayActionState state) { // Make sure the container is properly stacked relative to lock screen
diff --git a/ash/wm/lock_action_handler_layout_manager.h b/ash/wm/lock_action_handler_layout_manager.h index 5ab1388f..7506732c 100644 --- a/ash/wm/lock_action_handler_layout_manager.h +++ b/ash/wm/lock_action_handler_layout_manager.h
@@ -7,7 +7,6 @@ #include "ash/ash_export.h" #include "ash/public/cpp/shelf_types.h" -#include "ash/shelf/shelf_observer.h" #include "ash/tray_action/tray_action_observer.h" #include "ash/wm/lock_layout_manager.h" #include "base/macros.h" @@ -15,8 +14,8 @@ namespace ash { -class TrayAction; class Shelf; +class TrayAction; // Window layout manager for windows intended to handle lock tray actions. // Since "new note" is currently the only supported action, the layout @@ -36,7 +35,6 @@ // Unlike lock layout manager, when maximizing windows, this layout manager will // ensure that the windows do not obscure the system shelf. class ASH_EXPORT LockActionHandlerLayoutManager : public LockLayoutManager, - public ShelfObserver, public TrayActionObserver { public: LockActionHandlerLayoutManager(aura::Window* window, Shelf* shelf); @@ -47,14 +45,10 @@ void OnChildWindowVisibilityChanged(aura::Window* child, bool visibile) override; - // ShelfObserver: - void WillChangeVisibilityState(ShelfVisibilityState visibility) override; - // TrayActionObserver: void OnLockScreenNoteStateChanged(mojom::TrayActionState state) override; private: - ScopedObserver<Shelf, ShelfObserver> shelf_observer_; ScopedObserver<TrayAction, TrayActionObserver> tray_action_observer_; DISALLOW_COPY_AND_ASSIGN(LockActionHandlerLayoutManager);
diff --git a/ash/wm/lock_layout_manager.cc b/ash/wm/lock_layout_manager.cc index e4c2657b..21b5f3b 100644 --- a/ash/wm/lock_layout_manager.cc +++ b/ash/wm/lock_layout_manager.cc
@@ -5,6 +5,7 @@ #include "ash/wm/lock_layout_manager.h" #include "ash/keyboard/keyboard_observer_register.h" +#include "ash/shelf/shelf.h" #include "ash/shell.h" #include "ash/wm/lock_window_state.h" #include "ash/wm/window_state.h" @@ -15,15 +16,17 @@ namespace ash { -LockLayoutManager::LockLayoutManager(aura::Window* window) +LockLayoutManager::LockLayoutManager(aura::Window* window, Shelf* shelf) : wm::WmSnapToPixelLayoutManager(), window_(window), root_window_(window->GetRootWindow()), + shelf_observer_(this), keyboard_observer_(this) { Shell::Get()->AddShellObserver(this); root_window_->AddObserver(this); if (keyboard::KeyboardController::GetInstance()) keyboard_observer_.Add(keyboard::KeyboardController::GetInstance()); + shelf_observer_.Add(shelf); } LockLayoutManager::~LockLayoutManager() { @@ -88,6 +91,20 @@ &keyboard_observer_); } +void LockLayoutManager::WillChangeVisibilityState( + ShelfVisibilityState visibility) { + // This will be called when shelf work area changes. + // * LockLayoutManager windows depend on changes to the accessibility panel + // height. + // * LockActionHandlerLayoutManager windows bounds depend on the work area + // bound defined by the shelf layout (see + // ScreenUtil::GetDisplayWorkAreaBoundsInParentForLockScreen). + // In short, when shelf bounds change, the windows in this layout manager + // should be updated, too. + const wm::WMEvent event(wm::WM_EVENT_WORKAREA_BOUNDS_CHANGED); + AdjustWindowsForWorkAreaChange(&event); +} + void LockLayoutManager::OnKeyboardBoundsChanging(const gfx::Rect& new_bounds) { keyboard_bounds_ = new_bounds; OnWindowResized();
diff --git a/ash/wm/lock_layout_manager.h b/ash/wm/lock_layout_manager.h index 95aeffb..8e46b85 100644 --- a/ash/wm/lock_layout_manager.h +++ b/ash/wm/lock_layout_manager.h
@@ -6,6 +6,7 @@ #define ASH_WM_LOCK_LAYOUT_MANAGER_H_ #include "ash/ash_export.h" +#include "ash/shelf/shelf_observer.h" #include "ash/shell_observer.h" #include "ash/wm/wm_snap_to_pixel_layout_manager.h" #include "ash/wm/wm_types.h" @@ -17,6 +18,9 @@ #include "ui/keyboard/keyboard_controller_observer.h" namespace ash { + +class Shelf; + namespace wm { class WindowState; class WMEvent; @@ -37,9 +41,10 @@ : public wm::WmSnapToPixelLayoutManager, public aura::WindowObserver, public ShellObserver, + public ShelfObserver, public keyboard::KeyboardControllerObserver { public: - explicit LockLayoutManager(aura::Window* window); + LockLayoutManager(aura::Window* window, Shelf* shelf); ~LockLayoutManager() override; // Overridden from WmSnapToPixelLayoutManager: @@ -62,6 +67,9 @@ void OnVirtualKeyboardStateChanged(bool activated, aura::Window* root_window) override; + // ShelfObserver: + void WillChangeVisibilityState(ShelfVisibilityState visibility) override; + // keyboard::KeyboardControllerObserver overrides: void OnKeyboardBoundsChanging(const gfx::Rect& new_bounds) override; void OnKeyboardClosed() override; @@ -78,6 +86,7 @@ aura::Window* window_; aura::Window* root_window_; + ScopedObserver<Shelf, ShelfObserver> shelf_observer_; ScopedObserver<keyboard::KeyboardController, keyboard::KeyboardControllerObserver> keyboard_observer_;
diff --git a/ash/wm/lock_layout_manager_unittest.cc b/ash/wm/lock_layout_manager_unittest.cc index 940f851..2dc89c6d 100644 --- a/ash/wm/lock_layout_manager_unittest.cc +++ b/ash/wm/lock_layout_manager_unittest.cc
@@ -5,6 +5,7 @@ #include "ash/public/cpp/shell_window_ids.h" #include "ash/root_window_controller.h" #include "ash/screen_util.h" +#include "ash/shelf/shelf_layout_manager.h" #include "ash/shell.h" #include "ash/test/ash_test_base.h" #include "ash/wm/window_state.h" @@ -179,6 +180,42 @@ fullscreen_window->GetBoundsInScreen().ToString()); } +TEST_F(LockLayoutManagerTest, AccessibilityPanel) { + ash::ShelfLayoutManager* shelf_layout_manager = + GetPrimaryShelf()->shelf_layout_manager(); + ASSERT_TRUE(shelf_layout_manager); + + // Set the accessibility panel height. + int chromevox_panel_height = 45; + shelf_layout_manager->SetChromeVoxPanelHeight(chromevox_panel_height); + + views::Widget::InitParams widget_params( + views::Widget::InitParams::TYPE_WINDOW_FRAMELESS); + widget_params.show_state = ui::SHOW_STATE_FULLSCREEN; + std::unique_ptr<aura::Window> window( + CreateTestLoginWindow(widget_params, false /* use_delegate */)); + + display::Display primary_display = + display::Screen::GetScreen()->GetPrimaryDisplay(); + + gfx::Rect target_bounds = primary_display.bounds(); + target_bounds.Inset(0 /* left */, chromevox_panel_height /* top */, + 0 /* right */, 0 /* bottom */); + + EXPECT_EQ(target_bounds, window->GetBoundsInScreen()); + + // Update the accessibility panel height, and verify the window bounds are + // updated accordingly. + chromevox_panel_height = 25; + shelf_layout_manager->SetChromeVoxPanelHeight(chromevox_panel_height); + + target_bounds = primary_display.bounds(); + target_bounds.Inset(0 /* left */, chromevox_panel_height /* top */, + 0 /* right */, 0 /* bottom */); + + EXPECT_EQ(target_bounds, window->GetBoundsInScreen()); +} + TEST_F(LockLayoutManagerTest, KeyboardBounds) { display::Display primary_display = display::Screen::GetScreen()->GetPrimaryDisplay(); @@ -291,4 +328,47 @@ EXPECT_EQ(screen_bounds.ToString(), window->GetBoundsInScreen().ToString()); } +TEST_F(LockLayoutManagerTest, AccessibilityPanelWithMultipleMonitors) { + UpdateDisplay("300x400,400x500"); + + ash::ShelfLayoutManager* shelf_layout_manager = + GetPrimaryShelf()->shelf_layout_manager(); + ASSERT_TRUE(shelf_layout_manager); + + int chromevox_panel_height = 45; + shelf_layout_manager->SetChromeVoxPanelHeight(chromevox_panel_height); + + aura::Window::Windows root_windows = Shell::GetAllRootWindows(); + + views::Widget::InitParams widget_params( + views::Widget::InitParams::TYPE_WINDOW_FRAMELESS); + widget_params.show_state = ui::SHOW_STATE_FULLSCREEN; + std::unique_ptr<aura::Window> window( + CreateTestLoginWindow(widget_params, false /* use_delegate */)); + window->SetProperty(aura::client::kResizeBehaviorKey, + ui::mojom::kResizeBehaviorCanMaximize); + + gfx::Rect target_bounds = + display::Screen::GetScreen()->GetPrimaryDisplay().bounds(); + target_bounds.Inset(0, chromevox_panel_height, 0, 0); + EXPECT_EQ(target_bounds, window->GetBoundsInScreen()); + + // Restore window with bounds in the second display, the window should be + // shown in the primary display. + wm::WindowState* window_state = wm::GetWindowState(window.get()); + window_state->SetRestoreBoundsInScreen(gfx::Rect(400, 0, 30, 40)); + + window_state->Restore(); + EXPECT_EQ(root_windows[0], window->GetRootWindow()); + EXPECT_EQ(target_bounds, window->GetBoundsInScreen()); + + // Force the window to secondary display - accessibility panel is only set + // for the primary shelf, so it should not influence the screen bounds. + window->SetBoundsInScreen(gfx::Rect(0, 0, 30, 40), GetSecondaryDisplay()); + + target_bounds = gfx::Rect(300, 0, 400, 500); + EXPECT_EQ(root_windows[1], window->GetRootWindow()); + EXPECT_EQ(target_bounds, window->GetBoundsInScreen()); +} + } // namespace ash
diff --git a/ash/wm/lock_window_state.cc b/ash/wm/lock_window_state.cc index ef1aed1..4a17f478 100644 --- a/ash/wm/lock_window_state.cc +++ b/ash/wm/lock_window_state.cc
@@ -8,6 +8,7 @@ #include <utility> #include "ash/screen_util.h" +#include "ash/shelf/shelf.h" #include "ash/wm/lock_layout_manager.h" #include "ash/wm/window_animation_types.h" #include "ash/wm/window_state.h" @@ -189,7 +190,8 @@ } gfx::Rect bounds = ScreenUtil::GetDisplayBoundsWithShelf(window); - bounds.Inset(0, 0, 0, keyboard_bounds.height()); + bounds.Inset(0, Shelf::ForWindow(window)->GetAccessibilityPanelHeight(), 0, + keyboard_bounds.height()); return bounds; }
diff --git a/ash/wm/overview/overview_window_drag_controller.cc b/ash/wm/overview/overview_window_drag_controller.cc index da677bb..8dff81d 100644 --- a/ash/wm/overview/overview_window_drag_controller.cc +++ b/ash/wm/overview/overview_window_drag_controller.cc
@@ -60,7 +60,7 @@ item_->SetBounds(bounds, OverviewAnimationType::OVERVIEW_ANIMATION_NONE); previous_event_location_ = location_in_screen; - UpdatePhantomWindowAndWindowGrid(location_in_screen); + UpdatePhantomWindow(location_in_screen); } void OverviewWindowDragController::CompleteDrag() { @@ -90,20 +90,10 @@ } } -void OverviewWindowDragController::UpdatePhantomWindowAndWindowGrid( +void OverviewWindowDragController::UpdatePhantomWindow( const gfx::Point& location_in_screen) { SplitViewController::SnapPosition last_snap_position = snap_position_; snap_position_ = GetSnapPosition(location_in_screen); - - // If there is no current snapped window, update the window grid size if the - // dragged window can be snapped if dropped. - if (split_view_controller_->state() == SplitViewController::NO_SNAP && - snap_position_ != last_snap_position) { - // Do not reposition the item that is currently being dragged. - window_selector_->SetBoundsForWindowGridsInScreenIgnoringWindow( - GetGridBounds(snap_position_), item_); - } - if (snap_position_ == SplitViewController::NONE || snap_position_ != last_snap_position) { phantom_window_controller_.reset(); @@ -145,25 +135,6 @@ return SplitViewController::NONE; } -gfx::Rect OverviewWindowDragController::GetGridBounds( - SplitViewController::SnapPosition snap_position) { - aura::Window* pending_snapped_window = item_->GetWindow(); - switch (snap_position) { - case SplitViewController::NONE: - return gfx::Rect(split_view_controller_->GetDisplayWorkAreaBoundsInParent( - pending_snapped_window)); - case SplitViewController::LEFT: - return split_view_controller_->GetSnappedWindowBoundsInScreen( - pending_snapped_window, SplitViewController::RIGHT); - case SplitViewController::RIGHT: - return split_view_controller_->GetSnappedWindowBoundsInScreen( - pending_snapped_window, SplitViewController::LEFT); - } - - NOTREACHED(); - return gfx::Rect(); -} - void OverviewWindowDragController::SnapWindow( SplitViewController::SnapPosition snap_position) { DCHECK_NE(snap_position, SplitViewController::NONE);
diff --git a/ash/wm/overview/overview_window_drag_controller.h b/ash/wm/overview/overview_window_drag_controller.h index 89f8d94..c12fee4 100644 --- a/ash/wm/overview/overview_window_drag_controller.h +++ b/ash/wm/overview/overview_window_drag_controller.h
@@ -34,15 +34,11 @@ WindowSelectorItem* item() { return item_; } private: - // Updates visuals for the user while dragging items around. - void UpdatePhantomWindowAndWindowGrid(const gfx::Point& location_in_screen); + void UpdatePhantomWindow(const gfx::Point& location_in_screen); SplitViewController::SnapPosition GetSnapPosition( const gfx::Point& location_in_screen) const; - // Returns the expected window grid bounds based on |snap_position|. - gfx::Rect GetGridBounds(SplitViewController::SnapPosition snap_position); - void SnapWindow(SplitViewController::SnapPosition snap_position); WindowSelector* window_selector_;
diff --git a/ash/wm/overview/window_grid.cc b/ash/wm/overview/window_grid.cc index 41acb9f..acb22d7 100644 --- a/ash/wm/overview/window_grid.cc +++ b/ash/wm/overview/window_grid.cc
@@ -320,8 +320,7 @@ prepared_for_overview_ = true; } -void WindowGrid::PositionWindows(bool animate, - WindowSelectorItem* ignored_item) { +void WindowGrid::PositionWindows(bool animate) { if (window_selector_->is_shut_down() || window_list_.empty()) return; DCHECK(shield_widget_.get()); @@ -433,19 +432,11 @@ std::min(kMaxHeight + 2 * kWindowMargin, height), &rects, &max_bottom, &min_right, &max_right); } - // Position the windows centering the left-aligned rows vertically. Do not - // position |ignored_item| if it is not nullptr and matches a item in - // |window_list_|. + // Position the windows centering the left-aligned rows vertically. gfx::Vector2d offset(0, (total_bounds.bottom() - max_bottom) / 2); - for (size_t i = 0, j = 0; i < window_list_.size(); ++i, ++j) { - if (ignored_item != nullptr && window_list_[i].get() == ignored_item) { - // Decrement the |rects| index so that after repositioning there will not - // be a gap where the ignored item was supposed to be. - --j; - continue; - } + for (size_t i = 0; i < window_list_.size(); ++i) { window_list_[i]->SetBounds( - rects[j] + offset, + rects[i] + offset, animate ? OverviewAnimationType::OVERVIEW_ANIMATION_LAY_OUT_SELECTOR_ITEMS : OverviewAnimationType::OVERVIEW_ANIMATION_NONE); @@ -573,13 +564,6 @@ PositionWindows(true /* animate */); } -void WindowGrid::SetBoundsAndUpdatePositionsIgnoringWindow( - const gfx::Rect& bounds, - WindowSelectorItem* ignored_item) { - bounds_ = bounds; - PositionWindows(true /* animate */, ignored_item); -} - void WindowGrid::OnWindowDestroying(aura::Window* window) { window_observer_.Remove(window); window_state_observer_.Remove(wm::GetWindowState(window));
diff --git a/ash/wm/overview/window_grid.h b/ash/wm/overview/window_grid.h index 88a4df2..7164cfd 100644 --- a/ash/wm/overview/window_grid.h +++ b/ash/wm/overview/window_grid.h
@@ -76,10 +76,7 @@ // row height which is equivalent assuming fixed height), balanced rows and // minimal wasted space. // Optionally animates the windows to their targets when |animate| is true. - // If |ignored_item| is not null and is an item in |window_list_|, that item - // is not positioned. This is for split screen. - void PositionWindows(bool animate, - WindowSelectorItem* ignored_item = nullptr); + void PositionWindows(bool animate); // Updates |selected_index_| according to the specified |direction| and calls // MoveSelectionWidget(). Returns |true| if the new selection index is out of @@ -109,9 +106,6 @@ // Sets bounds for the window grid and positions all windows in the grid. void SetBoundsAndUpdatePositions(const gfx::Rect& bounds_in_screen); - void SetBoundsAndUpdatePositionsIgnoringWindow( - const gfx::Rect& bounds, - WindowSelectorItem* ignored_item); // Returns true if the grid has no more windows. bool empty() const { return window_list_.empty(); }
diff --git a/ash/wm/overview/window_selector.cc b/ash/wm/overview/window_selector.cc index dcd66afe..a38bd9e 100644 --- a/ash/wm/overview/window_selector.cc +++ b/ash/wm/overview/window_selector.cc
@@ -474,13 +474,6 @@ grid->SetBoundsAndUpdatePositions(bounds); } -void WindowSelector::SetBoundsForWindowGridsInScreenIgnoringWindow( - const gfx::Rect& bounds, - WindowSelectorItem* ignored_item) { - for (std::unique_ptr<WindowGrid>& grid : grid_list_) - grid->SetBoundsAndUpdatePositionsIgnoringWindow(bounds, ignored_item); -} - void WindowSelector::RemoveWindowSelectorItem(WindowSelectorItem* item) { if (item->GetWindow()->HasObserver(this)) { item->GetWindow()->RemoveObserver(this); @@ -720,8 +713,23 @@ ResetFocusRestoreWindow(false); } - if (state == SplitViewController::BOTH_SNAPPED || - state == SplitViewController::NO_SNAP) { + if (state == SplitViewController::LEFT_SNAPPED) { + aura::Window* snapped_window = + Shell::Get()->split_view_controller()->left_window(); + const gfx::Rect bounds_in_screen = + Shell::Get()->split_view_controller()->GetSnappedWindowBoundsInScreen( + snapped_window, SplitViewController::RIGHT); + SetBoundsForWindowGridsInScreen(bounds_in_screen); + } else if (state == SplitViewController::RIGHT_SNAPPED) { + aura::Window* snapped_window = + Shell::Get()->split_view_controller()->right_window(); + const gfx::Rect bounds_in_screen = + Shell::Get()->split_view_controller()->GetSnappedWindowBoundsInScreen( + snapped_window, SplitViewController::LEFT); + SetBoundsForWindowGridsInScreen(bounds_in_screen); + } else { + DCHECK(state == SplitViewController::BOTH_SNAPPED || + state == SplitViewController::NO_SNAP); // If two windows were snapped to both sides of the screen, end overview // mode. If split view mode was ended (e.g., one of the snapped window was // closed or minimized / fullscreened / maximized), also end overview mode
diff --git a/ash/wm/overview/window_selector.h b/ash/wm/overview/window_selector.h index fae4971..8e99394 100644 --- a/ash/wm/overview/window_selector.h +++ b/ash/wm/overview/window_selector.h
@@ -85,9 +85,6 @@ // Called to set bounds for window grids. Used for split view. void SetBoundsForWindowGridsInScreen(const gfx::Rect& bounds); - void SetBoundsForWindowGridsInScreenIgnoringWindow( - const gfx::Rect& bounds, - WindowSelectorItem* ignored_item); // Removes the window selector item from the overview window grid. void RemoveWindowSelectorItem(WindowSelectorItem* item);
diff --git a/ash/wm/overview/window_selector_unittest.cc b/ash/wm/overview/window_selector_unittest.cc index 0ebf5d4e..40c944aa 100644 --- a/ash/wm/overview/window_selector_unittest.cc +++ b/ash/wm/overview/window_selector_unittest.cc
@@ -333,21 +333,6 @@ return window_selector()->text_filter_widget_.get(); } - gfx::Rect GetSplitViewLeftWindowBounds(aura::Window* window) { - return split_view_controller()->GetLeftWindowBoundsInScreen(window); - } - - gfx::Rect GetSplitViewRightWindowBounds(aura::Window* window) { - return split_view_controller()->GetRightWindowBoundsInScreen(window); - } - - gfx::Rect GetGridBounds() { - if (window_selector()) - return window_selector()->grid_list_[0]->bounds_; - - return gfx::Rect(); - } - private: aura::test::TestWindowDelegate delegate_; NonActivatableActivationDelegate non_activatable_activation_delegate_; @@ -1983,78 +1968,4 @@ EXPECT_FALSE(window_selector_controller()->IsSelecting()); } -// Verify the window grid size changes as expected when dragging items around in -// overview mode when split view is enabled. -TEST_F(WindowSelectorTest, WindowGridSizeWhileDraggingWithSplitView) { - // Enable split view, enter maximize mode, add some windows and enter overview - // mode. - base::CommandLine::ForCurrentProcess()->AppendSwitch( - switches::kAshEnableTabletSplitView); - Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(true); - - const gfx::Rect bounds(0, 0, 400, 400); - std::unique_ptr<aura::Window> window1(CreateWindow(bounds)); - std::unique_ptr<aura::Window> window2(CreateWindow(bounds)); - std::unique_ptr<aura::Window> window3(CreateWindow(bounds)); - - ToggleOverview(); - ASSERT_TRUE(window_selector_controller()->IsSelecting()); - - // Select window one and start the drag. - const int grid_index = 0; - const int window_width = - Shell::Get()->GetPrimaryRootWindow()->GetBoundsInScreen().width(); - WindowSelectorItem* selector_item = - GetWindowItemForWindow(grid_index, window1.get()); - gfx::Rect selector_item_bounds = selector_item->target_bounds(); - gfx::Point start_location(selector_item_bounds.CenterPoint()); - window_selector()->InitiateDrag(selector_item, start_location); - - // Verify that when dragged to the left, the window grid is located where the - // right window of split view mode should be. - const gfx::Point left(0, 0); - window_selector()->Drag(selector_item, left); - EXPECT_FALSE(split_view_controller()->IsSplitViewModeActive()); - EXPECT_EQ(SplitViewController::NO_SNAP, split_view_controller()->state()); - EXPECT_TRUE(split_view_controller()->left_window() == nullptr); - EXPECT_EQ(GetSplitViewRightWindowBounds(window1.get()), GetGridBounds()); - - // Verify that when dragged to the right, the window grid is located where the - // left window of split view mode should be. - const gfx::Point right(window_width, 0); - window_selector()->Drag(selector_item, right); - EXPECT_EQ(SplitViewController::NO_SNAP, split_view_controller()->state()); - EXPECT_TRUE(split_view_controller()->right_window() == nullptr); - EXPECT_EQ(GetSplitViewLeftWindowBounds(window1.get()), GetGridBounds()); - - // Verify that when dragged to the center, the window grid is has the - // dimensions of the work area. - const gfx::Point center(window_width / 2, 0); - window_selector()->Drag(selector_item, center); - EXPECT_EQ(SplitViewController::NO_SNAP, split_view_controller()->state()); - EXPECT_EQ( - split_view_controller()->GetDisplayWorkAreaBoundsInScreen(window1.get()), - GetGridBounds()); - - // Snap window1 to the left and initialize dragging for window2. - window_selector()->Drag(selector_item, left); - window_selector()->CompleteDrag(selector_item); - ASSERT_EQ(SplitViewController::LEFT_SNAPPED, - split_view_controller()->state()); - ASSERT_EQ(window1.get(), split_view_controller()->left_window()); - selector_item = GetWindowItemForWindow(grid_index, window2.get()); - selector_item_bounds = selector_item->target_bounds(); - start_location = selector_item_bounds.CenterPoint(); - window_selector()->InitiateDrag(selector_item, start_location); - - // Verify that when there is a snapped window, the window grid bounds remain - // constant despite window selector items being dragged left and right. - window_selector()->Drag(selector_item, left); - EXPECT_EQ(GetSplitViewRightWindowBounds(window1.get()), GetGridBounds()); - window_selector()->Drag(selector_item, right); - EXPECT_EQ(GetSplitViewRightWindowBounds(window1.get()), GetGridBounds()); - window_selector()->Drag(selector_item, center); - EXPECT_EQ(GetSplitViewRightWindowBounds(window1.get()), GetGridBounds()); -} - } // namespace ash
diff --git a/ash/wm/resize_shadow_and_cursor_unittest.cc b/ash/wm/resize_shadow_and_cursor_unittest.cc index 0d2434bc..00d42d07 100644 --- a/ash/wm/resize_shadow_and_cursor_unittest.cc +++ b/ash/wm/resize_shadow_and_cursor_unittest.cc
@@ -242,4 +242,20 @@ EXPECT_EQ(ui::CursorType::kEastResize, GetCurrentCursorType()); } +// Verifies that the shadow hides when a window is minimized. Regression test +// for crbug.com/752583 +TEST_F(ResizeShadowAndCursorTest, Minimize) { + ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow()); + ASSERT_TRUE(ash::wm::GetWindowState(window())->IsNormalStateType()); + + generator.MoveMouseTo(200, 50); + VerifyResizeShadow(true); + + ash::wm::GetWindowState(window())->Minimize(); + VerifyResizeShadow(false); + + ash::wm::GetWindowState(window())->Restore(); + VerifyResizeShadow(false); +} + } // namespace ash
diff --git a/ash/wm/resize_shadow_controller.cc b/ash/wm/resize_shadow_controller.cc index ebef13e..8177347d2 100644 --- a/ash/wm/resize_shadow_controller.cc +++ b/ash/wm/resize_shadow_controller.cc
@@ -41,6 +41,12 @@ window_shadows_.erase(window); } +void ResizeShadowController::OnWindowVisibilityChanging(aura::Window* window, + bool visible) { + if (!visible) + HideShadow(window); +} + ResizeShadow* ResizeShadowController::CreateShadow(aura::Window* window) { auto shadow = base::MakeUnique<ResizeShadow>(window); window->AddObserver(this);
diff --git a/ash/wm/resize_shadow_controller.h b/ash/wm/resize_shadow_controller.h index 31fcf6e..447e80b 100644 --- a/ash/wm/resize_shadow_controller.h +++ b/ash/wm/resize_shadow_controller.h
@@ -37,6 +37,7 @@ // aura::WindowObserver overrides: void OnWindowDestroying(aura::Window* window) override; + void OnWindowVisibilityChanging(aura::Window* window, bool visible) override; private: // Creates a shadow for a given window and returns it. |window_shadows_|
diff --git a/ash/wm/splitview/split_view_controller.h b/ash/wm/splitview/split_view_controller.h index c151e39..4696747 100644 --- a/ash/wm/splitview/split_view_controller.h +++ b/ash/wm/splitview/split_view_controller.h
@@ -22,7 +22,6 @@ class SplitViewControllerTest; class SplitViewDivider; -class WindowSelectorTest; // The controller for the split view. It snaps a window to left/right side of // the screen. It also observes the two snapped windows and decides when to exit @@ -103,7 +102,6 @@ private: friend class SplitViewControllerTest; - friend class WindowSelectorTest; // Ends the split view mode. void EndSplitView();
diff --git a/ash/wm/tablet_mode/tablet_mode_controller.h b/ash/wm/tablet_mode/tablet_mode_controller.h index 6f6f1f5b..9153e4f 100644 --- a/ash/wm/tablet_mode/tablet_mode_controller.h +++ b/ash/wm/tablet_mode/tablet_mode_controller.h
@@ -50,7 +50,7 @@ class ASH_EXPORT TabletModeController : public chromeos::AccelerometerReader::Observer, public chromeos::PowerManagerClient::Observer, - NON_EXPORTED_BASE(public mojom::TouchViewManager), + public mojom::TouchViewManager, public ShellObserver, public WindowTreeHostManager::Observer, public SessionObserver {
diff --git a/ash/wm/workspace/backdrop_controller.cc b/ash/wm/workspace/backdrop_controller.cc index 5b39987..a02c739 100644 --- a/ash/wm/workspace/backdrop_controller.cc +++ b/ash/wm/workspace/backdrop_controller.cc
@@ -9,7 +9,6 @@ #include "ash/public/cpp/shell_window_ids.h" #include "ash/shell.h" #include "ash/system/tray/system_tray_notifier.h" -#include "ash/wm/tablet_mode/tablet_mode_controller.h" #include "ash/wm/window_util.h" #include "ash/wm/workspace/backdrop_delegate.h" #include "base/auto_reset.h" @@ -159,13 +158,9 @@ if (container_->GetRootWindow() != root_window) return; - // Hide or update backdrop only for fullscreen app list in tablet mode. - if (!app_list::features::IsFullscreenAppListEnabled() || - !Shell::Get() - ->tablet_mode_controller() - ->IsTabletModeWindowManagerEnabled()) { + // Hide or update backdrop only for fullscreen app list. + if (!app_list::features::IsFullscreenAppListEnabled()) return; - } if (shown) AddForceHidden();
diff --git a/ash/wm/workspace/workspace_layout_manager_unittest.cc b/ash/wm/workspace/workspace_layout_manager_unittest.cc index db262e1..552dba26 100644 --- a/ash/wm/workspace/workspace_layout_manager_unittest.cc +++ b/ash/wm/workspace/workspace_layout_manager_unittest.cc
@@ -29,7 +29,6 @@ #include "ash/wm/fullscreen_window_finder.h" #include "ash/wm/overview/window_selector_controller.h" #include "ash/wm/tablet_mode/tablet_mode_backdrop_delegate_impl.h" -#include "ash/wm/tablet_mode/tablet_mode_controller.h" #include "ash/wm/window_state.h" #include "ash/wm/window_util.h" #include "ash/wm/wm_event.h" @@ -1386,15 +1385,11 @@ true); EXPECT_TRUE(secondary_test_helper.GetBackdropWindow()); - // Enable tablet mode and fullscreen app list. + // Enable fullscreen app list. base::test::ScopedFeatureList scoped_feature_list; scoped_feature_list.InitAndEnableFeature( app_list::features::kEnableFullscreenAppList); - Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(true); EXPECT_TRUE(app_list::features::IsFullscreenAppListEnabled()); - EXPECT_TRUE(Shell::Get() - ->tablet_mode_controller() - ->IsTabletModeWindowManagerEnabled()); // Show app list in primary display will not hide the backdrop in secondary // display. @@ -1437,16 +1432,12 @@ generator.GestureTapAt(shelf_point); EXPECT_TRUE(test_helper.GetBackdropWindow()); - // Enable tablet mode and fullscreen app list. + // Enable fullscreen app list. base::test::ScopedFeatureList scoped_feature_list; scoped_feature_list.InitAndEnableFeature( app_list::features::kEnableFullscreenAppList); - Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(true); EXPECT_TRUE(test_helper.GetBackdropWindow()); EXPECT_TRUE(app_list::features::IsFullscreenAppListEnabled()); - EXPECT_TRUE(Shell::Get() - ->tablet_mode_controller() - ->IsTabletModeWindowManagerEnabled()); // Show the fullscreen app list should hide the backdrop. app_list_presenter_impl_.Show( display::Screen::GetScreen()->GetPrimaryDisplay().id());
diff --git a/base/BUILD.gn b/base/BUILD.gn index 29b25e24..007232c 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -2413,6 +2413,10 @@ # TODO(krasin): remove CFI_CAST_CHECK, see https://crbug.com/626794. defines += [ "CFI_CAST_CHECK" ] } + + if (use_cfi_diag && !use_cfi_recover) { + defines += [ "CFI_ENFORCEMENT_DIAGNOSTIC" ] + } } action("build_date") {
diff --git a/base/android/java/src/org/chromium/base/process_launcher/ChildProcessConnection.java b/base/android/java/src/org/chromium/base/process_launcher/ChildProcessConnection.java index 9019b2a..61bc3f7 100644 --- a/base/android/java/src/org/chromium/base/process_launcher/ChildProcessConnection.java +++ b/base/android/java/src/org/chromium/base/process_launcher/ChildProcessConnection.java
@@ -228,8 +228,9 @@ // to start() and stop(). private final ChildServiceConnection mWaivedBinding; - // Incremented on addStrongBinding(), decremented on removeStrongBinding(). + // Refcount of bindings. private int mStrongBindingCount; + private int mModerateBindingCount; // Indicates whether the connection only has the waived binding (if the connection is unbound, // it contains the state at time of unbinding). @@ -571,17 +572,6 @@ updateWaivedBoundOnlyState(); } - public void dropOomBindings() { - assert isRunningOnLauncherThread(); - mInitialBinding.unbind(); - - mStrongBindingCount = 0; - mStrongBinding.unbind(); - updateWaivedBoundOnlyState(); - - mModerateBinding.unbind(); - } - public void addStrongBinding() { assert isRunningOnLauncherThread(); if (!isConnected()) { @@ -620,8 +610,11 @@ Log.w(TAG, "The connection is not bound for %d", getPid()); return; } - mModerateBinding.bind(); - updateWaivedBoundOnlyState(); + if (mModerateBindingCount == 0) { + mModerateBinding.bind(); + updateWaivedBoundOnlyState(); + } + mModerateBindingCount++; } public void removeModerateBinding() { @@ -630,8 +623,12 @@ Log.w(TAG, "The connection is not bound for %d", getPid()); return; } - mModerateBinding.unbind(); - updateWaivedBoundOnlyState(); + assert mModerateBindingCount > 0; + mModerateBindingCount--; + if (mModerateBindingCount == 0) { + mModerateBinding.unbind(); + updateWaivedBoundOnlyState(); + } } /**
diff --git a/base/android/jni_generator/SampleForTests_jni.golden b/base/android/jni_generator/SampleForTests_jni.golden index 3ca91eb3..5754e7e 100644 --- a/base/android/jni_generator/SampleForTests_jni.golden +++ b/base/android/jni_generator/SampleForTests_jni.golden
@@ -232,7 +232,7 @@ static base::subtle::AtomicWord g_org_chromium_example_jni_1generator_SampleForTests_javaMethod = 0; static jint Java_SampleForTests_javaMethod(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper foo, + base::android::JavaRef<jobject>& obj, JniIntWrapper foo, JniIntWrapper bar) { CHECK_CLAZZ(env, obj.obj(), org_chromium_example_jni_1generator_SampleForTests_clazz(env), 0); @@ -282,7 +282,7 @@ g_org_chromium_example_jni_1generator_SampleForTests_packagePrivateJavaMethod = 0; static void Java_SampleForTests_packagePrivateJavaMethod(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) { + base::android::JavaRef<jobject>& obj) { CHECK_CLAZZ(env, obj.obj(), org_chromium_example_jni_1generator_SampleForTests_clazz(env)); jmethodID method_id = @@ -304,7 +304,7 @@ g_org_chromium_example_jni_1generator_SampleForTests_methodThatThrowsException = 0; static void Java_SampleForTests_methodThatThrowsException(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) { + base::android::JavaRef<jobject>& obj) { CHECK_CLAZZ(env, obj.obj(), org_chromium_example_jni_1generator_SampleForTests_clazz(env)); jmethodID method_id = @@ -325,7 +325,7 @@ g_org_chromium_example_jni_1generator_SampleForTests_javaMethodWithAnnotatedParam = 0; static void Java_SampleForTests_javaMethodWithAnnotatedParam(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper foo) { + base::android::JavaRef<jobject>& obj, JniIntWrapper foo) { CHECK_CLAZZ(env, obj.obj(), org_chromium_example_jni_1generator_SampleForTests_clazz(env)); jmethodID method_id = @@ -350,7 +350,7 @@ static base::android::ScopedJavaLocalRef<jobject> Java_InnerStructA_create(JNIEnv* env, jlong l, JniIntWrapper i, - const base::android::JavaRefOrBare<jstring>& s) { + const base::android::JavaRef<jstring>& s) { CHECK_CLAZZ(env, org_chromium_example_jni_1generator_SampleForTests_00024InnerStructA_clazz(env), org_chromium_example_jni_1generator_SampleForTests_00024InnerStructA_clazz(env), @@ -379,8 +379,8 @@ static base::subtle::AtomicWord g_org_chromium_example_jni_1generator_SampleForTests_addStructA = 0; static void Java_SampleForTests_addStructA(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, const - base::android::JavaRefOrBare<jobject>& a) { + base::android::JavaRef<jobject>& obj, const base::android::JavaRef<jobject>& + a) { CHECK_CLAZZ(env, obj.obj(), org_chromium_example_jni_1generator_SampleForTests_clazz(env)); jmethodID method_id = @@ -403,7 +403,7 @@ g_org_chromium_example_jni_1generator_SampleForTests_iterateAndDoSomething = 0; static void Java_SampleForTests_iterateAndDoSomething(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) { + base::android::JavaRef<jobject>& obj) { CHECK_CLAZZ(env, obj.obj(), org_chromium_example_jni_1generator_SampleForTests_clazz(env)); jmethodID method_id = @@ -425,7 +425,7 @@ g_org_chromium_example_jni_1generator_SampleForTests_00024InnerStructB_getKey = 0; static jlong Java_InnerStructB_getKey(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) { + base::android::JavaRef<jobject>& obj) { CHECK_CLAZZ(env, obj.obj(), org_chromium_example_jni_1generator_SampleForTests_00024InnerStructB_clazz(env), 0); @@ -452,7 +452,7 @@ = 0; static base::android::ScopedJavaLocalRef<jstring> Java_InnerStructB_getValue(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) { + base::android::JavaRef<jobject>& obj) { CHECK_CLAZZ(env, obj.obj(), org_chromium_example_jni_1generator_SampleForTests_00024InnerStructB_clazz(env), NULL);
diff --git a/base/android/jni_generator/jni_generator.py b/base/android/jni_generator/jni_generator.py index d7f0119..afe6e0c 100755 --- a/base/android/jni_generator/jni_generator.py +++ b/base/android/jni_generator/jni_generator.py
@@ -169,7 +169,7 @@ else: c_type = JavaDataTypeToC(java_type) if re.match(RE_SCOPED_JNI_TYPES, c_type): - return 'const base::android::JavaRefOrBare<' + c_type + '>&' + return 'const base::android::JavaRef<' + c_type + '>&' else: return c_type @@ -1089,7 +1089,7 @@ first_param_in_call = ('%s_clazz(env)' % GetBinaryClassName(java_class)) else: first_param_in_declaration = ( - ', const base::android::JavaRefOrBare<jobject>& obj') + ', const base::android::JavaRef<jobject>& obj') first_param_in_call = 'obj.obj()' params_in_declaration = self.GetCalledByNativeParamsInDeclaration( called_by_native)
diff --git a/base/android/jni_generator/testCalledByNatives.golden b/base/android/jni_generator/testCalledByNatives.golden index 8bc2afa..314614d 100644 --- a/base/android/jni_generator/testCalledByNatives.golden +++ b/base/android/jni_generator/testCalledByNatives.golden
@@ -53,11 +53,11 @@ static base::subtle::AtomicWord g_org_chromium_TestJni_showConfirmInfoBar = 0; static base::android::ScopedJavaLocalRef<jobject> Java_TestJni_showConfirmInfoBar(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper nativeInfoBar, - const base::android::JavaRefOrBare<jstring>& buttonOk, - const base::android::JavaRefOrBare<jstring>& buttonCancel, - const base::android::JavaRefOrBare<jstring>& title, - const base::android::JavaRefOrBare<jobject>& icon) { + base::android::JavaRef<jobject>& obj, JniIntWrapper nativeInfoBar, + const base::android::JavaRef<jstring>& buttonOk, + const base::android::JavaRef<jstring>& buttonCancel, + const base::android::JavaRef<jstring>& title, + const base::android::JavaRef<jobject>& icon) { CHECK_CLAZZ(env, obj.obj(), org_chromium_TestJni_clazz(env), NULL); jmethodID method_id = @@ -86,10 +86,10 @@ static base::subtle::AtomicWord g_org_chromium_TestJni_showAutoLoginInfoBar = 0; static base::android::ScopedJavaLocalRef<jobject> Java_TestJni_showAutoLoginInfoBar(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper nativeInfoBar, - const base::android::JavaRefOrBare<jstring>& realm, - const base::android::JavaRefOrBare<jstring>& account, - const base::android::JavaRefOrBare<jstring>& args) { + base::android::JavaRef<jobject>& obj, JniIntWrapper nativeInfoBar, + const base::android::JavaRef<jstring>& realm, + const base::android::JavaRef<jstring>& account, + const base::android::JavaRef<jstring>& args) { CHECK_CLAZZ(env, obj.obj(), org_chromium_TestJni_clazz(env), NULL); jmethodID method_id = @@ -116,7 +116,7 @@ static base::subtle::AtomicWord g_org_chromium_TestJni_00024InfoBar_dismiss = 0; static void Java_InfoBar_dismiss(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) { + base::android::JavaRef<jobject>& obj) { CHECK_CLAZZ(env, obj.obj(), org_chromium_TestJni_00024InfoBar_clazz(env)); jmethodID method_id = @@ -136,10 +136,10 @@ static base::subtle::AtomicWord g_org_chromium_TestJni_shouldShowAutoLogin = 0; static jboolean Java_TestJni_shouldShowAutoLogin(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& view, - const base::android::JavaRefOrBare<jstring>& realm, - const base::android::JavaRefOrBare<jstring>& account, - const base::android::JavaRefOrBare<jstring>& args) { + base::android::JavaRef<jobject>& view, + const base::android::JavaRef<jstring>& realm, + const base::android::JavaRef<jstring>& account, + const base::android::JavaRef<jstring>& args) { CHECK_CLAZZ(env, org_chromium_TestJni_clazz(env), org_chromium_TestJni_clazz(env), false); jmethodID method_id = @@ -165,7 +165,7 @@ static base::subtle::AtomicWord g_org_chromium_TestJni_openUrl = 0; static base::android::ScopedJavaLocalRef<jobject> Java_TestJni_openUrl(JNIEnv* - env, const base::android::JavaRefOrBare<jstring>& url) { + env, const base::android::JavaRef<jstring>& url) { CHECK_CLAZZ(env, org_chromium_TestJni_clazz(env), org_chromium_TestJni_clazz(env), NULL); jmethodID method_id = @@ -189,7 +189,7 @@ static base::subtle::AtomicWord g_org_chromium_TestJni_activateHardwareAcceleration = 0; static void Java_TestJni_activateHardwareAcceleration(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, jboolean activated, + base::android::JavaRef<jobject>& obj, jboolean activated, JniIntWrapper iPid, JniIntWrapper iType, JniIntWrapper iPrimaryID, @@ -241,7 +241,7 @@ static base::subtle::AtomicWord g_org_chromium_TestJni_uncheckedCall = 0; static void Java_TestJni_uncheckedCall(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper iParam) { + base::android::JavaRef<jobject>& obj, JniIntWrapper iParam) { CHECK_CLAZZ(env, obj.obj(), org_chromium_TestJni_clazz(env)); jmethodID method_id = @@ -262,7 +262,7 @@ static base::subtle::AtomicWord g_org_chromium_TestJni_returnByteArray = 0; static base::android::ScopedJavaLocalRef<jbyteArray> Java_TestJni_returnByteArray(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) { + base::android::JavaRef<jobject>& obj) { CHECK_CLAZZ(env, obj.obj(), org_chromium_TestJni_clazz(env), NULL); jmethodID method_id = @@ -285,7 +285,7 @@ static base::subtle::AtomicWord g_org_chromium_TestJni_returnBooleanArray = 0; static base::android::ScopedJavaLocalRef<jbooleanArray> Java_TestJni_returnBooleanArray(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) { + base::android::JavaRef<jobject>& obj) { CHECK_CLAZZ(env, obj.obj(), org_chromium_TestJni_clazz(env), NULL); jmethodID method_id = @@ -308,7 +308,7 @@ static base::subtle::AtomicWord g_org_chromium_TestJni_returnCharArray = 0; static base::android::ScopedJavaLocalRef<jcharArray> Java_TestJni_returnCharArray(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) { + base::android::JavaRef<jobject>& obj) { CHECK_CLAZZ(env, obj.obj(), org_chromium_TestJni_clazz(env), NULL); jmethodID method_id = @@ -331,7 +331,7 @@ static base::subtle::AtomicWord g_org_chromium_TestJni_returnShortArray = 0; static base::android::ScopedJavaLocalRef<jshortArray> Java_TestJni_returnShortArray(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) { + base::android::JavaRef<jobject>& obj) { CHECK_CLAZZ(env, obj.obj(), org_chromium_TestJni_clazz(env), NULL); jmethodID method_id = @@ -354,7 +354,7 @@ static base::subtle::AtomicWord g_org_chromium_TestJni_returnIntArray = 0; static base::android::ScopedJavaLocalRef<jintArray> Java_TestJni_returnIntArray(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) { + base::android::JavaRef<jobject>& obj) { CHECK_CLAZZ(env, obj.obj(), org_chromium_TestJni_clazz(env), NULL); jmethodID method_id = @@ -377,7 +377,7 @@ static base::subtle::AtomicWord g_org_chromium_TestJni_returnLongArray = 0; static base::android::ScopedJavaLocalRef<jlongArray> Java_TestJni_returnLongArray(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) { + base::android::JavaRef<jobject>& obj) { CHECK_CLAZZ(env, obj.obj(), org_chromium_TestJni_clazz(env), NULL); jmethodID method_id = @@ -400,7 +400,7 @@ static base::subtle::AtomicWord g_org_chromium_TestJni_returnDoubleArray = 0; static base::android::ScopedJavaLocalRef<jdoubleArray> Java_TestJni_returnDoubleArray(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) { + base::android::JavaRef<jobject>& obj) { CHECK_CLAZZ(env, obj.obj(), org_chromium_TestJni_clazz(env), NULL); jmethodID method_id = @@ -423,7 +423,7 @@ static base::subtle::AtomicWord g_org_chromium_TestJni_returnObjectArray = 0; static base::android::ScopedJavaLocalRef<jobjectArray> Java_TestJni_returnObjectArray(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) { + base::android::JavaRef<jobject>& obj) { CHECK_CLAZZ(env, obj.obj(), org_chromium_TestJni_clazz(env), NULL); jmethodID method_id = @@ -447,7 +447,7 @@ 0; static base::android::ScopedJavaLocalRef<jobjectArray> Java_TestJni_returnArrayOfByteArray(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) { + base::android::JavaRef<jobject>& obj) { CHECK_CLAZZ(env, obj.obj(), org_chromium_TestJni_clazz(env), NULL); jmethodID method_id = @@ -470,7 +470,7 @@ static base::subtle::AtomicWord g_org_chromium_TestJni_getCompressFormat = 0; static base::android::ScopedJavaLocalRef<jobject> Java_TestJni_getCompressFormat(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) { + base::android::JavaRef<jobject>& obj) { CHECK_CLAZZ(env, obj.obj(), org_chromium_TestJni_clazz(env), NULL); jmethodID method_id = @@ -494,7 +494,7 @@ 0; static base::android::ScopedJavaLocalRef<jobject> Java_TestJni_getCompressFormatList(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) { + base::android::JavaRef<jobject>& obj) { CHECK_CLAZZ(env, obj.obj(), org_chromium_TestJni_clazz(env), NULL); jmethodID method_id =
diff --git a/base/android/jni_generator/testConstantsFromJavaP.golden b/base/android/jni_generator/testConstantsFromJavaP.golden index 3b8af36..d511200 100644 --- a/base/android/jni_generator/testConstantsFromJavaP.golden +++ b/base/android/jni_generator/testConstantsFromJavaP.golden
@@ -120,9 +120,9 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_finalize = 0; static void Java_MotionEvent_finalize(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) __attribute__ ((unused)); + base::android::JavaRef<jobject>& obj) __attribute__ ((unused)); static void Java_MotionEvent_finalize(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) { + base::android::JavaRef<jobject>& obj) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env)); jmethodID method_id = @@ -147,8 +147,8 @@ jlong p1, JniIntWrapper p2, JniIntWrapper p3, - const base::android::JavaRefOrBare<jobjectArray>& p4, - const base::android::JavaRefOrBare<jobjectArray>& p5, + const base::android::JavaRef<jobjectArray>& p4, + const base::android::JavaRef<jobjectArray>& p5, JniIntWrapper p6, JniIntWrapper p7, jfloat p8, @@ -163,8 +163,8 @@ jlong p1, JniIntWrapper p2, JniIntWrapper p3, - const base::android::JavaRefOrBare<jobjectArray>& p4, - const base::android::JavaRefOrBare<jobjectArray>& p5, + const base::android::JavaRef<jobjectArray>& p4, + const base::android::JavaRef<jobjectArray>& p5, JniIntWrapper p6, JniIntWrapper p7, jfloat p8, @@ -200,8 +200,8 @@ jlong p1, JniIntWrapper p2, JniIntWrapper p3, - const base::android::JavaRefOrBare<jintArray>& p4, - const base::android::JavaRefOrBare<jobjectArray>& p5, + const base::android::JavaRef<jintArray>& p4, + const base::android::JavaRef<jobjectArray>& p5, JniIntWrapper p6, jfloat p7, jfloat p8, @@ -215,8 +215,8 @@ jlong p1, JniIntWrapper p2, JniIntWrapper p3, - const base::android::JavaRefOrBare<jintArray>& p4, - const base::android::JavaRefOrBare<jobjectArray>& p5, + const base::android::JavaRef<jintArray>& p4, + const base::android::JavaRef<jobjectArray>& p5, JniIntWrapper p6, jfloat p7, jfloat p8, @@ -373,10 +373,10 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_obtainAVME_AVME = 0; static base::android::ScopedJavaLocalRef<jobject> Java_MotionEvent_obtainAVME_AVME(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& p0) __attribute__ ((unused)); + base::android::JavaRef<jobject>& p0) __attribute__ ((unused)); static base::android::ScopedJavaLocalRef<jobject> Java_MotionEvent_obtainAVME_AVME(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& p0) { + base::android::JavaRef<jobject>& p0) { CHECK_CLAZZ(env, android_view_MotionEvent_clazz(env), android_view_MotionEvent_clazz(env), NULL); jmethodID method_id = @@ -397,10 +397,10 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_obtainNoHistory = 0; static base::android::ScopedJavaLocalRef<jobject> Java_MotionEvent_obtainNoHistory(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& p0) __attribute__ ((unused)); + base::android::JavaRef<jobject>& p0) __attribute__ ((unused)); static base::android::ScopedJavaLocalRef<jobject> Java_MotionEvent_obtainNoHistory(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& p0) { + base::android::JavaRef<jobject>& p0) { CHECK_CLAZZ(env, android_view_MotionEvent_clazz(env), android_view_MotionEvent_clazz(env), NULL); jmethodID method_id = @@ -420,9 +420,9 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_recycle = 0; static void Java_MotionEvent_recycle(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) __attribute__ ((unused)); + base::android::JavaRef<jobject>& obj) __attribute__ ((unused)); static void Java_MotionEvent_recycle(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) { + base::android::JavaRef<jobject>& obj) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env)); jmethodID method_id = @@ -440,9 +440,9 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_getDeviceId = 0; static jint Java_MotionEvent_getDeviceId(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) __attribute__ ((unused)); + base::android::JavaRef<jobject>& obj) __attribute__ ((unused)); static jint Java_MotionEvent_getDeviceId(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) { + base::android::JavaRef<jobject>& obj) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env), 0); jmethodID method_id = @@ -462,9 +462,9 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_getSource = 0; static jint Java_MotionEvent_getSource(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) __attribute__ ((unused)); + base::android::JavaRef<jobject>& obj) __attribute__ ((unused)); static jint Java_MotionEvent_getSource(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) { + base::android::JavaRef<jobject>& obj) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env), 0); jmethodID method_id = @@ -484,10 +484,10 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_setSource = 0; static void Java_MotionEvent_setSource(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0) __attribute__ + base::android::JavaRef<jobject>& obj, JniIntWrapper p0) __attribute__ ((unused)); static void Java_MotionEvent_setSource(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0) { + base::android::JavaRef<jobject>& obj, JniIntWrapper p0) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env)); jmethodID method_id = @@ -505,9 +505,9 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_getAction = 0; static jint Java_MotionEvent_getAction(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) __attribute__ ((unused)); + base::android::JavaRef<jobject>& obj) __attribute__ ((unused)); static jint Java_MotionEvent_getAction(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) { + base::android::JavaRef<jobject>& obj) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env), 0); jmethodID method_id = @@ -527,9 +527,9 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_getActionMasked = 0; static jint Java_MotionEvent_getActionMasked(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) __attribute__ ((unused)); + base::android::JavaRef<jobject>& obj) __attribute__ ((unused)); static jint Java_MotionEvent_getActionMasked(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) { + base::android::JavaRef<jobject>& obj) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env), 0); jmethodID method_id = @@ -549,9 +549,9 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_getActionIndex = 0; static jint Java_MotionEvent_getActionIndex(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) __attribute__ ((unused)); + base::android::JavaRef<jobject>& obj) __attribute__ ((unused)); static jint Java_MotionEvent_getActionIndex(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) { + base::android::JavaRef<jobject>& obj) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env), 0); jmethodID method_id = @@ -571,9 +571,9 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_getFlags = 0; static jint Java_MotionEvent_getFlags(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) __attribute__ ((unused)); + base::android::JavaRef<jobject>& obj) __attribute__ ((unused)); static jint Java_MotionEvent_getFlags(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) { + base::android::JavaRef<jobject>& obj) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env), 0); jmethodID method_id = @@ -593,9 +593,9 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_getDownTime = 0; static jlong Java_MotionEvent_getDownTime(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) __attribute__ ((unused)); + base::android::JavaRef<jobject>& obj) __attribute__ ((unused)); static jlong Java_MotionEvent_getDownTime(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) { + base::android::JavaRef<jobject>& obj) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env), 0); jmethodID method_id = @@ -615,9 +615,9 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_getEventTime = 0; static jlong Java_MotionEvent_getEventTime(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) __attribute__ ((unused)); + base::android::JavaRef<jobject>& obj) __attribute__ ((unused)); static jlong Java_MotionEvent_getEventTime(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) { + base::android::JavaRef<jobject>& obj) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env), 0); jmethodID method_id = @@ -637,9 +637,9 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_getXF = 0; static jfloat Java_MotionEvent_getXF(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) __attribute__ ((unused)); + base::android::JavaRef<jobject>& obj) __attribute__ ((unused)); static jfloat Java_MotionEvent_getXF(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) { + base::android::JavaRef<jobject>& obj) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env), 0); jmethodID method_id = @@ -659,9 +659,9 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_getYF = 0; static jfloat Java_MotionEvent_getYF(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) __attribute__ ((unused)); + base::android::JavaRef<jobject>& obj) __attribute__ ((unused)); static jfloat Java_MotionEvent_getYF(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) { + base::android::JavaRef<jobject>& obj) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env), 0); jmethodID method_id = @@ -681,9 +681,9 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_getPressureF = 0; static jfloat Java_MotionEvent_getPressureF(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) __attribute__ ((unused)); + base::android::JavaRef<jobject>& obj) __attribute__ ((unused)); static jfloat Java_MotionEvent_getPressureF(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) { + base::android::JavaRef<jobject>& obj) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env), 0); jmethodID method_id = @@ -703,9 +703,9 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_getSizeF = 0; static jfloat Java_MotionEvent_getSizeF(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) __attribute__ ((unused)); + base::android::JavaRef<jobject>& obj) __attribute__ ((unused)); static jfloat Java_MotionEvent_getSizeF(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) { + base::android::JavaRef<jobject>& obj) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env), 0); jmethodID method_id = @@ -725,9 +725,9 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_getTouchMajorF = 0; static jfloat Java_MotionEvent_getTouchMajorF(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) __attribute__ ((unused)); + base::android::JavaRef<jobject>& obj) __attribute__ ((unused)); static jfloat Java_MotionEvent_getTouchMajorF(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) { + base::android::JavaRef<jobject>& obj) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env), 0); jmethodID method_id = @@ -747,9 +747,9 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_getTouchMinorF = 0; static jfloat Java_MotionEvent_getTouchMinorF(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) __attribute__ ((unused)); + base::android::JavaRef<jobject>& obj) __attribute__ ((unused)); static jfloat Java_MotionEvent_getTouchMinorF(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) { + base::android::JavaRef<jobject>& obj) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env), 0); jmethodID method_id = @@ -769,9 +769,9 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_getToolMajorF = 0; static jfloat Java_MotionEvent_getToolMajorF(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) __attribute__ ((unused)); + base::android::JavaRef<jobject>& obj) __attribute__ ((unused)); static jfloat Java_MotionEvent_getToolMajorF(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) { + base::android::JavaRef<jobject>& obj) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env), 0); jmethodID method_id = @@ -791,9 +791,9 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_getToolMinorF = 0; static jfloat Java_MotionEvent_getToolMinorF(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) __attribute__ ((unused)); + base::android::JavaRef<jobject>& obj) __attribute__ ((unused)); static jfloat Java_MotionEvent_getToolMinorF(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) { + base::android::JavaRef<jobject>& obj) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env), 0); jmethodID method_id = @@ -813,9 +813,9 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_getOrientationF = 0; static jfloat Java_MotionEvent_getOrientationF(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) __attribute__ ((unused)); + base::android::JavaRef<jobject>& obj) __attribute__ ((unused)); static jfloat Java_MotionEvent_getOrientationF(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) { + base::android::JavaRef<jobject>& obj) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env), 0); jmethodID method_id = @@ -835,10 +835,10 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_getAxisValueF_I = 0; static jfloat Java_MotionEvent_getAxisValueF_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0) __attribute__ + base::android::JavaRef<jobject>& obj, JniIntWrapper p0) __attribute__ ((unused)); static jfloat Java_MotionEvent_getAxisValueF_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0) { + base::android::JavaRef<jobject>& obj, JniIntWrapper p0) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env), 0); jmethodID method_id = @@ -858,9 +858,9 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_getPointerCount = 0; static jint Java_MotionEvent_getPointerCount(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) __attribute__ ((unused)); + base::android::JavaRef<jobject>& obj) __attribute__ ((unused)); static jint Java_MotionEvent_getPointerCount(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) { + base::android::JavaRef<jobject>& obj) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env), 0); jmethodID method_id = @@ -880,10 +880,10 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_getPointerId = 0; static jint Java_MotionEvent_getPointerId(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0) __attribute__ + base::android::JavaRef<jobject>& obj, JniIntWrapper p0) __attribute__ ((unused)); static jint Java_MotionEvent_getPointerId(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0) { + base::android::JavaRef<jobject>& obj, JniIntWrapper p0) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env), 0); jmethodID method_id = @@ -903,10 +903,10 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_getToolType = 0; static jint Java_MotionEvent_getToolType(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0) __attribute__ + base::android::JavaRef<jobject>& obj, JniIntWrapper p0) __attribute__ ((unused)); static jint Java_MotionEvent_getToolType(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0) { + base::android::JavaRef<jobject>& obj, JniIntWrapper p0) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env), 0); jmethodID method_id = @@ -926,10 +926,10 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_findPointerIndex = 0; static jint Java_MotionEvent_findPointerIndex(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0) __attribute__ + base::android::JavaRef<jobject>& obj, JniIntWrapper p0) __attribute__ ((unused)); static jint Java_MotionEvent_findPointerIndex(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0) { + base::android::JavaRef<jobject>& obj, JniIntWrapper p0) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env), 0); jmethodID method_id = @@ -949,10 +949,10 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_getXF_I = 0; static jfloat Java_MotionEvent_getXF_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0) __attribute__ + base::android::JavaRef<jobject>& obj, JniIntWrapper p0) __attribute__ ((unused)); static jfloat Java_MotionEvent_getXF_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0) { + base::android::JavaRef<jobject>& obj, JniIntWrapper p0) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env), 0); jmethodID method_id = @@ -972,10 +972,10 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_getYF_I = 0; static jfloat Java_MotionEvent_getYF_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0) __attribute__ + base::android::JavaRef<jobject>& obj, JniIntWrapper p0) __attribute__ ((unused)); static jfloat Java_MotionEvent_getYF_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0) { + base::android::JavaRef<jobject>& obj, JniIntWrapper p0) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env), 0); jmethodID method_id = @@ -995,10 +995,10 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_getPressureF_I = 0; static jfloat Java_MotionEvent_getPressureF_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0) __attribute__ + base::android::JavaRef<jobject>& obj, JniIntWrapper p0) __attribute__ ((unused)); static jfloat Java_MotionEvent_getPressureF_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0) { + base::android::JavaRef<jobject>& obj, JniIntWrapper p0) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env), 0); jmethodID method_id = @@ -1018,10 +1018,10 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_getSizeF_I = 0; static jfloat Java_MotionEvent_getSizeF_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0) __attribute__ + base::android::JavaRef<jobject>& obj, JniIntWrapper p0) __attribute__ ((unused)); static jfloat Java_MotionEvent_getSizeF_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0) { + base::android::JavaRef<jobject>& obj, JniIntWrapper p0) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env), 0); jmethodID method_id = @@ -1041,10 +1041,10 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_getTouchMajorF_I = 0; static jfloat Java_MotionEvent_getTouchMajorF_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0) __attribute__ + base::android::JavaRef<jobject>& obj, JniIntWrapper p0) __attribute__ ((unused)); static jfloat Java_MotionEvent_getTouchMajorF_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0) { + base::android::JavaRef<jobject>& obj, JniIntWrapper p0) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env), 0); jmethodID method_id = @@ -1064,10 +1064,10 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_getTouchMinorF_I = 0; static jfloat Java_MotionEvent_getTouchMinorF_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0) __attribute__ + base::android::JavaRef<jobject>& obj, JniIntWrapper p0) __attribute__ ((unused)); static jfloat Java_MotionEvent_getTouchMinorF_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0) { + base::android::JavaRef<jobject>& obj, JniIntWrapper p0) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env), 0); jmethodID method_id = @@ -1087,10 +1087,10 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_getToolMajorF_I = 0; static jfloat Java_MotionEvent_getToolMajorF_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0) __attribute__ + base::android::JavaRef<jobject>& obj, JniIntWrapper p0) __attribute__ ((unused)); static jfloat Java_MotionEvent_getToolMajorF_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0) { + base::android::JavaRef<jobject>& obj, JniIntWrapper p0) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env), 0); jmethodID method_id = @@ -1110,10 +1110,10 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_getToolMinorF_I = 0; static jfloat Java_MotionEvent_getToolMinorF_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0) __attribute__ + base::android::JavaRef<jobject>& obj, JniIntWrapper p0) __attribute__ ((unused)); static jfloat Java_MotionEvent_getToolMinorF_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0) { + base::android::JavaRef<jobject>& obj, JniIntWrapper p0) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env), 0); jmethodID method_id = @@ -1134,10 +1134,10 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_getOrientationF_I = 0; static jfloat Java_MotionEvent_getOrientationF_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0) __attribute__ + base::android::JavaRef<jobject>& obj, JniIntWrapper p0) __attribute__ ((unused)); static jfloat Java_MotionEvent_getOrientationF_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0) { + base::android::JavaRef<jobject>& obj, JniIntWrapper p0) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env), 0); jmethodID method_id = @@ -1158,10 +1158,10 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_getAxisValueF_I_I = 0; static jfloat Java_MotionEvent_getAxisValueF_I_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0, + base::android::JavaRef<jobject>& obj, JniIntWrapper p0, JniIntWrapper p1) __attribute__ ((unused)); static jfloat Java_MotionEvent_getAxisValueF_I_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0, + base::android::JavaRef<jobject>& obj, JniIntWrapper p0, JniIntWrapper p1) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env), 0); @@ -1182,11 +1182,11 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_getPointerCoords = 0; static void Java_MotionEvent_getPointerCoords(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0, - const base::android::JavaRefOrBare<jobject>& p1) __attribute__ ((unused)); + base::android::JavaRef<jobject>& obj, JniIntWrapper p0, + const base::android::JavaRef<jobject>& p1) __attribute__ ((unused)); static void Java_MotionEvent_getPointerCoords(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0, - const base::android::JavaRefOrBare<jobject>& p1) { + base::android::JavaRef<jobject>& obj, JniIntWrapper p0, + const base::android::JavaRef<jobject>& p1) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env)); jmethodID method_id = @@ -1205,11 +1205,11 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_getPointerProperties = 0; static void Java_MotionEvent_getPointerProperties(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0, - const base::android::JavaRefOrBare<jobject>& p1) __attribute__ ((unused)); + base::android::JavaRef<jobject>& obj, JniIntWrapper p0, + const base::android::JavaRef<jobject>& p1) __attribute__ ((unused)); static void Java_MotionEvent_getPointerProperties(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0, - const base::android::JavaRefOrBare<jobject>& p1) { + base::android::JavaRef<jobject>& obj, JniIntWrapper p0, + const base::android::JavaRef<jobject>& p1) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env)); jmethodID method_id = @@ -1227,9 +1227,9 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_getMetaState = 0; static jint Java_MotionEvent_getMetaState(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) __attribute__ ((unused)); + base::android::JavaRef<jobject>& obj) __attribute__ ((unused)); static jint Java_MotionEvent_getMetaState(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) { + base::android::JavaRef<jobject>& obj) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env), 0); jmethodID method_id = @@ -1249,9 +1249,9 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_getButtonState = 0; static jint Java_MotionEvent_getButtonState(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) __attribute__ ((unused)); + base::android::JavaRef<jobject>& obj) __attribute__ ((unused)); static jint Java_MotionEvent_getButtonState(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) { + base::android::JavaRef<jobject>& obj) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env), 0); jmethodID method_id = @@ -1271,9 +1271,9 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_getRawX = 0; static jfloat Java_MotionEvent_getRawX(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) __attribute__ ((unused)); + base::android::JavaRef<jobject>& obj) __attribute__ ((unused)); static jfloat Java_MotionEvent_getRawX(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) { + base::android::JavaRef<jobject>& obj) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env), 0); jmethodID method_id = @@ -1293,9 +1293,9 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_getRawY = 0; static jfloat Java_MotionEvent_getRawY(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) __attribute__ ((unused)); + base::android::JavaRef<jobject>& obj) __attribute__ ((unused)); static jfloat Java_MotionEvent_getRawY(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) { + base::android::JavaRef<jobject>& obj) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env), 0); jmethodID method_id = @@ -1315,9 +1315,9 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_getXPrecision = 0; static jfloat Java_MotionEvent_getXPrecision(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) __attribute__ ((unused)); + base::android::JavaRef<jobject>& obj) __attribute__ ((unused)); static jfloat Java_MotionEvent_getXPrecision(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) { + base::android::JavaRef<jobject>& obj) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env), 0); jmethodID method_id = @@ -1337,9 +1337,9 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_getYPrecision = 0; static jfloat Java_MotionEvent_getYPrecision(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) __attribute__ ((unused)); + base::android::JavaRef<jobject>& obj) __attribute__ ((unused)); static jfloat Java_MotionEvent_getYPrecision(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) { + base::android::JavaRef<jobject>& obj) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env), 0); jmethodID method_id = @@ -1359,9 +1359,9 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_getHistorySize = 0; static jint Java_MotionEvent_getHistorySize(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) __attribute__ ((unused)); + base::android::JavaRef<jobject>& obj) __attribute__ ((unused)); static jint Java_MotionEvent_getHistorySize(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) { + base::android::JavaRef<jobject>& obj) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env), 0); jmethodID method_id = @@ -1382,10 +1382,10 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_getHistoricalEventTime = 0; static jlong Java_MotionEvent_getHistoricalEventTime(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0) __attribute__ + base::android::JavaRef<jobject>& obj, JniIntWrapper p0) __attribute__ ((unused)); static jlong Java_MotionEvent_getHistoricalEventTime(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0) { + base::android::JavaRef<jobject>& obj, JniIntWrapper p0) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env), 0); jmethodID method_id = @@ -1406,10 +1406,10 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_getHistoricalXF_I = 0; static jfloat Java_MotionEvent_getHistoricalXF_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0) __attribute__ + base::android::JavaRef<jobject>& obj, JniIntWrapper p0) __attribute__ ((unused)); static jfloat Java_MotionEvent_getHistoricalXF_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0) { + base::android::JavaRef<jobject>& obj, JniIntWrapper p0) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env), 0); jmethodID method_id = @@ -1430,10 +1430,10 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_getHistoricalYF_I = 0; static jfloat Java_MotionEvent_getHistoricalYF_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0) __attribute__ + base::android::JavaRef<jobject>& obj, JniIntWrapper p0) __attribute__ ((unused)); static jfloat Java_MotionEvent_getHistoricalYF_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0) { + base::android::JavaRef<jobject>& obj, JniIntWrapper p0) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env), 0); jmethodID method_id = @@ -1454,10 +1454,10 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_getHistoricalPressureF_I = 0; static jfloat Java_MotionEvent_getHistoricalPressureF_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0) __attribute__ + base::android::JavaRef<jobject>& obj, JniIntWrapper p0) __attribute__ ((unused)); static jfloat Java_MotionEvent_getHistoricalPressureF_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0) { + base::android::JavaRef<jobject>& obj, JniIntWrapper p0) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env), 0); jmethodID method_id = @@ -1478,10 +1478,10 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_getHistoricalSizeF_I = 0; static jfloat Java_MotionEvent_getHistoricalSizeF_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0) __attribute__ + base::android::JavaRef<jobject>& obj, JniIntWrapper p0) __attribute__ ((unused)); static jfloat Java_MotionEvent_getHistoricalSizeF_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0) { + base::android::JavaRef<jobject>& obj, JniIntWrapper p0) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env), 0); jmethodID method_id = @@ -1502,10 +1502,10 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_getHistoricalTouchMajorF_I = 0; static jfloat Java_MotionEvent_getHistoricalTouchMajorF_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0) __attribute__ + base::android::JavaRef<jobject>& obj, JniIntWrapper p0) __attribute__ ((unused)); static jfloat Java_MotionEvent_getHistoricalTouchMajorF_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0) { + base::android::JavaRef<jobject>& obj, JniIntWrapper p0) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env), 0); jmethodID method_id = @@ -1526,10 +1526,10 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_getHistoricalTouchMinorF_I = 0; static jfloat Java_MotionEvent_getHistoricalTouchMinorF_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0) __attribute__ + base::android::JavaRef<jobject>& obj, JniIntWrapper p0) __attribute__ ((unused)); static jfloat Java_MotionEvent_getHistoricalTouchMinorF_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0) { + base::android::JavaRef<jobject>& obj, JniIntWrapper p0) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env), 0); jmethodID method_id = @@ -1550,10 +1550,10 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_getHistoricalToolMajorF_I = 0; static jfloat Java_MotionEvent_getHistoricalToolMajorF_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0) __attribute__ + base::android::JavaRef<jobject>& obj, JniIntWrapper p0) __attribute__ ((unused)); static jfloat Java_MotionEvent_getHistoricalToolMajorF_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0) { + base::android::JavaRef<jobject>& obj, JniIntWrapper p0) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env), 0); jmethodID method_id = @@ -1574,10 +1574,10 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_getHistoricalToolMinorF_I = 0; static jfloat Java_MotionEvent_getHistoricalToolMinorF_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0) __attribute__ + base::android::JavaRef<jobject>& obj, JniIntWrapper p0) __attribute__ ((unused)); static jfloat Java_MotionEvent_getHistoricalToolMinorF_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0) { + base::android::JavaRef<jobject>& obj, JniIntWrapper p0) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env), 0); jmethodID method_id = @@ -1598,10 +1598,10 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_getHistoricalOrientationF_I = 0; static jfloat Java_MotionEvent_getHistoricalOrientationF_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0) __attribute__ + base::android::JavaRef<jobject>& obj, JniIntWrapper p0) __attribute__ ((unused)); static jfloat Java_MotionEvent_getHistoricalOrientationF_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0) { + base::android::JavaRef<jobject>& obj, JniIntWrapper p0) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env), 0); jmethodID method_id = @@ -1622,10 +1622,10 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_getHistoricalAxisValueF_I_I = 0; static jfloat Java_MotionEvent_getHistoricalAxisValueF_I_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0, + base::android::JavaRef<jobject>& obj, JniIntWrapper p0, JniIntWrapper p1) __attribute__ ((unused)); static jfloat Java_MotionEvent_getHistoricalAxisValueF_I_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0, + base::android::JavaRef<jobject>& obj, JniIntWrapper p0, JniIntWrapper p1) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env), 0); @@ -1647,10 +1647,10 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_getHistoricalXF_I_I = 0; static jfloat Java_MotionEvent_getHistoricalXF_I_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0, + base::android::JavaRef<jobject>& obj, JniIntWrapper p0, JniIntWrapper p1) __attribute__ ((unused)); static jfloat Java_MotionEvent_getHistoricalXF_I_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0, + base::android::JavaRef<jobject>& obj, JniIntWrapper p0, JniIntWrapper p1) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env), 0); @@ -1672,10 +1672,10 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_getHistoricalYF_I_I = 0; static jfloat Java_MotionEvent_getHistoricalYF_I_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0, + base::android::JavaRef<jobject>& obj, JniIntWrapper p0, JniIntWrapper p1) __attribute__ ((unused)); static jfloat Java_MotionEvent_getHistoricalYF_I_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0, + base::android::JavaRef<jobject>& obj, JniIntWrapper p0, JniIntWrapper p1) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env), 0); @@ -1697,10 +1697,10 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_getHistoricalPressureF_I_I = 0; static jfloat Java_MotionEvent_getHistoricalPressureF_I_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0, + base::android::JavaRef<jobject>& obj, JniIntWrapper p0, JniIntWrapper p1) __attribute__ ((unused)); static jfloat Java_MotionEvent_getHistoricalPressureF_I_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0, + base::android::JavaRef<jobject>& obj, JniIntWrapper p0, JniIntWrapper p1) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env), 0); @@ -1722,10 +1722,10 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_getHistoricalSizeF_I_I = 0; static jfloat Java_MotionEvent_getHistoricalSizeF_I_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0, + base::android::JavaRef<jobject>& obj, JniIntWrapper p0, JniIntWrapper p1) __attribute__ ((unused)); static jfloat Java_MotionEvent_getHistoricalSizeF_I_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0, + base::android::JavaRef<jobject>& obj, JniIntWrapper p0, JniIntWrapper p1) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env), 0); @@ -1747,10 +1747,10 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_getHistoricalTouchMajorF_I_I = 0; static jfloat Java_MotionEvent_getHistoricalTouchMajorF_I_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0, + base::android::JavaRef<jobject>& obj, JniIntWrapper p0, JniIntWrapper p1) __attribute__ ((unused)); static jfloat Java_MotionEvent_getHistoricalTouchMajorF_I_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0, + base::android::JavaRef<jobject>& obj, JniIntWrapper p0, JniIntWrapper p1) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env), 0); @@ -1772,10 +1772,10 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_getHistoricalTouchMinorF_I_I = 0; static jfloat Java_MotionEvent_getHistoricalTouchMinorF_I_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0, + base::android::JavaRef<jobject>& obj, JniIntWrapper p0, JniIntWrapper p1) __attribute__ ((unused)); static jfloat Java_MotionEvent_getHistoricalTouchMinorF_I_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0, + base::android::JavaRef<jobject>& obj, JniIntWrapper p0, JniIntWrapper p1) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env), 0); @@ -1797,10 +1797,10 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_getHistoricalToolMajorF_I_I = 0; static jfloat Java_MotionEvent_getHistoricalToolMajorF_I_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0, + base::android::JavaRef<jobject>& obj, JniIntWrapper p0, JniIntWrapper p1) __attribute__ ((unused)); static jfloat Java_MotionEvent_getHistoricalToolMajorF_I_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0, + base::android::JavaRef<jobject>& obj, JniIntWrapper p0, JniIntWrapper p1) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env), 0); @@ -1822,10 +1822,10 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_getHistoricalToolMinorF_I_I = 0; static jfloat Java_MotionEvent_getHistoricalToolMinorF_I_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0, + base::android::JavaRef<jobject>& obj, JniIntWrapper p0, JniIntWrapper p1) __attribute__ ((unused)); static jfloat Java_MotionEvent_getHistoricalToolMinorF_I_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0, + base::android::JavaRef<jobject>& obj, JniIntWrapper p0, JniIntWrapper p1) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env), 0); @@ -1847,10 +1847,10 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_getHistoricalOrientationF_I_I = 0; static jfloat Java_MotionEvent_getHistoricalOrientationF_I_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0, + base::android::JavaRef<jobject>& obj, JniIntWrapper p0, JniIntWrapper p1) __attribute__ ((unused)); static jfloat Java_MotionEvent_getHistoricalOrientationF_I_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0, + base::android::JavaRef<jobject>& obj, JniIntWrapper p0, JniIntWrapper p1) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env), 0); @@ -1872,11 +1872,11 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_getHistoricalAxisValueF_I_I_I = 0; static jfloat Java_MotionEvent_getHistoricalAxisValueF_I_I_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0, + base::android::JavaRef<jobject>& obj, JniIntWrapper p0, JniIntWrapper p1, JniIntWrapper p2) __attribute__ ((unused)); static jfloat Java_MotionEvent_getHistoricalAxisValueF_I_I_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0, + base::android::JavaRef<jobject>& obj, JniIntWrapper p0, JniIntWrapper p1, JniIntWrapper p2) { CHECK_CLAZZ(env, obj.obj(), @@ -1899,13 +1899,13 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_getHistoricalPointerCoords = 0; static void Java_MotionEvent_getHistoricalPointerCoords(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0, + base::android::JavaRef<jobject>& obj, JniIntWrapper p0, JniIntWrapper p1, - const base::android::JavaRefOrBare<jobject>& p2) __attribute__ ((unused)); + const base::android::JavaRef<jobject>& p2) __attribute__ ((unused)); static void Java_MotionEvent_getHistoricalPointerCoords(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0, + base::android::JavaRef<jobject>& obj, JniIntWrapper p0, JniIntWrapper p1, - const base::android::JavaRefOrBare<jobject>& p2) { + const base::android::JavaRef<jobject>& p2) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env)); jmethodID method_id = @@ -1923,9 +1923,9 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_getEdgeFlags = 0; static jint Java_MotionEvent_getEdgeFlags(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) __attribute__ ((unused)); + base::android::JavaRef<jobject>& obj) __attribute__ ((unused)); static jint Java_MotionEvent_getEdgeFlags(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) { + base::android::JavaRef<jobject>& obj) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env), 0); jmethodID method_id = @@ -1945,10 +1945,10 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_setEdgeFlags = 0; static void Java_MotionEvent_setEdgeFlags(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0) __attribute__ + base::android::JavaRef<jobject>& obj, JniIntWrapper p0) __attribute__ ((unused)); static void Java_MotionEvent_setEdgeFlags(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0) { + base::android::JavaRef<jobject>& obj, JniIntWrapper p0) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env)); jmethodID method_id = @@ -1966,10 +1966,10 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_setAction = 0; static void Java_MotionEvent_setAction(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0) __attribute__ + base::android::JavaRef<jobject>& obj, JniIntWrapper p0) __attribute__ ((unused)); static void Java_MotionEvent_setAction(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0) { + base::android::JavaRef<jobject>& obj, JniIntWrapper p0) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env)); jmethodID method_id = @@ -1987,10 +1987,10 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_offsetLocation = 0; static void Java_MotionEvent_offsetLocation(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, jfloat p0, + base::android::JavaRef<jobject>& obj, jfloat p0, jfloat p1) __attribute__ ((unused)); static void Java_MotionEvent_offsetLocation(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, jfloat p0, + base::android::JavaRef<jobject>& obj, jfloat p0, jfloat p1) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env)); @@ -2009,10 +2009,10 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_setLocation = 0; static void Java_MotionEvent_setLocation(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, jfloat p0, + base::android::JavaRef<jobject>& obj, jfloat p0, jfloat p1) __attribute__ ((unused)); static void Java_MotionEvent_setLocation(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, jfloat p0, + base::android::JavaRef<jobject>& obj, jfloat p0, jfloat p1) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env)); @@ -2031,11 +2031,11 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_transform = 0; static void Java_MotionEvent_transform(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, const - base::android::JavaRefOrBare<jobject>& p0) __attribute__ ((unused)); + base::android::JavaRef<jobject>& obj, const base::android::JavaRef<jobject>& + p0) __attribute__ ((unused)); static void Java_MotionEvent_transform(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, const - base::android::JavaRefOrBare<jobject>& p0) { + base::android::JavaRef<jobject>& obj, const base::android::JavaRef<jobject>& + p0) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env)); jmethodID method_id = @@ -2054,14 +2054,14 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_addBatchV_J_F_F_F_F_I = 0; static void Java_MotionEvent_addBatchV_J_F_F_F_F_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, jlong p0, + base::android::JavaRef<jobject>& obj, jlong p0, jfloat p1, jfloat p2, jfloat p3, jfloat p4, JniIntWrapper p5) __attribute__ ((unused)); static void Java_MotionEvent_addBatchV_J_F_F_F_F_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, jlong p0, + base::android::JavaRef<jobject>& obj, jlong p0, jfloat p1, jfloat p2, jfloat p3, @@ -2085,12 +2085,12 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_addBatchV_J_LAVMEPC_I = 0; static void Java_MotionEvent_addBatchV_J_LAVMEPC_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, jlong p0, - const base::android::JavaRefOrBare<jobjectArray>& p1, + base::android::JavaRef<jobject>& obj, jlong p0, + const base::android::JavaRef<jobjectArray>& p1, JniIntWrapper p2) __attribute__ ((unused)); static void Java_MotionEvent_addBatchV_J_LAVMEPC_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, jlong p0, - const base::android::JavaRefOrBare<jobjectArray>& p1, + base::android::JavaRef<jobject>& obj, jlong p0, + const base::android::JavaRef<jobjectArray>& p1, JniIntWrapper p2) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env)); @@ -2110,10 +2110,10 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_toString = 0; static base::android::ScopedJavaLocalRef<jstring> Java_MotionEvent_toString(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) __attribute__ ((unused)); + base::android::JavaRef<jobject>& obj) __attribute__ ((unused)); static base::android::ScopedJavaLocalRef<jstring> Java_MotionEvent_toString(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) { + base::android::JavaRef<jobject>& obj) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env), NULL); jmethodID method_id = @@ -2179,9 +2179,9 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_axisFromString = 0; static jint Java_MotionEvent_axisFromString(JNIEnv* env, const - base::android::JavaRefOrBare<jstring>& p0) __attribute__ ((unused)); + base::android::JavaRef<jstring>& p0) __attribute__ ((unused)); static jint Java_MotionEvent_axisFromString(JNIEnv* env, const - base::android::JavaRefOrBare<jstring>& p0) { + base::android::JavaRef<jstring>& p0) { CHECK_CLAZZ(env, android_view_MotionEvent_clazz(env), android_view_MotionEvent_clazz(env), 0); jmethodID method_id = @@ -2201,12 +2201,12 @@ static base::subtle::AtomicWord g_android_view_MotionEvent_writeToParcel = 0; static void Java_MotionEvent_writeToParcel(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, const - base::android::JavaRefOrBare<jobject>& p0, + base::android::JavaRef<jobject>& obj, const base::android::JavaRef<jobject>& + p0, JniIntWrapper p1) __attribute__ ((unused)); static void Java_MotionEvent_writeToParcel(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, const - base::android::JavaRefOrBare<jobject>& p0, + base::android::JavaRef<jobject>& obj, const base::android::JavaRef<jobject>& + p0, JniIntWrapper p1) { CHECK_CLAZZ(env, obj.obj(), android_view_MotionEvent_clazz(env));
diff --git a/base/android/jni_generator/testFromJavaP.golden b/base/android/jni_generator/testFromJavaP.golden index 214c6c6..85d81852 100644 --- a/base/android/jni_generator/testFromJavaP.golden +++ b/base/android/jni_generator/testFromJavaP.golden
@@ -37,9 +37,9 @@ static base::subtle::AtomicWord g_java_io_InputStream_available = 0; static jint Java_InputStream_available(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) __attribute__ ((unused)); + base::android::JavaRef<jobject>& obj) __attribute__ ((unused)); static jint Java_InputStream_available(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) { + base::android::JavaRef<jobject>& obj) { CHECK_CLAZZ(env, obj.obj(), java_io_InputStream_clazz(env), 0); jmethodID method_id = @@ -59,9 +59,9 @@ static base::subtle::AtomicWord g_java_io_InputStream_close = 0; static void Java_InputStream_close(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) __attribute__ ((unused)); + base::android::JavaRef<jobject>& obj) __attribute__ ((unused)); static void Java_InputStream_close(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) { + base::android::JavaRef<jobject>& obj) { CHECK_CLAZZ(env, obj.obj(), java_io_InputStream_clazz(env)); jmethodID method_id = @@ -79,10 +79,10 @@ static base::subtle::AtomicWord g_java_io_InputStream_mark = 0; static void Java_InputStream_mark(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0) __attribute__ + base::android::JavaRef<jobject>& obj, JniIntWrapper p0) __attribute__ ((unused)); static void Java_InputStream_mark(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper p0) { + base::android::JavaRef<jobject>& obj, JniIntWrapper p0) { CHECK_CLAZZ(env, obj.obj(), java_io_InputStream_clazz(env)); jmethodID method_id = @@ -100,9 +100,9 @@ static base::subtle::AtomicWord g_java_io_InputStream_markSupported = 0; static jboolean Java_InputStream_markSupported(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) __attribute__ ((unused)); + base::android::JavaRef<jobject>& obj) __attribute__ ((unused)); static jboolean Java_InputStream_markSupported(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) { + base::android::JavaRef<jobject>& obj) { CHECK_CLAZZ(env, obj.obj(), java_io_InputStream_clazz(env), false); jmethodID method_id = @@ -122,9 +122,9 @@ static base::subtle::AtomicWord g_java_io_InputStream_readI = 0; static jint Java_InputStream_readI(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) __attribute__ ((unused)); + base::android::JavaRef<jobject>& obj) __attribute__ ((unused)); static jint Java_InputStream_readI(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) { + base::android::JavaRef<jobject>& obj) { CHECK_CLAZZ(env, obj.obj(), java_io_InputStream_clazz(env), 0); jmethodID method_id = @@ -144,11 +144,11 @@ static base::subtle::AtomicWord g_java_io_InputStream_readI_AB = 0; static jint Java_InputStream_readI_AB(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, const - base::android::JavaRefOrBare<jbyteArray>& p0) __attribute__ ((unused)); + base::android::JavaRef<jobject>& obj, const + base::android::JavaRef<jbyteArray>& p0) __attribute__ ((unused)); static jint Java_InputStream_readI_AB(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, const - base::android::JavaRefOrBare<jbyteArray>& p0) { + base::android::JavaRef<jobject>& obj, const + base::android::JavaRef<jbyteArray>& p0) { CHECK_CLAZZ(env, obj.obj(), java_io_InputStream_clazz(env), 0); jmethodID method_id = @@ -168,13 +168,13 @@ static base::subtle::AtomicWord g_java_io_InputStream_readI_AB_I_I = 0; static jint Java_InputStream_readI_AB_I_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, const - base::android::JavaRefOrBare<jbyteArray>& p0, + base::android::JavaRef<jobject>& obj, const + base::android::JavaRef<jbyteArray>& p0, JniIntWrapper p1, JniIntWrapper p2) __attribute__ ((unused)); static jint Java_InputStream_readI_AB_I_I(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, const - base::android::JavaRefOrBare<jbyteArray>& p0, + base::android::JavaRef<jobject>& obj, const + base::android::JavaRef<jbyteArray>& p0, JniIntWrapper p1, JniIntWrapper p2) { CHECK_CLAZZ(env, obj.obj(), @@ -196,9 +196,9 @@ static base::subtle::AtomicWord g_java_io_InputStream_reset = 0; static void Java_InputStream_reset(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) __attribute__ ((unused)); + base::android::JavaRef<jobject>& obj) __attribute__ ((unused)); static void Java_InputStream_reset(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) { + base::android::JavaRef<jobject>& obj) { CHECK_CLAZZ(env, obj.obj(), java_io_InputStream_clazz(env)); jmethodID method_id = @@ -216,10 +216,9 @@ static base::subtle::AtomicWord g_java_io_InputStream_skip = 0; static jlong Java_InputStream_skip(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, jlong p0) __attribute__ - ((unused)); + base::android::JavaRef<jobject>& obj, jlong p0) __attribute__ ((unused)); static jlong Java_InputStream_skip(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, jlong p0) { + base::android::JavaRef<jobject>& obj, jlong p0) { CHECK_CLAZZ(env, obj.obj(), java_io_InputStream_clazz(env), 0); jmethodID method_id =
diff --git a/base/android/jni_generator/testFromJavaPGenerics.golden b/base/android/jni_generator/testFromJavaPGenerics.golden index 6d46a932..f0c19b3 100644 --- a/base/android/jni_generator/testFromJavaPGenerics.golden +++ b/base/android/jni_generator/testFromJavaPGenerics.golden
@@ -36,9 +36,9 @@ static base::subtle::AtomicWord g_java_util_HashSet_dummy = 0; static void Java_HashSet_dummy(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) __attribute__ ((unused)); + base::android::JavaRef<jobject>& obj) __attribute__ ((unused)); static void Java_HashSet_dummy(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj) { + base::android::JavaRef<jobject>& obj) { CHECK_CLAZZ(env, obj.obj(), java_util_HashSet_clazz(env)); jmethodID method_id =
diff --git a/base/android/jni_generator/testMultipleJNIAdditionalImport.golden b/base/android/jni_generator/testMultipleJNIAdditionalImport.golden index da0605f..c29e542c 100644 --- a/base/android/jni_generator/testMultipleJNIAdditionalImport.golden +++ b/base/android/jni_generator/testMultipleJNIAdditionalImport.golden
@@ -49,8 +49,8 @@ static base::subtle::AtomicWord g_org_chromium_foo_Foo_calledByNative = 0; static void Java_Foo_calledByNative(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& callback1, - const base::android::JavaRefOrBare<jobject>& callback2) { + base::android::JavaRef<jobject>& callback1, + const base::android::JavaRef<jobject>& callback2) { CHECK_CLAZZ(env, org_chromium_foo_Foo_clazz(env), org_chromium_foo_Foo_clazz(env)); jmethodID method_id =
diff --git a/base/android/jni_generator/testNativeExportsOnlyOption.golden b/base/android/jni_generator/testNativeExportsOnlyOption.golden index c15c816..d4d7569 100644 --- a/base/android/jni_generator/testNativeExportsOnlyOption.golden +++ b/base/android/jni_generator/testNativeExportsOnlyOption.golden
@@ -122,7 +122,7 @@ g_org_chromium_example_jni_1generator_SampleForTests_testMethodWithParam = 0; static void Java_SampleForTests_testMethodWithParam(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper iParam) { + base::android::JavaRef<jobject>& obj, JniIntWrapper iParam) { CHECK_CLAZZ(env, obj.obj(), org_chromium_example_jni_1generator_SampleForTests_clazz(env)); jmethodID method_id = @@ -146,7 +146,7 @@ = 0; static base::android::ScopedJavaLocalRef<jstring> Java_SampleForTests_testMethodWithParamAndReturn(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper iParam) { + base::android::JavaRef<jobject>& obj, JniIntWrapper iParam) { CHECK_CLAZZ(env, obj.obj(), org_chromium_example_jni_1generator_SampleForTests_clazz(env), NULL); jmethodID method_id =
diff --git a/base/android/jni_generator/testSingleJNIAdditionalImport.golden b/base/android/jni_generator/testSingleJNIAdditionalImport.golden index 4d0e38b..75295ba3 100644 --- a/base/android/jni_generator/testSingleJNIAdditionalImport.golden +++ b/base/android/jni_generator/testSingleJNIAdditionalImport.golden
@@ -46,7 +46,7 @@ static base::subtle::AtomicWord g_org_chromium_foo_Foo_calledByNative = 0; static void Java_Foo_calledByNative(JNIEnv* env, const - base::android::JavaRefOrBare<jobject>& callback) { + base::android::JavaRef<jobject>& callback) { CHECK_CLAZZ(env, org_chromium_foo_Foo_clazz(env), org_chromium_foo_Foo_clazz(env)); jmethodID method_id =
diff --git a/base/android/scoped_java_ref.h b/base/android/scoped_java_ref.h index 12d418de..1ff0229 100644 --- a/base/android/scoped_java_ref.h +++ b/base/android/scoped_java_ref.h
@@ -279,24 +279,6 @@ } }; -// Temporary type for parameters to Java functions, to allow incremental -// migration from bare jobject to JavaRef. Don't use outside JNI generator. -template <typename T> -class JavaRefOrBare { - public: - JavaRefOrBare(std::nullptr_t) : obj_(nullptr) {} - JavaRefOrBare(const JavaRef<T>& ref) : obj_(ref.obj()) {} - // TODO(torne): this is no longer permitted; remove the entire class and just - // use JavaRef once this removal sticks. - // JavaRefOrBare(T obj) : obj_(obj) {} - T obj() const { return obj_; } - - private: - T obj_; - - DISALLOW_COPY_AND_ASSIGN(JavaRefOrBare); -}; - } // namespace android } // namespace base
diff --git a/base/containers/span.h b/base/containers/span.h index 9b55740..c5f82ce0 100644 --- a/base/containers/span.h +++ b/base/containers/span.h
@@ -7,6 +7,8 @@ #include <stddef.h> +#include <algorithm> + namespace base { // A Span represents an array of elements of type T. It consists of a pointer to @@ -20,30 +22,73 @@ // TODO(https://crbug.com/754077): Document differences from the working group // proposal: http://open-std.org/JTC1/SC22/WG21/docs/papers/2016/p0122r1.pdf. // TODO(https://crbug.com/754077): Implement more Span support, such as -// initialization from containers and iterators and document why this is useful -// (greater safety since no need to manually pass in data + size) +// initialization from containers, and document why this is useful (greater +// safety since no need to manually pass in data + size) template <typename T> class Span { public: + using element_type = T; + using pointer = T*; + using reference = T&; + using iterator = T*; + using const_iterator = const T*; + // TODO(dcheng): What about reverse iterators? + constexpr Span() noexcept : data_(nullptr), size_(0) {} constexpr Span(T* data, size_t size) noexcept : data_(data), size_(size) {} template <size_t N> constexpr Span(T (&array)[N]) noexcept : data_(array), size_(N) {} - constexpr T* data() const noexcept { return data_; } - constexpr size_t size() const noexcept { return size_; } - + // Span subviews constexpr Span subspan(size_t pos, size_t count) const { // Note: ideally this would DCHECK, but it requires fairly horrible // contortions. return Span(data_ + pos, count); } + // Span observers + constexpr size_t size() const noexcept { return size_; } + + // Span element access + constexpr T& operator[](size_t index) const noexcept { return data_[index]; } + constexpr T* data() const noexcept { return data_; } + + // Span iterator support + iterator begin() const noexcept { return data_; } + iterator end() const noexcept { return data_ + size_; } + + const_iterator cbegin() const noexcept { return begin(); } + const_iterator cend() const noexcept { return end(); } + private: T* data_; size_t size_; }; +// Relational operators. Equality is a element-wise comparison. +template <typename T> +constexpr bool operator==(const Span<T>& lhs, const Span<T>& rhs) noexcept { + return std::equal(lhs.cbegin(), lhs.cend(), rhs.cbegin(), rhs.cend()); +} + +template <typename T> +constexpr bool operator!=(const Span<T>& lhs, const Span<T>& rhs) noexcept { + return !(lhs == rhs); +} + +// TODO(dcheng): Implement other relational operators. + +// Type-deducing helpers for constructing a Span. +template <typename T> +constexpr Span<T> MakeSpan(T* data, size_t size) noexcept { + return Span<T>(data, size); +} + +template <typename T, size_t N> +constexpr Span<T> MakeSpan(T (&array)[N]) noexcept { + return Span<T>(array); +} + } // namespace base #endif // BASE_SPAN_H_
diff --git a/base/containers/span_unittest.cc b/base/containers/span_unittest.cc index f7e60fa..f45f533 100644 --- a/base/containers/span_unittest.cc +++ b/base/containers/span_unittest.cc
@@ -7,8 +7,11 @@ #include <vector> #include "base/macros.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +using ::testing::ElementsAre; + namespace base { // TODO(dcheng): Add tests for initializer list, containers, etc. @@ -20,9 +23,8 @@ EXPECT_EQ(vector.data(), span.data()); EXPECT_EQ(vector.size(), span.size()); - // TODO(dcheng): Use operator[] when implemented. for (size_t i = 0; i < span.size(); ++i) - EXPECT_EQ(vector[i], span.data()[i]); + EXPECT_EQ(vector[i], span[i]); } TEST(SpanTest, ConstructFromConstexprArray) { @@ -32,9 +34,8 @@ EXPECT_EQ(kArray, span.data()); EXPECT_EQ(arraysize(kArray), span.size()); - // TODO(dcheng): Use operator[] when implemented. for (size_t i = 0; i < span.size(); ++i) - EXPECT_EQ(kArray[i], span.data()[i]); + EXPECT_EQ(kArray[i], span[i]); } TEST(SpanTest, ConstructFromArray) { @@ -43,16 +44,14 @@ Span<const int> const_span(array); EXPECT_EQ(array, const_span.data()); EXPECT_EQ(arraysize(array), const_span.size()); - // TODO(dcheng): Use operator[] when implemented. for (size_t i = 0; i < const_span.size(); ++i) - EXPECT_EQ(array[i], const_span.data()[i]); + EXPECT_EQ(array[i], const_span[i]); Span<int> span(array); EXPECT_EQ(array, span.data()); EXPECT_EQ(arraysize(array), span.size()); - // TODO(dcheng): Use operator[] when implemented. for (size_t i = 0; i < span.size(); ++i) - EXPECT_EQ(array[i], span.data()[i]); + EXPECT_EQ(array[i], span[i]); } TEST(SpanTest, Subspan) { @@ -81,47 +80,97 @@ auto subspan = span.subspan(0, 1); EXPECT_EQ(span.data(), subspan.data()); EXPECT_EQ(1u, subspan.size()); - EXPECT_EQ(1, subspan.data()[0]); + EXPECT_EQ(1, subspan[0]); } { auto subspan = span.subspan(1, 1); EXPECT_EQ(span.data() + 1, subspan.data()); EXPECT_EQ(1u, subspan.size()); - EXPECT_EQ(2, subspan.data()[0]); + EXPECT_EQ(2, subspan[0]); } { auto subspan = span.subspan(2, 1); EXPECT_EQ(span.data() + 2, subspan.data()); EXPECT_EQ(1u, subspan.size()); - EXPECT_EQ(3, subspan.data()[0]); + EXPECT_EQ(3, subspan[0]); } { auto subspan = span.subspan(0, 2); EXPECT_EQ(span.data(), subspan.data()); EXPECT_EQ(2u, subspan.size()); - EXPECT_EQ(1, subspan.data()[0]); - EXPECT_EQ(2, subspan.data()[1]); + EXPECT_EQ(1, subspan[0]); + EXPECT_EQ(2, subspan[1]); } { auto subspan = span.subspan(1, 2); EXPECT_EQ(span.data() + 1, subspan.data()); EXPECT_EQ(2u, subspan.size()); - EXPECT_EQ(2, subspan.data()[0]); - EXPECT_EQ(3, subspan.data()[1]); + EXPECT_EQ(2, subspan[0]); + EXPECT_EQ(3, subspan[1]); } { auto subspan = span.subspan(0, 3); EXPECT_EQ(span.data(), subspan.data()); EXPECT_EQ(span.size(), subspan.size()); - EXPECT_EQ(1, subspan.data()[0]); - EXPECT_EQ(2, subspan.data()[1]); - EXPECT_EQ(3, subspan.data()[2]); + EXPECT_EQ(1, subspan[0]); + EXPECT_EQ(2, subspan[1]); + EXPECT_EQ(3, subspan[2]); } } +TEST(SpanTest, Iterator) { + static constexpr int kArray[] = {1, 6, 1, 8, 0}; + constexpr Span<const int> span(kArray); + + std::vector<int> results; + for (int i : span) + results.emplace_back(i); + EXPECT_THAT(results, ElementsAre(1, 6, 1, 8, 0)); +} + +TEST(SpanTest, Equality) { + static constexpr int kArray1[] = {3, 1, 4, 1, 5}; + static constexpr int kArray2[] = {3, 1, 4, 1, 5}; + constexpr Span<const int> span1(kArray1); + constexpr Span<const int> span2(kArray2); + + EXPECT_EQ(span1, span2); + + static constexpr int kArray3[] = {2, 7, 1, 8, 3}; + constexpr Span<const int> span3(kArray3); + + EXPECT_FALSE(span1 == span3); +} + +TEST(SpanTest, Inequality) { + static constexpr int kArray1[] = {2, 3, 5, 7, 11}; + static constexpr int kArray2[] = {1, 4, 6, 8, 9}; + constexpr Span<const int> span1(kArray1); + constexpr Span<const int> span2(kArray2); + + EXPECT_NE(span1, span2); + + static constexpr int kArray3[] = {2, 3, 5, 7, 11}; + constexpr Span<const int> span3(kArray3); + + EXPECT_FALSE(span1 != span3); +} + +TEST(SpanTest, MakeSpanFromDataAndSize) { + std::vector<int> vector = {1, 1, 2, 3, 5, 8}; + Span<int> span(vector.data(), vector.size()); + EXPECT_EQ(span, MakeSpan(vector.data(), vector.size())); +} + +TEST(SpanTest, MakeSpanFromConstexprArray) { + static constexpr int kArray[] = {1, 2, 3, 4, 5}; + constexpr Span<const int> span(kArray); + EXPECT_EQ(span, MakeSpan(kArray)); +} + } // namespace base
diff --git a/base/debug/stack_trace_posix.cc b/base/debug/stack_trace_posix.cc index 7696be8..db32e5b 100644 --- a/base/debug/stack_trace_posix.cc +++ b/base/debug/stack_trace_posix.cc
@@ -311,7 +311,7 @@ } PrintToStderr("\n"); -#if defined(CFI_ENFORCEMENT) +#if defined(CFI_ENFORCEMENT_TRAP) if (signal == SIGILL && info->si_code == ILL_ILLOPN) { PrintToStderr( "CFI: Most likely a control flow integrity violation; for more "
diff --git a/base/memory/ptr_util.h b/base/memory/ptr_util.h index 8747ac9..8a2d487 100644 --- a/base/memory/ptr_util.h +++ b/base/memory/ptr_util.h
@@ -18,57 +18,13 @@ return std::unique_ptr<T>(ptr); } -namespace internal { - -template <typename T> -struct MakeUniqueResult { - using Scalar = std::unique_ptr<T>; -}; - -template <typename T> -struct MakeUniqueResult<T[]> { - using Array = std::unique_ptr<T[]>; -}; - -template <typename T, size_t N> -struct MakeUniqueResult<T[N]> { - using Invalid = void; -}; - -} // namespace internal - -// Helper to construct an object wrapped in a std::unique_ptr. This is an -// implementation of C++14's std::make_unique that can be used in Chrome. -// -// MakeUnique<T>(args) should be preferred over WrapUnique(new T(args)): bare -// calls to `new` should be treated with scrutiny. -// -// Usage: -// // ptr is a std::unique_ptr<std::string> -// auto ptr = MakeUnique<std::string>("hello world!"); -// -// // arr is a std::unique_ptr<int[]> -// auto arr = MakeUnique<int[]>(5); - -// Overload for non-array types. Arguments are forwarded to T's constructor. +// TODO(crbug.com/755727): Inline all uses. template <typename T, typename... Args> -typename internal::MakeUniqueResult<T>::Scalar MakeUnique(Args&&... args) { - return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); +auto MakeUnique(Args&&... args) + -> decltype(std::make_unique<T>(std::forward<Args>(args)...)) { + return std::make_unique<T>(std::forward<Args>(args)...); } -// Overload for array types of unknown bound, e.g. T[]. The array is allocated -// with `new T[n]()` and value-initialized: note that this is distinct from -// `new T[n]`, which default-initializes. -template <typename T> -typename internal::MakeUniqueResult<T>::Array MakeUnique(size_t size) { - return std::unique_ptr<T>(new typename std::remove_extent<T>::type[size]()); -} - -// Overload to reject array types of known bound, e.g. T[n]. -template <typename T, typename... Args> -typename internal::MakeUniqueResult<T>::Invalid MakeUnique(Args&&... args) = - delete; - } // namespace base #endif // BASE_MEMORY_PTR_UTIL_H_
diff --git a/base/message_loop/message_pump_fuchsia.cc b/base/message_loop/message_pump_fuchsia.cc index 4199ffc..e2aa37bc 100644 --- a/base/message_loop/message_pump_fuchsia.cc +++ b/base/message_loop/message_pump_fuchsia.cc
@@ -32,9 +32,13 @@ was_stopped_ = nullptr; } - // If the pump is gone, or we haven't begun waiting, then there is nothing - // to cancel. - if (!weak_pump_ || !has_begun_) + if (!has_begun_) + return true; + + has_begun_ = false; + + // If the pump is gone then there is nothing to cancel. + if (!weak_pump_) return true; int result = mx_port_cancel(weak_pump_->port_.get(), handle_, wait_key()); @@ -42,8 +46,6 @@ << "mx_port_cancel(handle=" << handle_ << ") failed: " << mx_status_get_string(result); - has_begun_ = false; - return result == MX_OK; } @@ -233,9 +235,11 @@ const mx_status_t wait_status = mx_port_wait(port_.get(), deadline, &packet, 0); - if (wait_status != MX_OK && wait_status != MX_ERR_TIMED_OUT) { - NOTREACHED() << "unexpected wait status: " - << mx_status_get_string(wait_status); + if (wait_status != MX_OK) { + if (wait_status != MX_ERR_TIMED_OUT) { + NOTREACHED() << "unexpected wait status: " + << mx_status_get_string(wait_status); + } continue; }
diff --git a/base/metrics/histogram.cc b/base/metrics/histogram.cc index 7cdddcd..93456e25 100644 --- a/base/metrics/histogram.cc +++ b/base/metrics/histogram.cc
@@ -555,6 +555,7 @@ kHistogramNameField, kFlagsField, kLoggedBucketRangesField, + kDummyField, }; uint32_t bad_fields = 0; @@ -572,6 +573,8 @@ bad_fields |= 1 << kHistogramNameField; if (flags() == 0) bad_fields |= 1 << kFlagsField; + if (dummy_ != kDummyValue) + bad_fields |= 1 << kDummyField; const bool is_valid = (bad_fields & ~(1 << kFlagsField)) == 0; if (is_valid || !crash_if_invalid) @@ -585,7 +588,7 @@ // Temporary for https://crbug.com/736675. base::debug::ScopedCrashKey crash_key("bad_histogram", debug_string); #endif - // CHECK(false) << debug_string; + CHECK(false) << debug_string; debug::Alias(&bad_fields); return false; }
diff --git a/base/numerics/README.md b/base/numerics/README.md index 297d114..5d7df89 100644 --- a/base/numerics/README.md +++ b/base/numerics/README.md
@@ -1,8 +1,9 @@ # `base/numerics` This directory contains a dependency-free, header-only library of templates -providing well-defined semantics for safely handling a variety of numeric -operations, including most common arithmetic operations and conversions. +providing well-defined semantics for safely and performantly handling a variety +of numeric operations, including most common arithmetic operations and +conversions. The public API is broken out into the following header files: @@ -28,6 +29,129 @@ [TOC] +## Common patterns and use-cases + +The following covers the preferred style for the most common uses of this +library. Please don't cargo-cult from anywhere else. 😉 + +### Performing checked arithmetic conversions + +The `checked_cast` template converts between arbitrary arithmetic types, and is +used for cases where a conversion failure should result in program termination: + +```cpp +// Crash if signed_value is out of range for buff_size. +size_t buff_size = checked_cast<size_t>(signed_value); +``` + +### Performing saturated (clamped) arithmetic conversions + +The `saturated_cast` template converts between arbitrary arithmetic types, and +is used in cases where an out-of-bounds source value should be saturated to the +corresponding maximum or minimum of the destination type: + +```cpp +// Convert from float with saturation to INT_MAX, INT_MIN, or 0 for NaN. +int int_value = saturated_cast<int>(floating_point_value); +``` + +### Enforcing arithmetic conversions at compile-time + +The `strict_cast` enforces type restrictions at compile-time and results in +emitted code that is identical to a normal `static_cast`. However, a +`strict_cast` assignment will fail to compile if the destination type cannot +represent the full range of the source type: + +```cpp +// Throw a compiler error if byte_value is changed to an out-of-range-type. +int int_value = saturated_cast<int>(byte_value); +``` + +You can also enforce these compile-time restrictions on function parameters by +using the `StrictNumeric` template: + +```cpp +// Throw a compiler error if the size argument cannot be represented by a +// size_t (e.g. passing an int will fail to compile). +bool AllocateBuffer(void** buffer, StrictCast<size_t> size); +``` + +### Comparing values between arbitrary arithmetic types + +Both the `StrictNumeric` and `ClampedNumeric` types provide well defined +comparisons between arbitrary arithmetic types. This allows you to perform +comparisons that are not legal or would trigger compiler warnings or errors +under the normal arithmetic promotion rules: + +```cpp +bool foo(unsigned value, int upper_bound) { + // Converting to StrictNumeric allows this comparison to work correctly. + if (MakeStrictNum(value) >= upper_bound) + return false; +``` + +*** note +**Warning:** Do not perform manual conversions using the comparison operators. +Instead, use the cast templates described in the previous sections, or the +constexpr template functions `IsValueInRangeForNumericType` and +`IsTypeInRangeForNumericType`, as these templates properly handle the full range +of corner cases and employ various optimizations. +*** + +### Calculating a buffer size (checked arithmetic) + +When making exact calculations—such as for buffer lengths—it's often necessary +to know when those calculations trigger an overflow, undefined behavior, or +other boundary conditions. The `CheckedNumeric` template does this by storing +a bit determining whether or not some arithmetic operation has occured that +would put the variable in an "invalid" state. Attempting to extract the value +from a variable in an invalid state will trigger a check/trap condition, that +by default will result in process termination. + +Here's an example of a buffer calculation using a `CheckedNumeric` type (note: +the AssignIfValid method will trigger a compile error if the result is ignored). + +```cpp +// Calculate the buffer size and detect if an overflow occurs. +size_t size; +if (!CheckAdd(kHeaderSize, CheckMul(count, kItemSize)).AssignIfValid(&size)) { + // Handle an overflow error... +} +``` + +### Calculating clamped coordinates (non-sticky saturating arithmetic) + +Certain classes of calculations—such as coordinate calculations—require +well-defined semantics that always produce a valid result on boundary +conditions. The `ClampedNumeric` template addresses this by providing +performant, non-sticky saturating arithmetic operations. + +Here's an example of using a `ClampedNumeric` to calculate an operation +insetting a rectangle. + +```cpp +// Use clamped arithmetic since inset calculations might overflow. +void Rect::Inset(int left, int top, int right, int bottom) { + origin_ += Vector2d(left, top); + set_width(ClampSub(width(), ClampAdd(left, right))); + set_height(ClampSub(height(), ClampAdd(top, bottom))); +} +``` + +*** note +The `ClampedNumeric` type is not "sticky", which means the saturation is not +retained across individual operations. As such, one arithmetic operation may +result in a saturated value, while the next operation may then "desaturate" +the value. Here's an example: + +```cpp +ClampedNumeric<int> value = INT_MAX; +++value; // value is still INT_MAX, due to saturation. +--value; // value is now (INT_MAX - 1), because saturation is not sticky. +``` + +*** + ## Conversion functions and StrictNumeric<> in safe_conversions.h This header includes a collection of helper `constexpr` templates for safely @@ -89,10 +213,13 @@ The `CheckedNumeric` type implicitly converts from floating point and integer data types, and contains overloads for basic arithmetic operations (i.e.: `+`, `-`, `*`, `/` for all types and `%`, `<<`, `>>`, `&`, `|`, `^` for integers). -However, *the variadic template functions are the prefered API,* as they remove -type ambiguities and help prevent a number of common errors. The variadic -functions can also be more performant, as the eliminate redundant expressions that are unavoidable with the with the operator overloads. (Ideally the compiler should -optimize those away, but better to avoid them in the first place.) +However, *the [variadic template functions +](#CheckedNumeric_in-checked_math_h-Non_member-helper-functions) +are the prefered API,* as they remove type ambiguities and help prevent a number +of common errors. The variadic functions can also be more performant, as they +eliminate redundant expressions that are unavoidable with the with the operator +overloads. (Ideally the compiler should optimize those away, but better to avoid +them in the first place.) Type promotions are a slightly modified version of the [standard C/C++ numeric promotions @@ -198,8 +325,10 @@ and integer data types, saturating on assignment as appropriate. It contains overloads for basic arithmetic operations (i.e.: `+`, `-`, `*`, `/` for all types and `%`, `<<`, `>>`, `&`, `|`, `^` for integers) along with comparison -operators for arithmetic types of any size. However, *the variadic template -functions are the prefered API,* as they remove type ambiguities and help prevent +operators for arithmetic types of any size. However, *the [variadic template +functions +](#ClampedNumeric_in-clamped_math_h-Non_member-helper-functions) +are the prefered API,* as they remove type ambiguities and help prevent a number of common errors. The variadic functions can also be more performant, as they eliminate redundant expressions that are unavoidable with the operator overloads. (Ideally the compiler should optimize those away, but better to avoid
diff --git a/base/process/process_util_unittest.cc b/base/process/process_util_unittest.cc index a8d7777..accdbf89 100644 --- a/base/process/process_util_unittest.cc +++ b/base/process/process_util_unittest.cc
@@ -486,7 +486,7 @@ base::WaitableEvent event(base::win::ScopedHandle( CreateEvent(&security_attributes, true, false, NULL))); base::LaunchOptions options; - options.handles_to_inherit.push_back(event.handle()); + options.handles_to_inherit.emplace_back(event.handle()); base::CommandLine cmd_line = MakeCmdLine("TriggerEventChildProcess"); cmd_line.AppendSwitchASCII( @@ -624,7 +624,7 @@ NOTREACHED(); base::LaunchOptions options; - options.fds_to_remap.push_back(std::pair<int, int>(fds[1], kChildPipe)); + options.fds_to_remap.emplace_back(fds[1], kChildPipe); base::SpawnChildResult spawn_child = SpawnChildWithOptions("ProcessUtilsLeakFDChildProcess", options); CHECK(spawn_child.process.IsValid()); @@ -710,7 +710,7 @@ // Launch the test process, which should inherit our pipe stdio. base::LaunchOptions options; - options.fds_to_remap.push_back(std::pair<int, int>(dev_null, dev_null)); + options.fds_to_remap.emplace_back(dev_null, dev_null); base::SpawnChildResult spawn_child = SpawnChildWithOptions("ProcessUtilsVerifyStdio", options); ASSERT_TRUE(spawn_child.process.IsValid()); @@ -813,7 +813,7 @@ options.wait = true; options.environ = env_changes; options.clear_environ = clear_environ; - options.fds_to_remap.push_back(std::make_pair(fds[1], 1)); + options.fds_to_remap.emplace_back(fds[1], 1); #if defined(OS_LINUX) options.clone_flags = clone_flags; #else @@ -844,12 +844,12 @@ TEST_F(ProcessUtilTest, LaunchProcess) { base::EnvironmentMap env_changes; std::vector<std::string> echo_base_test; - echo_base_test.push_back(kShellPath); - echo_base_test.push_back("-c"); - echo_base_test.push_back("echo $BASE_TEST"); + echo_base_test.emplace_back(kShellPath); + echo_base_test.emplace_back("-c"); + echo_base_test.emplace_back("echo $BASE_TEST"); std::vector<std::string> print_env; - print_env.push_back("/usr/bin/env"); + print_env.emplace_back("/usr/bin/env"); const int no_clone_flags = 0; const bool no_clear_environ = false; @@ -916,15 +916,15 @@ std::vector<std::string> argv; #if defined(OS_FUCHSIA) // There's no sh in PATH on Fuchsia by default, so provide a full path to sh. - argv.push_back("/boot/bin/sh"); + argv.emplace_back("/boot/bin/sh"); #elif defined(OS_ANDROID) - argv.push_back("sh"); // Instead of /bin/sh, force path search to find it. + argv.emplace_back("sh"); // Instead of /bin/sh, force path search to find it. #else #error Port. #endif - argv.push_back("-c"); + argv.emplace_back("-c"); - argv.push_back("exit 0"); + argv.emplace_back("exit 0"); EXPECT_TRUE(base::GetAppOutput(base::CommandLine(argv), &output)); EXPECT_STREQ("", output.c_str()); @@ -944,9 +944,9 @@ &output)); std::vector<std::string> argv; - argv.push_back("/bin/echo"); - argv.push_back("-n"); - argv.push_back("foobar42"); + argv.emplace_back("/bin/echo"); + argv.emplace_back("-n"); + argv.emplace_back("foobar42"); EXPECT_TRUE(base::GetAppOutput(base::CommandLine(argv), &output)); EXPECT_STREQ("foobar42", output.c_str()); #endif // defined(OS_ANDROID) @@ -957,9 +957,9 @@ std::vector<std::string> argv; std::string output; int exit_code; - argv.push_back(std::string(kShellPath)); // argv[0] - argv.push_back("-c"); // argv[1] - argv.push_back("echo foo"); // argv[2]; + argv.emplace_back(kShellPath); // argv[0] + argv.emplace_back("-c"); // argv[1] + argv.emplace_back("echo foo"); // argv[2]; EXPECT_TRUE(base::GetAppOutputWithExitCode(base::CommandLine(argv), &output, &exit_code)); EXPECT_STREQ("foo\n", output.c_str()); @@ -1067,7 +1067,7 @@ ReadFromPipeDelegate read_from_pipe_delegate(read_fd.get()); base::LaunchOptions options; - options.fds_to_remap.push_back(std::make_pair(read_fd.get(), read_fd.get())); + options.fds_to_remap.emplace_back(read_fd.get(), read_fd.get()); options.pre_exec_delegate = &read_from_pipe_delegate; base::SpawnChildResult spawn_child = SpawnChildWithOptions("SimpleChildProcess", options);
diff --git a/base/tools_sanity_unittest.cc b/base/tools_sanity_unittest.cc index 9075d16..940d02d 100644 --- a/base/tools_sanity_unittest.cc +++ b/base/tools_sanity_unittest.cc
@@ -342,23 +342,13 @@ EXPECT_EQ(kMagicValue, shared); } -#if defined(CFI_ENFORCEMENT) -// TODO(krasin): remove CFI_CAST_CHECK, see https://crbug.com/626794. -#if defined(CFI_CAST_CHECK) -TEST(ToolsSanityTest, BadCast) { - class A { - virtual void f() {} - }; +#if defined(CFI_ENFORCEMENT_TRAP) +#define CFI_ERROR_MSG "ILL_ILLOPN" +#elif defined(CFI_ENFORCEMENT_DIAGNOSTIC) +#define CFI_ERROR_MSG "runtime error: control flow integrity check" +#endif // CFI_ENFORCEMENT_TRAP || CFI_ENFORCEMENT_DIAGNOSTIC - class B { - virtual void f() {} - }; - - A a; - EXPECT_DEATH((void)(B*)&a, "ILL_ILLOPN"); -} -#endif // CFI_CAST_CHECK - +#if defined(CFI_ERROR_MSG) class A { public: A(): n_(0) {} @@ -372,17 +362,56 @@ void f() override { n_--; } }; +class C: public B { + public: + void f() override { n_ += 2; } +}; + NOINLINE void KillVptrAndCall(A *obj) { *reinterpret_cast<void **>(obj) = 0; obj->f(); } -TEST(ToolsSanityTest, BadVirtualCall) { +TEST(ToolsSanityTest, BadVirtualCallNull) { A a; B b; - EXPECT_DEATH({ KillVptrAndCall(&a); KillVptrAndCall(&b); }, "ILL_ILLOPN"); + EXPECT_DEATH({ KillVptrAndCall(&a); KillVptrAndCall(&b); }, CFI_ERROR_MSG); } -#endif // CFI_ENFORCEMENT +NOINLINE void OverwriteVptrAndCall(B *obj, A *vptr) { + *reinterpret_cast<void **>(obj) = *reinterpret_cast<void **>(vptr); + obj->f(); +} + +TEST(ToolsSanityTest, BadVirtualCallWrongType) { + A a; + B b; + C c; + EXPECT_DEATH({ OverwriteVptrAndCall(&b, &a); OverwriteVptrAndCall(&b, &c); }, + CFI_ERROR_MSG); +} + +// TODO(pcc): remove CFI_CAST_CHECK, see https://crbug.com/626794. +#if defined(CFI_CAST_CHECK) +TEST(ToolsSanityTest, BadDerivedCast) { + A a; + EXPECT_DEATH((void)(B*)&a, CFI_ERROR_MSG); +} + +TEST(ToolsSanityTest, BadUnrelatedCast) { + class A { + virtual void f() {} + }; + + class B { + virtual void f() {} + }; + + A a; + EXPECT_DEATH((void)(B*)&a, CFI_ERROR_MSG); +} +#endif // CFI_CAST_CHECK + +#endif // CFI_ERROR_MSG } // namespace base
diff --git a/base/trace_event/process_memory_dump.cc b/base/trace_event/process_memory_dump.cc index b2fdbca7..2006bcb 100644 --- a/base/trace_event/process_memory_dump.cc +++ b/base/trace_event/process_memory_dump.cc
@@ -391,27 +391,23 @@ void ProcessMemoryDump::CreateSharedMemoryOwnershipEdge( const MemoryAllocatorDumpGuid& client_local_dump_guid, - const MemoryAllocatorDumpGuid& client_global_dump_guid, const UnguessableToken& shared_memory_guid, int importance) { - CreateSharedMemoryOwnershipEdgeInternal( - client_local_dump_guid, client_global_dump_guid, shared_memory_guid, - importance, false /*is_weak*/); + CreateSharedMemoryOwnershipEdgeInternal(client_local_dump_guid, + shared_memory_guid, importance, + false /*is_weak*/); } void ProcessMemoryDump::CreateWeakSharedMemoryOwnershipEdge( const MemoryAllocatorDumpGuid& client_local_dump_guid, - const MemoryAllocatorDumpGuid& client_global_dump_guid, const UnguessableToken& shared_memory_guid, int importance) { CreateSharedMemoryOwnershipEdgeInternal( - client_local_dump_guid, client_global_dump_guid, shared_memory_guid, - importance, true /*is_weak*/); + client_local_dump_guid, shared_memory_guid, importance, true /*is_weak*/); } void ProcessMemoryDump::CreateSharedMemoryOwnershipEdgeInternal( const MemoryAllocatorDumpGuid& client_local_dump_guid, - const MemoryAllocatorDumpGuid& client_global_dump_guid, const UnguessableToken& shared_memory_guid, int importance, bool is_weak) {
diff --git a/base/trace_event/process_memory_dump.h b/base/trace_event/process_memory_dump.h index fbe4e8b..8103b89 100644 --- a/base/trace_event/process_memory_dump.h +++ b/base/trace_event/process_memory_dump.h
@@ -164,21 +164,16 @@ // channel crbug.com/713763. The weak version creates a weak global dump. // |client_local_dump_guid| The guid of the local dump created by the client // of base::SharedMemory. - // |client_global_dump_guid| The global guid given by the clients to create - // ownership edges of their own. These global dumps will no longer be required - // after the transition. // |shared_memory_guid| The ID of the base::SharedMemory that is assigned // globally, used to create global dump edges in the new model. // |importance| Importance of the global dump edges to say if the current // process owns the memory segment. void CreateSharedMemoryOwnershipEdge( const MemoryAllocatorDumpGuid& client_local_dump_guid, - const MemoryAllocatorDumpGuid& client_global_dump_guid, const UnguessableToken& shared_memory_guid, int importance); void CreateWeakSharedMemoryOwnershipEdge( const MemoryAllocatorDumpGuid& client_local_dump_guid, - const MemoryAllocatorDumpGuid& client_global_dump_guid, const UnguessableToken& shared_memory_guid, int importance); @@ -226,7 +221,6 @@ void CreateSharedMemoryOwnershipEdgeInternal( const MemoryAllocatorDumpGuid& client_local_dump_guid, - const MemoryAllocatorDumpGuid& client_global_dump_guid, const UnguessableToken& shared_memory_guid, int importance, bool is_weak);
diff --git a/base/trace_event/process_memory_dump_unittest.cc b/base/trace_event/process_memory_dump_unittest.cc index 405c3cef..4dae756 100644 --- a/base/trace_event/process_memory_dump_unittest.cc +++ b/base/trace_event/process_memory_dump_unittest.cc
@@ -333,7 +333,6 @@ pmd->allocator_dumps_edges_for_testing(); auto* client_dump2 = pmd->CreateAllocatorDump("discardable/segment2"); - MemoryAllocatorDumpGuid client_global_guid2(2); auto shm_token2 = UnguessableToken::Create(); MemoryAllocatorDumpGuid shm_local_guid2 = SharedMemoryTracker::GetDumpIdForTracing(shm_token2); @@ -342,8 +341,7 @@ pmd->AddOverridableOwnershipEdge(shm_local_guid2, shm_global_guid2, 0 /* importance */); - pmd->CreateSharedMemoryOwnershipEdge(client_dump2->guid(), - client_global_guid2, shm_token2, + pmd->CreateSharedMemoryOwnershipEdge(client_dump2->guid(), shm_token2, 1 /* importance */); EXPECT_EQ(2u, edges.size());
diff --git a/build/android/BUILD.gn b/build/android/BUILD.gn index 80c21c1..bb3a5aa 100644 --- a/build/android/BUILD.gn +++ b/build/android/BUILD.gn
@@ -6,22 +6,6 @@ import("//build/config/android/rules.gni") if (enable_java_templates) { - java_library("build_hooks_java") { - java_files = [ - "buildhooks/java/org/chromium/build/BuildHooks.java", - "buildhooks/java/org/chromium/build/Callback.java", - ] - - # Make all targets pull in the try-with-resources support files. - # If an apk ends up not using any such statements, ProGuard will remove - # them. - deps = [ - "//third_party/bazel/desugar:desugar_runtime_java", - ] - no_build_hooks = true - supports_android = true - } - import("//third_party/ijar/ijar.gni") sun_tools_jar_path = "$root_gen_dir/sun_tools_jar/tools.jar"
diff --git a/build/android/buildhooks/BUILD.gn b/build/android/buildhooks/BUILD.gn new file mode 100644 index 0000000..c63eb3872 --- /dev/null +++ b/build/android/buildhooks/BUILD.gn
@@ -0,0 +1,40 @@ +# Copyright 2017 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//build/config/android/rules.gni") + +java_library("build_hooks_java") { + java_files = [ "java/org/chromium/build/BuildHooks.java" ] + + # Make all targets pull in the try-with-resources support files. + # If an apk ends up not using any such statements, ProGuard will remove + # them. + deps = [ + "//third_party/bazel/desugar:desugar_runtime_java", + ] + no_build_hooks = true + supports_android = true +} + +build_hooks_android_impl = "java/org/chromium/build/BuildHooksAndroidImpl.java" + +android_library("build_hooks_android_java") { + java_files = [ + "java/org/chromium/build/BuildHooksAndroid.java", + build_hooks_android_impl, + ] + + jar_excluded_patterns = [ "*/BuildHooksAndroidImpl.class" ] + no_build_hooks = true +} + +# This default implementation is used if an android_apk target doesn't +# specify a different implementation via build_hooks_android_impl_deps. +android_library("build_hooks_android_impl_java") { + java_files = [ build_hooks_android_impl ] + deps = [ + ":build_hooks_android_java", + ] + no_build_hooks = true +}
diff --git a/build/android/buildhooks/java/org/chromium/build/BuildHooks.java b/build/android/buildhooks/java/org/chromium/build/BuildHooks.java index bea1b8d..0fb5e78a 100644 --- a/build/android/buildhooks/java/org/chromium/build/BuildHooks.java +++ b/build/android/buildhooks/java/org/chromium/build/BuildHooks.java
@@ -5,27 +5,13 @@ package org.chromium.build; /** - * This class is inserted in build, all Java targets have dependence on it. + * All Java targets that support android have dependence on this class. */ -public class BuildHooks { - private static Callback<AssertionError> sAssertCallback; +public abstract class BuildHooks { /** - * Handle AssertionError, decide whether throw or report without crashing base on gn arg. * This method is inserted to handle any assert failure by java_assertion_enabler. */ public static void assertFailureHandler(AssertionError assertionError) { - if (sAssertCallback != null) { - sAssertCallback.run(assertionError); - } else { - throw assertionError; - } - } - - /** - * Set the callback function that handles assert failure. - * This should be called from attachBaseContext. - */ - public static void setAssertCallback(Callback<AssertionError> callback) { - sAssertCallback = callback; + throw assertionError; } }
diff --git a/build/android/buildhooks/java/org/chromium/build/BuildHooksAndroid.java b/build/android/buildhooks/java/org/chromium/build/BuildHooksAndroid.java new file mode 100644 index 0000000..9095b37d --- /dev/null +++ b/build/android/buildhooks/java/org/chromium/build/BuildHooksAndroid.java
@@ -0,0 +1,34 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.build; + +import android.content.res.Resources; + +/** + * All Java targets that require android have dependence on this class. Add methods that do not + * require Android to {@link BuildHooks}. + * + * This class provides hooks needed when bytecode rewriting. Static convenience methods are used to + * minimize the amount of code required to be manually generated when bytecode rewriting. + * + * This class contains default implementations for all methods and is used when no other + * implementation is supplied to an android_apk target (via build_hooks_android_impl_deps). + */ +public abstract class BuildHooksAndroid { + private static BuildHooksAndroidImpl sInstance = new BuildHooksAndroidImpl(); + + /** + * Hook to provide custom resources. + * @param resources fallback resources to use if custom resources aren't available. + * @return custom resources. + */ + public static Resources getResources(Resources resources) { + return sInstance.getResourcesImpl(resources); + } + + protected Resources getResourcesImpl(Resources resources) { + return resources; + } +} \ No newline at end of file
diff --git a/build/android/buildhooks/java/org/chromium/build/BuildHooksAndroidImpl.java b/build/android/buildhooks/java/org/chromium/build/BuildHooksAndroidImpl.java new file mode 100644 index 0000000..3986116 --- /dev/null +++ b/build/android/buildhooks/java/org/chromium/build/BuildHooksAndroidImpl.java
@@ -0,0 +1,10 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.build; + +/** + * Instantiatable version of {@link BuildHooksAndroid}, don't add anything to this class! + */ +public class BuildHooksAndroidImpl extends BuildHooksAndroid {} \ No newline at end of file
diff --git a/build/android/buildhooks/java/org/chromium/build/Callback.java b/build/android/buildhooks/java/org/chromium/build/Callback.java deleted file mode 100644 index a2febf9..0000000 --- a/build/android/buildhooks/java/org/chromium/build/Callback.java +++ /dev/null
@@ -1,10 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.build; - -/** - * Callback interface. - */ -public interface Callback<T> { void run(T arg); }
diff --git a/build/android/gyp/package_resources.py b/build/android/gyp/package_resources.py index 7d4449f..8b16f176 100755 --- a/build/android/gyp/package_resources.py +++ b/build/android/gyp/package_resources.py
@@ -106,10 +106,9 @@ help='path to the Android SDK jar.') parser.add_option('--aapt-path', help='path to the Android aapt tool') - - parser.add_option('--configuration-name', - help='Gyp\'s configuration name (Debug or Release).') - + parser.add_option('--debuggable', + action='store_true', + help='Whether to add android:debuggable="true"') parser.add_option('--android-manifest', help='AndroidManifest.xml path') parser.add_option('--version-code', help='Version code for apk.') parser.add_option('--version-name', help='Version name for apk.') @@ -160,9 +159,8 @@ parser.error('No positional arguments should be given.') # Check that required options have been provided. - required_options = ('android_sdk_jar', 'aapt_path', 'configuration_name', - 'android_manifest', 'version_code', 'version_name', - 'apk_path') + required_options = ('android_sdk_jar', 'aapt_path', 'android_manifest', + 'version_code', 'version_name', 'apk_path') build_utils.CheckOptions(options, parser, required=required_options) @@ -308,7 +306,7 @@ for lang in options.language_splits: package_command.extend(('--split', lang)) - if 'Debug' in options.configuration_name: + if options.debuggable: package_command += ['--debug-mode'] if options.locale_whitelist:
diff --git a/build/android/pylib/local/device/local_device_instrumentation_test_run.py b/build/android/pylib/local/device/local_device_instrumentation_test_run.py index 9b8ef58..4c6e081 100644 --- a/build/android/pylib/local/device/local_device_instrumentation_test_run.py +++ b/build/android/pylib/local/device/local_device_instrumentation_test_run.py
@@ -17,6 +17,7 @@ from devil.android import device_errors from devil.android import device_temp_file from devil.android import flag_changer +from devil.android.sdk import shared_prefs from devil.android.tools import system_app from devil.utils import reraiser_thread from incremental_install import installer @@ -211,8 +212,11 @@ @trace_event.traced def edit_shared_prefs(): - shared_preference_utils.ApplySharedPreferenceSettings( - dev, self._test_instance.edit_shared_prefs) + for setting in self._test_instance.edit_shared_prefs: + shared_pref = shared_prefs.SharedPrefs(dev, setting['package'], + setting['filename']) + shared_preference_utils.ApplySharedPreferenceSetting( + shared_pref, setting) @instrumentation_tracing.no_tracing def push_test_data(): @@ -594,7 +598,6 @@ test_package = self._test_instance.test_package extras = {} extras['log'] = 'true' - extras['package'] = '.'.join(test_package.split('.')[:2]) extras[_EXTRA_TEST_LIST] = dev_test_list_json.name target = '%s/%s' % (test_package, junit4_runner_class) test_list_run_output = dev.StartInstrumentation(
diff --git a/build/android/pylib/utils/shared_preference_utils.py b/build/android/pylib/utils/shared_preference_utils.py index 0541be4..ce78010 100644 --- a/build/android/pylib/utils/shared_preference_utils.py +++ b/build/android/pylib/utils/shared_preference_utils.py
@@ -7,8 +7,6 @@ import json import logging -from devil.android.sdk import shared_prefs - def ExtractSettingsFromJson(filepath): """Extracts the settings data from the given JSON file. @@ -35,12 +33,12 @@ return unicode_to_str(json.load(prefs_file)) -def ApplySharedPreferenceSettings(device, settings): +def ApplySharedPreferenceSetting(shared_pref, setting): """Applies the given app settings to the given device. Modifies an installed app's settings by modifying its shared preference - settings file. Provided settings data must be a list of settings dictionaries, - where dictionaries are in the following format: + settings file. Provided settings data must be a settings dictionary, + which are in the following format: { "package": "com.example.package", "filename": "AppSettingsFile.xml", @@ -61,28 +59,26 @@ this function are in //chrome/android/shared_preference_files/test/. Args: - device: The devil DeviceUtils object for the device the settings will be - applied to. - settings: A list of settings dictionaries to apply. + shared_pref: The devil SharedPrefs object for the device the settings will + be applied to. + setting: A settings dictionary to apply. """ - for pref in settings: - prefs = shared_prefs.SharedPrefs(device, pref['package'], pref['filename']) - prefs.Load() - for key in pref.get('remove', []): - try: - prefs.Remove(key) - except KeyError: - logging.warning("Attempted to remove non-existent key %s", key) - for key, value in pref.get('set', {}).iteritems(): - if isinstance(value, bool): - prefs.SetBoolean(key, value) - elif isinstance(value, basestring): - prefs.SetString(key, value) - elif isinstance(value, long) or isinstance(value, int): - prefs.SetLong(key, value) - elif isinstance(value, list): - prefs.SetStringSet(key, value) - else: - raise ValueError("Given invalid value type %s for key %s" % ( - str(type(value)), key)) - prefs.Commit() + shared_pref.Load() + for key in setting.get('remove', []): + try: + shared_pref.Remove(key) + except KeyError: + logging.warning("Attempted to remove non-existent key %s", key) + for key, value in setting.get('set', {}).iteritems(): + if isinstance(value, bool): + shared_pref.SetBoolean(key, value) + elif isinstance(value, basestring): + shared_pref.SetString(key, value) + elif isinstance(value, long) or isinstance(value, int): + shared_pref.SetLong(key, value) + elif isinstance(value, list): + shared_pref.SetStringSet(key, value) + else: + raise ValueError("Given invalid value type %s for key %s" % ( + str(type(value)), key)) + shared_pref.Commit()
diff --git a/build/config/android/config.gni b/build/config/android/config.gni index 12070753..be84f1b 100644 --- a/build/config/android/config.gni +++ b/build/config/android/config.gni
@@ -130,6 +130,9 @@ # off will enable proguard. is_java_debug = is_debug + # Mark APKs as android:debuggable="true". + debuggable_apks = !is_official_build + # Set to true to enable the Errorprone compiler use_errorprone_java_compiler = false
diff --git a/build/config/android/internal_rules.gni b/build/config/android/internal_rules.gni index 01bb360..b8d0119 100644 --- a/build/config/android/internal_rules.gni +++ b/build/config/android/internal_rules.gni
@@ -755,11 +755,6 @@ rebased_android_sdk_jar = rebase_path(android_sdk_jar, root_build_dir) android_default_aapt_path = "$rebased_android_sdk_build_tools/aapt" - android_configuration_name = "Release" - if (is_debug) { - android_configuration_name = "Debug" - } - template("android_lint") { action(target_name) { forward_variables_from(invoker, @@ -1273,7 +1268,7 @@ _deps = [ ":$_desugar_target" ] _previous_output_jar = _desugar_output_jar } - + if (_filter_jar) { _filter_target = "${target_name}__filter" _filter_input_jar = _previous_output_jar @@ -1690,7 +1685,6 @@ _rebased_android_sdk_jar, "--aapt-path", _android_aapt_path, - "--configuration-name=$android_configuration_name", "--android-manifest", rebase_path(invoker.android_manifest, root_build_dir), "--version-code", @@ -1701,6 +1695,12 @@ rebase_path(_resource_packaged_apk_path, root_build_dir), ] + # Useful to have android:debuggable in the manifest even for Release + # builds. Just omit it for officai + if (debuggable_apks) { + args += [ "--debuggable" ] + } + if (defined(_resources_zip)) { args += [ "--resource-zips", @@ -2456,11 +2456,15 @@ _enable_build_hooks = _supports_android && - (!defined(invoker.no_build_hooks) || - (defined(invoker.no_build_hooks) && !invoker.no_build_hooks)) - + (!defined(invoker.no_build_hooks) || !invoker.no_build_hooks) if (_enable_build_hooks) { - _accumulated_deps += [ "//build/android:build_hooks_java" ] + _accumulated_deps += [ "//build/android/buildhooks:build_hooks_java" ] + } + + _enable_build_hooks_android = _enable_build_hooks && _requires_android + if (_enable_build_hooks_android) { + _accumulated_deps += + [ "//build/android/buildhooks:build_hooks_android_java" ] } if (defined(invoker.run_findbugs_override)) { @@ -2545,7 +2549,12 @@ if (defined(invoker.deps)) { possible_config_deps = invoker.deps if (_enable_build_hooks) { - possible_config_deps += [ "//build/android:build_hooks_java" ] + possible_config_deps += + [ "//build/android/buildhooks:build_hooks_java" ] + } + if (_enable_build_hooks_android) { + possible_config_deps += + [ "//build/android/buildhooks:build_hooks_android_java" ] } } supports_android = _supports_android
diff --git a/build/config/android/rules.gni b/build/config/android/rules.gni index cec2697..b02d741 100644 --- a/build/config/android/rules.gni +++ b/build/config/android/rules.gni
@@ -1672,6 +1672,13 @@ _srcjar_deps += invoker.srcjar_deps } + if (defined(invoker.build_hooks_android_impl_deps)) { + _build_hooks_android_impl_deps = invoker.build_hooks_android_impl_deps + } else { + _build_hooks_android_impl_deps = + [ "//build/android/buildhooks:build_hooks_android_impl_java" ] + } + _use_chromium_linker = defined(invoker.use_chromium_linker) && invoker.use_chromium_linker _enable_relocation_packing = defined(invoker.enable_relocation_packing) && @@ -1815,9 +1822,9 @@ deps = _android_root_manifest_deps - possible_config_deps = [] + possible_config_deps = _build_hooks_android_impl_deps if (defined(invoker.deps)) { - possible_config_deps = invoker.deps + possible_config_deps += invoker.deps } # Added emma to the target's classpath via its .build_config. @@ -2020,9 +2027,9 @@ requires_android = true override_build_config = _build_config deps = [ - ":$android_manifest_target", - ":$build_config_target", - ] + ":$android_manifest_target", + ":$build_config_target", + ] + _build_hooks_android_impl_deps android_manifest = _android_manifest srcjar_deps = _srcjar_deps
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn index 00101626..1a917f9 100644 --- a/build/config/compiler/BUILD.gn +++ b/build/config/compiler/BUILD.gn
@@ -1766,11 +1766,15 @@ } } else { cflags = [] - if (is_android && target_cpu == "arm") { + if (!use_debug_fission && target_cpu == "arm") { # dump_syms has issues with dwarf4 on arm, https://crbug.com/744956 # TODO(thakis): Remove this again once dump_syms is fixed. # - # "-gdwarf-3" doesn't work with dump_syms in Chrome OS. + # debug fission needs DWARF DIEs to be emitted at version 4. + # Chrome OS emits Debug Frame in DWARF1 to make breakpad happy. [1] + # Unless Android needs debug fission, DWARF3 is the simplest solution. + # + # [1] crrev.com/a81d5ade0b043208e06ad71a38bcf9c348a1a52f cflags += [ "-gdwarf-3" ] } cflags += [ "-g2" ]
diff --git a/build/config/fuchsia/BUILD.gn b/build/config/fuchsia/BUILD.gn index ee1946ba..23bbdf1 100644 --- a/build/config/fuchsia/BUILD.gn +++ b/build/config/fuchsia/BUILD.gn
@@ -28,28 +28,32 @@ } asmflags = cflags - # TODO(thakis): Once Fuchsia's libclang_rt.builtin no longer has upstream - # patches, we might want to make tools/clang/scripts/update.py build it - # and bundle it with the clang package instead of using the library from - # the SDK, https://crbug.com/724204 - # Note: Intentionally 6.0.0 instead of $clang_version because the clang - # version of the toolchain_libs directory in the Fuchsia SDK can be - # different from the version of Chromium's clang. ldflags += [ + # TODO(thakis): Once Fuchsia's libclang_rt.builtin no longer has upstream + # patches, we might want to make tools/clang/scripts/update.py build it + # and bundle it with the clang package instead of using the library from + # the SDK, https://crbug.com/724204 + # Note: Intentionally 6.0.0 instead of $clang_version because the clang + # version of the toolchain_libs directory in the Fuchsia SDK can be + # different from the version of Chromium's clang. "-resource-dir", rebase_path(fuchsia_sdk, root_build_dir) + "/toolchain_libs/clang/6.0.0", - ] - ldflags += [ # The stack defaults to 256k on Fuchsia (see # https://fuchsia.googlesource.com/magenta/+/master/system/private/magenta/stack.h#9), # but on other platforms it's much higher, so a variety of code assumes more # will be available. Raise to 8M which matches e.g. macOS. "-Wl,-z,stack-size=0x800000", + + # We always want mxio or else e.g. stdio wouldn't be initialized if mxio + # happens to not be directly referenced. The common POSIX-y compiler setup + # uses -Wl,--as-needed which drops it if it's simply "-lmxio" from a libs + # setting. Disable --as-needed, add mxio, and then set back to --as-needed. + # https://crbug.com/731217. + "-Wl,--no-as-needed", + "-lmxio", + "-Wl,--as-needed", ] - libs = [ - "mxio", - "magenta", - ] + libs = [ "magenta" ] }
diff --git a/build/config/ios/rules.gni b/build/config/ios/rules.gni index bdf7e08..48bdf7c 100644 --- a/build/config/ios/rules.gni +++ b/build/config/ios/rules.gni
@@ -162,6 +162,10 @@ # entitlements (must generate a single file as output); cannot be # defined if entitlements_path is set. # +# xcode_test_application_name: +# (optional) string, name of the test application for Xcode unit or ui +# test target. +# template("create_signed_bundle") { assert(defined(invoker.product_type), "product_type must be defined for $target_name") @@ -172,6 +176,13 @@ defined(invoker.bundle_binary_path), "Only one of bundle_binary_target or bundle_binary_path may be specified in " + target_name) + if (defined(invoker.xcode_test_application_name)) { + assert( + invoker.product_type == "com.apple.product-type.bundle.unit-test" || + invoker.product_type == "com.apple.product-type.bundle.ui-testing", + "xcode_test_application_name can be only defined for Xcode unit or ui test target.") + } + _target_name = target_name _output_name = target_name if (defined(invoker.output_name)) { @@ -225,6 +236,7 @@ "public_deps", "testonly", "visibility", + "xcode_test_application_name", ]) bundle_root_dir = _bundle_root_dir @@ -1365,6 +1377,9 @@ # string, name of the target that depends on the generated bundle, this # value is used to restrict visibilities. # +# xcode_test_application_name: +# string, name of the test application for Xcode unit or ui test target. +# # output_name # (optional) string, name of the generated application, if omitted, # defaults to the target_name. @@ -1382,16 +1397,15 @@ "product_type defined for $target_name is invalid.") assert(defined(invoker.host_target), "host_target must be defined for $target_name") + assert(defined(invoker.xcode_test_application_name), + "xcode_test_application_name must be defined for $target_name") # Silence "assignment had no effect" error for non-default toolchains as - # host_target is only used in the expansion of the template for the default - # toolchain. - assert(invoker.host_target != target_name) - - # Silence "assignment had no effect" error for non-default toolchains as - # configs is only used in the expansion of the template for the default - # toolchain. + # following variables are only used in the expansion of the template for the + # default toolchain. assert(invoker.configs != []) + assert(invoker.host_target != target_name) + assert(invoker.xcode_test_application_name != target_name) _target_name = target_name _output_name = target_name @@ -1492,6 +1506,7 @@ [ "enable_code_signing", "product_type", + "xcode_test_application_name", ]) testonly = true @@ -1561,6 +1576,7 @@ output_name = _xctest_output product_type = "com.apple.product-type.bundle.unit-test" host_target = _host_target + xcode_test_application_name = _host_output deps = [ ":$_xctest_shell_source_target",
diff --git a/build/config/sanitizers/BUILD.gn b/build/config/sanitizers/BUILD.gn index 65966cf1..d617396d 100644 --- a/build/config/sanitizers/BUILD.gn +++ b/build/config/sanitizers/BUILD.gn
@@ -372,7 +372,7 @@ cflags += [ "-fsanitize-recover=cfi" ] } } else { - defines = [ "CFI_ENFORCEMENT" ] + defines = [ "CFI_ENFORCEMENT_TRAP" ] } } }
diff --git a/build/config/sanitizers/sanitizers.gni b/build/config/sanitizers/sanitizers.gni index 3b2ed9b..c7f59a1 100644 --- a/build/config/sanitizers/sanitizers.gni +++ b/build/config/sanitizers/sanitizers.gni
@@ -208,9 +208,13 @@ "Only use CFI recovery together with diagnostics.") # TODO(crbug.com/753445): the use_sanitizer_coverage arg is currently -# not supported by the Chromium mac_clang_x64 toolchain. +# not supported by the Chromium mac_clang_x64 toolchain on iOS distribution. +# The coverage works with iOS toolchain but it is broken when the mac +# toolchain is used as a secondary one on iOS distribution. E.g., it should be +# possible to build the "net" target for iOS with the sanitizer coverage +# enabled. assert( - !(use_sanitizer_coverage && is_mac), + !(use_sanitizer_coverage && is_mac && target_os == "ios"), "crbug.com/753445: use_sanitizer_coverage=true is not supported by the " + - "Chromium mac_clang_x64 toolchain. Please set the argument value to " + - "false.") + "Chromium mac_clang_x64 toolchain on iOS distribution. Please set " + + "the argument value to false.")
diff --git a/build/fuchsia/exe_runner.py b/build/fuchsia/exe_runner.py index 2c87b2a7..6863c812 100755 --- a/build/fuchsia/exe_runner.py +++ b/build/fuchsia/exe_runner.py
@@ -36,11 +36,11 @@ bootfs = BuildBootfs( args.output_directory, ReadRuntimeDeps(args.runtime_deps_path, args.output_directory), - args.exe_name, child_args, args.device, args.dry_run) + args.exe_name, child_args, args.dry_run, power_off=False) if not bootfs: return 2 - return RunFuchsia(bootfs, args.device, args.dry_run) + return RunFuchsia(bootfs, args.device, args.dry_run, interactive=True) if __name__ == '__main__':
diff --git a/build/fuchsia/runner_common.py b/build/fuchsia/runner_common.py index 8728a11..06aff3e 100755 --- a/build/fuchsia/runner_common.py +++ b/build/fuchsia/runner_common.py
@@ -149,7 +149,7 @@ return result def BuildBootfs(output_directory, runtime_deps, bin_name, child_args, - device, dry_run): + dry_run, power_off): # |runtime_deps| already contains (target, source) pairs for the runtime deps, # so we can initialize |file_mapping| from it directly. file_mapping = dict(runtime_deps) @@ -167,7 +167,7 @@ autorun_file.write('\n') autorun_file.write('echo Process terminated.\n') - if not device: + if power_off: # If shutdown of QEMU happens too soon after the program finishes, log # statements from the end of the run will be lost, so sleep for a bit before # shutting down. When running on device don't power off so the output and @@ -212,12 +212,13 @@ def _SymbolizeEntry(entry): + filename_re = re.compile(r'at ([-._a-zA-Z0-9/+]+):(\d+)') raw, frame_id = entry['raw'], entry['frame_id'] prefix = '#%s: ' % frame_id if entry.has_key('debug_binary') and entry.has_key('pc_offset'): # Invoke addr2line on the host-side binary to resolve the symbol. addr2line_output = subprocess.check_output( - ['addr2line', '-s', '-Cipf', '--exe=' + entry['debug_binary'], + ['addr2line', '-Cipf', '--exe=' + entry['debug_binary'], entry['pc_offset']]) # addr2line outputs a second line for inlining information, offset @@ -225,7 +226,13 @@ addr2line_filtered = addr2line_output.strip().replace( '(inlined', ' ' * len(prefix) + '(inlined') - # If symbolization files just output the raw backtrace. + # Relativize path to DIR_SOURCE_ROOT if we see a filename. + def RelativizePath(m): + relpath = os.path.relpath(os.path.normpath(m.group(1)), DIR_SOURCE_ROOT) + return 'at ' + relpath + ':' + m.group(2) + addr2line_filtered = filename_re.sub(RelativizePath, addr2line_filtered) + + # If symbolization fails just output the raw backtrace. if '??' in addr2line_filtered: addr2line_filtered = raw else: @@ -292,7 +299,7 @@ return symbolized -def RunFuchsia(bootfs_and_manifest, use_device, dry_run): +def RunFuchsia(bootfs_and_manifest, use_device, dry_run, interactive): bootfs, bootfs_manifest = bootfs_and_manifest kernel_path = os.path.join(SDK_ROOT, 'kernel', 'magenta.bin') @@ -318,7 +325,16 @@ '-netdev', 'user,id=net0,net=192.168.3.0/24,dhcpstart=192.168.3.9,' + 'host=192.168.3.2', '-device', 'e1000,netdev=net0', + ] + if interactive: + # TERM is passed through to make locally entered commands echo. With + # TERM=dumb what's typed isn't visible. + qemu_command.extend([ + '-append', 'TERM=%s kernel.halt_on_panic=true' % os.environ.get('TERM'), + ]) + else: + qemu_command.extend([ # Use stdio for the guest OS only; don't attach the QEMU interactive # monitor. '-serial', 'stdio', @@ -326,7 +342,8 @@ # TERM=dumb tells the guest OS to not emit ANSI commands that trigger # noisy ANSI spew from the user's terminal emulator. - '-append', 'TERM=dumb kernel.halt_on_panic=true'] + '-append', 'TERM=dumb kernel.halt_on_panic=true', + ]) if int(os.environ.get('CHROME_HEADLESS', 0)) == 0: qemu_command += ['-enable-kvm', '-cpu', 'host,migratable=no'] @@ -337,6 +354,10 @@ print 'Run:', ' '.join(qemu_command) return 0 + if interactive: + subprocess.check_call(qemu_command) + return 0 + # Set up backtrace-parsing regexps. qemu_prefix = re.compile(r'^.*> ') backtrace_prefix = re.compile(r'bt#(?P<frame_id>\d+): ')
diff --git a/build/fuchsia/test_runner.py b/build/fuchsia/test_runner.py index c883658..469a5959 100755 --- a/build/fuchsia/test_runner.py +++ b/build/fuchsia/test_runner.py
@@ -166,11 +166,11 @@ child_args.append('--test-launcher-filter-file=/system/test_filter_file') bootfs = BuildBootfs(args.output_directory, runtime_deps, args.exe_name, - child_args, args.device, args.dry_run) + child_args, args.dry_run, power_off=not args.device) if not bootfs: return 2 - return RunFuchsia(bootfs, args.device, args.dry_run) + return RunFuchsia(bootfs, args.device, args.dry_run, interactive=False) if __name__ == '__main__':
diff --git a/build/toolchain/mac/BUILD.gn b/build/toolchain/mac/BUILD.gn index 85aa44f7..71a3f8e 100644 --- a/build/toolchain/mac/BUILD.gn +++ b/build/toolchain/mac/BUILD.gn
@@ -461,9 +461,12 @@ current_cpu = "x64" current_os = "mac" - # TODO(crbug.com/753445): the use_sanitizer_coverage arg is currently - # not supported by the Chromium mac_clang_x64 toolchain. - use_sanitizer_coverage = false + if (target_os == "ios") { + # TODO(crbug.com/753445): the use_sanitizer_coverage arg is currently + # not supported by the Chromium mac_clang_x64 toolchain on iOS + # distribution. + use_sanitizer_coverage = false + } } }
diff --git a/build/toolchain/win/tool_wrapper.py b/build/toolchain/win/tool_wrapper.py index c20c333..4d749ef 100644 --- a/build/toolchain/win/tool_wrapper.py +++ b/build/toolchain/win/tool_wrapper.py
@@ -111,6 +111,9 @@ shutil.copytree(source, dest) else: shutil.copy2(source, dest) + # Try to diagnose crbug.com/741603 + if not os.path.exists(dest): + raise Exception("Copying of %s to %s failed" % (source, dest)) def ExecLinkWrapper(self, arch, use_separate_mspdbsrv, *args): """Filter diagnostic output from link that looks like:
diff --git a/cc/animation/animation_events.h b/cc/animation/animation_events.h index b8b66f6..e19d20d8 100644 --- a/cc/animation/animation_events.h +++ b/cc/animation/animation_events.h
@@ -47,8 +47,7 @@ std::unique_ptr<AnimationCurve> curve; }; -class CC_ANIMATION_EXPORT AnimationEvents - : public NON_EXPORTED_BASE(MutatorEvents) { +class CC_ANIMATION_EXPORT AnimationEvents : public MutatorEvents { public: AnimationEvents();
diff --git a/cc/animation/animation_host.h b/cc/animation/animation_host.h index 31e45e6..a570eca93 100644 --- a/cc/animation/animation_host.h +++ b/cc/animation/animation_host.h
@@ -43,8 +43,7 @@ // (PushPropertiesTo). // An AnimationHost talks to its correspondent LayerTreeHost via // MutatorHostClient interface. -class CC_ANIMATION_EXPORT AnimationHost - : public NON_EXPORTED_BASE(MutatorHost) { +class CC_ANIMATION_EXPORT AnimationHost : public MutatorHost { public: using ElementToAnimationsMap = std::unordered_map<ElementId,
diff --git a/cc/blink/web_compositor_support_impl.h b/cc/blink/web_compositor_support_impl.h index d97a0dc0..46748bdc 100644 --- a/cc/blink/web_compositor_support_impl.h +++ b/cc/blink/web_compositor_support_impl.h
@@ -15,7 +15,7 @@ namespace cc_blink { class CC_BLINK_EXPORT WebCompositorSupportImpl - : public NON_EXPORTED_BASE(blink::WebCompositorSupport) { + : public blink::WebCompositorSupport { public: WebCompositorSupportImpl(); ~WebCompositorSupportImpl() override;
diff --git a/cc/blink/web_layer_impl.cc b/cc/blink/web_layer_impl.cc index fe1a88eb..35a3a0a 100644 --- a/cc/blink/web_layer_impl.cc +++ b/cc/blink/web_layer_impl.cc
@@ -360,6 +360,10 @@ return layer_->IsContainerForFixedPositionLayers(); } +void WebLayerImpl::SetIsResizedByBrowserControls(bool enable) { + layer_->SetIsResizedByBrowserControls(enable); +} + static blink::WebLayerPositionConstraint ToWebLayerPositionConstraint( const cc::LayerPositionConstraint& constraint) { blink::WebLayerPositionConstraint web_constraint;
diff --git a/cc/blink/web_layer_impl.h b/cc/blink/web_layer_impl.h index 69fb7a761..7c35072 100644 --- a/cc/blink/web_layer_impl.h +++ b/cc/blink/web_layer_impl.h
@@ -35,7 +35,7 @@ namespace cc_blink { -class CC_BLINK_EXPORT WebLayerImpl : public NON_EXPORTED_BASE(blink::WebLayer) { +class CC_BLINK_EXPORT WebLayerImpl : public blink::WebLayer { public: WebLayerImpl(); explicit WebLayerImpl(scoped_refptr<cc::Layer>); @@ -115,6 +115,7 @@ cc::TouchAction) const override; void SetIsContainerForFixedPositionLayers(bool is_container) override; bool IsContainerForFixedPositionLayers() const override; + void SetIsResizedByBrowserControls(bool) override; void SetPositionConstraint( const blink::WebLayerPositionConstraint& constraint) override; blink::WebLayerPositionConstraint PositionConstraint() const override;
diff --git a/cc/ipc/BUILD.gn b/cc/ipc/BUILD.gn index 532f12e..b6ec63a 100644 --- a/cc/ipc/BUILD.gn +++ b/cc/ipc/BUILD.gn
@@ -39,7 +39,6 @@ mojom("interfaces") { sources = [ - "begin_frame_args.mojom", "copy_output_request.mojom", "copy_output_result.mojom", "filter_operation.mojom",
diff --git a/cc/ipc/begin_frame_args.mojom b/cc/ipc/begin_frame_args.mojom deleted file mode 100644 index baa81606..0000000 --- a/cc/ipc/begin_frame_args.mojom +++ /dev/null
@@ -1,32 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -module cc.mojom; - -import "mojo/common/time.mojom"; - -enum BeginFrameArgsType { - INVALID, - NORMAL, - MISSED, - BEGIN_FRAME_ARGS_TYPE_MAX -}; - -// See cc/output/begin_frame_args.h. -struct BeginFrameArgs { - mojo.common.mojom.TimeTicks frame_time; - mojo.common.mojom.TimeTicks deadline; - mojo.common.mojom.TimeDelta interval; - uint64 sequence_number; - uint32 source_id; - BeginFrameArgsType type; - bool on_critical_path; -}; - -// See cc/output/begin_frame_args.h. -struct BeginFrameAck { - uint64 sequence_number; - uint32 source_id; - // |has_damage| is implicit through IPC message name, so not transmitted. -};
diff --git a/cc/ipc/begin_frame_args.typemap b/cc/ipc/begin_frame_args.typemap deleted file mode 100644 index a76e9d3..0000000 --- a/cc/ipc/begin_frame_args.typemap +++ /dev/null
@@ -1,18 +0,0 @@ -# Copyright 2016 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -mojom = "//cc/ipc/begin_frame_args.mojom" -public_headers = [ "//components/viz/common/frame_sinks/begin_frame_args.h" ] -traits_headers = [ "//cc/ipc/begin_frame_args_struct_traits.h" ] -deps = [ - "//components/viz/common", - "//mojo/common:struct_traits", -] -sources = [ - "begin_frame_args_struct_traits.cc", -] -type_mappings = [ - "cc.mojom.BeginFrameArgs=viz::BeginFrameArgs", - "cc.mojom.BeginFrameAck=viz::BeginFrameAck", -]
diff --git a/cc/ipc/begin_frame_args_for_blink.typemap b/cc/ipc/begin_frame_args_for_blink.typemap deleted file mode 100644 index d7a4bbd..0000000 --- a/cc/ipc/begin_frame_args_for_blink.typemap +++ /dev/null
@@ -1,15 +0,0 @@ -# Copyright 2016 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -mojom = "//cc/ipc/begin_frame_args.mojom" -public_headers = [ "//components/viz/common/frame_sinks/begin_frame_args.h" ] -traits_headers = [ "//cc/ipc/begin_frame_args_struct_traits.h" ] -deps = [ - "//cc", - "//mojo/common:struct_traits", -] -type_mappings = [ - "cc.mojom.BeginFrameArgs=viz::BeginFrameArgs", - "cc.mojom.BeginFrameAck=viz::BeginFrameAck", -]
diff --git a/cc/ipc/begin_frame_args_struct_traits.cc b/cc/ipc/begin_frame_args_struct_traits.cc deleted file mode 100644 index 8511b99..0000000 --- a/cc/ipc/begin_frame_args_struct_traits.cc +++ /dev/null
@@ -1,39 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "cc/ipc/begin_frame_args_struct_traits.h" -#include "ipc/ipc_message_utils.h" -#include "mojo/common/common_custom_types_struct_traits.h" - -namespace mojo { - -// static -bool StructTraits<cc::mojom::BeginFrameArgsDataView, viz::BeginFrameArgs>::Read( - cc::mojom::BeginFrameArgsDataView data, - viz::BeginFrameArgs* out) { - if (!data.ReadFrameTime(&out->frame_time) || - !data.ReadDeadline(&out->deadline) || - !data.ReadInterval(&out->interval)) { - return false; - } - out->source_id = data.source_id(); - out->sequence_number = data.sequence_number(); - // TODO(eseckler): Use EnumTraits for |type|. - out->type = static_cast<viz::BeginFrameArgs::BeginFrameArgsType>(data.type()); - out->on_critical_path = data.on_critical_path(); - return true; -} - -// static -bool StructTraits<cc::mojom::BeginFrameAckDataView, viz::BeginFrameAck>::Read( - cc::mojom::BeginFrameAckDataView data, - viz::BeginFrameAck* out) { - if (data.sequence_number() < viz::BeginFrameArgs::kStartingFrameNumber) - return false; - out->source_id = data.source_id(); - out->sequence_number = data.sequence_number(); - return true; -} - -} // namespace mojo
diff --git a/cc/ipc/begin_frame_args_struct_traits.h b/cc/ipc/begin_frame_args_struct_traits.h deleted file mode 100644 index 4607df1..0000000 --- a/cc/ipc/begin_frame_args_struct_traits.h +++ /dev/null
@@ -1,63 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CC_IPC_BEGIN_FRAME_ARGS_STRUCT_TRAITS_H_ -#define CC_IPC_BEGIN_FRAME_ARGS_STRUCT_TRAITS_H_ - -#include "cc/ipc/begin_frame_args.mojom-shared.h" -#include "components/viz/common/frame_sinks/begin_frame_args.h" - -namespace mojo { - -template <> -struct StructTraits<cc::mojom::BeginFrameArgsDataView, viz::BeginFrameArgs> { - static base::TimeTicks frame_time(const viz::BeginFrameArgs& args) { - return args.frame_time; - } - - static base::TimeTicks deadline(const viz::BeginFrameArgs& args) { - return args.deadline; - } - - static base::TimeDelta interval(const viz::BeginFrameArgs& args) { - return args.interval; - } - - static uint64_t sequence_number(const viz::BeginFrameArgs& args) { - return args.sequence_number; - } - - static uint32_t source_id(const viz::BeginFrameArgs& args) { - return args.source_id; - } - - static cc::mojom::BeginFrameArgsType type(const viz::BeginFrameArgs& args) { - return static_cast<cc::mojom::BeginFrameArgsType>(args.type); - } - - static bool on_critical_path(const viz::BeginFrameArgs& args) { - return args.on_critical_path; - } - - static bool Read(cc::mojom::BeginFrameArgsDataView data, - viz::BeginFrameArgs* out); -}; - -template <> -struct StructTraits<cc::mojom::BeginFrameAckDataView, viz::BeginFrameAck> { - static uint64_t sequence_number(const viz::BeginFrameAck& ack) { - return ack.sequence_number; - } - - static uint32_t source_id(const viz::BeginFrameAck& ack) { - return ack.source_id; - } - - static bool Read(cc::mojom::BeginFrameAckDataView data, - viz::BeginFrameAck* out); -}; - -} // namespace mojo - -#endif // CC_IPC_BEGIN_FRAME_ARGS_STRUCT_TRAITS_H_
diff --git a/cc/ipc/cc_serialization_perftest.cc b/cc/ipc/cc_serialization_perftest.cc index 12a0acc4..0be85ac 100644 --- a/cc/ipc/cc_serialization_perftest.cc +++ b/cc/ipc/cc_serialization_perftest.cc
@@ -6,7 +6,6 @@ #include "base/test/launcher/unit_test_launcher.h" #include "base/test/test_suite.h" -#include "cc/ipc/begin_frame_args_struct_traits.h" #include "cc/ipc/cc_param_traits.h" #include "cc/ipc/shared_quad_state_struct_traits.h" #include "cc/ipc/surface_id_struct_traits.h"
diff --git a/cc/ipc/struct_traits_unittest.cc b/cc/ipc/struct_traits_unittest.cc index 8f2517ff..bdb7210b 100644 --- a/cc/ipc/struct_traits_unittest.cc +++ b/cc/ipc/struct_traits_unittest.cc
@@ -41,16 +41,6 @@ private: // TraitsTestService: - void EchoBeginFrameArgs(const viz::BeginFrameArgs& b, - EchoBeginFrameArgsCallback callback) override { - std::move(callback).Run(b); - } - - void EchoBeginFrameAck(const viz::BeginFrameAck& b, - EchoBeginFrameAckCallback callback) override { - std::move(callback).Run(b); - } - void EchoCopyOutputRequest(std::unique_ptr<viz::CopyOutputRequest> c, EchoCopyOutputRequestCallback callback) override { std::move(callback).Run(std::move(c)); @@ -122,52 +112,6 @@ } // namespace -TEST_F(StructTraitsTest, BeginFrameArgs) { - const base::TimeTicks frame_time = base::TimeTicks::Now(); - const base::TimeTicks deadline = base::TimeTicks::Now(); - const base::TimeDelta interval = base::TimeDelta::FromMilliseconds(1337); - const viz::BeginFrameArgs::BeginFrameArgsType type = - viz::BeginFrameArgs::NORMAL; - const bool on_critical_path = true; - const uint32_t source_id = 5; - const uint64_t sequence_number = 10; - viz::BeginFrameArgs input; - input.source_id = source_id; - input.sequence_number = sequence_number; - input.frame_time = frame_time; - input.deadline = deadline; - input.interval = interval; - input.type = type; - input.on_critical_path = on_critical_path; - mojom::TraitsTestServicePtr proxy = GetTraitsTestProxy(); - viz::BeginFrameArgs output; - proxy->EchoBeginFrameArgs(input, &output); - EXPECT_EQ(source_id, output.source_id); - EXPECT_EQ(sequence_number, output.sequence_number); - EXPECT_EQ(frame_time, output.frame_time); - EXPECT_EQ(deadline, output.deadline); - EXPECT_EQ(interval, output.interval); - EXPECT_EQ(type, output.type); - EXPECT_EQ(on_critical_path, output.on_critical_path); -} - -TEST_F(StructTraitsTest, BeginFrameAck) { - const uint32_t source_id = 5; - const uint64_t sequence_number = 10; - const bool has_damage = true; - viz::BeginFrameAck input; - input.source_id = source_id; - input.sequence_number = sequence_number; - input.has_damage = has_damage; - mojom::TraitsTestServicePtr proxy = GetTraitsTestProxy(); - viz::BeginFrameAck output; - proxy->EchoBeginFrameAck(input, &output); - EXPECT_EQ(source_id, output.source_id); - EXPECT_EQ(sequence_number, output.sequence_number); - // |has_damage| is not transmitted. - EXPECT_FALSE(output.has_damage); -} - TEST_F(StructTraitsTest, CopyOutputRequest_BitmapRequest) { const gfx::Rect area(5, 7, 44, 55); const auto source =
diff --git a/cc/ipc/traits_test_service.mojom b/cc/ipc/traits_test_service.mojom index bc4e727..406898ba 100644 --- a/cc/ipc/traits_test_service.mojom +++ b/cc/ipc/traits_test_service.mojom
@@ -4,7 +4,6 @@ module cc.mojom; -import "cc/ipc/begin_frame_args.mojom"; import "cc/ipc/copy_output_request.mojom"; import "cc/ipc/copy_output_result.mojom"; import "cc/ipc/filter_operation.mojom"; @@ -17,12 +16,6 @@ // serialization and deserialization. interface TraitsTestService { [Sync] - EchoBeginFrameArgs(BeginFrameArgs b) => (BeginFrameArgs pass); - - [Sync] - EchoBeginFrameAck(BeginFrameAck b) => (BeginFrameAck pass); - - [Sync] EchoCopyOutputRequest(CopyOutputRequest c) => (CopyOutputRequest pass); [Sync]
diff --git a/cc/ipc/typemaps.gni b/cc/ipc/typemaps.gni index ca328cb..196c094 100644 --- a/cc/ipc/typemaps.gni +++ b/cc/ipc/typemaps.gni
@@ -3,7 +3,6 @@ # found in the LICENSE file. typemaps = [ - "//cc/ipc/begin_frame_args.typemap", "//cc/ipc/copy_output_request.typemap", "//cc/ipc/copy_output_result.typemap", "//cc/ipc/filter_operation.typemap",
diff --git a/cc/layers/layer.cc b/cc/layers/layer.cc index 7d878f7..36c96354 100644 --- a/cc/layers/layer.cc +++ b/cc/layers/layer.cc
@@ -59,6 +59,7 @@ user_scrollable_vertical(true), main_thread_scrolling_reasons( MainThreadScrollingReason::kNotScrollingOnMain), + is_resized_by_browser_controls(false), is_container_for_fixed_position_layers(false), mutable_properties(MutableProperty::kNone), scroll_parent(nullptr), @@ -1112,6 +1113,18 @@ return false; } +void Layer::SetIsResizedByBrowserControls(bool resized) { + if (inputs_.is_resized_by_browser_controls == resized) + return; + inputs_.is_resized_by_browser_controls = resized; + + SetNeedsCommit(); +} + +bool Layer::IsResizedByBrowserControls() const { + return inputs_.is_resized_by_browser_controls; +} + void Layer::SetIsContainerForFixedPositionLayers(bool container) { if (inputs_.is_container_for_fixed_position_layers == container) return;
diff --git a/cc/layers/layer.h b/cc/layers/layer.h index 7476721..5b555414 100644 --- a/cc/layers/layer.h +++ b/cc/layers/layer.h
@@ -175,6 +175,9 @@ void SetIsContainerForFixedPositionLayers(bool container); bool IsContainerForFixedPositionLayers() const; + void SetIsResizedByBrowserControls(bool resized); + bool IsResizedByBrowserControls() const; + void SetPositionConstraint(const LayerPositionConstraint& constraint); const LayerPositionConstraint& position_constraint() const { return inputs_.position_constraint; @@ -597,6 +600,14 @@ TouchActionRegion touch_action_region; + // When set, position: fixed children of this layer will be affected by URL + // bar movement. bottom-fixed element will be pushed down as the URL bar + // hides (and the viewport expands) so that the element stays fixed to the + // viewport bottom. This will always be set on the outer viewport scroll + // layer. In the case of a non-default rootScroller, all iframes in the + // rootScroller ancestor chain will also have it set on their scroll + // layers. + bool is_resized_by_browser_controls : 1; bool is_container_for_fixed_position_layers : 1; LayerPositionConstraint position_constraint;
diff --git a/cc/layers/layer_impl.cc b/cc/layers/layer_impl.cc index ed41acb..a4f2ef3 100644 --- a/cc/layers/layer_impl.cc +++ b/cc/layers/layer_impl.cc
@@ -65,6 +65,7 @@ draws_content_(false), contributes_to_drawn_render_surface_(false), should_hit_test_(false), + is_resized_by_browser_controls_(false), viewport_layer_type_(NOT_VIEWPORT_LAYER), background_color_(0), safe_opaque_background_color_(0), @@ -364,6 +365,14 @@ ->in_subtree_of_page_scale_layer; } +bool LayerImpl::IsResizedByBrowserControls() const { + return is_resized_by_browser_controls_; +} + +void LayerImpl::SetIsResizedByBrowserControls(bool resized) { + is_resized_by_browser_controls_ = resized; +} + std::unique_ptr<base::DictionaryValue> LayerImpl::LayerTreeAsJson() { std::unique_ptr<base::DictionaryValue> result(new base::DictionaryValue); result->SetInteger("LayerId", id());
diff --git a/cc/layers/layer_impl.h b/cc/layers/layer_impl.h index e5fd235..42ef2d67 100644 --- a/cc/layers/layer_impl.h +++ b/cc/layers/layer_impl.h
@@ -208,6 +208,9 @@ return use_parent_backface_visibility_; } + bool IsResizedByBrowserControls() const; + void SetIsResizedByBrowserControls(bool resized); + void SetShouldCheckBackfaceVisibility(bool should_check_backface_visibility) { should_check_backface_visibility_ = should_check_backface_visibility; } @@ -503,6 +506,7 @@ bool draws_content_ : 1; bool contributes_to_drawn_render_surface_ : 1; bool should_hit_test_ : 1; + bool is_resized_by_browser_controls_ : 1; static_assert(LAST_VIEWPORT_LAYER_TYPE < (1u << 3), "enough bits for ViewportLayerType (viewport_layer_type_)");
diff --git a/cc/layers/layer_impl_unittest.cc b/cc/layers/layer_impl_unittest.cc index 560e84d..d7110377 100644 --- a/cc/layers/layer_impl_unittest.cc +++ b/cc/layers/layer_impl_unittest.cc
@@ -483,10 +483,10 @@ class LayerImplScrollTest : public testing::Test { public: - LayerImplScrollTest() - : host_impl_(settings(), - &task_runner_provider_, - &task_graph_runner_), + LayerImplScrollTest() : LayerImplScrollTest(LayerTreeSettings()) {} + + LayerImplScrollTest(const LayerTreeSettings& settings) + : host_impl_(settings, &task_runner_provider_, &task_graph_runner_), root_id_(7) { host_impl_.active_tree()->SetRootLayerForTesting( LayerImpl::Create(host_impl_.active_tree(), root_id_)); @@ -520,11 +520,6 @@ LayerTreeImpl* tree() { return host_impl_.active_tree(); } - LayerTreeSettings settings() { - LayerTreeSettings settings; - return settings; - } - private: FakeImplTaskRunnerProvider task_runner_provider_; TestTaskGraphRunner task_graph_runner_; @@ -532,6 +527,17 @@ int root_id_; }; +class CommitToPendingTreeLayerImplScrollTest : public LayerImplScrollTest { + public: + CommitToPendingTreeLayerImplScrollTest() : LayerImplScrollTest(settings()) {} + + LayerTreeSettings settings() { + LayerTreeSettings tree_settings; + tree_settings.commit_to_active_tree = false; + return tree_settings; + } +}; + TEST_F(LayerImplScrollTest, ScrollByWithZeroOffset) { // Test that LayerImpl::ScrollBy only affects ScrollDelta and total scroll // offset is bounded by the range [0, max scroll offset]. @@ -635,7 +641,8 @@ EXPECT_VECTOR_EQ(gfx::Vector2dF(30.5f, 5), layer()->CurrentScrollOffset()); } -TEST_F(LayerImplScrollTest, PushPropertiesToMirrorsCurrentScrollOffset) { +TEST_F(CommitToPendingTreeLayerImplScrollTest, + PushPropertiesToMirrorsCurrentScrollOffset) { gfx::ScrollOffset scroll_offset(10, 5); gfx::Vector2dF scroll_delta(12, 18);
diff --git a/cc/layers/layer_position_constraint_unittest.cc b/cc/layers/layer_position_constraint_unittest.cc index ad5f81c3..1afd8382 100644 --- a/cc/layers/layer_position_constraint_unittest.cc +++ b/cc/layers/layer_position_constraint_unittest.cc
@@ -144,6 +144,8 @@ inner_viewport_container_layer_->AddChild(page_scale_layer_); root_->AddChild(inner_viewport_container_layer_); + child_->SetIsResizedByBrowserControls(true); + layer_tree_host_->SetRootLayer(root_); LayerTreeHost::ViewportLayers viewport_layers; viewport_layers.page_scale = page_scale_layer_;
diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc index 66e4e9c..b8b9890 100644 --- a/cc/layers/picture_layer_impl.cc +++ b/cc/layers/picture_layer_impl.cc
@@ -785,6 +785,14 @@ default_tile_width += 2 * PictureLayerTiling::kBorderTexels; default_tile_height += 2 * PictureLayerTiling::kBorderTexels; + // Use half-width GPU tiles on low-end devices when the content width is + // larger than the viewport width. + if (layer_tree_impl() + ->settings() + .use_half_width_tiles_for_gpu_rasterization && + content_bounds.width() > viewport_width) + default_tile_width /= 2; + // Round GPU default tile sizes to a multiple of kGpuDefaultTileAlignment. // This helps prevent rounding errors in our CA path. crbug.com/632274 default_tile_width =
diff --git a/cc/layers/picture_layer_impl.h b/cc/layers/picture_layer_impl.h index 88559c8..ebc2c8b 100644 --- a/cc/layers/picture_layer_impl.h +++ b/cc/layers/picture_layer_impl.h
@@ -27,9 +27,8 @@ class MicroBenchmarkImpl; class Tile; -class CC_EXPORT PictureLayerImpl - : public LayerImpl, - NON_EXPORTED_BASE(public PictureLayerTilingClient) { +class CC_EXPORT PictureLayerImpl : public LayerImpl, + public PictureLayerTilingClient { public: static std::unique_ptr<PictureLayerImpl> Create(LayerTreeImpl* tree_impl, int id, Layer::LayerMaskType mask_type) {
diff --git a/cc/layers/picture_layer_impl_unittest.cc b/cc/layers/picture_layer_impl_unittest.cc index ff9fa3b..736db40 100644 --- a/cc/layers/picture_layer_impl_unittest.cc +++ b/cc/layers/picture_layer_impl_unittest.cc
@@ -79,6 +79,7 @@ LayerTreeSettings CreateSettings() override { LayerTreeSettings settings; + settings.commit_to_active_tree = false; settings.layer_transforms_should_scale_layer_contents = true; settings.create_low_res_tiling = true; settings.resource_settings.buffer_to_texture_target_map = @@ -269,6 +270,15 @@ void TestQuadsForSolidColor(bool test_for_solid, bool partial_opaque); }; +class CommitToActiveTreePictureLayerImplTest : public PictureLayerImplTest { + public: + LayerTreeSettings CreateSettings() override { + LayerTreeSettings settings = PictureLayerImplTest::CreateSettings(); + settings.commit_to_active_tree = true; + return settings; + } +}; + class NoLowResPictureLayerImplTest : public PictureLayerImplTest { public: LayerTreeSettings CreateSettings() override { @@ -2404,7 +2414,8 @@ EXPECT_EQ(2u, active_layer()->tilings()->num_tilings()); } -TEST_F(PictureLayerImplTest, NoLowResTilingWithGpuRasterization) { +TEST_F(CommitToActiveTreePictureLayerImplTest, + NoLowResTilingWithGpuRasterization) { gfx::Size default_tile_size(host_impl()->settings().default_tile_size); gfx::Size layer_bounds(default_tile_size.width() * 4, default_tile_size.height() * 4); @@ -2421,7 +2432,8 @@ EXPECT_EQ(1u, active_layer()->tilings()->num_tilings()); } -TEST_F(PictureLayerImplTest, RequiredTilesWithGpuRasterization) { +TEST_F(CommitToActiveTreePictureLayerImplTest, + RequiredTilesWithGpuRasterization) { host_impl()->SetHasGpuRasterizationTrigger(true); host_impl()->CommitComplete(); @@ -4770,6 +4782,55 @@ EXPECT_EQ(result.height(), 512); // 500 + 2, 32-byte aligned. } +class HalfWidthTileTest : public PictureLayerImplTest { + public: + LayerTreeSettings CreateSettings() override { + LayerTreeSettings settings = PictureLayerImplTest::CreateSettings(); + settings.use_half_width_tiles_for_gpu_rasterization = true; + return settings; + } +}; + +TEST_F(HalfWidthTileTest, TileSizes) { + host_impl()->CreatePendingTree(); + + LayerTreeImpl* pending_tree = host_impl()->pending_tree(); + std::unique_ptr<FakePictureLayerImpl> layer = + FakePictureLayerImpl::Create(pending_tree, layer_id()); + + gfx::Size result; + host_impl()->SetHasGpuRasterizationTrigger(true); + host_impl()->CommitComplete(); + EXPECT_EQ(host_impl()->gpu_rasterization_status(), + GpuRasterizationStatus::ON); + host_impl()->SetViewportSize(gfx::Size(2000, 2000)); + host_impl()->NotifyReadyToActivate(); + + layer->set_gpu_raster_max_texture_size(host_impl()->device_viewport_size()); + result = layer->CalculateTileSize(gfx::Size(10000, 10000)); + EXPECT_EQ(result.width(), + MathUtil::UncheckedRoundUp( + (2000 + 2 * PictureLayerTiling::kBorderTexels) / 2, 32)); + EXPECT_EQ(result.height(), 512); + + // Clamp and round-up, when smaller than viewport. + // Tile-height doubles to 50% when width shrinks to <= 50%. + host_impl()->SetViewportSize(gfx::Size(1000, 1000)); + layer->set_gpu_raster_max_texture_size(host_impl()->device_viewport_size()); + result = layer->CalculateTileSize(gfx::Size(447, 10000)); + EXPECT_EQ(result.width(), 448); + EXPECT_EQ(result.height(), 512); + + // Largest layer is 50% of viewport width (rounded up), and + // 50% of viewport in height. + result = layer->CalculateTileSize(gfx::Size(447, 400)); + EXPECT_EQ(result.width(), 448); + EXPECT_EQ(result.height(), 448); + result = layer->CalculateTileSize(gfx::Size(500, 499)); + EXPECT_EQ(result.width(), 512); + EXPECT_EQ(result.height(), 512); +} + TEST_F(NoLowResPictureLayerImplTest, LowResWasHighResCollision) { gfx::Size layer_bounds(1300, 1900);
diff --git a/cc/paint/paint_op_buffer.cc b/cc/paint/paint_op_buffer.cc index 807ee3c..93a0ab8 100644 --- a/cc/paint/paint_op_buffer.cc +++ b/cc/paint/paint_op_buffer.cc
@@ -293,7 +293,7 @@ static const SerializeFunction g_serialize_functions[kNumOpTypes] = {TYPES(M)}; #undef M -using DeserializeFunction = PaintOp* (*)(const void* input, +using DeserializeFunction = PaintOp* (*)(const volatile void* input, size_t input_size, void* output, size_t output_size); @@ -691,13 +691,13 @@ } template <typename T> -T* SimpleDeserialize(const void* input, +T* SimpleDeserialize(const volatile void* input, size_t input_size, void* output, size_t output_size) { if (input_size < sizeof(T)) return nullptr; - memcpy(output, input, sizeof(T)); + memcpy(output, const_cast<void*>(input), sizeof(T)); T* op = reinterpret_cast<T*>(output); if (!op->IsValid()) @@ -708,7 +708,7 @@ return op; } -PaintOp* AnnotateOp::Deserialize(const void* input, +PaintOp* AnnotateOp::Deserialize(const volatile void* input, size_t input_size, void* output, size_t output_size) { @@ -728,7 +728,7 @@ return op; } -PaintOp* ClipDeviceRectOp::Deserialize(const void* input, +PaintOp* ClipDeviceRectOp::Deserialize(const volatile void* input, size_t input_size, void* output, size_t output_size) { @@ -737,7 +737,7 @@ output_size); } -PaintOp* ClipPathOp::Deserialize(const void* input, +PaintOp* ClipPathOp::Deserialize(const volatile void* input, size_t input_size, void* output, size_t output_size) { @@ -757,7 +757,7 @@ return op; } -PaintOp* ClipRectOp::Deserialize(const void* input, +PaintOp* ClipRectOp::Deserialize(const volatile void* input, size_t input_size, void* output, size_t output_size) { @@ -765,7 +765,7 @@ return SimpleDeserialize<ClipRectOp>(input, input_size, output, output_size); } -PaintOp* ClipRRectOp::Deserialize(const void* input, +PaintOp* ClipRRectOp::Deserialize(const volatile void* input, size_t input_size, void* output, size_t output_size) { @@ -773,7 +773,7 @@ return SimpleDeserialize<ClipRRectOp>(input, input_size, output, output_size); } -PaintOp* ConcatOp::Deserialize(const void* input, +PaintOp* ConcatOp::Deserialize(const volatile void* input, size_t input_size, void* output, size_t output_size) { @@ -781,7 +781,7 @@ return SimpleDeserialize<ConcatOp>(input, input_size, output, output_size); } -PaintOp* DrawArcOp::Deserialize(const void* input, +PaintOp* DrawArcOp::Deserialize(const volatile void* input, size_t input_size, void* output, size_t output_size) { @@ -802,7 +802,7 @@ return op; } -PaintOp* DrawColorOp::Deserialize(const void* input, +PaintOp* DrawColorOp::Deserialize(const volatile void* input, size_t input_size, void* output, size_t output_size) { @@ -810,7 +810,7 @@ return SimpleDeserialize<DrawColorOp>(input, input_size, output, output_size); } -PaintOp* DrawDRRectOp::Deserialize(const void* input, +PaintOp* DrawDRRectOp::Deserialize(const volatile void* input, size_t input_size, void* output, size_t output_size) { @@ -829,7 +829,7 @@ return op; } -PaintOp* DrawImageOp::Deserialize(const void* input, +PaintOp* DrawImageOp::Deserialize(const volatile void* input, size_t input_size, void* output, size_t output_size) { @@ -849,7 +849,7 @@ return op; } -PaintOp* DrawImageRectOp::Deserialize(const void* input, +PaintOp* DrawImageRectOp::Deserialize(const volatile void* input, size_t input_size, void* output, size_t output_size) { @@ -870,7 +870,7 @@ return op; } -PaintOp* DrawIRectOp::Deserialize(const void* input, +PaintOp* DrawIRectOp::Deserialize(const volatile void* input, size_t input_size, void* output, size_t output_size) { @@ -888,7 +888,7 @@ return op; } -PaintOp* DrawLineOp::Deserialize(const void* input, +PaintOp* DrawLineOp::Deserialize(const volatile void* input, size_t input_size, void* output, size_t output_size) { @@ -909,7 +909,7 @@ return op; } -PaintOp* DrawOvalOp::Deserialize(const void* input, +PaintOp* DrawOvalOp::Deserialize(const volatile void* input, size_t input_size, void* output, size_t output_size) { @@ -927,7 +927,7 @@ return op; } -PaintOp* DrawPathOp::Deserialize(const void* input, +PaintOp* DrawPathOp::Deserialize(const volatile void* input, size_t input_size, void* output, size_t output_size) { @@ -945,7 +945,7 @@ return op; } -PaintOp* DrawRecordOp::Deserialize(const void* input, +PaintOp* DrawRecordOp::Deserialize(const volatile void* input, size_t input_size, void* output, size_t output_size) { @@ -954,7 +954,7 @@ return nullptr; } -PaintOp* DrawRectOp::Deserialize(const void* input, +PaintOp* DrawRectOp::Deserialize(const volatile void* input, size_t input_size, void* output, size_t output_size) { @@ -972,7 +972,7 @@ return op; } -PaintOp* DrawRRectOp::Deserialize(const void* input, +PaintOp* DrawRRectOp::Deserialize(const volatile void* input, size_t input_size, void* output, size_t output_size) { @@ -990,7 +990,7 @@ return op; } -PaintOp* DrawTextBlobOp::Deserialize(const void* input, +PaintOp* DrawTextBlobOp::Deserialize(const volatile void* input, size_t input_size, void* output, size_t output_size) { @@ -1010,7 +1010,7 @@ return op; } -PaintOp* NoopOp::Deserialize(const void* input, +PaintOp* NoopOp::Deserialize(const volatile void* input, size_t input_size, void* output, size_t output_size) { @@ -1018,7 +1018,7 @@ return SimpleDeserialize<NoopOp>(input, input_size, output, output_size); } -PaintOp* RestoreOp::Deserialize(const void* input, +PaintOp* RestoreOp::Deserialize(const volatile void* input, size_t input_size, void* output, size_t output_size) { @@ -1026,7 +1026,7 @@ return SimpleDeserialize<RestoreOp>(input, input_size, output, output_size); } -PaintOp* RotateOp::Deserialize(const void* input, +PaintOp* RotateOp::Deserialize(const volatile void* input, size_t input_size, void* output, size_t output_size) { @@ -1034,7 +1034,7 @@ return SimpleDeserialize<RotateOp>(input, input_size, output, output_size); } -PaintOp* SaveOp::Deserialize(const void* input, +PaintOp* SaveOp::Deserialize(const volatile void* input, size_t input_size, void* output, size_t output_size) { @@ -1042,7 +1042,7 @@ return SimpleDeserialize<SaveOp>(input, input_size, output, output_size); } -PaintOp* SaveLayerOp::Deserialize(const void* input, +PaintOp* SaveLayerOp::Deserialize(const volatile void* input, size_t input_size, void* output, size_t output_size) { @@ -1060,7 +1060,7 @@ return op; } -PaintOp* SaveLayerAlphaOp::Deserialize(const void* input, +PaintOp* SaveLayerAlphaOp::Deserialize(const volatile void* input, size_t input_size, void* output, size_t output_size) { @@ -1069,7 +1069,7 @@ output_size); } -PaintOp* ScaleOp::Deserialize(const void* input, +PaintOp* ScaleOp::Deserialize(const volatile void* input, size_t input_size, void* output, size_t output_size) { @@ -1078,7 +1078,7 @@ return SimpleDeserialize<ScaleOp>(input, input_size, output, output_size); } -PaintOp* SetMatrixOp::Deserialize(const void* input, +PaintOp* SetMatrixOp::Deserialize(const volatile void* input, size_t input_size, void* output, size_t output_size) { @@ -1086,7 +1086,7 @@ return SimpleDeserialize<SetMatrixOp>(input, input_size, output, output_size); } -PaintOp* TranslateOp::Deserialize(const void* input, +PaintOp* TranslateOp::Deserialize(const volatile void* input, size_t input_size, void* output, size_t output_size) { @@ -1414,23 +1414,25 @@ return skip; } -PaintOp* PaintOp::Deserialize(const void* input, +PaintOp* PaintOp::Deserialize(const volatile void* input, size_t input_size, void* output, - size_t output_size) { + size_t output_size, + size_t* read_bytes) { DCHECK_GE(output_size, sizeof(LargestPaintOp)); - const PaintOp* serialized = reinterpret_cast<const PaintOp*>(input); - uint32_t skip = serialized->skip; + + uint32_t first_word = reinterpret_cast<const volatile uint32_t*>(input)[0]; + uint8_t type = static_cast<uint8_t>(first_word & 0xFF); + uint32_t skip = first_word >> 8; + if (input_size < skip) return nullptr; if (skip % PaintOpBuffer::PaintOpAlign != 0) return nullptr; - uint8_t type = serialized->type; if (type > static_cast<uint8_t>(PaintOpType::LastPaintOpType)) return nullptr; - - return g_deserialize_functions[serialized->type](input, skip, output, - output_size); + *read_bytes = skip; + return g_deserialize_functions[type](input, skip, output, output_size); } // static
diff --git a/cc/paint/paint_op_buffer.h b/cc/paint/paint_op_buffer.h index 4e545d8..f78bc8f 100644 --- a/cc/paint/paint_op_buffer.h +++ b/cc/paint/paint_op_buffer.h
@@ -49,10 +49,10 @@ // See PaintOp::Serialize/Deserialize for comments. Derived Serialize types // don't write the 4 byte type/skip header because they don't know how much // data they will need to write. PaintOp::Serialize itself must update it. -#define HAS_SERIALIZATION_FUNCTIONS() \ - static size_t Serialize(const PaintOp* op, void* memory, size_t size, \ - const SerializeOptions& options); \ - static PaintOp* Deserialize(const void* input, size_t input_size, \ +#define HAS_SERIALIZATION_FUNCTIONS() \ + static size_t Serialize(const PaintOp* op, void* memory, size_t size, \ + const SerializeOptions& options); \ + static PaintOp* Deserialize(const volatile void* input, size_t input_size, \ void* output, size_t output_size); enum class PaintOpType : uint8_t { @@ -109,6 +109,7 @@ void Raster(SkCanvas* canvas, const PlaybackParams& params) const; bool IsDrawOp() const; bool IsPaintOpWithFlags() const; + bool IsValid() const; struct SerializeOptions { ImageDecodeCache* decode_cache = nullptr; @@ -127,10 +128,12 @@ // if valid. nullptr is returned if the deserialization fails. // |output_size| must be at least LargestPaintOp + serialized->skip, // to fit all ops. The caller is responsible for destroying these ops. - static PaintOp* Deserialize(const void* input, + // After reading, it returns the number of bytes read in |read_bytes|. + static PaintOp* Deserialize(const volatile void* input, size_t input_size, void* output, - size_t output_size); + size_t output_size, + size_t* read_bytes); // For draw ops, returns true if a conservative bounding rect can be provided // for the op. @@ -169,6 +172,10 @@ static_cast<uint32_t>(SkClipOp::kMax_EnumValue); } + static bool IsValidPath(const SkPath& path) { + return path.isValid() && path.pathRefIsValid(); + } + static bool IsUnsetRect(const SkRect& rect) { return rect.fLeft == SK_ScalarInfinity; } @@ -268,7 +275,7 @@ static void Raster(const ClipPathOp* op, SkCanvas* canvas, const PlaybackParams& params); - bool IsValid() const { return IsValidSkClipOp(op); } + bool IsValid() const { return IsValidSkClipOp(op) && IsValidPath(path); } int CountSlowPaths() const; bool HasNonAAPaint() const { return !antialias; } HAS_SERIALIZATION_FUNCTIONS(); @@ -540,7 +547,7 @@ const PaintFlags* flags, SkCanvas* canvas, const PlaybackParams& params); - bool IsValid() const { return flags.IsValid(); } + bool IsValid() const { return flags.IsValid() && IsValidPath(path); } int CountSlowPaths() const; HAS_SERIALIZATION_FUNCTIONS();
diff --git a/cc/paint/paint_op_buffer_fuzzer.cc b/cc/paint/paint_op_buffer_fuzzer.cc index 94560b0..6a7cca6b 100644 --- a/cc/paint/paint_op_buffer_fuzzer.cc +++ b/cc/paint/paint_op_buffer_fuzzer.cc
@@ -31,16 +31,16 @@ // Need 4 bytes to be able to read the type/skip. while (size >= 4) { const cc::PaintOp* serialized = reinterpret_cast<const cc::PaintOp*>(data); - if (serialized->skip > kMaxSerializedSize) break; - size_t deserialized_size = sizeof(cc::LargestPaintOp) + serialized->skip; std::unique_ptr<char, base::AlignedFreeDeleter> deserialized( static_cast<char*>(base::AlignedAlloc( - deserialized_size, cc::PaintOpBuffer::PaintOpAlign))); - cc::PaintOp* deserialized_op = cc::PaintOp::Deserialize( - data, size, deserialized.get(), deserialized_size); + sizeof(cc::LargestPaintOp), cc::PaintOpBuffer::PaintOpAlign))); + size_t bytes_read = 0; + cc::PaintOp* deserialized_op = + cc::PaintOp::Deserialize(data, size, deserialized.get(), + sizeof(cc::LargestPaintOp), &bytes_read); if (!deserialized_op) break; @@ -52,8 +52,8 @@ if (serialized->skip >= size) break; - size -= serialized->skip; - data += serialized->skip; + size -= bytes_read; + data += bytes_read; } return 0; }
diff --git a/cc/paint/paint_op_buffer_unittest.cc b/cc/paint/paint_op_buffer_unittest.cc index 6eef674..9718ff0 100644 --- a/cc/paint/paint_op_buffer_unittest.cc +++ b/cc/paint/paint_op_buffer_unittest.cc
@@ -32,6 +32,14 @@ // unit test. This can also be used for deserialized op size safely in this // unit test suite as generally deserialized ops are smaller. static constexpr size_t kBufferBytesPerOp = 1000 + sizeof(LargestPaintOp); + +template <typename T> +void ValidateOps(PaintOpBuffer* buffer) { + // Make sure all test data is valid before serializing it. + for (auto* op : PaintOpBuffer::Iterator(buffer)) + EXPECT_TRUE(static_cast<T*>(op)->IsValid()); +} + } // namespace class PaintOpSerializationTestUtils { @@ -1544,11 +1552,9 @@ input_size_ != other.input_size_ || remaining_ != other.remaining_; } DeserializerIterator& operator++() { - const PaintOp* serialized = reinterpret_cast<const PaintOp*>(current_); - - CHECK_GE(remaining_, serialized->skip); - current_ += serialized->skip; - remaining_ -= serialized->skip; + CHECK_GE(remaining_, last_bytes_read_); + current_ += last_bytes_read_; + remaining_ -= last_bytes_read_; if (remaining_ > 0) CHECK_GE(remaining_, 4u); @@ -1571,6 +1577,8 @@ current_(current), input_size_(input_size), remaining_(remaining) { + data_.reset(static_cast<char*>(base::AlignedAlloc( + sizeof(LargestPaintOp), PaintOpBuffer::PaintOpAlign))); DeserializeCurrentOp(); } @@ -1586,25 +1594,17 @@ if (!remaining_) return; - - const PaintOp* serialized = reinterpret_cast<const PaintOp*>(current_); - size_t required = sizeof(LargestPaintOp) + serialized->skip; - - if (data_size_ < required) { - data_.reset(static_cast<char*>( - base::AlignedAlloc(required, PaintOpBuffer::PaintOpAlign))); - data_size_ = required; - } deserialized_op_ = - PaintOp::Deserialize(current_, remaining_, data_.get(), data_size_); + PaintOp::Deserialize(current_, remaining_, data_.get(), + sizeof(LargestPaintOp), &last_bytes_read_); } const void* input_ = nullptr; const char* current_ = nullptr; size_t input_size_ = 0u; size_t remaining_ = 0u; + size_t last_bytes_read_ = 0u; std::unique_ptr<char, base::AlignedFreeDeleter> data_; - size_t data_size_ = 0u; PaintOp* deserialized_op_ = nullptr; }; @@ -1616,6 +1616,7 @@ test_rects[1], nullptr); buffer->push<AnnotateOp>(PaintCanvas::AnnotationType::NAMED_DESTINATION, test_rects[2], SkData::MakeEmpty()); + ValidateOps<AnnotateOp>(buffer); } void PushClipDeviceRectOps(PaintOpBuffer* buffer) { @@ -1623,6 +1624,7 @@ SkClipOp op = i % 3 ? SkClipOp::kDifference : SkClipOp::kIntersect; buffer->push<ClipDeviceRectOp>(test_irects[i - 1], test_irects[0], op); } + ValidateOps<ClipDeviceRectOp>(buffer); } void PushClipPathOps(PaintOpBuffer* buffer) { @@ -1630,6 +1632,7 @@ SkClipOp op = i % 3 ? SkClipOp::kDifference : SkClipOp::kIntersect; buffer->push<ClipPathOp>(test_paths[i], op, !!(i % 2)); } + ValidateOps<ClipPathOp>(buffer); } void PushClipRectOps(PaintOpBuffer* buffer) { @@ -1638,6 +1641,7 @@ bool antialias = !!(i % 3); buffer->push<ClipRectOp>(test_rects[i], op, antialias); } + ValidateOps<ClipRectOp>(buffer); } void PushClipRRectOps(PaintOpBuffer* buffer) { @@ -1646,11 +1650,13 @@ bool antialias = !!(i % 3); buffer->push<ClipRRectOp>(test_rrects[i], op, antialias); } + ValidateOps<ClipRRectOp>(buffer); } void PushConcatOps(PaintOpBuffer* buffer) { for (size_t i = 0; i < test_matrices.size(); ++i) buffer->push<ConcatOp>(test_matrices[i]); + ValidateOps<ConcatOp>(buffer); } void PushDrawArcOps(PaintOpBuffer* buffer) { @@ -1661,12 +1667,14 @@ buffer->push<DrawArcOp>(test_rects[i], test_floats[i], test_floats[i + 1], use_center, test_flags[i]); } + ValidateOps<DrawArcOp>(buffer); } void PushDrawColorOps(PaintOpBuffer* buffer) { for (size_t i = 0; i < test_colors.size(); ++i) { buffer->push<DrawColorOp>(test_colors[i], static_cast<SkBlendMode>(i)); } + ValidateOps<DrawColorOp>(buffer); } void PushDrawDRRectOps(PaintOpBuffer* buffer) { @@ -1675,6 +1683,7 @@ buffer->push<DrawDRRectOp>(test_rrects[i], test_rrects[i + 1], test_flags[i]); } + ValidateOps<DrawDRRectOp>(buffer); } void PushDrawImageOps(PaintOpBuffer* buffer) { @@ -1689,6 +1698,7 @@ // TODO(enne): maybe all these optional ops should not be optional. buffer->push<DrawImageOp>(test_images[0], test_floats[0], test_floats[1], nullptr); + ValidateOps<DrawImageOp>(buffer); } void PushDrawImageRectOps(PaintOpBuffer* buffer) { @@ -1707,12 +1717,14 @@ buffer->push<DrawImageRectOp>(test_images[0], test_rects[0], test_rects[1], nullptr, PaintCanvas::kStrict_SrcRectConstraint); + ValidateOps<DrawImageRectOp>(buffer); } void PushDrawIRectOps(PaintOpBuffer* buffer) { size_t len = std::min(test_irects.size(), test_flags.size()); for (size_t i = 0; i < len; ++i) buffer->push<DrawIRectOp>(test_irects[i], test_flags[i]); + ValidateOps<DrawIRectOp>(buffer); } void PushDrawLineOps(PaintOpBuffer* buffer) { @@ -1722,30 +1734,35 @@ test_floats[i + 2], test_floats[i + 3], test_flags[i]); } + ValidateOps<DrawLineOp>(buffer); } void PushDrawOvalOps(PaintOpBuffer* buffer) { size_t len = std::min(test_paths.size(), test_flags.size()); for (size_t i = 0; i < len; ++i) buffer->push<DrawOvalOp>(test_rects[i], test_flags[i]); + ValidateOps<DrawOvalOp>(buffer); } void PushDrawPathOps(PaintOpBuffer* buffer) { size_t len = std::min(test_paths.size(), test_flags.size()); for (size_t i = 0; i < len; ++i) buffer->push<DrawPathOp>(test_paths[i], test_flags[i]); + ValidateOps<DrawPathOp>(buffer); } void PushDrawRectOps(PaintOpBuffer* buffer) { size_t len = std::min(test_rects.size(), test_flags.size()); for (size_t i = 0; i < len; ++i) buffer->push<DrawRectOp>(test_rects[i], test_flags[i]); + ValidateOps<DrawRectOp>(buffer); } void PushDrawRRectOps(PaintOpBuffer* buffer) { size_t len = std::min(test_rrects.size(), test_flags.size()); for (size_t i = 0; i < len; ++i) buffer->push<DrawRRectOp>(test_rrects[i], test_flags[i]); + ValidateOps<DrawRRectOp>(buffer); } void PushDrawTextBlobOps(PaintOpBuffer* buffer) { @@ -1755,6 +1772,7 @@ buffer->push<DrawTextBlobOp>(test_blobs[i], test_floats[i], test_floats[i + 1], test_flags[i]); } + ValidateOps<DrawTextBlobOp>(buffer); } void PushNoopOps(PaintOpBuffer* buffer) { @@ -1762,6 +1780,7 @@ buffer->push<NoopOp>(); buffer->push<NoopOp>(); buffer->push<NoopOp>(); + ValidateOps<NoopOp>(buffer); } void PushRestoreOps(PaintOpBuffer* buffer) { @@ -1769,11 +1788,13 @@ buffer->push<RestoreOp>(); buffer->push<RestoreOp>(); buffer->push<RestoreOp>(); + ValidateOps<RestoreOp>(buffer); } void PushRotateOps(PaintOpBuffer* buffer) { for (size_t i = 0; i < test_floats.size(); ++i) buffer->push<RotateOp>(test_floats[i]); + ValidateOps<RotateOp>(buffer); } void PushSaveOps(PaintOpBuffer* buffer) { @@ -1781,6 +1802,7 @@ buffer->push<SaveOp>(); buffer->push<SaveOp>(); buffer->push<SaveOp>(); + ValidateOps<SaveOp>(buffer); } void PushSaveLayerOps(PaintOpBuffer* buffer) { @@ -1792,6 +1814,7 @@ buffer->push<SaveLayerOp>(nullptr, &test_flags[0]); buffer->push<SaveLayerOp>(&test_rects[0], nullptr); buffer->push<SaveLayerOp>(nullptr, nullptr); + ValidateOps<SaveLayerOp>(buffer); } void PushSaveLayerAlphaOps(PaintOpBuffer* buffer) { @@ -1801,21 +1824,25 @@ // Test optional args. buffer->push<SaveLayerAlphaOp>(nullptr, test_uint8s[0], false); + ValidateOps<SaveLayerAlphaOp>(buffer); } void PushScaleOps(PaintOpBuffer* buffer) { for (size_t i = 0; i < test_floats.size(); i += 2) buffer->push<ScaleOp>(test_floats[i], test_floats[i + 1]); + ValidateOps<ScaleOp>(buffer); } void PushSetMatrixOps(PaintOpBuffer* buffer) { for (size_t i = 0; i < test_matrices.size(); ++i) buffer->push<SetMatrixOp>(test_matrices[i]); + ValidateOps<SetMatrixOp>(buffer); } void PushTranslateOps(PaintOpBuffer* buffer) { for (size_t i = 0; i < test_floats.size(); i += 2) buffer->push<TranslateOp>(test_floats[i], test_floats[i + 1]); + ValidateOps<TranslateOp>(buffer); } void CompareFlags(const PaintFlags& original, const PaintFlags& written) { @@ -2071,14 +2098,6 @@ class PaintOpSerializationTest : public ::testing::TestWithParam<uint8_t> { public: - PaintOpSerializationTest() { - // Verify test data. - for (size_t i = 0; i < test_rrects.size(); ++i) - EXPECT_TRUE(test_rrects[i].isValid()); - for (size_t i = 0; i < test_rects.size(); ++i) - EXPECT_TRUE(test_rects[i].isFinite()); - } - PaintOpType GetParamType() const { return static_cast<PaintOpType>(GetParam()); } @@ -2427,14 +2446,17 @@ // This will verify that individual op deserializing code behaves // properly when presented with invalid offsets. serialized->skip = read_size; - PaintOp* written = PaintOp::Deserialize( - current, read_size, deserialize_buffer_.get(), kOutputOpSize); + size_t bytes_read = 0; + PaintOp* written = + PaintOp::Deserialize(current, read_size, deserialize_buffer_.get(), + kOutputOpSize, &bytes_read); // Skips are only valid if they are aligned. if (read_size >= skip && read_size % kAlign == 0) { ASSERT_NE(nullptr, written); ASSERT_LE(written->skip, kOutputOpSize); EXPECT_EQ(GetParamType(), written->GetType()); + EXPECT_EQ(serialized->skip, bytes_read); } else { EXPECT_EQ(nullptr, written); } @@ -2468,28 +2490,31 @@ ASSERT_GT(bytes_written, 0u); // can deserialize from exactly the right size - PaintOp* success = - PaintOp::Deserialize(input_.get(), bytes_written, output_.get(), kSize); + size_t bytes_read = 0; + PaintOp* success = PaintOp::Deserialize(input_.get(), bytes_written, + output_.get(), kSize, &bytes_read); ASSERT_TRUE(success); + EXPECT_EQ(bytes_written, bytes_read); success->DestroyThis(); // fail to deserialize if skip goes past input size // (the DeserializationFailures test above tests if the skip is lying) for (size_t i = 0; i < bytes_written - 1; ++i) - EXPECT_FALSE(PaintOp::Deserialize(input_.get(), i, output_.get(), kSize)); + EXPECT_FALSE(PaintOp::Deserialize(input_.get(), i, output_.get(), kSize, + &bytes_read)); // unaligned skips fail to deserialize PaintOp* serialized = reinterpret_cast<PaintOp*>(input_.get()); EXPECT_EQ(0u, serialized->skip % kAlign); serialized->skip -= 1; - EXPECT_FALSE( - PaintOp::Deserialize(input_.get(), bytes_written, output_.get(), kSize)); + EXPECT_FALSE(PaintOp::Deserialize(input_.get(), bytes_written, output_.get(), + kSize, &bytes_read)); serialized->skip += 1; // bogus types fail to deserialize serialized->type = static_cast<uint8_t>(PaintOpType::LastPaintOpType) + 1; - EXPECT_FALSE( - PaintOp::Deserialize(input_.get(), bytes_written, output_.get(), kSize)); + EXPECT_FALSE(PaintOp::Deserialize(input_.get(), bytes_written, output_.get(), + kSize, &bytes_read)); } // Test that deserializing invalid SkClipOp enums fails silently. @@ -2528,13 +2553,16 @@ size_t bytes_written = op->Serialize(serialized.get(), buffer_size, options); ASSERT_GT(bytes_written, 0u); - PaintOp* written = PaintOp::Deserialize(serialized.get(), bytes_written, - deserialized.get(), buffer_size); + size_t bytes_read = 0; + PaintOp* written = + PaintOp::Deserialize(serialized.get(), bytes_written, + deserialized.get(), buffer_size, &bytes_read); // First op should succeed. Other ops with bad enums should // serialize correctly but fail to deserialize due to the bad // SkClipOp enum. if (!op_idx) { EXPECT_TRUE(written) << "op: " << op_idx; + EXPECT_EQ(bytes_written, bytes_read); written->DestroyThis(); } else { EXPECT_FALSE(written) << "op: " << op_idx; @@ -2605,13 +2633,16 @@ size_t bytes_written = op->Serialize(serialized.get(), buffer_size, options); ASSERT_GT(bytes_written, 0u); - PaintOp* written = PaintOp::Deserialize(serialized.get(), bytes_written, - deserialized.get(), buffer_size); + size_t bytes_read = 0; + PaintOp* written = + PaintOp::Deserialize(serialized.get(), bytes_written, + deserialized.get(), buffer_size, &bytes_read); // First two ops should succeed. Other ops with bad enums should // serialize correctly but fail to deserialize due to the bad // SkBlendMode enum. if (op_idx < 2) { EXPECT_TRUE(written) << "op: " << op_idx; + EXPECT_EQ(bytes_written, bytes_read); written->DestroyThis(); } else { EXPECT_FALSE(written) << "op: " << op_idx; @@ -2660,8 +2691,10 @@ size_t bytes_written = op->Serialize(serialized.get(), buffer_size, options); ASSERT_GT(bytes_written, 0u); - PaintOp* written = PaintOp::Deserialize(serialized.get(), bytes_written, - deserialized.get(), buffer_size); + size_t bytes_read = 0; + PaintOp* written = + PaintOp::Deserialize(serialized.get(), bytes_written, + deserialized.get(), buffer_size, &bytes_read); EXPECT_FALSE(written) << "op: " << op_idx; ++op_idx; }
diff --git a/cc/paint/paint_op_reader.cc b/cc/paint/paint_op_reader.cc index cd1e43e..988e007 100644 --- a/cc/paint/paint_op_reader.cc +++ b/cc/paint/paint_op_reader.cc
@@ -34,6 +34,8 @@ template <typename T> void PaintOpReader::ReadSimple(T* val) { + static_assert(base::is_trivially_copyable<T>::value, + "Not trivially copyable"); if (!AlignMemory(alignof(T))) valid_ = false; if (remaining_bytes_ < sizeof(T)) @@ -41,7 +43,11 @@ if (!valid_) return; - *val = reinterpret_cast<const T*>(memory_)[0]; + // Most of the time this is used for primitives, but this function is also + // used for SkRect/SkIRect/SkMatrix whose implicit operator= can't use a + // volatile. TOCTOU violations don't matter for these simple types so + // use assignment. + *val = *reinterpret_cast<const T*>(const_cast<const char*>(memory_)); memory_ += sizeof(T); remaining_bytes_ -= sizeof(T); @@ -60,8 +66,11 @@ if (bytes == 0) return; + // This is assumed safe from TOCTOU violations as the flattenable + // deserializing function uses an SkReadBuffer which reads each piece of + // memory once much like PaintOpReader does. val->reset(static_cast<T*>(SkValidatingDeserializeFlattenable( - memory_, bytes, T::GetFlattenableType()))); + const_cast<const char*>(memory_), bytes, T::GetFlattenableType()))); if (!val) valid_ = false; @@ -77,7 +86,7 @@ if (bytes == 0) return; - memcpy(data, memory_, bytes); + memcpy(data, const_cast<const char*>(memory_), bytes); memory_ += bytes; remaining_bytes_ -= bytes; } @@ -94,7 +103,7 @@ if (count == 0) return; - memcpy(array, memory_, bytes); + memcpy(array, const_cast<const char*>(memory_), bytes); memory_ += bytes; remaining_bytes_ -= bytes; } @@ -127,8 +136,12 @@ if (!valid_) return; - // TODO(enne): Should the writer write how many bytes it expects as well? - size_t read_bytes = path->readFromMemory(memory_, remaining_bytes_); + // This is assumed safe from TOCTOU violations as the SkPath deserializing + // function uses an SkRBuffer which reads each piece of memory once much + // like PaintOpReader does. Additionally, paths are later validated in + // PaintOpBuffer. + size_t read_bytes = + path->readFromMemory(const_cast<const char*>(memory_), remaining_bytes_); if (!read_bytes) valid_ = false; @@ -177,7 +190,9 @@ *data = SkData::MakeEmpty(); return; } - *data = SkData::MakeWithCopy(memory_, bytes); + + // This is safe to cast away the volatile as it is just a memcpy internally. + *data = SkData::MakeWithCopy(const_cast<const char*>(memory_), bytes); memory_ += bytes; remaining_bytes_ -= bytes;
diff --git a/cc/paint/paint_op_reader.h b/cc/paint/paint_op_reader.h index 376a7bc..8f1e9ac 100644 --- a/cc/paint/paint_op_reader.h +++ b/cc/paint/paint_op_reader.h
@@ -18,8 +18,8 @@ // read functions. class CC_PAINT_EXPORT PaintOpReader { public: - PaintOpReader(const void* memory, size_t size) - : memory_(static_cast<const char*>(memory) + + PaintOpReader(const volatile void* memory, size_t size) + : memory_(static_cast<const volatile char*>(memory) + PaintOpWriter::HeaderBytes()), remaining_bytes_(size - PaintOpWriter::HeaderBytes()) { if (size < PaintOpWriter::HeaderBytes()) @@ -77,7 +77,7 @@ // is unsufficient bytes remaining to do this padding. bool AlignMemory(size_t alignment); - const char* memory_ = nullptr; + const volatile char* memory_ = nullptr; size_t remaining_bytes_ = 0u; bool valid_ = true; };
diff --git a/cc/raster/staging_buffer_pool.cc b/cc/raster/staging_buffer_pool.cc index a053fc3..e5951e7 100644 --- a/cc/raster/staging_buffer_pool.cc +++ b/cc/raster/staging_buffer_pool.cc
@@ -112,16 +112,14 @@ const uint64_t tracing_process_id = base::trace_event::MemoryDumpManager::GetInstance() ->GetTracingProcessId(); - auto shared_buffer_guid = - gpu_memory_buffer->GetGUIDForTracing(tracing_process_id); - auto shared_memory_guid = gpu_memory_buffer->GetHandle().handle.GetGUID(); const int kImportance = 2; if (!shared_memory_guid.is_empty()) { pmd->CreateSharedMemoryOwnershipEdge(buffer_dump->guid(), - shared_buffer_guid, shared_memory_guid, - kImportance); + shared_memory_guid, kImportance); } else { + auto shared_buffer_guid = + gpu_memory_buffer->GetGUIDForTracing(tracing_process_id); pmd->CreateSharedGlobalAllocatorDump(shared_buffer_guid); pmd->AddOwnershipEdge(buffer_dump->guid(), shared_buffer_guid, kImportance); }
diff --git a/cc/resources/resource_provider.cc b/cc/resources/resource_provider.cc index f4f1a64..9312ed556 100644 --- a/cc/resources/resource_provider.cc +++ b/cc/resources/resource_provider.cc
@@ -1253,7 +1253,12 @@ viz::ResourceId resource_id) : resource_provider_(resource_provider), resource_id_(resource_id) { const Resource* resource = resource_provider->LockForRead(resource_id); - if (resource->gl_id) { + if (resource_provider_->resource_sk_image_.find(resource_id) != + resource_provider_->resource_sk_image_.end()) { + // Use cached sk_image. + sk_image_ = + resource_provider_->resource_sk_image_.find(resource_id)->second; + } else if (resource->gl_id) { GrGLTextureInfo texture_info; texture_info.fID = resource->gl_id; texture_info.fTarget = resource->target; @@ -2104,8 +2109,8 @@ const int kImportance = 2; if (!shared_memory_guid.is_empty()) { - pmd->CreateSharedMemoryOwnershipEdge(dump->guid(), guid, - shared_memory_guid, kImportance); + pmd->CreateSharedMemoryOwnershipEdge(dump->guid(), shared_memory_guid, + kImportance); } else { pmd->CreateSharedGlobalAllocatorDump(guid); pmd->AddOwnershipEdge(dump->guid(), guid, kImportance);
diff --git a/cc/resources/resource_provider.h b/cc/resources/resource_provider.h index 3a68b0b..ad5eb0b 100644 --- a/cc/resources/resource_provider.h +++ b/cc/resources/resource_provider.h
@@ -802,6 +802,7 @@ bool lost_context_provider_; viz::ResourceId next_id_; ResourceMap resources_; + base::flat_map<viz::ResourceId, sk_sp<SkImage>> resource_sk_image_; int next_child_; ChildMap children_; scoped_refptr<Fence> current_read_lock_fence_;
diff --git a/cc/test/layer_tree_test.cc b/cc/test/layer_tree_test.cc index 5a41348..d3a4f3c 100644 --- a/cc/test/layer_tree_test.cc +++ b/cc/test/layer_tree_test.cc
@@ -827,6 +827,8 @@ gpu_memory_buffer_manager_.reset(new TestGpuMemoryBufferManager); task_graph_runner_.reset(new TestTaskGraphRunner); + if (mode == CompositorMode::THREADED) + settings_.commit_to_active_tree = false; // Spend less time waiting for BeginFrame because the output is // mocked out. settings_.background_animation_rate = 200.0;
diff --git a/cc/tiles/tile_manager_unittest.cc b/cc/tiles/tile_manager_unittest.cc index 8cdad6d2..16fd412 100644 --- a/cc/tiles/tile_manager_unittest.cc +++ b/cc/tiles/tile_manager_unittest.cc
@@ -2325,6 +2325,7 @@ LayerTreeSettings CreateSettings() override { LayerTreeSettings settings; + settings.commit_to_active_tree = false; settings.enable_checker_imaging = true; settings.resource_settings.buffer_to_texture_target_map = viz::DefaultBufferToTextureTargetMapForTesting();
diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc index f34b3a4..0b469b50 100644 --- a/cc/trees/layer_tree_host.cc +++ b/cc/trees/layer_tree_host.cc
@@ -1085,7 +1085,7 @@ DCHECK(!LayerById(layer->id())); DCHECK(!in_paint_layer_contents_); layer_id_map_[layer->id()] = layer; - if (layer->element_id()) { + if (!settings_.use_layer_lists && layer->element_id()) { mutator_host_->RegisterElement(layer->element_id(), ElementListType::ACTIVE); } @@ -1094,7 +1094,7 @@ void LayerTreeHost::UnregisterLayer(Layer* layer) { DCHECK(LayerById(layer->id())); DCHECK(!in_paint_layer_contents_); - if (layer->element_id()) { + if (!settings_.use_layer_lists && layer->element_id()) { mutator_host_->UnregisterElement(layer->element_id(), ElementListType::ACTIVE); }
diff --git a/cc/trees/layer_tree_host.h b/cc/trees/layer_tree_host.h index 2b5f0aca..6988a90a 100644 --- a/cc/trees/layer_tree_host.h +++ b/cc/trees/layer_tree_host.h
@@ -65,9 +65,8 @@ struct RenderingStats; struct ScrollAndScaleSet; -class CC_EXPORT LayerTreeHost - : public NON_EXPORTED_BASE(viz::SurfaceReferenceOwner), - public NON_EXPORTED_BASE(MutatorHostClient) { +class CC_EXPORT LayerTreeHost : public viz::SurfaceReferenceOwner, + public MutatorHostClient { public: struct CC_EXPORT InitParams { LayerTreeHostClient* client = nullptr;
diff --git a/cc/trees/layer_tree_host_common_unittest.cc b/cc/trees/layer_tree_host_common_unittest.cc index 2af1ab53..8c430ea 100644 --- a/cc/trees/layer_tree_host_common_unittest.cc +++ b/cc/trees/layer_tree_host_common_unittest.cc
@@ -230,7 +230,7 @@ gfx::Size device_viewport_size = gfx::Size(root_layer->bounds().width() * device_scale_factor, root_layer->bounds().height() * device_scale_factor); - update_layer_list_impl_.reset(new LayerImplList); + update_layer_impl_list_.reset(new LayerImplList); root_layer->layer_tree_impl()->BuildLayerListForTesting(); PropertyTrees* property_trees = root_layer->layer_tree_impl()->property_trees(); @@ -243,9 +243,9 @@ root_layer, property_trees, can_adjust_raster_scales); draw_property_utils::FindLayersThatNeedUpdates( root_layer->layer_tree_impl(), property_trees, - update_layer_list_impl_.get()); + update_layer_impl_list_.get()); draw_property_utils::ComputeDrawPropertiesOfVisibleLayers( - update_layer_list_impl(), property_trees); + update_layer_impl_list(), property_trees); } void ExecuteCalculateDrawPropertiesWithoutAdjustingRasterScales( @@ -262,8 +262,8 @@ LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); } - bool UpdateLayerListImplContains(int id) const { - for (auto* layer : *update_layer_list_impl_) { + bool UpdateLayerImplListContains(int id) const { + for (auto* layer : *update_layer_impl_list_) { if (layer->id() == id) return true; } @@ -281,8 +281,8 @@ const RenderSurfaceList* render_surface_list_impl() const { return render_surface_list_impl_.get(); } - const LayerImplList* update_layer_list_impl() const { - return update_layer_list_impl_.get(); + const LayerImplList* update_layer_impl_list() const { + return update_layer_impl_list_.get(); } const LayerList& update_layer_list() const { return update_layer_list_; } @@ -295,7 +295,7 @@ private: std::unique_ptr<RenderSurfaceList> render_surface_list_impl_; LayerList update_layer_list_; - std::unique_ptr<LayerImplList> update_layer_list_impl_; + std::unique_ptr<LayerImplList> update_layer_impl_list_; }; class LayerTreeHostCommonTest : public LayerTreeHostCommonTestBase, @@ -3750,10 +3750,10 @@ EXPECT_EQ(GetRenderSurface(back_facing_child_of_back_facing_surface), GetRenderSurface(back_facing_surface)); - EXPECT_EQ(3u, update_layer_list_impl()->size()); - EXPECT_TRUE(UpdateLayerListImplContains(front_facing_child->id())); - EXPECT_TRUE(UpdateLayerListImplContains(front_facing_surface->id())); - EXPECT_TRUE(UpdateLayerListImplContains( + EXPECT_EQ(3u, update_layer_impl_list()->size()); + EXPECT_TRUE(UpdateLayerImplListContains(front_facing_child->id())); + EXPECT_TRUE(UpdateLayerImplListContains(front_facing_surface->id())); + EXPECT_TRUE(UpdateLayerImplListContains( front_facing_child_of_front_facing_surface->id())); } @@ -3865,11 +3865,11 @@ EXPECT_EQ(GetRenderSurface(back_facing_child_of_back_facing_surface), GetRenderSurface(back_facing_surface)); - EXPECT_EQ(3u, update_layer_list_impl()->size()); + EXPECT_EQ(3u, update_layer_impl_list()->size()); - EXPECT_TRUE(UpdateLayerListImplContains(front_facing_child->id())); - EXPECT_TRUE(UpdateLayerListImplContains(front_facing_surface->id())); - EXPECT_TRUE(UpdateLayerListImplContains( + EXPECT_TRUE(UpdateLayerImplListContains(front_facing_child->id())); + EXPECT_TRUE(UpdateLayerImplListContains(front_facing_surface->id())); + EXPECT_TRUE(UpdateLayerImplListContains( front_facing_child_of_front_facing_surface->id())); } @@ -3936,11 +3936,11 @@ EXPECT_EQ(GetRenderSurface(animating_child), GetRenderSurface(root)); EXPECT_EQ(GetRenderSurface(child2), GetRenderSurface(root)); - EXPECT_EQ(1u, update_layer_list_impl()->size()); + EXPECT_EQ(1u, update_layer_impl_list()->size()); // The back facing layers are culled from the layer list, and have an empty // visible rect. - EXPECT_TRUE(UpdateLayerListImplContains(child2->id())); + EXPECT_TRUE(UpdateLayerImplListContains(child2->id())); EXPECT_TRUE(child->visible_layer_rect().IsEmpty()); EXPECT_TRUE(animating_surface->visible_layer_rect().IsEmpty()); EXPECT_TRUE(child_of_animating_surface->visible_layer_rect().IsEmpty()); @@ -3997,9 +3997,9 @@ EXPECT_EQ(GetRenderSurface(child1), GetRenderSurface(front_facing_surface)); EXPECT_EQ(GetRenderSurface(child2), GetRenderSurface(back_facing_surface)); - EXPECT_EQ(2u, update_layer_list_impl()->size()); - EXPECT_TRUE(UpdateLayerListImplContains(front_facing_surface->id())); - EXPECT_TRUE(UpdateLayerListImplContains(child1->id())); + EXPECT_EQ(2u, update_layer_impl_list()->size()); + EXPECT_TRUE(UpdateLayerImplListContains(front_facing_surface->id())); + EXPECT_TRUE(UpdateLayerImplListContains(child1->id())); } TEST_F(LayerTreeHostCommonScalingTest, LayerTransformsInHighDPI) { @@ -8127,6 +8127,7 @@ inner_viewport_scroll_layer->SetIsContainerForFixedPositionLayers(true); outer_viewport_scroll_layer->SetIsContainerForFixedPositionLayers(true); + outer_viewport_scroll_layer->SetIsResizedByBrowserControls(true); host()->SetRootLayer(root); LayerTreeHost::ViewportLayers viewport_layers;
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc index d4eb1ae..00d6ee4 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc
@@ -861,7 +861,8 @@ render_surface->EffectTreeIndex() == EffectTree::kContentsRootNodeId; bool should_draw_into_render_pass = is_root_surface || render_surface->contributes_to_drawn_surface() || - render_surface->HasCopyRequest(); + render_surface->HasCopyRequest() || + render_surface->ShouldCacheRenderSurface(); if (should_draw_into_render_pass) frame->render_passes.push_back(render_surface->CreateRenderPass()); } @@ -4435,9 +4436,7 @@ } bool LayerTreeHostImpl::CommitToActiveTree() const { - // In single threaded mode we skip the pending tree and commit directly to the - // active tree. - return !task_runner_provider_->HasImplThread(); + return settings_.commit_to_active_tree; } void LayerTreeHostImpl::SetContextVisibility(bool is_visible) {
diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h index 6572be2..73b23ca 100644 --- a/cc/trees/layer_tree_host_impl.h +++ b/cc/trees/layer_tree_host_impl.h
@@ -435,9 +435,7 @@ const LayerTreeImpl* recycle_tree() const { return recycle_tree_.get(); } // Returns the tree LTH synchronizes with. LayerTreeImpl* sync_tree() const { - // TODO(enne): This is bogus. It should return based on the value of - // CommitToActiveTree() and not whether the pending tree exists. - return pending_tree_ ? pending_tree_.get() : active_tree_.get(); + return CommitToActiveTree() ? active_tree_.get() : pending_tree_.get(); } virtual void CreatePendingTree(); virtual void ActivateSyncTree();
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc index eddb892b..14e5290 100644 --- a/cc/trees/layer_tree_host_impl_unittest.cc +++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -567,9 +567,6 @@ } void TestGPUMemoryForTilings(const gfx::Size& layer_size) { - LayerTreeSettings settings = DefaultSettings(); - CreateHostImpl(settings, CreateLayerTreeFrameSink()); - std::unique_ptr<FakeRecordingSource> recording_source = FakeRecordingSource::CreateFilledRecordingSource(layer_size); PaintImage checkerable_image = @@ -680,6 +677,15 @@ std::unique_ptr<base::Thread> image_worker_; }; +class CommitToPendingTreeLayerTreeHostImplTest : public LayerTreeHostImplTest { + public: + void SetUp() override { + LayerTreeSettings settings = DefaultSettings(); + settings.commit_to_active_tree = false; + CreateHostImpl(settings, CreateLayerTreeFrameSink()); + } +}; + // A test fixture for new animation timelines tests. class LayerTreeHostImplTimelinesTest : public LayerTreeHostImplTest { public: @@ -934,7 +940,8 @@ 1); } -TEST_F(LayerTreeHostImplTest, GPUMemoryForSmallLayerHistogramTest) { +TEST_F(CommitToPendingTreeLayerTreeHostImplTest, + GPUMemoryForSmallLayerHistogramTest) { base::HistogramTester histogram_tester; SetClientNameForMetrics("Renderer"); // With default tile size being set to 256 * 256, the following layer needs @@ -946,7 +953,8 @@ "Compositing.Renderer.GPUMemoryForTilingsInKb", 1); } -TEST_F(LayerTreeHostImplTest, GPUMemoryForLargeLayerHistogramTest) { +TEST_F(CommitToPendingTreeLayerTreeHostImplTest, + GPUMemoryForLargeLayerHistogramTest) { base::HistogramTester histogram_tester; SetClientNameForMetrics("Renderer"); // With default tile size being set to 256 * 256, the following layer needs @@ -1673,7 +1681,8 @@ EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 20), overflow->CurrentScrollOffset()); } -TEST_F(LayerTreeHostImplTest, AnimationSchedulingPendingTree) { +TEST_F(CommitToPendingTreeLayerTreeHostImplTest, + AnimationSchedulingPendingTree) { EXPECT_FALSE(host_impl_->CommitToActiveTree()); host_impl_->SetViewportSize(gfx::Size(50, 50)); @@ -1730,7 +1739,8 @@ EXPECT_FALSE(did_request_commit_); } -TEST_F(LayerTreeHostImplTest, AnimationSchedulingActiveTree) { +TEST_F(CommitToPendingTreeLayerTreeHostImplTest, + AnimationSchedulingActiveTree) { EXPECT_FALSE(host_impl_->CommitToActiveTree()); host_impl_->SetViewportSize(gfx::Size(50, 50)); @@ -4209,7 +4219,8 @@ layer->AddCopyRequest(); } -TEST_F(LayerTreeHostImplTest, PrepareToDrawSucceedsAndFails) { +TEST_F(CommitToPendingTreeLayerTreeHostImplTest, + PrepareToDrawSucceedsAndFails) { std::vector<PrepareToDrawSuccessTestCase> cases; // 0. Default case. @@ -9599,9 +9610,9 @@ public: void SetUp() override { LayerTreeSettings settings = DefaultSettings(); + settings.commit_to_active_tree = false; CreateHostImpl(settings, CreateLayerTreeFrameSink()); host_impl_->active_tree()->set_top_controls_height(top_controls_height_); - host_impl_->sync_tree()->set_top_controls_height(top_controls_height_); host_impl_->active_tree()->SetCurrentBrowserControlsShownRatio(1.f); } @@ -10871,7 +10882,8 @@ EXPECT_FALSE(did_request_prepare_tiles_); } -TEST_F(LayerTreeHostImplTest, ExternalTileConstraintReflectedInPendingTree) { +TEST_F(CommitToPendingTreeLayerTreeHostImplTest, + ExternalTileConstraintReflectedInPendingTree) { EXPECT_FALSE(host_impl_->CommitToActiveTree()); const gfx::Size layer_size(100, 100); host_impl_->SetViewportSize(layer_size); @@ -12704,6 +12716,7 @@ TEST_F(LayerTreeHostImplTest, CheckerImagingTileInvalidation) { LayerTreeSettings settings = DefaultSettings(); + settings.commit_to_active_tree = false; settings.enable_checker_imaging = true; settings.default_tile_size = gfx::Size(256, 256); settings.max_untiled_layer_size = gfx::Size(256, 256);
diff --git a/cc/trees/layer_tree_host_unittest_animation.cc b/cc/trees/layer_tree_host_unittest_animation.cc index a66d26c..6cec0f01 100644 --- a/cc/trees/layer_tree_host_unittest_animation.cc +++ b/cc/trees/layer_tree_host_unittest_animation.cc
@@ -304,7 +304,7 @@ return; // Wait for the commit with the animation to happen. - if (host_impl->sync_tree()->source_frame_number() != 0) + if (host_impl->active_tree()->source_frame_number() != 0) return; scoped_refptr<AnimationTimeline> timeline_impl =
diff --git a/cc/trees/layer_tree_host_unittest_picture.cc b/cc/trees/layer_tree_host_unittest_picture.cc index 6579662..b92a4aa4 100644 --- a/cc/trees/layer_tree_host_unittest_picture.cc +++ b/cc/trees/layer_tree_host_unittest_picture.cc
@@ -342,7 +342,7 @@ LayerImpl* gchild = impl->sync_tree()->LayerById(picture_->id()); FakePictureLayerImpl* picture = static_cast<FakePictureLayerImpl*>(gchild); - switch (impl->sync_tree()->source_frame_number()) { + switch (impl->active_tree()->source_frame_number()) { case 0: // On 1st commit the layer has tilings. EXPECT_GT(picture->tilings()->num_tilings(), 0u); @@ -359,7 +359,7 @@ } void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override { - LayerImpl* gchild = impl->sync_tree()->LayerById(picture_->id()); + LayerImpl* gchild = impl->active_tree()->LayerById(picture_->id()); FakePictureLayerImpl* picture = static_cast<FakePictureLayerImpl*>(gchild); switch (impl->active_tree()->source_frame_number()) { @@ -400,7 +400,7 @@ scoped_refptr<FakePictureLayer> picture_; }; -SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostPictureTestRSLLMembership); +SINGLE_THREAD_TEST_F(LayerTreeHostPictureTestRSLLMembership); class LayerTreeHostPictureTestRSLLMembershipWithScale : public LayerTreeHostPictureTest { @@ -614,7 +614,7 @@ FakePictureLayerImpl* normal_layer = static_cast<FakePictureLayerImpl*>( impl->active_tree()->LayerById(normal_layer_->id())); - switch (impl->sync_tree()->source_frame_number()) { + switch (impl->active_tree()->source_frame_number()) { case 0: // On first commit, both layers are at the default scale. ASSERT_EQ(1u, will_change_layer->tilings()->num_tilings()); @@ -682,7 +682,7 @@ scoped_refptr<FakePictureLayer> normal_layer_; }; -SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostPictureTestForceRecalculateScales); +SINGLE_THREAD_TEST_F(LayerTreeHostPictureTestForceRecalculateScales); } // namespace } // namespace cc
diff --git a/cc/trees/layer_tree_host_unittest_proxy.cc b/cc/trees/layer_tree_host_unittest_proxy.cc index 27e2835..12e0283 100644 --- a/cc/trees/layer_tree_host_unittest_proxy.cc +++ b/cc/trees/layer_tree_host_unittest_proxy.cc
@@ -335,7 +335,9 @@ void BeginTest() override { PostSetNeedsCommitToMainThread(); } void ReadyToCommitOnThread(LayerTreeHostImpl* impl) override { - switch (impl->sync_tree()->source_frame_number()) { + LayerTreeImpl* sync_tree = + impl->pending_tree() ? impl->pending_tree() : impl->active_tree(); + switch (sync_tree->source_frame_number()) { case -1: // Block the activation of the initial commit until the second main // frame is ready.
diff --git a/cc/trees/layer_tree_settings.h b/cc/trees/layer_tree_settings.h index 03a2b69..da47d91 100644 --- a/cc/trees/layer_tree_settings.h +++ b/cc/trees/layer_tree_settings.h
@@ -121,6 +121,19 @@ // completed the current BeginFrame before triggering their own BeginFrame // deadlines. bool wait_for_all_pipeline_stages_before_draw = false; + + // On a low-end android devices where the GPU memory is low, we are reducing + // the tile width to half in the cases where the content width > screen width. + // This doesn't impact CPU tile size, and we should see an obvious GPU memory + // saving. + bool use_half_width_tiles_for_gpu_rasterization = false; + + // Whether layer tree commits should be made directly to the active + // tree on the impl thread. If |false| LayerTreeHostImpl creates a + // pending layer tree and produces that as the 'sync tree' with + // which LayerTreeHost synchronizes. If |true| LayerTreeHostImpl + // produces the active tree as its 'sync tree'. + bool commit_to_active_tree = true; }; } // namespace cc
diff --git a/cc/trees/property_tree_builder.cc b/cc/trees/property_tree_builder.cc index ac367b9..8d9799b 100644 --- a/cc/trees/property_tree_builder.cc +++ b/cc/trees/property_tree_builder.cc
@@ -377,7 +377,7 @@ if (IsContainerForFixedPositionLayers(layer) || is_root) { data_for_children->affected_by_outer_viewport_bounds_delta = - layer == data_from_ancestor.outer_viewport_scroll_layer; + layer->IsResizedByBrowserControls(); if (is_scrollable) { DCHECK(Transform(layer).IsIdentity()); data_for_children->transform_fixed_parent = Parent(layer);
diff --git a/cc/trees/proxy_impl.h b/cc/trees/proxy_impl.h index af992ef7..bf613e7 100644 --- a/cc/trees/proxy_impl.h +++ b/cc/trees/proxy_impl.h
@@ -22,8 +22,8 @@ // This class aggregates all the interactions that the main side of the // compositor needs to have with the impl side. // The class is created and lives on the impl thread. -class CC_EXPORT ProxyImpl : public NON_EXPORTED_BASE(LayerTreeHostImplClient), - public NON_EXPORTED_BASE(SchedulerClient) { +class CC_EXPORT ProxyImpl : public LayerTreeHostImplClient, + public SchedulerClient { public: ProxyImpl(base::WeakPtr<ProxyMain> proxy_main_weak_ptr, LayerTreeHost* layer_tree_host,
diff --git a/cc/trees/single_thread_proxy.h b/cc/trees/single_thread_proxy.h index 7d9b238..4dd282cb 100644 --- a/cc/trees/single_thread_proxy.h +++ b/cc/trees/single_thread_proxy.h
@@ -28,7 +28,7 @@ class LayerTreeHostSingleThreadClient; class CC_EXPORT SingleThreadProxy : public Proxy, - NON_EXPORTED_BASE(LayerTreeHostImplClient), + LayerTreeHostImplClient, public SchedulerClient { public: static std::unique_ptr<Proxy> Create(
diff --git a/chrome/BUILD.gn b/chrome/BUILD.gn index e56a06b..79619bf 100644 --- a/chrome/BUILD.gn +++ b/chrome/BUILD.gn
@@ -1566,7 +1566,6 @@ if (is_chromeos) { public_deps += [ - "//chrome/browser/resources:options_resources", "//chrome/browser/resources/chromeos/chromevox", "//chrome/browser/resources/chromeos/select_to_speak", "//chrome/browser/resources/chromeos/switch_access",
diff --git a/chrome/VERSION b/chrome/VERSION index 3c17dd0..d8153e1 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=62 MINOR=0 -BUILD=3187 +BUILD=3188 PATCH=0
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index 73b5325..9ca7ba2 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -39,9 +39,8 @@ app_hooks_impl = "java/src/org/chromium/chrome/browser/AppHooksImpl.java" if (enable_resource_whitelist_generation) { - # Path cannot depend on cur_toolchain. monochrome_resource_whitelist = - "$root_build_dir/monochrome_resource_whitelist.txt" + "$target_gen_dir/monochrome_resource_whitelist.txt" system_webview_locale_resource_id_list = "$target_gen_dir/system_webview_locale_resource_id_list.txt" monochrome_locale_whitelist = @@ -718,30 +717,6 @@ public_configs = extra_chrome_shared_library_configs } -# For why we defined the whitelist target in $fat_lib_toolchain rather than -# just using :monochrome($fat_lib_toolchain) as a dep, see crbug.com/749003. -if (enable_resource_whitelist_generation) { - if (!android_64bit_target_cpu) { - fat_lib_toolchain = current_toolchain - } else { - fat_lib_toolchain = android_secondary_abi_toolchain - } - - # Always use the 32-bit library's whitelist since the 64-bit one is - # webview-only. - if (current_toolchain == fat_lib_toolchain) { - generate_resource_whitelist("monochrome_resource_whitelist") { - deps = [ - ":monochrome", - ] - - input = get_label_info(deps[0], "root_out_dir") + - "/libmonochrome$shlib_extension.whitelist" - output = monochrome_resource_whitelist - } - } -} - # Ensure that .pak files are built only once (build them in the default # toolchain). The central header file calling JNI registration functions # is generated from Java code so it just needs to be generated once. @@ -760,6 +735,23 @@ } if (enable_resource_whitelist_generation) { + generate_resource_whitelist("monochrome_resource_whitelist") { + # Always use the 32-bit library's whitelist since the 64-bit one is + # webview-only. + if (!android_64bit_target_cpu) { + _fat_lib_toolchain = current_toolchain + } else { + _fat_lib_toolchain = android_secondary_abi_toolchain + } + deps = [ + ":monochrome($_fat_lib_toolchain)", + ] + + input = get_label_info(deps[0], "root_out_dir") + + "/libmonochrome$shlib_extension.whitelist" + output = monochrome_resource_whitelist + } + # Use custom resource ID list instead of android_webview's compiler # resource whitelist because //android_webview: generate_webui_resources # and //android_webview: generate_components_resources use hand-written @@ -803,7 +795,7 @@ ] deps = [ - ":monochrome_resource_whitelist($fat_lib_toolchain)", + ":monochrome_resource_whitelist", ":system_webview_locale_resource_id_list", "//android_webview:system_webview_pak_whitelist", ] @@ -829,7 +821,7 @@ if (enable_resource_whitelist_generation) { repack_whitelist = monochrome_resource_whitelist - deps += [ ":monochrome_resource_whitelist($fat_lib_toolchain)" ] + deps += [ ":monochrome_resource_whitelist" ] locale_whitelist = monochrome_locale_whitelist deps += [ ":monochrome_locale_whitelist" ] }
diff --git a/chrome/android/java/AndroidManifest.xml b/chrome/android/java/AndroidManifest.xml index d469ca2..8059930 100644 --- a/chrome/android/java/AndroidManifest.xml +++ b/chrome/android/java/AndroidManifest.xml
@@ -747,6 +747,11 @@ android:exported="false"> </service> + <!-- Download broadcast manager service --> + <service android:name="org.chromium.chrome.browser.download.DownloadBroadcastManager" + android:exported="false"> + </service> + <!-- Bookmarks widget --> <receiver android:name="com.google.android.apps.chrome.appwidget.bookmarks.BookmarkThumbnailWidgetProvider" android:label="@string/bookmark_widget_title">
diff --git a/chrome/android/java/res/layout/accessibility_tab_switcher_list_item.xml b/chrome/android/java/res/layout/accessibility_tab_switcher_list_item.xml index f8957e7..4b0346f5 100644 --- a/chrome/android/java/res/layout/accessibility_tab_switcher_list_item.xml +++ b/chrome/android/java/res/layout/accessibility_tab_switcher_list_item.xml
@@ -49,7 +49,6 @@ android:minWidth="48dp" android:padding="4dp" android:background="?attr/selectableItemBackground" - android:contentDescription="@string/accessibility_tabstrip_btn_close_tab" android:src="@drawable/btn_close" chrome:chrometint="@color/light_mode_tint" android:gravity="end|center_vertical" />
diff --git a/chrome/android/java/res/layout/suggestions_bottom_sheet_content.xml b/chrome/android/java/res/layout/suggestions_bottom_sheet_content.xml index cec7ada..d3956e1 100644 --- a/chrome/android/java/res/layout/suggestions_bottom_sheet_content.xml +++ b/chrome/android/java/res/layout/suggestions_bottom_sheet_content.xml
@@ -18,7 +18,7 @@ <org.chromium.chrome.browser.suggestions.SuggestionsRecyclerView android:id="@+id/recycler_view" android:layout_width="match_parent" - android:layout_height="wrap_content" + android:layout_height="match_parent" android:paddingTop="@dimen/bottom_control_container_height" /> <org.chromium.chrome.browser.widget.FadingShadowView @@ -28,4 +28,4 @@ android:layout_marginTop="@dimen/bottom_control_container_height" android:visibility="gone" /> -</FrameLayout> \ No newline at end of file +</FrameLayout>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/SingleTabActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/SingleTabActivity.java index 801b65d..6c6f0822 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/SingleTabActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/SingleTabActivity.java
@@ -16,6 +16,7 @@ import org.chromium.chrome.browser.tabmodel.TabModel.TabSelectionType; import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.tabmodel.document.TabDelegate; +import org.chromium.content_public.browser.ChildProcessImportance; import org.chromium.content_public.browser.LoadUrlParams; import java.io.File; @@ -66,6 +67,7 @@ Tab tab = createTab(); getTabModelSelector().setTab(tab); tab.show(TabSelectionType.FROM_NEW); + tab.setImportance(ChildProcessImportance.MODERATE); } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java index 6ade3dce..f2335f3 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java
@@ -420,7 +420,7 @@ /** * @return The SurfaceView proxy used by the Compositor. */ - public View getCompositorView() { + public CompositorView getCompositorView() { return mCompositorView; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java index 20f8297f..73980a0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java
@@ -1823,6 +1823,6 @@ } builder.append(mContext.getResources().getString(resId)); - stripTab.setAccessibilityDescription(builder.toString()); + stripTab.setAccessibilityDescription(builder.toString(), title); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutTab.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutTab.java index 0136fed8..634982e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutTab.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutTab.java
@@ -9,6 +9,7 @@ import android.content.Context; import android.graphics.RectF; +import org.chromium.base.ContextUtils; import org.chromium.base.ObserverList; import org.chromium.base.VisibleForTesting; import org.chromium.chrome.R; @@ -151,9 +152,6 @@ mCloseButton.setIncognito(mIncognito); mCloseButton.setBounds(getCloseRect()); mCloseButton.setClickSlop(0.f); - String description = - context.getResources().getString(R.string.accessibility_tabstrip_btn_close_tab); - mCloseButton.setAccessibilityDescription(description, description); } /** @param observer The observer to add. */ @@ -178,10 +176,15 @@ } /** + * Set strip tab and close button accessibility description. * @param description A description for accessibility events. + * @param title The title of the tab. */ - public void setAccessibilityDescription(String description) { + public void setAccessibilityDescription(String description, String title) { mAccessibilityDescription = description; + String closeButtonDescription = ContextUtils.getApplicationContext().getString( + R.string.accessibility_tabstrip_btn_close_tab, title); + mCloseButton.setAccessibilityDescription(closeButtonDescription, closeButtonDescription); } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadBroadcastManager.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadBroadcastManager.java index 9dd140b..a13eb86 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadBroadcastManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadBroadcastManager.java
@@ -4,21 +4,32 @@ package org.chromium.chrome.browser.download; +import static android.app.DownloadManager.ACTION_NOTIFICATION_CLICKED; + import static org.chromium.chrome.browser.download.DownloadNotificationService.ACTION_DOWNLOAD_CANCEL; import static org.chromium.chrome.browser.download.DownloadNotificationService.ACTION_DOWNLOAD_OPEN; import static org.chromium.chrome.browser.download.DownloadNotificationService.ACTION_DOWNLOAD_PAUSE; import static org.chromium.chrome.browser.download.DownloadNotificationService.ACTION_DOWNLOAD_RESUME; -import static org.chromium.chrome.browser.download.DownloadNotificationService.ACTION_DOWNLOAD_RESUME_ALL; +import static org.chromium.chrome.browser.download.DownloadNotificationService.EXTRA_DOWNLOAD_CONTENTID_ID; +import static org.chromium.chrome.browser.download.DownloadNotificationService.EXTRA_DOWNLOAD_CONTENTID_NAMESPACE; import static org.chromium.chrome.browser.download.DownloadNotificationService.EXTRA_IS_OFF_THE_RECORD; -import static org.chromium.chrome.browser.download.DownloadNotificationService.getContentIdFromIntent; +import static org.chromium.chrome.browser.download.DownloadNotificationService.MAX_RESUMPTION_ATTEMPT_LEFT; import static org.chromium.chrome.browser.download.DownloadNotificationService.getServiceDelegate; +import static org.chromium.chrome.browser.download.DownloadNotificationService.updateResumptionAttemptLeft; +import android.app.DownloadManager; +import android.app.Service; +import android.content.ComponentName; import android.content.Context; import android.content.Intent; +import android.net.Uri; import android.os.Handler; +import android.os.IBinder; +import android.support.annotation.Nullable; import com.google.ipc.invalidation.util.Preconditions; +import org.chromium.base.ContextUtils; import org.chromium.base.Log; import org.chromium.base.VisibleForTesting; import org.chromium.base.library_loader.ProcessInitException; @@ -27,6 +38,7 @@ import org.chromium.chrome.browser.init.BrowserParts; import org.chromium.chrome.browser.init.ChromeBrowserInitializer; import org.chromium.chrome.browser.init.EmptyBrowserParts; +import org.chromium.chrome.browser.notifications.NotificationConstants; import org.chromium.chrome.browser.offlinepages.downloads.OfflinePageDownloadBridge; import org.chromium.chrome.browser.util.IntentUtils; import org.chromium.components.offline_items_collection.ContentId; @@ -36,7 +48,7 @@ * Class that spins up native when an interaction with a notification happens and passes the * relevant information on to native. */ -public class DownloadBroadcastManager { +public class DownloadBroadcastManager extends Service { private static final String TAG = "DLBroadcastManager"; // TODO(jming): Check to see if this wait time is long enough to execute commands on native. private static final int WAIT_TIME_MS = 5000; @@ -44,40 +56,63 @@ private final DownloadSharedPreferenceHelper mDownloadSharedPreferenceHelper = DownloadSharedPreferenceHelper.getInstance(); + private final Context mApplicationContext; private final Handler mHandler = new Handler(); private final Runnable mStopSelfRunnable = new Runnable() { @Override public void run() { - // TODO(jming): Add stopSelf() call when this becomes a service. + stopSelf(); } }; - public DownloadBroadcastManager() {} + public DownloadBroadcastManager() { + mApplicationContext = ContextUtils.getApplicationContext(); + } + + public static void startDownloadBroadcastManager(Context context, Intent source) { + Intent intent = source != null ? new Intent(source) : new Intent(); + intent.setComponent(new ComponentName(context, DownloadBroadcastManager.class)); + context.startService(intent); + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + // Handle the download operation. + onNotificationInteraction(intent); + + // Handle resumption tracking logic. + DownloadResumptionScheduler.getDownloadResumptionScheduler(mApplicationContext) + .cancelTask(); + updateResumptionAttemptLeft(MAX_RESUMPTION_ATTEMPT_LEFT); + + // If Chrome gets killed, do not restart the service. + return START_NOT_STICKY; + } /** * Passes down information about a notification interaction to native. - * TODO(jming): Move this call to onStartCommand when this class becomes a service. - * @param context of the interaction. * @param intent with information about the notification interaction (action, contentId, etc). */ - public void onNotificationInteraction(Context context, final Intent intent) { - String action = intent.getAction(); - if (!isActionHandled(action)) return; + public void onNotificationInteraction(final Intent intent) { + if (!isActionHandled(intent)) return; // Remove delayed stop of service until after native library is loaded. mHandler.removeCallbacks(mStopSelfRunnable); + // TODO(jming): When DownloadNotificationService is no longer a service, invoke it to + // propagate immediate notification changes (ie. when pause is clicked, have progress bar be + // paused even before there is an update in native). http://crbug.com/755588 + // Handle the intent and propagate it through the native library. - loadNativeAndPropagateInteraction(context, intent); + loadNativeAndPropagateInteraction(intent); } /** * Helper function that loads the native and runs given runnable. - * @param context of the application. * @param intent that is propagated when the native is loaded. */ @VisibleForTesting - void loadNativeAndPropagateInteraction(Context context, final Intent intent) { + void loadNativeAndPropagateInteraction(final Intent intent) { final BrowserParts parts = new EmptyBrowserParts() { @Override public void finishNativeInitialization() { @@ -91,8 +126,9 @@ }; try { - ChromeBrowserInitializer.getInstance(context).handlePreNativeStartup(parts); - ChromeBrowserInitializer.getInstance(context).handlePostNativeStartup(true, parts); + ChromeBrowserInitializer.getInstance(mApplicationContext).handlePreNativeStartup(parts); + ChromeBrowserInitializer.getInstance(mApplicationContext) + .handlePostNativeStartup(true, parts); } catch (ProcessInitException e) { Log.e(TAG, "Unable to load native library.", e); ChromeApplication.reportStartupErrorAndExit(e); @@ -103,33 +139,40 @@ void propagateInteraction(Intent intent) { String action = intent.getAction(); final ContentId id = getContentIdFromIntent(intent); + + switch (action) { + case ACTION_NOTIFICATION_CLICKED: + openDownload(mApplicationContext, intent, id); + return; + + case ACTION_DOWNLOAD_OPEN: + if (LegacyHelpers.isLegacyOfflinePage(id)) { + OfflinePageDownloadBridge.openDownloadedPage(id); + } else if (id != null) { + OfflineContentAggregatorNotificationBridgeUiFactory.instance().openItem(id); + } + return; + } + final DownloadSharedPreferenceEntry entry = getDownloadEntryFromIntent(intent); boolean isOffTheRecord = entry == null ? IntentUtils.safeGetBooleanExtra(intent, EXTRA_IS_OFF_THE_RECORD, false) : entry.isOffTheRecord; + DownloadServiceDelegate downloadServiceDelegate = getServiceDelegate(id); - DownloadServiceDelegate downloadServiceDelegate = - ACTION_DOWNLOAD_OPEN.equals(action) ? null : getServiceDelegate(id); + Preconditions.checkNotNull(downloadServiceDelegate); + Preconditions.checkNotNull(id); switch (action) { case ACTION_DOWNLOAD_CANCEL: - Preconditions.checkNotNull(downloadServiceDelegate); - Preconditions.checkNotNull(id); - downloadServiceDelegate.cancelDownload(id, isOffTheRecord); break; case ACTION_DOWNLOAD_PAUSE: - Preconditions.checkNotNull(downloadServiceDelegate); - Preconditions.checkNotNull(id); - downloadServiceDelegate.pauseDownload(id, isOffTheRecord); break; case ACTION_DOWNLOAD_RESUME: - Preconditions.checkNotNull(downloadServiceDelegate); - Preconditions.checkNotNull(id); - DownloadInfo info = new DownloadInfo.Builder() .setDownloadGuid(id.id) .setIsOffTheRecord(isOffTheRecord) @@ -139,36 +182,88 @@ id, new DownloadItem(false, info), true /* hasUserGesture */); break; - case ACTION_DOWNLOAD_OPEN: - if (LegacyHelpers.isLegacyOfflinePage(id)) { - OfflinePageDownloadBridge.openDownloadedPage(id); - } else if (id != null) { - OfflineContentAggregatorNotificationBridgeUiFactory.instance().openItem(id); - } - break; - default: // No-op. break; } - if (downloadServiceDelegate != null) downloadServiceDelegate.destroyServiceDelegate(); + downloadServiceDelegate.destroyServiceDelegate(); } - private boolean isActionHandled(String action) { + static boolean isActionHandled(Intent intent) { + if (intent == null) return false; + String action = intent.getAction(); return ACTION_DOWNLOAD_CANCEL.equals(action) || ACTION_DOWNLOAD_PAUSE.equals(action) - || ACTION_DOWNLOAD_RESUME.equals(action) || ACTION_DOWNLOAD_OPEN.equals(action); + || ACTION_DOWNLOAD_RESUME.equals(action) || ACTION_DOWNLOAD_OPEN.equals(action) + || ACTION_NOTIFICATION_CLICKED.equals(action); } /** * Retrieves DownloadSharedPreferenceEntry from a download action intent. - * TODO(jming): Make private when no longer needed by DownloadNotificationService. * TODO(jming): Instead of getting entire entry, pass only id/isOffTheRecord (crbug.com/749323). * @param intent Intent that contains the download action. */ - DownloadSharedPreferenceEntry getDownloadEntryFromIntent(Intent intent) { - if (ACTION_DOWNLOAD_RESUME_ALL.equals(intent.getAction())) return null; + private DownloadSharedPreferenceEntry getDownloadEntryFromIntent(Intent intent) { return mDownloadSharedPreferenceHelper.getDownloadSharedPreferenceEntry( getContentIdFromIntent(intent)); } + + /** + * @param intent The {@link Intent} to pull from and build a {@link ContentId}. + * @return A {@link ContentId} built by pulling extras from {@code intent}. This will be + * {@code null} if {@code intent} is missing any required extras. + */ + private static ContentId getContentIdFromIntent(Intent intent) { + if (!intent.hasExtra(EXTRA_DOWNLOAD_CONTENTID_ID) + || !intent.hasExtra(EXTRA_DOWNLOAD_CONTENTID_NAMESPACE)) { + return null; + } + + return new ContentId( + IntentUtils.safeGetStringExtra(intent, EXTRA_DOWNLOAD_CONTENTID_NAMESPACE), + IntentUtils.safeGetStringExtra(intent, EXTRA_DOWNLOAD_CONTENTID_ID)); + } + + /** + * Called to open a particular download item. Falls back to opening Download Home. + * @param context Context of the receiver. + * @param intent Intent from the android DownloadManager. + */ + private void openDownload(Context context, Intent intent, ContentId contentId) { + int notificationId = IntentUtils.safeGetIntExtra( + intent, NotificationConstants.EXTRA_NOTIFICATION_ID, -1); + DownloadNotificationService.hideDanglingSummaryNotification(context, notificationId); + + long ids[] = + intent.getLongArrayExtra(DownloadManager.EXTRA_NOTIFICATION_CLICK_DOWNLOAD_IDS); + if (ids == null || ids.length == 0) { + DownloadManagerService.openDownloadsPage(context); + return; + } + + long id = ids[0]; + Uri uri = DownloadManagerDelegate.getContentUriFromDownloadManager(context, id); + if (uri == null) { + DownloadManagerService.openDownloadsPage(context); + return; + } + + String downloadFilename = IntentUtils.safeGetStringExtra( + intent, DownloadNotificationService.EXTRA_DOWNLOAD_FILE_PATH); + boolean isSupportedMimeType = IntentUtils.safeGetBooleanExtra( + intent, DownloadNotificationService.EXTRA_IS_SUPPORTED_MIME_TYPE, false); + boolean isOffTheRecord = IntentUtils.safeGetBooleanExtra( + intent, DownloadNotificationService.EXTRA_IS_OFF_THE_RECORD, false); + String originalUrl = IntentUtils.safeGetStringExtra(intent, Intent.EXTRA_ORIGINATING_URI); + String referrer = IntentUtils.safeGetStringExtra(intent, Intent.EXTRA_REFERRER); + DownloadManagerService.openDownloadedContent(context, downloadFilename, isSupportedMimeType, + isOffTheRecord, contentId.id, id, originalUrl, referrer); + } + + @Nullable + @Override + public IBinder onBind(Intent intent) { + // Since this service does not need to be bound, just return null. + return null; + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadBroadcastReceiver.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadBroadcastReceiver.java index b0b894a..7ff533ef 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadBroadcastReceiver.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadBroadcastReceiver.java
@@ -4,15 +4,11 @@ package org.chromium.chrome.browser.download; -import android.app.DownloadManager; +import static org.chromium.chrome.browser.download.DownloadNotificationService.ACTION_DOWNLOAD_UPDATE_SUMMARY_ICON; + import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; -import android.net.Uri; - -import org.chromium.chrome.browser.notifications.NotificationConstants; -import org.chromium.chrome.browser.util.IntentUtils; -import org.chromium.components.offline_items_collection.ContentId; /** * This {@link BroadcastReceiver} handles clicks to download notifications and their action buttons. @@ -24,70 +20,7 @@ public class DownloadBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(final Context context, Intent intent) { - String action = intent.getAction(); - switch (action) { - case DownloadManager.ACTION_NOTIFICATION_CLICKED: - openDownload(context, intent); - break; - case DownloadNotificationService.ACTION_DOWNLOAD_RESUME: - case DownloadNotificationService.ACTION_DOWNLOAD_CANCEL: - case DownloadNotificationService.ACTION_DOWNLOAD_PAUSE: - case DownloadNotificationService.ACTION_DOWNLOAD_OPEN: - case DownloadNotificationService.ACTION_DOWNLOAD_UPDATE_SUMMARY_ICON: - performDownloadOperation(context, intent); - break; - default: - break; - } - } - - /** - * Called to open a particular download item. Falls back to opening Download Home. - * @param context Context of the receiver. - * @param intent Intent from the android DownloadManager. - */ - private void openDownload(final Context context, Intent intent) { - int notificationId = IntentUtils.safeGetIntExtra( - intent, NotificationConstants.EXTRA_NOTIFICATION_ID, -1); - DownloadNotificationService.hideDanglingSummaryNotification(context, notificationId); - - long ids[] = - intent.getLongArrayExtra(DownloadManager.EXTRA_NOTIFICATION_CLICK_DOWNLOAD_IDS); - if (ids == null || ids.length == 0) { - DownloadManagerService.openDownloadsPage(context); - return; - } - - long id = ids[0]; - Uri uri = DownloadManagerDelegate.getContentUriFromDownloadManager(context, id); - if (uri == null) { - DownloadManagerService.openDownloadsPage(context); - return; - } - - String downloadFilename = IntentUtils.safeGetStringExtra( - intent, DownloadNotificationService.EXTRA_DOWNLOAD_FILE_PATH); - boolean isSupportedMimeType = IntentUtils.safeGetBooleanExtra( - intent, DownloadNotificationService.EXTRA_IS_SUPPORTED_MIME_TYPE, false); - boolean isOffTheRecord = IntentUtils.safeGetBooleanExtra( - intent, DownloadNotificationService.EXTRA_IS_OFF_THE_RECORD, false); - String originalUrl = IntentUtils.safeGetStringExtra( - intent, Intent.EXTRA_ORIGINATING_URI); - String referrer = IntentUtils.safeGetStringExtra(intent, Intent.EXTRA_REFERRER); - ContentId contentId = DownloadNotificationService.getContentIdFromIntent(intent); - DownloadManagerService.openDownloadedContent( - context, downloadFilename, isSupportedMimeType, isOffTheRecord, contentId.id, id, - originalUrl, referrer); - } - - /** - * Called to perform a download operation. This will call the DownloadNotificationService - * to start the browser process asynchronously, and resume or cancel the download afterwards. - * @param context Context of the receiver. - * @param intent Intent retrieved from the notification. - */ - private void performDownloadOperation(final Context context, Intent intent) { - if (DownloadNotificationService.isDownloadOperationIntent(intent)) { + if (ACTION_DOWNLOAD_UPDATE_SUMMARY_ICON.equals(intent.getAction())) { DownloadNotificationService.startDownloadNotificationService(context, intent); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationFactory.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationFactory.java index c6848b9..dafe5b0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationFactory.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationFactory.java
@@ -231,10 +231,10 @@ } ComponentName component = new ComponentName( - context.getPackageName(), DownloadBroadcastReceiver.class.getName()); + context.getPackageName(), DownloadBroadcastManager.class.getName()); intent.setComponent(component); builder.setContentIntent( - PendingIntent.getBroadcast(context, downloadUpdate.getNotificationId(), + PendingIntent.getService(context, downloadUpdate.getNotificationId(), intent, PendingIntent.FLAG_UPDATE_CURRENT)); } builder.setDeleteIntent( @@ -292,14 +292,15 @@ */ private static PendingIntent buildPendingIntent( Context context, Intent intent, int notificationId) { - return PendingIntent.getBroadcast( + return PendingIntent.getService( context, notificationId, intent, PendingIntent.FLAG_UPDATE_CURRENT); } private static PendingIntent buildSummaryIconIntent(Context context, int notificationId) { Intent intent = new Intent(context, DownloadBroadcastReceiver.class); intent.setAction(ACTION_DOWNLOAD_UPDATE_SUMMARY_ICON); - return buildPendingIntent(context, intent, notificationId); + return PendingIntent.getBroadcast( + context, notificationId, intent, PendingIntent.FLAG_UPDATE_CURRENT); } /** @@ -312,7 +313,7 @@ public static Intent buildActionIntent( Context context, String action, ContentId id, boolean isOffTheRecord) { ComponentName component = new ComponentName( - context.getPackageName(), DownloadBroadcastReceiver.class.getName()); + context.getPackageName(), DownloadBroadcastManager.class.getName()); Intent intent = new Intent(action); intent.setComponent(component); intent.putExtra(EXTRA_DOWNLOAD_CONTENTID_ID, id != null ? id.id : "");
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationService.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationService.java index 60bf46c..acfbfdc 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationService.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationService.java
@@ -31,7 +31,6 @@ import org.chromium.base.ApplicationStatus; import org.chromium.base.BuildInfo; import org.chromium.base.ContextUtils; -import org.chromium.base.Log; import org.chromium.base.ObserverList; import org.chromium.base.VisibleForTesting; import org.chromium.base.library_loader.LibraryProcessType; @@ -44,7 +43,6 @@ import org.chromium.chrome.browser.notifications.channels.ChannelDefinitions; import org.chromium.chrome.browser.offlinepages.downloads.OfflinePageDownloadBridge; import org.chromium.chrome.browser.profiles.Profile; -import org.chromium.chrome.browser.util.IntentUtils; import org.chromium.components.offline_items_collection.ContentId; import org.chromium.components.offline_items_collection.LegacyHelpers; import org.chromium.components.offline_items_collection.OfflineItem.Progress; @@ -59,7 +57,9 @@ * * On O and above, this service will receive {@link Service#startForeground(int, Notification)} * calls when containing active downloads. The foreground notification will be the summary - * notification generated by {@link DownloadNotificationService#buildSummaryNotification(Context)}. + * notification generated by {@link DownloadNotificationService#buildSummaryNotification(Context, + * NotificationManager)}. + * * The service will receive a {@link Service#stopForeground(boolean)} call when all active downloads * are paused. The summary notification will be hidden when there are no other notifications in the * {@link NotificationConstants#GROUP_DOWNLOADS} group. This gets checked after every notification @@ -71,10 +71,10 @@ static final String EXTRA_DOWNLOAD_CONTENTID_NAMESPACE = "org.chromium.chrome.browser.download.DownloadContentId_Namespace"; static final String EXTRA_DOWNLOAD_FILE_PATH = "DownloadFilePath"; - static final String EXTRA_NOTIFICATION_DISMISSED = "NotificationDismissed"; static final String EXTRA_IS_SUPPORTED_MIME_TYPE = "IsSupportedMimeType"; static final String EXTRA_IS_OFF_THE_RECORD = "org.chromium.chrome.browser.download.IS_OFF_THE_RECORD"; + static final int MAX_RESUMPTION_ATTEMPT_LEFT = 5; public static final String ACTION_DOWNLOAD_CANCEL = "org.chromium.chrome.browser.download.DOWNLOAD_CANCEL"; @@ -97,7 +97,6 @@ "Chrome.NotificationBundleIconIdExtra"; /** Notification Id starting value, to avoid conflicts from IDs used in prior versions. */ private static final int STARTING_NOTIFICATION_ID = 1000000; - private static final int MAX_RESUMPTION_ATTEMPT_LEFT = 5; private static final String KEY_AUTO_RESUMPTION_ATTEMPT_LEFT = "ResumptionAttemptLeft"; private static final String KEY_NEXT_DOWNLOAD_NOTIFICATION_ID = "NextDownloadNotificationId"; @@ -129,10 +128,8 @@ private SharedPreferences mSharedPrefs; private Context mContext; private int mNextNotificationId; - private int mNumAutoResumptionAttemptLeft; private Bitmap mDownloadSuccessLargeIcon; private DownloadSharedPreferenceHelper mDownloadSharedPreferenceHelper; - private DownloadBroadcastManager mDownloadBroadcastManager; /** * @return Whether or not this service should be made a foreground service if there are active @@ -395,12 +392,9 @@ mNotificationManager = (NotificationManager) mContext.getSystemService( Context.NOTIFICATION_SERVICE); mSharedPrefs = ContextUtils.getAppSharedPreferences(); - mNumAutoResumptionAttemptLeft = mSharedPrefs.getInt(KEY_AUTO_RESUMPTION_ATTEMPT_LEFT, - MAX_RESUMPTION_ATTEMPT_LEFT); mDownloadSharedPreferenceHelper = DownloadSharedPreferenceHelper.getInstance(); mNextNotificationId = mSharedPrefs.getInt( KEY_NEXT_DOWNLOAD_NOTIFICATION_ID, STARTING_NOTIFICATION_ID); - mDownloadBroadcastManager = new DownloadBroadcastManager(); } @Override @@ -423,28 +417,25 @@ // into a pending state, then try to restart. Finally validate that we are actually // showing something. updateNotificationsForShutdown(); - handleDownloadOperation( - new Intent(DownloadNotificationService.ACTION_DOWNLOAD_RESUME_ALL)); + resumeAllPendingDownloads(); hideSummaryNotificationIfNecessary(-1); } else if (TextUtils.equals(intent.getAction(), DownloadNotificationService.ACTION_DOWNLOAD_FAIL_SAFE)) { hideSummaryNotificationIfNecessary(-1); - } else if (isDownloadOperationIntent(intent)) { - handleDownloadOperation(intent); - DownloadResumptionScheduler.getDownloadResumptionScheduler(mContext).cancelTask(); - // Limit the number of auto resumption attempts in case Chrome falls into a vicious - // cycle. - if (ACTION_DOWNLOAD_RESUME_ALL.equals(intent.getAction())) { - if (mNumAutoResumptionAttemptLeft > 0) { - mNumAutoResumptionAttemptLeft--; - updateResumptionAttemptLeft(); - } - } else { - // Reset number of attempts left if the action is triggered by user. - mNumAutoResumptionAttemptLeft = MAX_RESUMPTION_ATTEMPT_LEFT; - clearResumptionAttemptLeft(); + } else if (ACTION_DOWNLOAD_UPDATE_SUMMARY_ICON.equals(intent.getAction())) { + updateSummaryIcon(mContext, mNotificationManager, -1, null); + hideSummaryNotificationIfNecessary(-1); + } else if (ACTION_DOWNLOAD_RESUME_ALL.equals(intent.getAction())) { + resumeAllPendingDownloads(); + + // Limit num auto resumption attempts in case Chrome falls into a vicious cycle. + int numAutoResumptionAttemptLeft = getResumptionAttemptLeft(); + if (numAutoResumptionAttemptLeft > 0) { + numAutoResumptionAttemptLeft--; + updateResumptionAttemptLeft(numAutoResumptionAttemptLeft); } } + // This should restart the service after Chrome gets killed. However, this // doesn't work on Android 4.4.2. return START_STICKY; @@ -481,7 +472,8 @@ /** * On >= O Android releases, puts this service into a foreground state, binding it to the - * {@link Notification} generated by {@link #buildSummaryNotification(Context)}. + * {@link Notification} generated by {@link #buildSummaryNotification(Context, + * NotificationManager)}. */ @VisibleForTesting void startForegroundInternal() { @@ -516,7 +508,7 @@ } } - if (scheduleAutoResumption && mNumAutoResumptionAttemptLeft > 0) { + if (scheduleAutoResumption && getResumptionAttemptLeft() > 0) { DownloadResumptionScheduler.getDownloadResumptionScheduler(mContext).schedule( allowMeteredConnection); } @@ -679,18 +671,27 @@ /** * Helper method to update the remaining number of background resumption attempts left. */ - private void updateResumptionAttemptLeft() { - SharedPreferences.Editor editor = mSharedPrefs.edit(); - editor.putInt(KEY_AUTO_RESUMPTION_ATTEMPT_LEFT, mNumAutoResumptionAttemptLeft); + static void updateResumptionAttemptLeft(int numAutoResumptionAttemptLeft) { + SharedPreferences sharedPrefs = ContextUtils.getAppSharedPreferences(); + SharedPreferences.Editor editor = sharedPrefs.edit(); + editor.putInt(KEY_AUTO_RESUMPTION_ATTEMPT_LEFT, numAutoResumptionAttemptLeft); editor.apply(); } /** + * Helper method to get the remaining number of background resumption attempts left. + */ + static int getResumptionAttemptLeft() { + SharedPreferences sharedPrefs = ContextUtils.getAppSharedPreferences(); + return sharedPrefs.getInt(KEY_AUTO_RESUMPTION_ATTEMPT_LEFT, MAX_RESUMPTION_ATTEMPT_LEFT); + } + + /** * Helper method to clear the remaining number of background resumption attempts left. */ static void clearResumptionAttemptLeft() { - SharedPreferences SharedPrefs = ContextUtils.getAppSharedPreferences(); - SharedPreferences.Editor editor = SharedPrefs.edit(); + SharedPreferences sharedPrefs = ContextUtils.getAppSharedPreferences(); + SharedPreferences.Editor editor = sharedPrefs.edit(); editor.remove(KEY_AUTO_RESUMPTION_ATTEMPT_LEFT); editor.apply(); } @@ -963,119 +964,6 @@ return result; } - @VisibleForTesting - void setDownloadBroadcastManager(DownloadBroadcastManager downloadBroadcastManager) { - mDownloadBroadcastManager = downloadBroadcastManager; - } - - /** - * Helper method to launch the browser process and handle a download operation that is included - * in the given intent. - * @param intent Intent with the download operation. - */ - private void handleDownloadOperation(final Intent intent) { - String action = intent.getAction(); - - // Process updating the summary notification first. This has no impact on a specific - // download. - if (ACTION_DOWNLOAD_UPDATE_SUMMARY_ICON.equals(action)) { - updateSummaryIcon(mContext, mNotificationManager, -1, null); - hideSummaryNotificationIfNecessary(-1); - return; - } - - // TODO(qinmin): Figure out how to properly handle this case. - final ContentId id = getContentIdFromIntent(intent); - final DownloadSharedPreferenceEntry entry = - mDownloadBroadcastManager.getDownloadEntryFromIntent(intent); - if (entry == null - && !(id != null && LegacyHelpers.isLegacyOfflinePage(id) - && TextUtils.equals(intent.getAction(), ACTION_DOWNLOAD_OPEN))) { - mDownloadBroadcastManager.onNotificationInteraction(mContext, intent); - hideSummaryNotificationIfNecessary(-1); - return; - } - - switch (action) { - case ACTION_DOWNLOAD_PAUSE: - // If browser process already goes away, the download should have already paused. Do - // nothing in that case. - if (!DownloadManagerService.hasDownloadManagerService()) { - // TODO(dtrainor): Should we spin up native to make sure we have the icon? Or - // maybe build a Java cache for easy access. - notifyDownloadPaused(entry.id, entry.fileName, !entry.isOffTheRecord, false, - entry.isOffTheRecord, entry.isTransient, null); - hideSummaryNotificationIfNecessary(-1); - return; - } - - // TODO(dtrainor): Consider hitting the delegate and rely on that to update the - // state. - notifyDownloadPaused(entry.id, entry.fileName, true, false, entry.isOffTheRecord, - entry.isTransient, null); - mDownloadBroadcastManager.onNotificationInteraction(mContext, intent); - break; - - case ACTION_DOWNLOAD_RESUME: - // If user manually resumes a download, update the network type if it - // is not metered previously. - boolean canDownloadWhileMetered = entry.canDownloadWhileMetered - || DownloadManagerService.isActiveNetworkMetered(mContext); - // Update the SharedPreference entry. - mDownloadSharedPreferenceHelper.addOrReplaceSharedPreferenceEntry( - new DownloadSharedPreferenceEntry(entry.id, entry.notificationId, - entry.isOffTheRecord, canDownloadWhileMetered, entry.fileName, true, - entry.isTransient)); - - // TODO(dtrainor): Consider hitting the delegate and rely on that to update the - // state. - notifyDownloadPending(entry.id, entry.fileName, entry.isOffTheRecord, - entry.canDownloadWhileMetered, entry.isTransient, null); - mDownloadBroadcastManager.onNotificationInteraction(mContext, intent); - break; - - case ACTION_DOWNLOAD_RESUME_ALL: - if (mDownloadSharedPreferenceHelper.getEntries().isEmpty() - || DownloadManagerService.hasDownloadManagerService()) { - hideSummaryNotificationIfNecessary(-1); - return; - } - resumeAllPendingDownloads(); - break; - - case ACTION_DOWNLOAD_OPEN: - // TODO(fgorski): Do we even need to do anything special before we launch Chrome? - mDownloadBroadcastManager.onNotificationInteraction(mContext, intent); - break; - - case ACTION_DOWNLOAD_CANCEL: - if (IntentUtils.safeGetBooleanExtra(intent, EXTRA_NOTIFICATION_DISMISSED, false)) { - // User canceled a download by dismissing its notification from earlier - // versions, ignore it. TODO(qinmin): remove this else-if block after M60. - return; - } - // TODO(jming): Potential condition if cancelNotification deletes the shared - // preference entry before this gets called. - mDownloadBroadcastManager.onNotificationInteraction(mContext, intent); - - // TODO(qinmin): Alternatively, we can delete the downloaded content on - // SD card, and remove the download ID from the SharedPreferences so we - // don't need to restart the browser process. http://crbug.com/579643. - for (Observer observer : mObservers) { - observer.onDownloadCanceled(entry.id); - } - cancelNotification(entry.notificationId, entry.id); - break; - - default: - Log.e(TAG, "Unrecognized intent action.", intent); - break; - } - - hideSummaryNotificationIfNecessary( - ACTION_DOWNLOAD_CANCEL.equals(intent.getAction()) ? entry.notificationId : -1); - } - /** * Gets appropriate download delegate that can handle interactions with download item referred * to by the entry. @@ -1122,52 +1010,16 @@ ChannelDefinitions.CHANNEL_ID_DOWNLOADS); } - /** - * Checks if an intent requires operations on a download. - * @param intent An intent to validate. - * @return true if the intent requires actions, or false otherwise. - */ - static boolean isDownloadOperationIntent(Intent intent) { - if (intent == null) return false; - if (ACTION_DOWNLOAD_UPDATE_SUMMARY_ICON.equals(intent.getAction())) return true; - if (ACTION_DOWNLOAD_RESUME_ALL.equals(intent.getAction())) return true; - if (!ACTION_DOWNLOAD_CANCEL.equals(intent.getAction()) - && !ACTION_DOWNLOAD_RESUME.equals(intent.getAction()) - && !ACTION_DOWNLOAD_PAUSE.equals(intent.getAction()) - && !ACTION_DOWNLOAD_OPEN.equals(intent.getAction())) { - return false; - } - - ContentId id = getContentIdFromIntent(intent); - if (id == null) return false; - return true; - } - static boolean canResumeDownload(Context context, DownloadSharedPreferenceEntry entry) { if (entry == null) return false; if (!entry.isAutoResumable) return false; boolean isNetworkMetered = DownloadManagerService.isActiveNetworkMetered(context); + return entry.canDownloadWhileMetered || !isNetworkMetered; } /** - * @param intent The {@link Intent} to pull from and build a {@link ContentId}. - * @return A {@link ContentId} built by pulling extras from {@code intent}. This will be - * {@code null} if {@code intent} is missing any required extras. - */ - public static ContentId getContentIdFromIntent(Intent intent) { - if (!intent.hasExtra(EXTRA_DOWNLOAD_CONTENTID_ID) - || !intent.hasExtra(EXTRA_DOWNLOAD_CONTENTID_NAMESPACE)) { - return null; - } - - return new ContentId( - IntentUtils.safeGetStringExtra(intent, EXTRA_DOWNLOAD_CONTENTID_NAMESPACE), - IntentUtils.safeGetStringExtra(intent, EXTRA_DOWNLOAD_CONTENTID_ID)); - } - - /** * Resumes all pending downloads from SharedPreferences. If a download is * already in progress, do nothing. */ @@ -1178,19 +1030,21 @@ if (!canResumeDownload(mContext, entry)) continue; if (mDownloadsInProgress.contains(entry.id)) continue; - notifyDownloadPending(entry.id, entry.fileName, entry.isOffTheRecord, - entry.canDownloadWhileMetered, entry.isTransient, null); - // TODO(jming): Move this to DownloadBroadcastManager eventually. Intent intent = new Intent(); intent.setAction(ACTION_DOWNLOAD_RESUME); intent.putExtra(EXTRA_DOWNLOAD_CONTENTID_ID, entry.id.id); intent.putExtra(EXTRA_DOWNLOAD_CONTENTID_NAMESPACE, entry.id.namespace); - mDownloadBroadcastManager.onNotificationInteraction(mContext, intent); + resumeDownload(intent); } } + @VisibleForTesting + void resumeDownload(Intent intent) { + DownloadBroadcastManager.startDownloadBroadcastManager(mContext, intent); + } + /** * Return the notification ID for the given download {@link ContentId}. * @param id the {@link ContentId} of the download.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/service/DownloadBackgroundTask.java b/chrome/android/java/src/org/chromium/chrome/browser/download/service/DownloadBackgroundTask.java index 6ff490f..3571bbc 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/service/DownloadBackgroundTask.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/service/DownloadBackgroundTask.java
@@ -115,7 +115,7 @@ @Override public void reschedule(Context context) { - // TODO(shaktisahu): Called when system asks us to schedule the task again. (crbug/730786) + DownloadTaskScheduler.rescheduleAllTasks(); } private native void nativeStartBackgroundTask(
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/service/DownloadTaskScheduler.java b/chrome/android/java/src/org/chromium/chrome/browser/download/service/DownloadTaskScheduler.java index 4b5b642..c10ca39 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/service/DownloadTaskScheduler.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/service/DownloadTaskScheduler.java
@@ -24,6 +24,8 @@ @JNINamespace("download::android") public class DownloadTaskScheduler { public static final String EXTRA_TASK_TYPE = "extra_task_type"; + static final long TWELVE_HOURS_IN_SECONDS = TimeUnit.HOURS.toSeconds(12); + static final long FIVE_MINUTES_IN_SECONDS = TimeUnit.MINUTES.toSeconds(5); @CalledByNative private static void scheduleTask(@DownloadTaskType int taskType, boolean requiresCharging, @@ -52,6 +54,17 @@ scheduler.cancel(ContextUtils.getApplicationContext(), getTaskId(taskType)); } + /** + * Invoked when the system sends a reschedule() call, which might happen in case of OS or play + * services upgrade etc. This will schedule the tasks in future with least restrictive criteria. + */ + public static void rescheduleAllTasks() { + scheduleTask(DownloadTaskType.DOWNLOAD_TASK, false, false, FIVE_MINUTES_IN_SECONDS, + 2 * FIVE_MINUTES_IN_SECONDS); + scheduleTask(DownloadTaskType.CLEANUP_TASK, false, false, TWELVE_HOURS_IN_SECONDS, + 2 * TWELVE_HOURS_IN_SECONDS); + } + private static int getTaskId(@DownloadTaskType int taskType) { switch (taskType) { case DownloadTaskType.DOWNLOAD_TASK:
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/ToSAckedReceiver.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/ToSAckedReceiver.java index 3110a791..71926c1e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/ToSAckedReceiver.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/ToSAckedReceiver.java
@@ -12,6 +12,8 @@ import android.os.Bundle; import org.chromium.base.ContextUtils; +import org.chromium.base.ThreadUtils; +import org.chromium.chrome.browser.init.ProcessInitializationHandler; import org.chromium.components.signin.AccountManagerFacade; import java.util.HashSet; @@ -23,8 +25,8 @@ * the Chrome ToS so that we don't show the ToS string during our first run. */ public class ToSAckedReceiver extends BroadcastReceiver { - private static final String TOS_ACKED_ACCOUNTS = "ToS acknowledged accounts"; - private static final String EXTRA_ACCOUNT_NAME = "TosAckedReceiver.account"; + static final String TOS_ACKED_ACCOUNTS = "ToS acknowledged accounts"; + static final String EXTRA_ACCOUNT_NAME = "TosAckedReceiver.account"; @Override public void onReceive(Context context, Intent intent) { @@ -56,6 +58,12 @@ ContextUtils.getAppSharedPreferences().getStringSet( TOS_ACKED_ACCOUNTS, null); if (toSAckedAccounts == null || toSAckedAccounts.isEmpty()) return false; + ThreadUtils.runOnUiThreadBlocking(new Runnable() { + @Override + public void run() { + ProcessInitializationHandler.getInstance().initializePreNative(); + } + }); AccountManagerFacade accountHelper = AccountManagerFacade.get(); List<String> accountNames = accountHelper.tryGetGoogleAccountNames(); if (accountNames.isEmpty()) return false;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/init/ProcessInitializationHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/init/ProcessInitializationHandler.java index 83b44a3..c833a941 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/init/ProcessInitializationHandler.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/init/ProcessInitializationHandler.java
@@ -145,7 +145,7 @@ * Performs the shared class initialization. */ protected void handlePreNativeInitialization() { - ChromeApplication application = (ChromeApplication) ContextUtils.getApplicationContext(); + Context application = ContextUtils.getApplicationContext(); UiUtils.setKeyboardShowingDelegate(new UiUtils.KeyboardShowingDelegate() { @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/remote/MediaUrlResolver.java b/chrome/android/java/src/org/chromium/chrome/browser/media/remote/MediaUrlResolver.java index 0a41375..d78410e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/media/remote/MediaUrlResolver.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/media/remote/MediaUrlResolver.java
@@ -37,9 +37,10 @@ private static final int RESOLVE_RESULT_SERVER_ERROR = 4; private static final int RESOLVE_RESULT_NETWORK_ERROR = 5; private static final int RESOLVE_RESULT_UNSUPPORTED_MEDIA = 6; + private static final int RESOLVE_RESULT_HUC_EXCEPTION = 7; // Range of histogram. - private static final int HISTOGRAM_RESULT_COUNT = 7; + private static final int HISTOGRAM_RESULT_COUNT = 8; // Acceptal response codes for URL resolving request. private static final Integer[] SUCCESS_RESPONSE_CODES = { @@ -185,8 +186,13 @@ recordResultHistogram(RESOLVE_RESULT_NETWORK_ERROR); Log.e(TAG, "Failed to fetch the final url", e); uri = Uri.EMPTY; + } catch (ArrayIndexOutOfBoundsException | NullPointerException e) { + recordResultHistogram(RESOLVE_RESULT_HUC_EXCEPTION); + Log.e(TAG, "Threading issue with HUC, see https://crbug.com/754480", e); + uri = Uri.EMPTY; + } finally { + if (urlConnection != null) urlConnection.disconnect(); } - if (urlConnection != null) urlConnection.disconnect(); return new MediaUrlResolver.Result(uri, canPlayMedia(uri, headers)); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridge.java index 4062e11..f8547fa 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridge.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridge.java
@@ -193,6 +193,17 @@ } /** + * Gets the offline pages associated with the provided origin. + * @param origin The JSON-like string of the app's package name and encrypted signature hash. + * @return A list of {@link OfflinePageItem} matching the provided origin, or an empty + * list if none exist. + */ + public void getPagesByRequestOrigin(String origin, Callback<List<OfflinePageItem>> callback) { + List<OfflinePageItem> result = new ArrayList<>(); + nativeGetPagesByRequestOrigin(mNativeOfflinePageBridge, result, origin, callback); + } + + /** * Gets the offline pages associated with the provided namespace. * * @param namespace The string form of the namespace to query. @@ -644,6 +655,9 @@ @VisibleForTesting native void nativeGetPagesByClientId(long nativeOfflinePageBridge, List<OfflinePageItem> result, String[] namespaces, String[] ids, Callback<List<OfflinePageItem>> callback); + native void nativeGetPagesByRequestOrigin(long nativeOfflinePageBridge, + List<OfflinePageItem> result, String requestOrigin, + Callback<List<OfflinePageItem>> callback); native void nativeGetPagesForNamespace(long nativeOfflinePageBridge, List<OfflinePageItem> result, String nameSpace, Callback<List<OfflinePageItem>> callback);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java index 8c7a50b..29ea23e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java
@@ -97,6 +97,7 @@ import org.chromium.content.browser.ContentView; import org.chromium.content.browser.ContentViewCore; import org.chromium.content.browser.crypto.CipherFactory; +import org.chromium.content_public.browser.ChildProcessImportance; import org.chromium.content_public.browser.GestureStateListener; import org.chromium.content_public.browser.ImeEventObserver; import org.chromium.content_public.browser.LoadUrlParams; @@ -301,6 +302,13 @@ */ private boolean mIsHidden = true; + /** + * Importance of the WebContents currently attached to this tab. Note the key difference from + * |mIsHidden| is that a tab is hidden when the application is hidden, but the importance is + * not affected by this signal. + */ + private @ChildProcessImportance int mImportance = ChildProcessImportance.NORMAL; + /** Whether the renderer is currently unresponsive. */ private boolean mIsRendererUnresponsive; @@ -1196,6 +1204,14 @@ } } + public final void setImportance(@ChildProcessImportance int importance) { + if (mImportance == importance) return; + mImportance = importance; + WebContents webContents = getWebContents(); + if (webContents == null) return; + webContents.setImportance(mImportance); + } + /** * Shows the given {@code nativePage} if it's not already showing. * @param nativePage The {@link NativePage} to show. @@ -1652,9 +1668,11 @@ if (mContentViewCore != null) { mContentViewCore.setObscuredByAnotherView(false); + mContentViewCore.getWebContents().setImportance(ChildProcessImportance.NORMAL); } mContentViewCore = cvc; + mContentViewCore.getWebContents().setImportance(mImportance); cvc.getContainerView().setOnHierarchyChangeListener(this); cvc.getContainerView().setOnSystemUiVisibilityChangeListener(this);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorImpl.java index 1f87ce6..2775bc1f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorImpl.java
@@ -14,6 +14,7 @@ import org.chromium.chrome.browser.tabmodel.TabModel.TabLaunchType; import org.chromium.chrome.browser.tabmodel.TabModel.TabSelectionType; import org.chromium.chrome.browser.tabmodel.TabPersistentStore.TabPersistentStoreObserver; +import org.chromium.content_public.browser.ChildProcessImportance; import org.chromium.content_public.browser.LoadUrlParams; import java.util.concurrent.atomic.AtomicBoolean; @@ -346,6 +347,7 @@ cacheTabBitmap(mVisibleTab); } mVisibleTab.hide(); + mVisibleTab.setImportance(ChildProcessImportance.NORMAL); mTabSaver.addTabToSaveQueue(mVisibleTab); } mVisibleTab = null; @@ -370,6 +372,7 @@ // http://crbug.com/316166. if (type != TabSelectionType.FROM_EXIT) { tab.show(type); + mVisibleTab.setImportance(ChildProcessImportance.MODERATE); mUma.onShowTab(tab.getId(), tab.isBeingRestored()); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java index 92dce66..6d43b40 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java
@@ -207,7 +207,7 @@ controlContainer); if (getFullscreenManager() != null) getFullscreenManager().setTab(getActivityTab()); - mSplashController.onFinishedNativeInit(getActivityTab()); + mSplashController.onFinishedNativeInit(getActivityTab(), getCompositorViewHolder()); super.finishNativeInitialization(); mIsInitialized = true; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappSplashScreenController.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappSplashScreenController.java index 3ba88d1..0bce301 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappSplashScreenController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappSplashScreenController.java
@@ -17,6 +17,7 @@ import org.chromium.base.ContextUtils; import org.chromium.base.VisibleForTesting; import org.chromium.chrome.R; +import org.chromium.chrome.browser.compositor.CompositorViewHolder; import org.chromium.chrome.browser.metrics.WebappUma; import org.chromium.chrome.browser.tab.EmptyTabObserver; import org.chromium.chrome.browser.tab.Tab; @@ -24,6 +25,9 @@ /** Shows and hides splash screen. */ class WebappSplashScreenController extends EmptyTabObserver { + /** Used to schedule splash screen hiding. */ + private CompositorViewHolder mCompositorViewHolder; + /** View to which the splash screen is added. */ private ViewGroup mParentView; @@ -76,8 +80,9 @@ } /** Should be called once native has loaded. */ - public void onFinishedNativeInit(Tab tab) { + public void onFinishedNativeInit(Tab tab, CompositorViewHolder compositorViewHolder) { mNativeLoaded = true; + mCompositorViewHolder = compositorViewHolder; tab.addObserver(this); if (mInitializedLayout) { mWebappUma.commitMetrics(); @@ -92,27 +97,27 @@ @Override public void didFirstVisuallyNonEmptyPaint(Tab tab) { if (canHideSplashScreen()) { - hideSplashScreen(tab, WebappUma.SPLASHSCREEN_HIDES_REASON_PAINT); + hideSplashScreenOnDrawingFinished(tab, WebappUma.SPLASHSCREEN_HIDES_REASON_PAINT); } } @Override public void onPageLoadFinished(Tab tab) { if (canHideSplashScreen()) { - hideSplashScreen(tab, WebappUma.SPLASHSCREEN_HIDES_REASON_LOAD_FINISHED); + animateHidingSplashScreen(tab, WebappUma.SPLASHSCREEN_HIDES_REASON_LOAD_FINISHED); } } @Override public void onPageLoadFailed(Tab tab, int errorCode) { if (canHideSplashScreen()) { - hideSplashScreen(tab, WebappUma.SPLASHSCREEN_HIDES_REASON_LOAD_FAILED); + animateHidingSplashScreen(tab, WebappUma.SPLASHSCREEN_HIDES_REASON_LOAD_FAILED); } } @Override public void onCrash(Tab tab, boolean sadTabShown) { - hideSplashScreen(tab, WebappUma.SPLASHSCREEN_HIDES_REASON_CRASH); + animateHidingSplashScreen(tab, WebappUma.SPLASHSCREEN_HIDES_REASON_CRASH); } protected boolean canHideSplashScreen() { @@ -181,8 +186,30 @@ } } - /** Hides the splash screen. */ - private void hideSplashScreen(final Tab tab, final int reason) { + /** + * Schedules the splash screen hiding once the compositor has finished drawing a frame. + * + * Without this callback we were seeing a short flash of white between the splash screen and + * the web content (crbug.com/734500). + * */ + private void hideSplashScreenOnDrawingFinished(final Tab tab, final int reason) { + if (mSplashScreen == null) return; + + if (mCompositorViewHolder == null) { + animateHidingSplashScreen(tab, reason); + return; + } + + mCompositorViewHolder.getCompositorView().surfaceRedrawNeededAsync(null, new Runnable() { + @Override + public void run() { + animateHidingSplashScreen(tab, reason); + } + }); + } + + /** Performs the splash screen hiding animation. */ + private void animateHidingSplashScreen(final Tab tab, final int reason) { if (mSplashScreen == null) return; mSplashScreen.animate().alpha(0f).withEndAction(new Runnable() { @@ -192,6 +219,7 @@ mParentView.removeView(mSplashScreen); tab.removeObserver(WebappSplashScreenController.this); mSplashScreen = null; + mCompositorViewHolder = null; mWebappUma.splashscreenHidden(reason); } });
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/accessibility/AccessibilityTabModelListItem.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/accessibility/AccessibilityTabModelListItem.java index 3aaf3c8..ea98ef8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/accessibility/AccessibilityTabModelListItem.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/accessibility/AccessibilityTabModelListItem.java
@@ -283,6 +283,8 @@ if (!accessibilityString.equals(getContentDescription())) { setContentDescription(getContext().getString(R.string.accessibility_tabstrip_tab, title)); + mCloseButton.setContentDescription( + getContext().getString(R.string.accessibility_tabstrip_btn_close_tab, title)); } }
diff --git a/chrome/android/java/strings/android_chrome_strings.grd b/chrome/android/java/strings/android_chrome_strings.grd index 1d22971..0eb04a3b 100644 --- a/chrome/android/java/strings/android_chrome_strings.grd +++ b/chrome/android/java/strings/android_chrome_strings.grd
@@ -1514,7 +1514,7 @@ <ph name="TAB_TITLE">%1$s<ex>Welcome to Facebook</ex></ph>, tab </message> <message name="IDS_ACCESSIBILITY_TABSTRIP_BTN_CLOSE_TAB" desc="Content description for the close tab button."> - Close tab + Close <ph name="TAB_TITLE">%1$s<ex>Google</ex></ph> tab </message> <message name="IDS_TAB_LOADING_DEFAULT_TITLE" desc="The title of a tab when we are still waiting for either the URL or the real title. This generally shows when the page is first loading."> Loading…
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni index f2b2ed2..d6415c1 100644 --- a/chrome/android/java_sources.gni +++ b/chrome/android/java_sources.gni
@@ -1345,7 +1345,6 @@ "javatests/src/org/chromium/chrome/browser/ChromeBackgroundServiceTest.java", "javatests/src/org/chromium/chrome/browser/ContentViewFocusTest.java", "javatests/src/org/chromium/chrome/browser/CopylessPasteTest.java", - "javatests/src/org/chromium/chrome/browser/CrashTest.java", "javatests/src/org/chromium/chrome/browser/ExampleUiCaptureTest.java", "javatests/src/org/chromium/chrome/browser/FocusedEditableTextFieldZoomTest.java", "javatests/src/org/chromium/chrome/browser/FullscreenActivityTest.java", @@ -1765,6 +1764,7 @@ "junit/src/org/chromium/chrome/browser/download/items/OfflineContentAggregatorNotificationBridgeUiTest.java", "junit/src/org/chromium/chrome/browser/externalauth/ExternalAuthUtilsTest.java", "junit/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencerTest.java", + "junit/src/org/chromium/chrome/browser/firstrun/ToSAckedReceiverTest.java", "junit/src/org/chromium/chrome/browser/fullscreen/BrowserStateBrowserControlsVisibilityDelegateTest.java", "junit/src/org/chromium/chrome/browser/gcore/GoogleApiClientHelperTest.java", "junit/src/org/chromium/chrome/browser/init/AsyncInitTaskRunnerTest.java",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/CrashTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/CrashTest.java deleted file mode 100644 index 51d03315..0000000 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/CrashTest.java +++ /dev/null
@@ -1,40 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser; - -import android.support.test.filters.SmallTest; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.chromium.base.test.util.CommandLineFlags; -import org.chromium.base.test.util.DisabledTest; -import org.chromium.chrome.test.ChromeActivityTestRule; -import org.chromium.chrome.test.ChromeJUnit4ClassRunner; - -/** - * The class contains a testcase that intentionally crashes. - */ -@RunWith(ChromeJUnit4ClassRunner.class) -@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE, - ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG}) -public class CrashTest { - @Rule - public ChromeActivityTestRule<ChromeActivity> mActivityTestRule = - new ChromeActivityTestRule<>(ChromeActivity.class); - - /** - * Intentionally crashing the test. The testcase should be - * disabled the majority of time. - */ - @Test - @DisabledTest - @SmallTest - public void testIntentionalBrowserCrash() throws Exception { - mActivityTestRule.startMainActivityFromLauncher(); - mActivityTestRule.loadUrl("chrome://inducebrowsercrashforrealz"); - } -}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadNotificationServiceTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadNotificationServiceTest.java index 7dc58c7..dfff6a6 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadNotificationServiceTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadNotificationServiceTest.java
@@ -16,6 +16,7 @@ import org.chromium.base.ContextUtils; import org.chromium.base.ThreadUtils; import org.chromium.base.test.util.AdvancedMockContext; +import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.RetryOnFailure; import org.chromium.components.offline_items_collection.ContentId; @@ -23,9 +24,7 @@ import org.chromium.components.offline_items_collection.OfflineItem.Progress; import org.chromium.components.offline_items_collection.OfflineItemProgressUnit; -import java.util.ArrayList; import java.util.HashSet; -import java.util.List; import java.util.Set; import java.util.UUID; @@ -34,33 +33,6 @@ */ public class DownloadNotificationServiceTest extends ServiceTestCase<MockDownloadNotificationService> { - /** - * Implementation of DownloadBroadcastManager that skips loading the native to just propagate - * interactions through for testing purposes. - */ - private static class MockDownloadBroadcastManager extends DownloadBroadcastManager { - @Override - void loadNativeAndPropagateInteraction(Context context, Intent intent) { - // Skip loading the native and just propagate interaction. - propagateInteraction(intent); - } - } - - private static class MockDownloadManagerService extends DownloadManagerService { - final List<DownloadItem> mDownloads = new ArrayList<DownloadItem>(); - - public MockDownloadManagerService(Context context) { - super(context, null, getTestHandler(), 1000); - } - - @Override - protected void init() {} - - @Override - public void resumeDownload(ContentId id, DownloadItem item, boolean hasUserGesture) { - mDownloads.add(item); - } - } private static class MockDownloadResumptionScheduler extends DownloadResumptionScheduler { boolean mScheduled; @@ -333,9 +305,10 @@ /** * Tests resume all pending downloads. Only auto resumable downloads can resume. */ - @SmallTest - @Feature({"Download"}) - @RetryOnFailure + //@SmallTest + //@Feature({"Download"}) + //@RetryOnFailure + @DisabledTest public void testResumeAllPendingDownloads() throws Exception { setupService(); Context mockContext = new AdvancedMockContext(getSystemContext()); @@ -358,21 +331,19 @@ DownloadNotificationService service = bindNotificationService(); DownloadManagerService.disableNetworkListenerForTest(); - final MockDownloadManagerService manager = - new MockDownloadManagerService(getSystemContext().getApplicationContext()); - ThreadUtils.runOnUiThreadBlocking( - (Runnable) () -> DownloadManagerService.setDownloadManagerService(manager)); DownloadManagerService.setIsNetworkMeteredForTest(true); - service.setDownloadBroadcastManager(new MockDownloadBroadcastManager()); resumeAllDownloads(service); - assertEquals(1, manager.mDownloads.size()); - assertEquals(manager.mDownloads.get(0).getDownloadInfo().getDownloadGuid(), guid2); + assertEquals(1, getService().getResumedDownloads().size()); + assertEquals(getService().getResumedDownloads().get(0), guid2); - manager.mDownloads.clear(); + // TODO(jming): Right now, assuming all downloads are resumed because of the way downloads + // in progress are tracked internally. Change when this is updated. http://crbug.com/755588 + getService().clearResumedDownloads(); DownloadManagerService.setIsNetworkMeteredForTest(false); resumeAllDownloads(service); - assertEquals(1, manager.mDownloads.size()); - assertEquals(manager.mDownloads.get(0).getDownloadInfo().getDownloadGuid(), guid1); + assertEquals(2, getService().getResumedDownloads().size()); + assertEquals(getService().getResumedDownloads().get(0), guid2); + assertEquals(getService().getResumedDownloads().get(1), guid1); } /**
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/download/MockDownloadNotificationService.java b/chrome/android/javatests/src/org/chromium/chrome/browser/download/MockDownloadNotificationService.java index ed88ca02..dd39dec9 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/download/MockDownloadNotificationService.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/download/MockDownloadNotificationService.java
@@ -6,9 +6,11 @@ import android.app.Notification; import android.content.Context; +import android.content.Intent; import android.graphics.Bitmap; import org.chromium.base.ThreadUtils; +import org.chromium.chrome.browser.util.IntentUtils; import org.chromium.components.offline_items_collection.ContentId; import org.chromium.components.offline_items_collection.OfflineItem.Progress; @@ -23,6 +25,7 @@ private boolean mPaused = false; private Context mContext; private int mLastNotificationId; + private List<String> mResumedDownloads = new ArrayList<>(); void setContext(Context context) { mContext = context; @@ -124,5 +127,18 @@ ThreadUtils.runOnUiThreadBlocking( () -> MockDownloadNotificationService.super.notifyDownloadCanceled(id)); } + + @Override + void resumeDownload(Intent intent) { + mResumedDownloads.add(IntentUtils.safeGetStringExtra(intent, EXTRA_DOWNLOAD_CONTENTID_ID)); + } + + List<String> getResumedDownloads() { + return mResumedDownloads; + } + + void clearResumedDownloads() { + mResumedDownloads.clear(); + } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/snippets/ArticleSnippetsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/snippets/ArticleSnippetsTest.java index cd15265..af191d9f 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/snippets/ArticleSnippetsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/snippets/ArticleSnippetsTest.java
@@ -7,6 +7,7 @@ import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.drawable.Drawable; +import android.support.annotation.DrawableRes; import android.support.test.InstrumentationRegistry; import android.support.test.filters.MediumTest; import android.text.format.DateUtils; @@ -44,6 +45,7 @@ import org.chromium.chrome.browser.ntp.cards.SignInPromo; import org.chromium.chrome.browser.ntp.cards.SuggestionsCategoryInfo; import org.chromium.chrome.browser.offlinepages.OfflinePageBridge; +import org.chromium.chrome.browser.preferences.ChromePreferenceManager; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.suggestions.ContentSuggestionsAdditionalAction; import org.chromium.chrome.browser.suggestions.DestructionObserver; @@ -345,20 +347,24 @@ @Before public void setUp() throws Exception { mActivityTestRule.startMainActivityOnBlankPage(); + ChromePreferenceManager.getInstance().setNewTabPageSigninPromoDismissed(true); mThumbnailProvider = new MockThumbnailProvider(); mSnippetsSource = new FakeSuggestionsSource(); mSuggestionsDeps.getFactory().thumbnailProvider = mThumbnailProvider; mSuggestionsDeps.getFactory().suggestionsSource = mSnippetsSource; mUiDelegate = new MockUiDelegate(); - Bitmap favicon = BitmapFactory.decodeResource( - mActivityTestRule.getActivity().getResources(), R.drawable.star_green); - mSnippetsSource.setDefaultFavicon(favicon); + mSnippetsSource.setDefaultFavicon(getBitmap(R.drawable.star_green)); if (isModern()) { mRenderTestRule.setVariantPrefix("modern"); } } + private Bitmap getBitmap(@DrawableRes int resId) { + return BitmapFactory.decodeResource( + mActivityTestRule.getInstrumentation().getTargetContext().getResources(), resId); + } + /** * Simple mock ThumbnailProvider that allows delaying requests and fulfilling them at a later * point. @@ -450,13 +456,9 @@ public void makeFaviconRequest(SnippetArticle suggestion, final int faviconSizePx, final Callback<Bitmap> faviconCallback) { // Run the callback asynchronously in case the caller made that assumption. - ThreadUtils.postOnUiThread(new Runnable() { - @Override - public void run() { - // Return an arbitrary drawable. - faviconCallback.onResult(BitmapFactory.decodeResource( - mActivityTestRule.getActivity().getResources(), R.drawable.star_green)); - } + ThreadUtils.postOnUiThread(() -> { + // Return an arbitrary drawable. + faviconCallback.onResult(getBitmap(R.drawable.star_green)); }); } @@ -464,16 +466,10 @@ public void makeLargeIconRequest(final String url, final int largeIconSizePx, final LargeIconBridge.LargeIconCallback callback) { // Run the callback asynchronously in case the caller made that assumption. - ThreadUtils.postOnUiThread(new Runnable() { - @Override - public void run() { - // Return an arbitrary drawable. - callback.onLargeIconAvailable( - BitmapFactory.decodeResource( - mActivityTestRule.getActivity().getResources(), - R.drawable.star_green), - largeIconSizePx, true); - } + ThreadUtils.postOnUiThread(() -> { + // Return an arbitrary drawable. + callback.onLargeIconAvailable( + getBitmap(R.drawable.star_green), largeIconSizePx, true); }); } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappNavigationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappNavigationTest.java index dd530aee..9d99b93 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappNavigationTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappNavigationTest.java
@@ -25,6 +25,7 @@ import org.chromium.base.ApplicationStatus; import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.Feature; +import org.chromium.base.test.util.RetryOnFailure; import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeSwitches; import org.chromium.chrome.browser.ChromeTabbedActivity; @@ -71,6 +72,7 @@ @Test @SmallTest @Feature({"Webapps"}) + @RetryOnFailure public void testRegularLinkOffOriginInCctNoWebappThemeColor() throws Exception { runWebappActivityAndWaitForIdle(mActivityTestRule.createIntent()); addAnchor("testId", OFF_ORIGIN_URL, "_self"); @@ -89,6 +91,7 @@ @Test @SmallTest @Feature({"Webapps"}) + @RetryOnFailure public void testWindowTopLocationOffOriginInCctAndWebappThemeColor() throws Exception { runWebappActivityAndWaitForIdle(mActivityTestRule.createIntent().putExtra( ShortcutHelper.EXTRA_THEME_COLOR, (long) Color.CYAN)); @@ -105,6 +108,7 @@ @Test @SmallTest @Feature({"Webapps"}) + @RetryOnFailure public void testOffScopeNewTabLinkOpensInCct() throws Exception { runWebappActivityAndWaitForIdle(mActivityTestRule.createIntent().putExtra( ShortcutHelper.EXTRA_THEME_COLOR, (long) Color.CYAN)); @@ -122,6 +126,7 @@ @Test @SmallTest @Feature({"Webapps"}) + @RetryOnFailure public void testInScopeNewTabLinkOpensInCct() throws Exception { runWebappActivityAndWaitForIdle(mActivityTestRule.createIntent().putExtra( ShortcutHelper.EXTRA_THEME_COLOR, (long) Color.CYAN)); @@ -138,6 +143,7 @@ @Test @SmallTest @Feature({"Webapps"}) + @RetryOnFailure public void testWindowOpenInCct() throws Exception { runWebappActivityAndWaitForIdle(mActivityTestRule.createIntent()); // Executing window.open() through a click on a link, @@ -165,6 +171,7 @@ @Test @SmallTest @Feature({"Webapps"}) + @RetryOnFailure public void testInScopeNavigationStaysInWebapp() throws Exception { runWebappActivityAndWaitForIdle(mActivityTestRule.createIntent()); @@ -183,6 +190,7 @@ @Test @SmallTest @Feature({"Webapps"}) + @RetryOnFailure public void testOpenInChromeFromContextMenuTabbedChrome() throws Exception { // Needed to get full context menu. FirstRunStatus.setFirstRunFlowComplete(true); @@ -205,6 +213,7 @@ @Test @SmallTest @Feature({"Webapps"}) + @RetryOnFailure public void testRegularLinkToExternalApp() throws Exception { runWebappActivityAndWaitForIdle(mActivityTestRule.createIntent()); @@ -223,6 +232,7 @@ @Test @SmallTest @Feature({"Webapps"}) + @RetryOnFailure public void testNewTabLinkToExternalApp() throws Exception { runWebappActivityAndWaitForIdle(mActivityTestRule.createIntent());
diff --git a/chrome/android/javatests/src/org/chromium/chrome/test/crash/IntentionalCrashTest.java b/chrome/android/javatests/src/org/chromium/chrome/test/crash/IntentionalCrashTest.java index 52066717..77feed3 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/test/crash/IntentionalCrashTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/test/crash/IntentionalCrashTest.java
@@ -4,6 +4,8 @@ package org.chromium.chrome.test.crash; +import android.support.test.filters.SmallTest; + import org.junit.Assert; import org.junit.Rule; import org.junit.Test; @@ -28,6 +30,7 @@ new ChromeActivityTestRule<>(ChromeActivity.class); @DisabledTest + @SmallTest @Test public void testRendererCrash() { try { @@ -38,6 +41,7 @@ } @DisabledTest + @SmallTest @Test public void testBrowserCrash() { try { @@ -48,6 +52,7 @@ } @DisabledTest + @SmallTest @Test public void testJavaCrash() { try { @@ -58,6 +63,7 @@ } @DisabledTest + @SmallTest @Test public void testGpuCrash() { try {
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperTest.java index 1f5b49c..0944243 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperTest.java
@@ -55,7 +55,7 @@ private StripLayoutHelper mStripLayoutHelper; private boolean mIncognito; private static final String[] TEST_TAB_TITLES = {"Tab 1", "Tab 2", "Tab 3", "", null}; - private static final String CLOSE_TAB = "Close tab test string"; + private static final String CLOSE_TAB = "Close %1$s tab"; private static final String NEW_TAB = "New tab test string"; private static final String NEW_INCOGNITO_TAB = "New incognito tab test string"; private static final String IDENTIFIER = "Tab"; @@ -178,7 +178,8 @@ // Tab titles for (int i = 0; i < expectedNumberOfViews - 1; i++) { final String expectedDescription = i % 2 == 0 - ? expectedAccessibilityDescriptions[i / 2] : CLOSE_TAB; + ? expectedAccessibilityDescriptions[i / 2] + : String.format(CLOSE_TAB, TEST_TAB_TITLES[i / 2]); assertEquals(expectedDescription, views.get(i).getAccessibilityDescription()); }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/firstrun/ToSAckedReceiverTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/firstrun/ToSAckedReceiverTest.java new file mode 100644 index 0000000..f1f7884e --- /dev/null +++ b/chrome/android/junit/src/org/chromium/chrome/browser/firstrun/ToSAckedReceiverTest.java
@@ -0,0 +1,69 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.firstrun; + +import android.accounts.Account; +import android.content.Intent; +import android.os.Build; + +import org.hamcrest.Matchers; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; +import org.robolectric.util.ReflectionHelpers; + +import org.chromium.base.ContextUtils; +import org.chromium.components.signin.AccountManagerDelegate; +import org.chromium.components.signin.AccountManagerDelegateException; +import org.chromium.components.signin.AccountManagerFacade; +import org.chromium.testing.local.LocalRobolectricTestRunner; + +import java.util.HashSet; +import java.util.Set; + +@RunWith(LocalRobolectricTestRunner.class) +@Config(manifest = Config.NONE) +public class ToSAckedReceiverTest { + private static final String GOOGLE_ACCOUNT = "TestyMcTesterson@gmail.com"; + + private ToSAckedReceiver mReceiver; + + @Before + public void setUp() { + ContextUtils.initApplicationContextForTests(RuntimeEnvironment.application); + ReflectionHelpers.setStaticField( + Build.VERSION.class, "SDK_INT", Build.VERSION_CODES.KITKAT); + mReceiver = new ToSAckedReceiver(); + } + + @Test + public void testNoToSAccounts() { + Assert.assertFalse(ToSAckedReceiver.checkAnyUserHasSeenToS(RuntimeEnvironment.application)); + } + + @Test + public void testReceivedToSPing() throws AccountManagerDelegateException { + Intent intent = new Intent(); + intent.putExtra(ToSAckedReceiver.EXTRA_ACCOUNT_NAME, GOOGLE_ACCOUNT); + + mReceiver.onReceive(RuntimeEnvironment.application, intent); + Assert.assertFalse(ToSAckedReceiver.checkAnyUserHasSeenToS(RuntimeEnvironment.application)); + Set<String> toSAckedAccounts = ContextUtils.getAppSharedPreferences().getStringSet( + ToSAckedReceiver.TOS_ACKED_ACCOUNTS, new HashSet<>()); + Assert.assertThat(toSAckedAccounts, Matchers.contains(GOOGLE_ACCOUNT)); + + AccountManagerDelegate accountManagerDelegate = Mockito.mock(AccountManagerDelegate.class); + Account[] accounts = new Account[1]; + accounts[0] = new Account(GOOGLE_ACCOUNT, "LegitAccount"); + Mockito.doReturn(accounts).when(accountManagerDelegate).getAccountsSync(); + AccountManagerFacade.overrideAccountManagerFacadeForTests( + RuntimeEnvironment.application, accountManagerDelegate); + Assert.assertTrue(ToSAckedReceiver.checkAnyUserHasSeenToS(RuntimeEnvironment.application)); + } +}
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/omnibox/AutocompleteEditTextTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/omnibox/AutocompleteEditTextTest.java index 890eecd..5e9de2ba 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/omnibox/AutocompleteEditTextTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/omnibox/AutocompleteEditTextTest.java
@@ -55,11 +55,11 @@ // Limits the target of InOrder#verify. private static class Verifier { public void onAutocompleteTextStateChanged(boolean updateDisplay) { - if (DEBUG) Log.i(TAG, "onAutocompleteTextStateChanged: " + updateDisplay); + if (DEBUG) Log.i(TAG, "onAutocompleteTextStateChanged(%b)", updateDisplay); } public void onUpdateSelection(int selStart, int selEnd) { - if (DEBUG) Log.i(TAG, "onUpdateSelection: [%d,%d]", selStart, selEnd); + if (DEBUG) Log.i(TAG, "onUpdateSelection(%d, %d)", selStart, selEnd); } } @@ -178,6 +178,8 @@ mInOrder.verify(mVerifier).onUpdateSelection(5, 5); mInOrder.verify(mVerifier).onAutocompleteTextStateChanged(false); } else { + mInOrder.verify(mVerifier).onAutocompleteTextStateChanged(false); + mInOrder.verify(mVerifier).onUpdateSelection(11, 11); mInOrder.verify(mVerifier).onAutocompleteTextStateChanged(true); mInOrder.verify(mVerifier).onUpdateSelection(5, 5); } @@ -334,6 +336,7 @@ if (isUsingSpannableModel()) { assertFalse(mAutocomplete.isCursorVisible()); } else { + mInOrder.verify(mVerifier).onUpdateSelection(11, 11); mInOrder.verify(mVerifier).onUpdateSelection(6, 11); } mInOrder.verifyNoMoreInteractions(); @@ -490,6 +493,7 @@ mInOrder.verify(mVerifier).onAutocompleteTextStateChanged(false); mInOrder.verify(mVerifier).onUpdateSelection(7, 7); } + mInOrder.verifyNoMoreInteractions(); assertFalse(mAutocomplete.shouldAutocomplete()); assertTexts("hello world", ""); } @@ -537,9 +541,11 @@ mInOrder.verify(mVerifier).onUpdateSelection(3, 3); mInOrder.verify(mVerifier).onAutocompleteTextStateChanged(false); } else { + mInOrder.verify(mVerifier).onAutocompleteTextStateChanged(true); mInOrder.verify(mVerifier).onAutocompleteTextStateChanged(false); mInOrder.verify(mVerifier).onUpdateSelection(3, 3); } + mInOrder.verifyNoMoreInteractions(); assertFalse(mAutocomplete.shouldAutocomplete()); // Autocomplete text is removed. assertTexts("hello", "");
diff --git a/chrome/app/BUILD.gn b/chrome/app/BUILD.gn index 18011e3e..e67a5d0d 100644 --- a/chrome/app/BUILD.gn +++ b/chrome/app/BUILD.gn
@@ -399,7 +399,7 @@ if (is_chromeos) { chrome_packaged_services += - [ "//chrome/browser:preferences_forwarder_manifest" ] + [ "//chrome/browser/chromeos:ash_pref_connector_manifest" ] } service_manifest("chrome_manifest") {
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp index 107043d..f2ca2e6 100644 --- a/chrome/app/chromeos_strings.grdp +++ b/chrome/app/chromeos_strings.grdp
@@ -4069,9 +4069,6 @@ <message name="IDS_VERSION_FIELD_PREFIX" desc="Display the OS version to the user."> version </message> - <message name="IDS_PROXY_PAGE_TITLE_FORMAT" desc="The title of the proxy page for a specific network."> - Network proxy for <ph name="NETWORK_NAME">$1<ex>Ethernet</ex></ph> - </message> <message name="IDS_PROXY_CONFIG_TITLE" desc="The title of the basic proxy config."> Proxy Configuration </message>
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp index 1b6543f..c3c3e49 100644 --- a/chrome/app/settings_strings.grdp +++ b/chrome/app/settings_strings.grdp
@@ -1246,6 +1246,9 @@ <message name="IDS_SETTINGS_INTERNET_NETWORK_PROXY_CONNECTION_TYPE" desc="Settings > Internet > Network details: Label for proxy connection type dropdown."> Connection type </message> + <message name="IDS_SETTINGS_INTERNET_NETWORK_PROXY_CONNECTION_TYPE_DIALOG" desc="Label for proxy connection type dropdown in the network details dialog used in the login screen."> + Proxy connection type + </message> <message name="IDS_SETTINGS_INTERNET_NETWORK_PROXY_AUTO_CONFIG" desc="Settings > Internet > Network details: Label for proxy autoconfiguration URL input."> Autoconfiguration URL: </message>
diff --git a/chrome/app/vector_icons/BUILD.gn b/chrome/app/vector_icons/BUILD.gn index e8262fd..3cf1abb 100644 --- a/chrome/app/vector_icons/BUILD.gn +++ b/chrome/app/vector_icons/BUILD.gn
@@ -49,6 +49,7 @@ "folder_supervised.1x.icon", "folder_supervised.icon", "globe.icon", + "google_g_logo.icon", "image.icon", "incognito.1x.icon", "incognito.icon", @@ -101,7 +102,6 @@ if (is_mac) { icons += [ "default_favicon.icon", - "google_search_mac_touchbar.icon", "new_tab_mac_touchbar.icon", ] }
diff --git a/chrome/app/vector_icons/google_search_mac_touchbar.icon b/chrome/app/vector_icons/google_g_logo.icon similarity index 100% rename from chrome/app/vector_icons/google_search_mac_touchbar.icon rename to chrome/app/vector_icons/google_g_logo.icon
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index d20b00f..b385ebb4 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -20,7 +20,6 @@ import("//printing/features/features.gni") import("//rlz/features/features.gni") import("//sandbox/features.gni") -import("//services/service_manager/public/service_manifest.gni") import("//third_party/protobuf/proto_library.gni") import("//ui/base/ui_features.gni") @@ -821,6 +820,8 @@ "ntp_snippets/content_suggestions_notifier_service_factory.h", "ntp_snippets/content_suggestions_service_factory.cc", "ntp_snippets/content_suggestions_service_factory.h", + "ntp_snippets/contextual_content_suggestions_service_factory.cc", + "ntp_snippets/contextual_content_suggestions_service_factory.h", "ntp_snippets/download_suggestions_provider.cc", "ntp_snippets/download_suggestions_provider.h", "ntp_snippets/ntp_snippets_metrics.cc", @@ -2346,8 +2347,6 @@ "metrics/perf/windowed_incognito_observer.h", "policy/default_geolocation_policy_handler.cc", "policy/default_geolocation_policy_handler.h", - "prefs/active_profile_pref_service.cc", - "prefs/active_profile_pref_service.h", "task_manager/providers/arc/arc_process_task.cc", "task_manager/providers/arc/arc_process_task.h", "task_manager/providers/arc/arc_process_task_provider.cc", @@ -4400,8 +4399,6 @@ "net/dns_probe_test_util.h", "net/url_request_mock_util.cc", "net/url_request_mock_util.h", - "notifications/notification_display_service_tester.cc", - "notifications/notification_display_service_tester.h", "notifications/notification_test_util.cc", "notifications/notification_test_util.h", "notifications/stub_notification_display_service.cc", @@ -4673,8 +4670,3 @@ ] } } - -service_manifest("preferences_forwarder_manifest") { - name = "preferences_forwarder" - source = "prefs/forwarder_manifest.json" -}
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index b3c12384..a884d77 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -2871,6 +2871,10 @@ flag_descriptions::kEnableAutofillCreditCardUploadCvcPromptDescription, kOsDesktop, FEATURE_VALUE_TYPE(autofill::kAutofillUpstreamRequestCvcIfMissing)}, + {"enable-autofill-credit-card-upload-google-logo", + flag_descriptions::kEnableAutofillCreditCardUploadGoogleLogoName, + flag_descriptions::kEnableAutofillCreditCardUploadGoogleLogoDescription, + kOsDesktop, FEATURE_VALUE_TYPE(autofill::kAutofillUpstreamShowGoogleLogo)}, {"enable-autofill-credit-card-upload-new-ui", flag_descriptions::kEnableAutofillCreditCardUploadNewUiName, flag_descriptions::kEnableAutofillCreditCardUploadNewUiDescription,
diff --git a/chrome/browser/android/chrome_feature_list.cc b/chrome/browser/android/chrome_feature_list.cc index 66af908..79ebe63 100644 --- a/chrome/browser/android/chrome_feature_list.cc +++ b/chrome/browser/android/chrome_feature_list.cc
@@ -283,7 +283,7 @@ "WebPaymentsSingleAppUiSkip", base::FEATURE_ENABLED_BY_DEFAULT}; const base::Feature kWebVrAutopresent{"WebVrAutopresent", - base::FEATURE_DISABLED_BY_DEFAULT}; + base::FEATURE_ENABLED_BY_DEFAULT}; const base::Feature kWebVRCardboardSupport{"WebVRCardboardSupport", base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/chrome/browser/android/instantapps/instant_apps_infobar_delegate.cc b/chrome/browser/android/instantapps/instant_apps_infobar_delegate.cc index 459795c..7590d24a 100644 --- a/chrome/browser/android/instantapps/instant_apps_infobar_delegate.cc +++ b/chrome/browser/android/instantapps/instant_apps_infobar_delegate.cc
@@ -33,7 +33,9 @@ content::WebContents* web_contents, const jobject jdata, const std::string& url) - : content::WebContentsObserver(web_contents), url_(url) { + : content::WebContentsObserver(web_contents), + url_(url), + web_contents_(web_contents) { JNIEnv* env = base::android::AttachCurrentThread(); java_delegate_.Reset(Java_InstantAppsInfoBarDelegate_create(env)); data_.Reset(env, jdata); @@ -64,9 +66,7 @@ void InstantAppsInfoBarDelegate::InfoBarDismissed() { - content::WebContents* web_contents = - InfoBarService::WebContentsFromInfoBar(infobar()); - InstantAppsSettings::RecordInfoBarDismissEvent(web_contents, url_); + InstantAppsSettings::RecordInfoBarDismissEvent(web_contents_, url_); base::RecordAction(base::UserMetricsAction( "Android.InstantApps.BannerDismissed")); } @@ -80,11 +80,9 @@ bool InstantAppsInfoBarDelegate::ShouldExpire( const NavigationDetails& details) const { - content::WebContents* web_contents = - InfoBarService::WebContentsFromInfoBar(infobar()); bool navigation_url_is_launch_url = - web_contents != NULL && - web_contents->GetURL().EqualsIgnoringRef(GURL(url_)); + web_contents_ != NULL && + web_contents_->GetURL().EqualsIgnoringRef(GURL(url_)); return !navigation_url_is_launch_url && ConfirmInfoBarDelegate::ShouldExpire(details); }
diff --git a/chrome/browser/android/instantapps/instant_apps_infobar_delegate.h b/chrome/browser/android/instantapps/instant_apps_infobar_delegate.h index cdf20ea8..39586fd 100644 --- a/chrome/browser/android/instantapps/instant_apps_infobar_delegate.h +++ b/chrome/browser/android/instantapps/instant_apps_infobar_delegate.h
@@ -46,6 +46,7 @@ base::android::ScopedJavaGlobalRef<jobject> java_delegate_; base::android::ScopedJavaGlobalRef<jobject> data_; std::string url_; + content::WebContents* web_contents_; DISALLOW_COPY_AND_ASSIGN(InstantAppsInfoBarDelegate); };
diff --git a/chrome/browser/android/ntp/ntp_snippets_bridge.cc b/chrome/browser/android/ntp/ntp_snippets_bridge.cc index d49d33ef..34c6b90 100644 --- a/chrome/browser/android/ntp/ntp_snippets_bridge.cc +++ b/chrome/browser/android/ntp/ntp_snippets_bridge.cc
@@ -20,6 +20,7 @@ #include "chrome/browser/history/history_service_factory.h" #include "chrome/browser/ntp_snippets/content_suggestions_notifier_service_factory.h" #include "chrome/browser/ntp_snippets/content_suggestions_service_factory.h" +#include "chrome/browser/ntp_snippets/contextual_content_suggestions_service_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_android.h" #include "chrome/browser/profiles/profile_manager.h" @@ -220,6 +221,8 @@ Profile* profile = ProfileAndroid::FromProfileAndroid(j_profile); content_suggestions_service_ = ContentSuggestionsServiceFactory::GetForProfile(profile); + contextual_content_suggestions_service_ = + ContextualContentSuggestionsServiceFactory::GetForProfile(profile); history_service_ = HistoryServiceFactory::GetForProfile( profile, ServiceAccessType::EXPLICIT_ACCESS); content_suggestions_service_observer_.Add(content_suggestions_service_); @@ -338,11 +341,10 @@ DCHECK(base::FeatureList::IsEnabled( chrome::android::kContextualSuggestionsCarousel)); GURL url(ConvertJavaStringToUTF8(env, j_url)); - content_suggestions_service_->contextual_suggestions_source() - ->FetchContextualSuggestions( - url, base::Bind(&NTPSnippetsBridge::OnContextualSuggestionsFetched, - weak_ptr_factory_.GetWeakPtr(), - ScopedJavaGlobalRef<jobject>(j_callback))); + contextual_content_suggestions_service_->FetchContextualSuggestions( + url, base::Bind(&NTPSnippetsBridge::OnContextualSuggestionsFetched, + weak_ptr_factory_.GetWeakPtr(), + ScopedJavaGlobalRef<jobject>(j_callback))); } void NTPSnippetsBridge::FetchContextualSuggestionImage( @@ -352,13 +354,11 @@ const JavaParamRef<jstring>& id_within_category, const JavaParamRef<jobject>& j_callback) { ScopedJavaGlobalRef<jobject> callback(j_callback); - content_suggestions_service_->contextual_suggestions_source() - ->FetchContextualSuggestionImage( - ContentSuggestion::ID( - Category::FromIDValue(j_category_id), - ConvertJavaStringToUTF8(env, id_within_category)), - base::Bind(&NTPSnippetsBridge::OnImageFetched, - weak_ptr_factory_.GetWeakPtr(), callback)); + contextual_content_suggestions_service_->FetchContextualSuggestionImage( + ContentSuggestion::ID(Category::FromIDValue(j_category_id), + ConvertJavaStringToUTF8(env, id_within_category)), + base::Bind(&NTPSnippetsBridge::OnImageFetched, + weak_ptr_factory_.GetWeakPtr(), callback)); } void NTPSnippetsBridge::ReloadSuggestions(JNIEnv* env,
diff --git a/chrome/browser/android/ntp/ntp_snippets_bridge.h b/chrome/browser/android/ntp/ntp_snippets_bridge.h index 83e26b47..09f549e 100644 --- a/chrome/browser/android/ntp/ntp_snippets_bridge.h +++ b/chrome/browser/android/ntp/ntp_snippets_bridge.h
@@ -13,6 +13,7 @@ #include "components/ntp_snippets/category.h" #include "components/ntp_snippets/category_status.h" #include "components/ntp_snippets/content_suggestions_service.h" +#include "components/ntp_snippets/contextual/contextual_content_suggestions_service.h" #include "components/ntp_snippets/status.h" namespace gfx { @@ -139,6 +140,8 @@ std::vector<ntp_snippets::ContentSuggestion> suggestions); ntp_snippets::ContentSuggestionsService* content_suggestions_service_; + ntp_snippets::ContextualContentSuggestionsService* + contextual_content_suggestions_service_; history::HistoryService* history_service_; base::CancelableTaskTracker tracker_;
diff --git a/chrome/browser/android/offline_pages/evaluation/offline_page_evaluation_bridge.cc b/chrome/browser/android/offline_pages/evaluation/offline_page_evaluation_bridge.cc index 27e429b..1b37b55 100644 --- a/chrome/browser/android/offline_pages/evaluation/offline_page_evaluation_bridge.cc +++ b/chrome/browser/android/offline_pages/evaluation/offline_page_evaluation_bridge.cc
@@ -42,6 +42,7 @@ using base::android::ConvertJavaStringToUTF8; using base::android::ConvertUTF8ToJavaString; using base::android::JavaParamRef; +using base::android::JavaRef; using base::android::ScopedJavaGlobalRef; using base::android::ScopedJavaLocalRef; @@ -54,7 +55,7 @@ FILE_PATH_LITERAL("Offline Pages/test_request_queue"); void ToJavaOfflinePageList(JNIEnv* env, - jobject j_result_obj, + const JavaRef<jobject>& j_result_obj, const std::vector<OfflinePageItem>& offline_pages) { for (const OfflinePageItem& offline_page : offline_pages) { Java_OfflinePageEvaluationBridge_createOfflinePageAndAddToList( @@ -104,7 +105,7 @@ const ScopedJavaGlobalRef<jobject>& j_callback_obj, const OfflinePageModel::MultipleOfflinePageItemResult& result) { JNIEnv* env = base::android::AttachCurrentThread(); - ToJavaOfflinePageList(env, j_result_obj.obj(), result); + ToJavaOfflinePageList(env, j_result_obj, result); base::android::RunCallbackAndroid(j_callback_obj, j_result_obj); }
diff --git a/chrome/browser/android/preferences/website_preference_bridge.cc b/chrome/browser/android/preferences/website_preference_bridge.cc index 4b0de63..a749350e 100644 --- a/chrome/browser/android/preferences/website_preference_bridge.cc +++ b/chrome/browser/android/preferences/website_preference_bridge.cc
@@ -111,9 +111,9 @@ typedef void (*InfoListInsertionFunction)( JNIEnv*, - const base::android::JavaRefOrBare<jobject>&, - const base::android::JavaRefOrBare<jstring>&, - const base::android::JavaRefOrBare<jstring>&); + const base::android::JavaRef<jobject>&, + const base::android::JavaRef<jstring>&, + const base::android::JavaRef<jstring>&); void GetOrigins(JNIEnv* env, ContentSettingsType content_type,
diff --git a/chrome/browser/android/shortcut_helper.cc b/chrome/browser/android/shortcut_helper.cc index 30309ec3..8a7b589 100644 --- a/chrome/browser/android/shortcut_helper.cc +++ b/chrome/browser/android/shortcut_helper.cc
@@ -12,6 +12,7 @@ #include "base/android/jni_string.h" #include "base/bind.h" #include "base/callback.h" +#include "base/feature_list.h" #include "base/guid.h" #include "base/strings/string16.h" #include "base/strings/utf_string_conversions.h" @@ -19,6 +20,7 @@ #include "chrome/browser/android/webapk/chrome_webapk_host.h" #include "chrome/browser/android/webapk/webapk_install_service.h" #include "chrome/browser/android/webapk/webapk_metrics.h" +#include "chrome/common/chrome_features.h" #include "chrome/common/chrome_switches.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/manifest_icon_downloader.h" @@ -138,7 +140,9 @@ const SkBitmap& icon_bitmap) { std::string webapp_id = base::GenerateGUID(); if (info.display == blink::kWebDisplayModeStandalone || - info.display == blink::kWebDisplayModeFullscreen) { + info.display == blink::kWebDisplayModeFullscreen || + (info.display == blink::kWebDisplayModeMinimalUi && + base::FeatureList::IsEnabled(features::kPwaMinimalUi))) { AddWebappWithSkBitmap( info, webapp_id, icon_bitmap, base::Bind(&ShortcutHelper::FetchSplashScreenImage, web_contents,
diff --git a/chrome/browser/android/shortcut_info.cc b/chrome/browser/android/shortcut_info.cc index c4fca5c1..6d7fca8 100644 --- a/chrome/browser/android/shortcut_info.cc +++ b/chrome/browser/android/shortcut_info.cc
@@ -2,7 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "base/feature_list.h" #include "chrome/browser/android/shortcut_info.h" +#include "chrome/common/chrome_features.h" ShortcutInfo::ShortcutInfo(const GURL& shortcut_url) : url(shortcut_url), @@ -42,22 +44,19 @@ if (manifest.display != blink::kWebDisplayModeUndefined) display = manifest.display; - // 'minimal-ui' is not yet supported (see crbug.com/604390). Otherwise, set - // the source to be standalone if appropriate. - if (manifest.display == blink::kWebDisplayModeMinimalUi) { + if (manifest.display == blink::kWebDisplayModeMinimalUi && + !base::FeatureList::IsEnabled(features::kPwaMinimalUi)) { display = blink::kWebDisplayModeBrowser; } else if (display == blink::kWebDisplayModeStandalone || - display == blink::kWebDisplayModeFullscreen) { + display == blink::kWebDisplayModeFullscreen || + (display == blink::kWebDisplayModeMinimalUi && + base::FeatureList::IsEnabled(features::kPwaMinimalUi))) { source = SOURCE_ADD_TO_HOMESCREEN_STANDALONE; - } - - // Set the orientation based on the manifest value, if any. - if (manifest.orientation != blink::kWebScreenOrientationLockDefault) { - // Ignore the orientation if the display mode is different from - // 'standalone' or 'fullscreen'. - // TODO(mlamouri): send a message to the developer console about this. - if (display == blink::kWebDisplayModeStandalone || - display == blink::kWebDisplayModeFullscreen) { + // Set the orientation based on the manifest value, or ignore if the display + // mode is different from 'standalone', 'fullscreen' or 'minimal-ui'. + if (manifest.orientation != blink::kWebScreenOrientationLockDefault) { + // TODO(mlamouri): Send a message to the developer console if we ignored + // Manifest orientation because display property is not set. orientation = manifest.orientation; } }
diff --git a/chrome/browser/browser_process_platform_part_chromeos.cc b/chrome/browser/browser_process_platform_part_chromeos.cc index 5bf9c27..4c7b1fad 100644 --- a/chrome/browser/browser_process_platform_part_chromeos.cc +++ b/chrome/browser/browser_process_platform_part_chromeos.cc
@@ -16,6 +16,7 @@ #include "chrome/browser/chromeos/login/users/chrome_user_manager_impl.h" #include "chrome/browser/chromeos/net/delay_network_call.h" #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" +#include "chrome/browser/chromeos/prefs/pref_connector_service.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/chromeos/settings/cros_settings.h" #include "chrome/browser/chromeos/system/automatic_reboot_manager.h" @@ -26,7 +27,6 @@ #include "chrome/browser/chromeos/system/timezone_util.h" #include "chrome/browser/lifetime/keep_alive_types.h" #include "chrome/browser/lifetime/scoped_keep_alive.h" -#include "chrome/browser/prefs/active_profile_pref_service.h" #include "chrome/browser/ui/ash/ash_util.h" #include "chrome/common/chrome_features.h" #include "chrome/common/chrome_switches.h" @@ -189,10 +189,11 @@ service_manager::EmbeddedServiceInfo info; info.factory = base::Bind([] { return std::unique_ptr<service_manager::Service>( - base::MakeUnique<ActiveProfilePrefService>()); + base::MakeUnique<AshPrefConnector>()); }); info.task_runner = base::ThreadTaskRunnerHandle::Get(); - services->insert(std::make_pair(prefs::mojom::kForwarderServiceName, info)); + services->insert( + std::make_pair(ash::mojom::kPrefConnectorServiceName, info)); } if (!ash_util::IsRunningInMash()) {
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd index 5bd6cdb7..135dacfa 100644 --- a/chrome/browser/browser_resources.grd +++ b/chrome/browser/browser_resources.grd
@@ -20,13 +20,6 @@ <if expr="chromeos"> <structure name="IDR_FIRST_RUN_HTML" file="resources\chromeos\first_run\first_run.html" flattenhtml="true" type="chrome_html"/> <structure name="IDR_FIRST_RUN_JS" file="resources\chromeos\first_run\first_run.js" flattenhtml="true" type="chrome_html" /> - <structure name="IDR_HELP_CSS" file="resources\help\help.css" flattenhtml="true" type="chrome_html" /> - <structure name="IDR_HELP_HTML" file="resources\help\help.html" flattenhtml="true" type="chrome_html" /> - <structure name="IDR_HELP_CONTENT_CSS" file="resources\help\help_content.css" flattenhtml="true" type="chrome_html" /> - <structure name="IDR_HELP_CONTENT_HTML" file="resources\help\help_content.html" flattenhtml="true" type="chrome_html" /> - <structure name="IDR_HELP_PAGE_HTML" file="resources\help\help_page.html" flattenhtml="true" type="chrome_html" /> - <structure name="IDR_HELP_CHANNEL_CHANGE_PAGE_CSS" file="resources\help\channel_change_page.css" flattenhtml="true" type="chrome_html" /> - <structure name="IDR_HELP_CHANNEL_CHANGE_PAGE_HTML" file="resources\help\channel_change_page.html" flattenhtml="true" type="chrome_html" /> </if> <if expr="not is_android"> <structure name="IDR_INCOGNITO_TAB_HTML" file="resources\ntp4\incognito_tab.html" flattenhtml="true" type="chrome_html" /> @@ -251,11 +244,6 @@ <include name="IDR_HOTWORD_MANIFEST" file="resources\hotword\manifest.json" type="BINDATA" /> <include name="IDR_HOTWORD_AUDIO_VERIFICATION_MANIFEST" file="resources\hotword_audio_verification\manifest.json" type="BINDATA" /> </if> - <if expr="chromeos"> - <include name="IDR_HELP_JS" file="resources\help\help.js" flattenhtml="true" type="BINDATA" /> - <include name="IDR_HELP_PAGE_JS" file="resources\help\help_page.js" flattenhtml="true" type="BINDATA" /> - <include name="IDR_CHANNEL_CHANGE_PAGE_JS" file="resources\help\channel_change_page.js" flattenhtml="true" type="BINDATA" /> - </if> <if expr="not is_android and not is_ios"> <!-- MD Bookmarks. --> @@ -521,6 +509,8 @@ <include name="IDR_MERGE_SESSION_LOAD_HTML" file="resources\chromeos\merge_session_load.html" flattenhtml="true" type="BINDATA" /> <include name="IDR_OS_CREDITS_HTML" file="resources\chromeos\about_os_credits.html" flattenhtml="true" type="BINDATA" /> <include name="IDR_PROXY_SETTINGS_HTML" file="resources\chromeos\proxy_settings.html" flattenhtml="true" type="BINDATA" /> + <include name="IDR_INTERNET_DETAIL_DIALOG_HTML" file="resources\chromeos\internet_detail_dialog.html" flattenhtml="true" allowexternalscript="true" type="chrome_html" /> + <include name="IDR_INTERNET_DETAIL_DIALOG_JS" file="resources\chromeos\internet_detail_dialog.js" type="chrome_html" /> <include name="IDR_CERT_MANAGER_DIALOG_HTML" file="resources\chromeos\certificate_manager_dialog.html" flattenhtml="true" type="BINDATA" /> <include name="IDR_BLUETOOTH_PAIR_DEVICE_HTML" file="resources\chromeos\bluetooth_pair_device.html" flattenhtml="true" type="BINDATA" /> <include name="IDR_BLUETOOTH_DIALOG_HOST_HTML" file="resources\chromeos\bluetooth_dialog_host.html" flattenhtml="true" allowexternalscript="true" type="chrome_html" />
diff --git a/chrome/browser/browsing_data/downloads_counter_browsertest.cc b/chrome/browser/browsing_data/downloads_counter_browsertest.cc index e451143b..ad7f157 100644 --- a/chrome/browser/browsing_data/downloads_counter_browsertest.cc +++ b/chrome/browser/browsing_data/downloads_counter_browsertest.cc
@@ -122,7 +122,7 @@ const GURL& url, std::string mime_type, bool incognito) { - std::string guid = base::ToUpperASCII(base::GenerateGUID()); + std::string guid = base::GenerateGUID(); std::vector<GURL> url_chain; url_chain.push_back(url);
diff --git a/chrome/browser/chrome_content_browser_manifest_overlay.json b/chrome/browser/chrome_content_browser_manifest_overlay.json index b6a631e..3be9831 100644 --- a/chrome/browser/chrome_content_browser_manifest_overlay.json +++ b/chrome/browser/chrome_content_browser_manifest_overlay.json
@@ -31,13 +31,14 @@ "accessibility_autoclick": [ "ash:autoclick" ], "ash": [ "ash", "display" ], // Only used in classic ash case. + "ash_pref_connector": [ "pref_connector" ], + // Only used in classic ash case. "chrome": [ "input_device_controller" ], "device": [ "device:fingerprint" ], "identity": [ "identity_manager" ], "nacl_broker": [ "browser" ], "nacl_loader": [ "browser" ], "profiling": [ "memlog" ], - "preferences_forwarder": [ "pref_client" ], "preferences": [ "pref_client", "pref_control" ], "ui": [ "display_controller",
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index ea42528a..c66edb74 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -7,6 +7,7 @@ import("//extensions/features/features.gni") import("//media/media_options.gni") import("//printing/features/features.gni") +import("//services/service_manager/public/service_manifest.gni") import("//third_party/protobuf/proto_library.gni") import("//ui/ozone/ozone.gni") @@ -147,6 +148,7 @@ "//net", "//ppapi/proxy:ipc", # For PpapiMsg_LoadPlugin "//services/device/public/interfaces", + "//services/preferences/public/interfaces", "//services/service_manager/public/cpp", "//services/service_manager/runner/common", "//services/ui/public/interfaces/display", @@ -324,6 +326,8 @@ "arc/boot_phase_monitor/arc_boot_phase_monitor_bridge.h", "arc/boot_phase_monitor/arc_instance_throttle.cc", "arc/boot_phase_monitor/arc_instance_throttle.h", + "arc/cast_receiver/arc_cast_receiver_service.cc", + "arc/cast_receiver/arc_cast_receiver_service.h", "arc/downloads_watcher/arc_downloads_watcher_service.cc", "arc/downloads_watcher/arc_downloads_watcher_service.h", "arc/enterprise/arc_enterprise_reporting_service.cc", @@ -348,6 +352,8 @@ "arc/fileapi/arc_documents_provider_root.h", "arc/fileapi/arc_documents_provider_root_map.cc", "arc/fileapi/arc_documents_provider_root_map.h", + "arc/fileapi/arc_documents_provider_root_map_factory.cc", + "arc/fileapi/arc_documents_provider_root_map_factory.h", "arc/fileapi/arc_documents_provider_util.cc", "arc/fileapi/arc_documents_provider_util.h", "arc/fileapi/arc_documents_provider_watcher_manager.cc", @@ -710,6 +716,8 @@ "fileapi/mtp_watcher_manager.h", "fileapi/recent_context.cc", "fileapi/recent_context.h", + "fileapi/recent_download_source.cc", + "fileapi/recent_download_source.h", "fileapi/recent_model.cc", "fileapi/recent_model.h", "fileapi/recent_model_factory.cc", @@ -1328,6 +1336,8 @@ "power/renderer_freezer.h", "preferences.cc", "preferences.h", + "prefs/pref_connector_service.cc", + "prefs/pref_connector_service.h", "printing/combining_printer_detector.cc", "printing/combining_printer_detector.h", "printing/cups_print_job.cc", @@ -1763,6 +1773,7 @@ "fileapi/external_file_url_util_unittest.cc", "fileapi/file_access_permissions_unittest.cc", "fileapi/file_system_backend_unittest.cc", + "fileapi/recent_download_source_unittest.cc", "fileapi/recent_model_unittest.cc", "fileapi/test/fake_recent_source.cc", "hats/hats_finch_helper_unittest.cc", @@ -1987,3 +1998,8 @@ "attestation/attestation_key_payload.proto", ] } + +service_manifest("ash_pref_connector_manifest") { + name = "ash_pref_connector" + source = "prefs/ash_pref_connector_manifest.json" +}
diff --git a/chrome/browser/chromeos/arc/arc_auth_notification.cc b/chrome/browser/chromeos/arc/arc_auth_notification.cc index 4eea4be2..1cb37bec 100644 --- a/chrome/browser/chromeos/arc/arc_auth_notification.cc +++ b/chrome/browser/chromeos/arc/arc_auth_notification.cc
@@ -8,7 +8,6 @@ #include <string> #include <utility> -#include "ash/system/devicetype_utils.h" #include "base/macros.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/chromeos/arc/arc_optin_uma.h" @@ -20,6 +19,7 @@ #include "components/signin/core/account_id/account_id.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h" +#include "ui/chromeos/devicetype_utils.h" #include "ui/message_center/message_center.h" #include "ui/message_center/message_center_observer.h" #include "ui/message_center/notification.h" @@ -115,7 +115,7 @@ new message_center::Notification( message_center::NOTIFICATION_TYPE_SIMPLE, kFirstRunNotificationId, l10n_util::GetStringFUTF16(IDS_ARC_NOTIFICATION_TITLE, - ash::GetChromeOSDeviceName()), + ui::GetChromeOSDeviceName()), l10n_util::GetStringUTF16(IDS_ARC_NOTIFICATION_MESSAGE), resource_bundle.GetImageNamed(IDR_ARC_PLAY_STORE_NOTIFICATION), base::UTF8ToUTF16(kDisplaySource), GURL(), notifier_id, data,
diff --git a/chrome/browser/chromeos/arc/arc_migration_guide_notification.cc b/chrome/browser/chromeos/arc/arc_migration_guide_notification.cc index 1b152e0..6483b26 100644 --- a/chrome/browser/chromeos/arc/arc_migration_guide_notification.cc +++ b/chrome/browser/chromeos/arc/arc_migration_guide_notification.cc
@@ -4,7 +4,6 @@ #include "chrome/browser/chromeos/arc/arc_migration_guide_notification.h" -#include "ash/system/devicetype_utils.h" #include "ash/system/power/power_status.h" #include "base/macros.h" #include "base/memory/ptr_util.h" @@ -21,6 +20,7 @@ #include "components/signin/core/account_id/account_id.h" #include "components/user_manager/known_user.h" #include "ui/base/l10n/l10n_util.h" +#include "ui/chromeos/devicetype_utils.h" #include "ui/gfx/color_palette.h" #include "ui/gfx/paint_vector_icon.h" #include "ui/message_center/message_center.h" @@ -86,7 +86,7 @@ const base::string16 message = is_low_battery - ? ash::SubstituteChromeOSDeviceType( + ? ui::SubstituteChromeOSDeviceType( IDS_ARC_MIGRATE_ENCRYPTION_NOTIFICATION_LOW_BATTERY_MESSAGE) : l10n_util::GetStringUTF16( IDS_ARC_MIGRATE_ENCRYPTION_NOTIFICATION_MESSAGE);
diff --git a/chrome/browser/chromeos/arc/arc_service_launcher.cc b/chrome/browser/chromeos/arc/arc_service_launcher.cc index d5949c8..e9b9858 100644 --- a/chrome/browser/chromeos/arc/arc_service_launcher.cc +++ b/chrome/browser/chromeos/arc/arc_service_launcher.cc
@@ -15,6 +15,7 @@ #include "chrome/browser/chromeos/arc/arc_util.h" #include "chrome/browser/chromeos/arc/auth/arc_auth_service.h" #include "chrome/browser/chromeos/arc/boot_phase_monitor/arc_boot_phase_monitor_bridge.h" +#include "chrome/browser/chromeos/arc/cast_receiver/arc_cast_receiver_service.h" #include "chrome/browser/chromeos/arc/downloads_watcher/arc_downloads_watcher_service.h" #include "chrome/browser/chromeos/arc/enterprise/arc_enterprise_reporting_service.h" #include "chrome/browser/chromeos/arc/fileapi/arc_file_system_bridge.h" @@ -131,6 +132,7 @@ ArcBluetoothBridge::GetForBrowserContext(profile); ArcBootErrorNotification::GetForBrowserContext(profile); ArcBootPhaseMonitorBridge::GetForBrowserContext(profile); + ArcCastReceiverService::GetForBrowserContext(profile); ArcClipboardBridge::GetForBrowserContext(profile); ArcCrashCollectorBridge::GetForBrowserContext(profile); ArcDownloadsWatcherService::GetForBrowserContext(profile);
diff --git a/chrome/browser/chromeos/arc/arc_support_host.cc b/chrome/browser/chromeos/arc/arc_support_host.cc index 31e917f..0eb25c3 100644 --- a/chrome/browser/chromeos/arc/arc_support_host.cc +++ b/chrome/browser/chromeos/arc/arc_support_host.cc
@@ -7,7 +7,6 @@ #include <string> #include <utility> -#include "ash/system/devicetype_utils.h" #include "base/bind.h" #include "base/i18n/timezone.h" #include "base/json/json_reader.h" @@ -28,6 +27,7 @@ #include "extensions/browser/extension_registry.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/webui/web_ui_util.h" +#include "ui/chromeos/devicetype_utils.h" #include "ui/display/screen.h" namespace {
diff --git a/chrome/browser/chromeos/arc/cast_receiver/arc_cast_receiver_service.cc b/chrome/browser/chromeos/arc/cast_receiver/arc_cast_receiver_service.cc new file mode 100644 index 0000000..866b3c5 --- /dev/null +++ b/chrome/browser/chromeos/arc/cast_receiver/arc_cast_receiver_service.cc
@@ -0,0 +1,114 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/arc/cast_receiver/arc_cast_receiver_service.h" + +#include "base/bind.h" +#include "base/bind_helpers.h" +#include "base/logging.h" +#include "base/memory/ptr_util.h" +#include "base/memory/singleton.h" +#include "base/strings/utf_string_conversions.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/common/pref_names.h" +#include "components/arc/arc_bridge_service.h" +#include "components/arc/arc_browser_context_keyed_service_factory_base.h" +#include "components/prefs/pref_change_registrar.h" +#include "components/prefs/pref_service.h" + +namespace arc { +namespace { + +// A callback for CastReceiverInstance calls that ignores the result passed +// to it. We use this for calls made from a preferences observer since there +// is noone to pass that result to now. +void OnResultReceivedIgnoreResult(mojom::CastReceiverInstance::Result) {} + +// Singleton factory for ArcCastReceiverService. +class ArcCastReceiverServiceFactory + : public internal::ArcBrowserContextKeyedServiceFactoryBase< + ArcCastReceiverService, + ArcCastReceiverServiceFactory> { + public: + // Factory name used by ArcBrowserContextKeyedServiceFactoryBase. + static constexpr const char* kName = "ArcCastReceiverServiceFactory"; + + static ArcCastReceiverServiceFactory* GetInstance() { + return base::Singleton<ArcCastReceiverServiceFactory>::get(); + } + + private: + friend base::DefaultSingletonTraits<ArcCastReceiverServiceFactory>; + ArcCastReceiverServiceFactory() = default; + ~ArcCastReceiverServiceFactory() override = default; +}; + +} // namespace + +// static +ArcCastReceiverService* ArcCastReceiverService::GetForBrowserContext( + content::BrowserContext* context) { + return ArcCastReceiverServiceFactory::GetForBrowserContext(context); +} + +ArcCastReceiverService::ArcCastReceiverService(content::BrowserContext* context, + ArcBridgeService* bridge_service) + : arc_bridge_service_(bridge_service) { + arc_bridge_service_->cast_receiver()->AddObserver(this); + + pref_change_registrar_ = base::MakeUnique<PrefChangeRegistrar>(); + pref_change_registrar_->Init( + Profile::FromBrowserContext(context)->GetPrefs()); + // Observe prefs for the Cast Receiver. We can use base::Unretained() here + // because we own |pref_change_registrar_|. + pref_change_registrar_->Add( + prefs::kCastReceiverEnabled, + base::Bind(&ArcCastReceiverService::OnCastReceiverEnabledChanged, + base::Unretained(this))); + pref_change_registrar_->Add( + prefs::kCastReceiverName, + base::Bind(&ArcCastReceiverService::OnCastReceiverNameChanged, + base::Unretained(this))); +} + +ArcCastReceiverService::~ArcCastReceiverService() { + arc_bridge_service_->cast_receiver()->RemoveObserver(this); +} + +void ArcCastReceiverService::OnInstanceReady() { + // Push all existing preferences to the Cast Receiver. Always end with + // the preference for enabling the receiver so that it does not show up + // briefly with the wrong settings (e.g. its name). + OnCastReceiverNameChanged(); + // Now sets whether the receiver is enabled or not, which will make it + // discoverable if needed. + OnCastReceiverEnabledChanged(); +} + +void ArcCastReceiverService::OnCastReceiverEnabledChanged() const { + mojom::CastReceiverInstance* cast_receiver_instance = + ARC_GET_INSTANCE_FOR_METHOD(arc_bridge_service_->cast_receiver(), + SetEnabled); + if (!cast_receiver_instance) + return; + cast_receiver_instance->SetEnabled( + pref_change_registrar_->prefs()->GetBoolean(prefs::kCastReceiverEnabled), + base::Bind(&OnResultReceivedIgnoreResult)); +} + +void ArcCastReceiverService::OnCastReceiverNameChanged() const { + mojom::CastReceiverInstance* cast_receiver_instance = + ARC_GET_INSTANCE_FOR_METHOD(arc_bridge_service_->cast_receiver(), + SetName); + if (!cast_receiver_instance) + return; + const PrefService::Preference* pref = + pref_change_registrar_->prefs()->FindPreference(prefs::kCastReceiverName); + if (!pref) + return; + cast_receiver_instance->SetName(pref->GetValue()->GetString(), + base::Bind(&OnResultReceivedIgnoreResult)); +} + +} // namespace arc
diff --git a/chrome/browser/chromeos/arc/cast_receiver/arc_cast_receiver_service.h b/chrome/browser/chromeos/arc/cast_receiver/arc_cast_receiver_service.h new file mode 100644 index 0000000..ce8cd43 --- /dev/null +++ b/chrome/browser/chromeos/arc/cast_receiver/arc_cast_receiver_service.h
@@ -0,0 +1,59 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_CHROMEOS_ARC_CAST_RECEIVER_ARC_CAST_RECEIVER_SERVICE_H_ +#define CHROME_BROWSER_CHROMEOS_ARC_CAST_RECEIVER_ARC_CAST_RECEIVER_SERVICE_H_ + +#include <memory> + +#include "base/macros.h" +#include "components/arc/common/cast_receiver.mojom.h" +#include "components/arc/instance_holder.h" +#include "components/keyed_service/core/keyed_service.h" + +namespace content { +class BrowserContext; +} // namespace content + +class PrefChangeRegistrar; + +namespace arc { + +class ArcBridgeService; + +// Provides control of the Android Cast Receiver. +class ArcCastReceiverService + : public KeyedService, + public InstanceHolder<mojom::CastReceiverInstance>::Observer { + public: + // Returns singleton instance for the given BrowserContext, + // or nullptr if the browser |context| is not allowed to use ARC. + static ArcCastReceiverService* GetForBrowserContext( + content::BrowserContext* context); + + ArcCastReceiverService(content::BrowserContext* context, + ArcBridgeService* bridge_service); + ~ArcCastReceiverService() override; + + // InstanceHolder<mojom::CastReceiverInstance>::Observer overrides: + void OnInstanceReady() override; + + private: + // Callback for when the pref for enabling the Cast Receiver changes. + void OnCastReceiverEnabledChanged() const; + + // Callback for when the pref for naming the Cast Receiver changes. + void OnCastReceiverNameChanged() const; + + ArcBridgeService* const arc_bridge_service_; // Owned by ArcServiceManager. + + // Registrar to observe pref changes. + std::unique_ptr<PrefChangeRegistrar> pref_change_registrar_; + + DISALLOW_COPY_AND_ASSIGN(ArcCastReceiverService); +}; + +} // namespace arc + +#endif // CHROME_BROWSER_CHROMEOS_ARC_CAST_RECEIVER_ARC_CAST_RECEIVER_SERVICE_H_
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_async_file_util.cc b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_async_file_util.cc index 1f988db..6390543 100644 --- a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_async_file_util.cc +++ b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_async_file_util.cc
@@ -12,6 +12,7 @@ #include "chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root.h" #include "chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root_map.h" #include "chrome/browser/chromeos/arc/fileapi/arc_documents_provider_util.h" +#include "chrome/browser/profiles/profile.h" #include "content/public/browser/browser_thread.h" #include "storage/browser/blob/shareable_file_reference.h" #include "storage/browser/fileapi/file_system_operation_context.h" @@ -21,9 +22,80 @@ namespace arc { -ArcDocumentsProviderAsyncFileUtil::ArcDocumentsProviderAsyncFileUtil( - ArcDocumentsProviderRootMap* roots) - : roots_(roots) {} +namespace { + +void OnGetFileInfoOnUIThread( + const ArcDocumentsProviderRoot::GetFileInfoCallback& callback, + base::File::Error result, + const base::File::Info& info) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, + base::BindOnce(callback, result, info)); +} + +void OnReadDirectoryOnUIThread( + const ArcDocumentsProviderRoot::ReadDirectoryCallback& callback, + base::File::Error result, + const storage::AsyncFileUtil::EntryList& entries, + bool has_more) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, + base::BindOnce(callback, result, entries, has_more)); +} + +void GetFileInfoOnUIThread( + const storage::FileSystemURL& url, + int fields, + const ArcDocumentsProviderRoot::GetFileInfoCallback& callback) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + + ArcDocumentsProviderRootMap* roots = + ArcDocumentsProviderRootMap::GetForArcBrowserContext(); + if (!roots) { + OnGetFileInfoOnUIThread(callback, base::File::FILE_ERROR_SECURITY, + base::File::Info()); + return; + } + + base::FilePath path; + ArcDocumentsProviderRoot* root = roots->ParseAndLookup(url, &path); + if (!root) { + OnGetFileInfoOnUIThread(callback, base::File::FILE_ERROR_NOT_FOUND, + base::File::Info()); + return; + } + + root->GetFileInfo(path, base::Bind(&OnGetFileInfoOnUIThread, callback)); +} + +void ReadDirectoryOnUIThread( + const storage::FileSystemURL& url, + const ArcDocumentsProviderRoot::ReadDirectoryCallback& callback) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + + ArcDocumentsProviderRootMap* roots = + ArcDocumentsProviderRootMap::GetForArcBrowserContext(); + if (!roots) { + OnReadDirectoryOnUIThread(callback, base::File::FILE_ERROR_SECURITY, + storage::AsyncFileUtil::EntryList(), false); + return; + } + + base::FilePath path; + ArcDocumentsProviderRoot* root = roots->ParseAndLookup(url, &path); + if (!root) { + OnReadDirectoryOnUIThread(callback, base::File::FILE_ERROR_NOT_FOUND, + storage::AsyncFileUtil::EntryList(), false); + return; + } + + root->ReadDirectory(path, base::Bind(&OnReadDirectoryOnUIThread, callback)); +} + +} // namespace + +ArcDocumentsProviderAsyncFileUtil::ArcDocumentsProviderAsyncFileUtil() = + default; ArcDocumentsProviderAsyncFileUtil::~ArcDocumentsProviderAsyncFileUtil() = default; @@ -68,14 +140,9 @@ DCHECK_CURRENTLY_ON(BrowserThread::IO); DCHECK_EQ(storage::kFileSystemTypeArcDocumentsProvider, url.type()); - base::FilePath path; - ArcDocumentsProviderRoot* root = roots_->ParseAndLookup(url, &path); - if (!root) { - callback.Run(base::File::FILE_ERROR_NOT_FOUND, base::File::Info()); - return; - } - - root->GetFileInfo(path, callback); + BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, + base::BindOnce(&GetFileInfoOnUIThread, url, fields, callback)); } void ArcDocumentsProviderAsyncFileUtil::ReadDirectory( @@ -85,14 +152,9 @@ DCHECK_CURRENTLY_ON(BrowserThread::IO); DCHECK_EQ(storage::kFileSystemTypeArcDocumentsProvider, url.type()); - base::FilePath path; - ArcDocumentsProviderRoot* root = roots_->ParseAndLookup(url, &path); - if (!root) { - callback.Run(base::File::FILE_ERROR_NOT_FOUND, EntryList(), false); - return; - } - - root->ReadDirectory(path, callback); + BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, + base::BindOnce(&ReadDirectoryOnUIThread, url, callback)); } void ArcDocumentsProviderAsyncFileUtil::Touch(
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_async_file_util.h b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_async_file_util.h index 32b4a196..24037e2 100644 --- a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_async_file_util.h +++ b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_async_file_util.h
@@ -13,15 +13,12 @@ namespace arc { -class ArcDocumentsProviderRootMap; - // The implementation of storage::AsyncFileUtil for media view. // // All of the methods must be called on the IO thread. class ArcDocumentsProviderAsyncFileUtil : public storage::AsyncFileUtil { public: - explicit ArcDocumentsProviderAsyncFileUtil( - ArcDocumentsProviderRootMap* roots); + ArcDocumentsProviderAsyncFileUtil(); ~ArcDocumentsProviderAsyncFileUtil() override; // storage::AsyncFileUtil overrides. @@ -92,9 +89,6 @@ const CreateSnapshotFileCallback& callback) override; private: - // Owned by ArcDocumentsProviderBackendDelegate. - ArcDocumentsProviderRootMap* const roots_; - DISALLOW_COPY_AND_ASSIGN(ArcDocumentsProviderAsyncFileUtil); };
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_backend_delegate.cc b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_backend_delegate.cc index 10dd24c..0c08f26e 100644 --- a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_backend_delegate.cc +++ b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_backend_delegate.cc
@@ -18,8 +18,8 @@ namespace arc { -ArcDocumentsProviderBackendDelegate::ArcDocumentsProviderBackendDelegate() - : async_file_util_(&roots_), watcher_manager_(&roots_) {} +ArcDocumentsProviderBackendDelegate::ArcDocumentsProviderBackendDelegate() = + default; ArcDocumentsProviderBackendDelegate::~ArcDocumentsProviderBackendDelegate() { DCHECK_CURRENTLY_ON(BrowserThread::IO); @@ -40,8 +40,7 @@ storage::FileSystemContext* context) { DCHECK_CURRENTLY_ON(BrowserThread::IO); - return base::MakeUnique<ArcDocumentsProviderFileStreamReader>(url, offset, - &roots_); + return base::MakeUnique<ArcDocumentsProviderFileStreamReader>(url, offset); } std::unique_ptr<storage::FileStreamWriter>
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_backend_delegate.h b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_backend_delegate.h index 2fbad14..667c3974 100644 --- a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_backend_delegate.h +++ b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_backend_delegate.h
@@ -41,7 +41,6 @@ const storage::URLCallback& callback) override; private: - ArcDocumentsProviderRootMap roots_; ArcDocumentsProviderAsyncFileUtil async_file_util_; ArcDocumentsProviderWatcherManager watcher_manager_;
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_file_stream_reader.cc b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_file_stream_reader.cc index dee5497..2fbed23 100644 --- a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_file_stream_reader.cc +++ b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_file_stream_reader.cc
@@ -12,29 +12,61 @@ #include "content/public/browser/browser_thread.h" #include "net/base/io_buffer.h" #include "net/base/net_errors.h" +#include "storage/browser/fileapi/file_system_url.h" #include "url/gurl.h" using content::BrowserThread; namespace arc { -ArcDocumentsProviderFileStreamReader::ArcDocumentsProviderFileStreamReader( +namespace { + +void OnResolveToContentUrlOnUIThread( + const ArcDocumentsProviderRoot::ResolveToContentUrlCallback& callback, + const GURL& url) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, + base::BindOnce(callback, url)); +} + +void ResolveToContentUrlOnUIThread( const storage::FileSystemURL& url, - int64_t offset, - ArcDocumentsProviderRootMap* roots) - : offset_(offset), content_url_resolved_(false), weak_ptr_factory_(this) { - DCHECK_CURRENTLY_ON(BrowserThread::IO); + const ArcDocumentsProviderRoot::ResolveToContentUrlCallback& callback) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + + ArcDocumentsProviderRootMap* roots = + ArcDocumentsProviderRootMap::GetForArcBrowserContext(); + if (!roots) { + OnResolveToContentUrlOnUIThread(callback, GURL()); + return; + } base::FilePath path; ArcDocumentsProviderRoot* root = roots->ParseAndLookup(url, &path); if (!root) { - content_url_resolved_ = true; + OnResolveToContentUrlOnUIThread(callback, GURL()); return; } + root->ResolveToContentUrl( - path, - base::Bind(&ArcDocumentsProviderFileStreamReader::OnResolveToContentUrl, - weak_ptr_factory_.GetWeakPtr())); + path, base::Bind(&OnResolveToContentUrlOnUIThread, callback)); +} + +} // namespace + +ArcDocumentsProviderFileStreamReader::ArcDocumentsProviderFileStreamReader( + const storage::FileSystemURL& url, + int64_t offset) + : offset_(offset), content_url_resolved_(false), weak_ptr_factory_(this) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + + BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, + base::BindOnce( + &ResolveToContentUrlOnUIThread, url, + base::Bind( + &ArcDocumentsProviderFileStreamReader::OnResolveToContentUrl, + weak_ptr_factory_.GetWeakPtr()))); } ArcDocumentsProviderFileStreamReader::~ArcDocumentsProviderFileStreamReader() {
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_file_stream_reader.h b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_file_stream_reader.h index 9a392d4..34323db 100644 --- a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_file_stream_reader.h +++ b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_file_stream_reader.h
@@ -23,17 +23,13 @@ namespace arc { -class ArcDocumentsProviderRootMap; - // FileStreamReader implementation for ARC documents provider file system. // It actually delegates operations to ArcContentFileSystemFileStreamReader. // TODO(crbug.com/678886): Write unit tests. class ArcDocumentsProviderFileStreamReader : public storage::FileStreamReader { public: - // |roots| can be released soon after the constructor returns. ArcDocumentsProviderFileStreamReader(const storage::FileSystemURL& url, - int64_t offset, - ArcDocumentsProviderRootMap* roots); + int64_t offset); ~ArcDocumentsProviderFileStreamReader() override; // storage::FileStreamReader override:
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root.cc b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root.cc index ae6b9c2b..41523b7 100644 --- a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root.cc +++ b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root.cc
@@ -33,23 +33,26 @@ kInvalidWatcherRequestId}; ArcDocumentsProviderRoot::ArcDocumentsProviderRoot( + ArcFileSystemOperationRunner* runner, const std::string& authority, const std::string& root_document_id) - : authority_(authority), + : runner_(runner), + authority_(authority), root_document_id_(root_document_id), - weak_ptr_factory_(this) {} + weak_ptr_factory_(this) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + runner_->AddObserver(this); +} ArcDocumentsProviderRoot::~ArcDocumentsProviderRoot() { - DCHECK_CURRENTLY_ON(BrowserThread::IO); - if (observer_wrapper_) - file_system_operation_runner_util::RemoveObserverOnIOThread( - std::move(observer_wrapper_)); + DCHECK_CURRENTLY_ON(BrowserThread::UI); + runner_->RemoveObserver(this); } void ArcDocumentsProviderRoot::GetFileInfo( const base::FilePath& path, const GetFileInfoCallback& callback) { - DCHECK_CURRENTLY_ON(BrowserThread::IO); + DCHECK_CURRENTLY_ON(BrowserThread::UI); ResolveToDocumentId( path, base::Bind(&ArcDocumentsProviderRoot::GetFileInfoWithDocumentId, weak_ptr_factory_.GetWeakPtr(), callback)); @@ -58,7 +61,7 @@ void ArcDocumentsProviderRoot::ReadDirectory( const base::FilePath& path, const ReadDirectoryCallback& callback) { - DCHECK_CURRENTLY_ON(BrowserThread::IO); + DCHECK_CURRENTLY_ON(BrowserThread::UI); ResolveToDocumentId( path, base::Bind(&ArcDocumentsProviderRoot::ReadDirectoryWithDocumentId, weak_ptr_factory_.GetWeakPtr(), callback)); @@ -68,7 +71,7 @@ const base::FilePath& path, const WatcherCallback& watcher_callback, const StatusCallback& callback) { - DCHECK_CURRENTLY_ON(BrowserThread::IO); + DCHECK_CURRENTLY_ON(BrowserThread::UI); if (path_to_watcher_data_.count(path)) { callback.Run(base::File::FILE_ERROR_FAILED); return; @@ -91,7 +94,7 @@ void ArcDocumentsProviderRoot::RemoveWatcher(const base::FilePath& path, const StatusCallback& callback) { - DCHECK_CURRENTLY_ON(BrowserThread::IO); + DCHECK_CURRENTLY_ON(BrowserThread::UI); auto iter = path_to_watcher_data_.find(path); if (iter == path_to_watcher_data_.end()) { callback.Run(base::File::FILE_ERROR_FAILED); @@ -105,16 +108,15 @@ callback.Run(base::File::FILE_OK); return; } - file_system_operation_runner_util::RemoveWatcherOnIOThread( - watcher_id, - base::Bind(&ArcDocumentsProviderRoot::OnWatcherRemoved, - weak_ptr_factory_.GetWeakPtr(), callback)); + runner_->RemoveWatcher(watcher_id, + base::Bind(&ArcDocumentsProviderRoot::OnWatcherRemoved, + weak_ptr_factory_.GetWeakPtr(), callback)); } void ArcDocumentsProviderRoot::ResolveToContentUrl( const base::FilePath& path, const ResolveToContentUrlCallback& callback) { - DCHECK_CURRENTLY_ON(BrowserThread::IO); + DCHECK_CURRENTLY_ON(BrowserThread::UI); ResolveToDocumentId( path, base::Bind(&ArcDocumentsProviderRoot::ResolveToContentUrlWithDocumentId, @@ -122,7 +124,7 @@ } void ArcDocumentsProviderRoot::OnWatchersCleared() { - DCHECK_CURRENTLY_ON(BrowserThread::IO); + DCHECK_CURRENTLY_ON(BrowserThread::UI); // Mark all watchers invalid. for (auto& entry : path_to_watcher_data_) entry.second = kInvalidWatcherData; @@ -131,7 +133,7 @@ void ArcDocumentsProviderRoot::GetFileInfoWithDocumentId( const GetFileInfoCallback& callback, const std::string& document_id) { - DCHECK_CURRENTLY_ON(BrowserThread::IO); + DCHECK_CURRENTLY_ON(BrowserThread::UI); if (document_id.empty()) { callback.Run(base::File::FILE_ERROR_NOT_FOUND, base::File::Info()); return; @@ -149,7 +151,7 @@ callback.Run(base::File::FILE_OK, info); return; } - file_system_operation_runner_util::GetDocumentOnIOThread( + runner_->GetDocument( authority_, document_id, base::Bind(&ArcDocumentsProviderRoot::GetFileInfoWithDocument, weak_ptr_factory_.GetWeakPtr(), callback)); @@ -158,7 +160,7 @@ void ArcDocumentsProviderRoot::GetFileInfoWithDocument( const GetFileInfoCallback& callback, mojom::DocumentPtr document) { - DCHECK_CURRENTLY_ON(BrowserThread::IO); + DCHECK_CURRENTLY_ON(BrowserThread::UI); if (document.is_null()) { callback.Run(base::File::FILE_ERROR_NOT_FOUND, base::File::Info()); return; @@ -175,7 +177,7 @@ void ArcDocumentsProviderRoot::ReadDirectoryWithDocumentId( const ReadDirectoryCallback& callback, const std::string& document_id) { - DCHECK_CURRENTLY_ON(BrowserThread::IO); + DCHECK_CURRENTLY_ON(BrowserThread::UI); if (document_id.empty()) { callback.Run(base::File::FILE_ERROR_NOT_FOUND, EntryList(), false /* has_more */); @@ -192,7 +194,7 @@ const ReadDirectoryCallback& callback, base::File::Error error, NameToThinDocumentMap mapping) { - DCHECK_CURRENTLY_ON(BrowserThread::IO); + DCHECK_CURRENTLY_ON(BrowserThread::UI); if (error != base::File::FILE_OK) { callback.Run(error, EntryList(), false /* has_more */); return; @@ -211,7 +213,7 @@ uint64_t watcher_request_id, const WatcherCallback& watcher_callback, const std::string& document_id) { - DCHECK_CURRENTLY_ON(BrowserThread::IO); + DCHECK_CURRENTLY_ON(BrowserThread::UI); if (IsWatcherInflightRequestCanceled(path, watcher_request_id)) return; @@ -222,14 +224,7 @@ return; } - // Start observing ArcFileSystemOperationRunner if we have not. - if (!observer_wrapper_) { - observer_wrapper_ = - new file_system_operation_runner_util::ObserverIOThreadWrapper(this); - file_system_operation_runner_util::AddObserverOnIOThread(observer_wrapper_); - } - - file_system_operation_runner_util::AddWatcherOnIOThread( + runner_->AddWatcher( authority_, document_id, watcher_callback, base::Bind(&ArcDocumentsProviderRoot::OnWatcherAdded, weak_ptr_factory_.GetWeakPtr(), path, watcher_request_id)); @@ -238,10 +233,10 @@ void ArcDocumentsProviderRoot::OnWatcherAdded(const base::FilePath& path, uint64_t watcher_request_id, int64_t watcher_id) { - DCHECK_CURRENTLY_ON(BrowserThread::IO); + DCHECK_CURRENTLY_ON(BrowserThread::UI); if (IsWatcherInflightRequestCanceled(path, watcher_request_id)) { - file_system_operation_runner_util::RemoveWatcherOnIOThread( + runner_->RemoveWatcher( watcher_id, base::Bind(&ArcDocumentsProviderRoot::OnWatcherAddedButRemoved, weak_ptr_factory_.GetWeakPtr())); @@ -255,13 +250,13 @@ } void ArcDocumentsProviderRoot::OnWatcherAddedButRemoved(bool success) { - DCHECK_CURRENTLY_ON(BrowserThread::IO); + DCHECK_CURRENTLY_ON(BrowserThread::UI); // Ignore |success|. } void ArcDocumentsProviderRoot::OnWatcherRemoved(const StatusCallback& callback, bool success) { - DCHECK_CURRENTLY_ON(BrowserThread::IO); + DCHECK_CURRENTLY_ON(BrowserThread::UI); callback.Run(success ? base::File::FILE_OK : base::File::FILE_ERROR_FAILED); } @@ -276,7 +271,7 @@ void ArcDocumentsProviderRoot::ResolveToContentUrlWithDocumentId( const ResolveToContentUrlCallback& callback, const std::string& document_id) { - DCHECK_CURRENTLY_ON(BrowserThread::IO); + DCHECK_CURRENTLY_ON(BrowserThread::UI); if (document_id.empty()) { callback.Run(GURL()); return; @@ -287,7 +282,7 @@ void ArcDocumentsProviderRoot::ResolveToDocumentId( const base::FilePath& path, const ResolveToDocumentIdCallback& callback) { - DCHECK_CURRENTLY_ON(BrowserThread::IO); + DCHECK_CURRENTLY_ON(BrowserThread::UI); std::vector<base::FilePath::StringType> components; path.GetComponents(&components); ResolveToDocumentIdRecursively(root_document_id_, components, callback); @@ -297,7 +292,7 @@ const std::string& document_id, const std::vector<base::FilePath::StringType>& components, const ResolveToDocumentIdCallback& callback) { - DCHECK_CURRENTLY_ON(BrowserThread::IO); + DCHECK_CURRENTLY_ON(BrowserThread::UI); if (components.empty()) { callback.Run(document_id); return; @@ -315,7 +310,7 @@ const ResolveToDocumentIdCallback& callback, base::File::Error error, NameToThinDocumentMap mapping) { - DCHECK_CURRENTLY_ON(BrowserThread::IO); + DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK(!components.empty()); if (error != base::File::FILE_OK) { callback.Run(std::string()); @@ -335,7 +330,7 @@ void ArcDocumentsProviderRoot::ReadDirectoryInternal( const std::string& document_id, const ReadDirectoryInternalCallback& callback) { - file_system_operation_runner_util::GetChildDocumentsOnIOThread( + runner_->GetChildDocuments( authority_, document_id, base::Bind( &ArcDocumentsProviderRoot::ReadDirectoryInternalWithChildDocuments,
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root.h b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root.h index d5bac2956..03632b9 100644 --- a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root.h +++ b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root.h
@@ -18,7 +18,6 @@ #include "base/memory/weak_ptr.h" #include "base/optional.h" #include "chrome/browser/chromeos/arc/fileapi/arc_file_system_operation_runner.h" -#include "chrome/browser/chromeos/arc/fileapi/arc_file_system_operation_runner_util.h" #include "components/arc/common/file_system.mojom.h" #include "storage/browser/fileapi/async_file_util.h" #include "storage/browser/fileapi/watcher_manager.h" @@ -29,7 +28,7 @@ // Represents a file system root in Android Documents Provider. // -// All methods must be called on the IO thread. +// All methods must be called on the UI thread. // If this object is deleted while there are in-flight operations, callbacks // for those operations will be never called. class ArcDocumentsProviderRoot : public ArcFileSystemOperationRunner::Observer { @@ -37,12 +36,14 @@ using GetFileInfoCallback = storage::AsyncFileUtil::GetFileInfoCallback; using ReadDirectoryCallback = storage::AsyncFileUtil::ReadDirectoryCallback; using ChangeType = storage::WatcherManager::ChangeType; + // TODO(nya): Use OnceCallback/RepeatingCallback. using WatcherCallback = base::Callback<void(ChangeType type)>; using StatusCallback = base::Callback<void(base::File::Error error)>; using ResolveToContentUrlCallback = base::Callback<void(const GURL& content_url)>; - ArcDocumentsProviderRoot(const std::string& authority, + ArcDocumentsProviderRoot(ArcFileSystemOperationRunner* runner, + const std::string& authority, const std::string& root_document_id); ~ArcDocumentsProviderRoot() override; @@ -213,6 +214,11 @@ const ReadDirectoryInternalCallback& callback, base::Optional<std::vector<mojom::DocumentPtr>> maybe_children); + // |runner_| outlives this object. ArcDocumentsProviderRootMap, the owner of + // this object, depends on ArcFileSystemOperationRunner in the + // BrowserContextKeyedServiceFactory dependency graph. + ArcFileSystemOperationRunner* const runner_; + const std::string authority_; const std::string root_document_id_; @@ -226,11 +232,6 @@ uint64_t next_watcher_request_id_ = 1; - // Can be null if this instance is not observing ArcFileSystemOperationRunner. - // Observation is started on the first call of AddWatcher(). - scoped_refptr<file_system_operation_runner_util::ObserverIOThreadWrapper> - observer_wrapper_; - base::WeakPtrFactory<ArcDocumentsProviderRoot> weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(ArcDocumentsProviderRoot);
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root_map.cc b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root_map.cc index 5de18cd..4976c4b3 100644 --- a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root_map.cc +++ b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root_map.cc
@@ -5,8 +5,15 @@ #include "chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root_map.h" #include "base/memory/ptr_util.h" +#include "chrome/browser/chromeos/arc/arc_util.h" #include "chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root.h" +#include "chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root_map_factory.h" #include "chrome/browser/chromeos/arc/fileapi/arc_documents_provider_util.h" +#include "chrome/browser/profiles/profile.h" +#include "components/arc/arc_service_manager.h" +#include "content/public/browser/browser_thread.h" + +using content::BrowserThread; namespace arc { @@ -26,19 +33,42 @@ } // namespace -ArcDocumentsProviderRootMap::ArcDocumentsProviderRootMap() { +// static +ArcDocumentsProviderRootMap* ArcDocumentsProviderRootMap::GetForBrowserContext( + content::BrowserContext* context) { + return ArcDocumentsProviderRootMapFactory::GetForBrowserContext(context); +} + +// static +ArcDocumentsProviderRootMap* +ArcDocumentsProviderRootMap::GetForArcBrowserContext() { + return GetForBrowserContext(ArcServiceManager::Get()->browser_context()); +} + +ArcDocumentsProviderRootMap::ArcDocumentsProviderRootMap(Profile* profile) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + DCHECK(IsArcAllowedForProfile(profile)); // Already checked in the factory. + + ArcFileSystemOperationRunner* runner = + ArcFileSystemOperationRunner::GetForBrowserContext(profile); + for (auto spec : kDocumentsProviderWhitelist) { map_[Key(spec.authority, spec.root_document_id)] = - base::MakeUnique<ArcDocumentsProviderRoot>(spec.authority, + base::MakeUnique<ArcDocumentsProviderRoot>(runner, spec.authority, spec.root_document_id); } } -ArcDocumentsProviderRootMap::~ArcDocumentsProviderRootMap() = default; +ArcDocumentsProviderRootMap::~ArcDocumentsProviderRootMap() { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + DCHECK(map_.empty()); +} ArcDocumentsProviderRoot* ArcDocumentsProviderRootMap::ParseAndLookup( const storage::FileSystemURL& url, base::FilePath* path) const { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + std::string authority; std::string root_document_id; base::FilePath tmp_path; @@ -51,4 +81,12 @@ return iter->second.get(); } +void ArcDocumentsProviderRootMap::Shutdown() { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + + // ArcDocumentsProviderRoot has a reference to another KeyedService + // (ArcFileSystemOperationRunner), so we need to destruct them on shutdown. + map_.clear(); +} + } // namespace arc
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root_map.h b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root_map.h index ad9e10a..891319b 100644 --- a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root_map.h +++ b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root_map.h
@@ -12,6 +12,13 @@ #include "base/files/file_path.h" #include "base/macros.h" +#include "components/keyed_service/core/keyed_service.h" + +class Profile; + +namespace content { +class BrowserContext; +} // namespace content namespace storage { class FileSystemURL; @@ -23,12 +30,22 @@ // Container of ArcDocumentsProviderRoot instances. // -// This class is thread-safe, but ArcDocumentsProviderRoot must be accessed -// only on the IO thread anyway. -class ArcDocumentsProviderRootMap { +// All member function must be called on the UI thread. +class ArcDocumentsProviderRootMap : public KeyedService { public: - ArcDocumentsProviderRootMap(); - ~ArcDocumentsProviderRootMap(); + ~ArcDocumentsProviderRootMap() override; + + // Returns an instance for the given browser context, or nullptr if ARC is not + // allowed for the browser context. + static ArcDocumentsProviderRootMap* GetForBrowserContext( + content::BrowserContext* context); + + // Returns an instance for the browser context associated with ARC, or nullptr + // if ARC is not allowed. + // TODO(nya): Remove this function when we support multi-user ARC. For now, + // it is okay to call this function only from chromeos::FileSystemBackend and + // its delegates. + static ArcDocumentsProviderRootMap* GetForArcBrowserContext(); // Looks up a root corresponding to |url|. // |path| is set to the remaining path part of |url|. @@ -36,7 +53,14 @@ ArcDocumentsProviderRoot* ParseAndLookup(const storage::FileSystemURL& url, base::FilePath* path) const; + // KeyedService overrides: + void Shutdown() override; + private: + friend class ArcDocumentsProviderRootMapFactory; + + explicit ArcDocumentsProviderRootMap(Profile* profile); + // Key is (authority, root_document_id). using Key = std::pair<std::string, std::string>; std::map<Key, std::unique_ptr<ArcDocumentsProviderRoot>> map_;
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root_map_factory.cc b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root_map_factory.cc new file mode 100644 index 0000000..ff42f39e --- /dev/null +++ b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root_map_factory.cc
@@ -0,0 +1,58 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root_map_factory.h" + +#include "chrome/browser/chromeos/arc/arc_util.h" +#include "chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root_map.h" +#include "chrome/browser/chromeos/arc/fileapi/arc_file_system_operation_runner.h" +#include "chrome/browser/profiles/incognito_helpers.h" +#include "chrome/browser/profiles/profile.h" +#include "components/keyed_service/content/browser_context_dependency_manager.h" + +namespace arc { + +// static +ArcDocumentsProviderRootMap* +ArcDocumentsProviderRootMapFactory::GetForBrowserContext( + content::BrowserContext* context) { + return static_cast<ArcDocumentsProviderRootMap*>( + GetInstance()->GetServiceForBrowserContext(context, true /* create */)); +} + +ArcDocumentsProviderRootMapFactory::ArcDocumentsProviderRootMapFactory() + : BrowserContextKeyedServiceFactory( + "ArcDocumentsProviderRootMap", + BrowserContextDependencyManager::GetInstance()) { + DependsOn(ArcFileSystemOperationRunner::GetFactory()); +} + +ArcDocumentsProviderRootMapFactory::~ArcDocumentsProviderRootMapFactory() = + default; + +// static +ArcDocumentsProviderRootMapFactory* +ArcDocumentsProviderRootMapFactory::GetInstance() { + return base::Singleton<ArcDocumentsProviderRootMapFactory>::get(); +} + +content::BrowserContext* +ArcDocumentsProviderRootMapFactory::GetBrowserContextToUse( + content::BrowserContext* context) const { + // Allow accessing ArcDocumentsProvider files in incognito mode. + return chrome::GetBrowserContextRedirectedInIncognito(context); +} + +KeyedService* ArcDocumentsProviderRootMapFactory::BuildServiceInstanceFor( + content::BrowserContext* context) const { + Profile* profile = Profile::FromBrowserContext(context); + + // Check if ARC is allowed for this profile. + if (!arc::IsArcAllowedForProfile(profile)) + return nullptr; + + return new ArcDocumentsProviderRootMap(profile); +} + +} // namespace arc
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root_map_factory.h b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root_map_factory.h new file mode 100644 index 0000000..476e3b60 --- /dev/null +++ b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root_map_factory.h
@@ -0,0 +1,45 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_CHROMEOS_ARC_FILEAPI_ARC_DOCUMENTS_PROVIDER_ROOT_MAP_FACTORY_H_ +#define CHROME_BROWSER_CHROMEOS_ARC_FILEAPI_ARC_DOCUMENTS_PROVIDER_ROOT_MAP_FACTORY_H_ + +#include "base/macros.h" +#include "base/memory/singleton.h" +#include "components/keyed_service/content/browser_context_keyed_service_factory.h" + +namespace arc { + +class ArcDocumentsProviderRootMap; + +class ArcDocumentsProviderRootMapFactory + : public BrowserContextKeyedServiceFactory { + public: + // Returns the ArcDocumentsProviderRootMap for |context|, creating it if not + // created yet. + static ArcDocumentsProviderRootMap* GetForBrowserContext( + content::BrowserContext* context); + + // Returns the singleton ArcDocumentsProviderRootMapFactory instance. + static ArcDocumentsProviderRootMapFactory* GetInstance(); + + private: + friend struct base::DefaultSingletonTraits< + ArcDocumentsProviderRootMapFactory>; + + ArcDocumentsProviderRootMapFactory(); + ~ArcDocumentsProviderRootMapFactory() override; + + // BrowserContextKeyedServiceFactory overrides. + content::BrowserContext* GetBrowserContextToUse( + content::BrowserContext* context) const override; + KeyedService* BuildServiceInstanceFor( + content::BrowserContext* context) const override; + + DISALLOW_COPY_AND_ASSIGN(ArcDocumentsProviderRootMapFactory); +}; + +} // namespace arc + +#endif // CHROME_BROWSER_CHROMEOS_ARC_FILEAPI_ARC_DOCUMENTS_PROVIDER_ROOT_MAP_FACTORY_H_
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root_unittest.cc b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root_unittest.cc index 3ac35a2..669ba2f 100644 --- a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root_unittest.cc +++ b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root_unittest.cc
@@ -136,8 +136,9 @@ base::RunLoop().RunUntilIdle(); ASSERT_TRUE(fake_file_system_.InitCalled()); - root_ = base::MakeUnique<ArcDocumentsProviderRoot>(kAuthority, - kRootSpec.document_id); + root_ = base::MakeUnique<ArcDocumentsProviderRoot>( + ArcFileSystemOperationRunner::GetForBrowserContext(profile_.get()), + kAuthority, kRootSpec.document_id); } void TearDown() override {
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_watcher_manager.cc b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_watcher_manager.cc index a81fbb9d..3245c61 100644 --- a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_watcher_manager.cc +++ b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_watcher_manager.cc
@@ -16,9 +16,83 @@ namespace arc { -ArcDocumentsProviderWatcherManager::ArcDocumentsProviderWatcherManager( - ArcDocumentsProviderRootMap* roots) - : roots_(roots), weak_ptr_factory_(this) {} +namespace { + +void OnAddWatcherOnUIThread( + const ArcDocumentsProviderRoot::StatusCallback& callback, + base::File::Error result) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, + base::BindOnce(callback, result)); +} + +void OnRemoveWatcherOnUIThread( + const ArcDocumentsProviderRoot::StatusCallback& callback, + base::File::Error result) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, + base::BindOnce(callback, result)); +} + +void OnNotificationOnUIThread( + const ArcDocumentsProviderRoot::WatcherCallback& notification_callback, + ArcDocumentsProviderRoot::ChangeType change_type) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, + base::BindOnce(notification_callback, change_type)); +} + +void AddWatcherOnUIThread( + const storage::FileSystemURL& url, + const ArcDocumentsProviderRoot::StatusCallback& callback, + const ArcDocumentsProviderRoot::WatcherCallback& notification_callback) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + + ArcDocumentsProviderRootMap* roots = + ArcDocumentsProviderRootMap::GetForArcBrowserContext(); + if (!roots) { + OnAddWatcherOnUIThread(callback, base::File::FILE_ERROR_SECURITY); + return; + } + + base::FilePath path; + ArcDocumentsProviderRoot* root = roots->ParseAndLookup(url, &path); + if (!root) { + OnAddWatcherOnUIThread(callback, base::File::FILE_ERROR_NOT_FOUND); + return; + } + + root->AddWatcher(path, + base::Bind(&OnNotificationOnUIThread, notification_callback), + base::Bind(&OnAddWatcherOnUIThread, callback)); +} + +void RemoveWatcherOnUIThread( + const storage::FileSystemURL& url, + const ArcDocumentsProviderRoot::StatusCallback& callback) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + + ArcDocumentsProviderRootMap* roots = + ArcDocumentsProviderRootMap::GetForArcBrowserContext(); + if (!roots) { + OnRemoveWatcherOnUIThread(callback, base::File::FILE_ERROR_SECURITY); + return; + } + + base::FilePath path; + ArcDocumentsProviderRoot* root = roots->ParseAndLookup(url, &path); + if (!root) { + OnRemoveWatcherOnUIThread(callback, base::File::FILE_ERROR_NOT_FOUND); + return; + } + + root->RemoveWatcher(path, base::Bind(&OnRemoveWatcherOnUIThread, callback)); +} + +} // namespace + +ArcDocumentsProviderWatcherManager::ArcDocumentsProviderWatcherManager() + : weak_ptr_factory_(this) {} ArcDocumentsProviderWatcherManager::~ArcDocumentsProviderWatcherManager() { DCHECK_CURRENTLY_ON(BrowserThread::IO); @@ -37,14 +111,14 @@ return; } - base::FilePath path; - ArcDocumentsProviderRoot* root = roots_->ParseAndLookup(url, &path); - if (!root) { - callback.Run(base::File::FILE_ERROR_NOT_FOUND); - return; - } - - root->AddWatcher(path, notification_callback, callback); + BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, + base::BindOnce( + &AddWatcherOnUIThread, url, + base::Bind(&ArcDocumentsProviderWatcherManager::OnAddWatcher, + weak_ptr_factory_.GetWeakPtr(), callback), + base::Bind(&ArcDocumentsProviderWatcherManager::OnNotification, + weak_ptr_factory_.GetWeakPtr(), notification_callback))); } void ArcDocumentsProviderWatcherManager::RemoveWatcher( @@ -59,14 +133,33 @@ return; } - base::FilePath path; - ArcDocumentsProviderRoot* root = roots_->ParseAndLookup(url, &path); - if (!root) { - callback.Run(base::File::FILE_ERROR_NOT_FOUND); - return; - } + BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, + base::BindOnce( + &RemoveWatcherOnUIThread, url, + base::Bind(&ArcDocumentsProviderWatcherManager::OnRemoveWatcher, + weak_ptr_factory_.GetWeakPtr(), callback))); +} - root->RemoveWatcher(path, callback); +void ArcDocumentsProviderWatcherManager::OnAddWatcher( + const StatusCallback& callback, + base::File::Error result) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + callback.Run(result); +} + +void ArcDocumentsProviderWatcherManager::OnRemoveWatcher( + const StatusCallback& callback, + base::File::Error result) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + callback.Run(result); +} + +void ArcDocumentsProviderWatcherManager::OnNotification( + const NotificationCallback& notification_callback, + ChangeType change_type) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + notification_callback.Run(change_type); } } // namespace arc
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_watcher_manager.h b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_watcher_manager.h index 17ddf72..8b1b4e8 100644 --- a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_watcher_manager.h +++ b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_watcher_manager.h
@@ -11,17 +11,17 @@ namespace arc { -class ArcDocumentsProviderRootMap; - // The implementation of storage::WatcherManager for ARC documents provider // filesystem. // // Note that this WatcherManager is not always correct. See comments at // ArcDocumentsProviderRoot::AddWatcher(). +// +// After destruction of this object, callbacks of pending operations will not +// be called. class ArcDocumentsProviderWatcherManager : public storage::WatcherManager { public: - explicit ArcDocumentsProviderWatcherManager( - ArcDocumentsProviderRootMap* roots); + ArcDocumentsProviderWatcherManager(); ~ArcDocumentsProviderWatcherManager() override; // storage::WatcherManager overrides. @@ -34,8 +34,11 @@ const StatusCallback& callback) override; private: - // Owned by ArcDocumentsProviderBackendDelegate. - ArcDocumentsProviderRootMap* const roots_; + void OnAddWatcher(const StatusCallback& callback, base::File::Error result); + void OnRemoveWatcher(const StatusCallback& callback, + base::File::Error result); + void OnNotification(const NotificationCallback& notification_callback, + ChangeType change_type); base::WeakPtrFactory<ArcDocumentsProviderWatcherManager> weak_ptr_factory_;
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_file_system_operation_runner_util.cc b/chrome/browser/chromeos/arc/fileapi/arc_file_system_operation_runner_util.cc index ccb9f56..28ad859 100644 --- a/chrome/browser/chromeos/arc/fileapi/arc_file_system_operation_runner_util.cc +++ b/chrome/browser/chromeos/arc/fileapi/arc_file_system_operation_runner_util.cc
@@ -60,126 +60,8 @@ runner->OpenFileToRead(url, callback); } -void GetDocumentOnUIThread(const std::string& authority, - const std::string& document_id, - const GetDocumentCallback& callback) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - auto* runner = GetArcFileSystemOperationRunner(); - if (!runner) { - DLOG(ERROR) << "ArcFileSystemOperationRunner unavailable. " - << "File system operations are dropped."; - callback.Run(mojom::DocumentPtr()); - return; - } - runner->GetDocument(authority, document_id, callback); -} - -void GetChildDocumentsOnUIThread(const std::string& authority, - const std::string& parent_document_id, - const GetChildDocumentsCallback& callback) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - auto* runner = GetArcFileSystemOperationRunner(); - if (!runner) { - DLOG(ERROR) << "ArcFileSystemOperationRunner unavailable. " - << "File system operations are dropped."; - callback.Run(base::nullopt); - return; - } - runner->GetChildDocuments(authority, parent_document_id, callback); -} - -void GetRecentDocumentsOnUIThread(const std::string& authority, - const std::string& root_id, - const GetRecentDocumentsCallback& callback) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - auto* runner = GetArcFileSystemOperationRunner(); - if (!runner) { - DLOG(ERROR) << "ArcFileSystemOperationRunner unavailable. " - << "File system operations are dropped."; - callback.Run(base::nullopt); - return; - } - runner->GetRecentDocuments(authority, root_id, callback); -} - -void AddWatcherOnUIThread(const std::string& authority, - const std::string& document_id, - const WatcherCallback& watcher_callback, - const AddWatcherCallback& callback) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - auto* runner = GetArcFileSystemOperationRunner(); - if (!runner) { - DLOG(ERROR) << "ArcFileSystemOperationRunner unavailable. " - << "File system operations are dropped."; - callback.Run(-1); - return; - } - runner->AddWatcher(authority, document_id, watcher_callback, callback); -} - -void RemoveWatcherOnUIThread(int64_t watcher_id, - const RemoveWatcherCallback& callback) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - auto* runner = GetArcFileSystemOperationRunner(); - if (!runner) { - DLOG(ERROR) << "ArcFileSystemOperationRunner unavailable. " - << "File system operations are dropped."; - callback.Run(false); - return; - } - runner->RemoveWatcher(watcher_id, callback); -} - -void AddObserverOnUIThread(scoped_refptr<ObserverIOThreadWrapper> observer) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - auto* runner = GetArcFileSystemOperationRunner(); - if (!runner) { - DLOG(ERROR) << "ArcFileSystemOperationRunner unavailable. " - << "File system operations are dropped."; - return; - } - runner->AddObserver(observer.get()); -} - -void RemoveObserverOnUIThread(scoped_refptr<ObserverIOThreadWrapper> observer) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - auto* runner = GetArcFileSystemOperationRunner(); - if (!runner) { - DLOG(ERROR) << "ArcFileSystemOperationRunner unavailable. " - << "File system operations are dropped."; - return; - } - runner->RemoveObserver(observer.get()); -} - } // namespace -ObserverIOThreadWrapper::ObserverIOThreadWrapper( - ArcFileSystemOperationRunner::Observer* underlying_observer) - : underlying_observer_(underlying_observer) {} - -ObserverIOThreadWrapper::~ObserverIOThreadWrapper() = default; - -void ObserverIOThreadWrapper::Disable() { - DCHECK_CURRENTLY_ON(BrowserThread::IO); - disabled_ = true; -} - -void ObserverIOThreadWrapper::OnWatchersCleared() { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - base::BindOnce(&ObserverIOThreadWrapper::OnWatchersClearedOnIOThread, - this)); -} - -void ObserverIOThreadWrapper::OnWatchersClearedOnIOThread() { - DCHECK_CURRENTLY_ON(BrowserThread::IO); - if (disabled_) - return; - underlying_observer_->OnWatchersCleared(); -} - void GetFileSizeOnIOThread(const GURL& url, const GetFileSizeCallback& callback) { DCHECK_CURRENTLY_ON(BrowserThread::IO); @@ -199,81 +81,6 @@ base::Bind(&PostToIOThread<mojo::ScopedHandle>, callback))); } -void GetDocumentOnIOThread(const std::string& authority, - const std::string& document_id, - const GetDocumentCallback& callback) { - DCHECK_CURRENTLY_ON(BrowserThread::IO); - BrowserThread::PostTask( - BrowserThread::UI, FROM_HERE, - base::BindOnce( - &GetDocumentOnUIThread, authority, document_id, - base::Bind(&PostToIOThread<mojom::DocumentPtr>, callback))); -} - -void GetChildDocumentsOnIOThread(const std::string& authority, - const std::string& parent_document_id, - const GetChildDocumentsCallback& callback) { - DCHECK_CURRENTLY_ON(BrowserThread::IO); - BrowserThread::PostTask( - BrowserThread::UI, FROM_HERE, - base::BindOnce( - &GetChildDocumentsOnUIThread, authority, parent_document_id, - base::Bind( - &PostToIOThread<base::Optional<std::vector<mojom::DocumentPtr>>>, - callback))); -} - -void GetRecentDocumentsOnIOThread(const std::string& authority, - const std::string& root_id, - const GetRecentDocumentsCallback& callback) { - DCHECK_CURRENTLY_ON(BrowserThread::IO); - BrowserThread::PostTask( - BrowserThread::UI, FROM_HERE, - base::BindOnce( - &GetRecentDocumentsOnUIThread, authority, root_id, - base::Bind( - &PostToIOThread<base::Optional<std::vector<mojom::DocumentPtr>>>, - callback))); -} - -void AddWatcherOnIOThread(const std::string& authority, - const std::string& document_id, - const WatcherCallback& watcher_callback, - const AddWatcherCallback& callback) { - DCHECK_CURRENTLY_ON(BrowserThread::IO); - BrowserThread::PostTask( - BrowserThread::UI, FROM_HERE, - base::BindOnce( - &AddWatcherOnUIThread, authority, document_id, - base::Bind(&PostToIOThread<ArcFileSystemOperationRunner::ChangeType>, - watcher_callback), - base::Bind(&PostToIOThread<int64_t>, callback))); -} - -void RemoveWatcherOnIOThread(int64_t watcher_id, - const RemoveWatcherCallback& callback) { - DCHECK_CURRENTLY_ON(BrowserThread::IO); - BrowserThread::PostTask( - BrowserThread::UI, FROM_HERE, - base::BindOnce(&RemoveWatcherOnUIThread, watcher_id, - base::Bind(&PostToIOThread<bool>, callback))); -} - -void AddObserverOnIOThread(scoped_refptr<ObserverIOThreadWrapper> observer) { - DCHECK_CURRENTLY_ON(BrowserThread::IO); - BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, - base::BindOnce(&AddObserverOnUIThread, observer)); -} - -void RemoveObserverOnIOThread(scoped_refptr<ObserverIOThreadWrapper> observer) { - DCHECK_CURRENTLY_ON(BrowserThread::IO); - // Disable the observer now to guarantee the underlying observer is never - // called after this function returns. - observer->Disable(); - BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, - base::BindOnce(&RemoveObserverOnUIThread, observer)); -} - } // namespace file_system_operation_runner_util } // namespace arc
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_file_system_operation_runner_util.h b/chrome/browser/chromeos/arc/fileapi/arc_file_system_operation_runner_util.h index 4268c2d5..0bb6e32 100644 --- a/chrome/browser/chromeos/arc/fileapi/arc_file_system_operation_runner_util.h +++ b/chrome/browser/chromeos/arc/fileapi/arc_file_system_operation_runner_util.h
@@ -19,48 +19,6 @@ using GetFileSizeCallback = ArcFileSystemOperationRunner::GetFileSizeCallback; using OpenFileToReadCallback = ArcFileSystemOperationRunner::OpenFileToReadCallback; -using GetDocumentCallback = ArcFileSystemOperationRunner::GetDocumentCallback; -using GetChildDocumentsCallback = - ArcFileSystemOperationRunner::GetChildDocumentsCallback; -using GetRecentDocumentsCallback = - ArcFileSystemOperationRunner::GetRecentDocumentsCallback; -using AddWatcherCallback = ArcFileSystemOperationRunner::AddWatcherCallback; -using RemoveWatcherCallback = - ArcFileSystemOperationRunner::RemoveWatcherCallback; -using WatcherCallback = ArcFileSystemOperationRunner::WatcherCallback; - -// Wraps an ArcFileSystemOperationRunner::Observer so it is called on the IO -// thread. -class ObserverIOThreadWrapper - : public base::RefCountedThreadSafe<ObserverIOThreadWrapper>, - public ArcFileSystemOperationRunner::Observer { - public: - explicit ObserverIOThreadWrapper( - ArcFileSystemOperationRunner::Observer* underlying_observer); - - // Disables the observer. After calling this function, the underlying observer - // will never be called. - // This function should be called on the IO thread. - void Disable(); - - // ArcFileSystemOperationRunner::Observer overrides: - void OnWatchersCleared() override; - - private: - friend class base::RefCountedThreadSafe<ObserverIOThreadWrapper>; - - ~ObserverIOThreadWrapper() override; - - void OnWatchersClearedOnIOThread(); - - ArcFileSystemOperationRunner::Observer* const underlying_observer_; - - // If set to true, |observer_| will not be called. This variable should be - // accessed only on the IO thread. - bool disabled_ = false; - - DISALLOW_COPY_AND_ASSIGN(ObserverIOThreadWrapper); -}; // Utility functions to post a task to run ArcFileSystemOperationRunner methods. // These functions must be called on the IO thread. Callbacks and observers will @@ -69,23 +27,6 @@ const GetFileSizeCallback& callback); void OpenFileToReadOnIOThread(const GURL& url, const OpenFileToReadCallback& callback); -void GetDocumentOnIOThread(const std::string& authority, - const std::string& document_id, - const GetDocumentCallback& callback); -void GetChildDocumentsOnIOThread(const std::string& authority, - const std::string& parent_document_id, - const GetChildDocumentsCallback& callback); -void GetRecentDocumentsOnIOThread(const std::string& authority, - const std::string& root_id, - const GetRecentDocumentsCallback& callback); -void AddWatcherOnIOThread(const std::string& authority, - const std::string& document_id, - const WatcherCallback& watcher_callback, - const AddWatcherCallback& callback); -void RemoveWatcherOnIOThread(int64_t watcher_id, - const RemoveWatcherCallback& callback); -void AddObserverOnIOThread(scoped_refptr<ObserverIOThreadWrapper> observer); -void RemoveObserverOnIOThread(scoped_refptr<ObserverIOThreadWrapper> observer); } // namespace file_system_operation_runner_util } // namespace arc
diff --git a/chrome/browser/chromeos/arc/notification/arc_provision_notification_service.cc b/chrome/browser/chromeos/arc/notification/arc_provision_notification_service.cc index 903dac69..6224792 100644 --- a/chrome/browser/chromeos/arc/notification/arc_provision_notification_service.cc +++ b/chrome/browser/chromeos/arc/notification/arc_provision_notification_service.cc
@@ -6,7 +6,6 @@ #include <utility> -#include "ash/system/devicetype_utils.h" #include "base/memory/ptr_util.h" #include "base/memory/singleton.h" #include "base/strings/utf_string_conversions.h" @@ -20,6 +19,7 @@ #include "components/user_manager/user_manager.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h" +#include "ui/chromeos/devicetype_utils.h" #include "ui/gfx/image/image.h" #include "ui/message_center/message_center.h" #include "ui/message_center/notification.h" @@ -60,7 +60,7 @@ IDS_ARC_MANAGED_PROVISION_NOTIFICATION_TITLE), l10n_util::GetStringFUTF16( IDS_ARC_MANAGED_PROVISION_NOTIFICATION_MESSAGE, - ash::GetChromeOSDeviceName()), + ui::GetChromeOSDeviceName()), gfx::Image(ui::ResourceBundle::GetSharedInstance().GetImageNamed( IDR_ARC_PLAY_STORE_OPTIN_IN_PROGRESS_NOTIFICATION)), base::UTF8ToUTF16(kManagedProvisionDisplaySource), GURL(),
diff --git a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc index 1d6352e..0c08bf0bb 100644 --- a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc +++ b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
@@ -94,6 +94,7 @@ #include "chrome/browser/chromeos/system/input_device_settings.h" #include "chrome/browser/chromeos/ui/low_disk_notification.h" #include "chrome/browser/chromeos/upgrade_detector_chromeos.h" +#include "chrome/browser/component_updater/cros_component_installer.h" #include "chrome/browser/defaults.h" #include "chrome/browser/lifetime/application_lifetime.h" #include "chrome/browser/net/chrome_network_delegate.h" @@ -788,6 +789,12 @@ // header of new-style notification. message_center::MessageCenter::Get()->SetProductOSName( l10n_util::GetStringUTF16(IDS_PRODUCT_OS_NAME)); + + // Register all installed components for regular update. + base::PostTaskWithTraitsAndReplyWithResult( + FROM_HERE, {base::MayBlock()}, + base::BindOnce(component_updater::CrOSComponent::GetInstalledComponents), + base::BindOnce(component_updater::CrOSComponent::RegisterComponents)); } class GuestLanguageSetCallbackData {
diff --git a/chrome/browser/chromeos/extensions/file_manager/file_manager_private_apitest.cc b/chrome/browser/chromeos/extensions/file_manager/file_manager_private_apitest.cc index c4413d18..3c5c971 100644 --- a/chrome/browser/chromeos/extensions/file_manager/file_manager_private_apitest.cc +++ b/chrome/browser/chromeos/extensions/file_manager/file_manager_private_apitest.cc
@@ -445,3 +445,21 @@ ASSERT_TRUE(RunComponentExtensionTest("file_browser/content_checksum_test")); } + +IN_PROC_BROWSER_TEST_F(FileManagerPrivateApiTest, Recent) { + base::ScopedTempDir temp_dir; + ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); + const base::FilePath downloads_dir = temp_dir.GetPath(); + + ASSERT_TRUE(file_manager::VolumeManager::Get(browser()->profile()) + ->RegisterDownloadsDirectoryForTesting(downloads_dir)); + + // Create an empty file. + { + base::File file(downloads_dir.Append("all-justice.jpg"), + base::File::FLAG_CREATE | base::File::FLAG_WRITE); + ASSERT_TRUE(file.IsValid()); + } + + ASSERT_TRUE(RunComponentExtensionTest("file_browser/recent_test")); +}
diff --git a/chrome/browser/chromeos/extensions/file_manager/private_api_drive.cc b/chrome/browser/chromeos/extensions/file_manager/private_api_drive.cc index 76f1f02..e3b0e44 100644 --- a/chrome/browser/chromeos/extensions/file_manager/private_api_drive.cc +++ b/chrome/browser/chromeos/extensions/file_manager/private_api_drive.cc
@@ -824,11 +824,11 @@ DCHECK_NE(options, -1); file_system->SearchMetadata( - params->search_params.query, - options, - params->search_params.max_results, - base::Bind(&FileManagerPrivateSearchDriveMetadataFunction:: - OnSearchMetadata, this)); + params->search_params.query, options, params->search_params.max_results, + drive::MetadataSearchOrder::LAST_ACCESSED, + base::Bind( + &FileManagerPrivateSearchDriveMetadataFunction::OnSearchMetadata, + this)); return true; }
diff --git a/chrome/browser/chromeos/fileapi/recent_download_source.cc b/chrome/browser/chromeos/fileapi/recent_download_source.cc new file mode 100644 index 0000000..fe867888a --- /dev/null +++ b/chrome/browser/chromeos/fileapi/recent_download_source.cc
@@ -0,0 +1,219 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/fileapi/recent_download_source.h" + +#include <utility> + +#include "base/files/file_path.h" +#include "base/memory/ptr_util.h" +#include "base/time/time.h" +#include "chrome/browser/chromeos/file_manager/path_util.h" +#include "content/public/browser/browser_thread.h" +#include "storage/browser/fileapi/external_mount_points.h" +#include "storage/browser/fileapi/file_system_context.h" +#include "storage/browser/fileapi/file_system_operation.h" +#include "storage/browser/fileapi/file_system_operation_runner.h" +#include "storage/browser/fileapi/file_system_url.h" + +using content::BrowserThread; + +namespace chromeos { + +namespace { + +void OnReadDirectoryOnIOThread( + const storage::FileSystemOperation::ReadDirectoryCallback& callback, + base::File::Error result, + const storage::FileSystemOperation::FileEntryList& entries, + bool has_more) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, + base::BindOnce(callback, result, entries, has_more)); +} + +void ReadDirectoryOnIOThread( + scoped_refptr<storage::FileSystemContext> file_system_context, + const storage::FileSystemURL& url, + const storage::FileSystemOperation::ReadDirectoryCallback& callback) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + + file_system_context->operation_runner()->ReadDirectory( + url, base::Bind(&OnReadDirectoryOnIOThread, callback)); +} + +void OnGetMetadataOnIOThread( + const storage::FileSystemOperation::GetMetadataCallback& callback, + base::File::Error result, + const base::File::Info& info) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, + base::BindOnce(callback, result, info)); +} + +void GetMetadataOnIOThread( + scoped_refptr<storage::FileSystemContext> file_system_context, + const storage::FileSystemURL& url, + int fields, + const storage::FileSystemOperation::GetMetadataCallback& callback) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + + file_system_context->operation_runner()->GetMetadata( + url, fields, base::Bind(&OnGetMetadataOnIOThread, callback)); +} + +} // namespace + +struct RecentDownloadSource::FileSystemURLWithLastModified { + storage::FileSystemURL url; + base::Time last_modified; + + friend bool operator<(const FileSystemURLWithLastModified& a, + const FileSystemURLWithLastModified& b) { + // Reverse the comparison order because std::priority_queue.pop() deletes + // the most *largest* element whereas we want to delete the *oldest* + // document. + return a.last_modified > b.last_modified; + } +}; + +RecentDownloadSource::RecentDownloadSource(Profile* profile) + : RecentDownloadSource(profile, kMaxFilesFromSingleSource) {} + +RecentDownloadSource::RecentDownloadSource(Profile* profile, + size_t max_num_files) + : mount_point_name_( + file_manager::util::GetDownloadsMountPointName(profile)), + max_num_files_(max_num_files), + weak_ptr_factory_(this) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); +} + +RecentDownloadSource::~RecentDownloadSource() { + DCHECK_CURRENTLY_ON(BrowserThread::UI); +} + +void RecentDownloadSource::GetRecentFiles(RecentContext context, + GetRecentFilesCallback callback) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + DCHECK(!context_.is_valid()); + DCHECK(callback_.is_null()); + DCHECK_EQ(0, inflight_readdirs_); + DCHECK_EQ(0, inflight_stats_); + DCHECK(top_entries_.empty()); + + context_ = std::move(context); + callback_ = std::move(callback); + + DCHECK(context_.is_valid()); + DCHECK(!callback_.is_null()); + + ScanDirectory(base::FilePath()); +} + +void RecentDownloadSource::ScanDirectory(const base::FilePath& path) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + DCHECK(context_.is_valid()); + + storage::FileSystemURL url = BuildDownloadsURL(path); + + ++inflight_readdirs_; + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + base::BindOnce(&ReadDirectoryOnIOThread, + make_scoped_refptr(context_.file_system_context()), url, + base::Bind(&RecentDownloadSource::OnReadDirectory, + weak_ptr_factory_.GetWeakPtr(), path))); +} + +void RecentDownloadSource::OnReadDirectory( + const base::FilePath& path, + base::File::Error result, + const storage::FileSystemOperation::FileEntryList& entries, + bool has_more) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + DCHECK(context_.is_valid()); + + for (const auto& entry : entries) { + base::FilePath subpath = path.Append(entry.name); + if (entry.is_directory) { + ScanDirectory(subpath); + } else { + storage::FileSystemURL url = BuildDownloadsURL(subpath); + ++inflight_stats_; + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + base::BindOnce( + &GetMetadataOnIOThread, + make_scoped_refptr(context_.file_system_context()), url, + storage::FileSystemOperation::GET_METADATA_FIELD_LAST_MODIFIED, + base::Bind(&RecentDownloadSource::OnGetMetadata, + weak_ptr_factory_.GetWeakPtr(), url))); + } + } + + if (has_more) + return; + + --inflight_readdirs_; + OnReadOrStatFinished(); +} + +void RecentDownloadSource::OnGetMetadata(const storage::FileSystemURL& url, + base::File::Error result, + const base::File::Info& info) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + + if (result == base::File::FILE_OK) { + top_entries_.emplace( + FileSystemURLWithLastModified{url, info.last_modified}); + while (top_entries_.size() > max_num_files_) + top_entries_.pop(); + } + + --inflight_stats_; + OnReadOrStatFinished(); +} + +void RecentDownloadSource::OnReadOrStatFinished() { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + + if (inflight_readdirs_ > 0 || inflight_stats_ > 0) + return; + + // All reads/scans completed. + RecentFileList files; + while (!top_entries_.empty()) { + files.emplace_back(top_entries_.top().url); + top_entries_.pop(); + } + + context_ = RecentContext(); + GetRecentFilesCallback callback; + std::swap(callback, callback_); + + DCHECK(!context_.is_valid()); + DCHECK(callback_.is_null()); + DCHECK_EQ(0, inflight_readdirs_); + DCHECK_EQ(0, inflight_stats_); + DCHECK(top_entries_.empty()); + + std::move(callback).Run(std::move(files)); +} + +storage::FileSystemURL RecentDownloadSource::BuildDownloadsURL( + const base::FilePath& path) const { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + DCHECK(context_.is_valid()); + + storage::ExternalMountPoints* mount_points = + storage::ExternalMountPoints::GetSystemInstance(); + + return mount_points->CreateExternalFileSystemURL(context_.origin(), + mount_point_name_, path); +} + +} // namespace chromeos
diff --git a/chrome/browser/chromeos/fileapi/recent_download_source.h b/chrome/browser/chromeos/fileapi/recent_download_source.h new file mode 100644 index 0000000..3679bab --- /dev/null +++ b/chrome/browser/chromeos/fileapi/recent_download_source.h
@@ -0,0 +1,77 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_CHROMEOS_FILEAPI_RECENT_DOWNLOAD_SOURCE_H_ +#define CHROME_BROWSER_CHROMEOS_FILEAPI_RECENT_DOWNLOAD_SOURCE_H_ + +#include <memory> +#include <queue> +#include <string> +#include <vector> + +#include "base/files/file.h" +#include "base/files/file_path.h" +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "base/optional.h" +#include "chrome/browser/chromeos/fileapi/recent_context.h" +#include "chrome/browser/chromeos/fileapi/recent_model.h" +#include "chrome/browser/chromeos/fileapi/recent_source.h" +#include "storage/browser/fileapi/file_system_operation.h" + +class Profile; + +namespace chromeos { + +// RecentSource implementation for Downloads files. +// +// All member functions must be called on the UI thread. +class RecentDownloadSource : public RecentSource { + public: + explicit RecentDownloadSource(Profile* profile); + RecentDownloadSource(Profile* profile, size_t max_num_files); + ~RecentDownloadSource() override; + + // RecentSource overrides: + void GetRecentFiles(RecentContext context, + GetRecentFilesCallback callback) override; + + private: + struct FileSystemURLWithLastModified; + + void ScanDirectory(const base::FilePath& path); + void OnReadDirectory( + const base::FilePath& path, + base::File::Error result, + const storage::FileSystemOperation::FileEntryList& entries, + bool has_more); + void OnGetMetadata(const storage::FileSystemURL& url, + base::File::Error result, + const base::File::Info& info); + void OnReadOrStatFinished(); + + storage::FileSystemURL BuildDownloadsURL(const base::FilePath& path) const; + + const std::string mount_point_name_; + const size_t max_num_files_; + + // Parameters given to GetRecentFiles(). + RecentContext context_; + GetRecentFilesCallback callback_; + + // Number of ReadDirectory() calls in flight. + int inflight_readdirs_ = 0; + // Number of GetMetadata() calls in flight. + int inflight_stats_ = 0; + // Most recently modified entries. + std::priority_queue<FileSystemURLWithLastModified> top_entries_; + + base::WeakPtrFactory<RecentDownloadSource> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(RecentDownloadSource); +}; + +} // namespace chromeos + +#endif // CHROME_BROWSER_CHROMEOS_FILEAPI_RECENT_DOWNLOAD_SOURCE_H_
diff --git a/chrome/browser/chromeos/fileapi/recent_download_source_unittest.cc b/chrome/browser/chromeos/fileapi/recent_download_source_unittest.cc new file mode 100644 index 0000000..afd704d4 --- /dev/null +++ b/chrome/browser/chromeos/fileapi/recent_download_source_unittest.cc
@@ -0,0 +1,109 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <memory> +#include <string> +#include <vector> + +#include "base/files/file.h" +#include "base/files/scoped_temp_dir.h" +#include "base/memory/ptr_util.h" +#include "base/run_loop.h" +#include "base/time/time.h" +#include "chrome/browser/chromeos/file_manager/path_util.h" +#include "chrome/browser/chromeos/fileapi/recent_context.h" +#include "chrome/browser/chromeos/fileapi/recent_download_source.h" +#include "chrome/test/base/testing_profile.h" +#include "content/public/test/test_browser_thread_bundle.h" +#include "storage/browser/fileapi/external_mount_points.h" +#include "storage/browser/fileapi/file_system_context.h" +#include "storage/browser/fileapi/file_system_url.h" +#include "storage/browser/test/test_file_system_context.h" +#include "storage/common/fileapi/file_system_mount_option.h" +#include "storage/common/fileapi/file_system_types.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "url/gurl.h" + +namespace chromeos { +namespace { + +class RecentDownloadSourceTest : public testing::Test { + public: + RecentDownloadSourceTest() : origin_("https://example.com/") {} + + void SetUp() override { + profile_ = base::MakeUnique<TestingProfile>(); + + ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); + + file_system_context_ = content::CreateFileSystemContextForTesting( + nullptr, temp_dir_.GetPath()); + + RegisterFakeDownloadsFileSystem(); + + source_ = base::MakeUnique<RecentDownloadSource>(profile_.get(), + 3 /* max_num_files */); + + base_time_ = base::Time::Now(); + } + + protected: + void RegisterFakeDownloadsFileSystem() const { + storage::ExternalMountPoints* mount_points = + storage::ExternalMountPoints::GetSystemInstance(); + std::string mount_point_name = + file_manager::util::GetDownloadsMountPointName(profile_.get()); + + mount_points->RevokeFileSystem(mount_point_name); + ASSERT_TRUE(mount_points->RegisterFileSystem( + mount_point_name, storage::kFileSystemTypeTest, + storage::FileSystemMountOption(), base::FilePath())); + } + + bool CreateEmptyFile(const std::string& filename, int delta_time_in_seconds) { + base::File file(temp_dir_.GetPath().Append(filename), + base::File::FLAG_CREATE | base::File::FLAG_WRITE); + if (!file.IsValid()) + return false; + + base::Time time = + base_time_ + base::TimeDelta::FromSeconds(delta_time_in_seconds); + return file.SetTimes(time, time); + } + + content::TestBrowserThreadBundle thread_bundle_; + const GURL origin_; + std::unique_ptr<TestingProfile> profile_; + base::ScopedTempDir temp_dir_; + scoped_refptr<storage::FileSystemContext> file_system_context_; + std::unique_ptr<RecentDownloadSource> source_; + base::Time base_time_; +}; + +TEST_F(RecentDownloadSourceTest, GetRecentFiles) { + ASSERT_TRUE(CreateEmptyFile("1.jpg", 1)); // Oldest + ASSERT_TRUE(CreateEmptyFile("2.jpg", 2)); + ASSERT_TRUE(CreateEmptyFile("3.jpg", 3)); + ASSERT_TRUE(CreateEmptyFile("4.jpg", 4)); // Newest + + base::RunLoop run_loop; + + source_->GetRecentFiles( + RecentContext(file_system_context_.get(), origin_), + base::BindOnce( + [](base::RunLoop* run_loop, + std::vector<storage::FileSystemURL> files) { + run_loop->Quit(); + ASSERT_EQ(3u, files.size()); + EXPECT_EQ("2.jpg", files[0].path().BaseName().value()); + EXPECT_EQ("3.jpg", files[1].path().BaseName().value()); + EXPECT_EQ("4.jpg", files[2].path().BaseName().value()); + }, + &run_loop)); + + run_loop.Run(); +} + +} // namespace +} // namespace chromeos
diff --git a/chrome/browser/chromeos/fileapi/recent_model.cc b/chrome/browser/chromeos/fileapi/recent_model.cc index 1aa38d7..fb9617a 100644 --- a/chrome/browser/chromeos/fileapi/recent_model.cc +++ b/chrome/browser/chromeos/fileapi/recent_model.cc
@@ -14,6 +14,7 @@ #include "base/strings/stringprintf.h" #include "base/time/time.h" #include "chrome/browser/chromeos/fileapi/recent_context.h" +#include "chrome/browser/chromeos/fileapi/recent_download_source.h" #include "chrome/browser/chromeos/fileapi/recent_model_factory.h" #include "chrome/browser/chromeos/fileapi/recent_source.h" #include "content/public/browser/browser_thread.h" @@ -31,7 +32,7 @@ std::vector<std::unique_ptr<RecentSource>> CreateDefaultSources( Profile* profile) { std::vector<std::unique_ptr<RecentSource>> sources; - // TODO(nya): Add source implementations. + sources.emplace_back(base::MakeUnique<RecentDownloadSource>(profile)); return sources; }
diff --git a/chrome/browser/chromeos/login/session/user_session_manager.cc b/chrome/browser/chromeos/login/session/user_session_manager.cc index d5923ff81..3c39f83c 100644 --- a/chrome/browser/chromeos/login/session/user_session_manager.cc +++ b/chrome/browser/chromeos/login/session/user_session_manager.cc
@@ -425,7 +425,7 @@ should_launch_browser_(true), waiting_for_child_account_status_(false), weak_factory_(this) { - net::NetworkChangeNotifier::AddConnectionTypeObserver(this); + net::NetworkChangeNotifier::AddNetworkChangeObserver(this); user_manager::UserManager::Get()->AddSessionStateObserver(this); } @@ -436,7 +436,7 @@ // / UserSessionManager objects. if (user_manager::UserManager::IsInitialized()) user_manager::UserManager::Get()->RemoveSessionStateObserver(this); - net::NetworkChangeNotifier::RemoveConnectionTypeObserver(this); + net::NetworkChangeNotifier::RemoveNetworkChangeObserver(this); } void UserSessionManager::SetShouldObtainHandleInTests( @@ -911,7 +911,7 @@ } } -void UserSessionManager::OnConnectionTypeChanged( +void UserSessionManager::OnNetworkChanged( net::NetworkChangeNotifier::ConnectionType type) { user_manager::UserManager* user_manager = user_manager::UserManager::Get(); if (type == net::NetworkChangeNotifier::CONNECTION_NONE ||
diff --git a/chrome/browser/chromeos/login/session/user_session_manager.h b/chrome/browser/chromeos/login/session/user_session_manager.h index 592b842..5e9ab645 100644 --- a/chrome/browser/chromeos/login/session/user_session_manager.h +++ b/chrome/browser/chromeos/login/session/user_session_manager.h
@@ -83,7 +83,7 @@ // load profile, restore OAuth authentication session etc. class UserSessionManager : public OAuth2LoginManager::Observer, - public net::NetworkChangeNotifier::ConnectionTypeObserver, + public net::NetworkChangeNotifier::NetworkChangeObserver, public base::SupportsWeakPtr<UserSessionManager>, public UserSessionManagerDelegate, public user_manager::UserManager::UserSessionStateObserver { @@ -269,8 +269,8 @@ Profile* user_profile, OAuth2LoginManager::SessionRestoreState state) override; - // net::NetworkChangeNotifier::ConnectionTypeObserver overrides: - void OnConnectionTypeChanged( + // net::NetworkChangeNotifier::NetworkChangeObserver overrides: + void OnNetworkChanged( net::NetworkChangeNotifier::ConnectionType type) override; // UserSessionManagerDelegate overrides:
diff --git a/chrome/browser/chromeos/login/ui/proxy_settings_dialog.cc b/chrome/browser/chromeos/login/ui/proxy_settings_dialog.cc index 7bb0765ca..917c7ead 100644 --- a/chrome/browser/chromeos/login/ui/proxy_settings_dialog.cc +++ b/chrome/browser/chromeos/login/ui/proxy_settings_dialog.cc
@@ -23,27 +23,9 @@ namespace { -// Hints for size of proxy settings dialog. -const int kProxySettingsDialogReasonableWidth = 626; -const int kProxySettingsDialogReasonableHeight = 525; -const float kProxySettingsDialogReasonableWidthRatio = 0.4f; -const float kProxySettingsDialogReasonableHeightRatio = 0.4f; - -const char kProxySettingsURLParam[] = "?network=%s"; - -int CalculateSize(int screen_size, int min_comfortable, float desired_ratio) { - int desired_size = static_cast<int>(desired_ratio * screen_size); - desired_size = std::max(min_comfortable, desired_size); - return std::min(screen_size, desired_size); -} - -GURL GetURLForProxySettings(const std::string& guid) { - std::string url(chrome::kChromeUIProxySettingsURL); - url += base::StringPrintf( - kProxySettingsURLParam, - net::EscapeUrlEncodedData(guid, true).c_str()); - return GURL(url); -} +// Width matches the Settings UI, height is sized to match the content. +const int kProxySettingsDialogWidth = 640; +const int kProxySettingsDialogHeight = 480; } // namespace @@ -61,26 +43,14 @@ delegate, window, base::string16(), - GetURLForProxySettings(network.guid())) { + GURL(chrome::kChromeUIProxySettingsURL)), + guid_(network.guid()) { + name_ = network.Matches(NetworkTypePattern::Ethernet()) + ? l10n_util::GetStringUTF16(IDS_NETWORK_TYPE_ETHERNET) + : base::UTF8ToUTF16(network.name()); DCHECK_CURRENTLY_ON(content::BrowserThread::UI); ++instance_count_; - - gfx::Rect screen_bounds(chromeos::CalculateScreenBounds(gfx::Size())); - SetDialogSize(CalculateSize(screen_bounds.width(), - kProxySettingsDialogReasonableWidth, - kProxySettingsDialogReasonableWidthRatio), - CalculateSize(screen_bounds.height(), - kProxySettingsDialogReasonableHeight, - kProxySettingsDialogReasonableHeightRatio)); - - std::string network_name = network.name(); - if (network_name.empty() && network.Matches(NetworkTypePattern::Ethernet())) { - network_name = - l10n_util::GetStringUTF8(IDS_STATUSBAR_NETWORK_DEVICE_ETHERNET); - } - - SetDialogTitle(l10n_util::GetStringFUTF16(IDS_PROXY_PAGE_TITLE_FORMAT, - base::ASCIIToUTF16(network_name))); + SetDialogSize(kProxySettingsDialogWidth, kProxySettingsDialogHeight); } ProxySettingsDialog::~ProxySettingsDialog() { @@ -88,6 +58,14 @@ --instance_count_; } +base::string16 ProxySettingsDialog::GetDialogTitle() const { + return name_; +} + +std::string ProxySettingsDialog::GetDialogArgs() const { + return guid_; +} + void ProxySettingsDialog::OnDialogClosed(const std::string& json_retval) { LoginWebDialog::OnDialogClosed(json_retval); content::NotificationService::current()->Notify(
diff --git a/chrome/browser/chromeos/login/ui/proxy_settings_dialog.h b/chrome/browser/chromeos/login/ui/proxy_settings_dialog.h index 89721f1..63fdd50b 100644 --- a/chrome/browser/chromeos/login/ui/proxy_settings_dialog.h +++ b/chrome/browser/chromeos/login/ui/proxy_settings_dialog.h
@@ -6,6 +6,7 @@ #define CHROME_BROWSER_CHROMEOS_LOGIN_UI_PROXY_SETTINGS_DIALOG_H_ #include "base/macros.h" +#include "base/strings/string16.h" #include "chrome/browser/chromeos/login/ui/login_web_dialog.h" #include "ui/gfx/native_widget_types.h" @@ -29,6 +30,10 @@ gfx::NativeWindow window); ~ProxySettingsDialog() override; + // LoginWebDialog + base::string16 GetDialogTitle() const override; + std::string GetDialogArgs() const override; + protected: // ui::WebDialogDelegate implementation. void OnDialogClosed(const std::string& json_retval) override; @@ -38,6 +43,9 @@ // WebUI/login interfaces. static int instance_count_; + std::string guid_; + base::string16 name_; + DISALLOW_COPY_AND_ASSIGN(ProxySettingsDialog); };
diff --git a/chrome/browser/chromeos/login/users/chrome_user_manager_impl.cc b/chrome/browser/chromeos/login/users/chrome_user_manager_impl.cc index 577eda73..8f412c01 100644 --- a/chrome/browser/chromeos/login/users/chrome_user_manager_impl.cc +++ b/chrome/browser/chromeos/login/users/chrome_user_manager_impl.cc
@@ -507,7 +507,7 @@ user_manager::User* user = ProfileHelper::Get()->GetUserByProfile(profile); if (user != NULL) { - user->set_profile_is_created(); + user->SetProfileIsCreated(); if (user->HasGaiaAccount()) GetUserImageManager(user->GetAccountId())->UserProfileCreated();
diff --git a/chrome/browser/chromeos/login/users/fake_chrome_user_manager.cc b/chrome/browser/chromeos/login/users/fake_chrome_user_manager.cc index ff4d39b..a04b029 100644 --- a/chrome/browser/chromeos/login/users/fake_chrome_user_manager.cc +++ b/chrome/browser/chromeos/login/users/fake_chrome_user_manager.cc
@@ -143,7 +143,7 @@ // NOTE: This does not match production. See function comment. for (auto* user : users_) { if (user->GetAccountId() == account_id) { - user->set_profile_is_created(); + user->SetProfileIsCreated(); break; } }
diff --git a/chrome/browser/chromeos/night_light/night_light_client.h b/chrome/browser/chromeos/night_light/night_light_client.h index 0594840..89cbb148 100644 --- a/chrome/browser/chromeos/night_light/night_light_client.h +++ b/chrome/browser/chromeos/night_light/night_light_client.h
@@ -24,8 +24,7 @@ // Periodically requests the IP-based geolocation and provides it to the // NightLightController running in ash. -class NightLightClient - : public NON_EXPORTED_BASE(ash::mojom::NightLightClient) { +class NightLightClient : public ash::mojom::NightLightClient { public: NightLightClient(net::URLRequestContextGetter* url_context_getter); ~NightLightClient() override;
diff --git a/chrome/browser/chromeos/preferences.cc b/chrome/browser/chromeos/preferences.cc index 363f8ef..efdc665 100644 --- a/chrome/browser/chromeos/preferences.cc +++ b/chrome/browser/chromeos/preferences.cc
@@ -149,10 +149,6 @@ hardware_keyboard_id = "xkb:us::eng"; // only for testing. } - // Register ash prefs. - if (!ash_util::IsRunningInMash()) - ash::Shell::RegisterProfilePrefs(registry); - registry->RegisterBooleanPref(prefs::kPerformanceTracingEnabled, false); registry->RegisterBooleanPref(
diff --git a/chrome/browser/chromeos/prefs/ash_pref_connector_manifest.json b/chrome/browser/chromeos/prefs/ash_pref_connector_manifest.json new file mode 100644 index 0000000..e1c86f7 --- /dev/null +++ b/chrome/browser/chromeos/prefs/ash_pref_connector_manifest.json
@@ -0,0 +1,16 @@ +{ + "name": "ash_pref_connector", + "display_name": "Ash Pref Connector", + "interface_provider_specs": { + "service_manager:connector": { + "provides": { + "pref_connector": [ + "ash::mojom::PrefConnector" + ] + }, + "requires": { + "preferences": [ "pref_client" ] + } + } + } +}
diff --git a/chrome/browser/chromeos/prefs/pref_connector_service.cc b/chrome/browser/chromeos/prefs/pref_connector_service.cc new file mode 100644 index 0000000..61077d7c --- /dev/null +++ b/chrome/browser/chromeos/prefs/pref_connector_service.cc
@@ -0,0 +1,55 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/prefs/pref_connector_service.h" + +#include "base/bind.h" +#include "chrome/browser/chromeos/profiles/profile_helper.h" +#include "chrome/browser/profiles/profile_manager.h" +#include "components/user_manager/user_manager.h" +#include "content/public/browser/browser_context.h" +#include "mojo/public/cpp/bindings/interface_request.h" +#include "services/service_manager/public/cpp/connector.h" +#include "services/service_manager/public/cpp/service_context.h" + +AshPrefConnector::AshPrefConnector() : weak_factory_(this) { + registry_.AddInterface<ash::mojom::PrefConnector>(base::Bind( + &AshPrefConnector::BindConnectorRequest, base::Unretained(this))); +} + +AshPrefConnector::~AshPrefConnector() = default; + +void AshPrefConnector::GetPrefStoreConnectorForUser( + const AccountId& account_id, + prefs::mojom::PrefStoreConnectorRequest request) { + user_manager::User* user = + user_manager::UserManager::Get()->FindUserAndModify(account_id); + if (!user) + return; + + Profile* profile = chromeos::ProfileHelper::Get()->GetProfileByUser(user); + if (!profile) { + user->AddProfileCreatedObserver(base::BindOnce( + &AshPrefConnector::GetPrefStoreConnectorForUser, + weak_factory_.GetWeakPtr(), account_id, std::move(request))); + return; + } + + content::BrowserContext::GetConnectorFor(profile)->BindInterface( + prefs::mojom::kServiceName, std::move(request)); +} + +void AshPrefConnector::BindConnectorRequest( + ash::mojom::PrefConnectorRequest request) { + connector_bindings_.AddBinding(this, std::move(request)); +} + +void AshPrefConnector::OnStart() {} + +void AshPrefConnector::OnBindInterface( + const service_manager::BindSourceInfo& source_info, + const std::string& interface_name, + mojo::ScopedMessagePipeHandle interface_pipe) { + registry_.BindInterface(interface_name, std::move(interface_pipe)); +}
diff --git a/chrome/browser/chromeos/prefs/pref_connector_service.h b/chrome/browser/chromeos/prefs/pref_connector_service.h new file mode 100644 index 0000000..c9ec817 --- /dev/null +++ b/chrome/browser/chromeos/prefs/pref_connector_service.h
@@ -0,0 +1,54 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_CHROMEOS_PREFS_PREF_CONNECTOR_SERVICE_H_ +#define CHROME_BROWSER_CHROMEOS_PREFS_PREF_CONNECTOR_SERVICE_H_ + +#include <vector> + +#include "ash/public/interfaces/pref_connector.mojom.h" +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "components/prefs/pref_value_store.h" +#include "mojo/public/cpp/bindings/binding_set.h" +#include "services/preferences/public/interfaces/preferences.mojom.h" +#include "services/service_manager/public/cpp/binder_registry.h" +#include "services/service_manager/public/cpp/service.h" + +// A |ash::mojom::PrefConnector| implementation that provides ash with access to +// a |prefs::mojom::PrefStoreConnector| for a requested profile. +// +// TODO(http://crbug.com/705347): Once mash can connect to per-profile services +// via service manager, remove this class and the ash_pref_connector service. +class AshPrefConnector : public ash::mojom::PrefConnector, + public service_manager::Service { + public: + AshPrefConnector(); + ~AshPrefConnector() override; + + private: + // ash::mojom::PrefConnector: + void GetPrefStoreConnectorForUser( + const AccountId& account_id, + prefs::mojom::PrefStoreConnectorRequest request) override; + + // service_manager::Service: + void OnStart() override; + void OnBindInterface(const service_manager::BindSourceInfo& source_info, + const std::string& interface_name, + mojo::ScopedMessagePipeHandle interface_pipe) override; + + void BindConnectorRequest(ash::mojom::PrefConnectorRequest request); + + prefs::mojom::PrefStoreConnector& GetPrefStoreConnector(); + + service_manager::BinderRegistry registry_; + mojo::BindingSet<ash::mojom::PrefConnector> connector_bindings_; + + base::WeakPtrFactory<AshPrefConnector> weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(AshPrefConnector); +}; + +#endif // CHROME_BROWSER_CHROMEOS_PREFS_PREF_CONNECTOR_SERVICE_H_
diff --git a/chrome/browser/chromeos/profiles/avatar_menu_chromeos.cc b/chrome/browser/chromeos/profiles/avatar_menu_chromeos.cc index de3a55e..0617692 100644 --- a/chrome/browser/chromeos/profiles/avatar_menu_chromeos.cc +++ b/chrome/browser/chromeos/profiles/avatar_menu_chromeos.cc
@@ -14,10 +14,12 @@ #include "ui/gfx/image/image.h" // static -void AvatarMenu::GetImageForMenuButton(const base::FilePath& profile_path, - gfx::Image* image) { +AvatarMenu::ImageLoadStatus AvatarMenu::GetImageForMenuButton( + const base::FilePath& profile_path, + gfx::Image* image) { // ChromeOS avatar icon is circular. Profile* profile = g_browser_process->profile_manager()->GetProfileByPath(profile_path); *image = gfx::Image(GetAvatarImageForContext(profile)); + return AvatarMenu::ImageLoadStatus::LOADED; }
diff --git a/chrome/browser/chromeos/profiles/profile_helper.h b/chrome/browser/chromeos/profiles/profile_helper.h index 4c66225..c4f5fb6 100644 --- a/chrome/browser/chromeos/profiles/profile_helper.h +++ b/chrome/browser/chromeos/profiles/profile_helper.h
@@ -187,7 +187,6 @@ friend class PrinterDetectorAppSearchEnabledTest; friend class ProfileHelperTest; friend class ProfileListChromeOSTest; - friend class SystemTrayDelegateChromeOSTest; friend class ash::MultiUserWindowManagerChromeOSTest; friend class arc::ArcSessionManagerTest; friend class arc::ArcAuthServiceTest;
diff --git a/chrome/browser/component_updater/cros_component_installer.cc b/chrome/browser/component_updater/cros_component_installer.cc index 5dab04f..0c72420b 100644 --- a/chrome/browser/component_updater/cros_component_installer.cc +++ b/chrome/browser/component_updater/cros_component_installer.cc
@@ -6,6 +6,8 @@ #include <utility> +#include "base/files/file_util.h" +#include "base/path_service.h" #include "base/task_scheduler/post_task.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/component_updater/component_installer_errors.h" @@ -18,6 +20,8 @@ #include "chromeos/dbus/image_loader_client.h" #endif // defined(OS_CHROMEOS) +// ConfigMap list-initialization expression for all downloadable +// Chrome OS components. #define CONFIG_MAP_CONTENT \ {{"epson-inkjet-printer-escpr", \ {{"env_version", "2.1"}, \ @@ -37,6 +41,8 @@ namespace component_updater { #if defined(OS_CHROMEOS) +using ConfigMap = std::map<std::string, std::map<std::string, std::string>>; + void LogRegistrationResult(const std::string& name, chromeos::DBusMethodCallStatus call_status, bool result) { @@ -208,6 +214,7 @@ static void RegisterComponent(ComponentUpdateService* cus, const ComponentConfig& config, const base::Closure& register_callback) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); std::unique_ptr<ComponentInstallerTraits> traits( new CrOSComponentInstallerTraits(config)); // |cus| will take ownership of |installer| during @@ -251,6 +258,36 @@ } } +std::vector<ComponentConfig> CrOSComponent::GetInstalledComponents() { + std::vector<ComponentConfig> configs; + base::FilePath root; + if (!PathService::Get(DIR_COMPONENT_USER, &root)) + return configs; + + const ConfigMap components = CONFIG_MAP_CONTENT; + for (auto it : components) { + const std::string& name = it.first; + const std::map<std::string, std::string>& props = it.second; + base::FilePath component_path = root.Append(name); + if (base::PathExists(component_path)) { + ComponentConfig config(name, props.find("env_version")->second, + props.find("sha2hashstr")->second); + configs.push_back(config); + } + } + return configs; +} + +void CrOSComponent::RegisterComponents( + const std::vector<ComponentConfig>& configs) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + component_updater::ComponentUpdateService* updater = + g_browser_process->component_updater(); + for (const auto& config : configs) { + RegisterComponent(updater, config, base::Closure()); + } +} + #endif // defined(OS_CHROMEOS } // namespace component_updater
diff --git a/chrome/browser/component_updater/cros_component_installer.h b/chrome/browser/component_updater/cros_component_installer.h index 9a580201..42f71b3 100644 --- a/chrome/browser/component_updater/cros_component_installer.h +++ b/chrome/browser/component_updater/cros_component_installer.h
@@ -47,8 +47,6 @@ ~ComponentConfig(); }; -using ConfigMap = std::map<std::string, std::map<std::string, std::string>>; - class CrOSComponentInstallerTraits : public ComponentInstallerTraits { public: explicit CrOSComponentInstallerTraits(const ComponentConfig& config); @@ -93,14 +91,13 @@ const std::string& name, const base::Callback<void(const std::string&)>& load_callback); + // Returns all installed components. + static std::vector<ComponentConfig> GetInstalledComponents(); + + // Registers component |configs| to be updated. + static void RegisterComponents(const std::vector<ComponentConfig>& configs); + private: - FRIEND_TEST_ALL_PREFIXES(CrOSComponentInstallerTest, - RegisterComponentSuccessEscpr); - FRIEND_TEST_ALL_PREFIXES(CrOSComponentInstallerTest, - RegisterComponentSuccessStarCupsDriver); - FRIEND_TEST_ALL_PREFIXES(CrOSComponentInstallerTest, - RegisterComponentSuccessTermina); - FRIEND_TEST_ALL_PREFIXES(CrOSComponentInstallerTest, RegisterComponentFail); CrOSComponent() {} static void RegisterResult(ComponentUpdateService* cus, const std::string& id,
diff --git a/chrome/browser/component_updater/cros_component_installer_unittest.cc b/chrome/browser/component_updater/cros_component_installer_unittest.cc index 6766a22..6a6b910 100644 --- a/chrome/browser/component_updater/cros_component_installer_unittest.cc +++ b/chrome/browser/component_updater/cros_component_installer_unittest.cc
@@ -63,38 +63,6 @@ ASSERT_EQ(bppp.IsCompatibleCrOSComponent("a"), true); } -TEST_F(CrOSComponentInstallerTest, RegisterComponentSuccessEscpr) { - CrOSMockComponentUpdateService cus; - EXPECT_CALL(cus, RegisterComponent(testing::_)).Times(1); - component_updater::CrOSComponent::InstallComponent( - &cus, "epson-inkjet-printer-escpr", base::Bind(load_callback)); - RunUntilIdle(); -} - -TEST_F(CrOSComponentInstallerTest, RegisterComponentSuccessStarCupsDriver) { - CrOSMockComponentUpdateService cus; - EXPECT_CALL(cus, RegisterComponent(testing::_)).Times(1); - component_updater::CrOSComponent::InstallComponent(&cus, "star-cups-driver", - base::Bind(load_callback)); - RunUntilIdle(); -} - -TEST_F(CrOSComponentInstallerTest, RegisterComponentSuccessTermina) { - CrOSMockComponentUpdateService cus; - EXPECT_CALL(cus, RegisterComponent(testing::_)).Times(1); - component_updater::CrOSComponent::InstallComponent(&cus, "cros-termina", - base::Bind(load_callback)); - RunUntilIdle(); -} - -TEST_F(CrOSComponentInstallerTest, RegisterComponentFail) { - CrOSMockComponentUpdateService cus; - EXPECT_CALL(cus, RegisterComponent(testing::_)).Times(0); - component_updater::CrOSComponent::InstallComponent( - &cus, "a-component-not-exist", base::Bind(load_callback)); - RunUntilIdle(); -} - TEST_F(CrOSComponentInstallerTest, ComponentReadyCorrectManifest) { ComponentConfig config("a", "2.1", ""); MockCrOSComponentInstallerTraits traits(config);
diff --git a/chrome/browser/content_settings/host_content_settings_map_factory.cc b/chrome/browser/content_settings/host_content_settings_map_factory.cc index b9e9a44..7031e5a 100644 --- a/chrome/browser/content_settings/host_content_settings_map_factory.cc +++ b/chrome/browser/content_settings/host_content_settings_map_factory.cc
@@ -117,7 +117,7 @@ if (base::FeatureList::IsEnabled(features::kSiteNotificationChannels)) { auto channels_provider = base::MakeUnique<NotificationChannelsProviderAndroid>(); - settings_map->RegisterProvider( + settings_map->RegisterUserModifiableProvider( HostContentSettingsMap::NOTIFICATION_ANDROID_PROVIDER, std::move(channels_provider)); }
diff --git a/chrome/browser/content_settings/host_content_settings_map_unittest.cc b/chrome/browser/content_settings/host_content_settings_map_unittest.cc index 4e21146c..92ddec81 100644 --- a/chrome/browser/content_settings/host_content_settings_map_unittest.cc +++ b/chrome/browser/content_settings/host_content_settings_map_unittest.cc
@@ -13,6 +13,7 @@ #include "base/memory/ptr_util.h" #include "base/test/scoped_feature_list.h" #include "base/test/simple_test_clock.h" +#include "base/time/time.h" #include "chrome/browser/content_settings/content_settings_mock_observer.h" #include "chrome/browser/content_settings/cookie_settings_factory.h" #include "chrome/browser/content_settings/host_content_settings_map_factory.h" @@ -23,6 +24,7 @@ #include "components/content_settings/core/browser/content_settings_details.h" #include "components/content_settings/core/browser/cookie_settings.h" #include "components/content_settings/core/browser/host_content_settings_map.h" +#include "components/content_settings/core/browser/user_modifiable_provider.h" #include "components/content_settings/core/browser/website_settings_info.h" #include "components/content_settings/core/browser/website_settings_registry.h" #include "components/content_settings/core/common/pref_names.h" @@ -32,10 +34,13 @@ #include "content/public/test/test_browser_thread_bundle.h" #include "net/base/static_cookie_policy.h" #include "ppapi/features/features.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" using ::testing::_; +using ::testing::MockFunction; +using ::testing::Return; namespace { @@ -47,6 +52,34 @@ } // namespace +class MockUserModifiableProvider + : public content_settings::UserModifiableProvider { + public: + ~MockUserModifiableProvider() = default; + MOCK_CONST_METHOD3(GetRuleIterator, + std::unique_ptr<content_settings::RuleIterator>( + ContentSettingsType, + const content_settings::ResourceIdentifier&, + bool)); + + MOCK_METHOD5(SetWebsiteSetting, + bool(const ContentSettingsPattern&, + const ContentSettingsPattern&, + ContentSettingsType, + const content_settings::ResourceIdentifier&, + base::Value*)); + + MOCK_METHOD1(ClearAllContentSettingsRules, void(ContentSettingsType)); + + MOCK_METHOD0(ShutdownOnUIThread, void()); + + MOCK_METHOD4(GetWebsiteSettingLastModified, + base::Time(const ContentSettingsPattern&, + const ContentSettingsPattern&, + ContentSettingsType, + const content_settings::ResourceIdentifier&)); +}; + class HostContentSettingsMapTest : public testing::Test { public: HostContentSettingsMapTest() = default; @@ -1837,6 +1870,62 @@ EXPECT_EQ(t, clock->Now()); } +TEST_F(HostContentSettingsMapTest, LastModifiedMultipleModifiableProviders) { + base::test::ScopedFeatureList feature_list; + // Enable kTabsInCbd to activate last_modified timestamp recording. + feature_list.InitAndEnableFeature(features::kTabsInCbd); + + TestingProfile profile; + auto* map = HostContentSettingsMapFactory::GetForProfile(&profile); + base::Time t1 = base::Time::Now(); + + auto test_clock = base::MakeUnique<base::SimpleTestClock>(); + test_clock->SetNow(t1); + base::SimpleTestClock* clock = test_clock.get(); + clock->Advance(base::TimeDelta::FromSeconds(1)); + base::Time t2 = clock->Now(); + // This will set the Pref Provider clock to t2. + map->SetClockForTesting(std::move(test_clock)); + + // Modify setting at t2. + GURL url("https://www.google.com/"); + ContentSettingsPattern pattern = + ContentSettingsPattern::FromURLNoWildcard(url); + map->SetContentSettingDefaultScope(url, GURL(), + CONTENT_SETTINGS_TYPE_NOTIFICATIONS, + std::string(), CONTENT_SETTING_ALLOW); + + // Register a provider which reports a modification time of t1. + std::unique_ptr<MockUserModifiableProvider> mock_provider = + base::MakeUnique<MockUserModifiableProvider>(); + EXPECT_CALL(*mock_provider, GetWebsiteSettingLastModified( + _, _, CONTENT_SETTINGS_TYPE_NOTIFICATIONS, _)) + .WillOnce(Return(t1)); + MockUserModifiableProvider* weak_mock_provider = mock_provider.get(); + map->RegisterUserModifiableProvider( + HostContentSettingsMap::NOTIFICATION_ANDROID_PROVIDER, + std::move(mock_provider)); + + // Expect the more recent modification time to be reported. + EXPECT_EQ(t2, map->GetSettingLastModifiedDate( + pattern, ContentSettingsPattern::Wildcard(), + CONTENT_SETTINGS_TYPE_NOTIFICATIONS)); + + // Now have registered provider report a more recent modification time. + clock->Advance(base::TimeDelta::FromSeconds(1)); + base::Time t3 = clock->Now(); + EXPECT_CALL(*weak_mock_provider, + GetWebsiteSettingLastModified( + _, _, CONTENT_SETTINGS_TYPE_NOTIFICATIONS, _)) + .WillOnce(Return(t3)); + + // Expect the timestamp from the registered provider to be reported now. + EXPECT_EQ(t3, map->GetSettingLastModifiedDate( + pattern, ContentSettingsPattern::Wildcard(), + CONTENT_SETTINGS_TYPE_NOTIFICATIONS)); + weak_mock_provider->RemoveObserver(map); +} + TEST_F(HostContentSettingsMapTest, LastModifiedIsNotRecordedWhenDisabled) { base::test::ScopedFeatureList feature_list; feature_list.InitAndDisableFeature(features::kTabsInCbd);
diff --git a/chrome/browser/custom_handlers/protocol_handler_registry.cc b/chrome/browser/custom_handlers/protocol_handler_registry.cc index 820a794c..da7d1af 100644 --- a/chrome/browser/custom_handlers/protocol_handler_registry.cc +++ b/chrome/browser/custom_handlers/protocol_handler_registry.cc
@@ -879,8 +879,10 @@ void ProtocolHandlerRegistry::OnSetAsDefaultProtocolClientFinished( const std::string& protocol, shell_integration::DefaultWebClientState state) { + // Clear if the default protocol client isn't this installation. if (ShouldRemoveHandlersNotInOS() && - state == shell_integration::NOT_DEFAULT) { + (state == shell_integration::NOT_DEFAULT || + state == shell_integration::OTHER_MODE_IS_DEFAULT)) { ClearDefault(protocol); } }
diff --git a/chrome/browser/devtools/devtools_file_system_indexer.cc b/chrome/browser/devtools/devtools_file_system_indexer.cc index 87efb80..576a6206 100644 --- a/chrome/browser/devtools/devtools_file_system_indexer.cc +++ b/chrome/browser/devtools/devtools_file_system_indexer.cc
@@ -34,12 +34,13 @@ using base::TimeTicks; using content::BrowserThread; using std::map; -using std::set; using std::string; using std::vector; namespace { +using std::set; + base::SequencedTaskRunner* impl_task_runner() { constexpr base::TaskTraits kBlockingTraits = {base::MayBlock(), base::TaskPriority::BACKGROUND};
diff --git a/chrome/browser/extensions/BUILD.gn b/chrome/browser/extensions/BUILD.gn index 4557c3d..66de75d 100644 --- a/chrome/browser/extensions/BUILD.gn +++ b/chrome/browser/extensions/BUILD.gn
@@ -940,8 +940,6 @@ "api/feedback_private/log_source_access_manager.h", "api/feedback_private/log_source_resource.cc", "api/feedback_private/log_source_resource.h", - "api/feedback_private/single_log_source_factory.cc", - "api/feedback_private/single_log_source_factory.h", "api/file_system/consent_provider.cc", "api/file_system/consent_provider.h", "api/file_system/request_file_system_notification.cc",
diff --git a/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_api.cc b/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_api.cc index dacbb1a..5ab4238e 100644 --- a/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_api.cc +++ b/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_api.cc
@@ -52,10 +52,10 @@ #include "ui/gfx/range/range.h" #if defined(OS_CHROMEOS) -#include "ash/system/devicetype_utils.h" #include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_tpm_key_manager.h" #include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_tpm_key_manager_factory.h" #include "components/user_manager/user_manager.h" +#include "ui/chromeos/devicetype_utils.h" #endif using proximity_auth::ScreenlockState; @@ -139,7 +139,7 @@ std::unique_ptr<base::DictionaryValue> strings(new base::DictionaryValue); #if defined(OS_CHROMEOS) - const base::string16 device_type = ash::GetChromeOSDeviceName(); + const base::string16 device_type = ui::GetChromeOSDeviceName(); #else // TODO(isherman): Set an appropriate device name for non-ChromeOS devices. const base::string16 device_type = base::ASCIIToUTF16("Chromeschnozzle");
diff --git a/chrome/browser/extensions/api/feedback_private/chrome_feedback_private_delegate.cc b/chrome/browser/extensions/api/feedback_private/chrome_feedback_private_delegate.cc index 3e925eae..1be60f96 100644 --- a/chrome/browser/extensions/api/feedback_private/chrome_feedback_private_delegate.cc +++ b/chrome/browser/extensions/api/feedback_private/chrome_feedback_private_delegate.cc
@@ -19,7 +19,10 @@ #if defined(OS_CHROMEOS) #include "chrome/browser/chromeos/arc/arc_util.h" +#include "chrome/browser/chromeos/system_logs/single_debug_daemon_log_source.h" +#include "chrome/browser/chromeos/system_logs/single_log_file_log_source.h" #include "chrome/browser/profiles/profile.h" +#include "components/feedback/system_logs/system_logs_source.h" #endif // defined(OS_CHROMEOS) namespace extensions { @@ -94,4 +97,32 @@ return system_logs::BuildChromeSystemLogsFetcher(); } +#if defined(OS_CHROMEOS) +std::unique_ptr<system_logs::SystemLogsSource> +ChromeFeedbackPrivateDelegate::CreateSingleLogSource( + api::feedback_private::LogSource source_type) const { + switch (source_type) { + case api::feedback_private::LOG_SOURCE_MESSAGES: + return base::MakeUnique<system_logs::SingleLogFileLogSource>( + system_logs::SingleLogFileLogSource::SupportedSource::kMessages); + case api::feedback_private::LOG_SOURCE_UILATEST: + return base::MakeUnique<system_logs::SingleLogFileLogSource>( + system_logs::SingleLogFileLogSource::SupportedSource::kUiLatest); + case api::feedback_private::LOG_SOURCE_DRMMODETEST: + return base::MakeUnique<system_logs::SingleDebugDaemonLogSource>( + system_logs::SingleDebugDaemonLogSource::SupportedSource::kModetest); + case api::feedback_private::LOG_SOURCE_LSUSB: + return base::MakeUnique<system_logs::SingleDebugDaemonLogSource>( + system_logs::SingleDebugDaemonLogSource::SupportedSource::kLsusb); + case api::feedback_private::LOG_SOURCE_ATRUSLOG: + return base::MakeUnique<system_logs::SingleLogFileLogSource>( + system_logs::SingleLogFileLogSource::SupportedSource::kAtrusLog); + case api::feedback_private::LOG_SOURCE_NONE: + default: + NOTREACHED() << "Unknown log source type."; + return nullptr; + } +} +#endif // defined(OS_CHROMEOS) + } // namespace extensions
diff --git a/chrome/browser/extensions/api/feedback_private/chrome_feedback_private_delegate.h b/chrome/browser/extensions/api/feedback_private/chrome_feedback_private_delegate.h index 27a881e..16570148 100644 --- a/chrome/browser/extensions/api/feedback_private/chrome_feedback_private_delegate.h +++ b/chrome/browser/extensions/api/feedback_private/chrome_feedback_private_delegate.h
@@ -10,6 +10,11 @@ #include <memory> #include "base/macros.h" +#include "chrome/common/extensions/api/feedback_private.h" + +namespace system_logs { +class SystemLogsSource; +} // namespace system_logs namespace extensions { @@ -25,6 +30,13 @@ system_logs::SystemLogsFetcher* CreateSystemLogsFetcher( content::BrowserContext* context) const override; +#if defined(OS_CHROMEOS) + // TODO(michaelpg): Move declaration to FeedbackPrivateDelegate once the + // feedbackPrivate API header lives in //extensions. + virtual std::unique_ptr<system_logs::SystemLogsSource> CreateSingleLogSource( + api::feedback_private::LogSource source_type) const; +#endif // defined(OS_CHROMEOS) + private: DISALLOW_COPY_AND_ASSIGN(ChromeFeedbackPrivateDelegate); };
diff --git a/chrome/browser/extensions/api/feedback_private/feedback_private_api_chromeos_unittest.cc b/chrome/browser/extensions/api/feedback_private/feedback_private_api_chromeos_unittest.cc index ed67e16..971c6d9 100644 --- a/chrome/browser/extensions/api/feedback_private/feedback_private_api_chromeos_unittest.cc +++ b/chrome/browser/extensions/api/feedback_private/feedback_private_api_chromeos_unittest.cc
@@ -7,28 +7,19 @@ #include "base/json/json_writer.h" #include "base/macros.h" #include "base/memory/ptr_util.h" +#include "base/memory/ref_counted.h" #include "base/test/simple_test_tick_clock.h" #include "base/values.h" -#include "chrome/browser/extensions/api/feedback_private/log_source_resource.h" -#include "chrome/browser/extensions/api/feedback_private/single_log_source_factory.h" -#include "chrome/browser/extensions/extension_api_unittest.h" -#include "extensions/browser/api_test_utils.h" +#include "chrome/browser/extensions/api/feedback_private/feedback_private_api_unittest_base_chromeos.h" +#include "chrome/browser/extensions/api/feedback_private/log_source_access_manager.h" namespace extensions { namespace { -using api::feedback_private::LogSource; using api::feedback_private::ReadLogSourceResult; using api::feedback_private::ReadLogSourceParams; using base::TimeDelta; -using system_logs::SystemLogsResponse; -using system_logs::SystemLogsSource; - -std::unique_ptr<KeyedService> ApiResourceManagerTestFactory( - content::BrowserContext* context) { - return base::MakeUnique<ApiResourceManager<LogSourceResource>>(context); -} // Converts |params| to a string containing a JSON dictionary within an argument // list. @@ -41,87 +32,21 @@ return params_json_string; } -// A dummy SystemLogsSource that does not require real system logs to be -// available during testing. -class TestSingleLogSource : public SystemLogsSource { - public: - explicit TestSingleLogSource(LogSource type) - : SystemLogsSource(ToString(type)), call_count_(0) {} - - ~TestSingleLogSource() override = default; - - // Fetch() will return a single different string each time, in the following - // sequence: "a", " bb", " ccc", until 25 spaces followed by 26 z's. Will - // never return an empty result. - void Fetch(const system_logs::SysLogsSourceCallback& callback) override { - int count_modulus = call_count_ % kNumCharsToIterate; - std::string result = - std::string(count_modulus, ' ') + - std::string(count_modulus + 1, kInitialChar + count_modulus); - ASSERT_GT(result.size(), 0U); - ++call_count_; - - SystemLogsResponse* result_map = new SystemLogsResponse; - result_map->emplace("", result); - - // Do not directly pass the result to the callback, because that's not how - // log sources actually work. Instead, simulate the asynchronous operation - // of a SystemLogsSource by invoking the callback separately. - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::BindOnce(callback, base::Owned(result_map))); - } - - // Instantiates a new instance of this class. Does not retain ownership. Used - // to create a Callback that can be used to override the default behavior of - // SingleLogSourceFactory. - static std::unique_ptr<SystemLogsSource> Create(LogSource type) { - return base::MakeUnique<TestSingleLogSource>(type); - } - - private: - // Iterate over the whole lowercase alphabet, starting from 'a'. - const int kNumCharsToIterate = 26; - const char kInitialChar = 'a'; - - // Keep track of how many times Fetch() has been called, in order to determine - // its behavior each time. - int call_count_; - - DISALLOW_COPY_AND_ASSIGN(TestSingleLogSource); -}; - } // namespace -class FeedbackPrivateApiUnittest : public ExtensionApiUnittest { +class FeedbackPrivateApiUnittest : public FeedbackPrivateApiUnittestBase { public: - FeedbackPrivateApiUnittest() - : create_callback_(base::Bind(&TestSingleLogSource::Create)) {} - ~FeedbackPrivateApiUnittest() override {} + FeedbackPrivateApiUnittest() = default; + ~FeedbackPrivateApiUnittest() override = default; - void SetUp() override { - ExtensionApiUnittest::SetUp(); - - // The ApiResourceManager used for LogSourceResource is destroyed every time - // a unit test finishes, during TearDown(). There is no way to re-create it - // normally. The below code forces it to be re-created during SetUp(), so - // that there is always a valid ApiResourceManager<LogSourceResource> when - // subsequent unit tests are running. - ApiResourceManager<LogSourceResource>::GetFactoryInstance() - ->SetTestingFactoryAndUse(profile(), ApiResourceManagerTestFactory); - - SingleLogSourceFactory::SetForTesting(&create_callback_); - } - + // FeedbackPrivateApiUnittestBase: void TearDown() override { - SingleLogSourceFactory::SetForTesting(nullptr); - LogSourceAccessManager::SetRateLimitingTimeoutForTesting(nullptr); - FeedbackPrivateAPI::GetFactoryInstance() ->Get(profile()) ->GetLogSourceAccessManager() ->SetTickClockForTesting(nullptr); - ExtensionApiUnittest::TearDown(); + FeedbackPrivateApiUnittestBase::TearDown(); } // Runs the feedbackPrivate.readLogSource() function. See API function @@ -140,7 +65,7 @@ int* result_reader_id, std::string* result_string) { scoped_refptr<FeedbackPrivateReadLogSourceFunction> function = - new FeedbackPrivateReadLogSourceFunction; + base::MakeRefCounted<FeedbackPrivateReadLogSourceFunction>(); std::unique_ptr<base::Value> result_value = RunFunctionAndReturnValue(function.get(), ParamsToJSON(params)); @@ -171,16 +96,12 @@ std::string RunReadLogSourceFunctionWithError( const ReadLogSourceParams& params) { scoped_refptr<FeedbackPrivateReadLogSourceFunction> function = - new FeedbackPrivateReadLogSourceFunction; + base::MakeRefCounted<FeedbackPrivateReadLogSourceFunction>(); return RunFunctionAndReturnError(function.get(), ParamsToJSON(params)); } private: - // Passed to SingleLogSourceFactory so that the API can create an instance of - // TestSingleLogSource for testing. - SingleLogSourceFactory::CreateCallback create_callback_; - DISALLOW_COPY_AND_ASSIGN(FeedbackPrivateApiUnittest); }; @@ -191,7 +112,7 @@ ReadLogSourceParams params; params.source = api::feedback_private::LOG_SOURCE_MESSAGES; params.incremental = true; - params.reader_id.reset(new int(9999)); + params.reader_id = base::MakeUnique<int>(9999); EXPECT_NE("", RunReadLogSourceFunctionWithError(params)); } @@ -241,7 +162,7 @@ RunReadLogSourceFunction(params, &result_reader_id, &result_string)); EXPECT_GT(result_reader_id, 0); EXPECT_EQ("a", result_string); - params.reader_id.reset(new int(result_reader_id)); + params.reader_id = base::MakeUnique<int>(result_reader_id); EXPECT_TRUE( RunReadLogSourceFunction(params, &result_reader_id, &result_string)); @@ -354,7 +275,7 @@ EXPECT_TRUE( RunReadLogSourceFunction(params, &result_reader_id, &result_string)); EXPECT_EQ(1, result_reader_id); - params.reader_id.reset(new int(result_reader_id)); + params.reader_id = base::MakeUnique<int>(result_reader_id); // Immediately perform another read. This is not allowed. (empty result) EXPECT_FALSE(
diff --git a/chrome/browser/extensions/api/feedback_private/feedback_private_api_unittest_base_chromeos.cc b/chrome/browser/extensions/api/feedback_private/feedback_private_api_unittest_base_chromeos.cc new file mode 100644 index 0000000..ea8216c --- /dev/null +++ b/chrome/browser/extensions/api/feedback_private/feedback_private_api_unittest_base_chromeos.cc
@@ -0,0 +1,136 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/extensions/api/feedback_private/feedback_private_api_unittest_base_chromeos.h" + +#include "base/bind.h" +#include "base/bind_helpers.h" +#include "base/location.h" +#include "base/memory/ptr_util.h" +#include "base/threading/thread_task_runner_handle.h" +#include "chrome/browser/extensions/api/chrome_extensions_api_client.h" +#include "chrome/browser/extensions/api/feedback_private/chrome_feedback_private_delegate.h" +#include "chrome/browser/extensions/api/feedback_private/log_source_access_manager.h" +#include "chrome/browser/extensions/api/feedback_private/log_source_resource.h" +#include "chrome/common/extensions/api/feedback_private.h" +#include "components/feedback/system_logs/system_logs_source.h" +#include "components/keyed_service/core/keyed_service.h" +#include "extensions/browser/api/api_resource_manager.h" + +namespace extensions { + +namespace { + +using api::feedback_private::LogSource; +using system_logs::SystemLogsResponse; +using system_logs::SystemLogsSource; + +std::unique_ptr<KeyedService> ApiResourceManagerTestFactory( + content::BrowserContext* context) { + return base::MakeUnique<ApiResourceManager<LogSourceResource>>(context); +} + +// A dummy SystemLogsSource that does not require real system logs to be +// available during testing. +class TestSingleLogSource : public SystemLogsSource { + public: + explicit TestSingleLogSource(LogSource type) + : SystemLogsSource(ToString(type)) {} + + ~TestSingleLogSource() override = default; + + // Fetch() will return a single different string each time, in the following + // sequence: "a", " bb", " ccc", until 25 spaces followed by 26 z's. Will + // never return an empty result. + void Fetch(const system_logs::SysLogsSourceCallback& callback) override { + int count_modulus = call_count_ % kNumCharsToIterate; + std::string result = + std::string(count_modulus, ' ') + + std::string(count_modulus + 1, kInitialChar + count_modulus); + DCHECK_GT(result.size(), 0U); + ++call_count_; + + SystemLogsResponse* result_map = new SystemLogsResponse; + result_map->emplace("", result); + + // Do not directly pass the result to the callback, because that's not how + // log sources actually work. Instead, simulate the asynchronous operation + // of a SystemLogsSource by invoking the callback separately. + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(callback, base::Owned(result_map))); + } + + private: + // Iterate over the whole lowercase alphabet, starting from 'a'. + const int kNumCharsToIterate = 26; + const char kInitialChar = 'a'; + + // Keep track of how many times Fetch() has been called, in order to determine + // its behavior each time. + int call_count_ = 0; + + DISALLOW_COPY_AND_ASSIGN(TestSingleLogSource); +}; + +class TestFeedbackPrivateDelegate : public ChromeFeedbackPrivateDelegate { + public: + TestFeedbackPrivateDelegate() = default; + ~TestFeedbackPrivateDelegate() override = default; + + std::unique_ptr<system_logs::SystemLogsSource> CreateSingleLogSource( + api::feedback_private::LogSource source_type) const override { + return base::MakeUnique<TestSingleLogSource>(source_type); + } + + private: + DISALLOW_COPY_AND_ASSIGN(TestFeedbackPrivateDelegate); +}; + +class TestExtensionsAPIClient : public ChromeExtensionsAPIClient { + public: + TestExtensionsAPIClient() = default; + ~TestExtensionsAPIClient() override = default; + + // ChromeExtensionsApiClient implementation: + FeedbackPrivateDelegate* GetFeedbackPrivateDelegate() override { + if (!feedback_private_delegate_) { + feedback_private_delegate_ = + base::MakeUnique<TestFeedbackPrivateDelegate>(); + } + return feedback_private_delegate_.get(); + } + + private: + std::unique_ptr<FeedbackPrivateDelegate> feedback_private_delegate_; + + DISALLOW_COPY_AND_ASSIGN(TestExtensionsAPIClient); +}; + +} // namespace + +FeedbackPrivateApiUnittestBase::FeedbackPrivateApiUnittestBase() = default; +FeedbackPrivateApiUnittestBase::~FeedbackPrivateApiUnittestBase() = default; + +void FeedbackPrivateApiUnittestBase::SetUp() { + extensions_api_client_ = base::MakeUnique<TestExtensionsAPIClient>(); + + ExtensionApiUnittest::SetUp(); + + // The ApiResourceManager used for LogSourceResource is destroyed every time + // a unit test finishes, during TearDown(). There is no way to re-create it + // normally. The below code forces it to be re-created during SetUp(), so + // that there is always a valid ApiResourceManager<LogSourceResource> when + // subsequent unit tests are running. + ApiResourceManager<LogSourceResource>::GetFactoryInstance() + ->SetTestingFactoryAndUse(profile(), ApiResourceManagerTestFactory); +} + +void FeedbackPrivateApiUnittestBase::TearDown() { + // Clear the rate limit override that tests may have set. + LogSourceAccessManager::SetRateLimitingTimeoutForTesting(nullptr); + + ExtensionApiUnittest::TearDown(); +} + +} // namespace extensions
diff --git a/chrome/browser/extensions/api/feedback_private/feedback_private_api_unittest_base_chromeos.h b/chrome/browser/extensions/api/feedback_private/feedback_private_api_unittest_base_chromeos.h new file mode 100644 index 0000000..5da5bfc --- /dev/null +++ b/chrome/browser/extensions/api/feedback_private/feedback_private_api_unittest_base_chromeos.h
@@ -0,0 +1,35 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_EXTENSIONS_API_FEEDBACK_PRIVATE_FEEDBACK_PRIVATE_API_UNITTEST_BASE_CHROMEOS_H_ +#define CHROME_BROWSER_EXTENSIONS_API_FEEDBACK_PRIVATE_FEEDBACK_PRIVATE_API_UNITTEST_BASE_CHROMEOS_H_ + +#include <memory> + +#include "base/macros.h" +#include "chrome/browser/extensions/extension_api_unittest.h" + +namespace extensions { + +class ExtensionsAPIClient; + +// Creates a FeedbackPrivateDelegate that can generate a SystemLogsSource for +// testing. +class FeedbackPrivateApiUnittestBase : public ExtensionApiUnittest { + public: + FeedbackPrivateApiUnittestBase(); + ~FeedbackPrivateApiUnittestBase() override; + + void SetUp() override; + void TearDown() override; + + private: + std::unique_ptr<ExtensionsAPIClient> extensions_api_client_; + + DISALLOW_COPY_AND_ASSIGN(FeedbackPrivateApiUnittestBase); +}; + +} // namespace extensions + +#endif // CHROME_BROWSER_EXTENSIONS_API_FEEDBACK_PRIVATE_FEEDBACK_PRIVATE_API_UNITTEST_BASE_CHROMEOS_H_
diff --git a/chrome/browser/extensions/api/feedback_private/log_source_access_manager.cc b/chrome/browser/extensions/api/feedback_private/log_source_access_manager.cc index a71167e3..41a3bc8 100644 --- a/chrome/browser/extensions/api/feedback_private/log_source_access_manager.cc +++ b/chrome/browser/extensions/api/feedback_private/log_source_access_manager.cc
@@ -11,9 +11,11 @@ #include "base/memory/ptr_util.h" #include "base/strings/string_split.h" #include "base/time/default_tick_clock.h" +#include "chrome/browser/extensions/api/chrome_extensions_api_client.h" +#include "chrome/browser/extensions/api/feedback_private/chrome_feedback_private_delegate.h" #include "chrome/browser/extensions/api/feedback_private/log_source_resource.h" -#include "chrome/browser/extensions/api/feedback_private/single_log_source_factory.h" #include "extensions/browser/api/api_resource_manager.h" +#include "extensions/browser/api/extensions_api_client.h" namespace extensions { @@ -152,10 +154,15 @@ if (GetNumActiveResourcesForSource(key.source) >= kMaxReadersPerSource) return 0; + ChromeFeedbackPrivateDelegate* feedback_private_delegate = + static_cast<ChromeFeedbackPrivateDelegate*>( + ExtensionsAPIClient::Get()->GetFeedbackPrivateDelegate()); + DCHECK(feedback_private_delegate); + std::unique_ptr<LogSourceResource> new_resource = base::MakeUnique<LogSourceResource>( key.extension_id, - SingleLogSourceFactory::CreateSingleLogSource(key.source), + feedback_private_delegate->CreateSingleLogSource(key.source), base::Bind(&LogSourceAccessManager::RemoveSource, weak_factory_.GetWeakPtr(), key));
diff --git a/chrome/browser/extensions/api/feedback_private/log_source_access_manager_chromeos_unittest.cc b/chrome/browser/extensions/api/feedback_private/log_source_access_manager_chromeos_unittest.cc index 9e7f466..6a850aeab 100644 --- a/chrome/browser/extensions/api/feedback_private/log_source_access_manager_chromeos_unittest.cc +++ b/chrome/browser/extensions/api/feedback_private/log_source_access_manager_chromeos_unittest.cc
@@ -4,14 +4,10 @@ #include "chrome/browser/extensions/api/feedback_private/log_source_access_manager.h" -#include "base/macros.h" -#include "base/memory/ptr_util.h" +#include "base/bind.h" #include "base/run_loop.h" #include "base/strings/stringprintf.h" -#include "chrome/browser/extensions/api/feedback_private/log_source_resource.h" -#include "chrome/browser/extensions/api/feedback_private/single_log_source_factory.h" -#include "chrome/browser/extensions/extension_api_unittest.h" -#include "extensions/browser/api/api_resource_manager.h" +#include "chrome/browser/extensions/api/feedback_private/feedback_private_api_unittest_base_chromeos.h" namespace extensions { @@ -19,95 +15,22 @@ using api::feedback_private::LOG_SOURCE_MESSAGES; using api::feedback_private::LOG_SOURCE_UILATEST; -using api::feedback_private::LogSource; using api::feedback_private::ReadLogSourceResult; using api::feedback_private::ReadLogSourceParams; -using system_logs::SystemLogsSource; - -std::unique_ptr<KeyedService> ApiResourceManagerTestFactory( - content::BrowserContext* context) { - return base::MakeUnique<ApiResourceManager<LogSourceResource>>(context); -} - -// Dummy function used as a callback for FetchFromSource(). -void OnFetchedFromSource(const ReadLogSourceResult& result) {} - -// A dummy SystemLogsSource that does not require real system logs to be -// available during testing. Always returns an empty result. -class EmptySingleLogSource : public system_logs::SystemLogsSource { - public: - explicit EmptySingleLogSource(LogSource type) - : SystemLogsSource(api::feedback_private::ToString(type)) {} - - ~EmptySingleLogSource() override = default; - - void Fetch(const system_logs::SysLogsSourceCallback& callback) override { - system_logs::SystemLogsResponse* result_map = - new system_logs::SystemLogsResponse; - result_map->emplace("", ""); - - // Do not directly pass the result to the callback, because that's not how - // log sources actually work. Instead, simulate the asynchronous operation - // of a SystemLogsSource by invoking the callback separately. - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::BindOnce(callback, base::Owned(result_map))); - } - - // Instantiates a new instance of this class. Does not retain ownership. Used - // to create a Callback that can be used to override the default behavior of - // SingleLogSourceFactory. - static std::unique_ptr<SystemLogsSource> Create(LogSource type) { - return base::MakeUnique<EmptySingleLogSource>(type); - } - - private: - DISALLOW_COPY_AND_ASSIGN(EmptySingleLogSource); -}; } // namespace -class LogSourceAccessManagerTest : public ExtensionApiUnittest { - public: - LogSourceAccessManagerTest() - : create_callback_(base::Bind(&EmptySingleLogSource::Create)) {} - ~LogSourceAccessManagerTest() override {} - - void SetUp() override { - ExtensionApiUnittest::SetUp(); - - // The ApiResourceManager used for LogSourceResource is destroyed every time - // a unit test finishes, during TearDown(). There is no way to re-create it - // normally. The below code forces it to be re-created during SetUp(), so - // that there is always a valid ApiResourceManager<LogSourceResource> when - // subsequent unit tests are running. - ApiResourceManager<LogSourceResource>::GetFactoryInstance() - ->SetTestingFactoryAndUse(profile(), ApiResourceManagerTestFactory); - - SingleLogSourceFactory::SetForTesting(&create_callback_); - } - - void TearDown() override { - SingleLogSourceFactory::SetForTesting(nullptr); - LogSourceAccessManager::SetRateLimitingTimeoutForTesting(nullptr); - - ExtensionApiUnittest::TearDown(); - } - - private: - // Passed to SingleLogSourceFactory so that the API can create an instance of - // TestSingleLogSource for testing. - SingleLogSourceFactory::CreateCallback create_callback_; - - DISALLOW_COPY_AND_ASSIGN(LogSourceAccessManagerTest); -}; +using LogSourceAccessManagerTest = FeedbackPrivateApiUnittestBase; TEST_F(LogSourceAccessManagerTest, MaxNumberOfOpenLogSources) { const base::TimeDelta timeout(base::TimeDelta::FromMilliseconds(0)); LogSourceAccessManager::SetRateLimitingTimeoutForTesting(&timeout); LogSourceAccessManager manager(profile()); + + // Create a dummy callback to pass to FetchFromSource(). LogSourceAccessManager::ReadLogSourceCallback callback = - base::Bind(&OnFetchedFromSource); + base::Bind([](const ReadLogSourceResult&) {}); int count = 0;
diff --git a/chrome/browser/extensions/api/feedback_private/single_log_source_factory.cc b/chrome/browser/extensions/api/feedback_private/single_log_source_factory.cc deleted file mode 100644 index f9177c8..0000000 --- a/chrome/browser/extensions/api/feedback_private/single_log_source_factory.cc +++ /dev/null
@@ -1,61 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/extensions/api/feedback_private/single_log_source_factory.h" - -#include "base/memory/ptr_util.h" -#include "chrome/browser/chromeos/system_logs/single_debug_daemon_log_source.h" -#include "chrome/browser/chromeos/system_logs/single_log_file_log_source.h" - -namespace extensions { - -namespace { - -namespace feedback_private = api::feedback_private; - -using system_logs::SingleDebugDaemonLogSource; -using system_logs::SingleLogFileLogSource; -using system_logs::SystemLogsSource; - -SingleLogSourceFactory::CreateCallback* g_callback = nullptr; - -} // namespace - -// static -std::unique_ptr<SystemLogsSource> SingleLogSourceFactory::CreateSingleLogSource( - feedback_private::LogSource source_type) { - if (g_callback) - return g_callback->Run(source_type); - - switch (source_type) { - case feedback_private::LOG_SOURCE_MESSAGES: - return base::MakeUnique<SingleLogFileLogSource>( - SingleLogFileLogSource::SupportedSource::kMessages); - case feedback_private::LOG_SOURCE_UILATEST: - return base::MakeUnique<SingleLogFileLogSource>( - SingleLogFileLogSource::SupportedSource::kUiLatest); - case feedback_private::LOG_SOURCE_DRMMODETEST: - return base::MakeUnique<SingleDebugDaemonLogSource>( - SingleDebugDaemonLogSource::SupportedSource::kModetest); - case feedback_private::LOG_SOURCE_LSUSB: - return base::MakeUnique<SingleDebugDaemonLogSource>( - SingleDebugDaemonLogSource::SupportedSource::kLsusb); - case feedback_private::LOG_SOURCE_ATRUSLOG: - return base::MakeUnique<SingleLogFileLogSource>( - SingleLogFileLogSource::SupportedSource::kAtrusLog); - case feedback_private::LOG_SOURCE_NONE: - default: - NOTREACHED() << "Unknown log source type."; - break; - } - return std::unique_ptr<SystemLogsSource>(nullptr); -} - -// static -void SingleLogSourceFactory::SetForTesting( - SingleLogSourceFactory::CreateCallback* callback) { - g_callback = callback; -} - -} // namespace extensions
diff --git a/chrome/browser/extensions/api/feedback_private/single_log_source_factory.h b/chrome/browser/extensions/api/feedback_private/single_log_source_factory.h deleted file mode 100644 index 5743d1a..0000000 --- a/chrome/browser/extensions/api/feedback_private/single_log_source_factory.h +++ /dev/null
@@ -1,38 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_EXTENSIONS_API_FEEDBACK_PRIVATE_SINGLE_LOG_SOURCE_FACTORY_H_ -#define CHROME_BROWSER_EXTENSIONS_API_FEEDBACK_PRIVATE_SINGLE_LOG_SOURCE_FACTORY_H_ - -#include <memory> - -#include "base/callback.h" -#include "chrome/common/extensions/api/feedback_private.h" -#include "components/feedback/system_logs/system_logs_fetcher.h" - -namespace extensions { - -// Provides a way to override the creation of a new Single*LogSource during -// testing. -class SingleLogSourceFactory { - public: - using CreateCallback = - base::Callback<std::unique_ptr<system_logs::SystemLogsSource>( - api::feedback_private::LogSource)>; - - // Returns a Single*LogSource with source type corresponding to |type|. The - // caller must takeownership of the returned object. - static std::unique_ptr<system_logs::SystemLogsSource> CreateSingleLogSource( - api::feedback_private::LogSource type); - - // Pass in a callback that gets executed instead of the default behavior of - // CreateSingleLogSource. Does not take ownership of |callback|. When done - // testing, call this function again with |callback|=nullptr to restore the - // default behavior. - static void SetForTesting(CreateCallback* callback); -}; - -} // namespace extensions - -#endif // CHROME_BROWSER_EXTENSIONS_API_FEEDBACK_PRIVATE_SINGLE_LOG_SOURCE_FACTORY_H_
diff --git a/chrome/browser/extensions/api/hotword_private/hotword_private_api.cc b/chrome/browser/extensions/api/hotword_private/hotword_private_api.cc index 5011026..05389bdd 100644 --- a/chrome/browser/extensions/api/hotword_private/hotword_private_api.cc +++ b/chrome/browser/extensions/api/hotword_private/hotword_private_api.cc
@@ -30,7 +30,7 @@ #include "ui/base/webui/web_ui_util.h" #if defined(OS_CHROMEOS) -#include "ash/system/devicetype_utils.h" +#include "ui/chromeos/devicetype_utils.h" #endif namespace extensions { @@ -348,7 +348,7 @@ ExtensionFunction::ResponseAction HotwordPrivateGetLocalizedStringsFunction::Run() { #if defined(OS_CHROMEOS) - base::string16 device_type = ash::GetChromeOSDeviceName(); + base::string16 device_type = ui::GetChromeOSDeviceName(); #else base::string16 product_name = l10n_util::GetStringUTF16(IDS_SHORT_PRODUCT_NAME);
diff --git a/chrome/browser/extensions/api/notifications/notifications_apitest.cc b/chrome/browser/extensions/api/notifications/notifications_apitest.cc index 90717ea..a1ab2f0 100644 --- a/chrome/browser/extensions/api/notifications/notifications_apitest.cc +++ b/chrome/browser/extensions/api/notifications/notifications_apitest.cc
@@ -18,9 +18,10 @@ #include "chrome/browser/extensions/extension_function_test_utils.h" #include "chrome/browser/notifications/notification.h" #include "chrome/browser/notifications/notification_common.h" -#include "chrome/browser/notifications/notification_display_service_tester.h" +#include "chrome/browser/notifications/notification_display_service_factory.h" #include "chrome/browser/notifications/notifier_state_tracker.h" #include "chrome/browser/notifications/notifier_state_tracker_factory.h" +#include "chrome/browser/notifications/stub_notification_display_service.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/ui/extensions/app_launch_params.h" #include "chrome/browser/ui/extensions/application_launch.h" @@ -165,6 +166,11 @@ return ExtensionNotificationDisplayHelperFactory::GetForProfile(profile()); } + StubNotificationDisplayService* GetDisplayService() { + return reinterpret_cast<StubNotificationDisplayService*>( + NotificationDisplayServiceFactory::GetForProfile(profile())); + } + NotifierStateTracker* GetNotifierStateTracker() { return NotifierStateTrackerFactory::GetForProfile(profile()); } @@ -174,13 +180,8 @@ ExtensionApiTest::SetUpOnMainThread(); DCHECK(profile()); - display_service_tester_ = - base::MakeUnique<NotificationDisplayServiceTester>(profile()); - } - - void TearDown() override { - display_service_tester_.reset(); - ExtensionApiTest::TearDown(); + NotificationDisplayServiceFactory::GetInstance()->SetTestingFactory( + profile(), &StubNotificationDisplayService::FactoryForTests); } // Returns the notification that's being displayed for |extension|, or nullptr @@ -219,8 +220,6 @@ extensions::kAllowFullscreenAppNotificationsFeature); } - std::unique_ptr<NotificationDisplayServiceTester> display_service_tester_; - private: base::test::ScopedFeatureList feature_list_; }; @@ -256,7 +255,7 @@ ResultCatcher catcher; const std::string notification_id = GetNotificationIdFromDelegateId(extension->id() + "-FOO"); - display_service_tester_->RemoveNotification( + GetDisplayService()->RemoveNotification( NotificationCommon::EXTENSION, notification_id, false /* by_user */); EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); } @@ -265,21 +264,21 @@ ResultCatcher catcher; const std::string notification_id = GetNotificationIdFromDelegateId(extension->id() + "-BAR"); - display_service_tester_->RemoveNotification( + GetDisplayService()->RemoveNotification( NotificationCommon::EXTENSION, notification_id, true /* by_user */); EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); } { ResultCatcher catcher; - display_service_tester_->RemoveAllNotifications( - NotificationCommon::EXTENSION, false /* by_user */); + GetDisplayService()->RemoveAllNotifications(NotificationCommon::EXTENSION, + false /* by_user */); EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); } { ResultCatcher catcher; - display_service_tester_->RemoveAllNotifications( - NotificationCommon::EXTENSION, true /* by_user */); + GetDisplayService()->RemoveAllNotifications(NotificationCommon::EXTENSION, + true /* by_user */); EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); } }
diff --git a/chrome/browser/extensions/component_loader.cc b/chrome/browser/extensions/component_loader.cc index 29f09a5..796b0bf 100644 --- a/chrome/browser/extensions/component_loader.cc +++ b/chrome/browser/extensions/component_loader.cc
@@ -47,7 +47,6 @@ #include "ui/base/resource/resource_bundle.h" #if defined(OS_CHROMEOS) -#include "ash/system/devicetype_utils.h" #include "chromeos/chromeos_switches.h" #include "components/chrome_apps/grit/chrome_apps_resources.h" #include "components/user_manager/user_manager.h" @@ -55,6 +54,7 @@ #include "content/public/browser/storage_partition.h" #include "extensions/browser/extensions_browser_client.h" #include "storage/browser/fileapi/file_system_context.h" +#include "ui/chromeos/devicetype_utils.h" #include "ui/file_manager/grit/file_manager_resources.h" #include "ui/keyboard/grit/keyboard_resources.h" #include "ui/keyboard/keyboard_util.h" @@ -555,11 +555,12 @@ #if defined(OS_CHROMEOS) && defined(GOOGLE_CHROME_BUILD) // Since this is a v2 app it has a background page. AddWithNameAndDescription( - IDR_GENIUS_APP_MANIFEST, base::FilePath(FILE_PATH_LITERAL( - "/usr/share/chromeos-assets/genius_app")), + IDR_GENIUS_APP_MANIFEST, + base::FilePath( + FILE_PATH_LITERAL("/usr/share/chromeos-assets/genius_app")), l10n_util::GetStringUTF8(IDS_GENIUS_APP_NAME), l10n_util::GetStringFUTF8(IDS_GENIUS_APP_DESCRIPTION, - ash::GetChromeOSDeviceName())); + ui::GetChromeOSDeviceName())); #endif if (!skip_session_components) {
diff --git a/chrome/browser/extensions/extension_message_bubble_controller.cc b/chrome/browser/extensions/extension_message_bubble_controller.cc index 7d90eb4..28406d85 100644 --- a/chrome/browser/extensions/extension_message_bubble_controller.cc +++ b/chrome/browser/extensions/extension_message_bubble_controller.cc
@@ -105,9 +105,7 @@ initialized_(false), is_highlighting_(false), is_active_bubble_(false), - extension_registry_observer_(this), browser_list_observer_(this) { - extension_registry_observer_.Add(ExtensionRegistry::Get(browser_->profile())); browser_list_observer_.Add(BrowserList::GetInstance()); } @@ -203,21 +201,12 @@ } } -void ExtensionMessageBubbleController::OnShown( - const base::Closure& close_bubble_callback) { - close_bubble_callback_ = close_bubble_callback; +void ExtensionMessageBubbleController::OnShown() { DCHECK(is_active_bubble_); GetProfileSet()->insert(profile()->GetOriginalProfile()); } void ExtensionMessageBubbleController::OnBubbleAction() { - // In addition to closing the bubble, OnBubbleAction() may result in a removal - // or disabling of the extension. To prevent triggering OnExtensionUnloaded(), - // which will also try to close the bubble, the controller's extension - // registry observer is removed. Note, we do not remove the extension registry - // observer in the cases of OnBubbleDismiss() and OnLinkedClicked() since they - // do not result in extensions being unloaded. - extension_registry_observer_.RemoveAll(); DCHECK_EQ(ACTION_BOUNDARY, user_action_); user_action_ = ACTION_EXECUTE; @@ -280,19 +269,6 @@ g_should_ignore_learn_more_for_testing = should_ignore; } -void ExtensionMessageBubbleController::OnExtensionUnloaded( - content::BrowserContext* browser_context, - const Extension* extension, - UnloadedExtensionReason reason) { - UpdateExtensionIdList(); - // If the callback is set, then that means that OnShown() was called, and the - // bubble is displayed. - if (close_bubble_callback_ && GetExtensionIdList().empty()) { - base::ResetAndReturn(&close_bubble_callback_).Run(); - } - // If the bubble refers to multiple extensions, we do not close the bubble. -} - void ExtensionMessageBubbleController::OnBrowserRemoved(Browser* browser) { if (browser == browser_) { if (is_highlighting_) {
diff --git a/chrome/browser/extensions/extension_message_bubble_controller.h b/chrome/browser/extensions/extension_message_bubble_controller.h index 33e306a2..53a13a7 100644 --- a/chrome/browser/extensions/extension_message_bubble_controller.h +++ b/chrome/browser/extensions/extension_message_bubble_controller.h
@@ -13,7 +13,6 @@ #include "base/scoped_observer.h" #include "chrome/browser/ui/browser_list_observer.h" #include "extensions/browser/browser_context_keyed_api_factory.h" -#include "extensions/browser/extension_registry_observer.h" #include "extensions/common/extension.h" class Browser; @@ -26,8 +25,7 @@ class ExtensionRegistry; -class ExtensionMessageBubbleController : public chrome::BrowserListObserver, - public ExtensionRegistryObserver { +class ExtensionMessageBubbleController : public chrome::BrowserListObserver { public: // UMA histogram constants. enum BubbleAction { @@ -169,8 +167,7 @@ // Called when the bubble is actually shown. Because some bubbles are delayed // (in order to weather the "focus storm"), they are not shown immediately. - // Accepts a callback from platform-specifc ui code to close the bubble. - void OnShown(const base::Closure& close_bubble_callback); + void OnShown(); // Callbacks from bubble. Declared virtual for testing purposes. virtual void OnBubbleAction(); @@ -186,10 +183,6 @@ bool should_ignore_learn_more); private: - // ExtensionRegistryObserver: - void OnExtensionUnloaded(content::BrowserContext* browser_context, - const Extension* extension, - UnloadedExtensionReason reason) override; // BrowserListObserver: void OnBrowserRemoved(Browser* browser) override; @@ -228,11 +221,6 @@ // Whether or not this bubble is the active bubble being shown. bool is_active_bubble_; - // Platform-specific implementation of closing the bubble. - base::Closure close_bubble_callback_; - - ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver> - extension_registry_observer_; ScopedObserver<BrowserList, BrowserListObserver> browser_list_observer_; DISALLOW_COPY_AND_ASSIGN(ExtensionMessageBubbleController);
diff --git a/chrome/browser/extensions/extension_message_bubble_controller_unittest.cc b/chrome/browser/extensions/extension_message_bubble_controller_unittest.cc index 9e6f49b..c93f79c 100644 --- a/chrome/browser/extensions/extension_message_bubble_controller_unittest.cc +++ b/chrome/browser/extensions/extension_message_bubble_controller_unittest.cc
@@ -121,13 +121,10 @@ BUBBLE_ACTION_CLICK_DISMISS_BUTTON, BUBBLE_ACTION_DISMISS_DEACTIVATION, BUBBLE_ACTION_CLICK_LINK, - BUBBLE_ACTION_IGNORE, }; FakeExtensionMessageBubble() - : is_closed_(true), - action_(BUBBLE_ACTION_CLICK_ACTION_BUTTON), - controller_(nullptr) {} + : action_(BUBBLE_ACTION_CLICK_ACTION_BUTTON), controller_(nullptr) {} void set_action_on_show(ExtensionBubbleAction action) { action_ = action; @@ -136,43 +133,25 @@ controller_ = controller; } - bool is_closed() { return is_closed_; } - void Show() { - controller_->OnShown( - base::Bind(&FakeExtensionMessageBubble::Close, base::Unretained(this))); - - // Depending on the user action, the bubble may be closed as result. + controller_->OnShown(); switch (action_) { case BUBBLE_ACTION_CLICK_ACTION_BUTTON: controller_->OnBubbleAction(); - is_closed_ = true; break; case BUBBLE_ACTION_CLICK_DISMISS_BUTTON: controller_->OnBubbleDismiss(false); - is_closed_ = true; break; case BUBBLE_ACTION_DISMISS_DEACTIVATION: controller_->OnBubbleDismiss(true); - is_closed_ = true; break; case BUBBLE_ACTION_CLICK_LINK: controller_->OnLinkClicked(); - // Opening a new tab for the learn more link can cause the bubble to - // close. - is_closed_ = true; - break; - case BUBBLE_ACTION_IGNORE: - is_closed_ = false; break; } } private: - // Dummy close callback. - void Close() { is_closed_ = true; } - - bool is_closed_; ExtensionBubbleAction action_; ExtensionMessageBubbleController* controller_; @@ -818,86 +797,6 @@ } } -// Tests that a displayed extension bubble will be closed after its associated -// extension is uninstalled. -TEST_F(ExtensionMessageBubbleTest, TestBubbleClosedAfterExtensionUninstall) { - Init(); - ASSERT_TRUE(LoadExtensionOverridingNtp("1", kId1, Manifest::UNPACKED)); - - auto controller = base::MakeUnique<TestExtensionMessageBubbleController>( - new NtpOverriddenBubbleDelegate(browser()->profile()), browser()); - controller->SetIsActiveBubble(); - - EXPECT_TRUE(controller->ShouldShow()); - ASSERT_EQ(1U, controller->GetExtensionList().size()); - - // Simulate showing the bubble and take no action. - FakeExtensionMessageBubble bubble; - EXPECT_TRUE(controller->ShouldShow()); - bubble.set_controller(controller.get()); - bubble.set_action_on_show(FakeExtensionMessageBubble::BUBBLE_ACTION_IGNORE); - bubble.Show(); - EXPECT_FALSE(bubble.is_closed()); - - // Uninstall the extension. - service_->UninstallExtension(kId1, UNINSTALL_REASON_FOR_TESTING, - base::Bind(&base::DoNothing), nullptr); - ASSERT_EQ(0U, controller->GetExtensionList().size()); - - // The bubble should be closed after the extension is uninstalled. - EXPECT_TRUE(bubble.is_closed()); - - controller.reset(); -} - -// Tests that a bubble associated with multiple extensions remains shown after -// one of its associated extensions is uninstalled. Also tests that the bubble -// closes when all of its associated extensions are uninstalled. -TEST_F(ExtensionMessageBubbleTest, TestBubbleShownForMultipleExtensions) { - FeatureSwitch::ScopedOverride force_dev_mode_highlighting( - FeatureSwitch::force_dev_mode_highlighting(), true); - Init(); - ASSERT_TRUE(LoadGenericExtension("1", kId1, Manifest::UNPACKED)); - ASSERT_TRUE(LoadGenericExtension("2", kId2, Manifest::UNPACKED)); - ASSERT_TRUE(LoadGenericExtension("3", kId3, Manifest::UNPACKED)); - - auto controller = base::MakeUnique<TestExtensionMessageBubbleController>( - new DevModeBubbleDelegate(browser()->profile()), browser()); - controller->SetIsActiveBubble(); - - EXPECT_TRUE(controller->ShouldShow()); - ASSERT_EQ(3U, controller->GetExtensionList().size()); - - // Simulate showing the bubble and take no action. - FakeExtensionMessageBubble bubble; - EXPECT_TRUE(controller->ShouldShow()); - bubble.set_controller(controller.get()); - bubble.set_action_on_show(FakeExtensionMessageBubble::BUBBLE_ACTION_IGNORE); - bubble.Show(); - EXPECT_FALSE(bubble.is_closed()); - - // Uninstall one of the three extensions. - service_->UninstallExtension(kId1, UNINSTALL_REASON_FOR_TESTING, - base::Bind(&base::DoNothing), nullptr); - ASSERT_EQ(2U, controller->GetExtensionList().size()); - - // The bubble should still be shown for the remaining installed extensions. - EXPECT_FALSE(bubble.is_closed()); - - // Uninstall the remaining two extensions. - service_->UninstallExtension(kId2, UNINSTALL_REASON_FOR_TESTING, - base::Bind(&base::DoNothing), nullptr); - service_->UninstallExtension(kId3, UNINSTALL_REASON_FOR_TESTING, - base::Bind(&base::DoNothing), nullptr); - ASSERT_EQ(0U, controller->GetExtensionList().size()); - - // Since all the bubble's associated extensions are uninstalled, the bubble - // should be closed. - EXPECT_TRUE(bubble.is_closed()); - - controller.reset(); -} - // The feature this is meant to test is only enacted on Windows, but it should // pass on all platforms. TEST_F(ExtensionMessageBubbleTest, NtpOverriddenControllerTest) {
diff --git a/chrome/browser/extensions/startup_helper.cc b/chrome/browser/extensions/startup_helper.cc index 4bfaaa1..da864207 100644 --- a/chrome/browser/extensions/startup_helper.cc +++ b/chrome/browser/extensions/startup_helper.cc
@@ -13,9 +13,11 @@ #include "base/single_thread_task_runner.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" +#include "base/task_scheduler/post_task.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/extensions/chrome_extensions_client.h" #include "content/public/browser/browser_thread.h" +#include "extensions/browser/extension_file_task_runner.h" #include "extensions/browser/sandboxed_unpacker.h" #include "extensions/common/extension.h" @@ -78,21 +80,19 @@ public: ValidateCrxHelper(const CRXFileInfo& file, const base::FilePath& temp_dir, - base::RunLoop* run_loop) + base::OnceClosure quit_closure) : crx_file_(file), temp_dir_(temp_dir), - run_loop_(run_loop), - finished_(false), + quit_closure_(std::move(quit_closure)), success_(false) {} - bool finished() { return finished_; } bool success() { return success_; } const base::string16& error() { return error_; } void Start() { - BrowserThread::PostTask( - BrowserThread::FILE, FROM_HERE, - base::BindOnce(&ValidateCrxHelper::StartOnFileThread, this)); + GetExtensionFileTaskRunner()->PostTask( + FROM_HERE, + base::BindOnce(&ValidateCrxHelper::StartOnBlockingThread, this)); } protected: @@ -103,7 +103,7 @@ std::unique_ptr<base::DictionaryValue> original_manifest, const Extension* extension, const SkBitmap& install_icon) override { - finished_ = true; + DCHECK(GetExtensionFileTaskRunner()->RunsTasksInCurrentSequence()); success_ = true; BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, @@ -111,7 +111,7 @@ } void OnUnpackFailure(const CrxInstallError& error) override { - finished_ = true; + DCHECK(GetExtensionFileTaskRunner()->RunsTasksInCurrentSequence()); success_ = false; error_ = error.message(); BrowserThread::PostTask( @@ -120,19 +120,15 @@ } void FinishOnUIThread() { - CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - if (run_loop_->running()) - run_loop_->Quit(); + DCHECK_CURRENTLY_ON(BrowserThread::UI); + std::move(quit_closure_).Run(); } - void StartOnFileThread() { - CHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); - scoped_refptr<base::SingleThreadTaskRunner> file_task_runner = - BrowserThread::GetTaskRunnerForThread(BrowserThread::FILE); - + void StartOnBlockingThread() { + DCHECK(GetExtensionFileTaskRunner()->RunsTasksInCurrentSequence()); scoped_refptr<SandboxedUnpacker> unpacker(new SandboxedUnpacker( Manifest::INTERNAL, 0, /* no special creation flags */ - temp_dir_, file_task_runner.get(), this)); + temp_dir_, GetExtensionFileTaskRunner().get(), this)); unpacker->StartWithCrx(crx_file_); } @@ -142,17 +138,17 @@ // The temporary directory where the sandboxed unpacker will do work. const base::FilePath& temp_dir_; - // Unowned pointer to a runloop, so our consumer can wait for us to finish. - base::RunLoop* run_loop_; - - // Whether we're finished unpacking; - bool finished_; + // Closure called upon completion. + base::OnceClosure quit_closure_; // Whether the unpacking was successful. bool success_; // If the unpacking wasn't successful, this contains an error message. base::string16 error_; + + private: + DISALLOW_COPY_AND_ASSIGN(ValidateCrxHelper); }; } // namespace @@ -176,7 +172,7 @@ base::RunLoop run_loop; CRXFileInfo file(path); scoped_refptr<ValidateCrxHelper> helper( - new ValidateCrxHelper(file, temp_dir.GetPath(), &run_loop)); + new ValidateCrxHelper(file, temp_dir.GetPath(), run_loop.QuitClosure())); helper->Start(); run_loop.Run();
diff --git a/chrome/browser/external_protocol/external_protocol_handler_unittest.cc b/chrome/browser/external_protocol/external_protocol_handler_unittest.cc index 12e0128d..f2e5872 100644 --- a/chrome/browser/external_protocol/external_protocol_handler_unittest.cc +++ b/chrome/browser/external_protocol/external_protocol_handler_unittest.cc
@@ -171,6 +171,12 @@ false, false, true); } +TEST_F(ExternalProtocolHandlerTest, + TestLaunchSchemeBlockedChromeOtherModeDefault) { + DoTest(ExternalProtocolHandler::BLOCK, + shell_integration::OTHER_MODE_IS_DEFAULT, false, false, true); +} + TEST_F(ExternalProtocolHandlerTest, TestLaunchSchemeUnBlockedChromeDefault) { DoTest(ExternalProtocolHandler::DONT_BLOCK, shell_integration::IS_DEFAULT, false, false, true); @@ -187,6 +193,12 @@ } TEST_F(ExternalProtocolHandlerTest, + TestLaunchSchemeUnBlockedChromeOtherModeDefault) { + DoTest(ExternalProtocolHandler::DONT_BLOCK, + shell_integration::OTHER_MODE_IS_DEFAULT, false, true, false); +} + +TEST_F(ExternalProtocolHandlerTest, DISABLED_TestLaunchSchemeUnknownChromeDefault) { DoTest(ExternalProtocolHandler::UNKNOWN, shell_integration::IS_DEFAULT, false, false, true); @@ -202,6 +214,12 @@ true, false, false); } +TEST_F(ExternalProtocolHandlerTest, + TestLaunchSchemeUnknownChromeOtherModeDefault) { + DoTest(ExternalProtocolHandler::UNKNOWN, + shell_integration::OTHER_MODE_IS_DEFAULT, true, false, false); +} + TEST_F(ExternalProtocolHandlerTest, TestGetBlockStateUnknown) { ExternalProtocolHandler::BlockState block_state = ExternalProtocolHandler::GetBlockState("tel", profile_.get());
diff --git a/chrome/browser/favicon/content_favicon_driver_browsertest.cc b/chrome/browser/favicon/content_favicon_driver_browsertest.cc index 539aacec..8681db4 100644 --- a/chrome/browser/favicon/content_favicon_driver_browsertest.cc +++ b/chrome/browser/favicon/content_favicon_driver_browsertest.cc
@@ -443,6 +443,52 @@ GetFaviconForPageURL(landing_url, favicon_base::FAVICON).bitmap_data); } +// Test that a page which uses JavaScript's history.replaceState() to update +// the URL in the omnibox (and history) gets associated favicons. +IN_PROC_BROWSER_TEST_F(ContentFaviconDriverTest, + AssociateIconWithInitialPageIconDespiteReplaceState) { + ASSERT_TRUE(embedded_test_server()->Start()); + GURL url = + embedded_test_server()->GetURL("/favicon/replacestate_with_favicon.html"); + GURL replacestate_url = embedded_test_server()->GetURL( + "/favicon/replacestate_with_favicon_replaced.html"); + + PendingTaskWaiter waiter(web_contents(), replacestate_url); + ui_test_utils::NavigateToURLWithDisposition( + browser(), url, WindowOpenDisposition::CURRENT_TAB, + ui_test_utils::BROWSER_TEST_NONE); + waiter.Wait(); + + EXPECT_NE(nullptr, + GetFaviconForPageURL(url, favicon_base::FAVICON).bitmap_data); + EXPECT_NE(nullptr, + GetFaviconForPageURL(replacestate_url, favicon_base::FAVICON) + .bitmap_data); +} + +// Test that a page which uses JavaScript's history.pushState() to update +// the URL in the omnibox (and history) gets associated favicons. +IN_PROC_BROWSER_TEST_F(ContentFaviconDriverTest, + AssociateIconWithInitialPageIconDespitePushState) { + ASSERT_TRUE(embedded_test_server()->Start()); + GURL url = + embedded_test_server()->GetURL("/favicon/pushstate_with_favicon.html"); + GURL pushstate_url = embedded_test_server()->GetURL( + "/favicon/pushstate_with_favicon_pushed.html"); + + PendingTaskWaiter waiter(web_contents(), pushstate_url); + ui_test_utils::NavigateToURLWithDisposition( + browser(), url, WindowOpenDisposition::CURRENT_TAB, + ui_test_utils::BROWSER_TEST_NONE); + waiter.Wait(); + + EXPECT_NE(nullptr, + GetFaviconForPageURL(url, favicon_base::FAVICON).bitmap_data); + EXPECT_NE( + nullptr, + GetFaviconForPageURL(pushstate_url, favicon_base::FAVICON).bitmap_data); +} + #if defined(OS_ANDROID) IN_PROC_BROWSER_TEST_F(ContentFaviconDriverTest, LoadIconFromWebManifestDespitePushState) {
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 0df7d11..2b9c6e6 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -255,6 +255,12 @@ "If enabled, requests missing CVC when offering to upload credit cards to " "Google Payments."; +const char kEnableAutofillCreditCardUploadGoogleLogoName[] = + "Show Google Logo for Autofill credit card upload"; +const char kEnableAutofillCreditCardUploadGoogleLogoDescription[] = + "If enabled, displays the Google logo in the save prompt when offering to " + "upload credit cards to Google Payments."; + const char kEnableAutofillCreditCardUploadNewUiName[] = "Enable updated UI for Autofill credit card upload"; const char kEnableAutofillCreditCardUploadNewUiDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index 754e05a..9591c01e 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -181,6 +181,9 @@ extern const char kEnableAutofillCreditCardUploadCvcPromptName[]; extern const char kEnableAutofillCreditCardUploadCvcPromptDescription[]; +extern const char kEnableAutofillCreditCardUploadGoogleLogoName[]; +extern const char kEnableAutofillCreditCardUploadGoogleLogoDescription[]; + extern const char kEnableAutofillCreditCardUploadNewUiName[]; extern const char kEnableAutofillCreditCardUploadNewUiDescription[];
diff --git a/chrome/browser/installable/installable_manager.cc b/chrome/browser/installable/installable_manager.cc index ba07cb8f6..0105e29 100644 --- a/chrome/browser/installable/installable_manager.cc +++ b/chrome/browser/installable/installable_manager.cc
@@ -5,10 +5,12 @@ #include "chrome/browser/installable/installable_manager.h" #include "base/bind.h" +#include "base/feature_list.h" #include "base/stl_util.h" #include "base/strings/string_util.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ssl/security_state_tab_helper.h" +#include "chrome/common/chrome_features.h" #include "components/security_state/core/security_state.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_thread.h" @@ -88,7 +90,6 @@ page_status_(InstallabilityCheckStatus::NOT_STARTED), menu_open_count_(0), menu_item_add_to_homescreen_count_(0), - is_active_(false), is_pwa_check_complete_(false), weak_factory_(this) { // This is null in unit tests. @@ -138,13 +139,14 @@ // Return immediately if we're already working on a task. The new task will be // looked at once the current task is finished. - tasks_.push_back({params, callback}); - if (is_active_) + task_queue_.Insert({params, callback}); + if (task_queue_.is_active_) return; - is_active_ = true; + task_queue_.is_active_ = true; if (page_status_ == InstallabilityCheckStatus::NOT_STARTED) page_status_ = InstallabilityCheckStatus::NOT_COMPLETED; + StartNextTask(); } @@ -306,8 +308,7 @@ void InstallableManager::Reset() { // Prevent any outstanding callbacks to or from this object from being called. weak_factory_.InvalidateWeakPtrs(); - tasks_.clear(); - paused_tasks_.clear(); + task_queue_.Reset(); icons_.clear(); // We may have reset prior to completion, in which case |menu_open_count_| or @@ -329,13 +330,11 @@ valid_manifest_ = base::MakeUnique<ValidManifestProperty>(); worker_ = base::MakeUnique<ServiceWorkerProperty>(); - is_active_ = false; + task_queue_.is_active_ = false; } void InstallableManager::SetManifestDependentTasksComplete() { - DCHECK(!tasks_.empty()); - const InstallableParams& params = tasks_[0].first; - + const InstallableParams& params = task_queue_.Current().first; valid_manifest_->fetched = true; worker_->fetched = true; SetIconFetched(ParamsForPrimaryIcon(params)); @@ -370,20 +369,12 @@ } void InstallableManager::StartNextTask() { - // If there's nothing to do, exit. Resources remain cached so any future calls - // won't re-fetch anything that has already been retrieved. - if (tasks_.empty()) { - is_active_ = false; - return; - } - - DCHECK(is_active_); + DCHECK(task_queue_.is_active_); WorkOnTask(); } void InstallableManager::WorkOnTask() { - DCHECK(!tasks_.empty()); - const Task& task = tasks_[0]; + const Task& task = task_queue_.Current(); const InstallableParams& params = task.first; InstallableStatusCode code = GetErrorCode(params); @@ -397,8 +388,13 @@ // again. if (worker_error() == NO_MATCHING_SERVICE_WORKER) worker_ = base::MakeUnique<ServiceWorkerProperty>(); - tasks_.erase(tasks_.begin()); - StartNextTask(); + task_queue_.Next(); + + if (task_queue_.IsEmpty()) + task_queue_.is_active_ = false; + else + StartNextTask(); + return; } @@ -475,11 +471,10 @@ return false; } - // TODO(dominickn,mlamouri): when Chrome supports "minimal-ui", it should be - // accepted. If we accept it today, it would fallback to "browser" and make - // this check moot. See https://crbug.com/604390. if (manifest.display != blink::kWebDisplayModeStandalone && - manifest.display != blink::kWebDisplayModeFullscreen) { + manifest.display != blink::kWebDisplayModeFullscreen && + !(manifest.display == blink::kWebDisplayModeMinimalUi && + base::FeatureList::IsEnabled(features::kPwaMinimalUi))) { valid_manifest_->error = MANIFEST_DISPLAY_NOT_SUPPORTED; return false; } @@ -519,16 +514,19 @@ worker_->error = NOT_OFFLINE_CAPABLE; break; case content::ServiceWorkerCapability::NO_SERVICE_WORKER: - Task& task = tasks_[0]; + Task& task = task_queue_.Current(); InstallableParams& params = task.first; if (params.wait_for_worker) { // Wait for ServiceWorkerContextObserver::OnRegistrationStored. Set the // param |wait_for_worker| to false so we only wait once per task. params.wait_for_worker = false; OnWaitingForServiceWorker(); - paused_tasks_.push_back(task); - tasks_.erase(tasks_.begin()); - StartNextTask(); + task_queue_.PauseCurrent(); + if (task_queue_.IsEmpty()) + task_queue_.is_active_ = false; + else + StartNextTask(); + return; } worker_->has_worker = false; @@ -592,21 +590,18 @@ // a) we've already failed the check, or // b) we haven't yet called CheckHasServiceWorker. // Otherwise if the scope doesn't match we keep waiting. - if (paused_tasks_.empty() || !content::ServiceWorkerContext::ScopeMatches( - pattern, manifest().start_url)) { + if (!task_queue_.HasPaused() || !content::ServiceWorkerContext::ScopeMatches( + pattern, manifest().start_url)) { return; } - // Unpause the paused tasks. - for (const auto& task : paused_tasks_) - tasks_.push_back(task); - paused_tasks_.clear(); + task_queue_.UnpauseAll(); // Start the pipeline again if it is not running. This will call // CheckHasServiceWorker to check if the SW has a fetch handler. Otherwise, // adding the tasks to the end of the active queue is sufficient. - if (!is_active_) { - is_active_ = true; + if (!task_queue_.is_active_) { + task_queue_.is_active_ = true; StartNextTask(); } } @@ -635,3 +630,47 @@ bool InstallableManager::is_installable() const { return valid_manifest_->is_valid && worker_->has_worker; } + +InstallableManager::TaskQueue::TaskQueue() : is_active_(false) {} +InstallableManager::TaskQueue::~TaskQueue() {} + +void InstallableManager::TaskQueue::Insert(Task task) { + tasks_.push_back(task); +} + +void InstallableManager::TaskQueue::Reset() { + tasks_.clear(); + paused_tasks_.clear(); +} + +bool InstallableManager::TaskQueue::HasPaused() const { + return !paused_tasks_.empty(); +} + +void InstallableManager::TaskQueue::UnpauseAll() { + for (const auto& task : paused_tasks_) + Insert(task); + + paused_tasks_.clear(); +} + +InstallableManager::Task& InstallableManager::TaskQueue::Current() { + DCHECK(!tasks_.empty()); + return tasks_[0]; +} + +void InstallableManager::TaskQueue::PauseCurrent() { + paused_tasks_.push_back(Current()); + Next(); +} + +void InstallableManager::TaskQueue::Next() { + DCHECK(!tasks_.empty()); + tasks_.erase(tasks_.begin()); +} + +bool InstallableManager::TaskQueue::IsEmpty() const { + // TODO(mcgreevy): try to remove this method by removing the need to + // explicitly call StartNextTask. + return tasks_.empty(); +}
diff --git a/chrome/browser/installable/installable_manager.h b/chrome/browser/installable/installable_manager.h index 42b01761..0340fa13 100644 --- a/chrome/browser/installable/installable_manager.h +++ b/chrome/browser/installable/installable_manager.h
@@ -278,11 +278,49 @@ const content::Manifest& manifest() const; bool is_installable() const; - // The list of <params, callback> pairs that have come from a call to GetData. - std::vector<Task> tasks_; + // TaskQueue keeps track of pending tasks. + class TaskQueue { + public: + TaskQueue(); + ~TaskQueue(); - // Tasks which are waiting indefinitely for a service worker to be detected. - std::vector<Task> paused_tasks_; + // Adds task to the end of the active list of tasks to be processed. + void Insert(Task task); + + // Moves the current task from the main to the paused list. + void PauseCurrent(); + + // Reports whether there are any tasks in the paused list. + bool HasPaused() const; + + // Moves all paused tasks to the main list. + void UnpauseAll(); + + // Returns the currently active task. + Task& Current(); + + // Advances to the next task. + void Next(); + + // Clears all tasks from the main and paused list. + void Reset(); + + // Reports whether the main list is empty. + bool IsEmpty() const; + + private: + // The list of <params, callback> pairs that have come from a call to + // InstallableManager::GetData. + std::vector<Task> tasks_; + + // Tasks which are waiting indefinitely for a service worker to be detected. + std::vector<Task> paused_tasks_; + + public: + bool is_active_; + }; + + TaskQueue task_queue_; // Installable properties cached on this object. std::unique_ptr<ManifestProperty> manifest_; @@ -305,7 +343,6 @@ int menu_open_count_; int menu_item_add_to_homescreen_count_; - bool is_active_; bool is_pwa_check_complete_; base::WeakPtrFactory<InstallableManager> weak_factory_;
diff --git a/chrome/browser/installable/installable_manager_browsertest.cc b/chrome/browser/installable/installable_manager_browsertest.cc index 214798b..3eaf21a7 100644 --- a/chrome/browser/installable/installable_manager_browsertest.cc +++ b/chrome/browser/installable/installable_manager_browsertest.cc
@@ -234,7 +234,7 @@ EXPECT_EQ(NO_ERROR_DETECTED, manager->manifest_error()); EXPECT_EQ(NO_ERROR_DETECTED, manager->valid_manifest_error()); EXPECT_EQ(NO_ERROR_DETECTED, manager->worker_error()); - EXPECT_TRUE(manager->tasks_.empty()); + EXPECT_TRUE(manager->task_queue_.IsEmpty()); } IN_PROC_BROWSER_TEST_F(InstallableManagerBrowserTest, CheckNoManifest) { @@ -565,7 +565,7 @@ EXPECT_EQ(NO_ERROR_DETECTED, manager->valid_manifest_error()); EXPECT_EQ(NO_ERROR_DETECTED, manager->worker_error()); EXPECT_EQ(NO_ERROR_DETECTED, (manager->icon_error(kPrimaryIconParams))); - EXPECT_TRUE(manager->tasks_.empty()); + EXPECT_TRUE(manager->task_queue_.IsEmpty()); } // Request everything except badge icon again without navigating away. This @@ -602,7 +602,7 @@ EXPECT_EQ(NO_ERROR_DETECTED, manager->valid_manifest_error()); EXPECT_EQ(NO_ERROR_DETECTED, manager->worker_error()); EXPECT_EQ(NO_ERROR_DETECTED, (manager->icon_error(kPrimaryIconParams))); - EXPECT_TRUE(manager->tasks_.empty()); + EXPECT_TRUE(manager->task_queue_.IsEmpty()); } { @@ -617,7 +617,7 @@ EXPECT_EQ(NO_ERROR_DETECTED, manager->manifest_error()); EXPECT_EQ(NO_ERROR_DETECTED, manager->valid_manifest_error()); EXPECT_EQ(NO_ERROR_DETECTED, manager->worker_error()); - EXPECT_TRUE(manager->tasks_.empty()); + EXPECT_TRUE(manager->task_queue_.IsEmpty()); } } @@ -730,8 +730,8 @@ EXPECT_EQ(NO_ERROR_DETECTED, manager->valid_manifest_error()); EXPECT_EQ(NO_ERROR_DETECTED, manager->worker_error()); EXPECT_EQ(NO_ERROR_DETECTED, (manager->icon_error(kPrimaryIconParams))); - EXPECT_TRUE(manager->tasks_.empty()); - EXPECT_FALSE(manager->paused_tasks_.empty()); + EXPECT_TRUE(manager->task_queue_.IsEmpty()); + EXPECT_TRUE(manager->task_queue_.HasPaused()); { // Fetching just the manifest and icons should not hang while the other call @@ -782,8 +782,8 @@ EXPECT_EQ(NO_ERROR_DETECTED, manager->valid_manifest_error()); EXPECT_EQ(NO_ERROR_DETECTED, manager->worker_error()); EXPECT_EQ(NO_ERROR_DETECTED, (manager->icon_error(kPrimaryIconParams))); - EXPECT_TRUE(manager->tasks_.empty()); - EXPECT_TRUE(manager->paused_tasks_.empty()); + EXPECT_TRUE(manager->task_queue_.IsEmpty()); + EXPECT_FALSE(manager->task_queue_.HasPaused()); } IN_PROC_BROWSER_TEST_F(InstallableManagerBrowserTest, @@ -809,8 +809,8 @@ sw_run_loop.Run(); // We should now be waiting for the service worker. - EXPECT_TRUE(manager->tasks_.empty()); - EXPECT_FALSE(manager->paused_tasks_.empty()); + EXPECT_TRUE(manager->task_queue_.IsEmpty()); + EXPECT_TRUE(manager->task_queue_.HasPaused()); // Load the service worker with no fetch handler. EXPECT_TRUE(content::ExecuteScript(web_contents,
diff --git a/chrome/browser/installable/installable_manager_unittest.cc b/chrome/browser/installable/installable_manager_unittest.cc index eb5bfa4d..7bcbe25 100644 --- a/chrome/browser/installable/installable_manager_unittest.cc +++ b/chrome/browser/installable/installable_manager_unittest.cc
@@ -5,6 +5,8 @@ #include "chrome/browser/installable/installable_manager.h" #include "base/strings/utf_string_conversions.h" +#include "base/test/scoped_feature_list.h" +#include "chrome/common/chrome_features.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/WebKit/public/platform/WebDisplayMode.h" @@ -184,7 +186,9 @@ EXPECT_EQ(NO_ERROR_DETECTED, GetErrorCode()); } -TEST_F(InstallableManagerUnitTest, ManifestDisplayStandaloneFullscreen) { +TEST_F(InstallableManagerUnitTest, ManifestDisplayModes) { + base::test::ScopedFeatureList feature_list; + feature_list.InitAndDisableFeature(features::kPwaMinimalUi); content::Manifest manifest = GetValidManifest(); manifest.display = blink::kWebDisplayModeUndefined; @@ -207,3 +211,14 @@ EXPECT_TRUE(IsManifestValid(manifest)); EXPECT_EQ(NO_ERROR_DETECTED, GetErrorCode()); } + +TEST_F(InstallableManagerUnitTest, ManifestDisplayModesMinimalUiEnabled) { + base::test::ScopedFeatureList feature_list; + feature_list.InitAndEnableFeature(features::kPwaMinimalUi); + + content::Manifest manifest = GetValidManifest(); + manifest.display = blink::kWebDisplayModeMinimalUi; + + EXPECT_TRUE(IsManifestValid(manifest)); + EXPECT_EQ(NO_ERROR_DETECTED, GetErrorCode()); +}
diff --git a/chrome/browser/media/router/BUILD.gn b/chrome/browser/media/router/BUILD.gn index b61520f..9c8a96b 100644 --- a/chrome/browser/media/router/BUILD.gn +++ b/chrome/browser/media/router/BUILD.gn
@@ -43,8 +43,6 @@ "media_routes_observer.h", "media_sinks_observer.cc", "media_sinks_observer.h", - "mojo/media_route_controller.cc", - "mojo/media_route_controller.h", "offscreen_presentation_manager.cc", "offscreen_presentation_manager.h", "offscreen_presentation_manager_factory.cc", @@ -80,6 +78,8 @@ "media_router_ui_service.h", "media_router_ui_service_factory.cc", "media_router_ui_service_factory.h", + "mojo/media_route_controller.cc", + "mojo/media_route_controller.h", "mojo/media_route_provider_util_win.cc", "mojo/media_route_provider_util_win.h", "mojo/media_router_desktop.cc",
diff --git a/chrome/browser/media/router/browser_presentation_connection_proxy.h b/chrome/browser/media/router/browser_presentation_connection_proxy.h index 73727b8..132663d 100644 --- a/chrome/browser/media/router/browser_presentation_connection_proxy.h +++ b/chrome/browser/media/router/browser_presentation_connection_proxy.h
@@ -40,7 +40,7 @@ // |route_| is closed or terminated, instance of this class will be destroyed. class BrowserPresentationConnectionProxy - : public NON_EXPORTED_BASE(blink::mojom::PresentationConnection), + : public blink::mojom::PresentationConnection, public RouteMessageObserver { public: using OnMessageCallback = base::OnceCallback<void(bool)>;
diff --git a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service.cc b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service.cc index fd02e1c..8b6fbc21 100644 --- a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service.cc +++ b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service.cc
@@ -65,8 +65,8 @@ media_router::SinkIconType::CAST); media_router::CastSinkExtraData extra_data; - extra_data.ip_address = ip_address; - extra_data.port = service.service_host_port.port(); + extra_data.ip_endpoint = + net::IPEndPoint(ip_address, service.service_host_port.port()); extra_data.model_name = service_data["md"]; extra_data.capabilities = cast_channel::CastDeviceCapability::NONE;
diff --git a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.cc b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.cc index a5bdc99..803c45f0 100644 --- a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.cc +++ b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.cc
@@ -23,8 +23,9 @@ media_router::SinkIconType::CAST); media_router::CastSinkExtraData extra_data; - extra_data.ip_address = dial_sink.dial_data().ip_address; - extra_data.port = media_router::CastMediaSinkServiceImpl::kCastControlPort; + extra_data.ip_endpoint = + net::IPEndPoint(dial_sink.dial_data().ip_address, + media_router::CastMediaSinkServiceImpl::kCastControlPort); extra_data.model_name = dial_sink.dial_data().model_name; extra_data.discovered_by_dial = true; extra_data.capabilities = cast_channel::CastDeviceCapability::NONE; @@ -85,16 +86,16 @@ // Copy cast sink from mDNS service to |current_sinks_|. for (const auto& sink_it : current_sinks_by_mdns_) { DVLOG(2) << "Discovered by mdns [name]: " << sink_it.second.sink().name() - << " [ip_address]: " - << sink_it.second.cast_data().ip_address.ToString(); + << " [ip_endpoint]: " + << sink_it.second.cast_data().ip_endpoint.ToString(); current_sinks_.insert(sink_it.second); } // Copy cast sink from DIAL discovery to |current_sinks_|. for (const auto& sink_it : current_sinks_by_dial_) { DVLOG(2) << "Discovered by dial [name]: " << sink_it.second.sink().name() - << " [ip_address]: " - << sink_it.second.cast_data().ip_address.ToString(); + << " [ip_endpoint]: " + << sink_it.second.cast_data().ip_endpoint.ToString(); if (!base::ContainsKey(current_sinks_by_mdns_, sink_it.first)) current_sinks_.insert(sink_it.second); } @@ -114,8 +115,7 @@ current_service_ip_endpoints_.clear(); for (const auto& cast_sink : cast_sinks) { - net::IPEndPoint ip_endpoint(cast_sink.cast_data().ip_address, - cast_sink.cast_data().port); + const net::IPEndPoint& ip_endpoint = cast_sink.cast_data().ip_endpoint; current_service_ip_endpoints_.insert(ip_endpoint); OpenChannel(ip_endpoint, cast_sink); } @@ -188,7 +188,7 @@ DCHECK(socket); if (socket->error_state() != cast_channel::ChannelError::NONE) { DVLOG(2) << "Fail to open channel " - << cast_sink.cast_data().ip_address.ToString() + << cast_sink.cast_data().ip_endpoint.ToString() << " [name]: " << cast_sink.sink().name(); return; } @@ -202,7 +202,7 @@ DVLOG(2) << "Ading sink to current_sinks_ [name]: " << updated_sink.sink().name(); - auto& ip_address = cast_sink.cast_data().ip_address; + auto& ip_address = cast_sink.cast_data().ip_endpoint.address(); // Add or update existing cast sink. if (updated_sink.cast_data().discovered_by_dial) { current_sinks_by_dial_[ip_address] = updated_sink;
diff --git a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl_unittest.cc b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl_unittest.cc index 7d5c8ae6..9734b78 100644 --- a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl_unittest.cc +++ b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl_unittest.cc
@@ -40,7 +40,7 @@ media_router::MediaSink sink(unique_id, friendly_name, media_router::SinkIconType::CAST); media_router::CastSinkExtraData extra_data; - extra_data.ip_address = ip_endpoint.address(); + extra_data.ip_endpoint = ip_endpoint; extra_data.port = ip_endpoint.port(); extra_data.model_name = base::StringPrintf("model name %d", num); extra_data.cast_channel_id = num;
diff --git a/chrome/browser/media/router/media_router.h b/chrome/browser/media/router/media_router.h index 48b855cc..4913a8c 100644 --- a/chrome/browser/media/router/media_router.h +++ b/chrome/browser/media/router/media_router.h
@@ -13,6 +13,7 @@ #include "base/callback.h" #include "base/callback_list.h" #include "base/time/time.h" +#include "build/build_config.h" #include "chrome/browser/media/cast_remoting_connector.h" #include "chrome/browser/media/router/route_message_observer.h" #include "chrome/common/media_router/discovery/media_sink_internal.h" @@ -34,11 +35,13 @@ namespace media_router { class IssuesObserver; -class MediaRouteController; class MediaRoutesObserver; class MediaSinksObserver; class PresentationConnectionStateObserver; class RouteRequestResult; +#if !defined(OS_ANDROID) +class MediaRouteController; +#endif // !defined(OS_ANDROID) // Type of callback used in |CreateRoute()|, |JoinRoute()|, and // |ConnectRouteByRouteId()|. Callback is invoked when the route request either @@ -195,10 +198,12 @@ // there is a change to the media routes, subclass MediaRoutesObserver. virtual std::vector<MediaRoute> GetCurrentRoutes() const = 0; +#if !defined(OS_ANDROID) // Returns a controller for sending media commands to a route. Returns a // nullptr if no MediaRoute exists for the given |route_id|. virtual scoped_refptr<MediaRouteController> GetRouteController( const MediaRoute::Id& route_id) = 0; +#endif // !defined(OS_ANDROID) // Registers/Unregisters a CastRemotingConnector with the |tab_id|. For a // given |tab_id|, only one CastRemotingConnector can be registered. The @@ -211,10 +216,12 @@ private: friend class IssuesObserver; friend class MediaSinksObserver; - friend class MediaRouteController; friend class MediaRoutesObserver; friend class PresentationConnectionStateObserver; friend class RouteMessageObserver; +#if !defined(OS_ANDROID) + friend class MediaRouteController; +#endif // !defined(OS_ANDROID) // The following functions are called by friend Observer classes above. @@ -268,11 +275,13 @@ virtual void UnregisterRouteMessageObserver( RouteMessageObserver* observer) = 0; +#if !defined(OS_ANDROID) // Removes the MediaRouteController for |route_id| from the list of // controllers held by |this|. Called by MediaRouteController when it is // invalidated. virtual void DetachRouteController(const MediaRoute::Id& route_id, MediaRouteController* controller) = 0; +#endif // !defined(OS_ANDROID) }; } // namespace media_router
diff --git a/chrome/browser/media/router/media_router_base.cc b/chrome/browser/media/router/media_router_base.cc index e29be4c..f4dfbbb 100644 --- a/chrome/browser/media/router/media_router_base.cc +++ b/chrome/browser/media/router/media_router_base.cc
@@ -9,9 +9,11 @@ #include "base/memory/ptr_util.h" #include "base/stl_util.h" #include "chrome/browser/chrome_notification_types.h" -#include "chrome/browser/media/router/mojo/media_route_controller.h" #include "chrome/browser/profiles/profile.h" #include "content/public/browser/browser_thread.h" +#if !defined(OS_ANDROID) +#include "chrome/browser/media/router/mojo/media_route_controller.h" +#endif // !defined(OS_ANDROID) namespace media_router { @@ -77,10 +79,12 @@ return internal_routes_observer_->current_routes; } +#if !defined(OS_ANDROID) scoped_refptr<MediaRouteController> MediaRouterBase::GetRouteController( const MediaRoute::Id& route_id) { return nullptr; } +#endif // !defined(OS_ANDROID) MediaRouterBase::MediaRouterBase() : initialized_(false) {} @@ -152,8 +156,10 @@ internal_routes_observer_.reset(); } +#if !defined(OS_ANDROID) void MediaRouterBase::DetachRouteController(const MediaRoute::Id& route_id, MediaRouteController* controller) {} +#endif // !defined(OS_ANDROID) void MediaRouterBase::RegisterRemotingSource( int32_t tab_id,
diff --git a/chrome/browser/media/router/media_router_base.h b/chrome/browser/media/router/media_router_base.h index 807ac26..ecbecf5 100644 --- a/chrome/browser/media/router/media_router_base.h +++ b/chrome/browser/media/router/media_router_base.h
@@ -12,6 +12,7 @@ #include "base/callback_list.h" #include "base/gtest_prod_util.h" #include "base/macros.h" +#include "build/build_config.h" #include "chrome/browser/media/router/media_router.h" #include "chrome/browser/media/router/media_routes_observer.h" #include "chrome/common/media_router/media_route.h" @@ -34,8 +35,10 @@ std::vector<MediaRoute> GetCurrentRoutes() const override; +#if !defined(OS_ANDROID) scoped_refptr<MediaRouteController> GetRouteController( const MediaRoute::Id& route_id) override; +#endif // !defined(OS_ANDROID) void RegisterRemotingSource(int32_t tab_id, CastRemotingConnector* remoting_source) override; @@ -100,9 +103,11 @@ // KeyedService void Shutdown() override; +#if !defined(OS_ANDROID) // MediaRouter void DetachRouteController(const MediaRoute::Id& route_id, MediaRouteController* controller) override; +#endif // !defined(OS_ANDROID) std::unique_ptr<InternalMediaRoutesObserver> internal_routes_observer_; bool initialized_;
diff --git a/chrome/browser/media/router/mock_media_router.cc b/chrome/browser/media/router/mock_media_router.cc index 38a8f82d..860bd541 100644 --- a/chrome/browser/media/router/mock_media_router.cc +++ b/chrome/browser/media/router/mock_media_router.cc
@@ -6,6 +6,12 @@ namespace media_router { +// static +std::unique_ptr<KeyedService> MockMediaRouter::Create( + content::BrowserContext* context) { + return base::MakeUnique<MockMediaRouter>(); +} + MockMediaRouter::MockMediaRouter() { }
diff --git a/chrome/browser/media/router/mock_media_router.h b/chrome/browser/media/router/mock_media_router.h index a3d3a9a..8178137 100644 --- a/chrome/browser/media/router/mock_media_router.h +++ b/chrome/browser/media/router/mock_media_router.h
@@ -10,20 +10,31 @@ #include <string> #include <vector> +#include "build/build_config.h" #include "chrome/browser/media/router/media_router_base.h" -#include "chrome/browser/media/router/mojo/media_route_controller.h" #include "chrome/common/media_router/issue.h" #include "chrome/common/media_router/media_route.h" #include "chrome/common/media_router/media_sink.h" #include "chrome/common/media_router/media_source.h" #include "testing/gmock/include/gmock/gmock.h" #include "url/origin.h" +#if !defined(OS_ANDROID) +#include "chrome/browser/media/router/mojo/media_route_controller.h" +#endif // !defined(OS_ANDROID) + +namespace content { +class BrowserContext; +} namespace media_router { // Media Router mock class. Used for testing purposes. class MockMediaRouter : public MediaRouterBase { public: + // This method can be passed into MediaRouterFactory::SetTestingFactory() to + // make the factory return a MockMediaRouter. + static std::unique_ptr<KeyedService> Create(content::BrowserContext* context); + MockMediaRouter(); ~MockMediaRouter() override; @@ -143,9 +154,11 @@ MOCK_CONST_METHOD0(GetCurrentRoutes, std::vector<MediaRoute>()); MOCK_METHOD0(OnIncognitoProfileShutdown, void()); +#if !defined(OS_ANDROID) MOCK_METHOD1( GetRouteController, scoped_refptr<MediaRouteController>(const MediaRoute::Id& route_id)); +#endif // !defined(OS_ANDROID) MOCK_METHOD1(OnAddPresentationConnectionStateChangedCallbackInvoked, void(const content::PresentationConnectionStateChangedCallback& callback)); @@ -162,9 +175,11 @@ void(RouteMessageObserver* observer)); MOCK_METHOD1(UnregisterRouteMessageObserver, void(RouteMessageObserver* observer)); +#if !defined(OS_ANDROID) MOCK_METHOD2(DetachRouteController, void(const MediaRoute::Id& route_id, MediaRouteController* controller)); +#endif // !defined(OS_ANDROID) private: base::CallbackList<void(
diff --git a/chrome/browser/media/router/mojo/media_route_controller.cc b/chrome/browser/media/router/mojo/media_route_controller.cc index f1acacb..51391d6 100644 --- a/chrome/browser/media/router/mojo/media_route_controller.cc +++ b/chrome/browser/media/router/mojo/media_route_controller.cc
@@ -6,7 +6,10 @@ #include <utility> +#include "chrome/browser/media/router/event_page_request_manager.h" +#include "chrome/browser/media/router/event_page_request_manager_factory.h" #include "chrome/browser/media/router/media_router.h" +#include "chrome/browser/media/router/media_router_factory.h" namespace media_router { @@ -28,43 +31,69 @@ void MediaRouteController::Observer::OnControllerInvalidated() {} -MediaRouteController::MediaRouteController( - const MediaRoute::Id& route_id, - mojom::MediaControllerPtr mojo_media_controller, - MediaRouter* media_router) +MediaRouteController::MediaRouteController(const MediaRoute::Id& route_id, + content::BrowserContext* context) : route_id_(route_id), - mojo_media_controller_(std::move(mojo_media_controller)), - media_router_(media_router), - binding_(this) { - DCHECK(mojo_media_controller_.is_bound()); - DCHECK(media_router); - mojo_media_controller_.set_connection_error_handler(base::BindOnce( - &MediaRouteController::OnMojoConnectionError, base::Unretained(this))); + media_router_(MediaRouterFactory::GetApiForBrowserContext(context)), + request_manager_( + EventPageRequestManagerFactory::GetApiForBrowserContext(context)), + binding_(this), + weak_factory_(this) { + DCHECK(media_router_); + DCHECK(request_manager_); } -void MediaRouteController::Play() const { - DCHECK(is_valid_); - mojo_media_controller_->Play(); +void MediaRouteController::Play() { + if (request_manager_->mojo_connections_ready()) { + mojo_media_controller_->Play(); + return; + } + request_manager_->RunOrDefer( + base::BindOnce(&MediaRouteController::Play, weak_factory_.GetWeakPtr()), + MediaRouteProviderWakeReason::ROUTE_CONTROLLER_COMMAND); } -void MediaRouteController::Pause() const { - DCHECK(is_valid_); - mojo_media_controller_->Pause(); +void MediaRouteController::Pause() { + if (request_manager_->mojo_connections_ready()) { + mojo_media_controller_->Pause(); + return; + } + request_manager_->RunOrDefer( + base::BindOnce(&MediaRouteController::Pause, weak_factory_.GetWeakPtr()), + MediaRouteProviderWakeReason::ROUTE_CONTROLLER_COMMAND); } -void MediaRouteController::Seek(base::TimeDelta time) const { - DCHECK(is_valid_); - mojo_media_controller_->Seek(time); +void MediaRouteController::Seek(base::TimeDelta time) { + if (request_manager_->mojo_connections_ready()) { + mojo_media_controller_->Seek(time); + return; + } + request_manager_->RunOrDefer( + base::BindOnce(&MediaRouteController::Seek, weak_factory_.GetWeakPtr(), + time), + MediaRouteProviderWakeReason::ROUTE_CONTROLLER_COMMAND); } -void MediaRouteController::SetMute(bool mute) const { - DCHECK(is_valid_); - mojo_media_controller_->SetMute(mute); +void MediaRouteController::SetMute(bool mute) { + if (request_manager_->mojo_connections_ready()) { + mojo_media_controller_->SetMute(mute); + return; + } + request_manager_->RunOrDefer( + base::BindOnce(&MediaRouteController::SetMute, weak_factory_.GetWeakPtr(), + mute), + MediaRouteProviderWakeReason::ROUTE_CONTROLLER_COMMAND); } -void MediaRouteController::SetVolume(float volume) const { - DCHECK(is_valid_); - mojo_media_controller_->SetVolume(volume); +void MediaRouteController::SetVolume(float volume) { + if (request_manager_->mojo_connections_ready()) { + mojo_media_controller_->SetVolume(volume); + return; + } + request_manager_->RunOrDefer( + base::BindOnce(&MediaRouteController::SetVolume, + weak_factory_.GetWeakPtr(), volume), + MediaRouteProviderWakeReason::ROUTE_CONTROLLER_COMMAND); } void MediaRouteController::OnMediaStatusUpdated(const MediaStatus& status) { @@ -83,9 +112,12 @@ // |this| is deleted here! } +mojom::MediaControllerRequest MediaRouteController::CreateControllerRequest() { + return mojo::MakeRequest(&mojo_media_controller_); +} + mojom::MediaStatusObserverPtr MediaRouteController::BindObserverPtr() { DCHECK(is_valid_); - DCHECK(!binding_.is_bound()); mojom::MediaStatusObserverPtr observer; binding_.Bind(mojo::MakeRequest(&observer)); binding_.set_connection_error_handler(base::BindOnce( @@ -109,8 +141,8 @@ } void MediaRouteController::OnMojoConnectionError() { - media_router_->DetachRouteController(route_id_, this); - Invalidate(); + binding_.Close(); + mojo_media_controller_.reset(); } } // namespace media_router
diff --git a/chrome/browser/media/router/mojo/media_route_controller.h b/chrome/browser/media/router/mojo/media_route_controller.h index cfc65ceb..694d4c8 100644 --- a/chrome/browser/media/router/mojo/media_route_controller.h +++ b/chrome/browser/media/router/mojo/media_route_controller.h
@@ -8,18 +8,26 @@ #include <memory> #include "base/memory/ref_counted.h" +#include "base/memory/weak_ptr.h" #include "base/observer_list.h" #include "chrome/common/media_router/media_route.h" #include "chrome/common/media_router/mojo/media_controller.mojom.h" #include "mojo/public/cpp/bindings/binding.h" +namespace content { +class BrowserContext; +} + namespace media_router { +class EventPageRequestManager; class MediaRouter; -// A controller for a MediaRoute. Forwards commands for controlling the route to -// an out-of-process controller. Notifies its observers whenever there is a -// change in the route's MediaStatus. +// A controller for a MediaRoute. Notifies its observers whenever there is a +// change in the route's MediaStatus. Forwards commands for controlling the +// route to a controller in the Media Router component extension if the +// extension is ready, and queues commands with EventPageRequestManager +// otherwise. // // It is owned by its observers, each of which holds a scoped_refptr to it. All // the classes that hold a scoped_refptr must inherit from the Observer class. @@ -27,10 +35,8 @@ // MediaRouter::GetRouteController(). // // A MediaRouteController instance is destroyed when all its observers dispose -// their references to it. When the Mojo connection with the out-of-process -// controller is terminated or has an error, Invalidate() will be called by the -// MediaRouter or OnMojoConnectionError() to make observers dispose their -// refptrs. +// their references to it. When the associated route is destroyed, Invalidate() +// is called to make the controller's observers dispose their refptrs. class MediaRouteController : public mojom::MediaStatusObserver, public base::RefCounted<MediaRouteController> { public: @@ -72,16 +78,15 @@ // |mojo_media_controller|. |media_router| will be notified when the // MediaRouteController is destroyed via DetachRouteController(). MediaRouteController(const MediaRoute::Id& route_id, - mojom::MediaControllerPtr mojo_media_controller, - MediaRouter* media_router); + content::BrowserContext* context); // Media controller methods for forwarding commands to a // mojom::MediaControllerPtr held in |mojo_media_controller_|. - virtual void Play() const; - virtual void Pause() const; - virtual void Seek(base::TimeDelta time) const; - virtual void SetMute(bool mute) const; - virtual void SetVolume(float volume) const; + virtual void Play(); + virtual void Pause(); + virtual void Seek(base::TimeDelta time); + virtual void SetMute(bool mute); + virtual void SetVolume(float volume); // mojom::MediaStatusObserver: // Notifies |observers_| of a status update. @@ -91,6 +96,11 @@ // controller gets destroyed when all the references are disposed. void Invalidate(); + // Returns an interface request tied to |mojo_media_controller_|, to be bound + // to an implementation. |mojo_media_controller_| gets reset whenever this is + // called. + mojom::MediaControllerRequest CreateControllerRequest(); + // Returns a mojo pointer bound to |this| by |binding_|. This must only be // called at most once in the lifetime of the controller. mojom::MediaStatusObserverPtr BindObserverPtr(); @@ -126,6 +136,10 @@ // |media_router_| will be notified when the controller is destroyed. MediaRouter* const media_router_; + // Request manager responsible for waking the component extension and calling + // the requests to it. + EventPageRequestManager* const request_manager_; + // The binding to observe the out-of-process provider of status updates. mojo::Binding<mojom::MediaStatusObserver> binding_; @@ -139,6 +153,8 @@ // The latest media status that the controller has been notified with. base::Optional<MediaStatus> current_media_status_; + base::WeakPtrFactory<MediaRouteController> weak_factory_; + DISALLOW_COPY_AND_ASSIGN(MediaRouteController); };
diff --git a/chrome/browser/media/router/mojo/media_route_controller_unittest.cc b/chrome/browser/media/router/mojo/media_route_controller_unittest.cc index d11f6bf..57b0fa3 100644 --- a/chrome/browser/media/router/mojo/media_route_controller_unittest.cc +++ b/chrome/browser/media/router/mojo/media_route_controller_unittest.cc
@@ -8,11 +8,15 @@ #include <utility> #include "base/run_loop.h" +#include "chrome/browser/media/router/event_page_request_manager_factory.h" +#include "chrome/browser/media/router/media_router_factory.h" #include "chrome/browser/media/router/mock_media_router.h" #include "chrome/browser/media/router/mojo/media_router_mojo_test.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +using ::testing::_; +using ::testing::Invoke; using ::testing::Mock; using ::testing::StrictMock; @@ -30,16 +34,17 @@ ~MediaRouteControllerTest() override {} void SetUp() override { - mojom::MediaControllerPtr media_controller_ptr; - mojom::MediaControllerRequest media_controller_request = - mojo::MakeRequest(&media_controller_ptr); - mock_media_controller_.Bind(std::move(media_controller_request)); + SetUpMockObjects(); + auto controller = + base::MakeRefCounted<MediaRouteController>(kRouteId, &profile_); + mock_media_controller_.Bind(controller->CreateControllerRequest()); observer_ = base::MakeUnique<MockMediaRouteControllerObserver>( - base::MakeRefCounted<MediaRouteController>( - kRouteId, std::move(media_controller_ptr), &router_)); + std::move(controller)); } + void TearDown() override { observer_.reset(); } + scoped_refptr<MediaRouteController> GetController() const { return observer_->controller(); } @@ -52,19 +57,35 @@ GetController()); } - MockMediaRouter router_; + content::TestBrowserThreadBundle test_thread_bundle_; + TestingProfile profile_; + + MockMediaRouter* router_ = nullptr; + MockEventPageRequestManager* request_manager_ = nullptr; MockMediaController mock_media_controller_; std::unique_ptr<MockMediaRouteControllerObserver> observer_; - content::TestBrowserThreadBundle test_thread_bundle_; - private: + void SetUpMockObjects() { + request_manager_ = static_cast<MockEventPageRequestManager*>( + EventPageRequestManagerFactory::GetInstance()->SetTestingFactoryAndUse( + &profile_, &MockEventPageRequestManager::Create)); + request_manager_->set_mojo_connections_ready_for_test(true); + + router_ = static_cast<MockMediaRouter*>( + MediaRouterFactory::GetInstance()->SetTestingFactoryAndUse( + &profile_, &MockMediaRouter::Create)); + } + DISALLOW_COPY_AND_ASSIGN(MediaRouteControllerTest); }; +// Test that when Mojo connections are ready, calls to the Mojo controller go +// through immediately. TEST_F(MediaRouteControllerTest, ForwardControllerCommands) { const float volume = 0.5; const base::TimeDelta time = base::TimeDelta::FromSeconds(42); + ASSERT_TRUE(request_manager_->mojo_connections_ready()); EXPECT_CALL(mock_media_controller_, Play()); GetController()->Play(); @@ -76,6 +97,49 @@ GetController()->SetVolume(volume); EXPECT_CALL(mock_media_controller_, Seek(time)); GetController()->Seek(time); + + base::RunLoop().RunUntilIdle(); +} + +// Tests that when Mojo connections aren't ready, calls to the Mojo controller +// get queued. +TEST_F(MediaRouteControllerTest, DoNotCallMojoControllerDirectly) { + const float volume = 0.5; + const base::TimeDelta time = base::TimeDelta::FromSeconds(42); + std::vector<base::OnceClosure> requests; + request_manager_->set_mojo_connections_ready_for_test(false); + + EXPECT_CALL(*request_manager_, RunOrDeferInternal(_, _)) + .WillRepeatedly( + testing::WithArg<0>(Invoke([&requests](base::OnceClosure& request) { + requests.push_back(std::move(request)); + }))); + // None of the calls to the Mojo controller should go through yet. + EXPECT_CALL(mock_media_controller_, Play()).Times(0); + EXPECT_CALL(mock_media_controller_, Pause()).Times(0); + EXPECT_CALL(mock_media_controller_, SetMute(true)).Times(0); + EXPECT_CALL(mock_media_controller_, SetVolume(volume)).Times(0); + EXPECT_CALL(mock_media_controller_, Seek(time)).Times(0); + GetController()->Play(); + GetController()->Pause(); + GetController()->SetMute(true); + GetController()->SetVolume(volume); + GetController()->Seek(time); + base::RunLoop().RunUntilIdle(); + testing::Mock::VerifyAndClearExpectations(request_manager_); + testing::Mock::VerifyAndClearExpectations(&mock_media_controller_); + + // Execute all the queued requests. Now the calls to the Mojo controller + // should go through. + request_manager_->set_mojo_connections_ready_for_test(true); + EXPECT_CALL(mock_media_controller_, Play()); + EXPECT_CALL(mock_media_controller_, Pause()); + EXPECT_CALL(mock_media_controller_, SetMute(true)); + EXPECT_CALL(mock_media_controller_, SetVolume(volume)); + EXPECT_CALL(mock_media_controller_, Seek(time)); + for (base::OnceClosure& request : requests) + std::move(request).Run(); + base::RunLoop().RunUntilIdle(); } TEST_F(MediaRouteControllerTest, NotifyMediaRouteControllerObservers) { @@ -104,17 +168,6 @@ base::RunLoop().RunUntilIdle(); } -TEST_F(MediaRouteControllerTest, DestroyControllerOnDisconnect) { - // DetachRouteController() should be called when the connection to - // |mock_media_controller_| is invalidated. - EXPECT_CALL(router_, DetachRouteController(kRouteId, GetController().get())) - .Times(1); - mock_media_controller_.CloseBinding(); - - base::RunLoop().RunUntilIdle(); - EXPECT_TRUE(Mock::VerifyAndClearExpectations(&router_)); -} - TEST_F(MediaRouteControllerTest, DestroyControllerOnNoObservers) { auto observer1 = CreateObserver(); auto observer2 = CreateObserver(); @@ -123,14 +176,14 @@ // Get rid of |observer_| and its reference to the controller. observer_.reset(); - EXPECT_CALL(router_, DetachRouteController(kRouteId, controller)).Times(0); + EXPECT_CALL(*router_, DetachRouteController(kRouteId, controller)).Times(0); observer1.reset(); // DetachRouteController() should be called when the controller no longer // has any observers. - EXPECT_CALL(router_, DetachRouteController(kRouteId, controller)).Times(1); + EXPECT_CALL(*router_, DetachRouteController(kRouteId, controller)).Times(1); observer2.reset(); - EXPECT_TRUE(Mock::VerifyAndClearExpectations(&router_)); + EXPECT_TRUE(Mock::VerifyAndClearExpectations(router_)); } } // namespace media_router
diff --git a/chrome/browser/media/router/mojo/media_router_desktop.cc b/chrome/browser/media/router/mojo/media_router_desktop.cc index 82c73b7..72959d7 100644 --- a/chrome/browser/media/router/mojo/media_router_desktop.cc +++ b/chrome/browser/media/router/mojo/media_router_desktop.cc
@@ -7,6 +7,7 @@ #include "chrome/browser/media/router/event_page_request_manager.h" #include "chrome/browser/media/router/event_page_request_manager_factory.h" #include "chrome/browser/media/router/media_router_factory.h" +#include "chrome/browser/media/router/mojo/media_route_controller.h" #include "chrome/common/media_router/media_source_helper.h" #include "extensions/common/extension.h" #if defined(OS_WIN) @@ -354,6 +355,16 @@ // ExecutePendingRequests(). is_mdns_enabled_ = false; #endif + // Now that we have a Mojo pointer to the MRP, we request MRP-side route + // controllers to be created again. This must happen before |request_manager_| + // executes requests to the MRP and its route controllers. + for (const auto& pair : route_controllers_) { + const MediaRoute::Id& route_id = pair.first; + MediaRouteController* route_controller = pair.second; + MediaRouterMojoImpl::DoCreateMediaRouteController( + route_id, route_controller->CreateControllerRequest(), + route_controller->BindObserverPtr()); + } request_manager_->OnMojoConnectionsReady(); }
diff --git a/chrome/browser/media/router/mojo/media_router_desktop_unittest.cc b/chrome/browser/media/router/mojo/media_router_desktop_unittest.cc index fe3e2ee4..4c5bdd1 100644 --- a/chrome/browser/media/router/mojo/media_router_desktop_unittest.cc +++ b/chrome/browser/media/router/mojo/media_router_desktop_unittest.cc
@@ -14,6 +14,7 @@ #include "build/build_config.h" #include "chrome/browser/media/router/event_page_request_manager.h" #include "chrome/browser/media/router/event_page_request_manager_factory.h" +#include "chrome/browser/media/router/media_router_factory.h" #include "chrome/browser/media/router/mojo/media_router_mojo_test.h" #include "chrome/common/media_router/media_source_helper.h" #include "testing/gmock/include/gmock/gmock.h" @@ -42,58 +43,27 @@ final {} }; -class TestEventPageRequestManager : public EventPageRequestManager { - public: - static std::unique_ptr<KeyedService> Create( - content::BrowserContext* context) { - return base::MakeUnique<TestEventPageRequestManager>(context); - } - explicit TestEventPageRequestManager(content::BrowserContext* context) - : EventPageRequestManager(context) {} - ~TestEventPageRequestManager() = default; - - MOCK_METHOD1(SetExtensionId, void(const std::string& extension_id)); - void RunOrDefer(base::OnceClosure request, - MediaRouteProviderWakeReason wake_reason) override { - RunOrDeferInternal(request, wake_reason); - } - MOCK_METHOD2(RunOrDeferInternal, - void(base::OnceClosure& request, - MediaRouteProviderWakeReason wake_reason)); - MOCK_METHOD0(OnMojoConnectionsReady, void()); - MOCK_METHOD0(OnMojoConnectionError, void()); - - private: - DISALLOW_COPY_AND_ASSIGN(TestEventPageRequestManager); -}; } // namespace class MediaRouterDesktopTest : public MediaRouterMojoTest { public: - MediaRouterDesktopTest() { - EventPageRequestManagerFactory::GetInstance()->SetTestingFactory( - profile(), &TestEventPageRequestManager::Create); - request_manager_ = static_cast<TestEventPageRequestManager*>( - EventPageRequestManagerFactory::GetApiForBrowserContext(profile())); - request_manager_->set_mojo_connections_ready_for_test(true); - ON_CALL(*request_manager_, RunOrDeferInternal(_, _)) - .WillByDefault(Invoke([](base::OnceClosure& request, - MediaRouteProviderWakeReason wake_reason) { - std::move(request).Run(); - })); - } - + MediaRouterDesktopTest() {} ~MediaRouterDesktopTest() override {} protected: - std::unique_ptr<MediaRouterMojoImpl> CreateMediaRouter() override { - return std::unique_ptr<MediaRouterMojoImpl>( - new MediaRouterDesktop(profile())); + MediaRouterMojoImpl* SetTestingFactoryAndUse() override { + return static_cast<MediaRouterMojoImpl*>( + MediaRouterFactory::GetInstance()->SetTestingFactoryAndUse( + profile(), &CreateMediaRouter)); } - TestEventPageRequestManager* request_manager_ = nullptr; + private: + static std::unique_ptr<KeyedService> CreateMediaRouter( + content::BrowserContext* context) { + return std::unique_ptr<KeyedService>(new MediaRouterDesktop(context)); + } }; TEST_F(MediaRouterDesktopTest, CreateRoute) {
diff --git a/chrome/browser/media/router/mojo/media_router_mojo_impl.cc b/chrome/browser/media/router/mojo/media_router_mojo_impl.cc index ad801f3..bb23bae 100644 --- a/chrome/browser/media/router/mojo/media_router_mojo_impl.cc +++ b/chrome/browser/media/router/mojo/media_router_mojo_impl.cc
@@ -319,15 +319,11 @@ if (it != route_controllers_.end()) return scoped_refptr<MediaRouteController>(it->second); - mojom::MediaControllerPtr mojo_media_controller; - mojom::MediaControllerRequest mojo_media_controller_request = - mojo::MakeRequest(&mojo_media_controller); scoped_refptr<MediaRouteController> route_controller = - new MediaRouteController(route_id, std::move(mojo_media_controller), - this); + new MediaRouteController(route_id, context_); DoCreateMediaRouteController(route_id, - std::move(mojo_media_controller_request), + route_controller->CreateControllerRequest(), route_controller->BindObserverPtr()); route_controllers_.emplace(route_id, route_controller.get()); return route_controller;
diff --git a/chrome/browser/media/router/mojo/media_router_mojo_impl.h b/chrome/browser/media/router/mojo/media_router_mojo_impl.h index 9d2bfa0..0af9b77 100644 --- a/chrome/browser/media/router/mojo/media_router_mojo_impl.h +++ b/chrome/browser/media/router/mojo/media_router_mojo_impl.h
@@ -175,6 +175,9 @@ // if or a Mojo channel error occured. mojom::MediaRouteProviderPtr media_route_provider_; + // Stores route controllers that can be used to send media commands. + std::unordered_map<MediaRoute::Id, MediaRouteController*> route_controllers_; + private: friend class MediaRouterFactory; friend class MediaRouterMojoImplTest; @@ -342,10 +345,6 @@ // The last reported sink availability from the media route provider manager. mojom::MediaRouter::SinkAvailability availability_; - // Stores route controllers that can be used to send media commands to the - // extension. - std::unordered_map<MediaRoute::Id, MediaRouteController*> route_controllers_; - // Media sink service for DIAL devices. scoped_refptr<DialMediaSinkServiceProxy> dial_media_sink_service_proxy_;
diff --git a/chrome/browser/media/router/mojo/media_router_mojo_impl_unittest.cc b/chrome/browser/media/router/mojo/media_router_mojo_impl_unittest.cc index fe99aad..82b9255a9a5 100644 --- a/chrome/browser/media/router/mojo/media_router_mojo_impl_unittest.cc +++ b/chrome/browser/media/router/mojo/media_router_mojo_impl_unittest.cc
@@ -20,6 +20,7 @@ #include "base/threading/thread_task_runner_handle.h" #include "chrome/browser/media/router/event_page_request_manager.h" #include "chrome/browser/media/router/event_page_request_manager_factory.h" +#include "chrome/browser/media/router/media_router_factory.h" #include "chrome/browser/media/router/mock_media_router.h" #include "chrome/browser/media/router/mojo/media_router_mojo_metrics.h" #include "chrome/browser/media/router/mojo/media_router_mojo_test.h" @@ -138,12 +139,18 @@ expected_count); } - std::unique_ptr<MediaRouterMojoImpl> CreateMediaRouter() override { - return std::unique_ptr<MediaRouterMojoImpl>( - new MediaRouterMojoImpl(profile())); + MediaRouterMojoImpl* SetTestingFactoryAndUse() override { + return static_cast<MediaRouterMojoImpl*>( + MediaRouterFactory::GetInstance()->SetTestingFactoryAndUse( + profile(), &CreateMediaRouter)); } private: + static std::unique_ptr<KeyedService> CreateMediaRouter( + content::BrowserContext* context) { + return std::unique_ptr<KeyedService>(new MediaRouterMojoImpl(context)); + } + base::HistogramTester histogram_tester_; }; @@ -1064,24 +1071,4 @@ base::RunLoop().RunUntilIdle(); } -TEST_F(MediaRouterMojoImplTest, FailToCreateRouteController) { - router()->OnRoutesUpdated({CreateMediaRoute()}, std::string(), - std::vector<std::string>()); - - EXPECT_CALL(mock_media_route_provider_, - CreateMediaRouteControllerInternal(kRouteId, _, _, _)) - .WillOnce(Invoke( - [](Unused, Unused, Unused, - mojom::MediaRouteProvider::CreateMediaRouteControllerCallback& - cb) { std::move(cb).Run(false); })); - MockMediaRouteControllerObserver observer( - router()->GetRouteController(kRouteId)); - - // When the MediaRouter is notified that the MediaRouteProvider failed to - // create a controller, the browser-side controller should be invalidated. - EXPECT_CALL(observer, OnControllerInvalidated()); - - base::RunLoop().RunUntilIdle(); -} - } // namespace media_router
diff --git a/chrome/browser/media/router/mojo/media_router_mojo_metrics.h b/chrome/browser/media/router/mojo/media_router_mojo_metrics.h index 481640b..ae109f8 100644 --- a/chrome/browser/media/router/mojo/media_router_mojo_metrics.h +++ b/chrome/browser/media/router/mojo/media_router_mojo_metrics.h
@@ -21,7 +21,7 @@ // NOTE: Do not renumber enums as that would confuse interpretation of // previously logged data. When making changes, also update the enum lists -// in tools/metrics/histograms/histograms.xml to keep it in sync. +// in tools/metrics/histograms/enums.xml to keep it in sync. // Why the Media Route Provider process was woken up. enum class MediaRouteProviderWakeReason { @@ -45,9 +45,10 @@ SEARCH_SINKS = 17, PROVIDE_SINKS = 18, CREATE_MEDIA_ROUTE_CONTROLLER = 19, + ROUTE_CONTROLLER_COMMAND = 20, // NOTE: Add entries only immediately above this line. - TOTAL_COUNT = 20 + TOTAL_COUNT = 21 }; // The install status of the Media Router component extension.
diff --git a/chrome/browser/media/router/mojo/media_router_mojo_test.cc b/chrome/browser/media/router/mojo/media_router_mojo_test.cc index dbf72e6..a574d63 100644 --- a/chrome/browser/media/router/mojo/media_router_mojo_test.cc +++ b/chrome/browser/media/router/mojo/media_router_mojo_test.cc
@@ -7,6 +7,7 @@ #include <utility> #include "base/run_loop.h" +#include "chrome/browser/media/router/event_page_request_manager_factory.h" #include "extensions/common/test_util.h" using testing::_; @@ -71,6 +72,24 @@ MockEventPageTracker::~MockEventPageTracker() {} +// static +std::unique_ptr<KeyedService> MockEventPageRequestManager::Create( + content::BrowserContext* context) { + return base::MakeUnique<MockEventPageRequestManager>(context); +} + +MockEventPageRequestManager::MockEventPageRequestManager( + content::BrowserContext* context) + : EventPageRequestManager(context) {} + +MockEventPageRequestManager::~MockEventPageRequestManager() = default; + +void MockEventPageRequestManager::RunOrDefer( + base::OnceClosure request, + MediaRouteProviderWakeReason wake_reason) { + RunOrDeferInternal(request, wake_reason); +} + MockMediaController::MockMediaController() : binding_(this) {} MockMediaController::~MockMediaController() {} @@ -95,11 +114,8 @@ MockMediaRouteController::MockMediaRouteController( const MediaRoute::Id& route_id, - mojom::MediaControllerPtr mojo_media_controller, - MediaRouter* media_router) - : MediaRouteController(route_id, - std::move(mojo_media_controller), - media_router) {} + content::BrowserContext* context) + : MediaRouteController(route_id, context) {} MockMediaRouteController::~MockMediaRouteController() {} @@ -109,7 +125,17 @@ MockMediaRouteControllerObserver::~MockMediaRouteControllerObserver() {} -MediaRouterMojoTest::MediaRouterMojoTest() {} +MediaRouterMojoTest::MediaRouterMojoTest() { + request_manager_ = static_cast<MockEventPageRequestManager*>( + EventPageRequestManagerFactory::GetInstance()->SetTestingFactoryAndUse( + profile(), &MockEventPageRequestManager::Create)); + request_manager_->set_mojo_connections_ready_for_test(true); + ON_CALL(*request_manager_, RunOrDeferInternal(_, _)) + .WillByDefault(Invoke([](base::OnceClosure& request, + MediaRouteProviderWakeReason wake_reason) { + std::move(request).Run(); + })); +} MediaRouterMojoTest::~MediaRouterMojoTest() {} @@ -125,7 +151,7 @@ } void MediaRouterMojoTest::SetUp() { - media_router_ = CreateMediaRouter(); + media_router_ = SetTestingFactoryAndUse(); media_router_->set_instance_id_for_test(kInstanceId); ConnectProviderManagerService(); media_router_->Initialize(); @@ -135,7 +161,6 @@ void MediaRouterMojoTest::TearDown() { media_router_->Shutdown(); - media_router_.reset(); } void MediaRouterMojoTest::ProcessEventLoop() { @@ -342,7 +367,9 @@ std::vector<MediaSinkInternal> sinks; MediaSink sink(kSinkId, kSinkName, SinkIconType::CAST); CastSinkExtraData extra_data; - EXPECT_TRUE(extra_data.ip_address.AssignFromIPLiteral("192.168.1.3")); + net::IPAddress ip_address; + EXPECT_TRUE(ip_address.AssignFromIPLiteral("192.168.1.3")); + extra_data.ip_endpoint = net::IPEndPoint(ip_address, 0); extra_data.capabilities = 2; extra_data.cast_channel_id = 3; MediaSinkInternal expected_sink(sink, extra_data);
diff --git a/chrome/browser/media/router/mojo/media_router_mojo_test.h b/chrome/browser/media/router/mojo/media_router_mojo_test.h index c0409692..a552fe4 100644 --- a/chrome/browser/media/router/mojo/media_router_mojo_test.h +++ b/chrome/browser/media/router/mojo/media_router_mojo_test.h
@@ -9,6 +9,7 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" +#include "chrome/browser/media/router/event_page_request_manager.h" #include "chrome/browser/media/router/mock_media_router.h" #include "chrome/browser/media/router/mojo/media_router_mojo_impl.h" #include "chrome/browser/media/router/test_helper.h" @@ -168,6 +169,26 @@ const base::Callback<void(bool)>& callback)); }; +class MockEventPageRequestManager : public EventPageRequestManager { + public: + static std::unique_ptr<KeyedService> Create(content::BrowserContext* context); + + explicit MockEventPageRequestManager(content::BrowserContext* context); + ~MockEventPageRequestManager(); + + MOCK_METHOD1(SetExtensionId, void(const std::string& extension_id)); + void RunOrDefer(base::OnceClosure request, + MediaRouteProviderWakeReason wake_reason) override; + MOCK_METHOD2(RunOrDeferInternal, + void(base::OnceClosure& request, + MediaRouteProviderWakeReason wake_reason)); + MOCK_METHOD0(OnMojoConnectionsReady, void()); + MOCK_METHOD0(OnMojoConnectionError, void()); + + private: + DISALLOW_COPY_AND_ASSIGN(MockEventPageRequestManager); +}; + class MockMediaController : public mojom::MediaController { public: MockMediaController(); @@ -190,14 +211,13 @@ class MockMediaRouteController : public MediaRouteController { public: MockMediaRouteController(const MediaRoute::Id& route_id, - mojom::MediaControllerPtr mojo_media_controller, - MediaRouter* media_router); + content::BrowserContext* context); - MOCK_CONST_METHOD0(Play, void()); - MOCK_CONST_METHOD0(Pause, void()); - MOCK_CONST_METHOD1(Seek, void(base::TimeDelta time)); - MOCK_CONST_METHOD1(SetMute, void(bool mute)); - MOCK_CONST_METHOD1(SetVolume, void(float volume)); + MOCK_METHOD0(Play, void()); + MOCK_METHOD0(Pause, void()); + MOCK_METHOD1(Seek, void(base::TimeDelta time)); + MOCK_METHOD1(SetMute, void(bool mute)); + MOCK_METHOD1(SetVolume, void(float volume)); protected: // The dtor is protected because MockMediaRouteController is ref-counted. @@ -242,8 +262,9 @@ void SetUp() override; void TearDown() override; - // Create a MediaRouter instance to test. - virtual std::unique_ptr<MediaRouterMojoImpl> CreateMediaRouter() = 0; + // Set the MediaRouter instance to be used by the MediaRouterFactory and + // return it. + virtual MediaRouterMojoImpl* SetTestingFactoryAndUse() = 0; void ProcessEventLoop(); @@ -264,12 +285,13 @@ const std::string& extension_id() const { return extension_->id(); } - MediaRouterMojoImpl* router() const { return media_router_.get(); } + MediaRouterMojoImpl* router() const { return media_router_; } Profile* profile() { return &profile_; } // Mock objects. MockMediaRouteProvider mock_media_route_provider_; + MockEventPageRequestManager* request_manager_ = nullptr; RegisterMediaRouteProviderHandler provide_handler_; @@ -277,7 +299,7 @@ content::TestBrowserThreadBundle test_thread_bundle_; scoped_refptr<extensions::Extension> extension_; TestingProfile profile_; - std::unique_ptr<MediaRouterMojoImpl> media_router_; + MediaRouterMojoImpl* media_router_ = nullptr; std::unique_ptr<mojo::Binding<mojom::MediaRouteProvider>> binding_; DISALLOW_COPY_AND_ASSIGN(MediaRouterMojoTest);
diff --git a/chrome/browser/media/router/test_helper.h b/chrome/browser/media/router/test_helper.h index 0b1825d..d87d35b7 100644 --- a/chrome/browser/media/router/test_helper.h +++ b/chrome/browser/media/router/test_helper.h
@@ -83,7 +83,7 @@ }; class MockPresentationConnectionProxy - : public NON_EXPORTED_BASE(blink::mojom::PresentationConnection) { + : public blink::mojom::PresentationConnection { public: // PresentationConnectionMessage is move-only. // TODO(crbug.com/729950): Use MOCK_METHOD directly once GMock gets the
diff --git a/chrome/browser/media_galleries/fileapi/mtp_file_stream_reader.h b/chrome/browser/media_galleries/fileapi/mtp_file_stream_reader.h index da3f8c5..9992c66 100644 --- a/chrome/browser/media_galleries/fileapi/mtp_file_stream_reader.h +++ b/chrome/browser/media_galleries/fileapi/mtp_file_stream_reader.h
@@ -20,8 +20,7 @@ class FileSystemContext; } -class MTPFileStreamReader - : public NON_EXPORTED_BASE(storage::FileStreamReader) { +class MTPFileStreamReader : public storage::FileStreamReader { public: MTPFileStreamReader(storage::FileSystemContext* file_system_context, const storage::FileSystemURL& url,
diff --git a/chrome/browser/media_galleries/fileapi/readahead_file_stream_reader.h b/chrome/browser/media_galleries/fileapi/readahead_file_stream_reader.h index 5ddf1a2..57b4cf6 100644 --- a/chrome/browser/media_galleries/fileapi/readahead_file_stream_reader.h +++ b/chrome/browser/media_galleries/fileapi/readahead_file_stream_reader.h
@@ -15,8 +15,7 @@ #include "storage/browser/fileapi/file_stream_reader.h" // Wraps a source FileStreamReader with a readahead buffer. -class ReadaheadFileStreamReader - : public NON_EXPORTED_BASE(storage::FileStreamReader) { +class ReadaheadFileStreamReader : public storage::FileStreamReader { public: // Takes ownership of |source|. explicit ReadaheadFileStreamReader(storage::FileStreamReader* source);
diff --git a/chrome/browser/metrics/perf/perf_provider_chromeos_unittest.cc b/chrome/browser/metrics/perf/perf_provider_chromeos_unittest.cc index c8e0c02..43e6cc3 100644 --- a/chrome/browser/metrics/perf/perf_provider_chromeos_unittest.cc +++ b/chrome/browser/metrics/perf/perf_provider_chromeos_unittest.cc
@@ -91,17 +91,17 @@ PerfStatProto_PerfStatLine* line1 = proto.add_line(); line1->set_time_ms(1000); line1->set_count(2000); - line1->set_event("cycles"); + line1->set_event_name("cycles"); PerfStatProto_PerfStatLine* line2 = proto.add_line(); line2->set_time_ms(2000); line2->set_count(5678); - line2->set_event("instructions"); + line2->set_event_name("instructions"); PerfStatProto_PerfStatLine* line3 = proto.add_line(); line3->set_time_ms(3000); line3->set_count(9999); - line3->set_event("branches"); + line3->set_event_name("branches"); return proto; }
diff --git a/chrome/browser/metrics/process_memory_metrics_emitter.cc b/chrome/browser/metrics/process_memory_metrics_emitter.cc index 8911295..36ac31d 100644 --- a/chrome/browser/metrics/process_memory_metrics_emitter.cc +++ b/chrome/browser/metrics/process_memory_metrics_emitter.cc
@@ -8,7 +8,7 @@ #include "base/trace_event/memory_dump_request_args.h" #include "content/public/common/service_manager_connection.h" #include "content/public/common/service_names.mojom.h" -#include "services/metrics/public/cpp/ukm_entry_builder.h" +#include "services/metrics/public/cpp/ukm_builders.h" #include "services/metrics/public/cpp/ukm_recorder.h" #include "services/resource_coordinator/public/cpp/resource_coordinator_features.h" #include "services/resource_coordinator/public/interfaces/service_constants.mojom.h" @@ -20,102 +20,94 @@ namespace { -void TryAddMetric(ukm::UkmEntryBuilder* builder, - const char* metric_name, - int64_t value) { - // Builder might be null if it was created before the UKMService was started. - // In that case, just no-op. - if (builder) - builder->AddMetric(metric_name, value); -} - void EmitBrowserMemoryMetrics(const ProcessMemoryDumpPtr& pmd, - ukm::UkmEntryBuilder* builder) { - TryAddMetric(builder, "ProcessType", - static_cast<int64_t>( - memory_instrumentation::mojom::ProcessType::BROWSER)); + ukm::SourceId ukm_source_id, + ukm::UkmRecorder* ukm_recorder) { + ukm::builders::Memory_Experimental builder(ukm_source_id); + builder.SetProcessType(static_cast<int64_t>( + memory_instrumentation::mojom::ProcessType::BROWSER)); UMA_HISTOGRAM_MEMORY_LARGE_MB("Memory.Experimental.Browser2.Resident", pmd->os_dump->resident_set_kb / 1024); - TryAddMetric(builder, "Resident", pmd->os_dump->resident_set_kb / 1024); + builder.SetResident(pmd->os_dump->resident_set_kb / 1024); UMA_HISTOGRAM_MEMORY_LARGE_MB("Memory.Experimental.Browser2.Malloc", pmd->chrome_dump->malloc_total_kb / 1024); - TryAddMetric(builder, "Malloc", pmd->chrome_dump->malloc_total_kb / 1024); + builder.SetMalloc(pmd->chrome_dump->malloc_total_kb / 1024); UMA_HISTOGRAM_MEMORY_LARGE_MB( "Memory.Experimental.Browser2.PrivateMemoryFootprint", pmd->os_dump->private_footprint_kb / 1024); UMA_HISTOGRAM_MEMORY_LARGE_MB("Memory.Browser.PrivateMemoryFootprint", pmd->os_dump->private_footprint_kb / 1024); - TryAddMetric(builder, "PrivateMemoryFootprint", - pmd->os_dump->private_footprint_kb / 1024); + builder.SetPrivateMemoryFootprint(pmd->os_dump->private_footprint_kb / 1024); + builder.Record(ukm_recorder); } void EmitRendererMemoryMetrics(const ProcessMemoryDumpPtr& pmd, - ukm::UkmEntryBuilder* builder) { - TryAddMetric(builder, "ProcessType", - static_cast<int64_t>( - memory_instrumentation::mojom::ProcessType::RENDERER)); + ukm::SourceId ukm_source_id, + ukm::UkmRecorder* ukm_recorder) { + ukm::builders::Memory_Experimental builder(ukm_source_id); + builder.SetProcessType(static_cast<int64_t>( + memory_instrumentation::mojom::ProcessType::RENDERER)); UMA_HISTOGRAM_MEMORY_LARGE_MB("Memory.Experimental.Renderer2.Resident", pmd->os_dump->resident_set_kb / 1024); - TryAddMetric(builder, "Resident", pmd->os_dump->resident_set_kb / 1024); + builder.SetResident(pmd->os_dump->resident_set_kb / 1024); UMA_HISTOGRAM_MEMORY_LARGE_MB("Memory.Experimental.Renderer2.Malloc", pmd->chrome_dump->malloc_total_kb / 1024); - TryAddMetric(builder, "Malloc", pmd->chrome_dump->malloc_total_kb / 1024); + builder.SetMalloc(pmd->chrome_dump->malloc_total_kb / 1024); UMA_HISTOGRAM_MEMORY_LARGE_MB( "Memory.Experimental.Renderer2.PrivateMemoryFootprint", pmd->os_dump->private_footprint_kb / 1024); UMA_HISTOGRAM_MEMORY_LARGE_MB("Memory.Renderer.PrivateMemoryFootprint", pmd->os_dump->private_footprint_kb / 1024); - TryAddMetric(builder, "PrivateMemoryFootprint", - pmd->os_dump->private_footprint_kb / 1024); + builder.SetPrivateMemoryFootprint(pmd->os_dump->private_footprint_kb / 1024); UMA_HISTOGRAM_MEMORY_LARGE_MB( "Memory.Experimental.Renderer2.PartitionAlloc", pmd->chrome_dump->partition_alloc_total_kb / 1024); - TryAddMetric(builder, "PartitionAlloc", - pmd->chrome_dump->partition_alloc_total_kb / 1024); + builder.SetPartitionAlloc(pmd->chrome_dump->partition_alloc_total_kb / 1024); UMA_HISTOGRAM_MEMORY_LARGE_MB("Memory.Experimental.Renderer2.BlinkGC", pmd->chrome_dump->blink_gc_total_kb / 1024); - TryAddMetric(builder, "BlinkGC", pmd->chrome_dump->blink_gc_total_kb / 1024); + builder.SetBlinkGC(pmd->chrome_dump->blink_gc_total_kb / 1024); UMA_HISTOGRAM_MEMORY_LARGE_MB("Memory.Experimental.Renderer2.V8", pmd->chrome_dump->v8_total_kb / 1024); - TryAddMetric(builder, "V8", pmd->chrome_dump->v8_total_kb / 1024); + builder.SetV8(pmd->chrome_dump->v8_total_kb / 1024); + builder.Record(ukm_recorder); } void EmitGpuMemoryMetrics(const ProcessMemoryDumpPtr& pmd, - ukm::UkmEntryBuilder* builder) { - TryAddMetric( - builder, "ProcessType", + ukm::SourceId ukm_source_id, + ukm::UkmRecorder* ukm_recorder) { + ukm::builders::Memory_Experimental builder(ukm_source_id); + builder.SetProcessType( static_cast<int64_t>(memory_instrumentation::mojom::ProcessType::GPU)); UMA_HISTOGRAM_MEMORY_LARGE_MB("Memory.Experimental.Gpu2.Resident", pmd->os_dump->resident_set_kb / 1024); - TryAddMetric(builder, "Resident", pmd->os_dump->resident_set_kb / 1024); + builder.SetResident(pmd->os_dump->resident_set_kb / 1024); UMA_HISTOGRAM_MEMORY_LARGE_MB("Memory.Experimental.Gpu2.Malloc", pmd->chrome_dump->malloc_total_kb / 1024); - TryAddMetric(builder, "Malloc", pmd->chrome_dump->malloc_total_kb / 1024); + builder.SetMalloc(pmd->chrome_dump->malloc_total_kb / 1024); UMA_HISTOGRAM_MEMORY_LARGE_MB( "Memory.Experimental.Gpu2.CommandBuffer", pmd->chrome_dump->command_buffer_total_kb / 1024); - TryAddMetric(builder, "CommandBuffer", - pmd->chrome_dump->command_buffer_total_kb / 1024); + builder.SetCommandBuffer(pmd->chrome_dump->command_buffer_total_kb / 1024); UMA_HISTOGRAM_MEMORY_LARGE_MB( "Memory.Experimental.Gpu2.PrivateMemoryFootprint", pmd->os_dump->private_footprint_kb / 1024); UMA_HISTOGRAM_MEMORY_LARGE_MB("Memory.Gpu.PrivateMemoryFootprint", pmd->os_dump->private_footprint_kb / 1024); - TryAddMetric(builder, "PrivateMemoryFootprint", - pmd->os_dump->private_footprint_kb / 1024); + builder.SetPrivateMemoryFootprint(pmd->os_dump->private_footprint_kb / 1024); + builder.Record(ukm_recorder); } } // namespace @@ -157,16 +149,6 @@ ProcessMemoryMetricsEmitter::~ProcessMemoryMetricsEmitter() {} -std::unique_ptr<ukm::UkmEntryBuilder> -ProcessMemoryMetricsEmitter::CreateUkmBuilder(int64_t ukm_source_id) { - static const char event_name[] = "Memory.Experimental"; - ukm::UkmRecorder* ukm_recorder = GetUkmRecorder(); - if (!ukm_recorder) - return nullptr; - - return ukm_recorder->GetEntryBuilder(ukm_source_id, event_name); -} - void ProcessMemoryMetricsEmitter::ReceivedMemoryDump( bool success, uint64_t dump_guid, @@ -213,9 +195,8 @@ switch (pmd->process_type) { case memory_instrumentation::mojom::ProcessType::BROWSER: { - std::unique_ptr<ukm::UkmEntryBuilder> builder = - CreateUkmBuilder(ukm::UkmRecorder::GetNewSourceID()); - EmitBrowserMemoryMetrics(pmd, builder.get()); + EmitBrowserMemoryMetrics(pmd, ukm::UkmRecorder::GetNewSourceID(), + GetUkmRecorder()); break; } case memory_instrumentation::mojom::ProcessType::RENDERER: { @@ -230,15 +211,12 @@ ukm_source_id = process_info->ukm_source_ids[0]; } } - std::unique_ptr<ukm::UkmEntryBuilder> builder = - CreateUkmBuilder(ukm_source_id); - EmitRendererMemoryMetrics(pmd, builder.get()); + EmitRendererMemoryMetrics(pmd, ukm_source_id, GetUkmRecorder()); break; } case memory_instrumentation::mojom::ProcessType::GPU: { - std::unique_ptr<ukm::UkmEntryBuilder> builder = - CreateUkmBuilder(ukm::UkmRecorder::GetNewSourceID()); - EmitGpuMemoryMetrics(pmd, builder.get()); + EmitGpuMemoryMetrics(pmd, ukm::UkmRecorder::GetNewSourceID(), + GetUkmRecorder()); break; } case memory_instrumentation::mojom::ProcessType::UTILITY: @@ -253,8 +231,7 @@ UMA_HISTOGRAM_MEMORY_LARGE_MB("Memory.Total.PrivateMemoryFootprint", private_footprint_total_kb / 1024); - std::unique_ptr<ukm::UkmEntryBuilder> builder = - CreateUkmBuilder(ukm::UkmRecorder::GetNewSourceID()); - TryAddMetric(builder.get(), "Total2.PrivateMemoryFootprint", - private_footprint_total_kb / 1024); + ukm::builders::Memory_Experimental(ukm::UkmRecorder::GetNewSourceID()) + .SetTotal2_PrivateMemoryFootprint(private_footprint_total_kb / 1024) + .Record(GetUkmRecorder()); }
diff --git a/chrome/browser/metrics/process_memory_metrics_emitter.h b/chrome/browser/metrics/process_memory_metrics_emitter.h index c3ad6ad..649bcb21 100644 --- a/chrome/browser/metrics/process_memory_metrics_emitter.h +++ b/chrome/browser/metrics/process_memory_metrics_emitter.h
@@ -13,7 +13,6 @@ #include "services/resource_coordinator/public/interfaces/memory_instrumentation/memory_instrumentation.mojom.h" namespace ukm { -class UkmEntryBuilder; class UkmRecorder; } @@ -59,9 +58,6 @@ private: friend class base::RefCountedThreadSafe<ProcessMemoryMetricsEmitter>; - // The builder always has the same event name: "Memory.Experimental". - std::unique_ptr<ukm::UkmEntryBuilder> CreateUkmBuilder(int64_t ukm_source_id); - // This class sends two asynchronous service requests, whose results need to // be collated. void CollateResults();
diff --git a/chrome/browser/metrics/process_memory_metrics_emitter_browsertest.cc b/chrome/browser/metrics/process_memory_metrics_emitter_browsertest.cc index 8c1226c0..b728b79 100644 --- a/chrome/browser/metrics/process_memory_metrics_emitter_browsertest.cc +++ b/chrome/browser/metrics/process_memory_metrics_emitter_browsertest.cc
@@ -14,6 +14,7 @@ #include "chrome/test/base/tracing.h" #include "chrome/test/base/ui_test_utils.h" #include "components/ukm/test_ukm_recorder.h" +#include "content/public/common/content_switches.h" #include "content/public/test/test_utils.h" #include "services/resource_coordinator/public/cpp/memory_instrumentation/memory_instrumentation.h" #include "url/gurl.h" @@ -153,6 +154,12 @@ test_ukm_recorder_ = base::MakeUnique<ukm::TestAutoSetUkmRecorder>(); } + void SetUpCommandLine(base::CommandLine* command_line) override { + InProcessBrowserTest::SetUpCommandLine(command_line); + command_line->AppendSwitchASCII(switches::kEnableFeatures, + ukm::kUkmFeature.name); + } + protected: std::unique_ptr<ukm::TestAutoSetUkmRecorder> test_ukm_recorder_;
diff --git a/chrome/browser/notifications/arc_application_notifier_source_chromeos.cc b/chrome/browser/notifications/arc_application_notifier_source_chromeos.cc index 1612958..3a50796 100644 --- a/chrome/browser/notifications/arc_application_notifier_source_chromeos.cc +++ b/chrome/browser/notifications/arc_application_notifier_source_chromeos.cc
@@ -61,10 +61,6 @@ kArcAppIconSizeInDp, // The life time of icon must shorter than |this|. this)); - icon->image_skia().GetRepresentation( - ui::GetSupportedScaleFactor(display::Screen::GetScreen() - ->GetPrimaryDisplay() - .device_scale_factor())); // Apply icon now to set the default image. OnIconUpdated(icon.get());
diff --git a/chrome/browser/notifications/notification_channels_provider_android.cc b/chrome/browser/notifications/notification_channels_provider_android.cc index 66b4881d..8464a4c 100644 --- a/chrome/browser/notifications/notification_channels_provider_android.cc +++ b/chrome/browser/notifications/notification_channels_provider_android.cc
@@ -267,6 +267,10 @@ } } +void NotificationChannelsProviderAndroid::ShutdownOnUIThread() { + RemoveAllObservers(); +} + base::Time NotificationChannelsProviderAndroid::GetWebsiteSettingLastModified( const ContentSettingsPattern& primary_pattern, const ContentSettingsPattern& secondary_pattern, @@ -289,10 +293,6 @@ return channel_entry->second.timestamp; } -void NotificationChannelsProviderAndroid::ShutdownOnUIThread() { - RemoveAllObservers(); -} - // InitCachedChannels() must be called prior to calling this method. void NotificationChannelsProviderAndroid::CreateChannelIfRequired( const std::string& origin_string,
diff --git a/chrome/browser/notifications/notification_channels_provider_android.h b/chrome/browser/notifications/notification_channels_provider_android.h index 707ff62..a26326d 100644 --- a/chrome/browser/notifications/notification_channels_provider_android.h +++ b/chrome/browser/notifications/notification_channels_provider_android.h
@@ -13,9 +13,9 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/time/clock.h" -#include "components/content_settings/core/browser/content_settings_observable_provider.h" #include "components/content_settings/core/browser/content_settings_observer.h" #include "components/content_settings/core/browser/content_settings_rule.h" +#include "components/content_settings/core/browser/user_modifiable_provider.h" #include "components/content_settings/core/common/content_settings.h" #include "components/content_settings/core/common/content_settings_types.h" #include "components/keyed_service/core/keyed_service.h" @@ -44,7 +44,7 @@ // content settings, but defers to supervised user and policy settings - see // ordering of the ProviderType enum values in HostContentSettingsMap. class NotificationChannelsProviderAndroid - : public content_settings::ObservableProvider { + : public content_settings::UserModifiableProvider { public: // Helper class to make the JNI calls. class NotificationChannelsBridge { @@ -63,7 +63,7 @@ NotificationChannelsProviderAndroid(); ~NotificationChannelsProviderAndroid() override; - // ProviderInterface methods: + // UserModifiableProvider methods. std::unique_ptr<content_settings::RuleIterator> GetRuleIterator( ContentSettingsType content_type, const content_settings::ResourceIdentifier& resource_identifier, @@ -76,12 +76,11 @@ base::Value* value) override; void ClearAllContentSettingsRules(ContentSettingsType content_type) override; void ShutdownOnUIThread() override; - base::Time GetWebsiteSettingLastModified( const ContentSettingsPattern& primary_pattern, const ContentSettingsPattern& secondary_pattern, ContentSettingsType content_type, - const content_settings::ResourceIdentifier& resource_identifier); + const content_settings::ResourceIdentifier& resource_identifier) override; private: explicit NotificationChannelsProviderAndroid(
diff --git a/chrome/browser/notifications/notification_display_service_tester.cc b/chrome/browser/notifications/notification_display_service_tester.cc deleted file mode 100644 index 6228e48..0000000 --- a/chrome/browser/notifications/notification_display_service_tester.cc +++ /dev/null
@@ -1,47 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/notifications/notification_display_service_tester.h" - -#include "chrome/browser/notifications/notification.h" -#include "chrome/browser/notifications/notification_display_service.h" -#include "chrome/browser/notifications/notification_display_service_factory.h" -#include "chrome/browser/notifications/stub_notification_display_service.h" -#include "chrome/browser/profiles/profile.h" -#include "components/keyed_service/core/keyed_service.h" - -NotificationDisplayServiceTester::NotificationDisplayServiceTester( - Profile* profile) - : profile_(profile) { - DCHECK(profile_); - - display_service_ = static_cast<StubNotificationDisplayService*>( - NotificationDisplayServiceFactory::GetInstance()->SetTestingFactoryAndUse( - profile_, &StubNotificationDisplayService::FactoryForTests)); -} - -NotificationDisplayServiceTester::~NotificationDisplayServiceTester() { - NotificationDisplayServiceFactory::GetInstance()->SetTestingFactory(profile_, - nullptr); -} - -std::vector<Notification> -NotificationDisplayServiceTester::GetDisplayedNotificationsForType( - NotificationCommon::Type type) { - return display_service_->GetDisplayedNotificationsForType(type); -} - -void NotificationDisplayServiceTester::RemoveNotification( - NotificationCommon::Type type, - const std::string& notification_id, - bool by_user, - bool silent) { - display_service_->RemoveNotification(type, notification_id, by_user, silent); -} - -void NotificationDisplayServiceTester::RemoveAllNotifications( - NotificationCommon::Type type, - bool by_user) { - display_service_->RemoveAllNotifications(type, by_user); -}
diff --git a/chrome/browser/notifications/notification_display_service_tester.h b/chrome/browser/notifications/notification_display_service_tester.h deleted file mode 100644 index 12acf589..0000000 --- a/chrome/browser/notifications/notification_display_service_tester.h +++ /dev/null
@@ -1,51 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_NOTIFICATIONS_NOTIFICATION_DISPLAY_SERVICE_TESTER_H_ -#define CHROME_BROWSER_NOTIFICATIONS_NOTIFICATION_DISPLAY_SERVICE_TESTER_H_ - -#include <vector> - -#include "base/macros.h" -#include "chrome/browser/notifications/notification_common.h" - -class Notification; -class Profile; -class StubNotificationDisplayService; - -// Helper class that enables use of the NotificationDisplayService in tests. The -// Profile* passed when constructing an instance must outlive this class, as -// the service (or internals of the service) may be overridden. -// -// This class must only be used for testing purposes. -class NotificationDisplayServiceTester { - public: - explicit NotificationDisplayServiceTester(Profile* profile); - ~NotificationDisplayServiceTester(); - - // Synchronously gets a vector of the displayed Notifications for the |type|. - std::vector<Notification> GetDisplayedNotificationsForType( - NotificationCommon::Type type); - - // Simulates the notification identified by |notification_id| being closed due - // to external events, such as the user dismissing it when |by_user| is set. - // When |silent| is set, the notification handlers won't be informed of the - // change to immitate behaviour of operating systems that don't inform apps - // about removed notifications. - void RemoveNotification(NotificationCommon::Type type, - const std::string& notification_id, - bool by_user, - bool silent = false); - - // Removes all notifications of the given |type|. - void RemoveAllNotifications(NotificationCommon::Type type, bool by_user); - - private: - Profile* profile_; - StubNotificationDisplayService* display_service_; - - DISALLOW_COPY_AND_ASSIGN(NotificationDisplayServiceTester); -}; - -#endif // CHROME_BROWSER_NOTIFICATIONS_NOTIFICATION_DISPLAY_SERVICE_TESTER_H_
diff --git a/chrome/browser/notifications/platform_notification_service_interactive_uitest.cc b/chrome/browser/notifications/platform_notification_service_interactive_uitest.cc index 55ccf5f..a232dc6 100644 --- a/chrome/browser/notifications/platform_notification_service_interactive_uitest.cc +++ b/chrome/browser/notifications/platform_notification_service_interactive_uitest.cc
@@ -21,9 +21,11 @@ #include "chrome/browser/notifications/desktop_notification_profile_util.h" #include "chrome/browser/notifications/notification.h" #include "chrome/browser/notifications/notification_common.h" -#include "chrome/browser/notifications/notification_display_service_tester.h" +#include "chrome/browser/notifications/notification_display_service.h" +#include "chrome/browser/notifications/notification_display_service_factory.h" #include "chrome/browser/notifications/notification_test_util.h" #include "chrome/browser/notifications/platform_notification_service_impl.h" +#include "chrome/browser/notifications/stub_notification_display_service.h" #include "chrome/browser/notifications/web_notification_delegate.h" #include "chrome/browser/permissions/permission_manager.h" #include "chrome/browser/permissions/permission_request_manager.h" @@ -87,25 +89,25 @@ } void SetUpOnMainThread() override { - display_service_tester_ = - base::MakeUnique<NotificationDisplayServiceTester>( - browser()->profile()); + NotificationDisplayServiceFactory::GetInstance()->SetTestingFactory( + browser()->profile(), &StubNotificationDisplayService::FactoryForTests); SiteEngagementScore::SetParamValuesForTesting(); NavigateToTestPage(std::string("/") + kTestFileName); } - void TearDown() override { - display_service_tester_.reset(); - InProcessBrowserTest::TearDown(); - } - protected: // Returns the Platform Notification Service these unit tests are for. PlatformNotificationServiceImpl* service() const { return PlatformNotificationServiceImpl::GetInstance(); } + // Returns the stub notification display service. + StubNotificationDisplayService* GetDisplayService() const { + return static_cast<StubNotificationDisplayService*>( + NotificationDisplayServiceFactory::GetForProfile(browser()->profile())); + } + // Returns a vector with the Notification objects that are being displayed // by the notification display service. Synchronous. std::vector<Notification> GetDisplayedNotifications( @@ -114,7 +116,7 @@ ? NotificationCommon::PERSISTENT : NotificationCommon::NON_PERSISTENT; - return display_service_tester_->GetDisplayedNotificationsForType(type); + return GetDisplayService()->GetDisplayedNotificationsForType(type); } // Grants permission to display Web Notifications for origin of the test @@ -194,7 +196,6 @@ } const base::FilePath server_root_; - std::unique_ptr<NotificationDisplayServiceTester> display_service_tester_; private: std::unique_ptr<net::EmbeddedTestServer> https_server_; @@ -671,7 +672,7 @@ ASSERT_TRUE( base::StartsWith(notification.id(), "p:", base::CompareCase::SENSITIVE)); - display_service_tester_->RemoveNotification( + GetDisplayService()->RemoveNotification( NotificationCommon::PERSISTENT, notification.delegate_id(), false /* by_user */, true /* silent */);
diff --git a/chrome/browser/notifications/platform_notification_service_unittest.cc b/chrome/browser/notifications/platform_notification_service_unittest.cc index 64aa4e9..ddeee14 100644 --- a/chrome/browser/notifications/platform_notification_service_unittest.cc +++ b/chrome/browser/notifications/platform_notification_service_unittest.cc
@@ -10,22 +10,30 @@ #include "base/feature_list.h" #include "base/macros.h" #include "base/memory/ptr_util.h" +#include "base/run_loop.h" #include "base/strings/utf_string_conversions.h" +#include "base/threading/platform_thread.h" #include "base/time/time.h" #include "build/build_config.h" -#include "chrome/browser/notifications/notification_display_service_tester.h" +#include "chrome/browser/content_settings/host_content_settings_map_factory.h" +#include "chrome/browser/notifications/notification_display_service.h" +#include "chrome/browser/notifications/notification_display_service_factory.h" +#include "chrome/browser/notifications/notification_test_util.h" #include "chrome/browser/notifications/platform_notification_service_impl.h" +#include "chrome/browser/notifications/stub_notification_display_service.h" #include "chrome/browser/notifications/web_notification_delegate.h" #include "chrome/common/chrome_features.h" #include "chrome/test/base/testing_browser_process.h" #include "chrome/test/base/testing_profile.h" #include "chrome/test/base/testing_profile_manager.h" +#include "components/content_settings/core/browser/host_content_settings_map.h" #include "content/public/common/notification_resources.h" #include "content/public/common/platform_notification_data.h" #include "content/public/test/test_browser_thread_bundle.h" #include "extensions/features/features.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/WebKit/public/platform/modules/permissions/permission_status.mojom.h" #if BUILDFLAG(ENABLE_EXTENSIONS) #include "base/command_line.h" @@ -37,7 +45,6 @@ #include "extensions/common/extension_builder.h" #include "extensions/common/permissions/api_permission.h" #include "extensions/common/value_builder.h" -#include "third_party/WebKit/public/platform/modules/permissions/permission_status.mojom.h" #endif using content::NotificationResources; @@ -57,28 +64,32 @@ TestingBrowserProcess::GetGlobal()); ASSERT_TRUE(profile_manager_->SetUp()); profile_ = profile_manager_->CreateTestingProfile("Miguel"); - display_service_tester_ = - base::MakeUnique<NotificationDisplayServiceTester>(profile_); + + NotificationDisplayServiceFactory::GetInstance()->SetTestingFactory( + profile_, &StubNotificationDisplayService::FactoryForTests); } void TearDown() override { - display_service_tester_.reset(); profile_manager_.reset(); - TestingBrowserProcess::DeleteInstance(); } protected: - // Displays a simple, fake notification. The close closure may be specified if - // desired. + // Displays a simple, fake notifications. + void CreateSimplePageNotification() const { + CreateSimplePageNotificationWithCloseClosure(nullptr); + } + + // Displays a simple, fake notification. + // The close closure may be specified if desired. void CreateSimplePageNotificationWithCloseClosure( - base::Closure* close_closure) { + base::Closure* close_closure) const { PlatformNotificationData notification_data; notification_data.title = base::ASCIIToUTF16("My Notification"); notification_data.body = base::ASCIIToUTF16("Hello, world!"); service()->DisplayNotification( - profile_, kNotificationId, GURL("https://chrome.com/"), + profile(), kNotificationId, GURL("https://chrome.com/"), notification_data, NotificationResources(), close_closure); } @@ -87,26 +98,32 @@ return PlatformNotificationServiceImpl::GetInstance(); } + // Returns the stub notification display service. + StubNotificationDisplayService* GetDisplayService() const { + return static_cast<StubNotificationDisplayService*>( + NotificationDisplayServiceFactory::GetForProfile(profile_)); + } + + // Returns the Profile to be used for these tests. + Profile* profile() const { return profile_; } + size_t GetNotificationCountForType(NotificationCommon::Type type) { - return display_service_tester_->GetDisplayedNotificationsForType(type) - .size(); + return GetDisplayService()->GetDisplayedNotificationsForType(type).size(); } Notification GetDisplayedNotificationForType(NotificationCommon::Type type) { std::vector<Notification> notifications = - display_service_tester_->GetDisplayedNotificationsForType(type); + GetDisplayService()->GetDisplayedNotificationsForType(type); DCHECK_EQ(1u, notifications.size()); return notifications[0]; } - protected: - content::TestBrowserThreadBundle thread_bundle_; - + private: std::unique_ptr<TestingProfileManager> profile_manager_; TestingProfile* profile_; - - std::unique_ptr<NotificationDisplayServiceTester> display_service_tester_; + content::TestBrowserThreadBundle thread_bundle_; + std::unique_ptr<std::set<std::string>> displayed_notifications_; }; @@ -132,7 +149,7 @@ notification_data.body = base::ASCIIToUTF16("Hello, world!"); service()->DisplayPersistentNotification( - profile_, kNotificationId, GURL() /* service_worker_scope */, + profile(), kNotificationId, GURL() /* service_worker_scope */, GURL("https://chrome.com/"), notification_data, NotificationResources()); ASSERT_EQ(1u, GetNotificationCountForType(NotificationCommon::PERSISTENT)); @@ -145,7 +162,7 @@ EXPECT_EQ("Hello, world!", base::UTF16ToUTF8(notification.message())); - service()->ClosePersistentNotification(profile_, kNotificationId); + service()->ClosePersistentNotification(profile(), kNotificationId); EXPECT_EQ(0u, GetNotificationCountForType(NotificationCommon::PERSISTENT)); } @@ -160,7 +177,7 @@ notification_data.vibration_pattern = vibration_pattern; notification_data.silent = true; - service()->DisplayNotification(profile_, kNotificationId, + service()->DisplayNotification(profile(), kNotificationId, GURL("https://chrome.com/"), notification_data, NotificationResources(), nullptr); @@ -203,7 +220,7 @@ notification_resources.action_icons.resize(notification_data.actions.size()); service()->DisplayPersistentNotification( - profile_, kNotificationId, GURL() /* service_worker_scope */, + profile(), kNotificationId, GURL() /* service_worker_scope */, GURL("https://chrome.com/"), notification_data, notification_resources); ASSERT_EQ(1u, GetNotificationCountForType(NotificationCommon::PERSISTENT)); @@ -231,7 +248,7 @@ TEST_F(PlatformNotificationServiceTest, DisplayNameForContextMessage) { base::string16 display_name = service()->DisplayNameForContextMessage( - profile_, GURL("https://chrome.com/")); + profile(), GURL("https://chrome.com/")); EXPECT_TRUE(display_name.empty()); @@ -248,11 +265,11 @@ .Build(); extensions::ExtensionRegistry* registry = - extensions::ExtensionRegistry::Get(profile_); + extensions::ExtensionRegistry::Get(profile()); EXPECT_TRUE(registry->AddEnabled(extension)); display_name = service()->DisplayNameForContextMessage( - profile_, + profile(), GURL("chrome-extension://honijodknafkokifofgiaalefdiedpko/main.html")); EXPECT_EQ("NotificationTest", base::UTF16ToUTF8(display_name)); } @@ -261,7 +278,7 @@ base::CommandLine command_line(base::CommandLine::NO_PROGRAM); extensions::TestExtensionSystem* test_extension_system = static_cast<extensions::TestExtensionSystem*>( - extensions::ExtensionSystem::Get(profile_)); + extensions::ExtensionSystem::Get(profile())); ExtensionService* extension_service = test_extension_system->CreateExtensionService( @@ -287,7 +304,7 @@ // has been added to the extension registry successfully. extension_service->AddExtension(extension.get()); extensions::ExtensionRegistry* registry = - extensions::ExtensionRegistry::Get(profile_); + extensions::ExtensionRegistry::Get(profile()); ASSERT_TRUE(registry->GetExtensionById( extension->id(), extensions::ExtensionRegistry::ENABLED)); @@ -295,14 +312,16 @@ const int kFakeRenderProcessId = 42; // Mock that the extension is running in a fake render process id. - extensions::ProcessMap::Get(profile_)->Insert( - extension->id(), kFakeRenderProcessId, -1 /* site_instance_id */); + extensions::ProcessMap::Get(profile())->Insert(extension->id(), + kFakeRenderProcessId, + -1 /* site_instance_id */); // Verify that the service indicates that permission has been granted. We only // check the UI thread-method for now, as that's the one guarding the behavior // in the browser process. EXPECT_EQ(blink::mojom::PermissionStatus::GRANTED, - service()->CheckPermissionOnUIThread(profile_, extension->url(), + service()->CheckPermissionOnUIThread(profile(), + extension->url(), kFakeRenderProcessId)); } @@ -313,9 +332,9 @@ GURL origin("https://chrome.com/"); Notification notification = service()->CreateNotificationFromData( - profile_, GURL() /* service_worker_scope */, origin, notification_data, + profile(), GURL() /* service_worker_scope */, origin, notification_data, NotificationResources(), - new WebNotificationDelegate(NotificationCommon::PERSISTENT, profile_, + new WebNotificationDelegate(NotificationCommon::PERSISTENT, profile(), "id", origin)); EXPECT_TRUE(notification.context_message().empty()); @@ -332,15 +351,15 @@ .Build(); extensions::ExtensionRegistry* registry = - extensions::ExtensionRegistry::Get(profile_); + extensions::ExtensionRegistry::Get(profile()); EXPECT_TRUE(registry->AddEnabled(extension)); notification = service()->CreateNotificationFromData( - profile_, GURL() /* service_worker_scope */, + profile(), GURL() /* service_worker_scope */, GURL("chrome-extension://honijodknafkokifofgiaalefdiedpko/main.html"), notification_data, NotificationResources(), - new WebNotificationDelegate(NotificationCommon::EXTENSION, profile_, "id", - origin)); + new WebNotificationDelegate(NotificationCommon::EXTENSION, profile(), + "id", origin)); EXPECT_EQ("NotificationTest", base::UTF16ToUTF8(notification.context_message())); }
diff --git a/chrome/browser/notifications/stub_notification_display_service.h b/chrome/browser/notifications/stub_notification_display_service.h index f1a8dd3..699d40af 100644 --- a/chrome/browser/notifications/stub_notification_display_service.h +++ b/chrome/browser/notifications/stub_notification_display_service.h
@@ -33,15 +33,13 @@ std::vector<Notification> GetDisplayedNotificationsForType( NotificationCommon::Type type) const; - // Simulates the notification identified by |notification_id| being closed due - // to external events, such as the user dismissing it when |by_user| is set. - // When |silent| is set, the notification handlers won't be informed of the - // change to immitate behaviour of operating systems that don't inform apps - // about removed notifications. + // Removes the notification identified by |notification_id|. This can + // optionally be |silent|, which means the delegate events won't be invoked + // to imitate behaviour on operating systems that don't support such events. void RemoveNotification(NotificationCommon::Type notification_type, const std::string& notification_id, bool by_user, - bool silent); + bool silent = false); // Removes all notifications shown by this display service. void RemoveAllNotifications(NotificationCommon::Type notification_type,
diff --git a/chrome/browser/ntp_snippets/content_suggestions_service_factory.cc b/chrome/browser/ntp_snippets/content_suggestions_service_factory.cc index e359459..827e426 100644 --- a/chrome/browser/ntp_snippets/content_suggestions_service_factory.cc +++ b/chrome/browser/ntp_snippets/content_suggestions_service_factory.cc
@@ -42,8 +42,6 @@ #include "components/ntp_snippets/bookmarks/bookmark_suggestions_provider.h" #include "components/ntp_snippets/category_rankers/category_ranker.h" #include "components/ntp_snippets/content_suggestions_service.h" -#include "components/ntp_snippets/contextual/contextual_suggestions_fetcher_impl.h" -#include "components/ntp_snippets/contextual/contextual_suggestions_source.h" #include "components/ntp_snippets/features.h" #include "components/ntp_snippets/ntp_snippets_constants.h" #include "components/ntp_snippets/remote/persistent_scheduler.h" @@ -105,8 +103,6 @@ using ntp_snippets::BreakingNewsListener; using ntp_snippets::CategoryRanker; using ntp_snippets::ContentSuggestionsService; -using ntp_snippets::ContextualSuggestionsFetcherImpl; -using ntp_snippets::ContextualSuggestionsSource; using ntp_snippets::ForeignSessionsSuggestionsProvider; using ntp_snippets::GetFetchEndpoint; using ntp_snippets::PersistentScheduler; @@ -162,48 +158,6 @@ #endif } -bool IsContextualSuggestionsEnabled() { - return base::FeatureList::IsEnabled( - chrome::android::kContextualSuggestionsCarousel); -} - -void RegisterContextualSuggestionsSourceIfEnabled( - ContentSuggestionsService* service, - Profile* profile) { - if (!IsContextualSuggestionsEnabled()) { - return; - } - - PrefService* pref_service = profile->GetPrefs(); - SigninManagerBase* signin_manager = - SigninManagerFactory::GetForProfile(profile); - OAuth2TokenService* token_service = - ProfileOAuth2TokenServiceFactory::GetForProfile(profile); - scoped_refptr<net::URLRequestContextGetter> request_context = - profile->GetRequestContext(); - auto contextual_suggestions_fetcher = - base::MakeUnique<ContextualSuggestionsFetcherImpl>( - signin_manager, token_service, request_context, pref_service, - base::Bind(&safe_json::SafeJsonParser::Parse)); - base::FilePath database_dir( - profile->GetPath().Append("contextualSuggestionsDatabase")); - auto contextual_suggestions_database = - base::MakeUnique<RemoteSuggestionsDatabase>(database_dir); - auto cached_image_fetcher = - base::MakeUnique<ntp_snippets::CachedImageFetcher>( - base::MakeUnique<image_fetcher::ImageFetcherImpl>( - base::MakeUnique<ImageDecoderImpl>(), request_context.get()), - pref_service, contextual_suggestions_database.get()); - auto contextual_suggestions_source = - base::MakeUnique<ContextualSuggestionsSource>( - std::move(contextual_suggestions_fetcher), - std::move(cached_image_fetcher), - std::move(contextual_suggestions_database)); - - service->set_contextual_suggestions_source( - std::move(contextual_suggestions_source)); -} - #if BUILDFLAG(ENABLE_OFFLINE_PAGES) bool IsRecentTabProviderEnabled() { @@ -575,7 +529,6 @@ pref_service, std::move(category_ranker), std::move(user_classifier), std::move(scheduler)); - RegisterContextualSuggestionsSourceIfEnabled(service, profile); RegisterArticleProviderIfEnabled(service, profile, signin_manager, user_classifier_raw, offline_page_model); RegisterBookmarkProviderIfEnabled(service, profile);
diff --git a/chrome/browser/ntp_snippets/contextual_content_suggestions_service_factory.cc b/chrome/browser/ntp_snippets/contextual_content_suggestions_service_factory.cc new file mode 100644 index 0000000..4ee513c --- /dev/null +++ b/chrome/browser/ntp_snippets/contextual_content_suggestions_service_factory.cc
@@ -0,0 +1,119 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ntp_snippets/contextual_content_suggestions_service_factory.h" + +#include "base/files/file_path.h" +#include "base/memory/ptr_util.h" +#include "build/build_config.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/search/suggestions/image_decoder_impl.h" +#include "chrome/browser/signin/profile_oauth2_token_service_factory.h" +#include "chrome/browser/signin/signin_manager_factory.h" +#include "components/image_fetcher/core/image_decoder.h" +#include "components/image_fetcher/core/image_fetcher.h" +#include "components/image_fetcher/core/image_fetcher_impl.h" +#include "components/keyed_service/content/browser_context_dependency_manager.h" +#include "components/ntp_snippets/contextual/contextual_content_suggestions_service.h" +#include "components/ntp_snippets/contextual/contextual_suggestions_fetcher_impl.h" +#include "components/ntp_snippets/remote/cached_image_fetcher.h" +#include "components/ntp_snippets/remote/remote_suggestions_database.h" +#include "components/prefs/pref_service.h" +#include "components/safe_json/safe_json_parser.h" +#include "components/signin/core/browser/profile_oauth2_token_service.h" +#include "components/signin/core/browser/signin_manager.h" +#include "content/public/browser/browser_context.h" + +#if defined(OS_ANDROID) +#include "chrome/browser/android/chrome_feature_list.h" +#endif + +using ntp_snippets::ContextualSuggestionsFetcherImpl; +using ntp_snippets::ContextualContentSuggestionsService; +using ntp_snippets::RemoteSuggestionsDatabase; + +namespace { + +bool IsContextualContentSuggestionsEnabled() { +#if defined(OS_ANDROID) + return base::FeatureList::IsEnabled( + chrome::android::kContextualSuggestionsCarousel); +#else + return false; +#endif // OS_ANDROID +} + +} // namespace + +// static +ContextualContentSuggestionsServiceFactory* +ContextualContentSuggestionsServiceFactory::GetInstance() { + return base::Singleton<ContextualContentSuggestionsServiceFactory>::get(); +} + +// static +ContextualContentSuggestionsService* +ContextualContentSuggestionsServiceFactory::GetForProfile(Profile* profile) { + return static_cast<ContextualContentSuggestionsService*>( + GetInstance()->GetServiceForBrowserContext(profile, true)); +} + +// static +ContextualContentSuggestionsService* +ContextualContentSuggestionsServiceFactory::GetForProfileIfExists( + Profile* profile) { + return static_cast<ContextualContentSuggestionsService*>( + GetInstance()->GetServiceForBrowserContext(profile, false)); +} + +ContextualContentSuggestionsServiceFactory:: + ContextualContentSuggestionsServiceFactory() + : BrowserContextKeyedServiceFactory( + "ContextualContentSuggestionsService", + BrowserContextDependencyManager::GetInstance()) { + DependsOn(ProfileOAuth2TokenServiceFactory::GetInstance()); + DependsOn(SigninManagerFactory::GetInstance()); +} + +ContextualContentSuggestionsServiceFactory:: + ~ContextualContentSuggestionsServiceFactory() = default; + +KeyedService* +ContextualContentSuggestionsServiceFactory::BuildServiceInstanceFor( + content::BrowserContext* context) const { + Profile* profile = Profile::FromBrowserContext(context); + DCHECK(!profile->IsOffTheRecord()); + if (!IsContextualContentSuggestionsEnabled()) { + return nullptr; + } + + PrefService* pref_service = profile->GetPrefs(); + SigninManagerBase* signin_manager = + SigninManagerFactory::GetForProfile(profile); + OAuth2TokenService* token_service = + ProfileOAuth2TokenServiceFactory::GetForProfile(profile); + scoped_refptr<net::URLRequestContextGetter> request_context = + profile->GetRequestContext(); + auto contextual_suggestions_fetcher = + base::MakeUnique<ContextualSuggestionsFetcherImpl>( + signin_manager, token_service, request_context, pref_service, + base::Bind(&safe_json::SafeJsonParser::Parse)); + const base::FilePath::CharType kDatabaseFolder[] = + FILE_PATH_LITERAL("contextualSuggestionsDatabase"); + base::FilePath database_dir(profile->GetPath().Append(kDatabaseFolder)); + auto contextual_suggestions_database = + base::MakeUnique<RemoteSuggestionsDatabase>(database_dir); + auto cached_image_fetcher = + base::MakeUnique<ntp_snippets::CachedImageFetcher>( + base::MakeUnique<image_fetcher::ImageFetcherImpl>( + base::MakeUnique<suggestions::ImageDecoderImpl>(), + request_context.get()), + pref_service, contextual_suggestions_database.get()); + auto* service = new ContextualContentSuggestionsService( + std::move(contextual_suggestions_fetcher), + std::move(cached_image_fetcher), + std::move(contextual_suggestions_database)); + + return service; +}
diff --git a/chrome/browser/ntp_snippets/contextual_content_suggestions_service_factory.h b/chrome/browser/ntp_snippets/contextual_content_suggestions_service_factory.h new file mode 100644 index 0000000..ff7459c3 --- /dev/null +++ b/chrome/browser/ntp_snippets/contextual_content_suggestions_service_factory.h
@@ -0,0 +1,47 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_NTP_SNIPPETS_CONTEXTUAL_CONTENT_SUGGESTIONS_SERVICE_FACTORY_H_ +#define CHROME_BROWSER_NTP_SNIPPETS_CONTEXTUAL_CONTENT_SUGGESTIONS_SERVICE_FACTORY_H_ + +#include <memory> + +#include "base/macros.h" +#include "components/keyed_service/content/browser_context_keyed_service_factory.h" + +class Profile; + +namespace base { +template <typename T> +struct DefaultSingletonTraits; +} // namespace base + +namespace ntp_snippets { +class ContextualContentSuggestionsService; +} // namespace ntp_snippets + +class ContextualContentSuggestionsServiceFactory + : public BrowserContextKeyedServiceFactory { + public: + static ContextualContentSuggestionsServiceFactory* GetInstance(); + static ntp_snippets::ContextualContentSuggestionsService* GetForProfile( + Profile* profile); + static ntp_snippets::ContextualContentSuggestionsService* + GetForProfileIfExists(Profile* profile); + + private: + friend struct base::DefaultSingletonTraits< + ContextualContentSuggestionsServiceFactory>; + + ContextualContentSuggestionsServiceFactory(); + ~ContextualContentSuggestionsServiceFactory() override; + + // BrowserContextKeyedServiceFactory implementation. + KeyedService* BuildServiceInstanceFor( + content::BrowserContext* context) const override; + + DISALLOW_COPY_AND_ASSIGN(ContextualContentSuggestionsServiceFactory); +}; + +#endif // CHROME_BROWSER_NTP_SNIPPETS_CONTEXTUAL_CONTENT_SUGGESTIONS_SERVICE_FACTORY_H_
diff --git a/chrome/browser/offline_pages/android/offline_page_bridge.cc b/chrome/browser/offline_pages/android/offline_page_bridge.cc index f5f35b1c..0d816275 100644 --- a/chrome/browser/offline_pages/android/offline_page_bridge.cc +++ b/chrome/browser/offline_pages/android/offline_page_bridge.cc
@@ -437,6 +437,26 @@ client_ids, base::Bind(&MultipleOfflinePageItemCallback, j_result_ref, j_callback_ref)); } + +void OfflinePageBridge::GetPagesByRequestOrigin( + JNIEnv* env, + const JavaParamRef<jobject>& obj, + const JavaParamRef<jobject>& j_result_obj, + const JavaParamRef<jstring>& j_request_origin, + const JavaParamRef<jobject>& j_callback_obj) { + ScopedJavaGlobalRef<jobject> j_result_ref; + j_result_ref.Reset(env, j_result_obj); + + ScopedJavaGlobalRef<jobject> j_callback_ref; + j_callback_ref.Reset(env, j_callback_obj); + + std::string request_origin = ConvertJavaStringToUTF8(env, j_request_origin); + + offline_page_model_->GetPagesByRequestOrigin( + request_origin, base::Bind(&MultipleOfflinePageItemCallback, j_result_ref, + j_callback_ref)); +} + void OfflinePageBridge::GetPagesForNamespace( JNIEnv* env, const JavaParamRef<jobject>& obj,
diff --git a/chrome/browser/offline_pages/android/offline_page_bridge.h b/chrome/browser/offline_pages/android/offline_page_bridge.h index a23497d4..a210bca 100644 --- a/chrome/browser/offline_pages/android/offline_page_bridge.h +++ b/chrome/browser/offline_pages/android/offline_page_bridge.h
@@ -83,6 +83,13 @@ const base::android::JavaParamRef<jobjectArray>& j_ids_array, const base::android::JavaParamRef<jobject>& j_callback_obj); + void GetPagesByRequestOrigin( + JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj, + const base::android::JavaParamRef<jobject>& j_result_obj, + const base::android::JavaParamRef<jstring>& j_request_origin, + const base::android::JavaParamRef<jobject>& j_callback_obj); + void GetPagesForNamespace( JNIEnv* env, const base::android::JavaParamRef<jobject>& obj,
diff --git a/chrome/browser/offline_pages/prefetch/offline_prefetch_download_client.cc b/chrome/browser/offline_pages/prefetch/offline_prefetch_download_client.cc index d541f71..fbb097b 100644 --- a/chrome/browser/offline_pages/prefetch/offline_prefetch_download_client.cc +++ b/chrome/browser/offline_pages/prefetch/offline_prefetch_download_client.cc
@@ -21,12 +21,9 @@ void OfflinePrefetchDownloadClient::OnServiceInitialized( bool state_lost, const std::vector<std::string>& outstanding_download_guids) { - // TODO(jianli): Remove orphaned downloads. - // TODO(jianli, dtrainor): Handle service corruption and recovery if - // |state_lost| is |true|. PrefetchDownloader* downloader = GetPrefetchDownloader(); if (downloader) - downloader->OnDownloadServiceReady(); + downloader->OnDownloadServiceReady(outstanding_download_guids); } void OfflinePrefetchDownloadClient::OnServiceUnavailable() {
diff --git a/chrome/browser/pdf/pdf_extension_test.cc b/chrome/browser/pdf/pdf_extension_test.cc index a9d7fb2..8064360 100644 --- a/chrome/browser/pdf/pdf_extension_test.cc +++ b/chrome/browser/pdf/pdf_extension_test.cc
@@ -17,6 +17,7 @@ #include "base/path_service.h" #include "base/strings/pattern.h" #include "base/strings/utf_string_conversions.h" +#include "base/test/test_timeouts.h" #include "base/threading/thread_restrictions.h" #include "build/build_config.h" #include "chrome/browser/chrome_notification_types.h" @@ -57,7 +58,9 @@ #include "extensions/test/result_catcher.h" #include "net/dns/mock_host_resolver.h" #include "net/test/embedded_test_server/embedded_test_server.h" +#include "ui/base/clipboard/clipboard.h" #include "ui/base/resource/resource_bundle.h" +#include "ui/base/test/test_clipboard.h" #include "url/gurl.h" #if defined(TOOLKIT_VIEWS) && !defined(OS_MACOSX) @@ -1036,3 +1039,273 @@ const GURL& url = new_web_contents->GetURL(); EXPECT_EQ("http://www.example.com/", url.spec()); } + +class PDFExtensionClipboardTest : public PDFExtensionTest { + public: + PDFExtensionClipboardTest() : guest_contents_(nullptr) {} + ~PDFExtensionClipboardTest() override {} + + void SetUpOnMainThread() override { + PDFExtensionTest::SetUpOnMainThread(); + ui::TestClipboard::CreateForCurrentThread(); + } + + void TearDownOnMainThread() override { + ui::Clipboard::DestroyClipboardForCurrentThread(); + PDFExtensionTest::TearDownOnMainThread(); + } + + void LoadTestComboBoxPdfGetGuestContents() { + GURL test_pdf_url(embedded_test_server()->GetURL("/pdf/combobox_form.pdf")); + guest_contents_ = LoadPdfGetGuestContents(test_pdf_url); + ASSERT_TRUE(guest_contents_); + } + + // Returns a point near the left edge of the editable combo box in + // combobox_form.pdf, inside the combo box rect. The point is in Blink screen + // coordinates. + // + // The combo box's rect is [100 50 200 80] in PDF user space. (136, 318) in + // Blink page coordinates corresponds to approximately (102, 62) in PDF user + // space coordinates. See PDFExtensionLinkClickTest::GetLinkPosition() for + // more information on all the coordinate systems involved. + gfx::Point GetEditableComboBoxLeftPosition() { + gfx::Point position(136, 318); + ConvertPageCoordToScreenCoord(guest_contents_, &position); + return position; + } + + void ClickLeftSideOfEditableComboBox() { + content::SimulateMouseClickAt(GetActiveWebContents(), 0, + blink::WebMouseEvent::Button::kLeft, + GetEditableComboBoxLeftPosition()); + } + + void TypeHello() { + auto* web_contents = GetActiveWebContents(); + content::SimulateKeyPress(web_contents, ui::DomKey::FromCharacter('H'), + ui::DomCode::US_H, ui::VKEY_H, false, false, + false, false); + content::SimulateKeyPress(web_contents, ui::DomKey::FromCharacter('E'), + ui::DomCode::US_E, ui::VKEY_E, false, false, + false, false); + content::SimulateKeyPress(web_contents, ui::DomKey::FromCharacter('L'), + ui::DomCode::US_L, ui::VKEY_L, false, false, + false, false); + content::SimulateKeyPress(web_contents, ui::DomKey::FromCharacter('L'), + ui::DomCode::US_L, ui::VKEY_L, false, false, + false, false); + content::SimulateKeyPress(web_contents, ui::DomKey::FromCharacter('O'), + ui::DomCode::US_O, ui::VKEY_O, false, false, + false, false); + } + + // Presses the left arrow key. + void PressLeftArrow() { + content::SimulateKeyPressWithoutChar( + GetActiveWebContents(), ui::DomKey::ARROW_LEFT, ui::DomCode::ARROW_LEFT, + ui::VKEY_LEFT, false, false, false, false); + } + + // Presses down shift, presses the left arrow, and lets go of shift. + void PressShiftLeftArrow() { + content::SimulateKeyPressWithoutChar( + GetActiveWebContents(), ui::DomKey::ARROW_LEFT, ui::DomCode::ARROW_LEFT, + ui::VKEY_LEFT, false, /*shift=*/true, false, false); + } + + // Presses the right arrow key. + void PressRightArrow() { + content::SimulateKeyPressWithoutChar( + GetActiveWebContents(), ui::DomKey::ARROW_RIGHT, + ui::DomCode::ARROW_RIGHT, ui::VKEY_RIGHT, false, false, false, false); + } + + // Presses down shift, presses the right arrow, and lets go of shift. + void PressShiftRightArrow() { + content::SimulateKeyPressWithoutChar( + GetActiveWebContents(), ui::DomKey::ARROW_RIGHT, + ui::DomCode::ARROW_RIGHT, ui::VKEY_RIGHT, false, /*shift=*/true, false, + false); + } + + // Checks the Linux selection clipboard by polling. + void CheckSelectionClipboard(const std::string& expected) { +#if defined(OS_LINUX) && !defined(OS_CHROMEOS) + CheckClipboard(ui::CLIPBOARD_TYPE_SELECTION, expected); +#endif + } + + // Sends a copy command and checks the copy/paste clipboard by + // polling. Note: Trying to send ctrl+c does not work correctly with + // SimulateKeyPress(). Using IDC_COPY does not work on Mac in browser_tests. + void SendCopyCommandAndCheckCopyPasteClipboard(const std::string& expected) { + content::RunAllPendingInMessageLoop(); + GetActiveWebContents()->Copy(); + CheckClipboard(ui::CLIPBOARD_TYPE_COPY_PASTE, expected); + } + + private: + // Waits and polls the clipboard of a given |clipboard_type| until its + // contents reaches the length of |expected|. Then checks and see if the + // clipboard contents matches |expected|. + // TODO(thestig): Change this to avoid polling after https://crbug.com/755826 + // has been fixed. + void CheckClipboard(ui::ClipboardType clipboard_type, + const std::string& expected) { + auto* clipboard = ui::Clipboard::GetForCurrentThread(); + std::string clipboard_data; + const std::string& last_data = last_clipboard_data_[clipboard_type]; + if (last_data.size() == expected.size()) { + DCHECK_EQ(last_data, expected); + clipboard->ReadAsciiText(clipboard_type, &clipboard_data); + EXPECT_EQ(expected, clipboard_data); + return; + } + + const bool expect_increase = last_data.size() < expected.size(); + while (true) { + clipboard->ReadAsciiText(clipboard_type, &clipboard_data); + if (expect_increase) { + if (clipboard_data.size() >= expected.size()) + break; + } else { + if (clipboard_data.size() <= expected.size()) + break; + } + + content::RunAllPendingInMessageLoop(); + } + EXPECT_EQ(expected, clipboard_data); + + last_clipboard_data_[clipboard_type] = clipboard_data; + } + + std::map<ui::ClipboardType, std::string> last_clipboard_data_; + WebContents* guest_contents_; +}; + +IN_PROC_BROWSER_TEST_F(PDFExtensionClipboardTest, + IndividualShiftRightArrowPresses) { + LoadTestComboBoxPdfGetGuestContents(); + + // Give the editable combo box focus. + ClickLeftSideOfEditableComboBox(); + + TypeHello(); + + // Put the cursor back to the left side of the combo box. + ClickLeftSideOfEditableComboBox(); + + // Press shift + right arrow 3 times. Letting go of shift in between. + PressShiftRightArrow(); + CheckSelectionClipboard("H"); + PressShiftRightArrow(); + CheckSelectionClipboard("HE"); + PressShiftRightArrow(); + CheckSelectionClipboard("HEL"); + SendCopyCommandAndCheckCopyPasteClipboard("HEL"); +} + +IN_PROC_BROWSER_TEST_F(PDFExtensionClipboardTest, + IndividualShiftLeftArrowPresses) { + LoadTestComboBoxPdfGetGuestContents(); + + // Give the editable combo box focus. + ClickLeftSideOfEditableComboBox(); + + TypeHello(); + + // Put the cursor back to the left side of the combo box. + ClickLeftSideOfEditableComboBox(); + + for (int i = 0; i < 3; ++i) + PressRightArrow(); + + // Press shift + left arrow 2 times. Letting go of shift in between. + PressShiftLeftArrow(); + CheckSelectionClipboard("L"); + PressShiftLeftArrow(); + CheckSelectionClipboard("EL"); + SendCopyCommandAndCheckCopyPasteClipboard("EL"); + + // Press shift + left arrow 2 times. Letting go of shift in between. + PressShiftLeftArrow(); + CheckSelectionClipboard("HEL"); + PressShiftLeftArrow(); + CheckSelectionClipboard("HEL"); + SendCopyCommandAndCheckCopyPasteClipboard("HEL"); +} + +IN_PROC_BROWSER_TEST_F(PDFExtensionClipboardTest, + CombinedShiftRightArrowPresses) { + LoadTestComboBoxPdfGetGuestContents(); + + // Give the editable combo box focus. + ClickLeftSideOfEditableComboBox(); + + TypeHello(); + + // Put the cursor back to the left side of the combo box. + ClickLeftSideOfEditableComboBox(); + + // Press shift + right arrow 3 times. Holding down shift in between. + { + content::ScopedSimulateModifierKeyPress hold_shift( + GetActiveWebContents(), false, true, false, false); + hold_shift.KeyPressWithoutChar(ui::DomKey::ARROW_RIGHT, + ui::DomCode::ARROW_RIGHT, ui::VKEY_RIGHT); + CheckSelectionClipboard("H"); + hold_shift.KeyPressWithoutChar(ui::DomKey::ARROW_RIGHT, + ui::DomCode::ARROW_RIGHT, ui::VKEY_RIGHT); + CheckSelectionClipboard("HE"); + hold_shift.KeyPressWithoutChar(ui::DomKey::ARROW_RIGHT, + ui::DomCode::ARROW_RIGHT, ui::VKEY_RIGHT); + CheckSelectionClipboard("HEL"); + } + SendCopyCommandAndCheckCopyPasteClipboard("HEL"); +} + +IN_PROC_BROWSER_TEST_F(PDFExtensionClipboardTest, CombinedShiftArrowPresses) { + LoadTestComboBoxPdfGetGuestContents(); + + // Give the editable combo box focus. + ClickLeftSideOfEditableComboBox(); + + TypeHello(); + + // Put the cursor back to the left side of the combo box. + ClickLeftSideOfEditableComboBox(); + + for (int i = 0; i < 3; ++i) + PressRightArrow(); + + // Press shift + left arrow 3 times. Holding down shift in between. + { + content::ScopedSimulateModifierKeyPress hold_shift( + GetActiveWebContents(), false, true, false, false); + hold_shift.KeyPressWithoutChar(ui::DomKey::ARROW_LEFT, + ui::DomCode::ARROW_LEFT, ui::VKEY_LEFT); + CheckSelectionClipboard("L"); + hold_shift.KeyPressWithoutChar(ui::DomKey::ARROW_LEFT, + ui::DomCode::ARROW_LEFT, ui::VKEY_LEFT); + CheckSelectionClipboard("EL"); + hold_shift.KeyPressWithoutChar(ui::DomKey::ARROW_LEFT, + ui::DomCode::ARROW_LEFT, ui::VKEY_LEFT); + CheckSelectionClipboard("HEL"); + } + SendCopyCommandAndCheckCopyPasteClipboard("HEL"); + + // Press shift + right arrow 2 times. Holding down shift in between. + { + content::ScopedSimulateModifierKeyPress hold_shift( + GetActiveWebContents(), false, true, false, false); + hold_shift.KeyPressWithoutChar(ui::DomKey::ARROW_RIGHT, + ui::DomCode::ARROW_RIGHT, ui::VKEY_RIGHT); + CheckSelectionClipboard("EL"); + hold_shift.KeyPressWithoutChar(ui::DomKey::ARROW_RIGHT, + ui::DomCode::ARROW_RIGHT, ui::VKEY_RIGHT); + CheckSelectionClipboard("L"); + } + SendCopyCommandAndCheckCopyPasteClipboard("L"); +}
diff --git a/chrome/browser/permissions/permission_request_manager_browsertest.cc b/chrome/browser/permissions/permission_request_manager_browsertest.cc index 8c4e4bd..ebbc373 100644 --- a/chrome/browser/permissions/permission_request_manager_browsertest.cc +++ b/chrome/browser/permissions/permission_request_manager_browsertest.cc
@@ -420,8 +420,6 @@ EXPECT_EQ("denied", result); EXPECT_EQ(1, bubble_factory()->show_count()); EXPECT_EQ(1, bubble_factory()->TotalRequestCount()); - - variations::testing::ClearAllVariationParams(); } // Bubble requests should not be shown when the killswitch is on. @@ -449,9 +447,6 @@ EXPECT_EQ("denied", result); EXPECT_EQ(1, bubble_factory()->show_count()); EXPECT_EQ(1, bubble_factory()->TotalRequestCount()); - - variations::testing::ClearAllVariationParams(); - } // Host wants to run flash.
diff --git a/chrome/browser/policy/policy_browsertest.cc b/chrome/browser/policy/policy_browsertest.cc index f79425c..1bc01934 100644 --- a/chrome/browser/policy/policy_browsertest.cc +++ b/chrome/browser/policy/policy_browsertest.cc
@@ -2416,6 +2416,39 @@ } } +IN_PROC_BROWSER_TEST_F(PolicyTest, URLBlacklistAndWhitelist) { + // Regression test for http://crbug.com/755256. Blacklisting * and + // whitelisting an origin should work. + + // Filter |kURLS| on IO thread, so that requests to those hosts end up + // as URLRequestMockHTTPJobs. + const char* kURLS[] = { + "http://aaa.com/empty.html", + }; + { + base::RunLoop loop; + BrowserThread::PostTaskAndReply( + BrowserThread::IO, FROM_HERE, + base::BindOnce(RedirectHostsToTestData, kURLS, arraysize(kURLS)), + loop.QuitClosure()); + loop.Run(); + } + + base::ListValue blacklist; + blacklist.AppendString("*"); + PolicyMap policies; + policies.Set(key::kURLBlacklist, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, + POLICY_SOURCE_CLOUD, blacklist.CreateDeepCopy(), nullptr); + + base::ListValue whitelist; + whitelist.AppendString("aaa.com"); + policies.Set(key::kURLWhitelist, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, + POLICY_SOURCE_CLOUD, whitelist.CreateDeepCopy(), nullptr); + UpdateProviderPolicy(policies); + FlushBlacklistPolicy(); + CheckCanOpenURL(browser(), kURLS[0]); +} + IN_PROC_BROWSER_TEST_F(PolicyTest, URLBlacklistSubresources) { // Checks that an image with a blacklisted URL is loaded, but an iframe with a // blacklisted URL is not.
diff --git a/chrome/browser/predictors/autocomplete_action_predictor.cc b/chrome/browser/predictors/autocomplete_action_predictor.cc index ac80bb6..e18f3bee 100644 --- a/chrome/browser/predictors/autocomplete_action_predictor.cc +++ b/chrome/browser/predictors/autocomplete_action_predictor.cc
@@ -7,6 +7,8 @@ #include <math.h> #include <stddef.h> +#include <set> +#include <utility> #include <vector> #include "base/bind.h" @@ -92,7 +94,8 @@ PredictorDatabaseFactory::GetForProfile(profile_)->autocomplete_table(); // Observe all main frame loads so we can wait for the first to complete - // before accessing DB and IO threads to build the local cache. + // before accessing DB sequence of the AutocompleteActionPredictorTable and + // IO thread to build the local cache. notification_registrar_.Add(this, content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME, content::NotificationService::AllSources()); @@ -327,8 +330,8 @@ // available. std::vector<AutocompleteActionPredictorTable::Row>* rows = new std::vector<AutocompleteActionPredictorTable::Row>(); - content::BrowserThread::PostTaskAndReply( - content::BrowserThread::DB, FROM_HERE, + table_->GetTaskRunner()->PostTaskAndReply( + FROM_HERE, base::BindOnce(&AutocompleteActionPredictorTable::GetAllRows, table_, rows), base::BindOnce(&AutocompleteActionPredictor::CreateCaches, AsWeakPtr(), @@ -342,8 +345,8 @@ db_id_cache_.clear(); if (table_.get()) { - content::BrowserThread::PostTask( - content::BrowserThread::DB, FROM_HERE, + table_->GetTaskRunner()->PostTask( + FROM_HERE, base::BindOnce(&AutocompleteActionPredictorTable::DeleteAllRows, table_)); } @@ -373,10 +376,9 @@ } if (table_.get()) { - content::BrowserThread::PostTask( - content::BrowserThread::DB, FROM_HERE, - base::BindOnce(&AutocompleteActionPredictorTable::DeleteRows, table_, - id_list)); + table_->GetTaskRunner()->PostTask( + FROM_HERE, base::BindOnce(&AutocompleteActionPredictorTable::DeleteRows, + table_, id_list)); } UMA_HISTOGRAM_ENUMERATION("AutocompleteActionPredictor.DatabaseAction", @@ -416,8 +418,8 @@ } if (table_.get()) { - content::BrowserThread::PostTask( - content::BrowserThread::DB, FROM_HERE, + table_->GetTaskRunner()->PostTask( + FROM_HERE, base::BindOnce(&AutocompleteActionPredictorTable::AddAndUpdateRows, table_, rows_to_add, rows_to_update)); } @@ -475,10 +477,9 @@ std::vector<AutocompleteActionPredictorTable::Row::Id> ids_to_delete; DeleteOldIdsFromCaches(url_db, &ids_to_delete); - content::BrowserThread::PostTask( - content::BrowserThread::DB, FROM_HERE, - base::BindOnce(&AutocompleteActionPredictorTable::DeleteRows, table_, - ids_to_delete)); + table_->GetTaskRunner()->PostTask( + FROM_HERE, base::BindOnce(&AutocompleteActionPredictorTable::DeleteRows, + table_, ids_to_delete)); FinishInitialization(); if (incognito_predictor_)
diff --git a/chrome/browser/predictors/autocomplete_action_predictor_table.cc b/chrome/browser/predictors/autocomplete_action_predictor_table.cc index 380ebd9..49c01518 100644 --- a/chrome/browser/predictors/autocomplete_action_predictor_table.cc +++ b/chrome/browser/predictors/autocomplete_action_predictor_table.cc
@@ -4,7 +4,8 @@ #include "chrome/browser/predictors/autocomplete_action_predictor_table.h" -#include <stddef.h> +#include <cstddef> +#include <utility> #include "base/guid.h" #include "base/logging.h" @@ -78,7 +79,7 @@ void AutocompleteActionPredictorTable::GetRow(const Row::Id& id, Row* row) { - CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::DB)); + DCHECK(GetTaskRunner()->RunsTasksInCurrentSequence()); if (CantAccessDatabase()) return; @@ -93,7 +94,7 @@ } void AutocompleteActionPredictorTable::GetAllRows(Rows* row_buffer) { - CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::DB)); + DCHECK(GetTaskRunner()->RunsTasksInCurrentSequence()); if (CantAccessDatabase()) return; @@ -112,7 +113,7 @@ void AutocompleteActionPredictorTable::AddRow( const AutocompleteActionPredictorTable::Row& row) { - CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::DB)); + DCHECK(GetTaskRunner()->RunsTasksInCurrentSequence()); if (CantAccessDatabase()) return; @@ -121,7 +122,7 @@ void AutocompleteActionPredictorTable::UpdateRow( const AutocompleteActionPredictorTable::Row& row) { - CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::DB)); + DCHECK(GetTaskRunner()->RunsTasksInCurrentSequence()); if (CantAccessDatabase()) return; @@ -131,7 +132,7 @@ void AutocompleteActionPredictorTable::AddAndUpdateRows( const Rows& rows_to_add, const Rows& rows_to_update) { - CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::DB)); + DCHECK(GetTaskRunner()->RunsTasksInCurrentSequence()); if (CantAccessDatabase()) return; @@ -179,7 +180,7 @@ void AutocompleteActionPredictorTable::DeleteRows( const std::vector<Row::Id>& id_list) { - CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::DB)); + DCHECK(GetTaskRunner()->RunsTasksInCurrentSequence()); if (CantAccessDatabase()) return; @@ -206,7 +207,7 @@ } void AutocompleteActionPredictorTable::DeleteAllRows() { - CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::DB)); + DCHECK(GetTaskRunner()->RunsTasksInCurrentSequence()); if (CantAccessDatabase()) return; @@ -219,15 +220,14 @@ statement.Run(); } -AutocompleteActionPredictorTable::AutocompleteActionPredictorTable() - : PredictorTableBase() { -} +AutocompleteActionPredictorTable::AutocompleteActionPredictorTable( + scoped_refptr<base::SequencedTaskRunner> db_task_runner) + : PredictorTableBase(std::move(db_task_runner)) {} -AutocompleteActionPredictorTable::~AutocompleteActionPredictorTable() { -} +AutocompleteActionPredictorTable::~AutocompleteActionPredictorTable() = default; void AutocompleteActionPredictorTable::CreateTableIfNonExistent() { - CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::DB)); + DCHECK(GetTaskRunner()->RunsTasksInCurrentSequence()); if (CantAccessDatabase()) return; @@ -246,7 +246,7 @@ } void AutocompleteActionPredictorTable::LogDatabaseStats() { - CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::DB)); + DCHECK(GetTaskRunner()->RunsTasksInCurrentSequence()); if (CantAccessDatabase()) return;
diff --git a/chrome/browser/predictors/autocomplete_action_predictor_table.h b/chrome/browser/predictors/autocomplete_action_predictor_table.h index 425c4b01..e4622db 100644 --- a/chrome/browser/predictors/autocomplete_action_predictor_table.h +++ b/chrome/browser/predictors/autocomplete_action_predictor_table.h
@@ -32,7 +32,7 @@ // would allow DeleteOldEntries to be cheaper through use of a join. // // All the functions apart from constructor and destructor have to be called in -// the DB thread. +// the DB sequence provided to the constructor of this class. class AutocompleteActionPredictorTable : public PredictorTableBase { public: struct Row { @@ -62,7 +62,7 @@ typedef std::vector<Row> Rows; - // DB thread functions. + // DB sequence functions. void GetRow(const Row::Id& id, Row* row); void GetAllRows(Rows* row_buffer); void AddRow(const Row& row); @@ -74,10 +74,11 @@ private: friend class PredictorDatabaseInternal; - AutocompleteActionPredictorTable(); + explicit AutocompleteActionPredictorTable( + scoped_refptr<base::SequencedTaskRunner> db_task_runner); ~AutocompleteActionPredictorTable() override; - // PredictorTableBase methods (DB thread). + // PredictorTableBase methods (DB sequence). void CreateTableIfNonExistent() override; void LogDatabaseStats() override;
diff --git a/chrome/browser/predictors/autocomplete_action_predictor_table_unittest.cc b/chrome/browser/predictors/autocomplete_action_predictor_table_unittest.cc index f4598be1..e480259 100644 --- a/chrome/browser/predictors/autocomplete_action_predictor_table_unittest.cc +++ b/chrome/browser/predictors/autocomplete_action_predictor_table_unittest.cc
@@ -4,25 +4,24 @@ #include <stddef.h> +#include <memory> #include <vector> -#include "base/message_loop/message_loop.h" -#include "base/run_loop.h" #include "base/strings/utf_string_conversions.h" +#include "base/threading/sequenced_task_runner_handle.h" #include "base/time/time.h" #include "chrome/browser/predictors/autocomplete_action_predictor_table.h" #include "chrome/browser/predictors/predictor_database.h" #include "chrome/browser/predictors/predictor_database_factory.h" #include "chrome/test/base/testing_profile.h" -#include "content/public/test/test_browser_thread.h" #include "content/public/test/test_browser_thread_bundle.h" +#include "content/public/test/test_utils.h" #include "sql/statement.h" #include "testing/gtest/include/gtest/gtest.h" using base::Time; using base::TimeDelta; -using content::BrowserThread; using predictors::AutocompleteActionPredictorTable; namespace predictors { @@ -45,7 +44,6 @@ TestingProfile* profile() { return &profile_; } protected: - // Test functions that can be run against this text fixture or // AutocompleteActionPredictorTableReopenTest that inherits from this. void TestGetRow(); @@ -79,8 +77,9 @@ } void AutocompleteActionPredictorTableTest::SetUp() { - db_.reset(new PredictorDatabase(&profile_)); - base::RunLoop().RunUntilIdle(); + db_ = base::MakeUnique<PredictorDatabase>( + &profile_, base::SequencedTaskRunnerHandle::Get()); + content::RunAllBlockingPoolTasksUntilIdle(); test_db_.push_back(AutocompleteActionPredictorTable::Row( "BD85DBA2-8C29-49F9-84AE-48E1E90880DF", @@ -97,8 +96,8 @@ } void AutocompleteActionPredictorTableTest::TearDown() { - db_.reset(NULL); - base::RunLoop().RunUntilIdle(); + db_ = nullptr; + content::RunAllBlockingPoolTasksUntilIdle(); test_db_.clear(); }
diff --git a/chrome/browser/predictors/autocomplete_action_predictor_unittest.cc b/chrome/browser/predictors/autocomplete_action_predictor_unittest.cc index 7c9bed4dd..b7279893 100644 --- a/chrome/browser/predictors/autocomplete_action_predictor_unittest.cc +++ b/chrome/browser/predictors/autocomplete_action_predictor_unittest.cc
@@ -5,6 +5,8 @@ #include "chrome/browser/predictors/autocomplete_action_predictor.h" #include <stddef.h> +#include <string> +#include <vector> #include "base/auto_reset.h" #include "base/command_line.h" @@ -27,6 +29,7 @@ #include "components/history/core/browser/url_database.h" #include "components/omnibox/browser/autocomplete_match.h" #include "content/public/test/test_browser_thread_bundle.h" +#include "content/public/test/test_utils.h" #include "testing/gtest/include/gtest/gtest.h" using base::ASCIIToUTF16; @@ -88,13 +91,8 @@ class AutocompleteActionPredictorTest : public testing::Test { public: AutocompleteActionPredictorTest() - : profile_(new TestingProfile()), predictor_(nullptr) {} - - ~AutocompleteActionPredictorTest() override { - predictor_.reset(NULL); - profile_.reset(NULL); - base::RunLoop().RunUntilIdle(); - } + : profile_(base::MakeUnique<TestingProfile>()), predictor_(nullptr) {} + ~AutocompleteActionPredictorTest() override = default; void SetUp() override { base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( @@ -102,9 +100,10 @@ switches::kPrerenderFromOmniboxSwitchValueEnabled); ASSERT_TRUE(profile_->CreateHistoryService(true, false)); - predictor_.reset(new AutocompleteActionPredictor(profile_.get())); + predictor_ = base::MakeUnique<AutocompleteActionPredictor>(profile_.get()); predictor_->CreateLocalCachesFromDatabase(); profile_->BlockUntilHistoryProcessesPendingRequests(); + content::RunAllBlockingPoolTasksUntilIdle(); ASSERT_TRUE(predictor_->initialized_); ASSERT_TRUE(db_cache()->empty());
diff --git a/chrome/browser/predictors/glowplug_key_value_data.h b/chrome/browser/predictors/glowplug_key_value_data.h index bfb416c..6abd994f2 100644 --- a/chrome/browser/predictors/glowplug_key_value_data.h +++ b/chrome/browser/predictors/glowplug_key_value_data.h
@@ -5,9 +5,11 @@ #ifndef CHROME_BROWSER_PREDICTORS_GLOWPLUG_KEY_VALUE_DATA_H_ #define CHROME_BROWSER_PREDICTORS_GLOWPLUG_KEY_VALUE_DATA_H_ +#include <algorithm> #include <map> #include <memory> #include <string> +#include <utility> #include <vector> #include "base/location.h" @@ -26,8 +28,9 @@ // the memory. The cache size is limited by max_size parameter using Compare // function to decide which entry should be evicted. // -// InitializeOnDBThread() must be called on DB thread. All other methods must be -// called on UI thread. +// InitializeOnDBSequence() must be called on the DB sequence of the +// ResourcePrefetchPredictorTables. All other methods must be called on UI +// thread. template <typename T, typename Compare> class GlowplugKeyValueData { public: @@ -35,8 +38,9 @@ GlowplugKeyValueTable<T>* backend, size_t max_size); - // Must be called on DB thread before calling all other methods. - void InitializeOnDBThread(); + // Must be called on the DB sequence of the ResourcePrefetchPredictorTables + // before calling all other methods. + void InitializeOnDBSequence(); // Assigns data associated with the |key| to |data|. Returns true iff the // |key| exists, false otherwise. |data| pointer may be nullptr to get the @@ -85,10 +89,10 @@ } template <typename T, typename Compare> -void GlowplugKeyValueData<T, Compare>::InitializeOnDBThread() { - DCHECK_CURRENTLY_ON(content::BrowserThread::DB); +void GlowplugKeyValueData<T, Compare>::InitializeOnDBSequence() { + DCHECK(tables_->GetTaskRunner()->RunsTasksInCurrentSequence()); auto data_map = base::MakeUnique<std::map<std::string, T>>(); - tables_->ExecuteDBTaskOnDBThread( + tables_->ExecuteDBTaskOnDBSequence( base::BindOnce(&GlowplugKeyValueTable<T>::GetAllData, base::Unretained(backend_table_), data_map.get())); @@ -101,7 +105,7 @@ data_map->erase(entry_to_delete); } if (keys_to_delete.size() > 0) { - tables_->ExecuteDBTaskOnDBThread(base::BindOnce( + tables_->ExecuteDBTaskOnDBSequence(base::BindOnce( &GlowplugKeyValueTable<T>::DeleteData, base::Unretained(backend_table_), std::vector<std::string>(keys_to_delete))); }
diff --git a/chrome/browser/predictors/glowplug_key_value_table.h b/chrome/browser/predictors/glowplug_key_value_table.h index cdf5019..7b0cbcc 100644 --- a/chrome/browser/predictors/glowplug_key_value_table.h +++ b/chrome/browser/predictors/glowplug_key_value_table.h
@@ -38,7 +38,8 @@ // always consists of two columns, TEXT type "key" and BLOB type "proto". The // class doesn't manage the creation and the deletion of the table. // -// All the functions except of the constructor must be called on a DB thread. +// All the functions except of the constructor must be called on a DB sequence +// of the ResourcePrefetchPredictorTables. // The preferred way to call the methods of this class is passing the method to // ResourcePrefetchPredictorTables::ScheduleDBTask(). //
diff --git a/chrome/browser/predictors/loading_data_collector_unittest.cc b/chrome/browser/predictors/loading_data_collector_unittest.cc index 736c43f..0a549b9 100644 --- a/chrome/browser/predictors/loading_data_collector_unittest.cc +++ b/chrome/browser/predictors/loading_data_collector_unittest.cc
@@ -8,13 +8,13 @@ #include <memory> #include <utility> -#include "base/run_loop.h" #include "base/test/histogram_tester.h" #include "chrome/browser/history/history_service_factory.h" #include "chrome/browser/predictors/loading_predictor_config.h" #include "chrome/browser/predictors/loading_test_util.h" #include "chrome/test/base/testing_profile.h" #include "content/public/test/test_browser_thread_bundle.h" +#include "content/public/test/test_utils.h" #include "net/http/http_response_headers.h" #include "net/url_request/url_request_context.h" #include "net/url_request/url_request_job.h" @@ -27,7 +27,7 @@ class LoadingDataCollectorTest : public testing::Test { public: - LoadingDataCollectorTest() : profile_(new TestingProfile()) { + LoadingDataCollectorTest() : profile_(base::MakeUnique<TestingProfile>()) { LoadingPredictorConfig config; PopulateTestConfig(&config); mock_predictor_ = @@ -38,7 +38,7 @@ } void SetUp() override { - base::RunLoop().RunUntilIdle(); // Runs the DB lookup. + content::RunAllBlockingPoolTasksUntilIdle(); // Runs the DB lookup. url_request_job_factory_.Reset(); url_request_context_.set_job_factory(&url_request_job_factory_);
diff --git a/chrome/browser/predictors/loading_predictor_unittest.cc b/chrome/browser/predictors/loading_predictor_unittest.cc index 7b25cfaa..89b45192 100644 --- a/chrome/browser/predictors/loading_predictor_unittest.cc +++ b/chrome/browser/predictors/loading_predictor_unittest.cc
@@ -10,11 +10,11 @@ #include <utility> #include <vector> -#include "base/run_loop.h" #include "base/test/histogram_tester.h" #include "chrome/browser/predictors/loading_test_util.h" #include "chrome/test/base/testing_profile.h" #include "content/public/test/test_browser_thread_bundle.h" +#include "content/public/test/test_utils.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -40,8 +40,8 @@ protected: content::TestBrowserThreadBundle thread_bundle_; - std::unique_ptr<LoadingPredictor> predictor_; std::unique_ptr<TestingProfile> profile_; + std::unique_ptr<LoadingPredictor> predictor_; }; LoadingPredictorTest::LoadingPredictorTest() @@ -65,7 +65,7 @@ predictor_->set_mock_resource_prefetch_predictor(std::move(mock)); predictor_->StartInitialization(); - base::RunLoop().RunUntilIdle(); + content::RunAllBlockingPoolTasksUntilIdle(); } void LoadingPredictorTest::TearDown() {
diff --git a/chrome/browser/predictors/loading_stats_collector_unittest.cc b/chrome/browser/predictors/loading_stats_collector_unittest.cc index b34b337..90eae68 100644 --- a/chrome/browser/predictors/loading_stats_collector_unittest.cc +++ b/chrome/browser/predictors/loading_stats_collector_unittest.cc
@@ -5,11 +5,11 @@ #include "chrome/browser/predictors/loading_stats_collector.h" #include "base/memory/ptr_util.h" -#include "base/message_loop/message_loop.h" #include "base/test/histogram_tester.h" #include "chrome/browser/predictors/loading_test_util.h" #include "chrome/test/base/testing_profile.h" #include "content/public/test/test_browser_thread_bundle.h" +#include "content/public/test/test_utils.h" #include "testing/gtest/include/gtest/gtest.h" using testing::_; @@ -54,10 +54,7 @@ LoadingStatsCollectorTest::LoadingStatsCollectorTest() : profile_(base::MakeUnique<TestingProfile>()) {} -LoadingStatsCollectorTest::~LoadingStatsCollectorTest() { - profile_ = nullptr; - base::RunLoop().RunUntilIdle(); -} +LoadingStatsCollectorTest::~LoadingStatsCollectorTest() = default; void LoadingStatsCollectorTest::SetUp() { LoadingPredictorConfig config; @@ -68,7 +65,7 @@ stats_collector_ = base::MakeUnique<LoadingStatsCollector>(mock_predictor_.get(), config); histogram_tester_ = base::MakeUnique<base::HistogramTester>(); - base::RunLoop().RunUntilIdle(); + content::RunAllBlockingPoolTasksUntilIdle(); } void LoadingStatsCollectorTest::TearDown() {
diff --git a/chrome/browser/predictors/predictor_database.cc b/chrome/browser/predictors/predictor_database.cc index 24eafe97..11149a0 100644 --- a/chrome/browser/predictors/predictor_database.cc +++ b/chrome/browser/predictors/predictor_database.cc
@@ -12,6 +12,7 @@ #include "base/files/file_util.h" #include "base/logging.h" #include "base/macros.h" +#include "base/sequenced_task_runner.h" #include "chrome/browser/predictors/autocomplete_action_predictor_table.h" #include "chrome/browser/predictors/loading_predictor_config.h" #include "chrome/browser/predictors/resource_prefetch_predictor.h" @@ -33,21 +34,24 @@ namespace predictors { // Refcounted as it is created, initialized and destroyed on a different thread -// to the DB thread that is required for all methods performing database access. +// to the DB sequence provided to the constructor of this class that is required +// for all methods performing database access. class PredictorDatabaseInternal : public base::RefCountedThreadSafe<PredictorDatabaseInternal> { private: friend class base::RefCountedThreadSafe<PredictorDatabaseInternal>; friend class PredictorDatabase; - explicit PredictorDatabaseInternal(Profile* profile); + explicit PredictorDatabaseInternal( + Profile* profile, + scoped_refptr<base::SequencedTaskRunner> db_task_runner); virtual ~PredictorDatabaseInternal(); // Opens the database file from the profile path. Separated from the // constructor to ease construction/destruction of this object on one thread - // but database access on the DB thread. + // but database access on the DB sequence of |db_task_runner_|. void Initialize(); - void LogDatabaseStats(); // DB Thread. + void LogDatabaseStats(); // DB sequence. // Cancels pending DB transactions. Should only be called on the UI thread. void SetCancelled(); @@ -55,6 +59,7 @@ bool is_loading_predictor_enabled_; base::FilePath db_path_; std::unique_ptr<sql::Connection> db_; + scoped_refptr<base::SequencedTaskRunner> db_task_runner_; // TODO(shishir): These tables may not need to be refcounted. Maybe move them // to using a WeakPtr instead. @@ -64,12 +69,16 @@ DISALLOW_COPY_AND_ASSIGN(PredictorDatabaseInternal); }; - -PredictorDatabaseInternal::PredictorDatabaseInternal(Profile* profile) +PredictorDatabaseInternal::PredictorDatabaseInternal( + Profile* profile, + scoped_refptr<base::SequencedTaskRunner> db_task_runner) : db_path_(profile->GetPath().Append(kPredictorDatabaseName)), - db_(new sql::Connection()), - autocomplete_table_(new AutocompleteActionPredictorTable()), - resource_prefetch_tables_(new ResourcePrefetchPredictorTables()) { + db_(base::MakeUnique<sql::Connection>()), + db_task_runner_(db_task_runner), + autocomplete_table_( + new AutocompleteActionPredictorTable(db_task_runner_)), + resource_prefetch_tables_( + new ResourcePrefetchPredictorTables(db_task_runner_)) { db_->set_histogram_tag("Predictor"); // This db does not use [meta] table, store mmap status data elsewhere. @@ -79,15 +88,13 @@ } PredictorDatabaseInternal::~PredictorDatabaseInternal() { - // The connection pointer needs to be deleted on the DB thread since there - // might be a task in progress on the DB thread which uses this connection. - if (BrowserThread::IsMessageLoopValid(BrowserThread::DB)) - BrowserThread::DeleteSoon(BrowserThread::DB, FROM_HERE, db_.release()); + // The connection pointer needs to be deleted on the DB sequence since there + // might be a task in progress on the DB sequence which uses this connection. + db_task_runner_->DeleteSoon(FROM_HERE, db_.release()); } void PredictorDatabaseInternal::Initialize() { - CHECK(BrowserThread::CurrentlyOn(BrowserThread::DB) || - !BrowserThread::IsMessageLoopValid(BrowserThread::DB)); + DCHECK(db_task_runner_->RunsTasksInCurrentSequence()); // TODO(tburkard): figure out if we need this. // db_->set_exclusive_locking(); bool success = db_->Open(db_path_); @@ -106,27 +113,27 @@ } void PredictorDatabaseInternal::SetCancelled() { - CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || - !BrowserThread::IsMessageLoopValid(BrowserThread::UI)); + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || + !BrowserThread::IsMessageLoopValid(BrowserThread::UI)); autocomplete_table_->SetCancelled(); resource_prefetch_tables_->SetCancelled(); } void PredictorDatabaseInternal::LogDatabaseStats() { - CHECK(BrowserThread::CurrentlyOn(BrowserThread::DB) || - !BrowserThread::IsMessageLoopValid(BrowserThread::DB)); + DCHECK(db_task_runner_->RunsTasksInCurrentSequence()); autocomplete_table_->LogDatabaseStats(); if (is_loading_predictor_enabled_) resource_prefetch_tables_->LogDatabaseStats(); } -PredictorDatabase::PredictorDatabase(Profile* profile) - : db_(new PredictorDatabaseInternal(profile)) { - BrowserThread::PostTask( - BrowserThread::DB, FROM_HERE, - base::BindOnce(&PredictorDatabaseInternal::Initialize, db_)); +PredictorDatabase::PredictorDatabase( + Profile* profile, + scoped_refptr<base::SequencedTaskRunner> db_task_runner) + : db_(new PredictorDatabaseInternal(profile, db_task_runner)) { + db_task_runner->PostTask( + FROM_HERE, base::BindOnce(&PredictorDatabaseInternal::Initialize, db_)); } PredictorDatabase::~PredictorDatabase() {
diff --git a/chrome/browser/predictors/predictor_database.h b/chrome/browser/predictors/predictor_database.h index 4bf4e5e..2aa1e0a 100644 --- a/chrome/browser/predictors/predictor_database.h +++ b/chrome/browser/predictors/predictor_database.h
@@ -11,6 +11,10 @@ class Profile; +namespace base { +class SequencedTaskRunner; +} + namespace sql { class Connection; } @@ -23,7 +27,8 @@ class PredictorDatabase : public KeyedService { public: - explicit PredictorDatabase(Profile* profile); + PredictorDatabase(Profile* profile, + scoped_refptr<base::SequencedTaskRunner> db_task_runner); ~PredictorDatabase() override; scoped_refptr<AutocompleteActionPredictorTable> autocomplete_table();
diff --git a/chrome/browser/predictors/predictor_database_factory.cc b/chrome/browser/predictors/predictor_database_factory.cc index 588847f5..7c80152c 100644 --- a/chrome/browser/predictors/predictor_database_factory.cc +++ b/chrome/browser/predictors/predictor_database_factory.cc
@@ -4,7 +4,10 @@ #include "chrome/browser/predictors/predictor_database_factory.h" +#include <utility> + #include "base/bind.h" +#include "base/task_scheduler/post_task.h" #include "chrome/browser/predictors/predictor_database.h" #include "chrome/browser/profiles/profile.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" @@ -32,7 +35,12 @@ KeyedService* PredictorDatabaseFactory::BuildServiceInstanceFor( content::BrowserContext* profile) const { - return new PredictorDatabase(static_cast<Profile*>(profile)); + scoped_refptr<base::SequencedTaskRunner> db_task_runner = + base::CreateSequencedTaskRunnerWithTraits( + {base::MayBlock(), base::TaskPriority::BACKGROUND, + base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}); + return new PredictorDatabase(static_cast<Profile*>(profile), + std::move(db_task_runner)); } } // namespace predictors
diff --git a/chrome/browser/predictors/predictor_table_base.cc b/chrome/browser/predictors/predictor_table_base.cc index 8175e71d..5e7a35c 100644 --- a/chrome/browser/predictors/predictor_table_base.cc +++ b/chrome/browser/predictors/predictor_table_base.cc
@@ -4,7 +4,10 @@ #include "chrome/browser/predictors/predictor_table_base.h" +#include <utility> + #include "base/logging.h" +#include "base/sequenced_task_runner.h" #include "content/public/browser/browser_thread.h" #include "sql/connection.h" @@ -12,14 +15,19 @@ namespace predictors { -PredictorTableBase::PredictorTableBase() : db_(NULL) { +base::SequencedTaskRunner* PredictorTableBase::GetTaskRunner() { + return db_task_runner_.get(); } +PredictorTableBase::PredictorTableBase( + scoped_refptr<base::SequencedTaskRunner> db_task_runner) + : db_task_runner_(std::move(db_task_runner)), db_(nullptr) {} + PredictorTableBase::~PredictorTableBase() { } void PredictorTableBase::Initialize(sql::Connection* db) { - CHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); + DCHECK(db_task_runner_->RunsTasksInCurrentSequence()); db_ = db; CreateTableIfNonExistent(); } @@ -29,17 +37,17 @@ } sql::Connection* PredictorTableBase::DB() { - CHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); + DCHECK(db_task_runner_->RunsTasksInCurrentSequence()); return db_; } void PredictorTableBase::ResetDB() { - CHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); - db_ = NULL; + DCHECK(db_task_runner_->RunsTasksInCurrentSequence()); + db_ = nullptr; } bool PredictorTableBase::CantAccessDatabase() { - CHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); + DCHECK(db_task_runner_->RunsTasksInCurrentSequence()); return cancelled_.IsSet() || !db_; }
diff --git a/chrome/browser/predictors/predictor_table_base.h b/chrome/browser/predictors/predictor_table_base.h index 601370e..5c0c0e65 100644 --- a/chrome/browser/predictors/predictor_table_base.h +++ b/chrome/browser/predictors/predictor_table_base.h
@@ -9,6 +9,10 @@ #include "base/memory/ref_counted.h" #include "base/synchronization/cancellation_flag.h" +namespace base { +class SequencedTaskRunner; +} + namespace sql { class Connection; } @@ -18,14 +22,20 @@ // Base class for all tables in the PredictorDatabase. // // Refcounted as it is created and destroyed in the UI thread but all database -// related functions need to happen in the database thread. +// related functions need to happen in the database sequence. The task runner +// for this sequence is provided by the client to the constructor of this class. class PredictorTableBase : public base::RefCountedThreadSafe<PredictorTableBase> { + public: + // Returns a SequencedTaskRunner that is used to run tasks on the DB sequence. + base::SequencedTaskRunner* GetTaskRunner(); + protected: - PredictorTableBase(); + explicit PredictorTableBase( + scoped_refptr<base::SequencedTaskRunner> db_task_runner); virtual ~PredictorTableBase(); - // DB thread functions. + // DB sequence functions. virtual void CreateTableIfNonExistent() = 0; virtual void LogDatabaseStats() = 0; void Initialize(sql::Connection* db); @@ -40,6 +50,7 @@ friend class base::RefCountedThreadSafe<PredictorTableBase>; + scoped_refptr<base::SequencedTaskRunner> db_task_runner_; sql::Connection* db_; DISALLOW_COPY_AND_ASSIGN(PredictorTableBase);
diff --git a/chrome/browser/predictors/resource_prefetch_predictor.cc b/chrome/browser/predictors/resource_prefetch_predictor.cc index 46119b8..bee77f4 100644 --- a/chrome/browser/predictors/resource_prefetch_predictor.cc +++ b/chrome/browser/predictors/resource_prefetch_predictor.cc
@@ -107,17 +107,17 @@ GetUrlVisitCountTask::~GetUrlVisitCountTask() {} -void InitializeOnDBThread( +void InitializeOnDBSequence( ResourcePrefetchPredictor::PrefetchDataMap* url_resource_data, ResourcePrefetchPredictor::PrefetchDataMap* host_resource_data, ResourcePrefetchPredictor::RedirectDataMap* url_redirect_data, ResourcePrefetchPredictor::RedirectDataMap* host_redirect_data, ResourcePrefetchPredictor::OriginDataMap* origin_data) { - url_resource_data->InitializeOnDBThread(); - host_resource_data->InitializeOnDBThread(); - url_redirect_data->InitializeOnDBThread(); - host_redirect_data->InitializeOnDBThread(); - origin_data->InitializeOnDBThread(); + url_resource_data->InitializeOnDBSequence(); + host_resource_data->InitializeOnDBSequence(); + url_redirect_data->InitializeOnDBSequence(); + host_redirect_data->InitializeOnDBSequence(); + origin_data->InitializeOnDBSequence(); } } // namespace @@ -226,7 +226,7 @@ // Get raw pointers to pass to the first task. Ownership of the unique_ptrs // will be passed to the reply task. - auto task = base::BindOnce(InitializeOnDBThread, url_resource_data.get(), + auto task = base::BindOnce(InitializeOnDBSequence, url_resource_data.get(), host_resource_data.get(), url_redirect_data.get(), host_redirect_data.get(), origin_data.get()); auto reply = base::BindOnce( @@ -235,8 +235,8 @@ std::move(url_redirect_data), std::move(host_redirect_data), std::move(origin_data)); - BrowserThread::PostTaskAndReply(BrowserThread::DB, FROM_HERE, std::move(task), - std::move(reply)); + tables_->GetTaskRunner()->PostTaskAndReply(FROM_HERE, std::move(task), + std::move(reply)); } bool ResourcePrefetchPredictor::IsUrlPrefetchable(
diff --git a/chrome/browser/predictors/resource_prefetch_predictor.h b/chrome/browser/predictors/resource_prefetch_predictor.h index 66fbb756..d832f6c 100644 --- a/chrome/browser/predictors/resource_prefetch_predictor.h +++ b/chrome/browser/predictors/resource_prefetch_predictor.h
@@ -85,11 +85,11 @@ // LoadingDataCollector on the UI thread. This is owned by the ProfileIOData // for the profile. // * ResourcePrefetchPredictorTables - Persists ResourcePrefetchPredictor data -// to a sql database. Runs entirely on the DB thread. Owned by the -// PredictorDatabase. +// to a sql database. Runs entirely on the DB sequence provided by the client +// to the constructor of this class. Owned by the PredictorDatabase. // * ResourcePrefetchPredictor - Learns about resource requirements per URL in -// the UI thread through the LoadingPredictorObserver and persists -// it to disk in the DB thread through the ResourcePrefetchPredictorTables. It +// the UI thread through the LoadingPredictorObserver and persists it to disk +// in the DB sequence through the ResourcePrefetchPredictorTables. It // initiates resource prefetching using the ResourcePrefetcherManager. Owned // by profile. class ResourcePrefetchPredictor : public history::HistoryServiceObserver { @@ -132,8 +132,9 @@ Profile* profile); ~ResourcePrefetchPredictor() override; - // Starts initialization by posting a task to the DB thread to read the - // predictor database. Virtual for testing. + // Starts initialization by posting a task to the DB sequence of the + // ResourcePrefetchPredictorTables to read the predictor database. Virtual for + // testing. virtual void StartInitialization(); virtual void Shutdown();
diff --git a/chrome/browser/predictors/resource_prefetch_predictor_tables.cc b/chrome/browser/predictors/resource_prefetch_predictor_tables.cc index 0ee56dd..c0b285d4 100644 --- a/chrome/browser/predictors/resource_prefetch_predictor_tables.cc +++ b/chrome/browser/predictors/resource_prefetch_predictor_tables.cc
@@ -11,7 +11,6 @@ #include "base/metrics/histogram_macros.h" #include "base/strings/stringprintf.h" #include "base/trace_event/trace_event.h" -#include "content/public/browser/browser_thread.h" #include "sql/statement.h" using google::protobuf::MessageLite; @@ -55,8 +54,6 @@ namespace predictors { -using content::BrowserThread; - // static void ResourcePrefetchPredictorTables::TrimResources( PrefetchData* data, @@ -114,7 +111,9 @@ }); } -ResourcePrefetchPredictorTables::ResourcePrefetchPredictorTables() { +ResourcePrefetchPredictorTables::ResourcePrefetchPredictorTables( + scoped_refptr<base::SequencedTaskRunner> db_task_runner) + : PredictorTableBase(db_task_runner) { url_resource_table_ = base::MakeUnique<GlowplugKeyValueTable<PrefetchData>>( kUrlResourceTableName); url_redirect_table_ = base::MakeUnique<GlowplugKeyValueTable<RedirectData>>( @@ -187,14 +186,15 @@ void ResourcePrefetchPredictorTables::ScheduleDBTask( const tracked_objects::Location& from_here, DBTask task) { - BrowserThread::PostTask( - BrowserThread::DB, from_here, - base::BindOnce(&ResourcePrefetchPredictorTables::ExecuteDBTaskOnDBThread, - this, std::move(task))); + GetTaskRunner()->PostTask( + from_here, + base::BindOnce( + &ResourcePrefetchPredictorTables::ExecuteDBTaskOnDBSequence, this, + std::move(task))); } -void ResourcePrefetchPredictorTables::ExecuteDBTaskOnDBThread(DBTask task) { - DCHECK_CURRENTLY_ON(BrowserThread::DB); +void ResourcePrefetchPredictorTables::ExecuteDBTaskOnDBSequence(DBTask task) { + DCHECK(GetTaskRunner()->RunsTasksInCurrentSequence()); if (CantAccessDatabase()) return; @@ -288,7 +288,7 @@ } void ResourcePrefetchPredictorTables::CreateTableIfNonExistent() { - DCHECK_CURRENTLY_ON(BrowserThread::DB); + DCHECK(GetTaskRunner()->RunsTasksInCurrentSequence()); if (CantAccessDatabase()) return; @@ -317,7 +317,7 @@ } void ResourcePrefetchPredictorTables::LogDatabaseStats() { - DCHECK_CURRENTLY_ON(BrowserThread::DB); + DCHECK(GetTaskRunner()->RunsTasksInCurrentSequence()); if (CantAccessDatabase()) return;
diff --git a/chrome/browser/predictors/resource_prefetch_predictor_tables.h b/chrome/browser/predictors/resource_prefetch_predictor_tables.h index adb9e6f..f7ab5d6f 100644 --- a/chrome/browser/predictors/resource_prefetch_predictor_tables.h +++ b/chrome/browser/predictors/resource_prefetch_predictor_tables.h
@@ -25,7 +25,7 @@ namespace predictors { // Interface for database tables used by the ResourcePrefetchPredictor. -// All methods except the constructor and destructor need to be called on the DB +// All methods except the ExecuteDBTaskOnDBSequence need to be called on the UI // thread. // // Currently manages: @@ -41,7 +41,7 @@ virtual void ScheduleDBTask(const tracked_objects::Location& from_here, DBTask task); - virtual void ExecuteDBTaskOnDBThread(DBTask task); + virtual void ExecuteDBTaskOnDBSequence(DBTask task); virtual GlowplugKeyValueTable<PrefetchData>* url_resource_table(); virtual GlowplugKeyValueTable<RedirectData>* url_redirect_table(); @@ -79,7 +79,8 @@ protected: // Protected for testing. Use PredictorDatabase::resource_prefetch_tables() // instead of this constructor. - ResourcePrefetchPredictorTables(); + ResourcePrefetchPredictorTables( + scoped_refptr<base::SequencedTaskRunner> db_task_runner); ~ResourcePrefetchPredictorTables() override; private:
diff --git a/chrome/browser/predictors/resource_prefetch_predictor_tables_unittest.cc b/chrome/browser/predictors/resource_prefetch_predictor_tables_unittest.cc index ae72502..eca28141 100644 --- a/chrome/browser/predictors/resource_prefetch_predictor_tables_unittest.cc +++ b/chrome/browser/predictors/resource_prefetch_predictor_tables_unittest.cc
@@ -7,14 +7,14 @@ #include <utility> #include <vector> -#include "base/message_loop/message_loop.h" -#include "base/run_loop.h" #include "base/strings/utf_string_conversions.h" +#include "base/threading/sequenced_task_runner_handle.h" #include "chrome/browser/predictors/loading_test_util.h" #include "chrome/browser/predictors/predictor_database.h" #include "chrome/browser/predictors/resource_prefetch_predictor_tables.h" #include "chrome/test/base/testing_profile.h" #include "content/public/test/test_browser_thread_bundle.h" +#include "content/public/test/test_utils.h" #include "net/base/request_priority.h" #include "sql/statement.h" #include "testing/gtest/include/gtest/gtest.h" @@ -33,7 +33,7 @@ void SetUp() override; void TearDown() override; - void DeleteAllData() const; + void DeleteAllData(); void GetAllData(PrefetchDataMap* url_resource_data, PrefetchDataMap* host_resource_data, RedirectDataMap* url_redirect_data, @@ -48,6 +48,7 @@ void TestDeleteAllData(); content::TestBrowserThreadBundle thread_bundle_; + scoped_refptr<base::SequencedTaskRunner> task_runner_; TestingProfile profile_; std::unique_ptr<PredictorDatabase> db_; scoped_refptr<ResourcePrefetchPredictorTables> tables_; @@ -101,9 +102,10 @@ }; ResourcePrefetchPredictorTablesTest::ResourcePrefetchPredictorTablesTest() - : db_(new PredictorDatabase(&profile_)), + : task_runner_(base::SequencedTaskRunnerHandle::Get()), + db_(base::MakeUnique<PredictorDatabase>(&profile_, task_runner_)), tables_(db_->resource_prefetch_tables()) { - base::RunLoop().RunUntilIdle(); + content::RunAllBlockingPoolTasksUntilIdle(); } ResourcePrefetchPredictorTablesTest::~ResourcePrefetchPredictorTablesTest() { @@ -112,12 +114,13 @@ void ResourcePrefetchPredictorTablesTest::SetUp() { DeleteAllData(); InitializeSampleData(); + content::RunAllBlockingPoolTasksUntilIdle(); } void ResourcePrefetchPredictorTablesTest::TearDown() { tables_ = nullptr; - db_.reset(); - base::RunLoop().RunUntilIdle(); + db_ = nullptr; + content::RunAllBlockingPoolTasksUntilIdle(); } void ResourcePrefetchPredictorTablesTest::TestGetAllData() { @@ -139,24 +142,24 @@ std::vector<std::string> urls_to_delete = {"http://www.google.com", "http://www.yahoo.com"}; std::vector<std::string> hosts_to_delete = {"www.yahoo.com"}; - tables_->ExecuteDBTaskOnDBThread(base::BindOnce( + tables_->ExecuteDBTaskOnDBSequence(base::BindOnce( &GlowplugKeyValueTable<PrefetchData>::DeleteData, base::Unretained(tables_->url_resource_table()), urls_to_delete)); - tables_->ExecuteDBTaskOnDBThread(base::BindOnce( + tables_->ExecuteDBTaskOnDBSequence(base::BindOnce( &GlowplugKeyValueTable<PrefetchData>::DeleteData, base::Unretained(tables_->host_resource_table()), hosts_to_delete)); urls_to_delete = {"http://fb.com/google", "http://google.com"}; hosts_to_delete = {"microsoft.com"}; - tables_->ExecuteDBTaskOnDBThread(base::BindOnce( + tables_->ExecuteDBTaskOnDBSequence(base::BindOnce( &GlowplugKeyValueTable<RedirectData>::DeleteData, base::Unretained(tables_->url_redirect_table()), urls_to_delete)); - tables_->ExecuteDBTaskOnDBThread(base::BindOnce( + tables_->ExecuteDBTaskOnDBSequence(base::BindOnce( &GlowplugKeyValueTable<RedirectData>::DeleteData, base::Unretained(tables_->host_redirect_table()), hosts_to_delete)); hosts_to_delete = {"twitter.com"}; - tables_->ExecuteDBTaskOnDBThread(base::BindOnce( + tables_->ExecuteDBTaskOnDBSequence(base::BindOnce( &GlowplugKeyValueTable<OriginData>::DeleteData, base::Unretained(tables_->origin_table()), hosts_to_delete)); @@ -201,7 +204,7 @@ google.add_resources(), "http://www.resources.google.com/script.js", content::RESOURCE_TYPE_SCRIPT, 12, 0, 0, 8.5, net::MEDIUM, true, true); - tables_->ExecuteDBTaskOnDBThread( + tables_->ExecuteDBTaskOnDBSequence( base::BindOnce(&GlowplugKeyValueTable<PrefetchData>::UpdateData, base::Unretained(tables_->url_resource_table()), google.primary_key(), google)); @@ -211,7 +214,7 @@ yahoo.add_resources(), "http://www.yahoo.com/image.png", content::RESOURCE_TYPE_IMAGE, 120, 1, 1, 10.0, net::MEDIUM, true, false); - tables_->ExecuteDBTaskOnDBThread( + tables_->ExecuteDBTaskOnDBSequence( base::BindOnce(&GlowplugKeyValueTable<PrefetchData>::UpdateData, base::Unretained(tables_->host_resource_table()), yahoo.primary_key(), yahoo)); @@ -220,7 +223,7 @@ InitializeRedirectStat(facebook.add_redirect_endpoints(), "https://facebook.fr/google", 4, 2, 1); - tables_->ExecuteDBTaskOnDBThread( + tables_->ExecuteDBTaskOnDBSequence( base::BindOnce(&GlowplugKeyValueTable<RedirectData>::UpdateData, base::Unretained(tables_->url_redirect_table()), facebook.primary_key(), facebook)); @@ -231,7 +234,7 @@ InitializeRedirectStat(microsoft.add_redirect_endpoints(), "microsoft.org", 7, 2, 0); - tables_->ExecuteDBTaskOnDBThread( + tables_->ExecuteDBTaskOnDBSequence( base::BindOnce(&GlowplugKeyValueTable<RedirectData>::UpdateData, base::Unretained(tables_->host_redirect_table()), microsoft.primary_key(), microsoft)); @@ -239,7 +242,7 @@ OriginData twitter = CreateOriginData("twitter.com"); InitializeOriginStat(twitter.add_origins(), "https://dogs.twitter.com", 10, 1, 0, 12., false, true); - tables_->ExecuteDBTaskOnDBThread(base::BindOnce( + tables_->ExecuteDBTaskOnDBSequence(base::BindOnce( &GlowplugKeyValueTable<OriginData>::UpdateData, base::Unretained(tables_->origin_table()), twitter.host(), twitter)); @@ -452,20 +455,20 @@ m->insert(*it); } -void ResourcePrefetchPredictorTablesTest::DeleteAllData() const { - tables_->ExecuteDBTaskOnDBThread( +void ResourcePrefetchPredictorTablesTest::DeleteAllData() { + tables_->ExecuteDBTaskOnDBSequence( base::BindOnce(&GlowplugKeyValueTable<PrefetchData>::DeleteAllData, base::Unretained(tables_->url_resource_table()))); - tables_->ExecuteDBTaskOnDBThread( + tables_->ExecuteDBTaskOnDBSequence( base::BindOnce(&GlowplugKeyValueTable<RedirectData>::DeleteAllData, base::Unretained(tables_->url_redirect_table()))); - tables_->ExecuteDBTaskOnDBThread( + tables_->ExecuteDBTaskOnDBSequence( base::BindOnce(&GlowplugKeyValueTable<PrefetchData>::DeleteAllData, base::Unretained(tables_->host_resource_table()))); - tables_->ExecuteDBTaskOnDBThread( + tables_->ExecuteDBTaskOnDBSequence( base::BindOnce(&GlowplugKeyValueTable<RedirectData>::DeleteAllData, base::Unretained(tables_->host_redirect_table()))); - tables_->ExecuteDBTaskOnDBThread( + tables_->ExecuteDBTaskOnDBSequence( base::BindOnce(&GlowplugKeyValueTable<OriginData>::DeleteAllData, base::Unretained(tables_->origin_table()))); } @@ -476,19 +479,19 @@ RedirectDataMap* url_redirect_data, RedirectDataMap* host_redirect_data, OriginDataMap* origin_data) const { - tables_->ExecuteDBTaskOnDBThread(base::BindOnce( + tables_->ExecuteDBTaskOnDBSequence(base::BindOnce( &GlowplugKeyValueTable<PrefetchData>::GetAllData, base::Unretained(tables_->url_resource_table()), url_resource_data)); - tables_->ExecuteDBTaskOnDBThread(base::BindOnce( + tables_->ExecuteDBTaskOnDBSequence(base::BindOnce( &GlowplugKeyValueTable<RedirectData>::GetAllData, base::Unretained(tables_->url_redirect_table()), url_redirect_data)); - tables_->ExecuteDBTaskOnDBThread(base::BindOnce( + tables_->ExecuteDBTaskOnDBSequence(base::BindOnce( &GlowplugKeyValueTable<PrefetchData>::GetAllData, base::Unretained(tables_->host_resource_table()), host_resource_data)); - tables_->ExecuteDBTaskOnDBThread(base::BindOnce( + tables_->ExecuteDBTaskOnDBSequence(base::BindOnce( &GlowplugKeyValueTable<RedirectData>::GetAllData, base::Unretained(tables_->host_redirect_table()), host_redirect_data)); - tables_->ExecuteDBTaskOnDBThread( + tables_->ExecuteDBTaskOnDBSequence( base::BindOnce(&GlowplugKeyValueTable<OriginData>::GetAllData, base::Unretained(tables_->origin_table()), origin_data)); } @@ -534,15 +537,15 @@ test_url_data_.insert(std::make_pair(reddit.primary_key(), reddit)); test_url_data_.insert(std::make_pair(yahoo.primary_key(), yahoo)); - tables_->ExecuteDBTaskOnDBThread( + tables_->ExecuteDBTaskOnDBSequence( base::BindOnce(&GlowplugKeyValueTable<PrefetchData>::UpdateData, base::Unretained(tables_->url_resource_table()), google.primary_key(), google)); - tables_->ExecuteDBTaskOnDBThread( + tables_->ExecuteDBTaskOnDBSequence( base::BindOnce(&GlowplugKeyValueTable<PrefetchData>::UpdateData, base::Unretained(tables_->url_resource_table()), reddit.primary_key(), reddit)); - tables_->ExecuteDBTaskOnDBThread( + tables_->ExecuteDBTaskOnDBSequence( base::BindOnce(&GlowplugKeyValueTable<PrefetchData>::UpdateData, base::Unretained(tables_->url_resource_table()), yahoo.primary_key(), yahoo)); @@ -579,11 +582,11 @@ test_host_data_.insert(std::make_pair(facebook.primary_key(), facebook)); test_host_data_.insert(std::make_pair(yahoo.primary_key(), yahoo)); - tables_->ExecuteDBTaskOnDBThread( + tables_->ExecuteDBTaskOnDBSequence( base::BindOnce(&GlowplugKeyValueTable<PrefetchData>::UpdateData, base::Unretained(tables_->host_resource_table()), facebook.primary_key(), facebook)); - tables_->ExecuteDBTaskOnDBThread( + tables_->ExecuteDBTaskOnDBSequence( base::BindOnce(&GlowplugKeyValueTable<PrefetchData>::UpdateData, base::Unretained(tables_->host_resource_table()), yahoo.primary_key(), yahoo)); @@ -612,15 +615,15 @@ test_url_redirect_data_.insert( std::make_pair(google.primary_key(), google)); - tables_->ExecuteDBTaskOnDBThread( + tables_->ExecuteDBTaskOnDBSequence( base::BindOnce(&GlowplugKeyValueTable<RedirectData>::UpdateData, base::Unretained(tables_->url_redirect_table()), facebook.primary_key(), facebook)); - tables_->ExecuteDBTaskOnDBThread( + tables_->ExecuteDBTaskOnDBSequence( base::BindOnce(&GlowplugKeyValueTable<RedirectData>::UpdateData, base::Unretained(tables_->url_redirect_table()), nytimes.primary_key(), nytimes)); - tables_->ExecuteDBTaskOnDBThread( + tables_->ExecuteDBTaskOnDBSequence( base::BindOnce(&GlowplugKeyValueTable<RedirectData>::UpdateData, base::Unretained(tables_->url_redirect_table()), google.primary_key(), google)); @@ -642,11 +645,11 @@ test_host_redirect_data_.insert( std::make_pair(microsoft.primary_key(), microsoft)); - tables_->ExecuteDBTaskOnDBThread( + tables_->ExecuteDBTaskOnDBSequence( base::BindOnce(&GlowplugKeyValueTable<RedirectData>::UpdateData, base::Unretained(tables_->host_redirect_table()), bbc.primary_key(), bbc)); - tables_->ExecuteDBTaskOnDBThread( + tables_->ExecuteDBTaskOnDBSequence( base::BindOnce(&GlowplugKeyValueTable<RedirectData>::UpdateData, base::Unretained(tables_->host_redirect_table()), microsoft.primary_key(), microsoft)); @@ -671,18 +674,18 @@ test_origin_data_.insert({"twitter.com", twitter}); test_origin_data_.insert({"abc.xyz", alphabet}); - tables_->ExecuteDBTaskOnDBThread(base::BindOnce( + tables_->ExecuteDBTaskOnDBSequence(base::BindOnce( &GlowplugKeyValueTable<OriginData>::UpdateData, base::Unretained(tables_->origin_table()), twitter.host(), twitter)); - tables_->ExecuteDBTaskOnDBThread(base::BindOnce( + tables_->ExecuteDBTaskOnDBSequence(base::BindOnce( &GlowplugKeyValueTable<OriginData>::UpdateData, base::Unretained(tables_->origin_table()), alphabet.host(), alphabet)); } } void ResourcePrefetchPredictorTablesTest::ReopenDatabase() { - db_.reset(new PredictorDatabase(&profile_)); - base::RunLoop().RunUntilIdle(); + db_ = base::MakeUnique<PredictorDatabase>(&profile_, task_runner_); + content::RunAllBlockingPoolTasksUntilIdle(); tables_ = db_->resource_prefetch_tables(); }
diff --git a/chrome/browser/predictors/resource_prefetch_predictor_unittest.cc b/chrome/browser/predictors/resource_prefetch_predictor_unittest.cc index f97d6cfb..573661c 100644 --- a/chrome/browser/predictors/resource_prefetch_predictor_unittest.cc +++ b/chrome/browser/predictors/resource_prefetch_predictor_unittest.cc
@@ -10,8 +10,8 @@ #include "base/memory/ptr_util.h" #include "base/memory/ref_counted.h" -#include "base/run_loop.h" #include "base/test/histogram_tester.h" +#include "base/test/test_simple_task_runner.h" #include "base/time/time.h" #include "chrome/browser/history/history_service_factory.h" #include "chrome/browser/predictors/loading_predictor.h" @@ -22,6 +22,7 @@ #include "components/history/core/browser/history_types.h" #include "components/sessions/core/session_id.h" #include "content/public/test/test_browser_thread_bundle.h" +#include "content/public/test/test_utils.h" #include "net/http/http_response_headers.h" #include "net/traffic_annotation/network_traffic_annotation_test_helper.h" #include "net/url_request/url_request_context.h" @@ -64,14 +65,16 @@ class MockResourcePrefetchPredictorTables : public ResourcePrefetchPredictorTables { public: - MockResourcePrefetchPredictorTables() = default; + MockResourcePrefetchPredictorTables( + scoped_refptr<base::SequencedTaskRunner> db_task_runner) + : ResourcePrefetchPredictorTables(std::move(db_task_runner)) {} void ScheduleDBTask(const tracked_objects::Location& from_here, DBTask task) override { - ExecuteDBTaskOnDBThread(std::move(task)); + ExecuteDBTaskOnDBSequence(std::move(task)); } - void ExecuteDBTaskOnDBThread(DBTask task) override { + void ExecuteDBTaskOnDBSequence(DBTask task) override { std::move(task).Run(nullptr); } @@ -139,8 +142,7 @@ void InitializePredictor() { loading_predictor_->StartInitialization(); - base::RunLoop loop; - loop.RunUntilIdle(); // Runs the DB lookup. + db_task_runner_->RunUntilIdle(); profile_->BlockUntilHistoryProcessesPendingRequests(); } @@ -160,6 +162,7 @@ content::TestBrowserThreadBundle thread_bundle_; std::unique_ptr<TestingProfile> profile_; + scoped_refptr<base::TestSimpleTaskRunner> db_task_runner_; net::TestURLRequestContext url_request_context_; std::unique_ptr<LoadingPredictor> loading_predictor_; @@ -179,7 +182,9 @@ ResourcePrefetchPredictorTest::ResourcePrefetchPredictorTest() : profile_(base::MakeUnique<TestingProfile>()), - mock_tables_(new StrictMock<MockResourcePrefetchPredictorTables>()) {} + db_task_runner_(new base::TestSimpleTaskRunner()), + mock_tables_(new StrictMock<MockResourcePrefetchPredictorTables>( + db_task_runner_)) {} ResourcePrefetchPredictorTest::~ResourcePrefetchPredictorTest() = default; @@ -201,7 +206,7 @@ url_request_job_factory_.Reset(); url_request_context_.set_job_factory(&url_request_job_factory_); - histogram_tester_.reset(new base::HistogramTester()); + histogram_tester_ = base::MakeUnique<base::HistogramTester>(); } void ResourcePrefetchPredictorTest::TearDown() {
diff --git a/chrome/browser/prefs/active_profile_pref_service.cc b/chrome/browser/prefs/active_profile_pref_service.cc deleted file mode 100644 index 6023d749..0000000 --- a/chrome/browser/prefs/active_profile_pref_service.cc +++ /dev/null
@@ -1,82 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/prefs/active_profile_pref_service.h" - -#include "chrome/browser/profiles/profile_manager.h" -#include "content/public/browser/browser_context.h" -#include "mojo/public/cpp/bindings/interface_request.h" -#include "services/service_manager/public/cpp/connector.h" -#include "services/service_manager/public/cpp/service_context.h" - -ActiveProfilePrefService::ActiveProfilePrefService() - : connector_binding_(this) { - registry_.AddInterface<prefs::mojom::PrefStoreConnector>( - base::Bind(&ActiveProfilePrefService::Create, base::Unretained(this))); -} - -ActiveProfilePrefService::~ActiveProfilePrefService() = default; - -void ActiveProfilePrefService::Connect( - prefs::mojom::PrefRegistryPtr pref_registry, - ConnectCallback callback) { - GetPrefStoreConnector().Connect(std::move(pref_registry), - std::move(callback)); -} - -void ActiveProfilePrefService::Create( - prefs::mojom::PrefStoreConnectorRequest request) { - connector_binding_.Close(); - connector_binding_.Bind(std::move(request)); -} - -void ActiveProfilePrefService::OnStart() {} - -void ActiveProfilePrefService::OnBindInterface( - const service_manager::BindSourceInfo& source_info, - const std::string& interface_name, - mojo::ScopedMessagePipeHandle interface_pipe) { - // N.B. This check is important as not doing it would allow one user to read - // another user's prefs. - // TODO(beng): This should be obsoleted by Service Manager user id routing. - if (context()->identity().user_id() != source_info.identity.user_id()) { - LOG(WARNING) << "Blocked service instance=" - << source_info.identity.instance() - << ", name=" << source_info.identity.name() - << ", user_id=" << source_info.identity.user_id() - << " from connecting to the active profile's pref service."; - return; - } - registry_.BindInterface(interface_name, std::move(interface_pipe)); -} - -void ActiveProfilePrefService::OnConnectError() { - connector_binding_.Close(); -} - -prefs::mojom::PrefStoreConnector& -ActiveProfilePrefService::GetPrefStoreConnector() { - // The pref service enforces that each service always registers the same set - // of prefs. If the ActiveProfilePrefService connects directly using - // content::BrowserContext::GetConnectorFor(), the pref service will receive - // two connections from |content::mojom::kBrowserServiceName|: one for the - // browser and one from mash, each registering different prefs. - // - // Instead, the prefs::mojom::kForwarderServiceName running as root connects - // to the prefs::mojom::kForwarderServiceName running as the user for the - // active user profile, which then connects to the pref service. Thus, mash - // appears to be |prefs::mojom::kForwarderServiceName| instead of - // |content::mojom::kBrowserServiceName|. - if (context()->identity().user_id() == service_manager::mojom::kRootUserID) { - content::BrowserContext::GetConnectorFor( - ProfileManager::GetActiveUserProfile()->GetOriginalProfile()) - ->BindInterface(prefs::mojom::kForwarderServiceName, &connector_ptr_); - } else if (!connector_ptr_) { - context()->connector()->BindInterface(prefs::mojom::kServiceName, - &connector_ptr_); - } - connector_ptr_.set_connection_error_handler(base::Bind( - &ActiveProfilePrefService::OnConnectError, base::Unretained(this))); - return *connector_ptr_; -}
diff --git a/chrome/browser/prefs/active_profile_pref_service.h b/chrome/browser/prefs/active_profile_pref_service.h deleted file mode 100644 index 66dc88f..0000000 --- a/chrome/browser/prefs/active_profile_pref_service.h +++ /dev/null
@@ -1,55 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_PREFS_ACTIVE_PROFILE_PREF_SERVICE_H_ -#define CHROME_BROWSER_PREFS_ACTIVE_PROFILE_PREF_SERVICE_H_ - -#include <vector> - -#include "base/macros.h" -#include "components/prefs/pref_value_store.h" -#include "mojo/public/cpp/bindings/binding.h" -#include "services/preferences/public/interfaces/preferences.mojom.h" -#include "services/service_manager/public/cpp/binder_registry.h" -#include "services/service_manager/public/cpp/service.h" - -// A |prefs::mojom::PrefStoreConnector| implementation that forwards connection -// calls from the root service to the active profile. Used by mash, which runs -// as the root user, to talk to prefs. -// -// TODO(http://crbug.com/705347): Once mash supports several profiles, remove -// this class and the forwarder service. -class ActiveProfilePrefService : public prefs::mojom::PrefStoreConnector, - public service_manager::Service { - public: - ActiveProfilePrefService(); - ~ActiveProfilePrefService() override; - - private: - // prefs::mojom::PrefStoreConnector: - void Connect(prefs::mojom::PrefRegistryPtr pref_registry, - ConnectCallback callback) override; - - // service_manager::Service: - void OnStart() override; - void OnBindInterface(const service_manager::BindSourceInfo& source_info, - const std::string& interface_name, - mojo::ScopedMessagePipeHandle interface_pipe) override; - - void Create(prefs::mojom::PrefStoreConnectorRequest request); - - // Called if forwarding the connection request to the per-profile service - // instance failed. - void OnConnectError(); - - prefs::mojom::PrefStoreConnector& GetPrefStoreConnector(); - - prefs::mojom::PrefStoreConnectorPtr connector_ptr_; - service_manager::BinderRegistry registry_; - mojo::Binding<prefs::mojom::PrefStoreConnector> connector_binding_; - - DISALLOW_COPY_AND_ASSIGN(ActiveProfilePrefService); -}; - -#endif // CHROME_BROWSER_PREFS_ACTIVE_PROFILE_PREF_SERVICE_H_
diff --git a/chrome/browser/prefs/forwarder_manifest.json b/chrome/browser/prefs/forwarder_manifest.json deleted file mode 100644 index 93a1576..0000000 --- a/chrome/browser/prefs/forwarder_manifest.json +++ /dev/null
@@ -1,16 +0,0 @@ -{ - "name": "preferences_forwarder", - "display_name": "Preferences Forwarder", - "interface_provider_specs": { - "service_manager:connector": { - "provides": { - "pref_client": [ - "prefs::mojom::PrefStoreConnector" - ] - }, - "requires": { - "preferences": [ "pref_client" ] - } - } - } -}
diff --git a/chrome/browser/profiles/avatar_menu.h b/chrome/browser/profiles/avatar_menu.h index cada138..b8afb428 100644 --- a/chrome/browser/profiles/avatar_menu.h +++ b/chrome/browser/profiles/avatar_menu.h
@@ -87,6 +87,20 @@ base::FilePath profile_path; }; + // The load status of an avatar image. + enum class ImageLoadStatus { + // If there is a Gaia image used by the user, it is loaded. Otherwise, a + // default avatar image is loaded. + LOADED = 0, + // There is a Gaia image used by the user, and it's still being loaded. + LOADING, + // There is a Gaia image used by the user, but it cannot be found. A + // default avatar image is loaded instead. + MISSING, + // Nothing is loaded as the profile has been deleted. + PROFILE_DELETED + }; + // Constructor. |observer| can be NULL. |browser| can be NULL and a new one // will be created if an action requires it. AvatarMenu(ProfileAttributesStorage* profile_storage, @@ -98,9 +112,11 @@ static bool ShouldShowAvatarMenu(); // Sets |image| to the avatar corresponding to the profile at |profile_path|. - // For built-in profile avatars, returns the non-high res version. - static void GetImageForMenuButton(const base::FilePath& profile_path, - gfx::Image* image); + // For built-in profile avatars, returns the non-high res version. Returns the + // image load status. + static ImageLoadStatus GetImageForMenuButton( + const base::FilePath& profile_path, + gfx::Image* image); // Opens a Browser with the specified profile in response to the user // selecting an item. If |always_create| is true then a new window is created
diff --git a/chrome/browser/profiles/avatar_menu_desktop.cc b/chrome/browser/profiles/avatar_menu_desktop.cc index 225122b..cd8ec22 100644 --- a/chrome/browser/profiles/avatar_menu_desktop.cc +++ b/chrome/browser/profiles/avatar_menu_desktop.cc
@@ -15,22 +15,34 @@ #include "ui/base/resource/resource_bundle.h" // static -void AvatarMenu::GetImageForMenuButton(const base::FilePath& profile_path, - gfx::Image* image) { +AvatarMenu::ImageLoadStatus AvatarMenu::GetImageForMenuButton( + const base::FilePath& profile_path, + gfx::Image* image) { ProfileAttributesEntry* entry; if (!g_browser_process->profile_manager()->GetProfileAttributesStorage(). GetProfileAttributesWithPath(profile_path, &entry)) { // This can happen if the user deletes the current profile. - return; + return ImageLoadStatus::PROFILE_DELETED; } + ImageLoadStatus status = ImageLoadStatus::LOADED; + // If there is a Gaia image available, try to use that. if (entry->IsUsingGAIAPicture()) { + // TODO(chengx): The GetGAIAPicture API call will trigger an async image + // load from disk if it has not been loaded. This is non-obvious and + // dependency should be avoided. We should come with a better idea to handle + // this. const gfx::Image* gaia_image = entry->GetGAIAPicture(); + if (gaia_image) { *image = *gaia_image; - return; + return ImageLoadStatus::LOADED; } + if (entry->IsGAIAPictureLoaded()) + status = ImageLoadStatus::MISSING; + else + status = ImageLoadStatus::LOADING; } // Otherwise, use the default resource, not the downloaded high-res one. @@ -38,4 +50,6 @@ const int resource_id = profiles::GetDefaultAvatarIconResourceIDAtIndex(icon_index); *image = ResourceBundle::GetSharedInstance().GetNativeImageNamed(resource_id); + + return status; }
diff --git a/chrome/browser/profiles/profile_attributes_entry.cc b/chrome/browser/profiles/profile_attributes_entry.cc index 5165629..4483635 100644 --- a/chrome/browser/profiles/profile_attributes_entry.cc +++ b/chrome/browser/profiles/profile_attributes_entry.cc
@@ -82,6 +82,11 @@ profile_index()); } +bool ProfileAttributesEntry::IsGAIAPictureLoaded() const { + return profile_info_cache_->IsGAIAPictureOfProfileAtIndexLoaded( + profile_index()); +} + bool ProfileAttributesEntry::IsSupervised() const { return profile_info_cache_->ProfileIsSupervisedAtIndex(profile_index()); }
diff --git a/chrome/browser/profiles/profile_attributes_entry.h b/chrome/browser/profiles/profile_attributes_entry.h index 3c98b9992..819ceae6 100644 --- a/chrome/browser/profiles/profile_attributes_entry.h +++ b/chrome/browser/profiles/profile_attributes_entry.h
@@ -60,6 +60,8 @@ // Returns true if the profile displays a GAIA picture instead of one of the // locally bundled icons. bool IsUsingGAIAPicture() const; + // Returns true if a GAIA picture has been loaded or has failed to load. + bool IsGAIAPictureLoaded() const; // Returns true if the profile is signed in as a supervised user.. bool IsSupervised() const; // Returns true if the profile is signed in as a child account.
diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc index 793c947e..3644d25 100644 --- a/chrome/browser/profiles/profile_impl.cc +++ b/chrome/browser/profiles/profile_impl.cc
@@ -28,7 +28,6 @@ #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" -#include "base/synchronization/waitable_event.h" #include "base/task_scheduler/post_task.h" #include "base/task_scheduler/task_traits.h" #include "base/threading/thread_restrictions.h" @@ -217,47 +216,31 @@ } } -// Helper method needed because PostTask cannot currently take a Callback -// function with non-void return type. -void CreateDirectoryAndSignal(const base::FilePath& path, - base::WaitableEvent* done_creating, - bool create_readme) { - // If the readme exists, the profile directory must also already exist. - base::FilePath readme_path = path.Append(chrome::kReadmeFilename); - if (base::PathExists(readme_path)) { - done_creating->Signal(); - return; - } - - DVLOG(1) << "Creating directory " << path.value(); - if (base::CreateDirectory(path) && create_readme) - CreateProfileReadme(path); - done_creating->Signal(); -} - -// Task that blocks the FILE thread until CreateDirectoryAndSignal() finishes on -// the IO task runner. -void BlockFileThreadOnDirectoryCreate(base::WaitableEvent* done_creating) { - done_creating->Wait(); -} - -// Initiates creation of profile directory on |io_task_runner| and ensures that -// FILE thread is blocked until that operation finishes. If |create_readme| is -// true, the profile README will be created in the profile directory. +// Creates the profile directory synchronously if it doesn't exist. If +// |create_readme| is true, the profile README will be created asynchronously in +// the profile directory. void CreateProfileDirectory(base::SequencedTaskRunner* io_task_runner, const base::FilePath& path, bool create_readme) { - base::WaitableEvent* done_creating = - new base::WaitableEvent(base::WaitableEvent::ResetPolicy::AUTOMATIC, - base::WaitableEvent::InitialState::NOT_SIGNALED); - io_task_runner->PostTask( - FROM_HERE, base::BindOnce(&CreateDirectoryAndSignal, path, done_creating, - create_readme)); - // Block the FILE thread until directory is created on I/O task runner to make - // sure that we don't attempt any operation until that part completes. - BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, - base::BindOnce(&BlockFileThreadOnDirectoryCreate, - base::Owned(done_creating))); + // Create the profile directory synchronously otherwise we would need to + // sequence every otherwise independent I/O operation inside the profile + // directory with this operation. base::PathExists() and + // base::CreateDirectory() should be lightweight I/O operations and avoiding + // the headache of sequencing all otherwise unrelated I/O after these + // justifies running them on the main thread. + base::ThreadRestrictions::ScopedAllowIO allow_io_to_create_directory; + + // If the readme exists, the profile directory must also already exist. + if (base::PathExists(path.Append(chrome::kReadmeFilename))) + return; + + DVLOG(1) << "Creating directory " << path.value(); + if (base::CreateDirectory(path) && create_readme) { + base::PostTaskWithTraits(FROM_HERE, + {base::MayBlock(), base::TaskPriority::BACKGROUND, + base::TaskShutdownBehavior::BLOCK_SHUTDOWN}, + base::Bind(&CreateProfileReadme, path)); + } } base::FilePath GetMediaCachePath(const base::FilePath& base) {
diff --git a/chrome/browser/profiles/profile_info_cache.cc b/chrome/browser/profiles/profile_info_cache.cc index 6caa5a4..f775895c 100644 --- a/chrome/browser/profiles/profile_info_cache.cc +++ b/chrome/browser/profiles/profile_info_cache.cc
@@ -476,6 +476,11 @@ return value; } +bool ProfileInfoCache::IsGAIAPictureOfProfileAtIndexLoaded(size_t index) const { + return cached_avatar_images_.count( + CacheKeyFromProfilePath(GetPathOfProfileAtIndex(index))); +} + size_t ProfileInfoCache::GetAvatarIconIndexOfProfileAtIndex(size_t index) const { std::string icon_url;
diff --git a/chrome/browser/profiles/profile_info_cache.h b/chrome/browser/profiles/profile_info_cache.h index 26fdbe9..6a1cabf3 100644 --- a/chrome/browser/profiles/profile_info_cache.h +++ b/chrome/browser/profiles/profile_info_cache.h
@@ -108,6 +108,10 @@ bool ProfileIsUsingDefaultAvatarAtIndex(size_t index) const override; bool ProfileIsAuthErrorAtIndex(size_t index) const; + // Returns true if a GAIA picture has been loaded or has failed to load for + // profile at |index|. + bool IsGAIAPictureOfProfileAtIndexLoaded(size_t index) const; + size_t GetAvatarIconIndexOfProfileAtIndex(size_t index) const; void SetProfileActiveTimeAtIndex(size_t index);
diff --git a/chrome/browser/profiles/profile_info_cache_unittest.cc b/chrome/browser/profiles/profile_info_cache_unittest.cc index 59c193b..43db15b 100644 --- a/chrome/browser/profiles/profile_info_cache_unittest.cc +++ b/chrome/browser/profiles/profile_info_cache_unittest.cc
@@ -18,6 +18,7 @@ #include "base/time/time.h" #include "build/build_config.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/profiles/avatar_menu.h" #include "chrome/browser/profiles/profile_avatar_downloader.h" #include "chrome/browser/profiles/profile_avatar_icon_util.h" #include "chrome/browser/profiles/profile_info_cache.h" @@ -775,6 +776,50 @@ EXPECT_EQ(name_5, GetCache()->GetNameOfProfileAtIndex( GetCache()->GetIndexOfProfileWithPath(path_5))); } + +TEST_F(ProfileInfoCacheTest, GetGaiaImageForAvatarMenu) { + // The TestingProfileManager's ProfileInfoCache doesn't download avatars. + ProfileInfoCache profile_info_cache( + g_browser_process->local_state(), + testing_profile_manager_.profile_manager()->user_data_dir()); + + base::FilePath profile_path = GetProfilePath("path_1"); + + GetCache()->AddProfileToCache(profile_path, ASCIIToUTF16("name_1"), + std::string(), base::string16(), 0, + std::string()); + + gfx::Image gaia_image(gfx::test::CreateImage()); + GetCache()->SetGAIAPictureOfProfileAtIndex(0, &gaia_image); + + // Make sure everything has completed, and the file has been written to disk. + content::RunAllBlockingPoolTasksUntilIdle(); + + // Make sure this profile is using GAIA picture. + EXPECT_TRUE(GetCache()->IsUsingGAIAPictureOfProfileAtIndex(0)); + + ResetCache(); + + // We need to explicitly set the GAIA usage flag after resetting the cache. + GetCache()->SetIsUsingGAIAPictureOfProfileAtIndex(0, true); + EXPECT_TRUE(GetCache()->IsUsingGAIAPictureOfProfileAtIndex(0)); + + gfx::Image image_loaded; + + // Try to get the GAIA image. For the first time, it triggers an async image + // load from disk. The load status indicates the image is still being loaded. + EXPECT_EQ(AvatarMenu::ImageLoadStatus::LOADING, + AvatarMenu::GetImageForMenuButton(profile_path, &image_loaded)); + EXPECT_FALSE(gfx::test::AreImagesEqual(gaia_image, image_loaded)); + + // Wait until the async image load finishes. + content::RunAllBlockingPoolTasksUntilIdle(); + + // Since the GAIA image is loaded now, we can get it this time. + EXPECT_EQ(AvatarMenu::ImageLoadStatus::LOADED, + AvatarMenu::GetImageForMenuButton(profile_path, &image_loaded)); + EXPECT_TRUE(gfx::test::AreImagesEqual(gaia_image, image_loaded)); +} #endif #if defined(OS_CHROMEOS) || defined(OS_ANDROID)
diff --git a/chrome/browser/profiles/profile_manager_unittest.cc b/chrome/browser/profiles/profile_manager_unittest.cc index a3595c2d..67b6ed4 100644 --- a/chrome/browser/profiles/profile_manager_unittest.cc +++ b/chrome/browser/profiles/profile_manager_unittest.cc
@@ -14,6 +14,7 @@ #include "base/memory/ptr_util.h" #include "base/run_loop.h" #include "base/strings/utf_string_conversions.h" +#include "base/threading/thread_task_runner_handle.h" #include "base/values.h" #include "build/build_config.h" #include "chrome/browser/bookmarks/bookmark_model_factory.h" @@ -61,7 +62,6 @@ #endif // defined(OS_CHROMEOS) using base::ASCIIToUTF16; -using content::BrowserThread; namespace { @@ -85,9 +85,10 @@ Profile* CreateProfileAsyncHelper(const base::FilePath& path, Delegate* delegate) override { - // This is safe while all file operations are done on the FILE thread. - BrowserThread::PostTask( - BrowserThread::FILE, FROM_HERE, + // ThreadTaskRunnerHandle::Get() is TestingProfile's "async" IOTaskRunner + // (ref. TestingProfile::GetIOTaskRunner()). + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(base::IgnoreResult(&base::CreateDirectory), path)); return new TestingProfile(path, this);
diff --git a/chrome/browser/resource_coordinator/tab_manager.cc b/chrome/browser/resource_coordinator/tab_manager.cc index bec1740..7c11cab3 100644 --- a/chrome/browser/resource_coordinator/tab_manager.cc +++ b/chrome/browser/resource_coordinator/tab_manager.cc
@@ -918,8 +918,8 @@ // Discard the old tab's renderer. // TODO(jamescook): This breaks script connections with other tabs. - // Find a different approach that doesn't do that, perhaps based on navigation - // to swappedout://. + // Find a different approach that doesn't do that, perhaps based on + // RenderFrameProxyHosts. delete old_contents; recent_tab_discard_ = true;
diff --git a/chrome/browser/resources/BUILD.gn b/chrome/browser/resources/BUILD.gn index d95ce22..39e356bf 100644 --- a/chrome/browser/resources/BUILD.gn +++ b/chrome/browser/resources/BUILD.gn
@@ -123,18 +123,6 @@ } } -if (is_chromeos) { - grit("options_resources") { - source = "options_resources.grd" - defines = chrome_grit_defines - outputs = [ - "grit/options_resources.h", - "options_resources.pak", - ] - output_dir = "$root_gen_dir/chrome" - } -} - if (enable_extensions) { grit("sync_file_system_internals_resources") { source = "sync_file_system_internals_resources.grd"
diff --git a/chrome/browser/resources/OWNERS b/chrome/browser/resources/OWNERS index f005d38..7dc0fd026 100644 --- a/chrome/browser/resources/OWNERS +++ b/chrome/browser/resources/OWNERS
@@ -1,7 +1,6 @@ file://ui/webui/PLATFORM_OWNERS per-file component_extension_resources.grd=dgozman@chromium.org -per-file options_resources.grd=file://chrome/browser/resources/options/OWNERS per-file profile_signin_confirmation*=achuith@chromium.org per-file snippets_internals*=file://components/ntp_snippets/OWNERS per-file sync_file_system_internals_resources.*=tzik@chromium.org
diff --git a/chrome/browser/resources/chromeos/bluetooth_pair_device.html b/chrome/browser/resources/chromeos/bluetooth_pair_device.html index d977202..911237c3 100644 --- a/chrome/browser/resources/chromeos/bluetooth_pair_device.html +++ b/chrome/browser/resources/chromeos/bluetooth_pair_device.html
@@ -4,10 +4,10 @@ <head> <meta charset="utf-8"> <link rel="import" href="chrome://bluetooth-pairing/bluetooth_dialog_host.html"> - - <script src="chrome://resources/js/cr.js"></script> - <script src="chrome://resources/js/load_time_data.js"></script> - <script src="chrome://resources/js/util.js"></script> + <link rel="import" href="chrome://resources/html/cr.html"></script> + <link rel="import" href="chrome://resources/html/load_time_data.html"></script> + <link rel="import" href="chrome://resources/html/util.html"></script> + <link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css"> <script src="chrome://bluetooth-pairing/strings.js"></script> </head>
diff --git a/chrome/browser/resources/chromeos/compiled_resources2.gyp b/chrome/browser/resources/chromeos/compiled_resources2.gyp index f5836b4..e166fcf4 100644 --- a/chrome/browser/resources/chromeos/compiled_resources2.gyp +++ b/chrome/browser/resources/chromeos/compiled_resources2.gyp
@@ -15,5 +15,18 @@ ], 'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'], }, + { + 'target_name': 'internet_detail_dialog', + 'dependencies': [ + '<(DEPTH)/ui/webui/resources/cr_elements/chromeos/network/compiled_resources2.gyp:cr_onc_types', + '<(DEPTH)/ui/webui/resources/cr_elements/policy/compiled_resources2.gyp:cr_policy_network_behavior', + '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:assert', + '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:i18n_behavior', + '<(EXTERNS_GYP):chrome_send', + '<(EXTERNS_GYP):networking_private', + '<(INTERFACES_GYP):networking_private_interface', + ], + 'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'], + }, ], }
diff --git a/chrome/browser/resources/chromeos/internet_detail_dialog.html b/chrome/browser/resources/chromeos/internet_detail_dialog.html new file mode 100644 index 0000000..760ab03 --- /dev/null +++ b/chrome/browser/resources/chromeos/internet_detail_dialog.html
@@ -0,0 +1,107 @@ +<link rel="import" href="chrome://resources/html/polymer.html"> + +<link rel="import" href="chrome://resources/cr_components/chromeos/network/network_apnlist.html"> +<link rel="import" href="chrome://resources/cr_components/chromeos/network/network_ip_config.html"> +<link rel="import" href="chrome://resources/cr_components/chromeos/network/network_nameservers.html"> +<link rel="import" href="chrome://resources/cr_components/chromeos/network/network_property_list.html"> +<link rel="import" href="chrome://resources/cr_components/chromeos/network/network_proxy.html"> +<link rel="import" href="chrome://resources/cr_components/chromeos/network/network_shared_css.html"> +<link rel="import" href="chrome://resources/cr_elements/chromeos/network/cr_network_icon.html"> +<link rel="import" href="chrome://resources/cr_elements/chromeos/network/cr_onc_types.html"> +<link rel="import" href="chrome://resources/cr_elements/icons.html"> +<link rel="import" href="chrome://resources/html/i18n_behavior.html"> +<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/iron-flex-layout-classes.html"> +<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> +<link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css"> + +<dom-module id="internet-detail-dialog"> + <template> + <style include="network-shared iron-flex"> + div.property-box { + margin-bottom: 10px; + } + + .title { + -webkit-margin-start: 20px; + font-size: 107.69%; /* 14px / 13px */ + font-weight: 500; + } + + #networkState[connected] { + color: var(--google-green-500); + } + </style> + + <!-- Title section: Icon + name + connection state. --> + <div class="property-box first"> + <div class="start layout horizontal center"> + <cr-network-icon network-state="[[networkProperties]]"> + </cr-network-icon> + <div id="networkName" class="title"> + [[getNameText_(networkProperties)]] + </div> + <div id="networkState" class="title" + connected$="[[isConnectedState_(networkProperties)]]"> + [[getStateText_(networkProperties)]] + </div> + </div> + <paper-button class="primary-button" on-tap="onConnectTap_" + hidden$="[[!showConnect_(networkProperties)]]" + disabled="[[!enableConnect_(networkProperties)]]"> + $i18n{networkButtonConnect} + </paper-button> + <paper-button class="primary-button" on-tap="onDisconnectTap_" + hidden$="[[!showDisconnect_(networkProperties)]]"> + $i18n{networkButtonDisconnect} + </paper-button> + </div> + + <!-- Proxy --> + <div class="property-box single-column stretch"> + <network-proxy editable use-shared-proxies + on-proxy-change="onProxyChange_" + network-properties="[[networkProperties]]"> + </network-proxy> + </div> + + <template is="dom-if" + if="[[isRememberedOrConnected_(networkProperties)]]"> + <!-- IP Config --> + <div class="property-box single-column stretch"> + <network-ip-config editable on-ip-change="onIPConfigChange_" + network-properties="[[networkProperties]]"> + </network-ip-config> + </div> + + <!-- IP Config, Nameservers --> + <div class="property-box single-column stretch"> + <network-nameservers editable + on-nameservers-change="onIPConfigChange_" + network-properties="[[networkProperties]]"> + </network-nameservers> + </div> + </template> + + <!-- APN --> + <template is="dom-if" if="[[isCellular_(networkProperties)]]"> + <div class="property-box single-column stretch"> + <network-apnlist editable on-apn-change="onNetworkPropertyChange_" + network-properties="[[networkProperties]]"> + </network-apnlist> + </div> + </template> + + <!-- Other properties to show if present. --> + <template is="dom-if" if="[[hasInfoFields_(networkProperties)]]"> + <div class="property-box single-column stretch indented"> + <network-property-list + fields="[[getInfoFields_(networkProperties)]]" + property-dict="[[networkProperties]]" + on-property-change="onNetworkPropertyChange_"> + </network-property-list> + </div> + </template> + + </template> + <script src="internet_detail_dialog.js"></script> +</dom-module>
diff --git a/chrome/browser/resources/chromeos/internet_detail_dialog.js b/chrome/browser/resources/chromeos/internet_detail_dialog.js new file mode 100644 index 0000000..a927858 --- /dev/null +++ b/chrome/browser/resources/chromeos/internet_detail_dialog.js
@@ -0,0 +1,453 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * @fileoverview + * 'internet-detail-dialog' is used in the login screen to show a subset of + * internet details and allow configuration of proxy, IP, and nameservers. + */ +Polymer({ + is: 'internet-detail-dialog', + + behaviors: [I18nBehavior], + + properties: { + /** The network GUID to display details for. */ + guid: String, + + /** + * The current properties for the network matching |guid|. + * @type {!CrOnc.NetworkProperties|undefined} + */ + networkProperties: Object, + + /** + * Interface for networkingPrivate calls, passed from internet_page. + * @type {NetworkingPrivate} + */ + networkingPrivate: { + type: Object, + value: chrome.networkingPrivate, + }, + }, + + /** + * Listener function for chrome.networkingPrivate.onNetworksChanged event. + * @type {?function(!Array<string>)} + * @private + */ + networksChangedListener_: null, + + /** + * Set to true to once the initial properties have been received. This + * prevents setProperties from being called when setting default properties. + * @private {boolean} + */ + networkPropertiesReceived_: false, + + /** @override */ + attached: function() { + this.guid = chrome.getVariableValue('dialogArguments'); + if (!this.guid) { + console.error('Invalid guid'); + this.close_(); + } + + if (!this.networksChangedListener_) { + this.networksChangedListener_ = this.onNetworksChangedEvent_.bind(this); + this.networkingPrivate.onNetworksChanged.addListener( + this.networksChangedListener_); + } + + // Set basic networkProperties until they are loaded. + this.networkProperties = { + GUID: this.guid, + Type: CrOnc.Type.WI_FI, + ConnectionState: CrOnc.ConnectionState.NOT_CONNECTED, + Name: {Active: CrOnc.Type.WI_FI}, + }; + this.networkPropertiesReceived_ = false; + this.getNetworkDetails_(); + }, + + /** @override */ + detached: function() { + if (this.networksChangedListener_) { + this.networkingPrivate.onNetworksChanged.removeListener( + this.networksChangedListener_); + this.networksChangedListener_ = null; + } + }, + + /** @private */ + close_: function() { + chrome.send('dialogClose'); + }, + + /** + * networkingPrivate.onNetworksChanged event callback. + * @param {!Array<string>} networkIds The list of changed network GUIDs. + * @private + */ + onNetworksChangedEvent_: function(networkIds) { + if (networkIds.includes(this.guid)) + this.getNetworkDetails_(); + }, + + /** + * Calls networkingPrivate.getProperties for this.guid. + * @private + */ + getNetworkDetails_: function() { + assert(!!this.guid); + this.networkingPrivate.getManagedProperties( + this.guid, this.getPropertiesCallback_.bind(this)); + }, + + /** + * networkingPrivate.getProperties callback. + * @param {!CrOnc.NetworkProperties} properties The network properties. + * @private + */ + getPropertiesCallback_: function(properties) { + if (chrome.runtime.lastError) { + var message = chrome.runtime.lastError.message; + if (message == 'Error.InvalidNetworkGuid') { + console.error('Details page: GUID no longer exists: ' + this.guid); + } else { + console.error( + 'Unexpected networkingPrivate.getManagedProperties error: ' + + message + ' For: ' + this.guid); + } + this.close_(); + return; + } + if (!properties) { + console.error('No properties for: ' + this.guid); + this.close_(); + return; + } + this.networkProperties = properties; + this.networkPropertiesReceived_ = true; + }, + + /** + * @param {!chrome.networkingPrivate.NetworkConfigProperties} onc The ONC + * network properties. + * @private + */ + setNetworkProperties_: function(onc) { + if (!this.networkPropertiesReceived_) + return; + + assert(!!this.guid); + this.networkingPrivate.setProperties(this.guid, onc, () => { + if (chrome.runtime.lastError) { + // An error typically indicates invalid input; request the properties + // to update any invalid fields. + this.getNetworkDetails_(); + } + }); + }, + + /** + * @return {!chrome.networkingPrivate.NetworkConfigProperties} An ONC + * dictionary with just the Type property set. Used for passing properties + * to setNetworkProperties_. + * @private + */ + getEmptyNetworkProperties_: function() { + return {Type: this.networkProperties.Type}; + }, + + /** + * @param {!CrOnc.NetworkProperties} networkProperties + * @return {string} + * @private + */ + getStateText_: function(networkProperties) { + return this.i18n('Onc' + networkProperties.ConnectionState); + }, + + /** + * @param {!CrOnc.NetworkProperties} networkProperties + * @return {string} + * @private + */ + getNameText_: function(networkProperties) { + return CrOnc.getNetworkName(networkProperties); + }, + + /** + * @param {!CrOnc.NetworkProperties} networkProperties + * @return {boolean} True if the network is connected. + * @private + */ + isConnectedState_: function(networkProperties) { + return networkProperties.ConnectionState == CrOnc.ConnectionState.CONNECTED; + }, + + /** + * @param {!CrOnc.NetworkProperties} networkProperties + * @return {boolean} + * @private + */ + isRemembered_: function(networkProperties) { + var source = networkProperties.Source; + return !!source && source != CrOnc.Source.NONE; + }, + + /** + * @param {!CrOnc.NetworkProperties} networkProperties + * @return {boolean} + * @private + */ + isRememberedOrConnected_: function(networkProperties) { + return this.isRemembered_(networkProperties) || + this.isConnectedState_(networkProperties); + }, + + /** + * @param {!CrOnc.NetworkProperties} networkProperties + * @return {boolean} + * @private + */ + isCellular_: function(networkProperties) { + return networkProperties.Type == CrOnc.Type.CELLULAR && + !!networkProperties.Cellular; + }, + + /** + * @param {!CrOnc.NetworkProperties} networkProperties + * @return {boolean} + * @private + */ + showConnect_: function(networkProperties) { + return networkProperties.Type != CrOnc.Type.ETHERNET && + networkProperties.ConnectionState == + CrOnc.ConnectionState.NOT_CONNECTED; + }, + + /** + * @param {!CrOnc.NetworkProperties} networkProperties + * @return {boolean} + * @private + */ + showDisconnect_: function(networkProperties) { + return networkProperties.Type != CrOnc.Type.ETHERNET && + networkProperties.ConnectionState != + CrOnc.ConnectionState.NOT_CONNECTED; + }, + + /** + * @param {!CrOnc.NetworkProperties} networkProperties + * @return {boolean} Whether or not to enable the network connect button. + * @private + */ + enableConnect_: function(networkProperties) { + if (!this.showConnect_(networkProperties)) + return false; + if (networkProperties.Type == CrOnc.Type.CELLULAR && + CrOnc.isSimLocked(networkProperties)) { + return false; + } + return true; + }, + + /** @private */ + onConnectTap_: function() { + var properties = this.networkProperties; + this.networkingPrivate.startConnect(properties.GUID, function() { + if (chrome.runtime.lastError) { + var message = chrome.runtime.lastError.message; + if (message == 'connecting' || message == 'connect-canceled' || + message == 'connected' || message == 'Error.InvalidNetworkGuid') { + return; + } + console.error( + 'Unexpected networkingPrivate.startConnect error: ' + message + + ' For: ' + properties.GUID); + } + }); + }, + + /** @private */ + onDisconnectTap_: function() { + this.networkingPrivate.startDisconnect(this.guid); + }, + + /** + * Event triggered for elements associated with network properties. + * @param {!{detail: !{field: string, value: (string|!Object)}}} event + * @private + */ + onNetworkPropertyChange_: function(event) { + if (!this.networkProperties) + return; + var field = event.detail.field; + var value = event.detail.value; + var onc = this.getEmptyNetworkProperties_(); + if (field == 'APN') { + CrOnc.setTypeProperty(onc, 'APN', value); + } else { + console.error('Unexpected property change event: ' + field); + return; + } + this.setNetworkProperties_(onc); + }, + + /** + * Event triggered when the IP Config or NameServers element changes. + * TODO(stevenjb): Move this logic down to network_ip_config.js and + * network_nameservers.js and remove it from here and internet_detail_page.js. + * @param {!{detail: !{field: string, + * value: (string|!CrOnc.IPConfigProperties| + * !Array<string>)}}} event + * The network-ip-config or network-nameservers change event. + * @private + */ + onIPConfigChange_: function(event) { + if (!this.networkProperties) + return; + var field = event.detail.field; + var value = event.detail.value; + // Get an empty ONC dictionary and set just the IP Config properties that + // need to change. + var onc = this.getEmptyNetworkProperties_(); + var ipConfigType = + /** @type {chrome.networkingPrivate.IPConfigType|undefined} */ ( + CrOnc.getActiveValue(this.networkProperties.IPAddressConfigType)); + if (field == 'IPAddressConfigType') { + var newIpConfigType = + /** @type {chrome.networkingPrivate.IPConfigType} */ (value); + if (newIpConfigType == ipConfigType) + return; + onc.IPAddressConfigType = newIpConfigType; + } else if (field == 'NameServersConfigType') { + var nsConfigType = + /** @type {chrome.networkingPrivate.IPConfigType|undefined} */ ( + CrOnc.getActiveValue( + this.networkProperties.NameServersConfigType)); + var newNsConfigType = + /** @type {chrome.networkingPrivate.IPConfigType} */ (value); + if (newNsConfigType == nsConfigType) + return; + onc.NameServersConfigType = newNsConfigType; + } else if (field == 'StaticIPConfig') { + if (ipConfigType == CrOnc.IPConfigType.STATIC) { + var staticIpConfig = this.networkProperties.StaticIPConfig; + var ipConfigValue = /** @type {!Object} */ (value); + if (staticIpConfig && + this.allPropertiesMatch_(staticIpConfig, ipConfigValue)) { + return; + } + } + onc.IPAddressConfigType = CrOnc.IPConfigType.STATIC; + if (!onc.StaticIPConfig) { + onc.StaticIPConfig = + /** @type {!chrome.networkingPrivate.IPConfigProperties} */ ({}); + } + // Only copy Static IP properties. + var keysToCopy = ['Type', 'IPAddress', 'RoutingPrefix', 'Gateway']; + for (var i = 0; i < keysToCopy.length; ++i) { + var key = keysToCopy[i]; + if (key in value) + onc.StaticIPConfig[key] = value[key]; + } + } else if (field == 'NameServers') { + // If a StaticIPConfig property is specified and its NameServers value + // matches the new value, no need to set anything. + var nameServers = /** @type {!Array<string>} */ (value); + if (onc.NameServersConfigType == CrOnc.IPConfigType.STATIC && + onc.StaticIPConfig && onc.StaticIPConfig.NameServers == nameServers) { + return; + } + onc.NameServersConfigType = CrOnc.IPConfigType.STATIC; + if (!onc.StaticIPConfig) { + onc.StaticIPConfig = + /** @type {!chrome.networkingPrivate.IPConfigProperties} */ ({}); + } + onc.StaticIPConfig.NameServers = nameServers; + } else { + console.error('Unexpected change field: ' + field); + return; + } + // setValidStaticIPConfig will fill in any other properties from + // networkProperties. This is necessary since we update IP Address and + // NameServers independently. + CrOnc.setValidStaticIPConfig(onc, this.networkProperties); + this.setNetworkProperties_(onc); + }, + + /** + * Event triggered when the Proxy configuration element changes. + * @param {!{detail: {field: string, value: !CrOnc.ProxySettings}}} event + * The network-proxy change event. + * @private + */ + onProxyChange_: function(event) { + if (!this.networkProperties) + return; + if (event.detail.field != 'ProxySettings') + return; + var onc = this.getEmptyNetworkProperties_(); + CrOnc.setProperty( + onc, 'ProxySettings', /** @type {!Object} */ (event.detail.value)); + this.setNetworkProperties_(onc); + }, + + /** + * @param {!Array<string>} fields + * @return {boolean} + * @private + */ + hasVisibleFields_: function(fields) { + return fields.some((field) => { + var value = this.get(field, this.networkProperties); + return value !== undefined && value !== ''; + }); + }, + + /** + * @return {boolean} + * @private + */ + hasInfoFields_: function() { + return this.hasVisibleFields_(this.getInfoFields_()); + }, + + /** + * @return {!Array<string>} The fields to display in the info section. + * @private + */ + getInfoFields_: function() { + /** @type {!Array<string>} */ var fields = []; + var type = this.networkProperties.Type; + if (type == CrOnc.Type.CELLULAR && !!this.networkProperties.Cellular) { + fields.push( + 'Cellular.ActivationState', 'Cellular.RoamingState', + 'RestrictedConnectivity', 'Cellular.ServingOperator.Name'); + } else if (type == CrOnc.Type.WI_FI) { + fields.push('RestrictedConnectivity'); + } else if (type == CrOnc.Type.WI_MAX) { + fields.push('RestrictedConnectivity', 'WiMAX.EAP.Identity'); + } + fields.push('MacAddress'); + return fields; + }, + + /** + * @param {!Object} curValue + * @param {!Object} newValue + * @return {boolean} True if all properties set in |newValue| are equal to + * the corresponding properties in |curValue|. Note: Not all properties + * of |curValue| need to be specified in |newValue| for this to return + * true. + * @private + */ + allPropertiesMatch_: function(curValue, newValue) { + return Object.getOwnPropertyNames(newValue).every( + key => newValue[key] == curValue[key]); + } +});
diff --git a/chrome/browser/resources/chromeos/login/images/user_image.svg b/chrome/browser/resources/chromeos/login/images/user_image.svg new file mode 100644 index 0000000..f631ec30 --- /dev/null +++ b/chrome/browser/resources/chromeos/login/images/user_image.svg
@@ -0,0 +1 @@ +<svg width="64" height="64" viewBox="0 0 24 24" fill="#4285f4" xmlns="http://www.w3.org/2000/svg"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 3c1.66 0 3 1.34 3 3s-1.34 3-3 3-3-1.34-3-3 1.34-3 3-3zm0 14.2c-2.5 0-4.71-1.28-6-3.22.03-1.99 4-3.08 6-3.08 1.99 0 5.97 1.09 6 3.08-1.29 1.94-3.5 3.22-6 3.22z"/><path d="M0 0h24v24H0z" fill="none"/></svg>
diff --git a/chrome/browser/resources/chromeos/login/login_non_lock_shared.html b/chrome/browser/resources/chromeos/login/login_non_lock_shared.html index f0cdb4e66..2cc0e12 100644 --- a/chrome/browser/resources/chromeos/login/login_non_lock_shared.html +++ b/chrome/browser/resources/chromeos/login/login_non_lock_shared.html
@@ -37,6 +37,4 @@ <link rel="stylesheet" href="screen_unrecoverable_cryptohome_error.css"> <link rel="stylesheet" href="screen_active_directory_password_change.css"> -<link rel="stylesheet" href="../../options/chromeos/bluetooth.css"> - <script src="chrome://oobe/keyboard_utils.js"></script>
diff --git a/chrome/browser/resources/chromeos/login/oobe_change_picture.html b/chrome/browser/resources/chromeos/login/oobe_change_picture.html index c2fc0ad0..ad20678 100644 --- a/chrome/browser/resources/chromeos/login/oobe_change_picture.html +++ b/chrome/browser/resources/chromeos/login/oobe_change_picture.html
@@ -12,6 +12,8 @@ #description { -webkit-margin-end: 32px; -webkit-margin-start: 8px; + font-size: 13px; + line-height: 10px; } #container { @@ -19,7 +21,7 @@ align-items: flex-start; display: flex; margin-bottom: 32px; - padding-top: 16px; + padding-top: 32px; } #picturePane { @@ -33,7 +35,7 @@ #pictureList { -webkit-margin-end: 32px; - height: 304px; + height: 330px; overflow-x: hidden; overflow-y: auto; width: 340px; @@ -49,7 +51,7 @@ flip-photo-label="[[i18nDynamic(locale, 'flipPhoto')]]" take-photo-label="[[i18nDynamic(locale, 'takePhoto')]]"> </cr-picture-pane> - <cr-picture-list id="pictureList" tabindex="0" + <cr-picture-list id="pictureList" camera-present="[[cameraPresent]]" default-images="[[defaultImages]]" selected-item="{{selectedItem_}}"
diff --git a/chrome/browser/resources/chromeos/login/oobe_change_picture.js b/chrome/browser/resources/chromeos/login/oobe_change_picture.js index f4916ba..3b0deacd 100644 --- a/chrome/browser/resources/chromeos/login/oobe_change_picture.js +++ b/chrome/browser/resources/chromeos/login/oobe_change_picture.js
@@ -81,6 +81,11 @@ /** @type {CrPictureListElement} */ (this.$.pictureList); }, + /** Called when the screen is shown. */ + focus: function() { + this.$.pictureList.setFocus(); + }, + /** * @return {string} * @private
diff --git a/chrome/browser/resources/chromeos/login/oobe_hid_detection.html b/chrome/browser/resources/chromeos/login/oobe_hid_detection.html index 6955a479..61937527 100644 --- a/chrome/browser/resources/chromeos/login/oobe_hid_detection.html +++ b/chrome/browser/resources/chromeos/login/oobe_hid_detection.html
@@ -51,7 +51,6 @@ <template> <link rel="stylesheet" href="oobe_hid_detection.css"> <link rel="stylesheet" href="oobe_dialog_parameters.css"> - <link rel="stylesheet" href="../../options/chromeos/bluetooth.css"> <link rel="stylesheet" href="oobe_flex_layout.css"> <oobe-dialog has-buttons> <iron-icon icon="oobe-hid-detection:bluetooth" class="oobe-icon">
diff --git a/chrome/browser/resources/chromeos/login/oobe_screen_user_image.css b/chrome/browser/resources/chromeos/login/oobe_screen_user_image.css index d91266d..bf070a848 100644 --- a/chrome/browser/resources/chromeos/login/oobe_screen_user_image.css +++ b/chrome/browser/resources/chromeos/login/oobe_screen_user_image.css
@@ -3,15 +3,17 @@ * found in the LICENSE file. */ #user-image { - min-height: 443px; + min-height: 640px; padding-bottom: 24px; - width: 702px; + padding-left: 24px; + padding-top: 24px; + width: 768px; } #user-image.loading { - height: 528px; /* Should be the same as #gaia-signin height. */ + height: 640px; /* Should be the same as #gaia-signin height. */ padding: 0 0 0; - width: 448px; /* Should be the same as #gaia-signin width. */ + width: 768px; /* Should be the same as #gaia-signin width. */ } #user-image-screen-curtain { @@ -20,11 +22,12 @@ #user-image-screen-title { font-size: 28px; + margin-top: 24px; } #user-image .step-contents { -webkit-margin-start: 31px; - margin-bottom: 30px; + margin-bottom: 16px; } .user-image-stream-area .spinner { @@ -37,3 +40,15 @@ top: 50%; width: 44px; } + +#user-image-logo { + -webkit-margin-start: 8px; + height: 32px; + margin-top: 32px; + width: auto; +} + +#ok-button { + -webkit-margin-end: 16px; + margin-top: -6px; +}
diff --git a/chrome/browser/resources/chromeos/login/oobe_screen_user_image.html b/chrome/browser/resources/chromeos/login/oobe_screen_user_image.html index 65567e8..623a77c 100644 --- a/chrome/browser/resources/chromeos/login/oobe_screen_user_image.html +++ b/chrome/browser/resources/chromeos/login/oobe_screen_user_image.html
@@ -1,5 +1,6 @@ <div class="step right hidden loading no-logo" id="user-image" hidden> <div class="step-contents"> + <img id="user-image-logo" src="images/user_image.svg" alt> <div id="user-image-screen-curtain"> <p id="user-image-screen-title" i18n-content="userImageScreenTitle"></p>
diff --git a/chrome/browser/resources/chromeos/login/oobe_screen_user_image.js b/chrome/browser/resources/chromeos/login/oobe_screen_user_image.js index 04ad1c61..2067430 100644 --- a/chrome/browser/resources/chromeos/login/oobe_screen_user_image.js +++ b/chrome/browser/resources/chromeos/login/oobe_screen_user_image.js
@@ -42,9 +42,10 @@ * @type {array} Array of Buttons. */ get buttons() { - var okButton = this.ownerDocument.createElement('button'); + var okButton = this.ownerDocument.createElement('oobe-text-button'); okButton.id = 'ok-button'; okButton.textContent = loadTimeData.getString('okButtonText'); + okButton.setAttribute('inverse', ''); okButton.addEventListener('click', this.acceptImage_.bind(this)); return [okButton]; }, @@ -130,6 +131,7 @@ */ hideCurtain: function() { this.loading = false; + $('changePicture').focus(); }, /**
diff --git a/chrome/browser/resources/chromeos/proxy_settings.css b/chrome/browser/resources/chromeos/proxy_settings.css deleted file mode 100644 index d086331..0000000 --- a/chrome/browser/resources/chromeos/proxy_settings.css +++ /dev/null
@@ -1,47 +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. */ - -/* These additional styles constrain the size of the proxy page to the height of - the dialog containing them. */ -html { - height: 100%; -} - -body { - -webkit-box-sizing: border-box; - height: 100%; - margin: 0; - padding: 8px; -} - -#proxyPage { - height: 100%; -} - -#proxy-page-title { - /* We have a title on the window, so the title in domui should be hidden. */ - display: none; -} - -#internet-details-content-area > .subpages-tab-contents { - height: 100% !important; -} - -#advanced-config { - padding-top: 10px; -} - -html[highlight=strong] input[type='button']:focus, -html[highlight=strong] input[type='checkbox']:focus, -html[highlight=strong] input[type='radio']:focus, -html[highlight=strong] input[type='text']:focus, -html[highlight=strong] input[type='url']:focus, -html[highlight=strong] button:focus, -html[highlight=strong] list:focus { - box-shadow: 0 0 23px rgb(77, 144, 254) !important; -} - -html[highlight=strong] #network-proxy-tab { - padding: 10px; -}
diff --git a/chrome/browser/resources/chromeos/proxy_settings.html b/chrome/browser/resources/chromeos/proxy_settings.html index 061eaf8..4e70f19 100644 --- a/chrome/browser/resources/chromeos/proxy_settings.html +++ b/chrome/browser/resources/chromeos/proxy_settings.html
@@ -1,41 +1,17 @@ <!doctype html> -<html i18n-values="dir:textdirection;highlight:highlightStrength;lang:language"> -<head> -<meta charset="utf-8"> -<link rel="stylesheet" href="chrome://resources/css/chrome_shared.css"> -<link rel="stylesheet" href="chrome://resources/css/list.css"> -<link rel="stylesheet" href="chrome://resources/css/widgets.css"> +<html i18n-values="dir:textdirection;lang:language"> -<link rel="stylesheet" href="../options/options_page.css"> -<link rel="stylesheet" href="../options/chromeos/internet_detail.css"> -<link rel="stylesheet" href="proxy_settings.css"> -<script src="chrome://resources/js/cr.js"></script> -<script src="chrome://resources/js/event_tracker.js"></script> -<script src="chrome://resources/js/cr/event_target.js"></script> -<script src="chrome://resources/js/cr/ui.js"></script> -<script src="chrome://resources/js/cr/ui/touch_handler.js"></script> -<script src="chrome://resources/js/cr/ui/array_data_model.js"></script> -<script src="chrome://resources/js/cr/ui/list_selection_model.js"></script> -<script src="chrome://resources/js/cr/ui/list_selection_controller.js"></script> -<script src="chrome://resources/js/cr/ui/list_single_selection_model.js"></script> -<script src="chrome://resources/js/cr/ui/list_item.js"></script> -<script src="chrome://resources/js/cr/ui/list.js"></script> -<script src="chrome://resources/js/cr/ui/page_manager/page_manager.js"></script> -<script src="chrome://resources/js/cr/ui/page_manager/page.js"></script> -<script src="chrome://resources/js/util.js"></script> + <head> + <meta charset="utf-8"> + <link rel="import" href="chrome://proxy-settings/internet_detail_dialog.html"> + <link rel="import" href="chrome://resources/html/cr.html"></script> + <link rel="import" href="chrome://resources/html/load_time_data.html"></script> + <link rel="import" href="chrome://resources/html/util.html"></script> + <script src="chrome://proxy-settings/strings.js"></script> + </head> -<script src="../options/preferences.js"></script> -<script src="../options/pref_ui.js"></script> -<script src="../options/options_page.js"></script> -<script src="../options/chromeos/onc_data.js"></script> -<script src="../options/chromeos/internet_detail.js"></script> -<script src="../options/chromeos/proxy_rules_list.js"></script> -<script src="keyboard/keyboard_utils.js"></script> + <body> + <internet-detail-dialog></internet-detail-dialog> + </body> -<script src="proxy_settings.js"></script> -</head> - -<body> -<include src="../options/chromeos/internet_detail.html"> -</body> </html>
diff --git a/chrome/browser/resources/chromeos/proxy_settings.js b/chrome/browser/resources/chromeos/proxy_settings.js deleted file mode 100644 index d8e11a21..0000000 --- a/chrome/browser/resources/chromeos/proxy_settings.js +++ /dev/null
@@ -1,54 +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. - -var Preferences = options.Preferences; -var DetailsInternetPage = options.internet.DetailsInternetPage; - -/** - * DOMContentLoaded handler, sets up the page. - */ -function load() { - if (cr.isChromeOS) - document.documentElement.setAttribute('os', 'chromeos'); - - // Decorate the existing elements in the document. - cr.ui.decorate('input[pref][type=checkbox]', options.PrefCheckbox); - cr.ui.decorate('input[pref][type=number]', options.PrefNumber); - cr.ui.decorate('input[pref][type=radio]', options.PrefRadio); - cr.ui.decorate('input[pref][type=range]', options.PrefRange); - cr.ui.decorate('select[pref]', options.PrefSelect); - cr.ui.decorate('input[pref][type=text]', options.PrefTextField); - cr.ui.decorate('input[pref][type=url]', options.PrefTextField); - - DetailsInternetPage.initializeProxySettings(); - - // TODO(ivankr): remove when http://crosbug.com/20660 is resolved. - var inputs = document.querySelectorAll('input[pref]'); - for (var i = 0, el; el = inputs[i]; i++) { - el.addEventListener('keyup', function(e) { - cr.dispatchSimpleEvent(this, 'change'); - }); - } - - Preferences.getInstance().initialize(); - chrome.send('coreOptionsInitialize'); - - var params = parseQueryParams(window.location); - var network = params.network; - if (!network) { - console.error('Error: No network argument provided!'); - network = ''; - } - chrome.send('selectNetwork', [network]); - - DetailsInternetPage.showProxySettings(); -} - -disableTextSelectAndDrag(function(e) { - var src = e.target; - return src instanceof HTMLTextAreaElement || - src instanceof HTMLInputElement && /text|url/.test(src.type); -}); - -document.addEventListener('DOMContentLoaded', load);
diff --git a/chrome/browser/resources/help/OWNERS b/chrome/browser/resources/help/OWNERS deleted file mode 100644 index d337b42..0000000 --- a/chrome/browser/resources/help/OWNERS +++ /dev/null
@@ -1,3 +0,0 @@ -# This UI is deprecated. See chrome/browser/resources/settings/about_page -# instead. -dpapad@chromium.org
diff --git a/chrome/browser/resources/help/channel_change_page.css b/chrome/browser/resources/help/channel_change_page.css deleted file mode 100644 index 16ca904..0000000 --- a/chrome/browser/resources/help/channel_change_page.css +++ /dev/null
@@ -1,33 +0,0 @@ -/* Copyright 2013 The Chromium Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. */ - -#channel-change-page { - min-height: 200px; - width: 500px; -} - -.channel-change-page-channel label { - margin-left: 10px; -} - -.channel-change-page-channel { - display: block; - margin: 0 25px; -} - -.show-when-selected-channel-requires-powerwash, -.show-when-selected-channel-requires-delayed-update, -.show-when-selected-channel-good, -.show-when-selected-channel-unstable { - display: none !important; -} - -.selected-channel-requires-powerwash -.show-when-selected-channel-requires-powerwash, -.selected-channel-requires-delayed-update -.show-when-selected-channel-requires-delayed-update, -.selected-channel-good .show-when-selected-channel-good, -.selected-channel-unstable .show-when-selected-channel-unstable { - display: block !important; -}
diff --git a/chrome/browser/resources/help/channel_change_page.html b/chrome/browser/resources/help/channel_change_page.html deleted file mode 100644 index 67b16cf6..0000000 --- a/chrome/browser/resources/help/channel_change_page.html +++ /dev/null
@@ -1,52 +0,0 @@ -<div id="channel-change-page" class="page" hidden> - <div class="close-button"></div> - <h1>$i18n{channelChangePageTitle}</h1> - <div class="content-area"> - <div class="channel-change-page-channel radio"> - <input id="channel-change-page-stable-option" - type="radio" name="channel" value="stable-channel"> - <label for="channel-change-page-stable-option">$i18n{stable}</label> - </div> - <div class="channel-change-page-channel radio"> - <input id="channel-change-page-beta-option" - type="radio" name="channel" value="beta-channel"> - <label for="channel-change-page-beta-option">$i18n{beta}</label> - </div> - <div class="channel-change-page-channel radio"> - <input id="channel-change-page-dev-option" - type="radio" name="channel" value="dev-channel"> - <label for="channel-change-page-dev-option">$i18n{dev}</label> - </div> - </div> - <div class="content-area"> - <div class="show-when-selected-channel-requires-powerwash"> - <h2>$i18n{channelChangePagePowerwashTitle}</h2> - <div>$i18n{channelChangePagePowerwashMessage}</div> - </div> - <div class="show-when-selected-channel-requires-delayed-update"> - <h2>$i18n{channelChangePageDelayedChangeTitle}</h2> - <div>$i18n{channelChangePageDelayedChangeMessage}</div> - </div> - <div class="show-when-selected-channel-unstable"> - <h2>$i18n{channelChangePageUnstableTitle}</h2> - <div>$i18n{channelChangePageUnstableMessage}</div> - </div> - </div> - <div class="action-area"> - <div class="button-strip"> - <button id="channel-change-page-powerwash-button" - class="show-when-selected-channel-requires-powerwash"> - $i18n{channelChangePagePowerwashButton} - </button> - <button id="channel-change-page-change-button" - class="show-when-selected-channel-requires-delayed-update - show-when-selected-channel-good - show-when-selected-channel-unstable"> - $i18n{channelChangePageChangeButton} - </button> - <button id="channel-change-page-cancel-button" class="default-button"> - $i18n{channelChangePageCancelButton} - </button> - </div> - </div> -</div>
diff --git a/chrome/browser/resources/help/channel_change_page.js b/chrome/browser/resources/help/channel_change_page.js deleted file mode 100644 index 3763f65..0000000 --- a/chrome/browser/resources/help/channel_change_page.js +++ /dev/null
@@ -1,261 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -cr.define('help', function() { - var Page = cr.ui.pageManager.Page; - var PageManager = cr.ui.pageManager.PageManager; - - /** - * Encapsulated handling of the channel change overlay. - */ - function ChannelChangePage() { - Page.call(this, 'channel-change-page', '', 'channel-change-page'); - } - - cr.addSingletonGetter(ChannelChangePage); - - ChannelChangePage.prototype = { - __proto__: Page.prototype, - - /** - * Name of the channel the device is currently on. - * @private - */ - currentChannel_: null, - - /** - * Name of the channel the device is supposed to be on. - * @private - */ - targetChannel_: null, - - /** - * True iff the device is enterprise-managed. - * @private - */ - isEnterpriseManaged_: undefined, - - /** - * List of the channels names, from the least stable to the most stable. - * @private - */ - channelList_: ['dev-channel', 'beta-channel', 'stable-channel'], - - /** - * List of the possible ui states. - * @private - */ - uiClassTable_: ['selected-channel-requires-powerwash', - 'selected-channel-requires-delayed-update', - 'selected-channel-good', - 'selected-channel-unstable'], - - /** override */ - initializePage: function() { - Page.prototype.initializePage.call(this); - - $('channel-change-page-cancel-button').onclick = - PageManager.closeOverlay.bind(PageManager); - - var self = this; - var options = this.getAllChannelOptions_(); - for (var i = 0; i < options.length; i++) { - var option = options[i]; - option.onclick = function() { - self.updateUI_(this.value); - }; - } - - $('channel-change-page-powerwash-button').onclick = function() { - self.setChannel_(self.getSelectedOption_(), true); - PageManager.closeOverlay(); - }; - - $('channel-change-page-change-button').onclick = function() { - self.setChannel_(self.getSelectedOption_(), false); - PageManager.closeOverlay(); - }; - }, - - /** @override */ - didShowPage: function() { - if (this.targetChannel_ != null) - this.selectOption_(this.targetChannel_); - else if (this.currentChannel_ != null) - this.selectOption_(this.currentChannel_); - var options = this.getAllChannelOptions_(); - for (var i = 0; i < options.length; i++) { - var option = options[i]; - if (option.checked) - option.focus(); - } - }, - - /** - * Returns the list of all radio buttons responsible for channel selection. - * @return {NodeList} Array of radio buttons - * @private - */ - getAllChannelOptions_: function() { - return this.pageDiv.querySelectorAll('input[type="radio"]'); - }, - - /** - * Returns value of the selected option. - * @return {?string} Selected channel name or null, if neither - * option is selected. - * @private - */ - getSelectedOption_: function() { - var options = this.getAllChannelOptions_(); - for (var i = 0; i < options.length; i++) { - var option = options[i]; - if (option.checked) - return option.value; - } - return null; - }, - - /** - * Selects option for a given channel. - * @param {string} channel Name of channel option that should be selected. - * @private - */ - selectOption_: function(channel) { - var options = this.getAllChannelOptions_(); - for (var i = 0; i < options.length; i++) { - var option = options[i]; - if (option.value == channel) { - option.checked = true; - } - } - this.updateUI_(channel); - }, - - /** - * Updates UI according to selected channel. - * @param {string} selectedChannel Selected channel - * @private - */ - updateUI_: function(selectedChannel) { - var currentStability = this.channelList_.indexOf(this.currentChannel_); - var newStability = this.channelList_.indexOf(selectedChannel); - - var newOverlayClass = null; - - if (selectedChannel == this.currentChannel_) { - if (this.currentChannel_ != this.targetChannel_) { - // Allow user to switch back to the current channel. - newOverlayClass = 'selected-channel-good'; - } - } else if (selectedChannel != this.targetChannel_) { - // Selected channel isn't equal to the current and target channel. - if (newStability > currentStability) { - // More stable channel is selected. For customer devices - // notify user about powerwash. - if (this.isEnterpriseManaged_) - newOverlayClass = 'selected-channel-requires-delayed-update'; - else - newOverlayClass = 'selected-channel-requires-powerwash'; - } else if (selectedChannel == 'dev-channel') { - // Warn user about unstable channel. - newOverlayClass = 'selected-channel-unstable'; - } else { - // Switching to the less stable channel. - newOverlayClass = 'selected-channel-good'; - } - } - - // Switch to the new UI state. - for (var i = 0; i < this.uiClassTable_.length; i++) - this.pageDiv.classList.remove(this.uiClassTable_[i]); - - if (newOverlayClass) - this.pageDiv.classList.add(newOverlayClass); - }, - - /** - * Sets the device target channel. - * @param {string} channel The name of the target channel - * @param {boolean} isPowerwashAllowed True iff powerwash is allowed - * @private - */ - setChannel_: function(channel, isPowerwashAllowed) { - this.targetChannel_ = channel; - this.updateUI_(channel); - help.HelpPage.setChannel(channel, isPowerwashAllowed); - }, - - /** - * Updates page UI according to device owhership policy. - * @param {boolean} isEnterpriseManaged True if the device is - * enterprise managed - * @private - */ - updateIsEnterpriseManaged_: function(isEnterpriseManaged) { - this.isEnterpriseManaged_ = isEnterpriseManaged; - }, - - /** - * Updates name of the current channel, i.e. the name of the - * channel the device is currently on. - * @param {string} channel The name of the current channel - * @private - */ - updateCurrentChannel_: function(channel) { - if (this.channelList_.indexOf(channel) < 0) - return; - this.currentChannel_ = channel; - this.selectOption_(channel); - }, - - /** - * Updates name of the target channel, i.e. the name of the - * channel the device is supposed to be in case of a pending - * channel change. - * @param {string} channel The name of the target channel - * @private - */ - updateTargetChannel_: function(channel) { - if (this.channelList_.indexOf(channel) < 0) - return; - this.targetChannel_ = channel; - }, - - /** - * @return {boolean} True if the page is ready and can be - * displayed, false otherwise - * @private - */ - isPageReady_: function() { - if (typeof this.isEnterpriseManaged_ == 'undefined') - return false; - if (!this.currentChannel_ || !this.targetChannel_) - return false; - return true; - }, - }; - - ChannelChangePage.updateIsEnterpriseManaged = function(isEnterpriseManaged) { - ChannelChangePage.getInstance().updateIsEnterpriseManaged_( - isEnterpriseManaged); - }; - - ChannelChangePage.updateCurrentChannel = function(channel) { - ChannelChangePage.getInstance().updateCurrentChannel_(channel); - }; - - ChannelChangePage.updateTargetChannel = function(channel) { - ChannelChangePage.getInstance().updateTargetChannel_(channel); - }; - - ChannelChangePage.isPageReady = function() { - return ChannelChangePage.getInstance().isPageReady_(); - }; - - // Export - return { - ChannelChangePage: ChannelChangePage - }; -});
diff --git a/chrome/browser/resources/help/compiled_resources2.gyp b/chrome/browser/resources/help/compiled_resources2.gyp deleted file mode 100644 index c0ae4e7..0000000 --- a/chrome/browser/resources/help/compiled_resources2.gyp +++ /dev/null
@@ -1,103 +0,0 @@ -# Copyright 2017 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. -{ - 'targets': [ - { - 'target_name': 'help', - 'variables': { - 'extra_inputs': [ - '<!@(python <(CLOSURE_DIR)/build/get_includes.py ../options/options_bundle.js)', - ], - 'script_args': ['--custom_sources', '--custom_includes'], - 'source_files': [ - '<(DEPTH)/third_party/jstemplate/util.js', - '<(DEPTH)/third_party/jstemplate/jsevalcontext.js', - '<(DEPTH)/third_party/jstemplate/jstemplate.js', - '<(DEPTH)/ui/webui/resources/cr_elements/chromeos/network/cr_onc_types.js', - '<(DEPTH)/ui/webui/resources/js/action_link.js', - '<(DEPTH)/ui/webui/resources/js/cr.js', - '<(DEPTH)/ui/webui/resources/js/cr/event_target.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui/array_data_model.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui/autocomplete_list.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui/bubble.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui/bubble_button.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui/command.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui/controlled_indicator.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui/focus_manager.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui/focus_outline_manager.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui/focus_without_ink.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui/list.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui/list_item.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui/list_selection_controller.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui/list_selection_model.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui/list_single_selection_model.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui/grid.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui/menu.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui/menu_item.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui/overlay.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui/position_util.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui/node_utils.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui/page_manager/page.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui/page_manager/page_manager.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui/repeating_button.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui/touch_handler.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui/tree.js', - '<(DEPTH)/ui/webui/resources/js/event_tracker.js', - '<(DEPTH)/ui/webui/resources/js/icon.js', - '<(DEPTH)/ui/webui/resources/js/load_time_data.js', - '<(DEPTH)/ui/webui/resources/js/parse_html_subset.js', - '<(DEPTH)/ui/webui/resources/js/promise_resolver.js', - '<(DEPTH)/ui/webui/resources/js/util.js', - '../chromeos/keyboard/keyboard_utils.js', - '<(DEPTH)/ui/webui/resources/js/i18n_behavior.js', - '<(DEPTH)/ui/webui/resources/js/web_ui_listener_behavior.js', - '../settings/page_visibility.js', - '../settings/route.js', - '../settings/people_page/easy_unlock_browser_proxy.js', - '../settings/people_page/fingerprint_browser_proxy.js', - '<(DEPTH)/third_party/polymer/v1_0/components-chromium/iron-a11y-keys-behavior/iron-a11y-keys-behavior-extracted.js', - '<(DEPTH)/third_party/polymer/v1_0/components-chromium/iron-selector/iron-selection-extracted.js', - '<(DEPTH)/third_party/polymer/v1_0/components-chromium/iron-selector/iron-selectable-extracted.js', - '<(DEPTH)/third_party/polymer/v1_0/components-chromium/iron-selector/iron-multi-selectable-extracted.js', - '<(DEPTH)/third_party/polymer/v1_0/components-chromium/iron-menu-behavior/iron-menu-behavior-extracted.js', - '<(DEPTH)/third_party/polymer/v1_0/components-chromium/iron-menu-behavior/iron-menubar-behavior-extracted.js', - '<(DEPTH)/ui/webui/resources/cr_elements/cr_profile_avatar_selector/cr_profile_avatar_selector_grid.js', - '<(DEPTH)/ui/webui/resources/cr_elements/cr_profile_avatar_selector/cr_profile_avatar_selector.js', - '../settings/people_page/lock_screen_constants.js', - '<(DEPTH)/third_party/closure_compiler/externs/quick_unlock_private.js', - '../settings/people_page/lock_state_behavior.js', - '../settings/people_page/password_prompt_dialog.js', - '<(DEPTH)/ui/webui/resources/js/assert.js', - '<(DEPTH)/third_party/polymer/v1_0/components-chromium/iron-meta/iron-meta-extracted.js', - '<(DEPTH)/third_party/polymer/v1_0/components-chromium/iron-icon/iron-icon-extracted.js', - '<(DEPTH)/third_party/polymer/v1_0/components-chromium/iron-behaviors/iron-control-state-extracted.js', - '<(DEPTH)/third_party/polymer/v1_0/components-chromium/iron-behaviors/iron-button-state-extracted.js', - '<(DEPTH)/third_party/polymer/v1_0/components-chromium/paper-ripple/paper-ripple-extracted.js', - '<(DEPTH)/third_party/polymer/v1_0/components-chromium/paper-behaviors/paper-ripple-behavior-extracted.js', - '<(DEPTH)/third_party/polymer/v1_0/components-chromium/paper-behaviors/paper-inky-focus-behavior-extracted.js', - '<(DEPTH)/third_party/polymer/v1_0/components-chromium/paper-icon-button/paper-icon-button-extracted.js', - '<(DEPTH)/ui/webui/resources/cr_elements/cr_dialog/cr_dialog.js', - '../settings/people_page/lock_screen.js', - '<(DEPTH)/third_party/closure_compiler/externs/bluetooth.js', - '<(DEPTH)/third_party/closure_compiler/externs/bluetooth_private.js', - '<(DEPTH)/third_party/closure_compiler/externs/management.js', - '<(DEPTH)/third_party/closure_compiler/externs/metrics_private.js', - '<(DEPTH)/third_party/closure_compiler/externs/networking_private.js', - '<(DEPTH)/third_party/closure_compiler/externs/chrome_send.js', - '<(DEPTH)/third_party/closure_compiler/externs/web_animations.js', - '<(DEPTH)/ui/webui/resources/cr_elements/chromeos/network/cr_network_icon_externs.js', - '../options/options_bundle.js', - # Note: ^ this is just a copy of - # ../options/compiled_resources2.gyp:options_bundle#source_files. Most - # of this code is deprecated, but please keep in sync if you really - # need to change. - 'channel_change_page.js', - 'help_page.js', - ], - }, - 'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'], - } - ], -}
diff --git a/chrome/browser/resources/help/help.css b/chrome/browser/resources/help/help.css deleted file mode 100644 index 8e1be570..0000000 --- a/chrome/browser/resources/help/help.css +++ /dev/null
@@ -1,7 +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. */ - -body { - user-select: text; -}
diff --git a/chrome/browser/resources/help/help.html b/chrome/browser/resources/help/help.html deleted file mode 100644 index 0124090e..0000000 --- a/chrome/browser/resources/help/help.html +++ /dev/null
@@ -1,54 +0,0 @@ -<!doctype html> -<html i18n-values="dir:textdirection;lang:language"> -<head> - <meta charset="utf-8"> - <title>$i18n{aboutTitle}</title> - <link rel="stylesheet" href="chrome://resources/css/chrome_shared.css"> - <link rel="stylesheet" href="../uber/uber_shared.css"> - <link rel="stylesheet" href="help.css"> - <link rel="stylesheet" href="help_content.css"> -<if expr="chromeos"> - <link rel="stylesheet" href="chrome://resources/css/bubble.css"> - <link rel="stylesheet" href="chrome://resources/css/overlay.css"> - <link rel="stylesheet" href="channel_change_page.css"> -</if> - - <script src="chrome://resources/js/action_link.js"></script> - <script src="chrome://resources/js/cr.js"></script> - <script src="chrome://resources/js/cr/event_target.js"></script> - <script src="chrome://resources/js/load_time_data.js"></script> - <script src="chrome://resources/js/util.js"></script> - <script src="chrome://resources/js/cr/ui.js"></script> - <script src="chrome://resources/js/cr/ui/focus_manager.js"></script> - <script src="chrome://resources/js/cr/ui/focus_outline_manager.js"></script> - <script src="chrome://resources/js/cr/ui/overlay.js"></script> - <script src="chrome://resources/js/cr/ui/page_manager/page_manager.js"></script> - <script src="chrome://resources/js/cr/ui/page_manager/page.js"></script> -<if expr="chromeos"> - <script src="chrome://resources/js/cr/ui/bubble.js"></script> - <script src="chrome://resources/js/event_tracker.js"></script> - <script src="chrome://help-frame/channel_change_page.js"></script> -</if> - <script src="chrome://help-frame/help_page.js"></script> - <script src="chrome://help-frame/help.js"></script> -</head> -<body class="uber-frame"> - <header> - <h1>$i18n{aboutTitle}</h1> - </header> -<if expr="chromeos"> - <div id="overlay-container-1" class="overlay transparent" hidden> - <include src="channel_change_page.html"> - </div> -</if> - <div id="mainview-content"> - <div id="page-container"> - <div id="help-page" class="page"> - <include src="help_content.html"> - </div> - </div> - </div> -</body> -<script src="chrome://help-frame/strings.js"></script> -<script src="chrome://resources/js/i18n_template.js"></script> -</html>
diff --git a/chrome/browser/resources/help/help.js b/chrome/browser/resources/help/help.js deleted file mode 100644 index f03dcdee..0000000 --- a/chrome/browser/resources/help/help.js +++ /dev/null
@@ -1,51 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// <include src="../uber/uber_page_manager_observer.js"> -// <include src="../uber/uber_utils.js"> - -(function() { - var HelpPage = help.HelpPage; - var PageManager = cr.ui.pageManager.PageManager; - - /** - * DOMContentLoaded handler, sets up the page. - */ - function load() { - PageManager.register(HelpPage.getInstance()); - - if (help.ChannelChangePage) { - PageManager.registerOverlay(help.ChannelChangePage.getInstance(), - HelpPage.getInstance()); - } - PageManager.addObserver(new uber.PageManagerObserver()); - PageManager.initialize(HelpPage.getInstance()); - uber.onContentFrameLoaded(); - - var pageName = PageManager.getPageNameFromPath(); - // Still update history so that chrome://help/nonexistant redirects - // appropriately to chrome://help/. If the URL matches, updateHistory - // will avoid adding the extra state. - var updateHistory = true; - PageManager.showPageByName(pageName, updateHistory, {replaceState: true}); - } - - document.addEventListener('DOMContentLoaded', load); - - /** - * Listener for the |beforeunload| event. - */ - window.onbeforeunload = function() { - PageManager.willClose(); - }; - - /** - * Listener for the |popstate| event. - * @param {Event} e The |popstate| event. - */ - window.onpopstate = function(e) { - var pageName = PageManager.getPageNameFromPath(); - PageManager.setState(pageName, location.hash, e.state); - }; -})();
diff --git a/chrome/browser/resources/help/help_content.css b/chrome/browser/resources/help/help_content.css deleted file mode 100644 index 3bdd341..0000000 --- a/chrome/browser/resources/help/help_content.css +++ /dev/null
@@ -1,170 +0,0 @@ -/* Copyright 2014 The Chromium Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. */ - -#about-container { - align-items: center; - display: flex; -} - -#page-container #about-container { - margin-top: 10px; -} - -#product-description { - -webkit-margin-start: 10px; -} - -#version-container { - margin-top: 30px; -} - -#update-buttons-container { - margin-top: 5px; -} - -#update-status-container { - margin-bottom: 12px; - margin-top: 10px; -} - -#update-status { - vertical-align: middle; -} - -#update-percentage { - font-size: 90%; -} - -#get-help, -#promote { - -webkit-margin-end: 4px; -} - -#help-container { - margin-top: 16px; -} - -#product-container { - line-height: 1.8em; - margin-top: 200px; -} - -.overlay #product-container { - margin-top: 30px; -} - -.help-page-icon { - background-position: center; - background-repeat: no-repeat; - display: inline-block; - height: 18px; - vertical-align: middle; - width: 18px; -} - -#update-status-icon.up-to-date { - background-image: url(../../../../ui/webui/resources/images/check_circle.svg); - background-size: 18px; -} - -#update-status-icon.working { - background-image: url(chrome://resources/images/throbber_small.svg); - background-size: 16px; -} - -#update-status-icon.failed { - background-image: url(chrome://resources/images/error.svg); - background-size: 18px; -} - -#update-status-icon.disabled-by-admin { - background-image: url(../../../../ui/webui/resources/images/business.svg); - background-size: 18px; -} - -#controlled-feature-icon { - background-image: url(../../../../ui/webui/resources/images/business.svg); - background-size: 18px; -} - -#eol-status-icon { - background-image: url(../../../../ui/webui/resources/images/eol.svg); - background-size: 18px; -} - -#eol-status-container { - margin-bottom: 12px; - margin-top: 10px; -} - -#eol-status-message-container { - -webkit-margin-start: 8px; - display: inline-block; - vertical-align: middle; -} - -#update-status-message-container { - -webkit-margin-start: 8px; - display: inline-block; - vertical-align: middle; -} - -#more-info-expander { - -webkit-padding-start: 0; - margin-top: 10px; -} - -#more-info-container.visible { - margin-bottom: 10px; -} - -#more-info-container { - height: 0; - margin-bottom: 0; - overflow: hidden; - transition: all 200ms; -} - -#build-date-container.empty { - visibility: hidden; -} - -#channel-change-confirmation { - margin-top: 5px; -} - -#change-channel { - margin-top: 8px; -} - -#channel-change-disallowed-icon, -.channel-change-error-icon { - -webkit-margin-start: 4px; - background-image: url(../../../../ui/webui/resources/images/business.svg); - background-size: 18px; -} - -.channel-change-error-bubble { - display: flex; -} - -.channel-change-error-bubble .channel-change-error-icon { - vertical-align: top; -} - -.channel-change-error-text { - -webkit-margin-start: 4px; - display: block; - vertical-align: top; - width: 240px; -} - -#regulatory-label-container { - padding-top: 32px; -} - -#regulatory-label { - display: block; - width: 330px; -}
diff --git a/chrome/browser/resources/help/help_content.html b/chrome/browser/resources/help/help_content.html deleted file mode 100644 index 1c82f60..0000000 --- a/chrome/browser/resources/help/help_content.html +++ /dev/null
@@ -1,134 +0,0 @@ - <div class="content-area"> - <div id="about-container"> - <img id="product-logo" srcset="chrome://theme/current-channel-logo@1x 1x, - chrome://theme/current-channel-logo@2x 2x" - alt=""> - <div id="product-description"> - <h2>$i18n{aboutProductTitle}</h2> - <span>$i18n{aboutProductDescription}</span> - </div> - </div> - <div id="help-container"> - <button id="get-help">$i18n{getHelpWithChrome}</button> -<if expr="_google_chrome"> - <button id="report-issue">$i18n{reportAnIssue}</button> -</if> - </div> - <div id="version-container"> - <div> - <span dir="ltr">$i18n{browserVersion}</span> - </div> -<if expr="chromeos"> - <div> - <span>$i18n{platform}</span> <span id="os-version"></span> - </div> - <div> - <span>$i18n{arcVersion}</span> <span id="arc-version"></span> - </div> - <div> - <span>$i18n{firmware}</span> <span id="firmware"></span> - </div> -</if> -<if expr="chromeos or _google_chrome or is_linux"> - <div id="update-status-container" hidden> - <div id="update-status-icon" class="help-page-icon up-to-date"></div> - <div id="update-status-message-container"> - <div id="update-status-message">$i18n{updateCheckStarted}</div> -<if expr="is_macosx or is_win"> - <div id="update-obsolete-system-container" hidden> - <span id="update-obsolete-system">$i18n{updateObsoleteSystem}</span> - <a i18n-values="href:updateObsoleteSystemURL" target="_blank"> - $i18n{learnMore} - </a> - </div> -</if> - <div id="allowed-connection-types-message" hidden></div> - </div> - </div> -<if expr="chromeos"> - <div id="eol-status-container" hidden> - <div id="eol-status-icon" class="help-page-icon"></div> - <div id="eol-status-message-container"> - <div id="eol-message"></div> - <div id="eol-learnMore">$i18n{eolLearnMore}</div> - </div> - </div> -</if> - <div id="update-buttons-container"> - <div id="update-percentage" hidden></div> -<if expr="is_macosx"> - <button id="promote" hidden>$i18n{promote}</button> -</if> - <button id="relaunch" hidden>$i18n{relaunch}</button> -<if expr="chromeos"> - <button id="relaunch-and-powerwash" hidden> - $i18n{relaunchAndPowerwash} - </button> - <button id="request-update">$i18n{updateButton}</button> - <div id="controlled-feature-icon" class="help-page-icon" hidden></div> -</if> - </div> -</if> -<if expr="chromeos"> - <div id="more-info-container"> - <section id="channel-changer-container" hidden> - <h3>$i18n{channel}</h3> - <select id="channel-changer"> - <option value="stable-channel">$i18n{stable}</option> - <option value="beta-channel">$i18n{beta}</option> - <option value="dev-channel">$i18n{dev}</option> - </select> - <div id="channel-change-confirmation" hidden></div> - </section> - <section id="channel-change-page-container" hidden> - <h3>$i18n{channel}</h3> - <div id="current-channel"></div> - <div> - <span id="dev-channel-disclaimer" hidden> - $i18n{devChannelDisclaimer} - </span> - </div> - <button id="change-channel" disabled> - $i18n{channelChangeButton} - </button> - <div id="channel-change-disallowed-icon" - class="help-page-icon" hidden> - </div> - </section> - <section> - <h3 dir="ltr">$i18n{jsEngine}</h3> - <div>$i18n{jsEngineVersion}</div> - </section> - <section> - <h3>$i18n{userAgent}</h3> - <div dir="ltr">$i18n{userAgentInfo}</div> - </section> - <section> - <h3>$i18n{commandLine}</h3> - <div dir="ltr">$i18n{commandLineInfo}</div> - </section> - <section id="build-date-container" class="empty"> - <h3>$i18n{buildDate}</h3> - <div id="build-date"></div> - </section> - </div> - <a is="action-link" id="more-info-expander">$i18n{showMoreInfo}</a> -</if> - </div> - <div id="product-container"> - <div>$i18n{productName}</div> - <div>$i18n{productCopyright}</div> - <div id="product-license"></div> -<if expr="chromeos"> - <div id="product-os-license"></div> -</if> -<if expr="_google_chrome"> - <div id="product-tos"></div> -</if> - </div> -<if expr="chromeos"> - <div id="regulatory-label-container" hidden> - <img id="regulatory-label"> - </div> -</if> -</div>
diff --git a/chrome/browser/resources/help/help_page.html b/chrome/browser/resources/help/help_page.html deleted file mode 100644 index 79dcb07..0000000 --- a/chrome/browser/resources/help/help_page.html +++ /dev/null
@@ -1,10 +0,0 @@ -<div id="help-page" class="page" hidden> - <div class="close-button"></div> - <h1>$i18n{aboutTitle}</h1> - <include src="help_content.html"> - <div class="action-area"> - <div class="button-strip"> - <button id="about-done" class="default-button">$i18n{done}</button> - </div> - </div> -</div>
diff --git a/chrome/browser/resources/help/help_page.js b/chrome/browser/resources/help/help_page.js deleted file mode 100644 index 977ce38f..0000000 --- a/chrome/browser/resources/help/help_page.js +++ /dev/null
@@ -1,785 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -cr.define('help', function() { - var Page = cr.ui.pageManager.Page; - var PageManager = cr.ui.pageManager.PageManager; - - /** - * Encapsulated handling of the About page. Called 'help' internally to avoid - * confusion with generic AboutUI (about:version, about:sandbox, etc.). - */ - function HelpPage() { - var id = loadTimeData.valueExists('aboutOverlayTabTitle') ? - 'aboutOverlayTabTitle' : 'aboutTitle'; - Page.call(this, 'help', loadTimeData.getString(id), 'help-page'); - } - - cr.addSingletonGetter(HelpPage); - - HelpPage.prototype = { - __proto__: Page.prototype, - - /** - * List of the channel names. Should be ordered in increasing level of - * stability. - * @private - */ - channelList_: ['dev-channel', 'beta-channel', 'stable-channel'], - - /** - * Name of the channel the device is currently on. - * @private - */ - currentChannel_: null, - - /** - * Name of the channel the device is supposed to be on. - * @private - */ - targetChannel_: null, - - /** - * Last status received from the version updater. - * @private - */ - status_: null, - - /** - * Last message received from the version updater. - * @private - */ - message_: null, - - /** - * True if user is allowed to change channels, false otherwise. - * @private - */ - canChangeChannel_: false, - - /** - * True if we have never checked for available updates. - * @private - */ - haveNeverCheckedForUpdates_: true, - - /** - * Last EndofLife status received from the version updater. - * @private - */ - eolStatus_: null, - - /** - * Last EndofLife message received from the version updater. - * @private - */ - eolMessage_: null, - - /** @override */ - initializePage: function() { - Page.prototype.initializePage.call(this); - - $('product-license').innerHTML = loadTimeData.getString('productLicense'); - if (cr.isChromeOS) { - $('product-os-license').innerHTML = - loadTimeData.getString('productOsLicense'); - $('eol-learnMore').innerHTML = loadTimeData.getString('eolLearnMore'); - } - - var productTOS = $('product-tos'); - if (productTOS) - productTOS.innerHTML = loadTimeData.getString('productTOS'); - - $('get-help').onclick = function() { - chrome.send('openHelpPage'); - }; -// <if expr="_google_chrome"> - $('report-issue').onclick = function() { - chrome.send('openFeedbackDialog'); - }; -// </if> - - this.maybeSetOnClick_($('more-info-expander'), - this.toggleMoreInfo_.bind(this)); - - this.maybeSetOnClick_($('promote'), function() { - chrome.send('promoteUpdater'); - }); - this.maybeSetOnClick_($('relaunch'), function() { - chrome.send('relaunchNow'); - }); - if (cr.isChromeOS) { - this.maybeSetOnClick_($('relaunch-and-powerwash'), function() { - chrome.send('relaunchAndPowerwash'); - }); - - this.channelTable_ = { - 'stable-channel': { - 'name': loadTimeData.getString('stable'), - 'label': loadTimeData.getString('currentChannelStable'), - }, - 'beta-channel': { - 'name': loadTimeData.getString('beta'), - 'label': loadTimeData.getString('currentChannelBeta') - }, - 'dev-channel': { - 'name': loadTimeData.getString('dev'), - 'label': loadTimeData.getString('currentChannelDev') - } - }; - } - this.maybeSetOnClick_($('about-done'), function() { - // Event listener for the close button when shown as an overlay. - PageManager.closeOverlay(); - }); - - var self = this; - var channelChanger = $('channel-changer'); - if (channelChanger) { - channelChanger.onchange = function(event) { - self.setChannel_(event.target.value, false); - }; - } - - if (cr.isChromeOS) { - // Add event listener for the check for and apply updates button. - this.maybeSetOnClick_($('request-update'), function() { - self.setUpdateStatus_('checking'); - $('request-update').disabled = true; - chrome.send('requestUpdate'); - }); - - $('change-channel').onclick = function() { - PageManager.showPageByName('channel-change-page', false); - }; - - var channelChangeDisallowedError = document.createElement('div'); - channelChangeDisallowedError.className = 'channel-change-error-bubble'; - - var channelChangeDisallowedIcon = document.createElement('div'); - channelChangeDisallowedIcon.className = - 'help-page-icon channel-change-error-icon'; - channelChangeDisallowedError.appendChild(channelChangeDisallowedIcon); - - var channelChangeDisallowedText = document.createElement('div'); - channelChangeDisallowedText.className = 'channel-change-error-text'; - channelChangeDisallowedText.textContent = - loadTimeData.getString('channelChangeDisallowedMessage'); - channelChangeDisallowedError.appendChild(channelChangeDisallowedText); - - $('channel-change-disallowed-icon').onclick = function() { - PageManager.showBubble(channelChangeDisallowedError, - $('channel-change-disallowed-icon'), - $('help-container'), - cr.ui.ArrowLocation.TOP_END); - }; - - // Unhide the regulatory label if/when the image loads. - $('regulatory-label').onload = function() { - $('regulatory-label-container').hidden = false; - }; - - $('controlled-feature-icon').onclick = function(e) { - var content = /** @type {HTMLElement} */( - document.createElement('div')); - content.textContent = - loadTimeData.getString('updateDisabledByPolicy'); - var bubble = new cr.ui.AutoCloseBubble; - bubble.id = 'controlled-feature-bubble'; - bubble.anchorNode = $('controlled-feature-icon'); - bubble.domSibling = $('controlled-feature-icon'); - bubble.arrowLocation = cr.ui.ArrowLocation.TOP_END; - bubble.content = content; - bubble.show(); - }; - } - - var logo = $('product-logo'); - logo.onclick = function(e) { - logo.animate({ - transform: ['none', 'rotate(-10turn)'], - }, /** @type {!KeyframeEffectOptions} */({ - duration: 500, - easing: 'cubic-bezier(1, 0, 0, 1)', - })); - }; - - // Attempt to update. - chrome.send('onPageLoaded'); - }, - - /** @override */ - didClosePage: function() { - this.setMoreInfoVisible_(false); - }, - - /** - * Sets the visible state of the 'More Info' section. - * @param {boolean} visible Whether the section should be visible. - * @private - */ - setMoreInfoVisible_: function(visible) { - var moreInfo = $('more-info-container'); - if (!moreInfo || visible == moreInfo.classList.contains('visible')) - return; - - moreInfo.classList.toggle('visible', visible); - moreInfo.style.height = visible ? moreInfo.scrollHeight + 'px' : ''; - moreInfo.addEventListener('transitionend', function(event) { - $('more-info-expander').textContent = visible ? - loadTimeData.getString('hideMoreInfo') : - loadTimeData.getString('showMoreInfo'); - }); - }, - - /** - * Toggles the visible state of the 'More Info' section. - * @private - */ - toggleMoreInfo_: function() { - var moreInfo = $('more-info-container'); - this.setMoreInfoVisible_(!moreInfo.classList.contains('visible')); - }, - - /** - * Assigns |method| to the onclick property of |el| if |el| exists. - * @param {HTMLElement} el The element on which to set the click handler. - * @param {Function} method The click handler. - * @private - */ - maybeSetOnClick_: function(el, method) { - if (el) - el.onclick = method; - }, - - /** - * @param {string} state The state of the update. - * private - */ - setUpdateImage_: function(state) { - $('update-status-icon').className = 'help-page-icon ' + state; - }, - - /** - * @return {boolean} True, if new channel switcher UI is used, - * false otherwise. - * @private - */ - isNewChannelSwitcherUI_: function() { - return !loadTimeData.valueExists('disableNewChannelSwitcherUI'); - }, - - /** - * @return {boolean} True if target and current channels are not null and - * not equal. - * @private - */ - channelsDiffer_: function() { - var current = this.currentChannel_; - var target = this.targetChannel_; - return (current != null && target != null && current != target); - }, - - /** - * @return {boolean} True if target channel is more stable than the current - * one, and false otherwise. - * @private - */ - targetChannelIsMoreStable_: function() { - var current = this.currentChannel_; - var target = this.targetChannel_; - if (current == null || target == null) - return false; - var currentIndex = this.channelList_.indexOf(current); - var targetIndex = this.channelList_.indexOf(target); - if (currentIndex < 0 || targetIndex < 0) - return false; - return currentIndex < targetIndex; - }, - - /** - * @param {string} status The status of the update. - * @param {string} message Failure message to display. - * @private - */ - setUpdateStatus_: function(status, message) { - var oldStatus = this.status_; - this.status_ = status; - - if (oldStatus != status && oldStatus == 'disabled_by_admin') { - // If the auto update policy was recently re-enabled, then we'll - // re-enable the 'request-update' button. - this.haveNeverCheckedForUpdates_ = true; - } - - if (status == 'checking') - this.haveNeverCheckedForUpdates_ = false; - this.message_ = message; - - this.updateUI_(); - }, - - /** - * @param {string} eolStatus The EndofLife status of the device. - * @param {string} eolMessage The EndofLife message to display. - * @private - */ - updateEolMessage_: function(eolStatus, eolMessage) { - this.eolStatus_ = eolStatus; - this.eolMessage_ = eolMessage; - - this.updateUI_(); - }, - - /** - * Updates UI elements on the page according to current state. - * @private - */ - updateUI_: function() { - var status = this.status_; - var message = this.message_; - var channel = this.targetChannel_; - var eolStatus = this.eolStatus_; - var eolMessage = this.eolMessage_; - - if (this.channelList_.indexOf(channel) >= 0) { - $('current-channel').textContent = loadTimeData.getStringF( - 'currentChannel', this.channelTable_[channel].label); - this.updateChannelChangePageContainerVisibility_(); - if (cr.isChromeOS) - $('dev-channel-disclaimer').hidden = (channel != 'dev-channel'); - } - - if (status == null) - return; - - if (cr.isMac && - $('update-status-message') && - $('update-status-message').hidden) { - // Chrome has reached the end of the line on this system. The - // update-obsolete-system message is displayed. No other auto-update - // status should be displayed. - return; - } - - if (status == 'checking') { - this.setUpdateImage_('working'); - $('update-status-message').innerHTML = - loadTimeData.getString('updateCheckStarted'); - } else if (status == 'updating') { - this.setUpdateImage_('working'); - if (this.channelsDiffer_()) { - $('update-status-message').innerHTML = - loadTimeData.getStringF('updatingChannelSwitch', - this.channelTable_[channel].label); - } else { - $('update-status-message').innerHTML = - loadTimeData.getStringF('updating'); - } - } else if (status == 'nearly_updated') { - this.setUpdateImage_('up-to-date'); - if (this.channelsDiffer_()) { - $('update-status-message').innerHTML = - loadTimeData.getString('successfulChannelSwitch'); - } else { - $('update-status-message').innerHTML = - loadTimeData.getString('updateAlmostDone'); - } - } else if (status == 'updated') { - this.setUpdateImage_('up-to-date'); - $('update-status-message').innerHTML = - loadTimeData.getString('upToDate'); - } else if (status == 'failed') { - this.setUpdateImage_('failed'); - $('update-status-message').innerHTML = message; - } else if (status == 'disabled_by_admin') { - // This is the general behavior for non-chromeos. - this.setUpdateImage_('disabled-by-admin'); - $('update-status-message').innerHTML = message; - } - - // Show EndofLife Strings if applicable - if (eolStatus == 'device_supported') { - $('eol-status-container').hidden = true; - } else if (eolStatus == 'device_endoflife') { - $('eol-message').innerHTML = eolMessage; - $('eol-status-container').hidden = false; - } - - - if (cr.isChromeOS) { - $('change-channel').disabled = !this.canChangeChannel_ || - status == 'nearly_updated'; - $('channel-change-disallowed-icon').hidden = this.canChangeChannel_; - } - - // Following invariant must be established at the end of this function: - // { ~$('relaunch_and_powerwash').hidden -> $('relaunch').hidden } - var relaunchAndPowerwashHidden = true; - if ($('relaunch-and-powerwash')) { - // It's allowed to do powerwash only for customer devices, - // when user explicitly decides to update to a more stable - // channel. - relaunchAndPowerwashHidden = - !this.targetChannelIsMoreStable_() || status != 'nearly_updated'; - $('relaunch-and-powerwash').hidden = relaunchAndPowerwashHidden; - } - - if (cr.isChromeOS) { - // Re-enable the update button if we are in a stale 'updated' status or - // update has failed, and disable it if there's an update in progress or - // updates are disabled by policy. - // In addition, Update button will be disabled when device is in eol - // status - $('request-update').disabled = - !((this.haveNeverCheckedForUpdates_ && status == 'updated') || - status == 'failed') || (eolStatus == 'device_endoflife'); - // If updates are disabled by policy, unhide the - // controlled-feature-icon. - $('controlled-feature-icon').hidden = (status != 'disabled_by_admin'); - // If updates are no longer disabled by policy and the tooltip bubble - // is present, we hide it. - if (status != 'disabled_by_admin' && $('controlled-feature-bubble')) - $('controlled-feature-bubble').hide(); - } - - var container = $('update-status-container'); - if (container) { - container.hidden = status == 'disabled'; - $('relaunch').hidden = - (status != 'nearly_updated') || !relaunchAndPowerwashHidden; - - if (cr.isChromeOS) { - // Assume the "updated" status is stale if we haven't checked yet. - if (status == 'updated' && this.haveNeverCheckedForUpdates_ || - status == 'disabled_by_admin' || - eolStatus == 'device_endoflife') { - container.hidden = true; - } - - // Hide the request update button if auto-updating is disabled or - // a relaunch button is showing. - $('request-update').hidden = status == 'disabled' || - !$('relaunch').hidden || !relaunchAndPowerwashHidden; - } - - if (!cr.isMac) - $('update-percentage').hidden = status != 'updating'; - } - }, - - /** - * @param {number} progress The percent completion. - * @private - */ - setProgress_: function(progress) { - $('update-percentage').innerHTML = progress + '%'; - }, - - /** - * @param {string} message The allowed connection types message. - * @private - */ - setAllowedConnectionTypesMsg_: function(message) { - $('allowed-connection-types-message').innerText = message; - }, - - /** - * @param {boolean} visible Whether to show the message. - * @private - */ - showAllowedConnectionTypesMsg_: function(visible) { - $('allowed-connection-types-message').hidden = !visible; - }, - - /** - * @param {string} state The promote state to set. - * @private - */ - setPromotionState_: function(state) { - if (state == 'hidden') { - $('promote').hidden = true; - } else if (state == 'enabled') { - $('promote').disabled = false; - $('promote').hidden = false; - } else if (state == 'disabled') { - $('promote').disabled = true; - $('promote').hidden = false; - } - }, - - /** - * @param {boolean} obsolete Whether the system is obsolete. - * @private - */ - setObsoleteSystem_: function(obsolete) { - if ($('update-obsolete-system-container')) { - $('update-obsolete-system-container').hidden = !obsolete; - } - }, - - /** - * @param {boolean} endOfTheLine Whether the train has rolled into - * the station. - * @private - */ - setObsoleteSystemEndOfTheLine_: function(endOfTheLine) { - if ($('update-obsolete-system-container') && - !$('update-obsolete-system-container').hidden && - $('update-status-message')) { - $('update-status-message').hidden = endOfTheLine; - if (endOfTheLine) { - this.setUpdateImage_('failed'); - } - } - }, - - /** - * @param {string} version Version of Chrome OS. - * @private - */ - setOSVersion_: function(version) { - if (!cr.isChromeOS) - console.error('OS version unsupported on non-CrOS'); - - $('os-version').parentNode.hidden = (version == ''); - $('os-version').textContent = version; - }, - - /** - * @param {string} version Version of ARC. - * @private - */ - setARCVersion_: function(version) { - if (!cr.isChromeOS) - console.error('ARC version unsupported on non-CrOS'); - - $('arc-version').parentNode.hidden = (version == ''); - $('arc-version').textContent = version; - }, - - /** - * @param {string} firmware Firmware on Chrome OS. - * @private - */ - setOSFirmware_: function(firmware) { - if (!cr.isChromeOS) - console.error('OS firmware unsupported on non-CrOS'); - - $('firmware').parentNode.hidden = (firmware == ''); - $('firmware').textContent = firmware; - }, - - /** - * Updates page UI according to device owhership policy. - * @param {boolean} isEnterpriseManaged True if the device is - * enterprise managed. - * @private - */ - updateIsEnterpriseManaged_: function(isEnterpriseManaged) { - help.ChannelChangePage.updateIsEnterpriseManaged(isEnterpriseManaged); - this.updateUI_(); - }, - - /** - * Updates name of the current channel, i.e. the name of the - * channel the device is currently on. - * @param {string} channel The name of the current channel. - * @private - */ - updateCurrentChannel_: function(channel) { - if (this.channelList_.indexOf(channel) < 0) - return; - this.currentChannel_ = channel; - help.ChannelChangePage.updateCurrentChannel(channel); - this.updateUI_(); - }, - - /** - * Updates name of the target channel, i.e. the name of the - * channel the device is supposed to be. - * @param {string} channel The name of the target channel. - * @private - */ - updateTargetChannel_: function(channel) { - if (this.channelList_.indexOf(channel) < 0) - return; - this.targetChannel_ = channel; - help.ChannelChangePage.updateTargetChannel(channel); - this.updateUI_(); - }, - - /** - * @param {boolean} enabled True if the release channel can be enabled. - * @private - */ - updateEnableReleaseChannel_: function(enabled) { - this.updateChannelChangerContainerVisibility_(enabled); - this.canChangeChannel_ = enabled; - this.updateUI_(); - }, - - /** - * Sets the device target channel. - * @param {string} channel The name of the target channel. - * @param {boolean} isPowerwashAllowed True iff powerwash is allowed. - * @private - */ - setChannel_: function(channel, isPowerwashAllowed) { - chrome.send('setChannel', [channel, isPowerwashAllowed]); - $('channel-change-confirmation').hidden = false; - $('channel-change-confirmation').textContent = loadTimeData.getStringF( - 'channel-changed', this.channelTable_[channel].name); - this.updateTargetChannel_(channel); - }, - - /** - * Sets the value of the "Build Date" field of the "More Info" section. - * @param {string} buildDate The date of the build. - * @private - */ - setBuildDate_: function(buildDate) { - $('build-date-container').classList.remove('empty'); - $('build-date').textContent = buildDate; - }, - - /** - * Updates channel-change-page-container visibility according to - * internal state. - * @private - */ - updateChannelChangePageContainerVisibility_: function() { - if (!this.isNewChannelSwitcherUI_()) { - $('channel-change-page-container').hidden = true; - return; - } - $('channel-change-page-container').hidden = - !help.ChannelChangePage.isPageReady(); - }, - - /** - * Updates channel-changer dropdown visibility if |visible| is - * true and new channel switcher UI is disallowed. - * @param {boolean} visible True if channel-changer should be - * displayed, false otherwise. - * @private - */ - updateChannelChangerContainerVisibility_: function(visible) { - if (this.isNewChannelSwitcherUI_()) { - $('channel-changer').hidden = true; - return; - } - $('channel-changer').hidden = !visible; - }, - - /** - * Sets the regulatory label's source. - * @param {string} path The path to use for the image. - * @private - */ - setRegulatoryLabelPath_: function(path) { - $('regulatory-label').src = path; - }, - - /** - * Sets the regulatory label's alt text. - * @param {string} text The text to use for the image. - * @private - */ - setRegulatoryLabelText_: function(text) { - $('regulatory-label').alt = text; - }, - }; - - HelpPage.setUpdateStatus = function(status, message) { - HelpPage.getInstance().setUpdateStatus_(status, message); - }; - - HelpPage.setProgress = function(progress) { - HelpPage.getInstance().setProgress_(progress); - }; - - HelpPage.setAndShowAllowedConnectionTypesMsg = function(message) { - HelpPage.getInstance().setAllowedConnectionTypesMsg_(message); - HelpPage.getInstance().showAllowedConnectionTypesMsg_(true); - }; - - HelpPage.showAllowedConnectionTypesMsg = function(visible) { - HelpPage.getInstance().showAllowedConnectionTypesMsg_(visible); - }; - - HelpPage.setPromotionState = function(state) { - HelpPage.getInstance().setPromotionState_(state); - }; - - HelpPage.setObsoleteSystem = function(obsolete) { - HelpPage.getInstance().setObsoleteSystem_(obsolete); - }; - - HelpPage.setObsoleteSystemEndOfTheLine = function(endOfTheLine) { - HelpPage.getInstance().setObsoleteSystemEndOfTheLine_(endOfTheLine); - }; - - HelpPage.setOSVersion = function(version) { - HelpPage.getInstance().setOSVersion_(version); - }; - - HelpPage.setARCVersion = function(version) { - HelpPage.getInstance().setARCVersion_(version); - }; - - HelpPage.setOSFirmware = function(firmware) { - HelpPage.getInstance().setOSFirmware_(firmware); - }; - - HelpPage.updateIsEnterpriseManaged = function(isEnterpriseManaged) { - if (!cr.isChromeOS) - return; - HelpPage.getInstance().updateIsEnterpriseManaged_(isEnterpriseManaged); - }; - - HelpPage.updateCurrentChannel = function(channel) { - if (!cr.isChromeOS) - return; - HelpPage.getInstance().updateCurrentChannel_(channel); - }; - - HelpPage.updateTargetChannel = function(channel) { - if (!cr.isChromeOS) - return; - HelpPage.getInstance().updateTargetChannel_(channel); - }; - - HelpPage.updateEnableReleaseChannel = function(enabled) { - HelpPage.getInstance().updateEnableReleaseChannel_(enabled); - }; - - HelpPage.setChannel = function(channel, isPowerwashAllowed) { - HelpPage.getInstance().setChannel_(channel, isPowerwashAllowed); - }; - - HelpPage.setBuildDate = function(buildDate) { - HelpPage.getInstance().setBuildDate_(buildDate); - }; - - HelpPage.setRegulatoryLabelPath = function(path) { - assert(cr.isChromeOS); - HelpPage.getInstance().setRegulatoryLabelPath_(path); - }; - - HelpPage.setRegulatoryLabelText = function(text) { - assert(cr.isChromeOS); - HelpPage.getInstance().setRegulatoryLabelText_(text); - }; - - HelpPage.updateEolMessage = function(eolStatus, eolMessage) { - assert(cr.isChromeOS); - HelpPage.getInstance().updateEolMessage_(eolStatus, eolMessage); - }; - - // Export - return { - HelpPage: HelpPage - }; -});
diff --git a/chrome/browser/resources/md_extensions/detail_view.html b/chrome/browser/resources/md_extensions/detail_view.html index bb228b8f..831c2134 100644 --- a/chrome/browser/resources/md_extensions/detail_view.html +++ b/chrome/browser/resources/md_extensions/detail_view.html
@@ -3,6 +3,7 @@ <link rel="import" href="chrome://resources/cr_elements/cr_icons_css.html"> <link rel="import" href="chrome://resources/cr_elements/hidden_style_css.html"> <link rel="import" href="chrome://resources/cr_elements/paper_toggle_style_css.html"> +<link rel="import" href="chrome://resources/cr_elements/policy/cr_tooltip_icon.html"> <link rel="import" href="chrome://resources/html/action_link.html"> <link rel="import" href="chrome://resources/html/action_link_css.html"> <link rel="import" href="chrome://resources/html/cr.html"> @@ -18,6 +19,7 @@ <style include= "iron-flex cr-hidden-style cr-icons action-link paper-toggle-style"> :host { + --iron-icon-fill-color: var(--paper-grey-600); display: block; height: 100%; overflow: auto; @@ -67,6 +69,10 @@ padding: 0 20px; } + #enable-section cr-tooltip-icon { + -webkit-margin-end: 20px; + } + .section { border-bottom: 1px solid var(--paper-grey-400); padding: 16px 20px; @@ -118,11 +124,18 @@ </div> <div class="control-line" id="enable-section"> <span>[[computeEnabledText_(data.*)]]</span> - <paper-toggle-button id="enable-toggle" - checked="[[isEnabled_(data.state)]]" - on-change="onEnableChange_" - disabled="[[!isEnableToggleEnabled_(data.*)]]"> - </paper-toggle-button> + <div class="layout horizontal"> + <cr-tooltip-icon hidden$="[[!data.controlledInfo]]" + tooltip-text="[[data.controlledInfo.text]]" + icon-class="[[getIndicatorIcon_(data.controlledInfo.type)]]" + icon-aria-label="[[data.controlledInfo.type]]"> + </cr-tooltip-icon> + <paper-toggle-button id="enable-toggle" + checked="[[isEnabled_(data.state)]]" + on-change="onEnableChange_" + disabled="[[!isEnableToggleEnabled_(data.*)]]"> + </paper-toggle-button> + </div> </div> <div class="section"> <div class="section-title">$i18n{itemDescriptionLabel}</div>
diff --git a/chrome/browser/resources/md_extensions/detail_view.js b/chrome/browser/resources/md_extensions/detail_view.js index 82057c7..d98d860 100644 --- a/chrome/browser/resources/md_extensions/detail_view.js +++ b/chrome/browser/resources/md_extensions/detail_view.js
@@ -177,7 +177,25 @@ computeSourceString_: function() { return extensions.getItemSourceString( extensions.getItemSource(this.data)); - } + }, + + /** + * @param {chrome.developerPrivate.ControllerType} type + * @return {string} + * @private + */ + getIndicatorIcon_: function(type) { + switch (type) { + case 'POLICY': + return 'cr20:domain'; + case 'CHILD_CUSTODIAN': + return 'cr:account-child-invert'; + case 'SUPERVISED_USER_CUSTODIAN': + return 'cr:supervisor-account'; + default: + return ''; + } + }, }); return {DetailView: DetailView};
diff --git a/chrome/browser/resources/options/2x/yellow_gear.png b/chrome/browser/resources/options/2x/yellow_gear.png deleted file mode 100644 index 087c8a3..0000000 --- a/chrome/browser/resources/options/2x/yellow_gear.png +++ /dev/null Binary files differ
diff --git a/chrome/browser/resources/options/OWNERS b/chrome/browser/resources/options/OWNERS deleted file mode 100644 index 68aba13..0000000 --- a/chrome/browser/resources/options/OWNERS +++ /dev/null
@@ -1,3 +0,0 @@ -# This UI is deprecated. See chrome/browser/resources/settings/ instead. -michaelpg@chromium.org -stevenjb@chromium.org
diff --git a/chrome/browser/resources/options/alert_overlay.css b/chrome/browser/resources/options/alert_overlay.css deleted file mode 100644 index b2d9960a..0000000 --- a/chrome/browser/resources/options/alert_overlay.css +++ /dev/null
@@ -1,7 +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. */ - -#alertOverlayMessage { - width: 400px; -}
diff --git a/chrome/browser/resources/options/alert_overlay.html b/chrome/browser/resources/options/alert_overlay.html deleted file mode 100644 index 2c96ff1..0000000 --- a/chrome/browser/resources/options/alert_overlay.html +++ /dev/null
@@ -1,13 +0,0 @@ -<div id="alertOverlay" class="page" hidden> - <div class="close-button"></div> - <h1 id="alertOverlayTitle"></h1> - <div class="content-area"> - <div id="alertOverlayMessage"></div> - </div> - <div class="action-area"> - <div class="button-strip"> - <button id="alertOverlayCancel" type="reset"></button> - <button id="alertOverlayOk" class="default-button" type="submit"></button> - </div> - </div> -</div>
diff --git a/chrome/browser/resources/options/alert_overlay.js b/chrome/browser/resources/options/alert_overlay.js deleted file mode 100644 index 2206517d..0000000 --- a/chrome/browser/resources/options/alert_overlay.js +++ /dev/null
@@ -1,147 +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. - -cr.define('options', function() { - var Page = cr.ui.pageManager.Page; - var PageManager = cr.ui.pageManager.PageManager; - - /** - * AlertOverlay class - * Encapsulated handling of a generic alert. - * @constructor - * @extends {cr.ui.pageManager.Page} - */ - function AlertOverlay() { - Page.call(this, 'alertOverlay', '', 'alertOverlay'); - } - - cr.addSingletonGetter(AlertOverlay); - - AlertOverlay.prototype = { - // Inherit AlertOverlay from Page. - __proto__: Page.prototype, - - /** - * Whether the page can be shown. Used to make sure the page is only - * shown via AlertOverlay.Show(), and not via the address bar. - * @private - */ - canShow_: false, - - /** @override */ - initializePage: function() { - Page.prototype.initializePage.call(this); - - // AlertOverlay is special in that it is not tied to one page or overlay. - this.alwaysOnTop = true; - - var self = this; - $('alertOverlayOk').onclick = function(event) { - self.handleOK_(); - }; - - $('alertOverlayCancel').onclick = function(event) { - self.handleCancel_(); - }; - }, - - /** - * Handle the 'ok' button. Clear the overlay and call the ok callback if - * available. - * @private - */ - handleOK_: function() { - PageManager.closeOverlay(); - if (this.okCallback != undefined) { - this.okCallback.call(); - } - }, - - /** - * Handle the 'cancel' button. Clear the overlay and call the cancel - * callback if available. - * @private - */ - handleCancel_: function() { - PageManager.closeOverlay(); - if (this.cancelCallback != undefined) { - this.cancelCallback.call(); - } - }, - - /** - * The page is getting hidden. Don't let it be shown again. - * @override - */ - willHidePage: function() { - this.canShow_ = false; - }, - - /** @override */ - canShowPage: function() { - return this.canShow_; - }, - }; - - /** - * Show an alert overlay with the given message, button titles, and - * callbacks. - * @param {string} title The alert title to display to the user. - * @param {string} message The alert message to display to the user. - * @param {string} okTitle The title of the OK button. If undefined or empty, - * no button is shown. - * @param {string} cancelTitle The title of the cancel button. If undefined or - * empty, no button is shown. - * @param {function()} okCallback A function to be called when the user - * presses the ok button. The alert window will be closed automatically. - * Can be undefined. - * @param {function()} cancelCallback A function to be called when the user - * presses the cancel button. The alert window will be closed - * automatically. Can be undefined. - */ - AlertOverlay.show = function( - title, message, okTitle, cancelTitle, okCallback, cancelCallback) { - if (title != undefined) { - $('alertOverlayTitle').textContent = title; - $('alertOverlayTitle').style.display = 'block'; - } else { - $('alertOverlayTitle').style.display = 'none'; - } - - if (message != undefined) { - $('alertOverlayMessage').textContent = message; - $('alertOverlayMessage').style.display = 'block'; - } else { - $('alertOverlayMessage').style.display = 'none'; - } - - if (okTitle != undefined && okTitle != '') { - $('alertOverlayOk').textContent = okTitle; - $('alertOverlayOk').style.display = 'block'; - } else { - $('alertOverlayOk').style.display = 'none'; - } - - if (cancelTitle != undefined && cancelTitle != '') { - $('alertOverlayCancel').textContent = cancelTitle; - $('alertOverlayCancel').style.display = 'inline'; - } else { - $('alertOverlayCancel').style.display = 'none'; - } - - var alertOverlay = AlertOverlay.getInstance(); - alertOverlay.okCallback = okCallback; - alertOverlay.cancelCallback = cancelCallback; - alertOverlay.canShow_ = true; - - // Intentionally don't show the URL in the location bar as we don't want - // people trying to navigate here by hand. - PageManager.showPageByName('alertOverlay', false); - }; - - // Export - return { - AlertOverlay: AlertOverlay - }; -});
diff --git a/chrome/browser/resources/options/autofill_edit_address_overlay.html b/chrome/browser/resources/options/autofill_edit_address_overlay.html deleted file mode 100644 index 980d9ba..0000000 --- a/chrome/browser/resources/options/autofill_edit_address_overlay.html +++ /dev/null
@@ -1,42 +0,0 @@ -<div id="autofill-edit-address-overlay" class="page" hidden> - <div class="close-button"></div> - <h1 id="autofill-address-title"></h1> - <div class="content-area"> - <div id="autofill-edit-address-fields"> - </div> - - <div class="settings-row"> - <label> - <div>$i18n{autofillCountryLabel}</div> - <select class="country" field="country"></select> - </label> - </div> - - <div class="input-group settings-row"> - <div> - <label> - <div>$i18n{autofillPhoneLabel}</div> - <input class="short" field="phone"></input> - </label> - </div> - - <div> - <label> - <div>$i18n{autofillEmailLabel}</div> - <input class="short" field="email"></input> - </label> - </div> - </div> - - </div> - - <div class="action-area button-strip"> - <button id="autofill-edit-address-cancel-button" type="reset"> - $i18n{cancel} - </button> - <button id="autofill-edit-address-apply-button" type="submit" - class="default-button" disabled> - $i18n{ok} - </button> - </div> -</div>
diff --git a/chrome/browser/resources/options/autofill_edit_address_overlay.js b/chrome/browser/resources/options/autofill_edit_address_overlay.js deleted file mode 100644 index c9e5440..0000000 --- a/chrome/browser/resources/options/autofill_edit_address_overlay.js +++ /dev/null
@@ -1,350 +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. - -cr.define('options', function() { - /** @const */ var Page = cr.ui.pageManager.Page; - /** @const */ var PageManager = cr.ui.pageManager.PageManager; - /** @const */ var ArrayDataModel = cr.ui.ArrayDataModel; - - /** - * AutofillEditAddressOverlay class - * Encapsulated handling of the 'Add Page' overlay page. - * @constructor - * @extends {cr.ui.pageManager.Page} - */ - function AutofillEditAddressOverlay() { - Page.call(this, 'autofillEditAddress', - loadTimeData.getString('autofillEditAddressTitle'), - 'autofill-edit-address-overlay'); - } - - cr.addSingletonGetter(AutofillEditAddressOverlay); - - AutofillEditAddressOverlay.prototype = { - __proto__: Page.prototype, - - /** - * The GUID of the loaded address. - * @type {string} - */ - guid_: '', - - /** - * The BCP 47 language code for the layout of input fields. - * @type {string} - */ - languageCode_: '', - - /** - * The saved field values for the address. For example, if the user changes - * from United States to Switzerland, then the State field will be hidden - * and its value will be stored here. If the user changes back to United - * States, then the State field will be restored to its previous value, as - * stored in this object. - * @type {Object} - */ - savedFieldValues_: {}, - - /** @override */ - initializePage: function() { - Page.prototype.initializePage.call(this); - - var self = this; - $('autofill-edit-address-cancel-button').onclick = function(event) { - self.dismissOverlay_(); - }; - - // TODO(jhawkins): Investigate other possible solutions. - $('autofill-edit-address-apply-button').onclick = function(event) { - // Blur active element to ensure that pending changes are committed. - if (document.activeElement) - document.activeElement.blur(); - self.saveAddress_(); - self.dismissOverlay_(); - }; - - this.guid_ = ''; - this.populateCountryList_(); - this.rebuildInputFields_(/** @type {Array<Array<Object>>} */( - loadTimeData.getValue('autofillDefaultCountryComponents'))); - this.languageCode_ = - loadTimeData.getString('autofillDefaultCountryLanguageCode'); - this.connectInputEvents_(); - this.setInputFields_({}); - this.getCountrySwitcher_().onchange = function(event) { - self.countryChanged_(); - }; - }, - - /** - * Specifically catch the situations in which the overlay is cancelled - * externally (e.g. by pressing <Esc>), so that the input fields and - * GUID can be properly cleared. - * @override - */ - handleCancel: function() { - this.dismissOverlay_(); - }, - - /** - * Clears any uncommitted input, resets the stored GUID and dismisses the - * overlay. - * @private - */ - dismissOverlay_: function() { - this.setInputFields_({}); - this.inputFieldChanged_(); - this.guid_ = ''; - this.languageCode_ = ''; - this.savedInputFields_ = {}; - PageManager.closeOverlay(); - }, - - /** - * @return {Element} The element used to switch countries. - * @private - */ - getCountrySwitcher_: function() { - return this.pageDiv.querySelector('[field=country]'); - }, - - /** - * Returns all text input elements. - * @return {!NodeList} The text input elements. - * @private - */ - getTextFields_: function() { - return this.pageDiv.querySelectorAll('textarea[field], input[field]'); - }, - - /** - * Creates a map from type => value for all text fields. - * @return {Object} The mapping from field names to values. - * @private - */ - getInputFields_: function() { - var address = {country: this.getCountrySwitcher_().value}; - - var fields = this.getTextFields_(); - for (var i = 0; i < fields.length; i++) { - address[fields[i].getAttribute('field')] = fields[i].value; - } - - return address; - }, - - /** - * Sets the value of each input field according to |address|. - * @param {Object} address The object with values to use. - * @private - */ - setInputFields_: function(address) { - this.getCountrySwitcher_().value = address.country || ''; - - var fields = this.getTextFields_(); - for (var i = 0; i < fields.length; i++) { - fields[i].value = address[fields[i].getAttribute('field')] || ''; - } - }, - - /** - * Aggregates the values in the input fields into an array and sends the - * array to the Autofill handler. - * @private - */ - saveAddress_: function() { - var inputFields = this.getInputFields_(); - var address = [ - this.guid_, - inputFields['fullName'] || [], - inputFields['companyName'] || '', - inputFields['addrLines'] || '', - inputFields['dependentLocality'] || '', - inputFields['city'] || '', - inputFields['state'] || '', - inputFields['postalCode'] || '', - inputFields['sortingCode'] || '', - inputFields['country'] || loadTimeData.getString('defaultCountryCode'), - inputFields['phone'] || [], - inputFields['email'] || [], - this.languageCode_, - ]; - chrome.send('setAddress', address); - - // If the GUID is empty, this form is being used to add a new address, - // rather than edit an existing one. - if (!this.guid_.length) { - chrome.send('coreOptionsUserMetricsAction', - ['Options_AutofillAddressAdded']); - } - }, - - /** - * Connects each input field to the inputFieldChanged_() method that enables - * or disables the 'Ok' button based on whether all the fields are empty or - * not. - * @private - */ - connectInputEvents_: function() { - var fields = this.getTextFields_(); - for (var i = 0; i < fields.length; i++) { - fields[i].oninput = this.inputFieldChanged_.bind(this); - } - }, - - /** - * Disables the 'Ok' button if all of the fields are empty. - * @private - */ - inputFieldChanged_: function() { - var disabled = !this.getCountrySwitcher_().value; - if (disabled) { - var fields = this.getTextFields_(); - for (var i = 0; i < fields.length; i++) { - if (fields[i].value) { - disabled = false; - break; - } - } - } - - $('autofill-edit-address-apply-button').disabled = disabled; - }, - - /** - * Updates the address fields appropriately for the selected country. - * @private - */ - countryChanged_: function() { - var countryCode = this.getCountrySwitcher_().value; - if (countryCode) - chrome.send('loadAddressEditorComponents', [countryCode]); - else - this.inputFieldChanged_(); - }, - - /** - * Populates the country <select> list. - * @private - */ - populateCountryList_: function() { - var countryList = loadTimeData.getValue('autofillCountrySelectList'); - - // Add the countries to the country <select>. - var countrySelect = this.getCountrySwitcher_(); - // Add an empty option. - countrySelect.appendChild(new Option('', '')); - for (var i = 0; i < countryList.length; i++) { - var option = new Option(countryList[i].name, - countryList[i].value); - option.disabled = countryList[i].value == 'separator'; - countrySelect.appendChild(option); - } - }, - - /** - * Called to prepare the overlay when a new address is being added. - * @private - */ - prepForNewAddress_: function() { - // Focus the first element. - this.pageDiv.querySelector('input').focus(); - }, - - /** - * Loads the address data from |address|, sets the input fields based on - * this data, and stores the GUID and language code of the address. - * @param {!Object} address Lots of info about an address from the browser. - * @private - */ - loadAddress_: function(address) { - this.rebuildInputFields_(address.components); - this.setInputFields_(address); - this.inputFieldChanged_(); - this.connectInputEvents_(); - this.guid_ = address.guid; - this.languageCode_ = address.languageCode; - }, - - /** - * Takes a snapshot of the input values, clears the input values, loads the - * address input layout from |input.components|, restores the input values - * from snapshot, and stores the |input.languageCode| for the address. - * @param {{languageCode: string, components: Array<Array<Object>>}} input - * Info about how to layout inputs fields in this dialog. - * @private - */ - loadAddressComponents_: function(input) { - var inputFields = this.getInputFields_(); - for (var fieldName in inputFields) { - if (inputFields.hasOwnProperty(fieldName)) - this.savedFieldValues_[fieldName] = inputFields[fieldName]; - } - this.rebuildInputFields_(input.components); - this.setInputFields_(this.savedFieldValues_); - this.inputFieldChanged_(); - this.connectInputEvents_(); - this.languageCode_ = input.languageCode; - }, - - /** - * Clears address inputs and rebuilds the input fields according to - * |components|. - * @param {Array<Array<Object>>} components A list of information about - * each input field. - * @private - */ - rebuildInputFields_: function(components) { - var content = $('autofill-edit-address-fields'); - content.innerHTML = ''; - - var customInputElements = {addrLines: 'textarea'}; - - for (var i = 0; i < components.length; i++) { - var row = document.createElement('div'); - row.classList.add('input-group', 'settings-row'); - content.appendChild(row); - - for (var j = 0; j < components[i].length; j++) { - if (components[i][j].field == 'country') - continue; - - var fieldContainer = document.createElement('label'); - row.appendChild(fieldContainer); - - var fieldName = document.createElement('div'); - fieldName.textContent = components[i][j].name; - fieldContainer.appendChild(fieldName); - - var input = document.createElement( - customInputElements[components[i][j].field] || 'input'); - input.setAttribute('field', components[i][j].field); - input.classList.add(components[i][j].length); - fieldContainer.appendChild(input); - } - } - }, - }; - - AutofillEditAddressOverlay.prepForNewAddress = function() { - AutofillEditAddressOverlay.getInstance().prepForNewAddress_(); - }; - - AutofillEditAddressOverlay.loadAddress = function(address) { - AutofillEditAddressOverlay.getInstance().loadAddress_(address); - }; - - AutofillEditAddressOverlay.loadAddressComponents = function(input) { - AutofillEditAddressOverlay.getInstance().loadAddressComponents_(input); - }; - - AutofillEditAddressOverlay.setTitle = function(title) { - $('autofill-address-title').textContent = title; - }; - - // Export - return { - AutofillEditAddressOverlay: AutofillEditAddressOverlay - }; -});
diff --git a/chrome/browser/resources/options/autofill_edit_creditcard_overlay.html b/chrome/browser/resources/options/autofill_edit_creditcard_overlay.html deleted file mode 100644 index 9b2c5f8..0000000 --- a/chrome/browser/resources/options/autofill_edit_creditcard_overlay.html +++ /dev/null
@@ -1,35 +0,0 @@ -<div id="autofill-edit-credit-card-overlay" class="page" hidden> - <div class="close-button"></div> - <h1 id="autofill-credit-card-title"></h1> - <div class="content-area"> - <label class="settings-row"> - <div>$i18n{nameOnCardLabel}</div> - <input id="name-on-card" type="text"> - </label> - - <label class="settings-row"> - <div>$i18n{creditCardNumberLabel}</div> - <input id="credit-card-number" type="text"> - </label> - - <div class="settings-row"> - <div id="creditCardExpirationLabel"> - $i18n{creditCardExpirationDateLabel} - </div> - <select id="expiration-month" aria-labelledby="creditCardExpirationLabel"> - </select> - <select id="expiration-year" aria-labelledby="creditCardExpirationLabel"> - </select> - </div> - </div> - - <div class="action-area button-strip"> - <button id="autofill-edit-credit-card-cancel-button" type="reset"> - $i18n{cancel} - </button> - <button id="autofill-edit-credit-card-apply-button" type="submit" - class="default-button" disabled> - $i18n{ok} - </button> - </div> -</div>
diff --git a/chrome/browser/resources/options/autofill_edit_creditcard_overlay.js b/chrome/browser/resources/options/autofill_edit_creditcard_overlay.js deleted file mode 100644 index 369b7d9..0000000 --- a/chrome/browser/resources/options/autofill_edit_creditcard_overlay.js +++ /dev/null
@@ -1,223 +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. - -cr.define('options', function() { - /** @const */ var Page = cr.ui.pageManager.Page; - /** @const */ var PageManager = cr.ui.pageManager.PageManager; - - /** - * AutofillEditCreditCardOverlay class - * Encapsulated handling of the 'Add Page' overlay page. - * @class - */ - function AutofillEditCreditCardOverlay() { - Page.call(this, 'autofillEditCreditCard', - loadTimeData.getString('autofillEditCreditCardTitle'), - 'autofill-edit-credit-card-overlay'); - } - - cr.addSingletonGetter(AutofillEditCreditCardOverlay); - - AutofillEditCreditCardOverlay.prototype = { - __proto__: Page.prototype, - - /** @override */ - initializePage: function() { - Page.prototype.initializePage.call(this); - - var self = this; - $('autofill-edit-credit-card-cancel-button').onclick = function(event) { - self.dismissOverlay_(); - }; - $('autofill-edit-credit-card-apply-button').onclick = function(event) { - self.saveCreditCard_(); - self.dismissOverlay_(); - }; - - self.guid_ = ''; - self.clearInputFields_(); - self.connectInputEvents_(); - self.setDefaultSelectOptions_(); - }, - - /** - * Specifically catch the situations in which the overlay is cancelled - * externally (e.g. by pressing <Esc>), so that the input fields and - * GUID can be properly cleared. - * @override - */ - handleCancel: function() { - this.dismissOverlay_(); - }, - - /** - * Clears any uncommitted input, and dismisses the overlay. - * @private - */ - dismissOverlay_: function() { - this.clearInputFields_(); - this.guid_ = ''; - PageManager.closeOverlay(); - }, - - /** - * Aggregates the values in the input fields into an array and sends the - * array to the Autofill handler. - * @private - */ - saveCreditCard_: function() { - var creditCard = new Array(5); - creditCard[0] = this.guid_; - creditCard[1] = $('name-on-card').value; - creditCard[2] = $('credit-card-number').value; - creditCard[3] = $('expiration-month').value; - creditCard[4] = $('expiration-year').value; - chrome.send('setCreditCard', creditCard); - - // If the GUID is empty, this form is being used to add a new card, - // rather than edit an existing one. - if (!this.guid_.length) { - chrome.send('coreOptionsUserMetricsAction', - ['Options_AutofillCreditCardAdded']); - } - }, - - /** - * Connects each input field to the inputFieldChanged_() method that enables - * or disables the 'Ok' button based on whether all the fields are empty or - * not. - * @private - */ - connectInputEvents_: function() { - var ccNumber = $('credit-card-number'); - $('name-on-card').oninput = ccNumber.oninput = - $('expiration-month').onchange = $('expiration-year').onchange = - this.inputFieldChanged_.bind(this); - }, - - /** - * Checks the values of each of the input fields and disables the 'Ok' - * button if all of the fields are empty. - * @param {Event} opt_event Optional data for the 'input' event. - * @private - */ - inputFieldChanged_: function(opt_event) { - var disabled = !$('name-on-card').value.trim() && - !$('credit-card-number').value.trim(); - $('autofill-edit-credit-card-apply-button').disabled = disabled; - }, - - /** - * Sets the default values of the options in the 'Expiration date' select - * controls. - * @private - */ - setDefaultSelectOptions_: function() { - // Set the 'Expiration month' default options. - var expirationMonth = $('expiration-month'); - expirationMonth.options.length = 0; - for (var i = 1; i <= 12; ++i) { - var text = (i < 10 ? '0' : '') + i; - - var option = document.createElement('option'); - option.text = option.value = text; - expirationMonth.add(option, null); - } - - // Set the 'Expiration year' default options. - var expirationYear = $('expiration-year'); - expirationYear.options.length = 0; - - var date = new Date(); - var year = parseInt(date.getFullYear(), 10); - for (var i = 0; i < 10; ++i) { - var text = year + i; - var option = document.createElement('option'); - option.text = String(text); - option.value = text; - expirationYear.add(option, null); - } - }, - - /** - * Clears the value of each input field. - * @private - */ - clearInputFields_: function() { - $('name-on-card').value = ''; - $('credit-card-number').value = ''; - $('expiration-month').selectedIndex = 0; - $('expiration-year').selectedIndex = 0; - - // Reset the enabled status of the 'Ok' button. - this.inputFieldChanged_(); - }, - - /** - * Sets the value of each input field according to |creditCard| - * @param {CreditCardData} creditCard - * @private - */ - setInputFields_: function(creditCard) { - $('name-on-card').value = creditCard.nameOnCard; - $('credit-card-number').value = creditCard.creditCardNumber; - - // The options for the year select control may be out-dated at this point, - // e.g. the user opened the options page before midnight on New Year's Eve - // and then loaded a credit card profile to edit in the new year, so - // reload the select options just to be safe. - this.setDefaultSelectOptions_(); - - var idx = parseInt(creditCard.expirationMonth, 10); - $('expiration-month').selectedIndex = idx - 1; - - var expYear = creditCard.expirationYear; - var date = new Date(); - var year = parseInt(date.getFullYear(), 10); - for (var i = 0; i < 10; ++i) { - var text = year + i; - if (expYear == String(text)) - $('expiration-year').selectedIndex = i; - } - }, - - /** - * Called to prepare the overlay when a new card is being added. - * @private - */ - prepForNewCard_: function() { - // Focus the first element. - this.pageDiv.querySelector('input').focus(); - }, - - /** - * Loads the credit card data from |creditCard|, sets the input fields based - * on this data and stores the GUID of the credit card. - * @param {CreditCardData} creditCard - * @private - */ - loadCreditCard_: function(creditCard) { - this.setInputFields_(creditCard); - this.inputFieldChanged_(); - this.guid_ = creditCard.guid; - }, - }; - - AutofillEditCreditCardOverlay.prepForNewCard = function() { - AutofillEditCreditCardOverlay.getInstance().prepForNewCard_(); - }; - - AutofillEditCreditCardOverlay.loadCreditCard = function(creditCard) { - AutofillEditCreditCardOverlay.getInstance().loadCreditCard_(creditCard); - }; - - AutofillEditCreditCardOverlay.setTitle = function(title) { - $('autofill-credit-card-title').textContent = title; - }; - - // Export - return { - AutofillEditCreditCardOverlay: AutofillEditCreditCardOverlay - }; -});
diff --git a/chrome/browser/resources/options/autofill_edit_overlay.css b/chrome/browser/resources/options/autofill_edit_overlay.css deleted file mode 100644 index 9f781319..0000000 --- a/chrome/browser/resources/options/autofill_edit_overlay.css +++ /dev/null
@@ -1,76 +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. */ - -#autofill-edit-address-overlay { - min-width: 55em; -} - -#autofill-edit-credit-card-overlay { - min-width: 500px; -} - -#autofill-edit-address-overlay .long div[role='listitem'] > div > div, -#autofill-edit-address-overlay .long input, -#autofill-edit-address-overlay textarea.long, -#autofill-edit-address-overlay input.long { - width: 16em; -} - -#autofill-edit-address-overlay .short div[role='listitem'] > div > div, -#autofill-edit-address-overlay .short input, -#autofill-edit-address-overlay textarea.short, -#autofill-edit-address-overlay input.short { - width: 14em; -} - -#autofill-edit-address-overlay .country { - max-width: 450px; -} - -#autofill-edit-address-overlay list { - -webkit-margin-start: -3px; - /* Min height is a multiple of the list item height (32px). */ - min-height: 32px; -} - -#autofill-edit-address-overlay list div.static-text { - -webkit-box-flex: 1; - -webkit-padding-end: 4px; - -webkit-padding-start: 4px; - border: 1px solid darkGray; - border-radius: 2px; - /* Border should go "inside" the height. */ - box-sizing: border-box; - /* Set the line-height and min-height to match the height of an input element, - * so that even empty cells renderer with the correct height. */ - height: 2em; - line-height: 2em; -} - -#autofill-edit-address-overlay list:not([has-element-focus]) > - [selected]:not(:hover) { - background-color: transparent; -} - -#autofill-edit-address-overlay list:not([has-element-focus]) > *:not(:hover) - .row-delete-button { - opacity: 0; - pointer-events: none; -} - -:-webkit-any(#autofill-edit-credit-card-overlay, #autofill-edit-address-overlay) - .settings-row label > :-webkit-any(input, select, textarea, list) { - margin-top: 4px; -} - -.input-group > * { - -webkit-box-orient: vertical; - -webkit-margin-end: 2px; - display: -webkit-inline-box; - vertical-align: top; -} - -#autofill-edit-credit-card-overlay .content-area > *:first-child { - margin-top: 0; -}
diff --git a/chrome/browser/resources/options/autofill_options.css b/chrome/browser/resources/options/autofill_options.css deleted file mode 100644 index dd131a6..0000000 --- a/chrome/browser/resources/options/autofill_options.css +++ /dev/null
@@ -1,68 +0,0 @@ -/* Copyright (c) 2012 The Chromium Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. */ - -#autofill-options { - width: 550px; -} - -#autofill-options list { - height: 192px; /* This is the min-height for lists from WebUI.*/ -} - -.autofill-list-item { - -webkit-padding-start: 8px; - max-width: 50%; - overflow: hidden; - text-overflow: ellipsis; -} - -.autofill-list-item + .deemphasized { - -webkit-box-flex: 1; - overflow: hidden; - text-overflow: ellipsis; -} - -#autofill-options > div:last-child { - margin-top: 15px; -} - -#autofill-options .deemphasized { - color: #777; -} - -#autofill-options > div.settings-list > div:last-child { - border-top: 1px solid #d9d9d9; - padding: 5px 10px; -} - -#autofill-add-address, -#autofill-add-creditcard { - margin: 5px 0; -} - -#autofill-options .list-inline-button { - -webkit-margin-start: 12px; - margin-top: 0; - vertical-align: top; -} - -#autofill-options div[role='listitem']:not(:hover):not([selected]) - .hide-until-hover { - display: none; -} - -#autofill-options div[role='listitem']:-webkit-any(:hover,[selected]) - .hides-on-hover { - display: none; -} - -.settings-list + .autofill-section-header { - margin-top: 20px; -} - -#autofill-options .autofill-section-header { - display: flex; - justify-content: space-between; - margin-bottom: 5px; -} \ No newline at end of file
diff --git a/chrome/browser/resources/options/autofill_options.html b/chrome/browser/resources/options/autofill_options.html deleted file mode 100644 index d820ebee..0000000 --- a/chrome/browser/resources/options/autofill_options.html +++ /dev/null
@@ -1,33 +0,0 @@ -<div id="autofill-options" class="page" hidden> - <div class="close-button"></div> - <h1>$i18n{autofillOptionsPage}</h1> - <div class="content-area"> - <div class="autofill-section-header"> - <h3>$i18n{autofillAddresses}</h3> - <button id="autofill-add-address">$i18n{autofillAddAddress}</button> - </div> - <div class="settings-list"> - <list id="address-list"></list> - </div> - <div class="autofill-section-header"> - <h3>$i18n{autofillCreditCards}</h3> - <button id="autofill-add-creditcard"> - $i18n{autofillAddCreditCard} - </button> - </div> - <div class="settings-list"> - <list id="creditcard-list"></list> - </div> - </div> - - <div class="action-area"> - <a id="autofill-help" target="_blank" - href="$i18nRaw{helpUrl}">$i18n{helpButton}</a> - <div class="spacer-div"></div> - <div class="button-strip"> - <button id="autofill-options-confirm" class="default-button"> - $i18n{done} - </button> - </div> - </div> -</div>
diff --git a/chrome/browser/resources/options/autofill_options.js b/chrome/browser/resources/options/autofill_options.js deleted file mode 100644 index 7f30000..0000000 --- a/chrome/browser/resources/options/autofill_options.js +++ /dev/null
@@ -1,218 +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. - -/** - * @typedef {{ - * creditCardNumber: string, - * expirationMonth: string, - * expirationYear: string, - * guid: string, - * nameOnCard: string - * }} - * @see chrome/browser/ui/webui/options/autofill_options_handler.cc - */ -var CreditCardData; - -cr.define('options', function() { - var Page = cr.ui.pageManager.Page; - var PageManager = cr.ui.pageManager.PageManager; - var ArrayDataModel = cr.ui.ArrayDataModel; - - ///////////////////////////////////////////////////////////////////////////// - // AutofillOptions class: - - /** - * Encapsulated handling of Autofill options page. - * @constructor - * @extends {cr.ui.pageManager.Page} - */ - function AutofillOptions() { - Page.call(this, 'autofill', - loadTimeData.getString('autofillOptionsPageTabTitle'), - 'autofill-options'); - } - - cr.addSingletonGetter(AutofillOptions); - - AutofillOptions.prototype = { - __proto__: Page.prototype, - - /** - * The address list. - * @type {options.DeletableItemList} - * @private - */ - addressList_: null, - - /** - * The credit card list. - * @type {options.DeletableItemList} - * @private - */ - creditCardList_: null, - - /** @override */ - initializePage: function() { - Page.prototype.initializePage.call(this); - - this.createAddressList_(); - this.createCreditCardList_(); - - var self = this; - $('autofill-add-address').onclick = function(event) { - self.showAddAddressOverlay_(); - }; - $('autofill-add-creditcard').onclick = function(event) { - self.showAddCreditCardOverlay_(); - }; - $('autofill-options-confirm').onclick = function(event) { - PageManager.closeOverlay(); - }; - - $('autofill-help').onclick = function(event) { - chrome.send('coreOptionsUserMetricsAction', - ['Options_AutofillShowAbout']); - return true; // Always follow the href - }; - - // TODO(jhawkins): What happens when Autofill is disabled whilst on the - // Autofill options page? - }, - - /** - * Creates, decorates and initializes the address list. - * @private - */ - createAddressList_: function() { - var addressList = $('address-list'); - options.autofillOptions.AutofillAddressList.decorate(addressList); - this.addressList_ = assertInstanceof(addressList, - options.DeletableItemList); - this.addressList_.autoExpands = true; - }, - - /** - * Creates, decorates and initializes the credit card list. - * @private - */ - createCreditCardList_: function() { - var creditCardList = $('creditcard-list'); - options.autofillOptions.AutofillCreditCardList.decorate(creditCardList); - this.creditCardList_ = assertInstanceof(creditCardList, - options.DeletableItemList); - this.creditCardList_.autoExpands = true; - }, - - /** - * Shows the 'Add address' overlay, specifically by loading the - * 'Edit address' overlay and modifying the overlay title. - * @private - */ - showAddAddressOverlay_: function() { - var title = loadTimeData.getString('addAddressTitle'); - AutofillEditAddressOverlay.setTitle(title); - PageManager.showPageByName('autofillEditAddress'); - AutofillEditAddressOverlay.prepForNewAddress(); - }, - - /** - * Shows the 'Add credit card' overlay, specifically by loading the - * 'Edit credit card' overlay and modifying the overlay title. - * @private - */ - showAddCreditCardOverlay_: function() { - var title = loadTimeData.getString('addCreditCardTitle'); - AutofillEditCreditCardOverlay.setTitle(title); - PageManager.showPageByName('autofillEditCreditCard'); - AutofillEditCreditCardOverlay.prepForNewCard(); - }, - - /** - * Updates the data model for the address list with the values from - * |entries|. - * @param {!Array} entries The list of addresses. - */ - setAddressList_: function(entries) { - this.addressList_.dataModel = new ArrayDataModel(entries); - }, - - /** - * Updates the data model for the credit card list with the values from - * |entries|. - * @param {!Array} entries The list of credit cards. - */ - setCreditCardList_: function(entries) { - this.creditCardList_.dataModel = new ArrayDataModel(entries); - }, - - /** - * Removes the Autofill address or credit card represented by |guid|. - * @param {string} guid The GUID of the address to remove. - * @param {string=} metricsAction The name of the action to log for metrics. - * @private - */ - removeData_: function(guid, metricsAction) { - chrome.send('removeData', [guid]); - if (metricsAction) - chrome.send('coreOptionsUserMetricsAction', [metricsAction]); - }, - - /** - * Shows the 'Edit address' overlay, using the data in |address| to fill the - * input fields. |address| is a list with one item, an associative array - * that contains the address data. - * @private - */ - showEditAddressOverlay_: function(address) { - var title = loadTimeData.getString('editAddressTitle'); - AutofillEditAddressOverlay.setTitle(title); - AutofillEditAddressOverlay.loadAddress(address); - PageManager.showPageByName('autofillEditAddress'); - }, - - /** - * Shows the 'Edit credit card' overlay, using the data in |credit_card| to - * fill the input fields. |creditCard| is a list with one item, an - * associative array that contains the credit card data. - * @param {CreditCardData} creditCard - * @private - */ - showEditCreditCardOverlay_: function(creditCard) { - var title = loadTimeData.getString('editCreditCardTitle'); - AutofillEditCreditCardOverlay.setTitle(title); - AutofillEditCreditCardOverlay.loadCreditCard(creditCard); - PageManager.showPageByName('autofillEditCreditCard'); - }, - }; - - AutofillOptions.setAddressList = function(entries) { - AutofillOptions.getInstance().setAddressList_(entries); - }; - - AutofillOptions.setCreditCardList = function(entries) { - AutofillOptions.getInstance().setCreditCardList_(entries); - }; - - AutofillOptions.removeData = function(guid, metricsAction) { - AutofillOptions.getInstance().removeData_(guid, metricsAction); - }; - - AutofillOptions.editAddress = function(address) { - AutofillOptions.getInstance().showEditAddressOverlay_(address); - }; - - /** - * @param {CreditCardData} creditCard - */ - AutofillOptions.editCreditCard = function(creditCard) { - AutofillOptions.getInstance().showEditCreditCardOverlay_(creditCard); - }; - - // Export - return { - AutofillOptions: AutofillOptions - }; - -}); -
diff --git a/chrome/browser/resources/options/autofill_options_list.js b/chrome/browser/resources/options/autofill_options_list.js deleted file mode 100644 index 723c44b5..0000000 --- a/chrome/browser/resources/options/autofill_options_list.js +++ /dev/null
@@ -1,285 +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. - -/** - * @typedef {{ - * guid: string, - * label: string, - * sublabel: string, - * isLocal: boolean, - * isCached: boolean - * }} - * @see chrome/browser/ui/webui/options/autofill_options_handler.cc - */ -var AutofillEntityMetadata; - -cr.define('options.autofillOptions', function() { - /** @const */ var DeletableItem = options.DeletableItem; - /** @const */ var DeletableItemList = options.DeletableItemList; - /** @const */ var InlineEditableItem = options.InlineEditableItem; - /** @const */ var InlineEditableItemList = options.InlineEditableItemList; - - /** - * @return {!HTMLButtonElement} - */ - function AutofillEditProfileButton(edit) { - var editButtonEl = /** @type {HTMLButtonElement} */( - document.createElement('button')); - editButtonEl.className = - 'list-inline-button hide-until-hover custom-appearance'; - editButtonEl.textContent = - loadTimeData.getString('autofillEditProfileButton'); - editButtonEl.onclick = edit; - - editButtonEl.onmousedown = function(e) { - // Don't select the row when clicking the button. - e.stopPropagation(); - // Don't focus on the button when clicking it. - e.preventDefault(); - }; - - return editButtonEl; - } - - /** @return {!Element} */ - function CreateGoogleAccountLabel() { - var label = document.createElement('div'); - label.className = 'deemphasized hides-on-hover'; - label.textContent = loadTimeData.getString('autofillFromGoogleAccount'); - return label; - } - - /** - * Creates a new address list item. - * @constructor - * @param {AutofillEntityMetadata} metadata Details about an address profile. - * @extends {options.DeletableItem} - * @see chrome/browser/ui/webui/options/autofill_options_handler.cc - */ - function AddressListItem(metadata) { - var el = cr.doc.createElement('div'); - el.__proto__ = AddressListItem.prototype; - /** @private */ - el.metadata_ = metadata; - el.decorate(); - - return el; - } - - AddressListItem.prototype = { - __proto__: DeletableItem.prototype, - - /** @override */ - decorate: function() { - DeletableItem.prototype.decorate.call(this); - - var label = this.ownerDocument.createElement('div'); - label.className = 'autofill-list-item'; - label.textContent = this.metadata_.label; - this.contentElement.appendChild(label); - - var sublabel = this.ownerDocument.createElement('div'); - sublabel.className = 'deemphasized'; - sublabel.textContent = this.metadata_.sublabel; - this.contentElement.appendChild(sublabel); - - if (!this.metadata_.isLocal) { - this.deletable = false; - this.contentElement.appendChild(CreateGoogleAccountLabel()); - } - - // The 'Edit' button. - var metadata = this.metadata_; - var editButtonEl = AutofillEditProfileButton( - AddressListItem.prototype.loadAddressEditor.bind(this)); - this.contentElement.appendChild(editButtonEl); - }, - - /** - * For local Autofill data, this function causes the AutofillOptionsHandler - * to call showEditAddressOverlay(). For Payments data, the user is - * redirected to the Payments web interface. - */ - loadAddressEditor: function() { - if (this.metadata_.isLocal) - chrome.send('loadAddressEditor', [this.metadata_.guid]); - else - window.open(loadTimeData.getString('paymentsManageAddressesUrl')); - }, - }; - - /** - * Creates a new credit card list item. - * @param {AutofillEntityMetadata} metadata Details about a credit card. - * @constructor - * @extends {options.DeletableItem} - */ - function CreditCardListItem(metadata) { - var el = cr.doc.createElement('div'); - el.__proto__ = CreditCardListItem.prototype; - /** @private */ - el.metadata_ = metadata; - el.decorate(); - - return el; - } - - CreditCardListItem.prototype = { - __proto__: DeletableItem.prototype, - - /** @override */ - decorate: function() { - DeletableItem.prototype.decorate.call(this); - - var label = this.ownerDocument.createElement('div'); - label.className = 'autofill-list-item'; - label.textContent = this.metadata_.label; - this.contentElement.appendChild(label); - - var sublabel = this.ownerDocument.createElement('div'); - sublabel.className = 'deemphasized'; - sublabel.textContent = this.metadata_.sublabel; - this.contentElement.appendChild(sublabel); - - if (!this.metadata_.isLocal) { - this.deletable = false; - this.contentElement.appendChild(CreateGoogleAccountLabel()); - } - - var guid = this.metadata_.guid; - if (this.metadata_.isCached) { - var localCopyText = this.ownerDocument.createElement('span'); - localCopyText.className = 'hide-until-hover deemphasized'; - localCopyText.textContent = - loadTimeData.getString('autofillDescribeLocalCopy'); - this.contentElement.appendChild(localCopyText); - - var clearLocalCopyButton = AutofillEditProfileButton( - function() { chrome.send('clearLocalCardCopy', [guid]); }); - clearLocalCopyButton.textContent = - loadTimeData.getString('autofillClearLocalCopyButton'); - this.contentElement.appendChild(clearLocalCopyButton); - } - - // The 'Edit' button. - var metadata = this.metadata_; - var editButtonEl = AutofillEditProfileButton( - CreditCardListItem.prototype.loadCreditCardEditor.bind(this)); - this.contentElement.appendChild(editButtonEl); - }, - - /** - * For local Autofill data, this function causes the AutofillOptionsHandler - * to call showEditCreditCardOverlay(). For Payments data, the user is - * redirected to the Payments web interface. - */ - loadCreditCardEditor: function() { - if (this.metadata_.isLocal) - chrome.send('loadCreditCardEditor', [this.metadata_.guid]); - else - window.open(loadTimeData.getString('paymentsManageInstrumentsUrl')); - }, - }; - - /** - * Base class for shared implementation between address and credit card lists. - * @constructor - * @extends {options.DeletableItemList} - */ - var AutofillProfileList = cr.ui.define('list'); - - AutofillProfileList.prototype = { - __proto__: DeletableItemList.prototype, - - decorate: function() { - DeletableItemList.prototype.decorate.call(this); - - this.addEventListener('blur', this.onBlur_); - }, - - /** - * When the list loses focus, unselect all items in the list. - * @private - */ - onBlur_: function() { - this.selectionModel.unselectAll(); - }, - }; - - /** - * Create a new address list. - * @constructor - * @extends {options.autofillOptions.AutofillProfileList} - */ - var AutofillAddressList = cr.ui.define('list'); - - AutofillAddressList.prototype = { - __proto__: AutofillProfileList.prototype, - - decorate: function() { - AutofillProfileList.prototype.decorate.call(this); - }, - - /** @override */ - activateItemAtIndex: function(index) { - this.getListItemByIndex(index).loadAddressEditor(); - }, - - /** - * @override - * @param {AutofillEntityMetadata} metadata - */ - createItem: function(metadata) { - return new AddressListItem(metadata); - }, - - /** @override */ - deleteItemAtIndex: function(index) { - AutofillOptions.removeData(this.dataModel.item(index).guid, - 'Options_AutofillAddressDeleted'); - }, - }; - - /** - * Create a new credit card list. - * @constructor - * @extends {options.DeletableItemList} - */ - var AutofillCreditCardList = cr.ui.define('list'); - - AutofillCreditCardList.prototype = { - __proto__: AutofillProfileList.prototype, - - decorate: function() { - AutofillProfileList.prototype.decorate.call(this); - }, - - /** @override */ - activateItemAtIndex: function(index) { - this.getListItemByIndex(index).loadCreditCardEditor(); - }, - - /** - * @override - * @param {AutofillEntityMetadata} metadata - */ - createItem: function(metadata) { - return new CreditCardListItem(metadata); - }, - - /** @override */ - deleteItemAtIndex: function(index) { - AutofillOptions.removeData(this.dataModel.item(index).guid, - 'Options_AutofillCreditCardDeleted'); - }, - }; - - return { - AutofillProfileList: AutofillProfileList, - AddressListItem: AddressListItem, - CreditCardListItem: CreditCardListItem, - AutofillAddressList: AutofillAddressList, - AutofillCreditCardList: AutofillCreditCardList, - }; -});
diff --git a/chrome/browser/resources/options/automatic_settings_reset_banner.css b/chrome/browser/resources/options/automatic_settings_reset_banner.css deleted file mode 100644 index d11484a..0000000 --- a/chrome/browser/resources/options/automatic_settings_reset_banner.css +++ /dev/null
@@ -1,82 +0,0 @@ -/* Copyright 2014 The Chromium Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. */ - -.settings-banner { - background-color: #f5f5f5; - border-color: #c8c8c8; - border-radius: 3px; - border-style: solid; - border-width: 1px; - margin-bottom: 24px; - margin-top: 20px; - max-width: 716px; - position: relative; -} - -.settings-banner > .close-button { - background-image: url(chrome://theme/IDR_CLOSE_DIALOG); - background-position: center; - background-repeat: no-repeat; - height: 14px; - opacity: 0.5; - position: absolute; - right: 4px; - top: 4px; - width: 14px; -} - -html[dir='rtl'] .settings-banner > .close-button { - left: 4px; - right: auto; -} - -.settings-banner > .close-button:hover { - background-image: url(chrome://theme/IDR_CLOSE_DIALOG_H); -} - -.settings-banner > .close-button:active { - background-image: url(chrome://theme/IDR_CLOSE_DIALOG_P); -} - -.settings-banner .content-area { - align-items: center; - display: flex; - padding: 17px; -} - -.settings-banner .content-area .badge { - background-image: url(yellow_gear.png); - background-position: center; - background-repeat: no-repeat; - height: 55px; - width: 58px; -} - -.settings-banner .content-area .text { - -webkit-margin-start: 18px; - flex: 1; -} - -.settings-banner .content-area .text p { - margin-bottom: 0; - margin-top: 0; -} - -.settings-banner .content-area .button-area { - -webkit-margin-start: 54px; -} - -.settings-banner .nowrap { - white-space: nowrap; -} - -.settings-banner button { - margin-bottom: 1px; - margin-right: 0; -} - -#secondary-user-banner .content-area .badge { - background-color: rgb(210, 210, 212); - background-image: url(chrome://theme/IDR_SECONDARY_USER_SETTINGS); -}
diff --git a/chrome/browser/resources/options/automatic_settings_reset_banner.html b/chrome/browser/resources/options/automatic_settings_reset_banner.html deleted file mode 100644 index fcb16c40..0000000 --- a/chrome/browser/resources/options/automatic_settings_reset_banner.html +++ /dev/null
@@ -1,19 +0,0 @@ -<div id="automatic-settings-reset-banner" class="settings-banner" hidden> - <div id="automatic-settings-reset-banner-close" class="close-button"></div> - <div class="content-area"> - <div class="badge"></div> - <div class="text"> - <p> - <span>$i18nRaw{automaticSettingsResetBannerText}</span> - <a id="automatic-settings-reset-learn-more" class="nowrap" - href="$i18nRaw{automaticSettingsResetLearnMoreUrl}" - target="_blank">$i18n{learnMore}</a> - </p> - </div> - <div class="button-area"> - <button id="automatic-settings-reset-banner-activate-reset"> - $i18n{automaticSettingsResetBannerResetButtonText} - </button> - </div> - </div> -</div>
diff --git a/chrome/browser/resources/options/automatic_settings_reset_banner.js b/chrome/browser/resources/options/automatic_settings_reset_banner.js deleted file mode 100644 index 5755d80..0000000 --- a/chrome/browser/resources/options/automatic_settings_reset_banner.js +++ /dev/null
@@ -1,132 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Note: the native-side handler for this is AutomaticSettingsResetHandler. - -cr.define('options', function() { - /** @const */ var PageManager = cr.ui.pageManager.PageManager; - - /** - * AutomaticSettingsResetBanner class - * Provides encapsulated handling of the Reset Profile Settings banner. - * @constructor - */ - function AutomaticSettingsResetBanner() {} - - cr.addSingletonGetter(AutomaticSettingsResetBanner); - - AutomaticSettingsResetBanner.prototype = { - /** - * Whether or not the banner has already been dismissed. - * - * This is needed because of the surprising ordering of asynchronous - * JS<->native calls when the settings page is opened with specifying a - * given sub-page, e.g. chrome://settings/AutomaticSettingsReset. - * - * In such a case, AutomaticSettingsResetOverlay's didShowPage(), which - * calls our dismiss() method, would be called before the native Handlers' - * InitalizePage() methods have an effect in the JS, which includes calling - * our show() method. This would mean that the banner would be first - * dismissed, then shown. We want to prevent this. - * - * @private {boolean} - */ - wasDismissed_: false, - - /** - * Metric name to send when a show event occurs. - * @private {string} - */ - showMetricName_: '', - - /** - * Name of the native callback invoked when the banner is dismised. - */ - dismissNativeCallbackName_: '', - - /** - * DOM element whose visibility is set when setVisibility_ is called. - * @private {?HTMLElement} - */ - visibleElement_: null, - - /** - * Initializes the banner's event handlers. - * @suppress {checkTypes} - * TODO(vitalyp): remove the suppression. Suppression is needed because - * method dismiss() is attached to AutomaticSettingsResetBanner at run-time - * via "Forward public APIs to protected implementations" pattern (see - * below). Currently the compiler pass and cr.js handles only forwarding to - * private implementations using cr.makePublic(). - */ - initialize: function() { - this.showMetricName_ = 'AutomaticSettingsReset_WebUIBanner_BannerShown'; - - this.dismissNativeCallbackName_ = - 'onDismissedAutomaticSettingsResetBanner'; - - this.visibleElement_ = getRequiredElement( - 'automatic-settings-reset-banner'); - - $('automatic-settings-reset-banner-close').onclick = function(event) { - chrome.send('metricsHandler:recordAction', - ['AutomaticSettingsReset_WebUIBanner_ManuallyClosed']); - AutomaticSettingsResetBanner.dismiss(); - }; - $('automatic-settings-reset-learn-more').onclick = function(event) { - chrome.send('metricsHandler:recordAction', - ['AutomaticSettingsReset_WebUIBanner_LearnMoreClicked']); - }; - $('automatic-settings-reset-banner-activate-reset').onclick = - function(event) { - chrome.send('metricsHandler:recordAction', - ['AutomaticSettingsReset_WebUIBanner_ResetClicked']); - PageManager.showPageByName('resetProfileSettings'); - }; - }, - - /** - * Sets whether or not the reset profile settings banner shall be visible. - * @param {boolean} show Whether or not to show the banner. - * @protected - */ - setVisibility: function(show) { - this.visibleElement_.hidden = !show; - }, - - /** - * Called by the native code to show the banner if needed. - * @private - */ - show_: function() { - if (!this.wasDismissed_) { - chrome.send('metricsHandler:recordAction', [this.showMetricName_]); - this.setVisibility(true); - } - }, - - /** - * Called when the banner should be closed as a result of something taking - * place on the WebUI page, i.e. when its close button is pressed, or when - * the confirmation dialog for the profile settings reset feature is opened. - * @private - */ - dismiss_: function() { - chrome.send(assert(this.dismissNativeCallbackName_)); - this.wasDismissed_ = true; - this.setVisibility(false); - }, - }; - - // Forward public APIs to private implementations. - cr.makePublic(AutomaticSettingsResetBanner, [ - 'show', - 'dismiss', - ]); - - // Export - return { - AutomaticSettingsResetBanner: AutomaticSettingsResetBanner - }; -});
diff --git a/chrome/browser/resources/options/browser_options.css b/chrome/browser/resources/options/browser_options.css deleted file mode 100644 index cb9a251..0000000 --- a/chrome/browser/resources/options/browser_options.css +++ /dev/null
@@ -1,492 +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. */ - -#change-home-page-section { - -webkit-margin-start: 30px; -} - -#home-page-url { - display: inline-block; - max-width: 400px; - overflow: hidden; - text-overflow: ellipsis; - vertical-align: top; -} - -#default-browser-state, -#profiles-supervised-dashboard-tip { - margin-top: 6px; -} - -#sync-overview p { - display: inline; -} - -#account-picture-wrapper { - float: left; - margin: 0 2px 10px 0; -} - -html[dir=rtl] #account-picture-wrapper { - float: right; -} - -#account-picture-control { - border: 1px solid rgba(0, 0, 0, 0.3); - border-radius: 4px; - display: inline-block; - padding: 3px; - position: relative; -} - -#account-picture { - height: 56px; - object-fit: cover; - vertical-align: middle; - width: 56px; -} - -#account-picture:disabled { - cursor: default; -} - -#change-picture-caption { - background: rgba(0, 0, 0, 0.5); - bottom: 0; - color: white; - cursor: pointer; - font-size: small; - margin: 3px 0; - position: absolute; - text-align: center; - visibility: hidden; - /* Width of #account-picture. */ - width: 56px; -} - -#account-picture:not(:disabled):hover + #change-picture-caption, -#account-picture:not(:disabled) + #change-picture-caption:hover { - visibility: visible; -} - -#account-picture-indicator { - -webkit-margin-end: 3px; -} - -#sync-general { - -webkit-margin-start: 76px; - margin-bottom: 10px; -} - -#sync-buttons { - clear: both; -} - -#profiles-list { - margin-bottom: 10px; - min-height: 0; -} - -#profiles-list .profile-container { - -webkit-box-align: center; - display: -webkit-box; - max-width: 100%; -} - -#profiles-list .profile-name { - -webkit-box-flex: 1; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} - -#profiles-list .profile-supervised { - color: #999; - margin-left: 5px; -} - -#profiles-list > * { - height: 40px; -} - -#profiles-list:focus { - border-color: rgb(77, 144, 254); -} - -.profile-img { - height: 31px; - padding: 3px; - vertical-align: middle; - width: 38px; -} - -.profile-item-current { - font-weight: bold; -} - -#profiles-buttons { - white-space: nowrap; -} - -.sync-error { - background: rgb(255, 219, 219); - border: 1px solid rgb(206, 76, 76); - border-radius: 2px; - padding: 10px; -} - -.sync-error [is='action-link'] { - margin: 0 1ex; - padding: 0; -} - -#mac-passwords-warning { - margin-top: 10px; -} - -input[type='range'] { - vertical-align: middle; -} - -.extension-controlled-warning-box { - background-color: #fbfbfb; - border: 1px solid #cecece; - border-radius: 3px; - padding: 19px; -} - -.extension-controlled-warning { - -webkit-padding-start: 35px; - background-repeat: no-repeat; - padding-bottom: 20px; - padding-top: 3px; -} - -.setting-extra-description { - -webkit-margin-start: 1.8em; - color: #999; -} - -.hotword-settings { - -webkit-margin-start: 22px; -} - -.hotword-audio-history { - -webkit-margin-start: 1.8em; -} - -#audio-history { - margin-top: 1.5em; -} - -#hotword-retrain-link { - text-decoration: none; -} - -/* Internet settings */ - -#network-settings { - position: relative; -} - -#network-list { - min-height: 0; - width: 320px; -} - -#download-location-label.disabled { - color: #999; -} - -.network-group { - -webkit-box-orient: horizontal; - height: 42px; - overflow: visible; -} - -list:not([disabled]) > .network-group:hover, -list:not([disabled]) > .network-group[selected] { - background-color: #f8f8f8 !important; - background-image: -webkit-linear-gradient(rgba(255, 255, 255, 0.8), - rgba(255, 255, 255, 0)) !important; - box-shadow: inset 0 0 1px 1px #f0f0f0; -} - -.network-group-labels { - -webkit-box-flex: 1; - -webkit-box-orient: vertical; - display: -webkit-box; - padding-top: 3px; -} - -.network-icon { - -webkit-margin-end: 10px; - background-position: left top; - background-size: 25px; - height: 25px; - line-height: normal; - white-space: normal; - width: 25px; -} - -.network-icon cr-network-icon { - height: 100%; - width: 100%; -} - -@keyframes connecting-animation { - 0% { - background-position: 0 25%; - } - 12.5% { - background-position: 0 50%; - } - 25% { - background-position: 0 75%; - } - 37.5% { - background-position: 0 100%; - } - 50% { - background-position: 0 100%; - } - 62.5% { - background-position: 0 75%; - } - 75% { - background-position: 0 50%; - } - 87.5% { - background-position: 0 25%; - } -} - -.network-add-connection { - background-image: url(chrome://theme/IDR_NETWORK_ADD_CONNECTION); - background-position: center center !important; - background-repeat: no-repeat; - background-size: 16px; -} - -.network-options-button { - -webkit-box-flex: 0; - background-image: none; - background-position: center center; - display: block; - opacity: 0.5; - transform: scale(0.6); - vertical-align: middle; - width: 19px; -} - -.network-group > .controlled-setting-indicator, -.network-menu-item > .controlled-setting-indicator { - -webkit-margin-end: 5px; -} - -.network-options-button:hover { - opacity: 1; -} - -@keyframes vpn-connecting-animation { - from { - opacity: 1; - } - to { - opacity: 0.2; - } -} - -.network-connecting { - animation: connecting-animation 1s step-end infinite; -} - -.network-vpn.network-connecting { - animation: vpn-connecting-animation 500ms alternate infinite; -} - -.network-title { - font-weight: 600; - line-height: 120%; -} - -.network-subtitle { - color: #333; - display: inline-block; - line-height: 100%; - max-width: 260px; - opacity: 0.4; - overflow: hidden; - padding-bottom: 3px; - text-overflow: ellipsis; - white-space: nowrap; -} - -.network-selector { - background: right center no-repeat; - background-image: url(../../../../ui/webui/resources/images/select.png); - padding-right: 20px; -} - -.network-menu { - background: #fff; - box-shadow: - 0 0 0 1px rgba(0,0,0,0.1), - 0 5px 1px 1px rgba(0,0,0,0.1), - 0 5px 2px 1px rgba(0,0,0,0.1), - 0 5px 12px 1px rgba(0,0,0,0.5); - display: block; - position: absolute; - width: 320px; - z-index: 1; -} - -.network-menu-item { - -webkit-box-align: center; - -webkit-box-orient: horizontal; - display: -webkit-box; - height: 32px; - margin-left: 4px; - margin-right: 4px; -} - -.network-menu-item-label { - -webkit-box-flex: 1; - color: #555; - display: block; - overflow-x: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} - -.active-network { - color: black; - font-weight: bold; -} - -.network-disabled-control { - color: #999; -} - -/* Restrict the size of the networks menu, by limiting the number of - visible networks. */ -.network-menu-group { - max-height: 192px; - overflow-x: hidden; - overflow-y: auto; - text-overflow: ellipsis; -} - -.network-menu-item:hover, -.network-menu-item[selected] { - background-color: #eee; -} - -.network-menu > hr { - opacity: 0.4; -} - -#shared-proxies { - margin-top: 12px; -} - -#web-content-section select, -.web-content-select-label { - min-width: 145px; -} - -.web-content-select-label > span:only-of-type { - display: inline-block; - min-width: 100px; -} - -#timezone-value { - display: inline-block; - vertical-align: baseline; -} - -.loading #timezone-value select { - color: transparent; - text-shadow: none; -} - -#privacy-explanation { - line-height: 1.8em; -} - -#advanced-settings { - height: 0; - margin-top: 8px; - overflow: hidden; -} - -.sliding { - overflow-y: hidden; - transition: height 200ms; -} - -#keyboard-overlay .option-value > select { - width: 100%; -} - -#keyboard-overlay table, -#power-overlay table { - /* Same as .settings-row {margin}. */ - -webkit-border-horizontal-spacing: 0; - -webkit-border-vertical-spacing: 0.65em; -} - -#stylus-settings-link, -#power-settings-link { - /* Match the spacing of the touchpad/mouse slider. */ - line-height: 25px; -} - -#accessibility-autoclick .controlled-setting-with-label { - -webkit-box-align: baseline; -} - -#accessibility-autoclick-dropdown, -#accessibility-autoclick-label { - /* Same as .controlled-setting-with-label > input + span. */ - -webkit-margin-start: 0.6em; -} - -#accessibility-screen-magnifier-center-focus-check { - -webkit-margin-start: 0.4em; -} - -div[guestmode=true] :-webkit-any( -<if expr="not chromeos"> - #searchBox, -</if> - #appearance-section, - #startup-section, - #reset-profile-settings-section) { - display: none; -} - -div[supervisedMode=true] :-webkit-any( - #profiles-enable-guest, - #profiles-enable-add-person) { - display: none; -} - -footer { - display: flex; -} - -#about-button { - -webkit-margin-end: 30px; -} - -/* An input that has no function except to take up the same amount of space as - * a checkbox. */ -.spacer-checkbox { - visibility: hidden; -} - -#android-apps-settings { - -webkit-margin-start: 30px; -}
diff --git a/chrome/browser/resources/options/browser_options.html b/chrome/browser/resources/options/browser_options.html deleted file mode 100644 index e299d65..0000000 --- a/chrome/browser/resources/options/browser_options.html +++ /dev/null
@@ -1,1149 +0,0 @@ -<if expr="chromeos"> -<link rel="import" href="/people_page/lock_screen_constants.html"> -</if> -<div id="settings" class="page" hidden> - <header> - <h1>$i18n{settingsTitle}</h1> - </header> - <include src="automatic_settings_reset_banner.html"> -<if expr="chromeos"> - <link rel="import" href="chrome://resources/cr_elements/chromeos/network/cr_network_icon.html"> - <link rel="import" href="chrome://resources/cr_elements/chromeos/network/cr_onc_types.html"> - <include src="secondary_user_banner.html"> - <section id="network-section-cros"> - <div id="network-section-header" class="section-header"> - <h3>$i18n{sectionTitleInternet}</h3> - <span class="controlled-setting-indicator" plural></span> - </div> - <div id="network-settings"> - <list id="network-list"></list> - <div id="shared-proxies" class="checkbox"> - <label> - <input id="use-shared-proxies" type="checkbox" - metric="Options_NetworkUseSharedProxies" - pref="settings.use_shared_proxies"> - <span>$i18n{useSharedProxies}</span> - </label> - </div> - <div id="network-menus"></div> - </div> - </section> -</if> -<if expr="not chromeos"> - <include src="sync_section.html"> - <include src="startup_section.html"> -</if> - <section id="proxy-section" hidden> - <h3>$i18n{sectionTitleProxy}</h3> - <div id="proxy-section-content"></div> - </section> - - <section id="appearance-section"> - <h3>$i18n{sectionTitleAppearance}</h3> - <div class="settings-row"> -<if expr="chromeos"> - <button id="set-wallpaper" guest-visibility="disabled"> - $i18n{setWallpaper} - </button> - <span id="wallpaper-indicator" class="controlled-setting-indicator"> - </span> -</if> -<if expr="not chromeos and is_posix and not is_macosx"> - <button id="themes-gallery">$i18n{themesGallery}</button> - <button id="themes-native-button">$i18n{themesNativeButton}</button> - <button id="themes-reset">$i18n{themesSetClassic}</button> -</if> -<if expr="chromeos or is_win or is_macosx"> - <button id="themes-gallery">$i18n{themesGallery}</button> - <button id="themes-reset">$i18n{themesReset}</button> -</if> - </div> - <div class="checkbox controlled-setting-with-label" - guest-visibility="disabled"> - <label> - <input type="checkbox" - pref="browser.show_home_button" - metric="Options_Homepage_HomeButton"> - <span> - <span>$i18n{homePageShowHomeButton}</span> - <span class="controlled-setting-indicator" - pref="browser.show_home_button"></span> - </span> - </label> - </div> - <div id="change-home-page-section" hidden> - <div id="change-home-page-section-container" guest-visibility="disabled"> - <span id="home-page-ntp" class="home-page-label"> - $i18n{homePageNtp} - </span> - <span id="home-page-url" class="home-page-label"></span> - <a is="action-link" id="change-home-page">$i18n{changeHomePage}</a> - <div id="extension-controlled-container"></div> - </div> - </div> - <div class="checkbox controlled-setting-with-label" - guest-visibility="disabled"> - <label> - <input type="checkbox" - pref="bookmark_bar.show_on_all_tabs" - metric="Options_ShowBookmarksBar"> - <span> - <span>$i18n{toolbarShowBookmarksBar}</span> - <span class="controlled-setting-indicator" - pref="bookmark_bar.show_on_all_tabs"></span> - </span> - </label> - </div> -<if expr="is_linux and not chromeos"> - <div class="checkbox"><label> - <input id="show-window-decorations" type="checkbox" - pref="browser.custom_chrome_frame" metric="Options_CustomFrame" - inverted_pref> - <span>$i18n{showWindowDecorations}</span> - </label></div> -</if> - </section> -<if expr="chromeos"> - <section id="device-section"> - <h3>$i18n{sectionTitleDevice}</h3> - <div> - <span>$i18n{deviceGroupDescription}</span> - <div id="touchpad-settings" class="settings-row" hidden> - <span id="touchpad-speed-label" class="option-name"> - $i18n{touchpadSpeed} - </span> - <input id="touchpad-sensitivity-range" type="range" min="1" max="5" - pref="settings.touchpad.sensitivity2" class="touch-slider" - aria-labelledby="touchpad-speed-label"> - </div> - <div id="mouse-settings" class="settings-row" hidden> - <span id="mouse-speed-label" class="option-name"> - $i18n{mouseSpeed} - </span> - <input id="mouse-sensitivity-range" type="range" min="1" max="5" - pref="settings.mouse.sensitivity2" class="touch-slider" - aria-labelledby="mouse-speed-label"> - </div> - <div id="no-pointing-devices" class="settings-row" hidden> - $i18n{noPointingDevices} - </div> - <div class="settings-row"> - <button id="pointer-settings-button" hidden> - </button> - <button id="keyboard-settings-button"> - $i18n{keyboardSettingsButtonTitle} - </button> - <span id="display-options-section"> - <button id="display-options" disabled>$i18n{displayOptions}</button> - </span> - <button id="storage-manager-button"> - $i18n{storageManagerButtonTitle} - </button> - </div> - <div id="stylus-row" hidden> - <a is="action-link" id="stylus-settings-link"> - $i18n{stylusSettingsButtonTitle} - </a> - </div> - <div id="power-row" hidden> - <a is="action-link" id="power-settings-link"> - $i18n{powerSettingsButton} - </a> - </div> - </div> - </section> -</if> - <section id="search-section"> - <h3>$i18n{sectionTitleSearch}</h3> - <div id="search-section-content"> - <span id="default-search-engine-label"> - $i18nRaw{defaultSearchGroupLabel} - </span> - <div class="settings-row"> - <select id="default-search-engine" class="weakrtl" - aria-labelledby="default-search-engine-label"></select> - <span class="controlled-setting-indicator" - pref="default_search_provider_data.template_url_data"> - </span> - <button id="manage-default-search-engines"> - $i18n{defaultSearchManageEngines} - </button> - </div> - <div id="google-now-launcher" hidden> - <div class="checkbox"> - <label> - <input pref="google_now_launcher.enabled" type="checkbox"> - <span>$i18n{googleNowLauncherEnable}</span> - </label> - </div> - </div> - <div id="hotword-always-on-search" hidden> - <div class="checkbox controlled-setting-with-label"> - <label> - <input id="hotword-always-on-search-checkbox" - pref="hotword.always_on_search_enabled" type="checkbox"> - <span>$i18n{hotwordSearchEnable}</span> - </label> - <a target="_blank" class="hotword-link" - href="$i18nRaw{hotwordLearnMoreURL}"> - $i18n{learnMore} - </a> - <span id="hotword-always-on-search-setting-indicator" - pref="hotword.always_on_search_enabled" dialog-pref></span> - <div> - <span class="setting-extra-description"> - $i18n{hotwordAlwaysOnDesc} - </span> - <a id="hotword-retrain-link" is="action-link" hidden> - $i18n{hotwordRetrainLink} - </a> - </div> - </div> - </div> - <div id="hotword-no-dsp-search" hidden> - <div class="checkbox controlled-setting-with-label"> - <label> - <input id="hotword-no-dsp-search-checkbox" - pref="hotword.search_enabled_2" type="checkbox"> - <span>$i18n{hotwordSearchEnable}</span> - </label> - <a target="_blank" class="hotword-link" - href="$i18nRaw{hotwordLearnMoreURL}"> - $i18n{learnMore} - </a> - <span id="hotword-no-dsp-search-setting-indicator" - pref="hotword.search_enabled_2" dialog-pref></span> - <div> - <span class="setting-extra-description"> - $i18n{hotwordNoDSPDesc} - </span> - </div> - </div> - </div> - <div id="audio-history" hidden> - <div class="settings-row"> - <label class="hotword-audio-history"> - <span id="audio-history-label"></span> - </label> - <a target="_blank" class="hotword-link" - href="$i18nRaw{hotwordManageAudioHistoryURL}"> - $i18n{hotwordAudioHistoryManage} - </a> - </div> - <div class="settings-row" id="audio-history-always-on-description"> - <span class="setting-extra-description"> - $i18n{hotwordAlwaysOnAudioHistoryDescription} - </span> - </div> - </div> - </div> - </section> -<if expr="chromeos"> - <section id="android-apps-section" hidden> - <h3>$i18n{androidAppsTitle}</h3> - <div class="checkbox controlled-setting-with-label"> - <label> - <input id="android-apps-enabled" pref="arc.enabled" - metric="Options_AndroidApps" type="checkbox" dialog-pref> - <span> - <span>$i18n{androidAppsEnabled}</span> - <span class="controlled-setting-indicator" - pref="arc.enabled"></span> - </span> - </label> - <a target="_blank" href="http://support.google.com/chromebook?p=playapps"> - $i18n{learnMore} - </a> - </div> - <div id="android-apps-settings" class="controlled-setting-with-label" - hidden> - <label> - <span id="android-apps-settings-label"></span> - </label> - </div> - </section> -</if> - <section id="sync-users-section" guest-visibility="hidden"> - <h3>$i18n{sectionTitleUsers}</h3> -<if expr="chromeos"> - <include src="sync_section.html"> -</if> - <div id="profiles-section" hidden> - <list id="profiles-list" class="settings-list" hidden></list> - <div id="profiles-single-message" class="settings-row"> - $i18n{profilesSingleUser} - </div> -<if expr="not chromeos"> - <div id="profiles-enable-guest" class="checkbox"> - <label> - <input pref="profile.browser_guest_enabled" - type="checkbox" - metric="Options_BrowserGuestEnabled"> - <span>$i18n{profileBrowserGuestEnable}</span> - </label> - </div> - <div id="profiles-enable-add-person" class="checkbox"> - <label> - <input pref="profile.add_person_enabled" - type="checkbox" - metric="Options_AddPersonEnabled"> - <span>$i18n{profileAddPersonEnable}</span> - </label> - </div> -</if> - <div id="profiles-buttons"> - <button id="profiles-create">$i18n{profilesCreate}</button> - <button id="profiles-manage" disabled>$i18n{profilesManage}</button> - <button id="profiles-delete">$i18n{profilesDelete}</button> -<if expr="not chromeos"> - <button id="import-data">$i18n{importData}</button> -</if> - </div> - </div> - <div id="profiles-supervised-dashboard-tip" hidden> - $i18nRaw{profilesSupervisedDashboardTip} - </div> - </section> -<if expr="not chromeos"> - <section id="set-default-browser-section"> - <h3>$i18n{sectionTitleDefaultBrowser}</h3> - <div> - <button id="set-as-default-browser" hidden> - $i18n{defaultBrowserUseAsDefault} - </button> - <div id="default-browser-state">$i18n{defaultBrowserUnknown}</div> - </div> - </section> -</if> <!-- not chromeos --> -<div id="advanced-settings" hidden> -<div id="advanced-settings-container"> -<if expr="chromeos"> - <section id="date-time-section"> - <h3>$i18n{datetimeTitle}</h3> - <div class="option-control-table"> - <div guest-visibility="disabled"> - <span id="timezone-value-label" class="option-name"> - $i18n{timezone} - </span> - <div id="timezone-value"> - <select class="control" - id="timezone-value-select" - i18n-options="timezoneList" data-type="string" - pref="settings.timezone" - aria-labelledby="timezone-value-label" - metric="Options_TimezoneSelect"></select> - </div> - </div> - <div class="checkbox settings-row"> - <div id="resolve-timezone-by-geolocation-selection" hidden> - <label> - <input id="resolve-timezone-by-geolocation" - pref="settings.resolve_timezone_by_geolocation" - metric="Options_ResolveTimezoneByGeoLocation" type="checkbox"> - <span>$i18n{resolveTimezoneByGeoLocation}</span> - </label> - </div> - <label> - <input id="use-24hour-clock" pref="settings.clock.use_24hour_clock" - metric="Options_Use24HourClockCheckbox" type="checkbox"> - <span>$i18n{use24HourClock}</span> - </label> - </div> - <div id="set-time" class="settings-row" hidden> - <button id="set-time-button">$i18n{setTimeButton}</button> - </div> - </div> - </section> -</if> - <section id="privacy-section"> - <h3>$i18n{advancedSectionTitlePrivacy}</h3> - <div> - <div class="settings-row"> - <button id="privacyContentSettingsButton"> - $i18n{privacyContentSettingsButton} - </button> - <button id="privacyClearDataButton"> - $i18n{privacyClearDataButton} - </button> - </div> - <p id="privacy-explanation" class="settings-row"> - <span>$i18n{improveBrowsingExperience}</span> - <span>$i18n{disableWebServices}</span> - <a target="_blank" href="$i18nRaw{privacyLearnMoreURL}"> - $i18n{learnMore} - </a> - </p> - <div class="checkbox controlled-setting-with-label"> - <label> - <input id="alternateErrorPagesEnabled" - pref="alternate_error_pages.enabled" - metric="Options_LinkDoctorCheckbox" type="checkbox"> - <span> - <span>$i18n{linkDoctorPref}</span> - <span class="controlled-setting-indicator" - pref="alternate_error_pages.enabled"></span> - </span> - </label> - </div> - <div class="checkbox controlled-setting-with-label" - guest-visibility="disabled"> - <label> - <input pref="search.suggest_enabled" - metric="Options_UseSuggestCheckbox" type="checkbox"> - <span> - <span>$i18n{suggestPref}</span> - <span class="controlled-setting-indicator" - pref="search.suggest_enabled"></span> - </span> - </label> - </div> - <div class="checkbox" guest-visibility="disabled"> - <span class="controlled-setting-with-label"> - <label> - <input id="networkPredictionOptions" - metric="Options_DnsPrefetchCheckbox" type="checkbox"> - <span> - <span>$i18n{networkPredictionEnabledDescription}</span> - <span class="controlled-setting-indicator" - pref="net.network_prediction_options"></span> - </span> - </label> - </span> - </div> - <div class="checkbox controlled-setting-with-label"> - <label> - <input - id="safeBrowsingExtendedReportingCheckbox" - metric="Options_SafeBrowsingExtendedReportingCheckbox" - type="checkbox"> - <span> - <span>$i18n{safeBrowsingEnableExtendedReporting}</span> - <span class="controlled-setting-indicator"></span> - </span> - </label> - </div> - <div class="checkbox controlled-setting-with-label"> - <label> - <input pref="safebrowsing.enabled" - metric="Options_SafeBrowsingCheckbox" type="checkbox"> - <span> - <span>$i18n{safeBrowsingEnableProtection}</span> - <span class="controlled-setting-indicator" - pref="safebrowsing.enabled"></span> - </span> - </label> - </div> - <div id="spelling-enabled-container" - class="checkbox controlled-setting-with-label"> - <label> - <input id="spelling-enabled-control" type="checkbox" - metric="Options_SpellingServiceCheckbox" - pref="spellcheck.use_spelling_service" dialog-pref> - <span> - <span>$i18n{spellingPref}</span> - <span id="spelling-enabled-indicator" - class="controlled-setting-indicator" - pref="spellcheck.use_spelling_service" dialog-pref> - </span> - </label> - </div> -<if expr="_google_chrome"> - <div id="metrics-reporting-setting" - class="checkbox controlled-setting-with-label"> - <label> - <input id="metrics-reporting-enabled" type="checkbox"> - <span> - <span>$i18n{enableLogging}</span> - <span id="metrics-reporting-disabled-icon" - class="controlled-setting-indicator"></span> - </span> - </label> -<if expr="not chromeos"> - <span id="metrics-reporting-reset-restart" hidden> - <!-- Text filled by JavaScript --> - <span></span><a is="action-link" role="button" - class="standalone-action-link"></a><span></span> - </span> -</if> <!-- not chromeos --> - </div> -</if> <!-- _google_chrome --> - <div class="checkbox"> - <label> - <input id="do-not-track-enabled" pref="enable_do_not_track" - metric="Options_DoNotTrackCheckbox" type="checkbox" dialog-pref> - <span>$i18n{doNotTrack}</span> - </label> - </div> -<if expr="chromeos"> - <div class="checkbox controlled-setting-with-label"> - <label> - <input id="content-protection-attestation-enabled" type="checkbox" - pref="cros.device.attestation_for_content_protection_enabled"> - <span> - <span>$i18n{enableContentProtectionAttestation}</span> - <span class="controlled-setting-indicator" - pref="cros.device.attestation_for_content_protection_enabled"> - </span> - </span> - </label> - <a target="_blank" - href="$i18nRaw{contentProtectionAttestationLearnMoreURL}"> - $i18n{learnMore} - </a> - </div> -</if> - <div id="hotword-search" hidden> - <div class="checkbox controlled-setting-with-label"> - <label> - <input id="hotword-search-enable" pref="hotword.search_enabled_2" - metric="Options_HotwordCheckbox" type="checkbox" dialog-pref> - <span> - <span>$i18nRaw{hotwordSearchEnable}</span> - <span id="hotword-search-setting-indicator" - pref="hotword.search_enabled_2" dialog-pref></span> - </span> - </label> - </div> - </div> -<if expr="chromeos"> - <div id="wake-on-wifi" hidden - class="checkbox controlled-setting-with-label"> - <label> - <input id="wake-on-wifi-checkbox" type="checkbox" - metric="Options_WakeOnWifiSsid" - pref="settings.internet.wake_on_wifi_darkconnect"> - <span> - <span>$i18n{wakeOnWifiLabel}</span> - <span id="wake-on-wifi-indicator" - class="controlled-setting-indicator" - pref="settings.internet.wake_on_wifi_darkconnect"></span> - </span> - </label> - </div> -</if> - </div> - </section> -<if expr="chromeos"> - <!-- By default, the bluetooth section is hidden. It is only visible if a - bluetooth adapter is discovered --> - <section id="bluetooth-devices" hidden> - <h3>$i18n{bluetooth}</h3> - <div id="bluetooth-options-div"> - <div class="checkbox controlled-setting-with-label"> - <label> - <input type="checkbox" id="enable-bluetooth" - metric="Options_BluetoothEnabled"> - <span> - <span>$i18n{enableBluetooth}</span> - <span id="bluetooth-controlled-setting-indicator" - class="controlled-setting-indicator" - pref="cros.device.allow_bluetooth" - hidden="true"> - </span> - </span> - </label> - </div> - <div class="settings-list bluetooth-device-list" hidden> - <list id="bluetooth-paired-devices-list"></list> - <div id="bluetooth-paired-devices-list-empty-placeholder" - class="bluetooth-empty-list-label" hidden> - <span>$i18n{bluetoothNoDevices}</span> - </div> - </div> - <div id="bluetooth-button-group"> - <button id="bluetooth-add-device" hidden> - $i18n{addBluetoothDevice} - </button> - <button id="bluetooth-reconnect-device" disabled hidden> - $i18n{bluetoothConnectDevice} - </button> - </div> - </div> - </section> -</if> - <section id="passwords-and-autofill-section"> - <h3>$i18n{passwordsAndAutofillGroupName}</h3> - <div class="checkbox controlled-setting-with-label"> - <label> - <input id="autofill-enabled" pref="autofill.enabled" - metric="Options_FormAutofill" type="checkbox"> - <span> - <span>$i18n{autofillEnabled}</span> - <span class="controlled-setting-indicator" pref="autofill.enabled"> - </span> - </span> - </label> - <a is="action-link" id="autofill-settings"> - $i18n{manageAutofillSettings} - </a> - </div> - <div class="checkbox controlled-setting-with-label"> - <label> - <input id="password-manager-enabled" - pref="credentials_enable_service" - metric="Options_PasswordManager" type="checkbox"> - <span> - <span>$i18n{passwordManagerEnabled}</span> - <span class="controlled-setting-indicator" - pref="credentials_enable_service"></span> - </span> - </label> - <a is="action-link" id="manage-passwords">$i18n{managePasswords}</a> - </div> -<if expr="is_macosx"> - <div id="mac-passwords-warning" hidden>$i18n{macPasswordsWarning}</div> -</if> - </section> - <section id="easy-unlock-section" guest-visibility="hidden" hidden> - <h3>$i18n{easyUnlockSectionTitle}</h3> - <!-- Options shown when the user has not set up Easy Unlock --> - <div id="easy-unlock-disabled" hidden> - <div class="settings-row"> - <span>$i18n{easyUnlockSetupIntro}</span> - <a target="_blank" href="$i18nRaw{easyUnlockLearnMoreURL}"> - $i18n{learnMore} - </a> - </div> - <button id="easy-unlock-setup-button"> - $i18n{easyUnlockSetupButton} - </button> - </div> - <!-- Options shown when the user has set up Easy Unlock --> - <div id="easy-unlock-enabled" hidden> - <div class="settings-row"> - <span>$i18n{easyUnlockDescription}</span> - <a target="_blank" href="$i18nRaw{easyUnlockLearnMoreURL}"> - $i18n{learnMore} - </a> - </div> - <button id="easy-unlock-turn-off-button"> - $i18n{easyUnlockTurnOffButton} - </button> - </div> - </section> - <section id="web-content-section"> - <h3>$i18n{advancedSectionTitleContent}</h3> - <div> - <div class="settings-row"> - <label class="web-content-select-label"> - <span>$i18n{defaultFontSizeLabel}</span> - <select id="defaultFontSize"> - <option value="9">$i18n{fontSizeLabelVerySmall}</option> - <option value="12">$i18n{fontSizeLabelSmall}</option> - <option value="16">$i18n{fontSizeLabelMedium}</option> - <option value="20">$i18n{fontSizeLabelLarge}</option> - <option value="24">$i18n{fontSizeLabelVeryLarge}</option> - </select> - </label> - <span id="font-size-indicator" - class="controlled-setting-indicator"></span> - <button id="fontSettingsCustomizeFontsButton"> - $i18n{fontSettingsCustomizeFontsButton} - </button> - </div> - <div class="settings-row" guest-visibility="disabled"> - <label class="web-content-select-label"> - <span>$i18n{defaultZoomFactorLabel}</span> - <select id="defaultZoomFactor" dataType="double"></select> - </label> - </div> -<if expr="is_macosx"> - <div class="checkbox"> - <label> - <input id="tabsToLinksPref" pref="webkit.webprefs.tabs_to_links" - metric="Options_TabsToLinks" type="checkbox"> - <span>$i18n{tabsToLinksPref}</span> - </label> - </div> -</if> - </div> - </section> -<if expr="not chromeos"> - <section id="network-section"> - <h3>$i18n{advancedSectionTitleNetwork}</h3> - <div> - <span id="proxiesLabel" class="settings-row"> - $i18n{proxiesLabelSystem} - </span> - <div class="settings-row"> - <button id="proxiesConfigureButton"> - $i18n{proxiesConfigureButton} - </button> - <span class="controlled-setting-indicator" pref="proxy" plural></span> - </div> - </div> - </section> -</if> - <section id="languages-section"> - <h3>$i18n{advancedSectionTitleLanguages}</h3> - <div class="settings-row"> - <span>$i18n{languageSectionLabel}</span> - <a target="_blank" href="$i18nRaw{languagesLearnMoreURL}"> - $i18n{learnMore} - </a> - </div> - <div class="settings-row"> - <button id="language-button"> - $i18n{languageAndSpellCheckSettingsButton} - </button> - </div> - <div class="checkbox controlled-setting-with-label"> - <label> - <input pref="translate.enabled" - metric="Options_Translate" type="checkbox"> - <span> - <span>$i18n{translateEnableTranslate}</span> - <span class="controlled-setting-indicator" pref="translate.enabled"> - </span> - </span> - </label> - <a is="action-link" id="manage-languages">$i18n{manageLanguages}</a> - </div> - </section> - <section id="downloads-section"> - <h3>$i18n{downloadLocationGroupName}</h3> - <div> - <div class="settings-row"> - <label> - <span id="download-location-label"> - $i18n{downloadLocationBrowseTitle} - </span> - <input id="downloadLocationPath" class="weakrtl" type="text" - size="36" readonly> - </label> - <button id="downloadLocationChangeButton"> - $i18n{downloadLocationChangeButton} - </button> - <span class="controlled-setting-indicator" - pref="download.default_directory"> - </span> - </div> - <div class="checkbox controlled-setting-with-label"> - <label> - <input type="checkbox" - pref="download.prompt_for_download" - metric="Options_AskForSaveLocation"> - <span> - <span>$i18n{downloadLocationAskForSaveLocation}</span> - <span class="controlled-setting-indicator" - pref="download.prompt_for_download"></span> - </span> - </label> - </div> -<if expr="chromeos"> - <div class="checkbox controlled-setting-with-label" - id="disable-drive-row" guest-visibility="disabled"> - <label> - <input type="checkbox" - pref="gdata.disabled" - metric="Options_DisableGData"> - <span> - <span>$i18n{disableGData}</span> - <span class="controlled-setting-indicator" pref="gdata.disabled"> - </span> - </span> - </label> - </div> -</if> - <div id="auto-open-file-types-section" hidden> - <div id="auto-open-file-types-container"> - <div id="auto-open-file-types-label" class="settings-row"> - $i18n{autoOpenFileTypesInfo} - </div> - <div class="settings-row"> - <button id="autoOpenFileTypesResetToDefault"> - $i18n{autoOpenFileTypesResetToDefault} - </button> - </div> - </div> - </div> - </div> - </section> - <section id="certificates-section"> - <h3>$i18n{advancedSectionTitleCertificates}</h3> - <div> -<if expr="use_nss_certs or is_win or is_macosx"> - <div class="settings-row"> - <button id="certificatesManageButton"> - $i18n{certificatesManageButton} - </button> - </div> -</if> - </div> - </section> -<if expr="chromeos"> - <section id="cups-printers-section" hidden> - <h3>$i18n{advancedSectionTitleCupsPrint}</h3> - <div class="settings-row"> - <span>$i18n{cupsPrintOptionLabel}</span> - <a target="_blank" href="$i18nRaw{cupsPrintLearnMoreURL}"> - $i18n{learnMore} - </a> - </div> - <div class="settings-row"> - <button id="cupsPrintersManageButton"> - $i18n{cupsPrintersManageButton} - </button> - </div> - </section> -</if> -<if expr="enable_service_discovery"> - <section id="cloudprint-options-mdns"> - <h3>$i18n{advancedSectionTitleCloudPrint}</h3> - <div class="settings-row"> - <span>$i18n{cloudPrintOptionLabel}</span> - <a target="_blank" href="$i18nRaw{cloudPrintLearnMoreURL}"> - $i18n{learnMore} - </a> - </div> - <div class="settings-row"> - <button id="cloudPrintDevicesPageButton"> - $i18n{cloudPrintDevicesPageButton} - </button> - </div> - - <div class="settings-row checkbox controlled-setting-with-label" - i18n-values=".hidden: cloudPrintHideNotificationsCheckbox"> - <label> - <input id="local-discovery-notifications-enabled" - pref="local_discovery.notifications_enabled" - type="checkbox" - metric="LocalDiscoveryNotificationsDisabled_Settings"> - <span> - <span>$i18n{cloudPrintEnableNotificationsLabel}</span> - <span class="controlled-setting-indicator" - pref="local_discovery.notifications_enabled"></span> - </span> - </label> - </div> - </section> -</if> - -<if expr="chromeos"> - <include src="startup_section.html"> -</if> - -<section id="a11y-section"> - <h3>$i18n{accessibilityTitle}</h3> - - <div> - <a href="https://chrome.google.com/webstore/category/collection/accessibility" - id="accessibility-features" target="_blank"> - $i18n{accessibilityFeaturesLink} - </a> - </div> - -<if expr="chromeos"> - <div class="option-control-table"> - <p id="accessibility-explanation" class="settings-row"> - <span>$i18n{accessibilityExplanation}</span> - <a id="accessibility-learn-more" target="_blank" - href="$i18nRaw{accessibilityLearnMoreURL}"> - $i18n{learnMore} - </a> - </p> - <div class="option-name"> - <div class="checkbox controlled-setting-with-label"> - <label> - <input - pref="settings.a11y.enable_menu" type="checkbox" - metric="Options_AccessibilitySystemMenu"> - <span> - <span>$i18n{accessibilityAlwaysShowMenu}</span> - <span class="controlled-setting-indicator" - pref="settings.a11y.enable_menu"></span> - </span> - </label> - </div> - </div> - <div class="option-name"> - <div class="checkbox controlled-setting-with-label"> - <label> - <input - pref="settings.a11y.large_cursor_enabled" type="checkbox" - metric="Options_AccessibilityLargeMouseCursor"> - <span> - <span>$i18n{accessibilityLargeCursor}</span> - <span class="controlled-setting-indicator" - pref="settings.a11y.large_cursor_enabled"></span> - </span> - </label> - </div> - </div> - <div class="option-name"> - <div class="checkbox controlled-setting-with-label"> - <label> - <input id="accessibility-high-contrast-check" - pref="settings.a11y.high_contrast_enabled" type="checkbox" - metric="Options_AccessibilityHighContrastMode"> - <span> - <span>$i18n{accessibilityHighContrast}</span> - <span class="controlled-setting-indicator" - pref="settings.a11y.high_contrast_enabled"></span> - </span> - </label> - </div> - </div> - <div id="accessibility-sticky-keys" class="option-name"> - <div class="checkbox controlled-setting-with-label"> - <label> - <input id="accessibility-sticky-keys-check" - pref="settings.a11y.sticky_keys_enabled" type="checkbox" - metric="Options_AccessibilityStickyKeys"> - <span> - <span>$i18n{accessibilityStickyKeys}</span> - <span class="controlled-setting-indicator" - pref="settings.a11y.sticky_keys_enabled"></span> - </span> - </label> - </div> - </div> - <div class="option-name"> - <div class="checkbox controlled-setting-with-label"> - <label> - <input id="accessibility-spoken-feedback-check" - pref="settings.accessibility" type="checkbox" - metric="Options_AccessibilitySpokenFeedback"> - <span> - <span>$i18n{accessibilitySpokenFeedback}</span> - <span class="controlled-setting-indicator" - pref="settings.accessibility"></span> - </span> - </label> - <div id="accessibility-settings" hidden> - <button id="accessibility-settings-button"> - $i18n{accessibilitySettings} - </button> - <button id="talkback-settings-button"> - $i18n{accessibilityTalkBackSettings} - </button> - </div> - </div> - </div> - <div class="option-name"> - <div class="checkbox controlled-setting-with-label"> - <label> - <input - id="accessibility-screen-magnifier-check" - pref="settings.a11y.screen_magnifier" type="checkbox" - metric="Options_AccessibilityScreenMagnifier"> - <span> - <span>$i18n{accessibilityScreenMagnifier}</span> - <span class="controlled-setting-indicator" - pref="settings.a11y.screen_magnifier"></span> - </span> - </label> - </div> - <div class="checkbox controlled-setting-with-label"> - <!-- No whitespace between elements. --> - <input type="checkbox" class="spacer-checkbox"> - <label> - <input - id = "accessibility-screen-magnifier-center-focus-check" - pref="settings.a11y.screen_magnifier_center_focus" type="checkbox" - metric="Options_AccessibilityScreenMagnifierCenterFocus"> - <span> - <span>$i18n{accessibilityScreenMagnifierCenterFocus}</span> - <span class="controlled-setting-indicator" - pref="settings.a11y.screen_magnifier_center_focus"></span> - </span> - </label> - </div> - </div> - <div class="option-name" id="accessibility-tap-dragging"> - <div class="checkbox"> - <label> - <input id="accessibility-tap-dragging-check" - pref="settings.touchpad.enable_tap_dragging" type="checkbox" - metric="Options_AccessibilityTapDragging"> - <span>$i18n{accessibilityTapDragging}</span> - </label> - </div> - </div> - <div class="option-name" id="accessibility-autoclick"> - <div class="checkbox controlled-setting-with-label"> - <label> - <input id="accessibility-autoclick-check" - pref="settings.a11y.autoclick" type="checkbox"> - <span> - <span>$i18n{accessibilityAutoclick}</span> - <span class="controlled-setting-indicator" - pref="settings.a11y.autoclick"></span> - </span> - </label> - </div> - <div class="checkbox"> - <!-- No whitespace between elements. --> - <input type="checkbox" class="spacer-checkbox"> - <span id="accessibility-autoclick-label"> - $i18n{accessibilityAutoclickDropdown} - </span> - <select id="accessibility-autoclick-dropdown" class="control" - data-type="number" - aria-labelledby="accessibility-autoclick-label" - pref="settings.a11y.autoclick_delay_ms"> - <!-- i18n strings contain the autoclick duration; if the autoclick - timing gets changed, then the i18n strings also needs to be - updated. --> - <option value="600">$i18n{autoclickDelayExtremelyShort}</option> - <option value="800">$i18n{autoclickDelayVeryShort}</option> - <option value="1000">$i18n{autoclickDelayShort}</option> - <option value="2000">$i18n{autoclickDelayLong}</option> - <option value="4000">$i18n{autoclickDelayVeryLong}</option> - </select> - <span class="controlled-setting-indicator" - pref="settings.a11y.autoclick_delay_ms"></span> - </div> - </div> - <div class="option-name" id="accessibility_onscreen_keyboard"> - <div class="checkbox controlled-setting-with-label"> - <label> - <input pref="settings.a11y.virtual_keyboard" type="checkbox" - metric="Options_AccessibilityOnScreenKeyboard"> - <span> - <span>$i18n{accessibilityVirtualKeyboard}</span> - <span class="controlled-setting-indicator" - pref="settings.a11y.virtual_keyboard"></span> - </span> - </label> - </div> - </div> - <div class="option-name" id="accessibility_mono_audio"> - <div class="checkbox controlled-setting-with-label"> - <label> - <input pref="settings.a11y.mono_audio" type="checkbox" - metric="Options_AccessibilityMonoAudio"> - <span> - <span>$i18n{accessibilityMonoAudio}</span> - <span class="controlled-setting-indicator" - pref="settings.a11y.mono_audio"></span> - </span> - </label> - </div> - </div> - <div class="option-name"> - <div class="checkbox controlled-setting-with-label"> - <label> - <input pref="settings.a11y.caret_highlight" type="checkbox" - metric="Options_AccessibilityCaretHighlight"> - <span> - <span>$i18n{accessibilityCaretHighlight}</span> - <span class="controlled-setting-indicator" - pref="settings.a11y.caret_highlight"></span> - </span> - </label> - </div> - </div> - <div class="option-name"> - <div class="checkbox controlled-setting-with-label"> - <label> - <input pref="settings.a11y.cursor_highlight" type="checkbox" - metric="Options_AccessibilityCursorHighlight"> - <span> - <span>$i18n{accessibilityCursorHighlight}</span> - <span class="controlled-setting-indicator" - pref="settings.a11y.cursor_highlight"></span> - </span> - </label> - </div> - </div> - <div class="option-name"> - <div class="checkbox controlled-setting-with-label"> - <label> - <input pref="settings.a11y.focus_highlight" type="checkbox" - metric="Options_AccessibilityFocusHighlight"> - <span> - <span>$i18n{accessibilityFocusHighlight}</span> - <span class="controlled-setting-indicator" - pref="settings.a11y.focus_highlight"></span> - </span> - </label> - </div> - </div> - <div id="experimental-accessibility-features" hidden> - <div class="option-name"> - <div class="checkbox controlled-setting-with-label"> - <label> - <input pref="settings.a11y.select_to_speak" type="checkbox" - metric="Options_AccessibilitySelectToSpeak"> - <span> - <span>$i18n{accessibilitySelectToSpeak}</span> - <span class="controlled-setting-indicator" - pref="settings.a11y.select_to_speak"></span> - </span> - </label> - </div> - </div> - <div class="option-name"> - <div class="checkbox controlled-setting-with-label"> - <label> - <input pref="settings.a11y.switch_access" type="checkbox" - metric="Options_AccessibilitySwitchAccess"> - <span> - <span>$i18n{accessibilitySwitchAccess}</span> - <span class="controlled-setting-indicator" - pref="settings.a11y.switch_access"></span> - </span> - </label> - </div> - </div> - </div> - </div> -</if> - -</section> - -<if expr="chromeos"> - <section id="factory-reset-section" hidden> - <h3>$i18n{factoryResetTitle}</h3> - <div> - <span class="settings-row">$i18n{factoryResetDescription}</span> - <button id="factory-reset-restart">$i18n{factoryResetRestart}</button> - </div> - </section> -</if> -<if expr="not chromeos"> - <section id="system-section"> - <h3>$i18n{advancedSectionTitleSystem}</h3> -<if expr="not is_macosx"> - <div class="checkbox controlled-setting-with-label"> - <label> - <input pref="background_mode.enabled" - type="checkbox"> - <span> - <span>$i18n{backgroundModeCheckbox}</span> - <span class="controlled-setting-indicator" - pref="background_mode.enabled"></span> - </span> - </label> - </div> -</if> - <div class="checkbox controlled-setting-with-label"> - <label> - <input id="gpu-mode-checkbox" - pref="hardware_acceleration_mode.enabled" type="checkbox"> - <span> - <span>$i18n{gpuModeCheckbox}</span> - <span class="controlled-setting-indicator" - pref="hardware_acceleration_mode.enabled"></span> - </span> - </label> - <span id="gpu-mode-reset-restart">$i18nRaw{gpuModeResetRestart}</span> - </div> - </section> -</if> - <section id="reset-profile-settings-section"> - <h3>$i18n{resetProfileSettingsSectionTitle}</h3> - <div> - <span class="settings-row">$i18n{resetProfileSettingsDescription}</span> - <button id="reset-profile-settings">$i18n{resetProfileSettings}</button> - </div> - </section> - </div> <!-- advanced-settings-container --> - </div> <!-- advanced-settings --> - <footer id="advanced-settings-footer"> - <a is="action-link" id="advanced-settings-expander"> - $i18n{showAdvancedSettings} - </a> - </footer> -</div>
diff --git a/chrome/browser/resources/options/browser_options.js b/chrome/browser/resources/options/browser_options.js deleted file mode 100644 index 011ef0ce..0000000 --- a/chrome/browser/resources/options/browser_options.js +++ /dev/null
@@ -1,2487 +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. - -cr.exportPath('options'); - -/** - * @typedef {{actionLinkText: (string|undefined), - * accountInfo: (string|undefined), - * childUser: (boolean|undefined), - * hasError: (boolean|undefined), - * hasUnrecoverableError: (boolean|undefined), - * managed: (boolean|undefined), - * setupCompleted: (boolean|undefined), - * setupInProgress: (boolean|undefined), - * signedIn: (boolean|undefined), - * signinAllowed: (boolean|undefined), - * signoutAllowed: (boolean|undefined), - * statusAction: (string|undefined), - * statusText: (string|undefined), - * supervisedUser: (boolean|undefined), - * syncSystemEnabled: (boolean|undefined)}} - * @see chrome/browser/ui/webui/options/browser_options_handler.cc - */ -options.SyncStatus; - -/** - * @typedef {{id: string, name: string}} - */ -options.ExtensionData; - -/** - * @typedef {{name: string, - * filePath: string, - * isCurrentProfile: boolean, - * isSupervised: boolean, - * isChild: boolean, - * iconUrl: string}} - * @see chrome/browser/ui/webui/options/browser_options_handler.cc - */ -options.Profile; - -/** - * Device policy SystemTimezoneAutomaticDetection values. - * @enum {number} - * @const - */ -options.AutomaticTimezoneDetectionType = { - USERS_DECIDE: 0, - DISABLED: 1, - IP_ONLY: 2, - SEND_WIFI_ACCESS_POINTS: 3, - SEND_ALL_LOCATION_INFO: 4, -}; - -cr.define('options', function() { - var OptionsPage = options.OptionsPage; - var Page = cr.ui.pageManager.Page; - var PageManager = cr.ui.pageManager.PageManager; - var ArrayDataModel = cr.ui.ArrayDataModel; - var RepeatingButton = cr.ui.RepeatingButton; - var HotwordSearchSettingIndicator = options.HotwordSearchSettingIndicator; - var NetworkPredictionOptions = { - ALWAYS: 0, - WIFI_ONLY: 1, - NEVER: 2, - DEFAULT: 1 - }; - - /** - * Encapsulated handling of browser options page. - * @constructor - * @extends {cr.ui.pageManager.Page} - */ - function BrowserOptions() { - Page.call(this, 'settings', loadTimeData.getString('settingsTitle'), - 'settings'); - } - - cr.addSingletonGetter(BrowserOptions); - - /** - * @param {HTMLElement} section The section to show or hide. - * @return {boolean} Whether the section should be shown. - * @private - */ - BrowserOptions.shouldShowSection_ = function(section) { - // If the section is hidden or hiding, it should be shown. - return section.style.height == '' || section.style.height == '0px'; - }; - - BrowserOptions.prototype = { - __proto__: Page.prototype, - - /** - * Keeps track of whether the user is signed in or not. - * @private {boolean} - */ - signedIn_: false, - - /** - * Indicates whether signing out is allowed or whether a complete profile - * wipe is required to remove the current enterprise account. - * @private {boolean} - */ - signoutAllowed_: true, - - /** - * Keeps track of whether |onShowHomeButtonChanged_| has been called. See - * |onShowHomeButtonChanged_|. - * @private {boolean} - */ - onShowHomeButtonChangedCalled_: false, - - /** - * Track if page initialization is complete. All C++ UI handlers have the - * chance to manipulate page content within their InitializePage methods. - * This flag is set to true after all initializers have been called. - * @private {boolean} - */ - initializationComplete_: false, - - /** - * Current status of "Resolve Timezone by Geolocation" checkbox. - * @private {boolean} - */ - resolveTimezoneByGeolocation_: false, - - /** - * True if system timezone is managed by policy. - * @private {boolean} - */ - systemTimezoneIsManaged_: false, - - /** - * True if system timezone detection is managed by policy. - * @private {boolean} - */ - systemTimezoneAutomaticDetectionIsManaged_: false, - - /** - * This is the value of SystemTimezoneAutomaticDetection policy. - * @private {number} - */ - systemTimezoneAutomaticDetectionValue_: 0, - - /** - * Cached bluetooth adapter state. - * @private {?chrome.bluetooth.AdapterState} - */ - bluetoothAdapterState_: null, - - /** @override */ - initializePage: function() { - Page.prototype.initializePage.call(this); - var self = this; - - if (window.top != window) { - // The options page is not in its own window. - document.body.classList.add('uber-frame'); - PageManager.horizontalOffset = 155; - } - - // Ensure that navigation events are unblocked on uber page. A reload of - // the settings page while an overlay is open would otherwise leave uber - // page in a blocked state, where tab switching is not possible. - uber.invokeMethodOnParent('stopInterceptingEvents'); - - window.addEventListener('message', this.handleWindowMessage_.bind(this)); - - if (loadTimeData.getBoolean('allowAdvancedSettings')) { - $('advanced-settings-expander').onclick = function(e) { - var showAdvanced = - BrowserOptions.shouldShowSection_($('advanced-settings')); - if (showAdvanced) { - chrome.send('coreOptionsUserMetricsAction', - ['Options_ShowAdvancedSettings']); - } - self.toggleSectionWithAnimation_( - $('advanced-settings'), - $('advanced-settings-container')); - - // If the click was triggered using the keyboard and it showed the - // section (rather than hiding it), focus the first element in the - // container. - if (e.detail == 0 && showAdvanced) { - var focusElement = $('advanced-settings-container').querySelector( - 'button, input, list, select, a[href]'); - if (focusElement) - focusElement.focus(); - } - }; - } else { - $('advanced-settings-footer').hidden = true; - $('advanced-settings').hidden = true; - } - - $('advanced-settings').addEventListener('transitionend', - this.updateAdvancedSettingsExpander_.bind(this)); - - if (loadTimeData.valueExists('aboutOverlayTabTitle')) { - $('about-button').hidden = false; - $('about-button').addEventListener('click', function() { - PageManager.showPageByName('help'); - chrome.send('coreOptionsUserMetricsAction', - ['Options_About']); - }); - } - - if (cr.isChromeOS) { - UIAccountTweaks.applyGuestSessionVisibility(document); - UIAccountTweaks.applyPublicSessionVisibility(document); - if (loadTimeData.getBoolean('secondaryUser')) - $('secondary-user-banner').hidden = false; - } - - // Sync (Sign in) section. - this.updateSyncState_(/** @type {options.SyncStatus} */( - loadTimeData.getValue('syncData'))); - if (!$('sync-overview').hidden) { - chrome.send('metricsHandler:recordAction', - ['Signin_Impression_FromSettings']); - } - - $('start-stop-sync').onclick = function(event) { - if (self.signedIn_) { - if (self.signoutAllowed_) - SyncSetupOverlay.showStopSyncingUI(); - else - chrome.send('showDisconnectManagedProfileDialog'); - } else if (cr.isChromeOS) { - SyncSetupOverlay.showSetupUI(); - } else { - SyncSetupOverlay.startSignIn(false /* creatingSupervisedUser */); - } - }; - $('customize-sync').onclick = function(event) { - SyncSetupOverlay.showSetupUI(); - }; - - // Internet connection section (ChromeOS only). - if (cr.isChromeOS) { - options.network.NetworkList.decorate($('network-list')); - // Show that the network settings are shared if this is a secondary user - // in a multi-profile session. - if (loadTimeData.getBoolean('secondaryUser')) { - var networkIndicator = document.querySelector( - '#network-section-header > .controlled-setting-indicator'); - networkIndicator.setAttribute('controlled-by', 'shared'); - networkIndicator.location = cr.ui.ArrowLocation.TOP_START; - } - } - - // On Startup section. - Preferences.getInstance().addEventListener('session.restore_on_startup', - this.onRestoreOnStartupChanged_.bind(this)); - Preferences.getInstance().addEventListener( - 'session.startup_urls', - function(event) { - $('startup-set-pages').disabled = event.value.disabled; - }); - - $('startup-set-pages').onclick = function() { - PageManager.showPageByName('startup'); - }; - - // Appearance section. - Preferences.getInstance().addEventListener('browser.show_home_button', - this.onShowHomeButtonChanged_.bind(this)); - - Preferences.getInstance().addEventListener('homepage', - this.onHomePageChanged_.bind(this)); - Preferences.getInstance().addEventListener('homepage_is_newtabpage', - this.onHomePageIsNtpChanged_.bind(this)); - - $('change-home-page').onclick = function(event) { - PageManager.showPageByName('homePageOverlay'); - chrome.send('coreOptionsUserMetricsAction', - ['Options_Homepage_ShowSettings']); - }; - - HotwordSearchSettingIndicator.decorate( - $('hotword-search-setting-indicator')); - HotwordSearchSettingIndicator.decorate( - $('hotword-no-dsp-search-setting-indicator')); - var hotwordIndicator = $('hotword-always-on-search-setting-indicator'); - HotwordSearchSettingIndicator.decorate(hotwordIndicator); - hotwordIndicator.disabledOnErrorSection = - $('hotword-always-on-search-checkbox'); - chrome.send('requestHotwordAvailable'); - - chrome.send('requestGoogleNowAvailable'); - - if ($('set-wallpaper')) { - $('set-wallpaper').onclick = function(event) { - chrome.send('openWallpaperManager'); - chrome.send('coreOptionsUserMetricsAction', - ['Options_OpenWallpaperManager']); - }; - } - - // Control the hotword-always-on pref with the Hotword Audio - // Verification app. - $('hotword-always-on-search-checkbox').customChangeHandler = - function(event) { - if (!$('hotword-always-on-search-checkbox').checked) - return false; - - $('hotword-always-on-search-checkbox').checked = false; - chrome.send('launchHotwordAudioVerificationApp', [false]); - return true; - }; - - // Open the Hotword Audio Verification app to retrain a voice model. - $('hotword-retrain-link').onclick = function(event) { - chrome.send('launchHotwordAudioVerificationApp', [true]); - }; - Preferences.getInstance().addEventListener( - 'hotword.always_on_search_enabled', - this.onHotwordAlwaysOnChanged_.bind(this)); - - $('themes-gallery').onclick = function(event) { - window.open(loadTimeData.getString('themesGalleryURL')); - chrome.send('coreOptionsUserMetricsAction', - ['Options_ThemesGallery']); - }; - $('themes-reset').onclick = function(event) { - chrome.send('themesReset'); - }; - - if (loadTimeData.getBoolean('profileIsSupervised')) { - if ($('themes-native-button')) { - $('themes-native-button').disabled = true; - $('themes-native-button').hidden = true; - } - // Supervised users have just one default theme, even on Linux. So use - // the same button for Linux as for the other platforms. - $('themes-reset').textContent = loadTimeData.getString('themesReset'); - } - - // Device section (ChromeOS only). - if (cr.isChromeOS) { - // Probe for stylus hardware state. C++ will invoke - // BrowserOptions.setStylusInputStatus_ when the data is available. - chrome.send('requestStylusHardwareState'); - - if (loadTimeData.getBoolean('showPowerStatus')) { - $('power-settings-link').onclick = function(evt) { - PageManager.showPageByName('power-overlay'); - chrome.send('coreOptionsUserMetricsAction', - ['Options_ShowPowerSettings']); - }; - $('power-row').hidden = false; - } - $('keyboard-settings-button').onclick = function(evt) { - PageManager.showPageByName('keyboard-overlay'); - chrome.send('coreOptionsUserMetricsAction', - ['Options_ShowKeyboardSettings']); - }; - $('pointer-settings-button').onclick = function(evt) { - PageManager.showPageByName('pointer-overlay'); - chrome.send('coreOptionsUserMetricsAction', - ['Options_ShowTouchpadSettings']); - }; - $('storage-manager-button').onclick = function(evt) { - PageManager.showPageByName('storage'); - chrome.send('coreOptionsUserMetricsAction', - ['Options_ShowStorageManager']); - }; - } - - // Search section. - $('manage-default-search-engines').onclick = function(event) { - PageManager.showPageByName('searchEngines'); - chrome.send('coreOptionsUserMetricsAction', - ['Options_ManageSearchEngines']); - }; - $('default-search-engine').addEventListener('change', - this.setDefaultSearchEngine_); - - // Users section. - if (loadTimeData.valueExists('profilesInfo')) { - $('profiles-section').hidden = false; - this.maybeShowUserSection_(); - - var profilesList = $('profiles-list'); - options.browser_options.ProfileList.decorate(profilesList); - profilesList.autoExpands = true; - - // The profiles info data in |loadTimeData| might be stale. - this.setProfilesInfo_(/** @type {!Array<!options.Profile>} */( - loadTimeData.getValue('profilesInfo'))); - chrome.send('requestProfilesInfo'); - - profilesList.addEventListener('change', - this.setProfileViewButtonsStatus_); - $('profiles-create').onclick = function(event) { - chrome.send('metricsHandler:recordAction', - ['Options_ShowCreateProfileDlg']); - ManageProfileOverlay.showCreateDialog(); - }; - $('profiles-manage').onclick = function(event) { - chrome.send('metricsHandler:recordAction', - ['Options_ShowEditProfileDlg']); - ManageProfileOverlay.showManageDialog(); - }; - $('profiles-delete').onclick = function(event) { - var selectedProfile = self.getSelectedProfileItem_(); - if (selectedProfile) { - chrome.send('metricsHandler:recordAction', - ['Options_ShowDeleteProfileDlg']); - ManageProfileOverlay.showDeleteDialog(selectedProfile); - } - }; - if (loadTimeData.getBoolean('profileIsSupervised')) { - $('profiles-create').disabled = true; - } - if (!loadTimeData.getBoolean('allowProfileDeletion')) { - $('profiles-delete').disabled = true; - $('profiles-list').canDeleteItems = false; - } - } - - if (cr.isChromeOS) { - // Username (canonical email) of the currently logged in user or - // |kGuestUser| if a guest session is active. - this.username_ = loadTimeData.getString('username'); - - this.updateAccountPicture_(); - - $('account-picture').onclick = this.showImagerPickerOverlay_; - $('change-picture-caption').onclick = this.showImagerPickerOverlay_; - - $('manage-accounts-button').onclick = function(event) { - PageManager.showPageByName('accounts'); - chrome.send('coreOptionsUserMetricsAction', - ['Options_ManageAccounts']); - }; - - if (loadTimeData.getBoolean('showQuickUnlockSettings')) { - $('manage-screenlock').onclick = function(event) { - PageManager.showPageByName('quickUnlockConfigureOverlay'); - settings.recordLockScreenProgress( - LockScreenProgress.START_SCREEN_LOCK); - }; - $('manage-screenlock').hidden = false; - } - } else { - $('import-data').onclick = function(event) { - ImportDataOverlay.show(); - chrome.send('coreOptionsUserMetricsAction', ['Import_ShowDlg']); - }; - - if ($('themes-native-button')) { - $('themes-native-button').onclick = function(event) { - chrome.send('themesSetNative'); - }; - } - } - - // Date and time section (CrOS only). - if (cr.isChromeOS) { - if ($('set-time-button')) - $('set-time-button').onclick = this.handleSetTime_.bind(this); - - // Timezone - if (loadTimeData.getBoolean('enableTimeZoneTrackingOption')) { - $('resolve-timezone-by-geolocation-selection').hidden = false; - this.resolveTimezoneByGeolocation_ = loadTimeData.getBoolean( - 'resolveTimezoneByGeolocationInitialValue'); - this.updateTimezoneSectionState_(); - Preferences.getInstance().addEventListener( - 'settings.resolve_timezone_by_geolocation', - this.onResolveTimezoneByGeolocationChanged_.bind(this)); - } - } - - // Default browser section. - if (!cr.isChromeOS) { - if (!loadTimeData.getBoolean('showSetDefault')) { - $('set-default-browser-section').hidden = true; - } - $('set-as-default-browser').onclick = function(event) { - chrome.send('becomeDefaultBrowser'); - }; - } - - // Privacy section. - $('privacyContentSettingsButton').onclick = function(event) { - PageManager.showPageByName('content'); - OptionsPage.showTab($('cookies-nav-tab')); - chrome.send('coreOptionsUserMetricsAction', - ['Options_ContentSettings']); - }; - $('privacyClearDataButton').onclick = function(event) { - PageManager.showPageByName('clearBrowserData'); - chrome.send('coreOptionsUserMetricsAction', ['Options_ClearData']); - }; - - if ($('metrics-reporting-enabled')) { - $('metrics-reporting-enabled').checked = - loadTimeData.getBoolean('metricsReportingEnabledAtStart'); - - // A browser restart is never needed to toggle metrics reporting, - // and is only needed to toggle crash reporting when using Breakpad. - // Crashpad, used on Mac, does not require a browser restart. - var togglingMetricsRequiresRestart = !cr.isMac && !cr.isChromeOS; - $('metrics-reporting-enabled').onclick = function(event) { - chrome.send('metricsReportingCheckboxChanged', - [Boolean(event.currentTarget.checked)]); - if (cr.isChromeOS) { - // 'metricsReportingEnabled' element is only present on Chrome - // branded builds, and the 'metricsReportingCheckboxAction' message - // is only handled on ChromeOS. - chrome.send('metricsReportingCheckboxAction', - [String(event.currentTarget.checked)]); - } - - if (togglingMetricsRequiresRestart) { - $('metrics-reporting-reset-restart').hidden = - loadTimeData.getBoolean('metricsReportingEnabledAtStart') == - $('metrics-reporting-enabled').checked; - } - - }; - - // Initialize restart button if needed. - if (togglingMetricsRequiresRestart) { - // The localized string has the | symbol on each side of the text that - // needs to be made into a button to restart Chrome. We parse the text - // and build the button from that. - var restartTextFragments = - loadTimeData.getString('metricsReportingResetRestart').split('|'); - // Assume structure is something like "starting text |link text| - // ending text" where both starting text and ending text may or may - // not be present, but the split should always be in three pieces. - var restartElements = - $('metrics-reporting-reset-restart').querySelectorAll('*'); - for (var i = 0; i < restartTextFragments.length; i++) { - restartElements[i].textContent = restartTextFragments[i]; - } - restartElements[1].onclick = function(event) { - chrome.send('restartBrowser'); - }; - } - } - $('networkPredictionOptions').onchange = function(event) { - var value = (event.target.checked ? - NetworkPredictionOptions.WIFI_ONLY : - NetworkPredictionOptions.NEVER); - var metric = event.target.metric; - Preferences.setIntegerPref( - 'net.network_prediction_options', - value, - true, - metric); - }; - if (loadTimeData.valueExists('showWakeOnWifi') && - loadTimeData.getBoolean('showWakeOnWifi')) { - $('wake-on-wifi').hidden = false; - } - - // Bluetooth (CrOS only). - if (cr.isChromeOS) { - // Request the intial bluetooth adapter state. - var adapterStateChanged = - this.onBluetoothAdapterStateChanged_.bind(this); - chrome.bluetooth.getAdapterState(adapterStateChanged); - - // Set up observers. - chrome.bluetooth.onAdapterStateChanged.addListener(adapterStateChanged); - var deviceAddedOrChanged = - this.onBluetoothDeviceAddedOrChanged_.bind(this); - chrome.bluetooth.onDeviceAdded.addListener(deviceAddedOrChanged); - chrome.bluetooth.onDeviceChanged.addListener(deviceAddedOrChanged); - chrome.bluetooth.onDeviceRemoved.addListener( - this.onBluetoothDeviceRemoved_.bind(this)); - - chrome.bluetoothPrivate.onPairing.addListener( - this.onBluetoothPrivatePairing_.bind(this)); - - // Initialize UI. - options.system.bluetooth.BluetoothDeviceList.decorate( - $('bluetooth-paired-devices-list')); - - $('bluetooth-add-device').onclick = - this.handleAddBluetoothDevice_.bind(this); - - $('enable-bluetooth').onchange = function(event) { - var state = $('enable-bluetooth').checked; - chrome.bluetoothPrivate.setAdapterState({powered: state}, function() { - if (chrome.runtime.lastError) { - console.error('Error enabling bluetooth:', - chrome.runtime.lastError.message); - } - }); - }; - - $('bluetooth-reconnect-device').onclick = function(event) { - chrome.send('coreOptionsUserMetricsAction', - ['Options_BluetoothConnectPairedDevice']); - var device = $('bluetooth-paired-devices-list').selectedItem; - BluetoothPairing.connect(device); - }; - - $('bluetooth-paired-devices-list').addEventListener('change', - function() { - var item = $('bluetooth-paired-devices-list').selectedItem; - var disabled = !item || item.connected || !item.connectable; - $('bluetooth-reconnect-device').disabled = disabled; - }); - } - - // Passwords and Forms section. - $('autofill-settings').onclick = function(event) { - PageManager.showPageByName('autofill'); - chrome.send('coreOptionsUserMetricsAction', - ['Options_ShowAutofillSettings']); - }; - $('manage-passwords').onclick = function(event) { - PageManager.showPageByName('passwords'); - OptionsPage.showTab($('passwords-nav-tab')); - chrome.send('coreOptionsUserMetricsAction', - ['Options_ShowPasswordManager']); - }; - if (cr.isChromeOS && UIAccountTweaks.loggedInAsGuest()) { - // Disable and turn off Autofill in guest mode. - var autofillEnabled = $('autofill-enabled'); - autofillEnabled.disabled = true; - autofillEnabled.checked = false; - cr.dispatchSimpleEvent(autofillEnabled, 'change'); - $('autofill-settings').disabled = true; - - // Disable and turn off Password Manager in guest mode. - var passwordManagerEnabled = $('password-manager-enabled'); - passwordManagerEnabled.disabled = true; - passwordManagerEnabled.checked = false; - cr.dispatchSimpleEvent(passwordManagerEnabled, 'change'); - $('manage-passwords').disabled = true; - } - - if (cr.isMac) { - $('mac-passwords-warning').hidden = - !loadTimeData.getBoolean('multiple_profiles'); - } - - // Network section. - if (!cr.isChromeOS) { - $('proxiesConfigureButton').onclick = function(event) { - chrome.send('showNetworkProxySettings'); - }; - } - - // Easy Unlock section. - if (loadTimeData.getBoolean('easyUnlockAllowed')) { - $('easy-unlock-section').hidden = false; - $('easy-unlock-setup-button').onclick = function(event) { - chrome.send('launchEasyUnlockSetup'); - }; - $('easy-unlock-turn-off-button').onclick = function(event) { - PageManager.showPageByName('easyUnlockTurnOffOverlay'); - }; - } - - // Web Content section. - $('fontSettingsCustomizeFontsButton').onclick = function(event) { - PageManager.showPageByName('fonts'); - chrome.send('coreOptionsUserMetricsAction', - ['Options_ShowFontSettings']); - }; - $('defaultFontSize').onchange = function(event) { - var value = event.target.options[event.target.selectedIndex].value; - Preferences.setIntegerPref( - 'webkit.webprefs.default_fixed_font_size', - value - OptionsPage.SIZE_DIFFERENCE_FIXED_STANDARD, true); - chrome.send('defaultFontSizeAction', [String(value)]); - }; - $('defaultZoomFactor').onchange = function(event) { - chrome.send('defaultZoomFactorAction', - [String(event.target.options[event.target.selectedIndex].value)]); - }; - $('safeBrowsingExtendedReportingCheckbox').onchange = function(event) { - chrome.send('safeBrowsingExtendedReportingAction', - [event.target.checked]); - }; - - // Languages section. - var showLanguageOptions = function(event) { - PageManager.showPageByName('languages'); - chrome.send('coreOptionsUserMetricsAction', - ['Options_LanuageAndSpellCheckSettings']); - }; - $('language-button').onclick = showLanguageOptions; - $('manage-languages').onclick = showLanguageOptions; - - // Downloads section. - Preferences.getInstance().addEventListener('download.default_directory', - this.onDefaultDownloadDirectoryChanged_.bind(this)); - $('downloadLocationChangeButton').onclick = function(event) { - chrome.send('selectDownloadLocation'); - }; - if (cr.isChromeOS) { - $('disable-drive-row').hidden = - UIAccountTweaks.loggedInAsSupervisedUser(); - } - $('autoOpenFileTypesResetToDefault').onclick = function(event) { - chrome.send('autoOpenFileTypesAction'); - }; - - // HTTPS/SSL section. - if (cr.isWindows || cr.isMac) { - $('certificatesManageButton').onclick = function(event) { - chrome.send('showManageSSLCertificates'); - }; - } else { - $('certificatesManageButton').onclick = function(event) { - PageManager.showPageByName('certificates'); - chrome.send('coreOptionsUserMetricsAction', - ['Options_ManageSSLCertificates']); - }; - } - - // CUPS Print section (CrOS only). - if (cr.isChromeOS) { - $('cups-printers-section').hidden = false; - $('cupsPrintersManageButton').onclick = function() { - chrome.send('showCupsPrintDevicesPage'); - }; - } - - if (loadTimeData.getBoolean('cloudPrintShowMDnsOptions')) { - $('cloudprint-options-mdns').hidden = false; - $('cloudPrintDevicesPageButton').onclick = function() { - chrome.send('showCloudPrintDevicesPage'); - }; - } - - // Accessibility section (CrOS only). - if (cr.isChromeOS) { - var updateAccessibilitySettingsSection = function() { - $('accessibility-settings').hidden = - !($('accessibility-spoken-feedback-check').checked); - }; - Preferences.getInstance().addEventListener( - 'settings.accessibility', - updateAccessibilitySettingsSection); - $('accessibility-learn-more').onclick = function(unused_event) { - chrome.send('coreOptionsUserMetricsAction', - ['Options_AccessibilityLearnMore']); - }; - $('accessibility-settings-button').onclick = function(unused_event) { - window.open(loadTimeData.getString('accessibilitySettingsURL')); - }; - $('talkback-settings-button').onclick = function(unused_event) { - chrome.send('showAccessibilityTalkBackSettings'); - }; - $('accessibility-spoken-feedback-check').onchange = - updateAccessibilitySettingsSection; - updateAccessibilitySettingsSection(); - - var updateScreenMagnifierCenterFocus = function() { - $('accessibility-screen-magnifier-center-focus-check').disabled = - !$('accessibility-screen-magnifier-check').checked; - }; - Preferences.getInstance().addEventListener( - $('accessibility-screen-magnifier-check').getAttribute('pref'), - updateScreenMagnifierCenterFocus); - - var updateDelayDropdown = function() { - $('accessibility-autoclick-dropdown').disabled = - !$('accessibility-autoclick-check').checked; - }; - Preferences.getInstance().addEventListener( - $('accessibility-autoclick-check').getAttribute('pref'), - updateDelayDropdown); - $('experimental-accessibility-features').hidden = - !loadTimeData.getBoolean('enableExperimentalAccessibilityFeatures'); - } - - // Display management section (CrOS only). - if (cr.isChromeOS) { - $('display-options').onclick = function(event) { - PageManager.showPageByName('display'); - chrome.send('coreOptionsUserMetricsAction', - ['Options_Display']); - }; - } - - // Factory reset section (CrOS only). - if (cr.isChromeOS) { - $('factory-reset-restart').onclick = function(event) { - PageManager.showPageByName('factoryResetData'); - chrome.send('onPowerwashDialogShow'); - }; - } - - // System section. - if (!cr.isChromeOS) { - var updateGpuRestartButton = function() { - $('gpu-mode-reset-restart').hidden = - loadTimeData.getBoolean('gpuEnabledAtStart') == - $('gpu-mode-checkbox').checked; - }; - Preferences.getInstance().addEventListener( - $('gpu-mode-checkbox').getAttribute('pref'), - updateGpuRestartButton); - $('gpu-mode-reset-restart-button').onclick = function(event) { - chrome.send('restartBrowser'); - }; - updateGpuRestartButton(); - } - - // Reset profile settings section. - $('reset-profile-settings').onclick = function(event) { - // We use the hash to indicate the source of the reset request. The hash - // is removed by the reset profile settings overlay once it has been - // consumed. - PageManager.showPageByName('resetProfileSettings', true, - {hash: '#userclick'}); - }; - - // Extension controlled UI. - this.addExtensionControlledBox_('search-section-content', - 'search-engine-controlled', - true); - this.addExtensionControlledBox_('extension-controlled-container', - 'homepage-controlled', - true); - this.addExtensionControlledBox_('startup-section-content', - 'startpage-controlled', - false); - this.addExtensionControlledBox_('newtab-section-content', - 'newtab-controlled', - false); - this.addExtensionControlledBox_('proxy-section-content', - 'proxy-controlled', - true); - - document.body.addEventListener('click', function(e) { - var target = assertInstanceof(e.target, Node); - var button = findAncestor(target, function(el) { - return el.tagName == 'BUTTON' && - el.dataset.extensionId !== undefined && - el.dataset.extensionId.length; - }); - if (button) - chrome.send('disableExtension', [button.dataset.extensionId]); - }); - - // Setup ARC section. - if (cr.isChromeOS) { - $('android-apps-settings-label').innerHTML = - loadTimeData.getString('androidAppsSettingsLabel'); - Preferences.getInstance().addEventListener('arc.enabled', function(e) { - // Only change settings visibility on committed settings changes. - if (e.value.uncommitted) - return; - - var isArcEnabled = !e.value.value; - $('android-apps-settings').hidden = isArcEnabled; - $('talkback-settings-button').hidden = isArcEnabled; - $('stylus-find-more-link').hidden = isArcEnabled; - }); - - $('android-apps-settings-link').addEventListener('click', function(e) { - // MouseEvent.detail indicates the current click count (or tap - // count, in the case of touch events) in the 'click' event. - var activatedFromKeyboard = e.detail == 0; - chrome.send('showAndroidAppsSettings', [activatedFromKeyboard]); - }); - } - }, - - /** @override */ - didShowPage: function() { - $('search-field').focus(); - }, - - /** - * Called after all C++ UI handlers have called InitializePage to notify - * that initialization is complete. - * @private - */ - notifyInitializationComplete_: function() { - this.initializationComplete_ = true; - cr.dispatchSimpleEvent(document, 'initializationComplete'); - }, - - /** - * Event listener for the 'session.restore_on_startup' pref. - * @param {Event} event The preference change event. - * @private - */ - onRestoreOnStartupChanged_: function(event) { - /** @const */ var showHomePageValue = 0; - - if (event.value.value == showHomePageValue) { - // If the user previously selected "Show the homepage", the - // preference will already be migrated to "Open a specific page". So - // the only way to reach this code is if the 'restore on startup' - // preference is managed. - assert(event.value.controlledBy); - - // Select "open the following pages" and lock down the list of URLs - // to reflect the intention of the policy. - $('startup-show-pages').checked = true; - StartupOverlay.getInstance().setControlsDisabled(true); - } else { - // Re-enable the controls in the startup overlay if necessary. - StartupOverlay.getInstance().updateControlStates(); - } - }, - - /** - * Handler for messages sent from the main uber page. - * @param {Event} e The 'message' event from the uber page. - * @private - */ - handleWindowMessage_: function(e) { - if ((/** @type {{method: string}} */(e.data)).method == 'frameSelected') - $('search-field').focus(); - }, - - /** - * Animatedly changes height |from| a px number |to| a px number. - * @param {HTMLElement} section The section to animate. - * @param {HTMLElement} container The container of |section|. - * @param {boolean} showing Whether to go from 0 -> container height or - * container height -> 0. - * @private - */ - animatedSectionHeightChange_: function(section, container, showing) { - // If the section is already animating, dispatch a synthetic transition - // end event as the upcoming code will cancel the current one. - if (section.classList.contains('sliding')) - cr.dispatchSimpleEvent(section, 'transitionend'); - - this.addTransitionEndListener_(section); - - section.hidden = false; - section.style.height = (showing ? 0 : container.offsetHeight) + 'px'; - section.classList.add('sliding'); - - // Force a style recalc before starting the animation. - /** @suppress {suspiciousCode} */ - section.offsetHeight; - - section.style.height = (showing ? container.offsetHeight : 0) + 'px'; - }, - - /** - * Shows the given section. - * @param {HTMLElement} section The section to be shown. - * @param {HTMLElement} container The container for the section. Must be - * inside of |section|. - * @param {boolean} animate Indicate if the expansion should be animated. - * @private - */ - showSection_: function(section, container, animate) { - if (section == $('advanced-settings') && - !loadTimeData.getBoolean('allowAdvancedSettings')) { - return; - } - // Delay starting the transition if animating so that hidden change will - // be processed. - if (animate) { - this.animatedSectionHeightChange_(section, container, true); - } else { - section.hidden = false; - section.style.height = 'auto'; - } - }, - - /** - * Shows the given section, with animation. - * @param {HTMLElement} section The section to be shown. - * @param {HTMLElement} container The container for the section. Must be - * inside of |section|. - * @private - */ - showSectionWithAnimation_: function(section, container) { - this.showSection_(section, container, /* animate */ true); - }, - - /** - * Hides the given |section| with animation. - * @param {HTMLElement} section The section to be hidden. - * @param {HTMLElement} container The container for the section. Must be - * inside of |section|. - * @private - */ - hideSectionWithAnimation_: function(section, container) { - this.animatedSectionHeightChange_(section, container, false); - }, - - /** - * Toggles the visibility of |section| in an animated way. - * @param {HTMLElement} section The section to be toggled. - * @param {HTMLElement} container The container for the section. Must be - * inside of |section|. - * @private - */ - toggleSectionWithAnimation_: function(section, container) { - if (BrowserOptions.shouldShowSection_(section)) - this.showSectionWithAnimation_(section, container); - else - this.hideSectionWithAnimation_(section, container); - }, - - /** - * Scrolls the settings page to make the section visible auto-expanding - * advanced settings if required. The transition is not animated. This - * method is used to ensure that a section associated with an overlay - * is visible when the overlay is closed. - * @param {!Element} section The section to make visible. - * @private - */ - scrollToSection_: function(section) { - var advancedSettings = $('advanced-settings'); - var container = $('advanced-settings-container'); - var expander = $('advanced-settings-expander'); - if (!expander.hidden && - advancedSettings.hidden && - section.parentNode == container) { - this.showSection_($('advanced-settings'), - $('advanced-settings-container'), - /* animate */ false); - this.updateAdvancedSettingsExpander_(); - } - - if (!this.initializationComplete_) { - var self = this; - var callback = function() { - document.removeEventListener('initializationComplete', callback); - self.scrollToSection_(section); - }; - document.addEventListener('initializationComplete', callback); - return; - } - - var pageContainer = $('page-container'); - // pageContainer.offsetTop is relative to the screen. - var pageTop = pageContainer.offsetTop; - var sectionBottom = section.offsetTop + section.offsetHeight; - // section.offsetTop is relative to the 'page-container'. - var sectionTop = section.offsetTop; - if (pageTop + sectionBottom > document.body.scrollHeight || - pageTop + sectionTop < 0) { - // Currently not all layout updates are guaranteed to precede the - // initializationComplete event (for example 'set-as-default-browser' - // button) leaving some uncertainty in the optimal scroll position. - // The section is placed approximately in the middle of the screen. - var top = Math.min(0, document.body.scrollHeight / 2 - sectionBottom); - pageContainer.style.top = top + 'px'; - pageContainer.oldScrollTop = -top; - } - }, - - /** - * Adds a |transitionend| listener to the given section so that - * it can be animated. The listener will only be added to a given section - * once, so this can be called as multiple times. - * @param {HTMLElement} section The section to be animated. - * @private - */ - addTransitionEndListener_: function(section) { - if (section.hasTransitionEndListener_) - return; - - section.addEventListener('transitionend', - this.onTransitionEnd_.bind(this)); - section.hasTransitionEndListener_ = true; - }, - - /** - * Called after an animation transition has ended. - * @param {Event} event The transitionend event. NOTE: May be - * synthetic. - * @private - */ - onTransitionEnd_: function(event) { - if (event.propertyName && event.propertyName != 'height') { - // If not a synthetic event or a real transition we care about, bail. - return; - } - - var section = event.target; - section.classList.remove('sliding'); - - if (!event.propertyName) { - // Only real transitions past this point. - return; - } - - if (section.style.height == '0px') { - // Hide the content so it can't get tab focus. - section.hidden = true; - section.style.height = ''; - } else { - // Set the section height to 'auto' to allow for size changes - // (due to font change or dynamic content). - section.style.height = 'auto'; - } - }, - - /** @private */ - updateAdvancedSettingsExpander_: function() { - var expander = $('advanced-settings-expander'); - if (BrowserOptions.shouldShowSection_($('advanced-settings'))) - expander.textContent = loadTimeData.getString('showAdvancedSettings'); - else - expander.textContent = loadTimeData.getString('hideAdvancedSettings'); - }, - - /** - * Updates the sync section with the given state. - * @param {options.SyncStatus} syncData A bunch of data records that - * describe the status of the sync system. - * @private - */ - updateSyncState_: function(syncData) { - if (!syncData.signinAllowed && - (!syncData.supervisedUser || !cr.isChromeOS)) { - $('sync-section').hidden = true; - this.maybeShowUserSection_(); - return; - } - - $('sync-section').hidden = false; - this.maybeShowUserSection_(); - - if (cr.isChromeOS && syncData.supervisedUser && !syncData.childUser) { - var subSection = $('sync-section').firstChild; - while (subSection) { - if (subSection.nodeType == Node.ELEMENT_NODE) - subSection.hidden = true; - subSection = subSection.nextSibling; - } - - $('account-picture-wrapper').hidden = false; - $('sync-general').hidden = false; - $('sync-status').hidden = true; - - return; - } - - // If the user gets signed out while the advanced sync settings dialog is - // visible, say, due to a dashboard clear, close the dialog. - // However, if the user gets signed out as a result of abandoning first - // time sync setup, do not call closeOverlay as it will redirect the - // browser to the main settings page and override any in-progress - // user-initiated navigation. See crbug.com/278030. - // Note: SyncSetupOverlay.closeOverlay is a no-op if the overlay is - // already hidden. - if (this.signedIn_ && !syncData.signedIn && !syncData.setupInProgress) - SyncSetupOverlay.closeOverlay(); - - this.signedIn_ = !!syncData.signedIn; - - // Display the "advanced settings" button if we're signed in and sync is - // not managed/disabled. If the user is signed in, but sync is disabled, - // this button is used to re-enable sync. - var customizeSyncButton = $('customize-sync'); - customizeSyncButton.hidden = !this.signedIn_ || - syncData.managed || - !syncData.syncSystemEnabled; - - // Only modify the customize button's text if the new text is different. - // Otherwise, it can affect search-highlighting in the settings page. - // See http://crbug.com/268265. - var customizeSyncButtonNewText = syncData.setupCompleted ? - loadTimeData.getString('customizeSync') : - loadTimeData.getString('syncButtonTextStart'); - if (customizeSyncButton.textContent != customizeSyncButtonNewText) - customizeSyncButton.textContent = customizeSyncButtonNewText; - - // Disable the "sign in" button if we're currently signing in, or if we're - // already signed in and signout is not allowed. - var signInButton = $('start-stop-sync'); - signInButton.disabled = syncData.setupInProgress; - this.signoutAllowed_ = !!syncData.signoutAllowed; - if (!syncData.signoutAllowed) - $('start-stop-sync-indicator').setAttribute('controlled-by', 'policy'); - else - $('start-stop-sync-indicator').removeAttribute('controlled-by'); - - // Hide the "sign in" button on Chrome OS, and show it on desktop Chrome - // (except for supervised users, which can't change their signed-in - // status). - signInButton.hidden = cr.isChromeOS || syncData.supervisedUser; - - signInButton.textContent = - this.signedIn_ ? - loadTimeData.getString('syncButtonTextStop') : - syncData.setupInProgress ? - loadTimeData.getString('syncButtonTextInProgress') : - loadTimeData.getString('syncButtonTextSignIn'); - $('start-stop-sync-indicator').hidden = signInButton.hidden; - - $('account-info').textContent = syncData.accountInfo; - $('account-info').hidden = !this.signedIn_; - - // TODO(estade): can this just be textContent? - $('sync-status-text').innerHTML = syncData.statusText; - var statusSet = syncData.statusText.length != 0; - $('sync-overview').hidden = - statusSet || - (cr.isChromeOS && UIAccountTweaks.loggedInAsPublicAccount()); - $('sync-status').hidden = !statusSet; - - $('sync-action-link').textContent = syncData.actionLinkText; - // Don't show the action link if it is empty or undefined. - $('sync-action-link').hidden = syncData.actionLinkText.length == 0; - $('sync-action-link').disabled = syncData.managed || - !syncData.syncSystemEnabled; - - $('sync-action-link').onclick = function(event) { - switch (syncData.statusAction) { - case 'reauthenticate': - SyncSetupOverlay.startSignIn(false /* creatingSupervisedUser */); - break; - case 'signOutAndSignIn': -// <if expr="chromeos"> - // On Chrome OS, sign out the user and sign in again to get fresh - // credentials on auth errors. - SyncSetupOverlay.doSignOutOnAuthError(); -// </if> -// <if expr="not chromeos"> - if (syncData.signoutAllowed) { - // Silently sign the user out without deleting their profile and - // prompt them to sign back in. - chrome.send('SyncSetupStopSyncing', [false /* deleteProfile */]); - SyncSetupOverlay.startSignIn(false /* creatingSupervisedUser */); - } else { - chrome.send('showDisconnectManagedProfileDialog'); - } -// </if> - break; - case 'upgradeClient': - PageManager.showPageByName('help'); - break; - default: - SyncSetupOverlay.showSetupUI(); - } - }; - - if (syncData.hasError) - $('sync-status').classList.add('sync-error'); - else - $('sync-status').classList.remove('sync-error'); - - // Disable the "customize / set up sync" button if sync has an - // unrecoverable error. Also disable the button if sync has not been set - // up and the user is being presented with a link to re-auth. - // See crbug.com/289791. - customizeSyncButton.disabled = - syncData.hasUnrecoverableError || - (!syncData.setupCompleted && !$('sync-action-link').hidden); - }, - - /** - * Update the UI depending on whether Easy Unlock is enabled for the current - * profile. - * @param {boolean} isEnabled True if the feature is enabled for the current - * profile. - */ - updateEasyUnlock_: function(isEnabled) { - $('easy-unlock-disabled').hidden = isEnabled; - $('easy-unlock-enabled').hidden = !isEnabled; - if (!isEnabled && EasyUnlockTurnOffOverlay.getInstance().visible) { - EasyUnlockTurnOffOverlay.dismiss(); - } - }, - - /** - * Update the UI depending on whether the current profile manages any - * supervised users. - * @param {boolean} show True if the current profile manages any supervised - * users. - */ - updateManagesSupervisedUsers_: function(show) { - $('profiles-supervised-dashboard-tip').hidden = !show; - this.maybeShowUserSection_(); - }, - - /** - * Get the start/stop sync button DOM element. Used for testing. - * @return {Element} The start/stop sync button. - * @private - */ - getStartStopSyncButton_: function() { - return $('start-stop-sync'); - }, - - /** - * Event listener for the 'show home button' preference. Shows/hides the - * UI for changing the home page with animation, unless this is the first - * time this function is called, in which case there is no animation. - * @param {Event} event The preference change event. - */ - onShowHomeButtonChanged_: function(event) { - var section = $('change-home-page-section'); - if (this.onShowHomeButtonChangedCalled_) { - var container = $('change-home-page-section-container'); - if (event.value.value) - this.showSectionWithAnimation_(section, container); - else - this.hideSectionWithAnimation_(section, container); - } else { - section.hidden = !event.value.value; - this.onShowHomeButtonChangedCalled_ = true; - } - }, - - /** - * Activates the Hotword section from the System settings page. - * @param {string} sectionId The id of the section to display. - * @param {string} indicatorId The id of the indicator to display. - * @param {string=} opt_error The error message to display. - * @private - */ - showHotwordCheckboxAndIndicator_: function(sectionId, indicatorId, - opt_error) { - $(sectionId).hidden = false; - $(indicatorId).setError(opt_error); - if (opt_error) - $(indicatorId).updateBasedOnError(); - }, - - /** - * Activates the Hotword section from the System settings page. - * @param {string=} opt_error The error message to display. - * @private - */ - showHotwordSection_: function(opt_error) { - this.showHotwordCheckboxAndIndicator_( - 'hotword-search', - 'hotword-search-setting-indicator', - opt_error); - }, - - /** - * Activates the Always-On Hotword sections from the - * System settings page. - * @param {string=} opt_error The error message to display. - * @private - */ - showHotwordAlwaysOnSection_: function(opt_error) { - this.showHotwordCheckboxAndIndicator_( - 'hotword-always-on-search', - 'hotword-always-on-search-setting-indicator', - opt_error); - }, - - /** - * Activates the Hotword section on devices with no DSP - * from the System settings page. - * @param {string=} opt_error The error message to display. - * @private - */ - showHotwordNoDspSection_: function(opt_error) { - this.showHotwordCheckboxAndIndicator_( - 'hotword-no-dsp-search', - 'hotword-no-dsp-search-setting-indicator', - opt_error); - }, - - /** - * Controls the visibility of all the hotword sections. - * @param {boolean} visible Whether to show hotword sections. - * @private - */ - setAllHotwordSectionsVisible_: function(visible) { - $('hotword-search').hidden = !visible; - $('hotword-always-on-search').hidden = !visible; - $('hotword-no-dsp-search').hidden = !visible; - $('audio-history').hidden = !visible; - }, - - /** - * Shows or hides the hotword retrain link - * @param {boolean} visible Whether to show the link. - * @private - */ - setHotwordRetrainLinkVisible_: function(visible) { - $('hotword-retrain-link').hidden = !visible; - }, - - /** - * Event listener for the 'hotword always on search enabled' preference. - * Updates the visibility of the 'retrain' link. - * @param {Event} event The preference change event. - * @private - */ - onHotwordAlwaysOnChanged_: function(event) { - this.setHotwordRetrainLinkVisible_(event.value.value); - }, - - /** - * Controls the visibility of the Now settings. - * @param {boolean} visible Whether to show Now settings. - * @private - */ - setNowSectionVisible_: function(visible) { - $('google-now-launcher').hidden = !visible; - }, - - /** - * Activates the Audio History section of the Settings page. - * @param {boolean} visible Whether the audio history section is visible. - * @param {string} labelText Text describing current audio history state. - * @private - */ - setAudioHistorySectionVisible_: function(visible, labelText) { - $('audio-history').hidden = !visible; - $('audio-history-label').textContent = labelText; - }, - - /** - * Event listener for the 'homepage is NTP' preference. Updates the label - * next to the 'Change' button. - * @param {Event} event The preference change event. - */ - onHomePageIsNtpChanged_: function(event) { - if (!event.value.uncommitted) { - $('home-page-url').hidden = event.value.value; - $('home-page-ntp').hidden = !event.value.value; - } - }, - - /** - * Event listener for changes to the homepage preference. Updates the label - * next to the 'Change' button. - * @param {Event} event The preference change event. - */ - onHomePageChanged_: function(event) { - if (!event.value.uncommitted) - $('home-page-url').textContent = this.stripHttp_(event.value.value); - }, - - /** - * Removes the 'http://' from a URL, like the omnibox does. If the string - * doesn't start with 'http://' it is returned unchanged. - * @param {string} url The url to be processed - * @return {string} The url with the 'http://' removed. - */ - stripHttp_: function(url) { - return url.replace(/^http:\/\//, ''); - }, - - /** - * Called when the value of the download.default_directory preference - * changes. - * @param {Event} event Change event. - * @private - */ - onDefaultDownloadDirectoryChanged_: function(event) { - $('downloadLocationPath').value = event.value.value; - if (cr.isChromeOS) { - // On ChromeOS, replace /special/drive-<hash>/root with "Google Drive" - // for remote files, /home/chronos/user/Downloads or - // /home/chronos/u-<hash>/Downloads with "Downloads" for local paths, - // and '/' with ' \u203a ' (angled quote sign) everywhere. The modified - // path is used only for display purpose. - var path = $('downloadLocationPath').value; - path = path.replace(/^\/special\/drive[^\/]*\/root/, 'Google Drive'); - path = path.replace(/^\/home\/chronos\/(user|u-[^\/]*)\//, ''); - path = path.replace(/\//g, ' \u203a '); - $('downloadLocationPath').value = path; - } - $('download-location-label').classList.toggle('disabled', - event.value.disabled); - $('downloadLocationChangeButton').disabled = event.value.disabled; - }, - - /** - * Update the Default Browsers section based on the current state. - * @param {string} statusString Description of the current default state. - * @param {boolean} isDefault Whether or not the browser is currently - * default. - * @param {boolean} canBeDefault Whether or not the browser can be default. - * @private - */ - updateDefaultBrowserState_: function(statusString, isDefault, - canBeDefault) { - if (!cr.isChromeOS) { - var label = $('default-browser-state'); - label.textContent = statusString; - - $('set-as-default-browser').hidden = !canBeDefault || isDefault; - } - }, - - /** - * Clears the search engine popup. - * @private - */ - clearSearchEngines_: function() { - $('default-search-engine').textContent = ''; - }, - - /** - * Updates the search engine popup with the given entries. - * @param {Array} engines List of available search engines. - * @param {number} defaultValue The value of the current default engine. - * @param {boolean} defaultManaged Whether the default search provider is - * managed. If true, the default search provider can't be changed. - * @private - */ - updateSearchEngines_: function(engines, defaultValue, defaultManaged) { - this.clearSearchEngines_(); - var engineSelect = $('default-search-engine'); - engineSelect.disabled = defaultManaged; - if (defaultManaged && defaultValue == -1) - return; - var engineCount = engines.length; - var defaultIndex = -1; - for (var i = 0; i < engineCount; i++) { - var engine = engines[i]; - var option = new Option(engine.name, engine.index); - if (defaultValue == option.value) - defaultIndex = i; - engineSelect.appendChild(option); - } - if (defaultIndex >= 0) - engineSelect.selectedIndex = defaultIndex; - }, - - /** - * Set the default search engine based on the popup selection. - * @private - */ - setDefaultSearchEngine_: function() { - var engineSelect = $('default-search-engine'); - var selectedIndex = engineSelect.selectedIndex; - if (selectedIndex >= 0) { - var selection = engineSelect.options[selectedIndex]; - chrome.send('setDefaultSearchEngine', [String(selection.value)]); - } - }, - - /** - * Get the selected profile item from the profile list. This also works - * correctly if the list is not displayed. - * @return {?Object} The profile item object, or null if nothing is - * selected. - * @private - */ - getSelectedProfileItem_: function() { - var profilesList = $('profiles-list'); - if (profilesList.hidden) { - if (profilesList.dataModel.length > 0) - return profilesList.dataModel.item(0); - } else { - return profilesList.selectedItem; - } - return null; - }, - - /** - * Helper function to set the status of profile view buttons to disabled or - * enabled, depending on the number of profiles and selection status of the - * profiles list. - * @private - */ - setProfileViewButtonsStatus_: function() { - var profilesList = $('profiles-list'); - var selectedProfile = profilesList.selectedItem; - var hasSelection = selectedProfile != null; - var hasSingleProfile = profilesList.dataModel.length == 1; - $('profiles-manage').disabled = !hasSelection || - !selectedProfile.isCurrentProfile; - if (hasSelection && !selectedProfile.isCurrentProfile) - $('profiles-manage').title = loadTimeData.getString('currentUserOnly'); - else - $('profiles-manage').title = ''; - $('profiles-delete').disabled = !profilesList.canDeleteItems || - !hasSelection; - var importData = $('import-data'); - if (importData) { - importData.disabled = $('import-data').disabled = hasSelection && - !selectedProfile.isCurrentProfile; - } - }, - - /** - * Display the correct dialog layout, depending on how many profiles are - * available. - * @param {number} numProfiles The number of profiles to display. - * @private - */ - setProfileViewSingle_: function(numProfiles) { - // Always show the profiles list when using the new Profiles UI. - var usingNewProfilesUI = loadTimeData.getBoolean('usingNewProfilesUI'); - var showSingleProfileView = !usingNewProfilesUI && numProfiles == 1; - $('profiles-list').hidden = showSingleProfileView; - $('profiles-single-message').hidden = !showSingleProfileView; - $('profiles-manage').hidden = showSingleProfileView; - $('profiles-delete').textContent = showSingleProfileView ? - loadTimeData.getString('profilesDeleteSingle') : - loadTimeData.getString('profilesDelete'); - }, - - /** - * Adds all |profiles| to the list. - * @param {!Array<!options.Profile>} profiles An array of profile info - * objects. - * @private - */ - setProfilesInfo_: function(profiles) { - this.setProfileViewSingle_(profiles.length); - // add it to the list, even if the list is hidden so we can access it - // later. - $('profiles-list').dataModel = new ArrayDataModel(profiles); - - // Received new data. If showing the "manage" overlay, keep it up to - // date. If showing the "delete" overlay, close it. - if (ManageProfileOverlay.getInstance().visible && - !$('manage-profile-overlay-manage').hidden) { - ManageProfileOverlay.showManageDialog(false); - } else { - ManageProfileOverlay.getInstance().visible = false; - } - - this.setProfileViewButtonsStatus_(); - }, - - /** - * Reports supervised user import errors to the SupervisedUserImportOverlay. - * @param {string} error The error message to display. - * @private - */ - showSupervisedUserImportError_: function(error) { - SupervisedUserImportOverlay.onError(error); - }, - - /** - * Reports successful importing of a supervised user to - * the SupervisedUserImportOverlay. - * @private - */ - showSupervisedUserImportSuccess_: function() { - SupervisedUserImportOverlay.onSuccess(); - }, - - /** - * Reports an error to the "create" overlay during profile creation. - * @param {string} error The error message to display. - * @private - */ - showCreateProfileError_: function(error) { - CreateProfileOverlay.onError(error); - }, - - /** - * Sends a warning message to the "create" overlay during profile creation. - * @param {string} warning The warning message to display. - * @private - */ - showCreateProfileWarning_: function(warning) { - CreateProfileOverlay.onWarning(warning); - }, - - /** - * Reports successful profile creation to the "create" overlay. - * @param {options.Profile} profileInfo An object of the form: - * profileInfo = { - * name: "Profile Name", - * filePath: "/path/to/profile/data/on/disk" - * isSupervised: (true|false), - * }; - * @private - */ - showCreateProfileSuccess_: function(profileInfo) { - CreateProfileOverlay.onSuccess(profileInfo); - }, - - /** - * Returns the currently active profile for this browser window. - * @return {options.Profile} A profile info object. - * @private - */ - getCurrentProfile_: function() { - for (var i = 0; i < $('profiles-list').dataModel.length; i++) { - var profile = $('profiles-list').dataModel.item(i); - if (profile.isCurrentProfile) - return profile; - } - - assertNotReached('There should always be a current profile.'); - }, - - /** - * Propmpts user to confirm deletion of the profile for this browser - * window. - * @private - */ - deleteCurrentProfile_: function() { - ManageProfileOverlay.showDeleteDialog(this.getCurrentProfile_()); - }, - - /** - * @param {boolean} enabled - */ - setNativeThemeButtonEnabled_: function(enabled) { - var button = $('themes-native-button'); - if (button) - button.disabled = !enabled; - }, - - /** - * @param {boolean} enabled - */ - setThemesResetButtonEnabled_: function(enabled) { - $('themes-reset').disabled = !enabled; - }, - - /** - * @param {boolean} managed - */ - setAccountPictureManaged_: function(managed) { - var picture = $('account-picture'); - if (managed || UIAccountTweaks.loggedInAsGuest()) { - picture.disabled = true; - ChangePictureOptions.closeOverlay(); - } else { - picture.disabled = false; - } - - // Create a synthetic pref change event decorated as - // CoreOptionsHandler::CreateValueForPref() does. - var event = new Event('account-picture'); - if (managed) - event.value = { controlledBy: 'policy' }; - else - event.value = {}; - $('account-picture-indicator').handlePrefChange(event); - }, - - /** - * (Re)loads IMG element with current user account picture. - * @private - */ - updateAccountPicture_: function() { - var picture = $('account-picture'); - if (picture) { - picture.src = 'chrome://userimage/' + this.username_ + '?id=' + - Date.now(); - } - }, - - /** - * @param {boolean} managed - */ - setWallpaperManaged_: function(managed) { - if (managed) - $('set-wallpaper').disabled = true; - else - this.enableElementIfPossible_(getRequiredElement('set-wallpaper')); - - // Create a synthetic pref change event decorated as - // CoreOptionsHandler::CreateValueForPref() does. - var event = new Event('wallpaper'); - event.value = managed ? { controlledBy: 'policy' } : {}; - $('wallpaper-indicator').handlePrefChange(event); - }, - - /** - * This enables or disables dependent settings in timezone section. - * @private - */ - updateTimezoneSectionState_: function() { - var self = this; - $('resolve-timezone-by-geolocation') - .onclick = function(event) { - self.resolveTimezoneByGeolocation_ = event.currentTarget.checked; - }; - if (this.systemTimezoneIsManaged_) { - $('resolve-timezone-by-geolocation').disabled = true; - $('resolve-timezone-by-geolocation').checked = false; - } else if (this.systemTimezoneAutomaticDetectionIsManaged_) { - if (this.systemTimezoneAutomaticDetectionValue_ == - options.AutomaticTimezoneDetectionType.USERS_DECIDE) { - $('resolve-timezone-by-geolocation').disabled = false; - $('resolve-timezone-by-geolocation') - .checked = this.resolveTimezoneByGeolocation_; - $('timezone-value-select') - .disabled = this.resolveTimezoneByGeolocation_; - } else { - $('resolve-timezone-by-geolocation').disabled = true; - $('resolve-timezone-by-geolocation') - .checked = - (this.systemTimezoneAutomaticDetectionValue_ != - options.AutomaticTimezoneDetectionType.DISABLED); - $('timezone-value-select').disabled = true; - } - } else { - this.enableElementIfPossible_( - getRequiredElement('resolve-timezone-by-geolocation')); - $('timezone-value-select').disabled = - this.resolveTimezoneByGeolocation_; - $('resolve-timezone-by-geolocation') - .checked = this.resolveTimezoneByGeolocation_; - } - }, - - /** - * Called when stylus hardware detection probing is complete. - * @param {boolean} hasStylus - * @private - */ - setStylusInputStatus_: function(hasStylus) { - if (!hasStylus) - return; - - $('stylus-settings-link').onclick = function(event) { - PageManager.showPageByName('stylus-overlay'); - }; - $('stylus-row').hidden = false; - }, - - /** - * This is called from chromium code when system timezone "managed" state - * is changed. Enables or disables dependent settings. - * @param {boolean} managed Is true when system Timezone is managed by - * enterprise policy. False otherwize. - */ - setSystemTimezoneManaged_: function(managed) { - this.systemTimezoneIsManaged_ = managed; - this.updateTimezoneSectionState_(); - }, - - /** - * This is called from chromium code when system timezone detection - * "managed" state is changed. Enables or disables dependent settings. - * @param {boolean} managed Is true when system timezone autodetection is - * managed by enterprise policy. False otherwize. - * @param {options.AutomaticTimezoneDetectionType} value Current value of - * SystemTimezoneAutomaticDetection device policy. - */ - setSystemTimezoneAutomaticDetectionManaged_: function(managed, value) { - this.systemTimezoneAutomaticDetectionIsManaged_ = managed; - this.systemTimezoneAutomaticDetectionValue_ = value; - this.updateTimezoneSectionState_(); - }, - - /** - * This is Preferences event listener, which is called when - * kResolveTimezoneByGeolocation preference is changed. - * Enables or disables dependent settings. - * @param {Event} value New preference state. - */ - onResolveTimezoneByGeolocationChanged_: function(value) { - this.resolveTimezoneByGeolocation_ = value.value.value; - this.updateTimezoneSectionState_(); - }, - - /** - * Handle the 'add device' button click. - * @private - */ - handleAddBluetoothDevice_: function() { - chrome.send('coreOptionsUserMetricsAction', - ['Options_BluetoothShowAddDevice']); - PageManager.showPageByName('bluetooth', false); - }, - - /** - * Enables or disables the Manage SSL Certificates button. - * @private - */ - enableCertificateButton_: function(enabled) { - $('certificatesManageButton').disabled = !enabled; - }, - - /** - * Enables or disables the Chrome OS display settings button and overlay. - * @param {boolean} uiEnabled - * @param {boolean} unifiedEnabled - * @param {boolean} mirroredEnabled - * @private - */ - enableDisplaySettings_: function( - uiEnabled, unifiedEnabled, mirroredEnabled) { - if (cr.isChromeOS) { - $('display-options').disabled = !uiEnabled; - DisplayOptions.getInstance().setEnabled( - uiEnabled, unifiedEnabled, mirroredEnabled); - } - }, - - /** - * Enables factory reset section. - * @private - */ - enableFactoryResetSection_: function() { - $('factory-reset-section').hidden = false; - }, - - /** - * Set the checked state of the metrics reporting checkbox. - * @private - */ - setMetricsReportingCheckboxState_: function(checked, - policyManaged, - ownerManaged) { - $('metrics-reporting-enabled').checked = checked; - $('metrics-reporting-enabled').disabled = policyManaged || ownerManaged; - - // If checkbox gets disabled then add an attribute for displaying the - // special icon. Otherwise remove the indicator attribute. - if (policyManaged) { - $('metrics-reporting-disabled-icon').setAttribute('controlled-by', - 'policy'); - } else if (ownerManaged) { - $('metrics-reporting-disabled-icon').setAttribute('controlled-by', - 'owner'); - } else { - $('metrics-reporting-disabled-icon').removeAttribute('controlled-by'); - } - - }, - - /** - * @private - */ - setMetricsReportingSettingVisibility_: function(visible) { - if (visible) - $('metrics-reporting-setting').style.display = 'block'; - else - $('metrics-reporting-setting').style.display = 'none'; - }, - - /** - * Set the checked state of the Safe Browsing Extended Reporting Enabled - * checkbox. - * @private - */ - setExtendedReportingEnabledCheckboxState_: function(checked) { - $('safeBrowsingExtendedReportingCheckbox').checked = checked; - }, - - /** - * Set network prediction checkbox value. - * - * @param {{value: number, disabled: boolean}} pref Information about - * network prediction options. |pref.value| is the value of network - * prediction options. |pref.disabled| shows if the pref is not user - * modifiable. - * @private - */ - setNetworkPredictionValue_: function(pref) { - var checkbox = $('networkPredictionOptions'); - checkbox.disabled = pref.disabled || - loadTimeData.getBoolean('profileIsGuest'); - checkbox.checked = (pref.value != NetworkPredictionOptions.NEVER); - }, - - /** - * Set the font size selected item. This item actually reflects two - * preferences: the default font size and the default fixed font size. - * - * @param {{value: number, disabled: boolean, controlledBy: string}} pref - * Information about the font size preferences. |pref.value| is the - * value of the default font size pref. |pref.disabled| is true if - * either pref not user modifiable. |pref.controlledBy| is the source of - * the pref value(s) if either pref is currently not controlled by the - * user. - * @private - */ - setFontSize_: function(pref) { - var selectCtl = /** @type {HTMLSelectElement} */($('defaultFontSize')); - selectCtl.disabled = pref.disabled; - // Create a synthetic pref change event decorated as - // CoreOptionsHandler::CreateValueForPref() does. - var event = new Event('synthetic-font-size'); - event.value = { - value: pref.value, - controlledBy: pref.controlledBy, - disabled: pref.disabled - }; - $('font-size-indicator').handlePrefChange(event); - - for (var i = 0; i < selectCtl.options.length; i++) { - if (selectCtl.options[i].value == pref.value) { - selectCtl.selectedIndex = i; - if ($('Custom')) - selectCtl.remove($('Custom').index); - return; - } - } - - // Add/Select Custom Option in the font size label list. - if (!$('Custom')) { - var option = new Option(loadTimeData.getString('fontSizeLabelCustom'), - -1, false, true); - option.setAttribute('id', 'Custom'); - selectCtl.add(option); - } - $('Custom').selected = true; - }, - - /** - * Populate the page zoom selector with values received from the caller. - * @param {Array} items An array of items to populate the selector. - * each object is an array with three elements as follows: - * 0: The title of the item (string). - * 1: The value of the item (number). - * 2: Whether the item should be selected (boolean). - * @private - */ - setupPageZoomSelector_: function(items) { - var element = $('defaultZoomFactor'); - - // Remove any existing content. - element.textContent = ''; - - // Insert new child nodes into select element. - var value, title, selected; - for (var i = 0; i < items.length; i++) { - title = items[i][0]; - value = items[i][1]; - selected = items[i][2]; - element.appendChild(new Option(title, value, false, selected)); - } - }, - - /** - * Shows/hides the autoOpenFileTypesResetToDefault button and label, with - * animation. - * @param {boolean} display Whether to show the button and label or not. - * @private - */ - setAutoOpenFileTypesDisplayed_: function(display) { - if ($('advanced-settings').hidden) { - // If the Advanced section is hidden, don't animate the transition. - $('auto-open-file-types-section').hidden = !display; - } else { - if (display) { - this.showSectionWithAnimation_( - $('auto-open-file-types-section'), - $('auto-open-file-types-container')); - } else { - this.hideSectionWithAnimation_( - $('auto-open-file-types-section'), - $('auto-open-file-types-container')); - } - } - }, - - /** - * Set the enabled state for the proxy settings button and its associated - * message when extension controlled. - * @param {boolean} disabled Whether the button should be disabled. - * @param {boolean} extensionControlled Whether the proxy is extension - * controlled. - * @private - */ - setupProxySettingsButton_: function(disabled, extensionControlled) { - if (!cr.isChromeOS) { - $('proxiesConfigureButton').disabled = disabled; - $('proxiesLabel').textContent = - loadTimeData.getString(extensionControlled ? - 'proxiesLabelExtension' : 'proxiesLabelSystem'); - } - }, - - /** - * Set the initial state of the spoken feedback checkbox. - * @private - */ - setSpokenFeedbackCheckboxState_: function(checked) { - $('accessibility-spoken-feedback-check').checked = checked; - }, - - /** - * Set the initial state of the high contrast checkbox. - * @private - */ - setHighContrastCheckboxState_: function(checked) { - $('accessibility-high-contrast-check').checked = checked; - }, - - /** - * Set the initial state of the virtual keyboard checkbox. - * @private - */ - setVirtualKeyboardCheckboxState_: function(checked) { - // TODO(zork): Update UI - }, - - /** - * Show/hide mouse settings slider. - * @private - */ - showMouseControls_: function(show) { - $('mouse-settings').hidden = !show; - }, - - /** - * Adds hidden warning boxes for settings potentially controlled by - * extensions. - * @param {string} parentDiv The div name to append the bubble to. - * @param {string} bubbleId The ID to use for the bubble. - * @param {boolean} first Add as first node if true, otherwise last. - * @private - */ - addExtensionControlledBox_: function(parentDiv, bubbleId, first) { - var bubble = $('extension-controlled-warning-template').cloneNode(true); - bubble.id = bubbleId; - var parent = $(parentDiv); - if (first) - parent.insertBefore(bubble, parent.firstChild); - else - parent.appendChild(bubble); - }, - - /** - * Adds a bubble showing that an extension is controlling a particular - * setting. - * @param {string} parentDiv The div name to append the bubble to. - * @param {string} bubbleId The ID to use for the bubble. - * @param {string} extensionId The ID of the controlling extension. - * @param {string} extensionName The name of the controlling extension. - * @private - */ - toggleExtensionControlledBox_: function( - parentDiv, bubbleId, extensionId, extensionName) { - var bubble = $(bubbleId); - assert(bubble); - bubble.hidden = extensionId.length == 0; - if (bubble.hidden) - return; - - // Set the extension image. - var div = bubble.firstElementChild; - div.style.backgroundImage = - 'url(chrome://extension-icon/' + extensionId + '/24/1)'; - - // Set the bubble label. - var label = loadTimeData.getStringF('extensionControlled', extensionName); - var docFrag = parseHtmlSubset('<div>' + label + '</div>', ['B', 'DIV']); - div.innerHTML = docFrag.firstChild.innerHTML; - - // Wire up the button to disable the right extension. - var button = div.nextElementSibling; - button.dataset.extensionId = extensionId; - }, - - /** - * Toggles the warning boxes that show which extension is controlling - * various settings of Chrome. - * @param {{searchEngine: options.ExtensionData, - * homePage: options.ExtensionData, - * startUpPage: options.ExtensionData, - * newTabPage: options.ExtensionData, - * proxy: options.ExtensionData}} details A dictionary of ID+name - * pairs for each of the settings controlled by an extension. - * @private - */ - toggleExtensionIndicators_: function(details) { - this.toggleExtensionControlledBox_('search-section-content', - 'search-engine-controlled', - details.searchEngine.id, - details.searchEngine.name); - this.toggleExtensionControlledBox_('extension-controlled-container', - 'homepage-controlled', - details.homePage.id, - details.homePage.name); - this.toggleExtensionControlledBox_('startup-section-content', - 'startpage-controlled', - details.startUpPage.id, - details.startUpPage.name); - this.toggleExtensionControlledBox_('newtab-section-content', - 'newtab-controlled', - details.newTabPage.id, - details.newTabPage.name); - this.toggleExtensionControlledBox_('proxy-section-content', - 'proxy-controlled', - details.proxy.id, - details.proxy.name); - - // The proxy section contains just the warning box and nothing else, so - // if we're hiding the proxy warning box, we should also hide its header - // section. - $('proxy-section').hidden = details.proxy.id.length == 0; - }, - - - /** - * Show/hide touchpad-related settings. - * @private - */ - showTouchpadControls_: function(show) { - $('touchpad-settings').hidden = !show; - $('accessibility-tap-dragging').hidden = !show; - }, - - /** - * Sets the state of the checkbox indicating if Bluetooth is turned on. The - * state of the "Find devices" button and the list of discovered devices may - * also be affected by a change to the state. - * @param {boolean} checked Flag Indicating if Bluetooth is turned on. - * @private - */ - setBluetoothState_: function(checked) { - $('enable-bluetooth').checked = checked; - $('bluetooth-paired-devices-list').parentNode.hidden = !checked; - $('bluetooth-add-device').hidden = !checked; - $('bluetooth-reconnect-device').hidden = !checked; - }, - - /** - * Process a bluetooth.onAdapterStateChanged event. - * @param {!chrome.bluetooth.AdapterState} state - * @private - */ - onBluetoothAdapterStateChanged_: function(state) { - var disallowBluetooth = !loadTimeData.getBoolean('allowBluetooth'); - // If allowBluetooth is false, state.available will always be false, so - // assume Bluetooth is available but disabled by policy. - if (!state || (!state.available && !disallowBluetooth)) { - this.bluetoothAdapterState_ = null; - $('bluetooth-devices').hidden = true; - return; - } - $('bluetooth-devices').hidden = false; - this.bluetoothAdapterState_ = state; - this.setBluetoothState_(state.powered); - - var enableBluetoothEl = $('enable-bluetooth'); - if (disallowBluetooth) { - enableBluetoothEl.setAttribute('pref', 'cros.device.allow_bluetooth'); - enableBluetoothEl.setAttribute('controlled-by', 'policy'); - enableBluetoothEl.disabled = true; - $('bluetooth-controlled-setting-indicator').hidden = false; - return; - } - enableBluetoothEl.removeAttribute('pref'); - enableBluetoothEl.removeAttribute('controlled-by'); - enableBluetoothEl.disabled = false; - $('bluetooth-controlled-setting-indicator').hidden = true; - - // Flush the device lists. - $('bluetooth-paired-devices-list').clear(); - $('bluetooth-unpaired-devices-list').clear(); - if (state.powered) { - options.BluetoothOptions.updateDiscoveryState(state.discovering); - // Update the device lists. - chrome.bluetooth.getDevices(function(devices) { - for (var device of devices) - this.updateBluetoothDevicesList_(device); - }.bind(this)); - } else { - options.BluetoothOptions.dismissOverlay(); - } - }, - - /** - * Process a bluetooth.onDeviceAdded or onDeviceChanged event and update the - * device list. - * @param {!chrome.bluetooth.Device} device - * @private - */ - onBluetoothDeviceAddedOrChanged_: function(device) { - this.updateBluetoothDevicesList_(device); - }, - - /** - * Process a bluetooth.onDeviceRemoved event and update the device list. - * @param {!chrome.bluetooth.Device} device - * @private - */ - onBluetoothDeviceRemoved_: function(device) { - this.removeBluetoothDevice_(device.address); - }, - - /** - * Process a bluetoothPrivate onPairing event and update the device list. - * @param {!chrome.bluetoothPrivate.PairingEvent} pairing_event - * @private - */ - onBluetoothPrivatePairing_: function(pairing_event) { - this.updateBluetoothDevicesList_(pairing_event.device); - BluetoothPairing.onBluetoothPairingEvent(pairing_event); - }, - - /** - * Add |device| to the appropriate list of Bluetooth devices. - * @param {!chrome.bluetooth.Device} device - * @private - */ - addBluetoothDeviceToList_: function(device) { - // Display the "connecting" (already paired or not yet paired) and the - // paired devices in the same list. - if (device.paired || device.connecting) - $('bluetooth-paired-devices-list').appendDevice(device); - else - $('bluetooth-unpaired-devices-list').appendDevice(device); - }, - - /** - * Add |device| to the appropriate list of Bluetooth devices or update the - * entry if a device with a matching |address| property exists. - * @param {!chrome.bluetooth.Device} device - * @private - */ - updateBluetoothDevicesList_: function(device) { - // Display the "connecting" (already paired or not yet paired) and the - // paired devices in the same list. - if (device.paired || device.connecting) { - // Test to see if the device is currently in the unpaired list, in which - // case it should be removed from that list. - var index = $('bluetooth-unpaired-devices-list').find(device.address); - if (index != undefined) - $('bluetooth-unpaired-devices-list').deleteItemAtIndex(index); - } else { - // Test to see if the device is currently in the paired list, in which - // case it should be removed from that list. - var index = $('bluetooth-paired-devices-list').find(device.address); - if (index != undefined) - $('bluetooth-paired-devices-list').deleteItemAtIndex(index); - } - this.addBluetoothDeviceToList_(device); - }, - - /** - * Removes an element from the list of available devices. - * @param {string} address Unique address of the device. - * @private - */ - removeBluetoothDevice_: function(address) { - var index = $('bluetooth-unpaired-devices-list').find(address); - if (index != undefined) { - $('bluetooth-unpaired-devices-list').deleteItemAtIndex(index); - } else { - index = $('bluetooth-paired-devices-list').find(address); - if (index != undefined) - $('bluetooth-paired-devices-list').deleteItemAtIndex(index); - } - }, - - /** - * Shows the overlay dialog for changing the user avatar image. - * @private - */ - showImagerPickerOverlay_: function() { - PageManager.showPageByName('changePicture'); - }, - - /** - * Shows (or not) the "User" section of the settings page based on whether - * any of the sub-sections are present (or not). - * @private - */ - maybeShowUserSection_: function() { - $('sync-users-section').hidden = - $('profiles-section').hidden && - $('sync-section').hidden && - $('profiles-supervised-dashboard-tip').hidden; - }, - - /** - * Updates the date and time section with time sync information. - * @param {boolean} canSetTime Whether the system time can be set. - * @private - */ - setCanSetTime_: function(canSetTime) { - // If the time has been network-synced, it cannot be set manually. - $('set-time').hidden = !canSetTime; - }, - - /** - * Handle the 'set date and time' button click. - * @private - */ - handleSetTime_: function() { - chrome.send('showSetTime'); - }, - - /** - * Enables the given element if possible; on Chrome OS, it won't enable - * an element that must stay disabled for the session type. - * @param {!Element} element Element to enable. - */ - enableElementIfPossible_: function(element) { - if (cr.isChromeOS) - UIAccountTweaks.enableElementIfPossible(element); - else - element.disabled = false; - }, - }; - - // Forward public APIs to private implementations. - cr.makePublic(BrowserOptions, [ - 'deleteCurrentProfile', - 'enableCertificateButton', - 'enableDisplaySettings', - 'enableFactoryResetSection', - 'getCurrentProfile', - 'getStartStopSyncButton', - 'notifyInitializationComplete', - 'removeBluetoothDevice', - 'scrollToSection', - 'setAccountPictureManaged', - 'setAllHotwordSectionsVisible', - 'setAudioHistorySectionVisible', - 'setAutoOpenFileTypesDisplayed', - 'setCanSetTime', - 'setExtendedReportingEnabledCheckboxState', - 'setFontSize', - 'setHighContrastCheckboxState', - 'setHotwordRetrainLinkVisible', - 'setMetricsReportingCheckboxState', - 'setMetricsReportingSettingVisibility', - 'setNativeThemeButtonEnabled', - 'setNetworkPredictionValue', - 'setNowSectionVisible', - 'setProfilesInfo', - 'setSpokenFeedbackCheckboxState', - 'setStylusInputStatus', - 'setSystemTimezoneAutomaticDetectionManaged', - 'setSystemTimezoneManaged', - 'setThemesResetButtonEnabled', - 'setVirtualKeyboardCheckboxState', - 'setWallpaperManaged', - 'setupPageZoomSelector', - 'setupProxySettingsButton', - 'showCreateProfileError', - 'showCreateProfileSuccess', - 'showCreateProfileWarning', - 'showHotwordAlwaysOnSection', - 'showHotwordNoDspSection', - 'showHotwordSection', - 'showMouseControls', - 'showSupervisedUserImportError', - 'showSupervisedUserImportSuccess', - 'showTouchpadControls', - 'toggleExtensionIndicators', - 'updateAccountPicture', - 'updateDefaultBrowserState', - 'updateEasyUnlock', - 'updateManagesSupervisedUsers', - 'updateSearchEngines', - 'updateSyncState', - ]); - - if (cr.isChromeOS) { - /** - * Returns username (canonical email) of the user logged in (ChromeOS only). - * @return {string} user email. - */ - // TODO(jhawkins): Investigate the use case for this method. - BrowserOptions.getLoggedInUsername = function() { - return BrowserOptions.getInstance().username_; - }; - - /** - * Shows Android Apps settings when they are available. - * (Chrome OS only). - */ - BrowserOptions.showAndroidAppsSection = function(isArcEnabled) { - var section = $('android-apps-section'); - if (!section) - return; - - section.hidden = false; - }; - - /** - * Shows/hides Android Settings app section. - * (Chrome OS only). - */ - BrowserOptions.setAndroidAppsSettingsVisibility = function(isVisible) { - var settings = $('android-apps-settings'); - if (!settings) - return; - - settings.hidden = !isVisible; - }; - } - - // Export - return { - BrowserOptions: BrowserOptions - }; -});
diff --git a/chrome/browser/resources/options/browser_options_profile_list.js b/chrome/browser/resources/options/browser_options_profile_list.js deleted file mode 100644 index bd23274..0000000 --- a/chrome/browser/resources/options/browser_options_profile_list.js +++ /dev/null
@@ -1,141 +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. - -cr.define('options.browser_options', function() { - /** @const */ var DeletableItem = options.DeletableItem; - /** @const */ var DeletableItemList = options.DeletableItemList; - /** @const */ var ListSingleSelectionModel = cr.ui.ListSingleSelectionModel; - - /** - * Creates a new profile list item. - * @param {Object} profileInfo The profile this item represents. - * @constructor - * @extends {options.DeletableItem} - */ - function ProfileListItem(profileInfo) { - var el = cr.doc.createElement('div'); - el.profileInfo_ = profileInfo; - ProfileListItem.decorate(el); - return el; - } - - /** - * Decorates an element as a profile list item. - * @param {!HTMLElement} el The element to decorate. - */ - ProfileListItem.decorate = function(el) { - el.__proto__ = ProfileListItem.prototype; - el.decorate(); - }; - - ProfileListItem.prototype = { - __proto__: DeletableItem.prototype, - - /** - * @type {string} the file path of this profile list item. - */ - get profilePath() { - return this.profileInfo_.filePath; - }, - - /** @override */ - decorate: function() { - DeletableItem.prototype.decorate.call(this); - - var profileInfo = this.profileInfo_; - - var containerEl = this.ownerDocument.createElement('div'); - containerEl.className = 'profile-container'; - - var iconEl = this.ownerDocument.createElement('img'); - iconEl.className = 'profile-img'; - iconEl.style.content = cr.icon.getImage(profileInfo.iconURL); - iconEl.alt = ''; - containerEl.appendChild(iconEl); - - var nameEl = this.ownerDocument.createElement('div'); - nameEl.className = 'profile-name'; - if (profileInfo.isCurrentProfile) - nameEl.classList.add('profile-item-current'); - containerEl.appendChild(nameEl); - - var displayName = profileInfo.name; - if (profileInfo.isCurrentProfile) { - displayName = loadTimeData.getStringF('profilesListItemCurrent', - profileInfo.name); - } - nameEl.textContent = displayName; - - if (profileInfo.isSupervised) { - var supervisedEl = this.ownerDocument.createElement('div'); - supervisedEl.className = 'profile-supervised'; - supervisedEl.textContent = profileInfo.isChild ? - loadTimeData.getString('childLabel') : - loadTimeData.getString('supervisedUserLabel'); - containerEl.appendChild(supervisedEl); - } - - this.contentElement.appendChild(containerEl); - - // Ensure that the button cannot be tabbed to for accessibility reasons. - this.closeButtonElement.tabIndex = -1; - }, - }; - - var ProfileList = cr.ui.define('list'); - - ProfileList.prototype = { - __proto__: DeletableItemList.prototype, - - /** @override */ - decorate: function() { - DeletableItemList.prototype.decorate.call(this); - this.selectionModel = new ListSingleSelectionModel(); - }, - - /** @override */ - createItem: function(pageInfo) { - var item = new ProfileListItem(pageInfo); - item.deletable = this.canDeleteItems_; - return item; - }, - - /** @override */ - deleteItemAtIndex: function(index) { - ManageProfileOverlay.showDeleteDialog(this.dataModel.item(index)); - }, - - /** @override */ - activateItemAtIndex: function(index) { - // Don't allow the user to edit a profile that is not current. - var profileInfo = this.dataModel.item(index); - if (profileInfo.isCurrentProfile) - ManageProfileOverlay.showManageDialog(profileInfo); - }, - - /** - * Sets whether items in this list are deletable. - */ - set canDeleteItems(value) { - this.canDeleteItems_ = value; - }, - - /** - * @type {boolean} whether the items in this list are deletable. - */ - get canDeleteItems() { - return this.canDeleteItems_; - }, - - /** - * If false, items in this list will not be deletable. - * @private - */ - canDeleteItems_: true, - }; - - return { - ProfileList: ProfileList - }; -});
diff --git a/chrome/browser/resources/options/browser_options_startup_page_list.js b/chrome/browser/resources/options/browser_options_startup_page_list.js deleted file mode 100644 index 97fae10..0000000 --- a/chrome/browser/resources/options/browser_options_startup_page_list.js +++ /dev/null
@@ -1,321 +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. - -cr.define('options.browser_options', function() { - /** @const */ var AutocompleteList = cr.ui.AutocompleteList; - /** @const */ var InlineEditableItem = options.InlineEditableItem; - /** @const */ var InlineEditableItemList = options.InlineEditableItemList; - - /** - * Creates a new startup page list item. - * @param {Object} pageInfo The page this item represents. - * @constructor - * @extends {options.InlineEditableItem} - */ - function StartupPageListItem(pageInfo) { - var el = cr.doc.createElement('div'); - el.pageInfo_ = pageInfo; - StartupPageListItem.decorate(el); - return el; - } - - /** - * Decorates an element as a startup page list item. - * @param {!HTMLElement} el The element to decorate. - */ - StartupPageListItem.decorate = function(el) { - el.__proto__ = StartupPageListItem.prototype; - el.decorate(); - }; - - StartupPageListItem.prototype = { - __proto__: InlineEditableItem.prototype, - - /** - * Input field for editing the page url. - * @type {HTMLElement} - * @private - */ - urlField_: null, - - /** @override */ - decorate: function() { - InlineEditableItem.prototype.decorate.call(this); - - var pageInfo = this.pageInfo_; - - if (pageInfo.modelIndex == -1) { - this.isPlaceholder = true; - pageInfo.title = loadTimeData.getString('startupAddLabel'); - pageInfo.url = ''; - } - - var titleEl = this.ownerDocument.createElement('div'); - titleEl.className = 'title'; - titleEl.classList.add('favicon-cell'); - titleEl.classList.add('weakrtl'); - titleEl.textContent = pageInfo.title; - if (!this.isPlaceholder) { - titleEl.style.backgroundImage = cr.icon.getFavicon(pageInfo.url); - titleEl.title = pageInfo.tooltip; - } - - this.contentElement.appendChild(titleEl); - - var urlEl = this.createEditableTextCell(pageInfo.url); - urlEl.className = 'url'; - urlEl.classList.add('weakrtl'); - this.contentElement.appendChild(urlEl); - - var urlField = /** @type {HTMLElement} */(urlEl.querySelector('input')); - urlField.className = 'weakrtl'; - urlField.placeholder = loadTimeData.getString('startupPagesPlaceholder'); - this.urlField_ = urlField; - - this.addEventListener('commitedit', this.onEditCommitted_); - - var self = this; - urlField.addEventListener('focus', function(event) { - self.parentNode.autocompleteList.attachToInput(urlField); - }); - urlField.addEventListener('blur', function(event) { - self.parentNode.autocompleteList.detach(); - }); - - if (!this.isPlaceholder) - titleEl.draggable = true; - }, - - /** @override */ - get currentInputIsValid() { - return this.urlField_.validity.valid; - }, - - /** @override */ - get hasBeenEdited() { - return this.urlField_.value != this.pageInfo_.url; - }, - - /** - * Called when committing an edit; updates the model. - * @param {Event} e The end event. - * @private - */ - onEditCommitted_: function(e) { - var url = this.urlField_.value; - if (this.isPlaceholder) - chrome.send('addStartupPage', [url]); - else - chrome.send('editStartupPage', [this.pageInfo_.modelIndex, url]); - }, - }; - - var StartupPageList = cr.ui.define('list'); - - StartupPageList.prototype = { - __proto__: InlineEditableItemList.prototype, - - /** - * An autocomplete suggestion list for URL editing. - * @type {AutocompleteList} - */ - autocompleteList: null, - - /** - * The drop position information: "below" or "above". - */ - dropPos: null, - - /** @override */ - decorate: function() { - InlineEditableItemList.prototype.decorate.call(this); - - // Listen to drag and drop events. - this.addEventListener('dragstart', this.handleDragStart_.bind(this)); - this.addEventListener('dragenter', this.handleDragEnter_.bind(this)); - this.addEventListener('dragover', this.handleDragOver_.bind(this)); - this.addEventListener('drop', this.handleDrop_.bind(this)); - this.addEventListener('dragleave', this.handleDragLeave_.bind(this)); - this.addEventListener('dragend', this.handleDragEnd_.bind(this)); - }, - - /** @override */ - createItem: function(pageInfo) { - var item = new StartupPageListItem(pageInfo); - item.urlField_.disabled = this.disabled; - return item; - }, - - /** @override */ - deleteItemAtIndex: function(index) { - chrome.send('removeStartupPages', [index]); - }, - - /** - * Computes the target item of drop event. - * @param {Event} e The drop or dragover event. - * @private - */ - getTargetFromDropEvent_: function(e) { - var target = e.target; - // e.target may be an inner element of the list item - while (target != null && !(target instanceof StartupPageListItem)) { - target = target.parentNode; - } - return target; - }, - - /** - * Handles the dragstart event. - * @param {Event} e The dragstart event. - * @private - */ - handleDragStart_: function(e) { - // Prevent dragging if the list is disabled. - if (this.disabled) { - e.preventDefault(); - return false; - } - - var target = this.getTargetFromDropEvent_(e); - // StartupPageListItem should be the only draggable element type in the - // page but let's make sure. - if (target instanceof StartupPageListItem) { - this.draggedItem = target; - this.draggedItem.editable = false; - e.dataTransfer.effectAllowed = 'move'; - // We need to put some kind of data in the drag or it will be - // ignored. Use the URL in case the user drags to a text field or the - // desktop. - e.dataTransfer.setData('text/plain', target.urlField_.value); - } - }, - - /** - * Handles the dragenter event. - * @param {Event} e The dragenter event. - * @private - */ - handleDragEnter_: function(e) { - e.preventDefault(); - }, - - /** - * Handles the dragover event. - * @param {Event} e The dragover event. - * @private - */ - handleDragOver_: function(e) { - var dropTarget = this.getTargetFromDropEvent_(e); - // Determines whether the drop target is to accept the drop. - // The drop is only successful on another StartupPageListItem. - if (!(dropTarget instanceof StartupPageListItem) || - dropTarget == this.draggedItem || dropTarget.isPlaceholder) { - this.hideDropMarker_(); - return; - } - // Compute the drop postion. Should we move the dragged item to - // below or above the drop target? - var rect = dropTarget.getBoundingClientRect(); - var dy = e.clientY - rect.top; - var yRatio = dy / rect.height; - var dropPos = yRatio <= .5 ? 'above' : 'below'; - this.dropPos = dropPos; - this.showDropMarker_(dropTarget, dropPos); - e.preventDefault(); - }, - - /** - * Handles the drop event. - * @param {Event} e The drop event. - * @private - */ - handleDrop_: function(e) { - var dropTarget = this.getTargetFromDropEvent_(e); - - if (!(dropTarget instanceof StartupPageListItem) || - dropTarget.pageInfo_.modelIndex == -1) { - return; - } - - this.hideDropMarker_(); - - // Insert the selection at the new position. - var newIndex = this.dataModel.indexOf(dropTarget.pageInfo_); - if (this.dropPos == 'below') - newIndex += 1; - - // If there are selected indexes, it was a re-order. - if (this.selectionModel.selectedIndexes.length > 0) { - chrome.send('dragDropStartupPage', - [newIndex, this.selectionModel.selectedIndexes]); - return; - } - - // Otherwise it was potentially a drop of new data (e.g. a bookmark). - var url = e.dataTransfer.getData('url'); - if (url) { - e.preventDefault(); - chrome.send('addStartupPage', [url, newIndex]); - } - }, - - /** - * Handles the dragleave event. - * @param {Event} e The dragleave event. - * @private - */ - handleDragLeave_: function(e) { - this.hideDropMarker_(); - }, - - /** - * Handles the dragend event. - * @param {Event} e The dragend event. - * @private - */ - handleDragEnd_: function(e) { - this.draggedItem.editable = true; - this.draggedItem.updateEditState(); - }, - - /** - * Shows and positions the marker to indicate the drop target. - * @param {HTMLElement} target The current target list item of drop. - * @param {string} pos 'below' or 'above'. - * @private - */ - showDropMarker_: function(target, pos) { - window.clearTimeout(this.hideDropMarkerTimer_); - var marker = $('startupPagesListDropmarker'); - var rect = target.getBoundingClientRect(); - var markerHeight = 6; - if (pos == 'above') { - marker.style.top = (rect.top - markerHeight / 2) + 'px'; - } else { - marker.style.top = (rect.bottom - markerHeight / 2) + 'px'; - } - marker.style.width = rect.width + 'px'; - marker.style.left = rect.left + 'px'; - marker.style.display = 'block'; - }, - - /** - * Hides the drop marker. - * @private - */ - hideDropMarker_: function() { - // Hide the marker in a timeout to reduce flickering as we move between - // valid drop targets. - window.clearTimeout(this.hideDropMarkerTimer_); - this.hideDropMarkerTimer_ = window.setTimeout(function() { - $('startupPagesListDropmarker').style.display = ''; - }, 100); - }, - }; - - return { - StartupPageList: StartupPageList - }; -});
diff --git a/chrome/browser/resources/options/certificate_backup_overlay.html b/chrome/browser/resources/options/certificate_backup_overlay.html deleted file mode 100644 index 92601ef..0000000 --- a/chrome/browser/resources/options/certificate_backup_overlay.html +++ /dev/null
@@ -1,40 +0,0 @@ -<div id="certificateBackupOverlay" class="page" hidden> - <div class="close-button"></div> - <h1>$i18n{certificateExportPasswordDescription}</h1> - <div class="content-area"> - <table> - <tr> - <td id="certificate-backup-password-label"> - $i18n{certificatePasswordLabel} - </td> - <td> - <input id="certificateBackupPassword" type="password" - aria-labelledby="certificate-backup-password-label"> - </td> - </tr> - <tr> - <td id="certificate-backup-password-2-label"> - $i18n{certificateConfirmPasswordLabel} - </td> - <td> - <input id="certificateBackupPassword2" type="password" - aria-labelledby="certificate-backup-password-2-label"> - </td> - </tr> - </table> - <p> - <span>$i18n{certificateExportPasswordHelp}</span> - </p> - </div> - <div class="action-area"> - <div class="button-strip"> - <button id="certificateBackupCancelButton" type="reset"> - $i18n{cancel} - </button> - <button id="certificateBackupOkButton" class="default-button" - type="submit" disabled> - $i18n{ok} - </button> - </div> - </div> -</div>
diff --git a/chrome/browser/resources/options/certificate_backup_overlay.js b/chrome/browser/resources/options/certificate_backup_overlay.js deleted file mode 100644 index 9c516b0..0000000 --- a/chrome/browser/resources/options/certificate_backup_overlay.js +++ /dev/null
@@ -1,114 +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. - -cr.define('options', function() { - /** @const */ var Page = cr.ui.pageManager.Page; - /** @const */ var PageManager = cr.ui.pageManager.PageManager; - - /** - * CertificateBackupOverlay class - * Encapsulated handling of the 'enter backup password' overlay page. - * @class - */ - function CertificateBackupOverlay() { - Page.call(this, 'certificateBackupOverlay', '', 'certificateBackupOverlay'); - } - - cr.addSingletonGetter(CertificateBackupOverlay); - - CertificateBackupOverlay.prototype = { - __proto__: Page.prototype, - - /** @override */ - initializePage: function() { - Page.prototype.initializePage.call(this); - - var self = this; - $('certificateBackupCancelButton').onclick = function(event) { - self.cancelBackup_(); - }; - $('certificateBackupOkButton').onclick = function(event) { - self.finishBackup_(); - }; - var onBackupPasswordInput = function(event) { - self.comparePasswords_(); - }; - $('certificateBackupPassword').oninput = onBackupPasswordInput; - $('certificateBackupPassword2').oninput = onBackupPasswordInput; - - self.clearInputFields_(); - }, - - /** - * Clears any uncommitted input, and dismisses the overlay. - * @private - */ - dismissOverlay_: function() { - this.clearInputFields_(); - PageManager.closeOverlay(); - }, - - /** - * Attempt the Backup operation. - * The overlay will be left up with inputs disabled until the backend - * finishes and dismisses it. - * @private - */ - finishBackup_: function() { - chrome.send('exportPersonalCertificatePasswordSelected', - [$('certificateBackupPassword').value]); - $('certificateBackupCancelButton').disabled = true; - $('certificateBackupOkButton').disabled = true; - $('certificateBackupPassword').disabled = true; - $('certificateBackupPassword2').disabled = true; - }, - - /** - * Cancel the Backup operation. - * @private - */ - cancelBackup_: function() { - chrome.send('cancelImportExportCertificate'); - this.dismissOverlay_(); - }, - - /** - * Compares the password fields and sets the button state appropriately. - * @private - */ - comparePasswords_: function() { - var password1 = $('certificateBackupPassword').value; - var password2 = $('certificateBackupPassword2').value; - $('certificateBackupOkButton').disabled = - !password1 || password1 != password2; - }, - - /** - * Clears the value of each input field. - * @private - */ - clearInputFields_: function() { - $('certificateBackupPassword').value = ''; - $('certificateBackupPassword2').value = ''; - $('certificateBackupPassword').disabled = false; - $('certificateBackupPassword2').disabled = false; - $('certificateBackupCancelButton').disabled = false; - $('certificateBackupOkButton').disabled = true; - }, - }; - - CertificateBackupOverlay.show = function() { - CertificateBackupOverlay.getInstance().clearInputFields_(); - PageManager.showPageByName('certificateBackupOverlay'); - }; - - CertificateBackupOverlay.dismiss = function() { - CertificateBackupOverlay.getInstance().dismissOverlay_(); - }; - - // Export - return { - CertificateBackupOverlay: CertificateBackupOverlay - }; -});
diff --git a/chrome/browser/resources/options/certificate_edit_ca_trust_overlay.html b/chrome/browser/resources/options/certificate_edit_ca_trust_overlay.html deleted file mode 100644 index 198002d..0000000 --- a/chrome/browser/resources/options/certificate_edit_ca_trust_overlay.html +++ /dev/null
@@ -1,41 +0,0 @@ -<div id="certificateEditCaTrustOverlay" class="page" hidden> - <h1><span>$i18n{certificateEditCaTitle}</span></h1> - <div class="close-button"></div> - <div class="content-area"> - <div> - <span id="certificateEditCaTrustDescription"></span> - </div> - <section> - <h3><span>$i18n{certificateEditTrustLabel}</span></h3> - <div class="checkbox"> - <label id="certificateCaTrustSSLLabel"> - <input id="certificateCaTrustSSLCheckbox" type="checkbox"> - <span>$i18n{certificateCaTrustSSLLabel}</span> - </label> - </div> - <div class="checkbox"> - <label id="certificateCaTrustEmailLabel"> - <input id="certificateCaTrustEmailCheckbox" type="checkbox"> - <span>$i18n{certificateCaTrustEmailLabel}</span> - </label> - </div> - <div class="checkbox"> - <label id="certificateCaTrustObjSignLabel"> - <input id="certificateCaTrustObjSignCheckbox" type="checkbox"> - <span>$i18n{certificateCaTrustObjSignLabel}</span> - </label> - </div> - </section> - </div> - <div class="action-area"> - <div class="button-strip"> - <button id="certificateEditCaTrustCancelButton" type="reset"> - $i18n{cancel} - </button> - <button id="certificateEditCaTrustOkButton" class="default-button" - type="submit"> - $i18n{ok} - </button> - </div> - </div> -</div>
diff --git a/chrome/browser/resources/options/certificate_edit_ca_trust_overlay.js b/chrome/browser/resources/options/certificate_edit_ca_trust_overlay.js deleted file mode 100644 index f65b26b..0000000 --- a/chrome/browser/resources/options/certificate_edit_ca_trust_overlay.js +++ /dev/null
@@ -1,162 +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. - -cr.define('options', function() { - /** @const */ var Page = cr.ui.pageManager.Page; - /** @const */ var PageManager = cr.ui.pageManager.PageManager; - - /** - * CertificateEditCaTrustOverlay class - * Encapsulated handling of the 'edit ca trust' and 'import ca' overlay pages. - * @class - */ - function CertificateEditCaTrustOverlay() { - Page.call(this, 'certificateEditCaTrustOverlay', '', - 'certificateEditCaTrustOverlay'); - } - - cr.addSingletonGetter(CertificateEditCaTrustOverlay); - - CertificateEditCaTrustOverlay.prototype = { - __proto__: Page.prototype, - - /** - * Dismisses the overlay. - * @private - */ - dismissOverlay_: function() { - PageManager.closeOverlay(); - }, - - /** - * Enables or disables input fields. - * @private - */ - enableInputs_: function(enabled) { - $('certificateCaTrustSSLCheckbox').disabled = - $('certificateCaTrustEmailCheckbox').disabled = - $('certificateCaTrustObjSignCheckbox').disabled = - $('certificateEditCaTrustCancelButton').disabled = - $('certificateEditCaTrustOkButton').disabled = !enabled; - }, - - /** - * Attempt the Edit operation. - * The overlay will be left up with inputs disabled until the backend - * finishes and dismisses it. - * @private - */ - finishEdit_: function() { - // TODO(mattm): Send checked values as booleans. For now send them as - // strings, since WebUIBindings::send does not support any other types :( - chrome.send('editCaCertificateTrust', - [this.certId, - $('certificateCaTrustSSLCheckbox').checked.toString(), - $('certificateCaTrustEmailCheckbox').checked.toString(), - $('certificateCaTrustObjSignCheckbox').checked.toString()]); - this.enableInputs_(false); - }, - - /** - * Cancel the Edit operation. - * @private - */ - cancelEdit_: function() { - this.dismissOverlay_(); - }, - - /** - * Attempt the Import operation. - * The overlay will be left up with inputs disabled until the backend - * finishes and dismisses it. - * @private - */ - finishImport_: function() { - // TODO(mattm): Send checked values as booleans. For now send them as - // strings, since WebUIBindings::send does not support any other types :( - chrome.send('importCaCertificateTrustSelected', - [$('certificateCaTrustSSLCheckbox').checked.toString(), - $('certificateCaTrustEmailCheckbox').checked.toString(), - $('certificateCaTrustObjSignCheckbox').checked.toString()]); - this.enableInputs_(false); - }, - - /** - * Cancel the Import operation. - * @private - */ - cancelImport_: function() { - chrome.send('cancelImportExportCertificate'); - this.dismissOverlay_(); - }, - }; - - /** - * Callback from CertificateManagerHandler with the trust values. - * @param {boolean} trustSSL The initial value of SSL trust checkbox. - * @param {boolean} trustEmail The initial value of Email trust checkbox. - * @param {boolean} trustObjSign The initial value of Object Signing trust. - */ - CertificateEditCaTrustOverlay.populateTrust = function( - trustSSL, trustEmail, trustObjSign) { - $('certificateCaTrustSSLCheckbox').checked = trustSSL; - $('certificateCaTrustEmailCheckbox').checked = trustEmail; - $('certificateCaTrustObjSignCheckbox').checked = trustObjSign; - CertificateEditCaTrustOverlay.getInstance().enableInputs_(true); - }; - - /** - * Show the Edit CA Trust overlay. - * @param {string} certId The id of the certificate to be passed to the - * certificate manager model. - * @param {string} certName The display name of the certificate. - * checkbox. - */ - CertificateEditCaTrustOverlay.show = function(certId, certName) { - var self = CertificateEditCaTrustOverlay.getInstance(); - self.certId = certId; - $('certificateEditCaTrustCancelButton').onclick = function(event) { - self.cancelEdit_(); - }; - $('certificateEditCaTrustOkButton').onclick = function(event) { - self.finishEdit_(); - }; - $('certificateEditCaTrustDescription').textContent = - loadTimeData.getStringF('certificateEditCaTrustDescriptionFormat', - certName); - self.enableInputs_(false); - PageManager.showPageByName('certificateEditCaTrustOverlay'); - chrome.send('getCaCertificateTrust', [certId]); - }; - - /** - * Show the Import CA overlay. - * @param {string} certName The display name of the certificate. - * checkbox. - */ - CertificateEditCaTrustOverlay.showImport = function(certName) { - var self = CertificateEditCaTrustOverlay.getInstance(); - // TODO(mattm): do we want a view certificate button here like firefox has? - $('certificateEditCaTrustCancelButton').onclick = function(event) { - self.cancelImport_(); - }; - $('certificateEditCaTrustOkButton').onclick = function(event) { - self.finishImport_(); - }; - $('certificateEditCaTrustDescription').textContent = - loadTimeData.getStringF('certificateImportCaDescriptionFormat', - certName); - CertificateEditCaTrustOverlay.populateTrust(false, false, false); - PageManager.showPageByName('certificateEditCaTrustOverlay'); - }; - - CertificateEditCaTrustOverlay.dismiss = function() { - CertificateEditCaTrustOverlay.getInstance().dismissOverlay_(); - }; - - // Export - return { - CertificateEditCaTrustOverlay: CertificateEditCaTrustOverlay - }; -});
diff --git a/chrome/browser/resources/options/certificate_import_error_overlay.html b/chrome/browser/resources/options/certificate_import_error_overlay.html deleted file mode 100644 index c468b01..0000000 --- a/chrome/browser/resources/options/certificate_import_error_overlay.html +++ /dev/null
@@ -1,16 +0,0 @@ -<div id="certificateImportErrorOverlay" class="page" hidden> - <div class="close-button"></div> - <h1 id="certificateImportErrorOverlayTitle"></h1> - <div class="content-area"> - <div id="certificateImportErrorOverlayMessage"></div> - <ul id="certificateImportErrorOverlayCertErrors"></ul> - </div> - <div class="action-area"> - <div class="button-strip"> - <button id="certificateImportErrorOverlayOk" class="default-button" - type="submit"> - $i18n{done} - </button> - </div> - </div> -</div>
diff --git a/chrome/browser/resources/options/certificate_import_error_overlay.js b/chrome/browser/resources/options/certificate_import_error_overlay.js deleted file mode 100644 index 2e29185..0000000 --- a/chrome/browser/resources/options/certificate_import_error_overlay.js +++ /dev/null
@@ -1,65 +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. - -cr.define('options', function() { - var Page = cr.ui.pageManager.Page; - var PageManager = cr.ui.pageManager.PageManager; - - /** - * CertificateImportErrorOverlay class - * Displays a list of certificates and errors. - * @class - */ - function CertificateImportErrorOverlay() { - Page.call(this, 'certificateImportErrorOverlay', '', - 'certificateImportErrorOverlay'); - } - - cr.addSingletonGetter(CertificateImportErrorOverlay); - - CertificateImportErrorOverlay.prototype = { - // Inherit CertificateImportErrorOverlay from Page. - __proto__: Page.prototype, - - /** @override */ - initializePage: function() { - Page.prototype.initializePage.call(this); - - $('certificateImportErrorOverlayOk').onclick = function(event) { - PageManager.closeOverlay(); - }; - }, - }; - - /** - * Show an alert overlay with the given message, button titles, and - * callbacks. - * @param {string} title The alert title to display to the user. - * @param {string} message The alert message to display to the user. - * @param {Array} certErrors The list of cert errors. Each error should have - * a .name and .error attribute. - */ - CertificateImportErrorOverlay.show = function(title, message, certErrors) { - $('certificateImportErrorOverlayTitle').textContent = title; - $('certificateImportErrorOverlayMessage').textContent = message; - - var ul = $('certificateImportErrorOverlayCertErrors'); - ul.innerHTML = ''; - for (var i = 0; i < certErrors.length; ++i) { - var li = document.createElement('li'); - li.textContent = loadTimeData.getStringF('certificateImportErrorFormat', - certErrors[i].name, - certErrors[i].error); - ul.appendChild(li); - } - - PageManager.showPageByName('certificateImportErrorOverlay'); - }; - - // Export - return { - CertificateImportErrorOverlay: CertificateImportErrorOverlay - }; - -});
diff --git a/chrome/browser/resources/options/certificate_manager.css b/chrome/browser/resources/options/certificate_manager.css deleted file mode 100644 index 0516e5b..0000000 --- a/chrome/browser/resources/options/certificate_manager.css +++ /dev/null
@@ -1,32 +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. */ - -#certificateManagerPage { - min-width: 700px; -} - -#certificateRestoreOverlay h1 { - /* Leave enough space for the close-button. */ - /* TODO(KGR): make dialogs to use flex-boxes instead of relying on padding. */ - padding-right: 35px; -} - -/* Force tab strip to extend to the left and right edges of the window. */ -#certificate-manager-content-area { - padding: 6px 0 6px 0; -} - -#certificate-manager-content-area .subpages-tab-contents { - padding-left: 28px; - padding-right: 14px; -} - -.certificate-tree-table { - width: 100%; -} - -.certificate-tree { - /* TODO(mattm): BLAH. Make this not statically sized. */ - height: 300px; -}
diff --git a/chrome/browser/resources/options/certificate_manager.html b/chrome/browser/resources/options/certificate_manager.html deleted file mode 100644 index b619dd81..0000000 --- a/chrome/browser/resources/options/certificate_manager.html +++ /dev/null
@@ -1,143 +0,0 @@ -<div id="certificateManagerPage" class="page" hidden> - <div class="close-button"></div> - <h1 id='cert-manager-header'>$i18n{certificateManagerPage}</h1> - <div id="certificate-manager-content-area" class="content-area"> - <!-- Navigation tabs --> - <div class="subpages-nav-tabs"> - <span id="personal-certs-nav-tab" class="tab" - tab-contents="personalCertsTab"> - <span class="tab-label">$i18n{personalCertsTabTitle}</span> - <span class="active-tab-label">$i18n{personalCertsTabTitle}</span> - </span> - <span id="server-certs-nav-tab" class="tab" tab-contents="serverCertsTab"> - <span class="tab-label">$i18n{serverCertsTabTitle}</span> - <span class="active-tab-label">$i18n{serverCertsTabTitle}</span> - </span> - <span id="ca-certs-nav-tab" class="tab" tab-contents="caCertsTab"> - <span class="tab-label">$i18n{caCertsTabTitle}</span> - <span class="active-tab-label">$i18n{caCertsTabTitle}</span> - </span> - <span id="other-certs-nav-tab" class="tab" tab-contents="otherCertsTab"> - <span class="tab-label">$i18n{otherCertsTabTitle}</span> - <span class="active-tab-label">$i18n{otherCertsTabTitle}</span> - </span> - </div> - <!-- TODO(mattm): get rid of use of tables --> - <!-- Tab contents --> - <div id="personalCertsTab" class="subpages-tab-contents"> - <table class="certificate-tree-table"> - <tr><td> - <span>$i18n{personalCertsTabDescription}</span> - </td></tr> - <tr><td> - <tree id="personalCertsTab-tree" class="certificate-tree" - icon-visibility="parent"> - </tree> - </td></tr> - <tr><td> - <button id="personalCertsTab-view" disabled> - $i18n{view_certificate} - </button> - <button id="personalCertsTab-import" disabled> - $i18n{import_certificate} - </button> -<if expr="chromeos"> - <button id="personalCertsTab-import-and-bind" disabled> - $i18n{importAndBindCertificate} - </button> -</if> - <button id="personalCertsTab-backup" disabled> - $i18n{export_certificate} - </button> - <button id="personalCertsTab-delete" disabled> - $i18n{delete_certificate} - </button> - </td></tr> - </table> - </div> - <div id="serverCertsTab" class="subpages-tab-contents"> - <table class="certificate-tree-table"> - <tr><td> - <span>$i18n{serverCertsTabDescription}</span> - </td></tr> - <tr><td> - <tree id="serverCertsTab-tree" class="certificate-tree" - icon-visibility="parent"> - </tree> - </td></tr> - <tr><td> - <button id="serverCertsTab-view" disabled> - $i18n{view_certificate} - </button> - <button id="serverCertsTab-import" disabled> - $i18n{import_certificate} - </button> - <button id="serverCertsTab-export" disabled> - $i18n{export_certificate} - </button> - <button id="serverCertsTab-delete" disabled> - $i18n{delete_certificate} - </button> - </td></tr> - </table> - </div> - <div id="caCertsTab" class="subpages-tab-contents"> - <table class="certificate-tree-table"> - <tr><td> - <span>$i18n{caCertsTabDescription}</span> - </td></tr> - <tr><td> - <tree id="caCertsTab-tree" class="certificate-tree" - icon-visibility="parent"> - </tree> - </td></tr> - <tr><td> - <button id="caCertsTab-view" disabled> - $i18n{view_certificate} - </button> - <button id="caCertsTab-edit" disabled> - $i18n{edit_certificate} - </button> - <button id="caCertsTab-import" disabled> - $i18n{import_certificate} - </button> - <button id="caCertsTab-export" disabled> - $i18n{export_certificate} - </button> - <button id="caCertsTab-delete" disabled> - $i18n{delete_certificate} - </button> - </td></tr> - </table> - </div> - <div id="otherCertsTab" class="subpages-tab-contents"> - <table class="certificate-tree-table"> - <tr><td> - <span>$i18n{otherCertsTabDescription}</span> - </td></tr> - <tr><td> - <tree id="otherCertsTab-tree" class="certificate-tree" - icon-visibility="parent"></tree> - </td></tr> - <tr><td> - <button id="otherCertsTab-view" disabled> - $i18n{view_certificate} - </button> - <button id="otherCertsTab-export" disabled> - $i18n{export_certificate} - </button> - <button id="otherCertsTab-delete" disabled> - $i18n{delete_certificate} - </button> - </td></tr> - </table> - </div> - </div> - <div class="action-area"> - <div class="button-strip"> - <button id="certificate-confirm" class="default-button"> - $i18n{done} - </button> - </div> - </div> -</div>
diff --git a/chrome/browser/resources/options/certificate_manager.js b/chrome/browser/resources/options/certificate_manager.js deleted file mode 100644 index 1447008..0000000 --- a/chrome/browser/resources/options/certificate_manager.js +++ /dev/null
@@ -1,264 +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. - -cr.define('options', function() { - var OptionsPage = options.OptionsPage; - var Page = cr.ui.pageManager.Page; - var PageManager = cr.ui.pageManager.PageManager; - - ///////////////////////////////////////////////////////////////////////////// - // CertificateManagerTab class: - - /** - * blah - * @param {!string} id The id of this tab. - * @param {boolean} isKiosk True if dialog is shown during CrOS kiosk launch. - * @constructor - */ - function CertificateManagerTab(id, isKiosk) { - this.tree = $(id + '-tree'); - - options.CertificatesTree.decorate(this.tree); - this.tree.addEventListener('change', - this.handleCertificatesTreeChange_.bind(this)); - - var tree = this.tree; - - this.viewButton = $(id + '-view'); - this.viewButton.onclick = function(e) { - var selected = tree.selectedItem; - chrome.send('viewCertificate', [selected.data.id]); - }; - - this.editButton = $(id + '-edit'); - if (this.editButton !== null) { - if (id == 'serverCertsTab') { - this.editButton.onclick = function(e) { - var selected = tree.selectedItem; - chrome.send('editServerCertificate', [selected.data.id]); - }; - } else if (id == 'caCertsTab') { - this.editButton.onclick = function(e) { - var data = tree.selectedItem.data; - CertificateEditCaTrustOverlay.show(data.id, data.name); - }; - } - } - - this.backupButton = $(id + '-backup'); - if (this.backupButton !== null) { - if (id == 'personalCertsTab' && isKiosk) { - this.backupButton.hidden = true; - } else { - this.backupButton.onclick = function(e) { - var selected = tree.selectedItem; - chrome.send('exportPersonalCertificate', [selected.data.id]); - }; - } - } - - this.backupAllButton = $(id + '-backup-all'); - if (this.backupAllButton !== null) { - if (id == 'personalCertsTab' && isKiosk) { - this.backupAllButton.hidden = true; - } else { - this.backupAllButton.onclick = function(e) { - chrome.send('exportAllPersonalCertificates'); - }; - } - } - - this.importButton = $(id + '-import'); - if (this.importButton !== null) { - if (id == 'personalCertsTab') { - if (isKiosk) { - this.importButton.hidden = true; - } else { - this.importButton.onclick = function(e) { - chrome.send('importPersonalCertificate', [false]); - }; - } - } else if (id == 'serverCertsTab') { - this.importButton.onclick = function(e) { - chrome.send('importServerCertificate'); - }; - } else if (id == 'caCertsTab') { - this.importButton.onclick = function(e) { - chrome.send('importCaCertificate'); - }; - } - } - - this.importAndBindButton = $(id + '-import-and-bind'); - if (this.importAndBindButton !== null) { - if (id == 'personalCertsTab') { - this.importAndBindButton.onclick = function(e) { - chrome.send('importPersonalCertificate', [true]); - }; - } - } - - this.exportButton = $(id + '-export'); - if (this.exportButton !== null) { - if (id == 'personalCertsTab' && isKiosk) { - this.exportButton.hidden = true; - } else { - this.exportButton.onclick = function(e) { - var selected = tree.selectedItem; - chrome.send('exportCertificate', [selected.data.id]); - }; - } - } - - this.deleteButton = $(id + '-delete'); - this.deleteButton.onclick = function(e) { - var data = tree.selectedItem.data; - AlertOverlay.show( - loadTimeData.getStringF(id + 'DeleteConfirm', data.name), - loadTimeData.getString(id + 'DeleteImpact'), - loadTimeData.getString('ok'), - loadTimeData.getString('cancel'), - function() { - tree.selectedItem = null; - chrome.send('deleteCertificate', [data.id]); - }); - }; - } - - CertificateManagerTab.prototype = { - /** - * Update button state. - * @private - * @param {!Object} data The data of the selected item. - */ - updateButtonState: function(data) { - var isCert = !!data && data.isCert; - var readOnly = !!data && data.readonly; - var extractable = !!data && data.extractable; - var hasChildren = this.tree.items.length > 0; - var isPolicy = !!data && data.policy; - this.viewButton.disabled = !isCert; - if (this.editButton !== null) - this.editButton.disabled = !isCert || isPolicy; - if (this.backupButton !== null) - this.backupButton.disabled = !isCert || !extractable; - if (this.backupAllButton !== null) - this.backupAllButton.disabled = !hasChildren; - if (this.exportButton !== null) - this.exportButton.disabled = !isCert; - this.deleteButton.disabled = !isCert || readOnly || isPolicy; - }, - - /** - * Handles certificate tree selection change. - * @private - * @param {!Event} e The change event object. - */ - handleCertificatesTreeChange_: function(e) { - var data = null; - if (this.tree.selectedItem) - data = this.tree.selectedItem.data; - - this.updateButtonState(data); - }, - }; - - ///////////////////////////////////////////////////////////////////////////// - // CertificateManager class: - - /** - * Encapsulated handling of ChromeOS accounts options page. - * @constructor - * @extends {cr.ui.pageManager.Page} - */ - function CertificateManager() { - Page.call(this, 'certificates', - loadTimeData.getString('certificateManagerPageTabTitle'), - 'certificateManagerPage'); - } - - cr.addSingletonGetter(CertificateManager); - - CertificateManager.prototype = { - __proto__: Page.prototype, - - /** @private {boolean} */ - isKiosk_: false, - - /** @param {boolean} isKiosk */ - setIsKiosk: function(isKiosk) { - this.isKiosk_ = isKiosk; - }, - - /** @override */ - initializePage: function() { - Page.prototype.initializePage.call(this); - - this.personalTab = new CertificateManagerTab('personalCertsTab', - this.isKiosk_); - this.serverTab = new CertificateManagerTab('serverCertsTab', - this.isKiosk_); - this.caTab = new CertificateManagerTab('caCertsTab', this.isKiosk_); - this.otherTab = new CertificateManagerTab('otherCertsTab', this.isKiosk_); - - if (this.isKiosk_) { - // No "Servers" and "Authorities" tab in kiosk mode. - // See http://crbug.com/719907 for details. - $('server-certs-nav-tab').hidden = true; - $('ca-certs-nav-tab').hidden = true; - } - - this.addEventListener('visibleChange', this.handleVisibleChange_); - - $('certificate-confirm').onclick = function() { - PageManager.closeOverlay(); - }; - }, - - initalized_: false, - - /** - * Handler for Page's visible property change event. - * @private - * @param {Event} e Property change event. - */ - handleVisibleChange_: function(e) { - if (!this.initalized_ && this.visible) { - this.initalized_ = true; - OptionsPage.showTab($('personal-certs-nav-tab')); - chrome.send('populateCertificateManager'); - } - } - }; - - // CertificateManagerHandler callbacks. - CertificateManager.onPopulateTree = function(args) { - $(args[0]).populate(args[1]); - }; - - CertificateManager.exportPersonalAskPassword = function(args) { - CertificateBackupOverlay.show(); - }; - - CertificateManager.importPersonalAskPassword = function(args) { - CertificateRestoreOverlay.show(); - }; - - CertificateManager.onModelReady = function(userDbAvailable, - tpmAvailable) { - if (!userDbAvailable) - return; - if (tpmAvailable) - $('personalCertsTab-import-and-bind').disabled = false; - $('personalCertsTab-import').disabled = false; - $('serverCertsTab-import').disabled = false; - $('caCertsTab-import').disabled = false; - }; - - // Export - return { - CertificateManagerTab: CertificateManagerTab, - CertificateManager: CertificateManager - }; -});
diff --git a/chrome/browser/resources/options/certificate_restore_overlay.html b/chrome/browser/resources/options/certificate_restore_overlay.html deleted file mode 100644 index f238cbc..0000000 --- a/chrome/browser/resources/options/certificate_restore_overlay.html +++ /dev/null
@@ -1,21 +0,0 @@ -<div id="certificateRestoreOverlay" class="page" hidden> - <div class="close-button"></div> - <h1>$i18n{certificateRestorePasswordDescription}</h1> - <div class="content-area"> - <label id="certificateRestorePasswordLabel"> - <span>$i18n{certificatePasswordLabel}</span> - <input id="certificateRestorePassword" type="password"> - </label> - </div> - <div class="action-area"> - <div class="button-strip"> - <button id="certificateRestoreCancelButton" type="reset"> - $i18n{cancel} - </button> - <button id="certificateRestoreOkButton" class="default-button" - type="submit"> - $i18n{ok} - </button> - </div> - </div> -</div>
diff --git a/chrome/browser/resources/options/certificate_restore_overlay.js b/chrome/browser/resources/options/certificate_restore_overlay.js deleted file mode 100644 index 5070c6e..0000000 --- a/chrome/browser/resources/options/certificate_restore_overlay.js +++ /dev/null
@@ -1,99 +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. - -cr.define('options', function() { - /** @const */ var Page = cr.ui.pageManager.Page; - /** @const */ var PageManager = cr.ui.pageManager.PageManager; - - /** - * CertificateRestoreOverlay class - * Encapsulated handling of the 'enter restore password' overlay page. - * @class - */ - function CertificateRestoreOverlay() { - Page.call(this, 'certificateRestore', '', 'certificateRestoreOverlay'); - } - - cr.addSingletonGetter(CertificateRestoreOverlay); - - CertificateRestoreOverlay.prototype = { - __proto__: Page.prototype, - - /** @override */ - initializePage: function() { - Page.prototype.initializePage.call(this); - - var self = this; - $('certificateRestoreCancelButton').onclick = function(event) { - self.cancelRestore_(); - }; - $('certificateRestoreOkButton').onclick = function(event) { - self.finishRestore_(); - }; - - self.clearInputFields_(); - }, - - /** @override */ - didShowPage: function() { - $('certificateRestorePassword').focus(); - }, - - /** - * Clears any uncommitted input, and dismisses the overlay. - * @private - */ - dismissOverlay_: function() { - this.clearInputFields_(); - PageManager.closeOverlay(); - }, - - /** - * Attempt the restore operation. - * The overlay will be left up with inputs disabled until the backend - * finishes and dismisses it. - * @private - */ - finishRestore_: function() { - chrome.send('importPersonalCertificatePasswordSelected', - [$('certificateRestorePassword').value]); - $('certificateRestoreCancelButton').disabled = true; - $('certificateRestoreOkButton').disabled = true; - }, - - /** - * Cancel the restore operation. - * @private - */ - cancelRestore_: function() { - chrome.send('cancelImportExportCertificate'); - this.dismissOverlay_(); - }, - - /** - * Clears the value of each input field. - * @private - */ - clearInputFields_: function() { - $('certificateRestorePassword').value = ''; - $('certificateRestoreCancelButton').disabled = false; - $('certificateRestoreOkButton').disabled = false; - }, - }; - - CertificateRestoreOverlay.show = function() { - CertificateRestoreOverlay.getInstance().clearInputFields_(); - PageManager.showPageByName('certificateRestore'); - }; - - CertificateRestoreOverlay.dismiss = function() { - CertificateRestoreOverlay.getInstance().dismissOverlay_(); - }; - - // Export - return { - CertificateRestoreOverlay: CertificateRestoreOverlay - }; - -});
diff --git a/chrome/browser/resources/options/certificate_tree.css b/chrome/browser/resources/options/certificate_tree.css deleted file mode 100644 index ee83aed..0000000 --- a/chrome/browser/resources/options/certificate_tree.css +++ /dev/null
@@ -1,17 +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. */ - -span.cert-untrusted { - background-color: pink; - border: 1px solid red; - border-radius: 3px; - margin-right: 3px; - padding-left: 1px; - padding-right: 1px; -} - -span.cert-policy { - margin-left: 3px; - vertical-align: middle; -}
diff --git a/chrome/browser/resources/options/certificate_tree.js b/chrome/browser/resources/options/certificate_tree.js deleted file mode 100644 index 6265e14d..0000000 --- a/chrome/browser/resources/options/certificate_tree.js +++ /dev/null
@@ -1,177 +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. - -/** - * @typedef {{ - * id: string, - * name: string, - * subnodes: Array<{id: string, name: string, readonly: boolean, - * untrusted: boolean, extractable: boolean, - * policy: boolean}> - * }} - */ -var CertificateData; - -cr.define('options', function() { - /** @const */ var Tree = cr.ui.Tree; - /** @const */ var TreeItem = cr.ui.TreeItem; - - /** - * Creates a new tree folder for certificate data. - * @param {Object=} data Data used to create a certificate tree folder. - * @constructor - * @extends {TreeItem} - */ - function CertificateTreeFolder(data) { - data.isCert = false; - var treeFolder = new TreeItem({ - label: data.name, - data: data - }); - treeFolder.__proto__ = CertificateTreeFolder.prototype; - - if (data.icon) - treeFolder.icon = data.icon; - - return treeFolder; - } - - CertificateTreeFolder.prototype = { - __proto__: TreeItem.prototype, - - /** - * The tree path id/. - * @type {string} - */ - get pathId() { - return this.data.id; - } - }; - - /** - * Creates a new tree item for certificate data. - * @param {Object=} data Data used to create a certificate tree item. - * @constructor - * @extends {TreeItem} - */ - function CertificateTreeItem(data) { - data.isCert = true; - // TODO(mattm): other columns - var treeItem = new TreeItem({ - label: data.name, - data: data - }); - treeItem.__proto__ = CertificateTreeItem.prototype; - - if (data.icon) - treeItem.icon = data.icon; - - if (data.untrusted) { - var badge = document.createElement('span'); - badge.classList.add('cert-untrusted'); - badge.textContent = loadTimeData.getString('badgeCertUntrusted'); - treeItem.labelElement.insertBefore( - badge, treeItem.labelElement.firstChild); - } - - if (data.policy) { - var policyIndicator = new options.ControlledSettingIndicator(); - policyIndicator.controlledBy = 'policy'; - policyIndicator.setAttribute( - 'textpolicy', loadTimeData.getString('certPolicyInstalled')); - policyIndicator.classList.add('cert-policy'); - treeItem.labelElement.appendChild(policyIndicator); - } - - return treeItem; - } - - CertificateTreeItem.prototype = { - __proto__: TreeItem.prototype, - - /** - * The tree path id/. - * @type {string} - */ - get pathId() { - return this.parentItem.pathId + ',' + this.data.id; - } - }; - - /** - * Creates a new cookies tree. - * @param {Object=} opt_propertyBag Optional properties. - * @constructor - * @extends {Tree} - */ - var CertificatesTree = cr.ui.define('tree'); - - CertificatesTree.prototype = { - __proto__: Tree.prototype, - - /** @override */ - decorate: function() { - Tree.prototype.decorate.call(this); - this.treeLookup_ = {}; - }, - - /** @override */ - addAt: function(child, index) { - Tree.prototype.addAt.call(this, child, index); - if (child.data && child.data.id) - this.treeLookup_[child.data.id] = child; - }, - - /** - * @param {!cr.ui.TreeItem=} child - * @override - */ - remove: function(child) { - Tree.prototype.remove.call(this, child); - if (child.data && child.data.id) - delete this.treeLookup_[child.data.id]; - }, - - /** - * Clears the tree. - */ - clear: function() { - // Remove all fields without recreating the object since other code - // references it. - for (var id in this.treeLookup_) - delete this.treeLookup_[id]; - this.textContent = ''; - }, - - /** - * Populate the tree. - * @param {Array<CertificateData>} nodesData Nodes data array. - */ - populate: function(nodesData) { - this.clear(); - - for (var i = 0; i < nodesData.length; ++i) { - var subnodes = nodesData[i].subnodes; - delete nodesData[i].subnodes; - - var item = new CertificateTreeFolder(nodesData[i]); - this.addAt(item, i); - - for (var j = 0; j < subnodes.length; ++j) { - var subitem = new CertificateTreeItem(subnodes[j]); - item.addAt(subitem, j); - } - // Make tree expanded by default. - item.expanded = true; - } - - cr.dispatchSimpleEvent(this, 'change'); - }, - }; - - return { - CertificatesTree: CertificatesTree - }; -}); -
diff --git a/chrome/browser/resources/options/chromeos/2x/warning.png b/chrome/browser/resources/options/chromeos/2x/warning.png deleted file mode 100644 index b28ab36..0000000 --- a/chrome/browser/resources/options/chromeos/2x/warning.png +++ /dev/null Binary files differ
diff --git a/chrome/browser/resources/options/chromeos/OWNERS b/chrome/browser/resources/options/chromeos/OWNERS deleted file mode 100644 index 66764c92..0000000 --- a/chrome/browser/resources/options/chromeos/OWNERS +++ /dev/null
@@ -1,8 +0,0 @@ -# This UI is deprecated. See chrome/browser/resources/settings/ instead. -achuith@chromium.org -stevenjb@chromium.org -xiyuan@chromium.org -zelidrag@chromium.org - -# Display options. -mukai@chromium.org
diff --git a/chrome/browser/resources/options/chromeos/accounts_options.html b/chrome/browser/resources/options/chromeos/accounts_options.html deleted file mode 100644 index 1cbfe32..0000000 --- a/chrome/browser/resources/options/chromeos/accounts_options.html +++ /dev/null
@@ -1,85 +0,0 @@ -<div id="accountsPage" class="page" hidden> - <div class="close-button"></div> - <h1>$i18n{accountsPage}</h1> - <div class="content-area"> - <div class="option"> - <div id="ownerOnlyWarning" hidden> - <span>$i18n{owner_only}</span> - <span>$i18n{ownerUserId}</span> - </div> - <table class="option-control-table"> - <tr> - <td class="option-name"> - <div class="checkbox"> - <label> - <input id="allowBwsiCheck" type="checkbox" - metric="Options_GuestBrowsing" - pref="cros.accounts.allowBWSI"> - <span>$i18n{allow_BWSI}</span> - </label> - </div> - </td> - </tr> - <tr> - <td class="option-name"> - <div class="checkbox"> - <label> - <input id="allowSupervisedCheck" type="checkbox" - metric="Options_SupervisedUsers" - pref="cros.accounts.supervisedUsersEnabled"> - <span>$i18n{allow_supervised_users}</span> - </label> - </div> - </td> - </tr> - <tr> - <td class="option-name"> - <div class="checkbox"> - <label> - <input id="showUserNamesCheck" type="checkbox" - metric="Options_ShowUserNamesOnSignin" - pref="cros.accounts.showUserNamesOnSignIn"> - <span>$i18n{show_user_on_signin}</span> - </label> - </div> - </td> - </tr> - <tr> - <td class="option-name"> - <div class="checkbox"> - <label> - <input id="useWhitelistCheck" type="checkbox" - metric="Options_AllowAllUsers" - pref="cros.accounts.allowGuest" - inverted_pref> - <span>$i18n{use_whitelist}</span> - </label> - </div> - </td> - </tr> - <tr><td> </td></tr> - <tr><td> - <table class="user-list-table"> - <tr><td> - <list id="userList"></list> - </td></tr> - <tr><td class="user-name-edit-row"> - <label><span>$i18n{add_users}</span><br> - <input id="userNameEdit" type="text" - placeholder="$i18n{username_edit_hint}"> - </span> - </label> - </td></tr> - </table> - </td></tr> - </table> - </div> - </div> - <div class="action-area"> - <div class="button-strip"> - <button id="accounts-options-overlay-confirm" class="default-button"> - $i18n{done} - </button> - </div> - </div> -</div>
diff --git a/chrome/browser/resources/options/chromeos/accounts_options.js b/chrome/browser/resources/options/chromeos/accounts_options.js deleted file mode 100644 index 27b04fd..0000000 --- a/chrome/browser/resources/options/chromeos/accounts_options.js +++ /dev/null
@@ -1,158 +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. - -cr.define('options', function() { - var Page = cr.ui.pageManager.Page; - var PageManager = cr.ui.pageManager.PageManager; - - ///////////////////////////////////////////////////////////////////////////// - // AccountsOptions class: - - /** - * Encapsulated handling of ChromeOS accounts options page. - * @constructor - * @extends {cr.ui.pageManager.Page} - */ - function AccountsOptions(model) { - Page.call(this, 'accounts', loadTimeData.getString('accountsPageTabTitle'), - 'accountsPage'); - // Whether to show the whitelist. - this.showWhitelist_ = false; - } - - cr.addSingletonGetter(AccountsOptions); - - AccountsOptions.prototype = { - // Inherit AccountsOptions from Page. - __proto__: Page.prototype, - - /** @override */ - initializePage: function() { - Page.prototype.initializePage.call(this); - - // Set up accounts page. - var userList = $('userList'); - userList.addEventListener('remove', this.handleRemoveUser_); - - var userNameEdit = $('userNameEdit'); - options.accounts.UserNameEdit.decorate(userNameEdit); - userNameEdit.addEventListener('add', this.handleAddUser_); - - // If the current user is not the owner, do not show the user list. - // If the current user is not the owner, or the device is enterprise - // managed, show a warning that settings cannot be modified. - this.showWhitelist_ = UIAccountTweaks.currentUserIsOwner(); - if (this.showWhitelist_) { - options.accounts.UserList.decorate(userList); - } else { - $('ownerOnlyWarning').hidden = false; - this.managed = AccountsOptions.whitelistIsManaged(); - } - - this.addEventListener('visibleChange', this.handleVisibleChange_); - - $('useWhitelistCheck').addEventListener('change', - this.handleUseWhitelistCheckChange_.bind(this)); - - Preferences.getInstance().addEventListener( - $('useWhitelistCheck').pref, - this.handleUseWhitelistPrefChange_.bind(this)); - - $('accounts-options-overlay-confirm').onclick = - PageManager.closeOverlay.bind(PageManager); - }, - - /** - * Update user list control state. - * @private - */ - updateControls_: function() { - $('userList').disabled = - $('userNameEdit').disabled = !this.showWhitelist_ || - AccountsOptions.whitelistIsManaged() || - !$('useWhitelistCheck').checked; - }, - - /** - * Handler for Page's visible property change event. - * @private - * @param {Event} e Property change event. - */ - handleVisibleChange_: function(e) { - if (this.visible) { - chrome.send('updateWhitelist'); - this.updateControls_(); - if (this.showWhitelist_) - $('userList').redraw(); - } - }, - - /** - * Handler for allow guest check change. - * @private - */ - handleUseWhitelistCheckChange_: function(e) { - // Whitelist existing users when guest login is being disabled. - if ($('useWhitelistCheck').checked) { - chrome.send('updateWhitelist'); - } - - this.updateControls_(); - }, - - /** - * handler for allow guest pref change. - * @private - */ - handleUseWhitelistPrefChange_: function(e) { - this.updateControls_(); - }, - - /** - * Handler for "add" event fired from userNameEdit. - * @private - * @param {Event} e Add event fired from userNameEdit. - */ - handleAddUser_: function(e) { - chrome.send('whitelistUser', [e.user.email, e.user.name]); - chrome.send('coreOptionsUserMetricsAction', - ['Options_WhitelistedUser_Add']); - }, - - /** - * Handler for "remove" event fired from userList. - * @private - * @param {Event} e Remove event fired from userList. - */ - handleRemoveUser_: function(e) { - chrome.send('unwhitelistUser', [e.user.username]); - chrome.send('coreOptionsUserMetricsAction', - ['Options_WhitelistedUser_Remove']); - }, - - /** - * Update account picture. - * @param {string} username User for which to update the image. - */ - updateAccountPicture: function(username) { - if (this.showWhitelist_) - $('userList').updateAccountPicture(username); - } - }; - - - /** - * Returns whether the whitelist is managed by policy or not. - */ - AccountsOptions.whitelistIsManaged = function() { - return loadTimeData.getBoolean('whitelist_is_managed'); - }; - - - // Export - return { - AccountsOptions: AccountsOptions - }; - -});
diff --git a/chrome/browser/resources/options/chromeos/accounts_options_page.css b/chrome/browser/resources/options/chromeos/accounts_options_page.css deleted file mode 100644 index 36577575..0000000 --- a/chrome/browser/resources/options/chromeos/accounts_options_page.css +++ /dev/null
@@ -1,94 +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. */ - -.user-list-table { - border: 1px solid lightgrey; - border-collapse: collapse; - border-spacing: 0; -} - -.user-name-edit-row { - background-color: rgb(235, 239, 250); - border: 1px solid lightgrey; - padding: 5px; -} - -.user-list-item { - padding: 2px; -} - -.user-icon { - border: 1px solid black; - height: 26px; - width: 26px; -} - -.user-email-label, -.user-name-label { - -webkit-margin-start: 10px; -} - -.user-email-name-block { - -webkit-box-flex: 1; - max-width: 318px; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} - -.remove-user-button { - background-image: -webkit-image-set( - url(../../../../../ui/resources/default_100_percent/close_2.png) 1x, - url(../../../../../ui/resources/default_200_percent/close_2.png) 2x); - height: 16px; - width: 16px; -} - -.remove-user-button:hover { - background-image: -webkit-image-set( - url(../../../../../ui/resources/default_100_percent/close_2_hover.png) - 1x, - url(../../../../../ui/resources/default_200_percent/close_2_hover.png) - 2x); -} - -#userList { - height: 166px; - padding: 5px; - width: 366px; -} - -#userList[disabled], -#userList[disabled] > [selected], -#userList[disabled] > :hover { - border-color: hsl(0, 0%, 85%); -} - -#userList[disabled] > [selected], -#userList[disabled] > :hover { - background-color: hsl(0, 0%, 90%); -} - -#userList[disabled] .remove-user-button { - visibility: hidden; -} - -#userNameEdit { - border: 1px solid lightgrey; - width: 366px; -} - -#ownerOnlyWarning { - -webkit-padding-start: 20px; - background-image: url(warning.png); - background-repeat: no-repeat; - margin-bottom: 10px; - margin-top: 10px; - min-height: 17px; - padding-bottom: 1px; -} - -input#userNameEdit:invalid { - background-color: rgb(255, 102, 102); -}
diff --git a/chrome/browser/resources/options/chromeos/accounts_user_list.js b/chrome/browser/resources/options/chromeos/accounts_user_list.js deleted file mode 100644 index 8bb3e3f0..0000000 --- a/chrome/browser/resources/options/chromeos/accounts_user_list.js +++ /dev/null
@@ -1,197 +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. - -cr.define('options.accounts', function() { - /** @const */ var List = cr.ui.List; - /** @const */ var ListItem = cr.ui.ListItem; - /** @const */ var ArrayDataModel = cr.ui.ArrayDataModel; - - /** - * Creates a new user list. - * @param {Object=} opt_propertyBag Optional properties. - * @constructor - * @extends {cr.ui.List} - */ - var UserList = cr.ui.define('list'); - - UserList.prototype = { - __proto__: List.prototype, - - pref: 'cros.accounts.users', - - /** @override */ - decorate: function() { - List.prototype.decorate.call(this); - - // HACK(arv): http://crbug.com/40902 - window.addEventListener('resize', this.redraw.bind(this)); - - var self = this; - - // Listens to pref changes. - Preferences.getInstance().addEventListener(this.pref, - function(event) { - self.load_(event.value.value); - }); - }, - - /** - * @override - * @param {Object} user - */ - createItem: function(user) { - return new UserListItem(user); - }, - - /** - * Finds the index of user by given username (canonicalized email). - * @private - * @param {string} username The username to look for. - * @return {number} The index of the found user or -1 if not found. - */ - indexOf_: function(username) { - var dataModel = this.dataModel; - if (!dataModel) - return -1; - - var length = dataModel.length; - for (var i = 0; i < length; ++i) { - var user = dataModel.item(i); - if (user.username == username) { - return i; - } - } - - return -1; - }, - - /** - * Update given user's account picture. - * @param {string} username User for which to update the image. - */ - updateAccountPicture: function(username) { - var index = this.indexOf_(username); - if (index >= 0) { - var item = this.getListItemByIndex(index); - if (item) - item.updatePicture(); - } - }, - - /** - * Loads given user list. - * @param {!Array<Object>} users An array of user info objects. - * @private - */ - load_: function(users) { - this.dataModel = new ArrayDataModel(users); - }, - - /** - * Removes given user from the list. - * @param {Object} user User info object to be removed from user list. - * @private - */ - removeUser_: function(user) { - var e = new Event('remove'); - e.user = user; - this.dispatchEvent(e); - } - }; - - /** - * Whether the user list is disabled. Only used for display purpose. - */ - cr.defineProperty(UserList, 'disabled', cr.PropertyKind.BOOL_ATTR); - - /** - * Creates a new user list item. - * @param {Object} user The user account this represents. - * @constructor - * @extends {cr.ui.ListItem} - */ - function UserListItem(user) { - var el = cr.doc.createElement('div'); - el.user = user; - UserListItem.decorate(el); - return el; - } - - /** - * Decorates an element as a user account item. - * @param {!HTMLElement} el The element to decorate. - */ - UserListItem.decorate = function(el) { - el.__proto__ = UserListItem.prototype; - el.decorate(); - }; - - UserListItem.prototype = { - __proto__: ListItem.prototype, - - /** @override */ - decorate: function() { - ListItem.prototype.decorate.call(this); - - this.className = 'user-list-item'; - - this.icon_ = this.ownerDocument.createElement('img'); - this.icon_.className = 'user-icon'; - this.updatePicture(); - - var labelEmail = this.ownerDocument.createElement('span'); - labelEmail.className = 'user-email-label'; - labelEmail.textContent = this.user.email; - - var labelName = this.ownerDocument.createElement('span'); - labelName.className = 'user-name-label'; - labelName.textContent = this.user.owner ? - loadTimeData.getStringF('username_format', this.user.name) : - this.user.name; - - var emailNameBlock = this.ownerDocument.createElement('div'); - emailNameBlock.className = 'user-email-name-block'; - emailNameBlock.appendChild(labelEmail); - emailNameBlock.appendChild(labelName); - emailNameBlock.title = this.user.owner ? - loadTimeData.getStringF('username_format', this.user.email) : - this.user.email; - - this.appendChild(this.icon_); - this.appendChild(emailNameBlock); - - if (!this.user.owner) { - var removeButton = this.ownerDocument.createElement('button'); - removeButton.className = - 'raw-button remove-user-button custom-appearance'; - removeButton.addEventListener( - 'click', this.handleRemoveButtonClick_.bind(this)); - this.appendChild(removeButton); - } - }, - - /** - * Handles click on the remove button. - * @param {Event} e Click event. - * @private - */ - handleRemoveButtonClick_: function(e) { - // Handle left button click - if (e.button == 0) - this.parentNode.removeUser_(this.user); - }, - - /** - * Reloads user picture. - */ - updatePicture: function() { - this.icon_.src = 'chrome://userimage/' + this.user.username + - '?id=' + (new Date()).getTime(); - } - }; - - return { - UserList: UserList - }; -});
diff --git a/chrome/browser/resources/options/chromeos/accounts_user_name_edit.js b/chrome/browser/resources/options/chromeos/accounts_user_name_edit.js deleted file mode 100644 index 6766e96..0000000 --- a/chrome/browser/resources/options/chromeos/accounts_user_name_edit.js +++ /dev/null
@@ -1,129 +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. - -cr.define('options.accounts', function() { - /** - * Email alias only, assuming it's a gmail address. - * e.g. 'john' - * {name: 'john', email: 'john@gmail.com'} - * @const - */ - var format1String = - '^\\s*([\\w\\.!#\\$%&\'\\*\\+-\\/=\\?\\^`\\{\\|\\}~]+)\\s*$'; - /** - * Email address only. - * e.g. 'john@chromium.org' - * {name: 'john', email: 'john@chromium.org'} - * @const - */ - var format2String = - '^\\s*([\\w\\.!#\\$%&\'\\*\\+-\\/=\\?\\^`\\{\\|\\}~]+)@' + - '([A-Za-z0-9\-]{2,63}\\..+)\\s*$'; - /** - * Full format. - * e.g. '"John Doe" <john@chromium.org>' - * {name: 'John doe', email: 'john@chromium.org'} - * @const - */ - var format3String = - '^\\s*"{0,1}([^"]+)"{0,1}\\s*' + - '<([\\w\\.!#\\$%&\'\\*\\+-\\/=\\?\\^`\\{\\|\\}~]+@' + - '[A-Za-z0-9\-]{2,63}\\..+)>\\s*$'; - - /** - * Creates a new user name edit element. - * @param {Object=} opt_propertyBag Optional properties. - * @constructor - * @extends {HTMLInputElement} - */ - var UserNameEdit = cr.ui.define('input'); - - UserNameEdit.prototype = { - __proto__: HTMLInputElement.prototype, - - /** - * Called when an element is decorated as a user name edit. - */ - decorate: function() { - this.pattern = format1String + '|' + format2String + '|' + - format3String; - - this.onkeydown = this.handleKeyDown_.bind(this); - }, - - - /** - * Parses given str for user info. - * - * Note that the email parsing is based on RFC 5322 and does not support - * IMA (Internationalized Email Address). We take only the following chars - * as valid for an email alias (aka local-part): - * - Letters: a–z, A–Z - * - Digits: 0-9 - * - Characters: ! # $ % & ' * + - / = ? ^ _ ` { | } ~ - * - Dot: . (Note that we did not cover the cases that dot should not - * appear as first or last character and should not appear two or - * more times in a row.) - * - * @param {string} str A string to parse. - * @return {?{name: string, email: string}} User info parsed from the - * string. - */ - parse: function(str) { - /** @const */ var format1 = new RegExp(format1String); - /** @const */ var format2 = new RegExp(format2String); - /** @const */ var format3 = new RegExp(format3String); - - var matches = format1.exec(str); - if (matches) { - return { - name: matches[1], - email: matches[1] + '@gmail.com' - }; - } - - matches = format2.exec(str); - if (matches) { - return { - name: matches[1], - email: matches[1] + '@' + matches[2] - }; - } - - matches = format3.exec(str); - if (matches) { - return { - name: matches[1], - email: matches[2] - }; - } - - return null; - }, - - /** - * Handler for key down event. - * @private - * @param {Event} e The keydown event object. - */ - handleKeyDown_: function(e) { - if (e.key == 'Enter') { - var user = this.parse(this.value); - if (user) { - var event = new Event('add'); - event.user = user; - this.dispatchEvent(event); - } - this.select(); - // Avoid double-handling so the dialog doesn't close. - e.stopPropagation(); - } - } - }; - - return { - UserNameEdit: UserNameEdit - }; -}); -
diff --git a/chrome/browser/resources/options/chromeos/arc_opt_out_confirm_overlay.css b/chrome/browser/resources/options/chromeos/arc_opt_out_confirm_overlay.css deleted file mode 100644 index c72e26d..0000000 --- a/chrome/browser/resources/options/chromeos/arc_opt_out_confirm_overlay.css +++ /dev/null
@@ -1,11 +0,0 @@ -/* Copyright 2016 The Chromium Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. */ - -#arc-opt-out-confirm-overlay { - max-width: 500px; -} - -#arc-opt-out-confirm-overlay .content-area { - white-space: pre-line; -} \ No newline at end of file
diff --git a/chrome/browser/resources/options/chromeos/arc_opt_out_confirm_overlay.html b/chrome/browser/resources/options/chromeos/arc_opt_out_confirm_overlay.html deleted file mode 100644 index 6e6575d..0000000 --- a/chrome/browser/resources/options/chromeos/arc_opt_out_confirm_overlay.html +++ /dev/null
@@ -1,21 +0,0 @@ -<div id="arc-opt-out-confirm-overlay" class="page" hidden> - <div class="close-button"></div> - <h1>$i18n{arcOptOutDialogHeader}</h1> - <div class="content-area"> - <span id="arc-opt-out-confirm-text"> - $i18nRaw{arcOptOutDialogDescription} - </span> - </div> - <div class="action-area"> - <div class="action-area-right"> - <div class="button-strip"> - <button id="arc-opt-out-confirm-cancel"> - $i18n{arcOptOutDialogButtonCancel} - </button> - <button id="arc-opt-out-confirm-ok"> - $i18n{arcOptOutDialogButtonConfirmDisable} - </button> - </div> - </div> - </div> -</div>
diff --git a/chrome/browser/resources/options/chromeos/bluetooth.css b/chrome/browser/resources/options/chromeos/bluetooth.css deleted file mode 100644 index 6a06c88..0000000 --- a/chrome/browser/resources/options/chromeos/bluetooth.css +++ /dev/null
@@ -1,188 +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. */ - -#bluetooth-pairing { - max-width: 480px; - width: 100%; -} - -#bluetooth-pairing h1 { - border-bottom: 1px solid #c0c0c0; - font-size: 15px; -} - -#bluetooth-pairing > .close-button { - padding: 8px 16px; -} - -#bluetooth-pairing .button-strip button { - background-color: rgb(66, 133, 244); - background-image: none; - border: none; - color: white; - font-size: 14px; - padding: 8px 20px; - text-shadow: none; -} - -.bluetooth-device-list { - margin: 10px 0; - padding: 5px 10px; -} - -.bluetooth-device[notconnectable] { - color: gray; -} - -.bluetooth-device[connected] { - font-weight: bold; /* semibold */ -} - -#bluetooth-options .bluetooth-device-list { - margin: 0 10px; -} - -#bluetooth-options .button-strip { - -webkit-box-pack: justify; -} - -#bluetooth-options .button-strip #bluetooth-scanning-label, -#bluetooth-options .button-strip #bluetooth-scan-stopped-label { - -webkit-box-flex: 1; - display: block; -} - -#bluetooth-scanning-label, -#bluetooth-scan-stopped-label { - -webkit-margin-start: 5px; - color: #999; -} - -#bluetooth-scanning-icon { - height: 20px; - opacity: 0.66; - vertical-align: middle; - width: 20px; -} - -#bluetooth-paired-devices-list { - min-height: 96px !important; -} - -#bluetooth-paired-devices-list, -#bluetooth-unpaired-devices-list { - /* Prevent dialog from expanding if many devices are found. */ - max-height: 192px; - overflow-x: hidden; - overflow-y: auto; -} - -.bluetooth-empty-list-label { - box-sizing: border-box; - color: #999; - padding-top: 32px; - text-align: center; -} - -#bluetooth-paired-devices-list-empty-placeholder { - height: 96px; -} - -#bluetooth-unpaired-devices-list-empty-placeholder { - height: 192px; -} - -/* Fix the dimensions of the message area so that the dialog does not change - change size during the pairing process as the message changes. Sized - generously to accomodate the longest of the messages. */ -#bluetooth-pairing-message-area { - display: table; - height: 160px; - padding: 6px 16px !important; - width: 420px; -} - -/* Force the message to be vertical centered so that a shorter message does not - look out of place when there is room for a much longer message. */ -#bluetooth-pairing-message-contents { - display: table-cell; - vertical-align: middle; -} - -#bluetooth-pairing-instructions { - font-size: 13px; - text-align: left; -} - -#bluetooth-pairing-passkey-display, -#bluetooth-pairing-passkey-entry, -#bluetooth-pairing-pincode-entry, -#bluetooth-passkey, -#bluetooth-pincode { - text-align: center; -} - -#bluetooth-pairing-instructions { - margin: 20px 0; -} - -#bluetooth-pairing-passkey-display, -#bluetooth-pairing-passkey-entry, -#bluetooth-pairing-pincode-entry { - margin: 40px 0; -} - -.bluetooth-keyboard-button { - -webkit-padding-end: 15px; - -webkit-padding-start: 15px; - border: 1px solid #ccc; - border-radius: 4px; - box-shadow: 0 0 0 1px #222; - color: #222; - display: inline-block; - font-size: 16px; - height: 38px; - line-height: 38px; - margin: 0 10px 0 0; - position: relative; - text-align: center; - text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); - vertical-align: baseline; -} - -.bluetooth-keyboard-button:last-child { - margin: 0; -} - -#bluetooth-enter-key { - min-width: 54px; -} - -.bluetooth-passkey-char { - -webkit-margin-start: 45px; - font-size: 32px; - padding-bottom: 5px; -} - -.bluetooth-passkey-char:first-child { - -webkit-margin-start: 0; -} - -.bluetooth-keyboard-button.key-typed { - color: #222; -} - -.bluetooth-keyboard-button.key-next { - background: rgb(77, 144, 254); - background-image: none; - border: 2px solid rgb(77, 144, 254); - box-shadow: none; - color: #fff; -} - -.bluetooth-keyboard-button.key-untyped { - border: 1px solid #d4d4d4; - box-shadow: 0 0 0 1px #888; - color: #666; -}
diff --git a/chrome/browser/resources/options/chromeos/bluetooth_add_device_overlay.html b/chrome/browser/resources/options/chromeos/bluetooth_add_device_overlay.html deleted file mode 100644 index 99cafad2..0000000 --- a/chrome/browser/resources/options/chromeos/bluetooth_add_device_overlay.html +++ /dev/null
@@ -1,23 +0,0 @@ -<div id="bluetooth-options" class="page" hidden> - <div class="close-button"></div> - <h1>$i18n{bluetoothAddDeviceTitle}</h1> - <div class="settings-list bluetooth-device-list content-area"> - <list id="bluetooth-unpaired-devices-list"></list> - <div id="bluetooth-unpaired-devices-list-empty-placeholder" - class="bluetooth-empty-list-label" hidden> - <span>$i18n{bluetoothNoDevicesFound}</span> - </div> - </div> - <div class="action-area button-strip"> - <button id="bluetooth-add-device-cancel-button" type="reset"> - $i18n{cancel} - </button> - <button id="bluetooth-add-device-apply-button" type="submit" - class="default-button" disabled> - $i18n{bluetoothConnectDevice} - </button> - <span id="bluetooth-scanning-label">$i18n{bluetoothScanning}</span> - <span id="bluetooth-scan-stopped-label">$i18n{bluetoothScanStopped}</span> - <div id="bluetooth-scanning-icon" class="inline-spinner"></div> - </div> -</div>
diff --git a/chrome/browser/resources/options/chromeos/bluetooth_add_device_overlay.js b/chrome/browser/resources/options/chromeos/bluetooth_add_device_overlay.js deleted file mode 100644 index 323a31fb..0000000 --- a/chrome/browser/resources/options/chromeos/bluetooth_add_device_overlay.js +++ /dev/null
@@ -1,131 +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. - -cr.define('options', function() { - /** @const */ var Page = cr.ui.pageManager.Page; - /** @const */ var PageManager = cr.ui.pageManager.PageManager; - - /** - * Encapsulated handling of the Bluetooth options page. - * @constructor - * @extends {cr.ui.pageManager.Page} - */ - function BluetoothOptions() { - Page.call(this, 'bluetooth', - loadTimeData.getString('bluetoothOptionsPageTabTitle'), - 'bluetooth-options'); - } - - cr.addSingletonGetter(BluetoothOptions); - - BluetoothOptions.prototype = { - __proto__: Page.prototype, - - /** - * The list of available (unpaired) bluetooth devices. - * @type {options.DeletableItemList} - * @private - */ - deviceList_: null, - - /** @override */ - initializePage: function() { - Page.prototype.initializePage.call(this); - this.createDeviceList_(); - - $('bluetooth-add-device-cancel-button').onclick = function(event) { - PageManager.closeOverlay(); - }; - - var self = this; - $('bluetooth-add-device-apply-button').onclick = function(event) { - chrome.send('coreOptionsUserMetricsAction', - ['Options_BluetoothConnectNewDevice']); - var device = self.deviceList_.selectedItem; - PageManager.closeOverlay(); - options.BluetoothPairing.connect(device, true); - }; - - $('bluetooth-unpaired-devices-list').addEventListener('change', - function() { - var item = $('bluetooth-unpaired-devices-list').selectedItem; - // The "bluetooth-add-device-apply-button" should be enabled for devices - // that can be paired or remembered. Devices not supporting pairing will - // be just remembered and later reported as "item.paired" = true. The - // button should be disabled in any other case: - // * No item is selected (item is undefined). - // * Paired devices (item.paired is true) are already paired and a new - // pairing attempt will fail. Paired devices could appear in this list - // shortly after the pairing initiated in another window finishes. - // * "Connecting" devices (item.connecting is true) are in the process - // of a pairing or connection. Another attempt to pair before the - // ongoing pair finishes will fail, so the button should be disabled. - var disabled = !item || item.paired || item.connecting; - $('bluetooth-add-device-apply-button').disabled = disabled; - }); - }, - - /** @override */ - didShowPage: function() { - chrome.bluetooth.startDiscovery(function() { - if (chrome.runtime.lastError) { - console.error( - 'Unexpected error calling bluetooth.startDiscovery: ' + - chrome.runtime.lastError.message); - } - }); - BluetoothOptions.updateDiscoveryState(true); - }, - - /** @override */ - didClosePage: function() { - chrome.bluetooth.stopDiscovery(function() { - // The page may get closed before discovery started, so ignore any - // 'Failed to stop discovery' errors. - if (chrome.runtime.lastError && - chrome.runtime.lastError.message != 'Failed to stop discovery') { - console.log( - 'Unexpected error calling bluetooth.stopDiscovery: ' + - chrome.runtime.lastError.message); - - } - }); - }, - - /** - * Creates, decorates and initializes the bluetooth device list. - * @private - */ - createDeviceList_: function() { - var deviceList = $('bluetooth-unpaired-devices-list'); - options.system.bluetooth.BluetoothDeviceList.decorate(deviceList); - this.deviceList_ = assertInstanceof(deviceList, - options.DeletableItemList); - } - }; - - /** - * Updates the dialog to show that device discovery has stopped. Updates the - * label text and hides/unhides the spinner. based on discovery state. - */ - BluetoothOptions.updateDiscoveryState = function(discovering) { - $('bluetooth-scanning-label').hidden = !discovering; - $('bluetooth-scanning-icon').hidden = !discovering; - $('bluetooth-scan-stopped-label').hidden = discovering; - }; - - /** - * If the "Add device" dialog is visible, dismiss it. - */ - BluetoothOptions.dismissOverlay = function() { - var page = BluetoothOptions.getInstance(); - if (page && page.visible) - PageManager.closeOverlay(); - }; - - // Export - return { - BluetoothOptions: BluetoothOptions - }; -});
diff --git a/chrome/browser/resources/options/chromeos/bluetooth_device_list.js b/chrome/browser/resources/options/chromeos/bluetooth_device_list.js deleted file mode 100644 index c7fcfd9..0000000 --- a/chrome/browser/resources/options/chromeos/bluetooth_device_list.js +++ /dev/null
@@ -1,342 +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. - -cr.define('options.system.bluetooth', function() { - /** @const */ var ArrayDataModel = cr.ui.ArrayDataModel; - /** @const */ var DeletableItem = options.DeletableItem; - /** @const */ var DeletableItemList = options.DeletableItemList; - /** @const */ var ListSingleSelectionModel = cr.ui.ListSingleSelectionModel; - - /** - * Bluetooth settings constants. - */ - function Constants() {} - - /** - * Creates a new bluetooth list item. - * @param {chrome.bluetooth.Device} device - * @constructor - * @extends {options.DeletableItem} - */ - function BluetoothListItem(device) { - var el = cr.doc.createElement('div'); - el.__proto__ = BluetoothListItem.prototype; - el.data = {}; - for (var key in device) - el.data[key] = device[key]; - el.decorate(); - // Only show the close button for paired devices, but not for connecting - // devices. - el.deletable = device.paired && !device.connecting; - return el; - } - - BluetoothListItem.prototype = { - __proto__: DeletableItem.prototype, - - /** - * Description of the Bluetooth device. - * @type {?chrome.bluetooth.Device} - */ - data: null, - - /** @override */ - decorate: function() { - DeletableItem.prototype.decorate.call(this); - var label = this.ownerDocument.createElement('div'); - label.className = 'bluetooth-device-label'; - this.classList.add('bluetooth-device'); - - var connecting = !!this.data.connecting; - var connected = !!this.data.connected; - var connectable = !!this.data.connectable; - var paired = !!this.data.paired; - - // There are four kinds of devices we want to distinguish: - // * Connecting devices: in bold with a "connecting" label, - // * Connected devices: in bold, - // * Paired, not connected but connectable devices: regular and - // * Paired, not connected and not connectable devices: grayed out. - this.connected = connecting || (paired && connected); - this.notconnectable = paired && !connecting && - !connected && !connectable; - // "paired" devices are those that are remembered but not connected. - this.paired = paired && !connected && connectable; - - var content = this.data.name; - // Update the device's label according to its state. A "connecting" device - // can be in the process of connecting and pairing, so we check connecting - // first. - if (connecting) { - content = loadTimeData.getStringF('bluetoothDeviceConnecting', - this.data.name); - } - label.textContent = content; - this.contentElement.appendChild(label); - }, - }; - - /** - * Class for displaying a list of Bluetooth devices. - * @constructor - * @extends {options.DeletableItemList} - */ - var BluetoothDeviceList = cr.ui.define('list'); - - BluetoothDeviceList.prototype = { - __proto__: DeletableItemList.prototype, - - /** - * Height of a list entry in px. - * @type {number} - * @private - */ - itemHeight_: 32, - - /** - * Width of a list entry in px. - * @type {number} - * @private - */ - itemWidth_: 400, - - /** @override */ - decorate: function() { - DeletableItemList.prototype.decorate.call(this); - // Force layout of all items even if not in the viewport to address - // errors in scroll positioning when the list is hidden during initial - // layout. The impact on performance should be minimal given that the - // list is not expected to grow very large. Fixed height items are also - // required to avoid caching incorrect sizes during layout of a hidden - // list. - this.autoExpands = true; - this.fixedHeight = true; - this.clear(); - this.selectionModel = new ListSingleSelectionModel(); - }, - - /** - * Adds a bluetooth device to the list of available devices. A check is - * made to see if the device is already in the list, in which case the - * existing device is updated. - * @param {!chrome.bluetooth.Device} device - * @return {boolean} True if the devies was successfully added or updated. - */ - appendDevice: function(device) { - var selectedDevice = this.getSelectedDevice_(); - var index = this.find(device.address); - if (index == undefined) { - this.dataModel.push(device); - this.redraw(); - } else { - this.dataModel.splice(index, 1, device); - this.redrawItem(index); - } - this.updateListVisibility_(); - if (selectedDevice) - this.setSelectedDevice_(selectedDevice); - return true; - }, - - /** - * Forces a revailidation of the list content. Deleting a single item from - * the list results in a stale cache requiring an invalidation. - * @param {string=} opt_selection Optional address of device to select - * after refreshing the list. - */ - refresh: function(opt_selection) { - // TODO(kevers): Investigate if the stale cache issue can be fixed in - // cr.ui.list. - var selectedDevice = opt_selection ? opt_selection : - this.getSelectedDevice_(); - this.invalidate(); - this.redraw(); - if (selectedDevice) - this.setSelectedDevice_(selectedDevice); - }, - - /** - * Retrieves the address of the selected device, or null if no device is - * selected. - * @return {(string|undefined)} Address of selected device or null. - * @private - */ - getSelectedDevice_: function() { - var selection = this.selectedItem; - if (selection) - return selection.address; - return undefined; - }, - - /** - * Selects the device with the matching address. - * @param {string} address The unique address of the device. - * @private - */ - setSelectedDevice_: function(address) { - var index = this.find(address); - if (index != undefined) - this.selectionModel.selectRange(index, index); - }, - - /** - * Perges all devices from the list. - */ - clear: function() { - this.dataModel = new ArrayDataModel([]); - this.redraw(); - this.updateListVisibility_(); - }, - - /** - * Returns the index of the list entry with the matching address. - * @param {string} address Unique address of the Bluetooth device. - * @return {number|undefined} Index of the matching entry or - * undefined if no match found. - */ - find: function(address) { - var size = this.dataModel.length; - for (var i = 0; i < size; i++) { - var entry = this.dataModel.item(i); - if (entry.address == address) - return i; - } - return undefined; - }, - - /** - * @override - * @param {chrome.bluetooth.Device} entry - */ - createItem: function(entry) { - return new BluetoothListItem(entry); - }, - - /** - * Overrides the default implementation, which is used to compute the - * size of an element in the list. The default implementation relies - * on adding a placeholder item to the list and fetching its size and - * position. This strategy does not work if an item is added to the list - * while it is hidden, as the computed metrics will all be zero in that - * case. - * @return {{height: number, marginTop: number, marginBottom: number, - * width: number, marginLeft: number, marginRight: number}} - * The height and width of the item, taking margins into account, - * and the margins themselves. - */ - measureItem: function() { - return { - height: this.itemHeight_, - marginTop: 0, - marginBottom: 0, - width: this.itemWidth_, - marginLeft: 0, - marginRight: 0 - }; - }, - - /** - * Override the default implementation to return a predetermined size, - * which in turns allows proper layout of items even if the list is hidden. - * @return {{height: number, width: number}} Dimensions of a single item in - * the list of bluetooth device. - * @private - */ - getDefaultItemSize_: function() { - return { - height: this.itemHeight_, - width: this.itemWidth_ - }; - }, - - /** - * Override base implementation of handleClick, which unconditionally - * removes the item. In this case, removal of the element is deferred - * pending confirmation from the Bluetooth adapter. - * @param {Event} e The click event object. - * @override - */ - handleClick: function(e) { - if (this.disabled) - return; - - var target = /** @type {HTMLElement} */(e.target); - if (!target.classList.contains('row-delete-button')) - return; - - var item = this.getListItemAncestor(target); - var selected = this.selectionModel.selectedIndex; - var index = this.getIndexOfListItem(item); - if (item && item.deletable) { - if (selected != index) - this.setSelectedDevice_(item.data.address); - // Device is busy until we hear back from the Bluetooth adapter. - // Prevent double removal request. - item.deletable = false; - // TODO(kevers): Provide visual feedback that the device is busy. - - // Inform the bluetooth adapter that we are disconnecting or - // forgetting the device. - var address = item.data.address; - if (item.connected) { - chrome.bluetoothPrivate.disconnectAll(address, function() { - if (chrome.runtime.lastError) { - options.BluetoothPairing.showMessage( - {message: 'bluetoothDisconnectFailed', address: address}); - } - }); - } else { - chrome.bluetoothPrivate.forgetDevice(address, function() { - if (chrome.runtime.lastError) { - options.BluetoothPairing.showMessage( - {message: 'bluetoothForgetFailed', address: address}); - } - }); - } - chrome.send('coreOptionsUserMetricsAction', - ['Options_BluetoothRemoveDevice']); - } - }, - - /** @override */ - deleteItemAtIndex: function(index) { - var selectedDevice = this.getSelectedDevice_(); - this.dataModel.splice(index, 1); - this.refresh(selectedDevice); - this.updateListVisibility_(); - }, - - /** - * If the list has an associated empty list placholder then update the - * visibility of the list and placeholder. - * @private - */ - updateListVisibility_: function() { - var empty = this.dataModel.length == 0; - var listPlaceHolderID = this.id + '-empty-placeholder'; - if ($(listPlaceHolderID)) { - if (this.hidden != empty) { - this.hidden = empty; - $(listPlaceHolderID).hidden = !empty; - this.refresh(); - } - } - }, - }; - - cr.defineProperty(BluetoothListItem, 'connected', cr.PropertyKind.BOOL_ATTR); - - cr.defineProperty(BluetoothListItem, 'paired', cr.PropertyKind.BOOL_ATTR); - - cr.defineProperty(BluetoothListItem, 'connecting', cr.PropertyKind.BOOL_ATTR); - - cr.defineProperty(BluetoothListItem, 'notconnectable', - cr.PropertyKind.BOOL_ATTR); - - return { - BluetoothListItem: BluetoothListItem, - BluetoothDeviceList: BluetoothDeviceList, - Constants: Constants - }; -});
diff --git a/chrome/browser/resources/options/chromeos/bluetooth_pair_device_overlay.html b/chrome/browser/resources/options/chromeos/bluetooth_pair_device_overlay.html deleted file mode 100644 index cc37aa1..0000000 --- a/chrome/browser/resources/options/chromeos/bluetooth_pair_device_overlay.html +++ /dev/null
@@ -1,33 +0,0 @@ -<div id="bluetooth-pairing" class="page" hidden> - <div id="bluetooth-pairing-close-button" class="close-button"></div> - <h1>$i18n{bluetoothAddDeviceTitle}</h1> - <div id="bluetooth-pairing-message-area" class="content-area"> - <div id="bluetooth-pairing-message-contents"> - <div id="bluetooth-pairing-instructions"></div> - <div id="bluetooth-pairing-passkey-display" hidden></div> - <div id="bluetooth-pairing-passkey-entry" hidden> - <input id="bluetooth-passkey" maxlength="6" type="text"> - </div> - <div id="bluetooth-pairing-pincode-entry" hidden> - <input id="bluetooth-pincode" maxlength="16" type="text"> - </div> - </div> - </div> - <div class="action-area button-strip"> - <button id="bluetooth-pair-device-cancel-button" type="reset" hidden> - $i18n{cancel} - </button> - <button id="bluetooth-pair-device-connect-button" type="reset" hidden> - $i18n{bluetoothConnectDevice} - </button> - <button id="bluetooth-pair-device-reject-button" type="reset" hidden> - $i18n{bluetoothRejectPasskey} - </button> - <button id="bluetooth-pair-device-accept-button" type="reset" hidden> - $i18n{bluetoothAcceptPasskey} - </button> - <button id="bluetooth-pair-device-dismiss-button" type="reset" hidden> - $i18n{bluetoothDismissError} - </button> - </div> -</div>
diff --git a/chrome/browser/resources/options/chromeos/bluetooth_pair_device_overlay.js b/chrome/browser/resources/options/chromeos/bluetooth_pair_device_overlay.js deleted file mode 100644 index 426de19..0000000 --- a/chrome/browser/resources/options/chromeos/bluetooth_pair_device_overlay.js +++ /dev/null
@@ -1,587 +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. - -/** - * Enumeration of possible states during pairing. The value associated with - * each state maps to a localized string in the global variable - * |loadTimeData|. - * @enum {string} - */ -var BluetoothPairingEventType = { - CONNECTING: 'bluetoothStartConnecting', - ENTER_PIN_CODE: 'bluetoothEnterPinCode', - ENTER_PASSKEY: 'bluetoothEnterPasskey', - REMOTE_PIN_CODE: 'bluetoothRemotePinCode', - REMOTE_PASSKEY: 'bluetoothRemotePasskey', - CONFIRM_PASSKEY: 'bluetoothConfirmPasskey', - CONNECT_FAILED: 'bluetoothConnectFailed', - CANCELED: 'bluetoothPairingCanceled', - DISMISSED: 'bluetoothPairingDismissed', // pairing dismissed (succeeded or - // canceled). - NOOP: '' // Update device but do not show or update the dialog. -}; - -/** - * @typedef {{pairing: (BluetoothPairingEventType|undefined), - * device: !chrome.bluetooth.Device, - * pincode: (string|undefined), - * passkey: (number|undefined), - * enteredKey: (number|undefined)}} - */ -var BluetoothPairingEvent; - -/** - * Returns a BluetoothPairingEventType corresponding to |event_type|. - * @param {!chrome.bluetoothPrivate.PairingEventType} event_type - * @return {BluetoothPairingEventType} - */ -function GetBluetoothPairingEvent(event_type) { - switch (event_type) { - case chrome.bluetoothPrivate.PairingEventType.REQUEST_PINCODE: - return BluetoothPairingEventType.ENTER_PIN_CODE; - case chrome.bluetoothPrivate.PairingEventType.DISPLAY_PINCODE: - return BluetoothPairingEventType.REMOTE_PIN_CODE; - case chrome.bluetoothPrivate.PairingEventType.REQUEST_PASSKEY: - return BluetoothPairingEventType.ENTER_PASSKEY; - case chrome.bluetoothPrivate.PairingEventType.DISPLAY_PASSKEY: - return BluetoothPairingEventType.REMOTE_PASSKEY; - case chrome.bluetoothPrivate.PairingEventType.KEYS_ENTERED: - return BluetoothPairingEventType.NOOP; - case chrome.bluetoothPrivate.PairingEventType.CONFIRM_PASSKEY: - return BluetoothPairingEventType.CONFIRM_PASSKEY; - case chrome.bluetoothPrivate.PairingEventType.REQUEST_AUTHORIZATION: - return BluetoothPairingEventType.NOOP; - case chrome.bluetoothPrivate.PairingEventType.COMPLETE: - return BluetoothPairingEventType.NOOP; - } - return BluetoothPairingEventType.NOOP; -} - -cr.define('options', function() { - /** @const */ var Page = cr.ui.pageManager.Page; - /** @const */ var PageManager = cr.ui.pageManager.PageManager; - - /** - * List of IDs for conditionally visible elements in the dialog. - * @type {Array<string>} - * @const - */ - var ELEMENTS = ['bluetooth-pairing-passkey-display', - 'bluetooth-pairing-passkey-entry', - 'bluetooth-pairing-pincode-entry', - 'bluetooth-pair-device-connect-button', - 'bluetooth-pair-device-cancel-button', - 'bluetooth-pair-device-accept-button', - 'bluetooth-pair-device-reject-button', - 'bluetooth-pair-device-dismiss-button']; - - /** - * Encapsulated handling of the Bluetooth device pairing page. - * @constructor - * @extends {cr.ui.pageManager.Page} - */ - function BluetoothPairing() { - Page.call(this, 'bluetoothPairing', - loadTimeData.getString('bluetoothOptionsPageTabTitle'), - 'bluetooth-pairing'); - } - - cr.addSingletonGetter(BluetoothPairing); - - BluetoothPairing.prototype = { - __proto__: Page.prototype, - - /** - * Device pairing event. - * @type {?BluetoothPairingEvent} - * @private - */ - event_: null, - - /** - * Can the dialog be programmatically dismissed. - * @type {boolean} - */ - dismissible_: true, - - /** @override */ - initializePage: function() { - Page.prototype.initializePage.call(this); - var self = this; - $('bluetooth-pair-device-cancel-button').onclick = function() { - PageManager.closeOverlay(); - }; - $('bluetooth-pair-device-reject-button').onclick = function() { - var options = { - device: self.event_.device, - response: chrome.bluetoothPrivate.PairingResponse.REJECT - }; - chrome.bluetoothPrivate.setPairingResponse(options); - self.event_.pairing = BluetoothPairingEventType.DISMISSED; - PageManager.closeOverlay(); - }; - $('bluetooth-pair-device-connect-button').onclick = function() { - // Prevent sending a 'connect' command twice. - $('bluetooth-pair-device-connect-button').disabled = true; - - var options = { - device: self.event_.device, - response: chrome.bluetoothPrivate.PairingResponse.CONFIRM - }; - var passkey = self.event_.passkey; - if (passkey) { - options.passkey = passkey; - } else if (!$('bluetooth-pairing-passkey-entry').hidden) { - options.passkey = parseInt($('bluetooth-passkey').value, 10); - } else if (!$('bluetooth-pairing-pincode-entry').hidden) { - options.pincode = $('bluetooth-pincode').value; - } else { - BluetoothPairing.connect(self.event_.device); - return; - } - chrome.bluetoothPrivate.setPairingResponse(options); - var event = /** @type {!BluetoothPairingEvent} */ ({ - pairing: BluetoothPairingEventType.CONNECTING, - device: self.event_.device - }); - BluetoothPairing.showDialog(event); - }; - $('bluetooth-pair-device-accept-button').onclick = function() { - var options = { - device: self.event_.device, - response: chrome.bluetoothPrivate.PairingResponse.CONFIRM - }; - chrome.bluetoothPrivate.setPairingResponse(options); - // Prevent sending a 'accept' command twice. - $('bluetooth-pair-device-accept-button').disabled = true; - }; - $('bluetooth-pair-device-dismiss-button').onclick = function() { - PageManager.closeOverlay(); - }; - $('bluetooth-passkey').oninput = function() { - var inputField = $('bluetooth-passkey'); - var value = inputField.value; - // Note that using <input type="number"> is insufficient to restrict - // the input as it allows negative numbers and does not limit the - // number of charactes typed even if a range is set. Furthermore, - // it sometimes produces strange repaint artifacts. - var filtered = value.replace(/[^0-9]/g, ''); - if (filtered != value) - inputField.value = filtered; - $('bluetooth-pair-device-connect-button').disabled = - inputField.value.length == 0; - }; - $('bluetooth-pincode').oninput = function() { - $('bluetooth-pair-device-connect-button').disabled = - $('bluetooth-pincode').value.length == 0; - }; - $('bluetooth-passkey').addEventListener('keydown', - this.keyDownEventHandler_.bind(this)); - $('bluetooth-pincode').addEventListener('keydown', - this.keyDownEventHandler_.bind(this)); - $('bluetooth-pairing-close-button').addEventListener('click', - this.onClose_.bind(this)); - }, - - /** @override */ - didClosePage: function() { - if (this.event_ && - this.event_.pairing != BluetoothPairingEventType.DISMISSED && - this.event_.pairing != BluetoothPairingEventType.CONNECT_FAILED) { - this.event_.pairing = BluetoothPairingEventType.CANCELED; - var options = { - device: this.event_.device, - response: chrome.bluetoothPrivate.PairingResponse.CANCEL - }; - chrome.bluetoothPrivate.setPairingResponse(options); - } - }, - - /** - * Override to prevent showing the overlay if the Bluetooth device details - * have not been specified. Prevents showing an empty dialog if the user - * quits and restarts Chrome while in the process of pairing with a device. - * @return {boolean} True if the overlay can be displayed. - */ - canShowPage: function() { - return !!(this.event_ && this.event_.device.address && - this.event_.pairing); - }, - - /** - * Sets input focus on the passkey or pincode field if appropriate. - */ - didShowPage: function() { - if (!$('bluetooth-pincode').hidden) - $('bluetooth-pincode').focus(); - else if (!$('bluetooth-passkey').hidden) - $('bluetooth-passkey').focus(); - }, - - /** - * Configures the overlay for pairing a device. - * @param {!BluetoothPairingEvent} event - * @param {boolean=} opt_notDismissible - */ - update: function(event, opt_notDismissible) { - assert(event); - assert(event.device); - if (this.event_ == undefined || - this.event_.device.address != event.device.address) { - // New event or device, create a new BluetoothPairingEvent. - this.event_ = - /** @type {BluetoothPairingEvent} */ ({device: event.device}); - } else { - // Update to an existing event; just update |device| in case it changed. - this.event_.device = event.device; - } - - if (event.pairing) - this.event_.pairing = event.pairing; - - if (!this.event_.pairing) - return; - - if (this.event_.pairing == BluetoothPairingEventType.CANCELED) { - // If we receive an update after canceling a pairing (e.g. a key - // press), ignore it and clear the device so that future updates for - // the device will also be ignored. - this.event_.device.address = ''; - return; - } - - if (event.pincode != undefined) - this.event_.pincode = event.pincode; - if (event.passkey != undefined) - this.event_.passkey = event.passkey; - if (event.enteredKey != undefined) - this.event_.enteredKey = event.enteredKey; - - // Update the list model (in case, e.g. the name changed). - if (this.event_.device.name) { - var list = $('bluetooth-unpaired-devices-list'); - if (list) { // May be undefined in tests. - var index = list.find(this.event_.device.address); - if (index != undefined) - list.dataModel.splice(index, 1, this.event_.device); - } - } - - // Update the pairing instructions. - var instructionsEl = assert($('bluetooth-pairing-instructions')); - this.clearElement_(instructionsEl); - this.dismissible_ = opt_notDismissible !== true; - var message = loadTimeData.getString(this.event_.pairing); - assert(typeof this.event_.device.name == 'string'); - message = message.replace( - '%1', /** @type {string} */(this.event_.device.name)); - instructionsEl.textContent = message; - - // Update visibility of dialog elements. - if (this.event_.passkey) { - this.updatePasskey_(String(this.event_.passkey)); - if (this.event_.pairing == BluetoothPairingEventType.CONFIRM_PASSKEY) { - // Confirming a match between displayed passkeys. - this.displayElements_(['bluetooth-pairing-passkey-display', - 'bluetooth-pair-device-accept-button', - 'bluetooth-pair-device-reject-button']); - $('bluetooth-pair-device-accept-button').disabled = false; - } else { - // Remote entering a passkey. - this.displayElements_(['bluetooth-pairing-passkey-display', - 'bluetooth-pair-device-cancel-button']); - } - } else if (this.event_.pincode) { - this.updatePasskey_(String(this.event_.pincode)); - this.displayElements_(['bluetooth-pairing-passkey-display', - 'bluetooth-pair-device-cancel-button']); - } else if (this.event_.pairing == - BluetoothPairingEventType.ENTER_PIN_CODE) { - // Prompting the user to enter a PIN code. - this.displayElements_(['bluetooth-pairing-pincode-entry', - 'bluetooth-pair-device-connect-button', - 'bluetooth-pair-device-cancel-button']); - $('bluetooth-pincode').value = ''; - } else if (this.event_.pairing == - BluetoothPairingEventType.ENTER_PASSKEY) { - // Prompting the user to enter a passkey. - this.displayElements_(['bluetooth-pairing-passkey-entry', - 'bluetooth-pair-device-connect-button', - 'bluetooth-pair-device-cancel-button']); - $('bluetooth-passkey').value = ''; - } else if (this.event_.pairing == BluetoothPairingEventType.CONNECTING) { - // Starting the pairing process. - this.displayElements_(['bluetooth-pair-device-cancel-button']); - } else { - // Displaying an error message. - this.displayElements_(['bluetooth-pair-device-dismiss-button']); - } - // User is required to enter a passkey or pincode before the connect - // button can be enabled. The 'oninput' methods for the input fields - // determine when the connect button becomes active. - $('bluetooth-pair-device-connect-button').disabled = true; - }, - - /** - * Handles the ENTER key for the passkey or pincode entry field. - * @param {Event} event A keydown event. - * @private - */ - keyDownEventHandler_: function(event) { - /** @const */ var ENTER_KEY_CODE = 13; - if (event.keyCode == ENTER_KEY_CODE) { - var button = $('bluetooth-pair-device-connect-button'); - if (!button.hidden) - button.click(); - } - }, - - /** - * Handles the click event on the close button. - * @param {Event} event A click down event. - * @private - */ - onClose_: function(event) { - event.preventDefault(); - chrome.send('dialogClose'); - }, - - /** - * Updates the visibility of elements in the dialog. - * @param {Array<string>} list List of conditionally visible elements that - * are to be made visible. - * @private - */ - displayElements_: function(list) { - var enabled = {}; - for (var i = 0; i < list.length; i++) { - var key = list[i]; - enabled[key] = true; - } - for (var i = 0; i < ELEMENTS.length; i++) { - var key = ELEMENTS[i]; - $(key).hidden = !enabled[key]; - } - }, - - /** - * Removes all children from an element. - * @param {!Element} element Target element to clear. - */ - clearElement_: function(element) { - var child = element.firstChild; - while (child) { - element.removeChild(child); - child = element.firstChild; - } - }, - - /** - * Formats an element for displaying the passkey or PIN code. - * @param {string} key Passkey or PIN to display. - */ - updatePasskey_: function(key) { - var passkeyEl = assert($('bluetooth-pairing-passkey-display')); - var keyClass = - (this.event_.pairing == BluetoothPairingEventType.REMOTE_PASSKEY || - this.event_.pairing == BluetoothPairingEventType.REMOTE_PIN_CODE) ? - 'bluetooth-keyboard-button' : - 'bluetooth-passkey-char'; - this.clearElement_(passkeyEl); - // Passkey should always have 6 digits. - key = '000000'.substring(0, 6 - key.length) + key; - var progress = this.event_.enteredKey; - for (var i = 0; i < key.length; i++) { - var keyEl = document.createElement('span'); - keyEl.textContent = key.charAt(i); - keyEl.className = keyClass; - if (progress != undefined) { - if (i < progress) - keyEl.classList.add('key-typed'); - else if (i == progress) - keyEl.classList.add('key-next'); - else - keyEl.classList.add('key-untyped'); - } - passkeyEl.appendChild(keyEl); - } - if (this.event_.pairing == BluetoothPairingEventType.REMOTE_PASSKEY || - this.event_.pairing == BluetoothPairingEventType.REMOTE_PIN_CODE) { - // Add enter key. - var label = loadTimeData.getString('bluetoothEnterKey'); - var keyEl = document.createElement('span'); - keyEl.textContent = label; - keyEl.className = keyClass; - keyEl.id = 'bluetooth-enter-key'; - if (progress != undefined) { - if (progress > key.length) - keyEl.classList.add('key-typed'); - else if (progress == key.length) - keyEl.classList.add('key-next'); - else - keyEl.classList.add('key-untyped'); - } - passkeyEl.appendChild(keyEl); - } - passkeyEl.hidden = false; - }, - }; - - /** - * Configures the device pairing instructions and displays the pairing - * overlay. - * @param {!BluetoothPairingEvent} event - * @param {boolean=} opt_notDismissible If set to true, the dialog can not - * be dismissed. - */ - BluetoothPairing.showDialog = function(event, opt_notDismissible) { - BluetoothPairing.getInstance().update(event, opt_notDismissible); - PageManager.showPageByName('bluetoothPairing', false); - }; - - - /** - * Handles bluetoothPrivate onPairing events. - * @param {!chrome.bluetoothPrivate.PairingEvent} event - */ - BluetoothPairing.onBluetoothPairingEvent = function(event) { - var dialog = BluetoothPairing.getInstance(); - if (!dialog.event_ || dialog.event_.device.address != event.device.address) - return; // Ignore events not associated with an active connect or pair. - var pairingEvent = /** @type {!BluetoothPairingEvent} */ ({ - pairing: GetBluetoothPairingEvent(event.pairing), - device: event.device, - pincode: event.pincode, - passkey: event.passkey, - enteredKey: event.enteredKey - }); - dialog.update(pairingEvent); - PageManager.showPageByName('bluetoothPairing', false); - }; - - /** - * Displays a message from the Bluetooth adapter. - * @param {{message: string, address: string}} data Data for constructing the - * message. |data.message| is the name of message to show. |data.address| - * is the device address. - */ - BluetoothPairing.showMessage = function(data) { - /** @type {string} */ var name = data.address; - if (name.length == 0) - return; - var dialog = BluetoothPairing.getInstance(); - if (dialog.event_ && name == dialog.event_.device.address && - dialog.event_.pairing == BluetoothPairingEventType.CANCELED) { - // Do not show any error message after cancelation of the pairing. - return; - } - - var list = $('bluetooth-paired-devices-list'); - if (list) { - var index = list.find(name); - if (index == undefined) { - list = $('bluetooth-unpaired-devices-list'); - index = list.find(name); - } - if (index != undefined) { - var entry = list.dataModel.item(index); - if (entry && entry.name) - name = /** @type {string} */ (entry.name); - } - } - var event = /** @type {!BluetoothPairingEvent} */ ({ - pairing: /** @type {BluetoothPairingEventType} */ (data.message), - device: /** @type {!chrome.bluetooth.Device} */ ({ - name: name, - address: data.address, - }) - }); - BluetoothPairing.showDialog(event, true /* not dismissible */); - }; - - /** - * Sends a connect request to the bluetoothPrivate API. If there is an error - * the pairing dialog will be shown with the error message. - * @param {!chrome.bluetooth.Device} device - * @param {boolean=} opt_showConnecting If true, show 'connecting' message in - * the pairing dialog. - */ - BluetoothPairing.connect = function(device, opt_showConnecting) { - if (opt_showConnecting) { - var event = /** @type {!BluetoothPairingEvent} */ ( - {pairing: BluetoothPairingEventType.CONNECTING, device: device}); - BluetoothPairing.showDialog(event); - } - var address = device.address; - chrome.bluetoothPrivate.connect(address, function(result) { - BluetoothPairing.connectCompleted_(address, result); - }); - }; - - /** - * Connect request completion callback. - * @param {string} address - * @param {chrome.bluetoothPrivate.ConnectResultType} result - */ - BluetoothPairing.connectCompleted_ = function(address, result) { - var message; - if (chrome.runtime.lastError) { - var errorMessage = chrome.runtime.lastError.message; - if (errorMessage != 'Connect failed') { - console.error('bluetoothPrivate.connect: Unexpected error for: ' + - address + ': ' + errorMessage); - } - } - switch (result) { - case chrome.bluetoothPrivate.ConnectResultType.SUCCESS: - case chrome.bluetoothPrivate.ConnectResultType.ALREADY_CONNECTED: - BluetoothPairing.dismissDialog(); - return; - case chrome.bluetoothPrivate.ConnectResultType.UNKNOWN_ERROR: - message = 'bluetoothConnectUnknownError'; - break; - case chrome.bluetoothPrivate.ConnectResultType.IN_PROGRESS: - message = 'bluetoothConnectInProgress'; - break; - case chrome.bluetoothPrivate.ConnectResultType.FAILED: - message = 'bluetoothConnectFailed'; - break; - case chrome.bluetoothPrivate.ConnectResultType.AUTH_FAILED: - message = 'bluetoothConnectAuthFailed'; - break; - case chrome.bluetoothPrivate.ConnectResultType.AUTH_CANCELED: - message = 'bluetoothConnectAuthCanceled'; - break; - case chrome.bluetoothPrivate.ConnectResultType.AUTH_REJECTED: - message = 'bluetoothConnectAuthRejected'; - break; - case chrome.bluetoothPrivate.ConnectResultType.AUTH_TIMEOUT: - message = 'bluetoothConnectAuthTimeout'; - break; - case chrome.bluetoothPrivate.ConnectResultType.UNSUPPORTED_DEVICE: - message = 'bluetoothConnectUnsupportedDevice'; - break; - } - if (message) - BluetoothPairing.showMessage({message: message, address: address}); - }; - - /** - * Closes the Bluetooth pairing dialog. - */ - BluetoothPairing.dismissDialog = function() { - var overlay = PageManager.getTopmostVisiblePage(); - var dialog = BluetoothPairing.getInstance(); - if (overlay == dialog && dialog.dismissible_) { - if (dialog.event_) - dialog.event_.pairing = BluetoothPairingEventType.DISMISSED; - PageManager.closeOverlay(); - } - }; - - // Export - return { - BluetoothPairing: BluetoothPairing - }; -});
diff --git a/chrome/browser/resources/options/chromeos/browser_options.css b/chrome/browser/resources/options/chromeos/browser_options.css deleted file mode 100644 index e02cae24..0000000 --- a/chrome/browser/resources/options/chromeos/browser_options.css +++ /dev/null
@@ -1,7 +0,0 @@ -/* Copyright 2013 The Chromium Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. */ - -#sync-section { - min-height: 64px; -}
diff --git a/chrome/browser/resources/options/chromeos/change_picture_options.css b/chrome/browser/resources/options/chromeos/change_picture_options.css deleted file mode 100644 index a93e591..0000000 --- a/chrome/browser/resources/options/chromeos/change_picture_options.css +++ /dev/null
@@ -1,177 +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. */ - -#user-images-area { - display: -webkit-box; -} - -#user-image-grid { - -webkit-user-drag: none; - height: 264px; - margin: 10px; - outline: none; - /* Necessary for correct metrics calculation by grid.js. */ - overflow: hidden; - padding: 0; - user-select: none; - width: 530px; -} - -#user-image-grid * { - margin: 0; - padding: 0; -} - -#user-image-grid img { - background-color: white; - height: 64px; - vertical-align: middle; - width: 64px; -} - -#user-image-grid > li { - border: 1px solid rgba(0, 0, 0, 0.15); - border-radius: 4px; - display: inline-block; - margin: 8px; - padding: 3px; -} - -#user-image-grid [selected] { - border: 2px solid rgb(0, 102, 204); - padding: 2px; -} - -/* #user-image-preview can have the following classes: - * .default-image: one of the default images is selected (including the grey - * silhouette); - * .profile-image: profile image is selected; - * .online: camera is streaming video; - * .camera: camera (live or photo) is selected; - * .live: camera is in live mode (no photo taken yet/last photo removed). */ - -#user-image-preview { - margin: 18px 10px 0 0; - max-width: 220px; - position: relative; -} - -#user-image-preview .perspective-box { - border: solid 1px #cacaca; - border-radius: 4px; - padding: 3px; - perspective: 600px; - width: 220px; -} - -#user-image-preview-img { - background: white; - border: solid 1px #cacaca; - border-radius: 4px; - max-height: 220px; - max-width: 220px; - padding: 3px; -} - -.camera.live #user-image-preview-img { - display: none; -} - -.camera.flip-x #user-image-preview-img { - transform: rotateY(180deg); -} - -.user-image-stream-area { - display: none; - position: relative; -} - -.camera.live .user-image-stream-area { - display: block; -} - -#user-image-stream-crop { - height: 220px; - overflow: hidden; - position: relative; - width: 220px; -} - -.flip-x #user-image-stream-crop { - transform: rotateY(180deg); -} - -/* TODO(ivankr): specify dimensions from real capture size. */ -.user-image-stream { - border: solid 1px #cacaca; - height: 220px; - /* Center image for 4:3 aspect ratio. */ - left: -16.6%; - position: absolute; - visibility: hidden; -} - -.online .user-image-stream { - visibility: visible; -} - -.user-image-stream-area .spinner { - display: none; - height: 44px; - left: 50%; - margin: -22px 0 0 -22px; - position: absolute; - top: 50%; - width: 44px; -} - -.camera.live:not(.online) .user-image-stream-area .spinner { - display: block; -} - -#flip-photo { - background: url(chrome://theme/IDR_MIRROR_FLIP) no-repeat; - border: none; - bottom: 44px; /* 8px + image bottom. */ - display: block; - height: 32px; - position: absolute; - right: 8px; - width: 32px; -} - -html[dir=rtl] #flip-photo { - left: 8px; - right: auto; -} - -#discard-photo, -#take-photo { - display: none; - height: 25px; - margin: 4px; - padding: 0; - width: 220px; -} - -.camera:not(.live) #discard-photo { - background: url(chrome://theme/IDR_USER_IMAGE_RECYCLE) - no-repeat center center; - display: block; -} - -.camera.live.online #take-photo { - background: url(chrome://theme/IDR_USER_IMAGE_CAPTURE) - no-repeat center -1px; - display: block; -} - -#user-image-attribution { - -webkit-padding-start: 34px; - line-height: 26px; -} - -#user-image-author-website { - -webkit-padding-start: 5px; -}
diff --git a/chrome/browser/resources/options/chromeos/change_picture_options.html b/chrome/browser/resources/options/chromeos/change_picture_options.html deleted file mode 100644 index 55f4bcb..0000000 --- a/chrome/browser/resources/options/chromeos/change_picture_options.html +++ /dev/null
@@ -1,39 +0,0 @@ -<div id="change-picture-page" class="page" hidden> - <div class="close-button"></div> - <h1>$i18n{changePicturePage}</h1> - <div class="content-area"> - <div>$i18n{changePicturePageDescription}</div> - <div id="user-images-area"> - <grid id="user-image-grid" class="user-image-picker" tabindex="1"></grid> - <div id="user-image-preview"> - <img id="user-image-preview-img" alt="$i18n{previewAltText}"> - <div class="user-image-stream-area"> - <div class="perspective-box"> - <div id="user-image-stream-crop"> - <video class="user-image-stream" autoplay></video> - </div> - </div> - <div class="spinner"></div> - </div> - <button id="discard-photo" title="$i18n{discardPhoto}" tabindex="2"> - </button> - <button id="take-photo" title="$i18n{takePhoto}" tabindex="2"> - </button> - <button id="flip-photo" class="custom-appearance" - title="$i18n{flipPhoto}" tabindex="1"></button> - </div> - </div> - <div id="user-image-attribution"> - <span>$i18n{authorCredit}</span> - <strong id="user-image-author-name"></strong> - <a id="user-image-author-website" target="_blank"></a> - </div> - </div> - <div class="action-area"> - <div class="button-strip"> - <button id="change-picture-overlay-confirm" tabindex="2"> - $i18n{done} - </button> - </div> - </div> -</div>
diff --git a/chrome/browser/resources/options/chromeos/change_picture_options.js b/chrome/browser/resources/options/chromeos/change_picture_options.js deleted file mode 100644 index 5034ca2..0000000 --- a/chrome/browser/resources/options/chromeos/change_picture_options.js +++ /dev/null
@@ -1,331 +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. - -cr.define('options', function() { - var Page = cr.ui.pageManager.Page; - var PageManager = cr.ui.pageManager.PageManager; - var UserImagesGrid = options.UserImagesGrid; - var ButtonImages = UserImagesGrid.ButtonImages; - - /** - * Array of button URLs used on this page. - * @type {Array<string>} - * @const - */ - var ButtonImageUrls = [ - ButtonImages.TAKE_PHOTO, - ButtonImages.CHOOSE_FILE - ]; - - ///////////////////////////////////////////////////////////////////////////// - // ChangePictureOptions class: - - /** - * Encapsulated handling of ChromeOS change picture options page. - * @constructor - * @extends {cr.ui.pageManager.Page} - */ - function ChangePictureOptions() { - Page.call(this, 'changePicture', - loadTimeData.getString('changePicturePage'), - 'change-picture-page'); - } - - cr.addSingletonGetter(ChangePictureOptions); - - ChangePictureOptions.prototype = { - // Inherit ChangePictureOptions from Page. - __proto__: Page.prototype, - - /** @override */ - initializePage: function() { - Page.prototype.initializePage.call(this); - - var imageGrid = $('user-image-grid'); - UserImagesGrid.decorate(imageGrid); - - // Preview image will track the selected item's URL. - var previewElement = $('user-image-preview'); - previewElement.oncontextmenu = function(e) { e.preventDefault(); }; - - imageGrid.previewElement = previewElement; - imageGrid.selectionType = 'default'; - imageGrid.flipPhotoElement = $('flip-photo'); - - imageGrid.addEventListener('select', - this.handleImageSelected_.bind(this)); - imageGrid.addEventListener('activate', - this.handleImageActivated_.bind(this)); - imageGrid.addEventListener('phototaken', - this.handlePhotoTaken_.bind(this)); - imageGrid.addEventListener('photoupdated', - this.handlePhotoTaken_.bind(this)); - - // Add the "Choose file" button. - imageGrid.addItem(ButtonImages.CHOOSE_FILE, - loadTimeData.getString('chooseFile'), - this.handleChooseFile_.bind(this)).type = 'file'; - - // Profile image data. - this.profileImage_ = imageGrid.addItem( - ButtonImages.PROFILE_PICTURE, - loadTimeData.getString('profilePhotoLoading')); - this.profileImage_.type = 'profile'; - - // Set the title for camera item in the grid. - imageGrid.setCameraTitles( - loadTimeData.getString('takePhoto'), - loadTimeData.getString('photoFromCamera')); - - $('take-photo').addEventListener( - 'click', this.handleTakePhoto_.bind(this)); - $('discard-photo').addEventListener( - 'click', this.handleDiscardPhoto_.bind(this)); - - // Toggle 'animation' class for the duration of WebKit transition. - $('flip-photo').addEventListener( - 'click', this.handleFlipPhoto_.bind(this)); - $('user-image-stream-crop').addEventListener( - 'transitionend', function(e) { - previewElement.classList.remove('animation'); - }); - $('user-image-preview-img').addEventListener( - 'transitionend', function(e) { - previewElement.classList.remove('animation'); - }); - - // Old user image data (if present). - this.oldImage_ = null; - - $('change-picture-overlay-confirm').addEventListener( - 'click', this.closeOverlay_.bind(this)); - - chrome.send('onChangePicturePageInitialized'); - }, - - /** @override */ - didShowPage: function() { - var imageGrid = $('user-image-grid'); - // Reset camera element. - imageGrid.cameraImage = null; - imageGrid.updateAndFocus(); - chrome.send('onChangePicturePageShown'); - }, - - /** @override */ - willHidePage: function() { - var imageGrid = $('user-image-grid'); - imageGrid.blur(); // Make sure the image grid is not active. - imageGrid.stopCamera(); - if (this.oldImage_) { - imageGrid.removeItem(this.oldImage_); - this.oldImage_ = null; - } - chrome.send('onChangePicturePageHidden'); - }, - - /** - * Either willHidePage or didClosePage may be called depending on the way - * the page was closed. - * @override - */ - didClosePage: function() { - this.willHidePage(); - }, - - /** - * Closes the overlay, returning to the main settings page. - * @private - */ - closeOverlay_: function() { - if (!$('change-picture-page').hidden) - PageManager.closeOverlay(); - }, - - /** - * Handle camera-photo flip. - */ - handleFlipPhoto_: function() { - var imageGrid = $('user-image-grid'); - imageGrid.previewElement.classList.add('animation'); - imageGrid.flipPhoto = !imageGrid.flipPhoto; - var flipMessageId = imageGrid.flipPhoto ? - 'photoFlippedAccessibleText' : 'photoFlippedBackAccessibleText'; - announceAccessibleMessage(loadTimeData.getString(flipMessageId)); - }, - - /** - * Handles "Take photo" button click. - * @private - */ - handleTakePhoto_: function() { - $('user-image-grid').takePhoto(); - chrome.send('takePhoto'); - }, - - /** - * Handle photo captured event. - * @param {Event} e Event with 'dataURL' property containing a data URL. - */ - handlePhotoTaken_: function(e) { - chrome.send('photoTaken', [e.dataURL]); - announceAccessibleMessage( - loadTimeData.getString('photoCaptureAccessibleText')); - }, - - /** - * Handles "Discard photo" button click. - * @private - */ - handleDiscardPhoto_: function() { - $('user-image-grid').discardPhoto(); - chrome.send('discardPhoto'); - announceAccessibleMessage( - loadTimeData.getString('photoDiscardAccessibleText')); - }, - - /** - * Handles "Choose a file" button activation. - * @private - */ - handleChooseFile_: function() { - chrome.send('chooseFile'); - this.closeOverlay_(); - }, - - /** - * Handles image selection change. - * @param {Event} e Selection change Event. - * @private - */ - handleImageSelected_: function(e) { - var imageGrid = $('user-image-grid'); - var url = imageGrid.selectedItemUrl; - - // Flip button available only for camera picture. - imageGrid.flipPhotoElement.hidden = - imageGrid.selectionType != 'camera'; - // Ignore selection change caused by program itself and selection of one - // of the action buttons. - if (!imageGrid.inProgramSelection && - url != ButtonImages.TAKE_PHOTO && url != ButtonImages.CHOOSE_FILE) { - chrome.send('selectImage', [url, imageGrid.selectionType]); - } - // Start/stop camera on (de)selection. - if (!imageGrid.inProgramSelection && - imageGrid.selectionType != e.oldSelectionType) { - if (imageGrid.selectionType == 'camera') { - imageGrid.startCamera( - function() { - // Start capture if camera is still the selected item. - return imageGrid.selectedItem == imageGrid.cameraImage; - }); - } else { - imageGrid.stopCamera(); - } - } - // Update image attribution text. - var image = imageGrid.selectedItem; - $('user-image-author-name').textContent = image.author; - $('user-image-author-website').textContent = image.website; - $('user-image-author-website').href = image.website; - $('user-image-attribution').style.visibility = - (image.author || image.website) ? 'visible' : 'hidden'; - }, - - /** - * Handles image activation (by pressing Enter). - * @private - */ - handleImageActivated_: function() { - switch ($('user-image-grid').selectedItemUrl) { - case ButtonImages.TAKE_PHOTO: - this.handleTakePhoto_(); - break; - case ButtonImages.CHOOSE_FILE: - this.handleChooseFile_(); - break; - default: - this.closeOverlay_(); - break; - } - }, - - /** - * Adds or updates old user image taken from file/camera (neither a profile - * image nor a default one). - * @param {string} imageUrl Old user image, as data or internal URL. - * @private - */ - setOldImage_: function(imageUrl) { - var imageGrid = $('user-image-grid'); - if (this.oldImage_) { - this.oldImage_ = imageGrid.updateItem(this.oldImage_, imageUrl); - } else { - // Insert next to the profile image. - var pos = imageGrid.indexOf(this.profileImage_) + 1; - this.oldImage_ = imageGrid.addItem(imageUrl, undefined, undefined, pos); - this.oldImage_.type = 'old'; - imageGrid.selectedItem = this.oldImage_; - } - }, - - /** - * Updates user's profile image. - * @param {string} imageUrl Profile image, encoded as data URL. - * @param {boolean} select If true, profile image should be selected. - * @private - */ - setProfileImage_: function(imageUrl, select) { - var imageGrid = $('user-image-grid'); - this.profileImage_ = imageGrid.updateItem( - this.profileImage_, imageUrl, loadTimeData.getString('profilePhoto')); - if (select) - imageGrid.selectedItem = this.profileImage_; - }, - - /** - * Selects user image with the given URL. - * @param {string} url URL of the image to select. - * @private - */ - setSelectedImage_: function(url) { - $('user-image-grid').selectedItemUrl = url; - }, - - /** - * @param {boolean} present Whether camera is detected. - */ - setCameraPresent_: function(present) { - $('user-image-grid').cameraPresent = present; - }, - - /** - * Appends default images to the image grid. Should only be called once. - * @param {Array<{url: string, author: string, website: string}>} - * imagesData An array of default images data, including URL, author and - * website. - * @private - */ - setDefaultImages_: function(imagesData) { - $('user-image-grid').setDefaultImages(imagesData); - }, - }; - - // Forward public APIs to private implementations. - cr.makePublic(ChangePictureOptions, [ - 'closeOverlay', - 'setCameraPresent', - 'setDefaultImages', - 'setOldImage', - 'setProfileImage', - 'setSelectedImage', - ]); - - // Export - return { - ChangePictureOptions: ChangePictureOptions - }; - -});
diff --git a/chrome/browser/resources/options/chromeos/display_layout.js b/chrome/browser/resources/options/chromeos/display_layout.js deleted file mode 100644 index fe72812..0000000 --- a/chrome/browser/resources/options/chromeos/display_layout.js +++ /dev/null
@@ -1,456 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -cr.exportPath('options'); - -/** - * Enumeration of display layout. These values must match the C++ values in - * ash::DisplayController. - * @enum {number} - */ -options.DisplayLayoutType = { - TOP: 0, - RIGHT: 1, - BOTTOM: 2, - LEFT: 3 -}; - -/** - * @typedef {{ - * left: number, - * top: number, - * width: number, - * height: number - * }} - */ -options.DisplayBounds; - -/** - * @typedef {{ - * x: number, - * y: number - * }} - */ -options.DisplayPosition; - -cr.define('options', function() { - 'use strict'; - - /** - * Snaps the region [point, width] to [basePoint, baseWidth] if - * the [point, width] is close enough to the base's edge. - * @param {number} point The starting point of the region. - * @param {number} width The width of the region. - * @param {number} basePoint The starting point of the base region. - * @param {number} baseWidth The width of the base region. - * @param {number=} opt_snapDistance Provide to override the snap distance. - * 0 means snap at any distance. - * @return {number} The moved point. Returns the point itself if it doesn't - * need to snap to the edge. - * @private - */ - function snapToEdge_(point, width, basePoint, baseWidth, opt_snapDistance) { - // If the edge of the region is smaller than this, it will snap to the - // base's edge. - /** @const */ var SNAP_DISTANCE_PX = 16; - var snapDist; - if (opt_snapDistance !== undefined) - snapDist = opt_snapDistance; - else - snapDist = SNAP_DISTANCE_PX; - - var startDiff = Math.abs(point - basePoint); - var endDiff = Math.abs(point + width - (basePoint + baseWidth)); - // Prefer the closer one if both edges are close enough. - if ((!snapDist || startDiff < snapDist) && startDiff < endDiff) - return basePoint; - else if (!snapDist || endDiff < snapDist) - return basePoint + baseWidth - width; - - return point; - } - - /** - * @constructor - * @param {string} id - * @param {string} name - * @param {!options.DisplayBounds} bounds - * @param {!options.DisplayLayoutType|undefined} layoutType - * @param {number|undefined} offset - * @param {string|undefined} parentId - * @return {!options.DisplayLayout} - */ - function DisplayLayout(id, name, bounds, layoutType, offset, parentId) { - this.bounds = bounds; - this.id = id; - if (layoutType != undefined) - this.layoutType = layoutType; - this.name = name; - if (offset != undefined) - this.offset = offset; - this.originalDivOffsets = {x: 0, y: 0}; - if (parentId != undefined) - this.parentId = parentId; - } - - // Class describing a display layout. - DisplayLayout.prototype = { - /** @type {?options.DisplayBounds} */ - bounds: null, - - /** @type {?HTMLElement} */ - div: null, - - /** @type {string} */ - id: '', - - /** @type {options.DisplayLayoutType} */ - layoutType: options.DisplayLayoutType.TOP, - - /** @type {string} */ - name: '', - - /** @type {number} */ - offset: 0, - - /** @type {?options.DisplayPosition} */ - originalDivOffsets: null, - - /** @type {string} */ - parentId: '', - - /** - * Calculates the div layout for displayLayout. - * @param {?options.DisplayPosition} offset - * @param {number} scale - * @param {?options.DisplayLayout} parentLayout - */ - layoutDivFromBounds: function(offset, scale, parentLayout) { - assert(offset); - var div = this.div; - var bounds = this.bounds; - - div.style.width = Math.floor(bounds.width * scale) + 'px'; - div.style.height = Math.floor(bounds.height * scale) + 'px'; - - if (!parentLayout) { - div.style.left = Math.trunc(bounds.left * scale) + offset.x + 'px'; - div.style.top = Math.trunc(bounds.top * scale) + offset.y + 'px'; - return; - } - - var parentDiv = parentLayout.div; - switch (this.layoutType) { - case options.DisplayLayoutType.TOP: - div.style.left = Math.trunc(bounds.left * scale) + offset.x + 'px'; - div.style.top = parentDiv.offsetTop - div.offsetHeight + 'px'; - break; - case options.DisplayLayoutType.RIGHT: - div.style.left = parentDiv.offsetLeft + parentDiv.offsetWidth + 'px'; - div.style.top = Math.trunc(bounds.top * scale) + offset.y + 'px'; - break; - case options.DisplayLayoutType.BOTTOM: - div.style.left = Math.trunc(bounds.left * scale) + offset.x + 'px'; - div.style.top = parentDiv.offsetTop + parentDiv.offsetHeight + 'px'; - break; - case options.DisplayLayoutType.LEFT: - div.style.left = parentDiv.offsetLeft - div.offsetWidth + 'px'; - div.style.top = Math.trunc(bounds.top * scale) + offset.y + 'px'; - break; - } - }, - - /** - * Calculates the offset relative to |parent|. - * @param {number} scale - * @param {?options.DisplayLayout} parent - */ - calculateOffset: function(scale, parent) { - // Offset is calculated from top or left edge. - if (!parent) { - this.offset = 0; - return; - } - assert(this.parentId == parent.id); - var offset; - if (this.layoutType == options.DisplayLayoutType.LEFT || - this.layoutType == options.DisplayLayoutType.RIGHT) { - offset = this.div.offsetTop - parent.div.offsetTop; - } else { - offset = this.div.offsetLeft - parent.div.offsetLeft; - } - this.offset = Math.trunc(offset / scale); - }, - - /** - * Calculates the bounds relative to |parentBounds|. - * @param {!options.DisplayBounds} parentBounds - * @return {!options.DisplayBounds} - */ - calculateBounds: function(parentBounds) { - var left = 0, top = 0; - switch (this.layoutType) { - case options.DisplayLayoutType.TOP: - left = parentBounds.left + this.offset; - top = parentBounds.top - this.bounds.height; - break; - case options.DisplayLayoutType.RIGHT: - left = parentBounds.left + parentBounds.width; - top = parentBounds.top + this.offset; - break; - case options.DisplayLayoutType.BOTTOM: - left = parentBounds.left + this.offset; - top = parentBounds.top + parentBounds.height; - break; - case options.DisplayLayoutType.LEFT: - left = parentBounds.left - this.bounds.width; - top = parentBounds.top + this.offset; - break; - } - return { - left: left, - top: top, - width: this.bounds.width, - height: this.bounds.height - }; - }, - - /** - * Return the position closest to |newPosition| along the edge of - * |parentDiv| specified by |layoutType|. - * @param {options.DisplayPosition} newPosition - * @param {?HTMLElement} parentDiv - * @param {!options.DisplayLayoutType} layoutType - * @return {!options.DisplayPosition} - */ - getSnapPosition: function(newPosition, parentDiv, layoutType) { - var x; - if (layoutType == options.DisplayLayoutType.LEFT) { - x = parentDiv.offsetLeft - this.div.offsetWidth; - } else if (layoutType == options.DisplayLayoutType.RIGHT) { - x = parentDiv.offsetLeft + parentDiv.offsetWidth; - } else { - x = this.snapToX(newPosition.x, parentDiv); - } - - var y; - if (layoutType == options.DisplayLayoutType.TOP) { - y = parentDiv.offsetTop - this.div.offsetHeight; - } else if (layoutType == options.DisplayLayoutType.BOTTOM) { - y = parentDiv.offsetTop + parentDiv.offsetHeight; - } else { - y = this.snapToY(newPosition.y, parentDiv); - } - - return {x: x, y: y}; - }, - - /** - * Update the div location to the position closest to |newPosition| along - * the edge of |parentDiv| specified by |layoutType|. - * @param {options.DisplayPosition} newPosition - * @param {?HTMLElement} parentDiv - * @param {!options.DisplayLayoutType} layoutType - */ - setDivPosition: function(newPosition, parentDiv, layoutType) { - var div = this.div; - switch (layoutType) { - case options.DisplayLayoutType.RIGHT: - div.style.left = parentDiv.offsetLeft + parentDiv.offsetWidth + 'px'; - div.style.top = newPosition.y + 'px'; - break; - case options.DisplayLayoutType.LEFT: - div.style.left = parentDiv.offsetLeft - div.offsetWidth + 'px'; - div.style.top = newPosition.y + 'px'; - break; - case options.DisplayLayoutType.TOP: - div.style.top = parentDiv.offsetTop - div.offsetHeight + 'px'; - div.style.left = newPosition.x + 'px'; - break; - case options.DisplayLayoutType.BOTTOM: - div.style.top = parentDiv.offsetTop + parentDiv.offsetHeight + 'px'; - div.style.left = newPosition.x + 'px'; - break; - } - }, - - /** - * Return the position of the corner of the div closest to |pos|. - * @param {?HTMLElement} parentDiv - * @param {options.DisplayPosition} pos - * @return {!options.DisplayPosition} - * @private - */ - getCornerPos: function(parentDiv, pos) { - var x; - if (pos.x > parentDiv.offsetLeft + parentDiv.offsetWidth / 2) - x = parentDiv.offsetLeft + parentDiv.offsetWidth; - else - x = parentDiv.offsetLeft - this.div.offsetWidth; - var y; - if (pos.y > parentDiv.offsetTop + parentDiv.offsetHeight / 2) - y = parentDiv.offsetTop + parentDiv.offsetHeight; - else - y = parentDiv.offsetTop - this.div.offsetHeight; - return {x: x, y: y}; - }, - - /** - * Ensures that there is a minimum overlap when displays meet at a corner. - * @param {?HTMLElement} parentDiv - * @param {options.DisplayLayoutType} layoutType - */ - adjustCorners: function(parentDiv, layoutType) { - // The number of pixels to share the edges between displays. - /** @const */ var MIN_OFFSET_OVERLAP = 5; - - var div = this.div; - if (layoutType == options.DisplayLayoutType.LEFT || - layoutType == options.DisplayLayoutType.RIGHT) { - var top = Math.max( - div.offsetTop, - parentDiv.offsetTop - div.offsetHeight + MIN_OFFSET_OVERLAP); - top = Math.min( - top, - parentDiv.offsetTop + parentDiv.offsetHeight - MIN_OFFSET_OVERLAP); - div.style.top = top + 'px'; - } else { - var left = Math.max( - div.offsetLeft, - parentDiv.offsetLeft - div.offsetWidth + MIN_OFFSET_OVERLAP); - left = Math.min( - left, - parentDiv.offsetLeft + parentDiv.offsetWidth - MIN_OFFSET_OVERLAP); - div.style.left = left + 'px'; - } - }, - - /** - * Calculates the layoutType for |position| relative to |parentDiv|. - * @param {?HTMLElement} parentDiv - * @param {!options.DisplayPosition} position - * @return {options.DisplayLayoutType} - */ - getLayoutTypeForPosition: function(parentDiv, position) { - var div = this.div; - - // Translate position from top-left to center. - var x = position.x + div.offsetWidth / 2; - var y = position.y + div.offsetHeight / 2; - - // Determine the distance from the new position to both of the near edges. - var left = parentDiv.offsetLeft; - var top = parentDiv.offsetTop; - var width = parentDiv.offsetWidth; - var height = parentDiv.offsetHeight; - - // Signed deltas to the center of the div. - var dx = x - (left + width / 2); - var dy = y - (top + height / 2); - - // Unsigned distance to each edge. - var distx = Math.abs(dx) - width / 2; - var disty = Math.abs(dy) - height / 2; - - if (distx > disty) { - if (dx < 0) - return options.DisplayLayoutType.LEFT; - else - return options.DisplayLayoutType.RIGHT; - } else { - if (dy < 0) - return options.DisplayLayoutType.TOP; - else - return options.DisplayLayoutType.BOTTOM; - } - }, - - /** - * Snaps a horizontal value, see SnapToEdge. - * @param {number} x - * @param {?HTMLElement} parentDiv - * @param {number=} opt_snapDistance Provide to override the snap distance. - * 0 means snap from any distance. - * @return {number} - */ - snapToX: function(x, parentDiv, opt_snapDistance) { - return snapToEdge_( - x, this.div.offsetWidth, parentDiv.offsetLeft, parentDiv.offsetWidth, - opt_snapDistance); - }, - - /** - * Snaps a vertical value, see SnapToEdge. - * @param {number} y - * @param {?HTMLElement} parentDiv - * @param {number=} opt_snapDistance Provide to override the snap distance. - * 0 means snap from any distance. - * @return {number} - */ - snapToY: function(y, parentDiv, opt_snapDistance) { - return snapToEdge_( - y, this.div.offsetHeight, parentDiv.offsetTop, parentDiv.offsetHeight, - opt_snapDistance); - }, - - /** - * Intersects this.div at |pos| with |otherDiv|. If there is a collision, - * modifies |deltaPos| to limit movement to a single axis and avoid the - * collision and returns true. - * @param {!options.DisplayPosition} pos - * @param {?HTMLElement} otherDiv - * @param {!options.DisplayPosition} deltaPos - * @return {boolean} Whether there was a collision. - */ - collideWithDivAndModifyDelta: function(pos, otherDiv, deltaPos) { - var div = this.div; - var newX = pos.x + deltaPos.x; - var newY = pos.y + deltaPos.y; - - if ((newX + div.offsetWidth <= otherDiv.offsetLeft) || - (newX >= otherDiv.offsetLeft + otherDiv.offsetWidth) || - (newY + div.offsetHeight <= otherDiv.offsetTop) || - (newY >= otherDiv.offsetTop + otherDiv.offsetHeight)) { - return false; - } - - if (Math.abs(deltaPos.x) > Math.abs(deltaPos.y)) { - if (deltaPos.x > 0) { - var x = otherDiv.offsetLeft - div.offsetWidth; - if (x > pos.x) - deltaPos.x = x - pos.x; - else - deltaPos.x = 0; - } else { - var x = otherDiv.offsetLeft + otherDiv.offsetWidth; - if (x < pos.x) - deltaPos.x = x - pos.x; - else - deltaPos.x = 0; - } - deltaPos.y = 0; - } else { - deltaPos.x = 0; - if (deltaPos.y > 0) { - var y = otherDiv.offsetTop - div.offsetHeight; - if (y > pos.y) - deltaPos.y = y - pos.y; - else - deltaPos.y = 0; - } else if (deltaPos.y < 0) { - var y = otherDiv.offsetTop + otherDiv.offsetTop; - if (y < pos.y) - deltaPos.y = y - pos.y; - else - deltaPos.y = 0; - } - } - - return true; - } - }; - - // Export - return {DisplayLayout: DisplayLayout}; -});
diff --git a/chrome/browser/resources/options/chromeos/display_layout_manager.js b/chrome/browser/resources/options/chromeos/display_layout_manager.js deleted file mode 100644 index c51cbdcd..0000000 --- a/chrome/browser/resources/options/chromeos/display_layout_manager.js +++ /dev/null
@@ -1,386 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -cr.exportPath('options'); - -cr.define('options', function() { - 'use strict'; - - /** - * Gets the layout type of |point| relative to |rect|. - * @param {!options.DisplayBounds} rect The base rectangle. - * @param {!options.DisplayPosition} point The point to check the position. - * @return {options.DisplayLayoutType} - */ - function getLayoutTypeForPosition(rect, point) { - // Separates the area into four (LEFT/RIGHT/TOP/BOTTOM) by the diagonals of - // the rect, and decides which area the display should reside. - var diagonalSlope = rect.height / rect.width; - var topDownIntercept = rect.top - rect.left * diagonalSlope; - var bottomUpIntercept = rect.top + rect.height + rect.left * diagonalSlope; - - if (point.y > topDownIntercept + point.x * diagonalSlope) { - if (point.y > bottomUpIntercept - point.x * diagonalSlope) - return options.DisplayLayoutType.BOTTOM; - else - return options.DisplayLayoutType.LEFT; - } else { - if (point.y > bottomUpIntercept - point.x * diagonalSlope) - return options.DisplayLayoutType.RIGHT; - else - return options.DisplayLayoutType.TOP; - } - } - - /** - * @param {options.DisplayLayoutType} layoutType - * @return {!options.DisplayLayoutType} - */ - function invertLayoutType(layoutType) { - switch (layoutType) { - case options.DisplayLayoutType.RIGHT: - return options.DisplayLayoutType.LEFT; - case options.DisplayLayoutType.LEFT: - return options.DisplayLayoutType.RIGHT; - case options.DisplayLayoutType.TOP: - return options.DisplayLayoutType.BOTTOM; - case options.DisplayLayoutType.BOTTOM: - return options.DisplayLayoutType.TOP; - } - assertNotReached(); - return layoutType; - } - - /** - * @constructor - */ - function DisplayLayoutManager() { - this.displayLayoutMap_ = {}; - this.displayAreaOffset_ = {x: 0, y: 0}; - } - - // Helper class for display layout management. Implements logic for laying - // out two displays. - DisplayLayoutManager.prototype = { - /** - * An object containing DisplayLayout objects for each entry in - * |displays_|. - * @type {?Object<!options.DisplayLayout>} - * @private - */ - displayLayoutMap_: null, - - /** - * The scale factor of the actual display size to the drawn display - * rectangle size. Set in calculateDisplayArea_. - * @type {number} - * @private - */ - visualScale_: 1, - - /** - * The offset to the center of the display area div. - * @type {?options.DisplayPosition} - * @private - */ - displayAreaOffset_: null, - - /** - * Adds a display to the layout map. - * @param {options.DisplayLayout} displayLayout - */ - addDisplayLayout: function(displayLayout) { - this.displayLayoutMap_[displayLayout.id] = displayLayout; - }, - - /** - * Returns the display layout for |id|. - * @param {string} id - * @return {options.DisplayLayout} - */ - getDisplayLayout: function(id) { return this.displayLayoutMap_[id]; }, - - /** - * Returns the number of display layout entries. - * @return {number} - */ - getDisplayLayoutCount: function() { - return Object.keys(/** @type {!Object} */ (this.displayLayoutMap_)) - .length; - }, - - /** - * Returns the display layout corresponding to |div|. - * @param {!HTMLElement} div - * @return {?options.DisplayLayout} - */ - getFocusedLayoutForDiv: function(div) { - for (var id in this.displayLayoutMap_) { - var layout = this.displayLayoutMap_[id]; - if (layout.div == div || - (div.offsetParent && layout.div == div.offsetParent)) { - return layout; - } - } - return null; - }, - - /** - * Sets the display area div size and creates a div for each entry in - * displayLayoutMap_. - * @param {!Element} displayAreaDiv The display area div element. - * @param {number} minVisualScale The minimum visualScale value. - * @return {number} The calculated visual scale. - */ - createDisplayArea: function(displayAreaDiv, minVisualScale) { - this.calculateDisplayArea_(displayAreaDiv, minVisualScale); - for (var id in this.displayLayoutMap_) { - var layout = this.displayLayoutMap_[id]; - if (layout.div) { - // Parent divs must be created before children, so the div for this - // entry may have already been created. - continue; - } - this.createDisplayLayoutDiv_(id, displayAreaDiv); - } - return this.visualScale_; - }, - - /** - * Sets the display layout div corresponding to |id| to focused and - * sets all other display layouts to unfocused. - * @param {string} focusedId - * @param {boolean=} opt_userAction If true, focus was triggered by a - * user action. (Used in DisplayLayoutManagerMulti override). - */ - setFocusedId: function(focusedId, opt_userAction) { - for (var id in this.displayLayoutMap_) { - var layout = this.displayLayoutMap_[id]; - layout.div.classList.toggle('displays-focused', layout.id == focusedId); - } - }, - - /** - * Sets the mouse event callbacks for each div. - * @param {function (Event)} onMouseDown - * @param {function (Event)} onTouchStart - */ - setDivCallbacks: function(onMouseDown, onTouchStart) { - for (var id in this.displayLayoutMap_) { - var layout = this.displayLayoutMap_[id]; - layout.div.onmousedown = onMouseDown; - layout.div.ontouchstart = onTouchStart; - } - }, - - /** - * Update the location of display |id| to |newPosition|. - * @param {string} id - * @param {options.DisplayPosition} newPosition - * @private - */ - updatePosition: function(id, newPosition) { - var displayLayout = this.displayLayoutMap_[id]; - var div = displayLayout.div; - var baseLayout = this.getBaseLayout_(displayLayout); - var baseDiv = baseLayout.div; - - newPosition.x = displayLayout.snapToX(newPosition.x, baseDiv); - newPosition.y = displayLayout.snapToY(newPosition.y, baseDiv); - - /** @type {!options.DisplayPosition} */ var newCenter = { - x: newPosition.x + div.offsetWidth / 2, - y: newPosition.y + div.offsetHeight / 2 - }; - - /** @type {!options.DisplayBounds} */ var baseBounds = { - left: baseDiv.offsetLeft, - top: baseDiv.offsetTop, - width: baseDiv.offsetWidth, - height: baseDiv.offsetHeight - }; - - // This implementation considers only the case of two displays, i.e - // a single parent with one child. - var isPrimary = displayLayout.parentId == ''; - - var layoutType = getLayoutTypeForPosition(baseBounds, newCenter); - if (isPrimary) - layoutType = invertLayoutType(layoutType); - - if (layoutType == options.DisplayLayoutType.LEFT || - layoutType == options.DisplayLayoutType.RIGHT) { - if (newPosition.y > baseDiv.offsetTop + baseDiv.offsetHeight) { - layoutType = isPrimary ? options.DisplayLayoutType.TOP : - options.DisplayLayoutType.BOTTOM; - } else if (newPosition.y + div.offsetHeight < baseDiv.offsetTop) { - layoutType = isPrimary ? options.DisplayLayoutType.BOTTOM : - options.DisplayLayoutType.TOP; - } - } else { - if (newPosition.x > baseDiv.offsetLeft + baseDiv.offsetWidth) { - layoutType = isPrimary ? options.DisplayLayoutType.LEFT : - options.DisplayLayoutType.RIGHT; - } else if (newPosition.x + div.offsetWidth < baseDiv.offsetLeft) { - layoutType = isPrimary ? options.DisplayLayoutType.RIGHT : - options.DisplayLayoutType.LEFT; - } - } - - // layout is always relative to primary and stored in the child layout. - var layoutToBase; - if (!isPrimary) { - displayLayout.layoutType = layoutType; - layoutToBase = layoutType; - } else { - baseLayout.layoutType = layoutType; - layoutToBase = invertLayoutType(layoutType); - } - - displayLayout.setDivPosition(newPosition, baseDiv, layoutToBase); - }, - - /** - * Called from the UI to finalize the location of display |id| after updates - * are complete (e.g. after a drag was completed). - * @param {string} id - * @return {boolean} True if the final position differs from the original. - */ - finalizePosition: function(id) { - var displayLayout = this.displayLayoutMap_[id]; - var div = displayLayout.div; - var baseLayout = this.getBaseLayout_(displayLayout); - - var isPrimary = displayLayout.parentId == ''; - var layoutType = - isPrimary ? baseLayout.layoutType : displayLayout.layoutType; - - // Make sure the dragging location is connected. - displayLayout.adjustCorners(baseLayout.div, layoutType); - - // Calculate the offset of the child display. - if (isPrimary) { - baseLayout.calculateOffset(this.visualScale_, displayLayout); - } else { - var parent = this.displayLayoutMap_[displayLayout.parentId]; - displayLayout.calculateOffset(this.visualScale_, parent); - } - - return displayLayout.originalDivOffsets.x != div.offsetLeft || - displayLayout.originalDivOffsets.y != div.offsetTop; - }, - - /** - * Calculates the display area offset and scale. - * @param {!Element} displayAreaDiv The containing display area div. - * @param {number} minVisualScale The minimum visualScale value. - */ - calculateDisplayArea_(displayAreaDiv, minVisualScale) { - var maxWidth = 0; - var maxHeight = 0; - var boundingBox = {left: 0, right: 0, top: 0, bottom: 0}; - - for (var id in this.displayLayoutMap_) { - var layout = this.displayLayoutMap_[id]; - var bounds = layout.bounds; - boundingBox.left = Math.min(boundingBox.left, bounds.left); - boundingBox.right = - Math.max(boundingBox.right, bounds.left + bounds.width); - boundingBox.top = Math.min(boundingBox.top, bounds.top); - boundingBox.bottom = - Math.max(boundingBox.bottom, bounds.top + bounds.height); - maxWidth = Math.max(maxWidth, bounds.width); - maxHeight = Math.max(maxHeight, bounds.height); - } - - // Make the margin around the bounding box. - var areaWidth = boundingBox.right - boundingBox.left + maxWidth; - var areaHeight = boundingBox.bottom - boundingBox.top + maxHeight; - - // Calculates the scale by the width since horizontal size is more strict. - // TODO(mukai): Adds the check of vertical size in case. - this.visualScale_ = - Math.min(minVisualScale, displayAreaDiv.offsetWidth / areaWidth); - - // Prepare enough area for displays_view by adding the maximum height. - displayAreaDiv.style.height = - Math.ceil(areaHeight * this.visualScale_) + 'px'; - - // Centering the bounding box of the display rectangles. - this.displayAreaOffset_ = { - x: Math.floor( - displayAreaDiv.offsetWidth / 2 - - (boundingBox.right + boundingBox.left) * this.visualScale_ / 2), - y: Math.floor( - displayAreaDiv.offsetHeight / 2 - - (boundingBox.bottom + boundingBox.top) * this.visualScale_ / 2) - }; - }, - - /** - * Creates a div element and assigns it to |displayLayout|. Returns the - * created div for additional decoration. - * @param {string} id - * @param {!Element} displayAreaDiv The containing display area div. - */ - createDisplayLayoutDiv_: function(id, displayAreaDiv) { - var displayLayout = this.displayLayoutMap_[id]; - var parentId = displayLayout.parentId; - var parentLayout = null; - if (parentId) { - // Ensure the parent div is created first. - parentLayout = this.displayLayoutMap_[parentId]; - if (!parentLayout.div) - this.createDisplayLayoutDiv_(parentId, displayAreaDiv); - } - - var div = /** @type {!HTMLElement} */ (document.createElement('div')); - div.className = 'displays-display'; - displayLayout.div = div; - - // div needs to be added to the DOM tree first, otherwise offsetHeight for - // nameContainer below cannot be computed. - displayAreaDiv.appendChild(div); - - var nameContainer = document.createElement('div'); - nameContainer.textContent = displayLayout.name; - div.appendChild(nameContainer); - - var newHeight = - Math.floor(displayLayout.bounds.height * this.visualScale_); - nameContainer.style.marginTop = - (newHeight - nameContainer.offsetHeight) / 2 + 'px'; - - displayLayout.layoutDivFromBounds( - this.displayAreaOffset_, this.visualScale_, parentLayout); - - displayLayout.originalDivOffsets.x = div.offsetLeft; - displayLayout.originalDivOffsets.y = div.offsetTop; - - displayLayout.calculateOffset(this.visualScale_, parentLayout); - }, - - /** - * Returns the display paired with |displayLayout|, either the parent - * or a matching child (currently there will only be one). - * @param {options.DisplayLayout} displayLayout - * @return {?options.DisplayLayout} - * @private - */ - getBaseLayout_(displayLayout) { - if (displayLayout.parentId != '') - return this.displayLayoutMap_[displayLayout.parentId]; - for (var childId in this.displayLayoutMap_) { - var child = this.displayLayoutMap_[childId]; - if (child.parentId == displayLayout.id) - return child; - } - assertNotReached(); - return null; - } - }; - - // Export - return {DisplayLayoutManager: DisplayLayoutManager}; -});
diff --git a/chrome/browser/resources/options/chromeos/display_layout_manager_multi.js b/chrome/browser/resources/options/chromeos/display_layout_manager_multi.js deleted file mode 100644 index 1c9400e..0000000 --- a/chrome/browser/resources/options/chromeos/display_layout_manager_multi.js +++ /dev/null
@@ -1,368 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -cr.exportPath('options'); - -cr.define('options', function() { - 'use strict'; - - var DisplayLayoutManager = options.DisplayLayoutManager; - - /** - * @constructor - * @extends {options.DisplayLayoutManager} - */ - function DisplayLayoutManagerMulti() { DisplayLayoutManager.call(this); } - - // Helper class for display layout management. Implements logic for laying - // out 3+ displays. - DisplayLayoutManagerMulti.prototype = { - __proto__: DisplayLayoutManager.prototype, - - /** @type {string} */ - dragId_: '', - - /** @type {string} */ - dragParentId_: '', - - /** @type {options.DisplayLayoutType} */ - dragLayoutType_: options.DisplayLayoutType.RIGHT, - - /** @override */ - setFocusedId: function(focusedId, opt_userAction) { - DisplayLayoutManager.prototype.setFocusedId.call(this, focusedId); - if (!opt_userAction || this.dragId_ != '') - return; - var layout = this.displayLayoutMap_[focusedId]; - this.highlightEdge_(layout.parentId, layout.layoutType); - }, - - /** @override */ - updatePosition: function(id, newPosition) { - this.dragId_ = id; - var layout = this.displayLayoutMap_[id]; - - // Find the closest parent. - var parentId = this.findClosest_(layout, newPosition); - var parent = this.displayLayoutMap_[parentId]; - - // Find the closest edge. - var layoutType = layout.getLayoutTypeForPosition(parent.div, newPosition); - - // Calculate the new position and delta. - var oldPos = {x: layout.div.offsetLeft, y: layout.div.offsetTop}; - var newPos = layout.getSnapPosition(newPosition, parent.div, layoutType); - var deltaPos = {x: newPos.x - oldPos.x, y: newPos.y - oldPos.y}; - - // Check for collisions. - this.collideAndModifyDelta_(layout, oldPos, deltaPos); - if (deltaPos.x == 0 && deltaPos.y == 0) - return; - - // Update the div (but not the actual layout type or offset yet), - newPos = {x: oldPos.x + deltaPos.x, y: oldPos.y + deltaPos.y}; - layout.setDivPosition(newPos, parent.div, layoutType); - - // If the edge changed, update and highlight it. - if (layoutType != this.dragLayoutType_ || - parentId != this.dragParentId_) { - this.dragLayoutType_ = layoutType; - this.dragParentId_ = parentId; - this.highlightEdge_(this.dragParentId_, this.dragLayoutType_); - } - }, - - /** @override */ - finalizePosition: function(id) { - if (id != this.dragId_ || !this.dragParentId_) { - this.dragId_ = ''; - return false; - } - - var layout = this.displayLayoutMap_[id]; - - // All immediate children of |layout| will need to be re-parented. - var orphanIds = this.findChildren_(id, false /* do not recurse */); - - if (layout.parentId == '') { - // We can not re-parent the primary display, so instead re-parent the - // "drag parent" to the primary display and make all other displays - // orphans. - orphanIds = this.findChildren_(id, true /* recurse */); - - // Remove the "drag parent" from the orphans list and reparent it first. - var index = orphanIds.indexOf(this.dragParentId_); - assert(index != -1); - orphanIds.splice(index, 1); - this.reparentOrphan_(this.dragParentId_, orphanIds); - } else { - var dragParent = this.displayLayoutMap_[this.dragParentId_]; - - // Special case: re-parenting to a descendant. Parent the immediate - // child (the 'top parent') to the dragged display's current parent. - var topParent = dragParent; - while (topParent) { - if (topParent.parentId == '') - break; - if (topParent.parentId == id) { - topParent.parentId = layout.parentId; - break; - } - topParent = this.displayLayoutMap_[topParent.parentId]; - } - - // Re-parent the dragged display. - layout.parentId = this.dragParentId_; - layout.layoutType = this.dragLayoutType_; - - // Snap to corners and calculate the offset from the new parent. - // This does not depend on any unresolved child layout. - layout.adjustCorners(dragParent.div, this.dragLayoutType_); - layout.calculateOffset(this.visualScale_, dragParent); - } - - // Update any orphaned children. This may cause the dragged display to - // be re-attached if it was attached to a child. - this.updateOrphans_(orphanIds); - - this.highlightEdge_('', undefined); // Remove any highlights. - this.dragId_ = ''; - - return layout.originalDivOffsets.x != layout.div.offsetLeft || - layout.originalDivOffsets.y != layout.div.offsetTop; - }, - - /** - * Re-parent all entries in |orphanIds| and any children. - * @param {Array<string>} orphanIds The list of ids affected by the move. - * @private - */ - updateOrphans_: function(orphanIds) { - var orphans = orphanIds.slice(); - for (var orphan of orphanIds) { - var newOrphans = this.findChildren_(orphan, true /* recurse */); - // If the dragged display was re-parented to one of its children, - // there may be duplicates so merge the lists. - for (var o of newOrphans) { - if (orphans.indexOf(o) == -1) - orphans.push(o); - } - } - - // Remove each orphan from the list as it is re-parented so that - // subsequent orphans can be parented to it. - while (orphans.length) { - var orphanId = orphans.shift(); - this.reparentOrphan_(orphanId, orphans); - } - }, - - /** - * Re-parent the orphan to a layout that is not a member of - * |otherOrphanIds|. - * @param {string} orphanId The id of the orphan to re-parent. - * @param {Array<string>} otherOrphanIds The list of ids of other orphans - * to ignore when re-parenting. - * @private - */ - reparentOrphan_: function(orphanId, otherOrphanIds) { - var orphan = this.displayLayoutMap_[orphanId]; - - if (orphanId == this.dragId_ && orphan.parentId != '') { - // Preserve the layout and offset of the dragged div. - var parent = this.displayLayoutMap_[orphan.parentId]; - orphan.bounds = this.calcLayoutBounds_(orphan); - orphan.layoutDivFromBounds( - this.displayAreaOffset_, this.visualScale_, parent); - return; - } - - // Find the closest parent. - var pos = {x: orphan.div.offsetLeft, y: orphan.div.offsetTop}; - var newParentId = this.findClosest_(orphan, pos, otherOrphanIds); - orphan.parentId = newParentId; - assert(newParentId != ''); - var parent = this.displayLayoutMap_[newParentId]; - - // Find the closest edge. - var layoutType = orphan.getLayoutTypeForPosition(parent.div, pos); - - // Snap from the nearest corner to the desired locaiton and get the delta. - var cornerPos = orphan.getCornerPos(parent.div, pos); - pos = orphan.getSnapPosition(pos, parent.div, layoutType); - var deltaPos = {x: pos.x - cornerPos.x, y: pos.y - cornerPos.y}; - - // Check for collisions. - this.collideAndModifyDelta_(orphan, cornerPos, deltaPos); - pos = {x: cornerPos.x + deltaPos.x, y: cornerPos.y + deltaPos.y}; - - // Update the div and adjust the corners. - orphan.layoutType = layoutType; - orphan.setDivPosition(pos, parent.div, layoutType); - orphan.adjustCorners(parent.div, layoutType); - - // Calculate the bounds from the new div position. - orphan.calculateOffset(this.visualScale_, parent); - - // TODO(stevenjb): Set bounds and send orphan update. - }, - - /** - * @param {string} parentId - * @param {boolean} recurse Include descendants of children. - * @return {!Array<string>} - * @private - */ - findChildren_: function(parentId, recurse) { - var children = []; - for (var childId in this.displayLayoutMap_) { - if (childId == parentId) - continue; - if (this.displayLayoutMap_[childId].parentId == parentId) { - // Insert immediate children at the front of the array. - children.unshift(childId); - if (recurse) { - // Descendants get added to the end of the list. - children = children.concat(this.findChildren_(childId, true)); - } - } - } - return children; - }, - - /** - * Finds the display closest to |position| ignoring |child|. - * @param {!options.DisplayLayout} child - * @param {!options.DisplayPosition} position - * @param {Array<string>=} opt_ignoreIds Ids to ignore. - * @return {string} - * @private - */ - findClosest_: function(child, position, opt_ignoreIds) { - var x = position.x + child.div.offsetWidth / 2; - var y = position.y + child.div.offsetHeight / 2; - var closestId = ''; - var closestDelta2 = 0; - for (var id in this.displayLayoutMap_) { - if (id == child.id) - continue; - if (opt_ignoreIds && opt_ignoreIds.indexOf(id) != -1) - continue; - var div = this.displayLayoutMap_[id].div; - var left = div.offsetLeft; - var top = div.offsetTop; - var width = div.offsetWidth; - var height = div.offsetHeight; - if (x >= left && x < left + width && y >= top && y < top + height) - return id; // point is inside rect - var dx, dy; - if (x < left) - dx = left - x; - else if (x > left + width) - dx = x - (left + width); - else - dx = 0; - if (y < top) - dy = top - y; - else if (y > top + height) - dy = y - (top + height); - else - dy = 0; - var delta2 = dx * dx + dy * dy; - if (closestId == '' || delta2 < closestDelta2) { - closestId = id; - closestDelta2 = delta2; - } - } - return closestId; - }, - - /** - * Intersects |layout| at |pos| with each other layout and reduces - * |deltaPos| to avoid any collisions (or sets it to [0,0] if the div can - * not be moved in the direction of |deltaPos|). - * @param {!options.DisplayLayout} layout - * @param {!options.DisplayPosition} pos - * @param {!options.DisplayPosition} deltaPos - */ - collideAndModifyDelta_: function(layout, pos, deltaPos) { - var keys = Object.keys( - /** @type {!Object<!options.DisplayLayout>}*/ ( - this.displayLayoutMap_)); - var others = new Set(keys); - others.delete(layout.id); - var checkCollisions = true; - while (checkCollisions) { - checkCollisions = false; - for (var tid of others) { - var tlayout = this.displayLayoutMap_[tid]; - if (layout.collideWithDivAndModifyDelta(pos, tlayout.div, deltaPos)) { - if (deltaPos.x == 0 && deltaPos.y == 0) - return; - others.delete(tid); - checkCollisions = true; - break; - } - } - } - }, - - /** - * Highlights the edge of the div associated with |parentId| based on - * |layoutType| and removes any other highlights. If |layoutType| is - * undefined, removes all highlights. - * @param {string} id - * @param {options.DisplayLayoutType|undefined} layoutType - * @private - */ - highlightEdge_: function(id, layoutType) { - for (var tid in this.displayLayoutMap_) { - var tlayout = this.displayLayoutMap_[tid]; - var highlight = ''; - if (tlayout.id == id) { - switch (layoutType) { - case options.DisplayLayoutType.RIGHT: - highlight = 'displays-parent-right'; - break; - case options.DisplayLayoutType.LEFT: - highlight = 'displays-parent-left'; - break; - case options.DisplayLayoutType.TOP: - highlight = 'displays-parent-top'; - break; - case options.DisplayLayoutType.BOTTOM: - highlight = 'displays-parent-bottom'; - break; - } - } - tlayout.div.classList.toggle( - 'displays-parent-right', highlight == 'displays-parent-right'); - tlayout.div.classList.toggle( - 'displays-parent-left', highlight == 'displays-parent-left'); - tlayout.div.classList.toggle( - 'displays-parent-top', highlight == 'displays-parent-top'); - tlayout.div.classList.toggle( - 'displays-parent-bottom', highlight == 'displays-parent-bottom'); - } - }, - - /** - * Calculates but do not set the div bound. - * @param {!options.DisplayLayout} layout - * @return {!options.DisplayBounds} - */ - calcLayoutBounds_: function(layout) { - if (layout.parentId == '') - return /** @type {!options.DisplayBounds} */ (layout.bounds); - var parent = this.displayLayoutMap_[layout.parentId]; - // Parent layout bounds may not be calculated yet, so calculate (but - // do not set) them. - var parentBounds = this.calcLayoutBounds_(parent); - return layout.calculateBounds(parentBounds); - }, - }; - - // Export - return {DisplayLayoutManagerMulti: DisplayLayoutManagerMulti}; -});
diff --git a/chrome/browser/resources/options/chromeos/display_options.css b/chrome/browser/resources/options/chromeos/display_options.css deleted file mode 100644 index 6722e7b..0000000 --- a/chrome/browser/resources/options/chromeos/display_options.css +++ /dev/null
@@ -1,122 +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. */ - -#display-options-page { - background-color: rgb(240, 240, 240); -} - -#display-options-content-area { - padding: 0; -} - -#display-options-displays-view-host { - padding: 20px 0 20px 0; -} - -#display-options-displays-view { - overflow: hidden; - position: relative; - width: 100%; -} - -#display-configurations { - -webkit-padding-end: 0; - -webkit-padding-start: 15px; - border-top: 1px solid lightgrey; - padding-top: 15px; -} - -/* The arrow at the border #display-configurations to point the focused display. - * This is achieved by a square rotated by 45-deg, and it has border at the - * upper-half, which were left/top before the rotation. */ -#display-configuration-arrow { - border-left: 1px solid lightgrey; - border-top: 1px solid lightgrey; - height: 20px; - position: absolute; - transform: rotate(45deg); - width: 20px; - z-index: 1; -} - -#display-configurations, -#display-configuration-arrow, -#display-options-page .action-area { - background-color: white; -} - -#display-options-page .action-area { - /* Because this element has a background-color, we need to emulate the - * parent's border-radius (otherwise there's sharp corners). */ - border-bottom-left-radius: inherit; - border-bottom-right-radius: inherit; -} - -#selected-display-data-container { - z-index: 2; -} - -#selected-display-name { - font-size: large; - font-weight: normal; - margin-top: 5px; - padding: 0; -} - -.selected-display-option-row { - margin-top: 10px; -} - -.selected-display-option-title { - display: inline-block; - margin-right: 10px; -} - -.displays-display { - background: rgb(240, 240, 240); - border: solid 1px; - box-sizing: border-box; - font-weight: bold; - position: absolute; - text-align: center; - user-select: none; - z-index: 2; -} - -.display-mirrored { - border: solid 1px; -} - -.displays-focused { - border: solid 2px rgb(0, 138, 255); - color: rgb(0, 138, 255); -} - -.displays-parent-left { - border-left: solid 1px rgb(255, 138, 0); -} - -.displays-parent-right { - border-right: solid 1px rgb(255, 138, 0); -} - -.displays-parent-top { - border-top: solid 1px rgb(255, 138, 0); -} - -.displays-parent-bottom { - border-bottom: solid 1px rgb(255, 138, 0); -} - -#display-options-select-mirroring { - margin-right: 5px; -} - -.display-options-button { - width: 140px; -} - -.display-options-button2 { - width: 120px; -}
diff --git a/chrome/browser/resources/options/chromeos/display_options.html b/chrome/browser/resources/options/chromeos/display_options.html deleted file mode 100644 index 13be28d..0000000 --- a/chrome/browser/resources/options/chromeos/display_options.html +++ /dev/null
@@ -1,88 +0,0 @@ -<div id="display-options-page" class="page" hidden> - <div class="close-button"></div> - <h1>$i18n{displayOptionsPage}</h1> - <div class="content-area" id="display-options-content-area"> - <div id="display-options-displays-view-host"> - </div> - <div id="display-configurations"> - <div id="selected-display-data-container"> - <div id="selected-display-name"></div> - <div class="selected-display-option-row"> - <div class="selected-display-option-title"> - $i18n{selectedDisplayTitleOptions} - </div> - <select id="display-options-select-mirroring" - class="display-options-button"> - <option value="extended">$i18n{extendedMode}</option> - <option value="mirroring">$i18n{mirroringMode}</option> - </select> - <button id="display-options-set-primary" - class="display-options-button2"> - $i18n{setPrimary} - </button> - </div> - <div id="display-options-unified-desktop" - class="checkbox selected-display-option-row" hidden> - <!-- intentionally blank for the title column space. --> - <div class="selected-display-option-title"> - </div> - <label> - <input id="display-options-toggle-unified-desktop" type="checkbox"> - <span class="controlled-setting-with-label"> - $i18n{enableUnifiedDesktop} - </span> - </label> - </div> - <div class="selected-display-option-row"> - <div class="selected-display-option-title"> - $i18n{selectedDisplayTitleResolution} - </div> - <select id="display-options-resolution-selection" - class="display-options-button"> - </select> - </div> - <div class="selected-display-option-row"> - <div class="selected-display-option-title"> - $i18n{selectedDisplayTitleOrientation} - </div> - <select id="display-options-orientation-selection" - class="display-options-button"> - <option value="0">$i18n{orientation0}</option> - <option value="90">$i18n{orientation90}</option> - <option value="180">$i18n{orientation180}</option> - <option value="270">$i18n{orientation270}</option> - </select> - </div> - <div class="selected-display-option-row"> - <div class="selected-display-option-title"> - $i18n{selectedDisplayTitleOverscan} - </div> - <button id="selected-display-start-calibrating-overscan" - class="display-options-button"> - $i18n{startCalibratingOverscan} - </button> - </div> - <div class="selected-display-option-row" - id="selected-display-color-profile-row" hidden> - <div class="selected-display-option-title"> - $i18n{selectedDisplayColorProfile} - </div> - <select id="display-options-color-profile-selection" - class="display-options-button"> - </select> - </div> - </div> - </div> - <!-- The arrow of display-configuration is achieved by a div - rotated by 45deg. --> - <div id="display-configuration-arrow"> - </div> - </div> - <div class="action-area"> - <div class="button-strip"> - <button id="display-options-done" class="default-button"> - $i18n{done} - </button> - </div> - </div> -</div>
diff --git a/chrome/browser/resources/options/chromeos/display_options.js b/chrome/browser/resources/options/chromeos/display_options.js deleted file mode 100644 index 9ffc820b..0000000 --- a/chrome/browser/resources/options/chromeos/display_options.js +++ /dev/null
@@ -1,729 +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. - -cr.exportPath('options'); - -/** - * Enumeration of multi display mode. These values must match the C++ values in - * ash::DisplayManager. - * @enum {number} - */ -options.MultiDisplayMode = { - EXTENDED: 0, - MIRRORING: 1, - UNIFIED: 2, -}; - -/** - * @typedef {{ - * width: number, - * height: number, - * originalWidth: number, - * originalHeight: number, - * deviceScaleFactor: number, - * scale: number, - * refreshRate: number, - * isBest: boolean, - * selected: boolean - * }} - */ -options.DisplayMode; - -/** - * @typedef {{ - * profileId: number, - * name: string - * }} - */ -options.ColorProfile; - -/** - * @typedef {{ - * availableColorProfiles: !Array<!options.ColorProfile>, - * bounds: !options.DisplayBounds, - * colorProfileId: number, - * id: string, - * isInternal: boolean, - * isPrimary: boolean, - * layoutType: (!options.DisplayLayoutType|undefined), - * name: string, - * offset: (number|undefined), - * parentId: (string|undefined), - * resolutions: !Array<!options.DisplayMode>, - * rotation: number - * }} - */ -options.DisplayInfo; - -cr.define('options', function() { - var Page = cr.ui.pageManager.Page; - var PageManager = cr.ui.pageManager.PageManager; - - // The scale ratio of the display rectangle to its original size. - /** @const */ var VISUAL_SCALE = 1 / 10; - - /** - * Encapsulated handling of the 'Display' page. - * @constructor - * @extends {cr.ui.pageManager.Page} - */ - function DisplayOptions() { - Page.call(this, 'display', - loadTimeData.getString('displayOptionsPageTabTitle'), - 'display-options-page'); - } - - cr.addSingletonGetter(DisplayOptions); - - DisplayOptions.prototype = { - __proto__: Page.prototype, - - /** - * Whether the current output status is mirroring displays or not. - * @type {boolean} - * @private - */ - mirroring_: false, - - /** - * Whether the unified desktop is enable or not. - * @type {boolean} - * @private - */ - unifiedDesktopEnabled_: false, - - /** - * Whether the unified desktop option should be present. - * @type {boolean} - * @private - */ - unifiedEnabled_: false, - - /** - * Whether the mirroring option should be present. - * @type {boolean} - * @private - */ - mirroredEnabled_: false, - - /** - * The array of current output displays. It also contains the display - * rectangles currently rendered on screen. - * @type {!Array<!options.DisplayInfo>} - * @private - */ - displays_: [], - - /** - * Manages the display layout. - * @type {?options.DisplayLayoutManager} - * @private - */ - displayLayoutManager_: null, - - /** - * The id of the currently focused display, or empty for none. - * @type {string} - * @private - */ - focusedId_: '', - - /** - * Drag info. - * @type {?{displayId: string, - * originalLocation: !options.DisplayPosition, - * eventLocation: !options.DisplayPosition}} - * @private - */ - dragInfo_: null, - - /** - * The container div element which contains all of the display rectangles. - * @type {?Element} - * @private - */ - displaysView_: null, - - /** - * The scale factor of the actual display size to the drawn display - * rectangle size. - * @type {number} - * @private - */ - visualScale_: VISUAL_SCALE, - - /** - * The location where the last touch event happened. This is used to - * prevent unnecessary dragging events happen. Set to null unless it's - * during touch events. - * @type {?options.DisplayPosition} - * @private - */ - lastTouchLocation_: null, - - /** - * Whether the display settings can be shown. - * @type {boolean} - * @private - */ - enabled_: true, - - /** @override */ - initializePage: function() { - Page.prototype.initializePage.call(this); - - $('display-options-select-mirroring').onchange = (function() { - this.mirroring_ = - $('display-options-select-mirroring').value == 'mirroring'; - chrome.send('setMirroring', [this.mirroring_]); - }).bind(this); - - var container = $('display-options-displays-view-host'); - container.onmousemove = this.onMouseMove_.bind(this); - window.addEventListener('mouseup', this.endDragging_.bind(this), true); - container.ontouchmove = this.onTouchMove_.bind(this); - container.ontouchend = this.endDragging_.bind(this); - - $('display-options-set-primary').onclick = (function() { - chrome.send('setPrimary', [this.focusedId_]); - }).bind(this); - $('display-options-resolution-selection').onchange = (function(ev) { - var display = this.getDisplayInfoFromId_(this.focusedId_); - if (!display) - return; - var resolution = display.resolutions[ev.target.value]; - chrome.send('setDisplayMode', [this.focusedId_, resolution]); - }).bind(this); - $('display-options-orientation-selection').onchange = (function(ev) { - var rotation = parseInt(ev.target.value, 10); - chrome.send('setRotation', [this.focusedId_, rotation]); - }).bind(this); - $('display-options-color-profile-selection').onchange = (function(ev) { - chrome.send('setColorProfile', [this.focusedId_, ev.target.value]); - }).bind(this); - $('selected-display-start-calibrating-overscan').onclick = (function() { - // Passes the target display ID. Do not specify it through URL hash, - // we do not care back/forward. - var displayOverscan = options.DisplayOverscan.getInstance(); - displayOverscan.setDisplayId(this.focusedId_); - PageManager.showPageByName('displayOverscan'); - chrome.send('coreOptionsUserMetricsAction', - ['Options_DisplaySetOverscan']); - }).bind(this); - - $('display-options-done').onclick = function() { - PageManager.closeOverlay(); - }; - - $('display-options-toggle-unified-desktop').onclick = (function() { - this.unifiedDesktopEnabled_ = !this.unifiedDesktopEnabled_; - chrome.send('setUnifiedDesktopEnabled', - [this.unifiedDesktopEnabled_]); - }).bind(this); - }, - - /** @override */ - didShowPage: function() { - var optionTitles = document.getElementsByClassName( - 'selected-display-option-title'); - var maxSize = 0; - for (var i = 0; i < optionTitles.length; i++) - maxSize = Math.max(maxSize, optionTitles[i].clientWidth); - for (var i = 0; i < optionTitles.length; i++) - optionTitles[i].style.width = maxSize + 'px'; - chrome.send('getDisplayInfo'); - }, - - /** @override */ - canShowPage: function() { return this.enabled_; }, - - /** - * Enables or disables the page. When disabled, the page will not be able to - * open, and will close if currently opened. Also sets the enabled states of - * mirrored and unifed desktop. - * @param {boolean} uiEnabled - * @param {boolean} unifiedEnabled - * @param {boolean} mirroredEnabled - */ - setEnabled: function(uiEnabled, unifiedEnabled, mirroredEnabled) { - this.unifiedEnabled_ = unifiedEnabled; - this.mirroredEnabled_ = mirroredEnabled; - if (this.enabled_ == uiEnabled) - return; - this.enabled_ = uiEnabled; - if (!uiEnabled && this.visible) - PageManager.closeOverlay(); - }, - - /** - * Mouse move handler for dragging display rectangle. - * @param {Event} e The mouse move event. - * @private - */ - onMouseMove_: function(e) { - return this.processDragging_(e, {x: e.pageX, y: e.pageY}); - }, - - /** - * Touch move handler for dragging display rectangle. - * @param {Event} e The touch move event. - * @private - */ - onTouchMove_: function(e) { - if (e.touches.length != 1) - return true; - - var touchLocation = {x: e.touches[0].pageX, y: e.touches[0].pageY}; - // Touch move events happen even if the touch location doesn't change, but - // it doesn't need to process the dragging. Since sometimes the touch - // position changes slightly even though the user doesn't think to move - // the finger, very small move is just ignored. - /** @const */ var IGNORABLE_TOUCH_MOVE_PX = 1; - var xDiff = Math.abs(touchLocation.x - this.lastTouchLocation_.x); - var yDiff = Math.abs(touchLocation.y - this.lastTouchLocation_.y); - if (xDiff <= IGNORABLE_TOUCH_MOVE_PX && - yDiff <= IGNORABLE_TOUCH_MOVE_PX) { - return true; - } - - this.lastTouchLocation_ = touchLocation; - return this.processDragging_(e, touchLocation); - }, - - /** - * Mouse down handler for dragging display rectangle. - * @param {Event} e The mouse down event. - * @private - */ - onMouseDown_: function(e) { - if (this.mirroring_) - return true; - - if (e.button != 0) - return true; - - e.preventDefault(); - var target = assertInstanceof(e.target, HTMLElement); - return this.startDragging_(target, {x: e.pageX, y: e.pageY}); - }, - - /** - * Touch start handler for dragging display rectangle. - * @param {Event} e The touch start event. - * @private - */ - onTouchStart_: function(e) { - if (this.mirroring_) - return true; - - if (e.touches.length != 1) - return false; - - e.preventDefault(); - var touch = e.touches[0]; - this.lastTouchLocation_ = {x: touch.pageX, y: touch.pageY}; - var target = assertInstanceof(e.target, HTMLElement); - return this.startDragging_(target, this.lastTouchLocation_); - }, - - /** - * @param {string} id - * @return {!options.DisplayInfo|undefined} - */ - getDisplayInfoFromId_(id) { - return this.displays_.find(function(display) { - return display.id == id; - }); - }, - - /** - * Sends the display layout for the secondary display to Chrome. - * @private - */ - sendDragResult_: function() { - var layouts = []; - for (var i = 0; i < this.displays_.length; i++) { - var id = this.displays_[i].id; - layouts.push(this.displayLayoutManager_.getDisplayLayout(id)); - } - chrome.send('setDisplayLayout', [layouts]); - }, - - /** - * Processes the actual dragging of display rectangle. - * @param {Event} e The event which triggers this drag. - * @param {options.DisplayPosition} eventLocation The location where the - * event happens. - * @private - */ - processDragging_: function(e, eventLocation) { - if (!this.dragInfo_) - return true; - - e.preventDefault(); - - var dragInfo = this.dragInfo_; - - /** @type {options.DisplayPosition} */ var newPosition = { - x: dragInfo.originalLocation.x + - (eventLocation.x - dragInfo.eventLocation.x), - y: dragInfo.originalLocation.y + - (eventLocation.y - dragInfo.eventLocation.y) - }; - - this.displayLayoutManager_.updatePosition( - dragInfo.displayId, newPosition); - - return false; - }, - - /** - * Start dragging of a display rectangle. - * @param {!HTMLElement} target The event target. - * @param {!options.DisplayPosition} eventLocation The event location. - * @private - */ - startDragging_: function(target, eventLocation) { - var focused = this.displayLayoutManager_.getFocusedLayoutForDiv(target); - if (!focused) - return false; - - var updateDisplayDescription = focused.id != this.focusedId_; - this.focusedId_ = focused.id; - this.displayLayoutManager_.setFocusedId( - focused.id, true /* user action */); - - if (this.displayLayoutManager_.getDisplayLayoutCount() > 1) { - this.dragInfo_ = { - displayId: focused.id, - originalLocation: { - x: focused.div.offsetLeft, - y: focused.div.offsetTop - }, - eventLocation: {x: eventLocation.x, y: eventLocation.y} - }; - } - - if (updateDisplayDescription) - this.updateSelectedDisplayDescription_(); - - return false; - }, - - /** - * finish the current dragging of displays. - * @param {Event} e The event which triggers this. - * @private - */ - endDragging_: function(e) { - this.lastTouchLocation_ = null; - if (!this.dragInfo_) - return false; - - if (this.displayLayoutManager_.finalizePosition(this.dragInfo_.displayId)) - this.sendDragResult_(); - - this.dragInfo_ = null; - - return false; - }, - - /** - * Updates the description of selected display section for mirroring mode. - * @private - */ - updateSelectedDisplaySectionMirroring_: function() { - $('display-configuration-arrow').hidden = true; - $('display-options-set-primary').disabled = true; - $('display-options-select-mirroring').disabled = false; - $('selected-display-start-calibrating-overscan').disabled = true; - var display = this.displays_[0]; - var orientation = $('display-options-orientation-selection'); - orientation.disabled = false; - var orientationOptions = orientation.getElementsByTagName('option'); - var orientationIndex = Math.floor(display.rotation / 90); - orientationOptions[orientationIndex].selected = true; - $('selected-display-name').textContent = - loadTimeData.getString('mirroringDisplay'); - var resolution = $('display-options-resolution-selection'); - var option = document.createElement('option'); - option.value = 'default'; - option.textContent = display.bounds.width + 'x' + display.bounds.height; - resolution.appendChild(option); - resolution.disabled = true; - }, - - /** - * Updates the description of selected display section when no display is - * selected. - * @private - */ - updateSelectedDisplaySectionNoSelected_: function() { - $('display-configuration-arrow').hidden = true; - $('display-options-set-primary').disabled = true; - $('display-options-select-mirroring').disabled = true; - $('selected-display-start-calibrating-overscan').disabled = true; - $('display-options-orientation-selection').disabled = true; - $('selected-display-name').textContent = ''; - var resolution = $('display-options-resolution-selection'); - resolution.appendChild(document.createElement('option')); - resolution.disabled = true; - }, - - /** - * Updates the description of selected display section for the selected - * display. - * @param {options.DisplayInfo} display The selected display object. - * @private - */ - updateSelectedDisplaySectionForDisplay_: function(display) { - var displayLayout = - this.displayLayoutManager_.getDisplayLayout(display.id); - var arrow = $('display-configuration-arrow'); - arrow.hidden = false; - // Adding 1 px to the position to fit the border line and the border in - // arrow precisely. - arrow.style.top = $('display-configurations').offsetTop - - arrow.offsetHeight / 2 + 'px'; - arrow.style.left = displayLayout.div.offsetLeft + - displayLayout.div.offsetWidth / 2 - arrow.offsetWidth / 2 + 'px'; - - $('display-options-set-primary').disabled = display.isPrimary; - $('display-options-select-mirroring').disabled = !this.mirroredEnabled_; - $('selected-display-start-calibrating-overscan').disabled = - display.isInternal; - - var orientation = $('display-options-orientation-selection'); - orientation.disabled = this.unifiedDesktopEnabled_; - - var orientationOptions = orientation.getElementsByTagName('option'); - var orientationIndex = Math.floor(display.rotation / 90); - orientationOptions[orientationIndex].selected = true; - - $('selected-display-name').textContent = display.name; - - var resolution = $('display-options-resolution-selection'); - if (display.resolutions.length <= 1) { - var option = document.createElement('option'); - option.value = 'default'; - option.textContent = display.bounds.width + 'x' + display.bounds.height; - option.selected = true; - resolution.appendChild(option); - resolution.disabled = true; - } else { - var previousOption; - for (var i = 0; i < display.resolutions.length; i++) { - var option = document.createElement('option'); - option.value = i; - option.textContent = display.resolutions[i].width + 'x' + - display.resolutions[i].height; - if (display.resolutions[i].isBest) { - option.textContent += ' ' + - loadTimeData.getString('annotateBest'); - } else if (display.resolutions[i].isNative) { - option.textContent += ' ' + - loadTimeData.getString('annotateNative'); - } - if (display.resolutions[i].deviceScaleFactor && previousOption && - previousOption.textContent == option.textContent) { - option.textContent += - ' (' + display.resolutions[i].deviceScaleFactor + 'x)'; - } - option.selected = display.resolutions[i].selected; - resolution.appendChild(option); - previousOption = option; - } - resolution.disabled = (display.resolutions.length <= 1); - } - - if (display.availableColorProfiles.length <= 1) { - $('selected-display-color-profile-row').hidden = true; - } else { - $('selected-display-color-profile-row').hidden = false; - var profiles = $('display-options-color-profile-selection'); - profiles.innerHTML = ''; - for (var i = 0; i < display.availableColorProfiles.length; i++) { - var option = document.createElement('option'); - var colorProfile = display.availableColorProfiles[i]; - option.value = colorProfile.profileId; - option.textContent = colorProfile.name; - option.selected = (display.colorProfileId == colorProfile.profileId); - profiles.appendChild(option); - } - } - }, - - /** - * Updates the description of the selected display section. - * @private - */ - updateSelectedDisplayDescription_: function() { - var resolution = $('display-options-resolution-selection'); - resolution.textContent = ''; - var orientation = $('display-options-orientation-selection'); - var orientationOptions = orientation.getElementsByTagName('option'); - for (var i = 0; i < orientationOptions.length; i++) - orientationOptions[i].selected = false; - - if (this.mirroring_) { - this.updateSelectedDisplaySectionMirroring_(); - } else if (this.focusedId_ == '') { - this.updateSelectedDisplaySectionNoSelected_(); - } else { - var focusedDisplay = this.getDisplayInfoFromId_(this.focusedId_); - if (focusedDisplay) - this.updateSelectedDisplaySectionForDisplay_(focusedDisplay); - } - }, - - /** - * Clears the drawing area for display rectangles. - * @private - */ - resetDisplaysView_: function() { - var displaysViewHost = $('display-options-displays-view-host'); - displaysViewHost.removeChild(displaysViewHost.firstChild); - this.displaysView_ = document.createElement('div'); - this.displaysView_.id = 'display-options-displays-view'; - displaysViewHost.appendChild(this.displaysView_); - }, - - /** - * Lays out the display rectangles for mirroring. - * @private - */ - layoutMirroringDisplays_: function() { - // Offset pixels for secondary display rectangles. The offset includes the - // border width. - /** @const */ var MIRRORING_OFFSET_PIXELS = 3; - // Always show two displays because there must be two displays when - // the display_options is enabled. Don't rely on displays_.length because - // there is only one display from chrome's perspective in mirror mode. - /** @const */ var MIN_NUM_DISPLAYS = 2; - /** @const */ var MIRRORING_VERTICAL_MARGIN = 20; - - // The width/height should be same as the first display: - var width = Math.ceil(this.displays_[0].bounds.width * this.visualScale_); - var height = - Math.ceil(this.displays_[0].bounds.height * this.visualScale_); - - var numDisplays = Math.max(MIN_NUM_DISPLAYS, this.displays_.length); - - var totalWidth = width + numDisplays * MIRRORING_OFFSET_PIXELS; - var totalHeight = height + numDisplays * MIRRORING_OFFSET_PIXELS; - - this.displaysView_.style.height = totalHeight + 'px'; - - // The displays should be centered. - var offsetX = - $('display-options-displays-view').offsetWidth / 2 - totalWidth / 2; - - for (var i = 0; i < numDisplays; i++) { - var div = /** @type {HTMLElement} */ (document.createElement('div')); - div.className = 'displays-display'; - div.style.top = i * MIRRORING_OFFSET_PIXELS + 'px'; - div.style.left = i * MIRRORING_OFFSET_PIXELS + offsetX + 'px'; - div.style.width = width + 'px'; - div.style.height = height + 'px'; - div.style.zIndex = i; - // set 'display-mirrored' class for the background display rectangles. - if (i != numDisplays - 1) - div.classList.add('display-mirrored'); - this.displaysView_.appendChild(div); - } - }, - - /** - * Layouts the display rectangles according to the current layout_. - * @private - */ - layoutDisplays_: function() { - // Create the layout manager. TODO(stevenjb): Elim DisplayLayoutManager() - // once DisplayLayoutManagerMulti is well tested. - if (this.displays_.length > 2) - this.displayLayoutManager_ = new options.DisplayLayoutManagerMulti(); - else - this.displayLayoutManager_ = new options.DisplayLayoutManager(); - - // Create the display layouts. - for (var i = 0; i < this.displays_.length; i++) { - var display = this.displays_[i]; - var layout = new options.DisplayLayout( - display.id, display.name, display.bounds, display.layoutType, - display.offset, display.parentId); - this.displayLayoutManager_.addDisplayLayout(layout); - } - - // Calculate the display area bounds and create the divs for each display. - this.visualScale_ = this.displayLayoutManager_.createDisplayArea( - /** @type {!Element} */(this.displaysView_), VISUAL_SCALE); - - this.displayLayoutManager_.setFocusedId(this.focusedId_); - this.displayLayoutManager_.setDivCallbacks( - this.onMouseDown_.bind(this), this.onTouchStart_.bind(this)); - }, - - /** - * Called when the display arrangement has changed. - * @param {options.MultiDisplayMode} mode multi display mode. - * @param {!Array<!options.DisplayInfo>} displays The list of the display - * information. - * @private - */ - onDisplayChanged_: function(mode, displays) { - if (!this.visible) - return; - - var mirroring = mode == options.MultiDisplayMode.MIRRORING; - var unifiedDesktopEnabled = mode == options.MultiDisplayMode.UNIFIED; - - // Focus to the first display next to the primary one when |displays_| - // is updated. - if (mirroring) { - this.focusedId_ = ''; - } else if ( - this.focusedId_ == '' || this.mirroring_ != mirroring || - this.unifiedDesktopEnabled_ != unifiedDesktopEnabled || - this.displays_.length != displays.length) { - this.focusedId_ = displays.length > 0 ? displays[0].id : ''; - } - - this.displays_ = displays; - this.mirroring_ = mirroring; - this.unifiedDesktopEnabled_ = unifiedDesktopEnabled; - - this.resetDisplaysView_(); - if (this.mirroring_) - this.layoutMirroringDisplays_(); - else - this.layoutDisplays_(); - - $('display-options-select-mirroring').value = - mirroring ? 'mirroring' : 'extended'; - - $('display-options-unified-desktop').hidden = !this.unifiedEnabled_; - - $('display-options-toggle-unified-desktop').checked = - this.unifiedDesktopEnabled_; - - var disableUnifiedDesktopOption = - (this.mirroring_ || - (!this.unifiedDesktopEnabled_ && this.displays_.length == 1)); - - $('display-options-toggle-unified-desktop').disabled = - disableUnifiedDesktopOption; - - this.updateSelectedDisplayDescription_(); - } - }; - - DisplayOptions.setDisplayInfo = function(mode, displays) { - DisplayOptions.getInstance().onDisplayChanged_(mode, displays); - }; - - // Export - return { - DisplayOptions: DisplayOptions - }; -});
diff --git a/chrome/browser/resources/options/chromeos/display_overscan.css b/chrome/browser/resources/options/chromeos/display_overscan.css deleted file mode 100644 index 6069a80..0000000 --- a/chrome/browser/resources/options/chromeos/display_overscan.css +++ /dev/null
@@ -1,63 +0,0 @@ -/* Copyright (c) 2013 The Chromium Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. */ - -#display-overscan-content-area { - margin: 20px; - padding: 0; -} - -#display-overscan-operations-table { - position: absolute; - width: 100%; -} - -#display-overscan-operations-table td { - font-size: 12px; - text-align: center; - width: 50%; -} - -.display-overscan-operation-image { - padding-bottom: 30px; -} - -#display-overscan-operation-images-row { - vertical-align: middle; -} - -#display-overscan-operation-arrows { - background-image: -webkit-image-set( - url(overscan_arrows.png) 1x, - url(overscan_arrows_2x.png) 2x); - background-position: center; - background-repeat: no-repeat; - height: 51px; - width: 100%; -} - -#display-overscan-operation-shift { - background-image: -webkit-image-set( - url(overscan_shift.png) 1x, - url(overscan_shift_2x.png) 2x); - background-position: center; - background-repeat: no-repeat; - height: 23px; - width: 100%; -} - -html[dir=rtl] #display-overscan-operation-shift { - background-image: -webkit-image-set( - url(overscan_shift_rtl.png) 1x, - url(overscan_shift_rtl_2x.png) 2x); -} - -#display-overscan-button-strip { - bottom: 0; - position: absolute; - width: 100%; -} - -#display-overscan-buttons-spacer { - -webkit-box-flex: 1; -}
diff --git a/chrome/browser/resources/options/chromeos/display_overscan.html b/chrome/browser/resources/options/chromeos/display_overscan.html deleted file mode 100644 index ce5b97f..0000000 --- a/chrome/browser/resources/options/chromeos/display_overscan.html +++ /dev/null
@@ -1,29 +0,0 @@ -<div id="display-overscan-page" class="page" hidden> - <div class="close-button"></div> - <div class="content-area" id="display-overscan-content-area"> - <table id="display-overscan-operations-table"> - <tr id="display-overscan-operation-images-row"> - <td class="display-overscan-operation-image"> - <div id="display-overscan-operation-arrows"></div></td> - <td class="display-overscan-operation-image"> - <div id="display-overscan-operation-shift"></div></td> - </tr> - <tr> - <td><span>$i18n{shrinkAndExpand}</span></td> - <td><span>$i18n{move}</span></td> - </tr> - </table> - <!-- Specify 'reversed' to prevernt re-reversing the button order by - options_page. --> - <div class="button-strip" id="display-overscan-button-strip" reversed> - <button id="display-overscan-operation-reset"> - $i18n{overscanReset} - </button> - <div id="display-overscan-buttons-spacer"></div> - <button id="display-overscan-operation-ok">$i18n{overscanOK}</button> - <button id="display-overscan-operation-cancel"> - $i18n{overscanCancel} - </button> - </div> - </div> -</div>
diff --git a/chrome/browser/resources/options/chromeos/display_overscan.js b/chrome/browser/resources/options/chromeos/display_overscan.js deleted file mode 100644 index ab1a176..0000000 --- a/chrome/browser/resources/options/chromeos/display_overscan.js +++ /dev/null
@@ -1,160 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -cr.define('options', function() { - var Page = cr.ui.pageManager.Page; - var PageManager = cr.ui.pageManager.PageManager; - - /** - * Encapsulated handling of the 'DisplayOverscan' page. - * @constructor - * @extends {cr.ui.pageManager.Page} - */ - function DisplayOverscan() { - Page.call(this, 'displayOverscan', - loadTimeData.getString('displayOverscanPageTabTitle'), - 'display-overscan-page'); - } - - cr.addSingletonGetter(DisplayOverscan); - - DisplayOverscan.prototype = { - __proto__: Page.prototype, - - /** - * The ID of the target display. - * @private {?string} - */ - id_: null, - - /** - * The keyboard event handler function. - * @private - */ - keyHandler_: null, - - /** @override */ - initializePage: function() { - Page.prototype.initializePage.call(this); - - this.keyHandler_ = this.handleKeyevent_.bind(this); - $('display-overscan-operation-reset').onclick = function() { - chrome.send('reset'); - }; - $('display-overscan-operation-ok').onclick = function() { - chrome.send('commit'); - PageManager.closeOverlay(); - }; - $('display-overscan-operation-cancel').onclick = function() { - PageManager.cancelOverlay(); - }; - }, - - /** @override */ - handleCancel: function() { - // signals the cancel event. - chrome.send('cancel'); - PageManager.closeOverlay(); - }, - - /** @override */ - didShowPage: function() { - if (this.id_ == null) { - PageManager.cancelOverlay(); - return; - } - - window.addEventListener('keydown', this.keyHandler_); - // Sets up the size of the overscan dialog based on DisplayOptions dialog. - var displayOptionsPage = $('display-options-page'); - var displayOverscanPage = $('display-overscan-page'); - displayOverscanPage.style.width = - displayOptionsPage.offsetWidth - 20 + 'px'; - displayOverscanPage.style.minWidth = displayOverscanPage.style.width; - displayOverscanPage.style.height = - displayOptionsPage.offsetHeight - 50 + 'px'; - - // Moves the table to describe operation at the middle of the contents - // vertically. - var operationsTable = $('display-overscan-operations-table'); - var buttonsContainer = $('display-overscan-button-strip'); - operationsTable.style.top = buttonsContainer.offsetTop / 2 - - operationsTable.offsetHeight / 2 + 'px'; - - $('display-overscan-operation-cancel').focus(); - chrome.send('start', [this.id_]); - }, - - /** @override */ - didClosePage: function() { - window.removeEventListener('keydown', this.keyHandler_); - }, - - /** - * Called when the overscan calibration is canceled at the system level, - * such like the display is disconnected. - * @private - */ - onOverscanCanceled_: function() { - if (PageManager.getTopmostVisiblePage() == this) - PageManager.cancelOverlay(); - }, - - /** - * Sets the target display id. This method has to be called before - * navigating to this page. - * @param {string} id The target display id. - */ - setDisplayId: function(id) { - this.id_ = id; - }, - - /** - * Key event handler to make the effect of display rectangle. - * @param {Event} event The keyboard event. - * @private - */ - handleKeyevent_: function(event) { - switch (event.keyCode) { - case 37: // left arrow - if (event.shiftKey) - chrome.send('move', ['horizontal', -1]); - else - chrome.send('resize', ['horizontal', -1]); - event.preventDefault(); - break; - case 38: // up arrow - if (event.shiftKey) - chrome.send('move', ['vertical', -1]); - else - chrome.send('resize', ['vertical', -1]); - event.preventDefault(); - break; - case 39: // right arrow - if (event.shiftKey) - chrome.send('move', ['horizontal', 1]); - else - chrome.send('resize', ['horizontal', 1]); - event.preventDefault(); - break; - case 40: // bottom arrow - if (event.shiftKey) - chrome.send('move', ['vertical', 1]); - else - chrome.send('resize', ['vertical', 1]); - event.preventDefault(); - break; - } - } - }; - - DisplayOverscan.onOverscanCanceled = function() { - DisplayOverscan.getInstance().onOverscanCanceled_(); - }; - - // Export - return { - DisplayOverscan: DisplayOverscan - }; -});
diff --git a/chrome/browser/resources/options/chromeos/internet_detail.css b/chrome/browser/resources/options/chromeos/internet_detail.css deleted file mode 100644 index 1b1d0011..0000000 --- a/chrome/browser/resources/options/chromeos/internet_detail.css +++ /dev/null
@@ -1,117 +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. */ - -/* Force tab strip to extend to the left and right edges of the window. */ -#internet-details-content-area { - -webkit-box-orient: vertical; - display: -webkit-box; - padding: 6px 0 0 0; -} - -#network-details-header { - -webkit-padding-start: 20px; - margin: 0; - padding-bottom: 12px; - padding-top: 32px; -} - -#network-details-title { - font-size: 18px; -} - -#network-details-subtitle-status { - color: rgb(53, 174, 71); -} - - -/* Fix the height of the subpages so that the dialog does not resize when the - user switches tabs. */ -#internet-details-content-area > .subpages-tab-contents { - -webkit-box-flex: 1; - -webkit-box-sizing: border-box; - -webkit-padding-end: 10px; - height: 390px; - min-width: 480px; - overflow-y: auto; -} - -/* Avoid additional margins between text fields and controlled setting - indicators as the fields in these dialogs have sufficient spacing around - them already. */ -#internet-details-content-area - input:-webkit-any([type='text'],[type='url'],:not([type])) + - .controlled-setting-indicator { - -webkit-margin-start: 0; -} - -#vpn-tab td { - padding: 0; -} - -#vpn-tab .option-value:not(input) { - padding: 4px; -} - -#vpn-tab.third-party-vpn-provider tr.built-in-vpn-provider-only { - display: none; -} - -#vpn-tab:not(.third-party-vpn-provider) tr.third-party-vpn-provider-only { - display: none; -} - -#ip-config-list { - min-height: 96px !important; -} - -/* Minimum and maximum height are integer multiples of the height of a list - entry. */ -#ignored-host-list { - -webkit-margin-start: 0; - border: 1px solid #bfbfbf; - min-height: 64px; - width: 400px; -} - -#ignored-host-list[disabled] { - background-color: rgb(235, 235, 228); - color: #999; - opacity: 1; -} - -#new-host { - -webkit-margin-start: 0; - margin-top: 8px; -} - -#ipconfig-section { - border-top: 1px solid #eee; - margin-bottom: 8px; - padding-top: 8px; -} - -#ipconfig-dns-section { - border-top: 1px solid #eee; - padding-top: 8px; -} - -#user-dns-settings:not([selected]) { - display: none; -} - -.dns-display { - -webkit-margin-start: 24px; - color: #bbb; - font-style: italic; - transition: opacity 150ms ease-in-out; -} - -.dns-display:not([selected]) { - display: none; - transition: opacity 150ms ease-in-out; -} - -.proxy-subsection { - padding-left: 24px; -}
diff --git a/chrome/browser/resources/options/chromeos/internet_detail.html b/chrome/browser/resources/options/chromeos/internet_detail.html deleted file mode 100644 index b3b07bb..0000000 --- a/chrome/browser/resources/options/chromeos/internet_detail.html +++ /dev/null
@@ -1,689 +0,0 @@ -<div id="details-internet-page" class="page" hidden> - <div class="close-button"></div> - <!-- Network header --> - <div id="network-details-header"> - <div id="network-details-title"></div> - <div id="network-details-subtitle"> - <span id="network-details-subtitle-status"></span> - <span id="network-details-subtitle-separator"> - </span> - <span id="network-details-subtitle-type"></span> - </div> - </div> - <div id="internet-details-content-area" class="content-area"> - <!-- Navigation tabs --> - <div id="details-tab-strip" class="subpages-nav-tabs"> - <span id="wifi-network-nav-tab" class="tab wifi-details" - tab-contents="wifi-network-tab"> - <span class="tab-label">$i18n{wifiNetworkTabLabel}</span> - <span class="active-tab-label">$i18n{wifiNetworkTabLabel}</span> - </span> - <span id="vpn-nav-tab" class="tab vpn-details" - tab-contents="vpn-tab"> - <span class="tab-label">$i18n{vpnTabLabel}</span> - <span class="active-tab-label">$i18n{vpnTabLabel}</span> - </span> - <span id="wimax-network-nav-tab" class="tab wimax-details" - tab-contents="wimax-network-tab"> - <span class="tab-label">$i18n{wimaxConnTabLabel}</span> - <span class="active-tab-label">$i18n{wimaxConnTabLabel}</span> - </span> - <span id="cellular-conn-nav-tab" class="tab cellular-details" - tab-contents="cellular-conn-tab"> - <span class="tab-label">$i18n{cellularConnTabLabel}</span> - <span class="active-tab-label">$i18n{cellularConnTabLabel}</span> - </span> - <span id="cellular-device-nav-tab" class="tab cellular-details" - tab-contents="cellular-device-tab"> - <span class="tab-label">$i18n{cellularDeviceTabLabel}</span> - <span class="active-tab-label">$i18n{cellularDeviceTabLabel}</span> - </span> - <span id="internet-nav-tab" class="tab network-details" - tab-contents="internet-tab"> - <span class="tab-label">$i18n{networkTabLabel}</span> - <span class="active-tab-label">$i18n{networkTabLabel}</span> - </span> - <span id="security-nav-tab" class="tab cellular-details gsm-only" - tab-contents="security-tab"> - <span class="tab-label">$i18n{securityTabLabel}</span> - <span class="active-tab-label">$i18n{securityTabLabel}</span> - </span> - <span id="internet-proxy-nav-tab" class="tab proxy-details" - tab-contents="network-proxy-tab"> - <span class="tab-label">$i18n{proxyTabLabel}</span> - <span class="active-tab-label">$i18n{proxyTabLabel}</span> - </span> - </div> - <div id="wifi-network-tab" class="subpages-tab-contents wifi-details"> - <section> - <table class="option-control-table"> - <tr id="prefer-network"> - <td> - <div class="checkbox controlled-setting-with-label"> - <label> - <input id="prefer-network-wifi" type="checkbox"> - <span> - <span>$i18n{inetPreferredNetwork}</span> - <span class="controlled-setting-indicator" - managed="Priority" - internet-detail-for="prefer-network-wifi"></span> - </span> - </label> - </div> - </td> - </tr> - <tr class="auto-connect-network"> - <td> - <div class="checkbox controlled-setting-with-label"> - <label> - <input id="auto-connect-network-wifi" type="checkbox"> - <span> - <span>$i18n{inetAutoConnectNetwork}</span> - <span class="controlled-setting-indicator" - managed="WiFi.AutoConnect" - internet-detail-for="auto-connect-network-wifi"> - </span> - </span> - </label> - </div> - </td> - </tr> - </table> - </section> - <section> - <table id="wifi-settings-table"> - <tr> - <td class="option-name">$i18n{connectionState}</td> - <td id="wifi-connection-state" class="option-value"></td> - </tr> - <tr> - <td class="option-name">$i18n{restrictedConnectivity}</td> - <td id="wifi-restricted-connectivity" class="option-value"></td> - </tr> - <tr> - <td class="option-name">$i18n{inetSsid}</td> - <td id="wifi-ssid" class="option-value"></td> - </tr> - <tr id="wifi-bssid-entry"> - <td class="option-name">$i18n{inetBssid}</td> - <td id="wifi-bssid" class="option-value"></td> - </tr> - <tr id="wifi-security-entry"> - <td class="options-name">$i18n{inetEncryption}</td> - <td id="wifi-security" class="option-value"></td> - </tr> - <tr> - <td class="options-name">$i18n{inetFrequency}</td> - <td id="wifi-frequency" class="option-value"></td> - </tr> - <tr> - <td class="options-name">$i18n{inetSignalStrength}</td> - <td id="wifi-signal-strength" class="option-value"></td> - </tr> - <tr id="wifi-hardware-address-entry"> - <td class="option-name">$i18n{hardwareAddress}</td> - <td id="wifi-hardware-address" class="option-value"></td> - </tr> - </table> - </section> - <section> - <table class="option-control-table"> - <tr> - <td id="password-details" class="option-name"> - $i18n{inetPassProtected} - </td> - </tr> - <tr> - <td id="wifi-shared-network" class="option-name"> - $i18n{inetNetworkShared} - </td> - </tr> - </table> - </section> - </div> - <div id="wimax-network-tab" class="subpages-tab-contents wimax-details"> - <section> - <table class="option-control-table"> - <tr class="auto-connect-network"> - <td> - <div class="checkbox controlled-setting-with-label"> - <label> - <input id="auto-connect-network-wimax" type="checkbox"> - <span> - <span>$i18n{inetAutoConnectNetwork}</span> - <span class="controlled-setting-indicator" - managed="WiMAX.AutoConnect" - internet-detail-for="auto-connect-network-wimax"> - </span> - </span> - </label> - </div> - </td> - </tr> - </table> - </section> - <section> - <table id="wimax-settings-table"> - <tr> - <td class="option-name">$i18n{connectionState}</td> - <td id="wimax-connection-state" class="option-value"></td> - </tr> - <tr> - <td class="option-name">$i18n{restrictedConnectivity}</td> - <td id="wimax-restricted-connectivity" class="option-value"></td> - </tr> - <tr id="wimax-eap-identity-entry"> - <td class="option-name">$i18n{inetUsername}</td> - <td id="wimax-eap-identity" class="option-value"></td> - </tr> - <tr> - <td class="options-name">$i18n{inetSignalStrength}</td> - <td id="wimax-signal-strength" class="option-value"></td> - </tr> - </table> - </section> - <section> - <table class="option-control-table"> - <tr> - <td id="wimax-shared-network" class="option-name"> - $i18n{inetNetworkShared} - </td> - </tr> - </table> - </section> - </div> - <div id="vpn-tab" class="subpages-tab-contents vpn-details"> - <section> - <table class="option-control-table"> - <tr class="auto-connect-network built-in-vpn-provider-only"> - <td> - <div class="checkbox controlled-setting-with-label"> - <label> - <input id="auto-connect-network-vpn" type="checkbox"> - <span> - <span>$i18n{inetAutoConnectNetwork}</span> - <span class="controlled-setting-indicator" - managed="VPN.AutoConnect" - internet-detail-for="auto-connect-network-vpn"></span> - </span> - </label> - </div> - </td> - </tr> - <tr> - <td class="option-name">$i18n{inetServiceName}</td> - <td id="inet-service-name" class="option-value"></td> - </tr> - <tr class="built-in-vpn-provider-only"> - <td class="option-name">$i18n{inetServerHostname}</td> - <td> - <input class="option-value" id="inet-server-hostname"></input> - <span class="controlled-setting-indicator" - managed="VPN.Host" - internet-detail-for="inet-server-hostname"></span> - </td> - </tr> - <tr> - <td class="option-name">$i18n{inetProviderType}</td> - <td id="inet-provider-type" class="option-value"></td> - </tr> - <tr class="third-party-vpn-provider-only"> - <td class="option-name">$i18n{inetProviderName}</td> - <td id="inet-provider-name" class="option-value"></td> - </tr> - <tr class="built-in-vpn-provider-only"> - <td class="option-name">$i18n{inetUsername}</td> - <td id="inet-username" class="option-value"></td> - </tr> - </table> - </section> - </div> - <div id="cellular-conn-tab" class="subpages-tab-contents cellular-details"> - <section id="cellular-network-options"> - <table class="option-control-table"> - <tr> - <td class="option-name">$i18n{serviceName}</td> - <td id="service-name" class="option-value"></td> - </tr> - <tr> - <td class="option-name">$i18n{networkTechnology}</td> - <td id="network-technology" class="option-value"></td> - </tr> - <tr> - <td class="option-name">$i18n{activationState}</td> - <td id="activation-state" class="option-value"></td> - </tr> - <tr> - <td class="option-name">$i18n{roamingState}</td> - <td id="roaming-state" class="option-value"></td> - </tr> - <tr> - <td class="option-name">$i18n{restrictedConnectivity}</td> - <td id="cellular-restricted-connectivity" class="option-value"></td> - </tr> - <tr> - <td class="option-name">$i18n{operatorName}</td> - <td id="operator-name" class="option-value"></td> - </tr> - <tr> - <td class="option-name">$i18n{operatorCode}</td> - <td id="operator-code" class="option-value"></td> - </tr> - <tr> - <td class="option-name">$i18n{errorState}</td> - <td id="error-state" class="option-value"></td> - </tr> - <tr class="gsm-only apn-list-view"> - <td class="option-name">$i18n{cellularApnLabel}</td> - <td id="cellular-apn-label" class="option-value"> - <select id="select-apn"> - <option value="-1">$i18n{cellularApnOther}</option> - </select> - <span class="controlled-setting-indicator" - managed="Cellular.APN" - internet-detail-for="select-apn"></span> - </td> - </tr> - <tr class="gsm-only apn-details-view"> - <td class="option-name">$i18n{cellularApnLabel}</td> - <td id="cellular-apn-label" class="option-value"> - <input id="cellular-apn" type="text"> - </td> - </tr> - <tr class="gsm-only apn-details-view"> - <td class="option-name">$i18n{cellularApnUsername}</td> - <td id="cellular-apn-username-label" class="option-value"> - <input id="cellular-apn-username" type="text"> - </td> - </tr> - <tr class="gsm-only apn-details-view"> - <td class="option-name">$i18n{cellularApnPassword}</td> - <td id="cellular-apn-password-label" class="option-value"> - <input id="cellular-apn-password" type="password"> - </td> - </tr> - <tr class="gsm-only apn-details-view"> - <td class="option-name"></td> - <td class="option-value"> - <button id="cellular-apn-use-default"> - $i18n{cellularApnUseDefault} - </button> - <button id="cellular-apn-set">$i18n{cellularApnSet}</button> - <button id="cellular-apn-cancel"> - $i18n{cellularApnCancel} - </button> - </td> - </tr> - <tr> - <td colspan="2"> - <div class="checkbox controlled-setting-with-label"> - <label> - <input id="auto-connect-network-cellular" type="checkbox"> - <span> - <span>$i18n{inetAutoConnectNetwork}</span> - <span class="controlled-setting-indicator" - managed="Cellular.AutoConnect" - internet-detail-for="auto-connect-network-cellular"> - </span> - </span> - </label> - </div> - </td> - </tr> - </table> - </section> - </div> - <div id="cellular-device-tab" class="subpages-tab-contents - cellular-details"> - <section id="cellular-device-options"> - <table class="option-control-table"> - <tr> - <td class="option-name">$i18n{cellularManufacturer}</td> - <td id="manufacturer" class="option-value"></td> - </tr> - <tr> - <td class="option-name">$i18n{modelId}</td> - <td id="model-id" class="option-value"></td> - </tr> - <tr> - <td class="option-name">$i18n{firmwareRevision}</td> - <td id="firmware-revision" class="option-value"></td> - </tr> - <tr> - <td class="option-name">$i18n{hardwareRevision}</td> - <td id="hardware-revision" class="option-value"></td> - </tr> - <tr class="cdma-only"> - <td class="option-name">$i18n{prlVersion}</td> - <td id="prl-version" class="option-value"></td> - </tr> - <tr> - <td class="option-name">MEID:</td> - <td id="meid" class="option-value"></td> - </tr> - <tr class="gsm-only"> - <td class="option-name">ICCID:</td> - <td id="iccid" class="option-value"></td> - </tr> - <tr> - <td class="option-name">ESN:</td> - <td id="esn" class="option-value"></td> - </tr> - <tr> - <td class="option-name">IMEI:</td> - <td id="imei" class="option-value"></td> - </tr> - <tr class="gsm-only"> - <td class="option-name">IMSI:</td> - <td id="imsi" class="option-value"></td> - </tr> - <tr> - <td class="option-name">MDN:</td> - <td id="mdn" class="option-value"></td> - </tr> - <tr> - <td class="option-name">MIN/MSID:</td> - <td id="min" class="option-value"></td> - </tr> - </table> - </section> - </div> - <div id="internet-tab" class="subpages-tab-contents"> - <section id="advanced-section"> - <table class="option-control-table"> - <tr> - <td class="option-name">$i18n{connectionState}</td> - <td id="connection-state" class="option-value"></td> - </tr> - <tr id="hardware-address-row"> - <td class="option-name">$i18n{hardwareAddress}</td> - <td id="hardware-address" class="option-value"></td> - </tr> - </table> - </section> - <section id="ipconfig-section"> - <div id="ip-automatic-configuration" - class="checkbox controlled-setting-with-label"> - <label> - <input id="ip-automatic-configuration-checkbox" - type="checkbox"> - <span> - <span>$i18n{ipAutomaticConfiguration}</span> - <span class="controlled-setting-indicator" - managed="IPAddressConfigType"></span> - </span> - </label> - </div> - <div> - <table id="ip-address-settings"> - <tr> - <td class="spacer" width="14px"></td> - <td class="option-name">$i18n{inetAddress}</td> - <td><div id="ip-address"></div></td> - </tr> - <tr> - <td class="spacer" width="14px"></td> - <td class="option-name" id="ip-netmask-label"> - $i18n{inetNetmask} - </td> - <td><div id="ip-netmask"></div></td> - </tr> - <tr> - <td class="spacer" width="14px"></td> - <td class="option-name">$i18n{inetGateway}</td> - <td><div id="ip-gateway"></div></td> - </tr> - <tr> - <td class="spacer" width="14px"></td> - <td class="option-name">$i18n{ipv6Address}</td> - <td><div id="ipv6-address"></div></td> - </tr> - </table> - </section> - <section id="ipconfig-dns-section"> - <div class="radio"> - <label> - <input id="automatic-dns-radio" type="radio" name="dnstype" - value="automatic"> - <span> - <span>$i18n{automaticNameServers}</span> - <span class="controlled-setting-indicator" - managed="NameServersConfigType"></span> - </span> - </label> - </div> - <div id="automatic-dns-display" class="dns-display"></div> - <div class="radio"> - <label> - <input id="google-dns-radio" type="radio" name="dnstype" - value="google"> - <span id="google-dns-label"></span> - </label> - </div> - <div id="google-dns-display" class="dns-display"></div> - <div class="radio"> - <label> - <input id="user-dns-radio" type="radio" name="dnstype" - value="user"> - <span>$i18n{userNameServers}</span> - </label> - </div> - <table id="user-dns-settings"> - <tr> - <td class="spacer" width="14px"></td> - <td> - <div id="ipconfig-dns1" i18n-placeholder-text="userNameServer1" - allow-empty> - </div> - </td> - <td> - <div id="ipconfig-dns2" i18n-placeholder-text="userNameServer2" - allow-empty> - </div> - </td> - </tr> - <tr> - <td class="spacer" width="14px"></td> - <td> - <div id="ipconfig-dns3" i18n-placeholder-text="userNameServer3" - allow-empty> - </div> - </td> - <td> - <div id="ipconfig-dns4" i18n-placeholder-text="userNameServer4" - allow-empty> - </div> - </td> - </tr> - </table> - </section> - </div> - <div id="security-tab" - class="subpages-tab-contents cellular-details gsm-only"> - <div id="cellular-security-options"> - <section> - <div id="sim-pin-lock" class="checkbox controlled-setting-with-label"> - <label> - <input id="sim-card-lock-enabled" type="checkbox"> - <span> - <span>$i18n{lockSimCard}</span> - <span class="controlled-setting-indicator" - managed="Cellular.SIMLockStatus.LockEnabled" - internet-detail-for="sim-card-lock-enabled"></span> - </span> - </label> - </div> - </section> - <section> - <div id="change-pin-area"> - <button id="change-pin">$i18n{changePinButton}</button> - <span class="controlled-setting-indicator" - managed="Cellular.SIMLockStatus.LockType" - internet-detail-for="change-pin"></span> - </div> - </section> - </div> - </div> - <div id="network-proxy-tab" class="subpages-tab-contents"> - <section> - <div id="network-proxy-info-banner" hidden> - <span id="banner-text" class="page-banner-text"></span> - </div> - <div class="radio"> - <label> - <input id="direct-proxy" type="radio" name="proxytype" value="1" - pref="cros.session.proxy.type"> - <span>$i18n{proxyDirectInternetConnection}</span> - </label> - </div> - <div class="radio"> - <label> - <input id="auto-proxy" type="radio" name="proxytype" value="3" - pref="cros.session.proxy.type"> - <span>$i18n{proxyAutomatic}</span> - </label> - </div> - <div class="proxy-subsection" id="auto-proxy-parms"> - <div class="checkbox"> - <label> - <input id="proxy-use-pac-url" type="checkbox" - pref="cros.session.proxy.usepacurl"> - <span>$i18n{proxyUseConfigUrl}</span> - </label> - </div> - <div> - <label> - <input id="proxy-pac-url" type="url" size="50" - pref="cros.session.proxy.pacurl"> - </label> - </div> - </div> - <div class="radio"> - <label> - <input id="manual-proxy" type="radio" name="proxytype" value="2" - pref="cros.session.proxy.type"> - <span>$i18n{proxyManual}</span> - </label> - </div> - <div class="proxy-subsection" id="manual-proxy-parms"> - <div class="checkbox"> - <label> - <input id="proxy-all-protocols" type="checkbox" - pref="cros.session.proxy.single"> - <span>$i18n{sameProxyProtocols}</span> - </label> - </div> - <div id="single-proxy"> - <table> - <tr> - <td> - <span>$i18n{httpProxy}</span> - <input id="proxy-host-single-name" type="text" size="25" - pref="cros.session.proxy.singlehttp" disabled> - </td> - <td> - <span>$i18n{proxyPort}</span> - <input id="proxy-host-single-port" size="4" - pref="cros.session.proxy.singlehttpport" disabled> - </td> - </tr> - </table> - </div> - <div id="multi-proxy"> - <table> - <tr> - <td> - <span>$i18n{httpProxy}</span> - </td> - <td> - <input id="proxy-host-name" type="text" size="25" - pref="cros.session.proxy.httpurl" disabled> - </td> - <td> - <span>$i18n{proxyPort}</span> - </td> - <td> - <input id="proxy-host-port" size="4" - pref="cros.session.proxy.httpport" disabled> - </td> - </tr> - <tr> - <td> - <span>$i18n{secureHttpProxy}</span> - </td> - <td> - <input id="secure-proxy-host-name" type="text" size="25" - pref="cros.session.proxy.httpsurl" disabled> - </td> - <td> - <span>$i18n{proxyPort}</span> - </td> - <td> - <input id="secure-proxy-port" size="4" - pref="cros.session.proxy.httpsport" disabled> - </td> - </tr> - <tr> - <td> - <span>$i18n{ftpProxy}</span> - </td> - <td> - <input id="ftp-proxy" type="text" size="25" - pref="cros.session.proxy.ftpurl" disabled> - </td> - <td> - <span>$i18n{proxyPort}</span> - </td> - <td> - <input id="ftp-proxy-port" size="4" - pref="cros.session.proxy.ftpport" disabled> - </td> - </tr> - <tr> - <td> - <span>$i18n{socksHost}</span> - </td> - <td> - <input id="socks-host" type="text" size="25" - pref="cros.session.proxy.socks" disabled> - </td> - <td> - <span>$i18n{proxyPort}</span> - </td> - <td> - <input id="socks-port" size="4" - pref="cros.session.proxy.socksport" disabled> - </td> - </tr> - </table> - </div> - <div id="advanced-config"> - <div class="option vbox flex"> - <div>$i18n{proxyBypass}</div> - <list id="ignored-host-list"></list> - <input id="new-host" type="url" size="30"> - <button id="add-host">$i18n{addHost}</button> - <button id="remove-host">$i18n{removeHost}</button> - </div> - </div> - </div> - <div class="proxy-subsection" id="web-proxy-auto-discovery"> - <span>$i18n{webProxyAutoDiscoveryUrl}</span> - <input id="web-proxy-auto-discovery-url" type="url" disabled> - </div> - </section> - </div> - </div> - <div class="action-area"> - <div class="button-strip"> - <!-- TODO(dbeam): Clarify style guide regarding tag wrap. --> - <button id="details-internet-dismiss" class="default-button"> - $i18n{detailsInternetDismiss} - </button> - <button id="details-internet-login">$i18n{connectButton}</button> - <button id="details-internet-disconnect">$i18n{disconnectButton}</button> - <button id="details-internet-configure">$i18n{configureButton}</button> - <button id="activate-details">$i18n{activateButton}</button> - <button id="view-account-details">$i18n{viewAccountButton}</button> - </div> - </div> -</div>
diff --git a/chrome/browser/resources/options/chromeos/internet_detail.js b/chrome/browser/resources/options/chromeos/internet_detail.js deleted file mode 100644 index 41db2c8..0000000 --- a/chrome/browser/resources/options/chromeos/internet_detail.js +++ /dev/null
@@ -1,1815 +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. - -// require: onc_data.js - -// NOTE(stevenjb): This code is in the process of being converted to be -// compatible with the networkingPrivate extension API: -// * The network property dictionaries are being converted to use ONC values. -// * chrome.send calls will be replaced with chrome.networkingPrivate calls. -// See crbug.com/279351 for more info. - -cr.define('options.internet', function() { - var OncData = cr.onc.OncData; - var Page = cr.ui.pageManager.Page; - var PageManager = cr.ui.pageManager.PageManager; - /** @const */ var IPAddressField = options.internet.IPAddressField; - - /** @const */ var GoogleNameServers = ['8.8.4.4', '8.8.8.8']; - /** @const */ var CarrierSprint = 'Sprint'; - /** @const */ var CarrierVerizon = 'Verizon Wireless'; - - /** - * Helper function to set hidden attribute for elements matching a selector. - * @param {string} selector CSS selector for extracting a list of elements. - * @param {boolean} hidden New hidden value. - */ - function updateHidden(selector, hidden) { - var elements = cr.doc.querySelectorAll(selector); - for (var i = 0, el; el = elements[i]; i++) { - el.hidden = hidden; - } - } - - /** - * Helper function to update the properties of the data object from the - * properties in the update object. - * @param {Object} data Object to update. - * @param {Object} update Object containing the updated properties. - */ - function updateDataObject(data, update) { - for (var prop in update) { - if (prop in data) - data[prop] = update[prop]; - } - } - - /** - * Monitor pref change of given element. - * @param {Element} el Target element. - */ - function observePrefsUI(el) { - Preferences.getInstance().addEventListener(el.pref, handlePrefUpdate); - } - - /** - * UI pref change handler. - * @param {Event} e The update event. - */ - function handlePrefUpdate(e) { - DetailsInternetPage.getInstance().updateControls(); - } - - /** - * Simple helper method for converting a field to a string. It is used to - * easily assign an empty string from fields that may be unknown or undefined. - * @param {Object} value that should be converted to a string. - * @return {string} the result. - */ - function stringFromValue(value) { - return value ? String(value) : ''; - } - - /** - * @param {string} action An action to send to coreOptionsUserMetricsAction. - */ - function sendChromeMetricsAction(action) { - chrome.send('coreOptionsUserMetricsAction', [action]); - } - - /** - * Send metrics to Chrome when the detailed page is opened. - * @param {string} type The ONC type of the network being shown. - * @param {string} state The ONC network state. - */ - function sendShowDetailsMetrics(type, state) { - if (type == 'WiFi') { - sendChromeMetricsAction('Options_NetworkShowDetailsWifi'); - if (state != 'NotConnected') - sendChromeMetricsAction('Options_NetworkShowDetailsWifiConnected'); - } else if (type == 'Cellular') { - sendChromeMetricsAction('Options_NetworkShowDetailsCellular'); - if (state != 'NotConnected') - sendChromeMetricsAction('Options_NetworkShowDetailsCellularConnected'); - } else if (type == 'VPN') { - sendChromeMetricsAction('Options_NetworkShowDetailsVPN'); - if (state != 'NotConnected') - sendChromeMetricsAction('Options_NetworkShowDetailsVPNConnected'); - } - } - - /** - * Returns the netmask as a string for a given prefix length. - * @param {number} prefixLength The ONC routing prefix length. - * @return {string} The corresponding netmask. - */ - function prefixLengthToNetmask(prefixLength) { - // Return the empty string for invalid inputs. - if (prefixLength < 0 || prefixLength > 32) - return ''; - var netmask = ''; - for (var i = 0; i < 4; ++i) { - var remainder = 8; - if (prefixLength >= 8) { - prefixLength -= 8; - } else { - remainder = prefixLength; - prefixLength = 0; - } - if (i > 0) - netmask += '.'; - var value = 0; - if (remainder != 0) - value = ((2 << (remainder - 1)) - 1) << (8 - remainder); - netmask += value.toString(); - } - return netmask; - } - - /** - * Returns the prefix length from the netmask string. - * @param {string} netmask The netmask string, e.g. 255.255.255.0. - * @return {number} The corresponding netmask or -1 if invalid. - */ - function netmaskToPrefixLength(netmask) { - var prefixLength = 0; - var tokens = netmask.split('.'); - if (tokens.length != 4) - return -1; - for (var i = 0; i < tokens.length; ++i) { - var token = tokens[i]; - // If we already found the last mask and the current one is not - // '0' then the netmask is invalid. For example, 255.224.255.0 - if (prefixLength / 8 != i) { - if (token != '0') - return -1; - } else if (token == '255') { - prefixLength += 8; - } else if (token == '254') { - prefixLength += 7; - } else if (token == '252') { - prefixLength += 6; - } else if (token == '248') { - prefixLength += 5; - } else if (token == '240') { - prefixLength += 4; - } else if (token == '224') { - prefixLength += 3; - } else if (token == '192') { - prefixLength += 2; - } else if (token == '128') { - prefixLength += 1; - } else if (token == '0') { - prefixLength += 0; - } else { - // mask is not a valid number. - return -1; - } - } - return prefixLength; - } - - // Returns true if we should show the 'View Account' button for |onc|. - // TODO(stevenjb): We should query the Mobile Config API for whether or not to - // show the 'View Account' button once it is integrated with Settings. - function shouldShowViewAccountButton(onc) { - var activationState = onc.getActiveValue('Cellular.ActivationState'); - if (activationState != 'Activating' && activationState != 'Activated') - return false; - - // If no online payment URL was provided by Shill, only show 'View Account' - // for Verizon Wireless. - if (!onc.getActiveValue('Cellular.PaymentPortal.Url') && - onc.getActiveValue('Cellular.Carrier') != CarrierVerizon) { - return false; - } - - // 'View Account' should only be shown for connected networks, or - // disconnected LTE networks with a valid MDN. - var connectionState = onc.getActiveValue('ConnectionState'); - if (connectionState != 'Connected') { - var technology = onc.getActiveValue('Cellular.NetworkTechnology'); - if (technology != 'LTE' && technology != 'LTEAdvanced') - return false; - if (!onc.getActiveValue('Cellular.MDN')) - return false; - } - - return true; - } - - ///////////////////////////////////////////////////////////////////////////// - // DetailsInternetPage class: - - /** - * Encapsulated handling of ChromeOS internet details overlay page. - * @constructor - * @extends {cr.ui.pageManager.Page} - */ - function DetailsInternetPage() { - // If non-negative, indicates a custom entry in select-apn. - this.userApnIndex_ = -1; - - // The custom APN properties associated with entry |userApnIndex_|. - this.userApn_ = {}; - - // The currently selected APN entry in $('select-apn') (which may or may not - // == userApnIndex_). - this.selectedApnIndex_ = -1; - - // We show the Proxy configuration tab for remembered networks and when - // configuring a proxy from the login screen. - this.showProxy_ = false; - - Page.call(this, 'detailsInternetPage', '', 'details-internet-page'); - } - - cr.addSingletonGetter(DetailsInternetPage); - - DetailsInternetPage.prototype = { - __proto__: Page.prototype, - - /** @override */ - initializePage: function() { - Page.prototype.initializePage.call(this); - this.initializePageContents_(); - - chrome.networkingPrivate.onNetworksChanged.addListener( - this.onNetworksChanged_.bind(this)); - - this.showNetworkDetails_(); - }, - - /** - * Automatically shows the network details dialog if network information - * is included in the URL. - */ - showNetworkDetails_: function() { - var guid = parseQueryParams(window.location).guid; - if (!guid || !guid.length) - return; - chrome.networkingPrivate.getManagedProperties( - guid, DetailsInternetPage.initializeDetailsPage); - }, - - /** - * networkingPrivate callback when networks change. - * @param {Array<string>} changes List of GUIDs whose properties have - * changed. - * @private - */ - onNetworksChanged_: function(changes) { - if (!this.onc_) - return; - var guid = this.onc_.guid(); - if (changes.indexOf(guid) != -1) { - chrome.networkingPrivate.getManagedProperties( - guid, DetailsInternetPage.updateConnectionData); - } - }, - - /** - * Initializes the contents of the page. - */ - initializePageContents_: function() { - $('details-internet-dismiss').addEventListener('click', function(event) { - DetailsInternetPage.setDetails(); - }); - - $('details-internet-login').addEventListener('click', function(event) { - DetailsInternetPage.setDetails(); - DetailsInternetPage.loginFromDetails(); - }); - - $('details-internet-disconnect').addEventListener('click', - function(event) { - DetailsInternetPage.setDetails(); - DetailsInternetPage.disconnectNetwork(); - }); - - $('details-internet-configure').addEventListener('click', - function(event) { - DetailsInternetPage.setDetails(); - DetailsInternetPage.configureNetwork(); - }); - - $('activate-details').addEventListener('click', function(event) { - DetailsInternetPage.activateFromDetails(); - }); - - $('view-account-details').addEventListener('click', function(event) { - chrome.send('showMorePlanInfo', - [DetailsInternetPage.getInstance().onc_.guid()]); - PageManager.closeOverlay(); - }); - - $('cellular-apn-use-default').addEventListener('click', function(event) { - DetailsInternetPage.getInstance().setDefaultApn_(); - }); - - $('cellular-apn-set').addEventListener('click', function(event) { - DetailsInternetPage.getInstance().setApn_($('cellular-apn').value); - }); - - $('cellular-apn-cancel').addEventListener('click', function(event) { - DetailsInternetPage.getInstance().cancelApn_(); - }); - - $('select-apn').addEventListener('change', function(event) { - DetailsInternetPage.getInstance().selectApn_(); - }); - - $('sim-card-lock-enabled').addEventListener('click', function(event) { - var newValue = $('sim-card-lock-enabled').checked; - // Leave value as is because user needs to enter PIN code first. - // When PIN will be entered and value changed, - // we'll update UI to reflect that change. - $('sim-card-lock-enabled').checked = !newValue; - var operation = newValue ? 'setLocked' : 'setUnlocked'; - chrome.send('simOperation', [operation]); - }); - $('change-pin').addEventListener('click', function(event) { - chrome.send('simOperation', ['changePin']); - }); - - // Proxy - ['proxy-host-single-port', - 'secure-proxy-port', - 'socks-port', - 'ftp-proxy-port', - 'proxy-host-port' - ].forEach(function(id) { - options.PrefPortNumber.decorate($(id)); - }); - - options.proxyexceptions.ProxyExceptions.decorate($('ignored-host-list')); - $('remove-host').addEventListener('click', - this.handleRemoveProxyExceptions_); - $('add-host').addEventListener('click', this.handleAddProxyException_); - $('direct-proxy').addEventListener('click', this.disableManualProxy_); - $('manual-proxy').addEventListener('click', this.enableManualProxy_); - $('auto-proxy').addEventListener('click', this.disableManualProxy_); - $('proxy-all-protocols').addEventListener('click', - this.toggleSingleProxy_); - $('proxy-use-pac-url').addEventListener('change', - this.handleAutoConfigProxy_); - - observePrefsUI($('direct-proxy')); - observePrefsUI($('manual-proxy')); - observePrefsUI($('auto-proxy')); - observePrefsUI($('proxy-all-protocols')); - observePrefsUI($('proxy-use-pac-url')); - - $('ip-automatic-configuration-checkbox').addEventListener('click', - this.handleIpAutoConfig_); - $('automatic-dns-radio').addEventListener('click', - this.handleNameServerTypeChange_); - $('google-dns-radio').addEventListener('click', - this.handleNameServerTypeChange_); - $('user-dns-radio').addEventListener('click', - this.handleNameServerTypeChange_); - - // We only load this string if we have the string data available - // because the proxy settings page on the login screen re-uses the - // proxy sub-page from the internet options, and it doesn't ever - // show the DNS settings, so we don't need this string there. - // The string isn't available because - // chrome://settings-frame/strings.js (where the string is - // stored) is not accessible from the login screen. - // TODO(pneubeck): Remove this once i18n of the proxy dialog on the login - // page is fixed. http://crbug.com/242865 - if (loadTimeData.data_) { - $('google-dns-label').innerHTML = - loadTimeData.getString('googleNameServers'); - } - }, - - /** - * Handler for "add" event fired from userNameEdit. - * @param {Event} e Add event fired from userNameEdit. - * @private - */ - handleAddProxyException_: function(e) { - var exception = $('new-host').value; - $('new-host').value = ''; - - exception = exception.trim(); - if (exception) - $('ignored-host-list').addException(exception); - }, - - /** - * Handler for when the remove button is clicked - * @param {Event} e The click event. - * @private - */ - handleRemoveProxyExceptions_: function(e) { - var selectedItems = $('ignored-host-list').selectedItems; - for (var x = 0; x < selectedItems.length; x++) { - $('ignored-host-list').removeException(selectedItems[x]); - } - }, - - /** - * Handler for when the IP automatic configuration checkbox is clicked. - * @param {Event} e The click event. - * @private - */ - handleIpAutoConfig_: function(e) { - var checked = $('ip-automatic-configuration-checkbox').checked; - var fields = [$('ip-address'), $('ip-netmask'), $('ip-gateway')]; - for (var i = 0; i < fields.length; ++i) { - fields[i].editable = !checked; - if (checked) { - var model = fields[i].model; - model.value = model.automatic; - fields[i].model = model; - } - } - if (!checked) - $('ip-address').focus(); - }, - - /** - * Handler for when the name server selection changes. - * @param {Event} event The click event. - * @private - */ - handleNameServerTypeChange_: function(event) { - var type = event.target.value; - DetailsInternetPage.updateNameServerDisplay(type); - }, - - /** - * Gets the IPConfig ONC Object. - * @param {string} nameServerType The selected name server type: - * 'automatic', 'google', or 'user'. - * @return {Object} The IPConfig ONC object. - * @private - */ - getIpConfig_: function(nameServerType) { - var ipConfig = {}; - // If 'ip-address' is empty, automatic configuration will be used. - if (!$('ip-automatic-configuration-checkbox').checked && - $('ip-address').model.value) { - ipConfig['IPAddress'] = $('ip-address').model.value; - var netmask = $('ip-netmask').model.value; - var routingPrefix = 0; - if (netmask) { - routingPrefix = netmaskToPrefixLength(netmask); - if (routingPrefix == -1) { - console.error('Invalid netmask: ' + netmask); - routingPrefix = 0; - } - } - ipConfig['RoutingPrefix'] = routingPrefix; - ipConfig['Gateway'] = $('ip-gateway').model.value || ''; - } - - // Note: If no nameserver fields are set, automatic configuration will be - // used. TODO(stevenjb): Validate input fields. - if (nameServerType != 'automatic') { - var userNameServers = []; - if (nameServerType == 'google') { - userNameServers = GoogleNameServers.slice(); - } else if (nameServerType == 'user') { - for (var i = 1; i <= 4; ++i) { - var nameServerField = $('ipconfig-dns' + i); - // Skip empty values. - if (nameServerField && nameServerField.model && - nameServerField.model.value) { - userNameServers.push(nameServerField.model.value); - } - } - } - if (userNameServers.length) - ipConfig['NameServers'] = userNameServers.sort(); - } - return ipConfig; - }, - - /** - * Creates an indicator event for controlled properties using - * the same dictionary format as CoreOptionsHandler::CreateValueForPref. - * @param {string} name The name for the Event. - * @param {{value: *, controlledBy: *, recommendedValue: *}} propData - * Property dictionary. - * @private - */ - createControlledEvent_: function(name, propData) { - assert('value' in propData && 'controlledBy' in propData && - 'recommendedValue' in propData); - var event = new Event(name); - event.value = { - value: propData.value, - controlledBy: propData.controlledBy, - recommendedValue: propData.recommendedValue - }; - return event; - }, - - /** - * Creates an indicator event for controlled properties using - * the ONC getManagedProperties dictionary format. - * @param {string} name The name for the Event. - * @param {Object} propData ONC managed network property dictionary. - * @private - */ - createManagedEvent_: function(name, propData) { - var event = new Event(name); - event.value = {}; - - // Set the current value and recommended value. - var activeValue = propData['Active']; - var effective = propData['Effective']; - if (activeValue == undefined) - activeValue = propData[effective]; - event.value.value = activeValue; - - // If a property is editable then it is not enforced, and 'controlledBy' - // is set to 'recommended' unless effective == {User|Shared}Setting, in - // which case the value was modified from the recommended value. - // Otherwise if 'Effective' is set to 'UserPolicy' or 'DevicePolicy' then - // the set value is mandated by the policy. - if (propData['UserEditable']) { - if (effective == 'UserPolicy') - event.value.controlledBy = 'recommended'; - event.value.recommendedValue = propData['UserPolicy']; - } else if (propData['DeviceEditable']) { - if (effective == 'DevicePolicy') - event.value.controlledBy = 'recommended'; - event.value.recommendedValue = propData['DevicePolicy']; - } else if (effective == 'UserPolicy' || effective == 'DevicePolicy') { - event.value.controlledBy = 'policy'; - } - - return event; - }, - - /** - * Update details page controls. - */ - updateControls: function() { - // Note: onc may be undefined when called from a pref update before - // initialized in initializeDetailsPage. - var onc = this.onc_; - - // Always show the ipconfig section. TODO(stevenjb): Improve the display - // for unconnected networks. Currently the IP address fields may be - // blank if the network is not connected. - $('ipconfig-section').hidden = false; - $('ipconfig-dns-section').hidden = false; - - // Network type related. - updateHidden('#details-internet-page .cellular-details', - this.type_ != 'Cellular'); - updateHidden('#details-internet-page .wifi-details', - this.type_ != 'WiFi'); - updateHidden('#details-internet-page .wimax-details', - this.type_ != 'WiMAX'); - updateHidden('#details-internet-page .vpn-details', this.type_ != 'VPN'); - updateHidden('#details-internet-page .proxy-details', !this.showProxy_); - - // Cellular - if (onc && this.type_ == 'Cellular') { - // Hide gsm/cdma specific elements. - if (onc.getActiveValue('Cellular.Family') == 'GSM') - updateHidden('#details-internet-page .cdma-only', true); - else - updateHidden('#details-internet-page .gsm-only', true); - } - - // Wifi - - // Hide network tab for VPN. - updateHidden('#details-internet-page .network-details', - this.type_ == 'VPN'); - - // Password and shared. - var source = onc ? onc.getSource() : 'None'; - var shared = (source == 'Device' || source == 'DevicePolicy'); - var security = onc ? onc.getWiFiSecurity() : 'None'; - updateHidden('#details-internet-page #password-details', - this.type_ != 'WiFi' || security == 'None'); - updateHidden('#details-internet-page #wifi-shared-network', !shared); - updateHidden('#details-internet-page #prefer-network', source == 'None'); - - // WiMAX. - updateHidden('#details-internet-page #wimax-shared-network', !shared); - - // Proxy - this.updateProxyBannerVisibility_(); - this.toggleSingleProxy_(); - if ($('manual-proxy').checked) - this.enableManualProxy_(); - else - this.disableManualProxy_(); - }, - - /** - * Updates info banner visibility state. This function shows the banner - * if proxy is managed or shared-proxies is off for shared network. - * @private - */ - updateProxyBannerVisibility_: function() { - var bannerDiv = $('network-proxy-info-banner'); - if (!loadTimeData.data_) { - // TODO(pneubeck): This temporarily prevents an exception below until - // i18n of the proxy dialog on the login page is - // fixed. http://crbug.com/242865 - bannerDiv.hidden = true; - return; - } - - // Show banner and determine its message if necessary. - var controlledBy = $('direct-proxy').controlledBy; - if (!controlledBy || controlledBy == '') { - bannerDiv.hidden = true; - } else { - bannerDiv.hidden = false; - // The possible banner texts are loaded in proxy_handler.cc. - var bannerText = 'proxyBanner' + controlledBy.charAt(0).toUpperCase() + - controlledBy.slice(1); - $('banner-text').textContent = loadTimeData.getString(bannerText); - } - }, - - /** - * Handler for when the user clicks on the checkbox to allow a - * single proxy usage. - * @private - */ - toggleSingleProxy_: function() { - if ($('proxy-all-protocols').checked) { - $('multi-proxy').hidden = true; - $('single-proxy').hidden = false; - } else { - $('multi-proxy').hidden = false; - $('single-proxy').hidden = true; - } - }, - - /** - * Handler for when the user clicks on the checkbox to enter - * auto configuration URL. - * @private - */ - handleAutoConfigProxy_: function() { - $('proxy-pac-url').disabled = !$('proxy-use-pac-url').checked; - }, - - /** - * Handler for selecting a radio button that will disable the manual - * controls. - * @private - */ - disableManualProxy_: function() { - $('ignored-host-list').disabled = true; - $('new-host').disabled = true; - $('remove-host').disabled = true; - $('add-host').disabled = true; - $('proxy-all-protocols').disabled = true; - $('proxy-host-name').disabled = true; - $('proxy-host-port').disabled = true; - $('proxy-host-single-name').disabled = true; - $('proxy-host-single-port').disabled = true; - $('secure-proxy-host-name').disabled = true; - $('secure-proxy-port').disabled = true; - $('ftp-proxy').disabled = true; - $('ftp-proxy-port').disabled = true; - $('socks-host').disabled = true; - $('socks-port').disabled = true; - $('proxy-use-pac-url').disabled = $('auto-proxy').disabled || - !$('auto-proxy').checked; - $('proxy-pac-url').disabled = $('proxy-use-pac-url').disabled || - !$('proxy-use-pac-url').checked; - $('auto-proxy-parms').hidden = !$('auto-proxy').checked; - $('manual-proxy-parms').hidden = !$('manual-proxy').checked; - sendChromeMetricsAction('Options_NetworkManualProxy_Disable'); - }, - - /** - * Handler for selecting a radio button that will enable the manual - * controls. - * @private - */ - enableManualProxy_: function() { - $('ignored-host-list').redraw(); - var allDisabled = $('manual-proxy').disabled; - $('ignored-host-list').disabled = allDisabled; - $('new-host').disabled = allDisabled; - $('remove-host').disabled = allDisabled; - $('add-host').disabled = allDisabled; - $('proxy-all-protocols').disabled = allDisabled; - $('proxy-host-name').disabled = allDisabled; - $('proxy-host-port').disabled = allDisabled; - $('proxy-host-single-name').disabled = allDisabled; - $('proxy-host-single-port').disabled = allDisabled; - $('secure-proxy-host-name').disabled = allDisabled; - $('secure-proxy-port').disabled = allDisabled; - $('ftp-proxy').disabled = allDisabled; - $('ftp-proxy-port').disabled = allDisabled; - $('socks-host').disabled = allDisabled; - $('socks-port').disabled = allDisabled; - $('proxy-use-pac-url').disabled = true; - $('proxy-pac-url').disabled = true; - $('auto-proxy-parms').hidden = !$('auto-proxy').checked; - $('manual-proxy-parms').hidden = !$('manual-proxy').checked; - sendChromeMetricsAction('Options_NetworkManualProxy_Enable'); - }, - - /** - * Helper method called from initializeDetailsPage and updateConnectionData. - * Updates visibility/enabled of the login/disconnect/configure buttons. - * @private - */ - updateConnectionButtonVisibility_: function() { - var onc = this.onc_; - - var prohibitedByPolicy = - this.type_ == 'WiFi' && - loadTimeData.valueExists('allowOnlyPolicyNetworksToConnect') && - loadTimeData.getBoolean('allowOnlyPolicyNetworksToConnect') && - (onc.data_.Source != 'DevicePolicy' && - onc.data_.Source != 'UserPolicy'); - - if (this.type_ == 'Ethernet') { - // Ethernet can never be connected or disconnected and can always be - // configured (e.g. to set security). - $('details-internet-login').hidden = true; - $('details-internet-disconnect').hidden = true; - $('details-internet-configure').hidden = false; - return; - } - - var connectable = onc.getActiveValue('Connectable'); - var connectState = onc.getActiveValue('ConnectionState'); - if (connectState == 'NotConnected') { - $('details-internet-disconnect').hidden = true; - $('details-internet-login').hidden = false; - // Connecting to an unconfigured network might trigger certificate - // installation UI. Until that gets handled here, always enable the - // Connect button for built-in networks. - var enabled = ((this.type_ != 'VPN') || - (onc.getActiveValue('VPN.Type') != 'ThirdPartyVPN') || - connectable) && !prohibitedByPolicy; - if (prohibitedByPolicy) { - $('details-internet-login').setAttribute( - 'title', loadTimeData.getString('prohibitedNetwork')); - } else { - $('details-internet-login').removeAttribute('title'); - } - $('details-internet-login').disabled = !enabled; - } else { - $('details-internet-login').hidden = true; - $('details-internet-disconnect').hidden = false; - } - - var showConfigure = false; - if (this.type_ == 'VPN') { - showConfigure = true; - } else if (this.type_ == 'WiMAX' && connectState == 'NotConnected') { - showConfigure = true; - } else if (this.type_ == 'WiFi') { - showConfigure = (connectState == 'NotConnected' && - (!connectable || onc.getWiFiSecurity() != 'None') && - !prohibitedByPolicy); - } - $('details-internet-configure').hidden = !showConfigure; - }, - - /** - * Helper method called from initializeDetailsPage and updateConnectionData. - * Updates the connection state property and account / sim card links. - * @private - */ - updateDetails_: function() { - var onc = this.onc_; - - var connectionStateString = onc.getTranslatedValue('ConnectionState'); - $('connection-state').textContent = connectionStateString; - - var type = this.type_; - var showViewAccount = false; - var showActivate = false; - if (type == 'WiFi') { - $('wifi-connection-state').textContent = connectionStateString; - } else if (type == 'WiMAX') { - $('wimax-connection-state').textContent = connectionStateString; - } else if (type == 'Cellular') { - $('activation-state').textContent = - onc.getTranslatedValue('Cellular.ActivationState'); - if (onc.getActiveValue('Cellular.Family') == 'GSM') { - var lockEnabled = - onc.getActiveValue('Cellular.SIMLockStatus.LockEnabled'); - $('sim-card-lock-enabled').checked = lockEnabled; - $('change-pin').hidden = !lockEnabled; - } - showViewAccount = shouldShowViewAccountButton(onc); - var activationState = onc.getActiveValue('Cellular.ActivationState'); - showActivate = (activationState == 'NotActivated' || - activationState == 'PartiallyActivated'); - } - - $('view-account-details').hidden = !showViewAccount; - $('activate-details').hidden = !showActivate; - // If activation is not complete, hide the login button. - if (showActivate) - $('details-internet-login').hidden = true; - }, - - /** - * Helper method called from initializeDetailsPage and updateConnectionData. - * Updates the fields in the header section of the details frame. - * @private - */ - populateHeader_: function() { - var onc = this.onc_; - - var name = onc.getTranslatedValue('Name'); - if (onc.getActiveValue('Type') == 'VPN' && - onc.getActiveValue('VPN.Type') == 'ThirdPartyVPN') { - var providerName = - onc.getActiveValue('VPN.ThirdPartyVPN.ProviderName') || - loadTimeData.getString('defaultThirdPartyProviderName'); - name = loadTimeData.getStringF('vpnNameTemplate', providerName, name); - } - $('network-details-title').textContent = name; - - var connectionStateString = onc.getTranslatedValue('ConnectionState'); - $('network-details-subtitle-status').textContent = connectionStateString; - - var typeKey; - var type = this.type_; - if (type == 'Ethernet') - typeKey = 'ethernetTitle'; - else if (type == 'WiFi') - typeKey = 'wifiTitle'; - else if (type == 'WiMAX') - typeKey = 'wimaxTitle'; - else if (type == 'Cellular') - typeKey = 'cellularTitle'; - else if (type == 'VPN') - typeKey = 'vpnTitle'; - else - typeKey = null; - var typeLabel = $('network-details-subtitle-type'); - var typeSeparator = $('network-details-subtitle-separator'); - if (typeKey) { - typeLabel.textContent = loadTimeData.getString(typeKey); - typeLabel.hidden = false; - typeSeparator.hidden = false; - } else { - typeLabel.hidden = true; - typeSeparator.hidden = true; - } - }, - - /** - * Helper method to insert a 'user' option into the Apn list. - * @param {Object} userOption The 'user' apn dictionary - * @private - */ - insertApnUserOption_: function(userOption) { - // Add the 'user' option before the last option ('other') - var apnSelector = $('select-apn'); - assert(apnSelector.length > 0); - var otherOption = apnSelector[apnSelector.length - 1]; - apnSelector.add(userOption, otherOption); - this.userApnIndex_ = apnSelector.length - 2; - this.selectedApnIndex_ = this.userApnIndex_; - }, - - /** - * Helper method called from initializeApnList to populate the Apn list. - * @param {Array} apnList List of available APNs. - * @private - */ - populateApnList_: function(apnList) { - var onc = this.onc_; - var apnSelector = $('select-apn'); - assert(apnSelector.length == 1); - var otherOption = apnSelector[0]; - var activeApn = onc.getActiveValue('Cellular.APN.AccessPointName'); - var lastGoodApn = - onc.getActiveValue('Cellular.LastGoodAPN.AccessPointName'); - for (var i = 0; i < apnList.length; i++) { - var apnDict = apnList[i]; - var localizedName = apnDict['LocalizedName']; - var name = localizedName ? localizedName : apnDict['Name']; - var accessPointName = apnDict['AccessPointName']; - var option = document.createElement('option'); - option.textContent = - name ? (name + ' (' + accessPointName + ')') : accessPointName; - option.value = i; - // Insert new option before 'other' option. - apnSelector.add(option, otherOption); - if (this.selectedApnIndex_ != -1) - continue; - // If this matches the active Apn name, or LastGoodApn name (or there - // is no last good APN), set it as the selected Apn. - if ((activeApn == accessPointName) || - (!activeApn && (!lastGoodApn || lastGoodApn == accessPointName))) { - this.selectedApnIndex_ = i; - } - } - if (this.selectedApnIndex_ == -1 && activeApn) { - this.userApn_ = activeApn; - // Create a 'user' entry for any active apn not in the list. - var userOption = document.createElement('option'); - userOption.textContent = activeApn; - userOption.value = -1; - this.insertApnUserOption_(userOption); - } - }, - - /** - * Helper method called from initializeDetailsPage to initialize the Apn - * list. - * @private - */ - initializeApnList_: function() { - this.selectedApnIndex_ = -1; - this.userApnIndex_ = -1; - - var onc = this.onc_; - var apnSelector = /** @type {HTMLSelectElement} */($('select-apn')); - - // Clear APN lists, keep only last element, 'other'. - while (apnSelector.length != 1) - apnSelector.remove(0); - - var apnList = onc.getActiveValue('Cellular.APNList'); - if (apnList) { - // Populate the list with the existing APNs. - this.populateApnList_(apnList); - } else { - // Create a single 'default' entry. - var otherOption = apnSelector[0]; - var defaultOption = /** @type {HTMLElement} */( - document.createElement('option')); - defaultOption.textContent = - loadTimeData.getString('cellularApnUseDefault'); - defaultOption.value = -1; - // Add 'default' entry before 'other' option - apnSelector.add(defaultOption, otherOption); - assert(apnSelector.length == 2); // 'default', 'other' - this.selectedApnIndex_ = 0; // Select 'default' - } - assert(this.selectedApnIndex_ >= 0); - apnSelector.selectedIndex = this.selectedApnIndex_; - updateHidden('.apn-list-view', false); - updateHidden('.apn-details-view', true); - }, - - /** - * Helper function for setting APN properties. - * @param {Object} apnValue Dictionary of APN properties. - * @private - */ - setActiveApn_: function(apnValue) { - var activeApn = {}; - var apnName = apnValue['AccessPointName']; - if (apnName) { - activeApn['AccessPointName'] = apnName; - activeApn['Username'] = stringFromValue(apnValue['Username']); - activeApn['Password'] = stringFromValue(apnValue['Password']); - } - // Set the cached ONC data. - this.onc_.setProperty('Cellular.APN', activeApn); - // Set an ONC object with just the APN values. - var oncData = new OncData({}); - oncData.setProperty('Cellular.APN', activeApn); - chrome.networkingPrivate.setProperties(this.onc_.guid(), - oncData.getData()); - }, - - /** - * Event Listener for the cellular-apn-use-default button. - * @private - */ - setDefaultApn_: function() { - var apnSelector = /** @type {HTMLSelectElement} */($('select-apn')); - - // Remove the 'user' entry if it exists. - if (this.userApnIndex_ != -1) { - assert(this.userApnIndex_ < apnSelector.length - 1); - apnSelector.remove(this.userApnIndex_); - this.userApnIndex_ = -1; - } - - var apnList = this.onc_.getActiveValue('Cellular.APNList'); - var iApn = (apnList != undefined && apnList.length > 0) ? 0 : -1; - apnSelector.selectedIndex = iApn; - this.selectedApnIndex_ = iApn; - - // Clear any user APN entry to inform Chrome to use the default APN. - this.setActiveApn_({}); - - updateHidden('.apn-list-view', false); - updateHidden('.apn-details-view', true); - }, - - /** - * Event Listener for the cellular-apn-set button. - * @private - */ - setApn_: function(apnValue) { - if (apnValue == '') - return; - - var apnSelector = /** @type {HTMLSelectElement} */($('select-apn')); - - var activeApn = {}; - activeApn['AccessPointName'] = stringFromValue(apnValue); - activeApn['Username'] = stringFromValue($('cellular-apn-username').value); - activeApn['Password'] = stringFromValue($('cellular-apn-password').value); - this.setActiveApn_(activeApn); - // Set the user selected APN. - this.userApn_ = activeApn; - - // Remove any existing 'user' entry. - if (this.userApnIndex_ != -1) { - assert(this.userApnIndex_ < apnSelector.length - 1); - apnSelector.remove(this.userApnIndex_); - this.userApnIndex_ = -1; - } - - // Create a new 'user' entry with the new active apn. - var option = document.createElement('option'); - option.textContent = activeApn['AccessPointName']; - option.value = -1; - option.selected = true; - this.insertApnUserOption_(option); - - updateHidden('.apn-list-view', false); - updateHidden('.apn-details-view', true); - }, - - /** - * Event Listener for the cellular-apn-cancel button. - * @private - */ - cancelApn_: function() { this.initializeApnList_(); }, - - /** - * Event Listener for the select-apn button. - * @private - */ - selectApn_: function() { - var onc = this.onc_; - var apnSelector = $('select-apn'); - if (apnSelector[apnSelector.selectedIndex].value != -1) { - var apnList = onc.getActiveValue('Cellular.APNList'); - var apnIndex = apnSelector.selectedIndex; - assert(apnIndex < apnList.length); - this.selectedApnIndex_ = apnIndex; - this.setActiveApn_(apnList[apnIndex]); - } else if (apnSelector.selectedIndex == this.userApnIndex_) { - this.selectedApnIndex_ = apnSelector.selectedIndex; - this.setActiveApn_(this.userApn_); - } else { // 'Other' - var apnDict; - if (this.userApn_['AccessPointName']) { - // Fill in the details fields with the existing 'user' config. - apnDict = this.userApn_; - } else { - // No 'user' config, use the current values. - apnDict = {}; - apnDict['AccessPointName'] = - onc.getActiveValue('Cellular.APN.AccessPointName'); - apnDict['Username'] = onc.getActiveValue('Cellular.APN.Username'); - apnDict['Password'] = onc.getActiveValue('Cellular.APN.Password'); - } - $('cellular-apn').value = stringFromValue(apnDict['AccessPointName']); - $('cellular-apn-username').value = stringFromValue(apnDict['Username']); - $('cellular-apn-password').value = stringFromValue(apnDict['Password']); - updateHidden('.apn-list-view', true); - updateHidden('.apn-details-view', false); - } - } - }; - - /** - * Enables or Disables all buttons that provide operations on the cellular - * network. - */ - DetailsInternetPage.changeCellularButtonsState = function(disable) { - var buttonsToDisableList = - new Array('details-internet-login', - 'details-internet-disconnect', - 'details-internet-configure', - 'activate-details', - 'view-account-details'); - - for (var i = 0; i < buttonsToDisableList.length; ++i) { - var button = $(buttonsToDisableList[i]); - button.disabled = disable; - } - }; - - /** - * If the network is not already activated, starts the activation process or - * shows the activation UI. Otherwise does nothing. - */ - DetailsInternetPage.activateCellular = function(guid) { - chrome.networkingPrivate.getProperties(guid, function(properties) { - var oncData = new OncData(properties); - if (oncData.getActiveValue('Cellular.ActivationState') == 'Activated') { - return; - } - var carrier = oncData.getActiveValue('Cellular.Carrier'); - if (carrier == CarrierSprint) { - // Sprint is directly ativated, call startActivate(). - chrome.networkingPrivate.startActivate(guid, ''); - } else { - chrome.send('showMorePlanInfo', [guid]); - } - }); - }; - - /** - * Performs minimal initialization of the InternetDetails dialog in - * preparation for showing proxy-settings. - */ - DetailsInternetPage.initializeProxySettings = function() { - DetailsInternetPage.getInstance().initializePageContents_(); - }; - - /** - * Displays the InternetDetails dialog with only the proxy settings visible. - */ - DetailsInternetPage.showProxySettings = function() { - var detailsPage = DetailsInternetPage.getInstance(); - $('network-details-header').hidden = true; - $('activate-details').hidden = true; - $('view-account-details').hidden = true; - $('web-proxy-auto-discovery').hidden = true; - detailsPage.showProxy_ = true; - updateHidden('#internet-tab', true); - updateHidden('#details-tab-strip', true); - updateHidden('#details-internet-page .action-area', true); - detailsPage.updateControls(); - detailsPage.visible = true; - sendChromeMetricsAction('Options_NetworkShowProxyTab'); - }; - - /** - * Initializes even handling for keyboard driven flow. - */ - DetailsInternetPage.initializeKeyboardFlow = function() { - keyboard.initializeKeyboardFlow(false); - }; - - DetailsInternetPage.updateProxySettings = function(type) { - var proxyHost = null, - proxyPort = null; - - if (type == 'cros.session.proxy.singlehttp') { - proxyHost = 'proxy-host-single-name'; - proxyPort = 'proxy-host-single-port'; - } else if (type == 'cros.session.proxy.httpurl') { - proxyHost = 'proxy-host-name'; - proxyPort = 'proxy-host-port'; - } else if (type == 'cros.session.proxy.httpsurl') { - proxyHost = 'secure-proxy-host-name'; - proxyPort = 'secure-proxy-port'; - } else if (type == 'cros.session.proxy.ftpurl') { - proxyHost = 'ftp-proxy'; - proxyPort = 'ftp-proxy-port'; - } else if (type == 'cros.session.proxy.socks') { - proxyHost = 'socks-host'; - proxyPort = 'socks-port'; - } else { - return; - } - - var hostValue = $(proxyHost).value; - if (hostValue.indexOf(':') !== -1) { - if (hostValue.match(/:/g).length == 1) { - hostValue = hostValue.split(':'); - $(proxyHost).value = hostValue[0]; - $(proxyPort).value = hostValue[1]; - } - } - }; - - DetailsInternetPage.loginFromDetails = function() { - DetailsInternetPage.configureOrConnect(); - PageManager.closeOverlay(); - }; - - /** - * This function identifies unconfigured networks and networks that are - * likely to fail (e.g. due to a bad passphrase on a previous connect - * attempt). For such networks a configure dialog will be opened. Otherwise - * a connection will be attempted. - */ - DetailsInternetPage.configureOrConnect = function() { - var detailsPage = DetailsInternetPage.getInstance(); - if (detailsPage.type_ == 'WiFi') - sendChromeMetricsAction('Options_NetworkConnectToWifi'); - else if (detailsPage.type_ == 'VPN') - sendChromeMetricsAction('Options_NetworkConnectToVPN'); - - var onc = detailsPage.onc_; - var guid = onc.guid(); - var type = onc.getActiveValue('Type'); - - // Built-in VPNs do not correctly set 'Connectable', so we always show the - // configuration UI. - if (type == 'VPN') { - if (onc.getActiveValue('VPN.Type') != 'ThirdPartyVPN') { - chrome.send('configureNetwork', [guid]); - return; - } - } - - // If 'Connectable' is false for WiFi or WiMAX, Shill requires - // additional configuration to connect, so show the configuration UI. - if ((type == 'WiFi' || type == 'WiMAX') && - !onc.getActiveValue('Connectable')) { - chrome.send('configureNetwork', [guid]); - return; - } - - // Secure WiFi networks with ErrorState set most likely require - // configuration (e.g. a correct passphrase) before connecting. - if (type == 'WiFi' && onc.getWiFiSecurity() != 'None') { - var errorState = onc.getActiveValue('ErrorState'); - if (errorState && errorState != 'Unknown') { - chrome.send('configureNetwork', [guid]); - return; - } - } - - // Cellular networks need to be activated before they can be connected to. - if (type == 'Cellular') { - var activationState = onc.getActiveValue('Cellular.ActivationState'); - if (activationState != 'Activated' && activationState != 'Unknown') { - DetailsInternetPage.activateCellular(guid); - return; - } - } - - chrome.networkingPrivate.startConnect(guid); - }; - - DetailsInternetPage.disconnectNetwork = function() { - var detailsPage = DetailsInternetPage.getInstance(); - if (detailsPage.type_ == 'WiFi') - sendChromeMetricsAction('Options_NetworkDisconnectWifi'); - else if (detailsPage.type_ == 'VPN') - sendChromeMetricsAction('Options_NetworkDisconnectVPN'); - chrome.networkingPrivate.startDisconnect(detailsPage.onc_.guid()); - PageManager.closeOverlay(); - }; - - DetailsInternetPage.configureNetwork = function() { - var detailsPage = DetailsInternetPage.getInstance(); - // This is an explicit request to show the configure dialog; do not show - // the enrollment dialog for networks missing a certificate. - var forceShow = true; - chrome.send('configureNetwork', [detailsPage.onc_.guid(), forceShow]); - PageManager.closeOverlay(); - }; - - DetailsInternetPage.activateFromDetails = function() { - var detailsPage = DetailsInternetPage.getInstance(); - if (detailsPage.type_ == 'Cellular') - DetailsInternetPage.activateCellular(detailsPage.onc_.guid()); - PageManager.closeOverlay(); - }; - - /** - * Event handler called when the details page is closed. Sends changed - * properties to Chrome and closes the overlay. - */ - DetailsInternetPage.setDetails = function() { - var detailsPage = DetailsInternetPage.getInstance(); - var type = detailsPage.type_; - var oncData = new OncData({}); - var autoConnectCheckboxId = ''; - if (type == 'WiFi') { - var preferredCheckbox = - assertInstanceof($('prefer-network-wifi'), HTMLInputElement); - if (!preferredCheckbox.hidden && !preferredCheckbox.disabled) { - var kPreferredPriority = 1; - var priority = preferredCheckbox.checked ? kPreferredPriority : 0; - oncData.setProperty('Priority', priority); - sendChromeMetricsAction('Options_NetworkSetPrefer'); - } - autoConnectCheckboxId = 'auto-connect-network-wifi'; - } else if (type == 'WiMAX') { - autoConnectCheckboxId = 'auto-connect-network-wimax'; - } else if (type == 'Cellular') { - autoConnectCheckboxId = 'auto-connect-network-cellular'; - } else if (type == 'VPN') { - var providerType = detailsPage.onc_.getActiveValue('VPN.Type'); - if (providerType != 'ThirdPartyVPN') { - oncData.setProperty('VPN.Type', providerType); - oncData.setProperty('VPN.Host', $('inet-server-hostname').value); - autoConnectCheckboxId = 'auto-connect-network-vpn'; - } - } - if (autoConnectCheckboxId != '') { - var autoConnectCheckbox = - assertInstanceof($(autoConnectCheckboxId), HTMLInputElement); - if (!autoConnectCheckbox.hidden && !autoConnectCheckbox.disabled) { - var autoConnectKey = type + '.AutoConnect'; - oncData.setProperty(autoConnectKey, !!autoConnectCheckbox.checked); - sendChromeMetricsAction('Options_NetworkAutoConnect'); - } - } - - var nameServerTypes = ['automatic', 'google', 'user']; - var nameServerType = 'automatic'; - for (var i = 0; i < nameServerTypes.length; ++i) { - if ($(nameServerTypes[i] + '-dns-radio').checked) { - nameServerType = nameServerTypes[i]; - break; - } - } - var ipConfig = detailsPage.getIpConfig_(nameServerType); - var ipAddressType = ('IPAddress' in ipConfig) ? 'Static' : 'DHCP'; - var nameServersType = ('NameServers' in ipConfig) ? 'Static' : 'DHCP'; - oncData.setProperty('IPAddressConfigType', ipAddressType); - oncData.setProperty('NameServersConfigType', nameServersType); - oncData.setProperty('StaticIPConfig', ipConfig); - - var data = oncData.getData(); - if (Object.keys(data).length > 0) { - // TODO(stevenjb): Only set changed properties. - chrome.networkingPrivate.setProperties(detailsPage.onc_.guid(), data); - } - - PageManager.closeOverlay(); - }; - - /** - * Event handler called when the name server type changes. - * @param {string} type The selected name sever type, 'automatic', 'google', - * or 'user'. - */ - DetailsInternetPage.updateNameServerDisplay = function(type) { - var editable = type == 'user'; - var fields = [$('ipconfig-dns1'), $('ipconfig-dns2'), - $('ipconfig-dns3'), $('ipconfig-dns4')]; - for (var i = 0; i < fields.length; ++i) { - fields[i].editable = editable; - } - if (editable) - $('ipconfig-dns1').focus(); - - var automaticDns = $('automatic-dns-display'); - var googleDns = $('google-dns-display'); - var userDns = $('user-dns-settings'); - switch (type) { - case 'automatic': - automaticDns.setAttribute('selected', ''); - googleDns.removeAttribute('selected'); - userDns.removeAttribute('selected'); - break; - case 'google': - automaticDns.removeAttribute('selected'); - googleDns.setAttribute('selected', ''); - userDns.removeAttribute('selected'); - break; - case 'user': - automaticDns.removeAttribute('selected'); - googleDns.removeAttribute('selected'); - userDns.setAttribute('selected', ''); - break; - } - }; - - /** - * Method called from Chrome when the ONC properties for the displayed - * network may have changed. - * @param {Object} oncData The updated ONC dictionary for the network. - */ - DetailsInternetPage.updateConnectionData = function(oncData) { - var detailsPage = DetailsInternetPage.getInstance(); - if (!detailsPage.visible) - return; - - if (oncData.GUID != detailsPage.onc_.guid()) - return; - - // Update our cached data object. - detailsPage.onc_ = new OncData(oncData); - - detailsPage.populateHeader_(); - detailsPage.updateConnectionButtonVisibility_(); - detailsPage.updateDetails_(); - }; - - /** - * Initializes the details page with the provided ONC data. - * @param {Object} oncData Dictionary of ONC properties. - */ - DetailsInternetPage.initializeDetailsPage = function(oncData) { - var onc = new OncData(oncData); - - var detailsPage = DetailsInternetPage.getInstance(); - detailsPage.onc_ = onc; - var type = onc.getActiveValue('Type'); - detailsPage.type_ = type; - - sendShowDetailsMetrics(type, onc.getActiveValue('ConnectionState')); - - detailsPage.populateHeader_(); - detailsPage.updateConnectionButtonVisibility_(); - detailsPage.updateDetails_(); - - // TODO(stevenjb): Some of the setup below should be moved to - // updateDetails_() so that updates are reflected in the UI. - - // Only show proxy for remembered networks. - var remembered = onc.getSource() != 'None'; - if (remembered) { - detailsPage.showProxy_ = true; - // Inform Chrome which network to use for proxy configuration. - chrome.send('selectNetwork', [detailsPage.onc_.guid()]); - } else { - detailsPage.showProxy_ = false; - } - - $('web-proxy-auto-discovery').hidden = true; - - var restricted = onc.getActiveValue('RestrictedConnectivity'); - var restrictedString = loadTimeData.getString( - restricted ? 'restrictedYes' : 'restrictedNo'); - - // These objects contain an 'automatic' property that is displayed when - // ip-automatic-configuration-checkbox is checked, and a 'value' property - // that is displayed when unchecked and used to set the associated ONC - // property for StaticIPConfig on commit. - var inetAddress = {}; - var inetNetmask = {}; - var inetGateway = {}; - var ipv6Address = {}; - - var inetNameServersString; - - var ipconfigList = onc.getActiveValue('IPConfigs'); - if (Array.isArray(ipconfigList)) { - for (var i = 0; i < ipconfigList.length; ++i) { - var ipconfig = ipconfigList[i]; - var ipType = ipconfig['Type']; - var address = ipconfig['IPAddress']; - if (ipType != 'IPv4') { - if (ipType == 'IPv6' && !ipv6Address.value) { - ipv6Address.automatic = address; - ipv6Address.value = address; - } - continue; - } - if (inetAddress.value) - continue; // ipv4 address already provided. - inetAddress.automatic = address; - inetAddress.value = address; - var netmask = prefixLengthToNetmask(ipconfig['RoutingPrefix']); - inetNetmask.automatic = netmask; - inetNetmask.value = netmask; - var gateway = ipconfig['Gateway']; - inetGateway.automatic = gateway; - inetGateway.value = gateway; - if ('WebProxyAutoDiscoveryUrl' in ipconfig) { - $('web-proxy-auto-discovery').hidden = false; - $('web-proxy-auto-discovery-url').value = - ipconfig['WebProxyAutoDiscoveryUrl']; - } - if ('NameServers' in ipconfig) { - var inetNameServers = ipconfig['NameServers']; - inetNameServers = inetNameServers.sort(); - inetNameServersString = inetNameServers.join(','); - } - } - } - - // Override the 'automatic' properties with the saved DHCP values if the - // saved value is set, and set any unset 'value' properties. - var savedNameServersString; - var savedIpAddress = onc.getActiveValue('SavedIPConfig.IPAddress'); - if (savedIpAddress != undefined) { - inetAddress.automatic = savedIpAddress; - if (!inetAddress.value) - inetAddress.value = savedIpAddress; - } - var savedPrefix = onc.getActiveValue('SavedIPConfig.RoutingPrefix'); - if (savedPrefix != undefined) { - assert(typeof savedPrefix == 'number'); - var savedNetmask = prefixLengthToNetmask( - /** @type {number} */(savedPrefix)); - inetNetmask.automatic = savedNetmask; - if (!inetNetmask.value) - inetNetmask.value = savedNetmask; - } - var savedGateway = onc.getActiveValue('SavedIPConfig.Gateway'); - if (savedGateway != undefined) { - inetGateway.automatic = savedGateway; - if (!inetGateway.value) - inetGateway.value = savedGateway; - } - - var savedNameServers = onc.getActiveValue('SavedIPConfig.NameServers'); - if (savedNameServers) { - savedNameServers = savedNameServers.sort(); - savedNameServersString = savedNameServers.join(','); - } - - var ipAutoConfig = 'automatic'; - if (onc.getActiveValue('IPAddressConfigType') == 'Static') { - ipAutoConfig = 'user'; - var staticIpAddress = onc.getActiveValue('StaticIPConfig.IPAddress'); - inetAddress.user = staticIpAddress; - inetAddress.value = staticIpAddress; - - var staticPrefix = onc.getActiveValue('StaticIPConfig.RoutingPrefix'); - if (typeof staticPrefix != 'number') - staticPrefix = 0; - var staticNetmask = prefixLengthToNetmask( - /** @type {number} */ (staticPrefix)); - inetNetmask.user = staticNetmask; - inetNetmask.value = staticNetmask; - - var staticGateway = onc.getActiveValue('StaticIPConfig.Gateway'); - inetGateway.user = staticGateway; - inetGateway.value = staticGateway; - } - - var staticNameServersString; - if (onc.getActiveValue('NameServersConfigType') == 'Static') { - var staticNameServers = onc.getActiveValue('StaticIPConfig.NameServers'); - staticNameServers = staticNameServers.sort(); - staticNameServersString = staticNameServers.join(','); - } - - $('ip-automatic-configuration-checkbox').checked = - ipAutoConfig == 'automatic'; - - inetAddress.autoConfig = ipAutoConfig; - inetNetmask.autoConfig = ipAutoConfig; - inetGateway.autoConfig = ipAutoConfig; - - var configureAddressField = function(field, model) { - IPAddressField.decorate(field); - field.model = model; - field.editable = model.autoConfig == 'user'; - }; - configureAddressField($('ip-address'), inetAddress); - configureAddressField($('ipv6-address'), ipv6Address); - configureAddressField($('ip-netmask'), inetNetmask); - configureAddressField($('ip-gateway'), inetGateway); - - // Set Nameserver fields. Nameservers are 'automatic' by default. If a - // static namerserver is set, use that unless it does not match a non - // empty 'NameServers' value (indicating that the custom nameservers are - // invalid or not being applied for some reason). TODO(stevenjb): Only - // set these properites if they change so that invalid custom values do - // not get lost. - var nameServerType = 'automatic'; - if (staticNameServersString && - (!inetNameServersString || - staticNameServersString == inetNameServersString)) { - if (staticNameServersString == GoogleNameServers.join(',')) - nameServerType = 'google'; - else - nameServerType = 'user'; - } - if (nameServerType == 'automatic') - $('automatic-dns-display').textContent = inetNameServersString; - else - $('automatic-dns-display').textContent = savedNameServersString; - $('google-dns-display').textContent = GoogleNameServers.join(','); - - var nameServersUser = []; - if (staticNameServers) { - nameServersUser = staticNameServers; - } else if (savedNameServers) { - // Pre-populate with values provided by DHCP server. - nameServersUser = savedNameServers; - } - - var nameServerModels = []; - for (var i = 0; i < 4; ++i) - nameServerModels.push({value: nameServersUser[i] || ''}); - - $(nameServerType + '-dns-radio').checked = true; - configureAddressField($('ipconfig-dns1'), nameServerModels[0]); - configureAddressField($('ipconfig-dns2'), nameServerModels[1]); - configureAddressField($('ipconfig-dns3'), nameServerModels[2]); - configureAddressField($('ipconfig-dns4'), nameServerModels[3]); - - DetailsInternetPage.updateNameServerDisplay(nameServerType); - - var macAddress = onc.getActiveValue('MacAddress'); - if (macAddress) { - $('hardware-address').textContent = macAddress; - $('hardware-address-row').style.display = 'table-row'; - } else { - // This is most likely a device without a hardware address. - $('hardware-address-row').style.display = 'none'; - } - - var setOrHideParent = function(field, property) { - if (property != undefined) { - $(field).textContent = property; - $(field).parentElement.hidden = false; - } else { - $(field).parentElement.hidden = true; - } - }; - - var networkName = onc.getTranslatedValue('Name'); - - // Signal strength as percentage (for WiFi and WiMAX). - var signalStrength; - if (type == 'WiFi' || type == 'WiMAX') - signalStrength = onc.getActiveValue(type + '.SignalStrength'); - if (!signalStrength) - signalStrength = 0; - var strengthFormat = loadTimeData.getString('inetSignalStrengthFormat'); - var strengthString = strengthFormat.replace('$1', signalStrength); - - if (type == 'WiFi') { - OptionsPage.showTab($('wifi-network-nav-tab')); - $('wifi-restricted-connectivity').textContent = restrictedString; - var ssid = onc.getActiveValue('WiFi.SSID'); - $('wifi-ssid').textContent = ssid ? ssid : networkName; - setOrHideParent('wifi-bssid', onc.getActiveValue('WiFi.BSSID')); - var security = onc.getWiFiSecurity(); - if (security == 'None') - security = undefined; - setOrHideParent('wifi-security', security); - // Frequency is in MHz. - var frequency = onc.getActiveValue('WiFi.Frequency'); - if (!frequency) - frequency = 0; - var frequencyFormat = loadTimeData.getString('inetFrequencyFormat'); - frequencyFormat = frequencyFormat.replace('$1', frequency); - $('wifi-frequency').textContent = frequencyFormat; - $('wifi-signal-strength').textContent = strengthString; - setOrHideParent('wifi-hardware-address', - onc.getActiveValue('MacAddress')); - var priority = onc.getActiveValue('Priority'); - $('prefer-network-wifi').checked = priority > 0; - $('prefer-network-wifi').disabled = !remembered; - $('auto-connect-network-wifi').checked = - onc.getActiveValue('WiFi.AutoConnect'); - $('auto-connect-network-wifi').disabled = !remembered; - } else if (type == 'WiMAX') { - OptionsPage.showTab($('wimax-network-nav-tab')); - $('wimax-restricted-connectivity').textContent = restrictedString; - - $('auto-connect-network-wimax').checked = - onc.getActiveValue('WiMAX.AutoConnect'); - $('auto-connect-network-wimax').disabled = !remembered; - var identity = onc.getActiveValue('WiMAX.EAP.Identity'); - setOrHideParent('wimax-eap-identity', identity); - $('wimax-signal-strength').textContent = strengthString; - } else if (type == 'Cellular') { - OptionsPage.showTab($('cellular-conn-nav-tab')); - - var isGsm = onc.getActiveValue('Cellular.Family') == 'GSM'; - - $('service-name').textContent = networkName; - - // TODO(stevenjb): Ideally many of these should be localized. - $('network-technology').textContent = - onc.getActiveValue('Cellular.NetworkTechnology'); - $('roaming-state').textContent = - onc.getTranslatedValue('Cellular.RoamingState'); - $('cellular-restricted-connectivity').textContent = restrictedString; - $('error-state').textContent = onc.getActiveValue('ErrorState'); - $('manufacturer').textContent = - onc.getActiveValue('Cellular.Manufacturer'); - $('model-id').textContent = onc.getActiveValue('Cellular.ModelID'); - $('firmware-revision').textContent = - onc.getActiveValue('Cellular.FirmwareRevision'); - $('hardware-revision').textContent = - onc.getActiveValue('Cellular.HardwareRevision'); - $('mdn').textContent = onc.getActiveValue('Cellular.MDN'); - - // Show ServingOperator properties only if available. - var servingOperatorName = - onc.getActiveValue('Cellular.ServingOperator.Name'); - var servingOperatorCode = - onc.getActiveValue('Cellular.ServingOperator.Code'); - if (servingOperatorName != undefined && - servingOperatorCode != undefined) { - $('operator-name').textContent = servingOperatorName; - $('operator-code').textContent = servingOperatorCode; - } else { - $('operator-name').parentElement.hidden = true; - $('operator-code').parentElement.hidden = true; - } - // Make sure that GSM/CDMA specific properties that shouldn't be hidden - // are visible. - updateHidden('#details-internet-page .gsm-only', false); - updateHidden('#details-internet-page .cdma-only', false); - - // Show IMEI/ESN/MEID/MIN/PRL only if they are available. - setOrHideParent('esn', onc.getActiveValue('Cellular.ESN')); - setOrHideParent('imei', onc.getActiveValue('Cellular.IMEI')); - setOrHideParent('meid', onc.getActiveValue('Cellular.MEID')); - setOrHideParent('min', onc.getActiveValue('Cellular.MIN')); - setOrHideParent('prl-version', onc.getActiveValue('Cellular.PRLVersion')); - - if (isGsm) { - $('iccid').textContent = onc.getActiveValue('Cellular.ICCID'); - $('imsi').textContent = onc.getActiveValue('Cellular.IMSI'); - detailsPage.initializeApnList_(); - } - $('auto-connect-network-cellular').checked = - onc.getActiveValue('Cellular.AutoConnect'); - $('auto-connect-network-cellular').disabled = false; - } else if (type == 'VPN') { - OptionsPage.showTab($('vpn-nav-tab')); - var providerType = onc.getActiveValue('VPN.Type'); - var isThirdPartyVPN = providerType == 'ThirdPartyVPN'; - $('vpn-tab').classList.toggle('third-party-vpn-provider', - isThirdPartyVPN); - - $('inet-service-name').textContent = networkName; - $('inet-provider-type').textContent = - onc.getTranslatedValue('VPN.Type'); - - if (isThirdPartyVPN) { - $('inet-provider-name').textContent = - onc.getActiveValue('VPN.ThirdPartyVPN.ProviderName'); - } else { - var usernameKey; - if (providerType == 'OpenVPN') - usernameKey = 'VPN.OpenVPN.Username'; - else if (providerType == 'L2TP-IPsec') - usernameKey = 'VPN.L2TP.Username'; - - if (usernameKey) { - $('inet-username').parentElement.hidden = false; - $('inet-username').textContent = onc.getActiveValue(usernameKey); - } else { - $('inet-username').parentElement.hidden = true; - } - var inetServerHostname = $('inet-server-hostname'); - inetServerHostname.value = onc.getActiveValue('VPN.Host'); - inetServerHostname.resetHandler = function() { - PageManager.hideBubble(); - var recommended = onc.getRecommendedValue('VPN.Host'); - if (recommended != undefined) - inetServerHostname.value = recommended; - }; - $('auto-connect-network-vpn').checked = - onc.getActiveValue('VPN.AutoConnect'); - $('auto-connect-network-vpn').disabled = false; - } - } else { - OptionsPage.showTab($('internet-nav-tab')); - } - - // Update controlled option indicators. - var indicators = cr.doc.querySelectorAll( - '#details-internet-page .controlled-setting-indicator'); - for (var i = 0; i < indicators.length; i++) { - var managed = indicators[i].hasAttribute('managed'); - // TODO(stevenjb): Eliminate support for 'data' once 39 is stable. - var attributeName = managed ? 'managed' : 'data'; - var propName = indicators[i].getAttribute(attributeName); - if (!propName) - continue; - var propValue = managed ? - onc.getManagedProperty(propName) : - onc.getActiveValue(propName); - // If the property is unset or unmanaged (i.e. not an Object) skip it. - if (propValue == undefined || (typeof propValue != 'object')) - continue; - var event; - if (managed) - event = detailsPage.createManagedEvent_(propName, propValue); - else - event = detailsPage.createControlledEvent_(propName, - /** @type {{value: *, controlledBy: *, recommendedValue: *}} */( - propValue)); - indicators[i].handlePrefChange(event); - var forElement = $(indicators[i].getAttribute('internet-detail-for')); - if (forElement) { - if (event.value.controlledBy == 'policy') - forElement.disabled = true; - if (forElement.resetHandler) - indicators[i].resetHandler = forElement.resetHandler; - } - } - - detailsPage.updateControls(); - - // Don't show page name in address bar and in history to prevent people - // navigate here by hand and solve issue with page session restore. - PageManager.showPageByName('detailsInternetPage', false); - }; - - return { - DetailsInternetPage: DetailsInternetPage - }; -});
diff --git a/chrome/browser/resources/options/chromeos/internet_detail_ip_address_field.js b/chrome/browser/resources/options/chromeos/internet_detail_ip_address_field.js deleted file mode 100644 index a5e4f69..0000000 --- a/chrome/browser/resources/options/chromeos/internet_detail_ip_address_field.js +++ /dev/null
@@ -1,112 +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. - -cr.define('options.internet', function() { - /** @const */ var EditableTextField = options.EditableTextField; - - /** - * The regular expression that matches an IP address. String to match against - * should have all whitespace stripped already. - * @const - * @type {RegExp} - */ - var singleIp = /^([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)$/; - - /** - * Creates a new field specifically for entering IP addresses. - * @constructor - * @extends {options.EditableTextField} - */ - function IPAddressField() { - var el = cr.doc.createElement('div'); - IPAddressField.decorate(el); - return el; - } - - /** - * Decorates an element as a inline-editable list item. Note that this is - * a subclass of IPAddressField. - * @param {!HTMLElement} el The element to decorate. - */ - IPAddressField.decorate = function(el) { - el.__proto__ = IPAddressField.prototype; - el.decorate(); - }; - - IPAddressField.prototype = { - __proto__: EditableTextField.prototype, - - /** @override */ - decorate: function() { - EditableTextField.prototype.decorate.call(this); - }, - - /** - * Indicates whether or not empty values are allowed. - * @type {boolean} - */ - get allowEmpty() { - return this.hasAttribute('allow-empty'); - }, - - /** @override */ - get currentInputIsValid() { - if (!this.editField.value && this.allowEmpty) - return true; - - // Make sure it's only got numbers and ".", there are the correct - // count of them, and they are all within the correct range. - var fieldValue = this.editField.value.replace(/\s/g, ''); - var matches = singleIp.exec(fieldValue); - var rangeCorrect = true; - if (matches != null) { - for (var i = 1; i < matches.length; ++i) { - var value = parseInt(matches[i], 10); - if (value < 0 || value > 255) { - rangeCorrect = false; - break; - } - } - } - return this.editField.validity.valid && matches != null && - rangeCorrect && matches.length == 5; - }, - - /** @override */ - get hasBeenEdited() { - return this.editField.value != this.model.value; - }, - - /** - * Overrides superclass to mutate the input during a successful commit. For - * the purposes of entering IP addresses, this just means stripping off - * whitespace and leading zeros from each of the octets so that they conform - * to the normal format for IP addresses. - * @override - * @param {string} value Input IP address to be mutated. - * @return {string} mutated IP address. - */ - mutateInput: function(value) { - if (!value) - return value; - - var fieldValue = value.replace(/\s/g, ''); - var matches = singleIp.exec(fieldValue); - var result = []; - - // If we got this far, matches shouldn't be null, but make sure. - if (matches != null) { - // starting at one because the first match element contains the entire - // match, and we don't care about that. - for (var i = 1; i < matches.length; ++i) - result.push(parseInt(matches[i], 10)); - } - return result.join('.'); - }, - }; - - return { - IPAddressField: IPAddressField, - }; -});
diff --git a/chrome/browser/resources/options/chromeos/keyboard_overlay.css b/chrome/browser/resources/options/chromeos/keyboard_overlay.css deleted file mode 100644 index 89b913d..0000000 --- a/chrome/browser/resources/options/chromeos/keyboard_overlay.css +++ /dev/null
@@ -1,26 +0,0 @@ -/* Copyright 2013 The Chromium Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. */ - -#send-function-keys-description { - color: gray; -} - -#auto-repeat-settings-section { - -webkit-margin-start: 30px; - display: table; - white-space: nowrap; -} - -#auto-repeat-settings-section .row { - display: table-row; -} - -#auto-repeat-settings-section .row > * { - display: table-cell; -} - -#auto-repeat-settings-section input[type='range'] { - margin-left: 5px; - margin-right: 5px; -}
diff --git a/chrome/browser/resources/options/chromeos/keyboard_overlay.html b/chrome/browser/resources/options/chromeos/keyboard_overlay.html deleted file mode 100644 index b5a33c1..0000000 --- a/chrome/browser/resources/options/chromeos/keyboard_overlay.html +++ /dev/null
@@ -1,163 +0,0 @@ -<div id="keyboard-overlay" class="page" hidden> - <div class="close-button"></div> - <h1>$i18n{keyboardOverlay}</h1> - <div class="content-area"> - <table class="option-control-table"> - <tr> - <td class="option-name" id="remap-search-key-to-label"> - $i18n{remapSearchKeyToContent} - </td> - <td class="option-value"> - <select class="control" - data-type="number" i18n-options="remapSearchKeyToValue" - metric="Options_KeyboardRemapSearchKey" - pref="settings.language.xkb_remap_search_key_to" - aria-labelledby="remap-search-key-to-label" dialog-pref> - </select> - </td> - </tr> - <tr> - <td class="option-name" id="remap-control-key-to-label"> - $i18n{remapControlKeyToContent} - </td> - <td class="option-value"> - <select class="control" - data-type="number" i18n-options="remapControlKeyToValue" - metric="Options_KeyboardRemapControlKey" - pref="settings.language.xkb_remap_control_key_to" - aria-labelledby="remap-control-key-to-label" dialog-pref> - </select> - </td> - </tr> - <tr> - <td class="option-name" id="remap-alt-key-to-label"> - $i18n{remapAltKeyToContent} - </td> - <td class="option-value"> - <select class="control" data-type="number" - metric="Options_KeyboardRemapAltKey" - pref="settings.language.xkb_remap_alt_key_to" - i18n-options="remapAltKeyToValue" - aria-labelledby="remap-alt-key-to-label" dialog-pref></select> - </td> - </tr> - <!-- The caps lock section is hidden by default. This is only visible - when --has-chromeos-keyboard flag is not passed. --> - <tr id="caps-lock-remapping-section" hidden> - <td class="option-name" id="remap-caps-lock-key-to-label"> - $i18n{remapCapsLockKeyToContent} - </td> - <td class="option-value"> - <select class="control" - data-type="number" - metric="Options_KeyboardRemapCapsLockKey" - pref="settings.language.remap_caps_lock_key_to" - i18n-options="remapCapsLockKeyToValue" - aria-labelledby="remap-caps-lock-key-to-label" dialog-pref> - </select> - </td> - </tr> - <!-- The diamond key section is hidden by default. This is only visible - when --has-chromeos-diamond-key flag is passed. --> - <tr id="diamond-key-remapping-section" hidden> - <td class="option-name" id="remap-diamond-key-to-label"> - $i18n{remapDiamondKeyToContent} - </td> - <td class="option-value"> - <select class="control" - data-type="number" - metric="Options_KeyboardRemapDiamondKey" - pref="settings.language.remap_diamond_key_to" - i18n-options="remapDiamondKeyToValue" - aria-labelledby="remap-diamond-key-to-label" dialog-pref> - </select> - </td> - </tr> - <tr> - <td class="option-name" id="remap-backspace-key-to-label"> - $i18n{remapBackspaceKeyToContent} - </td> - <td class="option-value"> - <select class="control" data-type="number" - metric="Options_KeyboardRemapBackspaceKey" - pref="settings.language.remap_backspace_key_to" - i18n-options="remapBackspaceKeyToValue" - aria-labelledby="remap-backspace-key-to-label" dialog-pref> - </select> - </td> - </tr> - <tr> - <td class="option-name" id="remap-escape-key-to-label"> - $i18n{remapEscapeKeyToContent} - </td> - <td class="option-value"> - <select class="control" data-type="number" - metric="Options_KeyboardRemapEscapeKey" - pref="settings.language.remap_escape_key_to" - i18n-options="remapEscapeKeyToValue" - aria-labelledby="remap-escape-key-to-label" dialog-pref></select> - </td> - </tr> - </table> - <div class="settings-row"> - <div class="checkbox controlled-setting-with-label"> - <label> - <input type="checkbox" - pref="settings.language.send_function_keys" - aria-describedby="send-function-keys-description" dialog-pref> - <span> - <span>$i18n{sendFunctionKeys}</span> - <span class="bubble-button controlled-setting-indicator" - pref="settings.language.send_function_keys"></span> - </span> - </label> - </div> - <span id="send-function-keys-description"> - $i18n{sendFunctionKeysDescription} - </span> - </div> - <div class="settings-row"> - <div class="checkbox"> - <label> - <input id="enable-auto-repeat" type="checkbox" - pref="settings.language.xkb_auto_repeat_enabled_r2" - metric="Options_KeyboardAutoRepeat" dialog-pref> - <span>$i18n{enableAutoRepeat}</span> - </label> - </div> - <div id="auto-repeat-settings-section"> - <div class="row"> - <span class="option-name">$i18n{autoRepeatDelay}</span> - <span>$i18n{autoRepeatDelayLong}</span> - <input id="auto-repeat-delay-range" type="range" - class="touch-slider" metric="Options_KeyboardAutoRepeat_Delay" - pref="settings.language.xkb_auto_repeat_delay_r2" dialog-pref> - <span>$i18n{autoRepeatDelayShort}</span> - </div> - <div class="row"> - <span class="option-name">$i18n{autoRepeatRate}</span> - <span>$i18n{autoRepeatRateSlow}</span> - <input id="auto-repeat-interval-range" type="range" - class="touch-slider" - pref="settings.language.xkb_auto_repeat_interval_r2" - metric="Options_KeyboardAutoRepeat_Interval" dialog-pref> - <span>$i18n{autoRepeatRateFast}</span> - </div> - </div> - </div> - <a is="action-link" id="keyboard-shortcuts" class="settings-row"> - $i18n{showKeyboardShortcuts} - </a> - <a is="action-link" id="languages-and-input-settings" class="settings-row"> - $i18n{changeLanguageAndInputSettings} - </a> - </div> - <div class="action-area"> - <div class="button-strip"> - <button id="keyboard-cancel" type="reset">$i18n{cancel}</button> - <button id="keyboard-confirm" class="default-button" type="submit"> - $i18n{ok} - </button> - </div> - </div> -</div>
diff --git a/chrome/browser/resources/options/chromeos/keyboard_overlay.js b/chrome/browser/resources/options/chromeos/keyboard_overlay.js deleted file mode 100644 index b18af10..0000000 --- a/chrome/browser/resources/options/chromeos/keyboard_overlay.js +++ /dev/null
@@ -1,174 +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. - -cr.define('options', function() { - - /** - * Auto-repeat delays (in ms) for the corresponding slider values, from - * long to short. The values were chosen to provide a large range while giving - * several options near the defaults. - * @type {!Array<number>} - * @const - */ - var AUTO_REPEAT_DELAYS = - [2000, 1500, 1000, 500, 300, 200, 150]; - - /** - * Auto-repeat intervals (in ms) for the corresponding slider values, from - * long to short. The slider itself is labeled "rate", the inverse of - * interval, and goes from slow (long interval) to fast (short interval). - * @type {!Array<number>} - * @const - */ - var AUTO_REPEAT_INTERVALS = - [2000, 1000, 500, 300, 200, 100, 50, 30, 20]; - - /** - * Encapsulated handling of the keyboard overlay. - * @constructor - * @extends {options.SettingsDialog} - */ - function KeyboardOverlay() { - options.SettingsDialog.call(this, 'keyboard-overlay', - loadTimeData.getString('keyboardOverlayTabTitle'), - 'keyboard-overlay', - assertInstanceof($('keyboard-confirm'), HTMLButtonElement), - assertInstanceof($('keyboard-cancel'), HTMLButtonElement)); - } - - cr.addSingletonGetter(KeyboardOverlay); - - KeyboardOverlay.prototype = { - __proto__: options.SettingsDialog.prototype, - - /** @override */ - initializePage: function() { - options.SettingsDialog.prototype.initializePage.call(this); - - $('enable-auto-repeat').customPrefChangeHandler = - this.handleAutoRepeatEnabledPrefChange_.bind(this); - - var autoRepeatDelayRange = $('auto-repeat-delay-range'); - autoRepeatDelayRange.valueMap = AUTO_REPEAT_DELAYS; - autoRepeatDelayRange.max = AUTO_REPEAT_DELAYS.length - 1; - autoRepeatDelayRange.customPrefChangeHandler = - this.handleAutoRepeatDelayPrefChange_.bind(this); - - var autoRepeatIntervalRange = $('auto-repeat-interval-range'); - autoRepeatIntervalRange.valueMap = AUTO_REPEAT_INTERVALS; - autoRepeatIntervalRange.max = AUTO_REPEAT_INTERVALS.length - 1; - autoRepeatIntervalRange.customPrefChangeHandler = - this.handleAutoRepeatIntervalPrefChange_.bind(this); - - $('languages-and-input-settings').onclick = function(e) { - PageManager.showPageByName('languages'); - chrome.send('coreOptionsUserMetricsAction', - ['Options_KeyboardShowLanguageSettings']); - }; - - $('keyboard-shortcuts').onclick = function(e) { - chrome.send('showKeyboardShortcuts'); - chrome.send('coreOptionsUserMetricsAction', - ['Options_KeyboardShowKeyboardShortcuts']); - }; - }, - - /** - * Handles auto-repeat enabled pref change and allows the event to continue - * propagating. - * @param {Event} e Change event. - * @return {boolean} Whether the event has finished being handled. - * @private - */ - handleAutoRepeatEnabledPrefChange_: function(e) { - $('auto-repeat-settings-section').classList.toggle('disabled', - !e.value.value); - $('auto-repeat-delay-range').disabled = - $('auto-repeat-interval-range').disabled = !e.value.value; - return false; - }, - - /** - * Handles auto-repeat delay pref change and stops the event from - * propagating. - * @param {Event} e Change event. - * @return {boolean} Whether the event has finished being handled. - * @private - */ - handleAutoRepeatDelayPrefChange_: function(e) { - this.updateSliderFromValue_('auto-repeat-delay-range', - e.value.value, - AUTO_REPEAT_DELAYS); - return true; - }, - - /** - * Handles auto-repeat interval pref change and stops the event from - * propagating. - * @param {Event} e Change event. - * @return {boolean} Whether the event has finished being handled. - * @private - */ - handleAutoRepeatIntervalPrefChange_: function(e) { - this.updateSliderFromValue_('auto-repeat-interval-range', - e.value.value, - AUTO_REPEAT_INTERVALS); - return true; - }, - - /** - * Show/hide the caps lock remapping section. - * @private - */ - showCapsLockOptions_: function(show) { - $('caps-lock-remapping-section').hidden = !show; - }, - - /** - * Show/hide the diamond key remapping section. - * @private - */ - showDiamondKeyOptions_: function(show) { - $('diamond-key-remapping-section').hidden = !show; - }, - - /** - * Sets the slider's value to the number in |values| that is closest to - * |value|. - * @param {string} id The slider's ID. - * @param {number} value The value to find. - * @param {!Array<number>} values The array to search. - * @private - */ - updateSliderFromValue_: function(id, value, values) { - var index = values.indexOf(value); - if (index == -1) { - var closestValue = Infinity; - for (var i = 0; i < values.length; i++) { - if (Math.abs(values[i] - value) < - Math.abs(closestValue - value)) { - closestValue = values[i]; - index = i; - } - } - - assert(index != -1, - 'Failed to update ' + id + ' from pref with value ' + value); - } - - $(id).value = index; - }, - }; - - // Forward public APIs to private implementations. - cr.makePublic(KeyboardOverlay, [ - 'showCapsLockOptions', - 'showDiamondKeyOptions', - ]); - - // Export - return { - KeyboardOverlay: KeyboardOverlay - }; -});
diff --git a/chrome/browser/resources/options/chromeos/network_list.js b/chrome/browser/resources/options/chromeos/network_list.js deleted file mode 100644 index 7b75858..0000000 --- a/chrome/browser/resources/options/chromeos/network_list.js +++ /dev/null
@@ -1,1584 +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. - -/** - * Partial definition of the result of networkingPrivate.getProperties()). - * TODO(stevenjb): Replace with chrome.networkingPrivate.NetworkStateProperties - * once that is fully speced. - * @typedef {{ - * ConnectionState: string, - * Cellular: ?{ - * Family: ?string, - * SIMPresent: ?boolean, - * SIMLockStatus: ?{ LockType: ?string }, - * SupportNetworkScan: ?boolean - * }, - * GUID: string, - * Name: string, - * Source: string, - * Type: string, - * VPN: ?{ - * Type: string, - * ThirdPartyVPN: chrome.networkingPrivate.ThirdPartyVPNProperties - * } - * }} - * @see extensions/common/api/networking_private.idl - */ -var NetworkProperties; - -/** @typedef {chrome.management.ExtensionInfo} */ var ExtensionInfo; - -cr.define('options.network', function() { - var ArrayDataModel = cr.ui.ArrayDataModel; - var List = cr.ui.List; - var ListItem = cr.ui.ListItem; - var ListSingleSelectionModel = cr.ui.ListSingleSelectionModel; - var Menu = cr.ui.Menu; - var MenuItem = cr.ui.MenuItem; - var ControlledSettingIndicator = options.ControlledSettingIndicator; - - /** - * Network settings constants. These enums usually match their C++ - * counterparts. - */ - function Constants() {} - - /** - * Valid network type names. - */ - Constants.NETWORK_TYPES = ['Ethernet', 'WiFi', 'WiMAX', 'Cellular', 'VPN']; - - /** - * Helper function to check whether |type| is a valid network type. - * @param {string} type A string that may contain a valid network type. - * @return {boolean} Whether the string represents a valid network type. - */ - function isNetworkType(type) { - return (Constants.NETWORK_TYPES.indexOf(type) != -1); - } - - /** - * Order in which controls are to appear in the network list sorted by key. - */ - Constants.NETWORK_ORDER = ['Ethernet', - 'WiFi', - 'WiMAX', - 'Cellular', - 'VPN', - 'addConnection']; - - /** - * ID of the menu that is currently visible. - * @type {?string} - * @private - */ - var activeMenu = null; - - /** - * The state of the cellular device or undefined if not available. - * @type {?chrome.networkingPrivate.DeviceStateProperties} - * @private - */ - var cellularDevice = null; - - /** - * The active cellular network or null if none. - * @type {?NetworkProperties} - * @private - */ - var cellularNetwork = null; - - /** - * The active ethernet network or null if none. - * @type {?NetworkProperties} - * @private - */ - var ethernetNetwork = null; - - /** - * The state of the WiFi device or undefined if not available. - * @type {string|undefined} - * @private - */ - var wifiDeviceState = undefined; - - /** - * The state of the WiMAX device or undefined if not available. - * @type {string|undefined} - * @private - */ - var wimaxDeviceState = undefined; - - /** - * The current list of third-party VPN providers. - * @type {!Array<!chrome.networkingPrivate.ThirdPartyVPNProperties>}} - * @private - */ - var vpnProviders = []; - - /** - * Indicates if mobile data roaming is enabled. - * @type {boolean} - * @private - */ - var enableDataRoaming = false; - - /** - * Returns the display name for 'network'. - * @param {NetworkProperties} data The network data dictionary. - */ - function getNetworkName(data) { - if (data.Type == 'Ethernet') - return loadTimeData.getString('ethernetName'); - var name = data.Name; - if (data.Type == 'VPN' && data.VPN && data.VPN.Type == 'ThirdPartyVPN' && - data.VPN.ThirdPartyVPN) { - var providerName = data.VPN.ThirdPartyVPN.ProviderName; - if (providerName) - return loadTimeData.getStringF('vpnNameTemplate', providerName, name); - } - return name; - } - - /** - * Create an element in the network list for controlling network - * connectivity. - * @param {Object} data Description of the network list or command. - * @constructor - * @extends {cr.ui.ListItem} - */ - function NetworkListItem(data) { - var el = cr.doc.createElement('li'); - el.data_ = {}; - for (var key in data) - el.data_[key] = data[key]; - NetworkListItem.decorate(el); - return el; - } - - /** - * @param {string} action An action to send to coreOptionsUserMetricsAction. - */ - function sendChromeMetricsAction(action) { - chrome.send('coreOptionsUserMetricsAction', [action]); - } - - /** - * @param {string} guid The network GUID. - */ - function showDetails(guid) { - chrome.networkingPrivate.getManagedProperties( - guid, DetailsInternetPage.initializeDetailsPage); - } - - /** - * Decorate an element as a NetworkListItem. - * @param {!Element} el The element to decorate. - */ - NetworkListItem.decorate = function(el) { - el.__proto__ = NetworkListItem.prototype; - el.decorate(); - }; - - NetworkListItem.prototype = { - __proto__: ListItem.prototype, - - /** - * Description of the network group or control. - * @type {Object<Object>} - * @private - */ - data_: null, - - /** - * Element for the control's subtitle. - * @type {?Element} - * @private - */ - subtitle_: null, - - /** - * Div containing the list item icon. - * @type {?Element} - * @private - */ - iconDiv_: null, - - /** - * Description of the network control. - * @type {Object} - */ - get data() { - return this.data_; - }, - - /** - * Text label for the subtitle. - * @type {string} - */ - set subtitle(text) { - if (text) - this.subtitle_.textContent = text; - this.subtitle_.hidden = !text; - }, - - /** - * Sets the icon based on a network state object. - * @param {!NetworkProperties} data Network state properties. - */ - set iconData(data) { - if (!isNetworkType(data.Type)) - return; - var networkIcon = this.getNetworkIcon(); - networkIcon.networkState = - /** @type {chrome.networkingPrivate.NetworkStateProperties} */ (data); - }, - - /** - * Sets the icon based on a network type or a special type indecator, e.g. - * 'add-connection' - * @type {string} - */ - set iconType(type) { - if (isNetworkType(type)) { - var networkIcon = this.getNetworkIcon(); - networkIcon.networkState = { - GUID: '', - Type: /** @type {CrOnc.Type} */ (type), - }; - } else { - // Special cases. e.g. 'add-connection'. Background images are - // defined in browser_options.css. - var oldIcon = /** @type {CrNetworkIconElement} */ ( - this.iconDiv_.querySelector('cr-network-icon')); - if (oldIcon) - this.iconDiv_.removeChild(oldIcon); - this.iconDiv_.classList.add('network-' + type.toLowerCase()); - } - }, - - /** - * Returns any existing network icon for the list item or creates a new one. - * @return {!CrNetworkIconElement} The network icon for the list item. - */ - getNetworkIcon: function() { - var networkIcon = /** @type {CrNetworkIconElement} */ ( - this.iconDiv_.querySelector('cr-network-icon')); - if (!networkIcon) { - networkIcon = /** @type {!CrNetworkIconElement} */ ( - document.createElement('cr-network-icon')); - networkIcon.isListItem = false; - this.iconDiv_.appendChild(networkIcon); - } - return networkIcon; - }, - - /** - * Set the direction of the text. - * @param {string} direction The direction of the text, e.g. 'ltr'. - */ - setSubtitleDirection: function(direction) { - this.subtitle_.dir = direction; - }, - - /** - * Indicate that the selector arrow should be shown. - */ - showSelector: function() { - this.subtitle_.classList.add('network-selector'); - }, - - /** - * Adds an indicator to show that the network is policy managed. - */ - showManagedNetworkIndicator: function() { - this.appendChild(new ManagedNetworkIndicator()); - }, - - /** @override */ - decorate: function() { - ListItem.prototype.decorate.call(this); - this.className = 'network-group'; - this.iconDiv_ = this.ownerDocument.createElement('div'); - this.iconDiv_.className = 'network-icon'; - this.appendChild(this.iconDiv_); - var textContent = this.ownerDocument.createElement('div'); - textContent.className = 'network-group-labels'; - this.appendChild(textContent); - var categoryLabel = this.ownerDocument.createElement('div'); - var title; - if (this.data_.key == 'addConnection') - title = 'addConnectionTitle'; - else - title = this.data_.key.toLowerCase() + 'Title'; - categoryLabel.className = 'network-title'; - categoryLabel.textContent = loadTimeData.getString(title); - textContent.appendChild(categoryLabel); - this.subtitle_ = this.ownerDocument.createElement('div'); - this.subtitle_.className = 'network-subtitle'; - textContent.appendChild(this.subtitle_); - }, - }; - - /** - * Creates a control that displays a popup menu when clicked. - * @param {Object} data Description of the control. - * @constructor - * @extends {NetworkListItem} - */ - function NetworkMenuItem(data) { - var el = new NetworkListItem(data); - el.__proto__ = NetworkMenuItem.prototype; - el.decorate(); - return el; - } - - NetworkMenuItem.prototype = { - __proto__: NetworkListItem.prototype, - - /** - * Popup menu element. - * @type {?Element} - * @private - */ - menu_: null, - - /** @override */ - decorate: function() { - this.subtitle = null; - if (this.data.iconType) - this.iconType = this.data.iconType; - this.addEventListener('click', (function() { - this.showMenu(); - }).bind(this)); - }, - - /** - * Retrieves the ID for the menu. - */ - getMenuName: function() { - return this.data_.key.toLowerCase() + '-network-menu'; - }, - - /** - * Creates a popup menu for the control. - * @return {Element} The newly created menu. - */ - createMenu: function() { - if (this.data.menu) { - var menu = this.ownerDocument.createElement('div'); - menu.id = this.getMenuName(); - menu.className = 'network-menu'; - menu.hidden = true; - Menu.decorate(menu); - menu.menuItemSelector = '.network-menu-item'; - for (var i = 0; i < this.data.menu.length; i++) { - var entry = this.data.menu[i]; - createCallback_(menu, null, entry.label, entry.command); - } - return menu; - } - return null; - }, - - /** - * Determines if a menu can be updated on the fly. Menus that cannot be - * updated are fully regenerated using createMenu. The advantage of - * updating a menu is that it can preserve ordering of networks avoiding - * entries from jumping around after an update. - * @return {boolean} Whether the menu can be updated on the fly. - */ - canUpdateMenu: function() { - return false; - }, - - /** - * Removes the current menu contents, causing it to be regenerated when the - * menu is shown the next time. If the menu is showing right now, its - * contents are regenerated immediately and the menu remains visible. - */ - refreshMenu: function() { - this.menu_ = null; - if (activeMenu == this.getMenuName()) - this.showMenu(); - }, - - /** - * Displays a popup menu. - */ - showMenu: function() { - var rebuild = false; - // Force a rescan if opening the menu for WiFi networks to ensure the - // list is up to date. Networks are periodically rescanned, but depending - // on timing, there could be an excessive delay before the first rescan - // unless forced. - var rescan = !activeMenu && this.data_.key == 'WiFi'; - if (!this.menu_) { - rebuild = true; - var existing = $(this.getMenuName()); - if (existing) { - if (this.canUpdateMenu() && this.updateMenu()) - return; - closeMenu_(); - } - this.menu_ = this.createMenu(); - this.menu_.addEventListener('mousedown', function(e) { - // Prevent blurring of list, which would close the menu. - e.preventDefault(); - }); - var parent = $('network-menus'); - if (existing) - parent.replaceChild(this.menu_, existing); - else - parent.appendChild(this.menu_); - } - var top = this.offsetTop + this.clientHeight; - var menuId = this.getMenuName(); - if (menuId != activeMenu || rebuild) { - closeMenu_(); - activeMenu = menuId; - this.menu_.style.setProperty('top', top + 'px'); - this.menu_.hidden = false; - } - if (rescan) { - chrome.networkingPrivate.requestNetworkScan(); - } - } - }; - - /** - * Creates a control for selecting or configuring a network connection based - * on the type of connection (e.g. wifi versus vpn). - * @param {{key: string, networkList: Array<!NetworkProperties>}} data - * An object containing the network type (key) and an array of networks. - * @constructor - * @extends {NetworkMenuItem} - */ - function NetworkSelectorItem(data) { - var el = new NetworkMenuItem(data); - el.__proto__ = NetworkSelectorItem.prototype; - el.decorate(); - return el; - } - - /** - * Returns true if |source| is a policy managed source. - * @param {string} source The ONC source of a network. - * @return {boolean} Whether |source| is a managed source. - */ - function isManaged(source) { - return (source == 'DevicePolicy' || source == 'UserPolicy'); - } - - /** - * Returns true if |network| is visible. - * @param {!chrome.networkingPrivate.NetworkStateProperties} network The - * network state properties. - * @return {boolean} Whether |network| is visible. - */ - function networkIsVisible(network) { - if (network.Type == 'WiFi') - return !!(network.WiFi && (network.WiFi.SignalStrength > 0)); - if (network.Type == 'WiMAX') - return !!(network.WiMAX && (network.WiMAX.SignalStrength > 0)); - // Other network types are always considered 'visible'. - return true; - } - - /** - * Returns true if |cellular| is a GSM network with no sim present. - * @param {?chrome.networkingPrivate.DeviceStateProperties} cellularDevice - * @return {boolean} Whether |network| is missing a SIM card. - */ - function isCellularSimAbsent(cellularDevice) { - return !!cellularDevice && cellularDevice.SimPresent === false; - } - - /** - * Returns true if |cellular| has a locked SIM card. - * @param {?chrome.networkingPrivate.DeviceStateProperties} cellularDevice - * @return {boolean} Whether |network| has a locked SIM card. - */ - function isCellularSimLocked(cellularDevice) { - return !!cellularDevice && !!cellularDevice.SimLockType; - } - - NetworkSelectorItem.prototype = { - __proto__: NetworkMenuItem.prototype, - - /** @override */ - decorate: function() { - // TODO(kevers): Generalize method of setting default label. - this.subtitle = loadTimeData.getString('OncConnectionStateNotConnected'); - var list = this.data_.networkList; - var candidateData = null; - for (var i = 0; i < list.length; i++) { - var networkDetails = list[i]; - if (networkDetails.ConnectionState == 'Connecting' || - networkDetails.ConnectionState == 'Connected') { - this.subtitle = getNetworkName(networkDetails); - this.setSubtitleDirection('ltr'); - candidateData = networkDetails; - // Only break when we see a connecting network as it is possible to - // have a connected network and a connecting network at the same - // time. - if (networkDetails.ConnectionState == 'Connecting') - break; - } - } - if (candidateData) - this.iconData = candidateData; - else - this.iconType = this.data.key; - - this.showSelector(); - - if (candidateData && isManaged(candidateData.Source)) - this.showManagedNetworkIndicator(); - - if (activeMenu == this.getMenuName()) { - // Menu is already showing and needs to be updated. Explicitly calling - // show menu will force the existing menu to be replaced. The call - // is deferred in order to ensure that position of this element has - // beem properly updated. - var self = this; - setTimeout(function() {self.showMenu();}, 0); - } - }, - - /** - * Creates a menu for selecting, configuring or disconnecting from a - * network. - * @return {!Element} The newly created menu. - */ - createMenu: function() { - var menu = this.ownerDocument.createElement('div'); - menu.id = this.getMenuName(); - menu.className = 'network-menu'; - menu.hidden = true; - Menu.decorate(menu); - menu.menuItemSelector = '.network-menu-item'; - var addendum = []; - if (this.data_.key == 'WiFi') { - var item = { - label: loadTimeData.getString('joinOtherNetwork'), - data: {} - }; - if (allowUnmanagedNetworks_()) { - item.command = createAddNonVPNConnectionCallback_('WiFi'); - } else { - item.command = null; - item.tooltip = loadTimeData.getString('prohibitedNetworkOther'); - } - addendum.push(item); - } else if (this.data_.key == 'Cellular') { - if (cellularDevice.State == 'Enabled' && - cellularNetwork && cellularNetwork.Cellular && - cellularNetwork.Cellular.SupportNetworkScan) { - addendum.push({ - label: loadTimeData.getString('otherCellularNetworks'), - command: createAddNonVPNConnectionCallback_('Cellular'), - addClass: ['other-cellulars'], - data: {} - }); - } - - var label = enableDataRoaming ? 'disableDataRoaming' : - 'enableDataRoaming'; - var disabled = !loadTimeData.getValue('loggedInAsOwner'); - var entry = {label: loadTimeData.getString(label), - data: {}}; - if (disabled) { - entry.command = null; - entry.tooltip = - loadTimeData.getString('dataRoamingDisableToggleTooltip'); - } else { - var self = this; - entry.command = function() { - options.Preferences.setBooleanPref( - 'cros.signed.data_roaming_enabled', - !enableDataRoaming, true); - // Force revalidation of the menu the next time it is displayed. - self.menu_ = null; - }; - } - addendum.push(entry); - } else if (this.data_.key == 'VPN') { - addendum = addendum.concat(createAddVPNConnectionEntries_()); - } - - var list = this.data.rememberedNetworks; - if (list && list.length > 0) { - var callback = function(list) { - $('remembered-network-list').clear(); - var dialog = options.PreferredNetworks.getInstance(); - PageManager.showPageByName('preferredNetworksPage', false); - dialog.update(list); - sendChromeMetricsAction('Options_NetworkShowPreferred'); - }; - addendum.push({label: loadTimeData.getString('preferredNetworks'), - command: callback, - data: list}); - } - - var networkGroup = this.ownerDocument.createElement('div'); - networkGroup.className = 'network-menu-group'; - list = this.data.networkList; - var empty = !list || list.length == 0; - if (list) { - var connectedVpnGuid = ''; - for (var i = 0; i < list.length; i++) { - var data = list[i]; - this.createNetworkOptionsCallback_(networkGroup, data); - // For VPN only, append a 'Disconnect' item to the dropdown menu. - if (!connectedVpnGuid && data.Type == 'VPN' && - (data.ConnectionState == 'Connected' || - data.ConnectionState == 'Connecting')) { - connectedVpnGuid = data.GUID; - } - } - if (connectedVpnGuid) { - var disconnectCallback = function() { - sendChromeMetricsAction('Options_NetworkDisconnectVPN'); - chrome.networkingPrivate.startDisconnect(connectedVpnGuid); - }; - // Add separator - addendum.push({}); - addendum.push({label: loadTimeData.getString('disconnectNetwork'), - command: disconnectCallback, - data: data}); - } - } - if (this.data_.key == 'WiFi' || this.data_.key == 'WiMAX' || - this.data_.key == 'Cellular') { - addendum.push({}); - if (this.data_.key == 'WiFi') { - addendum.push({ - label: loadTimeData.getString('turnOffWifi'), - command: function() { - sendChromeMetricsAction('Options_NetworkWifiToggle'); - chrome.networkingPrivate.disableNetworkType( - chrome.networkingPrivate.NetworkType.WI_FI); - }, - data: {}}); - } else if (this.data_.key == 'WiMAX') { - addendum.push({ - label: loadTimeData.getString('turnOffWimax'), - command: function() { - chrome.networkingPrivate.disableNetworkType( - chrome.networkingPrivate.NetworkType.WI_MAX); - }, - data: {}}); - } else if (this.data_.key == 'Cellular') { - addendum.push({ - label: loadTimeData.getString('turnOffCellular'), - command: function() { - chrome.networkingPrivate.disableNetworkType( - chrome.networkingPrivate.NetworkType.CELLULAR); - }, - data: {}}); - } - } - if (!empty) - menu.appendChild(networkGroup); - if (addendum.length > 0) { - var separator = false; - if (!empty) { - menu.appendChild(MenuItem.createSeparator()); - separator = true; - } - for (var i = 0; i < addendum.length; i++) { - var value = addendum[i]; - if (value.data) { - var item = createCallback_(menu, value.data, value.label, - value.command); - if (value.tooltip) - item.title = value.tooltip; - if (value.addClass) - item.classList.add(value.addClass); - separator = false; - } else if (!separator) { - menu.appendChild(MenuItem.createSeparator()); - separator = true; - } - } - } - return menu; - }, - - /** @override */ - canUpdateMenu: function() { - return this.data_.key == 'WiFi' && activeMenu == this.getMenuName(); - }, - - /** - * Updates an existing menu. Updated menus preserve ordering of prior - * entries. During the update process, the ordering may differ from the - * preferred ordering as determined by the network library. If the - * ordering becomes potentially out of sync, then the updated menu is - * marked for disposal on close. Reopening the menu will force a - * regeneration, which will in turn fix the ordering. This method must only - * be called if canUpdateMenu() returned |true|. - * @return {boolean} True if successfully updated. - */ - updateMenu: function() { - var oldMenu = $(this.getMenuName()); - var group = oldMenu.getElementsByClassName('network-menu-group')[0]; - if (!group) - return false; - var newMenu = this.createMenu(); - var discardOnClose = false; - var oldNetworkButtons = this.extractNetworkConnectButtons_(oldMenu); - var newNetworkButtons = this.extractNetworkConnectButtons_(newMenu); - for (var key in oldNetworkButtons) { - if (newNetworkButtons[key]) { - group.replaceChild(newNetworkButtons[key].button, - oldNetworkButtons[key].button); - if (newNetworkButtons[key].index != oldNetworkButtons[key].index) - discardOnClose = true; - newNetworkButtons[key] = null; - } else { - // Leave item in list to prevent network items from jumping due to - // deletions. - oldNetworkButtons[key].disabled = true; - discardOnClose = true; - } - } - for (var key in newNetworkButtons) { - var entry = newNetworkButtons[key]; - if (entry) { - group.appendChild(entry.button); - discardOnClose = true; - } - } - oldMenu.data = {discardOnClose: discardOnClose}; - return true; - }, - - /** - * Extracts a mapping of network names to menu element and position. - * @param {!Element} menu The menu to process. - * @return {Object<?{index: number, button: Element}>} - * Network mapping. - * @private - */ - extractNetworkConnectButtons_: function(menu) { - var group = menu.getElementsByClassName('network-menu-group')[0]; - var networkButtons = {}; - if (!group) - return networkButtons; - var buttons = group.getElementsByClassName('network-menu-item'); - for (var i = 0; i < buttons.length; i++) { - var label = buttons[i].data.label; - networkButtons[label] = {index: i, button: buttons[i]}; - } - return networkButtons; - }, - - /** - * Adds a menu item for showing network details. - * @param {!Element} parent The parent element. - * @param {NetworkProperties} data Description of the network. - * @private - */ - createNetworkOptionsCallback_: function(parent, data) { - var menuItem = null; - if (data.Type == 'WiFi' && !allowUnmanagedNetworks_() && - !isManaged(data.Source)) { - menuItem = createCallback_(parent, - data, - getNetworkName(data), - null); - menuItem.title = loadTimeData.getString('prohibitedNetwork'); - } else { - menuItem = createCallback_(parent, - data, - getNetworkName(data), - showDetails.bind(null, data.GUID)); - } - if (isManaged(data.Source)) - menuItem.appendChild(new ManagedNetworkIndicator()); - if (data.ConnectionState == 'Connected' || - data.ConnectionState == 'Connecting') { - var label = menuItem.getElementsByClassName( - 'network-menu-item-label')[0]; - label.classList.add('active-network'); - } - } - }; - - /** - * Creates a button-like control for configurating internet connectivity. - * @param {{key: string, subtitle: string, command: Function}} data - * Description of the network control. - * @constructor - * @extends {NetworkListItem} - */ - function NetworkButtonItem(data) { - var el = new NetworkListItem(data); - el.__proto__ = NetworkButtonItem.prototype; - el.decorate(); - return el; - } - - NetworkButtonItem.prototype = { - __proto__: NetworkListItem.prototype, - - /** @override */ - decorate: function() { - if (this.data.subtitle) - this.subtitle = this.data.subtitle; - else - this.subtitle = null; - if (this.data.command) - this.addEventListener('click', this.data.command); - if (this.data.iconData) - this.iconData = this.data.iconData; - else if (this.data.iconType) - this.iconType = this.data.iconType; - if (isManaged(this.data.Source)) - this.showManagedNetworkIndicator(); - }, - }; - - /** - * Adds a command to a menu for modifying network settings. - * @param {!Element} menu Parent menu. - * @param {?NetworkProperties} data Description of the network. - * @param {!string} label Display name for the menu item. - * @param {Function} command Callback function. - * @return {!Element} The created menu item. - * @private - */ - function createCallback_(menu, data, label, command) { - var button = menu.ownerDocument.createElement('div'); - button.className = 'network-menu-item'; - - var buttonIconDiv = menu.ownerDocument.createElement('div'); - buttonIconDiv.className = 'network-icon'; - button.appendChild(buttonIconDiv); - if (data && isNetworkType(data.Type)) { - var networkIcon = /** @type {!CrNetworkIconElement} */ ( - document.createElement('cr-network-icon')); - buttonIconDiv.appendChild(networkIcon); - networkIcon.isListItem = true; - networkIcon.networkState = - /** @type {chrome.networkingPrivate.NetworkStateProperties} */ (data); - } - - var buttonLabel = menu.ownerDocument.createElement('span'); - buttonLabel.className = 'network-menu-item-label'; - buttonLabel.textContent = label; - button.appendChild(buttonLabel); - var callback = null; - if (command != null) { - if (data) { - callback = function() { - (/** @type {Function} */(command))(data); - closeMenu_(); - }; - } else { - callback = function() { - (/** @type {Function} */(command))(); - closeMenu_(); - }; - } - } - if (callback != null) - button.addEventListener('activate', callback); - else - buttonLabel.classList.add('network-disabled-control'); - - button.data = {label: label}; - MenuItem.decorate(button); - menu.appendChild(button); - return button; - } - - /** - * A list of controls for manipulating network connectivity. - * @constructor - * @extends {cr.ui.List} - */ - var NetworkList = cr.ui.define('list'); - - NetworkList.prototype = { - __proto__: List.prototype, - - /** @override */ - decorate: function() { - List.prototype.decorate.call(this); - this.startBatchUpdates(); - this.autoExpands = true; - this.dataModel = new ArrayDataModel([]); - this.selectionModel = new ListSingleSelectionModel(); - this.addEventListener('blur', this.onBlur_.bind(this)); - this.selectionModel.addEventListener('change', - this.onSelectionChange_.bind(this)); - - // Wi-Fi control is always visible. - this.update({key: 'WiFi', networkList: []}); - - this.updateAddConnectionMenuEntries_(); - - var prefs = options.Preferences.getInstance(); - prefs.addEventListener('cros.signed.data_roaming_enabled', - function(event) { - enableDataRoaming = event.value.value; - }); - this.endBatchUpdates(); - - this.onNetworkListChanged_(); // Trigger an initial network update - - chrome.networkingPrivate.onNetworkListChanged.addListener( - this.onNetworkListChanged_.bind(this)); - chrome.networkingPrivate.onDeviceStateListChanged.addListener( - this.onNetworkListChanged_.bind(this)); - - chrome.management.onInstalled.addListener( - this.onExtensionAdded_.bind(this)); - chrome.management.onEnabled.addListener( - this.onExtensionAdded_.bind(this)); - chrome.management.onUninstalled.addListener( - this.onExtensionRemoved_.bind(this)); - chrome.management.onDisabled.addListener(function(extension) { - this.onExtensionRemoved_(extension.id); - }.bind(this)); - - chrome.management.getAll(this.onGetAllExtensions_.bind(this)); - chrome.networkingPrivate.requestNetworkScan(); - }, - - /** - * networkingPrivate event called when the network list has changed. - */ - onNetworkListChanged_: function() { - var networkList = this; - chrome.networkingPrivate.getDeviceStates(function(deviceStates) { - var filter = { - networkType: chrome.networkingPrivate.NetworkType.ALL - }; - chrome.networkingPrivate.getNetworks(filter, function(networkStates) { - networkList.updateNetworkStates(deviceStates, networkStates); - }); - }); - }, - - /** - * chrome.management.getAll callback. - * @param {!Array<!ExtensionInfo>} extensions - * @private - */ - onGetAllExtensions_: function(extensions) { - vpnProviders = []; - for (var extension of extensions) - this.addVpnProvider_(extension); - }, - - /** - * If |extension| is a third-party VPN provider, add it to vpnProviders. - * @param {!ExtensionInfo} extension - * @private - */ - addVpnProvider_: function(extension) { - if (!extension.enabled || - extension.permissions.indexOf('vpnProvider') == -1) { - return; - } - // Ensure that we haven't already added this provider, e.g. if - // the onExtensionAdded_ callback gets invoked after onGetAllExtensions_ - // for an extension in the returned list. - for (var provider of vpnProviders) { - if (provider.ExtensionID == extension.id) - return; - } - var newProvider = { - ExtensionID: extension.id, - ProviderName: extension.name - }; - vpnProviders.push(newProvider); - this.refreshVpnProviders_(); - }, - - /** - * chrome.management.onInstalled or onEnabled event. - * @param {!ExtensionInfo} extension - * @private - */ - onExtensionAdded_: function(extension) { - this.addVpnProvider_(extension); - }, - - /** - * chrome.management.onUninstalled or onDisabled event. - * @param {string} extensionId - * @private - */ - onExtensionRemoved_: function(extensionId) { - for (var i = 0; i < vpnProviders.length; ++i) { - var provider = vpnProviders[i]; - if (provider.ExtensionID == extensionId) { - vpnProviders.splice(i, 1); - this.refreshVpnProviders_(); - break; - } - } - }, - - /** - * Rebuilds the list of VPN providers. - * @private - */ - refreshVpnProviders_: function() { - // Refresh the contents of the VPN menu. - var index = this.indexOf('VPN'); - if (index != undefined) - this.getListItemByIndex(index).refreshMenu(); - - // Refresh the contents of the "add connection" menu. - this.updateAddConnectionMenuEntries_(); - index = this.indexOf('addConnection'); - if (index != undefined) - this.getListItemByIndex(index).refreshMenu(); - }, - - /** - * Updates the entries in the "add connection" menu, based on the VPN - * providers currently enabled in the user's profile. - * @private - */ - updateAddConnectionMenuEntries_: function() { - var entries = [{ - label: loadTimeData.getString('addConnectionWifi'), - command: createAddNonVPNConnectionCallback_('WiFi') - }]; - entries = entries.concat(createAddVPNConnectionEntries_()); - this.update({key: 'addConnection', - iconType: 'add-connection', - menu: entries - }); - }, - - /** - * When the list loses focus, unselect all items in the list and close the - * active menu. - * @private - */ - onBlur_: function() { - this.selectionModel.unselectAll(); - closeMenu_(); - }, - - /** @override */ - handleKeyDown: function(e) { - if (activeMenu) { - // keyIdentifier does not report 'Esc' correctly - if (e.keyCode == 27 /* Esc */) { - closeMenu_(); - return; - } - - if ($(activeMenu).handleKeyDown(e)) { - e.preventDefault(); - e.stopPropagation(); - } - return; - } - - if (e.key == 'Enter' || - e.key == ' ' /* Space */) { - var selectedListItem = this.getListItemByIndex( - this.selectionModel.selectedIndex); - if (selectedListItem) { - selectedListItem.click(); - return; - } - } - - List.prototype.handleKeyDown.call(this, e); - }, - - /** - * Close bubble and menu when a different list item is selected. - * @param {Event} event Event detailing the selection change. - * @private - */ - onSelectionChange_: function(event) { - PageManager.hideBubble(); - // A list item may temporarily become unselected while it is constructing - // its menu. The menu should therefore only be closed if a different item - // is selected, not when the menu's owner item is deselected. - if (activeMenu) { - for (var i = 0; i < event.changes.length; ++i) { - if (event.changes[i].selected) { - var item = this.dataModel.item(event.changes[i].index); - if (!item.getMenuName || item.getMenuName() != activeMenu) { - closeMenu_(); - return; - } - } - } - } - }, - - /** - * Finds the index of a network item within the data model based on - * category. - * @param {string} key Unique key for the item in the list. - * @return {(number|undefined)} The index of the network item, or - * |undefined| if it is not found. - */ - indexOf: function(key) { - var size = this.dataModel.length; - for (var i = 0; i < size; i++) { - var entry = this.dataModel.item(i); - if (entry.key == key) - return i; - } - return undefined; - }, - - /** - * Updates a network control. - * @param {Object} data Description of the entry. - */ - update: function(data) { - this.startBatchUpdates(); - var index = this.indexOf(data.key); - if (index == undefined) { - // Find reference position for adding the element. We cannot hide - // individual list elements, thus we need to conditionally add or - // remove elements and cannot rely on any element having a fixed index. - for (var i = 0; i < Constants.NETWORK_ORDER.length; i++) { - if (data.key == Constants.NETWORK_ORDER[i]) { - data.sortIndex = i; - break; - } - } - var referenceIndex = -1; - for (var i = 0; i < this.dataModel.length; i++) { - var entry = this.dataModel.item(i); - if (entry.sortIndex < data.sortIndex) - referenceIndex = i; - else - break; - } - if (referenceIndex == -1) { - // Prepend to the start of the list. - this.dataModel.splice(0, 0, data); - } else if (referenceIndex == this.dataModel.length) { - // Append to the end of the list. - this.dataModel.push(data); - } else { - // Insert after the reference element. - this.dataModel.splice(referenceIndex + 1, 0, data); - } - } else { - var entry = this.dataModel.item(index); - data.sortIndex = entry.sortIndex; - this.dataModel.splice(index, 1, data); - } - this.endBatchUpdates(); - }, - - /** - * @override - * @param {Object} entry - */ - createItem: function(entry) { - if (entry.networkList) - return new NetworkSelectorItem( - /** @type {{key: string, networkList: Array<!NetworkProperties>}} */ - (entry)); - if (entry.command) - return new NetworkButtonItem( - /** @type {{key: string, subtitle: string, command: Function}} */( - entry)); - if (entry.menu) - return new NetworkMenuItem(entry); - assertNotReached(); - }, - - /** - * Deletes an element from the list. - * @param {string} key Unique identifier for the element. - */ - deleteItem: function(key) { - var index = this.indexOf(key); - if (index != undefined) - this.dataModel.splice(index, 1); - }, - - /** - * Updates the state of network devices and services. - * @param {!Array<!chrome.networkingPrivate.DeviceStateProperties>} - * deviceStates The result from networkingPrivate.getDeviceStates. - * @param {!Array<!chrome.networkingPrivate.NetworkStateProperties>} - * networkStates The result from networkingPrivate.getNetworks. - */ - updateNetworkStates: function(deviceStates, networkStates) { - // Update device states. - cellularDevice = null; - wifiDeviceState = undefined; - wimaxDeviceState = undefined; - for (var i = 0; i < deviceStates.length; ++i) { - var device = deviceStates[i]; - var type = device.Type; - var state = device.State; - if (type == 'Cellular') - cellularDevice = cellularDevice || device; - else if (type == 'WiFi') - wifiDeviceState = wifiDeviceState || state; - else if (type == 'WiMAX') - wimaxDeviceState = wimaxDeviceState || state; - } - - // Update active network states. - cellularNetwork = null; - ethernetNetwork = null; - for (var i = 0; i < networkStates.length; i++) { - // Note: This cast is valid since - // networkingPrivate.NetworkStateProperties is a subset of - // NetworkProperties and all missing properties are optional. - var entry = /** @type {NetworkProperties} */ (networkStates[i]); - switch (entry.Type) { - case 'Cellular': - cellularNetwork = cellularNetwork || entry; - break; - case 'Ethernet': - // Ignore any EAP Parameters networks (which lack ConnectionState). - if (entry.ConnectionState) - ethernetNetwork = ethernetNetwork || entry; - break; - } - if (cellularNetwork && ethernetNetwork) - break; - } - - if (cellularNetwork && cellularNetwork.GUID) { - // Get the complete set of cellular properties which includes SIM and - // Scan properties. - var networkList = this; - chrome.networkingPrivate.getProperties( - cellularNetwork.GUID, function(cellular) { - cellularNetwork = /** @type {NetworkProperties} */ (cellular); - networkList.updateControls(networkStates); - }); - } else { - this.updateControls(networkStates); - } - }, - - /** - * Updates network controls. - * @param {!Array<!chrome.networkingPrivate.NetworkStateProperties>} - * networkStates The result from networkingPrivate.getNetworks. - */ - updateControls: function(networkStates) { - this.startBatchUpdates(); - - // Only show Ethernet control if available. - if (ethernetNetwork) { - var ethernetOptions = showDetails.bind(null, ethernetNetwork.GUID); - var state = ethernetNetwork.ConnectionState; - var subtitle; - if (state == 'Connected') - subtitle = loadTimeData.getString('OncConnectionStateConnected'); - else if (state == 'Connecting') - subtitle = loadTimeData.getString('OncConnectionStateConnecting'); - else - subtitle = loadTimeData.getString('OncConnectionStateNotConnected'); - this.update( - { key: 'Ethernet', - subtitle: subtitle, - iconData: ethernetNetwork, - command: ethernetOptions, - Source: ethernetNetwork.Source } - ); - } else { - this.deleteItem('Ethernet'); - } - - if (wifiDeviceState == 'Enabled') - loadData_('WiFi', networkStates); - else if (wifiDeviceState == - chrome.networkingPrivate.DeviceStateType.PROHIBITED) - setTechnologiesProhibited_(chrome.networkingPrivate.NetworkType.WI_FI); - else - addEnableNetworkButton_(chrome.networkingPrivate.NetworkType.WI_FI); - - // Only show cellular control if available. - if (cellularDevice) { - if (cellularDevice.State == 'Enabled' && - !isCellularSimAbsent(cellularDevice) && - !isCellularSimLocked(cellularDevice)) { - loadData_('Cellular', networkStates); - } else if (cellularDevice.State == - chrome.networkingPrivate.DeviceStateType.PROHIBITED) { - setTechnologiesProhibited_( - chrome.networkingPrivate.NetworkType.CELLULAR); - } else { - addEnableNetworkButton_( - chrome.networkingPrivate.NetworkType.CELLULAR); - } - } else { - this.deleteItem('Cellular'); - } - - // Only show wimax control if available. Uses cellular icons. - if (wimaxDeviceState) { - if (wimaxDeviceState == 'Enabled') { - loadData_('WiMAX', networkStates); - } else if (wimaxDeviceState == - chrome.networkingPrivate.DeviceStateType.PROHIBITED) { - setTechnologiesProhibited_( - chrome.networkingPrivate.NetworkType.WI_MAX); - } else { - addEnableNetworkButton_(chrome.networkingPrivate.NetworkType.WI_MAX); - } - } else { - this.deleteItem('WiMAX'); - } - - // Only show VPN control if there is at least one VPN configured. - if (loadData_('VPN', networkStates) == 0) - this.deleteItem('VPN'); - - this.endBatchUpdates(); - } - }; - - /** - * Replaces a network menu with a button for enabling the network type. - * @param {chrome.networkingPrivate.NetworkType} type - * @private - */ - function addEnableNetworkButton_(type) { - var subtitle = loadTimeData.getString('networkDisabled'); - var enableNetwork = function() { - if (type == chrome.networkingPrivate.NetworkType.WI_FI) - sendChromeMetricsAction('Options_NetworkWifiToggle'); - if (type == chrome.networkingPrivate.NetworkType.CELLULAR) { - if (isCellularSimLocked(cellularDevice)) { - chrome.send('simOperation', ['unlock']); - return; - } else if (isCellularSimAbsent(cellularDevice)) { - chrome.send('simOperation', ['configure']); - return; - } - } - chrome.networkingPrivate.enableNetworkType(type); - }; - $('network-list').update({key: type, - subtitle: subtitle, - iconType: type, - command: enableNetwork}); - } - - /** - * Replaces a network menu with a button with nothing to do. - * @param {!chrome.networkingPrivate.NetworkType} type - * @private - */ - function setTechnologiesProhibited_(type) { - var subtitle = loadTimeData.getString('networkProhibited'); - var doNothingButRemoveClickShadow = function() { - this.removeAttribute('lead'); - this.removeAttribute('selected'); - this.parentNode.removeAttribute('has-element-focus'); - }; - $('network-list').update({key: type, - subtitle: subtitle, - iconType: type, - command: doNothingButRemoveClickShadow}); - } - - /** - * Element for indicating a policy managed network. - * @constructor - * @extends {options.ControlledSettingIndicator} - */ - function ManagedNetworkIndicator() { - var el = cr.doc.createElement('span'); - el.__proto__ = ManagedNetworkIndicator.prototype; - el.decorate(); - return el; - } - - ManagedNetworkIndicator.prototype = { - __proto__: ControlledSettingIndicator.prototype, - - /** @override */ - decorate: function() { - ControlledSettingIndicator.prototype.decorate.call(this); - this.controlledBy = 'policy'; - var policyLabel = loadTimeData.getString('managedNetwork'); - this.setAttribute('textPolicy', policyLabel); - this.removeAttribute('tabindex'); - }, - - /** @override */ - handleEvent: function(event) { - // Prevent focus blurring as that would close any currently open menu. - if (event.type == 'mousedown') - return; - ControlledSettingIndicator.prototype.handleEvent.call(this, event); - }, - - /** - * Handle mouse events received by the bubble, preventing focus blurring as - * that would close any currently open menu and preventing propagation to - * any elements located behind the bubble. - * @param {Event} event Mouse event. - */ - stopEvent: function(event) { - event.preventDefault(); - event.stopPropagation(); - }, - - /** @override */ - toggleBubble: function() { - if (activeMenu && !$(activeMenu).contains(this)) - closeMenu_(); - ControlledSettingIndicator.prototype.toggleBubble.call(this); - if (this.showingBubble) { - var bubble = PageManager.getVisibleBubble(); - bubble.addEventListener('mousedown', this.stopEvent); - bubble.addEventListener('click', this.stopEvent); - } - } - }; - - /** - * Updates the list of available networks and their status, filtered by - * network type. - * @param {string} type The type of network. - * @param {Array<!chrome.networkingPrivate.NetworkStateProperties>} networks - * The list of network objects. - * @return {number} The number of visible networks matching |type|. - */ - function loadData_(type, networks) { - var res = 0; - var availableNetworks = []; - var rememberedNetworks = []; - for (var i = 0; i < networks.length; i++) { - var network = networks[i]; - if (network.Type != type) - continue; - if (networkIsVisible(network)) { - availableNetworks.push(network); - ++res; - } - if ((type == 'WiFi' || type == 'VPN') && network.Source && - network.Source != 'None') { - rememberedNetworks.push(network); - } - } - var data = { - key: type, - networkList: availableNetworks, - rememberedNetworks: rememberedNetworks - }; - $('network-list').update(data); - return res; - } - - /** - * Hides the currently visible menu. - * @private - */ - function closeMenu_() { - if (activeMenu) { - var menu = $(activeMenu); - menu.hidden = true; - if (menu.data && menu.data.discardOnClose) - menu.parentNode.removeChild(menu); - activeMenu = null; - } - } - - /** - * Creates a callback function that adds a new connection of the given type. - * This method may be used for all network types except VPN. - * @param {string} type An ONC network type - * @return {function()} The created callback. - * @private - */ - function createAddNonVPNConnectionCallback_(type) { - return function() { - if (type == 'WiFi') - sendChromeMetricsAction('Options_NetworkJoinOtherWifi'); - chrome.send('addNonVPNConnection', [type]); - }; - } - - /** - * Creates a callback function that shows the "add network" dialog for a VPN - * provider. If |opt_extensionID| is omitted, the dialog for the built-in - * OpenVPN/L2TP provider is shown. Otherwise, |opt_extensionID| identifies the - * third-party provider for which the dialog should be shown. - * @param {string=} opt_extensionID Extension ID identifying the third-party - * VPN provider for which the dialog should be shown. - * @return {function()} The created callback. - * @private - */ - function createVPNConnectionCallback_(opt_extensionID) { - return function() { - sendChromeMetricsAction(opt_extensionID ? - 'Options_NetworkAddVPNThirdParty' : - 'Options_NetworkAddVPNBuiltIn'); - chrome.send('addVPNConnection', - opt_extensionID ? [opt_extensionID] : undefined); - }; - } - - /** - * Generates an "add network" entry for each VPN provider currently enabled in - * the user's profile. - * @return {!Array<{label: string, command: function(), data: !Object}>} The - * list of entries. - * @private - */ - function createAddVPNConnectionEntries_() { - var entries = []; - for (var i = 0; i < vpnProviders.length; ++i) { - var provider = vpnProviders[i]; - entries.push({ - label: loadTimeData.getStringF('addConnectionVPNTemplate', - provider.ProviderName), - command: createVPNConnectionCallback_(provider.ExtensionID), - data: {} - }); - } - // Add an entry for the built-in OpenVPN/L2TP provider. - entries.push({ - label: loadTimeData.getString('vpnBuiltInProvider'), - command: createVPNConnectionCallback_(), - data: {} - }); - return entries; - } - - /** - * Return whether connecting to or viewing unmanaged networks is allowed. - * @private - */ - function allowUnmanagedNetworks_() { - if (loadTimeData.valueExists('allowOnlyPolicyNetworksToConnect') && - loadTimeData.getBoolean('allowOnlyPolicyNetworksToConnect')) { - return false; - } - return true; - } - - /** - * Whether the Network list is disabled. Only used for display purpose. - */ - cr.defineProperty(NetworkList, 'disabled', cr.PropertyKind.BOOL_ATTR); - - // Export - return { - NetworkList: NetworkList - }; -});
diff --git a/chrome/browser/resources/options/chromeos/onc_data.js b/chrome/browser/resources/options/chromeos/onc_data.js deleted file mode 100644 index 8114dbd2..0000000 --- a/chrome/browser/resources/options/chromeos/onc_data.js +++ /dev/null
@@ -1,195 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -/** - * @fileoverview ONC Data support class. Wraps a dictionary object containing - * ONC managed or unmanaged dictionaries. Supports nested dictionaries, - * e.g. data.getManagedProperty('VPN.Type'). - */ - -cr.exportPath('cr.onc'); - -cr.define('cr.onc', function() { - 'use strict'; - - /** - * @constructor - */ - function OncData(data) { - this.data_ = data; - } - - OncData.prototype = { - /** @return {string} The GUID of the network. */ - guid: function() { return this.data_['GUID']; }, - - /** - * Returns either a managed property dictionary or an unmanaged value. - * @param {string} key The property key. - * @return {?} The property value or dictionary if it exists, otherwise - * undefined. - */ - getManagedProperty: function(key) { - var data = this.data_; - while (true) { - var index = key.indexOf('.'); - if (index < 0) - break; - var keyComponent = key.substr(0, index); - if (!(keyComponent in data)) - return undefined; - data = data[keyComponent]; - key = key.substr(index + 1); - } - return data[key]; - }, - - /** - * Sets the value of a property. Currently only supports unmanaged - * properties. - * @param {string} key The property key. - * @param {?} value The property value to set. - */ - setProperty: function(key, value) { - var data = this.data_; - while (true) { - var index = key.indexOf('.'); - if (index < 0) - break; - var keyComponent = key.substr(0, index); - if (!(keyComponent in data)) - data[keyComponent] = {}; - data = data[keyComponent]; - key = key.substr(index + 1); - } - if (!(key in data) || - (typeof data[key] != 'object') || - (!('Active' in data[key]) && !('Effective' in data[key]))) { - data[key] = value; - } else { - var effective = data[key]['Effective']; - assert(effective != 'UserPolicy' || data[key]['UserEditable']); - assert(effective != 'DevicePolicy' || data[key]['DeviceEditable']); - // For now, just update the active value. TODO(stevenjb): Eventually we - // should update the 'UserSetting' and 'Effective' properties correctly - // and send that back to Chrome. - data[key]['Active'] = value; - } - }, - - /** - * Gets the active value of a property. - * @param {string} key The property key. - * @return {?} The property value or undefined. - */ - getActiveValue: function(key) { - var property = this.getManagedProperty(key); - if (Array.isArray(property) || typeof property != 'object') - return property; - // Otherwise get the Active value (default behavior). - if ('Active' in property) - return property['Active']; - // If no Active value is defined, return the effective value if present. - var effective = this.getEffectiveValueFromProperty_( - /** @type {Object} */(property)); - if (effective != undefined) - return effective; - // Otherwise this is an Object but not a Managed one. - return property; - }, - - /** - * Gets the translated ONC value from the result of getActiveValue() using - * loadTimeData. If no translation exists, returns the untranslated value. - * @param {string} key The property key. - * @return {?} The translation if available or the value if not. - */ - getTranslatedValue: function(key) { - var value = this.getActiveValue(key); - if (typeof value != 'string') - return value; - var oncString = 'Onc' + key + value; - // Handle special cases - if (key == 'Name' && this.getActiveValue('Type') == 'Ethernet') - return loadTimeData.getString('ethernetName'); - if (key == 'VPN.Type' && value == 'L2TP-IPsec') { - var auth = this.getActiveValue('VPN.IPsec.AuthenticationType'); - if (auth != undefined) - oncString += auth; - } - oncString = oncString.replace(/\./g, '-'); - if (loadTimeData.valueExists(oncString)) - return loadTimeData.getString(oncString); - return value; - }, - - /** - * Gets the recommended value of a property. - * @param {string} key The property key. - * @return {?} The property value or undefined. - */ - getRecommendedValue: function(key) { - var property = this.getManagedProperty(key); - if (Array.isArray(property) || typeof property != 'object') - return undefined; - if (property['UserEditable']) - return property['UserPolicy']; - if (property['DeviceEditable']) - return property['DevicePolicy']; - // No value recommended by policy. - return undefined; - }, - - /** - * Returns the Source of this configuration. If undefined returns 'None'. - * @return {string} The configuration source: 'None', 'User', 'Device', - * 'UserPolicy', or 'DevicePolicy'. - */ - getSource: function() { - var source = this.getActiveValue('Source'); - if (source == undefined) - return 'None'; - assert(typeof source == 'string'); - return source; - }, - - /** - * Returns the WiFi security type (defaults to 'None'). - * @return {string} The security type. - */ - getWiFiSecurity: function() { - var security = this.getActiveValue('WiFi.Security'); - if (security == undefined) - return 'None'; - assert(typeof security == 'string'); - return security; - }, - - /** - * Get the effective value from a Managed property ONC dictionary. - * @param {Object} property The managed property ONC dictionary. - * @return {?} The effective value or undefined. - * @private - */ - getEffectiveValueFromProperty_: function(property) { - if ('Effective' in property) { - var effective = property.Effective; - if (effective in property) - return property[effective]; - } - return undefined; - }, - - /** - * Returns the complete ONC dictionary. - */ - getData: function() { - return this.data_; - } - }; - - return { - OncData: OncData - }; -});
diff --git a/chrome/browser/resources/options/chromeos/overscan_arrows.png b/chrome/browser/resources/options/chromeos/overscan_arrows.png deleted file mode 100644 index 6f3e394a..0000000 --- a/chrome/browser/resources/options/chromeos/overscan_arrows.png +++ /dev/null Binary files differ
diff --git a/chrome/browser/resources/options/chromeos/overscan_arrows_2x.png b/chrome/browser/resources/options/chromeos/overscan_arrows_2x.png deleted file mode 100644 index 10171c6a..0000000 --- a/chrome/browser/resources/options/chromeos/overscan_arrows_2x.png +++ /dev/null Binary files differ
diff --git a/chrome/browser/resources/options/chromeos/overscan_shift.png b/chrome/browser/resources/options/chromeos/overscan_shift.png deleted file mode 100644 index 7f4bef5..0000000 --- a/chrome/browser/resources/options/chromeos/overscan_shift.png +++ /dev/null Binary files differ
diff --git a/chrome/browser/resources/options/chromeos/overscan_shift_2x.png b/chrome/browser/resources/options/chromeos/overscan_shift_2x.png deleted file mode 100644 index 7d23fdfd..0000000 --- a/chrome/browser/resources/options/chromeos/overscan_shift_2x.png +++ /dev/null Binary files differ
diff --git a/chrome/browser/resources/options/chromeos/overscan_shift_rtl.png b/chrome/browser/resources/options/chromeos/overscan_shift_rtl.png deleted file mode 100644 index 3bc14f4..0000000 --- a/chrome/browser/resources/options/chromeos/overscan_shift_rtl.png +++ /dev/null Binary files differ
diff --git a/chrome/browser/resources/options/chromeos/overscan_shift_rtl_2x.png b/chrome/browser/resources/options/chromeos/overscan_shift_rtl_2x.png deleted file mode 100644 index fb89e2f..0000000 --- a/chrome/browser/resources/options/chromeos/overscan_shift_rtl_2x.png +++ /dev/null Binary files differ
diff --git a/chrome/browser/resources/options/chromeos/pointer_overlay.css b/chrome/browser/resources/options/chromeos/pointer_overlay.css deleted file mode 100644 index 9076ef19..0000000 --- a/chrome/browser/resources/options/chromeos/pointer_overlay.css +++ /dev/null
@@ -1,11 +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. */ - -#pointer-overlay > .content-area > :not([hidden]) + :nth-child(2) { - margin-top: 20px; -} - -#touchpad-scroll-direction { - margin-top: 12px; -}
diff --git a/chrome/browser/resources/options/chromeos/pointer_overlay.html b/chrome/browser/resources/options/chromeos/pointer_overlay.html deleted file mode 100644 index 1462249..0000000 --- a/chrome/browser/resources/options/chromeos/pointer_overlay.html +++ /dev/null
@@ -1,49 +0,0 @@ -<div id="pointer-overlay" class="page" hidden> - <div class="close-button"></div> - <div class="content-area"> - <section id="pointer-section-touchpad" hidden> - <h3>$i18n{pointerOverlaySectionTitleTouchpad}</h3> - <div class="checkbox"> - <label> - <input type="checkbox" metric="Options_TouchpadTapToClick" - pref="settings.touchpad.enable_tap_to_click" dialog-pref> - <span>$i18n{enableTapToClick}</span> - </label> - </div> - <div class="radio" id="touchpad-scroll-direction"> - <label> - <input type="radio" name="touchpad-scroll-direction" value="false" - metric="Options_TouchpadNaturalScroll" - pref="settings.touchpad.natural_scroll" dialog-pref> - <span>$i18n{traditionalScroll}</span> - </label> - </div> - <div class="radio"> - <label> - <input type="radio" name="touchpad-scroll-direction" value="true" - metric="Options_TouchpadNaturalScroll" - pref="settings.touchpad.natural_scroll" dialog-pref> - <span>$i18nRaw{naturalScroll}</span> - </label> - </div> - </section> - <section id="pointer-section-mouse" hidden> - <h3>$i18n{pointerOverlaySectionTitleMouse}</h3> - <div class="checkbox"> - <label> - <input type="checkbox" metric="Options_MousePrimaryRight" - pref="settings.mouse.primary_right" dialog-pref> - <span>$i18n{primaryMouseRight}</span> - </label> - </div> - </section> - </div> - <div class="action-area"> - <div class="button-strip"> - <button id="pointer-overlay-cancel" type="reset">$i18n{cancel}</button> - <button id="pointer-overlay-confirm" class="default-button" type="submit"> - $i18n{ok} - </button> - </div> - </div> -</div>
diff --git a/chrome/browser/resources/options/chromeos/pointer_overlay.js b/chrome/browser/resources/options/chromeos/pointer_overlay.js deleted file mode 100644 index 62c603a..0000000 --- a/chrome/browser/resources/options/chromeos/pointer_overlay.js +++ /dev/null
@@ -1,71 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -cr.define('options', function() { - /** @const */ var SettingsDialog = options.SettingsDialog; - - /** - * PointerOverlay class - * Dialog that allows users to set pointer settings (touchpad/mouse). - * @constructor - * @extends {options.SettingsDialog} - */ - function PointerOverlay() { - // The title is updated dynamically in the setTitle method as pointer - // devices are discovered or removed. - SettingsDialog.call(this, 'pointer-overlay', - '', 'pointer-overlay', - assertInstanceof($('pointer-overlay-confirm'), HTMLButtonElement), - assertInstanceof($('pointer-overlay-cancel'), HTMLButtonElement)); - } - - cr.addSingletonGetter(PointerOverlay); - - PointerOverlay.prototype = { - __proto__: SettingsDialog.prototype, - }; - - /** - * Sets the visibility state of the touchpad group. - * @param {boolean} show True to show, false to hide. - */ - PointerOverlay.showTouchpadControls = function(show) { - $('pointer-section-touchpad').hidden = !show; - }; - - /** - * Sets the visibility state of the mouse group. - * @param {boolean} show True to show, false to hide. - */ - PointerOverlay.showMouseControls = function(show) { - $('pointer-section-mouse').hidden = !show; - }; - - /** - * Updates the title of the pointer dialog. The title is set dynamically - * based on whether a touchpad, mouse or both are present. The label on the - * button that activates the overlay is also updated to stay in sync. A - * message is displayed in the main settings page if no pointer devices are - * available. - * @param {string} label i18n key for the overlay title. - */ - PointerOverlay.setTitle = function(label) { - var button = $('pointer-settings-button'); - var noPointersLabel = $('no-pointing-devices'); - if (label.length > 0) { - var title = loadTimeData.getString(label); - button.textContent = title; - button.hidden = false; - noPointersLabel.hidden = true; - } else { - button.hidden = true; - noPointersLabel.hidden = false; - } - }; - - // Export - return { - PointerOverlay: PointerOverlay - }; -});
diff --git a/chrome/browser/resources/options/chromeos/power_overlay.css b/chrome/browser/resources/options/chromeos/power_overlay.css deleted file mode 100644 index 91408fff7..0000000 --- a/chrome/browser/resources/options/chromeos/power_overlay.css +++ /dev/null
@@ -1,7 +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. */ - -#power-overlay > .content-area .option-value { - padding-left: 5px; -}
diff --git a/chrome/browser/resources/options/chromeos/power_overlay.html b/chrome/browser/resources/options/chromeos/power_overlay.html deleted file mode 100644 index f4b637c..0000000 --- a/chrome/browser/resources/options/chromeos/power_overlay.html +++ /dev/null
@@ -1,34 +0,0 @@ -<div id="power-overlay" class="page" hidden> - <div class="close-button"></div> - <h1>$i18n{powerOverlay}</h1> - <div class="content-area"> - <table> - <tr> - <td class="option-name">$i18n{batteryStatusLabel}</td> - <td id="battery-status-value" class="option-value"> - </td> - </tr> - <tr id="power-sources" hidden> - <td class="option-name"> - <label id="power-source-label">$i18n{powerSourceLabel}</label> - </td> - <td class="option-value"> - <select id="power-source-dropdown" - aria-labelledby="power-source-label"></select> - </td> - </tr> - <tr id="power-source-charger" hidden> - <td class="option-name">$i18n{powerSourceLabel}</td> - <td id="power-source-charger-type" class="option-value"> - </td> - </tr> - </table> - </div> - <div class="action-area"> - <div class="button-strip"> - <button id="power-confirm" class="default-button" type="submit"> - $i18n{done} - </button> - </div> - </div> -</div>
diff --git a/chrome/browser/resources/options/chromeos/power_overlay.js b/chrome/browser/resources/options/chromeos/power_overlay.js deleted file mode 100644 index b2f5b34..0000000 --- a/chrome/browser/resources/options/chromeos/power_overlay.js +++ /dev/null
@@ -1,172 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -cr.exportPath('options'); - -/** - * Copied from ash/system/power/power_status.h. - * @enum {number} - */ -options.PowerStatusDeviceType = { - DEDICATED_CHARGER: 0, - DUAL_ROLE_USB: 1, -}; - -/** - * @typedef {{ - * id: string, - * type: options.PowerStatusDeviceType, - * description: string - * }} - */ -options.PowerSource; - -cr.define('options', function() { - var Page = cr.ui.pageManager.Page; - var PageManager = cr.ui.pageManager.PageManager; - - /** - * Encapsulated handling of the power overlay. - * @constructor - * @extends {cr.ui.pageManager.Page} - */ - function PowerOverlay() { - Page.call(this, 'power-overlay', - loadTimeData.getString('powerOverlayTabTitle'), - 'power-overlay'); - } - - cr.addSingletonGetter(PowerOverlay); - - PowerOverlay.prototype = { - __proto__: Page.prototype, - - /** @override */ - initializePage: function() { - Page.prototype.initializePage.call(this); - - $('power-confirm').onclick = - PageManager.closeOverlay.bind(PageManager); - $('power-source-dropdown').onchange = - this.powerSourceChanged_.bind(this); - }, - - /** @override */ - didShowPage: function() { - chrome.send('updatePowerStatus'); - }, - - /** - * @param {string} status - * @private - */ - setBatteryStatusText_: function(status) { - $('battery-status-value').textContent = status; - }, - - /** - * @param {Array<options.PowerSource>} sources External power sources. - * @param {string} selectedId The ID of the currently used power source. - * @param {boolean} isUsbCharger Whether the currently used power source - * is a USB (low-powered) charger. - * @param {boolean} isCalculating Whether the power info is still - * being calculated. - * @private - */ - setPowerSources_: function(sources, selectedId, isUsbCharger, - isCalculating) { - if (this.lastPowerSource_ != selectedId) { - this.lastPowerSource_ = selectedId; - if (selectedId && !isUsbCharger) { - // It can take a while to detect a USB charger, but triggering a - // power status update makes the determination faster. - setTimeout(chrome.send.bind(null, 'updatePowerStatus'), 1000); - } - } - - var chargerRow = $('power-source-charger'); - - $('power-sources').hidden = chargerRow.hidden = true; - - // If no power sources are available, only show the battery status text. - if (sources.length == 0) - return; - - // If we're still calculating battery time and seem to have an AC - // adapter, the charger information may be wrong. - if (isCalculating && selectedId && !isUsbCharger) { - $('power-source-charger-type').textContent = - loadTimeData.getString('calculatingPower'); - chargerRow.hidden = false; - return; - } - - // Check if a dedicated charger is being used. - var usingDedicatedCharger = false; - if (selectedId) { - usingDedicatedCharger = sources.some(function(source) { - return source.id == selectedId && - source.type == options.PowerStatusDeviceType.DEDICATED_CHARGER; - }); - } - - if (usingDedicatedCharger) { - // Show charger information. - $('power-source-charger-type').textContent = loadTimeData.getString( - isUsbCharger ? 'powerSourceLowPowerCharger' : - 'powerSourceAcAdapter'); - chargerRow.hidden = false; - } else { - this.showPowerSourceList_(sources, selectedId); - } - }, - - /** - * Populates and shows the dropdown of available power sources. - * @param {Array<options.PowerSource>} sources External power sources. - * @param {string} selectedId The ID of the currently used power source. - * The empty string indicates no external power source is in use - * (running on battery). - * @private - */ - showPowerSourceList_: function(sources, selectedId) { - // Clear the dropdown. - var dropdown = $('power-source-dropdown'); - dropdown.innerHTML = ''; - - // Add a battery option. - sources.unshift({ - id: '', - description: loadTimeData.getString('powerSourceBattery'), - }); - - // Build the power source list. - sources.forEach(function(source) { - var option = document.createElement('option'); - option.value = source.id; - option.textContent = source.description; - option.selected = source.id == selectedId; - dropdown.appendChild(option); - }); - - // Show the power source list. - $('power-sources').hidden = false; - }, - - /** @private */ - powerSourceChanged_: function() { - chrome.send('setPowerSource', [$('power-source-dropdown').value]); - }, - }; - - cr.makePublic(PowerOverlay, [ - 'setBatteryStatusText', - 'setPowerSources', - ]); - - // Export - return { - PowerOverlay: PowerOverlay - }; -});
diff --git a/chrome/browser/resources/options/chromeos/preferred_networks.html b/chrome/browser/resources/options/chromeos/preferred_networks.html deleted file mode 100644 index 75b373e..0000000 --- a/chrome/browser/resources/options/chromeos/preferred_networks.html +++ /dev/null
@@ -1,16 +0,0 @@ -<div id="preferredNetworksPage" class="page" hidden> - <div class="close-button"></div> - <h1 id="preferred-networks-page-title" >$i18n{preferredNetworksPage}</h1> - <div class="content-area"> - <div class="settings-list"> - <list id="remembered-network-list"></list> - </div> - </div> - <div class="action-area"> - <div class="button-strip"> - <button id="preferred-networks-confirm" class="default-button"> - $i18n{done} - </button> - </div> - </div> -</div>
diff --git a/chrome/browser/resources/options/chromeos/preferred_networks.js b/chrome/browser/resources/options/chromeos/preferred_networks.js deleted file mode 100644 index 4f5a152b..0000000 --- a/chrome/browser/resources/options/chromeos/preferred_networks.js +++ /dev/null
@@ -1,161 +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. - -cr.exportPath('options'); - -/** - * @typedef {{GUID: string, Name: string, Source: string, Type: string}} - */ -options.PreferredNetwork; - -cr.define('options', function() { - - var Page = cr.ui.pageManager.Page; - var PageManager = cr.ui.pageManager.PageManager; - var ArrayDataModel = cr.ui.ArrayDataModel; - var DeletableItem = options.DeletableItem; - var DeletableItemList = options.DeletableItemList; - - ///////////////////////////////////////////////////////////////////////////// - // NetworkPreferences class: - - /** - * Encapsulated handling of ChromeOS network preferences page. - * @constructor - * @extends {cr.ui.pageManager.Page} - */ - function PreferredNetworks(model) { - Page.call(this, 'preferredNetworksPage', '', 'preferredNetworksPage'); - } - - cr.addSingletonGetter(PreferredNetworks); - - PreferredNetworks.prototype = { - __proto__: Page.prototype, - - /** @override */ - initializePage: function() { - Page.prototype.initializePage.call(this); - PreferredNetworkList.decorate($('remembered-network-list')); - $('preferred-networks-confirm').onclick = - PageManager.closeOverlay.bind(PageManager); - }, - - update: function(rememberedNetworks) { - var list = $('remembered-network-list'); - list.clear(); - for (var i = 0; i < rememberedNetworks.length; i++) { - list.append(rememberedNetworks[i]); - } - list.redraw(); - } - - }; - - /** - * Creates a list entry for a remembered network. - * @param {options.PreferredNetwork} data Description of the network. - * @constructor - * @extends {options.DeletableItem} - */ - function PreferredNetworkListItem(data) { - var el = cr.doc.createElement('div'); - el.__proto__ = PreferredNetworkListItem.prototype; - el.data = {}; - for (var key in data) - el.data[key] = data[key]; - el.decorate(); - return el; - } - - PreferredNetworkListItem.prototype = { - __proto__: DeletableItem.prototype, - - /** - * Description of the network. - * @type {?options.PreferredNetwork} - */ - data: null, - - /** @override */ - decorate: function() { - DeletableItem.prototype.decorate.call(this); - var label = this.ownerDocument.createElement('div'); - label.textContent = this.data.Name; - if (this.data.Source == 'DevicePolicy' || - this.data.Source == 'UserPolicy') { - this.deletable = false; - } - this.contentElement.appendChild(label); - } - }; - - /** - * Class for displaying a list of preferred networks. - * @constructor - * @extends {options.DeletableItemList} - */ - var PreferredNetworkList = cr.ui.define('list'); - - PreferredNetworkList.prototype = { - __proto__: DeletableItemList.prototype, - - /** @override */ - decorate: function() { - DeletableItemList.prototype.decorate.call(this); - this.addEventListener('blur', this.onBlur_); - this.clear(); - }, - - /** - * When the list loses focus, unselect all items in the list. - * @private - */ - onBlur_: function() { - this.selectionModel.unselectAll(); - }, - - /** - * @override - * @param {options.PreferredNetwork} entry - */ - createItem: function(entry) { - return new PreferredNetworkListItem(entry); - }, - - /** @override */ - deleteItemAtIndex: function(index) { - var item = this.dataModel.item(index); - if (item) - chrome.networkingPrivate.forgetNetwork(item.GUID); - this.dataModel.splice(index, 1); - // Invalidate the list since it has a stale cache after a splice - // involving a deletion. - this.invalidate(); - this.redraw(); - }, - - /** - * Purges all networks from the list. - */ - clear: function() { - this.dataModel = new ArrayDataModel([]); - this.redraw(); - }, - - /** - * Adds a remembered network to the list. - * @param {options.PreferredNetwork} data Description of the network. - */ - append: function(data) { - this.dataModel.push(data); - } - }; - - // Export - return { - PreferredNetworks: PreferredNetworks - }; - -});
diff --git a/chrome/browser/resources/options/chromeos/proxy_rules_list.js b/chrome/browser/resources/options/chromeos/proxy_rules_list.js deleted file mode 100644 index 8c86ffc..0000000 --- a/chrome/browser/resources/options/chromeos/proxy_rules_list.js +++ /dev/null
@@ -1,144 +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. - -cr.define('options.proxyexceptions', function() { - /** @const */ var List = cr.ui.List; - /** @const */ var ListItem = cr.ui.ListItem; - /** @const */ var ArrayDataModel = cr.ui.ArrayDataModel; - - /** - * Creates a new exception list. - * @param {Object=} opt_propertyBag Optional properties. - * @constructor - * @extends {cr.ui.List} - */ - var ProxyExceptions = cr.ui.define('list'); - - ProxyExceptions.prototype = { - __proto__: List.prototype, - - pref: 'cros.session.proxy.ignorelist', - - /** @override */ - decorate: function() { - List.prototype.decorate.call(this); - this.autoExpands = true; - - // HACK(arv): http://crbug.com/40902 - window.addEventListener('resize', this.redraw.bind(this)); - - this.addEventListener('click', this.handleClick_); - - var self = this; - - // Listens to pref changes. - Preferences.getInstance().addEventListener(this.pref, - function(event) { - self.load_(event.value.value); - }); - }, - - /** - * @override - * @param {Object} exception - */ - createItem: function(exception) { - return new ProxyExceptionsItem(exception); - }, - - /** - * Adds given exception to model and update backend. - * @param {Object} exception A exception to be added to exception list. - */ - addException: function(exception) { - this.dataModel.push(exception); - this.updateBackend_(); - }, - - /** - * Removes given exception from model and update backend. - */ - removeException: function(exception) { - var dataModel = this.dataModel; - - var index = dataModel.indexOf(exception); - if (index >= 0) { - dataModel.splice(index, 1); - this.updateBackend_(); - } - }, - - /** - * Handles the clicks on the list and triggers exception removal if the - * click is on the remove exception button. - * @private - * @param {!Event} e The click event object. - */ - handleClick_: function(e) { - // Handle left button click - if (e.button == 0) { - var el = e.target; - if (el.className == 'remove-exception-button') { - this.removeException(el.parentNode.exception); - } - } - }, - - /** - * Loads given exception list. - * @param {!Array} exceptions An array of exception object. - */ - load_: function(exceptions) { - this.dataModel = new ArrayDataModel(exceptions); - }, - - /** - * Updates backend. - */ - updateBackend_: function() { - Preferences.setListPref(this.pref, this.dataModel.slice(), true); - } - }; - - /** - * Creates a new exception list item. - * @param {Object} exception The exception account this represents. - * @constructor - * @extends {cr.ui.ListItem} - */ - function ProxyExceptionsItem(exception) { - var el = cr.doc.createElement('div'); - el.exception = exception; - ProxyExceptionsItem.decorate(el); - return el; - } - - /** - * Decorates an element as a exception account item. - * @param {!HTMLElement} el The element to decorate. - */ - ProxyExceptionsItem.decorate = function(el) { - el.__proto__ = ProxyExceptionsItem.prototype; - el.decorate(); - }; - - ProxyExceptionsItem.prototype = { - __proto__: ListItem.prototype, - - /** @override */ - decorate: function() { - ListItem.prototype.decorate.call(this); - this.className = 'exception-list-item'; - - var labelException = this.ownerDocument.createElement('span'); - labelException.className = ''; - labelException.textContent = this.exception; - this.appendChild(labelException); - } - }; - - return { - ProxyExceptions: ProxyExceptions - }; -});
diff --git a/chrome/browser/resources/options/chromeos/quick_unlock_configure_overlay.css b/chrome/browser/resources/options/chromeos/quick_unlock_configure_overlay.css deleted file mode 100644 index e0fd911..0000000 --- a/chrome/browser/resources/options/chromeos/quick_unlock_configure_overlay.css +++ /dev/null
@@ -1,7 +0,0 @@ -/* Copyright 2016 The Chromium Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. */ - -#quick-unlock-configure-overlay { - width: 480px; -}
diff --git a/chrome/browser/resources/options/chromeos/quick_unlock_configure_overlay.html b/chrome/browser/resources/options/chromeos/quick_unlock_configure_overlay.html deleted file mode 100644 index f0c54b1..0000000 --- a/chrome/browser/resources/options/chromeos/quick_unlock_configure_overlay.html +++ /dev/null
@@ -1,15 +0,0 @@ -<div id="quick-unlock-configure-overlay" class="page" hidden> - <div class="close-button"></div> - <h1>$i18n{lockScreenTitle}</h1> - <settings-lock-screen prefs="{{prefs}}" tabindex=0> - </settings-lock-screen> - - <div class="action-area"> - <div class="button-strip"> - <paper-button class="action-button" - id="screen-lock-done"> - $i18n{done} - </paper-button> - </div> - </div> -</div>
diff --git a/chrome/browser/resources/options/chromeos/quick_unlock_configure_overlay.js b/chrome/browser/resources/options/chromeos/quick_unlock_configure_overlay.js deleted file mode 100644 index 7a5f37e..0000000 --- a/chrome/browser/resources/options/chromeos/quick_unlock_configure_overlay.js +++ /dev/null
@@ -1,101 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -cr.define('options', function() { - var Page = cr.ui.pageManager.Page; - var PageManager = cr.ui.pageManager.PageManager; - - /** - * QuickUnlockConfigureOverlay class - * Dialog that allows users to configure screen lock. - * @constructor - * @extends {cr.ui.pageManager.Page} - */ - function QuickUnlockConfigureOverlay() { - Page.call(this, 'quickUnlockConfigureOverlay', - loadTimeData.getString('lockScreenTitle'), - 'quick-unlock-configure-overlay'); - - } - - cr.addSingletonGetter(QuickUnlockConfigureOverlay); - - QuickUnlockConfigureOverlay.prototype = { - __proto__: Page.prototype, - - /** @override */ - initializePage: function() { - Page.prototype.initializePage.call(this); - $('screen-lock-done').onclick = function() { - QuickUnlockConfigureOverlay.dismiss(); - }; - - if (loadTimeData.getBoolean('enablePolymerPreload')) - requestIdleCallback(this.ensurePolymerIsLoaded_.bind(this)); - }, - - /** @override */ - didClosePage: function() { - settings.navigateTo(settings.Route.PEOPLE); - }, - - /** @override */ - didShowPage: function() { - this.ensurePolymerIsLoaded_().then(this.onPolymerLoaded_.bind(this)); - }, - - /** - * @return {!Promise} - * @private - */ - ensurePolymerIsLoaded_: function() { - this.loaded_ = this.loaded_ || new Promise(function(resolve) { - var link = document.createElement('link'); - link.rel = 'import'; - link.href = 'chrome://settings-frame/options_polymer.html'; - link.onload = resolve; - document.head.appendChild(link); - }); - return this.loaded_; - }, - - /** - * Called when polymer has been loaded and the dialog should be displayed. - * @private - */ - onPolymerLoaded_: function() { - settings.navigateTo(settings.Route.LOCK_SCREEN); - var lockScreen = document.querySelector('settings-lock-screen'); - - // On settings the screen lock is part of the lock screen, but on options - // it is already part of the sync page, so hide the lock screen version on - // options. - var screenLockDiv = lockScreen.root.querySelector('#screenLockDiv'); - screenLockDiv.hidden = true; - - // The fingerprint settings and easy unlock on options is always hidden. - var fingerprintDiv = lockScreen.root.querySelector('#fingerprintDiv'); - fingerprintDiv.hidden = true; - var easyUnlockDiv = lockScreen.root.querySelector('#easyUnlock'); - easyUnlockDiv.hidden = true; - - var passwordPrompt = lockScreen.root. - querySelector('settings-password-prompt-dialog'); - passwordPrompt.addEventListener('close', function() { - if (!lockScreen.setModes_) { - QuickUnlockConfigureOverlay.dismiss(); - } - }.bind(this)); - }, - }; - - QuickUnlockConfigureOverlay.dismiss = function() { - PageManager.closeOverlay(); - }; - - // Export - return { - QuickUnlockConfigureOverlay: QuickUnlockConfigureOverlay - }; -});
diff --git a/chrome/browser/resources/options/chromeos/space_critically_low.svg b/chrome/browser/resources/options/chromeos/space_critically_low.svg deleted file mode 100644 index 731db4e..0000000 --- a/chrome/browser/resources/options/chromeos/space_critically_low.svg +++ /dev/null
@@ -1,4 +0,0 @@ -<svg xmlns="http://www.w3.org/2000/svg" width="48px" height="48px" viewBox="0 0 48 48" fill="#DB4437"> - <path d="M0 0h48v48H0z" fill="none"/> - <path d="M2 42h44L24 4 2 42zm24-6h-4v-4h4v4zm0-8h-4v-8h4v8z"/> -</svg>
diff --git a/chrome/browser/resources/options/chromeos/space_low.svg b/chrome/browser/resources/options/chromeos/space_low.svg deleted file mode 100644 index 7a4b985..0000000 --- a/chrome/browser/resources/options/chromeos/space_low.svg +++ /dev/null
@@ -1,4 +0,0 @@ -<svg xmlns="http://www.w3.org/2000/svg" width="48px" height="48px" viewBox="0 0 48 48" fill="#FFB000"> - <path d="M0 0h48v48H0z" fill="none"/> - <path d="M2 42h44L24 4 2 42zm24-6h-4v-4h4v4zm0-8h-4v-8h4v8z"/> -</svg>
diff --git a/chrome/browser/resources/options/chromeos/storage_clear_drive_cache_overlay.css b/chrome/browser/resources/options/chromeos/storage_clear_drive_cache_overlay.css deleted file mode 100644 index 4314e56..0000000 --- a/chrome/browser/resources/options/chromeos/storage_clear_drive_cache_overlay.css +++ /dev/null
@@ -1,11 +0,0 @@ -/* Copyright 2016 The Chromium Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. */ - -#clear-drive-cache-overlay-page { - max-width: 476px; -} - -#clear-drive-cache-overlay-page p { - line-height: 1.6em; -}
diff --git a/chrome/browser/resources/options/chromeos/storage_clear_drive_cache_overlay.html b/chrome/browser/resources/options/chromeos/storage_clear_drive_cache_overlay.html deleted file mode 100644 index 3ef1c80..0000000 --- a/chrome/browser/resources/options/chromeos/storage_clear_drive_cache_overlay.html +++ /dev/null
@@ -1,13 +0,0 @@ -<div id="clear-drive-cache-overlay-page" class="page" role="dialog" hidden> - <div class="close-button"></div> - <h1>$i18n{storageClearDriveCacheDialogTitle}</h1> - <div class="content-area"> - <div>$i18n{storageClearDriveCacheDescription}</div> - </div> - <div class="action-area button-strip"> - <button id="clear-drive-cache-overlay-cancel-button">$i18n{cancel}</button> - <button id="clear-drive-cache-overlay-delete-button" class="default-button"> - $i18n{storageDeleteAllButtonTitle} - </button> - </div> -</div>
diff --git a/chrome/browser/resources/options/chromeos/storage_clear_drive_cache_overlay.js b/chrome/browser/resources/options/chromeos/storage_clear_drive_cache_overlay.js deleted file mode 100644 index 38c30720..0000000 --- a/chrome/browser/resources/options/chromeos/storage_clear_drive_cache_overlay.js +++ /dev/null
@@ -1,37 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -cr.define('options', function() { - var Page = cr.ui.pageManager.Page; - var PageManager = cr.ui.pageManager.PageManager; - - function StorageClearDriveCacheOverlay() { - Page.call(this, 'storageClearDriveCache', - loadTimeData.getString('storageClearDriveCachePageTabTitle'), - 'clear-drive-cache-overlay-page'); - } - - cr.addSingletonGetter(StorageClearDriveCacheOverlay); - - StorageClearDriveCacheOverlay.prototype = { - __proto__: Page.prototype, - - /** @override */ - initializePage: function() { - Page.prototype.initializePage.call(this); - - $('clear-drive-cache-overlay-delete-button').onclick = function(e) { - chrome.send('clearDriveCache'); - PageManager.closeOverlay(); - }; - $('clear-drive-cache-overlay-cancel-button').onclick = function(e) { - PageManager.closeOverlay(); - }; - }, - }; - - return { - StorageClearDriveCacheOverlay: StorageClearDriveCacheOverlay - }; -});
diff --git a/chrome/browser/resources/options/chromeos/storage_manager.css b/chrome/browser/resources/options/chromeos/storage_manager.css deleted file mode 100644 index 98712ab..0000000 --- a/chrome/browser/resources/options/chromeos/storage_manager.css +++ /dev/null
@@ -1,119 +0,0 @@ -/* Copyright 2016 The Chromium Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. */ - -#storageManagerPage { - width: 476px; -} - -#storageManagerPage h1 { - font-size: 125%; /* go to 15px from 12px */ - padding: 15px 20px 14px; -} - -#storageManagerPage .content-area { - padding: 0 20px; -} - -.storage-manager-section { - margin: 0; -} - -.storage-manager-item, -.storage-manager-subitem { - align-items: baseline; - display: flex; - justify-content: space-between; -} - -.storage-manager-item { - color: black; - margin: 18px 0; -} - -.storage-manager-item .storage-manager-item-label { - font-size: 125%; /* go to 15px from 12px */ -} - -.storage-manager-subitem { - -webkit-padding-start: 20px; - margin: 14px 0; -} - -.storage-manager-subitem .storage-manager-item-size { - color: rgba(0, 0, 0, 0.54); -} - -#storage-manager-section-capacity { - margin-bottom: 23px; -} - -#storage-manager-section-capacity .storage-manager-item { - margin-bottom: 24px; - margin-top: 18px; -} - -#storage-manager-section-in-use { - margin-bottom: 30px; -} - -#storage-manager-section-available { - margin-bottom: 18px; -} - -.critically-low-space #storage-manager-message-critically-low-space, -.low-space #storage-manager-message-low-space { - display: block; -} - -.storage-manager-message-area { - background-color: rgb(245, 245, 245); - display: none; - margin-bottom: 4px; - padding: 22px 20px 8px; -} - -.storage-manager-message-area img { - height: 20px; - width: 20px; -} - -.storage-manager-message-title { - align-items: center; - display: flex; -} - -.storage-manager-message-title span { - color: black; - font-size: 125%; /* go to 15px from 12px */ - margin: 0 10px; -} - -.storage-manager-message-area p { - color: rgb(90, 90, 90); -} - -#storage-bar-progress { - -webkit-appearance: none; - display: block; - height: 4px; - width: 100%; -} - -#storage-bar-progress::-webkit-progress-bar { - background-color: rgb(224, 224, 226); - border-radius: 2px; -} - -#storage-bar-progress::-webkit-progress-value { - background-color: rgb(66, 133, 244); - border-radius: 2px; -} - -.critically-low-space #storage-bar-progress::-webkit-progress-value { - background-color: rgb(219, 68, 55); -} - -.low-space #storage-bar-progress::-webkit-progress-value { - background-color: rgb(255, 176, 0); -}
diff --git a/chrome/browser/resources/options/chromeos/storage_manager.html b/chrome/browser/resources/options/chromeos/storage_manager.html deleted file mode 100644 index faca73db..0000000 --- a/chrome/browser/resources/options/chromeos/storage_manager.html +++ /dev/null
@@ -1,106 +0,0 @@ -<div id="storageManagerPage" class="page" hidden> - <div class="close-button"></div> - <h1>$i18n{storageManagerPage}</h1> - - <div id="storage-manager-message-low-space" - class="storage-manager-message-area"> - <div class="storage-manager-message-title"> - <img src="space_low.svg"></img> - <span>$i18n{storageLowMessageTitle}</span> - </div> - <p>$i18n{storageLowMessageLine1}</p> - <p>$i18n{storageLowMessageLine2}</p> - </div> - <div id="storage-manager-message-critically-low-space" - class="storage-manager-message-area"> - <div class="storage-manager-message-title"> - <img src="space_critically_low.svg"></img> - <span>$i18n{storageCriticallyLowMessageTitle}</span> - </div> - <p>$i18n{storageCriticallyLowMessageLine1}</p> - <p>$i18n{storageCriticallyLowMessageLine2}</p> - </div> - - <div class="content-area"> - <div id="storage-manager-section-capacity" class="storage-manager-section"> - <div class="storage-manager-item"> - <span class="storage-manager-item-label"> - $i18n{storageItemLabelCapacity} - </span> - <span id="storage-manager-size-capacity" - class="storage-manager-item-size"></span> - </div> - <progress id="storage-bar-progress"></progress> - </div> - <div id="storage-manager-section-in-use" class="storage-manager-section"> - <div class="storage-manager-item"> - <span class="storage-manager-item-label"> - $i18n{storageItemLabelInUse} - </span> - <span id="storage-manager-size-in-use" - class="storage-manager-item-size"></span> - </div> - <div class="storage-manager-subitem"> - <a is="action-link" id="storage-manager-label-downloads"> - $i18n{storageSubitemLabelDownloads} - </a> - <span id="storage-manager-size-downloads" - class="storage-manager-item-size"> - $i18n{storageSizeCalculating} - </span> - </div> - <div id="storage-manager-item-drive-cache" - class="storage-manager-subitem" hidden> - <a is="action-link" id="storage-manager-label-drive-cache"> - $i18n{storageSubitemLabelDriveCache} - </a> - <span id="storage-manager-size-drive-cache" - class="storage-manager-item-size"> - $i18n{storageSizeCalculating} - </span> - </div> - <div class="storage-manager-subitem"> - <a is="action-link" id="storage-manager-label-browsing-data"> - $i18n{storageSubitemLabelBrowsingData} - </a> - <span id="storage-manager-size-browsing-data" - class="storage-manager-item-size"> - $i18n{storageSizeCalculating} - </span> - </div> - <div id="storage-manager-item-arc" - class="storage-manager-subitem" hidden> - <a is="action-link" id="storage-manager-label-arc"> - $i18n{storageSubitemLabelArc} - </a> - <span id="storage-manager-size-arc" class="storage-manager-item-size"> - $i18n{storageSizeCalculating} - </span> - </div> - <div class="storage-manager-subitem"> - <a is="action-link" id="storage-manager-label-other-users"> - $i18n{storageSubitemLabelOtherUsers} - </a> - <span id="storage-manager-size-other-users" - class="storage-manager-item-size"> - $i18n{storageSizeCalculating} - </span> - </div> - </div> - <div id="storage-manager-section-available" class="storage-manager-section"> - <div class="storage-manager-item"> - <span class="storage-manager-item-label"> - $i18n{storageItemLabelAvailable} - </span> - <span id="storage-manager-size-available" - class="storage-manager-item-size"></span> - </div> - </div> - </div> - - <div class="action-area"> - <div class="button-strip"> - <button id="storage-confirm" class="default-button">$i18n{done}</button> - </div> - </div> -</div>
diff --git a/chrome/browser/resources/options/chromeos/storage_manager.js b/chrome/browser/resources/options/chromeos/storage_manager.js deleted file mode 100644 index eff5d0b1..0000000 --- a/chrome/browser/resources/options/chromeos/storage_manager.js +++ /dev/null
@@ -1,223 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -/** - * Enumeration for device state about remaining space. - * These values must be kept in sync with - * StorageManagerHandler::StorageSpaceState in C++ code. - * @enum {number} - * @const - */ -options.StorageSpaceState = { - STORAGE_SPACE_NORMAL: 0, - STORAGE_SPACE_LOW: 1, - STORAGE_SPACE_CRITICALLY_LOW: 2 -}; - -/** - * @typedef {{ - * totalSize: string, - * availableSize: string, - * usedSize: string, - * usedRatio: number, - * spaceState: options.StorageSpaceState, - * }} - */ -options.StorageSizeStat; - -cr.define('options', function() { - var Page = cr.ui.pageManager.Page; - var PageManager = cr.ui.pageManager.PageManager; - - function StorageManager() { - Page.call(this, 'storage', - loadTimeData.getString('storageManagerPageTabTitle'), - 'storageManagerPage'); - } - - cr.addSingletonGetter(StorageManager); - - StorageManager.prototype = { - __proto__: Page.prototype, - - /** - * Timer ID for periodical update. - * @private {number} - */ - updateTimerId_: -1, - - /** @override */ - initializePage: function() { - Page.prototype.initializePage.call(this); - - $('storage-manager-label-downloads').onclick = function() { - chrome.send('openDownloads'); - chrome.send('coreOptionsUserMetricsAction', - ['Options_StorageOpenDownloads']); - }; - $('storage-manager-label-drive-cache').onclick = function() { - PageManager.showPageByName('storageClearDriveCache'); - chrome.send('coreOptionsUserMetricsAction', - ['Options_StorageOpenClearDriveCache']); - }; - $('storage-manager-label-browsing-data').onclick = function() { - PageManager.showPageByName('clearBrowserData'); - chrome.send('coreOptionsUserMetricsAction', - ['Options_StorageOpenClearBrowsingData']); - }; - $('storage-manager-label-arc').onclick = function() { - chrome.send('openArcStorage'); - chrome.send('coreOptionsUserMetricsAction', - ['Options_StorageOpenAndroidStorage']); - }; - $('storage-manager-label-other-users').onclick = function() { - PageManager.showPageByName('accounts'); - chrome.send('coreOptionsUserMetricsAction', - ['Options_StorageOpenAccounts']); - }; - - $('storage-confirm').onclick = function() { - PageManager.closeOverlay(); - }; - }, - - /** @override */ - didShowPage: function() { - // Updating storage information can be expensive (e.g. computing directory - // sizes recursively), so we delay this operation until the page is shown. - chrome.send('updateStorageInfo'); - // We periodically update the storage usage while the overlay is visible. - this.startPeriodicalUpdate_(); - }, - - /** @override */ - didClosePage: function() { - this.stopPeriodicalUpdate_(); - }, - - /** - * Updates the size information (total/used/available) of the internal - * storage. - * @param {!options.StorageSizeStat} sizeStat - * @private - */ - setSizeStat_: function(sizeStat) { - $('storage-manager-size-capacity').textContent = sizeStat.totalSize; - $('storage-manager-size-in-use').textContent = sizeStat.usedSize; - $('storage-manager-size-available').textContent = sizeStat.availableSize; - $('storage-bar-progress').setAttribute('value', sizeStat.usedRatio); - $('storageManagerPage').classList.toggle('low-space', - sizeStat.spaceState == - options.StorageSpaceState.STORAGE_SPACE_LOW); - $('storageManagerPage').classList.toggle('critically-low-space', - sizeStat.spaceState == - options.StorageSpaceState.STORAGE_SPACE_CRITICALLY_LOW); - }, - - /** - * Updates the size Downloads directory. - * @param {string} size Formatted string of the size of Downloads. - * @private - */ - setDownloadsSize_: function(size) { - $('storage-manager-size-downloads').textContent = size; - }, - - /** - * Updates the size of Google Drive offline files. - * @param {string} size Formatted string of the size of Google Drive offline - * files. - * @private - */ - setDriveCacheSize_: function(size) { - assert(!$('storage-manager-item-drive-cache').hidden); - $('storage-manager-size-drive-cache').textContent = size; - }, - - /** - * Updates the size of browsing data. - * @param {string} size Formatted string of the size of browsing data. - * @private - */ - setBrowsingDataSize_: function(size) { - $('storage-manager-size-browsing-data').textContent = size; - }, - - /** - * Updates the size of other users. - * @param {string} size Formatted string of the size of other users. - * @private - */ - setOtherUsersSize_: function(size) { - $('storage-manager-size-other-users').textContent = size; - }, - - /** - * Updates the total size of Android apps and cache. - * @param {string} size Formatted string of the size of Android apps and - * cache. - * @private - */ - setArcSize_: function(size) { - assert(!$('storage-manager-item-arc').hidden); - $('storage-manager-size-arc').textContent = size; - }, - - /** - * Shows the item "Offline files" on the overlay UI. - * @private - */ - showDriveCacheItem_: function() { - $('storage-manager-item-drive-cache').hidden = false; - }, - - /** - * Shows the item "Android apps and cache" on the overlay UI. - * @private - */ - showArcItem_: function() { - $('storage-manager-item-arc').hidden = false; - }, - - /** - * Starts periodical update for storage usage. - * @private - */ - startPeriodicalUpdate_: function() { - // We update the storage usage every 5 seconds. - if (this.updateTimerId_ == -1) { - this.updateTimerId_ = window.setInterval(function() { - chrome.send('updateStorageInfo'); - }, 5000); - } - }, - - /** - * Stops periodical update for storage usage. - * @private - */ - stopPeriodicalUpdate_: function() { - if (this.updateTimerId_ != -1) { - window.clearInterval(this.updateTimerId_); - this.updateTimerId_ = -1; - } - }, - }; - - // Forward public APIs to private implementations. - cr.makePublic(StorageManager, [ - 'setArcSize', - 'setBrowsingDataSize', - 'setDownloadsSize', - 'setDriveCacheSize', - 'setOtherUsersSize', - 'setSizeStat', - 'showArcItem', - 'showDriveCacheItem', - ]); - - return { - StorageManager: StorageManager - }; -});
diff --git a/chrome/browser/resources/options/chromeos/stylus_overlay.css b/chrome/browser/resources/options/chromeos/stylus_overlay.css deleted file mode 100644 index f5ce7ab..0000000 --- a/chrome/browser/resources/options/chromeos/stylus_overlay.css +++ /dev/null
@@ -1,8 +0,0 @@ -/* Copyright 2016 The Chromium Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. */ - -#stylus-find-more-link { - /* Match the normal options spacing. */ - line-height: 25px; -}
diff --git a/chrome/browser/resources/options/chromeos/stylus_overlay.html b/chrome/browser/resources/options/chromeos/stylus_overlay.html deleted file mode 100644 index af93cc6..0000000 --- a/chrome/browser/resources/options/chromeos/stylus_overlay.html +++ /dev/null
@@ -1,48 +0,0 @@ -<div id="stylus-overlay" class="page" hidden> - <div class="close-button"></div> - <h1>$i18n{stylusOverlay}</h1> - <div class="content-area"> - <div class="option-control-table"> - <div class="option-name"> - <div class="checkbox controlled-setting-with-label"> - <label> - <input pref="settings.enable_stylus_tools" type="checkbox" - dialog-pref> - <span>$i18n{stylusEnableStylusTools}</span> - </label> - </div> - <div class="checkbox controlled-setting-with-label"> - <label> - <input id="launch-palette-on-eject-input" - pref="settings.launch_palette_on_eject_event" - type="checkbox" dialog-pref> - <span>$i18n{stylusAutoOpenStylusTools}</span> - </label> - </div> - </div> - <div class="settings-row"> - <div class="controlled-setting-with-label"> - <label> - <span class="option-name">$i18n{stylusNoteTakingApp}</span> - <select id="stylus-note-taking-app-select" class="option-value"> - </select> - </label> - </div> - </div> - </div> - <div class="settings-row"> - <a is="action-link" id='stylus-find-more-link'> - $i18n{stylusFindMoreApps} - </a> - </div> - </div> - - <div class="action-area"> - <div class="button-strip"> - <button id="stylus-cancel" type="reset">$i18n{cancel}</button> - <button id="stylus-confirm" class="default-button" type="submit"> - $i18n{ok} - </button> - </div> - </div> -</div>
diff --git a/chrome/browser/resources/options/chromeos/stylus_overlay.js b/chrome/browser/resources/options/chromeos/stylus_overlay.js deleted file mode 100644 index 9fa277fa..0000000 --- a/chrome/browser/resources/options/chromeos/stylus_overlay.js +++ /dev/null
@@ -1,157 +0,0 @@ -// Copyright (c) 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -cr.define('options', function() { - /** - * Encapsulated handling of the stylus overlay. - * @constructor - * @extends {options.SettingsDialog} - */ - function StylusOverlay() { - options.SettingsDialog.call(this, 'stylus-overlay', - loadTimeData.getString('stylusOverlayTabTitle'), - 'stylus-overlay', - assertInstanceof($('stylus-confirm'), HTMLButtonElement), - assertInstanceof($('stylus-cancel'), HTMLButtonElement)); - } - - cr.addSingletonGetter(StylusOverlay); - - StylusOverlay.prototype = { - __proto__: options.SettingsDialog.prototype, - - /** - * True if the "enable stylus tools" pref is set to true. - * @type {boolean} - */ - stylusToolsEnabled_: true, - - /** - * True if the last call to updateNoteTakingApps_() passed at least one - * available note-taking app and indicated that we are not waiting for - * Android to start. - * @type {boolean} - */ - noteTakingAppsAvailable_: false, - - /** - * Note-taking app ID selected by the user, or null if the user didn't - * change the selection. - * @type {?string} - */ - selectedNoteTakingAppId_: null, - - /** @override */ - initializePage: function() { - options.SettingsDialog.prototype.initializePage.call(this); - - // Disable some elements when enable stylus tools pref is false. - Preferences.getInstance().addEventListener('settings.enable_stylus_tools', - function(e) { - this.stylusToolsEnabled_ = e.value.value; - $('launch-palette-on-eject-input').disabled = !e.value.value; - this.updateNoteTakingAppsSelectDisabled_(); - }.bind(this)); - - $('stylus-note-taking-app-select') - .addEventListener( - 'change', this.handleNoteTakingAppSelected_.bind(this)); - - var stylusAppsUrl = "https://play.google.com/store/apps/collection/" + - "promotion_30023cb_stylus_apps"; - $('stylus-find-more-link').onclick = function(event) { - chrome.send('showPlayStoreApps', [stylusAppsUrl]); - }; - }, - - /** @override */ - handleConfirm: function() { - options.SettingsDialog.prototype.handleConfirm.call(this); - - if (this.selectedNoteTakingAppId_) { - chrome.send( - 'setPreferredNoteTakingApp', [this.selectedNoteTakingAppId_]); - this.selectedNoteTakingAppId_ = null; - } - }, - - /** @override */ - handleCancel: function() { - options.SettingsDialog.prototype.handleCancel.call(this); - - var selectOptions = $('stylus-note-taking-app-select').children; - for (var i = 0; i < selectOptions.length; i++) { - selectOptions[i].selected = selectOptions[i].defaultSelected; - } - }, - - /** - * Updates the list of available note-taking apps. Called from C++. - * @param {Array<{name: string, id: string, preferred: boolean}>} - * apps Array of app info structs containing: - * name App name to display to user. - * id Opaque app ID. - * preferred Whether this is the preferred app. - * @param {boolean} waitingForAndroid True if Android is starting. - * @private - */ - updateNoteTakingApps_: function(apps, waitingForAndroid) { - var element = $('stylus-note-taking-app-select'); - - // Clear any existing options and make sure we don't save an old - // selection when "OK" is clicked. - element.textContent = ''; - this.noteTakingAppsAvailable_ = false; - this.selectedNoteTakingAppId_ = null; - - // Disable the menu and use it to display an informative message if - // Android is starting or no note-taking apps are installed. - if (waitingForAndroid) { - element.appendChild(new Option( - loadTimeData.getString('stylusNoteTakingAppWaitingForAndroid'), '', - false, false)); - } else if (apps.length == 0) { - element.appendChild(new Option( - loadTimeData.getString('stylusNoteTakingAppNoneAvailable'), '', - false, false)); - } else { - for (var i = 0; i < apps.length; i++) { - var app = apps[i]; - element.appendChild( - new Option(app.name, app.id, app.preferred, app.preferred)); - } - this.noteTakingAppsAvailable_ = true; - } - - this.updateNoteTakingAppsSelectDisabled_(); - }, - - /** - * Updates the disabled state of the note-taking app select element. - * @private - */ - updateNoteTakingAppsSelectDisabled_: function() { - $('stylus-note-taking-app-select').disabled = - !this.stylusToolsEnabled_ || !this.noteTakingAppsAvailable_; - }, - - /** - * Records the user's selection of a note-taking app so it can be saved when - * the "OK" button is clicked. - * @private - */ - handleNoteTakingAppSelected_: function() { - this.selectedNoteTakingAppId_ = $('stylus-note-taking-app-select').value; - }, - }; - - cr.makePublic(StylusOverlay, [ - 'updateNoteTakingApps', - ]); - - // Export - return { - StylusOverlay: StylusOverlay - }; -});
diff --git a/chrome/browser/resources/options/chromeos/third_party_ime_confirm_overlay.css b/chrome/browser/resources/options/chromeos/third_party_ime_confirm_overlay.css deleted file mode 100644 index 8a0ec40..0000000 --- a/chrome/browser/resources/options/chromeos/third_party_ime_confirm_overlay.css +++ /dev/null
@@ -1,7 +0,0 @@ -/* Copyright 2014 The Chromium Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. */ - -#third-party-ime-confirm-overlay { - width: 500px; -}
diff --git a/chrome/browser/resources/options/chromeos/third_party_ime_confirm_overlay.html b/chrome/browser/resources/options/chromeos/third_party_ime_confirm_overlay.html deleted file mode 100644 index 4664e52..0000000 --- a/chrome/browser/resources/options/chromeos/third_party_ime_confirm_overlay.html +++ /dev/null
@@ -1,21 +0,0 @@ -<div id="third-party-ime-confirm-overlay" class="page" hidden> - <div class="close-button"></div> - <h1>$i18n{thirdPartyImeConfirmOverlay}</h1> - <div class="content-area"> - <span id="third-party-ime-confirm-text"> - $i18n{thirdPartyImeConfirmMessage} - </span> - </div> - <div class="action-area"> - <div class="action-area-right"> - <div class="button-strip"> - <button id="third-party-ime-confirm-cancel"> - $i18n{thirdPartyImeConfirmDisable} - </button> - <button id="third-party-ime-confirm-ok" class="default-button"> - $i18n{thirdPartyImeConfirmEnable} - </button> - </div> - </div> - </div> -</div>
diff --git a/chrome/browser/resources/options/chromeos/third_party_ime_confirm_overlay.js b/chrome/browser/resources/options/chromeos/third_party_ime_confirm_overlay.js deleted file mode 100644 index 1f2d6c3..0000000 --- a/chrome/browser/resources/options/chromeos/third_party_ime_confirm_overlay.js +++ /dev/null
@@ -1,91 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -cr.define('options', function() { - /** @const */ var PageManager = cr.ui.pageManager.PageManager; - /** @const */ var SettingsDialog = options.SettingsDialog; - - /** - * HomePageOverlay class - * Dialog that allows users to set the home page. - * @constructor - * @extends {options.SettingsDialog} - */ - function ThirdPartyImeConfirmOverlay() { - SettingsDialog.call( - this, 'thirdPartyImeConfirm', - loadTimeData.getString('thirdPartyImeConfirmOverlayTabTitle'), - 'third-party-ime-confirm-overlay', - assertInstanceof($('third-party-ime-confirm-ok'), HTMLButtonElement), - assertInstanceof($('third-party-ime-confirm-cancel'), - HTMLButtonElement)); - } - - cr.addSingletonGetter(ThirdPartyImeConfirmOverlay); - - ThirdPartyImeConfirmOverlay.prototype = { - __proto__: SettingsDialog.prototype, - - /** - * Callback to authorize use of an input method. - * @type {Function} - * @private - */ - confirmationCallback_: null, - - /** - * Callback to cancel enabling an input method. - * @type {Function} - * @private - */ - cancellationCallback_: null, - - /** - * Confirms enabling of a third party IME. - */ - handleConfirm: function() { - SettingsDialog.prototype.handleConfirm.call(this); - this.confirmationCallback_(); - }, - - /** - * Resets state of the checkobx. - */ - handleCancel: function() { - SettingsDialog.prototype.handleCancel.call(this); - this.cancellationCallback_(); - }, - - /** - * Displays a confirmation dialog indicating the risk fo enabling - * a third party IME. - * @param {{extension: string, confirm: Function, cancel: Function}} data - * Options for the confirmation dialog. - * @private - */ - showConfirmationDialog_: function(data) { - this.confirmationCallback_ = data.confirm; - this.cancellationCallback_ = data.cancel; - var message = loadTimeData.getStringF('thirdPartyImeConfirmMessage', - data.extension); - $('third-party-ime-confirm-text').textContent = message; - PageManager.showPageByName(this.name, false); - }, - }; - - /** - * Displays a confirmation dialog indicating the risk fo enabling - * a third party IME. - * @param {{extension: string, confirm: Function, cancel: Function}} data - * Options for the confirmation dialog. - */ - ThirdPartyImeConfirmOverlay.showConfirmationDialog = function(data) { - ThirdPartyImeConfirmOverlay.getInstance().showConfirmationDialog_(data); - }; - - // Export - return { - ThirdPartyImeConfirmOverlay: ThirdPartyImeConfirmOverlay - }; -});
diff --git a/chrome/browser/resources/options/chromeos/warning.png b/chrome/browser/resources/options/chromeos/warning.png deleted file mode 100644 index 53713ba3..0000000 --- a/chrome/browser/resources/options/chromeos/warning.png +++ /dev/null Binary files differ
diff --git a/chrome/browser/resources/options/clear_browser_data_history_notice_overlay.html b/chrome/browser/resources/options/clear_browser_data_history_notice_overlay.html deleted file mode 100644 index f77e4b5..0000000 --- a/chrome/browser/resources/options/clear_browser_data_history_notice_overlay.html +++ /dev/null
@@ -1,13 +0,0 @@ -<div id="clear-browser-data-history-notice" class="page" hidden> - <h1>$i18n{clearBrowserDataHistoryNoticeTitle}</h1> - <div class="content-area"> - <p>$i18nRaw{clearBrowserDataHistoryNotice}</p> - </div> - <div class="action-area"> - <div class="button-strip"> - <button id="clear-browser-data-history-notice-ok" class="default-button"> - $i18n{clearBrowserDataHistoryNoticeOk} - </button> - </div> - </div> -</div>
diff --git a/chrome/browser/resources/options/clear_browser_data_history_notice_overlay.js b/chrome/browser/resources/options/clear_browser_data_history_notice_overlay.js deleted file mode 100644 index a96f20f..0000000 --- a/chrome/browser/resources/options/clear_browser_data_history_notice_overlay.js +++ /dev/null
@@ -1,45 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -/** - * @fileoverview A popup that may be shown on top of the Clear Browsing Data - * overlay after the deletion finished. - */ - -cr.define('options', function() { - /** @const */ var Page = cr.ui.pageManager.Page; - /** @const */ var PageManager = cr.ui.pageManager.PageManager; - - /** - * A notice to be shown atop of the Clear Browsing Data overlay after - * the deletion of browsing history, informing the user that other forms - * of browsing history are still available. - * @constructor - * @extends {cr.ui.pageManager.Page} - */ - function ClearBrowserDataHistoryNotice() { - Page.call(this, 'clearBrowserDataHistoryNotice', - loadTimeData.getString('clearBrowserDataOverlayTabTitle'), - 'clear-browser-data-history-notice'); - } - - cr.addSingletonGetter(ClearBrowserDataHistoryNotice); - - ClearBrowserDataHistoryNotice.prototype = { - __proto__: Page.prototype, - - /** @override */ - initializePage: function() { - $('clear-browser-data-history-notice-ok').onclick = function() { - // Close this popup, and the Clear Browsing Data overlay below it. - PageManager.closeOverlay(); - ClearBrowserDataOverlay.dismiss(); - }; - }, - }; - - return { - ClearBrowserDataHistoryNotice: ClearBrowserDataHistoryNotice - }; -});
diff --git a/chrome/browser/resources/options/clear_browser_data_overlay.css b/chrome/browser/resources/options/clear_browser_data_overlay.css deleted file mode 100644 index 555ff4dc..0000000 --- a/chrome/browser/resources/options/clear_browser_data_overlay.css +++ /dev/null
@@ -1,86 +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. */ - -#clear-browser-data-overlay { - width: 500px; -} - -#clear-data-checkboxes { - -webkit-padding-start: 8px; - margin: 5px 0; -} - -#cbd-throbber { - /* This should be changed to align-self: center; when the parent is changed to - * display: flex; */ - position: relative; - top: 5px; - visibility: hidden; -} - -#flash-storage-settings { - padding-top: 5px; -} - -#clear-browser-data-info-banner { - background-color: rgb(249, 237, 184); - border: solid 1px rgb(237, 201, 103); - border-radius: 2px; - font-weight: bold; - margin: 0 20px 11px 17px; - padding: 6px 8px; -} - -.clear-browser-data-counter { - color: #999; -} - -input[type=checkbox] ~ span { - line-height: 1.4em; -} - -.clear-browser-data-counter:not(:empty)::before { - content: '\00a0–\00a0\00a0'; -} - -input[type=checkbox]:not(:checked) ~ span > .clear-browser-data-counter { - display: none; -} - -#clear-browser-data-info-banner:empty { - display: none; -} - -#some-stuff-remains-footer { - display: block; -} - -#some-stuff-remains-footer > p { - -webkit-padding-start: 33px; -} - -#some-stuff-remains-footer button { - padding: 0; -} - -#clear-browser-data-history-footer { - background: url(googleg.svg) left no-repeat; - margin: 0 0 0.8em 0; - min-height: 16px; -} - -#clear-browser-data-general-footer { - background: url(../../../../ui/webui/resources/images/info.svg) left no-repeat; - margin: 0; - min-height: 18px; -} - -html[dir='rtl'] #clear-browser-data-history-footer, -html[dir='rtl'] #clear-browser-data-general-footer { - background-position: right center; -} - -#clear-browser-data-history-notice { - width: 300px; -}
diff --git a/chrome/browser/resources/options/clear_browser_data_overlay.html b/chrome/browser/resources/options/clear_browser_data_overlay.html deleted file mode 100644 index ec5faef..0000000 --- a/chrome/browser/resources/options/clear_browser_data_overlay.html +++ /dev/null
@@ -1,138 +0,0 @@ -<div id="clear-browser-data-overlay" class="page not-resizable" hidden> - <div class="close-button"></div> - <h1>$i18n{clearBrowserDataOverlay}</h1> - <!-- NOTE: Make sure there's not whitespace between <div></div> for - #clear-browser-data-info-banner as it's styled with :empty. --> - <div id="clear-browser-data-info-banner"></div> - <div id="cbd-content-area" class="content-area"> - <span>$i18n{clearBrowserDataLabel}</span> - <select id="clear-browser-data-time-period" - i18n-options="clearBrowserDataTimeList" - pref="browser.clear_data.time_period" - data-type="number"> - </select> - <div id="clear-data-checkboxes"> - <div id="delete-browsing-history-container" class="checkbox"> - <label> - <input id="delete-browsing-history-checkbox" - pref="browser.clear_data.browsing_history" type="checkbox" - aria-controls="delete-browsing-history-counter"> - <span> - <span>$i18n{deleteBrowsingHistoryCheckbox}</span> - <span class="controlled-setting-indicator" - pref="history.deleting_enabled"> - </span> - <span class="clear-browser-data-counter" role="note" - aria-live="polite" id="delete-browsing-history-counter"></span> - </span> - </label> - </div> - <div id="delete-download-history-container" class="checkbox"> - <label> - <input id="delete-download-history-checkbox" - pref="browser.clear_data.download_history" type="checkbox"> - <span>$i18n{deleteDownloadHistoryCheckbox}</span> - <span class="controlled-setting-indicator" - pref="history.deleting_enabled"> - </span> - </label> - </div> - <div id="delete-cookies-container" class="checkbox"> - <label> - <input id="delete-cookies-checkbox" - pref="browser.clear_data.cookies" type="checkbox"> - <span class="clear-plugin-lso-data-enabled"> - $i18n{deleteCookiesFlashCheckbox} - </span> - <span class="clear-plugin-lso-data-disabled"> - $i18n{deleteCookiesCheckbox} - </span> - </label> - </div> - <div id="delete-cache-container" class="checkbox"> - <label> - <input id="delete-cache-checkbox" - pref="browser.clear_data.cache" type="checkbox" - aria-controls="delete-cache-counter"> - <span> - <span>$i18n{deleteCacheCheckbox}</span> - <span class="clear-browser-data-counter" role="note" - aria-live="polite" id="delete-cache-counter"></span> - </span> - </label> - </div> - <div id="delete-passwords-container" class="checkbox"> - <label> - <input id="delete-passwords-checkbox" - pref="browser.clear_data.passwords" type="checkbox" - aria-controls="delete-passwords-counter"> - <span> - <span>$i18n{deletePasswordsCheckbox}</span> - <span class="clear-browser-data-counter" role="note" - aria-live="polite" id="delete-passwords-counter"></span> - </span> - </label> - </div> - <div id="delete-form-data-container" class="checkbox"> - <label> - <input id="delete-form-data-checkbox" - pref="browser.clear_data.form_data" type="checkbox" - aria-controls="delete-form-data-counter"> - <span> - <span>$i18n{deleteFormDataCheckbox}</span> - <span class="clear-browser-data-counter" role="note" - aria-live="polite" id="delete-form-data-counter"></span> - </span> - </label> - </div> - <div id="delete-hosted-apps-data-container" class="checkbox"> - <label> - <input id="delete-hosted-apps-data-checkbox" - pref="browser.clear_data.hosted_apps_data" type="checkbox"> - <span>$i18n{deleteHostedAppsDataCheckbox}</span> - </label> - </div> - <div id="delete-media-licenses-container" class="checkbox"> - <label> - <input id="delete-media-licenses-checkbox" - pref="browser.clear_data.media_licenses" type="checkbox" - aria-controls="delete-media-licenses-counter"> - <span> - <span>$i18n{deleteMediaLicensesCheckbox}</span> - <span class="clear-browser-data-counter" role="note" - aria-live="polite" id="delete-media-licenses-counter"></span> - </span> - </label> - </div> - </div> - <div id="flash-storage-settings" class="flash-plugin-area"> - <a target="_blank" - href="$i18nRaw{flashStorageUrl}">$i18n{flashStorageSettings}</a> - </div> - </div> - <div class="action-area"> - <div class="hbox stretch"> - <a id="clear-browser-data-old-learn-more-link" hidden target="_blank" - href="$i18nRaw{clearBrowsingDataLearnMoreUrl}">$i18n{learnMore}</a> - </div> - <div class="action-area-right"> - <div id="cbd-throbber" class="throbber"></div> - <div class="button-strip"> - <button id="clear-browser-data-dismiss">$i18n{cancel}</button> - <button id="clear-browser-data-commit" class="default-button"> - $i18n{clearBrowserDataCommit} - </button> - </div> - </div> - </div> - <div id="some-stuff-remains-footer" class="gray-bottom-bar"> - <p id="clear-browser-data-history-footer" hidden> - $i18nRaw{clearBrowserDataHistoryFooter} - </p> - <p id="clear-browser-data-general-footer"> - <span><!--This is filled by JavaScript--></span> - <a id="clear-browser-data-footer-learn-more-link" hidden target="_blank" - href="$i18nRaw{clearBrowsingDataLearnMoreUrl}">$i18n{learnMore}</a> - </p> - </div> -</div>
diff --git a/chrome/browser/resources/options/clear_browser_data_overlay.js b/chrome/browser/resources/options/clear_browser_data_overlay.js deleted file mode 100644 index 092353e..0000000 --- a/chrome/browser/resources/options/clear_browser_data_overlay.js +++ /dev/null
@@ -1,341 +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. - -cr.define('options', function() { - var Page = cr.ui.pageManager.Page; - var PageManager = cr.ui.pageManager.PageManager; - - /** - * ClearBrowserDataOverlay class - * Encapsulated handling of the 'Clear Browser Data' overlay page. - * @class - */ - function ClearBrowserDataOverlay() { - Page.call(this, 'clearBrowserData', - loadTimeData.getString('clearBrowserDataOverlayTabTitle'), - 'clear-browser-data-overlay'); - } - - cr.addSingletonGetter(ClearBrowserDataOverlay); - - ClearBrowserDataOverlay.prototype = { - // Inherit ClearBrowserDataOverlay from Page. - __proto__: Page.prototype, - - /** - * Whether deleting history and downloads is allowed. - * @type {boolean} - * @private - */ - allowDeletingHistory_: true, - - /** - * Whether or not clearing browsing data is currently in progress. - * @type {boolean} - * @private - */ - isClearingInProgress_: false, - - /** - * Whether or not the WebUI handler has completed initialization. - * - * Unless this becomes true, it must be assumed that the above flags might - * not contain the authoritative values. - * - * @type {boolean} - * @private - */ - isInitializationComplete_: false, - - /** @override */ - initializePage: function() { - Page.prototype.initializePage.call(this); - - var f = this.updateStateOfControls_.bind(this); - var types = ['browser.clear_data.browsing_history', - 'browser.clear_data.download_history', - 'browser.clear_data.cache', - 'browser.clear_data.cookies', - 'browser.clear_data.passwords', - 'browser.clear_data.form_data', - 'browser.clear_data.hosted_apps_data', - 'browser.clear_data.media_licenses']; - types.forEach(function(type) { - Preferences.getInstance().addEventListener(type, f); - }); - - var checkboxes = document.querySelectorAll( - '#cbd-content-area input[type=checkbox]'); - for (var i = 0; i < checkboxes.length; i++) { - checkboxes[i].onclick = f; - } - - $('clear-browser-data-dismiss').onclick = function(event) { - ClearBrowserDataOverlay.dismiss(); - }; - $('clear-browser-data-commit').onclick = function(event) { - ClearBrowserDataOverlay.setClearing(true); - chrome.send('performClearBrowserData'); - }; - - // For managed profiles, hide the checkboxes controlling whether or not - // browsing and download history should be cleared. Note that this is - // different than just disabling them as a result of enterprise policies. - if (!loadTimeData.getBoolean('showDeleteBrowsingHistoryCheckboxes')) { - $('delete-browsing-history-container').hidden = true; - $('delete-download-history-container').hidden = true; - } - - this.updateStateOfControls_(); - }, - - /** @override */ - didShowPage: function() { - chrome.send('openedClearBrowserData'); - }, - - /** - * Create a footer that explains that some content is not cleared by the - * clear browsing data dialog and warns that the deletion may be synced. - * @param {boolean} simple Whether to use a simple support string. - * @param {boolean} syncing Whether the user uses Sync. - * @param {boolean} showHistoryFooter Whether to show an additional footer - * about other forms of browsing history. - * @private - */ - createFooter_: function(simple, syncing, showHistoryFooter) { - // The localized string is of the form "Saved [content settings] and - // {search engines} will not be cleared and may reflect your browsing - // habits.", or of the form "Some settings that may reflect browsing - // habits |will not be cleared|." if the simplified support string - // experiment is enabled. The following parses out the parts in brackets - // and braces and converts them into buttons whereas the remainders are - // represented as span elements. - var footer = - document.querySelector('#some-stuff-remains-footer p span'); - var footerFragments = - loadTimeData.getString('clearBrowserDataSupportString') - .split(/([|#])/); - - if (simple) { - footerFragments.unshift( - loadTimeData.getString('clearBrowserDataSyncWarning') + - ' ' // Padding between the sync warning and the rest of the footer. - ); - } - - for (var i = 0; i < footerFragments.length;) { - var linkId = ''; - if (i + 2 < footerFragments.length) { - if (footerFragments[i] == '|' && footerFragments[i + 2] == '|') { - linkId = 'open-content-settings-from-clear-browsing-data'; - } else if (footerFragments[i] == '#' && - footerFragments[i + 2] == '#') { - linkId = 'open-search-engines-from-clear-browsing-data'; - } - } - - if (linkId) { - var link = new ActionLink; - link.id = linkId; - link.textContent = footerFragments[i + 1]; - footer.appendChild(link); - i += 3; - } else { - var span = document.createElement('span'); - span.textContent = footerFragments[i]; - if (simple && i == 0) { - span.id = 'clear-browser-data-sync-warning'; - span.hidden = !syncing; - } - footer.appendChild(span); - i += 1; - } - } - - if (!simple) { - $('open-content-settings-from-clear-browsing-data').onclick = - function(event) { - PageManager.showPageByName('content'); - }; - $('open-search-engines-from-clear-browsing-data').onclick = - function(event) { - PageManager.showPageByName('searchEngines'); - }; - } - - $('clear-browser-data-old-learn-more-link').hidden = simple; - $('clear-browser-data-footer-learn-more-link').hidden = !simple; - $('flash-storage-settings').hidden = simple; - $('clear-browser-data-history-footer').hidden = !showHistoryFooter; - }, - - /** - * Shows or hides the sync warning based on whether the user uses Sync. - * @param {boolean} syncing Whether the user uses Sync. - * @param {boolean} showHistoryFooter Whether the user syncs history - * and conditions are met to show an additional history footer. - * @private - */ - updateSyncWarningAndHistoryFooter_: function(syncing, showHistoryFooter) { - $('clear-browser-data-sync-warning').hidden = !syncing; - $('clear-browser-data-history-footer').hidden = !showHistoryFooter; - }, - - /** - * Sets whether or not we are in the process of clearing data. - * @param {boolean} clearing Whether the browsing data is currently being - * cleared. - * @private - */ - setClearing_: function(clearing) { - this.isClearingInProgress_ = clearing; - this.updateStateOfControls_(); - }, - - /** - * Sets whether deleting history and downloads is disallowed by enterprise - * policies. This is called on initialization and in response to a change in - * the corresponding preference. - * @param {boolean} allowed Whether to allow deleting history and downloads. - * @private - */ - setAllowDeletingHistory_: function(allowed) { - this.allowDeletingHistory_ = allowed; - this.updateStateOfControls_(); - }, - - /** - * Called by the WebUI handler to signal that it has finished calling all - * initialization methods. - * @private - */ - markInitializationComplete_: function() { - this.isInitializationComplete_ = true; - this.updateStateOfControls_(); - }, - - /** - * Updates the enabled/disabled/hidden status of all controls on the dialog. - * @private - */ - updateStateOfControls_: function() { - // The commit button is enabled if at least one data type selected to be - // cleared, and if we are not already in the process of clearing. - // To prevent the commit button from being hazardously enabled for a very - // short time before setClearing() is called the first time by the native - // side, also disable the button if |isInitializationComplete_| is false. - var enabled = false; - if (this.isInitializationComplete_ && !this.isClearingInProgress_) { - var checkboxes = document.querySelectorAll( - '#cbd-content-area input[type=checkbox]'); - for (var i = 0; i < checkboxes.length; i++) { - if (checkboxes[i].checked) { - enabled = true; - break; - } - } - } - $('clear-browser-data-commit').disabled = !enabled; - - // The checkboxes for clearing history/downloads are enabled unless they - // are disallowed by policies, or we are in the process of clearing data. - // To prevent flickering, these, and the rest of the controls can safely - // be enabled for a short time before the first call to setClearing(). - var enabled = this.allowDeletingHistory_ && !this.isClearingInProgress_; - $('delete-browsing-history-checkbox').disabled = !enabled; - $('delete-download-history-checkbox').disabled = !enabled; - if (!this.allowDeletingHistory_) { - $('delete-browsing-history-checkbox').checked = false; - $('delete-download-history-checkbox').checked = false; - } - - // Enable everything else unless we are in the process of clearing. - var clearing = this.isClearingInProgress_; - $('delete-cache-checkbox').disabled = clearing; - $('delete-cookies-checkbox').disabled = clearing; - $('delete-passwords-checkbox').disabled = clearing; - $('delete-form-data-checkbox').disabled = clearing; - $('delete-hosted-apps-data-checkbox').disabled = clearing; - $('delete-media-licenses-checkbox').disabled = clearing; - $('clear-browser-data-time-period').disabled = clearing; - $('cbd-throbber').style.visibility = clearing ? 'visible' : 'hidden'; - $('clear-browser-data-dismiss').disabled = clearing; - }, - - /** - * Updates the given data volume counter with a given text. - * @param {string} pref_name Name of the deletion preference of the counter - * to be updated. - * @param {string} text The new text of the counter. - * @private - */ - updateCounter_: function(pref_name, text) { - var counter = document.querySelector( - 'input[pref="' + pref_name + - '"] ~ span > .clear-browser-data-counter'); - counter.textContent = text; - } - }; - - // - // Chrome callbacks - // - ClearBrowserDataOverlay.setAllowDeletingHistory = function(allowed) { - ClearBrowserDataOverlay.getInstance().setAllowDeletingHistory_(allowed); - }; - - ClearBrowserDataOverlay.updateCounter = function(pref_name, text) { - ClearBrowserDataOverlay.getInstance().updateCounter_(pref_name, text); - }; - - ClearBrowserDataOverlay.createFooter = function( - simple, syncing, showHistoryFooter) { - ClearBrowserDataOverlay.getInstance().createFooter_( - simple, syncing, showHistoryFooter); - }; - - ClearBrowserDataOverlay.updateSyncWarningAndHistoryFooter = function( - syncing, showHistoryFooter) { - ClearBrowserDataOverlay.getInstance().updateSyncWarningAndHistoryFooter_( - syncing, showHistoryFooter); - }; - - ClearBrowserDataOverlay.setClearing = function(clearing) { - ClearBrowserDataOverlay.getInstance().setClearing_(clearing); - }; - - ClearBrowserDataOverlay.markInitializationComplete = function() { - ClearBrowserDataOverlay.getInstance().markInitializationComplete_(); - }; - - ClearBrowserDataOverlay.setBannerText = function(text) { - $('clear-browser-data-info-banner').innerText = text; - }; - - ClearBrowserDataOverlay.doneClearing = function(showHistoryNotice) { - // The delay gives the user some feedback that the clearing - // actually worked. Otherwise the dialog just vanishes instantly in most - // cases. - window.setTimeout(function() { - ClearBrowserDataOverlay.setClearing(false); - - if (showHistoryNotice) - PageManager.showPageByName('clearBrowserDataHistoryNotice'); - else - ClearBrowserDataOverlay.dismiss(); - }, 200); - }; - - ClearBrowserDataOverlay.dismiss = function() { - var topmostVisiblePage = PageManager.getTopmostVisiblePage(); - if (topmostVisiblePage && topmostVisiblePage.name == 'clearBrowserData') - PageManager.closeOverlay(); - }; - - // Export - return { - ClearBrowserDataOverlay: ClearBrowserDataOverlay - }; -});
diff --git a/chrome/browser/resources/options/compiled_resources2.gyp b/chrome/browser/resources/options/compiled_resources2.gyp deleted file mode 100644 index 50ff2da5..0000000 --- a/chrome/browser/resources/options/compiled_resources2.gyp +++ /dev/null
@@ -1,101 +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. -{ - 'targets': [ - { - 'target_name': 'options_bundle', - 'variables': { - 'extra_inputs': [ - '<!@(python <(CLOSURE_DIR)/build/get_includes.py options_bundle.js)', - ], - 'script_args': ['--custom_sources', '--custom_includes'], - 'source_files': [ - # Note: this code is deprecated. If you really need to change this - # list for some reason, please also update the copies at: - # ../help/compiled_resources2.gyp:help#source_files - # ../chromeos/compiled_resources2.gyp:*#source_files - '<(DEPTH)/third_party/jstemplate/util.js', - '<(DEPTH)/third_party/jstemplate/jsevalcontext.js', - '<(DEPTH)/third_party/jstemplate/jstemplate.js', - '<(DEPTH)/ui/webui/resources/cr_elements/chromeos/network/cr_onc_types.js', - '<(DEPTH)/ui/webui/resources/js/action_link.js', - '<(DEPTH)/ui/webui/resources/js/cr.js', - '<(DEPTH)/ui/webui/resources/js/cr/event_target.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui/array_data_model.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui/autocomplete_list.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui/bubble.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui/bubble_button.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui/command.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui/controlled_indicator.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui/focus_manager.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui/focus_outline_manager.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui/focus_without_ink.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui/list.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui/list_item.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui/list_selection_controller.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui/list_selection_model.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui/list_single_selection_model.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui/grid.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui/menu.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui/menu_item.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui/overlay.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui/position_util.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui/node_utils.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui/page_manager/page.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui/page_manager/page_manager.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui/repeating_button.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui/touch_handler.js', - '<(DEPTH)/ui/webui/resources/js/cr/ui/tree.js', - '<(DEPTH)/ui/webui/resources/js/event_tracker.js', - '<(DEPTH)/ui/webui/resources/js/icon.js', - '<(DEPTH)/ui/webui/resources/js/load_time_data.js', - '<(DEPTH)/ui/webui/resources/js/parse_html_subset.js', - '<(DEPTH)/ui/webui/resources/js/promise_resolver.js', - '<(DEPTH)/ui/webui/resources/js/util.js', - '../chromeos/keyboard/keyboard_utils.js', - '<(DEPTH)/ui/webui/resources/js/i18n_behavior.js', - '<(DEPTH)/ui/webui/resources/js/web_ui_listener_behavior.js', - '../settings/page_visibility.js', - '../settings/route.js', - '../settings/people_page/easy_unlock_browser_proxy.js', - '../settings/people_page/fingerprint_browser_proxy.js', - '<(DEPTH)/third_party/polymer/v1_0/components-chromium/iron-a11y-keys-behavior/iron-a11y-keys-behavior-extracted.js', - '<(DEPTH)/third_party/polymer/v1_0/components-chromium/iron-selector/iron-selection-extracted.js', - '<(DEPTH)/third_party/polymer/v1_0/components-chromium/iron-selector/iron-selectable-extracted.js', - '<(DEPTH)/third_party/polymer/v1_0/components-chromium/iron-selector/iron-multi-selectable-extracted.js', - '<(DEPTH)/third_party/polymer/v1_0/components-chromium/iron-menu-behavior/iron-menu-behavior-extracted.js', - '<(DEPTH)/third_party/polymer/v1_0/components-chromium/iron-menu-behavior/iron-menubar-behavior-extracted.js', - '<(DEPTH)/ui/webui/resources/cr_elements/cr_profile_avatar_selector/cr_profile_avatar_selector_grid.js', - '<(DEPTH)/ui/webui/resources/cr_elements/cr_profile_avatar_selector/cr_profile_avatar_selector.js', - '../settings/people_page/lock_screen_constants.js', - '<(DEPTH)/third_party/closure_compiler/externs/quick_unlock_private.js', - '../settings/people_page/lock_state_behavior.js', - '../settings/people_page/password_prompt_dialog.js', - '<(DEPTH)/ui/webui/resources/js/assert.js', - '<(DEPTH)/third_party/polymer/v1_0/components-chromium/iron-meta/iron-meta-extracted.js', - '<(DEPTH)/third_party/polymer/v1_0/components-chromium/iron-icon/iron-icon-extracted.js', - '<(DEPTH)/third_party/polymer/v1_0/components-chromium/iron-behaviors/iron-control-state-extracted.js', - '<(DEPTH)/third_party/polymer/v1_0/components-chromium/iron-behaviors/iron-button-state-extracted.js', - '<(DEPTH)/third_party/polymer/v1_0/components-chromium/paper-ripple/paper-ripple-extracted.js', - '<(DEPTH)/third_party/polymer/v1_0/components-chromium/paper-behaviors/paper-ripple-behavior-extracted.js', - '<(DEPTH)/third_party/polymer/v1_0/components-chromium/paper-behaviors/paper-inky-focus-behavior-extracted.js', - '<(DEPTH)/third_party/polymer/v1_0/components-chromium/paper-icon-button/paper-icon-button-extracted.js', - '<(DEPTH)/ui/webui/resources/cr_elements/cr_dialog/cr_dialog.js', - '../settings/people_page/lock_screen.js', - '<(DEPTH)/third_party/closure_compiler/externs/bluetooth.js', - '<(DEPTH)/third_party/closure_compiler/externs/bluetooth_private.js', - '<(DEPTH)/third_party/closure_compiler/externs/management.js', - '<(DEPTH)/third_party/closure_compiler/externs/metrics_private.js', - '<(DEPTH)/third_party/closure_compiler/externs/networking_private.js', - '<(DEPTH)/third_party/closure_compiler/externs/chrome_send.js', - '<(DEPTH)/third_party/closure_compiler/externs/web_animations.js', - '<(DEPTH)/ui/webui/resources/cr_elements/chromeos/network/cr_network_icon_externs.js', - 'options_bundle.js', - ], - }, - 'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'], - }, - ], -}
diff --git a/chrome/browser/resources/options/confirm_dialog.js b/chrome/browser/resources/options/confirm_dialog.js deleted file mode 100644 index c70c338..0000000 --- a/chrome/browser/resources/options/confirm_dialog.js +++ /dev/null
@@ -1,134 +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. - -cr.define('options', function() { - /** @const */ var SettingsDialog = options.SettingsDialog; - - /** - * A dialog that will pop up when the user attempts to set the value of the - * Boolean |pref| to |true|, asking for confirmation. If the user clicks OK, - * the new value is committed to Chrome. If the user clicks Cancel or leaves - * the settings page, the new value is discarded. - * @constructor - * @param {string} name See Page constructor. - * @param {string} title See Page constructor. - * @param {string} pageDivName See Page constructor. - * @param {HTMLButtonElement} okButton The confirmation button element. - * @param {HTMLButtonElement} cancelButton The cancellation button element. - * @param {string} pref The pref that requires confirmation. - * @param {string} metric User metrics identifier. - * @param {string=} opt_confirmedPref A pref used to remember whether the - * user has confirmed the dialog before. This ensures that the user is - * presented with the dialog only once. If left |undefined|, the dialog - * will pop up every time the user attempts to set |pref| to |true|. - * @param {boolean=} opt_confirmValue The value to which changing should - * trigger the confirmation dialog. Defaults to |true| if left - * |undefined|. - * @extends {options.SettingsDialog} - */ - function ConfirmDialog(name, title, pageDivName, okButton, cancelButton, pref, - metric, opt_confirmedPref, opt_confirmValue) { - SettingsDialog.call(this, name, title, pageDivName, okButton, cancelButton); - - /** @protected */ - this.pref = pref; - - /** @protected */ - this.metric = metric; - - /** @private */ - this.confirmedPref_ = opt_confirmedPref; - - /** @private */ - this.confirmed_ = false; - - /** @private */ - this.confirmValue_ = opt_confirmValue === false ? false : true; - } - - ConfirmDialog.prototype = { - // Set up the prototype chain - __proto__: SettingsDialog.prototype, - - /** - * Handle changes to |pref|. Only uncommitted changes are relevant as these - * originate from user and need to be explicitly committed to take effect. - * Pop up the dialog or commit the change, depending on whether confirmation - * is needed. - * @param {Event} event Change event. - * @private - */ - onPrefChanged_: function(event) { - if (!event.value.uncommitted) - return; - - if (event.value.value == this.confirmValue_ && !this.confirmed_) - PageManager.showPageByName(this.name, false); - else - Preferences.getInstance().commitPref(this.pref, this.metric); - }, - - /** - * Handle changes to |confirmedPref_| by caching them. - * @param {Event} event Change event. - * @private - */ - onConfirmedChanged_: function(event) { - this.confirmed_ = event.value.value; - }, - - /** @override */ - initializePage: function() { - SettingsDialog.prototype.initializePage.call(this); - - this.okButton.onclick = this.handleConfirm.bind(this); - this.cancelButton.onclick = this.handleCancel.bind(this); - Preferences.getInstance().addEventListener( - this.pref, this.onPrefChanged_.bind(this)); - if (this.confirmedPref_) { - Preferences.getInstance().addEventListener( - this.confirmedPref_, this.onConfirmedChanged_.bind(this)); - } - }, - - /** - * Handle the confirm button by committing the |pref| change. If - * |confirmedPref_| has been specified, also remember that the dialog has - * been confirmed to avoid bringing it up in the future. - * @override - */ - handleConfirm: function() { - SettingsDialog.prototype.handleConfirm.call(this); - - Preferences.getInstance().commitPref(this.pref, this.metric); - if (this.confirmedPref_) - Preferences.setBooleanPref( - this.confirmedPref_, this.confirmValue_, true); - }, - - /** - * Handle the cancel button by rolling back the |pref| change without it - * ever taking effect. - * @override - */ - handleCancel: function() { - SettingsDialog.prototype.handleCancel.call(this); - Preferences.getInstance().rollbackPref(this.pref); - }, - - /** - * When a user navigates away from a confirm dialog, treat as a cancel. - * @protected - * @override - */ - willHidePage: function() { - if (this.visible) - Preferences.getInstance().rollbackPref(this.pref); - }, - }; - - return { - ConfirmDialog: ConfirmDialog - }; -});
diff --git a/chrome/browser/resources/options/content_settings.css b/chrome/browser/resources/options/content_settings.css deleted file mode 100644 index 6f9a453..0000000 --- a/chrome/browser/resources/options/content_settings.css +++ /dev/null
@@ -1,117 +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. */ - -#content-settings-page { - min-width: 620px; -} - -#content-settings-exceptions-area { - min-width: 540px; -} - -.exception-pattern { - -webkit-box-flex: 1; - -webkit-margin-end: 10px; - -webkit-margin-start: 14px; -} - -.exception-setting { - display: inline-block; - width: 120px; -} - -.settings-list div[role='listitem'][controlled-by='policy'] .exception-setting, -.settings-list div[role='listitem'][controlled-by='extension'] - .exception-setting { - width: calc(120px - 8px); -} - -select.exception-setting { - vertical-align: middle; -} - -.overruled .exception-setting { - width: calc(120px - 24px); -} - -.overruled .overruleable { - text-decoration: line-through; -} - -#exception-column-headers { - -webkit-margin-start: 17px; - display: -webkit-box; - margin-top: 17px; -} - -#exception-column-headers > div { - font-weight: bold; -} - -#exception-pattern-column { - -webkit-box-flex: 1; -} - -.exception-value-column-header { - width: 145px; -} - -.otr-explanation { - font-style: italic; -} - -#content-settings-exceptions-area list { - margin-bottom: 10px; - margin-top: 4px; -} - -#group-indicator { - margin-left: 5px; -} - -div[role='listitem'][controlled-by] { - color: #666; - font-style: italic; - position: relative; -} - -.settings-list div[role='listitem'][controlled-by='policy'], -.settings-list div[role='listitem'][controlled-by='extension'] { - background: rgb(250, 230, 146); - border-bottom: 1px solid rgb(201, 189, 141); - border-top: 0; -} - -.sublabel { - -webkit-margin-start: 2em; -} - -select.media-device-control { - margin: 5px 0; - width: 12em; -} - -select.media-device-control:empty { - display: none; -} - -.exception-setting.media-audio-setting { - width: 6em; -} - -.exception-setting.media-video-setting { - width: 6.5em; -} - -#media-column-header { - display: -webkit-box; -} - -#media-audio-column { - width: 6em; -} - -#media-video-column { - width: 8.5em; -}
diff --git a/chrome/browser/resources/options/content_settings.html b/chrome/browser/resources/options/content_settings.html deleted file mode 100644 index db509948..0000000 --- a/chrome/browser/resources/options/content_settings.html +++ /dev/null
@@ -1,649 +0,0 @@ -<div id="content-settings-page" class="page" hidden> - <div class="close-button"></div> - <h1>$i18n{contentSettingsPage}</h1> - <div class="content-area"> - <!-- Cookie filter tab contents --> - <section> - <h3>$i18n{cookiesTabLabel}</h3> - <div> - <div class="radio controlled-setting-with-label"> - <label> - <input type="radio" name="cookies" value="allow"> - <span> - <span>$i18n{cookiesAllow}</span> - <span class="controlled-setting-indicator" - content-setting="cookies" value="allow"></span> - </span> - </label> - </div> - <div class="radio controlled-setting-with-label"> - <label> - <input type="radio" name="cookies" value="session_only"> - <span> - <span>$i18n{cookiesSessionOnly}</span> - <span class="controlled-setting-indicator" - content-setting="cookies" value="session_only"></span> - </span> - </label> - </div> - <div class="radio controlled-setting-with-label"> - <label> - <input type="radio" name="cookies" value="block"> - <span> - <span>$i18n{cookiesBlock}</span> - <span class="controlled-setting-indicator" - content-setting="cookies" value="block"></span> - </span> - </label> - </div> - <div class="checkbox controlled-setting-with-label"> - <label> - <input pref="profile.block_third_party_cookies" type="checkbox"> - <span> - <span>$i18n{cookiesBlock3rdParty}</span> - <span class="controlled-setting-indicator" - pref="profile.block_third_party_cookies"></span> - </label> - </div> - <div class="settings-row"> - <button class="exceptions-list-button" contentType="cookies"> - $i18n{manageExceptions} - </button> - <button id="show-cookies-button">$i18n{cookiesShowCookies}</button> - </div> - </div> - </section> - <!-- Image filter --> - <section> - <h3>$i18n{imagesTabLabel}</h3> - <div> - <div class="radio controlled-setting-with-label"> - <label> - <input type="radio" name="images" value="allow"> - <span> - <span>$i18n{imagesAllow}</span> - <span class="controlled-setting-indicator" - content-setting="images" value="allow"></span> - </span> - </label> - </div> - <div class="radio controlled-setting-with-label"> - <label> - <input type="radio" name="images" value="block"> - <span> - <span>$i18n{imagesBlock}</span> - <span class="controlled-setting-indicator" - content-setting="images" value="block"></span> - </span> - </label> - </div> - <div class="settings-row"> - <button class="exceptions-list-button" contentType="images"> - $i18n{manageExceptions} - </button> - </div> - </div> - </section> - <!-- JavaScript filter --> - <section> - <h3>$i18n{javascriptTabLabel}</h3> - <div> - <div class="radio controlled-setting-with-label"> - <label> - <input type="radio" name="javascript" value="allow"> - <span> - <span>$i18n{javascriptAllow}</span> - <span class="controlled-setting-indicator" - content-setting="javascript" value="allow"></span> - </span> - </label> - </div> - <div class="radio controlled-setting-with-label"> - <label> - <input type="radio" name="javascript" value="block"> - <span> - <span>$i18n{javascriptBlock}</span> - <span class="controlled-setting-indicator" - content-setting="javascript" value="block"></span> - </span> - </label> - </div> - <div class="settings-row"> - <button class="exceptions-list-button" contentType="javascript"> - $i18n{manageExceptions} - </button> - </div> - </div> - </section> - <!-- Handlers settings --> - <section id="handlers-section"> - <h3>$i18n{handlersTabLabel}</h3> - <div> - <div class="radio"> - <label> - <input type="radio" name="handlers" value="allow" - class="handler-radio"> - <span>$i18n{handlersAllow}</span> - </label> - </div> - <div class="radio"> - <label> - <input type="radio" name="handlers" value="block" - class="handler-radio"> - <span>$i18n{handlersBlock}</span> - </label> - </div> - <div class="settings-row"> - <button id="manage-handlers-button" contentType="handlers"> - $i18n{manageHandlers} - </button> - </div> - </div> - </section> - <!-- Plugins filter --> - <section> - <h3>$i18n{pluginsTabLabel}</h3> - <div> - <div class="radio controlled-setting-with-label"> - <label> - <input id="plugins-allow-radio" type="radio" name="plugins" - value="allow"> - <span> - <span>$i18n{pluginsAllow}</span> - <span class="controlled-setting-indicator" - content-setting="plugins" value="allow"></span> - </span> - </label> - </div> - <div class="radio controlled-setting-with-label"> - <label> - <input type="radio" name="plugins" value="detect_important_content"> - <span> - <span>$i18n{pluginsDetectImportantContent}</span> - <span class="controlled-setting-indicator" - content-setting="plugins" value="detect_important_content"> - </span> - </span> - </label> - </div> - <div class="radio controlled-setting-with-label"> - <label> - <input type="radio" name="plugins" value="block"> - <span> - <span>$i18n{pluginsBlock}</span> - <span class="controlled-setting-indicator" - content-setting="plugins" value="block"></span> - </span> - </label> - </div> - <div class="settings-row"> - <button class="exceptions-list-button" contentType="plugins"> - $i18n{manageExceptions} - </button> - </div> - </div> - </section> - <!-- Pop-ups filter --> - <section> - <h3 class="content-settings-header">$i18n{popupsTabLabel}</h3> - <div> - <div class="radio controlled-setting-with-label"> - <label> - <input type="radio" name="popups" value="allow"> - <span> - <span>$i18n{popupsAllow}</span> - <span class="controlled-setting-indicator" - content-setting="popups" value="allow"></span> - </span> - </label> - </div> - <div class="radio controlled-setting-with-label"> - <label> - <input type="radio" name="popups" value="block"> - <span> - <span>$i18n{popupsBlock}</span> - <span class="controlled-setting-indicator" - content-setting="popups" value="block"></span> - </span> - </label> - </div> - <div class="settings-row"> - <button class="exceptions-list-button" contentType="popups"> - $i18n{manageExceptions} - </button> - </div> - </div> - </section> - <!-- Location filter --> - <section> - <h3>$i18n{locationTabLabel}</h3> - <div> - <div class="radio controlled-setting-with-label"> - <label> - <input type="radio" name="location" value="allow"> - <span> - <span>$i18n{locationAllow}</span> - <span class="controlled-setting-indicator" - content-setting="location" value="allow"></span> - </span> - </label> - </div> - <div class="radio controlled-setting-with-label"> - <label> - <input type="radio" name="location" value="ask"> - <span> - <span>$i18n{locationAsk}</span> - <span class="controlled-setting-indicator" - content-setting="location" value="ask"></span> - </span> - </label> - </div> - <div class="radio controlled-setting-with-label"> - <label> - <input type="radio" name="location" - value="block"> - <span> - <span>$i18n{locationBlock}</span> - <span class="controlled-setting-indicator" - content-setting="location" value="block"></span> - </span> - </label> - </div> -<if expr="enable_google_now"> - <div class="checkbox controlled-setting-with-label" - id="geolocationCheckbox" hidden> - <label> - <input pref="googlegeolocationaccess.enabled" - metric="Options_GoogleGeolocationAccessCheckbox" - type="checkbox"> - <span> - <span>$i18n{googleGeolocationAccessEnable}</span> - <span class="controlled-setting-indicator" - pref="googlegeolocationaccess.enabled"></span> - </span> - </label> - </div> -</if> - <div class="settings-row"> - <button class="exceptions-list-button" contentType="location"> - $i18n{manageExceptions} - </button> - </div> - </div> - </section> - <!-- Notifications filter tab contents --> - <section id="notifications-section"> - <h3>$i18n{notificationsTabLabel}</h3> - <div> - <div class="radio controlled-setting-with-label"> - <label> - <input type="radio" name="notifications" value="allow"> - <span> - <span>$i18n{notificationsAllow}</span> - <span class="controlled-setting-indicator" - content-setting="notifications" value="allow"></span> - </span> - </label> - </div> - <div class="radio controlled-setting-with-label"> - <label> - <input type="radio" name="notifications" value="ask"> - <span> - <span>$i18n{notificationsAsk}</span> - <span class="controlled-setting-indicator" - content-setting="notifications" value="ask"></span> - </span> - </label> - </div> - <div class="radio controlled-setting-with-label"> - <label> - <input type="radio" name="notifications" value="block"> - <span> - <span>$i18n{notificationsBlock}</span> - <span class="controlled-setting-indicator" - content-setting="notifications" value="block"></span> - </span> - </label> - </div> - <div class="settings-row"> - <button class="exceptions-list-button" contentType="notifications"> - $i18n{manageExceptions} - </button> - </div> - </div> - </section> - <!-- Protected Content filter --> - <section guest-visibility="disabled"> - <h3 class="content-settings-header">$i18n{protectedContentTabLabel}</h3> - <div> - <div class="checkbox"> - <label> - <input pref="webkit.webprefs.encrypted_media_enabled" - type="checkbox"> - <span>$i18n{protectedContentEnableCheckbox}</span> - </label> - </div> -<if expr="chromeos or is_win"> - <div class="settings-row"> - <p>$i18n{protectedContentInfo}</p> - </div> - <div class="checkbox"> - <label> - <input pref="settings.privacy.drm_enabled" type="checkbox"> - <span>$i18n{protectedContentEnableIdentifiersCheckbox}</span> - </label> - </div> -</if> -<if expr="chromeos"> - <div class="settings-row"> - <button id="protected-content-exceptions" - class="exceptions-list-button" contentType="protectedContent"> - $i18n{manageExceptions} - </button> - </div> -</if> - </div> - </section> - <!-- Microphone filter --> - <section id="media-stream-mic"> - <h3>$i18n{mediaStreamMicTabLabel}</h3> - <div> - <span id="media-select-mic-label" hidden> - $i18n{mediaSelectMicLabel} - </span> - <select id="media-select-mic" class="weakrtl media-device-control" - aria-labelledby="media-select-mic-label"></select> - <div class="radio controlled-setting-with-label"> - <label> - <input type="radio" name="media-stream-mic" value="ask"> - <span> - <span>$i18n{mediaStreamMicAsk}</span> - <span class="controlled-setting-indicator" - content-setting="media-stream-mic" value="ask"></span> - </span> - </label> - </div> - <div class="radio controlled-setting-with-label"> - <label> - <input type="radio" name="media-stream-mic" value="block"> - <span> - <span>$i18n{mediaStreamMicBlock}</span> - <span class="controlled-setting-indicator" - content-setting="media-stream-mic" value="block"></span> - </span> - </label> - </div> - <div class="settings-row"> - <button class="exceptions-list-button" contentType="media-stream-mic"> - $i18n{manageExceptions} - </button> - </div> - <div id="media-pepper-flash-default-mic" class="pepper-flash-settings"> - <span>$i18n{mediaPepperFlashMicDefaultDivergedLabel}</span> - <a target="_blank" href="$i18nRaw{mediaPepperFlashGlobalPrivacyURL}"> - $i18n{mediaPepperFlashChangeLink} - </a> - </div> - </div> - </section> - <!-- Camera filter --> - <section id="media-stream-camera"> - <h3>$i18n{mediaStreamCameraTabLabel}</h3> - <div> - <span id="media-select-camera-label" hidden> - $i18n{mediaSelectCameraLabel} - </span> - <select id="media-select-camera" class="weakrtl media-device-control" - aria-labelledby="media-select-camera-label"></select> - <div class="radio controlled-setting-with-label"> - <label> - <input type="radio" name="media-stream-camera" value="ask"> - <span> - <span>$i18n{mediaStreamCameraAsk}</span> - <span class="controlled-setting-indicator" - content-setting="media-stream-camera" value="ask"></span> - </span> - </label> - </div> - <div class="radio controlled-setting-with-label"> - <label> - <input type="radio" name="media-stream-camera" value="block"> - <span> - <span>$i18n{mediaStreamCameraBlock}</span> - <span class="controlled-setting-indicator" - content-setting="media-stream-camera" value="block"></span> - </span> - </label> - </div> - <div class="settings-row"> - <button class="exceptions-list-button" - contentType="media-stream-camera"> - $i18n{manageExceptions} - </button> - </div> - <div id="media-pepper-flash-default-camera" - class="pepper-flash-settings"> - <span>$i18n{mediaPepperFlashCameraDefaultDivergedLabel}</span> - <a target="_blank" href="$i18nRaw{mediaPepperFlashGlobalPrivacyURL}"> - $i18n{mediaPepperFlashChangeLink} - </a> - </div> - </div> - </section> - <!-- PPAPI broker --> - <section> - <h3>$i18n{ppapiBrokerTabLabel}</h3> - <div> - <div class="radio"> - <label> - <input type="radio" name="ppapi-broker" value="allow"> - <span> - <span>$i18n{ppapiBrokerAllow}</span> - <span class="controlled-setting-indicator" - content-setting="ppapi-broker" value="allow"></span> - </span> - </label> - </div> - <div class="radio"> - <label> - <input type="radio" name="ppapi-broker" value="ask"> - <span> - <span>$i18n{ppapiBrokerAsk}</span> - <span class="controlled-setting-indicator" - content-setting="ppapi-broker" value="ask"></span> - </span> - </label> - </div> - <div class="radio"> - <label> - <input type="radio" name="ppapi-broker" value="block"> - <span> - <span>$i18n{ppapiBrokerBlock}</span> - <span class="controlled-setting-indicator" - content-setting="ppapi-broker" value="block"></span> - </span> - </label> - </div> - <div class="settings-row"> - <button class="exceptions-list-button" contentType="ppapi-broker"> - $i18n{manageExceptions} - </button> - </div> - </div> - </section> - <!-- Automatic Downloads filter --> - <section> - <h3>$i18n{multipleAutomaticDownloadsTabLabel}</h3> - <div> - <div class="radio controlled-setting-with-label"> - <label> - <input type="radio" name="multiple-automatic-downloads" - value="allow"> - <span> - <span>$i18n{multipleAutomaticDownloadsAllow}</span> - <span class="controlled-setting-indicator" - content-setting="multiple-automatic-downloads" value="allow"> - </span> - </span> - </label> - </div> - <div class="radio controlled-setting-with-label"> - <label> - <input type="radio" name="multiple-automatic-downloads" value="ask"> - <span> - <span>$i18n{multipleAutomaticDownloadsAsk}</span> - <span class="controlled-setting-indicator" - content-setting="multiple-automatic-downloads" value="ask"> - </span> - </span> - </label> - </div> - <div class="radio controlled-setting-with-label"> - <label> - <input type="radio" name="multiple-automatic-downloads" - value="block"> - <span> - <span>$i18n{multipleAutomaticDownloadsBlock}</span> - <span class="controlled-setting-indicator" - content-setting="multiple-automatic-downloads" value="block"> - </span> - </span> - </label> - </div> - <div class="settings-row"> - <button class="exceptions-list-button" - contentType="multiple-automatic-downloads"> - $i18n{manageExceptions} - </button> - </div> - </div> - </section> - <!-- MIDI system exclusive messages filter --> - <section> - <h3>$i18n{midiSysexHeader}</h3> - <div> - <div class="radio"> - <label> - <input type="radio" name="midi-sysex" value="allow"> - <span>$i18n{midiSysExAllow}</span> - </label> - </div> - <div class="radio"> - <label> - <input type="radio" name="midi-sysex" value="ask"> - <span>$i18n{midiSysExAsk}</span> - </label> - </div> - <div class="radio"> - <label> - <input type="radio" name="midi-sysex" value="block"> - <span>$i18n{midiSysExBlock}</span> - </label> - </div> - <div class="settings-row"> - <button class="exceptions-list-button" contentType="midi-sysex"> - $i18n{manageExceptions} - </button> - </div> - </div> - </section> - <!-- Push messaging filter --> - <section id="experimental-push-messaging-settings" hidden="true"> - <h3>$i18n{pushMessagingHeader}</h3> - <div> - <div class="radio"> - <label> - <input type="radio" name="push-messaging" value="allow"> - <span>$i18n{pushMessagingAllow}</span> - </label> - </div> - <div class="radio"> - <label> - <input type="radio" name="push-messaging" value="ask"> - <span>$i18n{pushMessagingAsk}</span> - </label> - </div> - <div class="radio"> - <label> - <input type="radio" name="push-messaging" value="block"> - <span>$i18n{pushMessagingBlock}</span> - </label> - </div> - <div class="settings-row"> - <button class="exceptions-list-button" contentType="push-messaging"> - $i18n{manageExceptions} - </button> - </div> - </div> - </section> - <!-- USB devices --> - <section> - <h3>$i18n{usbDevicesHeader}</h3> - <div> - <div class="settings-row"> - <button class="exceptions-list-button" contentType="usb-devices"> - $i18n{usbDevicesManage} - </button> - </div> - </div> - </section> - <!-- Background sync --> - <section> - <h3>$i18n{backgroundSyncHeader}</h3> - <div> - <div class="radio"> - <label> - <input type="radio" name="background-sync" value="allow"> - <span>$i18n{backgroundSyncAllow}</span> - </label> - </div> - <div class="radio"> - <label> - <input type="radio" name="background-sync" value="block"> - <span>$i18n{backgroundSyncBlock}</span> - </label> - </div> - <div class="settings-row"> - <button class="exceptions-list-button" contentType="background-sync"> - $i18n{manageExceptions} - </button> - </div> - </div> - </section> - <!-- Page zoom levels --> - <section id="page-zoom-levels"> - <h3>$i18n{zoomlevelsHeader}</h3> - <div> - <div class="settings-row"> - <button class="exceptions-list-button" contentType="zoomlevels"> - $i18n{zoomLevelsManage} - </button> - </div> - </div> - </section> - <!-- PDF Plugin filter --> - <section id="pdf-section"> - <h3 class="content-settings-header">$i18n{pdfTabLabel}</h3> - <div> - <div class="checkbox"> - <label> - <input pref="plugins.always_open_pdf_externally" type="checkbox"> - <span> - <span>$i18n{pdfEnable}</span> - <span class="controlled-setting-indicator" - pref="plugins.always_open_pdf_externally"> - </span> - </span> - </label> - </div> - </div> - </section> - </div> - <div class="action-area"> - <div class="button-strip"> - <button id="content-settings-overlay-confirm" class="default-button"> - $i18n{done} - </button> - </div> - </div> -</div>
diff --git a/chrome/browser/resources/options/content_settings.js b/chrome/browser/resources/options/content_settings.js deleted file mode 100644 index edcadafe..0000000 --- a/chrome/browser/resources/options/content_settings.js +++ /dev/null
@@ -1,286 +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. - -cr.exportPath('options'); - -/** - * @typedef {{appId: string, - * appName: (string|undefined), - * embeddingOrigin: (string|undefined), - * origin: string, - * setting: string, - * source: string, - * video: (string|undefined)}} - */ -options.Exception; - -cr.define('options', function() { - /** @const */ var Page = cr.ui.pageManager.Page; - /** @const */ var PageManager = cr.ui.pageManager.PageManager; - - ////////////////////////////////////////////////////////////////////////////// - // ContentSettings class: - - /** - * Encapsulated handling of content settings page. - * @constructor - * @extends {cr.ui.pageManager.Page} - */ - function ContentSettings() { - this.activeNavTab = null; - Page.call(this, 'content', - loadTimeData.getString('contentSettingsPageTabTitle'), - 'content-settings-page'); - } - - cr.addSingletonGetter(ContentSettings); - - ContentSettings.prototype = { - __proto__: Page.prototype, - - /** @override */ - initializePage: function() { - Page.prototype.initializePage.call(this); - - var exceptionsButtons = - this.pageDiv.querySelectorAll('.exceptions-list-button'); - for (var i = 0; i < exceptionsButtons.length; i++) { - exceptionsButtons[i].onclick = function(event) { - var hash = event.currentTarget.getAttribute('contentType'); - PageManager.showPageByName('contentExceptions', true, - {hash: '#' + hash}); - }; - } - - var manageHandlersButton = $('manage-handlers-button'); - if (manageHandlersButton) { - manageHandlersButton.onclick = function(event) { - PageManager.showPageByName('handlers'); - }; - } - - if (cr.isChromeOS) { - // Disable some controls for Guest in Chrome OS. - UIAccountTweaks.applyGuestSessionVisibility(document); - - // Disable some controls for Public session in Chrome OS. - UIAccountTweaks.applyPublicSessionVisibility(document); - } - - // Cookies filter page --------------------------------------------------- - $('show-cookies-button').onclick = function(event) { - chrome.send('coreOptionsUserMetricsAction', ['Options_ShowCookies']); - PageManager.showPageByName('cookies'); - }; - - $('content-settings-overlay-confirm').onclick = - PageManager.closeOverlay.bind(PageManager); - - $('media-pepper-flash-default-mic').hidden = true; - $('media-pepper-flash-default-camera').hidden = true; - $('media-pepper-flash-exceptions-mic').hidden = true; - $('media-pepper-flash-exceptions-camera').hidden = true; - - $('media-select-mic').addEventListener('change', - ContentSettings.setDefaultMicrophone_); - $('media-select-camera').addEventListener('change', - ContentSettings.setDefaultCamera_); - }, - }; - - ContentSettings.updateHandlersEnabledRadios = function(enabled) { - var selector = '#content-settings-page input[type=radio][value=' + - (enabled ? 'allow' : 'block') + '].handler-radio'; - document.querySelector(selector).checked = true; - }; - - /** - * Sets the values for all the content settings radios and labels. - * @param {Object<{managedBy: string, value: string}>} dict A mapping from - * radio groups to the checked value for that group. - */ - ContentSettings.setContentFilterSettingsValue = function(dict) { - for (var group in dict) { - var managedBy = dict[group].managedBy; - var controlledBy = managedBy == 'policy' || managedBy == 'extension' ? - managedBy : null; - document.querySelector('input[type=radio][name=' + group + '][value=' + - dict[group].value + ']').checked = true; - var radios = document.querySelectorAll('input[type=radio][name=' + - group + ']'); - for (var i = 0, len = radios.length; i < len; i++) { - radios[i].disabled = (managedBy != 'default'); - radios[i].controlledBy = controlledBy; - } - var indicators = document.querySelectorAll( - 'span.controlled-setting-indicator[content-setting=' + group + ']'); - if (indicators.length == 0) - continue; - // Create a synthetic pref change event decorated as - // CoreOptionsHandler::CreateValueForPref() does. - var event = new Event(group); - event.value = { - value: dict[group].value, - controlledBy: controlledBy, - }; - for (var i = 0; i < indicators.length; i++) { - indicators[i].handlePrefChange(event); - } - if (controlledBy) - this.getExceptionsList(group, 'normal').setOverruledBy(controlledBy); - } - }; - - /** - * Initializes an exceptions list. - * @param {string} type The content type that we are setting exceptions for. - * @param {Array<options.Exception>} exceptions An array of pairs, where the - * first element of each pair is the filter string, and the second is the - * setting (allow/block). - */ - ContentSettings.setExceptions = function(type, exceptions) { - this.getExceptionsList(type, 'normal').setExceptions(exceptions); - }; - - ContentSettings.setHandlers = function(handlers) { - $('handlers-list').setHandlers(handlers); - }; - - ContentSettings.setIgnoredHandlers = function(ignoredHandlers) { - $('ignored-handlers-list').setHandlers(ignoredHandlers); - }; - - ContentSettings.setOTRExceptions = function(type, otrExceptions) { - var exceptionsList = this.getExceptionsList(type, 'otr'); - // Settings for Guest hides many sections, so check for null first. - if (exceptionsList) { - exceptionsList.parentNode.hidden = false; - exceptionsList.setExceptions(otrExceptions); - } - }; - - /** - * @param {string} type The type of exceptions (e.g. "location") to get. - * @param {string} mode The mode of the desired exceptions list (e.g. otr). - * @return {?options.contentSettings.ExceptionsList} The corresponding - * exceptions list or null. - */ - ContentSettings.getExceptionsList = function(type, mode) { - var exceptionsList = document.querySelector( - 'div[contentType=' + type + '] list[mode=' + mode + ']'); - return !exceptionsList ? null : - assertInstanceof(exceptionsList, - options.contentSettings.ExceptionsList); - }; - - /** - * The browser's response to a request to check the validity of a given URL - * pattern. - * @param {string} type The content type. - * @param {string} mode The browser mode. - * @param {string} pattern The pattern. - * @param {boolean} valid Whether said pattern is valid in the context of - * a content exception setting. - */ - ContentSettings.patternValidityCheckComplete = - function(type, mode, pattern, valid) { - this.getExceptionsList(type, mode).patternValidityCheckComplete(pattern, - valid); - }; - - /** - * Shows/hides the link to the Pepper Flash camera or microphone, - * default or exceptions settings. - * Please note that whether the link is actually showed or not is also - * affected by the style class pepper-flash-settings. - * @param {string} linkType Can be 'default' or 'exceptions'. - * @param {string} contentType Can be 'mic' or 'camera'. - * @param {boolean} show Whether to show (or hide) the link. - */ - ContentSettings.showMediaPepperFlashLink = - function(linkType, contentType, show) { - assert(['default', 'exceptions'].indexOf(linkType) >= 0); - assert(['mic', 'camera'].indexOf(contentType) >= 0); - $('media-pepper-flash-' + linkType + '-' + contentType).hidden = !show; - }; - - /** - * Updates the microphone/camera devices menu with the given entries. - * @param {string} type The device type. - * @param {Array} devices List of available devices. - * @param {string} defaultdevice The unique id of the current default device. - */ - ContentSettings.updateDevicesMenu = function(type, devices, defaultdevice) { - var deviceSelect = ''; - if (type == 'mic') { - deviceSelect = $('media-select-mic'); - } else if (type == 'camera') { - deviceSelect = $('media-select-camera'); - } else { - console.error('Unknown device type for <device select> UI element: ' + - type); - return; - } - - deviceSelect.textContent = ''; - - var deviceCount = devices.length; - var defaultIndex = -1; - for (var i = 0; i < deviceCount; i++) { - var device = devices[i]; - var option = new Option(device.name, device.id); - if (option.value == defaultdevice) - defaultIndex = i; - deviceSelect.appendChild(option); - } - if (defaultIndex >= 0) - deviceSelect.selectedIndex = defaultIndex; - }; - - /** - * Sets the visibility of the microphone/camera devices menu. - * @param {string} type The content settings type name of this device. - * @param {boolean} show Whether to show the menu. - */ - ContentSettings.setDevicesMenuVisibility = function(type, show) { - assert(type == 'media-stream-mic' || type == 'media-stream-camera'); - var deviceSelect = $(type == 'media-stream-mic' ? 'media-select-mic' : - 'media-select-camera'); - deviceSelect.hidden = !show; - }; - - /** - * Enables/disables the protected content exceptions button. - * @param {boolean} enable Whether to enable the button. - */ - ContentSettings.enableProtectedContentExceptions = function(enable) { - var exceptionsButton = $('protected-content-exceptions'); - if (exceptionsButton) - exceptionsButton.disabled = !enable; - }; - - /** - * Set the default microphone device based on the popup selection. - * @private - */ - ContentSettings.setDefaultMicrophone_ = function() { - var deviceSelect = $('media-select-mic'); - chrome.send('setDefaultCaptureDevice', ['mic', deviceSelect.value]); - }; - - /** - * Set the default camera device based on the popup selection. - * @private - */ - ContentSettings.setDefaultCamera_ = function() { - var deviceSelect = $('media-select-camera'); - chrome.send('setDefaultCaptureDevice', ['camera', deviceSelect.value]); - }; - - // Export - return { - ContentSettings: ContentSettings - }; - -});
diff --git a/chrome/browser/resources/options/content_settings_exceptions_area.html b/chrome/browser/resources/options/content_settings_exceptions_area.html deleted file mode 100644 index c6b5efd..0000000 --- a/chrome/browser/resources/options/content_settings_exceptions_area.html +++ /dev/null
@@ -1,155 +0,0 @@ -<div id="content-settings-exceptions-area" class="page" hidden> - <div class="close-button"></div> - <h1></h1> - <div class="content-area"> - <div id="exception-column-headers"> - <div id="exception-pattern-column">$i18n{exceptionPatternHeader}</div> - <div id="exception-behavior-column" class="exception-value-column-header"> - $i18n{exceptionBehaviorHeader} - </div> - <div id="exception-zoom-column" class="exception-value-column-header" - hidden> - $i18n{exceptionZoomHeader} - </div> - <div id="exception-usb-device-column" - class="exception-value-column-header" hidden> - $i18n{exceptionUsbDeviceHeader} - </div> - </div> - <div contentType="cookies"> - <list mode="normal"></list> - <div> - <span class="otr-explanation">$i18n{otrExceptionsExplanation}</span> - <list mode="otr"></list> - </div> - <div class="flash-plugin-area"> - <a href="$i18nRaw{flashStorageUrl}" target="_blank"> - $i18n{flashStorageSettings} - </a> - </div> - </div> - <div contentType="images"> - <list mode="normal"></list> - <div> - <span class="otr-explanation">$i18n{otrExceptionsExplanation}</span> - <list mode="otr"></list> - </div> - </div> - <div contentType="javascript"> - <list mode="normal"></list> - <div> - <span class="otr-explanation">$i18n{otrExceptionsExplanation}</span> - <list mode="otr"></list> - </div> - </div> - <div contentType="plugins"> - <list mode="normal"></list> - <div> - <span class="otr-explanation">$i18n{otrExceptionsExplanation}</span> - <list mode="otr"></list> - </div> - </div> - <div contentType="popups"> - <list mode="normal"></list> - <div> - <span class="otr-explanation">$i18n{otrExceptionsExplanation}</span> - <list mode="otr"></list> - </div> - </div> - <div contentType="location"> - <list mode="normal"></list> - </div> - <div contentType="notifications"> - <list mode="normal"></list> - </div> - <div contentType="protectedContent"> - <list mode="normal"></list> - <div> - <span class="otr-explanation">$i18n{otrExceptionsExplanation}</span> - <list mode="otr"></list> - </div> - </div> - <div contentType="media-stream-mic"> - <list mode="normal"></list> - <div> - <span class="otr-explanation">$i18n{otrExceptionsExplanation}</span> - <list mode="otr"></list> - </div> - <div id="media-pepper-flash-exceptions-mic" class="pepper-flash-settings"> - <span>$i18n{mediaPepperFlashMicExceptionsDivergedLabel}</span> - <a target="_blank" href="$i18nRaw{mediaPepperFlashWebsitePrivacyURL}"> - $i18n{mediaPepperFlashChangeLink} - </a> - </div> - </div> - <div contentType="media-stream-camera"> - <list mode="normal"></list> - <div> - <span class="otr-explanation">$i18n{otrExceptionsExplanation}</span> - <list mode="otr"></list> - </div> - <div id="media-pepper-flash-exceptions-camera" - class="pepper-flash-settings"> - <span>$i18n{mediaPepperFlashCameraExceptionsDivergedLabel}</span> - <a target="_blank" href="$i18nRaw{mediaPepperFlashWebsitePrivacyURL}"> - $i18n{mediaPepperFlashChangeLink} - </a> - </div> - </div> - <div contentType="ppapi-broker"> - <list mode="normal"></list> - <div> - <span class="otr-explanation">$i18n{otrExceptionsExplanation}</span> - <list mode="otr"></list> - </div> - </div> - <div contentType="multiple-automatic-downloads"> - <list mode="normal"></list> - </div> - <div contentType="midi-sysex"> - <list mode="normal"></list> - <div> - <span class="otr-explanation">$i18n{otrExceptionsExplanation}</span> - <list mode="otr"></list> - </div> - </div> - <div contentType="push-messaging"> - <list mode="normal"></list> - <div> - <span class="otr-explanation">$i18n{otrExceptionsExplanation}</span> - <list mode="otr"></list> - </div> - </div> - <div contentType="usb-devices"> - <list mode="normal"></list> - <div> - <span class="otr-explanation">$i18n{otrExceptionsExplanation}</span> - <list mode="otr"></list> - </div> - </div> - <div contentType="background-sync"> - <list mode="normal"></list> - </div> - <div contentType="zoomlevels"> - <list mode="normal"></list> - <div> - <span class="otr-explanation">$i18n{otrExceptionsExplanation}</span> - <list mode="otr"></list> - </div> - </div> - </div> - <div class="action-area"> - <div class="hbox stretch"> - <a target="_blank" - href="$i18nRaw{exceptionsLearnMoreUrl}">$i18n{learnMore}</a> - </div> - <div class="action-area-right"> - <div class="button-strip"> - <button id="content-settings-exceptions-overlay-confirm" - class="default-button"> - $i18n{done} - </button> - </div> - </div> - </div> -</div>
diff --git a/chrome/browser/resources/options/content_settings_exceptions_area.js b/chrome/browser/resources/options/content_settings_exceptions_area.js deleted file mode 100644 index 9043b088..0000000 --- a/chrome/browser/resources/options/content_settings_exceptions_area.js +++ /dev/null
@@ -1,734 +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. - -cr.define('options.contentSettings', function() { - /** @const */ var ControlledSettingIndicator = - options.ControlledSettingIndicator; - /** @const */ var InlineEditableItemList = options.InlineEditableItemList; - /** @const */ var InlineEditableItem = options.InlineEditableItem; - /** @const */ var ArrayDataModel = cr.ui.ArrayDataModel; - - /** - * Returns whether exceptions list for the type is editable. - * - * @param {string} contentType The type of the list. - */ - function isEditableType(contentType) { - // Exceptions of the following lists are not editable for now. - return !(contentType == 'location' || - contentType == 'media-stream-mic' || - contentType == 'media-stream-camera' || - contentType == 'midi-sysex' || - contentType == 'zoomlevels' || - isChosenObjectType(contentType)); - } - - /** - * Returns whether exceptions of this type represent chosen objects. - * - * @param {string} contentType The type of the list. - */ - function isChosenObjectType(contentType) { - return contentType == 'usb-devices'; - } - - /** - * Returns the ID of the column containing values for the given content type. - * - * @param {string} contentType The type of the list. - */ - function valueColumnForContentType(contentType) { - if (contentType == 'usb-devices') - return 'exception-usb-device-column'; - if (contentType == 'zoomlevels') - return 'exception-zoom-column'; - return 'exception-behavior-column'; - } - - /** - * Creates a new exceptions list item. - * - * @param {string} contentType The type of the list. - * @param {string} mode The browser mode, 'otr' or 'normal'. - * @param {Object} exception A dictionary that contains the data of the - * exception. - * @constructor - * @extends {options.InlineEditableItem} - */ - function ExceptionsListItem(contentType, mode, exception) { - var el = cr.doc.createElement('div'); - el.mode = mode; - el.contentType = contentType; - el.dataItem = exception; - el.__proto__ = ExceptionsListItem.prototype; - el.decorate(); - - return el; - } - - ExceptionsListItem.prototype = { - __proto__: InlineEditableItem.prototype, - - /** - * Called when an element is decorated as a list item. - */ - decorate: function() { - InlineEditableItem.prototype.decorate.call(this); - - this.isPlaceholder = !this.pattern; - var patternCell = this.createEditableTextCell(this.pattern); - patternCell.className = 'exception-pattern'; - patternCell.classList.add('weakrtl'); - this.contentElement.appendChild(patternCell); - if (this.pattern) - this.patternLabel = patternCell.querySelector('.static-text'); - var input = patternCell.querySelector('input'); - - // Setting label for display mode. |pattern| will be null for the 'add new - // exception' row. - if (this.pattern) { - var settingLabel = cr.doc.createElement('span'); - settingLabel.textContent = this.settingForDisplay(); - settingLabel.className = 'exception-setting overruleable'; - settingLabel.setAttribute('displaymode', 'static'); - this.contentElement.appendChild(settingLabel); - this.settingLabel = settingLabel; - } - - // Setting select element for edit mode. - var select = cr.doc.createElement('select'); - var optionAllow = cr.doc.createElement('option'); - optionAllow.textContent = loadTimeData.getString('allowException'); - optionAllow.value = 'allow'; - select.appendChild(optionAllow); - - if (this.contentType == 'plugins') { - var optionDetect = cr.doc.createElement('option'); - optionDetect.textContent = loadTimeData.getString('detectException'); - optionDetect.value = 'detect_important_content'; - select.appendChild(optionDetect); - } - - if (this.contentType == 'cookies') { - var optionSession = cr.doc.createElement('option'); - optionSession.textContent = loadTimeData.getString('sessionException'); - optionSession.value = 'session_only'; - select.appendChild(optionSession); - } - - var optionBlock = cr.doc.createElement('option'); - optionBlock.textContent = loadTimeData.getString('blockException'); - optionBlock.value = 'block'; - select.appendChild(optionBlock); - - if (this.isEmbeddingRule()) { - this.patternLabel.classList.add('sublabel'); - this.editable = false; - } - - if (this.setting == 'default') { - // Items that don't have their own settings (parents of 'embedded on' - // items) aren't deletable. - this.deletable = false; - this.editable = false; - } - - if (this.contentType != 'zoomlevels' && - !isChosenObjectType(this.contentType)) { - this.addEditField(select, this.settingLabel); - this.contentElement.appendChild(select); - } - select.className = 'exception-setting'; - select.setAttribute('aria-labelledby', - valueColumnForContentType(this.contentType)); - - if (this.pattern) - select.setAttribute('displaymode', 'edit'); - - if (this.contentType == 'zoomlevels') { - this.deletable = true; - - var zoomLabel = cr.doc.createElement('span'); - zoomLabel.textContent = this.dataItem.zoom; - zoomLabel.className = 'exception-setting'; - zoomLabel.setAttribute('displaymode', 'static'); - this.contentElement.appendChild(zoomLabel); - this.zoomLabel = zoomLabel; - } - - if (isChosenObjectType(this.contentType) && - this.dataItem.object !== undefined) { - this.deletable = true; - - var objectLabel = cr.doc.createElement('span'); - objectLabel.textContent = this.dataItem['objectName']; - objectLabel.className = 'exception-setting'; - objectLabel.setAttribute('displaymode', 'static'); - this.contentElement.appendChild(objectLabel); - this.objectLabel = objectLabel; - } - - // Used to track whether the URL pattern in the input is valid. - // This will be true if the browser process has informed us that the - // current text in the input is valid. Changing the text resets this to - // false, and getting a response from the browser sets it back to true. - // It starts off as false for empty string (new exceptions) or true for - // already-existing exceptions (which we assume are valid). - this.inputValidityKnown = this.pattern; - // This one tracks the actual validity of the pattern in the input. This - // starts off as true so as not to annoy the user when they add a new and - // empty input. - this.inputIsValid = true; - - this.input = input; - this.select = select; - - this.updateEditables(); - this.editable = this.editable && isEditableType(this.contentType); - - // If the source of the content setting exception is not a user - // preference, that source controls the exception and the user cannot edit - // or delete it. - var controlledBy = - this.dataItem.source && this.dataItem.source != 'preference' ? - this.dataItem.source : null; - - if (controlledBy) { - this.setAttribute('controlled-by', controlledBy); - this.deletable = false; - this.editable = false; - } - - if (controlledBy == 'policy' || controlledBy == 'extension') { - this.querySelector('.row-delete-button').hidden = true; - this.appendIndicatorElement(controlledBy); - } - - // If the exception comes from a hosted app, display the name and the - // icon of the app. - if (controlledBy == 'HostedApp') { - this.title = - loadTimeData.getString('setBy') + ' ' + this.dataItem.appName; - var button = this.querySelector('.row-delete-button'); - // Use the host app's favicon (16px, match bigger size). - // See c/b/ui/webui/extensions/extension_icon_source.h - // for a description of the chrome://extension-icon URL. - button.style.backgroundImage = - 'url(\'chrome://extension-icon/' + this.dataItem.appId + '/16/1\')'; - } - - var listItem = this; - // Handle events on the editable nodes. - input.oninput = function(event) { - listItem.inputValidityKnown = false; - chrome.send('checkExceptionPatternValidity', - [listItem.contentType, listItem.mode, input.value]); - }; - - // Listen for edit events. - this.addEventListener('canceledit', this.onEditCancelled_); - this.addEventListener('commitedit', this.onEditCommitted_); - }, - - /** - * Appends an indicator element to the item. Should be called at most once. - * - * @param {string} controlledBy The source that controls the item. - */ - appendIndicatorElement: function(controlledBy) { - var indicator = new ControlledSettingIndicator(); - indicator.setAttribute('content-exception', this.contentType); - // Create a synthetic pref change event decorated as - // CoreOptionsHandler::CreateValueForPref() does. - var event = new Event(this.contentType); - event.value = {controlledBy: controlledBy}; - indicator.handlePrefChange(event); - this.appendChild(indicator); - }, - - isEmbeddingRule: function() { - return this.dataItem.embeddingOrigin && - this.dataItem.embeddingOrigin !== this.dataItem.origin; - }, - - /** - * The pattern (e.g., a URL) for the exception. - * - * @type {string} - */ - get pattern() { - if (!this.isEmbeddingRule()) - return this.dataItem.origin; - - return loadTimeData.getStringF('embeddedOnHost', - this.dataItem.embeddingOrigin); - }, - set pattern(pattern) { - if (!this.editable) - console.error('Tried to change uneditable pattern'); - - this.dataItem.displayPattern = pattern; - }, - - /** - * The setting (allow/block) for the exception. - * - * @type {string} - */ - get setting() { - return this.dataItem.setting; - }, - set setting(setting) { - this.dataItem.setting = setting; - }, - - /** - * Gets a human-readable setting string. - * - * @return {string} The display string. - */ - settingForDisplay: function() { - return this.getDisplayStringForSetting(this.setting); - }, - - /** - * Gets a human-readable display string for setting. - * - * @param {string} setting The setting to be displayed. - * @return {string} The display string. - */ - getDisplayStringForSetting: function(setting) { - if (setting == 'allow') - return loadTimeData.getString('allowException'); - else if (setting == 'block') - return loadTimeData.getString('blockException'); - else if (setting == 'ask') - return loadTimeData.getString('askException'); - else if (setting == 'session_only') - return loadTimeData.getString('sessionException'); - else if (setting == 'detect_important_content') - return loadTimeData.getString('detectException'); - else if (setting == 'default') - return ''; - - console.error('Unknown setting: [' + setting + ']'); - return ''; - }, - - /** - * Update this list item to reflect whether the input is a valid pattern. - * - * @param {boolean} valid Whether said pattern is valid in the context of a - * content exception setting. - */ - setPatternValid: function(valid) { - if (valid || !this.input.value) - this.input.setCustomValidity(''); - else - this.input.setCustomValidity(' '); - this.inputIsValid = valid; - this.inputValidityKnown = true; - }, - - /** - * Set the <input> to its original contents. Used when the user quits - * editing. - */ - resetInput: function() { - this.input.value = this.pattern; - }, - - /** - * Copy the data model values to the editable nodes. - */ - updateEditables: function() { - this.resetInput(); - - var settingOption = - this.select.querySelector('[value=\'' + this.setting + '\']'); - if (settingOption) - settingOption.selected = true; - }, - - /** - * Updates UI to indicate that the exception was overruled by a source. - * - * @param {string} overruledBy The source that overrules the exception. - */ - setOverruledBy: function(overruledBy) { - this.classList.toggle('overruled', !!overruledBy); - this.appendIndicatorElement(overruledBy); - }, - - /** @override */ - get currentInputIsValid() { - return this.inputValidityKnown && this.inputIsValid; - }, - - /** @override */ - get hasBeenEdited() { - var livePattern = this.input.value; - var liveSetting = this.select.value; - return livePattern != this.pattern || liveSetting != this.setting; - }, - - /** - * Called when committing an edit. - * - * @param {Event} e The end event. - * @private - */ - onEditCommitted_: function(e) { - var newPattern = this.input.value; - var newSetting = this.select.value; - - this.finishEdit(newPattern, newSetting); - }, - - /** - * Called when cancelling an edit; resets the control states. - * - * @param {Event} e The cancel event. - * @private - */ - onEditCancelled_: function(e) { - this.updateEditables(); - this.setPatternValid(true); - }, - - /** - * Editing is complete; update the model. - * - * @param {string} newPattern The pattern that the user entered. - * @param {string} newSetting The setting the user chose. - */ - finishEdit: function(newPattern, newSetting) { - this.patternLabel.textContent = newPattern; - this.settingLabel.textContent = this.settingForDisplay(); - var oldPattern = this.pattern; - this.pattern = newPattern; - this.setting = newSetting; - - // TODO(estade): this will need to be updated if geolocation/notifications - // become editable. - if (oldPattern != newPattern) { - chrome.send('removeException', - [this.contentType, this.mode, oldPattern]); - } - - chrome.send('setException', - [this.contentType, this.mode, newPattern, newSetting]); - }, - }; - - /** - * Creates a new list item for the Add New Item row, which doesn't represent - * an actual entry in the exceptions list but allows the user to add new - * exceptions. - * - * @param {string} contentType The type of the list. - * @param {string} mode The browser mode, 'otr' or 'normal'. - * @constructor - * @extends {options.contentSettings.ExceptionsListItem} - */ - function ExceptionsAddRowListItem(contentType, mode) { - var el = cr.doc.createElement('div'); - el.mode = mode; - el.contentType = contentType; - el.dataItem = []; - el.__proto__ = ExceptionsAddRowListItem.prototype; - el.decorate(); - - return el; - } - - ExceptionsAddRowListItem.prototype = { - __proto__: ExceptionsListItem.prototype, - - decorate: function() { - ExceptionsListItem.prototype.decorate.call(this); - - this.input.placeholder = - loadTimeData.getString('addNewExceptionInstructions'); - - // Do we always want a default of allow? - this.setting = 'allow'; - }, - - /** - * Clear the <input> and let the placeholder text show again. - */ - resetInput: function() { - this.input.value = ''; - }, - - /** @override */ - get hasBeenEdited() { - return this.input.value != ''; - }, - - /** - * Editing is complete; update the model. As long as the pattern isn't - * empty, we'll just add it. - * - * @param {string} newPattern The pattern that the user entered. - * @param {string} newSetting The setting the user chose. - */ - finishEdit: function(newPattern, newSetting) { - this.resetInput(); - chrome.send('setException', - [this.contentType, this.mode, newPattern, newSetting]); - }, - }; - - /** - * Creates a new exceptions list. - * - * @constructor - * @extends {options.InlineEditableItemList} - */ - var ExceptionsList = cr.ui.define('list'); - - ExceptionsList.prototype = { - __proto__: InlineEditableItemList.prototype, - - /** - * Called when an element is decorated as a list. - */ - decorate: function() { - InlineEditableItemList.prototype.decorate.call(this); - - this.classList.add('settings-list'); - - for (var parentNode = this.parentNode; parentNode; - parentNode = parentNode.parentNode) { - if (parentNode.hasAttribute('contentType')) { - this.contentType = parentNode.getAttribute('contentType'); - break; - } - } - - if (!this.isEditable()) - this.tabIndex = 0; - - this.mode = this.getAttribute('mode'); - this.autoExpands = true; - this.reset(); - }, - - /** - * Creates an item to go in the list. - * - * @param {Object} entry The element from the data model for this row. - */ - createItem: function(entry) { - if (entry) { - return new ExceptionsListItem(this.contentType, - this.mode, - entry); - } else { - var addRowItem = new ExceptionsAddRowListItem(this.contentType, - this.mode); - addRowItem.deletable = false; - return addRowItem; - } - }, - - /** - * Updates UI to indicate that user exceptions were overruled by a source. - * - * @param {string} overruledBy The source that overrules user exceptions. - */ - setOverruledBy: function(overruledBy) { - for (var index = 0; index < this.dataModel.length; ++index) { - var item = this.getListItemByIndex(index); - if (item.dataItem.source == 'preference') - item.setOverruledBy(overruledBy); - } - }, - - /** - * Sets the exceptions in the js model. - * - * @param {Array<options.Exception>} entries A list of dictionaries of - * values, each dictionary represents an exception. - */ - setExceptions: function(entries) { - var deleteCount = this.dataModel.length; - - if (this.isEditable()) { - // We don't want to remove the Add New Exception row. - deleteCount = deleteCount - 1; - } - - var args = [0, deleteCount]; - args.push.apply(args, entries); - this.dataModel.splice.apply(this.dataModel, args); - }, - - /** - * The browser has finished checking a pattern for validity. Update the list - * item to reflect this. - * - * @param {string} pattern The pattern. - * @param {boolean} valid Whether said pattern is valid in the context of a - * content exception setting. - */ - patternValidityCheckComplete: function(pattern, valid) { - var listItems = this.items; - for (var i = 0; i < listItems.length; i++) { - var listItem = listItems[i]; - // Don't do anything for messages for the item if it is not the intended - // recipient, or if the response is stale (i.e. the input value has - // changed since we sent the request to analyze it). - if (pattern == listItem.input.value) - listItem.setPatternValid(valid); - } - }, - - /** - * Returns whether the rows are editable in this list. - */ - isEditable: function() { - // Exceptions of the following lists are not editable for now. - return isEditableType(this.contentType); - }, - - /** - * Removes all exceptions from the js model. - */ - reset: function() { - if (this.isEditable()) { - // The null creates the Add New Exception row. - this.dataModel = new ArrayDataModel([null]); - } else { - this.dataModel = new ArrayDataModel([]); - } - }, - - /** @override */ - deleteItemAtIndex: function(index) { - var listItem = this.getListItemByIndex(index); - if (!listItem.deletable) - return; - - var dataItem = listItem.dataItem; - var params = [listItem.contentType, - listItem.mode, - dataItem.origin, - dataItem.embeddingOrigin]; - - if (isChosenObjectType(this.contentType)) - params.push(dataItem.object); - - chrome.send('removeException', params); - }, - }; - - var Page = cr.ui.pageManager.Page; - var PageManager = cr.ui.pageManager.PageManager; - - /** - * Encapsulated handling of content settings list subpage. - * - * @constructor - * @extends {cr.ui.pageManager.Page} - */ - function ContentSettingsExceptionsArea() { - Page.call(this, 'contentExceptions', - loadTimeData.getString('contentSettingsPageTabTitle'), - 'content-settings-exceptions-area'); - } - - cr.addSingletonGetter(ContentSettingsExceptionsArea); - - ContentSettingsExceptionsArea.prototype = { - __proto__: Page.prototype, - - /** @override */ - initializePage: function() { - Page.prototype.initializePage.call(this); - - var exceptionsLists = this.pageDiv.querySelectorAll('list'); - for (var i = 0; i < exceptionsLists.length; i++) { - options.contentSettings.ExceptionsList.decorate(exceptionsLists[i]); - } - - ContentSettingsExceptionsArea.hideOTRLists(false); - - // If the user types in the URL without a hash, show just cookies. - this.showList('cookies'); - - $('content-settings-exceptions-overlay-confirm').onclick = - PageManager.closeOverlay.bind(PageManager); - }, - - /** - * Shows one list and hides all others. - * - * @param {string} type The content type. - */ - showList: function(type) { - // Update the title for the type that was shown. - this.title = loadTimeData.getString(type + 'TabTitle'); - - var header = this.pageDiv.querySelector('h1'); - var camelCasedType = type.replace(/-([a-z])/g, function(g) { - return g[1].toUpperCase(); - }); - header.textContent = loadTimeData.getString(camelCasedType + 'Header'); - - var divs = this.pageDiv.querySelectorAll('div[contentType]'); - for (var i = 0; i < divs.length; i++) { - if (divs[i].getAttribute('contentType') == type) - divs[i].hidden = false; - else - divs[i].hidden = true; - } - - var valueColumnId = valueColumnForContentType(type); - var headers = - this.pageDiv.querySelectorAll('div.exception-value-column-header'); - for (var i = 0; i < headers.length; ++i) - headers[i].hidden = (headers[i].id != valueColumnId); - }, - - /** - * Called after the page has been shown. Show the content type for the - * location's hash. - */ - didShowPage: function() { - if (this.hash) - this.showList(this.hash.slice(1)); - }, - }; - - /** - * Called when the last incognito window is closed. - */ - ContentSettingsExceptionsArea.OTRProfileDestroyed = function() { - this.hideOTRLists(true); - }; - - /** - * Hides the incognito exceptions lists and optionally clears them as well. - * @param {boolean} clear Whether to clear the lists. - */ - ContentSettingsExceptionsArea.hideOTRLists = function(clear) { - var otrLists = document.querySelectorAll('list[mode=otr]'); - - for (var i = 0; i < otrLists.length; i++) { - otrLists[i].parentNode.hidden = true; - if (clear) - otrLists[i].reset(); - } - }; - - return { - ExceptionsListItem: ExceptionsListItem, - ExceptionsAddRowListItem: ExceptionsAddRowListItem, - ExceptionsList: ExceptionsList, - ContentSettingsExceptionsArea: ContentSettingsExceptionsArea, - }; -});
diff --git a/chrome/browser/resources/options/content_settings_ui.js b/chrome/browser/resources/options/content_settings_ui.js deleted file mode 100644 index 995b52a..0000000 --- a/chrome/browser/resources/options/content_settings_ui.js +++ /dev/null
@@ -1,66 +0,0 @@ -// Copyright (c) 2011 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. - -cr.define('options', function() { - - ////////////////////////////////////////////////////////////////////////////// - // ContentSettingsRadio class: - - // Define a constructor that uses an input element as its underlying element. - var ContentSettingsRadio = cr.ui.define('input'); - - ContentSettingsRadio.prototype = { - __proto__: HTMLInputElement.prototype, - - /** - * Initialization function for the cr.ui framework. - */ - decorate: function() { - this.type = 'radio'; - var self = this; - - this.addEventListener('change', - function(e) { - chrome.send('setContentFilter', [this.name, this.value]); - }); - }, - }; - - /** - * Whether the content setting is controlled by something else than the user's - * settings (either 'policy' or 'extension'). - */ - cr.defineProperty(ContentSettingsRadio, 'controlledBy', cr.PropertyKind.ATTR); - - ////////////////////////////////////////////////////////////////////////////// - // HandlersEnabledRadio class: - - // Define a constructor that uses an input element as its underlying element. - var HandlersEnabledRadio = cr.ui.define('input'); - - HandlersEnabledRadio.prototype = { - __proto__: HTMLInputElement.prototype, - - /** - * Initialization function for the cr.ui framework. - */ - decorate: function() { - this.type = 'radio'; - var self = this; - - this.addEventListener('change', - function(e) { - chrome.send('setHandlersEnabled', [this.value == 'allow']); - }); - }, - }; - - // Export - return { - ContentSettingsRadio: ContentSettingsRadio, - HandlersEnabledRadio: HandlersEnabledRadio - }; - -}); -
diff --git a/chrome/browser/resources/options/controlled_setting.js b/chrome/browser/resources/options/controlled_setting.js deleted file mode 100644 index 7b38321..0000000 --- a/chrome/browser/resources/options/controlled_setting.js +++ /dev/null
@@ -1,226 +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. - -cr.define('options', function() { - /** @const */ var Preferences = options.Preferences; - - /** - * A controlled setting indicator that can be placed on a setting as an - * indicator that the value is controlled by some external entity such as - * policy or an extension. - * @constructor - * @extends {cr.ui.ControlledIndicator} - */ - var ControlledSettingIndicator = cr.ui.define('span'); - - ControlledSettingIndicator.prototype = { - __proto__: cr.ui.ControlledIndicator.prototype, - - /** - * Decorates the base element to show the proper icon. - */ - decorate: function() { - cr.ui.ControlledIndicator.prototype.decorate.call(this); - - // If there is a pref, track its controlledBy and recommendedValue - // properties in order to be able to bring up the correct bubble. - if (this.pref) { - Preferences.getInstance().addEventListener( - this.pref, this.handlePrefChange.bind(this)); - this.resetHandler = this.clearAssociatedPref_; - } - }, - - /** - * The given handler will be called when the user clicks on the 'reset to - * recommended value' link shown in the indicator bubble. The |this| object - * will be the indicator itself. - * @param {function()} handler The handler to be called. - */ - set resetHandler(handler) { - this.resetHandler_ = handler; - }, - - /** - * Clears the preference associated with this indicator. - * @private - */ - clearAssociatedPref_: function() { - Preferences.clearPref(this.pref, !this.dialogPref); - }, - - /** - * Handle changes to the associated pref by hiding any currently visible - * bubble and updating the controlledBy property. - * @param {Event} event Pref change event. - * @suppress {checkTypes} - * TODO(vitalyp): remove the suppression. |controlledBy| property is defined - * by cr.defineProperty(). Currently null can't be assigned to such - * properties due to implementation of ChromePass.java. See this discussion - * to change nulls to empty string below: - * https://chromiumcodereview.appspot.com/11066015/ - */ - handlePrefChange: function(event) { - PageManager.hideBubble(); - if (event.value.controlledBy) { - if (!this.value || String(event.value.value) == this.value) { - this.controlledBy = event.value.controlledBy; - if (event.value.extension) { - this.extensionId = event.value.extension.id; - this.extensionIcon = event.value.extension.icon; - this.extensionName = event.value.extension.name; - } - } else { - this.controlledBy = null; - } - } else if (event.value.recommendedValue != undefined) { - this.controlledBy = - !this.value || String(event.value.recommendedValue) == this.value ? - 'hasRecommendation' : null; - } else { - this.controlledBy = null; - } - }, - - /** - * Uses the page's PageManager to display an informational bubble. - * @override - */ - showBubble: function(content) { - PageManager.showBubble(content, this.image, this, this.location); - }, - - /** - * Uses the page's PageManager to hide the currently visible bubble, if - * any. - * @override - */ - hideBubble: function() { - PageManager.hideBubble(); - }, - - /** - * Queries the |loadTimeData| singleton for the default bubble text strings. - * @override - */ - getDefaultStrings: function() { - // Construct the bubble text. - if (this.hasAttribute('plural')) { - var defaultStrings = { - 'policy': loadTimeData.getString('controlledSettingsPolicy'), - 'extension': loadTimeData.getString('controlledSettingsExtension'), - 'extensionWithName': - loadTimeData.getString('controlledSettingsExtensionWithName'), - }; - if (cr.isChromeOS) { - defaultStrings.shared = - loadTimeData.getString('controlledSettingsShared'); - } - } else { - var defaultStrings = { - 'policy': loadTimeData.getString('controlledSettingPolicy'), - 'extension': loadTimeData.getString('controlledSettingExtension'), - 'extensionWithName': - loadTimeData.getString('controlledSettingExtensionWithName'), - 'recommended': loadTimeData.getString('controlledSettingRecommended'), - 'hasRecommendation': - loadTimeData.getString('controlledSettingHasRecommendation'), - }; - if (cr.isChromeOS) { - defaultStrings.owner = - loadTimeData.getString('controlledSettingOwner'); - defaultStrings.shared = - loadTimeData.getString('controlledSettingShared'); - } - } - return defaultStrings; - }, - - /** - * Returns the DOM tree for a showing the message |text|. - * @param {string} text to be shown in the bubble. - * @override - */ - createDomTree: function(text) { - var content = document.createElement('div'); - content.classList.add('controlled-setting-bubble-header'); - content.textContent = text; - - if (this.controlledBy == 'hasRecommendation' && this.resetHandler_ && - !this.readOnly) { - var container = document.createElement('div'); - var action = new ActionLink; - action.classList.add('controlled-setting-bubble-action'); - action.textContent = - loadTimeData.getString('controlledSettingFollowRecommendation'); - action.addEventListener('click', this.resetHandler_.bind(this)); - container.appendChild(action); - content.appendChild(container); - } else if (this.controlledBy == 'extension' && this.extensionName) { - var extensionContainer = - $('extension-controlled-settings-bubble-template').cloneNode(true); - // No need for an id anymore, and thus remove to avoid id collision. - extensionContainer.removeAttribute('id'); - extensionContainer.hidden = false; - - var extensionName = extensionContainer.querySelector( - '.controlled-setting-bubble-extension-name'); - extensionName.textContent = this.extensionName; - extensionName.style.backgroundImage = - 'url("' + this.extensionIcon + '")'; - - var manageLink = extensionContainer.querySelector( - '.controlled-setting-bubble-extension-manage-link'); - var extensionId = this.extensionId; - manageLink.onclick = function() { - if (window != window.top) { - uber.invokeMethodOnWindow( - window.top, 'showPage', - {pageId: 'extensions', path: '?id=' + extensionId}); - } else { - window.open('chrome://extensions/?id=' + extensionId); - } - }; - - var disableButton = extensionContainer.querySelector( - '.controlled-setting-bubble-extension-disable-button'); - disableButton.onclick = - function() { chrome.send('disableExtension', [extensionId]); }; - content.appendChild(extensionContainer); - } - return content; - }, - }; - - /** - * The name of the associated preference. - */ - cr.defineProperty(ControlledSettingIndicator, 'pref', cr.PropertyKind.ATTR); - - /** - * Whether this indicator is part of a dialog. If so, changes made to the - * associated preference take effect in the settings UI immediately but are - * only actually committed when the user confirms the dialog. If the user - * cancels the dialog instead, the changes are rolled back in the settings UI - * and never committed. - */ - cr.defineProperty(ControlledSettingIndicator, 'dialogPref', - cr.PropertyKind.BOOL_ATTR); - - /** - * The value of the associated preference that the indicator represents. If - * this is not set, the indicator will be visible whenever any value is - * enforced or recommended. If it is set, the indicator will be visible only - * when the enforced or recommended value matches the value it represents. - * This allows multiple indicators to be created for a set of radio buttons, - * ensuring that only one of them is visible at a time. - */ - cr.defineProperty(ControlledSettingIndicator, 'value', - cr.PropertyKind.ATTR); - - // Export. - return { - ControlledSettingIndicator: ControlledSettingIndicator - }; -});
diff --git a/chrome/browser/resources/options/cookies_list.js b/chrome/browser/resources/options/cookies_list.js deleted file mode 100644 index 5cd0f97..0000000 --- a/chrome/browser/resources/options/cookies_list.js +++ /dev/null
@@ -1,961 +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. - -cr.define('options', function() { - /** @const */ var DeletableItemList = options.DeletableItemList; - /** @const */ var DeletableItem = options.DeletableItem; - /** @const */ var ArrayDataModel = cr.ui.ArrayDataModel; - /** @const */ var ListSingleSelectionModel = cr.ui.ListSingleSelectionModel; - - // This structure maps the various cookie type names from C++ (hence the - // underscores) to arrays of the different types of data each has, along with - // the i18n name for the description of that data type. - /** @const */ var cookieInfo = { - 'cookie': [['name', 'label_cookie_name'], - ['content', 'label_cookie_content'], - ['domain', 'label_cookie_domain'], - ['path', 'label_cookie_path'], - ['sendfor', 'label_cookie_send_for'], - ['accessibleToScript', 'label_cookie_accessible_to_script'], - ['created', 'label_cookie_created'], - ['expires', 'label_cookie_expires']], - 'app_cache': [['manifest', 'label_app_cache_manifest'], - ['size', 'label_local_storage_size'], - ['created', 'label_cookie_created'], - ['accessed', 'label_cookie_last_accessed']], - 'database': [['name', 'label_cookie_name'], - ['desc', 'label_webdb_desc'], - ['size', 'label_local_storage_size'], - ['modified', 'label_local_storage_last_modified']], - 'local_storage': [['origin', 'label_local_storage_origin'], - ['size', 'label_local_storage_size'], - ['modified', 'label_local_storage_last_modified']], - 'indexed_db': [['origin', 'label_indexed_db_origin'], - ['size', 'label_indexed_db_size'], - ['modified', 'label_indexed_db_last_modified']], - 'file_system': [['origin', 'label_file_system_origin'], - ['persistent', 'label_file_system_persistent_usage'], - ['temporary', 'label_file_system_temporary_usage']], - 'channel_id': [['serverId', 'label_channel_id_server_id'], - ['certType', 'label_channel_id_type'], - ['created', 'label_channel_id_created']], - 'service_worker': [['origin', 'label_service_worker_origin'], - ['size', 'label_service_worker_size'], - ['scopes', 'label_service_worker_scopes']], - 'cache_storage': [['origin', 'label_cache_storage_origin'], - ['size', 'label_cache_storage_size'], - ['modified', 'label_cache_storage_last_modified']], - 'flash_lso': [['domain', 'label_cookie_domain']], - 'media_license': [['origin', 'label_media_license_origin'], - ['size', 'label_media_license_size'], - ['modified', 'label_media_license_last_modified']], - }; - - /** - * Returns the item's height, like offsetHeight but such that it works better - * when the page is zoomed. See the similar calculation in @{code cr.ui.List}. - * This version also accounts for the animation done in this file. - * @param {Element} item The item to get the height of. - * @return {number} The height of the item, calculated with zooming in mind. - */ - function getItemHeight(item) { - var height = item.style.height; - // Use the fixed animation target height if set, in case the element is - // currently being animated and we'd get an intermediate height below. - if (height && height.substr(-2) == 'px') - return parseInt(height.substr(0, height.length - 2), 10); - return item.getBoundingClientRect().height; - } - - /** - * Create tree nodes for the objects in the data array, and insert them all - * into the given list using its @{code splice} method at the given index. - * @param {Array<Object>} data The data objects for the nodes to add. - * @param {number} start The index at which to start inserting the nodes. - * @return {Array<options.CookieTreeNode>} An array of CookieTreeNodes added. - */ - function spliceTreeNodes(data, start, list) { - var nodes = data.map(function(x) { return new CookieTreeNode(x); }); - // Insert [start, 0] at the beginning of the array of nodes, making it - // into the arguments we want to pass to @{code list.splice} below. - nodes.splice(0, 0, start, 0); - list.splice.apply(list, nodes); - // Remove the [start, 0] prefix and return the array of nodes. - nodes.splice(0, 2); - return nodes; - } - - /** - * Adds information about an app that protects this data item to the - * |element|. - * @param {Element} element The DOM element the information should be - appended to. - * @param {{id: string, name: string}} appInfo Information about an app. - */ - function addAppInfo(element, appInfo) { - var img = element.ownerDocument.createElement('img'); - img.src = 'chrome://extension-icon/' + appInfo.id + '/16/1'; - element.title = loadTimeData.getString('label_protected_by_apps') + - ' ' + appInfo.name; - img.className = 'protecting-app'; - element.appendChild(img); - } - - var parentLookup = {}; - var lookupRequests = {}; - - /** - * Creates a new list item for sites data. Note that these are created and - * destroyed lazily as they scroll into and out of view, so they must be - * stateless. We cache the expanded item in @{code CookiesList} though, so it - * can keep state. (Mostly just which item is selected.) - * @param {Object} origin Data used to create a cookie list item. - * @param {options.CookiesList} list The list that will contain this item. - * @constructor - * @extends {options.DeletableItem} - */ - function CookieListItem(origin, list) { - var listItem = new DeletableItem(); - listItem.__proto__ = CookieListItem.prototype; - - listItem.origin = origin; - listItem.list = list; - listItem.decorate(); - - // This hooks up updateOrigin() to the list item, makes the top-level - // tree nodes (i.e., origins) register their IDs in parentLookup, and - // causes them to request their children if they have none. Note that we - // have special logic in the setter for the parent property to make sure - // that we can still garbage collect list items when they scroll out of - // view, even though it appears that we keep a direct reference. - if (origin) { - origin.parent = listItem; - origin.updateOrigin(); - } - - return listItem; - } - - CookieListItem.prototype = { - __proto__: DeletableItem.prototype, - - /** @override */ - decorate: function() { - this.siteChild = this.ownerDocument.createElement('div'); - this.siteChild.className = 'cookie-site'; - this.dataChild = this.ownerDocument.createElement('div'); - this.dataChild.className = 'cookie-data'; - this.sizeChild = this.ownerDocument.createElement('div'); - this.sizeChild.className = 'cookie-size'; - this.itemsChild = this.ownerDocument.createElement('div'); - this.itemsChild.className = 'cookie-items'; - this.infoChild = this.ownerDocument.createElement('div'); - this.infoChild.className = 'cookie-details'; - this.infoChild.hidden = true; - - var remove = this.ownerDocument.createElement('button'); - remove.textContent = loadTimeData.getString('remove_cookie'); - remove.onclick = this.removeCookie_.bind(this); - this.infoChild.appendChild(remove); - var content = this.contentElement; - content.appendChild(this.siteChild); - content.appendChild(this.dataChild); - content.appendChild(this.sizeChild); - content.appendChild(this.itemsChild); - this.itemsChild.appendChild(this.infoChild); - if (this.origin && this.origin.data) { - this.siteChild.textContent = this.origin.data.title; - this.siteChild.setAttribute('title', this.origin.data.title); - } - this.itemList_ = []; - }, - - /** @type {boolean} */ - get expanded() { - return this.expanded_; - }, - set expanded(expanded) { - if (this.expanded_ == expanded) - return; - this.expanded_ = expanded; - if (expanded) { - this.classList.add('show-items'); - var oldExpanded = this.list.expandedItem; - this.list.expandedItem = this; - this.updateItems_(); - if (oldExpanded) - oldExpanded.expanded = false; - } else { - if (this.list.expandedItem == this) { - this.list.expandedItem = null; - } - this.style.height = ''; - this.itemsChild.style.height = ''; - this.classList.remove('show-items'); - } - }, - - /** - * The callback for the "remove" button shown when an item is selected. - * Requests that the currently selected cookie be removed. - * @private - */ - removeCookie_: function() { - if (this.selectedIndex_ >= 0) { - var item = this.itemList_[this.selectedIndex_]; - if (item && item.node) - chrome.send('removeCookie', [item.node.pathId]); - } - }, - - /** - * Disable animation within this cookie list item, in preparation for making - * changes that will need to be animated. Makes it possible to measure the - * contents without displaying them, to set animation targets. - * @private - */ - disableAnimation_: function() { - this.itemsHeight_ = getItemHeight(this.itemsChild); - this.classList.add('measure-items'); - }, - - /** - * Enable animation after changing the contents of this cookie list item. - * See @{code disableAnimation_}. - * @private - */ - enableAnimation_: function() { - if (!this.classList.contains('measure-items')) - this.disableAnimation_(); - this.itemsChild.style.height = ''; - // This will force relayout in order to calculate the new heights. - var itemsHeight = getItemHeight(this.itemsChild); - var fixedHeight = getItemHeight(this) + itemsHeight - this.itemsHeight_; - this.itemsChild.style.height = this.itemsHeight_ + 'px'; - // Force relayout before enabling animation, so that if we have - // changed things since the last layout, they will not be animated - // during subsequent layouts. - /** @suppress {suspiciousCode} */ - this.itemsChild.offsetHeight; - this.classList.remove('measure-items'); - this.itemsChild.style.height = itemsHeight + 'px'; - this.style.height = fixedHeight + 'px'; - }, - - /** - * Updates the origin summary to reflect changes in its items. - * Both CookieListItem and CookieTreeNode implement this API. - * This implementation scans the descendants to update the text. - */ - updateOrigin: function() { - var info = { - cookies: 0, - database: false, - localStorage: false, - appCache: false, - indexedDb: false, - fileSystem: false, - channelIDs: 0, - serviceWorker: false, - cacheStorage: false, - mediaLicense: false, - }; - if (this.origin) - this.origin.collectSummaryInfo(info); - - var list = []; - if (info.cookies > 1) - list.push(loadTimeData.getStringF('cookie_plural', info.cookies)); - else if (info.cookies > 0) - list.push(loadTimeData.getString('cookie_singular')); - if (info.database || info.indexedDb) - list.push(loadTimeData.getString('cookie_database_storage')); - if (info.localStorage) - list.push(loadTimeData.getString('cookie_local_storage')); - if (info.appCache) - list.push(loadTimeData.getString('cookie_app_cache')); - if (info.fileSystem) - list.push(loadTimeData.getString('cookie_file_system')); - if (info.channelIDs) - list.push(loadTimeData.getString('cookie_channel_id')); - if (info.serviceWorker) - list.push(loadTimeData.getString('cookie_service_worker')); - if (info.cacheStorage) - list.push(loadTimeData.getString('cookie_cache_storage')); - if (info.flashLSO) - list.push(loadTimeData.getString('cookie_flash_lso')); - if (info.mediaLicense) - list.push(loadTimeData.getString('cookie_media_license')); - - var text = ''; - for (var i = 0; i < list.length; ++i) { - if (text.length > 0) - text += ', ' + list[i]; - else - text = list[i]; - } - this.dataChild.textContent = text; - - var apps = info.appsProtectingThis; - for (var key in apps) { - addAppInfo(this.dataChild, apps[key]); - } - - if (info.quota && info.quota.totalUsage) - this.sizeChild.textContent = info.quota.totalUsage; - - if (this.expanded) - this.updateItems_(); - }, - - /** - * Updates the items section to reflect changes, animating to the new state. - * Removes existing contents and calls @{code CookieTreeNode.createItems}. - * @private - */ - updateItems_: function() { - this.disableAnimation_(); - this.itemsChild.textContent = ''; - this.infoChild.hidden = true; - this.selectedIndex_ = -1; - this.itemList_ = []; - if (this.origin) - this.origin.createItems(this); - this.itemsChild.appendChild(this.infoChild); - this.enableAnimation_(); - }, - - /** - * Append a new cookie node "bubble" to this list item. - * @param {options.CookieTreeNode} node The cookie node to add a bubble for. - * @param {Element} div The DOM element for the bubble itself. - * @return {number} The index the bubble was added at. - */ - appendItem: function(node, div) { - this.itemList_.push({node: node, div: div}); - this.itemsChild.appendChild(div); - return this.itemList_.length - 1; - }, - - /** - * The currently selected cookie node ("cookie bubble") index. - * @type {number} - * @private - */ - selectedIndex_: -1, - - /** - * Get the currently selected cookie node ("cookie bubble") index. - * @type {number} - */ - get selectedIndex() { - return this.selectedIndex_; - }, - - /** - * Set the currently selected cookie node ("cookie bubble") index to - * |itemIndex|, unselecting any previously selected node first. - * @param {number} itemIndex The index to set as the selected index. - */ - set selectedIndex(itemIndex) { - // Get the list index up front before we change anything. - var index = this.list.getIndexOfListItem(this); - // Unselect any previously selected item. - if (this.selectedIndex_ >= 0) { - var item = this.itemList_[this.selectedIndex_]; - if (item && item.div) - item.div.removeAttribute('selected'); - } - // Special case: decrementing -1 wraps around to the end of the list. - if (itemIndex == -2) - itemIndex = this.itemList_.length - 1; - // Check if we're going out of bounds and hide the item details. - if (itemIndex < 0 || itemIndex >= this.itemList_.length) { - this.selectedIndex_ = -1; - this.disableAnimation_(); - this.infoChild.hidden = true; - this.enableAnimation_(); - return; - } - // Set the new selected item and show the item details for it. - this.selectedIndex_ = itemIndex; - this.itemList_[itemIndex].div.setAttribute('selected', ''); - this.disableAnimation_(); - this.itemList_[itemIndex].node.setDetailText(this.infoChild, - this.list.infoNodes); - this.infoChild.hidden = false; - this.enableAnimation_(); - // If we're near the bottom of the list this may cause the list item to go - // beyond the end of the visible area. Fix it after the animation is done. - var list = this.list; - window.setTimeout(function() { list.scrollIndexIntoView(index); }, 150); - }, - }; - - /** - * {@code CookieTreeNode}s mirror the structure of the cookie tree lazily, and - * contain all the actual data used to generate the {@code CookieListItem}s. - * @param {Object} data The data object for this node. - * @constructor - */ - function CookieTreeNode(data) { - this.data = data; - this.children = []; - } - - CookieTreeNode.prototype = { - /** - * Insert the given list of cookie tree nodes at the given index. - * Both CookiesList and CookieTreeNode implement this API. - * @param {Array<Object>} data The data objects for the nodes to add. - * @param {number} start The index at which to start inserting the nodes. - */ - insertAt: function(data, start) { - var nodes = spliceTreeNodes(data, start, this.children); - for (var i = 0; i < nodes.length; i++) - nodes[i].parent = this; - this.updateOrigin(); - }, - - /** - * Remove a cookie tree node from the given index. - * Both CookiesList and CookieTreeNode implement this API. - * - * TODO(dbeam): this method now conflicts with HTMLElement#remove(), which - * is why the param is optional. Rename. - * - * @param {number=} index The index of the tree node to remove. - */ - remove: function(index) { - if (index < this.children.length) { - this.children.splice(index, 1); - this.updateOrigin(); - } - }, - - /** - * Clears all children. - * Both CookiesList and CookieTreeNode implement this API. - * It is used by CookiesList.loadChildren(). - */ - clear: function() { - // We might leave some garbage in parentLookup for removed children. - // But that should be OK because parentLookup is cleared when we - // reload the tree. - this.children = []; - this.updateOrigin(); - }, - - /** - * The counter used by startBatchUpdates() and endBatchUpdates(). - * @type {number} - */ - batchCount_: 0, - - /** - * See cr.ui.List.startBatchUpdates(). - * Both CookiesList (via List) and CookieTreeNode implement this API. - */ - startBatchUpdates: function() { - this.batchCount_++; - }, - - /** - * See cr.ui.List.endBatchUpdates(). - * Both CookiesList (via List) and CookieTreeNode implement this API. - */ - endBatchUpdates: function() { - if (!--this.batchCount_) - this.updateOrigin(); - }, - - /** - * Requests updating the origin summary to reflect changes in this item. - * Both CookieListItem and CookieTreeNode implement this API. - */ - updateOrigin: function() { - if (!this.batchCount_ && this.parent) - this.parent.updateOrigin(); - }, - - /** - * Summarize the information in this node and update @{code info}. - * This will recurse into child nodes to summarize all descendants. - * @param {Object} info The info object from @{code updateOrigin}. - */ - collectSummaryInfo: function(info) { - if (this.children.length > 0) { - for (var i = 0; i < this.children.length; ++i) - this.children[i].collectSummaryInfo(info); - } else if (this.data && !this.data.hasChildren) { - if (this.data.type == 'cookie') { - info.cookies++; - } else if (this.data.type == 'database') { - info.database = true; - } else if (this.data.type == 'local_storage') { - info.localStorage = true; - } else if (this.data.type == 'app_cache') { - info.appCache = true; - } else if (this.data.type == 'indexed_db') { - info.indexedDb = true; - } else if (this.data.type == 'file_system') { - info.fileSystem = true; - } else if (this.data.type == 'quota') { - info.quota = this.data; - } else if (this.data.type == 'channel_id') { - info.channelIDs++; - } else if (this.data.type == 'service_worker') { - info.serviceWorker = true; - } else if (this.data.type == 'cache_storage') { - info.cacheStorage = true; - } else if (this.data.type == 'flash_lso') { - info.flashLSO = true; - } else if (this.data.type == 'media_license') { - info.mediaLicense = true; - } - - var apps = this.data.appsProtectingThis; - if (apps) { - if (!info.appsProtectingThis) - info.appsProtectingThis = {}; - apps.forEach(function(appInfo) { - info.appsProtectingThis[appInfo.id] = appInfo; - }); - } - } - }, - - /** - * Create the cookie "bubbles" for this node, recursing into children - * if there are any. Append the cookie bubbles to @{code item}. - * @param {options.CookieListItem} item The cookie list item to create items - * in. - */ - createItems: function(item) { - if (this.children.length > 0) { - for (var i = 0; i < this.children.length; ++i) - this.children[i].createItems(item); - return; - } - - if (!this.data || this.data.hasChildren) - return; - - var text = ''; - switch (this.data.type) { - case 'cookie': - case 'database': - text = this.data.name; - break; - default: - text = loadTimeData.getString('cookie_' + this.data.type); - } - if (!text) - return; - - var div = item.ownerDocument.createElement('div'); - div.className = 'cookie-item'; - // Help out screen readers and such: this is a clickable thing. - div.setAttribute('role', 'button'); - div.textContent = text; - var apps = this.data.appsProtectingThis; - if (apps) - apps.forEach(addAppInfo.bind(null, div)); - - var index = item.appendItem(this, div); - div.onclick = function() { - item.selectedIndex = (item.selectedIndex == index) ? -1 : index; - }; - }, - - /** - * Set the detail text to be displayed to that of this cookie tree node. - * Uses preallocated DOM elements for each cookie node type from @{code - * infoNodes}, and inserts the appropriate elements to @{code element}. - * @param {Element} element The DOM element to insert elements to. - * @param {Object<{table: Element, info: Object<Element>}>} infoNodes The - * map from cookie node types to maps from cookie attribute names to DOM - * elements to display cookie attribute values, created by - * @see {CookiesList.decorate}. - */ - setDetailText: function(element, infoNodes) { - var table; - if (this.data && !this.data.hasChildren && cookieInfo[this.data.type]) { - var info = cookieInfo[this.data.type]; - var nodes = infoNodes[this.data.type].info; - for (var i = 0; i < info.length; ++i) { - var name = info[i][0]; - if (name != 'id' && this.data[name]) - nodes[name].textContent = this.data[name]; - else - nodes[name].textContent = ''; - } - table = infoNodes[this.data.type].table; - } - - while (element.childNodes.length > 1) - element.removeChild(element.firstChild); - - if (table) - element.insertBefore(table, element.firstChild); - }, - - /** - * The parent of this cookie tree node. - * @type {?(options.CookieTreeNode|options.CookieListItem)} - */ - get parent() { - // See below for an explanation of this special case. - if (typeof this.parent_ == 'number') - return this.list_.getListItemByIndex(this.parent_); - return this.parent_; - }, - set parent(parent) { - if (parent == this.parent) - return; - - if (parent instanceof CookieListItem) { - // If the parent is to be a CookieListItem, then we keep the reference - // to it by its containing list and list index, rather than directly. - // This allows the list items to be garbage collected when they scroll - // out of view (except the expanded item, which we cache). This is - // transparent except in the setter and getter, where we handle it. - if (this.parent_ == undefined || parent.listIndex != -1) { - // Setting the parent is somewhat tricky because the CookieListItem - // constructor has side-effects on the |origin| that it wraps. Every - // time a CookieListItem is created for an |origin|, it registers - // itself as the parent of the |origin|. - // The List implementation may create a temporary CookieListItem item - // that wraps the |origin| of the very first entry of the CokiesList, - // when the List is redrawn the first time. This temporary - // CookieListItem is fresh (has listIndex = -1) and is never inserted - // into the List. Therefore it gets never updated. This destroys the - // chain of parent pointers. - // This is the stack trace: - // CookieListItem - // CookiesList.createItem - // List.measureItem - // List.getDefaultItemSize_ - // List.getDefaultItemHeight_ - // List.getIndexForListOffset_ - // List.getItemsInViewPort - // List.redraw - // List.endBatchUpdates - // CookiesList.loadChildren - this.parent_ = parent.listIndex; - } - this.list_ = parent.list; - parent.addEventListener('listIndexChange', - this.parentIndexChanged_.bind(this)); - } else { - this.parent_ = parent; - } - - if (this.data && this.data.id) { - if (parent) - parentLookup[this.data.id] = this; - else - delete parentLookup[this.data.id]; - } - - if (this.data && this.data.hasChildren && - !this.children.length && !lookupRequests[this.data.id]) { - lookupRequests[this.data.id] = true; - chrome.send('loadCookie', [this.pathId]); - } - }, - - /** - * Called when the parent is a CookieListItem whose index has changed. - * See the code above that avoids keeping a direct reference to - * CookieListItem parents, to allow them to be garbage collected. - * @private - */ - parentIndexChanged_: function(event) { - if (typeof this.parent_ == 'number') { - this.parent_ = event.newValue; - // We set a timeout to update the origin, rather than doing it right - // away, because this callback may occur while the list items are - // being repopulated following a scroll event. Calling updateOrigin() - // immediately could trigger relayout that would reset the scroll - // position within the list, among other things. - window.setTimeout(this.updateOrigin.bind(this), 0); - } - }, - - /** - * The cookie tree path id. - * @type {string} - */ - get pathId() { - var parent = this.parent; - if (parent && parent instanceof CookieTreeNode) - return parent.pathId + ',' + this.data.id; - return this.data.id; - }, - }; - - /** - * Creates a new cookies list. - * @param {Object=} opt_propertyBag Optional properties. - * @constructor - * @extends {options.DeletableItemList} - */ - var CookiesList = cr.ui.define('list'); - - CookiesList.prototype = { - __proto__: DeletableItemList.prototype, - - /** @override */ - decorate: function() { - DeletableItemList.prototype.decorate.call(this); - this.classList.add('cookie-list'); - this.dataModel = new ArrayDataModel([]); - this.addEventListener('keydown', this.handleKeyLeftRight_.bind(this)); - var sm = new ListSingleSelectionModel(); - sm.addEventListener('change', this.cookieSelectionChange_.bind(this)); - sm.addEventListener('leadIndexChange', this.cookieLeadChange_.bind(this)); - this.selectionModel = sm; - this.infoNodes = {}; - this.fixedHeight = false; - var doc = this.ownerDocument; - // Create a table for each type of site data (e.g. cookies, databases, - // etc.) and save it so that we can reuse it for all origins. - for (var type in cookieInfo) { - var table = doc.createElement('table'); - table.className = 'cookie-details-table'; - var tbody = doc.createElement('tbody'); - table.appendChild(tbody); - var info = {}; - for (var i = 0; i < cookieInfo[type].length; i++) { - var tr = doc.createElement('tr'); - var name = doc.createElement('td'); - var data = doc.createElement('td'); - var pair = cookieInfo[type][i]; - name.className = 'cookie-details-label'; - name.textContent = loadTimeData.getString(pair[1]); - data.className = 'cookie-details-value'; - data.textContent = ''; - tr.appendChild(name); - tr.appendChild(data); - tbody.appendChild(tr); - info[pair[0]] = data; - } - this.infoNodes[type] = {table: table, info: info}; - } - }, - - /** - * Handles key down events and looks for left and right arrows, then - * dispatches to the currently expanded item, if any. - * @param {Event} e The keydown event. - * @private - */ - handleKeyLeftRight_: function(e) { - var id = e.key; - if (hasKeyModifiers(e)) - return; - if ((id == 'ArrowLeft' || id == 'ArrowRight') && this.expandedItem) { - var cs = this.ownerDocument.defaultView.getComputedStyle(this); - var rtl = cs.direction == 'rtl'; - if ((!rtl && id == 'ArrowLeft') || (rtl && id == 'ArrowRight')) - this.expandedItem.selectedIndex--; - else - this.expandedItem.selectedIndex++; - this.scrollIndexIntoView(this.expandedItem.listIndex); - // Prevent the page itself from scrolling. - e.preventDefault(); - } - }, - - /** - * Called on selection model selection changes. - * @param {Event} ce The selection change event. - * @private - */ - cookieSelectionChange_: function(ce) { - ce.changes.forEach(function(change) { - var listItem = this.getListItemByIndex(change.index); - if (listItem) { - if (!change.selected) { - // We set a timeout here, rather than setting the item unexpanded - // immediately, so that if another item gets set expanded right - // away, it will be expanded before this item is unexpanded. It - // will notice that, and unexpand this item in sync with its own - // expansion. Later, this callback will end up having no effect. - window.setTimeout(function() { - if (!listItem.selected || !listItem.lead) - listItem.expanded = false; - }, 0); - } else if (listItem.lead) { - listItem.expanded = true; - } - } - }, this); - }, - - /** - * Called on selection model lead changes. - * @param {Event} pe The lead change event. - * @private - */ - cookieLeadChange_: function(pe) { - if (pe.oldValue != -1) { - var listItem = this.getListItemByIndex(pe.oldValue); - if (listItem) { - // See cookieSelectionChange_ above for why we use a timeout here. - window.setTimeout(function() { - if (!listItem.lead || !listItem.selected) - listItem.expanded = false; - }, 0); - } - } - if (pe.newValue != -1) { - var listItem = this.getListItemByIndex(pe.newValue); - if (listItem && listItem.selected) - listItem.expanded = true; - } - }, - - /** - * The currently expanded item. Used by CookieListItem above. - * @type {?options.CookieListItem} - */ - expandedItem: null, - - // from cr.ui.List - /** - * @override - * @param {Object} data - */ - createItem: function(data) { - // We use the cached expanded item in order to allow it to maintain some - // state (like its fixed height, and which bubble is selected). - if (this.expandedItem && this.expandedItem.origin == data) - return this.expandedItem; - return new CookieListItem(data, this); - }, - - // from options.DeletableItemList - /** @override */ - deleteItemAtIndex: function(index) { - var item = this.dataModel.item(index); - if (item) { - var pathId = item.pathId; - if (pathId) - chrome.send('removeCookie', [pathId]); - } - }, - - /** - * Insert the given list of cookie tree nodes at the given index. - * Both CookiesList and CookieTreeNode implement this API. - * @param {Array<Object>} data The data objects for the nodes to add. - * @param {number} start The index at which to start inserting the nodes. - */ - insertAt: function(data, start) { - spliceTreeNodes(data, start, this.dataModel); - }, - - /** - * Remove a cookie tree node from the given index. - * Both CookiesList and CookieTreeNode implement this API. - * - * TODO(dbeam): this method now conflicts with HTMLElement#remove(), which - * is why the param is optional. Rename. - * - * @param {number=} index The index of the tree node to remove. - */ - remove: function(index) { - if (index < this.dataModel.length) - this.dataModel.splice(index, 1); - }, - - /** - * Clears the list. - * Both CookiesList and CookieTreeNode implement this API. - * It is used by CookiesList.loadChildren(). - */ - clear: function() { - parentLookup = {}; - this.dataModel.splice(0, this.dataModel.length); - this.redraw(); - }, - - /** - * Add tree nodes by given parent. - * @param {Object} parent The parent node. - * @param {number} start The index at which to start inserting the nodes. - * @param {Array} nodesData Nodes data array. - * @private - */ - addByParent_: function(parent, start, nodesData) { - if (!parent) - return; - - parent.startBatchUpdates(); - parent.insertAt(nodesData, start); - parent.endBatchUpdates(); - - cr.dispatchSimpleEvent(this, 'change'); - }, - - /** - * Add tree nodes by parent id. - * This is used by cookies_view.js. - * @param {string} parentId Id of the parent node. - * @param {number} start The index at which to start inserting the nodes. - * @param {Array} nodesData Nodes data array. - */ - addByParentId: function(parentId, start, nodesData) { - var parent = parentId ? parentLookup[parentId] : this; - this.addByParent_(parent, start, nodesData); - }, - - /** - * Removes tree nodes by parent id. - * This is used by cookies_view.js. - * @param {string} parentId Id of the parent node. - * @param {number} start The index at which to start removing the nodes. - * @param {number} count Number of nodes to remove. - */ - removeByParentId: function(parentId, start, count) { - var parent = parentId ? parentLookup[parentId] : this; - if (!parent) - return; - - parent.startBatchUpdates(); - while (count-- > 0) - parent.remove(start); - parent.endBatchUpdates(); - - cr.dispatchSimpleEvent(this, 'change'); - }, - - /** - * Loads the immediate children of given parent node. - * This is used by cookies_view.js. - * @param {string} parentId Id of the parent node. - * @param {Array} children The immediate children of parent node. - */ - loadChildren: function(parentId, children) { - if (parentId) - delete lookupRequests[parentId]; - var parent = parentId ? parentLookup[parentId] : this; - if (!parent) - return; - - parent.startBatchUpdates(); - parent.clear(); - this.addByParent_(parent, 0, children); - parent.endBatchUpdates(); - }, - }; - - return { - CookiesList: CookiesList, - CookieListItem: CookieListItem, - CookieTreeNode: CookieTreeNode, - }; -});
diff --git a/chrome/browser/resources/options/cookies_view.css b/chrome/browser/resources/options/cookies_view.css deleted file mode 100644 index 5189011..0000000 --- a/chrome/browser/resources/options/cookies_view.css +++ /dev/null
@@ -1,200 +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. */ - -/* Styles for the cookies list page. */ -.cookies-view-page { - height: 90%; - margin-left: -15px; - width: 720px; -} - -/* Styles for the cookies list elements in cookies_view.html. */ -.cookies-list { - -webkit-box-flex: 1; - /* This property overrides the |min-height: 192px;| property above due to - * special behavior of the cookies list. */ - border: 1px solid #D9D9D9; - margin: 0; - margin-top: 5px; - min-height: 0; -} - -.cookies-list-content-area { - -webkit-box-orient: vertical; - display: -webkit-box; - overflow-y: hidden; -} - -.cookies-column-headers { - -webkit-box-align: baseline; - -webkit-box-orient: horizontal; - display: -webkit-box; - position: relative; - width: 100%; -} - -.cookies-column-headers > * { - display: block; -} - -.cookies-column-headers h3 { - font-size: 105%; - font-weight: bold; - margin: 10px 0; -} - -/* Notice the width and padding for these columns match up with those below. */ -.cookies-site-column { - -webkit-padding-start: 7px; - width: 14em; -} - -.cookies-data-column { - -webkit-box-flex: 1; - -webkit-padding-start: 7px; -} - -/* Enable animating the height of items. */ -list.cookie-list .deletable-item { - transition: height 150ms ease-in-out; -} - -/* Disable webkit-box display. */ -list.cookie-list .deletable-item > :first-child { - display: block; -} - -/* Force the X for deleting an origin to stay at the top. */ -list.cookie-list > .deletable-item > .close-button { - position: absolute; - right: 2px; - top: 8px; -} - -html[dir=rtl] list.cookie-list > .deletable-item > .close-button { - left: 2px; - right: auto; -} - -/* Styles for the site (aka origin) and its summary. */ -.cookie-site { - /* Notice that the width, margin, and padding match up with those above. */ - -webkit-margin-end: 2px; - -webkit-padding-start: 5px; - display: inline-block; - overflow: hidden; - text-overflow: ellipsis; - width: 14em; -} - -list.cookie-list > .deletable-item[selected] .cookie-site { - user-select: text; -} - -.cookie-data { - display: inline-block; - max-width: 410px; - overflow: hidden; - text-overflow: ellipsis; -} - -.cookie-size { - display: inline-block; - float: right; - margin-right: 0; -} - -list.cookie-list > .deletable-item[selected] .cookie-data { - user-select: text; -} - - -/* Styles for the individual items (cookies, etc.). */ -.cookie-items { - /* Notice that the margin and padding match up with those above. */ - -webkit-margin-start: 14em; - -webkit-padding-start: 7px; - display: none; - height: 0; - opacity: 0; - transition: 150ms ease-in-out; - /* Make the cookie items wrap correctly. */ - white-space: normal; -} - -.measure-items .cookie-items { - height: auto; - transition: none; - visibility: hidden; -} - -.show-items .cookie-items { - display: block; - opacity: 1; -} - -.cookie-items .cookie-item { - background: rgb(224, 233, 245); - border: 1px solid rgb(131, 146, 174); - border-radius: 5px; - display: inline-block; - font-size: 85%; - height: auto; - margin: 2px 4px 2px 0; - max-width: 120px; - min-width: 40px; - overflow: hidden; - padding: 0 3px; - text-align: center; - text-overflow: ellipsis; -} - -.cookie-items .cookie-item:hover { - background: rgb(238, 243, 249); - border-color: rgb(100, 113, 135); -} - -.cookie-items .cookie-item[selected] { - background: rgb(245, 248, 248); - border-color: #B2B2B2; -} - -.cookie-items .cookie-item[selected]:hover { - background: rgb(245, 248, 248); - border-color: rgb(100, 113, 135); -} - -.cookie-items .cookie-item .protecting-app, -.cookie-data .protecting-app { - margin-bottom: -3px; - margin-left: 4px; -} - -/* Styles for the cookie details box. */ -.cookie-details { - background: rgb(245, 248, 248); - border: 1px solid #B2B2B2; - border-radius: 5px; - margin-top: 2px; - padding: 5px; -} - -list.cookie-list > .deletable-item[selected] .cookie-details { - user-select: text; -} - -.cookie-details-table { - table-layout: fixed; - width: 100%; -} - -.cookie-details-label { - vertical-align: top; - white-space: pre; - width: 10em; -} - -.cookie-details-value { - word-wrap: break-word; -}
diff --git a/chrome/browser/resources/options/cookies_view.html b/chrome/browser/resources/options/cookies_view.html deleted file mode 100644 index 8176c3b..0000000 --- a/chrome/browser/resources/options/cookies_view.html +++ /dev/null
@@ -1,29 +0,0 @@ -<div id="cookies-view-page" class="page cookies-view-page" hidden> - <div class="close-button"></div> - <h1>$i18n{cookiesViewPage}</h1> - <div class="content-area cookies-list-content-area"> - <div class="cookies-column-headers"> - <div class="cookies-site-column"> - <h3>$i18n{cookie_domain}</h3> - </div> - <div class="cookies-data-column"> - <h3>$i18n{cookie_local_data}</h3> - </div> - <div class="cookies-header-controls"> - <button class="remove-all-cookies-button"> - $i18n{remove_all_cookie} - </button> - <input type="search" class="cookies-search-box" - placeholder="$i18n{search_cookies}" incremental> - </div> - </div> - <list id="cookies-list" class="cookies-list"></list> - </div> - <div class="action-area"> - <div class="button-strip"> - <button class="cookies-view-overlay-confirm default-button"> - $i18n{done} - </button> - </div> - </div> -</div>
diff --git a/chrome/browser/resources/options/cookies_view.js b/chrome/browser/resources/options/cookies_view.js deleted file mode 100644 index 7e2221ae..0000000 --- a/chrome/browser/resources/options/cookies_view.js +++ /dev/null
@@ -1,147 +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. - -cr.define('options', function() { - - var Page = cr.ui.pageManager.Page; - var PageManager = cr.ui.pageManager.PageManager; - - ///////////////////////////////////////////////////////////////////////////// - // CookiesView class: - - /** - * Encapsulated handling of the cookies and other site data page. - * @constructor - * @extends {cr.ui.pageManager.Page} - */ - function CookiesView(model) { - Page.call(this, 'cookies', - loadTimeData.getString('cookiesViewPageTabTitle'), - 'cookies-view-page'); - } - - cr.addSingletonGetter(CookiesView); - - CookiesView.prototype = { - __proto__: Page.prototype, - - /** - * The timer id of the timer set on search query change events. - * @type {number} - * @private - */ - queryDelayTimerId_: 0, - - /** - * The most recent search query, empty string if the query is empty. - * @type {string} - * @private - */ - lastQuery_: '', - - /** @override */ - initializePage: function() { - Page.prototype.initializePage.call(this); - - var searchBox = this.pageDiv.querySelector('.cookies-search-box'); - searchBox.addEventListener( - 'search', this.handleSearchQueryChange_.bind(this)); - searchBox.onkeydown = function(e) { - // Prevent the overlay from handling this event. - if (e.key == 'Enter') - e.stopPropagation(); - }; - - this.pageDiv.querySelector('.remove-all-cookies-button').onclick = - function(e) { - chrome.send('removeAllCookies'); - }; - - var cookiesList = this.pageDiv.querySelector('.cookies-list'); - options.CookiesList.decorate(cookiesList); - - this.addEventListener('visibleChange', this.handleVisibleChange_); - - this.pageDiv.querySelector('.cookies-view-overlay-confirm').onclick = - PageManager.closeOverlay.bind(PageManager); - }, - - /** @override */ - didShowPage: function() { - this.pageDiv.querySelector('.cookies-search-box').value = ''; - this.lastQuery_ = ''; - }, - - /** - * Search cookie using text in |cookies-search-box|. - */ - searchCookie: function() { - this.queryDelayTimerId_ = 0; - var filter = this.pageDiv.querySelector('.cookies-search-box').value; - if (this.lastQuery_ != filter) { - this.lastQuery_ = filter; - chrome.send('updateCookieSearchResults', [filter]); - } - }, - - /** - * Handles search query changes. - * @param {!Event} e The event object. - * @private - */ - handleSearchQueryChange_: function(e) { - var stringId = document.querySelector('.cookies-search-box').value ? - 'remove_all_shown_cookie' : 'remove_all_cookie'; - document.querySelector('.remove-all-cookies-button').innerHTML = - loadTimeData.getString(stringId); - if (this.queryDelayTimerId_) - window.clearTimeout(this.queryDelayTimerId_); - - this.queryDelayTimerId_ = window.setTimeout( - this.searchCookie.bind(this), 500); - }, - - initialized_: false, - - /** - * Handler for Page's visible property change event. - * @param {Event} e Property change event. - * @private - */ - handleVisibleChange_: function(e) { - if (!this.visible) - return; - - chrome.send('reloadCookies'); - - if (!this.initialized_) { - this.initialized_ = true; - this.searchCookie(); - } else { - this.pageDiv.querySelector('.cookies-list').redraw(); - } - - this.pageDiv.querySelector('.cookies-search-box').focus(); - }, - }; - - // CookiesViewHandler callbacks. - CookiesView.onTreeItemAdded = function(args) { - $('cookies-list').addByParentId(args[0], args[1], args[2]); - }; - - CookiesView.onTreeItemRemoved = function(args) { - $('cookies-list').removeByParentId(args[0], args[1], args[2]); - }; - - CookiesView.loadChildren = function(args) { - $('cookies-list').loadChildren(args[0], args[1]); - }; - - // Export - return { - CookiesView: CookiesView - }; - -});
diff --git a/chrome/browser/resources/options/deletable_item_list.js b/chrome/browser/resources/options/deletable_item_list.js deleted file mode 100644 index 57b684bf..0000000 --- a/chrome/browser/resources/options/deletable_item_list.js +++ /dev/null
@@ -1,214 +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. - -cr.define('options', function() { - /** @const */ var List = cr.ui.List; - /** @const */ var ListItem = cr.ui.ListItem; - - /** - * Creates a deletable list item, which has a button that will trigger a call - * to deleteItemAtIndex(index) in the list. - * @constructor - * @extends {cr.ui.ListItem} - */ - var DeletableItem = cr.ui.define('li'); - - DeletableItem.prototype = { - __proto__: ListItem.prototype, - - /** - * The element subclasses should populate with content. - * @type {HTMLElement} - * @private - */ - contentElement_: null, - - /** - * The close button element. - * @type {HTMLElement} - * @private - */ - closeButtonElement_: null, - - /** - * Whether or not this item can be deleted. - * @type {boolean} - * @private - */ - deletable_: true, - - /** - * Whether or not the close button can ever be navigated to using the - * keyboard. - * @type {boolean} - * @protected - */ - closeButtonFocusAllowed: false, - - /** @override */ - decorate: function() { - ListItem.prototype.decorate.call(this); - - this.classList.add('deletable-item'); - - this.contentElement_ = /** @type {HTMLElement} */( - this.ownerDocument.createElement('div')); - this.appendChild(this.contentElement_); - - this.closeButtonElement_ = /** @type {HTMLElement} */( - this.ownerDocument.createElement('button')); - this.closeButtonElement_.className = - 'raw-button row-delete-button custom-appearance'; - this.closeButtonElement_.addEventListener('mousedown', - this.handleMouseDownUpOnClose_); - this.closeButtonElement_.addEventListener('mouseup', - this.handleMouseDownUpOnClose_); - this.closeButtonElement_.addEventListener('focus', - this.handleFocus.bind(this)); - this.closeButtonElement_.tabIndex = -1; - this.closeButtonElement_.title = - loadTimeData.getString('deletableItemDeleteButtonTitle'); - this.appendChild(this.closeButtonElement_); - }, - - /** - * Returns the element subclasses should add content to. - * @return {HTMLElement} The element subclasses should popuplate. - */ - get contentElement() { - return this.contentElement_; - }, - - /** - * Returns the close button element. - * @return {HTMLElement} The close |<button>| element. - */ - get closeButtonElement() { - return this.closeButtonElement_; - }, - - /* Gets/sets the deletable property. An item that is not deletable doesn't - * show the delete button (although space is still reserved for it). - */ - get deletable() { - return this.deletable_; - }, - set deletable(value) { - this.deletable_ = value; - this.closeButtonElement_.disabled = !value; - }, - - /** - * Called when a focusable child element receives focus. Selects this item - * in the list selection model. - * @protected - */ - handleFocus: function() { - // This handler is also fired when the child receives focus as a result of - // the item getting selected by the customized mouse/keyboard handling in - // SelectionController. Take care not to destroy a potential multiple - // selection in this case. - if (this.selected) - return; - - var list = this.parentNode; - var index = list.getIndexOfListItem(this); - list.selectionModel.selectedIndex = index; - list.selectionModel.anchorIndex = index; - }, - - /** - * Don't let the list have a crack at the event. We don't want clicking the - * close button to change the selection of the list or to focus on the close - * button. - * @param {Event} e The mouse down/up event object. - * @private - */ - handleMouseDownUpOnClose_: function(e) { - if (e.target.disabled) - return; - e.stopPropagation(); - e.preventDefault(); - }, - }; - - /** - * @constructor - * @extends {cr.ui.List} - */ - var DeletableItemList = cr.ui.define('list'); - - DeletableItemList.prototype = { - __proto__: List.prototype, - - /** @override */ - decorate: function() { - List.prototype.decorate.call(this); - this.addEventListener('click', this.handleClick); - this.addEventListener('keydown', this.handleKeyDown_); - }, - - /** - * Callback for onclick events. - * @param {Event} e The click event object. - * @protected - */ - handleClick: function(e) { - if (this.disabled) - return; - - var target = e.target; - if (target.classList.contains('row-delete-button')) { - var listItem = this.getListItemAncestor( - /** @type {HTMLElement} */(target)); - var idx = this.getIndexOfListItem(listItem); - this.deleteItemAtIndex(idx); - } - }, - - /** - * Callback for keydown events. - * @param {Event} e The keydown event object. - * @private - */ - handleKeyDown_: function(e) { - // Map delete (and backspace on Mac) to item deletion (unless focus is - // in an input field, where it's intended for text editing). - if ((e.keyCode == 46 || (e.keyCode == 8 && cr.isMac)) && - e.target.tagName != 'INPUT') { - this.deleteSelectedItems_(); - // Prevent the browser from going back. - e.preventDefault(); - } - }, - - /** - * Deletes all the currently selected items that are deletable. - * @private - */ - deleteSelectedItems_: function() { - var selected = this.selectionModel.selectedIndexes; - // Reverse through the list of selected indexes to maintain the - // correct index values after deletion. - for (var j = selected.length - 1; j >= 0; j--) { - var index = selected[j]; - if (this.getListItemByIndex(index).deletable) - this.deleteItemAtIndex(index); - } - }, - - /** - * Called when an item should be deleted; subclasses are responsible for - * implementing. - * @param {number} index The index of the item that is being deleted. - */ - deleteItemAtIndex: function(index) { - }, - }; - - return { - DeletableItemList: DeletableItemList, - DeletableItem: DeletableItem, - }; -});
diff --git a/chrome/browser/resources/options/do_not_track_confirm_overlay.css b/chrome/browser/resources/options/do_not_track_confirm_overlay.css deleted file mode 100644 index 96950c10..0000000 --- a/chrome/browser/resources/options/do_not_track_confirm_overlay.css +++ /dev/null
@@ -1,7 +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. */ - -#do-not-track-confirm-overlay { - width: 500px; -}
diff --git a/chrome/browser/resources/options/do_not_track_confirm_overlay.html b/chrome/browser/resources/options/do_not_track_confirm_overlay.html deleted file mode 100644 index 3116968..0000000 --- a/chrome/browser/resources/options/do_not_track_confirm_overlay.html +++ /dev/null
@@ -1,23 +0,0 @@ -<div id="do-not-track-confirm-overlay" class="page" hidden> - <div class="close-button"></div> - <h1>$i18n{doNotTrackConfirmOverlay}</h1> - <div class="content-area"> - <span id="do-not-track-confirm-text">$i18n{doNotTrackConfirmMessage}</span> - </div> - <div class="action-area"> - <div class="hbox stretch"> - <a target="_blank" - href="$i18nRaw{doNotTrackLearnMoreURL}">$i18n{learnMore}</a> - </div> - <div class="action-area-right"> - <div class="button-strip"> - <button id="do-not-track-confirm-cancel"> - $i18n{doNotTrackConfirmDisable} - </button> - <button id="do-not-track-confirm-ok" class="default-button"> - $i18n{doNotTrackConfirmEnable} - </button> - </div> - </div> - </div> -</div>
diff --git a/chrome/browser/resources/options/easy_unlock_turn_off_overlay.css b/chrome/browser/resources/options/easy_unlock_turn_off_overlay.css deleted file mode 100644 index 817db4b..0000000 --- a/chrome/browser/resources/options/easy_unlock_turn_off_overlay.css +++ /dev/null
@@ -1,7 +0,0 @@ -/* Copyright 2014 The Chromium Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. */ - -#easy-unlock-turn-off-overlay { - max-width: 480px; -}
diff --git a/chrome/browser/resources/options/easy_unlock_turn_off_overlay.html b/chrome/browser/resources/options/easy_unlock_turn_off_overlay.html deleted file mode 100644 index 8a2db2e..0000000 --- a/chrome/browser/resources/options/easy_unlock_turn_off_overlay.html +++ /dev/null
@@ -1,17 +0,0 @@ -<div id="easy-unlock-turn-off-overlay" class="page" hidden> - <div class="close-button"></div> - <h1 id="easy-unlock-turn-off-title">$i18n{easyUnlockTurnOffTitle}</h1> - <div class="content-area"> - <p id="easy-unlock-turn-off-messagee" class="settings-row"> - $i18n{easyUnlockTurnOffDescription} - </p> - </div> - <div class="action-area button-strip"> - <button id="easy-unlock-turn-off-dismiss">$i18n{cancel}</button> - <button id="easy-unlock-turn-off-confirm" class="default-button"> - $i18n{easyUnlockTurnOffButton} - </button> - <div class="stretch"></div> - <div id="easy-unlock-turn-off-spinner" class="spinner" hidden></div> - </div> -</div>
diff --git a/chrome/browser/resources/options/easy_unlock_turn_off_overlay.js b/chrome/browser/resources/options/easy_unlock_turn_off_overlay.js deleted file mode 100644 index eb065df0..0000000 --- a/chrome/browser/resources/options/easy_unlock_turn_off_overlay.js +++ /dev/null
@@ -1,193 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -cr.define('options', function() { - var Page = cr.ui.pageManager.Page; - var PageManager = cr.ui.pageManager.PageManager; - - // UI state of the turn off overlay. - // @enum {string} - var UIState = { - UNKNOWN: 'unknown', - OFFLINE: 'offline', - IDLE: 'idle', - PENDING: 'pending', - SERVER_ERROR: 'server-error', - }; - - /** - * EasyUnlockTurnOffOverlay class - * Encapsulated handling of the Factory Reset confirmation overlay page. - * @class - */ - function EasyUnlockTurnOffOverlay() { - Page.call(this, 'easyUnlockTurnOffOverlay', - loadTimeData.getString('easyUnlockTurnOffTitle'), - 'easy-unlock-turn-off-overlay'); - } - - cr.addSingletonGetter(EasyUnlockTurnOffOverlay); - - EasyUnlockTurnOffOverlay.prototype = { - // Inherit EasyUnlockTurnOffOverlay from Page. - __proto__: Page.prototype, - - /** Current UI state */ - uiState_: UIState.UNKNOWN, - get uiState() { - return this.uiState_; - }, - set uiState(newUiState) { - if (newUiState == this.uiState_) - return; - - this.uiState_ = newUiState; - switch (this.uiState_) { - case UIState.OFFLINE: - this.setUpOfflineUI_(); - break; - case UIState.IDLE: - this.setUpTurnOffUI_(false); - break; - case UIState.PENDING: - this.setUpTurnOffUI_(true); - break; - case UIState.SERVER_ERROR: - this.setUpServerErrorUI_(); - break; - default: - console.error('Unknow Easy unlock turn off UI state: ' + - this.uiState_); - this.setUpTurnOffUI_(false); - break; - } - }, - - /** @override */ - initializePage: function() { - Page.prototype.initializePage.call(this); - - $('easy-unlock-turn-off-dismiss').onclick = function(event) { - EasyUnlockTurnOffOverlay.dismiss(); - }; - $('easy-unlock-turn-off-confirm').onclick = function(event) { - this.uiState = UIState.PENDING; - chrome.send('easyUnlockRequestTurnOff'); - }.bind(this); - }, - - /** @override */ - didShowPage: function() { - if (navigator.onLine) { - this.uiState = UIState.IDLE; - chrome.send('easyUnlockGetTurnOffFlowStatus'); - } else { - this.uiState = UIState.OFFLINE; - } - }, - - /** @override */ - didClosePage: function() { - chrome.send('easyUnlockTurnOffOverlayDismissed'); - }, - - /** - * Returns the button strip element. - * @return {HTMLDivElement} The container div of action buttons. - */ - get buttonStrip() { - return this.pageDiv.querySelector('.button-strip'); - }, - - /** - * Set visibility of action buttons in button strip. - * @private - */ - setActionButtonsVisible_: function(visible) { - var buttons = this.buttonStrip.querySelectorAll('button'); - for (var i = 0; i < buttons.length; ++i) { - buttons[i].hidden = !visible; - } - }, - - /** - * Set visibility of spinner. - * @private - */ - setSpinnerVisible_: function(visible) { - $('easy-unlock-turn-off-spinner').hidden = !visible; - }, - - /** - * Set up UI for showing offline message. - * @private - */ - setUpOfflineUI_: function() { - $('easy-unlock-turn-off-title').textContent = - loadTimeData.getString('easyUnlockTurnOffOfflineTitle'); - $('easy-unlock-turn-off-messagee').textContent = - loadTimeData.getString('easyUnlockTurnOffOfflineMessage'); - - this.setActionButtonsVisible_(false); - this.setSpinnerVisible_(false); - }, - - /** - * Set up UI for turning off Easy Unlock. - * @param {boolean} pending Whether there is a pending turn-off call. - * @private - */ - setUpTurnOffUI_: function(pending) { - $('easy-unlock-turn-off-title').textContent = - loadTimeData.getString('easyUnlockTurnOffTitle'); - $('easy-unlock-turn-off-messagee').textContent = - loadTimeData.getString('easyUnlockTurnOffDescription'); - $('easy-unlock-turn-off-confirm').textContent = - loadTimeData.getString('easyUnlockTurnOffButton'); - - this.setActionButtonsVisible_(true); - this.setSpinnerVisible_(pending); - $('easy-unlock-turn-off-confirm').disabled = pending; - $('easy-unlock-turn-off-dismiss').hidden = false; - }, - - /** - * Set up UI for showing server error. - * @private - */ - setUpServerErrorUI_: function() { - $('easy-unlock-turn-off-title').textContent = - loadTimeData.getString('easyUnlockTurnOffErrorTitle'); - $('easy-unlock-turn-off-messagee').textContent = - loadTimeData.getString('easyUnlockTurnOffErrorMessage'); - $('easy-unlock-turn-off-confirm').textContent = - loadTimeData.getString('easyUnlockTurnOffRetryButton'); - - this.setActionButtonsVisible_(true); - this.setSpinnerVisible_(false); - $('easy-unlock-turn-off-confirm').disabled = false; - $('easy-unlock-turn-off-dismiss').hidden = true; - }, - }; - - /** - * Closes the Easy unlock turn off overlay. - */ - EasyUnlockTurnOffOverlay.dismiss = function() { - PageManager.closeOverlay(); - }; - - /** - * Update UI to reflect the turn off operation status. - * @param {string} newState The UIState string representing the new state. - */ - EasyUnlockTurnOffOverlay.updateUIState = function(newState) { - EasyUnlockTurnOffOverlay.getInstance().uiState = newState; - }; - - // Export - return { - EasyUnlockTurnOffOverlay: EasyUnlockTurnOffOverlay - }; -});
diff --git a/chrome/browser/resources/options/editable_text_field.js b/chrome/browser/resources/options/editable_text_field.js deleted file mode 100644 index b895613..0000000 --- a/chrome/browser/resources/options/editable_text_field.js +++ /dev/null
@@ -1,372 +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. - -cr.define('options', function() { - /** - * @constructor - * @extends {HTMLDivElement} - */ - var EditableTextField = cr.ui.define('div'); - - EditableTextField.prototype = { - __proto__: HTMLDivElement.prototype, - - /** - * The actual input element in this field. - * @type {?HTMLElement} - * @private - */ - editField_: null, - - /** - * The static text displayed when this field isn't editable. - * @type {?HTMLElement} - * @private - */ - staticText_: null, - - /** - * The data model for this field. - * @type {?Object} - * @private - */ - model_: null, - - /** - * Whether or not the current edit should be considered canceled, rather - * than committed, when editing ends. - * @type {boolean} - * @private - */ - editCanceled_: true, - - /** @protected */ - decorate: function() { - this.classList.add('editable-text-field'); - - this.createEditableTextCell(''); - - if (this.hasAttribute('i18n-placeholder-text')) { - var identifier = this.getAttribute('i18n-placeholder-text'); - var localizedText = loadTimeData.getString(identifier); - if (localizedText) - this.setAttribute('placeholder-text', localizedText); - } - - this.addEventListener('keydown', this.handleKeyDown_); - this.editField_.addEventListener('focus', this.handleFocus_.bind(this)); - this.editField_.addEventListener('blur', this.handleBlur_.bind(this)); - this.checkForEmpty_(); - }, - - /** - * Indicates that this field has no value in the model, and the placeholder - * text (if any) should be shown. - * @type {boolean} - */ - get empty() { - return this.hasAttribute('empty'); - }, - - /** - * The placeholder text to be used when the model or its value is empty. - * @type {string} - */ - get placeholderText() { - return this.getAttribute('placeholder-text'); - }, - set placeholderText(text) { - if (text) - this.setAttribute('placeholder-text', text); - else - this.removeAttribute('placeholder-text'); - - this.checkForEmpty_(); - }, - - /** - * Returns the input element in this text field. - * @type {HTMLElement} The element that is the actual input field. - */ - get editField() { - return this.editField_; - }, - - /** - * Whether the user is currently editing the list item. - * @type {boolean} - */ - get editing() { - return this.hasAttribute('editing'); - }, - set editing(editing) { - if (this.editing == editing) - return; - - if (editing) - this.setAttribute('editing', ''); - else - this.removeAttribute('editing'); - - if (editing) { - this.editCanceled_ = false; - - if (this.empty) { - this.removeAttribute('empty'); - if (this.editField) - this.editField.value = ''; - } - if (this.editField) { - this.editField.focus(); - this.editField.select(); - } - } else { - if (!this.editCanceled_ && this.hasBeenEdited && - this.currentInputIsValid) { - this.updateStaticValues_(); - cr.dispatchSimpleEvent(this, 'commitedit', true); - } else { - this.resetEditableValues_(); - cr.dispatchSimpleEvent(this, 'canceledit', true); - } - this.checkForEmpty_(); - } - }, - - /** - * Whether the item is editable. - * @type {boolean} - */ - get editable() { - return this.hasAttribute('editable'); - }, - set editable(editable) { - if (this.editable == editable) - return; - - if (editable) - this.setAttribute('editable', ''); - else - this.removeAttribute('editable'); - this.editable_ = editable; - }, - - /** - * The data model for this field. - * @type {Object} - */ - get model() { - return this.model_; - }, - set model(model) { - this.model_ = model; - this.checkForEmpty_(); // This also updates the editField value. - this.updateStaticValues_(); - }, - - /** - * The HTML element that should have focus initially when editing starts, - * if a specific element wasn't clicked. Defaults to the first <input> - * element; can be overridden by subclasses if a different element should be - * focused. - * @type {?HTMLElement} - */ - get initialFocusElement() { - return this.querySelector('input'); - }, - - /** - * Whether the input in currently valid to submit. If this returns false - * when editing would be submitted, either editing will not be ended, - * or it will be cancelled, depending on the context. Can be overridden by - * subclasses to perform input validation. - * @type {boolean} - */ - get currentInputIsValid() { - return true; - }, - - /** - * Returns true if the item has been changed by an edit. Can be overridden - * by subclasses to return false when nothing has changed to avoid - * unnecessary commits. - * @type {boolean} - */ - get hasBeenEdited() { - return true; - }, - - /** - * Mutates the input during a successful commit. Can be overridden to - * provide a way to "clean up" valid input so that it conforms to a - * desired format. Will only be called when commit succeeds for valid - * input, or when the model is set. - * @param {string} value Input text to be mutated. - * @return {string} mutated text. - */ - mutateInput: function(value) { - return value; - }, - - /** - * Creates a div containing an <input>, as well as static text, keeping - * references to them so they can be manipulated. - * @param {string} text The text of the cell. - * @private - */ - createEditableTextCell: function(text) { - // This function should only be called once. - if (this.editField_) - return; - - var container = this.ownerDocument.createElement('div'); - - var textEl = /** @type {HTMLElement} */( - this.ownerDocument.createElement('div')); - textEl.className = 'static-text'; - textEl.textContent = text; - textEl.setAttribute('displaymode', 'static'); - this.appendChild(textEl); - this.staticText_ = textEl; - - var inputEl = /** @type {HTMLElement} */( - this.ownerDocument.createElement('input')); - inputEl.className = 'editable-text'; - inputEl.type = 'text'; - inputEl.value = text; - inputEl.setAttribute('displaymode', 'edit'); - inputEl.staticVersion = textEl; - this.appendChild(inputEl); - this.editField_ = inputEl; - }, - - /** - * Resets the editable version of any controls created by - * createEditableTextCell to match the static text. - * @private - */ - resetEditableValues_: function() { - var editField = this.editField_; - var staticLabel = editField.staticVersion; - if (!staticLabel) - return; - - if (editField instanceof HTMLInputElement) - editField.value = staticLabel.textContent; - - editField.setCustomValidity(''); - }, - - /** - * Sets the static version of any controls created by createEditableTextCell - * to match the current value of the editable version. Called on commit so - * that there's no flicker of the old value before the model updates. Also - * updates the model's value with the mutated value of the edit field. - * @private - */ - updateStaticValues_: function() { - var editField = this.editField_; - var staticLabel = editField.staticVersion; - if (!staticLabel) - return; - - if (editField instanceof HTMLInputElement) { - staticLabel.textContent = editField.value; - this.model_.value = this.mutateInput(editField.value); - } - }, - - /** - * Checks to see if the model or its value are empty. If they are, then set - * the edit field to the placeholder text, if any, and if not, set it to the - * model's value. - * @private - */ - checkForEmpty_: function() { - var editField = this.editField_; - if (!editField) - return; - - if (!this.model_ || !this.model_.value) { - this.setAttribute('empty', ''); - editField.value = this.placeholderText || ''; - } else { - this.removeAttribute('empty'); - editField.value = this.model_.value; - } - }, - - /** - * Called when this widget receives focus. - * @param {Event} e the focus event. - * @private - */ - handleFocus_: function(e) { - if (this.editing) - return; - - this.editing = true; - if (this.editField_) - this.editField_.focus(); - }, - - /** - * Called when this widget loses focus. - * @param {Event} e the blur event. - * @private - */ - handleBlur_: function(e) { - if (!this.editing) - return; - - this.editing = false; - }, - - /** - * Called when a key is pressed. Handles committing and canceling edits. - * @param {Event} e The key down event. - * @private - */ - handleKeyDown_: function(e) { - if (!this.editing) - return; - - var endEdit; - switch (e.key) { - case 'Escape': - this.editCanceled_ = true; - endEdit = true; - break; - case 'Enter': - if (this.currentInputIsValid) - endEdit = true; - break; - } - - if (endEdit) { - // Blurring will trigger the edit to end. - this.ownerDocument.activeElement.blur(); - // Make sure that handled keys aren't passed on and double-handled. - // (e.g., esc shouldn't both cancel an edit and close a subpage) - e.stopPropagation(); - } - }, - }; - - /** - * Takes care of committing changes to EditableTextField items when the - * window loses focus. - */ - window.addEventListener('blur', function(e) { - var itemAncestor = findAncestor(document.activeElement, function(node) { - return node instanceof EditableTextField; - }); - if (itemAncestor) - document.activeElement.blur(); - }); - - return { - EditableTextField: EditableTextField, - }; -});
diff --git a/chrome/browser/resources/options/factory_reset_overlay.css b/chrome/browser/resources/options/factory_reset_overlay.css deleted file mode 100644 index c7369e3f..0000000 --- a/chrome/browser/resources/options/factory_reset_overlay.css +++ /dev/null
@@ -1,7 +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. */ - -#factory-reset-overlay { - max-width: 550px; -}
diff --git a/chrome/browser/resources/options/factory_reset_overlay.html b/chrome/browser/resources/options/factory_reset_overlay.html deleted file mode 100644 index 3c0a0f0..0000000 --- a/chrome/browser/resources/options/factory_reset_overlay.html +++ /dev/null
@@ -1,15 +0,0 @@ -<div id="factory-reset-overlay" class="page" hidden> - <div class="close-button"></div> - <h1>$i18n{factoryResetHeading}</h1> - <div class="content-area"> - <span>$i18n{factoryResetWarning}</span> - <a href="$i18nRaw{factoryResetHelpUrl}" - target="_blank">$i18n{errorLearnMore}</a> - </div> - <div class="action-area button-strip"> - <button id="factory-reset-data-dismiss">$i18n{cancel}</button> - <button id="factory-reset-data-restart" class="default-button"> - $i18n{factoryResetDataRestart} - </button> - </div> -</div>
diff --git a/chrome/browser/resources/options/factory_reset_overlay.js b/chrome/browser/resources/options/factory_reset_overlay.js deleted file mode 100644 index 0a44648..0000000 --- a/chrome/browser/resources/options/factory_reset_overlay.js +++ /dev/null
@@ -1,47 +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. - -cr.define('options', function() { - var Page = cr.ui.pageManager.Page; - var PageManager = cr.ui.pageManager.PageManager; - - /** - * FactoryResetOverlay class - * Encapsulated handling of the Factory Reset confirmation overlay page. - * @class - */ - function FactoryResetOverlay() { - Page.call(this, 'factoryResetData', - loadTimeData.getString('factoryResetTitle'), - 'factory-reset-overlay'); - } - - cr.addSingletonGetter(FactoryResetOverlay); - - FactoryResetOverlay.prototype = { - // Inherit FactoryResetOverlay from Page. - __proto__: Page.prototype, - - /** @override */ - initializePage: function() { - Page.prototype.initializePage.call(this); - - $('factory-reset-data-dismiss').onclick = function(event) { - FactoryResetOverlay.dismiss(); - }; - $('factory-reset-data-restart').onclick = function(event) { - chrome.send('performFactoryResetRestart'); - }; - }, - }; - - FactoryResetOverlay.dismiss = function() { - PageManager.closeOverlay(); - }; - - // Export - return { - FactoryResetOverlay: FactoryResetOverlay - }; -});
diff --git a/chrome/browser/resources/options/font_settings.css b/chrome/browser/resources/options/font_settings.css deleted file mode 100644 index f999c58..0000000 --- a/chrome/browser/resources/options/font_settings.css +++ /dev/null
@@ -1,62 +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. */ - -#font-settings > section { - overflow: hidden; -} - -#font-settings .action-area { - -webkit-box-pack: start; -} - -#font-settings .action-area .spacer { - -webkit-box-flex: 1; - display: -webkit-box; -} - -#font-settings .button-strip { - width: 100%; -} - -.font-setting-container { - display: -webkit-box; -} - -#font-settings input[type='range'] { - width: 100%; -} - -#minimum-font-sample { - height: 35px; - overflow: hidden; - width: 270px; -} - -.font-input-div { - -webkit-margin-end: 3em; - width: 12em; -} - -.font-input-div > div > select { - margin-bottom: 10px; -} - -.font-input { - width: 100%; -} - -.font-sample-div { - direction: ltr; - height: 70px; - overflow: hidden; - width: 270px; -} - -.font-settings-huge { - float: right; -} - -html[dir=rtl] .font-settings-huge { - float: left; -}
diff --git a/chrome/browser/resources/options/font_settings.html b/chrome/browser/resources/options/font_settings.html deleted file mode 100644 index f22c3dc..0000000 --- a/chrome/browser/resources/options/font_settings.html +++ /dev/null
@@ -1,104 +0,0 @@ -<div id="font-settings" class="page" hidden> - <div class="close-button"></div> - <h1>$i18n{fontSettingsPage}</h1> - <div class="content-area"> - <section> - <h3>$i18n{fontSettingsStandard}</h3> - <div class="font-setting-container"> - <div class="font-input-div"> - <div> - <select id="standard-font-family" class="font-input" - data-type="string" metric="Options_ChangeStandardFont" - pref="webkit.webprefs.fonts.standard.Zyyy"> - </select> - </div> - <div> - <input id="standard-font-size" type="range" min="0" max="24" - pref="webkit.webprefs.default_font_size"> - <div> - <span>$i18n{fontSettingsSizeTiny}</span> - <span class="font-settings-huge"> - $i18n{fontSettingsSizeHuge} - </span> - </div> - </div> - </div> - <div id="standard-font-sample" class="font-sample-div"></div> - </div> - </section> - <section> - <h3>$i18n{fontSettingsSerif}</h3> - <div class="font-setting-container"> - <div class="font-input-div"> - <div> - <select id="serif-font-family" class="font-input" data-type="string" - pref="webkit.webprefs.fonts.serif.Zyyy" - metric="Options_ChangeSerifFont"> - </select> - </div> - </div> - <div id="serif-font-sample" class="font-sample-div"></div> - </div> - </section> - <section> - <h3>$i18n{fontSettingsSansSerif}</h3> - <div class="font-setting-container"> - <div class="font-input-div"> - <div> - <select id="sans-serif-font-family" class="font-input" - data-type="string" metric="Options_ChangeSansSerifFont" - pref="webkit.webprefs.fonts.sansserif.Zyyy"> - </select> - </div> - </div> - <div id="sans-serif-font-sample" class="font-sample-div"></div> - </div> - </section> - <section> - <h3>$i18n{fontSettingsFixedWidth}</h3> - <div class="font-setting-container"> - <div class="font-input-div"> - <div> - <select id="fixed-font-family" class="font-input" data-type="string" - pref="webkit.webprefs.fonts.fixed.Zyyy" - metric="Options_ChangeFixedFont"> - </select> - </div> - </div> - <div id="fixed-font-sample" class="font-sample-div"></div> - </div> - </section> - <section> - <h3>$i18n{fontSettingsMinimumSize}</h3> - <div class="font-setting-container"> - <div class="font-input-div"> - <div> - <input id="minimum-font-size" type="range" min="0" max="15" - pref="webkit.webprefs.minimum_font_size"> - <div> - <span>$i18n{fontSettingsSizeTiny}</span> - <span class="font-settings-huge"> - $i18n{fontSettingsSizeHuge} - </span> - </div> - </div> - </div> - <div id="minimum-font-sample" class="font-sample-div"></div> - </div> - </section> - </div> - <div class="action-area"> - <div class="button-strip"> - <span id="advanced-font-settings-install" hidden> - $i18nRaw{advancedFontSettingsInstall} - </span> - <a is="action-link" id="advanced-font-settings-options" hidden> - $i18n{advancedFontSettingsOptions} - </a> - <span class="spacer"></span> - <button id="font-settings-confirm" class="default-button"> - $i18n{done} - </button> - </div> - </div> -</div>
diff --git a/chrome/browser/resources/options/font_settings.js b/chrome/browser/resources/options/font_settings.js deleted file mode 100644 index 74be53d..0000000 --- a/chrome/browser/resources/options/font_settings.js +++ /dev/null
@@ -1,252 +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. - -cr.define('options', function() { - - var OptionsPage = options.OptionsPage; - var Page = cr.ui.pageManager.Page; - var PageManager = cr.ui.pageManager.PageManager; - - /** - * FontSettings class - * Encapsulated handling of the 'Fonts' page. - * @class - */ - function FontSettings() { - Page.call(this, 'fonts', - loadTimeData.getString('fontSettingsPageTabTitle'), - 'font-settings'); - } - - cr.addSingletonGetter(FontSettings); - - FontSettings.prototype = { - __proto__: Page.prototype, - - /** @override */ - initializePage: function() { - Page.prototype.initializePage.call(this); - - var standardFontRange = $('standard-font-size'); - standardFontRange.valueMap = [9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, - 22, 24, 26, 28, 30, 32, 34, 36, 40, 44, 48, 56, 64, 72]; - standardFontRange.addEventListener( - 'change', this.standardRangeChanged_.bind(this, standardFontRange)); - standardFontRange.addEventListener( - 'input', this.standardRangeChanged_.bind(this, standardFontRange)); - standardFontRange.customChangeHandler = - this.standardFontSizeChanged_.bind(standardFontRange); - - var minimumFontRange = $('minimum-font-size'); - minimumFontRange.valueMap = [6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, - 18, 20, 22, 24]; - minimumFontRange.addEventListener( - 'change', this.minimumRangeChanged_.bind(this, minimumFontRange)); - minimumFontRange.addEventListener( - 'input', this.minimumRangeChanged_.bind(this, minimumFontRange)); - minimumFontRange.customChangeHandler = - this.minimumFontSizeChanged_.bind(minimumFontRange); - - var placeholder = loadTimeData.getString('fontSettingsPlaceholder'); - var elements = [$('standard-font-family'), $('serif-font-family'), - $('sans-serif-font-family'), $('fixed-font-family')]; - elements.forEach(function(el) { - el.appendChild(new Option(placeholder)); - el.setDisabled('noFontsAvailable', true); - }); - - $('font-settings-confirm').onclick = function() { - PageManager.closeOverlay(); - }; - - $('advanced-font-settings-options').onclick = function() { - chrome.send('openAdvancedFontSettingsOptions'); - }; - }, - - /** @override */ - didShowPage: function() { - // The fonts list may be large so we only load it when this page is - // loaded for the first time. This makes opening the options window - // faster and consume less memory if the user never opens the fonts - // dialog. - if (!this.hasShown) { - chrome.send('fetchFontsData'); - this.hasShown = true; - } - }, - - /** - * Handler that is called when the user changes the position of the standard - * font size slider. This allows the UI to show a preview of the change - * before the slider has been released and the associated prefs updated. - * @param {Element} el The slider input element. - * @param {Event} event Change event. - * @private - */ - standardRangeChanged_: function(el, event) { - var size = el.mapPositionToPref(el.value); - var fontSampleEl = $('standard-font-sample'); - this.setUpFontSample_(fontSampleEl, size, fontSampleEl.style.fontFamily, - true); - - fontSampleEl = $('serif-font-sample'); - this.setUpFontSample_(fontSampleEl, size, fontSampleEl.style.fontFamily, - true); - - fontSampleEl = $('sans-serif-font-sample'); - this.setUpFontSample_(fontSampleEl, size, fontSampleEl.style.fontFamily, - true); - - fontSampleEl = $('fixed-font-sample'); - this.setUpFontSample_(fontSampleEl, - size - OptionsPage.SIZE_DIFFERENCE_FIXED_STANDARD, - fontSampleEl.style.fontFamily, false); - }, - - /** - * Sets the 'default_fixed_font_size' preference when the user changes the - * standard font size. - * @param {Event} event Change event. - * @private - */ - standardFontSizeChanged_: function(event) { - var size = this.mapPositionToPref(this.value); - Preferences.setIntegerPref( - 'webkit.webprefs.default_fixed_font_size', - size - OptionsPage.SIZE_DIFFERENCE_FIXED_STANDARD, true); - return false; - }, - - /** - * Handler that is called when the user changes the position of the minimum - * font size slider. This allows the UI to show a preview of the change - * before the slider has been released and the associated prefs updated. - * @param {Element} el The slider input element. - * @param {Event} event Change event. - * @private - */ - minimumRangeChanged_: function(el, event) { - var size = el.mapPositionToPref(el.value); - var fontSampleEl = $('minimum-font-sample'); - this.setUpFontSample_(fontSampleEl, size, fontSampleEl.style.fontFamily, - true); - }, - - /** - * Sets the 'minimum_logical_font_size' preference when the user changes the - * minimum font size. - * @param {Event} event Change event. - * @private - */ - minimumFontSizeChanged_: function(event) { - var size = this.mapPositionToPref(this.value); - Preferences.setIntegerPref( - 'webkit.webprefs.minimum_logical_font_size', size, true); - return false; - }, - - /** - * Sets the text, font size and font family of the sample text. - * @param {Element} el The div containing the sample text. - * @param {number} size The font size of the sample text. - * @param {string} font The font family of the sample text. - * @param {boolean} showSize True if the font size should appear in the - * sample. - * @private - */ - setUpFontSample_: function(el, size, font, showSize) { - var prefix = showSize ? (size + ': ') : ''; - el.textContent = prefix + - loadTimeData.getString('fontSettingsLoremIpsum'); - el.style.fontSize = size + 'px'; - if (font) - el.style.fontFamily = font; - }, - - /** - * Populates a select list and selects the specified item. - * @param {Element} element The select element to populate. - * @param {Array} items The array of items from which to populate. - * @param {string} selectedValue The selected item. - * @private - */ - populateSelect_: function(element, items, selectedValue) { - // Remove any existing content. - element.textContent = ''; - - // Insert new child nodes into select element. - for (var i = 0; i < items.length; i++) { - var value = items[i][0]; - var text = items[i][1]; - var dir = items[i][2]; - if (text) { - var selected = value == selectedValue; - var option = new Option(text, value, false, selected); - option.dir = dir; - element.appendChild(option); - } else { - element.appendChild(document.createElement('hr')); - } - } - - element.setDisabled('noFontsAvailable', false); - } - }; - - // Chrome callbacks - FontSettings.setFontsData = function(fonts, selectedValues) { - FontSettings.getInstance().populateSelect_($('standard-font-family'), fonts, - selectedValues[0]); - FontSettings.getInstance().populateSelect_($('serif-font-family'), fonts, - selectedValues[1]); - FontSettings.getInstance().populateSelect_($('sans-serif-font-family'), - fonts, selectedValues[2]); - FontSettings.getInstance().populateSelect_($('fixed-font-family'), fonts, - selectedValues[3]); - }; - - FontSettings.setUpStandardFontSample = function(font, size) { - FontSettings.getInstance().setUpFontSample_($('standard-font-sample'), size, - font, true); - }; - - FontSettings.setUpSerifFontSample = function(font, size) { - FontSettings.getInstance().setUpFontSample_($('serif-font-sample'), size, - font, true); - }; - - FontSettings.setUpSansSerifFontSample = function(font, size) { - FontSettings.getInstance().setUpFontSample_($('sans-serif-font-sample'), - size, font, true); - }; - - FontSettings.setUpFixedFontSample = function(font, size) { - FontSettings.getInstance().setUpFontSample_($('fixed-font-sample'), - size, font, false); - }; - - FontSettings.setUpMinimumFontSample = function(size) { - // If size is less than 6, represent it as six in the sample to account - // for the minimum logical font size. - if (size < 6) - size = 6; - FontSettings.getInstance().setUpFontSample_($('minimum-font-sample'), size, - null, true); - }; - - /** - * @param {boolean} available Whether the Advanced Font Settings Extension - * is installed and enabled. - */ - FontSettings.notifyAdvancedFontSettingsAvailability = function(available) { - $('advanced-font-settings-install').hidden = available; - $('advanced-font-settings-options').hidden = !available; - }; - - // Export - return { - FontSettings: FontSettings - }; -});
diff --git a/chrome/browser/resources/options/geolocation_options.js b/chrome/browser/resources/options/geolocation_options.js deleted file mode 100644 index 30071df3..0000000 --- a/chrome/browser/resources/options/geolocation_options.js +++ /dev/null
@@ -1,33 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -cr.define('options', function() { - var Page = cr.ui.pageManager.Page; - - /** - * GeolocationOptions class - * Handles initialization of the geolocation options. - * @constructor - * @extends {cr.ui.pageManager.Page} - */ - function GeolocationOptions() { - Page.call(this, 'geolocationOptions', - loadTimeData.getString('geolocationOptionsPageTabTitle'), - 'geolocationCheckbox'); - } - - cr.addSingletonGetter(GeolocationOptions); - - GeolocationOptions.prototype = { - __proto__: Page.prototype - }; - - // TODO(robliao): Determine if a full unroll is necessary - // (http://crbug.com/306613). - GeolocationOptions.showGeolocationOption = function() {}; - - return { - GeolocationOptions: GeolocationOptions - }; -});
diff --git a/chrome/browser/resources/options/googleg.svg b/chrome/browser/resources/options/googleg.svg deleted file mode 100644 index 7a1ad34..0000000 --- a/chrome/browser/resources/options/googleg.svg +++ /dev/null
@@ -1,7 +0,0 @@ -<svg xmlns="http://www.w3.org/2000/svg" width="16px" height="16px" viewBox="0 0 16 16"> - <path fill="#4285F4" d="M14.72 8.16c0-.46-.05-.81-.11-1.16H8v2.4h3.97c-.1.62-.52 1.59-1.45 2.26v1.64h2.12c1.32-1.21 2.08-3.01 2.08-5.14z"/> - <path fill="#34A853" d="M8 15c1.89 0 3.47-.63 4.63-1.69l-2.12-1.64c-.6.43-1.42.75-2.51.75-1.89 0-3.48-1.24-4.08-2.96H1.75v1.69C2.9 13.43 5.26 15 8 15z"/> - <path fill="#FBBC05" d="M3.92 9.45C3.77 9 3.66 8.51 3.66 8s.1-1 .26-1.45V4.86H1.75C1.27 5.81 1 6.87 1 8s.27 2.19.75 3.14l2.17-1.69z"/> - <path fill="#EA4335" d="M8 3.58c1.36 0 2.27.58 2.79 1.08l1.9-1.83C11.47 1.69 9.89 1 8 1 5.26 1 2.9 2.57 1.75 4.86l2.17 1.69C4.52 4.83 6.11 3.58 8 3.58z"/> - <path fill="none" d="M1 1h14v14H1z"/> -</svg>
diff --git a/chrome/browser/resources/options/handler_options.css b/chrome/browser/resources/options/handler_options.css deleted file mode 100644 index a022d97..0000000 --- a/chrome/browser/resources/options/handler_options.css +++ /dev/null
@@ -1,55 +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. */ - -.handlers-column-headers { - display: -webkit-box; - font-size: 13px; - font-weight: bold; -} - -.handlers-type-column { - -webkit-margin-end: 10px; - -webkit-margin-start: 14px; - width: 100px; -} - -.handlers-site-column { - max-width: 180px; -} - -.handlers-site-column select { - max-width: 170px; -} - -.handlers-remove-column { - -webkit-box-flex: 1; -} - -.handlers-remove-link { - color: #555; - cursor: pointer; - opacity: 0; - padding-left: 14px; - text-decoration: underline; - transition: 150ms opacity; -} - -div > .handlers-remove-column { - opacity: 0; -} - -div:not(.none):hover > .handlers-remove-column { - opacity: 1; -} - -#handlers { - min-height: 250px; -} - -#handler-options list { - border: solid 1px #D9D9D9; - border-radius: 2px; - margin-bottom: 10px; - margin-top: 4px; -}
diff --git a/chrome/browser/resources/options/handler_options.html b/chrome/browser/resources/options/handler_options.html deleted file mode 100644 index fb4f576..0000000 --- a/chrome/browser/resources/options/handler_options.html +++ /dev/null
@@ -1,44 +0,0 @@ -<div id="handler-options" class="page" hidden> - <div class="close-button"></div> - <h1>$i18n{handlersPage}</h1> - <div class="content-area"> - <h3>$i18n{handlersActiveHeading}</h3> - <div class="handlers-column-headers"> - <div class="handlers-type-column"> - <div>$i18n{handlersTypeColumnHeader}</div> - </div> - <div class="handlers-site-column"> - <div>$i18n{handlersSiteColumnHeader}</div> - </div> - <div class="handlers-remove-column"></div> - </div> - <list id="handlers-list"></list> - - <div id="ignored-handlers-section"> - <h3>$i18n{handlersIgnoredHeading}</h3> - <div class="handlers-column-headers"> - <div class="handlers-type-column"> - <h3>$i18n{handlersTypeColumnHeader}</h3> - </div> - <div class="handlers-site-column"> - <h3>$i18n{handlersSiteColumnHeader}</h3> - </div> - <div class="handlers-remove-column"></div> - </div> - <list id="ignored-handlers-list"></list> - </div> - </div> - <div class="action-area"> - <div class="hbox stretch"> - <a target="_blank" - href="$i18nRaw{handlersLearnMoreUrl}">$i18n{learnMore}</a> - </div> - <div class="action-area-right"> - <div class="button-strip"> - <button id="handler-options-overlay-confirm" class="default-button"> - $i18n{done} - </button> - </div> - </div> - </div> -</div>
diff --git a/chrome/browser/resources/options/handler_options.js b/chrome/browser/resources/options/handler_options.js deleted file mode 100644 index a01261f..0000000 --- a/chrome/browser/resources/options/handler_options.js +++ /dev/null
@@ -1,97 +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. - -/** - * @typedef {{ - * default_handler: number, - * handlers: Array, - * has_policy_recommendations: boolean, - * is_default_handler_set_by_user: boolean, - * protocol: string - * }} - * @see chrome/browser/ui/webui/options/handler_options_handler.cc - */ -var Handlers; - -cr.define('options', function() { - /** @const */ var Page = cr.ui.pageManager.Page; - /** @const */ var PageManager = cr.ui.pageManager.PageManager; - - ///////////////////////////////////////////////////////////////////////////// - // HandlerOptions class: - - /** - * Encapsulated handling of handler options page. - * @constructor - * @extends {cr.ui.pageManager.Page} - */ - function HandlerOptions() { - this.activeNavTab = null; - Page.call(this, - 'handlers', - loadTimeData.getString('handlersPageTabTitle'), - 'handler-options'); - } - - cr.addSingletonGetter(HandlerOptions); - - HandlerOptions.prototype = { - __proto__: Page.prototype, - - /** - * The handlers list. - * @type {options.HandlersList} - * @private - */ - handlersList_: null, - - /** @override */ - initializePage: function() { - Page.prototype.initializePage.call(this); - - this.createHandlersList_(); - - $('handler-options-overlay-confirm').onclick = - PageManager.closeOverlay.bind(PageManager); - }, - - /** - * Creates, decorates and initializes the handlers list. - * @private - */ - createHandlersList_: function() { - var handlersList = $('handlers-list'); - options.HandlersList.decorate(handlersList); - this.handlersList_ = assertInstanceof(handlersList, options.HandlersList); - this.handlersList_.autoExpands = true; - - var ignoredHandlersList = $('ignored-handlers-list'); - options.IgnoredHandlersList.decorate(ignoredHandlersList); - this.ignoredHandlersList_ = assertInstanceof(ignoredHandlersList, - options.IgnoredHandlersList); - this.ignoredHandlersList_.autoExpands = true; - }, - }; - - /** - * Sets the list of handlers shown by the view. - * @param {Array<Handlers>} handlers Handlers to be shown in the view. - */ - HandlerOptions.setHandlers = function(handlers) { - $('handlers-list').setHandlers(handlers); - }; - - /** - * Sets the list of ignored handlers shown by the view. - * @param {Array} handlers Handlers to be shown in the view. - */ - HandlerOptions.setIgnoredHandlers = function(handlers) { - $('ignored-handlers-section').hidden = handlers.length == 0; - $('ignored-handlers-list').setHandlers(handlers); - }; - - return { - HandlerOptions: HandlerOptions - }; -});
diff --git a/chrome/browser/resources/options/handler_options_list.js b/chrome/browser/resources/options/handler_options_list.js deleted file mode 100644 index 283e21b1..0000000 --- a/chrome/browser/resources/options/handler_options_list.js +++ /dev/null
@@ -1,268 +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. - -cr.define('options', function() { - /** @const */ var ArrayDataModel = cr.ui.ArrayDataModel; - /** @const */ var List = cr.ui.List; - /** @const */ var ListItem = cr.ui.ListItem; - /** @const */ var DeletableItem = options.DeletableItem; - /** @const */ var DeletableItemList = options.DeletableItemList; - - /** - * Creates a new ignored protocol / content handler list item. - * - * Accepts values in the form - * ['mailto', 'http://www.thesite.com/%s', 'www.thesite.com'], - * @param {Object} entry A dictionary describing the handlers for a given - * protocol. - * @constructor - * @extends {options.DeletableItem} - */ - function IgnoredHandlersListItem(entry) { - var el = cr.doc.createElement('div'); - el.dataItem = entry; - el.__proto__ = IgnoredHandlersListItem.prototype; - el.decorate(); - return el; - } - - IgnoredHandlersListItem.prototype = { - __proto__: DeletableItem.prototype, - - /** @override */ - decorate: function() { - DeletableItem.prototype.decorate.call(this); - - // Protocol. - var protocolElement = document.createElement('div'); - protocolElement.textContent = this.dataItem[0]; - protocolElement.className = 'handlers-type-column'; - this.contentElement_.appendChild(protocolElement); - - // Host name. - var hostElement = document.createElement('div'); - hostElement.textContent = this.dataItem[2]; - hostElement.className = 'handlers-site-column'; - hostElement.title = this.dataItem[1]; - this.contentElement_.appendChild(hostElement); - }, - }; - - /** - * @constructor - * @extends {options.DeletableItemList} - */ - var IgnoredHandlersList = cr.ui.define('list'); - - IgnoredHandlersList.prototype = { - __proto__: DeletableItemList.prototype, - - /** - * @override - * @param {Object} entry - */ - createItem: function(entry) { - return new IgnoredHandlersListItem(entry); - }, - - deleteItemAtIndex: function(index) { - chrome.send('removeIgnoredHandler', [this.dataModel.item(index)]); - }, - - /** - * The length of the list. - */ - get length() { - return this.dataModel.length; - }, - - /** - * Set the protocol handlers displayed by this list. See - * IgnoredHandlersListItem for an example of the format the list should - * take. - * - * @param {!Array} list A list of ignored protocol handlers. - */ - setHandlers: function(list) { - this.dataModel = new ArrayDataModel(list); - }, - }; - - /** - * Creates a new protocol / content handler list item. - * - * Accepts values in the form - * { protocol: 'mailto', - * handlers: [ - * ['mailto', 'http://www.thesite.com/%s', 'www.thesite.com'], - * ..., - * ], - * } - * @param {Object} entry A dictionary describing the handlers for a given - * protocol. - * @constructor - * @extends {cr.ui.ListItem} - */ - function HandlerListItem(entry) { - var el = cr.doc.createElement('div'); - el.dataItem = entry; - el.__proto__ = HandlerListItem.prototype; - el.decorate(); - return el; - } - - HandlerListItem.prototype = { - __proto__: ListItem.prototype, - - /** - * @param {Handlers} data - * @param {{removeHandler: Function, setDefault: Function, - * clearDefault: Function}} delegate - */ - buildWidget_: function(data, delegate) { - // Protocol. - var protocolElement = document.createElement('div'); - protocolElement.textContent = data.protocol; - protocolElement.className = 'handlers-type-column'; - this.appendChild(protocolElement); - - // Handler selection. - var handlerElement = document.createElement('div'); - var selectElement = document.createElement('select'); - var defaultOptionElement = document.createElement('option'); - defaultOptionElement.selected = data.default_handler == -1; - defaultOptionElement.textContent = - loadTimeData.getString('handlersNoneHandler'); - defaultOptionElement.value = -1; - selectElement.appendChild(defaultOptionElement); - - for (var i = 0; i < data.handlers.length; ++i) { - var optionElement = document.createElement('option'); - optionElement.selected = i == data.default_handler; - optionElement.textContent = data.handlers[i][2]; - optionElement.value = i; - selectElement.appendChild(optionElement); - } - - selectElement.addEventListener('change', function(e) { - var index = e.target.value; - if (index == -1) { - this.classList.add('none'); - delegate.clearDefault(data.protocol); - } else { - handlerElement.classList.remove('none'); - delegate.setDefault(data.handlers[index]); - } - }); - handlerElement.appendChild(selectElement); - handlerElement.className = 'handlers-site-column'; - if (data.default_handler == -1) - this.classList.add('none'); - this.appendChild(handlerElement); - - if (data.has_policy_recommendations) { - // Create an indicator to show that the handler has policy - // recommendations. - var indicator = new options.ControlledSettingIndicator(); - if (data.is_default_handler_set_by_user || data.default_handler == -1) { - // The default handler is registered by the user or set to none, which - // indicates that the user setting has overridden a policy - // recommendation. Show the appropriate bubble. - indicator.controlledBy = 'hasRecommendation'; - indicator.resetHandler = function() { - // If there is a policy recommendation, data.handlers.length >= 1. - // Setting the default handler to 0 ensures that it won't be 'none', - // and there *is* a user registered handler created by setDefault, - // which is required for a change notification. - // The user-registered handlers are removed in a loop. Note that if - // a handler is installed by policy, removeHandler does nothing. - delegate.setDefault(data.handlers[0]); - for (var i = 0; i < data.handlers.length; ++i) { - delegate.removeHandler(i, data.handlers[i]); - } - }; - } else { - indicator.controlledBy = 'recommended'; - } - this.appendChild(indicator); - } - - if (data.is_default_handler_set_by_user) { - // Remove link. - var removeElement = document.createElement('div'); - removeElement.textContent = - loadTimeData.getString('handlersRemoveLink'); - removeElement.addEventListener('click', function(e) { - var value = selectElement ? selectElement.value : 0; - delegate.removeHandler(value, data.handlers[value]); - }); - removeElement.className = - 'handlers-remove-column handlers-remove-link'; - this.appendChild(removeElement); - } - }, - - /** @override */ - decorate: function() { - ListItem.prototype.decorate.call(this); - - var delegate = { - removeHandler: function(index, handler) { - chrome.send('removeHandler', [handler]); - }, - setDefault: function(handler) { - chrome.send('setDefault', [handler]); - }, - clearDefault: function(protocol) { - chrome.send('clearDefault', [protocol]); - }, - }; - - this.buildWidget_(this.dataItem, delegate); - }, - }; - - /** - * Create a new passwords list. - * @constructor - * @extends {cr.ui.List} - */ - var HandlersList = cr.ui.define('list'); - - HandlersList.prototype = { - __proto__: List.prototype, - - /** - * @override - * @param {Object} entry - */ - createItem: function(entry) { - return new HandlerListItem(entry); - }, - - /** - * The length of the list. - */ - get length() { - return this.dataModel.length; - }, - - /** - * Set the protocol handlers displayed by this list. - * See HandlerListItem for an example of the format the list should take. - * - * @param {!Array} list A list of protocols with their registered handlers. - */ - setHandlers: function(list) { - this.dataModel = new ArrayDataModel(list); - }, - }; - - return { - IgnoredHandlersListItem: IgnoredHandlersListItem, - IgnoredHandlersList: IgnoredHandlersList, - HandlerListItem: HandlerListItem, - HandlersList: HandlersList, - }; -});
diff --git a/chrome/browser/resources/options/home_page_overlay.html b/chrome/browser/resources/options/home_page_overlay.html deleted file mode 100644 index d73b0f5..0000000 --- a/chrome/browser/resources/options/home_page_overlay.html +++ /dev/null
@@ -1,45 +0,0 @@ -<div id="home-page-overlay" class="page" role="dialog" hidden> - <div class="close-button"></div> - <h1>$i18n{homePageOverlay}</h1> - <div class="content-area"> - <div class="radio controlled-setting-with-label"> - <label> - <input id="homepage-use-ntp" type="radio" name="homepage" - pref="homepage_is_newtabpage" value="true" - metric="Options_Homepage_IsNewTabPage" dialog-pref> - <span> - <span>$i18n{homePageUseNewTab}</span> - <span class="controlled-setting-indicator" - pref="homepage_is_newtabpage" value="true" dialog-pref></span> - </span> - </label> - </div> - <div class="radio controlled-setting-with-label"> - <label class="option-name"> - <input id="homepage-use-url" type="radio" name="homepage" - pref="homepage_is_newtabpage" value="false" - metric="Options_Homepage_IsNewTabPage" dialog-pref> - <span> - <span id="homepage-use-url-label">$i18n{homePageUseURL}</span> - <span class="controlled-setting-indicator" - pref="homepage_is_newtabpage" value="false" dialog-pref></span> - </span> - </label> - <input id="homepage-url-field" type="url" data-type="url" - class="weakrtl favicon-cell stretch" pref="homepage" - aria-labelledby="homepage-use-url-label" - metric="Options_Homepage_URL" dialog-pref> - </input> - <span id="homepage-url-field-indicator" - class="controlled-setting-indicator" pref="homepage" - dialog-pref> - </span> - </div> - </div> - <div class="action-area"> - <div class="button-strip"> - <button id="home-page-cancel" type="reset">$i18n{cancel}</button> - <button id="home-page-confirm" class="default-button">$i18n{ok}</button> - </div> - </div> -</div>
diff --git a/chrome/browser/resources/options/home_page_overlay.js b/chrome/browser/resources/options/home_page_overlay.js deleted file mode 100644 index d4b1b8f3..0000000 --- a/chrome/browser/resources/options/home_page_overlay.js +++ /dev/null
@@ -1,154 +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. - -cr.define('options', function() { - /** @const */ var Page = cr.ui.pageManager.Page; - /** @const */ var SettingsDialog = options.SettingsDialog; - - /** - * HomePageOverlay class - * Dialog that allows users to set the home page. - * @constructor - * @extends {options.SettingsDialog} - */ - function HomePageOverlay() { - SettingsDialog.call(this, 'homePageOverlay', - loadTimeData.getString('homePageOverlayTabTitle'), - 'home-page-overlay', - assertInstanceof($('home-page-confirm'), HTMLButtonElement), - assertInstanceof($('home-page-cancel'), HTMLButtonElement)); - } - - cr.addSingletonGetter(HomePageOverlay); - - HomePageOverlay.prototype = { - __proto__: SettingsDialog.prototype, - - /** - * An autocomplete list that can be attached to the home page URL field. - * @type {cr.ui.AutocompleteList} - * @private - */ - autocompleteList_: null, - - /** @override */ - initializePage: function() { - SettingsDialog.prototype.initializePage.call(this); - - var self = this; - options.Preferences.getInstance().addEventListener( - 'homepage_is_newtabpage', - this.handleHomepageIsNTPPrefChange.bind(this)); - - var urlField = $('homepage-url-field'); - urlField.addEventListener('keydown', function(event) { - // Don't auto-submit when the user selects something from the - // auto-complete list. - if (event.key == 'Enter' && !self.autocompleteList_.hidden) - event.stopPropagation(); - }); - urlField.addEventListener('change', this.updateFavicon_.bind(this)); - - var suggestionList = new cr.ui.AutocompleteList(); - suggestionList.autoExpands = true; - suggestionList.requestSuggestions = - this.requestAutocompleteSuggestions_.bind(this); - $('home-page-overlay').appendChild(suggestionList); - this.autocompleteList_ = suggestionList; - - urlField.addEventListener('focus', function(event) { - self.autocompleteList_.attachToInput(urlField); - }); - urlField.addEventListener('blur', function(event) { - self.autocompleteList_.detach(); - }); - }, - - /** @override */ - didShowPage: function() { - this.updateFavicon_(); - }, - - /** - * Updates the state of the homepage text input and its controlled setting - * indicator when the |homepage_is_newtabpage| pref changes. The input is - * enabled only if the homepage is not the NTP. The indicator is always - * enabled but treats the input's value as read-only if the homepage is the - * NTP. - * @param {Event} event Pref change event. - */ - handleHomepageIsNTPPrefChange: function(event) { - var urlField = $('homepage-url-field'); - var urlFieldIndicator = $('homepage-url-field-indicator'); - urlField.setDisabled('homepage-is-ntp', event.value.value); - urlFieldIndicator.readOnly = event.value.value; - }, - - /** - * Updates the background of the url field to show the favicon for the - * URL that is currently typed in. - * @private - */ - updateFavicon_: function() { - var urlField = $('homepage-url-field'); - urlField.style.backgroundImage = cr.icon.getFavicon(urlField.value); - }, - - /** - * Sends an asynchronous request for new autocompletion suggestions for the - * the given query. When new suggestions are available, the C++ handler will - * call updateAutocompleteSuggestions_. - * @param {string} query List of autocomplete suggestions. - * @private - */ - requestAutocompleteSuggestions_: function(query) { - chrome.send('requestAutocompleteSuggestionsForHomePage', [query]); - }, - - /** - * Updates the autocomplete suggestion list with the given entries. - * @param {Array} suggestions List of autocomplete suggestions. - * @private - */ - updateAutocompleteSuggestions_: function(suggestions) { - var list = this.autocompleteList_; - // If the trigger for this update was a value being selected from the - // current list, do nothing. - if (list.targetInput && list.selectedItem && - list.selectedItem.url == list.targetInput.value) { - return; - } - list.suggestions = suggestions; - }, - - /** - * Sets the 'show home button' and 'home page is new tab page' preferences. - * (The home page url preference is set automatically by the SettingsDialog - * code.) - */ - handleConfirm: function() { - // Strip whitespace. - var urlField = $('homepage-url-field'); - var homePageValue = urlField.value.replace(/\s*/g, ''); - urlField.value = homePageValue; - - // Don't save an empty URL for the home page. If the user left the field - // empty, switch to the New Tab page. - if (!homePageValue) - $('homepage-use-ntp').checked = true; - - SettingsDialog.prototype.handleConfirm.call(this); - }, - }; - - HomePageOverlay.updateAutocompleteSuggestions = function() { - var instance = HomePageOverlay.getInstance(); - instance.updateAutocompleteSuggestions_.apply(instance, arguments); - }; - - // Export - return { - HomePageOverlay: HomePageOverlay - }; -});
diff --git a/chrome/browser/resources/options/hotword_confirm_dialog.js b/chrome/browser/resources/options/hotword_confirm_dialog.js deleted file mode 100644 index a14d1fe9..0000000 --- a/chrome/browser/resources/options/hotword_confirm_dialog.js +++ /dev/null
@@ -1,81 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -cr.define('options', function() { - /** @const */ var ConfirmDialog = options.ConfirmDialog; - /** @const */ var SettingsDialog = options.SettingsDialog; - /** @const */ var PageManager = cr.ui.pageManager.PageManager; - - /** - * A dialog that will pop up when the user attempts to set the value of the - * Boolean |pref| to |true|, asking for confirmation. It will first check for - * any errors and if any exist, not display the dialog but toggle the - * indicator. Like its superclass, if the user clicks OK, the new value is - * committed to Chrome. If the user clicks Cancel or leaves the settings page, - * the new value is discarded. - * @constructor - * @extends {options.ConfirmDialog} - */ - function HotwordConfirmDialog() { - ConfirmDialog.call(this, - 'hotwordConfim', // name - loadTimeData.getString('hotwordConfirmOverlayTabTitle'), - 'hotword-confirm-overlay', // pageDivName - assertInstanceof($('hotword-confirm-ok'), HTMLButtonElement), - assertInstanceof($('hotword-confirm-cancel'), HTMLButtonElement), - $('hotword-search-enable')['pref'], // pref - $('hotword-search-enable')['metric']); // metric - - this.indicator = $('hotword-search-setting-indicator'); - } - - HotwordConfirmDialog.prototype = { - // TODO(dbeam): this class should probably derive SettingsDialog again as it - // evily duplicates much of ConfirmDialog's functionality, calls methods - // on SettingsDialog.prototype, and shadows private method names. - __proto__: ConfirmDialog.prototype, - - /** - * Handle changes to |pref|. Only uncommitted changes are relevant as these - * originate from user and need to be explicitly committed to take effect. - * Pop up the dialog if there are no errors from the indicator or commit the - * change, depending on whether confirmation is needed. - * @param {Event} event Change event. - * @private - */ - onPrefChanged_: function(event) { - if (!event.value.uncommitted) - return; - - if (event.value.value && !this.confirmed_) { - // If there is an error, show the indicator icon with more information. - if (this.indicator.errorText) - this.indicator.updateBasedOnError(); - - // Show confirmation dialog (regardless of whether there is an error). - PageManager.showPageByName(this.name, false); - } else { - Preferences.getInstance().commitPref(this.pref, this.metric); - } - }, - - /** - * Override the initializePage function so that an updated version of - * onPrefChanged_ can be used. - * @override - */ - initializePage: function() { - SettingsDialog.prototype.initializePage.call(this); - - this.okButton.onclick = this.handleConfirm.bind(this); - this.cancelButton.onclick = this.handleCancel.bind(this); - Preferences.getInstance().addEventListener( - this.pref, this.onPrefChanged_.bind(this)); - } - }; - - return { - HotwordConfirmDialog: HotwordConfirmDialog - }; -});
diff --git a/chrome/browser/resources/options/hotword_confirm_overlay.css b/chrome/browser/resources/options/hotword_confirm_overlay.css deleted file mode 100644 index 542d8745..0000000 --- a/chrome/browser/resources/options/hotword_confirm_overlay.css +++ /dev/null
@@ -1,7 +0,0 @@ -/* Copyright 2014 The Chromium Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. */ - -#hotword-confirm-overlay { - width: 500px; -}
diff --git a/chrome/browser/resources/options/hotword_confirm_overlay.html b/chrome/browser/resources/options/hotword_confirm_overlay.html deleted file mode 100644 index 5733921..0000000 --- a/chrome/browser/resources/options/hotword_confirm_overlay.html +++ /dev/null
@@ -1,32 +0,0 @@ -<div id="hotword-confirm-overlay" class="page" hidden> - <div class="close-button"></div> - <h1>$i18n{hotwordConfirmOverlay}</h1> - <div class="content-area"> - <span id="hotword-confirm-text">$i18n{hotwordConfirmMessage}</span> - </div> - <div class="action-area"> - <div class="hbox stretch"> - <a target="_blank" - href="$i18nRaw{hotwordLearnMoreURL}">$i18n{learnMore}</a> - </div> - <div class="action-area-right"> - <div class="button-strip"> - <button id="hotword-confirm-cancel"> - $i18n{hotwordConfirmDisable} - </button> - <button id="hotword-confirm-ok" class="default-button"> - $i18n{hotwordConfirmEnable} - </button> - </div> - </div> - </div> - <div id="audio-logging-bar" class="gray-bottom-bar checkbox"> - <label> - <input - pref="hotword.audio_logging_enabled" - metric="Options_Hotword_AudioLogging_Checkbox" - type="checkbox" dialog-pref checked> - <span>$i18n{hotwordAudioLoggingEnable}</span> - </label> - </div> -</div>
diff --git a/chrome/browser/resources/options/hotword_search_setting_indicator.css b/chrome/browser/resources/options/hotword_search_setting_indicator.css deleted file mode 100644 index d486d1a..0000000 --- a/chrome/browser/resources/options/hotword_search_setting_indicator.css +++ /dev/null
@@ -1,12 +0,0 @@ -/* Copyright 2014 The Chromium Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. */ - -/* Hotword extension-specific controlled setting indicator and bubble. */ - -#hotword-search-setting-indicator > div, -#hotword-always-on-search-setting-indicator > div, -#hotword-no-dsp-search-setting-indicator > div { - background: url(chrome://theme/IDR_WARNING) left top no-repeat; - background-size: 18px; -}
diff --git a/chrome/browser/resources/options/hotword_search_setting_indicator.js b/chrome/browser/resources/options/hotword_search_setting_indicator.js deleted file mode 100644 index 40e1b170..0000000 --- a/chrome/browser/resources/options/hotword_search_setting_indicator.js +++ /dev/null
@@ -1,122 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -cr.define('options', function() { - /** @const */ var ControlledSettingIndicator = - options.ControlledSettingIndicator; - - /** - * A variant of the {@link ControlledSettingIndicator} that shows the status - * of the hotword search setting, including a bubble to show setup errors - * (such as failures to download extension resources). - * @constructor - * @extends {options.ControlledSettingIndicator} - */ - var HotwordSearchSettingIndicator = cr.ui.define('span'); - - HotwordSearchSettingIndicator.prototype = { - __proto__: ControlledSettingIndicator.prototype, - - /** - * Decorates the base element to show the proper icon. - * @override - */ - decorate: function() { - ControlledSettingIndicator.prototype.decorate.call(this); - this.hidden = true; - }, - - /** - * Handle changes to the associated pref by hiding any currently visible - * bubble. - * @param {Event} event Pref change event. - * @override - */ - handlePrefChange: function(event) { - PageManager.hideBubble(); - }, - - /** - * Sets the variable tracking the section which becomes disabled if an - * error exists. - * @param {HTMLElement} section The section to disable. - */ - set disabledOnErrorSection(section) { - // TODO(kcarattini): Instead of this, add a cr.EventTarget and have - // the element to disable register an event on it. - this.disabledOnErrorSection_ = section; - }, - - /** - * Returns the current error. - * @return {string} The error message to be displayed. May be undefined if - * there is no error. - */ - get errorText() { - return this.errorText_; - }, - - /** - * Checks for errors and records them. - * @param {string} errorMsg The error message to be displayed. May be - * undefined if there is no error. - */ - setError: function(errorMsg) { - this.setAttribute('controlled-by', 'policy'); - this.errorText_ = errorMsg; - }, - - /** - * Changes the display to be visible if there are errors and disables - * the section. - */ - updateBasedOnError: function() { - if (this.errorText_) - this.hidden = false; - if (this.disabledOnErrorSection_) - this.disabledOnErrorSection_.disabled = !!this.errorText_; - }, - - /** - * Toggles showing and hiding the error message bubble. An empty - * |errorText_| indicates that there is no error message. So the bubble - * only be shown if |errorText_| has a value. - * @override - */ - toggleBubble: function() { - if (this.showingBubble) { - PageManager.hideBubble(); - return; - } - - if (!this.errorText_) - return; - - var self = this; - // Create the DOM tree for the bubble content. - var closeButton = document.createElement('div'); - closeButton.classList.add('close-button'); - - var text = document.createElement('p'); - text.innerHTML = this.errorText_; - - var textDiv = document.createElement('div'); - textDiv.appendChild(text); - - var container = document.createElement('div'); - container.appendChild(closeButton); - container.appendChild(textDiv); - - var content = document.createElement('div'); - content.appendChild(container); - - PageManager.showBubble(content, this.image, this, this.location); - }, - }; - - // Export - return { - HotwordSearchSettingIndicator: HotwordSearchSettingIndicator - }; -});
diff --git a/chrome/browser/resources/options/i18n_setup.html b/chrome/browser/resources/options/i18n_setup.html deleted file mode 100644 index cec2322..0000000 --- a/chrome/browser/resources/options/i18n_setup.html +++ /dev/null
@@ -1,6 +0,0 @@ -<!-- This file is intentionally empty. - settings-lock-screen element will import i18n_setup.html file in settings. - The scripts included by i18n_setup.html is already included in options.html, - including the same script again seems to throw some errors. So creating an - empty file here just for options. --->
diff --git a/chrome/browser/resources/options/import_data_overlay.css b/chrome/browser/resources/options/import_data_overlay.css deleted file mode 100644 index 0d730dc..0000000 --- a/chrome/browser/resources/options/import_data_overlay.css +++ /dev/null
@@ -1,36 +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-data-overlay { - width: 400px; -} - -#import-from-div { - margin-bottom: 20px; -} - -#import-checkboxes > div:not(:first-child) { - -webkit-padding-start: 8px; -} - -#import-throbber { - margin: 4px 10px; - vertical-align: middle; - visibility: hidden; -} - -#import-success-header { - font-size: 1.2em; -} - -#import-success-image { - -webkit-mask-image: url(../../../../ui/webui/resources/images/check_circle.svg); - -webkit-mask-position: center; - -webkit-mask-repeat: no-repeat; - -webkit-mask-size: 96px; - background-color: rgb(15, 157, 88); - height: 96px; - margin: 20px 0; - width: 100%; -}
diff --git a/chrome/browser/resources/options/import_data_overlay.html b/chrome/browser/resources/options/import_data_overlay.html deleted file mode 100644 index 7d604146..0000000 --- a/chrome/browser/resources/options/import_data_overlay.html +++ /dev/null
@@ -1,120 +0,0 @@ -<div id="import-data-overlay" class="page" hidden> - <div class="close-button"></div> - <h1>$i18n{importDataOverlay}</h1> - <div class="content-area"> - <div class="import-data-configure"> - <div id="import-from-div"> - <span>$i18n{importFromLabel}</span> - <select id="import-browsers"> - <option>$i18n{importLoading}</option> - </select> - </div> - <div id="import-checkboxes"> - <div>$i18n{importDescription}</div> - <div class="checkbox controlled-setting-with-label" - id="import-history-with-label"> - <label> - <input id="import-history" type="checkbox" - pref="import_dialog_history"> - <span> - <span>$i18n{importHistory}</span> - <span class="controlled-setting-indicator" - pref="import_dialog_history"> - </span> - </span> - </label> - </div> - <div class="checkbox controlled-setting-with-label" - id="import-favorites-with-label"> - <label> - <input id="import-favorites" type="checkbox" - pref="import_dialog_bookmarks"> - <span> - <span>$i18n{importFavorites}</span> - <span class="controlled-setting-indicator" - pref="import_dialog_bookmarks"></span> - </span> - </label> - </div> - <div class="checkbox controlled-setting-with-label" - id="import-passwords-with-label"> - <label> - <input id="import-passwords" type="checkbox" - pref="import_dialog_saved_passwords"> - <span> - <span>$i18n{importPasswords}</span> - <span class="controlled-setting-indicator" - pref="import_dialog_saved_passwords"></span> - </span> - </label> - </div> - <div class="checkbox controlled-setting-with-label" - id="import-search-with-label"> - <label> - <input id="import-search" type="checkbox" - pref="import_dialog_search_engine"> - <span> - <span>$i18n{importSearch}</span> - <span class="controlled-setting-indicator" - pref="import_dialog_search_engine"></span> - </span> - </label> - </div> - <div class="checkbox controlled-setting-with-label" - id="import-autofill-form-data-with-label"> - <label> - <input id="import-autofill-form-data" type="checkbox" - pref="import_dialog_autofill_form_data"> - <span>$i18n{importAutofillFormData}</span> - </label> - <span class="controlled-setting-indicator" - pref="import_dialog_autofill_form_data"></span> - </div> - </div> - </div> - <div class="import-data-success" hidden> - <div id="import-success-header"> - <strong>$i18n{importSucceeded}</strong> - </div> - <div id="import-success-image"></div> - <div id="import-find-your-bookmarks"> - <span>$i18n{findYourImportedBookmarks}</span> - <div class="checkbox controlled-setting-with-label"> - <label> - <input id="import-data-show-bookmarks-bar" - pref="bookmark_bar.show_on_all_tabs" - metric="Options_ShowBookmarksBar" type="checkbox"> - <span> - <span>$i18n{toolbarShowBookmarksBar}</span> - <span class="controlled-setting-indicator" - pref="bookmark_bar.show_on_all_tabs"></span> - </span> - </label> - </div> - </div> - </div> - </div> - <div class="action-area"> - <div class="import-data-configure"> - <div class="action-area-right"> - <div id="import-throbber" class="throbber"></div> - <div class="button-strip"> - <button id="import-data-cancel">$i18n{cancel}</button> - <button id="import-choose-file">$i18n{importChooseFile}</button> - <button id="import-data-commit" class="default-button"> - $i18n{importCommit} - </button> - </div> - </div> - </div> - <div class="import-data-success" hidden> - <div class="action-area-right"> - <div class="button-strip"> - <button id="import-data-confirm" class="default-button"> - $i18n{done} - </button> - </div> - </div> - </div> - </div> -</div>
diff --git a/chrome/browser/resources/options/import_data_overlay.js b/chrome/browser/resources/options/import_data_overlay.js deleted file mode 100644 index 2d9fd60..0000000 --- a/chrome/browser/resources/options/import_data_overlay.js +++ /dev/null
@@ -1,269 +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. - -cr.define('options', function() { - var Page = cr.ui.pageManager.Page; - var PageManager = cr.ui.pageManager.PageManager; - - /** - * ImportDataOverlay class - * Encapsulated handling of the 'Import Data' overlay page. - * @class - */ - function ImportDataOverlay() { - Page.call(this, - 'importData', - loadTimeData.getString('importDataOverlayTabTitle'), - 'import-data-overlay'); - } - - cr.addSingletonGetter(ImportDataOverlay); - - /** - * @param {string} type The type of data to import. Used in the element's ID. - */ - function importable(type) { - var id = 'import-' + type; - return $(id).checked && !$(id + '-with-label').hidden; - } - - ImportDataOverlay.prototype = { - // Inherit from Page. - __proto__: Page.prototype, - - /** @override */ - initializePage: function() { - Page.prototype.initializePage.call(this); - - var self = this; - var checkboxes = - document.querySelectorAll('#import-checkboxes input[type=checkbox]'); - for (var i = 0; i < checkboxes.length; i++) { - checkboxes[i].customPrefChangeHandler = function(e) { - options.PrefCheckbox.prototype.defaultPrefChangeHandler.call(this, e); - self.validateCommitButton_(); - return true; - }; - } - - $('import-browsers').onchange = function() { - self.updateCheckboxes_(); - self.validateCommitButton_(); - }; - - $('import-data-commit').onclick = function() { - chrome.send('importData', [ - String($('import-browsers').selectedIndex), - String($('import-history').checked), - String($('import-favorites').checked), - String($('import-passwords').checked), - String($('import-search').checked), - String($('import-autofill-form-data').checked)]); - }; - - $('import-data-cancel').onclick = function() { - ImportDataOverlay.dismiss(); - }; - - $('import-choose-file').onclick = function() { - chrome.send('chooseBookmarksFile'); - }; - - $('import-data-confirm').onclick = function() { - ImportDataOverlay.dismiss(); - }; - - // Form controls are disabled until the profile list has been loaded. - self.setAllControlsEnabled_(false); - }, - - /** - * Sets the enabled and checked state of the commit button. - * @private - */ - validateCommitButton_: function() { - var somethingToImport = - importable('history') || importable('favorites') || - importable('passwords') || importable('search') || - importable('autofill-form-data'); - $('import-data-commit').disabled = !somethingToImport; - $('import-choose-file').disabled = !$('import-favorites').checked; - }, - - /** - * Sets the enabled state of all the checkboxes and the commit button. - * @private - */ - setAllControlsEnabled_: function(enabled) { - var checkboxes = - document.querySelectorAll('#import-checkboxes input[type=checkbox]'); - for (var i = 0; i < checkboxes.length; i++) - this.setUpCheckboxState_(checkboxes[i], enabled); - $('import-data-commit').disabled = !enabled; - $('import-choose-file').hidden = !enabled; - }, - - /** - * Sets the enabled state of a checkbox element. - * @param {Object} checkbox A checkbox element. - * @param {boolean} enabled The enabled state of the checkbox. If false, - * the checkbox is disabled. If true, the checkbox is enabled. - * @private - */ - setUpCheckboxState_: function(checkbox, enabled) { - checkbox.setDisabled('noProfileData', !enabled); - }, - - /** - * Update the enabled and visible states of all the checkboxes. - * @private - */ - updateCheckboxes_: function() { - var index = $('import-browsers').selectedIndex; - var bookmarksFileSelected = index == this.browserProfiles.length - 1; - $('import-choose-file').hidden = !bookmarksFileSelected; - $('import-data-commit').hidden = bookmarksFileSelected; - - var browserProfile; - if (this.browserProfiles.length > index) - browserProfile = this.browserProfiles[index]; - var importOptions = ['history', - 'favorites', - 'passwords', - 'search', - 'autofill-form-data']; - for (var i = 0; i < importOptions.length; i++) { - var id = 'import-' + importOptions[i]; - var enable = browserProfile && browserProfile[importOptions[i]]; - this.setUpCheckboxState_($(id), enable); - $(id + '-with-label').hidden = !enable; - } - }, - - /** - * Update the supported browsers popup with given entries. - * @param {Array} browsers List of supported browsers name. - * @private - */ - updateSupportedBrowsers_: function(browsers) { - this.browserProfiles = browsers; - var browserSelect = /** @type {HTMLSelectElement} */( - $('import-browsers')); - browserSelect.remove(0); // Remove the 'Loading...' option. - browserSelect.textContent = ''; - var browserCount = browsers.length; - - if (browserCount == 0) { - var option = new Option(loadTimeData.getString('noProfileFound'), 0); - browserSelect.appendChild(option); - - this.setAllControlsEnabled_(false); - } else { - this.setAllControlsEnabled_(true); - for (var i = 0; i < browserCount; i++) { - var browser = browsers[i]; - var option = new Option(browser.name, browser.index); - browserSelect.appendChild(option); - } - - this.updateCheckboxes_(); - this.validateCommitButton_(); - } - }, - - /** - * Clear import prefs set when user checks/unchecks a checkbox so that each - * checkbox goes back to the default "checked" state (or alternatively, to - * the state set by a recommended policy). - * @private - */ - clearUserPrefs_: function() { - var importPrefs = [ - 'import_dialog_history', 'import_dialog_bookmarks', - 'import_dialog_saved_passwords', 'import_dialog_search_engine', - 'import_dialog_autofill_form_data' - ]; - for (var i = 0; i < importPrefs.length; i++) - Preferences.clearPref(importPrefs[i], true); - }, - - /** - * Update the dialog layout to reflect success state. - * @param {boolean} success If true, show success dialog elements. - * @private - */ - updateSuccessState_: function(success) { - var sections = document.querySelectorAll('.import-data-configure'); - for (var i = 0; i < sections.length; i++) - sections[i].hidden = success; - - sections = document.querySelectorAll('.import-data-success'); - for (var i = 0; i < sections.length; i++) - sections[i].hidden = !success; - }, - }; - - ImportDataOverlay.clearUserPrefs = function() { - ImportDataOverlay.getInstance().clearUserPrefs_(); - }; - - /** - * Update the supported browsers popup with given entries. - * @param {Array} browsers List of supported browsers name. - */ - ImportDataOverlay.updateSupportedBrowsers = function(browsers) { - ImportDataOverlay.getInstance().updateSupportedBrowsers_(browsers); - }; - - /** - * Update the UI to reflect whether an import operation is in progress. - * @param {boolean} importing True if an import operation is in progress. - */ - ImportDataOverlay.setImportingState = function(importing) { - var checkboxes = - document.querySelectorAll('#import-checkboxes input[type=checkbox]'); - for (var i = 0; i < checkboxes.length; i++) - checkboxes[i].setDisabled('Importing', importing); - if (!importing) - ImportDataOverlay.getInstance().updateCheckboxes_(); - $('import-browsers').disabled = importing; - $('import-throbber').style.visibility = importing ? 'visible' : 'hidden'; - ImportDataOverlay.getInstance().validateCommitButton_(); - }; - - /** - * Remove the import overlay from display. - */ - ImportDataOverlay.dismiss = function() { - ImportDataOverlay.clearUserPrefs(); - PageManager.closeOverlay(); - }; - - /** - * Show a message confirming the success of the import operation. - */ - ImportDataOverlay.confirmSuccess = function() { - var showBookmarksMessage = $('import-favorites').checked; - ImportDataOverlay.setImportingState(false); - $('import-find-your-bookmarks').hidden = !showBookmarksMessage; - ImportDataOverlay.getInstance().updateSuccessState_(true); - }; - - /** - * Show the import data overlay. - */ - ImportDataOverlay.show = function() { - // Make sure that any previous import success message is hidden, and - // we're showing the UI to import further data. - ImportDataOverlay.getInstance().updateSuccessState_(false); - ImportDataOverlay.getInstance().validateCommitButton_(); - - PageManager.showPageByName('importData'); - }; - - // Export - return { - ImportDataOverlay: ImportDataOverlay - }; -});
diff --git a/chrome/browser/resources/options/inline_editable_list.js b/chrome/browser/resources/options/inline_editable_list.js deleted file mode 100644 index da5751e2..0000000 --- a/chrome/browser/resources/options/inline_editable_list.js +++ /dev/null
@@ -1,774 +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. - -cr.define('options', function() { - /** @const */ var DeletableItem = options.DeletableItem; - /** @const */ var DeletableItemList = options.DeletableItemList; - - /** - * Creates a new list item with support for inline editing. - * @constructor - * @extends {options.DeletableItem} - */ - function InlineEditableItem() { - var el = cr.doc.createElement('div'); - InlineEditableItem.decorate(el); - return el; - } - - /** - * Decorates an element as a inline-editable list item. Note that this is - * a subclass of DeletableItem. - * @param {!HTMLElement} el The element to decorate. - */ - InlineEditableItem.decorate = function(el) { - el.__proto__ = InlineEditableItem.prototype; - el.decorate(); - }; - - InlineEditableItem.prototype = { - __proto__: DeletableItem.prototype, - - /** - * Index of currently focused column, or -1 for none. - * @type {number} - */ - focusedColumnIndex: -1, - - /** - * Whether or not this item can be edited. - * @type {boolean} - * @private - */ - editable_: true, - - /** - * Whether or not this is a placeholder for adding a new item. - * @type {boolean} - * @private - */ - isPlaceholder_: false, - - /** - * Fields associated with edit mode. - * @type {Array} - * @private - */ - editFields_: null, - - /** - * Whether or not the current edit should be considered cancelled, rather - * than committed, when editing ends. - * @type {boolean} - * @private - */ - editCancelled_: true, - - /** - * The editable item corresponding to the last click, if any. Used to decide - * initial focus when entering edit mode. - * @type {HTMLElement} - * @private - */ - editClickTarget_: null, - - /** @override */ - decorate: function() { - DeletableItem.prototype.decorate.call(this); - - this.editFields_ = []; - this.addEventListener('mousedown', this.handleMouseDown_); - this.addEventListener('keydown', this.handleKeyDown_); - this.addEventListener('focusin', this.handleFocusIn_); - }, - - /** @override */ - selectionChanged: function() { - if (!this.parentNode.ignoreChangeEvents_) - this.updateEditState(); - }, - - /** - * Called when this element gains or loses 'lead' status. Updates editing - * mode accordingly. - */ - updateLeadState: function() { - // Add focusability before call to updateEditState. - if (this.lead) { - this.setEditableValuesFocusable(true); - this.setCloseButtonFocusable(true); - } - - this.updateEditState(); - - // Remove focusability after call to updateEditState. - this.setStaticValuesFocusable(false); - if (!this.lead) { - this.setEditableValuesFocusable(false); - this.setCloseButtonFocusable(false); - } - }, - - /** - * Updates the edit state based on the current selected and lead states. - */ - updateEditState: function() { - if (this.editable) - this.editing = this.selected && this.lead; - }, - - /** - * Whether the user is currently editing the list item. - * @type {boolean} - */ - get editing() { - return this.hasAttribute('editing'); - }, - set editing(editing) { - if (this.editing == editing) - return; - - if (editing) - this.setAttribute('editing', ''); - else - this.removeAttribute('editing'); - - if (editing) { - this.editCancelled_ = false; - - cr.dispatchSimpleEvent(this, 'edit', true); - - var isMouseClick = this.editClickTarget_; - var focusElement = this.getEditFocusElement_(); - if (focusElement) { - if (isMouseClick) { - // Delay focus to fix http://crbug.com/436789 - setTimeout(function() { - this.focusAndMaybeSelect_(focusElement); - }.bind(this), 0); - } else { - this.focusAndMaybeSelect_(focusElement); - } - } - } else { - if (!this.editCancelled_ && this.hasBeenEdited && - this.currentInputIsValid) { - this.parentNode.needsToFocusPlaceholder_ = this.isPlaceholder && - this.parentNode.shouldFocusPlaceholderOnEditCommit(); - this.updateStaticValues_(); - cr.dispatchSimpleEvent(this, 'commitedit', true); - } else { - this.parentNode.needsToFocusPlaceholder_ = false; - this.resetEditableValues_(); - cr.dispatchSimpleEvent(this, 'canceledit', true); - } - } - }, - - /** - * Return editable element that should be focused, or null for none. - * @private - */ - getEditFocusElement_: function() { - // If an edit field was clicked on then use the clicked element. - if (this.editClickTarget_) { - var result = this.editClickTarget_; - this.editClickTarget_ = null; - return result; - } - - // If focusedColumnIndex is valid then use the element in that column. - if (this.focusedColumnIndex != -1) { - var nearestColumn = - this.getNearestColumnByIndex_(this.focusedColumnIndex); - if (nearestColumn) - return nearestColumn; - } - - // It's possible that focusedColumnIndex hasn't been updated yet. - // Check getFocusedColumnIndex_ directly. - // This can't completely replace the above focusedColumnIndex check - // because InlineEditableItemList may have set focusedColumnIndex to a - // different value. - var columnIndex = this.getFocusedColumnIndex_(); - if (columnIndex != -1) { - var nearestColumn = this.getNearestColumnByIndex_(columnIndex); - if (nearestColumn) - return nearestColumn; - } - - // Everything else failed so return the default. - return this.initialFocusElement; - }, - - /** - * Focus on the specified element, and select the editable text in it - * if possible. - * @param {!Element} control An element to be focused. - * @private - */ - focusAndMaybeSelect_: function(control) { - control.focus(); - if (control.tagName == 'INPUT') - control.select(); - }, - - /** - * Whether the item is editable. - * @type {boolean} - */ - get editable() { - return this.editable_; - }, - set editable(editable) { - this.editable_ = editable; - if (!editable) - this.editing = false; - }, - - /** - * Whether the item is a new item placeholder. - * @type {boolean} - */ - get isPlaceholder() { - return this.isPlaceholder_; - }, - set isPlaceholder(isPlaceholder) { - this.isPlaceholder_ = isPlaceholder; - if (isPlaceholder) - this.deletable = false; - }, - - /** - * The HTML element that should have focus initially when editing starts, - * if a specific element wasn't clicked. - * Defaults to the first <input> element; can be overridden by subclasses if - * a different element should be focused. - * @type {HTMLElement} - */ - get initialFocusElement() { - return this.contentElement.querySelector('input'); - }, - - /** - * Whether the input in currently valid to submit. If this returns false - * when editing would be submitted, either editing will not be ended, - * or it will be cancelled, depending on the context. - * Can be overridden by subclasses to perform input validation. - * @type {boolean} - */ - get currentInputIsValid() { - return true; - }, - - /** - * Returns true if the item has been changed by an edit. - * Can be overridden by subclasses to return false when nothing has changed - * to avoid unnecessary commits. - * @type {boolean} - */ - get hasBeenEdited() { - return true; - }, - - /** - * Sets whether the editable values can be given focus using the keyboard. - * @param {boolean} focusable The desired focusable state. - */ - setEditableValuesFocusable: function(focusable) { - focusable = focusable && this.editable; - var editFields = this.editFields_; - for (var i = 0; i < editFields.length; i++) { - editFields[i].tabIndex = focusable ? 0 : -1; - } - }, - - /** - * Sets whether the static values can be given focus using the keyboard. - * @param {boolean} focusable The desired focusable state. - */ - setStaticValuesFocusable: function(focusable) { - var editFields = this.editFields_; - for (var i = 0; i < editFields.length; i++) { - var staticVersion = editFields[i].staticVersion; - if (!staticVersion) - continue; - if (this.editable) { - staticVersion.tabIndex = focusable ? 0 : -1; - } else { - // staticVersion remains visible when !this.editable. Remove - // tabindex so that it will not become focused by clicking on it and - // have selection box drawn around it. - staticVersion.removeAttribute('tabindex'); - } - } - }, - - /** - * Sets whether the close button can be focused using the keyboard. - * @param {boolean} focusable The desired focusable state. - */ - setCloseButtonFocusable: function(focusable) { - this.closeButtonElement.tabIndex = - focusable && this.closeButtonFocusAllowed ? 0 : -1; - }, - - /** - * Returns a div containing an <input>, as well as static text if - * isPlaceholder is not true. - * @param {string} text The text of the cell. - * @return {HTMLElement} The HTML element for the cell. - * @private - */ - createEditableTextCell: function(text) { - var container = /** @type {HTMLElement} */( - this.ownerDocument.createElement('div')); - var textEl = null; - if (!this.isPlaceholder) { - textEl = this.ownerDocument.createElement('div'); - textEl.className = 'static-text overruleable'; - textEl.textContent = text; - textEl.setAttribute('displaymode', 'static'); - container.appendChild(textEl); - } - - var inputEl = this.ownerDocument.createElement('input'); - inputEl.type = 'text'; - inputEl.value = text; - if (!this.isPlaceholder) - inputEl.setAttribute('displaymode', 'edit'); - - // In some cases 'focus' event may arrive before 'input'. - // To make sure revalidation is triggered we postpone 'focus' handling. - var handler = this.handleFocus.bind(this); - inputEl.addEventListener('focus', function() { - window.setTimeout(function() { - if (inputEl.ownerDocument.activeElement == inputEl) - handler(); - }, 0); - }); - container.appendChild(inputEl); - this.addEditField(inputEl, textEl); - - return container; - }, - - /** - * Register an edit field. - * @param {!Element} control An editable element. It's a form control - * element typically. - * @param {Element} staticElement An element representing non-editable - * state. - */ - addEditField: function(control, staticElement) { - control.staticVersion = staticElement; - if (this.editable) - control.tabIndex = -1; - - if (control.staticVersion) { - if (this.editable) - control.staticVersion.tabIndex = -1; - control.staticVersion.editableVersion = control; - control.staticVersion.addEventListener('focus', - this.handleFocus.bind(this)); - } - this.editFields_.push(control); - }, - - /** - * Set the column index for a child element of this InlineEditableItem. - * Only elements with a column index will be keyboard focusable, e.g. by - * pressing the tab key. - * @param {Element} element Element whose column index to set. Method does - * nothing if element is null. - * @param {number} columnIndex The new column index to set on the element. - * -1 removes the column index. - */ - setFocusableColumnIndex: function(element, columnIndex) { - if (!element) - return; - - if (columnIndex >= 0) - element.setAttribute('inlineeditable-column', columnIndex); - else - element.removeAttribute('inlineeditable-column'); - }, - - /** - * Resets the editable version of any controls created by createEditable* - * to match the static text. - * @private - */ - resetEditableValues_: function() { - var editFields = this.editFields_; - for (var i = 0; i < editFields.length; i++) { - var staticLabel = editFields[i].staticVersion; - if (!staticLabel && !this.isPlaceholder) - continue; - - if (editFields[i].tagName == 'INPUT') { - editFields[i].value = - this.isPlaceholder ? '' : staticLabel.textContent; - } - // Add more tag types here as new createEditable* methods are added. - - editFields[i].setCustomValidity(''); - } - }, - - /** - * Sets the static version of any controls created by createEditable* - * to match the current value of the editable version. Called on commit so - * that there's no flicker of the old value before the model updates. - * @private - */ - updateStaticValues_: function() { - var editFields = this.editFields_; - for (var i = 0; i < editFields.length; i++) { - var staticLabel = editFields[i].staticVersion; - if (!staticLabel) - continue; - - if (editFields[i].tagName == 'INPUT') - staticLabel.textContent = editFields[i].value; - // Add more tag types here as new createEditable* methods are added. - } - }, - - /** - * Returns the index of the column that currently has focus, or -1 if no - * column has focus. - * @return {number} - * @private - */ - getFocusedColumnIndex_: function() { - var element = document.activeElement.editableVersion || - document.activeElement; - - if (element.hasAttribute('inlineeditable-column')) - return parseInt(element.getAttribute('inlineeditable-column'), 10); - return -1; - }, - - /** - * Returns the element from the column that has the largest index where: - * where: - * + index <= startIndex, and - * + the element exists, and - * + the element is not disabled - * @return {Element} - * @private - */ - getNearestColumnByIndex_: function(startIndex) { - for (var i = startIndex; i >= 0; --i) { - var el = this.querySelector('[inlineeditable-column="' + i + '"]'); - if (el && !el.disabled) - return el; - } - return null; - }, - - /** - * Called when a key is pressed. Handles committing and canceling edits. - * @param {Event} e The key down event. - * @private - */ - handleKeyDown_: function(e) { - if (!this.editing) - return; - - var endEdit = false; - var handledKey = true; - switch (e.key) { - case 'Escape': - this.editCancelled_ = true; - endEdit = true; - break; - case 'Enter': - if (this.currentInputIsValid) - endEdit = true; - break; - default: - handledKey = false; - } - if (handledKey) { - // Make sure that handled keys aren't passed on and double-handled. - // (e.g., esc shouldn't both cancel an edit and close a subpage) - e.stopPropagation(); - } - if (endEdit) { - // Blurring will trigger the edit to end; see InlineEditableItemList. - this.ownerDocument.activeElement.blur(); - } - }, - - /** - * Called when the list item is clicked. If the click target corresponds to - * an editable item, stores that item to focus when edit mode is started. - * @param {Event} e The mouse down event. - * @private - */ - handleMouseDown_: function(e) { - if (!this.editable) - return; - - var clickTarget = e.target; - var editFields = this.editFields_; - var editClickTarget; - for (var i = 0; i < editFields.length; i++) { - if (editFields[i] == clickTarget || - editFields[i].staticVersion == clickTarget) { - editClickTarget = editFields[i]; - break; - } - } - - if (this.editing) { - if (!editClickTarget) { - // Clicked on the list item outside of an edit field. Don't lose focus - // from currently selected edit field. - e.stopPropagation(); - e.preventDefault(); - } - return; - } - - if (editClickTarget && !editClickTarget.disabled) - this.editClickTarget_ = editClickTarget; - }, - - /** - * Called when this InlineEditableItem or any of its children are given - * focus. Updates focusedColumnIndex with the index of the newly focused - * column, or -1 if the focused element does not have a column index. - * @param {Event} e The focusin event. - * @private - */ - handleFocusIn_: function(e) { - var target = e.target.editableVersion || e.target; - this.focusedColumnIndex = target.hasAttribute('inlineeditable-column') ? - parseInt(target.getAttribute('inlineeditable-column'), 10) : -1; - }, - }; - - /** - * Takes care of committing changes to inline editable list items when the - * window loses focus. - */ - function handleWindowBlurs() { - window.addEventListener('blur', function(e) { - var itemAncestor = findAncestor(document.activeElement, function(node) { - return node instanceof InlineEditableItem; - }); - if (itemAncestor) - document.activeElement.blur(); - }); - } - handleWindowBlurs(); - - /** - * @constructor - * @extends {options.DeletableItemList} - */ - var InlineEditableItemList = cr.ui.define('list'); - - InlineEditableItemList.prototype = { - __proto__: DeletableItemList.prototype, - - /** - * Whether to ignore list change events. - * Used to modify the list without processing selection change and lead - * change events. - * @type {boolean} - * @private - */ - ignoreChangeEvents_: false, - - /** - * Focuses the input element of the placeholder if true. - * @type {boolean} - * @private - */ - needsToFocusPlaceholder_: false, - - /** @override */ - decorate: function() { - DeletableItemList.prototype.decorate.call(this); - this.setAttribute('inlineeditable', ''); - this.addEventListener('hasElementFocusChange', - this.handleListFocusChange_); - // <list> isn't focusable by default, but cr.ui.List defaults tabindex to - // 0 if it's not set. - this.tabIndex = -1; - }, - - /** - * Called when the list hierarchy as a whole loses or gains focus; starts - * or ends editing for the lead item if necessary. - * @param {Event} e The change event. - * @private - */ - handleListFocusChange_: function(e) { - var leadItem = this.getListItemByIndex(this.selectionModel.leadIndex); - if (leadItem) { - if (e.newValue) { - // Add focusability before making other changes. - leadItem.setEditableValuesFocusable(true); - leadItem.setCloseButtonFocusable(true); - leadItem.focusedColumnIndex = -1; - leadItem.updateEditState(); - // Remove focusability after making other changes. - leadItem.setStaticValuesFocusable(false); - } else { - // Add focusability before making other changes. - leadItem.setStaticValuesFocusable(true); - leadItem.setCloseButtonFocusable(true); - leadItem.editing = false; - // Remove focusability after making other changes. - if (!leadItem.isPlaceholder) - leadItem.setEditableValuesFocusable(false); - } - } - }, - - /** @override */ - handleLeadChange: function(e) { - if (this.ignoreChangeEvents_) - return; - - DeletableItemList.prototype.handleLeadChange.call(this, e); - - var focusedColumnIndex = -1; - if (e.oldValue != -1) { - var element = this.getListItemByIndex(e.oldValue); - if (element) { - focusedColumnIndex = element.focusedColumnIndex; - element.updateLeadState(); - } - } - - if (e.newValue != -1) { - var element = this.getListItemByIndex(e.newValue); - if (element) { - element.focusedColumnIndex = focusedColumnIndex; - element.updateLeadState(); - } - } - }, - - /** @override */ - onSetDataModelComplete: function() { - DeletableItemList.prototype.onSetDataModelComplete.call(this); - - if (this.needsToFocusPlaceholder_) { - this.focusPlaceholder(); - } else { - var item = this.getInitialFocusableItem(); - if (item) { - item.setStaticValuesFocusable(true); - item.setCloseButtonFocusable(true); - if (item.isPlaceholder) - item.setEditableValuesFocusable(true); - } - } - }, - - /** - * Execute |callback| with list change events disabled. Selection change and - * lead change events will not be processed. - * @param {!Function} callback The function to execute. - * @protected - */ - ignoreChangeEvents: function(callback) { - assert(!this.ignoreChangeEvents_); - this.ignoreChangeEvents_ = true; - callback(); - this.ignoreChangeEvents_ = false; - }, - - /** - * Set the selected index without changing the focused element on the page. - * Used to change the selected index when the list doesn't have focus (and - * doesn't want to take focus). - * @param {number} index The index to select. - */ - selectIndexWithoutFocusing: function(index) { - // Remove focusability from old item. - var oldItem = this.getListItemByIndex(this.selectionModel.leadIndex) || - this.getInitialFocusableItem(); - if (oldItem) { - oldItem.setEditableValuesFocusable(false); - oldItem.setStaticValuesFocusable(false); - oldItem.setCloseButtonFocusable(false); - oldItem.lead = false; - } - - // Select the new item. - this.ignoreChangeEvents(function() { - this.selectionModel.selectedIndex = index; - }.bind(this)); - - // Add focusability to new item. - var newItem = this.getListItemByIndex(index); - if (newItem) { - if (newItem.isPlaceholder) - newItem.setEditableValuesFocusable(true); - else - newItem.setStaticValuesFocusable(true); - - newItem.setCloseButtonFocusable(true); - newItem.lead = true; - } - }, - - /** - * Focus the placeholder's first input field. - * Should only be called immediately after the list has been repopulated. - */ - focusPlaceholder: function() { - // Remove focusability from initial item. - var item = this.getInitialFocusableItem(); - if (item) { - item.setStaticValuesFocusable(false); - item.setCloseButtonFocusable(false); - } - // Find placeholder and focus it. - for (var i = 0; i < this.dataModel.length; i++) { - var item = this.getListItemByIndex(i); - if (item.isPlaceholder) { - item.setEditableValuesFocusable(true); - item.setCloseButtonFocusable(true); - item.querySelector('input').focus(); - return; - } - } - }, - - /** - * May be overridden by subclasses to disable focusing the placeholder. - * @return {boolean} True if the placeholder element should be focused on - * edit commit. - * @protected - */ - shouldFocusPlaceholderOnEditCommit: function() { - return true; - }, - - /** - * Override to change which item is initially focusable. - * @return {options.InlineEditableItem} Initially focusable item or null. - * @protected - */ - getInitialFocusableItem: function() { - return /** @type {options.InlineEditableItem} */( - this.getListItemByIndex(0)); - }, - }; - - // Export - return { - InlineEditableItem: InlineEditableItem, - InlineEditableItemList: InlineEditableItemList, - }; -});
diff --git a/chrome/browser/resources/options/language_add_language_overlay.html b/chrome/browser/resources/options/language_add_language_overlay.html deleted file mode 100644 index c95a56a..0000000 --- a/chrome/browser/resources/options/language_add_language_overlay.html +++ /dev/null
@@ -1,17 +0,0 @@ -<div id="add-language-overlay-page" class="page" role="dialog" hidden> - <div class="close-button"></div> - <h1>$i18n{addLanguageTitle}</h1> - <div class="content-area"> - <label id="add-language-overlay-language-list-label"> - $i18n{addLanguageSelectLabel} - </label> - <select id="add-language-overlay-language-list" - aria-labelledby="add-language-overlay-language-list-label"></select> - </div> - <div class="action-area button-strip"> - <button id="add-language-overlay-cancel-button">$i18n{cancel}</button> - <button id="add-language-overlay-ok-button" class="default-button"> - $i18n{ok} - </button> - </div> -</div>
diff --git a/chrome/browser/resources/options/language_add_language_overlay.js b/chrome/browser/resources/options/language_add_language_overlay.js deleted file mode 100644 index 9ea8904..0000000 --- a/chrome/browser/resources/options/language_add_language_overlay.js +++ /dev/null
@@ -1,75 +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. - -/////////////////////////////////////////////////////////////////////////////// -// AddLanguageOverlay class: - -/** - * @typedef {{ - * code: string, - * displayName: string, - * textDirection: string, - * nativeDisplayName: string - * }} - */ -options.LanguageData; - -cr.define('options', function() { - /** @const */ var Page = cr.ui.pageManager.Page; - /** @const */ var PageManager = cr.ui.pageManager.PageManager; - - /** - * Encapsulated handling of ChromeOS add language overlay page. - * @constructor - * @extends {cr.ui.pageManager.Page} - */ - function AddLanguageOverlay() { - Page.call(this, 'addLanguage', - loadTimeData.getString('addButton'), - 'add-language-overlay-page'); - } - - cr.addSingletonGetter(AddLanguageOverlay); - - AddLanguageOverlay.prototype = { - // Inherit AddLanguageOverlay from Page. - __proto__: Page.prototype, - - /** @override */ - initializePage: function() { - Page.prototype.initializePage.call(this); - - // Set up the cancel button. - $('add-language-overlay-cancel-button').onclick = function(e) { - PageManager.closeOverlay(); - }; - - // Create the language list with which users can add a language. - var addLanguageList = $('add-language-overlay-language-list'); - - /** - * @type {!Array<!options.LanguageData>} - * @see chrome/browser/ui/webui/options/language_options_handler.cc - */ - var languageListData = /** @type {!Array<!options.LanguageData>} */( - loadTimeData.getValue('languageList')); - for (var i = 0; i < languageListData.length; i++) { - var language = languageListData[i]; - var displayText = language.displayName; - // If the native name is different, add it. - if (language.displayName != language.nativeDisplayName) - displayText += ' - ' + language.nativeDisplayName; - - var option = cr.doc.createElement('option'); - option.value = language.code; - option.textContent = displayText; - addLanguageList.appendChild(option); - } - }, - }; - - return { - AddLanguageOverlay: AddLanguageOverlay - }; -});
diff --git a/chrome/browser/resources/options/language_dictionary_overlay.css b/chrome/browser/resources/options/language_dictionary_overlay.css deleted file mode 100644 index a02c181..0000000 --- a/chrome/browser/resources/options/language_dictionary_overlay.css +++ /dev/null
@@ -1,47 +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. */ - -#language-dictionary-overlay-no-matches { - line-height: 2.5em; - margin-bottom: 0; - margin-top: 0; - padding: 0 3px; -} - -#language-dictionary-overlay-page h1 { - margin-right: 16em; - padding-top: 25px; -} - -html[dir=rtl] #language-dictionary-overlay-page h1 { - margin-left: 16em; - margin-right: auto; -} - -#language-dictionary-overlay-search-field { - position: absolute; - right: 32px; - top: 21px; -} - -html[dir=rtl] #language-dictionary-overlay-search-field { - left: 32px; - right: auto; -} - -#language-dictionary-overlay-word-list { - height: 20em; -} - -#language-dictionary-overlay-word-list.no-search-matches { - height: 17.5em; -} - -#language-dictionary-overlay-word-list > * { - height: 2.5em; -} - -.language-dictionary-overlay-word-list-item { - width: 30em; -}
diff --git a/chrome/browser/resources/options/language_dictionary_overlay.html b/chrome/browser/resources/options/language_dictionary_overlay.html deleted file mode 100644 index 9e1a67f..0000000 --- a/chrome/browser/resources/options/language_dictionary_overlay.html +++ /dev/null
@@ -1,21 +0,0 @@ -<div id="language-dictionary-overlay-page" class="page" hidden> - <div class="close-button"></div> - <h1>$i18n{languageDictionaryOverlayTitle}</h1> - <input id="language-dictionary-overlay-search-field" type="search" - placeholder="$i18n{languageDictionaryOverlaySearchPlaceholder}" - aria-label="$i18n{languageDictionaryOverlaySearchPlaceholder}" - incremental> - <div class="content-area"> - <div class="settings-list"> - <p id="language-dictionary-overlay-no-matches" hidden> - $i18n{languageDictionaryOverlayNoMatches} - </p> - <list id="language-dictionary-overlay-word-list"></list> - </div> - </div> - <div class="action-area button-strip"> - <button id="language-dictionary-overlay-done-button" class="default-button"> - $i18n{done} - </button> - </div> -</div>
diff --git a/chrome/browser/resources/options/language_dictionary_overlay.js b/chrome/browser/resources/options/language_dictionary_overlay.js deleted file mode 100644 index 6f7a4a2c..0000000 --- a/chrome/browser/resources/options/language_dictionary_overlay.js +++ /dev/null
@@ -1,117 +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. - -cr.define('options', function() { - /** @const */ var DictionaryWordsList = - options.dictionary_words.DictionaryWordsList; - /** @const */ var Page = cr.ui.pageManager.Page; - /** @const */ var PageManager = cr.ui.pageManager.PageManager; - - /** - * Adding and removing words in custom spelling dictionary. - * @constructor - * @extends {cr.ui.pageManager.Page} - */ - function EditDictionaryOverlay() { - Page.call(this, 'editDictionary', - loadTimeData.getString('languageDictionaryOverlayPage'), - 'language-dictionary-overlay-page'); - } - - cr.addSingletonGetter(EditDictionaryOverlay); - - EditDictionaryOverlay.prototype = { - __proto__: Page.prototype, - - /** - * A list of words in the dictionary. - * @type {options.dictionary_words.DictionaryWordsList} - * @private - */ - wordList_: null, - - /** - * The input field for searching for words in the dictionary. - * @type {HTMLElement} - * @private - */ - searchField_: null, - - /** - * The paragraph of text that indicates that search returned no results. - * @type {HTMLElement} - * @private - */ - noMatchesLabel_: null, - - /** @override */ - initializePage: function() { - Page.prototype.initializePage.call(this); - - var wordList = $('language-dictionary-overlay-word-list'); - DictionaryWordsList.decorate(wordList); - this.wordList_ = assertInstanceof(wordList, DictionaryWordsList); - this.wordList_.onWordListChanged = function() { - this.onWordListChanged_(); - }.bind(this); - - this.searchField_ = $('language-dictionary-overlay-search-field'); - this.searchField_.onsearch = function(e) { - this.wordList_.search(e.currentTarget.value); - }.bind(this); - this.searchField_.onkeydown = function(e) { - // Don't propagate enter key events. Otherwise the default button will - // activate. - if (e.key == 'Enter') - e.stopPropagation(); - }; - - this.noMatchesLabel_ = getRequiredElement( - 'language-dictionary-overlay-no-matches'); - - $('language-dictionary-overlay-done-button').onclick = function(e) { - PageManager.closeOverlay(); - }; - }, - - /** - * Refresh the dictionary words when the page is displayed. - * @override - */ - didShowPage: function() { - chrome.send('refreshDictionaryWords'); - }, - - /** - * Update the view based on the changes in the word list. - * @private - */ - onWordListChanged_: function() { - if (this.searchField_.value.length > 0 && this.wordList_.empty) { - this.noMatchesLabel_.hidden = false; - this.wordList_.classList.add('no-search-matches'); - } else { - this.noMatchesLabel_.hidden = true; - this.wordList_.classList.remove('no-search-matches'); - } - }, - }; - - EditDictionaryOverlay.setWordList = function(entries) { - EditDictionaryOverlay.getInstance().wordList_.setWordList(entries); - }; - - EditDictionaryOverlay.updateWords = function(add_words, remove_words) { - EditDictionaryOverlay.getInstance().wordList_.addWords(add_words); - EditDictionaryOverlay.getInstance().wordList_.removeWords(remove_words); - }; - - EditDictionaryOverlay.getWordListForTesting = function() { - return EditDictionaryOverlay.getInstance().wordList_; - }; - - return { - EditDictionaryOverlay: EditDictionaryOverlay - }; -});
diff --git a/chrome/browser/resources/options/language_dictionary_overlay_word_list.js b/chrome/browser/resources/options/language_dictionary_overlay_word_list.js deleted file mode 100644 index fbc868e..0000000 --- a/chrome/browser/resources/options/language_dictionary_overlay_word_list.js +++ /dev/null
@@ -1,267 +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. - -cr.define('options.dictionary_words', function() { - /** @const */ var InlineEditableItemList = options.InlineEditableItemList; - /** @const */ var InlineEditableItem = options.InlineEditableItem; - - /** - * Creates a new dictionary word list item. - * @param {string} dictionaryWord The dictionary word. - * @param {function(string)} addDictionaryWordCallback Callback for - * adding a dictionary word. - * @constructor - * @extends {options.InlineEditableItem} - */ - function DictionaryWordsListItem(dictionaryWord, addDictionaryWordCallback) { - var el = cr.doc.createElement('div'); - el.dictionaryWord_ = dictionaryWord; - el.addDictionaryWordCallback_ = addDictionaryWordCallback; - DictionaryWordsListItem.decorate(el); - return el; - } - - /** - * Decorates an HTML element as a dictionary word list item. - * @param {HTMLElement} el The element to decorate. - */ - DictionaryWordsListItem.decorate = function(el) { - el.__proto__ = DictionaryWordsListItem.prototype; - el.decorate(); - }; - - DictionaryWordsListItem.prototype = { - __proto__: InlineEditableItem.prototype, - - /** @override */ - decorate: function() { - InlineEditableItem.prototype.decorate.call(this); - if (this.dictionaryWord_ == '') - this.isPlaceholder = true; - else - this.editable = false; - - var wordEl = this.createEditableTextCell(this.dictionaryWord_); - wordEl.classList.add('weakrtl'); - wordEl.classList.add('language-dictionary-overlay-word-list-item'); - this.contentElement.appendChild(wordEl); - - var wordField = wordEl.querySelector('input'); - wordField.classList.add('language-dictionary-overlay-word-list-item'); - if (this.isPlaceholder) { - wordField.placeholder = - loadTimeData.getString('languageDictionaryOverlayAddWordLabel'); - } - - this.addEventListener('commitedit', this.onEditCommitted_.bind(this)); - }, - - /** @override */ - get hasBeenEdited() { - return this.querySelector('input').value.length > 0; - }, - - /** @override */ - updateLeadState: function() { - InlineEditableItem.prototype.updateLeadState.call(this); - - // Allow focusing the list item itself if not editable. - if (!this.editable) - this.tabIndex = this.lead ? 0 : -1; - }, - - /** @override */ - updateEditState: function() { - InlineEditableItem.prototype.updateEditState.call(this); - - // Focus the list item itself if not editable. - if (!this.editable && this.selected && this.lead) - this.focus(); - }, - - /** - * Adds a word to the dictionary. - * @param {Event} e Edit committed event. - * @private - */ - onEditCommitted_: function(e) { - var input = e.currentTarget.querySelector('input'); - this.addDictionaryWordCallback_(input.value); - input.value = ''; - }, - }; - - /** - * A list of words in the dictionary. - * @constructor - * @extends {options.InlineEditableItemList} - */ - var DictionaryWordsList = cr.ui.define('list'); - - DictionaryWordsList.prototype = { - __proto__: InlineEditableItemList.prototype, - - /** - * The function to notify that the word list has changed. - * @type {?Function} - */ - onWordListChanged: null, - - /** - * The list of all words in the dictionary. Used to generate a filtered word - * list in the |search(searchTerm)| method. - * @type {Array} - * @private - */ - allWordsList_: null, - - /** - * The list of words that the user removed, but |DictionaryWordList| has not - * received a notification of their removal yet. - * @type {Array} - * @private - */ - removedWordsList_: [], - - /** - * Adds a dictionary word. - * @param {string} dictionaryWord The word to add. - * @private - */ - addDictionaryWord_: function(dictionaryWord) { - this.allWordsList_.push(dictionaryWord); - this.dataModel.splice(this.dataModel.length - 1, 0, dictionaryWord); - this.onWordListChanged(); - chrome.send('addDictionaryWord', [dictionaryWord]); - }, - - /** - * Searches the list for the matching words. - * @param {string} searchTerm The search term. - */ - search: function(searchTerm) { - var filteredWordList = this.allWordsList_.filter( - function(element, index, array) { - return element.indexOf(searchTerm) > -1; - }); - filteredWordList.push(''); - this.dataModel = new cr.ui.ArrayDataModel(filteredWordList); - this.onWordListChanged(); - }, - - /** - * Sets the list of dictionary words. - * @param {Array} entries The list of dictionary words. - */ - setWordList: function(entries) { - this.allWordsList_ = entries.slice(0); - // Empty string is a placeholder for entering new words. - entries.push(''); - this.dataModel = new cr.ui.ArrayDataModel(entries); - this.onWordListChanged(); - }, - - /** - * Adds non-duplicate dictionary words. - * @param {Array} entries The list of dictionary words. - */ - addWords: function(entries) { - var toAdd = []; - for (var i = 0; i < entries.length; i++) { - if (this.allWordsList_.indexOf(entries[i]) == -1) { - this.allWordsList_.push(entries[i]); - toAdd.push(entries[i]); - } - } - if (toAdd.length == 0) - return; - for (var i = 0; i < toAdd.length; i++) - this.dataModel.splice(this.dataModel.length - 1, 0, toAdd[i]); - this.onWordListChanged(); - }, - - /** - * Removes dictionary words that are not in |removedWordsList_|. If a word - * is in |removedWordsList_|, then removes the word from there instead. - * @param {Array} entries The list of dictionary words. - */ - removeWords: function(entries) { - var index; - var toRemove = []; - for (var i = 0; i < entries.length; i++) { - index = this.removedWordsList_.indexOf(entries[i]); - if (index > -1) { - this.removedWordsList_.splice(index, 1); - } else { - index = this.allWordsList_.indexOf(entries[i]); - if (index > -1) { - this.allWordsList_.splice(index, 1); - toRemove.push(entries[i]); - } - } - } - if (toRemove.length == 0) - return; - for (var i = 0; i < toRemove.length; i++) { - index = this.dataModel.indexOf(toRemove[i]); - if (index > -1) - this.dataModel.splice(index, 1); - } - this.onWordListChanged(); - }, - - /** - * Returns true if the data model contains no words, otherwise returns - * false. - * @type {boolean} - */ - get empty() { - // A data model without dictionary words contains one placeholder for - // entering new words. - return this.dataModel.length < 2; - }, - - /** - * @override - * @param {string} dictionaryWord - */ - createItem: function(dictionaryWord) { - return new DictionaryWordsListItem( - dictionaryWord, - this.addDictionaryWord_.bind(this)); - }, - - /** @override */ - deleteItemAtIndex: function(index) { - // The last element in the data model is an undeletable placeholder for - // entering new words. - assert(index > -1 && index < this.dataModel.length - 1); - var item = this.dataModel.item(index); - var allWordsListIndex = this.allWordsList_.indexOf(item); - assert(allWordsListIndex > -1); - this.allWordsList_.splice(allWordsListIndex, 1); - this.dataModel.splice(index, 1); - this.removedWordsList_.push(item); - this.onWordListChanged(); - chrome.send('removeDictionaryWord', [item]); - }, - - /** @override */ - shouldFocusPlaceholderOnEditCommit: function() { - return false; - }, - - /** @override */ - getInitialFocusableItem: function() { - return /** @type {options.InlineEditableItem} */( - this.getListItemByIndex(this.selectionModel.length - 1)); - }, - }; - - return { - DictionaryWordsList: DictionaryWordsList - }; - -}); -
diff --git a/chrome/browser/resources/options/language_list.js b/chrome/browser/resources/options/language_list.js deleted file mode 100644 index 7fc79e56..0000000 --- a/chrome/browser/resources/options/language_list.js +++ /dev/null
@@ -1,444 +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. - -cr.define('options', function() { - /** @const */ var ArrayDataModel = cr.ui.ArrayDataModel; - /** @const */ var DeletableItem = options.DeletableItem; - /** @const */ var DeletableItemList = options.DeletableItemList; - /** @const */ var List = cr.ui.List; - /** @const */ var ListItem = cr.ui.ListItem; - /** @const */ var ListSingleSelectionModel = cr.ui.ListSingleSelectionModel; - - /** - * Creates a new Language list item. - * @param {Object} languageInfo The information of the language. - * @constructor - * @extends {options.DeletableItem} - */ - function LanguageListItem(languageInfo) { - var el = cr.doc.createElement('li'); - el.__proto__ = LanguageListItem.prototype; - el.language_ = languageInfo; - el.decorate(); - return el; - } - - LanguageListItem.prototype = { - __proto__: DeletableItem.prototype, - - /** - * The language code of this language. - * @type {?string} - * @private - */ - languageCode_: null, - - /** @override */ - decorate: function() { - DeletableItem.prototype.decorate.call(this); - - var languageCode = this.language_.code; - var languageOptions = options.LanguageOptions.getInstance(); - this.deletable = languageOptions.languageIsDeletable(languageCode); - this.languageCode = languageCode; - this.languageName = cr.doc.createElement('div'); - this.languageName.className = 'language-name'; - this.languageName.dir = this.language_.textDirection; - this.languageName.textContent = this.language_.displayName; - this.contentElement.appendChild(this.languageName); - this.title = this.language_.nativeDisplayName; - this.draggable = true; - }, - }; - - /** - * Creates a new language list. - * @param {Object=} opt_propertyBag Optional properties. - * @constructor - * @extends {options.DeletableItemList} - */ - var LanguageList = cr.ui.define('list'); - - /** - * Gets information of a language from the given language code. - * @param {string} languageCode Language code (ex. "fr"). - */ - LanguageList.getLanguageInfoFromLanguageCode = function(languageCode) { - // Build the language code to language info dictionary at first time. - if (!this.languageCodeToLanguageInfo_) { - this.languageCodeToLanguageInfo_ = {}; - var languageList = loadTimeData.getValue('languageList'); - for (var i = 0; i < languageList.length; i++) { - var languageInfo = languageList[i]; - this.languageCodeToLanguageInfo_[languageInfo.code] = languageInfo; - } - } - - return this.languageCodeToLanguageInfo_[languageCode]; - }; - - /** - * Returns true if the given language code is valid. - * @param {string} languageCode Language code (ex. "fr"). - */ - LanguageList.isValidLanguageCode = function(languageCode) { - // Having the display name for the language code means that the - // language code is valid. - if (LanguageList.getLanguageInfoFromLanguageCode(languageCode)) { - return true; - } - return false; - }; - - LanguageList.prototype = { - __proto__: DeletableItemList.prototype, - - // The list item being dragged. - draggedItem: null, - // The drop position information: "below" or "above". - dropPos: null, - // The preference is a CSV string that describes preferred languages - // in Chrome OS. The language list is used for showing the language - // list in "Language and Input" options page. - preferredLanguagesPref: 'settings.language.preferred_languages', - // The preference is a CSV string that describes accept languages used - // for content negotiation. To be more precise, the list will be used - // in "Accept-Language" header in HTTP requests. - acceptLanguagesPref: 'intl.accept_languages', - - /** @override */ - decorate: function() { - DeletableItemList.prototype.decorate.call(this); - this.selectionModel = new ListSingleSelectionModel; - - // HACK(arv): http://crbug.com/40902 - window.addEventListener('resize', this.redraw.bind(this)); - - // Listen to pref change. - if (cr.isChromeOS) { - Preferences.getInstance().addEventListener(this.preferredLanguagesPref, - this.handlePreferredLanguagesPrefChange_.bind(this)); - } else { - Preferences.getInstance().addEventListener(this.acceptLanguagesPref, - this.handleAcceptLanguagesPrefChange_.bind(this)); - } - - // Listen to drag and drop events. - this.addEventListener('dragstart', this.handleDragStart_.bind(this)); - this.addEventListener('dragenter', this.handleDragEnter_.bind(this)); - this.addEventListener('dragover', this.handleDragOver_.bind(this)); - this.addEventListener('drop', this.handleDrop_.bind(this)); - this.addEventListener('dragleave', this.handleDragLeave_.bind(this)); - }, - - /** - * @override - * @param {string} languageCode - */ - createItem: function(languageCode) { - var languageInfo = - LanguageList.getLanguageInfoFromLanguageCode(languageCode); - return new LanguageListItem(languageInfo); - }, - - /* - * For each item, determines whether it's deletable. - */ - updateDeletable: function() { - var items = this.items; - for (var i = 0; i < items.length; ++i) { - var item = items[i]; - var languageCode = item.languageCode; - var languageOptions = options.LanguageOptions.getInstance(); - item.deletable = languageOptions.languageIsDeletable(languageCode); - } - }, - - /** - * Adds a language to the language list. - * @param {string} languageCode language code (ex. "fr"). - */ - addLanguage: function(languageCode) { - // It shouldn't happen but ignore the language code if it's - // null/undefined, or already present. - if (!languageCode || this.dataModel.indexOf(languageCode) >= 0) { - return; - } - this.dataModel.push(languageCode); - // Select the last item, which is the language added. - this.selectionModel.selectedIndex = this.dataModel.length - 1; - - this.savePreference_(); - }, - - /** - * Gets the language codes of the currently listed languages. - */ - getLanguageCodes: function() { - return this.dataModel.slice(); - }, - - /** - * Clears the selection - */ - clearSelection: function() { - this.selectionModel.unselectAll(); - }, - - /** - * Gets the language code of the selected language. - */ - getSelectedLanguageCode: function() { - return this.selectedItem; - }, - - /** - * Selects the language by the given language code. - * @return {boolean} True if the operation is successful. - */ - selectLanguageByCode: function(languageCode) { - var index = this.dataModel.indexOf(languageCode); - if (index >= 0) { - this.selectionModel.selectedIndex = index; - return true; - } - return false; - }, - - /** @override */ - deleteItemAtIndex: function(index) { - if (index >= 0) { - this.dataModel.splice(index, 1); - // Once the selected item is removed, there will be no selected item. - // Select the item pointed by the lead index. - index = this.selectionModel.leadIndex; - this.savePreference_(); - } - return index; - }, - - /** - * Computes the target item of drop event. - * @param {Event} e The drop or dragover event. - * @private - */ - getTargetFromDropEvent_: function(e) { - var target = e.target; - // e.target may be an inner element of the list item - while (target != null && !(target instanceof ListItem)) { - target = target.parentNode; - } - return target; - }, - - /** - * Handles the dragstart event. - * @param {Event} e The dragstart event. - * @private - */ - handleDragStart_: function(e) { - var target = e.target; - // ListItem should be the only draggable element type in the page, - // but just in case. - if (target instanceof ListItem) { - this.draggedItem = target; - e.dataTransfer.effectAllowed = 'move'; - // We need to put some kind of data in the drag or it will be - // ignored. Use the display name in case the user drags to a text - // field or the desktop. - e.dataTransfer.setData('text/plain', target.title); - } - }, - - /** - * Handles the dragenter event. - * @param {Event} e The dragenter event. - * @private - */ - handleDragEnter_: function(e) { - e.preventDefault(); - }, - - /** - * Handles the dragover event. - * @param {Event} e The dragover event. - * @private - */ - handleDragOver_: function(e) { - var dropTarget = this.getTargetFromDropEvent_(e); - // Determines whether the drop target is to accept the drop. - // The drop is only successful on another ListItem. - if (!(dropTarget instanceof ListItem) || - dropTarget == this.draggedItem) { - this.hideDropMarker_(); - return; - } - // Compute the drop postion. Should we move the dragged item to - // below or above the drop target? - var rect = dropTarget.getBoundingClientRect(); - var dy = e.clientY - rect.top; - var yRatio = dy / rect.height; - var dropPos = yRatio <= .5 ? 'above' : 'below'; - this.dropPos = dropPos; - this.showDropMarker_(dropTarget, dropPos); - e.preventDefault(); - }, - - /** - * Handles the drop event. - * @param {Event} e The drop event. - * @private - */ - handleDrop_: function(e) { - var dropTarget = this.getTargetFromDropEvent_(e); - this.hideDropMarker_(); - - // Delete the language from the original position. - var languageCode = this.draggedItem.languageCode; - var originalIndex = this.dataModel.indexOf(languageCode); - this.dataModel.splice(originalIndex, 1); - // Insert the language to the new position. - var newIndex = this.dataModel.indexOf(dropTarget.languageCode); - if (this.dropPos == 'below') - newIndex += 1; - this.dataModel.splice(newIndex, 0, languageCode); - // The cursor should move to the moved item. - this.selectionModel.selectedIndex = newIndex; - // Save the preference. - this.savePreference_(); - }, - - /** - * Handles the dragleave event. - * @param {Event} e The dragleave event - * @private - */ - handleDragLeave_: function(e) { - this.hideDropMarker_(); - }, - - /** - * Shows and positions the marker to indicate the drop target. - * @param {HTMLElement} target The current target list item of drop - * @param {string} pos 'below' or 'above' - * @private - */ - showDropMarker_: function(target, pos) { - window.clearTimeout(this.hideDropMarkerTimer_); - var marker = $('language-options-list-dropmarker'); - var rect = target.getBoundingClientRect(); - var markerHeight = 8; - if (pos == 'above') { - marker.style.top = (rect.top - markerHeight / 2) + 'px'; - } else { - marker.style.top = (rect.bottom - markerHeight / 2) + 'px'; - } - marker.style.width = rect.width + 'px'; - marker.style.left = rect.left + 'px'; - marker.style.display = 'block'; - }, - - /** - * Hides the drop marker. - * @private - */ - hideDropMarker_: function() { - // Hide the marker in a timeout to reduce flickering as we move between - // valid drop targets. - window.clearTimeout(this.hideDropMarkerTimer_); - this.hideDropMarkerTimer_ = window.setTimeout(function() { - $('language-options-list-dropmarker').style.display = ''; - }, 100); - }, - - /** - * Handles preferred languages pref change. - * @param {Event} e The change event object. - * @private - */ - handlePreferredLanguagesPrefChange_: function(e) { - var languageCodesInCsv = e.value.value; - var languageCodes = languageCodesInCsv.split(','); - - // Add the UI language to the initial list of languages. This is to avoid - // a bug where the UI language would be removed from the preferred - // language list by sync on first login. - // See: crosbug.com/14283 - languageCodes.push(navigator.language); - languageCodes = this.filterBadLanguageCodes_(languageCodes); - this.load_(languageCodes); - }, - - /** - * Handles accept languages pref change. - * @param {Event} e The change event object. - * @private - */ - handleAcceptLanguagesPrefChange_: function(e) { - var languageCodesInCsv = e.value.value; - var languageCodes = this.filterBadLanguageCodes_( - languageCodesInCsv.split(',')); - this.load_(languageCodes); - }, - - /** - * Loads given language list. - * @param {!Array} languageCodes List of language codes. - * @private - */ - load_: function(languageCodes) { - // Preserve the original selected index. See comments below. - var originalSelectedIndex = this.selectionModel.selectedIndex; - this.dataModel = new ArrayDataModel(languageCodes); - if (originalSelectedIndex >= 0 && - originalSelectedIndex < this.dataModel.length) { - // Restore the original selected index if the selected index is - // valid after the data model is loaded. This is needed to keep - // the selected language after the languge is added or removed. - this.selectionModel.selectedIndex = originalSelectedIndex; - // The lead index should be updated too. - this.selectionModel.leadIndex = originalSelectedIndex; - } else if (this.dataModel.length > 0) { - // Otherwise, select the first item if it's not empty. - // Note that ListSingleSelectionModel won't select an item - // automatically, hence we manually select the first item here. - this.selectionModel.selectedIndex = 0; - } - }, - - /** - * Saves the preference. - */ - savePreference_: function() { - chrome.send('updateLanguageList', [this.dataModel.slice()]); - cr.dispatchSimpleEvent(this, 'save'); - }, - - /** - * Filters bad language codes in case bad language codes are - * stored in the preference. Removes duplicates as well. - * @param {Array} languageCodes List of language codes. - * @private - */ - filterBadLanguageCodes_: function(languageCodes) { - var filteredLanguageCodes = []; - var seen = {}; - for (var i = 0; i < languageCodes.length; i++) { - // Check if the the language code is valid, and not - // duplicate. Otherwise, skip it. - if (LanguageList.isValidLanguageCode(languageCodes[i]) && - !(languageCodes[i] in seen)) { - filteredLanguageCodes.push(languageCodes[i]); - seen[languageCodes[i]] = true; - } - } - return filteredLanguageCodes; - }, - }; - - return { - LanguageList: LanguageList, - LanguageListItem: LanguageListItem - }; -});
diff --git a/chrome/browser/resources/options/language_options.css b/chrome/browser/resources/options/language_options.css deleted file mode 100644 index e34f513..0000000 --- a/chrome/browser/resources/options/language_options.css +++ /dev/null
@@ -1,192 +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. */ - -#languagePage .content-area { - width: 660px; -} - -.language-options { - display: -webkit-box; - margin: 10px 0; -} - -.language-options-lower-left button, -#language-options-details button { - min-width: 70px; -} - -.language-options h3 { - -webkit-margin-start: 12px; - font-size: 100%; - font-weight: bold; - margin-bottom: 12px; - margin-top: 12px; -} - -.language-options-contents { - min-height: 28px; - padding: 0 12px 4px; -} - -.language-options-contents > - span:not(.input-method-label):not(.controlled-setting-indicator) { - display: inline-block; - margin: 1px; - padding: 0.42em 10px; -} - -.language-options-header, -.language-options-footer { - margin: 10px 0; -} - -#language-options-languages, -#language-options-details { - border: 1px solid #ccc; - height: 369px; - padding: 0; - vertical-align: top; -} - -#language-options-languages { - -webkit-box-orient: vertical; - background-color: rgb(235, 239, 249); - display: -webkit-box; - width: 300px; -} - -.language-options-lower-left { - -webkit-box-flex: 0; - -webkit-padding-start: 12px; - padding-bottom: 10px; -} - -#language-options-details { - -webkit-box-flex: 1; - /* To share the center line with the left pane. */ - -webkit-margin-start: -1px; - overflow-y: auto; -} - -#language-options-details h3:not(:first-of-type) { - margin-top: 24px; -} - -.language-options-notification { - background-color: rgb(255, 247, 193); - margin: 0 0 4px; - padding: 8px 30px 8px 12px; -} - -.language-options-notification > div { - margin-bottom: 4px; -} - -#language-options-input-method-list button { - -webkit-margin-start: 20px; - display: block; - /* Same margin as .settings-row. */ - margin-bottom: 0.65em; - margin-top: 0.65em; -} - -#language-options-list { - -webkit-box-flex: 1; - outline: none; - padding: 0; - width: 100%; -} - -#language-options-list .language-name { - -webkit-box-flex: 1; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} - -#language-options-list li { - -webkit-padding-start: 12px; - padding-bottom: 2px; - padding-top: 2px; -} - -#language-options-list-dropmarker { - background-clip: padding-box; - background-color: hsl(214, 91%, 65%); - border: 3px solid hsl(214, 91%, 65%); - border-bottom-color: transparent; - border-radius: 0; - border-top-color: transparent; - box-sizing: border-box; - display: none; - height: 8px; - overflow: hidden; - pointer-events: none; - position: fixed; - z-index: 10; -} - -/* TODO(kochi): This is temporary copy from new_tab.css */ -/* Notification */ - -#notification { - background-color: hsl(52, 100%, 80%); - border: 1px solid rgb(211, 211, 211); - border-radius: 6px; - color: black; - display: table; - font-weight: bold; - /* Set the height and margin so that the element does not use any vertical - space. */ - height: 16px; - margin: -44px auto 12px auto; - opacity: 0; - padding: 7px 15px; - pointer-events: none; - position: relative; - transition: opacity 150ms; - white-space: nowrap; - z-index: 1; -} - -#notification > * { - display: table-cell; - max-width: 500px; - overflow: hidden; - text-overflow: ellipsis; -} - -#notification.show { - opacity: 1; - pointer-events: all; - transition: opacity 1s; -} - -#notification .link { - -webkit-appearance: none; - -webkit-padding-start: 20px; - background: none; - border: 0; - color: rgba(0, 102, 204, 0.3); - cursor: pointer; - text-decoration: underline; -} - -#notification .link-color { - color: rgb(0, 102, 204); -} - -#chewing-max-chi-symbol-len { - height: 30%; - width: 100px; -} - -#add-language-overlay-page .content-area { - padding-bottom: 10px; -} - -/* TODO(hshi): Remove this temporary hack once the bug is fixed in Chrome. */ -#add-language-overlay-language-list { - width: -webkit-calc(100% - 4px); -}
diff --git a/chrome/browser/resources/options/language_options.html b/chrome/browser/resources/options/language_options.html deleted file mode 100644 index 7f9f33a..0000000 --- a/chrome/browser/resources/options/language_options.html +++ /dev/null
@@ -1,142 +0,0 @@ -<div id="languagePage" class="page" hidden> - <div class="close-button"></div> - <h1>$i18n{languagePage}</h1> - <div class="content-area"> - <div id="notification"> - <span> </span> - <span class="link"><span class="link-color"></span></span> - </div> - <div class="language-options-header"> - <span>$i18n{addLanguageInstructions}</span> -<if expr="chromeos"> - <span>$i18n{inputMethodInstructions}</span> -</if> - <a target="_blank" - href="$i18nRaw{languagesLearnMoreURL}">$i18n{learnMore}</a> - </div> - <div class="language-options"> - <div id="language-options-languages"> - <h3>$i18n{languages}</h3> - <list id="language-options-list"></list> - <div class="language-options-lower-left"> - <button id="language-options-add-button">$i18n{addButton}</button> - </div> - <div id="language-options-list-dropmarker"></div> - </div> - <div id="language-options-details"> - <h3 id="language-options-language-name"></h3> -<if expr="os == 'win32' or chromeos"> - <div id="language-options-ui-language-section" - class="language-options-contents"> - <button id="language-options-ui-language-button"> - $i18n{displayInThisLanguage} - </button> - <span class="controlled-setting-indicator"></span> - <span id="language-options-ui-language-message" hidden></span> - </div> -</if> -<!-- Chrome uses the native OS spellchecker in OS X, so don't display the - dictionary pane. --> -<if expr="not is_macosx"> - <div id="language-options-spellcheck" class="language-options-contents"> - <div class="checkbox" id="spellcheck-language-checkbox-container"> - <label> - <input type="checkbox" id="spellcheck-language-checkbox"> - <span>$i18n{useThisForSpellChecking}</span> - </label> - </div> - <span id="spellcheck-language-message" hidden></span> - <span id="language-options-dictionary-downloading-message" hidden> - $i18n{downloadingDictionary} - </span> - </div> - <div id="language-options-dictionary-download-failed-message" - class="language-options-notification" hidden> - <div>$i18n{downloadFailed}</div> - <div id="language-options-dictionary-download-fail-help-message" - hidden> - $i18n{downloadFailHelp} - </div> - <button id="dictionary-download-retry-button"> - $i18n{retryButton} - </button> - </div> - <div id="language-options-ui-notification-bar" - class="language-options-notification" hidden> - <div>$i18n{restartRequired}</div> -<if expr="chromeos"> - <button id="language-options-ui-restart-button"> - $i18n{restartButton} - </button> -</if> - </div> -</if> - <div id="language-options-offer-to-translate" - class="language-options-contents" hidden> - <div class="checkbox"> - <label> - <input type="checkbox" id="offer-to-translate-in-this-language"> - <span class="offer-to-translate-label"> - $i18n{offerToTranslateInThisLanguage} - </span> - </label> - </div> - <span id="cannot-translate-in-this-language" hidden> - $i18n{cannotTranslateInThisLanguage} - </span> - </div> -<if expr="chromeos"> - <h3>$i18n{inputMethod}</h3> - <div id="language-options-input-method-template" class="input-method" - hidden> - <div class="checkbox"> - <label> - <input type="checkbox"> - <span class="input-method-label"></span> - </label> - </div> - </div> - <div id="language-options-input-method-list" - class="language-options-contents"> - <span id="language-options-input-method-none" hidden> - $i18n{noInputMethods} - </span> - </div> -</if> - </div> - </div> - <div class="language-options-footer"> -<if expr="chromeos"> - <div>$i18n{switchInputMethodsHint}</div> - <div>$i18n{selectPreviousInputMethodHint}</div> - <a is="action-link" id="edit-custom-dictionary-button" - class="standalone-action-link"> - $i18n{languageDictionaryOverlayTitle} - </a> - <div id="language-options-ime-menu-template" class="checkbox" hidden> - <label> - <input type="checkbox" id="activate-ime-menu"> - <span>$i18n{activateImeMenu}</span> - </label> - </div> -</if> -<if expr="not chromeos and not is_macosx"> - <div class="checkbox"> - <label id="enable-spellcheck-container"> - <input id="enable-spellcheck" pref="browser.enable_spellchecking" - metric="Options_SpellCheck" type="checkbox"> - <span>$i18n{enableSpellCheck}</span> - </label> - <a is="action-link" id="edit-custom-dictionary-button" hidden> - $i18n{languageDictionaryOverlayTitle} - </a> - </div> -</if> - </div> - </div> - <div class="action-area"> - <div class="button-strip"> - <button id="language-confirm" class="default-button">$i18n{done}</button> - </div> - </div> -</div>
diff --git a/chrome/browser/resources/options/language_options.js b/chrome/browser/resources/options/language_options.js deleted file mode 100644 index 0e85622..0000000 --- a/chrome/browser/resources/options/language_options.js +++ /dev/null
@@ -1,1446 +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. - -// TODO(kochi): Generalize the notification as a component and put it -// in js/cr/ui/notification.js . - -cr.define('options', function() { - /** @const */ var Page = cr.ui.pageManager.Page; - /** @const */ var PageManager = cr.ui.pageManager.PageManager; - /** @const */ var LanguageList = options.LanguageList; - /** @const */ var ThirdPartyImeConfirmOverlay = - options.ThirdPartyImeConfirmOverlay; - - /** - * Spell check dictionary download status. - * @type {Enum} - */ - /** @const*/ var DOWNLOAD_STATUS = { - IN_PROGRESS: 1, - FAILED: 2 - }; - - /** - * The preference is a boolean that enables/disables spell checking. - * @type {string} - * @const - */ - var ENABLE_SPELL_CHECK_PREF = 'browser.enable_spellchecking'; - - /** - * The preference is a CSV string that describes preload engines - * (i.e. active input methods). - * @type {string} - * @const - */ - var PRELOAD_ENGINES_PREF = 'settings.language.preload_engines'; - - /** - * The preference that lists the extension IMEs that are enabled in the - * language menu. - * @type {string} - * @const - */ - var ENABLED_EXTENSION_IME_PREF = 'settings.language.enabled_extension_imes'; - - /** - * The preference that lists the languages which are not translated. - * @type {string} - * @const - */ - var TRANSLATE_BLOCKED_LANGUAGES_PREF = 'translate_blocked_languages'; - - /** - * The preference key that is a list of strings that describes the spellcheck - * dictionary language, like ["en-US", "fr"]. - * @type {string} - * @const - */ - var SPELL_CHECK_DICTIONARIES_PREF = 'spellcheck.dictionaries'; - - /** - * The preference that indicates if the Translate feature is enabled. - * @type {string} - * @const - */ - var ENABLE_TRANSLATE = 'translate.enabled'; - - /** - * The preference is a boolean that activates/deactivates IME menu on shelf. - * @type {string} - * @const - */ - var ACTIVATE_IME_MENU_PREF = 'settings.language.ime_menu_activated'; - - ///////////////////////////////////////////////////////////////////////////// - // LanguageOptions class: - - /** - * Encapsulated handling of ChromeOS language options page. - * @constructor - * @extends {cr.ui.pageManager.Page} - */ - function LanguageOptions(model) { - Page.call(this, 'languages', - loadTimeData.getString('languagePageTabTitle'), 'languagePage'); - } - - cr.addSingletonGetter(LanguageOptions); - - // Inherit LanguageOptions from Page. - LanguageOptions.prototype = { - __proto__: Page.prototype, - - /** - * For recording the prospective language (the next locale after relaunch). - * @type {?string} - * @private - */ - prospectiveUiLanguageCode_: null, - - /** - * Map from language code to spell check dictionary download status for that - * language. - * @type {!Object} - * @private - */ - spellcheckDictionaryDownloadStatus_: {}, - - /** - * Number of times a spell check dictionary download failed. - * @type {number} - * @private - */ - spellcheckDictionaryDownloadFailures_: 0, - - /** - * The list of preload engines, like ['mozc', 'pinyin']. - * @type {Array} - * @private - */ - preloadEngines_: [], - - /** - * The list of extension IMEs that are enabled out of the language menu. - * @type {Array} - * @private - */ - enabledExtensionImes_: [], - - /** - * The list of the languages which is not translated. - * @type {Array} - * @private - */ - translateBlockedLanguages_: [], - - /** - * The list of the languages supported by Translate server - * @type {Array} - * @private - */ - translateSupportedLanguages_: [], - - /** - * The dictionary of currently selected spellcheck dictionary languages, - * like {"en-US": true, "sl-SI": true}. - * @type {!Object} - * @private - */ - spellCheckLanguages_: {}, - - /** - * The map of language code to input method IDs, like: - * {'ja': ['mozc', 'mozc-jp'], 'zh-CN': ['pinyin'], ...} - * @type {Object} - * @private - */ - languageCodeToInputMethodIdsMap_: {}, - - /** - * The value that indicates if Translate feature is enabled or not. - * @type {boolean} - * @private - */ - enableTranslate_: false, - - /** @override */ - initializePage: function() { - Page.prototype.initializePage.call(this); - - var languageOptionsList = $('language-options-list'); - LanguageList.decorate(languageOptionsList); - - languageOptionsList.addEventListener('change', - this.handleLanguageOptionsListChange_.bind(this)); - languageOptionsList.addEventListener('save', - this.handleLanguageOptionsListSave_.bind(this)); - - this.prospectiveUiLanguageCode_ = - loadTimeData.getString('prospectiveUiLanguageCode'); - this.addEventListener('visibleChange', - this.handleVisibleChange_.bind(this)); - - if (cr.isChromeOS) { - this.initializeInputMethodList_(); - this.initializeLanguageCodeToInputMethodIdsMap_(); - } - - var checkbox = $('offer-to-translate-in-this-language'); - checkbox.addEventListener('click', - this.handleOfferToTranslateCheckboxClick_.bind(this)); - - Preferences.getInstance().addEventListener( - TRANSLATE_BLOCKED_LANGUAGES_PREF, - this.handleTranslateBlockedLanguagesPrefChange_.bind(this)); - Preferences.getInstance().addEventListener(SPELL_CHECK_DICTIONARIES_PREF, - this.handleSpellCheckDictionariesPrefChange_.bind(this)); - Preferences.getInstance().addEventListener(ENABLE_TRANSLATE, - this.handleEnableTranslatePrefChange_.bind(this)); - this.translateSupportedLanguages_ = /** @type {Array} */( - loadTimeData.getValue('translateSupportedLanguages')); - - // Set up add button. - var onclick = function(e) { - // Add the language without showing the overlay if it's specified in - // the URL hash (ex. lang_add=ja). Used for automated testing. - var match = document.location.hash.match(/\blang_add=([\w-]+)/); - if (match) { - var addLanguageCode = match[1]; - $('language-options-list').addLanguage(addLanguageCode); - this.addBlockedLanguage_(addLanguageCode); - } else { - PageManager.showPageByName('addLanguage'); - chrome.send('coreOptionsUserMetricsAction', - ['Options_Languages_Add']); - } - }; - $('language-options-add-button').onclick = onclick.bind(this); - - if (!cr.isMac) { - // Set up the button for editing custom spelling dictionary. - $('edit-custom-dictionary-button').onclick = function(e) { - PageManager.showPageByName('editDictionary'); - }; - $('dictionary-download-retry-button').onclick = function(e) { - chrome.send('retryDictionaryDownload', - [e.currentTarget.languageCode]); - }; - } - - // Listen to add language dialog ok button. - $('add-language-overlay-ok-button').addEventListener( - 'click', this.handleAddLanguageOkButtonClick_.bind(this)); - - if (!(cr.isMac || cr.isChromeOS)) { - // Handle spell check enable/disable. - Preferences.getInstance().addEventListener( - ENABLE_SPELL_CHECK_PREF, this.updateEnableSpellCheck_.bind(this)); - } - - // Handle clicks on "Use this language for spell checking" button. - if (!cr.isMac) { - $('spellcheck-language-checkbox').addEventListener( - 'change', - this.handleSpellCheckLanguageCheckboxClick_.bind(this)); - } - - if (cr.isChromeOS) { - $('language-options-ui-restart-button').onclick = function() { - chrome.send('uiLanguageRestart'); - }; - } - - $('language-confirm').onclick = - PageManager.closeOverlay.bind(PageManager); - - // Public session users cannot change the locale. - if (cr.isChromeOS && UIAccountTweaks.loggedInAsPublicAccount()) - $('language-options-ui-language-section').hidden = true; - - // IME menu (CrOS only). - if (cr.isChromeOS) { - // Show the 'activate-ime-menu' checkbox if the flag is tured on. - if (loadTimeData.getBoolean('enableLanguageOptionsImeMenu')) - $('language-options-ime-menu-template').hidden = false; - - // Updates the initial checked state of the check box. - Preferences.getInstance().addEventListener( - ACTIVATE_IME_MENU_PREF, this.updateImeMenuCheckbox_.bind(this)); - - // Listen to check on 'activate-ime-menu' checkbox. - var checkboxImeMenu = $('activate-ime-menu'); - checkboxImeMenu.addEventListener('click', - this.handleActivateImeMenuCheckboxClick_.bind(this)); - } - }, - - /** - * Initializes the input method list. - */ - initializeInputMethodList_: function() { - var inputMethodList = $('language-options-input-method-list'); - var inputMethodPrototype = $('language-options-input-method-template'); - - // Add all input methods, but make all of them invisible here. We'll - // change the visibility in handleLanguageOptionsListChange_() based - // on the selected language. Note that we only have less than 100 - // input methods, so creating DOM nodes at once here should be ok. - this.appendInputMethodElement_(/** @type {!Array} */( - loadTimeData.getValue('inputMethodList'))); - this.appendComponentExtensionIme_(/** @type {!Array} */( - loadTimeData.getValue('componentExtensionImeList'))); - this.appendInputMethodElement_(/** @type {!Array} */( - loadTimeData.getValue('extensionImeList'))); - - // Listen to pref change once the input method list is initialized. - Preferences.getInstance().addEventListener( - PRELOAD_ENGINES_PREF, - this.handlePreloadEnginesPrefChange_.bind(this)); - Preferences.getInstance().addEventListener( - ENABLED_EXTENSION_IME_PREF, - this.handleEnabledExtensionsPrefChange_.bind(this)); - }, - - /** - * Appends input method lists based on component extension ime list. - * @param {!Array} componentExtensionImeList A list of input method - * descriptors. - * @private - */ - appendComponentExtensionIme_: function(componentExtensionImeList) { - this.appendInputMethodElement_(componentExtensionImeList); - - for (var i = 0; i < componentExtensionImeList.length; i++) { - var inputMethod = componentExtensionImeList[i]; - for (var languageCode in inputMethod.languageCodeSet) { - if (languageCode in this.languageCodeToInputMethodIdsMap_) { - this.languageCodeToInputMethodIdsMap_[languageCode].push( - inputMethod.id); - } else { - this.languageCodeToInputMethodIdsMap_[languageCode] = - [inputMethod.id]; - } - } - } - }, - - /** - * Appends input methods into input method list. - * @param {!Array} inputMethods A list of input method descriptors. - * @private - */ - appendInputMethodElement_: function(inputMethods) { - var inputMethodList = $('language-options-input-method-list'); - var inputMethodTemplate = $('language-options-input-method-template'); - - for (var i = 0; i < inputMethods.length; i++) { - var inputMethod = inputMethods[i]; - var element = inputMethodTemplate.cloneNode(true); - element.id = ''; - element.languageCodeSet = inputMethod.languageCodeSet; - - var input = element.querySelector('input'); - input.inputMethodId = inputMethod.id; - input.imeProvider = inputMethod.extensionName; - var span = element.querySelector('span'); - span.textContent = inputMethod.displayName; - - if (inputMethod.optionsPage) { - var button = document.createElement('button'); - button.textContent = loadTimeData.getString('configure'); - button.inputMethodId = inputMethod.id; - button.onclick = function(inputMethodId, e) { - chrome.send('inputMethodOptionsOpen', [inputMethodId]); - }.bind(this, inputMethod.id); - element.appendChild(button); - } - - // Listen to user clicks. - input.addEventListener('click', - this.handleCheckboxClick_.bind(this)); - inputMethodList.appendChild(element); - } - }, - - /** - * Adds a language to the preference 'translate_blocked_languages'. If - * |langCode| is already added, nothing happens. |langCode| is converted - * to a Translate language synonym before added. - * @param {string} langCode A language code like 'en' - * @private - */ - addBlockedLanguage_: function(langCode) { - langCode = this.convertLangCodeForTranslation_(langCode); - if (this.translateBlockedLanguages_.indexOf(langCode) == -1) { - this.translateBlockedLanguages_.push(langCode); - Preferences.setListPref(TRANSLATE_BLOCKED_LANGUAGES_PREF, - this.translateBlockedLanguages_, true); - } - }, - - /** - * Removes a language from the preference 'translate_blocked_languages'. - * If |langCode| doesn't exist in the preference, nothing happens. - * |langCode| is converted to a Translate language synonym before removed. - * @param {string} langCode A language code like 'en' - * @private - */ - removeBlockedLanguage_: function(langCode) { - langCode = this.convertLangCodeForTranslation_(langCode); - if (this.translateBlockedLanguages_.indexOf(langCode) != -1) { - this.translateBlockedLanguages_ = - this.translateBlockedLanguages_.filter( - function(langCodeNotTranslated) { - return langCodeNotTranslated != langCode; - }); - Preferences.setListPref(TRANSLATE_BLOCKED_LANGUAGES_PREF, - this.translateBlockedLanguages_, true); - } - }, - - /** - * Handles Page's visible property change event. - * @param {Event} e Property change event. - * @private - */ - handleVisibleChange_: function(e) { - if (this.visible) { - $('language-options-list').redraw(); - chrome.send('languageOptionsOpen'); - } - }, - - /** - * Handles languageOptionsList's change event. - * @param {Event} e Change event. - * @private - */ - handleLanguageOptionsListChange_: function(e) { - var languageOptionsList = $('language-options-list'); - var languageCode = languageOptionsList.getSelectedLanguageCode(); - - // If there's no selection, just return. - if (!languageCode) - return; - - // Select the language if it's specified in the URL hash (ex. lang=ja). - // Used for automated testing. - var match = document.location.hash.match(/\blang=([\w-]+)/); - if (match) { - var specifiedLanguageCode = match[1]; - if (languageOptionsList.selectLanguageByCode(specifiedLanguageCode)) { - languageCode = specifiedLanguageCode; - } - } - - this.updateOfferToTranslateCheckbox_(languageCode); - - if (cr.isWindows || cr.isChromeOS) - this.updateUiLanguageButton_(languageCode); - - this.updateSelectedLanguageName_(languageCode); - - if (!cr.isMac) - this.updateSpellCheckLanguageControls_(languageCode); - - if (cr.isChromeOS) - this.updateInputMethodList_(languageCode); - - this.updateLanguageListInAddLanguageOverlay_(); - }, - - /** - * Handles languageOptionsList's save event. - * @param {Event} e Save event. - * @private - */ - handleLanguageOptionsListSave_: function(e) { - if (cr.isChromeOS) { - // Sort the preload engines per the saved languages before save. - this.preloadEngines_ = this.sortPreloadEngines_(this.preloadEngines_); - this.savePreloadEnginesPref_(); - } - }, - - /** - * Sorts preloadEngines_ by languageOptionsList's order. - * @param {Array} preloadEngines List of preload engines. - * @return {Array} Returns sorted preloadEngines. - * @private - */ - sortPreloadEngines_: function(preloadEngines) { - // For instance, suppose we have two languages and associated input - // methods: - // - // - Korean: hangul - // - Chinese: pinyin - // - // The preloadEngines preference should look like "hangul,pinyin". - // If the user reverse the order, the preference should be reorderd - // to "pinyin,hangul". - var languageOptionsList = $('language-options-list'); - var languageCodes = languageOptionsList.getLanguageCodes(); - - // Convert the list into a dictonary for simpler lookup. - var preloadEngineSet = {}; - for (var i = 0; i < preloadEngines.length; i++) { - preloadEngineSet[preloadEngines[i]] = true; - } - - // Create the new preload engine list per the language codes. - var newPreloadEngines = []; - for (var i = 0; i < languageCodes.length; i++) { - var languageCode = languageCodes[i]; - var inputMethodIds = this.languageCodeToInputMethodIdsMap_[ - languageCode]; - if (!inputMethodIds) - continue; - - // Check if we have active input methods associated with the language. - for (var j = 0; j < inputMethodIds.length; j++) { - var inputMethodId = inputMethodIds[j]; - if (inputMethodId in preloadEngineSet) { - // If we have, add it to the new engine list. - newPreloadEngines.push(inputMethodId); - // And delete it from the set. This is necessary as one input - // method can be associated with more than one language thus - // we should avoid having duplicates in the new list. - delete preloadEngineSet[inputMethodId]; - } - } - } - - return newPreloadEngines; - }, - - /** - * Initializes the map of language code to input method IDs. - * @private - */ - initializeLanguageCodeToInputMethodIdsMap_: function() { - var inputMethodList = loadTimeData.getValue('inputMethodList'); - for (var i = 0; i < inputMethodList.length; i++) { - var inputMethod = inputMethodList[i]; - for (var languageCode in inputMethod.languageCodeSet) { - if (languageCode in this.languageCodeToInputMethodIdsMap_) { - this.languageCodeToInputMethodIdsMap_[languageCode].push( - inputMethod.id); - } else { - this.languageCodeToInputMethodIdsMap_[languageCode] = - [inputMethod.id]; - } - } - } - }, - - /** - * Updates the currently selected language name. - * @param {string} languageCode Language code (ex. "fr"). - * @private - */ - updateSelectedLanguageName_: function(languageCode) { - var languageInfo = LanguageList.getLanguageInfoFromLanguageCode( - languageCode); - var languageDisplayName = languageInfo.displayName; - var languageNativeDisplayName = languageInfo.nativeDisplayName; - var textDirection = languageInfo.textDirection; - - // If the native name is different, add it. - if (languageDisplayName != languageNativeDisplayName) { - languageDisplayName += ' - ' + languageNativeDisplayName; - } - - // Update the currently selected language name. - var languageName = $('language-options-language-name'); - languageName.textContent = languageDisplayName; - languageName.dir = textDirection; - }, - - /** - * Updates the UI language button. - * @param {string} languageCode Language code (ex. "fr"). - * @private - */ - updateUiLanguageButton_: function(languageCode) { - var uiLanguageButton = $('language-options-ui-language-button'); - var uiLanguageMessage = $('language-options-ui-language-message'); - var uiLanguageNotification = $('language-options-ui-notification-bar'); - - // Remove the event listener and add it back if useful. - uiLanguageButton.onclick = null; - - // Unhide the language button every time, as it could've been previously - // hidden by a language change. - uiLanguageButton.hidden = false; - - // Hide the controlled setting indicator. - var uiLanguageIndicator = document.querySelector( - '.language-options-contents .controlled-setting-indicator'); - uiLanguageIndicator.removeAttribute('controlled-by'); - - if (languageCode == this.prospectiveUiLanguageCode_) { - uiLanguageMessage.textContent = - loadTimeData.getString('isDisplayedInThisLanguage'); - showMutuallyExclusiveNodes( - [uiLanguageButton, uiLanguageMessage, uiLanguageNotification], 1); - } else if (languageCode in loadTimeData.getValue('uiLanguageCodeSet')) { - if (cr.isChromeOS && UIAccountTweaks.loggedInAsGuest()) { - // In the guest mode for ChromeOS, changing UI language does not make - // sense because it does not take effect after browser restart. - uiLanguageButton.hidden = true; - uiLanguageMessage.hidden = true; - } else { - uiLanguageButton.textContent = - loadTimeData.getString('displayInThisLanguage'); - - if (loadTimeData.valueExists('secondaryUser') && - loadTimeData.getBoolean('secondaryUser')) { - uiLanguageButton.disabled = true; - uiLanguageIndicator.setAttribute('controlled-by', 'shared'); - } else { - uiLanguageButton.onclick = function(e) { - chrome.send('uiLanguageChange', [languageCode]); - }; - } - showMutuallyExclusiveNodes( - [uiLanguageButton, uiLanguageMessage, uiLanguageNotification], 0); - } - } else { - uiLanguageMessage.textContent = - loadTimeData.getString('cannotBeDisplayedInThisLanguage'); - showMutuallyExclusiveNodes( - [uiLanguageButton, uiLanguageMessage, uiLanguageNotification], 1); - } - }, - - /** - * Updates the spell check language button/checkbox, dictionary download - * dialog, and the "Enable spell checking" checkbox. - * @param {string} languageCode Language code (ex. "fr"). - * @private - */ - updateSpellCheckLanguageControls_: function(languageCode) { - assert(languageCode); - var spellCheckLanguageSection = $('language-options-spellcheck'); - var spellCheckLanguageCheckboxContainer = - $('spellcheck-language-checkbox-container'); - var spellCheckLanguageCheckbox = $('spellcheck-language-checkbox'); - var spellCheckLanguageMessage = $('spellcheck-language-message'); - var dictionaryDownloadInProgress = - $('language-options-dictionary-downloading-message'); - var dictionaryDownloadFailed = - $('language-options-dictionary-download-failed-message'); - var dictionaryDownloadFailHelp = - $('language-options-dictionary-download-fail-help-message'); - - spellCheckLanguageSection.hidden = false; - spellCheckLanguageMessage.hidden = true; - spellCheckLanguageCheckboxContainer.hidden = true; - dictionaryDownloadInProgress.hidden = true; - dictionaryDownloadFailed.hidden = true; - dictionaryDownloadFailHelp.hidden = true; - spellCheckLanguageCheckbox.checked = false; - - var canBeUsedForSpellchecking = - languageCode in loadTimeData.getValue('spellCheckLanguageCodeSet'); - - if (!canBeUsedForSpellchecking) { - spellCheckLanguageMessage.textContent = - loadTimeData.getString('cannotBeUsedForSpellChecking'); - spellCheckLanguageMessage.hidden = false; - return; - } - - var isUsedForSpellchecking = languageCode in this.spellCheckLanguages_; - - spellCheckLanguageCheckbox.languageCode = languageCode; - spellCheckLanguageCheckbox.checked = isUsedForSpellchecking; - spellCheckLanguageCheckboxContainer.hidden = false; - - switch (this.spellcheckDictionaryDownloadStatus_[languageCode]) { - case DOWNLOAD_STATUS.IN_PROGRESS: - dictionaryDownloadInProgress.hidden = false; - break; - case DOWNLOAD_STATUS.FAILED: - showMutuallyExclusiveNodes( - [spellCheckLanguageSection, dictionaryDownloadFailed], 1); - if (this.spellcheckDictionaryDownloadFailures_ > 1) - dictionaryDownloadFailHelp.hidden = false; - $('dictionary-download-retry-button').languageCode = languageCode; - break; - } - - var areNoLanguagesSelected = - Object.keys(this.spellCheckLanguages_).length == 0; - var usesSystemSpellchecker = !$('enable-spellcheck-container'); - var isSpellcheckingEnabled = usesSystemSpellchecker || - $('enable-spellcheck').checked; - $('edit-custom-dictionary-button').hidden = - areNoLanguagesSelected || !isSpellcheckingEnabled; - }, - - /** - * Updates the checkbox for stopping translation. - * @param {string} languageCode Language code (ex. "fr"). - * @private - */ - updateOfferToTranslateCheckbox_: function(languageCode) { - var div = $('language-options-offer-to-translate'); - - // Translation server supports Chinese (Transitional) and Chinese - // (Simplified) but not 'general' Chinese. To avoid ambiguity, we don't - // show this preference when general Chinese is selected. - if (languageCode != 'zh') { - div.hidden = false; - } else { - div.hidden = true; - return; - } - - var offerToTranslate = div.querySelector('div'); - var cannotTranslate = $('cannot-translate-in-this-language'); - var nodes = [offerToTranslate, cannotTranslate]; - - var convertedLangCode = this.convertLangCodeForTranslation_(languageCode); - if (this.translateSupportedLanguages_.indexOf(convertedLangCode) != -1) { - showMutuallyExclusiveNodes(nodes, 0); - } else { - showMutuallyExclusiveNodes(nodes, 1); - return; - } - - var checkbox = $('offer-to-translate-in-this-language'); - - if (!this.enableTranslate_) { - checkbox.disabled = true; - checkbox.checked = false; - return; - } - - // If the language corresponds to the default target language (in most - // cases, the user's locale language), "Offer to translate" checkbox - // should be always unchecked. - var defaultTargetLanguage = - loadTimeData.getString('defaultTargetLanguage'); - if (convertedLangCode == defaultTargetLanguage) { - checkbox.disabled = true; - checkbox.checked = false; - return; - } - - checkbox.disabled = false; - - var blockedLanguages = this.translateBlockedLanguages_; - var checked = blockedLanguages.indexOf(convertedLangCode) == -1; - checkbox.checked = checked; - }, - - /** - * Updates the input method list. - * @param {string} languageCode Language code (ex. "fr"). - * @private - */ - updateInputMethodList_: function(languageCode) { - // Give one of the checkboxes or buttons focus, if it's specified in the - // URL hash (ex. focus=mozc). Used for automated testing. - var focusInputMethodId = -1; - var match = document.location.hash.match(/\bfocus=([\w:-]+)\b/); - if (match) { - focusInputMethodId = match[1]; - } - // Change the visibility of the input method list. Input methods that - // matches |languageCode| will become visible. - var inputMethodList = $('language-options-input-method-list'); - var methods = inputMethodList.querySelectorAll('.input-method'); - for (var i = 0; i < methods.length; i++) { - var method = methods[i]; - if (languageCode in method.languageCodeSet) { - method.hidden = false; - var input = method.querySelector('input'); - // Give it focus if the ID matches. - if (input.inputMethodId == focusInputMethodId) { - input.focus(); - } - } else { - method.hidden = true; - } - } - - $('language-options-input-method-none').hidden = - (languageCode in this.languageCodeToInputMethodIdsMap_); - - if (focusInputMethodId == 'add') { - $('language-options-add-button').focus(); - } - }, - - /** - * Updates the language list in the add language overlay. - * @private - */ - updateLanguageListInAddLanguageOverlay_: function() { - // Change the visibility of the language list in the add language - // overlay. Languages that are already active will become invisible, - // so that users don't add the same language twice. - var languageOptionsList = $('language-options-list'); - var languageCodes = languageOptionsList.getLanguageCodes(); - var languageCodeSet = {}; - for (var i = 0; i < languageCodes.length; i++) { - languageCodeSet[languageCodes[i]] = true; - } - - var addLanguageList = $('add-language-overlay-language-list'); - var options = addLanguageList.querySelectorAll('option'); - assert(options.length > 0); - var selectedFirstItem = false; - for (var i = 0; i < options.length; i++) { - var option = options[i]; - option.hidden = option.value in languageCodeSet; - if (!option.hidden && !selectedFirstItem) { - // Select first visible item, otherwise previously selected hidden - // item will be selected by default at the next time. - option.selected = true; - selectedFirstItem = true; - } - } - }, - - /** - * Handles preloadEnginesPref change. - * @param {Event} e Change event. - * @private - */ - handlePreloadEnginesPrefChange_: function(e) { - var value = e.value.value; - this.preloadEngines_ = this.filterBadPreloadEngines_(value.split(',')); - this.updateCheckboxesFromPreloadEngines_(); - $('language-options-list').updateDeletable(); - }, - - /** - * Handles enabledExtensionImePref change. - * @param {Event} e Change event. - * @private - */ - handleEnabledExtensionsPrefChange_: function(e) { - var value = e.value.value; - this.enabledExtensionImes_ = value.split(','); - this.updateCheckboxesFromEnabledExtensions_(); - }, - - /** - * Handles offer-to-translate checkbox's click event. - * @param {Event} e Click event. - * @private - */ - handleOfferToTranslateCheckboxClick_: function(e) { - var checkbox = e.target; - var checked = checkbox.checked; - - var languageOptionsList = $('language-options-list'); - var selectedLanguageCode = languageOptionsList.getSelectedLanguageCode(); - - if (checked) - this.removeBlockedLanguage_(selectedLanguageCode); - else - this.addBlockedLanguage_(selectedLanguageCode); - }, - - /** - * Handles input method checkbox's click event. - * @param {Event} e Click event. - * @private - */ - handleCheckboxClick_: function(e) { - var checkbox = assertInstanceof(e.target, Element); - - // Third party IMEs require additional confirmation prior to enabling due - // to privacy risk. - if (/^_ext_ime_/.test(checkbox.inputMethodId) && checkbox.checked) { - var confirmationCallback = this.handleCheckboxUpdate_.bind(this, - checkbox); - var cancellationCallback = function() { - checkbox.checked = false; - }; - ThirdPartyImeConfirmOverlay.showConfirmationDialog({ - extension: checkbox.imeProvider, - confirm: confirmationCallback, - cancel: cancellationCallback - }); - } else { - this.handleCheckboxUpdate_(checkbox); - } - - chrome.send('coreOptionsUserMetricsAction', - ['Options_Languages_InputMethodCheckbox' + - (checkbox.checked ? '_Enable' : '_Disable')]); - }, - - /** - * Updates active IMEs based on change in state of a checkbox for an input - * method. - * @param {!Element} checkbox Updated checkbox element. - * @private - */ - handleCheckboxUpdate_: function(checkbox) { - if (checkbox.inputMethodId.match(/^_ext_ime_/)) { - this.updateEnabledExtensionsFromCheckboxes_(); - this.saveEnabledExtensionPref_(); - return; - } - if (this.preloadEngines_.length == 1 && !checkbox.checked) { - // Don't allow disabling the last input method. - this.showNotification_( - loadTimeData.getString('pleaseAddAnotherInputMethod'), - loadTimeData.getString('okButton')); - checkbox.checked = true; - return; - } - if (checkbox.checked) { - chrome.send('inputMethodEnable', [checkbox.inputMethodId]); - } else { - chrome.send('inputMethodDisable', [checkbox.inputMethodId]); - } - this.updatePreloadEnginesFromCheckboxes_(); - this.preloadEngines_ = this.sortPreloadEngines_(this.preloadEngines_); - this.savePreloadEnginesPref_(); - }, - - /** - * Handles clicks on the "OK" button of the "Add language" dialog. - * @param {Event} e Click event. - * @private - */ - handleAddLanguageOkButtonClick_: function(e) { - var languagesSelect = $('add-language-overlay-language-list'); - var selectedIndex = languagesSelect.selectedIndex; - if (selectedIndex >= 0) { - var selection = languagesSelect.options[selectedIndex]; - var langCode = String(selection.value); - $('language-options-list').addLanguage(langCode); - this.addBlockedLanguage_(langCode); - PageManager.closeOverlay(); - } - }, - - /** - * Checks if languageCode is deletable or not. - * @param {string} languageCode the languageCode to check for deletability. - */ - languageIsDeletable: function(languageCode) { - // Don't allow removing the language if it's a UI language. - if (languageCode == this.prospectiveUiLanguageCode_) - return false; - return (!cr.isChromeOS || - this.canDeleteLanguage_(languageCode)); - }, - - /** - * Handles browser.enable_spellchecking change. - * @param {Event} e Change event. - * @private - */ - updateEnableSpellCheck_: function(e) { - var value = !$('enable-spellcheck').checked; - var languageControl = $('spellcheck-language-checkbox'); - languageControl.disabled = value; - if (!cr.isMac) - $('edit-custom-dictionary-button').hidden = value; - }, - - /** - * Handles translateBlockedLanguagesPref change. - * @param {Event} e Change event. - * @private - */ - handleTranslateBlockedLanguagesPrefChange_: function(e) { - this.translateBlockedLanguages_ = e.value.value; - this.updateOfferToTranslateCheckbox_( - $('language-options-list').getSelectedLanguageCode()); - }, - - /** - * Updates spellcheck dictionary UI (checkboxes, buttons, and labels) when - * preferences change. - * @param {Event} e Preference change event where e.value.value is the list - * of languages currently used for spellchecking. - * @private - */ - handleSpellCheckDictionariesPrefChange_: function(e) { - if (cr.isMac) - return; - - var languages = e.value.value; - this.spellCheckLanguages_ = {}; - for (var i = 0; i < languages.length; i++) { - this.spellCheckLanguages_[languages[i]] = true; - } - this.updateSpellCheckLanguageControls_( - $('language-options-list').getSelectedLanguageCode()); - }, - - /** - * Handles translate.enabled change. - * @param {Event} e Change event. - * @private - */ - handleEnableTranslatePrefChange_: function(e) { - var enabled = e.value.value; - this.enableTranslate_ = enabled; - this.updateOfferToTranslateCheckbox_( - $('language-options-list').getSelectedLanguageCode()); - }, - - /** - * Updates the spellcheck.dictionaries preference with the currently - * selected language codes. - * @param {Event} e Click event. e.currentTarget represents the "Use this - * language for spellchecking" checkbox. - * @private - */ - handleSpellCheckLanguageCheckboxClick_: function(e) { - var languageCode = e.currentTarget.languageCode; - - if (e.currentTarget.checked) - this.spellCheckLanguages_[languageCode] = true; - else - delete this.spellCheckLanguages_[languageCode]; - - var languageCodes = Object.keys(this.spellCheckLanguages_); - Preferences.setListPref(SPELL_CHECK_DICTIONARIES_PREF, - languageCodes, true); - - // The spellCheckLanguageChange argument is only used for logging. - chrome.send('spellCheckLanguageChange', [languageCodes.join(',')]); - chrome.send('coreOptionsUserMetricsAction', - ['Options_Languages_SpellCheck']); - }, - - /** - * Checks whether it's possible to remove the language specified by - * languageCode and returns true if possible. This function returns false - * if the removal causes the number of preload engines to be zero. - * - * @param {string} languageCode Language code (ex. "fr"). - * @return {boolean} Returns true on success. - * @private - */ - canDeleteLanguage_: function(languageCode) { - // First create the set of engines to be removed from input methods - // associated with the language code. - var enginesToBeRemovedSet = {}; - var inputMethodIds = this.languageCodeToInputMethodIdsMap_[languageCode]; - - // If this language doesn't have any input methods, it can be deleted. - if (!inputMethodIds) - return true; - - for (var i = 0; i < inputMethodIds.length; i++) { - enginesToBeRemovedSet[inputMethodIds[i]] = true; - } - - // Then eliminate engines that are also used for other active languages. - // For instance, if "xkb:us::eng" is used for both English and Filipino. - var languageCodes = $('language-options-list').getLanguageCodes(); - for (var i = 0; i < languageCodes.length; i++) { - // Skip the target language code. - if (languageCodes[i] == languageCode) { - continue; - } - // Check if input methods used in this language are included in - // enginesToBeRemovedSet. If so, eliminate these from the set, so - // we don't remove this time. - var inputMethodIdsForAnotherLanguage = - this.languageCodeToInputMethodIdsMap_[languageCodes[i]]; - if (!inputMethodIdsForAnotherLanguage) - continue; - - for (var j = 0; j < inputMethodIdsForAnotherLanguage.length; j++) { - var inputMethodId = inputMethodIdsForAnotherLanguage[j]; - if (inputMethodId in enginesToBeRemovedSet) { - delete enginesToBeRemovedSet[inputMethodId]; - } - } - } - - // Update the preload engine list with the to-be-removed set. - var newPreloadEngines = []; - for (var i = 0; i < this.preloadEngines_.length; i++) { - if (!(this.preloadEngines_[i] in enginesToBeRemovedSet)) { - newPreloadEngines.push(this.preloadEngines_[i]); - } - } - // Don't allow this operation if it causes the number of preload - // engines to be zero. - return (newPreloadEngines.length > 0); - }, - - /** - * Saves the enabled extension preference. - * @private - */ - saveEnabledExtensionPref_: function() { - Preferences.setStringPref(ENABLED_EXTENSION_IME_PREF, - this.enabledExtensionImes_.join(','), true); - }, - - /** - * Updates the checkboxes in the input method list from the enabled - * extensions preference. - * @private - */ - updateCheckboxesFromEnabledExtensions_: function() { - // Convert the list into a dictonary for simpler lookup. - var dictionary = {}; - for (var i = 0; i < this.enabledExtensionImes_.length; i++) - dictionary[this.enabledExtensionImes_[i]] = true; - - var inputMethodList = $('language-options-input-method-list'); - var checkboxes = inputMethodList.querySelectorAll('input'); - for (var i = 0; i < checkboxes.length; i++) { - if (checkboxes[i].inputMethodId.match(/^_ext_ime_/)) - checkboxes[i].checked = (checkboxes[i].inputMethodId in dictionary); - } - var configureButtons = inputMethodList.querySelectorAll('button'); - for (var i = 0; i < configureButtons.length; i++) { - if (configureButtons[i].inputMethodId.match(/^_ext_ime_/)) { - configureButtons[i].hidden = - !(configureButtons[i].inputMethodId in dictionary); - } - } - }, - - /** - * Updates the enabled extensions preference from the checkboxes in the - * input method list. - * @private - */ - updateEnabledExtensionsFromCheckboxes_: function() { - this.enabledExtensionImes_ = []; - var inputMethodList = $('language-options-input-method-list'); - var checkboxes = inputMethodList.querySelectorAll('input'); - for (var i = 0; i < checkboxes.length; i++) { - if (checkboxes[i].inputMethodId.match(/^_ext_ime_/)) { - if (checkboxes[i].checked) - this.enabledExtensionImes_.push(checkboxes[i].inputMethodId); - } - } - }, - - /** - * Saves the preload engines preference. - * @private - */ - savePreloadEnginesPref_: function() { - Preferences.setStringPref(PRELOAD_ENGINES_PREF, - this.preloadEngines_.join(','), true); - }, - - /** - * Updates the checkboxes in the input method list from the preload - * engines preference. - * @private - */ - updateCheckboxesFromPreloadEngines_: function() { - // Convert the list into a dictonary for simpler lookup. - var dictionary = {}; - for (var i = 0; i < this.preloadEngines_.length; i++) { - dictionary[this.preloadEngines_[i]] = true; - } - - var inputMethodList = $('language-options-input-method-list'); - var checkboxes = inputMethodList.querySelectorAll('input'); - for (var i = 0; i < checkboxes.length; i++) { - if (!checkboxes[i].inputMethodId.match(/^_ext_ime_/)) - checkboxes[i].checked = (checkboxes[i].inputMethodId in dictionary); - } - var configureButtons = inputMethodList.querySelectorAll('button'); - for (var i = 0; i < configureButtons.length; i++) { - if (!configureButtons[i].inputMethodId.match(/^_ext_ime_/)) { - configureButtons[i].hidden = - !(configureButtons[i].inputMethodId in dictionary); - } - } - }, - - /** - * Updates the preload engines preference from the checkboxes in the - * input method list. - * @private - */ - updatePreloadEnginesFromCheckboxes_: function() { - this.preloadEngines_ = []; - var inputMethodList = $('language-options-input-method-list'); - var checkboxes = inputMethodList.querySelectorAll('input'); - for (var i = 0; i < checkboxes.length; i++) { - if (!checkboxes[i].inputMethodId.match(/^_ext_ime_/)) { - if (checkboxes[i].checked) - this.preloadEngines_.push(checkboxes[i].inputMethodId); - } - } - var languageOptionsList = $('language-options-list'); - languageOptionsList.updateDeletable(); - }, - - /** - * Filters bad preload engines in case bad preload engines are - * stored in the preference. Removes duplicates as well. - * @param {Array} preloadEngines List of preload engines. - * @private - */ - filterBadPreloadEngines_: function(preloadEngines) { - // Convert the list into a dictonary for simpler lookup. - var dictionary = {}; - var list = loadTimeData.getValue('inputMethodList'); - for (var i = 0; i < list.length; i++) { - dictionary[list[i].id] = true; - } - - var enabledPreloadEngines = []; - var seen = {}; - for (var i = 0; i < preloadEngines.length; i++) { - // Check if the preload engine is present in the - // dictionary, and not duplicate. Otherwise, skip it. - // Component Extension IME should be handled same as preloadEngines and - // "_comp_" is the special prefix of its ID. - if ((preloadEngines[i] in dictionary && !(preloadEngines[i] in seen)) || - /^_comp_/.test(preloadEngines[i])) { - enabledPreloadEngines.push(preloadEngines[i]); - seen[preloadEngines[i]] = true; - } - } - return enabledPreloadEngines; - }, - - // TODO(kochi): This is an adapted copy from new_tab.js. - // If this will go as final UI, refactor this to share the component with - // new new tab page. - /** - * @private - */ - notificationTimeout_: null, - - /** - * Shows notification. - * @param {string} text - * @param {string} actionText - * @param {number=} opt_delay - * @private - */ - showNotification_: function(text, actionText, opt_delay) { - var notificationElement = $('notification'); - var actionLink = notificationElement.querySelector('.link-color'); - var delay = opt_delay || 10000; - - function show() { - window.clearTimeout(this.notificationTimeout_); - notificationElement.classList.add('show'); - document.body.classList.add('notification-shown'); - } - - function hide() { - window.clearTimeout(this.notificationTimeout_); - notificationElement.classList.remove('show'); - document.body.classList.remove('notification-shown'); - // Prevent tabbing to the hidden link. - actionLink.tabIndex = -1; - // Setting tabIndex to -1 only prevents future tabbing to it. If, - // however, the user switches window or a tab and then moves back to - // this tab the element may gain focus. We therefore make sure that we - // blur the element so that the element focus is not restored when - // coming back to this window. - actionLink.blur(); - } - - function delayedHide() { - this.notificationTimeout_ = window.setTimeout(hide, delay); - } - - notificationElement.firstElementChild.textContent = text; - actionLink.textContent = actionText; - - actionLink.onclick = hide; - actionLink.onkeydown = function(e) { - if (e.key == 'Enter') { - hide(); - } - }; - notificationElement.onmouseover = show; - notificationElement.onmouseout = delayedHide; - actionLink.onfocus = show; - actionLink.onblur = delayedHide; - // Enable tabbing to the link now that it is shown. - actionLink.tabIndex = 0; - - show(); - delayedHide(); - }, - - /** - * Chrome callback for when the UI language preference is saved. - * @param {string} languageCode The newly selected language to use. - * @private - */ - uiLanguageSaved_: function(languageCode) { - this.prospectiveUiLanguageCode_ = languageCode; - - // If the user is no longer on the same language code, ignore. - if ($('language-options-list').getSelectedLanguageCode() != languageCode) - return; - - // Special case for when a user changes to a different language, and - // changes back to the same language without having restarted Chrome or - // logged in/out of ChromeOS. - if (languageCode == loadTimeData.getString('currentUiLanguageCode')) { - this.updateUiLanguageButton_(languageCode); - return; - } - - // Otherwise, show a notification telling the user that their changes will - // only take effect after restart. - showMutuallyExclusiveNodes([$('language-options-ui-language-button'), - $('language-options-ui-notification-bar')], - 1); - }, - - /** - * A handler for when dictionary for |languageCode| begins downloading. - * @param {string} languageCode The language of the dictionary that just - * began downloading. - * @private - */ - onDictionaryDownloadBegin_: function(languageCode) { - this.spellcheckDictionaryDownloadStatus_[languageCode] = - DOWNLOAD_STATUS.IN_PROGRESS; - if (!cr.isMac && - languageCode == - $('language-options-list').getSelectedLanguageCode()) { - this.updateSpellCheckLanguageControls_(languageCode); - } - }, - - /** - * A handler for when dictionary for |languageCode| successfully downloaded. - * @param {string} languageCode The language of the dictionary that - * succeeded downloading. - * @private - */ - onDictionaryDownloadSuccess_: function(languageCode) { - delete this.spellcheckDictionaryDownloadStatus_[languageCode]; - this.spellcheckDictionaryDownloadFailures_ = 0; - if (!cr.isMac && - languageCode == - $('language-options-list').getSelectedLanguageCode()) { - this.updateSpellCheckLanguageControls_(languageCode); - } - }, - - /** - * A handler for when dictionary for |languageCode| fails to download. - * @param {string} languageCode The language of the dictionary that failed - * to download. - * @private - */ - onDictionaryDownloadFailure_: function(languageCode) { - this.spellcheckDictionaryDownloadStatus_[languageCode] = - DOWNLOAD_STATUS.FAILED; - this.spellcheckDictionaryDownloadFailures_++; - if (!cr.isMac && - languageCode == - $('language-options-list').getSelectedLanguageCode()) { - this.updateSpellCheckLanguageControls_(languageCode); - } - }, - - /** - * Converts the language code for Translation. There are some differences - * between the language set for Translation and that for Accept-Language. - * @param {string} languageCode The language code like 'fr'. - * @return {string} The converted language code. - * @private - */ - convertLangCodeForTranslation_: function(languageCode) { - var tokens = languageCode.split('-'); - var main = tokens[0]; - - // See also: components/translate/core/browser/common/translate_util.cc - var synonyms = { - 'nb': 'no', - 'he': 'iw', - 'jv': 'jw', - 'fil': 'tl', - 'zh-HK': 'zh-TW', - 'zh-MO': 'zh-TW', - 'zh-SG': 'zh-CN', - }; - - if (main in synonyms) { - return synonyms[main]; - } else if (main == 'zh') { - // In Translation, general Chinese is not used, and the sub code is - // necessary as a language code for Translate server. - return languageCode; - } - - return main; - }, - - /** - * Handles activate-ime-menu checkbox's click event. - * @param {Event} e Click event. - * @private - */ - handleActivateImeMenuCheckboxClick_: function(e) { - if (cr.isChromeOS) { - var checkbox = e.target; - Preferences.setBooleanPref(ACTIVATE_IME_MENU_PREF, - checkbox.checked, true); - } - }, - - /** - * Updates the activate-ime-menu check box's checked state. - * @param {Event} e Change event. - * @private - */ - updateImeMenuCheckbox_: function(e) { - $('activate-ime-menu').checked = e.value.value; - }, - }; - - /** - * Shows the node at |index| in |nodes|, hides all others. - * @param {Array<HTMLElement>} nodes The nodes to be shown or hidden. - * @param {number} index The index of |nodes| to show. - */ - function showMutuallyExclusiveNodes(nodes, index) { - assert(index >= 0 && index < nodes.length); - for (var i = 0; i < nodes.length; ++i) { - assert(nodes[i] instanceof HTMLElement); // TODO(dbeam): Ignore null? - nodes[i].hidden = i != index; - } - } - - LanguageOptions.uiLanguageSaved = function(languageCode) { - LanguageOptions.getInstance().uiLanguageSaved_(languageCode); - }; - - LanguageOptions.onDictionaryDownloadBegin = function(languageCode) { - LanguageOptions.getInstance().onDictionaryDownloadBegin_(languageCode); - }; - - LanguageOptions.onDictionaryDownloadSuccess = function(languageCode) { - LanguageOptions.getInstance().onDictionaryDownloadSuccess_(languageCode); - }; - - LanguageOptions.onDictionaryDownloadFailure = function(languageCode) { - LanguageOptions.getInstance().onDictionaryDownloadFailure_(languageCode); - }; - - // Export - return { - LanguageOptions: LanguageOptions - }; -});
diff --git a/chrome/browser/resources/options/manage_profile_overlay.css b/chrome/browser/resources/options/manage_profile_overlay.css deleted file mode 100644 index f8a022ec..0000000 --- a/chrome/browser/resources/options/manage_profile_overlay.css +++ /dev/null
@@ -1,163 +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. */ - -#manage-profile-overlay { - width: 616px; -} - -.profile-icon-grid-item { - height: 31px; - margin: 2px 4px; - padding: 4px; - width: 38px; -} - -.profile-icon { - height: 31px; - width: 38px; -} - -#create-profile-name-input-container, -#manage-profile-name-input-container { - margin-top: 5px; -} - -#create-profile-name-input-container { - margin-bottom: 5px; -} - -#create-profile-name, -#manage-profile-name { - margin-left: 10px; -} - -#create-profile-name:invalid, -#manage-profile-name:invalid { - background-color: pink; -} - -#disconnect-managed-profile-domain-name { - font-weight: bold; -} - -#disconnect-managed-profile-domain-information { - background-color: #f0f0f0; - padding: 14px 0 14px 17px; -} - -#disconnect-managed-profile-message { - padding-top: 9px; -} - -#create-profile-error-bubble, -#manage-profile-error-bubble { - background-color: rgb(238, 185, 57); - border-radius: 4px; - font-weight: bold; - margin-left: auto; - margin-right: auto; - max-height: 50px; - overflow: hidden; - padding: 10px 10px; - text-align: center; - transition: max-height 200ms, padding 200ms; - width: 80%; -} - -html[dir='ltr'] #create-profile-error-bubble { - margin-left: 20px; - width: 90%; -} - -html[dir='rtl'] #create-profile-error-bubble { - margin-right: 20px; - width: 90%; -} - -#create-profile-error-bubble[hidden], -#manage-profile-error-bubble[hidden] { - display: block !important; - max-height: 0; - padding: 0 10px; -} - -#create-profile-icon-grid, -#manage-profile-icon-grid { - background-color: rgba(255, 255, 255, 0.75); - padding: 2px; -} - -:-webkit-any(#create-profile-content, #manage-profile-content) > - :not(:last-child) { - margin-bottom: 10px; -} - -:-webkit-any(#create-profile-content, #manage-profile-content) > - :not(:first-child) { - margin-top: 10px; -} - -:-webkit-any(#create-profile-content, #manage-profile-content) > - .name-input-container { - margin-top: 5px; -} - -:-webkit-any(#create-profile-content, #manage-profile-content) > - .name-label-container { - margin-bottom: 5px; -} - -#create-profile-content { - padding-bottom: 0; -} - -.action-area-shortcut-container { - -webkit-box-flex: 1; -} - -/* Proper spacing for the buttons. */ -#remove-shortcut-button, -#add-shortcut-button { - -webkit-margin-end: 10px; -} - -#delete-supervised-profile-addendum { - -webkit-padding-start: 48px; - margin-top: 10px; -} - -html[dir='ltr'] #delete-profile-icon { - float: left; - margin-right: 10px; -} - -html[dir='rtl'] #delete-profile-icon { - float: right; - margin-left: 10px; -} - -#create-profile-supervised-not-signed-in { - color: #999; -} - -#create-profile-supervised-not-signed-in-label, -#create-profile-supervised-account-details-out-of-date-label { - white-space: pre-wrap; - word-wrap: break-word; -} - -#create-profile-supervised-content-area { - padding-top: 5px; -} - -#import-existing-supervised-user-link { - bottom: 25px; - left: 17px; - position: absolute; -} - -#supervised-user-import-existing { - margin: 0; - padding: 0; -}
diff --git a/chrome/browser/resources/options/manage_profile_overlay.html b/chrome/browser/resources/options/manage_profile_overlay.html deleted file mode 100644 index f72093c0..0000000 --- a/chrome/browser/resources/options/manage_profile_overlay.html +++ /dev/null
@@ -1,141 +0,0 @@ -<div id="manage-profile-overlay" class="page" hidden> - <div class="close-button"></div> - <!-- Dialog for managing profiles. --> - <div id="manage-profile-overlay-manage" hidden> - <h1>$i18n{manageProfile}</h1> - <div id="manage-profile-content" class="content-area"> - <div id="manage-profile-icon-label">$i18n{manageProfilesIconLabel}</div> - <grid id="manage-profile-icon-grid"></grid> - <div id="manage-profile-name-input-container"> - <label> - <span>$i18n{manageProfilesNameLabel}</span> - <input id="manage-profile-name" type="text" pattern=".*\S.*" required> - </label> - </div> - <div id="manage-profile-error-bubble" hidden></div> - </div> - <div class="action-area"> - <div class="action-area-shortcut-container"> - <button id="remove-shortcut-button" hidden> - $i18n{removeProfileShortcutButton} - </button> - <button id="add-shortcut-button" hidden> - $i18n{createProfileShortcutButton} - </button> - </div> - <div class="button-strip"> - <button id="manage-profile-cancel">$i18n{cancel}</button> - <button id="manage-profile-ok" class="default-button"> - $i18n{manageProfilesConfirm} - </button> - </div> - </div> - </div> - <!-- Dialog for deleting profiles. --> - <div id="manage-profile-overlay-delete" hidden> - <h1>$i18n{deleteProfileTitle}</h1> - <div class="content-area"> - <div id="delete-profile-message"> - <img id="delete-profile-icon" class="profile-icon"> - <div id="delete-profile-text"></div> - </div> - <div id="delete-supervised-profile-addendum" hidden> - $i18nRaw{deleteSupervisedProfileAddendum} - </div> - </div> - <div class="action-area button-strip"> - <button id="delete-profile-ok">$i18n{deleteProfileOK}</button> - <button id="delete-profile-cancel" class="default-button"> - $i18n{cancel} - </button> - </div> - </div> - <!-- Dialog for disconnecting enterprise managed profiles. --> - <div id="manage-profile-overlay-disconnect-managed" hidden> - <h1>$i18n{disconnectManagedProfileTitle}</h1> - <div class="content-area" - id="disconnect-managed-profile-domain-information"> - $i18nRaw{disconnectManagedProfileDomainInformation} - </div> - <div class="content-area"> - <div id="disconnect-managed-profile-message"> - <div id="disconnect-managed-profile-text"> - $i18nRaw{disconnectManagedProfileText} - </div> - </div> - </div> - <div class="action-area"> - <div class="button-strip"> - <button id="disconnect-managed-profile-ok"> - $i18n{disconnectManagedProfileOK} - </button> - <button id="disconnect-managed-profile-cancel" class="default-button"> - $i18n{cancel} - </button> - </div> - </div> - </div> - <!-- Dialog for creating profiles. --> - <div id="manage-profile-overlay-create" hidden> - <h1>$i18n{createProfileTitle}</h1> - <div id="create-profile-content" class="content-area"> - <div id="create-profile-instructions"></div> - <grid id="create-profile-icon-grid"></grid> - <div id="create-profile-name-input-container"> - <label> - <span id="create-profile-name-label"> - $i18n{manageProfilesNameLabel} - </span> - <input id="create-profile-name" type="text" pattern=".*\S.*" required> - </label> - </div> - </div> - <div id="create-profile-supervised-content-area" class="content-area"> - <div id="create-shortcut-container" class="checkbox" hidden> - <label> - <input id="create-shortcut" type="checkbox"> - <span>$i18n{createProfileShortcutCheckbox}</span> - </label> - </div> - <div id="create-profile-supervised-container" class="checkbox"> - <label> - <input id="create-profile-supervised" type="checkbox"> - <span id="create-profile-supervised-signed-in"> - <span id="create-profile-supervised-signed-in-label"></span> - <span - id="create-profile-supervised-account-details-out-of-date-label" - hidden> - </span> - <a id="create-profile-supervised-signed-in-learn-more-link" - is="action-link"> - $i18n{learnMore} - </a> - <a id="create-profile-supervised-sign-in-again-link" - is="action-link" hidden> - $i18n{manageProfilesSupervisedSignInAgainLink} - </a> - </span> - <span id="create-profile-supervised-not-signed-in" hidden> - $i18nRaw{manageProfilesSupervisedNotSignedIn} - </span> - </label> - <span id="create-profile-supervised-indicator" - class="bubble-button controlled-setting-indicator"> - </span> - </div> - <div id="create-profile-error-bubble" hidden></div> - </div> - <div class="action-area"> - <div id="create-profile-throbber" class="throbber"></div> - <a is="action-link" id="import-existing-supervised-user-link" hidden> - $i18n{importExistingSupervisedUserLink} - </a> - <div class="button-strip"> - <button id="create-profile-cancel">$i18n{cancel}</button> - <button id="create-profile-ok" class="default-button"> - $i18n{createProfileConfirm} - </button> - </div> - </div> - </div> -</div>
diff --git a/chrome/browser/resources/options/manage_profile_overlay.js b/chrome/browser/resources/options/manage_profile_overlay.js deleted file mode 100644 index 7e3371d..0000000 --- a/chrome/browser/resources/options/manage_profile_overlay.js +++ /dev/null
@@ -1,917 +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. - -cr.define('options', function() { - var Page = cr.ui.pageManager.Page; - var PageManager = cr.ui.pageManager.PageManager; - var ArrayDataModel = cr.ui.ArrayDataModel; - - /** - * ManageProfileOverlay class - * Encapsulated handling of the 'Manage profile...' overlay page. - * @constructor - * @extends {cr.ui.pageManager.Page} - */ - function ManageProfileOverlay() { - Page.call(this, 'manageProfile', - loadTimeData.getString('manageProfileTabTitle'), - 'manage-profile-overlay'); - } - - cr.addSingletonGetter(ManageProfileOverlay); - - ManageProfileOverlay.prototype = { - // Inherit from Page. - __proto__: Page.prototype, - - // Info about the currently managed/deleted profile. - profileInfo_: null, - - // Whether the currently chosen name for a new profile was assigned - // automatically by choosing an avatar. Set on receiveNewProfileDefaults; - // cleared on first edit (in onNameChanged_). - profileNameIsDefault_: false, - - // List of default profile names corresponding to the respective icons. - defaultProfileNames_: [], - - // An object containing all names of existing profiles. - existingProfileNames_: {}, - - // The currently selected icon in the icon grid. - iconGridSelectedURL_: null, - - /** @override */ - initializePage: function() { - Page.prototype.initializePage.call(this); - - var self = this; - options.ProfilesIconGrid.decorate($('manage-profile-icon-grid')); - options.ProfilesIconGrid.decorate($('create-profile-icon-grid')); - self.registerCommonEventHandlers_('create', - self.submitCreateProfile_.bind(self)); - self.registerCommonEventHandlers_('manage', - self.submitManageChanges_.bind(self)); - - // Override the create-profile-ok and create-* keydown handlers, to avoid - // closing the overlay until we finish creating the profile. - $('create-profile-ok').onclick = function(event) { - self.submitCreateProfile_(); - }; - - $('create-profile-cancel').onclick = function(event) { - CreateProfileOverlay.cancelCreateProfile(); - }; - - $('manage-profile-cancel').onclick = - $('disconnect-managed-profile-cancel').onclick = - $('delete-profile-cancel').onclick = function(event) { - PageManager.closeOverlay(); - }; - $('delete-profile-ok').onclick = function(event) { - PageManager.closeOverlay(); - chrome.send('deleteProfile', [self.profileInfo_.filePath]); - options.SupervisedUserListData.resetPromise(); - }; - $('add-shortcut-button').onclick = function(event) { - chrome.send('addProfileShortcut', [self.profileInfo_.filePath]); - }; - $('remove-shortcut-button').onclick = function(event) { - chrome.send('removeProfileShortcut', [self.profileInfo_.filePath]); - }; - - $('disconnect-managed-profile-ok').onclick = function(event) { - PageManager.closeOverlay(); - chrome.send('deleteProfile', - [BrowserOptions.getCurrentProfile().filePath]); - }; - - $('create-profile-supervised-signed-in-learn-more-link').onclick = - function(event) { - PageManager.showPageByName('supervisedUserLearnMore'); - return false; - }; - - $('create-profile-supervised-sign-in-link').onclick = - function(event) { - SyncSetupOverlay.startSignIn(true /* creatingSupervisedUser */); - }; - - $('create-profile-supervised-sign-in-again-link').onclick = - function(event) { - SyncSetupOverlay.showSetupUI(); - }; - - $('import-existing-supervised-user-link').onclick = function(event) { - // Hide the import button to trigger a cursor update. The import button - // is shown again when the import overlay loads. TODO(akuegel): Remove - // this temporary fix when crbug/246304 is resolved. - $('import-existing-supervised-user-link').hidden = true; - PageManager.showPageByName('supervisedUserImport'); - }; - }, - - /** @override */ - didShowPage: function() { - chrome.send('requestDefaultProfileIcons', ['manage']); - - // Just ignore the manage profile dialog on Chrome OS, they use /accounts. - if (!cr.isChromeOS && window.location.pathname == '/manageProfile') - ManageProfileOverlay.getInstance().prepareForManageDialog_(); - - // When editing a profile, initially hide the "add shortcut" and - // "remove shortcut" buttons and ask the handler which to show. It will - // call |receiveHasProfileShortcuts|, which will show the appropriate one. - $('remove-shortcut-button').hidden = true; - $('add-shortcut-button').hidden = true; - - if (loadTimeData.getBoolean('profileShortcutsEnabled')) { - var profileInfo = ManageProfileOverlay.getInstance().profileInfo_; - chrome.send('requestHasProfileShortcuts', [profileInfo.filePath]); - } - - var manageNameField = $('manage-profile-name'); - // Legacy supervised users cannot edit their names. - if (manageNameField.disabled) - $('manage-profile-ok').focus(); - else - manageNameField.focus(); - - this.profileNameIsDefault_ = false; - }, - - /** - * Registers event handlers that are common between create and manage modes. - * @param {string} mode A label that specifies the type of dialog box which - * is currently being viewed (i.e. 'create' or 'manage'). - * @param {function()} submitFunction The function that should be called - * when the user chooses to submit (e.g. by clicking the OK button). - * @private - */ - registerCommonEventHandlers_: function(mode, submitFunction) { - var self = this; - $(mode + '-profile-icon-grid').addEventListener('change', function(e) { - self.onIconGridSelectionChanged_(mode); - }); - $(mode + '-profile-name').oninput = function(event) { - self.onNameChanged_(mode); - }; - $(mode + '-profile-ok').onclick = function(event) { - PageManager.closeOverlay(); - submitFunction(); - }; - }, - - /** - * Set the profile info used in the dialog. - * @param {Object} profileInfo An object of the form: - * profileInfo = { - * name: "Profile Name", - * iconURL: "chrome://path/to/icon/image", - * filePath: "/path/to/profile/data/on/disk", - * isCurrentProfile: false, - * isSupervised: false - * }; - * @param {string} mode A label that specifies the type of dialog box which - * is currently being viewed (i.e. 'create' or 'manage'). - * @private - */ - setProfileInfo_: function(profileInfo, mode) { - this.iconGridSelectedURL_ = profileInfo.iconURL; - this.profileInfo_ = profileInfo; - $(mode + '-profile-name').value = profileInfo.name; - $(mode + '-profile-icon-grid').selectedItem = profileInfo.iconURL; - }, - - /** - * Sets the name of the profile being edited or created. - * @param {string} name New profile name. - * @param {string} mode A label that specifies the type of dialog box which - * is currently being viewed (i.e. 'create' or 'manage'). - * @private - */ - setProfileName_: function(name, mode) { - if (this.profileInfo_) - this.profileInfo_.name = name; - $(mode + '-profile-name').value = name; - }, - - /** - * Set an array of default icon URLs. These will be added to the grid that - * the user will use to choose their profile icon. - * @param {string} mode A label that specifies the type of dialog box which - * is currently being viewed (i.e. 'create' or 'manage'). - * @param {!Array<string>} iconURLs An array of icon URLs. - * @param {Array<string>} names An array of default names - * corresponding to the icons. - * @private - */ - receiveDefaultProfileIconsAndNames_: function(mode, iconURLs, names) { - this.defaultProfileNames_ = names; - - var grid = $(mode + '-profile-icon-grid'); - - grid.dataModel = new ArrayDataModel(iconURLs); - - if (this.profileInfo_) - grid.selectedItem = this.profileInfo_.iconURL; - - // Recalculate the measured item size. - grid.measured_ = null; - grid.columns = 0; - grid.redraw(); - }, - - /** - * Callback to set the initial values when creating a new profile. - * @param {Object} profileInfo An object of the form: - * profileInfo = { - * name: "Profile Name", - * iconURL: "chrome://path/to/icon/image", - * }; - * @private - */ - receiveNewProfileDefaults_: function(profileInfo) { - ManageProfileOverlay.setProfileInfo(profileInfo, 'create'); - this.profileNameIsDefault_ = true; - $('create-profile-name-label').hidden = false; - $('create-profile-name').hidden = false; - // Trying to change the focus if this isn't the topmost overlay can - // instead cause the FocusManager to override another overlay's focus, - // e.g. if an overlay above this one is in the process of being reloaded. - // But the C++ handler calls this method directly on ManageProfileOverlay, - // so check the pageDiv to also include its subclasses (in particular - // CreateProfileOverlay, which has higher sub-overlays). - if (PageManager.getTopmostVisiblePage().pageDiv == this.pageDiv) { - // This will only have an effect if the 'create-profile-name' element - // is visible, i.e. if the overlay is in create mode. - $('create-profile-name').focus(); - } - $('create-profile-ok').disabled = false; - }, - - /** - * Set a dictionary of all profile names. These are used to prevent the - * user from naming two profiles the same. - * @param {Object} profileNames A dictionary of profile names. - * @private - */ - receiveExistingProfileNames_: function(profileNames) { - this.existingProfileNames_ = profileNames; - }, - - /** - * Callback to show the add/remove shortcut buttons when in edit mode, - * called by the handler as a result of the 'requestHasProfileShortcuts_' - * message. - * @param {boolean} hasShortcuts Whether profile has any existing shortcuts. - * @private - */ - receiveHasProfileShortcuts_: function(hasShortcuts) { - $('add-shortcut-button').hidden = hasShortcuts; - $('remove-shortcut-button').hidden = !hasShortcuts; - }, - - /** - * Display the error bubble, with |errorHtml| in the bubble. - * @param {string} errorHtml The html string to display as an error. - * @param {string} mode A label that specifies the type of dialog box which - * is currently being viewed (i.e. 'create' or 'manage'). - * @param {boolean} disableOKButton True if the dialog's OK button should be - * disabled when the error bubble is shown. It will be (re-)enabled when - * the error bubble is hidden. - * @private - */ - showErrorBubble_: function(errorHtml, mode, disableOKButton) { - var nameErrorEl = $(mode + '-profile-error-bubble'); - nameErrorEl.hidden = false; - nameErrorEl.innerHTML = errorHtml; - - if (disableOKButton) - $(mode + '-profile-ok').disabled = true; - }, - - /** - * Hide the error bubble. - * @param {string} mode A label that specifies the type of dialog box which - * is currently being viewed (i.e. 'create' or 'manage'). - * @private - */ - hideErrorBubble_: function(mode) { - $(mode + '-profile-error-bubble').innerHTML = ''; - $(mode + '-profile-error-bubble').hidden = true; - $(mode + '-profile-ok').disabled = false; - }, - - /** - * oninput callback for <input> field. - * @param {string} mode A label that specifies the type of dialog box which - * is currently being viewed (i.e. 'create' or 'manage'). - * @private - */ - onNameChanged_: function(mode) { - this.profileNameIsDefault_ = false; - this.updateCreateOrImport_(mode); - }, - - /** - * Called when the profile name is changed or the 'create supervised' - * checkbox is toggled. Updates the 'ok' button and the 'import existing - * supervised user' link. - * @param {string} mode A label that specifies the type of dialog box which - * is currently being viewed (i.e. 'create' or 'manage'). - * @private - */ - updateCreateOrImport_: function(mode) { - this.updateOkButton_(mode); - // In 'create' mode, check for existing supervised users with the same - // name. - if (mode == 'create') - this.requestExistingSupervisedUsers_(); - }, - - /** - * Tries to get the list of existing supervised users and updates the UI - * accordingly. - * @private - */ - requestExistingSupervisedUsers_: function() { - options.SupervisedUserListData.requestExistingSupervisedUsers().then( - this.receiveExistingSupervisedUsers_.bind(this), - this.onSigninError_.bind(this)); - }, - - /** - * @param {Object} supervisedUser - * @param {boolean} nameIsUnique - */ - getImportHandler_: function(supervisedUser, nameIsUnique) { - return function() { - if (supervisedUser.needAvatar || !nameIsUnique) { - PageManager.showPageByName('supervisedUserImport'); - } else { - this.hideErrorBubble_('create'); - CreateProfileOverlay.updateCreateInProgress(true); - chrome.send('createProfile', - [supervisedUser.name, supervisedUser.iconURL, false, true, - supervisedUser.id]); - } - }.bind(this); - }, - - /** - * Callback which receives the list of existing supervised users. Checks if - * the currently entered name is the name of an already existing supervised - * user. If yes, the user is prompted to import the existing supervised - * user, and the create button is disabled. - * If the received list is empty, hides the "import" link. - * @param {Array<Object>} supervisedUsers The list of existing supervised - * users. - * @private - */ - receiveExistingSupervisedUsers_: function(supervisedUsers) { - // After a supervised user has been created and the dialog has been - // hidden, this gets called again with a list including - // the just-created SU. Ignore, to prevent the "already exists" bubble - // from showing up if the overlay is already hidden. - if (PageManager.getTopmostVisiblePage().pageDiv != this.pageDiv) - return; - $('import-existing-supervised-user-link').hidden = - supervisedUsers.length === 0; - if (!$('create-profile-supervised').checked) - return; - - var newName = $('create-profile-name').value; - var i; - for (i = 0; i < supervisedUsers.length; ++i) { - if (supervisedUsers[i].name != newName) - continue; - // Check if another supervised user also exists with that name. - var nameIsUnique = true; - // Handling the case when multiple supervised users with the same - // name exist, but not all of them are on the device. - // If at least one is not imported, we want to offer that - // option to the user. This could happen due to a bug that allowed - // creating SUs with the same name (https://crbug.com/557445). - var allOnCurrentDevice = supervisedUsers[i].onCurrentDevice; - var j; - for (j = i + 1; j < supervisedUsers.length; ++j) { - if (supervisedUsers[j].name == newName) { - nameIsUnique = false; - allOnCurrentDevice = allOnCurrentDevice && - supervisedUsers[j].onCurrentDevice; - } - } - - var errorHtml = allOnCurrentDevice ? - loadTimeData.getStringF( - 'managedProfilesExistingLocalSupervisedUser') : - loadTimeData.getStringF( - 'manageProfilesExistingSupervisedUser', - HTMLEscape(elide(newName, /* maxLength */ 50))); - this.showErrorBubble_(errorHtml, 'create', true); - - if ($('supervised-user-import-existing')) { - $('supervised-user-import-existing').onclick = - this.getImportHandler_(supervisedUsers[i], nameIsUnique); - } - $('create-profile-ok').disabled = true; - return; - } - }, - - /** - * Called in case the request for the list of supervised users fails because - * of a signin error. - * @private - */ - onSigninError_: function() { - this.updateSignedInStatus(this.signedInEmail_, true); - }, - - /** - * Called to update the state of the ok button depending if the name is - * already used or not. - * @param {string} mode A label that specifies the type of dialog box which - * is currently being viewed (i.e. 'create' or 'manage'). - * @private - */ - updateOkButton_: function(mode) { - var oldName = this.profileInfo_.name; - var newName = $(mode + '-profile-name').value; - this.hideErrorBubble_(mode); - - var nameIsValid = $(mode + '-profile-name').validity.valid; - $(mode + '-profile-ok').disabled = !nameIsValid; - }, - - /** - * Called when the user clicks "OK" or hits enter. Saves the newly changed - * profile info. - * @private - */ - submitManageChanges_: function() { - var name = $('manage-profile-name').value; - var iconURL = $('manage-profile-icon-grid').selectedItem; - - chrome.send('setProfileIconAndName', - [this.profileInfo_.filePath, iconURL, name]); - if (name != this.profileInfo_.name) - options.SupervisedUserListData.resetPromise(); - }, - - /** - * Abstract method. Should be overriden in subclasses. - * @param {string} email - * @param {boolean} hasError - * @protected - */ - updateSignedInStatus: function(email, hasError) { - // TODO: Fix triggering the assert, crbug.com/423267 - // assertNotReached(); - }, - - /** - * Called when the user clicks "OK" or hits enter. Creates the profile - * using the information in the dialog. - * @private - */ - submitCreateProfile_: function() { - // This is visual polish: the UI to access this should be disabled for - // supervised users, and the back end will prevent user creation anyway. - if (this.profileInfo_ && this.profileInfo_.isSupervised) - return; - - this.hideErrorBubble_('create'); - CreateProfileOverlay.updateCreateInProgress(true); - - // Get the user's chosen name and icon, or default if they do not - // wish to customize their profile. - var name = $('create-profile-name').value; - var iconUrl = $('create-profile-icon-grid').selectedItem; - var createShortcut = $('create-shortcut').checked; - var isSupervised = $('create-profile-supervised').checked; - var existingSupervisedUserId = ''; - - // 'createProfile' is handled by the CreateProfileHandler. - chrome.send('createProfile', - [name, iconUrl, createShortcut, - isSupervised, existingSupervisedUserId]); - }, - - /** - * Called when the selected icon in the icon grid changes. - * @param {string} mode A label that specifies the type of dialog box which - * is currently being viewed (i.e. 'create' or 'manage'). - * @private - */ - onIconGridSelectionChanged_: function(mode) { - var iconURL = $(mode + '-profile-icon-grid').selectedItem; - if (!iconURL || iconURL == this.iconGridSelectedURL_) - return; - this.iconGridSelectedURL_ = iconURL; - if (this.profileNameIsDefault_) { - var index = $(mode + '-profile-icon-grid').selectionModel.selectedIndex; - var name = this.defaultProfileNames_[index]; - if (name) { - this.setProfileName_(name, mode); - this.updateCreateOrImport_(mode); - } - } - if (this.profileInfo_ && this.profileInfo_.filePath) { - chrome.send('profileIconSelectionChanged', - [this.profileInfo_.filePath, iconURL]); - } - }, - - /** - * Updates the contents of the "Manage Profile" section of the dialog, - * and shows that section. - * @private - */ - prepareForManageDialog_: function() { - chrome.send('refreshGaiaPicture'); - var profileInfo = BrowserOptions.getCurrentProfile(); - ManageProfileOverlay.setProfileInfo(profileInfo, 'manage'); - $('manage-profile-overlay-create').hidden = true; - $('manage-profile-overlay-manage').hidden = false; - $('manage-profile-overlay-delete').hidden = true; - $('manage-profile-overlay-disconnect-managed').hidden = true; - $('manage-profile-name').disabled = - profileInfo.isSupervised && !profileInfo.isChild; - this.hideErrorBubble_('manage'); - }, - - /** - * Display the "Manage Profile" dialog. - * @param {boolean=} opt_updateHistory If we should update the history after - * showing the dialog (defaults to true). - * @private - */ - showManageDialog_: function(opt_updateHistory) { - var updateHistory = opt_updateHistory !== false; - this.prepareForManageDialog_(); - PageManager.showPageByName('manageProfile', updateHistory); - }, - - /** - * Display the "Delete Profile" dialog. - * @param {Object} profileInfo The profile object of the profile to delete. - * @private - */ - showDeleteDialog_: function(profileInfo) { - ManageProfileOverlay.setProfileInfo(profileInfo, 'manage'); - $('manage-profile-overlay-create').hidden = true; - $('manage-profile-overlay-manage').hidden = true; - $('manage-profile-overlay-delete').hidden = false; - $('manage-profile-overlay-disconnect-managed').hidden = true; - $('delete-profile-icon').style.content = - cr.icon.getImage(profileInfo.iconURL); - $('delete-profile-text').textContent = - loadTimeData.getStringF('deleteProfileMessage', - elide(profileInfo.name, /* maxLength */ 50)); - $('delete-supervised-profile-addendum').hidden = - !profileInfo.isSupervised || profileInfo.isChild; - - // Because this dialog isn't useful when refreshing or as part of the - // history, don't create a history entry for it when showing. - PageManager.showPageByName('manageProfile', false); - chrome.send('logDeleteUserDialogShown'); - }, - - /** - * Display the "Disconnect Managed Profile" dialog. - * @private - */ - showDisconnectManagedProfileDialog_: function(replacements) { - loadTimeData.overrideValues(replacements); - $('manage-profile-overlay-create').hidden = true; - $('manage-profile-overlay-manage').hidden = true; - $('manage-profile-overlay-delete').hidden = true; - $('disconnect-managed-profile-domain-information').innerHTML = - loadTimeData.getString('disconnectManagedProfileDomainInformation'); - $('disconnect-managed-profile-text').innerHTML = - loadTimeData.getString('disconnectManagedProfileText'); - $('manage-profile-overlay-disconnect-managed').hidden = false; - - PageManager.showPageByName('signOut'); - }, - - /** - * Display the "Create Profile" dialog. - * @private - */ - showCreateDialog_: function() { - PageManager.showPageByName('createProfile'); - }, - }; - - // Forward public APIs to private implementations. - cr.makePublic(ManageProfileOverlay, [ - 'receiveDefaultProfileIconsAndNames', - 'receiveNewProfileDefaults', - 'receiveExistingProfileNames', - 'receiveHasProfileShortcuts', - 'setProfileInfo', - 'setProfileName', - 'showManageDialog', - 'showDeleteDialog', - 'showDisconnectManagedProfileDialog', - 'showCreateDialog', - ]); - - /** - * @constructor - * @extends {options.ManageProfileOverlay} - */ - function DisconnectAccountOverlay() { - Page.call(this, 'signOut', - loadTimeData.getString('disconnectAccountTabTitle'), - 'manage-profile-overlay'); - } - - cr.addSingletonGetter(DisconnectAccountOverlay); - - DisconnectAccountOverlay.prototype = { - __proto__: ManageProfileOverlay.prototype, - - /** @override */ - canShowPage: function() { - var syncData = loadTimeData.getValue('syncData'); - return syncData.signedIn && !syncData.signoutAllowed; - }, - - /** @override */ - didShowPage: function() { - chrome.send('showDisconnectManagedProfileDialog'); - } - }; - - /** - * @constructor - * @extends {options.ManageProfileOverlay} - */ - function CreateProfileOverlay() { - Page.call(this, 'createProfile', - loadTimeData.getString('createProfileTabTitle'), - 'manage-profile-overlay'); - } - - cr.addSingletonGetter(CreateProfileOverlay); - - CreateProfileOverlay.prototype = { - __proto__: ManageProfileOverlay.prototype, - - // The signed-in email address of the current profile, or empty if they're - // not signed in. - signedInEmail_: '', - - /** @override */ - canShowPage: function() { - return !BrowserOptions.getCurrentProfile().isSupervised; - }, - - /** - * Configures the overlay to the "create user" mode. - * @override - */ - didShowPage: function() { - chrome.send('requestCreateProfileUpdate'); - chrome.send('requestDefaultProfileIcons', ['create']); - chrome.send('requestNewProfileDefaults'); - - $('manage-profile-overlay-create').hidden = false; - $('manage-profile-overlay-manage').hidden = true; - $('manage-profile-overlay-delete').hidden = true; - $('manage-profile-overlay-disconnect-managed').hidden = true; - $('create-profile-instructions').textContent = - loadTimeData.getStringF('createProfileInstructions'); - this.hideErrorBubble_(); - this.updateCreateInProgress_(false); - - var shortcutsEnabled = loadTimeData.getBoolean('profileShortcutsEnabled'); - $('create-shortcut-container').hidden = !shortcutsEnabled; - $('create-shortcut').checked = shortcutsEnabled; - - $('create-profile-name-label').hidden = true; - $('create-profile-name').hidden = true; - $('create-profile-ok').disabled = true; - - $('create-profile-supervised').checked = false; - $('import-existing-supervised-user-link').hidden = true; - $('create-profile-supervised').onchange = function() { - ManageProfileOverlay.getInstance().updateCreateOrImport_('create'); - }; - $('create-profile-supervised').hidden = true; - $('create-profile-supervised-signed-in').disabled = true; - $('create-profile-supervised-signed-in').hidden = true; - $('create-profile-supervised-not-signed-in').hidden = true; - - this.profileNameIsDefault_ = false; - }, - - /** @override */ - handleCancel: function() { - this.cancelCreateProfile_(); - }, - - /** @override */ - showErrorBubble_: function(errorHtml) { - ManageProfileOverlay.getInstance().showErrorBubble_(errorHtml, - 'create', - false); - }, - - /** @override */ - hideErrorBubble_: function() { - ManageProfileOverlay.getInstance().hideErrorBubble_('create'); - }, - - /** - * Updates the UI when a profile create step begins or ends. - * Note that hideErrorBubble_() also enables the "OK" button, so it - * must be called before this function if both are used. - * @param {boolean} inProgress True if the UI should be updated to show that - * profile creation is now in progress. - * @private - */ - updateCreateInProgress_: function(inProgress) { - this.createInProgress_ = inProgress; - this.updateCreateSupervisedUserCheckbox_(); - - $('create-profile-icon-grid').disabled = inProgress; - $('create-profile-name').disabled = inProgress; - $('create-shortcut').disabled = inProgress; - $('create-profile-ok').disabled = inProgress; - $('import-existing-supervised-user-link').disabled = inProgress; - - $('create-profile-throbber').hidden = !inProgress; - }, - - /** - * Cancels the creation of the a profile. It is safe to call this even - * when no profile is in the process of being created. - * @private - */ - cancelCreateProfile_: function() { - PageManager.closeOverlay(); - chrome.send('cancelCreateProfile'); - this.hideErrorBubble_(); - this.updateCreateInProgress_(false); - }, - - /** - * Shows an error message describing an error that occurred while creating - * a new profile. - * Called by BrowserOptions via the BrowserOptionsHandler. - * @param {string} error The error message to display. - * @private - */ - onError_: function(error) { - this.updateCreateInProgress_(false); - this.showErrorBubble_(error); - }, - - /** - * Shows a warning message giving information while creating a new profile. - * Called by BrowserOptions via the BrowserOptionsHandler. - * @param {string} warning The warning message to display. - * @private - */ - onWarning_: function(warning) { - this.showErrorBubble_(warning); - }, - - /** - * For new supervised users, shows a confirmation page after successfully - * creating a new profile; otherwise, the handler will open a new window. - * @param {Object} profileInfo An object of the form: - * profileInfo = { - * name: "Profile Name", - * filePath: "/path/to/profile/data/on/disk" - * isSupervised: (true|false), - * }; - * @private - */ - onSuccess_: function(profileInfo) { - this.updateCreateInProgress_(false); - PageManager.closeOverlay(); - if (profileInfo.isSupervised) { - options.SupervisedUserListData.resetPromise(); - profileInfo.custodianEmail = this.signedInEmail_; - SupervisedUserCreateConfirmOverlay.setProfileInfo(profileInfo); - PageManager.showPageByName('supervisedUserCreateConfirm', false); - BrowserOptions.updateManagesSupervisedUsers(true); - } - }, - - /** - * @param {string} email - * @param {boolean} hasError - * @override - */ - updateSignedInStatus: function(email, hasError) { - this.updateSignedInStatus_(email, hasError); - }, - - /** - * Updates the signed-in or not-signed-in UI when in create mode. Called by - * the handler in response to the 'requestCreateProfileUpdate' message. - * updateSupervisedUsersAllowed_ is expected to be called after this is, and - * will update additional UI elements. - * @param {string} email The email address of the currently signed-in user. - * An empty string indicates that the user is not signed in. - * @param {boolean} hasError Whether the user's sign-in credentials are - * still valid. - * @private - */ - updateSignedInStatus_: function(email, hasError) { - this.signedInEmail_ = email; - this.hasError_ = hasError; - var isSignedIn = email !== ''; - $('create-profile-supervised').hidden = !isSignedIn; - $('create-profile-supervised-signed-in').hidden = !isSignedIn; - $('create-profile-supervised-not-signed-in').hidden = isSignedIn; - - if (isSignedIn) { - var accountDetailsOutOfDate = - $('create-profile-supervised-account-details-out-of-date-label'); - accountDetailsOutOfDate.textContent = loadTimeData.getStringF( - 'manageProfilesSupervisedAccountDetailsOutOfDate', email); - accountDetailsOutOfDate.hidden = !hasError; - - $('create-profile-supervised-signed-in-label').textContent = - loadTimeData.getStringF( - 'manageProfilesSupervisedSignedInLabel', email); - $('create-profile-supervised-signed-in-label').hidden = hasError; - - $('create-profile-supervised-sign-in-again-link').hidden = !hasError; - $('create-profile-supervised-signed-in-learn-more-link').hidden = - hasError; - } - - this.updateCreateSupervisedUserCheckbox_(); - // If we're signed in, showing/hiding import-existing-supervised-user-link - // is handled in receiveExistingSupervisedUsers_. - if (isSignedIn && !hasError) - this.requestExistingSupervisedUsers_(); - else - $('import-existing-supervised-user-link').hidden = true; - }, - - /** - * Sets whether creating supervised users is allowed or not. Called by the - * handler in response to the 'requestCreateProfileUpdate' message or a - * change in the (policy-controlled) pref that prohibits creating supervised - * users, after the signed-in status has been updated. - * @param {boolean} allowed True if creating supervised users should be - * allowed. - * @private - */ - updateSupervisedUsersAllowed_: function(allowed) { - this.supervisedUsersAllowed_ = allowed; - this.updateCreateSupervisedUserCheckbox_(); - - $('create-profile-supervised-sign-in-link').enabled = allowed; - if (!allowed) { - $('create-profile-supervised-indicator').setAttribute('controlled-by', - 'policy'); - } else { - $('create-profile-supervised-indicator').removeAttribute( - 'controlled-by'); - } - }, - - /** - * Updates the status of the "create supervised user" checkbox. Called from - * updateSupervisedUsersAllowed_() or updateCreateInProgress_(). - * updateSignedInStatus_() does not call this method directly, because it - * will be followed by a call to updateSupervisedUsersAllowed_(). - * @private - */ - updateCreateSupervisedUserCheckbox_: function() { - $('create-profile-supervised').disabled = - !this.supervisedUsersAllowed_ || this.createInProgress_ || - this.signedInEmail_ == '' || this.hasError_; - }, - }; - - // Forward public APIs to private implementations. - cr.makePublic(CreateProfileOverlay, [ - 'cancelCreateProfile', - 'onError', - 'onSuccess', - 'onWarning', - 'updateCreateInProgress', - 'updateSignedInStatus', - 'updateSupervisedUsersAllowed', - ]); - - // Export - return { - ManageProfileOverlay: ManageProfileOverlay, - DisconnectAccountOverlay: DisconnectAccountOverlay, - CreateProfileOverlay: CreateProfileOverlay, - }; -});
diff --git a/chrome/browser/resources/options/options.html b/chrome/browser/resources/options/options.html deleted file mode 100644 index 95936d5..0000000 --- a/chrome/browser/resources/options/options.html +++ /dev/null
@@ -1,218 +0,0 @@ -<!doctype html> -<html id="t" dir="$i18n{textdirection}" lang="$i18n{language}"> -<head> -<meta charset="utf-8"> -<title>$i18n{optionsPageTitle}</title> -<link rel="stylesheet" href="chrome://resources/css/bubble.css"> -<link rel="stylesheet" href="chrome://resources/css/bubble_button.css"> -<link rel="stylesheet" href="chrome://resources/css/chrome_shared.css"> -<link rel="stylesheet" href="chrome://resources/css/controlled_indicator.css"> -<link rel="stylesheet" href="chrome://resources/css/list.css"> -<link rel="stylesheet" href="chrome://resources/css/overlay.css"> -<link rel="stylesheet" href="chrome://resources/css/spinner.css"> -<link rel="stylesheet" href="chrome://resources/css/throbber.css"> -<link rel="stylesheet" href="chrome://resources/css/tree.css"> -<link rel="stylesheet" href="../uber/uber_shared.css"> -<link rel="stylesheet" href="options_page.css"> -<link rel="stylesheet" href="alert_overlay.css"> -<link rel="stylesheet" href="autofill_edit_overlay.css"> -<link rel="stylesheet" href="autofill_options.css"> -<link rel="stylesheet" href="automatic_settings_reset_banner.css"> -<link rel="stylesheet" href="browser_options.css"> -<if expr="chromeos"> - <link rel="stylesheet" href="chromeos/browser_options.css"> -</if> -<link rel="stylesheet" href="clear_browser_data_overlay.css"> -<link rel="stylesheet" href="content_settings.css"> -<link rel="stylesheet" href="cookies_view.css"> -<link rel="stylesheet" href="do_not_track_confirm_overlay.css"> -<link rel="stylesheet" href="easy_unlock_turn_off_overlay.css"> -<link rel="stylesheet" href="font_settings.css"> -<link rel="stylesheet" href="handler_options.css"> -<link rel="stylesheet" href="hotword_confirm_overlay.css"> -<link rel="stylesheet" href="hotword_search_setting_indicator.css"> -<link rel="stylesheet" href="import_data_overlay.css"> -<if expr="not is_macosx"> -<link rel="stylesheet" href="language_dictionary_overlay.css"> -</if> -<link rel="stylesheet" href="language_options.css"> -<link rel="stylesheet" href="manage_profile_overlay.css"> -<link rel="stylesheet" href="password_manager.css"> -<link rel="stylesheet" href="password_manager_list.css"> -<link rel="stylesheet" href="reset_profile_settings_overlay.css"> -<link rel="stylesheet" href="search_engine_manager.css"> -<link rel="stylesheet" href="search_page.css"> -<link rel="stylesheet" href="spelling_confirm_overlay.css"> -<link rel="stylesheet" href="startup_overlay.css"> -<link rel="stylesheet" href="subpages_tab_controls.css"> -<link rel="stylesheet" href="supervised_user_create_confirm.css"> -<link rel="stylesheet" href="supervised_user_import.css"> -<link rel="stylesheet" href="supervised_user_learn_more.css"> -<link rel="stylesheet" href="../help/help_content.css"> -<link rel="stylesheet" href="sync_setup_overlay.css"> -<if expr="chromeos"> -<link rel="stylesheet" href="chromeos/third_party_ime_confirm_overlay.css"> -<link rel="stylesheet" href="chromeos/accounts_options_page.css"> -<link rel="stylesheet" href="chromeos/arc_opt_out_confirm_overlay.css"> -<link rel="stylesheet" href="chromeos/bluetooth.css"> -<link rel="stylesheet" href="chromeos/change_picture_options.css"> -<link rel="stylesheet" href="chromeos/display_options.css"> -<link rel="stylesheet" href="chromeos/display_overscan.css"> -<link rel="stylesheet" href="chromeos/internet_detail.css"> -<link rel="stylesheet" href="chromeos/keyboard_overlay.css"> -<link rel="stylesheet" href="chromeos/stylus_overlay.css"> -<link rel="stylesheet" href="chromeos/pointer_overlay.css"> -<link rel="stylesheet" href="chromeos/quick_unlock_configure_overlay.css"> -<link rel="stylesheet" href="chromeos/storage_clear_drive_cache_overlay.css"> -<link rel="stylesheet" href="chromeos/storage_manager.css"> -<link rel="stylesheet" href="factory_reset_overlay.css"> -<link rel="stylesheet" href="../help/channel_change_page.css"> -</if> -<if expr="use_nss_certs"> -<link rel="stylesheet" href="certificate_manager.css"> -<link rel="stylesheet" href="certificate_tree.css"> -</if> -<link rel="import" href="chrome://resources/html/action_link.html"> -<script src="chrome://resources/js/cr.js"></script> -<script src="chrome://resources/js/event_tracker.js"></script> -<script src="chrome://resources/js/cr/event_target.js"></script> -<script src="chrome://resources/js/cr/ui.js"></script> -<script src="chrome://resources/js/cr/ui/touch_handler.js"></script> -<script src="chrome://resources/js/cr/ui/array_data_model.js"></script> -<script src="chrome://resources/js/cr/ui/bubble.js"></script> -<script src="chrome://resources/js/cr/ui/bubble_button.js"></script> -<script src="chrome://resources/js/cr/ui/controlled_indicator.js"></script> -<script src="chrome://resources/js/cr/ui/focus_manager.js"></script> -<script src="chrome://resources/js/cr/ui/focus_outline_manager.js"></script> -<script src="chrome://resources/js/cr/ui/list_selection_model.js"></script> -<script src="chrome://resources/js/cr/ui/list_selection_controller.js"></script> -<script src="chrome://resources/js/cr/ui/list_single_selection_model.js"> -</script> -<script src="chrome://resources/js/cr/ui/list_item.js"></script> -<script src="chrome://resources/js/cr/ui/list.js"></script> -<script src="chrome://resources/js/cr/ui/menu_item.js"></script> -<script src="chrome://resources/js/cr/ui/menu.js"></script> -<script src="chrome://resources/js/cr/ui/autocomplete_list.js"></script> -<script src="chrome://resources/js/cr/ui/grid.js"></script> -<script src="chrome://resources/js/cr/ui/overlay.js"></script> -<script src="chrome://resources/js/cr/ui/position_util.js"></script> -<script src="chrome://resources/js/cr/ui/repeating_button.js"></script> -<script src="chrome://resources/js/cr/ui/tree.js"></script> -<script src="chrome://resources/js/cr/ui/page_manager/page_manager.js"></script> -<script src="chrome://resources/js/cr/ui/page_manager/page.js"></script> -<script src="chrome://resources/js/icon.js"></script> -<script src="chrome://resources/js/load_time_data.js"></script> -<script src="chrome://resources/js/parse_html_subset.js"></script> -<script src="chrome://resources/js/util.js"></script> - -<script src="chrome://settings-frame/strings.js"></script> -<script src="chrome://settings-frame/options_bundle.js"></script> -</head> - -<body> -<div id="overlay-container-1" class="overlay transparent" hidden> - <include src="autofill_options.html"> - <include src="clear_browser_data_overlay.html"> - <include src="content_settings.html"> - <include src="do_not_track_confirm_overlay.html"> - <include src="easy_unlock_turn_off_overlay.html"> - <include src="font_settings.html"> - <include src="home_page_overlay.html"> - <include src="hotword_confirm_overlay.html"> - <include src="import_data_overlay.html"> - <include src="language_options.html"> - <include src="manage_profile_overlay.html"> - <include src="password_manager.html"> - <include src="reset_profile_settings_overlay.html"> - <include src="search_engine_manager.html"> - <include src="spelling_confirm_overlay.html"> - <include src="startup_overlay.html"> - <include src="supervised_user_create_confirm.html"> - <include src="../help/help_page.html"> - <include src="sync_setup_overlay.html"> -<if expr="chromeos"> - <include src="chromeos/accounts_options.html"> - <include src="chromeos/arc_opt_out_confirm_overlay.html"> - <include src="chromeos/bluetooth_add_device_overlay.html"> - <include src="chromeos/bluetooth_pair_device_overlay.html"> - <include src="chromeos/change_picture_options.html"> - <include src="chromeos/display_options.html"> - <include src="chromeos/keyboard_overlay.html"> - <include src="chromeos/stylus_overlay.html"> - <include src="chromeos/pointer_overlay.html"> - <include src="chromeos/power_overlay.html"> - <include src="chromeos/quick_unlock_configure_overlay.html"> - <include src="chromeos/storage_manager.html"> - <include src="factory_reset_overlay.html"> -</if> -<if expr="use_nss_certs"> - <include src="certificate_manager.html"> -</if> -</div> -<div id="overlay-container-2" class="overlay transparent" hidden> - <include src="alert_overlay.html"> - <include src="autofill_edit_address_overlay.html"> - <include src="autofill_edit_creditcard_overlay.html"> - <include src="clear_browser_data_history_notice_overlay.html"> - <include src="content_settings_exceptions_area.html"> - <include src="cookies_view.html"> - <include src="handler_options.html"> - <include src="language_add_language_overlay.html"> - <include src="supervised_user_import.html"> - <include src="supervised_user_learn_more.html"> -<if expr="not is_macosx"> - <include src="language_dictionary_overlay.html"> -</if> -<if expr="chromeos"> - <include src="chromeos/display_overscan.html"> - <include src="chromeos/internet_detail.html"> - <include src="chromeos/preferred_networks.html"> - <include src="chromeos/storage_clear_drive_cache_overlay.html"> - <include src="chromeos/third_party_ime_confirm_overlay.html"> - <include src="../help/channel_change_page.html"> -</if> -<if expr="not is_win and not is_macosx"> - <include src="certificate_restore_overlay.html"> - <include src="certificate_backup_overlay.html"> - <include src="certificate_edit_ca_trust_overlay.html"> - <include src="certificate_import_error_overlay.html"> -</if> -</div> -<div id="extension-controlled-settings-bubble-template" hidden> - <div class="controlled-setting-bubble-content-row"> - <div class="controlled-setting-bubble-extension-name"></div> - </div> - <div class="controlled-setting-bubble-content-row"> - <a is="action-link" class="controlled-setting-bubble-extension-manage-link"> - $i18n{controlledSettingManageExtension} - </a> - <button class='controlled-setting-bubble-extension-disable-button'> - $i18n{controlledSettingDisableExtension} - </button> - </div> -</div> - -<div id="extension-controlled-warning-template" - class="extension-controlled-warning-box settings-row" hidden> - <div class="extension-controlled-warning"></div> - <button>$i18n{extensionDisable}</button> -</div> - -<div id="main-content" - i18n-values="guestMode:profileIsGuest;supervisedMode:profileIsSupervised"> - <div id="mainview"> - <div id="mainview-content"> - <div id="page-container"> - <!-- Please keep the main pages in desired order of display. This will - allow search results to display in the desired order. --> - <include src="search_box.html"> - <include src="search_page.html"> - <include src="browser_options.html"> - </div> - </div> - </div> -</div> - -<script src="chrome://resources/js/i18n_template.js"></script> -</body> -</html>
diff --git a/chrome/browser/resources/options/options.js b/chrome/browser/resources/options/options.js deleted file mode 100644 index cdfb732..0000000 --- a/chrome/browser/resources/options/options.js +++ /dev/null
@@ -1,316 +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. - -var AddLanguageOverlay = options.AddLanguageOverlay; -var AlertOverlay = options.AlertOverlay; -var AutofillEditAddressOverlay = options.AutofillEditAddressOverlay; -var AutofillEditCreditCardOverlay = options.AutofillEditCreditCardOverlay; -var AutofillOptions = options.AutofillOptions; -var AutomaticSettingsResetBanner = options.AutomaticSettingsResetBanner; -var BrowserOptions = options.BrowserOptions; -var ClearBrowserDataOverlay = options.ClearBrowserDataOverlay; -var ClearBrowserDataHistoryNotice = options.ClearBrowserDataHistoryNotice; -var ConfirmDialog = options.ConfirmDialog; -var ContentSettingsExceptionsArea = - options.contentSettings.ContentSettingsExceptionsArea; -var ContentSettings = options.ContentSettings; -var CookiesView = options.CookiesView; -var CreateProfileOverlay = options.CreateProfileOverlay; -var EditDictionaryOverlay = cr.IsMac ? null : options.EditDictionaryOverlay; -var EasyUnlockTurnOffOverlay = options.EasyUnlockTurnOffOverlay; -var FactoryResetOverlay = options.FactoryResetOverlay; -// <if expr="enable_google_now"> -var GeolocationOptions = options.GeolocationOptions; -// </if> -var FontSettings = options.FontSettings; -var HandlerOptions = options.HandlerOptions; -var HomePageOverlay = options.HomePageOverlay; -var HotwordConfirmDialog = options.HotwordConfirmDialog; -var ImportDataOverlay = options.ImportDataOverlay; -var LanguageOptions = options.LanguageOptions; -var ManageProfileOverlay = options.ManageProfileOverlay; -var DisconnectAccountOverlay = options.DisconnectAccountOverlay; -var OptionsFocusManager = options.OptionsFocusManager; -var OptionsPage = options.OptionsPage; -var PageManager = cr.ui.pageManager.PageManager; -var PasswordManager = options.PasswordManager; -var Preferences = options.Preferences; -var PreferredNetworks = options.PreferredNetworks; -var ResetProfileSettingsOverlay = options.ResetProfileSettingsOverlay; -var SearchEngineManager = options.SearchEngineManager; -var SearchPage = options.SearchPage; -var StartupOverlay = options.StartupOverlay; -var SupervisedUserCreateConfirmOverlay = - options.SupervisedUserCreateConfirmOverlay; -var SupervisedUserImportOverlay = options.SupervisedUserImportOverlay; -var SupervisedUserLearnMoreOverlay = options.SupervisedUserLearnMoreOverlay; -var SyncSetupOverlay = options.SyncSetupOverlay; -var ThirdPartyImeConfirmOverlay = options.ThirdPartyImeConfirmOverlay; - -/** - * DOMContentLoaded handler, sets up the page. - */ -function load() { - // Decorate the existing elements in the document. - cr.ui.decorate('input[pref][type=checkbox]', options.PrefCheckbox); - cr.ui.decorate('input[pref][type=number]', options.PrefNumber); - cr.ui.decorate('input[pref][type=radio]', options.PrefRadio); - cr.ui.decorate('input[pref][type=range]', options.PrefRange); - cr.ui.decorate('select[pref]', options.PrefSelect); - cr.ui.decorate('input[pref][type=text]', options.PrefTextField); - cr.ui.decorate('input[pref][type=url]', options.PrefTextField); - cr.ui.decorate('button[pref]', options.PrefButton); - cr.ui.decorate('#content-settings-page input[type=radio]:not(.handler-radio)', - options.ContentSettingsRadio); - cr.ui.decorate('#content-settings-page input[type=radio].handler-radio', - options.HandlersEnabledRadio); - cr.ui.decorate('span.controlled-setting-indicator', - options.ControlledSettingIndicator); - - // Top level pages. - PageManager.register(SearchPage.getInstance()); - PageManager.register(BrowserOptions.getInstance()); - - // Overlays. - PageManager.registerOverlay(AddLanguageOverlay.getInstance(), - LanguageOptions.getInstance()); - PageManager.registerOverlay(AlertOverlay.getInstance()); - PageManager.registerOverlay(AutofillEditAddressOverlay.getInstance(), - AutofillOptions.getInstance()); - PageManager.registerOverlay(AutofillEditCreditCardOverlay.getInstance(), - AutofillOptions.getInstance()); - PageManager.registerOverlay(AutofillOptions.getInstance(), - BrowserOptions.getInstance(), - [$('autofill-settings')]); - PageManager.registerOverlay(ClearBrowserDataOverlay.getInstance(), - BrowserOptions.getInstance(), - [$('privacyClearDataButton')]); - PageManager.registerOverlay( - ClearBrowserDataHistoryNotice.getInstance(), - ClearBrowserDataOverlay.getInstance()); - PageManager.registerOverlay( - new ConfirmDialog( - 'doNotTrackConfirm', - loadTimeData.getString('doNotTrackConfirmOverlayTabTitle'), - 'do-not-track-confirm-overlay', - /** @type {HTMLButtonElement} */($('do-not-track-confirm-ok')), - /** @type {HTMLButtonElement} */($('do-not-track-confirm-cancel')), - $('do-not-track-enabled')['pref'], - $('do-not-track-enabled')['metric']), - BrowserOptions.getInstance()); - PageManager.registerOverlay( - new ConfirmDialog( - 'spellingConfirm', - loadTimeData.getString('spellingConfirmOverlayTabTitle'), - 'spelling-confirm-overlay', - /** @type {HTMLButtonElement} */($('spelling-confirm-ok')), - /** @type {HTMLButtonElement} */($('spelling-confirm-cancel')), - $('spelling-enabled-control')['pref'], - $('spelling-enabled-control')['metric']), - BrowserOptions.getInstance()); - PageManager.registerOverlay(new HotwordConfirmDialog(), - BrowserOptions.getInstance()); - PageManager.registerOverlay(ContentSettings.getInstance(), - BrowserOptions.getInstance(), - [$('privacyContentSettingsButton')]); - PageManager.registerOverlay(ContentSettingsExceptionsArea.getInstance(), - ContentSettings.getInstance()); - PageManager.registerOverlay(CookiesView.getInstance(), - ContentSettings.getInstance(), - [$('privacyContentSettingsButton'), - $('show-cookies-button')]); - PageManager.registerOverlay(CreateProfileOverlay.getInstance(), - BrowserOptions.getInstance()); - PageManager.registerOverlay(DisconnectAccountOverlay.getInstance(), - BrowserOptions.getInstance()); - PageManager.registerOverlay(EasyUnlockTurnOffOverlay.getInstance(), - BrowserOptions.getInstance(), - [$('easy-unlock-turn-off-button')]); - if (!cr.isMac) { - PageManager.registerOverlay(EditDictionaryOverlay.getInstance(), - LanguageOptions.getInstance(), - [$('edit-custom-dictionary-button')]); - } - PageManager.registerOverlay(FontSettings.getInstance(), - BrowserOptions.getInstance(), - [$('fontSettingsCustomizeFontsButton')]); - if (HandlerOptions && $('manage-handlers-button')) { - PageManager.registerOverlay(HandlerOptions.getInstance(), - ContentSettings.getInstance(), - [$('manage-handlers-button')]); - } - PageManager.registerOverlay(HomePageOverlay.getInstance(), - BrowserOptions.getInstance(), - [$('change-home-page')]); - PageManager.registerOverlay(ImportDataOverlay.getInstance(), - BrowserOptions.getInstance()); - PageManager.registerOverlay(LanguageOptions.getInstance(), - BrowserOptions.getInstance(), - [$('language-button'), - $('manage-languages')]); - PageManager.registerOverlay(ManageProfileOverlay.getInstance(), - BrowserOptions.getInstance()); - if (!cr.isChromeOS) { - PageManager.registerOverlay(SupervisedUserCreateConfirmOverlay. - getInstance(), - BrowserOptions.getInstance()); - PageManager.registerOverlay(SupervisedUserImportOverlay.getInstance(), - CreateProfileOverlay.getInstance()); - PageManager.registerOverlay(SupervisedUserLearnMoreOverlay.getInstance(), - CreateProfileOverlay.getInstance()); - } - PageManager.registerOverlay(PasswordManager.getInstance(), - BrowserOptions.getInstance(), - [$('manage-passwords')]); - PageManager.registerOverlay( - new ResetProfileSettingsOverlay(false /* isTriggered */), - BrowserOptions.getInstance(), - [$('reset-profile-settings')]); - PageManager.registerOverlay(SearchEngineManager.getInstance(), - BrowserOptions.getInstance(), - [$('manage-default-search-engines')]); - PageManager.registerOverlay(StartupOverlay.getInstance(), - BrowserOptions.getInstance()); - PageManager.registerOverlay(SyncSetupOverlay.getInstance(), - BrowserOptions.getInstance(), - [$('customize-sync')]); - -// <if expr="is_win"> - PageManager.registerOverlay( - new ResetProfileSettingsOverlay(true /* isTriggered */), - BrowserOptions.getInstance()); -// </if> - - if (loadTimeData.valueExists('aboutOverlayTabTitle')) { - PageManager.registerOverlay(help.HelpPage.getInstance(), - BrowserOptions.getInstance()); - if (help.ChannelChangePage) { - PageManager.registerOverlay(help.ChannelChangePage.getInstance(), - help.HelpPage.getInstance()); - } - } - if (cr.isChromeOS) { - PageManager.registerOverlay(AccountsOptions.getInstance(), - BrowserOptions.getInstance(), - [$('manage-accounts-button')]); - PageManager.registerOverlay(BluetoothOptions.getInstance(), - BrowserOptions.getInstance(), - [$('bluetooth-add-device')]); - PageManager.registerOverlay(BluetoothPairing.getInstance(), - BrowserOptions.getInstance()); - PageManager.registerOverlay(FactoryResetOverlay.getInstance(), - BrowserOptions.getInstance(), - [$('factory-reset-restart')]); - PageManager.registerOverlay(ChangePictureOptions.getInstance(), - BrowserOptions.getInstance(), - [$('account-picture')]); - PageManager.registerOverlay(StorageClearDriveCacheOverlay.getInstance(), - StorageManager.getInstance()); - PageManager.registerOverlay(DetailsInternetPage.getInstance(), - BrowserOptions.getInstance()); - PageManager.registerOverlay(DisplayOptions.getInstance(), - BrowserOptions.getInstance(), - [$('display-options')]); - PageManager.registerOverlay(DisplayOverscan.getInstance(), - DisplayOptions.getInstance()); - PageManager.registerOverlay(KeyboardOverlay.getInstance(), - BrowserOptions.getInstance(), - [$('keyboard-settings-button')]); - PageManager.registerOverlay(PointerOverlay.getInstance(), - BrowserOptions.getInstance(), - [$('pointer-settings-button')]); - PageManager.registerOverlay(PreferredNetworks.getInstance(), - BrowserOptions.getInstance()); - PageManager.registerOverlay(StylusOverlay.getInstance(), - BrowserOptions.getInstance(), - [$('stylus-settings-link')]); - PageManager.registerOverlay(PowerOverlay.getInstance(), - BrowserOptions.getInstance(), - [$('power-settings-link')]); - PageManager.registerOverlay(QuickUnlockConfigureOverlay.getInstance(), - BrowserOptions.getInstance(), - [$('manage-screenlock')]); - PageManager.registerOverlay(StorageManager.getInstance(), - BrowserOptions.getInstance(), - [$('storage-manager-button')]); - PageManager.registerOverlay(ThirdPartyImeConfirmOverlay.getInstance(), - LanguageOptions.getInstance()); - PageManager.registerOverlay( - new ConfirmDialog( - 'arcOptOutConfirm', - loadTimeData.getString('arcOptOutConfirmOverlayTabTitle'), - 'arc-opt-out-confirm-overlay', - /** @type {HTMLButtonElement} */($('arc-opt-out-confirm-ok')), - /** @type {HTMLButtonElement} */($('arc-opt-out-confirm-cancel')), - $('android-apps-enabled')['pref'], - $('android-apps-enabled')['metric'], - undefined, - false), - BrowserOptions.getInstance()); - } - - if (!cr.isWindows && !cr.isMac) { - PageManager.registerOverlay(CertificateBackupOverlay.getInstance(), - CertificateManager.getInstance()); - PageManager.registerOverlay(CertificateEditCaTrustOverlay.getInstance(), - CertificateManager.getInstance()); - PageManager.registerOverlay(CertificateImportErrorOverlay.getInstance(), - CertificateManager.getInstance()); - PageManager.registerOverlay(CertificateManager.getInstance(), - BrowserOptions.getInstance(), - [$('certificatesManageButton')]); - PageManager.registerOverlay(CertificateRestoreOverlay.getInstance(), - CertificateManager.getInstance()); - } - - OptionsFocusManager.getInstance().initialize(); - Preferences.getInstance().initialize(); - AutomaticSettingsResetBanner.getInstance().initialize(); - OptionsPage.initialize(); - PageManager.initialize(BrowserOptions.getInstance()); - PageManager.addObserver(new uber.PageManagerObserver()); - uber.onContentFrameLoaded(); - - var pageName = PageManager.getPageNameFromPath(); - // Still update history so that chrome://settings/nonexistant redirects - // appropriately to chrome://settings/. If the URL matches, updateHistory_ - // will avoid the extra replaceState. - var updateHistory = true; - PageManager.showPageByName(pageName, updateHistory, - {replaceState: true, hash: location.hash}); - - var subpagesNavTabs = document.querySelectorAll('.subpages-nav-tabs'); - for (var i = 0; i < subpagesNavTabs.length; i++) { - subpagesNavTabs[i].onclick = function(event) { - OptionsPage.showTab(event.srcElement); - }; - } - - window.setTimeout(function() { - document.documentElement.classList.remove('loading'); - chrome.send('onFinishedLoadingOptions'); - chrome.send( - 'metricsHandler:recordTime', - ['Settings.TimeUntilInteractive', window.performance.now()]); - }, 0); -} - -document.documentElement.classList.add('loading'); -document.addEventListener('DOMContentLoaded', load); - -/** - * Listener for the |beforeunload| event. - */ -window.onbeforeunload = function() { - PageManager.willClose(); -}; - -/** - * Listener for the |popstate| event. - * @param {Event} e The |popstate| event. - */ -window.onpopstate = function(e) { - var pageName = PageManager.getPageNameFromPath(); - PageManager.setState(pageName, location.hash, e.state); -};
diff --git a/chrome/browser/resources/options/options_bundle.js b/chrome/browser/resources/options/options_bundle.js deleted file mode 100644 index 2dca003..0000000 --- a/chrome/browser/resources/options/options_bundle.js +++ /dev/null
@@ -1,130 +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. -// -// This file exists to aggregate all of the javascript used by the -// settings page into a single file which will be flattened and served -// as a single resource. -// <include src="preferences.js"> -// <include src="controlled_setting.js"> -// <include src="deletable_item_list.js"> -// <include src="editable_text_field.js"> -// <include src="hotword_search_setting_indicator.js"> -// <include src="inline_editable_list.js"> -// <include src="options_page.js"> -// <include src="pref_ui.js"> -// <include src="settings_dialog.js"> -// <if expr="chromeos"> -// <include src="../chromeos/user_images_grid.js"> -// <include src="../help/channel_change_page.js"> -// <include src="../../../../ui/webui/resources/js/chromeos/ui_account_tweaks.js"> -// <include src="chromeos/onc_data.js"> -// <include src="chromeos/change_picture_options.js"> -// <include src="chromeos/internet_detail_ip_address_field.js"> -// <include src="chromeos/internet_detail.js"> -// <include src="chromeos/network_list.js"> -// <include src="chromeos/preferred_networks.js"> -// <include src="chromeos/bluetooth_device_list.js"> -// <include src="chromeos/bluetooth_add_device_overlay.js"> -// <include src="chromeos/bluetooth_pair_device_overlay.js"> -// <include src="chromeos/accounts_options.js"> -// <include src="chromeos/proxy_rules_list.js"> -// <include src="chromeos/accounts_user_list.js"> -// <include src="chromeos/accounts_user_name_edit.js"> -// <include src="chromeos/display_layout.js"> -// <include src="chromeos/display_layout_manager.js"> -// <include src="chromeos/display_layout_manager_multi.js"> -// <include src="chromeos/display_options.js"> -// <include src="chromeos/display_overscan.js"> -// <include src="chromeos/keyboard_overlay.js"> -// <include src="chromeos/stylus_overlay.js"> -// <include src="chromeos/pointer_overlay.js"> -// <include src="chromeos/quick_unlock_configure_overlay.js"> -// <include src="chromeos/storage_clear_drive_cache_overlay.js"> -// <include src="chromeos/storage_manager.js"> -// <include src="chromeos/third_party_ime_confirm_overlay.js"> -// <include src="chromeos/power_overlay.js"> -var AccountsOptions = options.AccountsOptions; -var ChangePictureOptions = options.ChangePictureOptions; -var DetailsInternetPage = options.internet.DetailsInternetPage; -var DisplayOptions = options.DisplayOptions; -var DisplayOverscan = options.DisplayOverscan; -var BluetoothOptions = options.BluetoothOptions; -var BluetoothPairing = options.BluetoothPairing; -var KeyboardOverlay = options.KeyboardOverlay; -var StylusOverlay = options.StylusOverlay; -var PointerOverlay = options.PointerOverlay; -var PowerOverlay = options.PowerOverlay; -var QuickUnlockConfigureOverlay = options.QuickUnlockConfigureOverlay; -var StorageClearDriveCacheOverlay = options.StorageClearDriveCacheOverlay; -var StorageManager = options.StorageManager; -var UIAccountTweaks = uiAccountTweaks.UIAccountTweaks; -// </if> -// <if expr="use_nss_certs"> -// <include src="certificate_tree.js"> -// <include src="certificate_manager.js"> -// <include src="certificate_restore_overlay.js"> -// <include src="certificate_backup_overlay.js"> -// <include src="certificate_edit_ca_trust_overlay.js"> -// <include src="certificate_import_error_overlay.js"> -var CertificateManager = options.CertificateManager; -var CertificateRestoreOverlay = options.CertificateRestoreOverlay; -var CertificateBackupOverlay = options.CertificateBackupOverlay; -var CertificateEditCaTrustOverlay = options.CertificateEditCaTrustOverlay; -var CertificateImportErrorOverlay = options.CertificateImportErrorOverlay; -// </if> -// <include src="alert_overlay.js"> -// <include src="autofill_edit_address_overlay.js"> -// <include src="autofill_edit_creditcard_overlay.js"> -// <include src="autofill_options.js"> -// <include src="autofill_options_list.js"> -// <include src="automatic_settings_reset_banner.js"> -// <include src="browser_options.js"> -// <include src="browser_options_profile_list.js"> -// <include src="browser_options_startup_page_list.js"> -// <include src="clear_browser_data_overlay.js"> -// <include src="clear_browser_data_history_notice_overlay.js"> -// <include src="confirm_dialog.js"> -// <include src="content_settings.js"> -// <include src="content_settings_exceptions_area.js"> -// <include src="content_settings_ui.js"> -// <include src="cookies_list.js"> -// <include src="cookies_view.js"> -// <include src="easy_unlock_turn_off_overlay.js"> -// <include src="factory_reset_overlay.js"> -// <include src="font_settings.js"> -// <if expr="enable_google_now"> -// <include src="geolocation_options.js"> -// </if> -// <include src="handler_options.js"> -// <include src="handler_options_list.js"> -// <include src="home_page_overlay.js"> -// <include src="hotword_confirm_dialog.js"> -// <include src="import_data_overlay.js"> -// <include src="language_add_language_overlay.js"> -// <if expr="not is_macosx"> -// <include src="language_dictionary_overlay_word_list.js"> -// <include src="language_dictionary_overlay.js"> -// </if> -// <include src="language_list.js"> -// <include src="language_options.js"> -// <include src="manage_profile_overlay.js"> -// <include src="options_focus_manager.js"> -// <include src="password_manager.js"> -// <include src="password_manager_list.js"> -// <include src="profiles_icon_grid.js"> -// <include src="reset_profile_settings_overlay.js"> -// <include src="search_engine_manager.js"> -// <include src="search_engine_manager_engine_list.js"> -// <include src="search_page.js"> -// <include src="startup_overlay.js"> -// <include src="supervised_user_create_confirm.js"> -// <include src="supervised_user_import.js"> -// <include src="supervised_user_learn_more.js"> -// <include src="supervised_user_list.js"> -// <include src="supervised_user_list_data.js"> -// <include src="../help/help_page.js"> -// <include src="sync_setup_overlay.js"> -// <include src="../uber/uber_page_manager_observer.js"> -// <include src="../uber/uber_utils.js"> -// <include src="options.js">
diff --git a/chrome/browser/resources/options/options_focus_manager.js b/chrome/browser/resources/options/options_focus_manager.js deleted file mode 100644 index 9fc3f21..0000000 --- a/chrome/browser/resources/options/options_focus_manager.js +++ /dev/null
@@ -1,34 +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. - -cr.define('options', function() { - var FocusManager = cr.ui.FocusManager; - var PageManager = cr.ui.pageManager.PageManager; - - function OptionsFocusManager() { - } - - cr.addSingletonGetter(OptionsFocusManager); - - OptionsFocusManager.prototype = { - __proto__: FocusManager.prototype, - - /** @override */ - getFocusParent: function() { - var topPage = PageManager.getTopmostVisiblePage().pageDiv; - - // The default page and search page include a search field that is a - // sibling of the rest of the page instead of a child. Thus, use the - // parent node to allow the search field to receive focus. - if (topPage.parentNode.id == 'page-container') - return topPage.parentNode; - - return topPage; - }, - }; - - return { - OptionsFocusManager: OptionsFocusManager, - }; -});
diff --git a/chrome/browser/resources/options/options_page.css b/chrome/browser/resources/options/options_page.css deleted file mode 100644 index 485cdc7..0000000 --- a/chrome/browser/resources/options/options_page.css +++ /dev/null
@@ -1,451 +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. */ - -body { - position: relative; -} - -#main-content { - bottom: 0; - display: -webkit-box; - left: 0; - position: absolute; - right: 0; - top: 0; -} - -#mainview { - -webkit-box-align: stretch; - bottom: 0; - left: 0; - margin: 0; - position: absolute; - right: 0; - top: 0; - z-index: 1; -} - -#mainview-content { - min-height: 100%; - position: relative; -} - -#page-container { - box-sizing: border-box; - max-width: 888px; - min-width: 600px; -} - -body #searchBox { - position: fixed; - z-index: 4; -} - -div.disabled { - color: #999; -} - -.settings-row { - display: block; - margin: 0.65em 0; -} - -.hbox { - -webkit-box-orient: horizontal; - display: -webkit-box; -} - -.vbox { - -webkit-box-orient: vertical; - display: -webkit-box; -} - -.box-align-center { - -webkit-box-align: center; -} - -.stretch { - -webkit-box-flex: 1; -} - -.raw-button, -.raw-button:hover, -.raw-button:active { - background-color: transparent; - background-repeat: no-repeat; - border: none; - box-shadow: none; - min-width: 0; - padding: 1px 6px; -} - -.bottom-strip { - border-top: none; - bottom: 0; - padding: 12px; - position: absolute; - right: 0; -} - -/* Omit top padding (currently only on #settings) whenever the search page is - * showing. */ -#searchPage:not([hidden]) + #settings { - padding-top: 0; -} - -.page list { - /* Min height is a multiple of the list item height (32) */ - min-height: 192px; -} - -.option { - margin-top: 0; -} - -.touch-slider { - -webkit-appearance: slider-horizontal; -} - -.settings-list, -.settings-list-empty { - border: 1px solid #d9d9d9; - border-radius: 2px; -} - -.settings-list-empty { - background-color: #f4f4f4; - box-sizing: border-box; - min-height: 125px; - padding-left: 20px; - padding-top: 20px; -} - - -/* Editable text field properties */ -.editable-text-field > * { - -webkit-box-align: center; - border: none; - box-sizing: border-box; - display: -webkit-box; - height: 20px; - margin: 0; - transition: 150ms background-color; -} - -.editable-text-field > .spacer { - /* The above height rule should not apply to spacers. */ - height: 0; -} - -.editable-text-field .editable-text { - padding: 2px 3px; -} - -.editable-text-field .static-text { - height: 24px; - overflow: hidden; - padding: 3px 4px; - text-overflow: ellipsis; - white-space: nowrap; -} - -.editable-text-field:not([editable]) > [displaymode='edit'] { - display: none; -} - -.editable-text-field[editable] > [displaymode='static'] { - display: none; -} - -.editable-text-field[empty] > input[type='text'] { - color: #ccc; - font-style: italic; -} - -.editable-text-field[disabled] { - opacity: 0.6; -} - -/* Editable List properties */ -list > * { - -webkit-box-align: center; - border: none; - border-radius: 0; /* TODO(dbeam): Is this necessary? */ - box-sizing: border-box; - display: -webkit-box; - height: 32px; - margin: 0; - transition: 150ms background-color; -} - -list > .spacer { - /* The above height rule should not apply to spacers. When redraw is called - on the list they will be given an explicit element height but this ensures - they have 0 height to begin with. */ - height: 0; -} - -list:not([disabled]) > :hover { - background-color: rgb(228, 236, 247); -} - -/* Note: If this becomes the list style for other WebUI pages these rules can be - * simplified (since they wont need to override other rules). */ - -list:not([has-element-focus]) > [selected], -list:not([has-element-focus]) > [lead][selected] { - background-color: #d0d0d0; - background-image: none; -} - -list[has-element-focus] > [selected], -list[has-element-focus] > [lead][selected], -list:not([has-element-focus]) > [selected]:hover, -list:not([has-element-focus]) > [selected][lead]:hover { - background-color: rgb(187, 206, 233); - background-image: none; -} - -.settings-list[has-element-focus] > [lead], -.settings-list[has-element-focus] > [lead][selected] { - border-bottom: 1px solid rgb(120, 146, 180); - border-top: 1px solid rgb(120, 146, 180); -} - -.settings-list[has-element-focus] > [lead]:nth-child(2), -.settings-list[has-element-focus] > [lead][selected]:nth-child(2) { - border-top: 1px solid transparent; -} - -.settings-list[has-element-focus] > [lead]:nth-last-child(2), -.settings-list[has-element-focus] > [lead][selected]:nth-last-child(2) { - border-bottom: 1px solid transparent; -} - -.settings-list[disabled] > [lead][selected], -.settings-list[disabled]:focus > [lead][selected] { - border: none; -} - -list[disabled] { - opacity: 0.6; -} - -list > .heading { - color: #666; -} - -list > .heading:hover { - background-color: transparent; - border-color: transparent; -} - -list .deletable-item { - -webkit-box-align: center; - outline: none; -} - -list .deletable-item > :first-child { - -webkit-box-align: center; - -webkit-box-flex: 1; - -webkit-padding-end: 5px; - display: -webkit-box; -} - -list .row-delete-button { - background-color: transparent; - background-image: -webkit-image-set( - url(../../../../ui/resources/default_100_percent/close_2.png) 1x, - url(../../../../ui/resources/default_200_percent/close_2.png) 2x); - border: none; - display: block; - height: 16px; - opacity: 1; - transition: 150ms opacity; - width: 16px; -} - -list > *:not(:hover):not([selected]):not([lead]) .row-delete-button, -list:not([has-element-focus]) > *:not(:hover):not([selected]) - .row-delete-button, -list[disabled] .row-delete-button, -list .row-delete-button[disabled] { - opacity: 0; - pointer-events: none; -} - -/* HostedApp entries use the disabled closing button to display the App's - * favicon, as an indicator that instead of deleting the permission here - * the user has to remove the hosted app.*/ -list div[role='listitem'][managedby='HostedApp'] .row-delete-button { - opacity: 1; -} - -list .row-delete-button:hover { - background-image: -webkit-image-set( - url(../../../../ui/resources/default_100_percent/close_2_hover.png) 1x, - url(../../../../ui/resources/default_200_percent/close_2_hover.png) 2x); -} - -list .row-delete-button:active { - background-image: -webkit-image-set( - url(../../../../ui/resources/default_100_percent/close_2_pressed.png) - 1x, - url(../../../../ui/resources/default_200_percent/close_2_pressed.png) - 2x); -} - -list .static-text { - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} - -list[type='text'][inlineeditable] input { - box-sizing: border-box; - margin: 0; - width: 100%; -} - -list > :not([editing]) [displaymode='edit'] { - display: none; -} - -list > [editing] [displaymode='static'] { - /* Don't use display:none or visibility:hidden because we need to keep an - * element focusable. - * We shrink only height. We don't shrink width to avoid to change the size - * of containing boxes. */ - border-bottom: 0 !important; - border-top: 0 !important; - height: 0 !important; - margin-bottom: 0 !important; - margin-top: 0 !important; - overflow: hidden; - pointer-events: none; -} - -list > [editing] input:invalid { - background-color: pink; -} - -.list-inline-button { - -webkit-appearance: none; - background: rgb(138, 170, 237); - border: none; - border-radius: 2px; - color: white; - font-weight: bold; - opacity: 0.7; - transition: opacity 150ms; -} - -.list-inline-button:hover { - opacity: 1; -} - -.option-name { - -webkit-padding-end: 5px; -} - -.favicon-cell { - -webkit-padding-start: 20px; - background-position: left; - background-repeat: no-repeat; - background-size: 16px; -} - -input[type='url'].favicon-cell { - -webkit-padding-start: 22px; - background-position-x: 4px; -} - -html[dir=rtl] input.favicon-cell, -input[dir=rtl].favicon-cell { - background-position-x: -webkit-calc(100% - 4px); -} - -list .favicon-cell { - -webkit-margin-start: 7px; - -webkit-padding-start: 26px; - display: block; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} - -html[dir=rtl] list .favicon-cell { - background-position: right; -} - -html[enable-background-mode=false] #background-mode-section { - display: none; -} - -/* UI Controls */ - -/* LIST */ -.settings-list[has-element-focus] { -<if expr="not is_macosx"> - outline: 1px solid rgba(0, 128, 256, 0.5); - outline-offset: -2px; -</if> -<if expr="is_macosx"> - /* This matches the native list outline on Mac */ - outline-color: rgb(117, 154, 217); - outline-offset: -1px; - outline-style: auto; - outline-width: 5px; -</if> -} - -.suboption { - -webkit-margin-start: 23px; -} - -list.autocomplete-suggestions { - background-color: white; - border: 1px solid #aaa; - border-radius: 2px; - min-height: 0; - opacity: 0.9; - position: fixed; - z-index: 3; -} - -list.autocomplete-suggestions > div { - height: auto; -} - -list.autocomplete-suggestions:not([has-element-focus]) > [selected], -list.autocomplete-suggestions:not([has-element-focus]) > [lead][selected] { - background-color: rgb(187, 206, 233); -} - -html:not(.focus-outline-visible) -:enabled:focus:-webkit-any(input[type='checkbox'], input[type='radio']) { - /* Cancel border-color for :focus specified in widgets.css. */ - border-color: rgba(0, 0, 0, 0.25); -} - -html:not([hasFlashPlugin]) .flash-plugin-area, -/* If the Flash plug-in supports the NPP_ClearSiteData API, we don't need to - * show the link to the Flash storage settings manager: */ -html[flashPluginSupportsClearSiteData] .flash-plugin-area, -html:not([flashPluginSupportsClearSiteData]) .clear-plugin-lso-data-enabled, -html[flashPluginSupportsClearSiteData] .clear-plugin-lso-data-disabled, -html:not([enablePepperFlashSettings]) .pepper-flash-settings { - display: none; -} - -.standalone-action-link { - padding: 0; -} - -:-webkit-any(.checkbox, .radio) label ~ a { - display: inline-block; - /* Matches padding of -webkit-any(.checkbox, .radio) */ - padding-bottom: 7px; - vertical-align: bottom; -}
diff --git a/chrome/browser/resources/options/options_page.js b/chrome/browser/resources/options/options_page.js deleted file mode 100644 index 9700c74..0000000 --- a/chrome/browser/resources/options/options_page.js +++ /dev/null
@@ -1,94 +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. - -cr.define('options', function() { - /** @const */ var FocusOutlineManager = cr.ui.FocusOutlineManager; - - var OptionsPage = { - /** - * This is the absolute difference maintained between standard and - * fixed-width font sizes. Refer http://crbug.com/91922. - * @const - */ - SIZE_DIFFERENCE_FIXED_STANDARD: 3, - - /** - * Initializes the complete options page. This will cause all C++ handlers - * to be invoked to do final setup. - */ - initialize: function() { - chrome.send('coreOptionsInitialize'); - }, - - /** - * Shows the tab contents for the given navigation tab. - * @param {Node} tab The tab that the user clicked. - */ - showTab: function(tab) { - // Search parents until we find a tab, or the nav bar itself. This allows - // tabs to have child nodes, e.g. labels in separately-styled spans. - while (tab && tab.classList && - !tab.classList.contains('subpages-nav-tabs') && - !tab.classList.contains('tab')) { - tab = tab.parentNode; - } - if (!tab || !tab.classList || !tab.classList.contains('tab')) - return; - - // Find tab bar of the tab. - var tabBar = tab; - while (tabBar && tabBar.classList && - !tabBar.classList.contains('subpages-nav-tabs')) { - tabBar = tabBar.parentNode; - } - if (!tabBar || !tabBar.classList) - return; - - if (tabBar.activeNavTab != null) { - tabBar.activeNavTab.classList.remove('active-tab'); - $(tabBar.activeNavTab.getAttribute('tab-contents')).classList. - remove('active-tab-contents'); - } - - tab.classList.add('active-tab'); - $(tab.getAttribute('tab-contents')).classList.add('active-tab-contents'); - tabBar.activeNavTab = tab; - }, - - /** - * Shows or hides options for clearing Flash LSOs. - * @param {boolean} enabled Whether plugin data can be cleared. - */ - setClearPluginLSODataEnabled: function(enabled) { - if (enabled) { - document.documentElement.setAttribute( - 'flashPluginSupportsClearSiteData', ''); - } else { - document.documentElement.removeAttribute( - 'flashPluginSupportsClearSiteData'); - } - if (navigator.plugins['Shockwave Flash']) - document.documentElement.setAttribute('hasFlashPlugin', ''); - }, - - /** - * Shows or hides Pepper Flash settings. - * @param {boolean} enabled Whether Pepper Flash settings should be enabled. - */ - setPepperFlashSettingsEnabled: function(enabled) { - if (enabled) { - document.documentElement.setAttribute( - 'enablePepperFlashSettings', ''); - } else { - document.documentElement.removeAttribute( - 'enablePepperFlashSettings'); - } - }, - }; - - // Export - return { - OptionsPage: OptionsPage - }; -});
diff --git a/chrome/browser/resources/options/options_polymer.html b/chrome/browser/resources/options/options_polymer.html deleted file mode 100644 index afbf9fd..0000000 --- a/chrome/browser/resources/options/options_polymer.html +++ /dev/null
@@ -1,11 +0,0 @@ -<link rel="import" href="chrome://resources/html/polymer.html"> -<link rel="import" href="chrome://resources/html/i18n_behavior.html"> -<link rel="import" href="chrome://resources/cr_elements/icons.html"> -<link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html"> -<link rel="import" href="chrome://resources/cr_elements/cr_dialog/cr_dialog.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/paper-radio-group/paper-radio-group.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/paper-radio-button/paper-radio-button.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/neon-animation/neon-animatable.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/paper-checkbox/paper-checkbox.html"> -<link rel="import" href="chrome://settings-frame/people_page/lock_screen.html">
diff --git a/chrome/browser/resources/options/password_manager.css b/chrome/browser/resources/options/password_manager.css deleted file mode 100644 index 33bc94b..0000000 --- a/chrome/browser/resources/options/password_manager.css +++ /dev/null
@@ -1,33 +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. */ - -#password-manager > div.content-area { - width: 600px; -} - -#password-search-column { - bottom: 10px; - position: absolute; - right: 0; -} - -html[dir=rtl] #password-search-column { - left: 0; - right: auto; -} - -#password-list-headers { - position: relative; - width: 100%; -} - -#passwords-title { - display: inline-block; -} - -#saved-passwords-list, -#password-exceptions-list { - max-height: 192px; /* For performance (crbug.com/651049). */ - min-height: 128px; /* Smallest value rendering enough initial list items. */ -}
diff --git a/chrome/browser/resources/options/password_manager.html b/chrome/browser/resources/options/password_manager.html deleted file mode 100644 index c128a3b..0000000 --- a/chrome/browser/resources/options/password_manager.html +++ /dev/null
@@ -1,67 +0,0 @@ -<div id="password-manager" class="page" hidden> - <div class="close-button"></div> - <h1>$i18n{passwordsPage}</h1> - <div class="content-area"> - <div class="password-manager-home"> - <div id="auto-signin-block" class="checkbox"> - <label> - <input pref="credentials_enable_autosignin" type="checkbox"> - <span>$i18n{autoSigninTitle}</span> - </label> - <div class="setting-extra-description"> - <span>$i18n{autoSigninDescription}</span> - </div> - </div> - <div id="password-list-headers"> - <div id="passwords-title"> - <h3>$i18n{savedPasswordsTitle}</h3> - </div> - <div id="password-search-column"> - <input id="password-search-box" type="search" - placeholder="$i18n{passwordSearchPlaceholder}" incremental> - </div> - </div> - <list id="saved-passwords-list" class="settings-list"></list> - <div id="saved-passwords-list-empty-placeholder" - class="settings-list-empty" hidden> - <span>$i18n{passwordsNoPasswordsDescription}</span> - <a target="_blank" - href="$i18nRaw{passwordManagerLearnMoreURL}">$i18n{learnMore}</a> - </div> - <div id="password-manager-import-export" class="action-area" hidden> - <div class="button-strip"> - <button id="password-manager-import" class="password-manager-home"> - $i18n{passwordManagerImportPasswordButtonText} - </button> - <button id="password-manager-export" class="password-manager-home"> - $i18n{passwordManagerExportPasswordButtonText} - </button> - </div> - </div> - <h3>$i18n{passwordExceptionsTitle}</h3> - <list id="password-exceptions-list" class="settings-list"></list> - <div id="password-exceptions-list-empty-placeholder" hidden - class="settings-list-empty"> - <span>$i18n{passwordsNoExceptionsDescription}</span> - <a id="exceptions-learn-more" target="_blank" - href="$i18nRaw{passwordManagerLearnMoreURL}">$i18n{learnMore}</a> - </div> - </div> - </div> - <div class="action-area"> - <span id="manage-passwords-span"> - <span>$i18n{passwordsManagePasswordsBeforeLinkText}</span> - <a id="manage-passwords-link" target="_blank" - href="$i18nRaw{passwordsManagePasswordsLink}"> - $i18n{passwordsManagePasswordsLinkText} - </a> - <span>$i18n{passwordsManagePasswordsAfterLinkText}</span> - </span> - <div class="spacer-div"></div> - <div class="button-strip"> - <button id="password-manager-confirm" class="password-manager-home"> - $i18n{done} - </button> - </div> - </div> -</div>
diff --git a/chrome/browser/resources/options/password_manager.js b/chrome/browser/resources/options/password_manager.js deleted file mode 100644 index 5d4825b..0000000 --- a/chrome/browser/resources/options/password_manager.js +++ /dev/null
@@ -1,285 +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. - -cr.define('options', function() { - /** @const */ var Page = cr.ui.pageManager.Page; - /** @const */ var PageManager = cr.ui.pageManager.PageManager; - /** @const */ var ArrayDataModel = cr.ui.ArrayDataModel; - - ///////////////////////////////////////////////////////////////////////////// - // PasswordManager class: - - /** - * Encapsulated handling of password and exceptions page. - * @constructor - * @extends {cr.ui.pageManager.Page} - */ - function PasswordManager() { - this.activeNavTab = null; - Page.call(this, 'passwords', - loadTimeData.getString('passwordsPageTabTitle'), - 'password-manager'); - } - - cr.addSingletonGetter(PasswordManager); - - PasswordManager.prototype = { - __proto__: Page.prototype, - - /** - * The saved passwords list. - * @type {options.DeletableItemList} - * @private - */ - savedPasswordsList_: null, - - /** - * The password exceptions list. - * @type {options.DeletableItemList} - * @private - */ - passwordExceptionsList_: null, - - /** - * The timer id of the timer set on search query change events. - * @type {number} - * @private - */ - queryDelayTimerId_: 0, - - /** - * The most recent search query, or null if the query is empty. - * @type {?string} - * @private - */ - lastQuery_: null, - - /** @override */ - initializePage: function() { - Page.prototype.initializePage.call(this); - - $('password-manager-confirm').onclick = function() { - PageManager.closeOverlay(); - }; - - $('password-manager-import').onclick = function() { - chrome.send('importPassword'); - }; - - $('password-manager-export').onclick = function() { - chrome.send('exportPassword'); - }; - - $('password-search-box').addEventListener('search', - this.handleSearchQueryChange_.bind(this)); - - $('exceptions-learn-more').onclick = function() { - chrome.send('coreOptionsUserMetricsAction', - ['Options_PasswordManagerExceptionsLearnMore']); - return true; // Always follow the href - }; - - this.createSavedPasswordsList_(); - this.createPasswordExceptionsList_(); - }, - - /** @override */ - canShowPage: function() { - return !(cr.isChromeOS && UIAccountTweaks.loggedInAsGuest()); - }, - - /** @override */ - didShowPage: function() { - // Updating the password lists may cause a blocking platform dialog pop up - // (Mac, Linux), so we delay this operation until the page is shown. - chrome.send('updatePasswordLists'); - $('password-search-box').focus(); - }, - - /** - * Creates, decorates and initializes the saved passwords list. - * @private - */ - createSavedPasswordsList_: function() { - var savedPasswordsList = $('saved-passwords-list'); - options.passwordManager.PasswordsList.decorate(savedPasswordsList); - this.savedPasswordsList_ = assertInstanceof(savedPasswordsList, - options.DeletableItemList); - }, - - /** - * Creates, decorates and initializes the password exceptions list. - * @private - */ - createPasswordExceptionsList_: function() { - var passwordExceptionsList = $('password-exceptions-list'); - options.passwordManager.PasswordExceptionsList.decorate( - passwordExceptionsList); - this.passwordExceptionsList_ = assertInstanceof(passwordExceptionsList, - options.DeletableItemList); - }, - - /** - * Handles search query changes. - * @param {!Event} e The event object. - * @private - */ - handleSearchQueryChange_: function(e) { - if (this.queryDelayTimerId_) - window.clearTimeout(this.queryDelayTimerId_); - - // Searching cookies uses a timeout of 500ms. We use a shorter timeout - // because there are probably fewer passwords and we want the UI to be - // snappier since users will expect that it's "less work." - this.queryDelayTimerId_ = window.setTimeout( - this.searchPasswords_.bind(this), 250); - - chrome.send('coreOptionsUserMetricsAction', - ['Options_PasswordManagerSearch']); - }, - - /** - * Search passwords using text in |password-search-box|. - * @private - */ - searchPasswords_: function() { - this.queryDelayTimerId_ = 0; - var filter = $('password-search-box').value; - filter = (filter == '') ? null : filter; - if (this.lastQuery_ != filter) { - this.lastQuery_ = filter; - // Searching for passwords has the side effect of requerying the - // underlying password store. This is done intentionally, as on OS X and - // Linux they can change from outside and we won't be notified of it. - chrome.send('updatePasswordLists'); - } - }, - - /** - * Updates the list with the given entries and updates the visibility of the - * list and empty list placeholder. - * @param {!cr.ui.List} list The list to toggle visilibility for. - * @param {!Array} entries The list of entries. - */ - updateListAndVisibility_: function(list, entries) { - // Setting the dataModel results in a redraw of the viewport, which is why - // the visibility needs to be updated first. Otherwise, redraw will not - // render the updated entries when transitioning from a previously empty - // list to a non-empty one. The attribute list.hidden would be true in - // this case, resulting in |redraw()| not adding the new elements to the - // viewport and thus showing a empty list to the user - // (http://crbug.com/672869). - var empty = entries.length == 0; - var listPlaceHolderID = list.id + '-empty-placeholder'; - list.hidden = empty; - $(listPlaceHolderID).hidden = !empty; - list.dataModel = new ArrayDataModel(entries); - }, - - /** - * Updates the data model for the saved passwords list with the values from - * |entries|. - * @param {!Array} entries The list of saved password data. - */ - setSavedPasswordsList_: function(entries) { - if (this.lastQuery_) { - // Implement password searching here in javascript, rather than in C++. - // The number of saved passwords shouldn't be too big for us to handle. - var query = this.lastQuery_; - var filter = function(entry, index, list) { - // Search both shown URL and username. - var shownOrigin = entry[options.passwordManager.SHOWN_ORIGIN_FIELD]; - var username = entry[options.passwordManager.USERNAME_FIELD]; - if (shownOrigin.toLowerCase().indexOf(query.toLowerCase()) >= 0 || - username.toLowerCase().indexOf(query.toLowerCase()) >= 0) { - // Keep the original index so we can delete correctly. See also - // deleteItemAtIndex() in password_manager_list.js that uses this. - entry[options.passwordManager.ORIGINAL_INDEX_FIELD] = index; - return true; - } - return false; - }; - entries = entries.filter(filter); - } - this.updateListAndVisibility_(assert(this.savedPasswordsList_), entries); - }, - - /** - * Updates the data model for the password exceptions list with the values - * from |entries|. - * @param {!Array} entries The list of password exception data. - */ - setPasswordExceptionsList_: function(entries) { - this.updateListAndVisibility_( - assert(this.passwordExceptionsList_), entries); - }, - - /** - * Reveals the password for a saved password entry. This is called by the - * backend after it has authenticated the user. - * @param {number} index The original index of the entry in the model. - * @param {string} password The saved password. - */ - showPassword_: function(index, password) { - var model = this.savedPasswordsList_.dataModel; - if (this.lastQuery_) { - // When a filter is active, |index| does not represent the current - // index in the model, but each entry stores its original index, so - // we can find the item using a linear search. - for (var i = 0; i < model.length; ++i) { - if (model.item(i)[options.passwordManager.ORIGINAL_INDEX_FIELD] == - index) { - index = i; - break; - } - } - } - - // Reveal the password in the UI. - var item = this.savedPasswordsList_.getListItemByIndex(index); - item.showPassword(password); - }, - - /** @private */ - showImportExportButton_: function() { - $('password-manager-import-export').hidden = false; - }, - }; - - /** - * Removes a saved password. - * @param {number} rowIndex indicating the row to remove. - */ - PasswordManager.removeSavedPassword = function(rowIndex) { - chrome.send('removeSavedPassword', [String(rowIndex)]); - chrome.send('coreOptionsUserMetricsAction', - ['Options_PasswordManagerDeletePassword']); - }; - - /** - * Removes a password exception. - * @param {number} rowIndex indicating the row to remove. - */ - PasswordManager.removePasswordException = function(rowIndex) { - chrome.send('removePasswordException', [String(rowIndex)]); - }; - - PasswordManager.requestShowPassword = function(index) { - chrome.send('requestShowPassword', [index]); - }; - - // Forward public APIs to private implementations on the singleton instance. - cr.makePublic(PasswordManager, [ - 'setSavedPasswordsList', - 'setPasswordExceptionsList', - 'showImportExportButton', - 'showPassword', - ]); - - // Export - return { - PasswordManager: PasswordManager - }; - -});
diff --git a/chrome/browser/resources/options/password_manager_list.css b/chrome/browser/resources/options/password_manager_list.css deleted file mode 100644 index 5e2acacf..0000000 --- a/chrome/browser/resources/options/password_manager_list.css +++ /dev/null
@@ -1,95 +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. */ - -#saved-passwords-list .list-inline-button { - background: rgb(138, 170, 237); - font-size: 0.9em; - height: 18px; - margin-left: 2px; - margin-right: 2px; - padding: 0 2px; - position: absolute; - top: 3px; - transition: opacity 150ms; -} - -html[dir='ltr'] #saved-passwords-list .list-inline-button { - right: 2px; -} - -html[dir='rtl'] #saved-passwords-list .list-inline-button { - left: 2px; -} - -input.inactive-item { - background: transparent; - border: none; -} - -#saved-passwords-list .url { - box-sizing: border-box; - width: 40%; -} - -#saved-passwords-list .deletable-item:not(:hover) a:not(:focus) { - color: black; - text-decoration: none; -} - -#saved-passwords-list .name { - -webkit-box-flex: 1; - width: 30%; -} - -#saved-passwords-list .url, -#password-exceptions-list .url { - user-select: text; -} - -#saved-passwords-list .password, -#saved-passwords-list .federation { - -webkit-box-flex: 1; - position: relative; - width: 30%; -} - -#saved-passwords-list .password input[type='password'], -#saved-passwords-list .password input[type='text'] { - box-sizing: border-box; - width: 100%; -} - -#password-exceptions-list .url { - -webkit-box-flex: 1; -} - -#saved-passwords-list .url, -#saved-passwords-list .name, -#saved-passwords-list .federation, -#password-exceptions-list .url { - overflow: hidden; - text-overflow: ellipsis; -} - -html[dir='ltr'] #saved-passwords-list .url, -html[dir='ltr'] #password-exceptions-list .url { - -webkit-margin-end: 1em; - -webkit-margin-start: 0; - -webkit-padding-end: 2em; - -webkit-padding-start: 1em; - direction: rtl; - text-align: left; -} - -html[dir='rtl'] #saved-passwords-list .url, -html[dir='rtl'] #password-exceptions-list .url { - -webkit-margin-end: 0; - -webkit-margin-start: 1em; - -webkit-padding-end: 1em; - -webkit-padding-start: 2em; - /* Explicitly mention the direction, which, while the same, is independent of - * the surrounding text the for URLs. */ - direction: rtl; - text-align: right; -}
diff --git a/chrome/browser/resources/options/password_manager_list.js b/chrome/browser/resources/options/password_manager_list.js deleted file mode 100644 index 9fd160f..0000000 --- a/chrome/browser/resources/options/password_manager_list.js +++ /dev/null
@@ -1,552 +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. - -cr.define('options.passwordManager', function() { - /** @const */ var ArrayDataModel = cr.ui.ArrayDataModel; - /** @const */ var DeletableItemList = options.DeletableItemList; - /** @const */ var DeletableItem = options.DeletableItem; - /** @const */ var List = cr.ui.List; - - // The following constants should be synchronized with the constants in - // chrome/browser/ui/webui/options/password_manager_handler.cc. - /** @const */ var URL_FIELD = 'url'; - /** @const */ var SHOWN_ORIGIN_FIELD = 'shownOrigin'; - /** @const */ var IS_ANDROID_URI_FIELD = 'isAndroidUri'; - /** @const */ var IS_CLICKABLE_FIELD = 'isClickable'; - /** @const */ var IS_SECURE_FIELD = 'isSecure'; - /** @const */ var USERNAME_FIELD = 'username'; - /** @const */ var PASSWORD_FIELD = 'password'; - /** @const */ var FEDERATION_FIELD = 'federation'; - /** @const */ var ORIGINAL_INDEX_FIELD = 'index'; - - /** - * Creates a new passwords list item. - * @param {cr.ui.ArrayDataModel} dataModel The data model that contains this - * item. - * @param {Object} entry A dictionary of data on new list item. When the - * list has been filtered, one more element [index] may be present. - * @param {boolean} showPasswords If true, add a button to the element to - * allow the user to reveal the saved password. - * @constructor - * @extends {options.DeletableItem} - */ - function PasswordListItem(dataModel, entry, showPasswords) { - var el = cr.doc.createElement('div'); - el.dataItem = entry; - el.dataModel = dataModel; - el.__proto__ = PasswordListItem.prototype; - el.showPasswords_ = showPasswords; - el.decorate(); - - return el; - } - - /** - * Returns title for password's origin. If the origin is not clickable, - * returns the origin as it is. For clickable origins, removes the scheme if - * the url is insecure and removes trailing punctuation symbols. - * @param {Object} item A dictionary of data on the list item. - * @return {string} The title for password's origin. - */ - function getTitleForPasswordOrigin(item) { - var title = item.url; - if (!item.isClickable) - return title; - if (!item.isSecure) { - var ind = title.indexOf('://'); - if (ind >= 0) { - title = title.substring(ind + 3); - } - } - return title; - } - - /** - * Helper function that creates an HTML element for displaying the link to - * the origin of saved password. - * @param {Object} item A dictionary of data on the list item. - * @param {Element} urlDiv div-element that will enclose the created - * element. - * @return {Element} The element for displaying the link to the origin. - */ - function createUrlLink(item, urlDiv) { - var urlLink; - if (item.isClickable) { - urlLink = item.ownerDocument.createElement('a'); - urlLink.href = item.url; - urlLink.setAttribute('target', '_blank'); - } else { - urlLink = item.ownerDocument.createElement('span'); - } - urlLink.textContent = item.shownOrigin; - urlLink.addEventListener('focus', function() { - item.handleFocus(); - }.bind(item)); - return urlLink; - } - - /** - * Helper function that creates an HTML element for displaying the origin of - * saved password. It also sets some properties in |item|. - * @param {Object} item A dictionary of data on the list item. - * @return {Element} The element for displaying the origin of saved password. - */ - function createUrlDiv(item) { - var urlDiv = cr.doc.createElement('div'); - urlDiv.className = 'favicon-cell url'; - urlDiv.setAttribute('title', getTitleForPasswordOrigin(item)); - urlDiv.style.backgroundImage = cr.icon.getFavicon(item.url); - - item.urlLink = createUrlLink(item, urlDiv); - urlDiv.appendChild(item.urlLink); - - if (item.isAndroidUri && item.isClickable) { - item.androidUriSuffix = cr.doc.createElement('span'); - item.androidUriSuffix.textContent = - loadTimeData.getString('androidUriSuffix'); - urlDiv.appendChild(item.androidUriSuffix); - } - - item.urlDiv = urlDiv; - return urlDiv; - } - - PasswordListItem.prototype = { - __proto__: DeletableItem.prototype, - - /** @override */ - decorate: function() { - DeletableItem.prototype.decorate.call(this); - - // The URL of the site. - this.contentElement.appendChild(createUrlDiv(this)); - - // The stored username. - var usernameDiv = this.ownerDocument.createElement('div'); - usernameDiv.className = 'name'; - usernameDiv.title = this.username; - this.contentElement.appendChild(usernameDiv); - var usernameInput = this.ownerDocument.createElement('input'); - usernameInput.type = 'text'; - usernameInput.className = 'inactive-item'; - usernameInput.readOnly = true; - usernameInput.value = this.username; - usernameInput.addEventListener('focus', function() { - this.handleFocus(); - }.bind(this)); - usernameDiv.appendChild(usernameInput); - this.usernameField = usernameInput; - - if (this.federation) { - // The federation. - var federationDiv = this.ownerDocument.createElement('div'); - federationDiv.className = 'federation'; - federationDiv.textContent = this.federation; - federationDiv.title = this.federation; - this.contentElement.appendChild(federationDiv); - } else { - // The stored password. - var passwordInputDiv = this.ownerDocument.createElement('div'); - passwordInputDiv.className = 'password'; - - // The password input field. - var passwordInput = this.ownerDocument.createElement('input'); - passwordInput.type = 'password'; - passwordInput.className = 'inactive-item'; - passwordInput.readOnly = true; - passwordInput.value = this.showPasswords_ ? this.password : '********'; - passwordInputDiv.appendChild(passwordInput); - passwordInput.addEventListener('focus', function() { - this.handleFocus(); - }.bind(this)); - this.passwordField = passwordInput; - - // The show/hide button. - if (this.showPasswords_) { - var button = this.ownerDocument.createElement('button'); - button.hidden = true; - button.className = 'list-inline-button custom-appearance'; - button.textContent = loadTimeData.getString('passwordShowButton'); - button.addEventListener('click', this.onClick_.bind(this), true); - button.addEventListener('mousedown', function(event) { - // Don't focus on this button by mousedown. - event.preventDefault(); - // Don't handle list item selection. It causes focus change. - event.stopPropagation(); - }, false); - button.addEventListener('focus', function() { - this.handleFocus(); - }.bind(this)); - passwordInputDiv.appendChild(button); - this.passwordShowButton = button; - } - this.contentElement.appendChild(passwordInputDiv); - } - this.setFocusable_(false); - }, - - /** @override */ - selectionChanged: function() { - var usernameInput = this.usernameField; - var passwordInput = this.passwordField; - var button = this.passwordShowButton; - - this.setFocusable_(this.selected); - - if (this.selected) { - usernameInput.classList.remove('inactive-item'); - if (button) { - passwordInput.classList.remove('inactive-item'); - button.hidden = false; - passwordInput.focus(); - } else { - usernameInput.focus(); - } - } else { - usernameInput.classList.add('inactive-item'); - if (button) { - passwordInput.classList.add('inactive-item'); - button.hidden = true; - } - } - }, - - /** - * Set the focusability of this row. - * @param {boolean} focusable - * @private - */ - setFocusable_: function(focusable) { - var tabIndex = focusable ? 0 : -1; - this.urlLink.tabIndex = tabIndex; - this.usernameField.tabIndex = tabIndex; - this.closeButtonElement.tabIndex = tabIndex; - if (this.passwordShowButton) - this.passwordField.tabIndex = tabIndex; - }, - - /** - * Reveals the plain text password of this entry. - */ - showPassword: function(password) { - this.passwordField.value = password; - this.passwordField.type = 'text'; - - var button = this.passwordShowButton; - if (button) - button.textContent = loadTimeData.getString('passwordHideButton'); - }, - - /** - * Hides the plain text password of this entry. - */ - hidePassword: function() { - this.passwordField.type = 'password'; - - var button = this.passwordShowButton; - if (button) - button.textContent = loadTimeData.getString('passwordShowButton'); - }, - - /** - * Get the original index of this item in the data model. - * @return {number} The index. - * @private - */ - getOriginalIndex_: function() { - var index = this.dataItem[ORIGINAL_INDEX_FIELD]; - return index ? index : this.dataModel.indexOf(this.dataItem); - }, - - /** - * On-click event handler. Swaps the type of the input field from password - * to text and back. - * @private - */ - onClick_: function(event) { - if (this.passwordField.type == 'password') { - // After the user is authenticated, showPassword() will be called. - PasswordManager.requestShowPassword(this.getOriginalIndex_()); - } else { - this.hidePassword(); - } - }, - - /** - * Get the URL for the entry. - * @type {string} - */ - get url() { - return this.dataItem[URL_FIELD]; - }, - - /** - * Get the shown origin for the entry. - * @type {string} - */ - get shownOrigin() { - return this.dataItem[SHOWN_ORIGIN_FIELD]; - }, - - /** - * Get whether the origin is Android URI. - * @type {boolean} - */ - get isAndroidUri() { - return this.dataItem[IS_ANDROID_URI_FIELD]; - }, - - /** - * Get whether the origin is clickable. - * @type {boolean} - */ - get isClickable() { - return this.dataItem[IS_CLICKABLE_FIELD]; - }, - - /** - * Get whether the origin uses secure scheme. - * @type {boolean} - */ - get isSecure() { - return this.dataItem[IS_SECURE_FIELD]; - }, - - /** - * Get the username for the entry. - * @type {string} - */ - get username() { - return this.dataItem[USERNAME_FIELD]; - }, - - /** - * Get the password for the entry. - * @type {string} - */ - get password() { - return this.dataItem[PASSWORD_FIELD]; - }, - - /** - * Get the federation for the entry. - * @type {string} - */ - get federation() { - return this.dataItem[FEDERATION_FIELD]; - }, - }; - - /** - * Creates a new PasswordExceptions list item. - * @param {Object} entry A dictionary of data on new list item. - * @constructor - * @extends {options.DeletableItem} - */ - function PasswordExceptionsListItem(entry) { - var el = cr.doc.createElement('div'); - el.dataItem = entry; - el.__proto__ = PasswordExceptionsListItem.prototype; - el.decorate(); - - return el; - } - - PasswordExceptionsListItem.prototype = { - __proto__: DeletableItem.prototype, - - /** - * Call when an element is decorated as a list item. - */ - decorate: function() { - DeletableItem.prototype.decorate.call(this); - - // The URL of the site. - this.contentElement.appendChild(createUrlDiv(this)); - }, - - /** @override */ - selectionChanged: function() { - if (this.selected) { - this.setFocusable_(true); - this.urlLink.focus(); - } else { - this.setFocusable_(false); - } - }, - - /** - * Set the focusability of this row. - * @param {boolean} focusable - * @private - */ - setFocusable_: function(focusable) { - var tabIndex = focusable ? 0 : -1; - this.urlLink.tabIndex = tabIndex; - this.closeButtonElement.tabIndex = tabIndex; - }, - - /** - * Get the url for the entry. - * @type {string} - */ - get url() { - return this.dataItem[URL_FIELD]; - }, - - /** - * Get the shown origin for the entry. - * @type {string} - */ - get shownOrigin() { - return this.dataItem[SHOWN_ORIGIN_FIELD]; - }, - - /** - * Get whether the origin is Android URI. - * @type {boolean} - */ - get isAndroidUri() { - return this.dataItem[IS_ANDROID_URI_FIELD]; - }, - - /** - * Get whether the origin is clickable. - * @type {boolean} - */ - get isClickable() { - return this.dataItem[IS_CLICKABLE_FIELD]; - }, - - /** - * Get whether the origin uses secure scheme. - * @type {boolean} - */ - get isSecure() { - return this.dataItem[IS_SECURE_FIELD]; - }, - }; - - /** - * Create a new passwords list. - * @constructor - * @extends {options.DeletableItemList} - */ - var PasswordsList = cr.ui.define('list'); - - PasswordsList.prototype = { - __proto__: DeletableItemList.prototype, - - /** - * Whether passwords can be revealed or not. - * @type {boolean} - * @private - */ - showPasswords_: true, - - /** @override */ - decorate: function() { - DeletableItemList.prototype.decorate.call(this); - this.addEventListener('focus', this.onFocus_.bind(this)); - }, - - /** - * Listener for changes on the preference. - * @param {Event} event The preference update event. - * @private - */ - onPreferenceChanged_: function(event) { - this.showPasswords_ = event.value.value; - this.redraw(); - }, - - /** - * @override - * @param {Array} entry - */ - createItem: function(entry) { - var showPasswords = this.showPasswords_; - - if (loadTimeData.getBoolean('disableShowPasswords')) - showPasswords = false; - - return new PasswordListItem(this.dataModel, entry, showPasswords); - }, - - /** @override */ - deleteItemAtIndex: function(index) { - var item = this.dataModel.item(index); - if (item && item[ORIGINAL_INDEX_FIELD] != undefined) { - // The fifth element, if present, is the original index to delete. - index = item[ORIGINAL_INDEX_FIELD]; - } - PasswordManager.removeSavedPassword(index); - }, - - /** - * The length of the list. - */ - get length() { - return this.dataModel.length; - }, - - /** - * Will make to first row focusable if none are selected. This makes it - * possible to tab into the rows without pressing up/down first. - * @param {Event} e The focus event. - * @private - */ - onFocus_: function(e) { - if (!this.selectedItem && this.items) - this.items[0].setFocusable_(true); - }, - }; - - /** - * Create a new passwords list. - * @constructor - * @extends {options.DeletableItemList} - */ - var PasswordExceptionsList = cr.ui.define('list'); - - PasswordExceptionsList.prototype = { - __proto__: DeletableItemList.prototype, - - /** - * @override - * @param {Array} entry - */ - createItem: function(entry) { - return new PasswordExceptionsListItem(entry); - }, - - /** @override */ - deleteItemAtIndex: function(index) { - PasswordManager.removePasswordException(index); - }, - - /** - * The length of the list. - */ - get length() { - return this.dataModel.length; - }, - }; - - return { - PasswordListItem: PasswordListItem, - PasswordExceptionsListItem: PasswordExceptionsListItem, - PasswordsList: PasswordsList, - PasswordExceptionsList: PasswordExceptionsList, - URL_FIELD: URL_FIELD, - SHOWN_ORIGIN_FIELD: SHOWN_ORIGIN_FIELD, - IS_ANDROID_URI_FIELD: IS_ANDROID_URI_FIELD, - IS_CLICKABLE_FIELD: IS_CLICKABLE_FIELD, - IS_SECURE_FIELD: IS_SECURE_FIELD, - USERNAME_FIELD: USERNAME_FIELD, - PASSWORD_FIELD: PASSWORD_FIELD, - FEDERATION_FIELD: FEDERATION_FIELD, - ORIGINAL_INDEX_FIELD: ORIGINAL_INDEX_FIELD - }; -});
diff --git a/chrome/browser/resources/options/pref_ui.js b/chrome/browser/resources/options/pref_ui.js deleted file mode 100644 index c0776fee..0000000 --- a/chrome/browser/resources/options/pref_ui.js +++ /dev/null
@@ -1,639 +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. - -cr.define('options', function() { - var Preferences = options.Preferences; - - /** - * Allows an element to be disabled for several reasons. - * The element is disabled if at least one reason is true, and the reasons - * can be set separately. - * @private - * @param {!HTMLElement} el The element to update. - * @param {string} reason The reason for disabling the element. - * @param {boolean} disabled Whether the element should be disabled or enabled - * for the given |reason|. - */ - function updateDisabledState(el, reason, disabled) { - if (!el.disabledReasons) - el.disabledReasons = {}; - - if (el.disabled && (Object.keys(el.disabledReasons).length == 0)) { - // The element has been previously disabled without a reason, so we add - // one to keep it disabled. - el.disabledReasons.other = true; - } - - if (!el.disabled) { - // If the element is not disabled, there should be no reason, except for - // 'other'. - delete el.disabledReasons.other; - if (Object.keys(el.disabledReasons).length > 0) - console.error('Element is not disabled but should be'); - } - - if (disabled) - el.disabledReasons[reason] = true; - else - delete el.disabledReasons[reason]; - - el.disabled = Object.keys(el.disabledReasons).length > 0; - } - - ///////////////////////////////////////////////////////////////////////////// - // PrefInputElement class: - - /** - * Define a constructor that uses an input element as its underlying element. - * @constructor - * @extends {HTMLInputElement} - */ - var PrefInputElement = cr.ui.define('input'); - - PrefInputElement.prototype = { - // Set up the prototype chain - __proto__: HTMLInputElement.prototype, - - /** - * Initialization function for the cr.ui framework. - */ - decorate: function() { - var self = this; - - // Listen for user events. - this.addEventListener('change', this.handleChange.bind(this)); - - // Listen for pref changes. - Preferences.getInstance().addEventListener(this.pref, function(event) { - if (event.value.uncommitted && !self.dialogPref) - return; - self.updateStateFromPref(event); - updateDisabledState(self, 'notUserModifiable', event.value.disabled); - self.controlledBy = event.value.controlledBy; - }); - }, - - /** - * Handle changes to the input element's state made by the user. If a custom - * change handler does not suppress it, a default handler is invoked that - * updates the associated pref. - * @param {Event} event Change event. - * @protected - */ - handleChange: function(event) { - if (!this.customChangeHandler(event)) - this.updatePrefFromState(); - }, - - /** - * Handles changes to the pref. If a custom change handler does not suppress - * it, a default handler is invoked that updates the input element's state. - * @param {Event} event Pref change event. - * @protected - */ - updateStateFromPref: function(event) { - if (!this.customPrefChangeHandler(event)) - this.value = event.value.value; - }, - - /** - * An abstract method for all subclasses to override to update their - * preference from existing state. - * @protected - */ - updatePrefFromState: assertNotReached, - - /** - * See |updateDisabledState| above. - */ - setDisabled: function(reason, disabled) { - updateDisabledState(this, reason, disabled); - }, - - /** - * Custom change handler that is invoked first when the user makes changes - * to the input element's state. If it returns false, a default handler is - * invoked next that updates the associated pref. If it returns true, the - * default handler is suppressed (i.e., this works like stopPropagation or - * cancelBubble). - * @param {Event} event Input element change event. - */ - customChangeHandler: function(event) { - return false; - }, - - /** - * Custom change handler that is invoked first when the preference - * associated with the input element changes. If it returns false, a default - * handler is invoked next that updates the input element. If it returns - * true, the default handler is suppressed. - * @param {Event} event Input element change event. - */ - customPrefChangeHandler: function(event) { - return false; - }, - }; - - /** - * The name of the associated preference. - */ - cr.defineProperty(PrefInputElement, 'pref', cr.PropertyKind.ATTR); - - /** - * The data type of the associated preference, only relevant for derived - * classes that support different data types. - */ - cr.defineProperty(PrefInputElement, 'dataType', cr.PropertyKind.ATTR); - - /** - * Whether this input element is part of a dialog. If so, changes take effect - * in the settings UI immediately but are only actually committed when the - * user confirms the dialog. If the user cancels the dialog instead, the - * changes are rolled back in the settings UI and never committed. - */ - cr.defineProperty(PrefInputElement, 'dialogPref', cr.PropertyKind.BOOL_ATTR); - - /** - * Whether the associated preference is controlled by a source other than the - * user's setting (can be 'policy', 'extension', 'recommended' or unset). - */ - cr.defineProperty(PrefInputElement, 'controlledBy', cr.PropertyKind.ATTR); - - /** - * The user metric string. - */ - cr.defineProperty(PrefInputElement, 'metric', cr.PropertyKind.ATTR); - - ///////////////////////////////////////////////////////////////////////////// - // PrefCheckbox class: - - /** - * Define a constructor that uses an input element as its underlying element. - * @constructor - * @extends {options.PrefInputElement} - */ - var PrefCheckbox = cr.ui.define('input'); - - PrefCheckbox.prototype = { - // Set up the prototype chain - __proto__: PrefInputElement.prototype, - - /** - * Initialization function for the cr.ui framework. - */ - decorate: function() { - PrefInputElement.prototype.decorate.call(this); - this.type = 'checkbox'; - - // Consider a checked dialog checkbox as a 'suggestion' which is committed - // once the user confirms the dialog. - if (this.dialogPref && this.checked) - this.updatePrefFromState(); - }, - - /** - * Update the associated pref when when the user makes changes to the - * checkbox state. - * @override - */ - updatePrefFromState: function() { - var value = this.inverted_pref ? !this.checked : this.checked; - Preferences.setBooleanPref(this.pref, value, - !this.dialogPref, this.metric); - }, - - /** @override */ - updateStateFromPref: function(event) { - if (!this.customPrefChangeHandler(event)) - this.defaultPrefChangeHandler(event); - }, - - /** - * @param {Event} event A pref change event. - */ - defaultPrefChangeHandler: function(event) { - var value = Boolean(event.value.value); - this.checked = this.inverted_pref ? !value : value; - }, - }; - - /** - * Whether the mapping between checkbox state and associated pref is inverted. - */ - cr.defineProperty(PrefCheckbox, 'inverted_pref', cr.PropertyKind.BOOL_ATTR); - - ///////////////////////////////////////////////////////////////////////////// - // PrefNumber class: - - // Define a constructor that uses an input element as its underlying element. - var PrefNumber = cr.ui.define('input'); - - PrefNumber.prototype = { - // Set up the prototype chain - __proto__: PrefInputElement.prototype, - - /** - * Initialization function for the cr.ui framework. - */ - decorate: function() { - PrefInputElement.prototype.decorate.call(this); - this.type = 'number'; - }, - - /** - * Update the associated pref when the user inputs a number. - * @override - */ - updatePrefFromState: function() { - if (this.validity.valid) { - Preferences.setIntegerPref(this.pref, this.value, - !this.dialogPref, this.metric); - } - }, - }; - - ///////////////////////////////////////////////////////////////////////////// - // PrefRadio class: - - //Define a constructor that uses an input element as its underlying element. - var PrefRadio = cr.ui.define('input'); - - PrefRadio.prototype = { - // Set up the prototype chain - __proto__: PrefInputElement.prototype, - - /** - * Initialization function for the cr.ui framework. - */ - decorate: function() { - PrefInputElement.prototype.decorate.call(this); - this.type = 'radio'; - }, - - /** - * Update the associated pref when when the user selects the radio button. - * @override - */ - updatePrefFromState: function() { - if (this.value == 'true' || this.value == 'false') { - Preferences.setBooleanPref(this.pref, - this.value == String(this.checked), - !this.dialogPref, this.metric); - } else { - Preferences.setIntegerPref(this.pref, this.value, - !this.dialogPref, this.metric); - } - }, - - /** @override */ - updateStateFromPref: function(event) { - if (!this.customPrefChangeHandler(event)) - this.checked = this.value == String(event.value.value); - }, - }; - - ///////////////////////////////////////////////////////////////////////////// - // PrefRange class: - - /** - * Define a constructor that uses an input element as its underlying element. - * @constructor - * @extends {options.PrefInputElement} - */ - var PrefRange = cr.ui.define('input'); - - PrefRange.prototype = { - // Set up the prototype chain - __proto__: PrefInputElement.prototype, - - /** - * The map from slider position to corresponding pref value. - */ - valueMap: undefined, - - /** - * Initialization function for the cr.ui framework. - */ - decorate: function() { - PrefInputElement.prototype.decorate.call(this); - this.type = 'range'; - - // Listen for user events. - // TODO(jhawkins): Add onmousewheel handling once the associated WK bug is - // fixed. - // https://bugs.webkit.org/show_bug.cgi?id=52256 - this.addEventListener('keyup', this.handleRelease_.bind(this)); - this.addEventListener('mouseup', this.handleRelease_.bind(this)); - this.addEventListener('touchcancel', this.handleRelease_.bind(this)); - this.addEventListener('touchend', this.handleRelease_.bind(this)); - }, - - /** - * Update the associated pref when when the user releases the slider. - * @override - */ - updatePrefFromState: function() { - Preferences.setIntegerPref( - this.pref, - this.mapPositionToPref(parseInt(this.value, 10)), - !this.dialogPref, - this.metric); - }, - - /** @override */ - handleChange: function() { - // Ignore changes to the slider position made by the user while the slider - // has not been released. - }, - - /** - * Handle changes to the slider position made by the user when the slider is - * released. If a custom change handler does not suppress it, a default - * handler is invoked that updates the associated pref. - * @param {Event} event Change event. - * @private - */ - handleRelease_: function(event) { - if (!this.customChangeHandler(event)) - this.updatePrefFromState(); - }, - - /** - * Handles changes to the pref associated with the slider. If a custom - * change handler does not suppress it, a default handler is invoked that - * updates the slider position. - * @override. - */ - updateStateFromPref: function(event) { - if (this.customPrefChangeHandler(event)) - return; - var value = event.value.value; - this.value = this.valueMap ? this.valueMap.indexOf(value) : value; - }, - - /** - * Map slider position to the range of values provided by the client, - * represented by |valueMap|. - * @param {number} position The slider position to map. - */ - mapPositionToPref: function(position) { - return this.valueMap ? this.valueMap[position] : position; - }, - }; - - ///////////////////////////////////////////////////////////////////////////// - // PrefSelect class: - - // Define a constructor that uses a select element as its underlying element. - var PrefSelect = cr.ui.define('select'); - - PrefSelect.prototype = { - // Set up the prototype chain - __proto__: HTMLSelectElement.prototype, - - /** @override */ - decorate: PrefInputElement.prototype.decorate, - - /** @override */ - handleChange: PrefInputElement.prototype.handleChange, - - /** - * Update the associated pref when when the user selects an item. - * @override - */ - updatePrefFromState: function() { - var value = this.options[this.selectedIndex].value; - switch (this.dataType) { - case 'number': - Preferences.setIntegerPref(this.pref, value, - !this.dialogPref, this.metric); - break; - case 'double': - Preferences.setDoublePref(this.pref, value, - !this.dialogPref, this.metric); - break; - case 'boolean': - Preferences.setBooleanPref(this.pref, value == 'true', - !this.dialogPref, this.metric); - break; - case 'string': - Preferences.setStringPref(this.pref, value, - !this.dialogPref, this.metric); - break; - default: - console.error('Unknown data type for <select> UI element: ' + - this.dataType); - } - }, - - /** @override */ - updateStateFromPref: function(event) { - if (this.customPrefChangeHandler(event)) - return; - - // Make sure the value is a string, because the value is stored as a - // string in the HTMLOptionElement. - var value = String(event.value.value); - - var found = false; - for (var i = 0; i < this.options.length; i++) { - if (this.options[i].value == value) { - this.selectedIndex = i; - found = true; - } - } - - // Item not found, select first item. - if (!found) - this.selectedIndex = 0; - - // The "onchange" event automatically fires when the user makes a manual - // change. It should never be fired for a programmatic change. However, - // these two lines were here already and it is hard to tell who may be - // relying on them. - if (this.onchange) - this.onchange(event); - }, - - /** @override */ - setDisabled: PrefInputElement.prototype.setDisabled, - - /** @override */ - customChangeHandler: PrefInputElement.prototype.customChangeHandler, - - /** @override */ - customPrefChangeHandler: PrefInputElement.prototype.customPrefChangeHandler, - }; - - /** - * The name of the associated preference. - */ - cr.defineProperty(PrefSelect, 'pref', cr.PropertyKind.ATTR); - - /** - * The data type of the associated preference, only relevant for derived - * classes that support different data types. - */ - cr.defineProperty(PrefSelect, 'dataType', cr.PropertyKind.ATTR); - - /** - * Whether this input element is part of a dialog. If so, changes take effect - * in the settings UI immediately but are only actually committed when the - * user confirms the dialog. If the user cancels the dialog instead, the - * changes are rolled back in the settings UI and never committed. - */ - cr.defineProperty(PrefSelect, 'dialogPref', cr.PropertyKind.BOOL_ATTR); - - /** - * Whether the associated preference is controlled by a source other than the - * user's setting (can be 'policy', 'extension', 'recommended' or unset). - */ - cr.defineProperty(PrefSelect, 'controlledBy', cr.PropertyKind.ATTR); - - /** - * The user metric string. - */ - cr.defineProperty(PrefSelect, 'metric', cr.PropertyKind.ATTR); - - ///////////////////////////////////////////////////////////////////////////// - // PrefTextField class: - - // Define a constructor that uses an input element as its underlying element. - var PrefTextField = cr.ui.define('input'); - - PrefTextField.prototype = { - // Set up the prototype chain - __proto__: PrefInputElement.prototype, - - /** - * Initialization function for the cr.ui framework. - */ - decorate: function() { - PrefInputElement.prototype.decorate.call(this); - var self = this; - - // Listen for user events. - window.addEventListener('unload', function() { - if (document.activeElement == self) - self.blur(); - }); - }, - - /** - * Update the associated pref when when the user inputs text. - * @override - */ - updatePrefFromState: function(event) { - switch (this.dataType) { - case 'number': - Preferences.setIntegerPref(this.pref, this.value, - !this.dialogPref, this.metric); - break; - case 'double': - Preferences.setDoublePref(this.pref, this.value, - !this.dialogPref, this.metric); - break; - case 'url': - Preferences.setURLPref(this.pref, this.value, - !this.dialogPref, this.metric); - break; - default: - Preferences.setStringPref(this.pref, this.value, - !this.dialogPref, this.metric); - break; - } - }, - }; - - ///////////////////////////////////////////////////////////////////////////// - // PrefPortNumber class: - - // Define a constructor that uses an input element as its underlying element. - var PrefPortNumber = cr.ui.define('input'); - - PrefPortNumber.prototype = { - // Set up the prototype chain - __proto__: PrefTextField.prototype, - - /** - * Initialization function for the cr.ui framework. - */ - decorate: function() { - var self = this; - self.type = 'text'; - self.dataType = 'number'; - PrefTextField.prototype.decorate.call(this); - self.oninput = function() { - // Note that using <input type="number"> is insufficient to restrict - // the input as it allows negative numbers and does not limit the - // number of charactes typed even if a range is set. Furthermore, - // it sometimes produces strange repaint artifacts. - var filtered = self.value.replace(/[^0-9]/g, ''); - if (filtered != self.value) - self.value = filtered; - }; - } - }; - - ///////////////////////////////////////////////////////////////////////////// - // PrefButton class: - - // Define a constructor that uses a button element as its underlying element. - var PrefButton = cr.ui.define('button'); - - PrefButton.prototype = { - // Set up the prototype chain - __proto__: HTMLButtonElement.prototype, - - /** - * Initialization function for the cr.ui framework. - */ - decorate: function() { - var self = this; - - // Listen for pref changes. - // This element behaves like a normal button and does not affect the - // underlying preference; it just becomes disabled when the preference is - // managed, and its value is false. This is useful for buttons that should - // be disabled when the underlying Boolean preference is set to false by a - // policy or extension. - Preferences.getInstance().addEventListener(this.pref, function(event) { - updateDisabledState(self, 'notUserModifiable', - event.value.disabled && !event.value.value); - self.controlledBy = event.value.controlledBy; - }); - }, - - /** - * See |updateDisabledState| above. - */ - setDisabled: function(reason, disabled) { - updateDisabledState(this, reason, disabled); - }, - }; - - /** - * The name of the associated preference. - */ - cr.defineProperty(PrefButton, 'pref', cr.PropertyKind.ATTR); - - /** - * Whether the associated preference is controlled by a source other than the - * user's setting (can be 'policy', 'extension', 'recommended' or unset). - */ - cr.defineProperty(PrefButton, 'controlledBy', cr.PropertyKind.ATTR); - - // Export - return { - PrefCheckbox: PrefCheckbox, - PrefInputElement: PrefInputElement, - PrefNumber: PrefNumber, - PrefRadio: PrefRadio, - PrefRange: PrefRange, - PrefSelect: PrefSelect, - PrefTextField: PrefTextField, - PrefPortNumber: PrefPortNumber, - PrefButton: PrefButton - }; -});
diff --git a/chrome/browser/resources/options/preferences.js b/chrome/browser/resources/options/preferences.js deleted file mode 100644 index c7ea93d3..0000000 --- a/chrome/browser/resources/options/preferences.js +++ /dev/null
@@ -1,338 +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. - -cr.define('options', function() { - - ///////////////////////////////////////////////////////////////////////////// - // Preferences class: - - /** - * Preferences class manages access to Chrome profile preferences. - * @constructor - * @extends {cr.EventTarget} - */ - function Preferences() { - // Map of registered preferences. - this.registeredPreferences_ = {}; - } - - cr.addSingletonGetter(Preferences); - - /** - * Sets a Boolean preference and signals its new value. - * @param {string} name Preference name. - * @param {boolean} value New preference value. - * @param {boolean} commit Whether to commit the change to Chrome. - * @param {string=} opt_metric User metrics identifier. - */ - Preferences.setBooleanPref = function(name, value, commit, opt_metric) { - if (!commit) { - Preferences.getInstance().setPrefNoCommit_(name, 'bool', Boolean(value)); - return; - } - - var argumentList = [name, Boolean(value)]; - if (opt_metric != undefined) argumentList.push(opt_metric); - chrome.send('setBooleanPref', argumentList); - }; - - /** - * Sets an integer preference and signals its new value. - * @param {string} name Preference name. - * @param {number} value New preference value. - * @param {boolean} commit Whether to commit the change to Chrome. - * @param {string} metric User metrics identifier. - */ - Preferences.setIntegerPref = function(name, value, commit, metric) { - if (!commit) { - Preferences.getInstance().setPrefNoCommit_(name, 'int', Number(value)); - return; - } - - var argumentList = [name, Number(value)]; - if (metric != undefined) argumentList.push(metric); - chrome.send('setIntegerPref', argumentList); - }; - - /** - * Sets a double-valued preference and signals its new value. - * @param {string} name Preference name. - * @param {number} value New preference value. - * @param {boolean} commit Whether to commit the change to Chrome. - * @param {string} metric User metrics identifier. - */ - Preferences.setDoublePref = function(name, value, commit, metric) { - if (!commit) { - Preferences.getInstance().setPrefNoCommit_(name, 'double', Number(value)); - return; - } - - var argumentList = [name, Number(value)]; - if (metric != undefined) argumentList.push(metric); - chrome.send('setDoublePref', argumentList); - }; - - /** - * Sets a string preference and signals its new value. - * @param {string} name Preference name. - * @param {string} value New preference value. - * @param {boolean} commit Whether to commit the change to Chrome. - * @param {string} metric User metrics identifier. - */ - Preferences.setStringPref = function(name, value, commit, metric) { - if (!commit) { - Preferences.getInstance().setPrefNoCommit_(name, 'string', String(value)); - return; - } - - var argumentList = [name, String(value)]; - if (metric != undefined) argumentList.push(metric); - chrome.send('setStringPref', argumentList); - }; - - /** - * Sets a string preference that represents a URL and signals its new value. - * The value will be fixed to be a valid URL when it gets committed to Chrome. - * @param {string} name Preference name. - * @param {string} value New preference value. - * @param {boolean} commit Whether to commit the change to Chrome. - * @param {string} metric User metrics identifier. - */ - Preferences.setURLPref = function(name, value, commit, metric) { - if (!commit) { - Preferences.getInstance().setPrefNoCommit_(name, 'url', String(value)); - return; - } - - var argumentList = [name, String(value)]; - if (metric != undefined) argumentList.push(metric); - chrome.send('setURLPref', argumentList); - }; - - /** - * Sets a JSON list preference and signals its new value. - * @param {string} name Preference name. - * @param {Array} value New preference value. - * @param {boolean} commit Whether to commit the change to Chrome. - * @param {string} metric User metrics identifier. - */ - Preferences.setListPref = function(name, value, commit, metric) { - if (!commit) { - Preferences.getInstance().setPrefNoCommit_(name, 'list', value); - return; - } - - var argumentList = [name, JSON.stringify(value)]; - if (metric != undefined) argumentList.push(metric); - chrome.send('setListPref', argumentList); - }; - - /** - * Clears the user setting for a preference and signals its new effective - * value. - * @param {string} name Preference name. - * @param {boolean} commit Whether to commit the change to Chrome. - * @param {string=} opt_metric User metrics identifier. - */ - Preferences.clearPref = function(name, commit, opt_metric) { - if (!commit) { - Preferences.getInstance().clearPrefNoCommit_(name); - return; - } - - var argumentList = [name]; - if (opt_metric != undefined) argumentList.push(opt_metric); - chrome.send('clearPref', argumentList); - }; - - Preferences.prototype = { - __proto__: cr.EventTarget.prototype, - - /** - * Adds an event listener to the target. - * @param {string} type The name of the event. - * @param {EventListenerType} handler The handler for the event. This is - * called when the event is dispatched. - */ - addEventListener: function(type, handler) { - cr.EventTarget.prototype.addEventListener.call(this, type, handler); - if (!(type in this.registeredPreferences_)) - this.registeredPreferences_[type] = {}; - }, - - /** - * Initializes preference reading and change notifications. - */ - initialize: function() { - var params1 = ['Preferences.prefsFetchedCallback']; - var params2 = ['Preferences.prefsChangedCallback']; - for (var prefName in this.registeredPreferences_) { - params1.push(prefName); - params2.push(prefName); - } - chrome.send('fetchPrefs', params1); - chrome.send('observePrefs', params2); - }, - - /** - * Helper function for flattening of dictionary passed via fetchPrefs - * callback. - * @param {string} prefix Preference name prefix. - * @param {Object} dict Map with preference values. - * @private - */ - flattenMapAndDispatchEvent_: function(prefix, dict) { - for (var prefName in dict) { - var value = dict[prefName]; - if (typeof value == 'object' && - !this.registeredPreferences_[prefix + prefName]) { - this.flattenMapAndDispatchEvent_(prefix + prefName + '.', value); - } else if (value) { - var event = new Event(prefix + prefName); - this.registeredPreferences_[prefix + prefName].orig = value; - event.value = value; - this.dispatchEvent(event); - } - } - }, - - /** - * Sets a preference and signals its new value. The change is propagated - * throughout the UI code but is not committed to Chrome yet. The new value - * and its data type are stored so that commitPref() can later be used to - * invoke the appropriate set*Pref() method and actually commit the change. - * @param {string} name Preference name. - * @param {string} type Preference data type. - * @param {*} value New preference value. - * @private - */ - setPrefNoCommit_: function(name, type, value) { - var pref = this.registeredPreferences_[name]; - pref.action = 'set'; - pref.type = type; - pref.value = value; - - var event = new Event(name); - // Decorate pref value as CoreOptionsHandler::CreateValueForPref() does. - event.value = {value: value, uncommitted: true}; - if (pref.orig) { - event.value.recommendedValue = pref.orig.recommendedValue; - event.value.disabled = pref.orig.disabled; - } - this.dispatchEvent(event); - }, - - /** - * Clears a preference and signals its new value. The change is propagated - * throughout the UI code but is not committed to Chrome yet. - * @param {string} name Preference name. - * @private - */ - clearPrefNoCommit_: function(name) { - var pref = this.registeredPreferences_[name]; - pref.action = 'clear'; - delete pref.type; - delete pref.value; - - var event = new Event(name); - // Decorate pref value as CoreOptionsHandler::CreateValueForPref() does. - event.value = {controlledBy: 'recommended', uncommitted: true}; - if (pref.orig) { - event.value.value = pref.orig.recommendedValue; - event.value.recommendedValue = pref.orig.recommendedValue; - event.value.disabled = pref.orig.disabled; - } - this.dispatchEvent(event); - }, - - /** - * Commits a preference change to Chrome and signals the new preference - * value. Does nothing if there is no uncommitted change. - * @param {string} name Preference name. - * @param {string} metric User metrics identifier. - */ - commitPref: function(name, metric) { - var pref = this.registeredPreferences_[name]; - switch (pref.action) { - case 'set': - switch (pref.type) { - case 'bool': - Preferences.setBooleanPref(name, pref.value, true, metric); - break; - case 'int': - Preferences.setIntegerPref(name, pref.value, true, metric); - break; - case 'double': - Preferences.setDoublePref(name, pref.value, true, metric); - break; - case 'string': - Preferences.setStringPref(name, pref.value, true, metric); - break; - case 'url': - Preferences.setURLPref(name, pref.value, true, metric); - break; - case 'list': - Preferences.setListPref(name, pref.value, true, metric); - break; - } - break; - case 'clear': - Preferences.clearPref(name, true, metric); - break; - } - delete pref.action; - delete pref.type; - delete pref.value; - }, - - /** - * Rolls back a preference change and signals the original preference value. - * Does nothing if there is no uncommitted change. - * @param {string} name Preference name. - */ - rollbackPref: function(name) { - var pref = this.registeredPreferences_[name]; - if (!pref.action) - return; - - delete pref.action; - delete pref.type; - delete pref.value; - - var event = new Event(name); - event.value = pref.orig || {}; - event.value.uncommitted = true; - this.dispatchEvent(event); - } - }; - - /** - * Callback for fetchPrefs method. - * @param {Object} dict Map of fetched property values. - */ - Preferences.prefsFetchedCallback = function(dict) { - Preferences.getInstance().flattenMapAndDispatchEvent_('', dict); - }; - - /** - * Callback for observePrefs method. - * @param {Array} notification An array defining changed preference values. - * notification[0] contains name of the change preference while its new - * value is stored in notification[1]. - */ - Preferences.prefsChangedCallback = function(notification) { - var event = new Event(notification[0]); - event.value = notification[1]; - var prefs = Preferences.getInstance(); - prefs.registeredPreferences_[notification[0]] = {orig: notification[1]}; - if (event.value) - prefs.dispatchEvent(event); - }; - - // Export - return { - Preferences: Preferences - }; - -});
diff --git a/chrome/browser/resources/options/profiles_icon_grid.js b/chrome/browser/resources/options/profiles_icon_grid.js deleted file mode 100644 index 9d0401d..0000000 --- a/chrome/browser/resources/options/profiles_icon_grid.js +++ /dev/null
@@ -1,67 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -cr.define('options', function() { - /** @const */ var ListItem = cr.ui.ListItem; - /** @const */ var Grid = cr.ui.Grid; - /** @const */ var ListSingleSelectionModel = cr.ui.ListSingleSelectionModel; - - /** - * Creates a new profile icon grid item. - * @param {Object} iconURL The profile icon URL. - * @constructor - * @extends {cr.ui.GridItem} - */ - function ProfilesIconGridItem(iconURL) { - var el = cr.doc.createElement('span'); - el.iconURL_ = iconURL; - ProfilesIconGridItem.decorate(el); - return el; - } - - /** - * Decorates an element as a profile grid item. - * @param {!HTMLElement} el The element to decorate. - */ - ProfilesIconGridItem.decorate = function(el) { - el.__proto__ = ProfilesIconGridItem.prototype; - el.decorate(); - }; - - ProfilesIconGridItem.prototype = { - __proto__: ListItem.prototype, - - /** @override */ - decorate: function() { - ListItem.prototype.decorate.call(this); - var imageEl = cr.doc.createElement('img'); - imageEl.className = 'profile-icon'; - imageEl.style.content = cr.icon.getImage(this.iconURL_); - this.appendChild(imageEl); - - this.className = 'profile-icon-grid-item'; - }, - }; - - var ProfilesIconGrid = cr.ui.define('grid'); - - ProfilesIconGrid.prototype = { - __proto__: Grid.prototype, - - /** @override */ - decorate: function() { - Grid.prototype.decorate.call(this); - this.selectionModel = new ListSingleSelectionModel(); - }, - - /** @override */ - createItem: function(iconURL) { - return new ProfilesIconGridItem(iconURL); - }, - }; - - return { - ProfilesIconGrid: ProfilesIconGrid - }; -});
diff --git a/chrome/browser/resources/options/reset_profile_settings_overlay.css b/chrome/browser/resources/options/reset_profile_settings_overlay.css deleted file mode 100644 index c20f8220..0000000 --- a/chrome/browser/resources/options/reset_profile_settings_overlay.css +++ /dev/null
@@ -1,65 +0,0 @@ -/* Copyright 2013 The Chromium Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. */ - -#reset-profile-settings-overlay { - width: 500px; -} - -#reset-profile-settings-content-area { - -webkit-box-flex: 0; -} - -#reset-profile-settings-throbber { - margin: 4px 10px; - vertical-align: middle; - visibility: hidden; -} - -#feedback-bar { - -webkit-box-flex: 1; - -webkit-box-orient: vertical; -} - -#feedback-template { - -webkit-box-flex: 1; - overflow-y: auto; -} - -#feedback-template table { - table-layout: fixed; - width: 100%; -} - -#feedback-template table td { - word-wrap: break-word; -} - -#feedback-template .key { - padding-right: 5px; - text-align: right; - vertical-align: top; -} - -#feedback-template .value { - color: #333; - text-align: left; - white-space: pre-line; -} - -#feedback-bar span { - vertical-align: middle; -} - -#expand-feedback { - -webkit-mask-box-image: url(../../../../ui/webui/resources/images/help.svg); - background-color: #828282; - display: inline-block; - height: 14px; - opacity: 0.33; - width: 14px; -} - -#expand-feedback:hover { - opacity: 1; -}
diff --git a/chrome/browser/resources/options/reset_profile_settings_overlay.html b/chrome/browser/resources/options/reset_profile_settings_overlay.html deleted file mode 100644 index 07ba372..0000000 --- a/chrome/browser/resources/options/reset_profile_settings_overlay.html +++ /dev/null
@@ -1,45 +0,0 @@ -<div id="reset-profile-settings-overlay" class="page not-resizable" hidden> - <div class="close-button"></div> - <!-- Text populated dynamically from didShowPage. --> - <h1 id="reset-profile-settings-title"></h1> - <div id="reset-profile-settings-content-area" class="content-area"> - <!-- Text populated dynamically from didShowPage. --> - <span id="reset-profile-settings-explanation"></span> - </div> - <div class="action-area"> - <div class="hbox stretch"> - <a target="_blank" - href="$i18nRaw{resetProfileSettingsLearnMoreUrl}">$i18n{learnMore}</a> - </div> - <div class="action-area-right"> - <div id="reset-profile-settings-throbber" class="throbber"></div> - <div class="button-strip"> - <button id="reset-profile-settings-dismiss">$i18n{cancel}</button> - <button id="reset-profile-settings-commit"> - $i18n{resetProfileSettingsCommit} - </button> - </div> - </div> - </div> - <div id="feedback-bar" - class="gray-bottom-bar checkbox controlled-setting-with-label"> - <label> - <input id="send-settings" type="checkbox" checked> - <span> - <span>$i18n{resetProfileSettingsFeedback}</span> - <span id="expand-feedback"></span> - </span> - </label> - <div id="feedback-template" hidden> - <div> - <table> - <tr jsselect="feedbackInfo"> - <td class="key"><span jscontent="key">KEY</span></td> - <td class="value"><span jscontent="value">VALUE</span></td> - </tr> - </table> - </div> - </div> - </div> -</div> -<script src="chrome://resources/js/jstemplate_compiled.js"></script>
diff --git a/chrome/browser/resources/options/reset_profile_settings_overlay.js b/chrome/browser/resources/options/reset_profile_settings_overlay.js deleted file mode 100644 index 55091cf..0000000 --- a/chrome/browser/resources/options/reset_profile_settings_overlay.js +++ /dev/null
@@ -1,156 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -cr.define('options', function() { - var Page = cr.ui.pageManager.Page; - - var AutomaticSettingsResetBanner = options.AutomaticSettingsResetBanner; - - /** - * ResetProfileSettingsOverlay class - * - * Encapsulated handling of the 'Reset Profile Settings' and the 'Triggered - * Reset Profile Settings' overlay pages. See triggered_profile_resetter.h for - * when the triggered variant will be used. - * - * @constructor - * @param {boolean} isTriggered Whether the overlay is the triggered variant. - * @extends {cr.ui.pageManager.Page} - */ - function ResetProfileSettingsOverlay(isTriggered) { - this.isTriggered_ = isTriggered; - Page.call( - this, - isTriggered ? 'triggeredResetProfileSettings' : 'resetProfileSettings', - loadTimeData.getString(isTriggered ? - 'triggeredResetProfileSettingsOverlay' : - 'resetProfileSettingsOverlayTabTitle'), - 'reset-profile-settings-overlay'); - } - - ResetProfileSettingsOverlay.prototype = { - // Inherit ResetProfileSettingsOverlay from Page. - __proto__: Page.prototype, - - /** - * Indicates whether the overlay is a triggered reset overlay. - * @type {boolean} - * @private - */ - isTriggered_: false, - - /** @override */ - initializePage: function() { - Page.prototype.initializePage.call(this); - - if (!ResetProfileSettingsOverlay.listenersAdded_) { - $('reset-profile-settings-dismiss').onclick = function(e) { - ResetProfileSettingsOverlay.dismiss(); - }; - $('reset-profile-settings-commit').onclick = function(e) { - ResetProfileSettingsOverlay.setResettingState(true); - chrome.send('performResetProfileSettings', - [$('send-settings').checked, - ResetProfileSettingsOverlay.resetRequestOrigin_]); - }; - $('expand-feedback').onclick = function(e) { - var feedbackTemplate = $('feedback-template'); - feedbackTemplate.hidden = !feedbackTemplate.hidden; - e.preventDefault(); - }; - - ResetProfileSettingsOverlay.listenersAdded_ = true; - } - }, - - /** - * @override - * @suppress {checkTypes} - * TODO(vitalyp): remove the suppression. See the explanation in - * chrome/browser/resources/options/automatic_settings_reset_banner.js. - */ - didShowPage: function() { - $('reset-profile-settings-title').textContent = - loadTimeData.getString(this.isTriggered_ ? - 'triggeredResetProfileSettingsOverlay' : - 'resetProfileSettingsOverlay'); - $('reset-profile-settings-explanation').textContent = - loadTimeData.getString(this.isTriggered_ ? - 'triggeredResetProfileSettingsExplanation' : - 'resetProfileSettingsExplanation'); - - // Set ResetProfileSettingsOverlay.resetRequestOrigin_ to indicate where - // the reset request came from. - if (this.isTriggered_) { - ResetProfileSettingsOverlay.resetRequestOrigin_ = 'triggeredreset'; - } else { - // For the non-triggered reset overlay, a '#userclick' hash indicates - // that the reset request came from the user clicking on the reset - // settings button and is set by the browser_options page. A '#cct' hash - // indicates that the reset request came from the CCT by launching - // Chrome with the startup URL - // chrome://settings/resetProfileSettings#cct. - var hash = this.hash.slice(1).toLowerCase(); - ResetProfileSettingsOverlay.resetRequestOrigin_ = - (hash === 'cct' || hash === 'userclick') ? hash : ''; - this.setHash(''); - } - - chrome.send('onShowResetProfileDialog'); - }, - - /** @override */ - didClosePage: function() { - chrome.send('onHideResetProfileDialog'); - }, - }; - - /** @private {boolean} */ - ResetProfileSettingsOverlay.listenersAdded_ = false; - - /** @private {string} */ - ResetProfileSettingsOverlay.resetRequestOrigin_ = ''; - - /** - * Enables/disables UI elements after/while Chrome is performing a reset. - * @param {boolean} state If true, UI elements are disabled. - */ - ResetProfileSettingsOverlay.setResettingState = function(state) { - $('reset-profile-settings-throbber').style.visibility = - state ? 'visible' : 'hidden'; - $('reset-profile-settings-dismiss').disabled = state; - $('reset-profile-settings-commit').disabled = state; - }; - - /** - * Chrome callback to notify ResetProfileSettingsOverlay that the reset - * operation has terminated. - * @suppress {checkTypes} - * TODO(vitalyp): remove the suppression. See the explanation in - * chrome/browser/resources/options/automatic_settings_reset_banner.js. - */ - ResetProfileSettingsOverlay.doneResetting = function() { - AutomaticSettingsResetBanner.dismiss(); - ResetProfileSettingsOverlay.dismiss(); - }; - - /** - * Dismisses the overlay. - */ - ResetProfileSettingsOverlay.dismiss = function() { - PageManager.closeOverlay(); - ResetProfileSettingsOverlay.setResettingState(false); - }; - - ResetProfileSettingsOverlay.setFeedbackInfo = function(feedbackListData) { - var input = new JsEvalContext(feedbackListData); - var output = $('feedback-template'); - jstProcess(input, output); - }; - - // Export - return { - ResetProfileSettingsOverlay: ResetProfileSettingsOverlay - }; -});
diff --git a/chrome/browser/resources/options/search_box.html b/chrome/browser/resources/options/search_box.html deleted file mode 100644 index 854538e5..0000000 --- a/chrome/browser/resources/options/search_box.html +++ /dev/null
@@ -1,11 +0,0 @@ -<div id="searchBox" class="page"> - <header > - <span id="browser-options-search-field-container" - class="search-field-container"> - <a is="action-link" id="about-button" hidden>$i18n{aboutButton}</a> - <input id="search-field" type="search" - placeholder="$i18n{searchPlaceholder}" - aria-label="$i18n{searchPlaceholder}" incremental> - </span> - </header> -</div>
diff --git a/chrome/browser/resources/options/search_engine_manager.css b/chrome/browser/resources/options/search_engine_manager.css deleted file mode 100644 index 3235031..0000000 --- a/chrome/browser/resources/options/search_engine_manager.css +++ /dev/null
@@ -1,89 +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. */ - -#search-engine-manager-page { - width: 700px; -} - -.search-engine-list input { - width: 100%; -} - -.search-engine-list > div { - display: -webkit-box; -} - -.search-engine-list .favicon { - background-position: center center; - background-repeat: no-repeat; - background-size: 16px; - height: 16px; - line-height: 16px; - padding: 0 7px; - width: 16px; -} - -.search-engine-list .name-column { - -webkit-box-align: center; - -webkit-padding-end: 1ex; - box-sizing: border-box; - display: -webkit-box; - width: 30%; -} - -.search-engine-list .name-column :last-child { - -webkit-box-flex: 1; -} - -.search-engine-list .keyword-column { - -webkit-padding-end: 1ex; - box-sizing: border-box; - width: 26%; -} - -.search-engine-list .url-column { - box-sizing: border-box; - width: 44%; -} - -.search-engine-list .keyword-column, -.search-engine-list .url-column { - color: #666; -} - -.search-engine-list .default .name-column, -.search-engine-list .default .keyword-column { - font-weight: bold; -} - -/* For temporary Make Default button */ -.search-engine-list .url-column { - -webkit-box-align: center; - display: -webkit-box; -} - -.search-engine-list .url-column :first-child { - -webkit-box-flex: 1; -} - -.search-engine-list .url-column .list-inline-button { - -webkit-margin-start: 1ex; - margin-top: 0; - padding: 1px 6px 2px 6px; -} - -.search-engine-list > :not(:hover):not([editing]) .url-column - .list-inline-button { - display: none; -} - -#default-search-engine-list { - z-index: 2; -} - -#other-search-engine-list { - z-index: 1; -} - -/* End temporary Make Default button styling */
diff --git a/chrome/browser/resources/options/search_engine_manager.html b/chrome/browser/resources/options/search_engine_manager.html deleted file mode 100644 index 9d76000..0000000 --- a/chrome/browser/resources/options/search_engine_manager.html +++ /dev/null
@@ -1,27 +0,0 @@ -<div id="search-engine-manager-page" class="page" hidden> - <div class="close-button"></div> - <h1>$i18n{searchEngineManagerPage}</h1> - <div class="content-area"> - <h3>$i18n{defaultSearchEngineListTitle}</h3> - <list id="default-search-engine-list" - class="search-engine-list settings-list"></list> - <h3>$i18n{otherSearchEngineListTitle}</h3> - <list id="other-search-engine-list" - class="search-engine-list settings-list"></list> - <div id="extension-keyword-div" hidden> - <h3 id="extension-keyword-list-title"> - $i18n{extensionKeywordsListTitle} - </h3> - <list id="extension-keyword-list" - class="search-engine-list settings-list"></list> - </div> - </div> - <div class="action-area"> - <div class="button-strip"> - <button id="search-engine-manager-confirm" type="submit" - class="default-button"> - $i18n{done} - </button> - </div> - </div> -</div>
diff --git a/chrome/browser/resources/options/search_engine_manager.js b/chrome/browser/resources/options/search_engine_manager.js deleted file mode 100644 index ce31ef6..0000000 --- a/chrome/browser/resources/options/search_engine_manager.js +++ /dev/null
@@ -1,133 +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. - -cr.define('options', function() { - /** @const */ var Page = cr.ui.pageManager.Page; - /** @const */ var PageManager = cr.ui.pageManager.PageManager; - /** @const */ var ArrayDataModel = cr.ui.ArrayDataModel; - - /** - * Encapsulated handling of search engine management page. - * @constructor - * @extends {cr.ui.pageManager.Page} - */ - function SearchEngineManager() { - this.activeNavTab = null; - Page.call(this, 'searchEngines', - loadTimeData.getString('searchEngineManagerPageTabTitle'), - 'search-engine-manager-page'); - } - - cr.addSingletonGetter(SearchEngineManager); - - SearchEngineManager.prototype = { - __proto__: Page.prototype, - - /** - * List for default search engine options. - * @private - */ - defaultsList_: null, - - /** - * List for other search engine options. - * @private - */ - othersList_: null, - - /** - * List for extension keywords. - * @private - */ - extensionList_: null, - - /** @override */ - initializePage: function() { - Page.prototype.initializePage.call(this); - - this.defaultsList_ = $('default-search-engine-list'); - this.setUpList_(this.defaultsList_); - - this.othersList_ = $('other-search-engine-list'); - this.setUpList_(this.othersList_); - - this.extensionList_ = $('extension-keyword-list'); - this.setUpList_(this.extensionList_); - - $('search-engine-manager-confirm').onclick = function() { - PageManager.closeOverlay(); - }; - }, - - /** - * Sets up the given list as a search engine list - * @param {HTMLElement} list The list to set up. - * @private - */ - setUpList_: function(list) { - options.search_engines.SearchEngineList.decorate(list); - list.autoExpands = true; - }, - - /** - * Updates the search engine list with the given entries. - * @private - * @param {!Array} defaultEngines List of possible default search engines. - * @param {!Array} otherEngines List of other search engines. - * @param {!Array} keywords List of keywords from extensions. - */ - updateSearchEngineList_: function(defaultEngines, otherEngines, keywords) { - this.defaultsList_.dataModel = new ArrayDataModel(defaultEngines); - - otherEngines = otherEngines.map(function(x) { - return [x, x.name.toLocaleLowerCase()]; - }).sort(function(a, b) { - return a[1].localeCompare(b[1]); - }).map(function(x) { - return x[0]; - }); - - var othersModel = new ArrayDataModel(otherEngines); - // Add a "new engine" row. - othersModel.push({ - 'modelIndex': '-1', - 'canBeEdited': true - }); - this.othersList_.dataModel = othersModel; - - if (keywords.length > 0) { - $('extension-keyword-div').hidden = false; - var extensionsModel = new ArrayDataModel(keywords); - this.extensionList_.dataModel = extensionsModel; - } else { - $('extension-keyword-div').hidden = true; - } - }, - }; - - SearchEngineManager.updateSearchEngineList = function(defaultEngines, - otherEngines, - keywords) { - SearchEngineManager.getInstance().updateSearchEngineList_(defaultEngines, - otherEngines, - keywords); - }; - - SearchEngineManager.validityCheckCallback = function(validity, modelIndex) { - // Forward to all lists; those without a matching modelIndex will ignore it. - SearchEngineManager.getInstance().defaultsList_.validationComplete( - validity, modelIndex); - SearchEngineManager.getInstance().othersList_.validationComplete( - validity, modelIndex); - SearchEngineManager.getInstance().extensionList_.validationComplete( - validity, modelIndex); - }; - - // Export - return { - SearchEngineManager: SearchEngineManager - }; - -}); -
diff --git a/chrome/browser/resources/options/search_engine_manager_engine_list.js b/chrome/browser/resources/options/search_engine_manager_engine_list.js deleted file mode 100644 index 7284ae9c..0000000 --- a/chrome/browser/resources/options/search_engine_manager_engine_list.js +++ /dev/null
@@ -1,379 +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. - -/** - * @typedef {{canBeDefault: boolean, - * canBeEdited: boolean, - * canBeRemoved: boolean, - * default: boolean, - * displayName: string, - * extension: (Object|undefined), - * iconURL: (string|undefined), - * isOmniboxExtension: boolean, - * keyword: string, - * modelIndex: string, - * name: string, - * url: string, - * urlLocked: boolean}} - * @see chrome/browser/ui/webui/options/search_engine_manager_handler.cc - */ -var SearchEngine; - -cr.define('options.search_engines', function() { - /** @const */ var ControlledSettingIndicator = - options.ControlledSettingIndicator; - /** @const */ var InlineEditableItemList = options.InlineEditableItemList; - /** @const */ var InlineEditableItem = options.InlineEditableItem; - /** @const */ var ListSelectionController = cr.ui.ListSelectionController; - - /** - * Creates a new search engine list item. - * @param {SearchEngine} searchEngine The search engine this represents. - * @constructor - * @extends {options.InlineEditableItem} - */ - function SearchEngineListItem(searchEngine) { - var el = cr.doc.createElement('div'); - el.searchEngine_ = searchEngine; - SearchEngineListItem.decorate(el); - return el; - } - - /** - * Decorates an element as a search engine list item. - * @param {!HTMLElement} el The element to decorate. - */ - SearchEngineListItem.decorate = function(el) { - el.__proto__ = SearchEngineListItem.prototype; - el.decorate(); - }; - - SearchEngineListItem.prototype = { - __proto__: InlineEditableItem.prototype, - - /** - * Input field for editing the engine name. - * @type {HTMLElement} - * @private - */ - nameField_: null, - - /** - * Input field for editing the engine keyword. - * @type {HTMLElement} - * @private - */ - keywordField_: null, - - /** - * Input field for editing the engine url. - * @type {HTMLElement} - * @private - */ - urlField_: null, - - /** - * Whether or not an input validation request is currently outstanding. - * @type {boolean} - * @private - */ - waitingForValidation_: false, - - /** - * Whether or not the current set of input is known to be valid. - * @type {boolean} - * @private - */ - currentlyValid_: false, - - /** - * @type {?SearchEngine} - */ - searchEngine_: null, - - /** @override */ - decorate: function() { - InlineEditableItem.prototype.decorate.call(this); - - var engine = this.searchEngine_; - - if (engine.modelIndex == '-1') { - this.isPlaceholder = true; - engine.name = ''; - engine.keyword = ''; - engine.url = ''; - } - - this.currentlyValid_ = !this.isPlaceholder; - - if (engine.default) - this.classList.add('default'); - - this.deletable = engine.canBeRemoved; - this.closeButtonFocusAllowed = true; - - // Construct the name column. - var nameColEl = this.ownerDocument.createElement('div'); - nameColEl.className = 'name-column'; - nameColEl.classList.add('weakrtl'); - this.contentElement.appendChild(nameColEl); - - // Add the favicon. - var faviconDivEl = this.ownerDocument.createElement('div'); - faviconDivEl.className = 'favicon'; - if (!this.isPlaceholder) { - // Force default icon if no iconURL is available. - faviconDivEl.style.backgroundImage = - cr.icon.getFavicon(engine.iconURL || ''); - } - - nameColEl.appendChild(faviconDivEl); - - var nameEl = this.createEditableTextCell(engine.displayName); - nameEl.classList.add('weakrtl'); - nameColEl.appendChild(nameEl); - - // Then the keyword column. - var keywordEl = this.createEditableTextCell(engine.keyword); - keywordEl.className = 'keyword-column'; - keywordEl.classList.add('weakrtl'); - this.contentElement.appendChild(keywordEl); - - // And the URL column. - var urlEl = this.createEditableTextCell(engine.url); - var makeDefaultButtonEl = null; - // Extensions should not display a URL column. - if (!engine.isOmniboxExtension) { - var urlWithButtonEl = this.ownerDocument.createElement('div'); - urlWithButtonEl.appendChild(urlEl); - urlWithButtonEl.className = 'url-column'; - urlWithButtonEl.classList.add('weakrtl'); - this.contentElement.appendChild(urlWithButtonEl); - // Add the Make Default button. Temporary until drag-and-drop - // re-ordering is implemented. When this is removed, remove the extra - // div above. - if (engine.canBeDefault) { - makeDefaultButtonEl = this.ownerDocument.createElement('button'); - makeDefaultButtonEl.className = - 'custom-appearance list-inline-button'; - makeDefaultButtonEl.textContent = - loadTimeData.getString('makeDefaultSearchEngineButton'); - makeDefaultButtonEl.onclick = function(e) { - chrome.send('managerSetDefaultSearchEngine', [engine.modelIndex]); - }; - makeDefaultButtonEl.onmousedown = function(e) { - // Don't select the row when clicking the button. - e.stopPropagation(); - // Don't focus on the button. - e.preventDefault(); - }; - urlWithButtonEl.appendChild(makeDefaultButtonEl); - } - } - - // Do final adjustment to the input fields. - this.nameField_ = /** @type {HTMLElement} */( - nameEl.querySelector('input')); - // The editable field uses the raw name, not the display name. - this.nameField_.value = engine.name; - this.keywordField_ = /** @type {HTMLElement} */( - keywordEl.querySelector('input')); - this.urlField_ = /** @type {HTMLElement} */(urlEl.querySelector('input')); - - if (engine.urlLocked) - this.urlField_.disabled = true; - - if (this.isPlaceholder) { - this.nameField_.placeholder = - loadTimeData.getString('searchEngineTableNamePlaceholder'); - this.keywordField_.placeholder = - loadTimeData.getString('searchEngineTableKeywordPlaceholder'); - this.urlField_.placeholder = - loadTimeData.getString('searchEngineTableURLPlaceholder'); - } - - this.setFocusableColumnIndex(this.nameField_, 0); - this.setFocusableColumnIndex(this.keywordField_, 1); - this.setFocusableColumnIndex(this.urlField_, 2); - this.setFocusableColumnIndex(makeDefaultButtonEl, 3); - this.setFocusableColumnIndex(this.closeButtonElement, 4); - - var fields = [this.nameField_, this.keywordField_, this.urlField_]; - for (var i = 0; i < fields.length; i++) { - fields[i].oninput = this.startFieldValidation_.bind(this); - } - - // Listen for edit events. - if (engine.canBeEdited) { - this.addEventListener('edit', this.onEditStarted_.bind(this)); - this.addEventListener('canceledit', this.onEditCancelled_.bind(this)); - this.addEventListener('commitedit', this.onEditCommitted_.bind(this)); - } else { - this.editable = false; - this.querySelector('.row-delete-button').hidden = true; - var indicator = new ControlledSettingIndicator(); - indicator.setAttribute('setting', 'search-engine'); - // Create a synthetic pref change event decorated as - // CoreOptionsHandler::CreateValueForPref() does. - var event = new Event(this.contentType); - if (engine.extension) { - event.value = { controlledBy: 'extension', - extension: engine.extension }; - } else { - event.value = { controlledBy: 'policy' }; - } - indicator.handlePrefChange(event); - this.appendChild(indicator); - } - }, - - /** @override */ - get currentInputIsValid() { - return !this.waitingForValidation_ && this.currentlyValid_; - }, - - /** @override */ - get hasBeenEdited() { - var engine = this.searchEngine_; - return this.nameField_.value != engine.name || - this.keywordField_.value != engine.keyword || - this.urlField_.value != engine.url; - }, - - /** - * Called when entering edit mode; starts an edit session in the model. - * @param {Event} e The edit event. - * @private - */ - onEditStarted_: function(e) { - var editIndex = this.searchEngine_.modelIndex; - chrome.send('editSearchEngine', [String(editIndex)]); - this.startFieldValidation_(); - }, - - /** - * Called when committing an edit; updates the model. - * @param {Event} e The end event. - * @private - */ - onEditCommitted_: function(e) { - chrome.send('searchEngineEditCompleted', this.getInputFieldValues_()); - }, - - /** - * Called when cancelling an edit; informs the model and resets the control - * states. - * @param {Event} e The cancel event. - * @private - */ - onEditCancelled_: function(e) { - chrome.send('searchEngineEditCancelled'); - - // The name field has been automatically set to match the display name, - // but it should use the raw name instead. - this.nameField_.value = this.searchEngine_.name; - this.currentlyValid_ = !this.isPlaceholder; - }, - - /** - * Returns the input field values as an array suitable for passing to - * chrome.send. The order of the array is important. - * @private - * @return {Array} The current input field values. - */ - getInputFieldValues_: function() { - return [this.nameField_.value, - this.keywordField_.value, - this.urlField_.value]; - }, - - /** - * Begins the process of asynchronously validing the input fields. - * @private - */ - startFieldValidation_: function() { - this.waitingForValidation_ = true; - var args = this.getInputFieldValues_(); - args.push(this.searchEngine_.modelIndex); - chrome.send('checkSearchEngineInfoValidity', args); - }, - - /** - * Callback for the completion of an input validition check. - * @param {Object} validity A dictionary of validitation results. - */ - validationComplete: function(validity) { - this.waitingForValidation_ = false; - if (validity.name) { - this.nameField_.setCustomValidity(''); - } else { - this.nameField_.setCustomValidity( - loadTimeData.getString('editSearchEngineInvalidTitleToolTip')); - } - - if (validity.keyword) { - this.keywordField_.setCustomValidity(''); - } else { - this.keywordField_.setCustomValidity( - loadTimeData.getString('editSearchEngineInvalidKeywordToolTip')); - } - - if (validity.url) { - this.urlField_.setCustomValidity(''); - } else { - this.urlField_.setCustomValidity( - loadTimeData.getString('editSearchEngineInvalidURLToolTip')); - } - - this.currentlyValid_ = validity.name && validity.keyword && validity.url; - }, - }; - - /** - * @constructor - * @extends {options.InlineEditableItemList} - */ - var SearchEngineList = cr.ui.define('list'); - - SearchEngineList.prototype = { - __proto__: InlineEditableItemList.prototype, - - /** - * @override - * @param {SearchEngine} searchEngine - */ - createItem: function(searchEngine) { - return new SearchEngineListItem(searchEngine); - }, - - /** @override */ - deleteItemAtIndex: function(index) { - var modelIndex = this.dataModel.item(index).modelIndex; - chrome.send('removeSearchEngine', [String(modelIndex)]); - }, - - /** - * Passes the results of an input validation check to the requesting row - * if it's still being edited. - * @param {number} modelIndex The model index of the item that was checked. - * @param {Object} validity A dictionary of validitation results. - */ - validationComplete: function(validity, modelIndex) { - // If it's not still being edited, it no longer matters. - var currentSelection = this.selectedItem; - if (!currentSelection) - return; - var listItem = this.getListItem(currentSelection); - if (listItem.editing && currentSelection.modelIndex == modelIndex) - listItem.validationComplete(validity); - }, - }; - - // Export - return { - SearchEngineList: SearchEngineList - }; - -}); -
diff --git a/chrome/browser/resources/options/search_page.css b/chrome/browser/resources/options/search_page.css deleted file mode 100644 index 2d047ba..0000000 --- a/chrome/browser/resources/options/search_page.css +++ /dev/null
@@ -1,80 +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. */ - -.search-hidden { - display: none !important; -} - -.search-highlighted { - background-color: rgba(255, 240, 120, 0.9); -} - -/* Container for the elements that make up the search bubble. */ -.search-bubble { - left: 0; - position: absolute; - top: -1000px; /* Minor hack: position off-screen by default. */ - /* Create a z-context for search-bubble-innards, its after and before. */ - z-index: 1; -} - -/* Contains the text content of the bubble. */ -.search-bubble-innards { - background: -webkit-linear-gradient(rgba(255, 248, 172, 0.9), - rgba(255, 243, 128, 0.9)); - border-radius: 2px; - padding: 4px 10px; - text-align: center; - width: 100px; -} - -/* Provides the border around the bubble (has to be behind ::after). */ -.search-bubble-innards::before { - border: 1px solid rgb(220, 198, 72); - border-radius: 2px; - bottom: -1px; - content: ''; - left: -1px; - position: absolute; - right: -1px; - top: -1px; - z-index: -2; -} - -/* Provides the arrow which points at the anchor element. */ -.search-bubble-innards::after { - background: - -webkit-linear-gradient(-45deg, rgb(251, 255, 181), - rgb(255, 248, 172) 50%, - rgba(255, 248, 172, 0)); - border: 1px solid rgb(220, 198, 72); - border-bottom-color: transparent; - border-right-color: transparent; - content: ''; - height: 12px; - left: 53px; - position: absolute; - top: -7px; - transform: rotate(45deg); - width: 12px; - z-index: -1; -} - -/* Turns the arrow direction downwards, when the bubble is placed above the - * anchor element */ -.search-bubble-innards.above::after { - bottom: -7px; - top: auto; - transform: rotate(-135deg); -} - -.search-bubble-wrapper { - position: relative; -} - -/* #mainview is here to win specificity. :( */ -#mainview #searchPage.page, -#mainview #searchBox.page { - padding-bottom: 0; -}
diff --git a/chrome/browser/resources/options/search_page.html b/chrome/browser/resources/options/search_page.html deleted file mode 100644 index dcc9ed70..0000000 --- a/chrome/browser/resources/options/search_page.html +++ /dev/null
@@ -1,12 +0,0 @@ -<div id="searchPage" class="page" hidden> - <header> - <h1>$i18n{searchPage}</h1> - </header> - <div id="searchPageNoMatches" hidden> - <p>$i18n{searchPageNoMatches}</p> - <p><span>$i18n{searchPageHelpLabel}</span> - <a target="_blank" - href="$i18nRaw{searchPageHelpURL}">$i18n{searchPageHelpTitle}</a> - </p> - </div> -</div>
diff --git a/chrome/browser/resources/options/search_page.js b/chrome/browser/resources/options/search_page.js deleted file mode 100644 index c561a0c..0000000 --- a/chrome/browser/resources/options/search_page.js +++ /dev/null
@@ -1,710 +0,0 @@ -// Copyright 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. - -/** - * Section IDs use for metrics. The integer values should match up with the - * |SettingsSections| in histograms.xml. - * @type {Object<string, number>} - */ -var SettingsSections = { - 'None': 0, - 'Unknown': 1, - 'network-section-cros': 2, - 'proxy-section': 3, - 'appearance-section': 4, - 'device-section': 5, - 'search-section': 6, - 'sync-users-section': 7, - 'set-default-browser-section': 8, - 'date-time-section': 9, - 'device-control-section': 10, - 'privacy-section': 11, - 'bluetooth-devices': 12, - 'passwords-and-autofill-section': 13, - 'easy-unlock-section': 14, - 'web-content-section': 15, - 'network-section': 16, - 'languages-section': 17, - 'downloads-section': 18, - 'certificates-section': 19, - 'cloudprint-options-mdns': 20, - 'a11y-section': 21, - 'factory-reset-section': 22, - 'system-section': 23, - 'reset-profile-settings-section': 24, - 'sync-section': 25, - 'startup-section': 26, - 'mouselock-section': 27, - 'page-zoom-levels': 28, - 'status-section': 29, - 'main-section': 30, - 'pointer-section-touchpad': 31, - 'pointer-section-mouse': 32, - 'prefs-blocked-languages': 33, - 'prefs-language-blacklist': 34, - 'prefs-site-blacklist': 35, - 'prefs-whitelists': 36, - 'prefs-supported-languages': 37, - 'prefs-cld-version': 38, - 'prefs-cld-data-source': 39, - 'prefs-dump': 40, -}; - -cr.define('options', function() { - /** @const */ var Page = cr.ui.pageManager.Page; - /** @const */ var PageManager = cr.ui.pageManager.PageManager; - - /** - * Encapsulated handling of a search bubble. - * @constructor - * @extends {HTMLDivElement} - */ - function SearchBubble(text) { - var el = cr.doc.createElement('div'); - SearchBubble.decorate(el); - el.content = text; - return el; - } - - /** - * Prohibit search for guests on desktop. - */ - function ShouldEnableSearch() { - return !loadTimeData.getBoolean('profileIsGuest') || cr.isChromeOS; - } - - SearchBubble.decorate = function(el) { - el.__proto__ = SearchBubble.prototype; - el.decorate(); - }; - - SearchBubble.prototype = { - __proto__: HTMLDivElement.prototype, - - decorate: function() { - this.className = 'search-bubble'; - - this.innards_ = cr.doc.createElement('div'); - this.innards_.className = 'search-bubble-innards'; - this.appendChild(this.innards_); - - // We create a timer to periodically update the position of the bubbles. - // While this isn't all that desirable, it's the only sure-fire way of - // making sure the bubbles stay in the correct location as sections - // may dynamically change size at any time. - this.intervalId = setInterval(this.updatePosition.bind(this), 250); - - this.addEventListener('mouseover', function() { - this.innards_.classList.toggle('above'); - this.updatePosition(); - }); - }, - - /** - * Sets the text message in the bubble. - * @param {string} text The text the bubble will show. - */ - set content(text) { - this.innards_.textContent = text; - }, - - /** - * Attach the bubble to the element. - */ - attachTo: function(element) { - var parent = element.parentElement; - if (!parent) - return; - if (parent.tagName == 'TD') { - // To make absolute positioning work inside a table cell we need - // to wrap the bubble div into another div with position:relative. - // This only works properly if the element is the first child of the - // table cell which is true for all options pages. - this.wrapper = cr.doc.createElement('div'); - this.wrapper.className = 'search-bubble-wrapper'; - this.wrapper.appendChild(this); - parent.insertBefore(this.wrapper, element); - } else { - parent.insertBefore(this, element); - } - }, - - /** - * Clear the interval timer and remove the element from the page. - */ - dispose: function() { - clearInterval(this.intervalId); - - var child = this.wrapper || this; - var parent = child.parentNode; - if (parent) - parent.removeChild(child); - }, - - /** - * Update the position of the bubble. Called at creation time and then - * periodically while the bubble remains visible. - */ - updatePosition: function() { - // This bubble is 'owned' by the next sibling. - var owner = (this.wrapper || this).nextSibling; - - // If there isn't an offset parent, we have nothing to do. - if (!owner.offsetParent) - return; - - // Position the bubble below the location of the owner. - var left = owner.offsetLeft + owner.offsetWidth / 2 - - this.offsetWidth / 2; - - var BUBBLE_EDGE_OFFSET = 5; - var top = owner.offsetTop; - if (this.innards_.classList.contains('above')) - top -= this.offsetHeight + BUBBLE_EDGE_OFFSET; - else - top += owner.offsetHeight + BUBBLE_EDGE_OFFSET; - - // Update the position in the CSS. Cache the last values for - // best performance. - if (left != this.lastLeft) { - this.style.left = left + 'px'; - this.lastLeft = left; - } - if (top != this.lastTop) { - this.style.top = top + 'px'; - this.lastTop = top; - } - }, - }; - - /** - * Encapsulated handling of the search page. - * @constructor - * @extends {cr.ui.pageManager.Page} - */ - function SearchPage() { - Page.call(this, 'search', - loadTimeData.getString('searchPageTabTitle'), - 'searchPage'); - } - - cr.addSingletonGetter(SearchPage); - - SearchPage.prototype = { - // Inherit SearchPage from Page. - __proto__: Page.prototype, - - /** - * Wait a bit to see if the user is still entering search text. - * @type {number|undefined} - * @private - */ - delayedSearchMetric_: undefined, - - /** - * Only send the time of first search once. - * @type {boolean} - * @private - */ - hasSentFirstSearchTime_: false, - - /** - * A boolean to prevent recursion. Used by setSearchText_(). - * @type {boolean} - * @private - */ - insideSetSearchText_: false, - - /** @override */ - initializePage: function() { - Page.prototype.initializePage.call(this); - - // Record the start time for use in reporting metrics. - this.createdTimestamp_ = Date.now(); - - this.searchField = $('search-field'); - - // Handle search events. (No need to throttle, WebKit's search field - // will do that automatically.) - this.searchField.onsearch = function(e) { - this.setSearchText_(e.currentTarget.value); - }.bind(this); - - // Install handler for key presses. - document.addEventListener('keydown', - this.keyDownEventHandler_.bind(this)); - }, - - /** @override */ - get sticky() { - return true; - }, - - /** @override */ - didShowPage: function() { - // This method is called by the PageManager after all pages have had their - // visibility attribute set. At this point we can perform the - // search-specific DOM manipulation. - this.setSearchActive_(true); - }, - - /** @override */ - didChangeHash: function() { - this.setSearchActive_(true); - }, - - /** @override */ - willHidePage: function() { - // This method is called by the PageManager before all pages have their - // visibility attribute set. Before that happens, we need to undo the - // search-specific DOM manipulation that was performed in didShowPage. - this.setSearchActive_(false); - }, - - /** - * Update the UI to reflect whether we are in a search state. - * @param {boolean} active True if we are on the search page. - * @private - */ - setSearchActive_: function(active) { - // It's fine to exit if search wasn't active and we're not going to - // activate it now. - if (!this.searchActive_ && !active) - return; - - if (!ShouldEnableSearch()) - return; - - this.searchActive_ = active; - - if (active) { - var hash = this.hash; - if (hash) { - this.searchField.value = - decodeURIComponent(hash.slice(1).replace(/\+/g, ' ')); - } else if (!this.searchField.value) { - // This should only happen if the user goes directly to - // chrome://settings-frame/search - PageManager.showDefaultPage(); - return; - } - - // Move 'advanced' sections into the main settings page to allow - // searching. - if (!this.advancedSections_) { - this.advancedSections_ = - $('advanced-settings-container').querySelectorAll('section'); - for (var i = 0, section; section = this.advancedSections_[i]; i++) - $('settings').appendChild(section); - } - } else { - this.searchField.value = ''; - } - - var pagesToSearch = this.getSearchablePages_(); - for (var i = 0; i < pagesToSearch.length; i++) { - var page = pagesToSearch[i]; - - if (!active) - page.visible = false; - - // Update the visible state of all top-level elements that are not - // sections (ie titles, button strips). We do this before changing - // the page visibility to avoid excessive re-draw. - for (var i = 0, childDiv; childDiv = page.pageDiv.children[i]; i++) { - if (active) { - if (childDiv.tagName != 'SECTION') - childDiv.classList.add('search-hidden'); - } else { - childDiv.classList.remove('search-hidden'); - } - } - - if (active) { - // When search is active, remove the 'hidden' tag. This tag may have - // been added by the PageManager. - page.pageDiv.hidden = false; - } - } - - if (active) { - this.setSearchText_(this.searchField.value); - this.searchField.focus(); - } else { - // After hiding all page content, remove any search results. - this.unhighlightMatches_(); - this.removeSearchBubbles_(); - - // Move 'advanced' sections back into their original container. - if (this.advancedSections_) { - for (var i = 0, section; section = this.advancedSections_[i]; i++) - $('advanced-settings-container').appendChild(section); - this.advancedSections_ = null; - } - } - }, - - /** - * Set the current search criteria. - * @param {string} text Search text. - * @private - */ - setSearchText_: function(text) { - if (!ShouldEnableSearch()) - return; - - // Prevent recursive execution of this method. - if (this.insideSetSearchText_) return; - this.insideSetSearchText_ = true; - - // Cleanup the search query string. - text = SearchPage.canonicalizeQuery(text); - - // If the search string becomes empty, flip back to the default page. - if (!text) { - if (this.searchActive_) - PageManager.showDefaultPage(); - this.insideSetSearchText_ = false; - return; - } - - if (!this.hasSentFirstSearchTime_) { - this.hasSentFirstSearchTime_ = true; - chrome.metricsPrivate.recordMediumTime('Settings.TimeToFirstSearch', - Date.now() - this.createdTimestamp_); - } - - // Toggle the search page if necessary. Otherwise, update the hash. - var hash = '#' + encodeURIComponent(text); - if (this.searchActive_) { - if (this.hash != hash) - this.setHash(hash); - } else { - PageManager.showPageByName(this.name, true, {hash: hash}); - } - - var foundMatches = false; - - // Remove any prior search results. - this.unhighlightMatches_(); - this.removeSearchBubbles_(); - - var pagesToSearch = this.getSearchablePages_(); - for (var i = 0; i < pagesToSearch.length; i++) { - var page = pagesToSearch[i]; - var elements = page.pageDiv.querySelectorAll('section'); - for (var i = 0, node; node = elements[i]; i++) { - node.classList.add('search-hidden'); - } - } - - var bubbleControls = []; - var pageMatchesForMetrics = 0; - var subpageMatchesForMetrics = 0; - var sectionMatchesForMetrics = {}; - - // Generate search text by applying lowercase and escaping any characters - // that would be problematic for regular expressions. - var searchText = - text.toLowerCase().replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'); - // Generate a regular expression for hilighting search terms. - var regExp = new RegExp('(' + searchText + ')', 'ig'); - - if (searchText.length) { - // Search all top-level sections for anchored string matches. - for (var i = 0; i < pagesToSearch.length; i++) { - var page = pagesToSearch[i]; - var elements = - page.pageDiv.querySelectorAll('section'); - for (var i = 0, node; node = elements[i]; i++) { - if (this.highlightMatches_(regExp, node)) { - node.classList.remove('search-hidden'); - if (!node.hidden) { - foundMatches = true; - pageMatchesForMetrics += 1; - var section = SettingsSections[node.id] || - SettingsSections['Unknown']; - sectionMatchesForMetrics[section] = section; - } - } - } - } - - // Search all sub-pages, generating an array of top-level sections that - // we need to make visible. - var subPagesToSearch = this.getSearchableSubPages_(); - var control, node; - for (var i = 0; i < subPagesToSearch.length; i++) { - var page = subPagesToSearch[i]; - if (this.highlightMatches_(regExp, page.pageDiv)) { - this.revealAssociatedSections_(page); - - bubbleControls = - bubbleControls.concat(this.getAssociatedControls_(page)); - - foundMatches = true; - subpageMatchesForMetrics += 1; - } - } - } - - // Configure elements on the search results page based on search results. - $('searchPageNoMatches').hidden = foundMatches; - - // Create search balloons for sub-page results. - var bubbleCount = bubbleControls.length; - for (var i = 0; i < bubbleCount; i++) - this.createSearchBubble_(bubbleControls[i], text); - - // If the search doesn't change for one second, send some metrics. - clearTimeout(this.delayedSearchMetric_); - this.delayedSearchMetric_ = setTimeout(function() { - if (!foundMatches) { - chrome.metricsPrivate.recordSmallCount( - 'Settings.SearchLengthNoMatch', text.length); - chrome.metricsPrivate.recordSmallCount( - 'Settings.SearchSections', SettingsSections['None']); - } else { - for (var section in sectionMatchesForMetrics) { - var sectionId = sectionMatchesForMetrics[section]; - assert(sectionId !== undefined); - chrome.metricsPrivate.recordSmallCount( - 'Settings.SearchSections', sectionId); - } - } - - chrome.metricsPrivate.recordUserAction('Settings.Searching'); - chrome.metricsPrivate.recordSmallCount( - 'Settings.SearchLength', text.length); - chrome.metricsPrivate.recordSmallCount( - 'Settings.SearchPageMatchCount', pageMatchesForMetrics); - chrome.metricsPrivate.recordSmallCount( - 'Settings.SearchSubpageMatchCount', subpageMatchesForMetrics); - }, 1000); - - // Cleanup the recursion-prevention variable. - this.insideSetSearchText_ = false; - }, - - /** - * Reveal the associated section for |subpage|, as well as the one for its - * |parentPage|, and its |parentPage|'s |parentPage|, etc. - * @private - */ - revealAssociatedSections_: function(subpage) { - for (var page = subpage; page; page = page.parentPage) { - var section = page.associatedSection; - if (section) - section.classList.remove('search-hidden'); - } - }, - - /** - * @return {!Array<HTMLElement>} all the associated controls for |subpage|, - * including |subpage.associatedControls| as well as any controls on parent - * pages that are indirectly necessary to get to the subpage. - * @private - */ - getAssociatedControls_: function(subpage) { - var controls = []; - for (var page = subpage; page; page = page.parentPage) { - if (page.associatedControls) - controls = controls.concat(page.associatedControls); - } - return controls; - }, - - /** - * Wraps matches in spans. - * @param {RegExp} regExp The search query (in regexp form). - * @param {Element} element An HTML container element to recursively search - * within. - * @return {boolean} true if the element was changed. - * @private - */ - highlightMatches_: function(regExp, element) { - var found = false; - var div, child, tmp; - - // Walk the tree, searching each TEXT node. - var walker = document.createTreeWalker(element, - NodeFilter.SHOW_TEXT, - null, - false); - var node = walker.nextNode(); - while (node) { - var textContent = node.nodeValue; - // Perform a search and replace on the text node value. - var split = textContent.split(regExp); - if (split.length > 1) { - found = true; - var nextNode = walker.nextNode(); - var parentNode = node.parentNode; - // Use existing node as placeholder to determine where to insert the - // replacement content. - for (var i = 0; i < split.length; ++i) { - if (i % 2 == 0) { - parentNode.insertBefore(document.createTextNode(split[i]), node); - } else { - var span = document.createElement('span'); - span.className = 'search-highlighted'; - span.textContent = split[i]; - parentNode.insertBefore(span, node); - } - } - // Remove old node. - parentNode.removeChild(node); - node = nextNode; - } else { - node = walker.nextNode(); - } - } - - return found; - }, - - /** - * Removes all search highlight tags from the document. - * @private - */ - unhighlightMatches_: function() { - // Find all search highlight elements. - var elements = document.querySelectorAll('.search-highlighted'); - - // For each element, remove the highlighting. - var parent, i; - for (var i = 0, node; node = elements[i]; i++) { - parent = node.parentNode; - - // Replace the highlight element with the first child (the text node). - parent.replaceChild(node.firstChild, node); - - // Normalize the parent so that multiple text nodes will be combined. - parent.normalize(); - } - }, - - /** - * Creates a search result bubble attached to an element. - * @param {Element} element An HTML element, usually a button. - * @param {string} text A string to show in the bubble. - * @private - */ - createSearchBubble_: function(element, text) { - // avoid appending multiple bubbles to a button. - var sibling = element.previousElementSibling; - if (sibling && (sibling.classList.contains('search-bubble') || - sibling.classList.contains('search-bubble-wrapper'))) - return; - - var parent = element.parentElement; - if (parent) { - var bubble = new SearchBubble(text); - bubble.attachTo(element); - bubble.updatePosition(); - } - }, - - /** - * Removes all search match bubbles. - * @private - */ - removeSearchBubbles_: function() { - var elements = document.querySelectorAll('.search-bubble'); - var length = elements.length; - for (var i = 0; i < length; i++) - elements[i].dispose(); - }, - - /** - * Builds a list of top-level pages to search. Omits the search page and - * all sub-pages. - * @return {Array} An array of pages to search. - * @private - */ - getSearchablePages_: function() { - var name, page, pages = []; - for (name in PageManager.registeredPages) { - if (name != this.name) { - page = PageManager.registeredPages[name]; - if (!page.parentPage) - pages.push(page); - } - } - return pages; - }, - - /** - * Builds a list of sub-pages (and overlay pages) to search. Ignore pages - * that have no associated controls, or whose controls are hidden. - * @return {Array} An array of pages to search. - * @private - */ - getSearchableSubPages_: function() { - var name, pageInfo, page, pages = []; - for (name in PageManager.registeredPages) { - page = PageManager.registeredPages[name]; - if (page.parentPage && - page.associatedSection && - !page.associatedSection.hidden) { - pages.push(page); - } - } - for (name in PageManager.registeredOverlayPages) { - page = PageManager.registeredOverlayPages[name]; - if (page.associatedSection && - !page.associatedSection.hidden && - page.pageDiv != undefined) { - pages.push(page); - } - } - return pages; - }, - - /** - * A function to handle key press events. - * @param {Event} event A keydown event. - * @private - */ - keyDownEventHandler_: function(event) { - /** @const */ var ESCAPE_KEY_CODE = 27; - /** @const */ var FORWARD_SLASH_KEY_CODE = 191; - - switch (event.keyCode) { - case ESCAPE_KEY_CODE: - if (event.target == this.searchField) { - this.setSearchText_(''); - this.searchField.blur(); - event.stopPropagation(); - event.preventDefault(); - } - break; - case FORWARD_SLASH_KEY_CODE: - if (!/INPUT|SELECT|BUTTON|TEXTAREA/.test(event.target.tagName) && - !event.ctrlKey && !event.altKey) { - this.searchField.focus(); - event.stopPropagation(); - event.preventDefault(); - } - break; - } - }, - }; - - /** - * Standardizes a user-entered text query by removing extra whitespace. - * @param {string} text The user-entered text. - * @return {string} The trimmed query. - */ - SearchPage.canonicalizeQuery = function(text) { - // Trim beginning and ending whitespace. - return text.replace(/^\s+|\s+$/g, ''); - }; - - // Export - return { - SearchPage: SearchPage - }; - -});
diff --git a/chrome/browser/resources/options/secondary_user_banner.html b/chrome/browser/resources/options/secondary_user_banner.html deleted file mode 100644 index f609d07..0000000 --- a/chrome/browser/resources/options/secondary_user_banner.html +++ /dev/null
@@ -1,10 +0,0 @@ -<div id="secondary-user-banner" class="settings-banner" hidden> - <div class="content-area"> - <div class="badge"></div> - <div class="text"> - <p> - <span>$i18nRaw{secondaryUserBannerText}</span> - </p> - </div> - </div> -</div>
diff --git a/chrome/browser/resources/options/settings_dialog.js b/chrome/browser/resources/options/settings_dialog.js deleted file mode 100644 index 01b2562..0000000 --- a/chrome/browser/resources/options/settings_dialog.js +++ /dev/null
@@ -1,71 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -/** - * @fileoverview Base class for dialogs that require saving preferences on - * confirm and resetting preference inputs on cancel. - */ - -cr.define('options', function() { - /** @const */ var Page = cr.ui.pageManager.Page; - /** @const */ var PageManager = cr.ui.pageManager.PageManager; - - /** - * Base class for settings dialogs. - * @constructor - * @param {string} name See Page constructor. - * @param {string} title See Page constructor. - * @param {string} pageDivName See Page constructor. - * @param {HTMLButtonElement} okButton The confirmation button element. - * @param {HTMLButtonElement} cancelButton The cancellation button element. - * @extends {cr.ui.pageManager.Page} - */ - function SettingsDialog(name, title, pageDivName, okButton, cancelButton) { - Page.call(this, name, title, pageDivName); - this.okButton = okButton; - this.cancelButton = cancelButton; - } - - SettingsDialog.prototype = { - __proto__: Page.prototype, - - /** @override */ - initializePage: function() { - this.okButton.onclick = this.handleConfirm.bind(this); - this.cancelButton.onclick = this.handleCancel.bind(this); - }, - - /** - * Handles the confirm button by saving the dialog preferences. - */ - handleConfirm: function() { - PageManager.closeOverlay(); - - var prefs = Preferences.getInstance(); - var els = this.pageDiv.querySelectorAll('[dialog-pref]'); - for (var i = 0; i < els.length; i++) { - if (els[i].pref) - prefs.commitPref(els[i].pref, els[i].metric); - } - }, - - /** - * Handles the cancel button by closing the overlay. - */ - handleCancel: function() { - PageManager.closeOverlay(); - - var prefs = Preferences.getInstance(); - var els = this.pageDiv.querySelectorAll('[dialog-pref]'); - for (var i = 0; i < els.length; i++) { - if (els[i].pref) - prefs.rollbackPref(els[i].pref); - } - }, - }; - - return { - SettingsDialog: SettingsDialog - }; -});
diff --git a/chrome/browser/resources/options/spelling_confirm_overlay.css b/chrome/browser/resources/options/spelling_confirm_overlay.css deleted file mode 100644 index ea3594b..0000000 --- a/chrome/browser/resources/options/spelling_confirm_overlay.css +++ /dev/null
@@ -1,7 +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. */ - -#spelling-confirm-overlay { - width: 500px; -}
diff --git a/chrome/browser/resources/options/spelling_confirm_overlay.html b/chrome/browser/resources/options/spelling_confirm_overlay.html deleted file mode 100644 index a8c977a..0000000 --- a/chrome/browser/resources/options/spelling_confirm_overlay.html +++ /dev/null
@@ -1,19 +0,0 @@ -<div id="spelling-confirm-overlay" class="page" hidden> - <div class="close-button"></div> - <h1>$i18n{spellingConfirmOverlay}</h1> - <div class="content-area"> - <span id="spelling-confirm-text">$i18n{spellingConfirmMessage}</span> - <a id="spelling-confirm-learn-more" target="_blank" - href="$i18nRaw{privacyLearnMoreURL}">$i18n{learnMore}</a> - </div> - <div class="action-area"> - <div class="button-strip"> - <button id="spelling-confirm-cancel"> - $i18n{spellingConfirmDisable} - </button> - <button id="spelling-confirm-ok" class="default-button"> - $i18n{spellingConfirmEnable} - </button> - </div> - </div> -</div>
diff --git a/chrome/browser/resources/options/startup_overlay.css b/chrome/browser/resources/options/startup_overlay.css deleted file mode 100644 index 322662c..0000000 --- a/chrome/browser/resources/options/startup_overlay.css +++ /dev/null
@@ -1,45 +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. */ - -#startup-overlay { - min-width: 500px; -} - -#startupPagesList { - margin-bottom: 20px; - min-height: 64px; -} - -#startupPagesList .title { - width: 40%; -} - -#startupPagesList .url { - -webkit-box-flex: 1; - color: #666; -} - -#startupPagesList > * { - max-width: 700px; -} - -#startupPagesList .url input { - width: 100%; -} - -#startupPagesListDropmarker { - background-clip: padding-box; - background-color: hsl(214, 91%, 65%); - border: 2px solid hsl(214, 91%, 65%); - border-bottom-color: transparent; - border-radius: 0; - border-top-color: transparent; - box-sizing: border-box; - display: none; - height: 6px; - overflow: hidden; - pointer-events: none; - position: fixed; - z-index: 10; -}
diff --git a/chrome/browser/resources/options/startup_overlay.html b/chrome/browser/resources/options/startup_overlay.html deleted file mode 100644 index 7864b70..0000000 --- a/chrome/browser/resources/options/startup_overlay.html +++ /dev/null
@@ -1,24 +0,0 @@ -<div id="startup-overlay" class="page" hidden> - <div class="close-button"></div> - <h1>$i18n{startupPagesOverlay}</h1> - <!-- This <input> element is always hidden. It needs to be here so that - its 'controlled-by' attribute will get set when the urls preference is - managed by a policy, so that the managed prefs bar will show up. - --> - <input type="text" pref="session.startup_urls" hidden> - <div class="content-area"> - <list id="startupPagesList"></list> - </div> - <div class="action-area"> - <span class="hbox stretch"> - <button id="startupUseCurrentButton">$i18n{startupUseCurrent}</button> - </span> - <div class="button-strip"> - <button id="startup-overlay-cancel">$i18n{cancel}</button> - <button id="startup-overlay-confirm" class="default-button"> - $i18n{ok} - </button> - </div> - </div> - <div id="startupPagesListDropmarker"></div> -</div>
diff --git a/chrome/browser/resources/options/startup_overlay.js b/chrome/browser/resources/options/startup_overlay.js deleted file mode 100644 index 8d761fe5..0000000 --- a/chrome/browser/resources/options/startup_overlay.js +++ /dev/null
@@ -1,166 +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. - -cr.define('options', function() { - /** @const */ var ArrayDataModel = cr.ui.ArrayDataModel; - /** @const */ var SettingsDialog = options.SettingsDialog; - - /** - * StartupOverlay class - * Encapsulated handling of the 'Set Startup pages' overlay page. - * @constructor - * @extends {options.SettingsDialog} - */ - function StartupOverlay() { - SettingsDialog.call(this, 'startup', - loadTimeData.getString('startupPagesOverlayTabTitle'), - 'startup-overlay', - assertInstanceof($('startup-overlay-confirm'), HTMLButtonElement), - assertInstanceof($('startup-overlay-cancel'), HTMLButtonElement)); - } - - cr.addSingletonGetter(StartupOverlay); - - StartupOverlay.prototype = { - __proto__: SettingsDialog.prototype, - - /** - * An autocomplete list that can be attached to a text field during editing. - * @type {HTMLElement} - * @private - */ - autocompleteList_: null, - - startup_pages_pref_: { - 'name': 'session.startup_urls', - 'disabled': false - }, - - /** @override */ - initializePage: function() { - SettingsDialog.prototype.initializePage.call(this); - - var self = this; - - var startupPagesList = $('startupPagesList'); - options.browser_options.StartupPageList.decorate(startupPagesList); - startupPagesList.autoExpands = true; - - $('startupUseCurrentButton').onclick = function(event) { - chrome.send('setStartupPagesToCurrentPages'); - }; - - Preferences.getInstance().addEventListener( - this.startup_pages_pref_.name, - this.handleStartupPageListChange_.bind(this)); - - var suggestionList = new cr.ui.AutocompleteList(); - suggestionList.autoExpands = true; - suggestionList.requestSuggestions = - this.requestAutocompleteSuggestions_.bind(this); - $('startup-overlay').appendChild(suggestionList); - this.autocompleteList_ = suggestionList; - startupPagesList.autocompleteList = suggestionList; - }, - - /** @override */ - handleConfirm: function() { - SettingsDialog.prototype.handleConfirm.call(this); - chrome.send('commitStartupPrefChanges'); - // Set the startup behavior to "open specific set of pages" so that the - // pages the user selected actually get opened on startup. - Preferences.setIntegerPref('session.restore_on_startup', 4, true); - }, - - /** @override */ - handleCancel: function() { - SettingsDialog.prototype.handleCancel.call(this); - chrome.send('cancelStartupPrefChanges'); - }, - - /** - * Sets the enabled state of the custom startup page list - * @param {boolean} disable True to disable, false to enable - */ - setControlsDisabled: function(disable) { - var startupPagesList = $('startupPagesList'); - startupPagesList.disabled = disable; - // Explicitly set disabled state for input text elements. - var inputs = startupPagesList.querySelectorAll("input[type='text']"); - for (var i = 0; i < inputs.length; i++) - inputs[i].disabled = disable; - $('startupUseCurrentButton').disabled = disable; - }, - - /** - * Enables or disables the the custom startup page list controls - * based on the whether the 'pages to restore on startup' pref is enabled. - */ - updateControlStates: function() { - this.setControlsDisabled( - this.startup_pages_pref_.disabled); - }, - - /** - * Handles change events of the preference - * 'session.startup_urls'. - * @param {Event} event Preference changed event. - * @private - */ - handleStartupPageListChange_: function(event) { - this.startup_pages_pref_.disabled = event.value.disabled; - this.updateControlStates(); - }, - - /** - * Updates the startup pages list with the given entries. - * @param {!Array} pages List of startup pages. - * @private - */ - updateStartupPages_: function(pages) { - var model = new ArrayDataModel(pages); - // Add a "new page" row. - model.push({modelIndex: -1}); - $('startupPagesList').dataModel = model; - }, - - /** - * Sends an asynchronous request for new autocompletion suggestions for the - * the given query. When new suggestions are available, the C++ handler will - * call updateAutocompleteSuggestions_. - * @param {string} query List of autocomplete suggestions. - * @private - */ - requestAutocompleteSuggestions_: function(query) { - chrome.send('requestAutocompleteSuggestionsForStartupPages', [query]); - }, - - /** - * Updates the autocomplete suggestion list with the given entries. - * @param {Array} suggestions List of autocomplete suggestions. - * @private - */ - updateAutocompleteSuggestions_: function(suggestions) { - var list = this.autocompleteList_; - // If the trigger for this update was a value being selected from the - // current list, do nothing. - if (list.targetInput && list.selectedItem && - list.selectedItem.url == list.targetInput.value) { - return; - } - list.suggestions = suggestions; - }, - }; - - // Forward public APIs to private implementations. - cr.makePublic(StartupOverlay, [ - 'updateStartupPages', - 'updateAutocompleteSuggestions', - ]); - - // Export - return { - StartupOverlay: StartupOverlay - }; -});
diff --git a/chrome/browser/resources/options/startup_section.html b/chrome/browser/resources/options/startup_section.html deleted file mode 100644 index 764f63a..0000000 --- a/chrome/browser/resources/options/startup_section.html +++ /dev/null
@@ -1,45 +0,0 @@ -<section id="startup-section" guest-visibility="hidden"> - <h3>$i18n{sectionTitleStartup}</h3> - <div id="startup-section-content"> - <div class="radio controlled-setting-with-label" - id="newtab-section-content"> - <label> - <input type="radio" name="startup" value="5" - pref="session.restore_on_startup" - metric="Options_Startup_NewTab"> - <span> - <span>$i18n{startupShowNewTab}</span> - <span class="controlled-setting-indicator" - pref="session.restore_on_startup" value="5"></span> - </span> - </label> - </div> - <div class="radio controlled-setting-with-label"> - <label> - <input id="startup-restore-session" type="radio" name="startup" - value="1" pref="session.restore_on_startup" - metric="Options_Startup_LastSession"> - <span> - <span>$i18n{startupRestoreLastSession}</span> - <span class="controlled-setting-indicator" - pref="session.restore_on_startup" value="1"></span> - </span> - </label> - </div> - <div class="radio controlled-setting-with-label"> - <label> - <input id="startup-show-pages" type="radio" name="startup" - pref="session.restore_on_startup" - value="4" metric="Options_Startup_Custom"> - <span> - <span>$i18n{startupShowPages}</span> - <span class="controlled-setting-indicator" - pref="session.restore_on_startup" value="4"></span> - </span> - </label> - <a is="action-link" id="startup-set-pages">$i18n{startupSetPages}</a> - <span class="controlled-setting-indicator" - pref="session.startup_urls"></span> - </div> - </div> -</section>
diff --git a/chrome/browser/resources/options/subpages_tab_controls.css b/chrome/browser/resources/options/subpages_tab_controls.css deleted file mode 100644 index 5ab21c3..0000000 --- a/chrome/browser/resources/options/subpages_tab_controls.css +++ /dev/null
@@ -1,70 +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. */ - -.subpages-nav-tabs .tab { - padding: 4px 8px; - position: relative; -} - -.subpages-nav-tabs .active-tab { - background: white; - border: 1px solid #ddd; - border-bottom: 2px solid white; - border-top-left-radius: 3px; - border-top-right-radius: 3px; - box-shadow: 8px -8px 12px -6px rgb(240, 240, 240); - position: relative; -} - -/* To avoid tabs changing size when they are clicked and their labels become - * bold, we actually put two labels inside each tab: an inactive label and an - * active label. Only one is visible at a time, but the bold label is used to - * size the tab even when it's not visible. This keeps the tab size constant. */ -.subpages-nav-tabs .active-tab-label, -.subpages-nav-tabs .tab-label:hover { - font-weight: bold; -} - -.subpages-nav-tabs .tab-label { - left: 9px; - position: absolute; - top: 5px; -} - -html[dir=rtl] .subpages-nav-tabs .tab-label { - right: 9px; -} - -.subpages-nav-tabs .active-tab-label, -.subpages-nav-tabs .active-tab .tab-label { - visibility: hidden; -} - -/* .tab is not removed when .active-tab is added, so we must override the hidden - * visibility above in the active tab case. */ -.subpages-nav-tabs .active-tab .active-tab-label { - visibility: visible; -} - -.subpages-nav-tabs { - background-image: linear-gradient( - to bottom, - rgb(255,255,255), - rgb(255,255,255) 60%, - rgb(250, 250, 250) 80%, - rgb(242,242,242) - ); - border-bottom: 1px solid #ddd; - padding: 4px 20px; -} - -.subpages-tab-contents { - -webkit-padding-start: 10px; - display: none; - padding-top: 15px; -} - -.active-tab-contents { - display: block; -}
diff --git a/chrome/browser/resources/options/supervised_user_create_confirm.css b/chrome/browser/resources/options/supervised_user_create_confirm.css deleted file mode 100644 index 828448a8..0000000 --- a/chrome/browser/resources/options/supervised_user_create_confirm.css +++ /dev/null
@@ -1,46 +0,0 @@ -/* Copyright 2014 The Chromium Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. */ - -#supervised-user-created { - width: 722px; -} - -#supervised-user-created-title { - padding: 20px; - word-wrap: break-word; -} - -@media only screen and (max-height:400px) { - -/* Omit the image on very small screens. */ -#supervised-user-created-image { - display: none; -} - -} /* @media only screen and (max-height:400px) */ - -#supervised-user-created-image { - background-image: -webkit-image-set( - url(../../../../ui/resources/default_100_percent/supervised_illustration_done.png) 1x, - url(../../../../ui/resources/default_200_percent/supervised_illustration_done.png) 2x); - background-position: center; - border-radius: 3px 3px 0 0; - flex: 5; - height: 344px; -} - -#supervised-user-created-text { - padding: 0 20px 0 20px; - white-space: pre-wrap; - word-wrap: break-word; -} - -#supervised-user-created-switch { - max-width: 600px; - word-wrap: break-word; -} - -#supervised-user-created-action-area { - padding: 20px; -}
diff --git a/chrome/browser/resources/options/supervised_user_create_confirm.html b/chrome/browser/resources/options/supervised_user_create_confirm.html deleted file mode 100644 index ae4076a..0000000 --- a/chrome/browser/resources/options/supervised_user_create_confirm.html +++ /dev/null
@@ -1,14 +0,0 @@ -<div id="supervised-user-created" class="page" hidden> - <div class="close-button"></div> - <!-- Overlay for the confirmation after creating a supervised user. --> - <div id="supervised-user-created-image"></div> - <h1 id="supervised-user-created-title"></h1> - <div id="supervised-user-created-text" class="content-area"></div> - <div id="supervised-user-created-action-area" - class="action-area button-strip"> - <button id="supervised-user-created-done"> - $i18n{supervisedUserCreatedDone} - </button> - <button id="supervised-user-created-switch"></button> - </div> -</div>
diff --git a/chrome/browser/resources/options/supervised_user_create_confirm.js b/chrome/browser/resources/options/supervised_user_create_confirm.js deleted file mode 100644 index cd3274b..0000000 --- a/chrome/browser/resources/options/supervised_user_create_confirm.js +++ /dev/null
@@ -1,128 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -cr.define('options', function() { - var Page = cr.ui.pageManager.Page; - var PageManager = cr.ui.pageManager.PageManager; - - /** - * SupervisedUserCreateConfirm class. - * Encapsulated handling of the confirmation overlay page when creating a - * supervised user. - * @constructor - * @extends {cr.ui.pageManager.Page} - */ - function SupervisedUserCreateConfirmOverlay() { - Page.call(this, 'supervisedUserCreateConfirm', - '', // The title will be based on the new profile name. - 'supervised-user-created'); - } - - cr.addSingletonGetter(SupervisedUserCreateConfirmOverlay); - - SupervisedUserCreateConfirmOverlay.prototype = { - // Inherit from Page. - __proto__: Page.prototype, - - // Info about the newly created profile. - profileInfo_: null, - - /** @override */ - initializePage: function() { - Page.prototype.initializePage.call(this); - - $('supervised-user-created-done').onclick = function(event) { - PageManager.closeOverlay(); - }; - - var self = this; - - $('supervised-user-created-switch').onclick = function(event) { - PageManager.closeOverlay(); - chrome.send('switchToProfile', [self.profileInfo_.filePath]); - }; - }, - - /** @override */ - didShowPage: function() { - $('supervised-user-created-switch').focus(); - }, - - /** - * Sets the profile info used in the dialog and updates the profile name - * displayed. Called by the profile creation overlay when this overlay is - * opened. - * @param {Object} info An object of the form: - * info = { - * name: "Profile Name", - * filePath: "/path/to/profile/data/on/disk", - * isSupervised: (true|false) - * custodianEmail: "example@gmail.com" - * }; - * @private - */ - setProfileInfo_: function(info) { - this.profileInfo_ = info; - var MAX_LENGTH = 50; - var elidedName = elide(info.name, MAX_LENGTH); - $('supervised-user-created-title').textContent = - loadTimeData.getStringF('supervisedUserCreatedTitle', elidedName); - $('supervised-user-created-switch').textContent = - loadTimeData.getStringF('supervisedUserCreatedSwitch', elidedName); - - // HTML-escape the user-supplied strings before putting them into - // innerHTML. This is probably excessive for the email address, but - // belt-and-suspenders is cheap here. - $('supervised-user-created-text').innerHTML = - loadTimeData.getStringF('supervisedUserCreatedText', - HTMLEscape(elidedName), - HTMLEscape(elide(info.custodianEmail, - MAX_LENGTH))); - }, - - /** @override */ - canShowPage: function() { - return this.profileInfo_ != null; - }, - - /** - * Updates the displayed profile name if it has changed. Called by the - * handler. - * @param {string} filePath The file path of the profile whose name - * changed. - * @param {string} newName The changed profile's new name. - * @private - */ - onUpdatedProfileName_: function(filePath, newName) { - if (filePath == this.profileInfo_.filePath) { - this.profileInfo_.name = newName; - this.setProfileInfo_(this.profileInfo_); - } - }, - - /** - * Closes this overlay if the new profile has been deleted. Called by the - * handler. - * @param {string} filePath The file path of the profile that was deleted. - * @private - */ - onDeletedProfile_: function(filePath) { - if (filePath == this.profileInfo_.filePath) { - PageManager.closeOverlay(); - } - }, - }; - - // Forward public APIs to private implementations. - cr.makePublic(SupervisedUserCreateConfirmOverlay, [ - 'onDeletedProfile', - 'onUpdatedProfileName', - 'setProfileInfo', - ]); - - // Export - return { - SupervisedUserCreateConfirmOverlay: SupervisedUserCreateConfirmOverlay, - }; -});
diff --git a/chrome/browser/resources/options/supervised_user_import.css b/chrome/browser/resources/options/supervised_user_import.css deleted file mode 100644 index af4b8c4..0000000 --- a/chrome/browser/resources/options/supervised_user_import.css +++ /dev/null
@@ -1,84 +0,0 @@ -/* Copyright 2014 The Chromium Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. */ - -#supervised-user-import { - width: 612px; -} - -#supervised-user-import-text, -#supervised-user-select-avatar-text { - padding-bottom: 10px; - padding-left: 17px; - white-space: pre-wrap; - word-wrap: break-word; -} - -#supervised-user-list { - height: 240px; - margin-bottom: 10px; -} - -#supervised-user-list .list-item { - align-items: center; - display: flex; -} - -#supervised-user-list .profile-img { - flex-shrink: 0; -} - -#supervised-user-list .profile-name { - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} - -#supervised-user-list .already-on-this-device { - flex-shrink: 0; -} - -#supervised-user-list > * { - height: 40px; -} - -#supervised-user-list:focus { - border-color: rgb(77, 144, 254); -} - -#select-avatar-grid { - background-color: rgba(255, 255, 255, 0.75); - padding: 2px; -} - -#supervised-user-import-error-bubble { - background-color: rgb(238, 185, 57); - border-radius: 4px; - font-weight: bold; - margin-left: auto; - margin-right: auto; - margin-top: 10px; - max-height: 50px; - overflow: hidden; - padding: 1px 10px; - text-align: center; - transition: max-height 200ms, padding 200ms; - width: 80%; -} - -#supervised-user-import-error-bubble[hidden] { - max-height: 0; -} - -.profile-img-disabled { - opacity: 0.4; -} - -.profile-name-disabled { - color: rgb(153, 153, 153); -} - -.already-on-this-device { - padding-left: 20px; - padding-right: 6px; -}
diff --git a/chrome/browser/resources/options/supervised_user_import.html b/chrome/browser/resources/options/supervised_user_import.html deleted file mode 100644 index 9fd806d..0000000 --- a/chrome/browser/resources/options/supervised_user_import.html +++ /dev/null
@@ -1,40 +0,0 @@ -<div id="supervised-user-import" class="page" hidden> - <div class="close-button"></div> - <!-- Overlay to import an existing supervised user during user creation --> - <h1 id="supervised-user-import-title" class="supervised-user-import"> - $i18n{supervisedUserImportTitle} - </h1> - <h1 id="supervised-user-select-avatar-title" - class="supervised-user-select-avatar" hidden> - $i18n{supervisedUserSelectAvatarTitle} - </h1> - <div id="supervised-user-import-text" class="supervised-user-import"> - $i18n{supervisedUserImportText} - </div> - <div id="supervised-user-select-avatar-text" - class="supervised-user-select-avatar" hidden> - $i18n{supervisedUserSelectAvatarText} - </div> - <div id="supervised-user-import-content-area" class="content-area"> - <list id="supervised-user-list" - class="settings-list supervised-user-import"> - </list> - <grid id="select-avatar-grid" class="supervised-user-select-avatar" hidden> - </grid> - </div> - <div id="supervised-user-import-error-bubble" hidden></div> - <div id="supervised-user-import-action-area" class="action-area"> - <div class="button-strip"> - <div id="supervised-user-import-throbber" class="throbber"></div> - <button id="supervised-user-import-cancel">$i18n{cancel}</button> - <button id="supervised-user-import-ok" - class="default-button supervised-user-import"> - $i18n{supervisedUserImportOk} - </button> - <button id="supervised-user-select-avatar-ok" - class="default-button supervised-user-select-avatar" hidden> - $i18n{supervisedUserSelectAvatarOk} - </button> - </div> - </div> -</div>
diff --git a/chrome/browser/resources/options/supervised_user_import.js b/chrome/browser/resources/options/supervised_user_import.js deleted file mode 100644 index ea97b42..0000000 --- a/chrome/browser/resources/options/supervised_user_import.js +++ /dev/null
@@ -1,252 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -cr.define('options', function() { - var Page = cr.ui.pageManager.Page; - var PageManager = cr.ui.pageManager.PageManager; - var ArrayDataModel = cr.ui.ArrayDataModel; - - /** - * SupervisedUserImportOverlay class. - * Encapsulated handling of the 'Import existing supervised user' overlay - * page. - * @constructor - * @extends {cr.ui.pageManager.Page} - */ - function SupervisedUserImportOverlay() { - var title = loadTimeData.getString('supervisedUserImportTitle'); - Page.call(this, 'supervisedUserImport', title, 'supervised-user-import'); - } - - cr.addSingletonGetter(SupervisedUserImportOverlay); - - SupervisedUserImportOverlay.prototype = { - // Inherit from Page. - __proto__: Page.prototype, - - /** @override */ - canShowPage: function() { - return !BrowserOptions.getCurrentProfile().isSupervised; - }, - - /** @override */ - initializePage: function() { - Page.prototype.initializePage.call(this); - - var supervisedUserList = $('supervised-user-list'); - options.supervisedUserOptions.SupervisedUserList.decorate( - supervisedUserList); - - var avatarGrid = $('select-avatar-grid'); - options.ProfilesIconGrid.decorate(avatarGrid); - var avatarIcons = loadTimeData.getValue('avatarIcons'); - avatarGrid.dataModel = new ArrayDataModel( - /** @type {!Array} */(avatarIcons)); - - supervisedUserList.addEventListener('change', function(event) { - var supervisedUser = supervisedUserList.selectedItem; - $('supervised-user-import-ok').disabled = - !supervisedUser || supervisedUser.onCurrentDevice; - }); - - var self = this; - $('supervised-user-import-cancel').onclick = function(event) { - if (self.inProgress_) { - self.updateImportInProgress_(false); - - // 'cancelCreateProfile' is handled by CreateProfileHandler. - chrome.send('cancelCreateProfile'); - } - PageManager.closeOverlay(); - }; - - $('supervised-user-import-ok').onclick = - this.showAvatarGridOrSubmit_.bind(this); - $('supervised-user-select-avatar-ok').onclick = - this.showAvatarGridOrSubmit_.bind(this); - }, - - /** - * @override - */ - didShowPage: function() { - // When the import link is clicked to open this overlay, it is hidden in - // order to trigger a cursor update. We can show the import link again - // now. TODO(akuegel): Remove this temporary fix when crbug/246304 is - // resolved. - $('import-existing-supervised-user-link').hidden = false; - - options.SupervisedUserListData.requestExistingSupervisedUsers().then( - this.receiveExistingSupervisedUsers_.bind(this), - this.onSigninError_.bind(this)); - options.SupervisedUserListData.addObserver(this); - - this.updateImportInProgress_(false); - $('supervised-user-import-error-bubble').hidden = true; - $('supervised-user-import-ok').disabled = true; - this.showAppropriateElements_(/* isSelectAvatarMode */ false); - }, - - /** - * @override - */ - didClosePage: function() { - options.SupervisedUserListData.removeObserver(this); - }, - - /** - * Shows either the supervised user import dom elements or the select avatar - * dom elements. - * @param {boolean} isSelectAvatarMode True if the overlay should show the - * select avatar grid, and false if the overlay should show the - * supervised user list. - * @private - */ - showAppropriateElements_: function(isSelectAvatarMode) { - var avatarElements = - this.pageDiv.querySelectorAll('.supervised-user-select-avatar'); - for (var i = 0; i < avatarElements.length; i++) - avatarElements[i].hidden = !isSelectAvatarMode; - var importElements = - this.pageDiv.querySelectorAll('.supervised-user-import'); - for (var i = 0; i < importElements.length; i++) - importElements[i].hidden = isSelectAvatarMode; - }, - - /** - * Called when the user clicks the "OK" button. In case the supervised - * user being imported has no avatar in sync, it shows the avatar - * icon grid. In case the avatar grid is visible or the supervised user - * already has an avatar stored in sync, it proceeds with importing - * the supervised user. - * @private - */ - showAvatarGridOrSubmit_: function() { - var supervisedUser = $('supervised-user-list').selectedItem; - if (!supervisedUser) - return; - - $('supervised-user-import-error-bubble').hidden = true; - - if ($('select-avatar-grid').hidden && supervisedUser.needAvatar) { - this.showAvatarGridHelper_(); - return; - } - - var avatarUrl = supervisedUser.needAvatar ? - $('select-avatar-grid').selectedItem : supervisedUser.iconURL; - - this.updateImportInProgress_(true); - - // 'createProfile' is handled by CreateProfileHandler. - chrome.send('createProfile', [supervisedUser.name, avatarUrl, - false, true, supervisedUser.id]); - }, - - /** - * Hides the 'supervised user list' and shows the avatar grid instead. - * It also updates the overlay text and title to instruct the user - * to choose an avatar for the supervised user. - * @private - */ - showAvatarGridHelper_: function() { - this.showAppropriateElements_(/* isSelectAvatarMode */ true); - $('select-avatar-grid').redraw(); - $('select-avatar-grid').selectedItem = - loadTimeData.getValue('avatarIcons')[0]; - }, - - /** - * Updates the UI according to the importing state. - * @param {boolean} inProgress True to indicate that - * importing is in progress and false otherwise. - * @private - */ - updateImportInProgress_: function(inProgress) { - this.inProgress_ = inProgress; - $('supervised-user-import-ok').disabled = inProgress; - $('supervised-user-select-avatar-ok').disabled = inProgress; - $('supervised-user-list').disabled = inProgress; - $('select-avatar-grid').disabled = inProgress; - $('supervised-user-import-throbber').hidden = !inProgress; - }, - - /** - * Sets the data model of the supervised user list to |supervisedUsers|. - * @param {Array<{id: string, name: string, iconURL: string, - * onCurrentDevice: boolean, needAvatar: boolean}>} supervisedUsers - * Array of supervised user objects. - * @private - */ - receiveExistingSupervisedUsers_: function(supervisedUsers) { - supervisedUsers.sort(function(a, b) { - if (a.onCurrentDevice != b.onCurrentDevice) - return a.onCurrentDevice ? 1 : -1; - return a.name.localeCompare(b.name); - }); - - $('supervised-user-list').dataModel = new ArrayDataModel(supervisedUsers); - if (supervisedUsers.length == 0) { - this.onErrorInternal_( - loadTimeData.getString('noExistingSupervisedUsers')); - $('supervised-user-import-ok').disabled = true; - } else { - // Hide the error bubble. - $('supervised-user-import-error-bubble').hidden = true; - } - }, - - onSigninError_: function() { - $('supervised-user-list').dataModel = null; - this.onErrorInternal_( - loadTimeData.getString('supervisedUserImportSigninError')); - }, - - /** - * Displays an error message if an error occurs while - * importing a supervised user. - * Called by BrowserOptions via the BrowserOptionsHandler. - * @param {string} error The error message to display. - * @private - */ - onError_: function(error) { - this.onErrorInternal_(error); - this.updateImportInProgress_(false); - }, - - /** - * Displays an error message. - * @param {string} error The error message to display. - * @private - */ - onErrorInternal_: function(error) { - var errorBubble = $('supervised-user-import-error-bubble'); - errorBubble.hidden = false; - errorBubble.textContent = error; - }, - - /** - * Closes the overlay if importing the supervised user was successful. Also - * reset the cached list of supervised users in order to get an updated list - * when the overlay is reopened. - * @private - */ - onSuccess_: function() { - this.updateImportInProgress_(false); - options.SupervisedUserListData.resetPromise(); - PageManager.closeAllOverlays(); - }, - }; - - // Forward public APIs to private implementations. - cr.makePublic(SupervisedUserImportOverlay, [ - 'onError', - 'onSuccess', - ]); - - // Export - return { - SupervisedUserImportOverlay: SupervisedUserImportOverlay, - }; -});
diff --git a/chrome/browser/resources/options/supervised_user_learn_more.css b/chrome/browser/resources/options/supervised_user_learn_more.css deleted file mode 100644 index e54d68b..0000000 --- a/chrome/browser/resources/options/supervised_user_learn_more.css +++ /dev/null
@@ -1,41 +0,0 @@ -/* Copyright 2014 The Chromium Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. */ - -#supervised-user-learn-more { - display: flex; - flex-direction: column; - width: 722px; -} - -#supervised-user-learn-more-title { - padding: 20px; -} - -#supervised-user-learn-more-text { - padding: 0 20px 0 20px; - white-space: pre-wrap; - word-wrap: break-word; -} - -@media only screen and (max-height:500px) { - -/* Omit the image on very small screens. */ -#supervised-user-learn-more-image { - display: none; -} - -} /* @media only screen and (max-height:500px) */ - -#supervised-user-learn-more-image { - background-image: -webkit-image-set( - url(../../../../ui/resources/default_100_percent/supervised_illustration_start.png) 1x, - url(../../../../ui/resources/default_200_percent/supervised_illustration_start.png) 2x); - background-position: center; - border-radius: 3px 3px 0 0; - height: 344px; -} - -#supervised-user-learn-more-action-area { - padding: 20px; -}
diff --git a/chrome/browser/resources/options/supervised_user_learn_more.html b/chrome/browser/resources/options/supervised_user_learn_more.html deleted file mode 100644 index 651cfb5e..0000000 --- a/chrome/browser/resources/options/supervised_user_learn_more.html +++ /dev/null
@@ -1,17 +0,0 @@ -<div id="supervised-user-learn-more" class="page" hidden> - <div class="close-button"></div> - <!-- Overlay for the 'Learn more' link when creating a supervised user. --> - <div id="supervised-user-learn-more-image"></div> - <h1 id="supervised-user-learn-more-title" - i18n-content="supervisedUserLearnMoreTitle"> - </h1> - <div id="supervised-user-learn-more-text" class="content-area" - i18n-values=".innerHTML:supervisedUserLearnMoreText"> - </div> - <div id="supervised-user-learn-more-action-area" - class="action-area button-strip"> - <button id="supervised-user-learn-more-done" - i18n-content="supervisedUserLearnMoreDone"> - </button> - </div> -</div>
diff --git a/chrome/browser/resources/options/supervised_user_learn_more.js b/chrome/browser/resources/options/supervised_user_learn_more.js deleted file mode 100644 index da7975e..0000000 --- a/chrome/browser/resources/options/supervised_user_learn_more.js +++ /dev/null
@@ -1,40 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -cr.define('options', function() { - var Page = cr.ui.pageManager.Page; - - /** - * SupervisedUserLearnMore class. - * Encapsulated handling of the 'Learn more...' overlay page. - * @constructor - * @extends {cr.ui.pageManager.Page} - */ - function SupervisedUserLearnMoreOverlay() { - Page.call(this, 'supervisedUserLearnMore', - loadTimeData.getString('supervisedUserLearnMoreTitle'), - 'supervised-user-learn-more'); - } - - cr.addSingletonGetter(SupervisedUserLearnMoreOverlay); - - SupervisedUserLearnMoreOverlay.prototype = { - // Inherit from Page. - __proto__: Page.prototype, - - /** @override */ - initializePage: function() { - Page.prototype.initializePage.call(this); - - $('supervised-user-learn-more-done').onclick = function(event) { - cr.ui.pageManager.PageManager.closeOverlay(); - }; - }, - }; - - // Export - return { - SupervisedUserLearnMoreOverlay: SupervisedUserLearnMoreOverlay, - }; -});
diff --git a/chrome/browser/resources/options/supervised_user_list.js b/chrome/browser/resources/options/supervised_user_list.js deleted file mode 100644 index ca4a479..0000000 --- a/chrome/browser/resources/options/supervised_user_list.js +++ /dev/null
@@ -1,120 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -cr.define('options.supervisedUserOptions', function() { - /** @const */ var List = cr.ui.List; - /** @const */ var ListItem = cr.ui.ListItem; - /** @const */ var ListSingleSelectionModel = cr.ui.ListSingleSelectionModel; - - /** - * Create a new supervised user list item. - * @param {Object} entry The supervised user this item represents. - * It has the following form: - * supervisedUser = { - * id: "Supervised User ID", - * name: "Supervised User Name", - * iconURL: "chrome://path/to/icon/image", - * onCurrentDevice: true or false, - * needAvatar: true or false - * } - * @constructor - * @extends {cr.ui.ListItem} - */ - function SupervisedUserListItem(entry) { - var el = cr.doc.createElement('div'); - el.className = 'list-item'; - el.supervisedUser_ = entry; - el.__proto__ = SupervisedUserListItem.prototype; - el.decorate(); - return el; - } - - SupervisedUserListItem.prototype = { - __proto__: ListItem.prototype, - - /** - * @type {string} the ID of this supervised user list item. - */ - get id() { - return this.supervisedUser_.id; - }, - - /** - * @type {string} the name of this supervised user list item. - */ - get name() { - return this.supervisedUser_.name; - }, - - /** - * @type {string} the path to the avatar icon of this supervised - * user list item. - */ - get iconURL() { - return this.supervisedUser_.iconURL; - }, - - /** @override */ - decorate: function() { - ListItem.prototype.decorate.call(this); - var supervisedUser = this.supervisedUser_; - - // Add the avatar. - var iconElement = this.ownerDocument.createElement('img'); - iconElement.className = 'profile-img'; - iconElement.style.content = cr.icon.getImage(supervisedUser.iconURL); - this.appendChild(iconElement); - - // Add the profile name. - var nameElement = this.ownerDocument.createElement('div'); - nameElement.className = 'profile-name'; - nameElement.textContent = supervisedUser.name; - this.appendChild(nameElement); - - if (supervisedUser.onCurrentDevice) { - iconElement.className += ' profile-img-disabled'; - nameElement.className += ' profile-name-disabled'; - - // Add "(already on this device)" message. - var alreadyOnDeviceElement = this.ownerDocument.createElement('div'); - alreadyOnDeviceElement.className = - 'profile-name-disabled already-on-this-device'; - alreadyOnDeviceElement.textContent = - loadTimeData.getString('supervisedUserAlreadyOnThisDevice'); - this.appendChild(alreadyOnDeviceElement); - } - }, - }; - - /** - * Create a new supervised users list. - * @constructor - * @extends {cr.ui.List} - */ - var SupervisedUserList = cr.ui.define('list'); - - SupervisedUserList.prototype = { - __proto__: List.prototype, - - /** - * @override - * @param {Object} entry - */ - createItem: function(entry) { - return new SupervisedUserListItem(entry); - }, - - /** @override */ - decorate: function() { - List.prototype.decorate.call(this); - this.selectionModel = new ListSingleSelectionModel(); - this.autoExpands = true; - }, - }; - - return { - SupervisedUserListItem: SupervisedUserListItem, - SupervisedUserList: SupervisedUserList, - }; -});
diff --git a/chrome/browser/resources/options/supervised_user_list_data.js b/chrome/browser/resources/options/supervised_user_list_data.js deleted file mode 100644 index 78967ca..0000000 --- a/chrome/browser/resources/options/supervised_user_list_data.js +++ /dev/null
@@ -1,150 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -cr.define('options', function() { - /** - * SupervisedUserListData class. - * Handles requests for retrieving a list of existing supervised users which - * are supervised by the current profile. For each request a promise is - * returned, which is cached in order to reuse the retrieved supervised users - * for future requests. The first request will be handled asynchronously. - * @constructor - * @class - */ - function SupervisedUserListData() { - this.observers_ = []; - } - - cr.addSingletonGetter(SupervisedUserListData); - - /** - * Receives a list of supervised users and resolves the promise. - * @param {Array<Object>} supervisedUsers Array of supervised user objects. - * Each object is of the form: - * supervisedUser = { - * id: "Supervised User ID", - * name: "Supervised User Name", - * iconURL: "chrome://path/to/icon/image", - * onCurrentDevice: true or false, - * needAvatar: true or false - * } - * @private - */ - SupervisedUserListData.prototype.receiveExistingSupervisedUsers_ = - function(supervisedUsers) { - if (!this.promise_) { - this.onDataChanged_(supervisedUsers); - return; - } - this.resolve_(supervisedUsers); - }; - - /** - * Called when there is a signin error when retrieving the list of supervised - * users. Rejects the promise and resets the cached promise to null. - * @private - */ - SupervisedUserListData.prototype.onSigninError_ = function() { - if (!this.promise_) { - return; - } - this.reject_(); - this.resetPromise_(); - }; - - /** - * Handles the request for the list of existing supervised users by returning - * a promise for the requested data. If there is no cached promise yet, a new - * one will be created. - * @return {Promise} The promise containing the list of supervised users. - * @private - */ - SupervisedUserListData.prototype.requestExistingSupervisedUsers_ = - function() { - if (this.promise_) - return this.promise_; - this.promise_ = this.createPromise_(); - chrome.send('requestSupervisedUserImportUpdate'); - return this.promise_; - }; - - /** - * Creates the promise containing the list of supervised users. The promise is - * resolved in receiveExistingSupervisedUsers_() or rejected in - * onSigninError_(). The promise is cached, so that for future requests it can - * be resolved immediately. - * @return {Promise} The promise containing the list of supervised users. - * @private - */ - SupervisedUserListData.prototype.createPromise_ = function() { - var self = this; - return new Promise(function(resolve, reject) { - self.resolve_ = resolve; - self.reject_ = reject; - }); - }; - - /** - * Resets the promise to null in order to avoid stale data. For the next - * request, a new promise will be created. - * @private - */ - SupervisedUserListData.prototype.resetPromise_ = function() { - this.promise_ = null; - }; - - /** - * Initializes |promise| with the new data and also passes the new data to - * observers. - * @param {Array<Object>} supervisedUsers Array of supervised user objects. - * For the format of the objects, see receiveExistingSupervisedUsers_(). - * @private - */ - SupervisedUserListData.prototype.onDataChanged_ = function(supervisedUsers) { - this.promise_ = this.createPromise_(); - this.resolve_(supervisedUsers); - for (var i = 0; i < this.observers_.length; ++i) - this.observers_[i].receiveExistingSupervisedUsers_(supervisedUsers); - }; - - /** - * Adds an observer to the list of observers. - * @param {Object} observer The observer to be added. - * @private - */ - SupervisedUserListData.prototype.addObserver_ = function(observer) { - for (var i = 0; i < this.observers_.length; ++i) - assert(this.observers_[i] != observer); - this.observers_.push(observer); - }; - - /** - * Removes an observer from the list of observers. - * @param {Object} observer The observer to be removed. - * @private - */ - SupervisedUserListData.prototype.removeObserver_ = function(observer) { - for (var i = 0; i < this.observers_.length; ++i) { - if (this.observers_[i] == observer) { - this.observers_.splice(i, 1); - return; - } - } - }; - - // Forward public APIs to private implementations. - cr.makePublic(SupervisedUserListData, [ - 'addObserver', - 'onSigninError', - 'receiveExistingSupervisedUsers', - 'removeObserver', - 'requestExistingSupervisedUsers', - 'resetPromise', - ]); - - // Export - return { - SupervisedUserListData: SupervisedUserListData, - }; -});
diff --git a/chrome/browser/resources/options/sync_section.html b/chrome/browser/resources/options/sync_section.html deleted file mode 100644 index 375601e2..0000000 --- a/chrome/browser/resources/options/sync_section.html +++ /dev/null
@@ -1,74 +0,0 @@ -<if expr="not chromeos"> -<section id="sync-section"> - <h3>$i18n{sectionTitleSync}</h3> -</if> -<if expr="chromeos"> -<div id="sync-section"> -</if> - - <div id="sync-overview" class="settings-row" hidden> - <p>$i18n{syncOverview}</p> - <a href="$i18nRaw{syncLearnMoreURL}" target="_blank">$i18n{learnMore}</a> - </div> - -<if expr="chromeos"> - <div id="account-picture-wrapper"> - <div id="account-picture-control"> - <input type="image" id="account-picture" tabindex="0" alt="" - aria-label="$i18n{changePicture}"> - <div id="change-picture-caption">$i18n{changePicture}</div> - </div> - <span id="account-picture-indicator" class="controlled-setting-indicator"> - </span> - </div> - <div id="sync-general"> -</if> <!-- chromeos --> - - <div id="sync-status" class="settings-row" hidden> - <span id="account-info" hidden></span> - <span id="sync-status-text"></span> - <a is="action-link" id="sync-action-link"></a> - </div> - -<if expr="chromeos"> - <div class="checkbox controlled-setting-with-label" - public-account-visibility="hidden"> - <label> - <input type="checkbox" - metric="Options_ScreenLock" - pref="settings.enable_screen_lock"> - <span> - <span>$i18n{enableScreenlock}</span> - <span class="controlled-setting-indicator" - textshared="$i18n{screenLockShared}" - pref="settings.enable_screen_lock"></span> - </span> - </label> - <a is="action-link" id="manage-screenlock" hidden> - $i18n{manageScreenlock} - </a> - </div> - </div> -</if> <!-- chromeos --> - - <div id="sync-buttons" class="settings-row"> - <button id="start-stop-sync" hidden></button> - <span id="start-stop-sync-indicator" - class="controlled-setting-indicator" hidden> - </span> - <button id="customize-sync" pref="sync.managed" hidden> - $i18n{customizeSync} - </button> -<if expr="chromeos"> - <button id="manage-accounts-button" public-account-visibility="hidden"> - $i18n{manageAccountsButtonTitle} - </button> -</if> <!-- chromeos --> - </div> - -<if expr="not chromeos"> -</section> -</if> -<if expr="chromeos"> -</div> -</if>
diff --git a/chrome/browser/resources/options/sync_setup_overlay.css b/chrome/browser/resources/options/sync_setup_overlay.css deleted file mode 100644 index e9d4f58..0000000 --- a/chrome/browser/resources/options/sync_setup_overlay.css +++ /dev/null
@@ -1,215 +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. */ - -/* TODO(jhawkins): Organize these by page. */ - -#sync-setup-overlay * h4 { - margin: 15px 0 5px; -} - -#sync-setup-overlay * form { - user-select: none; -} - -#sync-setup-overlay * .content-area { - padding: 10px 15px; -} - -.action-area-link-container { - -webkit-box-flex: 1; -} - -.sync-customize-section-container { - margin: 5px 0 10px 0; -} - -#sync-custom-passphrase { - margin: 0 25px; -} - -#sync-passphrase-message { - color: gray; -} - -.sync-custom-passphrase-input { - margin: 10px 0; -} - -#sync-existing-passphrase-container { - background: rgb(255, 242, 158); - border: 1px solid rgb(212, 205, 173); - padding: 10px; -} - -#sync-instructions-container { - line-height: 1.8em; - margin-bottom: 30px; -} - -#choose-data-types-body { - -webkit-column-count: 3; - margin: 10px 0 0 0; -} - -#choose-data-types-body > .checkbox:first-child { - margin-top: 0; -} - -#choose-data-types-body > .checkbox:last-child { - margin-bottom: 0; -} - -#sync-setup-overlay { - background-color: white; - margin-bottom: 6px; - margin-top: 6px; - user-select: none; - width: 500px; -} - -#sync-setup-overlay * a:link { - color: rgb(0, 0, 204); -} - -#sync-setup-overlay * a:visited { - color: rgb(85, 26, 139); -} - -#sync-setup-overlay * a:active { - color: rgb(255, 0, 0); -} - -#sync-setup-delete-profile { - margin: 10px 0 0 0; -} - -#email-readonly { - font-size: 15px; - height: 29px; - line-height: 29px; - margin: 0; -} - -#encryption-section-message { - color: gray; - margin-bottom: 5px; -} - -#basic-encryption-body, -#full-encryption-body { - display: table; -} - -#customize-sync-encryption-new, -#personalize-google-services { - border-top: 1px solid #ddd; - margin-top: 5px; -} - -#personalize-google-services { - line-height: 1.6em; -} - -#personalize-google-services .title { - align-items: center; - display: flex; - justify-content: space-between; -} - -#googleg-logo { - background-image: url(../../../../ui/webui/resources/images/200-logo_googleg.png); - background-size: cover; - height: 20px; - width: 20px; -} - -#passphrase-input { - margin-bottom: 5px; - margin-top: 5px; -} - -#incorrect-passphrase { - margin-top: 5px; -} - -#sync-setup-overlay * .error { - color: red; -} - -.overlay-warning { - background: white; - border: 2px solid #888; - border-radius: 8px; - box-shadow: 0.2em 0.2em 0.5em #888; - left: 25px; - padding: 15px; - position: absolute; - right: 25px; - top: 100px; -} - -#cancel-warning-header { - font-weight: bold; - margin-bottom: 8px; -} - -.overlay-warning input { - float: right; - margin-left: 5px; - margin-top: 12px; -} - -#sync-passphrase-warning { - margin-bottom: 5px; -} - -#asp-warning-div { - text-align: left; -} - -#logging-in-throbber { - margin: 0 10px; -} - -#password-row { - margin-bottom: 0; - margin-top: 2px; -} - -#action-area { - margin: 1em 0; -} - -#sync-setup-configure { - background: white; -} - -#choose-data-types-form { - user-select: none; -} - -#chooseDataTypesRadio { - vertical-align: top; -} - -#chooseDataTypes > div { - display: inline-block; -} - -.sync-data-types { - margin-left: 5px; -} - -#learn-more-link { - float: right; -} - -html[dir='rtl'] #learn-more-link { - float: left; -} - -#customize-link, -#use-default-link { - transition: opacity 250ms; -}
diff --git a/chrome/browser/resources/options/sync_setup_overlay.html b/chrome/browser/resources/options/sync_setup_overlay.html deleted file mode 100644 index ab179c1..0000000 --- a/chrome/browser/resources/options/sync_setup_overlay.html +++ /dev/null
@@ -1,246 +0,0 @@ -<div id="sync-setup-overlay" class="page" hidden> - <div class="close-button"></div> - <div id="sync-setup-configure" hidden> - <div id="confirm-sync-preferences"> - <h1 i18n-content="confirmSyncPreferences"></h1> - <div id="sync-instructions-container" class="content-area"> - <span i18n-content="chooseDataTypesInstructions"></span> - <a id="encryption-help-link" target="_blank" - i18n-values="href:syncEverythingHelpURL" i18n-content="learnMore"> - </a> - </div> - <div> - <div class="action-area"> - <div class="action-area-link-container"> - <a is="action-link" id="customize-link" - i18n-content="customizeLinkLabel"></a> - </div> - <div id="confirm-everything-throbber" class="throbber"></div> - <div class="button-strip"> - <button id="confirm-everything-cancel" i18n-content="cancel"> - <button id="confirm-everything-ok" class="default-button" - i18n-content="syncEverything"> - </div> - </div> - </div> - </div> - <div id="customize-sync-preferences" hidden> - <h1 i18n-content="syncSetupConfigureTitle"></h1> - <form id="choose-data-types-form"> - <div id="sync-configure-content" class="content-area"> - <div id="sync-select-container"> - <select id="sync-select-datatypes" - metric="Options_SyncSelectDataTypes"> - <option i18n-content="syncAllDataTypes" selected></option> - <option i18n-content="chooseDataTypes"></option> - </select> - <div id="choose-data-types-body"> - <div id="apps-item" class="sync-type-checkbox checkbox"> - <label> - <input id="apps-checkbox" type="checkbox"> - <span i18n-content="apps" i18n-values="title:apps"></span> - </label> - </div> - <div id="autofill-item" class="sync-type-checkbox checkbox"> - <label> - <input id="autofill-checkbox" type="checkbox"> - <span i18n-content="autofill" i18n-values="title:autofill"> - </span> - </label> - </div> - <div class="sync-type-checkbox checkbox"> - <label> - <input id="bookmarks-checkbox" type="checkbox"> - <span i18n-content="bookmarks" - i18n-values="title:bookmarks"></span> - </label> - </div> - <div id="extensions-item" class="sync-type-checkbox checkbox"> - <label> - <input id="extensions-checkbox" type="checkbox"> - <span i18n-content="extensions" - i18n-values="title:extensions"></span> - </label> - </div> - <div id="omnibox-item" class="sync-type-checkbox checkbox"> - <label> - <input id="typed-urls-checkbox" type="checkbox"> - <span i18n-content="typedURLs" - i18n-values="title:typedURLs"></span> - </label> - </div> - <div id="passwords-item" class="sync-type-checkbox checkbox"> - <label> - <input id="passwords-checkbox" type="checkbox"> - <span i18n-content="passwords" - i18n-values="title:passwords"></span> - </label> - </div> - <div class="sync-type-checkbox checkbox"> - <label> - <input id="preferences-checkbox" type="checkbox"> - <span i18n-content="preferences" - i18n-values="title:preferences"></span> - </label> - </div> - <div class="sync-type-checkbox checkbox"> - <label> - <input id="themes-checkbox" type="checkbox"> - <span i18n-content="themes" i18n-values="title:themes"> - </span> - </label> - </div> - <div id="tabs-item" class="sync-type-checkbox checkbox"> - <label> - <input id="tabs-checkbox" type="checkbox"> - <span i18n-content="openTabs" il8n-values="title:tabs"> - </span> - </label> - </div> - </div> - </div> - <div id="payments-integration-setting-area" class="checkbox"> - <label> - <input id="payments-integration-checkbox" type="checkbox"> - <span i18n-content="enablePaymentsIntegration"></span> - </label> - <a i18n-values="href:autofillHelpURL" target="_blank" - i18n-content="learnMore"></a> - </div> - <div id="customize-sync-encryption-new"> - <h4 i18n-content="encryptionSectionTitle"></h4> - <div id="encryption-section-message" - i18n-content="encryptionSectionMessage"></div> - <div id="sync-new-encryption-section-container"> - <div class="radio"> - <label> - <input id="basic-encryption-option" name="encrypt-new" - type="radio" value="full"> - <span id="basic-encryption-body" - i18n-content="basicEncryptionOption"></span> - </label> - </div> - <div class="radio"> - <label> - <input id="full-encryption-option" name="encrypt-new" - type="radio" value="full"> - <span id="full-encryption-body" - i18n-content="fullEncryptionOption"></span> - </label> - <a i18n-values="href:encryptionHelpURL" target="_blank" - i18n-content="learnMore"></a> - </div> - </div> - </div> - <div id="sync-custom-passphrase-container" - class="sync-customize-section-container"> - <div id="sync-custom-passphrase" - class="reset-hidden" hidden> - <div id="sync-passphrase-message"> - <span i18n-content="sectionExplicitMessagePrefix"></span> - <a href="https://www.google.com/settings/chrome/sync/" - target="_blank" - i18n-content="sectionExplicitMessagePostfix"></a> - <span>.</span> - </div> - <div class="sync-custom-passphrase-input"> - <input id="custom-passphrase" type="password" - class="reset-value" - i18n-values="placeholder:passphraseLabel"> - </div> - <div class="sync-custom-passphrase-input"> - <input id="confirm-passphrase" type="password" - class="reset-value" - i18n-values="placeholder:confirmLabel"> - </div> - <div id="empty-error" class="error" - i18n-content="emptyErrorMessage" hidden></div> - <div id="mismatch-error" class="error" - i18n-content="mismatchErrorMessage" hidden></div> - </div> - </div> - <div id="sync-existing-passphrase-container" hidden> - <div id="enter-passphrase"> - <span id="normal-body" i18n-content="enterPassphraseBody" hidden> - </span> - <span id="google-passphrase-needed-body" - i18n-content="enterGooglePassphraseBody" hidden> - </span> - <a id="passphrase-learn-more" i18n-content="learnMore" - i18n-values="href:syncErrorHelpURL" class="reset-hidden" - target="_blank" hidden> - </a> - </div> - <div id="passphrase-input"> - <input id="passphrase" name="passphrase" type="password" - class="reset-value" - i18n-values="placeholder:passphraseLabel"> - <div id="incorrect-passphrase" class="error" - i18n-content="incorrectPassphrase" hidden> - </div> - </div> - <div id="sync-passphrase-warning" - i18n-values=".innerHTML:passphraseRecover" hidden> - </div> - </div> - <div id="personalize-google-services"> - <div class="title"> - <h4 i18n-content="personalizeGoogleServicesTitle"></h4> - <div id="googleg-logo" class="logo"></div> - </div> - <div i18n-values=".innerHTML:personalizeGoogleServicesMessage"> - </div> - </div> - </div> - <div class="action-area"> - <div class="action-area-link-container"> - <a is="action-link" id="use-default-link" - i18n-content="useDefaultSettings"></a> - </div> - <div id="choose-datatypes-throbber" class="throbber"></div> - <div class="button-strip"> - <input id="choose-datatypes-cancel" type="button" - i18n-values="value:cancel"> - <input id="choose-datatypes-ok" type="submit" class="default-button" - i18n-values="value:ok"> - </div> - </div> - </form> - </div> - </div> - <div id="sync-setup-spinner" hidden> - <h1 i18n-content="syncSetupSpinnerTitle"></h1> - <div class="action-area button-strip"> - <button id="sync-spinner-cancel" class="default-button" - i18n-content="cancel"> - </div> - </div> - <div id="sync-setup-timeout" hidden> - <h1 i18n-content="syncSetupTimeoutTitle"></h1> - <div class="content-area"> - <span i18n-content="syncSetupTimeoutContent"></span> - </div> - <div class="action-area button-strip"> - <button id="timeout-ok" i18n-content="ok" class="default-button"></button> - </div> - </div> - <div id="sync-setup-stop-syncing" hidden> - <h1 i18n-content="stopSyncingTitle"></h1> - <div class="content-area"> - <span i18n-values=".innerHTML:stopSyncingExplanation"></span> -<if expr="(not chromeos and is_posix) or is_win or is_macosx"> - <div id="sync-setup-delete-profile" class="checkbox"> - <label> - <input id="delete-profile" type="checkbox"> - <span i18n-content="deleteProfileLabel"></span> - </label> - </div> -</if> - </div> - <div class="action-area button-strip"> - <button id="stop-syncing-cancel" i18n-content="cancel"> - <button id="stop-syncing-ok" class="default-button" - i18n-content="stopSyncingConfirm"> - </div> - </div> -</div>
diff --git a/chrome/browser/resources/options/sync_setup_overlay.js b/chrome/browser/resources/options/sync_setup_overlay.js deleted file mode 100644 index 12dc97d0..0000000 --- a/chrome/browser/resources/options/sync_setup_overlay.js +++ /dev/null
@@ -1,833 +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. - -cr.exportPath('options'); - -/** @typedef {{appsEnforced: boolean, - * appsRegistered: boolean, - * appsSynced: boolean, - * autofillEnforced: boolean, - * autofillRegistered: boolean, - * autofillSynced: boolean, - * bookmarksEnforced: boolean, - * bookmarksRegistered: boolean, - * bookmarksSynced: boolean, - * encryptAllData: boolean, - * encryptAllDataAllowed: boolean, - * enterGooglePassphraseBody: (string|undefined), - * enterPassphraseBody: (string|undefined), - * extensionsEnforced: boolean, - * extensionsRegistered: boolean, - * extensionsSynced: boolean, - * fullEncryptionBody: string, - * passphraseFailed: boolean, - * passwordsEnforced: boolean, - * passwordsRegistered: boolean, - * passwordsSynced: boolean, - * paymentsIntegrationEnabled: boolean, - * preferencesEnforced: boolean, - * preferencesRegistered: boolean, - * preferencesSynced: boolean, - * showPassphrase: boolean, - * syncAllDataTypes: boolean, - * tabsEnforced: boolean, - * tabsRegistered: boolean, - * tabsSynced: boolean, - * themesEnforced: boolean, - * themesRegistered: boolean, - * themesSynced: boolean, - * typedUrlsEnforced: boolean, - * typedUrlsRegistered: boolean, - * typedUrlsSynced: boolean, - * usePassphrase: boolean}} - */ -var SyncConfig; - -/** - * The user's selection in the synced data type drop-down menu, as an index. - * @enum {number} - * @const - */ -options.DataTypeSelection = { - SYNC_EVERYTHING: 0, - CHOOSE_WHAT_TO_SYNC: 1, -}; - -cr.define('options', function() { - /** @const */ var Page = cr.ui.pageManager.Page; - /** @const */ var PageManager = cr.ui.pageManager.PageManager; - - /** - * SyncSetupOverlay class - * Encapsulated handling of the 'Sync Setup' overlay page. - * @class - */ - function SyncSetupOverlay() { - Page.call(this, 'syncSetup', - loadTimeData.getString('syncSetupOverlayTabTitle'), - 'sync-setup-overlay'); - } - - cr.addSingletonGetter(SyncSetupOverlay); - - SyncSetupOverlay.prototype = { - __proto__: Page.prototype, - - /** - * True if the synced account uses a custom passphrase. - * @private {boolean} - */ - usePassphrase_: false, - - /** - * True if the synced account uses 'encrypt everything'. - * @private {boolean} - */ - useEncryptEverything_: false, - - /** - * An object used as a cache of the arguments passed in while initially - * displaying the advanced sync settings dialog. Used to switch between the - * options in the main drop-down menu. Reset when the dialog is closed. - * @private {?SyncConfig} - */ - syncConfigureArgs_: null, - - /** - * A dictionary that maps the sync data type checkbox names to their checked - * state. Initialized when the advanced settings dialog is first brought up, - * updated any time a box is checked / unchecked, and reset when the dialog - * is closed. Used to restore checkbox state while switching between the - * options in the main drop-down menu. All checkboxes are checked and - * disabled when the "Sync everything" menu-item is selected, and unchecked - * and disabled when "Sync nothing" is selected. When "Choose what to sync" - * is selected, the boxes are restored to their most recent checked state - * from this cache. - * @private {Object} - */ - dataTypeBoxesChecked_: {}, - - /** - * A dictionary that maps the sync data type checkbox names to their - * disabled state (when a data type is enabled programmatically without user - * choice). Initialized when the advanced settings dialog is first brought - * up, and reset when the dialog is closed. - * @private {Object} - */ - dataTypeBoxesDisabled_: {}, - - /** @override */ - initializePage: function() { - Page.prototype.initializePage.call(this); - - var self = this; - - // If 'profilesInfo' doesn't exist, it's forbidden to delete profile. - // So don't display the delete-profile checkbox. - if (!loadTimeData.valueExists('profilesInfo') && - $('sync-setup-delete-profile')) { - $('sync-setup-delete-profile').hidden = true; - } - - $('basic-encryption-option').onchange = - $('full-encryption-option').onchange = function() { - self.onEncryptionRadioChanged_(); - }; - $('choose-datatypes-cancel').onclick = - $('confirm-everything-cancel').onclick = - $('stop-syncing-cancel').onclick = - $('sync-spinner-cancel').onclick = function() { - self.closeOverlay_(); - }; - $('activity-controls').onclick = function() { - chrome.metricsPrivate.recordUserAction( - 'Signin_AccountSettings_GoogleActivityControlsClicked'); - }; - $('confirm-everything-ok').onclick = function() { - self.sendConfiguration_(); - }; - $('timeout-ok').onclick = function() { - chrome.send('CloseTimeout'); - self.closeOverlay_(); - }; - $('stop-syncing-ok').onclick = function() { - var deleteProfile = $('delete-profile') != undefined && - $('delete-profile').checked; - chrome.send('SyncSetupStopSyncing', [deleteProfile]); - self.closeOverlay_(); - }; - $('use-default-link').onclick = function() { - self.showSyncEverythingPage_(); - }; - $('autofill-checkbox').onclick = function() { - var autofillSyncEnabled = $('autofill-checkbox').checked; - $('payments-integration-checkbox').checked = autofillSyncEnabled; - $('payments-integration-checkbox').disabled = !autofillSyncEnabled; - }; - }, - - /** @private */ - showOverlay_: function() { - PageManager.showPageByName('syncSetup'); - }, - - /** @private */ - closeOverlay_: function() { - this.syncConfigureArgs_ = null; - this.dataTypeBoxesChecked_ = {}; - this.dataTypeBoxesDisabled_ = {}; - - var overlay = $('sync-setup-overlay'); - if (!overlay.hidden) - PageManager.closeOverlay(); - }, - - /** @override */ - didShowPage: function() { - chrome.send('SyncSetupShowSetupUI'); - }, - - /** @override */ - didClosePage: function() { - chrome.send('SyncSetupDidClosePage'); - }, - - /** @private */ - onEncryptionRadioChanged_: function() { - var visible = $('full-encryption-option').checked; - // TODO(dbeam): should sync-custom-passphrase-container be hidden instead? - $('sync-custom-passphrase').hidden = !visible; - chrome.send('coreOptionsUserMetricsAction', - ['Options_SyncSetEncryption']); - }, - - /** - * Sets the checked state of the individual sync data type checkboxes in the - * advanced sync settings dialog. - * @param {boolean} value True for checked, false for unchecked. - * @private - */ - checkAllDataTypeCheckboxes_: function(value) { - // Only check / uncheck the visible ones (since there's no way to uncheck - // / check the invisible ones). - var checkboxes = $('choose-data-types-body').querySelectorAll( - '.sync-type-checkbox:not([hidden]) input'); - for (var i = 0; i < checkboxes.length; i++) { - checkboxes[i].checked = value; - } - $('payments-integration-checkbox').checked = value; - }, - - /** - * Restores the checked states of the sync data type checkboxes in the - * advanced sync settings dialog. Called when "Choose what to sync" is - * selected. Required because all the checkboxes are checked when - * "Sync everything" is selected, and unchecked when "Sync nothing" is - * selected. Note: We only restore checkboxes for data types that are - * actually visible and whose old values are found in the cache, since it's - * possible for some data types to not be registered, and therefore, their - * checkboxes remain hidden, and never get cached. - * @private - */ - restoreDataTypeCheckboxes_: function() { - for (var dataType in this.dataTypeBoxesChecked_) { - $(dataType).checked = this.dataTypeBoxesChecked_[dataType]; - } - }, - - /** - * Enables / grays out the sync data type checkboxes in the advanced - * settings dialog. - * @param {boolean} enabled True for enabled, false for grayed out. - * @private - */ - setDataTypeCheckboxesEnabled_: function(enabled) { - for (var dataType in this.dataTypeBoxesDisabled_) { - $(dataType).disabled = - !enabled || this.dataTypeBoxesDisabled_[dataType]; - } - }, - - /** - * Sets the state of the sync data type checkboxes based on whether "Sync - * everything", "Choose what to sync", or "Sync nothing" are selected in the - * drop-down menu of the advanced settings dialog. - * @param {options.DataTypeSelection} selectedIndex Index of user's - * selection. - * @private - */ - setDataTypeCheckboxes_: function(selectedIndex) { - if (selectedIndex == options.DataTypeSelection.CHOOSE_WHAT_TO_SYNC) { - this.setDataTypeCheckboxesEnabled_(true); - this.restoreDataTypeCheckboxes_(); - } else { - this.setDataTypeCheckboxesEnabled_(false); - this.checkAllDataTypeCheckboxes_( - selectedIndex == options.DataTypeSelection.SYNC_EVERYTHING); - } - }, - - /** @private */ - checkPassphraseMatch_: function() { - var emptyError = $('empty-error'); - var mismatchError = $('mismatch-error'); - emptyError.hidden = true; - mismatchError.hidden = true; - - if (!$('full-encryption-option').checked || - $('basic-encryption-option').disabled) { - return true; - } - - var customPassphrase = $('custom-passphrase'); - if (customPassphrase.value.length == 0) { - emptyError.hidden = false; - return false; - } - - var confirmPassphrase = $('confirm-passphrase'); - if (confirmPassphrase.value != customPassphrase.value) { - mismatchError.hidden = false; - return false; - } - - return true; - }, - - /** @private */ - sendConfiguration_: function() { - var encryptAllData = $('full-encryption-option').checked; - - var usePassphrase; - var customPassphrase; - var googlePassphrase = false; - if (!$('sync-existing-passphrase-container').hidden) { - // If we were prompted for an existing passphrase, use it. - customPassphrase = getRequiredElement('passphrase').value; - usePassphrase = true; - // If we were displaying the 'enter your old google password' prompt, - // then that means this is the user's google password. - googlePassphrase = !$('google-passphrase-needed-body').hidden; - // We allow an empty passphrase, in case the user has disabled - // all their encrypted datatypes. In that case, the PSS will accept - // the passphrase and finish configuration. If the user has enabled - // encrypted datatypes, the PSS will prompt again specifying that the - // passphrase failed. - } else if (!$('basic-encryption-option').disabled && - $('full-encryption-option').checked) { - // The user is setting a custom passphrase for the first time. - if (!this.checkPassphraseMatch_()) - return; - customPassphrase = $('custom-passphrase').value; - usePassphrase = true; - } else { - // The user is not setting a custom passphrase. - usePassphrase = false; - } - - // Don't allow the user to tweak the settings once we send the - // configuration to the backend. - this.setInputElementsDisabledState_(true); - $('use-default-link').hidden = true; - - // These values need to be kept in sync with where they are read in - // sync_setup_handler.cc:GetConfiguration(). - var syncAll = $('sync-select-datatypes').selectedIndex == - options.DataTypeSelection.SYNC_EVERYTHING; - var autofillSynced = syncAll || $('autofill-checkbox').checked; - var result = JSON.stringify({ - 'syncAllDataTypes': syncAll, - 'bookmarksSynced': syncAll || $('bookmarks-checkbox').checked, - 'preferencesSynced': syncAll || $('preferences-checkbox').checked, - 'themesSynced': syncAll || $('themes-checkbox').checked, - 'passwordsSynced': syncAll || $('passwords-checkbox').checked, - 'autofillSynced': autofillSynced, - 'extensionsSynced': syncAll || $('extensions-checkbox').checked, - 'typedUrlsSynced': syncAll || $('typed-urls-checkbox').checked, - 'appsSynced': syncAll || $('apps-checkbox').checked, - 'tabsSynced': syncAll || $('tabs-checkbox').checked, - 'paymentsIntegrationEnabled': syncAll || - (autofillSynced && $('payments-integration-checkbox').checked), - 'encryptAllData': encryptAllData, - 'usePassphrase': usePassphrase, - 'isGooglePassphrase': googlePassphrase, - 'passphrase': customPassphrase - }); - chrome.send('SyncSetupConfigure', [result]); - }, - - /** - * Sets the disabled property of all input elements within the 'Customize - * Sync Preferences' screen. This is used to prohibit the user from changing - * the inputs after confirming the customized sync preferences, or resetting - * the state when re-showing the dialog. - * @param {boolean} disabled True if controls should be set to disabled. - * @private - */ - setInputElementsDisabledState_: function(disabled) { - var self = this; - var configureElements = - $('customize-sync-preferences').querySelectorAll('input'); - for (var i = 0; i < configureElements.length; i++) - configureElements[i].disabled = disabled; - $('sync-select-datatypes').disabled = disabled; - $('payments-integration-checkbox').disabled = disabled; - - $('customize-link').hidden = disabled; - $('customize-link').disabled = disabled; - $('customize-link').onclick = disabled ? null : function() { - SyncSetupOverlay.showCustomizePage(self.syncConfigureArgs_, - options.DataTypeSelection.SYNC_EVERYTHING); - return false; - }; - }, - - /** - * Shows or hides the sync data type checkboxes in the advanced sync - * settings dialog. Also initializes |this.dataTypeBoxesChecked_| and - * |this.dataTypeBoxedDisabled_| with their values, and makes their onclick - * handlers update |this.dataTypeBoxesChecked_|. - * @param {SyncConfig} args The configuration data used to show/hide UI. - * @private - */ - setChooseDataTypesCheckboxes_: function(args) { - var datatypeSelect = $('sync-select-datatypes'); - datatypeSelect.selectedIndex = args.syncAllDataTypes ? - options.DataTypeSelection.SYNC_EVERYTHING : - options.DataTypeSelection.CHOOSE_WHAT_TO_SYNC; - - $('bookmarks-checkbox').checked = args.bookmarksSynced; - this.dataTypeBoxesChecked_['bookmarks-checkbox'] = args.bookmarksSynced; - this.dataTypeBoxesDisabled_['bookmarks-checkbox'] = - args.bookmarksEnforced; - - $('preferences-checkbox').checked = args.preferencesSynced; - this.dataTypeBoxesChecked_['preferences-checkbox'] = - args.preferencesSynced; - this.dataTypeBoxesDisabled_['preferences-checkbox'] = - args.preferencesEnforced; - - $('themes-checkbox').checked = args.themesSynced; - this.dataTypeBoxesChecked_['themes-checkbox'] = args.themesSynced; - this.dataTypeBoxesDisabled_['themes-checkbox'] = args.themesEnforced; - - if (args.passwordsRegistered) { - $('passwords-checkbox').checked = args.passwordsSynced; - this.dataTypeBoxesChecked_['passwords-checkbox'] = args.passwordsSynced; - this.dataTypeBoxesDisabled_['passwords-checkbox'] = - args.passwordsEnforced; - $('passwords-item').hidden = false; - } else { - $('passwords-item').hidden = true; - } - if (args.autofillRegistered) { - $('autofill-checkbox').checked = args.autofillSynced; - this.dataTypeBoxesChecked_['autofill-checkbox'] = args.autofillSynced; - this.dataTypeBoxesDisabled_['autofill-checkbox'] = - args.autofillEnforced; - this.dataTypeBoxesChecked_['payments-integration-checkbox'] = - args.autofillSynced && args.paymentsIntegrationEnabled; - this.dataTypeBoxesDisabled_['payments-integration-checkbox'] = - !args.autofillSynced; - $('autofill-item').hidden = false; - $('payments-integration-setting-area').hidden = false; - } else { - $('autofill-item').hidden = true; - $('payments-integration-setting-area').hidden = true; - } - if (args.extensionsRegistered) { - $('extensions-checkbox').checked = args.extensionsSynced; - this.dataTypeBoxesChecked_['extensions-checkbox'] = - args.extensionsSynced; - this.dataTypeBoxesDisabled_['extensions-checkbox'] = - args.extensionsEnforced; - $('extensions-item').hidden = false; - } else { - $('extensions-item').hidden = true; - } - if (args.typedUrlsRegistered) { - $('typed-urls-checkbox').checked = args.typedUrlsSynced; - this.dataTypeBoxesChecked_['typed-urls-checkbox'] = - args.typedUrlsSynced; - this.dataTypeBoxesDisabled_['typed-urls-checkbox'] = - args.typedUrlsEnforced; - $('omnibox-item').hidden = false; - } else { - $('omnibox-item').hidden = true; - } - if (args.appsRegistered) { - $('apps-checkbox').checked = args.appsSynced; - this.dataTypeBoxesChecked_['apps-checkbox'] = args.appsSynced; - this.dataTypeBoxesDisabled_['apps-checkbox'] = args.appsEnforced; - $('apps-item').hidden = false; - } else { - $('apps-item').hidden = true; - } - if (args.tabsRegistered) { - $('tabs-checkbox').checked = args.tabsSynced; - this.dataTypeBoxesChecked_['tabs-checkbox'] = args.tabsSynced; - this.dataTypeBoxesDisabled_['tabs-checkbox'] = args.tabsEnforced; - $('tabs-item').hidden = false; - } else { - $('tabs-item').hidden = true; - } - - $('choose-data-types-body').onchange = - this.handleDataTypeChange_.bind(this); - - this.setDataTypeCheckboxes_(datatypeSelect.selectedIndex); - }, - - /** - * Updates the cached values of the sync data type checkboxes stored in - * |this.dataTypeBoxesChecked_|. Used as an onclick handler for each data - * type checkbox. - * @param {Event} e The change event. - * @private - */ - handleDataTypeChange_: function(e) { - var input = assertInstanceof(e.target, HTMLInputElement); - assert(input.type == 'checkbox'); - this.dataTypeBoxesChecked_[input.id] = input.checked; - chrome.send('coreOptionsUserMetricsAction', - ['Options_SyncToggleDataType']); - }, - - /** - * @param {SyncConfig} args - * @private - */ - setEncryptionRadios_: function(args) { - if (!args.encryptAllData && !args.usePassphrase) { - $('basic-encryption-option').checked = true; - } else { - $('full-encryption-option').checked = true; - $('full-encryption-option').disabled = true; - $('basic-encryption-option').disabled = true; - } - }, - - /** - * @param {SyncConfig} args - * @private - */ - setCheckboxesAndErrors_: function(args) { - this.setChooseDataTypesCheckboxes_(args); - this.setEncryptionRadios_(args); - }, - - /** - * @param {SyncConfig} args - * @private - */ - showConfigure_: function(args) { - var datatypeSelect = $('sync-select-datatypes'); - var self = this; - - // Cache the sync config args so they can be reused when we transition - // between the drop-down menu items in the advanced settings dialog. - if (args) - this.syncConfigureArgs_ = args; - - // Once the advanced sync settings dialog is visible, we transition - // between its drop-down menu items as follows: - // "Sync everything": Show encryption and passphrase sections, and disable - // and check all data type checkboxes. - // "Choose what to sync": Show encryption and passphrase sections, enable - // data type checkboxes, and restore their checked state to the last time - // the "Choose what to sync" was selected while the dialog was still up. - datatypeSelect.onchange = function() { - self.showCustomizePage_(self.syncConfigureArgs_, this.selectedIndex); - if (this.selectedIndex == options.DataTypeSelection.SYNC_EVERYTHING) { - self.checkAllDataTypeCheckboxes_(true); - } else { - self.restoreDataTypeCheckboxes_(); - } - }; - - this.resetPage_('sync-setup-configure'); - $('sync-setup-configure').hidden = false; - - // onsubmit is changed when submitting a passphrase. Reset it to its - // default. - $('choose-data-types-form').onsubmit = function() { - self.sendConfiguration_(); - return false; - }; - - if (args) { - this.setCheckboxesAndErrors_(args); - - this.useEncryptEverything_ = args.encryptAllData; - - // Determine whether to display the 'OK, sync everything' confirmation - // dialog or the advanced sync settings dialog, and assign focus to the - // OK button, or to the passphrase field if a passphrase is required. - this.usePassphrase_ = args.usePassphrase; - var index = args.syncAllDataTypes ? - options.DataTypeSelection.SYNC_EVERYTHING : - options.DataTypeSelection.CHOOSE_WHAT_TO_SYNC; - this.showCustomizePage_(args, index); - } - }, - - /** @private */ - showSpinner_: function() { - this.resetPage_('sync-setup-spinner'); - $('sync-setup-spinner').hidden = false; - }, - - /** @private */ - showTimeoutPage_: function() { - this.resetPage_('sync-setup-timeout'); - $('sync-setup-timeout').hidden = false; - }, - - /** @private */ - showSyncEverythingPage_: function() { - chrome.send('coreOptionsUserMetricsAction', - ['Options_SyncSetDefault']); - - $('confirm-sync-preferences').hidden = false; - $('customize-sync-preferences').hidden = true; - - // Reset the selection to 'Sync everything'. - $('sync-select-datatypes').selectedIndex = 0; - - // The default state is to sync everything. - this.setDataTypeCheckboxes_(options.DataTypeSelection.SYNC_EVERYTHING); - - // TODO(dbeam): should hide sync-custom-passphrase-container instead? - if (!this.usePassphrase_) - $('sync-custom-passphrase').hidden = true; - - if (!this.useEncryptEverything_ && !this.usePassphrase_) - $('basic-encryption-option').checked = true; - }, - - /** - * Reveals the UI for entering a custom passphrase during initial setup. - * This happens if the user has previously enabled a custom passphrase on a - * different machine. - * @param {SyncConfig} args The args that contain the passphrase UI - * configuration. - * @private - */ - showPassphraseContainer_: function(args) { - // Once we require a passphrase, we prevent the user from returning to - // the Sync Everything pane. - $('use-default-link').hidden = true; - $('sync-custom-passphrase-container').hidden = true; - $('sync-existing-passphrase-container').hidden = false; - - // Hide the selection options within the new encryption section when - // prompting for a passphrase. - $('sync-new-encryption-section-container').hidden = true; - - $('normal-body').hidden = true; - $('google-passphrase-needed-body').hidden = true; - // Display the correct prompt to the user depending on what type of - // passphrase is needed. - if (args.usePassphrase) - $('normal-body').hidden = false; - else - $('google-passphrase-needed-body').hidden = false; - - $('passphrase-learn-more').hidden = false; - // Warn the user about their incorrect passphrase if we need a passphrase - // and the passphrase field is non-empty (meaning they tried to set it - // previously but failed). - $('incorrect-passphrase').hidden = - !(args.usePassphrase && args.passphraseFailed); - - $('sync-passphrase-warning').hidden = false; - }, - - /** - * Displays the advanced sync setting dialog, and pre-selects either the - * "Sync everything" or the "Choose what to sync" drop-down menu item. - * @param {SyncConfig} args - * @param {options.DataTypeSelection} index Index of item to pre-select. - * @private - */ - showCustomizePage_: function(args, index) { - $('confirm-sync-preferences').hidden = true; - $('customize-sync-preferences').hidden = false; - - $('sync-custom-passphrase-container').hidden = false; - $('sync-new-encryption-section-container').hidden = false; - $('customize-sync-encryption-new').hidden = !args.encryptAllDataAllowed; - $('personalize-google-services').hidden = false; - - $('sync-existing-passphrase-container').hidden = true; - - $('sync-select-datatypes').selectedIndex = index; - this.setDataTypeCheckboxesEnabled_( - index == options.DataTypeSelection.CHOOSE_WHAT_TO_SYNC); - - if (args.showPassphrase) { - this.showPassphraseContainer_(args); - // TODO(dbeam): add an #updatePassphrase and only focus with that hash? - $('passphrase').focus(); - } else { - // We only show the 'Use Default' link if we're not prompting for an - // existing passphrase. - $('use-default-link').hidden = false; - } - }, - - /** - * Shows the appropriate sync setup page. - * @param {string} page A page of the sync setup to show. - * @param {SyncConfig} args Data from the C++ to forward on to the right - * section. - */ - showSyncSetupPage_: function(page, args) { - // If the user clicks the OK button, dismiss the dialog immediately, and - // do not go through the process of hiding elements of the overlay. - // See crbug.com/308873. - if (page == 'done') { - this.closeOverlay_(); - return; - } - - this.setThrobbersVisible_(false); - - // Hide an existing visible overlay (ensuring the close button is not - // hidden). - var children = document.querySelectorAll( - '#sync-setup-overlay > *:not(.close-button)'); - for (var i = 0; i < children.length; i++) - children[i].hidden = true; - - this.setInputElementsDisabledState_(false); - - // If new passphrase bodies are present, overwrite the existing ones. - if (args && args.enterPassphraseBody != undefined) - $('normal-body').innerHTML = args.enterPassphraseBody; - if (args && args.enterGooglePassphraseBody != undefined) { - $('google-passphrase-needed-body').innerHTML = - args.enterGooglePassphraseBody; - } - if (args && args.fullEncryptionBody != undefined) - $('full-encryption-body').innerHTML = args.fullEncryptionBody; - - // NOTE: Because both showGaiaLogin_() and showConfigure_() change the - // focus, we need to ensure that the overlay container and dialog aren't - // [hidden] (as trying to focus() nodes inside of a [hidden] DOM section - // doesn't work). - this.showOverlay_(); - - if (page == 'configure' || page == 'passphrase') - this.showConfigure_(args); - else if (page == 'spinner') - this.showSpinner_(); - else if (page == 'timeout') - this.showTimeoutPage_(); - }, - - /** - * Changes the visibility of throbbers on this page. - * @param {boolean} visible Whether or not to set all throbber nodes - * visible. - */ - setThrobbersVisible_: function(visible) { - var throbbers = this.pageDiv.getElementsByClassName('throbber'); - for (var i = 0; i < throbbers.length; i++) - throbbers[i].style.visibility = visible ? 'visible' : 'hidden'; - }, - - /** - * Reset the state of all descendant elements of a root element to their - * initial state. - * The initial state is specified by adding a class to the descendant - * element in sync_setup_overlay.html. - * @param {string} pageElementId The root page element id. - * @private - */ - resetPage_: function(pageElementId) { - var page = $(pageElementId); - var forEach = function(arr, fn) { - var length = arr.length; - for (var i = 0; i < length; i++) { - fn(arr[i]); - } - }; - - forEach(page.getElementsByClassName('reset-hidden'), - function(elt) { elt.hidden = true; }); - forEach(page.getElementsByClassName('reset-shown'), - function(elt) { elt.hidden = false; }); - forEach(page.getElementsByClassName('reset-disabled'), - function(elt) { elt.disabled = true; }); - forEach(page.getElementsByClassName('reset-enabled'), - function(elt) { elt.disabled = false; }); - forEach(page.getElementsByClassName('reset-value'), - function(elt) { elt.value = ''; }); - forEach(page.getElementsByClassName('reset-opaque'), - function(elt) { elt.classList.remove('transparent'); }); - }, - - /** - * Displays the stop syncing dialog. - * @private - */ - showStopSyncingUI_: function() { - // Hide any visible children of the overlay. - var overlay = $('sync-setup-overlay'); - for (var i = 0; i < overlay.children.length; i++) - overlay.children[i].hidden = true; - - // Bypass PageManager.showPageByName because it will call didShowPage - // which will set its own visible page, based on the flow state. - this.visible = true; - - $('sync-setup-stop-syncing').hidden = false; - }, - - /** - * Determines the appropriate page to show in the Sync Setup UI based on - * the state of the Sync backend. Does nothing if the user is not signed in. - * @private - */ - showSetupUI_: function() { - chrome.send('SyncSetupShowSetupUI'); - chrome.send('coreOptionsUserMetricsAction', ['Options_ShowSyncAdvanced']); - }, - - /** - * Starts the signin process for the user. Does nothing if the user is - * already signed in. - * @param {boolean} creatingSupervisedUser - * @private - */ - startSignIn_: function(creatingSupervisedUser) { - chrome.send('SyncSetupStartSignIn', [creatingSupervisedUser]); - }, - - /** - * Forces user to sign out of Chrome for Chrome OS. - * @private - */ - doSignOutOnAuthError_: function() { - chrome.send('AttemptUserExit'); - }, - }; - - // Forward public APIs to private implementations. - cr.makePublic(SyncSetupOverlay, [ - 'closeOverlay', - 'showSetupUI', - 'startSignIn', - 'doSignOutOnAuthError', - 'showSyncSetupPage', - 'showCustomizePage', - 'showStopSyncingUI', - ]); - - // Export - return { - SyncSetupOverlay: SyncSetupOverlay - }; -});
diff --git a/chrome/browser/resources/options/yellow_gear.png b/chrome/browser/resources/options/yellow_gear.png deleted file mode 100644 index 4134d3d..0000000 --- a/chrome/browser/resources/options/yellow_gear.png +++ /dev/null Binary files differ
diff --git a/chrome/browser/resources/options_resources.grd b/chrome/browser/resources/options_resources.grd deleted file mode 100644 index 4ddc0f1..0000000 --- a/chrome/browser/resources/options_resources.grd +++ /dev/null
@@ -1,163 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<grit latest_public_release="0" current_release="1" output_all_resource_defines="false"> - <outputs> - <output filename="grit/options_resources.h" type="rc_header"> - <emit emit_type='prepend'></emit> - </output> - <output filename="options_resources.pak" type="data_package" /> - </outputs> - <release seq="1"> - <structures> - <structure name="IDR_OPTIONS_BUNDLE_JS" - file="options/options_bundle.js" - flattenhtml="true" - type="chrome_html" /> - <structure name="IDR_OPTIONS_HTML" - file="options/options.html" - flattenhtml="true" - allowexternalscript="true" - type="chrome_html" /> - <if expr="chromeos"> - <structure name="IDR_OPTIONS_ICONS_HTML" - file="settings/icons.html" - type="chrome_html" - preprocess="true" /> - <structure name="IDR_OPTIONS_PIN_KEYBOARD_HTML" - file="chromeos/quick_unlock/pin_keyboard.html" - type="chrome_html" - preprocess="true" /> - <structure name="IDR_OPTIONS_PIN_KEYBOARD_JS" - file="chromeos/quick_unlock/pin_keyboard.js" - type="chrome_html" - preprocess="true" /> - <structure name="IDR_OPTIONS_PASSWORD_PROMPT_DIALOG_JS" - file="settings/people_page/password_prompt_dialog.js" - type="chrome_html" /> - <structure name="IDR_OPTIONS_PASSWORD_PROMPT_DIALOG_HTML" - file="settings/people_page/password_prompt_dialog.html" - type="chrome_html" /> - <structure name="IDR_OPTIONS_LOCK_SCREEN_CONSTANTS_JS" - file="settings/people_page/lock_screen_constants.js" - type="chrome_html" /> - <structure name="IDR_OPTIONS_LOCK_SCREEN_CONSTANTS_HTML" - file="settings/people_page/lock_screen_constants.html" - type="chrome_html" /> - <structure name="IDR_OPTIONS_LOCK_STATE_BEHAVIOR_JS" - file="settings/people_page/lock_state_behavior.js" - type="chrome_html" /> - <structure name="IDR_OPTIONS_LOCK_STATE_BEHAVIOR_HTML" - file="settings/people_page/lock_state_behavior.html" - type="chrome_html" /> - <structure name="IDR_OPTIONS_SETUP_PIN_DIALOG_JS" - file="settings/people_page/setup_pin_dialog.js" - type="chrome_html" /> - <structure name="IDR_OPTIONS_SETUP_PIN_DIALOG_HTML" - file="settings/people_page/setup_pin_dialog.html" - type="chrome_html" /> - <structure name="IDR_OPTIONS_EASY_UNLOCK_BROWSER_PROXY_JS" - file="settings/people_page/easy_unlock_browser_proxy.js" - type="chrome_html" /> - <structure name="IDR_OPTIONS_EASY_UNLOCK_BROWSER_PROXY_HTML" - file="settings/people_page/easy_unlock_browser_proxy.html" - type="chrome_html" /> - <structure name="IDR_OPTIONS_EASY_UNLOCK_TURN_OFF_DIALOG_JS" - file="settings/people_page/easy_unlock_turn_off_dialog.js" - type="chrome_html" /> - <structure name="IDR_OPTIONS_EASY_UNLOCK_TURN_OFF_DIALOG_HTML" - file="settings/people_page/easy_unlock_turn_off_dialog.html" - type="chrome_html" /> - <structure name="IDR_OPTIONS_FINGERPRINT_LIST_JS" - file="settings/people_page/fingerprint_list.js" - type="chrome_html" /> - <structure name="IDR_OPTIONS_FINGERPRINT_LIST_HTML" - file="settings/people_page/fingerprint_list.html" - type="chrome_html" /> - <structure name="IDR_OPTIONS_SETUP_FINGERPRINT_DIALOG_JS" - file="settings/people_page/setup_fingerprint_dialog.js" - type="chrome_html" /> - <structure name="IDR_OPTIONS_SETUP_FINGERPRINT_DIALOG_HTML" - file="settings/people_page/setup_fingerprint_dialog.html" - type="chrome_html" /> - <structure name="IDR_OPTIONS_FINGERPRINT_PROGRESS_ARC_JS" - file="settings/people_page/fingerprint_progress_arc.js" - type="chrome_html" /> - <structure name="IDR_OPTIONS_FINGERPRINT_PROGRESS_ARC_HTML" - file="settings/people_page/fingerprint_progress_arc.html" - type="chrome_html" /> - <structure name="IDR_OPTIONS_FINGERPRINT_BROWSER_PROXY_JS" - file="settings/people_page/fingerprint_browser_proxy.js" - type="chrome_html" /> - <structure name="IDR_OPTIONS_FINGERPRINT_BROWSER_PROXY_HTML" - file="settings/people_page/fingerprint_browser_proxy.html" - type="chrome_html" /> - <structure name="IDR_OPTIONS_LOCK_SCREEN_JS" - file="settings/people_page/lock_screen.js" - type="chrome_html" /> - <structure name="IDR_OPTIONS_LOCK_SCREEN_HTML" - file="settings/people_page/lock_screen.html" - type="chrome_html" /> - <structure name="IDR_OPTIONS_ROUTE_HTML" - file="settings/route.html" - type="chrome_html" /> - <structure name="IDR_OPTIONS_ROUTE_JS" - file="settings/route.js" - type="chrome_html" - preprocess="true" /> - <structure name="IDR_SETTINGS_SHARED_CSS_HTML" - file="settings/settings_shared_css.html" - type="chrome_html" /> - <structure name="IDR_SETTINGS_SLIDER_HTML" - file="settings/controls/settings_slider.html" - type="chrome_html" /> - <structure name="IDR_SETTINGS_SLIDER_JS" - file="settings/controls/settings_slider.js" - type="chrome_html" /> - <structure name="IDR_SETTINGS_TOGGLE_BUTTON_HTML" - file="settings/controls/settings_toggle_button.html" - type="chrome_html" /> - <structure name="IDR_SETTINGS_TOGGLE_BUTTON_JS" - file="settings/controls/settings_toggle_button.js" - type="chrome_html" /> - <structure name="IDR_SETTINGS_BOOLEAN_CONTROL_BEHAVIOR_HTML" - file="settings/controls/settings_boolean_control_behavior.html" - type="chrome_html" /> - <structure name="IDR_SETTINGS_BOOLEAN_CONTROL_BEHAVIOR_JS" - file="settings/controls/settings_boolean_control_behavior.js" - type="chrome_html" /> - <structure name="IDR_SETTINGS_PREF_CONTROL_BEHAVIOR_HTML" - file="settings/controls/pref_control_behavior.html" - type="chrome_html" /> - <structure name="IDR_SETTINGS_PREF_CONTROL_BEHAVIOR_JS" - file="settings/controls/pref_control_behavior.js" - type="chrome_html" /> - <structure name="IDR_SETTINGS_VARS_CSS_HTML" - file="settings/settings_vars_css.html" - type="chrome_html" /> - <structure name="IDR_SETTINGS_PREFS_BEHAVIOR_HTML" - file="settings/prefs/prefs_behavior.html" - type="chrome_html" /> - <structure name="IDR_SETTINGS_PREFS_BEHAVIOR_JS" - file="settings/prefs/prefs_behavior.js" - type="chrome_html" /> - <structure name="IDR_SETTINGS_PREFS_TYPES_HTML" - file="settings/prefs/prefs_types.html" - type="chrome_html" /> - <structure name="IDR_SETTINGS_PREFS_TYPES_JS" - file="settings/prefs/prefs_types.js" - type="chrome_html" /> - <structure name="IDR_SETTINGS_PREFS_HTML" - file="settings/prefs/prefs.html" - type="chrome_html" /> - <structure name="IDR_SETTINGS_PREFS_JS" - file="settings/prefs/prefs.js" - type="chrome_html" /> - <structure name="IDR_OPTIONS_I18N_SETUP_HTML" - file="options/i18n_setup.html" - type="chrome_html" /> - <structure name="IDR_OPTIONS_POLYMER_ELEMENTS_HTML" - file="options/options_polymer.html" - type="chrome_html" /> - </if> - </structures> - </release> -</grit>
diff --git a/chrome/browser/resources/settings/internet_page/internet_detail_page.html b/chrome/browser/resources/settings/internet_page/internet_detail_page.html index efb5ce22..34a54103 100644 --- a/chrome/browser/resources/settings/internet_page/internet_detail_page.html +++ b/chrome/browser/resources/settings/internet_page/internet_detail_page.html
@@ -66,7 +66,7 @@ } </style> <!-- Title section: Icon + name + connection state. --> - <div class="settings-box first"> + <div id="titleDiv" class="settings-box first"> <div class="start layout horizontal center"> <cr-network-icon network-state="[[networkProperties]]"> </cr-network-icon>
diff --git a/chrome/browser/resources/settings/internet_page/internet_detail_page.js b/chrome/browser/resources/settings/internet_page/internet_detail_page.js index ceb9eb7..ff5e1b8 100644 --- a/chrome/browser/resources/settings/internet_page/internet_detail_page.js +++ b/chrome/browser/resources/settings/internet_page/internet_detail_page.js
@@ -226,12 +226,12 @@ Polymer.dom.flush(); - if (this.didSetFocus_) { + if (!this.didSetFocus_) { // Focus a button once the initial state is set. this.didSetFocus_ = true; - var button = this.$$('#buttonDiv .primary-button:not([hidden])'); + var button = this.$$('#titleDiv .primary-button:not([hidden])'); if (!button) - button = this.$$('#buttonDiv .secondary-button:not([hidden])'); + button = this.$$('#titleDiv paper-button:not([hidden])'); assert(button); // At least one button will always be visible. button.focus(); } @@ -459,7 +459,8 @@ var type = networkProperties.Type; if (type != CrOnc.Type.WI_FI && type != CrOnc.Type.VPN) return false; - return this.isRemembered_(networkProperties); + return !this.isPolicySource(networkProperties.Source) && + this.isRemembered_(networkProperties); }, /**
diff --git a/chrome/browser/resources/settings/internet_page/internet_known_networks_page.html b/chrome/browser/resources/settings/internet_page/internet_known_networks_page.html index 79383a2..6d2f1357 100644 --- a/chrome/browser/resources/settings/internet_page/internet_known_networks_page.html +++ b/chrome/browser/resources/settings/internet_page/internet_known_networks_page.html
@@ -8,7 +8,11 @@ <dom-module id="settings-internet-known-networks-page"> <template> - <style include="settings-shared"></style> + <style include="internet-shared"> + cr-policy-indicator { + -webkit-margin-start: var(--settings-controlled-by-spacing); + } + </style> <div class="settings-box first"> <div>$i18n{knownNetworksMessage}</div> @@ -26,6 +30,11 @@ filter="networkIsPreferred_"> <div class="list-item"> <div class="start">[[item.Name]]</div> + <template is="dom-if" if="[[isPolicySource(item.Source))]]"> + <cr-policy-indicator + indicator-type="[[getIndicatorTypeForSource(item.Source)]]"> + </cr-policy-indicator> + </template> <button class="subpage-arrow" is="paper-icon-button-light" actionable on-tap="fireShowDetails_" tabindex$="[[tabindex]]" aria-label$="[[item.Name]]"> @@ -48,6 +57,11 @@ filter="networkIsNotPreferred_"> <div class="list-item"> <div class="start">[[item.Name]]</div> + <template is="dom-if" if="[[isPolicySource(item.Source))]]"> + <cr-policy-indicator + indicator-type="[[getIndicatorTypeForSource(item.Source)]]"> + </cr-policy-indicator> + </template> <button class="subpage-arrow" is="paper-icon-button-light" actionable on-tap="fireShowDetails_" tabindex$="[[tabindex]]" aria-label$="[[item.Name]]"> @@ -70,7 +84,8 @@ on-tap="onRemovePreferredTap_"> $i18n{knownNetworksMenuRemovePreferred} </button> - <button class="dropdown-item" on-tap="onForgetTap_"> + <button class="dropdown-item" disabled="[[!enableForget_]]" + on-tap="onForgetTap_"> $i18n{knownNetworksMenuForget} </button> </dialog>
diff --git a/chrome/browser/resources/settings/internet_page/internet_known_networks_page.js b/chrome/browser/resources/settings/internet_page/internet_known_networks_page.js index f125444..5ec39d7 100644 --- a/chrome/browser/resources/settings/internet_page/internet_known_networks_page.js +++ b/chrome/browser/resources/settings/internet_page/internet_known_networks_page.js
@@ -44,6 +44,14 @@ /** @private */ showRemovePreferred_: Boolean, + + /** + * We always show 'Forget' since we do not know whether or not to enable + * it until we fetch the managed properties, and we do not want an empty + * menu. + * @private + */ + enableForget_: Boolean, }, /** @private {string} */ @@ -153,8 +161,8 @@ this.networkingPrivate.getManagedProperties( this.selectedGuid_, properties => { if (chrome.runtime.lastError || !properties) { - this.showAddPreferred_ = false; - this.showRemovePreferred_ = false; + console.error( + 'Unexpected error: ' + chrome.runtime.lastError.message); return; } var preferred = button.hasAttribute('preferred'); @@ -165,6 +173,7 @@ this.showAddPreferred_ = !preferred; this.showRemovePreferred_ = preferred; } + this.enableForget_ = !this.isPolicySource(properties.Source); /** @type {!CrActionMenuElement} */ (this.$.dotsMenu).showAt(button); }); event.stopPropagation();
diff --git a/chrome/browser/resources/settings/internet_page/internet_subpage.js b/chrome/browser/resources/settings/internet_page/internet_subpage.js index fd952846..d64268471 100644 --- a/chrome/browser/resources/settings/internet_page/internet_subpage.js +++ b/chrome/browser/resources/settings/internet_page/internet_subpage.js
@@ -135,13 +135,18 @@ updateScanning_: function() { if (!this.deviceState) return; - if (this.deviceState.Type != CrOnc.Type.WI_FI) { - // deviceState probably changed, re-request networks. - this.getNetworkStateList_(); + + if (this.deviceState.Type == CrOnc.Type.WI_FI || + this.deviceState.Type == CrOnc.Type.TETHER || + (this.deviceState.Type == CrOnc.Type.CELLULAR && + this.tetherDeviceState)) { + this.showSpinner = !!this.deviceState.Scanning; + this.startScanning_(); return; } - this.showSpinner = !!this.deviceState.Scanning; - this.startScanning_(); + + // deviceState probably changed, re-request networks. + this.getNetworkStateList_(); }, /** @private */
diff --git a/chrome/browser/resources/settings/internet_page/network_siminfo.js b/chrome/browser/resources/settings/internet_page/network_siminfo.js index 3bf92e8..4936d836 100644 --- a/chrome/browser/resources/settings/internet_page/network_siminfo.js +++ b/chrome/browser/resources/settings/internet_page/network_siminfo.js
@@ -310,10 +310,10 @@ else return 'UNKNOWN ERROR'; var retriesLeft = - this.get( - 'Cellular.SIMLockStatus.RetriesLeft', this.networkProperties) || - 0; - msg += ' Retries left: ' + retriesLeft.toString(); + this.get('Cellular.SIMLockStatus.RetriesLeft', this.networkProperties); + if (retriesLeft) { + msg += ' Retries left: ' + retriesLeft.toString(); + } return msg; },
diff --git a/chrome/browser/resources/settings/on_startup_page/startup_url_dialog.html b/chrome/browser/resources/settings/on_startup_page/startup_url_dialog.html index 2d15f1b..7fb4e0b 100644 --- a/chrome/browser/resources/settings/on_startup_page/startup_url_dialog.html +++ b/chrome/browser/resources/settings/on_startup_page/startup_url_dialog.html
@@ -13,7 +13,7 @@ <div slot="title">[[dialogTitle_]]</div> <div slot="body"> <paper-input always-float-label id="url" label="$i18n{onStartupSiteUrl}" - value="{{url_}}" on-input="validate_" autofocus> + value="{{url_}}" on-input="validate_" spellcheck="false" autofocus> </paper-input> </div> <div slot="button-container">
diff --git a/chrome/browser/resources/settings/search_engines_page/search_engine_dialog.html b/chrome/browser/resources/settings/search_engines_page/search_engine_dialog.html index 54b9b69..a2788c60 100644 --- a/chrome/browser/resources/settings/search_engines_page/search_engine_dialog.html +++ b/chrome/browser/resources/settings/search_engines_page/search_engine_dialog.html
@@ -24,7 +24,7 @@ </style> <dialog is="cr-dialog" id="dialog" close-text="$i18n{close}"> <div slot="title">[[dialogTitle_]]</div> - <div slot="body"> + <div slot="body" spellcheck="false"> <paper-input always-float-label id="searchEngine" label="$i18n{searchEnginesSearchEngine}" error-message="$i18n{notValid}"
diff --git a/chrome/browser/resources/settings/site_settings/add_site_dialog.html b/chrome/browser/resources/settings/site_settings/add_site_dialog.html index 2bb9ba67..94157be 100644 --- a/chrome/browser/resources/settings/site_settings/add_site_dialog.html +++ b/chrome/browser/resources/settings/site_settings/add_site_dialog.html
@@ -27,7 +27,8 @@ <paper-input id="site" always-float-label label="$i18n{addSite}" placeholder="$i18n{addSiteExceptionPlaceholder}" value="{{site_}}" on-input="validate_" - error-message="$i18n{notValidWebAddress}" autofocus></paper-input> + error-message="$i18n{notValidWebAddress}" spellcheck="false" + autofocus></paper-input> <paper-checkbox id="incognito" invisible$="[[!showIncognitoSessionOnly_]]"> $i18n{incognitoSiteOnly}
diff --git a/chrome/browser/resources/settings/site_settings/site_details.js b/chrome/browser/resources/settings/site_settings/site_details.js index a157cf4d..91f8433 100644 --- a/chrome/browser/resources/settings/site_settings/site_details.js +++ b/chrome/browser/resources/settings/site_settings/site_details.js
@@ -90,10 +90,17 @@ * @private */ onOriginChanged_: function() { - if (this.enableSiteSettings_) - this.$.usageApi.fetchUsageTotal(this.toUrl(this.origin).hostname); + this.browserProxy.isOriginValid(this.origin).then((valid) => { + if (!valid) { + settings.navigateToPreviousRoute(); + } else { + if (this.enableSiteSettings_) + this.$.usageApi.fetchUsageTotal(this.toUrl(this.origin).hostname); - this.updatePermissions_(this.getCategoryList_()); + this.updatePermissions_(this.getCategoryList_()); + } + }); + }, /**
diff --git a/chrome/browser/resources/settings/site_settings/site_settings_prefs_browser_proxy.js b/chrome/browser/resources/settings/site_settings/site_settings_prefs_browser_proxy.js index 4842bc3..0fe74d5 100644 --- a/chrome/browser/resources/settings/site_settings/site_settings_prefs_browser_proxy.js +++ b/chrome/browser/resources/settings/site_settings/site_settings_prefs_browser_proxy.js
@@ -173,8 +173,15 @@ primaryPattern, secondaryPattern, contentType, value, incognito) {} /** + * Checks whether an origin is valid. + * @param {string} origin The origin to check. + * @return {!Promise<boolean>} True if the origin is valid. + */ + isOriginValid(origin) {} + + /** * Checks whether a pattern is valid. - * @param {string} pattern The pattern to check + * @param {string} pattern The pattern to check. * @return {!Promise<boolean>} True if the pattern is valid. */ isPatternValid(pattern) {} @@ -351,6 +358,11 @@ } /** @override */ + isOriginValid(origin) { + return cr.sendWithPromise('isOriginValid', origin); + } + + /** @override */ isPatternValid(pattern) { return cr.sendWithPromise('isPatternValid', pattern); }
diff --git a/chrome/browser/sessions/session_restore_delegate.cc b/chrome/browser/sessions/session_restore_delegate.cc index f562d944..a7b3651f 100644 --- a/chrome/browser/sessions/session_restore_delegate.cc +++ b/chrome/browser/sessions/session_restore_delegate.cc
@@ -76,7 +76,8 @@ // Restore the favicon for deferred tabs. favicon::ContentFaviconDriver* favicon_driver = favicon::ContentFaviconDriver::FromWebContents(restored_tab.contents()); - favicon_driver->FetchFavicon(favicon_driver->GetActiveURL()); + favicon_driver->FetchFavicon(favicon_driver->GetActiveURL(), + /*is_same_document=*/false); } TabLoader::RestoreTabs(tabs, restore_started);
diff --git a/chrome/browser/sessions/tab_loader.cc b/chrome/browser/sessions/tab_loader.cc index 69027ecf..1f6f8aa 100644 --- a/chrome/browser/sessions/tab_loader.cc +++ b/chrome/browser/sessions/tab_loader.cc
@@ -128,8 +128,10 @@ favicon::ContentFaviconDriver::FromWebContents( restored_tab.contents()); // |favicon_driver| might be null when testing. - if (favicon_driver) - favicon_driver->FetchFavicon(favicon_driver->GetActiveURL()); + if (favicon_driver) { + favicon_driver->FetchFavicon(favicon_driver->GetActiveURL(), + /*is_same_document=*/false); + } } else { ++started_to_load_count_; tabs_loading_.insert(&restored_tab.contents()->GetController());
diff --git a/chrome/browser/shell_integration.cc b/chrome/browser/shell_integration.cc index 2946e45..105650e 100644 --- a/chrome/browser/shell_integration.cc +++ b/chrome/browser/shell_integration.cc
@@ -230,18 +230,15 @@ if (!callback_.is_null()) { switch (state) { case NOT_DEFAULT: - callback_.Run(NOT_DEFAULT); - break; case IS_DEFAULT: - callback_.Run(IS_DEFAULT); - break; case UNKNOWN_DEFAULT: - callback_.Run(UNKNOWN_DEFAULT); - break; + case OTHER_MODE_IS_DEFAULT: + callback_.Run(state); + return; case NUM_DEFAULT_STATES: - NOTREACHED(); break; } + NOTREACHED(); } }
diff --git a/chrome/browser/shell_integration.h b/chrome/browser/shell_integration.h index e6b1bbb..f399855 100644 --- a/chrome/browser/shell_integration.h +++ b/chrome/browser/shell_integration.h
@@ -65,13 +65,21 @@ // Returns an empty string on failure. base::string16 GetApplicationNameForProtocol(const GURL& url); -// On Linux, it may not be possible to determine or set the default browser -// on some desktop environments or configurations. So, we use this enum and -// not a plain bool. +// Chrome's default web client state as a browser as a protocol client. If the +// current install mode is not default, the brand's other modes are +// checked. This allows callers to take specific action in case the current mode +// (e.g., Chrome Dev) is not the default handler, but another of the brand's +// modes (e.g., stable Chrome) is. enum DefaultWebClientState { + // No install mode for the brand is the default client. NOT_DEFAULT, + // The current install mode is the default client. IS_DEFAULT, + // An error occurred while attempting to check the default client. UNKNOWN_DEFAULT, + // The current install mode is not default, although one of the brand's + // other install modes is. + OTHER_MODE_IS_DEFAULT, NUM_DEFAULT_STATES };
diff --git a/chrome/browser/shell_integration_win.cc b/chrome/browser/shell_integration_win.cc index 2350866..77a73d7 100644 --- a/chrome/browser/shell_integration_win.cc +++ b/chrome/browser/shell_integration_win.cc
@@ -221,14 +221,17 @@ DefaultWebClientState GetDefaultWebClientStateFromShellUtilDefaultState( ShellUtil::DefaultState default_state) { switch (default_state) { + case ShellUtil::UNKNOWN_DEFAULT: + return DefaultWebClientState::UNKNOWN_DEFAULT; case ShellUtil::NOT_DEFAULT: return DefaultWebClientState::NOT_DEFAULT; case ShellUtil::IS_DEFAULT: return DefaultWebClientState::IS_DEFAULT; - default: - DCHECK_EQ(ShellUtil::UNKNOWN_DEFAULT, default_state); - return DefaultWebClientState::UNKNOWN_DEFAULT; + case ShellUtil::OTHER_MODE_IS_DEFAULT: + return DefaultWebClientState::OTHER_MODE_IS_DEFAULT; } + NOTREACHED(); + return DefaultWebClientState::UNKNOWN_DEFAULT; } // A recorder of user actions in the Windows Settings app.
diff --git a/chrome/browser/signin/DEPS b/chrome/browser/signin/DEPS deleted file mode 100644 index 392e891..0000000 --- a/chrome/browser/signin/DEPS +++ /dev/null
@@ -1,7 +0,0 @@ -include_rules = [ - # TODO(mash): Remove. http://crbug.com/724143 - "+ash/shell.h", - "+ash/system/devicetype_utils.h", - "+ash/system/system_notifier.h", - "+ash/test/ash_test_base.h", -]
diff --git a/chrome/browser/signin/easy_unlock_notification_controller_chromeos.cc b/chrome/browser/signin/easy_unlock_notification_controller_chromeos.cc index 20c01697..a72f3c8 100644 --- a/chrome/browser/signin/easy_unlock_notification_controller_chromeos.cc +++ b/chrome/browser/signin/easy_unlock_notification_controller_chromeos.cc
@@ -4,7 +4,6 @@ #include "chrome/browser/signin/easy_unlock_notification_controller_chromeos.h" -#include "ash/system/devicetype_utils.h" #include "base/guid.h" #include "base/memory/ptr_util.h" #include "base/strings/utf_string_conversions.h" @@ -14,6 +13,7 @@ #include "components/proximity_auth/screenlock_bridge.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h" +#include "ui/chromeos/devicetype_utils.h" #include "ui/message_center/message_center_types.h" #include "ui/message_center/notification_types.h" @@ -76,7 +76,7 @@ IDS_EASY_UNLOCK_CHROMEBOOK_ADDED_NOTIFICATION_TITLE), l10n_util::GetStringFUTF16( IDS_EASY_UNLOCK_CHROMEBOOK_ADDED_NOTIFICATION_MESSAGE, - ash::GetChromeOSDeviceName()), + ui::GetChromeOSDeviceName()), ui::ResourceBundle::GetSharedInstance().GetImageNamed( IDR_NOTIFICATION_EASYUNLOCK_ENABLED), rich_notification_data, @@ -99,7 +99,7 @@ IDS_EASY_UNLOCK_PAIRING_CHANGED_NOTIFICATION_TITLE), l10n_util::GetStringFUTF16( IDS_EASY_UNLOCK_PAIRING_CHANGED_NOTIFICATION_MESSAGE, - ash::GetChromeOSDeviceName()), + ui::GetChromeOSDeviceName()), ui::ResourceBundle::GetSharedInstance().GetImageNamed( IDR_NOTIFICATION_EASYUNLOCK_ENABLED), rich_notification_data, @@ -124,7 +124,7 @@ IDS_EASY_UNLOCK_PAIRING_CHANGE_APPLIED_NOTIFICATION_TITLE), l10n_util::GetStringFUTF16( IDS_EASY_UNLOCK_PAIRING_CHANGE_APPLIED_NOTIFICATION_MESSAGE, - base::UTF8ToUTF16(phone_name), ash::GetChromeOSDeviceName()), + base::UTF8ToUTF16(phone_name), ui::GetChromeOSDeviceName()), ui::ResourceBundle::GetSharedInstance().GetImageNamed( IDR_NOTIFICATION_EASYUNLOCK_ENABLED), rich_notification_data, @@ -141,9 +141,9 @@ ShowNotification(CreateNotification( kEasyUnlockPromotionNotifierId, l10n_util::GetStringFUTF16(IDS_EASY_UNLOCK_SETUP_NOTIFICATION_TITLE, - ash::GetChromeOSDeviceName()), + ui::GetChromeOSDeviceName()), l10n_util::GetStringFUTF16(IDS_EASY_UNLOCK_SETUP_NOTIFICATION_MESSAGE, - ash::GetChromeOSDeviceName()), + ui::GetChromeOSDeviceName()), ui::ResourceBundle::GetSharedInstance().GetImageNamed( IDR_NOTIFICATION_EASYUNLOCK_PROMO), rich_notification_data,
diff --git a/chrome/browser/signin/easy_unlock_screenlock_state_handler.cc b/chrome/browser/signin/easy_unlock_screenlock_state_handler.cc index 1ec77ea..6d9c35c 100644 --- a/chrome/browser/signin/easy_unlock_screenlock_state_handler.cc +++ b/chrome/browser/signin/easy_unlock_screenlock_state_handler.cc
@@ -15,7 +15,7 @@ #include "ui/base/l10n/l10n_util.h" #if defined(OS_CHROMEOS) -#include "ash/system/devicetype_utils.h" +#include "ui/chromeos/devicetype_utils.h" #endif using proximity_auth::ScreenlockState; @@ -361,7 +361,7 @@ base::string16 EasyUnlockScreenlockStateHandler::GetDeviceName() { #if defined(OS_CHROMEOS) - return ash::GetChromeOSDeviceName(); + return ui::GetChromeOSDeviceName(); #else // TODO(tbarzic): Figure out the name for non Chrome OS case. return base::ASCIIToUTF16("Chrome");
diff --git a/chrome/browser/signin/easy_unlock_service_regular.cc b/chrome/browser/signin/easy_unlock_service_regular.cc index 76783fc7..2e21437 100644 --- a/chrome/browser/signin/easy_unlock_service_regular.cc +++ b/chrome/browser/signin/easy_unlock_service_regular.cc
@@ -61,7 +61,6 @@ #if defined(OS_CHROMEOS) #include "apps/app_lifetime_monitor_factory.h" -#include "ash/shell.h" #include "base/linux_util.h" #include "base/threading/thread_task_runner_handle.h" #include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_key_manager.h"
diff --git a/chrome/browser/signin/signin_error_notifier_ash.cc b/chrome/browser/signin/signin_error_notifier_ash.cc index a60b0333..40efd9ef 100644 --- a/chrome/browser/signin/signin_error_notifier_ash.cc +++ b/chrome/browser/signin/signin_error_notifier_ash.cc
@@ -4,13 +4,14 @@ #include "chrome/browser/signin/signin_error_notifier_ash.h" -#include "ash/system/system_notifier.h" #include "base/logging.h" #include "base/macros.h" #include "base/strings/string16.h" #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/chromeos/login/user_flow.h" +#include "chrome/browser/chromeos/login/users/chrome_user_manager.h" #include "chrome/browser/lifetime/application_lifetime.h" #include "chrome/browser/notifications/notification.h" #include "chrome/browser/notifications/notification_delegate.h" @@ -20,25 +21,17 @@ #include "chrome/browser/ui/browser_tabstrip.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/chrome_pages.h" -#include "chrome/browser/ui/scoped_tabbed_browser_displayer.h" -#include "chrome/browser/ui/webui/signin/login_ui_service.h" -#include "chrome/browser/ui/webui/signin/login_ui_service_factory.h" #include "chrome/common/url_constants.h" #include "chrome/grit/chromium_strings.h" #include "chrome/grit/generated_resources.h" #include "chrome/grit/theme_resources.h" #include "components/signin/core/account_id/account_id.h" +#include "components/user_manager/user_manager.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h" #include "ui/message_center/notification.h" #include "ui/message_center/notification_delegate.h" -#if defined(OS_CHROMEOS) -#include "chrome/browser/chromeos/login/user_flow.h" -#include "chrome/browser/chromeos/login/users/chrome_user_manager.h" -#include "components/user_manager/user_manager.h" -#endif - namespace { const char kProfileSigninNotificationId[] = "chrome://settings/signin/"; @@ -46,8 +39,7 @@ // A notification delegate for the sign-out button. class SigninNotificationDelegate : public NotificationDelegate { public: - SigninNotificationDelegate(const std::string& id, - Profile* profile); + explicit SigninNotificationDelegate(const std::string& id); // NotificationDelegate: void Click() override; @@ -58,61 +50,29 @@ ~SigninNotificationDelegate() override; private: - void FixSignIn(); - // Unique id of the notification. const std::string id_; -#if !defined(OS_CHROMEOS) - Profile* profile_; -#endif - DISALLOW_COPY_AND_ASSIGN(SigninNotificationDelegate); }; -SigninNotificationDelegate::SigninNotificationDelegate(const std::string& id, - Profile* profile) -#if defined(OS_CHROMEOS) - : id_(id) { -#else - : id_(id), profile_(profile) { -#endif -} +SigninNotificationDelegate::SigninNotificationDelegate(const std::string& id) + : id_(id) {} -SigninNotificationDelegate::~SigninNotificationDelegate() { -} +SigninNotificationDelegate::~SigninNotificationDelegate() {} void SigninNotificationDelegate::Click() { - FixSignIn(); + chrome::AttemptUserExit(); } void SigninNotificationDelegate::ButtonClick(int button_index) { - FixSignIn(); + chrome::AttemptUserExit(); } std::string SigninNotificationDelegate::id() const { return id_; } -void SigninNotificationDelegate::FixSignIn() { -#if defined(OS_CHROMEOS) - chrome::AttemptUserExit(); -#else - LoginUIService* login_ui = LoginUIServiceFactory::GetForProfile(profile_); - if (login_ui->current_login_ui()) { - login_ui->current_login_ui()->FocusUI(); - return; - } - - // Find a browser instance or create one. - chrome::ScopedTabbedBrowserDisplayer browser_displayer(profile_); - - // Navigate to the sync setup subpage, which will launch a login page. - chrome::ShowSettingsSubPage(browser_displayer.browser(), - chrome::kSyncSetupSubPage); -#endif -} - } // namespace SigninErrorNotifier::SigninErrorNotifier(SigninErrorController* controller, @@ -151,7 +111,6 @@ return; } -#if defined(OS_CHROMEOS) if (user_manager::UserManager::IsInitialized()) { chromeos::UserFlow* user_flow = chromeos::ChromeUserManager::Get()->GetCurrentUserFlow(); @@ -162,7 +121,6 @@ if (!user_flow->ShouldLaunchBrowser()) return; } -#endif // Add an accept button to sign the user out. message_center::RichNotificationData data; @@ -171,7 +129,7 @@ // Set the delegate for the notification's sign-out button. SigninNotificationDelegate* delegate = - new SigninNotificationDelegate(notification_id_, profile_); + new SigninNotificationDelegate(notification_id_); message_center::NotifierId notifier_id( message_center::NotifierId::SYSTEM_COMPONENT,
diff --git a/chrome/browser/signin/signin_error_notifier_ash_unittest.cc b/chrome/browser/signin/signin_error_notifier_ash_unittest.cc index 9ec52e43..96c34f5 100644 --- a/chrome/browser/signin/signin_error_notifier_ash_unittest.cc +++ b/chrome/browser/signin/signin_error_notifier_ash_unittest.cc
@@ -8,16 +8,18 @@ #include <memory> -#include "ash/test/ash_test_base.h" #include "base/macros.h" #include "build/build_config.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/chromeos/login/users/mock_user_manager.h" +#include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h" #include "chrome/browser/notifications/notification.h" #include "chrome/browser/notifications/notification_ui_manager.h" #include "chrome/browser/signin/fake_signin_manager_builder.h" #include "chrome/browser/signin/signin_error_controller_factory.h" #include "chrome/browser/signin/signin_error_notifier_factory_ash.h" #include "chrome/browser/signin/signin_manager_factory.h" +#include "chrome/test/base/browser_with_test_window_test.h" #include "chrome/test/base/testing_browser_process.h" #include "chrome/test/base/testing_profile.h" #include "chrome/test/base/testing_profile_manager.h" @@ -28,19 +30,6 @@ #include "testing/gtest/include/gtest/gtest.h" #include "ui/message_center/notification.h" -#if defined(OS_WIN) -#include "ui/aura/test/test_screen.h" -#include "ui/display/screen.h" -#endif - -#if defined(OS_CHROMEOS) -#include "chrome/browser/chromeos/login/users/mock_user_manager.h" -#include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h" -#endif - -namespace ash { -namespace test { - namespace { static const char kTestAccountId[] = "testuser@test.com"; @@ -49,96 +38,74 @@ // kTestAccountId. static const char kNotificationId[] = "chrome://settings/signin/testuser@test.com"; -} -class SigninErrorNotifierTest : public AshTestBase { +class SigninErrorNotifierTest : public BrowserWithTestWindowTest { public: void SetUp() override { - // Create a signed-in profile. - TestingProfile::Builder builder; - builder.AddTestingFactory(SigninManagerFactory::GetInstance(), - BuildFakeSigninManagerBase); - profile_ = builder.Build(); - profile_->set_profile_name(kTestAccountId); - + BrowserWithTestWindowTest::SetUp(); profile_manager_.reset( new TestingProfileManager(TestingBrowserProcess::GetGlobal())); ASSERT_TRUE(profile_manager_->SetUp()); -#if defined(OS_CHROMEOS) mock_user_manager_ = new chromeos::MockUserManager(); user_manager_enabler_.reset( new chromeos::ScopedUserManagerEnabler(mock_user_manager_)); -#endif - TestingBrowserProcess::GetGlobal(); - AshTestBase::SetUp(); - - // Set up screen for Windows. -#if defined(OS_WIN) - test_screen_.reset(aura::TestScreen::Create(gfx::Size())); - display::Screen::SetScreenInstance(test_screen_.get()); -#endif - - error_controller_ = SigninErrorControllerFactory::GetForProfile( - profile_.get()); - SigninErrorNotifierFactory::GetForProfile(profile_.get()); + error_controller_ = + SigninErrorControllerFactory::GetForProfile(GetProfile()); + SigninErrorNotifierFactory::GetForProfile(GetProfile()); notification_ui_manager_ = g_browser_process->notification_ui_manager(); } void TearDown() override { -#if defined(OS_WIN) - display::Screen::SetScreenInstance(nullptr); - test_screen_.reset(); -#endif profile_manager_.reset(); + BrowserWithTestWindowTest::TearDown(); + } - AshTestBase::TearDown(); + TestingProfile* CreateProfile() override { + // Create a signed-in profile. + TestingProfile::Builder builder; + builder.AddTestingFactory(SigninManagerFactory::GetInstance(), + BuildFakeSigninManagerBase); + std::unique_ptr<TestingProfile> profile = builder.Build(); + profile->set_profile_name(kTestAccountId); + return profile.release(); } protected: void GetMessage(base::string16* message) { const Notification* notification = g_browser_process->notification_ui_manager()->FindById( - kNotificationId, - NotificationUIManager::GetProfileID(profile_.get())); + kNotificationId, NotificationUIManager::GetProfileID(GetProfile())); ASSERT_FALSE(notification == NULL); *message = notification->message(); } -#if defined(OS_WIN) - std::unique_ptr<display::Screen> test_screen_; -#endif std::unique_ptr<TestingProfileManager> profile_manager_; - std::unique_ptr<TestingProfile> profile_; SigninErrorController* error_controller_; NotificationUIManager* notification_ui_manager_; -#if defined(OS_CHROMEOS) chromeos::MockUserManager* mock_user_manager_; // Not owned. std::unique_ptr<chromeos::ScopedUserManagerEnabler> user_manager_enabler_; -#endif }; TEST_F(SigninErrorNotifierTest, NoErrorAuthStatusProviders) { ASSERT_FALSE(notification_ui_manager_->FindById( - kNotificationId, NotificationUIManager::GetProfileID(profile_.get()))); + kNotificationId, NotificationUIManager::GetProfileID(GetProfile()))); { // Add a provider (removes itself on exiting this scope). FakeAuthStatusProvider provider(error_controller_); ASSERT_FALSE(notification_ui_manager_->FindById( - kNotificationId, NotificationUIManager::GetProfileID(profile_.get()))); + kNotificationId, NotificationUIManager::GetProfileID(GetProfile()))); } ASSERT_FALSE(notification_ui_manager_->FindById( - kNotificationId, NotificationUIManager::GetProfileID(profile_.get()))); + kNotificationId, NotificationUIManager::GetProfileID(GetProfile()))); } -#if !defined(OS_WIN) -// Disabled on Win due to flake. http://crbug.com/372236 TEST_F(SigninErrorNotifierTest, ErrorAuthStatusProvider) { { FakeAuthStatusProvider provider(error_controller_); ASSERT_FALSE(notification_ui_manager_->FindById( - kNotificationId, NotificationUIManager::GetProfileID(profile_.get()))); + kNotificationId, NotificationUIManager::GetProfileID(GetProfile()))); { FakeAuthStatusProvider error_provider(error_controller_); error_provider.SetAuthError( @@ -146,28 +113,18 @@ GoogleServiceAuthError( GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS)); ASSERT_TRUE(notification_ui_manager_->FindById( - kNotificationId, - NotificationUIManager::GetProfileID(profile_.get()))); + kNotificationId, NotificationUIManager::GetProfileID(GetProfile()))); } // error_provider is removed now that we've left that scope. ASSERT_FALSE(notification_ui_manager_->FindById( - kNotificationId, NotificationUIManager::GetProfileID(profile_.get()))); + kNotificationId, NotificationUIManager::GetProfileID(GetProfile()))); } // All providers should be removed now. ASSERT_FALSE(notification_ui_manager_->FindById( - kNotificationId, NotificationUIManager::GetProfileID(profile_.get()))); + kNotificationId, NotificationUIManager::GetProfileID(GetProfile()))); } -#endif -#if defined(OS_WIN) -// Test started crashing on Win 7. http://crbug.com/372277 -#define MAYBE_AuthStatusProviderErrorTransition \ - DISABLED_AuthStatusProviderErrorTransition -#else -#define MAYBE_AuthStatusProviderErrorTransition \ - AuthStatusProviderErrorTransition -#endif -TEST_F(SigninErrorNotifierTest, MAYBE_AuthStatusProviderErrorTransition) { +TEST_F(SigninErrorNotifierTest, AuthStatusProviderErrorTransition) { { FakeAuthStatusProvider provider0(error_controller_); FakeAuthStatusProvider provider1(error_controller_); @@ -176,7 +133,7 @@ GoogleServiceAuthError( GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS)); ASSERT_TRUE(notification_ui_manager_->FindById( - kNotificationId, NotificationUIManager::GetProfileID(profile_.get()))); + kNotificationId, NotificationUIManager::GetProfileID(GetProfile()))); base::string16 message; GetMessage(&message); @@ -192,7 +149,7 @@ GoogleServiceAuthError::AuthErrorNone()); ASSERT_TRUE(notification_ui_manager_->FindById( - kNotificationId, NotificationUIManager::GetProfileID(profile_.get()))); + kNotificationId, NotificationUIManager::GetProfileID(GetProfile()))); base::string16 new_message; GetMessage(&new_message); @@ -203,12 +160,10 @@ provider1.SetAuthError( kTestAccountId, GoogleServiceAuthError::AuthErrorNone()); ASSERT_FALSE(notification_ui_manager_->FindById( - kNotificationId, NotificationUIManager::GetProfileID(profile_.get()))); + kNotificationId, NotificationUIManager::GetProfileID(GetProfile()))); } } -#if !defined(OS_WIN) -// Disabled on Win due to flake. http://crbug.com/372236 // Verify that SigninErrorNotifier ignores certain errors. TEST_F(SigninErrorNotifierTest, AuthStatusEnumerateAllErrors) { typedef struct { @@ -242,7 +197,7 @@ provider.SetAuthError(kTestAccountId, GoogleServiceAuthError(table[i].error_state)); const Notification* notification = notification_ui_manager_->FindById( - kNotificationId, NotificationUIManager::GetProfileID(profile_.get())); + kNotificationId, NotificationUIManager::GetProfileID(GetProfile())); ASSERT_EQ(table[i].is_error, notification != NULL); if (table[i].is_error) { EXPECT_FALSE(notification->title().empty()); @@ -251,7 +206,5 @@ } } } -#endif -} // namespace test -} // namespace ash +} // namespace
diff --git a/chrome/browser/signin/signin_error_notifier_factory_ash.cc b/chrome/browser/signin/signin_error_notifier_factory_ash.cc index bc777ec..e6737e0 100644 --- a/chrome/browser/signin/signin_error_notifier_factory_ash.cc +++ b/chrome/browser/signin/signin_error_notifier_factory_ash.cc
@@ -4,7 +4,6 @@ #include "chrome/browser/signin/signin_error_notifier_factory_ash.h" -#include "ash/shell.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/signin/signin_error_controller_factory.h" @@ -35,11 +34,7 @@ KeyedService* SigninErrorNotifierFactory::BuildServiceInstanceFor( content::BrowserContext* context) const { - if (!ash::Shell::HasInstance()) - return NULL; - Profile* profile = static_cast<Profile*>(context); - return new SigninErrorNotifier( SigninErrorControllerFactory::GetForProfile(profile), profile); }
diff --git a/chrome/browser/signin/signin_global_error_factory.cc b/chrome/browser/signin/signin_global_error_factory.cc index b24e366..0d32252 100644 --- a/chrome/browser/signin/signin_global_error_factory.cc +++ b/chrome/browser/signin/signin_global_error_factory.cc
@@ -12,10 +12,6 @@ #include "components/keyed_service/content/browser_context_dependency_manager.h" #include "components/signin/core/browser/profile_oauth2_token_service.h" -#if defined(USE_ASH) -#include "ash/shell.h" -#endif - SigninGlobalErrorFactory::SigninGlobalErrorFactory() : BrowserContextKeyedServiceFactory( "SigninGlobalError", @@ -41,12 +37,10 @@ KeyedService* SigninGlobalErrorFactory::BuildServiceInstanceFor( content::BrowserContext* context) const { #if defined(USE_ASH) - if (ash::Shell::HasInstance()) - return NULL; + return nullptr; #endif Profile* profile = static_cast<Profile*>(context); - return new SigninGlobalError( SigninErrorControllerFactory::GetForProfile(profile), profile); }
diff --git a/chrome/browser/subresource_filter/subresource_filter_browser_test_harness.cc b/chrome/browser/subresource_filter/subresource_filter_browser_test_harness.cc new file mode 100644 index 0000000..12d2a111 --- /dev/null +++ b/chrome/browser/subresource_filter/subresource_filter_browser_test_harness.cc
@@ -0,0 +1,280 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/subresource_filter/subresource_filter_browser_test_harness.h" + +#include <utility> + +#include "base/bind.h" +#include "base/command_line.h" +#include "base/files/file_path.h" +#include "base/location.h" +#include "base/logging.h" +#include "base/memory/ptr_util.h" +#include "base/path_service.h" +#include "base/strings/string_piece.h" +#include "base/strings/string_util.h" +#include "base/strings/stringprintf.h" +#include "build/build_config.h" +#include "chrome/browser/safe_browsing/safe_browsing_service.h" +#include "chrome/browser/safe_browsing/test_safe_browsing_service.h" +#include "chrome/browser/safe_browsing/v4_test_utils.h" +#include "chrome/browser/subresource_filter/subresource_filter_profile_context.h" +#include "chrome/browser/subresource_filter/subresource_filter_profile_context_factory.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/tabs/tab_strip_model.h" +#include "chrome/common/chrome_paths.h" +#include "components/safe_browsing_db/v4_database.h" +#include "components/safe_browsing_db/v4_feature_list.h" +#include "components/safe_browsing_db/v4_get_hash_protocol_manager.h" +#include "components/safe_browsing_db/v4_protocol_manager_util.h" +#include "components/subresource_filter/core/browser/subresource_filter_features.h" +#include "content/public/browser/web_contents.h" +#include "content/public/common/content_switches.h" +#include "content/public/test/browser_test_utils.h" +#include "content/public/test/test_navigation_observer.h" +#include "net/dns/mock_host_resolver.h" +#include "net/test/embedded_test_server/embedded_test_server.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace subresource_filter { + +namespace { + +// UI manager that never actually shows any interstitials, but emulates as if +// the user chose to proceed through them. +class FakeSafeBrowsingUIManager + : public safe_browsing::TestSafeBrowsingUIManager { + public: + FakeSafeBrowsingUIManager() {} + + protected: + ~FakeSafeBrowsingUIManager() override {} + + void DisplayBlockingPage(const UnsafeResource& resource) override { + resource.callback_thread->PostTask( + FROM_HERE, base::Bind(resource.callback, true /* proceed */)); + } + + private: + DISALLOW_COPY_AND_ASSIGN(FakeSafeBrowsingUIManager); +}; + +} // namespace + +SubresourceFilterBrowserTest::SubresourceFilterBrowserTest() {} +SubresourceFilterBrowserTest::~SubresourceFilterBrowserTest() {} + +void SubresourceFilterBrowserTest::SetUpCommandLine( + base::CommandLine* command_line) { + command_line->AppendSwitchASCII(switches::kEnableFeatures, + base::JoinString(RequiredFeatures(), ",")); +} + +std::vector<base::StringPiece> SubresourceFilterBrowserTest::RequiredFeatures() + const { + return {kSafeBrowsingSubresourceFilter.name, "SafeBrowsingV4OnlyEnabled", + kSafeBrowsingSubresourceFilterExperimentalUI.name}; +} + +void SubresourceFilterBrowserTest::SetUp() { + sb_factory_ = base::MakeUnique<safe_browsing::TestSafeBrowsingServiceFactory>( + safe_browsing::V4FeatureList::V4UsageStatus::V4_ONLY); + sb_factory_->SetTestUIManager(new FakeSafeBrowsingUIManager()); + safe_browsing::SafeBrowsingService::RegisterFactory(sb_factory_.get()); + + safe_browsing::V4Database::RegisterStoreFactoryForTest( + base::WrapUnique(new safe_browsing::TestV4StoreFactory())); + + v4_db_factory_ = new safe_browsing::TestV4DatabaseFactory(); + safe_browsing::V4Database::RegisterDatabaseFactoryForTest( + base::WrapUnique(v4_db_factory_)); + + v4_get_hash_factory_ = + new safe_browsing::TestV4GetHashProtocolManagerFactory(); + safe_browsing::V4GetHashProtocolManager::RegisterFactory( + base::WrapUnique(v4_get_hash_factory_)); + InProcessBrowserTest::SetUp(); +} + +void SubresourceFilterBrowserTest::TearDown() { + InProcessBrowserTest::TearDown(); + // Unregister test factories after InProcessBrowserTest::TearDown + // (which destructs SafeBrowsingService). + safe_browsing::V4GetHashProtocolManager::RegisterFactory(nullptr); + safe_browsing::V4Database::RegisterDatabaseFactoryForTest(nullptr); + safe_browsing::V4Database::RegisterStoreFactoryForTest(nullptr); + safe_browsing::SafeBrowsingService::RegisterFactory(nullptr); +} + +void SubresourceFilterBrowserTest::SetUpOnMainThread() { + base::FilePath test_data_dir; + PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir); + embedded_test_server()->ServeFilesFromDirectory(test_data_dir); + host_resolver()->AddSimulatedFailure("host-with-dns-lookup-failure"); + + host_resolver()->AddRule("*", "127.0.0.1"); + content::SetupCrossSiteRedirector(embedded_test_server()); + + // Add content/test/data for cross_site_iframe_factory.html + embedded_test_server()->ServeFilesFromSourceDirectory("content/test/data"); + + ASSERT_TRUE(embedded_test_server()->Start()); + ResetConfigurationToEnableOnPhishingSites(); + + settings_manager_ = SubresourceFilterProfileContextFactory::GetForProfile( + browser()->profile()) + ->settings_manager(); +#if defined(OS_ANDROID) + EXPECT_TRUE(settings_manager->should_use_smart_ui()); +#endif +} + +GURL SubresourceFilterBrowserTest::GetTestUrl( + const std::string& relative_url) const { + return embedded_test_server()->base_url().Resolve(relative_url); +} + +void SubresourceFilterBrowserTest::MarkUrlAsMatchingListWithId( + const GURL& bad_url, + const safe_browsing::ListIdentifier& list_id, + safe_browsing::ThreatPatternType threat_pattern_type) { + safe_browsing::FullHashInfo full_hash_info = + GetFullHashInfoWithMetadata(bad_url, list_id, threat_pattern_type); + v4_db_factory_->MarkPrefixAsBad(list_id, full_hash_info.full_hash); + v4_get_hash_factory_->AddToFullHashCache(full_hash_info); +} + +void SubresourceFilterBrowserTest::ConfigureAsPhishingURL(const GURL& url) { + MarkUrlAsMatchingListWithId(url, safe_browsing::GetUrlSocEngId(), + safe_browsing::ThreatPatternType::NONE); +} + +void SubresourceFilterBrowserTest::ConfigureAsSubresourceFilterOnlyURL( + const GURL& url) { + MarkUrlAsMatchingListWithId(url, safe_browsing::GetUrlSubresourceFilterId(), + safe_browsing::ThreatPatternType::NONE); +} + +content::WebContents* SubresourceFilterBrowserTest::web_contents() const { + return browser()->tab_strip_model()->GetActiveWebContents(); +} + +content::RenderFrameHost* SubresourceFilterBrowserTest::FindFrameByName( + const std::string& name) const { + return content::FrameMatchingPredicate( + web_contents(), base::Bind(&content::FrameMatchesName, name)); +} + +bool SubresourceFilterBrowserTest::WasParsedScriptElementLoaded( + content::RenderFrameHost* rfh) { + DCHECK(rfh); + bool script_resource_was_loaded = false; + EXPECT_TRUE(content::ExecuteScriptAndExtractBool( + rfh, "domAutomationController.send(!!document.scriptExecuted)", + &script_resource_was_loaded)); + return script_resource_was_loaded; +} + +void SubresourceFilterBrowserTest:: + ExpectParsedScriptElementLoadedStatusInFrames( + const std::vector<const char*>& frame_names, + const std::vector<bool>& expect_loaded) { + ASSERT_EQ(expect_loaded.size(), frame_names.size()); + for (size_t i = 0; i < frame_names.size(); ++i) { + SCOPED_TRACE(frame_names[i]); + content::RenderFrameHost* frame = FindFrameByName(frame_names[i]); + ASSERT_TRUE(frame); + ASSERT_EQ(expect_loaded[i], WasParsedScriptElementLoaded(frame)); + } +} + +void SubresourceFilterBrowserTest::ExpectFramesIncludedInLayout( + const std::vector<const char*>& frame_names, + const std::vector<bool>& expect_displayed) { + const char kScript[] = + "window.domAutomationController.send(" + " document.getElementsByName(\"%s\")[0].clientWidth" + ");"; + + ASSERT_EQ(expect_displayed.size(), frame_names.size()); + for (size_t i = 0; i < frame_names.size(); ++i) { + SCOPED_TRACE(frame_names[i]); + int client_width = 0; + EXPECT_TRUE(content::ExecuteScriptAndExtractInt( + web_contents()->GetMainFrame(), + base::StringPrintf(kScript, frame_names[i]), &client_width)); + EXPECT_EQ(expect_displayed[i], !!client_width) << client_width; + } +} + +bool SubresourceFilterBrowserTest::IsDynamicScriptElementLoaded( + content::RenderFrameHost* rfh) { + DCHECK(rfh); + bool script_resource_was_loaded = false; + EXPECT_TRUE(content::ExecuteScriptAndExtractBool( + rfh, "insertScriptElementAndReportSuccess()", + &script_resource_was_loaded)); + return script_resource_was_loaded; +} + +void SubresourceFilterBrowserTest::InsertDynamicFrameWithScript() { + bool frame_was_loaded = false; + ASSERT_TRUE(content::ExecuteScriptAndExtractBool( + web_contents()->GetMainFrame(), "insertFrameWithScriptAndNotify()", + &frame_was_loaded)); + ASSERT_TRUE(frame_was_loaded); +} + +void SubresourceFilterBrowserTest::NavigateFromRendererSide(const GURL& url) { + content::TestNavigationObserver navigation_observer(web_contents(), 1); + ASSERT_TRUE(content::ExecuteScript( + web_contents()->GetMainFrame(), + base::StringPrintf("window.location = \"%s\";", url.spec().c_str()))); + navigation_observer.Wait(); +} + +void SubresourceFilterBrowserTest::NavigateFrame(const char* frame_name, + const GURL& url) { + content::TestNavigationObserver navigation_observer(web_contents(), 1); + ASSERT_TRUE(content::ExecuteScript( + web_contents()->GetMainFrame(), + base::StringPrintf("document.getElementsByName(\"%s\")[0].src = \"%s\";", + frame_name, url.spec().c_str()))); + navigation_observer.Wait(); +} + +void SubresourceFilterBrowserTest::SetRulesetToDisallowURLsWithPathSuffix( + const std::string& suffix) { + TestRulesetPair test_ruleset_pair; + ruleset_creator_.CreateRulesetToDisallowURLsWithPathSuffix( + suffix, &test_ruleset_pair); + ASSERT_NO_FATAL_FAILURE( + test_ruleset_publisher_.SetRuleset(test_ruleset_pair.unindexed)); +} + +void SubresourceFilterBrowserTest::SetRulesetWithRules( + const std::vector<proto::UrlRule>& rules) { + TestRulesetPair test_ruleset_pair; + ruleset_creator_.CreateRulesetWithRules(rules, &test_ruleset_pair); + ASSERT_NO_FATAL_FAILURE( + test_ruleset_publisher_.SetRuleset(test_ruleset_pair.unindexed)); +} + +void SubresourceFilterBrowserTest::ResetConfiguration(Configuration config) { + scoped_configuration_.ResetConfiguration(std::move(config)); +} + +void SubresourceFilterBrowserTest::ResetConfigurationToEnableOnPhishingSites( + bool measure_performance, + bool whitelist_site_on_reload) { + Configuration config = Configuration::MakePresetForLiveRunOnPhishingSites(); + config.activation_options.performance_measurement_rate = + measure_performance ? 1.0 : 0.0; + config.activation_options.should_whitelist_site_on_reload = + whitelist_site_on_reload; + ResetConfiguration(std::move(config)); +} + +} // namespace subresource_filter
diff --git a/chrome/browser/subresource_filter/subresource_filter_browser_test_harness.h b/chrome/browser/subresource_filter/subresource_filter_browser_test_harness.h new file mode 100644 index 0000000..bac4899 --- /dev/null +++ b/chrome/browser/subresource_filter/subresource_filter_browser_test_harness.h
@@ -0,0 +1,123 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_SUBRESOURCE_FILTER_SUBRESOURCE_FILTER_BROWSER_TEST_HARNESS_H_ +#define CHROME_BROWSER_SUBRESOURCE_FILTER_SUBRESOURCE_FILTER_BROWSER_TEST_HARNESS_H_ + +#include <memory> +#include <string> +#include <vector> + +#include "base/macros.h" +#include "chrome/browser/subresource_filter/test_ruleset_publisher.h" +#include "chrome/test/base/in_process_browser_test.h" +#include "components/safe_browsing_db/util.h" +#include "components/subresource_filter/core/browser/subresource_filter_features_test_support.h" +#include "components/subresource_filter/core/common/test_ruleset_creator.h" +#include "components/url_pattern_index/proto/rules.pb.h" +#include "url/gurl.h" + +namespace proto = url_pattern_index::proto; + +using subresource_filter::testing::ScopedSubresourceFilterConfigurator; +using subresource_filter::testing::TestRulesetPublisher; +using subresource_filter::testing::TestRulesetCreator; +using subresource_filter::testing::TestRulesetPair; + +namespace content { +class RenderFrameHost; +class WebContents; +} // namespace content + +namespace safe_browsing { +class ListIdentifier; +class TestSafeBrowsingServiceFactory; +class TestV4DatabaseFactory; +class TestV4GetHashProtocolManagerFactory; +} // namespace safe_browsing + +class SubresourceFilterContentSettingsManager; + +namespace subresource_filter { + +class SubresourceFilterBrowserTest : public InProcessBrowserTest { + public: + SubresourceFilterBrowserTest(); + ~SubresourceFilterBrowserTest() override; + + protected: + // InProcessBrowserTest: + void SetUpCommandLine(base::CommandLine* command_line) override; + void SetUp() override; + void TearDown() override; + void SetUpOnMainThread() override; + + std::vector<base::StringPiece> RequiredFeatures() const; + + GURL GetTestUrl(const std::string& relative_url) const; + + void MarkUrlAsMatchingListWithId( + const GURL& bad_url, + const safe_browsing::ListIdentifier& list_id, + safe_browsing::ThreatPatternType threat_pattern_type); + + void ConfigureAsPhishingURL(const GURL& url); + + void ConfigureAsSubresourceFilterOnlyURL(const GURL& url); + + content::WebContents* web_contents() const; + + SubresourceFilterContentSettingsManager* settings_manager() const { + return settings_manager_; + } + + content::RenderFrameHost* FindFrameByName(const std::string& name) const; + + bool WasParsedScriptElementLoaded(content::RenderFrameHost* rfh); + + void ExpectParsedScriptElementLoadedStatusInFrames( + const std::vector<const char*>& frame_names, + const std::vector<bool>& expect_loaded); + + void ExpectFramesIncludedInLayout(const std::vector<const char*>& frame_names, + const std::vector<bool>& expect_displayed); + + bool IsDynamicScriptElementLoaded(content::RenderFrameHost* rfh); + + void InsertDynamicFrameWithScript(); + + void NavigateFromRendererSide(const GURL& url); + + void NavigateFrame(const char* frame_name, const GURL& url); + + void SetRulesetToDisallowURLsWithPathSuffix(const std::string& suffix); + + void SetRulesetWithRules(const std::vector<proto::UrlRule>& rules); + + void ResetConfiguration(Configuration config); + + void ResetConfigurationToEnableOnPhishingSites( + bool measure_performance = false, + bool whitelist_site_on_reload = false); + + private: + TestRulesetCreator ruleset_creator_; + ScopedSubresourceFilterConfigurator scoped_configuration_; + TestRulesetPublisher test_ruleset_publisher_; + + std::unique_ptr<safe_browsing::TestSafeBrowsingServiceFactory> sb_factory_; + // Owned by the V4Database. + safe_browsing::TestV4DatabaseFactory* v4_db_factory_; + // Owned by the V4GetHashProtocolManager. + safe_browsing::TestV4GetHashProtocolManagerFactory* v4_get_hash_factory_; + + // Owned by the profile. + SubresourceFilterContentSettingsManager* settings_manager_; + + DISALLOW_COPY_AND_ASSIGN(SubresourceFilterBrowserTest); +}; + +} // namespace subresource_filter + +#endif // CHROME_BROWSER_SUBRESOURCE_FILTER_SUBRESOURCE_FILTER_BROWSER_TEST_HARNESS_H_
diff --git a/chrome/browser/subresource_filter/subresource_filter_browsertest.cc b/chrome/browser/subresource_filter/subresource_filter_browsertest.cc index ef15b79..6c2df7e5 100644 --- a/chrome/browser/subresource_filter/subresource_filter_browsertest.cc +++ b/chrome/browser/subresource_filter/subresource_filter_browsertest.cc
@@ -7,35 +7,27 @@ #include <sstream> #include <string> +#include "chrome/browser/subresource_filter/subresource_filter_browser_test_harness.h" + #include "base/bind.h" -#include "base/bind_helpers.h" #include "base/command_line.h" -#include "base/files/file_path.h" #include "base/json/json_string_value_serializer.h" #include "base/location.h" #include "base/macros.h" #include "base/memory/ptr_util.h" #include "base/memory/ref_counted.h" -#include "base/path_service.h" #include "base/strings/pattern.h" -#include "base/strings/string16.h" #include "base/strings/string_piece.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "base/test/histogram_tester.h" -#include "base/test/simple_test_clock.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/content_settings/host_content_settings_map_factory.h" -#include "chrome/browser/content_settings/tab_specific_content_settings.h" #include "chrome/browser/metrics/subprocess_metrics_provider.h" #include "chrome/browser/page_load_metrics/observers/subresource_filter_metrics_observer.h" #include "chrome/browser/safe_browsing/test_safe_browsing_service.h" #include "chrome/browser/safe_browsing/v4_test_utils.h" #include "chrome/browser/subresource_filter/chrome_subresource_filter_client.h" -#include "chrome/browser/subresource_filter/subresource_filter_content_settings_manager.h" -#include "chrome/browser/subresource_filter/subresource_filter_profile_context.h" -#include "chrome/browser/subresource_filter/subresource_filter_profile_context_factory.h" #include "chrome/browser/subresource_filter/test_ruleset_publisher.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_commands.h" @@ -44,18 +36,11 @@ #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/url_constants.h" -#include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" -#include "components/content_settings/core/browser/host_content_settings_map.h" -#include "components/content_settings/core/common/content_settings.h" -#include "components/safe_browsing_db/test_database_manager.h" -#include "components/safe_browsing_db/util.h" -#include "components/safe_browsing_db/v4_database.h" #include "components/security_interstitials/content/unsafe_resource.h" #include "components/subresource_filter/content/browser/async_document_subresource_filter.h" #include "components/subresource_filter/content/browser/async_document_subresource_filter_test_utils.h" #include "components/subresource_filter/content/browser/content_ruleset_service.h" -#include "components/subresource_filter/content/browser/content_subresource_filter_driver_factory.h" #include "components/subresource_filter/core/browser/subresource_filter_constants.h" #include "components/subresource_filter/core/browser/subresource_filter_features.h" #include "components/subresource_filter/core/browser/subresource_filter_features_test_support.h" @@ -66,7 +51,6 @@ #include "components/subresource_filter/core/common/test_ruleset_creator.h" #include "components/subresource_filter/core/common/test_ruleset_utils.h" #include "components/url_pattern_index/proto/rules.pb.h" -#include "content/public/browser/browser_thread.h" #include "content/public/browser/devtools_agent_host.h" #include "content/public/browser/devtools_agent_host_client.h" #include "content/public/browser/notification_service.h" @@ -78,13 +62,11 @@ #include "content/public/common/content_features.h" #include "content/public/common/content_switches.h" #include "content/public/common/referrer.h" +#include "content/public/test/browser_test.h" #include "content/public/test/browser_test_utils.h" #include "content/public/test/test_navigation_observer.h" #include "content/public/test/test_utils.h" -#include "net/dns/mock_host_resolver.h" #include "net/test/embedded_test_server/embedded_test_server.h" -#include "net/test/spawned_test_server/spawned_test_server.h" -#include "net/test/test_data_directory.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" @@ -151,25 +133,6 @@ // Other histograms. const char kSubresourceFilterActionsHistogram[] = "SubresourceFilter.Actions"; -// UI manager that never actually shows any interstitials, but emulates as if -// the user chose to proceed through them. -class FakeSafeBrowsingUIManager - : public safe_browsing::TestSafeBrowsingUIManager { - public: - FakeSafeBrowsingUIManager() {} - - protected: - ~FakeSafeBrowsingUIManager() override {} - - void DisplayBlockingPage(const UnsafeResource& resource) override { - resource.callback_thread->PostTask( - FROM_HERE, base::Bind(resource.callback, true /* proceed */)); - } - - private: - DISALLOW_COPY_AND_ASSIGN(FakeSafeBrowsingUIManager); -}; - GURL GetURLWithFragment(const GURL& url, base::StringPiece fragment) { GURL::Replacements replacements; replacements.SetRefStr(fragment); @@ -190,8 +153,6 @@ namespace subresource_filter { -using subresource_filter::testing::ScopedSubresourceFilterConfigurator; -using subresource_filter::testing::TestRulesetPublisher; using subresource_filter::testing::TestRulesetCreator; using subresource_filter::testing::TestRulesetPair; @@ -212,6 +173,8 @@ DISALLOW_COPY_AND_ASSIGN(SubresourceFilterDisabledByDefaultBrowserTest); }; +// Tests ----------------------------------------------------------------------- + // The RulesetService should not even be instantiated when the feature is // disabled, which should be the default state unless there is an override // specified in the field trial configuration. @@ -220,314 +183,6 @@ EXPECT_FALSE(g_browser_process->subresource_filter_ruleset_service()); } -// SubresourceFilterBrowserTest ----------------------------------------------- - -class SubresourceFilterBrowserTest : public InProcessBrowserTest { - public: - SubresourceFilterBrowserTest() {} - ~SubresourceFilterBrowserTest() override {} - - protected: - void SetUpCommandLine(base::CommandLine* command_line) override { - command_line->AppendSwitchASCII(switches::kEnableFeatures, - base::JoinString(RequiredFeatures(), ",")); - } - - std::vector<base::StringPiece> RequiredFeatures() const { - return {kSafeBrowsingSubresourceFilter.name, "SafeBrowsingV4OnlyEnabled", - kSafeBrowsingSubresourceFilterExperimentalUI.name}; - } - - void SetUp() override { - sb_factory_ = - base::MakeUnique<safe_browsing::TestSafeBrowsingServiceFactory>( - safe_browsing::V4FeatureList::V4UsageStatus::V4_ONLY); - sb_factory_->SetTestUIManager(new FakeSafeBrowsingUIManager()); - safe_browsing::SafeBrowsingService::RegisterFactory(sb_factory_.get()); - - safe_browsing::V4Database::RegisterStoreFactoryForTest( - base::WrapUnique(new safe_browsing::TestV4StoreFactory())); - - v4_db_factory_ = new safe_browsing::TestV4DatabaseFactory(); - safe_browsing::V4Database::RegisterDatabaseFactoryForTest( - base::WrapUnique(v4_db_factory_)); - - v4_get_hash_factory_ = - new safe_browsing::TestV4GetHashProtocolManagerFactory(); - safe_browsing::V4GetHashProtocolManager::RegisterFactory( - base::WrapUnique(v4_get_hash_factory_)); - InProcessBrowserTest::SetUp(); - } - - void TearDown() override { - InProcessBrowserTest::TearDown(); - // Unregister test factories after InProcessBrowserTest::TearDown - // (which destructs SafeBrowsingService). - safe_browsing::V4GetHashProtocolManager::RegisterFactory(nullptr); - safe_browsing::V4Database::RegisterDatabaseFactoryForTest(nullptr); - safe_browsing::V4Database::RegisterStoreFactoryForTest(nullptr); - safe_browsing::SafeBrowsingService::RegisterFactory(nullptr); - } - - void SetUpOnMainThread() override { - base::FilePath test_data_dir; - PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir); - embedded_test_server()->ServeFilesFromDirectory(test_data_dir); - host_resolver()->AddSimulatedFailure("host-with-dns-lookup-failure"); - - host_resolver()->AddRule("*", "127.0.0.1"); - content::SetupCrossSiteRedirector(embedded_test_server()); - - // Add content/test/data for cross_site_iframe_factory.html - embedded_test_server()->ServeFilesFromSourceDirectory("content/test/data"); - - ASSERT_TRUE(embedded_test_server()->Start()); - ResetConfigurationToEnableOnPhishingSites(); - - settings_manager_ = SubresourceFilterProfileContextFactory::GetForProfile( - browser()->profile()) - ->settings_manager(); -#if defined(OS_ANDROID) - EXPECT_TRUE(settings_manager->should_use_smart_ui()); -#endif - } - - GURL GetTestUrl(const std::string& relative_url) { - return embedded_test_server()->base_url().Resolve(relative_url); - } - - void MarkUrlAsMatchingListWithId( - const GURL& bad_url, - const safe_browsing::ListIdentifier& list_id, - safe_browsing::ThreatPatternType threat_pattern_type) { - safe_browsing::FullHashInfo full_hash_info = - GetFullHashInfoWithMetadata(bad_url, list_id, threat_pattern_type); - v4_db_factory_->MarkPrefixAsBad(list_id, full_hash_info.full_hash); - v4_get_hash_factory_->AddToFullHashCache(full_hash_info); - } - - void ConfigureAsPhishingURL(const GURL& url) { - MarkUrlAsMatchingListWithId(url, safe_browsing::GetUrlSocEngId(), - safe_browsing::ThreatPatternType::NONE); - } - - void ConfigureAsSubresourceFilterOnlyURL(const GURL& url) { - MarkUrlAsMatchingListWithId(url, safe_browsing::GetUrlSubresourceFilterId(), - safe_browsing::ThreatPatternType::NONE); - } - - content::WebContents* web_contents() { - return browser()->tab_strip_model()->GetActiveWebContents(); - } - - SubresourceFilterContentSettingsManager* settings_manager() { - return settings_manager_; - } - - content::RenderFrameHost* FindFrameByName(const std::string& name) { - return content::FrameMatchingPredicate( - web_contents(), base::Bind(&content::FrameMatchesName, name)); - } - - bool WasParsedScriptElementLoaded(content::RenderFrameHost* rfh) { - DCHECK(rfh); - bool script_resource_was_loaded = false; - EXPECT_TRUE(content::ExecuteScriptAndExtractBool( - rfh, "domAutomationController.send(!!document.scriptExecuted)", - &script_resource_was_loaded)); - return script_resource_was_loaded; - } - - void ExpectParsedScriptElementLoadedStatusInFrames( - const std::vector<const char*>& frame_names, - const std::vector<bool>& expect_loaded) { - ASSERT_EQ(expect_loaded.size(), frame_names.size()); - for (size_t i = 0; i < frame_names.size(); ++i) { - SCOPED_TRACE(frame_names[i]); - content::RenderFrameHost* frame = FindFrameByName(frame_names[i]); - ASSERT_TRUE(frame); - ASSERT_EQ(expect_loaded[i], WasParsedScriptElementLoaded(frame)); - } - } - - void ExpectFramesIncludedInLayout(const std::vector<const char*>& frame_names, - const std::vector<bool>& expect_displayed) { - const char kScript[] = - "window.domAutomationController.send(" - " document.getElementsByName(\"%s\")[0].clientWidth" - ");"; - - ASSERT_EQ(expect_displayed.size(), frame_names.size()); - for (size_t i = 0; i < frame_names.size(); ++i) { - SCOPED_TRACE(frame_names[i]); - int client_width = 0; - EXPECT_TRUE(content::ExecuteScriptAndExtractInt( - web_contents()->GetMainFrame(), - base::StringPrintf(kScript, frame_names[i]), &client_width)); - EXPECT_EQ(expect_displayed[i], !!client_width) << client_width; - } - } - - bool IsDynamicScriptElementLoaded(content::RenderFrameHost* rfh) { - DCHECK(rfh); - bool script_resource_was_loaded = false; - EXPECT_TRUE(content::ExecuteScriptAndExtractBool( - rfh, "insertScriptElementAndReportSuccess()", - &script_resource_was_loaded)); - return script_resource_was_loaded; - } - - void InsertDynamicFrameWithScript() { - bool frame_was_loaded = false; - ASSERT_TRUE(content::ExecuteScriptAndExtractBool( - web_contents()->GetMainFrame(), "insertFrameWithScriptAndNotify()", - &frame_was_loaded)); - ASSERT_TRUE(frame_was_loaded); - } - - void NavigateFromRendererSide(const GURL& url) { - content::TestNavigationObserver navigation_observer(web_contents(), 1); - ASSERT_TRUE(content::ExecuteScript( - web_contents()->GetMainFrame(), - base::StringPrintf("window.location = \"%s\";", url.spec().c_str()))); - navigation_observer.Wait(); - } - - void NavigateFrame(const char* frame_name, const GURL& url) { - content::TestNavigationObserver navigation_observer(web_contents(), 1); - ASSERT_TRUE(content::ExecuteScript( - web_contents()->GetMainFrame(), - base::StringPrintf( - "document.getElementsByName(\"%s\")[0].src = \"%s\";", frame_name, - url.spec().c_str()))); - navigation_observer.Wait(); - } - - void SetRulesetToDisallowURLsWithPathSuffix(const std::string& suffix) { - TestRulesetPair test_ruleset_pair; - ruleset_creator_.CreateRulesetToDisallowURLsWithPathSuffix( - suffix, &test_ruleset_pair); - ASSERT_NO_FATAL_FAILURE( - test_ruleset_publisher_.SetRuleset(test_ruleset_pair.unindexed)); - } - - void SetRulesetWithRules(const std::vector<proto::UrlRule>& rules) { - TestRulesetPair test_ruleset_pair; - ruleset_creator_.CreateRulesetWithRules(rules, &test_ruleset_pair); - ASSERT_NO_FATAL_FAILURE( - test_ruleset_publisher_.SetRuleset(test_ruleset_pair.unindexed)); - } - - void ResetConfiguration(Configuration config) { - scoped_configuration_.ResetConfiguration(std::move(config)); - } - - void ResetConfigurationToEnableOnPhishingSites( - bool measure_performance = false, - bool whitelist_site_on_reload = false) { - Configuration config = Configuration::MakePresetForLiveRunOnPhishingSites(); - config.activation_options.performance_measurement_rate = - measure_performance ? 1.0 : 0.0; - config.activation_options.should_whitelist_site_on_reload = - whitelist_site_on_reload; - ResetConfiguration(std::move(config)); - } - - private: - TestRulesetCreator ruleset_creator_; - ScopedSubresourceFilterConfigurator scoped_configuration_; - TestRulesetPublisher test_ruleset_publisher_; - - std::unique_ptr<safe_browsing::TestSafeBrowsingServiceFactory> sb_factory_; - // Owned by the V4Database. - safe_browsing::TestV4DatabaseFactory* v4_db_factory_; - // Owned by the V4GetHashProtocolManager. - safe_browsing::TestV4GetHashProtocolManagerFactory* v4_get_hash_factory_; - - // Owned by the profile. - SubresourceFilterContentSettingsManager* settings_manager_; - - DISALLOW_COPY_AND_ASSIGN(SubresourceFilterBrowserTest); -}; - -enum WebSocketCreationPolicy { - IN_MAIN_FRAME, - IN_WORKER, -}; -class SubresourceFilterWebSocketBrowserTest - : public SubresourceFilterBrowserTest, - public ::testing::WithParamInterface<WebSocketCreationPolicy> { - public: - SubresourceFilterWebSocketBrowserTest() {} - - void SetUpOnMainThread() override { - SubresourceFilterBrowserTest::SetUpOnMainThread(); - websocket_test_server_ = base::MakeUnique<net::SpawnedTestServer>( - net::SpawnedTestServer::TYPE_WS, net::GetWebSocketTestDataDirectory()); - ASSERT_TRUE(websocket_test_server_->Start()); - } - - net::SpawnedTestServer* websocket_test_server() { - return websocket_test_server_.get(); - } - - GURL GetWebSocketUrl(const std::string& path) { - GURL::Replacements replacements; - replacements.SetSchemeStr("ws"); - return websocket_test_server_->GetURL(path).ReplaceComponents(replacements); - } - - void CreateWebSocketAndExpectResult(const GURL& url, - bool expect_connection_success) { - bool websocket_connection_succeeded = false; - EXPECT_TRUE(content::ExecuteScriptAndExtractBool( - browser()->tab_strip_model()->GetActiveWebContents(), - base::StringPrintf("connectWebSocket('%s');", url.spec().c_str()), - &websocket_connection_succeeded)); - EXPECT_EQ(expect_connection_success, websocket_connection_succeeded); - } - - private: - std::unique_ptr<net::SpawnedTestServer> websocket_test_server_; -}; - -enum class OffMainThreadFetchPolicy { - kEnabled, - kDisabled, -}; - -class SubresourceFilterWorkerFetchBrowserTest - : public SubresourceFilterBrowserTest, - public ::testing::WithParamInterface<OffMainThreadFetchPolicy> { - public: - SubresourceFilterWorkerFetchBrowserTest() {} - ~SubresourceFilterWorkerFetchBrowserTest() override {} - - protected: - void SetUpCommandLine(base::CommandLine* command_line) override { - std::vector<base::StringPiece> features = - SubresourceFilterBrowserTest::RequiredFeatures(); - if (GetParam() == OffMainThreadFetchPolicy::kEnabled) { - features.push_back(features::kOffMainThreadFetch.name); - } else { - command_line->AppendSwitchASCII(switches::kDisableFeatures, - features::kOffMainThreadFetch.name); - } - command_line->AppendSwitchASCII(switches::kEnableFeatures, - base::JoinString(features, ",")); - } - - void ClearTitle() { - ASSERT_TRUE(content::ExecuteScript(web_contents()->GetMainFrame(), - "document.title = \"\";")); - } - - private: - DISALLOW_COPY_AND_ASSIGN(SubresourceFilterWorkerFetchBrowserTest); -}; - -// Tests ----------------------------------------------------------------------- - IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest, MainFrameActivation) { content::ConsoleObserverDelegate console_observer(web_contents(), kActivationConsoleMessage); @@ -1206,413 +861,6 @@ EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame())); } -IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest, - NoConfiguration_AllowCreatingNewWindows) { - base::HistogramTester tester; - const char kWindowOpenPath[] = "/subresource_filter/window_open.html"; - GURL a_url(embedded_test_server()->GetURL("a.com", kWindowOpenPath)); - // Only configure |a_url| as a phishing URL. - ConfigureAsPhishingURL(a_url); - - // Only necessary so we have a valid ruleset. - ASSERT_NO_FATAL_FAILURE(SetRulesetWithRules(std::vector<proto::UrlRule>())); - - // Navigate to a_url, should not trigger the popup blocker. - ui_test_utils::NavigateToURL(browser(), a_url); - bool opened_window = false; - content::WebContents* web_contents = - browser()->tab_strip_model()->GetActiveWebContents(); - EXPECT_TRUE(content::ExecuteScriptAndExtractBool(web_contents, "openWindow()", - &opened_window)); - EXPECT_TRUE(opened_window); - EXPECT_FALSE(TabSpecificContentSettings::FromWebContents(web_contents) - ->IsContentBlocked(CONTENT_SETTINGS_TYPE_POPUPS)); -} - -IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest, BlockCreatingNewWindows) { - Configuration config = Configuration::MakePresetForLiveRunOnPhishingSites(); - config.activation_options.should_strengthen_popup_blocker = true; - ResetConfiguration(std::move(config)); - base::HistogramTester tester; - const char kWindowOpenPath[] = "/subresource_filter/window_open.html"; - GURL a_url(embedded_test_server()->GetURL("a.com", kWindowOpenPath)); - GURL b_url(embedded_test_server()->GetURL("b.com", kWindowOpenPath)); - // Only configure |a_url| as a phishing URL. - ConfigureAsPhishingURL(a_url); - - // Only necessary so we have a valid ruleset. - ASSERT_NO_FATAL_FAILURE(SetRulesetWithRules(std::vector<proto::UrlRule>())); - - // Navigate to a_url, should trigger the popup blocker. - ui_test_utils::NavigateToURL(browser(), a_url); - bool opened_window = false; - content::WebContents* web_contents = - browser()->tab_strip_model()->GetActiveWebContents(); - EXPECT_TRUE(content::ExecuteScriptAndExtractBool(web_contents, "openWindow()", - &opened_window)); - EXPECT_FALSE(opened_window); - tester.ExpectBucketCount(kSubresourceFilterActionsHistogram, kActionUIShown, - 1); - // Make sure the popup UI was shown. - EXPECT_TRUE(TabSpecificContentSettings::FromWebContents(web_contents) - ->IsContentBlocked(CONTENT_SETTINGS_TYPE_POPUPS)); - - // Navigate to |b_url|, which should successfully open the popup. - ui_test_utils::NavigateToURL(browser(), b_url); - opened_window = false; - EXPECT_TRUE(content::ExecuteScriptAndExtractBool(web_contents, "openWindow()", - &opened_window)); - EXPECT_TRUE(opened_window); - // Popup UI should not be shown. - EXPECT_FALSE(TabSpecificContentSettings::FromWebContents(web_contents) - ->IsContentBlocked(CONTENT_SETTINGS_TYPE_POPUPS)); -} - -IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest, BlockOpenURLFromTab) { - Configuration config = Configuration::MakePresetForLiveRunOnPhishingSites(); - config.activation_options.should_strengthen_popup_blocker = true; - ResetConfiguration(std::move(config)); - base::HistogramTester tester; - const char kWindowOpenPath[] = - "/subresource_filter/window_open_spoof_click.html"; - GURL a_url(embedded_test_server()->GetURL("a.com", kWindowOpenPath)); - GURL b_url(embedded_test_server()->GetURL("b.com", kWindowOpenPath)); - // Only configure |a_url| as a phishing URL. - ConfigureAsPhishingURL(a_url); - - // Only necessary so we have a valid ruleset. - ASSERT_NO_FATAL_FAILURE(SetRulesetWithRules(std::vector<proto::UrlRule>())); - - // Navigate to a_url, should trigger the popup blocker. - ui_test_utils::NavigateToURL(browser(), a_url); - - content::WebContents* web_contents = - browser()->tab_strip_model()->GetActiveWebContents(); - EXPECT_TRUE(content::ExecuteScript(web_contents, "openWindow()")); - tester.ExpectBucketCount(kSubresourceFilterActionsHistogram, kActionUIShown, - 1); - - EXPECT_TRUE(TabSpecificContentSettings::FromWebContents(web_contents) - ->IsContentBlocked(CONTENT_SETTINGS_TYPE_POPUPS)); - - // Navigate to |b_url|, which should successfully open the popup. - - ui_test_utils::NavigateToURL(browser(), b_url); - - content::TestNavigationObserver navigation_observer(nullptr, 1); - navigation_observer.StartWatchingNewWebContents(); - EXPECT_TRUE(content::ExecuteScript(web_contents, "openWindow()")); - navigation_observer.Wait(); - - // Popup UI should not be shown. - EXPECT_FALSE(TabSpecificContentSettings::FromWebContents(web_contents) - ->IsContentBlocked(CONTENT_SETTINGS_TYPE_POPUPS)); -} - -IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest, - BlockOpenURLFromTabInIframe) { - Configuration config = Configuration::MakePresetForLiveRunOnPhishingSites(); - config.activation_options.should_strengthen_popup_blocker = true; - ResetConfiguration(std::move(config)); - const char popup_path[] = "/subresource_filter/iframe_spoof_click_popup.html"; - GURL a_url(embedded_test_server()->GetURL("a.com", popup_path)); - // Only configure |a_url| as a phishing URL. - ConfigureAsPhishingURL(a_url); - - // Only necessary so we have a valid ruleset. - ASSERT_NO_FATAL_FAILURE(SetRulesetWithRules(std::vector<proto::UrlRule>())); - - // Navigate to a_url, should not trigger the popup blocker. - ui_test_utils::NavigateToURL(browser(), a_url); - bool sent_open = false; - content::WebContents* web_contents = - browser()->tab_strip_model()->GetActiveWebContents(); - EXPECT_TRUE(content::ExecuteScriptAndExtractBool(web_contents, "openWindow()", - &sent_open)); - EXPECT_TRUE(sent_open); - EXPECT_TRUE(TabSpecificContentSettings::FromWebContents(web_contents) - ->IsContentBlocked(CONTENT_SETTINGS_TYPE_POPUPS)); -} - -IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest, - TraditionalWindowOpen_NotBlocked) { - Configuration config = Configuration::MakePresetForLiveRunOnPhishingSites(); - config.activation_options.should_strengthen_popup_blocker = true; - ResetConfiguration(std::move(config)); - GURL url(GetTestUrl("/title2.html")); - ConfigureAsPhishingURL(url); - ui_test_utils::NavigateToURL(browser(), GetTestUrl("/title1.html")); - - // Only necessary so we have a valid ruleset. - ASSERT_NO_FATAL_FAILURE(SetRulesetWithRules(std::vector<proto::UrlRule>())); - - // Should not trigger the popup blocker because internally opens the tab with - // a user gesture. - ui_test_utils::NavigateToURLWithDisposition( - browser(), url, WindowOpenDisposition::NEW_FOREGROUND_TAB, - ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); - - content::WebContents* web_contents = - browser()->tab_strip_model()->GetActiveWebContents(); - EXPECT_FALSE(TabSpecificContentSettings::FromWebContents(web_contents) - ->IsContentBlocked(CONTENT_SETTINGS_TYPE_POPUPS)); -} - -IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest, - ContentSettingsWhitelist_DoNotActivate) { - ASSERT_NO_FATAL_FAILURE( - SetRulesetToDisallowURLsWithPathSuffix("included_script.js")); - GURL url(GetTestUrl("subresource_filter/frame_with_included_script.html")); - ConfigureAsPhishingURL(url); - - ui_test_utils::NavigateToURL(browser(), url); - EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame())); - - content::ConsoleObserverDelegate console_observer(web_contents(), - kActivationConsoleMessage); - web_contents()->SetDelegate(&console_observer); - - // Simulate an explicity whitelisting via content settings. - HostContentSettingsMap* settings_map = - HostContentSettingsMapFactory::GetForProfile(browser()->profile()); - settings_map->SetContentSettingDefaultScope( - url, url, ContentSettingsType::CONTENT_SETTINGS_TYPE_ADS, std::string(), - CONTENT_SETTING_ALLOW); - - ui_test_utils::NavigateToURL(browser(), url); - EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame())); - - // No message for whitelisted url. - EXPECT_TRUE(console_observer.message().empty()); -} - -IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest, - ContentSettingsAllowWithNoPageActivation_DoNotActivate) { - ASSERT_NO_FATAL_FAILURE( - SetRulesetToDisallowURLsWithPathSuffix("included_script.js")); - GURL url(GetTestUrl("subresource_filter/frame_with_included_script.html")); - - // Do not configure as phishing URL. - - ui_test_utils::NavigateToURL(browser(), url); - EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame())); - - // Simulate allowing the subresource filter via content settings. - HostContentSettingsMap* settings_map = - HostContentSettingsMapFactory::GetForProfile(browser()->profile()); - settings_map->SetContentSettingDefaultScope( - url, url, ContentSettingsType::CONTENT_SETTINGS_TYPE_ADS, std::string(), - CONTENT_SETTING_BLOCK); - - // Setting the site to "allow" should not activate filtering. - ui_test_utils::NavigateToURL(browser(), url); - EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame())); -} - -IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest, - ContentSettingsWhitelistViaReload_DoNotActivate) { - ASSERT_NO_FATAL_FAILURE( - SetRulesetToDisallowURLsWithPathSuffix("included_script.js")); - GURL url(GetTestUrl("subresource_filter/frame_with_included_script.html")); - ConfigureAsPhishingURL(url); - - ui_test_utils::NavigateToURL(browser(), url); - EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame())); - - // Whitelist via a reload. - content::TestNavigationObserver navigation_observer(web_contents(), 1); - ChromeSubresourceFilterClient::FromWebContents(web_contents()) - ->OnReloadRequested(); - navigation_observer.Wait(); - - EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame())); -} - -IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest, - ContentSettingsWhitelistViaReload_WhitelistIsByDomain) { - ASSERT_NO_FATAL_FAILURE( - SetRulesetToDisallowURLsWithPathSuffix("included_script.js")); - GURL url(GetTestUrl("subresource_filter/frame_with_included_script.html")); - ConfigureAsPhishingURL(url); - - ui_test_utils::NavigateToURL(browser(), url); - EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame())); - - // Whitelist via a reload. - content::TestNavigationObserver navigation_observer(web_contents(), 1); - ChromeSubresourceFilterClient::FromWebContents(web_contents()) - ->OnReloadRequested(); - navigation_observer.Wait(); - - EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame())); - - // Another navigation to the same domain should be whitelisted too. - ui_test_utils::NavigateToURL( - browser(), - GetTestUrl("subresource_filter/frame_with_included_script.html?query")); - EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame())); - - // A cross site blacklisted navigation should stay activated, however. - GURL a_url(embedded_test_server()->GetURL( - "a.com", "/subresource_filter/frame_with_included_script.html")); - ConfigureAsPhishingURL(a_url); - ui_test_utils::NavigateToURL(browser(), a_url); - EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame())); -} - -// Test the "smart" UI, aka the logic to hide the UI on subsequent same-domain -// navigations, until a certain time threshold has been reached. This is an -// android-only feature. -IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest, - DoNotShowUIUntilThresholdReached) { - ASSERT_NO_FATAL_FAILURE( - SetRulesetToDisallowURLsWithPathSuffix("included_script.js")); - GURL a_url(embedded_test_server()->GetURL( - "a.com", "/subresource_filter/frame_with_included_script.html")); - GURL b_url(embedded_test_server()->GetURL( - "b.com", "/subresource_filter/frame_with_included_script.html")); - // Test utils only support one blacklisted site at a time. - // TODO(csharrison): Add support for more than one URL. - ConfigureAsPhishingURL(a_url); - - ChromeSubresourceFilterClient* client = - ChromeSubresourceFilterClient::FromWebContents(web_contents()); - auto test_clock = base::MakeUnique<base::SimpleTestClock>(); - base::SimpleTestClock* raw_clock = test_clock.get(); - settings_manager()->set_clock_for_testing(std::move(test_clock)); - - base::HistogramTester histogram_tester; - - // First load should trigger the UI. - ui_test_utils::NavigateToURL(browser(), a_url); - EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame())); - EXPECT_TRUE(client->did_show_ui_for_navigation()); - - histogram_tester.ExpectBucketCount(kSubresourceFilterActionsHistogram, - kActionUISuppressed, 0); - - // Second load should not trigger the UI, but should still filter content. - ui_test_utils::NavigateToURL(browser(), a_url); - EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame())); - - bool use_smart_ui = settings_manager()->should_use_smart_ui(); - EXPECT_EQ(client->did_show_ui_for_navigation(), !use_smart_ui); - - histogram_tester.ExpectBucketCount(kSubresourceFilterActionsHistogram, - kActionUISuppressed, use_smart_ui ? 1 : 0); - - ConfigureAsPhishingURL(b_url); - - // Load to another domain should trigger the UI. - ui_test_utils::NavigateToURL(browser(), b_url); - EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame())); - EXPECT_TRUE(client->did_show_ui_for_navigation()); - - ConfigureAsPhishingURL(a_url); - - // Fast forward the clock, and a_url should trigger the UI again. - raw_clock->Advance( - SubresourceFilterContentSettingsManager::kDelayBeforeShowingInfobarAgain); - ui_test_utils::NavigateToURL(browser(), a_url); - EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame())); - EXPECT_TRUE(client->did_show_ui_for_navigation()); - - histogram_tester.ExpectBucketCount(kSubresourceFilterActionsHistogram, - kActionUISuppressed, use_smart_ui ? 1 : 0); -} - -IN_PROC_BROWSER_TEST_P(SubresourceFilterWebSocketBrowserTest, BlockWebSocket) { - GURL url(GetTestUrl( - base::StringPrintf("subresource_filter/page_with_websocket.html?%s", - GetParam() == IN_WORKER ? "inWorker" : ""))); - GURL websocket_url(GetWebSocketUrl("echo-with-no-extension")); - ConfigureAsPhishingURL(url); - ASSERT_NO_FATAL_FAILURE( - SetRulesetToDisallowURLsWithPathSuffix("echo-with-no-extension")); - ui_test_utils::NavigateToURL(browser(), url); - CreateWebSocketAndExpectResult(websocket_url, - false /* expect_connection_success */); -} - -IN_PROC_BROWSER_TEST_P(SubresourceFilterWebSocketBrowserTest, - DoNotBlockWebSocketNoActivatedFrame) { - GURL url(GetTestUrl( - base::StringPrintf("subresource_filter/page_with_websocket.html?%s", - GetParam() == IN_WORKER ? "inWorker" : ""))); - GURL websocket_url(GetWebSocketUrl("echo-with-no-extension")); - ASSERT_NO_FATAL_FAILURE( - SetRulesetToDisallowURLsWithPathSuffix("echo-with-no-extension")); - ui_test_utils::NavigateToURL(browser(), url); - - CreateWebSocketAndExpectResult(websocket_url, - true /* expect_connection_success */); -} - -IN_PROC_BROWSER_TEST_P(SubresourceFilterWebSocketBrowserTest, - DoNotBlockWebSocketInActivatedFrameWithNoRule) { - GURL url(GetTestUrl( - base::StringPrintf("subresource_filter/page_with_websocket.html?%s", - GetParam() == IN_WORKER ? "inWorker" : ""))); - GURL websocket_url(GetWebSocketUrl("echo-with-no-extension")); - ConfigureAsPhishingURL(url); - ui_test_utils::NavigateToURL(browser(), url); - - CreateWebSocketAndExpectResult(websocket_url, - true /* expect_connection_success */); -} - -INSTANTIATE_TEST_CASE_P( - /* no prefix */, - SubresourceFilterWebSocketBrowserTest, - ::testing::Values(WebSocketCreationPolicy::IN_WORKER, - WebSocketCreationPolicy::IN_MAIN_FRAME)); - -IN_PROC_BROWSER_TEST_P(SubresourceFilterWorkerFetchBrowserTest, WorkerFetch) { - const base::string16 fetch_succeeded_title = - base::ASCIIToUTF16("FetchSucceeded"); - const base::string16 fetch_failed_title = base::ASCIIToUTF16("FetchFailed"); - GURL url(GetTestUrl("subresource_filter/worker_fetch.html")); - ConfigureAsPhishingURL(url); - - ASSERT_NO_FATAL_FAILURE(SetRulesetToDisallowURLsWithPathSuffix( - "suffix-that-does-not-match-anything")); - { - content::TitleWatcher title_watcher( - browser()->tab_strip_model()->GetActiveWebContents(), - fetch_succeeded_title); - title_watcher.AlsoWaitForTitle(fetch_failed_title); - ui_test_utils::NavigateToURL(browser(), url); - EXPECT_EQ(fetch_succeeded_title, title_watcher.WaitAndGetTitle()); - } - ClearTitle(); - ASSERT_NO_FATAL_FAILURE( - SetRulesetToDisallowURLsWithPathSuffix("worker_fetch_data.txt")); - { - content::TitleWatcher title_watcher( - browser()->tab_strip_model()->GetActiveWebContents(), - fetch_succeeded_title); - title_watcher.AlsoWaitForTitle(fetch_failed_title); - ui_test_utils::NavigateToURL(browser(), url); - EXPECT_EQ(fetch_failed_title, title_watcher.WaitAndGetTitle()); - } - ClearTitle(); - // The main frame document should never be filtered. - SetRulesetToDisallowURLsWithPathSuffix("worker_fetch.html"); - { - content::TitleWatcher title_watcher( - browser()->tab_strip_model()->GetActiveWebContents(), - fetch_succeeded_title); - title_watcher.AlsoWaitForTitle(fetch_failed_title); - ui_test_utils::NavigateToURL(browser(), url); - EXPECT_EQ(fetch_succeeded_title, title_watcher.WaitAndGetTitle()); - } -} - -INSTANTIATE_TEST_CASE_P(/* no prefix */, - SubresourceFilterWorkerFetchBrowserTest, - ::testing::Values(OffMainThreadFetchPolicy::kEnabled, - OffMainThreadFetchPolicy::kDisabled)); - // Tests checking how histograms are recorded. --------------------------------- namespace {
diff --git a/chrome/browser/subresource_filter/subresource_filter_popup_browsertest.cc b/chrome/browser/subresource_filter/subresource_filter_popup_browsertest.cc new file mode 100644 index 0000000..95047c8 --- /dev/null +++ b/chrome/browser/subresource_filter/subresource_filter_popup_browsertest.cc
@@ -0,0 +1,189 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <utility> +#include <vector> + +#include "base/test/histogram_tester.h" +#include "chrome/browser/content_settings/tab_specific_content_settings.h" +#include "chrome/browser/subresource_filter/chrome_subresource_filter_client.h" +#include "chrome/browser/subresource_filter/subresource_filter_browser_test_harness.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/tabs/tab_strip_model.h" +#include "chrome/test/base/in_process_browser_test.h" +#include "chrome/test/base/ui_test_utils.h" +#include "components/content_settings/core/common/content_settings_types.h" +#include "components/subresource_filter/core/browser/subresource_filter_constants.h" +#include "components/subresource_filter/core/browser/subresource_filter_features.h" +#include "components/url_pattern_index/proto/rules.pb.h" +#include "content/public/browser/web_contents.h" +#include "content/public/test/browser_test.h" +#include "content/public/test/browser_test_utils.h" +#include "content/public/test/test_navigation_observer.h" +#include "net/test/embedded_test_server/embedded_test_server.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "url/gurl.h" + +namespace subresource_filter { + +const char kSubresourceFilterActionsHistogram[] = "SubresourceFilter.Actions"; + +// Tests for the subresource_filter popup blocker. +class SubresourceFilterPopupBrowserTest : public SubresourceFilterBrowserTest { +}; + +IN_PROC_BROWSER_TEST_F(SubresourceFilterPopupBrowserTest, + NoConfiguration_AllowCreatingNewWindows) { + base::HistogramTester tester; + const char kWindowOpenPath[] = "/subresource_filter/window_open.html"; + GURL a_url(embedded_test_server()->GetURL("a.com", kWindowOpenPath)); + // Only configure |a_url| as a phishing URL. + ConfigureAsPhishingURL(a_url); + + // Only necessary so we have a valid ruleset. + ASSERT_NO_FATAL_FAILURE(SetRulesetWithRules(std::vector<proto::UrlRule>())); + + // Navigate to a_url, should not trigger the popup blocker. + ui_test_utils::NavigateToURL(browser(), a_url); + bool opened_window = false; + content::WebContents* web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + EXPECT_TRUE(content::ExecuteScriptAndExtractBool(web_contents, "openWindow()", + &opened_window)); + EXPECT_TRUE(opened_window); + EXPECT_FALSE(TabSpecificContentSettings::FromWebContents(web_contents) + ->IsContentBlocked(CONTENT_SETTINGS_TYPE_POPUPS)); +} + +IN_PROC_BROWSER_TEST_F(SubresourceFilterPopupBrowserTest, + BlockCreatingNewWindows) { + Configuration config = Configuration::MakePresetForLiveRunOnPhishingSites(); + config.activation_options.should_strengthen_popup_blocker = true; + ResetConfiguration(std::move(config)); + base::HistogramTester tester; + const char kWindowOpenPath[] = "/subresource_filter/window_open.html"; + GURL a_url(embedded_test_server()->GetURL("a.com", kWindowOpenPath)); + GURL b_url(embedded_test_server()->GetURL("b.com", kWindowOpenPath)); + // Only configure |a_url| as a phishing URL. + ConfigureAsPhishingURL(a_url); + + // Only necessary so we have a valid ruleset. + ASSERT_NO_FATAL_FAILURE(SetRulesetWithRules(std::vector<proto::UrlRule>())); + + // Navigate to a_url, should trigger the popup blocker. + ui_test_utils::NavigateToURL(browser(), a_url); + bool opened_window = false; + content::WebContents* web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + EXPECT_TRUE(content::ExecuteScriptAndExtractBool(web_contents, "openWindow()", + &opened_window)); + EXPECT_FALSE(opened_window); + tester.ExpectBucketCount(kSubresourceFilterActionsHistogram, kActionUIShown, + 1); + // Make sure the popup UI was shown. + EXPECT_TRUE(TabSpecificContentSettings::FromWebContents(web_contents) + ->IsContentBlocked(CONTENT_SETTINGS_TYPE_POPUPS)); + + // Navigate to |b_url|, which should successfully open the popup. + ui_test_utils::NavigateToURL(browser(), b_url); + opened_window = false; + EXPECT_TRUE(content::ExecuteScriptAndExtractBool(web_contents, "openWindow()", + &opened_window)); + EXPECT_TRUE(opened_window); + // Popup UI should not be shown. + EXPECT_FALSE(TabSpecificContentSettings::FromWebContents(web_contents) + ->IsContentBlocked(CONTENT_SETTINGS_TYPE_POPUPS)); +} + +IN_PROC_BROWSER_TEST_F(SubresourceFilterPopupBrowserTest, BlockOpenURLFromTab) { + Configuration config = Configuration::MakePresetForLiveRunOnPhishingSites(); + config.activation_options.should_strengthen_popup_blocker = true; + ResetConfiguration(std::move(config)); + base::HistogramTester tester; + const char kWindowOpenPath[] = + "/subresource_filter/window_open_spoof_click.html"; + GURL a_url(embedded_test_server()->GetURL("a.com", kWindowOpenPath)); + GURL b_url(embedded_test_server()->GetURL("b.com", kWindowOpenPath)); + // Only configure |a_url| as a phishing URL. + ConfigureAsPhishingURL(a_url); + + // Only necessary so we have a valid ruleset. + ASSERT_NO_FATAL_FAILURE(SetRulesetWithRules(std::vector<proto::UrlRule>())); + + // Navigate to a_url, should trigger the popup blocker. + ui_test_utils::NavigateToURL(browser(), a_url); + + content::WebContents* web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + EXPECT_TRUE(content::ExecuteScript(web_contents, "openWindow()")); + tester.ExpectBucketCount(kSubresourceFilterActionsHistogram, kActionUIShown, + 1); + + EXPECT_TRUE(TabSpecificContentSettings::FromWebContents(web_contents) + ->IsContentBlocked(CONTENT_SETTINGS_TYPE_POPUPS)); + + // Navigate to |b_url|, which should successfully open the popup. + + ui_test_utils::NavigateToURL(browser(), b_url); + + content::TestNavigationObserver navigation_observer(nullptr, 1); + navigation_observer.StartWatchingNewWebContents(); + EXPECT_TRUE(content::ExecuteScript(web_contents, "openWindow()")); + navigation_observer.Wait(); + + // Popup UI should not be shown. + EXPECT_FALSE(TabSpecificContentSettings::FromWebContents(web_contents) + ->IsContentBlocked(CONTENT_SETTINGS_TYPE_POPUPS)); +} + +IN_PROC_BROWSER_TEST_F(SubresourceFilterPopupBrowserTest, + BlockOpenURLFromTabInIframe) { + Configuration config = Configuration::MakePresetForLiveRunOnPhishingSites(); + config.activation_options.should_strengthen_popup_blocker = true; + ResetConfiguration(std::move(config)); + const char popup_path[] = "/subresource_filter/iframe_spoof_click_popup.html"; + GURL a_url(embedded_test_server()->GetURL("a.com", popup_path)); + // Only configure |a_url| as a phishing URL. + ConfigureAsPhishingURL(a_url); + + // Only necessary so we have a valid ruleset. + ASSERT_NO_FATAL_FAILURE(SetRulesetWithRules(std::vector<proto::UrlRule>())); + + // Navigate to a_url, should not trigger the popup blocker. + ui_test_utils::NavigateToURL(browser(), a_url); + bool sent_open = false; + content::WebContents* web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + EXPECT_TRUE(content::ExecuteScriptAndExtractBool(web_contents, "openWindow()", + &sent_open)); + EXPECT_TRUE(sent_open); + EXPECT_TRUE(TabSpecificContentSettings::FromWebContents(web_contents) + ->IsContentBlocked(CONTENT_SETTINGS_TYPE_POPUPS)); +} + +IN_PROC_BROWSER_TEST_F(SubresourceFilterPopupBrowserTest, + TraditionalWindowOpen_NotBlocked) { + Configuration config = Configuration::MakePresetForLiveRunOnPhishingSites(); + config.activation_options.should_strengthen_popup_blocker = true; + ResetConfiguration(std::move(config)); + GURL url(GetTestUrl("/title2.html")); + ConfigureAsPhishingURL(url); + ui_test_utils::NavigateToURL(browser(), GetTestUrl("/title1.html")); + + // Only necessary so we have a valid ruleset. + ASSERT_NO_FATAL_FAILURE(SetRulesetWithRules(std::vector<proto::UrlRule>())); + + // Should not trigger the popup blocker because internally opens the tab with + // a user gesture. + ui_test_utils::NavigateToURLWithDisposition( + browser(), url, WindowOpenDisposition::NEW_FOREGROUND_TAB, + ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); + + content::WebContents* web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + EXPECT_FALSE(TabSpecificContentSettings::FromWebContents(web_contents) + ->IsContentBlocked(CONTENT_SETTINGS_TYPE_POPUPS)); +} + +} // namespace subresource_filter
diff --git a/chrome/browser/subresource_filter/subresource_filter_settings_browsertest.cc b/chrome/browser/subresource_filter/subresource_filter_settings_browsertest.cc new file mode 100644 index 0000000..873cb32 --- /dev/null +++ b/chrome/browser/subresource_filter/subresource_filter_settings_browsertest.cc
@@ -0,0 +1,202 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <memory> +#include <string> +#include <utility> + +#include "base/memory/ptr_util.h" +#include "base/test/histogram_tester.h" +#include "base/test/simple_test_clock.h" +#include "chrome/browser/content_settings/host_content_settings_map_factory.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/subresource_filter/chrome_subresource_filter_client.h" +#include "chrome/browser/subresource_filter/subresource_filter_browser_test_harness.h" +#include "chrome/browser/subresource_filter/subresource_filter_content_settings_manager.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/test/base/in_process_browser_test.h" +#include "chrome/test/base/ui_test_utils.h" +#include "components/content_settings/core/browser/host_content_settings_map.h" +#include "components/content_settings/core/common/content_settings.h" +#include "components/content_settings/core/common/content_settings_types.h" +#include "components/subresource_filter/core/browser/subresource_filter_constants.h" +#include "content/public/browser/web_contents.h" +#include "content/public/test/browser_test.h" +#include "content/public/test/browser_test_utils.h" +#include "content/public/test/test_navigation_observer.h" +#include "net/test/embedded_test_server/embedded_test_server.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "url/gurl.h" + +namespace subresource_filter { + +const char kSubresourceFilterActionsHistogram[] = "SubresourceFilter.Actions"; + +class SubresourceFilterSettingsBrowserTest + : public SubresourceFilterBrowserTest {}; + +IN_PROC_BROWSER_TEST_F(SubresourceFilterSettingsBrowserTest, + ContentSettingsWhitelist_DoNotActivate) { + ASSERT_NO_FATAL_FAILURE( + SetRulesetToDisallowURLsWithPathSuffix("included_script.js")); + GURL url(GetTestUrl("subresource_filter/frame_with_included_script.html")); + ConfigureAsPhishingURL(url); + + ui_test_utils::NavigateToURL(browser(), url); + EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame())); + + content::ConsoleObserverDelegate console_observer(web_contents(), + kActivationConsoleMessage); + web_contents()->SetDelegate(&console_observer); + + // Simulate an explicity whitelisting via content settings. + HostContentSettingsMap* settings_map = + HostContentSettingsMapFactory::GetForProfile(browser()->profile()); + settings_map->SetContentSettingDefaultScope( + url, url, ContentSettingsType::CONTENT_SETTINGS_TYPE_ADS, std::string(), + CONTENT_SETTING_ALLOW); + + ui_test_utils::NavigateToURL(browser(), url); + EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame())); + + // No message for whitelisted url. + EXPECT_TRUE(console_observer.message().empty()); +} + +IN_PROC_BROWSER_TEST_F(SubresourceFilterSettingsBrowserTest, + ContentSettingsAllowWithNoPageActivation_DoNotActivate) { + ASSERT_NO_FATAL_FAILURE( + SetRulesetToDisallowURLsWithPathSuffix("included_script.js")); + GURL url(GetTestUrl("subresource_filter/frame_with_included_script.html")); + + // Do not configure as phishing URL. + + ui_test_utils::NavigateToURL(browser(), url); + EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame())); + + // Simulate allowing the subresource filter via content settings. + HostContentSettingsMap* settings_map = + HostContentSettingsMapFactory::GetForProfile(browser()->profile()); + settings_map->SetContentSettingDefaultScope( + url, url, ContentSettingsType::CONTENT_SETTINGS_TYPE_ADS, std::string(), + CONTENT_SETTING_BLOCK); + + // Setting the site to "allow" should not activate filtering. + ui_test_utils::NavigateToURL(browser(), url); + EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame())); +} + +IN_PROC_BROWSER_TEST_F(SubresourceFilterSettingsBrowserTest, + ContentSettingsWhitelistViaReload_DoNotActivate) { + ASSERT_NO_FATAL_FAILURE( + SetRulesetToDisallowURLsWithPathSuffix("included_script.js")); + GURL url(GetTestUrl("subresource_filter/frame_with_included_script.html")); + ConfigureAsPhishingURL(url); + + ui_test_utils::NavigateToURL(browser(), url); + EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame())); + + // Whitelist via a reload. + content::TestNavigationObserver navigation_observer(web_contents(), 1); + ChromeSubresourceFilterClient::FromWebContents(web_contents()) + ->OnReloadRequested(); + navigation_observer.Wait(); + + EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame())); +} + +IN_PROC_BROWSER_TEST_F(SubresourceFilterSettingsBrowserTest, + ContentSettingsWhitelistViaReload_WhitelistIsByDomain) { + ASSERT_NO_FATAL_FAILURE( + SetRulesetToDisallowURLsWithPathSuffix("included_script.js")); + GURL url(GetTestUrl("subresource_filter/frame_with_included_script.html")); + ConfigureAsPhishingURL(url); + + ui_test_utils::NavigateToURL(browser(), url); + EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame())); + + // Whitelist via a reload. + content::TestNavigationObserver navigation_observer(web_contents(), 1); + ChromeSubresourceFilterClient::FromWebContents(web_contents()) + ->OnReloadRequested(); + navigation_observer.Wait(); + + EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame())); + + // Another navigation to the same domain should be whitelisted too. + ui_test_utils::NavigateToURL( + browser(), + GetTestUrl("subresource_filter/frame_with_included_script.html?query")); + EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame())); + + // A cross site blacklisted navigation should stay activated, however. + GURL a_url(embedded_test_server()->GetURL( + "a.com", "/subresource_filter/frame_with_included_script.html")); + ConfigureAsPhishingURL(a_url); + ui_test_utils::NavigateToURL(browser(), a_url); + EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame())); +} + +// Test the "smart" UI, aka the logic to hide the UI on subsequent same-domain +// navigations, until a certain time threshold has been reached. This is an +// android-only feature. +IN_PROC_BROWSER_TEST_F(SubresourceFilterSettingsBrowserTest, + DoNotShowUIUntilThresholdReached) { + ASSERT_NO_FATAL_FAILURE( + SetRulesetToDisallowURLsWithPathSuffix("included_script.js")); + GURL a_url(embedded_test_server()->GetURL( + "a.com", "/subresource_filter/frame_with_included_script.html")); + GURL b_url(embedded_test_server()->GetURL( + "b.com", "/subresource_filter/frame_with_included_script.html")); + // Test utils only support one blacklisted site at a time. + // TODO(csharrison): Add support for more than one URL. + ConfigureAsPhishingURL(a_url); + + ChromeSubresourceFilterClient* client = + ChromeSubresourceFilterClient::FromWebContents(web_contents()); + auto test_clock = base::MakeUnique<base::SimpleTestClock>(); + base::SimpleTestClock* raw_clock = test_clock.get(); + settings_manager()->set_clock_for_testing(std::move(test_clock)); + + base::HistogramTester histogram_tester; + + // First load should trigger the UI. + ui_test_utils::NavigateToURL(browser(), a_url); + EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame())); + EXPECT_TRUE(client->did_show_ui_for_navigation()); + + histogram_tester.ExpectBucketCount(kSubresourceFilterActionsHistogram, + kActionUISuppressed, 0); + + // Second load should not trigger the UI, but should still filter content. + ui_test_utils::NavigateToURL(browser(), a_url); + EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame())); + + bool use_smart_ui = settings_manager()->should_use_smart_ui(); + EXPECT_EQ(client->did_show_ui_for_navigation(), !use_smart_ui); + + histogram_tester.ExpectBucketCount(kSubresourceFilterActionsHistogram, + kActionUISuppressed, use_smart_ui ? 1 : 0); + + ConfigureAsPhishingURL(b_url); + + // Load to another domain should trigger the UI. + ui_test_utils::NavigateToURL(browser(), b_url); + EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame())); + EXPECT_TRUE(client->did_show_ui_for_navigation()); + + ConfigureAsPhishingURL(a_url); + + // Fast forward the clock, and a_url should trigger the UI again. + raw_clock->Advance( + SubresourceFilterContentSettingsManager::kDelayBeforeShowingInfobarAgain); + ui_test_utils::NavigateToURL(browser(), a_url); + EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame())); + EXPECT_TRUE(client->did_show_ui_for_navigation()); + + histogram_tester.ExpectBucketCount(kSubresourceFilterActionsHistogram, + kActionUISuppressed, use_smart_ui ? 1 : 0); +} + +} // namespace subresource_filter
diff --git a/chrome/browser/subresource_filter/subresource_filter_web_socket_browsertest.cc b/chrome/browser/subresource_filter/subresource_filter_web_socket_browsertest.cc new file mode 100644 index 0000000..233ce01 --- /dev/null +++ b/chrome/browser/subresource_filter/subresource_filter_web_socket_browsertest.cc
@@ -0,0 +1,114 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <memory> +#include <string> + +#include "base/macros.h" +#include "base/memory/ptr_util.h" +#include "base/strings/stringprintf.h" +#include "chrome/browser/subresource_filter/subresource_filter_browser_test_harness.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/tabs/tab_strip_model.h" +#include "chrome/test/base/in_process_browser_test.h" +#include "chrome/test/base/ui_test_utils.h" +#include "content/public/test/browser_test.h" +#include "content/public/test/browser_test_utils.h" +#include "net/test/spawned_test_server/spawned_test_server.h" +#include "net/test/test_data_directory.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "url/gurl.h" + +namespace subresource_filter { + +enum WebSocketCreationPolicy { + IN_MAIN_FRAME, + IN_WORKER, +}; +class SubresourceFilterWebSocketBrowserTest + : public SubresourceFilterBrowserTest, + public ::testing::WithParamInterface<WebSocketCreationPolicy> { + public: + SubresourceFilterWebSocketBrowserTest() {} + + void SetUpOnMainThread() override { + SubresourceFilterBrowserTest::SetUpOnMainThread(); + websocket_test_server_ = base::MakeUnique<net::SpawnedTestServer>( + net::SpawnedTestServer::TYPE_WS, net::GetWebSocketTestDataDirectory()); + ASSERT_TRUE(websocket_test_server_->Start()); + } + + net::SpawnedTestServer* websocket_test_server() { + return websocket_test_server_.get(); + } + + GURL GetWebSocketUrl(const std::string& path) { + GURL::Replacements replacements; + replacements.SetSchemeStr("ws"); + return websocket_test_server_->GetURL(path).ReplaceComponents(replacements); + } + + void CreateWebSocketAndExpectResult(const GURL& url, + bool expect_connection_success) { + bool websocket_connection_succeeded = false; + EXPECT_TRUE(content::ExecuteScriptAndExtractBool( + browser()->tab_strip_model()->GetActiveWebContents(), + base::StringPrintf("connectWebSocket('%s');", url.spec().c_str()), + &websocket_connection_succeeded)); + EXPECT_EQ(expect_connection_success, websocket_connection_succeeded); + } + + private: + std::unique_ptr<net::SpawnedTestServer> websocket_test_server_; + + DISALLOW_COPY_AND_ASSIGN(SubresourceFilterWebSocketBrowserTest); +}; + +IN_PROC_BROWSER_TEST_P(SubresourceFilterWebSocketBrowserTest, BlockWebSocket) { + GURL url(GetTestUrl( + base::StringPrintf("subresource_filter/page_with_websocket.html?%s", + GetParam() == IN_WORKER ? "inWorker" : ""))); + GURL websocket_url(GetWebSocketUrl("echo-with-no-extension")); + ConfigureAsPhishingURL(url); + ASSERT_NO_FATAL_FAILURE( + SetRulesetToDisallowURLsWithPathSuffix("echo-with-no-extension")); + ui_test_utils::NavigateToURL(browser(), url); + CreateWebSocketAndExpectResult(websocket_url, + false /* expect_connection_success */); +} + +IN_PROC_BROWSER_TEST_P(SubresourceFilterWebSocketBrowserTest, + DoNotBlockWebSocketNoActivatedFrame) { + GURL url(GetTestUrl( + base::StringPrintf("subresource_filter/page_with_websocket.html?%s", + GetParam() == IN_WORKER ? "inWorker" : ""))); + GURL websocket_url(GetWebSocketUrl("echo-with-no-extension")); + ASSERT_NO_FATAL_FAILURE( + SetRulesetToDisallowURLsWithPathSuffix("echo-with-no-extension")); + ui_test_utils::NavigateToURL(browser(), url); + + CreateWebSocketAndExpectResult(websocket_url, + true /* expect_connection_success */); +} + +IN_PROC_BROWSER_TEST_P(SubresourceFilterWebSocketBrowserTest, + DoNotBlockWebSocketInActivatedFrameWithNoRule) { + GURL url(GetTestUrl( + base::StringPrintf("subresource_filter/page_with_websocket.html?%s", + GetParam() == IN_WORKER ? "inWorker" : ""))); + GURL websocket_url(GetWebSocketUrl("echo-with-no-extension")); + ConfigureAsPhishingURL(url); + ui_test_utils::NavigateToURL(browser(), url); + + CreateWebSocketAndExpectResult(websocket_url, + true /* expect_connection_success */); +} + +INSTANTIATE_TEST_CASE_P( + /* no prefix */, + SubresourceFilterWebSocketBrowserTest, + ::testing::Values(WebSocketCreationPolicy::IN_WORKER, + WebSocketCreationPolicy::IN_MAIN_FRAME)); + +} // namespace subresource_filter
diff --git a/chrome/browser/subresource_filter/subresource_filter_worker_browsertest.cc b/chrome/browser/subresource_filter/subresource_filter_worker_browsertest.cc new file mode 100644 index 0000000..1571d3a --- /dev/null +++ b/chrome/browser/subresource_filter/subresource_filter_worker_browsertest.cc
@@ -0,0 +1,111 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <vector> + +#include "base/command_line.h" +#include "base/feature_list.h" +#include "base/macros.h" +#include "base/memory/ptr_util.h" +#include "base/strings/string16.h" +#include "base/strings/string_piece.h" +#include "base/strings/stringprintf.h" +#include "base/strings/utf_string_conversions.h" +#include "chrome/browser/subresource_filter/subresource_filter_browser_test_harness.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/tabs/tab_strip_model.h" +#include "chrome/test/base/in_process_browser_test.h" +#include "chrome/test/base/ui_test_utils.h" +#include "content/public/browser/web_contents.h" +#include "content/public/common/content_features.h" +#include "content/public/common/content_switches.h" +#include "content/public/test/browser_test.h" +#include "content/public/test/browser_test_utils.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "url/gurl.h" + +namespace subresource_filter { + +enum class OffMainThreadFetchPolicy { + kEnabled, + kDisabled, +}; + +class SubresourceFilterWorkerFetchBrowserTest + : public SubresourceFilterBrowserTest, + public ::testing::WithParamInterface<OffMainThreadFetchPolicy> { + public: + SubresourceFilterWorkerFetchBrowserTest() {} + ~SubresourceFilterWorkerFetchBrowserTest() override {} + + protected: + void SetUpCommandLine(base::CommandLine* command_line) override { + std::vector<base::StringPiece> features = + SubresourceFilterBrowserTest::RequiredFeatures(); + if (GetParam() == OffMainThreadFetchPolicy::kEnabled) { + features.push_back(features::kOffMainThreadFetch.name); + } else { + command_line->AppendSwitchASCII(switches::kDisableFeatures, + features::kOffMainThreadFetch.name); + } + command_line->AppendSwitchASCII(switches::kEnableFeatures, + base::JoinString(features, ",")); + } + + void ClearTitle() { + ASSERT_TRUE(content::ExecuteScript(web_contents()->GetMainFrame(), + "document.title = \"\";")); + } + + private: + DISALLOW_COPY_AND_ASSIGN(SubresourceFilterWorkerFetchBrowserTest); +}; + +IN_PROC_BROWSER_TEST_P(SubresourceFilterWorkerFetchBrowserTest, WorkerFetch) { + const base::string16 fetch_succeeded_title = + base::ASCIIToUTF16("FetchSucceeded"); + const base::string16 fetch_failed_title = base::ASCIIToUTF16("FetchFailed"); + GURL url(GetTestUrl("subresource_filter/worker_fetch.html")); + ConfigureAsPhishingURL(url); + + ASSERT_NO_FATAL_FAILURE(SetRulesetToDisallowURLsWithPathSuffix( + "suffix-that-does-not-match-anything")); + { + content::TitleWatcher title_watcher( + browser()->tab_strip_model()->GetActiveWebContents(), + fetch_succeeded_title); + title_watcher.AlsoWaitForTitle(fetch_failed_title); + ui_test_utils::NavigateToURL(browser(), url); + EXPECT_EQ(fetch_succeeded_title, title_watcher.WaitAndGetTitle()); + } + ClearTitle(); + ASSERT_NO_FATAL_FAILURE( + SetRulesetToDisallowURLsWithPathSuffix("worker_fetch_data.txt")); + { + content::TitleWatcher title_watcher( + browser()->tab_strip_model()->GetActiveWebContents(), + fetch_succeeded_title); + title_watcher.AlsoWaitForTitle(fetch_failed_title); + ui_test_utils::NavigateToURL(browser(), url); + EXPECT_EQ(fetch_failed_title, title_watcher.WaitAndGetTitle()); + } + ClearTitle(); + // The main frame document should never be filtered. + SetRulesetToDisallowURLsWithPathSuffix("worker_fetch.html"); + { + content::TitleWatcher title_watcher( + browser()->tab_strip_model()->GetActiveWebContents(), + fetch_succeeded_title); + title_watcher.AlsoWaitForTitle(fetch_failed_title); + ui_test_utils::NavigateToURL(browser(), url); + EXPECT_EQ(fetch_succeeded_title, title_watcher.WaitAndGetTitle()); + } +} + +INSTANTIATE_TEST_CASE_P(/* no prefix */, + SubresourceFilterWorkerFetchBrowserTest, + ::testing::Values(OffMainThreadFetchPolicy::kEnabled, + OffMainThreadFetchPolicy::kDisabled)); + +} // namespace subresource_filter
diff --git a/chrome/browser/sync_file_system/local/syncable_file_system_operation.h b/chrome/browser/sync_file_system/local/syncable_file_system_operation.h index d88c2fba..6d662d00 100644 --- a/chrome/browser/sync_file_system/local/syncable_file_system_operation.h +++ b/chrome/browser/sync_file_system/local/syncable_file_system_operation.h
@@ -27,8 +27,7 @@ class SyncableFileOperationRunner; // A wrapper class of FileSystemOperation for syncable file system. -class SyncableFileSystemOperation - : public NON_EXPORTED_BASE(storage::FileSystemOperation) { +class SyncableFileSystemOperation : public storage::FileSystemOperation { public: ~SyncableFileSystemOperation() override;
diff --git a/chrome/browser/task_manager/providers/fallback_task_provider.cc b/chrome/browser/task_manager/providers/fallback_task_provider.cc index 36b6785..795fdc3b 100644 --- a/chrome/browser/task_manager/providers/fallback_task_provider.cc +++ b/chrome/browser/task_manager/providers/fallback_task_provider.cc
@@ -85,8 +85,11 @@ } void FallbackTaskProvider::HideTask(Task* task) { - base::Erase(shown_tasks_, task); - NotifyObserverTaskRemoved(task); + auto it = std::remove(shown_tasks_.begin(), shown_tasks_.end(), task); + if (it != shown_tasks_.end()) { + shown_tasks_.erase(it, shown_tasks_.end()); + NotifyObserverTaskRemoved(task); + } } void FallbackTaskProvider::OnTaskAddedBySource(Task* task, @@ -127,8 +130,7 @@ } } } - if (base::ContainsValue(shown_tasks_, task)) - HideTask(task); + HideTask(task); } void FallbackTaskProvider::OnTaskUnresponsive(Task* task) {
diff --git a/chrome/browser/task_manager/providers/fallback_task_provider_unittest.cc b/chrome/browser/task_manager/providers/fallback_task_provider_unittest.cc index ce1c3263..8cb36ef 100644 --- a/chrome/browser/task_manager/providers/fallback_task_provider_unittest.cc +++ b/chrome/browser/task_manager/providers/fallback_task_provider_unittest.cc
@@ -91,12 +91,12 @@ // task_manager::TaskProviderObserver: void TaskAdded(Task* task) override { - DCHECK(task); + EXPECT_FALSE(base::ContainsValue(seen_tasks_, task)); seen_tasks_.emplace_back(task); } void TaskRemoved(Task* task) override { - DCHECK(task); + EXPECT_TRUE(base::ContainsValue(seen_tasks_, task)); base::Erase(seen_tasks_, task); }
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 90ec380..856593b 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -1162,8 +1162,6 @@ "hung_plugin_tab_helper.h", "webui/flash_ui.cc", "webui/flash_ui.h", - "webui/options/pepper_flash_content_settings_utils.cc", - "webui/options/pepper_flash_content_settings_utils.h", ] deps += [ "//ppapi/proxy:ipc" ] } @@ -1224,100 +1222,8 @@ "webui/chromeos/proxy_settings_ui.h", "webui/chromeos/user_image_source.cc", "webui/chromeos/user_image_source.h", - "webui/help/help_handler.cc", - "webui/help/help_handler.h", "webui/help/help_utils_chromeos.cc", "webui/help/help_utils_chromeos.h", - "webui/options/autofill_options_handler.cc", - "webui/options/autofill_options_handler.h", - "webui/options/automatic_settings_reset_handler.cc", - "webui/options/automatic_settings_reset_handler.h", - "webui/options/browser_options_handler.cc", - "webui/options/browser_options_handler.h", - "webui/options/chromeos/accounts_options_handler.cc", - "webui/options/chromeos/accounts_options_handler.h", - "webui/options/chromeos/bluetooth_options_handler.cc", - "webui/options/chromeos/bluetooth_options_handler.h", - "webui/options/chromeos/change_picture_options_handler.cc", - "webui/options/chromeos/change_picture_options_handler.h", - "webui/options/chromeos/core_chromeos_options_handler.cc", - "webui/options/chromeos/core_chromeos_options_handler.h", - "webui/options/chromeos/cros_language_options_handler.cc", - "webui/options/chromeos/cros_language_options_handler.h", - "webui/options/chromeos/date_time_options_handler.cc", - "webui/options/chromeos/date_time_options_handler.h", - "webui/options/chromeos/display_options_handler.cc", - "webui/options/chromeos/display_options_handler.h", - "webui/options/chromeos/display_overscan_handler.cc", - "webui/options/chromeos/display_overscan_handler.h", - "webui/options/chromeos/internet_options_handler.cc", - "webui/options/chromeos/internet_options_handler.h", - "webui/options/chromeos/internet_options_handler_strings.cc", - "webui/options/chromeos/internet_options_handler_strings.h", - "webui/options/chromeos/keyboard_handler.cc", - "webui/options/chromeos/keyboard_handler.h", - "webui/options/chromeos/options_stylus_handler.cc", - "webui/options/chromeos/options_stylus_handler.h", - "webui/options/chromeos/pointer_handler.cc", - "webui/options/chromeos/pointer_handler.h", - "webui/options/chromeos/power_handler.cc", - "webui/options/chromeos/power_handler.h", - "webui/options/chromeos/proxy_handler.cc", - "webui/options/chromeos/proxy_handler.h", - "webui/options/chromeos/stats_options_handler.cc", - "webui/options/chromeos/stats_options_handler.h", - "webui/options/chromeos/storage_manager_handler.cc", - "webui/options/chromeos/storage_manager_handler.h", - "webui/options/clear_browser_data_handler.cc", - "webui/options/clear_browser_data_handler.h", - "webui/options/content_settings_handler.cc", - "webui/options/content_settings_handler.h", - "webui/options/cookies_view_handler.cc", - "webui/options/cookies_view_handler.h", - "webui/options/core_options_handler.cc", - "webui/options/core_options_handler.h", - "webui/options/create_profile_handler.cc", - "webui/options/create_profile_handler.h", - "webui/options/easy_unlock_handler.cc", - "webui/options/easy_unlock_handler.h", - "webui/options/font_settings_handler.cc", - "webui/options/font_settings_handler.h", - "webui/options/handler_options_handler.cc", - "webui/options/handler_options_handler.h", - "webui/options/help_overlay_handler.cc", - "webui/options/help_overlay_handler.h", - "webui/options/home_page_overlay_handler.cc", - "webui/options/home_page_overlay_handler.h", - "webui/options/import_data_handler.cc", - "webui/options/import_data_handler.h", - "webui/options/language_dictionary_overlay_handler.cc", - "webui/options/language_dictionary_overlay_handler.h", - "webui/options/language_options_handler.cc", - "webui/options/language_options_handler.h", - "webui/options/language_options_handler_common.cc", - "webui/options/language_options_handler_common.h", - "webui/options/manage_profile_handler.cc", - "webui/options/manage_profile_handler.h", - "webui/options/media_devices_selection_handler.cc", - "webui/options/media_devices_selection_handler.h", - "webui/options/options_ui.cc", - "webui/options/options_ui.h", - "webui/options/password_manager_handler.cc", - "webui/options/password_manager_handler.h", - "webui/options/reset_profile_settings_handler.cc", - "webui/options/reset_profile_settings_handler.h", - "webui/options/search_engine_manager_handler.cc", - "webui/options/search_engine_manager_handler.h", - "webui/options/startup_pages_handler.cc", - "webui/options/startup_pages_handler.h", - "webui/options/supervised_user_create_confirm_handler.cc", - "webui/options/supervised_user_create_confirm_handler.h", - "webui/options/supervised_user_import_handler.cc", - "webui/options/supervised_user_import_handler.h", - "webui/options/supervised_user_learn_more_handler.cc", - "webui/options/supervised_user_learn_more_handler.h", - "webui/options/sync_setup_handler.cc", - "webui/options/sync_setup_handler.h", ] deps += [ "//chrome/browser/chromeos", @@ -1927,6 +1833,8 @@ "views/profiles/user_manager_view.h", "views/proximity_auth/proximity_auth_error_bubble_view.cc", "views/proximity_auth/proximity_auth_error_bubble_view.h", + "views/sad_tab_view.cc", + "views/sad_tab_view.h", "views/session_crashed_bubble_view.cc", "views/session_crashed_bubble_view.h", "views/ssl_client_certificate_selector.cc", @@ -2224,8 +2132,6 @@ "views/ime/ime_window_view.h", "views/renderer_context_menu/render_view_context_menu_views.cc", "views/renderer_context_menu/render_view_context_menu_views.h", - "views/sad_tab_view.cc", - "views/sad_tab_view.h", "views/tab_contents/chrome_web_contents_view_delegate_views.cc", "views/tab_contents/chrome_web_contents_view_delegate_views.h", "views/theme_profile_key.cc", @@ -2262,12 +2168,6 @@ "webui/certificates_handler.cc", "webui/certificates_handler.h", ] - if (is_chromeos) { - sources += [ - "webui/options/certificate_manager_handler.cc", - "webui/options/certificate_manager_handler.h", - ] - } } if (is_mac || is_win) { sources += [ @@ -2552,9 +2452,6 @@ "cocoa/status_icons/status_tray_mac.mm", "cocoa/tab_contents/chrome_web_contents_view_delegate_mac.h", "cocoa/tab_contents/chrome_web_contents_view_delegate_mac.mm", - "cocoa/tab_contents/sad_tab_mac.mm", - "cocoa/tab_contents/sad_tab_view_cocoa.h", - "cocoa/tab_contents/sad_tab_view_cocoa.mm", "cocoa/tab_contents/web_drag_bookmark_handler_mac.h", "cocoa/tab_contents/web_drag_bookmark_handler_mac.mm", "cocoa/ui_localizer.h", @@ -2591,6 +2488,8 @@ "views/frame/browser_non_client_frame_view_mac.mm", "views/frame/native_browser_frame_factory_mac.mm", "views/infobars/legacy_infobars_mac.cc", + "views/tab_contents/chrome_web_contents_view_delegate_views_mac.h", + "views/tab_contents/chrome_web_contents_view_delegate_views_mac.mm", "views/tabs/window_finder_mac.mm", ] deps += [ "//extensions/components/native_app_window" ] @@ -3084,6 +2983,9 @@ "cocoa/tab_contents/favicon_util_mac.mm", "cocoa/tab_contents/overlayable_contents_controller.h", "cocoa/tab_contents/overlayable_contents_controller.mm", + "cocoa/tab_contents/sad_tab_mac.mm", + "cocoa/tab_contents/sad_tab_view_cocoa.h", + "cocoa/tab_contents/sad_tab_view_cocoa.mm", "cocoa/tab_contents/tab_contents_controller.h", "cocoa/tab_contents/tab_contents_controller.mm", "cocoa/tab_dialogs_cocoa.h", @@ -3574,13 +3476,6 @@ "webui/extensions/extension_icon_source.h", ] } - if (enable_google_now && !is_android) { - sources += [ - # These are non-Android because Android excludes all of options. - "webui/options/geolocation_options_handler.cc", - "webui/options/geolocation_options_handler.h", - ] - } if (!is_android) { sources += [ "toolbar/media_router_action.cc",
diff --git a/chrome/browser/ui/app_list/search/arc/arc_playstore_search_result.cc b/chrome/browser/ui/app_list/search/arc/arc_playstore_search_result.cc index c491399..47dc907 100644 --- a/chrome/browser/ui/app_list/search/arc/arc_playstore_search_result.cc +++ b/chrome/browser/ui/app_list/search/arc/arc_playstore_search_result.cc
@@ -213,7 +213,9 @@ ui::MenuModel* ArcPlayStoreSearchResult::GetContextMenuModel() { context_menu_ = base::MakeUnique<ArcPlayStoreAppContextMenu>( this, profile_, list_controller_); - return context_menu_->GetMenuModel(); + // TODO(755701): Enable context menu once Play Store API starts returning both + // install and launch intents. + return nullptr; } void ArcPlayStoreSearchResult::ExecuteLaunchCommand(int event_flags) {
diff --git a/chrome/browser/ui/app_list/search/arc/arc_playstore_search_result.h b/chrome/browser/ui/app_list/search/arc/arc_playstore_search_result.h index 577659e..f3b5f4b9 100644 --- a/chrome/browser/ui/app_list/search/arc/arc_playstore_search_result.h +++ b/chrome/browser/ui/app_list/search/arc/arc_playstore_search_result.h
@@ -30,10 +30,10 @@ // app_list::SearchResult overrides: std::unique_ptr<SearchResult> Duplicate() const override; - - // app_list::AppContextMenuDelegate overrides: ui::MenuModel* GetContextMenuModel() override; void Open(int event_flags) override; + + // app_list::AppContextMenuDelegate overrides: void ExecuteLaunchCommand(int event_flags) override; // Disables async safe decoding requests when unit tests are executed.
diff --git a/chrome/browser/ui/app_list/search/search_controller_factory.cc b/chrome/browser/ui/app_list/search/search_controller_factory.cc index 3894c4b..2af7410 100644 --- a/chrome/browser/ui/app_list/search/search_controller_factory.cc +++ b/chrome/browser/ui/app_list/search/search_controller_factory.cc
@@ -39,6 +39,7 @@ // Maximum number of results to show in each mixer group. constexpr size_t kMaxAppsGroupResults = 8; +constexpr size_t kMaxAppsGroupResultsFullscreen = 6; constexpr size_t kMaxOmniboxResults = 4; constexpr size_t kMaxWebstoreResults = 2; constexpr size_t kMaxSuggestionsResults = 6; @@ -83,10 +84,14 @@ // a query turns up very few results, the mixer may take more than this // maximum from a particular group. + const bool is_fullscreen_app_list_enabled = + features::IsFullscreenAppListEnabled(); + size_t answer_card_group_id = controller->AddGroup(1, 1.0, 10.0); - size_t apps_group_id = - controller->AddGroup(kMaxAppsGroupResults, 1.0, - features::IsFullscreenAppListEnabled() ? 5.0 : 0.0); + size_t apps_group_id = controller->AddGroup( + is_fullscreen_app_list_enabled ? kMaxAppsGroupResultsFullscreen + : kMaxAppsGroupResults, + 1.0, is_fullscreen_app_list_enabled ? 5.0 : 0.0); size_t omnibox_group_id = controller->AddGroup(kMaxOmniboxResults, 1.0, 0.0); size_t webstore_group_id = controller->AddGroup(kMaxWebstoreResults, 0.4, 0.0);
diff --git a/chrome/browser/ui/apps/chrome_app_delegate.cc b/chrome/browser/ui/apps/chrome_app_delegate.cc index f18af9b3..9c236c45 100644 --- a/chrome/browser/ui/apps/chrome_app_delegate.cc +++ b/chrome/browser/ui/apps/chrome_app_delegate.cc
@@ -102,15 +102,16 @@ switch (state) { case shell_integration::IS_DEFAULT: OpenURLFromTabInternal(profile, params); - break; + return; case shell_integration::NOT_DEFAULT: case shell_integration::UNKNOWN_DEFAULT: + case shell_integration::OTHER_MODE_IS_DEFAULT: platform_util::OpenExternal(profile, params.url); - break; + return; case shell_integration::NUM_DEFAULT_STATES: - NOTREACHED(); break; } + NOTREACHED(); } } // namespace
diff --git a/chrome/browser/ui/ash/chrome_shell_delegate.cc b/chrome/browser/ui/ash/chrome_shell_delegate.cc index 588e18d5..37c7cac 100644 --- a/chrome/browser/ui/ash/chrome_shell_delegate.cc +++ b/chrome/browser/ui/ash/chrome_shell_delegate.cc
@@ -550,17 +550,6 @@ IDR_BLUETOOTH_KEYBOARD); } -PrefService* ChromeShellDelegate::GetActiveUserPrefService() const { - const user_manager::User* const user = - user_manager::UserManager::Get()->GetActiveUser(); - if (!user) - return nullptr; - - // The user's profile might not be ready yet, so we must check for that too. - Profile* profile = chromeos::ProfileHelper::Get()->GetProfileByUser(user); - return profile ? profile->GetPrefs() : nullptr; -} - bool ChromeShellDelegate::IsTouchscreenEnabledInPrefs( bool use_local_state) const { return chromeos::system::InputDeviceSettings::Get()
diff --git a/chrome/browser/ui/ash/chrome_shell_delegate.h b/chrome/browser/ui/ash/chrome_shell_delegate.h index 7509cfa..dd4e40a 100644 --- a/chrome/browser/ui/ash/chrome_shell_delegate.h +++ b/chrome/browser/ui/ash/chrome_shell_delegate.h
@@ -54,7 +54,6 @@ base::string16 GetProductName() const override; void OpenKeyboardShortcutHelpPage() const override; gfx::Image GetDeprecatedAcceleratorImage() const override; - PrefService* GetActiveUserPrefService() const override; bool IsTouchscreenEnabledInPrefs(bool use_local_state) const override; void SetTouchscreenEnabledInPrefs(bool enabled, bool use_local_state) override;
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc index d0c5e31..593554d 100644 --- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc +++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc
@@ -679,6 +679,12 @@ // no window on desktop, multi user, ..) the shelf could be shown - or not. PrefService* prefs = profile()->GetPrefs(); PrefService* other_prefs = other_profile->GetPrefs(); + // If ash prefs have not been registered with Chrome yet, Chrome cannot know + // whether the shelf bounds will change; err on the side of false positives. + if (!ash::AreShelfPrefsAvailable(prefs) || + !ash::AreShelfPrefsAvailable(other_prefs)) { + return true; + } const int64_t display = GetDisplayIDForShelf(shelf); const bool currently_shown = ash::SHELF_AUTO_HIDE_BEHAVIOR_NEVER ==
diff --git a/chrome/browser/ui/ash/system_tray_client_browsertest.cc b/chrome/browser/ui/ash/system_tray_client_browsertest.cc index e1cce6eb..e9d3be4 100644 --- a/chrome/browser/ui/ash/system_tray_client_browsertest.cc +++ b/chrome/browser/ui/ash/system_tray_client_browsertest.cc
@@ -6,22 +6,38 @@ #include "ash/root_window_controller.h" #include "ash/shell.h" +#include "ash/system/date/date_view.h" +#include "ash/system/date/system_info_default_view.h" +#include "ash/system/date/tray_system_info.h" #include "ash/system/enterprise/tray_enterprise.h" #include "ash/system/tray/label_tray_view.h" #include "ash/system/tray/system_tray.h" #include "ash/system/tray/system_tray_test_api.h" #include "ash/system/tray/tray_item_view.h" #include "ash/system/update/tray_update.h" +#include "base/i18n/time_formatting.h" #include "base/strings/utf_string_conversions.h" +#include "chrome/browser/chromeos/login/login_manager_test.h" +#include "chrome/browser/chromeos/login/startup_utils.h" +#include "chrome/browser/chromeos/login/ui/user_adding_screen.h" #include "chrome/browser/chromeos/policy/device_policy_cros_browser_test.h" +#include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/chromeos/upgrade_detector_chromeos.h" +#include "chrome/browser/profiles/profile.h" #include "chrome/browser/upgrade_detector.h" +#include "chrome/common/pref_names.h" #include "chrome/test/base/in_process_browser_test.h" #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/fake_update_engine_client.h" +#include "components/prefs/pref_service.h" +#include "components/signin/core/account_id/account_id.h" +#include "components/user_manager/user_manager.h" #include "content/public/test/test_utils.h" #include "ui/views/controls/label.h" +using chromeos::ProfileHelper; +using user_manager::UserManager; + namespace { // TODO(jamescook): Add a test-only mojo API to get system tray details. @@ -137,3 +153,73 @@ system_tray->CloseBubble(); } + +class SystemTrayClientClockTest : public chromeos::LoginManagerTest { + public: + SystemTrayClientClockTest() + : LoginManagerTest(false /* should_launch_browser */), + // Use consumer emails to avoid having to fake a policy fetch. + account_id1_(AccountId::FromUserEmail("user1@gmail.com")), + account_id2_(AccountId::FromUserEmail("user2@gmail.com")) {} + + ~SystemTrayClientClockTest() override = default; + + void SetupUserProfile(const AccountId& account_id, bool use_24_hour_clock) { + const user_manager::User* user = UserManager::Get()->FindUser(account_id); + Profile* profile = ProfileHelper::Get()->GetProfileByUser(user); + profile->GetPrefs()->SetBoolean(prefs::kUse24HourClock, use_24_hour_clock); + // Allow clock setting to be sent to ash over mojo. + content::RunAllPendingInMessageLoop(); + } + + static ash::TraySystemInfo* GetTraySystemInfo() { + return ash::SystemTrayTestApi(ash::Shell::Get()->GetPrimarySystemTray()) + .tray_system_info(); + } + + static base::HourClockType GetHourType() { + const ash::SystemInfoDefaultView* system_info_default_view = + GetTraySystemInfo()->GetDefaultViewForTesting(); + return system_info_default_view->GetDateView()->GetHourTypeForTesting(); + } + + static void CreateDefaultView() { + GetTraySystemInfo()->CreateDefaultViewForTesting( + ash::LoginStatus::NOT_LOGGED_IN); + } + + protected: + const AccountId account_id1_; + const AccountId account_id2_; + + private: + DISALLOW_COPY_AND_ASSIGN(SystemTrayClientClockTest); +}; + +IN_PROC_BROWSER_TEST_F(SystemTrayClientClockTest, + PRE_TestMultiProfile24HourClock) { + RegisterUser(account_id1_.GetUserEmail()); + RegisterUser(account_id2_.GetUserEmail()); + chromeos::StartupUtils::MarkOobeCompleted(); +} + +// Test that clock type is taken from user profile for current active user. +IN_PROC_BROWSER_TEST_F(SystemTrayClientClockTest, TestMultiProfile24HourClock) { + LoginUser(account_id1_.GetUserEmail()); + SetupUserProfile(account_id1_, true /* use_24_hour_clock */); + CreateDefaultView(); + EXPECT_EQ(base::k24HourClock, GetHourType()); + + chromeos::UserAddingScreen::Get()->Start(); + content::RunAllPendingInMessageLoop(); + AddUser(account_id2_.GetUserEmail()); + SetupUserProfile(account_id2_, false /* use_24_hour_clock */); + CreateDefaultView(); + EXPECT_EQ(base::k12HourClock, GetHourType()); + + UserManager::Get()->SwitchActiveUser(account_id1_); + // Allow clock setting to be sent to ash over mojo. + content::RunAllPendingInMessageLoop(); + CreateDefaultView(); + EXPECT_EQ(base::k24HourClock, GetHourType()); +}
diff --git a/chrome/browser/ui/ash/system_tray_delegate_chromeos_browsertest_chromeos.cc b/chrome/browser/ui/ash/system_tray_delegate_chromeos_browsertest_chromeos.cc deleted file mode 100644 index e4b2bf6..0000000 --- a/chrome/browser/ui/ash/system_tray_delegate_chromeos_browsertest_chromeos.cc +++ /dev/null
@@ -1,110 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/ash/system_tray_delegate_chromeos.h" - -#include <string> - -#include "ash/shell.h" -#include "ash/system/date/date_view.h" -#include "ash/system/date/system_info_default_view.h" -#include "ash/system/date/tray_system_info.h" -#include "ash/system/tray/system_tray.h" -#include "ash/system/tray/system_tray_test_api.h" -#include "base/macros.h" -#include "chrome/browser/chromeos/login/login_manager_test.h" -#include "chrome/browser/chromeos/login/session/user_session_manager.h" -#include "chrome/browser/chromeos/login/startup_utils.h" -#include "chrome/browser/chromeos/login/ui/user_adding_screen.h" -#include "chrome/browser/chromeos/profiles/profile_helper.h" -#include "chrome/browser/ui/browser.h" -#include "chrome/common/pref_names.h" -#include "chrome/test/base/in_process_browser_test.h" -#include "components/prefs/pref_service.h" -#include "components/user_manager/user_manager.h" -#include "content/public/test/test_utils.h" - -namespace chromeos { - -namespace { - -// Because policy is not needed this test it is better to use e-mails that -// are definitely not enterprise. This lets us to avoid faking of policy fetch -// procedure. -const char kUser1[] = "user1@gmail.com"; -const char kUser2[] = "user2@gmail.com"; - -ash::TraySystemInfo* GetTraySystemInfo() { - return ash::SystemTrayTestApi(ash::Shell::Get()->GetPrimarySystemTray()) - .tray_system_info(); -} - -base::HourClockType GetHourType() { - const ash::SystemInfoDefaultView* system_info_default_view = - GetTraySystemInfo()->GetDefaultViewForTesting(); - return system_info_default_view->GetDateView()->GetHourTypeForTesting(); -} - -void CreateDefaultView() { - GetTraySystemInfo()->CreateDefaultViewForTesting( - ash::LoginStatus::NOT_LOGGED_IN); -} - -} // namespace - -class SystemTrayDelegateChromeOSTest : public LoginManagerTest { - protected: - SystemTrayDelegateChromeOSTest() - : LoginManagerTest(false /* should_launch_browser */), - account_id1_(AccountId::FromUserEmail(kUser1)), - account_id2_(AccountId::FromUserEmail(kUser2)) {} - - ~SystemTrayDelegateChromeOSTest() override {} - - void SetupUserProfile(const AccountId& account_id, bool use_24_hour_clock) { - const user_manager::User* user = - user_manager::UserManager::Get()->FindUser(account_id); - Profile* profile = ProfileHelper::Get()->GetProfileByUser(user); - profile->GetPrefs()->SetBoolean(prefs::kUse24HourClock, use_24_hour_clock); - // Allow clock setting to be sent to ash over mojo. - content::RunAllPendingInMessageLoop(); - } - - const AccountId account_id1_; - const AccountId account_id2_; - - private: - DISALLOW_COPY_AND_ASSIGN(SystemTrayDelegateChromeOSTest); -}; - -IN_PROC_BROWSER_TEST_F(SystemTrayDelegateChromeOSTest, - PRE_TestMultiProfile24HourClock) { - RegisterUser(account_id1_.GetUserEmail()); - RegisterUser(account_id2_.GetUserEmail()); - StartupUtils::MarkOobeCompleted(); -} - -// Test that clock type is taken from user profile for current active user. -IN_PROC_BROWSER_TEST_F(SystemTrayDelegateChromeOSTest, - TestMultiProfile24HourClock) { - LoginUser(account_id1_.GetUserEmail()); - SetupUserProfile(account_id1_, true /* Use_24_hour_clock. */); - CreateDefaultView(); - EXPECT_EQ(base::k24HourClock, GetHourType()); - - UserAddingScreen::Get()->Start(); - content::RunAllPendingInMessageLoop(); - AddUser(account_id2_.GetUserEmail()); - SetupUserProfile(account_id2_, false /* Use_24_hour_clock. */); - CreateDefaultView(); - EXPECT_EQ(base::k12HourClock, GetHourType()); - - user_manager::UserManager::Get()->SwitchActiveUser(account_id1_); - // Allow clock setting to be sent to ash over mojo. - content::RunAllPendingInMessageLoop(); - CreateDefaultView(); - EXPECT_EQ(base::k24HourClock, GetHourType()); -} - -} // namespace chromeos
diff --git a/chrome/browser/ui/cocoa/browser_window_touch_bar.mm b/chrome/browser/ui/cocoa/browser_window_touch_bar.mm index f5ebe841..fa70cdf1 100644 --- a/chrome/browser/ui/cocoa/browser_window_touch_bar.mm +++ b/chrome/browser/ui/cocoa/browser_window_touch_bar.mm
@@ -415,7 +415,7 @@ NSImage* image; if (isGoogle) { image = NSImageFromImageSkiaWithColorSpace( - gfx::CreateVectorIcon(kGoogleSearchMacTouchbarIcon, kTouchBarIconSize, + gfx::CreateVectorIcon(kGoogleGLogoIcon, kTouchBarIconSize, gfx::kPlaceholderColor), base::mac::GetSRGBColorSpace()); } else {
diff --git a/chrome/browser/ui/cocoa/extensions/extension_message_bubble_browsertest_mac.mm b/chrome/browser/ui/cocoa/extensions/extension_message_bubble_browsertest_mac.mm index 723b469..95ca512 100644 --- a/chrome/browser/ui/cocoa/extensions/extension_message_bubble_browsertest_mac.mm +++ b/chrome/browser/ui/cocoa/extensions/extension_message_bubble_browsertest_mac.mm
@@ -268,8 +268,3 @@ TestControlledNewTabPageMessageBubble) { TestControlledNewTabPageBubbleShown(false); } - -IN_PROC_BROWSER_TEST_F(NtpBubbleBrowserTestMac, - TestBubbleClosedAfterExtensionUninstall) { - TestBubbleClosedAfterExtensionUninstall(); -}
diff --git a/chrome/browser/ui/cocoa/extensions/toolbar_actions_bar_bubble_mac.mm b/chrome/browser/ui/cocoa/extensions/toolbar_actions_bar_bubble_mac.mm index 16814b7..28b5696 100644 --- a/chrome/browser/ui/cocoa/extensions/toolbar_actions_bar_bubble_mac.mm +++ b/chrome/browser/ui/cocoa/extensions/toolbar_actions_bar_bubble_mac.mm
@@ -6,7 +6,6 @@ #include <utility> -#include "base/mac/bind_objc_block.h" #include "base/mac/foundation_util.h" #include "base/strings/sys_string_conversions.h" #import "chrome/browser/ui/cocoa/info_bubble_view.h" @@ -17,8 +16,8 @@ #include "third_party/skia/include/core/SkColor.h" #import "ui/base/cocoa/controls/hyperlink_button_cell.h" #import "ui/base/cocoa/hover_button.h" -#import "ui/base/cocoa/window_size_constants.h" #include "ui/base/resource/resource_bundle.h" +#import "ui/base/cocoa/window_size_constants.h" #include "ui/gfx/color_palette.h" #include "ui/gfx/image/image_skia_util_mac.h" #include "ui/gfx/paint_vector_icon.h" @@ -111,13 +110,7 @@ } - (IBAction)showWindow:(id)sender { - // The capturing lambda below is safe because the block creates a strong - // reference to |self|. The Block_copy operator automatically retains object - // variables, and when the block is destroyed, the variables are automatically - // released. - delegate_->OnBubbleShown(base::BindBlock(^{ - [self close]; - })); + delegate_->OnBubbleShown(); [super showWindow:sender]; }
diff --git a/chrome/browser/ui/cocoa/omnibox/omnibox_view_mac.mm b/chrome/browser/ui/cocoa/omnibox/omnibox_view_mac.mm index da565908..07296a3 100644 --- a/chrome/browser/ui/cocoa/omnibox/omnibox_view_mac.mm +++ b/chrome/browser/ui/cocoa/omnibox/omnibox_view_mac.mm
@@ -530,6 +530,8 @@ [paragraph_style setAlignment:cocoa_l10n_util::ShouldDoExperimentalRTLLayout() ? NSRightTextAlignment : NSLeftTextAlignment]; + if (@available(macOS 10.11, *)) + [paragraph_style setAllowsDefaultTighteningForTruncation:NO]; // If this is a URL, set the top-level paragraph direction to LTR (avoids RTL // characters from making the URL render from right to left, as per RFC 3987 // Section 4.1).
diff --git a/chrome/browser/ui/cocoa/tab_contents/chrome_web_contents_view_delegate_mac.h b/chrome/browser/ui/cocoa/tab_contents/chrome_web_contents_view_delegate_mac.h index bd85155..0e78170 100644 --- a/chrome/browser/ui/cocoa/tab_contents/chrome_web_contents_view_delegate_mac.h +++ b/chrome/browser/ui/cocoa/tab_contents/chrome_web_contents_view_delegate_mac.h
@@ -44,6 +44,9 @@ const content::ContextMenuParams& params) override; void ShowMenu(std::unique_ptr<RenderViewContextMenuBase> menu) override; + protected: + content::WebContents* web_contents() { return web_contents_; } + private: content::RenderWidgetHostView* GetActiveRenderWidgetHostView();
diff --git a/chrome/browser/ui/cocoa/tab_contents/chrome_web_contents_view_delegate_mac.mm b/chrome/browser/ui/cocoa/tab_contents/chrome_web_contents_view_delegate_mac.mm index 3df8d855..2ca0f76 100644 --- a/chrome/browser/ui/cocoa/tab_contents/chrome_web_contents_view_delegate_mac.mm +++ b/chrome/browser/ui/cocoa/tab_contents/chrome_web_contents_view_delegate_mac.mm
@@ -16,6 +16,7 @@ #include "chrome/browser/ui/tab_contents/chrome_web_contents_view_delegate.h" #include "content/public/browser/render_widget_host_view.h" #include "content/public/browser/web_contents.h" +#include "ui/base/ui_features.h" ChromeWebContentsViewDelegateMac::ChromeWebContentsViewDelegateMac( content::WebContents* web_contents) @@ -124,6 +125,7 @@ web_contents_->GetTopLevelRenderWidgetHostView(); } +#if !BUILDFLAG(MAC_VIEWS_BROWSER) namespace chrome { content::WebContentsViewDelegate* CreateWebContentsViewDelegate( @@ -132,3 +134,4 @@ } } // namespace chrome +#endif // MAC_VIEWS_BROWSER
diff --git a/chrome/browser/ui/extensions/blocked_action_bubble_delegate.cc b/chrome/browser/ui/extensions/blocked_action_bubble_delegate.cc index 332dd3e..232b5d0 100644 --- a/chrome/browser/ui/extensions/blocked_action_bubble_delegate.cc +++ b/chrome/browser/ui/extensions/blocked_action_bubble_delegate.cc
@@ -57,8 +57,7 @@ return extension_id_; } -void BlockedActionBubbleDelegate::OnBubbleShown( - const base::Closure& close_bubble_callback) {} +void BlockedActionBubbleDelegate::OnBubbleShown() {} void BlockedActionBubbleDelegate::OnBubbleClosed(CloseAction action) { base::ResetAndReturn(&callback_).Run(action);
diff --git a/chrome/browser/ui/extensions/blocked_action_bubble_delegate.h b/chrome/browser/ui/extensions/blocked_action_bubble_delegate.h index 2c63c2d..51df893 100644 --- a/chrome/browser/ui/extensions/blocked_action_bubble_delegate.h +++ b/chrome/browser/ui/extensions/blocked_action_bubble_delegate.h
@@ -30,7 +30,7 @@ std::unique_ptr<ToolbarActionsBarBubbleDelegate::ExtraViewInfo> GetExtraViewInfo() override; std::string GetAnchorActionId() override; - void OnBubbleShown(const base::Closure& close_bubble_callback) override; + void OnBubbleShown() override; void OnBubbleClosed(CloseAction action) override; base::Callback<void(CloseAction)> callback_;
diff --git a/chrome/browser/ui/extensions/extension_message_bubble_bridge.cc b/chrome/browser/ui/extensions/extension_message_bubble_bridge.cc index c1fbe33..6db09936 100644 --- a/chrome/browser/ui/extensions/extension_message_bubble_bridge.cc +++ b/chrome/browser/ui/extensions/extension_message_bubble_bridge.cc
@@ -81,9 +81,8 @@ : std::string(); } -void ExtensionMessageBubbleBridge::OnBubbleShown( - const base::Closure& close_bubble_callback) { - controller_->OnShown(close_bubble_callback); +void ExtensionMessageBubbleBridge::OnBubbleShown() { + controller_->OnShown(); } void ExtensionMessageBubbleBridge::OnBubbleClosed(CloseAction action) {
diff --git a/chrome/browser/ui/extensions/extension_message_bubble_bridge.h b/chrome/browser/ui/extensions/extension_message_bubble_bridge.h index 3e2dabe..3d4a6ac 100644 --- a/chrome/browser/ui/extensions/extension_message_bubble_bridge.h +++ b/chrome/browser/ui/extensions/extension_message_bubble_bridge.h
@@ -36,7 +36,7 @@ base::string16 GetLearnMoreButtonText() override; std::unique_ptr<ExtraViewInfo> GetExtraViewInfo() override; std::string GetAnchorActionId() override; - void OnBubbleShown(const base::Closure& close_bubble_callback) override; + void OnBubbleShown() override; void OnBubbleClosed(CloseAction action) override; std::unique_ptr<extensions::ExtensionMessageBubbleController> controller_;
diff --git a/chrome/browser/ui/extensions/extension_message_bubble_browsertest.cc b/chrome/browser/ui/extensions/extension_message_bubble_browsertest.cc index 2ea1480..f2557f4 100644 --- a/chrome/browser/ui/extensions/extension_message_bubble_browsertest.cc +++ b/chrome/browser/ui/extensions/extension_message_bubble_browsertest.cc
@@ -170,31 +170,6 @@ CloseBubble(second_browser); } -void ExtensionMessageBubbleBrowserTest:: - TestBubbleClosedAfterExtensionUninstall() { - const extensions::Extension* extension = - LoadExtension(test_data_dir_.AppendASCII("api_test") - .AppendASCII("override") - .AppendASCII("newtab")); - ASSERT_TRUE(extension); - - CheckBubbleIsNotPresent(browser(), false, false); - EXPECT_EQ(1, browser()->tab_strip_model()->count()); - chrome::NewTab(browser()); - EXPECT_EQ(2, browser()->tab_strip_model()->count()); - base::RunLoop().RunUntilIdle(); - CheckBubble(browser(), ANCHOR_BROWSER_ACTION, false); - - extension_service()->UninstallExtension( - extension->id(), extensions::UNINSTALL_REASON_FOR_TESTING, - base::Bind(&base::DoNothing), nullptr); - base::RunLoop().RunUntilIdle(); - - // If the only relevant extension was uninstalled, the bubble should - // automatically close. See crbug.com/748952. - CheckBubbleIsNotPresent(browser(), false, false); -} - void ExtensionMessageBubbleBrowserTest::TestUninstallDangerousExtension() { // Load an extension that overrides the proxy setting. ExtensionTestMessageListener listener("registered", false);
diff --git a/chrome/browser/ui/extensions/extension_message_bubble_browsertest.h b/chrome/browser/ui/extensions/extension_message_bubble_browsertest.h index 271712b..10fd818 100644 --- a/chrome/browser/ui/extensions/extension_message_bubble_browsertest.h +++ b/chrome/browser/ui/extensions/extension_message_bubble_browsertest.h
@@ -92,10 +92,6 @@ // Regression test for crbug.com/485614. void TestBubbleAnchoredToAppMenuWithOtherAction(); - // Tests that a displayed extension bubble will be closed after its associated - // extension is uninstalled. - void TestBubbleClosedAfterExtensionUninstall(); - // Tests that uninstalling the extension between when the bubble is originally // slated to show and when it does show is handled gracefully. // Regression test for crbug.com/531648.
diff --git a/chrome/browser/ui/input_method/input_method_engine.cc b/chrome/browser/ui/input_method/input_method_engine.cc index 9bb8ca7..0994e3e 100644 --- a/chrome/browser/ui/input_method/input_method_engine.cc +++ b/chrome/browser/ui/input_method/input_method_engine.cc
@@ -135,7 +135,7 @@ const ui::CompositionText& composition_text, uint32_t cursor_pos, bool is_visible) { - composition_.CopyFrom(composition_text); + composition_ = composition_text; // Use a black thin underline by default. if (composition_.ime_text_spans.empty()) { @@ -150,7 +150,7 @@ // until the key event is handled. if (input_context && !handling_key_event_) { input_context->UpdateCompositionText(composition_, cursor_pos, is_visible); - composition_.Clear(); + composition_ = ui::CompositionText(); } else { composition_changed_ = true; }
diff --git a/chrome/browser/ui/input_method/input_method_engine_base.cc b/chrome/browser/ui/input_method/input_method_engine_base.cc index 01625660..9c8e058 100644 --- a/chrome/browser/ui/input_method/input_method_engine_base.cc +++ b/chrome/browser/ui/input_method/input_method_engine_base.cc
@@ -412,7 +412,7 @@ input_context->UpdateCompositionText( composition_, composition_.selection.start(), true); } - composition_.Clear(); + composition_ = ui::CompositionText(); composition_changed_ = false; }
diff --git a/chrome/browser/ui/startup/default_browser_prompt.cc b/chrome/browser/ui/startup/default_browser_prompt.cc index 6402a3f..ca7cee5 100644 --- a/chrome/browser/ui/startup/default_browser_prompt.cc +++ b/chrome/browser/ui/startup/default_browser_prompt.cc
@@ -111,6 +111,9 @@ ResetCheckDefaultBrowserPref(profile_path); } else if (show_prompt && state == shell_integration::NOT_DEFAULT && shell_integration::CanSetAsDefaultBrowser()) { + // Only show the prompt if some other program is the user's default browser. + // In particular, don't show it if another install mode is default (e.g., + // don't prompt for Chrome Beta if stable Chrome is the default). ShowPrompt(); } }
diff --git a/chrome/browser/ui/startup/default_browser_prompt_win.cc b/chrome/browser/ui/startup/default_browser_prompt_win.cc index a3b2038c..3daad848 100644 --- a/chrome/browser/ui/startup/default_browser_prompt_win.cc +++ b/chrome/browser/ui/startup/default_browser_prompt_win.cc
@@ -19,7 +19,8 @@ // If the only available mode of setting the default browser requires // user interaction, it means this couldn't have been done yet. Therefore, - // we launch the dialog and inform the caller of it. + // we launch the dialog and inform the caller of it. Only take this step if + // neither this browser nor any side-by-side install is default. bool show_status = (shell_integration::GetDefaultWebClientSetPermission() == shell_integration::SET_DEFAULT_INTERACTIVE) && (shell_integration::GetDefaultBrowser() ==
diff --git a/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc b/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc index d0390d3..4064952a 100644 --- a/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc +++ b/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc
@@ -51,6 +51,7 @@ #include "components/prefs/pref_service.h" #include "content/public/browser/web_contents.h" #include "content/public/common/content_switches.h" +#include "content/public/test/test_navigation_observer.h" #include "content/public/test/test_utils.h" #include "extensions/browser/extension_system.h" #include "net/test/embedded_test_server/embedded_test_server.h" @@ -324,6 +325,44 @@ tab_strip->GetWebContentsAt(0)->GetURL().possibly_invalid_spec()); } +IN_PROC_BROWSER_TEST_F(StartupBrowserCreatorTest, OpenAppUrlShortcut) { + // Add --app=<url> to the command line. Tests launching legacy apps which may + // have been created by "Add to Desktop" in old versions of Chrome. + // TODO(mgiuca): Delete this feature (https://crbug.com/751029). We are + // keeping it for now to avoid disrupting existing workflows. + base::CommandLine command_line(base::CommandLine::NO_PROGRAM); + GURL url = ui_test_utils::GetTestUrl( + base::FilePath(base::FilePath::kCurrentDirectory), + base::FilePath(FILE_PATH_LITERAL("title2.html"))); + command_line.AppendSwitchASCII(switches::kApp, url.spec()); + + chrome::startup::IsFirstRun first_run = + first_run::IsChromeFirstRun() ? chrome::startup::IS_FIRST_RUN + : chrome::startup::IS_NOT_FIRST_RUN; + StartupBrowserCreatorImpl launch(base::FilePath(), command_line, first_run); + ASSERT_TRUE(launch.Launch(browser()->profile(), std::vector<GURL>(), false)); + + Browser* new_browser = FindOneOtherBrowser(browser()); + ASSERT_TRUE(new_browser); + + // The new window should be an app window. + EXPECT_TRUE(new_browser->is_app()); + + TabStripModel* tab_strip = new_browser->tab_strip_model(); + ASSERT_EQ(1, tab_strip->count()); + content::WebContents* web_contents = tab_strip->GetWebContentsAt(0); + // At this stage, the web contents' URL should be the one passed in to --app + // (but it will not yet be committed into the navigation controller). + EXPECT_EQ("title2.html", web_contents->GetVisibleURL().ExtractFileName()); + + // Wait until the navigation is complete. Then the URL will be committed to + // the navigation controller. + content::TestNavigationObserver observer(web_contents, 1); + observer.Wait(); + EXPECT_EQ("title2.html", + web_contents->GetLastCommittedURL().ExtractFileName()); +} + // App shortcuts are not implemented on mac os. #if !defined(OS_MACOSX) IN_PROC_BROWSER_TEST_F(StartupBrowserCreatorTest, OpenAppShortcutNoPref) {
diff --git a/chrome/browser/ui/startup/startup_browser_creator_impl.cc b/chrome/browser/ui/startup/startup_browser_creator_impl.cc index 162acc9..c482d2c 100644 --- a/chrome/browser/ui/startup/startup_browser_creator_impl.cc +++ b/chrome/browser/ui/startup/startup_browser_creator_impl.cc
@@ -1231,9 +1231,12 @@ if (net::NetworkChangeNotifier::IsOffline()) return; - // Do not welcome if Chrome was the default browser at startup. - if (g_browser_process->CachedDefaultWebClientState() == - shell_integration::IS_DEFAULT) { + // Do not welcome if this Chrome or another side-by-side install was the + // default browser at startup. + const shell_integration::DefaultWebClientState web_client_state = + g_browser_process->CachedDefaultWebClientState(); + if (web_client_state == shell_integration::IS_DEFAULT || + web_client_state == shell_integration::OTHER_MODE_IS_DEFAULT) { return; }
diff --git a/chrome/browser/ui/startup/startup_tab_provider.cc b/chrome/browser/ui/startup/startup_tab_provider.cc index faea7a0ef..d4cf7bc 100644 --- a/chrome/browser/ui/startup/startup_tab_provider.cc +++ b/chrome/browser/ui/startup/startup_tab_provider.cc
@@ -80,9 +80,13 @@ PrefService* local_state = g_browser_process->local_state(); bool has_seen_win10_promo = local_state && local_state->GetBoolean(prefs::kHasSeenWin10PromoPage); + const shell_integration::DefaultWebClientState web_client_state = + g_browser_process->CachedDefaultWebClientState(); + // Do not welcome if this Chrome or another side-by-side install was the + // default browser at startup. bool is_default_browser = - g_browser_process->CachedDefaultWebClientState() == - shell_integration::IS_DEFAULT; + web_client_state == shell_integration::IS_DEFAULT || + web_client_state == shell_integration::OTHER_MODE_IS_DEFAULT; return GetWin10OnboardingTabsForState( is_first_run, has_seen_welcome_page, has_seen_win10_promo, is_signin_allowed, is_signed_in, SetDefaultBrowserAllowed(local_state),
diff --git a/chrome/browser/ui/toolbar/test_toolbar_actions_bar_bubble_delegate.cc b/chrome/browser/ui/toolbar/test_toolbar_actions_bar_bubble_delegate.cc index 08944bf..69b1a442 100644 --- a/chrome/browser/ui/toolbar/test_toolbar_actions_bar_bubble_delegate.cc +++ b/chrome/browser/ui/toolbar/test_toolbar_actions_bar_bubble_delegate.cc
@@ -38,7 +38,7 @@ return nullptr; } std::string GetAnchorActionId() override { return std::string(); } - void OnBubbleShown(const base::Closure& close_bubble_callback) override { + void OnBubbleShown() override { CHECK(!parent_->shown_); parent_->shown_ = true; }
diff --git a/chrome/browser/ui/toolbar/toolbar_actions_bar_bubble_delegate.h b/chrome/browser/ui/toolbar/toolbar_actions_bar_bubble_delegate.h index b19550f1..189df92 100644 --- a/chrome/browser/ui/toolbar/toolbar_actions_bar_bubble_delegate.h +++ b/chrome/browser/ui/toolbar/toolbar_actions_bar_bubble_delegate.h
@@ -7,7 +7,6 @@ #include <string> -#include "base/callback_forward.h" #include "base/strings/string16.h" namespace gfx { @@ -82,9 +81,8 @@ // bubble should point to the center of the actions container. virtual std::string GetAnchorActionId() = 0; - // Called when the bubble is shown. Accepts a callback from platform-specifc - // ui code to close the bubble. - virtual void OnBubbleShown(const base::Closure& close_bubble_callback) = 0; + // Called when the bubble is shown. + virtual void OnBubbleShown() = 0; // Called when the bubble is closed with the type of action the user took. virtual void OnBubbleClosed(CloseAction action) = 0;
diff --git a/chrome/browser/ui/views/autofill/save_card_bubble_views.cc b/chrome/browser/ui/views/autofill/save_card_bubble_views.cc index 18b14d3..abd3c34 100644 --- a/chrome/browser/ui/views/autofill/save_card_bubble_views.cc +++ b/chrome/browser/ui/views/autofill/save_card_bubble_views.cc
@@ -9,6 +9,7 @@ #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" +#include "chrome/app/vector_icons/vector_icons.h" #include "chrome/browser/ui/browser_dialogs.h" #include "chrome/browser/ui/views/autofill/view_util.h" #include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" @@ -19,7 +20,9 @@ #include "components/strings/grit/components_strings.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h" +#include "ui/gfx/color_palette.h" #include "ui/gfx/geometry/insets.h" +#include "ui/gfx/paint_vector_icon.h" #include "ui/views/border.h" #include "ui/views/bubble/bubble_frame_view.h" #include "ui/views/controls/button/blue_button.h" @@ -119,8 +122,9 @@ // the stack and update the bubble. DCHECK(controller_); controller_->SetShowUploadConfirmTitle(true); - GetWidget()->UpdateWindowTitle(); view_stack_->Push(CreateRequestCvcView(), /*animate=*/true); + GetWidget()->UpdateWindowTitle(); + GetWidget()->UpdateWindowIcon(); // Disable the Save button until a valid CVC is entered: GetDialogClientView()->UpdateDialogButtons(); // Make the legal messaging footer appear: @@ -211,6 +215,19 @@ return controller_ ? controller_->GetWindowTitle() : base::string16(); } +gfx::ImageSkia SaveCardBubbleViews::GetWindowIcon() { + if (IsAutofillUpstreamShowGoogleLogoExperimentEnabled()) + return gfx::CreateVectorIcon(kGoogleGLogoIcon, 20, gfx::kPlaceholderColor); + return gfx::ImageSkia(); +} + +bool SaveCardBubbleViews::ShouldShowWindowIcon() const { + // Only show the Google logo on the first screen of the bubble: + return IsAutofillUpstreamShowGoogleLogoExperimentEnabled() && + (GetCurrentFlowStep() == UPLOAD_SAVE_ONLY_STEP || + GetCurrentFlowStep() == UPLOAD_SAVE_CVC_FIX_FLOW_STEP_1_OFFER_UPLOAD); +} + void SaveCardBubbleViews::WindowClosing() { if (controller_) controller_->OnBubbleClosed();
diff --git a/chrome/browser/ui/views/autofill/save_card_bubble_views.h b/chrome/browser/ui/views/autofill/save_card_bubble_views.h index 3c102bb..016f553 100644 --- a/chrome/browser/ui/views/autofill/save_card_bubble_views.h +++ b/chrome/browser/ui/views/autofill/save_card_bubble_views.h
@@ -61,6 +61,8 @@ // views::WidgetDelegate: bool ShouldShowCloseButton() const override; base::string16 GetWindowTitle() const override; + gfx::ImageSkia GetWindowIcon() override; + bool ShouldShowWindowIcon() const override; void WindowClosing() override; // views::LinkListener:
diff --git a/chrome/browser/ui/views/extensions/extension_message_bubble_view_browsertest.cc b/chrome/browser/ui/views/extensions/extension_message_bubble_view_browsertest.cc index 2ea4f4ed..696620c 100644 --- a/chrome/browser/ui/views/extensions/extension_message_bubble_view_browsertest.cc +++ b/chrome/browser/ui/views/extensions/extension_message_bubble_view_browsertest.cc
@@ -281,8 +281,3 @@ TestControlledNewTabPageMessageBubbleLearnMore) { TestControlledNewTabPageBubbleShown(true); } - -IN_PROC_BROWSER_TEST_F(NtpExtensionBubbleViewBrowserTest, - TestBubbleClosedAfterExtensionUninstall) { - TestBubbleClosedAfterExtensionUninstall(); -}
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view.cc index d64d4ee..17ae0b6 100644 --- a/chrome/browser/ui/views/frame/browser_non_client_frame_view.cc +++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view.cc
@@ -9,6 +9,7 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/profiles/avatar_menu.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/profiles/profile_attributes_entry.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/themes/theme_properties.h" #include "chrome/browser/ui/layout_constants.h" @@ -298,6 +299,11 @@ UpdateProfileIcons(); } +void BrowserNonClientFrameView::OnProfileHighResAvatarLoaded( + const base::FilePath& profile_path) { + UpdateTaskbarDecoration(); +} + const ui::ThemeProvider* BrowserNonClientFrameView::GetThemeProviderForProfile() const { // Because the frame's accessor reads the ThemeProvider from the profile and @@ -326,11 +332,17 @@ // with the default shortcut being pinned, we add the runtime badge for // safety. See crbug.com/313800. gfx::Image decoration; - AvatarMenu::GetImageForMenuButton( + AvatarMenu::ImageLoadStatus status = AvatarMenu::GetImageForMenuButton( browser_view()->browser()->profile()->GetPath(), &decoration); - // This can happen if the user deletes the current profile. - if (decoration.IsEmpty()) + + // If the user is using a Gaia picture and the picture is still being loaded, + // wait until the load finishes. This taskbar decoration will be triggered + // again upon the finish of the picture load. + if (status == AvatarMenu::ImageLoadStatus::LOADING || + status == AvatarMenu::ImageLoadStatus::PROFILE_DELETED) { return; + } + chrome::DrawTaskbarDecoration(frame_->GetNativeWindow(), &decoration); #endif }
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view.h b/chrome/browser/ui/views/frame/browser_non_client_frame_view.h index 730af36..70112de 100644 --- a/chrome/browser/ui/views/frame/browser_non_client_frame_view.h +++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view.h
@@ -115,6 +115,8 @@ void OnProfileWasRemoved(const base::FilePath& profile_path, const base::string16& profile_name) override; void OnProfileAvatarChanged(const base::FilePath& profile_path) override; + void OnProfileHighResAvatarLoaded( + const base::FilePath& profile_path) override; // Gets a theme provider that should be non-null even before we're added to a // view hierarchy.
diff --git a/chrome/browser/ui/views/frame/test_with_browser_view.cc b/chrome/browser/ui/views/frame/test_with_browser_view.cc index b600ed2..9fae7b4 100644 --- a/chrome/browser/ui/views/frame/test_with_browser_view.cc +++ b/chrome/browser/ui/views/frame/test_with_browser_view.cc
@@ -5,11 +5,11 @@ #include "chrome/browser/ui/views/frame/test_with_browser_view.h" #include "base/memory/ptr_util.h" +#include "base/threading/sequenced_task_runner_handle.h" #include "build/build_config.h" #include "chrome/browser/autocomplete/autocomplete_classifier_factory.h" #include "chrome/browser/autocomplete/chrome_autocomplete_provider_client.h" #include "chrome/browser/history/history_service_factory.h" -#include "chrome/browser/predictors/predictor_database.h" #include "chrome/browser/search_engines/chrome_template_url_service_client.h" #include "chrome/browser/search_engines/template_url_service_factory.h" #include "chrome/browser/search_engines/ui_thread_search_terms_data.h" @@ -82,7 +82,6 @@ #endif testing_io_thread_state_.reset(new chrome::TestingIOThreadState()); BrowserWithTestWindowTest::SetUp(); - predictor_db_.reset(new predictors::PredictorDatabase(GetProfile())); browser_view_ = static_cast<BrowserView*>(browser()->window()); } @@ -100,7 +99,6 @@ content::RunAllPendingInMessageLoop(content::BrowserThread::DB); BrowserWithTestWindowTest::TearDown(); testing_io_thread_state_.reset(); - predictor_db_.reset(); #if defined(OS_CHROMEOS) chromeos::input_method::Shutdown(); #endif
diff --git a/chrome/browser/ui/views/frame/test_with_browser_view.h b/chrome/browser/ui/views/frame/test_with_browser_view.h index d091378..db73a693 100644 --- a/chrome/browser/ui/views/frame/test_with_browser_view.h +++ b/chrome/browser/ui/views/frame/test_with_browser_view.h
@@ -14,10 +14,6 @@ class TestingIOThreadState; } -namespace predictors { -class PredictorDatabase; -} - class BrowserView; class ScopedTestingLocalState; @@ -41,7 +37,6 @@ private: BrowserView* browser_view_; // Not owned. std::unique_ptr<ScopedTestingLocalState> local_state_; - std::unique_ptr<predictors::PredictorDatabase> predictor_db_; std::unique_ptr<chrome::TestingIOThreadState> testing_io_thread_state_; DISALLOW_COPY_AND_ASSIGN(TestWithBrowserView);
diff --git a/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc b/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc index b1ac913d..840dd042 100644 --- a/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc +++ b/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc
@@ -639,8 +639,7 @@ inline_summary->SetLayoutManager(layout.release()); PaymentSheetRowBuilder builder( - this, l10n_util::GetStringUTF16( - IDS_PAYMENT_REQUEST_ORDER_SUMMARY_SECTION_NAME)); + this, l10n_util::GetStringUTF16(IDS_PAYMENTS_ORDER_SUMMARY_LABEL)); builder.Tag(PaymentSheetViewControllerTags::SHOW_ORDER_SUMMARY_BUTTON) .Id(DialogViewID::PAYMENT_SHEET_SUMMARY_SECTION);
diff --git a/chrome/browser/ui/views/payments/profile_list_view_controller.cc b/chrome/browser/ui/views/payments/profile_list_view_controller.cc index 96322d8..69840c3 100644 --- a/chrome/browser/ui/views/payments/profile_list_view_controller.cc +++ b/chrome/browser/ui/views/payments/profile_list_view_controller.cc
@@ -229,9 +229,7 @@ return GetShippingAddressSectionString(spec()->shipping_type()); } - int GetSecondaryButtonTextId() override { - return IDS_AUTOFILL_ADD_ADDRESS_CAPTION; - } + int GetSecondaryButtonTextId() override { return IDS_PAYMENTS_ADD_ADDRESS; } int GetSecondaryButtonTag() override { return static_cast<int>( @@ -327,9 +325,7 @@ IDS_PAYMENT_REQUEST_CONTACT_INFO_SECTION_NAME); } - int GetSecondaryButtonTextId() override { - return IDS_AUTOFILL_ADD_CONTACT_CAPTION; - } + int GetSecondaryButtonTextId() override { return IDS_PAYMENTS_ADD_CONTACT; } int GetSecondaryButtonTag() override { return static_cast<int>(
diff --git a/chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views_mac.h b/chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views_mac.h new file mode 100644 index 0000000..7ca515a2 --- /dev/null +++ b/chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views_mac.h
@@ -0,0 +1,24 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_VIEWS_TAB_CONTENTS_CHROME_WEB_CONTENTS_VIEW_DELEGATE_VIEWS_MAC_H_ +#define CHROME_BROWSER_UI_VIEWS_TAB_CONTENTS_CHROME_WEB_CONTENTS_VIEW_DELEGATE_VIEWS_MAC_H_ + +#import "chrome/browser/ui/cocoa/tab_contents/chrome_web_contents_view_delegate_mac.h" + +// A MacViews specific class that extends ChromeWebContentsViewDelegateMac. +class ChromeWebContentsViewDelegateViewsMac + : public ChromeWebContentsViewDelegateMac { + public: + explicit ChromeWebContentsViewDelegateViewsMac( + content::WebContents* web_contents); + + // ChromeWebContentsViewDelegateMac: + void SizeChanged(const gfx::Size& size) override; + + private: + DISALLOW_COPY_AND_ASSIGN(ChromeWebContentsViewDelegateViewsMac); +}; + +#endif // CHROME_BROWSER_UI_VIEWS_TAB_CONTENTS_CHROME_WEB_CONTENTS_VIEW_DELEGATE_VIEWS_MAC_H_
diff --git a/chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views_mac.mm b/chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views_mac.mm new file mode 100644 index 0000000..572ce6f4 --- /dev/null +++ b/chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views_mac.mm
@@ -0,0 +1,35 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views_mac.h" + +#include "chrome/browser/ui/sad_tab_helper.h" +#include "chrome/browser/ui/views/sad_tab_view.h" +#include "content/public/browser/web_contents.h" +#include "ui/base/ui_features.h" +#include "ui/views/widget/widget.h" + +ChromeWebContentsViewDelegateViewsMac::ChromeWebContentsViewDelegateViewsMac( + content::WebContents* web_contents) + : ChromeWebContentsViewDelegateMac(web_contents) {} + +void ChromeWebContentsViewDelegateViewsMac::SizeChanged(const gfx::Size& size) { + SadTabHelper* sad_tab_helper = SadTabHelper::FromWebContents(web_contents()); + if (!sad_tab_helper) + return; + SadTabView* sad_tab = static_cast<SadTabView*>(sad_tab_helper->sad_tab()); + if (sad_tab) + sad_tab->GetWidget()->SetBounds(gfx::Rect(size)); +} + +#if BUILDFLAG(MAC_VIEWS_BROWSER) +namespace chrome { + +content::WebContentsViewDelegate* CreateWebContentsViewDelegate( + content::WebContents* web_contents) { + return new ChromeWebContentsViewDelegateViewsMac(web_contents); +} + +} // namespace chrome +#endif // MAC_VIEWS_BROWSER
diff --git a/chrome/browser/ui/views/toolbar/toolbar_actions_bar_bubble_views.cc b/chrome/browser/ui/views/toolbar/toolbar_actions_bar_bubble_views.cc index 96d8a1b..37de419f 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_actions_bar_bubble_views.cc +++ b/chrome/browser/ui/views/toolbar/toolbar_actions_bar_bubble_views.cc
@@ -42,14 +42,7 @@ ToolbarActionsBarBubbleViews::~ToolbarActionsBarBubbleViews() {} void ToolbarActionsBarBubbleViews::Show() { - // Passing the Widget pointer (via GetWidget()) below in the lambda is safe - // because the controller, which eventually invokes the callback passed to - // OnBubbleShown, will never outlive the bubble view. This is because the - // ToolbarActionsBarBubbleView owns the ToolbarActionsBarBubbleDelegate. - // The ToolbarActionsBarBubbleDelegate is an ExtensionMessageBubbleBridge, - // which owns the ExtensionMessageBubbleController. - delegate_->OnBubbleShown( - base::Bind([](views::Widget* widget) { widget->Close(); }, GetWidget())); + delegate_->OnBubbleShown(); GetWidget()->Show(); }
diff --git a/chrome/browser/ui/webui/chromeos/login/encryption_migration_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/encryption_migration_screen_handler.cc index 0fe44e7..d147c91 100644 --- a/chrome/browser/ui/webui/chromeos/login/encryption_migration_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/encryption_migration_screen_handler.cc
@@ -8,7 +8,6 @@ #include <string> #include <utility> -#include "ash/system/devicetype_utils.h" #include "base/command_line.h" #include "base/files/file_path.h" #include "base/metrics/histogram_macros.h" @@ -41,6 +40,7 @@ #include "services/device/public/interfaces/wake_lock_provider.mojom.h" #include "services/service_manager/public/cpp/connector.h" #include "ui/base/text/bytes_formatting.h" +#include "ui/chromeos/devicetype_utils.h" namespace { @@ -300,19 +300,19 @@ ::login::LocalizedValuesBuilder* builder) { builder->Add("migrationReadyTitle", IDS_ENCRYPTION_MIGRATION_READY_TITLE); builder->Add("migrationReadyDescription", - ash::SubstituteChromeOSDeviceType( + ui::SubstituteChromeOSDeviceType( IDS_ENCRYPTION_MIGRATION_READY_DESCRIPTION)); builder->Add("migrationMigratingTitle", IDS_ENCRYPTION_MIGRATION_MIGRATING_TITLE); builder->Add("migrationMigratingDescription", - ash::SubstituteChromeOSDeviceType( + ui::SubstituteChromeOSDeviceType( IDS_ENCRYPTION_MIGRATION_MIGRATING_DESCRIPTION)); builder->Add("migrationProgressLabel", IDS_ENCRYPTION_MIGRATION_PROGRESS_LABEL); builder->Add("migrationBatteryWarningLabel", IDS_ENCRYPTION_MIGRATION_BATTERY_WARNING_LABEL); builder->Add("migrationAskChargeMessage", - ash::SubstituteChromeOSDeviceType( + ui::SubstituteChromeOSDeviceType( IDS_ENCRYPTION_MIGRATION_ASK_CHARGE_MESSAGE)); builder->Add("migrationNecessaryBatteryLevelLabel", IDS_ENCRYPTION_MIGRATION_NECESSARY_BATTERY_LEVEL_MESSAGE); @@ -322,7 +322,7 @@ builder->Add("migrationFailedSubtitle", IDS_ENCRYPTION_MIGRATION_FAILED_SUBTITLE); builder->Add("migrationFailedMessage", - ash::SubstituteChromeOSDeviceType( + ui::SubstituteChromeOSDeviceType( IDS_ENCRYPTION_MIGRATION_FAILED_MESSAGE)); builder->Add("migrationNospaceWarningLabel", IDS_ENCRYPTION_MIGRATION_NOSPACE_WARNING_LABEL);
diff --git a/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.cc index 0499e1d..6abc19d 100644 --- a/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.cc
@@ -6,7 +6,6 @@ #include <algorithm> -#include "ash/system/devicetype_utils.h" #include "base/bind.h" #include "base/bind_helpers.h" #include "base/files/file_util.h" @@ -35,6 +34,7 @@ #include "google_apis/gaia/gaia_urls.h" #include "google_apis/gaia/google_service_auth_error.h" #include "ui/base/l10n/l10n_util.h" +#include "ui/chromeos/devicetype_utils.h" namespace chromeos { namespace { @@ -204,7 +204,7 @@ void EnrollmentScreenHandler::ShowAttestationBasedEnrollmentSuccessScreen( const std::string& enterprise_domain) { - CallJS("showAttestationBasedEnrollmentSuccess", ash::GetChromeOSDeviceName(), + CallJS("showAttestationBasedEnrollmentSuccess", ui::GetChromeOSDeviceName(), enterprise_domain); } @@ -393,7 +393,7 @@ builder->Add("oauthEnrollNextBtn", IDS_OFFLINE_LOGIN_NEXT_BUTTON_TEXT); builder->Add("oauthEnrollSkip", IDS_ENTERPRISE_ENROLLMENT_SKIP); builder->AddF("oauthEnrollSuccess", IDS_ENTERPRISE_ENROLLMENT_SUCCESS, - ash::GetChromeOSDeviceName()); + ui::GetChromeOSDeviceName()); builder->Add("oauthEnrollDeviceInformation", IDS_ENTERPRISE_ENROLLMENT_DEVICE_INFORMATION); builder->Add("oauthEnrollExplainAttributeLink", @@ -659,7 +659,7 @@ void EnrollmentScreenHandler::ShowErrorForDevice(int message_id, bool retry) { ShowErrorMessage( - l10n_util::GetStringFUTF8(message_id, ash::GetChromeOSDeviceName()), + l10n_util::GetStringFUTF8(message_id, ui::GetChromeOSDeviceName()), retry); }
diff --git a/chrome/browser/ui/webui/chromeos/login/error_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/error_screen_handler.cc index af75d9e..b8d7f9d 100644 --- a/chrome/browser/ui/webui/chromeos/login/error_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/error_screen_handler.cc
@@ -4,13 +4,13 @@ #include "chrome/browser/ui/webui/chromeos/login/error_screen_handler.h" -#include "ash/system/devicetype_utils.h" #include "base/message_loop/message_loop.h" #include "base/time/time.h" #include "chrome/browser/chromeos/login/screens/error_screen.h" #include "chrome/grit/chromium_strings.h" #include "chrome/grit/generated_resources.h" #include "components/login/localized_values_builder.h" +#include "ui/chromeos/devicetype_utils.h" #include "ui/strings/grit/ui_strings.h" namespace { @@ -70,11 +70,11 @@ void ErrorScreenHandler::DeclareLocalizedValues( ::login::LocalizedValuesBuilder* builder) { - builder->Add("deviceType", ash::GetChromeOSDeviceName()); + builder->Add("deviceType", ui::GetChromeOSDeviceName()); builder->Add("loginErrorTitle", IDS_LOGIN_ERROR_TITLE); builder->Add("rollbackErrorTitle", IDS_RESET_SCREEN_REVERT_ERROR); builder->Add("signinOfflineMessageBody", - ash::SubstituteChromeOSDeviceType(IDS_LOGIN_OFFLINE_MESSAGE)); + ui::SubstituteChromeOSDeviceType(IDS_LOGIN_OFFLINE_MESSAGE)); builder->Add("kioskOfflineMessageBody", IDS_KIOSK_OFFLINE_MESSAGE); builder->Add("kioskOnlineTitle", IDS_LOGIN_NETWORK_RESTORED_TITLE); builder->Add("kioskOnlineMessageBody", IDS_KIOSK_ONLINE_MESSAGE); @@ -91,7 +91,7 @@ IDS_LOGIN_MAYBE_CAPTIVE_PORTAL_NETWORK_SELECT); builder->Add("signinProxyMessageText", IDS_LOGIN_PROXY_ERROR_MESSAGE); builder->Add("updateOfflineMessageBody", - ash::SubstituteChromeOSDeviceType(IDS_UPDATE_OFFLINE_MESSAGE)); + ui::SubstituteChromeOSDeviceType(IDS_UPDATE_OFFLINE_MESSAGE)); builder->Add("updateProxyMessageText", IDS_UPDATE_PROXY_ERROR_MESSAGE); builder->AddF("localStateErrorText0", IDS_LOCAL_STATE_ERROR_TEXT_0, IDS_SHORT_PRODUCT_NAME);
diff --git a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc index 4359367..d224d6f 100644 --- a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc
@@ -4,7 +4,6 @@ #include "chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h" -#include "ash/system/devicetype_utils.h" #include "base/bind.h" #include "base/callback.h" #include "base/feature_list.h" @@ -54,6 +53,7 @@ #include "ui/base/ime/chromeos/input_method_manager.h" #include "ui/base/ime/chromeos/input_method_util.h" #include "ui/base/l10n/l10n_util.h" +#include "ui/chromeos/devicetype_utils.h" using content::BrowserThread; namespace em = enterprise_management; @@ -437,7 +437,7 @@ IDS_LOGIN_FATAL_ERROR_TRY_AGAIN_BUTTON); builder->AddF("loginWelcomeMessage", IDS_LOGIN_WELCOME_MESSAGE, - ash::GetChromeOSDeviceTypeResourceId()); + ui::GetChromeOSDeviceTypeResourceId()); builder->Add("offlineLoginEmail", IDS_OFFLINE_LOGIN_EMAIL); builder->Add("offlineLoginPassword", IDS_OFFLINE_LOGIN_PASSWORD); builder->Add("offlineLoginInvalidEmail", IDS_OFFLINE_LOGIN_INVALID_EMAIL);
diff --git a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc index 6eb392d..95416e94 100644 --- a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
@@ -14,8 +14,6 @@ #include "ash/public/interfaces/shutdown.mojom.h" #include "ash/public/interfaces/tray_action.mojom.h" #include "ash/shell.h" -#include "ash/shutdown_reason.h" -#include "ash/system/devicetype_utils.h" #include "ash/wallpaper/wallpaper_controller.h" #include "base/bind.h" #include "base/i18n/number_formatting.h" @@ -106,6 +104,7 @@ #include "ui/base/ime/chromeos/input_method_manager.h" #include "ui/base/ime/chromeos/input_method_util.h" #include "ui/base/webui/web_ui_util.h" +#include "ui/chromeos/devicetype_utils.h" #include "ui/gfx/color_analysis.h" #include "ui/gfx/color_utils.h" @@ -405,7 +404,7 @@ builder->Add("forgotOldPasswordButtonText", IDS_LOGIN_PASSWORD_CHANGED_FORGOT_PASSWORD); builder->AddF("passwordChangedTitle", IDS_LOGIN_PASSWORD_CHANGED_TITLE, - ash::GetChromeOSDeviceName()); + ui::GetChromeOSDeviceName()); builder->Add("passwordChangedProceedAnywayTitle", IDS_LOGIN_PASSWORD_CHANGED_PROCEED_ANYWAY); builder->Add("passwordChangedTryAgain", IDS_LOGIN_PASSWORD_CHANGED_TRY_AGAIN); @@ -452,7 +451,7 @@ builder->Add("samlNotice", IDS_LOGIN_SAML_NOTICE); builder->Add("samlNoticeWithVideo", IDS_LOGIN_SAML_NOTICE_WITH_VIDEO); builder->AddF("confirmPasswordTitle", IDS_LOGIN_CONFIRM_PASSWORD_TITLE, - ash::GetChromeOSDeviceName()); + ui::GetChromeOSDeviceName()); builder->Add("manualPasswordTitle", IDS_LOGIN_MANUAL_PASSWORD_TITLE); builder->Add("manualPasswordInputLabel", IDS_LOGIN_MANUAL_PASSWORD_INPUT_LABEL);
diff --git a/chrome/browser/ui/webui/chromeos/network_element_localized_strings_provider.cc b/chrome/browser/ui/webui/chromeos/network_element_localized_strings_provider.cc index ef5eb81..c7c5d25 100644 --- a/chrome/browser/ui/webui/chromeos/network_element_localized_strings_provider.cc +++ b/chrome/browser/ui/webui/chromeos/network_element_localized_strings_provider.cc
@@ -42,6 +42,173 @@ builder->Add(entry.name, entry.id); } +void AddDetailsLocalizedStrings(content::WebUIDataSource* html_source) { + struct { + const char* name; + int id; + } localized_strings[] = { + {"OncTypeCellular", IDS_NETWORK_TYPE_MOBILE_DATA}, + {"OncTypeEthernet", IDS_NETWORK_TYPE_ETHERNET}, + {"OncTypeTether", IDS_NETWORK_TYPE_MOBILE_DATA}, + {"OncTypeVPN", IDS_NETWORK_TYPE_VPN}, + {"OncTypeWiFi", IDS_NETWORK_TYPE_WIFI}, + {"OncTypeWiMAX", IDS_NETWORK_TYPE_WIMAX}, + {"networkListItemConnected", IDS_STATUSBAR_NETWORK_DEVICE_CONNECTED}, + {"networkListItemConnecting", IDS_STATUSBAR_NETWORK_DEVICE_CONNECTING}, + {"networkListItemConnectingTo", IDS_NETWORK_LIST_CONNECTING_TO}, + {"networkListItemNotConnected", IDS_NETWORK_LIST_NOT_CONNECTED}, + {"vpnNameTemplate", IDS_NETWORK_LIST_THIRD_PARTY_VPN_NAME_TEMPLATE}, + }; + for (const auto& entry : localized_strings) + html_source->AddLocalizedString(entry.name, entry.id); +} + +void AddOncLocalizedStrings(content::WebUIDataSource* html_source) { + struct { + const char* name; + int id; + } localized_strings[] = { + // Thes strings are generated by prepending 'Onc' to the ONC property + // name. Any '.' in the property name is replaced with '-'. Properties + // with translatable enumerated values have the value appended after '_'. + {"OncCellular-APN-AccessPointName", + IDS_ONC_CELLULAR_APN_ACCESS_POINT_NAME}, + {"OncCellular-APN-AccessPointName_none", + IDS_ONC_CELLULAR_APN_ACCESS_POINT_NAME_NONE}, + {"OncCellular-APN-Password", IDS_ONC_CELLULAR_APN_PASSWORD}, + {"OncCellular-APN-Username", IDS_ONC_CELLULAR_APN_USERNAME}, + {"OncCellular-ActivationState", IDS_ONC_CELLULAR_ACTIVATION_STATE}, + {"OncCellular-ActivationState_Activated", + IDS_ONC_CELLULAR_ACTIVATION_STATE_ACTIVATED}, + {"OncCellular-ActivationState_Activating", + IDS_ONC_CELLULAR_ACTIVATION_STATE_ACTIVATING}, + {"OncCellular-ActivationState_NotActivated", + IDS_ONC_CELLULAR_ACTIVATION_STATE_NOT_ACTIVATED}, + {"OncCellular-ActivationState_PartiallyActivated", + IDS_ONC_CELLULAR_ACTIVATION_STATE_PARTIALLY_ACTIVATED}, + {"OncCellular-Carrier", IDS_ONC_CELLULAR_CARRIER}, + {"OncCellular-Family", IDS_ONC_CELLULAR_FAMILY}, + {"OncCellular-FirmwareRevision", IDS_ONC_CELLULAR_FIRMWARE_REVISION}, + {"OncCellular-HardwareRevision", IDS_ONC_CELLULAR_HARDWARE_REVISION}, + {"OncCellular-HomeProvider-Code", IDS_ONC_CELLULAR_HOME_PROVIDER_CODE}, + {"OncCellular-HomeProvider-Country", + IDS_ONC_CELLULAR_HOME_PROVIDER_COUNTRY}, + {"OncCellular-HomeProvider-Name", IDS_ONC_CELLULAR_HOME_PROVIDER_NAME}, + {"OncCellular-Manufacturer", IDS_ONC_CELLULAR_MANUFACTURER}, + {"OncCellular-ModelID", IDS_ONC_CELLULAR_MODEL_ID}, + {"OncCellular-NetworkTechnology", IDS_ONC_CELLULAR_NETWORK_TECHNOLOGY}, + {"OncCellular-PRLVersion", IDS_ONC_CELLULAR_PRL_VERSION}, + {"OncCellular-RoamingState", IDS_ONC_CELLULAR_ROAMING_STATE}, + {"OncCellular-RoamingState_Home", IDS_ONC_CELLULAR_ROAMING_STATE_HOME}, + {"OncCellular-RoamingState_Roaming", + IDS_ONC_CELLULAR_ROAMING_STATE_ROAMING}, + {"OncCellular-ServingOperator-Code", + IDS_ONC_CELLULAR_SERVING_OPERATOR_CODE}, + {"OncCellular-ServingOperator-Name", + IDS_ONC_CELLULAR_SERVING_OPERATOR_NAME}, + {"OncConnected", IDS_ONC_CONNECTED}, + {"OncConnecting", IDS_ONC_CONNECTING}, + {"OncEAP-AnonymousIdentity", IDS_ONC_EAP_ANONYMOUS_IDENTITY}, + {"OncEAP-Identity", IDS_ONC_EAP_IDENTITY}, + {"OncEAP-Inner", IDS_ONC_EAP_INNER}, + {"OncEAP-Inner_Automatic", IDS_ONC_EAP_INNER_AUTOMATIC}, + {"OncEAP-Inner_CHAP", IDS_ONC_EAP_INNER_CHAP}, + {"OncEAP-Inner_GTC", IDS_ONC_EAP_INNER_GTC}, + {"OncEAP-Inner_MD5", IDS_ONC_EAP_INNER_MD5}, + {"OncEAP-Inner_MSCHAP", IDS_ONC_EAP_INNER_MSCHAP}, + {"OncEAP-Inner_MSCHAPv2", IDS_ONC_EAP_INNER_MSCHAPV2}, + {"OncEAP-Inner_PAP", IDS_ONC_EAP_INNER_PAP}, + {"OncEAP-Outer", IDS_ONC_EAP_OUTER}, + {"OncEAP-Outer_LEAP", IDS_ONC_EAP_OUTER_LEAP}, + {"OncEAP-Outer_PEAP", IDS_ONC_EAP_OUTER_PEAP}, + {"OncEAP-Outer_EAP-TLS", IDS_ONC_EAP_OUTER_TLS}, + {"OncEAP-Outer_EAP-TTLS", IDS_ONC_EAP_OUTER_TTLS}, + {"OncEAP-Password", IDS_ONC_WIFI_PASSWORD}, + {"OncEAP-SubjectMatch", IDS_ONC_EAP_SUBJECT_MATCH}, + {"OncMacAddress", IDS_ONC_MAC_ADDRESS}, + {"OncNotConnected", IDS_ONC_NOT_CONNECTED}, + {"OncRestrictedConnectivity", IDS_ONC_RESTRICTED_CONNECTIVITY}, + {"OncTether-BatteryPercentage", IDS_ONC_TETHER_BATTERY_PERCENTAGE}, + {"OncTether-BatteryPercentage_Value", + IDS_ONC_TETHER_BATTERY_PERCENTAGE_VALUE}, + {"OncTether-SignalStrength", IDS_ONC_TETHER_SIGNAL_STRENGTH}, + {"OncTether-SignalStrength_Weak", IDS_ONC_TETHER_SIGNAL_STRENGTH_WEAK}, + {"OncTether-SignalStrength_Okay", IDS_ONC_TETHER_SIGNAL_STRENGTH_OKAY}, + {"OncTether-SignalStrength_Good", IDS_ONC_TETHER_SIGNAL_STRENGTH_GOOD}, + {"OncTether-SignalStrength_Strong", + IDS_ONC_TETHER_SIGNAL_STRENGTH_STRONG}, + {"OncTether-SignalStrength_VeryStrong", + IDS_ONC_TETHER_SIGNAL_STRENGTH_VERY_STRONG}, + {"OncTether-Carrier", IDS_ONC_TETHER_CARRIER}, + {"OncTether-Carrier_Unknown", IDS_ONC_TETHER_CARRIER_UNKNOWN}, + {"OncVPN-Host", IDS_ONC_VPN_HOST}, + {"OncVPN-L2TP-Username", IDS_ONC_VPN_L2TP_USERNAME}, + {"OncVPN-OpenVPN-Username", IDS_ONC_VPN_OPEN_VPN_USERNAME}, + {"OncVPN-ThirdPartyVPN-ProviderName", + IDS_ONC_VPN_THIRD_PARTY_VPN_PROVIDER_NAME}, + {"OncVPN-Type", IDS_ONC_VPN_TYPE}, + {"OncWiFi-Frequency", IDS_ONC_WIFI_FREQUENCY}, + {"OncWiFi-Passphrase", IDS_ONC_WIFI_PASSWORD}, + {"OncWiFi-SSID", IDS_ONC_WIFI_SSID}, + {"OncWiFi-Security", IDS_ONC_WIFI_SECURITY}, + {"OncWiFi-Security_None", IDS_ONC_WIFI_SECURITY_NONE}, + {"OncWiFi-Security_WEP-PSK", IDS_ONC_WIFI_SECURITY_WEP}, + {"OncWiFi-Security_WPA-EAP", IDS_ONC_WIFI_SECURITY_EAP}, + {"OncWiFi-Security_WPA-PSK", IDS_ONC_WIFI_SECURITY_PSK}, + {"OncWiFi-Security_WEP-8021X", IDS_ONC_WIFI_SECURITY_EAP}, + {"OncWiFi-SignalStrength", IDS_ONC_WIFI_SIGNAL_STRENGTH}, + {"OncWiMAX-EAP-Identity", IDS_ONC_WIMAX_EAP_IDENTITY}, + {"Oncipv4-Gateway", IDS_ONC_IPV4_GATEWAY}, + {"Oncipv4-IPAddress", IDS_ONC_IPV4_ADDRESS}, + {"Oncipv4-RoutingPrefix", IDS_ONC_IPV4_ROUTING_PREFIX}, + {"Oncipv6-IPAddress", IDS_ONC_IPV6_ADDRESS}, + }; + for (const auto& entry : localized_strings) + html_source->AddLocalizedString(entry.name, entry.id); +} + +void AddConfigLocalizedStrings(content::WebUIDataSource* html_source) { + struct { + const char* name; + int id; + } localized_strings[] = { + {"networkProxy", IDS_SETTINGS_INTERNET_NETWORK_PROXY_PROXY}, + {"networkProxyAddException", + IDS_SETTINGS_INTERNET_NETWORK_PROXY_ADD_EXCEPTION}, + {"networkProxyAllowShared", + IDS_SETTINGS_INTERNET_NETWORK_PROXY_ALLOW_SHARED}, + {"networkProxyAllowSharedWarningTitle", + IDS_SETTINGS_INTERNET_NETWORK_PROXY_ALLOW_SHARED_WARNING_TITLE}, + {"networkProxyAllowSharedWarningMessage", + IDS_SETTINGS_INTERNET_NETWORK_PROXY_ALLOW_SHARED_WARNING_MESSAGE}, + {"networkProxyAutoConfig", + IDS_SETTINGS_INTERNET_NETWORK_PROXY_AUTO_CONFIG}, + {"networkProxyConnectionType", + IDS_SETTINGS_INTERNET_NETWORK_PROXY_CONNECTION_TYPE}, + {"networkProxyEnforcedPolicy", + IDS_SETTINGS_INTERNET_NETWORK_PROXY_ENFORCED_POLICY}, + {"networkProxyExceptionList", + IDS_SETTINGS_INTERNET_NETWORK_PROXY_EXCEPTION_LIST}, + {"networkProxyFtp", IDS_SETTINGS_INTERNET_NETWORK_PROXY_FTP_PROXY}, + {"networkProxyHttp", IDS_SETTINGS_INTERNET_NETWORK_PROXY_HTTP_PROXY}, + {"networkProxyPort", IDS_SETTINGS_INTERNET_NETWORK_PROXY_PORT}, + {"networkProxyShttp", IDS_SETTINGS_INTERNET_NETWORK_PROXY_SHTTP_PROXY}, + {"networkProxySocks", IDS_SETTINGS_INTERNET_NETWORK_PROXY_SOCKS_HOST}, + {"networkProxyTypeDirect", + IDS_SETTINGS_INTERNET_NETWORK_PROXY_TYPE_DIRECT}, + {"networkProxyTypeManual", + IDS_SETTINGS_INTERNET_NETWORK_PROXY_TYPE_MANUAL}, + {"networkProxyTypePac", IDS_SETTINGS_INTERNET_NETWORK_PROXY_TYPE_PAC}, + {"networkProxyTypeWpad", IDS_SETTINGS_INTERNET_NETWORK_PROXY_TYPE_WPAD}, + {"networkProxyUseSame", IDS_SETTINGS_INTERNET_NETWORK_PROXY_USE_SAME}, + {"networkAccessPoint", IDS_SETTINGS_INTERNET_NETWORK_ACCESS_POINT}, + {"networkNameservers", IDS_SETTINGS_INTERNET_NETWORK_NAMESERVERS}, + {"networkProxyWpad", IDS_SETTINGS_INTERNET_NETWORK_PROXY_WPAD}, + }; + for (const auto& entry : localized_strings) + html_source->AddLocalizedString(entry.name, entry.id); +} + } // namespace network_element } // namespace chromeos
diff --git a/chrome/browser/ui/webui/chromeos/network_element_localized_strings_provider.h b/chrome/browser/ui/webui/chromeos/network_element_localized_strings_provider.h index a16ead5..2c1154e 100644 --- a/chrome/browser/ui/webui/chromeos/network_element_localized_strings_provider.h +++ b/chrome/browser/ui/webui/chromeos/network_element_localized_strings_provider.h
@@ -23,6 +23,13 @@ // Same as AddLocalizedStrings but for a LocalizedValuesBuilder. void AddLocalizedValuesToBuilder(::login::LocalizedValuesBuilder* builder); +// Adds ONC strings used by the details dialog used in Settings and WebUI. +void AddOncLocalizedStrings(content::WebUIDataSource* html_source); + +// Adds configuration strings used by the details dialog used in Settings and +// WebUI. +void AddConfigLocalizedStrings(content::WebUIDataSource* html_source); + } // namespace network_element } // namespace chromeos
diff --git a/chrome/browser/ui/webui/chromeos/proxy_settings_ui.cc b/chrome/browser/ui/webui/chromeos/proxy_settings_ui.cc index 33114a5..53455aa 100644 --- a/chrome/browser/ui/webui/chromeos/proxy_settings_ui.cc +++ b/chrome/browser/ui/webui/chromeos/proxy_settings_ui.cc
@@ -4,140 +4,65 @@ #include "chrome/browser/ui/webui/chromeos/proxy_settings_ui.h" -#include <memory> -#include <string> -#include <utility> - -#include "base/macros.h" -#include "base/memory/ptr_util.h" -#include "base/memory/ref_counted_memory.h" -#include "base/values.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/chromeos/system/input_device_settings.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/webui/options/chromeos/core_chromeos_options_handler.h" -#include "chrome/browser/ui/webui/options/chromeos/internet_options_handler_strings.h" -#include "chrome/browser/ui/webui/options/chromeos/proxy_handler.h" -#include "chrome/common/chrome_constants.h" +#include "chrome/browser/ui/webui/chromeos/network_element_localized_strings_provider.h" #include "chrome/common/url_constants.h" #include "chrome/grit/browser_resources.h" -#include "chromeos/chromeos_constants.h" -#include "content/public/browser/url_data_source.h" -#include "content/public/browser/web_contents.h" +#include "chrome/grit/generated_resources.h" +#include "components/strings/grit/components_strings.h" #include "content/public/browser/web_ui.h" -#include "content/public/browser/web_ui_message_handler.h" -#include "ui/base/resource/resource_bundle.h" -#include "ui/base/webui/jstemplate_builder.h" -#include "ui/base/webui/web_ui_util.h" +#include "content/public/browser/web_ui_data_source.h" -using content::WebContents; -using content::WebUIMessageHandler; +namespace chromeos { namespace { -class ProxySettingsHTMLSource : public content::URLDataSource { - public: - explicit ProxySettingsHTMLSource(base::DictionaryValue* localized_strings); - - // content::URLDataSource implementation. - std::string GetSource() const override; - void StartDataRequest( - const std::string& path, - const content::ResourceRequestInfo::WebContentsGetter& wc_getter, - const content::URLDataSource::GotDataCallback& callback) override; - std::string GetMimeType(const std::string&) const override { - return "text/html"; - } - bool ShouldAddContentSecurityPolicy() const override { return false; } - bool AllowCaching() const override { - // Should not be cached to reflect dynamically-generated contents that - // may depend on current settings. - return false; - } - - protected: - ~ProxySettingsHTMLSource() override {} - - private: - std::unique_ptr<base::DictionaryValue> localized_strings_; - - DISALLOW_COPY_AND_ASSIGN(ProxySettingsHTMLSource); -}; - -ProxySettingsHTMLSource::ProxySettingsHTMLSource( - base::DictionaryValue* localized_strings) - : localized_strings_(localized_strings) { -} - -std::string ProxySettingsHTMLSource::GetSource() const { - return chrome::kChromeUIProxySettingsHost; -} - -void ProxySettingsHTMLSource::StartDataRequest( - const std::string& path, - const content::ResourceRequestInfo::WebContentsGetter& wc_getter, - const content::URLDataSource::GotDataCallback& callback) { - const std::string& app_locale = g_browser_process->GetApplicationLocale(); - webui::SetLoadTimeDataDefaults(app_locale, localized_strings_.get()); - static const base::StringPiece html( - ResourceBundle::GetSharedInstance().GetRawDataResource( - IDR_PROXY_SETTINGS_HTML)); - std::string full_html = webui::GetI18nTemplateHtml( - html, localized_strings_.get()); - - callback.Run(base::RefCountedString::TakeString(&full_html)); +void AddInternetStrings(content::WebUIDataSource* html_source) { + // Add default strings first. + chromeos::network_element::AddLocalizedStrings(html_source); + chromeos::network_element::AddOncLocalizedStrings(html_source); + chromeos::network_element::AddConfigLocalizedStrings(html_source); + // Add additional strings and overrides needed by the dialog. + struct { + const char* name; + int id; + } localized_strings[] = { + {"networkButtonConnect", IDS_SETTINGS_INTERNET_BUTTON_CONNECT}, + {"networkButtonDisconnect", IDS_SETTINGS_INTERNET_BUTTON_DISCONNECT}, + {"networkIPAddress", IDS_SETTINGS_INTERNET_NETWORK_IP_ADDRESS}, + {"networkSectionNetwork", IDS_SETTINGS_INTERNET_NETWORK_SECTION_NETWORK}, + {"networkSectionProxy", IDS_SETTINGS_INTERNET_NETWORK_SECTION_PROXY}, + {"networkIPConfigAuto", IDS_SETTINGS_INTERNET_NETWORK_IP_CONFIG_AUTO}, + {"save", IDS_SAVE}, + // Override for network_element::AddConfigLocalizedStrings + {"networkProxyConnectionType", + IDS_SETTINGS_INTERNET_NETWORK_PROXY_CONNECTION_TYPE_DIALOG}, + }; + for (const auto& entry : localized_strings) + html_source->AddLocalizedString(entry.name, entry.id); } } // namespace -namespace chromeos { - ProxySettingsUI::ProxySettingsUI(content::WebUI* web_ui) - : ui::WebDialogUI(web_ui), initialized_handlers_(false) { - // |localized_strings| will be owned by ProxySettingsHTMLSource. - base::DictionaryValue* localized_strings = new base::DictionaryValue(); + : ui::WebDialogUI(web_ui) { + content::WebUIDataSource* source = + content::WebUIDataSource::Create(chrome::kChromeUIProxySettingsHost); - auto core_handler = base::MakeUnique<options::CoreChromeOSOptionsHandler>(); - core_handler_ = core_handler.get(); - web_ui->AddMessageHandler(std::move(core_handler)); - core_handler_->set_handlers_host(this); - core_handler_->GetLocalizedValues(localized_strings); + AddInternetStrings(source); - auto proxy_handler = base::MakeUnique<options::ProxyHandler>(); - proxy_handler_ = proxy_handler.get(); - web_ui->AddMessageHandler(std::move(proxy_handler)); - proxy_handler_->GetLocalizedValues(localized_strings); + source->SetJsonPath("strings.js"); + source->SetDefaultResource(IDR_PROXY_SETTINGS_HTML); + source->DisableContentSecurityPolicy(); - internet_options_strings::RegisterLocalizedStrings(localized_strings); - bool keyboard_driven_oobe = - system::InputDeviceSettings::Get()->ForceKeyboardDrivenUINavigation(); - localized_strings->SetString("highlightStrength", - keyboard_driven_oobe ? "strong" : "normal"); + source->AddResourcePath("internet_detail_dialog.html", + IDR_INTERNET_DETAIL_DIALOG_HTML); + source->AddResourcePath("internet_detail_dialog.js", + IDR_INTERNET_DETAIL_DIALOG_JS); - ProxySettingsHTMLSource* source = - new ProxySettingsHTMLSource(localized_strings); - Profile* profile = Profile::FromWebUI(web_ui); - content::URLDataSource::Add(profile, source); + content::WebUIDataSource::Add(Profile::FromWebUI(web_ui), source); } -ProxySettingsUI::~ProxySettingsUI() { - // Uninitialize all registered handlers. The base class owns them and it will - // eventually delete them. - core_handler_->Uninitialize(); - proxy_handler_->Uninitialize(); -} - -void ProxySettingsUI::InitializeHandlers() { - // A new web page DOM has been brought up in an existing renderer, causing - // this method to be called twice. In that case, don't initialize the handlers - // again. Compare with options_ui.cc. - if (!initialized_handlers_) { - core_handler_->InitializeHandler(); - proxy_handler_->InitializeHandler(); - initialized_handlers_ = true; - } - core_handler_->InitializePage(); - proxy_handler_->InitializePage(); -} +ProxySettingsUI::~ProxySettingsUI() {} } // namespace chromeos
diff --git a/chrome/browser/ui/webui/chromeos/proxy_settings_ui.h b/chrome/browser/ui/webui/chromeos/proxy_settings_ui.h index d0162c83..f0f23a8 100644 --- a/chrome/browser/ui/webui/chromeos/proxy_settings_ui.h +++ b/chrome/browser/ui/webui/chromeos/proxy_settings_ui.h
@@ -6,33 +6,19 @@ #define CHROME_BROWSER_UI_WEBUI_CHROMEOS_PROXY_SETTINGS_UI_H_ #include "base/macros.h" -#include "chrome/browser/ui/webui/options/options_ui.h" #include "ui/web_dialogs/web_dialog_ui.h" namespace chromeos { -namespace options { -class CoreChromeOSOptionsHandler; -class ProxyHandler; -} - -// A WebUI to host proxy settings splitted from settings page for better -// performance. -class ProxySettingsUI : public ui::WebDialogUI, - public ::options::OptionsPageUIHandlerHost { +// A WebUI to host a subset of the network details page to allow setting of +// proxy, IP address, and nameservers in the login screen. (Historically the +// dialog only contained proxy settings). +class ProxySettingsUI : public ui::WebDialogUI { public: explicit ProxySettingsUI(content::WebUI* web_ui); ~ProxySettingsUI() override; private: - // Overridden from OptionsPageUIHandlerHost: - void InitializeHandlers() override; - - bool initialized_handlers_; - - options::ProxyHandler* proxy_handler_ = nullptr; - options::CoreChromeOSOptionsHandler* core_handler_ = nullptr; - DISALLOW_COPY_AND_ASSIGN(ProxySettingsUI); };
diff --git a/chrome/browser/ui/webui/help/help_handler.cc b/chrome/browser/ui/webui/help/help_handler.cc index 2a26fa5..6aad55c9 100644 --- a/chrome/browser/ui/webui/help/help_handler.cc +++ b/chrome/browser/ui/webui/help/help_handler.cc
@@ -8,7 +8,6 @@ #include <string> -#include "ash/system/devicetype_utils.h" #include "base/base_switches.h" #include "base/bind.h" #include "base/bind_helpers.h" @@ -70,6 +69,7 @@ #include "chromeos/system/statistics_provider.h" #include "components/prefs/pref_service.h" #include "components/user_manager/user_manager.h" +#include "ui/chromeos/devicetype_utils.h" #endif using base::ListValue; @@ -303,8 +303,8 @@ } #if defined(OS_CHROMEOS) - localized_strings->SetString("upToDate", ash::SubstituteChromeOSDeviceType( - IDS_UPGRADE_UP_TO_DATE)); + localized_strings->SetString( + "upToDate", ui::SubstituteChromeOSDeviceType(IDS_UPGRADE_UP_TO_DATE)); #else localized_strings->SetString("upToDate", l10n_util::GetStringUTF16( IDS_UPGRADE_UP_TO_DATE));
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 b4e4f346e..fe2d12f 100644 --- a/chrome/browser/ui/webui/media_router/media_router_ui.cc +++ b/chrome/browser/ui/webui/media_router/media_router_ui.cc
@@ -930,7 +930,7 @@ handler_->UpdateMaxDialogHeight(height); } -const MediaRouteController* MediaRouterUI::GetMediaRouteController() const { +MediaRouteController* MediaRouterUI::GetMediaRouteController() const { return route_controller_observer_ ? route_controller_observer_->controller().get() : nullptr;
diff --git a/chrome/browser/ui/webui/media_router/media_router_ui.h b/chrome/browser/ui/webui/media_router/media_router_ui.h index 9fa34ea..5bda61b0 100644 --- a/chrome/browser/ui/webui/media_router/media_router_ui.h +++ b/chrome/browser/ui/webui/media_router/media_router_ui.h
@@ -177,7 +177,7 @@ // Gets the route controller currently in use by the UI. Returns a nullptr if // none is in use. - virtual const MediaRouteController* GetMediaRouteController() const; + virtual MediaRouteController* GetMediaRouteController() const; // Called when a media controller UI surface is created. Creates an observer // for the MediaRouteController for |route_id| to listen for media status
diff --git a/chrome/browser/ui/webui/media_router/media_router_ui_unittest.cc b/chrome/browser/ui/webui/media_router/media_router_ui_unittest.cc index 21484da..cfd062d 100644 --- a/chrome/browser/ui/webui/media_router/media_router_ui_unittest.cc +++ b/chrome/browser/ui/webui/media_router/media_router_ui_unittest.cc
@@ -11,6 +11,8 @@ #include "base/strings/utf_string_conversions.h" #include "base/test/scoped_feature_list.h" #include "chrome/browser/media/router/create_presentation_connection_request.h" +#include "chrome/browser/media/router/event_page_request_manager_factory.h" +#include "chrome/browser/media/router/media_router_factory.h" #include "chrome/browser/media/router/mock_media_router.h" #include "chrome/browser/media/router/mojo/media_router_mojo_test.h" #include "chrome/browser/media/router/test_helper.h" @@ -97,19 +99,27 @@ : presentation_request_({0, 0}, {GURL("https://google.com/presentation")}, url::Origin(GURL("http://google.com"))) { - ON_CALL(mock_router_, GetCurrentRoutes()) - .WillByDefault(Return(std::vector<MediaRoute>())); - // enable and disable features scoped_feature_list_.InitFromCommandLine( "EnableCastLocalMedia" /* enabled features */, std::string() /* disabled features */); } + void SetUp() override { + ChromeRenderViewHostTestHarness::SetUp(); + EventPageRequestManagerFactory::GetInstance()->SetTestingFactory( + profile(), &MockEventPageRequestManager::Create); + mock_router_ = static_cast<MockMediaRouter*>( + MediaRouterFactory::GetInstance()->SetTestingFactoryAndUse( + profile(), &MockMediaRouter::Create)); + ON_CALL(*mock_router_, GetCurrentRoutes()) + .WillByDefault(Return(std::vector<MediaRoute>())); + } + void TearDown() override { - EXPECT_CALL(mock_router_, UnregisterMediaSinksObserver(_)) + EXPECT_CALL(*mock_router_, UnregisterMediaSinksObserver(_)) .Times(AnyNumber()); - EXPECT_CALL(mock_router_, UnregisterMediaRoutesObserver(_)) + EXPECT_CALL(*mock_router_, UnregisterMediaRoutesObserver(_)) .Times(AnyNumber()); web_ui_contents_.reset(); create_session_request_.reset(); @@ -138,15 +148,15 @@ auto file_dialog = base::MakeUnique<MockMediaRouterFileDialog>(); mock_file_dialog_ = file_dialog.get(); - EXPECT_CALL(mock_router_, RegisterMediaSinksObserver(_)) + EXPECT_CALL(*mock_router_, RegisterMediaSinksObserver(_)) .WillRepeatedly(Invoke([this](MediaSinksObserver* observer) { this->media_sinks_observers_.push_back(observer); return true; })); - EXPECT_CALL(mock_router_, RegisterMediaRoutesObserver(_)) + EXPECT_CALL(*mock_router_, RegisterMediaRoutesObserver(_)) .Times(AnyNumber()); media_router_ui_->InitForTest( - &mock_router_, web_contents(), message_handler_.get(), + mock_router_, web_contents(), message_handler_.get(), std::move(create_session_request_), std::move(file_dialog)); message_handler_->SetWebUIForTest(&web_ui_); } @@ -158,25 +168,18 @@ return sink; } - scoped_refptr<MockMediaRouteController> CreateMediaRouteController( - const MediaRoute::Id& route_id) { - mojom::MediaControllerPtr mojo_media_controller; - mojo::MakeRequest(&mojo_media_controller); - return scoped_refptr<MockMediaRouteController>(new MockMediaRouteController( - route_id, std::move(mojo_media_controller), &mock_router_)); - } - // Notifies MediaRouterUI that a route details view has been opened. Expects // MediaRouterUI to request a MediaRouteController, and gives it a mock // controller. Returns a reference to the mock controller. scoped_refptr<MockMediaRouteController> OpenUIDetailsView( const MediaRoute::Id& route_id) { - auto controller = CreateMediaRouteController(route_id); + auto controller = + base::MakeRefCounted<MockMediaRouteController>(route_id, profile()); MediaSource media_source("mediaSource"); MediaRoute route(route_id, media_source, "sinkId", "", true, "", true); media_router_ui_->OnRoutesUpdated({route}, std::vector<MediaRoute::Id>()); - EXPECT_CALL(mock_router_, GetRouteController(route_id)) + EXPECT_CALL(*mock_router_, GetRouteController(route_id)) .WillOnce(Return(controller)); media_router_ui_->OnMediaControllerUIAvailable(route_id); @@ -185,7 +188,7 @@ protected: content::PresentationRequest presentation_request_; - MockMediaRouter mock_router_; + MockMediaRouter* mock_router_ = nullptr; content::TestWebUI web_ui_; std::unique_ptr<WebContents> web_ui_contents_; std::unique_ptr<CreatePresentationConnectionRequest> create_session_request_; @@ -199,7 +202,7 @@ TEST_F(MediaRouterUITest, RouteCreationTimeoutForTab) { CreateMediaRouterUI(profile()); std::vector<MediaRouteResponseCallback> callbacks; - EXPECT_CALL(mock_router_, + EXPECT_CALL(*mock_router_, CreateRouteInternal(_, _, _, _, _, base::TimeDelta::FromSeconds(60), false)) .WillOnce(SaveArgWithMove<4>(&callbacks)); @@ -208,7 +211,7 @@ std::string expected_title = l10n_util::GetStringUTF8( IDS_MEDIA_ROUTER_ISSUE_CREATE_ROUTE_TIMEOUT_FOR_TAB); - EXPECT_CALL(mock_router_, AddIssue(IssueTitleEquals(expected_title))); + EXPECT_CALL(*mock_router_, AddIssue(IssueTitleEquals(expected_title))); std::unique_ptr<RouteRequestResult> result = RouteRequestResult::FromError("Timed out", RouteRequestResult::TIMED_OUT); for (auto& callback : callbacks) @@ -218,7 +221,7 @@ TEST_F(MediaRouterUITest, RouteCreationTimeoutForDesktop) { CreateMediaRouterUI(profile()); std::vector<MediaRouteResponseCallback> callbacks; - EXPECT_CALL(mock_router_, + EXPECT_CALL(*mock_router_, CreateRouteInternal(_, _, _, _, _, base::TimeDelta::FromSeconds(120), false)) .WillOnce(SaveArgWithMove<4>(&callbacks)); @@ -227,7 +230,7 @@ std::string expected_title = l10n_util::GetStringUTF8( IDS_MEDIA_ROUTER_ISSUE_CREATE_ROUTE_TIMEOUT_FOR_DESKTOP); - EXPECT_CALL(mock_router_, AddIssue(IssueTitleEquals(expected_title))); + EXPECT_CALL(*mock_router_, AddIssue(IssueTitleEquals(expected_title))); std::unique_ptr<RouteRequestResult> result = RouteRequestResult::FromError("Timed out", RouteRequestResult::TIMED_OUT); for (auto& callback : callbacks) @@ -241,7 +244,7 @@ url::Origin(GURL("https://frameurl.fakeurl"))); media_router_ui_->OnDefaultPresentationChanged(presentation_request); std::vector<MediaRouteResponseCallback> callbacks; - EXPECT_CALL(mock_router_, + EXPECT_CALL(*mock_router_, CreateRouteInternal(_, _, _, _, _, base::TimeDelta::FromSeconds(20), false)) .WillOnce(SaveArgWithMove<4>(&callbacks)); @@ -251,7 +254,7 @@ std::string expected_title = l10n_util::GetStringFUTF8(IDS_MEDIA_ROUTER_ISSUE_CREATE_ROUTE_TIMEOUT, base::UTF8ToUTF16("frameurl.fakeurl")); - EXPECT_CALL(mock_router_, AddIssue(IssueTitleEquals(expected_title))); + EXPECT_CALL(*mock_router_, AddIssue(IssueTitleEquals(expected_title))); std::unique_ptr<RouteRequestResult> result = RouteRequestResult::FromError("Timed out", RouteRequestResult::TIMED_OUT); for (auto& callback : callbacks) @@ -274,7 +277,7 @@ // Expect that the media_router_ will make a call to the mock_router // then we will want to check that it made the call with. - EXPECT_CALL(mock_router_, CreateRouteInternal(_, _, _, _, _, _, _)) + EXPECT_CALL(*mock_router_, CreateRouteInternal(_, _, _, _, _, _, _)) .WillOnce(SaveArgWithMove<3>(&location_file_opened)); media_router_ui_->CreateRoute(CreateSinkCompatibleWithAllSources().id(), @@ -287,7 +290,7 @@ TEST_F(MediaRouterUITest, RouteCreationParametersCantBeCreated) { CreateMediaRouterUI(profile()); MediaSinkSearchResponseCallback sink_callback; - EXPECT_CALL(mock_router_, SearchSinksInternal(_, _, _, _, _)) + EXPECT_CALL(*mock_router_, SearchSinksInternal(_, _, _, _, _)) .WillOnce(SaveArgWithMove<4>(&sink_callback)); // Use PRESENTATION mode without setting a PresentationRequest. @@ -295,7 +298,7 @@ "sinkId", "search input", "domain", MediaCastMode::PRESENTATION); std::string expected_title = l10n_util::GetStringUTF8( IDS_MEDIA_ROUTER_ISSUE_CREATE_ROUTE_TIMEOUT_FOR_TAB); - EXPECT_CALL(mock_router_, AddIssue(IssueTitleEquals(expected_title))); + EXPECT_CALL(*mock_router_, AddIssue(IssueTitleEquals(expected_title))); std::move(sink_callback).Run("foundSinkId"); } @@ -303,7 +306,7 @@ CreateMediaRouterUI(profile()->GetOffTheRecordProfile()); media_router_ui_->OnDefaultPresentationChanged(presentation_request_); - EXPECT_CALL(mock_router_, + EXPECT_CALL(*mock_router_, CreateRouteInternal(_, _, _, _, _, base::TimeDelta::FromSeconds(20), true)); media_router_ui_->CreateRoute(CreateSinkCompatibleWithAllSources().id(), @@ -430,7 +433,7 @@ MediaSource media_source_3(MediaSourceForDesktop()); std::unique_ptr<MediaRouterUI::UIMediaRoutesObserver> observer( new MediaRouterUI::UIMediaRoutesObserver( - &mock_router_, MediaSource::Id(), + mock_router_, MediaSource::Id(), base::Bind(&MediaRouterUI::OnRoutesUpdated, base::Unretained(media_router_ui_.get())))); @@ -467,7 +470,7 @@ EXPECT_NE(end(current_cast_modes), cast_mode_entry); EXPECT_EQ(MediaCastMode::DESKTOP_MIRROR, cast_mode_entry->second); - EXPECT_CALL(mock_router_, UnregisterMediaRoutesObserver(_)).Times(1); + EXPECT_CALL(*mock_router_, UnregisterMediaRoutesObserver(_)).Times(1); observer.reset(); } @@ -478,7 +481,7 @@ MediaSource media_source_3(MediaSourceForDesktop()); std::unique_ptr<MediaRouterUI::UIMediaRoutesObserver> observer( new MediaRouterUI::UIMediaRoutesObserver( - &mock_router_, MediaSource::Id(), + mock_router_, MediaSource::Id(), base::Bind(&MediaRouterUI::OnRoutesUpdated, base::Unretained(media_router_ui_.get())))); @@ -515,7 +518,7 @@ EXPECT_NE(end(current_cast_modes), cast_mode_entry); EXPECT_EQ(MediaCastMode::DESKTOP_MIRROR, cast_mode_entry->second); - EXPECT_CALL(mock_router_, UnregisterMediaRoutesObserver(_)).Times(1); + EXPECT_CALL(*mock_router_, UnregisterMediaRoutesObserver(_)).Times(1); observer.reset(); } @@ -697,10 +700,10 @@ // When the route details view is closed, the route controller observer should // be destroyed, also triggering the destruction of the controller. - EXPECT_CALL(mock_router_, DetachRouteController(route_id, _)); + EXPECT_CALL(*mock_router_, DetachRouteController(route_id, _)); media_router_ui_->OnMediaControllerUIClosed(); - EXPECT_TRUE(Mock::VerifyAndClearExpectations(&mock_router_)); + EXPECT_TRUE(Mock::VerifyAndClearExpectations(mock_router_)); } TEST_F(MediaRouterUITest, SendMediaStatusUpdate) { @@ -714,13 +717,19 @@ // update to the message handler. EXPECT_CALL(*message_handler_, UpdateMediaRouteStatus(status)); controller->OnMediaStatusUpdated(status); + + // |controller| will outlive |mock_router_| because we passed it into + // testing::Return(). Invalidate it so that it doesn't reference + // |mock_router_| in its dtor. + controller->Invalidate(); } TEST_F(MediaRouterUITest, SendInitialMediaStatusUpdate) { MediaStatus status; status.title = "test title"; std::string route_id = "routeId"; - auto controller = CreateMediaRouteController(route_id); + auto controller = + base::MakeRefCounted<MockMediaRouteController>(route_id, profile()); controller->OnMediaStatusUpdated(status); CreateMediaRouterUI(profile()); @@ -730,10 +739,15 @@ // If the controller has already received a media status update, MediaRouterUI // should be notified with it when it starts observing the controller. - EXPECT_CALL(mock_router_, GetRouteController(route_id)) + EXPECT_CALL(*mock_router_, GetRouteController(route_id)) .WillOnce(Return(controller)); EXPECT_CALL(*message_handler_, UpdateMediaRouteStatus(status)); media_router_ui_->OnMediaControllerUIAvailable(route_id); + + // |controller| will outlive |mock_router_| because we passed it into + // testing::Return(). Invalidate it so that it doesn't reference + // |mock_router_| in its dtor. + controller->Invalidate(); } TEST_F(MediaRouterUITest, SetsForcedCastModeWithPresentationURLs) { @@ -758,12 +772,12 @@ message_handler_ = base::MakeUnique<MockMediaRouterWebUIMessageHandler>( media_router_ui_.get()); message_handler_->SetWebUIForTest(&web_ui_); - EXPECT_CALL(mock_router_, RegisterMediaSinksObserver(_)) + EXPECT_CALL(*mock_router_, RegisterMediaSinksObserver(_)) .WillRepeatedly(Invoke([this](MediaSinksObserver* observer) { this->media_sinks_observers_.push_back(observer); return true; })); - EXPECT_CALL(mock_router_, RegisterMediaRoutesObserver(_)).Times(AnyNumber()); + EXPECT_CALL(*mock_router_, RegisterMediaRoutesObserver(_)).Times(AnyNumber()); // For some reason we push two sets of cast modes to the dialog, even when // initializing the dialog with a presentation request. The WebUI can handle // the forced mode that is not in the initial cast mode set, but is this a @@ -781,7 +795,7 @@ expected_modes, "google.com", base::Optional<MediaCastMode>(MediaCastMode::PRESENTATION))); media_router_ui_->UIInitialized(); - media_router_ui_->InitForTest(&mock_router_, web_contents(), + media_router_ui_->InitForTest(mock_router_, web_contents(), message_handler_.get(), std::move(create_session_request_), nullptr); // |media_router_ui_| takes ownership of |request_callbacks|.
diff --git a/chrome/browser/ui/webui/media_router/media_router_webui_message_handler.cc b/chrome/browser/ui/webui/media_router/media_router_webui_message_handler.cc index 31cb121..aa311c86 100644 --- a/chrome/browser/ui/webui/media_router/media_router_webui_message_handler.cc +++ b/chrome/browser/ui/webui/media_router/media_router_webui_message_handler.cc
@@ -907,7 +907,7 @@ void MediaRouterWebUIMessageHandler::OnPauseCurrentMedia( const base::ListValue* args) { - const MediaRouteController* route_controller = + MediaRouteController* route_controller = media_router_ui_->GetMediaRouteController(); if (route_controller) route_controller->Pause(); @@ -915,7 +915,7 @@ void MediaRouterWebUIMessageHandler::OnPlayCurrentMedia( const base::ListValue* args) { - const MediaRouteController* route_controller = + MediaRouteController* route_controller = media_router_ui_->GetMediaRouteController(); if (route_controller) route_controller->Play(); @@ -931,7 +931,7 @@ return; } base::TimeDelta time_delta = base::TimeDelta::FromSeconds(time); - const MediaRouteController* route_controller = + MediaRouteController* route_controller = media_router_ui_->GetMediaRouteController(); if (route_controller && current_media_status_ && time_delta >= base::TimeDelta() && @@ -949,7 +949,7 @@ DVLOG(1) << "Unable to extract mute"; return; } - const MediaRouteController* route_controller = + MediaRouteController* route_controller = media_router_ui_->GetMediaRouteController(); if (route_controller) route_controller->SetMute(mute); @@ -964,7 +964,7 @@ DVLOG(1) << "Unable to extract volume"; return; } - const MediaRouteController* route_controller = + MediaRouteController* route_controller = media_router_ui_->GetMediaRouteController(); if (route_controller && volume >= 0 && volume <= 1) route_controller->SetVolume(volume);
diff --git a/chrome/browser/ui/webui/media_router/media_router_webui_message_handler_unittest.cc b/chrome/browser/ui/webui/media_router/media_router_webui_message_handler_unittest.cc index 9cb1e48f..e945cf6 100644 --- a/chrome/browser/ui/webui/media_router/media_router_webui_message_handler_unittest.cc +++ b/chrome/browser/ui/webui/media_router/media_router_webui_message_handler_unittest.cc
@@ -103,7 +103,7 @@ MOCK_METHOD1(SeekRoute, void(base::TimeDelta time)); MOCK_METHOD1(SetRouteMute, void(bool mute)); MOCK_METHOD1(SetRouteVolume, void(float volume)); - MOCK_CONST_METHOD0(GetMediaRouteController, const MediaRouteController*()); + MOCK_CONST_METHOD0(GetMediaRouteController, MediaRouteController*()); }; class TestMediaRouterWebUIMessageHandler @@ -600,12 +600,8 @@ } TEST_F(MediaRouterWebUIMessageHandlerTest, OnMediaCommandsReceived) { - mojom::MediaControllerPtr mojo_media_controller; - mojo::MakeRequest(&mojo_media_controller); - MockMediaRouter media_router; - scoped_refptr<MockMediaRouteController> controller = - new MockMediaRouteController("routeId", std::move(mojo_media_controller), - &media_router); + auto controller = + base::MakeRefCounted<MockMediaRouteController>("routeId", profile()); EXPECT_CALL(*mock_media_router_ui_, GetMediaRouteController()) .WillRepeatedly(Return(controller.get())); MediaStatus status; @@ -642,12 +638,8 @@ } TEST_F(MediaRouterWebUIMessageHandlerTest, OnInvalidMediaCommandsReceived) { - mojom::MediaControllerPtr mojo_media_controller; - mojo::MakeRequest(&mojo_media_controller); - MockMediaRouter media_router; - scoped_refptr<MockMediaRouteController> controller = - new MockMediaRouteController("routeId", std::move(mojo_media_controller), - &media_router); + auto controller = + base::MakeRefCounted<MockMediaRouteController>("routeId", profile()); EXPECT_CALL(*mock_media_router_ui_, GetMediaRouteController()) .WillRepeatedly(Return(controller.get()));
diff --git a/chrome/browser/ui/webui/options/DEPS b/chrome/browser/ui/webui/options/DEPS deleted file mode 100644 index 0cb6537c..0000000 --- a/chrome/browser/ui/webui/options/DEPS +++ /dev/null
@@ -1,4 +0,0 @@ -include_rules = [ - "+components/user_manager", - "+third_party/libaddressinput", # for third_party/libaddressinput/messages.h -]
diff --git a/chrome/browser/ui/webui/options/OWNERS b/chrome/browser/ui/webui/options/OWNERS deleted file mode 100644 index 5b7d56c..0000000 --- a/chrome/browser/ui/webui/options/OWNERS +++ /dev/null
@@ -1,6 +0,0 @@ -# This UI is deprecated. See chrome/browser/ui/webui/settings/ instead. -michaelpg@chromium.org -stevenjb@chromium.org - -per-file sync_setup_handler*=atwilson@chromium.org -per-file sync_setup_handler*=rogerta@chromium.org
diff --git a/chrome/browser/ui/webui/options/autofill_options_handler.cc b/chrome/browser/ui/webui/options/autofill_options_handler.cc deleted file mode 100644 index f4480a23..0000000 --- a/chrome/browser/ui/webui/options/autofill_options_handler.cc +++ /dev/null
@@ -1,507 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/webui/options/autofill_options_handler.h" - -#include <stddef.h> - -#include <memory> -#include <utility> -#include <vector> - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/command_line.h" -#include "base/guid.h" -#include "base/logging.h" -#include "base/macros.h" -#include "base/memory/ptr_util.h" -#include "base/strings/string16.h" -#include "base/strings/string_number_conversions.h" -#include "base/strings/string_split.h" -#include "base/strings/utf_string_conversions.h" -#include "base/values.h" -#include "chrome/browser/autofill/personal_data_manager_factory.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/common/url_constants.h" -#include "chrome/grit/chromium_strings.h" -#include "chrome/grit/generated_resources.h" -#include "components/autofill/core/browser/autofill_address_util.h" -#include "components/autofill/core/browser/autofill_data_util.h" -#include "components/autofill/core/browser/autofill_profile.h" -#include "components/autofill/core/browser/country_combobox_model.h" -#include "components/autofill/core/browser/credit_card.h" -#include "components/autofill/core/browser/payments/payments_service_url.h" -#include "components/autofill/core/browser/personal_data_manager.h" -#include "components/autofill/core/browser/phone_number_i18n.h" -#include "components/autofill/core/common/autofill_constants.h" -#include "components/autofill/core/common/autofill_switches.h" -#include "components/strings/grit/components_strings.h" -#include "content/public/browser/web_ui.h" -#include "third_party/libaddressinput/messages.h" -#include "ui/base/l10n/l10n_util.h" -#include "ui/base/webui/web_ui_util.h" - -using autofill::AutofillType; -using autofill::AutofillProfile; -using autofill::CreditCard; -using autofill::PersonalDataManager; - -namespace { - -static const char kComponents[] = "components"; -static const char kLanguageCode[] = "languageCode"; - -std::unique_ptr<base::DictionaryValue> CreditCardToDictionary( - const CreditCard& card) { - std::unique_ptr<base::DictionaryValue> value(new base::DictionaryValue); - value->SetString("guid", card.guid()); - std::pair<base::string16, base::string16> label_pieces = card.LabelPieces(); - value->SetString("label", label_pieces.first); - value->SetString("sublabel", label_pieces.second); - value->SetBoolean("isLocal", card.record_type() == CreditCard::LOCAL_CARD); - value->SetBoolean("isCached", - card.record_type() == CreditCard::FULL_SERVER_CARD); - return value; -} - -} // namespace - -namespace options { - -AutofillOptionsHandler::AutofillOptionsHandler() : personal_data_(nullptr) {} - -AutofillOptionsHandler::~AutofillOptionsHandler() { - if (personal_data_) - personal_data_->RemoveObserver(this); -} - -///////////////////////////////////////////////////////////////////////////// -// OptionsPageUIHandler implementation: -void AutofillOptionsHandler::GetLocalizedValues( - base::DictionaryValue* localized_strings) { - DCHECK(localized_strings); - - static OptionsStringResource resources[] = { - { "autofillAddresses", IDS_AUTOFILL_ADDRESSES_GROUP_NAME }, - { "autofillCreditCards", IDS_AUTOFILL_CREDITCARDS_GROUP_NAME }, - { "autofillAddAddress", IDS_AUTOFILL_ADD_ADDRESS_BUTTON }, - { "autofillAddCreditCard", IDS_AUTOFILL_ADD_CREDITCARD_BUTTON }, - { "autofillEditProfileButton", IDS_AUTOFILL_EDIT_PROFILE_BUTTON }, - { "autofillFromGoogleAccount", IDS_AUTOFILL_FROM_GOOGLE_ACCOUNT }, - { "autofillDescribeLocalCopy", IDS_AUTOFILL_DESCRIBE_LOCAL_COPY }, - { "autofillClearLocalCopyButton", IDS_AUTOFILL_CLEAR_LOCAL_COPY_BUTTON }, - { "helpButton", IDS_AUTOFILL_HELP_LABEL }, - { "addAddressTitle", IDS_AUTOFILL_ADD_ADDRESS_CAPTION }, - { "editAddressTitle", IDS_AUTOFILL_EDIT_ADDRESS_CAPTION }, - { "addCreditCardTitle", IDS_AUTOFILL_ADD_CREDITCARD_CAPTION }, - { "editCreditCardTitle", IDS_AUTOFILL_EDIT_CREDITCARD_CAPTION }, - }; - - RegisterStrings(localized_strings, resources, arraysize(resources)); - RegisterTitle(localized_strings, "autofillOptionsPage", - IDS_AUTOFILL_OPTIONS_TITLE); - - localized_strings->SetString("helpUrl", autofill::kHelpURL); - - personal_data_ = autofill::PersonalDataManagerFactory::GetForProfile( - Profile::FromWebUI(web_ui())); - - SetAddressOverlayStrings(localized_strings); - SetCreditCardOverlayStrings(localized_strings); - - localized_strings->SetString( - "paymentsManageAddressesUrl", - autofill::payments::GetManageAddressesUrl(0).spec()); - localized_strings->SetString( - "paymentsManageInstrumentsUrl", - autofill::payments::GetManageInstrumentsUrl(0).spec()); -} - -void AutofillOptionsHandler::InitializeHandler() { - // personal_data_ is NULL in guest mode on Chrome OS. - if (personal_data_) - personal_data_->AddObserver(this); -} - -void AutofillOptionsHandler::InitializePage() { - if (personal_data_) - LoadAutofillData(); -} - -void AutofillOptionsHandler::RegisterMessages() { - web_ui()->RegisterMessageCallback( - "removeData", - base::Bind(&AutofillOptionsHandler::RemoveData, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "loadAddressEditor", - base::Bind(&AutofillOptionsHandler::LoadAddressEditor, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "loadAddressEditorComponents", - base::Bind(&AutofillOptionsHandler::LoadAddressEditorComponents, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "loadCreditCardEditor", - base::Bind(&AutofillOptionsHandler::LoadCreditCardEditor, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "setAddress", - base::Bind(&AutofillOptionsHandler::SetAddress, base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "setCreditCard", - base::Bind(&AutofillOptionsHandler::SetCreditCard, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "clearLocalCardCopy", - base::Bind(&AutofillOptionsHandler::RemaskServerCard, - base::Unretained(this))); -} - -///////////////////////////////////////////////////////////////////////////// -// PersonalDataManagerObserver implementation: -void AutofillOptionsHandler::OnPersonalDataChanged() { - LoadAutofillData(); -} - -void AutofillOptionsHandler::SetAddressOverlayStrings( - base::DictionaryValue* localized_strings) { - localized_strings->SetString("autofillEditAddressTitle", - l10n_util::GetStringUTF16(IDS_AUTOFILL_EDIT_ADDRESS_CAPTION)); - localized_strings->SetString("autofillCountryLabel", - l10n_util::GetStringUTF16(IDS_LIBADDRESSINPUT_COUNTRY_OR_REGION_LABEL)); - localized_strings->SetString("autofillPhoneLabel", - l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_PHONE)); - localized_strings->SetString("autofillEmailLabel", - l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_EMAIL)); - SetCountryData(*personal_data_, localized_strings, - g_browser_process->GetApplicationLocale()); -} - -void AutofillOptionsHandler::SetCreditCardOverlayStrings( - base::DictionaryValue* localized_strings) { - localized_strings->SetString("autofillEditCreditCardTitle", - l10n_util::GetStringUTF16(IDS_AUTOFILL_EDIT_CREDITCARD_CAPTION)); - localized_strings->SetString("nameOnCardLabel", - l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_NAME_ON_CARD)); - localized_strings->SetString("creditCardNumberLabel", - l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_CREDIT_CARD_NUMBER)); - localized_strings->SetString("creditCardExpirationDateLabel", - l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_EXPIRATION_DATE)); -} - -void AutofillOptionsHandler::LoadAutofillData() { - if (!IsPersonalDataLoaded()) - return; - - const std::vector<AutofillProfile*>& profiles = personal_data_->GetProfiles(); - std::vector<base::string16> labels; - AutofillProfile::CreateDifferentiatingLabels( - profiles, - g_browser_process->GetApplicationLocale(), - &labels); - DCHECK_EQ(labels.size(), profiles.size()); - - base::ListValue addresses; - for (size_t i = 0; i < profiles.size(); ++i) { - // Skip showing auxiliary profiles (e.g. Mac Contacts) for now. - if (profiles[i]->record_type() == AutofillProfile::AUXILIARY_PROFILE) - continue; - - base::string16 separator = - l10n_util::GetStringUTF16(IDS_AUTOFILL_ADDRESS_SUMMARY_SEPARATOR); - std::vector<base::string16> label_parts = base::SplitStringUsingSubstr( - labels[i], separator, base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); - - std::unique_ptr<base::DictionaryValue> value(new base::DictionaryValue); - value->SetString("guid", profiles[i]->guid()); - value->SetString("label", label_parts[0]); - value->SetString("sublabel", labels[i].substr(label_parts[0].size())); - value->SetBoolean("isLocal", profiles[i]->record_type() == - AutofillProfile::LOCAL_PROFILE); - addresses.Append(std::move(value)); - } - - web_ui()->CallJavascriptFunctionUnsafe("AutofillOptions.setAddressList", - addresses); - - base::ListValue credit_cards; - const std::vector<CreditCard*>& cards = personal_data_->GetCreditCards(); - for (const CreditCard* card : cards) { - credit_cards.Append(CreditCardToDictionary(*card)); - } - - web_ui()->CallJavascriptFunctionUnsafe("AutofillOptions.setCreditCardList", - credit_cards); -} - -void AutofillOptionsHandler::RemoveData(const base::ListValue* args) { - DCHECK(IsPersonalDataLoaded()); - - std::string guid; - if (!args->GetString(0, &guid)) { - NOTREACHED(); - return; - } - - personal_data_->RemoveByGUID(guid); -} - -void AutofillOptionsHandler::LoadAddressEditor(const base::ListValue* args) { - DCHECK(IsPersonalDataLoaded()); - - std::string guid; - if (!args->GetString(0, &guid)) { - NOTREACHED(); - return; - } - - const AutofillProfile* prior_profile = personal_data_->GetProfileByGUID(guid); - if (!prior_profile) { - // There is a race where a user can click once on the close button and - // quickly click again on the list item before the item is removed (since - // the list is not updated until the model tells the list an item has been - // removed). This will activate the editor for a profile that has been - // removed. Do nothing in that case. - return; - } - - base::DictionaryValue address; - AutofillProfileToDictionary(*prior_profile, &address); - - web_ui()->CallJavascriptFunctionUnsafe("AutofillOptions.editAddress", - address); -} - -void AutofillOptionsHandler::LoadAddressEditorComponents( - const base::ListValue* args) { - std::string country_code; - if (!args->GetString(0, &country_code)) { - NOTREACHED(); - return; - } - - base::DictionaryValue input; - std::unique_ptr<base::ListValue> components(new base::ListValue); - std::string language_code; - autofill::GetAddressComponents(country_code, - g_browser_process->GetApplicationLocale(), - components.get(), &language_code); - input.Set(kComponents, std::move(components)); - input.SetString(kLanguageCode, language_code); - - web_ui()->CallJavascriptFunctionUnsafe( - "AutofillEditAddressOverlay.loadAddressComponents", input); -} - -void AutofillOptionsHandler::LoadCreditCardEditor(const base::ListValue* args) { - DCHECK(IsPersonalDataLoaded()); - - std::string guid; - if (!args->GetString(0, &guid)) { - NOTREACHED(); - return; - } - - CreditCard* credit_card = personal_data_->GetCreditCardByGUID(guid); - if (!credit_card) { - // There is a race where a user can click once on the close button and - // quickly click again on the list item before the item is removed (since - // the list is not updated until the model tells the list an item has been - // removed). This will activate the editor for a profile that has been - // removed. Do nothing in that case. - return; - } - - base::DictionaryValue credit_card_data; - credit_card_data.SetString("guid", credit_card->guid()); - credit_card_data.SetString( - "nameOnCard", credit_card->GetRawInfo(autofill::CREDIT_CARD_NAME_FULL)); - credit_card_data.SetString( - "creditCardNumber", - credit_card->GetRawInfo(autofill::CREDIT_CARD_NUMBER)); - credit_card_data.SetString( - "expirationMonth", - credit_card->GetRawInfo(autofill::CREDIT_CARD_EXP_MONTH)); - credit_card_data.SetString( - "expirationYear", - credit_card->GetRawInfo(autofill::CREDIT_CARD_EXP_4_DIGIT_YEAR)); - - web_ui()->CallJavascriptFunctionUnsafe("AutofillOptions.editCreditCard", - credit_card_data); -} - -void AutofillOptionsHandler::SetAddress(const base::ListValue* args) { - if (!IsPersonalDataLoaded()) - return; - - int arg_counter = 0; - std::string guid; - if (!args->GetString(arg_counter++, &guid)) { - NOTREACHED(); - return; - } - - AutofillProfile profile(guid, autofill::kSettingsOrigin); - - base::string16 full_name; - if (args->GetString(arg_counter++, &full_name)) { - // Although First/Middle/Last are not displayed on the form, we transfer - // this information when they match the full name in the old version of the - // profile, if one exists. This is because it may not be possible later to - // correctly tokenize the concatenated full name; e.g., when the last name - // contains a space, the first word would be treated as a middle name. - const AutofillProfile* prior_profile = - base::IsValidGUID(profile.guid()) - ? personal_data_->GetProfileByGUID(guid) - : nullptr; - - if (prior_profile && autofill::data_util::ProfileMatchesFullName( - full_name, *prior_profile)) { - profile.SetRawInfo(autofill::NAME_FULL, full_name); - - profile.SetRawInfo(autofill::NAME_FIRST, - prior_profile->GetRawInfo(autofill::NAME_FIRST)); - profile.SetRawInfo(autofill::NAME_MIDDLE, - prior_profile->GetRawInfo(autofill::NAME_MIDDLE)); - profile.SetRawInfo(autofill::NAME_LAST, - prior_profile->GetRawInfo(autofill::NAME_LAST)); - } else { - // In contrast to SetRawInfo, SetInfo will naively attempt to populate the - // First/Middle/Last fields by tokenization. - profile.SetInfo(AutofillType(autofill::NAME_FULL), full_name, - g_browser_process->GetApplicationLocale()); - } - } - - base::string16 value; - if (args->GetString(arg_counter++, &value)) - profile.SetRawInfo(autofill::COMPANY_NAME, value); - - if (args->GetString(arg_counter++, &value)) - profile.SetRawInfo(autofill::ADDRESS_HOME_STREET_ADDRESS, value); - - if (args->GetString(arg_counter++, &value)) - profile.SetRawInfo(autofill::ADDRESS_HOME_DEPENDENT_LOCALITY, value); - - if (args->GetString(arg_counter++, &value)) - profile.SetRawInfo(autofill::ADDRESS_HOME_CITY, value); - - if (args->GetString(arg_counter++, &value)) - profile.SetRawInfo(autofill::ADDRESS_HOME_STATE, value); - - if (args->GetString(arg_counter++, &value)) - profile.SetRawInfo(autofill::ADDRESS_HOME_ZIP, value); - - if (args->GetString(arg_counter++, &value)) - profile.SetRawInfo(autofill::ADDRESS_HOME_SORTING_CODE, value); - - if (args->GetString(arg_counter++, &value)) - profile.SetRawInfo(autofill::ADDRESS_HOME_COUNTRY, value); - - if (args->GetString(arg_counter++, &value)) - profile.SetRawInfo(autofill::PHONE_HOME_WHOLE_NUMBER, value); - - if (args->GetString(arg_counter++, &value)) - profile.SetRawInfo(autofill::EMAIL_ADDRESS, value); - - if (args->GetString(arg_counter++, &value)) - profile.set_language_code(base::UTF16ToUTF8(value)); - - if (!base::IsValidGUID(profile.guid())) { - profile.set_guid(base::GenerateGUID()); - personal_data_->AddProfile(profile); - } else { - personal_data_->UpdateProfile(profile); - } -} - -void AutofillOptionsHandler::SetCreditCard(const base::ListValue* args) { - if (!IsPersonalDataLoaded()) - return; - - std::string guid; - if (!args->GetString(0, &guid)) { - NOTREACHED(); - return; - } - - CreditCard credit_card(guid, autofill::kSettingsOrigin); - - base::string16 value; - if (args->GetString(1, &value)) - credit_card.SetRawInfo(autofill::CREDIT_CARD_NAME_FULL, value); - - if (args->GetString(2, &value)) - credit_card.SetRawInfo(autofill::CREDIT_CARD_NUMBER, value); - - if (args->GetString(3, &value)) - credit_card.SetRawInfo(autofill::CREDIT_CARD_EXP_MONTH, value); - - if (args->GetString(4, &value)) - credit_card.SetRawInfo(autofill::CREDIT_CARD_EXP_4_DIGIT_YEAR, value); - - if (!base::IsValidGUID(credit_card.guid())) { - credit_card.set_guid(base::GenerateGUID()); - personal_data_->AddCreditCard(credit_card); - } else { - personal_data_->UpdateCreditCard(credit_card); - } -} - -void AutofillOptionsHandler::RemaskServerCard(const base::ListValue* args) { - std::string guid; - if (!args->GetString(0, &guid)) { - NOTREACHED(); - return; - } - - personal_data_->ResetFullServerCard(guid); -} - -bool AutofillOptionsHandler::IsPersonalDataLoaded() const { - return personal_data_ && personal_data_->IsDataLoaded(); -} - -// static -void AutofillOptionsHandler::AutofillProfileToDictionary( - const autofill::AutofillProfile& profile, - base::DictionaryValue* address) { - address->SetString("guid", profile.guid()); - address->SetString( - autofill::kFullNameField, - profile.GetInfo(AutofillType(autofill::NAME_FULL), - g_browser_process->GetApplicationLocale())); - address->SetString(autofill::kCompanyNameField, - profile.GetRawInfo(autofill::COMPANY_NAME)); - address->SetString(autofill::kAddressLineField, - profile.GetRawInfo(autofill::ADDRESS_HOME_STREET_ADDRESS)); - address->SetString(autofill::kCityField, - profile.GetRawInfo(autofill::ADDRESS_HOME_CITY)); - address->SetString(autofill::kStateField, - profile.GetRawInfo(autofill::ADDRESS_HOME_STATE)); - address->SetString( - autofill::kDependentLocalityField, - profile.GetRawInfo(autofill::ADDRESS_HOME_DEPENDENT_LOCALITY)); - address->SetString(autofill::kSortingCodeField, - profile.GetRawInfo(autofill::ADDRESS_HOME_SORTING_CODE)); - address->SetString(autofill::kPostalCodeField, - profile.GetRawInfo(autofill::ADDRESS_HOME_ZIP)); - address->SetString(autofill::kCountryField, - profile.GetRawInfo(autofill::ADDRESS_HOME_COUNTRY)); - address->SetString("phone", - profile.GetRawInfo(autofill::PHONE_HOME_WHOLE_NUMBER)); - address->SetString("email", profile.GetRawInfo(autofill::EMAIL_ADDRESS)); - address->SetString(kLanguageCode, profile.language_code()); - - std::unique_ptr<base::ListValue> components(new base::ListValue); - autofill::GetAddressComponents( - base::UTF16ToUTF8(profile.GetRawInfo(autofill::ADDRESS_HOME_COUNTRY)), - profile.language_code(), components.get(), nullptr); - address->Set(kComponents, std::move(components)); -} - -} // namespace options
diff --git a/chrome/browser/ui/webui/options/autofill_options_handler.h b/chrome/browser/ui/webui/options/autofill_options_handler.h deleted file mode 100644 index ef00b3e..0000000 --- a/chrome/browser/ui/webui/options/autofill_options_handler.h +++ /dev/null
@@ -1,114 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_WEBUI_OPTIONS_AUTOFILL_OPTIONS_HANDLER_H_ -#define CHROME_BROWSER_UI_WEBUI_OPTIONS_AUTOFILL_OPTIONS_HANDLER_H_ - -#include <string> - -#include "base/compiler_specific.h" -#include "base/gtest_prod_util.h" -#include "base/macros.h" -#include "base/scoped_observer.h" -#include "chrome/browser/ui/webui/options/options_ui.h" -#include "components/autofill/core/browser/personal_data_manager_observer.h" - -namespace autofill { -class AutofillProfile; -class PersonalDataManager; -} // namespace autofill - -namespace base { -class DictionaryValue; -class ListValue; -} - -namespace options { - -class AutofillOptionsHandler : public OptionsPageUIHandler, - public autofill::PersonalDataManagerObserver { - public: - AutofillOptionsHandler(); - ~AutofillOptionsHandler() override; - - // OptionsPageUIHandler implementation. - void GetLocalizedValues(base::DictionaryValue* localized_strings) override; - void InitializeHandler() override; - void InitializePage() override; - void RegisterMessages() override; - - // PersonalDataManagerObserver implementation. - void OnPersonalDataChanged() override; - - private: - FRIEND_TEST_ALL_PREFIXES(AutofillOptionsHandlerTest, AddressToDictionary); - - // Loads the strings for the address and credit card overlays. - void SetAddressOverlayStrings(base::DictionaryValue* localized_strings); - void SetCreditCardOverlayStrings(base::DictionaryValue* localized_strings); - - // Loads Autofill addresses and credit cards using the PersonalDataManager. - void LoadAutofillData(); - - // Removes data from the PersonalDataManager. - // |args| - A string, the GUID of the address or credit card to remove. - void RemoveData(const base::ListValue* args); - - // Requests profile data for a specific address. Calls into WebUI with the - // loaded profile data to open the address editor. - // |args| - A string, the GUID of the address to load. - void LoadAddressEditor(const base::ListValue* args); - - // Requests input form layout information for a specific country code. Calls - // into WebUI with the layout information. - // |args| - A string, the country code to load. - void LoadAddressEditorComponents(const base::ListValue* args); - - // Requests profile data for a specific credit card. Calls into WebUI with the - // loaded profile data to open the credit card editor. - // |args| - A string, the GUID of the credit card to load. - void LoadCreditCardEditor(const base::ListValue* args); - - // Adds or updates an address, depending on the GUID of the profile. If the - // GUID is empty, a new address is added to the WebDatabase; otherwise, the - // address with the matching GUID is updated. Called from WebUI. - // |args| - an array containing the GUID of the address followed by the - // address data. - void SetAddress(const base::ListValue* args); - - // Adds or updates a credit card, depending on the GUID of the profile. If the - // GUID is empty, a new credit card is added to the WebDatabase; otherwise, - // the credit card with the matching GUID is updated. Called from WebUI. - // |args| - an array containing the GUID of the credit card followed by the - // credit card data. - void SetCreditCard(const base::ListValue* args); - - // Validates a list of phone numbers. The resulting validated list of - // numbers is then sent back to the WebUI. - // |args| - an array containing the index of the modified or added number, the - // array of numbers, and the country code string set on the profile. - void ValidatePhoneNumbers(const base::ListValue* args); - - // Resets the masked state on the unmasked Wallet card described by the GUID - // in args[0]. - void RemaskServerCard(const base::ListValue* args); - - // Returns true if |personal_data_| is non-null and loaded. - bool IsPersonalDataLoaded() const; - - // Fills in |address| with the data format that the options js expects. - static void AutofillProfileToDictionary( - const autofill::AutofillProfile& profile, - base::DictionaryValue* address); - - // The personal data manager, used to load Autofill profiles and credit cards. - // Unowned pointer, may not be NULL. - autofill::PersonalDataManager* personal_data_; - - DISALLOW_COPY_AND_ASSIGN(AutofillOptionsHandler); -}; - -} // namespace options - -#endif // CHROME_BROWSER_UI_WEBUI_OPTIONS_AUTOFILL_OPTIONS_HANDLER_H_
diff --git a/chrome/browser/ui/webui/options/automatic_settings_reset_handler.cc b/chrome/browser/ui/webui/options/automatic_settings_reset_handler.cc deleted file mode 100644 index f6bf319..0000000 --- a/chrome/browser/ui/webui/options/automatic_settings_reset_handler.cc +++ /dev/null
@@ -1,71 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/webui/options/automatic_settings_reset_handler.h" - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/macros.h" -#include "base/time/time.h" -#include "chrome/browser/prefs/chrome_pref_service_factory.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/common/url_constants.h" -#include "chrome/grit/generated_resources.h" -#include "components/strings/grit/components_strings.h" -#include "content/public/browser/web_ui.h" - -namespace { - -void OnDismissedAutomaticSettingsResetBanner(Profile* profile, - const base::ListValue* value) { - chrome_prefs::ClearResetTime(profile); -} - -} // namespace - -namespace options { - -AutomaticSettingsResetHandler::AutomaticSettingsResetHandler() {} -AutomaticSettingsResetHandler::~AutomaticSettingsResetHandler() {} - -void AutomaticSettingsResetHandler::InitializePage() { - static const int kBannerShowTimeInDays = 5; - - const base::Time then = - chrome_prefs::GetResetTime(Profile::FromWebUI(web_ui())); - if (!then.is_null()) { - const base::Time now = base::Time::Now(); - if ((now - then).InDays() < kBannerShowTimeInDays) - web_ui()->CallJavascriptFunctionUnsafe( - "AutomaticSettingsResetBanner.show"); - } -} - -void AutomaticSettingsResetHandler::GetLocalizedValues( - base::DictionaryValue* localized_strings) { - DCHECK(localized_strings); - - static const OptionsStringResource resources[] = { - { "automaticSettingsResetBannerResetButtonText", - IDS_AUTOMATIC_SETTINGS_RESET_BANNER_RESET_BUTTON_TEXT }, - { "automaticSettingsResetBannerText", - IDS_AUTOMATIC_SETTINGS_RESET_BANNER_TEXT }, - { "automaticSettingsResetLearnMoreUrl", - IDS_LEARN_MORE }, - }; - - RegisterStrings(localized_strings, resources, arraysize(resources)); - localized_strings->SetString( - "automaticSettingsResetLearnMoreUrl", - chrome::kAutomaticSettingsResetLearnMoreURL); -} - -void AutomaticSettingsResetHandler::RegisterMessages() { - web_ui()->RegisterMessageCallback( - "onDismissedAutomaticSettingsResetBanner", - base::Bind(&OnDismissedAutomaticSettingsResetBanner, - Profile::FromWebUI(web_ui()))); -} - -} // namespace options
diff --git a/chrome/browser/ui/webui/options/automatic_settings_reset_handler.h b/chrome/browser/ui/webui/options/automatic_settings_reset_handler.h deleted file mode 100644 index 1b4baed..0000000 --- a/chrome/browser/ui/webui/options/automatic_settings_reset_handler.h +++ /dev/null
@@ -1,34 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_WEBUI_OPTIONS_AUTOMATIC_SETTINGS_RESET_HANDLER_H_ -#define CHROME_BROWSER_UI_WEBUI_OPTIONS_AUTOMATIC_SETTINGS_RESET_HANDLER_H_ - -#include "base/macros.h" -#include "base/memory/weak_ptr.h" -#include "chrome/browser/ui/webui/options/options_ui.h" - -namespace options { - -// Handler for the banner that displays a settings reset event at the top of the -// settings page. -class AutomaticSettingsResetHandler : public OptionsPageUIHandler { - public: - AutomaticSettingsResetHandler(); - ~AutomaticSettingsResetHandler() override; - - // OptionsPageUIHandler implementation. - void GetLocalizedValues(base::DictionaryValue* localized_strings) override; - void InitializePage() override; - - // WebUIMessageHandler implementation. - void RegisterMessages() override; - - private: - DISALLOW_COPY_AND_ASSIGN(AutomaticSettingsResetHandler); -}; - -} // namespace options - -#endif // CHROME_BROWSER_UI_WEBUI_OPTIONS_AUTOMATIC_SETTINGS_RESET_HANDLER_H_
diff --git a/chrome/browser/ui/webui/options/browser_options_handler.cc b/chrome/browser/ui/webui/options/browser_options_handler.cc deleted file mode 100644 index d775e136..0000000 --- a/chrome/browser/ui/webui/options/browser_options_handler.cc +++ /dev/null
@@ -1,2347 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/webui/options/browser_options_handler.h" - -#include <stddef.h> - -#include <set> -#include <utility> - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/command_line.h" -#include "base/environment.h" -#include "base/i18n/number_formatting.h" -#include "base/macros.h" -#include "base/memory/singleton.h" -#include "base/metrics/field_trial.h" -#include "base/metrics/histogram_macros.h" -#include "base/metrics/user_metrics.h" -#include "base/stl_util.h" -#include "base/strings/string_number_conversions.h" -#include "base/strings/utf_string_conversions.h" -#include "base/value_conversions.h" -#include "base/values.h" -#include "build/build_config.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/chrome_notification_types.h" -#include "chrome/browser/custom_home_pages_table_model.h" -#include "chrome/browser/download/download_prefs.h" -#include "chrome/browser/extensions/settings_api_helpers.h" -#include "chrome/browser/gpu/gpu_mode_manager.h" -#include "chrome/browser/lifetime/application_lifetime.h" -#include "chrome/browser/metrics/chrome_metrics_service_accessor.h" -#include "chrome/browser/metrics/metrics_reporting_state.h" -#include "chrome/browser/net/prediction_options.h" -#include "chrome/browser/prefs/session_startup_pref.h" -#include "chrome/browser/printing/cloud_print/cloud_print_proxy_service.h" -#include "chrome/browser/printing/cloud_print/cloud_print_proxy_service_factory.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/profiles/profile_attributes_entry.h" -#include "chrome/browser/profiles/profile_avatar_icon_util.h" -#include "chrome/browser/profiles/profile_manager.h" -#include "chrome/browser/profiles/profile_metrics.h" -#include "chrome/browser/profiles/profile_shortcut_manager.h" -#include "chrome/browser/profiles/profile_window.h" -#include "chrome/browser/profiles/profiles_state.h" -#include "chrome/browser/search/hotword_audio_history_handler.h" -#include "chrome/browser/search/hotword_service.h" -#include "chrome/browser/search/hotword_service_factory.h" -#include "chrome/browser/search/search.h" -#include "chrome/browser/search_engines/template_url_service_factory.h" -#include "chrome/browser/signin/easy_unlock_service.h" -#include "chrome/browser/signin/signin_manager_factory.h" -#include "chrome/browser/signin/signin_ui_util.h" -#include "chrome/browser/sync/profile_sync_service_factory.h" -#include "chrome/browser/sync/sync_ui_util.h" -#include "chrome/browser/themes/theme_service.h" -#include "chrome/browser/themes/theme_service_factory.h" -#include "chrome/browser/ui/browser_finder.h" -#include "chrome/browser/ui/chrome_select_file_policy.h" -#include "chrome/browser/ui/passwords/manage_passwords_view_utils_desktop.h" -#include "chrome/browser/ui/webui/favicon_source.h" -#include "chrome/browser/ui/webui/profile_helper.h" -#include "chrome/common/chrome_constants.h" -#include "chrome/common/chrome_features.h" -#include "chrome/common/chrome_paths.h" -#include "chrome/common/chrome_switches.h" -#include "chrome/common/extensions/extension_constants.h" -#include "chrome/common/features.h" -#include "chrome/common/pref_names.h" -#include "chrome/common/url_constants.h" -#include "chrome/grit/chromium_strings.h" -#include "chrome/grit/generated_resources.h" -#include "chrome/grit/locale_settings.h" -#include "components/browser_sync/profile_sync_service.h" -#include "components/metrics/metrics_pref_names.h" -#include "components/policy/core/common/policy_map.h" -#include "components/policy/core/common/policy_namespace.h" -#include "components/policy/core/common/policy_service.h" -#include "components/policy/policy_constants.h" -#include "components/prefs/pref_service.h" -#include "components/prefs/scoped_user_pref_update.h" -#include "components/proximity_auth/switches.h" -#include "components/proxy_config/proxy_config_pref_names.h" -#include "components/safe_browsing/common/safe_browsing_prefs.h" -#include "components/search_engines/template_url.h" -#include "components/search_engines/template_url_service.h" -#include "components/signin/core/browser/signin_manager.h" -#include "components/signin/core/common/profile_management_switches.h" -#include "components/signin/core/common/signin_pref_names.h" -#include "components/strings/grit/components_strings.h" -#include "components/user_manager/user_type.h" -#include "components/zoom/page_zoom.h" -#include "content/public/browser/browser_thread.h" -#include "content/public/browser/browser_url_handler.h" -#include "content/public/browser/download_manager.h" -#include "content/public/browser/navigation_controller.h" -#include "content/public/browser/notification_details.h" -#include "content/public/browser/notification_service.h" -#include "content/public/browser/notification_source.h" -#include "content/public/browser/notification_types.h" -#include "content/public/browser/url_data_source.h" -#include "content/public/browser/web_contents.h" -#include "content/public/common/page_zoom.h" -#include "extensions/browser/extension_registry.h" -#include "google_apis/gaia/gaia_auth_util.h" -#include "google_apis/gaia/google_service_auth_error.h" -#include "printing/features/features.h" -#include "third_party/skia/include/core/SkBitmap.h" -#include "ui/base/l10n/l10n_util.h" -#include "ui/base/webui/web_ui_util.h" - -#if !defined(OS_CHROMEOS) -#include "chrome/browser/ui/startup/default_browser_prompt.h" -#include "chrome/browser/ui/webui/settings_utils.h" -#endif - -#if defined(OS_CHROMEOS) -#include "ash/accessibility_types.h" // nogncheck -#include "ash/shell.h" // nogncheck -#include "ash/system/devicetype_utils.h" // nogncheck -#include "chrome/browser/browser_process_platform_part.h" -#include "chrome/browser/chromeos/accessibility/accessibility_util.h" -#include "chrome/browser/chromeos/arc/arc_util.h" -#include "chrome/browser/chromeos/login/quick_unlock/quick_unlock_utils.h" -#include "chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.h" -#include "chrome/browser/chromeos/net/wake_on_wifi_manager.h" -#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" -#include "chrome/browser/chromeos/profiles/profile_helper.h" -#include "chrome/browser/chromeos/reset/metrics.h" -#include "chrome/browser/chromeos/system/timezone_util.h" -#include "chrome/browser/policy/profile_policy_connector.h" -#include "chrome/browser/policy/profile_policy_connector_factory.h" -#include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h" -#include "chrome/browser/ui/app_list/arc/arc_app_utils.h" -#include "chrome/browser/ui/browser_window.h" -#include "chromeos/chromeos_switches.h" -#include "chromeos/dbus/dbus_thread_manager.h" -#include "chromeos/dbus/power_manager_client.h" -#include "components/arc/arc_util.h" -#include "components/user_manager/user.h" -#include "components/user_manager/user_manager.h" -#include "ui/gfx/image/image_skia.h" -#endif // defined(OS_CHROMEOS) - -#if BUILDFLAG(ENABLE_SERVICE_DISCOVERY) -#include "chrome/browser/printing/cloud_print/privet_notifications.h" -#endif - -using base::UserMetricsAction; -using content::BrowserContext; -using content::BrowserThread; -using content::DownloadManager; -using content::OpenURLParams; -using content::Referrer; -using extensions::Extension; -using extensions::ExtensionRegistry; - -namespace { - -void AppendExtensionData(const std::string& key, - const Extension* extension, - base::DictionaryValue* dict) { - std::unique_ptr<base::DictionaryValue> details(new base::DictionaryValue); - details->SetString("id", extension ? extension->id() : std::string()); - details->SetString("name", extension ? extension->name() : std::string()); - dict->Set(key, std::move(details)); -} - -#if !defined(OS_CHROMEOS) -bool IsDisabledByPolicy(const BooleanPrefMember& pref) { - return pref.IsManaged() && !pref.GetValue(); -} -#endif // !defined(OS_CHROMEOS) - -std::string GetSyncErrorAction(sync_ui_util::ActionType action_type) { - switch (action_type) { - case sync_ui_util::REAUTHENTICATE: - return "reauthenticate"; - case sync_ui_util::SIGNOUT_AND_SIGNIN: - return "signOutAndSignIn"; - case sync_ui_util::UPGRADE_CLIENT: - return "upgradeClient"; - case sync_ui_util::ENTER_PASSPHRASE: - return "enterPassphrase"; - default: - return "noAction"; - } -} - -#if defined(OS_CHROMEOS) -bool g_enable_polymer_preload = true; -#endif // defined(OS_CHROMEOS) -} // namespace - -namespace options { - -BrowserOptionsHandler::BrowserOptionsHandler() - : page_initialized_(false), - template_url_service_(NULL), - cloud_print_mdns_ui_enabled_(false), -#if defined(OS_CHROMEOS) - enable_factory_reset_(false), -#endif // defined(OS_CHROMEOS) - signin_observer_(this), - weak_ptr_factory_(this) { -#if !defined(OS_CHROMEOS) - // The worker pointer is reference counted. While it is running, the - // message loops of the FILE and UI thread will hold references to it - // and it will be automatically freed once all its tasks have finished. - default_browser_worker_ = new shell_integration::DefaultBrowserWorker( - base::Bind(&BrowserOptionsHandler::OnDefaultBrowserWorkerFinished, - weak_ptr_factory_.GetWeakPtr())); -#endif // !defined(OS_CHROMEOS) - -#if BUILDFLAG(ENABLE_SERVICE_DISCOVERY) - cloud_print_mdns_ui_enabled_ = true; -#endif -} - -BrowserOptionsHandler::~BrowserOptionsHandler() { - browser_sync::ProfileSyncService* sync_service( - ProfileSyncServiceFactory::GetInstance()->GetForProfile( - Profile::FromWebUI(web_ui()))); - if (sync_service) - sync_service->RemoveObserver(this); - - if (template_url_service_) - template_url_service_->RemoveObserver(this); - // There may be pending file dialogs, we need to tell them that we've gone - // away so they don't try and call back to us. - if (select_folder_dialog_.get()) - select_folder_dialog_->ListenerDestroyed(); - - g_browser_process->policy_service()->RemoveObserver( - policy::POLICY_DOMAIN_CHROME, this); -} - -void BrowserOptionsHandler::GetLocalizedValues(base::DictionaryValue* values) { - DCHECK(values); - -#if defined(OS_CHROMEOS) - const int device_type_resource_id = ash::GetChromeOSDeviceTypeResourceId(); - const int enable_logging_resource_id = - IDS_OPTIONS_ENABLE_LOGGING_DIAGNOSTIC_AND_USAGE_DATA; -#else - const int device_type_resource_id = IDS_EASY_UNLOCK_GENERIC_DEVICE_TYPE; - const int enable_logging_resource_id = IDS_OPTIONS_ENABLE_LOGGING; -#endif // defined(OS_CHROMEOS) - - static OptionsStringResource resources[] = { - // Please keep these in alphabetical order. - {"accessibilityFeaturesLink", IDS_OPTIONS_ACCESSIBILITY_FEATURES_LINK}, - {"accessibilityTitle", IDS_OPTIONS_SETTINGS_SECTION_TITLE_ACCESSIBILITY}, - {"advancedSectionTitleCertificates", - IDS_OPTIONS_ADVANCED_SECTION_TITLE_CERTIFICATES}, - {"advancedSectionTitleCloudPrint", IDS_GOOGLE_CLOUD_PRINT}, - {"advancedSectionTitleContent", IDS_OPTIONS_ADVANCED_SECTION_TITLE_CONTENT}, - {"advancedSectionTitleLanguages", - IDS_OPTIONS_ADVANCED_SECTION_TITLE_LANGUAGES}, - {"advancedSectionTitleNetwork", IDS_OPTIONS_ADVANCED_SECTION_TITLE_NETWORK}, - {"advancedSectionTitlePrivacy", IDS_OPTIONS_ADVANCED_SECTION_TITLE_PRIVACY}, - {"advancedSectionTitleSystem", IDS_OPTIONS_ADVANCED_SECTION_TITLE_SYSTEM}, - {"autoOpenFileTypesInfo", IDS_OPTIONS_OPEN_FILE_TYPES_AUTOMATICALLY}, - {"autoOpenFileTypesResetToDefault", - IDS_OPTIONS_AUTOOPENFILETYPES_RESETTODEFAULT}, - {"autofillEnabled", IDS_OPTIONS_AUTOFILL_ENABLE}, - {"autologinEnabled", IDS_OPTIONS_PASSWORDS_AUTOLOGIN}, - {"certificatesManageButton", IDS_OPTIONS_CERTIFICATES_MANAGE_BUTTON}, - {"changeHomePage", IDS_OPTIONS_CHANGE_HOME_PAGE}, - {"childLabel", IDS_PROFILES_LIST_CHILD_LABEL}, - {"currentUserOnly", IDS_OPTIONS_CURRENT_USER_ONLY}, - {"customizeSync", IDS_OPTIONS_CUSTOMIZE_SYNC_BUTTON_LABEL}, - {"defaultBrowserUnknown", IDS_OPTIONS_DEFAULTBROWSER_UNKNOWN, - IDS_PRODUCT_NAME}, - {"defaultBrowserUseAsDefault", IDS_OPTIONS_DEFAULTBROWSER_USEASDEFAULT}, - {"defaultFontSizeLabel", IDS_OPTIONS_DEFAULT_FONT_SIZE_LABEL}, - {"defaultSearchManageEngines", IDS_OPTIONS_DEFAULTSEARCH_MANAGE_ENGINES}, - {"defaultZoomFactorLabel", IDS_OPTIONS_DEFAULT_ZOOM_LEVEL_LABEL}, - {"disableWebServices", IDS_OPTIONS_DISABLE_WEB_SERVICES}, - {"doNotTrack", IDS_OPTIONS_ENABLE_DO_NOT_TRACK}, - {"doNotTrackConfirmDisable", - IDS_OPTIONS_ENABLE_DO_NOT_TRACK_BUBBLE_DISABLE}, - {"doNotTrackConfirmEnable", IDS_OPTIONS_ENABLE_DO_NOT_TRACK_BUBBLE_ENABLE}, - {"doNotTrackConfirmMessage", IDS_OPTIONS_ENABLE_DO_NOT_TRACK_BUBBLE_TEXT}, - {"downloadLocationAskForSaveLocation", - IDS_OPTIONS_DOWNLOADLOCATION_ASKFORSAVELOCATION}, - {"downloadLocationBrowseTitle", IDS_OPTIONS_DOWNLOADLOCATION_BROWSE_TITLE}, - {"downloadLocationChangeButton", - IDS_OPTIONS_DOWNLOADLOCATION_CHANGE_BUTTON}, - {"downloadLocationGroupName", IDS_OPTIONS_DOWNLOADLOCATION_GROUP_NAME}, - {"easyUnlockDescription", IDS_OPTIONS_EASY_UNLOCK_DESCRIPTION, - device_type_resource_id}, - {"easyUnlockSectionTitle", IDS_OPTIONS_EASY_UNLOCK_SECTION_TITLE}, - {"easyUnlockSetupButton", IDS_OPTIONS_EASY_UNLOCK_SETUP_BUTTON}, - {"easyUnlockSetupIntro", IDS_OPTIONS_EASY_UNLOCK_SETUP_INTRO, - device_type_resource_id}, - {"enableLogging", enable_logging_resource_id}, - {"extensionControlled", IDS_OPTIONS_TAB_EXTENSION_CONTROLLED}, - {"extensionDisable", IDS_OPTIONS_TAB_EXTENSION_CONTROLLED_DISABLE}, - {"fontSettingsCustomizeFontsButton", - IDS_OPTIONS_FONTSETTINGS_CUSTOMIZE_FONTS_BUTTON}, - {"fontSizeLabelCustom", IDS_OPTIONS_FONT_SIZE_LABEL_CUSTOM}, - {"fontSizeLabelLarge", IDS_OPTIONS_FONT_SIZE_LABEL_LARGE}, - {"fontSizeLabelMedium", IDS_OPTIONS_FONT_SIZE_LABEL_MEDIUM}, - {"fontSizeLabelSmall", IDS_OPTIONS_FONT_SIZE_LABEL_SMALL}, - {"fontSizeLabelVeryLarge", IDS_OPTIONS_FONT_SIZE_LABEL_VERY_LARGE}, - {"fontSizeLabelVerySmall", IDS_OPTIONS_FONT_SIZE_LABEL_VERY_SMALL}, - {"googleNowLauncherEnable", IDS_OPTIONS_ENABLE_GOOGLE_NOW}, - {"hideAdvancedSettings", IDS_SETTINGS_HIDE_ADVANCED_SETTINGS}, - {"homePageNtp", IDS_OPTIONS_HOMEPAGE_NTP}, - {"homePageShowHomeButton", IDS_OPTIONS_TOOLBAR_SHOW_HOME_BUTTON}, - {"homePageUseNewTab", IDS_OPTIONS_HOMEPAGE_USE_NEWTAB}, - {"homePageUseURL", IDS_OPTIONS_HOMEPAGE_USE_URL}, - {"hotwordAlwaysOnAudioHistoryDescription", - IDS_HOTWORD_ALWAYS_ON_AUDIO_HISTORY_DESCRIPTION}, - {"hotwordAlwaysOnDesc", IDS_HOTWORD_SEARCH_ALWAYS_ON_DESCRIPTION}, - {"hotwordAudioHistoryManage", IDS_HOTWORD_AUDIO_HISTORY_MANAGE_LINK}, - {"hotwordAudioLoggingEnable", IDS_HOTWORD_AUDIO_LOGGING_ENABLE}, - {"hotwordConfirmDisable", IDS_HOTWORD_CONFIRM_BUBBLE_DISABLE}, - {"hotwordConfirmEnable", IDS_HOTWORD_CONFIRM_BUBBLE_ENABLE}, - {"hotwordConfirmMessage", IDS_HOTWORD_SEARCH_PREF_DESCRIPTION}, - {"hotwordNoDSPDesc", IDS_HOTWORD_SEARCH_NO_DSP_DESCRIPTION}, - {"hotwordRetrainLink", IDS_HOTWORD_RETRAIN_LINK}, - {"hotwordSearchEnable", IDS_HOTWORD_SEARCH_PREF_CHKBOX}, - {"importData", IDS_OPTIONS_IMPORT_DATA_BUTTON}, - {"improveBrowsingExperience", IDS_OPTIONS_IMPROVE_BROWSING_EXPERIENCE}, - {"languageAndSpellCheckSettingsButton", - IDS_OPTIONS_SETTINGS_LANGUAGE_AND_INPUT_SETTINGS}, -#if defined(OS_CHROMEOS) - {"languageSectionLabel", IDS_OPTIONS_ADVANCED_LANGUAGE_LABEL, - IDS_SHORT_PRODUCT_OS_NAME}, -#else - {"languageSectionLabel", IDS_OPTIONS_ADVANCED_LANGUAGE_LABEL, - IDS_SHORT_PRODUCT_NAME}, -#endif - {"linkDoctorPref", IDS_OPTIONS_LINKDOCTOR_PREF}, - {"manageAutofillSettings", IDS_OPTIONS_MANAGE_AUTOFILL_SETTINGS_LINK}, - {"manageLanguages", IDS_OPTIONS_TRANSLATE_MANAGE_LANGUAGES}, - {"managePasswords", IDS_OPTIONS_PASSWORDS_MANAGE_PASSWORDS_LINK}, - {"metricsReportingResetRestart", IDS_OPTIONS_ENABLE_LOGGING_RESTART}, - {"networkPredictionEnabledDescription", - IDS_NETWORK_PREDICTION_ENABLED_DESCRIPTION}, - {"passwordManagerEnabled", GetPasswordManagerSettingsStringId( - ProfileSyncServiceFactory::GetForProfile( - Profile::FromWebUI(web_ui())))}, - {"passwordsAndAutofillGroupName", - IDS_OPTIONS_PASSWORDS_AND_FORMS_GROUP_NAME}, - {"privacyClearDataButton", IDS_OPTIONS_PRIVACY_CLEAR_DATA_BUTTON}, - {"privacyContentSettingsButton", - IDS_OPTIONS_PRIVACY_CONTENT_SETTINGS_BUTTON}, - {"profileAddPersonEnable", IDS_PROFILE_ADD_PERSON_ENABLE}, - {"profileBrowserGuestEnable", IDS_PROFILE_BROWSER_GUEST_ENABLE}, - {"profilesCreate", IDS_PROFILES_CREATE_BUTTON_LABEL}, - {"profilesDelete", IDS_PROFILES_DELETE_BUTTON_LABEL}, - {"profilesDeleteSingle", IDS_PROFILES_DELETE_SINGLE_BUTTON_LABEL}, - {"profilesListItemCurrent", IDS_PROFILES_LIST_ITEM_CURRENT}, - {"profilesManage", IDS_PROFILES_MANAGE_BUTTON_LABEL}, - {"profilesSingleUser", IDS_PROFILES_SINGLE_USER_MESSAGE, IDS_PRODUCT_NAME}, - {"proxiesLabelExtension", IDS_OPTIONS_EXTENSION_PROXIES_LABEL}, - {"proxiesLabelSystem", IDS_OPTIONS_SYSTEM_PROXIES_LABEL, IDS_PRODUCT_NAME}, - {"resetProfileSettings", IDS_RESET_PROFILE_SETTINGS_BUTTON}, - {"resetProfileSettingsDescription", IDS_RESET_PROFILE_SETTINGS_DESCRIPTION}, - {"resetProfileSettingsSectionTitle", - IDS_RESET_PROFILE_SETTINGS_SECTION_TITLE}, - {"safeBrowsingEnableProtection", IDS_OPTIONS_SAFEBROWSING_ENABLEPROTECTION}, - {"sectionTitleAppearance", IDS_APPEARANCE_GROUP_NAME}, - {"sectionTitleDefaultBrowser", IDS_OPTIONS_DEFAULTBROWSER_GROUP_NAME}, - {"sectionTitleProxy", IDS_OPTIONS_PROXY_GROUP_NAME}, - {"sectionTitleSearch", IDS_OPTIONS_DEFAULTSEARCH_GROUP_NAME}, - {"sectionTitleStartup", IDS_OPTIONS_STARTUP_GROUP_NAME}, - {"sectionTitleSync", IDS_SYNC_OPTIONS_GROUP_NAME}, - {"sectionTitleUsers", IDS_PROFILES_OPTIONS_GROUP_NAME}, - {"settingsTitle", IDS_SETTINGS_TITLE}, - {"showAdvancedSettings", IDS_SETTINGS_SHOW_ADVANCED_SETTINGS}, - {"spellingConfirmDisable", IDS_CONTENT_CONTEXT_SPELLING_BUBBLE_DISABLE}, - {"spellingConfirmEnable", IDS_CONTENT_CONTEXT_SPELLING_BUBBLE_ENABLE}, - {"spellingConfirmMessage", IDS_CONTENT_CONTEXT_SPELLING_BUBBLE_TEXT}, - {"spellingPref", IDS_OPTIONS_SPELLING_PREF}, - {"startupRestoreLastSession", IDS_OPTIONS_STARTUP_RESTORE_LAST_SESSION}, - {"startupSetPages", IDS_OPTIONS_STARTUP_SET_PAGES}, - {"startupShowNewTab", IDS_OPTIONS_STARTUP_SHOW_NEWTAB}, - {"startupShowPages", IDS_OPTIONS_STARTUP_SHOW_PAGES}, - {"suggestPref", IDS_OPTIONS_SUGGEST_PREF}, - {"supervisedUserLabel", IDS_PROFILES_LIST_LEGACY_SUPERVISED_USER_LABEL}, - {"syncButtonTextInProgress", IDS_SYNC_NTP_SETUP_IN_PROGRESS}, - {"syncButtonTextSignIn", IDS_SYNC_START_SYNC_BUTTON_LABEL, - IDS_SHORT_PRODUCT_NAME}, - {"syncButtonTextStop", IDS_SYNC_STOP_SYNCING_BUTTON_LABEL}, - {"syncOverview", IDS_SYNC_OVERVIEW}, - {"tabsToLinksPref", IDS_OPTIONS_TABS_TO_LINKS_PREF}, - {"themesGallery", IDS_THEMES_GALLERY_BUTTON}, - {"themesGalleryURL", IDS_THEMES_GALLERY_URL}, - {"themesReset", IDS_THEMES_RESET_BUTTON}, - {"toolbarShowBookmarksBar", IDS_OPTIONS_TOOLBAR_SHOW_BOOKMARKS_BAR}, - {"toolbarShowHomeButton", IDS_OPTIONS_TOOLBAR_SHOW_HOME_BUTTON}, - {"translateEnableTranslate", IDS_OPTIONS_TRANSLATE_ENABLE_TRANSLATE}, -#if defined(OS_CHROMEOS) - {"accessibilityAlwaysShowMenu", - IDS_OPTIONS_SETTINGS_ACCESSIBILITY_SHOULD_ALWAYS_SHOW_MENU}, - {"accessibilityAutoclick", - IDS_OPTIONS_SETTINGS_ACCESSIBILITY_AUTOCLICK_DESCRIPTION}, - {"accessibilityAutoclickDropdown", - IDS_OPTIONS_SETTINGS_ACCESSIBILITY_AUTOCLICK_DROPDOWN_DESCRIPTION}, - {"accessibilityCaretHighlight", - IDS_OPTIONS_SETTINGS_ACCESSIBILITY_CARET_HIGHLIGHT_DESCRIPTION}, - {"accessibilityCursorHighlight", - IDS_OPTIONS_SETTINGS_ACCESSIBILITY_CURSOR_HIGHLIGHT_DESCRIPTION}, - {"accessibilityExplanation", - IDS_OPTIONS_SETTINGS_ACCESSIBILITY_EXPLANATION}, - {"accessibilityFocusHighlight", - IDS_OPTIONS_SETTINGS_ACCESSIBILITY_FOCUS_HIGHLIGHT_DESCRIPTION}, - {"accessibilityHighContrast", - IDS_OPTIONS_SETTINGS_ACCESSIBILITY_HIGH_CONTRAST_DESCRIPTION}, - {"accessibilityLargeCursor", - IDS_OPTIONS_SETTINGS_ACCESSIBILITY_LARGE_CURSOR_DESCRIPTION}, - {"accessibilityScreenMagnifier", - IDS_OPTIONS_SETTINGS_ACCESSIBILITY_SCREEN_MAGNIFIER_DESCRIPTION}, - {"accessibilityScreenMagnifierCenterFocus", - IDS_OPTIONS_SETTINGS_ACCESSIBILITY_SCREEN_MAGNIFIER_CENTER_FOCUS}, - {"accessibilityScreenMagnifierFull", - IDS_OPTIONS_SETTINGS_ACCESSIBILITY_SCREEN_MAGNIFIER_FULL}, - {"accessibilityScreenMagnifierOff", - IDS_OPTIONS_SETTINGS_ACCESSIBILITY_SCREEN_MAGNIFIER_OFF}, - {"accessibilityScreenMagnifierPartial", - IDS_OPTIONS_SETTINGS_ACCESSIBILITY_SCREEN_MAGNIFIER_PARTIAL}, - {"accessibilitySelectToSpeak", - IDS_OPTIONS_SETTINGS_ACCESSIBILITY_SELECT_TO_SPEAK_DESCRIPTION}, - {"accessibilitySettings", IDS_OPTIONS_SETTINGS_ACCESSIBILITY_SETTINGS}, - {"accessibilitySpokenFeedback", - IDS_OPTIONS_SETTINGS_ACCESSIBILITY_SPOKEN_FEEDBACK_DESCRIPTION}, - {"accessibilityStickyKeys", - IDS_OPTIONS_SETTINGS_ACCESSIBILITY_STICKY_KEYS_DESCRIPTION}, - {"accessibilitySwitchAccess", - IDS_OPTIONS_SETTINGS_ACCESSIBILITY_SWITCH_ACCESS_DESCRIPTION}, - {"accessibilityTalkBackSettings", - IDS_OPTIONS_SETTINGS_ACCESSIBILITY_TALKBACK_SETTINGS}, - {"accessibilityTapDragging", - IDS_OPTIONS_SETTINGS_ACCESSIBILITY_TOUCHPAD_TAP_DRAGGING_DESCRIPTION}, - {"accessibilityVirtualKeyboard", - IDS_OPTIONS_SETTINGS_ACCESSIBILITY_VIRTUAL_KEYBOARD_DESCRIPTION}, - {"accessibilityMonoAudio", - IDS_OPTIONS_SETTINGS_ACCESSIBILITY_MONO_AUDIO_DESCRIPTION}, - {"advancedSectionTitleCupsPrint", - IDS_OPTIONS_ADVANCED_SECTION_TITLE_CUPS_PRINT}, - {"androidAppsTitle", IDS_OPTIONS_ARC_TITLE}, - {"androidAppsEnabled", IDS_OPTIONS_ARC_ENABLE}, - {"androidAppsSettingsLabel", IDS_OPTIONS_ARC_MANAGE_APPS}, - {"arcOptOutConfirmOverlayTabTitle", IDS_ARC_OPT_OUT_TAB_TITLE}, - {"arcOptOutDialogHeader", IDS_ARC_OPT_OUT_DIALOG_HEADER}, - {"arcOptOutDialogDescription", IDS_ARC_OPT_OUT_DIALOG_DESCRIPTION}, - {"arcOptOutDialogButtonConfirmDisable", - IDS_ARC_OPT_OUT_DIALOG_BUTTON_CONFIRM_DISABLE}, - {"arcOptOutDialogButtonCancel", IDS_ARC_OPT_OUT_DIALOG_BUTTON_CANCEL}, - {"autoclickDelayExtremelyShort", - IDS_OPTIONS_SETTINGS_ACCESSIBILITY_AUTOCLICK_DELAY_EXTREMELY_SHORT}, - {"autoclickDelayLong", - IDS_OPTIONS_SETTINGS_ACCESSIBILITY_AUTOCLICK_DELAY_LONG}, - {"autoclickDelayShort", - IDS_OPTIONS_SETTINGS_ACCESSIBILITY_AUTOCLICK_DELAY_SHORT}, - {"autoclickDelayVeryLong", - IDS_OPTIONS_SETTINGS_ACCESSIBILITY_AUTOCLICK_DELAY_VERY_LONG}, - {"autoclickDelayVeryShort", - IDS_OPTIONS_SETTINGS_ACCESSIBILITY_AUTOCLICK_DELAY_VERY_SHORT}, - {"changePicture", IDS_OPTIONS_CHANGE_PICTURE}, - {"changePictureCaption", IDS_OPTIONS_CHANGE_PICTURE_CAPTION}, - {"cupsPrintOptionLabel", IDS_OPTIONS_ADVANCED_SECTION_CUPS_PRINT_LABEL}, - {"cupsPrintersManageButton", - IDS_OPTIONS_ADVANCED_SECTION_CUPS_PRINT_MANAGE_BUTTON}, - {"datetimeTitle", IDS_OPTIONS_SETTINGS_SECTION_TITLE_DATETIME}, - {"deviceGroupDescription", IDS_OPTIONS_DEVICE_GROUP_DESCRIPTION}, - {"deviceGroupPointer", IDS_OPTIONS_DEVICE_GROUP_POINTER_SECTION}, - {"disableGData", IDS_OPTIONS_DISABLE_GDATA}, - {"displayOptions", IDS_OPTIONS_SETTINGS_DISPLAY_OPTIONS_BUTTON_LABEL}, - {"enableContentProtectionAttestation", - IDS_OPTIONS_ENABLE_CONTENT_PROTECTION_ATTESTATION}, - {"manageScreenlock", IDS_OPTIONS_MANAGE_SCREENLOCKER}, - {"factoryResetDataRestart", IDS_RELAUNCH_BUTTON}, - {"factoryResetDescription", IDS_OPTIONS_FACTORY_RESET_DESCRIPTION, - IDS_SHORT_PRODUCT_NAME}, - {"factoryResetHeading", IDS_OPTIONS_FACTORY_RESET_HEADING}, - {"factoryResetHelpUrl", IDS_FACTORY_RESET_HELP_URL}, - {"factoryResetRestart", IDS_OPTIONS_FACTORY_RESET_BUTTON}, - {"factoryResetTitle", IDS_OPTIONS_FACTORY_RESET}, - {"factoryResetWarning", IDS_OPTIONS_FACTORY_RESET_WARNING}, - {"internetOptionsButtonTitle", IDS_OPTIONS_INTERNET_OPTIONS_BUTTON_TITLE}, - {"keyboardSettingsButtonTitle", - IDS_OPTIONS_DEVICE_GROUP_KEYBOARD_SETTINGS_BUTTON_TITLE}, - {"manageAccountsButtonTitle", IDS_OPTIONS_ACCOUNTS_BUTTON_TITLE}, - {"mouseSpeed", IDS_OPTIONS_SETTINGS_MOUSE_SPEED_DESCRIPTION}, - {"noPointingDevices", IDS_OPTIONS_NO_POINTING_DEVICES}, - {"confirm", IDS_CONFIRM}, - {"configureFingerprintTitle", IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_TITLE}, - {"configureFingerprintInstructionLocateScannerStep", - IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_INSTRUCTION_LOCATE_SCANNER}, - {"configureFingerprintInstructionMoveFingerStep", - IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_INSTRUCTION_MOVE_FINGER}, - {"configureFingerprintInstructionReadyStep", - IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_INSTRUCTION_READY}, - {"configureFingerprintLiftFinger", - IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_LIFT_FINGER}, - {"configureFingerprintPartialData", - IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_PARTIAL_DATA}, - {"configureFingerprintInsufficientData", - IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_INSUFFICIENT_DATA}, - {"configureFingerprintSensorDirty", - IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_SENSOR_DIRTY}, - {"configureFingerprintTooSlow", - IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_FINGER_TOO_SLOW}, - {"configureFingerprintTooFast", - IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_FINGER_TOO_FAST}, - {"configureFingerprintImmobile", - IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_FINGER_IMMOBILE}, - {"configureFingerprintCancelButton", - IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_CANCEL_BUTTON}, - {"configureFingerprintDoneButton", - IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_DONE_BUTTON}, - {"configureFingerprintAddAnotherButton", - IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_ADD_ANOTHER_BUTTON}, - {"configurePinChoosePinTitle", - IDS_SETTINGS_PEOPLE_CONFIGURE_PIN_CHOOSE_PIN_TITLE}, - {"configurePinConfirmPinTitle", - IDS_SETTINGS_PEOPLE_CONFIGURE_PIN_CONFIRM_PIN_TITLE}, - {"configurePinContinueButton", - IDS_SETTINGS_PEOPLE_CONFIGURE_PIN_CONTINUE_BUTTON}, - {"configurePinMismatched", IDS_SETTINGS_PEOPLE_CONFIGURE_PIN_MISMATCHED}, - {"configurePinTooShort", IDS_SETTINGS_PEOPLE_CONFIGURE_PIN_TOO_SHORT}, - {"configurePinTooLong", IDS_SETTINGS_PEOPLE_CONFIGURE_PIN_TOO_LONG}, - {"configurePinWeakPin", IDS_SETTINGS_PEOPLE_CONFIGURE_PIN_WEAK_PIN}, - {"lockScreenAddFingerprint", - IDS_SETTINGS_PEOPLE_LOCK_SCREEN_ADD_FINGERPRINT_BUTTON}, - {"lockScreenChangePinButton", - IDS_SETTINGS_PEOPLE_LOCK_SCREEN_CHANGE_PIN_BUTTON}, - {"lockScreenEditFingerprints", - IDS_SETTINGS_PEOPLE_LOCK_SCREEN_EDIT_FINGERPRINTS}, - {"lockScreenEditFingerprintsDescription", - IDS_SETTINGS_PEOPLE_LOCK_SCREEN_EDIT_FINGERPRINTS_DESCRIPTION}, - {"lockScreenSetupFingerprintButton", - IDS_SETTINGS_PEOPLE_LOCK_SCREEN_FINGERPRINT_SETUP_BUTTON}, - {"lockScreenNumberFingerprints", - IDS_SETTINGS_PEOPLE_LOCK_SCREEN_NUM_FINGERPRINTS}, - {"lockScreenFingerprintEnable", - IDS_SETTINGS_PEOPLE_LOCK_SCREEN_ENABLE_FINGERPRINT_CHECKBOX_LABEL}, - {"lockScreenFingerprintNewName", - IDS_SETTINGS_PEOPLE_LOCK_SCREEN_NEW_FINGERPRINT_DEFAULT_NAME}, - {"lockScreenFingerprintTitle", - IDS_SETTINGS_PEOPLE_LOCK_SCREEN_FINGERPRINT_SUBPAGE_TITLE}, - {"lockScreenFingerprintWarning", - IDS_SETTINGS_PEOPLE_LOCK_SCREEN_FINGERPRINT_LESS_SECURE}, - {"lockScreenNone", IDS_SETTINGS_PEOPLE_LOCK_SCREEN_NONE}, - {"lockScreenOptions", IDS_SETTINGS_PEOPLE_LOCK_SCREEN_OPTIONS}, - {"lockScreenPasswordOnly", IDS_SETTINGS_PEOPLE_LOCK_SCREEN_PASSWORD_ONLY}, - {"lockScreenPinOrPassword", - IDS_SETTINGS_PEOPLE_LOCK_SCREEN_PIN_OR_PASSWORD}, - {"lockScreenRegisteredFingerprints", - IDS_SETTINGS_PEOPLE_LOCK_SCREEN_REGISTERED_FINGERPRINTS_LABEL}, - {"lockScreenSetupPinButton", - IDS_SETTINGS_PEOPLE_LOCK_SCREEN_SETUP_PIN_BUTTON}, - {"lockScreenTitle", IDS_SETTINGS_PEOPLE_LOCK_SCREEN_TITLE}, - {"passwordPromptEnterPassword", - IDS_SETTINGS_PEOPLE_PASSWORD_PROMPT_ENTER_PASSWORD}, - {"passwordPromptInvalidPassword", - IDS_SETTINGS_PEOPLE_PASSWORD_PROMPT_INVALID_PASSWORD}, - {"passwordPromptPasswordLabel", - IDS_SETTINGS_PEOPLE_PASSWORD_PROMPT_PASSWORD_LABEL}, - {"passwordPromptTitle", IDS_SETTINGS_PEOPLE_PASSWORD_PROMPT_TITLE}, - {"pinKeyboardPlaceholderPin", IDS_PIN_KEYBOARD_HINT_TEXT_PIN}, - {"pinKeyboardPlaceholderPinPassword", - IDS_PIN_KEYBOARD_HINT_TEXT_PIN_PASSWORD}, - {"pinKeyboardDeleteAccessibleName", - IDS_LOGIN_POD_PASSWORD_FIELD_ACCESSIBLE_NAME}, - {"powerSettingsButton", IDS_OPTIONS_DEVICE_GROUP_POWER_SETTINGS_BUTTON}, - {"resolveTimezoneByGeoLocation", - IDS_OPTIONS_RESOLVE_TIMEZONE_BY_GEOLOCATION_DESCRIPTION}, - {"sectionTitleDevice", IDS_OPTIONS_DEVICE_GROUP_NAME}, - {"sectionTitleInternet", IDS_OPTIONS_INTERNET_OPTIONS_GROUP_LABEL}, - {"storageManagerButtonTitle", - IDS_OPTIONS_DEVICE_GROUP_STORAGE_MANAGER_BUTTON_TITLE}, - {"syncButtonTextStart", IDS_SYNC_SETUP_BUTTON_LABEL}, - {"thirdPartyImeConfirmDisable", IDS_CANCEL}, - {"thirdPartyImeConfirmEnable", IDS_OK}, - {"thirdPartyImeConfirmMessage", - IDS_OPTIONS_SETTINGS_LANGUAGES_THIRD_PARTY_WARNING_MESSAGE}, - {"timezone", IDS_OPTIONS_SETTINGS_TIMEZONE_DESCRIPTION}, - {"touchpadSpeed", IDS_OPTIONS_SETTINGS_TOUCHPAD_SPEED_DESCRIPTION}, - {"use24HourClock", IDS_OPTIONS_SETTINGS_USE_24HOUR_CLOCK_DESCRIPTION}, - {"wakeOnWifiLabel", IDS_OPTIONS_SETTINGS_WAKE_ON_WIFI_DESCRIPTION}, -#else - {"gpuModeCheckbox", IDS_OPTIONS_SYSTEM_ENABLE_HARDWARE_ACCELERATION_MODE}, - {"gpuModeResetRestart", - IDS_OPTIONS_SYSTEM_ENABLE_HARDWARE_ACCELERATION_MODE_RESTART}, - {"proxiesConfigureButton", IDS_OPTIONS_PROXIES_CONFIGURE_BUTTON}, - {"syncButtonTextStart", IDS_SYNC_SETUP_BUTTON_LABEL}, -#endif // defined(OS_CHROMEOS) - -#if defined(OS_LINUX) && !defined(OS_CHROMEOS) - {"showWindowDecorations", IDS_SHOW_WINDOW_DECORATIONS}, - {"themesNativeButton", IDS_THEMES_GTK_BUTTON}, - {"themesSetClassic", IDS_THEMES_SET_CLASSIC}, -#else - {"themes", IDS_THEMES_GROUP_NAME}, -#endif // defined(OS_LINUX) && !defined(OS_CHROMEOS) - -#if defined(OS_CHROMEOS) - {"setWallpaper", IDS_SET_WALLPAPER_BUTTON}, -#endif // defined(OS_CHROMEOS) - -#if !defined(OS_MACOSX) && !defined(OS_CHROMEOS) - {"backgroundModeCheckbox", IDS_OPTIONS_SYSTEM_ENABLE_BACKGROUND_MODE}, -#endif // defined(OS_MACOSX) && !defined(OS_CHROMEOS) - -#if BUILDFLAG(ENABLE_SERVICE_DISCOVERY) - {"cloudPrintDevicesPageButton", IDS_LOCAL_DISCOVERY_DEVICES_PAGE_BUTTON}, - {"cloudPrintEnableNotificationsLabel", - IDS_LOCAL_DISCOVERY_NOTIFICATIONS_ENABLE_CHECKBOX_LABEL}, -#endif - }; - - RegisterStrings(values, resources, arraysize(resources)); - RegisterTitle(values, "doNotTrackConfirmOverlay", - IDS_OPTIONS_ENABLE_DO_NOT_TRACK_BUBBLE_TITLE); - RegisterTitle(values, "spellingConfirmOverlay", - IDS_CONTENT_CONTEXT_SPELLING_ASK_GOOGLE); -#if BUILDFLAG(ENABLE_PRINT_PREVIEW) - RegisterCloudPrintValues(values); -#endif - - Profile* profile = Profile::FromWebUI(web_ui()); - values->SetString( - "safeBrowsingEnableExtendedReporting", - l10n_util::GetStringUTF16(safe_browsing::ChooseOptInTextResource( - *profile->GetPrefs(), - IDS_OPTIONS_SAFEBROWSING_ENABLE_EXTENDED_REPORTING, - IDS_OPTIONS_SAFEBROWSING_ENABLE_SCOUT_REPORTING))); - values->SetString("syncLearnMoreURL", chrome::kSyncLearnMoreURL); - base::string16 omnibox_url = base::ASCIIToUTF16(chrome::kOmniboxLearnMoreURL); - values->SetString( - "defaultSearchGroupLabel", - l10n_util::GetStringFUTF16(IDS_SEARCH_PREF_EXPLANATION, omnibox_url)); - values->SetString("hotwordLearnMoreURL", chrome::kHotwordLearnMoreURL); - RegisterTitle(values, "hotwordConfirmOverlay", - IDS_HOTWORD_CONFIRM_BUBBLE_TITLE); - values->SetString("hotwordManageAudioHistoryURL", - chrome::kManageAudioHistoryURL); - base::string16 supervised_user_dashboard = - base::ASCIIToUTF16(chrome::kLegacySupervisedUserManagementURL); - values->SetString("profilesSupervisedDashboardTip", - l10n_util::GetStringFUTF16( - IDS_PROFILES_LEGACY_SUPERVISED_USER_DASHBOARD_TIP, - supervised_user_dashboard)); - -#if defined(OS_CHROMEOS) - std::string username = profile->GetProfileUserName(); - if (username.empty()) { - const user_manager::User* user = - chromeos::ProfileHelper::Get()->GetUserByProfile(profile); - if (user && (user->GetType() != user_manager::USER_TYPE_GUEST)) - username = user->GetAccountId().GetUserEmail(); - } - if (!username.empty()) - username = gaia::SanitizeEmail(gaia::CanonicalizeEmail(username)); - - values->SetString("username", username); -#endif - // Pass along sync status early so it will be available during page init. - values->Set("syncData", GetSyncStateDictionary()); - - values->SetString("privacyLearnMoreURL", chrome::kPrivacyLearnMoreURL); - - values->SetString("doNotTrackLearnMoreURL", chrome::kDoNotTrackLearnMoreURL); - - values->SetBoolean( - "metricsReportingEnabledAtStart", - ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled()); - -#if defined(OS_CHROMEOS) - // TODO(pastarmovj): replace this with a call to the CrosSettings list - // handling functionality to come. - values->Set("timezoneList", chromeos::system::GetTimezoneList()); - - values->SetString("accessibilityLearnMoreURL", - chrome::kChromeAccessibilityHelpURL); - - std::string settings_url = std::string("chrome-extension://") + - extension_misc::kChromeVoxExtensionId + - chrome::kChromeAccessibilitySettingsURL; - - values->SetString("accessibilitySettingsURL", - settings_url); - - values->SetString("contentProtectionAttestationLearnMoreURL", - chrome::kAttestationForContentProtectionLearnMoreURL); - - // Creates magnifierList. - std::unique_ptr<base::ListValue> magnifier_list(new base::ListValue); - - std::unique_ptr<base::ListValue> option_full(new base::ListValue); - option_full->AppendInteger(ash::MAGNIFIER_FULL); - option_full->AppendString(l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_ACCESSIBILITY_SCREEN_MAGNIFIER_FULL)); - magnifier_list->Append(std::move(option_full)); - - std::unique_ptr<base::ListValue> option_partial(new base::ListValue); - option_partial->AppendInteger(ash::MAGNIFIER_PARTIAL); - option_partial->AppendString(l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_ACCESSIBILITY_SCREEN_MAGNIFIER_PARTIAL)); - magnifier_list->Append(std::move(option_partial)); - - values->Set("magnifierList", std::move(magnifier_list)); - values->SetBoolean("enablePolymerPreload", g_enable_polymer_preload); -#endif // defined(OS_CHROMEOS) - -#if defined(OS_MACOSX) - values->SetString("macPasswordsWarning", - l10n_util::GetStringUTF16(IDS_OPTIONS_PASSWORDS_MAC_WARNING)); - values->SetBoolean("multiple_profiles", - g_browser_process->profile_manager()->GetNumberOfProfiles() > 1); -#endif - - if (ShouldShowMultiProfilesUserList()) - values->Set("profilesInfo", GetProfilesInfoList()); - - // Profile deletion is not allowed for any users in ChromeOS. - bool allow_deletion = true; -#if defined(OS_CHROMEOS) - allow_deletion = allow_deletion && !ash::Shell::HasInstance(); -#endif - values->SetBoolean("allowProfileDeletion", allow_deletion); - values->SetBoolean("profileIsGuest", profile->IsOffTheRecord()); - values->SetBoolean("profileIsSupervised", profile->IsSupervised()); - -#if !defined(OS_CHROMEOS) - values->SetBoolean( - "gpuEnabledAtStart", - g_browser_process->gpu_mode_manager()->initial_gpu_mode_pref()); -#endif - -#if defined(OS_CHROMEOS) - values->SetString("cupsPrintLearnMoreURL", chrome::kCrosPrintingLearnMoreURL); -#endif // defined(OS_CHROMEOS) - -#if BUILDFLAG(ENABLE_SERVICE_DISCOVERY) - values->SetBoolean("cloudPrintHideNotificationsCheckbox", - !cloud_print::PrivetNotificationService::IsEnabled()); -#endif - - values->SetBoolean("cloudPrintShowMDnsOptions", - cloud_print_mdns_ui_enabled_); - - values->SetString("cloudPrintLearnMoreURL", chrome::kCloudPrintLearnMoreURL); - - values->SetString("languagesLearnMoreURL", - chrome::kLanguageSettingsLearnMoreUrl); - - values->SetBoolean( - "easyUnlockAllowed", EasyUnlockService::Get(profile)->IsAllowed()); - values->SetString("easyUnlockLearnMoreURL", chrome::kEasyUnlockLearnMoreUrl); - -#if defined(OS_CHROMEOS) - RegisterTitle(values, "thirdPartyImeConfirmOverlay", - IDS_OPTIONS_SETTINGS_LANGUAGES_THIRD_PARTY_WARNING_TITLE); - values->SetBoolean("usingNewProfilesUI", false); -#else - values->SetBoolean("usingNewProfilesUI", true); -#endif - - values->SetBoolean("showSetDefault", ShouldShowSetDefaultBrowser()); - - values->SetBoolean("allowAdvancedSettings", ShouldAllowAdvancedSettings()); - -#if defined(OS_CHROMEOS) - values->SetBoolean( - "showWakeOnWifi", - chromeos::WakeOnWifiManager::Get()->WakeOnWifiSupported() && - chromeos::switches::WakeOnWifiEnabled()); - values->SetBoolean("enableTimeZoneTrackingOption", - !chromeos::system::HasSystemTimezonePolicy()); - values->SetBoolean("resolveTimezoneByGeolocationInitialValue", - profile->GetPrefs()->GetBoolean(prefs::kResolveTimezoneByGeolocation)); - values->SetBoolean("enableLanguageOptionsImeMenu", - base::FeatureList::IsEnabled(features::kOptInImeMenu)); - values->SetBoolean( - "enableExperimentalAccessibilityFeatures", - base::CommandLine::ForCurrentProcess()->HasSwitch( - chromeos::switches::kEnableExperimentalAccessibilityFeatures)); - - chromeos::CrosSettings* cros_settings = chromeos::CrosSettings::Get(); - bool allow_bluetooth = true; - cros_settings->GetBoolean(chromeos::kAllowBluetooth, &allow_bluetooth); - values->SetBoolean("allowBluetooth", allow_bluetooth); - - values->SetBoolean("showQuickUnlockSettings", - chromeos::quick_unlock::IsPinEnabled(profile->GetPrefs())); - values->SetBoolean("fingerprintUnlockEnabled", - chromeos::quick_unlock::IsFingerprintEnabled()); - values->SetBoolean("quickUnlockEnabled", - chromeos::quick_unlock::IsPinEnabled(profile->GetPrefs())); - if (chromeos::quick_unlock::IsPinEnabled(profile->GetPrefs())) { - values->SetString( - "enableScreenlock", - l10n_util::GetStringUTF16( - IDS_OPTIONS_ENABLE_SCREENLOCKER_CHECKBOX_WITH_QUICK_UNLOCK)); - } else { - values->SetString( - "enableScreenlock", - l10n_util::GetStringUTF16(IDS_OPTIONS_ENABLE_SCREENLOCKER_CHECKBOX)); - } - // Format numbers to be used on the pin keyboard. - for (int j = 0; j <= 9; ++j) { - values->SetString("pinKeyboard" + base::IntToString(j), - base::FormatNumber(int64_t{j})); - } -#endif -} - -#if BUILDFLAG(ENABLE_PRINT_PREVIEW) -void BrowserOptionsHandler::RegisterCloudPrintValues( - base::DictionaryValue* values) { - values->SetString("cloudPrintOptionLabel", - l10n_util::GetStringFUTF16( - IDS_CLOUD_PRINT_CHROMEOS_OPTION_LABEL, - l10n_util::GetStringUTF16(IDS_GOOGLE_CLOUD_PRINT))); -} -#endif // BUILDFLAG(ENABLE_PRINT_PREVIEW) - -void BrowserOptionsHandler::RegisterMessages() { - web_ui()->RegisterMessageCallback( - "setDefaultSearchEngine", - base::Bind(&BrowserOptionsHandler::SetDefaultSearchEngine, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "deleteProfile", - base::Bind(&BrowserOptionsHandler::DeleteProfile, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "themesReset", - base::Bind(&BrowserOptionsHandler::ThemesReset, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "requestProfilesInfo", - base::Bind(&BrowserOptionsHandler::HandleRequestProfilesInfo, - base::Unretained(this))); -#if defined(OS_LINUX) && !defined(OS_CHROMEOS) - web_ui()->RegisterMessageCallback( - "themesSetNative", - base::Bind(&BrowserOptionsHandler::ThemesSetNative, - base::Unretained(this))); -#endif - web_ui()->RegisterMessageCallback( - "selectDownloadLocation", - base::Bind(&BrowserOptionsHandler::HandleSelectDownloadLocation, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "autoOpenFileTypesAction", - base::Bind(&BrowserOptionsHandler::HandleAutoOpenButton, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "defaultFontSizeAction", - base::Bind(&BrowserOptionsHandler::HandleDefaultFontSize, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "defaultZoomFactorAction", - base::Bind(&BrowserOptionsHandler::HandleDefaultZoomFactor, - base::Unretained(this))); -#if defined(OS_WIN) || defined(OS_MACOSX) - web_ui()->RegisterMessageCallback( - "showManageSSLCertificates", - base::Bind(&BrowserOptionsHandler::ShowManageSSLCertificates, - base::Unretained(this))); -#endif -#if defined(OS_CHROMEOS) - web_ui()->RegisterMessageCallback( - "openWallpaperManager", - base::Bind(&BrowserOptionsHandler::HandleOpenWallpaperManager, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "virtualKeyboardChange", - base::Bind(&BrowserOptionsHandler::VirtualKeyboardChangeCallback, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "onPowerwashDialogShow", - base::Bind(&BrowserOptionsHandler::OnPowerwashDialogShow, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "performFactoryResetRestart", - base::Bind(&BrowserOptionsHandler::PerformFactoryResetRestart, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "showAndroidAppsSettings", - base::Bind(&BrowserOptionsHandler::ShowAndroidAppsSettings, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "showPlayStoreApps", - base::Bind(&BrowserOptionsHandler::ShowPlayStoreApps, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "showAccessibilityTalkBackSettings", - base::Bind(&BrowserOptionsHandler::ShowAccessibilityTalkBackSettings, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "showCupsPrintDevicesPage", - base::Bind(&BrowserOptionsHandler::ShowCupsPrintDevicesPage, - base::Unretained(this))); -#else - web_ui()->RegisterMessageCallback( - "becomeDefaultBrowser", - base::Bind(&BrowserOptionsHandler::BecomeDefaultBrowser, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "restartBrowser", - base::Bind(&BrowserOptionsHandler::HandleRestartBrowser, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "showNetworkProxySettings", - base::Bind(&BrowserOptionsHandler::ShowNetworkProxySettings, - base::Unretained(this))); -#endif // defined(OS_CHROMEOS) - -#if BUILDFLAG(ENABLE_SERVICE_DISCOVERY) - if (cloud_print_mdns_ui_enabled_) { - web_ui()->RegisterMessageCallback( - "showCloudPrintDevicesPage", - base::Bind(&BrowserOptionsHandler::ShowCloudPrintDevicesPage, - base::Unretained(this))); - } -#endif - web_ui()->RegisterMessageCallback( - "requestGoogleNowAvailable", - base::Bind(&BrowserOptionsHandler::HandleRequestGoogleNowAvailable, - base::Unretained(this))); - - web_ui()->RegisterMessageCallback( - "requestHotwordAvailable", - base::Bind(&BrowserOptionsHandler::HandleRequestHotwordAvailable, - base::Unretained(this))); - - web_ui()->RegisterMessageCallback( - "launchHotwordAudioVerificationApp", - base::Bind( - &BrowserOptionsHandler::HandleLaunchHotwordAudioVerificationApp, - base::Unretained(this))); - - web_ui()->RegisterMessageCallback( - "launchEasyUnlockSetup", - base::Bind(&BrowserOptionsHandler::HandleLaunchEasyUnlockSetup, - base::Unretained(this))); -#if defined(OS_WIN) - web_ui()->RegisterMessageCallback( - "refreshExtensionControlIndicators", - base::Bind( - &BrowserOptionsHandler::HandleRefreshExtensionControlIndicators, - base::Unretained(this))); -#endif // defined(OS_WIN) - web_ui()->RegisterMessageCallback("metricsReportingCheckboxChanged", - base::Bind(&BrowserOptionsHandler::HandleMetricsReportingChange, - base::Unretained(this))); - - web_ui()->RegisterMessageCallback( - "safeBrowsingExtendedReportingAction", - base::Bind(&BrowserOptionsHandler::HandleSafeBrowsingExtendedReporting, - base::Unretained(this))); -} - -void BrowserOptionsHandler::Uninitialize() { - registrar_.RemoveAll(); - g_browser_process->profile_manager()-> - GetProfileAttributesStorage().RemoveObserver(this); -#if defined(OS_WIN) - ExtensionRegistry::Get(Profile::FromWebUI(web_ui()))->RemoveObserver(this); -#endif -#if defined(OS_CHROMEOS) - ArcAppListPrefs* arc_prefs = ArcAppListPrefs::Get( - Profile::FromWebUI(web_ui())); - if (arc_prefs) - arc_prefs->RemoveObserver(this); - user_manager::UserManager::Get()->RemoveObserver(this); -#endif -} - -void BrowserOptionsHandler::OnStateChanged(syncer::SyncService* sync) { - UpdateSyncState(); -} - -void BrowserOptionsHandler::GoogleSigninSucceeded(const std::string& account_id, - const std::string& username) { - UpdateSyncState(); -} - -void BrowserOptionsHandler::GoogleSignedOut(const std::string& account_id, - const std::string& username) { - UpdateSyncState(); -} - -void BrowserOptionsHandler::PageLoadStarted() { - page_initialized_ = false; -} - -void BrowserOptionsHandler::InitializeHandler() { - Profile* profile = Profile::FromWebUI(web_ui()); - PrefService* prefs = profile->GetPrefs(); - ChromeZoomLevelPrefs* zoom_level_prefs = profile->GetZoomLevelPrefs(); - // Only regular profiles are able to edit default zoom level, or delete per- - // host zoom levels, via the settings menu. We only require a zoom_level_prefs - // if the profile is able to change these preference types. - DCHECK(zoom_level_prefs || - profile->GetProfileType() != Profile::REGULAR_PROFILE); - if (zoom_level_prefs) { - default_zoom_level_subscription_ = - zoom_level_prefs->RegisterDefaultZoomLevelCallback( - base::Bind(&BrowserOptionsHandler::SetupPageZoomSelector, - base::Unretained(this))); - } - - g_browser_process->policy_service()->AddObserver( - policy::POLICY_DOMAIN_CHROME, this); - - g_browser_process->profile_manager()-> - GetProfileAttributesStorage().AddObserver(this); - - browser_sync::ProfileSyncService* sync_service( - ProfileSyncServiceFactory::GetInstance()->GetForProfile(profile)); - // TODO(blundell): Use a ScopedObserver to observe the PSS so that cleanup on - // destruction is automatic. - if (sync_service) - sync_service->AddObserver(this); - - SigninManagerBase* signin_manager( - SigninManagerFactory::GetInstance()->GetForProfile(profile)); - if (signin_manager) - signin_observer_.Add(signin_manager); - - // Create our favicon data source. - content::URLDataSource::Add(profile, new FaviconSource(profile)); - -#if !defined(OS_CHROMEOS) - default_browser_policy_.Init( - prefs::kDefaultBrowserSettingEnabled, - g_browser_process->local_state(), - base::Bind(&BrowserOptionsHandler::UpdateDefaultBrowserState, - base::Unretained(this))); -#endif - -#if defined(OS_CHROMEOS) - user_manager::UserManager::Get()->AddObserver(this); -#endif - registrar_.Add(this, chrome::NOTIFICATION_BROWSER_THEME_CHANGED, - content::Source<ThemeService>( - ThemeServiceFactory::GetForProfile(profile))); - registrar_.Add(this, chrome::NOTIFICATION_GLOBAL_ERRORS_CHANGED, - content::Source<Profile>(profile)); - AddTemplateUrlServiceObserver(); - -#if defined(OS_WIN) - ExtensionRegistry::Get(profile)->AddObserver(this); -#endif - - // No preferences below this point may be modified by guest profiles. - if (profile->IsGuestSession()) - return; - - auto_open_files_.Init( - prefs::kDownloadExtensionsToOpen, prefs, - base::Bind(&BrowserOptionsHandler::SetupAutoOpenFileTypes, - base::Unretained(this))); - profile_pref_registrar_.Init(prefs); - profile_pref_registrar_.Add( - prefs::kNetworkPredictionOptions, - base::Bind(&BrowserOptionsHandler::SetupNetworkPredictionControl, - base::Unretained(this))); - profile_pref_registrar_.Add( - prefs::kWebKitDefaultFontSize, - base::Bind(&BrowserOptionsHandler::SetupFontSizeSelector, - base::Unretained(this))); - profile_pref_registrar_.Add( - prefs::kWebKitDefaultFixedFontSize, - base::Bind(&BrowserOptionsHandler::SetupFontSizeSelector, - base::Unretained(this))); - profile_pref_registrar_.Add( - prefs::kSupervisedUsers, - base::Bind(&BrowserOptionsHandler::SetupManagingSupervisedUsers, - base::Unretained(this))); - profile_pref_registrar_.Add( - prefs::kSigninAllowed, - base::Bind(&BrowserOptionsHandler::OnSigninAllowedPrefChange, - base::Unretained(this))); - profile_pref_registrar_.Add( - prefs::kEasyUnlockPairing, - base::Bind(&BrowserOptionsHandler::SetupEasyUnlock, - base::Unretained(this))); - -#if defined(OS_WIN) - profile_pref_registrar_.Add( - prefs::kURLsToRestoreOnStartup, - base::Bind(&BrowserOptionsHandler::SetupExtensionControlledIndicators, - base::Unretained(this))); - profile_pref_registrar_.Add( - prefs::kHomePage, - base::Bind(&BrowserOptionsHandler::SetupExtensionControlledIndicators, - base::Unretained(this))); -#endif // defined(OS_WIN) - -#if defined(OS_CHROMEOS) - if (!policy_registrar_) { - policy_registrar_.reset(new policy::PolicyChangeRegistrar( - policy::ProfilePolicyConnectorFactory::GetForBrowserContext(profile) - ->policy_service(), - policy::PolicyNamespace(policy::POLICY_DOMAIN_CHROME, std::string()))); - policy_registrar_->Observe( - policy::key::kUserAvatarImage, - base::Bind(&BrowserOptionsHandler::OnUserImagePolicyChanged, - base::Unretained(this))); - policy_registrar_->Observe( - policy::key::kWallpaperImage, - base::Bind(&BrowserOptionsHandler::OnWallpaperPolicyChanged, - base::Unretained(this))); - } - system_timezone_policy_observer_ = - chromeos::CrosSettings::Get()->AddSettingsObserver( - chromeos::kSystemTimezonePolicy, - base::Bind(&BrowserOptionsHandler::OnSystemTimezonePolicyChanged, - weak_ptr_factory_.GetWeakPtr())); - local_state_pref_change_registrar_.Init(g_browser_process->local_state()); - local_state_pref_change_registrar_.Add( - prefs::kSystemTimezoneAutomaticDetectionPolicy, - base::Bind(&BrowserOptionsHandler:: - OnSystemTimezoneAutomaticDetectionPolicyChanged, - base::Unretained(this))); - ArcAppListPrefs* arc_prefs = ArcAppListPrefs::Get(profile); - if (arc_prefs) - arc_prefs->AddObserver(this); -#else // !defined(OS_CHROMEOS) - profile_pref_registrar_.Add( - proxy_config::prefs::kProxy, - base::Bind(&BrowserOptionsHandler::SetupProxySettingsSection, - base::Unretained(this))); -#endif // !defined(OS_CHROMEOS) - - profile_pref_registrar_.Add( - prefs::kSafeBrowsingExtendedReportingEnabled, - base::Bind(&BrowserOptionsHandler::SetupSafeBrowsingExtendedReporting, - base::Unretained(this))); - profile_pref_registrar_.Add( - prefs::kSafeBrowsingScoutReportingEnabled, - base::Bind(&BrowserOptionsHandler::SetupSafeBrowsingExtendedReporting, - base::Unretained(this))); -} - -void BrowserOptionsHandler::InitializePage() { - page_initialized_ = true; - - OnTemplateURLServiceChanged(); - - ObserveThemeChanged(); - UpdateSyncState(); -#if !defined(OS_CHROMEOS) - UpdateDefaultBrowserState(); -#endif - - SetupMetricsReportingSettingVisibility(); - SetupMetricsReportingCheckbox(); - SetupNetworkPredictionControl(); - SetupFontSizeSelector(); - SetupPageZoomSelector(); - SetupAutoOpenFileTypes(); - SetupProxySettingsSection(); - SetupManagingSupervisedUsers(); - SetupEasyUnlock(); - SetupExtensionControlledIndicators(); - SetupSafeBrowsingExtendedReporting(); - -#if defined(OS_CHROMEOS) - SetupAccessibilityFeatures(); - policy::BrowserPolicyConnectorChromeOS* connector = - g_browser_process->platform_part()->browser_policy_connector_chromeos(); - enable_factory_reset_ = !connector->IsEnterpriseManaged() && - !user_manager::UserManager::Get()->IsLoggedInAsGuest() && - !user_manager::UserManager::Get()->IsLoggedInAsSupervisedUser(); - if (enable_factory_reset_) { - web_ui()->CallJavascriptFunctionUnsafe( - "BrowserOptions.enableFactoryResetSection"); - } - - Profile* const profile = Profile::FromWebUI(web_ui()); - user_manager::User const* const user = - chromeos::ProfileHelper::Get()->GetUserByProfile(profile); - - OnAccountPictureManagedChanged( - policy::ProfilePolicyConnectorFactory::GetForBrowserContext(profile) - ->policy_service() - ->GetPolicies(policy::PolicyNamespace(policy::POLICY_DOMAIN_CHROME, - std::string())) - .Get(policy::key::kUserAvatarImage)); - - OnWallpaperManagedChanged( - chromeos::WallpaperManager::Get()->IsPolicyControlled( - user->GetAccountId())); - - if (arc::IsArcAllowedForProfile(profile) && - !arc::IsArcOptInVerificationDisabled()) { - base::Value is_play_store_enabled( - arc::IsArcPlayStoreEnabledForProfile(profile)); - web_ui()->CallJavascriptFunctionUnsafe( - "BrowserOptions.showAndroidAppsSection", is_play_store_enabled); - // Get the initial state of Android Settings app readiness. - std::unique_ptr<ArcAppListPrefs::AppInfo> app_info = - ArcAppListPrefs::Get(profile)->GetApp(arc::kSettingsAppId); - if (app_info && app_info->ready) - UpdateAndroidSettingsAppState(app_info->ready); - } - - OnSystemTimezoneAutomaticDetectionPolicyChanged(); -#endif -} - -bool BrowserOptionsHandler::ShouldShowSetDefaultBrowser() { -#if defined(OS_CHROMEOS) - // We're always the default browser on ChromeOS. - return false; -#else - return !Profile::FromWebUI(web_ui())->IsGuestSession(); -#endif -} - -bool BrowserOptionsHandler::ShouldShowMultiProfilesUserList() { -#if defined(OS_CHROMEOS) - // On Chrome OS we use different UI for multi-profiles. - return false; -#else - if (Profile::FromWebUI(web_ui())->IsGuestSession()) - return false; - return profiles::IsMultipleProfilesEnabled(); -#endif -} - -bool BrowserOptionsHandler::ShouldAllowAdvancedSettings() { -#if defined(OS_CHROMEOS) - // ChromeOS handles guest-mode restrictions in a different manner. - return true; -#else - return !Profile::FromWebUI(web_ui())->IsGuestSession(); -#endif -} - -#if !defined(OS_CHROMEOS) - -void BrowserOptionsHandler::UpdateDefaultBrowserState() { - default_browser_worker_->StartCheckIsDefault(); -} - -void BrowserOptionsHandler::BecomeDefaultBrowser(const base::ListValue* args) { - // If the default browser setting is managed then we should not be able to - // call this function. - if (IsDisabledByPolicy(default_browser_policy_)) - return; - - base::RecordAction(UserMetricsAction("Options_SetAsDefaultBrowser")); - UMA_HISTOGRAM_COUNTS("Settings.StartSetAsDefault", true); - - // Callback takes care of updating UI. - default_browser_worker_->StartSetAsDefault(); - - // If the user attempted to make Chrome the default browser, notify - // them when this changes. - chrome::ResetDefaultBrowserPrompt(Profile::FromWebUI(web_ui())); -} - -void BrowserOptionsHandler::OnDefaultBrowserWorkerFinished( - shell_integration::DefaultWebClientState state) { - int status_string_id; - - if (state == shell_integration::IS_DEFAULT) { - status_string_id = IDS_OPTIONS_DEFAULTBROWSER_DEFAULT; - // Notify the user in the future if Chrome ceases to be the user's chosen - // default browser. - chrome::ResetDefaultBrowserPrompt(Profile::FromWebUI(web_ui())); - } else if (state == shell_integration::NOT_DEFAULT) { - if (shell_integration::CanSetAsDefaultBrowser()) { - status_string_id = IDS_OPTIONS_DEFAULTBROWSER_NOTDEFAULT; - } else { - status_string_id = IDS_OPTIONS_DEFAULTBROWSER_SXS; - } - } else if (state == shell_integration::UNKNOWN_DEFAULT) { - status_string_id = IDS_OPTIONS_DEFAULTBROWSER_UNKNOWN; - } else { - NOTREACHED(); - return; - } - - SetDefaultBrowserUIString(status_string_id); -} - -void BrowserOptionsHandler::SetDefaultBrowserUIString(int status_string_id) { - base::Value status_string(l10n_util::GetStringFUTF16( - status_string_id, l10n_util::GetStringUTF16(IDS_PRODUCT_NAME))); - - base::Value is_default(status_string_id == - IDS_OPTIONS_DEFAULTBROWSER_DEFAULT); - - base::Value can_be_default( - !IsDisabledByPolicy(default_browser_policy_) && - (status_string_id == IDS_OPTIONS_DEFAULTBROWSER_DEFAULT || - status_string_id == IDS_OPTIONS_DEFAULTBROWSER_NOTDEFAULT)); - - web_ui()->CallJavascriptFunctionUnsafe( - "BrowserOptions.updateDefaultBrowserState", status_string, is_default, - can_be_default); -} -#endif // !defined(OS_CHROMEOS) - -void BrowserOptionsHandler::OnTemplateURLServiceChanged() { - if (!template_url_service_ || !template_url_service_->loaded()) - return; - - const TemplateURL* default_url = - template_url_service_->GetDefaultSearchProvider(); - - int default_index = -1; - base::ListValue search_engines; - TemplateURLService::TemplateURLVector model_urls( - template_url_service_->GetTemplateURLs()); - for (size_t i = 0; i < model_urls.size(); ++i) { - TemplateURL* t_url = model_urls[i]; - if (!template_url_service_->ShowInDefaultList(t_url)) - continue; - - std::unique_ptr<base::DictionaryValue> entry(new base::DictionaryValue()); - entry->SetString("name", t_url->short_name()); - entry->SetInteger("index", i); - search_engines.Append(std::move(entry)); - if (t_url == default_url) - default_index = i; - } - - web_ui()->CallJavascriptFunctionUnsafe( - "BrowserOptions.updateSearchEngines", search_engines, - base::Value(default_index), - base::Value(template_url_service_->is_default_search_managed() || - template_url_service_->IsExtensionControlledDefaultSearch())); - - SetupExtensionControlledIndicators(); - - HandleRequestHotwordAvailable(nullptr); - HandleRequestGoogleNowAvailable(nullptr); -} - -void BrowserOptionsHandler::SetDefaultSearchEngine( - const base::ListValue* args) { - int selected_index = -1; - if (!ExtractIntegerValue(args, &selected_index)) { - NOTREACHED(); - return; - } - - TemplateURLService::TemplateURLVector model_urls( - template_url_service_->GetTemplateURLs()); - if (selected_index >= 0 && - selected_index < static_cast<int>(model_urls.size())) - template_url_service_->SetUserSelectedDefaultSearchProvider( - model_urls[selected_index]); - - base::RecordAction(UserMetricsAction("Options_SearchEngineChanged")); -} - -void BrowserOptionsHandler::AddTemplateUrlServiceObserver() { - template_url_service_ = - TemplateURLServiceFactory::GetForProfile(Profile::FromWebUI(web_ui())); - if (template_url_service_) { - template_url_service_->Load(); - template_url_service_->AddObserver(this); - } -} - -void BrowserOptionsHandler::OnExtensionLoaded( - content::BrowserContext* browser_context, - const Extension* extension) { - SetupExtensionControlledIndicators(); -} - -void BrowserOptionsHandler::OnExtensionUnloaded( - content::BrowserContext* browser_context, - const Extension* extension, - extensions::UnloadedExtensionReason reason) { - SetupExtensionControlledIndicators(); -} - -void BrowserOptionsHandler::Observe( - int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) { - // Notifications are used to update the UI dynamically when settings change in - // the background. If the UI is currently being loaded, no dynamic updates are - // possible (as the DOM and JS are not fully loaded) or necessary (as - // InitializePage() will update the UI at the end of the load). - if (!page_initialized_) - return; - - switch (type) { - case chrome::NOTIFICATION_BROWSER_THEME_CHANGED: - ObserveThemeChanged(); - break; - case chrome::NOTIFICATION_GLOBAL_ERRORS_CHANGED: - // Update our sync/signin status display. - UpdateSyncState(); - break; - default: - NOTREACHED(); - } -} - -void BrowserOptionsHandler::OnProfileAdded(const base::FilePath& profile_path) { - SendProfilesInfo(); -} - -void BrowserOptionsHandler::OnProfileWasRemoved( - const base::FilePath& profile_path, - const base::string16& profile_name) { - SendProfilesInfo(); -} - -void BrowserOptionsHandler::OnProfileNameChanged( - const base::FilePath& profile_path, - const base::string16& old_profile_name) { - SendProfilesInfo(); -} - -void BrowserOptionsHandler::OnProfileAvatarChanged( - const base::FilePath& profile_path) { - SendProfilesInfo(); -} - -std::unique_ptr<base::ListValue> BrowserOptionsHandler::GetProfilesInfoList() { - std::vector<ProfileAttributesEntry*> entries = - g_browser_process->profile_manager()-> - GetProfileAttributesStorage().GetAllProfilesAttributesSortedByName(); - std::unique_ptr<base::ListValue> profile_info_list(new base::ListValue); - base::FilePath current_profile_path = - web_ui()->GetWebContents()->GetBrowserContext()->GetPath(); - - for (const ProfileAttributesEntry* entry : entries) { - // The items in |profile_value| are also described in - // chrome/browser/resources/options/browser_options.js in a @typedef for - // Profile. Please update it whenever you add or remove any keys here. - std::unique_ptr<base::DictionaryValue> profile_value( - new base::DictionaryValue()); - profile_value->SetString("name", entry->GetName()); - base::FilePath profile_path = entry->GetPath(); - profile_value->Set("filePath", base::CreateFilePathValue(profile_path)); - profile_value->SetBoolean("isCurrentProfile", - profile_path == current_profile_path); - profile_value->SetBoolean("isSupervised", entry->IsSupervised()); - profile_value->SetBoolean("isChild", entry->IsChild()); - - if (entry->IsUsingGAIAPicture() && entry->GetGAIAPicture()) { - gfx::Image icon = profiles::GetAvatarIconForWebUI(entry->GetAvatarIcon(), - true); - profile_value->SetString("iconURL", - webui::GetBitmapDataUrl(icon.AsBitmap())); - } else { - size_t icon_index = entry->GetAvatarIconIndex(); - profile_value->SetString("iconURL", - profiles::GetDefaultAvatarIconUrl(icon_index)); - } - - profile_info_list->Append(std::move(profile_value)); - } - - return profile_info_list; -} - -void BrowserOptionsHandler::SendProfilesInfo() { - if (!ShouldShowMultiProfilesUserList()) - return; - web_ui()->CallJavascriptFunctionUnsafe("BrowserOptions.setProfilesInfo", - *GetProfilesInfoList()); -} - -void BrowserOptionsHandler::DeleteProfile(const base::ListValue* args) { - DCHECK(args); - const base::Value* file_path_value; - if (!args->Get(0, &file_path_value)) { - NOTREACHED(); - return; - } - - base::FilePath file_path; - if (!base::GetValueAsFilePath(*file_path_value, &file_path)) { - NOTREACHED(); - return; - } - - webui::DeleteProfileAtPath(file_path, - web_ui(), - ProfileMetrics::DELETE_PROFILE_SETTINGS); -} - -void BrowserOptionsHandler::ObserveThemeChanged() { - Profile* profile = Profile::FromWebUI(web_ui()); - ThemeService* theme_service = ThemeServiceFactory::GetForProfile(profile); - bool is_system_theme = false; - -#if defined(OS_LINUX) && !defined(OS_CHROMEOS) - bool profile_is_supervised = profile->IsSupervised(); - is_system_theme = theme_service->UsingSystemTheme(); - base::Value native_theme_enabled(!is_system_theme && !profile_is_supervised); - web_ui()->CallJavascriptFunctionUnsafe( - "BrowserOptions.setNativeThemeButtonEnabled", native_theme_enabled); -#endif - - bool is_classic_theme = !is_system_theme && - theme_service->UsingDefaultTheme(); - base::Value enabled(!is_classic_theme); - web_ui()->CallJavascriptFunctionUnsafe( - "BrowserOptions.setThemesResetButtonEnabled", enabled); -} - -void BrowserOptionsHandler::ThemesReset(const base::ListValue* args) { - Profile* profile = Profile::FromWebUI(web_ui()); - base::RecordAction(UserMetricsAction("Options_ThemesReset")); - ThemeServiceFactory::GetForProfile(profile)->UseDefaultTheme(); -} - -#if defined(OS_LINUX) && !defined(OS_CHROMEOS) -void BrowserOptionsHandler::ThemesSetNative(const base::ListValue* args) { - base::RecordAction(UserMetricsAction("Options_GtkThemeSet")); - Profile* profile = Profile::FromWebUI(web_ui()); - ThemeServiceFactory::GetForProfile(profile)->UseSystemTheme(); -} -#endif - -#if defined(OS_CHROMEOS) -void BrowserOptionsHandler::UpdateAccountPicture() { - std::string email = user_manager::UserManager::Get() - ->GetActiveUser() - ->GetAccountId() - .GetUserEmail(); - if (!email.empty()) { - web_ui()->CallJavascriptFunctionUnsafe( - "BrowserOptions.updateAccountPicture"); - base::Value email_value(email); - web_ui()->CallJavascriptFunctionUnsafe( - "BrowserOptions.updateAccountPicture", email_value); - web_ui()->CallJavascriptFunctionUnsafe( - "AccountsOptions.getInstance().updateAccountPicture", email_value); - } -} - -void BrowserOptionsHandler::OnAccountPictureManagedChanged(bool managed) { - web_ui()->CallJavascriptFunctionUnsafe( - "BrowserOptions.setAccountPictureManaged", base::Value(managed)); -} - -void BrowserOptionsHandler::OnWallpaperManagedChanged(bool managed) { - web_ui()->CallJavascriptFunctionUnsafe("BrowserOptions.setWallpaperManaged", - base::Value(managed)); -} - -void BrowserOptionsHandler::OnSystemTimezonePolicyChanged() { - web_ui()->CallJavascriptFunctionUnsafe( - "BrowserOptions.setSystemTimezoneManaged", - base::Value(chromeos::system::HasSystemTimezonePolicy())); -} - -void BrowserOptionsHandler::OnSystemTimezoneAutomaticDetectionPolicyChanged() { - if (base::CommandLine::ForCurrentProcess()->HasSwitch( - chromeos::switches::kDisableSystemTimezoneAutomaticDetectionPolicy)) { - return; - } - - PrefService* prefs = g_browser_process->local_state(); - const bool is_managed = prefs->IsManagedPreference( - prefs::kSystemTimezoneAutomaticDetectionPolicy); - const int value = - prefs->GetInteger(prefs::kSystemTimezoneAutomaticDetectionPolicy); - web_ui()->CallJavascriptFunctionUnsafe( - "BrowserOptions.setSystemTimezoneAutomaticDetectionManaged", - base::Value(is_managed), base::Value(value)); -} -#endif - -std::unique_ptr<base::DictionaryValue> -BrowserOptionsHandler::GetSyncStateDictionary() { - // The items which are to be written into |sync_status| are also described in - // chrome/browser/resources/options/browser_options.js in @typedef - // for SyncStatus. Please update it whenever you add or remove any keys here. - std::unique_ptr<base::DictionaryValue> sync_status(new base::DictionaryValue); - Profile* profile = Profile::FromWebUI(web_ui()); - if (profile->IsGuestSession()) { - // Cannot display signin status when running in guest mode on chromeos - // because there is no SigninManager. - sync_status->SetBoolean("signinAllowed", false); - return sync_status; - } - - sync_status->SetBoolean("supervisedUser", profile->IsSupervised()); - sync_status->SetBoolean("childUser", profile->IsChild()); - - bool signout_prohibited = false; -#if !defined(OS_CHROMEOS) - // Signout is not allowed if the user has policy (crbug.com/172204). - signout_prohibited = - SigninManagerFactory::GetForProfile(profile)->IsSignoutProhibited(); -#endif - - browser_sync::ProfileSyncService* service = - ProfileSyncServiceFactory::GetInstance()->GetForProfile(profile); - SigninManagerBase* signin = SigninManagerFactory::GetForProfile(profile); - DCHECK(signin); - sync_status->SetBoolean("signoutAllowed", !signout_prohibited); - sync_status->SetBoolean("signinAllowed", signin->IsSigninAllowed()); - sync_status->SetBoolean("syncSystemEnabled", (service != NULL)); - sync_status->SetBoolean("setupCompleted", - service && service->IsFirstSetupComplete()); - sync_status->SetBoolean("setupInProgress", - service && !service->IsManaged() && service->IsFirstSetupInProgress()); - - base::string16 status_label; - base::string16 link_label; - sync_ui_util::ActionType action_type = sync_ui_util::NO_ACTION; - bool status_has_error = - sync_ui_util::GetStatusLabels(profile, service, *signin, - sync_ui_util::WITH_HTML, &status_label, - &link_label, &action_type) == - sync_ui_util::SYNC_ERROR; - sync_status->SetString("statusText", status_label); - sync_status->SetString("actionLinkText", link_label); - sync_status->SetBoolean("hasError", status_has_error); - sync_status->SetString("statusAction", GetSyncErrorAction(action_type)); - sync_status->SetBoolean("managed", service && service->IsManaged()); - sync_status->SetBoolean("signedIn", signin->IsAuthenticated()); - sync_status->SetString("accountInfo", - l10n_util::GetStringFUTF16( - IDS_SYNC_ACCOUNT_INFO, - signin_ui_util::GetAuthenticatedUsername(signin))); - sync_status->SetBoolean("hasUnrecoverableError", - service && service->HasUnrecoverableError()); - - return sync_status; -} - -void BrowserOptionsHandler::HandleSelectDownloadLocation( - const base::ListValue* args) { - PrefService* pref_service = Profile::FromWebUI(web_ui())->GetPrefs(); - select_folder_dialog_ = ui::SelectFileDialog::Create( - this, new ChromeSelectFilePolicy(web_ui()->GetWebContents())); - ui::SelectFileDialog::FileTypeInfo info; - info.allowed_paths = ui::SelectFileDialog::FileTypeInfo::NATIVE_OR_DRIVE_PATH; - select_folder_dialog_->SelectFile( - ui::SelectFileDialog::SELECT_FOLDER, - l10n_util::GetStringUTF16(IDS_OPTIONS_DOWNLOADLOCATION_BROWSE_TITLE), - pref_service->GetFilePath(prefs::kDownloadDefaultDirectory), - &info, - 0, - base::FilePath::StringType(), - web_ui()->GetWebContents()->GetTopLevelNativeWindow(), - NULL); -} - -void BrowserOptionsHandler::FileSelected(const base::FilePath& path, int index, - void* params) { - base::RecordAction(UserMetricsAction("Options_SetDownloadDirectory")); - PrefService* pref_service = Profile::FromWebUI(web_ui())->GetPrefs(); - pref_service->SetFilePath(prefs::kDownloadDefaultDirectory, path); - pref_service->SetFilePath(prefs::kSaveFileDefaultDirectory, path); -} - -#if defined(OS_CHROMEOS) -void BrowserOptionsHandler::TouchpadExists(bool exists) { - base::Value val(exists); - web_ui()->CallJavascriptFunctionUnsafe("BrowserOptions.showTouchpadControls", - val); -} - -void BrowserOptionsHandler::MouseExists(bool exists) { - base::Value val(exists); - web_ui()->CallJavascriptFunctionUnsafe("BrowserOptions.showMouseControls", - val); -} - -void BrowserOptionsHandler::OnUserImagePolicyChanged( - const base::Value* previous_policy, - const base::Value* current_policy) { - const bool had_policy = previous_policy; - const bool has_policy = current_policy; - if (had_policy != has_policy) - OnAccountPictureManagedChanged(has_policy); -} - -void BrowserOptionsHandler::OnWallpaperPolicyChanged( - const base::Value* previous_policy, - const base::Value* current_policy) { - const bool had_policy = previous_policy; - const bool has_policy = current_policy; - if (had_policy != has_policy) - OnWallpaperManagedChanged(has_policy); -} - -void BrowserOptionsHandler::OnPowerwashDialogShow( - const base::ListValue* args) { - UMA_HISTOGRAM_ENUMERATION( - "Reset.ChromeOS.PowerwashDialogShown", - chromeos::reset::DIALOG_FROM_OPTIONS, - chromeos::reset::DIALOG_VIEW_TYPE_SIZE); -} - -#endif // defined(OS_CHROMEOS) - -void BrowserOptionsHandler::UpdateSyncState() { - web_ui()->CallJavascriptFunctionUnsafe("BrowserOptions.updateSyncState", - *GetSyncStateDictionary()); - - // A change in sign-in state also affects how hotwording and audio history are - // displayed. Hide all hotwording and re-display properly. - web_ui()->CallJavascriptFunctionUnsafe( - "BrowserOptions.setAllHotwordSectionsVisible", base::Value(false)); - HandleRequestHotwordAvailable(nullptr); -} - -void BrowserOptionsHandler::OnSigninAllowedPrefChange() { - UpdateSyncState(); -} - -void BrowserOptionsHandler::HandleAutoOpenButton(const base::ListValue* args) { - base::RecordAction(UserMetricsAction("Options_ResetAutoOpenFiles")); - DownloadManager* manager = BrowserContext::GetDownloadManager( - web_ui()->GetWebContents()->GetBrowserContext()); - DownloadPrefs::FromDownloadManager(manager)->ResetAutoOpen(); -} - -void BrowserOptionsHandler::HandleDefaultFontSize(const base::ListValue* args) { - int font_size; - if (ExtractIntegerValue(args, &font_size)) { - if (font_size > 0) { - PrefService* pref_service = Profile::FromWebUI(web_ui())->GetPrefs(); - pref_service->SetInteger(prefs::kWebKitDefaultFontSize, font_size); - SetupFontSizeSelector(); - } - } -} - -void BrowserOptionsHandler::HandleDefaultZoomFactor( - const base::ListValue* args) { - double zoom_factor; - if (ExtractDoubleValue(args, &zoom_factor)) { - ChromeZoomLevelPrefs* zoom_level_prefs = - Profile::FromWebUI(web_ui())->GetZoomLevelPrefs(); - DCHECK(zoom_level_prefs); - zoom_level_prefs->SetDefaultZoomLevelPref( - content::ZoomFactorToZoomLevel(zoom_factor)); - } -} - -void BrowserOptionsHandler::HandleRestartBrowser(const base::ListValue* args) { - chrome::AttemptRestart(); -} - -void BrowserOptionsHandler::HandleRequestProfilesInfo( - const base::ListValue* args) { - SendProfilesInfo(); -} - -#if !defined(OS_CHROMEOS) -void BrowserOptionsHandler::ShowNetworkProxySettings( - const base::ListValue* args) { - base::RecordAction(UserMetricsAction("Options_ShowProxySettings")); - settings_utils::ShowNetworkProxySettings(web_ui()->GetWebContents()); -} -#endif - -#if defined(OS_WIN) || defined(OS_MACOSX) -void BrowserOptionsHandler::ShowManageSSLCertificates( - const base::ListValue* args) { - base::RecordAction(UserMetricsAction("Options_ManageSSLCertificates")); - settings_utils::ShowManageSSLCertificates(web_ui()->GetWebContents()); -} -#endif - -#if defined(OS_CHROMEOS) -void BrowserOptionsHandler::ShowCupsPrintDevicesPage( - const base::ListValue* args) { - // Navigate in current tab to CUPS printers management page. - OpenURLParams params(GURL(chrome::kChromeUIMdCupsSettingsURL), Referrer(), - WindowOpenDisposition::NEW_FOREGROUND_TAB, - ui::PAGE_TRANSITION_LINK, false); - web_ui()->GetWebContents()->OpenURL(params); -} -#endif // defined(OS_CHROMEOS) - -#if BUILDFLAG(ENABLE_SERVICE_DISCOVERY) -void BrowserOptionsHandler::ShowCloudPrintDevicesPage( - const base::ListValue* args) { - base::RecordAction(UserMetricsAction("Options_CloudPrintDevicesPage")); - // Navigate in current tab to devices page. - OpenURLParams params(GURL(chrome::kChromeUIDevicesURL), Referrer(), - WindowOpenDisposition::CURRENT_TAB, - ui::PAGE_TRANSITION_LINK, false); - web_ui()->GetWebContents()->OpenURL(params); -} -#endif - -void BrowserOptionsHandler::SetHotwordAudioHistorySectionVisible( - const base::string16& audio_history_state, - bool success, bool logging_enabled) { - bool visible = logging_enabled && success; - web_ui()->CallJavascriptFunctionUnsafe( - "BrowserOptions.setAudioHistorySectionVisible", base::Value(visible), - base::Value(audio_history_state)); -} - -void BrowserOptionsHandler::HandleRequestGoogleNowAvailable( - const base::ListValue* args) { - bool is_search_provider_google = false; - if (template_url_service_ && template_url_service_->loaded()) { - const TemplateURL* default_url = - template_url_service_->GetDefaultSearchProvider(); - if (default_url && default_url->HasGoogleBaseURLs( - template_url_service_->search_terms_data())) { - is_search_provider_google = true; - } - } - - std::string group = base::FieldTrialList::FindFullName("GoogleNowExtension"); - bool has_field_trial = !group.empty() && group != "Disabled"; - - bool should_show = is_search_provider_google && has_field_trial; - web_ui()->CallJavascriptFunctionUnsafe("BrowserOptions.setNowSectionVisible", - base::Value(should_show)); -} - -void BrowserOptionsHandler::HandleRequestHotwordAvailable( - const base::ListValue* args) { - Profile* profile = Profile::FromWebUI(web_ui()); - - bool is_search_provider_google = false; - // The check for default search provider is only valid if the - // |template_url_service_| has loaded already. - if (template_url_service_ && template_url_service_->loaded()) { - const TemplateURL* default_url = - template_url_service_->GetDefaultSearchProvider(); - if (default_url && default_url->HasGoogleBaseURLs( - template_url_service_->search_terms_data())) { - is_search_provider_google = true; - } else { - // If the user has chosen a default search provide other than Google, turn - // off hotwording since other providers don't provide that functionality. - HotwordService* hotword_service = - HotwordServiceFactory::GetForProfile(profile); - if (hotword_service) - hotword_service->DisableHotwordPreferences(); - } - } - - // |is_search_provider_google| may be false because |template_url_service_| - // does not exist yet or because the user selected a different search - // provider. In either case it does not make sense to show the hotwording - // options. - if (!is_search_provider_google) { - web_ui()->CallJavascriptFunctionUnsafe( - "BrowserOptions.setAllHotwordSectionsVisible", base::Value(false)); - return; - } - - // Don't need to check the field trial here since |IsHotwordAllowed| also - // checks it. - if (HotwordServiceFactory::IsHotwordAllowed(profile)) { - // Update the current error value. - HotwordServiceFactory::IsServiceAvailable(profile); - int error = HotwordServiceFactory::GetCurrentError(profile); - - std::string function_name; - bool always_on = false; - SigninManagerBase* signin = SigninManagerFactory::GetForProfile(profile); - bool authenticated = signin && signin->IsAuthenticated(); - if (HotwordServiceFactory::IsAlwaysOnAvailable() && authenticated) { - function_name = "BrowserOptions.showHotwordAlwaysOnSection"; - always_on = true; - // Show the retrain link if always-on is enabled. - if (profile->GetPrefs()->GetBoolean( - prefs::kHotwordAlwaysOnSearchEnabled)) { - web_ui()->CallJavascriptFunctionUnsafe( - "BrowserOptions.setHotwordRetrainLinkVisible", base::Value(true)); - } - } else { - function_name = "BrowserOptions.showHotwordNoDspSection"; - } - - // Audio history should be displayed if it's enabled regardless of the - // hotword error state if the user is signed in. If the user is not signed - // in, audio history is meaningless. This is only displayed if always-on - // hotwording is available. - if (authenticated && always_on) { - std::string user_display_name = - signin->GetAuthenticatedAccountInfo().email; - DCHECK(!user_display_name.empty()); - base::string16 audio_history_state = - l10n_util::GetStringFUTF16(IDS_HOTWORD_AUDIO_HISTORY_ENABLED, - base::ASCIIToUTF16(user_display_name)); - HotwordService* hotword_service = - HotwordServiceFactory::GetForProfile(profile); - if (hotword_service) { - hotword_service->GetAudioHistoryHandler()->GetAudioHistoryEnabled( - base::Bind( - &BrowserOptionsHandler::SetHotwordAudioHistorySectionVisible, - weak_ptr_factory_.GetWeakPtr(), - audio_history_state)); - } - } - - if (!error) { - web_ui()->CallJavascriptFunctionUnsafe(function_name); - } else { - base::string16 hotword_help_url = - base::ASCIIToUTF16(chrome::kHotwordLearnMoreURL); - base::Value error_message(l10n_util::GetStringUTF16(error)); - if (error == IDS_HOTWORD_GENERIC_ERROR_MESSAGE) { - error_message = - base::Value(l10n_util::GetStringFUTF16(error, hotword_help_url)); - } - web_ui()->CallJavascriptFunctionUnsafe(function_name, error_message); - } - } -} - -void BrowserOptionsHandler::HandleLaunchHotwordAudioVerificationApp( - const base::ListValue* args) { - Profile* profile = Profile::FromWebUI(web_ui()); - - bool retrain = false; - bool success = args->GetBoolean(0, &retrain); - DCHECK(success); - HotwordService::LaunchMode launch_mode = - HotwordService::HOTWORD_AND_AUDIO_HISTORY; - - if (retrain) { - DCHECK(profile->GetPrefs()->GetBoolean( - prefs::kHotwordAlwaysOnSearchEnabled)); - DCHECK(profile->GetPrefs()->GetBoolean( - prefs::kHotwordAudioLoggingEnabled)); - - launch_mode = HotwordService::RETRAIN; - } else if (profile->GetPrefs()->GetBoolean( - prefs::kHotwordAudioLoggingEnabled)) { - DCHECK(!profile->GetPrefs()->GetBoolean( - prefs::kHotwordAlwaysOnSearchEnabled)); - launch_mode = HotwordService::HOTWORD_ONLY; - } else { - DCHECK(!profile->GetPrefs()->GetBoolean( - prefs::kHotwordAlwaysOnSearchEnabled)); - } - - HotwordService* hotword_service = - HotwordServiceFactory::GetForProfile(profile); - if (!hotword_service) - return; - - hotword_service->OptIntoHotwording(launch_mode); -} - -void BrowserOptionsHandler::HandleLaunchEasyUnlockSetup( - const base::ListValue* args) { - EasyUnlockService::Get(Profile::FromWebUI(web_ui()))->LaunchSetup(); -} - -void BrowserOptionsHandler::HandleRefreshExtensionControlIndicators( - const base::ListValue* args) { - SetupExtensionControlledIndicators(); -} - -#if defined(OS_CHROMEOS) -void BrowserOptionsHandler::HandleOpenWallpaperManager( - const base::ListValue* args) { - chromeos::WallpaperManager::Get()->Open(); -} - -void BrowserOptionsHandler::VirtualKeyboardChangeCallback( - const base::ListValue* args) { - bool enabled = false; - args->GetBoolean(0, &enabled); - - chromeos::accessibility::EnableVirtualKeyboard(enabled); -} - -void BrowserOptionsHandler::PerformFactoryResetRestart( - const base::ListValue* args) { - if (!enable_factory_reset_) - return; - - PrefService* prefs = g_browser_process->local_state(); - prefs->SetBoolean(prefs::kFactoryResetRequested, true); - prefs->CommitPendingWrite(); - - // Perform sign out. Current chrome process will then terminate, new one will - // be launched (as if it was a restart). - chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->RequestRestart(); -} - -void BrowserOptionsHandler::OnAppRegistered( - const std::string& app_id, - const ArcAppListPrefs::AppInfo& app_info) { - OnAppReadyChanged(app_id, app_info.ready); -} - -void BrowserOptionsHandler::OnAppRemoved(const std::string& app_id) { - OnAppReadyChanged(app_id, false); -} - -void BrowserOptionsHandler::OnAppReadyChanged( - const std::string& app_id, - bool ready) { - if (app_id == arc::kSettingsAppId) { - UpdateAndroidSettingsAppState(ready); - } -} - -void BrowserOptionsHandler::OnUserImageChanged(const user_manager::User& user) { - UpdateAccountPicture(); -} - -void BrowserOptionsHandler::UpdateAndroidSettingsAppState(bool visible) { - base::Value is_visible(visible); - web_ui()->CallJavascriptFunctionUnsafe( - "BrowserOptions.setAndroidAppsSettingsVisibility", is_visible); -} - -void BrowserOptionsHandler::ShowAndroidAppsSettings( - const base::ListValue* args) { - Profile* profile = Profile::FromWebUI(web_ui()); - // Settings in secondary profile cannot access ARC. - if (!arc::IsArcAllowedForProfile(profile)) { - LOG(ERROR) << "Settings can't be invoked for non-primary profile"; - return; - } - - // We only care whether the event came from a keyboard or non-keyboard - // (mouse/touch). Set the default flags in such a way that it would appear - // that it came from a mouse by default. - bool activated_from_keyboard = false; - args->GetBoolean(0, &activated_from_keyboard); - int flags = activated_from_keyboard ? ui::EF_NONE : ui::EF_LEFT_MOUSE_BUTTON; - - arc::LaunchAndroidSettingsApp(profile, flags); -} - -void BrowserOptionsHandler::ShowPlayStoreApps(const base::ListValue* args) { - std::string apps_url; - args->GetString(0, &apps_url); - Profile* profile = Profile::FromWebUI(web_ui()); - if (!arc::IsArcAllowedForProfile(profile)) { - VLOG(1) << "ARC is not enabled for this profile"; - return; - } - - arc::LaunchPlayStoreWithUrl(apps_url); -} - -void BrowserOptionsHandler::ShowAccessibilityTalkBackSettings( - const base::ListValue *args) { - Profile* profile = Profile::FromWebUI(web_ui()); - // Settings in secondary profile cannot access ARC. - if (!arc::IsArcAllowedForProfile(profile)) { - LOG(WARNING) << "Settings can't be invoked for non-primary profile"; - return; - } - - arc::ShowTalkBackSettings(); -} - -void BrowserOptionsHandler::SetupAccessibilityFeatures() { - PrefService* pref_service = g_browser_process->local_state(); - base::Value virtual_keyboard_enabled( - pref_service->GetBoolean(prefs::kAccessibilityVirtualKeyboardEnabled)); - web_ui()->CallJavascriptFunctionUnsafe( - "BrowserOptions.setVirtualKeyboardCheckboxState", - virtual_keyboard_enabled); -} -#endif - -void BrowserOptionsHandler::SetupMetricsReportingSettingVisibility() { -#if defined(GOOGLE_CHROME_BUILD) - // Don't show the reporting setting if we are in the guest mode. - if (Profile::FromWebUI(web_ui())->IsGuestSession()) { - base::Value visible(false); - web_ui()->CallJavascriptFunctionUnsafe( - "BrowserOptions.setMetricsReportingSettingVisibility", visible); - } -#endif -} - -void BrowserOptionsHandler::SetupNetworkPredictionControl() { - PrefService* pref_service = Profile::FromWebUI(web_ui())->GetPrefs(); - - base::DictionaryValue dict; - dict.SetInteger("value", - pref_service->GetInteger(prefs::kNetworkPredictionOptions)); - dict.SetBoolean("disabled", - !pref_service->IsUserModifiablePreference( - prefs::kNetworkPredictionOptions)); - - web_ui()->CallJavascriptFunctionUnsafe( - "BrowserOptions.setNetworkPredictionValue", dict); -} - -void BrowserOptionsHandler::SetupFontSizeSelector() { - PrefService* pref_service = Profile::FromWebUI(web_ui())->GetPrefs(); - const PrefService::Preference* default_font_size = - pref_service->FindPreference(prefs::kWebKitDefaultFontSize); - const PrefService::Preference* default_fixed_font_size = - pref_service->FindPreference(prefs::kWebKitDefaultFixedFontSize); - - base::DictionaryValue dict; - dict.SetInteger("value", - pref_service->GetInteger(prefs::kWebKitDefaultFontSize)); - - // The font size control displays the value of the default font size, but - // setting it alters both the default font size and the default fixed font - // size. So it must be disabled when either of those prefs is not user - // modifiable. - dict.SetBoolean("disabled", - !default_font_size->IsUserModifiable() || - !default_fixed_font_size->IsUserModifiable()); - - // This is a simplified version of CoreOptionsHandler::CreateValueForPref, - // adapted to consider two prefs. It may be better to refactor - // CreateValueForPref so it can be called from here. - if (default_font_size->IsManaged() || default_fixed_font_size->IsManaged()) { - dict.SetString("controlledBy", "policy"); - } else if (default_font_size->IsExtensionControlled() || - default_fixed_font_size->IsExtensionControlled()) { - dict.SetString("controlledBy", "extension"); - } - - web_ui()->CallJavascriptFunctionUnsafe("BrowserOptions.setFontSize", dict); -} - -void BrowserOptionsHandler::SetupPageZoomSelector() { - double default_zoom_level = - content::HostZoomMap::GetDefaultForBrowserContext( - Profile::FromWebUI(web_ui()))->GetDefaultZoomLevel(); - double default_zoom_factor = - content::ZoomLevelToZoomFactor(default_zoom_level); - - // Generate a vector of zoom factors from an array of known presets along with - // the default factor added if necessary. - std::vector<double> zoom_factors = - zoom::PageZoom::PresetZoomFactors(default_zoom_factor); - - // Iterate through the zoom factors and and build the contents of the - // selector that will be sent to the javascript handler. - // Each item in the list has the following parameters: - // 1. Title (string). - // 2. Value (double). - // 3. Is selected? (bool). - base::ListValue zoom_factors_value; - for (std::vector<double>::const_iterator i = zoom_factors.begin(); - i != zoom_factors.end(); ++i) { - std::unique_ptr<base::ListValue> option(new base::ListValue()); - double factor = *i; - int percent = static_cast<int>(factor * 100 + 0.5); - option->AppendString(base::FormatPercent(percent)); - option->AppendDouble(factor); - bool selected = content::ZoomValuesEqual(factor, default_zoom_factor); - option->AppendBoolean(selected); - zoom_factors_value.Append(std::move(option)); - } - - web_ui()->CallJavascriptFunctionUnsafe("BrowserOptions.setupPageZoomSelector", - zoom_factors_value); -} - -void BrowserOptionsHandler::SetupAutoOpenFileTypes() { - // Set the hidden state for the AutoOpenFileTypesResetToDefault button. - // We show the button if the user has any auto-open file types registered. - DownloadManager* manager = BrowserContext::GetDownloadManager( - web_ui()->GetWebContents()->GetBrowserContext()); - bool display = DownloadPrefs::FromDownloadManager(manager)->IsAutoOpenUsed(); - base::Value value(display); - web_ui()->CallJavascriptFunctionUnsafe( - "BrowserOptions.setAutoOpenFileTypesDisplayed", value); -} - -void BrowserOptionsHandler::SetupProxySettingsSection() { -#if !defined(OS_CHROMEOS) - PrefService* pref_service = Profile::FromWebUI(web_ui())->GetPrefs(); - const PrefService::Preference* proxy_config = - pref_service->FindPreference(proxy_config::prefs::kProxy); - bool is_extension_controlled = (proxy_config && - proxy_config->IsExtensionControlled()); - - base::Value disabled(proxy_config && !proxy_config->IsUserModifiable()); - base::Value extension_controlled(is_extension_controlled); - web_ui()->CallJavascriptFunctionUnsafe( - "BrowserOptions.setupProxySettingsButton", disabled, - extension_controlled); - -#if defined(OS_WIN) - SetupExtensionControlledIndicators(); -#endif // defined(OS_WIN) - -#endif // !defined(OS_CHROMEOS) -} - -void BrowserOptionsHandler::SetupManagingSupervisedUsers() { - bool has_users = !Profile::FromWebUI(web_ui())-> - GetPrefs()->GetDictionary(prefs::kSupervisedUsers)->empty(); - base::Value has_users_value(has_users); - web_ui()->CallJavascriptFunctionUnsafe( - "BrowserOptions.updateManagesSupervisedUsers", has_users_value); -} - -void BrowserOptionsHandler::SetupEasyUnlock() { - base::Value is_enabled( - EasyUnlockService::Get(Profile::FromWebUI(web_ui()))->IsEnabled()); - web_ui()->CallJavascriptFunctionUnsafe("BrowserOptions.updateEasyUnlock", - is_enabled); -} - -void BrowserOptionsHandler::SetupExtensionControlledIndicators() { - base::DictionaryValue extension_controlled; - - Profile* profile = Profile::FromWebUI(web_ui()); - - // Check if an extension is overriding the Search Engine. - const extensions::Extension* extension = - extensions::GetExtensionOverridingSearchEngine(profile); - AppendExtensionData("searchEngine", extension, &extension_controlled); - - // Check if an extension is overriding the Home page. - extension = extensions::GetExtensionOverridingHomepage(profile); - AppendExtensionData("homePage", extension, &extension_controlled); - - // Check if an extension is overriding the Startup pages. - extension = extensions::GetExtensionOverridingStartupPages(profile); - AppendExtensionData("startUpPage", extension, &extension_controlled); - - // Check if an extension is overriding the NTP page. - extension = extensions::GetExtensionOverridingNewTabPage(profile); - AppendExtensionData("newTabPage", extension, &extension_controlled); - - // Check if an extension is overwriting the proxy setting. - extension = extensions::GetExtensionOverridingProxy(profile); - AppendExtensionData("proxy", extension, &extension_controlled); - - web_ui()->CallJavascriptFunctionUnsafe( - "BrowserOptions.toggleExtensionIndicators", extension_controlled); -} - -void BrowserOptionsHandler::SetupMetricsReportingCheckbox() { -// As the metrics and crash reporting checkbox only exists for official builds -// it doesn't need to be set up for non-official builds. -#if defined(GOOGLE_CHROME_BUILD) - bool checked = - ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled(); - bool policy_managed = IsMetricsReportingPolicyManaged(); - bool owner_managed = false; -#if defined(OS_CHROMEOS) - owner_managed = !IsDeviceOwnerProfile(); -#endif // defined(OS_CHROMEOS) - SetMetricsReportingCheckbox(checked, policy_managed, owner_managed); -#endif // defined(GOOGLE_CHROME_BUILD) -} - -void BrowserOptionsHandler::HandleMetricsReportingChange( - const base::ListValue* args) { - bool enable; - if (!args->GetBoolean(0, &enable)) - return; - // Decline the change if current user shouldn't be able to change metrics - // reporting. - if (!IsDeviceOwnerProfile() || IsMetricsReportingPolicyManaged()) { - NotifyUIOfMetricsReportingChange( - ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled()); - return; - } - -// For Chrome OS updating device settings will notify an observer to update -// metrics pref, however we still need to call -// |ChangeMetricsReportingStateWithReply| with a proper callback so that UI gets -// updated in case of failure to update the metrics pref. -// TODO(gayane): Don't call |ChangeMetricsReportingStateWithReply| twice so that -// metrics service pref changes only as a result of device settings change for -// Chrome OS .crbug.com/552550. -#if defined(OS_CHROMEOS) - chromeos::CrosSettings::Get()->SetBoolean(chromeos::kStatsReportingPref, - enable); -#endif // defined(OS_CHROMEOS) - ChangeMetricsReportingStateWithReply( - enable, - base::Bind(&BrowserOptionsHandler::NotifyUIOfMetricsReportingChange, - weak_ptr_factory_.GetWeakPtr())); -} - -void BrowserOptionsHandler::NotifyUIOfMetricsReportingChange(bool enabled) { - SetMetricsReportingCheckbox(enabled, IsMetricsReportingPolicyManaged(), - !IsDeviceOwnerProfile()); -} - -void BrowserOptionsHandler::SetMetricsReportingCheckbox(bool checked, - bool policy_managed, - bool owner_managed) { - web_ui()->CallJavascriptFunctionUnsafe( - "BrowserOptions.setMetricsReportingCheckboxState", base::Value(checked), - base::Value(policy_managed), base::Value(owner_managed)); -} - -void BrowserOptionsHandler::SetupSafeBrowsingExtendedReporting() { - base::Value is_enabled(safe_browsing::IsExtendedReportingEnabled( - *Profile::FromWebUI(web_ui())->GetPrefs())); - web_ui()->CallJavascriptFunctionUnsafe( - "BrowserOptions.setExtendedReportingEnabledCheckboxState", is_enabled); -} - -void BrowserOptionsHandler::HandleSafeBrowsingExtendedReporting( - const base::ListValue* args) { - bool checked; - if (args->GetBoolean(0, &checked)) { - safe_browsing::SetExtendedReportingPrefAndMetric( - Profile::FromWebUI(web_ui())->GetPrefs(), checked, - safe_browsing::SBER_OPTIN_SITE_CHROME_SETTINGS); - } -} - -void BrowserOptionsHandler::OnPolicyUpdated(const policy::PolicyNamespace& ns, - const policy::PolicyMap& previous, - const policy::PolicyMap& current) { - std::set<std::string> different_keys; - current.GetDifferingKeys(previous, &different_keys); - if (base::ContainsKey(different_keys, policy::key::kMetricsReportingEnabled)) - SetupMetricsReportingCheckbox(); -} - -#if defined(OS_CHROMEOS) -// static -void BrowserOptionsHandler::DisablePolymerPreloadForTesting() { - g_enable_polymer_preload = false; -} -#endif // defined(OS_CHROMEOS) - -bool BrowserOptionsHandler::IsDeviceOwnerProfile() { -#if defined(OS_CHROMEOS) - return chromeos::ProfileHelper::IsOwnerProfile(Profile::FromWebUI(web_ui())); -#else - return true; -#endif -} - -} // namespace options
diff --git a/chrome/browser/ui/webui/options/browser_options_handler.h b/chrome/browser/ui/webui/options/browser_options_handler.h deleted file mode 100644 index 0fccab77..0000000 --- a/chrome/browser/ui/webui/options/browser_options_handler.h +++ /dev/null
@@ -1,464 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_WEBUI_OPTIONS_BROWSER_OPTIONS_HANDLER_H_ -#define CHROME_BROWSER_UI_WEBUI_OPTIONS_BROWSER_OPTIONS_HANDLER_H_ - -#include <memory> -#include <string> -#include <vector> - -#include "base/compiler_specific.h" -#include "base/macros.h" -#include "base/memory/ref_counted.h" -#include "base/memory/weak_ptr.h" -#include "base/scoped_observer.h" -#include "build/build_config.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/profiles/profile_attributes_storage.h" -#include "chrome/browser/ui/webui/options/options_ui.h" -#include "chrome/browser/ui/zoom/chrome_zoom_level_prefs.h" -#include "chrome/common/features.h" -#include "components/policy/core/common/policy_service.h" -#include "components/prefs/pref_change_registrar.h" -#include "components/prefs/pref_member.h" -#include "components/search_engines/template_url_service_observer.h" -#include "components/signin/core/browser/signin_manager_base.h" -#include "components/signin/core/common/signin_pref_names.h" -#include "components/sync/driver/sync_service_observer.h" -#include "content/public/browser/notification_observer.h" -#include "extensions/browser/extension_registry_observer.h" -#include "google_apis/gaia/google_service_auth_error.h" -#include "printing/features/features.h" -#include "ui/base/models/table_model_observer.h" -#include "ui/shell_dialogs/select_file_dialog.h" - -#if defined(OS_CHROMEOS) -#include "chrome/browser/chromeos/settings/cros_settings.h" -#include "chrome/browser/chromeos/system/pointer_device_observer.h" -#include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h" -#include "components/user_manager/user_manager.h" -#else // defined(OS_CHROMEOS) -#include "chrome/browser/shell_integration.h" -#endif // !defined(OS_CHROMEOS) - -class TemplateURLService; - -namespace base { -class Value; -} - -namespace policy { -class PolicyChangeRegistrar; -} - -namespace options { - -// Chrome browser options page UI handler. -class BrowserOptionsHandler - : public OptionsPageUIHandler, - public ProfileAttributesStorage::Observer, - public syncer::SyncServiceObserver, - public SigninManagerBase::Observer, - public ui::SelectFileDialog::Listener, -#if defined(OS_CHROMEOS) - public chromeos::system::PointerDeviceObserver::Observer, - public ArcAppListPrefs::Observer, - public user_manager::UserManager::Observer, -#endif - public TemplateURLServiceObserver, - public extensions::ExtensionRegistryObserver, - public content::NotificationObserver, - public policy::PolicyService::Observer { - public: - BrowserOptionsHandler(); - ~BrowserOptionsHandler() override; - - // OptionsPageUIHandler implementation. - void GetLocalizedValues(base::DictionaryValue* values) override; - void PageLoadStarted() override; - void InitializeHandler() override; - void InitializePage() override; - void RegisterMessages() override; - void Uninitialize() override; - - // syncer::SyncServiceObserver implementation. - void OnStateChanged(syncer::SyncService* sync) override; - - // SigninManagerBase::Observer implementation. - void GoogleSigninSucceeded(const std::string& account_id, - const std::string& username) override; - void GoogleSignedOut(const std::string& account_id, - const std::string& username) override; - - // TemplateURLServiceObserver implementation. - void OnTemplateURLServiceChanged() override; - - // extensions::ExtensionRegistryObserver: - void OnExtensionLoaded(content::BrowserContext* browser_context, - const extensions::Extension* extension) override; - void OnExtensionUnloaded(content::BrowserContext* browser_context, - const extensions::Extension* extension, - extensions::UnloadedExtensionReason reason) override; - - // policy::PolicyService::Observer: - void OnPolicyUpdated(const policy::PolicyNamespace& ns, - const policy::PolicyMap& previous, - const policy::PolicyMap& current) override; -#if defined(OS_CHROMEOS) - static void DisablePolymerPreloadForTesting(); -#endif // defined(OS_CHROMEOS) - - private: - // content::NotificationObserver implementation. - void Observe(int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) override; - - // ProfileAttributesStorage::Observer implementation. - void OnProfileAdded(const base::FilePath& profile_path) override; - void OnProfileWasRemoved(const base::FilePath& profile_path, - const base::string16& profile_name) override; - void OnProfileNameChanged(const base::FilePath& profile_path, - const base::string16& old_profile_name) override; - void OnProfileAvatarChanged(const base::FilePath& profile_path) override; - -#if BUILDFLAG(ENABLE_PRINT_PREVIEW) && !defined(OS_CHROMEOS) - void OnCloudPrintPrefsChanged(); -#endif - - // SelectFileDialog::Listener implementation - void FileSelected(const base::FilePath& path, - int index, - void* params) override; - -#if defined(OS_CHROMEOS) - // PointerDeviceObserver::Observer implementation. - void TouchpadExists(bool exists) override; - void MouseExists(bool exists) override; - - // Will be called when the policy::key::kUserAvatarImage policy changes. - void OnUserImagePolicyChanged(const base::Value* previous_policy, - const base::Value* current_policy); - - // Will be called when the policy::key::kWallpaperImage policy changes. - void OnWallpaperPolicyChanged(const base::Value* previous_policy, - const base::Value* current_policy); - - // Will be called when powerwash dialog is shown. - void OnPowerwashDialogShow(const base::ListValue* args); - - // ArcAppListPrefs::Observer overrides. - void OnAppReadyChanged(const std::string& app_id, bool ready) override; - void OnAppRemoved(const std::string& app_id) override; - void OnAppRegistered(const std::string& app_id, - const ArcAppListPrefs::AppInfo& app_info) override; - - // user_manager::UserManager::Observer overrides. - void OnUserImageChanged(const user_manager::User& user) override; -#endif - - void UpdateSyncState(); - - // Will be called when the kSigninAllowed pref has changed. - void OnSigninAllowedPrefChange(); - - // Sets the search engine at the given index to be default. Called from WebUI. - void SetDefaultSearchEngine(const base::ListValue* args); - - // Returns if the "make Chrome default browser" button should be shown. - bool ShouldShowSetDefaultBrowser(); - - // Returns if profiles list should be shown on settings page. - bool ShouldShowMultiProfilesUserList(); - - // Returns if access to advanced settings should be allowed. - bool ShouldAllowAdvancedSettings(); - -#if !defined(OS_CHROMEOS) - // Gets the current default browser state, and asynchronously reports it to - // the WebUI page. - void UpdateDefaultBrowserState(); - - // Makes this the default browser. Called from WebUI. - void BecomeDefaultBrowser(const base::ListValue* args); - - // Receives the default browser state when the worker is done. - void OnDefaultBrowserWorkerFinished( - shell_integration::DefaultWebClientState state); - - // Updates the UI with the given state for the default browser. - void SetDefaultBrowserUIString(int status_string_id); -#endif // !defined(OS_CHROMEOS) - - // Loads the possible default search engine list and reports it to the WebUI. - void AddTemplateUrlServiceObserver(); - - // Creates a list of dictionaries where each dictionary is of the form: - // profileInfo = { - // name: "Profile Name", - // iconURL: "chrome://path/to/icon/image", - // filePath: "/path/to/profile/data/on/disk", - // isCurrentProfile: false - // }; - std::unique_ptr<base::ListValue> GetProfilesInfoList(); - - // Sends an array of Profile objects to javascript. - void SendProfilesInfo(); - - // Deletes the given profile. Expects one argument: - // 0: profile file path (string) - void DeleteProfile(const base::ListValue* args); - - void ObserveThemeChanged(); - void ThemesReset(const base::ListValue* args); -#if defined(OS_LINUX) && !defined(OS_CHROMEOS) - void ThemesSetNative(const base::ListValue* args); -#endif - -#if defined(OS_CHROMEOS) - void UpdateAccountPicture(); - - // Updates the UI, allowing the user to change the avatar image if |managed| - // is |false| and preventing the user from changing the avatar image if - // |managed| is |true|. - void OnAccountPictureManagedChanged(bool managed); - - // Updates the UI, allowing the user to change the wallpaper if |managed| is - // |false| and preventing the user from changing the wallpaper if |managed| is - // |true|. - void OnWallpaperManagedChanged(bool managed); - - // Updates the UI, allowing the user to change the system time zone if - // kSystemTimezonePolicy is set, and preventing the user from changing the - // system time zone if kSystemTimezonePolicy is not set. - void OnSystemTimezonePolicyChanged(); - - // Updates the UI, preventing the user from changing timezone or timezone - // detection settings if kSystemTimezoneAutomaticDetectionPolicy is set, and - // allowing the user to update these settings if - // kSystemTimezoneAutomaticDetectionPolicy is not set. - void OnSystemTimezoneAutomaticDetectionPolicyChanged(); -#endif - - // Callback for the "selectDownloadLocation" message. This will prompt the - // user for a destination folder using platform-specific APIs. - void HandleSelectDownloadLocation(const base::ListValue* args); - - // Callback for the "autoOpenFileTypesResetToDefault" message. This will - // remove all auto-open file-type settings. - void HandleAutoOpenButton(const base::ListValue* args); - - // Callback for the "defaultFontSizeAction" message. This is called if the - // user changes the default font size. |args| is an array that contains - // one item, the font size as a numeric value. - void HandleDefaultFontSize(const base::ListValue* args); - - // Callback for the "defaultZoomFactorAction" message. This is called if the - // user changes the default zoom factor. |args| is an array that contains - // one item, the zoom factor as a numeric value. - void HandleDefaultZoomFactor(const base::ListValue* args); - - // Callback for the "Use SSL 3.0" checkbox. This is called if the user toggles - // the "Use SSL 3.0" checkbox. - void HandleUseSSL3Checkbox(const base::ListValue* args); - - // Callback for the "Use TLS 1.0" checkbox. This is called if the user toggles - // the "Use TLS 1.0" checkbox. - void HandleUseTLS1Checkbox(const base::ListValue* args); - - // Callback for the "restartBrowser" message. Restores all tabs on restart. - void HandleRestartBrowser(const base::ListValue* args); - - // Callback for "requestProfilesInfo" message. - void HandleRequestProfilesInfo(const base::ListValue* args); - -#if !defined(OS_CHROMEOS) - // Callback for the "showNetworkProxySettings" message. This will invoke - // an appropriate dialog for configuring proxy settings. - void ShowNetworkProxySettings(const base::ListValue* args); -#endif - -#if !defined(USE_NSS_CERTS) - // Callback for the "showManageSSLCertificates" message. This will invoke - // an appropriate certificate management action based on the platform. - void ShowManageSSLCertificates(const base::ListValue* args); -#endif - -#if defined(OS_CHROMEOS) - void ShowCupsPrintDevicesPage(const base::ListValue* args); -#endif // defined(OS_CHROMEOS) - -#if BUILDFLAG(ENABLE_SERVICE_DISCOVERY) - void ShowCloudPrintDevicesPage(const base::ListValue* args); -#endif - -#if BUILDFLAG(ENABLE_PRINT_PREVIEW) - // Register localized values used by Cloud Print - void RegisterCloudPrintValues(base::DictionaryValue* values); -#endif - - // Check if hotword is available. If it is, tell the javascript to show - // the hotword section of the settings page. - void SendHotwordAvailable(); - - // Callback that updates the visibility of the audio history upon completion - // of a call to the server to the get the current value. - void SetHotwordAudioHistorySectionVisible( - const base::string16& audio_history_state, - bool success, - bool logging_enabled); - - // Callback for "requestHotwordAvailable" message. - void HandleRequestHotwordAvailable(const base::ListValue* args); - - // Callback for "launchHotwordAudioVerificationApp" message. - void HandleLaunchHotwordAudioVerificationApp(const base::ListValue* args); - - // Callback for "requestGoogleNowAvailable" message. - void HandleRequestGoogleNowAvailable(const base::ListValue* args); - - // Callback for "launchEasyUnlockSetup" message. - void HandleLaunchEasyUnlockSetup(const base::ListValue* args); - - // Callback for "refreshExtensionControlIndicators" message. - void HandleRefreshExtensionControlIndicators(const base::ListValue* args); - -#if defined(OS_CHROMEOS) - // Opens the wallpaper manager component extension. - void HandleOpenWallpaperManager(const base::ListValue* args); - - // Called when the accessibility checkbox values are changed. - // |args| will contain the checkbox checked state as a string - // ("true" or "false"). - void VirtualKeyboardChangeCallback(const base::ListValue* args); - - // Called when the user confirmed factory reset. Chrome will - // initiate asynchronous file operation and then log out. - void PerformFactoryResetRestart(const base::ListValue* args); - - // Update visibility of Android apps settings section. - void UpdateAndroidSettingsAppState(bool visible); - - // Called to show Android apps settings. - void ShowAndroidAppsSettings(const base::ListValue* args); - - // Called to show apps based on a url for the Play Store. - void ShowPlayStoreApps(const base::ListValue* args); - - // Called to show TalkBack settings. - void ShowAccessibilityTalkBackSettings(const base::ListValue *args); -#endif - - // Setup the visibility for the metrics reporting setting. - void SetupMetricsReportingSettingVisibility(); - - // Update value of predictive network actions UI element. - void SetupNetworkPredictionControl(); - - // Setup the font size selector control. - void SetupFontSizeSelector(); - - // Setup the page zoom selector control. - void SetupPageZoomSelector(); - - // Setup the visibility of the reset button. - void SetupAutoOpenFileTypes(); - - // Setup the proxy settings section UI. - void SetupProxySettingsSection(); - - // Setup the UI specific to managing supervised users. - void SetupManagingSupervisedUsers(); - - // Setup the UI for Easy Unlock. - void SetupEasyUnlock(); - - // Setup the UI for showing which settings are extension controlled. - void SetupExtensionControlledIndicators(); - - // Setup the value and the disabled property for metrics reporting for (except - // Android). - void SetupMetricsReportingCheckbox(); - - // Called when the MetricsReportingEnabled checkbox values are changed. - // |args| will contain the checkbox checked state as a boolean. - void HandleMetricsReportingChange(const base::ListValue* args); - - // Notifies the result of MetricsReportingEnabled change to Javascript layer. - void NotifyUIOfMetricsReportingChange(bool enabled); - - // Calls a Javascript function to set the state of MetricsReporting checkbox. - void SetMetricsReportingCheckbox(bool checked, - bool policy_managed, - bool owner_managed); - -#if defined(OS_CHROMEOS) - // Setup the accessibility features for ChromeOS. - void SetupAccessibilityFeatures(); -#endif - - // Update the Extended Reporting Enabled checkbox based on the current state - // of the opt-in. - void SetupSafeBrowsingExtendedReporting(); - - // Callback for "safeBrowsingExtentedReportingAction" message. This is called - // if the user checks or unchecks the Extended Reporting checkbox. |args| is - // an array that contains one item, the checked state of the checkbox. - void HandleSafeBrowsingExtendedReporting(const base::ListValue* args); - - // Returns a newly created dictionary with a number of properties that - // correspond to the status of sync. - std::unique_ptr<base::DictionaryValue> GetSyncStateDictionary(); - - // Checks whether on Chrome OS the current user is the device owner. Returns - // true on other platforms. - bool IsDeviceOwnerProfile(); - -#if !defined(OS_CHROMEOS) - scoped_refptr<shell_integration::DefaultBrowserWorker> - default_browser_worker_; - BooleanPrefMember default_browser_policy_; -#endif - - bool page_initialized_; - - StringPrefMember homepage_; - - TemplateURLService* template_url_service_; // Weak. - - scoped_refptr<ui::SelectFileDialog> select_folder_dialog_; - - bool cloud_print_mdns_ui_enabled_; - - StringPrefMember auto_open_files_; - - std::unique_ptr<ChromeZoomLevelPrefs::DefaultZoomLevelSubscription> - default_zoom_level_subscription_; - - PrefChangeRegistrar profile_pref_registrar_; -#if defined(OS_CHROMEOS) - std::unique_ptr<policy::PolicyChangeRegistrar> policy_registrar_; - - // Whether factory reset can be performed. - bool enable_factory_reset_; - - PrefChangeRegistrar local_state_pref_change_registrar_; - - std::unique_ptr<chromeos::CrosSettings::ObserverSubscription> - system_timezone_policy_observer_; -#endif - - ScopedObserver<SigninManagerBase, SigninManagerBase::Observer> - signin_observer_; - - // Used to get WeakPtr to self for use on the UI thread. - base::WeakPtrFactory<BrowserOptionsHandler> weak_ptr_factory_; - - DISALLOW_COPY_AND_ASSIGN(BrowserOptionsHandler); -}; - -} // namespace options - -#endif // CHROME_BROWSER_UI_WEBUI_OPTIONS_BROWSER_OPTIONS_HANDLER_H_
diff --git a/chrome/browser/ui/webui/options/certificate_manager_handler.cc b/chrome/browser/ui/webui/options/certificate_manager_handler.cc deleted file mode 100644 index 7edeea61..0000000 --- a/chrome/browser/ui/webui/options/certificate_manager_handler.cc +++ /dev/null
@@ -1,1243 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/webui/options/certificate_manager_handler.h" - -#include <errno.h> -#include <stddef.h> -#include <stdint.h> - -#include <algorithm> -#include <map> -#include <utility> -#include <vector> - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/files/file_util.h" // for FileAccessProvider -#include "base/i18n/string_compare.h" -#include "base/id_map.h" -#include "base/macros.h" -#include "base/memory/ptr_util.h" -#include "base/posix/safe_strerror.h" -#include "base/strings/string_number_conversions.h" -#include "base/strings/utf_string_conversions.h" -#include "base/task_scheduler/post_task.h" -#include "base/task_scheduler/task_traits.h" -#include "base/values.h" -#include "build/build_config.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/certificate_viewer.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/certificate_dialogs.h" -#include "chrome/browser/ui/chrome_select_file_policy.h" -#include "chrome/browser/ui/crypto_module_password_dialog_nss.h" -#include "chrome/browser/ui/webui/certificate_viewer_webui.h" -#include "chrome/grit/generated_resources.h" -#include "components/strings/grit/components_strings.h" -#include "content/public/browser/web_contents.h" -#include "net/base/net_errors.h" -#include "net/cert/x509_certificate.h" -#include "net/der/input.h" -#include "net/der/parser.h" -#include "ui/base/l10n/l10n_util.h" - -#if defined(OS_CHROMEOS) -#include "chrome/browser/chromeos/policy/user_network_configuration_updater.h" -#include "chrome/browser/chromeos/policy/user_network_configuration_updater_factory.h" -#endif - -using base::UTF8ToUTF16; - -namespace { - -static const char kKeyId[] = "id"; -static const char kSubNodesId[] = "subnodes"; -static const char kNameId[] = "name"; -static const char kReadOnlyId[] = "readonly"; -static const char kUntrustedId[] = "untrusted"; -static const char kExtractableId[] = "extractable"; -static const char kErrorId[] = "error"; -static const char kPolicyTrustedId[] = "policy"; - -// Enumeration of different callers of SelectFile. (Start counting at 1 so -// if SelectFile is accidentally called with params=NULL it won't match any.) -enum { - EXPORT_PERSONAL_FILE_SELECTED = 1, - IMPORT_PERSONAL_FILE_SELECTED, - IMPORT_SERVER_FILE_SELECTED, - IMPORT_CA_FILE_SELECTED, -}; - -std::string OrgNameToId(const std::string& org) { - return "org-" + org; -} - -bool CallbackArgsToBool(const base::ListValue* args, int index, bool* result) { - std::string string_value; - if (!args->GetString(index, &string_value)) - return false; - - *result = string_value[0] == 't'; - return true; -} - -struct DictionaryIdComparator { - explicit DictionaryIdComparator(icu::Collator* collator) - : collator_(collator) { - } - - bool operator()(const base::Value& a, const base::Value& b) const { - const base::DictionaryValue* a_dict; - bool a_is_dictionary = a.GetAsDictionary(&a_dict); - DCHECK(a_is_dictionary); - const base::DictionaryValue* b_dict; - bool b_is_dictionary = b.GetAsDictionary(&b_dict); - DCHECK(b_is_dictionary); - base::string16 a_str; - base::string16 b_str; - a_dict->GetString(kNameId, &a_str); - b_dict->GetString(kNameId, &b_str); - if (collator_ == NULL) - return a_str < b_str; - return base::i18n::CompareString16WithCollator(*collator_, a_str, b_str) == - UCOL_LESS; - } - - icu::Collator* collator_; -}; - -std::string NetErrorToString(int net_error) { - switch (net_error) { - // TODO(mattm): handle more cases. - case net::ERR_IMPORT_CA_CERT_NOT_CA: - return l10n_util::GetStringUTF8(IDS_CERT_MANAGER_ERROR_NOT_CA); - case net::ERR_IMPORT_CERT_ALREADY_EXISTS: - return l10n_util::GetStringUTF8( - IDS_CERT_MANAGER_ERROR_CERT_ALREADY_EXISTS); - default: - return l10n_util::GetStringUTF8(IDS_CERT_MANAGER_UNKNOWN_ERROR); - } -} - -// Struct to bind the Equals member function to an object for use in find_if. -struct CertEquals { - explicit CertEquals(const net::X509Certificate* cert) : cert_(cert) {} - bool operator()(const scoped_refptr<net::X509Certificate> cert) const { - return cert_->Equals(cert.get()); - } - const net::X509Certificate* cert_; -}; - -// Determine whether a certificate was stored with web trust by a policy. -bool IsPolicyInstalledWithWebTrust( - const net::CertificateList& web_trust_certs, - net::X509Certificate* cert) { - return std::find_if(web_trust_certs.begin(), web_trust_certs.end(), - CertEquals(cert)) != web_trust_certs.end(); -} - -#if defined(OS_CHROMEOS) -void ShowCertificateViewerModalDialog(content::WebContents* web_contents, - gfx::NativeWindow parent, - net::X509Certificate* cert) { - CertificateViewerModalDialog* dialog = new CertificateViewerModalDialog(cert); - dialog->Show(web_contents, parent); -} -#endif - -// Determine if |data| could be a PFX Protocol Data Unit. -// This only does the minimum parsing necessary to distinguish a PFX file from a -// DER encoded Certificate. -// -// From RFC 7292 section 4: -// PFX ::= SEQUENCE { -// version INTEGER {v3(3)}(v3,...), -// authSafe ContentInfo, -// macData MacData OPTIONAL -// } -// From RFC 5280 section 4.1: -// Certificate ::= SEQUENCE { -// tbsCertificate TBSCertificate, -// signatureAlgorithm AlgorithmIdentifier, -// signatureValue BIT STRING } -// -// Certificate must be DER encoded, while PFX may be BER encoded. -// Therefore PFX can be distingushed by checking if the file starts with an -// indefinite SEQUENCE, or a definite SEQUENCE { INTEGER, ... }. -bool CouldBePFX(const std::string& data) { - if (data.size() < 4) - return false; - - // Indefinite length SEQUENCE. - if (data[0] == 0x30 && static_cast<uint8_t>(data[1]) == 0x80) - return true; - - // If the SEQUENCE is definite length, it can be parsed through the version - // tag using DER parser, since INTEGER must be definite length, even in BER. - net::der::Parser parser((net::der::Input(&data))); - net::der::Parser sequence_parser; - if (!parser.ReadSequence(&sequence_parser)) - return false; - if (!sequence_parser.SkipTag(net::der::kInteger)) - return false; - return true; -} - -} // namespace - -namespace options { - -/////////////////////////////////////////////////////////////////////////////// -// CertIdMap - -class CertIdMap { - public: - CertIdMap() {} - ~CertIdMap() {} - - std::string CertToId(net::X509Certificate* cert); - net::X509Certificate* IdToCert(const std::string& id); - net::X509Certificate* CallbackArgsToCert(const base::ListValue* args); - - private: - typedef std::map<net::X509Certificate*, int32_t> CertMap; - - // Creates an ID for cert and looks up the cert for an ID. - IDMap<net::X509Certificate*> id_map_; - - // Finds the ID for a cert. - CertMap cert_map_; - - DISALLOW_COPY_AND_ASSIGN(CertIdMap); -}; - -std::string CertIdMap::CertToId(net::X509Certificate* cert) { - CertMap::const_iterator iter = cert_map_.find(cert); - if (iter != cert_map_.end()) - return base::IntToString(iter->second); - - int32_t new_id = id_map_.Add(cert); - cert_map_[cert] = new_id; - return base::IntToString(new_id); -} - -net::X509Certificate* CertIdMap::IdToCert(const std::string& id) { - int32_t cert_id = 0; - if (!base::StringToInt(id, &cert_id)) - return NULL; - - return id_map_.Lookup(cert_id); -} - -net::X509Certificate* CertIdMap::CallbackArgsToCert( - const base::ListValue* args) { - std::string node_id; - if (!args->GetString(0, &node_id)) - return NULL; - - net::X509Certificate* cert = IdToCert(node_id); - if (!cert) { - NOTREACHED(); - return NULL; - } - - return cert; -} - -/////////////////////////////////////////////////////////////////////////////// -// FileAccessProvider - -// TODO(mattm): Move to some shared location? -class FileAccessProvider - : public base::RefCountedThreadSafe<FileAccessProvider> { - public: - // The first parameter is 0 on success or errno on failure. The second - // parameter is read result. - typedef base::Callback<void(const int*, const std::string*)> ReadCallback; - - // The first parameter is 0 on success or errno on failure. The second - // parameter is the number of bytes written on success. - typedef base::Callback<void(const int*, const int*)> WriteCallback; - - base::CancelableTaskTracker::TaskId StartRead( - const base::FilePath& path, - const ReadCallback& callback, - base::CancelableTaskTracker* tracker); - base::CancelableTaskTracker::TaskId StartWrite( - const base::FilePath& path, - const std::string& data, - const WriteCallback& callback, - base::CancelableTaskTracker* tracker); - - private: - friend class base::RefCountedThreadSafe<FileAccessProvider>; - virtual ~FileAccessProvider() {} - - // Reads file at |path|. |saved_errno| is 0 on success or errno on failure. - // When success, |data| has file content. - void DoRead(const base::FilePath& path, - int* saved_errno, - std::string* data); - // Writes data to file at |path|. |saved_errno| is 0 on success or errno on - // failure. When success, |bytes_written| has number of bytes written. - void DoWrite(const base::FilePath& path, - const std::string& data, - int* saved_errno, - int* bytes_written); -}; - -base::CancelableTaskTracker::TaskId FileAccessProvider::StartRead( - const base::FilePath& path, - const ReadCallback& callback, - base::CancelableTaskTracker* tracker) { - // Owned by reply callback posted below. - int* saved_errno = new int(0); - std::string* data = new std::string(); - - // Post task to a background sequence to read file. - auto task_runner = base::CreateTaskRunnerWithTraits( - {base::MayBlock(), base::TaskPriority::BACKGROUND}); - return tracker->PostTaskAndReply( - task_runner.get(), FROM_HERE, - base::Bind(&FileAccessProvider::DoRead, this, path, saved_errno, data), - base::Bind(callback, base::Owned(saved_errno), base::Owned(data))); -} - -base::CancelableTaskTracker::TaskId FileAccessProvider::StartWrite( - const base::FilePath& path, - const std::string& data, - const WriteCallback& callback, - base::CancelableTaskTracker* tracker) { - // Owned by reply callback posted below. - int* saved_errno = new int(0); - int* bytes_written = new int(0); - - // This task blocks shutdown because it saves critical user data. - auto task_runner = base::CreateTaskRunnerWithTraits( - {base::MayBlock(), base::TaskPriority::BACKGROUND, - base::TaskShutdownBehavior::BLOCK_SHUTDOWN}); - return tracker->PostTaskAndReply( - task_runner.get(), FROM_HERE, - base::Bind(&FileAccessProvider::DoWrite, this, path, data, saved_errno, - bytes_written), - base::Bind(callback, base::Owned(saved_errno), - base::Owned(bytes_written))); -} - -void FileAccessProvider::DoRead(const base::FilePath& path, - int* saved_errno, - std::string* data) { - bool success = base::ReadFileToString(path, data); - *saved_errno = success ? 0 : errno; -} - -void FileAccessProvider::DoWrite(const base::FilePath& path, - const std::string& data, - int* saved_errno, - int* bytes_written) { - *bytes_written = base::WriteFile(path, data.data(), data.size()); - *saved_errno = *bytes_written >= 0 ? 0 : errno; -} - -/////////////////////////////////////////////////////////////////////////////// -// CertificateManagerHandler - -CertificateManagerHandler::CertificateManagerHandler( - bool show_certs_in_modal_dialog) - : show_certs_in_modal_dialog_(show_certs_in_modal_dialog), - requested_certificate_manager_model_(false), - use_hardware_backed_(false), - file_access_provider_(new FileAccessProvider()), - cert_id_map_(new CertIdMap), - weak_ptr_factory_(this) {} - -CertificateManagerHandler::~CertificateManagerHandler() { -} - -void CertificateManagerHandler::GetLocalizedValues( - base::DictionaryValue* localized_strings) { - DCHECK(localized_strings); - - RegisterTitle(localized_strings, "certificateManagerPage", - IDS_CERTIFICATE_MANAGER_TITLE); - - // Tabs. - localized_strings->SetString("personalCertsTabTitle", - l10n_util::GetStringUTF16(IDS_CERT_MANAGER_PERSONAL_CERTS_TAB_LABEL)); - localized_strings->SetString("serverCertsTabTitle", - l10n_util::GetStringUTF16(IDS_CERT_MANAGER_SERVER_CERTS_TAB_LABEL)); - localized_strings->SetString("caCertsTabTitle", - l10n_util::GetStringUTF16(IDS_CERT_MANAGER_CERT_AUTHORITIES_TAB_LABEL)); - localized_strings->SetString("otherCertsTabTitle", - l10n_util::GetStringUTF16(IDS_CERT_MANAGER_OTHER_TAB_LABEL)); - - // Tab descriptions. - localized_strings->SetString("personalCertsTabDescription", - l10n_util::GetStringUTF16(IDS_CERT_MANAGER_USER_TREE_DESCRIPTION)); - localized_strings->SetString("serverCertsTabDescription", - l10n_util::GetStringUTF16(IDS_CERT_MANAGER_SERVER_TREE_DESCRIPTION)); - localized_strings->SetString("caCertsTabDescription", - l10n_util::GetStringUTF16(IDS_CERT_MANAGER_AUTHORITIES_TREE_DESCRIPTION)); - localized_strings->SetString("otherCertsTabDescription", - l10n_util::GetStringUTF16(IDS_CERT_MANAGER_OTHER_TREE_DESCRIPTION)); - - // Buttons. - localized_strings->SetString("view_certificate", - l10n_util::GetStringUTF16(IDS_CERT_MANAGER_VIEW_CERT_BUTTON)); - localized_strings->SetString("import_certificate", - l10n_util::GetStringUTF16(IDS_CERT_MANAGER_IMPORT_BUTTON)); - localized_strings->SetString("export_certificate", - l10n_util::GetStringUTF16(IDS_CERT_MANAGER_EXPORT_BUTTON)); - localized_strings->SetString("edit_certificate", - l10n_util::GetStringUTF16(IDS_CERT_MANAGER_EDIT_BUTTON)); - localized_strings->SetString("delete_certificate", - l10n_util::GetStringUTF16(IDS_CERT_MANAGER_DELETE_BUTTON)); - - // Certificate Delete overlay strings. - localized_strings->SetString("personalCertsTabDeleteConfirm", - l10n_util::GetStringUTF16(IDS_CERT_MANAGER_DELETE_USER_FORMAT)); - localized_strings->SetString("personalCertsTabDeleteImpact", - l10n_util::GetStringUTF16(IDS_CERT_MANAGER_DELETE_USER_DESCRIPTION)); - localized_strings->SetString("serverCertsTabDeleteConfirm", - l10n_util::GetStringUTF16(IDS_CERT_MANAGER_DELETE_SERVER_FORMAT)); - localized_strings->SetString("serverCertsTabDeleteImpact", - l10n_util::GetStringUTF16(IDS_CERT_MANAGER_DELETE_SERVER_DESCRIPTION)); - localized_strings->SetString("caCertsTabDeleteConfirm", - l10n_util::GetStringUTF16(IDS_CERT_MANAGER_DELETE_CA_FORMAT)); - localized_strings->SetString("caCertsTabDeleteImpact", - l10n_util::GetStringUTF16(IDS_CERT_MANAGER_DELETE_CA_DESCRIPTION)); - localized_strings->SetString("otherCertsTabDeleteConfirm", - l10n_util::GetStringUTF16(IDS_CERT_MANAGER_DELETE_OTHER_FORMAT)); - localized_strings->SetString("otherCertsTabDeleteImpact", std::string()); - - // Certificate Restore overlay strings. - localized_strings->SetString("certificateRestorePasswordDescription", - l10n_util::GetStringUTF16(IDS_CERT_MANAGER_RESTORE_PASSWORD_DESC)); - localized_strings->SetString("certificatePasswordLabel", - l10n_util::GetStringUTF16(IDS_CERT_MANAGER_PASSWORD_LABEL)); - - // Personal Certificate Export overlay strings. - localized_strings->SetString("certificateExportPasswordDescription", - l10n_util::GetStringUTF16(IDS_CERT_MANAGER_EXPORT_PASSWORD_DESC)); - localized_strings->SetString("certificateExportPasswordHelp", - l10n_util::GetStringUTF16(IDS_CERT_MANAGER_EXPORT_PASSWORD_HELP)); - localized_strings->SetString("certificateConfirmPasswordLabel", - l10n_util::GetStringUTF16(IDS_CERT_MANAGER_CONFIRM_PASSWORD_LABEL)); - - // Edit CA Trust & Import CA overlay strings. - localized_strings->SetString("certificateEditCaTitle", - l10n_util::GetStringUTF16(IDS_CERT_MANAGER_EDIT_CA_TITLE)); - localized_strings->SetString("certificateEditTrustLabel", - l10n_util::GetStringUTF16(IDS_CERT_MANAGER_EDIT_TRUST_LABEL)); - localized_strings->SetString("certificateEditCaTrustDescriptionFormat", - l10n_util::GetStringUTF16( - IDS_CERT_MANAGER_EDIT_CA_TRUST_DESCRIPTION_FORMAT)); - localized_strings->SetString("certificateImportCaDescriptionFormat", - l10n_util::GetStringUTF16( - IDS_CERT_MANAGER_IMPORT_CA_DESCRIPTION_FORMAT)); - localized_strings->SetString("certificateCaTrustSSLLabel", - l10n_util::GetStringUTF16(IDS_CERT_MANAGER_EDIT_CA_TRUST_SSL_LABEL)); - localized_strings->SetString("certificateCaTrustEmailLabel", - l10n_util::GetStringUTF16(IDS_CERT_MANAGER_EDIT_CA_TRUST_EMAIL_LABEL)); - localized_strings->SetString("certificateCaTrustObjSignLabel", - l10n_util::GetStringUTF16(IDS_CERT_MANAGER_EDIT_CA_TRUST_OBJSIGN_LABEL)); - localized_strings->SetString("certificateImportErrorFormat", - l10n_util::GetStringUTF16(IDS_CERT_MANAGER_IMPORT_ERROR_FORMAT)); - - // Badges next to certificates - localized_strings->SetString("badgeCertUntrusted", - l10n_util::GetStringUTF16(IDS_CERT_MANAGER_UNTRUSTED)); - localized_strings->SetString("certPolicyInstalled", - l10n_util::GetStringUTF16(IDS_CERT_MANAGER_POLICY_INSTALLED)); - -#if defined(OS_CHROMEOS) - localized_strings->SetString("importAndBindCertificate", - l10n_util::GetStringUTF16(IDS_CERT_MANAGER_IMPORT_AND_BIND_BUTTON)); -#endif // defined(OS_CHROMEOS) -} - -void CertificateManagerHandler::RegisterMessages() { - web_ui()->RegisterMessageCallback( - "viewCertificate", - base::Bind(&CertificateManagerHandler::View, base::Unretained(this))); - - web_ui()->RegisterMessageCallback( - "getCaCertificateTrust", - base::Bind(&CertificateManagerHandler::GetCATrust, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "editCaCertificateTrust", - base::Bind(&CertificateManagerHandler::EditCATrust, - base::Unretained(this))); - - web_ui()->RegisterMessageCallback( - "editServerCertificate", - base::Bind(&CertificateManagerHandler::EditServer, - base::Unretained(this))); - - web_ui()->RegisterMessageCallback( - "cancelImportExportCertificate", - base::Bind(&CertificateManagerHandler::CancelImportExportProcess, - base::Unretained(this))); - - web_ui()->RegisterMessageCallback( - "exportPersonalCertificate", - base::Bind(&CertificateManagerHandler::ExportPersonal, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "exportAllPersonalCertificates", - base::Bind(&CertificateManagerHandler::ExportAllPersonal, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "exportPersonalCertificatePasswordSelected", - base::Bind(&CertificateManagerHandler::ExportPersonalPasswordSelected, - base::Unretained(this))); - - web_ui()->RegisterMessageCallback( - "importPersonalCertificate", - base::Bind(&CertificateManagerHandler::StartImportPersonal, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "importPersonalCertificatePasswordSelected", - base::Bind(&CertificateManagerHandler::ImportPersonalPasswordSelected, - base::Unretained(this))); - - web_ui()->RegisterMessageCallback( - "importCaCertificate", - base::Bind(&CertificateManagerHandler::ImportCA, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "importCaCertificateTrustSelected", - base::Bind(&CertificateManagerHandler::ImportCATrustSelected, - base::Unretained(this))); - - web_ui()->RegisterMessageCallback( - "importServerCertificate", - base::Bind(&CertificateManagerHandler::ImportServer, - base::Unretained(this))); - - web_ui()->RegisterMessageCallback( - "exportCertificate", - base::Bind(&CertificateManagerHandler::Export, - base::Unretained(this))); - - web_ui()->RegisterMessageCallback( - "deleteCertificate", - base::Bind(&CertificateManagerHandler::Delete, - base::Unretained(this))); - - web_ui()->RegisterMessageCallback( - "populateCertificateManager", - base::Bind(&CertificateManagerHandler::Populate, - base::Unretained(this))); -} - -void CertificateManagerHandler::CertificatesRefreshed() { - net::CertificateList web_trusted_certs; -#if defined(OS_CHROMEOS) - policy::UserNetworkConfigurationUpdater* service = - policy::UserNetworkConfigurationUpdaterFactory::GetForProfile( - Profile::FromWebUI(web_ui())); - if (service) - service->GetWebTrustedCertificates(&web_trusted_certs); -#endif - PopulateTree("personalCertsTab", net::USER_CERT, web_trusted_certs); - PopulateTree("serverCertsTab", net::SERVER_CERT, web_trusted_certs); - PopulateTree("caCertsTab", net::CA_CERT, web_trusted_certs); - PopulateTree("otherCertsTab", net::OTHER_CERT, web_trusted_certs); -} - -void CertificateManagerHandler::FileSelected(const base::FilePath& path, - int index, - void* params) { - switch (reinterpret_cast<intptr_t>(params)) { - case EXPORT_PERSONAL_FILE_SELECTED: - ExportPersonalFileSelected(path); - break; - case IMPORT_PERSONAL_FILE_SELECTED: - ImportPersonalFileSelected(path); - break; - case IMPORT_SERVER_FILE_SELECTED: - ImportServerFileSelected(path); - break; - case IMPORT_CA_FILE_SELECTED: - ImportCAFileSelected(path); - break; - default: - NOTREACHED(); - } -} - -void CertificateManagerHandler::FileSelectionCanceled(void* params) { - switch (reinterpret_cast<intptr_t>(params)) { - case EXPORT_PERSONAL_FILE_SELECTED: - case IMPORT_PERSONAL_FILE_SELECTED: - case IMPORT_SERVER_FILE_SELECTED: - case IMPORT_CA_FILE_SELECTED: - ImportExportCleanup(); - break; - default: - NOTREACHED(); - } -} - -void CertificateManagerHandler::View(const base::ListValue* args) { - net::X509Certificate* cert = cert_id_map_->CallbackArgsToCert(args); - if (!cert) - return; -#if defined(OS_CHROMEOS) - if (show_certs_in_modal_dialog_) { - ShowCertificateViewerModalDialog(web_ui()->GetWebContents(), - GetParentWindow(), - cert); - return; - } -#endif - ShowCertificateViewer(web_ui()->GetWebContents(), GetParentWindow(), cert); -} - -void CertificateManagerHandler::GetCATrust(const base::ListValue* args) { - net::X509Certificate* cert = cert_id_map_->CallbackArgsToCert(args); - if (!cert) { - web_ui()->CallJavascriptFunctionUnsafe( - "CertificateEditCaTrustOverlay.dismiss"); - return; - } - - net::NSSCertDatabase::TrustBits trust_bits = - certificate_manager_model_->cert_db()->GetCertTrust(cert, net::CA_CERT); - base::Value ssl_value( - static_cast<bool>(trust_bits & net::NSSCertDatabase::TRUSTED_SSL)); - base::Value email_value( - static_cast<bool>(trust_bits & net::NSSCertDatabase::TRUSTED_EMAIL)); - base::Value obj_sign_value( - static_cast<bool>(trust_bits & net::NSSCertDatabase::TRUSTED_OBJ_SIGN)); - web_ui()->CallJavascriptFunctionUnsafe( - "CertificateEditCaTrustOverlay.populateTrust", ssl_value, email_value, - obj_sign_value); -} - -void CertificateManagerHandler::EditCATrust(const base::ListValue* args) { - net::X509Certificate* cert = cert_id_map_->CallbackArgsToCert(args); - bool fail = !cert; - bool trust_ssl = false; - bool trust_email = false; - bool trust_obj_sign = false; - fail |= !CallbackArgsToBool(args, 1, &trust_ssl); - fail |= !CallbackArgsToBool(args, 2, &trust_email); - fail |= !CallbackArgsToBool(args, 3, &trust_obj_sign); - if (fail) { - LOG(ERROR) << "EditCATrust args fail"; - web_ui()->CallJavascriptFunctionUnsafe( - "CertificateEditCaTrustOverlay.dismiss"); - return; - } - - bool result = certificate_manager_model_->SetCertTrust( - cert, - net::CA_CERT, - trust_ssl * net::NSSCertDatabase::TRUSTED_SSL + - trust_email * net::NSSCertDatabase::TRUSTED_EMAIL + - trust_obj_sign * net::NSSCertDatabase::TRUSTED_OBJ_SIGN); - web_ui()->CallJavascriptFunctionUnsafe( - "CertificateEditCaTrustOverlay.dismiss"); - if (!result) { - // TODO(mattm): better error messages? - ShowError( - l10n_util::GetStringUTF8(IDS_CERT_MANAGER_SET_TRUST_ERROR_TITLE), - l10n_util::GetStringUTF8(IDS_CERT_MANAGER_UNKNOWN_ERROR)); - } -} - -void CertificateManagerHandler::EditServer(const base::ListValue* args) { - NOTIMPLEMENTED(); -} - -void CertificateManagerHandler::ExportPersonal(const base::ListValue* args) { - net::X509Certificate* cert = cert_id_map_->CallbackArgsToCert(args); - if (!cert) - return; - - selected_cert_list_.push_back(cert); - - ui::SelectFileDialog::FileTypeInfo file_type_info; - file_type_info.extensions.resize(1); - file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("p12")); - file_type_info.extension_description_overrides.push_back( - l10n_util::GetStringUTF16(IDS_CERT_MANAGER_PKCS12_FILES)); - file_type_info.include_all_files = true; - select_file_dialog_ = ui::SelectFileDialog::Create( - this, new ChromeSelectFilePolicy(web_ui()->GetWebContents())); - select_file_dialog_->SelectFile( - ui::SelectFileDialog::SELECT_SAVEAS_FILE, base::string16(), - base::FilePath(), &file_type_info, 1, FILE_PATH_LITERAL("p12"), - GetParentWindow(), - reinterpret_cast<void*>(EXPORT_PERSONAL_FILE_SELECTED)); -} - -void CertificateManagerHandler::ExportAllPersonal(const base::ListValue* args) { - NOTIMPLEMENTED(); -} - -void CertificateManagerHandler::ExportPersonalFileSelected( - const base::FilePath& path) { - file_path_ = path; - web_ui()->CallJavascriptFunctionUnsafe( - "CertificateManager.exportPersonalAskPassword"); -} - -void CertificateManagerHandler::ExportPersonalPasswordSelected( - const base::ListValue* args) { - if (!args->GetString(0, &password_)) { - web_ui()->CallJavascriptFunctionUnsafe("CertificateRestoreOverlay.dismiss"); - ImportExportCleanup(); - return; - } - - // Currently, we don't support exporting more than one at a time. If we do, - // this would need to either change this to use UnlockSlotsIfNecessary or - // change UnlockCertSlotIfNecessary to take a CertificateList. - DCHECK_EQ(selected_cert_list_.size(), 1U); - - // TODO(mattm): do something smarter about non-extractable keys - chrome::UnlockCertSlotIfNecessary( - selected_cert_list_[0].get(), - chrome::kCryptoModulePasswordCertExport, - net::HostPortPair(), // unused. - GetParentWindow(), - base::Bind(&CertificateManagerHandler::ExportPersonalSlotsUnlocked, - base::Unretained(this))); -} - -void CertificateManagerHandler::ExportPersonalSlotsUnlocked() { - std::string output; - int num_exported = certificate_manager_model_->cert_db()->ExportToPKCS12( - selected_cert_list_, - password_, - &output); - if (!num_exported) { - web_ui()->CallJavascriptFunctionUnsafe("CertificateRestoreOverlay.dismiss"); - ShowError( - l10n_util::GetStringUTF8(IDS_CERT_MANAGER_PKCS12_EXPORT_ERROR_TITLE), - l10n_util::GetStringUTF8(IDS_CERT_MANAGER_UNKNOWN_ERROR)); - ImportExportCleanup(); - return; - } - file_access_provider_->StartWrite( - file_path_, - output, - base::Bind(&CertificateManagerHandler::ExportPersonalFileWritten, - base::Unretained(this)), - &tracker_); -} - -void CertificateManagerHandler::ExportPersonalFileWritten( - const int* write_errno, const int* bytes_written) { - web_ui()->CallJavascriptFunctionUnsafe("CertificateRestoreOverlay.dismiss"); - ImportExportCleanup(); - if (*write_errno) { - ShowError( - l10n_util::GetStringUTF8(IDS_CERT_MANAGER_PKCS12_EXPORT_ERROR_TITLE), - l10n_util::GetStringFUTF8(IDS_CERT_MANAGER_WRITE_ERROR_FORMAT, - UTF8ToUTF16( - base::safe_strerror(*write_errno)))); - } -} - -void CertificateManagerHandler::StartImportPersonal( - const base::ListValue* args) { - ui::SelectFileDialog::FileTypeInfo file_type_info; - if (!args->GetBoolean(0, &use_hardware_backed_)) { - // Unable to retrieve the hardware backed attribute from the args, - // so bail. - web_ui()->CallJavascriptFunctionUnsafe("CertificateRestoreOverlay.dismiss"); - ImportExportCleanup(); - return; - } - file_type_info.extensions.resize(1); - file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("p12")); - file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("pfx")); - file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("crt")); - file_type_info.extension_description_overrides.push_back( - l10n_util::GetStringUTF16(IDS_CERT_USAGE_SSL_CLIENT)); - file_type_info.include_all_files = true; - select_file_dialog_ = ui::SelectFileDialog::Create( - this, new ChromeSelectFilePolicy(web_ui()->GetWebContents())); - select_file_dialog_->SelectFile( - ui::SelectFileDialog::SELECT_OPEN_FILE, base::string16(), - base::FilePath(), &file_type_info, 1, FILE_PATH_LITERAL("p12"), - GetParentWindow(), - reinterpret_cast<void*>(IMPORT_PERSONAL_FILE_SELECTED)); -} - -void CertificateManagerHandler::ImportPersonalFileSelected( - const base::FilePath& path) { - file_access_provider_->StartRead( - path, base::Bind(&CertificateManagerHandler::ImportPersonalFileRead, - base::Unretained(this)), - &tracker_); -} - -void CertificateManagerHandler::ImportPersonalFileRead( - const int* read_errno, const std::string* data) { - if (*read_errno) { - ImportExportCleanup(); - web_ui()->CallJavascriptFunctionUnsafe("CertificateRestoreOverlay.dismiss"); - ShowError( - l10n_util::GetStringUTF8(IDS_CERT_MANAGER_IMPORT_ERROR_TITLE), - l10n_util::GetStringFUTF8(IDS_CERT_MANAGER_READ_ERROR_FORMAT, - UTF8ToUTF16( - base::safe_strerror(*read_errno)))); - return; - } - - file_data_ = *data; - - if (CouldBePFX(file_data_)) { - web_ui()->CallJavascriptFunctionUnsafe( - "CertificateManager.importPersonalAskPassword"); - return; - } - - // Non .p12/.pfx files are assumed to be single/chain certificates without - // private key data. The default extension according to spec is '.crt', - // however other extensions are also used in some places to represent these - // certificates. - int result = certificate_manager_model_->ImportUserCert(file_data_); - ImportExportCleanup(); - web_ui()->CallJavascriptFunctionUnsafe("CertificateRestoreOverlay.dismiss"); - int string_id; - switch (result) { - case net::OK: - return; - case net::ERR_NO_PRIVATE_KEY_FOR_CERT: - string_id = IDS_CERT_MANAGER_IMPORT_MISSING_KEY; - break; - case net::ERR_CERT_INVALID: - string_id = IDS_CERT_MANAGER_IMPORT_INVALID_FILE; - break; - default: - string_id = IDS_CERT_MANAGER_UNKNOWN_ERROR; - break; - } - ShowError( - l10n_util::GetStringUTF8(IDS_CERT_MANAGER_IMPORT_ERROR_TITLE), - l10n_util::GetStringUTF8(string_id)); -} - -void CertificateManagerHandler::ImportPersonalPasswordSelected( - const base::ListValue* args) { - if (!args->GetString(0, &password_)) { - web_ui()->CallJavascriptFunctionUnsafe("CertificateRestoreOverlay.dismiss"); - ImportExportCleanup(); - return; - } - - if (use_hardware_backed_) { - slot_ = certificate_manager_model_->cert_db()->GetPrivateSlot(); - } else { - slot_ = certificate_manager_model_->cert_db()->GetPublicSlot(); - } - - std::vector<crypto::ScopedPK11Slot> modules; - modules.push_back(crypto::ScopedPK11Slot(PK11_ReferenceSlot(slot_.get()))); - chrome::UnlockSlotsIfNecessary( - std::move(modules), chrome::kCryptoModulePasswordCertImport, - net::HostPortPair(), // unused. - GetParentWindow(), - base::Bind(&CertificateManagerHandler::ImportPersonalSlotUnlocked, - base::Unretained(this))); -} - -void CertificateManagerHandler::ImportPersonalSlotUnlocked() { - // Determine if the private key should be unextractable after the import. - // We do this by checking the value of |use_hardware_backed_| which is set - // to true if importing into a hardware module. Currently, this only happens - // for Chrome OS when the "Import and Bind" option is chosen. - bool is_extractable = !use_hardware_backed_; - int result = certificate_manager_model_->ImportFromPKCS12( - slot_.get(), file_data_, password_, is_extractable); - ImportExportCleanup(); - web_ui()->CallJavascriptFunctionUnsafe("CertificateRestoreOverlay.dismiss"); - int string_id; - switch (result) { - case net::OK: - return; - case net::ERR_PKCS12_IMPORT_BAD_PASSWORD: - // TODO(mattm): if the error was a bad password, we should reshow the - // password dialog after the user dismisses the error dialog. - string_id = IDS_CERT_MANAGER_BAD_PASSWORD; - break; - case net::ERR_PKCS12_IMPORT_INVALID_MAC: - string_id = IDS_CERT_MANAGER_IMPORT_INVALID_MAC; - break; - case net::ERR_PKCS12_IMPORT_INVALID_FILE: - string_id = IDS_CERT_MANAGER_IMPORT_INVALID_FILE; - break; - case net::ERR_PKCS12_IMPORT_UNSUPPORTED: - string_id = IDS_CERT_MANAGER_IMPORT_UNSUPPORTED; - break; - default: - string_id = IDS_CERT_MANAGER_UNKNOWN_ERROR; - break; - } - ShowError( - l10n_util::GetStringUTF8(IDS_CERT_MANAGER_IMPORT_ERROR_TITLE), - l10n_util::GetStringUTF8(string_id)); -} - -void CertificateManagerHandler::CancelImportExportProcess( - const base::ListValue* args) { - ImportExportCleanup(); -} - -void CertificateManagerHandler::ImportExportCleanup() { - file_path_.clear(); - password_.clear(); - file_data_.clear(); - use_hardware_backed_ = false; - selected_cert_list_.clear(); - slot_.reset(); - tracker_.TryCancelAll(); - - // There may be pending file dialogs, we need to tell them that we've gone - // away so they don't try and call back to us. - if (select_file_dialog_.get()) - select_file_dialog_->ListenerDestroyed(); - select_file_dialog_ = NULL; -} - -void CertificateManagerHandler::ImportServer(const base::ListValue* args) { - select_file_dialog_ = ui::SelectFileDialog::Create( - this, new ChromeSelectFilePolicy(web_ui()->GetWebContents())); - ShowCertSelectFileDialog( - select_file_dialog_.get(), - ui::SelectFileDialog::SELECT_OPEN_FILE, - base::FilePath(), - GetParentWindow(), - reinterpret_cast<void*>(IMPORT_SERVER_FILE_SELECTED)); -} - -void CertificateManagerHandler::ImportServerFileSelected( - const base::FilePath& path) { - file_access_provider_->StartRead( - path, base::Bind(&CertificateManagerHandler::ImportServerFileRead, - base::Unretained(this)), - &tracker_); -} - -void CertificateManagerHandler::ImportServerFileRead(const int* read_errno, - const std::string* data) { - if (*read_errno) { - ImportExportCleanup(); - ShowError( - l10n_util::GetStringUTF8(IDS_CERT_MANAGER_SERVER_IMPORT_ERROR_TITLE), - l10n_util::GetStringFUTF8(IDS_CERT_MANAGER_READ_ERROR_FORMAT, - UTF8ToUTF16( - base::safe_strerror(*read_errno)))); - return; - } - - selected_cert_list_ = net::X509Certificate::CreateCertificateListFromBytes( - data->data(), data->size(), net::X509Certificate::FORMAT_AUTO); - if (selected_cert_list_.empty()) { - ImportExportCleanup(); - ShowError( - l10n_util::GetStringUTF8(IDS_CERT_MANAGER_SERVER_IMPORT_ERROR_TITLE), - l10n_util::GetStringUTF8(IDS_CERT_MANAGER_CERT_PARSE_ERROR)); - return; - } - - net::NSSCertDatabase::ImportCertFailureList not_imported; - // TODO(mattm): Add UI for trust. http://crbug.com/76274 - bool result = certificate_manager_model_->ImportServerCert( - selected_cert_list_, - net::NSSCertDatabase::TRUST_DEFAULT, - ¬_imported); - if (!result) { - ShowError( - l10n_util::GetStringUTF8(IDS_CERT_MANAGER_SERVER_IMPORT_ERROR_TITLE), - l10n_util::GetStringUTF8(IDS_CERT_MANAGER_UNKNOWN_ERROR)); - } else if (!not_imported.empty()) { - ShowImportErrors( - l10n_util::GetStringUTF8(IDS_CERT_MANAGER_SERVER_IMPORT_ERROR_TITLE), - not_imported); - } - ImportExportCleanup(); -} - -void CertificateManagerHandler::ImportCA(const base::ListValue* args) { - select_file_dialog_ = ui::SelectFileDialog::Create( - this, new ChromeSelectFilePolicy(web_ui()->GetWebContents())); - ShowCertSelectFileDialog(select_file_dialog_.get(), - ui::SelectFileDialog::SELECT_OPEN_FILE, - base::FilePath(), - GetParentWindow(), - reinterpret_cast<void*>(IMPORT_CA_FILE_SELECTED)); -} - -void CertificateManagerHandler::ImportCAFileSelected( - const base::FilePath& path) { - file_access_provider_->StartRead( - path, base::Bind(&CertificateManagerHandler::ImportCAFileRead, - base::Unretained(this)), - &tracker_); -} - -void CertificateManagerHandler::ImportCAFileRead(const int* read_errno, - const std::string* data) { - if (*read_errno) { - ImportExportCleanup(); - ShowError( - l10n_util::GetStringUTF8(IDS_CERT_MANAGER_CA_IMPORT_ERROR_TITLE), - l10n_util::GetStringFUTF8(IDS_CERT_MANAGER_READ_ERROR_FORMAT, - UTF8ToUTF16( - base::safe_strerror(*read_errno)))); - return; - } - - selected_cert_list_ = net::X509Certificate::CreateCertificateListFromBytes( - data->data(), data->size(), net::X509Certificate::FORMAT_AUTO); - if (selected_cert_list_.empty()) { - ImportExportCleanup(); - ShowError( - l10n_util::GetStringUTF8(IDS_CERT_MANAGER_CA_IMPORT_ERROR_TITLE), - l10n_util::GetStringUTF8(IDS_CERT_MANAGER_CERT_PARSE_ERROR)); - return; - } - - scoped_refptr<net::X509Certificate> root_cert = - certificate_manager_model_->cert_db()->FindRootInList( - selected_cert_list_); - - // TODO(mattm): check here if root_cert is not a CA cert and show error. - - base::Value cert_name(root_cert->subject().GetDisplayName()); - web_ui()->CallJavascriptFunctionUnsafe( - "CertificateEditCaTrustOverlay.showImport", cert_name); -} - -void CertificateManagerHandler::ImportCATrustSelected( - const base::ListValue* args) { - bool fail = false; - bool trust_ssl = false; - bool trust_email = false; - bool trust_obj_sign = false; - fail |= !CallbackArgsToBool(args, 0, &trust_ssl); - fail |= !CallbackArgsToBool(args, 1, &trust_email); - fail |= !CallbackArgsToBool(args, 2, &trust_obj_sign); - if (fail) { - LOG(ERROR) << "ImportCATrustSelected args fail"; - ImportExportCleanup(); - web_ui()->CallJavascriptFunctionUnsafe( - "CertificateEditCaTrustOverlay.dismiss"); - return; - } - - // TODO(mattm): add UI for setting explicit distrust, too. - // http://crbug.com/128411 - net::NSSCertDatabase::ImportCertFailureList not_imported; - bool result = certificate_manager_model_->ImportCACerts( - selected_cert_list_, - trust_ssl * net::NSSCertDatabase::TRUSTED_SSL + - trust_email * net::NSSCertDatabase::TRUSTED_EMAIL + - trust_obj_sign * net::NSSCertDatabase::TRUSTED_OBJ_SIGN, - ¬_imported); - web_ui()->CallJavascriptFunctionUnsafe( - "CertificateEditCaTrustOverlay.dismiss"); - if (!result) { - ShowError( - l10n_util::GetStringUTF8(IDS_CERT_MANAGER_CA_IMPORT_ERROR_TITLE), - l10n_util::GetStringUTF8(IDS_CERT_MANAGER_UNKNOWN_ERROR)); - } else if (!not_imported.empty()) { - ShowImportErrors( - l10n_util::GetStringUTF8(IDS_CERT_MANAGER_CA_IMPORT_ERROR_TITLE), - not_imported); - } - ImportExportCleanup(); -} - -void CertificateManagerHandler::Export(const base::ListValue* args) { - net::X509Certificate* cert = cert_id_map_->CallbackArgsToCert(args); - if (!cert) - return; - ShowCertExportDialog(web_ui()->GetWebContents(), GetParentWindow(), cert); -} - -void CertificateManagerHandler::Delete(const base::ListValue* args) { - net::X509Certificate* cert = cert_id_map_->CallbackArgsToCert(args); - if (!cert) - return; - bool result = certificate_manager_model_->Delete(cert); - if (!result) { - // TODO(mattm): better error messages? - ShowError( - l10n_util::GetStringUTF8(IDS_CERT_MANAGER_DELETE_CERT_ERROR_TITLE), - l10n_util::GetStringUTF8(IDS_CERT_MANAGER_UNKNOWN_ERROR)); - } -} - -void CertificateManagerHandler::OnCertificateManagerModelCreated( - std::unique_ptr<CertificateManagerModel> model) { - certificate_manager_model_ = std::move(model); - CertificateManagerModelReady(); -} - -void CertificateManagerHandler::CertificateManagerModelReady() { - base::Value user_db_available_value( - certificate_manager_model_->is_user_db_available()); - base::Value tpm_available_value( - certificate_manager_model_->is_tpm_available()); - web_ui()->CallJavascriptFunctionUnsafe("CertificateManager.onModelReady", - user_db_available_value, - tpm_available_value); - certificate_manager_model_->Refresh(); -} - -void CertificateManagerHandler::Populate(const base::ListValue* args) { - if (certificate_manager_model_) { - // Already have a model, the webui must be re-loading. Just re-run the - // webui initialization. - CertificateManagerModelReady(); - return; - } - - if (!requested_certificate_manager_model_) { - // Request that a model be created. - CertificateManagerModel::Create( - Profile::FromWebUI(web_ui()), - this, - base::Bind(&CertificateManagerHandler::OnCertificateManagerModelCreated, - weak_ptr_factory_.GetWeakPtr())); - requested_certificate_manager_model_ = true; - return; - } - - // We are already waiting for a CertificateManagerModel to be created, no need - // to do anything. -} - -void CertificateManagerHandler::PopulateTree( - const std::string& tab_name, - net::CertType type, - const net::CertificateList& web_trust_certs) { - const std::string tree_name = tab_name + "-tree"; - - std::unique_ptr<icu::Collator> collator; - UErrorCode error = U_ZERO_ERROR; - collator.reset( - icu::Collator::createInstance( - icu::Locale(g_browser_process->GetApplicationLocale().c_str()), - error)); - if (U_FAILURE(error)) - collator.reset(NULL); - DictionaryIdComparator comparator(collator.get()); - CertificateManagerModel::OrgGroupingMap map; - - certificate_manager_model_->FilterAndBuildOrgGroupingMap(type, &map); - - { - std::unique_ptr<base::ListValue> nodes(new base::ListValue); - for (CertificateManagerModel::OrgGroupingMap::iterator i = map.begin(); - i != map.end(); ++i) { - // Populate first level (org name). - std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue); - dict->SetString(kKeyId, OrgNameToId(i->first)); - dict->SetString(kNameId, i->first); - - // Populate second level (certs). - auto subnodes = base::MakeUnique<base::ListValue>(); - for (net::CertificateList::const_iterator org_cert_it = i->second.begin(); - org_cert_it != i->second.end(); ++org_cert_it) { - std::unique_ptr<base::DictionaryValue> cert_dict( - new base::DictionaryValue); - net::X509Certificate* cert = org_cert_it->get(); - cert_dict->SetString(kKeyId, cert_id_map_->CertToId(cert)); - cert_dict->SetString(kNameId, certificate_manager_model_->GetColumnText( - *cert, CertificateManagerModel::COL_SUBJECT_NAME)); - cert_dict->SetBoolean( - kReadOnlyId, - certificate_manager_model_->cert_db()->IsReadOnly(cert)); - // Policy-installed certificates with web trust are trusted. - bool policy_trusted = - IsPolicyInstalledWithWebTrust(web_trust_certs, cert); - cert_dict->SetBoolean( - kUntrustedId, - !policy_trusted && - certificate_manager_model_->cert_db()->IsUntrusted(cert)); - cert_dict->SetBoolean(kPolicyTrustedId, policy_trusted); - // TODO(hshi): This should be determined by testing for PKCS #11 - // CKA_EXTRACTABLE attribute. We may need to use the NSS function - // PK11_ReadRawAttribute to do that. - cert_dict->SetBoolean( - kExtractableId, - !certificate_manager_model_->IsHardwareBacked(cert)); - // TODO(mattm): Other columns. - subnodes->Append(std::move(cert_dict)); - } - std::sort(subnodes->begin(), subnodes->end(), comparator); - - dict->Set(kSubNodesId, std::move(subnodes)); - nodes->Append(std::move(dict)); - } - std::sort(nodes->begin(), nodes->end(), comparator); - - base::ListValue args; - args.AppendString(tree_name); - args.Append(std::move(nodes)); - web_ui()->CallJavascriptFunctionUnsafe("CertificateManager.onPopulateTree", - args); - } -} - -void CertificateManagerHandler::ShowError(const std::string& title, - const std::string& error) const { - auto title_value = base::MakeUnique<base::Value>(title); - auto error_value = base::MakeUnique<base::Value>(error); - auto ok_title_value = - base::MakeUnique<base::Value>(l10n_util::GetStringUTF8(IDS_OK)); - auto cancel_title_value = base::MakeUnique<base::Value>(); - auto ok_callback_value = base::MakeUnique<base::Value>(); - auto cancel_callback_value = base::MakeUnique<base::Value>(); - std::vector<const base::Value*> args = { - title_value.get(), error_value.get(), - ok_title_value.get(), cancel_title_value.get(), - ok_callback_value.get(), cancel_callback_value.get()}; - web_ui()->CallJavascriptFunctionUnsafe("AlertOverlay.show", args); -} - -void CertificateManagerHandler::ShowImportErrors( - const std::string& title, - const net::NSSCertDatabase::ImportCertFailureList& not_imported) const { - std::string error; - if (selected_cert_list_.size() == 1) - error = l10n_util::GetStringUTF8( - IDS_CERT_MANAGER_IMPORT_SINGLE_NOT_IMPORTED); - else if (not_imported.size() == selected_cert_list_.size()) - error = l10n_util::GetStringUTF8(IDS_CERT_MANAGER_IMPORT_ALL_NOT_IMPORTED); - else - error = l10n_util::GetStringUTF8(IDS_CERT_MANAGER_IMPORT_SOME_NOT_IMPORTED); - - base::ListValue cert_error_list; - for (size_t i = 0; i < not_imported.size(); ++i) { - const net::NSSCertDatabase::ImportCertFailure& failure = not_imported[i]; - std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue); - dict->SetString(kNameId, failure.certificate->subject().GetDisplayName()); - dict->SetString(kErrorId, NetErrorToString(failure.net_error)); - cert_error_list.Append(std::move(dict)); - } - - base::Value title_value(title); - base::Value error_value(error); - web_ui()->CallJavascriptFunctionUnsafe("CertificateImportErrorOverlay.show", - title_value, error_value, - cert_error_list); -} - -gfx::NativeWindow CertificateManagerHandler::GetParentWindow() const { - return web_ui()->GetWebContents()->GetTopLevelNativeWindow(); -} - -} // namespace options
diff --git a/chrome/browser/ui/webui/options/certificate_manager_handler.h b/chrome/browser/ui/webui/options/certificate_manager_handler.h deleted file mode 100644 index 392790b..0000000 --- a/chrome/browser/ui/webui/options/certificate_manager_handler.h +++ /dev/null
@@ -1,194 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_WEBUI_OPTIONS_CERTIFICATE_MANAGER_HANDLER_H_ -#define CHROME_BROWSER_UI_WEBUI_OPTIONS_CERTIFICATE_MANAGER_HANDLER_H_ - -#include <memory> -#include <string> - -#include "base/compiler_specific.h" -#include "base/macros.h" -#include "base/memory/weak_ptr.h" -#include "base/task/cancelable_task_tracker.h" -#include "chrome/browser/certificate_manager_model.h" -#include "chrome/browser/ui/webui/options/options_ui.h" -#include "net/cert/nss_cert_database.h" -#include "ui/gfx/native_widget_types.h" -#include "ui/shell_dialogs/select_file_dialog.h" - -namespace options { - -class CertIdMap; -class FileAccessProvider; - -class CertificateManagerHandler - : public OptionsPageUIHandler, - public CertificateManagerModel::Observer, - public ui::SelectFileDialog::Listener { - public: - explicit CertificateManagerHandler(bool show_certs_in_modal_dialog); - ~CertificateManagerHandler() override; - - // OptionsPageUIHandler implementation. - void GetLocalizedValues(base::DictionaryValue* localized_strings) override; - void RegisterMessages() override; - - // CertificateManagerModel::Observer implementation. - void CertificatesRefreshed() override; - - // SelectFileDialog::Listener implementation. - void FileSelected(const base::FilePath& path, - int index, - void* params) override; - void FileSelectionCanceled(void* params) override; - - private: - // View certificate. - void View(const base::ListValue* args); - - // Edit server certificate trust values. - void EditServer(const base::ListValue* args); - - // Edit certificate authority trust values. The sequence goes like: - // 1. user clicks edit button -> CertificateEditCaTrustOverlay.show -> - // GetCATrust -> CertificateEditCaTrustOverlay.populateTrust - // 2. user clicks ok -> EditCATrust -> CertificateEditCaTrustOverlay.dismiss - void GetCATrust(const base::ListValue* args); - void EditCATrust(const base::ListValue* args); - - // Cleanup state stored during import or export process. - void CancelImportExportProcess(const base::ListValue* args); - void ImportExportCleanup(); - - // Export to PKCS #12 file. The sequence goes like: - // 1a. user click on export button -> ExportPersonal -> launches file - // selector - // 1b. user click on export all button -> ExportAllPersonal -> launches file - // selector - // 2. user selects file -> ExportPersonalFileSelected -> launches password - // dialog - // 3. user enters password -> ExportPersonalPasswordSelected -> unlock slots - // 4. slots unlocked -> ExportPersonalSlotsUnlocked -> exports to memory - // buffer -> starts async write operation - // 5. write finishes (or fails) -> ExportPersonalFileWritten - void ExportPersonal(const base::ListValue* args); - void ExportAllPersonal(const base::ListValue* args); - void ExportPersonalFileSelected(const base::FilePath& path); - void ExportPersonalPasswordSelected(const base::ListValue* args); - void ExportPersonalSlotsUnlocked(); - void ExportPersonalFileWritten(const int* write_errno, - const int* bytes_written); - - // Import from PKCS #12 or cert file. The sequence goes like: - // 1. user click on import button -> StartImportPersonal -> launches file - // selector - // 2. user selects file -> ImportPersonalFileSelected -> starts async - // read operation - // 3. read operation completes -> ImportPersonalFileRead -> - // If file is PFX -> launches password dialog, goto step 4 - // Else -> import as certificate, goto step 6 - // 4. user enters password -> ImportPersonalPasswordSelected -> unlock slot - // 5. slot unlocked -> ImportPersonalSlotUnlocked attempts to - // import with previously entered password - // 6a. if import succeeds -> ImportExportCleanup - // 6b. if import fails -> show error, ImportExportCleanup - // TODO(mattm): allow retrying with different password - void StartImportPersonal(const base::ListValue* args); - void ImportPersonalFileSelected(const base::FilePath& path); - void ImportPersonalFileRead(const int* read_errno, const std::string* data); - void ImportPersonalPasswordSelected(const base::ListValue* args); - void ImportPersonalSlotUnlocked(); - - // Import Server certificates from file. Sequence goes like: - // 1. user clicks on import button -> ImportServer -> launches file selector - // 2. user selects file -> ImportServerFileSelected -> starts async read - // 3. read completes -> ImportServerFileRead -> parse certs -> attempt import - // 4a. if import succeeds -> ImportExportCleanup - // 4b. if import fails -> show error, ImportExportCleanup - void ImportServer(const base::ListValue* args); - void ImportServerFileSelected(const base::FilePath& path); - void ImportServerFileRead(const int* read_errno, const std::string* data); - - // Import Certificate Authorities from file. Sequence goes like: - // 1. user clicks on import button -> ImportCA -> launches file selector - // 2. user selects file -> ImportCAFileSelected -> starts async read - // 3. read completes -> ImportCAFileRead -> parse certs -> - // CertificateEditCaTrustOverlay.showImport - // 4. user clicks ok -> ImportCATrustSelected -> attempt import - // 5a. if import succeeds -> ImportExportCleanup - // 5b. if import fails -> show error, ImportExportCleanup - void ImportCA(const base::ListValue* args); - void ImportCAFileSelected(const base::FilePath& path); - void ImportCAFileRead(const int* read_errno, const std::string* data); - void ImportCATrustSelected(const base::ListValue* args); - - // Export a certificate. - void Export(const base::ListValue* args); - - // Delete certificate and private key (if any). - void Delete(const base::ListValue* args); - - // Model initialization methods. - void OnCertificateManagerModelCreated( - std::unique_ptr<CertificateManagerModel> model); - void CertificateManagerModelReady(); - - // Populate the trees in all the tabs. - void Populate(const base::ListValue* args); - - // Populate the given tab's tree. - void PopulateTree(const std::string& tab_name, - net::CertType type, - const net::CertificateList& web_trust_certs); - - // Populate the tree after retrieving the list of policy-installed - // web-trusted certificates. - void OnPolicyWebTrustCertsRetrieved( - const net::CertificateList& web_trust_certs); - - // Display a WebUI error message box. - void ShowError(const std::string& title, const std::string& error) const; - - // Display a WebUI error message box for import failures. - // Depends on |selected_cert_list_| being set to the imports that we - // attempted to import. - void ShowImportErrors( - const std::string& title, - const net::NSSCertDatabase::ImportCertFailureList& not_imported) const; - - gfx::NativeWindow GetParentWindow() const; - - // True if certificate viewer should be shown in modal instead of constrianed - // dialog. - bool show_certs_in_modal_dialog_; - // The Certificates Manager model - bool requested_certificate_manager_model_; - std::unique_ptr<CertificateManagerModel> certificate_manager_model_; - - // For multi-step import or export processes, we need to store the path, - // password, etc the user chose while we wait for them to enter a password, - // wait for file to be read, etc. - base::FilePath file_path_; - base::string16 password_; - bool use_hardware_backed_; - std::string file_data_; - net::CertificateList selected_cert_list_; - scoped_refptr<ui::SelectFileDialog> select_file_dialog_; - crypto::ScopedPK11Slot slot_; - - // Used in reading and writing certificate files. - base::CancelableTaskTracker tracker_; - scoped_refptr<FileAccessProvider> file_access_provider_; - - std::unique_ptr<CertIdMap> cert_id_map_; - - base::WeakPtrFactory<CertificateManagerHandler> weak_ptr_factory_; - - DISALLOW_COPY_AND_ASSIGN(CertificateManagerHandler); -}; - -} // namespace options - -#endif // CHROME_BROWSER_UI_WEBUI_OPTIONS_CERTIFICATE_MANAGER_HANDLER_H_
diff --git a/chrome/browser/ui/webui/options/chromeos/DEPS b/chrome/browser/ui/webui/options/chromeos/DEPS deleted file mode 100644 index 273d26b..0000000 --- a/chrome/browser/ui/webui/options/chromeos/DEPS +++ /dev/null
@@ -1,3 +0,0 @@ -include_rules = [ - "+components/onc", -]
diff --git a/chrome/browser/ui/webui/options/chromeos/OWNERS b/chrome/browser/ui/webui/options/chromeos/OWNERS deleted file mode 100644 index fff9165..0000000 --- a/chrome/browser/ui/webui/options/chromeos/OWNERS +++ /dev/null
@@ -1,6 +0,0 @@ -# This UI is deprecated. See chrome/browser/ui/webui/settings/chromeos/ instead. -achuith@chromium.org -stevenjb@chromium.org - -# Display options. -mukai@chromium.org
diff --git a/chrome/browser/ui/webui/options/chromeos/accounts_options_handler.cc b/chrome/browser/ui/webui/options/chromeos/accounts_options_handler.cc deleted file mode 100644 index fd866107..0000000 --- a/chrome/browser/ui/webui/options/chromeos/accounts_options_handler.cc +++ /dev/null
@@ -1,182 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/webui/options/chromeos/accounts_options_handler.h" - -#include <stddef.h> - -#include <memory> -#include <string> - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/json/json_reader.h" -#include "base/memory/ptr_util.h" -#include "base/strings/utf_string_conversions.h" -#include "base/values.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos.h" -#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" -#include "chrome/browser/chromeos/settings/cros_settings.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/profiles/profile_metrics.h" -#include "chrome/browser/ui/webui/chromeos/ui_account_tweaks.h" -#include "chrome/grit/generated_resources.h" -#include "chromeos/settings/cros_settings_names.h" -#include "components/prefs/pref_service.h" -#include "components/user_manager/user_manager.h" -#include "components/user_manager/user_names.h" -#include "content/public/browser/web_ui.h" -#include "google_apis/gaia/gaia_auth_util.h" -#include "ui/base/l10n/l10n_util.h" - -namespace chromeos { - -namespace { - -// Adds specified user to the whitelist. Returns false if that user is already -// in the whitelist. -bool WhitelistUser(OwnerSettingsServiceChromeOS* service, - const std::string& username) { - if (CrosSettings::Get()->FindEmailInList(kAccountsPrefUsers, username, NULL)) - return false; - if (service) { - base::Value username_value(username); - service->AppendToList(kAccountsPrefUsers, username_value); - } - return true; -} - -} // namespace - -namespace options { - -AccountsOptionsHandler::AccountsOptionsHandler() { -} - -AccountsOptionsHandler::~AccountsOptionsHandler() { -} - -void AccountsOptionsHandler::RegisterMessages() { - web_ui()->RegisterMessageCallback("whitelistUser", - base::Bind(&AccountsOptionsHandler::HandleWhitelistUser, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("unwhitelistUser", - base::Bind(&AccountsOptionsHandler::HandleUnwhitelistUser, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("updateWhitelist", - base::Bind(&AccountsOptionsHandler::HandleUpdateWhitelist, - base::Unretained(this))); -} - -void AccountsOptionsHandler::GetLocalizedValues( - base::DictionaryValue* localized_strings) { - DCHECK(localized_strings); - - RegisterTitle(localized_strings, "accountsPage", - IDS_OPTIONS_ACCOUNTS_TAB_LABEL); - - localized_strings->SetString("allow_BWSI", l10n_util::GetStringUTF16( - IDS_OPTIONS_ACCOUNTS_ALLOW_BWSI_DESCRIPTION)); - localized_strings->SetString( - "allow_supervised_users", - l10n_util::GetStringUTF16(IDS_OPTIONS_ACCOUNTS_ENABLE_SUPERVISED_USERS)); - localized_strings->SetString("use_whitelist", l10n_util::GetStringUTF16( - IDS_OPTIONS_ACCOUNTS_USE_WHITELIST_DESCRIPTION)); - localized_strings->SetString("show_user_on_signin", l10n_util::GetStringUTF16( - IDS_OPTIONS_ACCOUNTS_SHOW_USER_NAMES_ON_SINGIN_DESCRIPTION)); - localized_strings->SetString("username_edit_hint", l10n_util::GetStringUTF16( - IDS_OPTIONS_ACCOUNTS_USERNAME_EDIT_HINT)); - localized_strings->SetString("username_format", l10n_util::GetStringUTF16( - IDS_OPTIONS_ACCOUNTS_USERNAME_FORMAT)); - localized_strings->SetString("add_users", l10n_util::GetStringUTF16( - IDS_OPTIONS_ACCOUNTS_ADD_USERS)); - localized_strings->SetString("owner_only", l10n_util::GetStringUTF16( - IDS_OPTIONS_ACCOUNTS_OWNER_ONLY)); - - policy::BrowserPolicyConnectorChromeOS* connector = - g_browser_process->platform_part()->browser_policy_connector_chromeos(); - localized_strings->SetBoolean("whitelist_is_managed", - connector->IsEnterpriseManaged()); - - AddAccountUITweaksLocalizedValues(localized_strings, - Profile::FromWebUI(web_ui())); -} - -void AccountsOptionsHandler::HandleWhitelistUser(const base::ListValue* args) { - std::string typed_email; - std::string name; - if (!args->GetString(0, &typed_email) || - !args->GetString(1, &name)) { - return; - } - - if (OwnerSettingsServiceChromeOS* service = - OwnerSettingsServiceChromeOS::FromWebUI(web_ui())) { - WhitelistUser(service, gaia::CanonicalizeEmail(typed_email)); - } -} - -void AccountsOptionsHandler::HandleUnwhitelistUser( - const base::ListValue* args) { - std::string email; - if (!args->GetString(0, &email)) { - return; - } - - ProfileMetrics::LogProfileDeleteUser(ProfileMetrics::DELETE_PROFILE_SETTINGS); - - base::Value canonical_email(gaia::CanonicalizeEmail(email)); - if (OwnerSettingsServiceChromeOS* service = - OwnerSettingsServiceChromeOS::FromWebUI(web_ui())) { - service->RemoveFromList(kAccountsPrefUsers, canonical_email); - } - user_manager::UserManager::Get()->RemoveUser(AccountId::FromUserEmail(email), - nullptr); -} - -void AccountsOptionsHandler::HandleUpdateWhitelist( - const base::ListValue* args) { - DCHECK(args && args->empty()); - - // Creates one list to set. This is needed because user white list update is - // asynchronous and sequential. Before previous write comes back, cached list - // is stale and should not be used for appending. See http://crbug.com/127215 - std::unique_ptr<base::ListValue> new_list; - - CrosSettings* cros_settings = CrosSettings::Get(); - const base::ListValue* existing = NULL; - if (cros_settings->GetList(kAccountsPrefUsers, &existing) && existing) - new_list.reset(existing->DeepCopy()); - else - new_list.reset(new base::ListValue); - - // Remove all supervised users. On the next step only supervised users present - // on the device will be added back. Thus not present SU are removed. - // No need to remove usual users as they can simply login back. - for (size_t i = 0; i < new_list->GetSize(); ++i) { - std::string whitelisted_user; - new_list->GetString(i, &whitelisted_user); - if (user_manager::UserManager::Get()->IsSupervisedAccountId( - AccountId::FromUserEmail(whitelisted_user))) { - new_list->Remove(i, NULL); - --i; - } - } - - const user_manager::UserList& users = - user_manager::UserManager::Get()->GetUsers(); - for (const auto* user : users) { - new_list->AppendIfNotPresent( - base::MakeUnique<base::Value>(user->GetAccountId().GetUserEmail())); - } - - if (OwnerSettingsServiceChromeOS* service = - OwnerSettingsServiceChromeOS::FromWebUI(web_ui())) { - service->Set(kAccountsPrefUsers, *new_list.get()); - } -} - -} // namespace options -} // namespace chromeos
diff --git a/chrome/browser/ui/webui/options/chromeos/accounts_options_handler.h b/chrome/browser/ui/webui/options/chromeos/accounts_options_handler.h deleted file mode 100644 index 83212bb..0000000 --- a/chrome/browser/ui/webui/options/chromeos/accounts_options_handler.h +++ /dev/null
@@ -1,42 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_ACCOUNTS_OPTIONS_HANDLER_H_ -#define CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_ACCOUNTS_OPTIONS_HANDLER_H_ - -#include "base/compiler_specific.h" -#include "base/macros.h" -#include "chrome/browser/ui/webui/options/options_ui.h" - -namespace chromeos { -namespace options { - -// ChromeOS accounts options page handler. -class AccountsOptionsHandler : public ::options::OptionsPageUIHandler { - public: - AccountsOptionsHandler(); - ~AccountsOptionsHandler() override; - - // WebUIMessageHandler implementation. - void RegisterMessages() override; - - // OptionsPageUIHandler implementation. - void GetLocalizedValues(base::DictionaryValue* localized_strings) override; - - private: - // Javascript callbacks to update whitelist/unwhitelist user. - void HandleWhitelistUser(const base::ListValue* args); - void HandleUnwhitelistUser(const base::ListValue* args); - - // Javascript callback to update the white list: auto add existing users, - // remove not present supervised users. - void HandleUpdateWhitelist(const base::ListValue* args); - - DISALLOW_COPY_AND_ASSIGN(AccountsOptionsHandler); -}; - -} // namespace options -} // namespace chromeos - -#endif // CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_ACCOUNTS_OPTIONS_HANDLER_H_
diff --git a/chrome/browser/ui/webui/options/chromeos/bluetooth_options_handler.cc b/chrome/browser/ui/webui/options/chromeos/bluetooth_options_handler.cc deleted file mode 100644 index ddff2c1..0000000 --- a/chrome/browser/ui/webui/options/chromeos/bluetooth_options_handler.cc +++ /dev/null
@@ -1,104 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/webui/options/chromeos/bluetooth_options_handler.h" - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/callback.h" -#include "base/command_line.h" -#include "base/macros.h" -#include "base/strings/string_number_conversions.h" -#include "base/strings/utf_string_conversions.h" -#include "base/values.h" -#include "chrome/grit/generated_resources.h" -#include "content/public/browser/web_ui.h" -#include "third_party/cros_system_api/dbus/service_constants.h" - -namespace chromeos { -namespace options { - -BluetoothOptionsHandler::BluetoothOptionsHandler() { -} - -BluetoothOptionsHandler::~BluetoothOptionsHandler() { -} - -void BluetoothOptionsHandler::GetLocalizedValues( - base::DictionaryValue* localized_strings) { - DCHECK(localized_strings); - - static OptionsStringResource resources[] = { - { "bluetooth", IDS_OPTIONS_SETTINGS_SECTION_TITLE_BLUETOOTH }, - { "disableBluetooth", IDS_OPTIONS_SETTINGS_BLUETOOTH_DISABLE }, - { "enableBluetooth", IDS_OPTIONS_SETTINGS_BLUETOOTH_ENABLE }, - { "addBluetoothDevice", IDS_OPTIONS_SETTINGS_ADD_BLUETOOTH_DEVICE }, - { "bluetoothAddDeviceTitle", - IDS_OPTIONS_SETTINGS_BLUETOOTH_ADD_DEVICE_TITLE }, - { "bluetoothOptionsPageTabTitle", - IDS_OPTIONS_SETTINGS_BLUETOOTH_ADD_DEVICE_TITLE }, - { "bluetoothNoDevices", IDS_OPTIONS_SETTINGS_BLUETOOTH_NO_DEVICES }, - { "bluetoothNoDevicesFound", - IDS_OPTIONS_SETTINGS_BLUETOOTH_NO_DEVICES_FOUND }, - { "bluetoothScanning", IDS_OPTIONS_SETTINGS_BLUETOOTH_SCANNING }, - { "bluetoothScanStopped", IDS_OPTIONS_SETTINGS_BLUETOOTH_SCAN_STOPPED }, - { "bluetoothDeviceConnecting", IDS_OPTIONS_SETTINGS_BLUETOOTH_CONNECTING }, - { "bluetoothConnectDevice", IDS_OPTIONS_SETTINGS_BLUETOOTH_CONNECT }, - { "bluetoothDisconnectDevice", IDS_OPTIONS_SETTINGS_BLUETOOTH_DISCONNECT }, - { "bluetoothForgetDevice", IDS_OPTIONS_SETTINGS_BLUETOOTH_FORGET }, - { "bluetoothCancel", IDS_OPTIONS_SETTINGS_BLUETOOTH_CANCEL }, - { "bluetoothEnterKey", IDS_OPTIONS_SETTINGS_BLUETOOTH_ENTER_KEY }, - { "bluetoothDismissError", IDS_OPTIONS_SETTINGS_BLUETOOTH_DISMISS_ERROR }, - - // Device connecting and pairing. - { "bluetoothStartConnecting", - IDS_OPTIONS_SETTINGS_BLUETOOTH_START_CONNECTING }, - { "bluetoothAcceptPasskey", - IDS_OPTIONS_SETTINGS_BLUETOOTH_ACCEPT_PASSKEY }, - { "bluetoothRejectPasskey", - IDS_OPTIONS_SETTINGS_BLUETOOTH_REJECT_PASSKEY }, - { "bluetoothEnterPinCode", - IDS_OPTIONS_SETTINGS_BLUETOOTH_ENTER_PIN_CODE_REQUEST }, - { "bluetoothEnterPasskey", - IDS_OPTIONS_SETTINGS_BLUETOOTH_ENTER_PASSKEY_REQUEST }, - { "bluetoothRemotePinCode", - IDS_OPTIONS_SETTINGS_BLUETOOTH_REMOTE_PIN_CODE_REQUEST }, - { "bluetoothRemotePasskey", - IDS_OPTIONS_SETTINGS_BLUETOOTH_REMOTE_PASSKEY_REQUEST }, - { "bluetoothConfirmPasskey", - IDS_OPTIONS_SETTINGS_BLUETOOTH_CONFIRM_PASSKEY_REQUEST }, - - // Error messages. - { "bluetoothStartDiscoveryFailed", - IDS_OPTIONS_SETTINGS_BLUETOOTH_START_DISCOVERY_FAILED }, - { "bluetoothStopDiscoveryFailed", - IDS_OPTIONS_SETTINGS_BLUETOOTH_STOP_DISCOVERY_FAILED }, - { "bluetoothChangePowerFailed", - IDS_OPTIONS_SETTINGS_BLUETOOTH_CHANGE_POWER_FAILED }, - { "bluetoothConnectUnknownError", - IDS_OPTIONS_SETTINGS_BLUETOOTH_CONNECT_UNKNOWN_ERROR }, - { "bluetoothConnectInProgress", - IDS_OPTIONS_SETTINGS_BLUETOOTH_CONNECT_IN_PROGRESS }, - { "bluetoothConnectFailed", - IDS_OPTIONS_SETTINGS_BLUETOOTH_CONNECT_FAILED }, - { "bluetoothConnectAuthFailed", - IDS_OPTIONS_SETTINGS_BLUETOOTH_CONNECT_AUTH_FAILED }, - { "bluetoothConnectAuthCanceled", - IDS_OPTIONS_SETTINGS_BLUETOOTH_CONNECT_AUTH_CANCELED }, - { "bluetoothConnectAuthRejected", - IDS_OPTIONS_SETTINGS_BLUETOOTH_CONNECT_AUTH_REJECTED }, - { "bluetoothConnectAuthTimeout", - IDS_OPTIONS_SETTINGS_BLUETOOTH_CONNECT_AUTH_TIMEOUT }, - { "bluetoothConnectUnsupportedDevice", - IDS_OPTIONS_SETTINGS_BLUETOOTH_CONNECT_UNSUPPORTED_DEVICE }, - { "bluetoothDisconnectFailed", - IDS_OPTIONS_SETTINGS_BLUETOOTH_DISCONNECT_FAILED }, - { "bluetoothForgetFailed", - IDS_OPTIONS_SETTINGS_BLUETOOTH_FORGET_FAILED }}; - - RegisterStrings(localized_strings, resources, arraysize(resources)); -} - -} // namespace options -} // namespace chromeos
diff --git a/chrome/browser/ui/webui/options/chromeos/bluetooth_options_handler.h b/chrome/browser/ui/webui/options/chromeos/bluetooth_options_handler.h deleted file mode 100644 index dfe8753..0000000 --- a/chrome/browser/ui/webui/options/chromeos/bluetooth_options_handler.h +++ /dev/null
@@ -1,40 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_BLUETOOTH_OPTIONS_HANDLER_H_ -#define CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_BLUETOOTH_OPTIONS_HANDLER_H_ - -#include <memory> -#include <string> - -#include "base/callback.h" -#include "base/compiler_specific.h" -#include "base/macros.h" -#include "base/memory/weak_ptr.h" -#include "chrome/browser/ui/webui/options/options_ui.h" - -namespace base { -class DictionaryValue; -} - -namespace chromeos { -namespace options { - -// Handler for Bluetooth options on the system options page. -class BluetoothOptionsHandler : public ::options::OptionsPageUIHandler { - public: - BluetoothOptionsHandler(); - ~BluetoothOptionsHandler() override; - - // OptionsPageUIHandler implementation. - void GetLocalizedValues(base::DictionaryValue* localized_strings) override; - - private: - DISALLOW_COPY_AND_ASSIGN(BluetoothOptionsHandler); -}; - -} // namespace options -} // namespace chromeos - -#endif // CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_BLUETOOTH_OPTIONS_HANDLER_H_
diff --git a/chrome/browser/ui/webui/options/chromeos/change_picture_options_handler.cc b/chrome/browser/ui/webui/options/chromeos/change_picture_options_handler.cc deleted file mode 100644 index bd265d2..0000000 --- a/chrome/browser/ui/webui/options/chromeos/change_picture_options_handler.cc +++ /dev/null
@@ -1,461 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/webui/options/chromeos/change_picture_options_handler.h" - -#include <utility> - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/command_line.h" -#include "base/metrics/histogram_macros.h" -#include "base/path_service.h" -#include "base/strings/string_util.h" -#include "base/strings/utf_string_conversions.h" -#include "base/values.h" -#include "chrome/browser/chrome_notification_types.h" -#include "chrome/browser/chromeos/accessibility/accessibility_manager.h" -#include "chrome/browser/chromeos/camera_presence_notifier.h" -#include "chrome/browser/chromeos/login/users/avatar/user_image_manager.h" -#include "chrome/browser/chromeos/login/users/chrome_user_manager.h" -#include "chrome/browser/chromeos/login/users/default_user_image/default_user_images.h" -#include "chrome/browser/chromeos/profiles/profile_helper.h" -#include "chrome/browser/ui/browser_finder.h" -#include "chrome/browser/ui/browser_window.h" -#include "chrome/browser/ui/chrome_select_file_policy.h" -#include "chrome/common/chrome_paths.h" -#include "chrome/common/chrome_switches.h" -#include "chrome/common/url_constants.h" -#include "chrome/grit/browser_resources.h" -#include "chrome/grit/generated_resources.h" -#include "chromeos/audio/chromeos_sounds.h" -#include "components/user_manager/user.h" -#include "components/user_manager/user_image/user_image.h" -#include "components/user_manager/user_manager.h" -#include "content/public/browser/browser_thread.h" -#include "content/public/browser/notification_service.h" -#include "content/public/browser/web_ui.h" -#include "content/public/common/url_constants.h" -#include "media/audio/sounds/sounds_manager.h" -#include "net/base/data_url.h" -#include "ui/base/l10n/l10n_util.h" -#include "ui/base/resource/resource_bundle.h" -#include "ui/base/webui/web_ui_util.h" -#include "ui/views/widget/widget.h" -#include "url/gurl.h" - -using content::BrowserThread; - -namespace chromeos { -namespace options { - -namespace { - -// Returns info about extensions for files we support as user images. -ui::SelectFileDialog::FileTypeInfo GetUserImageFileTypeInfo() { - ui::SelectFileDialog::FileTypeInfo file_type_info; - file_type_info.extensions.resize(1); - - file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("bmp")); - - file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("jpg")); - file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("jpeg")); - - file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("png")); - - file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("tif")); - file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("tiff")); - - file_type_info.extension_description_overrides.resize(1); - file_type_info.extension_description_overrides[0] = - l10n_util::GetStringUTF16(IDS_IMAGE_FILES); - - return file_type_info; -} - -// Time histogram suffix for profile image download. -const char kProfileDownloadReason[] = "Preferences"; - -} // namespace - -ChangePictureOptionsHandler::ChangePictureOptionsHandler() - : previous_image_url_(url::kAboutBlankURL), - previous_image_index_(user_manager::User::USER_IMAGE_INVALID) { - user_manager::UserManager::Get()->AddObserver(this); - - ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); - media::SoundsManager* manager = media::SoundsManager::Get(); - manager->Initialize(SOUND_OBJECT_DELETE, - bundle.GetRawDataResource(IDR_SOUND_OBJECT_DELETE_WAV)); - manager->Initialize(SOUND_CAMERA_SNAP, - bundle.GetRawDataResource(IDR_SOUND_CAMERA_SNAP_WAV)); -} - -ChangePictureOptionsHandler::~ChangePictureOptionsHandler() { - user_manager::UserManager::Get()->RemoveObserver(this); - CameraPresenceNotifier::GetInstance()->RemoveObserver(this); - if (select_file_dialog_.get()) - select_file_dialog_->ListenerDestroyed(); -} - -void ChangePictureOptionsHandler::GetLocalizedValues( - base::DictionaryValue* localized_strings) { - DCHECK(localized_strings); - localized_strings->SetString("changePicturePage", - l10n_util::GetStringUTF16(IDS_OPTIONS_CHANGE_PICTURE_DIALOG_TITLE)); - localized_strings->SetString("changePicturePageDescription", - l10n_util::GetStringUTF16(IDS_OPTIONS_CHANGE_PICTURE_DIALOG_TEXT)); - localized_strings->SetString("takePhoto", - l10n_util::GetStringUTF16(IDS_OPTIONS_CHANGE_PICTURE_TAKE_PHOTO)); - localized_strings->SetString("discardPhoto", - l10n_util::GetStringUTF16(IDS_OPTIONS_CHANGE_PICTURE_DISCARD_PHOTO)); - localized_strings->SetString("flipPhoto", - l10n_util::GetStringUTF16(IDS_OPTIONS_CHANGE_PICTURE_FLIP_PHOTO)); - localized_strings->SetString("chooseFile", - l10n_util::GetStringUTF16(IDS_OPTIONS_CHANGE_PICTURE_CHOOSE_FILE)); - localized_strings->SetString("profilePhoto", - l10n_util::GetStringUTF16(IDS_OPTIONS_CHANGE_PICTURE_PROFILE_PHOTO)); - localized_strings->SetString("profilePhotoLoading", - l10n_util::GetStringUTF16( - IDS_OPTIONS_CHANGE_PICTURE_PROFILE_LOADING_PHOTO)); - localized_strings->SetString("previewAltText", - l10n_util::GetStringUTF16(IDS_OPTIONS_CHANGE_PICTURE_PREVIEW_ALT)); - localized_strings->SetString("authorCredit", - l10n_util::GetStringUTF16(IDS_OPTIONS_SET_WALLPAPER_AUTHOR_TEXT)); - localized_strings->SetString("photoFromCamera", - l10n_util::GetStringUTF16(IDS_OPTIONS_CHANGE_PICTURE_PHOTO_FROM_CAMERA)); - localized_strings->SetString("photoFlippedAccessibleText", - l10n_util::GetStringUTF16(IDS_OPTIONS_PHOTO_FLIP_ACCESSIBLE_TEXT)); - localized_strings->SetString("photoFlippedBackAccessibleText", - l10n_util::GetStringUTF16(IDS_OPTIONS_PHOTO_FLIPBACK_ACCESSIBLE_TEXT)); - localized_strings->SetString("photoCaptureAccessibleText", - l10n_util::GetStringUTF16(IDS_OPTIONS_PHOTO_CAPTURE_ACCESSIBLE_TEXT)); - localized_strings->SetString("photoDiscardAccessibleText", - l10n_util::GetStringUTF16(IDS_OPTIONS_PHOTO_DISCARD_ACCESSIBLE_TEXT)); -} - -void ChangePictureOptionsHandler::RegisterMessages() { - web_ui()->RegisterMessageCallback("chooseFile", - base::Bind(&ChangePictureOptionsHandler::HandleChooseFile, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("takePhoto", - base::Bind(&ChangePictureOptionsHandler::HandleTakePhoto, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("photoTaken", - base::Bind(&ChangePictureOptionsHandler::HandlePhotoTaken, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("discardPhoto", - base::Bind(&ChangePictureOptionsHandler::HandleDiscardPhoto, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("onChangePicturePageShown", - base::Bind(&ChangePictureOptionsHandler::HandlePageShown, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("onChangePicturePageHidden", - base::Bind(&ChangePictureOptionsHandler::HandlePageHidden, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("onChangePicturePageInitialized", - base::Bind(&ChangePictureOptionsHandler::HandlePageInitialized, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("selectImage", - base::Bind(&ChangePictureOptionsHandler::HandleSelectImage, - base::Unretained(this))); -} - -void ChangePictureOptionsHandler::SendDefaultImages() { - std::unique_ptr<base::ListValue> image_urls = - default_user_image::GetAsDictionary(false /* all */); - web_ui()->CallJavascriptFunctionUnsafe( - "ChangePictureOptions.setDefaultImages", *image_urls); -} - -void ChangePictureOptionsHandler::HandleChooseFile( - const base::ListValue* args) { - DCHECK(args && args->empty()); - select_file_dialog_ = ui::SelectFileDialog::Create( - this, new ChromeSelectFilePolicy(web_ui()->GetWebContents())); - - base::FilePath downloads_path; - if (!PathService::Get(chrome::DIR_DEFAULT_DOWNLOADS, &downloads_path)) { - NOTREACHED(); - return; - } - - // Static so we initialize it only once. - CR_DEFINE_STATIC_LOCAL(ui::SelectFileDialog::FileTypeInfo, file_type_info, - (GetUserImageFileTypeInfo())); - - select_file_dialog_->SelectFile( - ui::SelectFileDialog::SELECT_OPEN_FILE, - l10n_util::GetStringUTF16(IDS_DOWNLOAD_TITLE), - downloads_path, - &file_type_info, - 0, - FILE_PATH_LITERAL(""), - GetBrowserWindow(), - NULL); -} - -void ChangePictureOptionsHandler::HandleTakePhoto( - const base::ListValue* args) { - DCHECK(args->empty()); - AccessibilityManager::Get()->PlayEarcon( - SOUND_CAMERA_SNAP, PlaySoundOption::SPOKEN_FEEDBACK_ENABLED); -} - -void ChangePictureOptionsHandler::HandleDiscardPhoto( - const base::ListValue* args) { - DCHECK(args->empty()); - AccessibilityManager::Get()->PlayEarcon( - SOUND_OBJECT_DELETE, PlaySoundOption::SPOKEN_FEEDBACK_ENABLED); -} - -void ChangePictureOptionsHandler::HandlePhotoTaken( - const base::ListValue* args) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - std::string image_url; - if (!args || args->GetSize() != 1 || !args->GetString(0, &image_url)) - NOTREACHED(); - DCHECK(!image_url.empty()); - - std::string mime_type, charset, raw_data; - if (!net::DataURL::Parse(GURL(image_url), &mime_type, &charset, &raw_data)) - NOTREACHED(); - DCHECK_EQ("image/png", mime_type); - - user_photo_ = gfx::ImageSkia(); - user_photo_data_url_ = image_url; - - ImageDecoder::Cancel(this); - ImageDecoder::Start(this, raw_data); -} - -void ChangePictureOptionsHandler::HandlePageInitialized( - const base::ListValue* args) { - DCHECK(args && args->empty()); - SendDefaultImages(); -} - -void ChangePictureOptionsHandler::HandlePageShown(const base::ListValue* args) { - DCHECK(args && args->empty()); - SendSelectedImage(); - UpdateProfileImage(); - CameraPresenceNotifier::GetInstance()->AddObserver(this); -} - -void ChangePictureOptionsHandler::HandlePageHidden( - const base::ListValue* args) { - CameraPresenceNotifier::GetInstance()->RemoveObserver(this); -} - -void ChangePictureOptionsHandler::SendSelectedImage() { - const user_manager::User* user = GetUser(); - DCHECK(user->GetAccountId().is_valid()); - - previous_image_index_ = user->image_index(); - switch (previous_image_index_) { - case user_manager::User::USER_IMAGE_EXTERNAL: { - // User has image from camera/file, record it and add to the image list. - previous_image_ = user->GetImage(); - SendOldImage(webui::GetBitmapDataUrl(*previous_image_.bitmap())); - break; - } - case user_manager::User::USER_IMAGE_PROFILE: { - // User has their Profile image as the current image. - SendProfileImage(user->GetImage(), true); - break; - } - default: { - if (default_user_image::IsInCurrentImageSet(previous_image_index_)) { - // User has image from the current set of default images. - base::Value image_url( - default_user_image::GetDefaultImageUrl(previous_image_index_)); - web_ui()->CallJavascriptFunctionUnsafe( - "ChangePictureOptions.setSelectedImage", image_url); - } else { - // User has an old default image, so present it in the same manner as a - // previous image from file. - SendOldImage( - default_user_image::GetDefaultImageUrl(previous_image_index_)); - } - } - } -} - -void ChangePictureOptionsHandler::SendProfileImage(const gfx::ImageSkia& image, - bool should_select) { - base::Value data_url(webui::GetBitmapDataUrl(*image.bitmap())); - base::Value select(should_select); - web_ui()->CallJavascriptFunctionUnsafe("ChangePictureOptions.setProfileImage", - data_url, select); -} - -void ChangePictureOptionsHandler::UpdateProfileImage() { - UserImageManager* user_image_manager = - ChromeUserManager::Get()->GetUserImageManager(GetUser()->GetAccountId()); - // If we have a downloaded profile image and haven't sent it in - // |SendSelectedImage|, send it now (without selecting). - if (previous_image_index_ != user_manager::User::USER_IMAGE_PROFILE && - !user_image_manager->DownloadedProfileImage().isNull()) - SendProfileImage(user_image_manager->DownloadedProfileImage(), false); - - user_image_manager->DownloadProfileImage(kProfileDownloadReason); -} - -void ChangePictureOptionsHandler::SendOldImage(const std::string& image_url) { - previous_image_url_ = image_url; - base::Value url(image_url); - web_ui()->CallJavascriptFunctionUnsafe("ChangePictureOptions.setOldImage", - url); -} - -void ChangePictureOptionsHandler::HandleSelectImage( - const base::ListValue* args) { - std::string image_url; - std::string image_type; - if (!args || - args->GetSize() != 2 || - !args->GetString(0, &image_url) || - !args->GetString(1, &image_type)) { - NOTREACHED(); - return; - } - DCHECK(!image_url.empty()); - DCHECK(!image_type.empty()); - - UserImageManager* user_image_manager = - ChromeUserManager::Get()->GetUserImageManager(GetUser()->GetAccountId()); - int image_index = user_manager::User::USER_IMAGE_INVALID; - bool waiting_for_camera_photo = false; - - if (image_type == "old") { - // Previous image (from camera or manually uploaded) re-selected. - DCHECK(!previous_image_.isNull()); - user_image_manager->SaveUserImage( - user_manager::UserImage::CreateAndEncode( - previous_image_, user_manager::UserImage::FORMAT_JPEG)); - - UMA_HISTOGRAM_EXACT_LINEAR("UserImage.ChangeChoice", - default_user_image::kHistogramImageOld, - default_user_image::kHistogramImagesCount); - VLOG(1) << "Selected old user image"; - } else if (image_type == "default" && - default_user_image::IsDefaultImageUrl(image_url, &image_index)) { - // One of the default user images. - user_image_manager->SaveUserDefaultImageIndex(image_index); - - UMA_HISTOGRAM_EXACT_LINEAR( - "UserImage.ChangeChoice", - default_user_image::GetDefaultImageHistogramValue(image_index), - default_user_image::kHistogramImagesCount); - VLOG(1) << "Selected default user image: " << image_index; - } else if (image_type == "camera") { - // Camera image is selected. - if (user_photo_.isNull()) { - waiting_for_camera_photo = true; - VLOG(1) << "Still waiting for camera image to decode"; - } else { - SetImageFromCamera(user_photo_); - } - } else if (image_type == "profile") { - // Profile image selected. Could be previous (old) user image. - user_image_manager->SaveUserImageFromProfileImage(); - - if (previous_image_index_ == user_manager::User::USER_IMAGE_PROFILE) { - UMA_HISTOGRAM_EXACT_LINEAR("UserImage.ChangeChoice", - default_user_image::kHistogramImageOld, - default_user_image::kHistogramImagesCount); - VLOG(1) << "Selected old (profile) user image"; - } else { - UMA_HISTOGRAM_EXACT_LINEAR("UserImage.ChangeChoice", - default_user_image::kHistogramImageFromProfile, - default_user_image::kHistogramImagesCount); - VLOG(1) << "Selected profile image"; - } - } else { - NOTREACHED() << "Unexpected image type: " << image_type; - } - - // Ignore the result of the previous decoding if it's no longer needed. - if (!waiting_for_camera_photo) - ImageDecoder::Cancel(this); -} - -void ChangePictureOptionsHandler::FileSelected(const base::FilePath& path, - int index, - void* params) { - ChromeUserManager::Get() - ->GetUserImageManager(GetUser()->GetAccountId()) - ->SaveUserImageFromFile(path); - UMA_HISTOGRAM_EXACT_LINEAR("UserImage.ChangeChoice", - default_user_image::kHistogramImageFromFile, - default_user_image::kHistogramImagesCount); - VLOG(1) << "Selected image from file"; -} - -void ChangePictureOptionsHandler::SetImageFromCamera( - const gfx::ImageSkia& photo) { - ChromeUserManager::Get() - ->GetUserImageManager(GetUser()->GetAccountId()) - ->SaveUserImage(user_manager::UserImage::CreateAndEncode( - photo, user_manager::UserImage::FORMAT_JPEG)); - UMA_HISTOGRAM_EXACT_LINEAR("UserImage.ChangeChoice", - default_user_image::kHistogramImageFromCamera, - default_user_image::kHistogramImagesCount); - VLOG(1) << "Selected camera photo"; -} - -void ChangePictureOptionsHandler::SetCameraPresent(bool present) { - base::Value present_value(present); - - web_ui()->CallJavascriptFunctionUnsafe( - "ChangePictureOptions.setCameraPresent", present_value); -} - -void ChangePictureOptionsHandler::OnCameraPresenceCheckDone( - bool is_camera_present) { - SetCameraPresent(is_camera_present); -} - -void ChangePictureOptionsHandler::OnUserImageChanged( - const user_manager::User& user) { - // Not initialized yet. - if (previous_image_index_ == user_manager::User::USER_IMAGE_INVALID) - return; - SendSelectedImage(); -} - -void ChangePictureOptionsHandler::OnUserProfileImageUpdated( - const user_manager::User& user, - const gfx::ImageSkia& profile_image) { - // User profile image has been updated. - SendProfileImage(profile_image, false); -} - -gfx::NativeWindow ChangePictureOptionsHandler::GetBrowserWindow() const { - Browser* browser = - chrome::FindBrowserWithWebContents(web_ui()->GetWebContents()); - return browser->window()->GetNativeWindow(); -} - -void ChangePictureOptionsHandler::OnImageDecoded( - const SkBitmap& decoded_image) { - user_photo_ = gfx::ImageSkia::CreateFrom1xBitmap(decoded_image); - SetImageFromCamera(user_photo_); -} - -void ChangePictureOptionsHandler::OnDecodeImageFailed() { - NOTREACHED() << "Failed to decode PNG image from WebUI"; -} - -const user_manager::User* ChangePictureOptionsHandler::GetUser() const { - Profile* profile = Profile::FromWebUI(web_ui()); - const user_manager::User* user = - ProfileHelper::Get()->GetUserByProfile(profile); - if (!user) - return user_manager::UserManager::Get()->GetActiveUser(); - return user; -} - -} // namespace options -} // namespace chromeos
diff --git a/chrome/browser/ui/webui/options/chromeos/change_picture_options_handler.h b/chrome/browser/ui/webui/options/chromeos/change_picture_options_handler.h deleted file mode 100644 index 625ce3b..0000000 --- a/chrome/browser/ui/webui/options/chromeos/change_picture_options_handler.h +++ /dev/null
@@ -1,145 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_CHANGE_PICTURE_OPTIONS_HANDLER_H_ -#define CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_CHANGE_PICTURE_OPTIONS_HANDLER_H_ - -#include "base/macros.h" -#include "chrome/browser/chromeos/camera_presence_notifier.h" -#include "chrome/browser/image_decoder.h" -#include "chrome/browser/ui/webui/options/options_ui.h" -#include "components/user_manager/user_manager.h" -#include "ui/gfx/image/image_skia.h" -#include "ui/gfx/native_widget_types.h" -#include "ui/shell_dialogs/select_file_dialog.h" - -namespace base { -class DictionaryValue; -class ListValue; -} - -namespace user_manager { -class User; -} - -namespace chromeos { - -namespace options { - -// ChromeOS user image options page UI handler. -class ChangePictureOptionsHandler : public ::options::OptionsPageUIHandler, - public ui::SelectFileDialog::Listener, - public user_manager::UserManager::Observer, - public ImageDecoder::ImageRequest, - public CameraPresenceNotifier::Observer { - public: - ChangePictureOptionsHandler(); - ~ChangePictureOptionsHandler() override; - - // OptionsPageUIHandler implementation. - void GetLocalizedValues(base::DictionaryValue* localized_strings) override; - - // WebUIMessageHandler implementation. - void RegisterMessages() override; - - // CameraPresenceNotifier::Observer implementation: - void OnCameraPresenceCheckDone(bool is_camera_present) override; - - private: - // Sends list of available default images to the page. - void SendDefaultImages(); - - // Sends current selection to the page. - void SendSelectedImage(); - - // Sends the profile image to the page. If |should_select| is true then - // the profile image element is selected. - void SendProfileImage(const gfx::ImageSkia& image, bool should_select); - - // Starts profile image update and shows the last downloaded profile image, - // if any, on the page. Shouldn't be called before |SendProfileImage|. - void UpdateProfileImage(); - - // Sends previous user image to the page. - void SendOldImage(const std::string& image_url); - - // Starts camera presence check. - void CheckCameraPresence(); - - // Updates UI with camera presence state. - void SetCameraPresent(bool present); - - // Opens a file selection dialog to choose user image from file. - void HandleChooseFile(const base::ListValue* args); - - // Handles 'take-photo' button click. - void HandleTakePhoto(const base::ListValue* args); - - // Handles photo taken with WebRTC UI. - void HandlePhotoTaken(const base::ListValue* args); - - // Handles 'discard-photo' button click. - void HandleDiscardPhoto(const base::ListValue* args); - - // Gets the list of available user images and sends it to the page. - void HandleGetAvailableImages(const base::ListValue* args); - - // Handles page initialized event. - void HandlePageInitialized(const base::ListValue* args); - - // Handles page shown event. - void HandlePageShown(const base::ListValue* args); - - // Handles page hidden event. - void HandlePageHidden(const base::ListValue* args); - - // Selects one of the available images as user's. - void HandleSelectImage(const base::ListValue* args); - - // SelectFileDialog::Delegate implementation. - void FileSelected(const base::FilePath& path, - int index, - void* params) override; - - // user_manager::UserManager::Observer implementation. - void OnUserImageChanged(const user_manager::User& user) override; - void OnUserProfileImageUpdated(const user_manager::User& user, - const gfx::ImageSkia& profile_image) override; - - // Sets user image to photo taken from camera. - void SetImageFromCamera(const gfx::ImageSkia& photo); - - // Returns handle to browser window or NULL if it can't be found. - gfx::NativeWindow GetBrowserWindow() const; - - // Overriden from ImageDecoder::ImageRequest: - void OnImageDecoded(const SkBitmap& decoded_image) override; - void OnDecodeImageFailed() override; - - // Returns user related to current WebUI. If this user doesn't exist, - // returns active user. - const user_manager::User* GetUser() const; - - scoped_refptr<ui::SelectFileDialog> select_file_dialog_; - - // Previous user image from camera/file and its data URL. - gfx::ImageSkia previous_image_; - std::string previous_image_url_; - - // Index of the previous user image. - int previous_image_index_; - - // Last user photo, if taken. - gfx::ImageSkia user_photo_; - - // Data URL for |user_photo_|. - std::string user_photo_data_url_; - - DISALLOW_COPY_AND_ASSIGN(ChangePictureOptionsHandler); -}; - -} // namespace options -} // namespace chromeos - -#endif // CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_CHANGE_PICTURE_OPTIONS_HANDLER_H_
diff --git a/chrome/browser/ui/webui/options/chromeos/core_chromeos_options_handler.cc b/chrome/browser/ui/webui/options/chromeos/core_chromeos_options_handler.cc deleted file mode 100644 index 201f458..0000000 --- a/chrome/browser/ui/webui/options/chromeos/core_chromeos_options_handler.cc +++ /dev/null
@@ -1,454 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/webui/options/chromeos/core_chromeos_options_handler.h" - -#include <stddef.h> -#include <string> -#include <utility> - -#include "base/bind.h" -#include "base/location.h" -#include "base/macros.h" -#include "base/memory/ptr_util.h" -#include "base/single_thread_task_runner.h" -#include "base/strings/string_number_conversions.h" -#include "base/strings/string_util.h" -#include "base/strings/utf_string_conversions.h" -#include "base/sys_info.h" -#include "base/threading/thread_task_runner_handle.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/chrome_notification_types.h" -#include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos.h" -#include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos_factory.h" -#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" -#include "chrome/browser/chromeos/profiles/profile_helper.h" -#include "chrome/browser/chromeos/proxy_cros_settings_parser.h" -#include "chrome/browser/chromeos/settings/cros_settings.h" -#include "chrome/browser/chromeos/system/timezone_util.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/ash/session_controller_client.h" -#include "chrome/browser/ui/webui/chromeos/ui_account_tweaks.h" -#include "chrome/browser/ui/webui/options/chromeos/accounts_options_handler.h" -#include "chrome/common/pref_names.h" -#include "chrome/grit/generated_resources.h" -#include "chromeos/network/network_handler.h" -#include "chromeos/network/proxy/ui_proxy_config_service.h" -#include "components/onc/onc_pref_names.h" -#include "components/prefs/pref_change_registrar.h" -#include "components/proxy_config/proxy_config_pref_names.h" -#include "components/user_manager/user_manager.h" -#include "content/public/browser/notification_service.h" -#include "content/public/browser/web_ui.h" -#include "ui/base/l10n/l10n_util.h" - -namespace chromeos { -namespace options { - -namespace { - -// List of settings that are not changeable by users. -const char* kReadOnlySettings[] = { - kSystemTimezone -}; - -// List of settings that should only be changeable by the primary user. -const char* kPrimaryUserSettings[] = { - prefs::kWakeOnWifiDarkConnect, - prefs::kUserTimezone, - prefs::kResolveTimezoneByGeolocation -}; - -// Returns true if |pref| can be controlled (e.g. by policy or owner). -bool IsSettingPrivileged(const std::string& pref) { - if (!chromeos::system::PerUserTimezoneEnabled()) { - return pref != kSystemTimezone; - } - // All the other Cros Settings are controlled. - return true; -} - -// Returns true if |pref| is modifiable from UI. -bool IsSettingWritable(const std::string& pref) { - if (!system::PerUserTimezoneEnabled()) - return true; - - const char** end = kReadOnlySettings + arraysize(kReadOnlySettings); - return std::find(kReadOnlySettings, end, pref) == end; -} - -// Returns true if |pref| is shared (controlled by the primary user). -bool IsSettingShared(const std::string& pref) { - const char** end = kPrimaryUserSettings + arraysize(kPrimaryUserSettings); - return std::find(kPrimaryUserSettings, end, pref) != end; -} - -// Creates a user info dictionary to be stored in the |ListValue| that is -// passed to Javascript for the |kAccountsPrefUsers| preference. -std::unique_ptr<base::DictionaryValue> CreateUserInfo( - const std::string& username, - const std::string& display_email, - const std::string& display_name) { - auto user_dict = base::MakeUnique<base::DictionaryValue>(); - user_dict->SetString("username", username); - user_dict->SetString("name", display_email); - user_dict->SetString("email", display_name); - - const bool is_owner = - user_manager::UserManager::Get()->GetOwnerAccountId().GetUserEmail() == - username; - user_dict->SetBoolean("owner", is_owner); - return user_dict; -} - -// This function decorates the bare list of emails with some more information -// needed by the UI to properly display the Accounts page. -std::unique_ptr<base::Value> CreateUsersWhitelist( - const base::Value* pref_value) { - const base::ListValue* list_value = - static_cast<const base::ListValue*>(pref_value); - auto user_list = base::MakeUnique<base::ListValue>(); - user_manager::UserManager* user_manager = user_manager::UserManager::Get(); - - for (base::ListValue::const_iterator i = list_value->begin(); - i != list_value->end(); ++i) { - std::string email; - if (i->GetAsString(&email)) { - // Translate email to the display email. - const std::string display_email = - user_manager->GetUserDisplayEmail(AccountId::FromUserEmail(email)); - // TODO(ivankr): fetch display name for existing users. - user_list->Append(CreateUserInfo(email, display_email, std::string())); - } - } - return std::move(user_list); -} - -// Checks whether this is a secondary user in a multi-profile session. -bool IsSecondaryUser(Profile* profile) { - user_manager::UserManager* user_manager = user_manager::UserManager::Get(); - const user_manager::User* user = - ProfileHelper::Get()->GetUserByProfile(profile); - return user && - user->GetAccountId() != user_manager->GetPrimaryUser()->GetAccountId(); -} - -const char kSelectNetworkMessage[] = "selectNetwork"; - -UIProxyConfigService* GetUiProxyConfigService() { - return NetworkHandler::Get()->ui_proxy_config_service(); -} - -} // namespace - -CoreChromeOSOptionsHandler::CoreChromeOSOptionsHandler() { - notification_registrar_.Add(this, - chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED, - content::NotificationService::AllSources()); -} - -CoreChromeOSOptionsHandler::~CoreChromeOSOptionsHandler() { -} - -void CoreChromeOSOptionsHandler::RegisterMessages() { - CoreOptionsHandler::RegisterMessages(); - web_ui()->RegisterMessageCallback( - kSelectNetworkMessage, - base::Bind(&CoreChromeOSOptionsHandler::SelectNetworkCallback, - base::Unretained(this))); -} - -void CoreChromeOSOptionsHandler::InitializeHandler() { - // This function is both called on the initial page load and on each reload. - CoreOptionsHandler::InitializeHandler(); - - if (!ProfileHelper::IsSigninProfile(Profile::FromWebUI(web_ui()))) - ObservePref(onc::prefs::kOpenNetworkConfiguration); - ObservePref(proxy_config::prefs::kProxy); - ObservePref(onc::prefs::kDeviceOpenNetworkConfiguration); -} - -void CoreChromeOSOptionsHandler::Observe( - int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) { - DCHECK_EQ(chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED, type); - - // Finish this asynchronously because the notification has to tricle in to all - // Chrome components before we can reliably read the status on the other end. - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(&CoreChromeOSOptionsHandler::NotifyOwnershipChanged, - base::Unretained(this))); -} - -void CoreChromeOSOptionsHandler::NotifyOwnershipChanged() { - for (auto& it : pref_subscription_map_) - NotifySettingsChanged(it.first); -} - -std::unique_ptr<base::Value> CoreChromeOSOptionsHandler::FetchPref( - const std::string& pref_name) { - if (proxy_cros_settings_parser::IsProxyPref(pref_name)) { - std::unique_ptr<base::Value> value; - proxy_cros_settings_parser::GetProxyPrefValue( - network_guid_, pref_name, GetUiProxyConfigService(), &value); - return value; - } - - Profile* profile = Profile::FromWebUI(web_ui()); - if (!CrosSettings::IsCrosSettings(pref_name)) { - std::string controlling_pref = - pref_name == proxy_config::prefs::kUseSharedProxies - ? proxy_config::prefs::kProxy - : std::string(); - std::unique_ptr<base::Value> value = - CreateValueForPref(pref_name, controlling_pref); - if (!IsSettingShared(pref_name) || !IsSecondaryUser(profile)) - return value; - base::DictionaryValue* dict; - if (!value->GetAsDictionary(&dict) || dict->HasKey("controlledBy")) - return value; - Profile* primary_profile = ProfileHelper::Get()->GetProfileByUser( - user_manager::UserManager::Get()->GetPrimaryUser()); - if (!primary_profile) - return value; - dict->SetString("controlledBy", "shared"); - dict->SetBoolean("disabled", true); - if (system::PerUserTimezoneEnabled()) { - const PrefService::Preference* pref = - primary_profile->GetPrefs()->FindPreference(pref_name); - dict->Set("value", base::MakeUnique<base::Value>(*pref->GetValue())); - } else { - dict->SetBoolean("value", - primary_profile->GetPrefs()->GetBoolean(pref_name)); - } - return value; - } - - const base::Value* pref_value = CrosSettings::Get()->GetPref(pref_name); - if (!pref_value) - return base::MakeUnique<base::Value>(); - - // Decorate pref value as CoreOptionsHandler::CreateValueForPref() does. - // TODO(estade): seems that this should replicate CreateValueForPref less. - auto dict = base::MakeUnique<base::DictionaryValue>(); - if (pref_name == kAccountsPrefUsers) - dict->Set("value", CreateUsersWhitelist(pref_value)); - else - dict->Set("value", base::MakeUnique<base::Value>(*pref_value)); - - std::string controlled_by; - if (system::PerUserTimezoneEnabled() || IsSettingPrivileged(pref_name)) { - policy::BrowserPolicyConnectorChromeOS* connector = - g_browser_process->platform_part()->browser_policy_connector_chromeos(); - if (connector->IsEnterpriseManaged()) - controlled_by = "policy"; - else if (!ProfileHelper::IsOwnerProfile(profile)) - controlled_by = "owner"; - } - if (!controlled_by.empty()) - dict->SetString("controlledBy", controlled_by); - - // Read-only setting is always disabled. - dict->SetBoolean("disabled", - !controlled_by.empty() || !IsSettingWritable(pref_name)); - return std::move(dict); -} - -void CoreChromeOSOptionsHandler::ObservePref(const std::string& pref_name) { - if (proxy_cros_settings_parser::IsProxyPref(pref_name)) { - // We observe those all the time. - return; - } - if (!CrosSettings::IsCrosSettings(pref_name)) - return ::options::CoreOptionsHandler::ObservePref(pref_name); - - std::unique_ptr<CrosSettings::ObserverSubscription> subscription = - CrosSettings::Get()->AddSettingsObserver( - pref_name.c_str(), - base::Bind(&CoreChromeOSOptionsHandler::NotifySettingsChanged, - base::Unretained(this), pref_name)); - pref_subscription_map_.insert(make_pair(pref_name, std::move(subscription))); -} - -void CoreChromeOSOptionsHandler::SetPref(const std::string& pref_name, - const base::Value* value, - const std::string& metric) { - if (proxy_cros_settings_parser::IsProxyPref(pref_name)) { - proxy_cros_settings_parser::SetProxyPrefValue( - network_guid_, pref_name, value, GetUiProxyConfigService()); - base::Value proxy_type(pref_name); - web_ui()->CallJavascriptFunctionUnsafe( - "options.internet.DetailsInternetPage.updateProxySettings", proxy_type); - ProcessUserMetric(value, metric); - return; - } - if (!CrosSettings::IsCrosSettings(pref_name)) - return ::options::CoreOptionsHandler::SetPref(pref_name, value, metric); - if (!IsSettingWritable(pref_name)) { - NOTREACHED() << pref_name; - return; - } - OwnerSettingsServiceChromeOS* service = - OwnerSettingsServiceChromeOS::FromWebUI(web_ui()); - if (service && service->HandlesSetting(pref_name)) - service->Set(pref_name, *value); - else - CrosSettings::Get()->Set(pref_name, *value); - - ProcessUserMetric(value, metric); -} - -void CoreChromeOSOptionsHandler::StopObservingPref(const std::string& path) { - if (proxy_cros_settings_parser::IsProxyPref(path)) - return; // We unregister those in the destructor. - // Unregister this instance from observing prefs of chrome os settings. - if (CrosSettings::IsCrosSettings(path)) - pref_subscription_map_.erase(path); - else // Call base class to handle regular preferences. - ::options::CoreOptionsHandler::StopObservingPref(path); -} - -std::unique_ptr<base::Value> CoreChromeOSOptionsHandler::CreateValueForPref( - const std::string& pref_name, - const std::string& controlling_pref_name) { - // The screen lock setting is shared if multiple users are logged in and at - // least one has chosen to require passwords. - if (pref_name == prefs::kEnableAutoScreenLock && - user_manager::UserManager::Get()->GetLoggedInUsers().size() > 1 && - controlling_pref_name.empty()) { - PrefService* user_prefs = Profile::FromWebUI(web_ui())->GetPrefs(); - const PrefService::Preference* pref = - user_prefs->FindPreference(prefs::kEnableAutoScreenLock); - - if (pref && pref->IsUserModifiable() && - SessionControllerClient::ShouldLockScreenAutomatically()) { - bool screen_lock = false; - bool success = pref->GetValue()->GetAsBoolean(&screen_lock); - DCHECK(success); - if (!screen_lock) { - // Screen lock is enabled for the session, but not in the user's - // preferences. Show the user's value in the checkbox, but indicate - // that the password requirement is enabled by some other user. - auto dict = base::MakeUnique<base::DictionaryValue>(); - dict->Set("value", base::MakeUnique<base::Value>(*pref->GetValue())); - dict->SetString("controlledBy", "shared"); - return std::move(dict); - } - } - } - - return CoreOptionsHandler::CreateValueForPref(pref_name, - controlling_pref_name); -} - -void CoreChromeOSOptionsHandler::GetLocalizedValues( - base::DictionaryValue* localized_strings) { - DCHECK(localized_strings); - CoreOptionsHandler::GetLocalizedValues(localized_strings); - - Profile* profile = Profile::FromWebUI(web_ui()); - AddAccountUITweaksLocalizedValues(localized_strings, profile); - - user_manager::UserManager* user_manager = user_manager::UserManager::Get(); - - if (IsSecondaryUser(profile)) { - const std::string& primary_email = - user_manager->GetPrimaryUser()->GetAccountId().GetUserEmail(); - - // Set secondaryUser to show the shared icon by the network section header. - localized_strings->SetBoolean("secondaryUser", true); - localized_strings->SetString("secondaryUserBannerText", - l10n_util::GetStringFUTF16( - IDS_OPTIONS_SETTINGS_SECONDARY_USER_BANNER, - base::ASCIIToUTF16(primary_email))); - localized_strings->SetString("controlledSettingShared", - l10n_util::GetStringFUTF16( - IDS_OPTIONS_CONTROLLED_SETTING_SHARED, - base::ASCIIToUTF16(primary_email))); - localized_strings->SetString("controlledSettingsShared", - l10n_util::GetStringFUTF16( - IDS_OPTIONS_CONTROLLED_SETTINGS_SHARED, - base::ASCIIToUTF16(primary_email))); - } else { - localized_strings->SetBoolean("secondaryUser", false); - localized_strings->SetString("secondaryUserBannerText", base::string16()); - localized_strings->SetString("controlledSettingShared", base::string16()); - localized_strings->SetString("controlledSettingsShared", base::string16()); - } - - // Screen lock icon can show up as primary or secondary user. - localized_strings->SetString("screenLockShared", - l10n_util::GetStringUTF16( - IDS_OPTIONS_CONTROLLED_SETTING_SHARED_SCREEN_LOCK)); - - policy::BrowserPolicyConnectorChromeOS* connector = - g_browser_process->platform_part()->browser_policy_connector_chromeos(); - if (connector->IsEnterpriseManaged()) { - // Managed machines have no "owner". - localized_strings->SetString("controlledSettingOwner", base::string16()); - } else { - localized_strings->SetString( - "controlledSettingOwner", - l10n_util::GetStringFUTF16( - IDS_OPTIONS_CONTROLLED_SETTING_OWNER, - base::ASCIIToUTF16( - user_manager->GetOwnerAccountId().GetUserEmail()))); - } -} - -void CoreChromeOSOptionsHandler::SelectNetworkCallback( - const base::ListValue* args) { - if (args->GetSize() != 1 || !args->GetString(0, &network_guid_)) { - NOTREACHED(); - return; - } - NotifyProxyPrefsChanged(); -} - -void CoreChromeOSOptionsHandler::OnPreferenceChanged( - PrefService* service, - const std::string& pref_name) { - // Redetermine the current proxy settings and notify the UI if any of these - // preferences change. - if (pref_name == onc::prefs::kOpenNetworkConfiguration || - pref_name == onc::prefs::kDeviceOpenNetworkConfiguration || - pref_name == proxy_config::prefs::kProxy) { - NotifyProxyPrefsChanged(); - return; - } - if (pref_name == proxy_config::prefs::kUseSharedProxies) { - // kProxy controls kUseSharedProxies and decides if it's managed by - // policy/extension. - NotifyPrefChanged(proxy_config::prefs::kUseSharedProxies, - proxy_config::prefs::kProxy); - return; - } - ::options::CoreOptionsHandler::OnPreferenceChanged(service, pref_name); -} - -void CoreChromeOSOptionsHandler::NotifySettingsChanged( - const std::string& setting_name) { - DCHECK(CrosSettings::Get()->IsCrosSettings(setting_name)); - std::unique_ptr<base::Value> value(FetchPref(setting_name)); - if (!value.get()) - NOTREACHED(); - DispatchPrefChangeNotification(setting_name, std::move(value)); -} - -void CoreChromeOSOptionsHandler::NotifyProxyPrefsChanged() { - GetUiProxyConfigService()->UpdateFromPrefs(network_guid_); - for (size_t i = 0; i < proxy_cros_settings_parser::kProxySettingsCount; ++i) { - std::unique_ptr<base::Value> value; - proxy_cros_settings_parser::GetProxyPrefValue( - network_guid_, proxy_cros_settings_parser::kProxySettings[i], - GetUiProxyConfigService(), &value); - DCHECK(value); - DispatchPrefChangeNotification( - proxy_cros_settings_parser::kProxySettings[i], std::move(value)); - } -} - -} // namespace options -} // namespace chromeos
diff --git a/chrome/browser/ui/webui/options/chromeos/core_chromeos_options_handler.h b/chrome/browser/ui/webui/options/chromeos/core_chromeos_options_handler.h deleted file mode 100644 index f5ee78b..0000000 --- a/chrome/browser/ui/webui/options/chromeos/core_chromeos_options_handler.h +++ /dev/null
@@ -1,79 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_CORE_CHROMEOS_OPTIONS_HANDLER_H_ -#define CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_CORE_CHROMEOS_OPTIONS_HANDLER_H_ - -#include <map> -#include <memory> -#include <string> - -#include "base/macros.h" -#include "chrome/browser/chromeos/settings/cros_settings.h" -#include "chrome/browser/ui/webui/options/core_options_handler.h" -#include "content/public/browser/notification_observer.h" -#include "content/public/browser/notification_registrar.h" - -namespace chromeos { -namespace options { - -// CoreChromeOSOptionsHandler handles ChromeOS settings. -class CoreChromeOSOptionsHandler : public ::options::CoreOptionsHandler, - public content::NotificationObserver { - public: - CoreChromeOSOptionsHandler(); - ~CoreChromeOSOptionsHandler() override; - - // ::CoreOptionsHandler overrides - void RegisterMessages() override; - std::unique_ptr<base::Value> FetchPref(const std::string& pref_name) override; - void InitializeHandler() override; - void ObservePref(const std::string& pref_name) override; - void SetPref(const std::string& pref_name, - const base::Value* value, - const std::string& metric) override; - void StopObservingPref(const std::string& path) override; - std::unique_ptr<base::Value> CreateValueForPref( - const std::string& pref_name, - const std::string& controlling_pref_name) override; - - // OptionsPageUIHandler implementation. - void GetLocalizedValues(base::DictionaryValue* localized_strings) override; - - // content::NotificationObserver implementation. - void Observe(int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) override; - - private: - void OnPreferenceChanged(PrefService* service, - const std::string& pref_name) override; - - // Called from Javascript to select the network to show proxy settings - // for. Triggers pref notifications about the updated proxy settings. - void SelectNetworkCallback(const base::ListValue* args); - - // Notifies registered JS callbacks on ChromeOS setting change. - void NotifySettingsChanged(const std::string& setting_name); - void NotifyProxyPrefsChanged(); - - // Called on changes to the ownership status. Needed to update the interface - // in case it has been shown before ownership has been fully established. - void NotifyOwnershipChanged(); - - std::map<std::string, std::unique_ptr<CrosSettings::ObserverSubscription>> - pref_subscription_map_; - - content::NotificationRegistrar notification_registrar_; - - // Currently selected network id. - std::string network_guid_; - - DISALLOW_COPY_AND_ASSIGN(CoreChromeOSOptionsHandler); -}; - -} // namespace options -} // namespace chromeos - -#endif // CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_CORE_CHROMEOS_OPTIONS_HANDLER_H_
diff --git a/chrome/browser/ui/webui/options/chromeos/cros_language_options_handler.cc b/chrome/browser/ui/webui/options/chromeos/cros_language_options_handler.cc deleted file mode 100644 index 8811f6ac..0000000 --- a/chrome/browser/ui/webui/options/chromeos/cros_language_options_handler.cc +++ /dev/null
@@ -1,278 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/webui/options/chromeos/cros_language_options_handler.h" - -#include <stddef.h> - -#include <memory> -#include <utility> - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/memory/ptr_util.h" -#include "base/metrics/user_metrics.h" -#include "base/strings/stringprintf.h" -#include "base/strings/utf_string_conversions.h" -#include "base/values.h" -#include "chrome/app/chrome_command_ids.h" -#include "chrome/browser/chromeos/profiles/profile_helper.h" -#include "chrome/browser/extensions/extension_tab_util.h" -#include "chrome/browser/lifetime/application_lifetime.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/browser.h" -#include "chrome/browser/ui/browser_finder.h" -#include "chrome/browser/ui/browser_window.h" -#include "chrome/browser/ui/tabs/tab_strip_model.h" -#include "chrome/browser/ui/webui/chromeos/login/l10n_util.h" -#include "chrome/grit/generated_resources.h" -#include "components/strings/grit/components_strings.h" -#include "components/user_manager/user_manager.h" -#include "components/user_manager/user_type.h" -#include "content/public/browser/navigation_controller.h" -#include "content/public/browser/web_contents.h" -#include "extensions/browser/extension_registry.h" -#include "extensions/common/extension.h" -#include "extensions/common/manifest_url_handlers.h" -#include "ui/base/ime/chromeos/component_extension_ime_manager.h" -#include "ui/base/ime/chromeos/extension_ime_util.h" -#include "ui/base/ime/chromeos/input_method_manager.h" -#include "ui/base/ime/chromeos/input_method_util.h" -#include "ui/base/l10n/l10n_util.h" - -using base::UserMetricsAction; - -namespace chromeos { -namespace options { - -CrosLanguageOptionsHandler::CrosLanguageOptionsHandler() { -} - -CrosLanguageOptionsHandler::~CrosLanguageOptionsHandler() { -} - -void CrosLanguageOptionsHandler::GetLocalizedValues( - base::DictionaryValue* localized_strings) { - ::options::LanguageOptionsHandlerCommon::GetLocalizedValues( - localized_strings); - - RegisterTitle(localized_strings, "languagePage", - IDS_OPTIONS_SETTINGS_LANGUAGES_AND_INPUT_DIALOG_TITLE); - localized_strings->SetString("okButton", l10n_util::GetStringUTF16(IDS_OK)); - localized_strings->SetString("configure", - l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_LANGUAGES_CONFIGURE)); - localized_strings->SetString("inputMethod", - l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_LANGUAGES_INPUT_METHOD)); - localized_strings->SetString("pleaseAddAnotherInputMethod", - l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_LANGUAGES_PLEASE_ADD_ANOTHER_INPUT_METHOD)); - localized_strings->SetString("inputMethodInstructions", - l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_LANGUAGES_INPUT_METHOD_INSTRUCTIONS)); - localized_strings->SetString("switchInputMethodsHint", - l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_LANGUAGES_SWITCH_INPUT_METHODS_HINT)); - localized_strings->SetString("selectPreviousInputMethodHint", - l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_LANGUAGES_SELECT_PREVIOUS_INPUT_METHOD_HINT)); - localized_strings->SetString("restartButton", - l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_LANGUAGES_SIGN_OUT_BUTTON)); - localized_strings->SetString("extensionImeLable", - l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_LANGUAGES_INPUT_METHOD_EXTENSION_IME)); - localized_strings->SetString("extensionImeDescription", - l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_LANGUAGES_INPUT_METHOD_EXTENSION_DESCRIPTION)); - localized_strings->SetString("noInputMethods", - l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_LANGUAGES_NO_INPUT_METHODS)); - localized_strings->SetString("activateImeMenu", - l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_LANGUAGES_ACTIVATE_IME_MENU)); - - // GetSupportedInputMethods() never returns NULL. - localized_strings->Set("languageList", GetAcceptLanguageList()); - localized_strings->Set("inputMethodList", GetInputMethodList()); - - input_method::InputMethodManager* manager = - input_method::InputMethodManager::Get(); - input_method::InputMethodDescriptors ext_ime_descriptors; - manager->GetActiveIMEState()->GetInputMethodExtensions(&ext_ime_descriptors); - - std::unique_ptr<base::ListValue> ext_ime_list = - ConvertInputMethodDescriptorsToIMEList(ext_ime_descriptors); - AddImeProvider(ext_ime_list.get()); - localized_strings->Set("extensionImeList", std::move(ext_ime_list)); - - ComponentExtensionIMEManager* component_extension_manager = - input_method::InputMethodManager::Get() - ->GetComponentExtensionIMEManager(); - localized_strings->Set( - "componentExtensionImeList", - ConvertInputMethodDescriptorsToIMEList( - component_extension_manager->GetAllIMEAsInputMethodDescriptor())); -} - -void CrosLanguageOptionsHandler::RegisterMessages() { - ::options::LanguageOptionsHandlerCommon::RegisterMessages(); - - web_ui()->RegisterMessageCallback("inputMethodDisable", - base::Bind(&CrosLanguageOptionsHandler::InputMethodDisableCallback, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("inputMethodEnable", - base::Bind(&CrosLanguageOptionsHandler::InputMethodEnableCallback, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("inputMethodOptionsOpen", - base::Bind(&CrosLanguageOptionsHandler::InputMethodOptionsOpenCallback, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("uiLanguageRestart", - base::Bind(&CrosLanguageOptionsHandler::RestartCallback, - base::Unretained(this))); -} - -// static -std::unique_ptr<base::ListValue> -CrosLanguageOptionsHandler::GetInputMethodList() { - input_method::InputMethodManager* manager = - input_method::InputMethodManager::Get(); - // GetSupportedInputMethods() never return NULL. - std::unique_ptr<input_method::InputMethodDescriptors> descriptors( - manager->GetSupportedInputMethods()); - - auto input_method_list = base::MakeUnique<base::ListValue>(); - - for (size_t i = 0; i < descriptors->size(); ++i) { - const input_method::InputMethodDescriptor& descriptor = - (*descriptors)[i]; - const std::string display_name = - manager->GetInputMethodUtil()->GetInputMethodDisplayNameFromId( - descriptor.id()); - auto dictionary = base::MakeUnique<base::DictionaryValue>(); - dictionary->SetString("id", descriptor.id()); - dictionary->SetString("displayName", display_name); - - // One input method can be associated with multiple languages, hence - // we use a dictionary here. - auto languages = base::MakeUnique<base::DictionaryValue>(); - for (size_t i = 0; i < descriptor.language_codes().size(); ++i) { - languages->SetBoolean(descriptor.language_codes().at(i), true); - } - dictionary->Set("languageCodeSet", std::move(languages)); - - input_method_list->Append(std::move(dictionary)); - } - - return input_method_list; -} - -std::unique_ptr<base::ListValue> -CrosLanguageOptionsHandler::ConvertInputMethodDescriptorsToIMEList( - const input_method::InputMethodDescriptors& descriptors) { - input_method::InputMethodUtil* util = - input_method::InputMethodManager::Get()->GetInputMethodUtil(); - std::unique_ptr<base::ListValue> ime_ids_list(new base::ListValue()); - for (size_t i = 0; i < descriptors.size(); ++i) { - const input_method::InputMethodDescriptor& descriptor = descriptors[i]; - std::unique_ptr<base::DictionaryValue> dictionary( - new base::DictionaryValue()); - dictionary->SetString("id", descriptor.id()); - dictionary->SetString( - "displayName", util->GetLocalizedDisplayName(descriptor)); - dictionary->SetString("optionsPage", descriptor.options_page_url().spec()); - std::unique_ptr<base::DictionaryValue> language_codes( - new base::DictionaryValue()); - for (size_t i = 0; i < descriptor.language_codes().size(); ++i) - language_codes->SetBoolean(descriptor.language_codes().at(i), true); - dictionary->Set("languageCodeSet", std::move(language_codes)); - ime_ids_list->Append(std::move(dictionary)); - } - return ime_ids_list; -} - -void CrosLanguageOptionsHandler::SetApplicationLocale( - const std::string& language_code) { - Profile* profile = Profile::FromWebUI(web_ui()); - user_manager::UserManager* user_manager = user_manager::UserManager::Get(); - - // Secondary users and public session users cannot change the locale. - const user_manager::User* user = - ProfileHelper::Get()->GetUserByProfile(profile); - if (user && - user->GetAccountId() == user_manager->GetPrimaryUser()->GetAccountId() && - user->GetType() != user_manager::USER_TYPE_PUBLIC_ACCOUNT) { - profile->ChangeAppLocale(language_code, - Profile::APP_LOCALE_CHANGED_VIA_SETTINGS); - } -} - -void CrosLanguageOptionsHandler::RestartCallback(const base::ListValue* args) { - base::RecordAction(UserMetricsAction("LanguageOptions_SignOut")); - chrome::AttemptUserExit(); -} - -void CrosLanguageOptionsHandler::InputMethodDisableCallback( - const base::ListValue* args) { - const std::string input_method_id = - base::UTF16ToASCII(ExtractStringValue(args)); - const std::string action = base::StringPrintf( - "LanguageOptions_DisableInputMethod_%s", input_method_id.c_str()); - base::RecordComputedAction(action); -} - -void CrosLanguageOptionsHandler::InputMethodEnableCallback( - const base::ListValue* args) { - const std::string input_method_id = - base::UTF16ToASCII(ExtractStringValue(args)); - const std::string action = base::StringPrintf( - "LanguageOptions_EnableInputMethod_%s", input_method_id.c_str()); - base::RecordComputedAction(action); -} - -void CrosLanguageOptionsHandler::InputMethodOptionsOpenCallback( - const base::ListValue* args) { - const std::string input_method_id = - base::UTF16ToASCII(ExtractStringValue(args)); - const std::string extension_id = - extension_ime_util::GetExtensionIDFromInputMethodID(input_method_id); - if (extension_id.empty()) - return; - - const input_method::InputMethodDescriptor* ime = - input_method::InputMethodManager::Get() - ->GetActiveIMEState() - ->GetInputMethodFromId(input_method_id); - if (!ime) - return; - - Browser* browser = chrome::FindBrowserWithWebContents( - web_ui()->GetWebContents()); - content::OpenURLParams params(ime->options_page_url(), content::Referrer(), - WindowOpenDisposition::SINGLETON_TAB, - ui::PAGE_TRANSITION_LINK, false); - browser->OpenURL(params); -} - -void CrosLanguageOptionsHandler::AddImeProvider(base::ListValue* list) { - Profile* profile = Profile::FromWebUI(web_ui()); - const extensions::ExtensionSet& enabled_extensions = - extensions::ExtensionRegistry::Get(profile)->enabled_extensions(); - for (size_t i = 0; i < list->GetSize(); ++i) { - base::DictionaryValue* entry; - list->GetDictionary(i, &entry); - - std::string input_method_id; - entry->GetString("id", &input_method_id); - - std::string extension_id = - extension_ime_util::GetExtensionIDFromInputMethodID(input_method_id); - const extensions::Extension* extension = - enabled_extensions.GetByID(extension_id); - if (extension) - entry->SetString("extensionName", extension->name()); - } -} - -} // namespace options -} // namespace chromeos
diff --git a/chrome/browser/ui/webui/options/chromeos/cros_language_options_handler.h b/chrome/browser/ui/webui/options/chromeos/cros_language_options_handler.h deleted file mode 100644 index 0a657c14..0000000 --- a/chrome/browser/ui/webui/options/chromeos/cros_language_options_handler.h +++ /dev/null
@@ -1,86 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_CROS_LANGUAGE_OPTIONS_HANDLER_H_ -#define CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_CROS_LANGUAGE_OPTIONS_HANDLER_H_ - -#include <memory> -#include <string> - -#include "base/compiler_specific.h" -#include "base/macros.h" -#include "chrome/browser/ui/webui/options/language_options_handler.h" -#include "ui/base/ime/chromeos/component_extension_ime_manager.h" -#include "ui/base/ime/chromeos/input_method_descriptor.h" - -namespace base { -class ListValue; -} - -namespace chromeos { -namespace options { - -// Language options page UI handler for Chrome OS. For non-Chrome OS, -// see LanguageOptionsHnadler. -class CrosLanguageOptionsHandler - : public ::options::LanguageOptionsHandlerCommon { - public: - CrosLanguageOptionsHandler(); - ~CrosLanguageOptionsHandler() override; - - // OptionsPageUIHandler implementation. - void GetLocalizedValues(base::DictionaryValue* localized_strings) override; - - // DOMMessageHandler implementation. - void RegisterMessages() override; - - // The following static methods are public for ease of testing. - - // Gets the list of supported input methods. - // The return value will look like: - // [{'id': 'pinyin', 'displayName': 'Pinyin', - // 'languageCodeSet': {'zh-CW': true}}, ...] - // - // Note that true in languageCodeSet does not mean anything. We just use - // the dictionary as a set. - static std::unique_ptr<base::ListValue> GetInputMethodList(); - - // Converts input method descriptors to the list of input methods. - // The return value will look like: - // [{'id': '_ext_ime_nejguenhnsnjnwychcnsdsdjketest', - // 'displayName': 'Sample IME'}, ...] - static std::unique_ptr<base::ListValue> - ConvertInputMethodDescriptorsToIMEList( - const input_method::InputMethodDescriptors& descriptors); - - private: - // LanguageOptionsHandlerCommon implementation. - void SetApplicationLocale(const std::string& language_code) override; - - // Called when the sign-out button is clicked. - void RestartCallback(const base::ListValue* args); - - // Called when the input method is disabled. - // |args| will contain the input method ID as string (ex. "mozc"). - void InputMethodDisableCallback(const base::ListValue* args); - - // Called when the input method is enabled. - // |args| will contain the input method ID as string (ex. "mozc"). - void InputMethodEnableCallback(const base::ListValue* args); - - // Called when the input method options page is opened. - // |args| will contain the input method ID as string (ex. "mozc"). - void InputMethodOptionsOpenCallback(const base::ListValue* args); - - // Adds the name of the extension that provides the IME to each entry in the - // |list| of extension IMEs. - void AddImeProvider(base::ListValue* list); - - DISALLOW_COPY_AND_ASSIGN(CrosLanguageOptionsHandler); -}; - -} // namespace options -} // namespace chromeos - -#endif // CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_CROS_LANGUAGE_OPTIONS_HANDLER_H_
diff --git a/chrome/browser/ui/webui/options/chromeos/date_time_options_handler.cc b/chrome/browser/ui/webui/options/chromeos/date_time_options_handler.cc deleted file mode 100644 index c26fe069..0000000 --- a/chrome/browser/ui/webui/options/chromeos/date_time_options_handler.cc +++ /dev/null
@@ -1,77 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/webui/options/chromeos/date_time_options_handler.h" - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/values.h" -#include "chrome/browser/chromeos/set_time_dialog.h" -#include "chrome/grit/generated_resources.h" -#include "chromeos/dbus/dbus_thread_manager.h" -#include "chromeos/dbus/system_clock_client.h" -#include "content/public/browser/web_contents.h" -#include "content/public/browser/web_ui.h" -#include "ui/base/l10n/l10n_util.h" - -namespace chromeos { -namespace options { - -DateTimeOptionsHandler::DateTimeOptionsHandler() - : can_set_time_(false), page_initialized_(false) { -} - -DateTimeOptionsHandler::~DateTimeOptionsHandler() { - DBusThreadManager::Get()->GetSystemClockClient()->RemoveObserver(this); -} - -void DateTimeOptionsHandler::GetLocalizedValues( - base::DictionaryValue* localized_strings) { - DCHECK(localized_strings); - - localized_strings->SetString( - "setTimeButton", - l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_SET_TIME_BUTTON)); -} - -void DateTimeOptionsHandler::InitializeHandler() { - SystemClockClient* system_clock_client = - DBusThreadManager::Get()->GetSystemClockClient(); - system_clock_client->AddObserver(this); - - can_set_time_ = system_clock_client->CanSetTime(); - SystemClockCanSetTimeChanged(can_set_time_); -} - -void DateTimeOptionsHandler::InitializePage() { - page_initialized_ = true; - SystemClockCanSetTimeChanged(can_set_time_); -} - -void DateTimeOptionsHandler::RegisterMessages() { - // Callback for set time button. - web_ui()->RegisterMessageCallback( - "showSetTime", - base::Bind(&DateTimeOptionsHandler::HandleShowSetTime, - base::Unretained(this))); -} - -void DateTimeOptionsHandler::SystemClockCanSetTimeChanged(bool can_set_time) { - if (page_initialized_) { - web_ui()->CallJavascriptFunctionUnsafe("BrowserOptions.setCanSetTime", - base::Value(can_set_time)); - } - can_set_time_ = can_set_time; -} - -void DateTimeOptionsHandler::HandleShowSetTime(const base::ListValue* args) { - // Make sure the clock status hasn't changed since the button was clicked. - if (can_set_time_) { - SetTimeDialog::ShowDialogInParent( - web_ui()->GetWebContents()->GetTopLevelNativeWindow()); - } -} - -} // namespace options -} // namespace chromeos
diff --git a/chrome/browser/ui/webui/options/chromeos/date_time_options_handler.h b/chrome/browser/ui/webui/options/chromeos/date_time_options_handler.h deleted file mode 100644 index 8313d8a..0000000 --- a/chrome/browser/ui/webui/options/chromeos/date_time_options_handler.h +++ /dev/null
@@ -1,47 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_DATE_TIME_OPTIONS_HANDLER_H_ -#define CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_DATE_TIME_OPTIONS_HANDLER_H_ - -#include "base/compiler_specific.h" -#include "base/macros.h" -#include "chrome/browser/ui/webui/options/options_ui.h" -#include "chromeos/dbus/system_clock_client.h" - -namespace chromeos { -namespace options { - -// Chrome OS handler for the set date/time link in the Advanced settings page. -class DateTimeOptionsHandler : public ::options::OptionsPageUIHandler, - public SystemClockClient::Observer { - public: - DateTimeOptionsHandler(); - ~DateTimeOptionsHandler() override; - - // OptionsPageUIHandler: - void GetLocalizedValues(base::DictionaryValue* localized_strings) override; - void InitializeHandler() override; - void InitializePage() override; - void RegisterMessages() override; - - private: - // SystemClockClient::Observer: - void SystemClockCanSetTimeChanged(bool can_set_time) override; - - // Callback for the "showSetTime" message to show the set time dialog. No - // arguments are expected. - void HandleShowSetTime(const base::ListValue* args); - - // Only expose the button and dialog if the system time can be set. - bool can_set_time_; - bool page_initialized_; - - DISALLOW_COPY_AND_ASSIGN(DateTimeOptionsHandler); -}; - -} // namespace options -} // namespace chromeos - -#endif // CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_DATE_TIME_OPTIONS_HANDLER_H_
diff --git a/chrome/browser/ui/webui/options/chromeos/display_options_handler.cc b/chrome/browser/ui/webui/options/chromeos/display_options_handler.cc deleted file mode 100644 index f18f3b2..0000000 --- a/chrome/browser/ui/webui/options/chromeos/display_options_handler.cc +++ /dev/null
@@ -1,581 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/webui/options/chromeos/display_options_handler.h" - -#include <stddef.h> -#include <stdint.h> - -#include <memory> -#include <string> -#include <utility> - -#include "ash/display/display_configuration_controller.h" -#include "ash/display/resolution_notification_controller.h" -#include "ash/display/window_tree_host_manager.h" -#include "ash/shell.h" -#include "ash/strings/grit/ash_strings.h" -#include "base/bind.h" -#include "base/command_line.h" -#include "base/logging.h" -#include "base/memory/ptr_util.h" -#include "base/metrics/user_metrics.h" -#include "base/strings/string_number_conversions.h" -#include "base/values.h" -#include "chrome/browser/chromeos/display/display_preferences.h" -#include "chrome/browser/ui/ash/ash_util.h" -#include "chrome/grit/generated_resources.h" -#include "chromeos/chromeos_switches.h" -#include "content/public/browser/web_ui.h" -#include "ui/base/l10n/l10n_util.h" -#include "ui/display/display.h" -#include "ui/display/display_layout.h" -#include "ui/display/display_layout_builder.h" -#include "ui/display/manager/display_manager.h" -#include "ui/display/screen.h" -#include "ui/display/types/display_constants.h" -#include "ui/gfx/geometry/rect.h" -#include "ui/gfx/geometry/size_conversions.h" - -namespace chromeos { -namespace options { -namespace { - -display::DisplayManager* GetDisplayManager() { - return ash::Shell::Get()->display_manager(); -} - -ash::DisplayConfigurationController* GetDisplayConfigurationController() { - return ash::Shell::Get()->display_configuration_controller(); -} - -int64_t GetDisplayIdFromValue(const base::Value* arg) { - std::string id_value; - if (!arg->GetAsString(&id_value)) - return display::kInvalidDisplayId; - int64_t display_id = display::kInvalidDisplayId; - if (!base::StringToInt64(id_value, &display_id)) - return display::kInvalidDisplayId; - return display_id; -} - -int64_t GetDisplayIdFromArgs(const base::ListValue* args) { - const base::Value* arg; - if (!args->Get(0, &arg)) { - LOG(ERROR) << "No display id arg"; - return display::kInvalidDisplayId; - } - int64_t display_id = GetDisplayIdFromValue(arg); - if (display_id == display::kInvalidDisplayId) - LOG(ERROR) << "Invalid display id: " << *arg; - return display_id; -} - -int64_t GetDisplayIdFromDictionary(const base::DictionaryValue* dictionary, - const std::string& key) { - const base::Value* arg; - if (!dictionary->Get(key, &arg)) - return display::kInvalidDisplayId; - return GetDisplayIdFromValue(arg); -} - -base::string16 GetColorProfileName(display::ColorCalibrationProfile profile) { - switch (profile) { - case display::COLOR_PROFILE_STANDARD: - return l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_DISPLAY_OPTIONS_COLOR_PROFILE_STANDARD); - case display::COLOR_PROFILE_DYNAMIC: - return l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_DISPLAY_OPTIONS_COLOR_PROFILE_DYNAMIC); - case display::COLOR_PROFILE_MOVIE: - return l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_DISPLAY_OPTIONS_COLOR_PROFILE_MOVIE); - case display::COLOR_PROFILE_READING: - return l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_DISPLAY_OPTIONS_COLOR_PROFILE_READING); - case display::NUM_COLOR_PROFILES: - break; - } - - NOTREACHED(); - return base::string16(); -} - -int GetIntOrDouble(const base::DictionaryValue* dict, - const std::string& field) { - double double_result = 0; - if (dict->GetDouble(field, &double_result)) - return static_cast<int>(double_result); - - int result = 0; - dict->GetInteger(field, &result); - return result; -} - -bool GetFloat(const base::DictionaryValue* dict, - const std::string& field, - float* result) { - double double_result = 0; - if (dict->GetDouble(field, &double_result)) { - *result = static_cast<float>(double_result); - return true; - } - return false; -} - -scoped_refptr<display::ManagedDisplayMode> ConvertValueToManagedDisplayMode( - const base::DictionaryValue* dict) { - scoped_refptr<display::ManagedDisplayMode> mode; - - gfx::Size size; - size.set_width(GetIntOrDouble(dict, "originalWidth")); - size.set_height(GetIntOrDouble(dict, "originalHeight")); - - if (size.IsEmpty()) { - LOG(ERROR) << "missing width or height."; - return mode; - } - - float refresh_rate, ui_scale, device_scale_factor; - if (!GetFloat(dict, "refreshRate", &refresh_rate)) { - LOG(ERROR) << "missing refreshRate."; - return mode; - } - if (!GetFloat(dict, "scale", &ui_scale)) { - LOG(ERROR) << "missing ui-scale."; - return mode; - } - if (!GetFloat(dict, "deviceScaleFactor", &device_scale_factor)) { - LOG(ERROR) << "missing deviceScaleFactor."; - return mode; - } - - // Used to select the actual mode. - mode = new display::ManagedDisplayMode( - size, refresh_rate, false /* interlaced */, false /* native */, ui_scale, - device_scale_factor); - return mode; -} - -std::unique_ptr<base::DictionaryValue> ConvertDisplayModeToValue( - int64_t display_id, - const scoped_refptr<display::ManagedDisplayMode>& mode) { - bool is_internal = display::Display::HasInternalDisplay() && - display::Display::InternalDisplayId() == display_id; - auto result = base::MakeUnique<base::DictionaryValue>(); - gfx::Size size_dip = mode->GetSizeInDIP(is_internal); - result->SetInteger("width", size_dip.width()); - result->SetInteger("height", size_dip.height()); - result->SetInteger("originalWidth", mode->size().width()); - result->SetInteger("originalHeight", mode->size().height()); - result->SetDouble("deviceScaleFactor", mode->device_scale_factor()); - result->SetDouble("scale", mode->ui_scale()); - result->SetDouble("refreshRate", mode->refresh_rate()); - result->SetBoolean("isBest", - is_internal ? (mode->ui_scale() == 1.0f) : mode->native()); - result->SetBoolean("isNative", mode->native()); - result->SetBoolean( - "selected", - mode->IsEquivalent( - GetDisplayManager()->GetActiveModeForDisplayId(display_id))); - return result; -} - -std::unique_ptr<base::DictionaryValue> ConvertBoundsToValue( - const gfx::Rect& bounds) { - auto result = base::MakeUnique<base::DictionaryValue>(); - result->SetInteger("left", bounds.x()); - result->SetInteger("top", bounds.y()); - result->SetInteger("width", bounds.width()); - result->SetInteger("height", bounds.height()); - return result; -} - -} // namespace - -DisplayOptionsHandler::DisplayOptionsHandler() { - // TODO(mash) Support Chrome display settings in Mash. crbug.com/548429 - if (!ash_util::IsRunningInMash()) - ash::Shell::Get()->window_tree_host_manager()->AddObserver(this); -} - -DisplayOptionsHandler::~DisplayOptionsHandler() { - // TODO(mash) Support Chrome display settings in Mash. crbug.com/548429 - if (!ash_util::IsRunningInMash()) - ash::Shell::Get()->window_tree_host_manager()->RemoveObserver(this); -} - -void DisplayOptionsHandler::GetLocalizedValues( - base::DictionaryValue* localized_strings) { - DCHECK(localized_strings); - RegisterTitle(localized_strings, "displayOptionsPage", - IDS_OPTIONS_SETTINGS_DISPLAY_OPTIONS_TAB_TITLE); - - localized_strings->SetString( - "selectedDisplayTitleOptions", l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_DISPLAY_OPTIONS_OPTIONS)); - localized_strings->SetString( - "selectedDisplayTitleResolution", l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_DISPLAY_OPTIONS_RESOLUTION)); - localized_strings->SetString( - "selectedDisplayTitleOrientation", l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_DISPLAY_OPTIONS_ORIENTATION)); - localized_strings->SetString( - "selectedDisplayTitleOverscan", l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_DISPLAY_OPTIONS_OVERSCAN)); - - localized_strings->SetString("extendedMode", l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_DISPLAY_OPTIONS_EXTENDED_MODE_LABEL)); - localized_strings->SetString("mirroringMode", l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_DISPLAY_OPTIONS_MIRRORING_MODE_LABEL)); - localized_strings->SetString("mirroringDisplay", l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_DISPLAY_OPTIONS_MIRRORING_DISPLAY_NAME)); - localized_strings->SetString("setPrimary", l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_DISPLAY_OPTIONS_SET_PRIMARY)); - localized_strings->SetString("annotateBest", l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_DISPLAY_OPTIONS_RESOLUTION_ANNOTATION_BEST)); - localized_strings->SetString("annotateNative", l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_DISPLAY_OPTIONS_RESOLUTION_ANNOTATION_NATIVE)); - localized_strings->SetString("orientation0", l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_DISPLAY_OPTIONS_STANDARD_ORIENTATION)); - localized_strings->SetString("orientation90", l10n_util::GetStringUTF16( - IDS_ASH_STATUS_TRAY_DISPLAY_ORIENTATION_90)); - localized_strings->SetString("orientation180", l10n_util::GetStringUTF16( - IDS_ASH_STATUS_TRAY_DISPLAY_ORIENTATION_180)); - localized_strings->SetString("orientation270", l10n_util::GetStringUTF16( - IDS_ASH_STATUS_TRAY_DISPLAY_ORIENTATION_270)); - localized_strings->SetString( - "startCalibratingOverscan", l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_DISPLAY_OPTIONS_START_CALIBRATING_OVERSCAN)); - localized_strings->SetString( - "selectedDisplayColorProfile", l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_DISPLAY_OPTIONS_COLOR_PROFILE)); - localized_strings->SetString( - "enableUnifiedDesktop", - l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_DISPLAY_OPTIONS_ENABLE_UNIFIED_DESKTOP)); -} - -void DisplayOptionsHandler::InitializePage() { - DCHECK(web_ui()); - UpdateDisplaySettingsEnabled(); -} - -void DisplayOptionsHandler::RegisterMessages() { - web_ui()->RegisterMessageCallback( - "getDisplayInfo", - base::Bind(&DisplayOptionsHandler::HandleDisplayInfo, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "setMirroring", - base::Bind(&DisplayOptionsHandler::HandleMirroring, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "setPrimary", - base::Bind(&DisplayOptionsHandler::HandleSetPrimary, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "setDisplayLayout", - base::Bind(&DisplayOptionsHandler::HandleSetDisplayLayout, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "setDisplayMode", - base::Bind(&DisplayOptionsHandler::HandleSetDisplayMode, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "setRotation", - base::Bind(&DisplayOptionsHandler::HandleSetRotation, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "setColorProfile", - base::Bind(&DisplayOptionsHandler::HandleSetColorProfile, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "setUnifiedDesktopEnabled", - base::Bind(&DisplayOptionsHandler::HandleSetUnifiedDesktopEnabled, - base::Unretained(this))); -} - -void DisplayOptionsHandler::OnDisplayConfigurationChanging() { -} - -void DisplayOptionsHandler::OnDisplayConfigurationChanged() { - UpdateDisplaySettingsEnabled(); - SendAllDisplayInfo(); -} - -void DisplayOptionsHandler::SendAllDisplayInfo() { - display::DisplayManager* display_manager = GetDisplayManager(); - - std::vector<display::Display> displays; - for (size_t i = 0; i < display_manager->GetNumDisplays(); ++i) - displays.push_back(display_manager->GetDisplayAt(i)); - - display::DisplayManager::MultiDisplayMode display_mode; - if (display_manager->IsInMirrorMode()) - display_mode = display::DisplayManager::MIRRORING; - else if (display_manager->IsInUnifiedMode()) - display_mode = display::DisplayManager::UNIFIED; - else - display_mode = display::DisplayManager::EXTENDED; - base::Value mode(static_cast<int>(display_mode)); - - int64_t primary_id = display::Screen::GetScreen()->GetPrimaryDisplay().id(); - std::unique_ptr<base::ListValue> js_displays(new base::ListValue); - for (const display::Display& display : displays) { - const display::ManagedDisplayInfo& display_info = - display_manager->GetDisplayInfo(display.id()); - auto js_display = base::MakeUnique<base::DictionaryValue>(); - js_display->SetString("id", base::Int64ToString(display.id())); - js_display->SetString("name", - display_manager->GetDisplayNameForId(display.id())); - js_display->Set("bounds", ConvertBoundsToValue(display.bounds())); - js_display->SetBoolean("isPrimary", display.id() == primary_id); - js_display->SetBoolean("isInternal", display.IsInternal()); - js_display->SetInteger("rotation", display.RotationAsDegree()); - - auto js_resolutions = base::MakeUnique<base::ListValue>(); - for (const scoped_refptr<display::ManagedDisplayMode>& display_mode : - display_info.display_modes()) { - js_resolutions->Append( - ConvertDisplayModeToValue(display.id(), display_mode)); - } - js_display->Set("resolutions", std::move(js_resolutions)); - - js_display->SetInteger("colorProfileId", display_info.color_profile()); - auto available_color_profiles = base::MakeUnique<base::ListValue>(); - for (const auto& color_profile : display_info.available_color_profiles()) { - const base::string16 profile_name = GetColorProfileName(color_profile); - if (profile_name.empty()) - continue; - auto color_profile_dict = base::MakeUnique<base::DictionaryValue>(); - color_profile_dict->SetInteger("profileId", color_profile); - color_profile_dict->SetString("name", profile_name); - available_color_profiles->Append(std::move(color_profile_dict)); - } - js_display->Set("availableColorProfiles", - std::move(available_color_profiles)); - - if (display_manager->GetNumDisplays() > 1) { - // The settings UI must use the resolved display layout to show the - // actual applied layout. - const display::DisplayPlacement placement = - display_manager->GetCurrentResolvedDisplayLayout().FindPlacementById( - display.id()); - if (placement.display_id != display::kInvalidDisplayId) { - js_display->SetString( - "parentId", base::Int64ToString(placement.parent_display_id)); - js_display->SetInteger("layoutType", placement.position); - js_display->SetInteger("offset", placement.offset); - } - } - - js_displays->Append(std::move(js_display)); - } - - web_ui()->CallJavascriptFunctionUnsafe( - "options.DisplayOptions.setDisplayInfo", mode, *js_displays); -} - -void DisplayOptionsHandler::UpdateDisplaySettingsEnabled() { - // TODO(mash) Support Chrome display settings in Mash. crbug.com/548429 - if (ash_util::IsRunningInMash()) - return; - - display::DisplayManager* display_manager = GetDisplayManager(); - bool disable_multi_display_layout = - base::CommandLine::ForCurrentProcess()->HasSwitch( - chromeos::switches::kDisableMultiDisplayLayout); - bool ui_enabled = display_manager->num_connected_displays() <= 2 || - !disable_multi_display_layout; - bool unified_enabled = display_manager->unified_desktop_enabled(); - bool mirrored_enabled = display_manager->num_connected_displays() == 2; - - web_ui()->CallJavascriptFunctionUnsafe( - "options.BrowserOptions.enableDisplaySettings", base::Value(ui_enabled), - base::Value(unified_enabled), base::Value(mirrored_enabled)); -} - -void DisplayOptionsHandler::HandleDisplayInfo( - const base::ListValue* unused_args) { - SendAllDisplayInfo(); -} - -void DisplayOptionsHandler::HandleMirroring(const base::ListValue* args) { - DCHECK(!args->empty()); - bool is_mirroring = false; - if (!args->GetBoolean(0, &is_mirroring)) - NOTREACHED(); - base::RecordAction(base::UserMetricsAction("Options_DisplayToggleMirroring")); - GetDisplayConfigurationController()->SetMirrorMode(is_mirroring); -} - -void DisplayOptionsHandler::HandleSetPrimary(const base::ListValue* args) { - DCHECK(!args->empty()); - int64_t display_id = GetDisplayIdFromArgs(args); - if (display_id == display::kInvalidDisplayId) - return; - - base::RecordAction(base::UserMetricsAction("Options_DisplaySetPrimary")); - GetDisplayConfigurationController()->SetPrimaryDisplayId(display_id); -} - -void DisplayOptionsHandler::HandleSetDisplayLayout( - const base::ListValue* args) { - const base::ListValue* layouts = nullptr; - if (!args->GetList(0, &layouts)) - NOTREACHED(); - base::RecordAction(base::UserMetricsAction("Options_DisplayRearrange")); - - display::DisplayManager* display_manager = GetDisplayManager(); - display::DisplayLayoutBuilder builder( - display_manager->GetCurrentDisplayLayout()); - builder.ClearPlacements(); - for (const auto& layout : *layouts) { - const base::DictionaryValue* dictionary; - if (!layout.GetAsDictionary(&dictionary)) { - LOG(ERROR) << "Invalid layout dictionary: " << *dictionary; - continue; - } - - int64_t parent_id = GetDisplayIdFromDictionary(dictionary, "parentId"); - if (parent_id == display::kInvalidDisplayId) - continue; // No placement for root (primary) display. - - int64_t display_id = GetDisplayIdFromDictionary(dictionary, "id"); - if (display_id == display::kInvalidDisplayId) { - LOG(ERROR) << "Invalud display id in layout dictionary: " << *dictionary; - continue; - } - - int position = 0; - dictionary->GetInteger("layoutType", &position); - int offset = 0; - dictionary->GetInteger("offset", &offset); - - builder.AddDisplayPlacement( - display_id, parent_id, - static_cast<display::DisplayPlacement::Position>(position), offset); - } - std::unique_ptr<display::DisplayLayout> layout = builder.Build(); - if (!display::DisplayLayout::Validate( - display_manager->GetCurrentDisplayIdList(), *layout)) { - LOG(ERROR) << "Invalid layout: " << layout->ToString(); - return; - } - - VLOG(1) << "Updating display layout: " << layout->ToString(); - GetDisplayConfigurationController()->SetDisplayLayout(std::move(layout)); -} - -void DisplayOptionsHandler::HandleSetDisplayMode(const base::ListValue* args) { - DCHECK(!args->empty()); - - int64_t display_id = GetDisplayIdFromArgs(args); - if (display_id == display::kInvalidDisplayId) - return; - - const base::DictionaryValue* mode_data = nullptr; - if (!args->GetDictionary(1, &mode_data)) { - LOG(ERROR) << "Failed to get mode data"; - return; - } - - scoped_refptr<display::ManagedDisplayMode> mode = - ConvertValueToManagedDisplayMode(mode_data); - if (!mode) - return; - - base::RecordAction(base::UserMetricsAction("Options_DisplaySetResolution")); - display::DisplayManager* display_manager = GetDisplayManager(); - scoped_refptr<display::ManagedDisplayMode> current_mode = - display_manager->GetActiveModeForDisplayId(display_id); - - if (mode->IsEquivalent(current_mode)) { - LOG(ERROR) << "New display mode matches current mode."; - return; - } - - if (!ash::Shell::Get() - ->resolution_notification_controller() - ->PrepareNotificationAndSetDisplayMode( - display_id, current_mode, mode, - base::Bind(&chromeos::StoreDisplayPrefs))) { - LOG(ERROR) << "Unable to set display mode for: " << display_id - << " Mode: " << *mode_data; - } -} - -void DisplayOptionsHandler::HandleSetRotation(const base::ListValue* args) { - DCHECK(!args->empty()); - - int64_t display_id = GetDisplayIdFromArgs(args); - if (display_id == display::kInvalidDisplayId) - return; - - int rotation_value = 0; - if (!args->GetInteger(1, &rotation_value)) { - LOG(ERROR) << "Can't parse rotation: " << args; - return; - } - display::Display::Rotation new_rotation = display::Display::ROTATE_0; - if (rotation_value == 90) - new_rotation = display::Display::ROTATE_90; - else if (rotation_value == 180) - new_rotation = display::Display::ROTATE_180; - else if (rotation_value == 270) - new_rotation = display::Display::ROTATE_270; - else if (rotation_value != 0) - LOG(ERROR) << "Invalid rotation: " << rotation_value << " Falls back to 0"; - - base::RecordAction(base::UserMetricsAction("Options_DisplaySetOrientation")); - GetDisplayConfigurationController()->SetDisplayRotation( - display_id, new_rotation, display::Display::ROTATION_SOURCE_USER); -} - -void DisplayOptionsHandler::HandleSetColorProfile(const base::ListValue* args) { - DCHECK(!args->empty()); - int64_t display_id = GetDisplayIdFromArgs(args); - if (display_id == display::kInvalidDisplayId) - return; - - std::string profile_value; - if (!args->GetString(1, &profile_value)) { - LOG(ERROR) << "Invalid profile_value"; - return; - } - - int profile_id; - if (!base::StringToInt(profile_value, &profile_id)) { - LOG(ERROR) << "Invalid profile: " << profile_value; - return; - } - - if (profile_id < display::COLOR_PROFILE_STANDARD || - profile_id > display::COLOR_PROFILE_READING) { - LOG(ERROR) << "Invalid profile_id: " << profile_id; - return; - } - - base::RecordAction(base::UserMetricsAction("Options_DisplaySetColorProfile")); - GetDisplayManager()->SetColorCalibrationProfile( - display_id, static_cast<display::ColorCalibrationProfile>(profile_id)); - - SendAllDisplayInfo(); -} - -void DisplayOptionsHandler::HandleSetUnifiedDesktopEnabled( - const base::ListValue* args) { - DCHECK(GetDisplayManager()->unified_desktop_enabled()); - bool enable = false; - if (!args->GetBoolean(0, &enable)) - NOTREACHED(); - - GetDisplayManager()->SetDefaultMultiDisplayModeForCurrentDisplays( - enable ? display::DisplayManager::UNIFIED - : display::DisplayManager::EXTENDED); -} - -} // namespace options -} // namespace chromeos
diff --git a/chrome/browser/ui/webui/options/chromeos/display_options_handler.h b/chrome/browser/ui/webui/options/chromeos/display_options_handler.h deleted file mode 100644 index 3f93b9a6..0000000 --- a/chrome/browser/ui/webui/options/chromeos/display_options_handler.h +++ /dev/null
@@ -1,63 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_DISPLAY_OPTIONS_HANDLER_H_ -#define CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_DISPLAY_OPTIONS_HANDLER_H_ - -#include <vector> - -#include "ash/display/window_tree_host_manager.h" -#include "base/macros.h" -#include "chrome/browser/ui/webui/options/options_ui.h" - -namespace base { -class DictionaryValue; -class ListValue; -} - -namespace chromeos { -namespace options { - -// Display options overlay page UI handler. -class DisplayOptionsHandler : public ::options::OptionsPageUIHandler, - public ash::WindowTreeHostManager::Observer { - public: - DisplayOptionsHandler(); - ~DisplayOptionsHandler() override; - - // OptionsPageUIHandler implementation. - void GetLocalizedValues(base::DictionaryValue* localized_strings) override; - void InitializePage() override; - - // WebUIMessageHandler implementation. - void RegisterMessages() override; - - // ash::WindowTreeHostManager::Observer implementation. - void OnDisplayConfigurationChanging() override; - void OnDisplayConfigurationChanged() override; - - private: - // Sends all of the current display information to the web_ui of options page. - void SendAllDisplayInfo(); - - // Enables or disables the display settings UI. - void UpdateDisplaySettingsEnabled(); - - // Handlers of JS messages. - void HandleDisplayInfo(const base::ListValue* unused_args); - void HandleMirroring(const base::ListValue* args); - void HandleSetPrimary(const base::ListValue* args); - void HandleSetDisplayLayout(const base::ListValue* args); - void HandleSetDisplayMode(const base::ListValue* args); - void HandleSetRotation(const base::ListValue* args); - void HandleSetColorProfile(const base::ListValue* args); - void HandleSetUnifiedDesktopEnabled(const base::ListValue* args); - - DISALLOW_COPY_AND_ASSIGN(DisplayOptionsHandler); -}; - -} // namespace options -} // namespace chromeos - -#endif // CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_DISPLAY_OPTIONS_HANDLER_H_
diff --git a/chrome/browser/ui/webui/options/chromeos/display_overscan_handler.cc b/chrome/browser/ui/webui/options/chromeos/display_overscan_handler.cc deleted file mode 100644 index 9616d7e..0000000 --- a/chrome/browser/ui/webui/options/chromeos/display_overscan_handler.cc +++ /dev/null
@@ -1,211 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/webui/options/chromeos/display_overscan_handler.h" - -#include <string> - -#include "ash/display/window_tree_host_manager.h" -#include "ash/shell.h" -#include "base/bind.h" -#include "base/logging.h" -#include "base/strings/string_number_conversions.h" -#include "base/values.h" -#include "chrome/browser/chromeos/display/overscan_calibrator.h" -#include "chrome/grit/generated_resources.h" -#include "content/public/browser/web_ui.h" -#include "ui/base/l10n/l10n_util.h" -#include "ui/display/display.h" -#include "ui/display/manager/display_manager.h" -#include "ui/display/screen.h" -#include "ui/display/types/display_constants.h" - -namespace chromeos { -namespace options { -namespace { - -// The value for the orientation of overscan operations. -const char kOrientationHorizontal[] = "horizontal"; -const char kOrientationVertical[] = "vertical"; - -} - -DisplayOverscanHandler::DisplayOverscanHandler() { - display::Screen::GetScreen()->AddObserver(this); -} - -DisplayOverscanHandler::~DisplayOverscanHandler() { - display::Screen::GetScreen()->RemoveObserver(this); -} - -void DisplayOverscanHandler::GetLocalizedValues( - base::DictionaryValue* localized_strings) { - RegisterTitle(localized_strings, "displayOverscanPage", - IDS_OPTIONS_SETTINGS_DISPLAY_OVERSCAN_TAB_TITLE); - localized_strings->SetString("shrinkAndExpand", l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_DISPLAY_OVERSCAN_SHRINK_EXPAND)); - localized_strings->SetString("move", l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_DISPLAY_OVERSCAN_MOVE)); - localized_strings->SetString("overscanReset", l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_DISPLAY_OVERSCAN_RESET_BUTTON_LABEL)); - localized_strings->SetString("overscanOK", l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_DISPLAY_OVERSCAN_OK_BUTTON_LABEL)); - localized_strings->SetString("overscanCancel", l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_DISPLAY_OVERSCAN_CANCEL_BUTTON_LABEL)); -} - -void DisplayOverscanHandler::RegisterMessages() { - web_ui()->RegisterMessageCallback( - "start", - base::Bind(&DisplayOverscanHandler::HandleStart, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "commit", - base::Bind(&DisplayOverscanHandler::HandleCommit, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "reset", - base::Bind(&DisplayOverscanHandler::HandleReset, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "cancel", - base::Bind(&DisplayOverscanHandler::HandleCancel, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "move", - base::Bind(&DisplayOverscanHandler::HandleMove, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "resize", - base::Bind(&DisplayOverscanHandler::HandleResize, - base::Unretained(this))); -} - -void DisplayOverscanHandler::OnDisplayAdded( - const display::Display& new_display) { - if (!overscan_calibrator_) - return; - - web_ui()->CallJavascriptFunctionUnsafe( - "options.DisplayOverscan.onOverscanCanceled"); -} - -void DisplayOverscanHandler::OnDisplayRemoved( - const display::Display& old_display) { - if (!overscan_calibrator_) - return; - - web_ui()->CallJavascriptFunctionUnsafe( - "options.DisplayOverscan.onOverscanCanceled"); -} - -void DisplayOverscanHandler::OnDisplayMetricsChanged(const display::Display&, - uint32_t) {} - -void DisplayOverscanHandler::HandleStart(const base::ListValue* args) { - int64_t display_id = display::kInvalidDisplayId; - std::string id_value; - if (!args->GetString(0, &id_value)) { - LOG(ERROR) << "Can't find ID"; - return; - } - - if (!base::StringToInt64(id_value, &display_id) || - display_id == display::kInvalidDisplayId) { - LOG(ERROR) << "Invalid parameter: " << id_value; - return; - } - - const display::Display& display = - ash::Shell::Get()->display_manager()->GetDisplayForId(display_id); - DCHECK(display.is_valid()); - if (!display.is_valid()) - return; - - ash::WindowTreeHostManager* window_tree_host_manager = - ash::Shell::Get()->window_tree_host_manager(); - overscan_calibrator_.reset(new OverscanCalibrator( - display, window_tree_host_manager->GetOverscanInsets(display_id))); -} - -void DisplayOverscanHandler::HandleCommit(const base::ListValue* unused_args) { - if (overscan_calibrator_.get()) { - overscan_calibrator_->Commit(); - overscan_calibrator_.reset(); - } -} - -void DisplayOverscanHandler::HandleReset(const base::ListValue* unused_args) { - if (overscan_calibrator_.get()) - overscan_calibrator_->Reset(); -} - -void DisplayOverscanHandler::HandleCancel(const base::ListValue* unused_args) { - overscan_calibrator_.reset(); -} - -void DisplayOverscanHandler::HandleMove(const base::ListValue* args) { - std::string orientation; - double length; - if (!args->GetString(0, &orientation)) { - LOG(ERROR) << "The first argument must be orientation"; - return; - } - if (!args->GetDouble(1, &length)) { - LOG(ERROR) << "The second argument must be a numeric"; - return; - } - - if (!overscan_calibrator_.get()) - return; - - gfx::Insets insets = overscan_calibrator_->insets(); - if (orientation == kOrientationHorizontal) { - insets.Set(insets.top(), insets.left() + length, - insets.bottom(), insets.right() - length); - } else if (orientation == kOrientationVertical) { - insets.Set(insets.top() + length, insets.left(), - insets.bottom() - length, insets.right()); - } else { - LOG(ERROR) << "The orientation must be '" << kOrientationHorizontal - << "' or '" << kOrientationVertical << "': " - << orientation; - return; - } - overscan_calibrator_->UpdateInsets(insets); -} - -void DisplayOverscanHandler::HandleResize(const base::ListValue* args) { - std::string orientation; - double length; - if (!args->GetString(0, &orientation)) { - LOG(ERROR) << "The first argument must be orientation"; - return; - } - if (!args->GetDouble(1, &length)) { - LOG(ERROR) << "The second argument must be a numeric"; - return; - } - - if (!overscan_calibrator_.get()) - return; - - gfx::Insets insets = overscan_calibrator_->insets(); - if (orientation == kOrientationHorizontal) { - insets.Set(insets.top(), insets.left() + length, - insets.bottom(), insets.right() + length); - } else if (orientation == kOrientationVertical) { - insets.Set(insets.top() + length, insets.left(), - insets.bottom() + length, insets.right()); - } else { - LOG(ERROR) << "The orientation must be '" << kOrientationHorizontal - << "' or '" << kOrientationVertical << "': " - << orientation; - return; - } - overscan_calibrator_->UpdateInsets(insets); -} - -} // namespace options -} // namespace chromeos
diff --git a/chrome/browser/ui/webui/options/chromeos/display_overscan_handler.h b/chrome/browser/ui/webui/options/chromeos/display_overscan_handler.h deleted file mode 100644 index d46e5275..0000000 --- a/chrome/browser/ui/webui/options/chromeos/display_overscan_handler.h +++ /dev/null
@@ -1,62 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_DISPLAY_OVERSCAN_HANDLER_H_ -#define CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_DISPLAY_OVERSCAN_HANDLER_H_ - -#include <stdint.h> - -#include <memory> - -#include "base/macros.h" -#include "chrome/browser/ui/webui/options/options_ui.h" -#include "ui/display/display_observer.h" - -namespace base { -class DictionaryValue; -class ListValue; -} - -namespace chromeos { -class OverscanCalibrator; - -namespace options { - -// Display options overlay page UI handler. -class DisplayOverscanHandler : public ::options::OptionsPageUIHandler, - public display::DisplayObserver { - public: - DisplayOverscanHandler(); - ~DisplayOverscanHandler() override; - - // OptionsPageUIHandler implementation. - void GetLocalizedValues(base::DictionaryValue* localized_strings) override; - - // WebUIMessageHandler implementation. - void RegisterMessages() override; - - // display::DisplayObserver implementation. - void OnDisplayAdded(const display::Display& new_display) override; - void OnDisplayRemoved(const display::Display& old_display) override; - void OnDisplayMetricsChanged(const display::Display& display, - uint32_t metrics) override; - - private: - // Handlers of JS messages. - void HandleStart(const base::ListValue* args); - void HandleCommit(const base::ListValue* unused_args); - void HandleReset(const base::ListValue* unused_args); - void HandleCancel(const base::ListValue* unused_args); - void HandleMove(const base::ListValue* args); - void HandleResize(const base::ListValue* args); - - std::unique_ptr<OverscanCalibrator> overscan_calibrator_; - - DISALLOW_COPY_AND_ASSIGN(DisplayOverscanHandler); -}; - -} // namespace options -} // namespace chromeos - -#endif // CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_DISPLAY_OVERSCAN_HANDLER_H_
diff --git a/chrome/browser/ui/webui/options/chromeos/internet_options_handler.cc b/chrome/browser/ui/webui/options/chromeos/internet_options_handler.cc deleted file mode 100644 index 75dab74..0000000 --- a/chrome/browser/ui/webui/options/chromeos/internet_options_handler.cc +++ /dev/null
@@ -1,253 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/webui/options/chromeos/internet_options_handler.h" - -#include <ctype.h> - -#include <map> -#include <string> -#include <vector> - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/values.h" -#include "chrome/browser/chromeos/enrollment_dialog_view.h" -#include "chrome/browser/chromeos/mobile_config.h" -#include "chrome/browser/chromeos/options/network_config_view.h" -#include "chrome/browser/chromeos/profiles/profile_helper.h" -#include "chrome/browser/chromeos/settings/cros_settings.h" -#include "chrome/browser/chromeos/sim_dialog_delegate.h" -#include "chrome/browser/chromeos/ui/choose_mobile_network_dialog.h" -#include "chrome/browser/chromeos/ui/mobile_config_ui.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/webui/chromeos/mobile_setup_dialog.h" -#include "chrome/browser/ui/webui/options/chromeos/internet_options_handler_strings.h" -#include "chromeos/login/login_state.h" -#include "chromeos/network/managed_network_configuration_handler.h" -#include "chromeos/network/network_connect.h" -#include "chromeos/network/network_state.h" -#include "chromeos/network/network_state_handler.h" -#include "components/onc/onc_constants.h" -#include "components/user_manager/user_manager.h" -#include "content/public/browser/web_contents.h" -#include "content/public/browser/web_ui.h" -#include "extensions/browser/api/vpn_provider/vpn_service.h" -#include "extensions/browser/api/vpn_provider/vpn_service_factory.h" -#include "third_party/cros_system_api/dbus/service_constants.h" -#include "ui/base/webui/web_ui_util.h" - -namespace chromeos { -namespace options { - -namespace { - -const char kAllowOnlyPolicyNetworksToConnect[] = - "allowOnlyPolicyNetworksToConnect"; - -// Keys for the initial "localized" dictionary values. -const char kLoggedInAsOwnerKey[] = "loggedInAsOwner"; - -// JS methods to show additional UI. -const char kShowMorePlanInfoMessage[] = "showMorePlanInfo"; -const char kSimOperationMessage[] = "simOperation"; - -// TODO(stevenjb): Deprecate these and integrate with settings Web UI. -const char kAddVPNConnectionMessage[] = "addVPNConnection"; -const char kAddNonVPNConnectionMessage[] = "addNonVPNConnection"; -const char kConfigureNetworkMessage[] = "configureNetwork"; - -// These are strings used to communicate with JavaScript. -const char kTagSimOpChangePin[] = "changePin"; -const char kTagSimOpConfigure[] = "configure"; -const char kTagSimOpSetLocked[] = "setLocked"; -const char kTagSimOpSetUnlocked[] = "setUnlocked"; -const char kTagSimOpUnlock[] = "unlock"; - -Profile* GetProfileForPrimaryUser() { - return chromeos::ProfileHelper::Get()->GetProfileByUser( - user_manager::UserManager::Get()->GetPrimaryUser()); -} - -} // namespace - -InternetOptionsHandler::InternetOptionsHandler() - : weak_factory_(this) { -} - -InternetOptionsHandler::~InternetOptionsHandler() { -} - -void InternetOptionsHandler::GetLocalizedValues( - base::DictionaryValue* localized_strings) { - DCHECK(localized_strings); - internet_options_strings::RegisterLocalizedStrings(localized_strings); - - // TODO(stevenjb): Find a better way to populate initial data. - std::string owner; - chromeos::CrosSettings::Get()->GetString(chromeos::kDeviceOwner, &owner); - bool logged_in_as_owner = LoginState::Get()->GetLoggedInUserType() == - LoginState::LOGGED_IN_USER_OWNER; - localized_strings->SetBoolean(kLoggedInAsOwnerKey, logged_in_as_owner); - - // TODO(fqj/stevenjb): Make this a property of networkingPrivate - const base::DictionaryValue* global_network_config = - NetworkHandler::Get() - ->managed_network_configuration_handler() - ->GetGlobalConfigFromPolicy( - std::string() /* no user hash, device policy*/); - if (global_network_config) { - bool only_policy_connect = false; - global_network_config->GetBooleanWithoutPathExpansion( - ::onc::global_network_config::kAllowOnlyPolicyNetworksToConnect, - &only_policy_connect); - localized_strings->SetBoolean(kAllowOnlyPolicyNetworksToConnect, - only_policy_connect); - } -} - -void InternetOptionsHandler::RegisterMessages() { - web_ui()->RegisterMessageCallback(kAddVPNConnectionMessage, - base::Bind(&InternetOptionsHandler::AddVPNConnection, - base::Unretained(this))); - web_ui()->RegisterMessageCallback(kAddNonVPNConnectionMessage, - base::Bind(&InternetOptionsHandler::AddNonVPNConnection, - base::Unretained(this))); - web_ui()->RegisterMessageCallback(kConfigureNetworkMessage, - base::Bind(&InternetOptionsHandler::ConfigureNetwork, - base::Unretained(this))); - web_ui()->RegisterMessageCallback(kShowMorePlanInfoMessage, - base::Bind(&InternetOptionsHandler::ShowMorePlanInfoCallback, - base::Unretained(this))); - web_ui()->RegisterMessageCallback(kSimOperationMessage, - base::Bind(&InternetOptionsHandler::SimOperationCallback, - base::Unretained(this))); -} - -void InternetOptionsHandler::ShowMorePlanInfoCallback( - const base::ListValue* args) { - if (!web_ui()) - return; - std::string guid; - if (args->GetSize() != 1 || !args->GetString(0, &guid)) { - NOTREACHED(); - return; - } - NetworkConnect::Get()->ShowMobileSetup(guid); -} - -void InternetOptionsHandler::SimOperationCallback(const base::ListValue* args) { - std::string operation; - if (args->GetSize() != 1 || !args->GetString(0, &operation)) { - NOTREACHED(); - return; - } - if (operation == kTagSimOpConfigure) { - mobile_config_ui::DisplayConfigDialog(); - return; - } - // 1. Bring up SIM unlock dialog, pass new RequirePin setting in URL. - // 2. Dialog will ask for current PIN in any case. - // 3. If card is locked it will first call PIN unlock operation - // 4. Then it will call Set RequirePin, passing the same PIN. - // 5. The dialog may change device properties, in which case - // DevicePropertiesUpdated() will get called which will update the UI. - SimDialogDelegate::SimDialogMode mode; - if (operation == kTagSimOpSetLocked) { - mode = SimDialogDelegate::SIM_DIALOG_SET_LOCK_ON; - } else if (operation == kTagSimOpSetUnlocked) { - mode = SimDialogDelegate::SIM_DIALOG_SET_LOCK_OFF; - } else if (operation == kTagSimOpUnlock) { - mode = SimDialogDelegate::SIM_DIALOG_UNLOCK; - } else if (operation == kTagSimOpChangePin) { - mode = SimDialogDelegate::SIM_DIALOG_CHANGE_PIN; - } else { - NOTREACHED(); - return; - } - SimDialogDelegate::ShowDialog(GetNativeWindow(), mode); -} - -//////////////////////////////////////////////////////////////////////////////// - -gfx::NativeWindow InternetOptionsHandler::GetNativeWindow() const { - return web_ui()->GetWebContents()->GetTopLevelNativeWindow(); -} - -const PrefService* InternetOptionsHandler::GetPrefs() const { - return Profile::FromWebUI(web_ui())->GetPrefs(); -} - - -void InternetOptionsHandler::AddVPNConnection(const base::ListValue* args) { - if (args->empty()) { - // Show the "add network" dialog for the built-in OpenVPN/L2TP provider. - NetworkConfigView::ShowForType(shill::kTypeVPN); - return; - } - - std::string extension_id; - if (args->GetSize() != 1 || !args->GetString(0, &extension_id)) { - NOTREACHED(); - return; - } - - // Request that the third-party VPN provider identified by |provider_id| - // show its "add network" dialog. - chromeos::VpnServiceFactory::GetForBrowserContext( - GetProfileForPrimaryUser())->SendShowAddDialogToExtension(extension_id); -} - -void InternetOptionsHandler::AddNonVPNConnection(const base::ListValue* args) { - std::string onc_type; - if (args->GetSize() != 1 || !args->GetString(0, &onc_type)) { - NOTREACHED(); - return; - } - if (onc_type == ::onc::network_type::kWiFi) { - NetworkConfigView::ShowForType(shill::kTypeWifi); - } else if (onc_type == ::onc::network_type::kCellular) { - ChooseMobileNetworkDialog::ShowDialog(GetNativeWindow()); - } else { - LOG(ERROR) << "Unsupported type for AddConnection"; - } -} - -void InternetOptionsHandler::ConfigureNetwork(const base::ListValue* args) { - std::string guid; - if (args->GetSize() < 1 || !args->GetString(0, &guid)) { - NOTREACHED(); - return; - } - bool force_show = false; - if (args->GetSize() >= 2) - args->GetBoolean(1, &force_show); - - const NetworkState* network = - NetworkHandler::Get()->network_state_handler()->GetNetworkStateFromGuid( - guid); - if (!network) - return; - - if (network->type() == shill::kTypeVPN && - network->vpn_provider_type() == shill::kProviderThirdPartyVpn) { - // Request that the third-party VPN provider used by the |network| show a - // configuration dialog for it. - VpnServiceFactory::GetForBrowserContext(GetProfileForPrimaryUser()) - ->SendShowConfigureDialogToExtension( - network->third_party_vpn_provider_extension_id(), network->name()); - return; - } - - // If a network is not connectable, show the enrollment dialog if available. - if (!force_show && !network->connectable() && - enrollment::CreateEnrollmentDialog(guid, GetNativeWindow())) { - return; - } - - NetworkConfigView::ShowForNetworkId(guid); -} - -} // namespace options -} // namespace chromeos
diff --git a/chrome/browser/ui/webui/options/chromeos/internet_options_handler.h b/chrome/browser/ui/webui/options/chromeos/internet_options_handler.h deleted file mode 100644 index 383b977..0000000 --- a/chrome/browser/ui/webui/options/chromeos/internet_options_handler.h +++ /dev/null
@@ -1,60 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_INTERNET_OPTIONS_HANDLER_H_ -#define CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_INTERNET_OPTIONS_HANDLER_H_ - -#include <string> - -#include "base/compiler_specific.h" -#include "base/macros.h" -#include "base/memory/weak_ptr.h" -#include "chrome/browser/ui/webui/options/options_ui.h" -#include "ui/gfx/native_widget_types.h" - -class PrefService; - -namespace chromeos { -namespace options { - -// ChromeOS internet options page UI handler. -class InternetOptionsHandler : public ::options::OptionsPageUIHandler { - public: - InternetOptionsHandler(); - ~InternetOptionsHandler() override; - - private: - // OptionsPageUIHandler - void GetLocalizedValues(base::DictionaryValue* localized_strings) override; - - // WebUIMessageHandler (from OptionsPageUIHandler) - void RegisterMessages() override; - - // Callbacks to set network state properties. - void ShowMorePlanInfoCallback(const base::ListValue* args); - void SimOperationCallback(const base::ListValue* args); - - // Gets the native window for hosting dialogs, etc. - gfx::NativeWindow GetNativeWindow() const; - - // Gets the user PrefService associated with the WebUI. - const PrefService* GetPrefs() const; - - // Additional callbacks for managing networks. - void AddVPNConnection(const base::ListValue* args); - void AddNonVPNConnection(const base::ListValue* args); - void ConfigureNetwork(const base::ListValue* args); - - // Weak pointer factory so we can start connections at a later time - // without worrying that they will actually try to happen after the lifetime - // of this object. - base::WeakPtrFactory<InternetOptionsHandler> weak_factory_; - - DISALLOW_COPY_AND_ASSIGN(InternetOptionsHandler); -}; - -} // namespace options -} // namespace chromeos - -#endif // CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_INTERNET_OPTIONS_HANDLER_H_
diff --git a/chrome/browser/ui/webui/options/chromeos/internet_options_handler_strings.cc b/chrome/browser/ui/webui/options/chromeos/internet_options_handler_strings.cc deleted file mode 100644 index accea76..0000000 --- a/chrome/browser/ui/webui/options/chromeos/internet_options_handler_strings.cc +++ /dev/null
@@ -1,208 +0,0 @@ -// Copyright (c) 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/webui/options/chromeos/internet_options_handler_strings.h" - -#include <stddef.h> - -#include "ash/strings/grit/ash_strings.h" -#include "base/macros.h" -#include "base/values.h" -#include "chrome/grit/generated_resources.h" -#include "components/strings/grit/components_strings.h" -#include "ui/base/l10n/l10n_util.h" - -namespace chromeos { -namespace internet_options_strings { - -namespace { - -struct StringResource { - const char* name; - int id; -}; - -StringResource kStringResources[] = { - // Main settings page. - {"ethernetName", IDS_STATUSBAR_NETWORK_DEVICE_ETHERNET}, - {"ethernetTitle", IDS_STATUSBAR_NETWORK_DEVICE_ETHERNET}, - {"wifiTitle", IDS_OPTIONS_SETTINGS_SECTION_TITLE_WIFI_NETWORK}, - {"wimaxTitle", IDS_OPTIONS_SETTINGS_SECTION_TITLE_WIMAX_NETWORK}, - {"cellularTitle", IDS_OPTIONS_SETTINGS_SECTION_TITLE_CELLULAR_NETWORK}, - {"vpnTitle", IDS_OPTIONS_SETTINGS_SECTION_TITLE_PRIVATE_NETWORK}, - {"vpnNameTemplate", - IDS_OPTIONS_SETTINGS_SECTION_THIRD_PARTY_VPN_NAME_TEMPLATE}, - {"defaultThirdPartyProviderName", - IDS_OPTIONS_SETTINGS_SECTION_DEFAULT_THIRD_PARTY_PROVIDER_NAME}, - {"vpnBuiltInProvider", IDS_ASH_STATUS_TRAY_VPN_BUILT_IN_PROVIDER}, - {"joinOtherNetwork", IDS_OPTIONS_SETTINGS_NETWORK_OTHER}, - {"networkDisabled", IDS_OPTIONS_SETTINGS_NETWORK_DISABLED}, - {"networkProhibited", IDS_OPTIONS_SETTINGS_NETWORK_PROHIBITED}, - {"turnOffWifi", IDS_OPTIONS_SETTINGS_NETWORK_DISABLE_WIFI}, - {"turnOffWimax", IDS_OPTIONS_SETTINGS_NETWORK_DISABLE_WIMAX}, - {"turnOffCellular", IDS_OPTIONS_SETTINGS_NETWORK_DISABLE_CELLULAR}, - {"disconnectNetwork", IDS_OPTIONS_SETTINGS_DISCONNECT}, - {"preferredNetworks", IDS_OPTIONS_SETTINGS_PREFERRED_NETWORKS_LABEL}, - {"preferredNetworksPage", IDS_OPTIONS_SETTINGS_PREFERRED_NETWORKS_TITLE}, - {"useSharedProxies", IDS_OPTIONS_SETTINGS_USE_SHARED_PROXIES}, - {"addConnectionTitle", IDS_OPTIONS_SETTINGS_SECTION_TITLE_ADD_CONNECTION}, - {"addConnectionWifi", IDS_OPTIONS_SETTINGS_ADD_CONNECTION_WIFI}, - {"addConnectionVPNTemplate", IDS_OPTIONS_SETTINGS_ADD_VPN_TEMPLATE}, - {"otherCellularNetworks", IDS_OPTIONS_SETTINGS_OTHER_CELLULAR_NETWORKS}, - {"enableDataRoaming", IDS_OPTIONS_SETTINGS_ENABLE_DATA_ROAMING}, - {"disableDataRoaming", IDS_OPTIONS_SETTINGS_DISABLE_DATA_ROAMING}, - {"dataRoamingDisableToggleTooltip", - IDS_OPTIONS_SETTINGS_TOGGLE_DATA_ROAMING_RESTRICTION}, - {"prohibitedNetwork", IDS_OPTIONS_SETTINGS_PROHIBITED_NETWORK}, - {"prohibitedNetworkOther", IDS_OPTIONS_SETTINGS_PROHIBITED_NETWORK_OTHER}, - - // ONC network states. Format is 'Onc' + key + value. - // Note: '.' must be replaced with '-', e.g. VPN.Type -> OncVPN-Type - {"OncCellular-ActivationStateActivated", - IDS_CHROMEOS_NETWORK_ACTIVATION_STATE_ACTIVATED}, - {"OncCellular-ActivationStateActivating", - IDS_CHROMEOS_NETWORK_ACTIVATION_STATE_ACTIVATING}, - {"OncCellular-ActivationStateNotActivated", - IDS_CHROMEOS_NETWORK_ACTIVATION_STATE_NOT_ACTIVATED}, - {"OncCellular-ActivationStatePartiallyActivated", - IDS_CHROMEOS_NETWORK_ACTIVATION_STATE_PARTIALLY_ACTIVATED}, - {"OncConnectionStateConnected", IDS_CHROMEOS_NETWORK_STATE_CONNECTED}, - {"OncConnectionStateConnecting", IDS_CHROMEOS_NETWORK_STATE_CONNECTING}, - {"OncConnectionStateNotConnected", - IDS_CHROMEOS_NETWORK_STATE_NOT_CONNECTED}, - {"OncCellular-RoamingStateHome", IDS_CHROMEOS_NETWORK_ROAMING_STATE_HOME}, - {"OncCellular-RoamingStateRoaming", - IDS_CHROMEOS_NETWORK_ROAMING_STATE_ROAMING}, - {"OncTypeCellular", IDS_NETWORK_TYPE_MOBILE_DATA}, - {"OncTypeEthernet", IDS_NETWORK_TYPE_ETHERNET}, - {"OncTypeTether", IDS_NETWORK_TYPE_MOBILE_DATA}, - {"OncTypeWiFi", IDS_NETWORK_TYPE_WIFI}, - {"OncTypeWimax", IDS_NETWORK_TYPE_WIMAX}, - {"OncVPN-TypeL2TP-IPsecCert", - IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_L2TP_IPSEC_USER_CERT}, - {"OncVPN-TypeL2TP-IPsecPSK", - IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_L2TP_IPSEC_PSK}, - {"OncVPN-TypeOpenVPN", IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_OPEN_VPN}, - {"OncVPN-TypeThirdPartyVPN", - IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_THIRD_PARTY_VPN}, - - // Internet details dialog. - {"restrictedNo", IDS_CONFIRM_MESSAGEBOX_NO_BUTTON_LABEL}, - {"restrictedYes", IDS_CONFIRM_MESSAGEBOX_YES_BUTTON_LABEL}, - {"managedNetwork", IDS_OPTIONS_SETTINGS_MANAGED_NETWORK}, - {"wifiNetworkTabLabel", IDS_OPTIONS_SETTINGS_INTERNET_TAB_CONNECTION}, - {"vpnTabLabel", IDS_OPTIONS_SETTINGS_INTERNET_TAB_VPN}, - {"cellularConnTabLabel", IDS_OPTIONS_SETTINGS_INTERNET_TAB_CONNECTION}, - {"cellularDeviceTabLabel", IDS_OPTIONS_SETTINGS_INTERNET_TAB_DEVICE}, - {"networkTabLabel", IDS_OPTIONS_SETTINGS_INTERNET_TAB_NETWORK}, - {"securityTabLabel", IDS_OPTIONS_SETTINGS_INTERNET_TAB_SECURITY}, - {"proxyTabLabel", IDS_OPTIONS_SETTINGS_INTERNET_TAB_PROXY}, - {"connectionState", IDS_OPTIONS_SETTINGS_INTERNET_CONNECTION_STATE}, - // TODO(stevenjb): Rename the IDS constant when we redesign the UI. - {"restrictedConnectivity", - IDS_OPTIONS_SETTINGS_INTERNET_CELLULAR_RESTRICTED_POOL}, - {"inetAddress", IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_ADDRESS}, - {"ipv6Address", IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_ADDRESS_IPV6}, - {"inetNetmask", IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_SUBNETMASK}, - {"inetGateway", IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_GATEWAY}, - {"inetNameServers", IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_DNSSERVER}, - {"ipAutomaticConfiguration", - IDS_OPTIONS_SETTINGS_INTERNET_IP_AUTOMATIC_CONFIGURATION}, - {"automaticNameServers", - IDS_OPTIONS_SETTINGS_INTERNET_AUTOMATIC_NAME_SERVERS}, - {"userNameServer1", IDS_OPTIONS_SETTINGS_INTERNET_USER_NAME_SERVER_1}, - {"userNameServer2", IDS_OPTIONS_SETTINGS_INTERNET_USER_NAME_SERVER_2}, - {"userNameServer3", IDS_OPTIONS_SETTINGS_INTERNET_USER_NAME_SERVER_3}, - {"userNameServer4", IDS_OPTIONS_SETTINGS_INTERNET_USER_NAME_SERVER_4}, - {"googleNameServers", IDS_OPTIONS_SETTINGS_INTERNET_GOOGLE_NAME_SERVERS}, - {"userNameServers", IDS_OPTIONS_SETTINGS_INTERNET_USER_NAME_SERVERS}, - {"hardwareAddress", IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_HARDWARE_ADDRESS}, - {"detailsInternetDismiss", IDS_CLOSE}, - {"activateButton", IDS_OPTIONS_SETTINGS_ACTIVATE}, - {"connectButton", IDS_OPTIONS_SETTINGS_CONNECT}, - {"configureButton", IDS_OPTIONS_SETTINGS_CONFIGURE}, - {"disconnectButton", IDS_OPTIONS_SETTINGS_DISCONNECT}, - {"viewAccountButton", IDS_STATUSBAR_NETWORK_VIEW_ACCOUNT}, - {"wimaxConnTabLabel", IDS_OPTIONS_SETTINGS_INTERNET_TAB_WIMAX}, - - // Wifi Tab. - {"inetSsid", IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_NETWORK_ID}, - {"inetBssid", IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_NETWORK_BSSID}, - {"inetEncryption", - IDS_OPTIONS_SETTIGNS_INTERNET_OPTIONS_NETWORK_ENCRYPTION}, - {"inetFrequency", IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_NETWORK_FREQUENCY}, - {"inetFrequencyFormat", - IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_NETWORK_FREQUENCY_MHZ}, - {"inetSignalStrength", - IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_NETWORK_STRENGTH}, - {"inetSignalStrengthFormat", - IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_NETWORK_STRENGTH_PERCENTAGE}, - {"inetPassProtected", IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_NET_PROTECTED}, - {"inetNetworkShared", IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_NETWORK_SHARED}, - {"inetPreferredNetwork", - IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_PREFER_NETWORK}, - {"inetAutoConnectNetwork", - IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_AUTO_CONNECT}, - - // VPN Tab. - {"inetServiceName", IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_VPN_SERVICE_NAME}, - {"inetServerHostname", - IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_VPN_SERVER_HOSTNAME}, - {"inetProviderType", - IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_VPN_PROVIDER_TYPE}, - {"inetProviderName", - IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_VPN_PROVIDER_NAME}, - {"inetUsername", IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_VPN_USERNAME}, - - // Cellular Tab. - {"serviceName", IDS_OPTIONS_SETTINGS_INTERNET_CELLULAR_SERVICE_NAME}, - {"networkTechnology", - IDS_OPTIONS_SETTINGS_INTERNET_CELLULAR_NETWORK_TECHNOLOGY}, - {"operatorName", IDS_OPTIONS_SETTINGS_INTERNET_CELLULAR_OPERATOR}, - {"operatorCode", IDS_OPTIONS_SETTINGS_INTERNET_CELLULAR_OPERATOR_CODE}, - {"activationState", - IDS_OPTIONS_SETTINGS_INTERNET_CELLULAR_ACTIVATION_STATE}, - {"roamingState", IDS_OPTIONS_SETTINGS_INTERNET_CELLULAR_ROAMING_STATE}, - {"errorState", IDS_OPTIONS_SETTINGS_INTERNET_CELLULAR_ERROR_STATE}, - {"cellularManufacturer", - IDS_OPTIONS_SETTINGS_INTERNET_CELLULAR_MANUFACTURER}, - {"modelId", IDS_OPTIONS_SETTINGS_INTERNET_CELLULAR_MODEL_ID}, - {"firmwareRevision", - IDS_OPTIONS_SETTINGS_INTERNET_CELLULAR_FIRMWARE_REVISION}, - {"hardwareRevision", - IDS_OPTIONS_SETTINGS_INTERNET_CELLULAR_HARDWARE_REVISION}, - {"prlVersion", IDS_OPTIONS_SETTINGS_INTERNET_CELLULAR_PRL_VERSION}, - {"cellularApnLabel", IDS_OPTIONS_SETTINGS_INTERNET_CELLULAR_APN}, - {"cellularApnOther", IDS_OPTIONS_SETTINGS_INTERNET_CELLULAR_APN_OTHER}, - {"cellularApnUsername", - IDS_OPTIONS_SETTINGS_INTERNET_CELLULAR_APN_USERNAME}, - {"cellularApnPassword", - IDS_OPTIONS_SETTINGS_INTERNET_CELLULAR_APN_PASSWORD}, - {"cellularApnUseDefault", IDS_OPTIONS_SETTINGS_INTERNET_CELLULAR_APN_CLEAR}, - {"cellularApnSet", IDS_OPTIONS_SETTINGS_INTERNET_CELLULAR_APN_SET}, - {"cellularApnCancel", IDS_CANCEL}, - - // Security Tab. - {"lockSimCard", IDS_OPTIONS_SETTINGS_INTERNET_CELLULAR_LOCK_SIM_CARD}, - {"changePinButton", - IDS_OPTIONS_SETTINGS_INTERNET_CELLULAR_CHANGE_PIN_BUTTON}, - - // Proxy Tab. - {"webProxyAutoDiscoveryUrl", IDS_PROXY_WEB_PROXY_AUTO_DISCOVERY}, -}; - -const size_t kStringResourcesLength = arraysize(kStringResources); - -} // namespace - -void RegisterLocalizedStrings(base::DictionaryValue* localized_strings) { - for (size_t i = 0; i < kStringResourcesLength; ++i) { - localized_strings->SetString( - kStringResources[i].name, - l10n_util::GetStringUTF16(kStringResources[i].id)); - } -} - -} // namespace internet_options_strings -} // namespace chromeos
diff --git a/chrome/browser/ui/webui/options/chromeos/internet_options_handler_strings.h b/chrome/browser/ui/webui/options/chromeos/internet_options_handler_strings.h deleted file mode 100644 index 2983f548..0000000 --- a/chrome/browser/ui/webui/options/chromeos/internet_options_handler_strings.h +++ /dev/null
@@ -1,22 +0,0 @@ -// Copyright (c) 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_INTERNET_OPTIONS_HANDLER_STRINGS_H_ -#define CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_INTERNET_OPTIONS_HANDLER_STRINGS_H_ - -#include <string> - -namespace base { -class DictionaryValue; -} - -namespace chromeos { -namespace internet_options_strings { - -void RegisterLocalizedStrings(base::DictionaryValue* localized_strings); - -} // namespace internet_options_strings -} // namespace chromeos - -#endif // CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_INTERNET_OPTIONS_HANDLER_STRINGS_H_
diff --git a/chrome/browser/ui/webui/options/chromeos/keyboard_handler.cc b/chrome/browser/ui/webui/options/chromeos/keyboard_handler.cc deleted file mode 100644 index 1d6882b..0000000 --- a/chrome/browser/ui/webui/options/chromeos/keyboard_handler.cc +++ /dev/null
@@ -1,191 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/webui/options/chromeos/keyboard_handler.h" - -#include <stddef.h> - -#include <memory> -#include <utility> - -#include "ash/new_window_controller.h" -#include "ash/shell.h" -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/command_line.h" -#include "base/macros.h" -#include "base/memory/ptr_util.h" -#include "base/values.h" -#include "chrome/grit/generated_resources.h" -#include "chromeos/chromeos_switches.h" -#include "content/public/browser/web_ui.h" -#include "ui/base/ime/chromeos/ime_keyboard.h" -#include "ui/base/l10n/l10n_util.h" -#include "ui/events/devices/input_device_manager.h" - -namespace { -const struct ModifierKeysSelectItem { - int message_id; - chromeos::input_method::ModifierKey value; -} kModifierKeysSelectItems[] = { - { IDS_OPTIONS_SETTINGS_LANGUAGES_KEY_SEARCH, - chromeos::input_method::kSearchKey }, - { IDS_OPTIONS_SETTINGS_LANGUAGES_KEY_LEFT_CTRL, - chromeos::input_method::kControlKey }, - { IDS_OPTIONS_SETTINGS_LANGUAGES_KEY_LEFT_ALT, - chromeos::input_method::kAltKey }, - { IDS_OPTIONS_SETTINGS_LANGUAGES_KEY_VOID, - chromeos::input_method::kVoidKey }, - { IDS_OPTIONS_SETTINGS_LANGUAGES_KEY_CAPS_LOCK, - chromeos::input_method::kCapsLockKey }, - { IDS_OPTIONS_SETTINGS_LANGUAGES_KEY_ESCAPE, - chromeos::input_method::kEscapeKey }, - { IDS_OPTIONS_SETTINGS_LANGUAGES_KEY_BACKSPACE, - chromeos::input_method::kBackspaceKey }, -}; - -const char* kDataValuesNames[] = { - "remapSearchKeyToValue", - "remapControlKeyToValue", - "remapAltKeyToValue", - "remapCapsLockKeyToValue", - "remapDiamondKeyToValue", - "remapEscapeKeyToValue", - "remapBackspaceKeyToValue", -}; - -bool HasExternalKeyboard() { - for (const ui::InputDevice& keyboard : - ui::InputDeviceManager::GetInstance()->GetKeyboardDevices()) { - if (keyboard.type == ui::InputDeviceType::INPUT_DEVICE_EXTERNAL) - return true; - } - - return false; -} -} // namespace - -namespace chromeos { -namespace options { - -KeyboardHandler::KeyboardHandler() { - ui::InputDeviceManager::GetInstance()->AddObserver(this); -} - -KeyboardHandler::~KeyboardHandler() { - ui::InputDeviceManager::GetInstance()->RemoveObserver(this); -} - -void KeyboardHandler::GetLocalizedValues( - base::DictionaryValue* localized_strings) { - DCHECK(localized_strings); - RegisterTitle(localized_strings, "keyboardOverlay", - IDS_OPTIONS_KEYBOARD_OVERLAY_TITLE); - - localized_strings->SetString("remapSearchKeyToContent", - l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_LANGUAGES_KEY_SEARCH_LABEL)); - localized_strings->SetString("remapControlKeyToContent", - l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_LANGUAGES_KEY_LEFT_CTRL_LABEL)); - localized_strings->SetString("remapAltKeyToContent", - l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_LANGUAGES_KEY_LEFT_ALT_LABEL)); - localized_strings->SetString("remapCapsLockKeyToContent", - l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_LANGUAGES_KEY_CAPS_LOCK_LABEL)); - localized_strings->SetString("remapDiamondKeyToContent", - l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_LANGUAGES_KEY_DIAMOND_KEY_LABEL)); - localized_strings->SetString("remapBackspaceKeyToContent", - l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_LANGUAGES_KEY_BACKSPACE_KEY_LABEL)); - localized_strings->SetString("remapEscapeKeyToContent", - l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_LANGUAGES_KEY_ESCAPE_KEY_LABEL)); - localized_strings->SetString("sendFunctionKeys", - l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_LANGUAGES_SEND_FUNCTION_KEYS)); - localized_strings->SetString("sendFunctionKeysDescription", - l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_LANGUAGES_SEND_FUNCTION_KEYS_DESCRIPTION)); - localized_strings->SetString("enableAutoRepeat", - l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_LANGUAGES_AUTO_REPEAT_ENABLE)); - localized_strings->SetString("autoRepeatDelay", - l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_LANGUAGES_AUTO_REPEAT_DELAY)); - localized_strings->SetString("autoRepeatDelayLong", - l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_LANGUAGES_AUTO_REPEAT_DELAY_LONG)); - localized_strings->SetString("autoRepeatDelayShort", - l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_LANGUAGES_AUTO_REPEAT_DELAY_SHORT)); - localized_strings->SetString("autoRepeatRate", - l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_LANGUAGES_AUTO_REPEAT_RATE)); - localized_strings->SetString("autoRepeatRateSlow", - l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_LANGUAGES_AUTO_REPEAT_RATE_SLOW)); - localized_strings->SetString("autoRepeatRateFast", - l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_LANGUAGES_AUTO_REPEAT_RATE_FAST)); - localized_strings->SetString("changeLanguageAndInputSettings", - l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_CHANGE_LANGUAGE_AND_INPUT_SETTINGS)); - localized_strings->SetString("showKeyboardShortcuts", - l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_SHOW_KEYBOARD_SHORTCUTS)); - - for (size_t i = 0; i < arraysize(kDataValuesNames); ++i) { - auto list_value = base::MakeUnique<base::ListValue>(); - for (size_t j = 0; j < arraysize(kModifierKeysSelectItems); ++j) { - const input_method::ModifierKey value = - kModifierKeysSelectItems[j].value; - const int message_id = kModifierKeysSelectItems[j].message_id; - auto option = base::MakeUnique<base::ListValue>(); - option->AppendInteger(value); - option->AppendString(l10n_util::GetStringUTF16(message_id)); - list_value->Append(std::move(option)); - } - localized_strings->Set(kDataValuesNames[i], std::move(list_value)); - } -} - -void KeyboardHandler::InitializePage() { - bool has_diamond_key = base::CommandLine::ForCurrentProcess()->HasSwitch( - chromeos::switches::kHasChromeOSDiamondKey); - const base::Value show_diamond_key_options(has_diamond_key); - - web_ui()->CallJavascriptFunctionUnsafe( - "options.KeyboardOverlay.showDiamondKeyOptions", - show_diamond_key_options); - - UpdateCapsLockOptions(); -} - -void KeyboardHandler::RegisterMessages() { - // Callback to show keyboard overlay. - web_ui()->RegisterMessageCallback( - "showKeyboardShortcuts", - base::Bind(&KeyboardHandler::HandleShowKeyboardShortcuts, - base::Unretained(this))); -} - -void KeyboardHandler::OnKeyboardDeviceConfigurationChanged() { - UpdateCapsLockOptions(); -} - -void KeyboardHandler::HandleShowKeyboardShortcuts(const base::ListValue* args) { - ash::Shell::Get()->new_window_controller()->ShowKeyboardOverlay(); -} - -void KeyboardHandler::UpdateCapsLockOptions() const { - const base::Value show_caps_lock_options(HasExternalKeyboard()); - web_ui()->CallJavascriptFunctionUnsafe( - "options.KeyboardOverlay.showCapsLockOptions", show_caps_lock_options); -} - -} // namespace options -} // namespace chromeos
diff --git a/chrome/browser/ui/webui/options/chromeos/keyboard_handler.h b/chrome/browser/ui/webui/options/chromeos/keyboard_handler.h deleted file mode 100644 index 8f6501a..0000000 --- a/chrome/browser/ui/webui/options/chromeos/keyboard_handler.h +++ /dev/null
@@ -1,47 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_KEYBOARD_HANDLER_H_ -#define CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_KEYBOARD_HANDLER_H_ - -#include "base/compiler_specific.h" -#include "base/macros.h" -#include "chrome/browser/ui/webui/options/options_ui.h" -#include "components/prefs/pref_member.h" -#include "ui/events/devices/input_device_event_observer.h" - -namespace chromeos { -namespace options { - -// Customize modifier keys overlay page UI handler. -class KeyboardHandler - : public ::options::OptionsPageUIHandler, - public ui::InputDeviceEventObserver { - public: - KeyboardHandler(); - ~KeyboardHandler() override; - - // OptionsPageUIHandler implementation. - void GetLocalizedValues(base::DictionaryValue* localized_strings) override; - void InitializePage() override; - void RegisterMessages() override; - - // ui::InputDeviceEventObserver: - void OnKeyboardDeviceConfigurationChanged() override; - - private: - // Show the keyboard shortcuts overlay from the options page. - void HandleShowKeyboardShortcuts(const base::ListValue* args); - - // Shows or hides the CapsLock options based on whether or not there is an - // external keyboard connected. - void UpdateCapsLockOptions() const; - - DISALLOW_COPY_AND_ASSIGN(KeyboardHandler); -}; - -} // namespace options -} // namespace chromeos - -#endif // CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_KEYBOARD_HANDLER_H_
diff --git a/chrome/browser/ui/webui/options/chromeos/options_stylus_handler.cc b/chrome/browser/ui/webui/options/chromeos/options_stylus_handler.cc deleted file mode 100644 index e705e1f..0000000 --- a/chrome/browser/ui/webui/options/chromeos/options_stylus_handler.cc +++ /dev/null
@@ -1,157 +0,0 @@ -// Copyright (c) 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/webui/options/chromeos/options_stylus_handler.h" - -#include "ash/system/palette/palette_utils.h" -#include "base/values.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/grit/generated_resources.h" -#include "ui/base/l10n/l10n_util.h" -#include "ui/events/devices/input_device_manager.h" - -namespace chromeos { -namespace options { - -namespace { - -// Keys in objects passed to updateNoteTakingApps_. -constexpr char kAppNameKey[] = "name"; -constexpr char kAppIdKey[] = "id"; -constexpr char kAppPreferredKey[] = "preferred"; - -} // namespace - -OptionsStylusHandler::OptionsStylusHandler() : weak_ptr_factory_(this) { - NoteTakingHelper::Get()->AddObserver(this); - ui::InputDeviceManager::GetInstance()->AddObserver(this); -} - -OptionsStylusHandler::~OptionsStylusHandler() { - ui::InputDeviceManager::GetInstance()->RemoveObserver(this); - NoteTakingHelper::Get()->RemoveObserver(this); -} - -void OptionsStylusHandler::GetLocalizedValues( - base::DictionaryValue* localized_strings) { - DCHECK(localized_strings); - - RegisterTitle(localized_strings, "stylusOverlay", IDS_SETTINGS_STYLUS_TITLE); - - localized_strings->SetString( - "stylusSettingsButtonTitle", - l10n_util::GetStringUTF16( - IDS_OPTIONS_DEVICE_GROUP_STYLUS_SETTINGS_BUTTON)); - localized_strings->SetString( - "stylusAutoOpenStylusTools", - l10n_util::GetStringUTF16(IDS_SETTINGS_STYLUS_AUTO_OPEN_STYLUS_TOOLS)); - localized_strings->SetString( - "stylusEnableStylusTools", - l10n_util::GetStringUTF16(IDS_SETTINGS_STYLUS_ENABLE_STYLUS_TOOLS)); - localized_strings->SetString( - "stylusFindMoreApps", - l10n_util::GetStringUTF16(IDS_SETTINGS_STYLUS_FIND_MORE_APPS_PRIMARY)); - localized_strings->SetString( - "stylusNoteTakingApp", - l10n_util::GetStringUTF16(IDS_OPTIONS_STYLUS_NOTE_TAKING_APP_LABEL)); - localized_strings->SetString( - "stylusNoteTakingAppNoneAvailable", - l10n_util::GetStringUTF16( - IDS_OPTIONS_STYLUS_NOTE_TAKING_APP_NONE_AVAILABLE)); - localized_strings->SetString( - "stylusNoteTakingAppWaitingForAndroid", - l10n_util::GetStringUTF16( - IDS_OPTIONS_STYLUS_NOTE_TAKING_APP_WAITING_FOR_ANDROID)); -} - -void OptionsStylusHandler::InitializePage() { - UpdateNoteTakingApps(); -} - -void OptionsStylusHandler::RegisterMessages() { - web_ui()->RegisterMessageCallback( - "setPreferredNoteTakingApp", - base::Bind(&OptionsStylusHandler::SetPreferredNoteTakingApp, - weak_ptr_factory_.GetWeakPtr())); - web_ui()->RegisterMessageCallback( - "requestStylusHardwareState", - base::Bind(&OptionsStylusHandler::RequestStylusHardwareState, - weak_ptr_factory_.GetWeakPtr())); -} - -void OptionsStylusHandler::OnAvailableNoteTakingAppsUpdated() { - UpdateNoteTakingApps(); -} - -void OptionsStylusHandler::OnPreferredNoteTakingAppUpdated(Profile* profile) { - if (Profile::FromWebUI(web_ui()) == profile) - UpdateNoteTakingApps(); -} - -void OptionsStylusHandler::OnDeviceListsComplete() { - SendHasStylus(); -} - -void OptionsStylusHandler::RequestStylusHardwareState( - const base::ListValue* args) { - if (ui::InputDeviceManager::GetInstance()->AreDeviceListsComplete()) - SendHasStylus(); -} - -void OptionsStylusHandler::SendHasStylus() { - DCHECK(ui::InputDeviceManager::GetInstance()->AreDeviceListsComplete()); - - web_ui()->CallJavascriptFunctionUnsafe( - "BrowserOptions.setStylusInputStatus", - base::Value(ash::palette_utils::HasStylusInput())); -} - -void OptionsStylusHandler::UpdateNoteTakingApps() { - bool waiting_for_android = false; - note_taking_app_ids_.clear(); - base::ListValue apps_list; - - NoteTakingHelper* helper = NoteTakingHelper::Get(); - if (helper->play_store_enabled() && !helper->android_apps_received()) { - // If Play Store is enabled but not ready yet, let the JS know so it can - // disable the menu and display an explanatory message. - waiting_for_android = true; - } else { - for (const NoteTakingAppInfo& info : - NoteTakingHelper::Get()->GetAvailableApps( - Profile::FromWebUI(web_ui()))) { - std::unique_ptr<base::DictionaryValue> dict( - new base::DictionaryValue()); - dict->SetString(kAppNameKey, info.name); - dict->SetString(kAppIdKey, info.app_id); - dict->SetBoolean(kAppPreferredKey, info.preferred); - apps_list.Append(std::move(dict)); - - note_taking_app_ids_.insert(info.app_id); - } - } - - web_ui()->CallJavascriptFunctionUnsafe("StylusOverlay.updateNoteTakingApps", - apps_list, - base::Value(waiting_for_android)); -} - -void OptionsStylusHandler::SetPreferredNoteTakingApp( - const base::ListValue* args) { - std::string app_id; - CHECK(args->GetString(0, &app_id)); - - // Sanity check: make sure that the ID we got back from WebUI is in the - // currently-available set. - if (!note_taking_app_ids_.count(app_id)) { - LOG(ERROR) << "Got unknown note-taking-app ID \"" << app_id << "\""; - return; - } - - NoteTakingHelper::Get()->SetPreferredApp(Profile::FromWebUI(web_ui()), - app_id); -} - -} // namespace options -} // namespace chromeos
diff --git a/chrome/browser/ui/webui/options/chromeos/options_stylus_handler.h b/chrome/browser/ui/webui/options/chromeos/options_stylus_handler.h deleted file mode 100644 index 3a51832..0000000 --- a/chrome/browser/ui/webui/options/chromeos/options_stylus_handler.h +++ /dev/null
@@ -1,72 +0,0 @@ -// Copyright (c) 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_OPTIONS_STYLUS_HANDLER_H_ -#define CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_OPTIONS_STYLUS_HANDLER_H_ - -#include <set> -#include <string> - -#include "base/macros.h" -#include "base/memory/weak_ptr.h" -#include "chrome/browser/chromeos/note_taking_helper.h" -#include "chrome/browser/ui/webui/options/options_ui.h" -#include "ui/events/devices/input_device_event_observer.h" - -class Profile; - -namespace base { -class ListValue; -} // namespace base - -namespace chromeos { -namespace options { - -// Stylus-specific options C++ code. -class OptionsStylusHandler : public ::options::OptionsPageUIHandler, - public NoteTakingHelper::Observer, - public ui::InputDeviceEventObserver { - public: - OptionsStylusHandler(); - ~OptionsStylusHandler() override; - - // OptionsPageUIHandler implementation. - void GetLocalizedValues(base::DictionaryValue* localized_strings) override; - void InitializePage() override; - void RegisterMessages() override; - - // NoteTakingHelper::Observer implementation. - void OnAvailableNoteTakingAppsUpdated() override; - void OnPreferredNoteTakingAppUpdated(Profile* profile) override; - - // ui::InputDeviceEventObserver implementation: - void OnDeviceListsComplete() override; - - private: - // Called from WebUI when the page is initialized to determine if stylus - // settings should be shown. - void RequestStylusHardwareState(const base::ListValue* args); - - // Sends if there is a stylus device to WebUI. - void SendHasStylus(); - - // Updates the note-taking app menu in the stylus overlay to display the - // currently-available set of apps. - void UpdateNoteTakingApps(); - - // Called from WebUI when the user selects a note-taking app. - void SetPreferredNoteTakingApp(const base::ListValue* args); - - // IDs of available note-taking apps. - std::set<std::string> note_taking_app_ids_; - - base::WeakPtrFactory<OptionsStylusHandler> weak_ptr_factory_; - - DISALLOW_COPY_AND_ASSIGN(OptionsStylusHandler); -}; - -} // namespace options -} // namespace chromeos - -#endif // CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_OPTIONS_STYLUS_HANDLER_H_
diff --git a/chrome/browser/ui/webui/options/chromeos/pointer_handler.cc b/chrome/browser/ui/webui/options/chromeos/pointer_handler.cc deleted file mode 100644 index a4ee792b..0000000 --- a/chrome/browser/ui/webui/options/chromeos/pointer_handler.cc +++ /dev/null
@@ -1,87 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/webui/options/chromeos/pointer_handler.h" - -#include "base/macros.h" -#include "base/strings/utf_string_conversions.h" -#include "base/values.h" -#include "chrome/common/url_constants.h" -#include "chrome/grit/generated_resources.h" -#include "content/public/browser/web_ui.h" -#include "ui/base/l10n/l10n_util.h" - -namespace chromeos { -namespace options { - -PointerHandler::PointerHandler() - : has_touchpad_(false), - has_mouse_(false) { -} - -PointerHandler::~PointerHandler() { -} - -void PointerHandler::GetLocalizedValues( - base::DictionaryValue* localized_strings) { - DCHECK(localized_strings); - - static OptionsStringResource resources[] = { - { "pointerOverlayTitleTouchpadOnly", - IDS_OPTIONS_POINTER_TOUCHPAD_OVERLAY_TITLE }, - { "pointerOverlayTitleMouseOnly", - IDS_OPTIONS_POINTER_MOUSE_OVERLAY_TITLE }, - { "pointerOverlayTitleTouchpadMouse", - IDS_OPTIONS_POINTER_TOUCHPAD_MOUSE_OVERLAY_TITLE }, - { "pointerOverlaySectionTitleTouchpad", - IDS_OPTIONS_POINTER_OVERLAY_SECTION_TITLE_TOUCHPAD }, - { "pointerOverlaySectionTitleMouse", - IDS_OPTIONS_POINTER_OVERLAY_SECTION_TITLE_MOUSE }, - { "enableTapToClick", - IDS_OPTIONS_SETTINGS_TAP_TO_CLICK_ENABLED_DESCRIPTION }, - { "primaryMouseRight", - IDS_OPTIONS_SETTINGS_PRIMARY_MOUSE_RIGHT_DESCRIPTION }, - { "traditionalScroll", - IDS_OPTIONS_SETTINGS_TRADITIONAL_SCROLL_DESCRIPTION }, - }; - - localized_strings->SetString("naturalScroll", - l10n_util::GetStringFUTF16( - IDS_OPTIONS_SETTINGS_NATURAL_SCROLL_DESCRIPTION, - base::ASCIIToUTF16(chrome::kNaturalScrollHelpURL))); - - RegisterStrings(localized_strings, resources, arraysize(resources)); -} - - -void PointerHandler::TouchpadExists(bool exists) { - has_touchpad_ = exists; - base::Value val(exists); - web_ui()->CallJavascriptFunctionUnsafe("PointerOverlay.showTouchpadControls", - val); - UpdateTitle(); -} - -void PointerHandler::MouseExists(bool exists) { - has_mouse_ = exists; - base::Value val(exists); - web_ui()->CallJavascriptFunctionUnsafe("PointerOverlay.showMouseControls", - val); - UpdateTitle(); -} - -void PointerHandler::UpdateTitle() { - std::string label; - if (has_touchpad_) { - label = has_mouse_ ? "pointerOverlayTitleTouchpadMouse" : - "pointerOverlayTitleTouchpadOnly"; - } else { - label = has_mouse_ ? "pointerOverlayTitleMouseOnly" : ""; - } - base::Value val(label); - web_ui()->CallJavascriptFunctionUnsafe("PointerOverlay.setTitle", val); -} - -} // namespace options -} // namespace chromeos
diff --git a/chrome/browser/ui/webui/options/chromeos/pointer_handler.h b/chrome/browser/ui/webui/options/chromeos/pointer_handler.h deleted file mode 100644 index d0d4c48..0000000 --- a/chrome/browser/ui/webui/options/chromeos/pointer_handler.h +++ /dev/null
@@ -1,47 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_POINTER_HANDLER_H_ -#define CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_POINTER_HANDLER_H_ - -#include "base/compiler_specific.h" -#include "base/macros.h" -#include "base/memory/weak_ptr.h" -#include "chrome/browser/chromeos/system/pointer_device_observer.h" -#include "chrome/browser/ui/webui/options/options_ui.h" -#include "components/prefs/pref_member.h" - -namespace chromeos { -namespace options { - -// Pointer settings overlay page UI handler. -class PointerHandler - : public ::options::OptionsPageUIHandler, - public chromeos::system::PointerDeviceObserver::Observer { - public: - PointerHandler(); - ~PointerHandler() override; - - // OptionsPageUIHandler implementation. - void GetLocalizedValues(base::DictionaryValue* localized_strings) override; - - private: - // PointerDeviceObserver implementation. - void TouchpadExists(bool exists) override; - void MouseExists(bool exists) override; - - // Set the title dynamically based on whether a touchpad and/or mouse is - // detected. - void UpdateTitle(); - - bool has_touchpad_; - bool has_mouse_; - - DISALLOW_COPY_AND_ASSIGN(PointerHandler); -}; - -} // namespace options -} // namespace chromeos - -#endif // CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_POINTER_HANDLER_H_
diff --git a/chrome/browser/ui/webui/options/chromeos/power_handler.cc b/chrome/browser/ui/webui/options/chromeos/power_handler.cc deleted file mode 100644 index d522183..0000000 --- a/chrome/browser/ui/webui/options/chromeos/power_handler.cc +++ /dev/null
@@ -1,173 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/webui/options/chromeos/power_handler.h" - -#include <utility> - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/strings/string_number_conversions.h" -#include "base/strings/utf_string_conversions.h" -#include "base/values.h" -#include "chrome/browser/ui/ash/ash_util.h" -#include "chrome/common/chrome_switches.h" -#include "chrome/grit/generated_resources.h" -#include "content/public/browser/web_ui.h" -#include "ui/base/l10n/l10n_util.h" -#include "ui/base/l10n/time_format.h" -#include "ui/base/resource/resource_bundle.h" -#include "ui/base/webui/web_ui_util.h" - -using ash::PowerStatus; - -namespace chromeos { -namespace options { - -PowerHandler::PowerHandler() { - // TODO(mash): Support Chrome power settings in Mash. crbug.com/644348 - this->show_power_status_ = !ash_util::IsRunningInMash() && - (switches::PowerOverlayEnabled() || - (PowerStatus::Get()->IsBatteryPresent() && - PowerStatus::Get()->SupportsDualRoleDevices())); -} - -PowerHandler::~PowerHandler() { - if (this->show_power_status_) - PowerStatus::Get()->RemoveObserver(this); -} - -void PowerHandler::GetLocalizedValues( - base::DictionaryValue* localized_strings) { - DCHECK(localized_strings); - RegisterTitle(localized_strings, "powerOverlay", - IDS_OPTIONS_POWER_OVERLAY_TITLE); - localized_strings->SetString( - "batteryStatusLabel", - l10n_util::GetStringUTF16(IDS_OPTIONS_BATTERY_STATUS_LABEL)); - localized_strings->SetBoolean( - "showPowerStatus", this->show_power_status_); - localized_strings->SetString( - "powerSourceLabel", - l10n_util::GetStringUTF16(IDS_OPTIONS_POWER_SOURCE_LABEL)); - localized_strings->SetString( - "powerSourceBattery", - l10n_util::GetStringUTF16(IDS_OPTIONS_POWER_SOURCE_BATTERY)); - localized_strings->SetString( - "powerSourceAcAdapter", - l10n_util::GetStringUTF16(IDS_OPTIONS_POWER_SOURCE_AC_ADAPTER)); - localized_strings->SetString( - "powerSourceLowPowerCharger", - l10n_util::GetStringUTF16(IDS_OPTIONS_POWER_SOURCE_LOW_POWER_CHARGER)); - localized_strings->SetString( - "calculatingPower", - l10n_util::GetStringUTF16(IDS_OPTIONS_POWER_OVERLAY_CALCULATING)); -} - -void PowerHandler::InitializePage() { - if (this->show_power_status_) - PowerStatus::Get()->RequestStatusUpdate(); -} - -void PowerHandler::RegisterMessages() { - if (this->show_power_status_) - PowerStatus::Get()->AddObserver(this); - // Callback to fetch the power info. - web_ui()->RegisterMessageCallback( - "updatePowerStatus", - base::Bind(&PowerHandler::UpdatePowerStatus, base::Unretained(this))); - // Callback to set the power source. - web_ui()->RegisterMessageCallback( - "setPowerSource", - base::Bind(&PowerHandler::SetPowerSource, base::Unretained(this))); -} - -void PowerHandler::OnPowerStatusChanged() { - web_ui()->CallJavascriptFunctionUnsafe( - "options.PowerOverlay.setBatteryStatusText", - base::Value(GetStatusValue())); - UpdatePowerSources(); -} - -base::string16 PowerHandler::GetStatusValue() const { - PowerStatus* status = PowerStatus::Get(); - if (!status->IsBatteryPresent()) - return base::string16(); - - bool charging = status->IsBatteryCharging(); - bool calculating = status->IsBatteryTimeBeingCalculated(); - int percent = status->GetRoundedBatteryPercent(); - base::TimeDelta time_left; - bool show_time = false; - - if (!calculating) { - time_left = charging ? status->GetBatteryTimeToFull() : - status->GetBatteryTimeToEmpty(); - show_time = PowerStatus::ShouldDisplayBatteryTime(time_left); - } - - if (!show_time) { - return l10n_util::GetStringFUTF16(IDS_OPTIONS_BATTERY_STATUS_SHORT, - base::IntToString16(percent)); - } else { - int hour = 0; - int min = 0; - PowerStatus::SplitTimeIntoHoursAndMinutes(time_left, &hour, &min); - - base::string16 time_text; - if (hour == 0 || min == 0) { - // Display only one unit ("2 hours" or "10 minutes"). - time_text = ui::TimeFormat::Simple(ui::TimeFormat::FORMAT_DURATION, - ui::TimeFormat::LENGTH_LONG, - time_left); - } else { - time_text = ui::TimeFormat::Detailed(ui::TimeFormat::FORMAT_DURATION, - ui::TimeFormat::LENGTH_LONG, - -1, // force hour and minute output - time_left); - } - - return l10n_util::GetStringFUTF16( - charging ? IDS_OPTIONS_BATTERY_STATUS_CHARGING : - IDS_OPTIONS_BATTERY_STATUS, - base::IntToString16(percent), - time_text); - } -} - -void PowerHandler::UpdatePowerStatus(const base::ListValue* args) { - PowerStatus::Get()->RequestStatusUpdate(); -} - -void PowerHandler::SetPowerSource(const base::ListValue* args) { - std::string id; - if (!args->GetString(0, &id)) { - NOTREACHED(); - return; - } - PowerStatus::Get()->SetPowerSource(id); -} - -void PowerHandler::UpdatePowerSources() { - PowerStatus* status = PowerStatus::Get(); - - base::ListValue sources_list; - for (const auto& source : status->GetPowerSources()) { - std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); - dict->SetString("id", source.id); - dict->SetInteger("type", source.type); - dict->SetString("description", - l10n_util::GetStringUTF16(source.description_id)); - sources_list.Append(std::move(dict)); - } - - web_ui()->CallJavascriptFunctionUnsafe( - "options.PowerOverlay.setPowerSources", sources_list, - base::Value(status->GetCurrentPowerSourceID()), - base::Value(status->IsUsbChargerConnected()), - base::Value(status->IsBatteryTimeBeingCalculated())); -} - -} // namespace options -} // namespace chromeos
diff --git a/chrome/browser/ui/webui/options/chromeos/power_handler.h b/chrome/browser/ui/webui/options/chromeos/power_handler.h deleted file mode 100644 index 843749b..0000000 --- a/chrome/browser/ui/webui/options/chromeos/power_handler.h +++ /dev/null
@@ -1,54 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_POWER_HANDLER_H_ -#define CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_POWER_HANDLER_H_ - -#include "ash/system/power/power_status.h" -#include "base/macros.h" -#include "base/strings/string16.h" -#include "chrome/browser/ui/webui/options/options_ui.h" - -namespace chromeos { -namespace options { - -// Shows battery status and power settings. -class PowerHandler : public ::options::OptionsPageUIHandler, - public ash::PowerStatus::Observer { - public: - PowerHandler(); - ~PowerHandler() override; - - // OptionsPageUIHandler implementation. - void GetLocalizedValues(base::DictionaryValue* localized_strings) override; - void InitializePage() override; - void RegisterMessages() override; - - // ash::PowerStatus::Observer implementation. - void OnPowerStatusChanged() override; - -private: - // Gets the battery status text, showing the percentage and time remaining if - // calculated. Returns an empty string if there is no battery. - base::string16 GetStatusValue() const; - - // Handler to request updating the power status. - void UpdatePowerStatus(const base::ListValue* args); - - // Handler to change the power source. - void SetPowerSource(const base::ListValue* args); - - // Updates the UI with the latest power source information. - void UpdatePowerSources(); - - // Whether the UI should show the power status. - bool show_power_status_; - - DISALLOW_COPY_AND_ASSIGN(PowerHandler); -}; - -} // namespace options -} // namespace chromeos - -#endif // CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_POWER_HANDLER_H_
diff --git a/chrome/browser/ui/webui/options/chromeos/proxy_handler.cc b/chrome/browser/ui/webui/options/chromeos/proxy_handler.cc deleted file mode 100644 index 6a6a7062..0000000 --- a/chrome/browser/ui/webui/options/chromeos/proxy_handler.cc +++ /dev/null
@@ -1,76 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/webui/options/chromeos/proxy_handler.h" - -#include "base/callback.h" -#include "base/macros.h" -#include "base/stl_util.h" -#include "base/strings/utf_string_conversions.h" -#include "base/time/time.h" -#include "base/values.h" -#include "chrome/browser/chromeos/system/input_device_settings.h" -#include "chrome/common/chrome_constants.h" -#include "chrome/grit/generated_resources.h" -#include "chromeos/chromeos_constants.h" -#include "content/public/browser/web_ui.h" -#include "ui/base/l10n/l10n_util.h" - -namespace chromeos { -namespace options { - -ProxyHandler::ProxyHandler() { -} - -ProxyHandler::~ProxyHandler() { -} - -void ProxyHandler::GetLocalizedValues( - base::DictionaryValue* localized_strings) { - DCHECK(localized_strings); - - // Proxy page - ChromeOS - static OptionsStringResource resources[] = { - { "proxyPage", IDS_OPTIONS_PROXY_TAB_LABEL }, - { "proxyDirectInternetConnection", IDS_PROXY_DIRECT_CONNECTION }, - { "proxyManual", IDS_PROXY_MANUAL_CONFIG }, - { "sameProxyProtocols", IDS_PROXY_SAME_FORALL }, - { "httpProxy", IDS_PROXY_HTTP_PROXY }, - { "secureHttpProxy", IDS_PROXY_HTTP_SECURE_HTTP_PROXY }, - { "ftpProxy", IDS_PROXY_FTP_PROXY }, - { "socksHost", IDS_PROXY_SOCKS_HOST }, - { "proxyAutomatic", IDS_PROXY_AUTOMATIC }, - { "proxyUseConfigUrl", IDS_PROXY_USE_AUTOCONFIG_URL }, - { "addHost", IDS_PROXY_ADD_HOST }, - { "removeHost", IDS_PROXY_REMOVE_HOST }, - { "proxyPort", IDS_PROXY_PORT }, - { "proxyBypass", IDS_PROXY_BYPASS }, - { "proxyBannerPolicy", IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_PROXY_POLICY }, - { "proxyBannerExtension", - IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_PROXY_EXTENSION }, - { "proxyBannerOther", - IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_PROXY_OTHER_PRECEDE } - }; - - RegisterStrings(localized_strings, resources, arraysize(resources)); - - localized_strings->SetString("proxyBannerShared", - l10n_util::GetStringFUTF16( - IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_PROXY_ENABLE_SHARED_HINT, - l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_USE_SHARED_PROXIES))); -} - -void ProxyHandler::InitializePage() { - ::options::OptionsPageUIHandler::InitializePage(); - - bool keyboard_driven_oobe = - system::InputDeviceSettings::Get()->ForceKeyboardDrivenUINavigation(); - if (keyboard_driven_oobe) { - web_ui()->CallJavascriptFunctionUnsafe( - "DetailsInternetPage.initializeKeyboardFlow"); - } -} - -} // namespace options -} // namespace chromeos
diff --git a/chrome/browser/ui/webui/options/chromeos/proxy_handler.h b/chrome/browser/ui/webui/options/chromeos/proxy_handler.h deleted file mode 100644 index 4280207..0000000 --- a/chrome/browser/ui/webui/options/chromeos/proxy_handler.h +++ /dev/null
@@ -1,33 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_PROXY_HANDLER_H_ -#define CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_PROXY_HANDLER_H_ - -#include "base/compiler_specific.h" -#include "base/macros.h" -#include "chrome/browser/ui/webui/options/options_ui.h" - -namespace chromeos { -namespace options { - -// ChromeOS proxy options page UI handler. -class ProxyHandler : public ::options::OptionsPageUIHandler { - public: - explicit ProxyHandler(); - ~ProxyHandler() override; - - // OptionsPageUIHandler implementation. - void GetLocalizedValues(base::DictionaryValue* localized_strings) override; - void InitializePage() override; - - private: - - DISALLOW_COPY_AND_ASSIGN(ProxyHandler); -}; - -} // namespace options -} // namespace chromeos - -#endif // CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_PROXY_HANDLER_H_
diff --git a/chrome/browser/ui/webui/options/chromeos/stats_options_handler.cc b/chrome/browser/ui/webui/options/chromeos/stats_options_handler.cc deleted file mode 100644 index 93048cbaf..0000000 --- a/chrome/browser/ui/webui/options/chromeos/stats_options_handler.cc +++ /dev/null
@@ -1,46 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/webui/options/chromeos/stats_options_handler.h" - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/metrics/user_metrics.h" -#include "base/strings/utf_string_conversions.h" -#include "base/values.h" -#include "content/public/browser/web_ui.h" - -using base::UserMetricsAction; - -namespace chromeos { -namespace options { - -StatsOptionsHandler::StatsOptionsHandler() { -} - -// OptionsPageUIHandler implementation. -void StatsOptionsHandler::GetLocalizedValues( - base::DictionaryValue* localized_strings) { -} - -// WebUIMessageHandler implementation. -void StatsOptionsHandler::RegisterMessages() { - web_ui()->RegisterMessageCallback("metricsReportingCheckboxAction", - base::Bind(&StatsOptionsHandler::HandleMetricsReportingCheckbox, - base::Unretained(this))); -} - -void StatsOptionsHandler::HandleMetricsReportingCheckbox( - const base::ListValue* args) { -#if defined(GOOGLE_CHROME_BUILD) - const std::string checked_str = base::UTF16ToUTF8(ExtractStringValue(args)); - const bool enabled = (checked_str == "true"); - base::RecordAction( - enabled ? UserMetricsAction("Options_MetricsReportingCheckbox_Enable") - : UserMetricsAction("Options_MetricsReportingCheckbox_Disable")); -#endif -} - -} // namespace options -} // namespace chromeos
diff --git a/chrome/browser/ui/webui/options/chromeos/stats_options_handler.h b/chrome/browser/ui/webui/options/chromeos/stats_options_handler.h deleted file mode 100644 index 8c95f11..0000000 --- a/chrome/browser/ui/webui/options/chromeos/stats_options_handler.h +++ /dev/null
@@ -1,38 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_STATS_OPTIONS_HANDLER_H_ -#define CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_STATS_OPTIONS_HANDLER_H_ - -#include "base/compiler_specific.h" -#include "base/macros.h" -#include "chrome/browser/ui/webui/options/options_ui.h" - -namespace chromeos { -namespace options { - -// ChromeOS handler for "Stats/crash reporting to Google" option of the Advanced -// settings page. This handler does only ChromeOS-specific actions while default -// code is in Chrome's AdvancedOptionsHandler -// (chrome/browser/webui/advanced_options_handler.cc). -class StatsOptionsHandler : public ::options::OptionsPageUIHandler { - public: - StatsOptionsHandler(); - - // OptionsPageUIHandler implementation. - void GetLocalizedValues(base::DictionaryValue* localized_strings) override; - - // WebUIMessageHandler implementation. - void RegisterMessages() override; - - private: - void HandleMetricsReportingCheckbox(const base::ListValue* args); - - DISALLOW_COPY_AND_ASSIGN(StatsOptionsHandler); -}; - -} // namespace options -} // namespace chromeos - -#endif // CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_STATS_OPTIONS_HANDLER_H_
diff --git a/chrome/browser/ui/webui/options/chromeos/storage_manager_handler.cc b/chrome/browser/ui/webui/options/chromeos/storage_manager_handler.cc deleted file mode 100644 index d5d1da4..0000000 --- a/chrome/browser/ui/webui/options/chromeos/storage_manager_handler.cc +++ /dev/null
@@ -1,457 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/webui/options/chromeos/storage_manager_handler.h" - -#include <algorithm> -#include <numeric> -#include <string> - -#include "base/files/file_util.h" -#include "base/sys_info.h" -#include "base/task_scheduler/post_task.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/browsing_data/browsing_data_appcache_helper.h" -#include "chrome/browser/browsing_data/browsing_data_cache_storage_helper.h" -#include "chrome/browser/browsing_data/browsing_data_channel_id_helper.h" -#include "chrome/browser/browsing_data/browsing_data_cookie_helper.h" -#include "chrome/browser/browsing_data/browsing_data_database_helper.h" -#include "chrome/browser/browsing_data/browsing_data_file_system_helper.h" -#include "chrome/browser/browsing_data/browsing_data_flash_lso_helper.h" -#include "chrome/browser/browsing_data/browsing_data_indexed_db_helper.h" -#include "chrome/browser/browsing_data/browsing_data_local_storage_helper.h" -#include "chrome/browser/browsing_data/browsing_data_service_worker_helper.h" -#include "chrome/browser/chromeos/arc/arc_util.h" -#include "chrome/browser/chromeos/drive/file_system_util.h" -#include "chrome/browser/chromeos/file_manager/path_util.h" -#include "chrome/browser/platform_util.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/grit/generated_resources.h" -#include "chromeos/cryptohome/homedir_methods.h" -#include "components/arc/arc_util.h" -#include "components/browsing_data/content/conditional_cache_counting_helper.h" -#include "components/drive/chromeos/file_system_interface.h" -#include "components/user_manager/user_manager.h" -#include "content/public/browser/browser_context.h" -#include "content/public/browser/storage_partition.h" -#include "ui/base/l10n/l10n_util.h" -#include "ui/base/text/bytes_formatting.h" - -namespace chromeos { -namespace options { -namespace { - -void GetSizeStatAsync(const base::FilePath& mount_path, - int64_t* total_size, - int64_t* available_size) { - int64_t size = base::SysInfo::AmountOfTotalDiskSpace(mount_path); - if (size >= 0) - *total_size = size; - size = base::SysInfo::AmountOfFreeDiskSpace(mount_path); - if (size >= 0) - *available_size = size; -} - -// Threshold to show a message indicating space is critically low (512 MB). -const int64_t kSpaceCriticallyLowBytes = 512 * 1024 * 1024; - -// Threshold to show a message indicating space is low (1 GB). -const int64_t kSpaceLowBytes = 1 * 1024 * 1024 * 1024; - -} // namespace - -StorageManagerHandler::StorageManagerHandler() - : browser_cache_size_(-1), - has_browser_cache_size_(false), - browser_site_data_size_(-1), - has_browser_site_data_size_(false), - updating_downloads_size_(false), - updating_drive_cache_size_(false), - updating_browsing_data_size_(false), - updating_arc_size_(false), - updating_other_users_size_(false), - weak_ptr_factory_(this) { -} - -StorageManagerHandler::~StorageManagerHandler() { -} - -void StorageManagerHandler::GetLocalizedValues( - base::DictionaryValue* localized_strings) { - DCHECK(localized_strings); - - RegisterTitle(localized_strings, "storageManagerPage", - IDS_OPTIONS_SETTINGS_STORAGE_MANAGER_TAB_TITLE); - RegisterTitle(localized_strings, "storageClearDriveCachePage", - IDS_OPTIONS_SETTINGS_STORAGE_CLEAR_DRIVE_CACHE_TAB_TITLE); - - localized_strings->SetString( - "storageItemLabelCapacity", l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_STORAGE_ITEM_LABEL_CAPACITY)); - localized_strings->SetString( - "storageItemLabelInUse", l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_STORAGE_ITEM_LABEL_IN_USE)); - localized_strings->SetString( - "storageItemLabelAvailable", l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_STORAGE_ITEM_LABEL_AVAILABLE)); - localized_strings->SetString( - "storageSubitemLabelDownloads", l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_STORAGE_SUBITEM_LABEL_DOWNLOADS)); - localized_strings->SetString( - "storageSubitemLabelDriveCache", l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_STORAGE_SUBITEM_LABEL_DRIVE_CACHE)); - localized_strings->SetString( - "storageSubitemLabelBrowsingData", l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_STORAGE_SUBITEM_LABEL_BROWSING_DATA)); - localized_strings->SetString( - "storageSubitemLabelOtherUsers", l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_STORAGE_SUBITEM_LABEL_OTHER_USERS)); - localized_strings->SetString( - "storageSubitemLabelArc", l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_STORAGE_SUBITEM_LABEL_ARC)); - localized_strings->SetString( - "storageSizeCalculating", l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_STORAGE_SIZE_CALCULATING)); - localized_strings->SetString( - "storageClearDriveCacheDialogTitle", l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_STORAGE_CLEAR_DRIVE_CACHE_DIALOG_TITLE)); - localized_strings->SetString( - "storageClearDriveCacheDescription", l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_STORAGE_CLEAR_DRIVE_CACHE_DESCRIPTION)); - localized_strings->SetString( - "storageDeleteAllButtonTitle", l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_STORAGE_DELETE_ALL_BUTTON_TITLE)); - localized_strings->SetString( - "storageLowMessageTitle", l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_STORAGE_SPACE_LOW_MESSAGE_TITLE)); - localized_strings->SetString( - "storageLowMessageLine1", l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_STORAGE_SPACE_LOW_MESSAGE_LINE_1)); - localized_strings->SetString( - "storageLowMessageLine2", l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_STORAGE_SPACE_LOW_MESSAGE_LINE_2)); - localized_strings->SetString( - "storageCriticallyLowMessageTitle", l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_STORAGE_SPACE_CRITICALLY_LOW_MESSAGE_TITLE)); - localized_strings->SetString( - "storageCriticallyLowMessageLine1", l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_STORAGE_SPACE_CRITICALLY_LOW_MESSAGE_LINE_1)); - localized_strings->SetString( - "storageCriticallyLowMessageLine2", l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_STORAGE_SPACE_CRITICALLY_LOW_MESSAGE_LINE_2)); -} - -void StorageManagerHandler::InitializePage() { - DCHECK(web_ui()); -} - -void StorageManagerHandler::RegisterMessages() { - DCHECK(web_ui()); - - web_ui()->RegisterMessageCallback( - "updateStorageInfo", - base::Bind(&StorageManagerHandler::HandleUpdateStorageInfo, - weak_ptr_factory_.GetWeakPtr())); - web_ui()->RegisterMessageCallback( - "openDownloads", - base::Bind(&StorageManagerHandler::HandleOpenDownloads, - weak_ptr_factory_.GetWeakPtr())); - web_ui()->RegisterMessageCallback( - "openArcStorage", - base::Bind(&StorageManagerHandler::HandleOpenArcStorage, - weak_ptr_factory_.GetWeakPtr())); - web_ui()->RegisterMessageCallback( - "clearDriveCache", - base::Bind(&StorageManagerHandler::HandleClearDriveCache, - weak_ptr_factory_.GetWeakPtr())); -} - -void StorageManagerHandler::HandleUpdateStorageInfo( - const base::ListValue* unused_args) { - UpdateSizeStat(); - UpdateDownloadsSize(); - UpdateDriveCacheSize(); - UpdateBrowsingDataSize(); - UpdateOtherUsersSize(); - UpdateArcSize(); -} - -void StorageManagerHandler::HandleOpenDownloads( - const base::ListValue* unused_args) { - Profile* const profile = Profile::FromWebUI(web_ui()); - const base::FilePath downloads_path = - file_manager::util::GetDownloadsFolderForProfile(profile); - platform_util::OpenItem( - profile, - downloads_path, - platform_util::OPEN_FOLDER, - platform_util::OpenOperationCallback()); -} - -void StorageManagerHandler::HandleOpenArcStorage( - const base::ListValue* unused_args) { - auto* arc_storage_manager = arc::ArcStorageManager::GetForBrowserContext( - Profile::FromWebUI(web_ui())); - if (arc_storage_manager) - arc_storage_manager->OpenPrivateVolumeSettings(); -} - -void StorageManagerHandler::HandleClearDriveCache( - const base::ListValue* unused_args) { - drive::FileSystemInterface* const file_system = - drive::util::GetFileSystemByProfile(Profile::FromWebUI(web_ui())); - file_system->FreeDiskSpaceIfNeededFor( - std::numeric_limits<int64_t>::max(), // Removes as much as possible. - base::Bind(&StorageManagerHandler::OnClearDriveCacheDone, - weak_ptr_factory_.GetWeakPtr())); -} - -void StorageManagerHandler::UpdateSizeStat() { - Profile* const profile = Profile::FromWebUI(web_ui()); - const base::FilePath downloads_path = - file_manager::util::GetDownloadsFolderForProfile(profile); - - int64_t* total_size = new int64_t(0); - int64_t* available_size = new int64_t(0); - base::PostTaskWithTraitsAndReply( - FROM_HERE, {base::MayBlock(), base::TaskPriority::BACKGROUND}, - base::Bind(&GetSizeStatAsync, downloads_path, total_size, available_size), - base::Bind(&StorageManagerHandler::OnGetSizeStat, - weak_ptr_factory_.GetWeakPtr(), base::Owned(total_size), - base::Owned(available_size))); -} - -void StorageManagerHandler::OnGetSizeStat(int64_t* total_size, - int64_t* available_size) { - int64_t used_size = *total_size - *available_size; - base::DictionaryValue size_stat; - size_stat.SetString("totalSize", ui::FormatBytes(*total_size)); - size_stat.SetString("availableSize", ui::FormatBytes(*available_size)); - size_stat.SetString("usedSize", ui::FormatBytes(used_size)); - size_stat.SetDouble("usedRatio", - static_cast<double>(used_size) / *total_size); - int storage_space_state = STORAGE_SPACE_NORMAL; - if (*available_size < kSpaceCriticallyLowBytes) - storage_space_state = STORAGE_SPACE_CRITICALLY_LOW; - else if (*available_size < kSpaceLowBytes) - storage_space_state = STORAGE_SPACE_LOW; - size_stat.SetInteger("spaceState", storage_space_state); - - web_ui()->CallJavascriptFunctionUnsafe( - "options.StorageManager.setSizeStat", size_stat); -} - -void StorageManagerHandler::UpdateDownloadsSize() { - if (updating_downloads_size_) - return; - updating_downloads_size_ = true; - - Profile* const profile = Profile::FromWebUI(web_ui()); - const base::FilePath downloads_path = - file_manager::util::GetDownloadsFolderForProfile(profile); - - base::PostTaskWithTraitsAndReplyWithResult( - FROM_HERE, {base::MayBlock(), base::TaskPriority::BACKGROUND}, - base::Bind(&base::ComputeDirectorySize, downloads_path), - base::Bind(&StorageManagerHandler::OnGetDownloadsSize, - weak_ptr_factory_.GetWeakPtr())); -} - -void StorageManagerHandler::OnGetDownloadsSize(int64_t size) { - updating_downloads_size_ = false; - web_ui()->CallJavascriptFunctionUnsafe( - "options.StorageManager.setDownloadsSize", - base::Value(ui::FormatBytes(size))); -} - -void StorageManagerHandler::UpdateDriveCacheSize() { - if (updating_drive_cache_size_) - return; - - drive::FileSystemInterface* const file_system = - drive::util::GetFileSystemByProfile(Profile::FromWebUI(web_ui())); - if (!file_system) - return; - - // Shows the item "Offline cache" and start calculating size. - web_ui()->CallJavascriptFunctionUnsafe( - "options.StorageManager.showDriveCacheItem"); - updating_drive_cache_size_ = true; - file_system->CalculateCacheSize( - base::Bind(&StorageManagerHandler::OnGetDriveCacheSize, - weak_ptr_factory_.GetWeakPtr())); -} - -void StorageManagerHandler::OnGetDriveCacheSize(int64_t size) { - updating_drive_cache_size_ = false; - web_ui()->CallJavascriptFunctionUnsafe( - "options.StorageManager.setDriveCacheSize", - base::Value(ui::FormatBytes(size))); -} - -void StorageManagerHandler::UpdateBrowsingDataSize() { - if (updating_browsing_data_size_) - return; - updating_browsing_data_size_ = true; - - has_browser_cache_size_ = false; - has_browser_site_data_size_ = false; - Profile* const profile = Profile::FromWebUI(web_ui()); - // Fetch the size of http cache in browsing data. - // ConditionalCacheCountingHelper deletes itself when it is done. - browsing_data::ConditionalCacheCountingHelper::CreateForRange( - content::BrowserContext::GetDefaultStoragePartition(profile), - base::Time(), base::Time::Max()) - ->CountAndDestroySelfWhenFinished( - base::Bind(&StorageManagerHandler::OnGetCacheSize, - weak_ptr_factory_.GetWeakPtr())); - - // Fetch the size of site data in browsing data. - if (!site_data_size_collector_.get()) { - content::StoragePartition* storage_partition = - content::BrowserContext::GetDefaultStoragePartition(profile); - site_data_size_collector_.reset(new SiteDataSizeCollector( - storage_partition->GetPath(), - new BrowsingDataCookieHelper(profile->GetRequestContext()), - new BrowsingDataDatabaseHelper(profile), - new BrowsingDataLocalStorageHelper(profile), - new BrowsingDataAppCacheHelper(profile), - new BrowsingDataIndexedDBHelper( - storage_partition->GetIndexedDBContext()), - BrowsingDataFileSystemHelper::Create( - storage_partition->GetFileSystemContext()), - BrowsingDataChannelIDHelper::Create(profile->GetRequestContext()), - new BrowsingDataServiceWorkerHelper( - storage_partition->GetServiceWorkerContext()), - new BrowsingDataCacheStorageHelper( - storage_partition->GetCacheStorageContext()), - BrowsingDataFlashLSOHelper::Create(profile))); - } - site_data_size_collector_->Fetch( - base::Bind(&StorageManagerHandler::OnGetBrowsingDataSize, - weak_ptr_factory_.GetWeakPtr(), true)); -} - -void StorageManagerHandler::OnGetCacheSize(bool is_upper_limit, int64_t size) { - DCHECK(!is_upper_limit); - OnGetBrowsingDataSize(false, size); -} - -void StorageManagerHandler::OnGetBrowsingDataSize(bool is_site_data, - int64_t size) { - if (is_site_data) { - has_browser_site_data_size_ = true; - browser_site_data_size_ = size; - } else { - has_browser_cache_size_ = true; - browser_cache_size_ = size; - } - if (has_browser_cache_size_ && has_browser_site_data_size_) { - base::string16 size_string; - if (browser_cache_size_ >= 0 && browser_site_data_size_ >= 0) { - size_string = ui::FormatBytes( - browser_site_data_size_ + browser_cache_size_); - } else { - size_string = l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_STORAGE_SIZE_UNKNOWN); - } - updating_browsing_data_size_ = false; - web_ui()->CallJavascriptFunctionUnsafe( - "options.StorageManager.setBrowsingDataSize", base::Value(size_string)); - } -} - -void StorageManagerHandler::UpdateOtherUsersSize() { - if (updating_other_users_size_) - return; - updating_other_users_size_ = true; - - other_users_.clear(); - user_sizes_.clear(); - const user_manager::UserList& users = - user_manager::UserManager::Get()->GetUsers(); - for (auto* user : users) { - if (user->is_active()) - continue; - other_users_.push_back(user); - cryptohome::HomedirMethods::GetInstance()->GetAccountDiskUsage( - cryptohome::Identification(user->GetAccountId()), - base::Bind(&StorageManagerHandler::OnGetOtherUserSize, - weak_ptr_factory_.GetWeakPtr())); - } - // We should show "0 B" if there is no other user. - if (other_users_.empty()) { - updating_other_users_size_ = false; - web_ui()->CallJavascriptFunctionUnsafe( - "options.StorageManager.setOtherUsersSize", - base::Value(ui::FormatBytes(0))); - } -} - -void StorageManagerHandler::OnGetOtherUserSize(bool success, int64_t size) { - user_sizes_.push_back(success ? size : -1); - if (user_sizes_.size() == other_users_.size()) { - base::string16 size_string; - // If all the requests succeed, shows the total bytes in the UI. - if (std::count(user_sizes_.begin(), user_sizes_.end(), -1) == 0) { - size_string = ui::FormatBytes( - std::accumulate(user_sizes_.begin(), user_sizes_.end(), 0LL)); - } else { - size_string = l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_STORAGE_SIZE_UNKNOWN); - } - updating_other_users_size_ = false; - web_ui()->CallJavascriptFunctionUnsafe( - "options.StorageManager.setOtherUsersSize", base::Value(size_string)); - } -} - -void StorageManagerHandler::UpdateArcSize() { - if (updating_arc_size_) - return; - updating_arc_size_ = true; - - Profile* const profile = Profile::FromWebUI(web_ui()); - if (!arc::IsArcPlayStoreEnabledForProfile(profile) || - arc::IsArcOptInVerificationDisabled()) { - return; - } - - // Shows the item "Android apps and cache" and start calculating size. - web_ui()->CallJavascriptFunctionUnsafe( - "options.StorageManager.showArcItem"); - bool success = false; - auto* arc_storage_manager = - arc::ArcStorageManager::GetForBrowserContext(profile); - if (arc_storage_manager) { - success = arc_storage_manager->GetApplicationsSize(base::Bind( - &StorageManagerHandler::OnGetArcSize, weak_ptr_factory_.GetWeakPtr())); - } - if (!success) - updating_arc_size_ = false; -} - -void StorageManagerHandler::OnGetArcSize(bool succeeded, - arc::mojom::ApplicationsSizePtr size) { - base::string16 size_string; - if (succeeded) { - uint64_t total_bytes = size->total_code_bytes + - size->total_data_bytes + - size->total_cache_bytes; - size_string = ui::FormatBytes(total_bytes); - } else { - size_string = l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_STORAGE_SIZE_UNKNOWN); - } - updating_arc_size_ = false; - web_ui()->CallJavascriptFunctionUnsafe("options.StorageManager.setArcSize", - base::Value(size_string)); -} - -void StorageManagerHandler::OnClearDriveCacheDone(bool success) { - UpdateDriveCacheSize(); -} - -} // namespace options -} // namespace chromeos
diff --git a/chrome/browser/ui/webui/options/chromeos/storage_manager_handler.h b/chrome/browser/ui/webui/options/chromeos/storage_manager_handler.h deleted file mode 100644 index 052524e..0000000 --- a/chrome/browser/ui/webui/options/chromeos/storage_manager_handler.h +++ /dev/null
@@ -1,130 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_STORAGE_MANAGER_HANDLER_H_ -#define CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_STORAGE_MANAGER_HANDLER_H_ - -#include <stdint.h> - -#include <memory> -#include <vector> - -#include "base/macros.h" -#include "base/memory/weak_ptr.h" -#include "chrome/browser/browsing_data/site_data_size_collector.h" -#include "chrome/browser/ui/webui/options/options_ui.h" -#include "components/arc/storage_manager/arc_storage_manager.h" -#include "components/user_manager/user.h" - -namespace chromeos { -namespace options { - -// Storage manager overlay page UI handler. -class StorageManagerHandler : public ::options::OptionsPageUIHandler { - public: - // Enumeration for device state about remaining space. These values must be - // kept in sync with options.StorageSpaceState in JS code. - enum StorageSpaceState { - STORAGE_SPACE_NORMAL = 0, - STORAGE_SPACE_LOW = 1, - STORAGE_SPACE_CRITICALLY_LOW = 2, - }; - - StorageManagerHandler(); - ~StorageManagerHandler() override; - - // OptionsPageUIHandler implementation. - void GetLocalizedValues(base::DictionaryValue* localized_strings) override; - void InitializePage() override; - - // WebUIMessageHandler implementation. - void RegisterMessages() override; - - private: - // Handlers of JS messages. - void HandleUpdateStorageInfo(const base::ListValue* unused_args); - void HandleOpenDownloads(const base::ListValue* unused_args); - void HandleOpenArcStorage(const base::ListValue* unused_args); - void HandleClearDriveCache(const base::ListValue* unused_args); - - // Requests updating disk space information. - void UpdateSizeStat(); - - // Callback to update the UI about disk space information. - void OnGetSizeStat(int64_t* total_size, int64_t* available_size); - - // Requests updating the size of Downloads directory. - void UpdateDownloadsSize(); - - // Callback to update the UI about the size of Downloads directory. - void OnGetDownloadsSize(int64_t size); - - // Requests updating the size of Drive Cache. - void UpdateDriveCacheSize(); - - // Callback to update the UI about the size of Drive Cache. - void OnGetDriveCacheSize(int64_t size); - - // Requests updating the size of browsing data. - void UpdateBrowsingDataSize(); - - // Callback to receive the cache size. - void OnGetCacheSize(bool is_upper_limit, int64_t size); - - // Callback to update the UI about the size of browsing data. - void OnGetBrowsingDataSize(bool is_site_data, int64_t size); - - // Requests updating the total size of other users' data. - void UpdateOtherUsersSize(); - - // Callback to save the fetched user sizes and update the UI. - void OnGetOtherUserSize(bool success, int64_t size); - - // Requests updating the space size used by Android apps and cache. - void UpdateArcSize(); - - // Callback to update the UI about Android apps and cache. - void OnGetArcSize(bool succeeded, arc::mojom::ApplicationsSizePtr size); - - // Callback called when clearing Drive cache is done. - void OnClearDriveCacheDone(bool success); - - // Total size of cache data in browsing data. - int64_t browser_cache_size_; - - // True if we have already received the size of http cache. - bool has_browser_cache_size_; - - // Total size of site data in browsing data. - int64_t browser_site_data_size_; - - // True if we have already received the size of site data. - bool has_browser_site_data_size_; - - // The list of other users whose directory sizes will be accumulated as the - // size of "Other users". - user_manager::UserList other_users_; - - // Fetched sizes of user directories. - std::vector<int64_t> user_sizes_; - - // Helper to compute the total size of all types of site date. - std::unique_ptr<SiteDataSizeCollector> site_data_size_collector_; - - // Flags indicating fetch operations for storage sizes are ongoing. - bool updating_downloads_size_; - bool updating_drive_cache_size_; - bool updating_browsing_data_size_; - bool updating_arc_size_; - bool updating_other_users_size_; - - base::WeakPtrFactory<StorageManagerHandler> weak_ptr_factory_; - - DISALLOW_COPY_AND_ASSIGN(StorageManagerHandler); -}; - -} // namespace options -} // namespace chromeos - -#endif // CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_STORAGE_MANAGER_HANDLER_H_
diff --git a/chrome/browser/ui/webui/options/clear_browser_data_handler.cc b/chrome/browser/ui/webui/options/clear_browser_data_handler.cc deleted file mode 100644 index 0c3e07d..0000000 --- a/chrome/browser/ui/webui/options/clear_browser_data_handler.cc +++ /dev/null
@@ -1,441 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/webui/options/clear_browser_data_handler.h" - -#include <stddef.h> - -#include <memory> -#include <utility> - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/macros.h" -#include "base/memory/ptr_util.h" -#include "base/metrics/histogram_macros.h" -#include "base/metrics/sparse_histogram.h" -#include "base/strings/string16.h" -#include "base/strings/string_number_conversions.h" -#include "base/strings/utf_string_conversions.h" -#include "base/values.h" -#include "chrome/app/chrome_command_ids.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/browsing_data/browsing_data_counter_factory.h" -#include "chrome/browser/browsing_data/browsing_data_counter_utils.h" -#include "chrome/browser/browsing_data/browsing_data_helper.h" -#include "chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.h" -#include "chrome/browser/history/web_history_service_factory.h" -#include "chrome/browser/prefs/incognito_mode_prefs.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/sync/profile_sync_service_factory.h" -#include "chrome/browser/ui/accelerator_utils.h" -#include "chrome/common/channel_info.h" -#include "chrome/common/pref_names.h" -#include "chrome/grit/generated_resources.h" -#include "chrome/grit/locale_settings.h" -#include "components/browsing_data/core/counters/browsing_data_counter.h" -#include "components/browsing_data/core/history_notice_utils.h" -#include "components/browsing_data/core/pref_names.h" -#include "components/google/core/browser/google_util.h" -#include "components/prefs/pref_service.h" -#include "content/public/browser/browsing_data_remover.h" -#include "content/public/browser/notification_details.h" -#include "content/public/browser/web_ui.h" -#include "ui/base/accelerators/accelerator.h" -#include "ui/base/l10n/l10n_util.h" -#include "ui/events/keycodes/keyboard_codes.h" - -namespace { - -const char kClearBrowsingDataLearnMoreUrl[] = - "https://support.google.com/chrome/?p=settings_clear_browsing_data"; - -const char kMyActivityUrlInFooter[] = - "https://history.google.com/history/?utm_source=chrome_cbd"; - -const char kMyActivityUrlInDialog[] = - "https://history.google.com/history/?utm_source=chrome_n"; - -const int kMaxTimesHistoryNoticeShown = 1; - -const char* kCounterPrefs[] = { - browsing_data::prefs::kDeleteBrowsingHistory, - browsing_data::prefs::kDeleteCache, - browsing_data::prefs::kDeleteFormData, - browsing_data::prefs::kDeleteMediaLicenses, - browsing_data::prefs::kDeletePasswords, -}; - -} // namespace - -namespace options { - -ClearBrowserDataHandler::ClearBrowserDataHandler() - : remover_(nullptr), - sync_service_(nullptr), - should_show_history_notice_(false), - should_show_history_deletion_dialog_(false), - weak_ptr_factory_(this) { -} - -ClearBrowserDataHandler::~ClearBrowserDataHandler() { - if (remover_) - remover_->RemoveObserver(this); - if (sync_service_) - sync_service_->RemoveObserver(this); -} - -void ClearBrowserDataHandler::InitializeHandler() { - PrefService* prefs = Profile::FromWebUI(web_ui())->GetPrefs(); - clear_plugin_lso_data_enabled_.Init(prefs::kClearPluginLSODataEnabled, prefs); - allow_deleting_browser_history_.Init( - prefs::kAllowDeletingBrowserHistory, - prefs, - base::Bind(&ClearBrowserDataHandler::OnBrowsingHistoryPrefChanged, - base::Unretained(this))); - - if (AreCountersEnabled()) { - Profile* profile = Profile::FromWebUI(web_ui()); - for (const std::string& pref : kCounterPrefs) { - AddCounter( - BrowsingDataCounterFactory::GetForProfileAndPref(profile, pref)); - } - - sync_service_ = ProfileSyncServiceFactory::GetForProfile(profile); - if (sync_service_) - sync_service_->AddObserver(this); - } -} - -void ClearBrowserDataHandler::InitializePage() { - web_ui()->CallJavascriptFunctionUnsafe( - "ClearBrowserDataOverlay.createFooter", base::Value(AreCountersEnabled()), - base::Value(sync_service_ && sync_service_->IsSyncActive()), - base::Value(should_show_history_notice_)); - RefreshHistoryNotice(); - UpdateInfoBannerVisibility(); - OnBrowsingHistoryPrefChanged(); - bool removal_in_progress = !!remover_; - web_ui()->CallJavascriptFunctionUnsafe("ClearBrowserDataOverlay.setClearing", - base::Value(removal_in_progress)); - - web_ui()->CallJavascriptFunctionUnsafe( - "ClearBrowserDataOverlay.markInitializationComplete"); -} - -void ClearBrowserDataHandler::UpdateInfoBannerVisibility() { - base::string16 text; - - Profile* profile = Profile::FromWebUI(web_ui()); - auto availability = IncognitoModePrefs::GetAvailability(profile->GetPrefs()); - if (availability == IncognitoModePrefs::ENABLED) { - base::Time last_clear_time = base::Time::FromInternalValue( - profile->GetPrefs()->GetInt64( - browsing_data::prefs::kLastClearBrowsingDataTime)); - - const base::TimeDelta since_clear = base::Time::Now() - last_clear_time; - if (since_clear < base::TimeDelta::FromHours(base::Time::kHoursPerDay)) { - ui::Accelerator acc = chrome::GetPrimaryChromeAcceleratorForCommandId( - IDC_NEW_INCOGNITO_WINDOW); - DCHECK_NE(ui::VKEY_UNKNOWN, acc.key_code()); - text = l10n_util::GetStringFUTF16(IDS_CLEAR_BROWSING_DATA_INFO_BAR_TEXT, - acc.GetShortcutText()); - } - } - - web_ui()->CallJavascriptFunctionUnsafe( - "ClearBrowserDataOverlay.setBannerText", base::Value(text)); -} - -void ClearBrowserDataHandler::OnPageOpened(const base::ListValue* value) { - for (const auto& counter : counters_) { - DCHECK(AreCountersEnabled()); - counter->Restart(); - } -} - -void ClearBrowserDataHandler::GetLocalizedValues( - base::DictionaryValue* localized_strings) { - DCHECK(localized_strings); - - static OptionsStringResource resources[] = { - {"clearBrowserDataLabel", IDS_CLEAR_BROWSING_DATA_LABEL}, - {"clearBrowserDataSyncWarning", IDS_CLEAR_BROWSING_DATA_SYNCED_DELETION}, - {"clearBrowserDataSupportString", - AreCountersEnabled() ? IDS_CLEAR_BROWSING_DATA_SOME_STUFF_REMAINS_SIMPLE - : IDS_CLEAR_BROWSING_DATA_SOME_STUFF_REMAINS}, - {"clearBrowserDataHistoryNoticeTitle", - IDS_CLEAR_BROWSING_DATA_HISTORY_NOTICE_TITLE}, - {"clearBrowserDataHistoryNoticeOk", - IDS_CLEAR_BROWSING_DATA_HISTORY_NOTICE_OK}, - {"deleteBrowsingHistoryCheckbox", IDS_DEL_BROWSING_HISTORY_CHKBOX}, - {"deleteDownloadHistoryCheckbox", IDS_DEL_DOWNLOAD_HISTORY_CHKBOX}, - {"deleteCacheCheckbox", IDS_DEL_CACHE_CHKBOX}, - {"deleteCookiesCheckbox", IDS_DEL_COOKIES_CHKBOX}, - {"deleteCookiesFlashCheckbox", IDS_DEL_COOKIES_FLASH_CHKBOX}, - {"deletePasswordsCheckbox", IDS_DEL_PASSWORDS_CHKBOX}, - {"deleteFormDataCheckbox", IDS_DEL_FORM_DATA_CHKBOX}, - {"deleteHostedAppsDataCheckbox", IDS_DEL_HOSTED_APPS_DATA_CHKBOX}, - {"deleteMediaLicensesCheckbox", IDS_DEL_MEDIA_LICENSES_CHKBOX}, - {"clearBrowserDataCommit", IDS_CLEAR_BROWSING_DATA_COMMIT}, - {"flashStorageUrl", IDS_FLASH_STORAGE_URL}, - }; - - RegisterStrings(localized_strings, resources, arraysize(resources)); - RegisterTitle(localized_strings, "clearBrowserDataOverlay", - IDS_CLEAR_BROWSING_DATA_TITLE); - localized_strings->SetString("clearBrowsingDataLearnMoreUrl", - kClearBrowsingDataLearnMoreUrl); - localized_strings->SetString( - "clearBrowserDataHistoryFooter", - l10n_util::GetStringFUTF16( - IDS_CLEAR_BROWSING_DATA_HISTORY_FOOTER, - base::ASCIIToUTF16(kMyActivityUrlInFooter))); - localized_strings->SetString( - "clearBrowserDataHistoryNotice", - l10n_util::GetStringFUTF16( - IDS_CLEAR_BROWSING_DATA_HISTORY_NOTICE, - base::ASCIIToUTF16(kMyActivityUrlInDialog))); - - auto time_list = base::MakeUnique<base::ListValue>(); - for (int i = 0; i < 5; i++) { - base::string16 label_string; - switch (i) { - case 0: - label_string = l10n_util::GetStringUTF16(IDS_CLEAR_DATA_HOUR); - break; - case 1: - label_string = l10n_util::GetStringUTF16(IDS_CLEAR_DATA_DAY); - break; - case 2: - label_string = l10n_util::GetStringUTF16(IDS_CLEAR_DATA_WEEK); - break; - case 3: - label_string = l10n_util::GetStringUTF16(IDS_CLEAR_DATA_4WEEKS); - break; - case 4: - label_string = l10n_util::GetStringUTF16(IDS_CLEAR_DATA_EVERYTHING); - break; - } - std::unique_ptr<base::ListValue> option(new base::ListValue()); - option->AppendInteger(i); - option->AppendString(label_string); - time_list->Append(std::move(option)); - } - localized_strings->Set("clearBrowserDataTimeList", std::move(time_list)); - localized_strings->SetBoolean("showDeleteBrowsingHistoryCheckboxes", - !Profile::FromWebUI(web_ui())->IsSupervised()); -} - -void ClearBrowserDataHandler::RegisterMessages() { - // Setup handlers specific to this panel. - web_ui()->RegisterMessageCallback("performClearBrowserData", - base::Bind(&ClearBrowserDataHandler::HandleClearBrowserData, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("openedClearBrowserData", - base::Bind(&ClearBrowserDataHandler::OnPageOpened, - base::Unretained(this))); -} - -void ClearBrowserDataHandler::HandleClearBrowserData( - const base::ListValue* value) { - // We should never be called when the previous clearing has not yet finished. - CHECK(!remover_); - - Profile* profile = Profile::FromWebUI(web_ui()); - PrefService* prefs = profile->GetPrefs(); - - int site_data_mask = ChromeBrowsingDataRemoverDelegate::DATA_TYPE_SITE_DATA; - // Don't try to clear LSO data if it's not supported. - if (!*clear_plugin_lso_data_enabled_) - site_data_mask &= ~ChromeBrowsingDataRemoverDelegate::DATA_TYPE_PLUGIN_DATA; - - int remove_mask = 0; - int origin_mask = 0; - if (prefs->GetBoolean(browsing_data::prefs::kDeleteBrowsingHistory) && - *allow_deleting_browser_history_) { - remove_mask |= ChromeBrowsingDataRemoverDelegate::DATA_TYPE_HISTORY; - } - if (prefs->GetBoolean(browsing_data::prefs::kDeleteDownloadHistory) && - *allow_deleting_browser_history_) { - remove_mask |= content::BrowsingDataRemover::DATA_TYPE_DOWNLOADS; - } - if (prefs->GetBoolean(browsing_data::prefs::kDeleteCache)) - remove_mask |= content::BrowsingDataRemover::DATA_TYPE_CACHE; - if (prefs->GetBoolean(browsing_data::prefs::kDeleteCookies)) { - remove_mask |= site_data_mask; - origin_mask |= content::BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB; - } - if (prefs->GetBoolean(browsing_data::prefs::kDeletePasswords)) - remove_mask |= ChromeBrowsingDataRemoverDelegate::DATA_TYPE_PASSWORDS; - if (prefs->GetBoolean(browsing_data::prefs::kDeleteFormData)) - remove_mask |= ChromeBrowsingDataRemoverDelegate::DATA_TYPE_FORM_DATA; - if (prefs->GetBoolean(browsing_data::prefs::kDeleteMediaLicenses)) - remove_mask |= content::BrowsingDataRemover::DATA_TYPE_MEDIA_LICENSES; - if (prefs->GetBoolean(browsing_data::prefs::kDeleteHostedAppsData)) { - remove_mask |= site_data_mask; - origin_mask |= content::BrowsingDataRemover::ORIGIN_TYPE_PROTECTED_WEB; - } - - // Record the deletion of cookies and cache. - content::BrowsingDataRemover::CookieOrCacheDeletionChoice choice = - content::BrowsingDataRemover::NEITHER_COOKIES_NOR_CACHE; - if (prefs->GetBoolean(browsing_data::prefs::kDeleteCookies)) { - choice = prefs->GetBoolean(browsing_data::prefs::kDeleteCache) - ? content::BrowsingDataRemover::BOTH_COOKIES_AND_CACHE - : content::BrowsingDataRemover::ONLY_COOKIES; - } else if (prefs->GetBoolean(browsing_data::prefs::kDeleteCache)) { - choice = content::BrowsingDataRemover::ONLY_CACHE; - } - UMA_HISTOGRAM_ENUMERATION( - "History.ClearBrowsingData.UserDeletedCookieOrCacheFromDialog", choice, - content::BrowsingDataRemover::MAX_CHOICE_VALUE); - - // Record the circumstances under which passwords are deleted. - if (prefs->GetBoolean(browsing_data::prefs::kDeletePasswords)) { - static const char* other_types[] = { - browsing_data::prefs::kDeleteBrowsingHistory, - browsing_data::prefs::kDeleteDownloadHistory, - browsing_data::prefs::kDeleteCache, - browsing_data::prefs::kDeleteCookies, - browsing_data::prefs::kDeleteFormData, - browsing_data::prefs::kDeleteHostedAppsData, - browsing_data::prefs::kDeleteMediaLicenses, - }; - static size_t num_other_types = arraysize(other_types); - int checked_other_types = std::count_if( - other_types, - other_types + num_other_types, - [prefs](const std::string& pref) { return prefs->GetBoolean(pref); }); - UMA_HISTOGRAM_SPARSE_SLOWLY( - "History.ClearBrowsingData.PasswordsDeletion.AdditionalDatatypesCount", - checked_other_types); - } - - remover_ = content::BrowserContext::GetBrowsingDataRemover(profile); - remover_->AddObserver(this); - int period_selected = - prefs->GetInteger(browsing_data::prefs::kDeleteTimePeriod); - browsing_data::TimePeriod time_period = - static_cast<browsing_data::TimePeriod>(period_selected); - browsing_data::RecordDeletionForPeriod(time_period); - remover_->RemoveAndReply( - browsing_data::CalculateBeginDeleteTime(time_period), - browsing_data::CalculateEndDeleteTime(time_period), - remove_mask, origin_mask, this); - - // Store the clear browsing data time. Next time the clear browsing data - // dialog is open, this time is used to decide whether to display an info - // banner or not. - prefs->SetInt64(browsing_data::prefs::kLastClearBrowsingDataTime, - base::Time::Now().ToInternalValue()); -} - -void ClearBrowserDataHandler::OnBrowsingDataRemoverDone() { - remover_->RemoveObserver(this); - remover_ = nullptr; - - PrefService* prefs = Profile::FromWebUI(web_ui())->GetPrefs(); - int notice_shown_times = prefs->GetInteger( - browsing_data::prefs::kClearBrowsingDataHistoryNoticeShownTimes); - - // When the deletion is complete, we might show an additional dialog with - // a notice about other forms of browsing history. This is the case if - const bool show_notice = - // 1. The dialog is relevant for the user. - should_show_history_deletion_dialog_ && - // 2. The selected data types contained browsing history. - prefs->GetBoolean(browsing_data::prefs::kDeleteBrowsingHistory) && - // 3. The notice has been shown less than |kMaxTimesHistoryNoticeShown|. - notice_shown_times < kMaxTimesHistoryNoticeShown; - - if (show_notice) { - // Increment the preference. - prefs->SetInteger( - browsing_data::prefs::kClearBrowsingDataHistoryNoticeShownTimes, - notice_shown_times + 1); - } - - UMA_HISTOGRAM_BOOLEAN( - "History.ClearBrowsingData.ShownHistoryNoticeAfterClearing", show_notice); - - web_ui()->CallJavascriptFunctionUnsafe("ClearBrowserDataOverlay.doneClearing", - base::Value(show_notice)); -} - -void ClearBrowserDataHandler::OnBrowsingHistoryPrefChanged() { - web_ui()->CallJavascriptFunctionUnsafe( - "ClearBrowserDataOverlay.setAllowDeletingHistory", - base::Value(*allow_deleting_browser_history_)); -} - -void ClearBrowserDataHandler::AddCounter( - std::unique_ptr<browsing_data::BrowsingDataCounter> counter) { - DCHECK(AreCountersEnabled()); - - counter->Init(Profile::FromWebUI(web_ui())->GetPrefs(), - browsing_data::ClearBrowsingDataTab::ADVANCED, - base::Bind(&ClearBrowserDataHandler::UpdateCounterText, - base::Unretained(this))); - counters_.push_back(std::move(counter)); -} - -void ClearBrowserDataHandler::UpdateCounterText( - std::unique_ptr<browsing_data::BrowsingDataCounter::Result> result) { - DCHECK(AreCountersEnabled()); - web_ui()->CallJavascriptFunctionUnsafe( - "ClearBrowserDataOverlay.updateCounter", - base::Value(result->source()->GetPrefName()), - base::Value(GetChromeCounterTextFromResult(result.get()))); -} - -void ClearBrowserDataHandler::OnStateChanged(syncer::SyncService* sync) { - UpdateSyncState(); -} - -void ClearBrowserDataHandler::UpdateSyncState() { - web_ui()->CallJavascriptFunctionUnsafe( - "ClearBrowserDataOverlay.updateSyncWarningAndHistoryFooter", - base::Value(sync_service_ && sync_service_->IsSyncActive()), - base::Value(should_show_history_notice_)); -} - -void ClearBrowserDataHandler::RefreshHistoryNotice() { - browsing_data::ShouldShowNoticeAboutOtherFormsOfBrowsingHistory( - sync_service_, - WebHistoryServiceFactory::GetForProfile(Profile::FromWebUI(web_ui())), - base::Bind(&ClearBrowserDataHandler::UpdateHistoryNotice, - weak_ptr_factory_.GetWeakPtr())); - - // If the dialog with history notice has been shown less than - // |kMaxTimesHistoryNoticeShown| times, we might have to show it when the - // user deletes history. Find out if the conditions are met. - int notice_shown_times = Profile::FromWebUI(web_ui())->GetPrefs()->GetInteger( - browsing_data::prefs::kClearBrowsingDataHistoryNoticeShownTimes); - - if (notice_shown_times < kMaxTimesHistoryNoticeShown) { - browsing_data::ShouldPopupDialogAboutOtherFormsOfBrowsingHistory( - sync_service_, - WebHistoryServiceFactory::GetForProfile(Profile::FromWebUI(web_ui())), - chrome::GetChannel(), - base::Bind(&ClearBrowserDataHandler::UpdateHistoryDeletionDialog, - weak_ptr_factory_.GetWeakPtr())); - } -} - -void ClearBrowserDataHandler::UpdateHistoryNotice(bool show) { - should_show_history_notice_ = show; - UpdateSyncState(); - - UMA_HISTOGRAM_BOOLEAN( - "History.ClearBrowsingData.HistoryNoticeShownInFooterWhenUpdated", - should_show_history_notice_); -} - -void ClearBrowserDataHandler::UpdateHistoryDeletionDialog(bool show) { - // This is used by OnBrowsingDataRemoverDone (when the deletion finishes). - should_show_history_deletion_dialog_ = show; -} - -} // namespace options
diff --git a/chrome/browser/ui/webui/options/clear_browser_data_handler.h b/chrome/browser/ui/webui/options/clear_browser_data_handler.h deleted file mode 100644 index 8c6a259..0000000 --- a/chrome/browser/ui/webui/options/clear_browser_data_handler.h +++ /dev/null
@@ -1,108 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_WEBUI_OPTIONS_CLEAR_BROWSER_DATA_HANDLER_H_ -#define CHROME_BROWSER_UI_WEBUI_OPTIONS_CLEAR_BROWSER_DATA_HANDLER_H_ - -#include <memory> -#include <vector> - -#include "base/macros.h" -#include "chrome/browser/ui/webui/options/options_ui.h" -#include "components/browser_sync/profile_sync_service.h" -#include "components/browsing_data/core/counters/browsing_data_counter.h" -#include "components/prefs/pref_member.h" -#include "content/public/browser/browsing_data_remover.h" - -namespace options { - -// Clear browser data handler page UI handler. -class ClearBrowserDataHandler : public OptionsPageUIHandler, - public content::BrowsingDataRemover::Observer, - public syncer::SyncServiceObserver { - public: - ClearBrowserDataHandler(); - ~ClearBrowserDataHandler() override; - - // OptionsPageUIHandler implementation. - void GetLocalizedValues(base::DictionaryValue* localized_strings) override; - void InitializeHandler() override; - void InitializePage() override; - - // WebUIMessageHandler implementation. - void RegisterMessages() override; - - void UpdateInfoBannerVisibility(); - - private: - // Javascript callback for when the CBD dialog is opened. The caller does - // not provide any parameters, so |value| is unused. - void OnPageOpened(const base::ListValue* value); - - // Javascript callback to start clearing data. - void HandleClearBrowserData(const base::ListValue* value); - - // BrowsingDataRemover::Observer implementation. - // Closes the dialog once all requested data has been removed. - void OnBrowsingDataRemoverDone() override; - - // Updates UI when the pref to allow clearing history changes. - virtual void OnBrowsingHistoryPrefChanged(); - - // Adds a |counter| for browsing data. - void AddCounter(std::unique_ptr<browsing_data::BrowsingDataCounter> counter); - - // Updates a counter in the UI according to the |result|. - void UpdateCounterText( - std::unique_ptr<browsing_data::BrowsingDataCounter::Result> result); - - // Implementation of SyncServiceObserver. - void OnStateChanged(syncer::SyncService* sync) override; - - // Updates the support string at the bottom of the dialog. - void UpdateSyncState(); - - // Finds out whether we should show a notice informing the user about other - // forms of browsing history. Responds with an asynchronous callback to - // |UpdateHistoryNotice|. - void RefreshHistoryNotice(); - - // Shows or hides the notice about other forms of browsing history. - void UpdateHistoryNotice(bool show); - - // Remembers whether we should popup a dialog about other forms of browsing - // history when the user deletes the history for the first time. - void UpdateHistoryDeletionDialog(bool show); - - // If non-null it means removal is in progress. - content::BrowsingDataRemover* remover_; - - // Keeps track of whether clearing LSO data is supported. - BooleanPrefMember clear_plugin_lso_data_enabled_; - - // Keeps track of whether deleting browsing history and downloads is allowed. - BooleanPrefMember allow_deleting_browser_history_; - - // Counters that calculate the data volume for some of the data types. - std::vector<std::unique_ptr<browsing_data::BrowsingDataCounter>> counters_; - - // Informs us whether the user is syncing their data. - browser_sync::ProfileSyncService* sync_service_; - - // Whether we should show a notice about other forms of browsing history. - bool should_show_history_notice_; - - // Whether we should popup a dialog about other forms of browsing history - // when the user deletes their browsing history for the first time. - bool should_show_history_deletion_dialog_; - - // A weak pointer factory for asynchronous calls referencing this class. - base::WeakPtrFactory<ClearBrowserDataHandler> weak_ptr_factory_; - - DISALLOW_COPY_AND_ASSIGN(ClearBrowserDataHandler); -}; - -} // namespace options - -#endif // CHROME_BROWSER_UI_WEBUI_OPTIONS_CLEAR_BROWSER_DATA_HANDLER_H_
diff --git a/chrome/browser/ui/webui/options/content_settings_handler.cc b/chrome/browser/ui/webui/options/content_settings_handler.cc deleted file mode 100644 index fbdd9ee..0000000 --- a/chrome/browser/ui/webui/options/content_settings_handler.cc +++ /dev/null
@@ -1,1494 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/webui/options/content_settings_handler.h" - -#include <stddef.h> - -#include <algorithm> -#include <map> -#include <utility> -#include <vector> - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/command_line.h" -#include "base/i18n/number_formatting.h" -#include "base/logging.h" -#include "base/macros.h" -#include "base/memory/ptr_util.h" -#include "base/metrics/user_metrics.h" -#include "base/stl_util.h" -#include "base/strings/utf_string_conversions.h" -#include "base/values.h" -#include "build/build_config.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/chrome_notification_types.h" -#include "chrome/browser/content_settings/host_content_settings_map_factory.h" -#include "chrome/browser/content_settings/web_site_settings_uma_util.h" -#include "chrome/browser/custom_handlers/protocol_handler_registry.h" -#include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h" -#include "chrome/browser/extensions/extension_special_storage_policy.h" -#include "chrome/browser/notifications/desktop_notification_profile_util.h" -#include "chrome/browser/permissions/chooser_context_base.h" -#include "chrome/browser/permissions/permission_uma_util.h" -#include "chrome/browser/permissions/permission_util.h" -#include "chrome/browser/plugins/plugin_utils.h" -#include "chrome/browser/plugins/plugins_field_trial.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/browser_list.h" -#include "chrome/browser/ui/exclusive_access/exclusive_access_manager.h" -#include "chrome/browser/ui/webui/site_settings_helper.h" -#include "chrome/browser/usb/usb_chooser_context.h" -#include "chrome/browser/usb/usb_chooser_context_factory.h" -#include "chrome/common/chrome_features.h" -#include "chrome/common/chrome_switches.h" -#include "chrome/common/extensions/manifest_handlers/app_launch_info.h" -#include "chrome/common/features.h" -#include "chrome/common/pref_names.h" -#include "chrome/common/url_constants.h" -#include "chrome/grit/generated_resources.h" -#include "chrome/grit/locale_settings.h" -#include "components/content_settings/core/browser/content_settings_details.h" -#include "components/content_settings/core/browser/content_settings_utils.h" -#include "components/content_settings/core/browser/host_content_settings_map.h" -#include "components/content_settings/core/browser/website_settings_info.h" -#include "components/content_settings/core/browser/website_settings_registry.h" -#include "components/content_settings/core/common/content_settings.h" -#include "components/content_settings/core/common/content_settings_pattern.h" -#include "components/google/core/browser/google_util.h" -#include "components/prefs/pref_service.h" -#include "components/signin/core/common/profile_management_switches.h" -#include "components/user_prefs/user_prefs.h" -#include "content/public/browser/notification_service.h" -#include "content/public/browser/notification_source.h" -#include "content/public/browser/notification_types.h" -#include "content/public/browser/storage_partition.h" -#include "content/public/browser/web_contents.h" -#include "content/public/browser/web_ui.h" -#include "content/public/common/content_switches.h" -#include "content/public/common/page_zoom.h" -#include "content/public/common/url_constants.h" -#include "extensions/browser/extension_registry.h" -#include "extensions/common/extension_set.h" -#include "extensions/common/permissions/api_permission.h" -#include "extensions/common/permissions/permissions_data.h" -#include "ppapi/features/features.h" -#include "ui/base/l10n/l10n_util.h" - -#if defined(OS_CHROMEOS) -#include "components/user_manager/user_manager.h" -#endif - -using base::UserMetricsAction; -using content_settings::ContentSettingToString; -using content_settings::ContentSettingFromString; -using extensions::APIPermission; - -namespace options { - -namespace { - -struct ContentSettingWithExceptions { - ContentSettingWithExceptions(bool otr, UserMetricsAction action) - : has_otr_exceptions(otr), uma(action) {} - bool has_otr_exceptions; - UserMetricsAction uma; -}; - -// The AppFilter is used in AddExceptionsGrantedByHostedApps() to choose -// extensions which should have their extent displayed. -typedef bool (*AppFilter)(const extensions::Extension& app, - content::BrowserContext* profile); - -constexpr char kAppName[] = "appName"; -constexpr char kAppId[] = "appId"; -constexpr char kZoom[] = "zoom"; - -// A pseudo content type. We use it to display data like a content setting even -// though it is not a real content setting. -constexpr char kZoomContentType[] = "zoomlevels"; - -// Maps from a content settings type to a content setting with exceptions -// struct. -typedef std::map<ContentSettingsType, ContentSettingWithExceptions> - ExceptionsInfoMap; - -const ExceptionsInfoMap& GetExceptionsInfoMap() { - CR_DEFINE_STATIC_LOCAL(ExceptionsInfoMap, exceptions_info_map, ()); - if (exceptions_info_map.empty()) { - // With OTR exceptions. - exceptions_info_map.insert(std::make_pair( - CONTENT_SETTINGS_TYPE_COOKIES, - ContentSettingWithExceptions( - true, UserMetricsAction("Options_DefaultCookieSettingChanged")))); - exceptions_info_map.insert(std::make_pair( - CONTENT_SETTINGS_TYPE_IMAGES, - ContentSettingWithExceptions( - true, UserMetricsAction("Options_DefaultImagesSettingChanged")))); - exceptions_info_map.insert(std::make_pair( - CONTENT_SETTINGS_TYPE_JAVASCRIPT, - ContentSettingWithExceptions( - true, - UserMetricsAction("Options_DefaultJavaScriptSettingChanged")))); - exceptions_info_map.insert(std::make_pair( - CONTENT_SETTINGS_TYPE_PLUGINS, - ContentSettingWithExceptions( - true, UserMetricsAction("Options_DefaultPluginsSettingChanged")))); - exceptions_info_map.insert(std::make_pair( - CONTENT_SETTINGS_TYPE_POPUPS, - ContentSettingWithExceptions( - true, UserMetricsAction("Options_DefaultPopupsSettingChanged")))); - exceptions_info_map.insert(std::make_pair( - CONTENT_SETTINGS_TYPE_PPAPI_BROKER, - ContentSettingWithExceptions( - true, - UserMetricsAction("Options_DefaultPPAPIBrokerSettingChanged")))); -#if defined(OS_ANDROID) || defined(OS_CHROMEOS) - exceptions_info_map.insert(std::make_pair( - CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER, - ContentSettingWithExceptions( - true, - UserMetricsAction( - "Options_DefaultProtectedMediaIdentifierSettingChanged")))); -#endif - - // Without OTR exceptions. - exceptions_info_map.insert(std::make_pair( - CONTENT_SETTINGS_TYPE_NOTIFICATIONS, - ContentSettingWithExceptions( - false, - UserMetricsAction("Options_DefaultNotificationsSettingChanged")))); - exceptions_info_map.insert(std::make_pair( - CONTENT_SETTINGS_TYPE_GEOLOCATION, - ContentSettingWithExceptions( - false, - UserMetricsAction("Options_DefaultGeolocationSettingChanged")))); - exceptions_info_map.insert(std::make_pair( - CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC, - ContentSettingWithExceptions( - false, - UserMetricsAction("Options_DefaultMediaStreamMicSettingChanged")))); - exceptions_info_map.insert(std::make_pair( - CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, - ContentSettingWithExceptions( - false, UserMetricsAction( - "Options_DefaultMediaStreamCameraSettingChanged")))); - exceptions_info_map.insert(std::make_pair( - CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS, - ContentSettingWithExceptions( - false, UserMetricsAction( - "Options_DefaultMultipleAutomaticDLSettingChange")))); - exceptions_info_map.insert(std::make_pair( - CONTENT_SETTINGS_TYPE_MIDI_SYSEX, - ContentSettingWithExceptions( - false, - UserMetricsAction("Options_DefaultMIDISysExSettingChanged")))); - exceptions_info_map.insert(std::make_pair( - CONTENT_SETTINGS_TYPE_BACKGROUND_SYNC, - ContentSettingWithExceptions( - false, - UserMetricsAction("Options_DefaultBackgroundSyncSettingChanged")))); - } - - return exceptions_info_map; -} - -content::BrowserContext* GetBrowserContext(content::WebUI* web_ui) { - return web_ui->GetWebContents()->GetBrowserContext(); -} - -// Create a DictionaryValue* that will act as a data source for a single row -// in the Geolocation exceptions table. -std::unique_ptr<base::DictionaryValue> GetGeolocationExceptionForPage( - const ContentSettingsPattern& origin, - const ContentSettingsPattern& embedding_origin, - ContentSetting setting) { - auto exception = base::MakeUnique<base::DictionaryValue>(); - - std::string setting_string = - content_settings::ContentSettingToString(setting); - DCHECK(!setting_string.empty()); - - exception->SetString(site_settings::kSetting, setting_string); - exception->SetString(site_settings::kOrigin, origin.ToString()); - exception->SetString( - site_settings::kEmbeddingOrigin, embedding_origin.ToString()); - return exception; -} - -// Create a DictionaryValue* that will act as a data source for a single row -// in the desktop notifications exceptions table. -std::unique_ptr<base::DictionaryValue> GetNotificationExceptionForPage( - const ContentSettingsPattern& primary_pattern, - const ContentSettingsPattern& secondary_pattern, - ContentSetting setting, - const std::string& provider_name) { - std::string embedding_origin; - if (secondary_pattern != ContentSettingsPattern::Wildcard()) - embedding_origin = secondary_pattern.ToString(); - - auto exception = base::MakeUnique<base::DictionaryValue>(); - - std::string setting_string = - content_settings::ContentSettingToString(setting); - DCHECK(!setting_string.empty()); - - exception->SetString(site_settings::kSetting, setting_string); - exception->SetString(site_settings::kOrigin, primary_pattern.ToString()); - exception->SetString(site_settings::kEmbeddingOrigin, embedding_origin); - exception->SetString(site_settings::kSource, provider_name); - return exception; -} - -// Returns true whenever the |extension| is hosted and has |permission|. -// Must have the AppFilter signature. -template <APIPermission::ID permission> -bool HostedAppHasPermission(const extensions::Extension& extension, - content::BrowserContext* /* context */) { - return extension.is_hosted_app() && - extension.permissions_data()->HasAPIPermission(permission); -} - -// Add an "Allow"-entry to the list of |exceptions| for a |url_pattern| from -// the web extent of a hosted |app|. -void AddExceptionForHostedApp(const std::string& url_pattern, - const extensions::Extension& app, base::ListValue* exceptions) { - std::unique_ptr<base::DictionaryValue> exception(new base::DictionaryValue()); - - std::string setting_string = - content_settings::ContentSettingToString(CONTENT_SETTING_ALLOW); - DCHECK(!setting_string.empty()); - - exception->SetString(site_settings::kSetting, setting_string); - exception->SetString(site_settings::kOrigin, url_pattern); - exception->SetString(site_settings::kEmbeddingOrigin, url_pattern); - exception->SetString(site_settings::kSource, "HostedApp"); - exception->SetString(kAppName, app.name()); - exception->SetString(kAppId, app.id()); - exceptions->Append(std::move(exception)); -} - -// Asks the |profile| for hosted apps which have the |permission| set, and -// adds their web extent and launch URL to the |exceptions| list. -void AddExceptionsGrantedByHostedApps(content::BrowserContext* context, - AppFilter app_filter, - base::ListValue* exceptions) { - const extensions::ExtensionSet& extensions = - extensions::ExtensionRegistry::Get(context)->enabled_extensions(); - for (extensions::ExtensionSet::const_iterator extension = extensions.begin(); - extension != extensions.end(); ++extension) { - if (!app_filter(*extension->get(), context)) - continue; - - extensions::URLPatternSet web_extent = (*extension)->web_extent(); - // Add patterns from web extent. - for (extensions::URLPatternSet::const_iterator pattern = web_extent.begin(); - pattern != web_extent.end(); ++pattern) { - std::string url_pattern = pattern->GetAsString(); - AddExceptionForHostedApp(url_pattern, *extension->get(), exceptions); - } - // Retrieve the launch URL. - GURL launch_url = - extensions::AppLaunchInfo::GetLaunchWebURL(extension->get()); - // Skip adding the launch URL if it is part of the web extent. - if (web_extent.MatchesURL(launch_url)) - continue; - AddExceptionForHostedApp(launch_url.spec(), *extension->get(), exceptions); - } -} - -} // namespace - -ContentSettingsHandler::MediaSettingsInfo::MediaSettingsInfo() { -} - -ContentSettingsHandler::MediaSettingsInfo::~MediaSettingsInfo() { -} - -ContentSettingsHandler::MediaSettingsInfo::ForFlash::ForFlash() - : default_setting(CONTENT_SETTING_DEFAULT), - initialized(false), - last_refresh_request_id(0) { -} - -ContentSettingsHandler::MediaSettingsInfo::ForFlash::~ForFlash() { -} - -ContentSettingsHandler::MediaSettingsInfo::ForFlash& - ContentSettingsHandler::MediaSettingsInfo::forFlash() { - return flash_settings_; -} - -ContentSettingsHandler::MediaSettingsInfo::ForOneType& - ContentSettingsHandler::MediaSettingsInfo::forType( - ContentSettingsType type) { - if (type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC) - return mic_settings_; - else if (type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA) - return camera_settings_; - - NOTREACHED(); - return mic_settings_; -} - -ContentSettingsHandler::MediaSettingsInfo::ForOneType::ForOneType() - : show_flash_default_link(false), - show_flash_exceptions_link(false), - default_setting(CONTENT_SETTING_DEFAULT), - policy_disable(false), - default_setting_initialized(false), - exceptions_initialized(false) { -} - -ContentSettingsHandler::MediaSettingsInfo::ForOneType::~ForOneType() { -} - -ContentSettingsHandler::ContentSettingsHandler() : observer_(this) { -} - -ContentSettingsHandler::~ContentSettingsHandler() { -} - -void ContentSettingsHandler::GetLocalizedValues( - base::DictionaryValue* localized_strings) { - DCHECK(localized_strings); - - static OptionsStringResource resources[] = { - {"allowException", IDS_EXCEPTIONS_ALLOW_BUTTON}, - {"blockException", IDS_EXCEPTIONS_BLOCK_BUTTON}, - {"sessionException", IDS_EXCEPTIONS_SESSION_ONLY_BUTTON}, - {"askException", IDS_EXCEPTIONS_ASK_BUTTON}, - {"otrExceptionsExplanation", IDS_EXCEPTIONS_OTR_LABEL}, - {"addNewExceptionInstructions", IDS_EXCEPTIONS_ADD_NEW_INSTRUCTIONS}, - {"manageExceptions", IDS_EXCEPTIONS_MANAGE}, - {"manageHandlers", IDS_HANDLERS_MANAGE}, - {"exceptionPatternHeader", IDS_EXCEPTIONS_PATTERN_HEADER}, - {"exceptionBehaviorHeader", IDS_EXCEPTIONS_ACTION_HEADER}, - {"exceptionUsbDeviceHeader", IDS_EXCEPTIONS_USB_DEVICE_HEADER}, - {"exceptionZoomHeader", IDS_EXCEPTIONS_ZOOM_HEADER}, - {"embeddedOnHost", IDS_EXCEPTIONS_GEOLOCATION_EMBEDDED_ON_HOST}, - // Cookies filter. - {"cookiesTabLabel", IDS_COOKIES_TAB_LABEL}, - {"cookiesHeader", IDS_COOKIES_HEADER}, - {"cookiesAllow", IDS_COOKIES_ALLOW_RADIO}, - {"cookiesBlock", IDS_COOKIES_BLOCK_RADIO}, - {"cookiesSessionOnly", IDS_COOKIES_SESSION_ONLY_RADIO}, - {"cookiesBlock3rdParty", IDS_COOKIES_BLOCK_3RDPARTY_CHKBOX}, - {"cookiesShowCookies", IDS_COOKIES_SHOW_COOKIES_BUTTON}, - {"flashStorageSettings", IDS_FLASH_STORAGE_SETTINGS}, - {"flashStorageUrl", IDS_FLASH_STORAGE_URL}, -#if BUILDFLAG(ENABLE_GOOGLE_NOW) - {"googleGeolocationAccessEnable", - IDS_GEOLOCATION_GOOGLE_ACCESS_ENABLE_CHKBOX}, -#endif - // Image filter. - {"imagesTabLabel", IDS_IMAGES_TAB_LABEL}, - {"imagesHeader", IDS_IMAGES_HEADER}, - {"imagesAllow", IDS_IMAGES_LOAD_RADIO}, - {"imagesBlock", IDS_IMAGES_NOLOAD_RADIO}, - // JavaScript filter. - {"javascriptTabLabel", IDS_JAVASCRIPT_TAB_LABEL}, - {"javascriptHeader", IDS_JAVASCRIPT_HEADER}, - {"javascriptAllow", IDS_JS_ALLOW_RADIO}, - {"javascriptBlock", IDS_JS_DONOTALLOW_RADIO}, - // Plugins filter. - {"pluginsTabLabel", IDS_FLASH_TAB_LABEL}, - {"pluginsHeader", IDS_FLASH_HEADER}, - {"pluginsAllow", IDS_FLASH_ALLOW_RADIO}, - {"pluginsBlock", IDS_FLASH_BLOCK_RADIO}, - // Pop-ups filter. - {"popupsTabLabel", IDS_POPUP_TAB_LABEL}, - {"popupsHeader", IDS_POPUP_HEADER}, - {"popupsAllow", IDS_POPUP_ALLOW_RADIO}, - {"popupsBlock", IDS_POPUP_BLOCK_RADIO}, - // Location filter. - {"locationTabLabel", IDS_GEOLOCATION_TAB_LABEL}, - {"locationHeader", IDS_GEOLOCATION_HEADER}, - {"locationAllow", IDS_GEOLOCATION_ALLOW_RADIO}, - {"locationAsk", IDS_GEOLOCATION_ASK_RADIO}, - {"locationBlock", IDS_GEOLOCATION_BLOCK_RADIO}, - {"setBy", IDS_GEOLOCATION_SET_BY_HOVER}, - // Notifications filter. - {"notificationsTabLabel", IDS_NOTIFICATIONS_TAB_LABEL}, - {"notificationsHeader", IDS_NOTIFICATIONS_HEADER}, - {"notificationsAllow", IDS_NOTIFICATIONS_ALLOW_RADIO}, - {"notificationsAsk", IDS_NOTIFICATIONS_ASK_RADIO}, - {"notificationsBlock", IDS_NOTIFICATIONS_BLOCK_RADIO}, - // Protected Content filter - {"protectedContentTabLabel", IDS_PROTECTED_CONTENT_TAB_LABEL}, - {"protectedContentEnableCheckbox", IDS_PROTECTED_CONTENT_ENABLE_CHECKBOX}, -#if defined(OS_CHROMEOS) || defined(OS_WIN) - {"protectedContentInfo", IDS_PROTECTED_CONTENT_INFO}, - {"protectedContentEnableIdentifiersCheckbox", - IDS_PROTECTED_CONTENT_ENABLE_IDENTIFIERS_CHECKBOX}, - {"protectedContentHeader", IDS_PROTECTED_CONTENT_HEADER}, -#endif // defined(OS_CHROMEOS) || defined(OS_WIN) - // Microphone filter. - {"mediaStreamMicTabLabel", IDS_MEDIA_STREAM_MIC_TAB_LABEL}, - {"mediaStreamMicHeader", IDS_MEDIA_STREAM_MIC_HEADER}, - {"mediaStreamMicAsk", IDS_MEDIA_STREAM_ASK_AUDIO_ONLY_RADIO}, - {"mediaStreamMicBlock", IDS_MEDIA_STREAM_BLOCK_AUDIO_ONLY_RADIO}, - // Camera filter. - {"mediaStreamCameraTabLabel", IDS_MEDIA_STREAM_CAMERA_TAB_LABEL}, - {"mediaStreamCameraHeader", IDS_MEDIA_STREAM_CAMERA_HEADER}, - {"mediaStreamCameraAsk", IDS_MEDIA_STREAM_ASK_VIDEO_ONLY_RADIO}, - {"mediaStreamCameraBlock", IDS_MEDIA_STREAM_BLOCK_VIDEO_ONLY_RADIO}, - // Flash media settings. - {"mediaPepperFlashMicDefaultDivergedLabel", - IDS_MEDIA_PEPPER_FLASH_MIC_DEFAULT_DIVERGED_LABEL}, - {"mediaPepperFlashCameraDefaultDivergedLabel", - IDS_MEDIA_PEPPER_FLASH_CAMERA_DEFAULT_DIVERGED_LABEL}, - {"mediaPepperFlashMicExceptionsDivergedLabel", - IDS_MEDIA_PEPPER_FLASH_MIC_EXCEPTIONS_DIVERGED_LABEL}, - {"mediaPepperFlashCameraExceptionsDivergedLabel", - IDS_MEDIA_PEPPER_FLASH_CAMERA_EXCEPTIONS_DIVERGED_LABEL}, - {"mediaPepperFlashChangeLink", IDS_MEDIA_PEPPER_FLASH_CHANGE_LINK}, - {"mediaPepperFlashGlobalPrivacyURL", IDS_FLASH_GLOBAL_PRIVACY_URL}, - {"mediaPepperFlashWebsitePrivacyURL", IDS_FLASH_WEBSITE_PRIVACY_URL}, - // PPAPI broker filter. - {"ppapiBrokerHeader", IDS_PPAPI_BROKER_HEADER}, - {"ppapiBrokerTabLabel", IDS_PPAPI_BROKER_TAB_LABEL}, - {"ppapiBrokerAllow", IDS_PPAPI_BROKER_ALLOW_RADIO}, - {"ppapiBrokerAsk", IDS_PPAPI_BROKER_ASK_RADIO}, - {"ppapiBrokerBlock", IDS_PPAPI_BROKER_BLOCK_RADIO}, - // Multiple automatic downloads. - {"multipleAutomaticDownloadsTabLabel", IDS_AUTOMATIC_DOWNLOADS_TAB_LABEL}, - {"multipleAutomaticDownloadsHeader", IDS_AUTOMATIC_DOWNLOADS_TAB_LABEL}, - {"multipleAutomaticDownloadsAllow", IDS_AUTOMATIC_DOWNLOADS_ALLOW_RADIO}, - {"multipleAutomaticDownloadsAsk", IDS_AUTOMATIC_DOWNLOADS_ASK_RADIO}, - {"multipleAutomaticDownloadsBlock", IDS_AUTOMATIC_DOWNLOADS_BLOCK_RADIO}, - // MIDI system exclusive messages. - {"midiSysexHeader", IDS_MIDI_SYSEX_TAB_LABEL}, - {"midiSysExAllow", IDS_MIDI_SYSEX_ALLOW_RADIO}, - {"midiSysExAsk", IDS_MIDI_SYSEX_ASK_RADIO}, - {"midiSysExBlock", IDS_MIDI_SYSEX_BLOCK_RADIO}, - // Push messaging strings. - {"pushMessagingHeader", IDS_PUSH_MESSAGES_TAB_LABEL}, - {"pushMessagingAllow", IDS_PUSH_MESSSAGING_ALLOW_RADIO}, - {"pushMessagingAsk", IDS_PUSH_MESSSAGING_ASK_RADIO}, - {"pushMessagingBlock", IDS_PUSH_MESSSAGING_BLOCK_RADIO}, - // USB devices. - {"usbDevicesHeader", IDS_USB_DEVICES_HEADER_AND_TAB_LABEL}, - {"usbDevicesManage", IDS_USB_DEVICES_MANAGE_BUTTON}, - // Background sync. - {"backgroundSyncHeader", IDS_BACKGROUND_SYNC_HEADER}, - {"backgroundSyncAllow", IDS_BACKGROUND_SYNC_ALLOW_RADIO}, - {"backgroundSyncBlock", IDS_BACKGROUND_SYNC_BLOCK_RADIO}, - // Zoom levels. - {"zoomlevelsHeader", IDS_ZOOMLEVELS_HEADER_AND_TAB_LABEL}, - {"zoomLevelsManage", IDS_ZOOMLEVELS_MANAGE_BUTTON}, - // PDF Plugin filter. - {"pdfTabLabel", IDS_PDF_TAB_LABEL}, - {"pdfEnable", IDS_PDF_ENABLE_CHECKBOX}, - }; - - RegisterStrings(localized_strings, resources, arraysize(resources)); - - // TODO(tommycli): When the HTML5 By Default feature flag is on, we want to - // display strings that begin with "Ask...", even though the setting remains - // DETECT. Once this feature is finalized, then we migrate the setting to ASK. - Profile* profile = Profile::FromWebUI(web_ui()); - bool is_hbd = PluginUtils::ShouldPreferHtmlOverPlugins( - HostContentSettingsMapFactory::GetForProfile(profile)); - static OptionsStringResource flash_strings[] = { - {"pluginsDetectImportantContent", - is_hbd ? IDS_FLASH_ASK_RECOMMENDED_RADIO - : IDS_FLASH_DETECT_RECOMMENDED_RADIO}, - {"detectException", - is_hbd ? IDS_EXCEPTIONS_ASK_BUTTON - : IDS_EXCEPTIONS_DETECT_IMPORTANT_CONTENT_BUTTON}, - }; - RegisterStrings(localized_strings, flash_strings, arraysize(flash_strings)); - - PrefService* prefs = Profile::FromWebUI(web_ui())->GetPrefs(); - const base::Value* default_pref = prefs->GetDefaultPrefValue( - content_settings::WebsiteSettingsRegistry::GetInstance() - ->Get(CONTENT_SETTINGS_TYPE_PLUGINS) - ->default_value_pref_name()); - - int default_value = CONTENT_SETTING_DEFAULT; - bool success = default_pref->GetAsInteger(&default_value); - DCHECK(success); - DCHECK_NE(CONTENT_SETTING_DEFAULT, default_value); - - RegisterTitle(localized_strings, "contentSettingsPage", - IDS_CONTENT_SETTINGS_TITLE); - - // Register titles for each of the individual settings whose exception - // dialogs will be processed by |ContentSettingsHandler|. - RegisterTitle(localized_strings, "cookies", - IDS_COOKIES_TAB_LABEL); - RegisterTitle(localized_strings, "images", - IDS_IMAGES_TAB_LABEL); - RegisterTitle(localized_strings, "javascript", - IDS_JAVASCRIPT_TAB_LABEL); - RegisterTitle(localized_strings, "plugins", IDS_FLASH_TAB_LABEL); - RegisterTitle(localized_strings, "popups", - IDS_POPUP_TAB_LABEL); - RegisterTitle(localized_strings, "location", - IDS_GEOLOCATION_TAB_LABEL); - RegisterTitle(localized_strings, "notifications", - IDS_NOTIFICATIONS_TAB_LABEL); -#if defined(OS_CHROMEOS) - RegisterTitle(localized_strings, "protectedContent", - IDS_PROTECTED_CONTENT_TAB_LABEL); -#endif - RegisterTitle(localized_strings, "media-stream-mic", - IDS_MEDIA_STREAM_MIC_TAB_LABEL); - RegisterTitle(localized_strings, "media-stream-camera", - IDS_MEDIA_STREAM_CAMERA_TAB_LABEL); - RegisterTitle(localized_strings, "ppapi-broker", - IDS_PPAPI_BROKER_TAB_LABEL); - RegisterTitle(localized_strings, "multiple-automatic-downloads", - IDS_AUTOMATIC_DOWNLOADS_TAB_LABEL); - RegisterTitle(localized_strings, "midi-sysex", - IDS_MIDI_SYSEX_TAB_LABEL); - RegisterTitle(localized_strings, "usb-devices", - IDS_USB_DEVICES_HEADER_AND_TAB_LABEL); - RegisterTitle(localized_strings, "background-sync", - IDS_BACKGROUND_SYNC_HEADER); - RegisterTitle(localized_strings, "zoomlevels", - IDS_ZOOMLEVELS_HEADER_AND_TAB_LABEL); - - localized_strings->SetString("exceptionsLearnMoreUrl", - chrome::kContentSettingsExceptionsLearnMoreURL); -} - -void ContentSettingsHandler::InitializeHandler() { - notification_registrar_.Add( - this, chrome::NOTIFICATION_PROFILE_CREATED, - content::NotificationService::AllSources()); - notification_registrar_.Add( - this, chrome::NOTIFICATION_PROFILE_DESTROYED, - content::NotificationService::AllSources()); - - content::BrowserContext* context = GetBrowserContext(web_ui()); - notification_registrar_.Add( - this, chrome::NOTIFICATION_PROTOCOL_HANDLER_REGISTRY_CHANGED, - content::Source<content::BrowserContext>(context)); - - PrefService* prefs = user_prefs::UserPrefs::Get(context); - pref_change_registrar_.Init(prefs); - pref_change_registrar_.Add( - prefs::kPepperFlashSettingsEnabled, - base::Bind(&ContentSettingsHandler::OnPepperFlashPrefChanged, - base::Unretained(this))); - pref_change_registrar_.Add( - prefs::kAudioCaptureAllowed, - base::Bind(&ContentSettingsHandler::UpdateSettingDefaultFromModel, - base::Unretained(this), - CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC)); - pref_change_registrar_.Add( - prefs::kAudioCaptureAllowedUrls, - base::Bind(&ContentSettingsHandler::UpdateExceptionsViewFromModel, - base::Unretained(this), - CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC)); - pref_change_registrar_.Add( - prefs::kVideoCaptureAllowed, - base::Bind(&ContentSettingsHandler::UpdateSettingDefaultFromModel, - base::Unretained(this), - CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA)); - pref_change_registrar_.Add( - prefs::kVideoCaptureAllowedUrls, - base::Bind(&ContentSettingsHandler::UpdateExceptionsViewFromModel, - base::Unretained(this), - CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA)); - pref_change_registrar_.Add( - prefs::kEnableDRM, - base::Bind( - &ContentSettingsHandler::UpdateProtectedContentExceptionsButton, - base::Unretained(this))); - - // Here we only subscribe to the HostZoomMap for the default storage partition - // since we don't allow the user to manage the zoom levels for apps. - // We're only interested in zoom-levels that are persisted, since the user - // is given the opportunity to view/delete these in the content-settings page. - host_zoom_map_subscription_ = - content::HostZoomMap::GetDefaultForBrowserContext(context) - ->AddZoomLevelChangedCallback( - base::Bind(&ContentSettingsHandler::OnZoomLevelChanged, - base::Unretained(this))); - - flash_settings_manager_.reset(new PepperFlashSettingsManager(this, context)); - - Profile* profile = Profile::FromWebUI(web_ui()); - observer_.Add(HostContentSettingsMapFactory::GetForProfile(profile)); - if (profile->HasOffTheRecordProfile()) { - auto* map = HostContentSettingsMapFactory::GetForProfile( - profile->GetOffTheRecordProfile()); - if (!observer_.IsObserving(map)) - observer_.Add(map); - } -} - -void ContentSettingsHandler::InitializePage() { - media_settings_.reset(new MediaSettingsInfo()); - RefreshFlashMediaSettings(); - - UpdateHandlersEnabledRadios(); - UpdateAllExceptionsViewsFromModel(); - UpdateAllChooserExceptionsViewsFromModel(); - UpdateProtectedContentExceptionsButton(); -} - -void ContentSettingsHandler::OnContentSettingChanged( - const ContentSettingsPattern& primary_pattern, - const ContentSettingsPattern& secondary_pattern, - ContentSettingsType content_type, - std::string resource_identifier) { - const ContentSettingsDetails details( - primary_pattern, secondary_pattern, content_type, resource_identifier); - // TODO(estade): we pretend update_all() is always true. - if (details.update_all_types()) { - UpdateAllExceptionsViewsFromModel(); - UpdateAllChooserExceptionsViewsFromModel(); - } else { - if (base::ContainsKey(GetExceptionsInfoMap(), details.type())) - UpdateExceptionsViewFromModel(details.type()); - } -} - -void ContentSettingsHandler::Observe( - int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) { - switch (type) { - case chrome::NOTIFICATION_PROFILE_DESTROYED: { - Profile* profile = content::Source<Profile>(source).ptr(); - HostContentSettingsMap* settings_map = - HostContentSettingsMapFactory::GetForProfile(profile); - if (profile->IsOffTheRecord() && - observer_.IsObserving(settings_map)) { - web_ui()->CallJavascriptFunctionUnsafe( - "ContentSettingsExceptionsArea.OTRProfileDestroyed"); - observer_.Remove(settings_map); - } - break; - } - - case chrome::NOTIFICATION_PROFILE_CREATED: { - Profile* profile = content::Source<Profile>(source).ptr(); - if (profile->IsOffTheRecord()) { - UpdateAllOTRExceptionsViewsFromModel(); - UpdateAllOTRChooserExceptionsViewsFromModel(); - observer_.Add(HostContentSettingsMapFactory::GetForProfile(profile)); - } - break; - } - - case chrome::NOTIFICATION_PROTOCOL_HANDLER_REGISTRY_CHANGED: { - UpdateHandlersEnabledRadios(); - break; - } - } -} - -void ContentSettingsHandler::OnGetPermissionSettingsCompleted( - uint32_t request_id, - bool success, - PP_Flash_BrowserOperations_Permission default_permission, - const ppapi::FlashSiteSettings& sites) { - MediaSettingsInfo::ForFlash& settings = media_settings_->forFlash(); - if (success && request_id == settings.last_refresh_request_id) { - settings.initialized = true; - settings.default_setting = - PepperFlashContentSettingsUtils::FlashPermissionToContentSetting( - default_permission); - PepperFlashContentSettingsUtils::FlashSiteSettingsToMediaExceptions( - sites, &settings.exceptions); - PepperFlashContentSettingsUtils::SortMediaExceptions( - &settings.exceptions); - - UpdateFlashMediaLinksVisibility(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC); - UpdateFlashMediaLinksVisibility(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA); - } -} - -void ContentSettingsHandler::UpdateSettingDefaultFromModel( - ContentSettingsType type) { - std::string provider_id; - HostContentSettingsMap* host_content_settings_map = - HostContentSettingsMapFactory::GetForProfile(GetProfile()); - ContentSetting default_setting = - host_content_settings_map->GetDefaultContentSetting(type, &provider_id); - -#if BUILDFLAG(ENABLE_PLUGINS) - default_setting = PluginsFieldTrial::EffectiveContentSetting( - host_content_settings_map, type, default_setting); -#endif - - // Camera and microphone default content settings cannot be set by the policy. - // However, the policy can disable them. Treat this case visually in the same - // way as if the policy set the default setting to BLOCK. Furthermore, compare - // the settings with Flash settings and show links to the Flash settings site - // if they differ. - if (type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC || - type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA) { - UpdateMediaSettingsFromPrefs(type); - if (media_settings_->forType(type).policy_disable) { - default_setting = CONTENT_SETTING_BLOCK; - provider_id = site_settings::SiteSettingSourceToString( - site_settings::SiteSettingSource::kPolicy); - } - } - - base::DictionaryValue filter_settings; - - std::string setting_string = - content_settings::ContentSettingToString(default_setting); - DCHECK(!setting_string.empty()); - - filter_settings.SetString( - site_settings::ContentSettingsTypeToGroupName(type) + ".value", - setting_string); - filter_settings.SetString( - site_settings::ContentSettingsTypeToGroupName(type) + ".managedBy", - provider_id); - - web_ui()->CallJavascriptFunctionUnsafe( - "ContentSettings.setContentFilterSettingsValue", filter_settings); -} - -void ContentSettingsHandler::UpdateMediaSettingsFromPrefs( - ContentSettingsType type) { - PrefService* prefs = user_prefs::UserPrefs::Get(GetBrowserContext(web_ui())); - HostContentSettingsMap* settings_map = - HostContentSettingsMapFactory::GetForProfile(GetProfile()); - MediaSettingsInfo::ForOneType& settings = media_settings_->forType(type); - std::string policy_pref = (type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC) - ? prefs::kAudioCaptureAllowed - : prefs::kVideoCaptureAllowed; - - settings.policy_disable = !prefs->GetBoolean(policy_pref) && - prefs->IsManagedPreference(policy_pref); - settings.default_setting = - settings_map->GetDefaultContentSetting(type, nullptr); - settings.default_setting_initialized = true; - - UpdateFlashMediaLinksVisibility(type); - UpdateMediaDeviceDropdownVisibility(type); -} - -void ContentSettingsHandler::UpdateHandlersEnabledRadios() { - base::Value handlers_enabled(GetProtocolHandlerRegistry()->enabled()); - - web_ui()->CallJavascriptFunctionUnsafe( - "ContentSettings.updateHandlersEnabledRadios", handlers_enabled); -} - -void ContentSettingsHandler::UpdateAllExceptionsViewsFromModel() { - const ExceptionsInfoMap& exceptions_info_map = GetExceptionsInfoMap(); - for (const auto& exceptions_info_pair : exceptions_info_map) - UpdateExceptionsViewFromModel(exceptions_info_pair.first); - - // Zoom levels are not actually a content type so we need to handle them - // separately. - UpdateZoomLevelsExceptionsView(); -} - -void ContentSettingsHandler::UpdateAllOTRExceptionsViewsFromModel() { - const ExceptionsInfoMap& exceptions_info_map = GetExceptionsInfoMap(); - for (const auto& exceptions_info_pair : exceptions_info_map) { - if (exceptions_info_pair.second.has_otr_exceptions) { - UpdateExceptionsViewFromOTRHostContentSettingsMap( - exceptions_info_pair.first); - } - } -} - -void ContentSettingsHandler::UpdateExceptionsViewFromModel( - ContentSettingsType type) { - if (type == CONTENT_SETTINGS_TYPE_GEOLOCATION) { - UpdateGeolocationExceptionsView(); - } else if (type == CONTENT_SETTINGS_TYPE_NOTIFICATIONS) { - UpdateNotificationExceptionsView(); - } else if (type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC || - type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA) { - CompareMediaExceptionsWithFlash(type); - UpdateExceptionsViewFromHostContentSettingsMap(type); - } else if (type == CONTENT_SETTINGS_TYPE_MIDI_SYSEX) { - UpdateMIDISysExExceptionsView(); - } else { - UpdateExceptionsViewFromHostContentSettingsMap(type); - } -} - -// TODO(estade): merge with GetExceptionsFromHostContentSettingsMap. -void ContentSettingsHandler::UpdateGeolocationExceptionsView() { - Profile* profile = Profile::FromWebUI(web_ui()); - HostContentSettingsMap* map = - HostContentSettingsMapFactory::GetForProfile(profile); - - ContentSettingsForOneType all_settings; - map->GetSettingsForOneType( - CONTENT_SETTINGS_TYPE_GEOLOCATION, - std::string(), - &all_settings); - - // Group geolocation settings by primary_pattern. - site_settings::AllPatternsSettings all_patterns_settings; - for (ContentSettingsForOneType::iterator i = all_settings.begin(); - i != all_settings.end(); ++i) { - // Don't add default settings. - if (i->primary_pattern == ContentSettingsPattern::Wildcard() && - i->secondary_pattern == ContentSettingsPattern::Wildcard() && - i->source != site_settings::SiteSettingSourceToString( - site_settings::SiteSettingSource::kPreference)) { - continue; - } - all_patterns_settings[std::make_pair(i->primary_pattern, i->source)] - [i->secondary_pattern] = i->GetContentSetting(); - } - - base::ListValue exceptions; - AddExceptionsGrantedByHostedApps( - profile, - HostedAppHasPermission<APIPermission::kGeolocation>, - &exceptions); - - for (site_settings::AllPatternsSettings::iterator i = - all_patterns_settings.begin(); i != all_patterns_settings.end(); ++i) { - const ContentSettingsPattern& primary_pattern = i->first.first; - const site_settings::OnePatternSettings& one_settings = i->second; - - site_settings::OnePatternSettings::const_iterator parent = - one_settings.find(primary_pattern); - - // Add the "parent" entry for the non-embedded setting. - ContentSetting parent_setting = - parent == one_settings.end() ? CONTENT_SETTING_DEFAULT : parent->second; - exceptions.Append(GetGeolocationExceptionForPage(primary_pattern, - primary_pattern, - parent_setting)); - - // Add the "children" for any embedded settings. - for (site_settings::OnePatternSettings::const_iterator j = - one_settings.begin(); - j != one_settings.end(); - ++j) { - // Skip the non-embedded setting which we already added above. - if (j == parent) - continue; - - exceptions.Append(GetGeolocationExceptionForPage( - primary_pattern, j->first, j->second)); - } - } - - base::Value type_string(site_settings::ContentSettingsTypeToGroupName( - CONTENT_SETTINGS_TYPE_GEOLOCATION)); - web_ui()->CallJavascriptFunctionUnsafe("ContentSettings.setExceptions", - type_string, exceptions); - - // This is mainly here to keep this function ideologically parallel to - // UpdateExceptionsViewFromHostContentSettingsMap(). - UpdateSettingDefaultFromModel(CONTENT_SETTINGS_TYPE_GEOLOCATION); -} - -void ContentSettingsHandler::UpdateNotificationExceptionsView() { - Profile* profile = Profile::FromWebUI(web_ui()); - ContentSettingsForOneType settings; - DesktopNotificationProfileUtil::GetNotificationsSettings(profile, &settings); - - base::ListValue exceptions; - AddExceptionsGrantedByHostedApps( - profile, - HostedAppHasPermission<APIPermission::kNotifications>, - &exceptions); - - for (ContentSettingsForOneType::const_iterator i = - settings.begin(); - i != settings.end(); - ++i) { - // Don't add default settings. - if (i->primary_pattern == ContentSettingsPattern::Wildcard() && - i->secondary_pattern == ContentSettingsPattern::Wildcard() && - i->source != site_settings::SiteSettingSourceToString( - site_settings::SiteSettingSource::kPreference)) { - continue; - } - - exceptions.Append(GetNotificationExceptionForPage( - i->primary_pattern, i->secondary_pattern, i->GetContentSetting(), - i->source)); - } - - base::Value type_string(site_settings::ContentSettingsTypeToGroupName( - CONTENT_SETTINGS_TYPE_NOTIFICATIONS)); - web_ui()->CallJavascriptFunctionUnsafe("ContentSettings.setExceptions", - type_string, exceptions); - - // This is mainly here to keep this function ideologically parallel to - // UpdateExceptionsViewFromHostContentSettingsMap(). - UpdateSettingDefaultFromModel(CONTENT_SETTINGS_TYPE_NOTIFICATIONS); -} - -void ContentSettingsHandler::CompareMediaExceptionsWithFlash( - ContentSettingsType type) { - MediaSettingsInfo::ForOneType& settings = media_settings_->forType(type); - HostContentSettingsMap* settings_map = - HostContentSettingsMapFactory::GetForProfile(GetProfile()); - const auto* extension_registry = - extensions::ExtensionRegistry::Get(GetProfile()); - base::ListValue exceptions; - site_settings::GetExceptionsFromHostContentSettingsMap( - settings_map, type, extension_registry, web_ui(), /*incognito=*/false, - /*filter=*/nullptr, &exceptions); - - settings.exceptions.clear(); - for (base::ListValue::const_iterator entry = exceptions.begin(); - entry != exceptions.end(); ++entry) { - const base::DictionaryValue* dict = nullptr; - bool valid_dict = entry->GetAsDictionary(&dict); - DCHECK(valid_dict); - - std::string origin; - std::string setting; - dict->GetString(site_settings::kOrigin, &origin); - dict->GetString(site_settings::kSetting, &setting); - - ContentSetting setting_type; - bool result = - content_settings::ContentSettingFromString(setting, &setting_type); - DCHECK(result); - - settings.exceptions.push_back(MediaException( - ContentSettingsPattern::FromString(origin), - setting_type)); - } - - PepperFlashContentSettingsUtils::SortMediaExceptions( - &settings.exceptions); - - settings.exceptions_initialized = true; - UpdateFlashMediaLinksVisibility(type); -} - -void ContentSettingsHandler::UpdateMIDISysExExceptionsView() { - UpdateSettingDefaultFromModel(CONTENT_SETTINGS_TYPE_MIDI_SYSEX); - UpdateExceptionsViewFromHostContentSettingsMap( - CONTENT_SETTINGS_TYPE_MIDI_SYSEX); -} - -void ContentSettingsHandler::UpdateAllChooserExceptionsViewsFromModel() { - for (const site_settings::ChooserTypeNameEntry& chooser_type : - site_settings::kChooserTypeGroupNames) - UpdateChooserExceptionsViewFromModel(chooser_type); -} - -void ContentSettingsHandler::UpdateAllOTRChooserExceptionsViewsFromModel() { - for (const site_settings::ChooserTypeNameEntry& chooser_type : - site_settings::kChooserTypeGroupNames) - UpdateOTRChooserExceptionsViewFromModel(chooser_type); -} - -void ContentSettingsHandler::UpdateChooserExceptionsViewFromModel( - const site_settings::ChooserTypeNameEntry& chooser_type) { - base::ListValue exceptions; - site_settings::GetChooserExceptionsFromProfile( - Profile::FromWebUI(web_ui()), false, chooser_type, &exceptions); - base::Value type_string(chooser_type.name); - web_ui()->CallJavascriptFunctionUnsafe("ContentSettings.setExceptions", - type_string, exceptions); - - UpdateOTRChooserExceptionsViewFromModel(chooser_type); -} - -void ContentSettingsHandler::UpdateOTRChooserExceptionsViewFromModel( - const site_settings::ChooserTypeNameEntry& chooser_type) { - if (!Profile::FromWebUI(web_ui())->HasOffTheRecordProfile()) - return; - - base::ListValue exceptions; - site_settings::GetChooserExceptionsFromProfile( - Profile::FromWebUI(web_ui()), true, chooser_type, &exceptions); - base::Value type_string(chooser_type.name); - web_ui()->CallJavascriptFunctionUnsafe("ContentSettings.setOTRExceptions", - type_string, exceptions); -} - -void ContentSettingsHandler::UpdateZoomLevelsExceptionsView() { - base::ListValue zoom_levels_exceptions; - - content::HostZoomMap* host_zoom_map = - content::HostZoomMap::GetDefaultForBrowserContext( - GetBrowserContext(web_ui())); - content::HostZoomMap::ZoomLevelVector zoom_levels( - host_zoom_map->GetAllZoomLevels()); - - // Sort ZoomLevelChanges by host and scheme - // (a.com < http://a.com < https://a.com < b.com). - std::sort(zoom_levels.begin(), zoom_levels.end(), - [](const content::HostZoomMap::ZoomLevelChange& a, - const content::HostZoomMap::ZoomLevelChange& b) { - return a.host == b.host ? a.scheme < b.scheme : a.host < b.host; - }); - - for (content::HostZoomMap::ZoomLevelVector::const_iterator i = - zoom_levels.begin(); - i != zoom_levels.end(); - ++i) { - std::unique_ptr<base::DictionaryValue> exception(new base::DictionaryValue); - switch (i->mode) { - case content::HostZoomMap::ZOOM_CHANGED_FOR_HOST: { - exception->SetString(site_settings::kOrigin, i->host); - std::string host = i->host; - if (host == content::kUnreachableWebDataURL) { - host = - l10n_util::GetStringUTF8(IDS_ZOOMLEVELS_CHROME_ERROR_PAGES_LABEL); - } - exception->SetString(site_settings::kOrigin, host); - break; - } - case content::HostZoomMap::ZOOM_CHANGED_FOR_SCHEME_AND_HOST: - // These are not stored in preferences and get cleared on next browser - // start. Therefore, we don't care for them. - continue; - case content::HostZoomMap::PAGE_SCALE_IS_ONE_CHANGED: - continue; - case content::HostZoomMap::ZOOM_CHANGED_TEMPORARY_ZOOM: - NOTREACHED(); - } - - std::string setting_string = - content_settings::ContentSettingToString(CONTENT_SETTING_DEFAULT); - DCHECK(!setting_string.empty()); - - exception->SetString(site_settings::kSetting, setting_string); - - // Calculate the zoom percent from the factor. Round up to the nearest whole - // number. - int zoom_percent = static_cast<int>( - content::ZoomLevelToZoomFactor(i->zoom_level) * 100 + 0.5); - exception->SetString(kZoom, base::FormatPercent(zoom_percent)); - exception->SetString(site_settings::kSource, - site_settings::SiteSettingSourceToString( - site_settings::SiteSettingSource::kPreference)); - // Append the new entry to the list and map. - zoom_levels_exceptions.Append(std::move(exception)); - } - - base::Value type_string(kZoomContentType); - web_ui()->CallJavascriptFunctionUnsafe("ContentSettings.setExceptions", - type_string, zoom_levels_exceptions); -} - -void ContentSettingsHandler::UpdateExceptionsViewFromHostContentSettingsMap( - ContentSettingsType type) { - base::ListValue exceptions; - HostContentSettingsMap* settings_map = - HostContentSettingsMapFactory::GetForProfile(GetProfile()); - const auto* extension_registry = - extensions::ExtensionRegistry::Get(GetProfile()); - site_settings::GetExceptionsFromHostContentSettingsMap( - settings_map, type, extension_registry, web_ui(), /*incognito=*/false, - /*filter=*/nullptr, &exceptions); - base::Value type_string(site_settings::ContentSettingsTypeToGroupName(type)); - web_ui()->CallJavascriptFunctionUnsafe("ContentSettings.setExceptions", - type_string, exceptions); - - UpdateExceptionsViewFromOTRHostContentSettingsMap(type); - -#if defined(OS_CHROMEOS) - // Also the default for protected contents is managed in another place. - if (type == CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER) - return; -#endif - - // The default may also have changed (we won't get a separate notification). - // If it hasn't changed, this call will be harmless. - UpdateSettingDefaultFromModel(type); -} - -void ContentSettingsHandler::UpdateExceptionsViewFromOTRHostContentSettingsMap( - ContentSettingsType type) { - const HostContentSettingsMap* otr_settings_map = - HostContentSettingsMapFactory::GetForProfile(GetOTRProfile()); - if (!otr_settings_map) - return; - const auto* extension_registry = - extensions::ExtensionRegistry::Get(GetOTRProfile()); - base::ListValue exceptions; - site_settings::GetExceptionsFromHostContentSettingsMap( - otr_settings_map, type, extension_registry, web_ui(), /*incognito=*/true, - /*filter=*/nullptr, &exceptions); - base::Value type_string(site_settings::ContentSettingsTypeToGroupName(type)); - web_ui()->CallJavascriptFunctionUnsafe("ContentSettings.setOTRExceptions", - type_string, exceptions); -} - -void ContentSettingsHandler::RemoveExceptionFromHostContentSettingsMap( - const base::ListValue* args, - ContentSettingsType type) { - std::string mode; - bool rv = args->GetString(1, &mode); - DCHECK(rv); - - std::string pattern; - rv = args->GetString(2, &pattern); - DCHECK(rv); - - // The fourth argument to this handler is optional. - std::string secondary_pattern_string; - if (args->GetSize() >= 4U) { - rv = args->GetString(3, &secondary_pattern_string); - DCHECK(rv); - } - - Profile* profile = mode == "normal" ? GetProfile() : GetOTRProfile(); - if (!profile) - return; - - HostContentSettingsMap* settings_map = - HostContentSettingsMapFactory::GetForProfile(profile); - ContentSettingsPattern primary_pattern = - ContentSettingsPattern::FromString(pattern); - ContentSettingsPattern secondary_pattern = - secondary_pattern_string.empty() - ? ContentSettingsPattern::Wildcard() - : ContentSettingsPattern::FromString(secondary_pattern_string); - PermissionUtil::ScopedRevocationReporter scoped_revocation_reporter( - profile, primary_pattern, secondary_pattern, type, - PermissionSourceUI::SITE_SETTINGS); - - settings_map->SetContentSettingCustomScope( - primary_pattern, secondary_pattern, type, std::string(), - CONTENT_SETTING_DEFAULT); -} - -void ContentSettingsHandler::RemoveZoomLevelException( - const base::ListValue* args) { - std::string mode; - bool rv = args->GetString(1, &mode); - DCHECK(rv); - - std::string pattern; - rv = args->GetString(2, &pattern); - DCHECK(rv); - - if (pattern == - l10n_util::GetStringUTF8(IDS_ZOOMLEVELS_CHROME_ERROR_PAGES_LABEL)) { - pattern = content::kUnreachableWebDataURL; - } - - content::HostZoomMap* host_zoom_map; - host_zoom_map = - content::HostZoomMap::GetDefaultForBrowserContext( - GetBrowserContext(web_ui())); - double default_level = host_zoom_map->GetDefaultZoomLevel(); - host_zoom_map->SetZoomLevelForHost(pattern, default_level); -} - -void ContentSettingsHandler::RemoveChooserException( - const site_settings::ChooserTypeNameEntry* chooser_type, - const base::ListValue* args) { - std::string mode; - bool rv = args->GetString(1, &mode); - DCHECK(rv); - - std::string requesting_origin_string; - rv = args->GetString(2, &requesting_origin_string); - DCHECK(rv); - GURL requesting_origin(requesting_origin_string); - DCHECK(requesting_origin.is_valid()); - - std::string embedding_origin_string; - rv = args->GetString(3, &embedding_origin_string); - DCHECK(rv); - GURL embedding_origin(embedding_origin_string); - DCHECK(embedding_origin.is_valid()); - - const base::DictionaryValue* object = nullptr; - rv = args->GetDictionary(4, &object); - DCHECK(rv); - - Profile* profile = Profile::FromWebUI(web_ui()); - if (mode != "normal") - profile = profile->GetOffTheRecordProfile(); - - ChooserContextBase* chooser_context = chooser_type->get_context(profile); - chooser_context->RevokeObjectPermission(requesting_origin, embedding_origin, - *object); - UpdateChooserExceptionsViewFromModel(*chooser_type); - // TODO(reillyg): Create metrics for revocations. crbug.com/556845 -} - -void ContentSettingsHandler::RegisterMessages() { - web_ui()->RegisterMessageCallback("setContentFilter", - base::Bind(&ContentSettingsHandler::SetContentFilter, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("removeException", - base::Bind(&ContentSettingsHandler::RemoveException, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("setException", - base::Bind(&ContentSettingsHandler::SetException, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("checkExceptionPatternValidity", - base::Bind(&ContentSettingsHandler::CheckExceptionPatternValidity, - base::Unretained(this))); -} - -void ContentSettingsHandler::SetContentFilter(const base::ListValue* args) { - DCHECK_EQ(2U, args->GetSize()); - std::string group, setting; - if (!(args->GetString(0, &group) && - args->GetString(1, &setting))) { - NOTREACHED(); - return; - } - - ContentSetting default_setting; - bool result = - content_settings::ContentSettingFromString(setting, &default_setting); - DCHECK(result); - - ContentSettingsType content_type = - site_settings::ContentSettingsTypeFromGroupName(group); - Profile* profile = Profile::FromWebUI(web_ui()); - -#if defined(OS_CHROMEOS) - // ChromeOS special case : in Guest mode settings are opened in Incognito - // mode, so we need original profile to actually modify settings. - if (user_manager::UserManager::Get()->IsLoggedInAsGuest()) - profile = profile->GetOriginalProfile(); -#endif - - HostContentSettingsMap* map = - HostContentSettingsMapFactory::GetForProfile(profile); - map->SetDefaultContentSetting(content_type, default_setting); - - const ExceptionsInfoMap& exceptions_info_map = GetExceptionsInfoMap(); - const auto& it = exceptions_info_map.find(content_type); - if (it != exceptions_info_map.end()) - base::RecordAction(it->second.uma); -} - -void ContentSettingsHandler::RemoveException(const base::ListValue* args) { - std::string type_string; - CHECK(args->GetString(0, &type_string)); - - // Zoom levels are no actual content type so we need to handle them - // separately. They would not be recognized by - // ContentSettingsTypeFromGroupName. - if (type_string == kZoomContentType) { - RemoveZoomLevelException(args); - return; - } - - const site_settings::ChooserTypeNameEntry* chooser_type = - site_settings::ChooserTypeFromGroupName(type_string); - if (chooser_type) { - RemoveChooserException(chooser_type, args); - return; - } - - ContentSettingsType type = - site_settings::ContentSettingsTypeFromGroupName(type_string); - RemoveExceptionFromHostContentSettingsMap(args, type); - - WebSiteSettingsUmaUtil::LogPermissionChange( - type, ContentSetting::CONTENT_SETTING_DEFAULT); -} - -void ContentSettingsHandler::SetException(const base::ListValue* args) { - std::string type_string; - CHECK(args->GetString(0, &type_string)); - std::string mode; - CHECK(args->GetString(1, &mode)); - std::string pattern; - CHECK(args->GetString(2, &pattern)); - std::string setting; - CHECK(args->GetString(3, &setting)); - - ContentSettingsType type = - site_settings::ContentSettingsTypeFromGroupName(type_string); - - DCHECK(type != CONTENT_SETTINGS_TYPE_GEOLOCATION && - type != CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC && - type != CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA); - - Profile* profile = mode == "normal" ? GetProfile() : GetOTRProfile(); - - // The profile could be nullptr if the mode was OTR but the OTR profile - // got destroyed before we received this message. - if (!profile) - return; - - ContentSetting setting_type; - bool result = - content_settings::ContentSettingFromString(setting, &setting_type); - DCHECK(result); - - HostContentSettingsMap* settings_map = - HostContentSettingsMapFactory::GetForProfile(profile); - - PermissionUtil::ScopedRevocationReporter scoped_revocation_reporter( - profile, ContentSettingsPattern::FromString(pattern), - ContentSettingsPattern::Wildcard(), type, - PermissionSourceUI::SITE_SETTINGS); - - settings_map->SetContentSettingCustomScope( - ContentSettingsPattern::FromString(pattern), - ContentSettingsPattern::Wildcard(), type, std::string(), setting_type); - WebSiteSettingsUmaUtil::LogPermissionChange(type, setting_type); -} - -void ContentSettingsHandler::CheckExceptionPatternValidity( - const base::ListValue* args) { - std::string type_string; - CHECK(args->GetString(0, &type_string)); - std::string mode_string; - CHECK(args->GetString(1, &mode_string)); - std::string pattern_string; - CHECK(args->GetString(2, &pattern_string)); - - ContentSettingsPattern pattern = - ContentSettingsPattern::FromString(pattern_string); - - web_ui()->CallJavascriptFunctionUnsafe( - "ContentSettings.patternValidityCheckComplete", base::Value(type_string), - base::Value(mode_string), base::Value(pattern_string), - base::Value(pattern.IsValid())); -} - -Profile* ContentSettingsHandler::GetProfile() { - return Profile::FromWebUI(web_ui()); -} - -ProtocolHandlerRegistry* ContentSettingsHandler::GetProtocolHandlerRegistry() { - return ProtocolHandlerRegistryFactory::GetForBrowserContext( - GetBrowserContext(web_ui())); -} - -Profile* ContentSettingsHandler::GetOTRProfile() { - return GetProfile()->HasOffTheRecordProfile() - ? GetProfile()->GetOffTheRecordProfile() - : nullptr; -} - -void ContentSettingsHandler::RefreshFlashMediaSettings() { - MediaSettingsInfo::ForFlash& settings = media_settings_->forFlash(); - settings.initialized = false; - - settings.last_refresh_request_id = - flash_settings_manager_->GetPermissionSettings( - PP_FLASH_BROWSEROPERATIONS_SETTINGTYPE_CAMERAMIC); -} - -void ContentSettingsHandler::OnPepperFlashPrefChanged() { - ShowFlashMediaLink( - DEFAULT_SETTING, CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC, false); - ShowFlashMediaLink( - DEFAULT_SETTING, CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, false); - ShowFlashMediaLink( - EXCEPTIONS, CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC, false); - ShowFlashMediaLink( - EXCEPTIONS, CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, false); - - PrefService* prefs = user_prefs::UserPrefs::Get(GetBrowserContext(web_ui())); - if (prefs->GetBoolean(prefs::kPepperFlashSettingsEnabled)) - RefreshFlashMediaSettings(); - else - media_settings_->forFlash().initialized = false; -} - -void ContentSettingsHandler::OnZoomLevelChanged( - const content::HostZoomMap::ZoomLevelChange& change) { - UpdateZoomLevelsExceptionsView(); -} - -void ContentSettingsHandler::ShowFlashMediaLink( - LinkType link_type, ContentSettingsType content_type, bool show) { - MediaSettingsInfo::ForOneType& settings = - media_settings_->forType(content_type); - - bool& show_link = link_type == DEFAULT_SETTING ? - settings.show_flash_default_link : - settings.show_flash_exceptions_link; - - if (show_link != show) { - web_ui()->CallJavascriptFunctionUnsafe( - "ContentSettings.showMediaPepperFlashLink", - base::Value(link_type == DEFAULT_SETTING ? "default" : "exceptions"), - base::Value(content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC - ? "mic" - : "camera"), - base::Value(show)); - show_link = show; - } -} - -void ContentSettingsHandler::UpdateFlashMediaLinksVisibility( - ContentSettingsType type) { - MediaSettingsInfo::ForOneType& settings = media_settings_->forType(type); - MediaSettingsInfo::ForFlash& flash_settings = media_settings_->forFlash(); - - if (!flash_settings.initialized) - return; - - // We handle four cases - default settings and exceptions for microphone - // and camera. We use the following criteria to determine whether to show - // the links. - // - // 1. Flash won't send us notifications when its settings get changed, which - // means the Flash settings in |media_settings_| may be out-dated, especially - // after we show links to change Flash settings. - // In order to avoid confusion, we won't hide the links once they are showed. - // One exception is that we will hide them when Pepper Flash is disabled - // (handled in OnPepperFlashPrefChanged()). - // - // 2. If audio or video capture are disabled by policy, the respective link - // shouldn't be showed. Flash conforms to the policy in this case because - // it cannot open those devices. - // - // 3. Otherwise, we show the link if the corresponding setting is different - // in HostContentSettingsMap than it is in Flash. - if (settings.policy_disable) - return; - - if (settings.default_setting_initialized && - !settings.show_flash_default_link && - (flash_settings.default_setting != - settings.default_setting)) { - ShowFlashMediaLink(DEFAULT_SETTING, type, true); - } - - if (settings.exceptions_initialized && - !settings.show_flash_exceptions_link && - !PepperFlashContentSettingsUtils::AreMediaExceptionsEqual( - settings.default_setting, - settings.exceptions, - flash_settings.default_setting, - flash_settings.exceptions)) { - ShowFlashMediaLink(EXCEPTIONS, type, true); - } -} - -void ContentSettingsHandler::UpdateMediaDeviceDropdownVisibility( - ContentSettingsType type) { - MediaSettingsInfo::ForOneType& settings = media_settings_->forType(type); - - web_ui()->CallJavascriptFunctionUnsafe( - "ContentSettings.setDevicesMenuVisibility", - base::Value(site_settings::ContentSettingsTypeToGroupName(type)), - base::Value(!settings.policy_disable)); -} - -void ContentSettingsHandler::UpdateProtectedContentExceptionsButton() { -#if defined(OS_CHROMEOS) - // Guests cannot modify exceptions. UIAccountTweaks will disabled the button. - if (user_manager::UserManager::Get()->IsLoggedInAsGuest()) - return; -#endif - - // Exceptions apply only when the feature is enabled. - PrefService* prefs = user_prefs::UserPrefs::Get(GetBrowserContext(web_ui())); - bool enable_exceptions = prefs->GetBoolean(prefs::kEnableDRM); - web_ui()->CallJavascriptFunctionUnsafe( - "ContentSettings.enableProtectedContentExceptions", - base::Value(enable_exceptions)); -} - -} // namespace options
diff --git a/chrome/browser/ui/webui/options/content_settings_handler.h b/chrome/browser/ui/webui/options/content_settings_handler.h deleted file mode 100644 index 768ff702..0000000 --- a/chrome/browser/ui/webui/options/content_settings_handler.h +++ /dev/null
@@ -1,285 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_WEBUI_OPTIONS_CONTENT_SETTINGS_HANDLER_H_ -#define CHROME_BROWSER_UI_WEBUI_OPTIONS_CONTENT_SETTINGS_HANDLER_H_ - -#include <stdint.h> - -#include <memory> -#include <string> - -#include "base/macros.h" -#include "base/scoped_observer.h" -#include "base/values.h" -#include "chrome/browser/pepper_flash_settings_manager.h" -#include "chrome/browser/ui/webui/options/options_ui.h" -#include "chrome/browser/ui/webui/options/pepper_flash_content_settings_utils.h" -#include "components/content_settings/core/browser/content_settings_observer.h" -#include "components/content_settings/core/common/content_settings.h" -#include "components/content_settings/core/common/content_settings_types.h" -#include "components/prefs/pref_change_registrar.h" -#include "content/public/browser/host_zoom_map.h" -#include "content/public/browser/notification_observer.h" -#include "content/public/browser/notification_registrar.h" - -class HostContentSettingsMap; -class Profile; -class ProtocolHandlerRegistry; - -namespace site_settings { -struct ChooserTypeNameEntry; -} - -namespace options { - -class ContentSettingsHandler : public OptionsPageUIHandler, - public content_settings::Observer, - public content::NotificationObserver, - public PepperFlashSettingsManager::Client { - public: - ContentSettingsHandler(); - ~ContentSettingsHandler() override; - - // OptionsPageUIHandler implementation. - void GetLocalizedValues(base::DictionaryValue* localized_strings) override; - void InitializeHandler() override; - void InitializePage() override; - void RegisterMessages() override; - - // content_settings::Observer implementation. - void OnContentSettingChanged(const ContentSettingsPattern& primary_pattern, - const ContentSettingsPattern& secondary_pattern, - ContentSettingsType content_type, - std::string resource_identifier) override; - - // content::NotificationObserver implementation. - void Observe(int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) override; - - // PepperFlashSettingsManager::Client implementation. - void OnGetPermissionSettingsCompleted( - uint32_t request_id, - bool success, - PP_Flash_BrowserOperations_Permission default_permission, - const ppapi::FlashSiteSettings& sites) override; - - private: - // Used to determine whether we should show links to Flash camera and - // microphone settings. - class MediaSettingsInfo { - public: - MediaSettingsInfo(); - ~MediaSettingsInfo(); - - // Cached Pepper Flash settings. - struct ForFlash { - ForFlash(); - ~ForFlash(); - - ContentSetting default_setting; - MediaExceptions exceptions; - bool initialized; - uint32_t last_refresh_request_id; - }; - - struct ForOneType { - ForOneType(); - ~ForOneType(); - - // Whether the links to Flash settings pages are showed. - bool show_flash_default_link; - bool show_flash_exceptions_link; - - // Cached Chrome media settings. - ContentSetting default_setting; - bool policy_disable; - bool default_setting_initialized; - MediaExceptions exceptions; - bool exceptions_initialized; - }; - - ForOneType& forType(ContentSettingsType type); - ForFlash& forFlash(); - - private: - ForOneType mic_settings_; - ForOneType camera_settings_; - ForFlash flash_settings_; - - DISALLOW_COPY_AND_ASSIGN(MediaSettingsInfo); - }; - - // Used by ShowFlashMediaLink() to specify which link to show/hide. - enum LinkType { - DEFAULT_SETTING = 0, - EXCEPTIONS, - }; - - // Functions that call into the page ----------------------------------------- - - // Updates the page with the default settings (allow, ask, block, etc.) - void UpdateSettingDefaultFromModel(ContentSettingsType type); - - // Compares the microphone or camera |type| default settings with Flash - // and updates the Flash links' visibility accordingly. - void UpdateMediaSettingsFromPrefs(ContentSettingsType type); - - // Clobbers and rebuilds the specific content setting type exceptions table. - void UpdateExceptionsViewFromModel(ContentSettingsType type); - - // Clobbers and rebuilds the specific content setting type exceptions - // OTR table. - void UpdateOTRExceptionsViewFromModel(ContentSettingsType type); - - // Clobbers and rebuilds all the exceptions tables in the page (both normal - // and OTR tables). - void UpdateAllExceptionsViewsFromModel(); - - // As above, but only OTR tables. - void UpdateAllOTRExceptionsViewsFromModel(); - - // Clobbers and rebuilds just the geolocation exception table. - void UpdateGeolocationExceptionsView(); - - // Clobbers and rebuilds just the desktop notification exception table. - void UpdateNotificationExceptionsView(); - - // Compares the exceptions of the camera or microphone |type| with its Flash - // counterparts and updates the Flash links' visibility accordingly. - void CompareMediaExceptionsWithFlash(ContentSettingsType type); - - // Clobbers and rebuilds just the MIDI SysEx exception table. - void UpdateMIDISysExExceptionsView(); - - // Clobbers and rebuilds all chooser-based exception tables. - void UpdateAllChooserExceptionsViewsFromModel(); - - // As above, but only OTR tables. - void UpdateAllOTRChooserExceptionsViewsFromModel(); - - // Clobbers and rebuilds the exception table for a particular chooser-based - // permission. - void UpdateChooserExceptionsViewFromModel( - const site_settings::ChooserTypeNameEntry& chooser_type); - - // As above, but only OTR tables. - void UpdateOTRChooserExceptionsViewFromModel( - const site_settings::ChooserTypeNameEntry& chooser_type); - - // Modifies the zoom level exceptions list to display correct chrome - // signin page entry. When the legacy (non-WebView-based) signin page - // goes away, this function can be removed. - void AdjustZoomLevelsListForSigninPageIfNecessary( - content::HostZoomMap::ZoomLevelVector* zoom_levels); - - // Clobbers and rebuilds just the zoom levels exception table. - void UpdateZoomLevelsExceptionsView(); - - // Clobbers and rebuilds an exception table that's managed by the host content - // settings map. - void UpdateExceptionsViewFromHostContentSettingsMap(ContentSettingsType type); - - // As above, but acts on the OTR table for the content setting type. - void UpdateExceptionsViewFromOTRHostContentSettingsMap( - ContentSettingsType type); - - // Updates the radio buttons for enabling / disabling handlers. - void UpdateHandlersEnabledRadios(); - - // Removes one geolocation exception. |args| contains the parameters passed to - // RemoveException(). - void RemoveGeolocationException(const base::ListValue* args); - - // Removes one notification exception. |args| contains the parameters passed - // to RemoveException(). - void RemoveNotificationException(const base::ListValue* args); - - // Removes one exception of |type| from the host content settings map. |args| - // contains the parameters passed to RemoveException(). - void RemoveExceptionFromHostContentSettingsMap( - const base::ListValue* args, - ContentSettingsType type); - - // Removes one zoom level exception. |args| contains the parameters passed to - // RemoveException(). - void RemoveZoomLevelException(const base::ListValue* args); - - // Removes one exception for a chooser-based permission. |args| contains the - // parameters passed to RemoveException(). - void RemoveChooserException( - const site_settings::ChooserTypeNameEntry* chooser_type, - const base::ListValue* args); - - // Callbacks used by the page ------------------------------------------------ - - // Sets the default value for a specific content type. |args| includes the - // content type and a string describing the new default the user has - // chosen. - void SetContentFilter(const base::ListValue* args); - - // Removes the given row from the table. The first entry in |args| is the - // content type, and the rest of the arguments depend on the content type - // to be removed. - void RemoveException(const base::ListValue* args); - - // Changes the value of an exception. Called after the user is done editing an - // exception. - void SetException(const base::ListValue* args); - - // Called to decide whether a given pattern is valid, or if it should be - // rejected. Called while the user is editing an exception pattern. - void CheckExceptionPatternValidity(const base::ListValue* args); - - // Utility functions --------------------------------------------------------- - - // Applies content settings whitelists to reduce breakage / user confusion. - void ApplyWhitelist(ContentSettingsType content_type, - ContentSetting default_setting); - - // Gets the normal profile. - Profile* GetProfile(); - - // Gets the incognito profile, or nullptr if there is no active incognito - // session. - Profile* GetOTRProfile(); - - // Gets the ProtocolHandlerRegistry for the normal profile. - ProtocolHandlerRegistry* GetProtocolHandlerRegistry(); - - void RefreshFlashMediaSettings(); - - void OnPepperFlashPrefChanged(); - - // content::HostZoomMap subscription. - void OnZoomLevelChanged(const content::HostZoomMap::ZoomLevelChange& change); - - void ShowFlashMediaLink( - LinkType link_type, ContentSettingsType content_type, bool show); - - void UpdateFlashMediaLinksVisibility(ContentSettingsType type); - - void UpdateMediaDeviceDropdownVisibility(ContentSettingsType type); - - void UpdateProtectedContentExceptionsButton(); - - // Member variables --------------------------------------------------------- - - content::NotificationRegistrar notification_registrar_; - PrefChangeRegistrar pref_change_registrar_; - std::unique_ptr<PepperFlashSettingsManager> flash_settings_manager_; - std::unique_ptr<MediaSettingsInfo> media_settings_; - std::unique_ptr<content::HostZoomMap::Subscription> - host_zoom_map_subscription_; - std::unique_ptr<content::HostZoomMap::Subscription> - signin_host_zoom_map_subscription_; - ScopedObserver<HostContentSettingsMap, content_settings::Observer> observer_; - - DISALLOW_COPY_AND_ASSIGN(ContentSettingsHandler); -}; - -} // namespace options - -#endif // CHROME_BROWSER_UI_WEBUI_OPTIONS_CONTENT_SETTINGS_HANDLER_H_
diff --git a/chrome/browser/ui/webui/options/cookies_view_handler.cc b/chrome/browser/ui/webui/options/cookies_view_handler.cc deleted file mode 100644 index 7b1a4bb..0000000 --- a/chrome/browser/ui/webui/options/cookies_view_handler.cc +++ /dev/null
@@ -1,297 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/webui/options/cookies_view_handler.h" - -#include <string> -#include <utility> - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/macros.h" -#include "base/memory/ptr_util.h" -#include "base/strings/utf_string_conversions.h" -#include "base/values.h" -#include "chrome/browser/browsing_data/browsing_data_appcache_helper.h" -#include "chrome/browser/browsing_data/browsing_data_cache_storage_helper.h" -#include "chrome/browser/browsing_data/browsing_data_channel_id_helper.h" -#include "chrome/browser/browsing_data/browsing_data_cookie_helper.h" -#include "chrome/browser/browsing_data/browsing_data_database_helper.h" -#include "chrome/browser/browsing_data/browsing_data_file_system_helper.h" -#include "chrome/browser/browsing_data/browsing_data_flash_lso_helper.h" -#include "chrome/browser/browsing_data/browsing_data_indexed_db_helper.h" -#include "chrome/browser/browsing_data/browsing_data_local_storage_helper.h" -#include "chrome/browser/browsing_data/browsing_data_media_license_helper.h" -#include "chrome/browser/browsing_data/browsing_data_quota_helper.h" -#include "chrome/browser/browsing_data/browsing_data_service_worker_helper.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/webui/cookies_tree_model_util.h" -#include "chrome/grit/generated_resources.h" -#include "content/public/browser/browser_context.h" -#include "content/public/browser/render_process_host.h" -#include "content/public/browser/site_instance.h" -#include "content/public/browser/storage_partition.h" -#include "content/public/browser/web_ui.h" - -namespace storage { -class FileSystemContext; -} - -namespace options { - -CookiesViewHandler::CookiesViewHandler() - : batch_update_(false), - model_util_(new CookiesTreeModelUtil) { -} - -CookiesViewHandler::~CookiesViewHandler() { -} - -void CookiesViewHandler::GetLocalizedValues( - base::DictionaryValue* localized_strings) { - DCHECK(localized_strings); - - static OptionsStringResource resources[] = { - {"label_cookie_name", IDS_COOKIES_COOKIE_NAME_LABEL}, - {"label_cookie_content", IDS_COOKIES_COOKIE_CONTENT_LABEL}, - {"label_cookie_domain", IDS_COOKIES_COOKIE_DOMAIN_LABEL}, - {"label_cookie_path", IDS_COOKIES_COOKIE_PATH_LABEL}, - {"label_cookie_send_for", IDS_COOKIES_COOKIE_SENDFOR_LABEL}, - {"label_cookie_accessible_to_script", - IDS_COOKIES_COOKIE_ACCESSIBLE_TO_SCRIPT_LABEL}, - {"label_cookie_created", IDS_COOKIES_COOKIE_CREATED_LABEL}, - {"label_cookie_expires", IDS_COOKIES_COOKIE_EXPIRES_LABEL}, - {"label_webdb_desc", IDS_COOKIES_WEB_DATABASE_DESCRIPTION_LABEL}, - {"label_local_storage_size", - IDS_COOKIES_LOCAL_STORAGE_SIZE_ON_DISK_LABEL}, - {"label_local_storage_last_modified", - IDS_COOKIES_LOCAL_STORAGE_LAST_MODIFIED_LABEL}, - {"label_local_storage_origin", IDS_COOKIES_LOCAL_STORAGE_ORIGIN_LABEL}, - {"label_indexed_db_size", IDS_COOKIES_LOCAL_STORAGE_SIZE_ON_DISK_LABEL}, - {"label_indexed_db_last_modified", - IDS_COOKIES_LOCAL_STORAGE_LAST_MODIFIED_LABEL}, - {"label_indexed_db_origin", IDS_COOKIES_LOCAL_STORAGE_ORIGIN_LABEL}, - {"label_service_worker_origin", IDS_COOKIES_LOCAL_STORAGE_ORIGIN_LABEL}, - {"label_service_worker_size", - IDS_COOKIES_LOCAL_STORAGE_SIZE_ON_DISK_LABEL}, - {"label_service_worker_scopes", IDS_COOKIES_SERVICE_WORKER_SCOPES_LABEL}, - {"label_cache_storage_origin", IDS_COOKIES_LOCAL_STORAGE_ORIGIN_LABEL}, - {"label_cache_storage_size", - IDS_COOKIES_LOCAL_STORAGE_SIZE_ON_DISK_LABEL}, - {"label_cache_storage_last_modified", - IDS_COOKIES_LOCAL_STORAGE_LAST_MODIFIED_LABEL}, - {"label_app_cache_manifest", - IDS_COOKIES_APPLICATION_CACHE_MANIFEST_LABEL}, - {"label_cookie_last_accessed", IDS_COOKIES_LAST_ACCESSED_LABEL}, - {"cookie_domain", IDS_COOKIES_DOMAIN_COLUMN_HEADER}, - {"cookie_local_data", IDS_COOKIES_DATA_COLUMN_HEADER}, - {"cookie_singular", IDS_COOKIES_SINGLE_COOKIE}, - {"cookie_plural", IDS_COOKIES_PLURAL_COOKIES}, - {"cookie_database_storage", IDS_COOKIES_DATABASE_STORAGE}, - {"cookie_indexed_db", IDS_COOKIES_INDEXED_DB}, - {"cookie_local_storage", IDS_COOKIES_LOCAL_STORAGE}, - {"cookie_app_cache", IDS_COOKIES_APPLICATION_CACHE}, - {"cookie_service_worker", IDS_COOKIES_SERVICE_WORKER}, - {"cookie_cache_storage", IDS_COOKIES_CACHE_STORAGE}, - {"cookie_flash_lso", IDS_COOKIES_FLASH_LSO}, - {"search_cookies", IDS_COOKIES_SEARCH_COOKIES}, - {"remove_cookie", IDS_COOKIES_REMOVE_LABEL}, - {"remove_all_cookie", IDS_COOKIES_REMOVE_ALL_LABEL}, - {"remove_all_shown_cookie", IDS_COOKIES_REMOVE_ALL_SHOWN_LABEL}, - {"cookie_file_system", IDS_COOKIES_FILE_SYSTEM}, - {"label_file_system_origin", IDS_COOKIES_LOCAL_STORAGE_ORIGIN_LABEL}, - {"label_file_system_temporary_usage", - IDS_COOKIES_FILE_SYSTEM_TEMPORARY_USAGE_LABEL}, - {"label_file_system_persistent_usage", - IDS_COOKIES_FILE_SYSTEM_PERSISTENT_USAGE_LABEL}, - {"cookie_channel_id", IDS_COOKIES_CHANNEL_ID}, - {"label_channel_id_server_id", IDS_COOKIES_CHANNEL_ID_ORIGIN_LABEL}, - {"label_channel_id_type", IDS_COOKIES_CHANNEL_ID_TYPE_LABEL}, - {"label_channel_id_created", IDS_COOKIES_CHANNEL_ID_CREATED_LABEL}, - {"label_channel_id_expires", IDS_COOKIES_CHANNEL_ID_EXPIRES_LABEL}, - {"label_protected_by_apps", - IDS_GEOLOCATION_SET_BY_HOVER}, // TODO(bauerb): Use a better string - {"cookie_media_license", IDS_COOKIES_MEDIA_LICENSE}, - {"label_media_license_origin", IDS_COOKIES_LOCAL_STORAGE_ORIGIN_LABEL}, - {"label_media_license_size", - IDS_COOKIES_LOCAL_STORAGE_SIZE_ON_DISK_LABEL}, - {"label_media_license_last_modified", - IDS_COOKIES_LOCAL_STORAGE_LAST_MODIFIED_LABEL}, - }; - - RegisterStrings(localized_strings, resources, arraysize(resources)); - RegisterTitle(localized_strings, "cookiesViewPage", - IDS_COOKIES_WEBSITE_PERMISSIONS_WINDOW_TITLE); -} - -void CookiesViewHandler::RegisterMessages() { - web_ui()->RegisterMessageCallback("updateCookieSearchResults", - base::Bind(&CookiesViewHandler::UpdateSearchResults, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("removeAllCookies", - base::Bind(&CookiesViewHandler::RemoveAll, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("removeCookie", - base::Bind(&CookiesViewHandler::Remove, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("loadCookie", - base::Bind(&CookiesViewHandler::LoadChildren, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("reloadCookies", - base::Bind(&CookiesViewHandler::ReloadCookies, - base::Unretained(this))); -} - -void CookiesViewHandler::TreeNodesAdded(ui::TreeModel* model, - ui::TreeModelNode* parent, - int start, - int count) { - // Skip if there is a batch update in progress. - if (batch_update_) - return; - - CookiesTreeModel* tree_model = static_cast<CookiesTreeModel*>(model); - CookieTreeNode* parent_node = tree_model->AsNode(parent); - - std::unique_ptr<base::ListValue> children(new base::ListValue); - model_util_->GetChildNodeList( - parent_node, start, count, /*include_quota_nodes=*/true, children.get()); - - base::ListValue args; - if (parent == tree_model->GetRoot()) - args.Append(base::MakeUnique<base::Value>()); - else - args.AppendString(model_util_->GetTreeNodeId(parent_node)); - args.AppendInteger(start); - args.Append(std::move(children)); - web_ui()->CallJavascriptFunctionUnsafe("CookiesView.onTreeItemAdded", args); -} - -void CookiesViewHandler::TreeNodesRemoved(ui::TreeModel* model, - ui::TreeModelNode* parent, - int start, - int count) { - // Skip if there is a batch update in progress. - if (batch_update_) - return; - - CookiesTreeModel* tree_model = static_cast<CookiesTreeModel*>(model); - - base::ListValue args; - if (parent == tree_model->GetRoot()) - args.Append(base::MakeUnique<base::Value>()); - else - args.AppendString(model_util_->GetTreeNodeId(tree_model->AsNode(parent))); - args.AppendInteger(start); - args.AppendInteger(count); - web_ui()->CallJavascriptFunctionUnsafe("CookiesView.onTreeItemRemoved", args); -} - -void CookiesViewHandler::TreeModelBeginBatch(CookiesTreeModel* model) { - DCHECK(!batch_update_); // There should be no nested batch begin. - batch_update_ = true; -} - -void CookiesViewHandler::TreeModelEndBatch(CookiesTreeModel* model) { - DCHECK(batch_update_); - batch_update_ = false; - - SendChildren(model->GetRoot()); -} - -void CookiesViewHandler::EnsureCookiesTreeModelCreated() { - if (!cookies_tree_model_.get()) { - Profile* profile = Profile::FromWebUI(web_ui()); - content::StoragePartition* storage_partition = - content::BrowserContext::GetDefaultStoragePartition(profile); - content::IndexedDBContext* indexed_db_context = - storage_partition->GetIndexedDBContext(); - content::ServiceWorkerContext* service_worker_context = - storage_partition->GetServiceWorkerContext(); - content::CacheStorageContext* cache_storage_context = - storage_partition->GetCacheStorageContext(); - storage::FileSystemContext* file_system_context = - storage_partition->GetFileSystemContext(); - LocalDataContainer* container = new LocalDataContainer( - new BrowsingDataCookieHelper(profile->GetRequestContext()), - new BrowsingDataDatabaseHelper(profile), - new BrowsingDataLocalStorageHelper(profile), NULL, - new BrowsingDataAppCacheHelper(profile), - new BrowsingDataIndexedDBHelper(indexed_db_context), - BrowsingDataFileSystemHelper::Create(file_system_context), - BrowsingDataQuotaHelper::Create(profile), - BrowsingDataChannelIDHelper::Create(profile->GetRequestContext()), - new BrowsingDataServiceWorkerHelper(service_worker_context), - new BrowsingDataCacheStorageHelper(cache_storage_context), - BrowsingDataFlashLSOHelper::Create(profile), - BrowsingDataMediaLicenseHelper::Create(file_system_context)); - cookies_tree_model_.reset(new CookiesTreeModel( - container, profile->GetExtensionSpecialStoragePolicy())); - cookies_tree_model_->AddCookiesTreeObserver(this); - } -} - -void CookiesViewHandler::UpdateSearchResults(const base::ListValue* args) { - base::string16 query; - if (!args->GetString(0, &query)) - return; - - EnsureCookiesTreeModelCreated(); - - cookies_tree_model_->UpdateSearchResults(query); -} - -void CookiesViewHandler::RemoveAll(const base::ListValue* args) { - EnsureCookiesTreeModelCreated(); - cookies_tree_model_->DeleteAllStoredObjects(); -} - -void CookiesViewHandler::Remove(const base::ListValue* args) { - std::string node_path; - if (!args->GetString(0, &node_path)) - return; - - EnsureCookiesTreeModelCreated(); - - const CookieTreeNode* node = model_util_->GetTreeNodeFromPath( - cookies_tree_model_->GetRoot(), node_path); - if (node) - cookies_tree_model_->DeleteCookieNode(const_cast<CookieTreeNode*>(node)); -} - -void CookiesViewHandler::LoadChildren(const base::ListValue* args) { - std::string node_path; - if (!args->GetString(0, &node_path)) - return; - - EnsureCookiesTreeModelCreated(); - - const CookieTreeNode* node = model_util_->GetTreeNodeFromPath( - cookies_tree_model_->GetRoot(), node_path); - if (node) - SendChildren(node); -} - -void CookiesViewHandler::SendChildren(const CookieTreeNode* parent) { - std::unique_ptr<base::ListValue> children(new base::ListValue); - model_util_->GetChildNodeList(parent, /*start=*/0, parent->child_count(), - /*include_quota_nodes=*/true, children.get()); - - base::ListValue args; - if (parent == cookies_tree_model_->GetRoot()) - args.Append(base::MakeUnique<base::Value>()); - else - args.AppendString(model_util_->GetTreeNodeId(parent)); - args.Append(std::move(children)); - - web_ui()->CallJavascriptFunctionUnsafe("CookiesView.loadChildren", args); -} - -void CookiesViewHandler::ReloadCookies(const base::ListValue* args) { - cookies_tree_model_.reset(); - - EnsureCookiesTreeModelCreated(); -} - -} // namespace options
diff --git a/chrome/browser/ui/webui/options/cookies_view_handler.h b/chrome/browser/ui/webui/options/cookies_view_handler.h deleted file mode 100644 index 4e440ae4..0000000 --- a/chrome/browser/ui/webui/options/cookies_view_handler.h +++ /dev/null
@@ -1,81 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_WEBUI_OPTIONS_COOKIES_VIEW_HANDLER_H_ -#define CHROME_BROWSER_UI_WEBUI_OPTIONS_COOKIES_VIEW_HANDLER_H_ - -#include <memory> - -#include "base/compiler_specific.h" -#include "base/macros.h" -#include "chrome/browser/browsing_data/cookies_tree_model.h" -#include "chrome/browser/ui/webui/options/options_ui.h" - -class CookiesTreeModelUtil; - -namespace options { - -class CookiesViewHandler : public OptionsPageUIHandler, - public CookiesTreeModel::Observer { - public: - CookiesViewHandler(); - ~CookiesViewHandler() override; - - // OptionsPageUIHandler implementation. - void GetLocalizedValues(base::DictionaryValue* localized_strings) override; - void RegisterMessages() override; - - // CookiesTreeModel::Observer implementation. - void TreeNodesAdded(ui::TreeModel* model, - ui::TreeModelNode* parent, - int start, - int count) override; - void TreeNodesRemoved(ui::TreeModel* model, - ui::TreeModelNode* parent, - int start, - int count) override; - void TreeNodeChanged(ui::TreeModel* model, ui::TreeModelNode* node) override { - } - void TreeModelBeginBatch(CookiesTreeModel* model) override; - void TreeModelEndBatch(CookiesTreeModel* model) override; - - private: - // Creates the CookiesTreeModel if neccessary. - void EnsureCookiesTreeModelCreated(); - - // Updates search filter for cookies tree model. - void UpdateSearchResults(const base::ListValue* args); - - // Remove all sites data. - void RemoveAll(const base::ListValue* args); - - // Remove selected sites data. - void Remove(const base::ListValue* args); - - // Get the tree node using the tree path info in |args| and call - // SendChildren to pass back children nodes data to WebUI. - void LoadChildren(const base::ListValue* args); - - // Get children nodes data and pass it to 'CookiesView.loadChildren' to - // update the WebUI. - void SendChildren(const CookieTreeNode* parent); - - // Reloads the CookiesTreeModel and passes the nodes to - // 'CookiesView.loadChildren' to update the WebUI. - void ReloadCookies(const base::ListValue* args); - - // The Cookies Tree model - std::unique_ptr<CookiesTreeModel> cookies_tree_model_; - - // Flag to indicate whether there is a batch update in progress. - bool batch_update_; - - std::unique_ptr<CookiesTreeModelUtil> model_util_; - - DISALLOW_COPY_AND_ASSIGN(CookiesViewHandler); -}; - -} // namespace options - -#endif // CHROME_BROWSER_UI_WEBUI_OPTIONS_COOKIES_VIEW_HANDLER_H_
diff --git a/chrome/browser/ui/webui/options/core_options_handler.cc b/chrome/browser/ui/webui/options/core_options_handler.cc deleted file mode 100644 index 45ca990..0000000 --- a/chrome/browser/ui/webui/options/core_options_handler.cc +++ /dev/null
@@ -1,664 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/webui/options/core_options_handler.h" - -#include <stddef.h> - -#include <memory> -#include <utility> - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/json/json_reader.h" -#include "base/memory/ptr_util.h" -#include "base/metrics/user_metrics.h" -#include "base/strings/string16.h" -#include "base/strings/string_number_conversions.h" -#include "base/strings/utf_string_conversions.h" -#include "base/values.h" -#include "build/build_config.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/chrome_notification_types.h" -#include "chrome/browser/extensions/extension_service.h" -#include "chrome/browser/extensions/extension_util.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/common/chrome_switches.h" -#include "chrome/common/pref_names.h" -#include "chrome/common/url_constants.h" -#include "chrome/grit/chromium_strings.h" -#include "chrome/grit/generated_resources.h" -#include "components/proxy_config/proxy_config_pref_names.h" -#include "components/strings/grit/components_strings.h" -#include "components/url_formatter/url_fixer.h" -#include "content/public/browser/notification_details.h" -#include "content/public/browser/notification_types.h" -#include "content/public/browser/web_ui.h" -#include "extensions/browser/extension_pref_value_map.h" -#include "extensions/browser/extension_pref_value_map_factory.h" -#include "extensions/browser/extension_registry.h" -#include "extensions/browser/extension_system.h" -#include "extensions/common/extension.h" -#include "ui/base/l10n/l10n_util.h" -#include "url/gurl.h" - -using base::UserMetricsAction; - -namespace options { - -namespace { - -// Whether "controlledBy" property of pref value sent to options web UI needs to -// be set to "extension" when the preference is controlled by an extension. -bool CanSetExtensionControlledPrefValue( - const PrefService::Preference* preference) { -#if defined(OS_WIN) - // These have more obvious UI than the standard one for extension controlled - // values (an extension puzzle piece) on the settings page. To avoiding - // showing the extension puzzle piece for these settings, their "controlledBy" - // value should never be set to "extension". - return preference->name() != prefs::kURLsToRestoreOnStartup && - preference->name() != prefs::kRestoreOnStartup && - preference->name() != prefs::kHomePage && - preference->name() != prefs::kHomePageIsNewTabPage; -#else - return true; -#endif -} - -} // namespace - -CoreOptionsHandler::CoreOptionsHandler() - : handlers_host_(NULL) { -} - -CoreOptionsHandler::~CoreOptionsHandler() {} - -void CoreOptionsHandler::InitializeHandler() { - Profile* profile = Profile::FromWebUI(web_ui()); - - plugin_status_pref_setter_.Init( - profile, - base::Bind(&CoreOptionsHandler::OnPreferenceChanged, - base::Unretained(this), - profile->GetPrefs())); - - pref_change_filters_[prefs::kBrowserGuestModeEnabled] = - base::Bind(&CoreOptionsHandler::IsUserUnsupervised, - base::Unretained(this)); - pref_change_filters_[prefs::kBrowserAddPersonEnabled] = - base::Bind(&CoreOptionsHandler::IsUserUnsupervised, - base::Unretained(this)); -} - -void CoreOptionsHandler::InitializePage() { - UpdateClearPluginLSOData(); - UpdatePepperFlashSettingsEnabled(); -} - -void CoreOptionsHandler::GetLocalizedValues( - base::DictionaryValue* localized_strings) { - GetStaticLocalizedValues(localized_strings); -} - -void CoreOptionsHandler::GetStaticLocalizedValues( - base::DictionaryValue* localized_strings) { - DCHECK(localized_strings); - // Main - localized_strings->SetString("optionsPageTitle", - l10n_util::GetStringUTF16(IDS_SETTINGS_TITLE)); - - // Controlled settings bubble. - localized_strings->SetString("controlledSettingPolicy", - l10n_util::GetStringUTF16(IDS_OPTIONS_CONTROLLED_SETTING_POLICY)); - localized_strings->SetString("controlledSettingExtension", - l10n_util::GetStringUTF16(IDS_OPTIONS_CONTROLLED_SETTING_EXTENSION)); - localized_strings->SetString("controlledSettingExtensionWithName", - l10n_util::GetStringUTF16( - IDS_OPTIONS_CONTROLLED_SETTING_EXTENSION_WITH_NAME)); - localized_strings->SetString("controlledSettingManageExtension", - l10n_util::GetStringUTF16( - IDS_OPTIONS_CONTROLLED_SETTING_MANAGE_EXTENSION)); - localized_strings->SetString("controlledSettingDisableExtension", - l10n_util::GetStringUTF16(IDS_EXTENSIONS_DISABLE)); - localized_strings->SetString("controlledSettingRecommended", - l10n_util::GetStringUTF16(IDS_OPTIONS_CONTROLLED_SETTING_RECOMMENDED)); - localized_strings->SetString("controlledSettingHasRecommendation", - l10n_util::GetStringUTF16( - IDS_OPTIONS_CONTROLLED_SETTING_HAS_RECOMMENDATION)); - localized_strings->SetString("controlledSettingFollowRecommendation", - l10n_util::GetStringUTF16( - IDS_OPTIONS_CONTROLLED_SETTING_FOLLOW_RECOMMENDATION)); - localized_strings->SetString("controlledSettingsPolicy", - l10n_util::GetStringUTF16(IDS_OPTIONS_CONTROLLED_SETTINGS_POLICY)); - localized_strings->SetString("controlledSettingsExtension", - l10n_util::GetStringUTF16(IDS_OPTIONS_CONTROLLED_SETTINGS_EXTENSION)); - localized_strings->SetString("controlledSettingsExtensionWithName", - l10n_util::GetStringUTF16( - IDS_OPTIONS_CONTROLLED_SETTINGS_EXTENSION_WITH_NAME)); - - // Search - RegisterTitle(localized_strings, "searchPage", IDS_OPTIONS_SEARCH_PAGE_TITLE); - localized_strings->SetString("searchPlaceholder", - l10n_util::GetStringUTF16(IDS_OPTIONS_SEARCH_PLACEHOLDER)); - localized_strings->SetString("searchPageNoMatches", - l10n_util::GetStringUTF16(IDS_OPTIONS_SEARCH_PAGE_NO_MATCHES)); - localized_strings->SetString("searchPageHelpLabel", - l10n_util::GetStringUTF16(IDS_OPTIONS_SEARCH_PAGE_HELP_LABEL)); - localized_strings->SetString("searchPageHelpTitle", - l10n_util::GetStringFUTF16(IDS_OPTIONS_SEARCH_PAGE_HELP_TITLE, - l10n_util::GetStringUTF16(IDS_PRODUCT_NAME))); - localized_strings->SetString("searchPageHelpURL", - chrome::kSettingsSearchHelpURL); - - // About - localized_strings->SetString("aboutButton", - l10n_util::GetStringUTF16(IDS_ABOUT_BUTTON)); - - // Common - localized_strings->SetString("ok", - l10n_util::GetStringUTF16(IDS_OK)); - localized_strings->SetString("cancel", - l10n_util::GetStringUTF16(IDS_CANCEL)); - localized_strings->SetString("learnMore", - l10n_util::GetStringUTF16(IDS_LEARN_MORE)); - localized_strings->SetString("close", - l10n_util::GetStringUTF16(IDS_CLOSE)); - localized_strings->SetString("done", - l10n_util::GetStringUTF16(IDS_DONE)); - localized_strings->SetString("deletableItemDeleteButtonTitle", - l10n_util::GetStringUTF16(IDS_OPTIONS_DELETABLE_ITEM_DELETE_BUTTON)); -} - -void CoreOptionsHandler::Uninitialize() { - std::string last_pref; - for (PreferenceCallbackMap::const_iterator iter = pref_callback_map_.begin(); - iter != pref_callback_map_.end(); - ++iter) { - if (last_pref != iter->first) { - StopObservingPref(iter->first); - last_pref = iter->first; - } - } -} - -void CoreOptionsHandler::OnPreferenceChanged(PrefService* service, - const std::string& pref_name) { - if (pref_name == prefs::kClearPluginLSODataEnabled) { - // This preference is stored in Local State, not in the user preferences. - UpdateClearPluginLSOData(); - return; - } - if (pref_name == prefs::kPepperFlashSettingsEnabled) { - UpdatePepperFlashSettingsEnabled(); - return; - } - NotifyPrefChanged(pref_name, std::string()); -} - -void CoreOptionsHandler::RegisterMessages() { - registrar_.Init(Profile::FromWebUI(web_ui())->GetPrefs()); - local_state_registrar_.Init(g_browser_process->local_state()); - - web_ui()->RegisterMessageCallback("coreOptionsInitialize", - base::Bind(&CoreOptionsHandler::HandleInitialize, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("onFinishedLoadingOptions", - base::Bind(&CoreOptionsHandler::OnFinishedLoading, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("fetchPrefs", - base::Bind(&CoreOptionsHandler::HandleFetchPrefs, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("observePrefs", - base::Bind(&CoreOptionsHandler::HandleObservePrefs, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("setBooleanPref", - base::Bind(&CoreOptionsHandler::HandleSetBooleanPref, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("setIntegerPref", - base::Bind(&CoreOptionsHandler::HandleSetIntegerPref, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("setDoublePref", - base::Bind(&CoreOptionsHandler::HandleSetDoublePref, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("setStringPref", - base::Bind(&CoreOptionsHandler::HandleSetStringPref, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("setURLPref", - base::Bind(&CoreOptionsHandler::HandleSetURLPref, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("setListPref", - base::Bind(&CoreOptionsHandler::HandleSetListPref, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("clearPref", - base::Bind(&CoreOptionsHandler::HandleClearPref, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("coreOptionsUserMetricsAction", - base::Bind(&CoreOptionsHandler::HandleUserMetricsAction, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("disableExtension", - base::Bind(&CoreOptionsHandler::HandleDisableExtension, - base::Unretained(this))); -} - -void CoreOptionsHandler::HandleInitialize(const base::ListValue* args) { - DCHECK(handlers_host_); - handlers_host_->InitializeHandlers(); -} - -void CoreOptionsHandler::OnFinishedLoading(const base::ListValue* args) { - DCHECK(handlers_host_); - handlers_host_->OnFinishedLoading(); -} - -std::unique_ptr<base::Value> CoreOptionsHandler::FetchPref( - const std::string& pref_name) { - return CreateValueForPref(pref_name, std::string()); -} - -void CoreOptionsHandler::ObservePref(const std::string& pref_name) { - if (g_browser_process->local_state()->FindPreference(pref_name)) { - local_state_registrar_.Add( - pref_name, - base::Bind(&CoreOptionsHandler::OnPreferenceChanged, - base::Unretained(this), - local_state_registrar_.prefs())); - } - // TODO(pneubeck): change this to if/else once kProxy is only used as a user - // pref. Currently, it is both a user and a local state pref. - if (Profile::FromWebUI(web_ui())->GetPrefs()->FindPreference(pref_name)) { - registrar_.Add( - pref_name, - base::Bind(&CoreOptionsHandler::OnPreferenceChanged, - base::Unretained(this), - registrar_.prefs())); - } -} - -void CoreOptionsHandler::StopObservingPref(const std::string& pref_name) { - if (g_browser_process->local_state()->FindPreference(pref_name)) - local_state_registrar_.Remove(pref_name); - else - registrar_.Remove(pref_name); -} - -void CoreOptionsHandler::SetPref(const std::string& pref_name, - const base::Value* value, - const std::string& metric) { - PrefService* pref_service = FindServiceForPref(pref_name); - PrefChangeFilterMap::iterator iter = pref_change_filters_.find(pref_name); - if (iter != pref_change_filters_.end()) { - // Also check if the pref is user modifiable (don't even try to run the - // filter function if the user is not allowed to change the pref). - const PrefService::Preference* pref = - pref_service->FindPreference(pref_name); - if ((pref && !pref->IsUserModifiable()) || !iter->second.Run(value)) { - // Reject the change; remind the page of the true value. - NotifyPrefChanged(pref_name, std::string()); - return; - } - } - - switch (value->GetType()) { - case base::Value::Type::BOOLEAN: - case base::Value::Type::INTEGER: - case base::Value::Type::DOUBLE: - case base::Value::Type::STRING: - case base::Value::Type::LIST: - pref_service->Set(pref_name, *value); - break; - - default: - NOTREACHED(); - return; - } - - ProcessUserMetric(value, metric); -} - -void CoreOptionsHandler::ClearPref(const std::string& pref_name, - const std::string& metric) { - PrefService* pref_service = FindServiceForPref(pref_name); - pref_service->ClearPref(pref_name); - - if (!metric.empty()) - base::RecordComputedAction(metric); -} - -void CoreOptionsHandler::ProcessUserMetric(const base::Value* value, - const std::string& metric) { - if (metric.empty()) - return; - - std::string metric_string = metric; - if (value->IsType(base::Value::Type::BOOLEAN)) { - bool bool_value; - CHECK(value->GetAsBoolean(&bool_value)); - metric_string += bool_value ? "_Enable" : "_Disable"; - } - - base::RecordComputedAction(metric_string); -} - -void CoreOptionsHandler::NotifyPrefChanged( - const std::string& pref_name, - const std::string& controlling_pref_name) { - std::unique_ptr<base::Value> value( - CreateValueForPref(pref_name, controlling_pref_name)); - DispatchPrefChangeNotification(pref_name, std::move(value)); -} - -void CoreOptionsHandler::DispatchPrefChangeNotification( - const std::string& name, - std::unique_ptr<base::Value> value) { - std::pair<PreferenceCallbackMap::const_iterator, - PreferenceCallbackMap::const_iterator> range = - pref_callback_map_.equal_range(name); - base::ListValue result_value; - result_value.AppendString(name); - result_value.Append(std::move(value)); - for (PreferenceCallbackMap::const_iterator iter = range.first; - iter != range.second; ++iter) { - const std::string& callback_function = iter->second; - web_ui()->CallJavascriptFunctionUnsafe(callback_function, result_value); - } -} - -std::unique_ptr<base::Value> CoreOptionsHandler::CreateValueForPref( - const std::string& pref_name, - const std::string& controlling_pref_name) { - const PrefService* pref_service = FindServiceForPref(pref_name); - const PrefService::Preference* pref = - pref_service->FindPreference(pref_name); - if (!pref) { - NOTREACHED(); - return base::MakeUnique<base::Value>(); - } - const PrefService::Preference* controlling_pref = - pref_service->FindPreference(controlling_pref_name); - if (!controlling_pref) - controlling_pref = pref; - - auto dict = base::MakeUnique<base::DictionaryValue>(); - dict->Set("value", base::MakeUnique<base::Value>(*pref->GetValue())); - if (controlling_pref->IsManaged()) { - dict->SetString("controlledBy", "policy"); - } else if (controlling_pref->IsExtensionControlled() && - CanSetExtensionControlledPrefValue(controlling_pref)) { - Profile* profile = Profile::FromWebUI(web_ui()); - ExtensionPrefValueMap* extension_pref_value_map = - ExtensionPrefValueMapFactory::GetForBrowserContext(profile); - std::string extension_id = - extension_pref_value_map->GetExtensionControllingPref( - controlling_pref->name()); - - const extensions::Extension* extension = - extensions::ExtensionRegistry::Get(profile)->GetExtensionById( - extension_id, extensions::ExtensionRegistry::EVERYTHING); - if (extension) { - dict->SetString("controlledBy", "extension"); - dict->Set("extension", extensions::util::GetExtensionInfo(extension)); - } - } else if (controlling_pref->IsRecommended()) { - dict->SetString("controlledBy", "recommended"); - } - - const base::Value* recommended_value = - controlling_pref->GetRecommendedValue(); - if (recommended_value) - dict->Set("recommendedValue", - base::MakeUnique<base::Value>(*recommended_value)); - dict->SetBoolean("disabled", !controlling_pref->IsUserModifiable()); - return std::move(dict); -} - -PrefService* CoreOptionsHandler::FindServiceForPref( - const std::string& pref_name) { - // Proxy is a peculiar case: on ChromeOS, settings exist in both user - // prefs and local state, but chrome://settings should affect only user prefs. - // Elsewhere the proxy settings are stored in local state. - // See http://crbug.com/157147 - PrefService* user_prefs = Profile::FromWebUI(web_ui())->GetPrefs(); - if (pref_name == proxy_config::prefs::kProxy) -#if defined(OS_CHROMEOS) - return user_prefs; -#else - return g_browser_process->local_state(); -#endif - - // Find which PrefService contains the given pref. Pref names should not - // be duplicated across services, however if they are, prefer the user's - // prefs. - if (user_prefs->FindPreference(pref_name)) - return user_prefs; - - if (g_browser_process->local_state()->FindPreference(pref_name)) - return g_browser_process->local_state(); - - return user_prefs; -} - -void CoreOptionsHandler::HandleFetchPrefs(const base::ListValue* args) { - // First param is name of callback function, so, there needs to be at least - // one more element for the actual preference identifier. - DCHECK_GE(static_cast<int>(args->GetSize()), 2); - - // Get callback JS function name. - const base::Value* callback; - if (!args->Get(0, &callback) || !callback->IsType(base::Value::Type::STRING)) - return; - - base::string16 callback_function; - if (!callback->GetAsString(&callback_function)) - return; - - // Get the list of name for prefs to build the response dictionary. - base::DictionaryValue result_value; - const base::Value* list_member; - - for (size_t i = 1; i < args->GetSize(); i++) { - if (!args->Get(i, &list_member)) - break; - - if (!list_member->IsType(base::Value::Type::STRING)) - continue; - - std::string pref_name; - if (!list_member->GetAsString(&pref_name)) - continue; - - result_value.Set(pref_name, FetchPref(pref_name)); - } - web_ui()->CallJavascriptFunctionUnsafe(base::UTF16ToASCII(callback_function), - result_value); -} - -void CoreOptionsHandler::HandleObservePrefs(const base::ListValue* args) { - // First param is name is JS callback function name, the rest are pref - // identifiers that we are observing. - DCHECK_GE(static_cast<int>(args->GetSize()), 2); - - // Get preference change callback function name. - std::string callback_func_name; - if (!args->GetString(0, &callback_func_name)) - return; - - // Get all other parameters - pref identifiers. - for (size_t i = 1; i < args->GetSize(); i++) { - const base::Value* list_member; - if (!args->Get(i, &list_member)) - break; - - // Just ignore bad pref identifiers for now. - std::string pref_name; - if (!list_member->IsType(base::Value::Type::STRING) || - !list_member->GetAsString(&pref_name)) - continue; - - if (pref_callback_map_.find(pref_name) == pref_callback_map_.end()) - ObservePref(pref_name); - - pref_callback_map_.insert( - PreferenceCallbackMap::value_type(pref_name, callback_func_name)); - } -} - -void CoreOptionsHandler::HandleSetBooleanPref(const base::ListValue* args) { - HandleSetPref(args, TYPE_BOOLEAN); -} - -void CoreOptionsHandler::HandleSetIntegerPref(const base::ListValue* args) { - HandleSetPref(args, TYPE_INTEGER); -} - -void CoreOptionsHandler::HandleSetDoublePref(const base::ListValue* args) { - HandleSetPref(args, TYPE_DOUBLE); -} - -void CoreOptionsHandler::HandleSetStringPref(const base::ListValue* args) { - HandleSetPref(args, TYPE_STRING); -} - -void CoreOptionsHandler::HandleSetURLPref(const base::ListValue* args) { - HandleSetPref(args, TYPE_URL); -} - -void CoreOptionsHandler::HandleSetListPref(const base::ListValue* args) { - HandleSetPref(args, TYPE_LIST); -} - -void CoreOptionsHandler::HandleSetPref(const base::ListValue* args, - PrefType type) { - DCHECK_GT(static_cast<int>(args->GetSize()), 1); - - std::string pref_name; - if (!args->GetString(0, &pref_name)) - return; - - const base::Value* value; - if (!args->Get(1, &value)) - return; - - std::unique_ptr<base::Value> temp_value; - - switch (type) { - case TYPE_BOOLEAN: - if (!value->IsType(base::Value::Type::BOOLEAN)) { - NOTREACHED(); - return; - } - break; - case TYPE_INTEGER: { - // In JS all numbers are doubles. - double double_value; - if (!value->GetAsDouble(&double_value)) { - NOTREACHED(); - return; - } - int int_value = static_cast<int>(double_value); - temp_value.reset(new base::Value(int_value)); - value = temp_value.get(); - break; - } - case TYPE_DOUBLE: - if (!value->IsType(base::Value::Type::DOUBLE)) { - NOTREACHED(); - return; - } - break; - case TYPE_STRING: - if (!value->IsType(base::Value::Type::STRING)) { - NOTREACHED(); - return; - } - break; - case TYPE_URL: { - std::string original; - if (!value->GetAsString(&original)) { - NOTREACHED(); - return; - } - GURL fixed = url_formatter::FixupURL(original, std::string()); - temp_value.reset(new base::Value(fixed.spec())); - value = temp_value.get(); - break; - } - case TYPE_LIST: { - // In case we have a List pref we got a JSON string. - std::string json_string; - if (!value->GetAsString(&json_string)) { - NOTREACHED(); - return; - } - temp_value = base::JSONReader::Read(json_string); - value = temp_value.get(); - if (!value || !value->IsType(base::Value::Type::LIST)) { - NOTREACHED(); - return; - } - break; - } - default: - NOTREACHED(); - } - - std::string metric; - if (args->GetSize() > 2 && !args->GetString(2, &metric)) - LOG(WARNING) << "Invalid metric parameter: " << pref_name; - SetPref(pref_name, value, metric); -} - -void CoreOptionsHandler::HandleClearPref(const base::ListValue* args) { - DCHECK_GT(static_cast<int>(args->GetSize()), 0); - - std::string pref_name; - if (!args->GetString(0, &pref_name)) - return; - - std::string metric; - if (args->GetSize() > 1) { - if (!args->GetString(1, &metric)) - NOTREACHED(); - } - - ClearPref(pref_name, metric); -} - -void CoreOptionsHandler::HandleUserMetricsAction(const base::ListValue* args) { - std::string metric = base::UTF16ToUTF8(ExtractStringValue(args)); - if (!metric.empty()) - base::RecordComputedAction(metric); -} - -void CoreOptionsHandler::HandleDisableExtension(const base::ListValue* args) { - std::string extension_id; - if (args->GetString(0, &extension_id)) { - ExtensionService* extension_service = extensions::ExtensionSystem::Get( - Profile::FromWebUI(web_ui()))->extension_service(); - DCHECK(extension_service); - extension_service->DisableExtension( - extension_id, extensions::Extension::DISABLE_USER_ACTION); - } else { - NOTREACHED(); - } -} - -void CoreOptionsHandler::UpdateClearPluginLSOData() { - base::Value enabled(plugin_status_pref_setter_.IsClearPluginLSODataEnabled()); - web_ui()->CallJavascriptFunctionUnsafe( - "options.OptionsPage.setClearPluginLSODataEnabled", enabled); -} - -void CoreOptionsHandler::UpdatePepperFlashSettingsEnabled() { - base::Value enabled( - plugin_status_pref_setter_.IsPepperFlashSettingsEnabled()); - web_ui()->CallJavascriptFunctionUnsafe( - "options.OptionsPage.setPepperFlashSettingsEnabled", enabled); -} - -bool CoreOptionsHandler::IsUserUnsupervised(const base::Value* to_value) { - return !Profile::FromWebUI(web_ui())->IsSupervised(); -} - -} // namespace options
diff --git a/chrome/browser/ui/webui/options/core_options_handler.h b/chrome/browser/ui/webui/options/core_options_handler.h deleted file mode 100644 index 1ff2c16..0000000 --- a/chrome/browser/ui/webui/options/core_options_handler.h +++ /dev/null
@@ -1,191 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_WEBUI_OPTIONS_CORE_OPTIONS_HANDLER_H_ -#define CHROME_BROWSER_UI_WEBUI_OPTIONS_CORE_OPTIONS_HANDLER_H_ - -#include <map> -#include <memory> -#include <string> - -#include "base/callback.h" -#include "base/macros.h" -#include "base/values.h" -#include "chrome/browser/plugins/plugin_status_pref_setter.h" -#include "chrome/browser/ui/webui/options/options_ui.h" -#include "components/prefs/pref_change_registrar.h" -#include "components/prefs/pref_service.h" - -namespace options { - -// Core options UI handler. -// Handles resource and JS calls common to all options sub-pages. -class CoreOptionsHandler : public OptionsPageUIHandler { - public: - CoreOptionsHandler(); - ~CoreOptionsHandler() override; - - // OptionsPageUIHandler implementation. - void GetLocalizedValues(base::DictionaryValue* localized_strings) override; - void InitializeHandler() override; - void InitializePage() override; - void Uninitialize() override; - - // WebUIMessageHandler implementation. - void RegisterMessages() override; - - void set_handlers_host(OptionsPageUIHandlerHost* handlers_host) { - handlers_host_ = handlers_host; - } - - // Adds localized strings to |localized_strings|. - static void GetStaticLocalizedValues( - base::DictionaryValue* localized_strings); - - protected: - // Fetches a pref value of given |pref_name|. - // Note that caller owns the returned Value. - virtual std::unique_ptr<base::Value> FetchPref(const std::string& pref_name); - - // Observes a pref of given |pref_name|. - virtual void ObservePref(const std::string& pref_name); - - // Stops observing given preference identified by |pref_name|. - virtual void StopObservingPref(const std::string& pref_name); - - // Sets a pref |value| to given |pref_name|. - virtual void SetPref(const std::string& pref_name, - const base::Value* value, - const std::string& metric); - - // Clears pref value for given |pref_name|. - void ClearPref(const std::string& pref_name, const std::string& metric); - - // Records a user metric action for the given value. - void ProcessUserMetric(const base::Value* value, - const std::string& metric); - - // Virtual dispatch is needed as handling of some prefs may be - // finessed in subclasses. The PrefService pointer is included - // so that subclasses can know whether the observed pref is from the - // local state or not. - virtual void OnPreferenceChanged(PrefService* service, - const std::string& pref_name); - - // Notifies registered JS callbacks on change in |pref_name| preference. - // |controlling_pref_name| controls if |pref_name| is managed by - // policy/extension; empty |controlling_pref_name| indicates no other pref is - // controlling |pref_name|. - void NotifyPrefChanged(const std::string& pref_name, - const std::string& controlling_pref_name); - - // Calls JS callbacks to report a change in the value of the |name| - // preference. |value| is the new value for |name|. Called from - // Notify*Changed methods to fire off the notifications. - void DispatchPrefChangeNotification(const std::string& name, - std::unique_ptr<base::Value> value); - - // Creates dictionary value for the pref described by |pref_name|. - // If |controlling_pref| is not empty, it describes the pref that manages - // |pref| via policy or extension. - virtual std::unique_ptr<base::Value> CreateValueForPref( - const std::string& pref_name, - const std::string& controlling_pref_name); - - typedef std::multimap<std::string, std::string> PreferenceCallbackMap; - PreferenceCallbackMap pref_callback_map_; - - private: - // Type of preference value received from the page. This doesn't map 1:1 to - // Value::Type, since a TYPE_STRING can require custom processing. - enum PrefType { - TYPE_BOOLEAN = 0, - TYPE_INTEGER, - TYPE_DOUBLE, - TYPE_STRING, - TYPE_URL, - TYPE_LIST, - }; - - // Finds the pref service that holds the given pref. If the pref is not found, - // it will return user prefs. - PrefService* FindServiceForPref(const std::string& pref_name); - - // Callback for the "coreOptionsInitialize" message. This message will - // trigger the Initialize() method of all other handlers so that final - // setup can be performed before the page is shown. - void HandleInitialize(const base::ListValue* args); - - // Callback for the "onFinishedLoadingOptions" message. This message is sent - // when the load() handler for the options frame, along with all asynchronous - // calls it has spawned, have finished running. - void OnFinishedLoading(const base::ListValue* args); - - // Callback for the "fetchPrefs" message. This message accepts the list of - // preference names passed as the |args| parameter (ListValue). It passes - // results dictionary of preference values by calling prefsFetched() JS method - // on the page. - void HandleFetchPrefs(const base::ListValue* args); - - // Callback for the "observePrefs" message. This message initiates - // notification observing for given array of preference names. - void HandleObservePrefs(const base::ListValue* args); - - // Callbacks for the "set<type>Pref" message. This message saves the new - // preference value. |args| is an array of parameters as follows: - // item 0 - name of the preference. - // item 1 - the value of the preference in string form. - // item 2 - name of the metric identifier (optional). - void HandleSetBooleanPref(const base::ListValue* args); - void HandleSetIntegerPref(const base::ListValue* args); - void HandleSetDoublePref(const base::ListValue* args); - void HandleSetStringPref(const base::ListValue* args); - void HandleSetURLPref(const base::ListValue* args); - void HandleSetListPref(const base::ListValue* args); - - void HandleSetPref(const base::ListValue* args, PrefType type); - - // Callback for the "clearPref" message. This message clears a preference - // value. |args| is an array of parameters as follows: - // item 0 - name of the preference. - // item 1 - name of the metric identifier (optional). - void HandleClearPref(const base::ListValue* args); - - // Callback for the "coreOptionsUserMetricsAction" message. This records - // an action that should be tracked if metrics recording is enabled. |args| - // is an array that contains a single item, the name of the metric identifier. - void HandleUserMetricsAction(const base::ListValue* args); - - // Callback for the "disableExtension" message. The extension ID string is the - // only argument in the |args| list. - void HandleDisableExtension(const base::ListValue* args); - - void UpdateClearPluginLSOData(); - void UpdatePepperFlashSettingsEnabled(); - - // Checks that the current profile is not supervised. Used as a pref filter. - bool IsUserUnsupervised(const base::Value* to_value); - - OptionsPageUIHandlerHost* handlers_host_; - // This registrar keeps track of user prefs. - PrefChangeRegistrar registrar_; - // This registrar keeps track of local state. - PrefChangeRegistrar local_state_registrar_; - - PluginStatusPrefSetter plugin_status_pref_setter_; - - // This maps pref names to filter functions. The callbacks should take the - // value that the user has attempted to set for the pref, and should return - // true if that value may be applied. If the return value is false, the - // change will be ignored. - typedef std::map<std::string, base::Callback<bool(const base::Value*)> > - PrefChangeFilterMap; - PrefChangeFilterMap pref_change_filters_; - - DISALLOW_COPY_AND_ASSIGN(CoreOptionsHandler); -}; - -} // namespace options - -#endif // CHROME_BROWSER_UI_WEBUI_OPTIONS_CORE_OPTIONS_HANDLER_H_
diff --git a/chrome/browser/ui/webui/options/create_profile_handler.cc b/chrome/browser/ui/webui/options/create_profile_handler.cc deleted file mode 100644 index f820a99..0000000 --- a/chrome/browser/ui/webui/options/create_profile_handler.cc +++ /dev/null
@@ -1,483 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/webui/options/create_profile_handler.h" - -#include <stddef.h> - -#include <vector> - -#include "base/bind.h" -#include "base/files/file_path.h" -#include "base/metrics/histogram_macros.h" -#include "base/strings/string_util.h" -#include "base/value_conversions.h" -#include "base/values.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/profiles/profile_attributes_entry.h" -#include "chrome/browser/profiles/profile_attributes_storage.h" -#include "chrome/browser/profiles/profile_avatar_icon_util.h" -#include "chrome/browser/profiles/profile_manager.h" -#include "chrome/browser/profiles/profile_metrics.h" -#include "chrome/browser/profiles/profiles_state.h" -#include "chrome/browser/sync/profile_sync_service_factory.h" -#include "chrome/browser/ui/webui/profile_helper.h" -#include "chrome/common/features.h" -#include "chrome/common/pref_names.h" -#include "chrome/grit/generated_resources.h" -#include "components/browser_sync/profile_sync_service.h" -#include "components/prefs/pref_service.h" -#include "content/public/browser/web_ui.h" -#include "ui/base/l10n/l10n_util.h" - -#if BUILDFLAG(ENABLE_SUPERVISED_USERS) -#include "chrome/browser/supervised_user/legacy/supervised_user_registration_utility.h" -#include "chrome/browser/supervised_user/legacy/supervised_user_sync_service.h" -#include "chrome/browser/supervised_user/legacy/supervised_user_sync_service_factory.h" -#include "chrome/browser/supervised_user/supervised_user_service.h" -#include "chrome/browser/supervised_user/supervised_user_service_factory.h" -#endif - -namespace options { - -CreateProfileHandler::CreateProfileHandler() - : profile_creation_type_(NO_CREATION_IN_PROGRESS), - weak_ptr_factory_(this) { -} - -CreateProfileHandler::~CreateProfileHandler() { -#if BUILDFLAG(ENABLE_SUPERVISED_USERS) - // Cancellation is only supported for supervised users. - CancelProfileRegistration(false); -#endif -} - -void CreateProfileHandler::GetLocalizedValues( - base::DictionaryValue* localized_strings) { -} - -void CreateProfileHandler::RegisterMessages() { -#if BUILDFLAG(ENABLE_SUPERVISED_USERS) - // Cancellation is only supported for supervised users. - web_ui()->RegisterMessageCallback( - "cancelCreateProfile", - base::Bind(&CreateProfileHandler::HandleCancelProfileCreation, - base::Unretained(this))); -#endif - web_ui()->RegisterMessageCallback( - "createProfile", - base::Bind(&CreateProfileHandler::CreateProfile, - base::Unretained(this))); -} - -void CreateProfileHandler::CreateProfile(const base::ListValue* args) { -#if BUILDFLAG(ENABLE_SUPERVISED_USERS) - // This handler could have been called for a supervised user, for example - // because the user fiddled with the web inspector. Silently return. - if (Profile::FromWebUI(web_ui())->IsSupervised()) - return; -#endif - - if (!profiles::IsMultipleProfilesEnabled()) - return; - - // We can have only one in progress profile creation - // at any given moment, if new ones are initiated just - // ignore them until we are done with the old one. - if (profile_creation_type_ != NO_CREATION_IN_PROGRESS) - return; - - profile_creation_type_ = NON_SUPERVISED_PROFILE_CREATION; - - DCHECK(profile_path_being_created_.empty()); - profile_creation_start_time_ = base::TimeTicks::Now(); - - base::string16 name; - std::string icon_url; - bool create_shortcut = false; - if (args->GetString(0, &name) && args->GetString(1, &icon_url)) { - DCHECK(base::IsStringASCII(icon_url)); - base::TrimWhitespace(name, base::TRIM_ALL, &name); - CHECK(!name.empty()); -#ifndef NDEBUG - size_t icon_index; - DCHECK(profiles::IsDefaultAvatarIconUrl(icon_url, &icon_index)); -#endif - args->GetBoolean(2, &create_shortcut); - } - std::string supervised_user_id; -#if BUILDFLAG(ENABLE_SUPERVISED_USERS) - if (!ProcessSupervisedCreateProfileArgs(args, &supervised_user_id)) - return; -#endif - - ProfileMetrics::LogProfileAddNewUser(ProfileMetrics::ADD_NEW_USER_DIALOG); - - profile_path_being_created_ = ProfileManager::CreateMultiProfileAsync( - name, icon_url, base::Bind(&CreateProfileHandler::OnProfileCreated, - weak_ptr_factory_.GetWeakPtr(), - create_shortcut, supervised_user_id), - supervised_user_id); -} - -void CreateProfileHandler::OnProfileCreated( - bool create_shortcut, - const std::string& supervised_user_id, - Profile* profile, - Profile::CreateStatus status) { - if (status != Profile::CREATE_STATUS_CREATED) - RecordProfileCreationMetrics(status); - - switch (status) { - case Profile::CREATE_STATUS_LOCAL_FAIL: { - ShowProfileCreationError(profile, GetProfileCreationErrorMessageLocal()); - break; - } - case Profile::CREATE_STATUS_CREATED: { - // Do nothing for an intermediate status. - break; - } - case Profile::CREATE_STATUS_INITIALIZED: { - HandleProfileCreationSuccess(create_shortcut, supervised_user_id, - profile); - break; - } - // User-initiated cancellation is handled in CancelProfileRegistration and - // does not call this callback. - case Profile::CREATE_STATUS_CANCELED: - // Supervised user registration errors are handled in - // OnSupervisedUserRegistered(). - case Profile::CREATE_STATUS_REMOTE_FAIL: - case Profile::MAX_CREATE_STATUS: { - NOTREACHED(); - break; - } - } -} - -void CreateProfileHandler::HandleProfileCreationSuccess( - bool create_shortcut, - const std::string& supervised_user_id, - Profile* profile) { - switch (profile_creation_type_) { - case NON_SUPERVISED_PROFILE_CREATION: { - DCHECK(supervised_user_id.empty()); - CreateShortcutAndShowSuccess(create_shortcut, profile); - break; - } -#if BUILDFLAG(ENABLE_SUPERVISED_USERS) - case SUPERVISED_PROFILE_CREATION: - case SUPERVISED_PROFILE_IMPORT: - RegisterSupervisedUser(create_shortcut, supervised_user_id, profile); - break; -#endif - case NO_CREATION_IN_PROGRESS: - NOTREACHED(); - break; - } -} - -void CreateProfileHandler::CreateShortcutAndShowSuccess(bool create_shortcut, - Profile* profile) { - if (create_shortcut) { - ProfileShortcutManager* shortcut_manager = - g_browser_process->profile_manager()->profile_shortcut_manager(); - - if (shortcut_manager) - shortcut_manager->CreateProfileShortcut(profile->GetPath()); - } - - DCHECK_EQ(profile_path_being_created_.value(), profile->GetPath().value()); - profile_path_being_created_.clear(); - DCHECK_NE(NO_CREATION_IN_PROGRESS, profile_creation_type_); - base::DictionaryValue dict; - dict.SetString("name", - profile->GetPrefs()->GetString(prefs::kProfileName)); - dict.Set("filePath", base::CreateFilePathValue(profile->GetPath())); -#if BUILDFLAG(ENABLE_SUPERVISED_USERS) - bool is_supervised = - profile_creation_type_ == SUPERVISED_PROFILE_CREATION || - profile_creation_type_ == SUPERVISED_PROFILE_IMPORT; - dict.SetBoolean("isSupervised", is_supervised); -#endif - web_ui()->CallJavascriptFunctionUnsafe( - GetJavascriptMethodName(PROFILE_CREATION_SUCCESS), dict); - - // If the new profile is a supervised user, instead of opening a new window - // right away, a confirmation overlay will be shown by JS from the creation - // dialog. If we are importing an existing supervised profile or creating a - // new non-supervised user profile we don't show any confirmation, so open - // the new window now. - bool should_open_new_window = true; -#if BUILDFLAG(ENABLE_SUPERVISED_USERS) - if (profile_creation_type_ == SUPERVISED_PROFILE_CREATION) - should_open_new_window = false; -#endif - - if (should_open_new_window) { - // Opening the new window must be the last action, after all callbacks - // have been run, to give them a chance to initialize the profile. - webui::OpenNewWindowForProfile(profile); - } - profile_creation_type_ = NO_CREATION_IN_PROGRESS; -} - -void CreateProfileHandler::ShowProfileCreationError( - Profile* profile, - const base::string16& error) { - DCHECK_NE(NO_CREATION_IN_PROGRESS, profile_creation_type_); - profile_creation_type_ = NO_CREATION_IN_PROGRESS; - profile_path_being_created_.clear(); - web_ui()->CallJavascriptFunctionUnsafe( - GetJavascriptMethodName(PROFILE_CREATION_ERROR), base::Value(error)); - // The ProfileManager calls us back with a NULL profile in some cases. - if (profile) { - webui::DeleteProfileAtPath(profile->GetPath(), - web_ui(), - ProfileMetrics::DELETE_PROFILE_SETTINGS); - } -} - -void CreateProfileHandler::RecordProfileCreationMetrics( - Profile::CreateStatus status) { - UMA_HISTOGRAM_ENUMERATION("Profile.CreateResult", - status, - Profile::MAX_CREATE_STATUS); - UMA_HISTOGRAM_MEDIUM_TIMES( - "Profile.CreateTimeNoTimeout", - base::TimeTicks::Now() - profile_creation_start_time_); -} - -base::string16 CreateProfileHandler::GetProfileCreationErrorMessageLocal() - const { - int message_id = IDS_PROFILES_CREATE_LOCAL_ERROR; -#if BUILDFLAG(ENABLE_SUPERVISED_USERS) - // Local errors can occur during supervised profile import. - if (profile_creation_type_ == SUPERVISED_PROFILE_IMPORT) - message_id = IDS_LEGACY_SUPERVISED_USER_IMPORT_LOCAL_ERROR; -#endif - return l10n_util::GetStringUTF16(message_id); -} - -#if BUILDFLAG(ENABLE_SUPERVISED_USERS) -base::string16 CreateProfileHandler::GetProfileCreationErrorMessageRemote() - const { - return l10n_util::GetStringUTF16( - profile_creation_type_ == SUPERVISED_PROFILE_IMPORT ? - IDS_LEGACY_SUPERVISED_USER_IMPORT_REMOTE_ERROR : - IDS_PROFILES_CREATE_REMOTE_ERROR); -} - -base::string16 CreateProfileHandler::GetProfileCreationErrorMessageSignin() - const { - return l10n_util::GetStringUTF16( - profile_creation_type_ == SUPERVISED_PROFILE_IMPORT ? - IDS_LEGACY_SUPERVISED_USER_IMPORT_SIGN_IN_ERROR : - IDS_PROFILES_CREATE_SIGN_IN_ERROR); -} -#endif - -std::string CreateProfileHandler::GetJavascriptMethodName( - ProfileCreationStatus status) const { - switch (profile_creation_type_) { -#if BUILDFLAG(ENABLE_SUPERVISED_USERS) - case SUPERVISED_PROFILE_IMPORT: - switch (status) { - case PROFILE_CREATION_SUCCESS: - return "BrowserOptions.showSupervisedUserImportSuccess"; - case PROFILE_CREATION_ERROR: - return "BrowserOptions.showSupervisedUserImportError"; - } - break; -#endif - default: - switch (status) { - case PROFILE_CREATION_SUCCESS: - return "BrowserOptions.showCreateProfileSuccess"; - case PROFILE_CREATION_ERROR: - return "BrowserOptions.showCreateProfileError"; - } - break; - } - - NOTREACHED(); - return std::string(); -} - -#if BUILDFLAG(ENABLE_SUPERVISED_USERS) -bool CreateProfileHandler::ProcessSupervisedCreateProfileArgs( - const base::ListValue* args, std::string* supervised_user_id) { - bool supervised_user = false; - if (args->GetSize() >= 5) { - bool success = args->GetBoolean(3, &supervised_user); - DCHECK(success); - - success = args->GetString(4, supervised_user_id); - DCHECK(success); - } - - if (supervised_user) { - if (!IsValidExistingSupervisedUserId(*supervised_user_id)) - return false; - - profile_creation_type_ = SUPERVISED_PROFILE_IMPORT; - if (supervised_user_id->empty()) { - profile_creation_type_ = SUPERVISED_PROFILE_CREATION; - *supervised_user_id = - SupervisedUserRegistrationUtility::GenerateNewSupervisedUserId(); - - // If sync is not yet fully initialized, the creation may take extra time, - // so show a message. Import doesn't wait for an acknowledgment, so it - // won't have the same potential delay. - browser_sync::ProfileSyncService* sync_service = - ProfileSyncServiceFactory::GetInstance()->GetForProfile( - Profile::FromWebUI(web_ui())); - browser_sync::ProfileSyncService::SyncStatusSummary status = - sync_service->QuerySyncStatusSummary(); - if (status == - browser_sync::ProfileSyncService::DATATYPES_NOT_INITIALIZED) { - ShowProfileCreationWarning(l10n_util::GetStringUTF16( - IDS_PROFILES_CREATE_SUPERVISED_JUST_SIGNED_IN)); - } - } - } - return true; -} - -void CreateProfileHandler::HandleCancelProfileCreation( - const base::ListValue* args) { - CancelProfileRegistration(true); -} - -// Non-supervised user creation cannot be canceled. (Creating a non-supervised -// profile shouldn't take significant time, and it can easily be deleted -// afterward.) -void CreateProfileHandler::CancelProfileRegistration(bool user_initiated) { - if (profile_path_being_created_.empty()) - return; - - ProfileManager* manager = g_browser_process->profile_manager(); - Profile* new_profile = manager->GetProfileByPath(profile_path_being_created_); - if (!new_profile || !new_profile->IsSupervised()) - return; - - DCHECK(supervised_user_registration_utility_.get()); - supervised_user_registration_utility_.reset(); - - if (user_initiated) { - UMA_HISTOGRAM_MEDIUM_TIMES( - "Profile.CreateTimeCanceledNoTimeout", - base::TimeTicks::Now() - profile_creation_start_time_); - RecordProfileCreationMetrics(Profile::CREATE_STATUS_CANCELED); - } - - DCHECK_NE(NO_CREATION_IN_PROGRESS, profile_creation_type_); - profile_creation_type_ = NO_CREATION_IN_PROGRESS; - - // Cancelling registration means the callback passed into - // RegisterAndInitSync() won't be called, so the cleanup must be done here. - profile_path_being_created_.clear(); - webui::DeleteProfileAtPath(new_profile->GetPath(), - web_ui(), - ProfileMetrics::DELETE_PROFILE_SETTINGS); -} - -void CreateProfileHandler::RegisterSupervisedUser( - bool create_shortcut, - const std::string& supervised_user_id, - Profile* new_profile) { - DCHECK_EQ(profile_path_being_created_.value(), - new_profile->GetPath().value()); - - SupervisedUserService* supervised_user_service = - SupervisedUserServiceFactory::GetForProfile(new_profile); - - // Register the supervised user using the profile of the custodian. - supervised_user_registration_utility_ = - SupervisedUserRegistrationUtility::Create(Profile::FromWebUI(web_ui())); - supervised_user_service->RegisterAndInitSync( - supervised_user_registration_utility_.get(), - Profile::FromWebUI(web_ui()), - supervised_user_id, - base::Bind(&CreateProfileHandler::OnSupervisedUserRegistered, - weak_ptr_factory_.GetWeakPtr(), - create_shortcut, - new_profile)); -} - -void CreateProfileHandler::OnSupervisedUserRegistered( - bool create_shortcut, - Profile* profile, - const GoogleServiceAuthError& error) { - GoogleServiceAuthError::State state = error.state(); - RecordSupervisedProfileCreationMetrics(state); - if (state == GoogleServiceAuthError::NONE) { - CreateShortcutAndShowSuccess(create_shortcut, profile); - return; - } - - base::string16 error_msg; - if (state == GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS || - state == GoogleServiceAuthError::USER_NOT_SIGNED_UP || - state == GoogleServiceAuthError::ACCOUNT_DELETED || - state == GoogleServiceAuthError::ACCOUNT_DISABLED) { - error_msg = GetProfileCreationErrorMessageSignin(); - } else { - error_msg = GetProfileCreationErrorMessageRemote(); - } - ShowProfileCreationError(profile, error_msg); -} - -void CreateProfileHandler::ShowProfileCreationWarning( - const base::string16& warning) { - DCHECK_EQ(SUPERVISED_PROFILE_CREATION, profile_creation_type_); - web_ui()->CallJavascriptFunctionUnsafe( - "BrowserOptions.showCreateProfileWarning", base::Value(warning)); -} - -void CreateProfileHandler::RecordSupervisedProfileCreationMetrics( - GoogleServiceAuthError::State error_state) { - if (profile_creation_type_ == SUPERVISED_PROFILE_CREATION) { - UMA_HISTOGRAM_ENUMERATION("Profile.SupervisedProfileCreateError", - error_state, - GoogleServiceAuthError::NUM_STATES); - UMA_HISTOGRAM_MEDIUM_TIMES( - "Profile.SupervisedProfileTotalCreateTime", - base::TimeTicks::Now() - profile_creation_start_time_); - } else { - DCHECK_EQ(SUPERVISED_PROFILE_IMPORT, profile_creation_type_); - UMA_HISTOGRAM_ENUMERATION("Profile.SupervisedProfileImportError", - error_state, - GoogleServiceAuthError::NUM_STATES); - UMA_HISTOGRAM_MEDIUM_TIMES( - "Profile.SupervisedProfileTotalImportTime", - base::TimeTicks::Now() - profile_creation_start_time_); - } -} - -bool CreateProfileHandler::IsValidExistingSupervisedUserId( - const std::string& existing_supervised_user_id) const { - if (existing_supervised_user_id.empty()) - return true; - - Profile* profile = Profile::FromWebUI(web_ui()); - const base::DictionaryValue* dict = - SupervisedUserSyncServiceFactory::GetForProfile(profile)-> - GetSupervisedUsers(); - if (!dict->HasKey(existing_supervised_user_id)) - return false; - - // Check if this supervised user already exists on this machine. - std::vector<ProfileAttributesEntry*> entries = - g_browser_process->profile_manager()-> - GetProfileAttributesStorage().GetAllProfilesAttributes(); - for (const ProfileAttributesEntry* entry : entries) { - if (existing_supervised_user_id == entry->GetSupervisedUserId()) - return false; - } - return true; -} -#endif - -} // namespace options
diff --git a/chrome/browser/ui/webui/options/create_profile_handler.h b/chrome/browser/ui/webui/options/create_profile_handler.h deleted file mode 100644 index 29795ca6..0000000 --- a/chrome/browser/ui/webui/options/create_profile_handler.h +++ /dev/null
@@ -1,171 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_WEBUI_OPTIONS_CREATE_PROFILE_HANDLER_H_ -#define CHROME_BROWSER_UI_WEBUI_OPTIONS_CREATE_PROFILE_HANDLER_H_ - -#include <string> - -#include "base/macros.h" -#include "base/memory/weak_ptr.h" -#include "base/time/time.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/profiles/profile_window.h" -#include "chrome/browser/ui/webui/options/options_ui.h" -#include "chrome/common/features.h" -#include "google_apis/gaia/google_service_auth_error.h" - - -namespace base { -class DictionaryValue; -class ListValue; -} - -#if BUILDFLAG(ENABLE_SUPERVISED_USERS) -class SupervisedUserRegistrationUtility; -#endif - -namespace options { - -// Handler for the 'create profile' overlay. -class CreateProfileHandler: public OptionsPageUIHandler { - public: - CreateProfileHandler(); - ~CreateProfileHandler() override; - - // OptionsPageUIHandler implementation. - void GetLocalizedValues(base::DictionaryValue* localized_strings) override; - - // WebUIMessageHandler implementation. - void RegisterMessages() override; - - private: - // Represents the final profile creation status. It is used to map - // the status to the javascript method to be called. - enum ProfileCreationStatus { - PROFILE_CREATION_SUCCESS, - PROFILE_CREATION_ERROR, - }; - - // Represents the type of the in progress profile creation operation. - // It is used to map the type of the profile creation operation to the - // correct UMA metric name. - enum ProfileCreationOperationType { -#if BUILDFLAG(ENABLE_SUPERVISED_USERS) - SUPERVISED_PROFILE_CREATION, - SUPERVISED_PROFILE_IMPORT, -#endif - NON_SUPERVISED_PROFILE_CREATION, - NO_CREATION_IN_PROGRESS - }; - - // Asynchronously creates and initializes a new profile. - // The arguments are as follows: - // 0: name (string) - // 1: icon (string) - // 2: a flag stating whether we should create a profile desktop shortcut - // (optional, boolean) - // 3: a flag stating whether the user should be supervised - // (optional, boolean) - // 4: a string representing the supervised user ID. - void CreateProfile(const base::ListValue* args); - - // If a local error occurs during profile creation, then show an appropriate - // error message. However, if profile creation succeeded and the - // profile being created/imported is a supervised user profile, - // then proceed with the registration step. Otherwise, update the UI - // as the final task after a new profile has been created. - void OnProfileCreated(bool create_shortcut, - const std::string& supervised_user_id, - Profile* profile, - Profile::CreateStatus status); - - void HandleProfileCreationSuccess(bool create_shortcut, - const std::string& supervised_user_id, - Profile* profile); - - // Creates desktop shortcut and updates the UI to indicate success - // when creating a profile. - void CreateShortcutAndShowSuccess(bool create_shortcut, Profile* profile); - - // Updates the UI to show an error when creating a profile. - void ShowProfileCreationError(Profile* profile, const base::string16& error); - - // Updates the UI to show a non-fatal warning when creating a profile. - void ShowProfileCreationWarning(const base::string16& warning); - - // Records UMA histograms relevant to profile creation. - void RecordProfileCreationMetrics(Profile::CreateStatus status); - - base::string16 GetProfileCreationErrorMessageLocal() const; -#if BUILDFLAG(ENABLE_SUPERVISED_USERS) - // The following error messages only apply to supervised profiles. - base::string16 GetProfileCreationErrorMessageRemote() const; - base::string16 GetProfileCreationErrorMessageSignin() const; -#endif - - std::string GetJavascriptMethodName(ProfileCreationStatus status) const; - - // Used to allow cancelling a profile creation (particularly a supervised-user - // registration) in progress. Set when profile creation is begun, and - // cleared when all the callbacks have been run and creation is complete. - base::FilePath profile_path_being_created_; - - // Used to track how long profile creation takes. - base::TimeTicks profile_creation_start_time_; - - // Indicates the type of the in progress profile creation operation. - // The value is only relevant while we are creating/importing a profile. - ProfileCreationOperationType profile_creation_type_; - -#if BUILDFLAG(ENABLE_SUPERVISED_USERS) - // Extracts the supervised user ID from the args passed into CreateProfile, - // sets |profile_creation_type_| if necessary, and returns true if the - // supervised user id specified in |args| are valid. - bool ProcessSupervisedCreateProfileArgs(const base::ListValue* args, - std::string* supervised_user_id); - - // Cancels creation of a supervised-user profile currently in progress, as - // indicated by profile_path_being_created_, removing the object and files - // and canceling supervised-user registration. This is the handler for the - // "cancelCreateProfile" message. |args| is not used. - void HandleCancelProfileCreation(const base::ListValue* args); - - // Internal implementation. This may safely be called whether profile creation - // or registration is in progress or not. |user_initiated| should be true if - // the cancellation was deliberately requested by the user, and false if it - // was caused implicitly, e.g. by shutting down the browser. - void CancelProfileRegistration(bool user_initiated); - - // After a new supervised-user profile has been created, registers the user - // with the management server. - void RegisterSupervisedUser(bool create_shortcut, - const std::string& managed_user_id, - Profile* new_profile); - - // Called back with the result of the supervised user registration. - void OnSupervisedUserRegistered(bool create_shortcut, - Profile* profile, - const GoogleServiceAuthError& error); - - // Records UMA histograms relevant to supervised user profiles - // creation and registration. - void RecordSupervisedProfileCreationMetrics( - GoogleServiceAuthError::State error_state); - - bool IsValidExistingSupervisedUserId( - const std::string& existing_supervised_user_id) const; - - std::unique_ptr<SupervisedUserRegistrationUtility> - supervised_user_registration_utility_; -#endif - - base::WeakPtrFactory<CreateProfileHandler> weak_ptr_factory_; - - DISALLOW_COPY_AND_ASSIGN(CreateProfileHandler); -}; - -} // namespace options - -#endif // CHROME_BROWSER_UI_WEBUI_OPTIONS_CREATE_PROFILE_HANDLER_H_
diff --git a/chrome/browser/ui/webui/options/easy_unlock_handler.cc b/chrome/browser/ui/webui/options/easy_unlock_handler.cc deleted file mode 100644 index ff3cf2dd..0000000 --- a/chrome/browser/ui/webui/options/easy_unlock_handler.cc +++ /dev/null
@@ -1,110 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/webui/options/easy_unlock_handler.h" - -#include <string> - -#include "base/bind.h" -#include "base/macros.h" -#include "base/values.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/signin/easy_unlock_service.h" -#include "chrome/grit/generated_resources.h" -#include "content/public/browser/web_ui.h" - -namespace options { - -EasyUnlockHandler::EasyUnlockHandler() { -} - -EasyUnlockHandler::~EasyUnlockHandler() { - EasyUnlockService::Get(Profile::FromWebUI(web_ui()))->RemoveObserver(this); -} - -void EasyUnlockHandler::GetLocalizedValues(base::DictionaryValue* values) { - static OptionsStringResource resources[] = { - {"easyUnlockTurnOffButton", IDS_OPTIONS_EASY_UNLOCK_TURN_OFF_BUTTON}, - {"easyUnlockTurnOffTitle", IDS_OPTIONS_EASY_UNLOCK_TURN_OFF_TITLE}, - {"easyUnlockTurnOffDescription", - IDS_OPTIONS_EASY_UNLOCK_TURN_OFF_DESCRIPTION}, - {"easyUnlockTurnOffOfflineTitle", - IDS_OPTIONS_EASY_UNLOCK_TURN_OFF_OFFLINE_TITLE}, - {"easyUnlockTurnOffOfflineMessage", - IDS_OPTIONS_EASY_UNLOCK_TURN_OFF_OFFLINE_MESSAGE}, - {"easyUnlockTurnOffErrorTitle", - IDS_OPTIONS_EASY_UNLOCK_TURN_OFF_ERROR_TITLE}, - {"easyUnlockTurnOffErrorMessage", - IDS_OPTIONS_EASY_UNLOCK_TURN_OFF_ERROR_MESSAGE}, - {"easyUnlockTurnOffRetryButton", - IDS_OPTIONS_EASY_UNLOCK_TURN_OFF_RETRY_BUTTON}, - }; - - RegisterStrings(values, resources, arraysize(resources)); -} - -void EasyUnlockHandler::InitializeHandler() { - EasyUnlockService::Get(Profile::FromWebUI(web_ui()))->AddObserver(this); -} - -void EasyUnlockHandler::RegisterMessages() { - web_ui()->RegisterMessageCallback( - "easyUnlockGetTurnOffFlowStatus", - base::Bind(&EasyUnlockHandler::HandleGetTurnOffFlowStatus, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "easyUnlockRequestTurnOff", - base::Bind(&EasyUnlockHandler::HandleRequestTurnOff, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "easyUnlockTurnOffOverlayDismissed", - base::Bind(&EasyUnlockHandler::HandlePageDismissed, - base::Unretained(this))); -} - -void EasyUnlockHandler::OnTurnOffOperationStatusChanged() { - SendTurnOffOperationStatus(); -} - -void EasyUnlockHandler::SendTurnOffOperationStatus() { - EasyUnlockService::TurnOffFlowStatus status = - EasyUnlockService::Get(Profile::FromWebUI(web_ui())) - ->GetTurnOffFlowStatus(); - - // Translate status into JS UI state string. Note the translated string - // should match UIState defined in easy_unlock_turn_off_overlay.js. - std::string status_string; - switch (status) { - case EasyUnlockService::IDLE: - status_string = "idle"; - break; - case EasyUnlockService::PENDING: - status_string = "pending"; - break; - case EasyUnlockService::FAIL: - status_string = "server-error"; - break; - default: - LOG(ERROR) << "Unknown Easy unlock turn-off operation status: " << status; - status_string = "idle"; - break; - } - web_ui()->CallJavascriptFunctionUnsafe( - "EasyUnlockTurnOffOverlay.updateUIState", base::Value(status_string)); -} - -void EasyUnlockHandler::HandleGetTurnOffFlowStatus( - const base::ListValue* args) { - SendTurnOffOperationStatus(); -} - -void EasyUnlockHandler::HandleRequestTurnOff(const base::ListValue* args) { - EasyUnlockService::Get(Profile::FromWebUI(web_ui()))->RunTurnOffFlow(); -} - -void EasyUnlockHandler::HandlePageDismissed(const base::ListValue* args) { - EasyUnlockService::Get(Profile::FromWebUI(web_ui()))->ResetTurnOffFlow(); -} - -} // namespace options
diff --git a/chrome/browser/ui/webui/options/easy_unlock_handler.h b/chrome/browser/ui/webui/options/easy_unlock_handler.h deleted file mode 100644 index c8feb5f..0000000 --- a/chrome/browser/ui/webui/options/easy_unlock_handler.h +++ /dev/null
@@ -1,43 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_WEBUI_OPTIONS_EASY_UNLOCK_HANDLER_H_ -#define CHROME_BROWSER_UI_WEBUI_OPTIONS_EASY_UNLOCK_HANDLER_H_ - -#include "base/macros.h" -#include "chrome/browser/signin/easy_unlock_service_observer.h" -#include "chrome/browser/ui/webui/options/options_ui.h" - -namespace options { - -class EasyUnlockHandler : public OptionsPageUIHandler, - public EasyUnlockServiceObserver { - public: - EasyUnlockHandler(); - ~EasyUnlockHandler() override; - - // OptionsPageUIHandler - void InitializeHandler() override; - void GetLocalizedValues(base::DictionaryValue* values) override; - - // WebUIMessageHandler - void RegisterMessages() override; - - // EasyUnlockServiceObserver - void OnTurnOffOperationStatusChanged() override; - - private: - void SendTurnOffOperationStatus(); - - // JS callbacks. - void HandleGetTurnOffFlowStatus(const base::ListValue* args); - void HandleRequestTurnOff(const base::ListValue* args); - void HandlePageDismissed(const base::ListValue* args); - - DISALLOW_COPY_AND_ASSIGN(EasyUnlockHandler); -}; - -} // namespace options - -#endif // CHROME_BROWSER_UI_WEBUI_OPTIONS_EASY_UNLOCK_HANDLER_H_
diff --git a/chrome/browser/ui/webui/options/font_settings_handler.cc b/chrome/browser/ui/webui/options/font_settings_handler.cc deleted file mode 100644 index 7b1ca1f..0000000 --- a/chrome/browser/ui/webui/options/font_settings_handler.cc +++ /dev/null
@@ -1,279 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/webui/options/font_settings_handler.h" - -#include <stddef.h> - -#include <string> -#include <utility> - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/i18n/rtl.h" -#include "base/macros.h" -#include "base/strings/string_number_conversions.h" -#include "base/strings/string_util.h" -#include "base/strings/utf_string_conversions.h" -#include "base/values.h" -#include "build/build_config.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/extensions/extension_service.h" -#include "chrome/browser/extensions/extension_tab_util.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/browser_finder.h" -#include "chrome/browser/ui/webui/settings_utils.h" -#include "chrome/common/pref_names.h" -#include "chrome/grit/generated_resources.h" -#include "components/prefs/pref_service.h" -#include "content/public/browser/font_list_async.h" -#include "content/public/browser/notification_details.h" -#include "content/public/browser/notification_service.h" -#include "content/public/browser/web_ui.h" -#include "extensions/browser/extension_registry.h" -#include "extensions/browser/extension_system.h" -#include "extensions/common/extension.h" -#include "extensions/common/extension_urls.h" -#include "ui/base/l10n/l10n_util.h" -#include "url/gurl.h" - -namespace { - -const char kAdvancedFontSettingsExtensionId[] = - "caclkomlalccbpcdllchkeecicepbmbm"; - -} // namespace - - -namespace options { - -FontSettingsHandler::FontSettingsHandler() - : extension_registry_observer_(this), - weak_ptr_factory_(this) { -} - -FontSettingsHandler::~FontSettingsHandler() { -} - -void FontSettingsHandler::GetLocalizedValues( - base::DictionaryValue* localized_strings) { - DCHECK(localized_strings); - - static OptionsStringResource resources[] = { - { "fontSettingsStandard", - IDS_FONT_LANGUAGE_SETTING_FONT_SELECTOR_STANDARD_LABEL }, - { "fontSettingsSerif", - IDS_FONT_LANGUAGE_SETTING_FONT_SELECTOR_SERIF_LABEL }, - { "fontSettingsSansSerif", - IDS_FONT_LANGUAGE_SETTING_FONT_SELECTOR_SANS_SERIF_LABEL }, - { "fontSettingsFixedWidth", - IDS_FONT_LANGUAGE_SETTING_FONT_SELECTOR_FIXED_WIDTH_LABEL }, - { "fontSettingsMinimumSize", - IDS_FONT_LANGUAGE_SETTING_MINIMUM_FONT_SIZE_TITLE }, - { "fontSettings", - IDS_FONT_LANGUAGE_SETTING_FONT_SUB_DIALOG_TITLE }, - { "fontSettingsSizeTiny", - IDS_FONT_LANGUAGE_SETTING_FONT_SIZE_TINY }, - { "fontSettingsSizeHuge", - IDS_FONT_LANGUAGE_SETTING_FONT_SIZE_HUGE }, - { "fontSettingsLoremIpsum", - IDS_FONT_LANGUAGE_SETTING_LOREM_IPSUM }, - { "advancedFontSettingsOptions", - IDS_FONT_LANGUAGE_SETTING_ADVANCED_FONT_SETTINGS_OPTIONS } - }; - - RegisterStrings(localized_strings, resources, arraysize(resources)); - RegisterTitle(localized_strings, "fontSettingsPage", - IDS_FONT_LANGUAGE_SETTING_FONT_TAB_TITLE); - localized_strings->SetString("fontSettingsPlaceholder", - l10n_util::GetStringUTF16( - IDS_FONT_LANGUAGE_SETTING_PLACEHOLDER)); - - GURL install_url(extension_urls::GetWebstoreItemDetailURLPrefix()); - localized_strings->SetString("advancedFontSettingsInstall", - l10n_util::GetStringFUTF16( - IDS_FONT_LANGUAGE_SETTING_ADVANCED_FONT_SETTINGS_INSTALL, - base::UTF8ToUTF16( - install_url.Resolve(kAdvancedFontSettingsExtensionId).spec()))); -} - -void FontSettingsHandler::InitializeHandler() { - Profile* profile = Profile::FromWebUI(web_ui()); - extension_registry_observer_.Add(extensions::ExtensionRegistry::Get(profile)); -} - -void FontSettingsHandler::InitializePage() { - DCHECK(web_ui()); - SetUpStandardFontSample(); - SetUpSerifFontSample(); - SetUpSansSerifFontSample(); - SetUpFixedFontSample(); - SetUpMinimumFontSample(); - NotifyAdvancedFontSettingsAvailability(); -} - -void FontSettingsHandler::RegisterMessages() { - // Perform validation for saved fonts. - PrefService* pref_service = Profile::FromWebUI(web_ui())->GetPrefs(); -#if defined(OS_MACOSX) - settings_utils::ValidateSavedFonts(pref_service); -#endif - - // Register for preferences that we need to observe manually. - standard_font_.Init(prefs::kWebKitStandardFontFamily, - pref_service, - base::Bind(&FontSettingsHandler::SetUpStandardFontSample, - base::Unretained(this))); - serif_font_.Init(prefs::kWebKitSerifFontFamily, - pref_service, - base::Bind(&FontSettingsHandler::SetUpSerifFontSample, - base::Unretained(this))); - sans_serif_font_.Init( - prefs::kWebKitSansSerifFontFamily, - pref_service, - base::Bind(&FontSettingsHandler::SetUpSansSerifFontSample, - base::Unretained(this))); - - base::Closure callback = base::Bind( - &FontSettingsHandler::SetUpFixedFontSample, base::Unretained(this)); - - fixed_font_.Init(prefs::kWebKitFixedFontFamily, pref_service, callback); - default_fixed_font_size_.Init(prefs::kWebKitDefaultFixedFontSize, - pref_service, callback); - default_font_size_.Init( - prefs::kWebKitDefaultFontSize, - pref_service, - base::Bind(&FontSettingsHandler::OnWebKitDefaultFontSizeChanged, - base::Unretained(this))); - minimum_font_size_.Init( - prefs::kWebKitMinimumFontSize, - pref_service, - base::Bind(&FontSettingsHandler::SetUpMinimumFontSample, - base::Unretained(this))); - - web_ui()->RegisterMessageCallback("fetchFontsData", - base::Bind(&FontSettingsHandler::HandleFetchFontsData, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("openAdvancedFontSettingsOptions", - base::Bind(&FontSettingsHandler::HandleOpenAdvancedFontSettingsOptions, - base::Unretained(this))); -} - -void FontSettingsHandler::OnExtensionLoaded( - content::BrowserContext* browser_context, - const extensions::Extension* extension) { - NotifyAdvancedFontSettingsAvailability(); -} - -void FontSettingsHandler::OnExtensionUnloaded( - content::BrowserContext* browser_context, - const extensions::Extension* extension, - extensions::UnloadedExtensionReason reason) { - NotifyAdvancedFontSettingsAvailability(); -} - -void FontSettingsHandler::HandleFetchFontsData(const base::ListValue* args) { - content::GetFontListAsync( - base::Bind(&FontSettingsHandler::FontsListHasLoaded, - weak_ptr_factory_.GetWeakPtr())); -} - -void FontSettingsHandler::FontsListHasLoaded( - std::unique_ptr<base::ListValue> list) { - // Selects the directionality for the fonts in the given list. - for (size_t i = 0; i < list->GetSize(); i++) { - base::ListValue* font; - bool has_font = list->GetList(i, &font); - DCHECK(has_font); - base::string16 value; - bool has_value = font->GetString(1, &value); - DCHECK(has_value); - bool has_rtl_chars = base::i18n::StringContainsStrongRTLChars(value); - font->AppendString(has_rtl_chars ? "rtl" : "ltr"); - } - - base::ListValue selected_values; - selected_values.AppendString( - settings_utils::MaybeGetLocalizedFontName(standard_font_.GetValue())); - selected_values.AppendString( - settings_utils::MaybeGetLocalizedFontName(serif_font_.GetValue())); - selected_values.AppendString( - settings_utils::MaybeGetLocalizedFontName(sans_serif_font_.GetValue())); - selected_values.AppendString( - settings_utils::MaybeGetLocalizedFontName(fixed_font_.GetValue())); - - web_ui()->CallJavascriptFunctionUnsafe( - "FontSettings.setFontsData", *list.get(), selected_values); -} - -void FontSettingsHandler::SetUpStandardFontSample() { - base::Value font_value( - settings_utils::ResolveFontList(standard_font_.GetValue())); - base::Value size_value(default_font_size_.GetValue()); - web_ui()->CallJavascriptFunctionUnsafe("FontSettings.setUpStandardFontSample", - font_value, size_value); -} - -void FontSettingsHandler::SetUpSerifFontSample() { - base::Value font_value( - settings_utils::ResolveFontList(serif_font_.GetValue())); - base::Value size_value(default_font_size_.GetValue()); - web_ui()->CallJavascriptFunctionUnsafe("FontSettings.setUpSerifFontSample", - font_value, size_value); -} - -void FontSettingsHandler::SetUpSansSerifFontSample() { - base::Value font_value( - settings_utils::ResolveFontList(sans_serif_font_.GetValue())); - base::Value size_value(default_font_size_.GetValue()); - web_ui()->CallJavascriptFunctionUnsafe( - "FontSettings.setUpSansSerifFontSample", font_value, size_value); -} - -void FontSettingsHandler::SetUpFixedFontSample() { - base::Value font_value( - settings_utils::ResolveFontList(fixed_font_.GetValue())); - base::Value size_value(default_fixed_font_size_.GetValue()); - web_ui()->CallJavascriptFunctionUnsafe("FontSettings.setUpFixedFontSample", - font_value, size_value); -} - -void FontSettingsHandler::SetUpMinimumFontSample() { - base::Value size_value(minimum_font_size_.GetValue()); - web_ui()->CallJavascriptFunctionUnsafe("FontSettings.setUpMinimumFontSample", - size_value); -} - -const extensions::Extension* -FontSettingsHandler::GetAdvancedFontSettingsExtension() { - Profile* profile = Profile::FromWebUI(web_ui()); - ExtensionService* service = - extensions::ExtensionSystem::Get(profile)->extension_service(); - if (!service->IsExtensionEnabled(kAdvancedFontSettingsExtensionId)) - return NULL; - return service->GetInstalledExtension(kAdvancedFontSettingsExtensionId); -} - -void FontSettingsHandler::NotifyAdvancedFontSettingsAvailability() { - web_ui()->CallJavascriptFunctionUnsafe( - "FontSettings.notifyAdvancedFontSettingsAvailability", - base::Value(GetAdvancedFontSettingsExtension() != NULL)); -} - -void FontSettingsHandler::HandleOpenAdvancedFontSettingsOptions( - const base::ListValue* args) { - const extensions::Extension* extension = GetAdvancedFontSettingsExtension(); - if (!extension) - return; - extensions::ExtensionTabUtil::OpenOptionsPage(extension, - chrome::FindBrowserWithWebContents(web_ui()->GetWebContents())); -} - -void FontSettingsHandler::OnWebKitDefaultFontSizeChanged() { - SetUpStandardFontSample(); - SetUpSerifFontSample(); - SetUpSansSerifFontSample(); -} - -} // namespace options
diff --git a/chrome/browser/ui/webui/options/font_settings_handler.h b/chrome/browser/ui/webui/options/font_settings_handler.h deleted file mode 100644 index adcd8e8..0000000 --- a/chrome/browser/ui/webui/options/font_settings_handler.h +++ /dev/null
@@ -1,91 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_WEBUI_OPTIONS_FONT_SETTINGS_HANDLER_H_ -#define CHROME_BROWSER_UI_WEBUI_OPTIONS_FONT_SETTINGS_HANDLER_H_ - -#include <memory> - -#include "base/macros.h" -#include "base/memory/weak_ptr.h" -#include "base/scoped_observer.h" -#include "chrome/browser/ui/webui/options/options_ui.h" -#include "components/prefs/pref_member.h" -#include "extensions/browser/extension_registry_observer.h" - -namespace base { -class ListValue; -} - -namespace extensions { -class Extension; -class ExtensionRegistry; -} - -namespace options { - -// Font settings overlay page UI handler. -class FontSettingsHandler : public OptionsPageUIHandler, - public extensions::ExtensionRegistryObserver { - public: - FontSettingsHandler(); - ~FontSettingsHandler() override; - - // OptionsPageUIHandler implementation. - void GetLocalizedValues(base::DictionaryValue* localized_strings) override; - void InitializeHandler() override; - void InitializePage() override; - - // WebUIMessageHandler implementation. - void RegisterMessages() override; - - // ExtensionRegistryObserver implementation. - void OnExtensionLoaded(content::BrowserContext* browser_context, - const extensions::Extension* extension) override; - void OnExtensionUnloaded(content::BrowserContext* browser_context, - const extensions::Extension* extension, - extensions::UnloadedExtensionReason reason) override; - - private: - void HandleFetchFontsData(const base::ListValue* args); - - void FontsListHasLoaded(std::unique_ptr<base::ListValue> list); - - void SetUpStandardFontSample(); - void SetUpSerifFontSample(); - void SetUpSansSerifFontSample(); - void SetUpFixedFontSample(); - void SetUpMinimumFontSample(); - - // Returns the Advanced Font Settings Extension if it's installed and enabled, - // or NULL otherwise. - const extensions::Extension* GetAdvancedFontSettingsExtension(); - // Notifies the web UI about whether the Advanced Font Settings Extension is - // installed and enabled. - void NotifyAdvancedFontSettingsAvailability(); - // Opens the options page of the Advanced Font Settings Extension. - void HandleOpenAdvancedFontSettingsOptions(const base::ListValue* args); - - void OnWebKitDefaultFontSizeChanged(); - - StringPrefMember standard_font_; - StringPrefMember serif_font_; - StringPrefMember sans_serif_font_; - StringPrefMember fixed_font_; - IntegerPrefMember default_font_size_; - IntegerPrefMember default_fixed_font_size_; - IntegerPrefMember minimum_font_size_; - - ScopedObserver<extensions::ExtensionRegistry, - extensions::ExtensionRegistryObserver> - extension_registry_observer_; - - base::WeakPtrFactory<FontSettingsHandler> weak_ptr_factory_; - - DISALLOW_COPY_AND_ASSIGN(FontSettingsHandler); -}; - -} // namespace options - -#endif // CHROME_BROWSER_UI_WEBUI_OPTIONS_FONT_SETTINGS_HANDLER_H_
diff --git a/chrome/browser/ui/webui/options/geolocation_options_handler.cc b/chrome/browser/ui/webui/options/geolocation_options_handler.cc deleted file mode 100644 index 05a04eb..0000000 --- a/chrome/browser/ui/webui/options/geolocation_options_handler.cc +++ /dev/null
@@ -1,40 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/webui/options/geolocation_options_handler.h" - -#include "base/command_line.h" -#include "base/metrics/field_trial.h" -#include "chrome/common/chrome_switches.h" -#include "content/public/browser/web_ui.h" - -namespace options { - -GeolocationOptionsHandler::GeolocationOptionsHandler() {} - -GeolocationOptionsHandler::~GeolocationOptionsHandler() {} - -void GeolocationOptionsHandler::GetLocalizedValues( - base::DictionaryValue* localized_strings) { -} - -void GeolocationOptionsHandler::InitializePage() { - DCHECK(web_ui()); - - const char kEnablePrefix[] = "Enable"; - const char kFieldTrialName[] = "GoogleNow"; - std::string enable_prefix(kEnablePrefix); - std::string field_trial_result = - base::FieldTrialList::FindFullName(kFieldTrialName); - if (field_trial_result.compare( - 0, - enable_prefix.length(), - enable_prefix) == 0) { - web_ui()->CallJavascriptFunctionUnsafe( - "GeolocationOptions.showGeolocationOption"); - } -} - -} // namespace options -
diff --git a/chrome/browser/ui/webui/options/geolocation_options_handler.h b/chrome/browser/ui/webui/options/geolocation_options_handler.h deleted file mode 100644 index aeb4e76..0000000 --- a/chrome/browser/ui/webui/options/geolocation_options_handler.h +++ /dev/null
@@ -1,31 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_WEBUI_OPTIONS_GEOLOCATION_OPTIONS_HANDLER_H_ -#define CHROME_BROWSER_UI_WEBUI_OPTIONS_GEOLOCATION_OPTIONS_HANDLER_H_ - -#include "base/macros.h" -#include "chrome/browser/ui/webui/options/options_ui.h" -#include "components/prefs/pref_member.h" - -namespace options { - -// Handles processing of the geolocation options on settings page load. -class GeolocationOptionsHandler : public OptionsPageUIHandler { - public: - GeolocationOptionsHandler(); - ~GeolocationOptionsHandler() override; - - // OptionsPageUIHandler implementation - void GetLocalizedValues(base::DictionaryValue* localized_strings) override; - void InitializePage() override; - - private: - DISALLOW_COPY_AND_ASSIGN(GeolocationOptionsHandler); -}; - -} // namespace options - -#endif // CHROME_BROWSER_UI_WEBUI_OPTIONS_GEOLOCATION_OPTIONS_HANDLER_H_ -
diff --git a/chrome/browser/ui/webui/options/handler_options_handler.cc b/chrome/browser/ui/webui/options/handler_options_handler.cc deleted file mode 100644 index 73b3fdea0..0000000 --- a/chrome/browser/ui/webui/options/handler_options_handler.cc +++ /dev/null
@@ -1,224 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/webui/options/handler_options_handler.h" - -#include <memory> -#include <utility> -#include <vector> - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/macros.h" -#include "base/memory/ptr_util.h" -#include "base/strings/utf_string_conversions.h" -#include "base/values.h" -#include "chrome/browser/chrome_notification_types.h" -#include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/common/url_constants.h" -#include "chrome/grit/generated_resources.h" -#include "components/google/core/browser/google_util.h" -#include "components/prefs/pref_service.h" -#include "content/public/browser/web_ui.h" - -namespace options { - -HandlerOptionsHandler::HandlerOptionsHandler() { -} - -HandlerOptionsHandler::~HandlerOptionsHandler() { -} - -void HandlerOptionsHandler::GetLocalizedValues( - base::DictionaryValue* localized_strings) { - DCHECK(localized_strings); - - static OptionsStringResource resources[] = { - { "handlersTabLabel", IDS_HANDLERS_TAB_LABEL }, - { "handlersAllow", IDS_HANDLERS_ALLOW_RADIO }, - { "handlersBlock", IDS_HANDLERS_DONOTALLOW_RADIO }, - { "handlersTypeColumnHeader", IDS_HANDLERS_TYPE_COLUMN_HEADER }, - { "handlersSiteColumnHeader", IDS_HANDLERS_SITE_COLUMN_HEADER }, - { "handlersRemoveLink", IDS_HANDLERS_REMOVE_HANDLER_LINK }, - { "handlersNoneHandler", IDS_HANDLERS_NONE_HANDLER }, - { "handlersActiveHeading", IDS_HANDLERS_ACTIVE_HEADING }, - { "handlersIgnoredHeading", IDS_HANDLERS_IGNORED_HEADING }, - }; - RegisterTitle(localized_strings, "handlersPage", - IDS_HANDLER_OPTIONS_WINDOW_TITLE); - RegisterStrings(localized_strings, resources, arraysize(resources)); - - localized_strings->SetString("handlersLearnMoreUrl", - chrome::kLearnMoreRegisterProtocolHandlerURL); -} - -void HandlerOptionsHandler::InitializeHandler() { - notification_registrar_.Add( - this, chrome::NOTIFICATION_PROTOCOL_HANDLER_REGISTRY_CHANGED, - content::Source<Profile>(Profile::FromWebUI(web_ui()))); -} - -void HandlerOptionsHandler::InitializePage() { - UpdateHandlerList(); -} - -void HandlerOptionsHandler::RegisterMessages() { - web_ui()->RegisterMessageCallback("clearDefault", - base::Bind(&HandlerOptionsHandler::ClearDefault, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("removeHandler", - base::Bind(&HandlerOptionsHandler::RemoveHandler, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("setHandlersEnabled", - base::Bind(&HandlerOptionsHandler::SetHandlersEnabled, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("setDefault", - base::Bind(&HandlerOptionsHandler::SetDefault, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("removeIgnoredHandler", - base::Bind(&HandlerOptionsHandler::RemoveIgnoredHandler, - base::Unretained(this))); -} - -ProtocolHandlerRegistry* HandlerOptionsHandler::GetProtocolHandlerRegistry() { - return ProtocolHandlerRegistryFactory::GetForBrowserContext( - Profile::FromWebUI(web_ui())); -} - -static void GetHandlersAsListValue( - const ProtocolHandlerRegistry::ProtocolHandlerList& handlers, - base::ListValue* handler_list) { - ProtocolHandlerRegistry::ProtocolHandlerList::const_iterator handler; - for (handler = handlers.begin(); handler != handlers.end(); ++handler) { - std::unique_ptr<base::ListValue> handler_value(new base::ListValue()); - handler_value->AppendString(handler->protocol()); - handler_value->AppendString(handler->url().spec()); - handler_value->AppendString(handler->url().host()); - handler_list->Append(std::move(handler_value)); - } -} - -void HandlerOptionsHandler::GetHandlersForProtocol( - const std::string& protocol, - base::DictionaryValue* handlers_value) { - ProtocolHandlerRegistry* registry = GetProtocolHandlerRegistry(); - // The items which are to be written into |handlers_value| are also described - // in chrome/browser/resources/options/handler_options.js in @typedef - // for Handlers. Please update them whenever you add or remove any keys here. - handlers_value->SetString("protocol", protocol); - handlers_value->SetInteger("default_handler", - registry->GetHandlerIndex(protocol)); - handlers_value->SetBoolean( - "is_default_handler_set_by_user", - registry->IsRegisteredByUser(registry->GetHandlerFor(protocol))); - handlers_value->SetBoolean("has_policy_recommendations", - registry->HasPolicyRegisteredHandler(protocol)); - - auto handlers_list = base::MakeUnique<base::ListValue>(); - GetHandlersAsListValue(registry->GetHandlersFor(protocol), - handlers_list.get()); - handlers_value->Set("handlers", std::move(handlers_list)); -} - -void HandlerOptionsHandler::GetIgnoredHandlers(base::ListValue* handlers) { - ProtocolHandlerRegistry* registry = GetProtocolHandlerRegistry(); - ProtocolHandlerRegistry::ProtocolHandlerList ignored_handlers = - registry->GetIgnoredHandlers(); - return GetHandlersAsListValue(ignored_handlers, handlers); -} - -void HandlerOptionsHandler::UpdateHandlerList() { - ProtocolHandlerRegistry* registry = GetProtocolHandlerRegistry(); - std::vector<std::string> protocols; - registry->GetRegisteredProtocols(&protocols); - - base::ListValue handlers; - for (std::vector<std::string>::iterator protocol = protocols.begin(); - protocol != protocols.end(); protocol++) { - std::unique_ptr<base::DictionaryValue> handler_value( - new base::DictionaryValue()); - GetHandlersForProtocol(*protocol, handler_value.get()); - handlers.Append(std::move(handler_value)); - } - - std::unique_ptr<base::ListValue> ignored_handlers(new base::ListValue()); - GetIgnoredHandlers(ignored_handlers.get()); - web_ui()->CallJavascriptFunctionUnsafe("HandlerOptions.setHandlers", - handlers); - web_ui()->CallJavascriptFunctionUnsafe("HandlerOptions.setIgnoredHandlers", - *ignored_handlers); -} - -void HandlerOptionsHandler::RemoveHandler(const base::ListValue* args) { - const base::ListValue* list; - if (!args->GetList(0, &list)) { - NOTREACHED(); - return; - } - - ProtocolHandler handler(ParseHandlerFromArgs(list)); - GetProtocolHandlerRegistry()->RemoveHandler(handler); - - // No need to call UpdateHandlerList() - we should receive a notification - // that the ProtocolHandlerRegistry has changed and we will update the view - // then. -} - -void HandlerOptionsHandler::RemoveIgnoredHandler(const base::ListValue* args) { - const base::ListValue* list; - if (!args->GetList(0, &list)) { - NOTREACHED(); - return; - } - - ProtocolHandler handler(ParseHandlerFromArgs(list)); - GetProtocolHandlerRegistry()->RemoveIgnoredHandler(handler); -} - -void HandlerOptionsHandler::SetHandlersEnabled(const base::ListValue* args) { - bool enabled = true; - CHECK(args->GetBoolean(0, &enabled)); - if (enabled) - GetProtocolHandlerRegistry()->Enable(); - else - GetProtocolHandlerRegistry()->Disable(); -} - -void HandlerOptionsHandler::ClearDefault(const base::ListValue* args) { - const base::Value* value; - CHECK(args->Get(0, &value)); - std::string protocol_to_clear; - CHECK(value->GetAsString(&protocol_to_clear)); - GetProtocolHandlerRegistry()->ClearDefault(protocol_to_clear); -} - -void HandlerOptionsHandler::SetDefault(const base::ListValue* args) { - const base::ListValue* list; - CHECK(args->GetList(0, &list)); - const ProtocolHandler& handler(ParseHandlerFromArgs(list)); - CHECK(!handler.IsEmpty()); - GetProtocolHandlerRegistry()->OnAcceptRegisterProtocolHandler(handler); -} - -ProtocolHandler HandlerOptionsHandler::ParseHandlerFromArgs( - const base::ListValue* args) const { - base::string16 protocol; - base::string16 url; - bool ok = args->GetString(0, &protocol) && args->GetString(1, &url); - if (!ok) - return ProtocolHandler::EmptyProtocolHandler(); - return ProtocolHandler::CreateProtocolHandler(base::UTF16ToUTF8(protocol), - GURL(base::UTF16ToUTF8(url))); -} - -void HandlerOptionsHandler::Observe( - int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) { - DCHECK_EQ(chrome::NOTIFICATION_PROTOCOL_HANDLER_REGISTRY_CHANGED, type); - UpdateHandlerList(); -} - -} // namespace options
diff --git a/chrome/browser/ui/webui/options/handler_options_handler.h b/chrome/browser/ui/webui/options/handler_options_handler.h deleted file mode 100644 index f1b49ac..0000000 --- a/chrome/browser/ui/webui/options/handler_options_handler.h +++ /dev/null
@@ -1,90 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_WEBUI_OPTIONS_HANDLER_OPTIONS_HANDLER_H_ -#define CHROME_BROWSER_UI_WEBUI_OPTIONS_HANDLER_OPTIONS_HANDLER_H_ - -#include <string> - -#include "base/macros.h" -#include "chrome/browser/custom_handlers/protocol_handler_registry.h" -#include "chrome/browser/ui/webui/options/options_ui.h" -#include "chrome/common/custom_handlers/protocol_handler.h" -#include "content/public/browser/notification_observer.h" -#include "content/public/browser/notification_registrar.h" - -//////////////////////////////////////////////////////////////////////////////// -// HandlerOptionsHandler - -// Listen for changes to protocol handlers (i.e. registerProtocolHandler()). -// This get triggered whenever a user allows a specific website or application -// to handle clicks on a link with a specified protocol (i.e. mailto: -> Gmail). - -namespace base { -class DictionaryValue; -} - -namespace options { - -class HandlerOptionsHandler : public OptionsPageUIHandler, - public content::NotificationObserver { - public: - HandlerOptionsHandler(); - ~HandlerOptionsHandler() override; - - // OptionsPageUIHandler implementation. - void GetLocalizedValues(base::DictionaryValue* localized_strings) override; - void InitializeHandler() override; - void InitializePage() override; - void RegisterMessages() override; - - // content::NotificationObserver implementation. - void Observe(int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) override; - - private: - // Called when the user toggles whether custom handlers are enabled. - void SetHandlersEnabled(const base::ListValue* args); - - // Called when the user sets a new default handler for a protocol. - void SetDefault(const base::ListValue* args); - - // Called when the user clears the default handler for a protocol. - // |args| is the string name of the protocol to clear. - void ClearDefault(const base::ListValue* args); - - // Parses a ProtocolHandler out of the arguments passed back from the view. - // |args| is a list of [protocol, url, title]. - ProtocolHandler ParseHandlerFromArgs(const base::ListValue* args) const; - - // Returns a JSON object describing the set of protocol handlers for the - // given protocol. - void GetHandlersForProtocol(const std::string& protocol, - base::DictionaryValue* value); - - // Returns a JSON list of the ignored protocol handlers. - void GetIgnoredHandlers(base::ListValue* handlers); - - // Called when the JS PasswordManager object is initialized. - void UpdateHandlerList(); - - // Remove a handler. - // |args| is a list of [protocol, url, title]. - void RemoveHandler(const base::ListValue* args); - - // Remove an ignored handler. - // |args| is a list of [protocol, url, title]. - void RemoveIgnoredHandler(const base::ListValue* args); - - ProtocolHandlerRegistry* GetProtocolHandlerRegistry(); - - content::NotificationRegistrar notification_registrar_; - - DISALLOW_COPY_AND_ASSIGN(HandlerOptionsHandler); -}; - -} // namespace options - -#endif // CHROME_BROWSER_UI_WEBUI_OPTIONS_HANDLER_OPTIONS_HANDLER_H_
diff --git a/chrome/browser/ui/webui/options/help_overlay_handler.cc b/chrome/browser/ui/webui/options/help_overlay_handler.cc deleted file mode 100644 index 6151769..0000000 --- a/chrome/browser/ui/webui/options/help_overlay_handler.cc +++ /dev/null
@@ -1,35 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/webui/options/help_overlay_handler.h" - -#include "base/memory/ptr_util.h" -#include "base/values.h" -#include "chrome/browser/ui/webui/help/help_handler.h" -#include "chrome/grit/generated_resources.h" -#include "content/public/browser/web_ui.h" - -namespace options { - -HelpOverlayHandler::HelpOverlayHandler() { -} - -HelpOverlayHandler::~HelpOverlayHandler() { -} - -void HelpOverlayHandler::GetLocalizedValues( - base::DictionaryValue* localized_strings) { -#if defined(OS_CHROMEOS) - RegisterTitle(localized_strings, "aboutOverlay", IDS_ABOUT_TITLE); -#endif - HelpHandler::GetLocalizedValues(localized_strings); -} - -void HelpOverlayHandler::RegisterMessages() { -#if defined(OS_CHROMEOS) - web_ui()->AddMessageHandler(base::MakeUnique<HelpHandler>()); -#endif -} - -} // namespace options
diff --git a/chrome/browser/ui/webui/options/help_overlay_handler.h b/chrome/browser/ui/webui/options/help_overlay_handler.h deleted file mode 100644 index 08b9973..0000000 --- a/chrome/browser/ui/webui/options/help_overlay_handler.h +++ /dev/null
@@ -1,32 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_WEBUI_OPTIONS_HELP_OVERLAY_HANDLER_H_ -#define CHROME_BROWSER_UI_WEBUI_OPTIONS_HELP_OVERLAY_HANDLER_H_ - -#include "base/macros.h" -#include "chrome/browser/ui/webui/options/options_ui.h" - -namespace options { - -// Help UI page handler to support About in Settings when using Settings in a -// window. Defers to ::HelpHandler. -class HelpOverlayHandler : public ::options::OptionsPageUIHandler { - public: - HelpOverlayHandler(); - ~HelpOverlayHandler() override; - - // OptionsPageUIHandler implementation. - void GetLocalizedValues(base::DictionaryValue* localized_strings) override; - - // WebUIMessageHandler implementation. - void RegisterMessages() override; - - private: - DISALLOW_COPY_AND_ASSIGN(HelpOverlayHandler); -}; - -} // namespace options - -#endif // CHROME_BROWSER_UI_WEBUI_OPTIONS_HELP_OVERLAY_HANDLER_H_
diff --git a/chrome/browser/ui/webui/options/home_page_overlay_handler.cc b/chrome/browser/ui/webui/options/home_page_overlay_handler.cc deleted file mode 100644 index e062ed3..0000000 --- a/chrome/browser/ui/webui/options/home_page_overlay_handler.cc +++ /dev/null
@@ -1,71 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/webui/options/home_page_overlay_handler.h" - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/memory/ptr_util.h" -#include "base/values.h" -#include "chrome/browser/autocomplete/chrome_autocomplete_provider_client.h" -#include "chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/search_engines/template_url_service_factory.h" -#include "chrome/grit/generated_resources.h" -#include "components/metrics/proto/omnibox_event.pb.h" -#include "components/omnibox/browser/autocomplete_classifier.h" -#include "components/omnibox/browser/autocomplete_controller.h" -#include "components/omnibox/browser/autocomplete_input.h" -#include "components/omnibox/browser/autocomplete_result.h" -#include "content/public/browser/web_ui.h" - -namespace options { - -HomePageOverlayHandler::HomePageOverlayHandler() { -} - -HomePageOverlayHandler::~HomePageOverlayHandler() { -} - -void HomePageOverlayHandler::RegisterMessages() { - web_ui()->RegisterMessageCallback( - "requestAutocompleteSuggestionsForHomePage", - base::Bind(&HomePageOverlayHandler::RequestAutocompleteSuggestions, - base::Unretained(this))); -} - -void HomePageOverlayHandler::InitializeHandler() { - Profile* profile = Profile::FromWebUI(web_ui()); - autocomplete_controller_.reset(new AutocompleteController( - base::MakeUnique<ChromeAutocompleteProviderClient>(profile), this, - AutocompleteClassifier::DefaultOmniboxProviders())); -} - -void HomePageOverlayHandler::GetLocalizedValues( - base::DictionaryValue* localized_strings) { - RegisterTitle(localized_strings, "homePageOverlay", - IDS_OPTIONS_HOMEPAGE_TITLE); -} - -void HomePageOverlayHandler::RequestAutocompleteSuggestions( - const base::ListValue* args) { - base::string16 input; - CHECK_EQ(args->GetSize(), 1U); - CHECK(args->GetString(0, &input)); - - autocomplete_controller_->Start(AutocompleteInput( - input, base::string16::npos, std::string(), GURL(), base::string16(), - metrics::OmniboxEventProto::INVALID_SPEC, true, false, false, true, false, - ChromeAutocompleteSchemeClassifier(Profile::FromWebUI(web_ui())))); -} - -void HomePageOverlayHandler::OnResultChanged(bool default_match_changed) { - const AutocompleteResult& result = autocomplete_controller_->result(); - base::ListValue suggestions; - OptionsUI::ProcessAutocompleteSuggestions(result, &suggestions); - web_ui()->CallJavascriptFunctionUnsafe( - "HomePageOverlay.updateAutocompleteSuggestions", suggestions); -} - -} // namespace options
diff --git a/chrome/browser/ui/webui/options/home_page_overlay_handler.h b/chrome/browser/ui/webui/options/home_page_overlay_handler.h deleted file mode 100644 index 852e3f97..0000000 --- a/chrome/browser/ui/webui/options/home_page_overlay_handler.h +++ /dev/null
@@ -1,48 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_WEBUI_OPTIONS_HOME_PAGE_OVERLAY_HANDLER_H_ -#define CHROME_BROWSER_UI_WEBUI_OPTIONS_HOME_PAGE_OVERLAY_HANDLER_H_ - -#include <memory> - -#include "base/compiler_specific.h" -#include "base/macros.h" -#include "chrome/browser/ui/webui/options/options_ui.h" -#include "components/omnibox/browser/autocomplete_controller_delegate.h" - -class AutocompleteController; - -namespace base { -class DictionaryValue; -class ListValue; -} - -namespace options { - -class HomePageOverlayHandler : public OptionsPageUIHandler, - public AutocompleteControllerDelegate { - public: - HomePageOverlayHandler(); - ~HomePageOverlayHandler() override; - - // OptionsPageUIHandler implementation - void GetLocalizedValues(base::DictionaryValue*) override; - void InitializeHandler() override; - void RegisterMessages() override; - - // AutocompleteControllerDelegate implementation. - void OnResultChanged(bool default_match_changed) override; - - private: - void RequestAutocompleteSuggestions(const base::ListValue* args); - - std::unique_ptr<AutocompleteController> autocomplete_controller_; - - DISALLOW_COPY_AND_ASSIGN(HomePageOverlayHandler); -}; - -} // namespace options - -#endif // CHROME_BROWSER_UI_WEBUI_OPTIONS_HOME_PAGE_OVERLAY_HANDLER_H_
diff --git a/chrome/browser/ui/webui/options/import_data_handler.cc b/chrome/browser/ui/webui/options/import_data_handler.cc deleted file mode 100644 index 0b49c98..0000000 --- a/chrome/browser/ui/webui/options/import_data_handler.cc +++ /dev/null
@@ -1,272 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/webui/options/import_data_handler.h" - -#include <stddef.h> - -#include <string> -#include <utility> - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/macros.h" -#include "base/strings/string16.h" -#include "base/strings/string_number_conversions.h" -#include "base/strings/string_util.h" -#include "base/strings/utf_string_conversions.h" -#include "base/threading/thread_restrictions.h" -#include "base/values.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/importer/external_process_importer_host.h" -#include "chrome/browser/importer/importer_list.h" -#include "chrome/browser/importer/importer_uma.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/browser_finder.h" -#include "chrome/browser/ui/browser_window.h" -#include "chrome/browser/ui/chrome_select_file_policy.h" -#include "chrome/grit/chromium_strings.h" -#include "chrome/grit/generated_resources.h" -#include "content/public/browser/browser_thread.h" -#include "content/public/browser/web_ui.h" - -using content::BrowserThread; - -namespace options { - -ImportDataHandler::ImportDataHandler() - : importer_host_(NULL), - import_did_succeed_(false) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); -} - -ImportDataHandler::~ImportDataHandler() { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - - if (importer_host_) - importer_host_->set_observer(NULL); - - if (select_file_dialog_.get()) - select_file_dialog_->ListenerDestroyed(); -} - -void ImportDataHandler::GetLocalizedValues( - base::DictionaryValue* localized_strings) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - DCHECK(localized_strings); - - static OptionsStringResource resources[] = { - {"importFromLabel", IDS_IMPORT_FROM_LABEL}, - {"importLoading", IDS_IMPORT_LOADING_PROFILES}, - {"importDescription", IDS_IMPORT_ITEMS_LABEL}, - {"importHistory", IDS_IMPORT_HISTORY_CHKBOX}, - {"importFavorites", IDS_IMPORT_FAVORITES_CHKBOX}, - {"importSearch", IDS_IMPORT_SEARCH_ENGINES_CHKBOX}, - {"importPasswords", IDS_IMPORT_PASSWORDS_CHKBOX}, - {"importAutofillFormData", IDS_IMPORT_AUTOFILL_FORM_DATA_CHKBOX}, - {"importChooseFile", IDS_IMPORT_CHOOSE_FILE}, - {"importCommit", IDS_IMPORT_COMMIT}, - {"noProfileFound", IDS_IMPORT_NO_PROFILE_FOUND}, - {"importSucceeded", IDS_IMPORT_SUCCEEDED}, - {"findYourImportedBookmarks", IDS_IMPORT_FIND_YOUR_BOOKMARKS}, - }; - - RegisterStrings(localized_strings, resources, arraysize(resources)); - RegisterTitle(localized_strings, "importDataOverlay", - IDS_IMPORT_SETTINGS_TITLE); -} - -void ImportDataHandler::InitializeHandler() { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - - importer_list_.reset(new ImporterList()); - importer_list_->DetectSourceProfiles( - g_browser_process->GetApplicationLocale(), - true, // include_interactive_profiles? - base::Bind(&ImportDataHandler::InitializePage, base::Unretained(this))); -} - -void ImportDataHandler::RegisterMessages() { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - - web_ui()->RegisterMessageCallback( - "importData", - base::Bind(&ImportDataHandler::ImportData, base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "chooseBookmarksFile", - base::Bind(&ImportDataHandler::HandleChooseBookmarksFile, - base::Unretained(this))); -} - -void ImportDataHandler::StartImport( - const importer::SourceProfile& source_profile, - uint16_t imported_items) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - - if (!imported_items) - return; - - // If another import is already ongoing, let it finish silently. - if (importer_host_) - importer_host_->set_observer(NULL); - - base::Value importing(true); - web_ui()->CallJavascriptFunctionUnsafe("ImportDataOverlay.setImportingState", - importing); - import_did_succeed_ = false; - - importer_host_ = new ExternalProcessImporterHost(); - importer_host_->set_observer(this); - Profile* profile = Profile::FromWebUI(web_ui()); - importer_host_->StartImportSettings(source_profile, profile, - imported_items, - new ProfileWriter(profile)); - - importer::LogImporterUseToMetrics("ImportDataHandler", - source_profile.importer_type); -} - -void ImportDataHandler::ImportData(const base::ListValue* args) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - - std::string string_value; - - int browser_index; - if (!args->GetString(0, &string_value) || - !base::StringToInt(string_value, &browser_index)) { - NOTREACHED(); - return; - } - - uint16_t selected_items = importer::NONE; - if (args->GetString(1, &string_value) && string_value == "true") { - selected_items |= importer::HISTORY; - } - if (args->GetString(2, &string_value) && string_value == "true") { - selected_items |= importer::FAVORITES; - } - if (args->GetString(3, &string_value) && string_value == "true") { - selected_items |= importer::PASSWORDS; - } - if (args->GetString(4, &string_value) && string_value == "true") { - selected_items |= importer::SEARCH_ENGINES; - } - if (args->GetString(5, &string_value) && string_value == "true") { - selected_items |= importer::AUTOFILL_FORM_DATA; - } - - const importer::SourceProfile& source_profile = - importer_list_->GetSourceProfileAt(browser_index); - uint16_t supported_items = source_profile.services_supported; - - uint16_t imported_items = (selected_items & supported_items); - if (imported_items) { - StartImport(source_profile, imported_items); - } else { - LOG(WARNING) << "There were no settings to import from '" - << source_profile.importer_name << "'."; - } -} - -void ImportDataHandler::InitializePage() { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - - base::ListValue browser_profiles; - for (size_t i = 0; i < importer_list_->count(); ++i) { - const importer::SourceProfile& source_profile = - importer_list_->GetSourceProfileAt(i); - uint16_t browser_services = source_profile.services_supported; - - std::unique_ptr<base::DictionaryValue> browser_profile( - new base::DictionaryValue()); - browser_profile->SetString("name", source_profile.importer_name); - browser_profile->SetInteger("index", i); - browser_profile->SetBoolean("history", - (browser_services & importer::HISTORY) != 0); - browser_profile->SetBoolean("favorites", - (browser_services & importer::FAVORITES) != 0); - browser_profile->SetBoolean("passwords", - (browser_services & importer::PASSWORDS) != 0); - browser_profile->SetBoolean("search", - (browser_services & importer::SEARCH_ENGINES) != 0); - browser_profile->SetBoolean("autofill-form-data", - (browser_services & importer::AUTOFILL_FORM_DATA) != 0); - - browser_profiles.Append(std::move(browser_profile)); - } - - web_ui()->CallJavascriptFunctionUnsafe( - "ImportDataOverlay.updateSupportedBrowsers", browser_profiles); -} - -void ImportDataHandler::ImportStarted() { - DCHECK_CURRENTLY_ON(BrowserThread::UI); -} - -void ImportDataHandler::ImportItemStarted(importer::ImportItem item) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - - // TODO(csilv): show progress detail in the web view. -} - -void ImportDataHandler::ImportItemEnded(importer::ImportItem item) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - - // TODO(csilv): show progress detail in the web view. - import_did_succeed_ = true; -} - -void ImportDataHandler::ImportEnded() { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - - importer_host_->set_observer(NULL); - importer_host_ = NULL; - - if (import_did_succeed_) { - web_ui()->CallJavascriptFunctionUnsafe("ImportDataOverlay.confirmSuccess"); - } else { - base::Value state(false); - web_ui()->CallJavascriptFunctionUnsafe( - "ImportDataOverlay.setImportingState", state); - web_ui()->CallJavascriptFunctionUnsafe("ImportDataOverlay.dismiss"); - } -} - -void ImportDataHandler::FileSelected(const base::FilePath& path, - int /*index*/, - void* /*params*/) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - - importer::SourceProfile source_profile; - source_profile.importer_type = importer::TYPE_BOOKMARKS_FILE; - source_profile.source_path = path; - - StartImport(source_profile, importer::FAVORITES); -} - -void ImportDataHandler::HandleChooseBookmarksFile(const base::ListValue* args) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - - DCHECK(args && args->empty()); - select_file_dialog_ = ui::SelectFileDialog::Create( - this, new ChromeSelectFilePolicy(web_ui()->GetWebContents())); - - ui::SelectFileDialog::FileTypeInfo file_type_info; - file_type_info.extensions.resize(1); - file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("html")); - - Browser* browser = - chrome::FindBrowserWithWebContents(web_ui()->GetWebContents()); - - select_file_dialog_->SelectFile(ui::SelectFileDialog::SELECT_OPEN_FILE, - base::string16(), - base::FilePath(), - &file_type_info, - 0, - base::FilePath::StringType(), - browser->window()->GetNativeWindow(), - NULL); -} - -} // namespace options
diff --git a/chrome/browser/ui/webui/options/import_data_handler.h b/chrome/browser/ui/webui/options/import_data_handler.h deleted file mode 100644 index 32bea2b..0000000 --- a/chrome/browser/ui/webui/options/import_data_handler.h +++ /dev/null
@@ -1,75 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_WEBUI_OPTIONS_IMPORT_DATA_HANDLER_H_ -#define CHROME_BROWSER_UI_WEBUI_OPTIONS_IMPORT_DATA_HANDLER_H_ - -#include <stdint.h> - -#include <memory> - -#include "base/compiler_specific.h" -#include "base/macros.h" -#include "chrome/browser/importer/importer_progress_observer.h" -#include "chrome/browser/ui/webui/options/options_ui.h" -#include "chrome/common/importer/importer_data_types.h" -#include "ui/shell_dialogs/select_file_dialog.h" - -class ExternalProcessImporterHost; -class ImporterList; - -namespace options { - -// Chrome personal stuff import data overlay UI handler. -class ImportDataHandler : public OptionsPageUIHandler, - public importer::ImporterProgressObserver, - public ui::SelectFileDialog::Listener { - public: - ImportDataHandler(); - ~ImportDataHandler() override; - - // OptionsPageUIHandler: - void GetLocalizedValues(base::DictionaryValue* localized_strings) override; - void InitializeHandler() override; - void InitializePage() override; - - // content::WebUIMessageHandler: - void RegisterMessages() override; - - private: - void StartImport(const importer::SourceProfile& source_profile, - uint16_t imported_items); - - void ImportData(const base::ListValue* args); - - // importer::ImporterProgressObserver: - void ImportStarted() override; - void ImportItemStarted(importer::ImportItem item) override; - void ImportItemEnded(importer::ImportItem item) override; - void ImportEnded() override; - - // ui::SelectFileDialog::Listener: - void FileSelected(const base::FilePath& path, - int index, - void* params) override; - - // Opens a file selection dialog to choose the bookmarks HTML file. - void HandleChooseBookmarksFile(const base::ListValue* args); - - std::unique_ptr<ImporterList> importer_list_; - - // If non-null it means importing is in progress. ImporterHost takes care - // of deleting itself when import is complete. - ExternalProcessImporterHost* importer_host_; // weak - - bool import_did_succeed_; - - scoped_refptr<ui::SelectFileDialog> select_file_dialog_; - - DISALLOW_COPY_AND_ASSIGN(ImportDataHandler); -}; - -} // namespace options - -#endif // CHROME_BROWSER_UI_WEBUI_OPTIONS_IMPORT_DATA_HANDLER_H_
diff --git a/chrome/browser/ui/webui/options/language_dictionary_overlay_handler.cc b/chrome/browser/ui/webui/options/language_dictionary_overlay_handler.cc deleted file mode 100644 index 247383ef..0000000 --- a/chrome/browser/ui/webui/options/language_dictionary_overlay_handler.cc +++ /dev/null
@@ -1,134 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/webui/options/language_dictionary_overlay_handler.h" - -#include <string> - -#include "base/bind.h" -#include "base/logging.h" -#include "base/values.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/spellchecker/spellcheck_factory.h" -#include "chrome/browser/spellchecker/spellcheck_service.h" -#include "chrome/grit/generated_resources.h" -#include "content/public/browser/web_ui.h" -#include "ui/base/l10n/l10n_util.h" - -namespace options { - -LanguageDictionaryOverlayHandler::LanguageDictionaryOverlayHandler() - : overlay_initialized_(false), - dictionary_(NULL) { -} - -LanguageDictionaryOverlayHandler::~LanguageDictionaryOverlayHandler() { -} - -void LanguageDictionaryOverlayHandler::GetLocalizedValues( - base::DictionaryValue* localized_strings) { - RegisterTitle(localized_strings, - "languageDictionaryOverlayPage", - IDS_LANGUAGE_DICTIONARY_OVERLAY_TITLE); - localized_strings->SetString( - "languageDictionaryOverlayTitle", - l10n_util::GetStringUTF16(IDS_LANGUAGE_DICTIONARY_OVERLAY_TITLE)); - localized_strings->SetString( - "languageDictionaryOverlayAddWordLabel", - l10n_util::GetStringUTF16( - IDS_LANGUAGE_DICTIONARY_OVERLAY_ADD_WORD_LABEL)); - localized_strings->SetString( - "languageDictionaryOverlaySearchPlaceholder", - l10n_util::GetStringUTF16( - IDS_LANGUAGE_DICTIONARY_OVERLAY_SEARCH_PLACEHOLDER)); - localized_strings->SetString( - "languageDictionaryOverlayNoMatches", - l10n_util::GetStringUTF16(IDS_LANGUAGE_DICTIONARY_OVERLAY_NO_MATCHES)); -} - -void LanguageDictionaryOverlayHandler::RegisterMessages() { - web_ui()->RegisterMessageCallback( - "addDictionaryWord", - base::Bind(&LanguageDictionaryOverlayHandler::AddWord, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "removeDictionaryWord", - base::Bind(&LanguageDictionaryOverlayHandler::RemoveWord, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "refreshDictionaryWords", - base::Bind(&LanguageDictionaryOverlayHandler::RefreshWords, - base::Unretained(this))); -} - -void LanguageDictionaryOverlayHandler::Uninitialize() { - overlay_initialized_ = false; - if (dictionary_) - dictionary_->RemoveObserver(this); -} - -void LanguageDictionaryOverlayHandler::OnCustomDictionaryLoaded() { - ResetDictionaryWords(); -} - -void LanguageDictionaryOverlayHandler::OnCustomDictionaryChanged( - const SpellcheckCustomDictionary::Change& dictionary_change) { - base::ListValue add_words; - for (const std::string& word : dictionary_change.to_add()) { - add_words.AppendString(word); - } - - base::ListValue remove_words; - for (const std::string& word : dictionary_change.to_remove()) { - remove_words.AppendString(word); - } - - web_ui()->CallJavascriptFunctionUnsafe("EditDictionaryOverlay.updateWords", - add_words, remove_words); -} - -void LanguageDictionaryOverlayHandler::ResetDictionaryWords() { - if (!overlay_initialized_) - return; - - if (!dictionary_) { - SpellcheckService* service = SpellcheckServiceFactory::GetForContext( - Profile::FromWebUI(web_ui())); - dictionary_ = service->GetCustomDictionary(); - dictionary_->AddObserver(this); - } - - base::ListValue list_value; - for (const std::string& word : dictionary_->GetWords()) { - list_value.AppendString(word); - } - web_ui()->CallJavascriptFunctionUnsafe("EditDictionaryOverlay.setWordList", - list_value); -} - -void LanguageDictionaryOverlayHandler::RefreshWords( - const base::ListValue* args) { - overlay_initialized_ = true; - ResetDictionaryWords(); -} - -void LanguageDictionaryOverlayHandler::AddWord(const base::ListValue* args) { - std::string new_word; - if (!args->GetString(0, &new_word) || new_word.empty() || !dictionary_) { - NOTREACHED(); - return; - } - dictionary_->AddWord(new_word); -} - -void LanguageDictionaryOverlayHandler::RemoveWord(const base::ListValue* args) { - std::string old_word; - if (!args->GetString(0, &old_word) || old_word.empty() || !dictionary_) { - NOTREACHED(); - return; - } - dictionary_->RemoveWord(old_word); -} - -} // namespace options
diff --git a/chrome/browser/ui/webui/options/language_dictionary_overlay_handler.h b/chrome/browser/ui/webui/options/language_dictionary_overlay_handler.h deleted file mode 100644 index 742272f3..0000000 --- a/chrome/browser/ui/webui/options/language_dictionary_overlay_handler.h +++ /dev/null
@@ -1,61 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_WEBUI_OPTIONS_LANGUAGE_DICTIONARY_OVERLAY_HANDLER_H_ -#define CHROME_BROWSER_UI_WEBUI_OPTIONS_LANGUAGE_DICTIONARY_OVERLAY_HANDLER_H_ - -#include "base/macros.h" -#include "chrome/browser/spellchecker/spellcheck_custom_dictionary.h" -#include "chrome/browser/ui/webui/options/options_ui.h" - -namespace base { -class DictionaryValue; -class ListValue; -} - -namespace options { - -class LanguageDictionaryOverlayHandler - : public OptionsPageUIHandler, - public SpellcheckCustomDictionary::Observer { - public: - LanguageDictionaryOverlayHandler(); - ~LanguageDictionaryOverlayHandler() override; - - // Overridden from OptionsPageUIHandler: - void GetLocalizedValues(base::DictionaryValue* localized_strings) override; - void RegisterMessages() override; - void Uninitialize() override; - - // Overridden from SpellcheckCustomDictionary::Observer: - void OnCustomDictionaryLoaded() override; - void OnCustomDictionaryChanged( - const SpellcheckCustomDictionary::Change& dictionary_change) override; - - private: - // Sends the dictionary words to WebUI. - void ResetDictionaryWords(); - - // Refreshes the displayed words. Called from WebUI. - void RefreshWords(const base::ListValue* args); - - // Adds a new word to the dictionary. Called from WebUI. - void AddWord(const base::ListValue* args); - - // Removes a word from the dictionary. Called from WebUI. - void RemoveWord(const base::ListValue* args); - - // Whether the overlay is initialized and ready to show data. - bool overlay_initialized_; - - // The custom spelling dictionary. Used for adding, removing, and reading - // words in custom dictionary file. - SpellcheckCustomDictionary* dictionary_; - - DISALLOW_COPY_AND_ASSIGN(LanguageDictionaryOverlayHandler); -}; - -} // namespace options - -#endif // CHROME_BROWSER_UI_WEBUI_OPTIONS_LANGUAGE_DICTIONARY_OVERLAY_HANDLER_H_
diff --git a/chrome/browser/ui/webui/options/language_options_handler.cc b/chrome/browser/ui/webui/options/language_options_handler.cc deleted file mode 100644 index 15491927..0000000 --- a/chrome/browser/ui/webui/options/language_options_handler.cc +++ /dev/null
@@ -1,131 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/webui/options/language_options_handler.h" - -#include <stddef.h> - -#include <map> -#include <memory> -#include <string> -#include <utility> -#include <vector> - -#include "base/bind.h" -#include "base/command_line.h" -#include "base/i18n/rtl.h" -#include "base/memory/ptr_util.h" -#include "base/metrics/user_metrics.h" -#include "base/strings/utf_string_conversions.h" -#include "base/values.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/lifetime/application_lifetime.h" -#include "chrome/common/chrome_switches.h" -#include "chrome/common/pref_names.h" -#include "chrome/grit/generated_resources.h" -#include "components/prefs/pref_service.h" -#include "content/public/browser/web_ui.h" -#include "ui/base/l10n/l10n_util.h" - -using base::UserMetricsAction; - -namespace options { - -LanguageOptionsHandler::LanguageOptionsHandler() { -} - -LanguageOptionsHandler::~LanguageOptionsHandler() { -} - -void LanguageOptionsHandler::GetLocalizedValues( - base::DictionaryValue* localized_strings) { - LanguageOptionsHandlerCommon::GetLocalizedValues(localized_strings); - - RegisterTitle(localized_strings, "languagePage", - IDS_OPTIONS_SETTINGS_LANGUAGES_DIALOG_TITLE); - localized_strings->SetString("restart_button", - l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_LANGUAGES_RELAUNCH_BUTTON)); - localized_strings->Set("languageList", GetLanguageList()); -} - -void LanguageOptionsHandler::RegisterMessages() { - LanguageOptionsHandlerCommon::RegisterMessages(); - - web_ui()->RegisterMessageCallback("uiLanguageRestart", - base::Bind(&LanguageOptionsHandler::RestartCallback, - base::Unretained(this))); -} - -std::unique_ptr<base::ListValue> LanguageOptionsHandler::GetLanguageList() { - // Collect the language codes from the supported accept-languages. - const std::string app_locale = g_browser_process->GetApplicationLocale(); - std::vector<std::string> language_codes; - l10n_util::GetAcceptLanguagesForLocale(app_locale, &language_codes); - - // Map of display name -> {language code, native_display_name}. - // In theory, we should be able to create a map that is sorted by - // display names using ICU comparator, but doing it is hard, thus we'll - // use an auxiliary vector to achieve the same result. - typedef std::pair<std::string, base::string16> LanguagePair; - typedef std::map<base::string16, LanguagePair> LanguageMap; - LanguageMap language_map; - // The auxiliary vector mentioned above. - std::vector<base::string16> display_names; - - // Build the list of display names, and build the language map. - for (size_t i = 0; i < language_codes.size(); ++i) { - base::string16 display_name = - l10n_util::GetDisplayNameForLocale(language_codes[i], app_locale, - false); - base::string16 native_display_name = - l10n_util::GetDisplayNameForLocale(language_codes[i], language_codes[i], - false); - display_names.push_back(display_name); - language_map[display_name] = - std::make_pair(language_codes[i], native_display_name); - } - DCHECK_EQ(display_names.size(), language_map.size()); - - // Sort display names using locale specific sorter. - l10n_util::SortStrings16(app_locale, &display_names); - - // Build the language list from the language map. - auto language_list = base::MakeUnique<base::ListValue>(); - for (size_t i = 0; i < display_names.size(); ++i) { - base::string16& display_name = display_names[i]; - base::string16 adjusted_display_name(display_name); - base::i18n::AdjustStringForLocaleDirection(&adjusted_display_name); - - const LanguagePair& pair = language_map[display_name]; - base::string16 adjusted_native_display_name(pair.second); - base::i18n::AdjustStringForLocaleDirection(&adjusted_native_display_name); - - bool has_rtl_chars = base::i18n::StringContainsStrongRTLChars(display_name); - std::string directionality = has_rtl_chars ? "rtl" : "ltr"; - - std::unique_ptr<base::DictionaryValue> dictionary( - new base::DictionaryValue()); - dictionary->SetString("code", pair.first); - dictionary->SetString("displayName", adjusted_display_name); - dictionary->SetString("textDirection", directionality); - dictionary->SetString("nativeDisplayName", adjusted_native_display_name); - language_list->Append(std::move(dictionary)); - } - - return language_list; -} - -void LanguageOptionsHandler::SetApplicationLocale( - const std::string& language_code) { - PrefService* pref_service = g_browser_process->local_state(); - pref_service->SetString(prefs::kApplicationLocale, language_code); -} - -void LanguageOptionsHandler::RestartCallback(const base::ListValue* args) { - base::RecordAction(UserMetricsAction("LanguageOptions_Restart")); - chrome::AttemptRestart(); -} - -} // namespace options
diff --git a/chrome/browser/ui/webui/options/language_options_handler.h b/chrome/browser/ui/webui/options/language_options_handler.h deleted file mode 100644 index 93943cd..0000000 --- a/chrome/browser/ui/webui/options/language_options_handler.h +++ /dev/null
@@ -1,52 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_WEBUI_OPTIONS_LANGUAGE_OPTIONS_HANDLER_H_ -#define CHROME_BROWSER_UI_WEBUI_OPTIONS_LANGUAGE_OPTIONS_HANDLER_H_ - -#include <memory> - -#include "base/macros.h" -#include "chrome/browser/ui/webui/options/language_options_handler_common.h" - -namespace base { -class ListValue; -} - -namespace options { - -// Language options UI page handler for non-Chrome OS platforms. For Chrome OS, -// see chromeos::CrosLanguageOptionsHandler. -class LanguageOptionsHandler : public LanguageOptionsHandlerCommon { - public: - LanguageOptionsHandler(); - ~LanguageOptionsHandler() override; - - // OptionsPageUIHandler implementation. - void GetLocalizedValues(base::DictionaryValue* localized_strings) override; - - // WebUIMessageHandler implementation. - void RegisterMessages() override; - - // The following static method is public for ease of testing. - - // Gets the list of languages from the given input descriptors. - // The return value will look like: - // [{'code': 'fi', 'displayName': 'Finnish', 'nativeDisplayName': 'suomi'}, - // ...] - static std::unique_ptr<base::ListValue> GetLanguageList(); - - private: - // LanguageOptionsHandlerCommon implementation. - void SetApplicationLocale(const std::string& language_code) override; - - // Called when the restart button is clicked. - void RestartCallback(const base::ListValue* args); - - DISALLOW_COPY_AND_ASSIGN(LanguageOptionsHandler); -}; - -} // namespace options - -#endif // CHROME_BROWSER_UI_WEBUI_OPTIONS_LANGUAGE_OPTIONS_HANDLER_H_
diff --git a/chrome/browser/ui/webui/options/language_options_handler_common.cc b/chrome/browser/ui/webui/options/language_options_handler_common.cc deleted file mode 100644 index fd127384..0000000 --- a/chrome/browser/ui/webui/options/language_options_handler_common.cc +++ /dev/null
@@ -1,302 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/webui/options/language_options_handler_common.h" - -#include <stddef.h> - -#include <map> -#include <string> -#include <utility> -#include <vector> - -#include "base/bind.h" -#include "base/command_line.h" -#include "base/macros.h" -#include "base/memory/ptr_util.h" -#include "base/metrics/user_metrics.h" -#include "base/strings/string_util.h" -#include "base/strings/stringprintf.h" -#include "base/strings/utf_string_conversions.h" -#include "base/values.h" -#include "build/build_config.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/spellchecker/spellcheck_factory.h" -#include "chrome/browser/spellchecker/spellcheck_service.h" -#include "chrome/browser/translate/chrome_translate_client.h" -#include "chrome/browser/translate/translate_service.h" -#include "chrome/browser/ui/browser_list.h" -#include "chrome/common/chrome_switches.h" -#include "chrome/common/pref_names.h" -#include "chrome/grit/chromium_strings.h" -#include "chrome/grit/generated_resources.h" -#include "components/prefs/pref_service.h" -#include "components/spellcheck/common/spellcheck_common.h" -#include "components/translate/core/browser/translate_download_manager.h" -#include "components/translate/core/browser/translate_prefs.h" -#include "content/public/browser/web_ui.h" -#include "ui/base/l10n/l10n_util.h" - -using base::UserMetricsAction; - -namespace options { - -LanguageOptionsHandlerCommon::LanguageOptionsHandlerCommon() { -} - -LanguageOptionsHandlerCommon::~LanguageOptionsHandlerCommon() { -} - -void LanguageOptionsHandlerCommon::GetLocalizedValues( - base::DictionaryValue* localized_strings) { - DCHECK(localized_strings); - -#if defined(OS_CHROMEOS) - const int product_id = IDS_PRODUCT_OS_NAME; -#else - const int product_id = IDS_PRODUCT_NAME; -#endif - - static OptionsStringResource resources[] = { - { "addButton", IDS_OPTIONS_SETTINGS_LANGUAGES_ADD_BUTTON }, - { "languages", IDS_OPTIONS_SETTINGS_LANGUAGES_LANGUAGES }, - { "addLanguageInstructions", - IDS_OPTIONS_SETTINGS_LANGUAGES_ADD_LANGUAGE_INSTRUCTIONS }, - { "cannotBeDisplayedInThisLanguage", - IDS_OPTIONS_SETTINGS_LANGUAGES_CANNOT_BE_DISPLAYED_IN_THIS_LANGUAGE, - product_id }, - { "isDisplayedInThisLanguage", - IDS_OPTIONS_SETTINGS_LANGUAGES_IS_DISPLAYED_IN_THIS_LANGUAGE, - product_id }, - { "displayInThisLanguage", - IDS_OPTIONS_SETTINGS_LANGUAGES_DISPLAY_IN_THIS_LANGUAGE, - product_id }, - { "restartRequired", IDS_OPTIONS_RELAUNCH_REQUIRED }, - // OS X uses the OS native spellchecker so no need for these strings. -#if !defined(OS_MACOSX) - { "useThisForSpellChecking", - IDS_OPTIONS_SETTINGS_USE_THIS_FOR_SPELL_CHECKING }, - { "cannotBeUsedForSpellChecking", - IDS_OPTIONS_SETTINGS_CANNOT_BE_USED_FOR_SPELL_CHECKING }, - { "enableSpellCheck", IDS_OPTIONS_ENABLE_SPELLCHECK }, - { "downloadingDictionary", IDS_OPTIONS_DICTIONARY_DOWNLOADING }, - { "downloadFailed", IDS_OPTIONS_DICTIONARY_DOWNLOAD_FAILED }, - { "retryButton", IDS_OPTIONS_DICTIONARY_DOWNLOAD_RETRY }, - { "downloadFailHelp", IDS_OPTIONS_DICTIONARY_DOWNLOAD_FAIL_HELP }, -#endif // !OS_MACOSX - { "addLanguageTitle", IDS_OPTIONS_LANGUAGES_ADD_TITLE }, - { "addLanguageSelectLabel", IDS_OPTIONS_LANGUAGES_ADD_SELECT_LABEL }, - { "restartButton", IDS_OPTIONS_SETTINGS_LANGUAGES_RELAUNCH_BUTTON }, - { "offerToTranslateInThisLanguage", - IDS_OPTIONS_LANGUAGES_OFFER_TO_TRANSLATE_IN_THIS_LANGUAGE }, - { "cannotTranslateInThisLanguage", - IDS_OPTIONS_LANGUAGES_CANNOT_TRANSLATE_IN_THIS_LANGUAGE }, - }; - - RegisterStrings(localized_strings, resources, arraysize(resources)); - - // The following are resources, rather than local strings. - std::string application_locale = g_browser_process->GetApplicationLocale(); - localized_strings->SetString("currentUiLanguageCode", application_locale); - std::string prospective_locale = - g_browser_process->local_state()->GetString(prefs::kApplicationLocale); - localized_strings->SetString("prospectiveUiLanguageCode", - !prospective_locale.empty() ? prospective_locale : application_locale); - localized_strings->Set("spellCheckLanguageCodeSet", - GetSpellCheckLanguageCodeSet()); - localized_strings->Set("uiLanguageCodeSet", GetUILanguageCodeSet()); - - Profile* profile = Profile::FromWebUI(web_ui()); - PrefService* prefs = profile->GetPrefs(); - std::string default_target_language = - TranslateService::GetTargetLanguage(prefs); - localized_strings->SetString("defaultTargetLanguage", - default_target_language); - - std::vector<std::string> languages; - translate::TranslateDownloadManager::GetSupportedLanguages(&languages); - - auto languages_list = base::MakeUnique<base::ListValue>(); - for (std::vector<std::string>::iterator it = languages.begin(); - it != languages.end(); ++it) { - languages_list->AppendString(*it); - } - - localized_strings->Set("translateSupportedLanguages", - std::move(languages_list)); -} - -void LanguageOptionsHandlerCommon::Uninitialize() { - SpellcheckService* service = GetSpellcheckService(); - if (!service) - return; - - for (const auto& dict : service->GetHunspellDictionaries()) - dict->RemoveObserver(this); -} - -void LanguageOptionsHandlerCommon::RegisterMessages() { - web_ui()->RegisterMessageCallback("languageOptionsOpen", - base::Bind( - &LanguageOptionsHandlerCommon::LanguageOptionsOpenCallback, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("spellCheckLanguageChange", - base::Bind( - &LanguageOptionsHandlerCommon::SpellCheckLanguageChangeCallback, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("uiLanguageChange", - base::Bind( - &LanguageOptionsHandlerCommon::UiLanguageChangeCallback, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("retryDictionaryDownload", - base::Bind( - &LanguageOptionsHandlerCommon::RetrySpellcheckDictionaryDownload, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("updateLanguageList", - base::Bind( - &LanguageOptionsHandlerCommon::UpdateLanguageListCallback, - base::Unretained(this))); -} - -void LanguageOptionsHandlerCommon::OnHunspellDictionaryInitialized( - const std::string& language) { -} - -void LanguageOptionsHandlerCommon::OnHunspellDictionaryDownloadBegin( - const std::string& language) { - web_ui()->CallJavascriptFunctionUnsafe( - "options.LanguageOptions.onDictionaryDownloadBegin", - base::Value(language)); -} - -void LanguageOptionsHandlerCommon::OnHunspellDictionaryDownloadSuccess( - const std::string& language) { - web_ui()->CallJavascriptFunctionUnsafe( - "options.LanguageOptions.onDictionaryDownloadSuccess", - base::Value(language)); -} - -void LanguageOptionsHandlerCommon::OnHunspellDictionaryDownloadFailure( - const std::string& language) { - web_ui()->CallJavascriptFunctionUnsafe( - "options.LanguageOptions.onDictionaryDownloadFailure", - base::Value(language)); -} - -std::unique_ptr<base::DictionaryValue> -LanguageOptionsHandlerCommon::GetUILanguageCodeSet() { - auto dictionary = base::MakeUnique<base::DictionaryValue>(); - const std::vector<std::string>& available_locales = - l10n_util::GetAvailableLocales(); - for (size_t i = 0; i < available_locales.size(); ++i) - dictionary->SetBoolean(available_locales[i], true); - return dictionary; -} - -std::unique_ptr<base::DictionaryValue> -LanguageOptionsHandlerCommon::GetSpellCheckLanguageCodeSet() { - auto dictionary = base::MakeUnique<base::DictionaryValue>(); - std::vector<std::string> spell_check_languages; - spellcheck::SpellCheckLanguages(&spell_check_languages); - for (size_t i = 0; i < spell_check_languages.size(); ++i) { - dictionary->SetBoolean(spell_check_languages[i], true); - } - return dictionary; -} - -void LanguageOptionsHandlerCommon::LanguageOptionsOpenCallback( - const base::ListValue* args) { - base::RecordAction(UserMetricsAction("LanguageOptions_Open")); - SpellcheckService* service = GetSpellcheckService(); - if (!service) - return; - - for (const auto& dictionary : service->GetHunspellDictionaries()) { - dictionary->RemoveObserver(this); - dictionary->AddObserver(this); - - if (dictionary->IsDownloadInProgress()) - OnHunspellDictionaryDownloadBegin(dictionary->GetLanguage()); - else if (dictionary->IsDownloadFailure()) - OnHunspellDictionaryDownloadFailure(dictionary->GetLanguage()); - else - OnHunspellDictionaryDownloadSuccess(dictionary->GetLanguage()); - } -} - -void LanguageOptionsHandlerCommon::UiLanguageChangeCallback( - const base::ListValue* args) { - const std::string language_code = - base::UTF16ToASCII(ExtractStringValue(args)); - CHECK(!language_code.empty()); - const std::string action = base::StringPrintf( - "LanguageOptions_UiLanguageChange_%s", language_code.c_str()); - base::RecordComputedAction(action); - SetApplicationLocale(language_code); - base::Value language_value(language_code); - web_ui()->CallJavascriptFunctionUnsafe( - "options.LanguageOptions.uiLanguageSaved", language_value); -} - -void LanguageOptionsHandlerCommon::SpellCheckLanguageChangeCallback( - const base::ListValue* args) { - const std::string language_code = - base::UTF16ToASCII(ExtractStringValue(args)); - const std::string action = base::StringPrintf( - "LanguageOptions_SpellCheckLanguageChange_%s", language_code.c_str()); - base::RecordComputedAction(action); - - SpellcheckService* service = GetSpellcheckService(); - if (!service) - return; - - for (const auto& dictionary : service->GetHunspellDictionaries()) { - dictionary->RemoveObserver(this); - dictionary->AddObserver(this); - } -} - -void LanguageOptionsHandlerCommon::UpdateLanguageListCallback( - const base::ListValue* args) { - CHECK_EQ(args->GetSize(), 1u); - const base::ListValue* language_list; - args->GetList(0, &language_list); - DCHECK(language_list); - - std::vector<std::string> languages; - for (base::ListValue::const_iterator it = language_list->begin(); - it != language_list->end(); ++it) { - std::string lang; - it->GetAsString(&lang); - languages.push_back(lang); - } - - Profile* profile = Profile::FromWebUI(web_ui()); - std::unique_ptr<translate::TranslatePrefs> translate_prefs = - ChromeTranslateClient::CreateTranslatePrefs(profile->GetPrefs()); - translate_prefs->UpdateLanguageList(languages); -} - -void LanguageOptionsHandlerCommon::RetrySpellcheckDictionaryDownload( - const base::ListValue* args) { - std::string language = base::UTF16ToUTF8(ExtractStringValue(args)); - SpellcheckService* service = GetSpellcheckService(); - if (!service) - return; - - for (const auto& dictionary : service->GetHunspellDictionaries()) { - if (dictionary->GetLanguage() == language) { - dictionary->RetryDownloadDictionary( - Profile::FromWebUI(web_ui())->GetRequestContext()); - return; - } - } -} - -SpellcheckService* LanguageOptionsHandlerCommon::GetSpellcheckService() { - return SpellcheckServiceFactory::GetForContext(Profile::FromWebUI(web_ui())); -} - -} // namespace options
diff --git a/chrome/browser/ui/webui/options/language_options_handler_common.h b/chrome/browser/ui/webui/options/language_options_handler_common.h deleted file mode 100644 index 18e3355..0000000 --- a/chrome/browser/ui/webui/options/language_options_handler_common.h +++ /dev/null
@@ -1,96 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_WEBUI_OPTIONS_LANGUAGE_OPTIONS_HANDLER_COMMON_H_ -#define CHROME_BROWSER_UI_WEBUI_OPTIONS_LANGUAGE_OPTIONS_HANDLER_COMMON_H_ - -#include <memory> - -#include "base/macros.h" -#include "base/memory/weak_ptr.h" -#include "chrome/browser/spellchecker/spellcheck_hunspell_dictionary.h" -#include "chrome/browser/ui/webui/options/options_ui.h" - -namespace base { -class DictionaryValue; -class ListValue; -} - -namespace options { - -// The base class for language options page UI handlers. This class has code -// common to the Chrome OS and non-Chrome OS implementation of the handler. -class LanguageOptionsHandlerCommon - : public OptionsPageUIHandler, - public SpellcheckHunspellDictionary::Observer { - public: - LanguageOptionsHandlerCommon(); - ~LanguageOptionsHandlerCommon() override; - - // OptionsPageUIHandler implementation. - void GetLocalizedValues(base::DictionaryValue* localized_strings) override; - void Uninitialize() override; - - // DOMMessageHandler implementation. - void RegisterMessages() override; - - // SpellcheckHunspellDictionary::Observer implementation. - void OnHunspellDictionaryInitialized(const std::string& language) override; - void OnHunspellDictionaryDownloadBegin(const std::string& language) override; - void OnHunspellDictionaryDownloadSuccess( - const std::string& language) override; - void OnHunspellDictionaryDownloadFailure( - const std::string& language) override; - - // The following static methods are public for ease of testing. - - // Gets the set of language codes that can be used as UI language. - // The return value will look like: - // {'en-US': true, 'fi': true, 'fr': true, ...} - // - // Note that true in values does not mean anything. We just use the - // dictionary as a set. - static std::unique_ptr<base::DictionaryValue> GetUILanguageCodeSet(); - - // Gets the set of language codes that can be used for spellchecking. - // The return value will look like: - // {'en-US': true, 'fi': true, 'fr': true, ...} - // - // Note that true in values does not mean anything. We just use the - // dictionary as a set. - static std::unique_ptr<base::DictionaryValue> GetSpellCheckLanguageCodeSet(); - - private: - // Sets the application locale. - virtual void SetApplicationLocale(const std::string& language_code) = 0; - - // Called when the language options is opened. - void LanguageOptionsOpenCallback(const base::ListValue* args); - - // Called when the UI language is changed. - // |args| will contain the language code as string (ex. "fr"). - void UiLanguageChangeCallback(const base::ListValue* args); - - // Called when the spell check language is changed. - // |args| will contain the language code as string (ex. "fr"). - void SpellCheckLanguageChangeCallback(const base::ListValue* args); - - // Called when the user clicks "Retry" button for a spellcheck dictionary that - // has failed to download. |args| will contain the language code as a string - // (ex. "fr"). - void RetrySpellcheckDictionaryDownload(const base::ListValue* args); - - // Called when the user saves the language list preferences. - void UpdateLanguageListCallback(const base::ListValue* args); - - // Returns a pointer to the browser SpellcheckService. Can be null if the - // service has already shut down. - SpellcheckService* GetSpellcheckService(); - - DISALLOW_COPY_AND_ASSIGN(LanguageOptionsHandlerCommon); -}; - -} // namespace options - -#endif // CHROME_BROWSER_UI_WEBUI_OPTIONS_LANGUAGE_OPTIONS_HANDLER_COMMON_H_
diff --git a/chrome/browser/ui/webui/options/manage_profile_handler.cc b/chrome/browser/ui/webui/options/manage_profile_handler.cc deleted file mode 100644 index 61f6b8e..0000000 --- a/chrome/browser/ui/webui/options/manage_profile_handler.cc +++ /dev/null
@@ -1,547 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/webui/options/manage_profile_handler.h" - -#include <stddef.h> - -#include <vector> - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/macros.h" -#include "base/strings/string_number_conversions.h" -#include "base/strings/string_util.h" -#include "base/strings/utf_string_conversions.h" -#include "base/value_conversions.h" -#include "base/values.h" -#include "build/build_config.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/chrome_notification_types.h" -#include "chrome/browser/profiles/gaia_info_update_service.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/profiles/profile_attributes_entry.h" -#include "chrome/browser/profiles/profile_avatar_icon_util.h" -#include "chrome/browser/profiles/profile_manager.h" -#include "chrome/browser/profiles/profile_metrics.h" -#include "chrome/browser/profiles/profile_shortcut_manager.h" -#include "chrome/browser/profiles/profile_window.h" -#include "chrome/browser/profiles/profiles_state.h" -#include "chrome/browser/signin/signin_manager_factory.h" -#include "chrome/browser/sync/profile_sync_service_factory.h" -#include "chrome/browser/ui/browser_finder.h" -#include "chrome/common/pref_names.h" -#include "chrome/common/url_constants.h" -#include "chrome/grit/chromium_strings.h" -#include "chrome/grit/generated_resources.h" -#include "components/browser_sync/profile_sync_service.h" -#include "components/prefs/pref_service.h" -#include "components/prefs/scoped_user_pref_update.h" -#include "components/signin/core/browser/signin_manager.h" -#include "components/signin/core/common/profile_management_switches.h" -#include "components/strings/grit/components_strings.h" -#include "content/public/browser/browser_thread.h" -#include "content/public/browser/notification_service.h" -#include "content/public/browser/web_ui.h" -#include "google_apis/gaia/gaia_auth_util.h" -#include "ui/base/l10n/l10n_util.h" -#include "ui/base/webui/web_ui_util.h" - -namespace options { - -namespace { - -const char kCreateProfileIdentifier[] = "create"; -const char kManageProfileIdentifier[] = "manage"; - -// Given |args| from the WebUI, parses value 0 as a FilePath |profile_file_path| -// and returns true on success. -bool GetProfilePathFromArgs(const base::ListValue* args, - base::FilePath* profile_file_path) { - const base::Value* file_path_value; - if (!args->Get(0, &file_path_value)) - return false; - return base::GetValueAsFilePath(*file_path_value, profile_file_path); -} - -void HandleLogDeleteUserDialogShown(const base::ListValue* args) { - ProfileMetrics::LogProfileDeleteUser( - ProfileMetrics::DELETE_PROFILE_SETTINGS_SHOW_WARNING); -} - -} // namespace - -ManageProfileHandler::ManageProfileHandler() - : weak_factory_(this) { -} - -ManageProfileHandler::~ManageProfileHandler() { - browser_sync::ProfileSyncService* service = - ProfileSyncServiceFactory::GetForProfile(Profile::FromWebUI(web_ui())); - // Sync may be disabled in tests. - if (service) - service->RemoveObserver(this); -} - -void ManageProfileHandler::GetLocalizedValues( - base::DictionaryValue* localized_strings) { - DCHECK(localized_strings); - - static OptionsStringResource resources[] = { - { "manageProfilesNameLabel", IDS_PROFILES_MANAGE_NAME_LABEL }, - { "manageProfilesIconLabel", IDS_PROFILES_MANAGE_ICON_LABEL }, - { "manageProfilesExistingSupervisedUser", - IDS_PROFILES_CREATE_LEGACY_SUPERVISED_USER_ERROR_EXISTS_REMOTELY }, - { "managedProfilesExistingLocalSupervisedUser", - IDS_PROFILES_CREATE_LEGACY_SUPERVISED_USER_ERROR_EXISTS_LOCALLY }, - { "manageProfilesSupervisedSignedInLabel", - IDS_PROFILES_CREATE_SUPERVISED_SIGNED_IN_LABEL }, - { "manageProfilesSupervisedNotSignedIn", - IDS_PROFILES_CREATE_SUPERVISED_NOT_SIGNED_IN_HTML }, - { "manageProfilesSupervisedAccountDetailsOutOfDate", - IDS_PROFILES_CREATE_SUPERVISED_ACCOUNT_DETAILS_OUT_OF_DATE_LABEL }, - { "manageProfilesSupervisedSignInAgainLink", - IDS_PROFILES_GAIA_REAUTH_TITLE }, - { "manageProfilesConfirm", IDS_SAVE }, - { "deleteProfileTitle", IDS_PROFILES_DELETE_TITLE }, - { "deleteProfileOK", IDS_PROFILES_DELETE_OK_BUTTON_LABEL }, - { "deleteProfileMessage", IDS_PROFILES_DELETE_MESSAGE }, - { "disconnectManagedProfileTitle", - IDS_PROFILES_DISCONNECT_MANAGED_PROFILE_TITLE }, - { "disconnectManagedProfileOK", - IDS_PROFILES_DISCONNECT_MANAGED_PROFILE_OK_BUTTON_LABEL }, - { "createProfileTitle", IDS_PROFILES_CREATE_TITLE }, - { "createProfileInstructions", IDS_PROFILES_CREATE_INSTRUCTIONS }, - { "createProfileConfirm", IDS_ADD }, - { "createProfileShortcutCheckbox", IDS_PROFILES_CREATE_SHORTCUT_CHECKBOX }, - { "createProfileShortcutButton", IDS_PROFILES_CREATE_SHORTCUT_BUTTON }, - { "removeProfileShortcutButton", IDS_PROFILES_REMOVE_SHORTCUT_BUTTON }, - { "importExistingSupervisedUserLink", - IDS_IMPORT_EXISTING_LEGACY_SUPERVISED_USER_TITLE }, - }; - - RegisterStrings(localized_strings, resources, arraysize(resources)); - RegisterTitle(localized_strings, "manageProfile", IDS_PROFILES_MANAGE_TITLE); - RegisterTitle(localized_strings, "createProfile", IDS_PROFILES_CREATE_TITLE); - RegisterTitle(localized_strings, "disconnectAccount", - IDS_DISCONNECT_ACCOUNT_TITLE); - - base::string16 supervised_user_dashboard_url = - base::ASCIIToUTF16(chrome::kLegacySupervisedUserManagementURL); - base::string16 supervised_user_dashboard_display = - base::ASCIIToUTF16(chrome::kLegacySupervisedUserManagementDisplayURL); - localized_strings->SetString("deleteSupervisedProfileAddendum", - l10n_util::GetStringFUTF16(IDS_PROFILES_DELETE_LEGACY_SUPERVISED_ADDENDUM, - supervised_user_dashboard_url, - supervised_user_dashboard_display)); - - localized_strings->SetBoolean("profileShortcutsEnabled", - ProfileShortcutManager::IsFeatureEnabled()); - - GenerateSignedinUserSpecificStrings(localized_strings); -} - -void ManageProfileHandler::InitializeHandler() { - g_browser_process->profile_manager()-> - GetProfileAttributesStorage().AddObserver(this); - - Profile* profile = Profile::FromWebUI(web_ui()); - pref_change_registrar_.Init(profile->GetPrefs()); - pref_change_registrar_.Add( - prefs::kSupervisedUserCreationAllowed, - base::Bind(&ManageProfileHandler::OnCreateSupervisedUserPrefChange, - base::Unretained(this))); - browser_sync::ProfileSyncService* service = - ProfileSyncServiceFactory::GetForProfile(profile); - // Sync may be disabled for tests. - if (service) - service->AddObserver(this); -} - -void ManageProfileHandler::InitializePage() { - SendExistingProfileNames(); - OnCreateSupervisedUserPrefChange(); -} - -void ManageProfileHandler::RegisterMessages() { - web_ui()->RegisterMessageCallback("setProfileIconAndName", - base::Bind(&ManageProfileHandler::SetProfileIconAndName, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("requestDefaultProfileIcons", - base::Bind(&ManageProfileHandler::RequestDefaultProfileIcons, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("requestNewProfileDefaults", - base::Bind(&ManageProfileHandler::RequestNewProfileDefaults, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("requestHasProfileShortcuts", - base::Bind(&ManageProfileHandler::RequestHasProfileShortcuts, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("requestCreateProfileUpdate", - base::Bind(&ManageProfileHandler::RequestCreateProfileUpdate, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("profileIconSelectionChanged", - base::Bind(&ManageProfileHandler::ProfileIconSelectionChanged, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("addProfileShortcut", - base::Bind(&ManageProfileHandler::AddProfileShortcut, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("removeProfileShortcut", - base::Bind(&ManageProfileHandler::RemoveProfileShortcut, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("refreshGaiaPicture", - base::Bind(&ManageProfileHandler::RefreshGaiaPicture, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "showDisconnectManagedProfileDialog", - base::Bind(&ManageProfileHandler::ShowDisconnectManagedProfileDialog, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("logDeleteUserDialogShown", - base::Bind(&HandleLogDeleteUserDialogShown)); -} - -void ManageProfileHandler::Uninitialize() { - g_browser_process->profile_manager()-> - GetProfileAttributesStorage().RemoveObserver(this); -} - -void ManageProfileHandler::OnProfileAdded(const base::FilePath& profile_path) { - SendExistingProfileNames(); -} - -void ManageProfileHandler::OnProfileWasRemoved( - const base::FilePath& profile_path, - const base::string16& profile_name) { - SendExistingProfileNames(); -} - -void ManageProfileHandler::OnProfileNameChanged( - const base::FilePath& profile_path, - const base::string16& old_profile_name) { - base::Value value(kManageProfileIdentifier); - SendProfileIconsAndNames(value); -} - -void ManageProfileHandler::OnProfileAvatarChanged( - const base::FilePath& profile_path) { - base::Value value(kManageProfileIdentifier); - SendProfileIconsAndNames(value); -} - -void ManageProfileHandler::OnStateChanged(syncer::SyncService* sync) { - RequestCreateProfileUpdate(NULL); -} - -void ManageProfileHandler::GenerateSignedinUserSpecificStrings( - base::DictionaryValue* dictionary) { - std::string username; - std::string domain_name; - -#if !defined(OS_CHROMEOS) - Profile* profile = Profile::FromWebUI(web_ui()); - DCHECK(profile); - SigninManagerBase* manager = SigninManagerFactory::GetForProfile(profile); - if (manager) { - username = manager->GetAuthenticatedAccountInfo().email; - // If there is no one logged in or if the profile name is empty then the - // domain name is empty. This happens in browser tests. - if (!username.empty()) { - domain_name = "<span id=disconnect-managed-profile-domain-name>" + - gaia::ExtractDomainName(username) + "</span>"; - } - } -#endif - - dictionary->SetString( - "disconnectManagedProfileDomainInformation", - l10n_util::GetStringFUTF16( - IDS_PROFILES_DISCONNECT_MANAGED_PROFILE_DOMAIN_INFORMATION, - base::ASCIIToUTF16(domain_name))); - - dictionary->SetString( - "disconnectManagedProfileText", - l10n_util::GetStringFUTF16( - IDS_PROFILES_DISCONNECT_MANAGED_PROFILE_TEXT, - base::UTF8ToUTF16(username), - base::UTF8ToUTF16(chrome::kSyncGoogleDashboardURL))); -} - -void ManageProfileHandler::RequestDefaultProfileIcons( - const base::ListValue* args) { - std::string mode; - bool ok = args->GetString(0, &mode); - DCHECK(ok); - DCHECK(mode == kCreateProfileIdentifier || mode == kManageProfileIdentifier); - if (ok) { - base::Value value(mode); - SendProfileIconsAndNames(value); - } -} - -void ManageProfileHandler::RequestNewProfileDefaults( - const base::ListValue* args) { - const ProfileAttributesStorage& storage = - g_browser_process->profile_manager()->GetProfileAttributesStorage(); - const size_t icon_index = storage.ChooseAvatarIconIndexForNewProfile(); - - base::DictionaryValue profile_info; - profile_info.SetString("name", storage.ChooseNameForNewProfile(icon_index)); - profile_info.SetString("iconURL", - profiles::GetDefaultAvatarIconUrl(icon_index)); - - web_ui()->CallJavascriptFunctionUnsafe( - "ManageProfileOverlay.receiveNewProfileDefaults", profile_info); -} - -void ManageProfileHandler::SendProfileIconsAndNames(const base::Value& mode) { - base::ListValue image_url_list; - base::ListValue default_name_list; - - ProfileAttributesStorage& storage = - g_browser_process->profile_manager()->GetProfileAttributesStorage(); - - // In manage mode, first add the GAIA picture if it is available. No GAIA - // picture in create mode. - if (mode.GetString() == kManageProfileIdentifier) { - Profile* profile = Profile::FromWebUI(web_ui()); - ProfileAttributesEntry* entry = nullptr; - bool success = storage.GetProfileAttributesWithPath(profile->GetPath(), - &entry); - const gfx::Image* icon = success ? entry->GetGAIAPicture() : nullptr; - if (icon) { - gfx::Image icon2 = profiles::GetAvatarIconForWebUI(*icon, true); - gaia_picture_url_ = webui::GetBitmapDataUrl(icon2.AsBitmap()); - image_url_list.AppendString(gaia_picture_url_); - default_name_list.AppendString(std::string()); - } - } - - // Next add the default avatar icons and names. - for (size_t i = 0; i < profiles::GetDefaultAvatarIconCount(); i++) { - std::string url = profiles::GetDefaultAvatarIconUrl(i); - image_url_list.AppendString(url); - default_name_list.AppendString(storage.ChooseNameForNewProfile(i)); - } - - web_ui()->CallJavascriptFunctionUnsafe( - "ManageProfileOverlay.receiveDefaultProfileIconsAndNames", mode, - image_url_list, default_name_list); -} - -void ManageProfileHandler::SendExistingProfileNames() { - std::vector<ProfileAttributesEntry*> entries = - g_browser_process->profile_manager()-> - GetProfileAttributesStorage().GetAllProfilesAttributes(); - base::DictionaryValue profile_name_dict; - for (const ProfileAttributesEntry* entry : entries) - profile_name_dict.SetBoolean(base::UTF16ToUTF8(entry->GetName()), true); - - web_ui()->CallJavascriptFunctionUnsafe( - "ManageProfileOverlay.receiveExistingProfileNames", profile_name_dict); -} - -void ManageProfileHandler::ShowDisconnectManagedProfileDialog( - const base::ListValue* args) { - base::DictionaryValue replacements; - GenerateSignedinUserSpecificStrings(&replacements); - web_ui()->CallJavascriptFunctionUnsafe( - "ManageProfileOverlay.showDisconnectManagedProfileDialog", replacements); -} - -void ManageProfileHandler::SetProfileIconAndName(const base::ListValue* args) { - DCHECK(args); - - base::FilePath profile_file_path; - if (!GetProfilePathFromArgs(args, &profile_file_path)) - return; - - Profile* profile = - g_browser_process->profile_manager()->GetProfile(profile_file_path); - if (!profile) - return; - - std::string icon_url; - if (!args->GetString(1, &icon_url)) - return; - - PrefService* pref_service = profile->GetPrefs(); - // Updating the profile preferences will cause the cache to be updated. - - // Metrics logging variable. - bool previously_using_gaia_icon = - pref_service->GetBoolean(prefs::kProfileUsingGAIAAvatar); - - size_t new_icon_index; - if (icon_url == gaia_picture_url_) { - pref_service->SetBoolean(prefs::kProfileUsingDefaultAvatar, false); - pref_service->SetBoolean(prefs::kProfileUsingGAIAAvatar, true); - if (!previously_using_gaia_icon) { - // Only log if they changed to the GAIA photo. - // Selection of GAIA photo as avatar is logged as part of the function - // below. - ProfileMetrics::LogProfileSwitchGaia(ProfileMetrics::GAIA_OPT_IN); - } - } else if (profiles::IsDefaultAvatarIconUrl(icon_url, &new_icon_index)) { - ProfileMetrics::LogProfileAvatarSelection(new_icon_index); - pref_service->SetInteger(prefs::kProfileAvatarIndex, new_icon_index); - pref_service->SetBoolean(prefs::kProfileUsingDefaultAvatar, false); - pref_service->SetBoolean(prefs::kProfileUsingGAIAAvatar, false); - } else { - // Only default avatars and Gaia account photos are supported. - CHECK(false); - } - ProfileMetrics::LogProfileUpdate(profile_file_path); - - if (profile->IsLegacySupervised()) - return; - - base::string16 new_profile_name; - if (!args->GetString(2, &new_profile_name)) - return; - - base::TrimWhitespace(new_profile_name, base::TRIM_ALL, &new_profile_name); - CHECK(!new_profile_name.empty()); - profiles::UpdateProfileName(profile, new_profile_name); -} - -void ManageProfileHandler::ProfileIconSelectionChanged( - const base::ListValue* args) { - DCHECK(args); - - base::FilePath profile_file_path; - if (!GetProfilePathFromArgs(args, &profile_file_path)) - return; - - // Currently this only supports editing the current profile's info. - if (profile_file_path != Profile::FromWebUI(web_ui())->GetPath()) - return; - - std::string icon_url; - if (!args->GetString(1, &icon_url)) - return; - - if (icon_url != gaia_picture_url_) - return; - - // If the selection is the GAIA picture then also show the profile name in the - // text field. This will display either the GAIA given name, if available, - // or the first name. - ProfileAttributesEntry* entry = nullptr; - if (!g_browser_process->profile_manager()->GetProfileAttributesStorage(). - GetProfileAttributesWithPath(profile_file_path, &entry)) - return; - base::string16 gaia_name = entry->GetName(); - if (gaia_name.empty()) - return; - - base::Value gaia_name_value(gaia_name); - base::Value mode_value(kManageProfileIdentifier); - web_ui()->CallJavascriptFunctionUnsafe("ManageProfileOverlay.setProfileName", - gaia_name_value, mode_value); -} - -void ManageProfileHandler::RequestHasProfileShortcuts( - const base::ListValue* args) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - DCHECK(ProfileShortcutManager::IsFeatureEnabled()); - - base::FilePath profile_file_path; - if (!GetProfilePathFromArgs(args, &profile_file_path)) - return; - - ProfileAttributesStorage& storage = - g_browser_process->profile_manager()->GetProfileAttributesStorage(); - ProfileAttributesEntry* entry; - if (!storage.GetProfileAttributesWithPath(profile_file_path, &entry)) - return; - - // Don't show the add/remove desktop shortcut button in the single user case. - if (storage.GetNumberOfProfiles() <= 1u) - return; - - ProfileShortcutManager* shortcut_manager = - g_browser_process->profile_manager()->profile_shortcut_manager(); - shortcut_manager->HasProfileShortcuts( - entry->GetPath(), base::Bind(&ManageProfileHandler::OnHasProfileShortcuts, - weak_factory_.GetWeakPtr())); -} - -void ManageProfileHandler::RequestCreateProfileUpdate( - const base::ListValue* args) { - Profile* profile = Profile::FromWebUI(web_ui()); - SigninManagerBase* manager = - SigninManagerFactory::GetForProfile(profile); - base::string16 username = - base::UTF8ToUTF16(manager->GetAuthenticatedAccountInfo().email); - browser_sync::ProfileSyncService* service = - ProfileSyncServiceFactory::GetForProfile(profile); - GoogleServiceAuthError::State state = GoogleServiceAuthError::NONE; - - // |service| might be null if Sync is disabled from the command line. - if (service) - state = service->GetAuthError().state(); - - bool has_error = (!service || - state == GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS || - state == GoogleServiceAuthError::USER_NOT_SIGNED_UP || - state == GoogleServiceAuthError::ACCOUNT_DELETED || - state == GoogleServiceAuthError::ACCOUNT_DISABLED); - web_ui()->CallJavascriptFunctionUnsafe( - "CreateProfileOverlay.updateSignedInStatus", base::Value(username), - base::Value(has_error)); - - OnCreateSupervisedUserPrefChange(); -} - -void ManageProfileHandler::OnCreateSupervisedUserPrefChange() { - PrefService* prefs = Profile::FromWebUI(web_ui())->GetPrefs(); - base::Value allowed(prefs->GetBoolean(prefs::kSupervisedUserCreationAllowed)); - web_ui()->CallJavascriptFunctionUnsafe( - "CreateProfileOverlay.updateSupervisedUsersAllowed", allowed); -} - -void ManageProfileHandler::OnHasProfileShortcuts(bool has_shortcuts) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - - const base::Value has_shortcuts_value(has_shortcuts); - web_ui()->CallJavascriptFunctionUnsafe( - "ManageProfileOverlay.receiveHasProfileShortcuts", has_shortcuts_value); -} - -void ManageProfileHandler::AddProfileShortcut(const base::ListValue* args) { - base::FilePath profile_file_path; - if (!GetProfilePathFromArgs(args, &profile_file_path)) - return; - - DCHECK(ProfileShortcutManager::IsFeatureEnabled()); - ProfileShortcutManager* shortcut_manager = - g_browser_process->profile_manager()->profile_shortcut_manager(); - DCHECK(shortcut_manager); - - shortcut_manager->CreateProfileShortcut(profile_file_path); - - // Update the UI buttons. - OnHasProfileShortcuts(true); -} - -void ManageProfileHandler::RemoveProfileShortcut(const base::ListValue* args) { - base::FilePath profile_file_path; - if (!GetProfilePathFromArgs(args, &profile_file_path)) - return; - - DCHECK(ProfileShortcutManager::IsFeatureEnabled()); - ProfileShortcutManager* shortcut_manager = - g_browser_process->profile_manager()->profile_shortcut_manager(); - DCHECK(shortcut_manager); - - shortcut_manager->RemoveProfileShortcuts(profile_file_path); - - // Update the UI buttons. - OnHasProfileShortcuts(false); -} - -void ManageProfileHandler::RefreshGaiaPicture(const base::ListValue* args) { - profiles::UpdateGaiaProfileInfoIfNeeded(Profile::FromWebUI(web_ui())); -} - -} // namespace options
diff --git a/chrome/browser/ui/webui/options/manage_profile_handler.h b/chrome/browser/ui/webui/options/manage_profile_handler.h deleted file mode 100644 index b0688bf..0000000 --- a/chrome/browser/ui/webui/options/manage_profile_handler.h +++ /dev/null
@@ -1,144 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_WEBUI_OPTIONS_MANAGE_PROFILE_HANDLER_H_ -#define CHROME_BROWSER_UI_WEBUI_OPTIONS_MANAGE_PROFILE_HANDLER_H_ - -#include <string> - -#include "base/macros.h" -#include "base/memory/weak_ptr.h" -#include "chrome/browser/profiles/profile_attributes_storage.h" -#include "chrome/browser/ui/webui/options/options_ui.h" -#include "components/prefs/pref_change_registrar.h" -#include "components/sync/driver/sync_service_observer.h" - -namespace base { -class Value; -} - -namespace options { - -// Chrome personal stuff profiles manage overlay UI handler. -class ManageProfileHandler : public OptionsPageUIHandler, - public ProfileAttributesStorage::Observer, - public syncer::SyncServiceObserver { - public: - ManageProfileHandler(); - ~ManageProfileHandler() override; - - // OptionsPageUIHandler: - void GetLocalizedValues(base::DictionaryValue* localized_strings) override; - void InitializeHandler() override; - void InitializePage() override; - void Uninitialize() override; - - // WebUIMessageHandler: - void RegisterMessages() override; - - // ProfileAttributesStorage::Observer: - void OnProfileAdded(const base::FilePath& profile_path) override; - void OnProfileWasRemoved(const base::FilePath& profile_path, - const base::string16& profile_name) override; - void OnProfileNameChanged(const base::FilePath& profile_path, - const base::string16& old_profile_name) override; - void OnProfileAvatarChanged(const base::FilePath& profile_path) override; - - // syncer::SyncServiceObserver: - void OnStateChanged(syncer::SyncService* sync) override; - - private: - // This function creates signed in user specific strings in loadTimeData. - void GenerateSignedinUserSpecificStrings(base::DictionaryValue* dictionary); - - // Callback for the "requestDefaultProfileIcons" message. - // Sends the array of default profile icon URLs and profile names to WebUI. - // First item of |args| is the dialog mode, i.e. "create" or "manage". - void RequestDefaultProfileIcons(const base::ListValue* args); - - // Callback for the "requestNewProfileDefaults" message. - // Sends an object to WebUI of the form: - // { "name": profileName, "iconURL": iconURL } - void RequestNewProfileDefaults(const base::ListValue* args); - - // Send all profile icons and their default names to the overlay. - // |mode| is the dialog mode, i.e. "create" or "manage". - void SendProfileIconsAndNames(const base::Value& mode); - - // Sends an object to WebUI of the form: - // profileNames = { - // "Profile Name 1": true, - // "Profile Name 2": true, - // ... - // }; - // This is used to detect duplicate profile names. - void SendExistingProfileNames(); - - // Show disconnect managed profile dialog after generating domain and user - // specific strings. - void ShowDisconnectManagedProfileDialog(const base::ListValue* args); - - // Callback for the "setProfileIconAndName" message. Sets the name and icon - // of a given profile. - // |args| is of the form: [ - // /*string*/ profileFilePath, - // /*string*/ newProfileIconURL - // /*string*/ newProfileName, - // ] - void SetProfileIconAndName(const base::ListValue* args); - - // Callback for the 'profileIconSelectionChanged' message. Used to update the - // name in the manager profile dialog based on the selected icon. - void ProfileIconSelectionChanged(const base::ListValue* args); - - // Callback for the "requestHasProfileShortcuts" message, which is called - // when editing an existing profile. Asks the profile shortcut manager whether - // the profile has shortcuts and gets the result in |OnHasProfileShortcuts()|. - // |args| is of the form: [ {string} profileFilePath ] - void RequestHasProfileShortcuts(const base::ListValue* args); - - // Callback for the "RequestCreateProfileUpdate" message. - // Sends the email address of the signed-in user, or an empty string if the - // user is not signed in. Also sends information about whether supervised - // users may be created. - void RequestCreateProfileUpdate(const base::ListValue* args); - - // When the pref allowing supervised-user creation changes, sends the new - // value to the UI. - void OnCreateSupervisedUserPrefChange(); - - // Callback invoked from the profile manager indicating whether the profile - // being edited has any desktop shortcuts. - void OnHasProfileShortcuts(bool has_shortcuts); - - // Callback for the "addProfileShortcut" message, which is called when editing - // an existing profile and the user clicks the "Add desktop shortcut" button. - // Adds a desktop shortcut for the profile. - void AddProfileShortcut(const base::ListValue* args); - - // Callback for the "removeProfileShortcut" message, which is called when - // editing an existing profile and the user clicks the "Remove desktop - // shortcut" button. Removes the desktop shortcut for the profile. - void RemoveProfileShortcut(const base::ListValue* args); - - // Callback for the "refreshGaiaPicture" message, which is called when the - // user is editing an existing profile. - void RefreshGaiaPicture(const base::ListValue* args); - - // URL for the current profile's GAIA picture. - std::string gaia_picture_url_; - - // Used to observe the preference that allows creating supervised users, which - // can be changed by policy. - PrefChangeRegistrar pref_change_registrar_; - - // For generating weak pointers to itself for callbacks. - base::WeakPtrFactory<ManageProfileHandler> weak_factory_; - - DISALLOW_COPY_AND_ASSIGN(ManageProfileHandler); -}; - -} // namespace options - -#endif // CHROME_BROWSER_UI_WEBUI_OPTIONS_MANAGE_PROFILE_HANDLER_H_
diff --git a/chrome/browser/ui/webui/options/media_devices_selection_handler.cc b/chrome/browser/ui/webui/options/media_devices_selection_handler.cc deleted file mode 100644 index df8b459..0000000 --- a/chrome/browser/ui/webui/options/media_devices_selection_handler.cc +++ /dev/null
@@ -1,181 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/webui/options/media_devices_selection_handler.h" - -#include <stddef.h> - -#include <memory> -#include <utility> - -#include "base/bind.h" -#include "base/macros.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/common/pref_names.h" -#include "chrome/grit/generated_resources.h" -#include "components/prefs/pref_service.h" - -#if BUILDFLAG(ENABLE_EXTENSIONS) -#include "extensions/strings/grit/extensions_strings.h" -#include "ui/base/l10n/l10n_util.h" -#endif - -namespace { - -const char kAudio[] = "mic"; -const char kVideo[] = "camera"; - -} // namespace - -namespace options { - -MediaDevicesSelectionHandler::MediaDevicesSelectionHandler() {} - -MediaDevicesSelectionHandler::~MediaDevicesSelectionHandler() { - MediaCaptureDevicesDispatcher::GetInstance()->RemoveObserver(this); -} - -void MediaDevicesSelectionHandler::GetLocalizedValues( - base::DictionaryValue* values) { - DCHECK(values); - - static OptionsStringResource resources[] = { - { "mediaSelectMicLabel", IDS_MEDIA_SELECTED_MIC_LABEL }, - { "mediaSelectCameraLabel", IDS_MEDIA_SELECTED_CAMERA_LABEL }, - }; - - RegisterStrings(values, resources, arraysize(resources)); -} - -void MediaDevicesSelectionHandler::InitializePage() { - // Register to the device observer list to get up-to-date device lists. - MediaCaptureDevicesDispatcher::GetInstance()->AddObserver(this); - - // Update the device selection menus. - UpdateDevicesMenuForType(AUDIO); - UpdateDevicesMenuForType(VIDEO); -} - -void MediaDevicesSelectionHandler::RegisterMessages() { - web_ui()->RegisterMessageCallback("setDefaultCaptureDevice", - base::Bind(&MediaDevicesSelectionHandler::SetDefaultCaptureDevice, - base::Unretained(this))); -} - -void MediaDevicesSelectionHandler::OnUpdateAudioDevices( - const content::MediaStreamDevices& devices) { - UpdateDevicesMenu(AUDIO, devices); -} - -void MediaDevicesSelectionHandler::OnUpdateVideoDevices( - const content::MediaStreamDevices& devices) { - UpdateDevicesMenu(VIDEO, devices); -} - -void MediaDevicesSelectionHandler::SetDefaultCaptureDevice( - const base::ListValue* args) { - DCHECK_EQ(2U, args->GetSize()); - std::string type, device; - if (!(args->GetString(0, &type) && args->GetString(1, &device))) { - NOTREACHED(); - return; - } - - DCHECK(!type.empty()); - DCHECK(!device.empty()); - - Profile* profile = Profile::FromWebUI(web_ui()); - PrefService* prefs = profile->GetPrefs(); - if (type == kAudio) - prefs->SetString(prefs::kDefaultAudioCaptureDevice, device); - else if (type == kVideo) - prefs->SetString(prefs::kDefaultVideoCaptureDevice, device); - else - NOTREACHED(); -} - -void MediaDevicesSelectionHandler::UpdateDevicesMenu( - DeviceType type, const content::MediaStreamDevices& devices) { - // Get the default device unique id from prefs. - Profile* profile = Profile::FromWebUI(web_ui()); - PrefService* prefs = profile->GetPrefs(); - std::string default_device; - std::string device_type; - switch (type) { - case AUDIO: - default_device = prefs->GetString(prefs::kDefaultAudioCaptureDevice); - device_type = kAudio; - break; - case VIDEO: - default_device = prefs->GetString(prefs::kDefaultVideoCaptureDevice); - device_type = kVideo; - break; - } - - // Build the list of devices to send to JS. - std::string default_id; - base::ListValue device_list; - for (size_t i = 0; i < devices.size(); ++i) { - std::unique_ptr<base::DictionaryValue> entry(new base::DictionaryValue()); - entry->SetString("name", GetDeviceDisplayName(devices[i])); - entry->SetString("id", devices[i].id); - device_list.Append(std::move(entry)); - if (devices[i].id == default_device) - default_id = default_device; - } - - // Use the first device as the default device if the preferred default device - // does not exist in the OS. - if (!devices.empty() && default_id.empty()) - default_id = devices[0].id; - - base::Value default_value(default_id); - base::Value type_value(device_type); - web_ui()->CallJavascriptFunctionUnsafe("ContentSettings.updateDevicesMenu", - type_value, device_list, - default_value); -} - -std::string MediaDevicesSelectionHandler::GetDeviceDisplayName( - const content::MediaStreamDevice& device) const { - std::string facing_info; - -#if BUILDFLAG(ENABLE_EXTENSIONS) - switch (device.video_facing) { - case media::VideoFacingMode::MEDIA_VIDEO_FACING_USER: - facing_info = l10n_util::GetStringUTF8(IDS_CAMERA_FACING_USER); - break; - case media::VideoFacingMode::MEDIA_VIDEO_FACING_ENVIRONMENT: - facing_info = l10n_util::GetStringUTF8(IDS_CAMERA_FACING_ENVIRONMENT); - break; - case media::VideoFacingMode::MEDIA_VIDEO_FACING_NONE: - break; - case media::VideoFacingMode::NUM_MEDIA_VIDEO_FACING_MODES: - NOTREACHED(); - break; - } -#endif - - if (facing_info.empty()) - return device.name; - return device.name + " " + facing_info; -} - -void MediaDevicesSelectionHandler::UpdateDevicesMenuForType(DeviceType type) { - content::MediaStreamDevices devices; - switch (type) { - case AUDIO: - devices = MediaCaptureDevicesDispatcher::GetInstance()-> - GetAudioCaptureDevices(); - break; - case VIDEO: - devices = MediaCaptureDevicesDispatcher::GetInstance()-> - GetVideoCaptureDevices(); - break; - } - - UpdateDevicesMenu(type, devices); -} - -} // namespace options
diff --git a/chrome/browser/ui/webui/options/media_devices_selection_handler.h b/chrome/browser/ui/webui/options/media_devices_selection_handler.h deleted file mode 100644 index ff1355a..0000000 --- a/chrome/browser/ui/webui/options/media_devices_selection_handler.h +++ /dev/null
@@ -1,59 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_WEBUI_OPTIONS_MEDIA_DEVICES_SELECTION_HANDLER_H_ -#define CHROME_BROWSER_UI_WEBUI_OPTIONS_MEDIA_DEVICES_SELECTION_HANDLER_H_ - -#include "base/macros.h" -#include "chrome/browser/media/webrtc/media_capture_devices_dispatcher.h" -#include "chrome/browser/ui/webui/options/options_ui.h" -#include "content/public/browser/web_contents.h" - -namespace options { - -// Handler for media devices selection in content settings. -class MediaDevicesSelectionHandler - : public MediaCaptureDevicesDispatcher::Observer, - public OptionsPageUIHandler { - public: - MediaDevicesSelectionHandler(); - ~MediaDevicesSelectionHandler() override; - - // OptionsPageUIHandler implementation. - void GetLocalizedValues(base::DictionaryValue* values) override; - void InitializePage() override; - void RegisterMessages() override; - - // MediaCaptureDevicesDispatcher::Observer implementation. - void OnUpdateAudioDevices( - const content::MediaStreamDevices& devices) override; - void OnUpdateVideoDevices( - const content::MediaStreamDevices& devices) override; - - private: - enum DeviceType { - AUDIO, - VIDEO, - }; - - // Sets the default audio/video capture device for media. |args| includes the - // media type (kAuudio/kVideo) and the unique id of the new default device - // that the user has chosen. - void SetDefaultCaptureDevice(const base::ListValue* args); - - // Helpers methods to update the device menus. - void UpdateDevicesMenuForType(DeviceType type); - void UpdateDevicesMenu(DeviceType type, - const content::MediaStreamDevices& devices); - - // Gets the human readable name of the device. - std::string GetDeviceDisplayName( - const content::MediaStreamDevice& device) const; - - DISALLOW_COPY_AND_ASSIGN(MediaDevicesSelectionHandler); -}; - -} // namespace options - -#endif // CHROME_BROWSER_UI_WEBUI_OPTIONS_MEDIA_DEVICES_SELECTION_HANDLER_H_
diff --git a/chrome/browser/ui/webui/options/options_ui.cc b/chrome/browser/ui/webui/options/options_ui.cc deleted file mode 100644 index aaf5474e..0000000 --- a/chrome/browser/ui/webui/options/options_ui.cc +++ /dev/null
@@ -1,662 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/webui/options/options_ui.h" - -#include <algorithm> -#include <utility> -#include <vector> - -#include "base/callback.h" -#include "base/command_line.h" -#include "base/macros.h" -#include "base/memory/ptr_util.h" -#include "base/memory/ref_counted_memory.h" -#include "base/memory/singleton.h" -#include "base/message_loop/message_loop.h" -#include "base/metrics/histogram_macros.h" -#include "base/strings/string_piece.h" -#include "base/strings/string_util.h" -#include "base/threading/thread.h" -#include "base/time/time.h" -#include "base/values.h" -#include "build/build_config.h" -#include "chrome/browser/browser_about_handler.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/extensions/tab_helper.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/webui/metrics_handler.h" -#include "chrome/browser/ui/webui/options/autofill_options_handler.h" -#include "chrome/browser/ui/webui/options/automatic_settings_reset_handler.h" -#include "chrome/browser/ui/webui/options/browser_options_handler.h" -#include "chrome/browser/ui/webui/options/clear_browser_data_handler.h" -#include "chrome/browser/ui/webui/options/content_settings_handler.h" -#include "chrome/browser/ui/webui/options/cookies_view_handler.h" -#include "chrome/browser/ui/webui/options/core_options_handler.h" -#include "chrome/browser/ui/webui/options/create_profile_handler.h" -#include "chrome/browser/ui/webui/options/easy_unlock_handler.h" -#include "chrome/browser/ui/webui/options/font_settings_handler.h" -#include "chrome/browser/ui/webui/options/handler_options_handler.h" -#include "chrome/browser/ui/webui/options/help_overlay_handler.h" -#include "chrome/browser/ui/webui/options/home_page_overlay_handler.h" -#include "chrome/browser/ui/webui/options/import_data_handler.h" -#include "chrome/browser/ui/webui/options/language_dictionary_overlay_handler.h" -#include "chrome/browser/ui/webui/options/language_options_handler.h" -#include "chrome/browser/ui/webui/options/manage_profile_handler.h" -#include "chrome/browser/ui/webui/options/media_devices_selection_handler.h" -#include "chrome/browser/ui/webui/options/password_manager_handler.h" -#include "chrome/browser/ui/webui/options/reset_profile_settings_handler.h" -#include "chrome/browser/ui/webui/options/search_engine_manager_handler.h" -#include "chrome/browser/ui/webui/options/startup_pages_handler.h" -#include "chrome/browser/ui/webui/options/sync_setup_handler.h" -#include "chrome/browser/ui/webui/theme_source.h" -#include "chrome/common/features.h" -#include "chrome/common/url_constants.h" -#include "chrome/grit/generated_resources.h" -#include "chrome/grit/options_resources.h" -#include "components/omnibox/browser/autocomplete_match.h" -#include "components/omnibox/browser/autocomplete_result.h" -#include "components/strings/grit/components_strings.h" -#include "content/public/browser/navigation_handle.h" -#include "content/public/browser/notification_types.h" -#include "content/public/browser/render_frame_host.h" -#include "content/public/browser/url_data_source.h" -#include "content/public/browser/web_contents.h" -#include "content/public/browser/web_contents_delegate.h" -#include "content/public/browser/web_ui.h" -#include "net/base/escape.h" -#include "ui/base/l10n/l10n_util.h" -#include "ui/base/resource/resource_bundle.h" -#include "ui/base/template_expressions.h" -#include "ui/base/webui/jstemplate_builder.h" -#include "ui/base/webui/web_ui_util.h" -#include "url/gurl.h" - -#if BUILDFLAG(ENABLE_SUPERVISED_USERS) -#include "chrome/browser/ui/webui/options/supervised_user_create_confirm_handler.h" -#include "chrome/browser/ui/webui/options/supervised_user_import_handler.h" -#include "chrome/browser/ui/webui/options/supervised_user_learn_more_handler.h" -#endif - -#if defined(OS_CHROMEOS) -#include "chrome/browser/browser_process_platform_part.h" -#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" -#include "chrome/browser/chromeos/system/pointer_device_observer.h" -#include "chrome/browser/ui/webui/chromeos/user_image_source.h" -#include "chrome/browser/ui/webui/options/chromeos/accounts_options_handler.h" -#include "chrome/browser/ui/webui/options/chromeos/bluetooth_options_handler.h" -#include "chrome/browser/ui/webui/options/chromeos/change_picture_options_handler.h" -#include "chrome/browser/ui/webui/options/chromeos/core_chromeos_options_handler.h" -#include "chrome/browser/ui/webui/options/chromeos/cros_language_options_handler.h" -#include "chrome/browser/ui/webui/options/chromeos/date_time_options_handler.h" -#include "chrome/browser/ui/webui/options/chromeos/display_options_handler.h" -#include "chrome/browser/ui/webui/options/chromeos/display_overscan_handler.h" -#include "chrome/browser/ui/webui/options/chromeos/internet_options_handler.h" -#include "chrome/browser/ui/webui/options/chromeos/keyboard_handler.h" -#include "chrome/browser/ui/webui/options/chromeos/options_stylus_handler.h" -#include "chrome/browser/ui/webui/options/chromeos/pointer_handler.h" -#include "chrome/browser/ui/webui/options/chromeos/power_handler.h" -#include "chrome/browser/ui/webui/options/chromeos/proxy_handler.h" -#include "chrome/browser/ui/webui/options/chromeos/stats_options_handler.h" -#include "chrome/browser/ui/webui/options/chromeos/storage_manager_handler.h" -#endif - -#if defined(USE_NSS_CERTS) -#include "chrome/browser/ui/webui/options/certificate_manager_handler.h" -#endif - -#if BUILDFLAG(ENABLE_GOOGLE_NOW) -#include "chrome/browser/ui/webui/options/geolocation_options_handler.h" -#endif - -using content::RenderViewHost; - -namespace { - -const char kLocalizedStringsFile[] = "strings.js"; -const char kOptionsBundleJsFile[] = "options_bundle.js"; - -#if defined(OS_CHROMEOS) -constexpr char kIconsHTMLPath[] = "icons.html"; -constexpr char kPinKeyboardHTMLPath[] = "people_page/pin_keyboard.html"; -constexpr char kPinKeyboardJSPath[] = "people_page/pin_keyboard.js"; -constexpr char kPasswordPromptDialogHTMLPath[] = - "people_page/password_prompt_dialog.html"; -constexpr char kPasswordPromptDialogJSPath[] = - "people_page/password_prompt_dialog.js"; -constexpr char kLockScreenConstantsHTMLPath[] = - "people_page/lock_screen_constants.html"; -constexpr char kLockScreenConstantsJSPath[] = - "people_page/lock_screen_constants.js"; -constexpr char kLockStateBehaviorHTMLPath[] = - "people_page/lock_state_behavior.html"; -constexpr char kLockStateBehaviorJSPath[] = - "people_page/lock_state_behavior.js"; -constexpr char kLockScreenHTMLPath[] = "people_page/lock_screen.html"; -constexpr char kLockScreenJSPath[] = "people_page/lock_screen.js"; -constexpr char kSetupPinHTMLPath[] = "people_page/setup_pin_dialog.html"; -constexpr char kSetupPinJSPath[] = "people_page/setup_pin_dialog.js"; -constexpr char kEasyUnlockBrowserProxyHTMLPath[] = - "people_page/easy_unlock_browser_proxy.html"; -constexpr char kEasyUnlockBrowserProxyJSPath[] = - "people_page/easy_unlock_browser_proxy.js"; -constexpr char kEasyUnlockTurnOffDialogHTMLPath[] = - "people_page/easy_unlock_turn_off_dialog.html"; -constexpr char kEasyUnlockTurnOffDialogJSPath[] = - "people_page/easy_unlock_turn_off_dialog.js"; -constexpr char kFingerprintListHTMLPath[] = "people_page/fingerprint_list.html"; -constexpr char kFingerprintListJSPath[] = "people_page/fingerprint_list.js"; -constexpr char kSetupFingerprintHTMLPath[] = - "people_page/setup_fingerprint_dialog.html"; -constexpr char kSetupFingerprintJSPath[] = - "people_page/setup_fingerprint_dialog.js"; -constexpr char kFingerprintBrowserProxyHTMLPath[] = - "people_page/fingerprint_browser_proxy.html"; -constexpr char kFingerprintBrowserProxyJSPath[] = - "people_page/fingerprint_browser_proxy.js"; -constexpr char kFingerprintProgressArcHTMLPath[] = - "people_page/fingerprint_progress_arc.html"; -constexpr char kFingerprintProgressArcJSPath[] = - "people_page/fingerprint_progress_arc.js"; -constexpr char kSettingsRouteHTMLPath[] = "route.html"; -constexpr char kSettingsRouteJSPath[] = "route.js"; -constexpr char kSettingsSharedCSSHTMLPath[] = "settings_shared_css.html"; -constexpr char kSettingsBooleanControlBehaviorHTMLPath[] = - "controls/settings_boolean_control_behavior.html"; -constexpr char kSettingsBooleanControlBehaviorJSPath[] = - "controls/settings_boolean_control_behavior.js"; -constexpr char kSettingsPrefControlBehaviorHTMLPath[] = - "controls/pref_control_behavior.html"; -constexpr char kSettingsPrefControlBehaviorJSPath[] = - "controls/pref_control_behavior.js"; -constexpr char kSettingsToggleButtonHTMLPath[] = - "controls/settings_toggle_button.html"; -constexpr char kSettingsToggleButtonJSPath[] = - "controls/settings_toggle_button.js"; -constexpr char kSettingsVarsCSSHTMLPath[] = "settings_vars_css.html"; -constexpr char kSettingsPrefsBehaviorHTMLPath[] = "prefs/prefs_behavior.html"; -constexpr char kSettingsPrefsBehaviorJSPath[] = "prefs/prefs_behavior.js"; -constexpr char kSettingsPrefsTypesHTMLPath[] = "prefs/prefs_types.html"; -constexpr char kSettingsPrefsTypesJSPath[] = "prefs/prefs_types.js"; -constexpr char kSettingsPrefsHTMLPath[] = "prefs/prefs.html"; -constexpr char kSettingsPrefsJSPath[] = "prefs/prefs.js"; -constexpr char kSettingsI18nHTMLPath[] = "i18n_setup.html"; -constexpr char kOptionsPolymerHTMLPath[] = "options_polymer.html"; -#endif - -} // namespace - -namespace options { - -//////////////////////////////////////////////////////////////////////////////// -// -// OptionsUIHTMLSource -// -//////////////////////////////////////////////////////////////////////////////// - -class OptionsUIHTMLSource : public content::URLDataSource { - public: - // The constructor takes over ownership of |localized_strings|. - explicit OptionsUIHTMLSource(base::DictionaryValue* localized_strings); - - // content::URLDataSource implementation. - std::string GetSource() const override; - void StartDataRequest( - const std::string& path, - const content::ResourceRequestInfo::WebContentsGetter& wc_getter, - const content::URLDataSource::GotDataCallback& callback) override; - bool AllowCaching() const override; - std::string GetMimeType(const std::string&) const override; - bool ShouldDenyXFrameOptions() const override; - - private: - ~OptionsUIHTMLSource() override; - void CreateDataSourceMap(); - - // Localized strings collection. - std::unique_ptr<base::DictionaryValue> localized_strings_; - std::map<std::string, int> path_to_idr_map_; - ui::TemplateReplacements replacements_; - - DISALLOW_COPY_AND_ASSIGN(OptionsUIHTMLSource); -}; - -OptionsUIHTMLSource::OptionsUIHTMLSource( - base::DictionaryValue* localized_strings) { - DCHECK(localized_strings); - localized_strings_.reset(localized_strings); - CreateDataSourceMap(); -} - -std::string OptionsUIHTMLSource::GetSource() const { - // TODO(stevenjb): Remove this file. Because everything in this directory - // depends on this, we will remove the entire directory at once after - // the old CrOS oobe/login UI dependencies are removed. crbug.com/748164. - NOTREACHED(); - return "settings-frame"; -} - -void OptionsUIHTMLSource::StartDataRequest( - const std::string& path, - const content::ResourceRequestInfo::WebContentsGetter& wc_getter, - const content::URLDataSource::GotDataCallback& callback) { - scoped_refptr<base::RefCountedMemory> response_bytes; - const std::string& app_locale = g_browser_process->GetApplicationLocale(); - webui::SetLoadTimeDataDefaults(app_locale, localized_strings_.get()); - ui::TemplateReplacementsFromDictionaryValue(*localized_strings_, - &replacements_); - - std::map<std::string, int>::iterator result; - result = path_to_idr_map_.find(path); - - if (path == kLocalizedStringsFile) { - // Return dynamically-generated strings from memory. - std::string strings_js; - webui::AppendJsonJS(localized_strings_.get(), &strings_js); - response_bytes = base::RefCountedString::TakeString(&strings_js); - } else if (path == kOptionsBundleJsFile) { - // Return (and cache) the options javascript code. - response_bytes = ui::ResourceBundle::GetSharedInstance(). - LoadDataResourceBytes(IDR_OPTIONS_BUNDLE_JS); - } else if (result != path_to_idr_map_.end()) { - response_bytes = - ui::ResourceBundle::GetSharedInstance().LoadDataResourceBytes( - result->second); - } else { - // Return (and cache) the main options html page as the default. - response_bytes = ui::ResourceBundle::GetSharedInstance(). - LoadDataResourceBytes(IDR_OPTIONS_HTML); - } - - // pre-process i18n strings - if (GetMimeType(path) == "text/html") { - std::string replaced = ui::ReplaceTemplateExpressions( - base::StringPiece(response_bytes->front_as<char>(), - response_bytes->size()), - replacements_); - response_bytes = base::RefCountedString::TakeString(&replaced); - } - - callback.Run(response_bytes.get()); -} - -bool OptionsUIHTMLSource::AllowCaching() const { - // Should not be cached to reflect dynamically-generated contents that depends - // on the current locale. - return false; -} - -std::string OptionsUIHTMLSource::GetMimeType(const std::string& path) const { - if (base::EndsWith(path, ".js", base::CompareCase::INSENSITIVE_ASCII)) - return "application/javascript"; - - return "text/html"; -} - -bool OptionsUIHTMLSource::ShouldDenyXFrameOptions() const { - return false; -} - -OptionsUIHTMLSource::~OptionsUIHTMLSource() {} - -void OptionsUIHTMLSource::CreateDataSourceMap() { -#if defined(OS_CHROMEOS) - path_to_idr_map_[kIconsHTMLPath] = IDR_OPTIONS_ICONS_HTML; - - // These are part of the LockScreen UI. - path_to_idr_map_[kPinKeyboardHTMLPath] = IDR_OPTIONS_PIN_KEYBOARD_HTML; - path_to_idr_map_[kPinKeyboardJSPath] = IDR_OPTIONS_PIN_KEYBOARD_JS; - path_to_idr_map_[kPasswordPromptDialogHTMLPath] = - IDR_OPTIONS_PASSWORD_PROMPT_DIALOG_HTML; - path_to_idr_map_[kPasswordPromptDialogJSPath] = - IDR_OPTIONS_PASSWORD_PROMPT_DIALOG_JS; - path_to_idr_map_[kLockScreenConstantsHTMLPath] = - IDR_OPTIONS_LOCK_SCREEN_CONSTANTS_HTML; - path_to_idr_map_[kLockScreenConstantsJSPath] = - IDR_OPTIONS_LOCK_SCREEN_CONSTANTS_JS; - path_to_idr_map_[kLockStateBehaviorHTMLPath] = - IDR_OPTIONS_LOCK_STATE_BEHAVIOR_HTML; - path_to_idr_map_[kLockStateBehaviorJSPath] = - IDR_OPTIONS_LOCK_STATE_BEHAVIOR_JS; - path_to_idr_map_[kLockScreenHTMLPath] = IDR_OPTIONS_LOCK_SCREEN_HTML; - path_to_idr_map_[kLockScreenJSPath] = IDR_OPTIONS_LOCK_SCREEN_JS; - path_to_idr_map_[kEasyUnlockBrowserProxyHTMLPath] = - IDR_OPTIONS_EASY_UNLOCK_BROWSER_PROXY_HTML; - path_to_idr_map_[kEasyUnlockBrowserProxyJSPath] = - IDR_OPTIONS_EASY_UNLOCK_BROWSER_PROXY_JS; - path_to_idr_map_[kEasyUnlockTurnOffDialogHTMLPath] = - IDR_OPTIONS_EASY_UNLOCK_TURN_OFF_DIALOG_HTML; - path_to_idr_map_[kEasyUnlockTurnOffDialogJSPath] = - IDR_OPTIONS_EASY_UNLOCK_TURN_OFF_DIALOG_JS; - path_to_idr_map_[kSetupPinHTMLPath] = IDR_OPTIONS_SETUP_PIN_DIALOG_HTML; - path_to_idr_map_[kSetupPinJSPath] = IDR_OPTIONS_SETUP_PIN_DIALOG_JS; - path_to_idr_map_[kFingerprintListHTMLPath] = - IDR_OPTIONS_FINGERPRINT_LIST_HTML; - path_to_idr_map_[kFingerprintListJSPath] = IDR_OPTIONS_FINGERPRINT_LIST_JS; - path_to_idr_map_[kSetupFingerprintHTMLPath] = - IDR_OPTIONS_SETUP_FINGERPRINT_DIALOG_HTML; - path_to_idr_map_[kSetupFingerprintJSPath] = - IDR_OPTIONS_SETUP_FINGERPRINT_DIALOG_JS; - - path_to_idr_map_[kSettingsRouteHTMLPath] = IDR_OPTIONS_ROUTE_HTML; - path_to_idr_map_[kSettingsRouteJSPath] = IDR_OPTIONS_ROUTE_JS; - path_to_idr_map_[kSettingsSharedCSSHTMLPath] = IDR_SETTINGS_SHARED_CSS_HTML; - path_to_idr_map_[kSettingsBooleanControlBehaviorHTMLPath] = - IDR_SETTINGS_BOOLEAN_CONTROL_BEHAVIOR_HTML; - path_to_idr_map_[kSettingsBooleanControlBehaviorJSPath] = - IDR_SETTINGS_BOOLEAN_CONTROL_BEHAVIOR_JS; - path_to_idr_map_[kSettingsPrefControlBehaviorHTMLPath] = - IDR_SETTINGS_PREF_CONTROL_BEHAVIOR_HTML; - path_to_idr_map_[kSettingsPrefControlBehaviorJSPath] = - IDR_SETTINGS_PREF_CONTROL_BEHAVIOR_JS; - path_to_idr_map_[kSettingsToggleButtonHTMLPath] = - IDR_SETTINGS_TOGGLE_BUTTON_HTML; - path_to_idr_map_[kSettingsToggleButtonJSPath] = IDR_SETTINGS_TOGGLE_BUTTON_JS; - path_to_idr_map_[kSettingsVarsCSSHTMLPath] = IDR_SETTINGS_VARS_CSS_HTML; - path_to_idr_map_[kSettingsPrefsBehaviorHTMLPath] = - IDR_SETTINGS_PREFS_BEHAVIOR_HTML; - path_to_idr_map_[kSettingsPrefsBehaviorJSPath] = - IDR_SETTINGS_PREFS_BEHAVIOR_JS; - path_to_idr_map_[kSettingsPrefsTypesHTMLPath] = IDR_SETTINGS_PREFS_TYPES_HTML; - path_to_idr_map_[kSettingsPrefsTypesJSPath] = IDR_SETTINGS_PREFS_TYPES_JS; - path_to_idr_map_[kOptionsPolymerHTMLPath] = IDR_OPTIONS_POLYMER_ELEMENTS_HTML; - path_to_idr_map_[kSettingsPrefsHTMLPath] = IDR_SETTINGS_PREFS_HTML; - path_to_idr_map_[kSettingsPrefsJSPath] = IDR_SETTINGS_PREFS_JS; - path_to_idr_map_[kSettingsI18nHTMLPath] = IDR_OPTIONS_I18N_SETUP_HTML; - path_to_idr_map_[kFingerprintBrowserProxyHTMLPath] = - IDR_OPTIONS_FINGERPRINT_BROWSER_PROXY_HTML; - path_to_idr_map_[kFingerprintBrowserProxyJSPath] = - IDR_OPTIONS_FINGERPRINT_BROWSER_PROXY_JS; - path_to_idr_map_[kFingerprintProgressArcHTMLPath] = - IDR_OPTIONS_FINGERPRINT_PROGRESS_ARC_HTML; - path_to_idr_map_[kFingerprintProgressArcJSPath] = - IDR_OPTIONS_FINGERPRINT_PROGRESS_ARC_JS; -#endif -} - -//////////////////////////////////////////////////////////////////////////////// -// -// OptionsPageUIHandler -// -//////////////////////////////////////////////////////////////////////////////// - -OptionsPageUIHandler::OptionsPageUIHandler() { -} - -OptionsPageUIHandler::~OptionsPageUIHandler() { -} - -bool OptionsPageUIHandler::IsEnabled() { - return true; -} - -// static -void OptionsPageUIHandler::RegisterStrings( - base::DictionaryValue* localized_strings, - const OptionsStringResource* resources, - size_t length) { - for (size_t i = 0; i < length; ++i) { - base::string16 value; - if (resources[i].substitution_id == 0) { - value = l10n_util::GetStringUTF16(resources[i].id); - } else { - value = l10n_util::GetStringFUTF16( - resources[i].id, - l10n_util::GetStringUTF16(resources[i].substitution_id)); - } - localized_strings->SetString(resources[i].name, value); - } -} - -void OptionsPageUIHandler::RegisterTitle( - base::DictionaryValue* localized_strings, - const std::string& variable_name, - int title_id) { - localized_strings->SetString(variable_name, - l10n_util::GetStringUTF16(title_id)); - localized_strings->SetString(variable_name + "TabTitle", - l10n_util::GetStringFUTF16(IDS_OPTIONS_TAB_TITLE, - l10n_util::GetStringUTF16(IDS_SETTINGS_TITLE), - l10n_util::GetStringUTF16(title_id))); -} - -//////////////////////////////////////////////////////////////////////////////// -// -// OptionsUI -// -//////////////////////////////////////////////////////////////////////////////// - -OptionsUI::OptionsUI(content::WebUI* web_ui) - : WebUIController(web_ui), - WebContentsObserver(web_ui->GetWebContents()), - initialized_handlers_(false) { - base::DictionaryValue* localized_strings = new base::DictionaryValue(); - CoreOptionsHandler* core_handler; -#if defined(OS_CHROMEOS) - core_handler = new chromeos::options::CoreChromeOSOptionsHandler(); -#else - core_handler = new CoreOptionsHandler(); -#endif - core_handler->set_handlers_host(this); - AddOptionsPageUIHandler(localized_strings, core_handler); - - AddOptionsPageUIHandler(localized_strings, new AutofillOptionsHandler()); - AddOptionsPageUIHandler(localized_strings, - new AutomaticSettingsResetHandler()); - - BrowserOptionsHandler* browser_options_handler = new BrowserOptionsHandler(); - AddOptionsPageUIHandler(localized_strings, browser_options_handler); - - AddOptionsPageUIHandler(localized_strings, new ClearBrowserDataHandler()); - AddOptionsPageUIHandler(localized_strings, new ContentSettingsHandler()); - AddOptionsPageUIHandler(localized_strings, new CookiesViewHandler()); - AddOptionsPageUIHandler(localized_strings, new CreateProfileHandler()); - AddOptionsPageUIHandler(localized_strings, new EasyUnlockHandler()); - AddOptionsPageUIHandler(localized_strings, new FontSettingsHandler()); -#if BUILDFLAG(ENABLE_GOOGLE_NOW) - AddOptionsPageUIHandler(localized_strings, new GeolocationOptionsHandler()); -#endif - AddOptionsPageUIHandler(localized_strings, new options::HelpOverlayHandler()); - AddOptionsPageUIHandler(localized_strings, new HomePageOverlayHandler()); - AddOptionsPageUIHandler(localized_strings, - new MediaDevicesSelectionHandler()); -#if defined(OS_CHROMEOS) - AddOptionsPageUIHandler(localized_strings, - new chromeos::options::CrosLanguageOptionsHandler()); -#else - AddOptionsPageUIHandler(localized_strings, new LanguageOptionsHandler()); -#endif - AddOptionsPageUIHandler(localized_strings, - new LanguageDictionaryOverlayHandler()); - AddOptionsPageUIHandler(localized_strings, new ManageProfileHandler()); - AddOptionsPageUIHandler(localized_strings, new PasswordManagerHandler()); - AddOptionsPageUIHandler(localized_strings, new ResetProfileSettingsHandler()); - AddOptionsPageUIHandler(localized_strings, new SearchEngineManagerHandler()); - AddOptionsPageUIHandler(localized_strings, new ImportDataHandler()); - AddOptionsPageUIHandler(localized_strings, new StartupPagesHandler()); -#if BUILDFLAG(ENABLE_SUPERVISED_USERS) - AddOptionsPageUIHandler(localized_strings, - new SupervisedUserCreateConfirmHandler()); - AddOptionsPageUIHandler(localized_strings, new SupervisedUserImportHandler()); - AddOptionsPageUIHandler(localized_strings, - new SupervisedUserLearnMoreHandler()); -#endif - AddOptionsPageUIHandler(localized_strings, new SyncSetupHandler()); -#if defined(OS_CHROMEOS) - AddOptionsPageUIHandler(localized_strings, - new chromeos::options::AccountsOptionsHandler()); - AddOptionsPageUIHandler(localized_strings, - new chromeos::options::BluetoothOptionsHandler()); - AddOptionsPageUIHandler(localized_strings, - new chromeos::options::DateTimeOptionsHandler()); - AddOptionsPageUIHandler(localized_strings, - new chromeos::options::DisplayOptionsHandler()); - AddOptionsPageUIHandler(localized_strings, - new chromeos::options::DisplayOverscanHandler()); - AddOptionsPageUIHandler(localized_strings, - new chromeos::options::PowerHandler()); - AddOptionsPageUIHandler(localized_strings, - new chromeos::options::InternetOptionsHandler()); - AddOptionsPageUIHandler(localized_strings, - new chromeos::options::KeyboardHandler()); - AddOptionsPageUIHandler(localized_strings, - new chromeos::options::OptionsStylusHandler()); - - chromeos::options::PointerHandler* pointer_handler = - new chromeos::options::PointerHandler(); - AddOptionsPageUIHandler(localized_strings, pointer_handler); - - AddOptionsPageUIHandler(localized_strings, - new chromeos::options::ProxyHandler()); - AddOptionsPageUIHandler( - localized_strings, - new chromeos::options::ChangePictureOptionsHandler()); - AddOptionsPageUIHandler(localized_strings, - new chromeos::options::StatsOptionsHandler()); - AddOptionsPageUIHandler(localized_strings, - new chromeos::options::StorageManagerHandler()); -#endif -#if defined(USE_NSS_CERTS) - AddOptionsPageUIHandler(localized_strings, - new CertificateManagerHandler(false)); -#endif - AddOptionsPageUIHandler(localized_strings, new HandlerOptionsHandler()); - - web_ui->AddMessageHandler(base::MakeUnique<MetricsHandler>()); - - // Enable extension API calls in the WebUI. - extensions::TabHelper::CreateForWebContents(web_ui->GetWebContents()); - - // |localized_strings| ownership is taken over by this constructor. - OptionsUIHTMLSource* html_source = - new OptionsUIHTMLSource(localized_strings); - - // Set up the chrome://settings-frame/ source. - Profile* profile = Profile::FromWebUI(web_ui); - content::URLDataSource::Add(profile, html_source); - - // Set up the chrome://theme/ source. - ThemeSource* theme = new ThemeSource(profile); - content::URLDataSource::Add(profile, theme); - -#if defined(OS_CHROMEOS) - // Set up the chrome://userimage/ source. - chromeos::UserImageSource* user_image_source = - new chromeos::UserImageSource(); - content::URLDataSource::Add(profile, user_image_source); - - pointer_device_observer_.reset( - new chromeos::system::PointerDeviceObserver()); - pointer_device_observer_->AddObserver(browser_options_handler); - pointer_device_observer_->AddObserver(pointer_handler); -#endif -} - -OptionsUI::~OptionsUI() { - // Uninitialize all registered handlers. Deleted by WebUIImpl. - for (size_t i = 0; i < handlers_.size(); ++i) - handlers_[i]->Uninitialize(); -} - -std::unique_ptr<OptionsUI::OnFinishedLoadingCallbackList::Subscription> -OptionsUI::RegisterOnFinishedLoadingCallback(const base::Closure& callback) { - return on_finished_loading_callbacks_.Add(callback); -} - -// static -void OptionsUI::ProcessAutocompleteSuggestions( - const AutocompleteResult& result, - base::ListValue* const suggestions) { - for (size_t i = 0; i < result.size(); ++i) { - const AutocompleteMatch& match = result.match_at(i); - AutocompleteMatchType::Type type = match.type; - if (type != AutocompleteMatchType::HISTORY_URL && - type != AutocompleteMatchType::HISTORY_TITLE && - type != AutocompleteMatchType::HISTORY_BODY && - type != AutocompleteMatchType::HISTORY_KEYWORD && - type != AutocompleteMatchType::NAVSUGGEST && - type != AutocompleteMatchType::NAVSUGGEST_PERSONALIZED) { - continue; - } - std::unique_ptr<base::DictionaryValue> entry(new base::DictionaryValue()); - entry->SetString("title", match.description); - entry->SetString("displayURL", match.contents); - entry->SetString("url", match.destination_url.spec()); - suggestions->Append(std::move(entry)); - } -} - -void OptionsUI::ReadyToCommitNavigation( - content::NavigationHandle* navigation_handle) { - if (navigation_handle->IsSameDocument()) - return; - - load_start_time_ = base::Time::Now(); - if (navigation_handle->GetRenderFrameHost()->GetRenderViewHost() == - web_ui()->GetWebContents()->GetRenderViewHost() && - navigation_handle->GetURL().host_piece() == "settings-frame") { - for (size_t i = 0; i < handlers_.size(); ++i) - handlers_[i]->PageLoadStarted(); - } -} - -void OptionsUI::DocumentLoadedInFrame( - content::RenderFrameHost *render_frame_host) { - UMA_HISTOGRAM_TIMES("Settings.LoadDocumentTime", - base::Time::Now() - load_start_time_); -} - -void OptionsUI::DocumentOnLoadCompletedInMainFrame() { - UMA_HISTOGRAM_TIMES("Settings.LoadCompletedTime", - base::Time::Now() - load_start_time_); -} - -void OptionsUI::InitializeHandlers() { - Profile* profile = Profile::FromWebUI(web_ui()); - DCHECK(!profile->IsOffTheRecord() || profile->IsGuestSession()); - - // A new web page DOM has been brought up in an existing renderer, causing - // this method to be called twice. If that happens, ignore the second call. - if (!initialized_handlers_) { - for (size_t i = 0; i < handlers_.size(); ++i) - handlers_[i]->InitializeHandler(); - initialized_handlers_ = true; - -#if defined(OS_CHROMEOS) - pointer_device_observer_->Init(); -#endif - } - -#if defined(OS_CHROMEOS) - pointer_device_observer_->CheckDevices(); -#endif - - // Always initialize the page as when handlers are left over we still need to - // do various things like show/hide sections and send data to the Javascript. - for (size_t i = 0; i < handlers_.size(); ++i) - handlers_[i]->InitializePage(); - - web_ui()->CallJavascriptFunctionUnsafe( - "BrowserOptions.notifyInitializationComplete"); -} - -void OptionsUI::OnFinishedLoading() { - on_finished_loading_callbacks_.Notify(); -} - -void OptionsUI::AddOptionsPageUIHandler( - base::DictionaryValue* localized_strings, - OptionsPageUIHandler* handler_raw) { - std::unique_ptr<OptionsPageUIHandler> handler(handler_raw); - DCHECK(handler.get()); - // Add only if handler's service is enabled. - if (handler->IsEnabled()) { - // Add handler to the list and also pass the ownership. - web_ui()->AddMessageHandler(std::move(handler)); - handler_raw->GetLocalizedValues(localized_strings); - handlers_.push_back(handler_raw); - } -} - -} // namespace options
diff --git a/chrome/browser/ui/webui/options/options_ui.h b/chrome/browser/ui/webui/options/options_ui.h deleted file mode 100644 index 9a597f0..0000000 --- a/chrome/browser/ui/webui/options/options_ui.h +++ /dev/null
@@ -1,164 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_WEBUI_OPTIONS_OPTIONS_UI_H_ -#define CHROME_BROWSER_UI_WEBUI_OPTIONS_OPTIONS_UI_H_ - -#include <stddef.h> - -#include <memory> -#include <string> -#include <vector> - -#include "base/callback_list.h" -#include "base/compiler_specific.h" -#include "base/macros.h" -#include "base/time/time.h" -#include "build/build_config.h" -#include "content/public/browser/notification_registrar.h" -#include "content/public/browser/web_contents_observer.h" -#include "content/public/browser/web_ui_controller.h" -#include "content/public/browser/web_ui_message_handler.h" - -class AutocompleteResult; - -namespace base { -class DictionaryValue; -class ListValue; -} - -#if defined(OS_CHROMEOS) -namespace chromeos { -namespace system { -class PointerDeviceObserver; -} // namespace system -} // namespace chromeos -#endif - -namespace options { - -// The base class handler of Javascript messages of options pages. -class OptionsPageUIHandler : public content::WebUIMessageHandler { - public: - OptionsPageUIHandler(); - ~OptionsPageUIHandler() override; - - // Is this handler enabled? - virtual bool IsEnabled(); - - // Collects localized strings for options page. - virtual void GetLocalizedValues(base::DictionaryValue* localized_strings) = 0; - - virtual void PageLoadStarted() {} - - // Will be called only once in the life time of the handler. Generally used to - // add observers, initializes preferences, or start asynchronous calls from - // various services. - virtual void InitializeHandler() {} - - // Initialize the page. Called once the DOM is available for manipulation. - // This will be called when a RenderView is re-used (when navigated to with - // back/forward or session restored in some cases) or when created. - virtual void InitializePage() {} - - // Uninitializes the page. Called just before the object is destructed. - virtual void Uninitialize() {} - - // WebUIMessageHandler implementation. - void RegisterMessages() override {} - - protected: - struct OptionsStringResource { - // The name of the resource in templateData. - const char* name; - // The .grd ID for the resource (IDS_*). - int id; - // The .grd ID of the string to replace $1 in |id|'s string. If zero or - // omitted (default initialized), no substitution is attempted. - int substitution_id; - }; - - // A helper to simplify string registration in WebUI for strings which do not - // change at runtime and optionally contain a single substitution. - static void RegisterStrings(base::DictionaryValue* localized_strings, - const OptionsStringResource* resources, - size_t length); - - // Registers string resources for a page's header and tab title. - static void RegisterTitle(base::DictionaryValue* localized_strings, - const std::string& variable_name, - int title_id); - - content::NotificationRegistrar registrar_; - - private: - DISALLOW_COPY_AND_ASSIGN(OptionsPageUIHandler); -}; - -// An interface for common operations that a host of OptionsPageUIHandlers -// should provide. -class OptionsPageUIHandlerHost { - public: - virtual void InitializeHandlers() = 0; - virtual void OnFinishedLoading() {} - - protected: - virtual ~OptionsPageUIHandlerHost() {} -}; - -// The WebUI for chrome:settings-frame. -class OptionsUI : public content::WebUIController, - public content::WebContentsObserver, - public OptionsPageUIHandlerHost { - public: - typedef base::CallbackList<void()> OnFinishedLoadingCallbackList; - - explicit OptionsUI(content::WebUI* web_ui); - ~OptionsUI() override; - - // Registers a callback to be called once the settings frame has finished - // loading on the HTML/JS side. - std::unique_ptr<OnFinishedLoadingCallbackList::Subscription> - RegisterOnFinishedLoadingCallback(const base::Closure& callback); - - // Takes the suggestions from |result| and adds them to |suggestions| so that - // they can be passed to a JavaScript function. - static void ProcessAutocompleteSuggestions( - const AutocompleteResult& result, - base::ListValue* const suggestions); - - // Overridden from content::WebContentsObserver: - void ReadyToCommitNavigation( - content::NavigationHandle* navigation_handle) override; - void DocumentLoadedInFrame( - content::RenderFrameHost *render_frame_host) override; - void DocumentOnLoadCompletedInMainFrame() override; - - // Overridden from OptionsPageUIHandlerHost: - void InitializeHandlers() override; - void OnFinishedLoading() override; - - private: - // Adds OptionsPageUiHandler to the handlers list if handler is enabled. - void AddOptionsPageUIHandler(base::DictionaryValue* localized_strings, - OptionsPageUIHandler* handler); - - bool initialized_handlers_; - - std::vector<OptionsPageUIHandler*> handlers_; - OnFinishedLoadingCallbackList on_finished_loading_callbacks_; - -#if defined(OS_CHROMEOS) - std::unique_ptr<chromeos::system::PointerDeviceObserver> - pointer_device_observer_; -#endif - - base::Time load_start_time_; - - DISALLOW_COPY_AND_ASSIGN(OptionsUI); -}; - -} // namespace options - -#endif // CHROME_BROWSER_UI_WEBUI_OPTIONS_OPTIONS_UI_H_
diff --git a/chrome/browser/ui/webui/options/password_manager_handler.cc b/chrome/browser/ui/webui/options/password_manager_handler.cc deleted file mode 100644 index 8503529..0000000 --- a/chrome/browser/ui/webui/options/password_manager_handler.cc +++ /dev/null
@@ -1,398 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/webui/options/password_manager_handler.h" - -#include <memory> -#include <tuple> -#include <utility> - -#include "base/bind.h" -#include "base/command_line.h" -#include "base/feature_list.h" -#include "base/files/file_path.h" -#include "base/macros.h" -#include "base/metrics/field_trial.h" -#include "base/metrics/histogram_macros.h" -#include "base/strings/string_number_conversions.h" -#include "base/strings/string_split.h" -#include "base/strings/utf_string_conversions.h" -#include "base/values.h" -#include "build/build_config.h" -#include "chrome/browser/chrome_notification_types.h" -#include "chrome/browser/password_manager/password_store_factory.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/sync/profile_sync_service_factory.h" -#include "chrome/browser/ui/chrome_select_file_policy.h" -#include "chrome/common/pref_names.h" -#include "chrome/common/url_constants.h" -#include "chrome/grit/generated_resources.h" -#include "components/autofill/core/common/password_form.h" -#include "components/browser_sync/profile_sync_service.h" -#include "components/password_manager/core/browser/android_affiliation/affiliation_utils.h" -#include "components/password_manager/core/browser/export/password_exporter.h" -#include "components/password_manager/core/browser/password_bubble_experiment.h" -#include "components/password_manager/core/browser/password_manager_constants.h" -#include "components/password_manager/core/browser/password_store.h" -#include "components/password_manager/core/browser/password_ui_utils.h" -#include "components/password_manager/core/common/experiments.h" -#include "components/password_manager/core/common/password_manager_features.h" -#include "components/prefs/pref_service.h" -#include "components/strings/grit/components_strings.h" -#include "components/url_formatter/url_formatter.h" -#include "content/public/browser/notification_details.h" -#include "content/public/browser/notification_source.h" -#include "content/public/browser/web_contents.h" -#include "content/public/browser/web_ui.h" -#include "content/public/common/origin_util.h" -#include "ui/base/l10n/l10n_util.h" -#include "url/gurl.h" - -namespace options { - -namespace { -// The following constants should be synchronized with the constants in -// chrome/browser/resources/options/password_manager_list.js. -const char kUrlField[] = "url"; -const char kShownOriginField[] = "shownOrigin"; -const char kIsAndroidUriField[] = "isAndroidUri"; -const char kIsClickable[] = "isClickable"; -const char kIsSecureField[] = "isSecure"; -const char kUsernameField[] = "username"; -const char kPasswordField[] = "password"; -const char kFederationField[] = "federation"; - -// Copies from |form| to |entry| the origin, shown origin, whether the origin is -// Android URI, and whether the origin is secure. -void CopyOriginInfoOfPasswordForm(const autofill::PasswordForm& form, - base::DictionaryValue* entry) { - std::string shown_origin; - GURL link_url; - std::tie(shown_origin, link_url) = - password_manager::GetShownOriginAndLinkUrl(form); - entry->SetString(kShownOriginField, shown_origin); - DCHECK(link_url.is_valid()); - entry->SetString(kUrlField, - url_formatter::FormatUrl( - link_url, url_formatter::kFormatUrlOmitNothing, - net::UnescapeRule::SPACES, nullptr, nullptr, nullptr)); - entry->SetBoolean( - kIsAndroidUriField, - password_manager::IsValidAndroidFacetURI(form.signon_realm)); - entry->SetBoolean(kIsClickable, true); - entry->SetBoolean(kIsSecureField, content::IsOriginSecure(link_url)); -} - -} // namespace - -PasswordManagerHandler::PasswordManagerHandler() { - password_manager_presenter_.reset(new PasswordManagerPresenter(this)); -} - -PasswordManagerHandler::PasswordManagerHandler( - std::unique_ptr<PasswordManagerPresenter> presenter) - : password_manager_presenter_(std::move(presenter)) {} - -PasswordManagerHandler::~PasswordManagerHandler() {} - -Profile* PasswordManagerHandler::GetProfile() { - return Profile::FromWebUI(web_ui()); -} - -#if !defined(OS_ANDROID) -gfx::NativeWindow PasswordManagerHandler::GetNativeWindow() const { - return web_ui()->GetWebContents()->GetTopLevelNativeWindow(); -} -#endif - -void PasswordManagerHandler::GetLocalizedValues( - base::DictionaryValue* localized_strings) { - DCHECK(localized_strings); - - static const OptionsStringResource resources[] = { - {"androidUriSuffix", IDS_PASSWORDS_ANDROID_URI_SUFFIX}, - {"autoSigninTitle", IDS_PASSWORDS_AUTO_SIGNIN_TITLE}, - {"autoSigninDescription", IDS_PASSWORDS_AUTO_SIGNIN_DESCRIPTION}, - {"savedPasswordsTitle", IDS_PASSWORD_MANAGER_SHOW_PASSWORDS_TAB_TITLE}, - {"passwordExceptionsTitle", IDS_PASSWORD_MANAGER_EXCEPTIONS_TAB_TITLE}, - {"passwordSearchPlaceholder", IDS_PASSWORDS_PAGE_SEARCH_PASSWORDS}, - {"passwordShowButton", IDS_PASSWORDS_PAGE_VIEW_SHOW_BUTTON}, - {"passwordHideButton", IDS_PASSWORDS_PAGE_VIEW_HIDE_BUTTON}, - {"passwordsNoPasswordsDescription", - IDS_PASSWORDS_PAGE_VIEW_NO_PASSWORDS_DESCRIPTION}, - {"passwordsNoExceptionsDescription", - IDS_PASSWORDS_PAGE_VIEW_NO_EXCEPTIONS_DESCRIPTION}, - {"passwordManagerImportPasswordButtonText", - IDS_PASSWORD_MANAGER_IMPORT_BUTTON}, - {"passwordManagerExportPasswordButtonText", - IDS_PASSWORD_MANAGER_EXPORT_BUTTON}, - }; - - RegisterStrings(localized_strings, resources, arraysize(resources)); - - RegisterTitle(localized_strings, "passwordsPage", - IDS_PASSWORDS_EXCEPTIONS_WINDOW_TITLE); - - localized_strings->SetString("passwordManagerLearnMoreURL", - chrome::kPasswordManagerLearnMoreURL); - localized_strings->SetString( - "passwordsManagePasswordsLink", - password_manager::kPasswordManagerAccountDashboardURL); - - std::string management_hostname = - GURL(password_manager::kPasswordManagerAccountDashboardURL).host(); - base::string16 link_text = base::UTF8ToUTF16(management_hostname); - size_t offset; - base::string16 full_text = l10n_util::GetStringFUTF16( - IDS_MANAGE_PASSWORDS_REMOTE_TEXT, link_text, &offset); - - localized_strings->SetString("passwordsManagePasswordsBeforeLinkText", - full_text.substr(0, offset)); - localized_strings->SetString("passwordsManagePasswordsLinkText", - full_text.substr(offset, link_text.size())); - localized_strings->SetString("passwordsManagePasswordsAfterLinkText", - full_text.substr(offset + link_text.size())); - - bool disable_show_passwords = false; - -#if defined(OS_WIN) && defined(USE_ASH) - // We disable the ability to show passwords when running in Windows Metro - // interface. This is because we cannot pop native Win32 dialogs from the - // Metro process. - // TODO(wfh): Revisit this if Metro usage grows. - if (chrome::IsNativeWindowInAsh(GetNativeWindow())) - disable_show_passwords = true; -#endif - - localized_strings->SetBoolean("disableShowPasswords", disable_show_passwords); -} - -void PasswordManagerHandler::RegisterMessages() { - web_ui()->RegisterMessageCallback( - "updatePasswordLists", - base::Bind(&PasswordManagerHandler::HandleUpdatePasswordLists, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "removeSavedPassword", - base::Bind(&PasswordManagerHandler::HandleRemoveSavedPassword, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "removePasswordException", - base::Bind(&PasswordManagerHandler::HandleRemovePasswordException, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "requestShowPassword", - base::Bind(&PasswordManagerHandler::HandleRequestShowPassword, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "importPassword", - base::Bind(&PasswordManagerHandler::HandlePasswordImport, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "exportPassword", - base::Bind(&PasswordManagerHandler::HandlePasswordExport, - base::Unretained(this))); -} - -void PasswordManagerHandler::InitializeHandler() { - password_manager_presenter_->Initialize(); -} - -void PasswordManagerHandler::InitializePage() { - if (base::FeatureList::IsEnabled( - password_manager::features::kPasswordImportExport)) { - web_ui()->CallJavascriptFunctionUnsafe( - "PasswordManager.showImportExportButton"); - } -} - -void PasswordManagerHandler::HandleRemoveSavedPassword( - const base::ListValue* args) { - std::string string_value = base::UTF16ToUTF8(ExtractStringValue(args)); - int index; - if (base::StringToInt(string_value, &index) && index >= 0) { - password_manager_presenter_->RemoveSavedPassword( - static_cast<size_t>(index)); - } -} - -void PasswordManagerHandler::HandleRemovePasswordException( - const base::ListValue* args) { - std::string string_value = base::UTF16ToUTF8(ExtractStringValue(args)); - int index; - if (base::StringToInt(string_value, &index) && index >= 0) { - password_manager_presenter_->RemovePasswordException( - static_cast<size_t>(index)); - } -} - -void PasswordManagerHandler::HandleRequestShowPassword( - const base::ListValue* args) { - int index; - if (!ExtractIntegerValue(args, &index)) - NOTREACHED(); - - password_manager_presenter_->RequestShowPassword(static_cast<size_t>(index)); -} - -void PasswordManagerHandler::ShowPassword( - size_t index, - const std::string& origin_url, - const std::string& username, - const base::string16& password_value) { - // Call back the front end to reveal the password. - web_ui()->CallJavascriptFunctionUnsafe("PasswordManager.showPassword", - base::Value(static_cast<int>(index)), - base::Value(password_value)); -} - -void PasswordManagerHandler::HandleUpdatePasswordLists( - const base::ListValue* args) { - password_manager_presenter_->UpdatePasswordLists(); -} - -void PasswordManagerHandler::SetPasswordList( - const std::vector<std::unique_ptr<autofill::PasswordForm>>& password_list) { - base::ListValue entries; - base::string16 placeholder(base::ASCIIToUTF16(" ")); - for (const auto& saved_password : password_list) { - std::unique_ptr<base::DictionaryValue> entry(new base::DictionaryValue); - CopyOriginInfoOfPasswordForm(*saved_password, entry.get()); - - entry->SetString(kUsernameField, saved_password->username_value); - // Use a placeholder value with the same length as the password. - entry->SetString( - kPasswordField, - base::string16(saved_password->password_value.length(), ' ')); - if (!saved_password->federation_origin.unique()) { - entry->SetString( - kFederationField, - l10n_util::GetStringFUTF16( - IDS_PASSWORDS_VIA_FEDERATION, - base::UTF8ToUTF16(saved_password->federation_origin.host()))); - } - - entries.Append(std::move(entry)); - } - - web_ui()->CallJavascriptFunctionUnsafe( - "PasswordManager.setSavedPasswordsList", entries); -} - -void PasswordManagerHandler::SetPasswordExceptionList( - const std::vector<std::unique_ptr<autofill::PasswordForm>>& - password_exception_list) { - base::ListValue entries; - for (const auto& exception : password_exception_list) { - std::unique_ptr<base::DictionaryValue> entry(new base::DictionaryValue); - CopyOriginInfoOfPasswordForm(*exception, entry.get()); - entries.Append(std::move(entry)); - } - - web_ui()->CallJavascriptFunctionUnsafe( - "PasswordManager.setPasswordExceptionsList", entries); -} - -void PasswordManagerHandler::FileSelected(const base::FilePath& path, - int index, - void* params) { - switch (static_cast<FileSelectorCaller>(reinterpret_cast<intptr_t>(params))) { - case IMPORT_FILE_SELECTED: - ImportPasswordFileSelected(path); - break; - case EXPORT_FILE_SELECTED: - ExportPasswordFileSelected(path); - break; - } -} - -void PasswordManagerHandler::HandlePasswordImport(const base::ListValue* args) { -#if !defined(OS_ANDROID) // This is never called on Android. - ui::SelectFileDialog::FileTypeInfo file_type_info; - - file_type_info.extensions = - password_manager::PasswordImporter::GetSupportedFileExtensions(); - DCHECK(!file_type_info.extensions.empty() && - !file_type_info.extensions[0].empty()); - file_type_info.include_all_files = true; - select_file_dialog_ = ui::SelectFileDialog::Create( - this, new ChromeSelectFilePolicy(web_ui()->GetWebContents())); - select_file_dialog_->SelectFile( - ui::SelectFileDialog::SELECT_OPEN_FILE, - l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_IMPORT_DIALOG_TITLE), - base::FilePath(), &file_type_info, 1, file_type_info.extensions[0][0], - web_ui()->GetWebContents()->GetTopLevelNativeWindow(), - reinterpret_cast<void*>(IMPORT_FILE_SELECTED)); -#endif -} - -void PasswordManagerHandler::ImportPasswordFileSelected( - const base::FilePath& path) { - scoped_refptr<ImportPasswordResultConsumer> form_consumer( - new ImportPasswordResultConsumer(GetProfile())); - - password_manager::PasswordImporter::Import( - path, base::Bind(&ImportPasswordResultConsumer::ConsumePassword, - form_consumer)); -} - -PasswordManagerHandler::ImportPasswordResultConsumer:: - ImportPasswordResultConsumer(Profile* profile) - : profile_(profile) {} - -void PasswordManagerHandler::ImportPasswordResultConsumer::ConsumePassword( - password_manager::PasswordImporter::Result result, - const std::vector<autofill::PasswordForm>& forms) { - UMA_HISTOGRAM_ENUMERATION( - "PasswordManager.ImportPasswordFromCSVResult", result, - password_manager::PasswordImporter::NUM_IMPORT_RESULTS); - if (result != password_manager::PasswordImporter::SUCCESS) - return; - - UMA_HISTOGRAM_COUNTS("PasswordManager.ImportedPasswordsPerUserInCSV", - forms.size()); - - scoped_refptr<password_manager::PasswordStore> store( - PasswordStoreFactory::GetForProfile(profile_, - ServiceAccessType::EXPLICIT_ACCESS)); - if (store) { - for (const autofill::PasswordForm& form : forms) { - store->AddLogin(form); - } - } - UMA_HISTOGRAM_BOOLEAN("PasswordManager.StorePasswordImportedFromCSVResult", - static_cast<bool>(store)); -} - -void PasswordManagerHandler::HandlePasswordExport(const base::ListValue* args) { -#if !defined(OS_ANDROID) // This is never called on Android. - if (!password_manager_presenter_->IsUserAuthenticated()) - return; - - ui::SelectFileDialog::FileTypeInfo file_type_info; - file_type_info.extensions = - password_manager::PasswordExporter::GetSupportedFileExtensions(); - DCHECK(!file_type_info.extensions.empty() && - !file_type_info.extensions[0].empty()); - file_type_info.include_all_files = true; - select_file_dialog_ = ui::SelectFileDialog::Create( - this, new ChromeSelectFilePolicy(web_ui()->GetWebContents())); - select_file_dialog_->SelectFile( - ui::SelectFileDialog::SELECT_SAVEAS_FILE, - l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_EXPORT_DIALOG_TITLE), - base::FilePath(), &file_type_info, 1, file_type_info.extensions[0][0], - GetNativeWindow(), reinterpret_cast<void*>(EXPORT_FILE_SELECTED)); -#endif -} - -void PasswordManagerHandler::ExportPasswordFileSelected( - const base::FilePath& path) { - std::vector<std::unique_ptr<autofill::PasswordForm>> password_list = - password_manager_presenter_->GetAllPasswords(); - UMA_HISTOGRAM_COUNTS("PasswordManager.ExportedPasswordsPerUserInCSV", - password_list.size()); - password_manager::PasswordExporter::Export(path, password_list); -} - -} // namespace options
diff --git a/chrome/browser/ui/webui/options/password_manager_handler.h b/chrome/browser/ui/webui/options/password_manager_handler.h deleted file mode 100644 index 5442df96..0000000 --- a/chrome/browser/ui/webui/options/password_manager_handler.h +++ /dev/null
@@ -1,138 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_WEBUI_OPTIONS_PASSWORD_MANAGER_HANDLER_H_ -#define CHROME_BROWSER_UI_WEBUI_OPTIONS_PASSWORD_MANAGER_HANDLER_H_ - -#include <stddef.h> - -#include <string> -#include <vector> - -#include "base/gtest_prod_util.h" -#include "base/macros.h" -#include "build/build_config.h" -#include "chrome/browser/ui/passwords/password_manager_presenter.h" -#include "chrome/browser/ui/passwords/password_ui_view.h" -#include "chrome/browser/ui/webui/options/options_ui.h" -#include "components/password_manager/core/browser/import/password_importer.h" -#include "components/prefs/pref_member.h" -#include "ui/shell_dialogs/select_file_dialog.h" - -namespace options { - -// The WebUI based PasswordUIView. Displays passwords in the web ui. -class PasswordManagerHandler : public OptionsPageUIHandler, - public PasswordUIView, - public ui::SelectFileDialog::Listener { - public: - // Enumeration of different callers of SelectFile. - enum FileSelectorCaller { - IMPORT_FILE_SELECTED, - EXPORT_FILE_SELECTED, - }; - - PasswordManagerHandler(); - ~PasswordManagerHandler() override; - - // OptionsPageUIHandler implementation. - void GetLocalizedValues(base::DictionaryValue* localized_strings) override; - void InitializeHandler() override; - void InitializePage() override; - void RegisterMessages() override; - - // ui::SelectFileDialog::Listener implementation. - // |params| is of type FileSelectorCaller which indicates direction of IO. - void FileSelected(const base::FilePath& path, - int index, - void* params) override; - - // PasswordUIView implementation. - Profile* GetProfile() override; - void ShowPassword( - size_t index, - const std::string& origin_url, - const std::string& username, - const base::string16& password_value) override; - void SetPasswordList( - const std::vector<std::unique_ptr<autofill::PasswordForm>>& password_list) - override; - void SetPasswordExceptionList( - const std::vector<std::unique_ptr<autofill::PasswordForm>>& - password_exception_list) override; -#if !defined(OS_ANDROID) - gfx::NativeWindow GetNativeWindow() const override; -#endif - - protected: - // This constructor is used for testing only. - explicit PasswordManagerHandler( - std::unique_ptr<PasswordManagerPresenter> presenter); - - private: - // Clears and then populates the list of passwords and password exceptions. - // Called when the JS PasswordManager object is initialized. - void HandleUpdatePasswordLists(const base::ListValue* args); - - // Removes a saved password entry. - // |value| the entry index to be removed. - void HandleRemoveSavedPassword(const base::ListValue* args); - - // Removes a saved password exception. - // |value| the entry index to be removed. - void HandleRemovePasswordException(const base::ListValue* args); - - // Requests the plain text password for an entry to be revealed. - // |index| The index of the entry. - void HandleRequestShowPassword(const base::ListValue* args); - - // Import from CSV/JSON file. The steps are: - // 1. user click import button -> HandlePasswordImport() -> - // start file selector - // 2. user selects file -> ImportPasswordFileSeleted() -> read to memory - // 3. read completes -> ImportPasswordFileRead() -> store to PasswordStore - void HandlePasswordImport(const base::ListValue* args); - void ImportPasswordFileSelected(const base::FilePath& path); - void ImportPasswordFileRead(password_manager::PasswordImporter::Result result, - const std::vector<autofill::PasswordForm>& forms); - - // Export to CSV/JSON file. The steps are: - // 1. user click export button -> HandlePasswordExport() -> - // check OS password if necessary -> start file selector - // 2. user selects file -> ExportPasswordFileSeleted() -> - // write to memory buffer -> start write operation - void HandlePasswordExport(const base::ListValue* args); - void ExportPasswordFileSelected(const base::FilePath& path); - - // A short class to persist imported password forms to password store. - class ImportPasswordResultConsumer - : public base::RefCountedThreadSafe<ImportPasswordResultConsumer> { - public: - explicit ImportPasswordResultConsumer(Profile* profile); - - void ConsumePassword(password_manager::PasswordImporter::Result result, - const std::vector<autofill::PasswordForm>& forms); - - private: - friend class base::RefCountedThreadSafe<ImportPasswordResultConsumer>; - - ~ImportPasswordResultConsumer() {} - - Profile* profile_; - }; - - // User pref for storing accept languages. - std::string languages_; - - std::unique_ptr<PasswordManagerPresenter> password_manager_presenter_; - - // File picker to import/export file path. - scoped_refptr<ui::SelectFileDialog> select_file_dialog_; - - DISALLOW_COPY_AND_ASSIGN(PasswordManagerHandler); -}; - -} // namespace options - -#endif // CHROME_BROWSER_UI_WEBUI_OPTIONS_PASSWORD_MANAGER_HANDLER_H_
diff --git a/chrome/browser/ui/webui/options/pepper_flash_content_settings_utils.cc b/chrome/browser/ui/webui/options/pepper_flash_content_settings_utils.cc deleted file mode 100644 index 542498b..0000000 --- a/chrome/browser/ui/webui/options/pepper_flash_content_settings_utils.cc +++ /dev/null
@@ -1,130 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/webui/options/pepper_flash_content_settings_utils.h" - -#include <algorithm> -#include <memory> - -namespace options { - -namespace { - -int CompareMediaException(const MediaException& i, const MediaException& j) { - return i.pattern.Compare(j.pattern); -} - -bool MediaExceptionSortFunc(const MediaException& i, const MediaException& j) { - return CompareMediaException(i, j) < 0; -} - -} // namespace - -MediaException::MediaException(const ContentSettingsPattern& in_pattern, - ContentSetting in_setting) - : pattern(in_pattern), - setting(in_setting) { -} - -MediaException::~MediaException() { -} - -bool MediaException::operator==(const MediaException& other) const { - return pattern == other.pattern && setting == other.setting; -} - -// static -ContentSetting PepperFlashContentSettingsUtils::FlashPermissionToContentSetting( - PP_Flash_BrowserOperations_Permission permission) { - switch (permission) { - case PP_FLASH_BROWSEROPERATIONS_PERMISSION_DEFAULT: - return CONTENT_SETTING_DEFAULT; - case PP_FLASH_BROWSEROPERATIONS_PERMISSION_ALLOW: - return CONTENT_SETTING_ALLOW; - case PP_FLASH_BROWSEROPERATIONS_PERMISSION_BLOCK: - return CONTENT_SETTING_BLOCK; - case PP_FLASH_BROWSEROPERATIONS_PERMISSION_ASK: - return CONTENT_SETTING_ASK; - // No default so the compiler will warn us if a new type is added. - } - return CONTENT_SETTING_DEFAULT; -} - -// static -void PepperFlashContentSettingsUtils::FlashSiteSettingsToMediaExceptions( - const ppapi::FlashSiteSettings& site_settings, - MediaExceptions* media_exceptions) { - media_exceptions->clear(); - - std::unique_ptr<ContentSettingsPattern::BuilderInterface> builder = - ContentSettingsPattern::CreateBuilder(); - builder->WithSchemeWildcard()->WithPortWildcard(); - for (ppapi::FlashSiteSettings::const_iterator iter = site_settings.begin(); - iter != site_settings.end(); ++iter) { - builder->WithHost(iter->site); - - ContentSettingsPattern pattern = builder->Build(); - if (!pattern.IsValid()) - continue; - - ContentSetting setting = FlashPermissionToContentSetting(iter->permission); - - media_exceptions->push_back(MediaException(pattern, setting)); - } -} - -// static -void PepperFlashContentSettingsUtils::SortMediaExceptions( - MediaExceptions* media_exceptions) { - std::sort(media_exceptions->begin(), media_exceptions->end(), - MediaExceptionSortFunc); -} - -// static -bool PepperFlashContentSettingsUtils::AreMediaExceptionsEqual( - ContentSetting default_setting_1, - const MediaExceptions& exceptions_1, - ContentSetting default_setting_2, - const MediaExceptions& exceptions_2) { - MediaExceptions::const_iterator iter_1 = exceptions_1.begin(); - MediaExceptions::const_iterator iter_2 = exceptions_2.begin(); - - MediaException default_exception_1(ContentSettingsPattern(), - default_setting_1); - MediaException default_exception_2(ContentSettingsPattern(), - default_setting_2); - - while (iter_1 != exceptions_1.end() && iter_2 != exceptions_2.end()) { - int compare_result = CompareMediaException(*iter_1, *iter_2); - if (compare_result < 0) { - if (iter_1->setting != default_exception_2.setting) - return false; - ++iter_1; - } else if (compare_result > 0) { - if (iter_2->setting != default_exception_1.setting) { - return false; - } - ++iter_2; - } else { - if (iter_1->setting != iter_2->setting) - return false; - ++iter_1; - ++iter_2; - } - } - - while (iter_1 != exceptions_1.end()) { - if (iter_1->setting != default_exception_2.setting) - return false; - ++iter_1; - } - while (iter_2 != exceptions_2.end()) { - if (iter_2->setting != default_exception_1.setting) - return false; - ++iter_2; - } - return true; -} - -} // namespace options
diff --git a/chrome/browser/ui/webui/options/pepper_flash_content_settings_utils.h b/chrome/browser/ui/webui/options/pepper_flash_content_settings_utils.h deleted file mode 100644 index 1e488239..0000000 --- a/chrome/browser/ui/webui/options/pepper_flash_content_settings_utils.h +++ /dev/null
@@ -1,62 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_WEBUI_OPTIONS_PEPPER_FLASH_CONTENT_SETTINGS_UTILS_H_ -#define CHROME_BROWSER_UI_WEBUI_OPTIONS_PEPPER_FLASH_CONTENT_SETTINGS_UTILS_H_ - -#include <vector> - -#include "base/macros.h" -#include "components/content_settings/core/common/content_settings.h" -#include "components/content_settings/core/common/content_settings_pattern.h" -#include "ppapi/c/private/ppp_flash_browser_operations.h" -#include "ppapi/shared_impl/ppp_flash_browser_operations_shared.h" - -namespace options { - -struct MediaException { - MediaException(const ContentSettingsPattern& in_pattern, - ContentSetting in_setting); - ~MediaException(); - - bool operator==(const MediaException& other) const; - - ContentSettingsPattern pattern; - ContentSetting setting; -}; - -typedef std::vector<MediaException> MediaExceptions; - -class PepperFlashContentSettingsUtils { - public: - static ContentSetting FlashPermissionToContentSetting( - PP_Flash_BrowserOperations_Permission permission); - - static void FlashSiteSettingsToMediaExceptions( - const ppapi::FlashSiteSettings& site_settings, - MediaExceptions* media_exceptions); - - // Sorts |media_exceptions| in ascending order by comparing the |pattern| - // field of the elements. - static void SortMediaExceptions(MediaExceptions* media_exceptions); - - // Checks whether |exceptions_1| and |exceptions_2| describe the same set of - // exceptions. |exceptions_1| and |exceptions_2| should be sorted by - // SortMediaExceptions() before passing into this method. - // - // When an element of |exceptions_1| has a pattern that doesn't match any - // element of |exceptions_2|, it would be compared with |default_setting_2|, - // and vice versa. - static bool AreMediaExceptionsEqual(ContentSetting default_setting_1, - const MediaExceptions& exceptions_1, - ContentSetting default_setting_2, - const MediaExceptions& exceptions_2); - - private: - DISALLOW_IMPLICIT_CONSTRUCTORS(PepperFlashContentSettingsUtils); -}; - -} // namespace options - -#endif // CHROME_BROWSER_UI_WEBUI_OPTIONS_PEPPER_FLASH_CONTENT_SETTINGS_UTILS_H_
diff --git a/chrome/browser/ui/webui/options/reset_profile_settings_handler.cc b/chrome/browser/ui/webui/options/reset_profile_settings_handler.cc deleted file mode 100644 index bc254c36..0000000 --- a/chrome/browser/ui/webui/options/reset_profile_settings_handler.cc +++ /dev/null
@@ -1,269 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/webui/options/reset_profile_settings_handler.h" - -#include <utility> - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/macros.h" -#include "base/metrics/histogram_macros.h" -#include "base/metrics/user_metrics.h" -#include "base/strings/string16.h" -#include "base/values.h" -#include "build/build_config.h" -#include "chrome/browser/google/google_brand.h" -#include "chrome/browser/profile_resetter/brandcode_config_fetcher.h" -#include "chrome/browser/profile_resetter/brandcoded_default_settings.h" -#include "chrome/browser/profile_resetter/profile_resetter.h" -#include "chrome/browser/profile_resetter/resettable_settings_snapshot.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/common/url_constants.h" -#include "chrome/grit/chromium_strings.h" -#include "chrome/grit/generated_resources.h" -#include "components/prefs/pref_service.h" -#include "components/strings/grit/components_strings.h" -#include "content/public/browser/web_ui.h" -#include "ui/base/l10n/l10n_util.h" - -#if defined(OS_WIN) -#include "chrome/browser/profile_resetter/triggered_profile_resetter.h" -#include "chrome/browser/profile_resetter/triggered_profile_resetter_factory.h" -#endif // defined(OS_WIN) - -namespace options { - -namespace { - -reset_report::ChromeResetReport::ResetRequestOrigin -ResetRequestOriginFromString(const std::string& reset_request_origin) { - static const char kOriginUserClick[] = "userclick"; - static const char kOriginTriggeredReset[] = "triggeredreset"; - - if (reset_request_origin == - ResetProfileSettingsHandler::kCctResetSettingsHash) { - return reset_report::ChromeResetReport::RESET_REQUEST_ORIGIN_CCT; - } - if (reset_request_origin == kOriginUserClick) - return reset_report::ChromeResetReport::RESET_REQUEST_ORIGIN_USER_CLICK; - if (reset_request_origin == kOriginTriggeredReset) { - return reset_report::ChromeResetReport:: - RESET_REQUEST_ORIGIN_TRIGGERED_RESET; - } - if (!reset_request_origin.empty()) - NOTREACHED(); - - return reset_report::ChromeResetReport::RESET_REQUEST_ORIGIN_UNKNOWN; -} - -} // namespace - -const char ResetProfileSettingsHandler::kCctResetSettingsHash[] = "cct"; - -ResetProfileSettingsHandler::ResetProfileSettingsHandler() { - google_brand::GetBrand(&brandcode_); -} - -ResetProfileSettingsHandler::~ResetProfileSettingsHandler() {} - -void ResetProfileSettingsHandler::InitializeHandler() { - Profile* profile = Profile::FromWebUI(web_ui()); - resetter_.reset(new ProfileResetter(profile)); -} - -void ResetProfileSettingsHandler::InitializePage() { - web_ui()->CallJavascriptFunctionUnsafe( - "ResetProfileSettingsOverlay.setResettingState", - base::Value(resetter_->IsActive())); -} - -void ResetProfileSettingsHandler::GetLocalizedValues( - base::DictionaryValue* localized_strings) { - DCHECK(localized_strings); - - static OptionsStringResource resources[] = { - { "resetProfileSettingsCommit", IDS_RESET_PROFILE_SETTINGS_COMMIT_BUTTON }, - { "resetProfileSettingsExplanation", - IDS_RESET_PROFILE_SETTINGS_EXPLANATION }, - { "resetProfileSettingsFeedback", IDS_RESET_PROFILE_SETTINGS_FEEDBACK } - }; - - RegisterStrings(localized_strings, resources, arraysize(resources)); - RegisterTitle(localized_strings, "resetProfileSettingsOverlay", - IDS_RESET_PROFILE_SETTINGS_TITLE); - localized_strings->SetString( - "resetProfileSettingsLearnMoreUrl", - chrome::kResetProfileSettingsLearnMoreURL); - - // Set up the localized strings for the triggered profile reset overlay. - // The reset tool name can currently only have a custom value on Windows. - base::string16 reset_tool_name; -#if defined(OS_WIN) - Profile* profile = Profile::FromWebUI(web_ui()); - TriggeredProfileResetter* triggered_profile_resetter = - TriggeredProfileResetterFactory::GetForBrowserContext(profile); - // TriggeredProfileResetter instance will be nullptr for incognito profiles. - if (triggered_profile_resetter) { - reset_tool_name = triggered_profile_resetter->GetResetToolName(); - - // Now that a reset UI has been shown, don't trigger again for this profile. - triggered_profile_resetter->ClearResetTrigger(); - } -#endif - - if (reset_tool_name.empty()) { - reset_tool_name = l10n_util::GetStringUTF16( - IDS_TRIGGERED_RESET_PROFILE_SETTINGS_DEFAULT_TOOL_NAME); - } - localized_strings->SetString( - "triggeredResetProfileSettingsOverlay", - l10n_util::GetStringFUTF16(IDS_TRIGGERED_RESET_PROFILE_SETTINGS_TITLE, - reset_tool_name)); - // Set the title manually since RegisterTitle() wants an id. - base::string16 title_string(l10n_util::GetStringFUTF16( - IDS_TRIGGERED_RESET_PROFILE_SETTINGS_TITLE, reset_tool_name)); - localized_strings->SetString("triggeredResetProfileSettingsOverlay", - title_string); - localized_strings->SetString( - "triggeredResetProfileSettingsOverlayTabTitle", - l10n_util::GetStringFUTF16(IDS_OPTIONS_TAB_TITLE, - l10n_util::GetStringUTF16(IDS_SETTINGS_TITLE), - title_string)); - localized_strings->SetString( - "triggeredResetProfileSettingsExplanation", - l10n_util::GetStringFUTF16( - IDS_TRIGGERED_RESET_PROFILE_SETTINGS_EXPLANATION, reset_tool_name)); -} - -void ResetProfileSettingsHandler::RegisterMessages() { - // Setup handlers specific to this panel. - web_ui()->RegisterMessageCallback("performResetProfileSettings", - base::Bind(&ResetProfileSettingsHandler::HandleResetProfileSettings, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("onShowResetProfileDialog", - base::Bind(&ResetProfileSettingsHandler::OnShowResetProfileDialog, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("onHideResetProfileDialog", - base::Bind(&ResetProfileSettingsHandler::OnHideResetProfileDialog, - base::Unretained(this))); -} - -void ResetProfileSettingsHandler::HandleResetProfileSettings( - const base::ListValue* value) { - bool send_settings = false; - std::string request_origin_string; - bool success = value->GetBoolean(0, &send_settings) && - value->GetString(1, &request_origin_string); - DCHECK(success); - - DCHECK(brandcode_.empty() || config_fetcher_); - reset_report::ChromeResetReport::ResetRequestOrigin request_origin = - ResetRequestOriginFromString(request_origin_string); - if (config_fetcher_ && config_fetcher_->IsActive()) { - // Reset once the prefs are fetched. - config_fetcher_->SetCallback( - base::Bind(&ResetProfileSettingsHandler::ResetProfile, Unretained(this), - send_settings, request_origin)); - } else { - ResetProfile(send_settings, request_origin); - } -} - -void ResetProfileSettingsHandler::OnResetProfileSettingsDone( - bool send_feedback, - reset_report::ChromeResetReport::ResetRequestOrigin request_origin) { - web_ui()->CallJavascriptFunctionUnsafe( - "ResetProfileSettingsOverlay.doneResetting"); - - if (send_feedback && setting_snapshot_) { - Profile* profile = Profile::FromWebUI(web_ui()); - ResettableSettingsSnapshot current_snapshot(profile); - int difference = setting_snapshot_->FindDifferentFields(current_snapshot); - if (difference) { - setting_snapshot_->Subtract(current_snapshot); - std::unique_ptr<reset_report::ChromeResetReport> report_proto = - SerializeSettingsReportToProto(*setting_snapshot_, difference); - if (report_proto) { - report_proto->set_reset_request_origin(request_origin); - SendSettingsFeedbackProto(*report_proto, profile); - } - } - } - setting_snapshot_.reset(); -} - -void ResetProfileSettingsHandler::OnShowResetProfileDialog( - const base::ListValue* value) { - if (!resetter_->IsActive()) { - setting_snapshot_.reset( - new ResettableSettingsSnapshot(Profile::FromWebUI(web_ui()))); - setting_snapshot_->RequestShortcuts(base::Bind( - &ResetProfileSettingsHandler::UpdateFeedbackUI, AsWeakPtr())); - UpdateFeedbackUI(); - } - - if (brandcode_.empty()) - return; - config_fetcher_.reset(new BrandcodeConfigFetcher( - base::Bind(&ResetProfileSettingsHandler::OnSettingsFetched, - Unretained(this)), - GURL("https://tools.google.com/service/update2"), - brandcode_)); -} - -void ResetProfileSettingsHandler::OnHideResetProfileDialog( - const base::ListValue* value) { - if (!resetter_->IsActive()) - setting_snapshot_.reset(); -} - -void ResetProfileSettingsHandler::OnSettingsFetched() { - DCHECK(config_fetcher_); - DCHECK(!config_fetcher_->IsActive()); - // The master prefs is fetched. We are waiting for user pressing 'Reset'. -} - -void ResetProfileSettingsHandler::ResetProfile( - bool send_settings, - reset_report::ChromeResetReport::ResetRequestOrigin request_origin) { - DCHECK(resetter_); - DCHECK(!resetter_->IsActive()); - - std::unique_ptr<BrandcodedDefaultSettings> default_settings; - if (config_fetcher_) { - DCHECK(!config_fetcher_->IsActive()); - default_settings = config_fetcher_->GetSettings(); - config_fetcher_.reset(); - } else { - DCHECK(brandcode_.empty()); - } - - // If failed to fetch BrandcodedDefaultSettings or this is an organic - // installation, use default settings. - if (!default_settings) - default_settings.reset(new BrandcodedDefaultSettings); - resetter_->Reset( - ProfileResetter::ALL, std::move(default_settings), - base::Bind(&ResetProfileSettingsHandler::OnResetProfileSettingsDone, - AsWeakPtr(), send_settings, request_origin)); - base::RecordAction(base::UserMetricsAction("ResetProfile")); - UMA_HISTOGRAM_BOOLEAN("ProfileReset.SendFeedback", send_settings); - UMA_HISTOGRAM_ENUMERATION( - "ProfileReset.ResetRequestOrigin", request_origin, - reset_report::ChromeResetReport::ResetRequestOrigin_MAX + 1); -} - -void ResetProfileSettingsHandler::UpdateFeedbackUI() { - if (!setting_snapshot_) - return; - std::unique_ptr<base::ListValue> list = GetReadableFeedbackForSnapshot( - Profile::FromWebUI(web_ui()), *setting_snapshot_); - base::DictionaryValue feedback_info; - feedback_info.Set("feedbackInfo", std::move(list)); - web_ui()->CallJavascriptFunctionUnsafe( - "ResetProfileSettingsOverlay.setFeedbackInfo", feedback_info); -} - -} // namespace options
diff --git a/chrome/browser/ui/webui/options/reset_profile_settings_handler.h b/chrome/browser/ui/webui/options/reset_profile_settings_handler.h deleted file mode 100644 index d0e3405..0000000 --- a/chrome/browser/ui/webui/options/reset_profile_settings_handler.h +++ /dev/null
@@ -1,91 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_WEBUI_OPTIONS_RESET_PROFILE_SETTINGS_HANDLER_H_ -#define CHROME_BROWSER_UI_WEBUI_OPTIONS_RESET_PROFILE_SETTINGS_HANDLER_H_ - -#include <memory> -#include <string> - -#include "base/compiler_specific.h" -#include "base/macros.h" -#include "base/memory/weak_ptr.h" -#include "chrome/browser/profile_resetter/profile_reset_report.pb.h" -#include "chrome/browser/ui/webui/options/options_ui.h" - -namespace base { -class DictionaryValue; -class ListValue; -} // namespace base - -class BrandcodeConfigFetcher; -class ProfileResetter; -class ResettableSettingsSnapshot; - -namespace options { - -// Handler for both the 'Reset Profile Settings' overlay page and also the -// corresponding banner that is shown at the top of the options page. -class ResetProfileSettingsHandler - : public OptionsPageUIHandler, - public base::SupportsWeakPtr<ResetProfileSettingsHandler> { - public: - // Hash used by the Chrome Cleanup Tool when launching chrome with the reset - // profile settings URL. - static const char kCctResetSettingsHash[]; - - ResetProfileSettingsHandler(); - ~ResetProfileSettingsHandler() override; - - // OptionsPageUIHandler implementation. - void GetLocalizedValues(base::DictionaryValue* localized_strings) override; - void InitializeHandler() override; - void InitializePage() override; - - // WebUIMessageHandler implementation. - void RegisterMessages() override; - - private: - // Javascript callback to start clearing data. - void HandleResetProfileSettings(const base::ListValue* value); - - // Closes the dialog once all requested settings has been reset. - void OnResetProfileSettingsDone( - bool send_feedback, - reset_report::ChromeResetReport::ResetRequestOrigin request_origin); - - // Called when the confirmation box appears. - void OnShowResetProfileDialog(const base::ListValue* value); - - // Called when the confirmation box disappears. - void OnHideResetProfileDialog(const base::ListValue* value); - - // Called when BrandcodeConfigFetcher completed fetching settings. - void OnSettingsFetched(); - - // Resets profile settings to default values. |send_settings| is true if user - // gave their consent to upload broken settings to Google for analysis. - void ResetProfile( - bool send_settings, - reset_report::ChromeResetReport::ResetRequestOrigin request_origin); - - // Sets new values for the feedback area. - void UpdateFeedbackUI(); - - std::unique_ptr<ProfileResetter> resetter_; - - std::unique_ptr<BrandcodeConfigFetcher> config_fetcher_; - - // Snapshot of settings before profile was reseted. - std::unique_ptr<ResettableSettingsSnapshot> setting_snapshot_; - - // Contains Chrome brand code; empty for organic Chrome. - std::string brandcode_; - - DISALLOW_COPY_AND_ASSIGN(ResetProfileSettingsHandler); -}; - -} // namespace options - -#endif // CHROME_BROWSER_UI_WEBUI_OPTIONS_RESET_PROFILE_SETTINGS_HANDLER_H_
diff --git a/chrome/browser/ui/webui/options/search_engine_manager_handler.cc b/chrome/browser/ui/webui/options/search_engine_manager_handler.cc deleted file mode 100644 index a9d43ebc..0000000 --- a/chrome/browser/ui/webui/options/search_engine_manager_handler.cc +++ /dev/null
@@ -1,329 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/webui/options/search_engine_manager_handler.h" - -#include "base/bind.h" -#include "base/metrics/user_metrics.h" -#include "base/strings/string_number_conversions.h" -#include "base/strings/utf_string_conversions.h" -#include "base/values.h" -#include "chrome/browser/extensions/extension_util.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/search_engines/ui_thread_search_terms_data.h" -#include "chrome/browser/ui/search_engines/keyword_editor_controller.h" -#include "chrome/browser/ui/search_engines/template_url_table_model.h" -#include "chrome/common/url_constants.h" -#include "chrome/grit/generated_resources.h" -#include "components/search_engines/template_url.h" -#include "components/search_engines/template_url_service.h" -#include "content/public/browser/web_ui.h" -#include "extensions/browser/extension_registry.h" -#include "extensions/common/extension.h" -#include "ui/base/l10n/l10n_util.h" - -namespace { - -enum EngineInfoIndexes { - ENGINE_NAME, - ENGINE_KEYWORD, - ENGINE_URL, -}; - -}; // namespace - -namespace options { - -SearchEngineManagerHandler::SearchEngineManagerHandler() { -} - -SearchEngineManagerHandler::~SearchEngineManagerHandler() { - if (list_controller_.get() && list_controller_->table_model()) - list_controller_->table_model()->SetObserver(NULL); -} - -void SearchEngineManagerHandler::InitializeHandler() { - list_controller_.reset( - new KeywordEditorController(Profile::FromWebUI(web_ui()))); - DCHECK(list_controller_.get()); - list_controller_->table_model()->SetObserver(this); -} - -void SearchEngineManagerHandler::InitializePage() { - OnModelChanged(); -} - -void SearchEngineManagerHandler::GetLocalizedValues( - base::DictionaryValue* localized_strings) { - DCHECK(localized_strings); - - RegisterTitle(localized_strings, "searchEngineManagerPage", - IDS_SEARCH_ENGINES_EDITOR_WINDOW_TITLE); - localized_strings->SetString("defaultSearchEngineListTitle", - l10n_util::GetStringUTF16(IDS_SEARCH_ENGINES_EDITOR_MAIN_SEPARATOR)); - localized_strings->SetString("otherSearchEngineListTitle", - l10n_util::GetStringUTF16(IDS_SEARCH_ENGINES_EDITOR_OTHER_SEPARATOR)); - localized_strings->SetString("extensionKeywordsListTitle", - l10n_util::GetStringUTF16( - IDS_SEARCH_ENGINES_EDITOR_EXTENSIONS_SEPARATOR)); - localized_strings->SetString("makeDefaultSearchEngineButton", - l10n_util::GetStringUTF16(IDS_SEARCH_ENGINES_EDITOR_MAKE_DEFAULT_BUTTON)); - localized_strings->SetString("searchEngineTableNamePlaceholder", - l10n_util::GetStringUTF16(IDS_SEARCH_ENGINE_ADD_NEW_NAME_PLACEHOLDER)); - localized_strings->SetString("searchEngineTableKeywordPlaceholder", - l10n_util::GetStringUTF16(IDS_SEARCH_ENGINE_ADD_NEW_KEYWORD_PLACEHOLDER)); - localized_strings->SetString("searchEngineTableURLPlaceholder", - l10n_util::GetStringUTF16(IDS_SEARCH_ENGINE_ADD_NEW_URL_PLACEHOLDER)); - localized_strings->SetString("editSearchEngineInvalidTitleToolTip", - l10n_util::GetStringUTF16(IDS_SEARCH_ENGINES_INVALID_TITLE_TT)); - localized_strings->SetString("editSearchEngineInvalidKeywordToolTip", - l10n_util::GetStringUTF16(IDS_SEARCH_ENGINES_INVALID_KEYWORD_TT)); - localized_strings->SetString("editSearchEngineInvalidURLToolTip", - l10n_util::GetStringUTF16(IDS_SEARCH_ENGINES_INVALID_URL_TT)); -} - -void SearchEngineManagerHandler::RegisterMessages() { - web_ui()->RegisterMessageCallback( - "managerSetDefaultSearchEngine", - base::Bind(&SearchEngineManagerHandler::SetDefaultSearchEngine, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "removeSearchEngine", - base::Bind(&SearchEngineManagerHandler::RemoveSearchEngine, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "editSearchEngine", - base::Bind(&SearchEngineManagerHandler::EditSearchEngine, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "checkSearchEngineInfoValidity", - base::Bind(&SearchEngineManagerHandler::CheckSearchEngineInfoValidity, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "searchEngineEditCancelled", - base::Bind(&SearchEngineManagerHandler::EditCancelled, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "searchEngineEditCompleted", - base::Bind(&SearchEngineManagerHandler::EditCompleted, - base::Unretained(this))); -} - -void SearchEngineManagerHandler::OnModelChanged() { - DCHECK(list_controller_.get()); - if (!list_controller_->loaded()) - return; - - // Find the default engine. - const TemplateURL* default_engine = - list_controller_->GetDefaultSearchProvider(); - int default_index = list_controller_->table_model()->IndexOfTemplateURL( - default_engine); - - // Build the first list (default search engine options). - base::ListValue defaults_list; - int last_default_engine_index = - list_controller_->table_model()->last_search_engine_index(); - for (int i = 0; i < last_default_engine_index; ++i) { - // Third argument is false, as the engine is not from an extension. - defaults_list.Append(CreateDictionaryForEngine( - i, i == default_index)); - } - - // Build the second list (other search templates). - base::ListValue others_list; - int last_other_engine_index = - list_controller_->table_model()->last_other_engine_index(); - if (last_default_engine_index < 0) - last_default_engine_index = 0; - for (int i = last_default_engine_index; i < last_other_engine_index; ++i) { - others_list.Append(CreateDictionaryForEngine(i, i == default_index)); - } - - // Build the extension keywords list. - base::ListValue keyword_list; - if (last_other_engine_index < 0) - last_other_engine_index = 0; - int engine_count = list_controller_->table_model()->RowCount(); - for (int i = last_other_engine_index; i < engine_count; ++i) { - keyword_list.Append(CreateDictionaryForEngine(i, i == default_index)); - } - - web_ui()->CallJavascriptFunctionUnsafe( - "SearchEngineManager.updateSearchEngineList", defaults_list, others_list, - keyword_list); -} - -void SearchEngineManagerHandler::OnItemsChanged(int start, int length) { - OnModelChanged(); -} - -void SearchEngineManagerHandler::OnItemsAdded(int start, int length) { - OnModelChanged(); -} - -void SearchEngineManagerHandler::OnItemsRemoved(int start, int length) { - OnModelChanged(); -} - -std::unique_ptr<base::DictionaryValue> -SearchEngineManagerHandler::CreateDictionaryForEngine(int index, - bool is_default) { - TemplateURLTableModel* table_model = list_controller_->table_model(); - const TemplateURL* template_url = list_controller_->GetTemplateURL(index); - - // The items which are to be written into |dict| are also described in - // chrome/browser/resources/options/search_engine_manager_engine_list.js - // in @typedef for SearchEngine. Please update it whenever you add or remove - // any keys here. - std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); - dict->SetString("name", template_url->short_name()); - dict->SetString("displayName", table_model->GetText( - index, IDS_SEARCH_ENGINES_EDITOR_DESCRIPTION_COLUMN)); - dict->SetString("keyword", table_model->GetText( - index, IDS_SEARCH_ENGINES_EDITOR_KEYWORD_COLUMN)); - dict->SetString("url", template_url->url_ref().DisplayURL( - UIThreadSearchTermsData(Profile::FromWebUI(web_ui())))); - dict->SetBoolean("urlLocked", template_url->prepopulate_id() > 0); - GURL icon_url = template_url->favicon_url(); - if (icon_url.is_valid()) - dict->SetString("iconURL", icon_url.spec()); - dict->SetString("modelIndex", base::IntToString(index)); - - dict->SetBoolean("canBeRemoved", - list_controller_->CanRemove(template_url)); - dict->SetBoolean("canBeDefault", - list_controller_->CanMakeDefault(template_url)); - dict->SetBoolean("default", is_default); - dict->SetBoolean("canBeEdited", list_controller_->CanEdit(template_url)); - TemplateURL::Type type = template_url->type(); - dict->SetBoolean("isOmniboxExtension", - type == TemplateURL::OMNIBOX_API_EXTENSION); - if (type == TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION || - type == TemplateURL::OMNIBOX_API_EXTENSION) { - const extensions::Extension* extension = - extensions::ExtensionRegistry::Get(Profile::FromWebUI(web_ui())) - ->GetExtensionById(template_url->GetExtensionId(), - extensions::ExtensionRegistry::EVERYTHING); - if (extension) { - dict->Set("extension", extensions::util::GetExtensionInfo(extension)); - } - } - return dict; -} - -void SearchEngineManagerHandler::SetDefaultSearchEngine( - const base::ListValue* args) { - int index; - if (!ExtractIntegerValue(args, &index)) { - NOTREACHED(); - return; - } - if (index < 0 || index >= list_controller_->table_model()->RowCount()) - return; - - list_controller_->MakeDefaultTemplateURL(index); - - base::RecordAction(base::UserMetricsAction("Options_SearchEngineSetDefault")); -} - -void SearchEngineManagerHandler::RemoveSearchEngine( - const base::ListValue* args) { - int index; - if (!ExtractIntegerValue(args, &index)) { - NOTREACHED(); - return; - } - if (index < 0 || index >= list_controller_->table_model()->RowCount()) - return; - - if (list_controller_->CanRemove(list_controller_->GetTemplateURL(index))) { - list_controller_->RemoveTemplateURL(index); - base::RecordAction(base::UserMetricsAction("Options_SearchEngineRemoved")); - } -} - -void SearchEngineManagerHandler::EditSearchEngine(const base::ListValue* args) { - int index; - if (!ExtractIntegerValue(args, &index)) { - NOTREACHED(); - return; - } - - // Allow -1, which means we are adding a new engine. - if (index < -1 || index >= list_controller_->table_model()->RowCount()) - return; - - edit_controller_.reset(new EditSearchEngineController( - (index == -1) ? NULL : list_controller_->GetTemplateURL(index), this, - Profile::FromWebUI(web_ui()))); -} - -void SearchEngineManagerHandler::OnEditedKeyword( - TemplateURL* template_url, - const base::string16& title, - const base::string16& keyword, - const std::string& url) { - DCHECK(!url.empty()); - if (template_url) - list_controller_->ModifyTemplateURL(template_url, title, keyword, url); - else - list_controller_->AddTemplateURL(title, keyword, url); - edit_controller_.reset(); -} - -void SearchEngineManagerHandler::CheckSearchEngineInfoValidity( - const base::ListValue* args) { - if (!edit_controller_.get()) - return; - base::string16 name; - base::string16 keyword; - std::string url; - std::string modelIndex; - if (!args->GetString(ENGINE_NAME, &name) || - !args->GetString(ENGINE_KEYWORD, &keyword) || - !args->GetString(ENGINE_URL, &url) || - !args->GetString(3, &modelIndex)) { - NOTREACHED(); - return; - } - - base::DictionaryValue validity; - validity.SetBoolean("name", edit_controller_->IsTitleValid(name)); - validity.SetBoolean("keyword", edit_controller_->IsKeywordValid(keyword)); - validity.SetBoolean("url", edit_controller_->IsURLValid(url)); - base::Value indexValue(modelIndex); - web_ui()->CallJavascriptFunctionUnsafe( - "SearchEngineManager.validityCheckCallback", validity, indexValue); -} - -void SearchEngineManagerHandler::EditCancelled(const base::ListValue* args) { - if (!edit_controller_.get()) - return; - edit_controller_->CleanUpCancelledAdd(); - edit_controller_.reset(); -} - -void SearchEngineManagerHandler::EditCompleted(const base::ListValue* args) { - if (!edit_controller_.get()) - return; - base::string16 name; - base::string16 keyword; - std::string url; - if (!args->GetString(ENGINE_NAME, &name) || - !args->GetString(ENGINE_KEYWORD, &keyword) || - !args->GetString(ENGINE_URL, &url)) { - NOTREACHED(); - return; - } - - // Recheck validity. It's possible to get here with invalid input if e.g. the - // user calls the right JS functions directly from the web inspector. - if (edit_controller_->IsTitleValid(name) && - edit_controller_->IsKeywordValid(keyword) && - edit_controller_->IsURLValid(url)) - edit_controller_->AcceptAddOrEdit(name, keyword, url); -} - -} // namespace options
diff --git a/chrome/browser/ui/webui/options/search_engine_manager_handler.h b/chrome/browser/ui/webui/options/search_engine_manager_handler.h deleted file mode 100644 index 9de72bf..0000000 --- a/chrome/browser/ui/webui/options/search_engine_manager_handler.h +++ /dev/null
@@ -1,90 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_WEBUI_OPTIONS_SEARCH_ENGINE_MANAGER_HANDLER_H_ -#define CHROME_BROWSER_UI_WEBUI_OPTIONS_SEARCH_ENGINE_MANAGER_HANDLER_H_ - -#include <memory> - -#include "base/macros.h" -#include "chrome/browser/ui/search_engines/edit_search_engine_controller.h" -#include "chrome/browser/ui/webui/options/options_ui.h" -#include "ui/base/models/table_model_observer.h" - -class KeywordEditorController; - -namespace extensions { -class Extension; -} - -namespace options { - -class SearchEngineManagerHandler : public OptionsPageUIHandler, - public ui::TableModelObserver, - public EditSearchEngineControllerDelegate { - public: - SearchEngineManagerHandler(); - ~SearchEngineManagerHandler() override; - - // OptionsPageUIHandler implementation. - void GetLocalizedValues(base::DictionaryValue* localized_strings) override; - void InitializeHandler() override; - void InitializePage() override; - - // ui::TableModelObserver implementation. - void OnModelChanged() override; - void OnItemsChanged(int start, int length) override; - void OnItemsAdded(int start, int length) override; - void OnItemsRemoved(int start, int length) override; - - // EditSearchEngineControllerDelegate implementation. - void OnEditedKeyword(TemplateURL* template_url, - const base::string16& title, - const base::string16& keyword, - const std::string& url) override; - - void RegisterMessages() override; - - private: - std::unique_ptr<KeywordEditorController> list_controller_; - std::unique_ptr<EditSearchEngineController> edit_controller_; - - // Removes the search engine at the given index. Called from WebUI. - void RemoveSearchEngine(const base::ListValue* args); - - // Sets the search engine at the given index to be default. Called from WebUI. - void SetDefaultSearchEngine(const base::ListValue* args); - - // Starts an edit session for the search engine at the given index. If the - // index is -1, starts editing a new search engine instead of an existing one. - // Called from WebUI. - void EditSearchEngine(const base::ListValue* args); - - // Validates the given search engine values, and reports the results back - // to WebUI. Called from WebUI. - void CheckSearchEngineInfoValidity(const base::ListValue* args); - - // Called when an edit is cancelled. - // Called from WebUI. - void EditCancelled(const base::ListValue* args); - - // Called when an edit is finished and should be saved. - // Called from WebUI. - void EditCompleted(const base::ListValue* args); - - // Returns a dictionary to pass to WebUI representing the given search engine. - std::unique_ptr<base::DictionaryValue> CreateDictionaryForEngine( - int index, - bool is_default); - - // Returns a dictionary to pass to WebUI representing the extension. - base::DictionaryValue* CreateDictionaryForExtension( - const extensions::Extension& extension); - - DISALLOW_COPY_AND_ASSIGN(SearchEngineManagerHandler); -}; - -} // namespace options - -#endif // CHROME_BROWSER_UI_WEBUI_OPTIONS_SEARCH_ENGINE_MANAGER_HANDLER_H_
diff --git a/chrome/browser/ui/webui/options/startup_pages_handler.cc b/chrome/browser/ui/webui/options/startup_pages_handler.cc deleted file mode 100644 index 70e4655..0000000 --- a/chrome/browser/ui/webui/options/startup_pages_handler.cc +++ /dev/null
@@ -1,272 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/webui/options/startup_pages_handler.h" - -#include <stddef.h> - -#include <utility> - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/logging.h" -#include "base/macros.h" -#include "base/memory/ptr_util.h" -#include "chrome/browser/autocomplete/chrome_autocomplete_provider_client.h" -#include "chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.h" -#include "chrome/browser/chrome_notification_types.h" -#include "chrome/browser/custom_home_pages_table_model.h" -#include "chrome/browser/prefs/session_startup_pref.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/search_engines/template_url_service_factory.h" -#include "chrome/browser/ui/webui/settings_utils.h" -#include "chrome/common/pref_names.h" -#include "chrome/grit/generated_resources.h" -#include "components/metrics/proto/omnibox_event.pb.h" -#include "components/omnibox/browser/autocomplete_classifier.h" -#include "components/omnibox/browser/autocomplete_controller.h" -#include "components/omnibox/browser/autocomplete_input.h" -#include "components/omnibox/browser/autocomplete_result.h" -#include "components/prefs/pref_service.h" -#include "content/public/browser/notification_details.h" -#include "content/public/browser/web_ui.h" -#include "url/gurl.h" - -namespace options { - -StartupPagesHandler::StartupPagesHandler() { -} - -StartupPagesHandler::~StartupPagesHandler() { -} - -void StartupPagesHandler::GetLocalizedValues( - base::DictionaryValue* localized_strings) { - DCHECK(localized_strings); - - static OptionsStringResource resources[] = { - { "startupAddLabel", IDS_OPTIONS_STARTUP_ADD_LABEL }, - { "startupUseCurrent", IDS_OPTIONS_STARTUP_USE_CURRENT }, - { "startupPagesPlaceholder", IDS_OPTIONS_STARTUP_PAGES_PLACEHOLDER }, - }; - - RegisterStrings(localized_strings, resources, arraysize(resources)); - RegisterTitle(localized_strings, "startupPagesOverlay", - IDS_OPTIONS_STARTUP_PAGES_DIALOG_TITLE); -} - -void StartupPagesHandler::RegisterMessages() { - // Guest profiles should never have been displayed the option to set these - // values. - if (Profile::FromWebUI(web_ui())->IsOffTheRecord()) - return; - - web_ui()->RegisterMessageCallback("removeStartupPages", - base::Bind(&StartupPagesHandler::RemoveStartupPages, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("addStartupPage", - base::Bind(&StartupPagesHandler::AddStartupPage, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("editStartupPage", - base::Bind(&StartupPagesHandler::EditStartupPage, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("setStartupPagesToCurrentPages", - base::Bind(&StartupPagesHandler::SetStartupPagesToCurrentPages, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("dragDropStartupPage", - base::Bind(&StartupPagesHandler::DragDropStartupPage, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "requestAutocompleteSuggestionsForStartupPages", - base::Bind(&StartupPagesHandler::RequestAutocompleteSuggestions, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("commitStartupPrefChanges", - base::Bind(&StartupPagesHandler::CommitChanges, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("cancelStartupPrefChanges", - base::Bind(&StartupPagesHandler::CancelChanges, - base::Unretained(this))); -} - -void StartupPagesHandler::UpdateStartupPages() { - Profile* profile = Profile::FromWebUI(web_ui()); - const SessionStartupPref startup_pref = - SessionStartupPref::GetStartupPref(profile->GetPrefs()); - startup_custom_pages_table_model_->SetURLs(startup_pref.urls); -} - -void StartupPagesHandler::InitializeHandler() { - Profile* profile = Profile::FromWebUI(web_ui()); - - startup_custom_pages_table_model_.reset( - new CustomHomePagesTableModel(profile)); - startup_custom_pages_table_model_->SetObserver(this); - - pref_change_registrar_.Init(profile->GetPrefs()); - pref_change_registrar_.Add( - prefs::kURLsToRestoreOnStartup, - base::Bind(&StartupPagesHandler::UpdateStartupPages, - base::Unretained(this))); - - autocomplete_controller_.reset(new AutocompleteController( - base::MakeUnique<ChromeAutocompleteProviderClient>(profile), this, - AutocompleteClassifier::DefaultOmniboxProviders())); -} - -void StartupPagesHandler::InitializePage() { - UpdateStartupPages(); -} - -void StartupPagesHandler::OnModelChanged() { - base::ListValue startup_pages; - int page_count = startup_custom_pages_table_model_->RowCount(); - std::vector<GURL> urls = startup_custom_pages_table_model_->GetURLs(); - for (int i = 0; i < page_count; ++i) { - std::unique_ptr<base::DictionaryValue> entry(new base::DictionaryValue()); - entry->SetString("title", startup_custom_pages_table_model_->GetText(i, 0)); - entry->SetString("url", urls[i].spec()); - entry->SetString("tooltip", - startup_custom_pages_table_model_->GetTooltip(i)); - entry->SetInteger("modelIndex", i); - startup_pages.Append(std::move(entry)); - } - - web_ui()->CallJavascriptFunctionUnsafe("StartupOverlay.updateStartupPages", - startup_pages); -} - -void StartupPagesHandler::OnItemsChanged(int start, int length) { - OnModelChanged(); -} - -void StartupPagesHandler::OnItemsAdded(int start, int length) { - OnModelChanged(); -} - -void StartupPagesHandler::OnItemsRemoved(int start, int length) { - OnModelChanged(); -} - -void StartupPagesHandler::SetStartupPagesToCurrentPages( - const base::ListValue* args) { - startup_custom_pages_table_model_->SetToCurrentlyOpenPages( - web_ui()->GetWebContents()); -} - -void StartupPagesHandler::RemoveStartupPages(const base::ListValue* args) { - for (int i = args->GetSize() - 1; i >= 0; --i) { - int selected_index; - CHECK(args->GetInteger(i, &selected_index)); - - if (selected_index < 0 || - selected_index >= startup_custom_pages_table_model_->RowCount()) { - NOTREACHED(); - return; - } - startup_custom_pages_table_model_->Remove(selected_index); - } -} - -void StartupPagesHandler::AddStartupPage(const base::ListValue* args) { - std::string url_string; - CHECK(args->GetString(0, &url_string)); - - GURL fixed_url; - if (!settings_utils::FixupAndValidateStartupPage(url_string, &fixed_url)) { - NOTREACHED(); - return; - } - - int row_count = startup_custom_pages_table_model_->RowCount(); - int index; - if (!args->GetInteger(1, &index) || index > row_count) - index = row_count; - - startup_custom_pages_table_model_->Add(index, fixed_url); -} - -void StartupPagesHandler::EditStartupPage(const base::ListValue* args) { - CHECK_EQ(args->GetSize(), 2U); - int index; - CHECK(args->GetInteger(0, &index)); - - if (index < 0 || index > startup_custom_pages_table_model_->RowCount()) { - NOTREACHED(); - return; - } - - std::string url_string; - CHECK(args->GetString(1, &url_string)); - - GURL fixed_url; - if (settings_utils::FixupAndValidateStartupPage(url_string, &fixed_url)) { - std::vector<GURL> urls = startup_custom_pages_table_model_->GetURLs(); - urls[index] = fixed_url; - startup_custom_pages_table_model_->SetURLs(urls); - } else { - startup_custom_pages_table_model_->Remove(index); - } -} - -void StartupPagesHandler::DragDropStartupPage(const base::ListValue* args) { - CHECK_EQ(args->GetSize(), 2U); - - int to_index; - - CHECK(args->GetInteger(0, &to_index)); - - const base::ListValue* selected; - CHECK(args->GetList(1, &selected)); - - std::vector<int> index_list; - for (size_t i = 0; i < selected->GetSize(); ++i) { - int index; - CHECK(selected->GetInteger(i, &index)); - index_list.push_back(index); - } - - startup_custom_pages_table_model_->MoveURLs(to_index, index_list); -} - -void StartupPagesHandler::SaveStartupPagesPref() { - PrefService* prefs = Profile::FromWebUI(web_ui())->GetPrefs(); - - SessionStartupPref pref = SessionStartupPref::GetStartupPref(prefs); - pref.urls = startup_custom_pages_table_model_->GetURLs(); - - if (pref.urls.empty()) - pref.type = SessionStartupPref::DEFAULT; - - SessionStartupPref::SetStartupPref(prefs, pref); -} - -void StartupPagesHandler::CommitChanges(const base::ListValue* args) { - SaveStartupPagesPref(); -} - -void StartupPagesHandler::CancelChanges(const base::ListValue* args) { - UpdateStartupPages(); -} - -void StartupPagesHandler::RequestAutocompleteSuggestions( - const base::ListValue* args) { - base::string16 input; - CHECK_EQ(args->GetSize(), 1U); - CHECK(args->GetString(0, &input)); - - autocomplete_controller_->Start(AutocompleteInput( - input, base::string16::npos, std::string(), GURL(), base::string16(), - metrics::OmniboxEventProto::INVALID_SPEC, true, false, false, true, false, - ChromeAutocompleteSchemeClassifier(Profile::FromWebUI(web_ui())))); -} - -void StartupPagesHandler::OnResultChanged(bool default_match_changed) { - const AutocompleteResult& result = autocomplete_controller_->result(); - base::ListValue suggestions; - OptionsUI::ProcessAutocompleteSuggestions(result, &suggestions); - web_ui()->CallJavascriptFunctionUnsafe( - "StartupOverlay.updateAutocompleteSuggestions", suggestions); -} - -} // namespace options
diff --git a/chrome/browser/ui/webui/options/startup_pages_handler.h b/chrome/browser/ui/webui/options/startup_pages_handler.h deleted file mode 100644 index 2f18174..0000000 --- a/chrome/browser/ui/webui/options/startup_pages_handler.h +++ /dev/null
@@ -1,95 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_WEBUI_OPTIONS_STARTUP_PAGES_HANDLER_H_ -#define CHROME_BROWSER_UI_WEBUI_OPTIONS_STARTUP_PAGES_HANDLER_H_ - -#include <memory> - -#include "base/macros.h" -#include "base/memory/ref_counted.h" -#include "base/memory/weak_ptr.h" -#include "chrome/browser/ui/webui/options/options_ui.h" -#include "components/omnibox/browser/autocomplete_controller_delegate.h" -#include "components/prefs/pref_change_registrar.h" -#include "components/prefs/pref_member.h" -#include "ui/base/models/table_model_observer.h" - -class AutocompleteController; -class CustomHomePagesTableModel; - -namespace options { - -// Chrome browser options page UI handler. -class StartupPagesHandler : public OptionsPageUIHandler, - public AutocompleteControllerDelegate, - public ui::TableModelObserver { - public: - StartupPagesHandler(); - ~StartupPagesHandler() override; - - // OptionsPageUIHandler implementation. - void GetLocalizedValues(base::DictionaryValue* localized_strings) override; - void InitializeHandler() override; - void InitializePage() override; - void RegisterMessages() override; - - // AutocompleteControllerDelegate implementation. - void OnResultChanged(bool default_match_changed) override; - - // ui::TableModelObserver implementation. - void OnModelChanged() override; - void OnItemsChanged(int start, int length) override; - void OnItemsAdded(int start, int length) override; - void OnItemsRemoved(int start, int length) override; - - private: - // Saves the changes that have been made. Called from WebUI. - void CommitChanges(const base::ListValue* args); - - // Cancels the changes that have been made. Called from WebUI. - void CancelChanges(const base::ListValue* args); - - // Removes the startup page at the given indexes. Called from WebUI. - void RemoveStartupPages(const base::ListValue* args); - - // Adds a startup page with the given URL after the given index. - // Called from WebUI. - void AddStartupPage(const base::ListValue* args); - - // Changes the startup page at the given index to the given URL. - // Called from WebUI. - void EditStartupPage(const base::ListValue* args); - - // Sets the startup page set to the current pages. Called from WebUI. - void SetStartupPagesToCurrentPages(const base::ListValue* args); - - // Writes the current set of startup pages to prefs. Called from WebUI. - void DragDropStartupPage(const base::ListValue* args); - - // Gets autocomplete suggestions asychronously for the given string. - // Called from WebUI. - void RequestAutocompleteSuggestions(const base::ListValue* args); - - // Loads the current set of custom startup pages and reports it to the WebUI. - void UpdateStartupPages(); - - // Writes the current set of startup pages to prefs. - void SaveStartupPagesPref(); - - std::unique_ptr<AutocompleteController> autocomplete_controller_; - - // Used to observe updates to the preference of the list of URLs to load - // on startup, which can be updated via sync. - PrefChangeRegistrar pref_change_registrar_; - - // The set of pages to launch on startup. - std::unique_ptr<CustomHomePagesTableModel> startup_custom_pages_table_model_; - - DISALLOW_COPY_AND_ASSIGN(StartupPagesHandler); -}; - -} // namespace options - -#endif // CHROME_BROWSER_UI_WEBUI_OPTIONS_STARTUP_PAGES_HANDLER_H_
diff --git a/chrome/browser/ui/webui/options/supervised_user_create_confirm_handler.cc b/chrome/browser/ui/webui/options/supervised_user_create_confirm_handler.cc deleted file mode 100644 index 9ff957d..0000000 --- a/chrome/browser/ui/webui/options/supervised_user_create_confirm_handler.cc +++ /dev/null
@@ -1,168 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/webui/options/supervised_user_create_confirm_handler.h" - -#include <stddef.h> - -#include <string> - -#include "base/bind.h" -#include "base/files/file_path.h" -#include "base/macros.h" -#include "base/scoped_observer.h" -#include "base/strings/utf_string_conversions.h" -#include "base/value_conversions.h" -#include "base/values.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/profiles/profile_attributes_entry.h" -#include "chrome/browser/profiles/profile_attributes_storage.h" -#include "chrome/browser/profiles/profile_manager.h" -#include "chrome/browser/profiles/profile_window.h" -#include "chrome/browser/signin/signin_manager_factory.h" -#include "chrome/browser/ui/browser_finder.h" -#include "chrome/browser/ui/startup/startup_types.h" -#include "chrome/common/url_constants.h" -#include "chrome/grit/generated_resources.h" -#include "components/signin/core/browser/signin_manager.h" -#include "components/signin/core/browser/signin_manager_base.h" -#include "content/public/browser/web_ui.h" -#include "ui/base/l10n/l10n_util.h" - -namespace options { - -// ProfileUpdateObserver------------------------------------------------------ - -class SupervisedUserCreateConfirmHandler::ProfileUpdateObserver - : public ProfileAttributesStorage::Observer { - public: - ProfileUpdateObserver(ProfileAttributesStorage* profile_attributes_storage, - SupervisedUserCreateConfirmHandler* handler) - : profile_attributes_storage_(profile_attributes_storage), - create_confirm_handler_(handler), - scoped_observer_(this) { - DCHECK(profile_attributes_storage_); - DCHECK(create_confirm_handler_); - scoped_observer_.Add(profile_attributes_storage_); - } - - private: - // ProfileAttributesStorage::Observer implementation: - // Forward possibly relevant changes to the dialog, which will check the - // affected profile and update or close as needed. - void OnProfileWasRemoved(const base::FilePath& profile_path, - const base::string16& profile_name) override { - std::unique_ptr<base::Value> profile_path_value( - base::CreateFilePathValue(profile_path)); - create_confirm_handler_->web_ui()->CallJavascriptFunctionUnsafe( - "SupervisedUserCreateConfirmOverlay.onDeletedProfile", - *profile_path_value); - } - - void OnProfileNameChanged(const base::FilePath& profile_path, - const base::string16& old_profile_name) override { - ProfileAttributesEntry* entry; - if (!profile_attributes_storage_-> - GetProfileAttributesWithPath(profile_path, &entry)) - return; - base::string16 new_profile_name = entry->GetName(); - std::unique_ptr<base::Value> profile_path_value( - base::CreateFilePathValue(profile_path)); - create_confirm_handler_->web_ui()->CallJavascriptFunctionUnsafe( - "SupervisedUserCreateConfirmOverlay.onUpdatedProfileName", - *profile_path_value, base::Value(new_profile_name)); - } - - // Weak. - ProfileAttributesStorage* profile_attributes_storage_; - - // Weak; owns us. - SupervisedUserCreateConfirmHandler* create_confirm_handler_; - - // Manages any sources we're observing, ensuring that they're all removed - // on destruction. - ScopedObserver<ProfileAttributesStorage, ProfileUpdateObserver> - scoped_observer_; - - DISALLOW_COPY_AND_ASSIGN(ProfileUpdateObserver); -}; - - -// SupervisedUserCreateConfirmHandler----------------------------------------- - -SupervisedUserCreateConfirmHandler::SupervisedUserCreateConfirmHandler() { - profile_update_observer_.reset( - new SupervisedUserCreateConfirmHandler::ProfileUpdateObserver( - &g_browser_process->profile_manager()->GetProfileAttributesStorage(), - this)); -} - -SupervisedUserCreateConfirmHandler::~SupervisedUserCreateConfirmHandler() { -} - -void SupervisedUserCreateConfirmHandler::GetLocalizedValues( - base::DictionaryValue* localized_strings) { - DCHECK(localized_strings); - - static OptionsStringResource resources[] = { - { "supervisedUserCreatedTitle", IDS_LEGACY_SUPERVISED_USER_CREATED_TITLE }, - { "supervisedUserCreatedDone", - IDS_LEGACY_SUPERVISED_USER_CREATED_DONE_BUTTON }, - { "supervisedUserCreatedSwitch", - IDS_LEGACY_SUPERVISED_USER_CREATED_SWITCH_BUTTON }, - }; - - SigninManagerBase* signin = - SigninManagerFactory::GetForProfile(Profile::FromWebUI(web_ui())); - if (signin) { - localized_strings->SetString("custodianEmail", - signin->GetAuthenticatedAccountInfo().email); - } else { - localized_strings->SetString("custodianEmail", std::string()); - } - - base::string16 supervised_user_dashboard_url = - base::ASCIIToUTF16(chrome::kLegacySupervisedUserManagementURL); - base::string16 supervised_user_dashboard_display = - base::ASCIIToUTF16(chrome::kLegacySupervisedUserManagementDisplayURL); - // The first two substitution parameters need to remain; they will be filled - // by the page's JS. - localized_strings->SetString("supervisedUserCreatedText", - l10n_util::GetStringFUTF16(IDS_LEGACY_SUPERVISED_USER_CREATED_TEXT, - base::ASCIIToUTF16("$1"), - base::ASCIIToUTF16("$2"), - supervised_user_dashboard_url, - supervised_user_dashboard_display)); - - RegisterStrings(localized_strings, resources, arraysize(resources)); -} - -void SupervisedUserCreateConfirmHandler::RegisterMessages() { - web_ui()->RegisterMessageCallback("switchToProfile", - base::Bind(&SupervisedUserCreateConfirmHandler::SwitchToProfile, - base::Unretained(this))); -} - -void SupervisedUserCreateConfirmHandler::SwitchToProfile( - const base::ListValue* args) { - DCHECK(args); - const base::Value* file_path_value; - if (!args->Get(0, &file_path_value)) - return; - - base::FilePath profile_file_path; - if (!base::GetValueAsFilePath(*file_path_value, &profile_file_path)) - return; - - Profile* profile = g_browser_process->profile_manager()-> - GetProfileByPath(profile_file_path); - DCHECK(profile); - - profiles::FindOrCreateNewWindowForProfile( - profile, chrome::startup::IS_PROCESS_STARTUP, - chrome::startup::IS_FIRST_RUN, false); -} - -} // namespace options
diff --git a/chrome/browser/ui/webui/options/supervised_user_create_confirm_handler.h b/chrome/browser/ui/webui/options/supervised_user_create_confirm_handler.h deleted file mode 100644 index cf18d3c26..0000000 --- a/chrome/browser/ui/webui/options/supervised_user_create_confirm_handler.h +++ /dev/null
@@ -1,49 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_WEBUI_OPTIONS_SUPERVISED_USER_CREATE_CONFIRM_HANDLER_H_ -#define CHROME_BROWSER_UI_WEBUI_OPTIONS_SUPERVISED_USER_CREATE_CONFIRM_HANDLER_H_ - -#include "base/macros.h" -#include "chrome/browser/ui/webui/options/options_ui.h" - -namespace base { -class DictionaryValue; -} - -namespace options { - -// Handler for the confirmation dialog after successful creation of a supervised -// user. -class SupervisedUserCreateConfirmHandler : public OptionsPageUIHandler { - public: - SupervisedUserCreateConfirmHandler(); - ~SupervisedUserCreateConfirmHandler() override; - - // OptionsPageUIHandler implementation. - void GetLocalizedValues(base::DictionaryValue* localized_strings) override; - - // WebUIMessageHandler implementation. - void RegisterMessages() override; - - private: - // An observer for any changes to Profiles in the ProfileAttributesStorage so - // that this dialog can be updated or closed. - class ProfileUpdateObserver; - - // Callback for the "switchToProfile" message. - // Opens a new window for the profile. - // |args| is of the form [ {string} profileFilePath ] - void SwitchToProfile(const base::ListValue* args); - - // Observes the ProfileAttributesStorage and gets notified when a profile has - // been modified, so that the dialog can be updated or closed. - std::unique_ptr<ProfileUpdateObserver> profile_update_observer_; - - DISALLOW_COPY_AND_ASSIGN(SupervisedUserCreateConfirmHandler); -}; - -} // namespace options - -#endif // CHROME_BROWSER_UI_WEBUI_OPTIONS_SUPERVISED_USER_CREATE_CONFIRM_HANDLER_H_
diff --git a/chrome/browser/ui/webui/options/supervised_user_import_handler.cc b/chrome/browser/ui/webui/options/supervised_user_import_handler.cc deleted file mode 100644 index e768ff1..0000000 --- a/chrome/browser/ui/webui/options/supervised_user_import_handler.cc +++ /dev/null
@@ -1,304 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/webui/options/supervised_user_import_handler.h" - -#include <stddef.h> - -#include <memory> -#include <set> -#include <utility> -#include <vector> - -#include "base/bind.h" -#include "base/macros.h" -#include "base/values.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/profiles/profile_attributes_entry.h" -#include "chrome/browser/profiles/profile_avatar_icon_util.h" -#include "chrome/browser/profiles/profile_manager.h" -#include "chrome/browser/signin/signin_error_controller_factory.h" -#include "chrome/browser/signin/signin_manager_factory.h" -#include "chrome/browser/supervised_user/legacy/supervised_user_shared_settings_service.h" -#include "chrome/browser/supervised_user/legacy/supervised_user_shared_settings_service_factory.h" -#include "chrome/browser/supervised_user/legacy/supervised_user_sync_service.h" -#include "chrome/browser/supervised_user/legacy/supervised_user_sync_service_factory.h" -#include "chrome/browser/supervised_user/supervised_user_constants.h" -#include "chrome/common/url_constants.h" -#include "chrome/grit/generated_resources.h" -#include "chrome/grit/theme_resources.h" -#include "components/prefs/pref_service.h" -#include "components/signin/core/browser/signin_error_controller.h" -#include "components/signin/core/browser/signin_manager.h" -#include "content/public/browser/web_ui.h" - -namespace { - -std::unique_ptr<base::ListValue> GetAvatarIcons() { - std::unique_ptr<base::ListValue> avatar_icons(new base::ListValue); - for (size_t i = 0; i < profiles::GetDefaultAvatarIconCount(); ++i) { - std::string avatar_url = profiles::GetDefaultAvatarIconUrl(i); - avatar_icons->AppendString(avatar_url); - } - - return avatar_icons; -} - -bool ProfileIsLegacySupervised(const base::FilePath& profile_path) { - ProfileAttributesEntry* entry; - - return g_browser_process->profile_manager()->GetProfileAttributesStorage(). - GetProfileAttributesWithPath(profile_path, &entry) && - entry->IsLegacySupervised(); -} - -} // namespace - -namespace options { - -SupervisedUserImportHandler::SupervisedUserImportHandler() - : profile_observer_(this), - signin_error_observer_(this), - supervised_user_sync_service_observer_(this), - removed_profile_is_supervised_(false), - weak_ptr_factory_(this) { -} - -SupervisedUserImportHandler::~SupervisedUserImportHandler() { -} - -void SupervisedUserImportHandler::GetLocalizedValues( - base::DictionaryValue* localized_strings) { - DCHECK(localized_strings); - - static OptionsStringResource resources[] = { - { "supervisedUserImportTitle", - IDS_IMPORT_EXISTING_LEGACY_SUPERVISED_USER_TITLE }, - { "supervisedUserImportText", - IDS_IMPORT_EXISTING_LEGACY_SUPERVISED_USER_TEXT }, - { "createNewUserLink", IDS_CREATE_NEW_LEGACY_SUPERVISED_USER_LINK }, - { "supervisedUserImportOk", - IDS_IMPORT_EXISTING_LEGACY_SUPERVISED_USER_OK }, - { "supervisedUserImportSigninError", - IDS_LEGACY_SUPERVISED_USER_IMPORT_SIGN_IN_ERROR }, - { "supervisedUserAlreadyOnThisDevice", - IDS_LEGACY_SUPERVISED_USER_ALREADY_ON_THIS_DEVICE }, - { "noExistingSupervisedUsers", - IDS_LEGACY_SUPERVISED_USER_NO_EXISTING_ERROR }, - { "supervisedUserSelectAvatarTitle", - IDS_LEGACY_SUPERVISED_USER_SELECT_AVATAR_TITLE }, - { "supervisedUserSelectAvatarText", - IDS_LEGACY_SUPERVISED_USER_SELECT_AVATAR_TEXT }, - { "supervisedUserSelectAvatarOk", - IDS_LEGACY_SUPERVISED_USER_SELECT_AVATAR_OK }, - }; - - RegisterStrings(localized_strings, resources, arraysize(resources)); - localized_strings->Set("avatarIcons", GetAvatarIcons()); -} - -void SupervisedUserImportHandler::InitializeHandler() { - Profile* profile = Profile::FromWebUI(web_ui()); - if (!profile->IsSupervised()) { - profile_observer_.Add( - &g_browser_process->profile_manager()->GetProfileAttributesStorage()); - SupervisedUserSyncService* sync_service = - SupervisedUserSyncServiceFactory::GetForProfile(profile); - if (sync_service) { - supervised_user_sync_service_observer_.Add(sync_service); - signin_error_observer_.Add( - SigninErrorControllerFactory::GetForProfile(profile)); - SupervisedUserSharedSettingsService* settings_service = - SupervisedUserSharedSettingsServiceFactory::GetForBrowserContext( - profile); - subscription_ = settings_service->Subscribe( - base::Bind(&SupervisedUserImportHandler::OnSharedSettingChanged, - weak_ptr_factory_.GetWeakPtr())); - } else { - DCHECK(!SupervisedUserSharedSettingsServiceFactory::GetForBrowserContext( - profile)); - DCHECK(!SigninErrorControllerFactory::GetForProfile(profile)); - } - } -} - -void SupervisedUserImportHandler::RegisterMessages() { - web_ui()->RegisterMessageCallback("requestSupervisedUserImportUpdate", - base::Bind(&SupervisedUserImportHandler:: - RequestSupervisedUserImportUpdate, - base::Unretained(this))); -} - -void SupervisedUserImportHandler::OnProfileAdded( - const base::FilePath& profile_path) { - // When a supervised profile is added, re-send the list to update the - // the "already on this device" status. - if (ProfileIsLegacySupervised(profile_path)) - FetchSupervisedUsers(); -} - -void SupervisedUserImportHandler::OnProfileWillBeRemoved( - const base::FilePath& profile_path) { - DCHECK(!removed_profile_is_supervised_); - // When a supervised profile is removed, re-send the list to update the - // "already on this device" status. We can't do that right now because the - // profile still exists, so defer to OnProfileWasRemoved. - if (ProfileIsLegacySupervised(profile_path)) - removed_profile_is_supervised_ = true; -} - -void SupervisedUserImportHandler::OnProfileWasRemoved( - const base::FilePath& profile_path, - const base::string16& profile_name) { - if (removed_profile_is_supervised_) { - removed_profile_is_supervised_ = false; - FetchSupervisedUsers(); - } -} - -void SupervisedUserImportHandler::OnProfileIsOmittedChanged( - const base::FilePath& profile_path) { - if (ProfileIsLegacySupervised(profile_path)) - FetchSupervisedUsers(); -} - -void SupervisedUserImportHandler::OnSupervisedUsersChanged() { - FetchSupervisedUsers(); -} - -void SupervisedUserImportHandler::FetchSupervisedUsers() { - web_ui()->CallJavascriptFunctionUnsafe( - "options.SupervisedUserListData.resetPromise"); - RequestSupervisedUserImportUpdate(NULL); -} - -void SupervisedUserImportHandler::RequestSupervisedUserImportUpdate( - const base::ListValue* /* args */) { - if (Profile::FromWebUI(web_ui())->IsSupervised()) - return; - - if (!IsAccountConnected() || HasAuthError()) { - ClearSupervisedUsersAndShowError(); - } else { - SupervisedUserSyncService* supervised_user_sync_service = - SupervisedUserSyncServiceFactory::GetForProfile( - Profile::FromWebUI(web_ui())); - if (supervised_user_sync_service) { - supervised_user_sync_service->GetSupervisedUsersAsync( - base::Bind(&SupervisedUserImportHandler::SendExistingSupervisedUsers, - weak_ptr_factory_.GetWeakPtr())); - } - } -} - -void SupervisedUserImportHandler::SendExistingSupervisedUsers( - const base::DictionaryValue* dict) { - DCHECK(dict); - std::vector<ProfileAttributesEntry*> entries = - g_browser_process->profile_manager()-> - GetProfileAttributesStorage().GetAllProfilesAttributes(); - - // Collect the ids of local supervised user profiles. - std::set<std::string> supervised_user_ids; - for (const ProfileAttributesEntry* entry : entries) { - // Filter out omitted profiles. These are currently being imported, and - // shouldn't show up as "already on this device" just yet. - if (entry->IsLegacySupervised() && !entry->IsOmitted()) { - supervised_user_ids.insert(entry->GetSupervisedUserId()); - } - } - - base::ListValue supervised_users; - Profile* profile = Profile::FromWebUI(web_ui()); - SupervisedUserSharedSettingsService* service = - SupervisedUserSharedSettingsServiceFactory::GetForBrowserContext(profile); - for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); it.Advance()) { - const base::DictionaryValue* value = NULL; - bool success = it.value().GetAsDictionary(&value); - DCHECK(success); - std::string name; - value->GetString(SupervisedUserSyncService::kName, &name); - - std::unique_ptr<base::DictionaryValue> supervised_user( - new base::DictionaryValue); - supervised_user->SetString("id", it.key()); - supervised_user->SetString("name", name); - - int avatar_index = SupervisedUserSyncService::kNoAvatar; - const base::Value* avatar_index_value = - service->GetValue(it.key(), supervised_users::kChromeAvatarIndex); - if (avatar_index_value) { - success = avatar_index_value->GetAsInteger(&avatar_index); - } else { - // Check if there is a legacy avatar index stored. - std::string avatar_str; - value->GetString(SupervisedUserSyncService::kChromeAvatar, &avatar_str); - success = - SupervisedUserSyncService::GetAvatarIndex(avatar_str, &avatar_index); - } - DCHECK(success); - supervised_user->SetBoolean( - "needAvatar", - avatar_index == SupervisedUserSyncService::kNoAvatar); - - std::string supervised_user_icon = - std::string(chrome::kChromeUIThemeURL) + - "IDR_SUPERVISED_USER_PLACEHOLDER"; - std::string avatar_url = - avatar_index == SupervisedUserSyncService::kNoAvatar ? - supervised_user_icon : - profiles::GetDefaultAvatarIconUrl(avatar_index); - supervised_user->SetString("iconURL", avatar_url); - bool on_current_device = - supervised_user_ids.find(it.key()) != supervised_user_ids.end(); - supervised_user->SetBoolean("onCurrentDevice", on_current_device); - - supervised_users.Append(std::move(supervised_user)); - } - - web_ui()->CallJavascriptFunctionUnsafe( - "options.SupervisedUserListData.receiveExistingSupervisedUsers", - supervised_users); -} - -void SupervisedUserImportHandler::ClearSupervisedUsersAndShowError() { - web_ui()->CallJavascriptFunctionUnsafe( - "options.SupervisedUserListData.onSigninError"); -} - -bool SupervisedUserImportHandler::IsAccountConnected() const { - Profile* profile = Profile::FromWebUI(web_ui()); - SigninManagerBase* signin_manager = - SigninManagerFactory::GetForProfile(profile); - return signin_manager && signin_manager->IsAuthenticated(); -} - -bool SupervisedUserImportHandler::HasAuthError() const { - Profile* profile = Profile::FromWebUI(web_ui()); - SigninErrorController* error_controller = - SigninErrorControllerFactory::GetForProfile(profile); - if (!error_controller) - return true; - - GoogleServiceAuthError::State state = error_controller->auth_error().state(); - - return state == GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS || - state == GoogleServiceAuthError::USER_NOT_SIGNED_UP || - state == GoogleServiceAuthError::ACCOUNT_DELETED || - state == GoogleServiceAuthError::ACCOUNT_DISABLED; -} - -void SupervisedUserImportHandler::OnSharedSettingChanged( - const std::string& supervised_user_id, - const std::string& key) { - if (key == supervised_users::kChromeAvatarIndex) - FetchSupervisedUsers(); -} - -void SupervisedUserImportHandler::OnErrorChanged() { - FetchSupervisedUsers(); -} - -} // namespace options
diff --git a/chrome/browser/ui/webui/options/supervised_user_import_handler.h b/chrome/browser/ui/webui/options/supervised_user_import_handler.h deleted file mode 100644 index 9b972e1..0000000 --- a/chrome/browser/ui/webui/options/supervised_user_import_handler.h +++ /dev/null
@@ -1,118 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_WEBUI_OPTIONS_SUPERVISED_USER_IMPORT_HANDLER_H_ -#define CHROME_BROWSER_UI_WEBUI_OPTIONS_SUPERVISED_USER_IMPORT_HANDLER_H_ - -#include <string> - -#include "base/callback_list.h" -#include "base/macros.h" -#include "base/memory/weak_ptr.h" -#include "base/scoped_observer.h" -#include "base/strings/string16.h" -#include "chrome/browser/profiles/profile_attributes_storage.h" -#include "chrome/browser/supervised_user/legacy/supervised_user_sync_service_observer.h" -#include "chrome/browser/ui/webui/options/options_ui.h" -#include "components/signin/core/browser/signin_error_controller.h" - -namespace base { -class DictionaryValue; -class ListValue; -} - -class ProfileAttributesStorage; -class SupervisedUserSyncService; - -namespace options { - -// Handler for the 'import existing supervised user' dialog. -class SupervisedUserImportHandler : public OptionsPageUIHandler, - public ProfileAttributesStorage::Observer, - public SupervisedUserSyncServiceObserver, - public SigninErrorController::Observer { - public: - typedef base::CallbackList<void(const std::string&, const std::string&)> - CallbackList; - - SupervisedUserImportHandler(); - ~SupervisedUserImportHandler() override; - - private: - // OptionsPageUIHandler implementation. - void GetLocalizedValues(base::DictionaryValue* localized_strings) override; - void InitializeHandler() override; - - // WebUIMessageHandler implementation. - void RegisterMessages() override; - - // ProfileAttributesStorage::Observer implementation. - void OnProfileAdded(const base::FilePath& profile_path) override; - void OnProfileWillBeRemoved(const base::FilePath& profile_path) override; - void OnProfileWasRemoved(const base::FilePath& profile_path, - const base::string16& profile_name) override; - void OnProfileIsOmittedChanged(const base::FilePath& profile_path) override; - - // SupervisedUserSyncServiceObserver implementation. - void OnSupervisedUserAcknowledged( - const std::string& supervised_user_id) override {} - void OnSupervisedUsersSyncingStopped() override {} - void OnSupervisedUsersChanged() override; - - // SigninErrorController::Observer implementation. - void OnErrorChanged() override; - - // Clears the cached list of supervised users and fetches the new list of - // supervised users. - void FetchSupervisedUsers(); - - // Callback for the "requestSupervisedUserImportUpdate" message. - // Checks the sign-in status of the custodian and accordingly - // sends an update to the WebUI. The update can be to show/hide - // an error bubble and update/clear the supervised user list. - void RequestSupervisedUserImportUpdate(const base::ListValue* args); - - // Sends an array of supervised users to WebUI. Each entry is of the form: - // supervisedProfile = { - // id: "Supervised User ID", - // name: "Supervised User Name", - // iconURL: "chrome://path/to/icon/image", - // onCurrentDevice: true or false, - // needAvatar: true or false - // } - // The array holds all existing supervised users attached to the - // custodian's profile which initiated the request. - void SendExistingSupervisedUsers(const base::DictionaryValue* dict); - - // Sends messages to the JS side to clear supervised users and show an error - // bubble. - void ClearSupervisedUsersAndShowError(); - - bool IsAccountConnected() const; - bool HasAuthError() const; - - // Called when a supervised user shared setting is changed. If the avatar was - // changed, FetchSupervisedUsers() is called. - void OnSharedSettingChanged(const std::string& supervised_user_id, - const std::string& key); - - std::unique_ptr<CallbackList::Subscription> subscription_; - - ScopedObserver<ProfileAttributesStorage, SupervisedUserImportHandler> - profile_observer_; - ScopedObserver<SigninErrorController, SupervisedUserImportHandler> - signin_error_observer_; - ScopedObserver<SupervisedUserSyncService, SupervisedUserImportHandler> - supervised_user_sync_service_observer_; - - bool removed_profile_is_supervised_; - - base::WeakPtrFactory<SupervisedUserImportHandler> weak_ptr_factory_; - - DISALLOW_COPY_AND_ASSIGN(SupervisedUserImportHandler); -}; - -} // namespace options - -#endif // CHROME_BROWSER_UI_WEBUI_OPTIONS_SUPERVISED_USER_IMPORT_HANDLER_H_
diff --git a/chrome/browser/ui/webui/options/supervised_user_learn_more_handler.cc b/chrome/browser/ui/webui/options/supervised_user_learn_more_handler.cc deleted file mode 100644 index f7707e89..0000000 --- a/chrome/browser/ui/webui/options/supervised_user_learn_more_handler.cc +++ /dev/null
@@ -1,42 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/webui/options/supervised_user_learn_more_handler.h" - -#include "base/macros.h" -#include "base/strings/utf_string_conversions.h" -#include "base/values.h" -#include "chrome/common/url_constants.h" -#include "chrome/grit/generated_resources.h" -#include "ui/base/l10n/l10n_util.h" - -namespace options { - -SupervisedUserLearnMoreHandler::SupervisedUserLearnMoreHandler() { -} - -SupervisedUserLearnMoreHandler::~SupervisedUserLearnMoreHandler() { -} - -void SupervisedUserLearnMoreHandler::GetLocalizedValues( - base::DictionaryValue* localized_strings) { - DCHECK(localized_strings); - - static OptionsStringResource resources[] = { - { "supervisedUserLearnMoreTitle", - IDS_LEGACY_SUPERVISED_USER_LEARN_MORE_TITLE }, - { "supervisedUserLearnMoreDone", - IDS_LEGACY_SUPERVISED_USER_LEARN_MORE_DONE_BUTTON }, - }; - - base::string16 supervised_user_dashboard_display = - base::ASCIIToUTF16(chrome::kLegacySupervisedUserManagementDisplayURL); - localized_strings->SetString("supervisedUserLearnMoreText", - l10n_util::GetStringFUTF16(IDS_LEGACY_SUPERVISED_USER_LEARN_MORE_TEXT, - supervised_user_dashboard_display)); - - RegisterStrings(localized_strings, resources, arraysize(resources)); -} - -} // namespace options
diff --git a/chrome/browser/ui/webui/options/supervised_user_learn_more_handler.h b/chrome/browser/ui/webui/options/supervised_user_learn_more_handler.h deleted file mode 100644 index 4d17286..0000000 --- a/chrome/browser/ui/webui/options/supervised_user_learn_more_handler.h +++ /dev/null
@@ -1,33 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_WEBUI_OPTIONS_SUPERVISED_USER_LEARN_MORE_HANDLER_H_ -#define CHROME_BROWSER_UI_WEBUI_OPTIONS_SUPERVISED_USER_LEARN_MORE_HANDLER_H_ - -#include "base/macros.h" -#include "chrome/browser/ui/webui/options/options_ui.h" - -namespace base { -class DictionaryValue; -} - -namespace options { - -// Handler for the "Learn more" dialog available during creation of a supervised -// user. -class SupervisedUserLearnMoreHandler : public OptionsPageUIHandler { - public: - SupervisedUserLearnMoreHandler(); - ~SupervisedUserLearnMoreHandler() override; - - // OptionsPageUIHandler implementation. - void GetLocalizedValues(base::DictionaryValue* localized_strings) override; - - private: - DISALLOW_COPY_AND_ASSIGN(SupervisedUserLearnMoreHandler); -}; - -} // namespace options - -#endif // CHROME_BROWSER_UI_WEBUI_OPTIONS_SUPERVISED_USER_LEARN_MORE_HANDLER_H_
diff --git a/chrome/browser/ui/webui/options/sync_setup_handler.cc b/chrome/browser/ui/webui/options/sync_setup_handler.cc deleted file mode 100644 index de91eaf7..0000000 --- a/chrome/browser/ui/webui/options/sync_setup_handler.cc +++ /dev/null
@@ -1,955 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/webui/options/sync_setup_handler.h" - -#include <string> - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/command_line.h" -#include "base/compiler_specific.h" -#include "base/i18n/time_formatting.h" -#include "base/json/json_reader.h" -#include "base/json/json_writer.h" -#include "base/macros.h" -#include "base/metrics/histogram_macros.h" -#include "base/strings/utf_string_conversions.h" -#include "base/values.h" -#include "build/build_config.h" -#include "chrome/app/chrome_command_ids.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/lifetime/application_lifetime.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/profiles/profile_metrics.h" -#include "chrome/browser/signin/chrome_signin_helper.h" -#include "chrome/browser/signin/signin_error_controller_factory.h" -#include "chrome/browser/signin/signin_manager_factory.h" -#include "chrome/browser/signin/signin_promo.h" -#include "chrome/browser/sync/profile_sync_service_factory.h" -#include "chrome/browser/ui/browser_finder.h" -#include "chrome/browser/ui/browser_window.h" -#include "chrome/browser/ui/singleton_tabs.h" -#include "chrome/browser/ui/webui/profile_helper.h" -#include "chrome/browser/ui/webui/signin/login_ui_service.h" -#include "chrome/browser/ui/webui/signin/login_ui_service_factory.h" -#include "chrome/common/chrome_switches.h" -#include "chrome/common/url_constants.h" -#include "chrome/grit/chromium_strings.h" -#include "chrome/grit/generated_resources.h" -#include "components/autofill/core/common/autofill_constants.h" -#include "components/autofill/core/common/autofill_pref_names.h" -#include "components/browser_sync/profile_sync_service.h" -#include "components/google/core/browser/google_util.h" -#include "components/prefs/pref_service.h" -#include "components/signin/core/browser/signin_error_controller.h" -#include "components/signin/core/browser/signin_header_helper.h" -#include "components/signin/core/browser/signin_metrics.h" -#include "components/signin/core/common/profile_management_switches.h" -#include "components/strings/grit/components_strings.h" -#include "components/sync/base/sync_prefs.h" -#include "content/public/browser/render_view_host.h" -#include "content/public/browser/web_contents.h" -#include "content/public/browser/web_contents_delegate.h" -#include "google_apis/gaia/gaia_auth_util.h" -#include "google_apis/gaia/gaia_constants.h" -#include "net/base/url_util.h" -#include "ui/base/l10n/l10n_util.h" - -#if defined(OS_CHROMEOS) -#include "components/signin/core/browser/signin_manager_base.h" -#else -#include "components/signin/core/browser/signin_manager.h" -#endif - -using browser_sync::ProfileSyncService; -using content::WebContents; -using l10n_util::GetStringFUTF16; -using l10n_util::GetStringUTF16; - -namespace { - -// A structure which contains all the configuration information for sync. -struct SyncConfigInfo { - SyncConfigInfo(); - ~SyncConfigInfo(); - - bool encrypt_all; - bool sync_everything; - syncer::ModelTypeSet data_types; - bool payments_integration_enabled; - std::string passphrase; - bool passphrase_is_gaia; -}; - -SyncConfigInfo::SyncConfigInfo() - : encrypt_all(false), - sync_everything(false), - payments_integration_enabled(false), - passphrase_is_gaia(false) {} - -SyncConfigInfo::~SyncConfigInfo() {} - -bool GetConfiguration(const std::string& json, SyncConfigInfo* config) { - std::unique_ptr<base::Value> parsed_value = base::JSONReader::Read(json); - base::DictionaryValue* result; - if (!parsed_value || !parsed_value->GetAsDictionary(&result)) { - DLOG(ERROR) << "GetConfiguration() not passed a Dictionary"; - return false; - } - - if (!result->GetBoolean("syncAllDataTypes", &config->sync_everything)) { - DLOG(ERROR) << "GetConfiguration() not passed a syncAllDataTypes value"; - return false; - } - - if (!result->GetBoolean("paymentsIntegrationEnabled", - &config->payments_integration_enabled)) { - DLOG(ERROR) << "GetConfiguration() not passed a paymentsIntegrationEnabled " - << "value"; - return false; - } - - syncer::ModelTypeNameMap type_names = syncer::GetUserSelectableTypeNameMap(); - - for (syncer::ModelTypeNameMap::const_iterator it = type_names.begin(); - it != type_names.end(); ++it) { - std::string key_name = it->second + std::string("Synced"); - bool sync_value; - if (!result->GetBoolean(key_name, &sync_value)) { - DLOG(ERROR) << "GetConfiguration() not passed a value for " << key_name; - return false; - } - if (sync_value) - config->data_types.Put(it->first); - } - - // Encryption settings. - if (!result->GetBoolean("encryptAllData", &config->encrypt_all)) { - DLOG(ERROR) << "GetConfiguration() not passed a value for encryptAllData"; - return false; - } - - // Passphrase settings. - bool have_passphrase; - if (!result->GetBoolean("usePassphrase", &have_passphrase)) { - DLOG(ERROR) << "GetConfiguration() not passed a usePassphrase value"; - return false; - } - - if (have_passphrase) { - if (!result->GetBoolean("isGooglePassphrase", - &config->passphrase_is_gaia)) { - DLOG(ERROR) << "GetConfiguration() not passed isGooglePassphrase value"; - return false; - } - if (!result->GetString("passphrase", &config->passphrase)) { - DLOG(ERROR) << "GetConfiguration() not passed a passphrase value"; - return false; - } - } - return true; -} - -} // namespace - -SyncSetupHandler::SyncSetupHandler() - : configuring_sync_(false) { -} - -SyncSetupHandler::~SyncSetupHandler() { - // Just exit if running unit tests (no actual WebUI is attached). - if (!web_ui()) - return; - - // This case is hit when the user performs a back navigation. - CloseSyncSetup(); -} - -void SyncSetupHandler::GetLocalizedValues( - base::DictionaryValue* localized_strings) { - GetStaticLocalizedValues(localized_strings, web_ui()); -} - -void SyncSetupHandler::GetStaticLocalizedValues( - base::DictionaryValue* localized_strings, - content::WebUI* web_ui) { - DCHECK(localized_strings); - - base::string16 product_name(GetStringUTF16(IDS_PRODUCT_NAME)); - localized_strings->SetString( - "chooseDataTypesInstructions", - GetStringFUTF16(IDS_SYNC_CHOOSE_DATATYPES_INSTRUCTIONS, product_name)); - localized_strings->SetString("autofillHelpURL", autofill::kHelpURL); - localized_strings->SetString( - "encryptionInstructions", - GetStringFUTF16(IDS_SYNC_ENCRYPTION_INSTRUCTIONS, product_name)); - localized_strings->SetString( - "encryptionHelpURL", chrome::kSyncEncryptionHelpURL); - localized_strings->SetString( - "encryptionSectionMessage", - GetStringFUTF16(IDS_SYNC_ENCRYPTION_SECTION_MESSAGE, product_name)); - localized_strings->SetString( - "personalizeGoogleServicesTitle", - GetStringUTF16(IDS_SYNC_CONFIRMATION_PERSONALIZE_SERVICES_TITLE)); - localized_strings->SetString( - "personalizeGoogleServicesMessage", - GetStringFUTF16( - IDS_SYNC_PERSONALIZE_GOOGLE_SERVICES_MESSAGE, - base::ASCIIToUTF16(chrome::kGoogleAccountActivityControlsURL))); - localized_strings->SetString( - "passphraseRecover", - GetStringFUTF16( - IDS_SYNC_PASSPHRASE_RECOVER, - base::ASCIIToUTF16( - google_util::AppendGoogleLocaleParam( - GURL(chrome::kSyncGoogleDashboardURL), - g_browser_process->GetApplicationLocale()).spec()))); - localized_strings->SetString( - "stopSyncingExplanation", - l10n_util::GetStringFUTF16( - IDS_SYNC_STOP_SYNCING_EXPLANATION_LABEL, - l10n_util::GetStringUTF16(IDS_PRODUCT_NAME), - base::ASCIIToUTF16( - google_util::AppendGoogleLocaleParam( - GURL(chrome::kSyncGoogleDashboardURL), - g_browser_process->GetApplicationLocale()).spec()))); - localized_strings->SetString("deleteProfileLabel", - l10n_util::GetStringUTF16(IDS_SYNC_STOP_DELETE_PROFILE_LABEL)); - localized_strings->SetString("stopSyncingTitle", - l10n_util::GetStringUTF16(IDS_SYNC_STOP_SYNCING_DIALOG_TITLE)); - localized_strings->SetString("stopSyncingConfirm", - l10n_util::GetStringUTF16(IDS_SYNC_STOP_SYNCING_CONFIRM_BUTTON_LABEL)); - - localized_strings->SetString( - "syncEverythingHelpURL", chrome::kSyncEverythingLearnMoreURL); - localized_strings->SetString( - "syncErrorHelpURL", chrome::kSyncErrorsHelpURL); - - static OptionsStringResource resources[] = { - {"syncSetupConfigureTitle", IDS_SYNC_SETUP_CONFIGURE_TITLE}, - {"syncSetupSpinnerTitle", IDS_SYNC_SETUP_SPINNER_TITLE}, - {"syncSetupTimeoutTitle", IDS_SYNC_SETUP_TIME_OUT_TITLE}, - {"syncSetupTimeoutContent", IDS_SYNC_SETUP_TIME_OUT_CONTENT}, - {"errorLearnMore", IDS_LEARN_MORE}, - {"cancel", IDS_CANCEL}, - {"loginSuccess", IDS_SYNC_SUCCESS}, - {"settingUp", IDS_SYNC_LOGIN_SETTING_UP}, - {"syncAllDataTypes", IDS_SYNC_EVERYTHING}, - {"chooseDataTypes", IDS_SYNC_CHOOSE_DATATYPES}, - {"bookmarks", IDS_SYNC_DATATYPE_BOOKMARKS}, - {"preferences", IDS_SYNC_DATATYPE_PREFERENCES}, - {"autofill", IDS_SYNC_DATATYPE_AUTOFILL}, - {"themes", IDS_SYNC_DATATYPE_THEMES}, - {"passwords", IDS_SYNC_DATATYPE_PASSWORDS}, - {"extensions", IDS_SYNC_DATATYPE_EXTENSIONS}, - {"typedURLs", IDS_SYNC_DATATYPE_TYPED_URLS}, - {"apps", IDS_SYNC_DATATYPE_APPS}, - {"openTabs", IDS_SYNC_DATATYPE_TABS}, - {"enablePaymentsIntegration", IDS_AUTOFILL_USE_PAYMENTS_DATA}, - {"serviceUnavailableError", IDS_SYNC_SETUP_ABORTED_BY_PENDING_CLEAR}, - {"confirmLabel", IDS_SYNC_CONFIRM_PASSPHRASE_LABEL}, - {"emptyErrorMessage", IDS_SYNC_EMPTY_PASSPHRASE_ERROR}, - {"mismatchErrorMessage", IDS_SYNC_PASSPHRASE_MISMATCH_ERROR}, - {"customizeLinkLabel", IDS_SYNC_CUSTOMIZE_LINK_LABEL}, - {"confirmSyncPreferences", IDS_SYNC_CONFIRM_SYNC_PREFERENCES}, - {"syncEverything", IDS_SYNC_SYNC_EVERYTHING}, - {"useDefaultSettings", IDS_SYNC_USE_DEFAULT_SETTINGS}, - {"enterPassphraseBody", IDS_SYNC_ENTER_PASSPHRASE_BODY}, - {"enterGooglePassphraseBody", IDS_SYNC_ENTER_GOOGLE_PASSPHRASE_BODY}, - {"passphraseLabel", IDS_SYNC_PASSPHRASE_LABEL}, - {"incorrectPassphrase", IDS_SYNC_INCORRECT_PASSPHRASE}, - {"passphraseWarning", IDS_SYNC_PASSPHRASE_WARNING}, - {"yes", IDS_SYNC_PASSPHRASE_CANCEL_YES}, - {"no", IDS_SYNC_PASSPHRASE_CANCEL_NO}, - {"sectionExplicitMessagePrefix", IDS_SYNC_PASSPHRASE_MSG_EXPLICIT_PREFIX}, - {"sectionExplicitMessagePostfix", - IDS_SYNC_PASSPHRASE_MSG_EXPLICIT_POSTFIX}, - // TODO(rogerta): browser/resource/sync_promo/sync_promo.html and related - // file may not be needed any more. If not, then the following promo - // strings can also be removed. - {"promoPageTitle", IDS_SYNC_PROMO_TAB_TITLE}, - {"promoSkipButton", IDS_SYNC_PROMO_SKIP_BUTTON}, - {"promoAdvanced", IDS_SYNC_PROMO_ADVANCED}, - {"promoLearnMore", IDS_LEARN_MORE}, - {"promoTitleShort", IDS_SYNC_PROMO_MESSAGE_TITLE_SHORT}, - {"encryptionSectionTitle", IDS_SYNC_ENCRYPTION_SECTION_TITLE}, - {"basicEncryptionOption", IDS_SYNC_BASIC_ENCRYPTION_DATA}, - {"fullEncryptionOption", IDS_SYNC_FULL_ENCRYPTION_DATA}, - }; - - RegisterStrings(localized_strings, resources, arraysize(resources)); - RegisterTitle(localized_strings, "syncSetupOverlay", IDS_SYNC_SETUP_TITLE); -} - -void SyncSetupHandler::ConfigureSyncDone() { - base::Value page("done"); - web_ui()->CallJavascriptFunctionUnsafe("SyncSetupOverlay.showSyncSetupPage", - page); - - // Suppress the sign in promo once the user starts sync. This way the user - // doesn't see the sign in promo even if they sign out later on. - signin::SetUserSkippedPromo(GetProfile()); - - ProfileSyncService* service = GetSyncService(); - DCHECK(service); - if (!service->IsFirstSetupComplete()) { - // This is the first time configuring sync, so log it. - base::FilePath profile_file_path = GetProfile()->GetPath(); - ProfileMetrics::LogProfileSyncSignIn(profile_file_path); - - // We're done configuring, so notify ProfileSyncService that it is OK to - // start syncing. - sync_blocker_.reset(); - service->SetFirstSetupComplete(); - } -} - -bool SyncSetupHandler::IsActiveLogin() const { - // LoginUIService can be NULL if page is brought up in incognito mode - // (i.e. if the user is running in guest mode in cros and brings up settings). - LoginUIService* service = GetLoginUIService(); - return service && (service->current_login_ui() == this); -} - -void SyncSetupHandler::RegisterMessages() { - web_ui()->RegisterMessageCallback( - "SyncSetupDidClosePage", - base::Bind(&SyncSetupHandler::OnDidClosePage, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "SyncSetupConfigure", - base::Bind(&SyncSetupHandler::HandleConfigure, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "SyncSetupShowSetupUI", - base::Bind(&SyncSetupHandler::HandleShowSetupUI, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("CloseTimeout", - base::Bind(&SyncSetupHandler::HandleCloseTimeout, - base::Unretained(this))); -#if defined(OS_CHROMEOS) - web_ui()->RegisterMessageCallback( - "AttemptUserExit", - base::Bind(&SyncSetupHandler::HandleAttemptUserExit, - base::Unretained(this))); -#else - web_ui()->RegisterMessageCallback("SyncSetupStopSyncing", - base::Bind(&SyncSetupHandler::HandleStopSyncing, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("SyncSetupStartSignIn", - base::Bind(&SyncSetupHandler::HandleStartSignin, - base::Unretained(this))); -#endif -} - -#if !defined(OS_CHROMEOS) -void SyncSetupHandler::DisplayGaiaLogin( - signin_metrics::AccessPoint access_point) { - DCHECK(!sync_startup_tracker_); - // Advanced options are no longer being configured if the login screen is - // visible. If the user exits the signin wizard after this without - // configuring sync, CloseSyncSetup() will ensure they are logged out. - configuring_sync_ = false; - DisplayGaiaLoginInNewTabOrWindow(access_point); -} - -void SyncSetupHandler::DisplayGaiaLoginInNewTabOrWindow( - signin_metrics::AccessPoint access_point) { - Browser* browser = chrome::FindBrowserWithWebContents( - web_ui()->GetWebContents()); - bool force_new_tab = false; - if (!browser) { - // Settings is not displayed in a browser window. Open a new window. - browser = new Browser( - Browser::CreateParams(Browser::TYPE_TABBED, GetProfile(), true)); - force_new_tab = true; - } - - // If the signin manager already has an authenticated username, this is a - // re-auth scenario, and we need to ensure that the user signs in with the - // same email address. - GURL url; - if (SigninManagerFactory::GetForProfile( - browser->profile())->IsAuthenticated()) { - UMA_HISTOGRAM_ENUMERATION("Signin.Reauth", - signin_metrics::HISTOGRAM_REAUTH_SHOWN, - signin_metrics::HISTOGRAM_REAUTH_MAX); - - SigninErrorController* error_controller = - SigninErrorControllerFactory::GetForProfile(browser->profile()); - DCHECK(error_controller->HasError()); - if (!force_new_tab) { - browser->window()->ShowAvatarBubbleFromAvatarButton( - BrowserWindow::AVATAR_BUBBLE_MODE_REAUTH, - signin::ManageAccountsParams(), access_point, false); - } else { - url = signin::GetReauthURL( - access_point, signin_metrics::Reason::REASON_REAUTHENTICATION, - browser->profile(), error_controller->error_account_id()); - } - } else { - if (!force_new_tab) { - browser->window()->ShowAvatarBubbleFromAvatarButton( - BrowserWindow::AVATAR_BUBBLE_MODE_SIGNIN, - signin::ManageAccountsParams(), access_point, false); - } else { - url = signin::GetPromoURL( - access_point, signin_metrics::Reason::REASON_SIGNIN_PRIMARY_ACCOUNT, - true); - } - } - - if (url.is_valid()) - chrome::ShowSingletonTab(browser, url); -} -#endif - -bool SyncSetupHandler::PrepareSyncSetup() { - // If the wizard is already visible, just focus that one. - if (FocusExistingWizardIfPresent()) { - if (!IsActiveLogin()) - CloseSyncSetup(); - return false; - } - - // Notify services that login UI is now active. - GetLoginUIService()->SetLoginUI(this); - - ProfileSyncService* service = GetSyncService(); - if (service) - sync_blocker_ = service->GetSetupInProgressHandle(); - - return true; -} - -void SyncSetupHandler::DisplaySpinner() { - configuring_sync_ = true; - base::Value page("spinner"); - base::DictionaryValue args; - - const int kTimeoutSec = 30; - DCHECK(!engine_start_timer_); - engine_start_timer_.reset(new base::OneShotTimer()); - engine_start_timer_->Start(FROM_HERE, - base::TimeDelta::FromSeconds(kTimeoutSec), this, - &SyncSetupHandler::DisplayTimeout); - - web_ui()->CallJavascriptFunctionUnsafe("SyncSetupOverlay.showSyncSetupPage", - page, args); -} - -// TODO(kochi): Handle error conditions other than timeout. -// http://crbug.com/128692 -void SyncSetupHandler::DisplayTimeout() { - // Stop a timer to handle timeout in waiting for checking network connection. - engine_start_timer_.reset(); - - // Do not listen to sync startup events. - sync_startup_tracker_.reset(); - - base::Value page("timeout"); - base::DictionaryValue args; - web_ui()->CallJavascriptFunctionUnsafe("SyncSetupOverlay.showSyncSetupPage", - page, args); -} - -void SyncSetupHandler::OnDidClosePage(const base::ListValue* args) { - CloseSyncSetup(); -} - -void SyncSetupHandler::SyncStartupFailed() { - // Stop a timer to handle timeout in waiting for checking network connection. - engine_start_timer_.reset(); - - // Just close the sync overlay (the idea is that the base settings page will - // display the current error.) - CloseUI(); -} - -void SyncSetupHandler::SyncStartupCompleted() { - ProfileSyncService* service = GetSyncService(); - DCHECK(service->IsEngineInitialized()); - - // Stop a timer to handle timeout in waiting for checking network connection. - engine_start_timer_.reset(); - - DisplayConfigureSync(false); -} - -Profile* SyncSetupHandler::GetProfile() const { - return Profile::FromWebUI(web_ui()); -} - -ProfileSyncService* SyncSetupHandler::GetSyncService() const { - Profile* profile = GetProfile(); - return profile->IsSyncAllowed() ? - ProfileSyncServiceFactory::GetForProfile(GetProfile()) : NULL; -} - -void SyncSetupHandler::HandleConfigure(const base::ListValue* args) { - DCHECK(!sync_startup_tracker_); - std::string json; - if (!args->GetString(0, &json)) { - NOTREACHED() << "Could not read JSON argument"; - return; - } - if (json.empty()) { - NOTREACHED(); - return; - } - - SyncConfigInfo configuration; - if (!GetConfiguration(json, &configuration)) { - // The page sent us something that we didn't understand. - // This probably indicates a programming error. - NOTREACHED(); - return; - } - - // Start configuring the ProfileSyncService using the configuration passed - // to us from the JS layer. - ProfileSyncService* service = GetSyncService(); - - // If the sync engine has shutdown for some reason, just close the sync - // dialog. - if (!service || !service->IsEngineInitialized()) { - CloseUI(); - return; - } - - // Don't allow "encrypt all" if the ProfileSyncService doesn't allow it. - // The UI is hidden, but the user may have enabled it e.g. by fiddling with - // the web inspector. - if (!service->IsEncryptEverythingAllowed()) - configuration.encrypt_all = false; - - // Note: Data encryption will not occur until configuration is complete - // (when the PSS receives its CONFIGURE_DONE notification from the sync - // engine), so the user still has a chance to cancel out of the operation - // if (for example) some kind of passphrase error is encountered. - if (configuration.encrypt_all) - service->EnableEncryptEverything(); - - bool passphrase_failed = false; - if (!configuration.passphrase.empty()) { - // We call IsPassphraseRequired() here (instead of - // IsPassphraseRequiredForDecryption()) because the user may try to enter - // a passphrase even though no encrypted data types are enabled. - if (service->IsPassphraseRequired()) { - // If we have pending keys, try to decrypt them with the provided - // passphrase. We track if this succeeds or fails because a failed - // decryption should result in an error even if there aren't any encrypted - // data types. - passphrase_failed = - !service->SetDecryptionPassphrase(configuration.passphrase); - } else { - // OK, the user sent us a passphrase, but we don't have pending keys. So - // it either means that the pending keys were resolved somehow since the - // time the UI was displayed (re-encryption, pending passphrase change, - // etc) or the user wants to re-encrypt. - if (!configuration.passphrase_is_gaia && - !service->IsUsingSecondaryPassphrase()) { - // User passed us a secondary passphrase, and the data is encrypted - // with a GAIA passphrase so they must want to encrypt. - service->SetEncryptionPassphrase(configuration.passphrase, - ProfileSyncService::EXPLICIT); - } - } - } - - bool user_was_prompted_for_passphrase = - service->IsPassphraseRequiredForDecryption(); - service->OnUserChoseDatatypes(configuration.sync_everything, - configuration.data_types); - - PrefService* pref_service = GetProfile()->GetPrefs(); - pref_service->SetBoolean(autofill::prefs::kAutofillWalletImportEnabled, - configuration.payments_integration_enabled); - - // Need to call IsPassphraseRequiredForDecryption() *after* calling - // OnUserChoseDatatypes() because the user may have just disabled the - // encrypted datatypes (in which case we just want to exit, not prompt the - // user for a passphrase). - if (passphrase_failed || service->IsPassphraseRequiredForDecryption()) { - // We need a passphrase, or the user's attempt to set a passphrase failed - - // prompt them again. This covers a few subtle cases: - // 1) The user enters an incorrect passphrase *and* disabled the encrypted - // data types. In that case we want to notify the user that the - // passphrase was incorrect even though there are no longer any encrypted - // types enabled (IsPassphraseRequiredForDecryption() == false). - // 2) The user doesn't enter any passphrase. In this case, we won't call - // SetDecryptionPassphrase() (passphrase_failed == false), but we still - // want to display an error message to let the user know that their - // blank passphrase entry is not acceptable. - // 3) The user just enabled an encrypted data type - in this case we don't - // want to display an "invalid passphrase" error, since it's the first - // time the user is seeing the prompt. - DisplayConfigureSync(passphrase_failed || user_was_prompted_for_passphrase); - } else { - // No passphrase is required from the user so mark the configuration as - // complete and close the sync setup overlay. - ConfigureSyncDone(); - } - - ProfileMetrics::LogProfileSyncInfo(ProfileMetrics::SYNC_CUSTOMIZE); - if (configuration.encrypt_all) - ProfileMetrics::LogProfileSyncInfo(ProfileMetrics::SYNC_ENCRYPT); - if (configuration.passphrase_is_gaia && !configuration.passphrase.empty()) - ProfileMetrics::LogProfileSyncInfo(ProfileMetrics::SYNC_PASSPHRASE); - if (!configuration.sync_everything) - ProfileMetrics::LogProfileSyncInfo(ProfileMetrics::SYNC_CHOOSE); -} - -void SyncSetupHandler::HandleShowSetupUI(const base::ListValue* args) { - if (!GetSyncService()) { - DLOG(WARNING) << "Cannot display sync UI when sync is disabled"; - CloseUI(); - return; - } - - SigninManagerBase* signin = - SigninManagerFactory::GetForProfile(GetProfile()); - if (!signin->IsAuthenticated()) { - // For web-based signin, the signin page is not displayed in an overlay - // on the settings page. So if we get here, it must be due to the user - // cancelling signin (by reloading the sync settings page during initial - // signin) or by directly navigating to settings/syncSetup - // (http://crbug.com/229836). So just exit and go back to the settings page. - DLOG(WARNING) << "Cannot display sync setup UI when not signed in"; - CloseUI(); - return; - } - - // If a setup wizard is already present, but not on this page, close the - // blank setup overlay on this page by showing the "done" page. This can - // happen if the user navigates to chrome://settings/syncSetup in more than - // one tab. See crbug.com/261566. - // Note: The following block will transfer focus to the existing wizard. - if (IsExistingWizardPresent() && !IsActiveLogin()) - CloseUI(); - - // If a setup wizard is present on this page or another, bring it to focus. - // Otherwise, display a new one on this page. - if (!FocusExistingWizardIfPresent()) - OpenSyncSetup(false /* creating_supervised_user */); -} - -#if defined(OS_CHROMEOS) -// On ChromeOS, we need to sign out the user session to fix an auth error, so -// the user goes through the real signin flow to generate a new auth token. -void SyncSetupHandler::HandleAttemptUserExit(const base::ListValue* args) { - chrome::AttemptUserExit(); -} -#endif - -#if !defined(OS_CHROMEOS) -void SyncSetupHandler::HandleStartSignin(const base::ListValue* args) { - // Should only be called if the user is not already signed in or has an auth - // error. - DCHECK( - !SigninManagerFactory::GetForProfile(GetProfile())->IsAuthenticated() || - SigninErrorControllerFactory::GetForProfile(GetProfile())->HasError()); - bool creating_supervised_user = false; - args->GetBoolean(0, &creating_supervised_user); - OpenSyncSetup(creating_supervised_user); -} - -void SyncSetupHandler::HandleStopSyncing(const base::ListValue* args) { - if (GetSyncService()) - ProfileSyncService::SyncEvent(ProfileSyncService::STOP_FROM_OPTIONS); - - bool delete_profile = false; - args->GetBoolean(0, &delete_profile); - signin_metrics::SignoutDelete delete_metric = - delete_profile ? signin_metrics::SignoutDelete::DELETED - : signin_metrics::SignoutDelete::KEEPING; - SigninManagerFactory::GetForProfile(GetProfile()) - ->SignOut(signin_metrics::USER_CLICKED_SIGNOUT_SETTINGS, delete_metric); - - if (delete_profile) { - // Do as BrowserOptionsHandler::DeleteProfile(). - webui::DeleteProfileAtPath(GetProfile()->GetPath(), - web_ui(), - ProfileMetrics::DELETE_PROFILE_SETTINGS); - } -} -#endif - -void SyncSetupHandler::HandleCloseTimeout(const base::ListValue* args) { - CloseSyncSetup(); -} - -void SyncSetupHandler::CloseSyncSetup() { - // Stop a timer to handle timeout in waiting for checking network connection. - engine_start_timer_.reset(); - - // Clear the sync startup tracker, since the setup wizard is being closed. - sync_startup_tracker_.reset(); - - ProfileSyncService* sync_service = GetSyncService(); - if (IsActiveLogin()) { - // Don't log a cancel event if the sync setup dialog is being - // automatically closed due to an auth error. - if (!sync_service || (!sync_service->IsFirstSetupComplete() && - sync_service->GetAuthError().state() == - GoogleServiceAuthError::NONE)) { - if (configuring_sync_) { - ProfileSyncService::SyncEvent( - ProfileSyncService::CANCEL_DURING_CONFIGURE); - - // If the user clicked "Cancel" while setting up sync, disable sync - // because we don't want the sync engine to remain in the - // first-setup-incomplete state. - // Note: In order to disable sync across restarts on Chrome OS, - // we must call RequestStop(CLEAR_DATA), which suppresses sync startup - // in addition to disabling it. - if (sync_service) { - DVLOG(1) << "Sync setup aborted by user action"; - sync_service->RequestStop(ProfileSyncService::CLEAR_DATA); - #if !defined(OS_CHROMEOS) - // Sign out the user on desktop Chrome if they click cancel during - // initial setup. - // TODO(rsimha): Revisit this for M30. See http://crbug.com/252049. - if (sync_service->IsFirstSetupInProgress()) { - SigninManagerFactory::GetForProfile(GetProfile()) - ->SignOut(signin_metrics::ABORT_SIGNIN, - signin_metrics::SignoutDelete::IGNORE_METRIC); - } - #endif - } - } - } - } - - LoginUIService* service = GetLoginUIService(); - if (service) - service->LoginUIClosed(this); - - // Alert the sync service anytime the sync setup dialog is closed. This can - // happen due to the user clicking the OK or Cancel button, or due to the - // dialog being closed by virtue of sync being disabled in the background. - sync_blocker_.reset(); - - configuring_sync_ = false; -} - -void SyncSetupHandler::OpenSyncSetup(bool creating_supervised_user) { - if (!PrepareSyncSetup()) - return; - - // There are several different UI flows that can bring the user here: - // 1) Signin promo. - // 2) Normal signin through settings page (IsAuthenticated() is false). - // 3) Previously working credentials have expired. - // 4) User is signed in, but has stopped sync via the google dashboard, and - // signout is prohibited by policy so we need to force a re-auth. - // 5) User clicks [Advanced Settings] button on options page while already - // logged in. - // 6) One-click signin (credentials are already available, so should display - // sync configure UI, not login UI). - // 7) User re-enables sync after disabling it via advanced settings. -#if !defined(OS_CHROMEOS) - SigninManagerBase* signin = - SigninManagerFactory::GetForProfile(GetProfile()); - - if (!signin->IsAuthenticated() || - SigninErrorControllerFactory::GetForProfile(GetProfile())->HasError()) { - // User is not logged in (cases 1-2), or login has been specially requested - // because previously working credentials have expired (case 3). Close sync - // setup including any visible overlays, and display the gaia auth page. - // Control will be returned to the sync settings page once auth is complete. - CloseUI(); - DisplayGaiaLogin( - creating_supervised_user ? - signin_metrics::AccessPoint::ACCESS_POINT_SUPERVISED_USER : - signin_metrics::AccessPoint::ACCESS_POINT_SETTINGS); - return; - } -#endif - if (!GetSyncService()) { - // This can happen if the user directly navigates to /settings/syncSetup. - DLOG(WARNING) << "Cannot display sync UI when sync is disabled"; - CloseUI(); - return; - } - - // User is already logged in. They must have brought up the config wizard - // via the "Advanced..." button or through One-Click signin (cases 4-6), or - // they are re-enabling sync after having disabled it (case 7). - DisplayConfigureSync(false); -} - -void SyncSetupHandler::OpenConfigureSync() { - if (!PrepareSyncSetup()) - return; - - DisplayConfigureSync(false); -} - -void SyncSetupHandler::FocusUI() { - DCHECK(IsActiveLogin()); - WebContents* web_contents = web_ui()->GetWebContents(); - web_contents->GetDelegate()->ActivateContents(web_contents); -} - -void SyncSetupHandler::CloseUI() { - CloseSyncSetup(); - base::Value page("done"); - web_ui()->CallJavascriptFunctionUnsafe("SyncSetupOverlay.showSyncSetupPage", - page); -} - -bool SyncSetupHandler::IsExistingWizardPresent() { - LoginUIService* service = GetLoginUIService(); - DCHECK(service); - return service->current_login_ui() != NULL; -} - -bool SyncSetupHandler::FocusExistingWizardIfPresent() { - if (!IsExistingWizardPresent()) - return false; - - LoginUIService* service = GetLoginUIService(); - DCHECK(service); - service->current_login_ui()->FocusUI(); - return true; -} - -void SyncSetupHandler::DisplayConfigureSync(bool passphrase_failed) { - // Should never call this when we are not signed in. - DCHECK(SigninManagerFactory::GetForProfile( - GetProfile())->IsAuthenticated()); - ProfileSyncService* service = GetSyncService(); - DCHECK(service); - if (!service->IsEngineInitialized()) { - service->RequestStart(); - - // See if it's even possible to bring up the sync engine - if not - // (unrecoverable error?), don't bother displaying a spinner that will be - // immediately closed because this leads to some ugly infinite UI loop (see - // http://crbug.com/244769). - if (SyncStartupTracker::GetSyncServiceState(GetProfile()) != - SyncStartupTracker::SYNC_STARTUP_ERROR) { - DisplaySpinner(); - } - - // Start SyncSetupTracker to wait for sync to initialize. - sync_startup_tracker_.reset( - new SyncStartupTracker(GetProfile(), this)); - return; - } - - // Should only get here if user is signed in and sync is initialized, so no - // longer need a SyncStartupTracker. - sync_startup_tracker_.reset(); - configuring_sync_ = true; - DCHECK(service->IsEngineInitialized()) - << "Cannot configure sync until the sync engine is initialized"; - - // Setup args for the sync configure screen: - // syncAllDataTypes: true if the user wants to sync everything - // syncNothing: true if the user wants to sync nothing - // <data_type>Registered: true if the associated data type is supported - // <data_type>Synced: true if the user wants to sync that specific data type - // paymentsIntegrationEnabled: true if the user wants Payments integration - // encryptionEnabled: true if sync supports encryption - // encryptAllData: true if user wants to encrypt all data (not just - // passwords) - // usePassphrase: true if the data is encrypted with a secondary passphrase - // show_passphrase: true if a passphrase is needed to decrypt the sync data - base::DictionaryValue args; - - // Tell the UI layer which data types are registered/enabled by the user. - const syncer::ModelTypeSet registered_types = - service->GetRegisteredDataTypes(); - const syncer::ModelTypeSet preferred_types = service->GetPreferredDataTypes(); - const syncer::ModelTypeSet enforced_types = service->GetForcedDataTypes(); - syncer::ModelTypeNameMap type_names = syncer::GetUserSelectableTypeNameMap(); - for (syncer::ModelTypeNameMap::const_iterator it = type_names.begin(); - it != type_names.end(); ++it) { - syncer::ModelType sync_type = it->first; - const std::string key_name = it->second; - args.SetBoolean(key_name + "Registered", registered_types.Has(sync_type)); - args.SetBoolean(key_name + "Synced", preferred_types.Has(sync_type)); - args.SetBoolean(key_name + "Enforced", enforced_types.Has(sync_type)); - // TODO(treib): How do we want to handle pref groups, i.e. when only some of - // the sync types behind a checkbox are force-enabled? crbug.com/403326 - } - PrefService* pref_service = GetProfile()->GetPrefs(); - syncer::SyncPrefs sync_prefs(pref_service); - args.SetBoolean("passphraseFailed", passphrase_failed); - args.SetBoolean("syncAllDataTypes", sync_prefs.HasKeepEverythingSynced()); - args.SetBoolean("syncNothing", false); // Always false during initial setup. - args.SetBoolean( - "paymentsIntegrationEnabled", - pref_service->GetBoolean(autofill::prefs::kAutofillWalletImportEnabled)); - args.SetBoolean("encryptAllData", service->IsEncryptEverythingEnabled()); - args.SetBoolean("encryptAllDataAllowed", - service->IsEncryptEverythingAllowed()); - - // We call IsPassphraseRequired() here, instead of calling - // IsPassphraseRequiredForDecryption(), because we want to show the passphrase - // UI even if no encrypted data types are enabled. - args.SetBoolean("showPassphrase", service->IsPassphraseRequired()); - - // To distinguish between FROZEN_IMPLICIT_PASSPHRASE and CUSTOM_PASSPHRASE - // we only set usePassphrase for PassphraseType::CUSTOM_PASSPHRASE. - args.SetBoolean("usePassphrase", - service->GetPassphraseType() == - syncer::PassphraseType::CUSTOM_PASSPHRASE); - base::Time passphrase_time = service->GetExplicitPassphraseTime(); - syncer::PassphraseType passphrase_type = service->GetPassphraseType(); - if (!passphrase_time.is_null()) { - base::string16 passphrase_time_str = - base::TimeFormatShortDate(passphrase_time); - args.SetString( - "enterPassphraseBody", - GetStringFUTF16(IDS_SYNC_ENTER_PASSPHRASE_BODY_WITH_DATE, - passphrase_time_str)); - args.SetString( - "enterGooglePassphraseBody", - GetStringFUTF16(IDS_SYNC_ENTER_GOOGLE_PASSPHRASE_BODY_WITH_DATE, - passphrase_time_str)); - switch (passphrase_type) { - case syncer::PassphraseType::FROZEN_IMPLICIT_PASSPHRASE: - args.SetString( - "fullEncryptionBody", - GetStringFUTF16(IDS_SYNC_FULL_ENCRYPTION_BODY_GOOGLE_WITH_DATE, - passphrase_time_str)); - break; - case syncer::PassphraseType::CUSTOM_PASSPHRASE: - args.SetString( - "fullEncryptionBody", - GetStringFUTF16(IDS_SYNC_FULL_ENCRYPTION_BODY_CUSTOM_WITH_DATE, - passphrase_time_str)); - break; - default: - args.SetString( - "fullEncryptionBody", - GetStringUTF16(IDS_SYNC_FULL_ENCRYPTION_BODY_CUSTOM)); - break; - } - } else if (passphrase_type == syncer::PassphraseType::CUSTOM_PASSPHRASE) { - args.SetString( - "fullEncryptionBody", - GetStringUTF16(IDS_SYNC_FULL_ENCRYPTION_BODY_CUSTOM)); - } else { - args.SetString( - "fullEncryptionBody", - GetStringUTF16(IDS_SYNC_FULL_ENCRYPTION_DATA)); - } - - base::Value page("configure"); - web_ui()->CallJavascriptFunctionUnsafe("SyncSetupOverlay.showSyncSetupPage", - page, args); - - // Make sure the tab used for the Gaia sign in does not cover the settings - // tab. - FocusUI(); -} - -LoginUIService* SyncSetupHandler::GetLoginUIService() const { - return LoginUIServiceFactory::GetForProfile(GetProfile()); -}
diff --git a/chrome/browser/ui/webui/options/sync_setup_handler.h b/chrome/browser/ui/webui/options/sync_setup_handler.h deleted file mode 100644 index 993293f3..0000000 --- a/chrome/browser/ui/webui/options/sync_setup_handler.h +++ /dev/null
@@ -1,175 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_WEBUI_OPTIONS_SYNC_SETUP_HANDLER_H_ -#define CHROME_BROWSER_UI_WEBUI_OPTIONS_SYNC_SETUP_HANDLER_H_ - -#include <memory> - -#include "base/gtest_prod_util.h" -#include "base/macros.h" -#include "base/timer/timer.h" -#include "build/build_config.h" -#include "chrome/browser/sync/sync_startup_tracker.h" -#include "chrome/browser/ui/webui/options/options_ui.h" -#include "chrome/browser/ui/webui/signin/login_ui_service.h" - -class LoginUIService; - -namespace browser_sync { -class ProfileSyncService; -} // namespace browser_sync - -namespace signin_metrics { -enum class AccessPoint; -} // namespace signin_metrics - -namespace syncer { -class SyncSetupInProgressHandle; -} // namespace syncer - -class SyncSetupHandler : public options::OptionsPageUIHandler, - public SyncStartupTracker::Observer, - public LoginUIService::LoginUI { - public: - SyncSetupHandler(); - ~SyncSetupHandler() override; - - // OptionsPageUIHandler implementation. - void GetLocalizedValues(base::DictionaryValue* localized_strings) override; - void RegisterMessages() override; - - // SyncStartupTracker::Observer implementation; - void SyncStartupCompleted() override; - void SyncStartupFailed() override; - - // LoginUIService::LoginUI implementation. - void FocusUI() override; - - static void GetStaticLocalizedValues( - base::DictionaryValue* localized_strings, - content::WebUI* web_ui); - - // Initializes the sync setup flow and shows the setup UI. - void OpenSyncSetup(bool creating_supervised_user); - - // Shows advanced configuration dialog without going through sign in dialog. - // Kicks the sync engine if necessary with showing spinner dialog until it - // gets ready. - void OpenConfigureSync(); - - // Terminates the sync setup flow. - void CloseSyncSetup(); - - protected: - friend class SyncSetupHandlerTest; - FRIEND_TEST_ALL_PREFIXES(SyncSetupHandlerTest, - DisplayConfigureWithEngineDisabledAndCancel); - FRIEND_TEST_ALL_PREFIXES(SyncSetupHandlerTest, HandleSetupUIWhenSyncDisabled); - FRIEND_TEST_ALL_PREFIXES(SyncSetupHandlerTest, SelectCustomEncryption); - FRIEND_TEST_ALL_PREFIXES(SyncSetupHandlerTest, ShowSyncSetupWhenNotSignedIn); - FRIEND_TEST_ALL_PREFIXES(SyncSetupHandlerTest, SuccessfullySetPassphrase); - FRIEND_TEST_ALL_PREFIXES(SyncSetupHandlerTest, TestSyncEverything); - FRIEND_TEST_ALL_PREFIXES(SyncSetupHandlerTest, TestSyncNothing); - FRIEND_TEST_ALL_PREFIXES(SyncSetupHandlerTest, TestSyncAllManually); - FRIEND_TEST_ALL_PREFIXES(SyncSetupHandlerTest, TestPassphraseStillRequired); - FRIEND_TEST_ALL_PREFIXES(SyncSetupHandlerTest, TestSyncIndividualTypes); - FRIEND_TEST_ALL_PREFIXES(SyncSetupHandlerTest, TurnOnEncryptAll); - FRIEND_TEST_ALL_PREFIXES(SyncSetupHandlerTest, TurnOnEncryptAllDisallowed); - FRIEND_TEST_ALL_PREFIXES(SyncSetupHandlerTest, UnsuccessfullySetPassphrase); - FRIEND_TEST_ALL_PREFIXES(SyncSetupHandlerNonCrosTest, - UnrecoverableErrorInitializingSync); - FRIEND_TEST_ALL_PREFIXES(SyncSetupHandlerNonCrosTest, - GaiaErrorInitializingSync); - FRIEND_TEST_ALL_PREFIXES(SyncSetupHandlerNonCrosTest, HandleCaptcha); - FRIEND_TEST_ALL_PREFIXES(SyncSetupHandlerNonCrosTest, HandleGaiaAuthFailure); - FRIEND_TEST_ALL_PREFIXES(SyncSetupHandlerNonCrosTest, - SubmitAuthWithInvalidUsername); - FRIEND_TEST_ALL_PREFIXES(SyncSetupHandlerFirstSigninTest, DisplayBasicLogin); - - bool is_configuring_sync() const { return configuring_sync_; } - - // Called when configuring sync is done to close the dialog and start syncing. - void ConfigureSyncDone(); - - // Helper routine that gets the ProfileSyncService associated with the parent - // profile. - browser_sync::ProfileSyncService* GetSyncService() const; - - // Returns the LoginUIService for the parent profile. - LoginUIService* GetLoginUIService() const; - - private: - // Callbacks from the page. - void OnDidClosePage(const base::ListValue* args); - void HandleConfigure(const base::ListValue* args); - void HandlePassphraseEntry(const base::ListValue* args); - void HandlePassphraseCancel(const base::ListValue* args); - void HandleShowSetupUI(const base::ListValue* args); - void HandleAttemptUserExit(const base::ListValue* args); - void HandleStartSignin(const base::ListValue* args); - void HandleStopSyncing(const base::ListValue* args); - void HandleCloseTimeout(const base::ListValue* args); -#if !defined(OS_CHROMEOS) - // Displays the GAIA login form. - void DisplayGaiaLogin(signin_metrics::AccessPoint access_point); - - // When web-flow is enabled, displays the Gaia login form in a new tab. - // This function is virtual so that tests can override. - virtual void DisplayGaiaLoginInNewTabOrWindow( - signin_metrics::AccessPoint access_point); -#endif - - // Helper routine that gets the Profile associated with this object (virtual - // so tests can override). - virtual Profile* GetProfile() const; - - // A utility function to call before actually showing setup dialog. Makes sure - // that a new dialog can be shown and sets flag that setup is in progress. - bool PrepareSyncSetup(); - - // Displays spinner-only UI indicating that something is going on in the - // background. - // TODO(kochi): better to show some message that the user can understand what - // is running in the background. - void DisplaySpinner(); - - // Displays an error dialog which shows timeout of starting the sync engine. - void DisplayTimeout(); - - // Closes the associated sync settings page. - void CloseUI(); - - // Returns true if this object is the active login object. - bool IsActiveLogin() const; - - // If a wizard already exists, return true. Otherwise, return false. - bool IsExistingWizardPresent(); - - // If a wizard already exists, focus it and return true. - bool FocusExistingWizardIfPresent(); - - // Display the configure sync UI. If |passphrase_failed| is true, the account - // requires a passphrase and one hasn't been provided or it was invalid. - void DisplayConfigureSync(bool passphrase_failed); - - // Helper object used to wait for the sync engine to startup. - std::unique_ptr<SyncStartupTracker> sync_startup_tracker_; - - // Prevents Sync from running until configuration is complete. - std::unique_ptr<syncer::SyncSetupInProgressHandle> sync_blocker_; - - // Set to true whenever the sync configure UI is visible. This is used to tell - // what stage of the setup wizard the user was in and to update the UMA - // histograms in the case that the user cancels out. - bool configuring_sync_; - - // The OneShotTimer object used to timeout of starting the sync engine - // service. - std::unique_ptr<base::OneShotTimer> engine_start_timer_; - - DISALLOW_COPY_AND_ASSIGN(SyncSetupHandler); -}; - -#endif // CHROME_BROWSER_UI_WEBUI_OPTIONS_SYNC_SETUP_HANDLER_H_
diff --git a/chrome/browser/ui/webui/set_as_default_browser_ui_win.cc b/chrome/browser/ui/webui/set_as_default_browser_ui_win.cc index d0cecfb..9834fa8c 100644 --- a/chrome/browser/ui/webui/set_as_default_browser_ui_win.cc +++ b/chrome/browser/ui/webui/set_as_default_browser_ui_win.cc
@@ -52,16 +52,19 @@ const char kSetAsDefaultBrowserHistogram[] = "DefaultBrowser.InteractionResult"; -// The enum permits registering in UMA the three possible outcomes (do not +// The enum permits registering in UMA the four possible outcomes (do not // reorder these). // ACCEPTED: user pressed Next and made Chrome default. // DECLINED: user simply closed the dialog without making Chrome default. -// REGRETTED: user pressed Next but then elected a different default browser. +// REGRETTED: user pressed Next but then selected a different default browser. +// ACCEPTED_OTHER_MODE: user selected a different side-by-side install of +// Chrome. enum MakeChromeDefaultResult { MAKE_CHROME_DEFAULT_ACCEPTED = 0, MAKE_CHROME_DEFAULT_DECLINED = 1, MAKE_CHROME_DEFAULT_REGRETTED = 2, // MAKE_CHROME_DEFAULT_ACCEPTED_IMMERSE = 3, // Deprecated. + MAKE_CHROME_DEFAULT_ACCEPTED_OTHER_MODE = 4, MAKE_CHROME_DEFAULT_MAX }; @@ -166,12 +169,25 @@ shell_integration::DefaultWebClientState state) { // The callback is expected to be invoked once the procedure has completed. DCHECK_CURRENTLY_ON(BrowserThread::UI); - if (state == shell_integration::NOT_DEFAULT) { - // The operation concluded, but Chrome is still not the default. This - // suggests the user has decided not to make Chrome the default. - ConcludeInteraction(MAKE_CHROME_DEFAULT_REGRETTED); - } else if (state == shell_integration::IS_DEFAULT) { - ConcludeInteraction(MAKE_CHROME_DEFAULT_ACCEPTED); + switch (state) { + case shell_integration::NOT_DEFAULT: + // The operation concluded, but Chrome is still not the default. This + // suggests the user has decided not to make Chrome the default. + ConcludeInteraction(MAKE_CHROME_DEFAULT_REGRETTED); + break; + case shell_integration::IS_DEFAULT: + ConcludeInteraction(MAKE_CHROME_DEFAULT_ACCEPTED); + break; + case shell_integration::UNKNOWN_DEFAULT: + break; + case shell_integration::OTHER_MODE_IS_DEFAULT: + // Interestingly, the user picked a different install mode of this browser + // (e.g., stable Chrome rather than Chrome Beta). + ConcludeInteraction(MAKE_CHROME_DEFAULT_ACCEPTED_OTHER_MODE); + break; + case shell_integration::NUM_DEFAULT_STATES: + NOTREACHED(); + break; } // Otherwise, keep the dialog open since the user probably didn't make a @@ -298,8 +314,10 @@ // Suppress showing the default browser infobar if the user explicitly elected // *not to* make Chrome default. - if (dialog_interaction_result_ == MAKE_CHROME_DEFAULT_REGRETTED) + if (dialog_interaction_result_ == MAKE_CHROME_DEFAULT_REGRETTED || + dialog_interaction_result_ == MAKE_CHROME_DEFAULT_ACCEPTED_OTHER_MODE) { chrome::DefaultBrowserPromptDeclined(profile_); + } // Carry on with a normal chrome session. For the purpose of surfacing this // dialog the actual browser window had to remain hidden. Now it's time to
diff --git a/chrome/browser/ui/webui/settings/about_handler.cc b/chrome/browser/ui/webui/settings/about_handler.cc index 5061aad..783593ba 100644 --- a/chrome/browser/ui/webui/settings/about_handler.cc +++ b/chrome/browser/ui/webui/settings/about_handler.cc
@@ -8,7 +8,6 @@ #include <string> -#include "ash/system/devicetype_utils.h" #include "base/bind.h" #include "base/bind_helpers.h" #include "base/command_line.h" @@ -72,6 +71,7 @@ #include "chromeos/network/network_state_handler.h" #include "chromeos/system/statistics_provider.h" #include "components/user_manager/user_manager.h" +#include "ui/chromeos/devicetype_utils.h" #endif using base::ListValue;
diff --git a/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc index f622641..bd292189 100644 --- a/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc +++ b/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc
@@ -35,7 +35,6 @@ #if defined(OS_CHROMEOS) #include "ash/strings/grit/ash_strings.h" -#include "ash/system/devicetype_utils.h" #include "ash/system/night_light/night_light_controller.h" #include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos.h" #include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos_factory.h" @@ -47,6 +46,7 @@ #include "chromeos/chromeos_switches.h" #include "components/arc/arc_util.h" #include "components/user_manager/user_manager.h" +#include "ui/chromeos/devicetype_utils.h" #include "ui/chromeos/events/keyboard_layout_util.h" #include "ui/display/display_switches.h" #else @@ -293,7 +293,7 @@ html_source->AddString( "aboutUpgradeUpToDate", #if defined(OS_CHROMEOS) - ash::SubstituteChromeOSDeviceType(IDS_SETTINGS_UPGRADE_UP_TO_DATE)); + ui::SubstituteChromeOSDeviceType(IDS_SETTINGS_UPGRADE_UP_TO_DATE)); #else l10n_util::GetStringUTF16(IDS_SETTINGS_UPGRADE_UP_TO_DATE)); #endif @@ -815,7 +815,7 @@ arraysize(localized_strings)); base::string16 device_name = - l10n_util::GetStringUTF16(ash::GetChromeOSDeviceTypeResourceId()); + l10n_util::GetStringUTF16(ui::GetChromeOSDeviceTypeResourceId()); html_source->AddString( "easyUnlockSetupIntro", l10n_util::GetStringFUTF16(IDS_SETTINGS_EASY_UNLOCK_SETUP_INTRO, @@ -900,38 +900,6 @@ {"networkPrefer", IDS_SETTINGS_INTERNET_NETWORK_PREFER}, {"networkPrimaryUserControlled", IDS_SETTINGS_INTERNET_NETWORK_PRIMARY_USER_CONTROLLED}, - {"networkProxy", IDS_SETTINGS_INTERNET_NETWORK_PROXY_PROXY}, - {"networkProxyAddException", - IDS_SETTINGS_INTERNET_NETWORK_PROXY_ADD_EXCEPTION}, - {"networkProxyAllowShared", - IDS_SETTINGS_INTERNET_NETWORK_PROXY_ALLOW_SHARED}, - {"networkProxyAllowSharedWarningTitle", - IDS_SETTINGS_INTERNET_NETWORK_PROXY_ALLOW_SHARED_WARNING_TITLE}, - {"networkProxyAllowSharedWarningMessage", - IDS_SETTINGS_INTERNET_NETWORK_PROXY_ALLOW_SHARED_WARNING_MESSAGE}, - {"networkProxyAutoConfig", - IDS_SETTINGS_INTERNET_NETWORK_PROXY_AUTO_CONFIG}, - {"networkProxyConnectionType", - IDS_SETTINGS_INTERNET_NETWORK_PROXY_CONNECTION_TYPE}, - {"networkProxyEnforcedPolicy", - IDS_SETTINGS_INTERNET_NETWORK_PROXY_ENFORCED_POLICY}, - {"networkProxyExceptionList", - IDS_SETTINGS_INTERNET_NETWORK_PROXY_EXCEPTION_LIST}, - {"networkProxyFtp", IDS_SETTINGS_INTERNET_NETWORK_PROXY_FTP_PROXY}, - {"networkProxyHttp", IDS_SETTINGS_INTERNET_NETWORK_PROXY_HTTP_PROXY}, - {"networkProxyPort", IDS_SETTINGS_INTERNET_NETWORK_PROXY_PORT}, - {"networkProxyShttp", IDS_SETTINGS_INTERNET_NETWORK_PROXY_SHTTP_PROXY}, - {"networkProxySocks", IDS_SETTINGS_INTERNET_NETWORK_PROXY_SOCKS_HOST}, - {"networkProxyTypeDirect", - IDS_SETTINGS_INTERNET_NETWORK_PROXY_TYPE_DIRECT}, - {"networkProxyTypeManual", - IDS_SETTINGS_INTERNET_NETWORK_PROXY_TYPE_MANUAL}, - {"networkProxyTypePac", IDS_SETTINGS_INTERNET_NETWORK_PROXY_TYPE_PAC}, - {"networkProxyTypeWpad", IDS_SETTINGS_INTERNET_NETWORK_PROXY_TYPE_WPAD}, - {"networkProxyUseSame", IDS_SETTINGS_INTERNET_NETWORK_PROXY_USE_SAME}, - {"networkAccessPoint", IDS_SETTINGS_INTERNET_NETWORK_ACCESS_POINT}, - {"networkNameservers", IDS_SETTINGS_INTERNET_NETWORK_NAMESERVERS}, - {"networkProxyWpad", IDS_SETTINGS_INTERNET_NETWORK_PROXY_WPAD}, {"networkSectionAdvanced", IDS_SETTINGS_INTERNET_NETWORK_SECTION_ADVANCED}, {"networkSectionAdvancedA11yLabel", @@ -2029,109 +1997,6 @@ } #endif -#if defined(OS_CHROMEOS) -void AddOncStrings(content::WebUIDataSource* html_source) { - LocalizedString onc_property_strings[] = { - // Thes strings are generated by prepending 'Onc' to the ONC property - // name. Any '.' in the property name is replaced with '-'. Properties - // with translatable enumerated values have the value appended after '_'. - {"OncCellular-APN-AccessPointName", - IDS_ONC_CELLULAR_APN_ACCESS_POINT_NAME}, - {"OncCellular-APN-AccessPointName_none", - IDS_ONC_CELLULAR_APN_ACCESS_POINT_NAME_NONE}, - {"OncCellular-APN-Password", IDS_ONC_CELLULAR_APN_PASSWORD}, - {"OncCellular-APN-Username", IDS_ONC_CELLULAR_APN_USERNAME}, - {"OncCellular-ActivationState", IDS_ONC_CELLULAR_ACTIVATION_STATE}, - {"OncCellular-ActivationState_Activated", - IDS_ONC_CELLULAR_ACTIVATION_STATE_ACTIVATED}, - {"OncCellular-ActivationState_Activating", - IDS_ONC_CELLULAR_ACTIVATION_STATE_ACTIVATING}, - {"OncCellular-ActivationState_NotActivated", - IDS_ONC_CELLULAR_ACTIVATION_STATE_NOT_ACTIVATED}, - {"OncCellular-ActivationState_PartiallyActivated", - IDS_ONC_CELLULAR_ACTIVATION_STATE_PARTIALLY_ACTIVATED}, - {"OncCellular-Carrier", IDS_ONC_CELLULAR_CARRIER}, - {"OncCellular-Family", IDS_ONC_CELLULAR_FAMILY}, - {"OncCellular-FirmwareRevision", IDS_ONC_CELLULAR_FIRMWARE_REVISION}, - {"OncCellular-HardwareRevision", IDS_ONC_CELLULAR_HARDWARE_REVISION}, - {"OncCellular-HomeProvider-Code", IDS_ONC_CELLULAR_HOME_PROVIDER_CODE}, - {"OncCellular-HomeProvider-Country", - IDS_ONC_CELLULAR_HOME_PROVIDER_COUNTRY}, - {"OncCellular-HomeProvider-Name", IDS_ONC_CELLULAR_HOME_PROVIDER_NAME}, - {"OncCellular-Manufacturer", IDS_ONC_CELLULAR_MANUFACTURER}, - {"OncCellular-ModelID", IDS_ONC_CELLULAR_MODEL_ID}, - {"OncCellular-NetworkTechnology", IDS_ONC_CELLULAR_NETWORK_TECHNOLOGY}, - {"OncCellular-PRLVersion", IDS_ONC_CELLULAR_PRL_VERSION}, - {"OncCellular-RoamingState", IDS_ONC_CELLULAR_ROAMING_STATE}, - {"OncCellular-RoamingState_Home", IDS_ONC_CELLULAR_ROAMING_STATE_HOME}, - {"OncCellular-RoamingState_Roaming", - IDS_ONC_CELLULAR_ROAMING_STATE_ROAMING}, - {"OncCellular-ServingOperator-Code", - IDS_ONC_CELLULAR_SERVING_OPERATOR_CODE}, - {"OncCellular-ServingOperator-Name", - IDS_ONC_CELLULAR_SERVING_OPERATOR_NAME}, - {"OncConnected", IDS_ONC_CONNECTED}, - {"OncConnecting", IDS_ONC_CONNECTING}, - {"OncEAP-AnonymousIdentity", IDS_ONC_EAP_ANONYMOUS_IDENTITY}, - {"OncEAP-Identity", IDS_ONC_EAP_IDENTITY}, - {"OncEAP-Inner", IDS_ONC_EAP_INNER}, - {"OncEAP-Inner_Automatic", IDS_ONC_EAP_INNER_AUTOMATIC}, - {"OncEAP-Inner_CHAP", IDS_ONC_EAP_INNER_CHAP}, - {"OncEAP-Inner_GTC", IDS_ONC_EAP_INNER_GTC}, - {"OncEAP-Inner_MD5", IDS_ONC_EAP_INNER_MD5}, - {"OncEAP-Inner_MSCHAP", IDS_ONC_EAP_INNER_MSCHAP}, - {"OncEAP-Inner_MSCHAPv2", IDS_ONC_EAP_INNER_MSCHAPV2}, - {"OncEAP-Inner_PAP", IDS_ONC_EAP_INNER_PAP}, - {"OncEAP-Outer", IDS_ONC_EAP_OUTER}, - {"OncEAP-Outer_LEAP", IDS_ONC_EAP_OUTER_LEAP}, - {"OncEAP-Outer_PEAP", IDS_ONC_EAP_OUTER_PEAP}, - {"OncEAP-Outer_EAP-TLS", IDS_ONC_EAP_OUTER_TLS}, - {"OncEAP-Outer_EAP-TTLS", IDS_ONC_EAP_OUTER_TTLS}, - {"OncEAP-Password", IDS_ONC_WIFI_PASSWORD}, - {"OncEAP-SubjectMatch", IDS_ONC_EAP_SUBJECT_MATCH}, - {"OncMacAddress", IDS_ONC_MAC_ADDRESS}, - {"OncNotConnected", IDS_ONC_NOT_CONNECTED}, - {"OncRestrictedConnectivity", IDS_ONC_RESTRICTED_CONNECTIVITY}, - {"OncTether-BatteryPercentage", IDS_ONC_TETHER_BATTERY_PERCENTAGE}, - {"OncTether-BatteryPercentage_Value", - IDS_ONC_TETHER_BATTERY_PERCENTAGE_VALUE}, - {"OncTether-SignalStrength", IDS_ONC_TETHER_SIGNAL_STRENGTH}, - {"OncTether-SignalStrength_Weak", IDS_ONC_TETHER_SIGNAL_STRENGTH_WEAK}, - {"OncTether-SignalStrength_Okay", IDS_ONC_TETHER_SIGNAL_STRENGTH_OKAY}, - {"OncTether-SignalStrength_Good", IDS_ONC_TETHER_SIGNAL_STRENGTH_GOOD}, - {"OncTether-SignalStrength_Strong", - IDS_ONC_TETHER_SIGNAL_STRENGTH_STRONG}, - {"OncTether-SignalStrength_VeryStrong", - IDS_ONC_TETHER_SIGNAL_STRENGTH_VERY_STRONG}, - {"OncTether-Carrier", IDS_ONC_TETHER_CARRIER}, - {"OncTether-Carrier_Unknown", IDS_ONC_TETHER_CARRIER_UNKNOWN}, - {"OncVPN-Host", IDS_ONC_VPN_HOST}, - {"OncVPN-L2TP-Username", IDS_ONC_VPN_L2TP_USERNAME}, - {"OncVPN-OpenVPN-Username", IDS_ONC_VPN_OPEN_VPN_USERNAME}, - {"OncVPN-ThirdPartyVPN-ProviderName", - IDS_ONC_VPN_THIRD_PARTY_VPN_PROVIDER_NAME}, - {"OncVPN-Type", IDS_ONC_VPN_TYPE}, - {"OncWiFi-Frequency", IDS_ONC_WIFI_FREQUENCY}, - {"OncWiFi-Passphrase", IDS_ONC_WIFI_PASSWORD}, - {"OncWiFi-SSID", IDS_ONC_WIFI_SSID}, - {"OncWiFi-Security", IDS_ONC_WIFI_SECURITY}, - {"OncWiFi-Security_None", IDS_ONC_WIFI_SECURITY_NONE}, - {"OncWiFi-Security_WEP-PSK", IDS_ONC_WIFI_SECURITY_WEP}, - {"OncWiFi-Security_WPA-EAP", IDS_ONC_WIFI_SECURITY_EAP}, - {"OncWiFi-Security_WPA-PSK", IDS_ONC_WIFI_SECURITY_PSK}, - {"OncWiFi-Security_WEP-8021X", IDS_ONC_WIFI_SECURITY_EAP}, - {"OncWiFi-SignalStrength", IDS_ONC_WIFI_SIGNAL_STRENGTH}, - {"OncWiMAX-EAP-Identity", IDS_ONC_WIMAX_EAP_IDENTITY}, - {"Oncipv4-Gateway", IDS_ONC_IPV4_GATEWAY}, - {"Oncipv4-IPAddress", IDS_ONC_IPV4_ADDRESS}, - {"Oncipv4-RoutingPrefix", IDS_ONC_IPV4_ROUTING_PREFIX}, - {"Oncipv6-IPAddress", IDS_ONC_IPV6_ADDRESS}, - }; - AddLocalizedStringsBulk(html_source, onc_property_strings, - arraysize(onc_property_strings)); -} -#endif // OS_CHROMEOS - } // namespace void AddLocalizedStrings(content::WebUIDataSource* html_source, @@ -2173,7 +2038,6 @@ AddEasyUnlockStrings(html_source); AddInternetStrings(html_source); AddMultideviceStrings(html_source); - AddOncStrings(html_source); AddUsersStrings(html_source); #else AddDefaultBrowserStrings(html_source); @@ -2187,6 +2051,8 @@ #if defined(OS_CHROMEOS) chromeos::network_element::AddLocalizedStrings(html_source); + chromeos::network_element::AddOncLocalizedStrings(html_source); + chromeos::network_element::AddConfigLocalizedStrings(html_source); #endif policy_indicator::AddLocalizedStrings(html_source);
diff --git a/chrome/browser/ui/webui/settings/people_handler.cc b/chrome/browser/ui/webui/settings/people_handler.cc index e6a1b37e..1477fb8c 100644 --- a/chrome/browser/ui/webui/settings/people_handler.cc +++ b/chrome/browser/ui/webui/settings/people_handler.cc
@@ -733,9 +733,6 @@ std::unique_ptr<base::DictionaryValue> PeopleHandler::GetSyncStatusDictionary() { - // The items which are to be written into |sync_status| are also described in - // chrome/browser/resources/options/browser_options.js in @typedef - // for SyncStatus. Please update it whenever you add or remove any keys here. std::unique_ptr<base::DictionaryValue> sync_status(new base::DictionaryValue); if (profile_->IsGuestSession()) { // Cannot display signin status when running in guest mode on chromeos
diff --git a/chrome/browser/ui/webui/settings/protocol_handlers_handler.cc b/chrome/browser/ui/webui/settings/protocol_handlers_handler.cc index 701fdad..102f869 100644 --- a/chrome/browser/ui/webui/settings/protocol_handlers_handler.cc +++ b/chrome/browser/ui/webui/settings/protocol_handlers_handler.cc
@@ -88,9 +88,6 @@ const std::string& protocol, base::DictionaryValue* handlers_value) { ProtocolHandlerRegistry* registry = GetProtocolHandlerRegistry(); - // The items which are to be written into |handlers_value| are also described - // in chrome/browser/resources/options/handler_options.js in @typedef - // for Handlers. Please update them whenever you add or remove any keys here. handlers_value->SetString("protocol", protocol); handlers_value->SetInteger("default_handler", registry->GetHandlerIndex(protocol));
diff --git a/chrome/browser/ui/webui/settings/site_settings_handler.cc b/chrome/browser/ui/webui/settings/site_settings_handler.cc index 338a20e..ac50ebe 100644 --- a/chrome/browser/ui/webui/settings/site_settings_handler.cc +++ b/chrome/browser/ui/webui/settings/site_settings_handler.cc
@@ -163,6 +163,9 @@ base::Bind(&SiteSettingsHandler::HandleSetCategoryPermissionForPattern, base::Unretained(this))); web_ui()->RegisterMessageCallback( + "isOriginValid", base::Bind(&SiteSettingsHandler::HandleIsOriginValid, + base::Unretained(this))); + web_ui()->RegisterMessageCallback( "isPatternValid", base::Bind(&SiteSettingsHandler::HandleIsPatternValid, base::Unretained(this))); @@ -523,6 +526,9 @@ CHECK(args->GetString(2, &value)); const GURL origin(origin_string); + if (!origin.is_valid()) + return; + ContentSetting setting; CHECK(content_settings::ContentSettingFromString(value, &setting)); for (size_t i = 0; i < types->GetSize(); ++i) { @@ -657,6 +663,18 @@ WebSiteSettingsUmaUtil::LogPermissionChange(content_type, setting); } +void SiteSettingsHandler::HandleIsOriginValid(const base::ListValue* args) { + AllowJavascript(); + CHECK_EQ(2U, args->GetSize()); + const base::Value* callback_id; + CHECK(args->Get(0, &callback_id)); + std::string origin_string; + CHECK(args->GetString(1, &origin_string)); + + ResolveJavascriptCallback(*callback_id, + base::Value(GURL(origin_string).is_valid())); +} + void SiteSettingsHandler::HandleIsPatternValid( const base::ListValue* args) { CHECK_EQ(2U, args->GetSize());
diff --git a/chrome/browser/ui/webui/settings/site_settings_handler.h b/chrome/browser/ui/webui/settings/site_settings_handler.h index 21088be..dfeac30 100644 --- a/chrome/browser/ui/webui/settings/site_settings_handler.h +++ b/chrome/browser/ui/webui/settings/site_settings_handler.h
@@ -65,6 +65,7 @@ FRIEND_TEST_ALL_PREFIXES(SiteSettingsHandlerTest, ExtensionDisplayName); FRIEND_TEST_ALL_PREFIXES(SiteSettingsHandlerTest, GetAndSetDefault); FRIEND_TEST_ALL_PREFIXES(SiteSettingsHandlerTest, GetAndSetOriginPermissions); + FRIEND_TEST_ALL_PREFIXES(SiteSettingsHandlerTest, GetAndSetForInvalidURLs); FRIEND_TEST_ALL_PREFIXES(SiteSettingsHandlerTest, Incognito); FRIEND_TEST_ALL_PREFIXES(SiteSettingsHandlerTest, Origins); FRIEND_TEST_ALL_PREFIXES(SiteSettingsHandlerTest, Patterns); @@ -94,7 +95,7 @@ // Gets and sets a list of ContentSettingTypes for an origin. // TODO(https://crbug.com/739241): Investigate replacing the - // '*CategoryPermissionForOrigin' equivalents below with these methods. + // '*CategoryPermissionForPattern' equivalents below with these methods. void HandleGetOriginPermissions(const base::ListValue* args); void HandleSetOriginPermissions(const base::ListValue* args); @@ -102,6 +103,9 @@ void HandleResetCategoryPermissionForPattern(const base::ListValue* args); void HandleSetCategoryPermissionForPattern(const base::ListValue* args); + // Returns whether a given string is a valid origin. + void HandleIsOriginValid(const base::ListValue* args); + // Returns whether a given pattern is valid. void HandleIsPatternValid(const base::ListValue* args);
diff --git a/chrome/browser/ui/webui/settings/site_settings_handler_unittest.cc b/chrome/browser/ui/webui/settings/site_settings_handler_unittest.cc index f3d5ec7..8741dd4 100644 --- a/chrome/browser/ui/webui/settings/site_settings_handler_unittest.cc +++ b/chrome/browser/ui/webui/settings/site_settings_handler_unittest.cc
@@ -472,6 +472,41 @@ site_settings::SiteSettingSource::kDefault, 4U); } +TEST_F(SiteSettingsHandlerTest, GetAndSetForInvalidURLs) { + const std::string origin("arbitrary string"); + EXPECT_FALSE(GURL(origin).is_valid()); + base::ListValue get_args; + get_args.AppendString(kCallbackId); + get_args.AppendString(origin); + { + auto category_list = base::MakeUnique<base::ListValue>(); + category_list->AppendString(kNotifications); + get_args.Append(std::move(category_list)); + } + handler()->HandleGetOriginPermissions(&get_args); + // Verify that it'll just return defaults. Note the display string will be + // blank since it's an invalid url. + ValidateOrigin(origin, origin, "", CONTENT_SETTING_ASK, + site_settings::SiteSettingSource::kDefault, 1U); + + // Make sure setting a permission on an invalid origin doesn't crash. + base::ListValue set_args; + set_args.AppendString(origin); + { + auto category_list = base::MakeUnique<base::ListValue>(); + category_list->AppendString(kNotifications); + set_args.Append(std::move(category_list)); + } + set_args.AppendString( + content_settings::ContentSettingToString(CONTENT_SETTING_BLOCK)); + handler()->HandleSetOriginPermissions(&set_args); + + // Also make sure the content setting for |origin| wasn't actually changed. + handler()->HandleGetOriginPermissions(&get_args); + ValidateOrigin(origin, origin, "", CONTENT_SETTING_ASK, + site_settings::SiteSettingSource::kDefault, 2U); +} + TEST_F(SiteSettingsHandlerTest, ExceptionHelpers) { ContentSettingsPattern pattern = ContentSettingsPattern::FromString("[*.]google.com");
diff --git a/chrome/browser/ui/webui/snippets_internals_message_handler.cc b/chrome/browser/ui/webui/snippets_internals_message_handler.cc index f79159d..2b36dce8 100644 --- a/chrome/browser/ui/webui/snippets_internals_message_handler.cc +++ b/chrome/browser/ui/webui/snippets_internals_message_handler.cc
@@ -33,7 +33,7 @@ #include "components/ntp_snippets/category.h" #include "components/ntp_snippets/category_info.h" #include "components/ntp_snippets/category_rankers/category_ranker.h" -#include "components/ntp_snippets/contextual/contextual_suggestions_source.h" +#include "components/ntp_snippets/contextual/contextual_content_suggestions_service.h" #include "components/ntp_snippets/features.h" #include "components/ntp_snippets/pref_names.h" #include "components/ntp_snippets/remote/remote_suggestions_fetcher.h" @@ -168,10 +168,14 @@ SnippetsInternalsMessageHandler::SnippetsInternalsMessageHandler( ntp_snippets::ContentSuggestionsService* content_suggestions_service, + ntp_snippets::ContextualContentSuggestionsService* + contextual_content_suggestions_service, PrefService* pref_service) : content_suggestions_service_observer_(this), dom_loaded_(false), content_suggestions_service_(content_suggestions_service), + contextual_content_suggestions_service_( + contextual_content_suggestions_service), remote_suggestions_provider_( content_suggestions_service_ ->remote_suggestions_provider_for_debugging()), @@ -380,12 +384,11 @@ DCHECK_EQ(1u, args->GetSize()); std::string url_str; args->GetString(0, &url_str); - content_suggestions_service_->contextual_suggestions_source() - ->FetchContextualSuggestions( - GURL(url_str), - base::BindOnce( - &SnippetsInternalsMessageHandler::OnContextualSuggestionsFetched, - weak_ptr_factory_.GetWeakPtr())); + contextual_content_suggestions_service_->FetchContextualSuggestions( + GURL(url_str), + base::BindOnce( + &SnippetsInternalsMessageHandler::OnContextualSuggestionsFetched, + weak_ptr_factory_.GetWeakPtr())); } void SnippetsInternalsMessageHandler::OnContextualSuggestionsFetched(
diff --git a/chrome/browser/ui/webui/snippets_internals_message_handler.h b/chrome/browser/ui/webui/snippets_internals_message_handler.h index 57808361..75499c65 100644 --- a/chrome/browser/ui/webui/snippets_internals_message_handler.h +++ b/chrome/browser/ui/webui/snippets_internals_message_handler.h
@@ -27,6 +27,7 @@ namespace ntp_snippets { class ContentSuggestionsService; +class ContextualContentSuggestionsService; } // namespace ntp_snippets class PrefService; @@ -38,6 +39,8 @@ public: SnippetsInternalsMessageHandler( ntp_snippets::ContentSuggestionsService* content_suggestions_service, + ntp_snippets::ContextualContentSuggestionsService* + contextual_content_suggestions_service, PrefService* pref_service); ~SnippetsInternalsMessageHandler() override; @@ -93,6 +96,8 @@ bool dom_loaded_; ntp_snippets::ContentSuggestionsService* content_suggestions_service_; + ntp_snippets::ContextualContentSuggestionsService* + contextual_content_suggestions_service_; ntp_snippets::RemoteSuggestionsProvider* remote_suggestions_provider_; PrefService* pref_service_;
diff --git a/chrome/browser/ui/webui/snippets_internals_ui.cc b/chrome/browser/ui/webui/snippets_internals_ui.cc index 26eb311..35e79554 100644 --- a/chrome/browser/ui/webui/snippets_internals_ui.cc +++ b/chrome/browser/ui/webui/snippets_internals_ui.cc
@@ -7,6 +7,7 @@ #include "base/memory/ptr_util.h" #include "build/build_config.h" #include "chrome/browser/ntp_snippets/content_suggestions_service_factory.h" +#include "chrome/browser/ntp_snippets/contextual_content_suggestions_service_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/webui/snippets_internals_message_handler.h" #include "chrome/common/url_constants.h" @@ -48,6 +49,8 @@ web_ui->AddMessageHandler(base::MakeUnique<SnippetsInternalsMessageHandler>( ContentSuggestionsServiceFactory::GetInstance()->GetForProfile(profile), + ContextualContentSuggestionsServiceFactory::GetInstance()->GetForProfile( + profile), profile->GetPrefs())); }
diff --git a/chrome/browser/ui/webui/welcome_win10_handler.cc b/chrome/browser/ui/webui/welcome_win10_handler.cc index eab42d6..bb74e7d 100644 --- a/chrome/browser/ui/webui/welcome_win10_handler.cc +++ b/chrome/browser/ui/webui/welcome_win10_handler.cc
@@ -22,10 +22,13 @@ void RecordDefaultBrowserResult( const std::string& histogram_suffix, shell_integration::DefaultWebClientState default_browser_state) { + // Consider the page successful if this or any other side-by-side install of + // Chrome was chosen as the user's default browser. base::UmaHistogramBoolean( base::StringPrintf("Welcome.Win10.DefaultPromptResult_%s", histogram_suffix.c_str()), - default_browser_state == shell_integration::IS_DEFAULT); + (default_browser_state == shell_integration::IS_DEFAULT || + default_browser_state == shell_integration::OTHER_MODE_IS_DEFAULT)); } void RecordPinnedResult(const std::string& histogram_suffix,
diff --git a/chrome/chrome_paks.gni b/chrome/chrome_paks.gni index 04fc8273..c9a9a3d 100644 --- a/chrome/chrome_paks.gni +++ b/chrome/chrome_paks.gni
@@ -148,12 +148,10 @@ } if (is_chromeos) { sources += [ - "$root_gen_dir/chrome/options_resources.pak", "$root_gen_dir/components/chrome_apps/chrome_apps_resources.pak", "$root_gen_dir/ui/file_manager/file_manager_resources.pak", ] deps += [ - "//chrome/browser/resources:options_resources", "//components/chrome_apps:resources", "//ui/file_manager:resources", ]
diff --git a/chrome/common/extensions/api/_manifest_features.json b/chrome/common/extensions/api/_manifest_features.json index de4250f..6ebe2fa 100644 --- a/chrome/common/extensions/api/_manifest_features.json +++ b/chrome/common/extensions/api/_manifest_features.json
@@ -103,8 +103,8 @@ "channel": "stable", "extension_types": ["legacy_packaged_app", "platform_app"], "whitelist": [ - "nmmhkkegccagdldgiimedpiccmgmieda", - "oedeeodfidgoollimchfdnbmhcpnklnd", // ZIP unpacker. + "64291898C201DAF15B090EC4B9EC270BEB6BE6FF", + "1630F9F78E4527E19E5D9008B99847A8D690F65D", // ZIP unpacker. "07BD6A765FFC289FF755D7CAB2893A40EC337FEC", // http://crbug.com/453955 "896B85CC7E913E11C34892C1425A093C0701D386", // http://crbug.com/453955 "11A01C82EF355E674E4F9728A801F5C3CB40D83F", // http://crbug.com/453955 @@ -122,7 +122,7 @@ "channel": "stable", "extension_types": ["legacy_packaged_app", "platform_app"], "whitelist": [ - "nmmhkkegccagdldgiimedpiccmgmieda", + "64291898C201DAF15B090EC4B9EC270BEB6BE6FF", "07BD6A765FFC289FF755D7CAB2893A40EC337FEC", // http://crbug.com/453955 "896B85CC7E913E11C34892C1425A093C0701D386", // http://crbug.com/453955 "11A01C82EF355E674E4F9728A801F5C3CB40D83F", // http://crbug.com/453955
diff --git a/chrome/common/features.gni b/chrome/common/features.gni index de9a2fc39..d1510ab 100644 --- a/chrome/common/features.gni +++ b/chrome/common/features.gni
@@ -37,10 +37,9 @@ # It is enableable separately to facilitate testing. enable_hangout_services_extension = is_chrome_branded - # 'Ok Google' hotwording is disabled by default. Set to true to enable. (This - # will download a closed-source NaCl module at startup.) Chrome-branded - # ChromeOS builds have this enabled by default. - enable_hotwording = is_chrome_branded && is_chromeos + # 'Ok Google' hotwording is disabled to prepare for its removal. + # http://crbug.com/755579 + enable_hotwording = false # Enables usage of the system-provided notification center. enable_native_notifications =
diff --git a/chrome/common/media_router/discovery/media_sink_internal.cc b/chrome/common/media_router/discovery/media_sink_internal.cc index 66071dd..8439c2e7 100644 --- a/chrome/common/media_router/discovery/media_sink_internal.cc +++ b/chrome/common/media_router/discovery/media_sink_internal.cc
@@ -175,8 +175,8 @@ CastSinkExtraData::~CastSinkExtraData() = default; bool CastSinkExtraData::operator==(const CastSinkExtraData& other) const { - return ip_address == other.ip_address && port == other.port && - model_name == other.model_name && capabilities == other.capabilities && + return ip_endpoint == other.ip_endpoint && model_name == other.model_name && + capabilities == other.capabilities && cast_channel_id == other.cast_channel_id && discovered_by_dial == other.discovered_by_dial; }
diff --git a/chrome/common/media_router/discovery/media_sink_internal.h b/chrome/common/media_router/discovery/media_sink_internal.h index 83fcea8..6705774 100644 --- a/chrome/common/media_router/discovery/media_sink_internal.h +++ b/chrome/common/media_router/discovery/media_sink_internal.h
@@ -10,6 +10,7 @@ #include "base/memory/manual_constructor.h" #include "chrome/common/media_router/media_sink.h" #include "net/base/ip_address.h" +#include "net/base/ip_endpoint.h" #include "url/gurl.h" namespace media_router { @@ -33,7 +34,7 @@ // Extra data for Cast media sink. struct CastSinkExtraData { - net::IPAddress ip_address; + net::IPEndPoint ip_endpoint; int port = 0;
diff --git a/chrome/common/media_router/discovery/media_sink_internal_unittest.cc b/chrome/common/media_router/discovery/media_sink_internal_unittest.cc index 3cdfb6d4..3853153 100644 --- a/chrome/common/media_router/discovery/media_sink_internal_unittest.cc +++ b/chrome/common/media_router/discovery/media_sink_internal_unittest.cc
@@ -30,7 +30,9 @@ uint8_t capabilities, int cast_channel_id) { media_router::CastSinkExtraData cast_extra_data; - EXPECT_TRUE(cast_extra_data.ip_address.AssignFromIPLiteral(ip_address)); + net::IPAddress ip; + EXPECT_TRUE(ip.AssignFromIPLiteral(ip_address)); + cast_extra_data.ip_endpoint = net::IPEndPoint(ip, 1234); cast_extra_data.model_name = model_name; cast_extra_data.capabilities = 2; cast_extra_data.cast_channel_id = 3;
diff --git a/chrome/common/media_router/mojo/media_router.mojom b/chrome/common/media_router/mojo/media_router.mojom index 63b111b4..1bcb0e6 100644 --- a/chrome/common/media_router/mojo/media_router.mojom +++ b/chrome/common/media_router/mojo/media_router.mojom
@@ -9,6 +9,7 @@ import "media/mojo/interfaces/mirror_service_remoting.mojom"; import "mojo/common/time.mojom"; import "net/interfaces/ip_address.mojom"; +import "net/interfaces/ip_endpoint.mojom"; import "url/mojo/origin.mojom"; import "url/mojo/url.mojom"; @@ -54,7 +55,7 @@ }; struct CastMediaSink { - net.interfaces.IPAddress ip_address; + net.interfaces.IPEndPoint ip_endpoint; // Model name of the sink, if it represents a physical device. string model_name;
diff --git a/chrome/common/media_router/mojo/media_router_struct_traits.cc b/chrome/common/media_router/mojo/media_router_struct_traits.cc index 2e5da449..3a284fe 100644 --- a/chrome/common/media_router/mojo/media_router_struct_traits.cc +++ b/chrome/common/media_router/mojo/media_router_struct_traits.cc
@@ -6,6 +6,7 @@ #include "chrome/common/media_router/media_source.h" #include "net/interfaces/ip_address_struct_traits.h" +#include "net/interfaces/ip_endpoint_struct_traits.h" #include "url/mojo/url_gurl_struct_traits.h" namespace mojo { @@ -154,7 +155,7 @@ media_router::CastSinkExtraData>:: Read(media_router::mojom::CastMediaSinkDataView data, media_router::CastSinkExtraData* out) { - if (!data.ReadIpAddress(&out->ip_address)) + if (!data.ReadIpEndpoint(&out->ip_endpoint)) return false; if (!data.ReadModelName(&out->model_name))
diff --git a/chrome/common/media_router/mojo/media_router_struct_traits.h b/chrome/common/media_router/mojo/media_router_struct_traits.h index 70fc2eb..93f2e67 100644 --- a/chrome/common/media_router/mojo/media_router_struct_traits.h +++ b/chrome/common/media_router/mojo/media_router_struct_traits.h
@@ -12,6 +12,7 @@ #include "chrome/common/media_router/mojo/media_router.mojom.h" #include "chrome/common/media_router/route_request_result.h" #include "mojo/common/common_custom_types_struct_traits.h" +#include "net/base/ip_endpoint.h" namespace mojo { @@ -136,9 +137,9 @@ return extra_data.model_name; } - static const net::IPAddress& ip_address( + static const net::IPEndPoint& ip_endpoint( const media_router::CastSinkExtraData& extra_data) { - return extra_data.ip_address; + return extra_data.ip_endpoint; } static uint8_t capabilities(
diff --git a/chrome/common/media_router/mojo/media_router_struct_traits_unittest.cc b/chrome/common/media_router/mojo/media_router_struct_traits_unittest.cc index c6087ea9..c985ae6 100644 --- a/chrome/common/media_router/mojo/media_router_struct_traits_unittest.cc +++ b/chrome/common/media_router/mojo/media_router_struct_traits_unittest.cc
@@ -68,12 +68,11 @@ MediaSink::Id sink_id("sinkId123"); std::string sink_name("The sink"); SinkIconType icon_type(SinkIconType::CAST); - std::string ip_address("192.168.1.2"); std::string model_name("model name"); MediaSink sink(sink_id, sink_name, icon_type); CastSinkExtraData extra_data; - EXPECT_TRUE(extra_data.ip_address.AssignFromIPLiteral(ip_address)); + extra_data.ip_endpoint = net::IPEndPoint(net::IPAddress(192, 168, 1, 2), 0); extra_data.model_name = model_name; extra_data.capabilities = 2; extra_data.cast_channel_id = 3;
diff --git a/chrome/install_static/google_chrome_install_modes.cc b/chrome/install_static/google_chrome_install_modes.cc index 53ffdd17..793f5e90 100644 --- a/chrome/install_static/google_chrome_install_modes.cc +++ b/chrome/install_static/google_chrome_install_modes.cc
@@ -64,7 +64,7 @@ L"beta", // Forced channel name. ChannelStrategy::FIXED, true, // Supports system-level installs. - false, // Does not support in-product set as default browser UX. + true, // Supports in-product set as default browser UX. true, // Supports retention experiments. false, // Did not support multi-install. icon_resources::kBetaApplicationIndex, // App icon resource index. @@ -87,7 +87,7 @@ L"dev", // Forced channel name. ChannelStrategy::FIXED, true, // Supports system-level installs. - false, // Does not support in-product set as default browser UX. + true, // Supports in-product set as default browser UX. true, // Supports retention experiments. false, // Did not support multi-install. icon_resources::kDevApplicationIndex, // App icon resource index.
diff --git a/chrome/installer/util/beacons.cc b/chrome/installer/util/beacons.cc index b8cd911..ac759ed 100644 --- a/chrome/installer/util/beacons.cc +++ b/chrome/installer/util/beacons.cc
@@ -21,15 +21,16 @@ void UpdateDefaultBrowserBeaconWithState( ShellUtil::DefaultState default_state) { switch (default_state) { + case ShellUtil::UNKNOWN_DEFAULT: + break; case ShellUtil::NOT_DEFAULT: installer_util::MakeFirstNotDefaultBeacon()->Update(); break; case ShellUtil::IS_DEFAULT: + case ShellUtil::OTHER_MODE_IS_DEFAULT: installer_util::MakeLastWasDefaultBeacon()->Update(); installer_util::MakeFirstNotDefaultBeacon()->Remove(); break; - case ShellUtil::UNKNOWN_DEFAULT: - break; } }
diff --git a/chrome/installer/util/shell_util.cc b/chrome/installer/util/shell_util.cc index bf8e226b..73c5ce4 100644 --- a/chrome/installer/util/shell_util.cc +++ b/chrome/installer/util/shell_util.cc
@@ -51,9 +51,13 @@ #include "base/win/windows_version.h" #include "chrome/common/chrome_constants.h" #include "chrome/common/chrome_switches.h" +#include "chrome/install_static/install_constants.h" +#include "chrome/install_static/install_details.h" +#include "chrome/install_static/install_modes.h" #include "chrome/install_static/install_util.h" #include "chrome/installer/util/beacons.h" #include "chrome/installer/util/browser_distribution.h" +#include "chrome/installer/util/helper.h" #include "chrome/installer/util/install_util.h" #include "chrome/installer/util/installer_util_strings.h" #include "chrome/installer/util/l10n_string_util.h" @@ -804,8 +808,7 @@ return true; } -// Returns true if the current install's |chrome_exe| has been registered with -// |suffix|. +// Returns true if |chrome_exe| has been registered with |suffix| for |mode|. // |confirmation_level| is the level of verification desired as described in // the RegistrationConfirmationLevel enum above. // |suffix| can be the empty string (this is used to support old installs @@ -815,9 +818,11 @@ // points to |chrome_exe|. This should only be used at run-time to determine // how Chrome is registered, not to know whether the registration is complete // at install-time (IsChromeRegistered() can be used for that). -bool QuickIsChromeRegistered(const base::FilePath& chrome_exe, - const base::string16& suffix, - RegistrationConfirmationLevel confirmation_level) { +bool QuickIsChromeRegisteredForMode( + const base::FilePath& chrome_exe, + const base::string16& suffix, + const install_static::InstallConstants& mode, + RegistrationConfirmationLevel confirmation_level) { // Get the appropriate key to look for based on the level desired. base::string16 reg_key; switch (confirmation_level) { @@ -825,7 +830,7 @@ // Software\Classes\ChromeHTML|suffix| reg_key = ShellUtil::kRegClasses; reg_key.push_back(base::FilePath::kSeparators[0]); - reg_key.append(install_static::GetProgIdPrefix()); + reg_key.append(mode.prog_id_prefix); reg_key.append(suffix); break; case CONFIRM_SHELL_REGISTRATION: @@ -861,6 +866,69 @@ return false; } +// Returns the installation suffix for |mode| at the current install level +// (system or user). +base::string16 GetInstallationSuffixForMode( + const install_static::InstallConstants& mode) { + // Search based on the default install location for the mode. If we ever + // support customizing the install location (https://crbug.com/113987, + // https://crbug.com/302491) this will have to change to something else, such + // as probing the Omaha keys in the registry to see where the mode is + // installed. + const bool system_install = !InstallUtil::IsPerUserInstall(); + const base::FilePath chrome_exe = + installer::GetChromeInstallPath(system_install) + .Append(installer::kChromeExe); + + // See the comment in ShellUtil::GetCurrentInstallationSuffix for details on + // what's going on here. + base::string16 tested_suffix; + if (!system_install && + (!ShellUtil::GetUserSpecificRegistrySuffix(&tested_suffix) || + !QuickIsChromeRegisteredForMode(chrome_exe, tested_suffix, mode, + CONFIRM_PROGID_REGISTRATION)) && + (!ShellUtil::GetOldUserSpecificRegistrySuffix(&tested_suffix) || + !QuickIsChromeRegisteredForMode(chrome_exe, tested_suffix, mode, + CONFIRM_PROGID_REGISTRATION)) && + !QuickIsChromeRegisteredForMode(chrome_exe, tested_suffix.erase(), mode, + CONFIRM_PROGID_REGISTRATION)) { + // If Chrome is not registered under any of the possible suffixes (e.g. + // tests, Canary, etc.): use the new-style suffix at run-time. + if (!ShellUtil::GetUserSpecificRegistrySuffix(&tested_suffix)) + NOTREACHED(); + } + return tested_suffix; +} + +// Returns |mode|'s application name. This application name will be suffixed as +// is appropriate for the install. This is the name that is registered with +// Default Programs on Windows and that should thus be used to "make chrome +// default" and such. +base::string16 GetApplicationNameForMode( + const install_static::InstallConstants& mode) { + return base::string16(mode.base_app_name) + .append(GetInstallationSuffixForMode(mode)); +} + +// Returns true if the current install's |chrome_exe| has been registered with +// |suffix|. +// |confirmation_level| is the level of verification desired as described in +// the RegistrationConfirmationLevel enum above. +// |suffix| can be the empty string (this is used to support old installs +// where we used to not suffix user-level installs if they were the first to +// request the non-suffixed registry entries on the machine). +// NOTE: This a quick check that only validates that a single registry entry +// points to |chrome_exe|. This should only be used at run-time to determine +// how Chrome is registered, not to know whether the registration is complete +// at install-time (IsChromeRegistered() can be used for that). +bool QuickIsChromeRegistered(const base::FilePath& chrome_exe, + const base::string16& suffix, + RegistrationConfirmationLevel confirmation_level) { + return QuickIsChromeRegisteredForMode( + chrome_exe, suffix, install_static::InstallDetails::Get().mode(), + confirmation_level); +} + // Sets |suffix| to a 27 character string that is specific to this user on this // machine (on user-level installs only). // To support old-style user-level installs however, |suffix| is cleared if the @@ -1057,18 +1125,50 @@ if (FAILED(hr)) return ShellUtil::UNKNOWN_DEFAULT; + // Get the ProgID for the current install mode. base::string16 prog_id(install_static::GetProgIdPrefix()); prog_id += ShellUtil::GetCurrentInstallationSuffix(chrome_exe); + const int current_install_mode_index = + install_static::InstallDetails::Get().install_mode_index(); + bool other_mode_is_default = false; for (size_t i = 0; i < num_protocols; ++i) { base::win::ScopedCoMem<wchar_t> current_app; hr = registration->QueryCurrentDefault(protocols[i], AT_URLPROTOCOL, AL_EFFECTIVE, ¤t_app); - if (FAILED(hr) || prog_id.compare(current_app) != 0) + if (FAILED(hr)) return ShellUtil::NOT_DEFAULT; - } + if (prog_id.compare(current_app) == 0) + continue; - return ShellUtil::IS_DEFAULT; + // See if another mode is the default handler for this protocol. + size_t current_app_len = std::char_traits<wchar_t>::length(current_app); + const auto* it = std::find_if( + &install_static::kInstallModes[0], + &install_static::kInstallModes[install_static::NUM_INSTALL_MODES], + [current_install_mode_index, ¤t_app, + current_app_len](const install_static::InstallConstants& mode) { + if (mode.index == current_install_mode_index) + return false; + const base::string16 mode_prog_id_prefix(mode.prog_id_prefix); + // Does the current app either match this mode's ProgID or contain + // this mode's ProgID as a prefix followed by the '.' separator for a + // per-user install's suffix? + return mode_prog_id_prefix.compare(current_app) == 0 || + (InstallUtil::IsPerUserInstall() && + current_app_len > mode_prog_id_prefix.length() && + current_app[mode_prog_id_prefix.length()] == L'.' && + std::char_traits<wchar_t>::compare( + mode_prog_id_prefix.c_str(), current_app, + mode_prog_id_prefix.length()) == 0); + }); + if (it == &install_static::kInstallModes[install_static::NUM_INSTALL_MODES]) + return ShellUtil::NOT_DEFAULT; + other_mode_is_default = true; + } + // This mode is default if it has all of the protocols. + return other_mode_is_default ? ShellUtil::OTHER_MODE_IS_DEFAULT + : ShellUtil::IS_DEFAULT; } // Probe using IApplicationAssociationRegistration::QueryAppIsDefault (Vista and @@ -1086,16 +1186,51 @@ base::string16 app_name(GetApplicationName(chrome_exe)); - BOOL result; - for (size_t i = 0; i < num_protocols; ++i) { - result = TRUE; - hr = registration->QueryAppIsDefault(protocols[i], AT_URLPROTOCOL, - AL_EFFECTIVE, app_name.c_str(), &result); - if (FAILED(hr) || result == FALSE) - return ShellUtil::NOT_DEFAULT; + // Generate the app names for this brand's other install modes. + const int current_install_mode_index = + install_static::InstallDetails::Get().install_mode_index(); + base::string16 other_app_names[install_static::NUM_INSTALL_MODES]; + for (int mode_index = 0; mode_index < install_static::NUM_INSTALL_MODES; + ++mode_index) { + if (mode_index == current_install_mode_index) + continue; // Leave the entry for the current mode empty. + other_app_names[mode_index] = + GetApplicationNameForMode(install_static::kInstallModes[mode_index]); } - return ShellUtil::IS_DEFAULT; + // Now check each protocol to see if this brand is default for all. This loop + // terminates when this brand is the default handler for the protocols. + bool other_mode_is_default = false; + for (size_t i = 0; i < num_protocols; ++i) { + const wchar_t* protocol = protocols[i]; + BOOL result = TRUE; + // Check the current app name. + hr = registration->QueryAppIsDefault(protocol, AT_URLPROTOCOL, AL_EFFECTIVE, + app_name.c_str(), &result); + if (FAILED(hr)) + return ShellUtil::NOT_DEFAULT; + if (result) + continue; + + // Search for a different install mode that is the default handler. + const auto* it = + std::find_if(std::cbegin(other_app_names), std::cend(other_app_names), + [®istration, protocol](const base::string16& app_name) { + if (app_name.empty()) + return false; + BOOL result = TRUE; + HRESULT hr = registration->QueryAppIsDefault( + protocol, AT_URLPROTOCOL, AL_EFFECTIVE, + app_name.c_str(), &result); + return SUCCEEDED(hr) && result; + }); + if (it == std::end(other_app_names)) + return ShellUtil::NOT_DEFAULT; + other_mode_is_default = true; + } + + return other_mode_is_default ? ShellUtil::OTHER_MODE_IS_DEFAULT + : ShellUtil::IS_DEFAULT; } // A helper function that probes default protocol handler registration (in a
diff --git a/chrome/installer/util/shell_util.h b/chrome/installer/util/shell_util.h index 7fe4a6e..2038f72 100644 --- a/chrome/installer/util/shell_util.h +++ b/chrome/installer/util/shell_util.h
@@ -44,11 +44,22 @@ SYSTEM_LEVEL = 0x2 // Make any shell changes only at the system level }; - // Chrome's default handler state for a given protocol. + // Chrome's default handler state for a given protocol. If the current install + // mode is not default, the brand's other modes are checked. This allows + // callers to take specific action in case the current mode (e.g., Chrome Dev) + // is not the default handler, but another of the brand's modes (e.g., stable + // Chrome) is. enum DefaultState { + // An error occurred while attempting to check the default handler for the + // protocol. UNKNOWN_DEFAULT, + // No install mode for the brand is default for the protocol. NOT_DEFAULT, + // The current install mode is default. IS_DEFAULT, + // The current install mode is not default, although one of the brand's + // other install modes is. + OTHER_MODE_IS_DEFAULT, }; // Typical shortcut directories. Resolved in GetShortcutPath().
diff --git a/chrome/installer/zucchini/BUILD.gn b/chrome/installer/zucchini/BUILD.gn index a6a4f5f..6b9701d 100644 --- a/chrome/installer/zucchini/BUILD.gn +++ b/chrome/installer/zucchini/BUILD.gn
@@ -47,6 +47,7 @@ "typed_value.h", "zucchini.h", "zucchini_apply.cc", + "zucchini_apply.h", "zucchini_gen.cc", "zucchini_gen.h", ] @@ -114,6 +115,7 @@ "test_reference_reader.cc", "test_reference_reader.h", "typed_value_unittest.cc", + "zucchini_apply_unittest.cc", "zucchini_gen_unittest.cc", ]
diff --git a/chrome/installer/zucchini/buffer_view.h b/chrome/installer/zucchini/buffer_view.h index 7c41ba6..ecc6f96 100644 --- a/chrome/installer/zucchini/buffer_view.h +++ b/chrome/installer/zucchini/buffer_view.h
@@ -67,9 +67,6 @@ // Element access - // Returns a BufferRegion describing the full view. - BufferRegion region() const { return BufferRegion{0, size()}; } - // Returns the raw value at specified location |pos|. // If |pos| is not within the range of the buffer, the process is terminated. reference operator[](size_type pos) const { @@ -101,6 +98,14 @@ bool empty() const { return first_ == last_; } size_type size() const { return last_ - first_; } + // Returns a BufferRegion describing the full view. + BufferRegion region() const { return BufferRegion{0, size()}; } + + // Returns true iff the object is large enough to entirely cover |region|. + bool covers(const BufferRegion& region) const { + return region.offset < size() && size() - region.offset >= region.size; + } + // Modifiers void shrink(size_type new_size) {
diff --git a/chrome/installer/zucchini/buffer_view_unittest.cc b/chrome/installer/zucchini/buffer_view_unittest.cc index 5b0e157d..5bb661d 100644 --- a/chrome/installer/zucchini/buffer_view_unittest.cc +++ b/chrome/installer/zucchini/buffer_view_unittest.cc
@@ -52,14 +52,6 @@ ConstBufferView::FromRange(std::begin(bytes_) + 1, std::begin(bytes_))); } -TEST_F(BufferViewTest, Region) { - ConstBufferView view(std::begin(bytes_), kLen); - - BufferRegion region = view.region(); - EXPECT_EQ(0U, region.offset); - EXPECT_EQ(kLen, region.size); -} - TEST_F(BufferViewTest, Subscript) { ConstBufferView view(std::begin(bytes_), kLen); @@ -132,4 +124,35 @@ EXPECT_DEATH(buffer.write<uint32_t>(7, 0xFFFFFFFF), ""); } +TEST_F(BufferViewTest, Region) { + ConstBufferView view(std::begin(bytes_), kLen); + + BufferRegion region = view.region(); + EXPECT_EQ(0U, region.offset); + EXPECT_EQ(kLen, region.size); +} + +TEST_F(BufferViewTest, Covers) { + EXPECT_FALSE(ConstBufferView().covers({0, 0})); + EXPECT_FALSE(ConstBufferView().covers({0, 1})); + + ConstBufferView view(std::begin(bytes_), kLen); + + EXPECT_TRUE(view.covers({0, 0})); + EXPECT_TRUE(view.covers({0, 1})); + EXPECT_TRUE(view.covers({0, kLen})); + EXPECT_FALSE(view.covers({0, kLen + 1})); + EXPECT_FALSE(view.covers({1, kLen})); + + EXPECT_TRUE(view.covers({kLen - 1, 0})); + EXPECT_TRUE(view.covers({kLen - 1, 1})); + EXPECT_FALSE(view.covers({kLen - 1, 2})); + EXPECT_FALSE(view.covers({kLen, 0})); + EXPECT_FALSE(view.covers({kLen, 1})); + + EXPECT_FALSE(view.covers({1, size_t(-1)})); + EXPECT_FALSE(view.covers({size_t(-1), 1})); + EXPECT_FALSE(view.covers({size_t(-1), size_t(-1)})); +} + } // namespace zucchini
diff --git a/chrome/installer/zucchini/disassembler.h b/chrome/installer/zucchini/disassembler.h index c9f1e739..8d80f5ac 100644 --- a/chrome/installer/zucchini/disassembler.h +++ b/chrome/installer/zucchini/disassembler.h
@@ -95,7 +95,7 @@ // Creates and returns a vector that contains all groups of references. // Groups must be aggregated by pool. - virtual std::vector<ReferenceGroup> GetReferenceGroups() const = 0; + virtual std::vector<ReferenceGroup> MakeReferenceGroups() const = 0; ConstBufferView GetImage() const { return image_; } size_t size() const { return image_.size(); }
diff --git a/chrome/installer/zucchini/disassembler_no_op.cc b/chrome/installer/zucchini/disassembler_no_op.cc index f6178da3..d7c38ef3 100644 --- a/chrome/installer/zucchini/disassembler_no_op.cc +++ b/chrome/installer/zucchini/disassembler_no_op.cc
@@ -25,7 +25,7 @@ return "(Unknown)"; } -std::vector<ReferenceGroup> DisassemblerNoOp::GetReferenceGroups() const { +std::vector<ReferenceGroup> DisassemblerNoOp::MakeReferenceGroups() const { return std::vector<ReferenceGroup>(); }
diff --git a/chrome/installer/zucchini/disassembler_no_op.h b/chrome/installer/zucchini/disassembler_no_op.h index 13ff32b..38330b92 100644 --- a/chrome/installer/zucchini/disassembler_no_op.h +++ b/chrome/installer/zucchini/disassembler_no_op.h
@@ -26,7 +26,7 @@ // Disassembler: ExecutableType GetExeType() const override; std::string GetExeTypeString() const override; - std::vector<ReferenceGroup> GetReferenceGroups() const override; + std::vector<ReferenceGroup> MakeReferenceGroups() const override; protected: DisassemblerNoOp();
diff --git a/chrome/installer/zucchini/patch_reader.cc b/chrome/installer/zucchini/patch_reader.cc index 402076d..ee43b187 100644 --- a/chrome/installer/zucchini/patch_reader.cc +++ b/chrome/installer/zucchini/patch_reader.cc
@@ -117,7 +117,6 @@ } base::Optional<ConstBufferView> ExtraDataSource::GetNext(offset_t size) { - DCHECK_GT(size, offset_t(0)); ConstBufferView buffer; if (!extra_data_.GetRegion(size, &buffer)) return base::nullopt;
diff --git a/chrome/installer/zucchini/zucchini_apply.cc b/chrome/installer/zucchini/zucchini_apply.cc index 95f8af8..59477be 100644 --- a/chrome/installer/zucchini/zucchini_apply.cc +++ b/chrome/installer/zucchini/zucchini_apply.cc
@@ -2,26 +2,257 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/installer/zucchini/zucchini.h" +#include "chrome/installer/zucchini/zucchini_apply.h" + +#include <algorithm> +#include <map> +#include <memory> +#include <utility> + +#include "base/logging.h" +#include "chrome/installer/zucchini/disassembler.h" +#include "chrome/installer/zucchini/element_detection.h" +#include "chrome/installer/zucchini/label_manager.h" namespace zucchini { +std::vector<offset_t> MakeNewTargetsFromPatch( + const std::vector<offset_t>& old_targets, + const EquivalenceSource& equivalence_source) { + // |old_targets| is sorted. This enables binary search usage below. + std::vector<offset_t> new_targets(old_targets.size(), kUnusedIndex); + + // First pass: For each equivalence, attempt to claim target in |new_targets| + // associated with each target in the "old" interval of the equivalence. "Old" + // interval collisions may occur. + { + EquivalenceSource tmp_equiv_source(equivalence_source); + for (auto equivalence = tmp_equiv_source.GetNext(); equivalence.has_value(); + equivalence = tmp_equiv_source.GetNext()) { + auto it = std::lower_bound(old_targets.begin(), old_targets.end(), + equivalence->src_offset); + offset_t idx = it - old_targets.begin(); + for (; it != old_targets.end() && *it < equivalence->src_end(); + ++it, ++idx) { + // To resolve collisions, |new_targets[idx]| is temporarily assigned the + // marked maximal length of competing equivalences that contain + // |new_tagets[idx]|. As a result, longer equivalences are favored. + if (new_targets[idx] == kUnusedIndex || + UnmarkIndex(new_targets[idx]) < equivalence->length) { + new_targets[idx] = MarkIndex(equivalence->length); + } + } + } + } + + // Second pass: Assign each claimed target in |new_targets|. + { + EquivalenceSource tmp_equiv_source(equivalence_source); + for (auto equivalence = tmp_equiv_source.GetNext(); equivalence.has_value(); + equivalence = tmp_equiv_source.GetNext()) { + auto it = std::lower_bound(old_targets.begin(), old_targets.end(), + equivalence->src_offset); + offset_t idx = it - old_targets.begin(); + for (; it != old_targets.end() && *it < equivalence->src_end(); + ++it, ++idx) { + // First |equivalence| (ordered by |Equivalence::dst_offset|) with + // designed length claims the target. This is how ties are resolved. + if (IsMarked(new_targets[idx]) && + UnmarkIndex(new_targets[idx]) == equivalence->length) { + new_targets[idx] = + *it - equivalence->src_offset + equivalence->dst_offset; + } + } + } + } + return new_targets; +} + +bool ApplyEquivalenceAndExtraData(ConstBufferView old_image, + const PatchElementReader& patch_reader, + MutableBufferView new_image) { + EquivalenceSource equiv_source = patch_reader.GetEquivalenceSource(); + ExtraDataSource extra_data_source = patch_reader.GetExtraDataSource(); + MutableBufferView::iterator dst_it = new_image.begin(); + + for (auto equivalence = equiv_source.GetNext(); equivalence.has_value(); + equivalence = equiv_source.GetNext()) { + // TODO(etiennep): Guard against out of range errors and return false + // instead. + MutableBufferView::iterator next_dst_it = + new_image.begin() + equivalence->dst_offset; + CHECK(next_dst_it >= dst_it); + offset_t gap = static_cast<offset_t>(next_dst_it - dst_it); + base::Optional<ConstBufferView> extra_data = extra_data_source.GetNext(gap); + if (!extra_data) { + LOG(ERROR) << "Error reading extra_data"; + return false; + } + dst_it = std::copy(extra_data->begin(), extra_data->end(), dst_it); + CHECK_EQ(dst_it, next_dst_it); + dst_it = std::copy_n(old_image.begin() + equivalence->src_offset, + equivalence->length, dst_it); + CHECK_EQ(dst_it, next_dst_it + equivalence->length); + } + offset_t gap = static_cast<offset_t>(new_image.end() - dst_it); + base::Optional<ConstBufferView> extra_data = extra_data_source.GetNext(gap); + if (!extra_data) { + LOG(ERROR) << "Error reading extra_data"; + return false; + } + std::copy(extra_data->begin(), extra_data->end(), dst_it); + if (!equiv_source.Done() || !extra_data_source.Done()) { + LOG(ERROR) << "Found trailing equivalence and extra_data"; + return false; + } + return true; +} + +bool ApplyRawDelta(const PatchElementReader& patch_reader, + MutableBufferView new_image) { + EquivalenceSource equiv_source = patch_reader.GetEquivalenceSource(); + RawDeltaSource raw_delta_source = patch_reader.GetRawDeltaSource(); + // Traverse |equiv_source| and |raw_delta_source| in lockstep. + auto equivalence = equiv_source.GetNext(); + offset_t base_copy_offset = 0; + for (auto delta = raw_delta_source.GetNext(); delta.has_value(); + delta = raw_delta_source.GetNext()) { + while (equivalence.has_value() && + base_copy_offset + equivalence->length <= delta->copy_offset) { + base_copy_offset += equivalence->length; + equivalence = equiv_source.GetNext(); + } + if (!equivalence.has_value()) { + LOG(ERROR) << "Error reading equivalences"; + return false; + } + CHECK_GE(delta->copy_offset, base_copy_offset); + CHECK_LT(delta->copy_offset, base_copy_offset + equivalence->length); + + // Invert byte diff. + new_image[equivalence->dst_offset - base_copy_offset + + delta->copy_offset] += delta->diff; + } + if (!raw_delta_source.Done()) { + LOG(ERROR) << "Found trailing raw_delta"; + return false; + } + return true; +} + +bool ApplyReferencesCorrection(ExecutableType exe_type, + ConstBufferView old_image, + const PatchElementReader& patch, + MutableBufferView new_image) { + auto old_disasm = MakeDisassemblerOfType(old_image, exe_type); + auto new_disasm = + MakeDisassemblerOfType(ConstBufferView(new_image), exe_type); + if (!old_disasm || !new_disasm) { + LOG(ERROR) << "Failed to create Disassembler"; + return false; + } + + ReferenceDeltaSource ref_delta_source = patch.GetReferenceDeltaSource(); + std::map<PoolTag, std::vector<ReferenceGroup>> pool_groups; + for (const auto& ref_group : old_disasm->MakeReferenceGroups()) + pool_groups[ref_group.pool_tag()].push_back(ref_group); + + std::vector<ReferenceGroup> new_groups = new_disasm->MakeReferenceGroups(); + for (const auto& pool_and_sub_groups : pool_groups) { + PoolTag pool_tag = pool_and_sub_groups.first; + const std::vector<ReferenceGroup>& sub_groups = pool_and_sub_groups.second; + + // Load all old targets for the pool. + OrderedLabelManager old_label_manager; + for (ReferenceGroup group : sub_groups) + old_label_manager.InsertTargets( + std::move(*group.GetReader(old_disasm.get()))); + + // Generate estimated new targets for the pool. + std::vector<offset_t> new_targets = MakeNewTargetsFromPatch( + old_label_manager.Labels(), patch.GetEquivalenceSource()); + UnorderedLabelManager new_label_manager; + new_label_manager.Init(std::move(new_targets)); + + // Load extra targets from patch. + TargetSource target_source = patch.GetExtraTargetSource(pool_tag); + for (auto offset = target_source.GetNext(); offset.has_value(); + offset = target_source.GetNext()) + new_label_manager.InsertNewOffset(offset.value()); + if (!target_source.Done()) { + LOG(ERROR) << "Found trailing extra_targets"; + return false; + } + + // Correct all new references, and write results to |new_disasm|. + for (ReferenceGroup group : sub_groups) { + std::unique_ptr<ReferenceWriter> ref_writer = + new_groups[group.type_tag().value()].GetWriter(new_image, + new_disasm.get()); + + EquivalenceSource equiv_source = patch.GetEquivalenceSource(); + for (auto equivalence = equiv_source.GetNext(); equivalence.has_value(); + equivalence = equiv_source.GetNext()) { + std::unique_ptr<ReferenceReader> ref_gen = group.GetReader( + equivalence->src_offset, equivalence->src_end(), old_disasm.get()); + for (auto ref = ref_gen->GetNext(); ref.has_value(); + ref = ref_gen->GetNext()) { + DCHECK_GE(ref->location, equivalence->src_offset); + DCHECK_LT(ref->location, equivalence->src_end()); + offset_t index = old_label_manager.IndexOfOffset(ref->target); + auto delta = ref_delta_source.GetNext(); + if (!delta.has_value()) { + LOG(ERROR) << "Error reading reference_delta"; + return false; + } + ref->target = new_label_manager.OffsetOfIndex(index + delta.value()); + ref->location = + ref->location - equivalence->src_offset + equivalence->dst_offset; + ref_writer->PutNext(*ref); + } + } + } + } + if (!ref_delta_source.Done()) { + LOG(ERROR) << "Found trailing ref_delta_source"; + return false; + } + return true; +} + +bool ApplyElement(ExecutableType exe_type, + ConstBufferView old_image, + const PatchElementReader& patch_reader, + MutableBufferView new_image) { + return ApplyEquivalenceAndExtraData(old_image, patch_reader, new_image) && + ApplyRawDelta(patch_reader, new_image) && + ApplyReferencesCorrection(exe_type, old_image, patch_reader, + new_image); +} + +/******** Exported Functions ********/ + status::Code Apply(ConstBufferView old_image, const EnsemblePatchReader& patch_reader, MutableBufferView new_image) { if (!patch_reader.CheckOldFile(old_image)) { LOG(ERROR) << "Invalid old_image."; - return zucchini::status::kStatusInvalidOldImage; + return status::kStatusInvalidOldImage; } - // TODO(etiennep): Implement. + for (const auto& element_patch : patch_reader.elements()) { + ElementMatch match = element_patch.element_match(); + if (!ApplyElement(match.old_element.exe_type, + old_image[match.old_element.region()], element_patch, + new_image[match.new_element.region()])) + return status::kStatusFatal; + } - // This will always fail for now, because of missing implementation. if (!patch_reader.CheckNewFile(ConstBufferView(new_image))) { LOG(ERROR) << "Invalid new_image."; - return zucchini::status::kStatusInvalidNewImage; + return status::kStatusInvalidNewImage; } - return zucchini::status::kStatusSuccess; + return status::kStatusSuccess; } } // namespace zucchini
diff --git a/chrome/installer/zucchini/zucchini_apply.h b/chrome/installer/zucchini/zucchini_apply.h new file mode 100644 index 0000000..52a82df --- /dev/null +++ b/chrome/installer/zucchini/zucchini_apply.h
@@ -0,0 +1,51 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_INSTALLER_ZUCCHINI_ZUCCHINI_APPLY_H_ +#define CHROME_INSTALLER_ZUCCHINI_ZUCCHINI_APPLY_H_ + +#include <vector> + +#include "chrome/installer/zucchini/image_utils.h" +#include "chrome/installer/zucchini/patch_reader.h" +#include "chrome/installer/zucchini/zucchini.h" + +namespace zucchini { + +// Projects targets in |old_targets| to a list of new targets using equivalences +// in |equivalence_source|. Targets that cannot be projected have offset +// assigned as |kUnusedIndex|. Returns the list of new targets in a new vector. +// |old_targets| must be sorted in ascending order +std::vector<offset_t> MakeNewTargetsFromPatch( + const std::vector<offset_t>& old_targets, + const EquivalenceSource& equivalence_source); + +// Reads equivalences from |patch_reader| to form preliminary |new_image|, +// copying regions from |old_image| and writing extra data from |patch_reader|. +bool ApplyEquivalenceAndExtraData(ConstBufferView old_image, + const PatchElementReader& patch_reader, + MutableBufferView new_image); + +// Reads raw delta from |patch_reader| and applies corrections to |new_image|. +bool ApplyRawDelta(const PatchElementReader& patch_reader, + MutableBufferView new_image); + +// Corrects references in |new_image| by projecting references from |old_image| +// and applying corrections from |patch_reader|. Both |old_image| and +// |new_image| are matching elements associated with |exe_type|. +bool ApplyReferencesCorrection(ExecutableType exe_type, + ConstBufferView old_image, + const PatchElementReader& patch_reader, + MutableBufferView new_image); + +// Applies patch element with type |exe_type| from |patch_reader| on |old_image| +// to produce |new_image|. +bool ApplyElement(ExecutableType exe_type, + ConstBufferView old_image, + const PatchElementReader& patch_reader, + MutableBufferView new_image); + +} // namespace zucchini + +#endif // CHROME_INSTALLER_ZUCCHINI_ZUCCHINI_APPLY_H_
diff --git a/chrome/installer/zucchini/zucchini_apply_unittest.cc b/chrome/installer/zucchini/zucchini_apply_unittest.cc new file mode 100644 index 0000000..cea670e9 --- /dev/null +++ b/chrome/installer/zucchini/zucchini_apply_unittest.cc
@@ -0,0 +1,80 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/installer/zucchini/zucchini_apply.h" + +#include <vector> + +#include "chrome/installer/zucchini/image_utils.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace zucchini { + +namespace { + +constexpr auto BAD = kUnusedIndex; +using OffsetVector = std::vector<offset_t>; + +} // namespace + +// Helper function wrapping MakeNewTargetsFromPatch(). |old_targets| must be +// sorted in ascending order and |equivalence| must be sorted in ascending order +// of |Equivalence::dst_offset|. +std::vector<offset_t> MakeNewTargetsFromPatchTest( + const OffsetVector& old_targets, + const std::vector<Equivalence>& equivalences) { + // Serialize |equivalences| to patch format, and read it back as + // EquivalenceSource. + EquivalenceSink equivalence_sink; + for (const Equivalence& equivalence : equivalences) + equivalence_sink.PutNext(equivalence); + + std::vector<uint8_t> buffer(equivalence_sink.SerializedSize()); + BufferSink sink(buffer.data(), buffer.size()); + equivalence_sink.SerializeInto(&sink); + + BufferSource source(buffer.data(), buffer.size()); + EquivalenceSource equivalence_source; + equivalence_source.Initialize(&source); + return MakeNewTargetsFromPatch(old_targets, equivalence_source); +} + +TEST(ZucchiniApplyTest, MakeNewTargetsFromPatch) { + // Note that |old_offsets| provided are sorted, and |equivalences| provided + // are sorted by |dst_offset|. + + EXPECT_EQ(OffsetVector(), MakeNewTargetsFromPatchTest({}, {})); + EXPECT_EQ(OffsetVector({BAD, BAD}), MakeNewTargetsFromPatchTest({0, 1}, {})); + + EXPECT_EQ(OffsetVector({0, 1, BAD}), + MakeNewTargetsFromPatchTest({0, 1, 2}, {{0, 0, 2}})); + EXPECT_EQ(OffsetVector({1, 2, BAD}), + MakeNewTargetsFromPatchTest({0, 1, 2}, {{0, 1, 2}})); + EXPECT_EQ( + OffsetVector({1, BAD, 4, 5, 6, BAD}), + MakeNewTargetsFromPatchTest({0, 1, 2, 3, 4, 5}, {{0, 1, 1}, {2, 4, 3}})); + EXPECT_EQ( + OffsetVector({3, BAD, 0, 1, 2, BAD}), + MakeNewTargetsFromPatchTest({0, 1, 2, 3, 4, 5}, {{2, 0, 3}, {0, 3, 1}})); + + // Overlap. + EXPECT_EQ( + OffsetVector({1, 2, 3, BAD, BAD}), + MakeNewTargetsFromPatchTest({0, 1, 2, 3, 4}, {{0, 1, 3}, {1, 4, 2}})); + EXPECT_EQ( + OffsetVector({1, 4, 5, 6, BAD}), + MakeNewTargetsFromPatchTest({0, 1, 2, 3, 4}, {{0, 1, 2}, {1, 4, 3}})); + EXPECT_EQ( + OffsetVector({1, 2, 5, BAD, BAD}), + MakeNewTargetsFromPatchTest({0, 1, 2, 3, 4}, {{0, 1, 2}, {1, 4, 2}})); + + // Jump. + EXPECT_EQ(OffsetVector({5, BAD, 6}), + MakeNewTargetsFromPatchTest({10, 13, 15}, + {{0, 1, 2}, {9, 4, 2}, {15, 6, 2}})); +} + +// TODO(huangs): Add more tests. + +} // namespace zucchini
diff --git a/chrome/profiling/json_exporter.cc b/chrome/profiling/json_exporter.cc index e490fa6fb..bf38801 100644 --- a/chrome/profiling/json_exporter.cc +++ b/chrome/profiling/json_exporter.cc
@@ -6,7 +6,12 @@ #include <map> +#include "base/command_line.h" +#include "base/cpu.h" +#include "base/format_macros.h" #include "base/strings/string_number_conversions.h" +#include "base/strings/stringprintf.h" +#include "base/sys_info.h" #include "base/trace_event/trace_event_argument.h" #include "services/resource_coordinator/public/cpp/memory_instrumentation/tracing_observer.h" @@ -14,6 +19,27 @@ namespace { +// This is the set of metadata fields that is too annoying to plumb into the +// profiling process for now. The memory dump is useful without all this data +// anyways. It's mostly here to make the tracing UI work well. +const char kFakeOtherMetadata[] = + R"END( + "field-trials":[], + "gpu-devid":5052, + "gpu-driver":"367.57", + "gpu-gl-renderer":"Quadro K1200/PCIe/SSE2", + "gpu-gl-vendor":"NVIDIA Corporation", + "gpu-psver":"4.50", + "gpu-venid":4318, + "gpu-vsver":"4.50", + "network-type":"Ethernet", + "product-version":"Chrome/59.0.3071.115", + "revision": + "3cf8514bb1239453fd15ff1f7efee389ac9df8ba-refs/branch-heads/3071@{#820}", + "trace-config":"{}", + "user-agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36", + "v8-version":"5.9.211.38")END"; + // Maps strings to integers for the JSON string table. using StringTable = std::map<std::string, size_t>; @@ -105,8 +131,17 @@ StringTable* string_table) { int parent = -1; for (const Address& addr : backtrace.addrs()) { - size_t sid = - AddOrGetString("pc:" + base::Uint64ToString(addr.value), string_table); + static constexpr char kPcPrefix[] = "pc:"; + // std::numeric_limits<>::digits gives the number of bits in the value. + // Dividing by 4 gives the number of hex digits needed to store the value. + // Adding to sizeof(kPcPrefix) yields the buffer size needed including the + // null terminator. + static constexpr int kBufSize = + sizeof(kPcPrefix) + + (std::numeric_limits<decltype(addr.value)>::digits / 4); + char buf[kBufSize]; + snprintf(buf, kBufSize, "%s%" PRIx64, kPcPrefix, addr.value); + size_t sid = AddOrGetString(buf, string_table); nodes->emplace_back(sid, parent); parent = nodes->size() - 1; } @@ -217,6 +252,101 @@ out << "]"; } +// Copy-pastaed from content/browser/tracing/tracing_controller_impl.cc. +std::string GetClockString() { + switch (base::TimeTicks::GetClock()) { + case base::TimeTicks::Clock::FUCHSIA_MX_CLOCK_MONOTONIC: + return "FUCHSIA_MX_CLOCK_MONOTONIC"; + case base::TimeTicks::Clock::LINUX_CLOCK_MONOTONIC: + return "LINUX_CLOCK_MONOTONIC"; + case base::TimeTicks::Clock::IOS_CF_ABSOLUTE_TIME_MINUS_KERN_BOOTTIME: + return "IOS_CF_ABSOLUTE_TIME_MINUS_KERN_BOOTTIME"; + case base::TimeTicks::Clock::MAC_MACH_ABSOLUTE_TIME: + return "MAC_MACH_ABSOLUTE_TIME"; + case base::TimeTicks::Clock::WIN_QPC: + return "WIN_QPC"; + case base::TimeTicks::Clock::WIN_ROLLOVER_PROTECTED_TIME_GET_TIME: + return "WIN_ROLLOVER_PROTECTED_TIME_GET_TIME"; + } + + NOTREACHED(); + return std::string(); +} + +void WriteMetadata(std::ostream& out) { + // This is copy-pastaed from + // TracingControllerImpl::GenerateTracingMetadataDict(). + // + // The memory dump doesn't really need most of this info. This is here to make + // the trace viewer and some supporting scripts happy. The main things that + // are useful are command_line and os-name which help the scripts know how to + // symbolize the dump. + out << "\"metadata\": {\n"; + +// Output the OS info. +#if defined(OS_CHROMEOS) + out << "\"os-name\": \"CrOS\",\n; + int32_t major_version; + int32_t minor_version; + int32_t bugfix_version; + // OperatingSystemVersion only has a POSIX implementation which returns the + // wrong versions for CrOS. + base::SysInfo::OperatingSystemVersionNumbers(&major_version, &minor_version, + &bugfix_version); + out << "\"os-version\": \"" + << base::StringPrintf("%d.%d.%d", major_version, minor_version, + bugfix_version) + << "\",\n"; +#else + out << "\"os-name\": \"" << base::SysInfo::OperatingSystemName() << "\",\n"; + out << "\"os-version\": \"" << base::SysInfo::OperatingSystemVersion() + << "\",\n"; +#endif + out << "\"os-arch\": \"" << base::SysInfo::OperatingSystemArchitecture() + << "\",\n"; + + // Output CPU info. + base::CPU cpu; + out << "\"cpu-family\": " << cpu.family() << ",\n" + << "\"cpu-model\": " << cpu.model() << ",\n" + << "\"cpu-stepping\": " << cpu.stepping() << ",\n" + << "\"num-cpus\": " << base::SysInfo::NumberOfProcessors() << ",\n" + << "\"physical-memory\": " << base::SysInfo::AmountOfPhysicalMemoryMB() + << ",\n"; + + std::string cpu_brand = cpu.cpu_brand(); + // Workaround for crbug.com/249713. + // TODO(oysteine): Remove workaround when bug is fixed. + size_t null_pos = cpu_brand.find('\0'); + if (null_pos != std::string::npos) + cpu_brand.erase(null_pos); + out << "\"cpu-brand\": \"" << cpu_brand << "\",\n"; + + // Output clock stuff. + out << "\"clock-domain\": \"" << GetClockString() << "\",\n" + << "\"highres-ticks\": " + << (base::TimeTicks::IsHighResolution() ? "true" : "false") << ",\n"; + + // Output timestamp. + base::Time::Exploded ctime; + base::Time::Now().UTCExplode(&ctime); + std::string time_string = base::StringPrintf( + "%u-%u-%u %d:%d:%d", ctime.year, ctime.month, ctime.day_of_month, + ctime.hour, ctime.minute, ctime.second); + out << "\"trace-capture-datetime\": \"" << time_string << "\",\n"; + + // TODO(ajwong): This is the commandline for the profiling process and not the + // target. This is completely the wrong thing, but for now it gets us going. + // https://crbug.com/755382 + out << "\"command_line\": \"" + << base::CommandLine::ForCurrentProcess()->GetCommandLineString() + << "\",\n"; + + out << kFakeOtherMetadata; + + out << "}\n"; +} + } // namespace void ExportAllocationEventSetToJSON( @@ -234,6 +364,9 @@ WriteHeapsV2Header(out); + // Output Heaps_V2 format version. Currently "1" is the only valid value. + out << "\"version\": 1,\n"; + StringTable string_table; // We hardcode one type, "[unknown]". @@ -255,6 +388,7 @@ // one and share the common nodes. std::vector<BacktraceNode> nodes; nodes.reserve(backtraces.size() * 10); // Guesstimate for end size. + VLOG(1) << "Number of backtraces " << backtraces.size(); for (auto& bt : backtraces) bt.second = AppendBacktraceStrings(*bt.first, &nodes, &string_table); @@ -288,7 +422,9 @@ WriteHeapsV2Footer(out); WriteDumpsFooter(out); - out << "]}\n"; + out << "],"; + WriteMetadata(out); + out << "}\n"; } } // namespace profiling
diff --git a/chrome/profiling/json_exporter_unittest.cc b/chrome/profiling/json_exporter_unittest.cc index ffd1367..095942cf 100644 --- a/chrome/profiling/json_exporter_unittest.cc +++ b/chrome/profiling/json_exporter_unittest.cc
@@ -97,7 +97,7 @@ std::unique_ptr<base::Value> root = reader.ReadToValue(stream.str()); ASSERT_EQ(base::JSONReader::JSON_NO_ERROR, reader.error_code()) << reader.GetErrorMessage(); - ASSERT_TRUE(root.get()); + ASSERT_TRUE(root); // The trace array contains two items, a process_name one and a // periodic_interval one. Find the latter. @@ -136,7 +136,7 @@ std::unique_ptr<base::Value> root = reader.ReadToValue(stream.str()); ASSERT_EQ(base::JSONReader::JSON_NO_ERROR, reader.error_code()) << reader.GetErrorMessage(); - ASSERT_TRUE(root.get()); + ASSERT_TRUE(root); const base::Value* periodic_interval = FindFirstPeriodicInterval(*root); ASSERT_TRUE(periodic_interval) << "Array contains no periodic_interval"; @@ -154,4 +154,53 @@ EXPECT_NE(size->second.GetString(), "0"); } +TEST(ProfilingJsonExporterTest, Metadata) { + BacktraceStorage backtrace_storage; + + std::vector<Address> stack1; + stack1.push_back(Address(1234)); + stack1.push_back(Address(5678)); + const Backtrace* bt1 = backtrace_storage.Insert(std::move(stack1)); + + std::vector<Address> stack2; + stack2.push_back(Address(9012)); + const Backtrace* bt2 = backtrace_storage.Insert(std::move(stack2)); + + AllocationEventSet events; + events.insert(AllocationEvent(Address(0x1), 16, bt1)); + events.insert(AllocationEvent(Address(0x2), 32, bt2)); + events.insert(AllocationEvent(Address(0x3), 16, bt1)); + + std::ostringstream stream; + ExportAllocationEventSetToJSON(1234, events, MemoryMap(), stream); + std::string json = stream.str(); + + // JSON should parse. + base::JSONReader reader(base::JSON_PARSE_RFC); + std::unique_ptr<base::Value> root = reader.ReadToValue(stream.str()); + ASSERT_EQ(base::JSONReader::JSON_NO_ERROR, reader.error_code()) + << reader.GetErrorMessage(); + ASSERT_TRUE(root); + + auto found_metadatas = + root->FindKeyOfType("metadata", base::Value::Type::DICTIONARY); + ASSERT_NE(found_metadatas, root->DictEnd()) << "Array contains no metadata"; + base::DictionaryValue* metadata; + ASSERT_TRUE(found_metadatas->second.GetAsDictionary(&metadata)); + + // Assert existence of key fields needed for symbolize_trace. + ASSERT_NE(metadata->FindKeyOfType("command_line", base::Value::Type::STRING), + metadata->DictEnd()); + ASSERT_NE(metadata->FindKeyOfType("os-name", base::Value::Type::STRING), + metadata->DictEnd()); + ASSERT_NE(metadata->FindKeyOfType("os-version", base::Value::Type::STRING), + metadata->DictEnd()); + ASSERT_NE(metadata->FindKeyOfType("trace-capture-datetime", + base::Value::Type::STRING), + metadata->DictEnd()); + ASSERT_NE( + metadata->FindKeyOfType("physical-memory", base::Value::Type::INTEGER), + metadata->DictEnd()); +} + } // namespace profiling
diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc index bee43c1..5eec56a 100644 --- a/chrome/renderer/chrome_content_renderer_client.cc +++ b/chrome/renderer/chrome_content_renderer_client.cc
@@ -1271,9 +1271,11 @@ if (base::FeatureList::IsEnabled(features::kNetworkService)) { InitSafeBrowsingIfNecessary(); RenderFrame* render_frame = content::RenderFrame::FromWebFrame(frame); + int render_frame_id = + render_frame ? render_frame->GetRoutingID() : MSG_ROUTING_NONE; throttles->push_back( base::MakeUnique<safe_browsing::RendererURLLoaderThrottle>( - safe_browsing_.get(), render_frame->GetRoutingID())); + safe_browsing_.get(), render_frame_id)); } // Check whether the request should be allowed. If not allowed, we reset the
diff --git a/chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.cc b/chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.cc index f16b2eb..8676962 100644 --- a/chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.cc +++ b/chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.cc
@@ -272,6 +272,8 @@ source_map->RegisterSource("mojo/common/time.mojom", IDR_MOJO_TIME_MOJOM_JS); source_map->RegisterSource("net/interfaces/ip_address.mojom", IDR_MOJO_IP_ADDRESS_MOJOM_JS); + source_map->RegisterSource("net/interfaces/ip_endpoint.mojom", + IDR_MOJO_IP_ENDPOINT_MOJOM_JS); source_map->RegisterSource("url/mojo/origin.mojom", IDR_ORIGIN_MOJOM_JS); source_map->RegisterSource("url/mojo/url.mojom", IDR_MOJO_URL_MOJOM_JS); source_map->RegisterSource("media/mojo/interfaces/remoting_common.mojom",
diff --git a/chrome/renderer/resources/extensions/media_router_bindings.js b/chrome/renderer/resources/extensions/media_router_bindings.js index 739d87d6..1f9f4fb 100644 --- a/chrome/renderer/resources/extensions/media_router_bindings.js +++ b/chrome/renderer/resources/extensions/media_router_bindings.js
@@ -15,6 +15,7 @@ 'mojo/common/time.mojom', 'mojo/public/js/bindings', 'net/interfaces/ip_address.mojom', + 'net/interfaces/ip_endpoint.mojom', 'url/mojo/origin.mojom', 'url/mojo/url.mojom', ], function(mediaControllerMojom, @@ -27,6 +28,7 @@ timeMojom, bindings, ipAddressMojom, + ipEndpointMojom, originMojom, urlMojom) { 'use strict'; @@ -280,6 +282,7 @@ DialMediaSink: mediaRouterMojom.DialMediaSink, CastMediaSink: mediaRouterMojom.CastMediaSink, IPAddress: ipAddressMojom.IPAddress, + IPEndpoint: ipEndpointMojom.IPEndpoint, InterfacePtrController: bindings.InterfacePtrController, InterfaceRequest: bindings.InterfaceRequest, MediaController: mediaControllerMojom.MediaController,
diff --git a/chrome/renderer/resources/renderer_resources.grd b/chrome/renderer/resources/renderer_resources.grd index 2fa8731a..6e937a3d 100644 --- a/chrome/renderer/resources/renderer_resources.grd +++ b/chrome/renderer/resources/renderer_resources.grd
@@ -90,6 +90,7 @@ <include name="IDR_MEDIA_STATUS_MOJOM_JS" file="${mojom_root}\chrome\common\media_router\mojo\media_status.mojom.js" use_base_dir="false" type="BINDATA" /> <include name="IDR_MOJO_TIME_MOJOM_JS" file="${mojom_root}\mojo\common\time.mojom.js" use_base_dir="false" type="BINDATA" /> <include name="IDR_MOJO_IP_ADDRESS_MOJOM_JS" file="${mojom_root}\net\interfaces\ip_address.mojom.js" use_base_dir="false" type="BINDATA" /> + <include name="IDR_MOJO_IP_ENDPOINT_MOJOM_JS" file="${mojom_root}\net\interfaces\ip_endpoint.mojom.js" use_base_dir="false" type="BINDATA" /> <include name="IDR_ORIGIN_MOJOM_JS" file="${mojom_root}\url\mojo\origin.mojom.js" use_base_dir="false" type="BINDATA" /> <include name="IDR_MOJO_URL_MOJOM_JS" file="${mojom_root}\url\mojo\url.mojom.js" use_base_dir="false" type="BINDATA" /> <include name="IDR_MEDIA_REMOTING_JS" file="${mojom_root}\media\mojo\interfaces\mirror_service_remoting.mojom.js" use_base_dir="false" type="BINDATA" />
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 8360ae5..af4a798 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -1447,7 +1447,13 @@ "../browser/ssl/ssl_client_certificate_selector_test.cc", "../browser/ssl/ssl_client_certificate_selector_test.h", "../browser/storage/durable_storage_browsertest.cc", + "../browser/subresource_filter/subresource_filter_browser_test_harness.cc", + "../browser/subresource_filter/subresource_filter_browser_test_harness.h", "../browser/subresource_filter/subresource_filter_browsertest.cc", + "../browser/subresource_filter/subresource_filter_popup_browsertest.cc", + "../browser/subresource_filter/subresource_filter_settings_browsertest.cc", + "../browser/subresource_filter/subresource_filter_web_socket_browsertest.cc", + "../browser/subresource_filter/subresource_filter_worker_browsertest.cc", "../browser/subresource_filter/test_ruleset_publisher.cc", "../browser/subresource_filter/test_ruleset_publisher.h", "../browser/sync_file_system/mock_local_change_processor.cc", @@ -2038,7 +2044,6 @@ "../browser/ui/ash/networking_config_delegate_chromeos_browsertest.cc", "../browser/ui/ash/shelf_browsertest.cc", "../browser/ui/ash/system_tray_client_browsertest.cc", - "../browser/ui/ash/system_tray_delegate_chromeos_browsertest_chromeos.cc", "../browser/ui/ash/system_tray_tray_cast_browsertest_media_router_chromeos.cc", "../browser/ui/ash/volume_controller_browsertest.cc", "../browser/ui/sort_windows_by_z_index_browsertest.cc", @@ -2941,6 +2946,7 @@ "//testing/scripts/common.py", "//testing/xvfb.py", "//testing/scripts/run_telemetry_as_googletest.py", + # For smoke testing run_telemetry_benchmark_as_googletest "//testing/scripts/run_telemetry_benchmark_as_googletest.py", ] @@ -3975,6 +3981,8 @@ "../browser/extensions/api/extension_action/browser_action_unittest.cc", "../browser/extensions/api/extension_action/extension_action_prefs_unittest.cc", "../browser/extensions/api/feedback_private/feedback_private_api_chromeos_unittest.cc", + "../browser/extensions/api/feedback_private/feedback_private_api_unittest_base_chromeos.cc", + "../browser/extensions/api/feedback_private/feedback_private_api_unittest_base_chromeos.h", "../browser/extensions/api/feedback_private/log_source_access_manager_chromeos_unittest.cc", "../browser/extensions/api/file_system/file_system_api_unittest.cc", "../browser/extensions/api/identity/extension_token_key_unittest.cc",
diff --git a/chrome/test/base/in_process_browser_test.cc b/chrome/test/base/in_process_browser_test.cc index e0b2e184..f3171b3 100644 --- a/chrome/test/base/in_process_browser_test.cc +++ b/chrome/test/base/in_process_browser_test.cc
@@ -85,7 +85,6 @@ #if defined(OS_CHROMEOS) #include "chrome/browser/chromeos/input_method/input_method_configuration.h" -#include "chrome/browser/ui/webui/options/browser_options_handler.h" #endif // defined(OS_CHROMEOS) #if defined(USE_ASH) @@ -253,9 +252,6 @@ google_util::SetMockLinkDoctorBaseURLForTesting(); #if defined(OS_CHROMEOS) - // Polymer Elements are used for quick unlock configuration in options page, - // which is chromeos specific feature. - options::BrowserOptionsHandler::DisablePolymerPreloadForTesting(); // On Chrome OS, access to files via file: scheme is restricted. Enable // access to all files here since browser_tests and interactive_ui_tests // rely on the ability to open any files via file: scheme.
diff --git a/chrome/test/chromedriver/BUILD.gn b/chrome/test/chromedriver/BUILD.gn index ce99cba..e8dd5e92 100644 --- a/chrome/test/chromedriver/BUILD.gn +++ b/chrome/test/chromedriver/BUILD.gn
@@ -10,6 +10,7 @@ js_files = [ "js/call_function.js", + "js/dispatch_touch_event.js", "js/execute_async_script.js", "js/focus.js", "js/get_element_region.js",
diff --git a/chrome/test/chromedriver/chrome/web_view_impl.cc b/chrome/test/chromedriver/chrome/web_view_impl.cc index 35391f88..8cb094b 100644 --- a/chrome/test/chromedriver/chrome/web_view_impl.cc +++ b/chrome/test/chromedriver/chrome/web_view_impl.cc
@@ -70,24 +70,11 @@ const char* GetAsString(TouchEventType type) { switch (type) { case kTouchStart: - return "touchStart"; + return "touchstart"; case kTouchEnd: - return "touchEnd"; + return "touchend"; case kTouchMove: - return "touchMove"; - default: - return ""; - } -} - -const char* GetPointStateString(TouchEventType type) { - switch (type) { - case kTouchStart: - return "touchPressed"; - case kTouchEnd: - return "touchReleased"; - case kTouchMove: - return "touchMoved"; + return "touchmove"; default: return ""; } @@ -387,16 +374,12 @@ } Status WebViewImpl::DispatchTouchEvent(const TouchEvent& event) { - base::DictionaryValue params; - params.SetString("type", GetAsString(event.type)); - auto point = base::MakeUnique<base::DictionaryValue>(); - point->SetString("state", GetPointStateString(event.type)); - point->SetInteger("x", event.x); - point->SetInteger("y", event.y); - auto point_list = base::MakeUnique<base::ListValue>(); - point_list->Append(std::move(point)); - params.Set("touchPoints", std::move(point_list)); - return client_->SendCommand("Input.dispatchTouchEvent", params); + base::ListValue args; + args.Append(base::MakeUnique<base::Value>(event.x)); + args.Append(base::MakeUnique<base::Value>(event.y)); + args.Append(base::MakeUnique<base::Value>(GetAsString(event.type))); + std::unique_ptr<base::Value> unused; + return CallFunction(std::string(), kDispatchTouchEventScript, args, &unused); } Status WebViewImpl::DispatchTouchEvents(const std::list<TouchEvent>& events) { @@ -490,6 +473,7 @@ params.SetBoolean("secure", secure); params.SetBoolean("httpOnly", httpOnly); params.SetDouble("expirationDate", expiry); + params.SetDouble("expires", expiry); return client_->SendCommand("Network.setCookie", params); }
diff --git a/chrome/test/chromedriver/js/dispatch_touch_event.js b/chrome/test/chromedriver/js/dispatch_touch_event.js new file mode 100644 index 0000000..82d5070 --- /dev/null +++ b/chrome/test/chromedriver/js/dispatch_touch_event.js
@@ -0,0 +1,46 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * Dispatches a fake touch event with a single touch point. + * + * @param {number} x X-coordinate of the touch point relative to viewport + * in CSS pixels. + * @param {number} y Y-coordinate of the touch point relative to viewport + * in CSS pixels. + * @param {string} type Touch event type, e.g. touchstart. + */ +function dispatchTouchEvent(x, y, type) { + var element = window.document.elementFromPoint(x, y); + var inputDeviceCapabilities = + new InputDeviceCapabilities({fireTouchEvents: true}); + var touch = new Touch({ + identifier: 0, + target: element, + clientX: x, + clientY: y, + pageX: x + window.document.scrollingElement.scrollLeft, + pageY: y + window.document.scrollingElement.scrollTop, + force: 1, + radiusX: 1, + radiusY: 1, + screenX: x + window.screenX, + screenY: y + window.screenY, + }); + var event = new TouchEvent(type, { + touches: [touch], + targetTouches: [touch], + changedTouches: [touch], + ctrlKey: false, + shiftKey: false, + altKey: false, + metaKey: false, + view: window, + bubbles: true, + cancelable: false, + composed: true, + sourceCapabilities: inputDeviceCapabilities, + }); + element.dispatchEvent(event); +}
diff --git a/chrome/test/chromedriver/js/dispatch_touch_event_test.html b/chrome/test/chromedriver/js/dispatch_touch_event_test.html new file mode 100644 index 0000000..4d03d7e --- /dev/null +++ b/chrome/test/chromedriver/js/dispatch_touch_event_test.html
@@ -0,0 +1,78 @@ +<!DOCTYPE HTML> +<html> +<script src='test.js'></script> +<script src='dispatch_touch_event.js'></script> +<script> + +function setup(state, classes) { + for (let c of classes) { + state[c] = {}; + state[c].onTouchStart = function(event) { + state[c].touchStart = event; + }; + state[c].onTouchMove = function(event) { + state[c].touchMove = event; + }; + state[c].onTouchEnd = function(event) { + state[c].touchEnd = event; + }; + state[c].el = document.querySelector('.' + c); + state[c].el.addEventListener('touchstart', state[c].onTouchStart, false); + state[c].el.addEventListener('touchmove', state[c].onTouchMove, false); + state[c].el.addEventListener('touchend', state[c].onTouchEnd, false); + } +} + +function teardown(state) { + for (let c in state) { + state[c].el.removeEventListener('touchstart', state[c].onTouchStart, false); + state[c].el.removeEventListener('touchmove', state[c].onTouchMove, false); + state[c].el.removeEventListener('touchend', state[c].onTouchEnd, false); + } +} + +function testCorrectTarget1() { + var s = {}; + setup(s, ['div1', 'div2']); + dispatchTouchEvent(50, 50, 'touchstart'); + teardown(s); + assert(s.div1.touchStart && s.div1.touchStart.target === s.div1.el); + assert(!s.div2.touchStart); +} + +function testCorrectTarget2() { + var s = {}; + setup(s, ['div1', 'div2']); + dispatchTouchEvent(50, 150, 'touchstart'); + teardown(s); + assert(s.div2.touchStart && s.div2.touchStart.target === s.div2.el); + assert(!s.div1.touchStart); +} + +function testAllEvents() { + var s = {}; + setup(s, ['div1', 'div2']); + dispatchTouchEvent(10, 20, 'touchstart'); + dispatchTouchEvent(30, 40, 'touchmove'); + dispatchTouchEvent(50, 60, 'touchend'); + teardown(s); + assert(s.div1.touchStart); + assert(s.div1.touchStart.target === s.div1.el); + assert(s.div1.touchStart.touches[0].clientX === 10); + assert(s.div1.touchStart.touches[0].clientY === 20); + assert(s.div1.touchMove); + assert(s.div1.touchMove.target === s.div1.el); + assert(s.div1.touchMove.touches[0].clientX === 30); + assert(s.div1.touchMove.touches[0].clientY === 40); + assert(s.div1.touchEnd); + assert(s.div1.touchEnd.target === s.div1.el); + assert(s.div1.touchEnd.touches[0].clientX === 50); + assert(s.div1.touchEnd.touches[0].clientY === 60); +} + +</script> +<body> +<div style="width:100px;height:100px;" class="div1"></div> +<div style="width:100px;height:100px;" class="div2"></div> +</body> +</html>
diff --git a/chrome/test/chromedriver/test/run_py_tests.py b/chrome/test/chromedriver/test/run_py_tests.py index ae18082..1f47ade 100755 --- a/chrome/test/chromedriver/test/run_py_tests.py +++ b/chrome/test/chromedriver/test/run_py_tests.py
@@ -69,6 +69,8 @@ 'ChromeDriverTest.testHoverOverElement', # https://bugs.chromium.org/p/chromedriver/issues/detail?id=833 'ChromeDriverTest.testAlertOnNewWindow', + # https://bugs.chromium.org/p/chromedriver/issues/detail?id=1882 + 'PerfTest.testColdExecuteScript', ] _VERSION_SPECIFIC_FILTER = {}
diff --git a/chrome/test/chromedriver/window_commands.cc b/chrome/test/chromedriver/window_commands.cc index b40eaa2..b8301f8 100644 --- a/chrome/test/chromedriver/window_commands.cc +++ b/chrome/test/chromedriver/window_commands.cc
@@ -131,7 +131,8 @@ cookie_dict->GetString("path", &path); double expiry = 0; cookie_dict->GetDouble("expires", &expiry); - expiry /= 1000; // Convert from millisecond to second. + if (expiry > 1e14) + expiry /= 1000; // Backwards compatibility ms -> sec. bool http_only = false; cookie_dict->GetBoolean("httpOnly", &http_only); bool session = false;
diff --git a/chrome/test/data/android/render_tests/ArticleSnippetsTest.modern-signin_promo.Nexus_5-19.png b/chrome/test/data/android/render_tests/ArticleSnippetsTest.modern-signin_promo.Nexus_5-19.png index 7278f66..54ff80d 100644 --- a/chrome/test/data/android/render_tests/ArticleSnippetsTest.modern-signin_promo.Nexus_5-19.png +++ b/chrome/test/data/android/render_tests/ArticleSnippetsTest.modern-signin_promo.Nexus_5-19.png Binary files differ
diff --git a/chrome/test/data/extensions/api_test/file_browser/recent_test/manifest.json b/chrome/test/data/extensions/api_test/file_browser/recent_test/manifest.json new file mode 100644 index 0000000..a81d09a5 --- /dev/null +++ b/chrome/test/data/extensions/api_test/file_browser/recent_test/manifest.json
@@ -0,0 +1,19 @@ +{ + // chrome-extension://pkplfbidichfdicaijlchgnapepdginl + "key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtDfX9dHNh948bt00YhZBm3P6E5QLaOt+v8kXVtibQfiPtOD2FTScB/f0wX/EQWVO7BkaSOsRkTPcPIgocyMPYr2FLgqGLFlYT9nQpKJZUFNF5oJ5rG6Nv7ppf4zEB3j6da1IBRTz2yOZ+6O1TMZxol/V62/QcqrJeggsHTEPGLdr9Ua4b1Ka0xKJnJngZljsbw93FI1o+P9dAh5BS6wTPiZI/vmJVjvMTkSTnaZ3n9Go2t7A0XLcSxLcVyuLAd2mAvSN0mIviOukdM66wr7llif71nKuUt+4qvlr/r9HfwzN6pA4jkwhtS1UD+3CmB+wsHwsnohNcuu4FIQ6rgq/7QIDAQAB", + "name": "chrome.fileManagerPrivate tests", + "version": "0.1", + "manifest_version": 2, + "description": "Tests of chrome.fileManagerPrivate.getRecentFiles", + "app": { + "background": { + "scripts": ["test.js"] + } + }, + "permissions": [ + "fileManagerPrivate", + { + "fileSystem": ["requestFileSystem"] + } + ] +}
diff --git a/chrome/test/data/extensions/api_test/file_browser/recent_test/test.js b/chrome/test/data/extensions/api_test/file_browser/recent_test/test.js new file mode 100644 index 0000000..3627c1f --- /dev/null +++ b/chrome/test/data/extensions/api_test/file_browser/recent_test/test.js
@@ -0,0 +1,52 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * Test files should be created before running the test extension. + */ + +function getVolumeMetadataList() { + return new Promise(function(resolve, reject) { + chrome.fileManagerPrivate.getVolumeMetadataList(resolve); + }); +} + +function requestFileSystem(volumeId) { + return new Promise(function(resolve, reject) { + chrome.fileSystem.requestFileSystem( + {volumeId: volumeId}, + function(fileSystem) { + if (!fileSystem) { + reject(new Error('Failed to acquire volume.')); + } + resolve(fileSystem); + }); + }); +} + +function requestAllFileSystems() { + return getVolumeMetadataList().then(function(volumes) { + return Promise.all(volumes.map(function(volume) { + return requestFileSystem(volume.volumeId); + })); + }); +} + +// Run the tests. +requestAllFileSystems().then(function() { + chrome.test.runTests([ + function testGetRecentFiles() { + chrome.fileManagerPrivate.getRecentFiles( + chrome.test.callbackPass(function(entries) { + var found = false; + for (var i = 0; i < entries.length; ++i) { + if (entries[i].name === 'all-justice.jpg') { + found = true; + } + } + chrome.test.assertTrue(found, 'all-justice.jpg not found'); + })); + } + ]); +});
diff --git a/chrome/test/data/extensions/api_test/networking_private/chromeos/test.js b/chrome/test/data/extensions/api_test/networking_private/chromeos/test.js index afe46db6..f78c92f 100644 --- a/chrome/test/data/extensions/api_test/networking_private/chromeos/test.js +++ b/chrome/test/data/extensions/api_test/networking_private/chromeos/test.js
@@ -274,8 +274,10 @@ WiFi: { BSSID: '00:01:02:03:04:05', Frequency: 2400, + HexSSID: "7769666931", Security: 'WEP-PSK', - SignalStrength: 40 + SignalStrength: 40, + SSID: "wifi1" } }, { GUID: 'stub_wifi2_guid', @@ -286,7 +288,9 @@ WiFi: { BSSID: '', Frequency: 5000, + HexSSID: "77696669325F50534B", Security: 'WPA-PSK', + SSID: "wifi2_PSK" } }], result); @@ -306,8 +310,10 @@ WiFi: { BSSID: '00:01:02:03:04:05', Frequency: 2400, + HexSSID: "7769666931", Security: 'WEP-PSK', - SignalStrength: 40 + SignalStrength: 40, + SSID: "wifi1" } }], result); @@ -359,8 +365,10 @@ WiFi: { BSSID: '00:01:02:03:04:05', Frequency: 2400, + HexSSID: "7769666931", Security: 'WEP-PSK', - SignalStrength: 40 + SignalStrength: 40, + SSID: "wifi1" } }, { Connectable: true, @@ -407,8 +415,10 @@ WiFi: { BSSID: '', Frequency: 5000, + HexSSID: "77696669325F50534B", Security: 'WPA-PSK', - SignalStrength: 80 + SignalStrength: 80, + SSID: "wifi2_PSK" } }], result); })); @@ -428,8 +438,10 @@ WiFi: { BSSID: '00:01:02:03:04:05', Frequency: 2400, + HexSSID: "7769666931", Security: 'WEP-PSK', - SignalStrength: 40 + SignalStrength: 40, + SSID: "wifi1" } }, { Connectable: true, @@ -442,8 +454,10 @@ WiFi: { BSSID: '', Frequency: 5000, + HexSSID: "77696669325F50534B", Security: 'WPA-PSK', - SignalStrength: 80 + SignalStrength: 80, + SSID: "wifi2_PSK" } }], result); })); @@ -737,8 +751,10 @@ WiFi: { BSSID: '', Frequency: 5000, + HexSSID: "77696669325F50534B", Security: 'WPA-PSK', - SignalStrength: 80 + SignalStrength: 80, + SSID: "wifi2_PSK" } }, result); }));
diff --git a/chrome/test/data/favicon/pushstate_with_favicon.html b/chrome/test/data/favicon/pushstate_with_favicon.html new file mode 100644 index 0000000..4c9d29bf --- /dev/null +++ b/chrome/test/data/favicon/pushstate_with_favicon.html
@@ -0,0 +1,10 @@ +<html> +<head> +<link rel="icon" href="icon.png"/> +<script> +window.onload = function() { + history.pushState("", "", "/favicon/pushstate_with_favicon_pushed.html"); +} +</script> +</head> +</html>
diff --git a/chrome/test/data/favicon/replacestate_with_favicon.html b/chrome/test/data/favicon/replacestate_with_favicon.html new file mode 100644 index 0000000..ee8bafd --- /dev/null +++ b/chrome/test/data/favicon/replacestate_with_favicon.html
@@ -0,0 +1,11 @@ +<html> +<head> +<link rel="icon" href="icon.png"/> +<script> +window.onload = function() { + history.replaceState("", "", + "/favicon/replacestate_with_favicon_replaced.html"); +} +</script> +</head> +</html>
diff --git a/chrome/test/data/pdf/combobox_form.pdf b/chrome/test/data/pdf/combobox_form.pdf new file mode 100644 index 0000000..5249276 --- /dev/null +++ b/chrome/test/data/pdf/combobox_form.pdf
@@ -0,0 +1,100 @@ +%PDF-1.7 +% ò¤ô +1 0 obj +<< + /Type /Catalog + /Pages 2 0 R + /AcroForm << /Fields [ 8 0 R 9 0 R 10 0 R ] /DR 4 0 R >> +>> +endobj +2 0 obj +<< /Count 1 /Kids [ 3 0 R ] /Type /Pages >> +endobj +3 0 obj +<< + /Type /Page + /Parent 2 0 R + /Resources 4 0 R + /MediaBox [ 0 0 300 300 ] + /Contents 7 0 R + /Annots [ 8 0 R 9 0 R 10 0 R ] +>> +endobj +4 0 obj +<< /Font 5 0 R >> +endobj +5 0 obj +<< /F1 6 0 R >> +endobj +6 0 obj +<< + /Type /Font + /Subtype /Type1 + /BaseFont /Helvetica +>> +endobj +7 0 obj +<< /Length 51 >> +stream +BT +0 0 0 rg +/F1 12 Tf +100 150 Td +(Test Form) Tj +ET +endstream +endobj +8 0 obj +<< + /Type /Annot + /FT /Ch + /Ff 393216 + /T (Combo_Editable) + /DA (0 0 0 rg /F1 12 Tf) + /Rect [ 100 50 200 80 ] + /Subtype /Widget + /Opt [[(foo) (Foo)] [(bar) (Bar)] [(qux) (Qux)]] +>> +endobj +9 0 obj +<< + /Type /Annot + /FT /Ch + /Ff 131072 + /T (Combo1) + /DA (0 0 0 rg /F1 12 Tf) + /Rect [ 100 100 200 130 ] + /Subtype /Widget + /Opt [(Apple) (Banana) (Cherry)] + /V (Banana) +>> +endobj +10 0 obj +<< + /Type /Annot + /FT /Ch + /Ff 131073 + /T (Combo_ReadOnly) + /DA (0 0 0 rg /F1 12 Tf) + /Rect [ 100 200 200 230 ] + /Subtype /Widget + /Opt [(Dog) (Elephant) (Frog)] +>> +endobj +xref +0 11 +0000000000 65535 f +0000000015 00000 n +0000000127 00000 n +0000000186 00000 n +0000000335 00000 n +0000000368 00000 n +0000000399 00000 n +0000000475 00000 n +0000000575 00000 n +0000000779 00000 n +0000000975 00000 n +trailer<< /Root 1 0 R /Size 11 >> +startxref +1164 +%%EOF
diff --git a/chrome/test/data/webui/extensions/cr_extensions_browsertest.js b/chrome/test/data/webui/extensions/cr_extensions_browsertest.js index 7f5b1ea..7aac99f 100644 --- a/chrome/test/data/webui/extensions/cr_extensions_browsertest.js +++ b/chrome/test/data/webui/extensions/cr_extensions_browsertest.js
@@ -164,6 +164,14 @@ .run(); }); +TEST_F( + 'CrExtensionsDetailViewTest', 'IndicatorTest', + function() { + mocha + .grep(assert(extension_detail_view_tests.TestNames.Indicator)) + .run(); + }); + //////////////////////////////////////////////////////////////////////////////// // Extension Item List Tests
diff --git a/chrome/test/data/webui/extensions/extension_detail_view_test.js b/chrome/test/data/webui/extensions/extension_detail_view_test.js index 1f137cf..4db9b1f 100644 --- a/chrome/test/data/webui/extensions/extension_detail_view_test.js +++ b/chrome/test/data/webui/extensions/extension_detail_view_test.js
@@ -8,6 +8,7 @@ var TestNames = { Layout: 'layout', ClickableElements: 'clickable elements', + Indicator: 'indicator', }; suite('ExtensionItemTest', function() { @@ -144,6 +145,14 @@ mockDelegate.testClickingCalls( item.$$('#remove-extension'), 'deleteItem', [extensionData.id]); }); + + test(assert(TestNames.Indicator), function() { + var indicator = item.$$('cr-tooltip-icon'); + expectTrue(indicator.hidden); + item.set('data.controlledInfo', {type: 'POLICY', text: 'policy'}); + Polymer.dom.flush(); + expectFalse(indicator.hidden); + }); }); return {
diff --git a/chrome/test/data/webui/extensions/extension_pack_dialog_test.js b/chrome/test/data/webui/extensions/extension_pack_dialog_test.js index fd0714b4..bce3f0f 100644 --- a/chrome/test/data/webui/extensions/extension_pack_dialog_test.js +++ b/chrome/test/data/webui/extensions/extension_pack_dialog_test.js
@@ -47,11 +47,6 @@ }, }; - var isElementVisible = function(element) { - var rect = element.getBoundingClientRect(); - return rect.width * rect.height > 0; - }; - suite('ExtensionPackDialogTests', function() { /** @type {extensions.PackDialog} */ var packDialog; @@ -70,9 +65,9 @@ test(assert(TestNames.Interaction), function() { var dialogElement = packDialog.$$('dialog'); - expectFalse(isElementVisible(dialogElement)); + expectFalse(extension_test_util.isElementVisible(dialogElement)); packDialog.show(); - expectTrue(isElementVisible(dialogElement)); + expectTrue(extension_test_util.isElementVisible(dialogElement)); expectEquals('', packDialog.$$('#root-dir').value); MockInteractions.tap(packDialog.$$('#root-dir-browse')); expectTrue(!!mockDelegate.rootPromise); @@ -110,7 +105,7 @@ var dialogElement = packDialog.$$('dialog'); packDialog.show(); - expectTrue(isElementVisible(dialogElement)); + expectTrue(extension_test_util.isElementVisible(dialogElement)); var kRootPath = 'this/is/a/path'; mockDelegate.mockResponse = { @@ -128,7 +123,7 @@ return PolymerTest.flushTasks(); }) .then(() => { - expectFalse(isElementVisible(dialogElement)); + expectFalse(extension_test_util.isElementVisible(dialogElement)); }); }); @@ -138,7 +133,7 @@ var alertElement; packDialog.show(); - expectTrue(isElementVisible(dialogElement)); + expectTrue(extension_test_util.isElementVisible(dialogElement)); var kRootPath = 'this/is/a/path'; mockDelegate.mockResponse = { @@ -156,15 +151,15 @@ // Make sure new alert and the appropriate buttons are visible. packDialogAlert = packDialog.$$('extensions-pack-dialog-alert'); alertElement = packDialogAlert.$.dialog; - expectTrue(isElementVisible(alertElement)); - expectTrue(isElementVisible(dialogElement)); + expectTrue(extension_test_util.isElementVisible(alertElement)); + expectTrue(extension_test_util.isElementVisible(dialogElement)); expectFalse(packDialogAlert.$$('.cancel-button').hidden); expectTrue(packDialogAlert.$$('.action-button').hidden); // After cancel, original dialog is still open and values unchanged. MockInteractions.tap(packDialogAlert.$$('.cancel-button')); - expectFalse(isElementVisible(alertElement)); - expectTrue(isElementVisible(dialogElement)); + expectFalse(extension_test_util.isElementVisible(alertElement)); + expectTrue(extension_test_util.isElementVisible(dialogElement)); expectEquals(kRootPath, packDialog.$$('#root-dir').value); }); }); @@ -175,7 +170,7 @@ var alertElement; packDialog.show(); - expectTrue(isElementVisible(dialogElement)); + expectTrue(extension_test_util.isElementVisible(dialogElement)); var kRootPath = 'this/is/a/path'; mockDelegate.mockResponse = { @@ -197,8 +192,8 @@ // Make sure new alert and the appropriate buttons are visible. packDialogAlert = packDialog.$$('extensions-pack-dialog-alert'); alertElement = packDialogAlert.$.dialog; - expectTrue(isElementVisible(alertElement)); - expectTrue(isElementVisible(dialogElement)); + expectTrue(extension_test_util.isElementVisible(alertElement)); + expectTrue(extension_test_util.isElementVisible(dialogElement)); expectFalse(packDialogAlert.$$('.cancel-button').hidden); expectFalse(packDialogAlert.$$('.action-button').hidden); @@ -209,7 +204,7 @@ }) .then(() => { // Make sure packExtension is called again with the right params. - expectFalse(isElementVisible(alertElement)); + expectFalse(extension_test_util.isElementVisible(alertElement)); expectEquals( mockDelegate.flag, mockDelegate.mockResponse.override_flags); });
diff --git a/chrome/test/data/webui/extensions/extension_test_util.js b/chrome/test/data/webui/extensions/extension_test_util.js index 941ec3a..5bd13fd 100644 --- a/chrome/test/data/webui/extensions/extension_test_util.js +++ b/chrome/test/data/webui/extensions/extension_test_util.js
@@ -125,7 +125,19 @@ }; /** - * Returns whether or not the element specified is visible. + * @param {!HTMLElement} element + * @return {boolean} whether or not the element passed in is visible + */ + function isElementVisible(element) { + var rect = element.getBoundingClientRect(); + return rect.width * rect.height > 0; // Width and height is never negative. + } + + /** + * Returns whether or not the element specified is visible. This is different + * from isElementVisible in that this function attempts to search for the + * element within a parent element, which means you can use it to check if + * the element exists at all. * @param {!HTMLElement} parentEl * @param {string} selector * @param {boolean=} checkLightDom @@ -195,15 +207,17 @@ } /** - * Tests that any iron-icon child of an HTML element has a corresponding - * non-empty svg element. + * Tests that any visible iron-icon child of an HTML element has a + * corresponding non-empty svg element. * @param {HTMLElement} e The element to check the iron icons in. */ function testIronIcons(e) { e.querySelectorAll('* /deep/ iron-icon').forEach(function(icon) { - var svg = icon.$$('svg'); - expectTrue(!!svg && svg.innerHTML != '', - 'icon "' + icon.icon + '" is not present'); + if(isElementVisible(icon)) { + var svg = icon.$$('svg'); + expectTrue(!!svg && svg.innerHTML != '', + 'icon "' + icon.icon + '" is not present'); + } }); } @@ -211,6 +225,7 @@ ClickMock: ClickMock, ListenerMock: ListenerMock, MockItemDelegate: MockItemDelegate, + isElementVisible: isElementVisible, isVisible: isVisible, testVisible: testVisible, createExtensionInfo: createExtensionInfo,
diff --git a/chrome/test/data/webui/settings/a11y/edit_dictionary_a11y_test.js b/chrome/test/data/webui/settings/a11y/edit_dictionary_a11y_test.js index 6a2c4ba8..4338943 100644 --- a/chrome/test/data/webui/settings/a11y/edit_dictionary_a11y_test.js +++ b/chrome/test/data/webui/settings/a11y/edit_dictionary_a11y_test.js
@@ -21,8 +21,6 @@ axeOptions: SettingsAccessibilityTest.axeOptions, /** @override */ setup: function() { - console.log('the route is not undefined!'); - assert(settings.routes.EDIT_DICTIONARY != undefined); settings.navigateTo(settings.routes.EDIT_DICTIONARY); Polymer.dom.flush(); },
diff --git a/chrome/test/data/webui/settings/site_details_tests.js b/chrome/test/data/webui/settings/site_details_tests.js index 05ebd72..f1d0a7d 100644 --- a/chrome/test/data/webui/settings/site_details_tests.js +++ b/chrome/test/data/webui/settings/site_details_tests.js
@@ -200,41 +200,49 @@ browserProxy.setPrefs(prefs); testElement = createSiteDetails('https://foo.com:443'); - return browserProxy.whenCalled('getOriginPermissions').then(() => { - testElement.root.querySelectorAll('site-details-permission') - .forEach((siteDetailsPermission) => { - // Verify settings match the values specified in |prefs|. - var expectedSetting = settings.ContentSetting.ALLOW; - var expectedSource = settings.SiteSettingSource.PREFERENCE; - var expectedMenuValue = settings.ContentSetting.ALLOW; + return browserProxy.whenCalled('isOriginValid') + .then(() => { + return browserProxy.whenCalled('getOriginPermissions'); + }) + .then(() => { + testElement.root.querySelectorAll('site-details-permission') + .forEach((siteDetailsPermission) => { + // Verify settings match the values specified in |prefs|. + var expectedSetting = settings.ContentSetting.ALLOW; + var expectedSource = settings.SiteSettingSource.PREFERENCE; + var expectedMenuValue = settings.ContentSetting.ALLOW; - // For all the categories with non-user-set 'Allow' preferences, - // update expected values. - if (siteDetailsPermission.category == - settings.ContentSettingsTypes.NOTIFICATIONS || - siteDetailsPermission.category == - settings.ContentSettingsTypes.PLUGINS || - siteDetailsPermission.category == - settings.ContentSettingsTypes.JAVASCRIPT || - siteDetailsPermission.category == - settings.ContentSettingsTypes.IMAGES || - siteDetailsPermission.category == - settings.ContentSettingsTypes.POPUPS) { - expectedSetting = - prefs.exceptions[siteDetailsPermission.category][0].setting; - expectedSource = - prefs.exceptions[siteDetailsPermission.category][0].source; - expectedMenuValue = - (expectedSource == settings.SiteSettingSource.DEFAULT) ? - settings.ContentSetting.DEFAULT : - expectedSetting; - } - assertEquals(expectedSetting, siteDetailsPermission.site.setting); - assertEquals(expectedSource, siteDetailsPermission.site.source); - assertEquals( - expectedMenuValue, siteDetailsPermission.$.permission.value); - }); - }); + // For all the categories with non-user-set 'Allow' preferences, + // update expected values. + if (siteDetailsPermission.category == + settings.ContentSettingsTypes.NOTIFICATIONS || + siteDetailsPermission.category == + settings.ContentSettingsTypes.PLUGINS || + siteDetailsPermission.category == + settings.ContentSettingsTypes.JAVASCRIPT || + siteDetailsPermission.category == + settings.ContentSettingsTypes.IMAGES || + siteDetailsPermission.category == + settings.ContentSettingsTypes.POPUPS) { + expectedSetting = + prefs.exceptions[siteDetailsPermission.category][0] + .setting; + expectedSource = + prefs.exceptions[siteDetailsPermission.category][0] + .source; + expectedMenuValue = + (expectedSource == settings.SiteSettingSource.DEFAULT) ? + settings.ContentSetting.DEFAULT : + expectedSetting; + } + assertEquals( + expectedSetting, siteDetailsPermission.site.setting); + assertEquals(expectedSource, siteDetailsPermission.site.source); + assertEquals( + expectedMenuValue, + siteDetailsPermission.$.permission.value); + }); + }); }); test('show confirmation dialog on reset settings', function() { @@ -268,7 +276,10 @@ testElement.root.querySelector('#notifications'); // Wait for all the permissions to be populated initially. - return browserProxy.whenCalled('getOriginPermissions') + return browserProxy.whenCalled('isOriginValid') + .then(() => { + return browserProxy.whenCalled('getOriginPermissions'); + }) .then(() => { // Make sure initial state is as expected. assertEquals( @@ -310,4 +321,31 @@ siteDetailsPermission.$.permission.value); }); }); + + test('invalid origins navigate back', function() { + var invalid_url = 'invalid url'; + browserProxy.setIsOriginValid(false); + + settings.navigateTo(settings.routes.SITE_SETTINGS); + settings.navigateTo(settings.routes.SITE_SETTINGS_SITE_DETAILS); + assertEquals( + settings.routes.SITE_SETTINGS_SITE_DETAILS.path, + settings.getCurrentRoute().path); + + loadTimeData.overrideValues({enableSiteSettings: false}); + testElement = createSiteDetails(invalid_url); + + return browserProxy.whenCalled('isOriginValid') + .then((args) => { + assertEquals(invalid_url, args); + return new Promise((resolve) => { + listenOnce(window, 'popstate', resolve); + }); + }) + .then(() => { + assertEquals( + settings.routes.SITE_SETTINGS.path, + settings.getCurrentRoute().path); + }) + }); });
diff --git a/chrome/test/data/webui/settings/test_site_settings_prefs_browser_proxy.js b/chrome/test/data/webui/settings/test_site_settings_prefs_browser_proxy.js index fce3d51d..72173d8 100644 --- a/chrome/test/data/webui/settings/test_site_settings_prefs_browser_proxy.js +++ b/chrome/test/data/webui/settings/test_site_settings_prefs_browser_proxy.js
@@ -67,6 +67,7 @@ 'getDefaultValueForContentType', 'getExceptionList', 'getOriginPermissions', + 'isOriginValid', 'isPatternValid', 'observeProtocolHandlers', 'observeProtocolHandlersEnabledState', @@ -102,6 +103,9 @@ this.cookieDetails_ = null; /** @private {boolean} */ + this.isOriginValid_ = true; + + /** @private {boolean} */ this.isPatternValid_ = true; } @@ -319,6 +323,19 @@ } /** @override */ + isOriginValid(origin) { + this.methodCalled('isOriginValid', origin); + return Promise.resolve(this.isOriginValid_); + } + + /** + * Specify whether isOriginValid should succeed or fail. + */ + setIsOriginValid(isValid) { + this.isOriginValid_ = isValid; + } + + /** @override */ isPatternValid(pattern) { this.methodCalled('isPatternValid', pattern); return Promise.resolve(this.isPatternValid_);
diff --git a/chromeos/network/network_state.cc b/chromeos/network/network_state.cc index 0b26d03..783ffd98 100644 --- a/chromeos/network/network_state.cc +++ b/chromeos/network/network_state.cc
@@ -295,6 +295,8 @@ dictionary->SetStringWithoutPathExpansion(shill::kEapMethodProperty, eap_method()); dictionary->SetKey(shill::kWifiFrequency, base::Value(frequency_)); + dictionary->SetStringWithoutPathExpansion(shill::kWifiHexSsid, + GetHexSsid()); } // Mobile properties
diff --git a/chromeos/network/network_state_unittest.cc b/chromeos/network/network_state_unittest.cc index fc008b75..7437d77 100644 --- a/chromeos/network/network_state_unittest.cc +++ b/chromeos/network/network_state_unittest.cc
@@ -120,7 +120,15 @@ base::HexEncode(wifi_hex_result.c_str(), wifi_hex_result.length()); EXPECT_TRUE(SetStringProperty(shill::kWifiHexSsid, wifi_hex)); EXPECT_TRUE(SignalInitialPropertiesReceived()); - EXPECT_EQ(network_state_.name(), wifi_hex_result); + EXPECT_EQ(wifi_hex_result, network_state_.name()); + + // Check HexSSID via network state dictionary. + base::DictionaryValue dictionary; + network_state_.GetStateProperties(&dictionary); + std::string value; + EXPECT_TRUE( + dictionary.GetStringWithoutPathExpansion(shill::kWifiHexSsid, &value)); + EXPECT_EQ(wifi_hex, value); } // Non-UTF-8 SSID should be preserved in |raw_ssid_| field.
diff --git a/components/arc/BUILD.gn b/components/arc/BUILD.gn index a735581..6f8e172 100644 --- a/components/arc/BUILD.gn +++ b/components/arc/BUILD.gn
@@ -138,6 +138,7 @@ "common/bitmap.mojom", "common/bluetooth.mojom", "common/boot_phase_monitor.mojom", + "common/cast_receiver.mojom", "common/clipboard.mojom", "common/crash_collector.mojom", "common/enterprise_reporting.mojom",
diff --git a/components/arc/arc_bridge_host_impl.cc b/components/arc/arc_bridge_host_impl.cc index 08fc8d13..43adfa9 100644 --- a/components/arc/arc_bridge_host_impl.cc +++ b/components/arc/arc_bridge_host_impl.cc
@@ -115,6 +115,12 @@ std::move(boot_phase_monitor_ptr)); } +void ArcBridgeHostImpl::OnCastReceiverInstanceReady( + mojom::CastReceiverInstancePtr cast_receiver_ptr) { + OnInstanceReady(arc_bridge_service_->cast_receiver(), + std::move(cast_receiver_ptr)); +} + void ArcBridgeHostImpl::OnClipboardInstanceReady( mojom::ClipboardInstancePtr clipboard_ptr) { OnInstanceReady(arc_bridge_service_->clipboard(), std::move(clipboard_ptr));
diff --git a/components/arc/arc_bridge_host_impl.h b/components/arc/arc_bridge_host_impl.h index bff6149..bcc4cab1 100644 --- a/components/arc/arc_bridge_host_impl.h +++ b/components/arc/arc_bridge_host_impl.h
@@ -47,6 +47,8 @@ mojom::BluetoothInstancePtr bluetooth_ptr) override; void OnBootPhaseMonitorInstanceReady( mojom::BootPhaseMonitorInstancePtr boot_phase_monitor_ptr) override; + void OnCastReceiverInstanceReady( + mojom::CastReceiverInstancePtr cast_receiver_ptr) override; void OnClipboardInstanceReady( mojom::ClipboardInstancePtr clipboard_ptr) override; void OnCrashCollectorInstanceReady(
diff --git a/components/arc/arc_bridge_service.h b/components/arc/arc_bridge_service.h index 447800b7..35eaabf1 100644 --- a/components/arc/arc_bridge_service.h +++ b/components/arc/arc_bridge_service.h
@@ -20,6 +20,7 @@ class AuthInstance; class BluetoothInstance; class BootPhaseMonitorInstance; +class CastReceiverInstance; class ClipboardInstance; class CrashCollectorInstance; class EnterpriseReportingInstance; @@ -63,6 +64,9 @@ InstanceHolder<mojom::BootPhaseMonitorInstance>* boot_phase_monitor() { return &boot_phase_monitor_; } + InstanceHolder<mojom::CastReceiverInstance>* cast_receiver() { + return &cast_receiver_; + } InstanceHolder<mojom::ClipboardInstance>* clipboard() { return &clipboard_; } InstanceHolder<mojom::CrashCollectorInstance>* crash_collector() { return &crash_collector_; @@ -116,6 +120,7 @@ InstanceHolder<mojom::AuthInstance> auth_; InstanceHolder<mojom::BluetoothInstance> bluetooth_; InstanceHolder<mojom::BootPhaseMonitorInstance> boot_phase_monitor_; + InstanceHolder<mojom::CastReceiverInstance> cast_receiver_; InstanceHolder<mojom::ClipboardInstance> clipboard_; InstanceHolder<mojom::CrashCollectorInstance> crash_collector_; InstanceHolder<mojom::EnterpriseReportingInstance> enterprise_reporting_;
diff --git a/components/arc/common/arc_bridge.mojom b/components/arc/common/arc_bridge.mojom index af02f87..0269e47 100644 --- a/components/arc/common/arc_bridge.mojom +++ b/components/arc/common/arc_bridge.mojom
@@ -10,6 +10,7 @@ import "auth.mojom"; import "bluetooth.mojom"; import "boot_phase_monitor.mojom"; +import "cast_receiver.mojom"; import "clipboard.mojom"; import "crash_collector.mojom"; import "enterprise_reporting.mojom"; @@ -34,9 +35,9 @@ import "volume_mounter.mojom"; import "wallpaper.mojom"; -// Next MinVersion: 26 +// Next MinVersion: 27 // Deprecated method IDs: 101, 105 -// Next method ID: 132 +// Next method ID: 133 interface ArcBridgeHost { // Keep the entries alphabetical. In order to do so without breaking // compatibility with the ARC instance, explicitly assign each interface a @@ -62,6 +63,10 @@ [MinVersion=19] OnBootPhaseMonitorInstanceReady@125( BootPhaseMonitorInstance instance_ptr); + // Notifies Chrome that the CastReceiverInstance interface is ready. + [MinVersion=27] OnCastReceiverInstanceReady@132( + CastReceiverInstance instance_ptr); + // Notifies Chrome that the ClipboardInstance interface is ready. [MinVersion=2] OnClipboardInstanceReady@109(ClipboardInstance instance_ptr);
diff --git a/components/arc/common/cast_receiver.mojom b/components/arc/common/cast_receiver.mojom new file mode 100644 index 0000000..3801a1fc --- /dev/null +++ b/components/arc/common/cast_receiver.mojom
@@ -0,0 +1,29 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Next MinVersion: 1 +module arc.mojom; + +// Next Method ID: 3 +interface CastReceiverInstance { + [Extensible] + enum Result { + SUCCESS = 0, + FAILURE = 1, + UNKNOWN = 2, // E.g. the operation was interrupted. + CAST_NOT_FOUND = 3, // Retrying won't help. + CAST_UNAVAILABLE = 4, // Could be disconnected or claimed. + }; + + // Gets the receiver name. + GetName@3() => (Result result, string name); + + // Sets whether the receiver is enabled or not. Enabling the receiver will + // start it if needed. + SetEnabled@1(bool enabled) => (Result result); + + // Sets the receiver name. If the name is blank, the receiver name will be + // set to the device name. + SetName@2(string name) => (Result result); +};
diff --git a/components/autofill/android/autofill_provider_android.cc b/components/autofill/android/autofill_provider_android.cc index 9066091..c2d1fb3f 100644 --- a/components/autofill/android/autofill_provider_android.cc +++ b/components/autofill/android/autofill_provider_android.cc
@@ -133,6 +133,7 @@ if (obj.is_null()) return false; Java_AutofillProvider_onWillSubmitForm(env, obj); + Reset(); return true; } @@ -198,8 +199,7 @@ DCHECK_CURRENTLY_ON(BrowserThread::UI); if (handler == handler_.get()) { handler_.reset(); - form_.reset(nullptr); - id_ = kNoQueryId; + Reset(); JNIEnv* env = AttachCurrentThread(); ScopedJavaLocalRef<jobject> obj = java_ref_.get(env); @@ -228,6 +228,11 @@ return bounding_box + client_area.OffsetFromOrigin(); } +void AutofillProviderAndroid::Reset() { + form_.reset(nullptr); + id_ = kNoQueryId; +} + bool RegisterAutofillProvider(JNIEnv* env) { return RegisterNativesImpl(env); }
diff --git a/components/autofill/android/autofill_provider_android.h b/components/autofill/android/autofill_provider_android.h index f71e5c22..f1af8ff7 100644 --- a/components/autofill/android/autofill_provider_android.h +++ b/components/autofill/android/autofill_provider_android.h
@@ -63,6 +63,8 @@ gfx::RectF ToClientAreaBound(const gfx::RectF& bounding_box); + void Reset(); + int32_t id_; std::unique_ptr<FormDataAndroid> form_; base::WeakPtr<AutofillHandlerProxy> handler_;
diff --git a/components/autofill/core/browser/autofill_experiments.cc b/components/autofill/core/browser/autofill_experiments.cc index c87a8b8..9919cd0 100644 --- a/components/autofill/core/browser/autofill_experiments.cc +++ b/components/autofill/core/browser/autofill_experiments.cc
@@ -45,6 +45,8 @@ "AutofillSuppressDisusedAddresses", base::FEATURE_DISABLED_BY_DEFAULT}; const base::Feature kAutofillUpstreamRequestCvcIfMissing{ "AutofillUpstreamRequestCvcIfMissing", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kAutofillUpstreamShowGoogleLogo{ + "AutofillUpstreamShowGoogleLogo", base::FEATURE_DISABLED_BY_DEFAULT}; const base::Feature kAutofillUpstreamShowNewUi{ "AutofillUpstreamShowNewUi", base::FEATURE_DISABLED_BY_DEFAULT}; const base::Feature kAutofillUpstreamUseAutofillProfileComparator{ @@ -268,6 +270,14 @@ #endif } +bool IsAutofillUpstreamShowGoogleLogoExperimentEnabled() { +#if defined(OS_ANDROID) + return false; +#else + return base::FeatureList::IsEnabled(kAutofillUpstreamShowGoogleLogo); +#endif +} + bool IsAutofillUpstreamShowNewUiExperimentEnabled() { #if defined(OS_ANDROID) return false;
diff --git a/components/autofill/core/browser/autofill_experiments.h b/components/autofill/core/browser/autofill_experiments.h index 41d1f47..6fcc5168 100644 --- a/components/autofill/core/browser/autofill_experiments.h +++ b/components/autofill/core/browser/autofill_experiments.h
@@ -35,6 +35,7 @@ extern const base::Feature kAutofillRationalizeFieldTypePredictions; extern const base::Feature kAutofillSuppressDisusedAddresses; extern const base::Feature kAutofillUpstreamRequestCvcIfMissing; +extern const base::Feature kAutofillUpstreamShowGoogleLogo; extern const base::Feature kAutofillUpstreamShowNewUi; extern const base::Feature kAutofillUpstreamUseAutofillProfileComparator; extern const base::Feature kAutofillUpstreamUseNotRecentlyUsedAutofillProfile; @@ -128,6 +129,10 @@ bool IsAutofillUpstreamRequestCvcIfMissingExperimentEnabled(); // Returns whether the experiment is enabled where Chrome Upstream displays a +// Google Logo in the save card bubble/infobar. +bool IsAutofillUpstreamShowGoogleLogoExperimentEnabled(); + +// Returns whether the experiment is enabled where Chrome Upstream displays a // new save card bubble/infobar design. bool IsAutofillUpstreamShowNewUiExperimentEnabled();
diff --git a/components/autofill_strings.grdp b/components/autofill_strings.grdp index 2ebefff..646a277 100644 --- a/components/autofill_strings.grdp +++ b/components/autofill_strings.grdp
@@ -220,7 +220,7 @@ </else> </if> <message name="IDS_AUTOFILL_SAVE_CARD_PROMPT_TITLE_TO_CLOUD_V2" desc="Title text for the Autofill save card prompt when the card is to be saved by uploading it to Google Payments, according to June 2017 UI guidelines. The prompt can be either a bubble or an infobar."> - Save this card for faster checkout? + Save card to Google? </message> <message name="IDS_AUTOFILL_SAVE_CARD_PROMPT_UPLOAD_EXPLANATION" desc="Explanation of the effect of the Autofill save card prompt when the card is to be saved by uploading it to Google Payments and also saved locally. The prompt can be either a bubble or an infobar."> Pay quickly on sites and apps across devices using cards you have saved with Google. @@ -228,12 +228,12 @@ <if expr="is_linux and not is_chromeos"> <then> <message name="IDS_AUTOFILL_SAVE_CARD_PROMPT_UPLOAD_EXPLANATION_V2" desc="Explanation of the effect of the Autofill save card prompt when the card is to be saved by uploading it to Google Payments, according to June 2017 UI guidelines. The prompt will be shown in a bubble below the omnibox."> - Your card will be saved in your Google Account + To pay faster next time, save this info to your Google Account </message> </then> <else> <message name="IDS_AUTOFILL_SAVE_CARD_PROMPT_UPLOAD_EXPLANATION_V2" desc="Explanation of the effect of the Autofill save card prompt when the card is to be saved by uploading it to Google Payments and also saved locally, according to June 2017 UI guidelines. The prompt can be either a bubble or an infobar."> - Your card will be saved in your Google Account and on this device + To pay faster next time, save this info to your Google Account and on this device </message> </else> </if>
diff --git a/components/content_settings/core/browser/BUILD.gn b/components/content_settings/core/browser/BUILD.gn index 44e44e3..97df967f 100644 --- a/components/content_settings/core/browser/BUILD.gn +++ b/components/content_settings/core/browser/BUILD.gn
@@ -39,6 +39,7 @@ "cookie_settings.h", "host_content_settings_map.cc", "host_content_settings_map.h", + "user_modifiable_provider.h", "website_settings_info.cc", "website_settings_info.h", "website_settings_registry.cc",
diff --git a/components/content_settings/core/browser/content_settings_pref_provider.h b/components/content_settings/core/browser/content_settings_pref_provider.h index 124ac9b..0518cc7cbe 100644 --- a/components/content_settings/core/browser/content_settings_pref_provider.h +++ b/components/content_settings/core/browser/content_settings_pref_provider.h
@@ -12,8 +12,8 @@ #include <vector> #include "base/macros.h" -#include "components/content_settings/core/browser/content_settings_observable_provider.h" #include "components/content_settings/core/browser/content_settings_utils.h" +#include "components/content_settings/core/browser/user_modifiable_provider.h" #include "components/prefs/pref_change_registrar.h" class PrefService; @@ -32,35 +32,30 @@ // Content settings provider that provides content settings from the user // preference. -class PrefProvider : public ObservableProvider { +class PrefProvider : public UserModifiableProvider { public: static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry); PrefProvider(PrefService* prefs, bool incognito, bool store_last_modified); ~PrefProvider() override; - // ProviderInterface implementations. + // UserModifiableProvider implementations. std::unique_ptr<RuleIterator> GetRuleIterator( ContentSettingsType content_type, const ResourceIdentifier& resource_identifier, bool incognito) const override; - bool SetWebsiteSetting(const ContentSettingsPattern& primary_pattern, const ContentSettingsPattern& secondary_pattern, ContentSettingsType content_type, const ResourceIdentifier& resource_identifier, base::Value* value) override; - - // Returns the |last_modified| date of a setting. + void ClearAllContentSettingsRules(ContentSettingsType content_type) override; + void ShutdownOnUIThread() override; base::Time GetWebsiteSettingLastModified( const ContentSettingsPattern& primary_pattern, const ContentSettingsPattern& secondary_pattern, ContentSettingsType content_type, - const ResourceIdentifier& resource_identifier); - - void ClearAllContentSettingsRules(ContentSettingsType content_type) override; - - void ShutdownOnUIThread() override; + const ResourceIdentifier& resource_identifier) override; void ClearPrefs();
diff --git a/components/content_settings/core/browser/host_content_settings_map.cc b/components/content_settings/core/browser/host_content_settings_map.cc index 19483f29..82686b9 100644 --- a/components/content_settings/core/browser/host_content_settings_map.cc +++ b/components/content_settings/core/browser/host_content_settings_map.cc
@@ -6,6 +6,7 @@ #include <stddef.h> +#include <algorithm> #include <utility> #include "base/command_line.h" @@ -28,6 +29,7 @@ #include "components/content_settings/core/browser/content_settings_registry.h" #include "components/content_settings/core/browser/content_settings_rule.h" #include "components/content_settings/core/browser/content_settings_utils.h" +#include "components/content_settings/core/browser/user_modifiable_provider.h" #include "components/content_settings/core/browser/website_settings_registry.h" #include "components/content_settings/core/common/content_settings_pattern.h" #include "components/content_settings/core/common/content_settings_utils.h" @@ -202,6 +204,7 @@ pref_provider_ = new content_settings::PrefProvider(prefs_, is_incognito_, store_last_modified_); content_settings_providers_[PREF_PROVIDER] = base::WrapUnique(pref_provider_); + user_modifiable_providers_.push_back(pref_provider_); pref_provider_->AddObserver(this); // This ensures that content settings are cleared for the guest profile. This @@ -235,6 +238,13 @@ content_settings::PolicyProvider::RegisterProfilePrefs(registry); } +void HostContentSettingsMap::RegisterUserModifiableProvider( + ProviderType type, + std::unique_ptr<content_settings::UserModifiableProvider> provider) { + user_modifiable_providers_.push_back(provider.get()); + RegisterProvider(type, std::move(provider)); +} + void HostContentSettingsMap::RegisterProvider( ProviderType type, std::unique_ptr<content_settings::ObservableProvider> provider) { @@ -669,8 +679,13 @@ const ContentSettingsPattern& primary_pattern, const ContentSettingsPattern& secondary_pattern, ContentSettingsType content_type) const { - return pref_provider_->GetWebsiteSettingLastModified( - primary_pattern, secondary_pattern, content_type, std::string()); + base::Time most_recent_time; + for (auto* provider : user_modifiable_providers_) { + base::Time time = provider->GetWebsiteSettingLastModified( + primary_pattern, secondary_pattern, content_type, std::string()); + most_recent_time = std::max(time, most_recent_time); + } + return most_recent_time; } void HostContentSettingsMap::ClearSettingsForOneTypeWithPredicate( @@ -688,13 +703,15 @@ if (pattern_predicate.is_null() || pattern_predicate.Run(setting.primary_pattern, setting.secondary_pattern)) { - base::Time last_modified = pref_provider_->GetWebsiteSettingLastModified( - setting.primary_pattern, setting.secondary_pattern, content_type, - std::string()); - if (last_modified >= begin_time) { - pref_provider_->SetWebsiteSetting(setting.primary_pattern, - setting.secondary_pattern, - content_type, std::string(), nullptr); + for (auto* provider : user_modifiable_providers_) { + base::Time last_modified = provider->GetWebsiteSettingLastModified( + setting.primary_pattern, setting.secondary_pattern, content_type, + std::string()); + if (last_modified >= begin_time) { + provider->SetWebsiteSetting(setting.primary_pattern, + setting.secondary_pattern, content_type, + std::string(), nullptr); + } } } }
diff --git a/components/content_settings/core/browser/host_content_settings_map.h b/components/content_settings/core/browser/host_content_settings_map.h index b9f4bfb..74a5f4d 100644 --- a/components/content_settings/core/browser/host_content_settings_map.h +++ b/components/content_settings/core/browser/host_content_settings_map.h
@@ -20,6 +20,7 @@ #include "base/threading/thread_checker.h" #include "components/content_settings/core/browser/content_settings_observer.h" #include "components/content_settings/core/browser/content_settings_utils.h" +#include "components/content_settings/core/browser/user_modifiable_provider.h" #include "components/content_settings/core/common/content_settings.h" #include "components/content_settings/core/common/content_settings_pattern.h" #include "components/content_settings/core/common/content_settings_types.h" @@ -73,6 +74,16 @@ static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry); + // Adds a new provider for |type|. This should be used instead of + // |RegisterProvider|, not in addition. + // + // Providers added via this method will be queried when + // |GetSettingLastModifiedDate| is called and their settings may be cleared by + // |ClearSettingsForOneTypeWithPredicate| if they were recently modified. + void RegisterUserModifiableProvider( + ProviderType type, + std::unique_ptr<content_settings::UserModifiableProvider> provider); + // Adds a new provider for |type|. void RegisterProvider( ProviderType type, @@ -386,6 +397,12 @@ std::map<ProviderType, std::unique_ptr<content_settings::ProviderInterface>> content_settings_providers_; + // List of content settings providers containing settings which can be + // modified by the user. Members are owned by the + // |content_settings_providers_| map above. + std::vector<content_settings::UserModifiableProvider*> + user_modifiable_providers_; + // content_settings_providers_[PREF_PROVIDER] but specialized. content_settings::PrefProvider* pref_provider_ = nullptr;
diff --git a/components/content_settings/core/browser/user_modifiable_provider.h b/components/content_settings/core/browser/user_modifiable_provider.h new file mode 100644 index 0000000..900778d --- /dev/null +++ b/components/content_settings/core/browser/user_modifiable_provider.h
@@ -0,0 +1,30 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_CONTENT_SETTINGS_CORE_BROWSER_USER_MODIFIABLE_PROVIDER_H_ +#define COMPONENTS_CONTENT_SETTINGS_CORE_BROWSER_USER_MODIFIABLE_PROVIDER_H_ + +#include "components/content_settings/core/browser/content_settings_observable_provider.h" +#include "components/content_settings/core/common/content_settings.h" + +class ContentSettingsPattern; + +namespace content_settings { + +// Content settings provider that provides settings which may be modified by the +// user. +class UserModifiableProvider : public ObservableProvider { + public: + ~UserModifiableProvider() override {} + // Returns the timestamp that a particular setting was last modified. + virtual base::Time GetWebsiteSettingLastModified( + const ContentSettingsPattern& primary_pattern, + const ContentSettingsPattern& secondary_pattern, + ContentSettingsType content_type, + const ResourceIdentifier& resource_identifier) = 0; +}; + +} // namespace content_settings + +#endif // COMPONENTS_CONTENT_SETTINGS_CORE_BROWSER_USER_MODIFIABLE_PROVIDER_H_
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.cc index ca8d3b05..eb109450 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.cc
@@ -56,6 +56,8 @@ COMPRESSED_VIDEO_REQUESTED = 5, IDENTITY_TRANSFORM_REQUESTED = 6, IDENTITY_TRANSFORM_RECEIVED = 7, + COMPRESSED_VIDEO_RECEIVED = 8, + UNKNOWN_TRANSFORM_RECEIVED = 9, ACCEPT_TRANSFORM_EVENT_BOUNDARY }; @@ -206,6 +208,7 @@ case TRANSFORM_NONE: break; case TRANSFORM_PAGE_POLICIES_EMPTY_IMAGE: + case TRANSFORM_UNKNOWN: NOTREACHED(); break; } @@ -218,6 +221,9 @@ } switch (ParseResponseTransform(*response_headers)) { + case TRANSFORM_UNKNOWN: + RecordAcceptTransformEvent(UNKNOWN_TRANSFORM_RECEIVED); + break; case TRANSFORM_LITE_PAGE: RecordAcceptTransformEvent(LITE_PAGE_TRANSFORM_RECEIVED); break; @@ -230,11 +236,10 @@ case TRANSFORM_IDENTITY: RecordAcceptTransformEvent(IDENTITY_TRANSFORM_RECEIVED); break; - case TRANSFORM_NONE: - break; case TRANSFORM_COMPRESSED_VIDEO: - // Compressed video response would instead be a redirect to resource. - NOTREACHED(); + RecordAcceptTransformEvent(COMPRESSED_VIDEO_RECEIVED); + break; + case TRANSFORM_NONE: break; } }
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate_unittest.cc index 46b1d24..26c5c57 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate_unittest.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate_unittest.cc
@@ -24,6 +24,7 @@ #include "base/strings/safe_sprintf.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" +#include "base/strings/stringprintf.h" #include "base/test/histogram_tester.h" #include "base/test/mock_entropy_provider.h" #include "base/test/scoped_feature_list.h" @@ -2170,6 +2171,15 @@ Init(USE_INSECURE_PROXY, false); base::HistogramTester histogram_tester; + const char kResponseHeadersWithCPCTFormat[] = + "HTTP/1.1 200 OK\r\n" + "Chrome-Proxy-Content-Transform: %s\r\n" + "Date: Wed, 28 Nov 2007 09:40:09 GMT\r\n" + "Expires: Mon, 24 Nov 2014 12:45:26 GMT\r\n" + "Via: 1.1 Chrome-Compression-Proxy\r\n" + "x-original-content-length: 200\r\n" + "\r\n"; + // Verify lite page request. net::HttpRequestHeaders request_headers; request_headers.SetHeader("chrome-proxy-accept-transform", "lite-page"); @@ -2194,16 +2204,9 @@ 3 /* EMPTY_IMAGE_REQUESTED */, 1); // Verify lite page response. - std::string response_headers = - "HTTP/1.1 200 OK\r\n" - "Chrome-Proxy-Content-Transform: lite-page\r\n" - "Date: Wed, 28 Nov 2007 09:40:09 GMT\r\n" - "Expires: Mon, 24 Nov 2014 12:45:26 GMT\r\n" - "Via: 1.1 Chrome-Compression-Proxy\r\n" - "x-original-content-length: 200\r\n" - "\r\n"; - auto request = - FetchURLRequest(GURL(kTestURL), nullptr, response_headers, 140, 0); + auto request = FetchURLRequest( + GURL(kTestURL), nullptr, + base::StringPrintf(kResponseHeadersWithCPCTFormat, "lite-page"), 140, 0); EXPECT_TRUE(DataReductionProxyData::GetData(*request)->lite_page_received()); histogram_tester.ExpectTotalCount( "DataReductionProxy.Protocol.AcceptTransform", 3); @@ -2215,7 +2218,7 @@ "DataReductionProxy.LoFi.TransformationType", LITE_PAGE, 1); // Verify page policy response. - response_headers = + std::string response_headers = "HTTP/1.1 200 OK\r\n" "Chrome-Proxy: page-policies=empty-image\r\n" "Date: Wed, 28 Nov 2007 09:40:09 GMT\r\n" @@ -2232,21 +2235,50 @@ 2 /* EMPTY_IMAGE_POLICY_DIRECTIVE_RECEIVED */, 1); // Verify empty image response. - response_headers = - "HTTP/1.1 200 OK\r\n" - "Chrome-Proxy-Content-Transform: empty-image\r\n" - "Date: Wed, 28 Nov 2007 09:40:09 GMT\r\n" - "Expires: Mon, 24 Nov 2014 12:45:26 GMT\r\n" - "Via: 1.1 Chrome-Compression-Proxy\r\n" - "x-original-content-length: 200\r\n" - "\r\n"; - request = FetchURLRequest(GURL(kTestURL), nullptr, response_headers, 140, 0); + request = FetchURLRequest( + GURL(kTestURL), nullptr, + base::StringPrintf(kResponseHeadersWithCPCTFormat, "empty-image"), 140, + 0); EXPECT_TRUE(DataReductionProxyData::GetData(*request)->lofi_received()); histogram_tester.ExpectTotalCount( "DataReductionProxy.Protocol.AcceptTransform", 5); histogram_tester.ExpectBucketCount( "DataReductionProxy.Protocol.AcceptTransform", 4 /* EMPTY_IMAGE_TRANSFORM_RECEIVED */, 1); + + // Verify compressed-video request. + request_headers.SetHeader("chrome-proxy-accept-transform", + "compressed-video"); + FetchURLRequest(GURL(kTestURL), &request_headers, std::string(), 140, 0); + histogram_tester.ExpectTotalCount( + "DataReductionProxy.Protocol.AcceptTransform", 6); + histogram_tester.ExpectBucketCount( + "DataReductionProxy.Protocol.AcceptTransform", + 5 /* COMPRESSED_VIDEO_REQUESTED */, 1); + + // Verify compressed-video response. + request = FetchURLRequest( + GURL(kTestURL), nullptr, + base::StringPrintf(kResponseHeadersWithCPCTFormat, "compressed-video"), + 140, 0); + EXPECT_FALSE(DataReductionProxyData::GetData(*request)->lofi_received()); + histogram_tester.ExpectTotalCount( + "DataReductionProxy.Protocol.AcceptTransform", 7); + histogram_tester.ExpectBucketCount( + "DataReductionProxy.Protocol.AcceptTransform", + 8 /* COMPRESSED_VIDEO_RECEIVED */, 1); + + // Verify response with an unknown CPAT value. + request = FetchURLRequest(GURL(kTestURL), nullptr, + base::StringPrintf(kResponseHeadersWithCPCTFormat, + "this-is-a-fake-transform"), + 140, 0); + EXPECT_FALSE(DataReductionProxyData::GetData(*request)->lofi_received()); + histogram_tester.ExpectTotalCount( + "DataReductionProxy.Protocol.AcceptTransform", 8); + histogram_tester.ExpectBucketCount( + "DataReductionProxy.Protocol.AcceptTransform", + 9 /* UNKNOWN_TRANSFORM_RECEIVED */, 1); } } // namespace
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.cc b/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.cc index 09e70dc5..d49a263 100644 --- a/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.cc +++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.cc
@@ -220,9 +220,14 @@ } else if (base::LowerCaseEqualsASCII(accept_transform_value, kIdentityDirective)) { return TRANSFORM_IDENTITY; - } else { - return TRANSFORM_NONE; } + + // On faster networks, Chrome might add a directive followed by "if-heavy", so + // just return TRANSFORM_NONE in that case. DCHECK that Chrome hasn't added + // any other unrecognized request headers. + DCHECK(base::EndsWith(accept_transform_value, kIfHeavyQualifier, + base::CompareCase::INSENSITIVE_ASCII)); + return TRANSFORM_NONE; } TransformDirective ParseResponseTransform( @@ -236,6 +241,7 @@ &chrome_proxy_header_value)) { return ParsePagePolicyDirective(chrome_proxy_header_value); } + return TRANSFORM_NONE; } else if (base::LowerCaseEqualsASCII(content_transform_value, lite_page_directive())) { return TRANSFORM_LITE_PAGE; @@ -245,11 +251,11 @@ } else if (base::LowerCaseEqualsASCII(content_transform_value, kIdentityDirective)) { return TRANSFORM_IDENTITY; - } else { - NOTREACHED() << "Unexpected content transform header: " - << content_transform_value; + } else if (base::LowerCaseEqualsASCII(content_transform_value, + compressed_video_directive())) { + return TRANSFORM_COMPRESSED_VIDEO; } - return TRANSFORM_NONE; + return TRANSFORM_UNKNOWN; } bool IsEmptyImagePreview(const net::HttpResponseHeaders& headers) {
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h b/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h index df3a976..2b1c2cf 100644 --- a/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h +++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h
@@ -25,6 +25,7 @@ // Transform directives that may be parsed out of http headers. enum TransformDirective { + TRANSFORM_UNKNOWN, TRANSFORM_NONE, TRANSFORM_LITE_PAGE, TRANSFORM_EMPTY_IMAGE,
diff --git a/components/discardable_memory/common/discardable_shared_memory_heap.cc b/components/discardable_memory/common/discardable_shared_memory_heap.cc index 58f4182..81b1665 100644 --- a/components/discardable_memory/common/discardable_shared_memory_heap.cc +++ b/components/discardable_memory/common/discardable_shared_memory_heap.cc
@@ -416,18 +416,6 @@ base::trace_event::MemoryAllocatorDump::kUnitsBytes, locked_objects_size_in_bytes); - // Emit an ownership edge towards a global allocator dump node. This allows - // to avoid double-counting segments when both browser and client process emit - // them. In the special case of single-process-mode, this will be the only - // dumper active and the single ownership edge will become a no-op in the UI. - // The global dump is created as a weak dump so that the segment is removed if - // the browser does not dump it (segment was purged). - const uint64_t tracing_process_id = - base::trace_event::MemoryDumpManager::GetInstance() - ->GetTracingProcessId(); - base::trace_event::MemoryAllocatorDumpGuid shared_segment_guid = - GetSegmentGUIDForTracing(tracing_process_id, segment_id); - // By creating an edge with a higher |importance| (w.r.t. browser-side dumps) // the tracing UI will account the effective size of the segment to the // client. @@ -435,19 +423,9 @@ auto shared_memory_guid = shared_memory->mapped_id(); segment_dump->AddString("id", "hash", shared_memory_guid.ToString()); pmd->CreateWeakSharedMemoryOwnershipEdge(segment_dump->guid(), - shared_segment_guid, shared_memory_guid, kImportance); } -// static -base::trace_event::MemoryAllocatorDumpGuid -DiscardableSharedMemoryHeap::GetSegmentGUIDForTracing( - uint64_t tracing_process_id, - int32_t segment_id) { - return base::trace_event::MemoryAllocatorDumpGuid(base::StringPrintf( - "discardable-x-process/%" PRIx64 "/%d", tracing_process_id, segment_id)); -} - base::trace_event::MemoryAllocatorDump* DiscardableSharedMemoryHeap::CreateMemoryAllocatorDump( Span* span,
diff --git a/components/discardable_memory/common/discardable_shared_memory_heap.h b/components/discardable_memory/common/discardable_shared_memory_heap.h index 2d68e253..8c9ff8d 100644 --- a/components/discardable_memory/common/discardable_shared_memory_heap.h +++ b/components/discardable_memory/common/discardable_shared_memory_heap.h
@@ -96,12 +96,6 @@ // Dumps memory statistics for chrome://tracing. bool OnMemoryDump(base::trace_event::ProcessMemoryDump* pmd); - // Returns a unique identifier for a given tuple of (process id, segment id) - // that can be used to match memory dumps across different processes. - static base::trace_event::MemoryAllocatorDumpGuid GetSegmentGUIDForTracing( - uint64_t tracing_process_id, - int32_t segment_id); - // Returns a MemoryAllocatorDump for a given span on |pmd| with the size of // the span. base::trace_event::MemoryAllocatorDump* CreateMemoryAllocatorDump(
diff --git a/components/discardable_memory/service/discardable_shared_memory_manager.cc b/components/discardable_memory/service/discardable_shared_memory_manager.cc index 282e28d..bb26341 100644 --- a/components/discardable_memory/service/discardable_shared_memory_manager.cc +++ b/components/discardable_memory/service/discardable_shared_memory_manager.cc
@@ -40,24 +40,8 @@ namespace discardable_memory { namespace { -const char kSingleProcess[] = "single-process"; - const int kInvalidUniqueClientID = -1; -const uint64_t kBrowserTracingProcessId = std::numeric_limits<uint64_t>::max(); - -uint64_t ClientProcessUniqueIdToTracingProcessId(int client_id) { - // TODO(penghuang): Move this function to right place. - // https://crbug.com/661257 - if (base::CommandLine::ForCurrentProcess()->HasSwitch(kSingleProcess)) - return kBrowserTracingProcessId; - // The hash value is incremented so that the tracing id is never equal to - // MemoryDumpManager::kInvalidTracingProcessId. - return static_cast<uint64_t>(base::Hash( - reinterpret_cast<const char*>(&client_id), sizeof(client_id))) + - 1; -} - // mojom::DiscardableSharedMemoryManager implementation. It contains the // |client_id_| which is not visible to client. We associate allocations with a // given mojo instance, so if the instance is closed, we can release the @@ -319,20 +303,9 @@ segment->memory()->IsMemoryLocked() ? segment->memory()->mapped_size() : 0u); - // Create the cross-process ownership edge. If the client creates a - // corresponding dump for the same segment, this will avoid to - // double-count them in tracing. If, instead, no other process will emit a - // dump with the same guid, the segment will be accounted to the browser. - const uint64_t client_tracing_id = - ClientProcessUniqueIdToTracingProcessId(client_id); - base::trace_event::MemoryAllocatorDumpGuid shared_segment_guid = - DiscardableSharedMemoryHeap::GetSegmentGUIDForTracing( - client_tracing_id, segment_id); - auto shared_memory_guid = segment->memory()->mapped_id(); dump->AddString("id", "hash", shared_memory_guid.ToString()); - pmd->CreateSharedMemoryOwnershipEdge(dump->guid(), shared_segment_guid, - shared_memory_guid, + pmd->CreateSharedMemoryOwnershipEdge(dump->guid(), shared_memory_guid, 0 /* importance */); } }
diff --git a/components/download/internal/download_service_impl.cc b/components/download/internal/download_service_impl.cc index ceff12d..c48b240 100644 --- a/components/download/internal/download_service_impl.cc +++ b/components/download/internal/download_service_impl.cc
@@ -74,7 +74,6 @@ void DownloadServiceImpl::StartDownload(const DownloadParams& download_params) { stats::LogServiceApiAction(download_params.client, stats::ServiceApiAction::START_DOWNLOAD); - DCHECK_EQ(download_params.guid, base::ToUpperASCII(download_params.guid)); stats::LogDownloadParams(download_params); if (startup_completed_) { controller_->StartDownload(download_params); @@ -88,8 +87,6 @@ void DownloadServiceImpl::PauseDownload(const std::string& guid) { stats::LogServiceApiAction(controller_->GetOwnerOfDownload(guid), stats::ServiceApiAction::PAUSE_DOWNLOAD); - DCHECK_EQ(guid, base::ToUpperASCII(guid)); - if (startup_completed_) { controller_->PauseDownload(guid); } else { @@ -101,8 +98,6 @@ void DownloadServiceImpl::ResumeDownload(const std::string& guid) { stats::LogServiceApiAction(controller_->GetOwnerOfDownload(guid), stats::ServiceApiAction::RESUME_DOWNLOAD); - DCHECK_EQ(guid, base::ToUpperASCII(guid)); - if (startup_completed_) { controller_->ResumeDownload(guid); } else { @@ -115,8 +110,6 @@ void DownloadServiceImpl::CancelDownload(const std::string& guid) { stats::LogServiceApiAction(controller_->GetOwnerOfDownload(guid), stats::ServiceApiAction::CANCEL_DOWNLOAD); - DCHECK_EQ(guid, base::ToUpperASCII(guid)); - if (startup_completed_) { controller_->CancelDownload(guid); } else { @@ -131,8 +124,6 @@ const SchedulingParams& params) { stats::LogServiceApiAction(controller_->GetOwnerOfDownload(guid), stats::ServiceApiAction::CHANGE_CRITERIA); - DCHECK_EQ(guid, base::ToUpperASCII(guid)); - if (startup_completed_) { controller_->ChangeDownloadCriteria(guid, params); } else {
diff --git a/components/download/internal/download_service_impl_unittest.cc b/components/download/internal/download_service_impl_unittest.cc index 74090dfb..ed6e9b66 100644 --- a/components/download/internal/download_service_impl_unittest.cc +++ b/components/download/internal/download_service_impl_unittest.cc
@@ -66,9 +66,6 @@ TEST_F(DownloadServiceImplTest, TestApiPassThrough) { DownloadParams params = test::BuildBasicDownloadParams(); - // TODO(xingliu): Remove the limitation of upper case guid in - // |download_params|, see http://crbug.com/734818. - params.guid = base::ToUpperASCII(params.guid); SchedulingParams scheduling_params; scheduling_params.priority = SchedulingParams::Priority::UI;
diff --git a/components/download/internal/test/BUILD.gn b/components/download/internal/test/BUILD.gn index 1ea6557..798f419 100644 --- a/components/download/internal/test/BUILD.gn +++ b/components/download/internal/test/BUILD.gn
@@ -3,7 +3,10 @@ # found in the LICENSE file. source_set("test_support") { - visibility = [ "//components/download/internal:unit_tests" ] + visibility = [ + "//components/download/internal:unit_tests", + "//components/offline_pages/core/prefetch:unit_tests", + ] testonly = true
diff --git a/components/download/internal/test/test_download_service.cc b/components/download/internal/test/test_download_service.cc index 7471e4f3..1f06039d 100644 --- a/components/download/internal/test/test_download_service.cc +++ b/components/download/internal/test/test_download_service.cc
@@ -59,39 +59,7 @@ : DownloadService::ServiceStatus::STARTING_UP; } -void TestDownloadService::StartDownload(const DownloadParams& download_params) { - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(&TestDownloadService::HandleStartDownload, - base::Unretained(this), download_params)); -} - -void TestDownloadService::PauseDownload(const std::string& guid) {} - -void TestDownloadService::ResumeDownload(const std::string& guid) {} - -void TestDownloadService::CancelDownload(const std::string& guid) { - for (auto iter = downloads_.begin(); iter != downloads_.end(); ++iter) { - if (iter->guid == guid) { - downloads_.erase(iter); - iter->callback.Run(iter->guid, - DownloadParams::StartResult::UNEXPECTED_GUID); - return; - } - } -} - -void TestDownloadService::ChangeDownloadCriteria( - const std::string& guid, - const SchedulingParams& params) {} - -void TestDownloadService::SetFailedDownload( - const std::string& failed_download_id, - bool fail_at_start) { - failed_download_id_ = failed_download_id; - fail_at_start_ = fail_at_start; -} - -void TestDownloadService::HandleStartDownload(const DownloadParams& params) { +void TestDownloadService::StartDownload(const DownloadParams& params) { if (!is_ready_) { params.callback.Run(params.guid, DownloadParams::StartResult::INTERNAL_ERROR); @@ -112,6 +80,39 @@ base::Unretained(this))); } +void TestDownloadService::PauseDownload(const std::string& guid) {} + +void TestDownloadService::ResumeDownload(const std::string& guid) {} + +void TestDownloadService::CancelDownload(const std::string& guid) { + for (auto iter = downloads_.begin(); iter != downloads_.end(); ++iter) { + if (iter->guid == guid) { + downloads_.erase(iter); + return; + } + } +} + +void TestDownloadService::ChangeDownloadCriteria( + const std::string& guid, + const SchedulingParams& params) {} + +base::Optional<DownloadParams> TestDownloadService::GetDownload( + const std::string& guid) const { + for (const auto& download : downloads_) { + if (download.guid == guid) + return base::Optional<DownloadParams>(download); + } + return base::Optional<DownloadParams>(); +} + +void TestDownloadService::SetFailedDownload( + const std::string& failed_download_id, + bool fail_at_start) { + failed_download_id_ = failed_download_id; + fail_at_start_ = fail_at_start; +} + void TestDownloadService::ProcessDownload() { DCHECK(!fail_at_start_); if (!is_ready_ || downloads_.empty())
diff --git a/components/download/internal/test/test_download_service.h b/components/download/internal/test/test_download_service.h index 361d55d..2ae644b 100644 --- a/components/download/internal/test/test_download_service.h +++ b/components/download/internal/test/test_download_service.h
@@ -7,6 +7,7 @@ #include <list> +#include "base/optional.h" #include "components/download/public/client.h" #include "components/download/public/download_params.h" #include "components/download/public/download_service.h" @@ -33,18 +34,17 @@ void ChangeDownloadCriteria(const std::string& guid, const SchedulingParams& params) override; + base::Optional<DownloadParams> GetDownload(const std::string& guid) const; + + // Set failed_download_id and fail_at_start. + void SetFailedDownload(const std::string& failed_download_id, + bool fail_at_start); + void set_is_ready(bool is_ready) { is_ready_ = is_ready; } void set_client(Client* client) { client_ = client; } private: - // Set failed_download_id and fail_at_start. - void SetFailedDownload(const std::string& failed_download_id, - bool fail_at_start); - - // Raise success/failure events based on the starting of the download. - void HandleStartDownload(const DownloadParams& params); - // Begin the download, raising success/failure events. void ProcessDownload();
diff --git a/components/download/public/download_params.h b/components/download/public/download_params.h index a42ea03..c6f7488 100644 --- a/components/download/public/download_params.h +++ b/components/download/public/download_params.h
@@ -144,8 +144,6 @@ DownloadClient client; // A unique GUID that represents this download. See |base::GenerateGUID()|. - // TODO(xingliu): guid in content download must be upper case, see - // http://crbug.com/734818. std::string guid; // A callback that will be notified if this download has been accepted and
diff --git a/components/download/public/download_service.h b/components/download/public/download_service.h index fdf8ac5..8954b75f 100644 --- a/components/download/public/download_service.h +++ b/components/download/public/download_service.h
@@ -76,8 +76,6 @@ // Sends the download to the service. A callback to // |DownloadParams::callback| will be triggered once the download has been // persisted and saved in the service. - // TODO(xingliu): Remove the limitation of upper case guid in - // |download_params|, see http://crbug.com/734818. virtual void StartDownload(const DownloadParams& download_params) = 0; // Allows any feature to pause or resume downloads at will. Paused downloads
diff --git a/components/drive/chromeos/dummy_file_system.h b/components/drive/chromeos/dummy_file_system.h index 36ab6487..6a35125 100644 --- a/components/drive/chromeos/dummy_file_system.h +++ b/components/drive/chromeos/dummy_file_system.h
@@ -76,6 +76,7 @@ void SearchMetadata(const std::string& query, int options, int at_most_num_matches, + MetadataSearchOrder order, const SearchMetadataCallback& callback) override {} void SearchByHashes(const std::set<std::string>& hashes, const SearchByHashesCallback& callback) override {}
diff --git a/components/drive/chromeos/fake_file_system.cc b/components/drive/chromeos/fake_file_system.cc index 69b7a28..a5bba4a 100644 --- a/components/drive/chromeos/fake_file_system.cc +++ b/components/drive/chromeos/fake_file_system.cc
@@ -183,11 +183,11 @@ DCHECK_CURRENTLY_ON(BrowserThread::UI); } -void FakeFileSystem::SearchMetadata( - const std::string& query, - int options, - int at_most_num_matches, - const SearchMetadataCallback& callback) { +void FakeFileSystem::SearchMetadata(const std::string& query, + int options, + int at_most_num_matches, + MetadataSearchOrder order, + const SearchMetadataCallback& callback) { DCHECK_CURRENTLY_ON(BrowserThread::UI); }
diff --git a/components/drive/chromeos/fake_file_system.h b/components/drive/chromeos/fake_file_system.h index 337dd1f8..e892bd9a 100644 --- a/components/drive/chromeos/fake_file_system.h +++ b/components/drive/chromeos/fake_file_system.h
@@ -104,6 +104,7 @@ void SearchMetadata(const std::string& query, int options, int at_most_num_matches, + MetadataSearchOrder order, const SearchMetadataCallback& callback) override; void SearchByHashes(const std::set<std::string>& hashes, const SearchByHashesCallback& callback) override;
diff --git a/components/drive/chromeos/file_system.cc b/components/drive/chromeos/file_system.cc index 5d6d756..b086def 100644 --- a/components/drive/chromeos/file_system.cc +++ b/components/drive/chromeos/file_system.cc
@@ -797,6 +797,7 @@ void FileSystem::SearchMetadata(const std::string& query, int options, int at_most_num_matches, + MetadataSearchOrder order, const SearchMetadataCallback& callback) { DCHECK(thread_checker_.CalledOnValidThread()); @@ -807,7 +808,7 @@ drive::internal::SearchMetadata( blocking_task_runner_, resource_metadata_, query, base::Bind(&drive::internal::MatchesType, options), at_most_num_matches, - callback); + order, callback); } void FileSystem::SearchByHashes(const std::set<std::string>& hashes, @@ -817,6 +818,7 @@ blocking_task_runner_, resource_metadata_, /* any file name */ "", base::Bind(&CheckHashes, hashes), std::numeric_limits<size_t>::max(), + drive::MetadataSearchOrder::LAST_ACCESSED, base::Bind(&RunSearchByHashesCallback, callback)); }
diff --git a/components/drive/chromeos/file_system.h b/components/drive/chromeos/file_system.h index 8cd78612..7a87830 100644 --- a/components/drive/chromeos/file_system.h +++ b/components/drive/chromeos/file_system.h
@@ -87,6 +87,7 @@ void SearchMetadata(const std::string& query, int options, int at_most_num_matches, + MetadataSearchOrder order, const SearchMetadataCallback& callback) override; void SearchByHashes(const std::set<std::string>& hashes, const SearchByHashesCallback& callback) override;
diff --git a/components/drive/chromeos/file_system_interface.h b/components/drive/chromeos/file_system_interface.h index ee2b113d..043d5c0 100644 --- a/components/drive/chromeos/file_system_interface.h +++ b/components/drive/chromeos/file_system_interface.h
@@ -38,6 +38,15 @@ base::FilePath path; }; +// Specifies the order in which SearchMetadata() results are sorted. +enum class MetadataSearchOrder { + // Most recently accessed file comes first. + LAST_ACCESSED = 0, + + // Most recently modified file comes first. + LAST_MODIFIED = 1, +}; + // Struct to represent a search result for SearchMetadata(). struct MetadataSearchResult { MetadataSearchResult(const base::FilePath& path, @@ -401,6 +410,7 @@ virtual void SearchMetadata(const std::string& query, int options, int at_most_num_matches, + MetadataSearchOrder order, const SearchMetadataCallback& callback) = 0; // Searches the local resource metadata, and returns the entries that have the
diff --git a/components/drive/chromeos/search_metadata.cc b/components/drive/chromeos/search_metadata.cc index 566d1d9..7dfe3e3 100644 --- a/components/drive/chromeos/search_metadata.cc +++ b/components/drive/chromeos/search_metadata.cc
@@ -42,24 +42,37 @@ // Used to sort the result candidates per the last accessed/modified time. The // recently accessed/modified files come first. -bool CompareByTimestamp(const ResourceEntry& a, const ResourceEntry& b) { +bool CompareByTimestamp(const ResourceEntry& a, + const ResourceEntry& b, + MetadataSearchOrder order) { const PlatformFileInfoProto& a_file_info = a.file_info(); const PlatformFileInfoProto& b_file_info = b.file_info(); - if (a_file_info.last_accessed() != b_file_info.last_accessed()) - return a_file_info.last_accessed() > b_file_info.last_accessed(); + switch (order) { + case MetadataSearchOrder::LAST_ACCESSED: + if (a_file_info.last_accessed() != b_file_info.last_accessed()) + return a_file_info.last_accessed() > b_file_info.last_accessed(); - // When the entries have the same last access time (which happens quite often - // because Drive server doesn't set the field until an entry is viewed via - // drive.google.com), we use last modified time as the tie breaker. - return a_file_info.last_modified() > b_file_info.last_modified(); + // When the entries have the same last access time (which happens quite + // often because Drive server doesn't set the field until an entry is + /// viewed via drive.google.com), we use last modified time as the tie + // breaker. + return a_file_info.last_modified() > b_file_info.last_modified(); + case MetadataSearchOrder::LAST_MODIFIED: + return a_file_info.last_modified() > b_file_info.last_modified(); + } } struct ResultCandidateComparator { + explicit ResultCandidateComparator(MetadataSearchOrder order) + : order_(order) {} bool operator()(const std::unique_ptr<ResultCandidate>& a, const std::unique_ptr<ResultCandidate>& b) const { - return CompareByTimestamp(a->entry, b->entry); + return CompareByTimestamp(a->entry, b->entry, order_); } + + private: + const MetadataSearchOrder order_; }; typedef std::priority_queue<std::unique_ptr<ResultCandidate>, @@ -127,6 +140,7 @@ base::i18n::FixedPatternStringSearchIgnoringCaseAndAccents>>& queries, const SearchMetadataPredicate& predicate, size_t at_most_num_matches, + MetadataSearchOrder order, HiddenEntryClassifier* hidden_entry_classifier, ResultCandidateQueue* result_candidates) { DCHECK_GE(at_most_num_matches, result_candidates->size()); @@ -137,7 +151,7 @@ // We perform this check first in order to avoid the costly find-and-highlight // or FilePath lookup as much as possible. if (result_candidates->size() == at_most_num_matches && - !CompareByTimestamp(entry, result_candidates->top()->entry)) + !CompareByTimestamp(entry, result_candidates->top()->entry, order)) return FILE_ERROR_OK; // Add |entry| to the result if the entry is eligible for the given @@ -167,8 +181,9 @@ const std::string& query_text, const SearchMetadataPredicate& predicate, int at_most_num_matches, + MetadataSearchOrder order, MetadataSearchResultVector* results) { - ResultCandidateQueue result_candidates; + ResultCandidateQueue result_candidates((ResultCandidateComparator(order))); // Prepare data structure for searching. std::vector<base::string16> keywords = @@ -201,7 +216,7 @@ for (; !it->IsAtEnd(); it->Advance()) { FileError error = MaybeAddEntryToResult( resource_metadata, it.get(), queries, predicate, at_most_num_matches, - &hidden_entry_classifier, &result_candidates); + order, &hidden_entry_classifier, &result_candidates); if (error != FILE_ERROR_OK) return error; } @@ -267,6 +282,7 @@ const std::string& query, const SearchMetadataPredicate& predicate, size_t at_most_num_matches, + MetadataSearchOrder order, const SearchMetadataCallback& callback) { DCHECK(!callback.is_null()); @@ -278,7 +294,7 @@ base::PostTaskAndReplyWithResult( blocking_task_runner.get(), FROM_HERE, base::Bind(&SearchMetadataOnBlockingPool, resource_metadata, query, - predicate, at_most_num_matches, results_ptr), + predicate, at_most_num_matches, order, results_ptr), base::Bind(&RunSearchMetadataCallback, callback, start_time, base::Passed(&results))); }
diff --git a/components/drive/chromeos/search_metadata.h b/components/drive/chromeos/search_metadata.h index 6e891621..a6a5d41 100644 --- a/components/drive/chromeos/search_metadata.h +++ b/components/drive/chromeos/search_metadata.h
@@ -41,6 +41,7 @@ const std::string& query, const SearchMetadataPredicate& predicate, size_t at_most_num_matches, + MetadataSearchOrder order, const SearchMetadataCallback& callback); // Returns true if |entry| is eligible for the search |options| and should be
diff --git a/components/drive/search_metadata_unittest.cc b/components/drive/search_metadata_unittest.cc index 438199866..85a0a36 100644 --- a/components/drive/search_metadata_unittest.cc +++ b/components/drive/search_metadata_unittest.cc
@@ -92,45 +92,56 @@ // drive/root/Directory-1 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry( - GetDirectoryEntry("Directory-1", "dir1", 1, root_local_id), + GetDirectoryEntry("Directory-1", "dir1", 1, 1, root_local_id), &local_id)); const std::string dir1_local_id = local_id; // drive/root/Directory-1/SubDirectory File 1.txt - EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(GetFileEntry( - "SubDirectory File 1.txt", "file1a", 2, dir1_local_id), &local_id)); + EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry( + GetFileEntry("SubDirectory File 1.txt", + "file1a", 2, 99, dir1_local_id), + &local_id)); EXPECT_EQ(FILE_ERROR_OK, cache_->Store( local_id, temp_file_md5, temp_file, FileCache::FILE_OPERATION_COPY)); // drive/root/Directory-1/Shared To The Account Owner.txt - entry = GetFileEntry( - "Shared To The Account Owner.txt", "file1b", 3, dir1_local_id); + entry = GetFileEntry("Shared To The Account Owner.txt", "file1b", 3, 3, + dir1_local_id); entry.set_shared_with_me(true); EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(entry, &local_id)); // drive/root/Directory 2 excludeDir-test - EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(GetDirectoryEntry( - "Directory 2 excludeDir-test", "dir2", 4, root_local_id), &local_id)); + EXPECT_EQ(FILE_ERROR_OK, + resource_metadata_->AddEntry( + GetDirectoryEntry("Directory 2 excludeDir-test", "dir2", 4, 4, + root_local_id), + &local_id)); // drive/root/Slash \xE2\x88\x95 in directory - EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry( - GetDirectoryEntry("Slash \xE2\x88\x95 in directory", "dir3", 5, - root_local_id), &local_id)); + EXPECT_EQ(FILE_ERROR_OK, + resource_metadata_->AddEntry( + GetDirectoryEntry("Slash \xE2\x88\x95 in directory", "dir3", + 5, 5, root_local_id), + &local_id)); const std::string dir3_local_id = local_id; // drive/root/Slash \xE2\x88\x95 in directory/Slash SubDir File.txt - EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(GetFileEntry( - "Slash SubDir File.txt", "file3a", 6, dir3_local_id), &local_id)); + EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry( + GetFileEntry("Slash SubDir File.txt", "file3a", + 6, 6, dir3_local_id), + &local_id)); // drive/root/File 2.txt - EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(GetFileEntry( - "File 2.txt", "file2", 7, root_local_id), &local_id)); + EXPECT_EQ(FILE_ERROR_OK, + resource_metadata_->AddEntry( + GetFileEntry("File 2.txt", "file2", 7, 7, root_local_id), + &local_id)); EXPECT_EQ(FILE_ERROR_OK, cache_->Store( local_id, temp_file_md5, temp_file, FileCache::FILE_OPERATION_COPY)); // drive/root/Document 1 excludeDir-test - entry = GetFileEntry( - "Document 1 excludeDir-test", "doc1", 8, root_local_id); + entry = + GetFileEntry("Document 1 excludeDir-test", "doc1", 8, 8, root_local_id); entry.mutable_file_specific_info()->set_is_hosted_document(true); entry.mutable_file_specific_info()->set_document_extension(".gdoc"); entry.mutable_file_specific_info()->set_content_mime_type( @@ -141,24 +152,28 @@ ResourceEntry GetFileEntry(const std::string& name, const std::string& resource_id, int64_t last_accessed, + int64_t last_modified, const std::string& parent_local_id) { ResourceEntry entry; entry.set_title(name); entry.set_resource_id(resource_id); entry.set_parent_local_id(parent_local_id); entry.mutable_file_info()->set_last_accessed(last_accessed); + entry.mutable_file_info()->set_last_modified(last_modified); return entry; } ResourceEntry GetDirectoryEntry(const std::string& name, const std::string& resource_id, int64_t last_accessed, + int64_t last_modified, const std::string& parent_local_id) { ResourceEntry entry; entry.set_title(name); entry.set_resource_id(resource_id); entry.set_parent_local_id(parent_local_id); entry.mutable_file_info()->set_last_accessed(last_accessed); + entry.mutable_file_info()->set_last_modified(last_modified); entry.mutable_file_info()->set_is_directory(true); return entry; } @@ -180,7 +195,7 @@ SearchMetadata( base::ThreadTaskRunnerHandle::Get(), resource_metadata_.get(), "NonExistent", base::Bind(&MatchesType, SEARCH_METADATA_ALL), - kDefaultAtMostNumMatches, + kDefaultAtMostNumMatches, MetadataSearchOrder::LAST_ACCESSED, google_apis::test_util::CreateCopyResultCallback(&error, &result)); base::RunLoop().RunUntilIdle(); EXPECT_EQ(FILE_ERROR_OK, error); @@ -195,7 +210,7 @@ SearchMetadata( base::ThreadTaskRunnerHandle::Get(), resource_metadata_.get(), "SubDirectory File 1.txt", base::Bind(&MatchesType, SEARCH_METADATA_ALL), - kDefaultAtMostNumMatches, + kDefaultAtMostNumMatches, MetadataSearchOrder::LAST_ACCESSED, google_apis::test_util::CreateCopyResultCallback(&error, &result)); base::RunLoop().RunUntilIdle(); EXPECT_EQ(FILE_ERROR_OK, error); @@ -215,7 +230,7 @@ SearchMetadata( base::ThreadTaskRunnerHandle::Get(), resource_metadata_.get(), "subdirectory file 1.txt", base::Bind(&MatchesType, SEARCH_METADATA_ALL), - kDefaultAtMostNumMatches, + kDefaultAtMostNumMatches, MetadataSearchOrder::LAST_ACCESSED, google_apis::test_util::CreateCopyResultCallback(&error, &result)); base::RunLoop().RunUntilIdle(); EXPECT_EQ(FILE_ERROR_OK, error); @@ -232,6 +247,7 @@ SearchMetadata( base::ThreadTaskRunnerHandle::Get(), resource_metadata_.get(), "SubDir", base::Bind(&MatchesType, SEARCH_METADATA_ALL), kDefaultAtMostNumMatches, + MetadataSearchOrder::LAST_ACCESSED, google_apis::test_util::CreateCopyResultCallback(&error, &result)); base::RunLoop().RunUntilIdle(); EXPECT_EQ(FILE_ERROR_OK, error); @@ -246,16 +262,17 @@ result->at(1).path.AsUTF8Unsafe()); } -TEST_F(SearchMetadataTest, SearchMetadata_AtMostOneFile) { +TEST_F(SearchMetadataTest, SearchMetadata_AtMostOneFile_LastAccessed) { FileError error = FILE_ERROR_FAILED; std::unique_ptr<MetadataSearchResultVector> result; // There are two files matching "SubDir" but only one file should be - // returned. + // returned. Results are ordered by last accessed time. SearchMetadata( base::ThreadTaskRunnerHandle::Get(), resource_metadata_.get(), "SubDir", base::Bind(&MatchesType, SEARCH_METADATA_ALL), 1, // at_most_num_matches + MetadataSearchOrder::LAST_ACCESSED, google_apis::test_util::CreateCopyResultCallback(&error, &result)); base::RunLoop().RunUntilIdle(); EXPECT_EQ(FILE_ERROR_OK, error); @@ -265,6 +282,26 @@ result->at(0).path.AsUTF8Unsafe()); } +TEST_F(SearchMetadataTest, SearchMetadata_AtMostOneFile_LastModified) { + FileError error = FILE_ERROR_FAILED; + std::unique_ptr<MetadataSearchResultVector> result; + + // There are two files matching "SubDir" but only one file should be + // returned. Results are ordered by last modified time. + SearchMetadata( + base::ThreadTaskRunnerHandle::Get(), resource_metadata_.get(), "SubDir", + base::Bind(&MatchesType, SEARCH_METADATA_ALL), + 1, // at_most_num_matches + MetadataSearchOrder::LAST_MODIFIED, + google_apis::test_util::CreateCopyResultCallback(&error, &result)); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(FILE_ERROR_OK, error); + ASSERT_TRUE(result); + ASSERT_EQ(1U, result->size()); + EXPECT_EQ("drive/root/Directory-1/SubDirectory File 1.txt", + result->at(0).path.AsUTF8Unsafe()); +} + TEST_F(SearchMetadataTest, SearchMetadata_Directory) { FileError error = FILE_ERROR_FAILED; std::unique_ptr<MetadataSearchResultVector> result; @@ -272,7 +309,7 @@ SearchMetadata( base::ThreadTaskRunnerHandle::Get(), resource_metadata_.get(), "Directory-1", base::Bind(&MatchesType, SEARCH_METADATA_ALL), - kDefaultAtMostNumMatches, + kDefaultAtMostNumMatches, MetadataSearchOrder::LAST_ACCESSED, google_apis::test_util::CreateCopyResultCallback(&error, &result)); base::RunLoop().RunUntilIdle(); EXPECT_EQ(FILE_ERROR_OK, error); @@ -288,6 +325,7 @@ SearchMetadata( base::ThreadTaskRunnerHandle::Get(), resource_metadata_.get(), "Document", base::Bind(&MatchesType, SEARCH_METADATA_ALL), kDefaultAtMostNumMatches, + MetadataSearchOrder::LAST_ACCESSED, google_apis::test_util::CreateCopyResultCallback(&error, &result)); base::RunLoop().RunUntilIdle(); EXPECT_EQ(FILE_ERROR_OK, error); @@ -305,7 +343,7 @@ SearchMetadata( base::ThreadTaskRunnerHandle::Get(), resource_metadata_.get(), "Document", base::Bind(&MatchesType, SEARCH_METADATA_EXCLUDE_HOSTED_DOCUMENTS), - kDefaultAtMostNumMatches, + kDefaultAtMostNumMatches, MetadataSearchOrder::LAST_ACCESSED, google_apis::test_util::CreateCopyResultCallback(&error, &result)); base::RunLoop().RunUntilIdle(); EXPECT_EQ(FILE_ERROR_OK, error); @@ -320,7 +358,7 @@ SearchMetadata( base::ThreadTaskRunnerHandle::Get(), resource_metadata_.get(), "", base::Bind(&MatchesType, SEARCH_METADATA_SHARED_WITH_ME), - kDefaultAtMostNumMatches, + kDefaultAtMostNumMatches, MetadataSearchOrder::LAST_ACCESSED, google_apis::test_util::CreateCopyResultCallback(&error, &result)); base::RunLoop().RunUntilIdle(); EXPECT_EQ(FILE_ERROR_OK, error); @@ -337,7 +375,7 @@ SearchMetadata( base::ThreadTaskRunnerHandle::Get(), resource_metadata_.get(), "excludeDir-test", base::Bind(&MatchesType, SEARCH_METADATA_ALL), - kDefaultAtMostNumMatches, + kDefaultAtMostNumMatches, MetadataSearchOrder::LAST_ACCESSED, google_apis::test_util::CreateCopyResultCallback(&error, &result)); base::RunLoop().RunUntilIdle(); @@ -359,7 +397,7 @@ base::ThreadTaskRunnerHandle::Get(), resource_metadata_.get(), "excludeDir-test", base::Bind(&MatchesType, SEARCH_METADATA_EXCLUDE_DIRECTORIES), - kDefaultAtMostNumMatches, + kDefaultAtMostNumMatches, MetadataSearchOrder::LAST_ACCESSED, google_apis::test_util::CreateCopyResultCallback(&error, &result)); base::RunLoop().RunUntilIdle(); @@ -382,6 +420,7 @@ SearchMetadata( base::ThreadTaskRunnerHandle::Get(), resource_metadata_.get(), query, base::Bind(&MatchesType, SEARCH_METADATA_ALL), kDefaultAtMostNumMatches, + MetadataSearchOrder::LAST_ACCESSED, google_apis::test_util::CreateCopyResultCallback(&error, &result)); base::RunLoop().RunUntilIdle(); @@ -398,7 +437,7 @@ SearchMetadata( base::ThreadTaskRunnerHandle::Get(), resource_metadata_.get(), "", base::Bind(&MatchesType, SEARCH_METADATA_OFFLINE), - kDefaultAtMostNumMatches, + kDefaultAtMostNumMatches, MetadataSearchOrder::LAST_ACCESSED, google_apis::test_util::CreateCopyResultCallback(&error, &result)); base::RunLoop().RunUntilIdle(); EXPECT_EQ(FILE_ERROR_OK, error); @@ -421,7 +460,7 @@ SearchMetadata( base::ThreadTaskRunnerHandle::Get(), resource_metadata_.get(), "Directory 1", base::Bind(&MatchesType, SEARCH_METADATA_ALL), - kDefaultAtMostNumMatches, + kDefaultAtMostNumMatches, MetadataSearchOrder::LAST_ACCESSED, google_apis::test_util::CreateCopyResultCallback(&error, &result)); base::RunLoop().RunUntilIdle(); @@ -445,6 +484,7 @@ "Directory\xE3\x80\x80" "1", base::Bind(&MatchesType, SEARCH_METADATA_ALL), kDefaultAtMostNumMatches, + MetadataSearchOrder::LAST_ACCESSED, google_apis::test_util::CreateCopyResultCallback(&error, &result)); base::RunLoop().RunUntilIdle();
diff --git a/components/exo/keyboard.cc b/components/exo/keyboard.cc index 94fd72f..35b827ce 100644 --- a/components/exo/keyboard.cc +++ b/components/exo/keyboard.cc
@@ -330,16 +330,20 @@ // Check pending acks and process them as if it's not handled if // expiration time passed. base::TimeTicks current_time = base::TimeTicks::Now(); - auto it = pending_key_acks_.begin(); - while (it != pending_key_acks_.end()) { - const ui::KeyEvent& event = it->second.first; + + while (!pending_key_acks_.empty()) { + auto it = pending_key_acks_.begin(); + const ui::KeyEvent event = it->second.first; if (it->second.second > current_time) break; + pending_key_acks_.erase(it); + + // |pending_key_acks_| may change and an iterator of it become invalid when + // |ProcessAccelerator| is called. if (focus_) ProcessAccelerator(focus_, &event); - it = pending_key_acks_.erase(it); } if (pending_key_acks_.empty())
diff --git a/components/exo/keyboard_unittest.cc b/components/exo/keyboard_unittest.cc index 0b05bfc..8844188 100644 --- a/components/exo/keyboard_unittest.cc +++ b/components/exo/keyboard_unittest.cc
@@ -482,5 +482,70 @@ keyboard.reset(); } +// Test for crbug.com/753539. If action for an accelerator moves the focus to +// another window, it causes clearing the map of pending key acks in Keyboard. +// We can't assume that an iterator of the map is valid after processing an +// accelerator. +class TestShellSurfaceWithMovingFocusAccelerator : public ShellSurface { + public: + explicit TestShellSurfaceWithMovingFocusAccelerator(Surface* surface) + : ShellSurface(surface) {} + + bool AcceleratorPressed(const ui::Accelerator& accelerator) override { + aura::client::FocusClient* focus_client = + aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow()); + focus_client->FocusWindow(nullptr); + return true; + } +}; + +TEST_F(KeyboardTest, AckKeyboardKeyExpiredWithMovingFocusAccelerator) { + std::unique_ptr<Surface> surface(new Surface); + auto shell_surface = + base::MakeUnique<TestShellSurfaceWithMovingFocusAccelerator>( + surface.get()); + gfx::Size buffer_size(10, 10); + std::unique_ptr<Buffer> buffer( + new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size))); + surface->Attach(buffer.get()); + surface->Commit(); + + aura::client::FocusClient* focus_client = + aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow()); + focus_client->FocusWindow(nullptr); + + MockKeyboardDelegate delegate; + std::unique_ptr<Keyboard> keyboard(new Keyboard(&delegate)); + + EXPECT_CALL(delegate, CanAcceptKeyboardEventsForSurface(surface.get())) + .WillOnce(testing::Return(true)); + EXPECT_CALL(delegate, OnKeyboardModifiers(0)); + EXPECT_CALL(delegate, + OnKeyboardEnter(surface.get(), std::vector<ui::DomCode>())); + focus_client->FocusWindow(surface->window()); + + ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow()); + keyboard->SetNeedKeyboardKeyAcks(true); + + // Press KEY_W with Ctrl. + EXPECT_CALL(delegate, OnKeyboardModifiers(4)); + EXPECT_CALL(delegate, OnKeyboardKey(testing::_, ui::DomCode::US_W, true)) + .WillOnce(testing::Return(1)); + generator.PressKey(ui::VKEY_W, ui::EF_CONTROL_DOWN); + + // Wait until |ProcessExpiredPendingKeyAcks| is fired. + // |ProcessExpiredPendingKeyAcks| will call |AcceleratorPressed| and focus + // will be moved from the surface. + EXPECT_CALL(delegate, OnKeyboardLeave(surface.get())); + base::RunLoop run_loop; + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, run_loop.QuitClosure(), + base::TimeDelta::FromMilliseconds(1000)); + run_loop.Run(); + RunAllPendingInMessageLoop(); + + keyboard.reset(); +} + } // namespace } // namespace exo
diff --git a/components/exo/shell_surface.cc b/components/exo/shell_surface.cc index e8313b5..0509569 100644 --- a/components/exo/shell_surface.cc +++ b/components/exo/shell_surface.cc
@@ -21,6 +21,7 @@ #include "base/strings/utf_string_conversions.h" #include "base/trace_event/trace_event.h" #include "base/trace_event/trace_event_argument.h" +#include "cc/output/layer_tree_frame_sink.h" #include "components/exo/surface.h" #include "services/ui/public/interfaces/window_tree_constants.mojom.h" #include "ui/aura/client/aura_constants.h" @@ -651,8 +652,11 @@ TRACE_EVENT1("exo", "ShellSurface::SetRectangularShadow_DEPRECATED", "content_bounds", content_bounds.ToString()); pending_shadow_underlay_in_surface_ = false; - shadow_content_bounds_ = content_bounds; - shadow_enabled_ = !content_bounds.IsEmpty(); + if (content_bounds != shadow_content_bounds_) { + shadow_content_bounds_ = content_bounds; + shadow_content_bounds_changed_ = true; + shadow_enabled_ = !content_bounds.IsEmpty(); + } } void ShellSurface::SetRectangularSurfaceShadow( @@ -660,8 +664,11 @@ TRACE_EVENT1("exo", "ShellSurface::SetRectangularSurfaceShadow", "content_bounds", content_bounds.ToString()); pending_shadow_underlay_in_surface_ = true; - shadow_content_bounds_ = content_bounds; - shadow_enabled_ = !content_bounds.IsEmpty(); + if (content_bounds != shadow_content_bounds_) { + shadow_content_bounds_ = content_bounds; + shadow_content_bounds_changed_ = true; + shadow_enabled_ = !content_bounds.IsEmpty(); + } } void ShellSurface::SetRectangularShadowBackgroundOpacity(float opacity) { @@ -741,6 +748,15 @@ // SurfaceDelegate overrides: void ShellSurface::OnSurfaceCommit() { + // When the shadow underlay is in surface coordinate space and the surface's + // bounds have changed, shadow API requires that we synchronize the shadow + // bounds change with the next frame, so we have to submit the next frame to a + // new surface, and let the host_window() use the new surface. + if (pending_shadow_underlay_in_surface_ && shadow_content_bounds_changed_) { + layer_tree_frame_sink_holder()->frame_sink()->SetLocalSurfaceId( + viz::LocalSurfaceId()); + } + SurfaceTreeHost::OnSurfaceCommit(); // Apply the accumulated pending origin offset to reflect acknowledged @@ -1693,6 +1709,8 @@ shadow_underlay_.reset(); } + shadow_content_bounds_changed_ = false; + aura::Window* window = widget_->GetNativeWindow(); // Enable the black backdrop layer behind the window if the window
diff --git a/components/exo/shell_surface.h b/components/exo/shell_surface.h index 23a35ae..100734f 100644 --- a/components/exo/shell_surface.h +++ b/components/exo/shell_surface.h
@@ -57,7 +57,7 @@ public ash::wm::WindowStateObserver, public WMHelper::ActivationObserver, public WMHelper::DisplayConfigurationObserver, - NON_EXPORTED_BASE(public ui::CompositorLockClient) { + public ui::CompositorLockClient { public: enum class BoundsMode { SHELL, CLIENT, FIXED }; @@ -393,6 +393,7 @@ std::unique_ptr<aura::Window> shadow_overlay_; std::unique_ptr<aura::Window> shadow_underlay_; gfx::Rect shadow_content_bounds_; + bool shadow_content_bounds_changed_ = false; float shadow_background_opacity_ = 1.0; std::deque<Config> pending_configs_; std::unique_ptr<ash::WindowResizer> resizer_;
diff --git a/components/exo/surface.cc b/components/exo/surface.cc index 298905cb..7cf62869 100644 --- a/components/exo/surface.cc +++ b/components/exo/surface.cc
@@ -411,9 +411,22 @@ std::list<PresentationCallback>* presentation_callbacks) { bool needs_commit = frame_type == FRAME_TYPE_COMMIT && needs_commit_surface_hierarchy_; + bool needs_full_damage = frame_type == FRAME_TYPE_RECREATED_RESOURCES; + if (needs_commit) { needs_commit_surface_hierarchy_ = false; + if (pending_state_.opaque_region != state_.opaque_region || + pending_state_.buffer_scale != state_.buffer_scale || + pending_state_.viewport != state_.viewport || + pending_state_.crop != state_.crop || + pending_state_.only_visible_on_secure_output != + state_.only_visible_on_secure_output || + pending_state_.blend_mode != state_.blend_mode || + pending_state_.alpha != state_.alpha) { + needs_full_damage = true; + } + state_ = pending_state_; pending_state_.only_visible_on_secure_output = false; @@ -470,7 +483,7 @@ frame_sink_holder, frame, frame_callbacks, presentation_callbacks); } - AppendContentsToFrame(origin, frame_type, frame); + AppendContentsToFrame(origin, frame, needs_full_damage); // Reset damage. if (needs_commit) @@ -639,23 +652,20 @@ } void Surface::AppendContentsToFrame(const gfx::Point& origin, - FrameType frame_type, - cc::CompositorFrame* frame) { + cc::CompositorFrame* frame, + bool needs_full_damage) { const std::unique_ptr<cc::RenderPass>& render_pass = frame->render_pass_list.back(); gfx::Rect output_rect = gfx::Rect(origin, content_size_); gfx::Rect quad_rect = output_rect; gfx::Rect damage_rect; - switch (frame_type) { - case FRAME_TYPE_COMMIT: - // pending_damage_ is in Surface coordinates. - damage_rect = gfx::SkIRectToRect(pending_damage_.getBounds()); - damage_rect.set_origin(origin); - damage_rect.Intersect(output_rect); - break; - case FRAME_TYPE_RECREATED_RESOURCES: - damage_rect = output_rect; - break; + if (needs_full_damage) { + damage_rect = output_rect; + } else { + // pending_damage_ is in Surface coordinates. + damage_rect = gfx::SkIRectToRect(pending_damage_.getBounds()); + damage_rect.set_origin(origin); + damage_rect.Intersect(output_rect); } render_pass->damage_rect.Union(damage_rect);
diff --git a/components/exo/surface.h b/components/exo/surface.h index 211d3ee..41cc351 100644 --- a/components/exo/surface.h +++ b/components/exo/surface.h
@@ -261,8 +261,8 @@ // Puts the current surface into a draw quad, and appends the draw quads into // the |frame|. void AppendContentsToFrame(const gfx::Point& origin, - FrameType frame_type, - cc::CompositorFrame* frame); + cc::CompositorFrame* frame, + bool needs_full_damage); void UpdateContentSize();
diff --git a/components/exo/surface_unittest.cc b/components/exo/surface_unittest.cc index 4eba0f3..98bf020e 100644 --- a/components/exo/surface_unittest.cc +++ b/components/exo/surface_unittest.cc
@@ -136,6 +136,8 @@ EXPECT_FALSE(frame.render_pass_list.back() ->quad_list.back() ->ShouldDrawWithBlending()); + EXPECT_EQ(gfx::Rect(0, 0, 1, 1), + frame.render_pass_list.back()->damage_rect); } // Setting an empty opaque region requires draw with blending. @@ -150,6 +152,8 @@ EXPECT_TRUE(frame.render_pass_list.back() ->quad_list.back() ->ShouldDrawWithBlending()); + EXPECT_EQ(gfx::Rect(0, 0, 1, 1), + frame.render_pass_list.back()->damage_rect); } std::unique_ptr<Buffer> buffer_without_alpha( @@ -169,6 +173,8 @@ EXPECT_FALSE(frame.render_pass_list.back() ->quad_list.back() ->ShouldDrawWithBlending()); + EXPECT_EQ(gfx::Rect(0, 0, 0, 0), + frame.render_pass_list.back()->damage_rect); } } @@ -201,6 +207,13 @@ EXPECT_EQ( gfx::ScaleToFlooredSize(buffer_size, 1.0f / kBufferScale).ToString(), surface->content_size().ToString()); + + RunAllPendingInMessageLoop(); + + const cc::CompositorFrame& frame = GetFrameFromSurface(shell_surface.get()); + ASSERT_EQ(1u, frame.render_pass_list.size()); + EXPECT_EQ(gfx::Rect(0, 0, 256, 256), + frame.render_pass_list.back()->damage_rect); } TEST_F(SurfaceTest, MirrorLayers) { @@ -247,6 +260,13 @@ EXPECT_EQ(viewport2.ToString(), surface->window()->bounds().size().ToString()); EXPECT_EQ(viewport2.ToString(), surface->content_size().ToString()); + + RunAllPendingInMessageLoop(); + + const cc::CompositorFrame& frame = GetFrameFromSurface(shell_surface.get()); + ASSERT_EQ(1u, frame.render_pass_list.size()); + EXPECT_EQ(gfx::Rect(0, 0, 512, 512), + frame.render_pass_list.back()->damage_rect); } TEST_F(SurfaceTest, SetCrop) { @@ -263,6 +283,13 @@ EXPECT_EQ(crop_size.ToString(), surface->window()->bounds().size().ToString()); EXPECT_EQ(crop_size.ToString(), surface->content_size().ToString()); + + RunAllPendingInMessageLoop(); + + const cc::CompositorFrame& frame = GetFrameFromSurface(shell_surface.get()); + ASSERT_EQ(1u, frame.render_pass_list.size()); + EXPECT_EQ(gfx::Rect(0, 0, 12, 12), + frame.render_pass_list.back()->damage_rect); } TEST_F(SurfaceTest, SetBlendMode) { @@ -319,6 +346,11 @@ surface->Attach(buffer.get()); surface->SetAlpha(0.5f); surface->Commit(); + RunAllPendingInMessageLoop(); + + const cc::CompositorFrame& frame = GetFrameFromSurface(shell_surface.get()); + ASSERT_EQ(1u, frame.render_pass_list.size()); + EXPECT_EQ(gfx::Rect(0, 0, 1, 1), frame.render_pass_list.back()->damage_rect); } TEST_F(SurfaceTest, Commit) {
diff --git a/components/exo/wayland/clients/client_base.cc b/components/exo/wayland/clients/client_base.cc index b4830f0..ebb9bb0 100644 --- a/components/exo/wayland/clients/client_base.cc +++ b/components/exo/wayland/clients/client_base.cc
@@ -133,7 +133,12 @@ //////////////////////////////////////////////////////////////////////////////// // ClientBase::InitParams, public: -ClientBase::InitParams::InitParams() {} +ClientBase::InitParams::InitParams() { +#if defined(OZONE_PLATFORM_GBM) + drm_format = DRM_FORMAT_ABGR8888; + bo_usage = GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING | GBM_BO_USE_TEXTURING; +#endif +} ClientBase::InitParams::~InitParams() {} @@ -291,7 +296,7 @@ } #endif for (size_t i = 0; i < params.num_buffers; ++i) { - auto buffer = CreateBuffer(size_); + auto buffer = CreateBuffer(size_, params.drm_format, params.bo_usage); if (!buffer) { LOG(ERROR) << "Failed to create buffer"; return false; @@ -358,49 +363,53 @@ // ClientBase, private: std::unique_ptr<ClientBase::Buffer> ClientBase::CreateBuffer( - const gfx::Size& size) { - std::unique_ptr<Buffer> buffer = CreateDRMBuffer(size, DRM_FORMAT_ABGR8888); - if (buffer) - return buffer; + const gfx::Size& size, + int32_t drm_format, + int32_t bo_usage) { + std::unique_ptr<Buffer> buffer; + if (device_) { + buffer = CreateDrmBuffer(size, drm_format, bo_usage); + CHECK(buffer) << "Can't create drm buffer"; + } else { + buffer = base::MakeUnique<Buffer>(); - buffer = base::MakeUnique<Buffer>(); + size_t stride = size.width() * kBytesPerPixel; + buffer->shared_memory.reset(new base::SharedMemory()); + buffer->shared_memory->CreateAndMapAnonymous(stride * size.height()); + buffer->shm_pool.reset(wl_shm_create_pool( + globals_.shm.get(), buffer->shared_memory->handle().GetHandle(), + buffer->shared_memory->requested_size())); - size_t stride = size.width() * kBytesPerPixel; - buffer->shared_memory.reset(new base::SharedMemory()); - buffer->shared_memory->CreateAndMapAnonymous(stride * size.height()); - buffer->shm_pool.reset(wl_shm_create_pool( - globals_.shm.get(), buffer->shared_memory->handle().GetHandle(), - buffer->shared_memory->requested_size())); + buffer->buffer.reset(static_cast<wl_buffer*>( + wl_shm_pool_create_buffer(buffer->shm_pool.get(), 0, size.width(), + size.height(), stride, kShmFormat))); + if (!buffer->buffer) { + LOG(ERROR) << "Can't create buffer"; + return nullptr; + } - buffer->buffer.reset(static_cast<wl_buffer*>( - wl_shm_pool_create_buffer(buffer->shm_pool.get(), 0, size.width(), - size.height(), stride, kShmFormat))); - if (!buffer->buffer) { - LOG(ERROR) << "Can't create buffer"; - return nullptr; + buffer->sk_surface = SkSurface::MakeRasterDirect( + SkImageInfo::Make(size.width(), size.height(), kColorType, + kOpaque_SkAlphaType), + static_cast<uint8_t*>(buffer->shared_memory->memory()), stride); + DCHECK(buffer->sk_surface); } wl_buffer_add_listener(buffer->buffer.get(), &g_buffer_listener, buffer.get()); - - buffer->sk_surface = SkSurface::MakeRasterDirect( - SkImageInfo::Make(size.width(), size.height(), kColorType, - kOpaque_SkAlphaType), - static_cast<uint8_t*>(buffer->shared_memory->memory()), stride); - DCHECK(buffer->sk_surface); return buffer; } -std::unique_ptr<ClientBase::Buffer> ClientBase::CreateDRMBuffer( +std::unique_ptr<ClientBase::Buffer> ClientBase::CreateDrmBuffer( const gfx::Size& size, - int32_t drm_format) { + int32_t drm_format, + int32_t bo_usage) { std::unique_ptr<Buffer> buffer; #if defined(OZONE_PLATFORM_GBM) if (device_) { buffer = base::MakeUnique<Buffer>(); buffer->bo.reset(gbm_bo_create(device_.get(), size.width(), size.height(), - drm_format, - GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING)); + drm_format, bo_usage)); if (!buffer->bo) { LOG(ERROR) << "Can't create gbm buffer"; return nullptr;
diff --git a/components/exo/wayland/clients/client_base.h b/components/exo/wayland/clients/client_base.h index b2d5c9a..5307dc3 100644 --- a/components/exo/wayland/clients/client_base.h +++ b/components/exo/wayland/clients/client_base.h
@@ -44,6 +44,8 @@ bool transparent_background = false; bool use_drm = false; std::string use_drm_value; + int32_t drm_format = 0; + int32_t bo_usage = 0; }; struct Globals { @@ -82,9 +84,12 @@ protected: ClientBase(); virtual ~ClientBase(); - std::unique_ptr<Buffer> CreateBuffer(const gfx::Size& size); - std::unique_ptr<Buffer> CreateDRMBuffer(const gfx::Size& size, - int32_t drm_format); + std::unique_ptr<Buffer> CreateBuffer(const gfx::Size& size, + int32_t drm_format, + int32_t bo_usage); + std::unique_ptr<Buffer> CreateDrmBuffer(const gfx::Size& size, + int32_t drm_format, + int32_t bo_usage); gfx::Size size_ = gfx::Size(256, 256); int scale_ = 1;
diff --git a/components/exo/wayland/clients/subsurface.cc b/components/exo/wayland/clients/subsurface.cc index c9f686ea..9fb4092 100644 --- a/components/exo/wayland/clients/subsurface.cc +++ b/components/exo/wayland/clients/subsurface.cc
@@ -59,7 +59,8 @@ constexpr int32_t kSubsurfaceWidth = 128; constexpr int32_t kSubsurfaceHeight = 128; - auto subbuffer = CreateBuffer(gfx::Size(kSubsurfaceWidth, kSubsurfaceHeight)); + auto subbuffer = CreateBuffer(gfx::Size(kSubsurfaceWidth, kSubsurfaceHeight), + params.drm_format, params.bo_usage); if (!subbuffer) { LOG(ERROR) << "Failed to create subbuffer"; return;
diff --git a/components/exo/wayland/clients/yuv.cc b/components/exo/wayland/clients/yuv.cc index 2c33be5..0b4293a8 100644 --- a/components/exo/wayland/clients/yuv.cc +++ b/components/exo/wayland/clients/yuv.cc
@@ -54,14 +54,14 @@ (0.439 * SkColorGetR(color)) - (0.368 * SkColorGetG(color)) - (0.071 * SkColorGetB(color)) + 128}; if (i == 0) { - for (uint32_t y = 0; y < height_; ++y) { - for (uint32_t x = 0; x < width_; ++x) { + for (int y = 0; y < size_.height(); ++y) { + for (int x = 0; x < size_.width(); ++x) { data[stride * y + x] = yuv[0]; } } } else { - for (uint32_t y = 0; y < height_ / 2; ++y) { - for (uint32_t x = 0; x < width_ / 2; ++x) { + for (int y = 0; y < size_.height() / 2; ++y) { + for (int x = 0; x < size_.width() / 2; ++x) { data[stride * y + x * 2] = yuv[1]; data[stride * y + x * 2 + 1] = yuv[2]; } @@ -107,7 +107,8 @@ return; wl_surface_set_buffer_scale(surface_.get(), scale_); - wl_surface_damage(surface_.get(), 0, 0, width_ / scale_, height_ / scale_); + wl_surface_damage(surface_.get(), 0, 0, size_.width() / scale_, + size_.height() / scale_); wl_surface_attach(surface_.get(), buffer->buffer.get(), 0, 0); frame_callback.reset(wl_surface_frame(surface_.get())); @@ -135,6 +136,8 @@ // TODO(dcastagna): Support other YUV formats. params.drm_format = DRM_FORMAT_NV12; + params.bo_usage = + GBM_BO_USE_SCANOUT | GBM_BO_USE_LINEAR | GBM_BO_USE_TEXTURING; exo::wayland::clients::YuvClient client; client.Run(params);
diff --git a/components/favicon/content/content_favicon_driver.cc b/components/favicon/content/content_favicon_driver.cc index 09b45ef..97d35010 100644 --- a/components/favicon/content/content_favicon_driver.cc +++ b/components/favicon/content/content_favicon_driver.cc
@@ -244,7 +244,7 @@ bypass_cache_page_url_ = GURL(); // Get the favicon, either from history or request it from the net. - FetchFavicon(url); + FetchFavicon(url, navigation_handle->IsSameDocument()); } } // namespace favicon
diff --git a/components/favicon/core/favicon_driver.h b/components/favicon/core/favicon_driver.h index 55c05c09..b5856a2 100644 --- a/components/favicon/core/favicon_driver.h +++ b/components/favicon/core/favicon_driver.h
@@ -28,8 +28,10 @@ void AddObserver(FaviconDriverObserver* observer); void RemoveObserver(FaviconDriverObserver* observer); - // Initiates loading the favicon for the specified url. - virtual void FetchFavicon(const GURL& url) = 0; + // Initiates loading the favicon for the specified url. |is_same_document| + // is true for cases where this page URL follows a navigation within the same + // document (e.g. fragment navigation). + virtual void FetchFavicon(const GURL& page_url, bool is_same_document) = 0; // Returns the favicon for this tab, or IDR_DEFAULT_FAVICON if the tab does // not have a favicon. The default implementation uses the current navigation
diff --git a/components/favicon/core/favicon_driver_impl.cc b/components/favicon/core/favicon_driver_impl.cc index 891772e..6dd1a7a31 100644 --- a/components/favicon/core/favicon_driver_impl.cc +++ b/components/favicon/core/favicon_driver_impl.cc
@@ -70,9 +70,10 @@ FaviconDriverImpl::~FaviconDriverImpl() { } -void FaviconDriverImpl::FetchFavicon(const GURL& url) { +void FaviconDriverImpl::FetchFavicon(const GURL& page_url, + bool is_same_document) { for (const std::unique_ptr<FaviconHandler>& handler : handlers_) - handler->FetchFavicon(url); + handler->FetchFavicon(page_url, is_same_document); } bool FaviconDriverImpl::IsBookmarked(const GURL& url) {
diff --git a/components/favicon/core/favicon_driver_impl.h b/components/favicon/core/favicon_driver_impl.h index a64a9f3..53619f1f 100644 --- a/components/favicon/core/favicon_driver_impl.h +++ b/components/favicon/core/favicon_driver_impl.h
@@ -38,7 +38,7 @@ public FaviconHandler::Delegate { public: // FaviconDriver implementation. - void FetchFavicon(const GURL& url) override; + void FetchFavicon(const GURL& page_url, bool is_same_document) override; // FaviconHandler::Delegate implementation. bool IsBookmarked(const GURL& url) override;
diff --git a/components/favicon/core/favicon_handler.cc b/components/favicon/core/favicon_handler.cc index 52b7f26..42b17daa 100644 --- a/components/favicon/core/favicon_handler.cc +++ b/components/favicon/core/favicon_handler.cc
@@ -189,6 +189,7 @@ download_largest_icon_( handler_type == FaviconDriverObserver::NON_TOUCH_LARGEST || handler_type == FaviconDriverObserver::TOUCH_LARGEST), + candidates_received_(false), notification_icon_type_(favicon_base::INVALID_ICON), service_(service), delegate_(delegate), @@ -214,17 +215,27 @@ return 0; } -void FaviconHandler::FetchFavicon(const GURL& url) { +void FaviconHandler::FetchFavicon(const GURL& page_url, bool is_same_document) { cancelable_task_tracker_for_page_url_.TryCancelAll(); cancelable_task_tracker_for_candidates_.TryCancelAll(); - url_ = url; + // We generally clear |page_urls_| and start clean unless there are obvious + // reasons to think URLs share favicons: the navigation must be within the + // same document (e.g. fragment navigation) AND it happened so early that no + // candidates were received for the previous URL(s) (e.g. redirect-like + // history.replaceState() during page load). + if (!is_same_document || candidates_received_) { + page_urls_.clear(); + } + page_urls_.insert(page_url); + last_page_url_ = page_url; initial_history_result_expired_or_incomplete_ = false; redownload_icons_ = false; got_favicon_from_history_ = false; manifest_download_request_.Cancel(); image_download_request_.Cancel(); + candidates_received_ = false; manifest_url_ = GURL(); non_manifest_original_candidates_.clear(); candidates_.clear(); @@ -236,9 +247,12 @@ // Request the favicon from the history service. In parallel to this the // renderer is going to notify us (well WebContents) when the favicon url is - // available. + // available. We use |last_page_url_| specifically (regardless of other + // possible values in |page_urls_|) because we want to use the most + // up-to-date / latest URL for DB lookups, which is the page URL for which + // we get <link rel="icon"> candidates (FaviconHandler::OnUpdateCandidates()). service_->GetFaviconForPageURL( - url_, icon_types_, preferred_icon_size(), + last_page_url_, icon_types_, preferred_icon_size(), base::Bind(&FaviconHandler::OnFaviconDataForInitialURLFromFaviconService, base::Unretained(this)), &cancelable_task_tracker_for_page_url_); @@ -272,8 +286,13 @@ void FaviconHandler::SetFavicon(const GURL& icon_url, const gfx::Image& image, favicon_base::IconType icon_type) { - if (ShouldSaveFavicon()) - service_->SetFavicons(url_, icon_url, icon_type, image); + // Associate the icon to all URLs in |page_urls_|, which contains page URLs + // within the same site/document that have been considered to reliably share + // the same icon candidates. + for (const GURL& page_url : page_urls_) { + if (ShouldSaveFavicon(page_url)) + service_->SetFavicons(page_url, icon_url, icon_type, image); + } NotifyFaviconUpdated(icon_url, icon_type, image); } @@ -304,7 +323,7 @@ gfx::Image image_with_adjusted_colorspace = image; favicon_base::SetFaviconColorSpace(&image_with_adjusted_colorspace); - delegate_->OnFaviconUpdated(url_, handler_type_, icon_url, + delegate_->OnFaviconUpdated(last_page_url_, handler_type_, icon_url, icon_url != notification_icon_url_, image_with_adjusted_colorspace); @@ -316,7 +335,7 @@ const GURL& page_url, const std::vector<FaviconURL>& candidates, const GURL& manifest_url) { - if (page_url != url_) + if (last_page_url_ != page_url) return; bool manifests_feature_enabled = @@ -325,13 +344,14 @@ // |candidates| or |manifest_url| could have been modified via Javascript. If // neither changed, ignore the call. if ((!manifests_feature_enabled || manifest_url_ == manifest_url) && - non_manifest_original_candidates_.size() == candidates.size() && - std::equal(candidates.begin(), candidates.end(), - non_manifest_original_candidates_.begin(), - &FaviconURLEquals)) { + (non_manifest_original_candidates_.size() == candidates.size() && + std::equal(candidates.begin(), candidates.end(), + non_manifest_original_candidates_.begin(), + &FaviconURLEquals))) { return; } + candidates_received_ = true; non_manifest_original_candidates_ = candidates; cancelable_task_tracker_for_candidates_.TryCancelAll(); manifest_download_request_.Cancel(); @@ -561,12 +581,12 @@ cancelable_task_tracker_for_candidates_.HasTrackedTasks(); } -bool FaviconHandler::ShouldSaveFavicon() { +bool FaviconHandler::ShouldSaveFavicon(const GURL& page_url) const { if (!delegate_->IsOffTheRecord()) return true; // Always save favicon if the page is bookmarked. - return delegate_->IsBookmarked(url_); + return delegate_->IsBookmarked(page_url); } void FaviconHandler::OnFaviconDataForInitialURLFromFaviconService( @@ -587,6 +607,12 @@ // url) we'll fetch later on. This way the user doesn't see a flash of the // default favicon. NotifyFaviconUpdated(favicon_bitmap_results); + + // For strict correctness, we should also set the database icon mappings for + // other URLs in |page_urls_| (same-document navigations like fragment + // navigations) because there is no guarantee that there is a mapping for + // the other page URLs (e.g. |last_page_url_| has a mapping because it's + // bookmarked but the rest don't). } if (current_candidate()) @@ -626,7 +652,7 @@ // include the mapping between the page url and the favicon url. // This is asynchronous. The history service will call back when done. service_->UpdateFaviconMappingsAndFetch( - url_, icon_url, icon_type, preferred_icon_size(), callback, + page_urls_, icon_url, icon_type, preferred_icon_size(), callback, &cancelable_task_tracker_for_candidates_); } }
diff --git a/components/favicon/core/favicon_handler.h b/components/favicon/core/favicon_handler.h index fce615f..875da2ab 100644 --- a/components/favicon/core/favicon_handler.h +++ b/components/favicon/core/favicon_handler.h
@@ -7,6 +7,7 @@ #include <stddef.h> +#include <set> #include <vector> #include "base/callback_forward.h" @@ -142,8 +143,10 @@ FaviconDriverObserver::NotificationIconType handler_type); ~FaviconHandler(); - // Initiates loading the favicon for the specified url. - void FetchFavicon(const GURL& url); + // Initiates loading the favicon for the specified url. |is_same_document| is + // true for fragment navigations and history pushState/replaceState, see + // NavigationHandle::IsSameDocument(). + void FetchFavicon(const GURL& page_url, bool is_same_document); // Collects the candidate favicons as listed in the HTML head, as well as // the WebManifest URL if available (or empty URL otherwise). @@ -250,7 +253,7 @@ const std::vector<SkBitmap>& bitmaps, const std::vector<gfx::Size>& original_bitmap_sizes); - bool ShouldSaveFavicon(); + bool ShouldSaveFavicon(const GURL& page_url) const; // Updates |best_favicon_| and returns true if it was considered a satisfying // image (e.g. exact size match). @@ -296,8 +299,11 @@ const FaviconDriverObserver::NotificationIconType handler_type_; - // URL of the page we're requesting the favicon for. - GURL url_; + // URL of the page(s) we're requesting the favicon for. They can be multiple + // in case of in-page navigations (e.g. fragment navigations). + std::set<GURL> page_urls_; + // The last page URL reported via FetchFavicon(). + GURL last_page_url_; // Whether we got data back for the initial request to the FaviconService. bool got_favicon_from_history_; @@ -328,6 +334,10 @@ // Whether the largest icon should be downloaded. const bool download_largest_icon_; + // Whether candidates have been received (OnUpdateCandidates() has been + // called, regardless of whether the provided list was empty). + bool candidates_received_; + // The manifest URL from the renderer (or empty URL if none). GURL manifest_url_;
diff --git a/components/favicon/core/favicon_handler_unittest.cc b/components/favicon/core/favicon_handler_unittest.cc index af8a73c..68c1045 100644 --- a/components/favicon/core/favicon_handler_unittest.cc +++ b/components/favicon/core/favicon_handler_unittest.cc
@@ -376,7 +376,7 @@ } base::CancelableTaskTracker::TaskId UpdateFaviconMappingsAndFetch( - const GURL& page_url, + const std::set<GURL>& page_urls, const GURL& icon_url, favicon_base::IconType icon_type, int desired_size_in_dip, @@ -506,11 +506,11 @@ // Returns the handler in case tests want to exercise further steps. std::unique_ptr<FaviconHandler> RunHandlerWithCandidates( FaviconDriverObserver::NotificationIconType handler_type, - const std::vector<favicon::FaviconURL>& candidates, + const std::vector<FaviconURL>& candidates, const GURL& manifest_url = GURL()) { auto handler = base::MakeUnique<FaviconHandler>(&favicon_service_, &delegate_, handler_type); - handler->FetchFavicon(kPageURL); + handler->FetchFavicon(kPageURL, /*is_same_document=*/false); // The first RunUntilIdle() causes the FaviconService lookups be faster than // OnUpdateCandidates(), which is the most likely scenario. base::RunLoop().RunUntilIdle(); @@ -561,15 +561,42 @@ } // Test that UpdateFaviconsAndFetch() is called with the appropriate parameters -// when there is data in the database for neither the page URL nor the icon URL. +// when there is no data in the database for the page URL. TEST_F(FaviconHandlerTest, UpdateFaviconMappingsAndFetch) { EXPECT_CALL(favicon_service_, - UpdateFaviconMappingsAndFetch(kPageURL, kIconURL16x16, FAVICON, + UpdateFaviconMappingsAndFetch(std::set<GURL>{kPageURL}, + kIconURL16x16, FAVICON, /*desired_size_in_dip=*/16, _, _)); RunHandlerWithSimpleFaviconCandidates({kIconURL16x16}); } +// Test that UpdateFaviconsAndFetch() is called with the appropriate parameters +// when there is no data in the database for the page URL, for the case where +// multiple page URLs exist due to a quick in-same-document navigation (e.g. +// fragment navigation). +TEST_F(FaviconHandlerTest, UpdateFaviconMappingsAndFetchWithMultipleURLs) { + const GURL kDifferentPageURL = GURL("http://www.google.com/other"); + + EXPECT_CALL(favicon_service_, UpdateFaviconMappingsAndFetch( + std::set<GURL>{kPageURL, kDifferentPageURL}, + kIconURL16x16, _, _, _, _)); + + std::unique_ptr<FaviconHandler> handler = base::MakeUnique<FaviconHandler>( + &favicon_service_, &delegate_, FaviconDriverObserver::NON_TOUCH_16_DIP); + handler->FetchFavicon(kPageURL, /*is_same_document=*/false); + base::RunLoop().RunUntilIdle(); + // Load a new URL (same document) without feeding any candidates for the first + // URL. + handler->FetchFavicon(kDifferentPageURL, /*is_same_document=*/true); + base::RunLoop().RunUntilIdle(); + // Feed in candidates for the second URL. + handler->OnUpdateCandidates(kDifferentPageURL, + {FaviconURL(kIconURL16x16, FAVICON, kEmptySizes)}, + /*manifest_url=*/GURL()); + base::RunLoop().RunUntilIdle(); +} + // Test that the FaviconHandler process finishes when: // - There is data in the database for neither the page URL nor the icon URL. // AND @@ -584,7 +611,7 @@ FaviconHandler handler(&favicon_service_, &delegate_, FaviconDriverObserver::NON_TOUCH_16_DIP); - handler.FetchFavicon(kPageURL); + handler.FetchFavicon(kPageURL, /*is_same_document=*/false); base::RunLoop().RunUntilIdle(); // Database lookup for |kPageURL| is ongoing. ASSERT_TRUE(favicon_service_.fake()->HasPendingManualCallback()); @@ -621,7 +648,7 @@ FaviconHandler handler(&favicon_service_, &delegate_, FaviconDriverObserver::NON_TOUCH_16_DIP); - handler.FetchFavicon(kPageURL); + handler.FetchFavicon(kPageURL, /*is_same_document=*/false); base::RunLoop().RunUntilIdle(); // Feed in favicons before completing the database lookup. handler.OnUpdateCandidates( @@ -1462,6 +1489,61 @@ /*expected_count=*/1))); } +// Test that if a page URL is followed by another page URL which is not +// considered the same document, favicon candidates listed in the second page +// get associated to that second page only. +TEST_F(FaviconHandlerTest, SetFaviconsForLastPageUrlOnly) { + const GURL kDifferentPageURL = GURL("http://www.google.com/other"); + + EXPECT_CALL(favicon_service_, + SetFavicons(kDifferentPageURL, kIconURL12x12, _, _)); + EXPECT_CALL(delegate_, + OnFaviconUpdated(kDifferentPageURL, + FaviconDriverObserver::NON_TOUCH_16_DIP, + kIconURL12x12, _, _)); + + std::unique_ptr<FaviconHandler> handler = base::MakeUnique<FaviconHandler>( + &favicon_service_, &delegate_, FaviconDriverObserver::NON_TOUCH_16_DIP); + handler->FetchFavicon(kPageURL, /*is_same_document=*/false); + base::RunLoop().RunUntilIdle(); + // Load a new URL (different document) without feeding any candidates for the + // first URL. + handler->FetchFavicon(kDifferentPageURL, /*is_same_document=*/false); + base::RunLoop().RunUntilIdle(); + handler->OnUpdateCandidates(kDifferentPageURL, + {FaviconURL(kIconURL12x12, FAVICON, kEmptySizes)}, + /*manifest_url=*/GURL()); + base::RunLoop().RunUntilIdle(); +} + +// Test that if a page URL is followed by another page URL which is considered +// the same document (e.g. fragment navigation), favicon candidates listed in +// the second page get associated to both page URLs. +TEST_F(FaviconHandlerTest, SetFaviconsForMultipleUrlsWithinDocument) { + const GURL kDifferentPageURL = GURL("http://www.google.com/other"); + + EXPECT_CALL(favicon_service_, SetFavicons(kPageURL, kIconURL12x12, _, _)); + EXPECT_CALL(favicon_service_, + SetFavicons(kDifferentPageURL, kIconURL12x12, _, _)); + EXPECT_CALL(delegate_, + OnFaviconUpdated(kDifferentPageURL, + FaviconDriverObserver::NON_TOUCH_16_DIP, + kIconURL12x12, _, _)); + + std::unique_ptr<FaviconHandler> handler = base::MakeUnique<FaviconHandler>( + &favicon_service_, &delegate_, FaviconDriverObserver::NON_TOUCH_16_DIP); + handler->FetchFavicon(kPageURL, /*is_same_document=*/false); + base::RunLoop().RunUntilIdle(); + // Load a new URL (same document) without feeding any candidates for the first + // URL. + handler->FetchFavicon(kDifferentPageURL, /*is_same_document=*/true); + base::RunLoop().RunUntilIdle(); + handler->OnUpdateCandidates(kDifferentPageURL, + {FaviconURL(kIconURL12x12, FAVICON, kEmptySizes)}, + /*manifest_url=*/GURL()); + base::RunLoop().RunUntilIdle(); +} + // Manifests are currently enabled by default. Leaving this fixture for // logical grouping and blame layer. class FaviconHandlerManifestsEnabledTest : public FaviconHandlerTest { @@ -1602,8 +1684,7 @@ delegate_.fake_manifest_downloader().Add(kManifestURL, kManifestIcons); - RunHandlerWithCandidates(FaviconDriverObserver::TOUCH_LARGEST, - std::vector<favicon::FaviconURL>(), kManifestURL); + RunHandlerWithSimpleTouchIconCandidates(URLVector(), kManifestURL); EXPECT_THAT(delegate_.downloads(), ElementsAre(kManifestURL, kIconURL192x192));
diff --git a/components/favicon/core/favicon_service.h b/components/favicon/core/favicon_service.h index 60552b1..1958ce4f 100644 --- a/components/favicon/core/favicon_service.h +++ b/components/favicon/core/favicon_service.h
@@ -8,6 +8,7 @@ #include <stdint.h> #include <memory> +#include <set> #include <vector> #include "base/callback.h" @@ -113,14 +114,14 @@ const favicon_base::FaviconResultsCallback& callback, base::CancelableTaskTracker* tracker) = 0; - // Maps |page_url| to the favicon at |icon_url| if there is an entry in the + // Maps |page_urls| to the favicon at |icon_url| if there is an entry in the // database for |icon_url| and |icon_type|. This occurs when there is a // mapping from a different page URL to |icon_url|. The favicon bitmaps whose // edge sizes most closely match |desired_size_in_dip| from the favicons which - // were just mapped to |page_url| are returned. If |desired_size_in_dip| has a - // '0' entry, the largest favicon bitmap is returned. + // were just mapped to |page_urls| are returned. If |desired_size_in_dip| has + // a '0' entry, the largest favicon bitmap is returned. virtual base::CancelableTaskTracker::TaskId UpdateFaviconMappingsAndFetch( - const GURL& page_url, + const std::set<GURL>& page_urls, const GURL& icon_url, favicon_base::IconType icon_type, int desired_size_in_dip,
diff --git a/components/favicon/core/favicon_service_impl.cc b/components/favicon/core/favicon_service_impl.cc index e267981e..aed6e95b 100644 --- a/components/favicon/core/favicon_service_impl.cc +++ b/components/favicon/core/favicon_service_impl.cc
@@ -175,14 +175,14 @@ base::CancelableTaskTracker::TaskId FaviconServiceImpl::UpdateFaviconMappingsAndFetch( - const GURL& page_url, + const std::set<GURL>& page_urls, const GURL& icon_url, favicon_base::IconType icon_type, int desired_size_in_dip, const favicon_base::FaviconResultsCallback& callback, base::CancelableTaskTracker* tracker) { return history_service_->UpdateFaviconMappingsAndFetch( - page_url, icon_url, icon_type, + page_urls, icon_url, icon_type, GetPixelSizesForFaviconScales(desired_size_in_dip), callback, tracker); }
diff --git a/components/favicon/core/favicon_service_impl.h b/components/favicon/core/favicon_service_impl.h index 7ad2d0a..314708d 100644 --- a/components/favicon/core/favicon_service_impl.h +++ b/components/favicon/core/favicon_service_impl.h
@@ -8,6 +8,7 @@ #include <stdint.h> #include <memory> +#include <set> #include <vector> #include "base/callback.h" @@ -80,7 +81,7 @@ const favicon_base::FaviconResultsCallback& callback, base::CancelableTaskTracker* tracker) override; base::CancelableTaskTracker::TaskId UpdateFaviconMappingsAndFetch( - const GURL& page_url, + const std::set<GURL>& page_urls, const GURL& icon_url, favicon_base::IconType icon_type, int desired_size_in_dip,
diff --git a/components/favicon/core/test/mock_favicon_service.h b/components/favicon/core/test/mock_favicon_service.h index c9da0a1..1e1dc30 100644 --- a/components/favicon/core/test/mock_favicon_service.h +++ b/components/favicon/core/test/mock_favicon_service.h
@@ -5,6 +5,7 @@ #ifndef COMPONENTS_FAVICON_CORE_TEST_MOCK_FAVICON_SERVICE_H_ #define COMPONENTS_FAVICON_CORE_TEST_MOCK_FAVICON_SERVICE_H_ +#include <set> #include <vector> #include "base/task/cancelable_task_tracker.h" @@ -77,7 +78,7 @@ base::CancelableTaskTracker* tracker)); MOCK_METHOD6(UpdateFaviconMappingsAndFetch, base::CancelableTaskTracker::TaskId( - const GURL& page_url, + const std::set<GURL>& page_urls, const GURL& icon_url, favicon_base::IconType icon_type, int desired_size_in_dip,
diff --git a/components/favicon/ios/web_favicon_driver.h b/components/favicon/ios/web_favicon_driver.h index 5006975b..8e6abd3 100644 --- a/components/favicon/ios/web_favicon_driver.h +++ b/components/favicon/ios/web_favicon_driver.h
@@ -32,7 +32,7 @@ bookmarks::BookmarkModel* bookmark_model); // FaviconDriver implementation. - void FetchFavicon(const GURL& url) override; + void FetchFavicon(const GURL& page_url, bool is_same_document) override; gfx::Image GetFavicon() const override; bool FaviconIsValid() const override; GURL GetActiveURL() override;
diff --git a/components/favicon/ios/web_favicon_driver.mm b/components/favicon/ios/web_favicon_driver.mm index 6d8c7d05..889d2ed9 100644 --- a/components/favicon/ios/web_favicon_driver.mm +++ b/components/favicon/ios/web_favicon_driver.mm
@@ -48,9 +48,10 @@ history_service, bookmark_model))); } -void WebFaviconDriver::FetchFavicon(const GURL& url) { - fetch_favicon_url_ = url; - FaviconDriverImpl::FetchFavicon(url); +void WebFaviconDriver::FetchFavicon(const GURL& page_url, + bool is_same_document) { + fetch_favicon_url_ = page_url; + FaviconDriverImpl::FetchFavicon(page_url, is_same_document); } gfx::Image WebFaviconDriver::GetFavicon() const {
diff --git a/components/guest_view/browser/bad_message.h b/components/guest_view/browser/bad_message.h index a0b2c4c..1a38fa6d 100644 --- a/components/guest_view/browser/bad_message.h +++ b/components/guest_view/browser/bad_message.h
@@ -24,6 +24,7 @@ enum BadMessageReason { GVM_EMBEDDER_FORBIDDEN_ACCESS_TO_GUEST = 0, GVM_INVALID_GUESTVIEW_TYPE = 1, + GVMF_UNEXPECTED_MESSAGE_BEFORE_GVM_CREATION = 2, // Please add new elements here. The naming convention is abbreviated class // name (e.g. GuestViewManager becomes GVM) plus a unique description of
diff --git a/components/guest_view/browser/guest_view_base.cc b/components/guest_view/browser/guest_view_base.cc index 4d491316..24ec4b6 100644 --- a/components/guest_view/browser/guest_view_base.cc +++ b/components/guest_view/browser/guest_view_base.cc
@@ -431,12 +431,16 @@ SendQueuedEvents(); } +// TODO(wjmaclean): Delete this when browser plugin goes away; +// https://crbug.com/533069 . void GuestViewBase::DidDetach() { GuestViewManager::FromBrowserContext(browser_context_)->DetachGuest(this); StopTrackingEmbedderZoomLevel(); owner_web_contents()->Send(new GuestViewMsg_GuestDetached( element_instance_id_)); element_instance_id_ = kInstanceIDNone; + if (ShouldDestroyOnDetach()) + Destroy(true); } WebContents* GuestViewBase::GetOwnerWebContents() const { @@ -451,6 +455,10 @@ return owner_web_contents()->GetLastCommittedURL(); } +bool GuestViewBase::ShouldDestroyOnDetach() const { + return false; +} + void GuestViewBase::Destroy(bool also_delete) { if (is_being_destroyed_) return;
diff --git a/components/guest_view/browser/guest_view_base.h b/components/guest_view/browser/guest_view_base.h index 70fa252..8b7d21d 100644 --- a/components/guest_view/browser/guest_view_base.h +++ b/components/guest_view/browser/guest_view_base.h
@@ -195,6 +195,11 @@ // Destroy this guest. void Destroy(bool also_delete); + // Indicates whether a guest should call destroy during DidDetach(). + // TODO(wjmaclean): Delete this when browser plugin goes away; + // https://crbug.com/533069 . + virtual bool ShouldDestroyOnDetach() const; + // Saves the attach state of the custom element hosting this GuestView. void SetAttachParams(const base::DictionaryValue& params); void SetOpener(GuestViewBase* opener);
diff --git a/components/guest_view/browser/guest_view_message_filter.cc b/components/guest_view/browser/guest_view_message_filter.cc index c2124ed..e0721b3 100644 --- a/components/guest_view/browser/guest_view_message_filter.cc +++ b/components/guest_view/browser/guest_view_message_filter.cc
@@ -5,6 +5,7 @@ #include "components/guest_view/browser/guest_view_message_filter.h" #include "base/memory/ptr_util.h" +#include "components/guest_view/browser/bad_message.h" #include "components/guest_view/browser/guest_view_base.h" #include "components/guest_view/browser/guest_view_manager.h" #include "components/guest_view/browser/guest_view_manager_delegate.h" @@ -57,6 +58,15 @@ return manager; } +GuestViewManager* GuestViewMessageFilter::GetGuestViewManagerOrKill() { + auto* manager = GuestViewManager::FromBrowserContext(browser_context_); + if (!manager) { + bad_message::ReceivedBadMessage( + this, bad_message::GVMF_UNEXPECTED_MESSAGE_BEFORE_GVM_CREATION); + } + return manager; +} + void GuestViewMessageFilter::OverrideThreadForMessage( const IPC::Message& message, BrowserThread::ID* thread) { @@ -119,8 +129,12 @@ int element_instance_id, int guest_instance_id, const base::DictionaryValue& params) { - auto* manager = GuestViewManager::FromBrowserContext(browser_context_); - DCHECK(manager); + // We should have a GuestViewManager at this point. If we don't then the + // embedder is misbehaving. + auto* manager = GetGuestViewManagerOrKill(); + if (!manager) + return; + content::WebContents* guest_web_contents = manager->GetGuestByInstanceIDSafely(guest_instance_id, render_process_id_);
diff --git a/components/guest_view/browser/guest_view_message_filter.h b/components/guest_view/browser/guest_view_message_filter.h index 1a24bf2c..a6587f9 100644 --- a/components/guest_view/browser/guest_view_message_filter.h +++ b/components/guest_view/browser/guest_view_message_filter.h
@@ -45,6 +45,12 @@ // or creates and returns one for |browser_context_| otherwise. virtual GuestViewManager* GetOrCreateGuestViewManager(); + // Returns the GuestViewManager for |browser_context_| if it exists. + // Callers consider the renderer to be misbehaving if we don't have a + // GuestViewManager at this point, in which case we kill the renderer and + // return nullptr. + GuestViewManager* GetGuestViewManagerOrKill(); + // content::BrowserMessageFilter implementation. void OverrideThreadForMessage(const IPC::Message& message, content::BrowserThread::ID* thread) override;
diff --git a/components/history/core/browser/history_backend.cc b/components/history/core/browser/history_backend.cc index a3a062a..dec7e10f 100644 --- a/components/history/core/browser/history_backend.cc +++ b/components/history/core/browser/history_backend.cc
@@ -1453,8 +1453,8 @@ favicon_base::IconType icon_type, const std::vector<int>& desired_sizes, std::vector<favicon_base::FaviconRawBitmapResult>* bitmap_results) { - UpdateFaviconMappingsAndFetchImpl(nullptr, icon_url, icon_type, desired_sizes, - bitmap_results); + UpdateFaviconMappingsAndFetchImpl(std::set<GURL>(), icon_url, icon_type, + desired_sizes, bitmap_results); } void HistoryBackend::GetLargestFaviconForURL( @@ -1585,12 +1585,12 @@ } void HistoryBackend::UpdateFaviconMappingsAndFetch( - const GURL& page_url, + const std::set<GURL>& page_urls, const GURL& icon_url, favicon_base::IconType icon_type, const std::vector<int>& desired_sizes, std::vector<favicon_base::FaviconRawBitmapResult>* bitmap_results) { - UpdateFaviconMappingsAndFetchImpl(&page_url, icon_url, icon_type, + UpdateFaviconMappingsAndFetchImpl(page_urls, icon_url, icon_type, desired_sizes, bitmap_results); } @@ -1906,7 +1906,7 @@ } void HistoryBackend::UpdateFaviconMappingsAndFetchImpl( - const GURL* page_url, + const std::set<GURL>& page_urls, const GURL& icon_url, favicon_base::IconType icon_type, const std::vector<int>& desired_sizes, @@ -1924,12 +1924,14 @@ if (favicon_id) favicon_ids.push_back(favicon_id); - if (page_url && !favicon_ids.empty()) { - bool mappings_updated = SetFaviconMappingsForPageAndRedirects( - *page_url, icon_type, favicon_ids); - if (mappings_updated) { - SendFaviconChangedNotificationForPageAndRedirects(*page_url); - ScheduleCommit(); + if (!favicon_ids.empty()) { + for (const GURL& page_url : page_urls) { + bool mappings_updated = SetFaviconMappingsForPageAndRedirects( + page_url, icon_type, favicon_ids); + if (mappings_updated) { + SendFaviconChangedNotificationForPageAndRedirects(page_url); + ScheduleCommit(); + } } }
diff --git a/components/history/core/browser/history_backend.h b/components/history/core/browser/history_backend.h index 43fdccd..1a698364 100644 --- a/components/history/core/browser/history_backend.h +++ b/components/history/core/browser/history_backend.h
@@ -309,7 +309,7 @@ std::vector<favicon_base::FaviconRawBitmapResult>* bitmap_results); void UpdateFaviconMappingsAndFetch( - const GURL& page_url, + const std::set<GURL>& page_urls, const GURL& icon_url, favicon_base::IconType icon_type, const std::vector<int>& desired_sizes, @@ -693,11 +693,11 @@ FaviconBitmapType type); // Used by both UpdateFaviconMappingsAndFetch() and GetFavicon(). - // If |page_url| is non-null and there is a favicon stored in the database - // for |icon_url|, a mapping is added to the database from |page_url| (and all - // redirects) to |icon_url|. + // If there is a favicon stored in the database for |icon_url|, a mapping is + // added to the database from each element in |page_urls| (and all redirects) + // to |icon_url|. void UpdateFaviconMappingsAndFetchImpl( - const GURL* page_url, + const std::set<GURL>& page_urls, const GURL& icon_url, favicon_base::IconType icon_type, const std::vector<int>& desired_sizes,
diff --git a/components/history/core/browser/history_backend_db_unittest.cc b/components/history/core/browser/history_backend_db_unittest.cc index 939e1c8..53e128e 100644 --- a/components/history/core/browser/history_backend_db_unittest.cc +++ b/components/history/core/browser/history_backend_db_unittest.cc
@@ -533,13 +533,13 @@ // => guid[14] == '4' // // * Bits 6-7 of clk_seq_hi_res should be set to 0b10 - // => guid[19] in {'8','9','A','B'} + // => guid[19] in {'8','9','A','B','a','b'} // // * All other bits should be random or pseudo random. // => http://dilbert.com/strip/2001-10-25 return base::IsValidGUID(guid) && guid[14] == '4' && (guid[19] == '8' || guid[19] == '9' || guid[19] == 'A' || - guid[19] == 'B'); + guid[19] == 'B' || guid[19] == 'a' || guid[19] == 'b'); } TEST_F(HistoryBackendDBTest, MigrateHashHttpMethodAndGenerateGuids) { @@ -608,7 +608,6 @@ std::string guid = s.ColumnString(0); uint32_t id = static_cast<uint32_t>(s.ColumnInt64(1)); EXPECT_TRUE(IsValidRFC4122Ver4GUID(guid)); - EXPECT_EQ(guid, base::ToUpperASCII(guid)); // Id is used as time_low in RFC 4122 to guarantee unique GUIDs EXPECT_EQ(guid.substr(0, 8), base::StringPrintf("%08" PRIX32, id)); guids.insert(guid);
diff --git a/components/history/core/browser/history_backend_unittest.cc b/components/history/core/browser/history_backend_unittest.cc index 9cb50d9d..79b79003a 100644 --- a/components/history/core/browser/history_backend_unittest.cc +++ b/components/history/core/browser/history_backend_unittest.cc
@@ -2049,8 +2049,8 @@ std::vector<favicon_base::FaviconRawBitmapResult> bitmap_results; backend_->UpdateFaviconMappingsAndFetch( - page_url2, icon_url, favicon_base::FAVICON, GetEdgeSizesSmallAndLarge(), - &bitmap_results); + std::set<GURL>{page_url2}, icon_url, favicon_base::FAVICON, + GetEdgeSizesSmallAndLarge(), &bitmap_results); // Check that the same FaviconID is mapped to both page URLs. std::vector<IconMapping> icon_mappings; @@ -2614,23 +2614,23 @@ // favicon at |icon_url1|. std::vector<favicon_base::FaviconRawBitmapResult> bitmap_results; backend_->UpdateFaviconMappingsAndFetch( - page_url3, icon_url1, favicon_base::FAVICON, + std::set<GURL>{page_url3}, icon_url1, favicon_base::FAVICON, GetEdgeSizesSmallAndLarge(), &bitmap_results); ClearBroadcastedNotifications(); } // SetFavicons() backend_->SetFavicons(page_url1, favicon_base::FAVICON, icon_url2, bitmaps); - ASSERT_EQ(1u, favicon_changed_notifications_page_urls().size()); - EXPECT_EQ(page_url1, favicon_changed_notifications_page_urls()[0]); + EXPECT_THAT(favicon_changed_notifications_page_urls(), + ElementsAre(page_url1)); EXPECT_EQ(0u, favicon_changed_notifications_icon_urls().size()); ClearBroadcastedNotifications(); // MergeFavicon() backend_->MergeFavicon(page_url1, icon_url1, favicon_base::FAVICON, new base::RefCountedBytes(png_bytes), kSmallSize); - ASSERT_EQ(1u, favicon_changed_notifications_page_urls().size()); - EXPECT_EQ(page_url1, favicon_changed_notifications_page_urls()[0]); + EXPECT_THAT(favicon_changed_notifications_page_urls(), + ElementsAre(page_url1)); EXPECT_EQ(0u, favicon_changed_notifications_icon_urls().size()); ClearBroadcastedNotifications(); @@ -2638,14 +2638,61 @@ { std::vector<favicon_base::FaviconRawBitmapResult> bitmap_results; backend_->UpdateFaviconMappingsAndFetch( - page_url1, icon_url2, favicon_base::FAVICON, + std::set<GURL>{page_url1}, icon_url2, favicon_base::FAVICON, GetEdgeSizesSmallAndLarge(), &bitmap_results); - ASSERT_EQ(1u, favicon_changed_notifications_page_urls().size()); - EXPECT_EQ(page_url1, favicon_changed_notifications_page_urls()[0]); + EXPECT_THAT(favicon_changed_notifications_page_urls(), + ElementsAre(page_url1)); EXPECT_EQ(0u, favicon_changed_notifications_icon_urls().size()); } } +// Test that changing the page URL -> icon URL mapping for multiple page URLs +// sends notifications that the favicon for each page URL has changed. +TEST_F(HistoryBackendTest, + FaviconChangedNotificationIconMappingChangedForMultiplePages) { + GURL page_url1("http://www.google.com/a"); + GURL page_url2("http://www.google.com/b"); + GURL page_url3("http://www.google.com/c"); + GURL page_url4("http://www.google.com/d"); + GURL icon_url("http://www.google.com/favicon.ico"); + + SkBitmap bitmap(CreateBitmap(SK_ColorBLUE, kSmallEdgeSize)); + std::vector<SkBitmap> bitmaps; + bitmaps.push_back(bitmap); + std::vector<unsigned char> png_bytes; + ASSERT_TRUE(gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, false, &png_bytes)); + + // Setup + { + std::vector<SkBitmap> bitmaps; + bitmaps.push_back(CreateBitmap(SK_ColorBLUE, kSmallEdgeSize)); + backend_->SetFavicons(page_url4, favicon_base::FAVICON, icon_url, bitmaps); + ClearBroadcastedNotifications(); + } + + // UpdateFaviconMappingsAndFetch() for two page URLs. + { + std::vector<favicon_base::FaviconRawBitmapResult> bitmap_results; + backend_->UpdateFaviconMappingsAndFetch( + {page_url1, page_url2}, icon_url, favicon_base::FAVICON, + GetEdgeSizesSmallAndLarge(), &bitmap_results); + EXPECT_THAT(favicon_changed_notifications_page_urls(), + ElementsAre(page_url1, page_url2)); + ClearBroadcastedNotifications(); + } + + // UpdateFaviconMappingsAndFetch() for two page URLs, but only one needs an + // update. + { + std::vector<favicon_base::FaviconRawBitmapResult> bitmap_results; + backend_->UpdateFaviconMappingsAndFetch( + {page_url3, page_url4}, icon_url, favicon_base::FAVICON, + GetEdgeSizesSmallAndLarge(), &bitmap_results); + EXPECT_THAT(favicon_changed_notifications_page_urls(), + ElementsAre(page_url3)); + } +} + // Test that changing both: // - The page URL -> icon URL mapping // - The favicon's bitmap data @@ -2670,7 +2717,7 @@ // favicon at |icon_url1|. std::vector<favicon_base::FaviconRawBitmapResult> bitmap_results; backend_->UpdateFaviconMappingsAndFetch( - page_url3, icon_url1, favicon_base::FAVICON, + std::set<GURL>{page_url3}, icon_url1, favicon_base::FAVICON, GetEdgeSizesSmallAndLarge(), &bitmap_results); ClearBroadcastedNotifications(); } @@ -2817,8 +2864,8 @@ { std::vector<favicon_base::FaviconRawBitmapResult> bitmap_results; backend_->UpdateFaviconMappingsAndFetch( - page_url, icon_url, favicon_base::FAVICON, GetEdgeSizesSmallAndLarge(), - &bitmap_results); + std::set<GURL>{page_url}, icon_url, favicon_base::FAVICON, + GetEdgeSizesSmallAndLarge(), &bitmap_results); } EXPECT_EQ(0u, favicon_changed_notifications_page_urls().size()); @@ -3094,9 +3141,9 @@ std::vector<favicon_base::FaviconRawBitmapResult> bitmap_results; - backend_->UpdateFaviconMappingsAndFetch(GURL(), GURL(), favicon_base::FAVICON, - GetEdgeSizesSmallAndLarge(), - &bitmap_results); + backend_->UpdateFaviconMappingsAndFetch( + std::set<GURL>{GURL()}, GURL(), favicon_base::FAVICON, + GetEdgeSizesSmallAndLarge(), &bitmap_results); EXPECT_TRUE(bitmap_results.empty()); }
diff --git a/components/history/core/browser/history_service.cc b/components/history/core/browser/history_service.cc index 6e8b789..982a8b1 100644 --- a/components/history/core/browser/history_service.cc +++ b/components/history/core/browser/history_service.cc
@@ -574,7 +574,7 @@ base::CancelableTaskTracker::TaskId HistoryService::UpdateFaviconMappingsAndFetch( - const GURL& page_url, + const std::set<GURL>& page_urls, const GURL& icon_url, favicon_base::IconType icon_type, const std::vector<int>& desired_sizes, @@ -588,8 +588,8 @@ return tracker->PostTaskAndReply( backend_task_runner_.get(), FROM_HERE, base::Bind(&HistoryBackend::UpdateFaviconMappingsAndFetch, - history_backend_, page_url, icon_url, icon_type, desired_sizes, - results), + history_backend_, page_urls, icon_url, icon_type, + desired_sizes, results), base::Bind(&RunWithFaviconResults, callback, base::Owned(results))); }
diff --git a/components/history/core/browser/history_service.h b/components/history/core/browser/history_service.h index 710ac70..140bbd35 100644 --- a/components/history/core/browser/history_service.h +++ b/components/history/core/browser/history_service.h
@@ -700,14 +700,14 @@ const favicon_base::FaviconResultsCallback& callback, base::CancelableTaskTracker* tracker); - // Maps |page_url| to the favicon at |icon_url| if there is an entry in the + // Maps |page_urls| to the favicon at |icon_url| if there is an entry in the // database for |icon_url| and |icon_type|. This occurs when there is a // mapping from a different page URL to |icon_url|. The favicon bitmaps whose // edge sizes most closely match |desired_sizes| from the favicons which were - // just mapped to |page_url| are returned. If |desired_sizes| has a '0' entry, - // the largest favicon bitmap is returned. + // just mapped to |page_urls| are returned. If |desired_sizes| has a '0' + // entry, the largest favicon bitmap is returned. base::CancelableTaskTracker::TaskId UpdateFaviconMappingsAndFetch( - const GURL& page_url, + const std::set<GURL>& page_urls, const GURL& icon_url, favicon_base::IconType icon_type, const std::vector<int>& desired_sizes,
diff --git a/components/infobars/core/infobar_delegate.h b/components/infobars/core/infobar_delegate.h index 513d447..1405106 100644 --- a/components/infobars/core/infobar_delegate.h +++ b/components/infobars/core/infobar_delegate.h
@@ -240,7 +240,7 @@ protected: InfoBarDelegate(); - InfoBar* infobar() const { return infobar_; } + InfoBar* infobar() { return infobar_; } private: // The InfoBar associated with us.
diff --git a/components/invalidation/impl/p2p_invalidator.h b/components/invalidation/impl/p2p_invalidator.h index 2a85655..26076d87 100644 --- a/components/invalidation/impl/p2p_invalidator.h +++ b/components/invalidation/impl/p2p_invalidator.h
@@ -86,9 +86,8 @@ ObjectIdInvalidationMap invalidation_map_; }; -class INVALIDATION_EXPORT P2PInvalidator - : public Invalidator, - public NON_EXPORTED_BASE(notifier::PushClientObserver) { +class INVALIDATION_EXPORT P2PInvalidator : public Invalidator, + public notifier::PushClientObserver { public: // The |send_notification_target| parameter was added to allow us to send // self-notifications in some cases, but not others. The value should be
diff --git a/components/invalidation/impl/push_client_channel.h b/components/invalidation/impl/push_client_channel.h index 85e8a0d..70a6359 100644 --- a/components/invalidation/impl/push_client_channel.h +++ b/components/invalidation/impl/push_client_channel.h
@@ -26,7 +26,7 @@ // routes messages through a PushClient. class INVALIDATION_EXPORT PushClientChannel : public SyncNetworkChannel, - public NON_EXPORTED_BASE(notifier::PushClientObserver) { + public notifier::PushClientObserver { public: // |push_client| is guaranteed to be destroyed only when this object // is destroyed.
diff --git a/components/invalidation/impl/sync_invalidation_listener.h b/components/invalidation/impl/sync_invalidation_listener.h index 85bc467f..5a644f25 100644 --- a/components/invalidation/impl/sync_invalidation_listener.h +++ b/components/invalidation/impl/sync_invalidation_listener.h
@@ -33,7 +33,7 @@ // SyncInvalidationListener is not thread-safe and lives on the sync // thread. class INVALIDATION_EXPORT SyncInvalidationListener - : public NON_EXPORTED_BASE(invalidation::InvalidationListener), + : public invalidation::InvalidationListener, public StateWriter, public SyncNetworkChannel::Observer, public AckHandler {
diff --git a/components/invalidation/impl/sync_system_resources.h b/components/invalidation/impl/sync_system_resources.h index b360086..8a77ec57 100644 --- a/components/invalidation/impl/sync_system_resources.h +++ b/components/invalidation/impl/sync_system_resources.h
@@ -85,7 +85,7 @@ // Implementation of particular network protocol should implement // SendMessage and call NotifyStateChange and DeliverIncomingMessage. class INVALIDATION_EXPORT SyncNetworkChannel - : public NON_EXPORTED_BASE(invalidation::NetworkChannel) { + : public invalidation::NetworkChannel { public: class Observer { public: @@ -211,7 +211,7 @@ }; class INVALIDATION_EXPORT SyncSystemResources - : public NON_EXPORTED_BASE(invalidation::SystemResources) { + : public invalidation::SystemResources { public: SyncSystemResources(SyncNetworkChannel* sync_network_channel, StateWriter* state_writer);
diff --git a/components/keyed_service/core/keyed_service_base_factory.h b/components/keyed_service/core/keyed_service_base_factory.h index 94d01d7..0c6d7c5 100644 --- a/components/keyed_service/core/keyed_service_base_factory.h +++ b/components/keyed_service/core/keyed_service_base_factory.h
@@ -28,8 +28,7 @@ // // This object describes general dependency management between factories while // direct subclasses react to lifecycle events and implement memory management. -class KEYED_SERVICE_EXPORT KeyedServiceBaseFactory - : NON_EXPORTED_BASE(public DependencyNode) { +class KEYED_SERVICE_EXPORT KeyedServiceBaseFactory : public DependencyNode { public: #ifndef NDEBUG // Returns our name. We don't keep track of this in release mode.
diff --git a/components/leveldb_proto/leveldb_database.cc b/components/leveldb_proto/leveldb_database.cc index 9fa1e43..cc65ae0 100644 --- a/components/leveldb_proto/leveldb_database.cc +++ b/components/leveldb_proto/leveldb_database.cc
@@ -4,22 +4,15 @@ #include "components/leveldb_proto/leveldb_database.h" -#include <inttypes.h> - #include <string> #include <vector> #include "base/files/file_path.h" #include "base/files/file_util.h" #include "base/metrics/histogram.h" -#include "base/strings/string_number_conversions.h" #include "base/strings/string_split.h" -#include "base/strings/stringprintf.h" #include "base/sys_info.h" -#include "base/threading/sequenced_task_runner_handle.h" #include "base/threading/thread_checker.h" -#include "base/trace_event/memory_dump_manager.h" -#include "base/trace_event/process_memory_dump.h" #include "third_party/leveldatabase/env_chromium.h" #include "third_party/leveldatabase/src/helpers/memenv/memenv.h" #include "third_party/leveldatabase/src/include/leveldb/cache.h" @@ -40,20 +33,17 @@ return s.ok(); } -LevelDB::LevelDB(const char* client_name) - : open_histogram_(nullptr), client_name_(client_name) { +LevelDB::LevelDB(const char* client_name) : open_histogram_(nullptr) { // Used in lieu of UMA_HISTOGRAM_ENUMERATION because the histogram name is // not a constant. open_histogram_ = base::LinearHistogram::FactoryGet( - std::string("LevelDB.Open.") + client_name_, 1, + std::string("LevelDB.Open.") + client_name, 1, leveldb_env::LEVELDB_STATUS_MAX, leveldb_env::LEVELDB_STATUS_MAX + 1, base::Histogram::kUmaTargetedHistogramFlag); } LevelDB::~LevelDB() { DFAKE_SCOPED_LOCK(thread_checker_); - base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider( - this); } bool LevelDB::InitWithOptions(const base::FilePath& database_dir, @@ -70,13 +60,8 @@ status = leveldb_env::OpenDB(options, path, &db_); } - if (status.ok()) { - base::trace_event::MemoryDumpManager::GetInstance() - ->RegisterDumpProviderWithSequencedTaskRunner( - this, "LevelDB", base::SequencedTaskRunnerHandle::Get(), - base::trace_event::MemoryDumpProvider::Options()); + if (status.ok()) return true; - } LOG(WARNING) << "Unable to open " << database_dir.value() << ": " << status.ToString(); @@ -194,36 +179,4 @@ return false; } -bool LevelDB::OnMemoryDump(const base::trace_event::MemoryDumpArgs& dump_args, - base::trace_event::ProcessMemoryDump* pmd) { - DFAKE_SCOPED_LOCK(thread_checker_); - if (!db_) - return false; - - std::string value; - uint64_t size; - bool res = db_->GetProperty("leveldb.approximate-memory-usage", &value); - DCHECK(res); - res = base::StringToUint64(value, &size); - DCHECK(res); - - base::trace_event::MemoryAllocatorDump* dump = pmd->CreateAllocatorDump( - base::StringPrintf("leveldb/leveldb_proto/0x%" PRIXPTR, - reinterpret_cast<uintptr_t>(db_.get()))); - dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize, - base::trace_event::MemoryAllocatorDump::kUnitsBytes, size); - if (!client_name_.empty() && - dump_args.level_of_detail != - base::trace_event::MemoryDumpLevelOfDetail::BACKGROUND) { - dump->AddString("client_name", "", client_name_); - } - - // All leveldb databases are already dumped by leveldb_env::DBTracker. Add - // an edge to avoid double counting. - pmd->AddSuballocation(dump->guid(), - leveldb_env::DBTracker::GetMemoryDumpName(db_.get())); - - return true; -} - } // namespace leveldb_proto
diff --git a/components/leveldb_proto/leveldb_database.h b/components/leveldb_proto/leveldb_database.h index 78b03571..f01bf14 100644 --- a/components/leveldb_proto/leveldb_database.h +++ b/components/leveldb_proto/leveldb_database.h
@@ -13,7 +13,6 @@ #include "base/macros.h" #include "base/strings/string_split.h" #include "base/threading/thread_collision_warner.h" -#include "base/trace_event/memory_dump_provider.h" #include "components/leveldb_proto/options.h" #include "third_party/leveldatabase/env_chromium.h" @@ -34,14 +33,14 @@ // Interacts with the LevelDB third party module. // Once constructed, function calls and destruction should all occur on the // same thread (not necessarily the same as the constructor). -class LevelDB : public base::trace_event::MemoryDumpProvider { +class LevelDB { public: // Constructor. Does *not* open a leveldb - only initialize this class. // |client_name| is the name of the "client" that owns this instance. Used // for UMA statics as so: LevelDB.<value>.<client name>. It is best to not // change once shipped. explicit LevelDB(const char* client_name); - ~LevelDB() override; + virtual ~LevelDB(); // Initializes a leveldb with the given options. If |options.database_dir| is // empty, this opens an in-memory db. @@ -55,10 +54,6 @@ static bool Destroy(const base::FilePath& database_dir); - // base::trace_event::MemoryDumpProvider implementation. - bool OnMemoryDump(const base::trace_event::MemoryDumpArgs& dump_args, - base::trace_event::ProcessMemoryDump* pmd) override; - protected: virtual bool InitWithOptions(const base::FilePath& database_dir, const leveldb_env::Options& options); @@ -74,8 +69,6 @@ std::unique_ptr<leveldb::Cache> custom_block_cache_; std::unique_ptr<leveldb::DB> db_; base::HistogramBase* open_histogram_; - // Name of the client shown in chrome://tracing. - std::string client_name_; DISALLOW_COPY_AND_ASSIGN(LevelDB); };
diff --git a/components/leveldb_proto/proto_database_impl_unittest.cc b/components/leveldb_proto/proto_database_impl_unittest.cc index 6e1bea1..22a79a8 100644 --- a/components/leveldb_proto/proto_database_impl_unittest.cc +++ b/components/leveldb_proto/proto_database_impl_unittest.cc
@@ -18,8 +18,6 @@ #include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "base/threading/thread.h" -#include "base/trace_event/memory_dump_manager.h" -#include "base/trace_event/process_memory_dump.h" #include "components/leveldb_proto/leveldb_database.h" #include "components/leveldb_proto/testing/proto/test.pb.h" #include "testing/gmock/include/gmock/gmock.h" @@ -547,8 +545,6 @@ // entries. If |close_after_save| is true, the database will be closed after // saving and then re-opened to ensure that the data is properly persisted. void TestLevelDBSaveAndLoad(bool close_after_save) { - base::MessageLoop main_loop; - ScopedTempDir temp_dir; ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); @@ -611,8 +607,6 @@ } TEST(ProtoDatabaseImplLevelDBTest, TestMemoryDatabase) { - base::MessageLoop main_loop; - std::unique_ptr<LevelDB> db(new LevelDB(kTestLevelDBClientName)); std::vector<std::string> load_entries; @@ -633,28 +627,4 @@ EXPECT_EQ(1u, second_load_entries.size()); } -TEST(ProtoDatabaseImplLevelDBTest, TestOnMemoryDumpEmitsData) { - base::MessageLoop main_loop; - std::unique_ptr<LevelDB> db(new LevelDB(kTestLevelDBClientName)); - std::vector<std::string> load_entries; - ASSERT_TRUE(db->Init(base::FilePath())); - KeyValueVector save_entries(1, std::make_pair("foo", "bar")); - KeyVector remove_keys; - ASSERT_TRUE(db->Save(save_entries, remove_keys)); - - base::trace_event::MemoryDumpArgs dump_args = { - base::trace_event::MemoryDumpLevelOfDetail::DETAILED}; - std::unique_ptr<base::trace_event::ProcessMemoryDump> process_memory_dump( - new base::trace_event::ProcessMemoryDump(nullptr, dump_args)); - db->OnMemoryDump(dump_args, process_memory_dump.get()); - - size_t leveldb_dump_count = 0; - for (const auto& dump : process_memory_dump->allocator_dumps()) { - if (dump.first.find("leveldb/leveldb_proto/") == 0) { - leveldb_dump_count++; - } - } - ASSERT_EQ(1u, leveldb_dump_count); -} - } // namespace leveldb_proto
diff --git a/components/metrics/metrics_log.cc b/components/metrics/metrics_log.cc index ee3de12..412179394 100644 --- a/components/metrics/metrics_log.cc +++ b/components/metrics/metrics_log.cc
@@ -143,7 +143,7 @@ UserActionEventProto* user_action = uma_proto_.add_user_action_event(); user_action->set_name_hash(Hash(key)); - user_action->set_time(GetCurrentTime()); + user_action->set_time_sec(GetCurrentTime()); } void MetricsLog::RecordCoreSystemProfile(MetricsServiceClient* client,
diff --git a/components/metrics/proto/omnibox_event.proto b/components/metrics/proto/omnibox_event.proto index 1998a08..7f5b045 100644 --- a/components/metrics/proto/omnibox_event.proto +++ b/components/metrics/proto/omnibox_event.proto
@@ -23,7 +23,7 @@ // These numbers are only comparable within a session. To sequence events // across sessions, order by the |session_id| from the // ChromeUserMetricsExtension message. - optional int64 time = 1; + optional int64 time_sec = 1; // The id of the originating tab for this omnibox interaction. // This is the current tab *unless* the user opened the target in a new tab.
diff --git a/components/metrics/proto/perf_stat.proto b/components/metrics/proto/perf_stat.proto index bdfb3c45..54fdf27 100644 --- a/components/metrics/proto/perf_stat.proto +++ b/components/metrics/proto/perf_stat.proto
@@ -23,7 +23,7 @@ // Represents one line of "perf stat" output. // Next tag: 4 - message PerfStatLine{ + message PerfStatLine { // Time since the start of the "perf stat" command, in milliseconds. // // When running "perf stat" and printing the counters at the end, this is @@ -47,6 +47,6 @@ // This string should also appear as part of |PerfStatProto::command_line|. // "perf stat" will preserve the event name exactly as it is passed in via // the command line. - optional string event = 3; + optional string event_name = 3; } }
diff --git a/components/metrics/proto/user_action_event.proto b/components/metrics/proto/user_action_event.proto index b7baa17..87f76658 100644 --- a/components/metrics/proto/user_action_event.proto +++ b/components/metrics/proto/user_action_event.proto
@@ -25,5 +25,5 @@ // These numbers are only comparable within a session. To sequence events // across sessions, order by the |session_id| from the // ChromeUserMetricsExtension message. - optional int64 time = 2; + optional int64 time_sec = 2; }
diff --git a/components/ntp_snippets/BUILD.gn b/components/ntp_snippets/BUILD.gn index 84b1769..329cd22 100644 --- a/components/ntp_snippets/BUILD.gn +++ b/components/ntp_snippets/BUILD.gn
@@ -42,13 +42,13 @@ "content_suggestions_provider.h", "content_suggestions_service.cc", "content_suggestions_service.h", + "contextual/contextual_content_suggestions_service.cc", + "contextual/contextual_content_suggestions_service.h", "contextual/contextual_json_request.cc", "contextual/contextual_json_request.h", "contextual/contextual_suggestions_fetcher.h", "contextual/contextual_suggestions_fetcher_impl.cc", "contextual/contextual_suggestions_fetcher_impl.h", - "contextual/contextual_suggestions_source.cc", - "contextual/contextual_suggestions_source.h", "features.cc", "features.h", "ntp_snippets_constants.cc", @@ -182,9 +182,9 @@ "category_unittest.cc", "content_suggestions_metrics_unittest.cc", "content_suggestions_service_unittest.cc", + "contextual/contextual_content_suggestions_service_unittest.cc", "contextual/contextual_json_request_unittest.cc", "contextual/contextual_suggestions_fetcher_impl_unittest.cc", - "contextual/contextual_suggestions_source_unittest.cc", "offline_pages/recent_tab_suggestions_provider_unittest.cc", "physical_web_pages/physical_web_page_suggestions_provider_unittest.cc", "reading_list/reading_list_suggestions_provider_unittest.cc",
diff --git a/components/ntp_snippets/content_suggestions_service.h b/components/ntp_snippets/content_suggestions_service.h index aa9837d..6783c341 100644 --- a/components/ntp_snippets/content_suggestions_service.h +++ b/components/ntp_snippets/content_suggestions_service.h
@@ -26,7 +26,6 @@ #include "components/ntp_snippets/category_rankers/category_ranker.h" #include "components/ntp_snippets/category_status.h" #include "components/ntp_snippets/content_suggestions_provider.h" -#include "components/ntp_snippets/contextual/contextual_suggestions_source.h" #include "components/ntp_snippets/remote/remote_suggestions_scheduler.h" #include "components/ntp_snippets/user_classifier.h" #include "components/signin/core/browser/signin_manager.h" @@ -246,12 +245,6 @@ // child account. bool AreRemoteSuggestionsManagedByCustodian() const; - void set_contextual_suggestions_source( - std::unique_ptr<ContextualSuggestionsSource> - contextual_suggestions_source) { - contextual_suggestions_source_ = std::move(contextual_suggestions_source); - } - // The reference to the RemoteSuggestionsProvider provider should // only be set by the factory and only used for debugging. // TODO(jkrcal) The way we deal with the circular dependency feels wrong. @@ -281,11 +274,6 @@ CategoryRanker* category_ranker() { return category_ranker_.get(); } - ContextualSuggestionsSource* contextual_suggestions_source() { - DCHECK(contextual_suggestions_source_); - return contextual_suggestions_source_.get(); - } - private: friend class ContentSuggestionsServiceTest; @@ -431,9 +419,6 @@ // Provides order for categories. std::unique_ptr<CategoryRanker> category_ranker_; - // Fetches and caches contextual suggestions for a given URL. - std::unique_ptr<ContextualSuggestionsSource> contextual_suggestions_source_; - DISALLOW_COPY_AND_ASSIGN(ContentSuggestionsService); };
diff --git a/components/ntp_snippets/contextual/contextual_content_suggestions_service.cc b/components/ntp_snippets/contextual/contextual_content_suggestions_service.cc new file mode 100644 index 0000000..4094976 --- /dev/null +++ b/components/ntp_snippets/contextual/contextual_content_suggestions_service.cc
@@ -0,0 +1,81 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/ntp_snippets/contextual/contextual_content_suggestions_service.h" + +#include <iterator> +#include <memory> +#include <set> +#include <utility> + +#include "base/bind.h" +#include "base/memory/ptr_util.h" +#include "components/ntp_snippets/remote/cached_image_fetcher.h" +#include "components/ntp_snippets/remote/remote_suggestions_database.h" +#include "components/ntp_snippets/remote/remote_suggestions_provider_impl.h" +#include "ui/gfx/image/image.h" + +namespace ntp_snippets { + +ContextualContentSuggestionsService::ContextualContentSuggestionsService( + std::unique_ptr<ContextualSuggestionsFetcher> + contextual_suggestions_fetcher, + std::unique_ptr<CachedImageFetcher> image_fetcher, + std::unique_ptr<RemoteSuggestionsDatabase> contextual_suggestions_database) + : contextual_suggestions_database_( + std::move(contextual_suggestions_database)), + contextual_suggestions_fetcher_( + std::move(contextual_suggestions_fetcher)), + image_fetcher_(std::move(image_fetcher)) {} + +ContextualContentSuggestionsService::~ContextualContentSuggestionsService() = + default; + +void ContextualContentSuggestionsService::FetchContextualSuggestions( + const GURL& url, + FetchContextualSuggestionsCallback callback) { + contextual_suggestions_fetcher_->FetchContextualSuggestions( + url, + base::BindOnce( + &ContextualContentSuggestionsService::DidFetchContextualSuggestions, + base::Unretained(this), url, std::move(callback))); +} + +void ContextualContentSuggestionsService::FetchContextualSuggestionImage( + const ContentSuggestion::ID& suggestion_id, + ImageFetchedCallback callback) { + const std::string& id_within_category = suggestion_id.id_within_category(); + auto image_url_iterator = image_url_by_id_.find(id_within_category); + if (image_url_iterator != image_url_by_id_.end()) { + GURL image_url = image_url_iterator->second; + image_fetcher_->FetchSuggestionImage(suggestion_id, image_url, + std::move(callback)); + } else { + DVLOG(1) << "FetchContextualSuggestionImage unknown image" + << " id_within_category: " << id_within_category; + std::move(callback).Run(gfx::Image()); + } +} + +// TODO(gaschler): Cache contextual suggestions at run-time. +void ContextualContentSuggestionsService::DidFetchContextualSuggestions( + const GURL& url, + FetchContextualSuggestionsCallback callback, + Status status, + ContextualSuggestionsFetcher::OptionalSuggestions fetched_suggestions) { + std::vector<ContentSuggestion> suggestions; + if (fetched_suggestions.has_value()) { + for (const std::unique_ptr<RemoteSuggestion>& suggestion : + fetched_suggestions.value()) { + suggestions.emplace_back(suggestion->ToContentSuggestion( + Category::FromKnownCategory(KnownCategories::CONTEXTUAL))); + ContentSuggestion::ID id = suggestions.back().id(); + GURL image_url = suggestion->salient_image_url(); + image_url_by_id_[id.id_within_category()] = image_url; + } + } + std::move(callback).Run(status, url, std::move(suggestions)); +} + +} // namespace ntp_snippets
diff --git a/components/ntp_snippets/contextual/contextual_content_suggestions_service.h b/components/ntp_snippets/contextual/contextual_content_suggestions_service.h new file mode 100644 index 0000000..e24fa661 --- /dev/null +++ b/components/ntp_snippets/contextual/contextual_content_suggestions_service.h
@@ -0,0 +1,76 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_NTP_SNIPPETS_CONTEXTUAL_CONTEXTUAL_CONTENT_SUGGESTIONS_SERVICE_H_ +#define COMPONENTS_NTP_SNIPPETS_CONTEXTUAL_CONTEXTUAL_CONTENT_SUGGESTIONS_SERVICE_H_ + +#include <map> +#include <memory> +#include <string> +#include <vector> + +#include "base/callback.h" +#include "base/optional.h" +#include "components/image_fetcher/core/image_fetcher.h" +#include "components/keyed_service/core/keyed_service.h" +#include "components/ntp_snippets/callbacks.h" +#include "components/ntp_snippets/contextual/contextual_suggestions_fetcher.h" + +namespace ntp_snippets { + +class CachedImageFetcher; +class RemoteSuggestionsDatabase; + +// Retrieves contextual suggestions for a given URL and fetches images +// for contextual suggestion, using caching. +class ContextualContentSuggestionsService : public KeyedService { + public: + ContextualContentSuggestionsService( + std::unique_ptr<ContextualSuggestionsFetcher> + contextual_suggestions_fetcher, + std::unique_ptr<CachedImageFetcher> image_fetcher, + std::unique_ptr<RemoteSuggestionsDatabase> + contextual_suggestions_database); + ~ContextualContentSuggestionsService() override; + + using FetchContextualSuggestionsCallback = + base::OnceCallback<void(Status status_code, + const GURL& url, + std::vector<ContentSuggestion> suggestions)>; + + // Asynchronously fetches contextual suggestions for the given URL. + void FetchContextualSuggestions(const GURL& url, + FetchContextualSuggestionsCallback callback); + + // Fetches an image for a given contextual suggestion ID. + // Asynchronous if cache or network is queried. + void FetchContextualSuggestionImage( + const ContentSuggestion::ID& suggestion_id, + ImageFetchedCallback callback); + + private: + void DidFetchContextualSuggestions( + const GURL& url, + FetchContextualSuggestionsCallback callback, + Status status, + ContextualSuggestionsFetcher::OptionalSuggestions fetched_suggestions); + + // Cache for images of contextual suggestions, needed by CachedImageFetcher. + std::unique_ptr<RemoteSuggestionsDatabase> contextual_suggestions_database_; + + // Performs actual network request to fetch contextual suggestions. + std::unique_ptr<ContextualSuggestionsFetcher> contextual_suggestions_fetcher_; + + std::unique_ptr<CachedImageFetcher> image_fetcher_; + + // Look up by ContentSuggestion::ID::id_within_category() aka std::string to + // get image URL. + std::map<std::string, GURL> image_url_by_id_; + + DISALLOW_COPY_AND_ASSIGN(ContextualContentSuggestionsService); +}; + +} // namespace ntp_snippets + +#endif // COMPONENTS_NTP_SNIPPETS_CONTEXTUAL_CONTEXTUAL_CONTENT_SUGGESTIONS_SERVICE_H_
diff --git a/components/ntp_snippets/contextual/contextual_content_suggestions_service_unittest.cc b/components/ntp_snippets/contextual/contextual_content_suggestions_service_unittest.cc new file mode 100644 index 0000000..40e34c2 --- /dev/null +++ b/components/ntp_snippets/contextual/contextual_content_suggestions_service_unittest.cc
@@ -0,0 +1,244 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/ntp_snippets/contextual/contextual_content_suggestions_service.h" + +#include <memory> +#include <utility> +#include <vector> + +#include "base/bind.h" +#include "base/macros.h" +#include "base/memory/ptr_util.h" +#include "base/message_loop/message_loop.h" +#include "base/run_loop.h" +#include "base/test/mock_callback.h" +#include "components/image_fetcher/core/image_fetcher_impl.h" +#include "components/ntp_snippets/category_info.h" +#include "components/ntp_snippets/content_suggestion.h" +#include "components/ntp_snippets/contextual/contextual_suggestions_fetcher.h" +#include "components/ntp_snippets/remote/cached_image_fetcher.h" +#include "components/ntp_snippets/remote/json_to_categories.h" +#include "components/ntp_snippets/remote/remote_suggestion.h" +#include "components/ntp_snippets/remote/remote_suggestion_builder.h" +#include "components/ntp_snippets/remote/remote_suggestions_database.h" +#include "components/prefs/pref_registry_simple.h" +#include "components/prefs/testing_pref_service.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/gfx/image/image.h" +#include "ui/gfx/image/image_unittest_util.h" + +using testing::_; +using testing::AllOf; +using testing::ElementsAre; +using testing::IsEmpty; +using testing::Mock; +using testing::Pointee; +using testing::Property; + +namespace ntp_snippets { + +namespace { + +ACTION_TEMPLATE(MoveArg, + HAS_1_TEMPLATE_PARAMS(int, k), + AND_1_VALUE_PARAMS(out)) { + *out = std::move(*::testing::get<k>(args)); +}; + +// Always fetches the result that was set by SetFakeResponse. +class FakeContextualSuggestionsFetcher : public ContextualSuggestionsFetcher { + public: + void FetchContextualSuggestions( + const GURL& url, + SuggestionsAvailableCallback callback) override { + std::move(callback).Run(fake_status_, std::move(fake_suggestions_)); + fake_suggestions_ = base::nullopt; + } + + void SetFakeResponse(Status fake_status, + OptionalSuggestions fake_suggestions) { + fake_status_ = fake_status; + fake_suggestions_ = std::move(fake_suggestions); + } + + const std::string& GetLastStatusForTesting() const override { return empty_; } + const std::string& GetLastJsonForTesting() const override { return empty_; } + const GURL& GetFetchUrlForTesting() const override { return empty_url_; } + + private: + std::string empty_; + GURL empty_url_; + Status fake_status_ = Status::Success(); + OptionalSuggestions fake_suggestions_; +}; + +// Always fetches a fake image if the given URL is valid. +class FakeCachedImageFetcher : public CachedImageFetcher { + public: + FakeCachedImageFetcher(PrefService* pref_service) + : CachedImageFetcher(std::unique_ptr<image_fetcher::ImageFetcher>(), + pref_service, + nullptr){}; + + void FetchSuggestionImage(const ContentSuggestion::ID&, + const GURL& image_url, + ImageFetchedCallback callback) override { + gfx::Image image; + if (image_url.is_valid()) { + image = gfx::test::CreateImage(); + } + std::move(callback).Run(image); + } +}; + +// GMock does not support movable-only types (ContentSuggestion). +// Instead WrappedRun is used as callback and it redirects the call to a +// method without movable-only types, which is then mocked. +class MockFetchContextualSuggestionsCallback { + public: + void WrappedRun(Status status, + const GURL& url, + std::vector<ContentSuggestion> suggestions) { + Run(status, url, &suggestions); + } + + ContextualContentSuggestionsService::FetchContextualSuggestionsCallback + ToOnceCallback() { + return base::BindOnce(&MockFetchContextualSuggestionsCallback::WrappedRun, + base::Unretained(this)); + } + + MOCK_METHOD3(Run, + void(Status status_code, + const GURL& url, + std::vector<ContentSuggestion>* suggestions)); +}; + +} // namespace + +class ContextualContentSuggestionsServiceTest : public testing::Test { + public: + ContextualContentSuggestionsServiceTest() { + RequestThrottler::RegisterProfilePrefs(pref_service_.registry()); + std::unique_ptr<FakeContextualSuggestionsFetcher> fetcher = + base::MakeUnique<FakeContextualSuggestionsFetcher>(); + fetcher_ = fetcher.get(); + source_ = base::MakeUnique<ContextualContentSuggestionsService>( + std::move(fetcher), + base::MakeUnique<FakeCachedImageFetcher>(&pref_service_), + std::unique_ptr<RemoteSuggestionsDatabase>()); + } + + FakeContextualSuggestionsFetcher* fetcher() { return fetcher_; } + ContextualContentSuggestionsService* source() { return source_.get(); } + + private: + FakeContextualSuggestionsFetcher* fetcher_; + base::MessageLoop message_loop_; + TestingPrefServiceSimple pref_service_; + std::unique_ptr<ContextualContentSuggestionsService> source_; + + DISALLOW_COPY_AND_ASSIGN(ContextualContentSuggestionsServiceTest); +}; + +TEST_F(ContextualContentSuggestionsServiceTest, + ShouldFetchContextualSuggestion) { + MockFetchContextualSuggestionsCallback mock_suggestions_callback; + const std::string kValidFromUrl = "http://some.url"; + const std::string kToUrl = "http://another.url"; + ContextualSuggestionsFetcher::OptionalSuggestions remote_suggestions = + RemoteSuggestion::PtrVector(); + remote_suggestions->push_back(test::RemoteSuggestionBuilder() + .AddId(kToUrl) + .SetUrl(kToUrl) + .SetAmpUrl(kToUrl) + .Build()); + fetcher()->SetFakeResponse(Status::Success(), std::move(remote_suggestions)); + EXPECT_CALL(mock_suggestions_callback, + Run(Property(&Status::IsSuccess, true), GURL(kValidFromUrl), + Pointee(ElementsAre(AllOf( + Property(&ContentSuggestion::id, + Property(&ContentSuggestion::ID::category, + Category::FromKnownCategory( + KnownCategories::CONTEXTUAL))), + Property(&ContentSuggestion::url, GURL(kToUrl))))))); + source()->FetchContextualSuggestions( + GURL(kValidFromUrl), mock_suggestions_callback.ToOnceCallback()); + base::RunLoop().RunUntilIdle(); +} + +TEST_F(ContextualContentSuggestionsServiceTest, + ShouldRunCallbackOnEmptyResults) { + MockFetchContextualSuggestionsCallback mock_suggestions_callback; + const std::string kEmpty; + fetcher()->SetFakeResponse(Status::Success(), RemoteSuggestion::PtrVector()); + EXPECT_CALL(mock_suggestions_callback, Run(Property(&Status::IsSuccess, true), + GURL(kEmpty), Pointee(IsEmpty()))); + source()->FetchContextualSuggestions( + GURL(kEmpty), mock_suggestions_callback.ToOnceCallback()); + base::RunLoop().RunUntilIdle(); +} + +TEST_F(ContextualContentSuggestionsServiceTest, ShouldRunCallbackOnError) { + MockFetchContextualSuggestionsCallback mock_suggestions_callback; + const std::string kEmpty; + fetcher()->SetFakeResponse(Status(StatusCode::TEMPORARY_ERROR, ""), + RemoteSuggestion::PtrVector()); + EXPECT_CALL(mock_suggestions_callback, + Run(Property(&Status::IsSuccess, false), GURL(kEmpty), + Pointee(IsEmpty()))); + source()->FetchContextualSuggestions( + GURL(kEmpty), mock_suggestions_callback.ToOnceCallback()); + base::RunLoop().RunUntilIdle(); +} + +TEST_F(ContextualContentSuggestionsServiceTest, + ShouldFetchEmptyImageIfNotFound) { + base::MockCallback<ImageFetchedCallback> mock_image_fetched_callback; + const std::string kEmpty; + ContentSuggestion::ID id( + Category::FromKnownCategory(KnownCategories::CONTEXTUAL), kEmpty); + EXPECT_CALL(mock_image_fetched_callback, + Run(Property(&gfx::Image::IsEmpty, true))); + source()->FetchContextualSuggestionImage(id, + mock_image_fetched_callback.Get()); + // TODO(gaschler): Verify with a mock that the image fetcher is not called if + // the id is unknown. + base::RunLoop().RunUntilIdle(); +} + +TEST_F(ContextualContentSuggestionsServiceTest, + ShouldFetchImageForPreviouslyFetchedSuggestion) { + const std::string kValidFromUrl = "http://some.url"; + const std::string kToUrl = "http://another.url"; + const std::string kValidImageUrl = "http://some.url/image.png"; + ContextualSuggestionsFetcher::OptionalSuggestions remote_suggestions = + RemoteSuggestion::PtrVector(); + remote_suggestions->push_back(test::RemoteSuggestionBuilder() + .AddId(kToUrl) + .SetUrl(kToUrl) + .SetAmpUrl(kToUrl) + .SetImageUrl(kValidImageUrl) + .Build()); + fetcher()->SetFakeResponse(Status::Success(), std::move(remote_suggestions)); + MockFetchContextualSuggestionsCallback mock_suggestions_callback; + std::vector<ContentSuggestion> suggestions; + EXPECT_CALL(mock_suggestions_callback, Run(_, _, _)) + .WillOnce(MoveArg<2>(&suggestions)); + source()->FetchContextualSuggestions( + GURL(kValidFromUrl), mock_suggestions_callback.ToOnceCallback()); + base::RunLoop().RunUntilIdle(); + + ASSERT_THAT(suggestions, Not(IsEmpty())); + base::MockCallback<ImageFetchedCallback> mock_image_fetched_callback; + EXPECT_CALL(mock_image_fetched_callback, + Run(Property(&gfx::Image::IsEmpty, false))); + source()->FetchContextualSuggestionImage(suggestions[0].id(), + mock_image_fetched_callback.Get()); + base::RunLoop().RunUntilIdle(); +} + +} // namespace ntp_snippets
diff --git a/components/ntp_snippets/contextual/contextual_suggestions_source.cc b/components/ntp_snippets/contextual/contextual_suggestions_source.cc deleted file mode 100644 index 58b30d5..0000000 --- a/components/ntp_snippets/contextual/contextual_suggestions_source.cc +++ /dev/null
@@ -1,80 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/ntp_snippets/contextual/contextual_suggestions_source.h" - -#include <iterator> -#include <memory> -#include <set> -#include <utility> - -#include "base/bind.h" -#include "base/memory/ptr_util.h" -#include "components/ntp_snippets/remote/cached_image_fetcher.h" -#include "components/ntp_snippets/remote/remote_suggestions_database.h" -#include "components/ntp_snippets/remote/remote_suggestions_provider_impl.h" -#include "ui/gfx/image/image.h" - -namespace ntp_snippets { - -// TODO(gaschler): Add unit tests. -ContextualSuggestionsSource::ContextualSuggestionsSource( - std::unique_ptr<ContextualSuggestionsFetcher> - contextual_suggestions_fetcher, - std::unique_ptr<CachedImageFetcher> image_fetcher, - std::unique_ptr<RemoteSuggestionsDatabase> contextual_suggestions_database) - : contextual_suggestions_database_( - std::move(contextual_suggestions_database)), - contextual_suggestions_fetcher_( - std::move(contextual_suggestions_fetcher)), - image_fetcher_(std::move(image_fetcher)) {} - -ContextualSuggestionsSource::~ContextualSuggestionsSource() = default; - -void ContextualSuggestionsSource::FetchContextualSuggestions( - const GURL& url, - FetchContextualSuggestionsCallback callback) { - contextual_suggestions_fetcher_->FetchContextualSuggestions( - url, base::BindOnce( - &ContextualSuggestionsSource::DidFetchContextualSuggestions, - base::Unretained(this), url, std::move(callback))); -} - -void ContextualSuggestionsSource::FetchContextualSuggestionImage( - const ContentSuggestion::ID& suggestion_id, - ImageFetchedCallback callback) { - const std::string& id_within_category = suggestion_id.id_within_category(); - auto image_url_iterator = image_url_by_id_.find(id_within_category); - if (image_url_iterator != image_url_by_id_.end()) { - GURL image_url = image_url_iterator->second; - image_fetcher_->FetchSuggestionImage(suggestion_id, image_url, - std::move(callback)); - } else { - DVLOG(1) << "FetchContextualSuggestionImage unknown image" - << " id_within_category: " << id_within_category; - std::move(callback).Run(gfx::Image()); - } -} - -// TODO(gaschler): Cache contextual suggestions at run-time. -void ContextualSuggestionsSource::DidFetchContextualSuggestions( - const GURL& url, - FetchContextualSuggestionsCallback callback, - Status status, - ContextualSuggestionsFetcher::OptionalSuggestions fetched_suggestions) { - std::vector<ContentSuggestion> suggestions; - if (fetched_suggestions.has_value()) { - for (const std::unique_ptr<RemoteSuggestion>& suggestion : - fetched_suggestions.value()) { - suggestions.emplace_back(suggestion->ToContentSuggestion( - Category::FromKnownCategory(KnownCategories::CONTEXTUAL))); - ContentSuggestion::ID id = suggestions.back().id(); - GURL image_url = suggestion->salient_image_url(); - image_url_by_id_[id.id_within_category()] = image_url; - } - } - std::move(callback).Run(status, url, std::move(suggestions)); -} - -} // namespace ntp_snippets
diff --git a/components/ntp_snippets/contextual/contextual_suggestions_source.h b/components/ntp_snippets/contextual/contextual_suggestions_source.h deleted file mode 100644 index 859ecf7..0000000 --- a/components/ntp_snippets/contextual/contextual_suggestions_source.h +++ /dev/null
@@ -1,74 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_NTP_SNIPPETS_CONTEXTUAL_CONTEXTUAL_SUGGESTIONS_SOURCE_H_ -#define COMPONENTS_NTP_SNIPPETS_CONTEXTUAL_CONTEXTUAL_SUGGESTIONS_SOURCE_H_ - -#include <map> -#include <memory> -#include <string> -#include <vector> - -#include "base/callback.h" -#include "base/optional.h" -#include "components/image_fetcher/core/image_fetcher.h" -#include "components/ntp_snippets/callbacks.h" -#include "components/ntp_snippets/contextual/contextual_suggestions_fetcher.h" - -namespace ntp_snippets { - -class CachedImageFetcher; -class RemoteSuggestionsDatabase; - -// Retrieves contextual suggestions for a given URL and fetches images -// for contextual suggestion, using caching. -class ContextualSuggestionsSource { - public: - ContextualSuggestionsSource(std::unique_ptr<ContextualSuggestionsFetcher> - contextual_suggestions_fetcher, - std::unique_ptr<CachedImageFetcher> image_fetcher, - std::unique_ptr<RemoteSuggestionsDatabase> - contextual_suggestions_database); - ~ContextualSuggestionsSource(); - - using FetchContextualSuggestionsCallback = - base::OnceCallback<void(Status status_code, - const GURL& url, - std::vector<ContentSuggestion> suggestions)>; - - // Asynchronously fetches contextual suggestions for the given URL. - void FetchContextualSuggestions(const GURL& url, - FetchContextualSuggestionsCallback callback); - - // Fetches an image for a given contextual suggestion ID. - // Asynchronous if cache or network is queried. - void FetchContextualSuggestionImage( - const ContentSuggestion::ID& suggestion_id, - ImageFetchedCallback callback); - - private: - void DidFetchContextualSuggestions( - const GURL& url, - FetchContextualSuggestionsCallback callback, - Status status, - ContextualSuggestionsFetcher::OptionalSuggestions fetched_suggestions); - - // Cache for images of contextual suggestions, needed by CachedImageFetcher. - std::unique_ptr<RemoteSuggestionsDatabase> contextual_suggestions_database_; - - // Performs actual network request to fetch contextual suggestions. - std::unique_ptr<ContextualSuggestionsFetcher> contextual_suggestions_fetcher_; - - std::unique_ptr<CachedImageFetcher> image_fetcher_; - - // Look up by ContentSuggestion::ID::id_within_category() aka std::string to - // get image URL. - std::map<std::string, GURL> image_url_by_id_; - - DISALLOW_COPY_AND_ASSIGN(ContextualSuggestionsSource); -}; - -} // namespace ntp_snippets - -#endif // COMPONENTS_NTP_SNIPPETS_CONTEXTUAL_CONTEXTUAL_SUGGESTIONS_SOURCE_H_
diff --git a/components/ntp_snippets/contextual/contextual_suggestions_source_unittest.cc b/components/ntp_snippets/contextual/contextual_suggestions_source_unittest.cc deleted file mode 100644 index f6c5b869..0000000 --- a/components/ntp_snippets/contextual/contextual_suggestions_source_unittest.cc +++ /dev/null
@@ -1,241 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/ntp_snippets/contextual/contextual_suggestions_source.h" - -#include <memory> -#include <utility> -#include <vector> - -#include "base/bind.h" -#include "base/macros.h" -#include "base/memory/ptr_util.h" -#include "base/message_loop/message_loop.h" -#include "base/run_loop.h" -#include "base/test/mock_callback.h" -#include "components/image_fetcher/core/image_fetcher_impl.h" -#include "components/ntp_snippets/category_info.h" -#include "components/ntp_snippets/content_suggestion.h" -#include "components/ntp_snippets/contextual/contextual_suggestions_fetcher.h" -#include "components/ntp_snippets/remote/cached_image_fetcher.h" -#include "components/ntp_snippets/remote/json_to_categories.h" -#include "components/ntp_snippets/remote/remote_suggestion.h" -#include "components/ntp_snippets/remote/remote_suggestion_builder.h" -#include "components/ntp_snippets/remote/remote_suggestions_database.h" -#include "components/prefs/pref_registry_simple.h" -#include "components/prefs/testing_pref_service.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "ui/gfx/image/image.h" -#include "ui/gfx/image/image_unittest_util.h" - -using testing::_; -using testing::AllOf; -using testing::ElementsAre; -using testing::IsEmpty; -using testing::Mock; -using testing::Pointee; -using testing::Property; - -namespace ntp_snippets { - -namespace { - -ACTION_TEMPLATE(MoveArg, - HAS_1_TEMPLATE_PARAMS(int, k), - AND_1_VALUE_PARAMS(out)) { - *out = std::move(*::testing::get<k>(args)); -}; - -// Always fetches the result that was set by SetFakeResponse. -class FakeContextualSuggestionsFetcher : public ContextualSuggestionsFetcher { - public: - void FetchContextualSuggestions( - const GURL& url, - SuggestionsAvailableCallback callback) override { - std::move(callback).Run(fake_status_, std::move(fake_suggestions_)); - fake_suggestions_ = base::nullopt; - } - - void SetFakeResponse(Status fake_status, - OptionalSuggestions fake_suggestions) { - fake_status_ = fake_status; - fake_suggestions_ = std::move(fake_suggestions); - } - - const std::string& GetLastStatusForTesting() const override { return empty_; } - const std::string& GetLastJsonForTesting() const override { return empty_; } - const GURL& GetFetchUrlForTesting() const override { return empty_url_; } - - private: - std::string empty_; - GURL empty_url_; - Status fake_status_ = Status::Success(); - OptionalSuggestions fake_suggestions_; -}; - -// Always fetches a fake image if the given URL is valid. -class FakeCachedImageFetcher : public CachedImageFetcher { - public: - FakeCachedImageFetcher(PrefService* pref_service) - : CachedImageFetcher(std::unique_ptr<image_fetcher::ImageFetcher>(), - pref_service, - nullptr){}; - - void FetchSuggestionImage(const ContentSuggestion::ID&, - const GURL& image_url, - ImageFetchedCallback callback) override { - gfx::Image image; - if (image_url.is_valid()) { - image = gfx::test::CreateImage(); - } - std::move(callback).Run(image); - } -}; - -// GMock does not support movable-only types (ContentSuggestion). -// Instead WrappedRun is used as callback and it redirects the call to a -// method without movable-only types, which is then mocked. -class MockFetchContextualSuggestionsCallback { - public: - void WrappedRun(Status status, - const GURL& url, - std::vector<ContentSuggestion> suggestions) { - Run(status, url, &suggestions); - } - - ContextualSuggestionsSource::FetchContextualSuggestionsCallback - ToOnceCallback() { - return base::BindOnce(&MockFetchContextualSuggestionsCallback::WrappedRun, - base::Unretained(this)); - } - - MOCK_METHOD3(Run, - void(Status status_code, - const GURL& url, - std::vector<ContentSuggestion>* suggestions)); -}; - -} // namespace - -class ContextualSuggestionsSourceTest : public testing::Test { - public: - ContextualSuggestionsSourceTest() { - RequestThrottler::RegisterProfilePrefs(pref_service_.registry()); - std::unique_ptr<FakeContextualSuggestionsFetcher> fetcher = - base::MakeUnique<FakeContextualSuggestionsFetcher>(); - fetcher_ = fetcher.get(); - source_ = base::MakeUnique<ContextualSuggestionsSource>( - std::move(fetcher), - base::MakeUnique<FakeCachedImageFetcher>(&pref_service_), - std::unique_ptr<RemoteSuggestionsDatabase>()); - } - - FakeContextualSuggestionsFetcher* fetcher() { return fetcher_; } - ContextualSuggestionsSource* source() { return source_.get(); } - - private: - FakeContextualSuggestionsFetcher* fetcher_; - base::MessageLoop message_loop_; - TestingPrefServiceSimple pref_service_; - std::unique_ptr<ContextualSuggestionsSource> source_; - - DISALLOW_COPY_AND_ASSIGN(ContextualSuggestionsSourceTest); -}; - -TEST_F(ContextualSuggestionsSourceTest, ShouldFetchContextualSuggestion) { - MockFetchContextualSuggestionsCallback mock_suggestions_callback; - const std::string kValidFromUrl = "http://some.url"; - const std::string kToUrl = "http://another.url"; - ContextualSuggestionsFetcher::OptionalSuggestions remote_suggestions = - RemoteSuggestion::PtrVector(); - remote_suggestions->push_back(test::RemoteSuggestionBuilder() - .AddId(kToUrl) - .SetUrl(kToUrl) - .SetAmpUrl(kToUrl) - .Build()); - fetcher()->SetFakeResponse(Status::Success(), std::move(remote_suggestions)); - EXPECT_CALL(mock_suggestions_callback, - Run(Property(&Status::IsSuccess, true), GURL(kValidFromUrl), - Pointee(ElementsAre(AllOf( - Property(&ContentSuggestion::id, - Property(&ContentSuggestion::ID::category, - Category::FromKnownCategory( - KnownCategories::CONTEXTUAL))), - Property(&ContentSuggestion::url, GURL(kToUrl))))))); - source()->FetchContextualSuggestions( - GURL(kValidFromUrl), mock_suggestions_callback.ToOnceCallback()); - base::RunLoop().RunUntilIdle(); -} - -TEST_F(ContextualSuggestionsSourceTest, ShouldRunCallbackOnEmptyResults) { - MockFetchContextualSuggestionsCallback mock_suggestions_callback; - const std::string kEmpty; - fetcher()->SetFakeResponse(Status::Success(), RemoteSuggestion::PtrVector()); - EXPECT_CALL(mock_suggestions_callback, Run(Property(&Status::IsSuccess, true), - GURL(kEmpty), Pointee(IsEmpty()))); - source()->FetchContextualSuggestions( - GURL(kEmpty), mock_suggestions_callback.ToOnceCallback()); - base::RunLoop().RunUntilIdle(); -} - -TEST_F(ContextualSuggestionsSourceTest, ShouldRunCallbackOnError) { - MockFetchContextualSuggestionsCallback mock_suggestions_callback; - const std::string kEmpty; - fetcher()->SetFakeResponse(Status(StatusCode::TEMPORARY_ERROR, ""), - RemoteSuggestion::PtrVector()); - EXPECT_CALL(mock_suggestions_callback, - Run(Property(&Status::IsSuccess, false), GURL(kEmpty), - Pointee(IsEmpty()))); - source()->FetchContextualSuggestions( - GURL(kEmpty), mock_suggestions_callback.ToOnceCallback()); - base::RunLoop().RunUntilIdle(); -} - -TEST_F(ContextualSuggestionsSourceTest, ShouldFetchEmptyImageIfNotFound) { - base::MockCallback<ImageFetchedCallback> mock_image_fetched_callback; - const std::string kEmpty; - ContentSuggestion::ID id( - Category::FromKnownCategory(KnownCategories::CONTEXTUAL), kEmpty); - EXPECT_CALL(mock_image_fetched_callback, - Run(Property(&gfx::Image::IsEmpty, true))); - source()->FetchContextualSuggestionImage(id, - mock_image_fetched_callback.Get()); - // TODO(gaschler): Verify with a mock that the image fetcher is not called if - // the id is unknown. - base::RunLoop().RunUntilIdle(); -} - -TEST_F(ContextualSuggestionsSourceTest, - ShouldFetchImageForPreviouslyFetchedSuggestion) { - const std::string kValidFromUrl = "http://some.url"; - const std::string kToUrl = "http://another.url"; - const std::string kValidImageUrl = "http://some.url/image.png"; - ContextualSuggestionsFetcher::OptionalSuggestions remote_suggestions = - RemoteSuggestion::PtrVector(); - remote_suggestions->push_back(test::RemoteSuggestionBuilder() - .AddId(kToUrl) - .SetUrl(kToUrl) - .SetAmpUrl(kToUrl) - .SetImageUrl(kValidImageUrl) - .Build()); - fetcher()->SetFakeResponse(Status::Success(), std::move(remote_suggestions)); - MockFetchContextualSuggestionsCallback mock_suggestions_callback; - std::vector<ContentSuggestion> suggestions; - EXPECT_CALL(mock_suggestions_callback, Run(_, _, _)) - .WillOnce(MoveArg<2>(&suggestions)); - source()->FetchContextualSuggestions( - GURL(kValidFromUrl), mock_suggestions_callback.ToOnceCallback()); - base::RunLoop().RunUntilIdle(); - - ASSERT_THAT(suggestions, Not(IsEmpty())); - base::MockCallback<ImageFetchedCallback> mock_image_fetched_callback; - EXPECT_CALL(mock_image_fetched_callback, - Run(Property(&gfx::Image::IsEmpty, false))); - source()->FetchContextualSuggestionImage(suggestions[0].id(), - mock_image_fetched_callback.Get()); - base::RunLoop().RunUntilIdle(); -} - -} // namespace ntp_snippets
diff --git a/components/ntp_snippets/remote/remote_suggestions_database_unittest.cc b/components/ntp_snippets/remote/remote_suggestions_database_unittest.cc index d7347dd3..1380fcb 100644 --- a/components/ntp_snippets/remote/remote_suggestions_database_unittest.cc +++ b/components/ntp_snippets/remote/remote_suggestions_database_unittest.cc
@@ -181,7 +181,7 @@ RunUntilIdle(); } -TEST_F(RemoteSuggestionsDatabaseTest, SavePersist) { +TEST_F(RemoteSuggestionsDatabaseTest, DISABLED_SavePersist) { CreateDatabase(); RunUntilIdle(); ASSERT_TRUE(db()->IsInitialized());
diff --git a/components/ntp_snippets/remote/remote_suggestions_provider_impl.cc b/components/ntp_snippets/remote/remote_suggestions_provider_impl.cc index c5724f9..2bfc572c 100644 --- a/components/ntp_snippets/remote/remote_suggestions_provider_impl.cc +++ b/components/ntp_snippets/remote/remote_suggestions_provider_impl.cc
@@ -163,6 +163,30 @@ kEnablePushedSuggestionsNotificationsDefault); } +// Whether signed-in users should be subscribed for pushed suggestions. +const bool kEnableSignedInUsersSubscriptionForPushedSuggestionsDefault = true; +const char kEnableSignedInUsersSubscriptionForPushedSuggestionsParamName[] = + "enable_signed_in_users_subscription_for_pushed_suggestions"; + +bool IsSignedInUsersSubscriptionForPushedSuggestionsEnabled() { + return base::GetFieldTrialParamByFeatureAsBool( + ntp_snippets::kBreakingNewsPushFeature, + kEnableSignedInUsersSubscriptionForPushedSuggestionsParamName, + kEnableSignedInUsersSubscriptionForPushedSuggestionsDefault); +} + +// Whether signed-out users should be subscribed for pushed suggestions. +const bool kEnableSignedOutUsersSubscriptionForPushedSuggestionsDefault = false; +const char kEnableSignedOutUsersSubscriptionForPushedSuggestionsParamName[] = + "enable_signed_out_users_subscription_for_pushed_suggestions"; + +bool IsSignedOutUsersSubscriptionForPushedSuggestionsEnabled() { + return base::GetFieldTrialParamByFeatureAsBool( + ntp_snippets::kBreakingNewsPushFeature, + kEnableSignedOutUsersSubscriptionForPushedSuggestionsParamName, + kEnableSignedOutUsersSubscriptionForPushedSuggestionsDefault); +} + template <typename SuggestionPtrContainer> std::unique_ptr<std::vector<std::string>> GetSuggestionIDVector( const SuggestionPtrContainer& suggestions) { @@ -1134,13 +1158,6 @@ UpdateCategoryStatus(category, CategoryStatus::AVAILABLE); } } - - if (breaking_news_raw_data_provider_) { - DCHECK(!breaking_news_raw_data_provider_->IsListening()); - breaking_news_raw_data_provider_->StartListening( - base::Bind(&RemoteSuggestionsProviderImpl::PrependArticleSuggestion, - base::Unretained(this))); - } } void RemoteSuggestionsProviderImpl::EnterStateDisabled() { @@ -1155,6 +1172,43 @@ status_service_.reset(); } +void RemoteSuggestionsProviderImpl:: + UpdatePushedSuggestionsSubscriptionDueToStatusChange( + RemoteSuggestionsStatus new_status) { + if (!breaking_news_raw_data_provider_) { + return; + } + + bool should_be_subscribed = false; + switch (new_status) { + case RemoteSuggestionsStatus::ENABLED_AND_SIGNED_IN: + should_be_subscribed = + IsSignedInUsersSubscriptionForPushedSuggestionsEnabled(); + break; + + case RemoteSuggestionsStatus::ENABLED_AND_SIGNED_OUT: + should_be_subscribed = + IsSignedOutUsersSubscriptionForPushedSuggestionsEnabled(); + break; + + case RemoteSuggestionsStatus::EXPLICITLY_DISABLED: + should_be_subscribed = false; + break; + } + + if (should_be_subscribed) { + if (!breaking_news_raw_data_provider_->IsListening()) { + breaking_news_raw_data_provider_->StartListening( + base::Bind(&RemoteSuggestionsProviderImpl::PrependArticleSuggestion, + base::Unretained(this))); + } + } else { + if (breaking_news_raw_data_provider_->IsListening()) { + breaking_news_raw_data_provider_->StopListening(); + } + } +} + void RemoteSuggestionsProviderImpl::FinishInitialization() { if (clear_history_dependent_state_when_initialized_) { // We clear here in addition to EnterStateReady, so that it happens even if @@ -1214,6 +1268,8 @@ UpdateAllCategoryStatus(CategoryStatus::CATEGORY_EXPLICITLY_DISABLED); break; } + + UpdatePushedSuggestionsSubscriptionDueToStatusChange(new_status); } void RemoteSuggestionsProviderImpl::EnterState(State state) {
diff --git a/components/ntp_snippets/remote/remote_suggestions_provider_impl.h b/components/ntp_snippets/remote/remote_suggestions_provider_impl.h index 44c02b5..4114efe2 100644 --- a/components/ntp_snippets/remote/remote_suggestions_provider_impl.h +++ b/components/ntp_snippets/remote/remote_suggestions_provider_impl.h
@@ -349,6 +349,11 @@ // Do not call directly, use |EnterState| instead. void EnterStateError(); + // Subscribes or unsubcribes from pushed suggestions depending on the new + // status. + void UpdatePushedSuggestionsSubscriptionDueToStatusChange( + RemoteSuggestionsStatus new_status); + // Converts the cached suggestions in the given |category| to content // suggestions and notifies the observer. void NotifyNewSuggestions(Category category, const CategoryContent& content);
diff --git a/components/ntp_snippets/remote/remote_suggestions_provider_impl_unittest.cc b/components/ntp_snippets/remote/remote_suggestions_provider_impl_unittest.cc index 69cb08d..aa600d03 100644 --- a/components/ntp_snippets/remote/remote_suggestions_provider_impl_unittest.cc +++ b/components/ntp_snippets/remote/remote_suggestions_provider_impl_unittest.cc
@@ -569,21 +569,28 @@ {kKeepPrefetchedContentSuggestions.name}); } - void SetTriggeringNotificationsParams(bool fetched_enabled, - bool pushed_enabled) { + void SetTriggeringNotificationsAndSubscriptionParams( + bool fetched_notifications_enabled, + bool pushed_notifications_enabled, + bool subscribe_signed_in, + bool subscribe_signed_out) { // VariationParamsManager supports only one // |SetVariationParamsWithFeatureAssociations| at a time, so we clear // previous settings first to make this explicit. params_manager_.ClearAllVariationParams(); params_manager_.SetVariationParamsWithFeatureAssociations( - kNotificationsFeature.name, + /*trial_name=*/kNotificationsFeature.name, { {"enable_fetched_suggestions_notifications", - BoolToString(fetched_enabled)}, + BoolToString(fetched_notifications_enabled)}, {"enable_pushed_suggestions_notifications", - BoolToString(pushed_enabled)}, + BoolToString(pushed_notifications_enabled)}, + {"enable_signed_in_users_subscription_for_pushed_suggestions", + BoolToString(subscribe_signed_in)}, + {"enable_signed_out_users_subscription_for_pushed_suggestions", + BoolToString(subscribe_signed_out)}, }, - {kNotificationsFeature.name}); + {kNotificationsFeature.name, kBreakingNewsPushFeature.name}); } private: @@ -3049,6 +3056,12 @@ TEST_F(RemoteSuggestionsProviderImplTest, PrependingShouldNotAffectOtherSuggestions) { + SetTriggeringNotificationsAndSubscriptionParams( + /*fetched_notifications_enabled=*/false, + /*pushed_notifications_enabled=*/false, + /*subscribe_signed_in=*/true, + /*subscribe_signed_out=*/true); + // Set up the provider with some article suggestions. auto provider = MakeSuggestionsProvider( /*use_mock_prefetched_pages_tracker=*/false, @@ -3092,6 +3105,12 @@ } TEST_F(RemoteSuggestionsProviderImplTest, ShouldNotPrependDismissedSuggestion) { + SetTriggeringNotificationsAndSubscriptionParams( + /*fetched_notifications_enabled=*/false, + /*pushed_notifications_enabled=*/false, + /*subscribe_signed_in=*/true, + /*subscribe_signed_out=*/true); + auto provider = MakeSuggestionsProvider( /*use_mock_prefetched_pages_tracker=*/false, /*use_fake_breaking_news_listener=*/true, @@ -3120,6 +3139,12 @@ TEST_F(RemoteSuggestionsProviderImplTest, ShouldRestorePrependedSuggestionOnTopAfterRestart) { + SetTriggeringNotificationsAndSubscriptionParams( + /*fetched_notifications_enabled=*/false, + /*pushed_notifications_enabled=*/false, + /*subscribe_signed_in=*/true, + /*subscribe_signed_out=*/true); + // Set up the provider with some article suggestions. auto provider = MakeSuggestionsProvider( /*use_mock_prefetched_pages_tracker=*/false, @@ -3172,8 +3197,11 @@ TEST_F( RemoteSuggestionsProviderImplTest, PrependingShouldNotTriggerFetchedSuggestionNotificationForTheSecondTime) { - SetTriggeringNotificationsParams(/*fetched_enabled=*/true, - /*pushed_enabled=*/true); + SetTriggeringNotificationsAndSubscriptionParams( + /*fetched_notifications_enabled=*/true, + /*pushed_notifications_enabled=*/true, + /*subscribe_signed_in=*/true, + /*subscribe_signed_out=*/true); // Set up the provider with an article suggestion triggering a notification. auto provider = MakeSuggestionsProvider( @@ -3220,8 +3248,11 @@ TEST_F( RemoteSuggestionsProviderImplTest, PrependingShouldNotTriggerPrependedSuggestionNotificationForTheSecondTime) { - SetTriggeringNotificationsParams(/*fetched_enabled=*/true, - /*pushed_enabled=*/true); + SetTriggeringNotificationsAndSubscriptionParams( + /*fetched_notifications_enabled=*/true, + /*pushed_notifications_enabled=*/true, + /*subscribe_signed_in=*/true, + /*subscribe_signed_out=*/true); auto provider = MakeSuggestionsProvider( /*use_mock_prefetched_pages_tracker=*/false, @@ -3263,8 +3294,11 @@ TEST_F(RemoteSuggestionsProviderImplTest, PrependingShouldNotTriggerNotificationWhenDisabled) { - SetTriggeringNotificationsParams(/*fetched_enabled=*/true, - /*pushed_enabled=*/false); + SetTriggeringNotificationsAndSubscriptionParams( + /*fetched_notifications_enabled=*/true, + /*pushed_notifications_enabled=*/false, + /*subscribe_signed_in=*/true, + /*subscribe_signed_out=*/true); auto provider = MakeSuggestionsProvider( /*use_mock_prefetched_pages_tracker=*/false, @@ -3291,8 +3325,11 @@ TEST_F(RemoteSuggestionsProviderImplTest, FetchingShouldNotTriggerNotificationWhenDisabled) { - SetTriggeringNotificationsParams(/*fetched_enabled=*/false, - /*pushed_enabled=*/true); + SetTriggeringNotificationsAndSubscriptionParams( + /*fetched_notifications_enabled=*/false, + /*pushed_notifications_enabled=*/true, + /*subscribe_signed_in=*/true, + /*subscribe_signed_out=*/true); auto provider = MakeSuggestionsProvider( /*use_mock_prefetched_pages_tracker=*/false, @@ -3323,8 +3360,11 @@ TEST_F(RemoteSuggestionsProviderImplTest, PrependingShouldTriggerNotificationEvenIfFetchedNotificationsDisabled) { - SetTriggeringNotificationsParams(/*fetched_enabled=*/false, - /*pushed_enabled=*/true); + SetTriggeringNotificationsAndSubscriptionParams( + /*fetched_notifications_enabled=*/false, + /*pushed_notifications_enabled=*/true, + /*subscribe_signed_in=*/true, + /*subscribe_signed_out=*/true); auto provider = MakeSuggestionsProvider( /*use_mock_prefetched_pages_tracker=*/false, @@ -3351,8 +3391,11 @@ TEST_F(RemoteSuggestionsProviderImplTest, FetchingShouldTriggerNotificationEvenIfPrependedNotificationsDisabled) { - SetTriggeringNotificationsParams(/*fetched_enabled=*/true, - /*pushed_enabled=*/false); + SetTriggeringNotificationsAndSubscriptionParams( + /*fetched_notifications_enabled=*/true, + /*pushed_notifications_enabled=*/false, + /*subscribe_signed_in=*/true, + /*subscribe_signed_out=*/true); auto provider = MakeSuggestionsProvider( /*use_mock_prefetched_pages_tracker=*/false, @@ -3383,6 +3426,12 @@ TEST_F(RemoteSuggestionsProviderImplTest, ShouldNotStartListeningForBreakingNewsIfSuggestionsDisabledAtStartup) { + SetTriggeringNotificationsAndSubscriptionParams( + /*fetched_notifications_enabled=*/false, + /*pushed_notifications_enabled=*/false, + /*subscribe_signed_in=*/true, + /*subscribe_signed_out=*/true); + auto provider = MakeSuggestionsProviderWithoutInitialization( /*use_mock_prefetched_pages_tracker=*/false, /*use_fake_breaking_news_listener=*/true, @@ -3402,7 +3451,41 @@ } TEST_F(RemoteSuggestionsProviderImplTest, + ShouldNotStartListeningForBreakingNewsIfSignedOutAndDisabled) { + SetTriggeringNotificationsAndSubscriptionParams( + /*fetched_notifications_enabled=*/false, + /*pushed_notifications_enabled=*/false, + /*subscribe_signed_in=*/true, + /*subscribe_signed_out=*/false); + + auto provider = MakeSuggestionsProviderWithoutInitialization( + /*use_mock_prefetched_pages_tracker=*/false, + /*use_fake_breaking_news_listener=*/true, + /*use_mock_remote_suggestions_status_service=*/true); + + FakeBreakingNewsListener* fake_listener = fake_breaking_news_listener(); + EXPECT_FALSE(fake_listener->IsListening()); + + WaitForSuggestionsProviderInitialization(provider.get()); + EXPECT_FALSE(fake_listener->IsListening()); + + // Notify the provider about status change (simulating startup). The provider + // should not start listening, because the user is signed out and such + // subscription is disabled via feature params. + ChangeRemoteSuggestionsStatus( + RemoteSuggestionsStatus::EXPLICITLY_DISABLED, + RemoteSuggestionsStatus::ENABLED_AND_SIGNED_OUT); + EXPECT_FALSE(fake_listener->IsListening()); +} + +TEST_F(RemoteSuggestionsProviderImplTest, ShouldStartListeningForBreakingNewsIfSuggestionsEnabledAtStartup) { + SetTriggeringNotificationsAndSubscriptionParams( + /*fetched_notifications_enabled=*/false, + /*pushed_notifications_enabled=*/false, + /*subscribe_signed_in=*/false, + /*subscribe_signed_out=*/true); + auto provider = MakeSuggestionsProvider( /*use_mock_prefetched_pages_tracker=*/false, /*use_fake_breaking_news_listener=*/true, @@ -3421,6 +3504,12 @@ TEST_F(RemoteSuggestionsProviderImplTest, ShouldStartListeningForBreakingNewsIfSuggestionsEnabled) { + SetTriggeringNotificationsAndSubscriptionParams( + /*fetched_notifications_enabled=*/false, + /*pushed_notifications_enabled=*/false, + /*subscribe_signed_in=*/true, + /*subscribe_signed_out=*/false); + auto provider = MakeSuggestionsProvider( /*use_mock_prefetched_pages_tracker=*/false, /*use_fake_breaking_news_listener=*/true, @@ -3435,14 +3524,19 @@ // Simulate the user enabling suggestions by notifying the status change. The // provider should start listening. - ChangeRemoteSuggestionsStatus( - RemoteSuggestionsStatus::EXPLICITLY_DISABLED, - RemoteSuggestionsStatus::ENABLED_AND_SIGNED_OUT); + ChangeRemoteSuggestionsStatus(RemoteSuggestionsStatus::EXPLICITLY_DISABLED, + RemoteSuggestionsStatus::ENABLED_AND_SIGNED_IN); EXPECT_TRUE(fake_listener->IsListening()); } TEST_F(RemoteSuggestionsProviderImplTest, ShouldStopListeningForBreakingNewsIfSuggestionsDisabled) { + SetTriggeringNotificationsAndSubscriptionParams( + /*fetched_notifications_enabled=*/false, + /*pushed_notifications_enabled=*/false, + /*subscribe_signed_in=*/true, + /*subscribe_signed_out=*/true); + auto provider = MakeSuggestionsProvider( /*use_mock_prefetched_pages_tracker=*/false, /*use_fake_breaking_news_listener=*/true, @@ -3463,4 +3557,62 @@ EXPECT_FALSE(fake_listener->IsListening()); } +TEST_F(RemoteSuggestionsProviderImplTest, + ShouldStopListeningForBreakingNewsAfterSignOutIfDisabled) { + SetTriggeringNotificationsAndSubscriptionParams( + /*fetched_notifications_enabled=*/false, + /*pushed_notifications_enabled=*/false, + /*subscribe_signed_in=*/true, + /*subscribe_signed_out=*/false); + + auto provider = MakeSuggestionsProvider( + /*use_mock_prefetched_pages_tracker=*/false, + /*use_fake_breaking_news_listener=*/true, + /*use_mock_remote_suggestions_status_service=*/true); + + FakeBreakingNewsListener* fake_listener = fake_breaking_news_listener(); + + // Notify the provider about status change (simulating startup). + ChangeRemoteSuggestionsStatus(RemoteSuggestionsStatus::EXPLICITLY_DISABLED, + RemoteSuggestionsStatus::ENABLED_AND_SIGNED_IN); + ASSERT_TRUE(fake_listener->IsListening()); + + // Simulate the user signing out by notifying the status change. The provider + // should stop listening, because signed out subscription is disabled via + // feature params. + ChangeRemoteSuggestionsStatus( + RemoteSuggestionsStatus::ENABLED_AND_SIGNED_IN, + RemoteSuggestionsStatus::ENABLED_AND_SIGNED_OUT); + EXPECT_FALSE(fake_listener->IsListening()); +} + +TEST_F(RemoteSuggestionsProviderImplTest, + ShouldStopListeningForBreakingNewsAfterSignInIfDisabled) { + SetTriggeringNotificationsAndSubscriptionParams( + /*fetched_notifications_enabled=*/false, + /*pushed_notifications_enabled=*/false, + /*subscribe_signed_in=*/false, + /*subscribe_signed_out=*/true); + + auto provider = MakeSuggestionsProvider( + /*use_mock_prefetched_pages_tracker=*/false, + /*use_fake_breaking_news_listener=*/true, + /*use_mock_remote_suggestions_status_service=*/true); + + FakeBreakingNewsListener* fake_listener = fake_breaking_news_listener(); + + // Notify the provider about status change (simulating startup). + ChangeRemoteSuggestionsStatus( + RemoteSuggestionsStatus::EXPLICITLY_DISABLED, + RemoteSuggestionsStatus::ENABLED_AND_SIGNED_OUT); + ASSERT_TRUE(fake_listener->IsListening()); + + // Simulate the user signing in by notifying the status change. The provider + // should stop listening, because signed in subscription is disabled via + // feature params. + ChangeRemoteSuggestionsStatus(RemoteSuggestionsStatus::ENABLED_AND_SIGNED_OUT, + RemoteSuggestionsStatus::ENABLED_AND_SIGNED_IN); + EXPECT_FALSE(fake_listener->IsListening()); +} + } // namespace ntp_snippets
diff --git a/components/offline_pages/core/offline_page_model.h b/components/offline_pages/core/offline_page_model.h index c7b89426..dd5a2b5f 100644 --- a/components/offline_pages/core/offline_page_model.h +++ b/components/offline_pages/core/offline_page_model.h
@@ -154,6 +154,11 @@ const std::vector<ClientId>& client_ids, const MultipleOfflinePageItemCallback& callback) = 0; + // Retrieves all pages associated with the |request_origin|. + virtual void GetPagesByRequestOrigin( + const std::string& request_origin, + const MultipleOfflinePageItemCallback& callback) = 0; + // Deletes cached offline pages matching the URL predicate. virtual void DeleteCachedPagesByURLPredicate( const UrlPredicate& predicate,
diff --git a/components/offline_pages/core/offline_page_model_impl.cc b/components/offline_pages/core/offline_page_model_impl.cc index 5a973ee..ebcd39d 100644 --- a/components/offline_pages/core/offline_page_model_impl.cc +++ b/components/offline_pages/core/offline_page_model_impl.cc
@@ -532,6 +532,18 @@ base::Passed(builder.Build(GetPolicyController())), callback)); } +void OfflinePageModelImpl::GetPagesByRequestOrigin( + const std::string& request_origin, + const MultipleOfflinePageItemCallback& callback) { + OfflinePageModelQueryBuilder builder; + builder.SetRequestOrigin(OfflinePageModelQuery::Requirement::INCLUDE_MATCHING, + request_origin); + RunWhenLoaded( + base::Bind(&OfflinePageModelImpl::GetPagesMatchingQueryWhenLoadDone, + weak_ptr_factory_.GetWeakPtr(), + base::Passed(builder.Build(GetPolicyController())), callback)); +} + void OfflinePageModelImpl::DeleteCachedPagesByURLPredicate( const UrlPredicate& predicate, const DeletePageCallback& callback) {
diff --git a/components/offline_pages/core/offline_page_model_impl.h b/components/offline_pages/core/offline_page_model_impl.h index 8e4a768..4aaf227 100644 --- a/components/offline_pages/core/offline_page_model_impl.h +++ b/components/offline_pages/core/offline_page_model_impl.h
@@ -83,6 +83,10 @@ const std::vector<ClientId>& client_ids, const MultipleOfflinePageItemCallback& callback) override; + void GetPagesByRequestOrigin( + const std::string& request_origin, + const MultipleOfflinePageItemCallback& callback) override; + void DeleteCachedPagesByURLPredicate( const UrlPredicate& predicate, const DeletePageCallback& callback) override;
diff --git a/components/offline_pages/core/offline_page_model_impl_unittest.cc b/components/offline_pages/core/offline_page_model_impl_unittest.cc index bc78dd5..226f49b 100644 --- a/components/offline_pages/core/offline_page_model_impl_unittest.cc +++ b/components/offline_pages/core/offline_page_model_impl_unittest.cc
@@ -131,6 +131,8 @@ MultipleOfflinePageItemResult GetAllPages(); MultipleOfflinePageItemResult GetPagesByClientIds( const std::vector<ClientId>& client_ids); + MultipleOfflinePageItemResult GetPagesByRequestOrigin( + const std::string& origin); void DeletePagesByClientIds(const std::vector<ClientId>& client_ids); // Saves the page without waiting for it to finish. @@ -457,6 +459,17 @@ return result; } +MultipleOfflinePageItemResult OfflinePageModelImplTest::GetPagesByRequestOrigin( + const std::string& origin) { + MultipleOfflinePageItemResult result; + model()->GetPagesByRequestOrigin( + origin, + base::Bind(&OfflinePageModelImplTest::OnGetMultipleOfflinePageItemsResult, + AsWeakPtr(), base::Unretained(&result))); + PumpLoop(); + return result; +} + void OfflinePageModelImplTest::DeletePagesByClientIds( const std::vector<ClientId>& client_ids) { model()->DeletePagesByClientIds( @@ -696,8 +709,8 @@ TEST_F(OfflinePageModelImplTest, SavePageLocalFileFailed) { // Don't create archiver since it will not be needed for pages that are not // going to be saved. - SavePageWithArchiver( - kFileUrl, kTestClientId1, std::unique_ptr<OfflinePageTestArchiver>()); + SavePageWithArchiver(kFileUrl, kTestClientId1, + std::unique_ptr<OfflinePageTestArchiver>()); EXPECT_EQ(SavePageResult::SKIPPED, last_save_result()); } @@ -1067,8 +1080,8 @@ EXPECT_TRUE(base::PathExists(path)); // Since we've manually changed the store, we have to reload the model to - // actually refresh the in-memory copy in model. Otherwise GetAllPages() would - // still have the page we saved above. + // actually refresh the in-memory copy in model. Otherwise GetAllPages() + // would still have the page we saved above. ResetModel(); PumpLoop(); @@ -1334,6 +1347,30 @@ EXPECT_EQ(kTestUrl2, item.url); } +TEST_F(OfflinePageModelImplTest, GetPagesByRequestOrigin) { + // We will save 3 pages. + std::string origin1("abc.xyz"); + std::string origin2("abc"); + std::pair<SavePageResult, int64_t> save_pages[3]; + save_pages[0] = SavePage(kTestUrl, kTestClientId1, origin1); + save_pages[1] = SavePage(kTestUrl2, kTestClientId2, origin2); + save_pages[2] = SavePage(kTestUrl3, kTestClientId3, origin1); + + for (const auto& save_result : save_pages) { + ASSERT_EQ(OfflinePageModel::SavePageResult::SUCCESS, + std::get<0>(save_result)); + } + + std::vector<OfflinePageItem> offline_pages = GetPagesByRequestOrigin(origin2); + EXPECT_EQ(1U, offline_pages.size()); + + const OfflinePageItem& item = offline_pages[0]; + EXPECT_EQ(kTestUrl2, item.url); + EXPECT_EQ(origin2, item.request_origin); + EXPECT_EQ(kTestClientId2.name_space, item.client_id.name_space); + EXPECT_EQ(kTestClientId2.id, item.client_id.id); +} + TEST_F(OfflinePageModelImplTest, DeletePagesByClientIds) { // We will save 3 pages. std::pair<SavePageResult, int64_t> saved_pages[3]; @@ -1402,8 +1439,8 @@ // Should record failure to load. histograms().ExpectBucketCount("OfflinePages.Model.FinalLoadSuccessful", false, 1); - // Should show the previous count since no attempts are recorded for failure. - // In case of failure, all attempts are assumed spent. + // Should show the previous count since no attempts are recorded for + // failure. In case of failure, all attempts are assumed spent. histograms().ExpectUniqueSample("OfflinePages.Model.InitAttemptsSpent", 1, 1); const std::vector<OfflinePageItem>& offline_pages = GetAllPages();
diff --git a/components/offline_pages/core/offline_page_model_query.cc b/components/offline_pages/core/offline_page_model_query.cc index 2f87756..dd737ad 100644 --- a/components/offline_pages/core/offline_page_model_query.cc +++ b/components/offline_pages/core/offline_page_model_query.cc
@@ -70,6 +70,13 @@ return *this; } +OfflinePageModelQueryBuilder& OfflinePageModelQueryBuilder::SetRequestOrigin( + Requirement requirement, + const std::string& request_origin) { + request_origin_ = std::make_pair(requirement, request_origin); + return *this; +} + OfflinePageModelQueryBuilder& OfflinePageModelQueryBuilder::SetUrls( Requirement requirement, const std::vector<GURL>& urls, @@ -136,6 +143,10 @@ std::set<ClientId>(client_ids_.second.begin(), client_ids_.second.end())); client_ids_ = std::make_pair(Requirement::UNSET, std::vector<ClientId>()); + query->request_origin_ = + std::make_pair(request_origin_.first, request_origin_.second); + request_origin_ = std::make_pair(Requirement::UNSET, std::string()); + std::vector<std::string> allowed_namespaces; bool uses_namespace_restrictions = false; @@ -232,6 +243,13 @@ return urls_; } +std::pair<Requirement, std::string> OfflinePageModelQuery::GetRequestOrigin() + const { + if (request_origin_.first == Requirement::UNSET) + return std::make_pair(Requirement::UNSET, std::string()); + return request_origin_; +} + bool OfflinePageModelQuery::Matches(const OfflinePageItem& item) const { switch (offline_ids_.first) { case Requirement::UNSET: @@ -278,6 +296,19 @@ break; } + switch (request_origin_.first) { + case Requirement::UNSET: + break; + case Requirement::INCLUDE_MATCHING: + if (request_origin_.second != item.request_origin) + return false; + break; + case Requirement::EXCLUDE_MATCHING: + if (request_origin_.second == item.request_origin) + return false; + break; + } + return true; }
diff --git a/components/offline_pages/core/offline_page_model_query.h b/components/offline_pages/core/offline_page_model_query.h index 8378b0ef..b20ebb2 100644 --- a/components/offline_pages/core/offline_page_model_query.h +++ b/components/offline_pages/core/offline_page_model_query.h
@@ -59,6 +59,7 @@ std::pair<Requirement, std::set<int64_t>> GetRestrictedToOfflineIds() const; std::pair<Requirement, std::set<ClientId>> GetRestrictedToClientIds() const; std::pair<Requirement, URLSearchParams> GetRestrictedToUrls() const; + std::pair<Requirement, std::string> GetRequestOrigin() const; // This is the workhorse function that is used by the in-memory offline page // model, given a page it will find out whether that page matches the query. @@ -72,6 +73,7 @@ std::pair<Requirement, std::set<int64_t>> offline_ids_; std::pair<Requirement, std::set<ClientId>> client_ids_; std::pair<Requirement, URLSearchParams> urls_; + std::pair<Requirement, std::string> request_origin_; DISALLOW_COPY_AND_ASSIGN(OfflinePageModelQuery); }; @@ -100,6 +102,12 @@ OfflinePageModelQueryBuilder& SetClientIds(Requirement requirement, const std::vector<ClientId>& ids); + // Sets the request origin that are valid for this request. If called + // multiple times, overwrites the previous request origin restrictions. + OfflinePageModelQueryBuilder& SetRequestOrigin( + Requirement requirement, + const std::string& request_origin); + // Sets the URLs that are valid for this request. If called multiple times, // overwrites previous URL restrictions. // |search_mode| is used to control if the URL will be matched with final @@ -160,6 +168,7 @@ std::pair<Requirement, std::vector<int64_t>> offline_ids_; std::pair<Requirement, std::vector<ClientId>> client_ids_; std::pair<Requirement, OfflinePageModelQuery::URLSearchParams> urls_; + std::pair<Requirement, std::string> request_origin_; Requirement removed_on_cache_reset_ = Requirement::UNSET; Requirement supported_by_download_ = Requirement::UNSET;
diff --git a/components/offline_pages/core/offline_page_model_query_unittest.cc b/components/offline_pages/core/offline_page_model_query_unittest.cc index d3d90b5..2e0145a6d 100644 --- a/components/offline_pages/core/offline_page_model_query_unittest.cc +++ b/components/offline_pages/core/offline_page_model_query_unittest.cc
@@ -65,6 +65,11 @@ {kLastNNamespace, "id1"}, base::FilePath(), 7); } + const OfflinePageItem cct_page() { + OfflinePageItem page = kTestItem1; + page.request_origin = "[\"abc.xyz\",[\"12345\"]]"; + return page; + } const OfflinePageItem CreatePageWithUrls(const GURL& url, const GURL& original_url) { OfflinePageItem page = kTestItem1; @@ -688,4 +693,50 @@ EXPECT_TRUE(query->Matches(CreatePageWithUrls(kTempFragUrl, GURL("")))); } +TEST_F(OfflinePageModelQueryTest, RequestOrigin_Exclude) { + builder_.SetRequestOrigin(Requirement::EXCLUDE_MATCHING, ""); + + std::unique_ptr<OfflinePageModelQuery> query = builder_.Build(&policy_); + std::pair<Requirement, std::string> offline_origin_restriction = + query->GetRequestOrigin(); + EXPECT_EQ(Requirement::EXCLUDE_MATCHING, offline_origin_restriction.first); + + ASSERT_EQ("", offline_origin_restriction.second); + + EXPECT_FALSE(query->Matches(kTestItem1)); + EXPECT_TRUE(query->Matches(cct_page())); +} + +TEST_F(OfflinePageModelQueryTest, RequestOrigin_Include) { + builder_.SetRequestOrigin(Requirement::INCLUDE_MATCHING, ""); + + std::unique_ptr<OfflinePageModelQuery> query = builder_.Build(&policy_); + std::pair<Requirement, std::string> offline_origin_restriction = + query->GetRequestOrigin(); + EXPECT_EQ(Requirement::INCLUDE_MATCHING, offline_origin_restriction.first); + + ASSERT_EQ("", offline_origin_restriction.second); + + EXPECT_TRUE(query->Matches(kTestItem1)); + EXPECT_FALSE(query->Matches(cct_page())); +} + +TEST_F(OfflinePageModelQueryTest, RequestOrigin_Replace) { + std::string origin1 = ""; + std::string origin2 = "[\"abc.xyz\",[\"12345\"]]"; + + builder_.SetRequestOrigin(Requirement::INCLUDE_MATCHING, origin1); + builder_.SetRequestOrigin(Requirement::INCLUDE_MATCHING, origin2); + + std::unique_ptr<OfflinePageModelQuery> query = builder_.Build(&policy_); + std::pair<Requirement, std::string> offline_origin_restriction = + query->GetRequestOrigin(); + EXPECT_EQ(Requirement::INCLUDE_MATCHING, offline_origin_restriction.first); + + ASSERT_EQ(origin2, offline_origin_restriction.second); + + EXPECT_FALSE(query->Matches(kTestItem1)); + EXPECT_TRUE(query->Matches(cct_page())); +} + } // namespace offline_pages
diff --git a/components/offline_pages/core/prefetch/BUILD.gn b/components/offline_pages/core/prefetch/BUILD.gn index f5f0f58..2543144 100644 --- a/components/offline_pages/core/prefetch/BUILD.gn +++ b/components/offline_pages/core/prefetch/BUILD.gn
@@ -56,6 +56,8 @@ "prefetch_service_impl.h", "prefetch_types.cc", "prefetch_types.h", + "stale_entry_finalizer_task.cc", + "stale_entry_finalizer_task.h", "store/prefetch_store.cc", "store/prefetch_store.h", "store/prefetch_store_utils.cc", @@ -155,6 +157,7 @@ "prefetch_request_fetcher_unittest.cc", "prefetch_request_operation_response_unittest.cc", "prefetch_server_urls_unittest.cc", + "stale_entry_finalizer_task_unittest.cc", "store/prefetch_store_unittest.cc", "suggested_articles_observer_unittest.cc", ] @@ -163,6 +166,7 @@ ":prefetch", ":test_support", "//base", + "//components/download/internal/test:test_support", "//components/download/public", "//components/gcm_driver/instance_id", "//components/offline_pages/core",
diff --git a/components/offline_pages/core/prefetch/DEPS b/components/offline_pages/core/prefetch/DEPS index 98d9dd2..0232f6a3 100644 --- a/components/offline_pages/core/prefetch/DEPS +++ b/components/offline_pages/core/prefetch/DEPS
@@ -1,4 +1,5 @@ include_rules = [ + "+components/download/internal/test", "+components/download/public", "+google_apis", "+components/variations",
diff --git a/components/offline_pages/core/prefetch/add_unique_urls_task.cc b/components/offline_pages/core/prefetch/add_unique_urls_task.cc index dacb9778..8d3e99f 100644 --- a/components/offline_pages/core/prefetch/add_unique_urls_task.cc +++ b/components/offline_pages/core/prefetch/add_unique_urls_task.cc
@@ -52,9 +52,9 @@ static const char kSql[] = "INSERT INTO prefetch_items" " (offline_id, requested_url, client_namespace, client_id, creation_time," - " freshness_time)" + " freshness_time, title)" " VALUES" - " (?, ?, ?, ?, ?, ?)"; + " (?, ?, ?, ?, ?, ?, ?)"; int64_t now_db_time = ToDatabaseTime(base::Time::Now()); sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql)); @@ -64,6 +64,7 @@ statement.BindString(3, prefetch_url.id); statement.BindInt64(4, now_db_time); statement.BindInt64(5, now_db_time); + statement.BindString16(6, prefetch_url.title); return statement.Run(); }
diff --git a/components/offline_pages/core/prefetch/add_unique_urls_task.h b/components/offline_pages/core/prefetch/add_unique_urls_task.h index b400915..ef4f0a2 100644 --- a/components/offline_pages/core/prefetch/add_unique_urls_task.h +++ b/components/offline_pages/core/prefetch/add_unique_urls_task.h
@@ -46,7 +46,7 @@ // Prefetch store to execute against. Not owned. PrefetchStore* prefetch_store_; - const std::string& name_space_; + std::string name_space_; std::vector<PrefetchURL> prefetch_urls_; base::WeakPtrFactory<AddUniqueUrlsTask> weak_ptr_factory_;
diff --git a/components/offline_pages/core/prefetch/add_unique_urls_task_unittest.cc b/components/offline_pages/core/prefetch/add_unique_urls_task_unittest.cc index 7974f50..42ec4e1 100644 --- a/components/offline_pages/core/prefetch/add_unique_urls_task_unittest.cc +++ b/components/offline_pages/core/prefetch/add_unique_urls_task_unittest.cc
@@ -4,17 +4,37 @@ #include "components/offline_pages/core/prefetch/add_unique_urls_task.h" +#include <map> +#include <set> #include <string> #include <vector> +#include "base/strings/utf_string_conversions.h" #include "base/test/test_simple_task_runner.h" #include "base/threading/thread_task_runner_handle.h" +#include "components/offline_pages/core/prefetch/prefetch_item.h" #include "components/offline_pages/core/prefetch/prefetch_types.h" #include "components/offline_pages/core/prefetch/store/prefetch_store.h" #include "components/offline_pages/core/prefetch/store/prefetch_store_test_util.h" #include "testing/gtest/include/gtest/gtest.h" namespace offline_pages { +namespace { +const char kTestNamespace[] = "test"; +const char kClientId1[] = "ID-1"; +const char kClientId2[] = "ID-2"; +const char kClientId3[] = "ID-3"; +const char kClientId4[] = "ID-5"; +const GURL kTestURL1("https://www.google.com/"); +const GURL kTestURL2("http://www.example.com/"); +const GURL kTestURL3("https://news.google.com/"); +const GURL kTestURL4("https://chrome.google.com/"); +const base::string16 kTestTitle1 = base::ASCIIToUTF16("Title 1"); +const base::string16 kTestTitle2 = base::ASCIIToUTF16("Title 2"); +const base::string16 kTestTitle3 = base::ASCIIToUTF16("Title 3"); +const base::string16 kTestTitle4 = base::ASCIIToUTF16("Title 4"); +} // namespace + class AddUniqueUrlsTaskTest : public testing::Test { public: AddUniqueUrlsTaskTest(); @@ -29,6 +49,9 @@ void PumpLoop(); + // Returns all items stored in a map keyed with client id. + std::map<std::string, PrefetchItem> GetAllItems(); + private: scoped_refptr<base::TestSimpleTaskRunner> task_runner_; base::ThreadTaskRunnerHandle task_runner_handle_; @@ -53,66 +76,106 @@ task_runner_->RunUntilIdle(); } +std::map<std::string, PrefetchItem> AddUniqueUrlsTaskTest::GetAllItems() { + std::set<PrefetchItem> set; + store_util()->GetAllItems(&set); + + std::map<std::string, PrefetchItem> map; + for (const auto& item : set) + map[item.client_id.id] = item; + return map; +} + TEST_F(AddUniqueUrlsTaskTest, AddTaskInEmptyStore) { - std::string name_space("test"); std::vector<PrefetchURL> urls; - urls.push_back(PrefetchURL{"ID-1", GURL("https://www.google.com/")}); - urls.push_back(PrefetchURL{"ID-2", GURL("http://www.example.com/")}); - AddUniqueUrlsTask task(store(), name_space, urls); + urls.push_back(PrefetchURL{kClientId1, kTestURL1, kTestTitle1}); + urls.push_back(PrefetchURL{kClientId2, kTestURL2, kTestTitle2}); + AddUniqueUrlsTask task(store(), kTestNamespace, urls); task.Run(); PumpLoop(); - EXPECT_EQ(2, store_util()->CountPrefetchItems()); + std::map<std::string, PrefetchItem> items = GetAllItems(); + ASSERT_EQ(2u, items.size()); + ASSERT_TRUE(items.count(kClientId1) > 0); + EXPECT_EQ(kTestURL1, items[kClientId1].url); + EXPECT_EQ(kTestNamespace, items[kClientId1].client_id.name_space); + EXPECT_EQ(kTestTitle1, items[kClientId1].title); + ASSERT_TRUE(items.count(kClientId2) > 0); + EXPECT_EQ(kTestURL2, items[kClientId2].url); + EXPECT_EQ(kTestNamespace, items[kClientId2].client_id.name_space); + EXPECT_EQ(kTestTitle2, items[kClientId2].title); } TEST_F(AddUniqueUrlsTaskTest, DontAddURLIfItExists) { - std::string name_space("test"); std::vector<PrefetchURL> urls; - urls.push_back(PrefetchURL{"ID-1", GURL("https://www.google.com/")}); - urls.push_back(PrefetchURL{"ID-2", GURL("http://www.example.com/")}); - AddUniqueUrlsTask task1(store(), name_space, urls); + urls.push_back(PrefetchURL{kClientId1, kTestURL1, kTestTitle1}); + urls.push_back(PrefetchURL{kClientId2, kTestURL2, kTestTitle2}); + AddUniqueUrlsTask task1(store(), kTestNamespace, urls); task1.Run(); PumpLoop(); urls.clear(); - urls.push_back(PrefetchURL{"ID-1", GURL("https://www.google.com/")}); - urls.push_back(PrefetchURL{"ID-3", GURL("https://news.google.com/")}); - AddUniqueUrlsTask task2(store(), name_space, urls); + urls.push_back(PrefetchURL{kClientId4, kTestURL1, kTestTitle4}); + urls.push_back(PrefetchURL{kClientId3, kTestURL3, kTestTitle3}); + AddUniqueUrlsTask task2(store(), kTestNamespace, urls); task2.Run(); PumpLoop(); - // Do the count here. - EXPECT_EQ(3, store_util()->CountPrefetchItems()); + std::map<std::string, PrefetchItem> items = GetAllItems(); + ASSERT_EQ(3u, items.size()); + ASSERT_TRUE(items.count(kClientId1) > 0); + EXPECT_EQ(kTestURL1, items[kClientId1].url); + EXPECT_EQ(kTestNamespace, items[kClientId1].client_id.name_space); + EXPECT_EQ(kTestTitle1, items[kClientId1].title); + ASSERT_TRUE(items.count(kClientId2) > 0); + EXPECT_EQ(kTestURL2, items[kClientId2].url); + EXPECT_EQ(kTestNamespace, items[kClientId2].client_id.name_space); + EXPECT_EQ(kTestTitle2, items[kClientId2].title); + ASSERT_TRUE(items.count(kClientId3) > 0); + EXPECT_EQ(kTestURL3, items[kClientId3].url); + EXPECT_EQ(kTestNamespace, items[kClientId3].client_id.name_space); + EXPECT_EQ(kTestTitle3, items[kClientId3].title); } TEST_F(AddUniqueUrlsTaskTest, HandleZombiePrefetchItems) { - std::string name_space("test"); std::vector<PrefetchURL> urls; - urls.push_back(PrefetchURL{"ID-1", GURL("https://www.google.com/")}); - urls.push_back(PrefetchURL{"ID-2", GURL("http://www.example.com/")}); - urls.push_back(PrefetchURL{"ID-3", GURL("https://news.google.com/")}); - AddUniqueUrlsTask task1(store(), name_space, urls); + urls.push_back(PrefetchURL{kClientId1, kTestURL1, kTestTitle1}); + urls.push_back(PrefetchURL{kClientId2, kTestURL2, kTestTitle2}); + urls.push_back(PrefetchURL{kClientId3, kTestURL3, kTestTitle3}); + AddUniqueUrlsTask task1(store(), kTestNamespace, urls); task1.Run(); PumpLoop(); // ZombifyPrefetchItem returns the number of affected items. - EXPECT_EQ(1, store_util()->ZombifyPrefetchItems(name_space, urls[0].url)); - EXPECT_EQ(1, store_util()->ZombifyPrefetchItems(name_space, urls[1].url)); + EXPECT_EQ(1, store_util()->ZombifyPrefetchItems(kTestNamespace, urls[0].url)); + EXPECT_EQ(1, store_util()->ZombifyPrefetchItems(kTestNamespace, urls[1].url)); urls.clear(); - urls.push_back(PrefetchURL{"ID-1", GURL("https://www.google.com/")}); - urls.push_back(PrefetchURL{"ID-3", GURL("https://news.google.com/")}); - urls.push_back(PrefetchURL{"ID-4", GURL("https://chrome.google.com/")}); + urls.push_back(PrefetchURL{kClientId1, kTestURL1, kTestTitle1}); + urls.push_back(PrefetchURL{kClientId3, kTestURL3, kTestTitle3}); + urls.push_back(PrefetchURL{kClientId4, kTestURL4, kTestTitle4}); // ID-1 is expected to stay in zombie state. // ID-2 is expected to be removed, because it is in zombie state. // ID-3 is still requested, so it is ignored. // ID-4 is added. - AddUniqueUrlsTask task2(store(), name_space, urls); + AddUniqueUrlsTask task2(store(), kTestNamespace, urls); task2.Run(); PumpLoop(); - // Do the count here. - EXPECT_EQ(3, store_util()->CountPrefetchItems()); + std::map<std::string, PrefetchItem> items = GetAllItems(); + ASSERT_EQ(3u, items.size()); + ASSERT_TRUE(items.count(kClientId1) > 0); + EXPECT_EQ(kTestURL1, items[kClientId1].url); + EXPECT_EQ(kTestNamespace, items[kClientId1].client_id.name_space); + EXPECT_EQ(kTestTitle1, items[kClientId1].title); + ASSERT_TRUE(items.count(kClientId3) > 0); + EXPECT_EQ(kTestURL3, items[kClientId3].url); + EXPECT_EQ(kTestNamespace, items[kClientId3].client_id.name_space); + EXPECT_EQ(kTestTitle3, items[kClientId3].title); + ASSERT_TRUE(items.count(kClientId4) > 0); + EXPECT_EQ(kTestURL4, items[kClientId4].url); + EXPECT_EQ(kTestNamespace, items[kClientId4].client_id.name_space); + EXPECT_EQ(kTestTitle4, items[kClientId4].title); } } // namespace offline_pages
diff --git a/components/offline_pages/core/prefetch/mock_prefetch_item_generator.cc b/components/offline_pages/core/prefetch/mock_prefetch_item_generator.cc index d213aaa..130f123 100644 --- a/components/offline_pages/core/prefetch/mock_prefetch_item_generator.cc +++ b/components/offline_pages/core/prefetch/mock_prefetch_item_generator.cc
@@ -4,9 +4,12 @@ #include "components/offline_pages/core/prefetch/mock_prefetch_item_generator.h" +#include "base/files/file_path.h" #include "base/guid.h" #include "base/strings/string_number_conversions.h" +#include "base/strings/utf_string_conversions.h" #include "base/time/time.h" +#include "build/build_config.h" #include "components/offline_pages/core/client_id.h" #include "url/gurl.h" @@ -24,6 +27,8 @@ "test_operation_name_"); const std::string MockPrefetchItemGenerator::kArchiveBodyNamePrefix( "test_archive_body_name_"); +const std::string MockPrefetchItemGenerator::kTitlePrefix("test_title_"); +const std::string MockPrefetchItemGenerator::kFilePathPrefix("test_file_path_"); MockPrefetchItemGenerator::MockPrefetchItemGenerator() = default; @@ -31,6 +36,7 @@ PrefetchItem MockPrefetchItemGenerator::CreateItem(PrefetchItemState state) { static int item_counter = 0; + ++item_counter; PrefetchItem new_item; // Values set with non prefix based values. @@ -40,17 +46,21 @@ new_item.freshness_time = new_item.creation_time; // Values always set using prefixes. + CHECK(client_namespace_.length()); new_item.client_id = ClientId( client_namespace_, client_id_prefix_ + base::IntToString(item_counter)); new_item.url = GURL(url_prefix_ + base::IntToString(item_counter)); - ++item_counter; + if (title_prefix_.length()) { + new_item.title = + base::UTF8ToUTF16(title_prefix_ + base::IntToString(item_counter)); + } + if (state == PrefetchItemState::NEW_REQUEST || state == PrefetchItemState::SENT_GENERATE_PAGE_BUNDLE) { return new_item; } - // Values set only if prefixes are not empty. if (operation_name_prefix_.length()) { new_item.operation_name = operation_name_prefix_ + base::IntToString(item_counter); @@ -67,18 +77,27 @@ archive_body_name_prefix_ + base::IntToString(item_counter); new_item.archive_body_length = item_counter * 100; } - if (final_url_prefix_.length()) { new_item.final_archived_url = GURL(final_url_prefix_ + base::IntToString(item_counter)); } + if (state == PrefetchItemState::RECEIVED_BUNDLE) return new_item; new_item.guid = base::GenerateGUID(); + if (file_path_prefix_.length()) { + new_item.file_path = base::FilePath::FromUTF8Unsafe( + file_path_prefix_ + base::IntToString(item_counter)); + } - if (state == PrefetchItemState::DOWNLOADING || - state == PrefetchItemState::DOWNLOADED || + if (state == PrefetchItemState::DOWNLOADING) { + return new_item; + } + + new_item.file_size = new_item.archive_body_length; + + if (state == PrefetchItemState::DOWNLOADED || state == PrefetchItemState::IMPORTING || state == PrefetchItemState::FINISHED || state == PrefetchItemState::ZOMBIE) {
diff --git a/components/offline_pages/core/prefetch/mock_prefetch_item_generator.h b/components/offline_pages/core/prefetch/mock_prefetch_item_generator.h index bb53138..fef45c67 100644 --- a/components/offline_pages/core/prefetch/mock_prefetch_item_generator.h +++ b/components/offline_pages/core/prefetch/mock_prefetch_item_generator.h
@@ -27,6 +27,8 @@ static const std::string kFinalUrlPrefix; static const std::string kOperationNamePrefix; static const std::string kArchiveBodyNamePrefix; + static const std::string kTitlePrefix; + static const std::string kFilePathPrefix; MockPrefetchItemGenerator(); ~MockPrefetchItemGenerator(); @@ -57,6 +59,12 @@ void set_archive_body_name_prefix(std::string archive_body_name_prefix) { archive_body_name_prefix_ = archive_body_name_prefix; } + void set_title_prefix(std::string title_prefix) { + title_prefix_ = title_prefix; + } + void set_file_path_prefix(std::string file_path_prefix) { + file_path_prefix_ = file_path_prefix; + } private: // These namespace name and prefixes must always be set. @@ -69,6 +77,8 @@ std::string final_url_prefix_ = kFinalUrlPrefix; std::string operation_name_prefix_ = kOperationNamePrefix; std::string archive_body_name_prefix_ = kArchiveBodyNamePrefix; + std::string title_prefix_ = kTitlePrefix; + std::string file_path_prefix_ = kFilePathPrefix; // Test offline IDs start at an arbitrary, non-zero value to ease recognizing // generated ID values among other integer values while debugging.
diff --git a/components/offline_pages/core/prefetch/prefetch_dispatcher_impl.cc b/components/offline_pages/core/prefetch/prefetch_dispatcher_impl.cc index d0905a2..3662b03 100644 --- a/components/offline_pages/core/prefetch/prefetch_dispatcher_impl.cc +++ b/components/offline_pages/core/prefetch/prefetch_dispatcher_impl.cc
@@ -28,6 +28,7 @@ #include "components/offline_pages/core/prefetch/prefetch_network_request_factory.h" #include "components/offline_pages/core/prefetch/prefetch_service.h" #include "components/offline_pages/core/prefetch/prefetch_types.h" +#include "components/offline_pages/core/prefetch/stale_entry_finalizer_task.h" #include "components/offline_pages/core/prefetch/suggested_articles_observer.h" #include "components/offline_pages/core/task.h" #include "url/gurl.h" @@ -99,7 +100,14 @@ } void PrefetchDispatcherImpl::QueueReconcileTasks() { - // TODO(dimich): add Reconcile tasks here. + // Note: For optimal results StaleEntryFinalizerTask should be executed before + // other reconciler tasks that deal with external systems so that entries + // finalized by it will promptly effect any external processing they relate + // to. + task_queue_.AddTask( + base::MakeUnique<StaleEntryFinalizerTask>(service_->GetPrefetchStore())); + + // TODO(dimich): add more reconciliation tasks here. } void PrefetchDispatcherImpl::QueueActionTasks() {
diff --git a/components/offline_pages/core/prefetch/prefetch_dispatcher_impl_unittest.cc b/components/offline_pages/core/prefetch/prefetch_dispatcher_impl_unittest.cc index 7944ff1..3840df3 100644 --- a/components/offline_pages/core/prefetch/prefetch_dispatcher_impl_unittest.cc +++ b/components/offline_pages/core/prefetch/prefetch_dispatcher_impl_unittest.cc
@@ -92,8 +92,9 @@ taco_->CreatePrefetchService(); ASSERT_TRUE(test_urls_.empty()); - test_urls_.push_back({"1", GURL("http://testurl.com/foo")}); - test_urls_.push_back({"2", GURL("https://testurl.com/bar")}); + test_urls_.push_back({"1", GURL("http://testurl.com/foo"), base::string16()}); + test_urls_.push_back( + {"2", GURL("https://testurl.com/bar"), base::string16()}); } void PrefetchDispatcherTest::TearDown() { @@ -131,7 +132,8 @@ disabled_feature_list.InitAndDisableFeature(kPrefetchingOfflinePagesFeature); // Don't add a task for new prefetch URLs. - PrefetchURL prefetch_url("id", GURL("https://www.chromium.org")); + PrefetchURL prefetch_url("id", GURL("https://www.chromium.org"), + base::string16()); prefetch_dispatcher()->AddCandidatePrefetchURLs( kTestNamespace, std::vector<PrefetchURL>(1, prefetch_url)); EXPECT_FALSE(dispatcher_task_queue()->HasRunningTask());
diff --git a/components/offline_pages/core/prefetch/prefetch_downloader.h b/components/offline_pages/core/prefetch/prefetch_downloader.h index 4e7fc53..94c11534 100644 --- a/components/offline_pages/core/prefetch/prefetch_downloader.h +++ b/components/offline_pages/core/prefetch/prefetch_downloader.h
@@ -29,7 +29,12 @@ // Called when the download service is initialized and can accept the // downloads. - virtual void OnDownloadServiceReady() = 0; + virtual void OnDownloadServiceReady( + const std::vector<std::string>& outstanding_download_ids) = 0; + + // Called when the download service fails to initialize and should not be + // used. + virtual void OnDownloadServiceUnavailable() = 0; // Called when the download service is tearing down. virtual void OnDownloadServiceShutdown() = 0;
diff --git a/components/offline_pages/core/prefetch/prefetch_downloader_impl.cc b/components/offline_pages/core/prefetch/prefetch_downloader_impl.cc index 76eaecb..5f71425f 100644 --- a/components/offline_pages/core/prefetch/prefetch_downloader_impl.cc +++ b/components/offline_pages/core/prefetch/prefetch_downloader_impl.cc
@@ -50,9 +50,7 @@ params.traffic_annotation = net::MutableNetworkTrafficAnnotationTag(NO_TRAFFIC_ANNOTATION_YET); params.client = download::DownloadClient::OFFLINE_PAGE_PREFETCH; - // TODO(jianli): Remove the uppercase after the download service fixes - // this issue. - params.guid = base::ToUpperASCII(download_id); + params.guid = download_id; params.callback = base::Bind(&PrefetchDownloaderImpl::OnStartDownload, weak_ptr_factory_.GetWeakPtr()); params.request_params.url = PrefetchDownloadURL(download_location, channel_); @@ -74,11 +72,14 @@ pending_cancellations_.push_back(download_id); } -void PrefetchDownloaderImpl::OnDownloadServiceReady() { +void PrefetchDownloaderImpl::OnDownloadServiceReady( + const std::vector<std::string>& outstanding_download_ids) { DCHECK_EQ(download::DownloadService::ServiceStatus::READY, download_service_->GetStatus()); service_started_ = true; + // TODO(jianli): Remove orphaned downloads. + for (const auto& entry : pending_downloads_) StartDownload(entry.first, entry.second); pending_downloads_.clear(); @@ -88,6 +89,10 @@ pending_cancellations_.clear(); } +void PrefetchDownloaderImpl::OnDownloadServiceUnavailable() { + // TODO(jianli): Report UMA. +} + void PrefetchDownloaderImpl::OnDownloadServiceShutdown() { service_started_ = false; }
diff --git a/components/offline_pages/core/prefetch/prefetch_downloader_impl.h b/components/offline_pages/core/prefetch/prefetch_downloader_impl.h index f1290a8..206863e 100644 --- a/components/offline_pages/core/prefetch/prefetch_downloader_impl.h +++ b/components/offline_pages/core/prefetch/prefetch_downloader_impl.h
@@ -38,7 +38,9 @@ void StartDownload(const std::string& download_id, const std::string& download_location) override; void CancelDownload(const std::string& download_id) override; - void OnDownloadServiceReady() override; + void OnDownloadServiceReady( + const std::vector<std::string>& outstanding_download_ids) override; + void OnDownloadServiceUnavailable() override; void OnDownloadServiceShutdown() override; void OnDownloadSucceeded(const std::string& download_id, const base::FilePath& file_path,
diff --git a/components/offline_pages/core/prefetch/prefetch_downloader_impl_unittest.cc b/components/offline_pages/core/prefetch/prefetch_downloader_impl_unittest.cc index 9f81879..0e037c2 100644 --- a/components/offline_pages/core/prefetch/prefetch_downloader_impl_unittest.cc +++ b/components/offline_pages/core/prefetch/prefetch_downloader_impl_unittest.cc
@@ -11,7 +11,8 @@ #include "base/bind.h" #include "base/test/test_simple_task_runner.h" #include "base/threading/thread_task_runner_handle.h" -#include "components/download/public/download_service.h" +#include "components/download/internal/test/empty_client.h" +#include "components/download/internal/test/test_download_service.h" #include "components/download/public/service_config.h" #include "components/offline_pages/core/prefetch/prefetch_service.h" #include "components/offline_pages/core/prefetch/prefetch_service_test_taco.h" @@ -21,122 +22,37 @@ namespace { const version_info::Channel kTestChannel = version_info::Channel::UNKNOWN; -const char kDownloadId[] = "1234"; -const char kDownloadId2[] = "ABCD"; -const char kFailedDownloadId[] = "FFFFFF"; +const char kDownloadId[] = "1234Ab"; +const char kDownloadId2[] = "Abcd"; +const char kFailedDownloadId[] = "f1f1FF"; const char kDownloadLocation[] = "page/1"; const char kDownloadLocation2[] = "page/zz"; const char kServerPathForDownload[] = "/v1/media/page/1"; -const uint64_t kTestFileSize = 12345678u; } // namespace -namespace download { -class TestServiceConfig : public ServiceConfig { +namespace offline_pages { + +class TestDownloadClient : public download::test::EmptyClient { public: - TestServiceConfig() = default; - ~TestServiceConfig() override = default; + explicit TestDownloadClient(PrefetchDownloader* downloader) + : downloader_(downloader) {} - uint32_t GetMaxScheduledDownloadsPerClient() const override { return 0; } - const base::TimeDelta& GetFileKeepAliveTime() const override { - return time_delta_; - } + ~TestDownloadClient() override = default; - private: - base::TimeDelta time_delta_; -}; - -class TestDownloadService : public DownloadService { - public: - TestDownloadService() = default; - ~TestDownloadService() override = default; - - // DownloadService implementation. - const ServiceConfig& GetConfig() override { return service_config_; } - void OnStartScheduledTask(DownloadTaskType task_type, - const TaskFinishedCallback& callback) override {} - bool OnStopScheduledTask(DownloadTaskType task_type) override { return true; } - ServiceStatus GetStatus() override { - return ready_ ? DownloadService::ServiceStatus::READY - : DownloadService::ServiceStatus::STARTING_UP; - } - - void StartDownload(const DownloadParams& download_params) override { - if (!ready_) { - OnDownloadFailed(download_params.guid); - return; - } - downloads_.push_back(download_params); - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(&TestDownloadService::ProcessDownload, - base::Unretained(this))); - } - - void PauseDownload(const std::string& guid) override {} - void ResumeDownload(const std::string& guid) override {} - - void CancelDownload(const std::string& guid) override { - for (auto iter = downloads_.begin(); iter != downloads_.end(); ++iter) { - if (iter->guid == guid) { - downloads_.erase(iter); - return; - } - } - } - - void ChangeDownloadCriteria(const std::string& guid, - const SchedulingParams& params) override {} - - DownloadParams GetDownload(const std::string& guid) const { - for (auto iter = downloads_.begin(); iter != downloads_.end(); ++iter) { - if (iter->guid == guid) - return *iter; - } - DownloadParams params; - params.traffic_annotation = - net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); - return params; - } - - void set_ready(bool ready) { ready_ = ready; } - void set_prefetch_downloader( - offline_pages::PrefetchDownloaderImpl* prefetch_downloader) { - prefetch_downloader_ = prefetch_downloader; - } - - private: - void ProcessDownload() { - if (!ready_ || downloads_.empty()) - return; - DownloadParams params = downloads_.front(); - downloads_.pop_front(); - if (params.guid == kFailedDownloadId) - OnDownloadFailed(params.guid); - else - OnDownloadSucceeded(params.guid, base::FilePath(), kTestFileSize); + void OnDownloadFailed(const std::string& guid, + download::Client::FailureReason reason) override { + downloader_->OnDownloadFailed(guid); } void OnDownloadSucceeded(const std::string& guid, - const base::FilePath& file_path, - uint64_t file_size) { - if (prefetch_downloader_) - prefetch_downloader_->OnDownloadSucceeded(guid, file_path, file_size); + const base::FilePath& path, + uint64_t size) override { + downloader_->OnDownloadSucceeded(guid, path, size); } - void OnDownloadFailed(const std::string& guid) { - if (prefetch_downloader_) - prefetch_downloader_->OnDownloadFailed(guid); - } - - bool ready_ = false; - offline_pages::PrefetchDownloaderImpl* prefetch_downloader_ = nullptr; - TestServiceConfig service_config_; - std::list<DownloadParams> downloads_; - - DISALLOW_COPY_AND_ASSIGN(TestDownloadService); + private: + PrefetchDownloader* downloader_; }; -} // namespace download - -namespace offline_pages { class PrefetchDownloaderTest : public testing::Test { public: @@ -149,7 +65,9 @@ auto downloader = base::MakeUnique<PrefetchDownloaderImpl>( &download_service_, kTestChannel); - download_service_.set_prefetch_downloader(downloader.get()); + download_service_.SetFailedDownload(kFailedDownloadId, false); + download_client_ = base::MakeUnique<TestDownloadClient>(downloader.get()); + download_service_.set_client(download_client_.get()); prefetch_service_taco_->SetPrefetchDownloader(std::move(downloader)); prefetch_service_taco_->CreatePrefetchService(); @@ -163,11 +81,13 @@ } void SetDownloadServiceReady(bool ready) { - download_service_.set_ready(ready); - if (ready) - GetPrefetchDownloader()->OnDownloadServiceReady(); - else + download_service_.set_is_ready(ready); + if (ready) { + GetPrefetchDownloader()->OnDownloadServiceReady( + std::vector<std::string>()); + } else { GetPrefetchDownloader()->OnDownloadServiceShutdown(); + } } void StartDownload(const std::string& download_id, @@ -179,7 +99,8 @@ GetPrefetchDownloader()->CancelDownload(download_id); } - download::DownloadParams GetDownload(const std::string& guid) const { + base::Optional<download::DownloadParams> GetDownload( + const std::string& guid) const { return download_service_.GetDownload(guid); } @@ -200,7 +121,8 @@ scoped_refptr<base::TestSimpleTaskRunner> task_runner_; base::ThreadTaskRunnerHandle task_runner_handle_; - download::TestDownloadService download_service_; + download::test::TestDownloadService download_service_; + std::unique_ptr<TestDownloadClient> download_client_; std::unique_ptr<PrefetchServiceTestTaco> prefetch_service_taco_; std::vector<PrefetchDownloadResult> completed_downloads_; }; @@ -208,10 +130,11 @@ TEST_F(PrefetchDownloaderTest, DownloadParams) { SetDownloadServiceReady(true); StartDownload(kDownloadId, kDownloadLocation); - download::DownloadParams params = GetDownload(kDownloadId); - EXPECT_EQ(kDownloadId, params.guid); - EXPECT_EQ(download::DownloadClient::OFFLINE_PAGE_PREFETCH, params.client); - GURL download_url = params.request_params.url; + base::Optional<download::DownloadParams> params = GetDownload(kDownloadId); + ASSERT_TRUE(params.has_value()); + EXPECT_EQ(kDownloadId, params->guid); + EXPECT_EQ(download::DownloadClient::OFFLINE_PAGE_PREFETCH, params->client); + GURL download_url = params->request_params.url; EXPECT_TRUE(download_url.SchemeIs(url::kHttpsScheme)); EXPECT_EQ(kServerPathForDownload, download_url.path()); std::string key_value;
diff --git a/components/offline_pages/core/prefetch/prefetch_item.cc b/components/offline_pages/core/prefetch/prefetch_item.cc index dce74a9..291409a5 100644 --- a/components/offline_pages/core/prefetch/prefetch_item.cc +++ b/components/offline_pages/core/prefetch/prefetch_item.cc
@@ -7,6 +7,7 @@ #include <ostream> #include "base/strings/string_number_conversions.h" +#include "base/strings/utf_string_conversions.h" #include "components/offline_pages/core/offline_time_utils.h" namespace offline_pages { @@ -63,7 +64,10 @@ s.append(base::IntToString(archive_body_length)).append(", "); s.append(base::Int64ToString(ToDatabaseTime(creation_time))).append(", "); s.append(base::Int64ToString(ToDatabaseTime(freshness_time))).append(", "); - s.append(base::IntToString(static_cast<int>(error_code))).append(")"); + s.append(base::IntToString(static_cast<int>(error_code))).append(", "); + s.append(base::UTF16ToUTF8(title)).append(", "); + s.append(file_path.AsUTF8Unsafe()).append(", "); + s.append(base::IntToString(static_cast<int>(file_size))).append(")"); return s; }
diff --git a/components/offline_pages/core/prefetch/prefetch_item_unittest.cc b/components/offline_pages/core/prefetch/prefetch_item_unittest.cc index 24deda6..8be14345 100644 --- a/components/offline_pages/core/prefetch/prefetch_item_unittest.cc +++ b/components/offline_pages/core/prefetch/prefetch_item_unittest.cc
@@ -4,91 +4,135 @@ #include "components/offline_pages/core/prefetch/prefetch_item.h" +#include "base/strings/string_split.h" +#include "base/strings/stringprintf.h" +#include "base/strings/utf_string_conversions.h" #include "base/time/time.h" #include "components/offline_pages/core/prefetch/prefetch_types.h" +#include "components/offline_pages/core/prefetch/store/prefetch_store.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" namespace offline_pages { -TEST(PrefetchItemTest, OperatorEqualsAndCopyConstructor) { +class PrefetchItemTest : public testing::Test { + public: + void CheckFieldAndResetItem(PrefetchItem& item, const char* tested_field); + void CheckAllFieldsWereTested(); + + std::size_t GetTableColumnsCount(); + + private: + std::size_t checked_fields_counter_ = 0; +}; + +// Checks behavior of some PrefetchItem methods for an item with one single +// member updated to a non-default value. After testing the item is reset and +// |checked_fields_counter_| is incremented. +void PrefetchItemTest::CheckFieldAndResetItem(PrefetchItem& item, + const char* tested_field) { + EXPECT_NE(item, PrefetchItem()) + << "Item with updated \"" << tested_field + << "\" should not equal a default constructed item"; + EXPECT_EQ(item, PrefetchItem(item)) + << "Item with updated \"" << tested_field + << "\" should equal a copy constructed based off of it"; + EXPECT_NE(item.ToString(), PrefetchItem().ToString()) + << "Result of ToString() from an item with updated \"" << tested_field + << "\" should not equal the ToString() result from a default constructed" + " item"; + item = PrefetchItem(); + ++checked_fields_counter_; +} + +// Compares the |checked_fields_counter_| value with the number of columns in +// the SQLite table to make sure they match. This should be run after all +// PrefetchItem fields were verified with CheckFieldAndResetItem and it helps in +// confirming PrefetchItem implementation and tests are coping with changes in +// the table. +void PrefetchItemTest::CheckAllFieldsWereTested() { + // Note: the off-by-1 difference is due to the single client_id field, of type + // ClientID, representing 2 columns in the database table (client_namespace + // and client_id). + EXPECT_EQ(GetTableColumnsCount() - 1, checked_fields_counter_) + << "The number of tested fields mismatches the number of columns in the " + "database table."; +} + +// Computes the number of columns the SQL table has. +std::size_t PrefetchItemTest::GetTableColumnsCount() { + std::string tableCreationSql(PrefetchStore::GetTableCreationSqlForTesting()); + std::vector<std::string> create_statement_split = base::SplitString( + tableCreationSql, "()", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL); + EXPECT_EQ(3U, create_statement_split.size()); + + std::string& columns_list = create_statement_split[1]; + std::vector<std::string> columns_split = base::SplitString( + columns_list, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); + return columns_split.size(); +} + +TEST_F(PrefetchItemTest, OperatorEqualsCopyConstructorAndToString) { PrefetchItem item1; EXPECT_EQ(item1, PrefetchItem()); EXPECT_EQ(item1, PrefetchItem(item1)); + EXPECT_EQ(item1.ToString(), PrefetchItem().ToString()); item1.offline_id = 77L; - EXPECT_NE(item1, PrefetchItem()); - EXPECT_EQ(item1, PrefetchItem(item1)); - item1 = PrefetchItem(); + CheckFieldAndResetItem(item1, "offline_id"); item1.guid = "A"; - EXPECT_NE(item1, PrefetchItem()); - EXPECT_EQ(item1, PrefetchItem(item1)); - item1 = PrefetchItem(); + CheckFieldAndResetItem(item1, "guid"); item1.client_id = ClientId("B", "C"); - EXPECT_NE(item1, PrefetchItem()); - EXPECT_EQ(item1, PrefetchItem(item1)); - item1 = PrefetchItem(); + CheckFieldAndResetItem(item1, "client_id"); item1.state = PrefetchItemState::AWAITING_GCM; - EXPECT_NE(item1, PrefetchItem()); - EXPECT_EQ(item1, PrefetchItem(item1)); - item1 = PrefetchItem(); + CheckFieldAndResetItem(item1, "state"); item1.url = GURL("http://test.com"); - EXPECT_NE(item1, PrefetchItem()); - EXPECT_EQ(item1, PrefetchItem(item1)); - item1 = PrefetchItem(); + CheckFieldAndResetItem(item1, "url"); item1.final_archived_url = GURL("http://test.com/final"); - EXPECT_NE(item1, PrefetchItem()); - EXPECT_EQ(item1, PrefetchItem(item1)); - item1 = PrefetchItem(); + CheckFieldAndResetItem(item1, "final_archived_url"); item1.generate_bundle_attempts = 10; - EXPECT_NE(item1, PrefetchItem()); - EXPECT_EQ(item1, PrefetchItem(item1)); - item1 = PrefetchItem(); + CheckFieldAndResetItem(item1, "generate_bundle_attempts"); item1.get_operation_attempts = 11; - EXPECT_NE(item1, PrefetchItem()); - EXPECT_EQ(item1, PrefetchItem(item1)); - item1 = PrefetchItem(); + CheckFieldAndResetItem(item1, "get_operation_attempts"); item1.download_initiation_attempts = 12; - EXPECT_NE(item1, PrefetchItem()); - EXPECT_EQ(item1, PrefetchItem(item1)); - item1 = PrefetchItem(); + CheckFieldAndResetItem(item1, "download_initiation_attempts"); item1.operation_name = "D"; - EXPECT_NE(item1, PrefetchItem()); - EXPECT_EQ(item1, PrefetchItem(item1)); - item1 = PrefetchItem(); + CheckFieldAndResetItem(item1, "operation_name"); item1.archive_body_name = "E"; - EXPECT_NE(item1, PrefetchItem()); - EXPECT_EQ(item1, PrefetchItem(item1)); - item1 = PrefetchItem(); + CheckFieldAndResetItem(item1, "archive_body_name"); item1.archive_body_length = 20; - EXPECT_NE(item1, PrefetchItem()); - EXPECT_EQ(item1, PrefetchItem(item1)); - item1 = PrefetchItem(); + CheckFieldAndResetItem(item1, "archive_body_length"); item1.creation_time = base::Time::FromJavaTime(1000L); - EXPECT_NE(item1, PrefetchItem()); - EXPECT_EQ(item1, PrefetchItem(item1)); - item1 = PrefetchItem(); + CheckFieldAndResetItem(item1, "creation_time"); item1.freshness_time = base::Time::FromJavaTime(2000L); - EXPECT_NE(item1, PrefetchItem()); - EXPECT_EQ(item1, PrefetchItem(item1)); - item1 = PrefetchItem(); + CheckFieldAndResetItem(item1, "freshness_time"); - item1.error_code = PrefetchItemErrorCode::EXPIRED; - EXPECT_NE(item1, PrefetchItem()); - EXPECT_EQ(item1, PrefetchItem(item1)); + item1.error_code = PrefetchItemErrorCode::TOO_MANY_NEW_URLS; + CheckFieldAndResetItem(item1, "error_code"); + + item1.title = base::UTF8ToUTF16("F"); + CheckFieldAndResetItem(item1, "title"); + + item1.file_path = base::FilePath(FILE_PATH_LITERAL("G")); + CheckFieldAndResetItem(item1, "file_path"); + + item1.file_size = 30; + CheckFieldAndResetItem(item1, "file_size"); + + CheckAllFieldsWereTested(); } } // namespace offline_pages
diff --git a/components/offline_pages/core/prefetch/prefetch_types.h b/components/offline_pages/core/prefetch/prefetch_types.h index 415135d..0f30539 100644 --- a/components/offline_pages/core/prefetch/prefetch_types.h +++ b/components/offline_pages/core/prefetch/prefetch_types.h
@@ -9,6 +9,7 @@ #include <vector> #include "base/files/file_path.h" +#include "base/strings/string16.h" #include "base/time/time.h" #include "components/offline_pages/core/client_id.h" #include "url/gurl.h" @@ -72,53 +73,68 @@ NEW_REQUEST = 0, // The item has been included in a GeneratePageBundle RPC requesting the // creation of an archive for its URL. - SENT_GENERATE_PAGE_BUNDLE, + SENT_GENERATE_PAGE_BUNDLE = 10, // The archive was not immediately available (cached) upon the request and // is now waiting for a GCM message notifying of its archiving operation // completion. - AWAITING_GCM, + AWAITING_GCM = 20, // The GCM message notifying of the archiving operation completion was // received for this item. - RECEIVED_GCM, + RECEIVED_GCM = 30, // A GetOperation RPC was sent for this item to query for the final results // of its archiving request. - SENT_GET_OPERATION, + SENT_GET_OPERATION = 40, // Information was received about a successfully created archive for this // item that can now be downloaded. - RECEIVED_BUNDLE, + RECEIVED_BUNDLE = 50, // This item's archive is currently being downloaded. - DOWNLOADING, + DOWNLOADING = 60, // The archive has been downloaded, waiting to be imported into offline pages // model. - DOWNLOADED, + DOWNLOADED = 70, // The archive is being imported into offline pages model. - IMPORTING, + IMPORTING = 80, // Item has finished processing, successfully or otherwise, and is waiting to // be processed for stats reporting to UMA. - FINISHED, + FINISHED = 90, // UMA stats have been reported and the item is being kept just long enough // to confirm that the same URL is not being repeatedly requested by its // client. - ZOMBIE, + ZOMBIE = 100, }; -// Error codes used to identify the reason why a prefetch item has finished -// processing. +// Error codes used to identify the reason why a prefetch entry has finished +// processing in the pipeline. This values are only meaningful for entries in +// the "finished" state. enum class PrefetchItemErrorCode { - // 0 used as default value for SQLite field. + // The entry had gone through the pipeline and successfully completed + // prefetching. Explicitly setting to 0 as that is the default value for the + // respective SQLite column. SUCCESS = 0, - EXPIRED, - // Got too many Urls from suggestions, canceled this one. See kMaxUrlsToSend + // Got too many URLs from suggestions, canceled this one. See kMaxUrlsToSend // defined in GeneratePageBundleTask. - TOO_MANY_NEW_URLS, - DOWNLOAD_ERROR, - IMPORT_ERROR, + TOO_MANY_NEW_URLS = 100, + // An error happened while attempting to download the archive file. + DOWNLOAD_ERROR = 200, + // An error happened while importing the downloaded archive file int the + // Offline Pages system. + IMPORT_ERROR = 300, // Got a failure result from GetOperation (or the GeneratePageBundle // metadata). - ARCHIVING_FAILED, + ARCHIVING_FAILED = 400, // Got a failure result from GetOperation or GeneratePageBundle that a // server-side limit on the page was exceeded. - ARCHIVING_LIMIT_EXCEEDED, + ARCHIVING_LIMIT_EXCEEDED = 500, + // These next STALE_AT_* values identify entries that stayed for too long in + // the same pipeline bucket so that their "freshness date" was considered too + // old for what was allowed for that bucket. See StaleEntryFinalizerTask for + // more details. + STALE_AT_NEW_REQUEST = 600, + STALE_AT_AWAITING_GCM = 700, + STALE_AT_RECEIVED_GCM = 800, + STALE_AT_RECEIVED_BUNDLE = 900, + STALE_AT_DOWNLOADING = 1000, + STALE_AT_UNKNOWN = 1100, }; // Callback invoked upon completion of a prefetch request. @@ -129,7 +145,10 @@ // Holds information about a suggested URL to be prefetched. struct PrefetchURL { - PrefetchURL(const std::string& id, const GURL& url) : id(id), url(url) {} + PrefetchURL(const std::string& id, + const GURL& url, + const base::string16& title) + : id(id), url(url), title(title) {} // Client provided ID to allow the matching of provided URLs to the respective // work item in the prefetching system within that client's assigned @@ -139,6 +158,9 @@ // This URL will be prefetched by the service. GURL url; + + // The title of the page. + base::string16 title; }; // Result of a completed download.
diff --git a/components/offline_pages/core/prefetch/stale_entry_finalizer_task.cc b/components/offline_pages/core/prefetch/stale_entry_finalizer_task.cc new file mode 100644 index 0000000..9c556a4c --- /dev/null +++ b/components/offline_pages/core/prefetch/stale_entry_finalizer_task.cc
@@ -0,0 +1,130 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/offline_pages/core/prefetch/stale_entry_finalizer_task.h" + +#include <array> + +#include "base/bind.h" +#include "components/offline_pages/core/offline_time_utils.h" +#include "components/offline_pages/core/prefetch/prefetch_types.h" +#include "components/offline_pages/core/prefetch/store/prefetch_store.h" +#include "sql/connection.h" +#include "sql/statement.h" +#include "sql/transaction.h" + +namespace offline_pages { + +namespace { + +const base::TimeDelta FreshnessPeriodForState(PrefetchItemState state) { + switch (state) { + // Bucket 1. + case PrefetchItemState::NEW_REQUEST: + return base::TimeDelta::FromDays(1); + // Bucket 2. + case PrefetchItemState::AWAITING_GCM: + case PrefetchItemState::RECEIVED_GCM: + case PrefetchItemState::RECEIVED_BUNDLE: + return base::TimeDelta::FromDays(1); + // Bucket 3. + case PrefetchItemState::DOWNLOADING: + return base::TimeDelta::FromDays(2); + default: + NOTREACHED(); + } + return base::TimeDelta::FromDays(1); +} + +PrefetchItemErrorCode ErrorCodeForState(PrefetchItemState state) { + switch (state) { + case PrefetchItemState::NEW_REQUEST: + return PrefetchItemErrorCode::STALE_AT_NEW_REQUEST; + case PrefetchItemState::AWAITING_GCM: + return PrefetchItemErrorCode::STALE_AT_AWAITING_GCM; + case PrefetchItemState::RECEIVED_GCM: + return PrefetchItemErrorCode::STALE_AT_RECEIVED_GCM; + case PrefetchItemState::RECEIVED_BUNDLE: + return PrefetchItemErrorCode::STALE_AT_RECEIVED_BUNDLE; + case PrefetchItemState::DOWNLOADING: + return PrefetchItemErrorCode::STALE_AT_DOWNLOADING; + default: + NOTREACHED(); + } + return PrefetchItemErrorCode::STALE_AT_UNKNOWN; +} + +bool FinalizeStaleItems(PrefetchItemState state, + base::Time now, + sql::Connection* db) { + static const char kSql[] = + "UPDATE prefetch_items SET state = ?, error_code = ?" + " WHERE state = ? AND freshness_time < ?"; + const int64_t earliest_fresh_db_time = + ToDatabaseTime(now - FreshnessPeriodForState(state)); + sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql)); + statement.BindInt(0, static_cast<int>(PrefetchItemState::FINISHED)); + statement.BindInt(1, static_cast<int>(ErrorCodeForState(state))); + statement.BindInt(2, static_cast<int>(state)); + statement.BindInt64(3, earliest_fresh_db_time); + + return statement.Run(); +} + +bool FinalizeStaleEntriesSync(StaleEntryFinalizerTask::NowGetter now_getter, + sql::Connection* db) { + if (!db) + return false; + + sql::Transaction transaction(db); + if (!transaction.Begin()) + return false; + + const std::array<PrefetchItemState, 5> expirable_states = {{ + // Bucket 1. + PrefetchItemState::NEW_REQUEST, + // Bucket 2. + PrefetchItemState::AWAITING_GCM, PrefetchItemState::RECEIVED_GCM, + PrefetchItemState::RECEIVED_BUNDLE, + // Bucket 3. + PrefetchItemState::DOWNLOADING, + }}; + base::Time now = now_getter.Run(); + for (PrefetchItemState state : expirable_states) { + if (!FinalizeStaleItems(state, now, db)) + return false; + } + + // If all FinalizeStaleItems calls succeeded the transaction is committed. + return transaction.Commit(); +} + +} // namespace + +StaleEntryFinalizerTask::StaleEntryFinalizerTask(PrefetchStore* prefetch_store) + : prefetch_store_(prefetch_store), + now_getter_(base::BindRepeating(&base::Time::Now)), + weak_ptr_factory_(this) { + DCHECK(prefetch_store_); +} + +StaleEntryFinalizerTask::~StaleEntryFinalizerTask() {} + +void StaleEntryFinalizerTask::Run() { + prefetch_store_->Execute( + base::BindOnce(&FinalizeStaleEntriesSync, now_getter_), + base::BindOnce(&StaleEntryFinalizerTask::OnFinished, + weak_ptr_factory_.GetWeakPtr())); +} + +void StaleEntryFinalizerTask::SetNowGetterForTesting(NowGetter now_getter) { + now_getter_ = now_getter; +} + +void StaleEntryFinalizerTask::OnFinished(bool success) { + ran_successfully_ = success; + TaskComplete(); +} + +} // namespace offline_pages
diff --git a/components/offline_pages/core/prefetch/stale_entry_finalizer_task.h b/components/offline_pages/core/prefetch/stale_entry_finalizer_task.h new file mode 100644 index 0000000..ac974a7 --- /dev/null +++ b/components/offline_pages/core/prefetch/stale_entry_finalizer_task.h
@@ -0,0 +1,56 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_OFFLINE_PAGES_CORE_PREFETCH_STALE_ENTRY_FINALIZER_TASK_H_ +#define COMPONENTS_OFFLINE_PAGES_CORE_PREFETCH_STALE_ENTRY_FINALIZER_TASK_H_ + +#include <vector> + +#include "base/callback.h" +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "components/offline_pages/core/task.h" + +namespace offline_pages { +class PrefetchStore; + +// Reconciliation task responsible for finalizing entries for which their +// freshness date are past the limits specific to each pipeline bucket. Entries +// considered stale are moved to the "finished" state and have their error code +// column set to the PrefetchItemErrorCode value that identifies the bucket they +// were at. +class StaleEntryFinalizerTask : public Task { + public: + using NowGetter = base::RepeatingCallback<base::Time()>; + + StaleEntryFinalizerTask(PrefetchStore* prefetch_store); + ~StaleEntryFinalizerTask() override; + + void Run() override; + + // Allows tests to control the source of current time values used internally + // for freshness checks. + void SetNowGetterForTesting(NowGetter now_getter); + + // Will be set to true upon after an error-free run. + bool ran_successfully() { return ran_successfully_; } + + private: + void OnFinished(bool success); + + // Prefetch store to execute against. Not owned. + PrefetchStore* prefetch_store_; + + // Defaults to base::Time::Now upon construction. + NowGetter now_getter_; + + bool ran_successfully_ = false; + + base::WeakPtrFactory<StaleEntryFinalizerTask> weak_ptr_factory_; + DISALLOW_COPY_AND_ASSIGN(StaleEntryFinalizerTask); +}; + +} // namespace offline_pages + +#endif // COMPONENTS_OFFLINE_PAGES_CORE_PREFETCH_STALE_ENTRY_FINALIZER_TASK_H_
diff --git a/components/offline_pages/core/prefetch/stale_entry_finalizer_task_unittest.cc b/components/offline_pages/core/prefetch/stale_entry_finalizer_task_unittest.cc new file mode 100644 index 0000000..b6fb110 --- /dev/null +++ b/components/offline_pages/core/prefetch/stale_entry_finalizer_task_unittest.cc
@@ -0,0 +1,195 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/offline_pages/core/prefetch/stale_entry_finalizer_task.h" + +#include <set> + +#include "base/bind.h" +#include "base/memory/ptr_util.h" +#include "base/strings/string_number_conversions.h" +#include "base/test/test_simple_task_runner.h" +#include "base/threading/thread_task_runner_handle.h" +#include "components/offline_pages/core/prefetch/mock_prefetch_item_generator.h" +#include "components/offline_pages/core/prefetch/prefetch_item.h" +#include "components/offline_pages/core/prefetch/prefetch_types.h" +#include "components/offline_pages/core/prefetch/store/prefetch_store_test_util.h" +#include "components/offline_pages/core/prefetch/task_test_base.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace offline_pages { + +std::set<PrefetchItem> Filter(const std::set<PrefetchItem>& items, + PrefetchItemState state) { + std::set<PrefetchItem> result; + for (const PrefetchItem& item : items) { + if (item.state == state) + result.insert(item); + } + return result; +} + +class StaleEntryFinalizerTaskTest : public TaskTestBase { + public: + StaleEntryFinalizerTaskTest() = default; + ~StaleEntryFinalizerTaskTest() override = default; + + void SetUp() override; + void TearDown() override; + + PrefetchItem CreateAndInsertItem(PrefetchItemState state, + int hours_in_the_past); + + protected: + std::unique_ptr<StaleEntryFinalizerTask> stale_finalizer_task_; + base::Time fake_now_; +}; + +void StaleEntryFinalizerTaskTest::SetUp() { + TaskTestBase::SetUp(); + stale_finalizer_task_ = base::MakeUnique<StaleEntryFinalizerTask>(store()); + fake_now_ = base::Time() + base::TimeDelta::FromDays(100); + stale_finalizer_task_->SetNowGetterForTesting(base::BindRepeating( + [](base::Time t) -> base::Time { return t; }, fake_now_)); +} + +void StaleEntryFinalizerTaskTest::TearDown() { + stale_finalizer_task_.reset(); + TaskTestBase::TearDown(); +} + +PrefetchItem StaleEntryFinalizerTaskTest::CreateAndInsertItem( + PrefetchItemState state, + int hours_in_the_past) { + PrefetchItem item(item_generator()->CreateItem(state)); + item.freshness_time = + fake_now_ - base::TimeDelta::FromHours(hours_in_the_past); + EXPECT_TRUE(store_util()->InsertPrefetchItem(item)) + << "Failed inserting item with state " << static_cast<int>(state); + return item; +} + +// Tests that the task works correctly with an empty database. +TEST_F(StaleEntryFinalizerTaskTest, EmptyRun) { + std::set<PrefetchItem> no_items; + EXPECT_EQ(0U, store_util()->GetAllItems(&no_items)); + + // Execute the expiration task. + ExpectTaskCompletes(stale_finalizer_task_.get()); + stale_finalizer_task_->Run(); + RunUntilIdle(); + EXPECT_TRUE(stale_finalizer_task_->ran_successfully()); + EXPECT_EQ(0U, store_util()->GetAllItems(&no_items)); +} + +// Verifies that expired and non-expired items from all expirable states are +// properly handled. +TEST_F(StaleEntryFinalizerTaskTest, HandlesFreshnessTimesCorrectly) { + // Insert fresh and stale items for all expirable states from all buckets. + PrefetchItem b1_item1_fresh = + CreateAndInsertItem(PrefetchItemState::NEW_REQUEST, 23); + PrefetchItem b1_item2_stale = + CreateAndInsertItem(PrefetchItemState::NEW_REQUEST, 25); + + PrefetchItem b2_item1_fresh = + CreateAndInsertItem(PrefetchItemState::AWAITING_GCM, 23); + PrefetchItem b2_item2_stale = + CreateAndInsertItem(PrefetchItemState::AWAITING_GCM, 25); + PrefetchItem b2_item3_fresh = + CreateAndInsertItem(PrefetchItemState::RECEIVED_GCM, 23); + PrefetchItem b2_item4_stale = + CreateAndInsertItem(PrefetchItemState::RECEIVED_GCM, 25); + PrefetchItem b2_item5_fresh = + CreateAndInsertItem(PrefetchItemState::RECEIVED_BUNDLE, 23); + PrefetchItem b2_item6_stale = + CreateAndInsertItem(PrefetchItemState::RECEIVED_BUNDLE, 25); + + PrefetchItem b3_item1_fresh = + CreateAndInsertItem(PrefetchItemState::DOWNLOADING, 47); + PrefetchItem b3_item2_stale = + CreateAndInsertItem(PrefetchItemState::DOWNLOADING, 49); + + // Check inserted initial items. + std::set<PrefetchItem> initial_items = { + b1_item1_fresh, b1_item2_stale, b2_item1_fresh, b2_item2_stale, + b2_item3_fresh, b2_item4_stale, b2_item5_fresh, b2_item6_stale, + b3_item1_fresh, b3_item2_stale}; + std::set<PrefetchItem> all_inserted_items; + EXPECT_EQ(10U, store_util()->GetAllItems(&all_inserted_items)); + EXPECT_EQ(initial_items, all_inserted_items); + + // Execute the expiration task. + ExpectTaskCompletes(stale_finalizer_task_.get()); + stale_finalizer_task_->Run(); + RunUntilIdle(); + EXPECT_TRUE(stale_finalizer_task_->ran_successfully()); + + // Create the expected finished version of each stale item. + PrefetchItem b1_item2_finished(b1_item2_stale); + b1_item2_finished.state = PrefetchItemState::FINISHED; + b1_item2_finished.error_code = PrefetchItemErrorCode::STALE_AT_NEW_REQUEST; + PrefetchItem b2_item2_finished(b2_item2_stale); + b2_item2_finished.state = PrefetchItemState::FINISHED; + b2_item2_finished.error_code = PrefetchItemErrorCode::STALE_AT_AWAITING_GCM; + PrefetchItem b2_item4_finished(b2_item4_stale); + b2_item4_finished.state = PrefetchItemState::FINISHED; + b2_item4_finished.error_code = PrefetchItemErrorCode::STALE_AT_RECEIVED_GCM; + PrefetchItem b2_item6_finished(b2_item6_stale); + b2_item6_finished.state = PrefetchItemState::FINISHED; + b2_item6_finished.error_code = + PrefetchItemErrorCode::STALE_AT_RECEIVED_BUNDLE; + PrefetchItem b3_item2_finished(b3_item2_stale); + b3_item2_finished.state = PrefetchItemState::FINISHED; + b3_item2_finished.error_code = PrefetchItemErrorCode::STALE_AT_DOWNLOADING; + + // Creates the expected set of final items and compares with what's in store. + std::set<PrefetchItem> expected_final_items = { + b1_item1_fresh, b1_item2_finished, b2_item1_fresh, b2_item2_finished, + b2_item3_fresh, b2_item4_finished, b2_item5_fresh, b2_item6_finished, + b3_item1_fresh, b3_item2_finished}; + EXPECT_EQ(10U, expected_final_items.size()); + std::set<PrefetchItem> all_items_post_expiration; + EXPECT_EQ(10U, store_util()->GetAllItems(&all_items_post_expiration)); + EXPECT_EQ(expected_final_items, all_items_post_expiration); +} + +// Checks that items from all states are handled properly by the task when all +// their freshness dates are really old. +TEST_F(StaleEntryFinalizerTaskTest, HandlesStalesInAllStatesCorrectly) { + // Insert "stale" items for every state. + const int many_hours = 7 * 24; + CreateAndInsertItem(PrefetchItemState::NEW_REQUEST, many_hours); + CreateAndInsertItem(PrefetchItemState::SENT_GENERATE_PAGE_BUNDLE, many_hours); + CreateAndInsertItem(PrefetchItemState::AWAITING_GCM, many_hours); + CreateAndInsertItem(PrefetchItemState::RECEIVED_GCM, many_hours); + CreateAndInsertItem(PrefetchItemState::SENT_GET_OPERATION, many_hours); + CreateAndInsertItem(PrefetchItemState::RECEIVED_BUNDLE, many_hours); + CreateAndInsertItem(PrefetchItemState::DOWNLOADING, many_hours); + CreateAndInsertItem(PrefetchItemState::DOWNLOADED, many_hours); + CreateAndInsertItem(PrefetchItemState::IMPORTING, many_hours); + CreateAndInsertItem(PrefetchItemState::FINISHED, many_hours); + CreateAndInsertItem(PrefetchItemState::ZOMBIE, many_hours); + EXPECT_EQ(11, store_util()->CountPrefetchItems()); + + // Execute the expiration task. + ExpectTaskCompletes(stale_finalizer_task_.get()); + stale_finalizer_task_->Run(); + RunUntilIdle(); + EXPECT_TRUE(stale_finalizer_task_->ran_successfully()); + + // Checks item counts for states expected to still exist. + std::set<PrefetchItem> post_items; + EXPECT_EQ(11U, store_util()->GetAllItems(&post_items)); + EXPECT_EQ( + 1U, + Filter(post_items, PrefetchItemState::SENT_GENERATE_PAGE_BUNDLE).size()); + EXPECT_EQ(1U, + Filter(post_items, PrefetchItemState::SENT_GET_OPERATION).size()); + EXPECT_EQ(1U, Filter(post_items, PrefetchItemState::DOWNLOADED).size()); + EXPECT_EQ(1U, Filter(post_items, PrefetchItemState::IMPORTING).size()); + EXPECT_EQ(6U, Filter(post_items, PrefetchItemState::FINISHED).size()); + EXPECT_EQ(1U, Filter(post_items, PrefetchItemState::ZOMBIE).size()); +} + +} // namespace offline_pages
diff --git a/components/offline_pages/core/prefetch/store/prefetch_store.cc b/components/offline_pages/core/prefetch/store/prefetch_store.cc index e0e3869..68c65a2 100644 --- a/components/offline_pages/core/prefetch/store/prefetch_store.cc +++ b/components/offline_pages/core/prefetch/store/prefetch_store.cc
@@ -34,30 +34,43 @@ base::Callback<void(InitializationStatus, std::unique_ptr<sql::Connection>)>; +// IMPORTANT: when making changes to these columns please also reflect them +// into: +// - PrefetchItem: update existing fields and all method implementations +// (operator=, operator<<, ToString, etc). +// - PrefetchItemTest, PrefetchStoreTestUtil: update test related code to cover +// the changed set of columns and PrefetchItem members. +// - MockPrefetchItemGenerator: so that its generated items consider all fields. +// IMPORTANT #2: the order of columns types is also important in SQLite tables +// for optimizing space utilization. Fixed length types must come first and +// variable length types later. +static const char kTableCreationSql[] = + "CREATE TABLE prefetch_items" + // Fixed length columns come first. + "(offline_id INTEGER PRIMARY KEY NOT NULL," + " state INTEGER NOT NULL DEFAULT 0," + " generate_bundle_attempts INTEGER NOT NULL DEFAULT 0," + " get_operation_attempts INTEGER NOT NULL DEFAULT 0," + " download_initiation_attempts INTEGER NOT NULL DEFAULT 0," + " archive_body_length INTEGER_NOT_NULL DEFAULT -1," + " creation_time INTEGER NOT NULL," + " freshness_time INTEGER NOT NULL," + " error_code INTEGER NOT NULL DEFAULT 0," + " file_size INTEGER NOT NULL DEFAULT 0," + // Variable length columns come later. + " guid VARCHAR NOT NULL DEFAULT ''," + " client_namespace VARCHAR NOT NULL DEFAULT ''," + " client_id VARCHAR NOT NULL DEFAULT ''," + " requested_url VARCHAR NOT NULL DEFAULT ''," + " final_archived_url VARCHAR NOT NULL DEFAULT ''," + " operation_name VARCHAR NOT NULL DEFAULT ''," + " archive_body_name VARCHAR NOT NULL DEFAULT ''," + " title VARCHAR NOT NULL DEFAULT ''," + " file_path VARCHAR NOT NULL DEFAULT ''" + ")"; + bool CreatePrefetchItemsTable(sql::Connection* db) { - static const char kSql[] = - "CREATE TABLE prefetch_items" - "(offline_id INTEGER PRIMARY KEY NOT NULL," - " state INTEGER NOT NULL DEFAULT 0," - " generate_bundle_attempts INTEGER NOT NULL DEFAULT 0," - " get_operation_attempts INTEGER NOT NULL DEFAULT 0," - " download_initiation_attempts INTEGER NOT NULL DEFAULT 0," - " archive_body_length INTEGER_NOT_NULL DEFAULT -1," - " creation_time INTEGER NOT NULL," - " freshness_time INTEGER NOT NULL," - " error_code INTEGER NOT NULL DEFAULT 0," - " guid VARCHAR NOT NULL DEFAULT ''," - " client_namespace VARCHAR NOT NULL DEFAULT ''," - " client_id VARCHAR NOT NULL DEFAULT ''," - " requested_url VARCHAR NOT NULL DEFAULT ''," - " final_archived_url VARCHAR NOT NULL DEFAULT ''," - " operation_name VARCHAR NOT NULL DEFAULT ''," - " archive_body_name VARCHAR NOT NULL DEFAULT ''," - " title VARCHAR NOT NULL DEFAULT ''," - " file_path VARCHAR NOT NULL DEFAULT ''," - " file_size INTEGER NOT NULL DEFAULT 0" - ")"; - return db->Execute(kSql); + return db->Execute(kTableCreationSql); } bool CreateSchema(sql::Connection* db) { @@ -174,4 +187,9 @@ initialization_status_ = InitializationStatus::NOT_INITIALIZED; } +// static +const char* PrefetchStore::GetTableCreationSqlForTesting() { + return kTableCreationSql; +} + } // namespace offline_pages
diff --git a/components/offline_pages/core/prefetch/store/prefetch_store.h b/components/offline_pages/core/prefetch/store/prefetch_store.h index 7be88483..713573f 100644 --- a/components/offline_pages/core/prefetch/store/prefetch_store.h +++ b/components/offline_pages/core/prefetch/store/prefetch_store.h
@@ -92,6 +92,8 @@ return initialization_status_; } + static const char* GetTableCreationSqlForTesting(); + private: // Used internally to initialize connection. void Initialize(base::OnceClosure pending_command);
diff --git a/components/offline_pages/core/prefetch/store/prefetch_store_unittest.cc b/components/offline_pages/core/prefetch/store/prefetch_store_unittest.cc index 3212dc9..3e21507 100644 --- a/components/offline_pages/core/prefetch/store/prefetch_store_unittest.cc +++ b/components/offline_pages/core/prefetch/store/prefetch_store_unittest.cc
@@ -61,7 +61,8 @@ item1.download_initiation_attempts = 12; item1.creation_time = FromDatabaseTime(1000L); item1.freshness_time = FromDatabaseTime(2000L); - item1.error_code = PrefetchItemErrorCode::EXPIRED; + item1.error_code = PrefetchItemErrorCode::TOO_MANY_NEW_URLS; + item1.file_size = item1.archive_body_length + 1; EXPECT_TRUE(store_util()->InsertPrefetchItem(item1)); std::set<PrefetchItem> all_items;
diff --git a/components/offline_pages/core/prefetch/suggested_articles_observer.cc b/components/offline_pages/core/prefetch/suggested_articles_observer.cc index 75a7f33..806d845 100644 --- a/components/offline_pages/core/prefetch/suggested_articles_observer.cc +++ b/components/offline_pages/core/prefetch/suggested_articles_observer.cc
@@ -64,8 +64,8 @@ : content_suggestions_service_->GetSuggestionsForCategory( ArticlesCategory()); for (const ContentSuggestion& suggestion : suggestions) { - prefetch_urls.push_back( - {suggestion.id().id_within_category(), suggestion.url()}); + prefetch_urls.push_back({suggestion.id().id_within_category(), + suggestion.url(), suggestion.title()}); } *result = prefetch_urls;
diff --git a/components/offline_pages/core/prefetch/suggested_articles_observer_unittest.cc b/components/offline_pages/core/prefetch/suggested_articles_observer_unittest.cc index a243c2e..ea86549 100644 --- a/components/offline_pages/core/prefetch/suggested_articles_observer_unittest.cc +++ b/components/offline_pages/core/prefetch/suggested_articles_observer_unittest.cc
@@ -5,6 +5,7 @@ #include "components/offline_pages/core/prefetch/suggested_articles_observer.h" #include "base/run_loop.h" +#include "base/strings/utf_string_conversions.h" #include "base/test/test_simple_task_runner.h" #include "base/threading/thread_task_runner_handle.h" #include "components/offline_pages/core/client_namespace_constants.h" @@ -24,10 +25,15 @@ namespace { +const base::string16 kTestTitle = base::ASCIIToUTF16("Title 1"); + ContentSuggestion ContentSuggestionFromTestURL(const GURL& test_url) { auto category = Category::FromKnownCategory(ntp_snippets::KnownCategories::ARTICLES); - return ContentSuggestion(category, test_url.spec(), test_url); + ContentSuggestion suggestion = + ContentSuggestion(category, test_url.spec(), test_url); + suggestion.set_title(kTestTitle); + return suggestion; } } // namespace @@ -89,6 +95,8 @@ EXPECT_EQ(1U, test_prefetch_dispatcher()->latest_prefetch_urls.size()); EXPECT_EQ(test_url_1, test_prefetch_dispatcher()->latest_prefetch_urls[0].url); + EXPECT_EQ(kTestTitle, + test_prefetch_dispatcher()->latest_prefetch_urls[0].title); EXPECT_EQ(kSuggestedArticlesNamespace, test_prefetch_dispatcher()->latest_name_space); }
diff --git a/components/offline_pages/core/stub_offline_page_model.cc b/components/offline_pages/core/stub_offline_page_model.cc index 0398211f..5808083 100644 --- a/components/offline_pages/core/stub_offline_page_model.cc +++ b/components/offline_pages/core/stub_offline_page_model.cc
@@ -48,6 +48,9 @@ const GURL& url, URLSearchMode url_search_mode, const MultipleOfflinePageItemCallback& callback) {} +void StubOfflinePageModel::GetPagesByRequestOrigin( + const std::string& origin, + const MultipleOfflinePageItemCallback& callback) {} ClientPolicyController* StubOfflinePageModel::GetPolicyController() { return &policy_controller_; }
diff --git a/components/offline_pages/core/stub_offline_page_model.h b/components/offline_pages/core/stub_offline_page_model.h index e540930..11d9c9f 100644 --- a/components/offline_pages/core/stub_offline_page_model.h +++ b/components/offline_pages/core/stub_offline_page_model.h
@@ -58,6 +58,9 @@ const GURL& url, URLSearchMode url_search_mode, const MultipleOfflinePageItemCallback& callback) override; + void GetPagesByRequestOrigin( + const std::string& origin, + const MultipleOfflinePageItemCallback& callback) override; ClientPolicyController* GetPolicyController() override; bool is_loaded() const override; OfflineEventLogger* GetLogger() override;
diff --git a/components/omnibox/browser/omnibox_metrics_provider.cc b/components/omnibox/browser/omnibox_metrics_provider.cc index 1848e571..37ba2f6 100644 --- a/components/omnibox/browser/omnibox_metrics_provider.cc +++ b/components/omnibox/browser/omnibox_metrics_provider.cc
@@ -117,7 +117,7 @@ base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY); OmniboxEventProto* omnibox_event = omnibox_events_cache.add_omnibox_event(); - omnibox_event->set_time(metrics::MetricsLog::GetCurrentTime()); + omnibox_event->set_time_sec(metrics::MetricsLog::GetCurrentTime()); if (log.tab_id != -1) { // If we know what tab the autocomplete URL was opened in, log it. omnibox_event->set_tab_id(log.tab_id);
diff --git a/components/password_manager/core/common/password_manager_features.cc b/components/password_manager/core/common/password_manager_features.cc index 78351930..1fc6017 100644 --- a/components/password_manager/core/common/password_manager_features.cc +++ b/components/password_manager/core/common/password_manager_features.cc
@@ -24,8 +24,13 @@ // view all saved passwords. // TODO(melandory): Re-enable once crbug.com/754326 has been fixed. const base::Feature kEnableManualFallbacksFilling = { - "EnableManualFallbacksFilling", base::FEATURE_DISABLED_BY_DEFAULT}; - + "EnableManualFallbacksFilling", +#if defined(OS_CHROMEOS) + base::FEATURE_DISABLED_BY_DEFAULT +#else + base::FEATURE_ENABLED_BY_DEFAULT +#endif +}; // Enable a context menu item in the password field that allows the user // to manually enforce saving of their password. const base::Feature kEnablePasswordForceSaving = {
diff --git a/components/payments_strings.grdp b/components/payments_strings.grdp index f5b9555..edcda78 100644 --- a/components/payments_strings.grdp +++ b/components/payments_strings.grdp
@@ -1,9 +1,252 @@ <?xml version="1.0" encoding="utf-8"?> <grit-part> - <message name="IDS_PAYMENTS_TITLE" desc="Title of the dialog that presents a request for payment for some good or service [Desktop and iOS only]."> - Your Payment - </message> + <!-- Titles and buttons which are title-cased on certain platforms. Make sure to keep the title-cased and sentence-cased variants in sync. --> + + + <!-- General titles, sentence-cased --> + <if expr="not use_titlecase"> + <message name="IDS_PAYMENTS_TITLE" desc="Title of the dialog that presents a request for payment for some good or service. Sentence-cased."> + Your payment + </message> + <message name="IDS_PAYMENTS_METHOD_OF_PAYMENT_LABEL" desc="The title for the section that lets the user select the method of payment. Sentence-cased." formatter_data="android_java"> + Payment method + </message> + <message name="IDS_PAYMENTS_CONTACT_DETAILS_LABEL" desc="The title for the section that lets the user select how they can be contacted. Sentence-cased." formatter_data="android_java"> + Contact info + </message> + <message name="IDS_PAYMENTS_ADD_CONTACT_DETAILS_LABEL" desc="The title of the dialog for user to add new contact information, such as the user's full name, an email address or a phone number. Sentence-cased." formatter_data="android_java"> + Add contact info + </message> + <message name="IDS_PAYMENTS_EDIT_CONTACT_DETAILS_LABEL" desc="The title of the dialog for user to edit their contact information, such as the user's full name, an email address or a phone number. Sentence-cased." formatter_data="android_java"> + Edit contact info + </message> + <message name="IDS_PAYMENTS_ADD_CARD_LABEL" desc="The title of the dialog for user to add new payment card. Sentence-cased." formatter_data="android_java"> + Add card + </message> + <message name="IDS_PAYMENTS_ADD_BILLING_ADDRESS" desc="The title of the dialog for user to add billing address to payment card. Sentence-cased." formatter_data="android_java"> + Add billing address + </message> + <message name="IDS_PAYMENTS_ADD_NAME_ON_CARD" desc="The title of the dialog for user to add name on card to payment card. Sentence-cased." formatter_data="android_java"> + Add name on card + </message> + <message name="IDS_PAYMENTS_ADD_VALID_CARD_NUMBER" desc="The title of the dialog for user to add valid payment card number. Sentence-cased." formatter_data="android_java"> + Add valid card number + </message> + <message name="IDS_PAYMENTS_ADD_MORE_INFORMATION" desc="The title in the Android app title bar for user to add more information to payment card or shipping address or contact info. Sentence-cased." formatter_data="android_java"> + Add more information + </message> + <message name="IDS_PAYMENTS_EDIT_CARD" desc="The title of the dialog for user to edit payment card. Sentence-cased." formatter_data="android_java"> + Edit card + </message> + <message name="IDS_PAYMENTS_ADD_PHONE_NUMBER" desc="The title of the dialog for user to add phone number to the shipping address or contact info. This phone number can be used, for example, if there's a problem with shipping a package to its destination. Sentence-cased." formatter_data="android_java"> + Add phone number + </message> + <message name="IDS_PAYMENTS_ADD_RECIPIENT" desc="The title of the dialog for user to add the name in the shipping address. This name identifies the person that will receive the shipped package. Sentence-cased." formatter_data="android_java"> + Add name + </message> + <message name="IDS_PAYMENTS_ADD_VALID_ADDRESS" desc="The title of the dialog for user to add valid shipping address. For example, missing state or city name. Sentence-cased." formatter_data="android_java"> + Add valid address + </message> + <message name="IDS_PAYMENTS_ADD_EMAIL" desc="The title of the dialog for user to add email to the contact details. This email can be used to contact the payer. Sentence-cased." formatter_data="android_java"> + Add email + </message> + <message name="IDS_PAYMENTS_ADD_NAME" desc="The title of the dialog for user to add name to the contact details. This name could be a person or institute name of the payer. Sentence-cased." formatter_data="android_java"> + Add name + </message> + <message name="IDS_PAYMENTS_ORDER_SUMMARY_LABEL" desc="The title of the section that shows the summary of the order, including names and prices of individual line items, i.e. the bill. Sentence-cased." formatter_data="android_java"> + Order summary + </message> + <message name="IDS_PAYMENT_REQUEST_PAYMENT_METHOD_SECTION_NAME" desc="The name of the Payment Method section in the Payment Sheet of the Payment Request dialog. Sentence-cased."> + Payment + </message> + <message name="IDS_PAYMENT_REQUEST_CONTACT_INFO_SECTION_NAME" desc="The name of the Contact Info section in the Payment Sheet of the Payment Request dialog. Sentence-cased."> + Contact info + </message> + <message name="IDS_PAYMENTS_SHIPPING_SUMMARY_LABEL" desc="The title for the section of shipping information. Shipping is used for packages and things that are mailed. In American English, 'shipping' is differentiated from 'delivery'. 'Delivery' is used, for example, for food delivery. Sentence-cased." formatter_data="android_java"> + Shipping + </message> + <message name="IDS_PAYMENTS_SHIPPING_ADDRESS_LABEL" desc="The title for the section that lets the user select the address where the product should be shipped. Shipping is typically used for packages. Sentence-cased." formatter_data="android_java"> + Shipping address + </message> + <message name="IDS_PAYMENTS_SHIPPING_OPTION_LABEL" desc="The title for the section that lets the user select how the product should be shipped. Shipping is typically used for packages. Sentence-cased." formatter_data="android_java"> + Shipping method + </message> + </if> <!-- not use_titlecase --> + <!-- General Titles, Title-Cased --> + <if expr="use_titlecase"> + <message name="IDS_PAYMENTS_TITLE" desc="Title of the dialog that presents a request for payment for some good or service. Title-Cased."> + Your Payment + </message> + <message name="IDS_PAYMENTS_METHOD_OF_PAYMENT_LABEL" desc="The title for the section that lets the user select the method of payment. Title-Cased."> + Payment Method + </message> + <message name="IDS_PAYMENTS_CONTACT_DETAILS_LABEL" desc="The title for the section that lets the user select how they can be contacted. Title-Cased."> + Contact Info + </message> + <message name="IDS_PAYMENTS_ADD_CONTACT_DETAILS_LABEL" desc="The title of the dialog for user to add new contact information, such as the user's full name, an email address or a phone number. Title-Cased."> + Add Contact Info + </message> + <message name="IDS_PAYMENTS_EDIT_CONTACT_DETAILS_LABEL" desc="The title of the dialog for user to edit their contact information, such as the user's full name, an email address or a phone number. Title-Cased."> + Edit Contact Info + </message> + <message name="IDS_PAYMENTS_ADD_CARD_LABEL" desc="The title of the dialog for user to add new payment card. Title-Cased."> + Add Card + </message> + <message name="IDS_PAYMENTS_ADD_BILLING_ADDRESS" desc="The title of the dialog for user to add billing address to payment card. Title-Cased."> + Add Billing Address + </message> + <message name="IDS_PAYMENTS_ADD_NAME_ON_CARD" desc="The title of the dialog for user to add name on card to payment card. Title-Cased."> + Add Name on Card + </message> + <message name="IDS_PAYMENTS_ADD_VALID_CARD_NUMBER" desc="The title of the dialog for user to add valid payment card number. Title-Cased."> + Add Valid Card Number + </message> + <message name="IDS_PAYMENTS_ADD_MORE_INFORMATION" desc="The title in the Android app title bar for user to add more information to payment card or shipping address or contact info. Title-Cased."> + Add More Information + </message> + <message name="IDS_PAYMENTS_EDIT_CARD" desc="The title of the dialog for user to edit payment card. Title-Cased."> + Edit Card + </message> + <message name="IDS_PAYMENTS_ADD_PHONE_NUMBER" desc="The title of the dialog for user to add phone number to the shipping address or contact info. This phone number can be used, for example, if there's a problem with shipping a package to its destination. Title-Cased."> + Add Phone Number + </message> + <message name="IDS_PAYMENTS_ADD_RECIPIENT" desc="The title of the dialog for user to add the name in the shipping address. This name identifies the person that will receive the shipped package. Title-Cased."> + Add Name + </message> + <message name="IDS_PAYMENTS_ADD_VALID_ADDRESS" desc="The title of the dialog for user to add valid shipping address. For example, missing state or city name. Title-Cased."> + Add Valid Address + </message> + <message name="IDS_PAYMENTS_ADD_EMAIL" desc="The title of the dialog for user to add email to the contact details. This email can be used to contact the payer. Title-Cased."> + Add Email + </message> + <message name="IDS_PAYMENTS_ADD_NAME" desc="The title of the dialog for user to add name to the contact details. This name could be a person or institute name of the payer. Title-Cased."> + Add Name + </message> + <message name="IDS_PAYMENTS_ORDER_SUMMARY_LABEL" desc="The title of the section that shows the summary of the order, including names and prices of individual line items, i.e. the bill. Title-Cased."> + Order Summary + </message> + <message name="IDS_PAYMENT_REQUEST_PAYMENT_METHOD_SECTION_NAME" desc="The name of the Payment Method section in the Payment Sheet of the Payment Request dialog. Title-Cased."> + Payment + </message> + <message name="IDS_PAYMENT_REQUEST_CONTACT_INFO_SECTION_NAME" desc="The name of the Contact Info section in the Payment Sheet of the Payment Request dialog. Title-Cased."> + Contact Info + </message> + <message name="IDS_PAYMENTS_SHIPPING_SUMMARY_LABEL" desc="The title for the section of shipping information. Shipping is used for packages and things that are mailed. In American English, 'shipping' is differentiated from 'delivery'. 'Delivery' is used, for example, for food delivery. Title-Cased."> + Shipping + </message> + <message name="IDS_PAYMENTS_SHIPPING_ADDRESS_LABEL" desc="The title for the section that lets the user select the address where the product should be shipped. Shipping is typically used for packages. Title-Cased."> + Shipping Address + </message> + <message name="IDS_PAYMENTS_SHIPPING_OPTION_LABEL" desc="The title for the section that lets the user select how the product should be shipped. Shipping is typically used for packages. Title-Cased."> + Shipping Method + </message> + </if> <!-- use_titlecase --> + + <!-- Delivery titles, sentence-cased --> + <if expr="not use_titlecase"> + <message name="IDS_PAYMENTS_DELIVERY_SUMMARY_LABEL" desc="The title for the section of delivery information. Delivery is commonly faster than shipping. For example, it might be used for food delivery. Sentence-cased." formatter_data="android_java"> + Delivery + </message> + <message name="IDS_PAYMENTS_DELIVERY_ADDRESS_LABEL" desc="The title for the section that lets the user select the address where the product should be delivered. In English, 'delivery' is differentiated from 'shipping.' For example, 'delivery' might be used for meals or meal items or items that need to be immediately sent to a recipient. Sentence-cased." formatter_data="android_java"> + Delivery address + </message> + <message name="IDS_PAYMENTS_DELIVERY_OPTION_LABEL" desc="The title for the section that lets the user select how the product should be delivered. Delivery is commonly faster than shipping. For example, it might be used for food delivery. Sentence-cased." formatter_data="android_java"> + Delivery method + </message> + </if> <!-- not use_titlecase --> + <!-- Delivery Titles, Title-Cased --> + <if expr="use_titlecase"> + <message name="IDS_PAYMENTS_DELIVERY_SUMMARY_LABEL" desc="The title for the section of delivery information. Delivery is commonly faster than shipping. For example, it might be used for food delivery. Title-Cased."> + Delivery + </message> + <message name="IDS_PAYMENTS_DELIVERY_ADDRESS_LABEL" desc="The title for the section that lets the user select the address where the product should be delivered. In English, 'delivery' is differentiated from 'shipping.' For example, 'delivery' might be used for meals or meal items or items that need to be immediately sent to a recipient. Title-Cased."> + Delivery Address + </message> + <message name="IDS_PAYMENTS_DELIVERY_OPTION_LABEL" desc="The title for the section that lets the user select how the product should be delivered. Delivery is commonly faster than shipping. For example, it might be used for food delivery. Title-Cased."> + Delivery Method + </message> + </if> <!-- use_titlecase --> + + <!-- Pickup titles, sentence-cased --> + <if expr="not use_titlecase"> + <message name="IDS_PAYMENTS_PICKUP_SUMMARY_LABEL" desc="The title for the section of information needed for a service to pick up items from a customer. For example, this could be the address for laundry pickup. 'Pickup' is a noun. Sentence-cased." formatter_data="android_java"> + Pickup + </message> + <message name="IDS_PAYMENTS_PICKUP_ADDRESS_LABEL" desc="The title for the section that lets the user select the address where a service item should be picked up. For example, the pickup address is where a laundry service picks up a customer’s items to be laundered. 'Pickup' functions as an adjective. Sentence-cased." formatter_data="android_java"> + Pickup address + </message> + <message name="IDS_PAYMENTS_PICKUP_OPTION_LABEL" desc="The title for the section that lets the user select how their service item should be picked up. This item can be laundry to be cleaned, for example. 'Pickup' functions as an adjective. Sentence-cased." formatter_data="android_java"> + Pickup method + </message> + </if> <!-- not use_titlecase --> + <!-- Pickup Titles, Title-Cased --> + <if expr="use_titlecase"> + <message name="IDS_PAYMENTS_PICKUP_SUMMARY_LABEL" desc="The title for the section of information needed for a service to pick up items from a customer. For example, this could be the address for laundry pickup. 'Pickup' is a noun. Title-Cased."> + Pickup + </message> + <message name="IDS_PAYMENTS_PICKUP_ADDRESS_LABEL" desc="The title for the section that lets the user select the address where a service item should be picked up. For example, the pickup address is where a laundry service picks up a customer’s items to be laundered. 'Pickup' functions as an adjective. Title-Cased."> + Pickup Address + </message> + <message name="IDS_PAYMENTS_PICKUP_OPTION_LABEL" desc="The title for the section that lets the user select how their service item should be picked up. This item can be laundry to be cleaned, for example. 'Pickup' functions as an adjective. Title-Cased."> + Pickup Method + </message> + </if> <!-- use_titlecase --> + + <!-- Buttons, sentence-cased --> + <if expr="not use_titlecase"> + <message name="IDS_PAYMENTS_EDIT_BUTTON" desc="The label for the button that lets the user edit their payment options. Sentence-cased." formatter_data="android_java"> + Edit + </message> + <message name="IDS_PAYMENTS_PAY_BUTTON" desc="The label for the button that finishes the payment process. Sentence-cased." formatter_data="android_java"> + Pay + </message> + <message name="IDS_PAYMENTS_ADD_CONTACT" desc="Text on a button that lets a user add new contact details, like the user's full name, an email address or a phone number. Sentence-cased." formatter_data="android_java"> + Add contact info + </message> + <message name="IDS_PAYMENTS_ADD_CARD" desc="Text on a button that lets a user add new payment card. Sentence-cased." formatter_data="android_java"> + Add card + </message> + <message name="IDS_PAYMENTS_ADD_ADDRESS" desc="Text on a button that lets a user add new address. Sentence-cased." formatter_data="android_java"> + Add address + </message> + <message name="IDS_PAYMENTS_EDIT_ADDRESS" desc="Text on a button that lets a user edit an existing address. Sentence-cased." formatter_data="android_java"> + Edit address + </message> + <message name="IDS_PAYMENTS_CANCEL_PAYMENT" desc="Label of the secondary button in payment request editors. Clicking that button closes the dialog and aborts the payment request completely. Sentence-cased."> + Cancel payment + </message> + </if> <!-- not use_titlecase --> + <!-- Buttons, Title-Cased --> + <if expr="use_titlecase"> + <message name="IDS_PAYMENTS_EDIT_BUTTON" desc="The label for the button that lets the user edit their payment options. Title-Cased."> + Edit + </message> + <message name="IDS_PAYMENTS_PAY_BUTTON" desc="The label for the button that finishes the payment process. Title-Cased."> + Pay + </message> + <message name="IDS_PAYMENTS_ADD_CONTACT" desc="Text on a button that lets a user add new contact details, like the user's full name, an email address or a phone number. Title-Cased."> + Add Contact Info + </message> + <message name="IDS_PAYMENTS_ADD_CARD" desc="Text on a button that lets a user add new payment card. Title-Cased."> + Add Card + </message> + <message name="IDS_PAYMENTS_ADD_ADDRESS" desc="Text on a button that lets a user add new address. Title-Cased."> + Add Address + </message> + <message name="IDS_PAYMENTS_EDIT_ADDRESS" desc="Text on a button that lets a user edit an existing address. Title-Cased."> + Edit Address + </message> + <message name="IDS_PAYMENTS_CANCEL_PAYMENT" desc="Label of the secondary button in payment request editors. Clicking that button closes the dialog and aborts the payment request completely. Title-Cased."> + Cancel Payment + </message> + </if> <!-- use_titlecase --> + + + <!-- Fields, descriptive sentences, and other strings which are never title-cased. --> + + + <!-- Fields & Editors --> <message name="IDS_PAYMENTS_NAME_FIELD_IN_CONTACT_DETAILS" desc="The label for text input field containing the full name of a person. [CHAR-LIMIT=32]" formatter_data="android_java"> Name </message> @@ -55,63 +298,9 @@ <message name="IDS_PAYMENTS_DEBIT_PREPAID_CARDS_ARE_ACCEPTED_LABEL" desc="A message for the section that displays user's debit and prepaid cards that the merchant accepts." formatter_data="android_java"> Debit and prepaid cards are accepted. </message> - <message name="IDS_PAYMENTS_METHOD_OF_PAYMENT_LABEL" desc="The title for the section that lets the user select the method of payment." formatter_data="android_java"> - Payment method - </message> - <message name="IDS_PAYMENTS_CONTACT_DETAILS_LABEL" desc="The title for the section that lets the user select how they can be contacted." formatter_data="android_java"> - Contact info - </message> - <message name="IDS_PAYMENTS_ADD_CONTACT_DETAILS_LABEL" desc="The title of the dialog for user to add new contact information, such as the user's full name, an email address or a phone number." formatter_data="android_java"> - Add contact info - </message> - <message name="IDS_PAYMENTS_EDIT_CONTACT_DETAILS_LABEL" desc="The title of the dialog for user to edit their contact information, such as the user's full name, an email address or a phone number." formatter_data="android_java"> - Edit contact info - </message> - <message name="IDS_PAYMENTS_ADD_CARD_LABEL" desc="The title of the dialog for user to add new payment card." formatter_data="android_java"> - Add card - </message> - <message name="IDS_PAYMENTS_ADD_BILLING_ADDRESS" desc="The title of the dialog for user to add billing address to payment card." formatter_data="android_java"> - Add billing address - </message> - <message name="IDS_PAYMENTS_ADD_NAME_ON_CARD" desc="The title of the dialog for user to add name on card to payment card." formatter_data="android_java"> - Add name on card - </message> - <message name="IDS_PAYMENTS_ADD_VALID_CARD_NUMBER" desc="The title of the dialog for user to add valid payment card number." formatter_data="android_java"> - Add valid card number - </message> - <message name="IDS_PAYMENTS_ADD_MORE_INFORMATION" desc="The title in the Android app title bar for user to add more information to payment card or shipping address or contact info." formatter_data="android_java"> - Add more information - </message> - <message name="IDS_PAYMENTS_EDIT_CARD" desc="The title of the dialog for user to edit payment card." formatter_data="android_java"> - Edit card - </message> <message name="IDS_PAYMENTS_CREDIT_CARD_EXPIRATION_DATE_ABBR" desc="Abbreviated label for credit card expiration date. [CHAR-LIMIT=32]" formatter_data="android_java"> Expires <ph name="EXPIRATION_MONTH">%1$s<ex>06</ex></ph>/<ph name="EXPIRATION_YEAR">%2$s<ex>17</ex></ph> </message> - <message name="IDS_PAYMENTS_ADD_PHONE_NUMBER" desc="The title of the dialog for user to add phone number to the shipping address or contact info. This phone number can be used, for example, if there's a problem with shipping a package to its destination." formatter_data="android_java"> - Add phone number - </message> - <message name="IDS_PAYMENTS_ADD_RECIPIENT" desc="The title of the dialog for user to add the name in the shipping address. This name identifies the person that will receive the shipped package." formatter_data="android_java"> - Add name - </message> - <message name="IDS_PAYMENTS_ADD_VALID_ADDRESS" desc="The title of the dialog for user to add valid shipping address. For example, missing state or city name." formatter_data="android_java"> - Add valid address - </message> - <message name="IDS_PAYMENTS_ADD_EMAIL" desc="The title of the dialog for user to add email to the contact details. This email can be used to contact the payer." formatter_data="android_java"> - Add email - </message> - <message name="IDS_PAYMENTS_ADD_NAME" desc="The title of the dialog for user to add name to the contact details. This name could be a person or institute name of the payer." formatter_data="android_java"> - Add name - </message> - <message name="IDS_PAYMENTS_ORDER_SUMMARY_LABEL" desc="The title of the section that shows the summary of the order, including names and prices of individual line items, i.e. the bill." formatter_data="android_java"> - Order summary - </message> - <message name="IDS_PAYMENTS_EDIT_BUTTON" desc="The label for the button that lets the user edit their payment options." formatter_data="android_java"> - Edit - </message> - <message name="IDS_PAYMENTS_PAY_BUTTON" desc="The label for the button that finishes the payment process." formatter_data="android_java"> - Pay - </message> <message name="IDS_PAYMENTS_LOADING_MESSAGE" desc="The text that informs the user that payment information is being loaded up." formatter_data="android_java"> Loading </message> @@ -124,18 +313,6 @@ <message name="IDS_PAYMENTS_ERROR_MESSAGE" desc="The text that informs the user that there is error in verifying and charging the payment." formatter_data="android_java"> There was an error processing your order. Please try again. </message> - <message name="IDS_PAYMENTS_ADD_CONTACT" desc="Text on a button that lets a user add new contact details, like the user's full name, an email address or a phone number." formatter_data="android_java"> - Add contact info - </message> - <message name="IDS_PAYMENTS_ADD_CARD" desc="Text on a button that lets a user add new payment card." formatter_data="android_java"> - Add card - </message> - <message name="IDS_PAYMENTS_ADD_ADDRESS" desc="Text on a button that lets a user add new address." formatter_data="android_java"> - Add address - </message> - <message name="IDS_PAYMENTS_EDIT_ADDRESS" desc="Text on a button that lets a user edit an existing address." formatter_data="android_java"> - Edit address - </message> <message name="IDS_PAYMENTS_CHECKING_OPTION" desc="Text explaining that the option the user selected is being checked and verified." formatter_data="android_java"> Checking </message> @@ -158,11 +335,8 @@ <message name="IDS_PAYMENTS_CARD_AND_ADDRESS_SETTINGS_SIGNED_OUT" desc="Label of the section containing the origin description and the link to go to the settings page for card and address options. This label is used when the user is not signed in." formatter_data="android_java"> Cards and addresses are from Chrome. You can manage them in <ph name="BEGIN_LINK">BEGIN_LINK</ph>Settings<ph name="END_LINK">END_LINK</ph>. </message> - <message name="IDS_PAYMENTS_CANCEL_PAYMENT" desc="Label of the secondary button in payment request editors. Clicking that button closes the dialog and aborts the payment request completely"> - Cancel Payment - </message> - <!-- Credit Card form --> + <!-- iOS Credit Card form --> <if expr="is_ios"> <message name="IDS_PAYMENTS_CARD_NUMBER" desc="Title of the field representing the number (PAN) on a credit card."> Card Number @@ -200,7 +374,7 @@ <message name="IDS_PAYMENTS_REQUIRED_FIELD_MESSAGE" desc="The text that informs the user that '*' character indicates an input field that is required. The '*' character should not be changed." formatter_data="android_java"> * Field is required </message> - <message name="IDS_PAYMENTS_FIELD_REQUIRED_VALIDATION_MESSAGE" desc="The text that informs the user that an input field is required. “Required” is an adjective." formatter_data="android_java"> + <message name="IDS_PAYMENTS_FIELD_REQUIRED_VALIDATION_MESSAGE" desc="The text that informs the user that an input field is required. 'Required' is an adjective." formatter_data="android_java"> Required field </message> <message name="IDS_PAYMENTS_PHONE_INVALID_VALIDATION_MESSAGE" desc="The text that informs the user that the phone number they have entered is not valid." formatter_data="android_java"> @@ -218,7 +392,7 @@ <message name="IDS_PAYMENTS_BILLING_ADDRESS_REQUIRED" desc="The label to indicate billing address is required for payment card." formatter_data="android_java"> Billing address required </message> - <message name="IDS_PAYMENTS_NAME_ON_CARD_REQUIRED" desc="The label to indicate the cardholder name (the name of the owner or “holder” of the credit card) must be entered." formatter_data="android_java"> + <message name="IDS_PAYMENTS_NAME_ON_CARD_REQUIRED" desc="The label to indicate the cardholder name (the name of the owner or 'holder' of the credit card) must be entered." formatter_data="android_java"> Cardholder name required </message> <message name="IDS_PAYMENTS_CARD_BILLING_ADDRESS_REQUIRED" desc="The label to indicate the billing address of the credit card must be entered." formatter_data="android_java"> @@ -243,16 +417,10 @@ Name required </message> - <!-- Payment Request (Sections mode) --> - <message name="IDS_PAYMENT_REQUEST_ORDER_SUMMARY_SECTION_NAME" desc="The name of the Order Summary section in the Payment Sheet of the Payment Request dialog."> - Order summary - </message> + <!-- Order Summary Data Formatting --> <message name="IDS_PAYMENT_REQUEST_ORDER_SUMMARY_SECTION_TOTAL_FORMAT" desc="The format specifier of the Total label in the Order Summary section of the Payment Sheet of the Payment Request dialog."> <ph name="TOTAL_LABEL">$1<ex>Total</ex></ph> <ph name="CURRENCY_CODE">$2<ex>USD</ex></ph> <ph name="FORMATTED_TOTAL_AMOUNT">$3<ex>$ 12.34</ex></ph> </message> - <message name="IDS_PAYMENT_REQUEST_PAYMENT_METHOD_SECTION_NAME" desc="The name of the Payment Method section in the Payment Sheet of the Payment Request dialog."> - Payment - </message> <message name="IDS_PAYMENT_REQUEST_ORDER_SUMMARY_SHEET_TOTAL_FORMAT" desc="The format specifier of the Total label in the Order Summary Sheet of the Payment Request dialog."> <ph name="CURRENCY_CODE">$1<ex>USD</ex></ph> <ph name="FORMATTED_TOTAL_AMOUNT">$2<ex>$ 12.34</ex></ph> </message> @@ -261,46 +429,22 @@ =1 {<ph name="ITEM_COUNT">#<ex>1</ex></ph> more item} other {<ph name="ITEM_COUNT">#<ex>2</ex></ph> more items}} </message> - <message name="IDS_PAYMENT_REQUEST_SHIPPING_SECTION_NAME" desc="The name of the Shipping Address section in the Payment Sheet of the Payment Request dialog."> - Shipping address - </message> - <message name="IDS_PAYMENT_REQUEST_CONTACT_INFO_SECTION_NAME" desc="The name of the Contact Info section in the Payment Sheet of the Payment Request dialog."> - Contact info - </message> <message name="IDS_PAYMENT_REQUEST_ORDER_SUMMARY_MULTIPLE_CURRENCY_INDICATOR" desc="The label that indicates that there are multiple currencies among the display items"> Multiple </message> - <!-- Shipping address in web payments API --> - <message name="IDS_PAYMENTS_SHIPPING_SUMMARY_LABEL" desc="The title for the section of shipping information. Shipping is used for packages and things that are mailed. In American English, “shipping” is differentiated from “delivery”. “Delivery” is used, for example, for food delivery." formatter_data="android_java"> - Shipping - </message> - <message name="IDS_PAYMENTS_SHIPPING_ADDRESS_LABEL" desc="The title for the section that lets the user select the address where the product should be shipped. Shipping is typically used for packages." formatter_data="android_java"> - Shipping address - </message> - <message name="IDS_PAYMENTS_SHIPPING_OPTION_LABEL" desc="The title for the section that lets the user select how the product should be shipped. Shipping is typically used for packages." formatter_data="android_java"> - Shipping method - </message> + <!-- Shipping address descriptive strings --> <message name="IDS_PAYMENTS_SELECT_SHIPPING_ADDRESS_FOR_SHIPPING_METHODS" desc="Text implying that a user needs to pick a shipping address to see the shipping methods. Shipping is typically used for packages." formatter_data="android_java"> To see shipping methods and requirements, select an address </message> - <message name="IDS_PAYMENTS_UNSUPPORTED_SHIPPING_ADDRESS" desc="Text implying that a user needs to pick a different shipping address, because the currently selected address is not supported. “Ship” is typically used for packages and items that are sent through the mail. In American English, we differentiate “ship” from “deliver." formatter_data="android_java"> + <message name="IDS_PAYMENTS_UNSUPPORTED_SHIPPING_ADDRESS" desc="Text implying that a user needs to pick a different shipping address, because the currently selected address is not supported. 'Ship' is typically used for packages and items that are sent through the mail. In American English, we differentiate 'ship' from 'deliver." formatter_data="android_java"> Can’t ship to this address. Select a different address. </message> - <message name="IDS_PAYMENTS_UNSUPPORTED_SHIPPING_OPTION" desc="Text implying that a user needs to pick a different shipping option, because the currently selected option is not supported. “Ship” is typically used for packages and items that are sent through the mail. In American English, we differentiate “ship” from deliver." formatter_data="android_java"> + <message name="IDS_PAYMENTS_UNSUPPORTED_SHIPPING_OPTION" desc="Text implying that a user needs to pick a different shipping option, because the currently selected option is not supported. 'Ship' is typically used for packages and items that are sent through the mail. In American English, we differentiate 'ship' from deliver." formatter_data="android_java"> This shipping method isn’t available. Try a different method. </message> - <!-- Delivery address in web payments API --> - <message name="IDS_PAYMENTS_DELIVERY_SUMMARY_LABEL" desc="The title for the section of delivery information. Delivery is commonly faster than shipping. For example, it might be used for food delivery." formatter_data="android_java"> - Delivery - </message> - <message name="IDS_PAYMENTS_DELIVERY_ADDRESS_LABEL" desc="The title for the section that lets the user select the address where the product should be delivered. In English, “delivery” is differentiated from “shipping.” For example, “delivery” might be used for meals or meal items or items that need to be immediately sent to a recipient." formatter_data="android_java"> - Delivery address - </message> - <message name="IDS_PAYMENTS_DELIVERY_OPTION_LABEL" desc="The title for the section that lets the user select how the product should be delivered. Delivery is commonly faster than shipping. For example, it might be used for food delivery." formatter_data="android_java"> - Delivery method - </message> + <!-- Delivery address descriptive strings --> <message name="IDS_PAYMENTS_SELECT_DELIVERY_ADDRESS_FOR_DELIVERY_METHODS" desc="Text implying that a user needs to pick a delivery address to see the delivery methods. Delivery is commonly faster than shipping. For example, it might be used for food delivery." formatter_data="android_java"> To see delivery methods and requirements, select an address </message> @@ -311,29 +455,21 @@ This delivery method isn’t available. Try a different method. </message> - <!-- Pickup address in web payments API --> - <message name="IDS_PAYMENTS_PICKUP_SUMMARY_LABEL" desc="The title for the section of information needed for a service to pick up items from a customer. For example, this could be the address for laundry pickup. “Pickup” is a noun." formatter_data="android_java"> - Pickup - </message> - <message name="IDS_PAYMENTS_PICKUP_ADDRESS_LABEL" desc="The title for the section that lets the user select the address where a service item should be picked up. For example, the pickup address is where a laundry service picks up a customer’s items to be laundered. “Pickup” functions as an adjective." formatter_data="android_java"> - Pickup address - </message> - <message name="IDS_PAYMENTS_PICKUP_OPTION_LABEL" desc="The title for the section that lets the user select how their service item should be picked up. This item can be laundry to be cleaned, for example. “Pickup” functions as an adjective." formatter_data="android_java"> - Pickup method - </message> - <message name="IDS_PAYMENTS_SELECT_PICKUP_ADDRESS_FOR_PICKUP_METHODS" desc="Text implying that a user needs to choose a pickup address to see the pickup methods. For example, this could be the address for laundry pickup. “Pickup” functions as an adjective." formatter_data="android_java"> + <!-- Pickup address descriptive strings--> + <message name="IDS_PAYMENTS_SELECT_PICKUP_ADDRESS_FOR_PICKUP_METHODS" desc="Text implying that a user needs to choose a pickup address to see the pickup methods. For example, this could be the address for laundry pickup. 'Pickup' functions as an adjective." formatter_data="android_java"> To see pickup methods and requirements, select an address </message> - <message name="IDS_PAYMENTS_UNSUPPORTED_PICKUP_ADDRESS" desc="Text implying that a user needs to choose a different pickup address, because the service can’t pick up items from that address. This address can be used, for example, for laundry pickup. Note that here, “pick up” is a verb." formatter_data="android_java"> + <message name="IDS_PAYMENTS_UNSUPPORTED_PICKUP_ADDRESS" desc="Text implying that a user needs to choose a different pickup address, because the service can’t pick up items from that address. This address can be used, for example, for laundry pickup. Note that here, 'pick up' is a verb." formatter_data="android_java"> Can’t pick up from this address. Select a different address. </message> <message name="IDS_PAYMENTS_UNSUPPORTED_PICKUP_OPTION" desc="Text implying that a user needs to choose a different pickup option, because the currently selected option is not supported. This option can be used, for example, for laundry pickup." formatter_data="android_java"> This pickup method isn’t available. Try a different method. </message> + + <!-- Payment Apps --> <message name="IDS_PAYMENTS_ANDROID_APP_ERROR" desc="Error message that is shown when an Android payment application fails to start." formatter_data="android_java"> Can’t open payment app </message> - <message name="IDS_UTILITY_PROCESS_PAYMENT_MANIFEST_PARSER_NAME" desc="The name of the utility process used for parsing payment manifest files."> Payment Manifest Parser </message>
diff --git a/components/policy/core/browser/url_blacklist_manager.cc b/components/policy/core/browser/url_blacklist_manager.cc index 9fe54dc4..fa97e73 100644 --- a/components/policy/core/browser/url_blacklist_manager.cc +++ b/components/policy/core/browser/url_blacklist_manager.cc
@@ -515,7 +515,10 @@ bool URLBlacklistManager::IsURLBlocked(const GURL& url) const { DCHECK(io_task_runner_->RunsTasksInCurrentSequence()); - return blacklist_->IsURLBlocked(url); + // Ignore blob scheme for two reasons: + // 1) PlzNavigate uses it to deliver the response to the renderer. + // 2) A whitelisted page can use blob URLs internally. + return !url.SchemeIs(url::kBlobScheme) && blacklist_->IsURLBlocked(url); } URLBlacklist::URLBlacklistState URLBlacklistManager::GetURLBlacklistState(
diff --git a/components/pref_registry/pref_registry_syncable.cc b/components/pref_registry/pref_registry_syncable.cc index a81cea0..f00f0c6 100644 --- a/components/pref_registry/pref_registry_syncable.cc +++ b/components/pref_registry/pref_registry_syncable.cc
@@ -43,6 +43,8 @@ // unregistration. scoped_refptr<PrefRegistrySyncable> registry(new PrefRegistrySyncable()); registry->defaults_ = defaults_; + registry->registration_flags_ = registration_flags_; + registry->foreign_pref_keys_ = foreign_pref_keys_; return registry; }
diff --git a/components/prefs/pref_notifier_impl.h b/components/prefs/pref_notifier_impl.h index c5448d3..5a8a137 100644 --- a/components/prefs/pref_notifier_impl.h +++ b/components/prefs/pref_notifier_impl.h
@@ -22,8 +22,7 @@ class PrefService; // The PrefNotifier implementation used by the PrefService. -class COMPONENTS_PREFS_EXPORT PrefNotifierImpl - : public NON_EXPORTED_BASE(PrefNotifier) { +class COMPONENTS_PREFS_EXPORT PrefNotifierImpl : public PrefNotifier { public: PrefNotifierImpl(); explicit PrefNotifierImpl(PrefService* pref_service);
diff --git a/components/prefs/pref_service.cc b/components/prefs/pref_service.cc index 6abc09bc..f56cf61 100644 --- a/components/prefs/pref_service.cc +++ b/components/prefs/pref_service.cc
@@ -252,6 +252,14 @@ } } +PrefService::PrefInitializationStatus +PrefService::GetAllPrefStoresInitializationStatus() const { + if (!pref_value_store_->IsInitializationComplete()) + return INITIALIZATION_STATUS_WAITING; + + return GetInitializationStatus(); +} + bool PrefService::IsManagedPreference(const std::string& pref_name) const { const Preference* pref = FindPreference(pref_name); return pref && pref->IsManaged();
diff --git a/components/prefs/pref_service.h b/components/prefs/pref_service.h index 8b33717..9fbcd39 100644 --- a/components/prefs/pref_service.h +++ b/components/prefs/pref_service.h
@@ -278,8 +278,12 @@ bool ReadOnly() const; + // Returns the initialization state, taking only user prefs into account. PrefInitializationStatus GetInitializationStatus() const; + // Returns the initialization state, taking all pref stores into account. + PrefInitializationStatus GetAllPrefStoresInitializationStatus() const; + // Tell our PrefValueStore to update itself to |command_line_store|. // Takes ownership of the store. virtual void UpdateCommandLinePrefStore(PrefStore* command_line_store);
diff --git a/components/prefs/pref_value_store.cc b/components/prefs/pref_value_store.cc index da58b23..f76d3a5 100644 --- a/components/prefs/pref_value_store.cc +++ b/components/prefs/pref_value_store.cc
@@ -198,6 +198,15 @@ delegate_->UpdateCommandLinePrefStore(command_line_prefs); } +bool PrefValueStore::IsInitializationComplete() const { + for (size_t i = 0; i <= PREF_STORE_TYPE_MAX; ++i) { + const PrefStore* pref_store = GetPrefStore(static_cast<PrefStoreType>(i)); + if (pref_store && !pref_store->IsInitializationComplete()) + return false; + } + return true; +} + bool PrefValueStore::PrefValueInStore( const std::string& name, PrefValueStore::PrefStoreType store) const {
diff --git a/components/prefs/pref_value_store.h b/components/prefs/pref_value_store.h index 9fb9ed1..ea6962d 100644 --- a/components/prefs/pref_value_store.h +++ b/components/prefs/pref_value_store.h
@@ -175,6 +175,8 @@ // Update the command line PrefStore with |command_line_prefs|. void UpdateCommandLinePrefStore(PrefStore* command_line_prefs); + bool IsInitializationComplete() const; + private: // Keeps a PrefStore reference on behalf of the PrefValueStore and monitors // the PrefStore for changes, forwarding notifications to PrefValueStore. This
diff --git a/components/safe_browsing/BUILD.gn b/components/safe_browsing/BUILD.gn index 41b9f45..3af5867 100644 --- a/components/safe_browsing/BUILD.gn +++ b/components/safe_browsing/BUILD.gn
@@ -33,6 +33,7 @@ ":features", "//base:base", "//base:i18n", + "//components/safe_browsing/common:common", "//components/safe_browsing/common:safe_browsing_prefs", "//components/safe_browsing/web_ui:constants", "//components/safe_browsing_db:database_manager",
diff --git a/components/safe_browsing/base_resource_throttle.cc b/components/safe_browsing/base_resource_throttle.cc index cac7fac6..a8d53f1d 100644 --- a/components/safe_browsing/base_resource_throttle.cc +++ b/components/safe_browsing/base_resource_throttle.cc
@@ -10,6 +10,7 @@ #include "base/trace_event/trace_event.h" #include "base/values.h" #include "components/safe_browsing/base_ui_manager.h" +#include "components/safe_browsing/common/utils.h" #include "components/safe_browsing/web_ui/constants.h" #include "components/safe_browsing_db/util.h" #include "components/security_interstitials/content/unsafe_resource.h" @@ -238,10 +239,10 @@ if (threat_type == SB_THREAT_TYPE_SAFE) { if (defer_state_ != DEFERRED_NONE) { // Log how much time the safe browsing check cost us. - ui_manager_->LogPauseDelay(base::TimeTicks::Now() - defer_start_time_); + LogDelay(base::TimeTicks::Now() - defer_start_time_); ResumeRequest(); } else { - ui_manager_->LogPauseDelay(base::TimeDelta()); + LogDelay(base::TimeDelta()); } return; } @@ -331,7 +332,7 @@ if (database_manager_->CheckBrowseUrl(url, threat_types_, this)) { threat_type_ = SB_THREAT_TYPE_SAFE; - ui_manager_->LogPauseDelay(base::TimeDelta()); // No delay. + LogDelay(base::TimeDelta()); // No delay. return true; }
diff --git a/components/safe_browsing/base_ui_manager.cc b/components/safe_browsing/base_ui_manager.cc index 456d89281..084dd71 100644 --- a/components/safe_browsing/base_ui_manager.cc +++ b/components/safe_browsing/base_ui_manager.cc
@@ -8,7 +8,6 @@ #include "base/callback.h" #include "base/i18n/rtl.h" #include "base/memory/ptr_util.h" -#include "base/metrics/histogram_macros.h" #include "base/supports_user_data.h" #include "components/safe_browsing/base_blocking_page.h" #include "content/public/browser/browser_thread.h" @@ -234,11 +233,6 @@ GetOrCreateWhitelist(web_contents); } -void BaseUIManager::LogPauseDelay(base::TimeDelta time) { - UMA_HISTOGRAM_LONG_TIMES("SB2.Delay", time); - return; -} - void BaseUIManager::CreateAndSendHitReport(const UnsafeResource& resource) {} void BaseUIManager::ShowBlockingPageForResource(
diff --git a/components/safe_browsing/base_ui_manager.h b/components/safe_browsing/base_ui_manager.h index 720b236..85de4149 100644 --- a/components/safe_browsing/base_ui_manager.h +++ b/components/safe_browsing/base_ui_manager.h
@@ -11,7 +11,6 @@ #include "base/bind_helpers.h" #include "base/macros.h" #include "base/memory/ref_counted.h" -#include "base/time/time.h" #include "components/security_interstitials/content/unsafe_resource.h" class GURL; @@ -48,12 +47,6 @@ // chain). Otherwise, |original_url| = |url|. virtual void DisplayBlockingPage(const UnsafeResource& resource); - // Log the user perceived delay caused by SafeBrowsing. This delay is the time - // delta starting from when we would have started reading data from the - // network, and ending when the SafeBrowsing check completes indicating that - // the current page is 'safe'. - virtual void LogPauseDelay(base::TimeDelta time); - // This is a no-op in the base class, but should be overridden to send threat // details. Called on the IO thread by the ThreatDetails with the serialized // protocol buffer.
diff --git a/components/safe_browsing/browser/BUILD.gn b/components/safe_browsing/browser/BUILD.gn index 1ad4965..f27f43a 100644 --- a/components/safe_browsing/browser/BUILD.gn +++ b/components/safe_browsing/browser/BUILD.gn
@@ -29,6 +29,7 @@ "//components/safe_browsing:csd_proto", "//components/safe_browsing:safe_browsing", "//components/safe_browsing/common:common", + "//components/safe_browsing/web_ui:constants", "//components/safe_browsing_db:database_manager", "//components/security_interstitials/content:security_interstitial_page", "//content/public/browser:browser",
diff --git a/components/safe_browsing/browser/browser_url_loader_throttle.cc b/components/safe_browsing/browser/browser_url_loader_throttle.cc index 8cf552d..a7639c6 100644 --- a/components/safe_browsing/browser/browser_url_loader_throttle.cc +++ b/components/safe_browsing/browser/browser_url_loader_throttle.cc
@@ -7,6 +7,7 @@ #include "base/logging.h" #include "components/safe_browsing/browser/safe_browsing_url_checker_impl.h" #include "components/safe_browsing/browser/url_checker_delegate.h" +#include "components/safe_browsing/common/utils.h" #include "content/public/common/resource_request.h" #include "net/url_request/redirect_info.h" @@ -71,8 +72,15 @@ // shouldn't be such a notification. DCHECK(!blocked_); - if (pending_checks_ > 0) - *defer = true; + if (pending_checks_ == 0) { + LogDelay(base::TimeDelta()); + return; + } + + DCHECK(!deferred_); + deferred_ = true; + defer_start_time_ = base::TimeTicks::Now(); + *defer = true; } void BrowserURLLoaderThrottle::OnCheckUrlResult(bool proceed, @@ -84,9 +92,9 @@ pending_checks_--; if (proceed) { - if (pending_checks_ == 0) { - // The resource load is not necessarily deferred, in that case Resume() is - // a no-op. + if (pending_checks_ == 0 && deferred_) { + LogDelay(base::TimeTicks::Now() - defer_start_time_); + deferred_ = false; delegate_->Resume(); } } else {
diff --git a/components/safe_browsing/browser/browser_url_loader_throttle.h b/components/safe_browsing/browser/browser_url_loader_throttle.h index acf7adb..71b1907 100644 --- a/components/safe_browsing/browser/browser_url_loader_throttle.h +++ b/components/safe_browsing/browser/browser_url_loader_throttle.h
@@ -10,6 +10,7 @@ #include "base/callback.h" #include "base/macros.h" #include "base/memory/ref_counted.h" +#include "base/time/time.h" #include "content/public/common/url_loader_throttle.h" namespace content { @@ -60,6 +61,10 @@ size_t pending_checks_ = 0; bool blocked_ = false; + // The time when we started deferring the request. + base::TimeTicks defer_start_time_; + bool deferred_ = false; + DISALLOW_COPY_AND_ASSIGN(BrowserURLLoaderThrottle); };
diff --git a/components/safe_browsing/browser/safe_browsing_url_checker_impl.cc b/components/safe_browsing/browser/safe_browsing_url_checker_impl.cc index cf86311..665aece 100644 --- a/components/safe_browsing/browser/safe_browsing_url_checker_impl.cc +++ b/components/safe_browsing/browser/safe_browsing_url_checker_impl.cc
@@ -4,7 +4,10 @@ #include "components/safe_browsing/browser/safe_browsing_url_checker_impl.h" +#include "base/metrics/histogram_macros.h" +#include "base/trace_event/trace_event.h" #include "components/safe_browsing/browser/url_checker_delegate.h" +#include "components/safe_browsing/web_ui/constants.h" #include "components/security_interstitials/content/unsafe_resource.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/web_contents.h" @@ -76,21 +79,26 @@ timer_.Stop(); if (threat_type == SB_THREAT_TYPE_SAFE) { state_ = STATE_NONE; - std::move(urls_[next_index_].callback).Run(true, false); - next_index_++; + RunNextCallback(true, false); ProcessUrls(); return; } if (load_flags_ & net::LOAD_PREFETCH) { // Destroy the prefetch with FINAL_STATUS_SAFEBROSWING. - if (resource_type_ == content::RESOURCE_TYPE_MAIN_FRAME) + if (resource_type_ == content::RESOURCE_TYPE_MAIN_FRAME) { url_checker_delegate_->MaybeDestroyPrerenderContents( web_contents_getter_); + } BlockAndProcessUrls(false); + UMA_HISTOGRAM_ENUMERATION("SB2.ResourceTypes2.UnsafePrefetchCanceled", + resource_type_, content::RESOURCE_TYPE_LAST_TYPE); return; } + UMA_HISTOGRAM_ENUMERATION("SB2.ResourceTypes2.Unsafe", resource_type_, + content::RESOURCE_TYPE_LAST_TYPE); + security_interstitials::UnsafeResource resource; resource.url = url; resource.original_url = urls_[0].url; @@ -137,16 +145,50 @@ while (next_index_ < urls_.size()) { DCHECK_EQ(STATE_NONE, state_); + + const GURL& url = urls_[next_index_].url; + + TRACE_EVENT1("loader", "SafeBrowsingUrlCheckerImpl::ProcessUrls", "url", + url.spec()); + + if (url_checker_delegate_->IsUrlWhitelisted(url)) { + RunNextCallback(true, false); + continue; + } + // TODO(yzshen): Consider moving CanCheckResourceType() to the renderer // side. That would save some IPCs. It requires a method on the // SafeBrowsing mojo interface to query all supported resource types. - if (url_checker_delegate_->IsUrlWhitelisted(urls_[next_index_].url) || - !database_manager_->CanCheckResourceType(resource_type_) || - database_manager_->CheckBrowseUrl( - urls_[next_index_].url, url_checker_delegate_->GetThreatTypes(), - this)) { - std::move(urls_[next_index_].callback).Run(true, false); - next_index_++; + if (!database_manager_->CanCheckResourceType(resource_type_)) { + // TODO(vakh): Consider changing this metric to + // SafeBrowsing.V4ResourceType to be consistent with the other PVer4 + // metrics. + UMA_HISTOGRAM_ENUMERATION("SB2.ResourceTypes2.Skipped", resource_type_, + content::RESOURCE_TYPE_LAST_TYPE); + + RunNextCallback(true, false); + continue; + } + + // TODO(vakh): Consider changing this metric to SafeBrowsing.V4ResourceType + // to be consistent with the other PVer4 metrics. + UMA_HISTOGRAM_ENUMERATION("SB2.ResourceTypes2.Checked", resource_type_, + content::RESOURCE_TYPE_LAST_TYPE); + + SBThreatType threat_type = CheckWebUIUrls(url); + if (threat_type != safe_browsing::SB_THREAT_TYPE_SAFE) { + state_ = STATE_CHECKING_URL; + content::BrowserThread::PostTask( + content::BrowserThread::IO, FROM_HERE, + base::Bind(&SafeBrowsingUrlCheckerImpl::OnCheckBrowseUrlResult, + weak_factory_.GetWeakPtr(), url, threat_type, + ThreatMetadata())); + break; + } + + if (database_manager_->CheckBrowseUrl( + url, url_checker_delegate_->GetThreatTypes(), this)) { + RunNextCallback(true, false); continue; } @@ -168,7 +210,7 @@ // If user decided to not proceed through a warning, mark all the remaining // redirects as "bad". for (; next_index_ < urls_.size(); ++next_index_) - std::move(urls_[next_index_].callback).Run(false, showed_interstitial); + RunNextCallback(false, showed_interstitial); } void SafeBrowsingUrlCheckerImpl::OnBlockingPageComplete(bool proceed) { @@ -176,12 +218,31 @@ if (proceed) { state_ = STATE_NONE; - std::move(urls_[next_index_].callback).Run(true, true); - next_index_++; + RunNextCallback(true, true); ProcessUrls(); } else { BlockAndProcessUrls(true); } } +SBThreatType SafeBrowsingUrlCheckerImpl::CheckWebUIUrls(const GURL& url) { + // TODO(yzshen): This duplicates the logic in + // safe_browsing::BaseResourceThrottle::CheckWebUIUrls(), which eventually + // will go away. crbug.com/715673 + if (url == kChromeUISafeBrowsingMatchMalwareUrl) + return safe_browsing::SB_THREAT_TYPE_URL_MALWARE; + if (url == kChromeUISafeBrowsingMatchPhishingUrl) + return safe_browsing::SB_THREAT_TYPE_URL_PHISHING; + if (url == kChromeUISafeBrowsingMatchUnwantedUrl) + return safe_browsing::SB_THREAT_TYPE_URL_UNWANTED; + + return safe_browsing::SB_THREAT_TYPE_SAFE; +} + +void SafeBrowsingUrlCheckerImpl::RunNextCallback(bool proceed, + bool showed_interstitial) { + DCHECK_LT(next_index_, urls_.size()); + std::move(urls_[next_index_++].callback).Run(proceed, showed_interstitial); +} + } // namespace safe_browsing
diff --git a/components/safe_browsing/browser/safe_browsing_url_checker_impl.h b/components/safe_browsing/browser/safe_browsing_url_checker_impl.h index 7cb8dd9..93fde0f 100644 --- a/components/safe_browsing/browser/safe_browsing_url_checker_impl.h +++ b/components/safe_browsing/browser/safe_browsing_url_checker_impl.h
@@ -30,8 +30,6 @@ // queries from the browser. In that case, the public methods are called // directly instead of through Mojo. // Used when --enable-network-service is in effect. -// -// TODO(yzshen): Do all the logging like what BaseResourceThrottle does. class SafeBrowsingUrlCheckerImpl : public mojom::SafeBrowsingUrlChecker, public SafeBrowsingDatabaseManager::Client { public: @@ -64,6 +62,10 @@ void OnBlockingPageComplete(bool proceed); + SBThreatType CheckWebUIUrls(const GURL& url); + + void RunNextCallback(bool proceed, bool showed_interstitial); + enum State { // Haven't started checking or checking is complete. STATE_NONE,
diff --git a/components/safe_browsing/common/utils.cc b/components/safe_browsing/common/utils.cc index 67baa8c1..52a75fe 100644 --- a/components/safe_browsing/common/utils.cc +++ b/components/safe_browsing/common/utils.cc
@@ -4,6 +4,7 @@ #include "components/safe_browsing/common/utils.h" +#include "base/metrics/histogram_macros.h" #include "base/strings/string_number_conversions.h" #include "crypto/sha2.h" @@ -22,4 +23,8 @@ return spec; } +void LogDelay(base::TimeDelta time) { + UMA_HISTOGRAM_LONG_TIMES("SB2.Delay", time); +} + } // namespace safe_browsing
diff --git a/components/safe_browsing/common/utils.h b/components/safe_browsing/common/utils.h index fa3b8a7..9a0965da 100644 --- a/components/safe_browsing/common/utils.h +++ b/components/safe_browsing/common/utils.h
@@ -1,4 +1,4 @@ -// Copyrights 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // @@ -7,6 +7,7 @@ #ifndef COMPONENTS_SAFE_BROWSING_COMMON_UTILS_H_ #define COMPONENTS_SAFE_BROWSING_COMMON_UTILS_H_ +#include "base/time/time.h" #include "url/gurl.h" namespace safe_browsing { @@ -15,6 +16,13 @@ // scheme. std::string ShortURLForReporting(const GURL& url); +// UMA histogram helper for logging "SB2.Delay". +// Logs the user perceived delay caused by SafeBrowsing. This delay is the time +// delta starting from when we would have started reading data from the network, +// and ending when the SafeBrowsing check completes indicating that the current +// page is 'safe'. +void LogDelay(base::TimeDelta time); + } // namespace safe_browsing #endif // COMPONENTS_SAFE_BROWSING_COMMON_UTILS_H_
diff --git a/components/safe_browsing/renderer/BUILD.gn b/components/safe_browsing/renderer/BUILD.gn index 8e7fdd0c..271efd9f 100644 --- a/components/safe_browsing/renderer/BUILD.gn +++ b/components/safe_browsing/renderer/BUILD.gn
@@ -32,6 +32,7 @@ deps = [ "//base:base", + "//components/safe_browsing/common:common", "//components/safe_browsing/common:interfaces", "//content/public/common:common", "//content/public/renderer:renderer",
diff --git a/components/safe_browsing/renderer/renderer_url_loader_throttle.cc b/components/safe_browsing/renderer/renderer_url_loader_throttle.cc index ec22e1d..32af0628 100644 --- a/components/safe_browsing/renderer/renderer_url_loader_throttle.cc +++ b/components/safe_browsing/renderer/renderer_url_loader_throttle.cc
@@ -5,6 +5,7 @@ #include "components/safe_browsing/renderer/renderer_url_loader_throttle.h" #include "base/logging.h" +#include "components/safe_browsing/common/utils.h" #include "content/public/common/resource_request.h" #include "mojo/public/cpp/bindings/interface_request.h" #include "net/url_request/redirect_info.h" @@ -66,8 +67,15 @@ // shouldn't be such a notification. DCHECK(!blocked_); - if (pending_checks_ > 0) - *defer = true; + if (pending_checks_ == 0) { + LogDelay(base::TimeDelta()); + return; + } + + DCHECK(!deferred_); + deferred_ = true; + defer_start_time_ = base::TimeTicks::Now(); + *defer = true; } void RendererURLLoaderThrottle::OnCheckUrlResult(bool proceed, @@ -79,9 +87,9 @@ pending_checks_--; if (proceed) { - if (pending_checks_ == 0) { - // The resource load is not necessarily deferred, in that case Resume() is - // a no-op. + if (pending_checks_ == 0 && deferred_) { + LogDelay(base::TimeTicks::Now() - defer_start_time_); + deferred_ = false; delegate_->Resume(); } } else { @@ -98,7 +106,12 @@ // If a service-side disconnect happens, treat all URLs as if they are safe. url_checker_.reset(); pending_checks_ = 0; - delegate_->Resume(); + + if (deferred_) { + deferred_ = false; + LogDelay(base::TimeTicks::Now() - defer_start_time_); + delegate_->Resume(); + } } } // namespace safe_browsing
diff --git a/components/safe_browsing/renderer/renderer_url_loader_throttle.h b/components/safe_browsing/renderer/renderer_url_loader_throttle.h index bb7a4b6..9f64297d 100644 --- a/components/safe_browsing/renderer/renderer_url_loader_throttle.h +++ b/components/safe_browsing/renderer/renderer_url_loader_throttle.h
@@ -44,6 +44,10 @@ size_t pending_checks_ = 0; bool blocked_ = false; + // The time when we started deferring the request. + base::TimeTicks defer_start_time_; + bool deferred_ = false; + base::WeakPtrFactory<RendererURLLoaderThrottle> weak_factory_; };
diff --git a/components/search_provider_logos/google_logo_api.cc b/components/search_provider_logos/google_logo_api.cc index 16f52c9..1bafc2b 100644 --- a/components/search_provider_logos/google_logo_api.cc +++ b/components/search_provider_logos/google_logo_api.cc
@@ -200,7 +200,7 @@ query += "async="; - std::vector<base::StringPiece> params; + std::vector<std::string> params; params.push_back("ntp:1"); if (gray_background) { params.push_back("graybg:1");
diff --git a/components/search_provider_logos/google_logo_api_unittest.cc b/components/search_provider_logos/google_logo_api_unittest.cc index 4331e43..213bbfc 100644 --- a/components/search_provider_logos/google_logo_api_unittest.cc +++ b/components/search_provider_logos/google_logo_api_unittest.cc
@@ -15,10 +15,24 @@ #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" -using testing::Eq; - namespace search_provider_logos { +TEST(GoogleNewLogoApiTest, AppendsQueryParams) { + const GURL logo_url("https://base.doo/target"); + + EXPECT_EQ( + GURL("https://base.doo/target?async=ntp:1"), + GoogleNewAppendQueryparamsToLogoURL(false, logo_url, std::string())); + EXPECT_EQ(GURL("https://base.doo/target?async=ntp:1,graybg:1"), + GoogleNewAppendQueryparamsToLogoURL(true, logo_url, std::string())); + EXPECT_EQ( + GURL("https://base.doo/target?async=ntp:1,es_dfp:fingerprint"), + GoogleNewAppendQueryparamsToLogoURL(false, logo_url, "fingerprint")); + EXPECT_EQ( + GURL("https://base.doo/target?async=ntp:1,graybg:1,es_dfp:fingerprint"), + GoogleNewAppendQueryparamsToLogoURL(true, logo_url, "fingerprint")); +} + TEST(GoogleNewLogoApiTest, ResolvesRelativeUrl) { const GURL base_url("https://base.doo/"); const std::string json = R"json()]}'
diff --git a/components/translate/core/browser/translate_manager.cc b/components/translate/core/browser/translate_manager.cc index 146d1ab..02abc3ec 100644 --- a/components/translate/core/browser/translate_manager.cc +++ b/components/translate/core/browser/translate_manager.cc
@@ -181,6 +181,10 @@ if (!translate_prefs->IsEnabled()) { TranslateBrowserMetrics::ReportInitiationStatus( TranslateBrowserMetrics::INITIATION_STATUS_DISABLED_BY_PREFS); + std::string target_lang = GetTargetLanguage(translate_prefs.get()); + std::string language_code = + TranslateDownloadManager::GetLanguageCode(page_lang); + InitTranslateEvent(language_code, target_lang, *translate_prefs); RecordTranslateEvent(metrics::TranslateEventProto::DISABLED_BY_PREF); const std::string& locale = TranslateDownloadManager::GetInstance()->application_locale(); @@ -209,8 +213,6 @@ std::string language_code = TranslateDownloadManager::GetLanguageCode(page_lang); - InitTranslateEvent(language_code, target_lang, *translate_prefs); - // Don't translate similar languages (ex: en-US to en). if (language_code == target_lang) { TranslateBrowserMetrics::ReportInitiationStatus( @@ -218,6 +220,8 @@ return; } + InitTranslateEvent(language_code, target_lang, *translate_prefs); + // Querying the ranker now, but not exiting immediately so that we may log // other potential suppression reasons. bool should_offer_translation =
diff --git a/components/translate/core/common/translate_util.cc b/components/translate/core/common/translate_util.cc index 7eef452..bcd3266 100644 --- a/components/translate/core/common/translate_util.cc +++ b/components/translate/core/common/translate_util.cc
@@ -48,7 +48,6 @@ // are different to be exact. // // If this table is updated, please sync this with the synonym table in -// chrome/browser/resources/options/language_options.js and // chrome/browser/resources/settings/languages_page/languages.js. const LanguageCodePair kLanguageCodeSimilitudes[] = { {"no", "nb"}, @@ -59,7 +58,6 @@ // codes are used, so we must see them as synonyms. // // If this table is updated, please sync this with the synonym table in -// chrome/browser/resources/options/language_options.js and // chrome/browser/resources/settings/languages_page/languages.js. const LanguageCodePair kLanguageCodeSynonyms[] = { {"iw", "he"}, @@ -70,7 +68,6 @@ // Translate. // // If this table is updated, please sync this with the synonym table in -// chrome/browser/resources/options/language_options.js and // chrome/browser/resources/settings/languages_page/languages.js. const LanguageCodePair kLanguageCodeChineseCompatiblePairs[] = { {"zh-TW", "zh-HK"},
diff --git a/components/ui_devtools/devtools_server.h b/components/ui_devtools/devtools_server.h index f5bce62..ae8d608b 100644 --- a/components/ui_devtools/devtools_server.h +++ b/components/ui_devtools/devtools_server.h
@@ -20,8 +20,7 @@ namespace ui_devtools { -class UI_DEVTOOLS_EXPORT UiDevToolsServer - : public NON_EXPORTED_BASE(net::HttpServer::Delegate) { +class UI_DEVTOOLS_EXPORT UiDevToolsServer : public net::HttpServer::Delegate { public: ~UiDevToolsServer() override;
diff --git a/components/url_formatter/elide_url.cc b/components/url_formatter/elide_url.cc index 87f8852..1a7dc74 100644 --- a/components/url_formatter/elide_url.cc +++ b/components/url_formatter/elide_url.cc
@@ -55,6 +55,8 @@ // Takes a prefix (Domain, or Domain+subdomain) and a collection of path // components and elides if possible. Returns a string containing the longest // possible elided path, or an empty string if elision is not possible. +// Warning: This is O(url_path_elements.size() ^ 2), so it should not be called +// on a very large path. base::string16 ElideComponentizedPath( const base::string16& url_path_prefix, const std::vector<base::string16>& url_path_elements, @@ -259,12 +261,13 @@ } const size_t kMaxNumberOfUrlPathElementsAllowed = 1024; - // TODO(mgiuca): If there is no path, this means the end of the domain gets - // elided, not the start (inconsistent). https://crbug.com/739636. - if (url_path_number_of_elements <= 1 || - url_path_number_of_elements > kMaxNumberOfUrlPathElementsAllowed) { - // No path to elide, or too long of a path (could overflow in loop below) - // Just elide this as a text string. + if (url_path_number_of_elements > kMaxNumberOfUrlPathElementsAllowed) { + // Too long of a path (ElideComponentizedPath is O(N^2) so this would result + // in degenerate behaviour). Just elide this as a text string. + // TODO(mgiuca): Fix ElideComponentizedPath to deal with degenerate cases + // itself, so we don't need this special case. We should not fall back on + // ElideText if we don't know the entire domain will fit, or else we might + // chop off the TLD. https://crbug.com/739975. return gfx::ElideText(url_subdomain + url_domain + url_path_query_etc, font_list, available_pixel_width, gfx::ELIDE_TAIL); } @@ -276,11 +279,13 @@ gfx::GetStringWidthF(kEllipsisAndSlash, font_list); // Check with both subdomain and domain. - base::string16 elided_path = ElideComponentizedPath( - url_subdomain + url_domain, url_path_elements, url_filename, url_query, - font_list, available_pixel_width); - if (!elided_path.empty()) - return elided_path; + if (url_path_number_of_elements > 0) { + base::string16 elided_path = ElideComponentizedPath( + url_subdomain + url_domain, url_path_elements, url_filename, url_query, + font_list, available_pixel_width); + if (!elided_path.empty()) + return elided_path; + } // Check with only domain. // If a subdomain is present, add an ellipsis before domain. @@ -294,12 +299,13 @@ else url_elided_domain = url_domain; - elided_path = ElideComponentizedPath(url_elided_domain, url_path_elements, - url_filename, url_query, font_list, - available_pixel_width); - - if (!elided_path.empty()) - return elided_path; + if (url_path_number_of_elements > 0) { + base::string16 elided_path = ElideComponentizedPath( + url_elided_domain, url_path_elements, url_filename, url_query, + font_list, available_pixel_width); + if (!elided_path.empty()) + return elided_path; + } } // Return elided domain/.../filename anyway.
diff --git a/components/url_formatter/elide_url_unittest.cc b/components/url_formatter/elide_url_unittest.cc index 54f7024..79c5bf7 100644 --- a/components/url_formatter/elide_url_unittest.cc +++ b/components/url_formatter/elide_url_unittest.cc
@@ -111,7 +111,7 @@ const std::string kEllipsisStr(gfx::kEllipsis); Testcase testcases[] = { // Eliding the same URL to various lengths. - {"http://www.google.com/foo?bar", "www.google.com/foo?bar"}, + {"http://xyz.google.com/foo?bar", "xyz.google.com/foo?bar"}, {"http://xyz.google.com/foo?bar", "xyz.google.com/foo?" + kEllipsisStr}, {"http://xyz.google.com/foo?bar", "xyz.google.com/foo" + kEllipsisStr}, {"http://xyz.google.com/foo?bar", "xyz.google.com/fo" + kEllipsisStr}, @@ -133,11 +133,13 @@ {"http://xyz.google.com/foo?bar", kEllipsisStr + "googl" + kEllipsisStr}, {"http://xyz.google.com/foo?bar", kEllipsisStr + "g" + kEllipsisStr}, + // URL with "www" subdomain (gets removed specially). + {"http://www.google.com/foo?bar", "www.google.com/foo?bar"}, + {"http://www.google.com/foo?bar", "google.com/foo?bar"}, + // URL with no path. - // TODO(mgiuca): These should elide the start of the URL, not the end. - // https://crbug.com/739636. - {"http://xyz.google.com", "xyz.google" + kEllipsisStr}, - {"https://xyz.google.com", "xyz.google" + kEllipsisStr}, + {"http://xyz.google.com", kEllipsisStr + "google.com"}, + {"https://xyz.google.com", kEllipsisStr + "google.com"}, {"http://a.b.com/pathname/c?d", "a.b.com/" + kEllipsisStr + "/c?d"}, {"", ""},
diff --git a/components/user_manager/fake_user_manager.cc b/components/user_manager/fake_user_manager.cc index c046e77..37dd70d 100644 --- a/components/user_manager/fake_user_manager.cc +++ b/components/user_manager/fake_user_manager.cc
@@ -95,7 +95,7 @@ it != users_.end(); ++it) { if ((*it)->username_hash() == username_hash) { (*it)->set_is_logged_in(true); - (*it)->set_profile_is_created(); + (*it)->SetProfileIsCreated(); logged_in_users_.push_back(*it); if (!primary_user_)
diff --git a/components/user_manager/user.cc b/components/user_manager/user.cc index 11aba12..a89a91d5 100644 --- a/components/user_manager/user.cc +++ b/components/user_manager/user.cc
@@ -6,6 +6,7 @@ #include <stddef.h> +#include "base/callback.h" #include "base/logging.h" #include "base/macros.h" #include "base/strings/stringprintf.h" @@ -223,10 +224,22 @@ return is_active_; } +void User::AddProfileCreatedObserver(base::OnceClosure on_profile_created) { + DCHECK(!profile_is_created_); + on_profile_created_observers_.push_back(std::move(on_profile_created)); +} + bool User::IsAffiliated() const { return is_affiliated_; } +void User::SetProfileIsCreated() { + profile_is_created_ = true; + for (auto& callback : on_profile_created_observers_) + std::move(callback).Run(); + on_profile_created_observers_.clear(); +} + void User::SetAffiliation(bool is_affiliated) { is_affiliated_ = is_affiliated; }
diff --git a/components/user_manager/user.h b/components/user_manager/user.h index b8940e6..645cf88 100644 --- a/components/user_manager/user.h +++ b/components/user_manager/user.h
@@ -9,6 +9,7 @@ #include <string> #include <vector> +#include "base/callback_forward.h" #include "base/gtest_prod_util.h" #include "base/macros.h" #include "base/strings/string16.h" @@ -176,6 +177,8 @@ return CreatePublicAccountUser(account_id); } + void AddProfileCreatedObserver(base::OnceClosure on_profile_created); + protected: friend class UserManagerBase; friend class chromeos::ChromeUserManagerImpl; @@ -253,7 +256,7 @@ void set_is_active(bool is_active) { is_active_ = is_active; } - void set_profile_is_created() { profile_is_created_ = true; } + void SetProfileIsCreated(); // True if user has google account (not a guest or managed user). bool has_gaia_account() const; @@ -306,6 +309,8 @@ // True if the user is affiliated to the device. bool is_affiliated_ = false; + std::vector<base::OnceClosure> on_profile_created_observers_; + DISALLOW_COPY_AND_ASSIGN(User); };
diff --git a/components/viz/common/display/renderer_settings.h b/components/viz/common/display/renderer_settings.h index c7fb57c..bb8e9d3a 100644 --- a/components/viz/common/display/renderer_settings.h +++ b/components/viz/common/display/renderer_settings.h
@@ -29,6 +29,7 @@ bool gl_composited_overlay_candidate_quad_border = false; bool show_overdraw_feedback = false; bool enable_color_correct_rendering = false; + bool use_skia_renderer = false; int highp_threshold_min = 0; // Determines whether we disallow non-exact matches when finding resources
diff --git a/components/viz/common/gpu/in_process_context_provider.h b/components/viz/common/gpu/in_process_context_provider.h index 493191f..f1eea6c0 100644 --- a/components/viz/common/gpu/in_process_context_provider.h +++ b/components/viz/common/gpu/in_process_context_provider.h
@@ -33,8 +33,7 @@ namespace viz { -class VIZ_COMMON_EXPORT InProcessContextProvider - : public NON_EXPORTED_BASE(ContextProvider) { +class VIZ_COMMON_EXPORT InProcessContextProvider : public ContextProvider { public: InProcessContextProvider( scoped_refptr<gpu::InProcessCommandBuffer::Service> service,
diff --git a/components/viz/common/surfaces/sequence_surface_reference_factory.h b/components/viz/common/surfaces/sequence_surface_reference_factory.h index 93fa953..c3cbde9 100644 --- a/components/viz/common/surfaces/sequence_surface_reference_factory.h +++ b/components/viz/common/surfaces/sequence_surface_reference_factory.h
@@ -13,7 +13,7 @@ // A surface reference factory that uses SurfaceSequence. class VIZ_COMMON_EXPORT SequenceSurfaceReferenceFactory - : public NON_EXPORTED_BASE(SurfaceReferenceFactory) { + : public SurfaceReferenceFactory { public: SequenceSurfaceReferenceFactory() = default;
diff --git a/components/viz/common/surfaces/stub_surface_reference_factory.h b/components/viz/common/surfaces/stub_surface_reference_factory.h index ca5d649c..156809c 100644 --- a/components/viz/common/surfaces/stub_surface_reference_factory.h +++ b/components/viz/common/surfaces/stub_surface_reference_factory.h
@@ -15,7 +15,7 @@ // TODO(kylechar): Delete this class and all usage of // SurfaceReferenceFactory when surface references are enabled by default. class VIZ_COMMON_EXPORT StubSurfaceReferenceFactory - : public NON_EXPORTED_BASE(SurfaceReferenceFactory) { + : public SurfaceReferenceFactory { public: StubSurfaceReferenceFactory() = default;
diff --git a/components/viz/host/host_frame_sink_manager.h b/components/viz/host/host_frame_sink_manager.h index aebd032..07881a5 100644 --- a/components/viz/host/host_frame_sink_manager.h +++ b/components/viz/host/host_frame_sink_manager.h
@@ -41,8 +41,8 @@ // UI thread. Manages frame sinks and is intended to replace all usage of // FrameSinkManagerImpl. class VIZ_HOST_EXPORT HostFrameSinkManager - : public NON_EXPORTED_BASE(mojom::FrameSinkManagerClient), - public NON_EXPORTED_BASE(CompositorFrameSinkSupportManager) { + : public mojom::FrameSinkManagerClient, + public CompositorFrameSinkSupportManager { public: HostFrameSinkManager(); ~HostFrameSinkManager() override;
diff --git a/components/viz/host/renderer_settings_creation.cc b/components/viz/host/renderer_settings_creation.cc index 8f922a7c..c26b9de 100644 --- a/components/viz/host/renderer_settings_creation.cc +++ b/components/viz/host/renderer_settings_creation.cc
@@ -46,6 +46,8 @@ command_line->HasSwitch(switches::kDisallowNonExactResourceReuse); renderer_settings.allow_antialiasing = !command_line->HasSwitch(switches::kDisableCompositedAntialiasing); + renderer_settings.use_skia_renderer = + command_line->HasSwitch(switches::kUseSkiaRenderer); return renderer_settings; }
diff --git a/components/viz/host/server_gpu_memory_buffer_manager.cc b/components/viz/host/server_gpu_memory_buffer_manager.cc index bc09bc6..e2b2079 100644 --- a/components/viz/host/server_gpu_memory_buffer_manager.cc +++ b/components/viz/host/server_gpu_memory_buffer_manager.cc
@@ -14,7 +14,6 @@ #include "gpu/ipc/common/gpu_memory_buffer_support.h" #include "services/viz/gl/privileged/interfaces/gpu_service.mojom.h" #include "ui/gfx/buffer_format_util.h" -#include "ui/gfx/gpu_memory_buffer_tracing.h" namespace viz { @@ -164,11 +163,8 @@ uint64_t client_tracing_process_id = ClientIdToTracingId(client_id); if (buffer_info.type == gfx::SHARED_MEMORY_BUFFER) { - auto shared_buffer_guid = gfx::GetSharedMemoryGUIDForTracing( - client_tracing_process_id, buffer_id); - pmd->CreateSharedMemoryOwnershipEdge(dump->guid(), shared_buffer_guid, - buffer_info.shared_memory_guid, - 0 /* importance */); + pmd->CreateSharedMemoryOwnershipEdge( + dump->guid(), buffer_info.shared_memory_guid, 0 /* importance */); } else { auto shared_buffer_guid = gfx::GetGenericSharedGpuMemoryGUIDForTracing( client_tracing_process_id, buffer_id);
diff --git a/components/viz/service/BUILD.gn b/components/viz/service/BUILD.gn index 52bd20e..5dc37aa 100644 --- a/components/viz/service/BUILD.gn +++ b/components/viz/service/BUILD.gn
@@ -29,6 +29,8 @@ "display/program_binding.h", "display/shader.cc", "display/shader.h", + "display/skia_renderer.cc", + "display/skia_renderer.h", "display/static_geometry_binding.cc", "display/static_geometry_binding.h", "display/surface_aggregator.cc",
diff --git a/components/viz/service/display/display.cc b/components/viz/service/display/display.cc index bddc235..0f70ad2c 100644 --- a/components/viz/service/display/display.cc +++ b/components/viz/service/display/display.cc
@@ -20,6 +20,7 @@ #include "components/viz/service/display/display_client.h" #include "components/viz/service/display/display_scheduler.h" #include "components/viz/service/display/gl_renderer.h" +#include "components/viz/service/display/skia_renderer.h" #include "components/viz/service/display/surface_aggregator.h" #include "components/viz/service/surfaces/surface.h" #include "components/viz/service/surfaces/surface_manager.h" @@ -188,9 +189,14 @@ if (output_surface_->context_provider()) { DCHECK(texture_mailbox_deleter_); - renderer_ = base::MakeUnique<GLRenderer>(&settings_, output_surface_.get(), - resource_provider_.get(), - texture_mailbox_deleter_.get()); + if (!settings_.use_skia_renderer) { + renderer_ = base::MakeUnique<GLRenderer>( + &settings_, output_surface_.get(), resource_provider_.get(), + texture_mailbox_deleter_.get()); + } else { + renderer_ = base::MakeUnique<SkiaRenderer>( + &settings_, output_surface_.get(), resource_provider_.get()); + } } else if (output_surface_->vulkan_context_provider()) { #if defined(ENABLE_VULKAN) DCHECK(texture_mailbox_deleter_);
diff --git a/components/viz/service/display/skia_renderer.cc b/components/viz/service/display/skia_renderer.cc new file mode 100644 index 0000000..b1fb7fd --- /dev/null +++ b/components/viz/service/display/skia_renderer.cc
@@ -0,0 +1,680 @@ +// Copyright 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 "components/viz/service/display/skia_renderer.h" + +#include "base/memory/ptr_util.h" +#include "base/trace_event/trace_event.h" +#include "cc/base/math_util.h" +#include "cc/base/render_surface_filters.h" +#include "cc/output/output_surface.h" +#include "cc/output/output_surface_frame.h" +#include "cc/quads/debug_border_draw_quad.h" +#include "cc/quads/picture_draw_quad.h" +#include "cc/quads/render_pass_draw_quad.h" +#include "cc/quads/solid_color_draw_quad.h" +#include "cc/quads/texture_draw_quad.h" +#include "cc/quads/tile_draw_quad.h" +#include "cc/resources/scoped_resource.h" +#include "components/viz/common/display/renderer_settings.h" +#include "components/viz/common/quads/copy_output_request.h" +#include "gpu/command_buffer/client/gles2_interface.h" +#include "skia/ext/opacity_filter_canvas.h" +#include "third_party/skia/include/core/SkCanvas.h" +#include "third_party/skia/include/core/SkColor.h" +#include "third_party/skia/include/core/SkImageFilter.h" +#include "third_party/skia/include/core/SkMatrix.h" +#include "third_party/skia/include/core/SkPath.h" +#include "third_party/skia/include/core/SkPoint.h" +#include "third_party/skia/include/core/SkShader.h" +#include "third_party/skia/include/effects/SkLayerRasterizer.h" +#include "third_party/skia/include/gpu/GrContext.h" +#include "ui/gfx/geometry/axis_transform2d.h" +#include "ui/gfx/geometry/rect_conversions.h" +#include "ui/gfx/skia_util.h" +#include "ui/gfx/transform.h" + +namespace viz { +namespace { + +static inline bool IsScalarNearlyInteger(SkScalar scalar) { + return SkScalarNearlyZero(scalar - SkScalarRoundToScalar(scalar)); +} + +bool IsScaleAndIntegerTranslate(const SkMatrix& matrix) { + return IsScalarNearlyInteger(matrix[SkMatrix::kMTransX]) && + IsScalarNearlyInteger(matrix[SkMatrix::kMTransY]) && + SkScalarNearlyZero(matrix[SkMatrix::kMSkewX]) && + SkScalarNearlyZero(matrix[SkMatrix::kMSkewY]) && + SkScalarNearlyZero(matrix[SkMatrix::kMPersp0]) && + SkScalarNearlyZero(matrix[SkMatrix::kMPersp1]) && + SkScalarNearlyZero(matrix[SkMatrix::kMPersp2] - 1.0f); +} + +} // anonymous namespace + +SkiaRenderer::SkiaRenderer(const RendererSettings* settings, + cc::OutputSurface* output_surface, + cc::ResourceProvider* resource_provider) + : DirectRenderer(settings, output_surface, resource_provider) { + const auto& context_caps = + output_surface_->context_provider()->ContextCapabilities(); + use_swap_with_bounds_ = context_caps.swap_buffers_with_bounds; +} + +SkiaRenderer::~SkiaRenderer() {} + +bool SkiaRenderer::CanPartialSwap() { + if (use_swap_with_bounds_) + return false; + auto* context_provider = output_surface_->context_provider(); + return context_provider->ContextCapabilities().post_sub_buffer; +} + +ResourceFormat SkiaRenderer::BackbufferFormat() const { + // From GL Renderer. + if (current_frame()->current_render_pass->color_space.IsHDR() && + resource_provider_->IsRenderBufferFormatSupported(RGBA_F16)) { + return RGBA_F16; + } + return resource_provider_->best_texture_format(); +} + +void SkiaRenderer::BeginDrawingFrame() { + TRACE_EVENT0("cc", "SkiaRenderer::BeginDrawingFrame"); + // Copied from GLRenderer. + bool use_sync_query_ = false; + scoped_refptr<cc::ResourceProvider::Fence> read_lock_fence; + // TODO(weiliangc): Implement use_sync_query_. (crbug.com/644851) + if (use_sync_query_) { + NOTIMPLEMENTED(); + } else { + read_lock_fence = + make_scoped_refptr(new cc::ResourceProvider::SynchronousFence( + output_surface_->context_provider()->ContextGL())); + } + resource_provider_->SetReadLockFence(read_lock_fence.get()); + + // Insert WaitSyncTokenCHROMIUM on quad resources prior to drawing the frame, + // so that drawing can proceed without GL context switching interruptions. + cc::ResourceProvider* resource_provider = resource_provider_; + for (const auto& pass : *current_frame()->render_passes_in_draw_order) { + for (auto* quad : pass->quad_list) { + for (ResourceId resource_id : quad->resources) + resource_provider->WaitSyncToken(resource_id); + } + } +} + +void SkiaRenderer::FinishDrawingFrame() { + TRACE_EVENT0("cc", "SkiaRenderer::FinishDrawingFrame"); + current_framebuffer_surface_lock_ = nullptr; + current_framebuffer_lock_ = nullptr; + current_canvas_ = nullptr; + + swap_buffer_rect_ = current_frame()->root_damage_rect; + + if (use_swap_with_bounds_) + swap_content_bounds_ = current_frame()->root_content_bounds; +} + +void SkiaRenderer::SwapBuffers(std::vector<ui::LatencyInfo> latency_info) { + DCHECK(visible_); + TRACE_EVENT0("cc,benchmark", "SkiaRenderer::SwapBuffers"); + cc::OutputSurfaceFrame output_frame; + output_frame.latency_info = std::move(latency_info); + output_frame.size = surface_size_for_swap_buffers(); + if (use_swap_with_bounds_) { + output_frame.content_bounds = std::move(swap_content_bounds_); + } else if (use_partial_swap_) { + swap_buffer_rect_.Intersect(gfx::Rect(surface_size_for_swap_buffers())); + output_frame.sub_buffer_rect = swap_buffer_rect_; + } else if (swap_buffer_rect_.IsEmpty() && allow_empty_swap_) { + output_frame.sub_buffer_rect = swap_buffer_rect_; + } + output_surface_->SwapBuffers(std::move(output_frame)); + + swap_buffer_rect_ = gfx::Rect(); +} + +bool SkiaRenderer::FlippedFramebuffer() const { + // TODO(weiliangc): Make sure flipped correctly for Windows. + // (crbug.com/644851) + return false; +} + +void SkiaRenderer::EnsureScissorTestEnabled() { + is_scissor_enabled_ = true; +} + +void SkiaRenderer::EnsureScissorTestDisabled() { + is_scissor_enabled_ = false; +} + +void SkiaRenderer::BindFramebufferToOutputSurface() { + DCHECK(!output_surface_->HasExternalStencilTest()); + current_framebuffer_lock_ = nullptr; + + // TODO(weiliangc): Set up correct can_use_lcd_text and + // use_distance_field_text for SkSurfaceProps flags. How to setup is in + // ResourceProvider. (crbug.com/644851) + + GrContext* gr_context = output_surface_->context_provider()->GrContext(); + if (!root_canvas_ || root_canvas_->getGrContext() != gr_context || + gfx::SkISizeToSize(root_canvas_->getBaseLayerSize()) != + current_frame()->device_viewport_size) { + // Either no SkSurface setup yet, or new GrContext, need to create new + // surface. + GrBackendRenderTargetDesc desc; + desc.fWidth = current_frame()->device_viewport_size.width(); + desc.fHeight = current_frame()->device_viewport_size.height(); + desc.fConfig = kRGBA_8888_GrPixelConfig; + desc.fOrigin = kBottomLeft_GrSurfaceOrigin; + desc.fSampleCnt = 1; + desc.fStencilBits = 8; + desc.fRenderTargetHandle = 0; + + // This is for use_distance_field_text false, and can_use_lcd_text true. + // LegacyFontHost will get LCD text and skia figures out what type to use. + SkSurfaceProps surface_props = + SkSurfaceProps(0, SkSurfaceProps::kLegacyFontHost_InitType); + + root_surface_ = SkSurface::MakeFromBackendRenderTarget( + gr_context, desc, nullptr, &surface_props); + } + + root_canvas_ = root_surface_->getCanvas(); + + current_canvas_ = root_canvas_; +} + +bool SkiaRenderer::BindFramebufferToTexture(const cc::ScopedResource* texture) { + DCHECK(texture->id()); + + // Explicitly release lock, otherwise we can crash when try to lock + // same texture again. + current_framebuffer_surface_lock_ = nullptr; + current_framebuffer_lock_ = nullptr; + current_framebuffer_lock_ = + base::WrapUnique(new cc::ResourceProvider::ScopedWriteLockGL( + resource_provider_, texture->id())); + + current_framebuffer_surface_lock_ = + base::WrapUnique(new cc::ResourceProvider::ScopedSkSurface( + output_surface_->context_provider()->GrContext(), + current_framebuffer_lock_->GetTexture(), + current_framebuffer_lock_->target(), + current_framebuffer_lock_->size(), + current_framebuffer_lock_->format(), false, true, 0)); + + current_canvas_ = current_framebuffer_surface_lock_->surface()->getCanvas(); + return true; +} + +void SkiaRenderer::SetScissorTestRect(const gfx::Rect& scissor_rect) { + is_scissor_enabled_ = true; + scissor_rect_ = scissor_rect; +} + +void SkiaRenderer::SetClipRect(const gfx::Rect& rect) { + if (!current_canvas_) + return; + // Skia applies the current matrix to clip rects so we reset it temporary. + SkMatrix current_matrix = current_canvas_->getTotalMatrix(); + current_canvas_->resetMatrix(); + // SetClipRect is assumed to be applied temporarily, on an + // otherwise-unclipped canvas. + DCHECK_EQ(current_canvas_->getDeviceClipBounds().width(), + current_canvas_->imageInfo().width()); + DCHECK_EQ(current_canvas_->getDeviceClipBounds().height(), + current_canvas_->imageInfo().height()); + current_canvas_->clipRect(gfx::RectToSkRect(rect)); + current_canvas_->setMatrix(current_matrix); +} + +void SkiaRenderer::ClearCanvas(SkColor color) { + if (!current_canvas_) + return; + + if (is_scissor_enabled_) { + // The same paint used by SkCanvas::clear, but applied to the scissor rect. + SkPaint clear_paint; + clear_paint.setColor(color); + clear_paint.setBlendMode(SkBlendMode::kSrc); + current_canvas_->drawRect(gfx::RectToSkRect(scissor_rect_), clear_paint); + } else { + current_canvas_->clear(color); + } +} + +void SkiaRenderer::ClearFramebuffer() { + if (current_frame()->current_render_pass->has_transparent_background) { + ClearCanvas(SkColorSetARGB(0, 0, 0, 0)); + } else { +#ifndef NDEBUG + // On DEBUG builds, opaque render passes are cleared to blue + // to easily see regions that were not drawn on the screen. + ClearCanvas(SkColorSetARGB(255, 0, 0, 255)); +#endif + } +} + +void SkiaRenderer::PrepareSurfaceForPass( + SurfaceInitializationMode initialization_mode, + const gfx::Rect& render_pass_scissor) { + switch (initialization_mode) { + case SURFACE_INITIALIZATION_MODE_PRESERVE: + EnsureScissorTestDisabled(); + return; + case SURFACE_INITIALIZATION_MODE_FULL_SURFACE_CLEAR: + EnsureScissorTestDisabled(); + ClearFramebuffer(); + break; + case SURFACE_INITIALIZATION_MODE_SCISSORED_CLEAR: + SetScissorTestRect(render_pass_scissor); + ClearFramebuffer(); + break; + } +} + +bool SkiaRenderer::IsSoftwareResource(ResourceId resource_id) const { + switch (resource_provider_->GetResourceType(resource_id)) { + case cc::ResourceProvider::RESOURCE_TYPE_GPU_MEMORY_BUFFER: + case cc::ResourceProvider::RESOURCE_TYPE_GL_TEXTURE: + return true; + case cc::ResourceProvider::RESOURCE_TYPE_BITMAP: + return false; + } + + LOG(FATAL) << "Invalid resource type."; + return false; +} + +void SkiaRenderer::DoDrawQuad(const cc::DrawQuad* quad, + const gfx::QuadF* draw_region) { + if (!current_canvas_) + return; + if (draw_region) { + current_canvas_->save(); + } + + TRACE_EVENT0("cc", "SkiaRenderer::DoDrawQuad"); + gfx::Transform quad_rect_matrix; + QuadRectTransform(&quad_rect_matrix, + quad->shared_quad_state->quad_to_target_transform, + gfx::RectF(quad->rect)); + gfx::Transform contents_device_transform = + current_frame()->window_matrix * current_frame()->projection_matrix * + quad_rect_matrix; + contents_device_transform.FlattenTo2d(); + SkMatrix sk_device_matrix; + gfx::TransformToFlattenedSkMatrix(contents_device_transform, + &sk_device_matrix); + current_canvas_->setMatrix(sk_device_matrix); + + current_paint_.reset(); + if (settings_->force_antialiasing || + !IsScaleAndIntegerTranslate(sk_device_matrix)) { + // TODO(danakj): Until we can enable AA only on exterior edges of the + // layer, disable AA if any interior edges are present. crbug.com/248175 + bool all_four_edges_are_exterior = + quad->IsTopEdge() && quad->IsLeftEdge() && quad->IsBottomEdge() && + quad->IsRightEdge(); + if (settings_->allow_antialiasing && + (settings_->force_antialiasing || all_four_edges_are_exterior)) + current_paint_.setAntiAlias(true); + current_paint_.setFilterQuality(kLow_SkFilterQuality); + } + + if (quad->ShouldDrawWithBlending() || + quad->shared_quad_state->blend_mode != SkBlendMode::kSrcOver) { + current_paint_.setAlpha(quad->shared_quad_state->opacity * 255); + current_paint_.setBlendMode( + static_cast<SkBlendMode>(quad->shared_quad_state->blend_mode)); + } else { + current_paint_.setBlendMode(SkBlendMode::kSrc); + } + + if (draw_region) { + gfx::QuadF local_draw_region(*draw_region); + SkPath draw_region_clip_path; + local_draw_region -= + gfx::Vector2dF(quad->visible_rect.x(), quad->visible_rect.y()); + local_draw_region.Scale(1.0f / quad->visible_rect.width(), + 1.0f / quad->visible_rect.height()); + local_draw_region -= gfx::Vector2dF(0.5f, 0.5f); + + SkPoint clip_points[4]; + QuadFToSkPoints(local_draw_region, clip_points); + draw_region_clip_path.addPoly(clip_points, 4, true); + + current_canvas_->clipPath(draw_region_clip_path); + } + + switch (quad->material) { + case cc::DrawQuad::DEBUG_BORDER: + DrawDebugBorderQuad(cc::DebugBorderDrawQuad::MaterialCast(quad)); + break; + case cc::DrawQuad::PICTURE_CONTENT: + DrawPictureQuad(cc::PictureDrawQuad::MaterialCast(quad)); + break; + case cc::DrawQuad::RENDER_PASS: + DrawRenderPassQuad(cc::RenderPassDrawQuad::MaterialCast(quad)); + break; + case cc::DrawQuad::SOLID_COLOR: + DrawSolidColorQuad(cc::SolidColorDrawQuad::MaterialCast(quad)); + break; + case cc::DrawQuad::TEXTURE_CONTENT: + DrawTextureQuad(cc::TextureDrawQuad::MaterialCast(quad)); + break; + case cc::DrawQuad::TILED_CONTENT: + DrawTileQuad(cc::TileDrawQuad::MaterialCast(quad)); + break; + case cc::DrawQuad::SURFACE_CONTENT: + // Surface content should be fully resolved to other quad types before + // reaching a direct renderer. + NOTREACHED(); + break; + case cc::DrawQuad::INVALID: + case cc::DrawQuad::YUV_VIDEO_CONTENT: + case cc::DrawQuad::STREAM_VIDEO_CONTENT: + DrawUnsupportedQuad(quad); + NOTREACHED(); + break; + } + + current_canvas_->resetMatrix(); + if (draw_region) { + current_canvas_->restore(); + } +} + +void SkiaRenderer::DrawDebugBorderQuad(const cc::DebugBorderDrawQuad* quad) { + // We need to apply the matrix manually to have pixel-sized stroke width. + SkPoint vertices[4]; + gfx::RectFToSkRect(QuadVertexRect()).toQuad(vertices); + SkPoint transformed_vertices[4]; + current_canvas_->getTotalMatrix().mapPoints(transformed_vertices, vertices, + 4); + current_canvas_->resetMatrix(); + + current_paint_.setColor(quad->color); + current_paint_.setAlpha(quad->shared_quad_state->opacity * + SkColorGetA(quad->color)); + current_paint_.setStyle(SkPaint::kStroke_Style); + current_paint_.setStrokeWidth(quad->width); + current_canvas_->drawPoints(SkCanvas::kPolygon_PointMode, 4, + transformed_vertices, current_paint_); +} + +void SkiaRenderer::DrawPictureQuad(const cc::PictureDrawQuad* quad) { + SkMatrix content_matrix; + content_matrix.setRectToRect(gfx::RectFToSkRect(quad->tex_coord_rect), + gfx::RectFToSkRect(QuadVertexRect()), + SkMatrix::kFill_ScaleToFit); + current_canvas_->concat(content_matrix); + + const bool needs_transparency = + SkScalarRoundToInt(quad->shared_quad_state->opacity * 255) < 255; + const bool disable_image_filtering = + disable_picture_quad_image_filtering_ || quad->nearest_neighbor; + + TRACE_EVENT0("cc", "SkiaRenderer::DrawPictureQuad"); + + // TODO(ccameron): Determin a color space strategy for software rendering. + gfx::ColorSpace canvas_color_space; + if (settings_->enable_color_correct_rendering) + canvas_color_space = gfx::ColorSpace::CreateSRGB(); + + cc::RasterSource::PlaybackSettings playback_settings; + playback_settings.playback_to_shared_canvas = true; + if (needs_transparency || disable_image_filtering) { + // TODO(aelias): This isn't correct in all cases. We should detect these + // cases and fall back to a persistent bitmap backing + // (http://crbug.com/280374). + // TODO(vmpstr): Fold this canvas into playback and have raster source + // accept a set of settings on playback that will determine which canvas to + // apply. (http://crbug.com/594679) + skia::OpacityFilterCanvas filtered_canvas(current_canvas_, + quad->shared_quad_state->opacity, + disable_image_filtering); + quad->raster_source->PlaybackToCanvas( + &filtered_canvas, canvas_color_space, quad->content_rect, + quad->content_rect, + gfx::AxisTransform2d(quad->contents_scale, gfx::Vector2dF()), + playback_settings); + } else { + quad->raster_source->PlaybackToCanvas( + current_canvas_, canvas_color_space, quad->content_rect, + quad->content_rect, + gfx::AxisTransform2d(quad->contents_scale, gfx::Vector2dF()), + playback_settings); + } +} + +void SkiaRenderer::DrawSolidColorQuad(const cc::SolidColorDrawQuad* quad) { + gfx::RectF visible_quad_vertex_rect = cc::MathUtil::ScaleRectProportional( + QuadVertexRect(), gfx::RectF(quad->rect), gfx::RectF(quad->visible_rect)); + current_paint_.setColor(quad->color); + current_paint_.setAlpha(quad->shared_quad_state->opacity * + SkColorGetA(quad->color)); + current_canvas_->drawRect(gfx::RectFToSkRect(visible_quad_vertex_rect), + current_paint_); +} + +void SkiaRenderer::DrawTextureQuad(const cc::TextureDrawQuad* quad) { + if (!IsSoftwareResource(quad->resource_id())) { + DrawUnsupportedQuad(quad); + return; + } + + // TODO(skaslev): Add support for non-premultiplied alpha. + cc::ResourceProvider::ScopedReadLockSkImage lock(resource_provider_, + quad->resource_id()); + const SkImage* image = lock.sk_image(); + if (!image) + return; + gfx::RectF uv_rect = gfx::ScaleRect( + gfx::BoundingRect(quad->uv_top_left, quad->uv_bottom_right), + image->width(), image->height()); + gfx::RectF visible_uv_rect = cc::MathUtil::ScaleRectProportional( + uv_rect, gfx::RectF(quad->rect), gfx::RectF(quad->visible_rect)); + SkRect sk_uv_rect = gfx::RectFToSkRect(visible_uv_rect); + gfx::RectF visible_quad_vertex_rect = cc::MathUtil::ScaleRectProportional( + QuadVertexRect(), gfx::RectF(quad->rect), gfx::RectF(quad->visible_rect)); + SkRect quad_rect = gfx::RectFToSkRect(visible_quad_vertex_rect); + + if (quad->y_flipped) + current_canvas_->scale(1, -1); + + bool blend_background = + quad->background_color != SK_ColorTRANSPARENT && !image->isOpaque(); + bool needs_layer = blend_background && (current_paint_.getAlpha() != 0xFF); + if (needs_layer) { + current_canvas_->saveLayerAlpha(&quad_rect, current_paint_.getAlpha()); + current_paint_.setAlpha(0xFF); + } + if (blend_background) { + SkPaint background_paint; + background_paint.setColor(quad->background_color); + current_canvas_->drawRect(quad_rect, background_paint); + } + current_paint_.setFilterQuality( + quad->nearest_neighbor ? kNone_SkFilterQuality : kLow_SkFilterQuality); + current_canvas_->drawImageRect(image, sk_uv_rect, quad_rect, ¤t_paint_); + if (needs_layer) + current_canvas_->restore(); +} + +void SkiaRenderer::DrawTileQuad(const cc::TileDrawQuad* quad) { + // |resource_provider_| can be NULL in resourceless software draws, which + // should never produce tile quads in the first place. + DCHECK(resource_provider_); + DCHECK(IsSoftwareResource(quad->resource_id())); + cc::ResourceProvider::ScopedReadLockSkImage lock(resource_provider_, + quad->resource_id()); + if (!lock.sk_image()) + return; + gfx::RectF visible_tex_coord_rect = cc::MathUtil::ScaleRectProportional( + quad->tex_coord_rect, gfx::RectF(quad->rect), + gfx::RectF(quad->visible_rect)); + gfx::RectF visible_quad_vertex_rect = cc::MathUtil::ScaleRectProportional( + QuadVertexRect(), gfx::RectF(quad->rect), gfx::RectF(quad->visible_rect)); + + SkRect uv_rect = gfx::RectFToSkRect(visible_tex_coord_rect); + current_paint_.setFilterQuality( + quad->nearest_neighbor ? kNone_SkFilterQuality : kLow_SkFilterQuality); + current_canvas_->drawImageRect(lock.sk_image(), uv_rect, + gfx::RectFToSkRect(visible_quad_vertex_rect), + ¤t_paint_); +} + +void SkiaRenderer::DrawRenderPassQuad(const cc::RenderPassDrawQuad* quad) { + cc::ScopedResource* content_texture = + render_pass_textures_[quad->render_pass_id].get(); + DCHECK(content_texture); + DCHECK(content_texture->id()); + DCHECK(IsSoftwareResource(content_texture->id())); + cc::ResourceProvider::ScopedReadLockSkImage lock(resource_provider_, + content_texture->id()); + if (!lock.sk_image()) + return; + + SkRect dest_rect = gfx::RectFToSkRect(QuadVertexRect()); + SkRect dest_visible_rect = + gfx::RectFToSkRect(cc::MathUtil::ScaleRectProportional( + QuadVertexRect(), gfx::RectF(quad->rect), + gfx::RectF(quad->visible_rect))); + SkRect content_rect = RectFToSkRect(quad->tex_coord_rect); + + const SkImage* content = lock.sk_image(); + + current_canvas_->drawImageRect(lock.sk_image(), content_rect, + dest_visible_rect, ¤t_paint_); + + const cc::FilterOperations* filters = FiltersForPass(quad->render_pass_id); + + // TODO(weiliangc): Implement filters. (crbug.com/644851) + if (filters) { + NOTIMPLEMENTED(); + } + + SkMatrix content_mat; + content_mat.setRectToRect(content_rect, dest_rect, + SkMatrix::kFill_ScaleToFit); + + sk_sp<SkShader> shader; + shader = content->makeShader(SkShader::kClamp_TileMode, + SkShader::kClamp_TileMode, &content_mat); + + // TODO(weiliangc): Implement mask. (crbug.com/644851) + if (quad->mask_resource_id()) { + NOTIMPLEMENTED(); + } + + // TODO(weiliangc): If we have a background filter shader, render its results + // first. (crbug.com/644851) + + current_paint_.setShader(std::move(shader)); + current_canvas_->drawRect(dest_visible_rect, current_paint_); +} + +void SkiaRenderer::DrawUnsupportedQuad(const cc::DrawQuad* quad) { + // TODO(weiliangc): Make sure unsupported quads work. (crbug.com/644851) + NOTIMPLEMENTED(); +#ifdef NDEBUG + current_paint_.setColor(SK_ColorWHITE); +#else + current_paint_.setColor(SK_ColorMAGENTA); +#endif + current_paint_.setAlpha(quad->shared_quad_state->opacity * 255); + current_canvas_->drawRect(gfx::RectFToSkRect(QuadVertexRect()), + current_paint_); +} + +void SkiaRenderer::CopyCurrentRenderPassToBitmap( + std::unique_ptr<CopyOutputRequest> request) { + // TODO(weiliangc): Make copy request work. (crbug.com/644851) + NOTIMPLEMENTED(); +} + +void SkiaRenderer::SetEnableDCLayers(bool enable) { + // TODO(crbug.com/678800): Part of surport overlay on Windows. + NOTIMPLEMENTED(); +} + +void SkiaRenderer::DidChangeVisibility() { + if (visible_) + output_surface_->EnsureBackbuffer(); + else + output_surface_->DiscardBackbuffer(); +} + +void SkiaRenderer::FinishDrawingQuadList() { + current_canvas_->flush(); +} + +bool SkiaRenderer::ShouldApplyBackgroundFilters( + const cc::RenderPassDrawQuad* quad, + const cc::FilterOperations* background_filters) const { + if (!background_filters) + return false; + DCHECK(!background_filters->IsEmpty()); + + // TODO(hendrikw): Look into allowing background filters to see pixels from + // other render targets. See crbug.com/314867. + + return true; +} + +// If non-null, auto_bounds will be filled with the automatically-computed +// destination bounds. If null, the output will be the same size as the +// input bitmap. +sk_sp<SkImage> SkiaRenderer::ApplyImageFilter( + SkImageFilter* filter, + const cc::RenderPassDrawQuad* quad, + const SkBitmap& to_filter, + SkIRect* auto_bounds) const { + // TODO(weiliangc): Implement image filter. (crbug.com/644851) + NOTIMPLEMENTED(); + return nullptr; +} + +SkBitmap SkiaRenderer::GetBackdropBitmap(const gfx::Rect& bounding_rect) const { + SkBitmap bitmap; + bitmap.allocPixels(SkImageInfo::MakeN32Premul(bounding_rect.width(), + bounding_rect.height())); + if (!current_canvas_->readPixels(bitmap, bounding_rect.x(), + bounding_rect.y())) + bitmap.reset(); + return bitmap; +} + +gfx::Rect SkiaRenderer::GetBackdropBoundingBoxForRenderPassQuad( + const cc::RenderPassDrawQuad* quad, + const gfx::Transform& contents_device_transform, + const cc::FilterOperations* background_filters) const { + DCHECK(ShouldApplyBackgroundFilters(quad, background_filters)); + gfx::Rect backdrop_rect = gfx::ToEnclosingRect(cc::MathUtil::MapClippedRect( + contents_device_transform, QuadVertexRect())); + + SkMatrix matrix; + matrix.setScale(quad->filters_scale.x(), quad->filters_scale.y()); + backdrop_rect = background_filters->MapRectReverse(backdrop_rect, matrix); + + backdrop_rect.Intersect(MoveFromDrawToWindowSpace( + current_frame()->current_render_pass->output_rect)); + + return backdrop_rect; +} + +sk_sp<SkShader> SkiaRenderer::GetBackgroundFilterShader( + const cc::RenderPassDrawQuad* quad, + SkShader::TileMode content_tile_mode) const { + // TODO(weiliangc): properly implement background filters. (crbug.com/644851) + NOTIMPLEMENTED(); + return nullptr; +} + +} // namespace viz
diff --git a/components/viz/service/display/skia_renderer.h b/components/viz/service/display/skia_renderer.h new file mode 100644 index 0000000..86cb168 --- /dev/null +++ b/components/viz/service/display/skia_renderer.h
@@ -0,0 +1,114 @@ +// Copyright 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_VIZ_SERVICE_DISPLAY_SKIA_RENDERER_H_ +#define COMPONENTS_VIZ_SERVICE_DISPLAY_SKIA_RENDERER_H_ + +#include "base/macros.h" +#include "cc/cc_export.h" +#include "cc/output/direct_renderer.h" +#include "components/viz/service/viz_service_export.h" +#include "ui/latency/latency_info.h" + +namespace cc { +class DebugBorderDrawQuad; +class OutputSurface; +class PictureDrawQuad; +class RenderPassDrawQuad; +class ResourceProvider; +class SolidColorDrawQuad; +class TextureDrawQuad; +class TileDrawQuad; +} // namespace cc + +namespace viz { +class VIZ_SERVICE_EXPORT SkiaRenderer : public cc::DirectRenderer { + public: + SkiaRenderer(const RendererSettings* settings, + cc::OutputSurface* output_surface, + cc::ResourceProvider* resource_provider); + + ~SkiaRenderer() override; + + void SwapBuffers(std::vector<ui::LatencyInfo> latency_info) override; + + void SetDisablePictureQuadImageFiltering(bool disable) { + disable_picture_quad_image_filtering_ = disable; + } + + protected: + bool CanPartialSwap() override; + ResourceFormat BackbufferFormat() const override; + void BindFramebufferToOutputSurface() override; + bool BindFramebufferToTexture(const cc::ScopedResource* texture) override; + void SetScissorTestRect(const gfx::Rect& scissor_rect) override; + void PrepareSurfaceForPass(SurfaceInitializationMode initialization_mode, + const gfx::Rect& render_pass_scissor) override; + void DoDrawQuad(const cc::DrawQuad* quad, + const gfx::QuadF* draw_region) override; + void BeginDrawingFrame() override; + void FinishDrawingFrame() override; + bool FlippedFramebuffer() const override; + void EnsureScissorTestEnabled() override; + void EnsureScissorTestDisabled() override; + void CopyCurrentRenderPassToBitmap( + std::unique_ptr<CopyOutputRequest> request) override; + void SetEnableDCLayers(bool enable) override; + void DidChangeVisibility() override; + void FinishDrawingQuadList() override; + + private: + void ClearCanvas(SkColor color); + void ClearFramebuffer(); + void SetClipRect(const gfx::Rect& rect); + bool IsSoftwareResource(ResourceId resource_id) const; + + void DrawDebugBorderQuad(const cc::DebugBorderDrawQuad* quad); + void DrawPictureQuad(const cc::PictureDrawQuad* quad); + void DrawRenderPassQuad(const cc::RenderPassDrawQuad* quad); + void DrawSolidColorQuad(const cc::SolidColorDrawQuad* quad); + void DrawTextureQuad(const cc::TextureDrawQuad* quad); + void DrawTileQuad(const cc::TileDrawQuad* quad); + void DrawUnsupportedQuad(const cc::DrawQuad* quad); + bool ShouldApplyBackgroundFilters( + const cc::RenderPassDrawQuad* quad, + const cc::FilterOperations* background_filters) const; + sk_sp<SkImage> ApplyImageFilter(SkImageFilter* filter, + const cc::RenderPassDrawQuad* quad, + const SkBitmap& to_filter, + SkIRect* auto_bounds) const; + gfx::Rect GetBackdropBoundingBoxForRenderPassQuad( + const cc::RenderPassDrawQuad* quad, + const gfx::Transform& contents_device_transform, + const cc::FilterOperations* background_filters) const; + SkBitmap GetBackdropBitmap(const gfx::Rect& bounding_rect) const; + sk_sp<SkShader> GetBackgroundFilterShader( + const cc::RenderPassDrawQuad* quad, + SkShader::TileMode content_tile_mode) const; + + bool disable_picture_quad_image_filtering_ = false; + + bool is_scissor_enabled_ = false; + gfx::Rect scissor_rect_; + + sk_sp<SkSurface> root_surface_; + SkCanvas* root_canvas_ = nullptr; + SkCanvas* current_canvas_ = nullptr; + SkPaint current_paint_; + std::unique_ptr<cc::ResourceProvider::ScopedWriteLockGL> + current_framebuffer_lock_; + std::unique_ptr<cc::ResourceProvider::ScopedSkSurface> + current_framebuffer_surface_lock_; + + bool use_swap_with_bounds_ = false; + + gfx::Rect swap_buffer_rect_; + std::vector<gfx::Rect> swap_content_bounds_; + + DISALLOW_COPY_AND_ASSIGN(SkiaRenderer); +}; + +} // namespace viz + +#endif // COMPONENTS_VIZ_SERVICE_DISPLAY_SKIA_RENDERER_H_
diff --git a/components/viz/service/display_embedder/gpu_display_provider.h b/components/viz/service/display_embedder/gpu_display_provider.h index 9c6a457..833e05da 100644 --- a/components/viz/service/display_embedder/gpu_display_provider.h +++ b/components/viz/service/display_embedder/gpu_display_provider.h
@@ -26,8 +26,7 @@ class Display; // In-process implementation of DisplayProvider. -class VIZ_SERVICE_EXPORT GpuDisplayProvider - : public NON_EXPORTED_BASE(DisplayProvider) { +class VIZ_SERVICE_EXPORT GpuDisplayProvider : public DisplayProvider { public: GpuDisplayProvider( scoped_refptr<gpu::InProcessCommandBuffer::Service> gpu_service,
diff --git a/components/viz/service/display_embedder/server_shared_bitmap_manager.cc b/components/viz/service/display_embedder/server_shared_bitmap_manager.cc index 07a45c9..840bf19 100644 --- a/components/viz/service/display_embedder/server_shared_bitmap_manager.cc +++ b/components/viz/service/display_embedder/server_shared_bitmap_manager.cc
@@ -139,17 +139,17 @@ base::trace_event::MemoryAllocatorDump::kUnitsBytes, bitmap.second->buffer_size); - // Generate a global GUID used to share this allocation with renderer - // processes. - auto guid = GetSharedBitmapGUIDForTracing(bitmap.first); - base::UnguessableToken shared_memory_guid; if (bitmap.second->memory) { - shared_memory_guid = bitmap.second->memory->mapped_id(); + base::UnguessableToken shared_memory_guid = + bitmap.second->memory->mapped_id(); if (!shared_memory_guid.is_empty()) { - pmd->CreateSharedMemoryOwnershipEdge( - dump->guid(), guid, shared_memory_guid, 0 /* importance*/); + pmd->CreateSharedMemoryOwnershipEdge(dump->guid(), shared_memory_guid, + 0 /* importance*/); } } else { + // Generate a global GUID used to share this allocation with renderer + // processes. + auto guid = GetSharedBitmapGUIDForTracing(bitmap.first); pmd->CreateSharedGlobalAllocatorDump(guid); pmd->AddOwnershipEdge(dump->guid(), guid); }
diff --git a/components/viz/service/display_embedder/server_shared_bitmap_manager.h b/components/viz/service/display_embedder/server_shared_bitmap_manager.h index cd801a1..ebffeabc 100644 --- a/components/viz/service/display_embedder/server_shared_bitmap_manager.h +++ b/components/viz/service/display_embedder/server_shared_bitmap_manager.h
@@ -26,7 +26,7 @@ // malloc/free, but can only be used in the same process as the display // compositor. class VIZ_SERVICE_EXPORT ServerSharedBitmapManager - : public NON_EXPORTED_BASE(SharedBitmapManager), + : public SharedBitmapManager, public base::trace_event::MemoryDumpProvider { public: ServerSharedBitmapManager();
diff --git a/components/viz/service/display_embedder/shared_bitmap_allocation_notifier_impl.h b/components/viz/service/display_embedder/shared_bitmap_allocation_notifier_impl.h index 080fece..cd3faf2 100644 --- a/components/viz/service/display_embedder/shared_bitmap_allocation_notifier_impl.h +++ b/components/viz/service/display_embedder/shared_bitmap_allocation_notifier_impl.h
@@ -23,7 +23,7 @@ }; class VIZ_SERVICE_EXPORT SharedBitmapAllocationNotifierImpl - : NON_EXPORTED_BASE(public mojom::SharedBitmapAllocationNotifier) { + : public mojom::SharedBitmapAllocationNotifier { public: explicit SharedBitmapAllocationNotifierImpl( ServerSharedBitmapManager* manager);
diff --git a/components/viz/service/frame_sinks/compositor_frame_sink_impl.h b/components/viz/service/frame_sinks/compositor_frame_sink_impl.h index f340824..b32cd25f 100644 --- a/components/viz/service/frame_sinks/compositor_frame_sink_impl.h +++ b/components/viz/service/frame_sinks/compositor_frame_sink_impl.h
@@ -20,9 +20,8 @@ namespace viz { // Server side representation of a WindowSurface. -class CompositorFrameSinkImpl - : public NON_EXPORTED_BASE(CompositorFrameSinkSupportClient), - public NON_EXPORTED_BASE(mojom::CompositorFrameSink) { +class CompositorFrameSinkImpl : public CompositorFrameSinkSupportClient, + public mojom::CompositorFrameSink { public: CompositorFrameSinkImpl(FrameSinkManagerImpl* frame_sink_manager, const FrameSinkId& frame_sink_id,
diff --git a/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.h b/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.h index 0b4dffd..fc8c401 100644 --- a/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.h +++ b/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.h
@@ -28,9 +28,9 @@ // client's frame being the root surface of the Display. class VIZ_SERVICE_EXPORT DirectLayerTreeFrameSink : public cc::LayerTreeFrameSink, - public NON_EXPORTED_BASE(CompositorFrameSinkSupportClient), + public CompositorFrameSinkSupportClient, public ExternalBeginFrameSourceClient, - public NON_EXPORTED_BASE(DisplayClient) { + public DisplayClient { public: // The underlying Display, FrameSinkManagerImpl, and LocalSurfaceIdAllocator // must outlive this class.
diff --git a/components/viz/service/frame_sinks/frame_sink_manager_impl.h b/components/viz/service/frame_sinks/frame_sink_manager_impl.h index c47489c..7c5a314 100644 --- a/components/viz/service/frame_sinks/frame_sink_manager_impl.h +++ b/components/viz/service/frame_sinks/frame_sink_manager_impl.h
@@ -40,9 +40,8 @@ // FrameSinkManagerImpl manages BeginFrame hierarchy. This is the implementation // detail for FrameSinkManagerImpl. -class VIZ_SERVICE_EXPORT FrameSinkManagerImpl - : public SurfaceObserver, - public NON_EXPORTED_BASE(mojom::FrameSinkManager) { +class VIZ_SERVICE_EXPORT FrameSinkManagerImpl : public SurfaceObserver, + public mojom::FrameSinkManager { public: FrameSinkManagerImpl(DisplayProvider* display_provider = nullptr, SurfaceManager::LifetimeType lifetime_type =
diff --git a/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.h b/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.h index e8bc685..13f3a3f 100644 --- a/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.h +++ b/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.h
@@ -25,12 +25,11 @@ class Display; class FrameSinkManagerImpl; -class RootCompositorFrameSinkImpl - : public NON_EXPORTED_BASE(CompositorFrameSinkSupportClient), - public NON_EXPORTED_BASE(mojom::CompositorFrameSink), - public NON_EXPORTED_BASE(mojom::DisplayPrivate), - public NON_EXPORTED_BASE(DisplayClient), - public HitTestAggregatorDelegate { +class RootCompositorFrameSinkImpl : public CompositorFrameSinkSupportClient, + public mojom::CompositorFrameSink, + public mojom::DisplayPrivate, + public DisplayClient, + public HitTestAggregatorDelegate { public: RootCompositorFrameSinkImpl( FrameSinkManagerImpl* frame_sink_manager,
diff --git a/components/viz/service/gl/gpu_service_impl.h b/components/viz/service/gl/gpu_service_impl.h index 5e5fe13..0633dad 100644 --- a/components/viz/service/gl/gpu_service_impl.h +++ b/components/viz/service/gl/gpu_service_impl.h
@@ -44,9 +44,8 @@ // This runs in the GPU process, and communicates with the gpu host (which is // the window server) over the mojom APIs. This is responsible for setting up // the connection to clients, allocating/free'ing gpu memory etc. -class VIZ_SERVICE_EXPORT GpuServiceImpl - : NON_EXPORTED_BASE(public gpu::GpuChannelManagerDelegate), - NON_EXPORTED_BASE(public mojom::GpuService) { +class VIZ_SERVICE_EXPORT GpuServiceImpl : public gpu::GpuChannelManagerDelegate, + public mojom::GpuService { public: GpuServiceImpl(const gpu::GPUInfo& gpu_info, std::unique_ptr<gpu::GpuWatchdogThread> watchdog,
diff --git a/components/viz/service/surfaces/direct_surface_reference_factory.h b/components/viz/service/surfaces/direct_surface_reference_factory.h index a938c72..1348578 100644 --- a/components/viz/service/surfaces/direct_surface_reference_factory.h +++ b/components/viz/service/surfaces/direct_surface_reference_factory.h
@@ -20,7 +20,7 @@ // You probably don't need to instantiate this class directly. // Use SurfaceManager::reference_factory() instead. class VIZ_SERVICE_EXPORT DirectSurfaceReferenceFactory final - : public NON_EXPORTED_BASE(SequenceSurfaceReferenceFactory) { + : public SequenceSurfaceReferenceFactory { public: explicit DirectSurfaceReferenceFactory(base::WeakPtr<SurfaceManager> manager);
diff --git a/components/webcrypto/fuzzer_support.cc b/components/webcrypto/fuzzer_support.cc index 832a9b8..f670933 100644 --- a/components/webcrypto/fuzzer_support.cc +++ b/components/webcrypto/fuzzer_support.cc
@@ -19,7 +19,7 @@ namespace { // This mock is used to initialize blink. -class InitOnce : NON_EXPORTED_BASE(public blink::Platform) { +class InitOnce : public blink::Platform { public: InitOnce() { base::CommandLine::Init(0, nullptr);
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index d2ced38..310963d 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -507,6 +507,7 @@ "cache_storage/cache_storage_scheduler.cc", "cache_storage/cache_storage_scheduler.h", "cache_storage/cache_storage_scheduler_client.h", + "child_process_importance.h", "child_process_launcher.cc", "child_process_launcher.h", "child_process_launcher_helper.cc", @@ -1465,6 +1466,10 @@ "service_worker/service_worker_response_info.h", "service_worker/service_worker_script_cache_map.cc", "service_worker/service_worker_script_cache_map.h", + "service_worker/service_worker_script_url_loader.cc", + "service_worker/service_worker_script_url_loader.h", + "service_worker/service_worker_script_url_loader_factory.cc", + "service_worker/service_worker_script_url_loader_factory.h", "service_worker/service_worker_storage.cc", "service_worker/service_worker_storage.h", "service_worker/service_worker_unregister_job.cc",
diff --git a/content/browser/accessibility/browser_accessibility_com_win.cc b/content/browser/accessibility/browser_accessibility_com_win.cc index f5200c1..c9a9be9 100644 --- a/content/browser/accessibility/browser_accessibility_com_win.cc +++ b/content/browser/accessibility/browser_accessibility_com_win.cc
@@ -85,17 +85,6 @@ } // -// IAccessible overrides: -// - -STDMETHODIMP BrowserAccessibilityComWin::get_accDefaultAction( - VARIANT var_id, - BSTR* def_action) { - AddAccessibilityModeFlags(kScreenReaderAndHTMLAccessibilityModes); - return AXPlatformNodeWin::get_accDefaultAction(var_id, def_action); -} - -// // IAccessible2 overrides: // @@ -123,11 +112,6 @@ return S_OK; } -STDMETHODIMP BrowserAccessibilityComWin::get_states(AccessibleStates* states) { - AddAccessibilityModeFlags(kScreenReaderAndHTMLAccessibilityModes); - return AXPlatformNodeWin::get_states(states); -} - STDMETHODIMP BrowserAccessibilityComWin::get_uniqueID(LONG* unique_id) { WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_UNIQUE_ID); if (!owner()) @@ -169,30 +153,6 @@ return S_OK; } -STDMETHODIMP BrowserAccessibilityComWin::get_nRelations(LONG* n_relations) { - WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_N_RELATIONS); - AddAccessibilityModeFlags(kScreenReaderAndHTMLAccessibilityModes); - return AXPlatformNodeWin::get_nRelations(n_relations); -} - -STDMETHODIMP BrowserAccessibilityComWin::get_relation( - LONG relation_index, - IAccessibleRelation** relation) { - WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_RELATION); - AddAccessibilityModeFlags(kScreenReaderAndHTMLAccessibilityModes); - return AXPlatformNodeWin::get_relation(relation_index, relation); -} - -STDMETHODIMP BrowserAccessibilityComWin::get_relations( - LONG max_relations, - IAccessibleRelation** relations, - LONG* n_relations) { - WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_RELATIONS); - AddAccessibilityModeFlags(kScreenReaderAndHTMLAccessibilityModes); - return AXPlatformNodeWin::get_relations(max_relations, relations, - n_relations); -} - STDMETHODIMP BrowserAccessibilityComWin::scrollTo(IA2ScrollType scroll_type) { WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_IA2_SCROLL_TO); if (!owner()) @@ -437,297 +397,6 @@ } // -// IAccessibleTable methods. -// - -STDMETHODIMP BrowserAccessibilityComWin::get_accessibleAt( - long row, - long column, - IUnknown** accessible) { - AddAccessibilityModeFlags(kScreenReaderAndHTMLAccessibilityModes); - return AXPlatformNodeWin::get_accessibleAt(row, column, accessible); -} - -STDMETHODIMP BrowserAccessibilityComWin::get_caption(IUnknown** accessible) { - AddAccessibilityModeFlags(kScreenReaderAndHTMLAccessibilityModes); - return AXPlatformNodeWin::get_caption(accessible); -} - -STDMETHODIMP BrowserAccessibilityComWin::get_childIndex(long row, - long column, - long* cell_index) { - AddAccessibilityModeFlags(kScreenReaderAndHTMLAccessibilityModes); - return AXPlatformNodeWin::get_childIndex(row, column, cell_index); -} - -STDMETHODIMP BrowserAccessibilityComWin::get_columnDescription( - long column, - BSTR* description) { - AddAccessibilityModeFlags(kScreenReaderAndHTMLAccessibilityModes); - return AXPlatformNodeWin::get_columnDescription(column, description); -} - -STDMETHODIMP BrowserAccessibilityComWin::get_columnExtentAt( - long row, - long column, - long* n_columns_spanned) { - AddAccessibilityModeFlags(kScreenReaderAndHTMLAccessibilityModes); - return AXPlatformNodeWin::get_columnExtentAt(row, column, n_columns_spanned); -} - -STDMETHODIMP BrowserAccessibilityComWin::get_columnHeader( - IAccessibleTable** accessible_table, - long* starting_row_index) { - AddAccessibilityModeFlags(kScreenReaderAndHTMLAccessibilityModes); - return AXPlatformNodeWin::get_columnHeader(accessible_table, - starting_row_index); -} - -STDMETHODIMP BrowserAccessibilityComWin::get_columnIndex(long cell_index, - long* column_index) { - AddAccessibilityModeFlags(kScreenReaderAndHTMLAccessibilityModes); - return AXPlatformNodeWin::get_columnIndex(cell_index, column_index); -} - -STDMETHODIMP BrowserAccessibilityComWin::get_nColumns(long* column_count) { - AddAccessibilityModeFlags(kScreenReaderAndHTMLAccessibilityModes); - return AXPlatformNodeWin::get_nColumns(column_count); -} - -STDMETHODIMP BrowserAccessibilityComWin::get_nRows(long* row_count) { - AddAccessibilityModeFlags(kScreenReaderAndHTMLAccessibilityModes); - return AXPlatformNodeWin::get_nRows(row_count); -} - -STDMETHODIMP BrowserAccessibilityComWin::get_nSelectedChildren( - long* cell_count) { - AddAccessibilityModeFlags(kScreenReaderAndHTMLAccessibilityModes); - return AXPlatformNodeWin::get_nSelectedChildren(cell_count); -} - -STDMETHODIMP BrowserAccessibilityComWin::get_nSelectedColumns( - long* column_count) { - AddAccessibilityModeFlags(kScreenReaderAndHTMLAccessibilityModes); - return AXPlatformNodeWin::get_nSelectedColumns(column_count); -} - -STDMETHODIMP BrowserAccessibilityComWin::get_nSelectedRows(long* row_count) { - AddAccessibilityModeFlags(kScreenReaderAndHTMLAccessibilityModes); - return AXPlatformNodeWin::get_nSelectedRows(row_count); -} - -STDMETHODIMP BrowserAccessibilityComWin::get_rowDescription(long row, - BSTR* description) { - AddAccessibilityModeFlags(kScreenReaderAndHTMLAccessibilityModes); - return AXPlatformNodeWin::get_rowDescription(row, description); -} - -STDMETHODIMP BrowserAccessibilityComWin::get_rowExtentAt(long row, - long column, - long* n_rows_spanned) { - AddAccessibilityModeFlags(kScreenReaderAndHTMLAccessibilityModes); - return AXPlatformNodeWin::get_rowExtentAt(row, column, n_rows_spanned); -} - -STDMETHODIMP BrowserAccessibilityComWin::get_rowHeader( - IAccessibleTable** accessible_table, - long* starting_column_index) { - AddAccessibilityModeFlags(kScreenReaderAndHTMLAccessibilityModes); - return AXPlatformNodeWin::get_rowHeader(accessible_table, - starting_column_index); -} - -STDMETHODIMP BrowserAccessibilityComWin::get_rowIndex(long cell_index, - long* row_index) { - AddAccessibilityModeFlags(kScreenReaderAndHTMLAccessibilityModes); - return AXPlatformNodeWin::get_rowIndex(cell_index, row_index); -} - -STDMETHODIMP BrowserAccessibilityComWin::get_selectedChildren( - long max_children, - long** children, - long* n_children) { - AddAccessibilityModeFlags(kScreenReaderAndHTMLAccessibilityModes); - return AXPlatformNodeWin::get_selectedChildren(max_children, children, - n_children); -} - -STDMETHODIMP BrowserAccessibilityComWin::get_selectedColumns(long max_columns, - long** columns, - long* n_columns) { - AddAccessibilityModeFlags(kScreenReaderAndHTMLAccessibilityModes); - return AXPlatformNodeWin::get_selectedColumns(max_columns, columns, - n_columns); -} - -STDMETHODIMP BrowserAccessibilityComWin::get_selectedRows(long max_rows, - long** rows, - long* n_rows) { - AddAccessibilityModeFlags(kScreenReaderAndHTMLAccessibilityModes); - return AXPlatformNodeWin::get_selectedRows(max_rows, rows, n_rows); -} - -STDMETHODIMP BrowserAccessibilityComWin::get_summary(IUnknown** accessible) { - AddAccessibilityModeFlags(kScreenReaderAndHTMLAccessibilityModes); - return AXPlatformNodeWin::get_summary(accessible); -} - -STDMETHODIMP BrowserAccessibilityComWin::get_isColumnSelected( - long column, - boolean* is_selected) { - AddAccessibilityModeFlags(kScreenReaderAndHTMLAccessibilityModes); - return AXPlatformNodeWin::get_isColumnSelected(column, is_selected); -} - -STDMETHODIMP BrowserAccessibilityComWin::get_isRowSelected( - long row, - boolean* is_selected) { - AddAccessibilityModeFlags(kScreenReaderAndHTMLAccessibilityModes); - return AXPlatformNodeWin::get_isRowSelected(row, is_selected); -} - -STDMETHODIMP BrowserAccessibilityComWin::get_isSelected(long row, - long column, - boolean* is_selected) { - AddAccessibilityModeFlags(kScreenReaderAndHTMLAccessibilityModes); - return AXPlatformNodeWin::get_isSelected(row, column, is_selected); -} - -STDMETHODIMP BrowserAccessibilityComWin::get_rowColumnExtentsAtIndex( - long index, - long* row, - long* column, - long* row_extents, - long* column_extents, - boolean* is_selected) { - AddAccessibilityModeFlags(kScreenReaderAndHTMLAccessibilityModes); - return AXPlatformNodeWin::get_rowColumnExtentsAtIndex( - index, row, column, row_extents, column_extents, is_selected); -} - -STDMETHODIMP BrowserAccessibilityComWin::selectRow(long row) { - AddAccessibilityModeFlags(kScreenReaderAndHTMLAccessibilityModes); - return AXPlatformNodeWin::selectRow(row); -} - -STDMETHODIMP BrowserAccessibilityComWin::selectColumn(long column) { - AddAccessibilityModeFlags(kScreenReaderAndHTMLAccessibilityModes); - return AXPlatformNodeWin::selectColumn(column); -} - -STDMETHODIMP BrowserAccessibilityComWin::unselectRow(long row) { - AddAccessibilityModeFlags(kScreenReaderAndHTMLAccessibilityModes); - return AXPlatformNodeWin::unselectRow(row); -} - -STDMETHODIMP BrowserAccessibilityComWin::unselectColumn(long column) { - AddAccessibilityModeFlags(kScreenReaderAndHTMLAccessibilityModes); - return AXPlatformNodeWin::unselectColumn(column); -} - -STDMETHODIMP -BrowserAccessibilityComWin::get_modelChange(IA2TableModelChange* model_change) { - return AXPlatformNodeWin::get_modelChange(model_change); -} - -// -// IAccessibleTable2 methods. -// - -STDMETHODIMP BrowserAccessibilityComWin::get_cellAt(long row, - long column, - IUnknown** cell) { - AddAccessibilityModeFlags(ui::AXMode::kScreenReader); - return AXPlatformNodeWin::get_cellAt(row, column, cell); -} - -STDMETHODIMP BrowserAccessibilityComWin::get_nSelectedCells(long* cell_count) { - AddAccessibilityModeFlags(kScreenReaderAndHTMLAccessibilityModes); - return AXPlatformNodeWin::get_nSelectedCells(cell_count); -} - -STDMETHODIMP BrowserAccessibilityComWin::get_selectedCells( - IUnknown*** cells, - long* n_selected_cells) { - AddAccessibilityModeFlags(kScreenReaderAndHTMLAccessibilityModes); - return AXPlatformNodeWin::get_selectedCells(cells, n_selected_cells); -} - -STDMETHODIMP BrowserAccessibilityComWin::get_selectedColumns(long** columns, - long* n_columns) { - AddAccessibilityModeFlags(kScreenReaderAndHTMLAccessibilityModes); - return AXPlatformNodeWin::get_selectedColumns(columns, n_columns); -} - -STDMETHODIMP BrowserAccessibilityComWin::get_selectedRows(long** rows, - long* n_rows) { - AddAccessibilityModeFlags(kScreenReaderAndHTMLAccessibilityModes); - return AXPlatformNodeWin::get_selectedRows(rows, n_rows); -} - -// -// IAccessibleTableCell methods. -// - -STDMETHODIMP BrowserAccessibilityComWin::get_columnExtent( - long* n_columns_spanned) { - AddAccessibilityModeFlags(kScreenReaderAndHTMLAccessibilityModes); - return AXPlatformNodeWin::get_columnExtent(n_columns_spanned); -} - -STDMETHODIMP BrowserAccessibilityComWin::get_columnHeaderCells( - IUnknown*** cell_accessibles, - long* n_column_header_cells) { - AddAccessibilityModeFlags(kScreenReaderAndHTMLAccessibilityModes); - return AXPlatformNodeWin::get_columnHeaderCells(cell_accessibles, - n_column_header_cells); -} - -STDMETHODIMP BrowserAccessibilityComWin::get_columnIndex(long* column_index) { - AddAccessibilityModeFlags(kScreenReaderAndHTMLAccessibilityModes); - return AXPlatformNodeWin::get_columnIndex(column_index); -} - -STDMETHODIMP BrowserAccessibilityComWin::get_rowExtent(long* n_rows_spanned) { - AddAccessibilityModeFlags(kScreenReaderAndHTMLAccessibilityModes); - return AXPlatformNodeWin::get_rowExtent(n_rows_spanned); -} - -STDMETHODIMP BrowserAccessibilityComWin::get_rowHeaderCells( - IUnknown*** cell_accessibles, - long* n_row_header_cells) { - AddAccessibilityModeFlags(kScreenReaderAndHTMLAccessibilityModes); - return AXPlatformNodeWin::get_rowHeaderCells(cell_accessibles, - n_row_header_cells); -} - -STDMETHODIMP BrowserAccessibilityComWin::get_rowIndex(long* row_index) { - AddAccessibilityModeFlags(kScreenReaderAndHTMLAccessibilityModes); - return AXPlatformNodeWin::get_rowIndex(row_index); -} - -STDMETHODIMP BrowserAccessibilityComWin::get_isSelected(boolean* is_selected) { - AddAccessibilityModeFlags(kScreenReaderAndHTMLAccessibilityModes); - return AXPlatformNodeWin::get_isSelected(is_selected); -} - -STDMETHODIMP BrowserAccessibilityComWin::get_rowColumnExtents( - long* row_index, - long* column_index, - long* row_extents, - long* column_extents, - boolean* is_selected) { - AddAccessibilityModeFlags(kScreenReaderAndHTMLAccessibilityModes); - return AXPlatformNodeWin::get_rowColumnExtents( - row_index, column_index, row_extents, column_extents, is_selected); -} - -STDMETHODIMP BrowserAccessibilityComWin::get_table(IUnknown** table) { - AddAccessibilityModeFlags(kScreenReaderAndHTMLAccessibilityModes); - return AXPlatformNodeWin::get_table(table); -} - -// // IAccessibleText methods. //
diff --git a/content/browser/accessibility/browser_accessibility_com_win.h b/content/browser/accessibility/browser_accessibility_com_win.h index ac269da..023ffd3 100644 --- a/content/browser/accessibility/browser_accessibility_com_win.h +++ b/content/browser/accessibility/browser_accessibility_com_win.h
@@ -67,9 +67,6 @@ COM_INTERFACE_ENTRY(IAccessibleHyperlink) COM_INTERFACE_ENTRY(IAccessibleHypertext) COM_INTERFACE_ENTRY(IAccessibleImage) - COM_INTERFACE_ENTRY(IAccessibleTable) - COM_INTERFACE_ENTRY(IAccessibleTable2) - COM_INTERFACE_ENTRY(IAccessibleTableCell) COM_INTERFACE_ENTRY(IAccessibleValue) COM_INTERFACE_ENTRY(IRawElementProviderSimple) COM_INTERFACE_ENTRY(ISimpleDOMDocument) @@ -99,20 +96,9 @@ CONTENT_EXPORT void UpdateStep3FireEvents(bool is_subtree_creation); // - // IAccessible methods. - // - - // Retrieves a string that describes the object's default action. - CONTENT_EXPORT STDMETHODIMP - get_accDefaultAction(VARIANT var_id, BSTR* default_action) override; - - // // IAccessible2 methods. // - // Returns the state bitmask from a larger set of possible states. - CONTENT_EXPORT STDMETHODIMP get_states(AccessibleStates* states) override; - // Returns the attributes specific to this IAccessible2 object, // such as a cell's formula. CONTENT_EXPORT STDMETHODIMP get_attributes(BSTR* attributes) override; @@ -127,14 +113,6 @@ // Get this object's index in its parent object. CONTENT_EXPORT STDMETHODIMP get_indexInParent(LONG* index_in_parent) override; - CONTENT_EXPORT STDMETHODIMP get_nRelations(LONG* n_relations) override; - - CONTENT_EXPORT STDMETHODIMP - get_relation(LONG relation_index, IAccessibleRelation** relation) override; - - CONTENT_EXPORT STDMETHODIMP get_relations(LONG max_relations, - IAccessibleRelation** relations, - LONG* n_relations) override; CONTENT_EXPORT STDMETHODIMP scrollTo(enum IA2ScrollType scroll_type) override; @@ -176,156 +154,6 @@ CONTENT_EXPORT STDMETHODIMP get_imageSize(LONG* height, LONG* width) override; // - // IAccessibleTable methods. - // - - // get_description - also used by IAccessibleImage - - CONTENT_EXPORT STDMETHODIMP get_accessibleAt(long row, - long column, - IUnknown** accessible) override; - - CONTENT_EXPORT STDMETHODIMP get_caption(IUnknown** accessible) override; - - CONTENT_EXPORT STDMETHODIMP get_childIndex(long row_index, - long column_index, - long* cell_index) override; - - CONTENT_EXPORT STDMETHODIMP get_columnDescription(long column, - BSTR* description) override; - - CONTENT_EXPORT STDMETHODIMP - get_columnExtentAt(long row, long column, long* n_columns_spanned) override; - - CONTENT_EXPORT STDMETHODIMP - get_columnHeader(IAccessibleTable** accessible_table, - long* starting_row_index) override; - - CONTENT_EXPORT STDMETHODIMP get_columnIndex(long cell_index, - long* column_index) override; - - CONTENT_EXPORT STDMETHODIMP get_nColumns(long* column_count) override; - - CONTENT_EXPORT STDMETHODIMP get_nRows(long* row_count) override; - - CONTENT_EXPORT STDMETHODIMP get_nSelectedChildren(long* cell_count) override; - - CONTENT_EXPORT STDMETHODIMP get_nSelectedColumns(long* column_count) override; - - CONTENT_EXPORT STDMETHODIMP get_nSelectedRows(long* row_count) override; - - CONTENT_EXPORT STDMETHODIMP get_rowDescription(long row, - BSTR* description) override; - - CONTENT_EXPORT STDMETHODIMP get_rowExtentAt(long row, - long column, - long* n_rows_spanned) override; - - CONTENT_EXPORT STDMETHODIMP - get_rowHeader(IAccessibleTable** accessible_table, - long* starting_column_index) override; - - CONTENT_EXPORT STDMETHODIMP get_rowIndex(long cell_index, - long* row_index) override; - - CONTENT_EXPORT STDMETHODIMP get_selectedChildren(long max_children, - long** children, - long* n_children) override; - - CONTENT_EXPORT STDMETHODIMP get_selectedColumns(long max_columns, - long** columns, - long* n_columns) override; - - CONTENT_EXPORT STDMETHODIMP get_selectedRows(long max_rows, - long** rows, - long* n_rows) override; - - CONTENT_EXPORT STDMETHODIMP get_summary(IUnknown** accessible) override; - - CONTENT_EXPORT STDMETHODIMP - get_isColumnSelected(long column, boolean* is_selected) override; - - CONTENT_EXPORT STDMETHODIMP get_isRowSelected(long row, - boolean* is_selected) override; - - CONTENT_EXPORT STDMETHODIMP get_isSelected(long row, - long column, - boolean* is_selected) override; - - CONTENT_EXPORT STDMETHODIMP - get_rowColumnExtentsAtIndex(long index, - long* row, - long* column, - long* row_extents, - long* column_extents, - boolean* is_selected) override; - - CONTENT_EXPORT STDMETHODIMP selectRow(long row) override; - - CONTENT_EXPORT STDMETHODIMP selectColumn(long column) override; - - CONTENT_EXPORT STDMETHODIMP unselectRow(long row) override; - - CONTENT_EXPORT STDMETHODIMP unselectColumn(long column) override; - - CONTENT_EXPORT STDMETHODIMP - get_modelChange(IA2TableModelChange* model_change) override; - - // - // IAccessibleTable2 methods. - // - // (Most of these are duplicates of IAccessibleTable methods, only the - // unique ones are included here.) - // - - CONTENT_EXPORT STDMETHODIMP get_cellAt(long row, - long column, - IUnknown** cell) override; - - CONTENT_EXPORT STDMETHODIMP get_nSelectedCells(long* cell_count) override; - - CONTENT_EXPORT STDMETHODIMP - get_selectedCells(IUnknown*** cells, long* n_selected_cells) override; - - CONTENT_EXPORT STDMETHODIMP get_selectedColumns(long** columns, - long* n_columns) override; - - CONTENT_EXPORT STDMETHODIMP get_selectedRows(long** rows, - long* n_rows) override; - - // - // IAccessibleTableCell methods. - // - - CONTENT_EXPORT STDMETHODIMP - get_columnExtent(long* n_columns_spanned) override; - - CONTENT_EXPORT STDMETHODIMP - get_columnHeaderCells(IUnknown*** cell_accessibles, - long* n_column_header_cells) override; - - CONTENT_EXPORT STDMETHODIMP get_columnIndex(long* column_index) override; - - CONTENT_EXPORT STDMETHODIMP get_rowExtent(long* n_rows_spanned) override; - - CONTENT_EXPORT STDMETHODIMP - get_rowHeaderCells(IUnknown*** cell_accessibles, - long* n_row_header_cells) override; - - CONTENT_EXPORT STDMETHODIMP get_rowIndex(long* row_index) override; - - CONTENT_EXPORT STDMETHODIMP get_isSelected(boolean* is_selected) override; - - CONTENT_EXPORT STDMETHODIMP - get_rowColumnExtents(long* row, - long* column, - long* row_extents, - long* column_extents, - boolean* is_selected) override; - - CONTENT_EXPORT STDMETHODIMP get_table(IUnknown** table) override; - - // // IAccessibleText methods. //
diff --git a/content/browser/accessibility/browser_accessibility_state_impl.cc b/content/browser/accessibility/browser_accessibility_state_impl.cc index 9a9fc3b0..869c222 100644 --- a/content/browser/accessibility/browser_accessibility_state_impl.cc +++ b/content/browser/accessibility/browser_accessibility_state_impl.cc
@@ -14,6 +14,7 @@ #include "content/browser/web_contents/web_contents_impl.h" #include "content/public/browser/browser_thread.h" #include "content/public/common/content_switches.h" +#include "ui/accessibility/platform/ax_platform_node.h" #include "ui/gfx/color_utils.h" namespace content { @@ -63,6 +64,9 @@ // delete it prematurely. AddRef(); + // Hook ourselves up to observe ax mode changes. + ui::AXPlatformNode::AddAXModeObserver(this); + #if defined(OS_WIN) // The delay is necessary because assistive technology sometimes isn't // detected until after the user interacts in some way, so a reasonable delay @@ -82,6 +86,8 @@ } BrowserAccessibilityStateImpl::~BrowserAccessibilityStateImpl() { + // Remove ourselves from the AXMode global observer list. + ui::AXPlatformNode::RemoveAXModeObserver(this); } void BrowserAccessibilityStateImpl::OnScreenReaderDetected() { @@ -147,6 +153,10 @@ switches::kForceRendererAccessibility)); } +void BrowserAccessibilityStateImpl::OnAXModeAdded(ui::AXMode mode) { + AddAccessibilityModeFlags(mode); +} + #if !defined(OS_WIN) && !defined(OS_MACOSX) void BrowserAccessibilityStateImpl::UpdatePlatformSpecificHistograms() { }
diff --git a/content/browser/accessibility/browser_accessibility_state_impl.h b/content/browser/accessibility/browser_accessibility_state_impl.h index 65efed8a..1eb3033 100644 --- a/content/browser/accessibility/browser_accessibility_state_impl.h +++ b/content/browser/accessibility/browser_accessibility_state_impl.h
@@ -11,6 +11,7 @@ #include "base/macros.h" #include "base/memory/singleton.h" #include "content/public/browser/browser_accessibility_state.h" +#include "ui/accessibility/ax_mode_observer.h" #include "ui/accessibility/ax_modes.h" namespace content { @@ -34,7 +35,8 @@ // mechanism). class CONTENT_EXPORT BrowserAccessibilityStateImpl : public base::RefCountedThreadSafe<BrowserAccessibilityStateImpl>, - public BrowserAccessibilityState { + public BrowserAccessibilityState, + public ui::AXModeObserver { public: BrowserAccessibilityStateImpl(); @@ -49,6 +51,9 @@ void UpdateHistogramsForTesting() override; + // AXModeObserver + void OnAXModeAdded(ui::AXMode mode) override; + ui::AXMode accessibility_mode() const { return accessibility_mode_; }; // Adds the given accessibility mode flags to the current accessibility
diff --git a/content/browser/accessibility/browser_accessibility_win.cc b/content/browser/accessibility/browser_accessibility_win.cc index 7e9341c5..604c4f9 100644 --- a/content/browser/accessibility/browser_accessibility_win.cc +++ b/content/browser/accessibility/browser_accessibility_win.cc
@@ -4,6 +4,7 @@ #include "content/browser/accessibility/browser_accessibility_win.h" #include "content/browser/accessibility/browser_accessibility_manager.h" +#include "content/browser/accessibility/browser_accessibility_state_impl.h" #include "ui/base/win/atl_module.h"
diff --git a/content/browser/accessibility/one_shot_accessibility_tree_search_unittest.cc b/content/browser/accessibility/one_shot_accessibility_tree_search_unittest.cc index 92fd8cdd..703392f 100644 --- a/content/browser/accessibility/one_shot_accessibility_tree_search_unittest.cc +++ b/content/browser/accessibility/one_shot_accessibility_tree_search_unittest.cc
@@ -7,6 +7,7 @@ #include <memory> #include "base/macros.h" +#include "base/task_scheduler/task_scheduler.h" #include "content/browser/accessibility/browser_accessibility.h" #include "content/browser/accessibility/browser_accessibility_manager.h" #include "testing/gtest/include/gtest/gtest.h" @@ -47,6 +48,14 @@ }; void MAYBE_OneShotAccessibilityTreeSearchTest::SetUp() { + // In order to mock TestBrowserAccessibilityManager, we need to also make sure + // there is a TaskScheduler started. This is because + // BrowserAccessibilityStateImpl posts a few tasks which will assert if there + // isn't a TaskScheduler. + // See: BrowserAccessibilityStateImpl::BrowserAccessibilityStateImpl(). + base::TaskScheduler::CreateAndStartWithDefaultParams( + "OneShotAccessibilityTreeSearchTest"); + ui::AXNodeData root; root.id = 1; root.SetName("Document");
diff --git a/content/browser/appcache/chrome_appcache_service.h b/content/browser/appcache/chrome_appcache_service.h index a34cd08..d4a2430 100644 --- a/content/browser/appcache/chrome_appcache_service.h +++ b/content/browser/appcache/chrome_appcache_service.h
@@ -41,8 +41,8 @@ class CONTENT_EXPORT ChromeAppCacheService : public base::RefCountedThreadSafe<ChromeAppCacheService, ChromeAppCacheServiceDeleter>, - NON_EXPORTED_BASE(public AppCacheServiceImpl), - NON_EXPORTED_BASE(public AppCachePolicy) { + public AppCacheServiceImpl, + public AppCachePolicy { public: explicit ChromeAppCacheService(storage::QuotaManagerProxy* proxy);
diff --git a/content/browser/background_sync/background_sync_manager.h b/content/browser/background_sync/background_sync_manager.h index 92ebc21..0ab44ce 100644 --- a/content/browser/background_sync/background_sync_manager.h +++ b/content/browser/background_sync/background_sync_manager.h
@@ -51,7 +51,7 @@ // the sync registrations are removed. This class must be run on the IO // thread. The asynchronous methods are executed sequentially. class CONTENT_EXPORT BackgroundSyncManager - : NON_EXPORTED_BASE(public ServiceWorkerContextCoreObserver) { + : public ServiceWorkerContextCoreObserver { public: using BoolCallback = base::OnceCallback<void(bool)>; using StatusAndRegistrationCallback =
diff --git a/content/browser/background_sync/background_sync_service_impl.h b/content/browser/background_sync/background_sync_service_impl.h index cf846da1..54ea4470 100644 --- a/content/browser/background_sync/background_sync_service_impl.h +++ b/content/browser/background_sync/background_sync_service_impl.h
@@ -22,7 +22,7 @@ class BackgroundSyncContext; class CONTENT_EXPORT BackgroundSyncServiceImpl - : public NON_EXPORTED_BASE(blink::mojom::BackgroundSyncService) { + : public blink::mojom::BackgroundSyncService { public: BackgroundSyncServiceImpl( BackgroundSyncContext* background_sync_context,
diff --git a/content/browser/bluetooth/web_bluetooth_service_impl.h b/content/browser/bluetooth/web_bluetooth_service_impl.h index c28200e..5ecd3e0 100644 --- a/content/browser/bluetooth/web_bluetooth_service_impl.h +++ b/content/browser/bluetooth/web_bluetooth_service_impl.h
@@ -47,7 +47,7 @@ // RenderFrameHostImpl will create an instance of this class and keep // ownership of it. class CONTENT_EXPORT WebBluetoothServiceImpl - : public NON_EXPORTED_BASE(blink::mojom::WebBluetoothService), + : public blink::mojom::WebBluetoothService, public WebContentsObserver, public device::BluetoothAdapter::Observer { public:
diff --git a/content/browser/browser_child_process_host_impl.h b/content/browser/browser_child_process_host_impl.h index 571e04a..7d23f16 100644 --- a/content/browser/browser_child_process_host_impl.h +++ b/content/browser/browser_child_process_host_impl.h
@@ -44,7 +44,7 @@ /// class because it lives on the UI thread. class CONTENT_EXPORT BrowserChildProcessHostImpl : public BrowserChildProcessHost, - public NON_EXPORTED_BASE(ChildProcessHostDelegate), + public ChildProcessHostDelegate, #if defined(OS_WIN) public base::win::ObjectWatcher::Delegate, #endif
diff --git a/content/browser/browser_context.cc b/content/browser/browser_context.cc index cea7206..cf2e555 100644 --- a/content/browser/browser_context.cc +++ b/content/browser/browser_context.cc
@@ -370,7 +370,7 @@ RenderProcessHost* host = host_iterator.GetCurrentValue(); if (host->GetBrowserContext() == browser_context) { // This will also clean up spare RPH references. - host->ForceReleaseWorkerRefCounts(); + host->DisableKeepAliveRefCount(); } } }
diff --git a/content/browser/cache_storage/cache_storage_context_impl.h b/content/browser/cache_storage/cache_storage_context_impl.h index 19c6e0e..47c28f0 100644 --- a/content/browser/cache_storage/cache_storage_context_impl.h +++ b/content/browser/cache_storage/cache_storage_context_impl.h
@@ -40,8 +40,7 @@ // child processes/origins. Most logic is delegated to the owned // CacheStorageManager instance, which is only accessed on the IO // thread. -class CONTENT_EXPORT CacheStorageContextImpl - : NON_EXPORTED_BASE(public CacheStorageContext) { +class CONTENT_EXPORT CacheStorageContextImpl : public CacheStorageContext { public: explicit CacheStorageContextImpl(BrowserContext* browser_context);
diff --git a/content/browser/child_process_importance.h b/content/browser/child_process_importance.h new file mode 100644 index 0000000..8f8edd1 --- /dev/null +++ b/content/browser/child_process_importance.h
@@ -0,0 +1,31 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_CHILD_PROCESS_IMPORTANCE_H_ +#define CONTENT_BROWSER_CHILD_PROCESS_IMPORTANCE_H_ + +namespace content { + +// Importance of a child process. For renderer processes, the importance is +// independent from visibility of its WebContents. +// Values are listed in increasing importance. +// +// Note this is only used by and implemented on Android which exposes this API +// through public java code. If this is useful on other platforms, then this +// enum and related methods on WebContentsImpl should be moved to the public +// interface. +// +// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.content_public.browser +enum class ChildProcessImportance { + // NORMAL is the default value. + NORMAL = 0, + MODERATE, + IMPORTANT, + // Place holder to represent number of values. + COUNT, +}; + +} // namespace content + +#endif // CONTENT_BROWSER_CHILD_PROCESS_IMPORTANCE_H_
diff --git a/content/browser/child_process_launcher.cc b/content/browser/child_process_launcher.cc index 0d87a7d..d2d28b96 100644 --- a/content/browser/child_process_launcher.cc +++ b/content/browser/child_process_launcher.cc
@@ -60,16 +60,18 @@ } } -void ChildProcessLauncher::SetProcessPriority(bool background, - bool boost_for_pending_views) { +void ChildProcessLauncher::SetProcessPriority( + bool background, + bool boost_for_pending_views, + ChildProcessImportance importance) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); base::Process to_pass = process_.process.Duplicate(); BrowserThread::PostTask( BrowserThread::PROCESS_LAUNCHER, FROM_HERE, base::Bind( &ChildProcessLauncherHelper::SetProcessPriorityOnLauncherThread, - helper_, base::Passed(&to_pass), background, - boost_for_pending_views)); + helper_, base::Passed(&to_pass), background, boost_for_pending_views, + importance)); } void ChildProcessLauncher::Notify(
diff --git a/content/browser/child_process_launcher.h b/content/browser/child_process_launcher.h index 074f2cf..10a9f09 100644 --- a/content/browser/child_process_launcher.h +++ b/content/browser/child_process_launcher.h
@@ -15,6 +15,7 @@ #include "base/process/process.h" #include "base/sequence_checker.h" #include "build/build_config.h" +#include "content/browser/child_process_importance.h" #include "content/browser/child_process_launcher_helper.h" #include "content/common/content_export.h" #include "content/public/browser/browser_thread.h" @@ -108,7 +109,9 @@ // Changes whether the process runs in the background or not. Only call // this after the process has started. - void SetProcessPriority(bool background, bool boost_for_pending_views); + void SetProcessPriority(bool background, + bool boost_for_pending_views, + ChildProcessImportance importance); // Terminates the process associated with this ChildProcessLauncher. // Returns true if the process was stopped, false if the process had not been
diff --git a/content/browser/child_process_launcher_helper.h b/content/browser/child_process_launcher_helper.h index 8c35bc4..2b20f6d 100644 --- a/content/browser/child_process_launcher_helper.h +++ b/content/browser/child_process_launcher_helper.h
@@ -12,6 +12,7 @@ #include "base/process/kill.h" #include "base/process/process.h" #include "build/build_config.h" +#include "content/browser/child_process_importance.h" #include "content/public/browser/browser_thread.h" #include "content/public/common/result_codes.h" #include "mojo/edk/embedder/embedder.h" @@ -161,7 +162,8 @@ void SetProcessPriorityOnLauncherThread(base::Process process, bool background, - bool boost_for_pending_views); + bool boost_for_pending_views, + ChildProcessImportance importance); static void SetRegisteredFilesForService( const std::string& service_name,
diff --git a/content/browser/child_process_launcher_helper_android.cc b/content/browser/child_process_launcher_helper_android.cc index 43d0c86..d126015 100644 --- a/content/browser/child_process_launcher_helper_android.cc +++ b/content/browser/child_process_launcher_helper_android.cc
@@ -171,11 +171,13 @@ void ChildProcessLauncherHelper::SetProcessPriorityOnLauncherThread( base::Process process, bool background, - bool boost_for_pending_views) { + bool boost_for_pending_views, + ChildProcessImportance importance) { JNIEnv* env = AttachCurrentThread(); DCHECK(env); - return Java_ChildProcessLauncherHelper_setInForeground( - env, java_peer_, process.Handle(), !background, boost_for_pending_views); + return Java_ChildProcessLauncherHelper_setPriority( + env, java_peer_, process.Handle(), !background, boost_for_pending_views, + static_cast<jint>(importance)); } // static
diff --git a/content/browser/child_process_launcher_helper_linux.cc b/content/browser/child_process_launcher_helper_linux.cc index 537522b..32c1c9c 100644 --- a/content/browser/child_process_launcher_helper_linux.cc +++ b/content/browser/child_process_launcher_helper_linux.cc
@@ -130,7 +130,8 @@ void ChildProcessLauncherHelper::SetProcessPriorityOnLauncherThread( base::Process process, bool background, - bool boost_for_pending_views) { + bool boost_for_pending_views, + ChildProcessImportance importance) { DCHECK_CURRENTLY_ON(BrowserThread::PROCESS_LAUNCHER); if (process.CanBackgroundProcesses()) process.SetProcessBackgrounded(background);
diff --git a/content/browser/child_process_launcher_helper_mac.cc b/content/browser/child_process_launcher_helper_mac.cc index e8a491e..52939da 100644 --- a/content/browser/child_process_launcher_helper_mac.cc +++ b/content/browser/child_process_launcher_helper_mac.cc
@@ -174,7 +174,8 @@ void ChildProcessLauncherHelper::SetProcessPriorityOnLauncherThread( base::Process process, bool background, - bool boost_for_pending_views) { + bool boost_for_pending_views, + ChildProcessImportance importance) { if (process.CanBackgroundProcesses()) process.SetProcessBackgrounded(MachBroker::GetInstance(), background); }
diff --git a/content/browser/child_process_launcher_helper_win.cc b/content/browser/child_process_launcher_helper_win.cc index d839c7b..d2bab245 100644 --- a/content/browser/child_process_launcher_helper_win.cc +++ b/content/browser/child_process_launcher_helper_win.cc
@@ -110,7 +110,8 @@ void ChildProcessLauncherHelper::SetProcessPriorityOnLauncherThread( base::Process process, bool background, - bool boost_for_pending_views) { + bool boost_for_pending_views, + ChildProcessImportance importance) { DCHECK_CURRENTLY_ON(BrowserThread::PROCESS_LAUNCHER); if (process.CanBackgroundProcesses()) process.SetProcessBackgrounded(background);
diff --git a/content/browser/child_process_security_policy_impl.h b/content/browser/child_process_security_policy_impl.h index 60dc5210..b1211d02 100644 --- a/content/browser/child_process_security_policy_impl.h +++ b/content/browser/child_process_security_policy_impl.h
@@ -39,7 +39,7 @@ class ResourceRequestBody; class CONTENT_EXPORT ChildProcessSecurityPolicyImpl - : NON_EXPORTED_BASE(public ChildProcessSecurityPolicy) { + : public ChildProcessSecurityPolicy { public: // Object can only be created through GetInstance() so the constructor is // private.
diff --git a/content/browser/device_sensors/device_sensor_browsertest.cc b/content/browser/device_sensors/device_sensor_browsertest.cc index feb4c75ac..c9cc0583 100644 --- a/content/browser/device_sensors/device_sensor_browsertest.cc +++ b/content/browser/device_sensors/device_sensor_browsertest.cc
@@ -2,13 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include <memory> -#include <string> -#include <utility> - #include "base/command_line.h" #include "base/macros.h" -#include "base/memory/ptr_util.h" #include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "base/synchronization/waitable_event.h" @@ -27,15 +22,6 @@ #include "device/sensors/device_sensor_service.h" #include "device/sensors/public/cpp/device_motion_hardware_buffer.h" #include "device/sensors/public/cpp/device_orientation_hardware_buffer.h" -#include "mojo/public/cpp/bindings/binding.h" -#include "mojo/public/cpp/bindings/strong_binding.h" -#include "mojo/public/cpp/system/buffer.h" -#include "services/device/public/cpp/generic_sensor/platform_sensor_configuration.h" -#include "services/device/public/cpp/generic_sensor/sensor_reading.h" -#include "services/device/public/interfaces/constants.mojom.h" -#include "services/device/public/interfaces/sensor.mojom.h" -#include "services/device/public/interfaces/sensor_provider.mojom.h" -#include "services/service_manager/public/cpp/service_context.h" namespace content { @@ -46,6 +32,14 @@ FakeDataFetcher() : sensor_data_available_(true) {} ~FakeDataFetcher() override {} + void SetMotionStartedCallback(base::Closure motion_started_callback) { + motion_started_callback_ = motion_started_callback; + } + + void SetMotionStoppedCallback(base::Closure motion_stopped_callback) { + motion_stopped_callback_ = motion_stopped_callback; + } + void SetOrientationStartedCallback( base::Closure orientation_started_callback) { orientation_started_callback_ = orientation_started_callback; @@ -72,6 +66,15 @@ EXPECT_TRUE(buffer); switch (consumer_type) { + case device::CONSUMER_TYPE_MOTION: { + device::DeviceMotionHardwareBuffer* motion_buffer = + static_cast<device::DeviceMotionHardwareBuffer*>(buffer); + if (sensor_data_available_) + UpdateMotion(motion_buffer); + SetMotionBufferReady(motion_buffer); + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, + motion_started_callback_); + } break; case device::CONSUMER_TYPE_ORIENTATION: { device::DeviceOrientationHardwareBuffer* orientation_buffer = static_cast<device::DeviceOrientationHardwareBuffer*>(buffer); @@ -98,6 +101,10 @@ bool Stop(device::ConsumerType consumer_type) override { switch (consumer_type) { + case device::CONSUMER_TYPE_MOTION: + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, + motion_stopped_callback_); + break; case device::CONSUMER_TYPE_ORIENTATION: BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, orientation_stopped_callback_); @@ -122,6 +129,12 @@ sensor_data_available_ = available; } + void SetMotionBufferReady(device::DeviceMotionHardwareBuffer* buffer) { + buffer->seqlock.WriteBegin(); + buffer->data.all_available_sensors_are_active = true; + buffer->seqlock.WriteEnd(); + } + void SetOrientationBufferReady( device::DeviceOrientationHardwareBuffer* buffer) { buffer->seqlock.WriteBegin(); @@ -129,6 +142,34 @@ buffer->seqlock.WriteEnd(); } + void UpdateMotion(device::DeviceMotionHardwareBuffer* buffer) { + buffer->seqlock.WriteBegin(); + buffer->data.acceleration_x = 1; + buffer->data.has_acceleration_x = true; + buffer->data.acceleration_y = 2; + buffer->data.has_acceleration_y = true; + buffer->data.acceleration_z = 3; + buffer->data.has_acceleration_z = true; + + buffer->data.acceleration_including_gravity_x = 4; + buffer->data.has_acceleration_including_gravity_x = true; + buffer->data.acceleration_including_gravity_y = 5; + buffer->data.has_acceleration_including_gravity_y = true; + buffer->data.acceleration_including_gravity_z = 6; + buffer->data.has_acceleration_including_gravity_z = true; + + buffer->data.rotation_rate_alpha = 7; + buffer->data.has_rotation_rate_alpha = true; + buffer->data.rotation_rate_beta = 8; + buffer->data.has_rotation_rate_beta = true; + buffer->data.rotation_rate_gamma = 9; + buffer->data.has_rotation_rate_gamma = true; + + buffer->data.interval = 100; + buffer->data.all_available_sensors_are_active = true; + buffer->seqlock.WriteEnd(); + } + void UpdateOrientation(device::DeviceOrientationHardwareBuffer* buffer) { buffer->seqlock.WriteBegin(); buffer->data.alpha = 1; @@ -156,8 +197,10 @@ } // The below callbacks should be run on the UI thread. + base::Closure motion_started_callback_; base::Closure orientation_started_callback_; base::Closure orientation_absolute_started_callback_; + base::Closure motion_stopped_callback_; base::Closure orientation_stopped_callback_; base::Closure orientation_absolute_stopped_callback_; bool sensor_data_available_; @@ -166,193 +209,6 @@ DISALLOW_COPY_AND_ASSIGN(FakeDataFetcher); }; -class FakeSensor : public device::mojom::Sensor { - public: - FakeSensor(device::mojom::SensorType sensor_type) - : sensor_type_(sensor_type) { - shared_buffer_handle_ = mojo::SharedBufferHandle::Create( - sizeof(device::SensorReadingSharedBuffer) * - static_cast<uint64_t>(device::mojom::SensorType::LAST)); - } - - ~FakeSensor() override = default; - - // device::mojom::Sensor: - void AddConfiguration( - const device::PlatformSensorConfiguration& configuration, - AddConfigurationCallback callback) override { - std::move(callback).Run(true); - SensorReadingChanged(); - } - - // device::mojom::Sensor: - void GetDefaultConfiguration( - GetDefaultConfigurationCallback callback) override { - std::move(callback).Run(GetDefaultConfiguration()); - } - - // device::mojom::Sensor: - void RemoveConfiguration( - const device::PlatformSensorConfiguration& configuration, - RemoveConfigurationCallback callback) override { - std::move(callback).Run(true); - } - - // device::mojom::Sensor: - void Suspend() override {} - void Resume() override {} - void ConfigureReadingChangeNotifications(bool enabled) override { - reading_notification_enabled_ = enabled; - } - - device::PlatformSensorConfiguration GetDefaultConfiguration() { - return device::PlatformSensorConfiguration(60 /* frequency */); - } - - device::mojom::ReportingMode GetReportingMode() { - return device::mojom::ReportingMode::ON_CHANGE; - } - - double GetMaximumSupportedFrequency() { return 60.0; } - double GetMinimumSupportedFrequency() { return 1.0; } - - device::mojom::SensorClientRequest GetClient() { - return mojo::MakeRequest(&client_); - } - - mojo::ScopedSharedBufferHandle GetSharedBufferHandle() { - return shared_buffer_handle_->Clone( - mojo::SharedBufferHandle::AccessMode::READ_ONLY); - } - - uint64_t GetBufferOffset() { - return device::SensorReadingSharedBuffer::GetOffset(sensor_type_); - } - - void set_reading(device::SensorReading reading) { reading_ = reading; } - - void SensorReadingChanged() { - if (!shared_buffer_handle_.is_valid()) - return; - - mojo::ScopedSharedBufferMapping shared_buffer = - shared_buffer_handle_->MapAtOffset( - device::mojom::SensorInitParams::kReadBufferSizeForTests, - GetBufferOffset()); - - device::SensorReadingSharedBuffer* buffer = - static_cast<device::SensorReadingSharedBuffer*>(shared_buffer.get()); - auto& seqlock = buffer->seqlock.value(); - seqlock.WriteBegin(); - buffer->reading = reading_; - seqlock.WriteEnd(); - - if (client_ && reading_notification_enabled_) - client_->SensorReadingChanged(); - } - - private: - device::mojom::SensorType sensor_type_; - bool reading_notification_enabled_ = true; - mojo::ScopedSharedBufferHandle shared_buffer_handle_; - device::mojom::SensorClientPtr client_; - device::SensorReading reading_; - - DISALLOW_COPY_AND_ASSIGN(FakeSensor); -}; - -class FakeSensorProvider : public device::mojom::SensorProvider { - public: - FakeSensorProvider() : binding_(this) {} - ~FakeSensorProvider() override = default; - - void Bind(const std::string& interface_name, - mojo::ScopedMessagePipeHandle handle, - const service_manager::BindSourceInfo& source_info) { - DCHECK(!binding_.is_bound()); - binding_.Bind(device::mojom::SensorProviderRequest(std::move(handle))); - } - - void set_accelerometer_is_available(bool accelerometer_is_available) { - accelerometer_is_available_ = accelerometer_is_available; - } - - void set_linear_acceleration_sensor_is_available( - bool linear_acceleration_sensor_is_available) { - linear_acceleration_sensor_is_available_ = - linear_acceleration_sensor_is_available; - } - - void set_gyroscope_is_available(bool gyroscope_is_available) { - gyroscope_is_available_ = gyroscope_is_available; - } - - // device::mojom::sensorProvider: - void GetSensor(device::mojom::SensorType type, - device::mojom::SensorRequest sensor_request, - GetSensorCallback callback) override { - std::unique_ptr<FakeSensor> sensor; - device::SensorReading reading; - reading.raw.timestamp = - (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF(); - - switch (type) { - case device::mojom::SensorType::ACCELEROMETER: - if (accelerometer_is_available_) { - sensor = base::MakeUnique<FakeSensor>( - device::mojom::SensorType::ACCELEROMETER); - reading.accel.x = 4; - reading.accel.y = 5; - reading.accel.z = 6; - } - break; - case device::mojom::SensorType::LINEAR_ACCELERATION: - if (linear_acceleration_sensor_is_available_) { - sensor = base::MakeUnique<FakeSensor>( - device::mojom::SensorType::LINEAR_ACCELERATION); - reading.accel.x = 1; - reading.accel.y = 2; - reading.accel.z = 3; - } - break; - case device::mojom::SensorType::GYROSCOPE: - if (gyroscope_is_available_) { - sensor = base::MakeUnique<FakeSensor>( - device::mojom::SensorType::GYROSCOPE); - reading.gyro.x = 7; - reading.gyro.y = 8; - reading.gyro.z = 9; - } - break; - default: - NOTIMPLEMENTED(); - } - - if (sensor) { - sensor->set_reading(reading); - auto init_params = device::mojom::SensorInitParams::New(); - init_params->memory = sensor->GetSharedBufferHandle(); - init_params->buffer_offset = sensor->GetBufferOffset(); - init_params->default_configuration = sensor->GetDefaultConfiguration(); - init_params->maximum_frequency = sensor->GetMaximumSupportedFrequency(); - init_params->minimum_frequency = sensor->GetMinimumSupportedFrequency(); - - std::move(callback).Run(std::move(init_params), sensor->GetClient()); - mojo::MakeStrongBinding(std::move(sensor), std::move(sensor_request)); - } else { - std::move(callback).Run(nullptr, nullptr); - } - } - - private: - mojo::Binding<device::mojom::SensorProvider> binding_; - bool accelerometer_is_available_ = true; - bool linear_acceleration_sensor_is_available_ = true; - bool gyroscope_is_available_ = true; - - DISALLOW_COPY_AND_ASSIGN(FakeSensorProvider); -}; - class DeviceSensorBrowserTest : public ContentBrowserTest { public: DeviceSensorBrowserTest() @@ -363,6 +219,8 @@ void SetUpOnMainThread() override { // Initialize the RunLoops now that the main thread has been created. + motion_started_runloop_.reset(new base::RunLoop()); + motion_stopped_runloop_.reset(new base::RunLoop()); orientation_started_runloop_.reset(new base::RunLoop()); orientation_stopped_runloop_.reset(new base::RunLoop()); orientation_absolute_started_runloop_.reset(new base::RunLoop()); @@ -370,17 +228,20 @@ #if defined(OS_ANDROID) // On Android, the DeviceSensorService lives on the UI thread. SetUpFetcher(); -#endif // defined(OS_ANDROID) - sensor_provider_ = base::MakeUnique<FakeSensorProvider>(); +#else + // On all other platforms, the DeviceSensorService lives on the IO thread. BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, base::Bind(&DeviceSensorBrowserTest::SetUpOnIOThread, base::Unretained(this))); io_loop_finished_event_.Wait(); +#endif } void SetUpFetcher() { fetcher_ = new FakeDataFetcher(); + fetcher_->SetMotionStartedCallback(motion_started_runloop_->QuitClosure()); + fetcher_->SetMotionStoppedCallback(motion_stopped_runloop_->QuitClosure()); fetcher_->SetOrientationStartedCallback( orientation_started_runloop_->QuitClosure()); fetcher_->SetOrientationStoppedCallback( @@ -394,18 +255,7 @@ } void SetUpOnIOThread() { -#if !defined(OS_ANDROID) - // On non-Android platforms, the DeviceSensorService lives on the IO thread. SetUpFetcher(); -#endif // !defined(OS_ANDROID) - // Because Device Service also runs in this process(browser process), here - // we can directly set our binder to intercept interface requests against - // it. - service_manager::ServiceContext::SetGlobalBinderForTesting( - device::mojom::kServiceName, device::mojom::SensorProvider::Name_, - base::Bind(&FakeSensorProvider::Bind, - base::Unretained(sensor_provider_.get()))); - io_loop_finished_event_.Signal(); } @@ -427,10 +277,11 @@ } FakeDataFetcher* fetcher_; - std::unique_ptr<FakeSensorProvider> sensor_provider_; // NOTE: These can only be initialized once the main thread has been created // and so must be pointers instead of plain objects. + std::unique_ptr<base::RunLoop> motion_started_runloop_; + std::unique_ptr<base::RunLoop> motion_stopped_runloop_; std::unique_ptr<base::RunLoop> orientation_started_runloop_; std::unique_ptr<base::RunLoop> orientation_stopped_runloop_; std::unique_ptr<base::RunLoop> orientation_absolute_started_runloop_; @@ -473,6 +324,8 @@ NavigateToURLBlockUntilNavigationsComplete(shell(), test_url, 2); EXPECT_EQ("pass", shell()->web_contents()->GetLastCommittedURL().ref()); + motion_started_runloop_->Run(); + motion_stopped_runloop_->Run(); } IN_PROC_BROWSER_TEST_F(DeviceSensorBrowserTest, OrientationNullTest) { @@ -507,27 +360,13 @@ // The test page registers an event handler for motion events and // expects to get an event with null values, because no sensor data can be // provided. - sensor_provider_->set_accelerometer_is_available(false); - sensor_provider_->set_linear_acceleration_sensor_is_available(false); - sensor_provider_->set_gyroscope_is_available(false); + fetcher_->SetSensorDataAvailable(false); GURL test_url = GetTestUrl("device_sensors", "device_motion_null_test.html"); NavigateToURLBlockUntilNavigationsComplete(shell(), test_url, 2); EXPECT_EQ("pass", shell()->web_contents()->GetLastCommittedURL().ref()); -} - -IN_PROC_BROWSER_TEST_F(DeviceSensorBrowserTest, - MotionOnlySomeSensorsAreAvailableTest) { - // The test page registers an event handler for motion events and - // expects to get an event with only the gyroscope and linear acceleration - // sensor values, because no accelerometer values can be provided. - sensor_provider_->set_accelerometer_is_available(false); - GURL test_url = - GetTestUrl("device_sensors", - "device_motion_only_some_sensors_are_available_test.html"); - NavigateToURLBlockUntilNavigationsComplete(shell(), test_url, 2); - - EXPECT_EQ("pass", shell()->web_contents()->GetLastCommittedURL().ref()); + motion_started_runloop_->Run(); + motion_stopped_runloop_->Run(); } IN_PROC_BROWSER_TEST_F(DeviceSensorBrowserTest, NullTestWithAlert) { @@ -537,9 +376,6 @@ // window after the alert is dismissed and the callbacks are invoked which // eventually navigate to #pass. fetcher_->SetSensorDataAvailable(false); - sensor_provider_->set_accelerometer_is_available(false); - sensor_provider_->set_linear_acceleration_sensor_is_available(false); - sensor_provider_->set_gyroscope_is_available(false); TestNavigationObserver same_tab_observer(shell()->web_contents(), 2); GURL test_url = @@ -550,6 +386,8 @@ // delay, crbug.com/360044. WaitForAlertDialogAndQuitAfterDelay(base::TimeDelta::FromMilliseconds(500)); + motion_started_runloop_->Run(); + motion_stopped_runloop_->Run(); orientation_started_runloop_->Run(); orientation_stopped_runloop_->Run(); same_tab_observer.Wait();
diff --git a/content/browser/devtools/devtools_http_handler.cc b/content/browser/devtools/devtools_http_handler.cc index 1414170..02b1abe 100644 --- a/content/browser/devtools/devtools_http_handler.cc +++ b/content/browser/devtools/devtools_http_handler.cc
@@ -231,6 +231,7 @@ "\nDevTools listening on ws://%s%s\n", ip_address->ToString().c_str(), browser_guid.c_str()); fprintf(stderr, "%s", message.c_str()); + fflush(stderr); // Write this port to a well-known file in the profile directory // so Telemetry can pick it up.
diff --git a/content/browser/devtools/protocol/devtools_protocol_browsertest.cc b/content/browser/devtools/protocol/devtools_protocol_browsertest.cc index 4d89cb2b..40236d1 100644 --- a/content/browser/devtools/protocol/devtools_protocol_browsertest.cc +++ b/content/browser/devtools/protocol/devtools_protocol_browsertest.cc
@@ -33,6 +33,7 @@ #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/render_widget_host_view.h" +#include "content/public/browser/security_style_explanations.h" #include "content/public/browser/ssl_status.h" #include "content/public/browser/web_contents.h" #include "content/public/common/content_switches.h" @@ -75,6 +76,34 @@ const char kMethodParam[] = "method"; const char kParamsParam[] = "params"; +// If |params| contains an explanation with a non-empty certificate list, +// returns true and points |certificate| to the certificate list of the first +// explanation that contains a nonempty certificate list. Otherwise returns +// false. |params| is expected to be the parameters of a securityStateChanged +// notification. +bool GetCertificateFromNotificationParams(base::DictionaryValue* params, + const base::ListValue** certificate) { + const base::ListValue* explanations; + if (!params->GetList("explanations", &explanations)) { + return false; + } + for (const auto& explanation : *explanations) { + const base::DictionaryValue* explanation_dict; + if (explanation.GetAsDictionary(&explanation_dict) && + explanation_dict->GetList("certificate", certificate) && + (*certificate)->GetSize() > 0u) { + return true; + } + } + return false; +} + +bool SecurityStateChangedHasCertificateExplanation( + base::DictionaryValue* params) { + const base::ListValue* unused; + return GetCertificateFromNotificationParams(params, &unused); +} + class TestJavaScriptDialogManager : public JavaScriptDialogManager, public WebContentsDelegate { public: @@ -142,6 +171,8 @@ public DevToolsAgentHostClient, public WebContentsDelegate { public: + typedef base::Callback<bool(base::DictionaryValue*)> NotificationMatcher; + DevToolsProtocolTest() : last_sent_id_(0), waiting_for_command_result_id_(0), @@ -149,15 +180,11 @@ agent_host_can_close_(false) {} void SetUpOnMainThread() override { - ok_cert_ = - net::ImportCertFromFile(net::GetTestCertsDirectory(), "ok_cert.pem"); - expired_cert_ = net::ImportCertFromFile(net::GetTestCertsDirectory(), - "expired_cert.pem"); host_resolver()->AddRule("*", "127.0.0.1"); } protected: - // WebContentsDelegate method: + // WebContentsDelegate methods: bool DidAddMessageToConsole(WebContents* source, int32_t level, const base::string16& message, @@ -167,6 +194,17 @@ return true; } + blink::WebSecurityStyle GetSecurityStyle( + content::WebContents* web_contents, + content::SecurityStyleExplanations* security_style_explanations) + override { + security_style_explanations->secure_explanations.push_back( + SecurityStyleExplanation( + "an explanation", "an explanation description", cert_, + blink::WebMixedContentContextType::kNotMixedContent)); + return blink::kWebSecurityStyleNeutral; + } + base::DictionaryValue* SendCommand( const std::string& method, std::unique_ptr<base::DictionaryValue> params) { @@ -266,6 +304,28 @@ return std::move(waiting_for_notification_params_); } + // Waits for a notification whose params, when passed to |matcher|, returns + // true. Existing notifications are allowed. + std::unique_ptr<base::DictionaryValue> WaitForMatchingNotification( + const std::string& notification, + const NotificationMatcher& matcher) { + for (size_t i = 0; i < notifications_.size(); i++) { + if (notifications_[i] == notification && + matcher.Run(notification_params_[i].get())) { + std::unique_ptr<base::DictionaryValue> result = + std::move(notification_params_[i]); + notifications_.erase(notifications_.begin() + i); + notification_params_.erase(notification_params_.begin() + i); + return result; + } + } + + waiting_for_notification_ = notification; + waiting_for_notification_matcher_ = matcher; + RunMessageLoop(); + return std::move(waiting_for_notification_params_); + } + void ClearNotifications() { notifications_.clear(); notification_params_.clear(); @@ -347,14 +407,13 @@ return urls; } - const scoped_refptr<net::X509Certificate>& ok_cert() { return ok_cert_; } - - const scoped_refptr<net::X509Certificate>& expired_cert() { - return expired_cert_; - } - void set_agent_host_can_close() { agent_host_can_close_ = true; } + void SetSecurityExplanationCert( + const scoped_refptr<net::X509Certificate>& cert) { + cert_ = cert; + } + std::unique_ptr<base::DictionaryValue> result_; scoped_refptr<DevToolsAgentHost> agent_host_; int last_sent_id_; @@ -391,8 +450,12 @@ notification_params_.push_back( base::WrapUnique(new base::DictionaryValue())); } - if (waiting_for_notification_ == notification) { + if (waiting_for_notification_ == notification && + (waiting_for_notification_matcher_.is_null() || + waiting_for_notification_matcher_.Run( + notification_params_[notification_params_.size() - 1].get()))) { waiting_for_notification_ = std::string(); + waiting_for_notification_matcher_ = NotificationMatcher(); waiting_for_notification_params_ = base::WrapUnique( notification_params_[notification_params_.size() - 1]->DeepCopy()); base::RunLoop::QuitCurrentDeprecated(); @@ -406,12 +469,12 @@ } std::string waiting_for_notification_; + NotificationMatcher waiting_for_notification_matcher_; std::unique_ptr<base::DictionaryValue> waiting_for_notification_params_; int waiting_for_command_result_id_; bool in_dispatch_; - scoped_refptr<net::X509Certificate> ok_cert_; - scoped_refptr<net::X509Certificate> expired_cert_; bool agent_host_can_close_; + scoped_refptr<net::X509Certificate> cert_; }; class TestInterstitialDelegate : public InterstitialPageDelegate { @@ -1980,4 +2043,63 @@ EXPECT_TRUE(result); } +// Tests that when a security explanation contains a certificate, it is properly +// serialized into the protocol message. +IN_PROC_BROWSER_TEST_F(DevToolsProtocolTest, CertificateExplanations) { + net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS); + https_server.AddDefaultHandlers( + base::FilePath(FILE_PATH_LITERAL("content/test/data"))); + ASSERT_TRUE(https_server.Start()); + + shell()->LoadURL(GURL("about:blank")); + WaitForLoadStop(shell()->web_contents()); + + // Navigate to a page on the server in order to retrieve its certificate + // chain. + NavigateToURLBlockUntilNavigationsComplete( + shell(), https_server.GetURL("/title1.html"), 1); + WebContentsImpl* wc = static_cast<WebContentsImpl*>(shell()->web_contents()); + NavigationEntry* entry = wc->GetController().GetLastCommittedEntry(); + ASSERT_TRUE(entry); + scoped_refptr<net::X509Certificate> cert = entry->GetSSL().certificate; + + // Provide |cert| as the certificate on the security style explanations. When + // the security handler is enabled, DidChangeVisibleSecurityState() is called + // and the explanations with |cert| are sent to DevTools. + SetSecurityExplanationCert(cert); + Attach(); + SendCommand("Security.enable", nullptr, false); + std::unique_ptr<base::DictionaryValue> params(new base::DictionaryValue()); + params = WaitForMatchingNotification( + "Security.securityStateChanged", + base::Bind(&SecurityStateChangedHasCertificateExplanation)); + + // There should be one explanation containing the server's certificate chain. + net::SHA256HashValue cert_chain_fingerprint = + net::X509Certificate::CalculateChainFingerprint256( + cert->os_cert_handle(), cert->GetIntermediateCertificates()); + + // Read the certificate out of the first explanation. + const base::ListValue* certificate; + ASSERT_TRUE(GetCertificateFromNotificationParams(params.get(), &certificate)); + std::vector<std::string> der_certs; + for (const auto& cert : *certificate) { + std::string decoded; + ASSERT_TRUE(base::Base64Decode(cert.GetString(), &decoded)); + der_certs.push_back(decoded); + } + std::vector<base::StringPiece> cert_string_piece; + for (const auto& str : der_certs) + cert_string_piece.push_back(str); + + // Check that the explanation certificate is correct. + scoped_refptr<net::X509Certificate> explanation_cert = + net::X509Certificate::CreateFromDERCertChain(cert_string_piece); + ASSERT_TRUE(explanation_cert); + EXPECT_EQ(cert_chain_fingerprint, + net::X509Certificate::CalculateChainFingerprint256( + explanation_cert->os_cert_handle(), + explanation_cert->GetIntermediateCertificates())); +} + } // namespace content
diff --git a/content/browser/devtools/protocol/input_handler.cc b/content/browser/devtools/protocol/input_handler.cc index dc2e8f71..a5524e4 100644 --- a/content/browser/devtools/protocol/input_handler.cc +++ b/content/browser/devtools/protocol/input_handler.cc
@@ -134,6 +134,8 @@ return blink::WebInputEvent::kMouseUp; if (type == Input::DispatchMouseEvent::TypeEnum::MouseMoved) return blink::WebInputEvent::kMouseMove; + if (type == Input::DispatchMouseEvent::TypeEnum::MouseWheel) + return blink::WebInputEvent::kMouseWheel; return blink::WebInputEvent::kUndefined; } @@ -236,10 +238,14 @@ !pending_key_callbacks_.empty()) { pending_key_callbacks_.front()->sendSuccess(); pending_key_callbacks_.pop_front(); - } else if (blink::WebInputEvent::IsMouseEventType(event.GetType()) && - !pending_mouse_callbacks_.empty()) { + return; + } + if ((blink::WebInputEvent::IsMouseEventType(event.GetType()) || + event.GetType() == blink::WebInputEvent::kMouseWheel) && + !pending_mouse_callbacks_.empty()) { pending_mouse_callbacks_.front()->sendSuccess(); pending_mouse_callbacks_.pop_front(); + return; } } @@ -353,49 +359,76 @@ } void InputHandler::DispatchMouseEvent( - const std::string& type, + const std::string& event_type, double x, double y, - Maybe<int> modifiers, - Maybe<double> timestamp, - Maybe<std::string> button, + Maybe<int> maybe_modifiers, + Maybe<double> maybe_timestamp, + Maybe<std::string> maybe_button, Maybe<int> click_count, + Maybe<double> delta_x, + Maybe<double> delta_y, std::unique_ptr<DispatchMouseEventCallback> callback) { - blink::WebInputEvent::Type event_type = GetMouseEventType(type); - if (event_type == blink::WebInputEvent::kUndefined) { + blink::WebInputEvent::Type type = GetMouseEventType(event_type); + if (type == blink::WebInputEvent::kUndefined) { callback->sendFailure(Response::InvalidParams( - base::StringPrintf("Unexpected event type '%s'", type.c_str()))); + base::StringPrintf("Unexpected event type '%s'", event_type.c_str()))); return; } - blink::WebPointerProperties::Button event_button = + + blink::WebPointerProperties::Button button = blink::WebPointerProperties::Button::kNoButton; int button_modifiers = 0; - if (!GetMouseEventButton(button.fromMaybe(""), &event_button, + if (!GetMouseEventButton(maybe_button.fromMaybe(""), &button, &button_modifiers)) { callback->sendFailure(Response::InvalidParams("Invalid mouse button")); return; } - blink::WebMouseEvent event( - event_type, - GetEventModifiers(modifiers.fromMaybe(blink::WebInputEvent::kNoModifiers), - false, false) | - button_modifiers, - GetEventTimestamp(std::move(timestamp))); + int modifiers = GetEventModifiers( + maybe_modifiers.fromMaybe(blink::WebInputEvent::kNoModifiers), false, + false); + modifiers |= button_modifiers; + double timestamp = GetEventTimestamp(std::move(maybe_timestamp)); - event.button = event_button; - event.SetPositionInWidget(x * page_scale_factor_, y * page_scale_factor_); - event.SetPositionInScreen(x * page_scale_factor_, y * page_scale_factor_); - event.click_count = click_count.fromMaybe(0); - event.pointer_type = blink::WebPointerProperties::PointerType::kMouse; + std::unique_ptr<blink::WebMouseEvent, ui::WebInputEventDeleter> mouse_event; + blink::WebMouseWheelEvent* wheel_event = nullptr; - if (!host_ || !host_->GetRenderWidgetHost()) + if (type == blink::WebInputEvent::kMouseWheel) { + wheel_event = new blink::WebMouseWheelEvent(type, modifiers, timestamp); + mouse_event.reset(wheel_event); + if (!delta_x.isJust() || !delta_y.isJust()) { + callback->sendFailure(Response::InvalidParams( + "'deltaX' and 'deltaY' are expected for mouseWheel event")); + return; + } + wheel_event->delta_x = static_cast<float>(-delta_x.fromJust()); + wheel_event->delta_y = static_cast<float>(-delta_y.fromJust()); + wheel_event->dispatch_type = blink::WebInputEvent::kBlocking; + } else { + mouse_event.reset(new blink::WebMouseEvent(type, modifiers, timestamp)); + } + + mouse_event->button = button; + mouse_event->SetPositionInWidget(x * page_scale_factor_, + y * page_scale_factor_); + mouse_event->SetPositionInScreen(x * page_scale_factor_, + y * page_scale_factor_); + mouse_event->click_count = click_count.fromMaybe(0); + mouse_event->pointer_type = blink::WebPointerProperties::PointerType::kMouse; + + if (!host_ || !host_->GetRenderWidgetHost()) { callback->sendFailure(Response::InternalError()); + return; + } host_->GetRenderWidgetHost()->Focus(); input_queued_ = false; pending_mouse_callbacks_.push_back(std::move(callback)); - host_->GetRenderWidgetHost()->ForwardMouseEvent(event); + if (wheel_event) + host_->GetRenderWidgetHost()->ForwardWheelEvent(*wheel_event); + else + host_->GetRenderWidgetHost()->ForwardMouseEvent(*mouse_event); if (!input_queued_) { pending_mouse_callbacks_.back()->sendSuccess(); pending_mouse_callbacks_.pop_back();
diff --git a/content/browser/devtools/protocol/input_handler.h b/content/browser/devtools/protocol/input_handler.h index ec1e10d..5133ed2 100644 --- a/content/browser/devtools/protocol/input_handler.h +++ b/content/browser/devtools/protocol/input_handler.h
@@ -63,6 +63,8 @@ Maybe<double> timestamp, Maybe<std::string> button, Maybe<int> click_count, + Maybe<double> delta_x, + Maybe<double> delta_y, std::unique_ptr<DispatchMouseEventCallback> callback) override; Response EmulateTouchFromMouseEvent(const std::string& type,
diff --git a/content/browser/devtools/protocol/network_handler.cc b/content/browser/devtools/protocol/network_handler.cc index 467d7e1..b71bb92 100644 --- a/content/browser/devtools/protocol/network_handler.cc +++ b/content/browser/devtools/protocol/network_handler.cc
@@ -54,23 +54,11 @@ using GetCookiesCallback = Network::Backend::GetCookiesCallback; using GetAllCookiesCallback = Network::Backend::GetAllCookiesCallback; using SetCookieCallback = Network::Backend::SetCookieCallback; +using SetCookiesCallback = Network::Backend::SetCookiesCallback; using DeleteCookieCallback = Network::Backend::DeleteCookieCallback; using ClearBrowserCookiesCallback = Network::Backend::ClearBrowserCookiesCallback; -net::URLRequestContext* GetRequestContextOnIO( - ResourceContext* resource_context, - net::URLRequestContextGetter* context_getter, - const GURL& url) { - DCHECK_CURRENTLY_ON(BrowserThread::IO); - net::URLRequestContext* context = - GetContentClient()->browser()->OverrideRequestContextForURL( - url, resource_context); - if (!context) - context = context_getter->GetURLRequestContext(); - return context; -} - class CookieRetriever : public base::RefCountedThreadSafe<CookieRetriever> { public: CookieRetriever(std::unique_ptr<GetCookiesCallback> callback) @@ -82,7 +70,6 @@ all_callback_(std::move(callback)) {} void RetrieveCookiesOnIO( - ResourceContext* resource_context, net::URLRequestContextGetter* context_getter, const std::vector<GURL>& urls) { DCHECK_CURRENTLY_ON(BrowserThread::IO); @@ -95,14 +82,13 @@ for (const GURL& url : urls) { net::URLRequestContext* request_context = - GetRequestContextOnIO(resource_context, context_getter, url); + context_getter->GetURLRequestContext(); request_context->cookie_store()->GetAllCookiesForURLAsync(url, base::Bind(&CookieRetriever::GotCookies, this)); } } void RetrieveAllCookiesOnIO( - ResourceContext* resource_context, net::URLRequestContextGetter* context_getter) { DCHECK_CURRENTLY_ON(BrowserThread::IO); callback_count_ = 1; @@ -148,28 +134,28 @@ ProtocolCookieArray::create(); for (const net::CanonicalCookie& cookie : cookie_list) { - std::unique_ptr<Network::Cookie> devtools_cookie = + std::unique_ptr<Network::Cookie> devtools_cookie = Network::Cookie::Create() - .SetName(cookie.Name()) - .SetValue(cookie.Value()) - .SetDomain(cookie.Domain()) - .SetPath(cookie.Path()) - .SetExpires(cookie.ExpiryDate().ToDoubleT() * 1000) - .SetSize(cookie.Name().length() + cookie.Value().length()) - .SetHttpOnly(cookie.IsHttpOnly()) - .SetSecure(cookie.IsSecure()) - .SetSession(!cookie.IsPersistent()) - .Build(); + .SetName(cookie.Name()) + .SetValue(cookie.Value()) + .SetDomain(cookie.Domain()) + .SetPath(cookie.Path()) + .SetExpires(cookie.ExpiryDate().ToDoubleT()) + .SetSize(cookie.Name().length() + cookie.Value().length()) + .SetHttpOnly(cookie.IsHttpOnly()) + .SetSecure(cookie.IsSecure()) + .SetSession(!cookie.IsPersistent()) + .Build(); - switch (cookie.SameSite()) { - case net::CookieSameSite::STRICT_MODE: - devtools_cookie->SetSameSite(Network::CookieSameSiteEnum::Strict); - break; - case net::CookieSameSite::LAX_MODE: - devtools_cookie->SetSameSite(Network::CookieSameSiteEnum::Lax); - break; - case net::CookieSameSite::NO_RESTRICTION: - break; + switch (cookie.SameSite()) { + case net::CookieSameSite::STRICT_MODE: + devtools_cookie->SetSameSite(Network::CookieSameSiteEnum::Strict); + break; + case net::CookieSameSite::LAX_MODE: + devtools_cookie->SetSameSite(Network::CookieSameSiteEnum::Lax); + break; + case net::CookieSameSite::NO_RESTRICTION: + break; } cookies->addItem(std::move(devtools_cookie)); @@ -200,8 +186,7 @@ base::Passed(std::move(callback)))); } -void ClearCookiesOnIO(ResourceContext* resource_context, - net::URLRequestContextGetter* context_getter, +void ClearCookiesOnIO(net::URLRequestContextGetter* context_getter, std::unique_ptr<ClearBrowserCookiesCallback> callback) { DCHECK_CURRENTLY_ON(BrowserThread::IO); net::URLRequestContext* request_context = @@ -220,14 +205,13 @@ } void DeleteCookieOnIO( - ResourceContext* resource_context, net::URLRequestContextGetter* context_getter, const GURL& url, const std::string& cookie_name, std::unique_ptr<DeleteCookieCallback> callback) { DCHECK_CURRENTLY_ON(BrowserThread::IO); net::URLRequestContext* request_context = - GetRequestContextOnIO(resource_context, context_getter, url); + context_getter->GetURLRequestContext(); request_context->cookie_store()->DeleteCookieAsync( url, cookie_name, base::Bind(&DeletedCookieOnIO, base::Passed(std::move(callback)))); @@ -243,33 +227,74 @@ success)); } -void SetCookieOnIO( - ResourceContext* resource_context, - net::URLRequestContextGetter* context_getter, - const GURL& url, - const std::string& name, - const std::string& value, - const std::string& domain, - const std::string& path, - bool secure, - bool http_only, - net::CookieSameSite same_site, - base::Time expires, - std::unique_ptr<SetCookieCallback> callback) { +void SetCookieOnIO(net::URLRequestContextGetter* context_getter, + const std::string& name, + const std::string& value, + const std::string& url_spec, + const std::string& domain, + const std::string& path, + bool secure, + bool http_only, + const std::string& same_site, + double expires, + base::OnceCallback<void(bool)> callback) { DCHECK_CURRENTLY_ON(BrowserThread::IO); net::URLRequestContext* request_context = - GetRequestContextOnIO(resource_context, context_getter, url); + context_getter->GetURLRequestContext(); + + GURL url; + if (!url_spec.empty()) { + url = GURL(url_spec); + secure = secure || url.SchemeIsCryptographic(); + } else { + url = GURL((secure ? "https://" : "http://") + domain + path); + } + + base::Time expiration_date; + if (expires >= 0) { + expiration_date = + expires ? base::Time::FromDoubleT(expires) : base::Time::UnixEpoch(); + } + + net::CookieSameSite css = net::CookieSameSite::NO_RESTRICTION; + if (same_site == Network::CookieSameSiteEnum::Lax) + css = net::CookieSameSite::LAX_MODE; + if (same_site == Network::CookieSameSiteEnum::Strict) + css = net::CookieSameSite::STRICT_MODE; request_context->cookie_store()->SetCookieWithDetailsAsync( - url, name, value, domain, path, - base::Time(), - expires, - base::Time(), - secure, - http_only, - same_site, - net::COOKIE_PRIORITY_DEFAULT, - base::Bind(&CookieSetOnIO, base::Passed(std::move(callback)))); + url, name, value, domain, path, base::Time(), expiration_date, + base::Time(), secure, http_only, css, net::COOKIE_PRIORITY_DEFAULT, + std::move(callback)); +} + +void CookiesSetOnIO(std::unique_ptr<SetCookiesCallback> callback, + bool success) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, + base::Bind(&SetCookiesCallback::sendSuccess, + base::Passed(std::move(callback)))); +} + +void SetCookiesOnIO( + net::URLRequestContextGetter* context_getter, + std::unique_ptr<protocol::Array<Network::CookieParam>> cookies, + base::OnceCallback<void(bool)> callback) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + + for (size_t i = 0; i < cookies->length(); i++) { + Network::CookieParam* cookie = cookies->get(i); + + base::OnceCallback<void(bool)> once_callback; + if (i == cookies->length() - 1) + once_callback = std::move(callback); + + SetCookieOnIO(context_getter, cookie->GetName(), cookie->GetValue(), + cookie->GetUrl(""), cookie->GetDomain(""), + cookie->GetPath(""), cookie->GetSecure(false), + cookie->GetHttpOnly(false), cookie->GetSameSite(""), + cookie->GetExpires(-1), std::move(once_callback)); + } } std::vector<GURL> ComputeCookieURLs(RenderFrameHostImpl* frame_host, @@ -568,9 +593,6 @@ BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, base::Bind(&ClearCookiesOnIO, - base::Unretained(host_->GetSiteInstance() - ->GetBrowserContext() - ->GetResourceContext()), base::Unretained(host_->GetProcess() ->GetStoragePartition() ->GetURLRequestContext()), @@ -592,9 +614,6 @@ BrowserThread::IO, FROM_HERE, base::Bind(&CookieRetriever::RetrieveCookiesOnIO, retriever, - base::Unretained(host_->GetSiteInstance() - ->GetBrowserContext() - ->GetResourceContext()), base::Unretained(host_->GetProcess() ->GetStoragePartition() ->GetURLRequestContext()), @@ -615,54 +634,57 @@ BrowserThread::IO, FROM_HERE, base::Bind(&CookieRetriever::RetrieveAllCookiesOnIO, retriever, - base::Unretained(host_->GetSiteInstance() - ->GetBrowserContext() - ->GetResourceContext()), base::Unretained(host_->GetProcess() ->GetStoragePartition() ->GetURLRequestContext()))); } -void NetworkHandler::SetCookie( - const std::string& url, - const std::string& name, - const std::string& value, - Maybe<std::string> domain, - Maybe<std::string> path, - Maybe<bool> secure, - Maybe<bool> http_only, - Maybe<std::string> same_site, - Maybe<double> expires, - std::unique_ptr<SetCookieCallback> callback) { +void NetworkHandler::SetCookie(const std::string& name, + const std::string& value, + Maybe<std::string> url, + Maybe<std::string> domain, + Maybe<std::string> path, + Maybe<bool> secure, + Maybe<bool> http_only, + Maybe<std::string> same_site, + Maybe<double> expires, + std::unique_ptr<SetCookieCallback> callback) { if (!host_) { callback->sendFailure(Response::InternalError()); return; } - net::CookieSameSite same_site_enum = net::CookieSameSite::DEFAULT_MODE; - if (same_site.isJust()) { - if (same_site.fromJust() == Network::CookieSameSiteEnum::Lax) - same_site_enum = net::CookieSameSite::LAX_MODE; - else if (same_site.fromJust() == Network::CookieSameSiteEnum::Strict) - same_site_enum = net::CookieSameSite::STRICT_MODE; + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + base::Bind( + &SetCookieOnIO, + base::Unretained(host_->GetProcess() + ->GetStoragePartition() + ->GetURLRequestContext()), + name, value, url.fromMaybe(""), domain.fromMaybe(""), + path.fromMaybe(""), secure.fromMaybe(false), + http_only.fromMaybe(false), same_site.fromMaybe(""), + expires.fromMaybe(-1), + base::Bind(&CookieSetOnIO, base::Passed(std::move(callback))))); +} + +void NetworkHandler::SetCookies( + std::unique_ptr<protocol::Array<Network::CookieParam>> cookies, + std::unique_ptr<SetCookiesCallback> callback) { + if (!host_) { + callback->sendFailure(Response::InternalError()); + return; } - base::Time expiration_date; - if (expires.isJust()) { - expiration_date = expires.fromJust() == 0 - ? base::Time::UnixEpoch() - : base::Time::FromDoubleT(expires.fromJust()); - } - - BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind( - &SetCookieOnIO, - base::Unretained(host_->GetSiteInstance()->GetBrowserContext()-> - GetResourceContext()), - base::Unretained(host_->GetProcess()->GetStoragePartition()-> - GetURLRequestContext()), - GURL(url), name, value, domain.fromMaybe(""), path.fromMaybe(""), - secure.fromMaybe(false), http_only.fromMaybe(false), same_site_enum, - expiration_date, base::Passed(std::move(callback)))); + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + base::Bind( + &SetCookiesOnIO, + base::Unretained(host_->GetProcess() + ->GetStoragePartition() + ->GetURLRequestContext()), + base::Passed(std::move(cookies)), + base::Bind(&CookiesSetOnIO, base::Passed(std::move(callback))))); } void NetworkHandler::DeleteCookie( @@ -675,8 +697,6 @@ } BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind( &DeleteCookieOnIO, - base::Unretained(host_->GetSiteInstance()->GetBrowserContext()-> - GetResourceContext()), base::Unretained(host_->GetProcess()->GetStoragePartition()-> GetURLRequestContext()), GURL(url),
diff --git a/content/browser/devtools/protocol/network_handler.h b/content/browser/devtools/protocol/network_handler.h index e96b7cb..929d962 100644 --- a/content/browser/devtools/protocol/network_handler.h +++ b/content/browser/devtools/protocol/network_handler.h
@@ -60,17 +60,19 @@ void DeleteCookie(const std::string& cookie_name, const std::string& url, std::unique_ptr<DeleteCookieCallback> callback) override; - void SetCookie( - const std::string& url, - const std::string& name, - const std::string& value, - Maybe<std::string> domain, - Maybe<std::string> path, - Maybe<bool> secure, - Maybe<bool> http_only, - Maybe<std::string> same_site, - Maybe<double> expires, - std::unique_ptr<SetCookieCallback> callback) override; + void SetCookie(const std::string& name, + const std::string& value, + Maybe<std::string> url, + Maybe<std::string> domain, + Maybe<std::string> path, + Maybe<bool> secure, + Maybe<bool> http_only, + Maybe<std::string> same_site, + Maybe<double> expires, + std::unique_ptr<SetCookieCallback> callback) override; + void SetCookies( + std::unique_ptr<protocol::Array<Network::CookieParam>> cookies, + std::unique_ptr<SetCookiesCallback> callback) override; Response SetUserAgentOverride(const std::string& user_agent) override; Response CanEmulateNetworkConditions(bool* result) override;
diff --git a/content/browser/devtools/protocol_config.json b/content/browser/devtools/protocol_config.json index 057470ce..cbc057a 100644 --- a/content/browser/devtools/protocol_config.json +++ b/content/browser/devtools/protocol_config.json
@@ -42,11 +42,11 @@ }, { "domain": "Network", - "include": ["enable", "disable", "clearBrowserCache", "clearBrowserCookies", "getCookies", "getAllCookies", "deleteCookie", "setCookie", "setUserAgentOverride", "canEmulateNetworkConditions", "setRequestInterceptionEnabled", "continueInterceptedRequest"], - "include_types": ["CookieSameSite", "Cookie", "Response", "Headers", "Request", "ResourceTiming", "SecurityDetails", "SignedCertificateTimestamp", "Initiator", "ResourcePriority", "RequestWillBeSentNotification", "ResponseReceivedNotification", "LoadingFinishedNotification", "LoadingFailedNotification", "RequestWillBeSentNotification", + "include": ["enable", "disable", "clearBrowserCache", "clearBrowserCookies", "getCookies", "getAllCookies", "deleteCookie", "setCookie", "setCookies", "setUserAgentOverride", "canEmulateNetworkConditions", "setRequestInterceptionEnabled", "continueInterceptedRequest"], + "include_types": ["CookieSameSite", "Cookie", "CookieParam", "Response", "Headers", "Request", "ResourceTiming", "SecurityDetails", "SignedCertificateTimestamp", "Initiator", "ResourcePriority", "RequestWillBeSentNotification", "ResponseReceivedNotification", "LoadingFinishedNotification", "LoadingFailedNotification", "RequestWillBeSentNotification", "ErrorReason", "RequestInterceptedNotification", "AuthChallenge", "AuthChallengeResponse"], "include_events": ["requestWillBeSent", "responseReceived", "loadingFinished", "loadingFailed", "requestIntercepted"], - "async": ["clearBrowserCookies", "getCookies", "getAllCookies", "deleteCookie", "setCookie", "continueInterceptedRequest"] + "async": ["clearBrowserCookies", "getCookies", "getAllCookies", "deleteCookie", "setCookie", "setCookies", "continueInterceptedRequest"] }, { "domain": "Page",
diff --git a/content/browser/dom_storage/dom_storage_context_wrapper.h b/content/browser/dom_storage/dom_storage_context_wrapper.h index bab7dbe0..ef74dc30 100644 --- a/content/browser/dom_storage/dom_storage_context_wrapper.h +++ b/content/browser/dom_storage/dom_storage_context_wrapper.h
@@ -37,10 +37,10 @@ // This is owned by Storage Partition and encapsulates all its dom storage // state. -class CONTENT_EXPORT DOMStorageContextWrapper : - NON_EXPORTED_BASE(public DOMStorageContext), - public base::RefCountedThreadSafe<DOMStorageContextWrapper>, - public base::MemoryCoordinatorClient { +class CONTENT_EXPORT DOMStorageContextWrapper + : public DOMStorageContext, + public base::RefCountedThreadSafe<DOMStorageContextWrapper>, + public base::MemoryCoordinatorClient { public: // If |data_path| is empty, nothing will be saved to disk. DOMStorageContextWrapper(
diff --git a/content/browser/dom_storage/session_storage_namespace_impl.h b/content/browser/dom_storage/session_storage_namespace_impl.h index 4823efb..f9afadb 100644 --- a/content/browser/dom_storage/session_storage_namespace_impl.h +++ b/content/browser/dom_storage/session_storage_namespace_impl.h
@@ -17,8 +17,7 @@ class DOMStorageContextWrapper; class DOMStorageSession; -class SessionStorageNamespaceImpl - : NON_EXPORTED_BASE(public SessionStorageNamespace) { +class SessionStorageNamespaceImpl : public SessionStorageNamespace { public: // Constructs a |SessionStorageNamespaceImpl| and allocates new IDs for it. //
diff --git a/content/browser/download/download_file.h b/content/browser/download/download_file.h index c25b4d7..8f6ae96 100644 --- a/content/browser/download/download_file.h +++ b/content/browser/download/download_file.h
@@ -69,6 +69,10 @@ int64_t offset, int64_t length) = 0; + // Called when the response for the stream starting at |offset| is completed, + virtual void OnResponseCompleted(int64_t offset, + DownloadInterruptReason status) = 0; + // Rename the download file to |full_path|. If that file exists // |full_path| will be uniquified by suffixing " (<number>)" to the // file name before the extension.
diff --git a/content/browser/download/download_file_impl.cc b/content/browser/download/download_file_impl.cc index 4b52dc7..1ab6ba7 100644 --- a/content/browser/download/download_file_impl.cc +++ b/content/browser/download/download_file_impl.cc
@@ -67,7 +67,9 @@ bytes_written_(0), finished_(false), index_(0u), - stream_reader_(std::move(stream_reader)) {} + stream_reader_(std::move(stream_reader)), + completion_status_(DOWNLOAD_INTERRUPT_REASON_NONE), + is_response_completed_(false) {} DownloadFileImpl::SourceStream::SourceStream( int64_t offset, @@ -78,6 +80,8 @@ bytes_written_(0), finished_(false), index_(0u), + completion_status_(DOWNLOAD_INTERRUPT_REASON_NONE), + is_response_completed_(false), consumer_handle_(std::move(consumer_handle)), handle_watcher_(base::MakeUnique<mojo::SimpleWatcher>( FROM_HERE, @@ -85,6 +89,17 @@ DownloadFileImpl::SourceStream::~SourceStream() = default; +void DownloadFileImpl::SourceStream::OnResponseCompleted( + DownloadInterruptReason status) { + // This can be called before or after data pipe is completely drained. So we + // need to pass the |completion_status_| to DownloadFileImpl if the data pipe + // is already drained. + is_response_completed_ = true; + completion_status_ = status; + if (completion_callback_) + std::move(completion_callback_).Run(this); +} + void DownloadFileImpl::SourceStream::OnWriteBytesToDisk(int64_t bytes_write) { bytes_written_ += bytes_write; } @@ -127,17 +142,20 @@ stream_reader_->RegisterCallback(base::Closure()); } -DownloadInterruptReason DownloadFileImpl::SourceStream::GetStatus() { +DownloadInterruptReason DownloadFileImpl::SourceStream::GetCompletionStatus() { if (stream_reader_) return static_cast<DownloadInterruptReason>(stream_reader_->GetStatus()); - // TODO(qinmin): figure out how to pass the complete status when data pipe is - // used. - return DOWNLOAD_INTERRUPT_REASON_NONE; + return completion_status_; } -DownloadFileImpl::SourceStream::ReadResult DownloadFileImpl::SourceStream::Read( - scoped_refptr<net::IOBuffer>* data, - size_t* length) { +void DownloadFileImpl::SourceStream::RegisterCompletionCallback( + DownloadFileImpl::SourceStream::CompletionCallback callback) { + completion_callback_ = std::move(callback); +} + +DownloadFileImpl::SourceStream::StreamState +DownloadFileImpl::SourceStream::Read(scoped_refptr<net::IOBuffer>* data, + size_t* length) { if (handle_watcher_) { *length = kBytesToRead; *data = new net::IOBuffer(kBytesToRead); @@ -150,7 +168,11 @@ case MOJO_RESULT_SHOULD_WAIT: return EMPTY; case MOJO_RESULT_FAILED_PRECONDITION: - return COMPLETE; + if (is_response_completed_) + return COMPLETE; + consumer_handle_.reset(); + ClearDataReadyCallback(); + return WAIT_FOR_COMPLETION; case MOJO_RESULT_INVALID_ARGUMENT: case MOJO_RESULT_OUT_OF_RANGE: case MOJO_RESULT_BUSY: @@ -301,6 +323,13 @@ OnSourceStreamAdded(source_streams_[offset].get()); } +void DownloadFileImpl::OnResponseCompleted(int64_t offset, + DownloadInterruptReason status) { + auto iter = source_streams_.find(offset); + if (iter != source_streams_.end()) + iter->second->OnResponseCompleted(status); +} + void DownloadFileImpl::OnSourceStreamAdded(SourceStream* source_stream) { // There are writers at different offsets now, create the received slices // vector if necessary. @@ -516,7 +545,7 @@ size_t num_buffers = 0; size_t bytes_to_write = 0; bool should_terminate = false; - SourceStream::ReadResult state(SourceStream::EMPTY); + SourceStream::StreamState state(SourceStream::EMPTY); DownloadInterruptReason reason = DOWNLOAD_INTERRUPT_REASON_NONE; base::TimeDelta delta( base::TimeDelta::FromMilliseconds(kMaxTimeBlockingFileThreadMs)); @@ -557,21 +586,11 @@ } } } break; - case SourceStream::COMPLETE: { - reason = source_stream->GetStatus(); - if (source_stream->length() == DownloadSaveInfo::kLengthFullContent && - !received_slices_.empty() && - (source_stream->offset() == - received_slices_.back().offset + - received_slices_.back().received_bytes) && - reason == DownloadInterruptReason:: - DOWNLOAD_INTERRUPT_REASON_SERVER_NO_RANGE) { - // We are probably reaching the end of the stream, don't treat this - // as an error. - reason = DOWNLOAD_INTERRUPT_REASON_NONE; - } - SendUpdate(); - } + case SourceStream::WAIT_FOR_COMPLETION: + source_stream->RegisterCompletionCallback(base::BindOnce( + &DownloadFileImpl::OnStreamCompleted, weak_factory_.GetWeakPtr())); + break; + case SourceStream::COMPLETE: break; default: NOTREACHED(); @@ -596,10 +615,42 @@ RecordContiguousWriteTime(now - start); - // Take care of communication with our observer. + if (state == SourceStream::COMPLETE) + OnStreamCompleted(source_stream); + else + NotifyObserver(source_stream, reason, state, should_terminate); + + if (net_log_.IsCapturing()) { + net_log_.AddEvent(net::NetLogEventType::DOWNLOAD_STREAM_DRAINED, + base::Bind(&FileStreamDrainedNetLogCallback, + total_incoming_data_size, num_buffers)); + } +} + +void DownloadFileImpl::OnStreamCompleted(SourceStream* source_stream) { + DownloadInterruptReason reason = source_stream->GetCompletionStatus(); + if (source_stream->length() == DownloadSaveInfo::kLengthFullContent && + !received_slices_.empty() && + (source_stream->offset() == received_slices_.back().offset + + received_slices_.back().received_bytes) && + reason == + DownloadInterruptReason::DOWNLOAD_INTERRUPT_REASON_SERVER_NO_RANGE) { + // We are probably reaching the end of the stream, don't treat this + // as an error. + reason = DOWNLOAD_INTERRUPT_REASON_NONE; + } + SendUpdate(); + + NotifyObserver(source_stream, reason, SourceStream::COMPLETE, false); +} + +void DownloadFileImpl::NotifyObserver(SourceStream* source_stream, + DownloadInterruptReason reason, + SourceStream::StreamState stream_state, + bool should_terminate) { if (reason != DOWNLOAD_INTERRUPT_REASON_NONE) { HandleStreamError(source_stream, reason); - } else if (state == SourceStream::COMPLETE || should_terminate) { + } else if (stream_state == SourceStream::COMPLETE || should_terminate) { // Signal successful completion or termination of the current stream. source_stream->ClearDataReadyCallback(); source_stream->set_finished(true); @@ -635,11 +686,6 @@ base::Passed(&hash_state))); } } - if (net_log_.IsCapturing()) { - net_log_.AddEvent(net::NetLogEventType::DOWNLOAD_STREAM_DRAINED, - base::Bind(&FileStreamDrainedNetLogCallback, - total_incoming_data_size, num_buffers)); - } } void DownloadFileImpl::RegisterAndActivateStream(SourceStream* source_stream) {
diff --git a/content/browser/download/download_file_impl.h b/content/browser/download/download_file_impl.h index 0771d0b..bfd5174 100644 --- a/content/browser/download/download_file_impl.h +++ b/content/browser/download/download_file_impl.h
@@ -68,6 +68,8 @@ void AddDataPipeConsumerHandle(mojo::ScopedDataPipeConsumerHandle handle, int64_t offset, int64_t length) override; + void OnResponseCompleted(int64_t offset, + DownloadInterruptReason status) override; void RenameAndUniquify(const base::FilePath& full_path, const RenameCompletionCallback& callback) override; void RenameAndAnnotate(const base::FilePath& full_path, @@ -120,6 +122,8 @@ mojo::ScopedDataPipeConsumerHandle consumer_handle); ~SourceStream(); + void OnResponseCompleted(DownloadInterruptReason status); + // Called after successfully writing a buffer to disk. void OnWriteBytesToDisk(int64_t bytes_write); @@ -142,15 +146,20 @@ // DownloadManager pass the status code to DownloadItem or DownloadFile. // However, a DownloadFile can have multiple SourceStreams, so we have to // maintain a map between data pipe and DownloadItem/DownloadFile somewhere. - DownloadInterruptReason GetStatus(); + DownloadInterruptReason GetCompletionStatus(); + + using CompletionCallback = base::OnceCallback<void(SourceStream*)>; + // Register an callback to be called when download completes. + void RegisterCompletionCallback(CompletionCallback callback); // Results for reading the SourceStream. - enum ReadResult { + enum StreamState { EMPTY = 0, HAS_DATA, + WAIT_FOR_COMPLETION, COMPLETE, }; - ReadResult Read(scoped_refptr<net::IOBuffer>* data, size_t* length); + StreamState Read(scoped_refptr<net::IOBuffer>* data, size_t* length); int64_t offset() const { return offset_; } int64_t length() const { return length_; } @@ -183,7 +192,14 @@ // The stream through which data comes. std::unique_ptr<ByteStreamReader> stream_reader_; - // Objects for reading from a mojo data pipe. + // Status when the response completes, used by data pipe. + DownloadInterruptReason completion_status_; + + // Whether the producer has completed handling the response. + bool is_response_completed_; + + CompletionCallback completion_callback_; + mojo::ScopedDataPipeConsumerHandle consumer_handle_; std::unique_ptr<mojo::SimpleWatcher> handle_watcher_; @@ -251,6 +267,15 @@ // Register callback and start to read data from the stream. void RegisterAndActivateStream(SourceStream* source_stream); + // Called when a stream completes. + void OnStreamCompleted(SourceStream* source_stream); + + // Notify |observer_| about the download status. + void NotifyObserver(SourceStream* source_stream, + DownloadInterruptReason reason, + SourceStream::StreamState stream_state, + bool should_terminate); + // Adds a new slice to |received_slices_| and update the existing entries in // |source_streams_| as their lengths will change. // TODO(qinmin): add a test for this function.
diff --git a/content/browser/download/download_item_impl.cc b/content/browser/download/download_item_impl.cc index dab4a0bf..ffe83eca 100644 --- a/content/browser/download/download_item_impl.cc +++ b/content/browser/download/download_item_impl.cc
@@ -234,7 +234,7 @@ false, std::string(), start_time), - guid_(base::ToUpperASCII(guid)), + guid_(guid), download_id_(download_id), mime_type_(mime_type), original_mime_type_(original_mime_type), @@ -282,8 +282,7 @@ info.has_user_gesture, info.remote_address, info.start_time), - guid_(info.guid.empty() ? base::ToUpperASCII(base::GenerateGUID()) - : info.guid), + guid_(info.guid.empty() ? base::GenerateGUID() : info.guid), download_id_(download_id), response_headers_(info.response_headers), content_disposition_(info.content_disposition), @@ -326,7 +325,7 @@ std::unique_ptr<DownloadRequestHandleInterface> request_handle, const net::NetLogWithSource& net_log) : request_info_(url), - guid_(base::ToUpperASCII(base::GenerateGUID())), + guid_(base::GenerateGUID()), download_id_(download_id), mime_type_(mime_type), original_mime_type_(mime_type),
diff --git a/content/browser/download/download_item_impl.h b/content/browser/download/download_item_impl.h index 0577a1f..dd1e68e 100644 --- a/content/browser/download/download_item_impl.h +++ b/content/browser/download/download_item_impl.h
@@ -628,6 +628,12 @@ RequestInfo request_info_; + // GUID to identify the download, generated by |base::GenerateGUID| in + // download item, or provided by |DownloadUrlParameters|. + // The format should follow UUID version 4 in RFC 4122. + // The string representation is case sensitive. Legacy download GUID hex + // digits may be upper case ASCII characters, and new GUID will be in lower + // case. std::string guid_; uint32_t download_id_ = kInvalidId;
diff --git a/content/browser/download/download_manager_impl.cc b/content/browser/download/download_manager_impl.cc index c2c89e2f..c9d82cb 100644 --- a/content/browser/download/download_manager_impl.cc +++ b/content/browser/download/download_manager_impl.cc
@@ -730,7 +730,6 @@ } DownloadItem* DownloadManagerImpl::GetDownloadByGuid(const std::string& guid) { - DCHECK(guid == base::ToUpperASCII(guid)); return base::ContainsKey(downloads_by_guid_, guid) ? downloads_by_guid_[guid] : nullptr; }
diff --git a/content/browser/download/download_manager_impl_unittest.cc b/content/browser/download/download_manager_impl_unittest.cc index 477d4ed..ab96db1 100644 --- a/content/browser/download/download_manager_impl_unittest.cc +++ b/content/browser/download/download_manager_impl_unittest.cc
@@ -253,8 +253,7 @@ EXPECT_CALL(*result, GetId()) .WillRepeatedly(Return(download_id)); EXPECT_CALL(*result, GetGuid()) - .WillRepeatedly( - ReturnRefOfCopy(base::ToUpperASCII(base::GenerateGUID()))); + .WillRepeatedly(ReturnRefOfCopy(base::GenerateGUID())); items_[download_id] = result; // Active items are created and then immediately are called to start
diff --git a/content/browser/download/mock_download_file.h b/content/browser/download/mock_download_file.h index 3da3b31..152a932 100644 --- a/content/browser/download/mock_download_file.h +++ b/content/browser/download/mock_download_file.h
@@ -47,6 +47,8 @@ void(ByteStreamReader* stream_reader, int64_t offset, int64_t length)); + MOCK_METHOD2(OnResponseCompleted, void(int64_t offset, + DownloadInterruptReason status)); MOCK_METHOD2(AppendDataToFile, DownloadInterruptReason( const char* data, size_t data_len)); MOCK_METHOD1(Rename, DownloadInterruptReason(
diff --git a/content/browser/fileapi/upload_file_system_file_element_reader.h b/content/browser/fileapi/upload_file_system_file_element_reader.h index 3a9ab9c..be6e313 100644 --- a/content/browser/fileapi/upload_file_system_file_element_reader.h +++ b/content/browser/fileapi/upload_file_system_file_element_reader.h
@@ -27,8 +27,8 @@ namespace content { // An UploadElementReader implementation for filesystem file. -class CONTENT_EXPORT UploadFileSystemFileElementReader : - NON_EXPORTED_BASE(public net::UploadElementReader) { +class CONTENT_EXPORT UploadFileSystemFileElementReader + : public net::UploadElementReader { public: UploadFileSystemFileElementReader( storage::FileSystemContext* file_system_context,
diff --git a/content/browser/frame_host/interstitial_page_impl.h b/content/browser/frame_host/interstitial_page_impl.h index 86b35ba..4af4ea8 100644 --- a/content/browser/frame_host/interstitial_page_impl.h +++ b/content/browser/frame_host/interstitial_page_impl.h
@@ -42,13 +42,12 @@ CANCEL }; -class CONTENT_EXPORT InterstitialPageImpl - : public NON_EXPORTED_BASE(InterstitialPage), - public NotificationObserver, - public NON_EXPORTED_BASE(RenderFrameHostDelegate), - public RenderViewHostDelegate, - public RenderWidgetHostDelegate, - public NON_EXPORTED_BASE(NavigatorDelegate) { +class CONTENT_EXPORT InterstitialPageImpl : public InterstitialPage, + public NotificationObserver, + public RenderFrameHostDelegate, + public RenderViewHostDelegate, + public RenderWidgetHostDelegate, + public NavigatorDelegate { public: // The different state of actions the user can take in an interstitial. enum ActionState {
diff --git a/content/browser/frame_host/navigation_controller_impl.h b/content/browser/frame_host/navigation_controller_impl.h index a86ca16..96769106 100644 --- a/content/browser/frame_host/navigation_controller_impl.h +++ b/content/browser/frame_host/navigation_controller_impl.h
@@ -32,8 +32,7 @@ class SiteInstance; struct LoadCommittedDetails; -class CONTENT_EXPORT NavigationControllerImpl - : public NON_EXPORTED_BASE(NavigationController) { +class CONTENT_EXPORT NavigationControllerImpl : public NavigationController { public: NavigationControllerImpl( NavigationControllerDelegate* delegate,
diff --git a/content/browser/frame_host/navigation_controller_impl_browsertest.cc b/content/browser/frame_host/navigation_controller_impl_browsertest.cc index b0b2092a..c64968e 100644 --- a/content/browser/frame_host/navigation_controller_impl_browsertest.cc +++ b/content/browser/frame_host/navigation_controller_impl_browsertest.cc
@@ -709,11 +709,11 @@ RenderFrameHostImpl* rfh = static_cast<RenderFrameHostImpl*>(render_frame_host); - // Don't pay attention to swapped out RenderFrameHosts in the main frame. - // TODO(nasko): Remove once swappedout:// is gone. - // See https://crbug.com/357747. + // Don't pay attention to pending delete RenderFrameHosts in the main frame, + // which might happen in a race if a cross-process navigation happens + // quickly. if (!rfh->is_active()) { - DLOG(INFO) << "Skipping swapped out RFH: " + DLOG(INFO) << "Skipping pending delete RFH: " << rfh->GetSiteInstance()->GetSiteURL(); return; }
diff --git a/content/browser/frame_host/navigation_entry_impl.h b/content/browser/frame_host/navigation_entry_impl.h index 0746ae3..b70a51f 100644 --- a/content/browser/frame_host/navigation_entry_impl.h +++ b/content/browser/frame_host/navigation_entry_impl.h
@@ -35,8 +35,7 @@ struct RequestNavigationParams; struct StartNavigationParams; -class CONTENT_EXPORT NavigationEntryImpl - : public NON_EXPORTED_BASE(NavigationEntry) { +class CONTENT_EXPORT NavigationEntryImpl : public NavigationEntry { public: // Represents a tree of FrameNavigationEntries that make up this joint session // history item. The tree currently only tracks the main frame by default,
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc index 5e28794..e3310940 100644 --- a/content/browser/frame_host/render_frame_host_impl.cc +++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -2989,9 +2989,11 @@ base::Bind(&AuthenticatorImpl::Create, base::Unretained(this))); } - registry_->AddInterface( - base::Bind(&ForwardRequest<device::mojom::SensorProvider>, - device::mojom::kServiceName)); + if (base::FeatureList::IsEnabled(features::kGenericSensor)) { + registry_->AddInterface( + base::Bind(&ForwardRequest<device::mojom::SensorProvider>, + device::mojom::kServiceName)); + } registry_->AddInterface( base::Bind(&ForwardRequest<device::mojom::VibrationManager>,
diff --git a/content/browser/frame_host/render_frame_host_impl.h b/content/browser/frame_host/render_frame_host_impl.h index 4bfcaaf..eae28864 100644 --- a/content/browser/frame_host/render_frame_host_impl.h +++ b/content/browser/frame_host/render_frame_host_impl.h
@@ -118,11 +118,11 @@ class CONTENT_EXPORT RenderFrameHostImpl : public RenderFrameHost, public base::SupportsUserData, - NON_EXPORTED_BASE(public mojom::FrameHost), - NON_EXPORTED_BASE(public mojom::FrameHostInterfaceBroker), + public mojom::FrameHost, + public mojom::FrameHostInterfaceBroker, public BrowserAccessibilityDelegate, public SiteInstanceImpl::Observer, - public NON_EXPORTED_BASE(service_manager::mojom::InterfaceProvider), + public service_manager::mojom::InterfaceProvider, public CSPContext { public: using AXTreeSnapshotCallback =
diff --git a/content/browser/frame_host/render_frame_host_manager_browsertest.cc b/content/browser/frame_host/render_frame_host_manager_browsertest.cc index 8bfab9a..b05e9aa9 100644 --- a/content/browser/frame_host/render_frame_host_manager_browsertest.cc +++ b/content/browser/frame_host/render_frame_host_manager_browsertest.cc
@@ -1709,16 +1709,15 @@ } // Test for crbug.com/143155. Frame tree updates during unload should not -// interrupt the intended navigation and show swappedout:// instead. +// interrupt the intended navigation. // Specifically: // 1) Open 2 tabs in an HTTP SiteInstance, with a subframe in the opener. // 2) Send the second tab to a different foo.com SiteInstance. -// This creates a swapped out opener for the first tab in the foo process. +// This created a swapped out opener for the first tab in the foo process. // 3) Navigate the first tab to the foo.com SiteInstance, and have the first // tab's unload handler remove its frame. -// This used to cause an update to the frame tree of the swapped out RV, -// just as it was navigating to a real page. That pre-empted the real -// navigation and visibly sent the tab to swappedout://. +// In older versions of Chrome, this caused an update to the frame tree that +// resulted in showing an internal page rather than the real page. IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest, DontPreemptNavigationWithFrameTreeUpdate) { StartEmbeddedServer();
diff --git a/content/browser/frame_host/render_frame_message_filter.h b/content/browser/frame_host/render_frame_message_filter.h index 7c40d15..db727c1 100644 --- a/content/browser/frame_host/render_frame_message_filter.h +++ b/content/browser/frame_host/render_frame_message_filter.h
@@ -52,7 +52,7 @@ class CONTENT_EXPORT RenderFrameMessageFilter : public BrowserMessageFilter, public BrowserAssociatedInterface<mojom::RenderFrameMessageFilter>, - public NON_EXPORTED_BASE(mojom::RenderFrameMessageFilter) { + public mojom::RenderFrameMessageFilter { public: RenderFrameMessageFilter(int render_process_id, PluginServiceImpl* plugin_service,
diff --git a/content/browser/frame_host/render_widget_host_view_child_frame.h b/content/browser/frame_host/render_widget_host_view_child_frame.h index f5a48b1c..3fbd66f 100644 --- a/content/browser/frame_host/render_widget_host_view_child_frame.h +++ b/content/browser/frame_host/render_widget_host_view_child_frame.h
@@ -55,8 +55,8 @@ class CONTENT_EXPORT RenderWidgetHostViewChildFrame : public RenderWidgetHostViewBase, public TouchSelectionControllerClientManager::Observer, - public NON_EXPORTED_BASE(viz::CompositorFrameSinkSupportClient), - public NON_EXPORTED_BASE(viz::HostFrameSinkClient) { + public viz::CompositorFrameSinkSupportClient, + public viz::HostFrameSinkClient { public: static RenderWidgetHostViewChildFrame* Create(RenderWidgetHost* widget); ~RenderWidgetHostViewChildFrame() override;
diff --git a/content/browser/geolocation/geolocation_service_impl.h b/content/browser/geolocation/geolocation_service_impl.h index f26eb32..e8af52b 100644 --- a/content/browser/geolocation/geolocation_service_impl.h +++ b/content/browser/geolocation/geolocation_service_impl.h
@@ -44,7 +44,7 @@ }; class CONTENT_EXPORT GeolocationServiceImpl - : public NON_EXPORTED_BASE(device::mojom::GeolocationService) { + : public device::mojom::GeolocationService { public: GeolocationServiceImpl(device::GeolocationContext* geolocation_context, PermissionManager* permission_manager,
diff --git a/content/browser/gpu/browser_gpu_memory_buffer_manager.cc b/content/browser/gpu/browser_gpu_memory_buffer_manager.cc index 98e4f9c..e43ddbc4 100644 --- a/content/browser/gpu/browser_gpu_memory_buffer_manager.cc +++ b/content/browser/gpu/browser_gpu_memory_buffer_manager.cc
@@ -23,7 +23,6 @@ #include "gpu/ipc/client/gpu_memory_buffer_impl.h" #include "gpu/ipc/client/gpu_memory_buffer_impl_shared_memory.h" #include "ui/gfx/buffer_format_util.h" -#include "ui/gfx/gpu_memory_buffer_tracing.h" #include "ui/gl/gl_switches.h" namespace content { @@ -182,11 +181,8 @@ ClientIdToTracingProcessId(client_id); if (buffer.second.type == gfx::SHARED_MEMORY_BUFFER) { - auto shared_buffer_guid = gfx::GetSharedMemoryGUIDForTracing( - client_tracing_process_id, buffer_id); - pmd->CreateSharedMemoryOwnershipEdge(dump->guid(), shared_buffer_guid, - buffer.second.shared_memory_guid, - 0 /* importance */); + pmd->CreateSharedMemoryOwnershipEdge( + dump->guid(), buffer.second.shared_memory_guid, 0 /* importance */); } else { auto shared_buffer_guid = gfx::GetGenericSharedGpuMemoryGUIDForTracing( client_tracing_process_id, buffer_id);
diff --git a/content/browser/gpu/gpu_data_manager_impl.h b/content/browser/gpu/gpu_data_manager_impl.h index e8390674..e278e140 100644 --- a/content/browser/gpu/gpu_data_manager_impl.h +++ b/content/browser/gpu/gpu_data_manager_impl.h
@@ -41,8 +41,7 @@ class GpuDataManagerImplPrivate; struct WebPreferences; -class CONTENT_EXPORT GpuDataManagerImpl - : public NON_EXPORTED_BASE(GpuDataManager) { +class CONTENT_EXPORT GpuDataManagerImpl : public GpuDataManager { public: // Indicates the guilt level of a domain which caused a GPU reset. // If a domain is 100% known to be guilty of resetting the GPU, then
diff --git a/content/browser/gpu/gpu_feature_checker_impl.h b/content/browser/gpu/gpu_feature_checker_impl.h index a7843cc..6e4841d1 100644 --- a/content/browser/gpu/gpu_feature_checker_impl.h +++ b/content/browser/gpu/gpu_feature_checker_impl.h
@@ -14,9 +14,8 @@ namespace content { -class CONTENT_EXPORT GpuFeatureCheckerImpl - : public NON_EXPORTED_BASE(GpuFeatureChecker), - public GpuDataManagerObserver { +class CONTENT_EXPORT GpuFeatureCheckerImpl : public GpuFeatureChecker, + public GpuDataManagerObserver { public: GpuFeatureCheckerImpl(gpu::GpuFeatureType feature, FeatureAvailableCallback callback);
diff --git a/content/browser/host_zoom_map_impl.h b/content/browser/host_zoom_map_impl.h index ad4c07e..ec701680 100644 --- a/content/browser/host_zoom_map_impl.h +++ b/content/browser/host_zoom_map_impl.h
@@ -24,7 +24,7 @@ // HostZoomMap needs to be deleted on the UI thread because it listens // to notifications on there (and holds a NotificationRegistrar). -class CONTENT_EXPORT HostZoomMapImpl : public NON_EXPORTED_BASE(HostZoomMap), +class CONTENT_EXPORT HostZoomMapImpl : public HostZoomMap, public NotificationObserver { public: HostZoomMapImpl();
diff --git a/content/browser/indexed_db/indexed_db_context_impl.h b/content/browser/indexed_db/indexed_db_context_impl.h index 30948886..5197234 100644 --- a/content/browser/indexed_db/indexed_db_context_impl.h +++ b/content/browser/indexed_db/indexed_db_context_impl.h
@@ -40,8 +40,7 @@ class IndexedDBConnection; -class CONTENT_EXPORT IndexedDBContextImpl - : NON_EXPORTED_BASE(public IndexedDBContext) { +class CONTENT_EXPORT IndexedDBContextImpl : public IndexedDBContext { public: // Recorded in histograms, so append only. enum ForceCloseReason {
diff --git a/content/browser/indexed_db/indexed_db_database.h b/content/browser/indexed_db/indexed_db_database.h index b7e42cfc..91791fb 100644 --- a/content/browser/indexed_db/indexed_db_database.h +++ b/content/browser/indexed_db/indexed_db_database.h
@@ -46,7 +46,7 @@ struct IndexedDBValue; class CONTENT_EXPORT IndexedDBDatabase - : NON_EXPORTED_BASE(public base::RefCounted<IndexedDBDatabase>) { + : public base::RefCounted<IndexedDBDatabase> { public: // Identifier is pair of (origin, database name). using Identifier = std::pair<url::Origin, base::string16>;
diff --git a/content/browser/indexed_db/indexed_db_factory.h b/content/browser/indexed_db/indexed_db_factory.h index 388b0cc6..a1816d1 100644 --- a/content/browser/indexed_db/indexed_db_factory.h +++ b/content/browser/indexed_db/indexed_db_factory.h
@@ -35,7 +35,7 @@ struct IndexedDBDataLossInfo; class CONTENT_EXPORT IndexedDBFactory - : NON_EXPORTED_BASE(public base::RefCountedThreadSafe<IndexedDBFactory>) { + : public base::RefCountedThreadSafe<IndexedDBFactory> { public: typedef std::multimap<url::Origin, IndexedDBDatabase*> OriginDBMap; typedef OriginDBMap::const_iterator OriginDBMapIterator;
diff --git a/content/browser/keyboard_lock/keyboard_lock_service_impl.h b/content/browser/keyboard_lock/keyboard_lock_service_impl.h index 4202eb3..d5576bb 100644 --- a/content/browser/keyboard_lock/keyboard_lock_service_impl.h +++ b/content/browser/keyboard_lock/keyboard_lock_service_impl.h
@@ -12,7 +12,7 @@ namespace content { class CONTENT_EXPORT KeyboardLockServiceImpl - : public NON_EXPORTED_BASE(blink::mojom::KeyboardLockService) { + : public blink::mojom::KeyboardLockService { public: KeyboardLockServiceImpl(); ~KeyboardLockServiceImpl() override;
diff --git a/content/browser/loader/mojo_async_resource_handler.h b/content/browser/loader/mojo_async_resource_handler.h index 77ebbc94..68e9648 100644 --- a/content/browser/loader/mojo_async_resource_handler.h +++ b/content/browser/loader/mojo_async_resource_handler.h
@@ -48,9 +48,8 @@ // TODO(yhirano): Send cached metadata. // // This class can be inherited only for tests. -class CONTENT_EXPORT MojoAsyncResourceHandler - : public ResourceHandler, - public NON_EXPORTED_BASE(mojom::URLLoader) { +class CONTENT_EXPORT MojoAsyncResourceHandler : public ResourceHandler, + public mojom::URLLoader { public: MojoAsyncResourceHandler(net::URLRequest* request, ResourceDispatcherHostImpl* rdh,
diff --git a/content/browser/media/capture/web_contents_audio_input_stream.h b/content/browser/media/capture/web_contents_audio_input_stream.h index dd2c0c29d..a7047af 100644 --- a/content/browser/media/capture/web_contents_audio_input_stream.h +++ b/content/browser/media/capture/web_contents_audio_input_stream.h
@@ -35,7 +35,7 @@ class WebContentsTracker; class CONTENT_EXPORT WebContentsAudioInputStream - : NON_EXPORTED_BASE(public media::AudioInputStream) { + : public media::AudioInputStream { public: // media::AudioInputStream implementation bool Open() override;
diff --git a/content/browser/media/cdm_registry_impl.h b/content/browser/media/cdm_registry_impl.h index f2bd940a..303f3c59 100644 --- a/content/browser/media/cdm_registry_impl.h +++ b/content/browser/media/cdm_registry_impl.h
@@ -16,7 +16,7 @@ struct CdmInfo; -class CONTENT_EXPORT CdmRegistryImpl : NON_EXPORTED_BASE(public CdmRegistry) { +class CONTENT_EXPORT CdmRegistryImpl : public CdmRegistry { public: // Returns the CdmRegistryImpl singleton. static CdmRegistryImpl* GetInstance();
diff --git a/content/browser/media/media_internals.h b/content/browser/media/media_internals.h index 7969d831..4a0fa4e 100644 --- a/content/browser/media/media_internals.h +++ b/content/browser/media/media_internals.h
@@ -32,9 +32,8 @@ namespace content { // This class stores information about currently active media. -class CONTENT_EXPORT MediaInternals - : NON_EXPORTED_BASE(public media::AudioLogFactory), - public NotificationObserver { +class CONTENT_EXPORT MediaInternals : public media::AudioLogFactory, + public NotificationObserver { public: // Called with the update string. typedef base::Callback<void(const base::string16&)> UpdateCallback;
diff --git a/content/browser/media/session/media_session_controller.h b/content/browser/media/session/media_session_controller.h index a7cc5cf5..5a35b25 100644 --- a/content/browser/media/session/media_session_controller.h +++ b/content/browser/media/session/media_session_controller.h
@@ -24,7 +24,7 @@ // browser side MediaSession commands back to a player hosted in the renderer // process. class CONTENT_EXPORT MediaSessionController - : NON_EXPORTED_BASE(public MediaSessionPlayerObserver) { + : public MediaSessionPlayerObserver { public: MediaSessionController(const WebContentsObserver::MediaPlayerId& id, MediaWebContentsObserver* media_web_contents_observer);
diff --git a/content/browser/notifications/platform_notification_context_impl.h b/content/browser/notifications/platform_notification_context_impl.h index eb7ed38..af5d335 100644 --- a/content/browser/notifications/platform_notification_context_impl.h +++ b/content/browser/notifications/platform_notification_context_impl.h
@@ -42,8 +42,8 @@ // defined in this interface must only be called on the IO thread unless // otherwise specified. class CONTENT_EXPORT PlatformNotificationContextImpl - : NON_EXPORTED_BASE(public PlatformNotificationContext), - NON_EXPORTED_BASE(public ServiceWorkerContextCoreObserver) { + : public PlatformNotificationContext, + public ServiceWorkerContextCoreObserver { public: // Constructs a new platform notification context. If |path| is non-empty, the // database will be initialized in the "Platform Notifications" subdirectory
diff --git a/content/browser/payments/payment_manager.h b/content/browser/payments/payment_manager.h index da77b81..f4eed48 100644 --- a/content/browser/payments/payment_manager.h +++ b/content/browser/payments/payment_manager.h
@@ -18,8 +18,7 @@ class PaymentAppContextImpl; -class CONTENT_EXPORT PaymentManager - : public NON_EXPORTED_BASE(payments::mojom::PaymentManager) { +class CONTENT_EXPORT PaymentManager : public payments::mojom::PaymentManager { public: PaymentManager( PaymentAppContextImpl* payment_app_context,
diff --git a/content/browser/pepper_flash_settings_helper_impl.h b/content/browser/pepper_flash_settings_helper_impl.h index cb11025..9565740 100644 --- a/content/browser/pepper_flash_settings_helper_impl.h +++ b/content/browser/pepper_flash_settings_helper_impl.h
@@ -14,7 +14,7 @@ class CONTENT_EXPORT PepperFlashSettingsHelperImpl : public PepperFlashSettingsHelper, - NON_EXPORTED_BASE(public PpapiPluginProcessHost::BrokerClient) { + public PpapiPluginProcessHost::BrokerClient { public: PepperFlashSettingsHelperImpl();
diff --git a/content/browser/plugin_service_impl.h b/content/browser/plugin_service_impl.h index 85b64dad..b654bf3 100644 --- a/content/browser/plugin_service_impl.h +++ b/content/browser/plugin_service_impl.h
@@ -47,8 +47,7 @@ class ResourceContext; struct PepperPluginInfo; -class CONTENT_EXPORT PluginServiceImpl - : NON_EXPORTED_BASE(public PluginService) { +class CONTENT_EXPORT PluginServiceImpl : public PluginService { public: // Returns the PluginServiceImpl singleton. static PluginServiceImpl* GetInstance();
diff --git a/content/browser/presentation/presentation_service_impl.h b/content/browser/presentation/presentation_service_impl.h index 8e9e8385..8941157 100644 --- a/content/browser/presentation/presentation_service_impl.h +++ b/content/browser/presentation/presentation_service_impl.h
@@ -43,7 +43,7 @@ // This class is instantiated on-demand via Mojo's ConnectToRemoteService // from the renderer when the first presentation API request is handled. class CONTENT_EXPORT PresentationServiceImpl - : public NON_EXPORTED_BASE(blink::mojom::PresentationService), + : public blink::mojom::PresentationService, public WebContentsObserver, public PresentationServiceDelegate::Observer { public:
diff --git a/content/browser/renderer_host/compositor_resize_lock.h b/content/browser/renderer_host/compositor_resize_lock.h index 4e5a17b4..eab4c0b9 100644 --- a/content/browser/renderer_host/compositor_resize_lock.h +++ b/content/browser/renderer_host/compositor_resize_lock.h
@@ -30,8 +30,7 @@ }; // Used to prevent further resizes while a resize is pending. -class CONTENT_EXPORT CompositorResizeLock - : NON_EXPORTED_BASE(public ui::CompositorLockClient) { +class CONTENT_EXPORT CompositorResizeLock : public ui::CompositorLockClient { public: CompositorResizeLock(CompositorResizeLockClient* client, const gfx::Size& new_size);
diff --git a/content/browser/renderer_host/compositor_resize_lock_unittest.cc b/content/browser/renderer_host/compositor_resize_lock_unittest.cc index 5199b3d..9416bd89 100644 --- a/content/browser/renderer_host/compositor_resize_lock_unittest.cc +++ b/content/browser/renderer_host/compositor_resize_lock_unittest.cc
@@ -13,9 +13,8 @@ namespace content { namespace { -class FakeCompositorResizeLockClient - : public CompositorResizeLockClient, - public NON_EXPORTED_BASE(ui::CompositorLockDelegate) { +class FakeCompositorResizeLockClient : public CompositorResizeLockClient, + public ui::CompositorLockDelegate { public: FakeCompositorResizeLockClient() : weak_ptr_factory_(this) {}
diff --git a/content/browser/renderer_host/delegated_frame_host.h b/content/browser/renderer_host/delegated_frame_host.h index b771339..985712ce 100644 --- a/content/browser/renderer_host/delegated_frame_host.h +++ b/content/browser/renderer_host/delegated_frame_host.h
@@ -81,8 +81,8 @@ public ui::CompositorVSyncManager::Observer, public ui::ContextFactoryObserver, public viz::FrameEvictorClient, - public NON_EXPORTED_BASE(viz::CompositorFrameSinkSupportClient), - public NON_EXPORTED_BASE(viz::HostFrameSinkClient), + public viz::CompositorFrameSinkSupportClient, + public viz::HostFrameSinkClient, public base::SupportsWeakPtr<DelegatedFrameHost> { public: DelegatedFrameHost(const viz::FrameSinkId& frame_sink_id,
diff --git a/content/browser/renderer_host/delegated_frame_host_client_aura.h b/content/browser/renderer_host/delegated_frame_host_client_aura.h index 3df9459..b056281 100644 --- a/content/browser/renderer_host/delegated_frame_host_client_aura.h +++ b/content/browser/renderer_host/delegated_frame_host_client_aura.h
@@ -17,7 +17,7 @@ // DelegatedFrameHostClient implementation for aura, not used in mus. class CONTENT_EXPORT DelegatedFrameHostClientAura : public DelegatedFrameHostClient, - NON_EXPORTED_BASE(public CompositorResizeLockClient) { + public CompositorResizeLockClient { public: explicit DelegatedFrameHostClientAura( RenderWidgetHostViewAura* render_widget_host_view);
diff --git a/content/browser/renderer_host/input/input_router_impl.h b/content/browser/renderer_host/input/input_router_impl.h index 3fcd575..88b069e 100644 --- a/content/browser/renderer_host/input/input_router_impl.h +++ b/content/browser/renderer_host/input/input_router_impl.h
@@ -43,11 +43,11 @@ // A default implementation for browser input event routing. class CONTENT_EXPORT InputRouterImpl - : public NON_EXPORTED_BASE(InputRouter), - public NON_EXPORTED_BASE(GestureEventQueueClient), - public NON_EXPORTED_BASE(MouseWheelEventQueueClient), - public NON_EXPORTED_BASE(TouchEventQueueClient), - public NON_EXPORTED_BASE(TouchpadTapSuppressionControllerClient) { + : public InputRouter, + public GestureEventQueueClient, + public MouseWheelEventQueueClient, + public TouchEventQueueClient, + public TouchpadTapSuppressionControllerClient { public: InputRouterImpl(InputRouterImplClient* client, InputDispositionHandler* disposition_handler,
diff --git a/content/browser/renderer_host/input/legacy_input_router_impl.h b/content/browser/renderer_host/input/legacy_input_router_impl.h index aa7415c..1fffe92 100644 --- a/content/browser/renderer_host/input/legacy_input_router_impl.h +++ b/content/browser/renderer_host/input/legacy_input_router_impl.h
@@ -45,11 +45,11 @@ // Chrome IPC which is deprecated. This class will be replaced with a Mojo // backed transport. See crbug.com/722928. class CONTENT_EXPORT LegacyInputRouterImpl - : public NON_EXPORTED_BASE(InputRouter), - public NON_EXPORTED_BASE(GestureEventQueueClient), - public NON_EXPORTED_BASE(MouseWheelEventQueueClient), - public NON_EXPORTED_BASE(TouchEventQueueClient), - public NON_EXPORTED_BASE(TouchpadTapSuppressionControllerClient) { + : public InputRouter, + public GestureEventQueueClient, + public MouseWheelEventQueueClient, + public TouchEventQueueClient, + public TouchpadTapSuppressionControllerClient { public: LegacyInputRouterImpl(IPC::Sender* sender, InputRouterClient* client,
diff --git a/content/browser/renderer_host/input/render_widget_host_latency_tracker.h b/content/browser/renderer_host/input/render_widget_host_latency_tracker.h index 84aa255..4e5d5c5 100644 --- a/content/browser/renderer_host/input/render_widget_host_latency_tracker.h +++ b/content/browser/renderer_host/input/render_widget_host_latency_tracker.h
@@ -24,7 +24,7 @@ // Utility class for tracking the latency of events passing through // a given RenderWidgetHost. class CONTENT_EXPORT RenderWidgetHostLatencyTracker - : NON_EXPORTED_BASE(public ui::LatencyTracker) { + : public ui::LatencyTracker { public: explicit RenderWidgetHostLatencyTracker(bool metric_sampling); ~RenderWidgetHostLatencyTracker();
diff --git a/content/browser/renderer_host/legacy_render_widget_host_win.h b/content/browser/renderer_host/legacy_render_widget_host_win.h index b89060ed..8cb8b83 100644 --- a/content/browser/renderer_host/legacy_render_widget_host_win.h +++ b/content/browser/renderer_host/legacy_render_widget_host_win.h
@@ -56,14 +56,15 @@ // HWND instead of the DesktopWindowTreeHostWin. class CONTENT_EXPORT LegacyRenderWidgetHostHWND : public ATL::CWindowImpl<LegacyRenderWidgetHostHWND, - NON_EXPORTED_BASE(ATL::CWindow), - ATL::CWinTraits<WS_CHILD> > { + ATL::CWindow, + ATL::CWinTraits<WS_CHILD>> { public: DECLARE_WND_CLASS_EX(L"Chrome_RenderWidgetHostHWND", CS_DBLCLKS, 0); typedef ATL::CWindowImpl<LegacyRenderWidgetHostHWND, - NON_EXPORTED_BASE(ATL::CWindow), - ATL::CWinTraits<WS_CHILD> > Base; + ATL::CWindow, + ATL::CWinTraits<WS_CHILD>> + Base; // Creates and returns an instance of the LegacyRenderWidgetHostHWND class on // successful creation of a child window parented to the parent window passed
diff --git a/content/browser/renderer_host/media/audio_sync_reader.h b/content/browser/renderer_host/media/audio_sync_reader.h index d7dce0ec..c0fbf1cc 100644 --- a/content/browser/renderer_host/media/audio_sync_reader.h +++ b/content/browser/renderer_host/media/audio_sync_reader.h
@@ -35,7 +35,7 @@ // transmitting audio packets between the browser process and the renderer // process. class CONTENT_EXPORT AudioSyncReader - : public NON_EXPORTED_BASE(media::AudioOutputController::SyncReader) { + : public media::AudioOutputController::SyncReader { public: // Create() automatically initializes the AudioSyncReader correctly, // and should be strongly preferred over calling the constructor directly!
diff --git a/content/browser/renderer_host/media/media_devices_dispatcher_host.cc b/content/browser/renderer_host/media/media_devices_dispatcher_host.cc index f75a4dd..f8fef9a 100644 --- a/content/browser/renderer_host/media/media_devices_dispatcher_host.cc +++ b/content/browser/renderer_host/media/media_devices_dispatcher_host.cc
@@ -6,6 +6,7 @@ #include <stddef.h> +#include <algorithm> #include <utility> #include <vector> @@ -455,6 +456,13 @@ media_stream_manager_->video_capture_manager()->GetDeviceSupportedFormats( device_id, &formats); + // Remove formats that have zero resolution. + formats.erase(std::remove_if(formats.begin(), formats.end(), + [](const media::VideoCaptureFormat& format) { + return format.frame_size.GetArea() <= 0; + }), + formats.end()); + return formats; }
diff --git a/content/browser/renderer_host/media/media_devices_dispatcher_host_unittest.cc b/content/browser/renderer_host/media/media_devices_dispatcher_host_unittest.cc index 724663b..8b073f966 100644 --- a/content/browser/renderer_host/media/media_devices_dispatcher_host_unittest.cc +++ b/content/browser/renderer_host/media/media_devices_dispatcher_host_unittest.cc
@@ -17,6 +17,7 @@ #include "base/run_loop.h" #include "base/strings/stringprintf.h" #include "base/threading/thread_task_runner_handle.h" +#include "content/browser/renderer_host/media/in_process_video_capture_provider.h" #include "content/browser/renderer_host/media/media_stream_manager.h" #include "content/browser/renderer_host/media/media_stream_ui_proxy.h" #include "content/browser/renderer_host/media/video_capture_manager.h" @@ -30,6 +31,7 @@ #include "media/audio/test_audio_thread.h" #include "media/base/media_switches.h" #include "media/capture/video/fake_video_capture_device_factory.h" +#include "media/capture/video/video_capture_system_impl.h" #include "mojo/public/cpp/bindings/binding.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -46,7 +48,10 @@ const int kProcessId = 5; const int kRenderId = 6; const size_t kNumFakeVideoDevices = 3; -const char kDefaultVideoDeviceID[] = "/dev/video2"; +const char kNormalVideoDeviceID[] = "/dev/video0"; +const char kNoFormatsVideoDeviceID[] = "/dev/video1"; +const char kZeroResolutionVideoDeviceID[] = "/dev/video2"; +const char* const kDefaultVideoDeviceID = kZeroResolutionVideoDeviceID; const char kDefaultAudioDeviceID[] = "fake_audio_input_2"; void PhysicalDevicesEnumerated(base::Closure quit_closure, @@ -83,16 +88,25 @@ // Make sure we use fake devices to avoid long delays. base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( switches::kUseFakeDeviceForMediaStream, - base::StringPrintf("device-count=%zu, video-input-default-id=%s, " + base::StringPrintf("video-input-default-id=%s, " "audio-input-default-id=%s", - kNumFakeVideoDevices, kDefaultVideoDeviceID, - kDefaultAudioDeviceID)); + kDefaultVideoDeviceID, kDefaultAudioDeviceID)); audio_manager_.reset(new media::MockAudioManager( base::MakeUnique<media::TestAudioThread>())); audio_system_ = media::AudioSystemImpl::Create(audio_manager_.get()); - media_stream_manager_ = - base::MakeUnique<MediaStreamManager>(audio_system_.get()); + auto video_capture_device_factory = + base::MakeUnique<media::FakeVideoCaptureDeviceFactory>(); + video_capture_device_factory_ = video_capture_device_factory.get(); + auto video_capture_system = base::MakeUnique<media::VideoCaptureSystemImpl>( + std::move(video_capture_device_factory)); + auto video_capture_provider = + base::MakeUnique<InProcessVideoCaptureProvider>( + std::move(video_capture_system), + base::ThreadTaskRunnerHandle::Get()); + + media_stream_manager_ = base::MakeUnique<MediaStreamManager>( + audio_system_.get(), std::move(video_capture_provider)); host_ = base::MakeUnique<MediaDevicesDispatcherHost>( kProcessId, kRenderId, browser_context_.GetMediaDeviceIDSalt(), media_stream_manager_.get()); @@ -101,6 +115,26 @@ ~MediaDevicesDispatcherHostTest() override { audio_manager_->Shutdown(); } void SetUp() override { + std::vector<media::FakeVideoCaptureDeviceSettings> fake_video_devices( + kNumFakeVideoDevices); + // A regular video device + fake_video_devices[0].device_id = kNormalVideoDeviceID; + fake_video_devices[0].supported_formats = { + {gfx::Size(640, 480), 30.0, media::PIXEL_FORMAT_I420}, + {gfx::Size(800, 600), 30.0, media::PIXEL_FORMAT_I420}, + {gfx::Size(1020, 780), 30.0, media::PIXEL_FORMAT_I420}, + {gfx::Size(1920, 1080), 20.0, media::PIXEL_FORMAT_I420}, + }; + // A video device that does not report any formats + fake_video_devices[1].device_id = kNoFormatsVideoDeviceID; + ASSERT_TRUE(fake_video_devices[1].supported_formats.empty()); + // A video device that reports a 0x0 resolution. + fake_video_devices[2].device_id = kZeroResolutionVideoDeviceID; + fake_video_devices[2].supported_formats = { + {gfx::Size(0, 0), 0.0, media::PIXEL_FORMAT_I420}, + }; + video_capture_device_factory_->SetToCustomDevicesConfig(fake_video_devices); + base::RunLoop run_loop; MediaDevicesManager::BoolDeviceTypes devices_to_enumerate; devices_to_enumerate[MEDIA_DEVICE_TYPE_AUDIO_INPUT] = true; @@ -133,13 +167,13 @@ EXPECT_EQ(kNumFakeVideoDevices, capabilities.size()); EXPECT_EQ(expected_first_device_id, capabilities[0]->device_id); for (const auto& capability : capabilities) { + // Always expect at least one format EXPECT_GT(capability->formats.size(), 1u); - EXPECT_GT(capability->formats[0].frame_size.width(), 1); - EXPECT_GT(capability->formats[0].frame_size.height(), 1); - EXPECT_GT(capability->formats[0].frame_rate, 1); - EXPECT_GT(capability->formats[1].frame_size.width(), 1); - EXPECT_GT(capability->formats[1].frame_size.height(), 1); - EXPECT_GT(capability->formats[1].frame_rate, 1); + for (auto& format : capability->formats) { + EXPECT_GE(format.frame_size.width(), 1); + EXPECT_GE(format.frame_size.height(), 1); + EXPECT_GE(format.frame_rate, 0.0); + } } } @@ -314,6 +348,7 @@ std::unique_ptr<media::AudioManager> audio_manager_; std::unique_ptr<media::AudioSystem> audio_system_; + media::FakeVideoCaptureDeviceFactory* video_capture_device_factory_; content::TestBrowserContext browser_context_; MediaDeviceEnumeration physical_devices_; url::Origin origin_;
diff --git a/content/browser/renderer_host/offscreen_canvas_surface_impl.h b/content/browser/renderer_host/offscreen_canvas_surface_impl.h index 7845e636..93e5be1 100644 --- a/content/browser/renderer_host/offscreen_canvas_surface_impl.h +++ b/content/browser/renderer_host/offscreen_canvas_surface_impl.h
@@ -21,7 +21,7 @@ // connections to both the renderer and frame sink manager. class CONTENT_EXPORT OffscreenCanvasSurfaceImpl : public blink::mojom::OffscreenCanvasSurface, - public NON_EXPORTED_BASE(viz::HostFrameSinkClient) { + public viz::HostFrameSinkClient { public: using DestroyCallback = base::OnceCallback<void()>;
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index 70385ca..67ea1762 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -1284,9 +1284,8 @@ is_self_deleted_(false), #endif pending_views_(0), - service_worker_ref_count_(0), - shared_worker_ref_count_(0), - is_worker_ref_count_disabled_(false), + keep_alive_ref_count_(0), + is_keep_alive_ref_count_disabled_(false), route_provider_binding_(this), visible_widgets_(0), is_process_backgrounded_(kLaunchingProcessIsBackgrounded), @@ -2095,56 +2094,35 @@ return is_process_backgrounded_; } -size_t RenderProcessHostImpl::GetWorkerRefCount() const { +void RenderProcessHostImpl::IncrementKeepAliveRefCount() { DCHECK_CURRENTLY_ON(BrowserThread::UI); - return service_worker_ref_count_ + shared_worker_ref_count_; + DCHECK(!is_keep_alive_ref_count_disabled_); + ++keep_alive_ref_count_; } -void RenderProcessHostImpl::IncrementServiceWorkerRefCount() { +void RenderProcessHostImpl::DecrementKeepAliveRefCount() { DCHECK_CURRENTLY_ON(BrowserThread::UI); - DCHECK(!is_worker_ref_count_disabled_); - ++service_worker_ref_count_; -} - -void RenderProcessHostImpl::DecrementServiceWorkerRefCount() { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - DCHECK(!is_worker_ref_count_disabled_); - DCHECK_GT(GetWorkerRefCount(), 0U); - --service_worker_ref_count_; - if (GetWorkerRefCount() == 0) + DCHECK(!is_keep_alive_ref_count_disabled_); + DCHECK_GT(keep_alive_ref_count_, 0U); + --keep_alive_ref_count_; + if (keep_alive_ref_count_ == 0) Cleanup(); } -void RenderProcessHostImpl::IncrementSharedWorkerRefCount() { +void RenderProcessHostImpl::DisableKeepAliveRefCount() { DCHECK_CURRENTLY_ON(BrowserThread::UI); - DCHECK(!is_worker_ref_count_disabled_); - ++shared_worker_ref_count_; -} - -void RenderProcessHostImpl::DecrementSharedWorkerRefCount() { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - DCHECK(!is_worker_ref_count_disabled_); - DCHECK_GT(GetWorkerRefCount(), 0U); - --shared_worker_ref_count_; - if (GetWorkerRefCount() == 0) - Cleanup(); -} - -void RenderProcessHostImpl::ForceReleaseWorkerRefCounts() { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - DCHECK(!is_worker_ref_count_disabled_); - is_worker_ref_count_disabled_ = true; - if (!GetWorkerRefCount()) + DCHECK(!is_keep_alive_ref_count_disabled_); + is_keep_alive_ref_count_disabled_ = true; + if (!keep_alive_ref_count_) return; - service_worker_ref_count_ = 0; - shared_worker_ref_count_ = 0; + keep_alive_ref_count_ = 0; // Cleaning up will also remove this from the SpareRenderProcessHostManager. Cleanup(); } -bool RenderProcessHostImpl::IsWorkerRefCountDisabled() { +bool RenderProcessHostImpl::IsKeepAliveRefCountDisabled() { DCHECK_CURRENTLY_ON(BrowserThread::UI); - return is_worker_ref_count_disabled_; + return is_keep_alive_ref_count_disabled_; } void RenderProcessHostImpl::PurgeAndSuspend() { @@ -2271,6 +2249,32 @@ return visible_widgets_; } +void RenderProcessHostImpl::UpdateWidgetImportance( + ChildProcessImportance old_value, + ChildProcessImportance new_value) { + DCHECK_NE(old_value, new_value); + DCHECK(widget_importance_counts_[static_cast<size_t>(old_value)]); + widget_importance_counts_[static_cast<size_t>(old_value)]--; + widget_importance_counts_[static_cast<size_t>(new_value)]++; + UpdateProcessPriority(); +} + +ChildProcessImportance RenderProcessHostImpl::GetWidgetImportanceForTesting() { + return ComputeEffectiveImportance(); +} + +ChildProcessImportance RenderProcessHostImpl::ComputeEffectiveImportance() { + ChildProcessImportance importance = ChildProcessImportance::NORMAL; + for (size_t i = 0u; i < arraysize(widget_importance_counts_); ++i) { + DCHECK_GE(widget_importance_counts_[i], 0); + if (widget_importance_counts_[i]) { + // No early out. Highest importance wins. + importance = static_cast<ChildProcessImportance>(i); + } + } + return importance; +} + RendererAudioOutputStreamFactoryContext* RenderProcessHostImpl::GetRendererAudioOutputStreamFactoryContext() { if (!audio_output_stream_factory_context_) { @@ -2392,7 +2396,7 @@ } bool RenderProcessHostImpl::HostHasNotBeenUsed() { - return IsUnused() && listeners_.IsEmpty() && GetWorkerRefCount() == 0 && + return IsUnused() && listeners_.IsEmpty() && keep_alive_ref_count_ == 0 && pending_views_ == 0; } @@ -2805,9 +2809,9 @@ if (!skip_unload_handlers && !SuddenTerminationAllowed()) return false; - if (GetWorkerRefCount() != 0) { - if (survive_for_worker_start_time_.is_null()) - survive_for_worker_start_time_ = base::TimeTicks::Now(); + if (keep_alive_ref_count_ != 0) { + if (keep_alive_start_time_.is_null()) + keep_alive_start_time_ = base::TimeTicks::Now(); return false; } @@ -3000,14 +3004,15 @@ } delayed_cleanup_needed_ = false; - // Records the time when the process starts surviving for workers for UMA. - if (listeners_.IsEmpty() && GetWorkerRefCount() > 0 && - survive_for_worker_start_time_.is_null()) { - survive_for_worker_start_time_ = base::TimeTicks::Now(); + // Records the time when the process starts kept alive by the ref count for + // UMA. + if (listeners_.IsEmpty() && keep_alive_ref_count_ > 0 && + keep_alive_start_time_.is_null()) { + keep_alive_start_time_ = base::TimeTicks::Now(); } // Until there are no other owners of this object, we can't delete ourselves. - if (!listeners_.IsEmpty() || GetWorkerRefCount() != 0) + if (!listeners_.IsEmpty() || keep_alive_ref_count_ != 0) return; #if BUILDFLAG(ENABLE_WEBRTC) @@ -3015,10 +3020,9 @@ ClearWebRtcLogMessageCallback(); #endif - if (!survive_for_worker_start_time_.is_null()) { - UMA_HISTOGRAM_LONG_TIMES( - "SharedWorker.RendererSurviveForWorkerTime", - base::TimeTicks::Now() - survive_for_worker_start_time_); + if (!keep_alive_start_time_.is_null()) { + UMA_HISTOGRAM_LONG_TIMES("SharedWorker.RendererSurviveForWorkerTime", + base::TimeTicks::Now() - keep_alive_start_time_); } // We cannot clean up twice; if this fails, there is an issue with our @@ -3092,11 +3096,22 @@ } void RenderProcessHostImpl::AddWidget(RenderWidgetHost* widget) { - widgets_.insert(static_cast<RenderWidgetHostImpl*>(widget)); + RenderWidgetHostImpl* widget_impl = + static_cast<RenderWidgetHostImpl*>(widget); + widgets_.insert(widget_impl); + widget_importance_counts_[static_cast<size_t>(widget_impl->importance())]++; + UpdateProcessPriority(); } void RenderProcessHostImpl::RemoveWidget(RenderWidgetHost* widget) { - widgets_.erase(static_cast<RenderWidgetHostImpl*>(widget)); + RenderWidgetHostImpl* widget_impl = + static_cast<RenderWidgetHostImpl*>(widget); + widgets_.erase(widget_impl); + + ChildProcessImportance importance = widget_impl->importance(); + DCHECK(widget_importance_counts_[static_cast<size_t>(importance)]); + widget_importance_counts_[static_cast<size_t>(importance)]--; + UpdateProcessPriority(); } void RenderProcessHostImpl::SetSuddenTerminationAllowed(bool enabled) { @@ -3775,9 +3790,11 @@ const bool should_background_changed = is_process_backgrounded_ != should_background; const bool has_pending_views = !!pending_views_; + const ChildProcessImportance importance = ComputeEffectiveImportance(); if (!should_background_changed && - boost_priority_for_pending_views_ == has_pending_views) { + boost_priority_for_pending_views_ == has_pending_views && + effective_importance_ == importance) { return; } @@ -3786,6 +3803,7 @@ has_pending_views); is_process_backgrounded_ = should_background; boost_priority_for_pending_views_ = has_pending_views; + effective_importance_ = importance; #if defined(OS_WIN) // The cbstext.dll loads as a global GetMessage hook in the browser process @@ -3804,7 +3822,7 @@ // swiftly scheduled by the OS per the low process priority // (http://crbug.com/398103). child_process_launcher_->SetProcessPriority(should_background, - has_pending_views); + has_pending_views, importance); // Notify the child process of background state. Note // |boost_priority_for_pending_views_| state is not sent to renderer simply
diff --git a/content/browser/renderer_host/render_process_host_impl.h b/content/browser/renderer_host/render_process_host_impl.h index ddadb7f..f5de5e63 100644 --- a/content/browser/renderer_host/render_process_host_impl.h +++ b/content/browser/renderer_host/render_process_host_impl.h
@@ -22,6 +22,7 @@ #include "base/synchronization/waitable_event.h" #include "build/build_config.h" #include "components/viz/service/display_embedder/shared_bitmap_allocation_notifier_impl.h" +#include "content/browser/child_process_importance.h" #include "content/browser/child_process_launcher.h" #include "content/browser/dom_storage/session_storage_namespace_impl.h" #include "content/browser/renderer_host/frame_sink_provider_impl.h" @@ -112,9 +113,9 @@ : public RenderProcessHost, public ChildProcessLauncher::Client, public ui::GpuSwitchingObserver, - public NON_EXPORTED_BASE(mojom::RouteProvider), - public NON_EXPORTED_BASE(mojom::AssociatedInterfaceProvider), - public NON_EXPORTED_BASE(mojom::RendererHost) { + public mojom::RouteProvider, + public mojom::AssociatedInterfaceProvider, + public mojom::RendererHost { public: // Use the spare RenderProcessHost if it exists, or create a new one. This // should be the usual way to get a new RenderProcessHost. @@ -171,6 +172,8 @@ void RemovePendingView() override; void AddWidget(RenderWidgetHost* widget) override; void RemoveWidget(RenderWidgetHost* widget) override; + void UpdateWidgetImportance(ChildProcessImportance old_value, + ChildProcessImportance new_value) override; void SetSuddenTerminationAllowed(bool enabled) override; bool SuddenTerminationAllowed() const override; IPC::ChannelProxy* GetChannel() override; @@ -200,13 +203,10 @@ override; const base::TimeTicks& GetInitTimeForNavigationMetrics() const override; bool IsProcessBackgrounded() const override; - size_t GetWorkerRefCount() const override; - void IncrementServiceWorkerRefCount() override; - void DecrementServiceWorkerRefCount() override; - void IncrementSharedWorkerRefCount() override; - void DecrementSharedWorkerRefCount() override; - void ForceReleaseWorkerRefCounts() override; - bool IsWorkerRefCountDisabled() override; + void IncrementKeepAliveRefCount() override; + void DecrementKeepAliveRefCount() override; + void DisableKeepAliveRefCount() override; + bool IsKeepAliveRefCountDisabled() override; void PurgeAndSuspend() override; void Resume() override; mojom::Renderer* GetRendererInterface() override; @@ -373,6 +373,9 @@ // globally-used spare RenderProcessHost at any time. static RenderProcessHost* GetSpareRenderProcessHostForTesting(); + // Test-only method to get the importance of this process. + ChildProcessImportance GetWidgetImportanceForTesting(); + protected: // A proxy for our IPC::Channel that lives on the IO thread. std::unique_ptr<IPC::ChannelProxy> channel_; @@ -467,6 +470,9 @@ // change. void UpdateProcessPriority(); + // Helper method to compute importance from |widget_importance_counts_|. + ChildProcessImportance ComputeEffectiveImportance(); + // Creates a PersistentMemoryAllocator and shares it with the renderer // process for it to store histograms from that process. The allocator is // available for extraction by a SubprocesMetricsProvider in order to @@ -547,16 +553,11 @@ scoped_refptr<ConnectionFilterController> connection_filter_controller_; service_manager::mojom::ServicePtr test_service_; - // The number of service workers running in this process. - size_t service_worker_ref_count_; - // See comments for IncrementSharedWorkerRefCount() and - // DecrementSharedWorkerRefCount(). This is more like a boolean flag and not - // actually the number of shared workers running in this process. - size_t shared_worker_ref_count_; + size_t keep_alive_ref_count_; - // Set in ForceReleaseWorkerRefCounts. When true, worker ref counts must no - // longer be modified. - bool is_worker_ref_count_disabled_; + // Set in DisableKeepAliveRefCount(). When true, |keep_alive_ref_count_| must + // no longer be modified. + bool is_keep_alive_ref_count_disabled_; // Whether this host is never suitable for reuse as determined in the // MayReuseHost() function. @@ -580,6 +581,16 @@ // backgrounded. int32_t visible_widgets_; + // Track count of number of widgets with each possible ChildProcessImportance + // value. + int32_t widget_importance_counts_[static_cast<size_t>( + ChildProcessImportance::COUNT)] = {0}; + + // Highest importance of any widget in the process. Note this is the + // importance last passed to |child_process_launcher_|, which means this may + // be out of date in comparison to |widget_importance_counts_|. + ChildProcessImportance effective_importance_ = ChildProcessImportance::NORMAL; + // The set of widgets in this RenderProcessHostImpl. std::set<RenderWidgetHostImpl*> widgets_; @@ -703,7 +714,7 @@ scoped_refptr<PeerConnectionTrackerHost> peer_connection_tracker_host_; // Records the time when the process starts surviving for workers for UMA. - base::TimeTicks survive_for_worker_start_time_; + base::TimeTicks keep_alive_start_time_; // Context shared for each mojom::PermissionService instance created for this // RPH.
diff --git a/content/browser/renderer_host/render_view_host_impl.h b/content/browser/renderer_host/render_view_host_impl.h index 7e0cc57..d9667c32 100644 --- a/content/browser/renderer_host/render_view_host_impl.h +++ b/content/browser/renderer_host/render_view_host_impl.h
@@ -294,8 +294,8 @@ // Tracks whether the main frame RenderFrameHost is swapped out. Unlike // is_active_, this is false when the frame is pending swap out or deletion. - // TODO(creis): Remove this when we no longer use swappedout://. - // See http://crbug.com/357747. + // TODO(creis): Remove this when we no longer filter IPCs after swap out. + // See https://crbug.com/745091. bool is_swapped_out_; // Routing ID for the main frame's RenderFrameHost.
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc index 4d07580..ce10061c 100644 --- a/content/browser/renderer_host/render_widget_host_impl.cc +++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -675,6 +675,14 @@ WasResized(); } +void RenderWidgetHostImpl::SetImportance(ChildProcessImportance importance) { + if (importance_ == importance) + return; + ChildProcessImportance old = importance_; + importance_ = importance; + process_->UpdateWidgetImportance(old, importance_); +} + bool RenderWidgetHostImpl::GetResizeParams(ResizeParams* resize_params) { *resize_params = ResizeParams();
diff --git a/content/browser/renderer_host/render_widget_host_impl.h b/content/browser/renderer_host/render_widget_host_impl.h index 52b5fa9..3d60d50 100644 --- a/content/browser/renderer_host/render_widget_host_impl.h +++ b/content/browser/renderer_host/render_widget_host_impl.h
@@ -28,6 +28,7 @@ #include "components/viz/common/quads/shared_bitmap.h" #include "components/viz/common/surfaces/frame_sink_id.h" #include "components/viz/service/display_embedder/shared_bitmap_allocation_notifier_impl.h" +#include "content/browser/child_process_importance.h" #include "content/browser/renderer_host/event_with_latency_info.h" #include "content/browser/renderer_host/input/input_disposition_handler.h" #include "content/browser/renderer_host/input/input_router_client.h" @@ -105,9 +106,9 @@ public InputRouterClient, public InputDispositionHandler, public TouchEmulatorClient, - public NON_EXPORTED_BASE(SyntheticGestureController::Delegate), - public NON_EXPORTED_BASE(viz::mojom::CompositorFrameSink), - public NON_EXPORTED_BASE(viz::SharedBitmapAllocationObserver), + public SyntheticGestureController::Delegate, + public viz::mojom::CompositorFrameSink, + public viz::SharedBitmapAllocationObserver, public IPC::Listener { public: // |routing_id| must not be MSG_ROUTING_NONE. @@ -275,6 +276,11 @@ void WasHidden(); void WasShown(const ui::LatencyInfo& latency_info); + // Set the importance of widget. The importance is passed onto + // RenderProcessHost which aggregates importance of all of its widgets. + void SetImportance(ChildProcessImportance importance); + ChildProcessImportance importance() const { return importance_; } + // Returns true if the RenderWidget is hidden. bool is_hidden() const { return is_hidden_; } @@ -800,6 +806,10 @@ // most recent call to process_->WidgetRestored() / WidgetHidden(). bool is_hidden_; + // Tracks the current importance of widget, so the old value can be passed to + // RenderProcessHost on changes. + ChildProcessImportance importance_ = ChildProcessImportance::NORMAL; + // Set if we are waiting for a repaint ack for the view. bool repaint_ack_pending_;
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.h b/content/browser/renderer_host/render_widget_host_view_aura.h index 910d321..097ebbc 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.h +++ b/content/browser/renderer_host/render_widget_host_view_aura.h
@@ -79,7 +79,7 @@ // RenderWidgetHostView class hierarchy described in render_widget_host_view.h. class CONTENT_EXPORT RenderWidgetHostViewAura : public RenderWidgetHostViewBase, - NON_EXPORTED_BASE(public RenderWidgetHostViewEventHandler::Delegate), + public RenderWidgetHostViewEventHandler::Delegate, public TextInputManager::Observer, public ui::TextInputClient, public display::DisplayObserver,
diff --git a/content/browser/renderer_host/render_widget_host_view_mac.mm b/content/browser/renderer_host/render_widget_host_view_mac.mm index d61f81f..640c1312 100644 --- a/content/browser/renderer_host/render_widget_host_view_mac.mm +++ b/content/browser/renderer_host/render_widget_host_view_mac.mm
@@ -2597,6 +2597,23 @@ // cancels the gesture, all remaining touches are forwarded to the content // scroll logic. The user cannot trigger the navigation logic again. - (void)scrollWheel:(NSEvent*)event { +#if defined(MAC_OS_X_VERSION_10_11) && \ + MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_11 + // When linking against the 10.11 (or later) SDK and running on 10.11 or + // later, check the phase of the event and specially handle the "begin" and + // "end" phases. + if (base::mac::IsAtLeastOS10_11()) { + if (event.phase == NSEventPhaseBegan) { + [self handleBeginGestureWithEvent:event]; + } + + if (event.phase == NSEventPhaseEnded || + event.phase == NSEventPhaseCancelled) { + [self handleEndGestureWithEvent:event]; + } + } +#endif + if (responderDelegate_ && [responderDelegate_ respondsToSelector:@selector(handleEvent:)]) { BOOL handled = [responderDelegate_ handleEvent:event];
diff --git a/content/browser/screen_orientation/screen_orientation_provider.h b/content/browser/screen_orientation/screen_orientation_provider.h index f525e0e..1f2b7c7c 100644 --- a/content/browser/screen_orientation/screen_orientation_provider.h +++ b/content/browser/screen_orientation/screen_orientation_provider.h
@@ -24,7 +24,7 @@ // Handles screen orientation lock/unlock. Platforms which wish to provide // custom implementations can provide a factory for ScreenOrientationDelegate. class CONTENT_EXPORT ScreenOrientationProvider - : NON_EXPORTED_BASE(public device::mojom::ScreenOrientation), + : public device::mojom::ScreenOrientation, public WebContentsObserver { public: ScreenOrientationProvider(WebContents* web_contents);
diff --git a/content/browser/service_worker/embedded_worker_instance.cc b/content/browser/service_worker/embedded_worker_instance.cc index d753d64..2e7cb1ab 100644 --- a/content/browser/service_worker/embedded_worker_instance.cc +++ b/content/browser/service_worker/embedded_worker_instance.cc
@@ -195,32 +195,30 @@ ~DevToolsProxy() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - BrowserThread::PostTask( - BrowserThread::UI, - FROM_HERE, - base::Bind(NotifyWorkerDestroyedOnUI, - process_id_, agent_route_id_)); + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, + base::BindOnce(NotifyWorkerDestroyedOnUI, + process_id_, agent_route_id_)); } void NotifyWorkerReadyForInspection() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, - base::Bind(NotifyWorkerReadyForInspectionOnUI, - process_id_, agent_route_id_)); + base::BindOnce(NotifyWorkerReadyForInspectionOnUI, + process_id_, agent_route_id_)); } void NotifyWorkerVersionInstalled() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, - base::Bind(NotifyWorkerVersionInstalledOnUI, - process_id_, agent_route_id_)); + base::BindOnce(NotifyWorkerVersionInstalledOnUI, + process_id_, agent_route_id_)); } void NotifyWorkerVersionDoomed() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, - base::Bind(NotifyWorkerVersionDoomedOnUI, - process_id_, agent_route_id_)); + base::BindOnce(NotifyWorkerVersionDoomedOnUI, + process_id_, agent_route_id_)); } bool ShouldNotifyWorkerStopIgnored() const { @@ -514,7 +512,7 @@ mojom::EmbeddedWorkerInstanceClientRequest request = mojo::MakeRequest(&client_); client_.set_connection_error_handler( - base::Bind(&CallDetach, base::Unretained(this))); + base::BindOnce(&CallDetach, base::Unretained(this))); pending_dispatcher_request_ = std::move(dispatcher_request); pending_installed_scripts_info_ = std::move(installed_scripts_info);
diff --git a/content/browser/service_worker/embedded_worker_instance.h b/content/browser/service_worker/embedded_worker_instance.h index c102e91..64d1aa24 100644 --- a/content/browser/service_worker/embedded_worker_instance.h +++ b/content/browser/service_worker/embedded_worker_instance.h
@@ -50,7 +50,7 @@ // // Owned by ServiceWorkerVersion. Lives on the IO thread. class CONTENT_EXPORT EmbeddedWorkerInstance - : NON_EXPORTED_BASE(public mojom::EmbeddedWorkerInstanceHost) { + : public mojom::EmbeddedWorkerInstanceHost { public: class DevToolsProxy; typedef base::Callback<void(ServiceWorkerStatusCode)> StatusCallback;
diff --git a/content/browser/service_worker/embedded_worker_registry.h b/content/browser/service_worker/embedded_worker_registry.h index 897d23b..5cb89a86 100644 --- a/content/browser/service_worker/embedded_worker_registry.h +++ b/content/browser/service_worker/embedded_worker_registry.h
@@ -34,7 +34,7 @@ // Hangs off ServiceWorkerContextCore (its reference is also held by each // EmbeddedWorkerInstance). Operated only on IO thread. class CONTENT_EXPORT EmbeddedWorkerRegistry - : public NON_EXPORTED_BASE(base::RefCounted<EmbeddedWorkerRegistry>) { + : public base::RefCounted<EmbeddedWorkerRegistry> { public: static scoped_refptr<EmbeddedWorkerRegistry> Create( const base::WeakPtr<ServiceWorkerContextCore>& contxet);
diff --git a/content/browser/service_worker/embedded_worker_test_helper.cc b/content/browser/service_worker/embedded_worker_test_helper.cc index ae990c7..dd00a03 100644 --- a/content/browser/service_worker/embedded_worker_test_helper.cc +++ b/content/browser/service_worker/embedded_worker_test_helper.cc
@@ -143,7 +143,7 @@ } class EmbeddedWorkerTestHelper::MockServiceWorkerEventDispatcher - : public NON_EXPORTED_BASE(mojom::ServiceWorkerEventDispatcher) { + : public mojom::ServiceWorkerEventDispatcher { public: static void Create(const base::WeakPtr<EmbeddedWorkerTestHelper>& helper, int thread_id, @@ -686,11 +686,12 @@ EXPECT_EQ(EmbeddedWorkerStatus::STARTING, worker->status()); base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, - base::Bind(&EmbeddedWorkerTestHelper::OnStartWorker, AsWeakPtr(), - params.embedded_worker_id, params.service_worker_version_id, - params.scope, params.script_url, params.pause_after_download, - base::Passed(&request), base::Passed(&instance_host), - base::Passed(&provider_info))); + base::BindOnce(&EmbeddedWorkerTestHelper::OnStartWorker, AsWeakPtr(), + params.embedded_worker_id, + params.service_worker_version_id, params.scope, + params.script_url, params.pause_after_download, + base::Passed(&request), base::Passed(&instance_host), + base::Passed(&provider_info))); } void EmbeddedWorkerTestHelper::OnResumeAfterDownloadStub( @@ -698,14 +699,15 @@ EmbeddedWorkerInstance* worker = registry()->GetWorker(embedded_worker_id); ASSERT_TRUE(worker); base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(&EmbeddedWorkerTestHelper::OnResumeAfterDownload, - AsWeakPtr(), embedded_worker_id)); + FROM_HERE, + base::BindOnce(&EmbeddedWorkerTestHelper::OnResumeAfterDownload, + AsWeakPtr(), embedded_worker_id)); } void EmbeddedWorkerTestHelper::OnStopWorkerStub(int embedded_worker_id) { base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(&EmbeddedWorkerTestHelper::OnStopWorker, - AsWeakPtr(), embedded_worker_id)); + FROM_HERE, base::BindOnce(&EmbeddedWorkerTestHelper::OnStopWorker, + AsWeakPtr(), embedded_worker_id)); } void EmbeddedWorkerTestHelper::OnMessageToWorkerStub( @@ -721,8 +723,8 @@ mojom::ServiceWorkerEventDispatcher::DispatchActivateEventCallback callback) { base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(&EmbeddedWorkerTestHelper::OnActivateEvent, - AsWeakPtr(), base::Passed(&callback))); + FROM_HERE, base::BindOnce(&EmbeddedWorkerTestHelper::OnActivateEvent, + AsWeakPtr(), base::Passed(&callback))); } void EmbeddedWorkerTestHelper::OnBackgroundFetchAbortEventStub( @@ -731,8 +733,8 @@ DispatchBackgroundFetchAbortEventCallback callback) { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, - base::Bind(&EmbeddedWorkerTestHelper::OnBackgroundFetchAbortEvent, - AsWeakPtr(), tag, base::Passed(&callback))); + base::BindOnce(&EmbeddedWorkerTestHelper::OnBackgroundFetchAbortEvent, + AsWeakPtr(), tag, base::Passed(&callback))); } void EmbeddedWorkerTestHelper::OnBackgroundFetchClickEventStub( @@ -742,8 +744,8 @@ DispatchBackgroundFetchClickEventCallback callback) { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, - base::Bind(&EmbeddedWorkerTestHelper::OnBackgroundFetchClickEvent, - AsWeakPtr(), tag, state, base::Passed(&callback))); + base::BindOnce(&EmbeddedWorkerTestHelper::OnBackgroundFetchClickEvent, + AsWeakPtr(), tag, state, base::Passed(&callback))); } void EmbeddedWorkerTestHelper::OnBackgroundFetchFailEventStub( @@ -753,8 +755,8 @@ DispatchBackgroundFetchFailEventCallback callback) { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, - base::Bind(&EmbeddedWorkerTestHelper::OnBackgroundFetchFailEvent, - AsWeakPtr(), tag, fetches, base::Passed(&callback))); + base::BindOnce(&EmbeddedWorkerTestHelper::OnBackgroundFetchFailEvent, + AsWeakPtr(), tag, fetches, base::Passed(&callback))); } void EmbeddedWorkerTestHelper::OnBackgroundFetchedEventStub( @@ -764,8 +766,8 @@ callback) { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, - base::Bind(&EmbeddedWorkerTestHelper::OnBackgroundFetchedEvent, - AsWeakPtr(), tag, fetches, base::Passed(&callback))); + base::BindOnce(&EmbeddedWorkerTestHelper::OnBackgroundFetchedEvent, + AsWeakPtr(), tag, fetches, base::Passed(&callback))); } void EmbeddedWorkerTestHelper::OnExtendableMessageEventStub( @@ -774,8 +776,9 @@ callback) { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, - base::Bind(&EmbeddedWorkerTestHelper::OnExtendableMessageEvent, - AsWeakPtr(), base::Passed(&event), base::Passed(&callback))); + base::BindOnce(&EmbeddedWorkerTestHelper::OnExtendableMessageEvent, + AsWeakPtr(), base::Passed(&event), + base::Passed(&callback))); } void EmbeddedWorkerTestHelper::OnInstallEventStub( @@ -784,8 +787,8 @@ callback) { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, - base::Bind(&EmbeddedWorkerTestHelper::OnInstallEvent, AsWeakPtr(), - base::Passed(&client), base::Passed(&callback))); + base::BindOnce(&EmbeddedWorkerTestHelper::OnInstallEvent, AsWeakPtr(), + base::Passed(&client), base::Passed(&callback))); } void EmbeddedWorkerTestHelper::OnFetchEventStub( @@ -797,11 +800,11 @@ FetchCallback finish_callback) { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, - base::Bind(&EmbeddedWorkerTestHelper::OnFetchEvent, AsWeakPtr(), - thread_id_embedded_worker_id_map_[thread_id], fetch_event_id, - request, base::Passed(&preload_handle), - base::Passed(&response_callback), - base::Passed(&finish_callback))); + base::BindOnce(&EmbeddedWorkerTestHelper::OnFetchEvent, AsWeakPtr(), + thread_id_embedded_worker_id_map_[thread_id], + fetch_event_id, request, base::Passed(&preload_handle), + base::Passed(&response_callback), + base::Passed(&finish_callback))); } void EmbeddedWorkerTestHelper::OnNotificationClickEventStub( @@ -812,9 +815,10 @@ mojom::ServiceWorkerEventDispatcher::DispatchNotificationClickEventCallback callback) { base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(&EmbeddedWorkerTestHelper::OnNotificationClickEvent, - AsWeakPtr(), notification_id, notification_data, - action_index, reply, base::Passed(&callback))); + FROM_HERE, + base::BindOnce(&EmbeddedWorkerTestHelper::OnNotificationClickEvent, + AsWeakPtr(), notification_id, notification_data, + action_index, reply, base::Passed(&callback))); } void EmbeddedWorkerTestHelper::OnNotificationCloseEventStub( @@ -823,17 +827,18 @@ mojom::ServiceWorkerEventDispatcher::DispatchNotificationCloseEventCallback callback) { base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(&EmbeddedWorkerTestHelper::OnNotificationCloseEvent, - AsWeakPtr(), notification_id, notification_data, - base::Passed(&callback))); + FROM_HERE, + base::BindOnce(&EmbeddedWorkerTestHelper::OnNotificationCloseEvent, + AsWeakPtr(), notification_id, notification_data, + base::Passed(&callback))); } void EmbeddedWorkerTestHelper::OnPushEventStub( const PushEventPayload& payload, mojom::ServiceWorkerEventDispatcher::DispatchPushEventCallback callback) { base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(&EmbeddedWorkerTestHelper::OnPushEvent, AsWeakPtr(), - payload, base::Passed(&callback))); + FROM_HERE, base::BindOnce(&EmbeddedWorkerTestHelper::OnPushEvent, + AsWeakPtr(), payload, base::Passed(&callback))); } void EmbeddedWorkerTestHelper::OnAbortPaymentEventStub( @@ -841,9 +846,9 @@ mojom::ServiceWorkerEventDispatcher::DispatchAbortPaymentEventCallback callback) { base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, - base::Bind(&EmbeddedWorkerTestHelper::OnAbortPaymentEvent, AsWeakPtr(), - base::Passed(&response_callback), base::Passed(&callback))); + FROM_HERE, base::BindOnce(&EmbeddedWorkerTestHelper::OnAbortPaymentEvent, + AsWeakPtr(), base::Passed(&response_callback), + base::Passed(&callback))); } void EmbeddedWorkerTestHelper::OnCanMakePaymentEventStub( @@ -853,9 +858,10 @@ callback) { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, - base::Bind(&EmbeddedWorkerTestHelper::OnCanMakePaymentEvent, AsWeakPtr(), - base::Passed(&event_data), base::Passed(&response_callback), - base::Passed(&callback))); + base::BindOnce(&EmbeddedWorkerTestHelper::OnCanMakePaymentEvent, + AsWeakPtr(), base::Passed(&event_data), + base::Passed(&response_callback), + base::Passed(&callback))); } void EmbeddedWorkerTestHelper::OnPaymentRequestEventStub( @@ -865,9 +871,10 @@ callback) { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, - base::Bind(&EmbeddedWorkerTestHelper::OnPaymentRequestEvent, AsWeakPtr(), - base::Passed(&event_data), base::Passed(&response_callback), - base::Passed(&callback))); + base::BindOnce(&EmbeddedWorkerTestHelper::OnPaymentRequestEvent, + AsWeakPtr(), base::Passed(&event_data), + base::Passed(&response_callback), + base::Passed(&callback))); } EmbeddedWorkerRegistry* EmbeddedWorkerTestHelper::registry() {
diff --git a/content/browser/service_worker/service_worker_browsertest.cc b/content/browser/service_worker/service_worker_browsertest.cc index b860847..0433019 100644 --- a/content/browser/service_worker/service_worker_browsertest.cc +++ b/content/browser/service_worker/service_worker_browsertest.cc
@@ -107,8 +107,8 @@ base::RunLoop run_loop; BrowserThread::PostDelayedTask( BrowserThread::IO, FROM_HERE, - base::Bind(&RunAndQuit, closure, run_loop.QuitClosure(), - base::RetainedRef(base::ThreadTaskRunnerHandle::Get())), + base::BindOnce(&RunAndQuit, closure, run_loop.QuitClosure(), + base::RetainedRef(base::ThreadTaskRunnerHandle::Get())), delay); run_loop.Run(); } @@ -125,9 +125,8 @@ base::ThreadTaskRunnerHandle::Get().get(), FROM_HERE, run_loop.QuitClosure()); - BrowserThread::PostTask(BrowserThread::IO, - FROM_HERE, - base::Bind(closure, quit_on_original_thread)); + BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, + base::BindOnce(closure, quit_on_original_thread)); run_loop.Run(); } @@ -190,9 +189,9 @@ const ServiceWorkerVersion* version = context_->GetLiveVersion(version_id); if (version->status() == ServiceWorkerVersion::ACTIVATED) { context_->RemoveObserver(this); - BrowserThread::PostTask(BrowserThread::UI, - FROM_HERE, - base::Bind(&WorkerActivatedObserver::Quit, this)); + BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, + base::BindOnce(&WorkerActivatedObserver::Quit, this)); } } void Wait() { run_loop_.Run(); } @@ -485,8 +484,8 @@ DCHECK_CURRENTLY_ON(BrowserThread::IO); BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, - base::Bind(&ConsoleListener::OnReportConsoleMessageOnUI, - base::Unretained(this), message)); + base::BindOnce(&ConsoleListener::OnReportConsoleMessageOnUI, + base::Unretained(this), message)); } void WaitForConsoleMessages(size_t expected_message_count) { @@ -587,8 +586,8 @@ base::RunLoop install_run_loop; BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, - base::Bind(&self::InstallOnIOThread, base::Unretained(this), - install_run_loop.QuitClosure(), &status)); + base::BindOnce(&self::InstallOnIOThread, base::Unretained(this), + install_run_loop.QuitClosure(), &status)); install_run_loop.Run(); ASSERT_EQ(expected_status, status); @@ -597,8 +596,8 @@ base::RunLoop stop_run_loop; BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, - base::Bind(&self::StopOnIOThread, base::Unretained(this), - stop_run_loop.QuitClosure(), &status)); + base::BindOnce(&self::StopOnIOThread, base::Unretained(this), + stop_run_loop.QuitClosure(), &status)); stop_run_loop.Run(); ASSERT_EQ(SERVICE_WORKER_OK, status); } @@ -610,8 +609,8 @@ base::RunLoop run_loop; BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, - base::Bind(&self::ActivateOnIOThread, base::Unretained(this), - run_loop.QuitClosure(), &status)); + base::BindOnce(&self::ActivateOnIOThread, base::Unretained(this), + run_loop.QuitClosure(), &status)); run_loop.Run(); ASSERT_EQ(expected_status, status); } @@ -628,9 +627,9 @@ base::RunLoop fetch_run_loop; BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, - base::Bind(&self::FetchOnIOThread, base::Unretained(this), - fetch_run_loop.QuitClosure(), &prepare_result, - &fetch_result)); + base::BindOnce(&self::FetchOnIOThread, base::Unretained(this), + fetch_run_loop.QuitClosure(), &prepare_result, + &fetch_result)); fetch_run_loop.Run(); ASSERT_TRUE(prepare_result); *result = fetch_result.result; @@ -704,8 +703,8 @@ base::RunLoop start_run_loop; BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, - base::Bind(&self::StartOnIOThread, base::Unretained(this), - start_run_loop.QuitClosure(), &status)); + base::BindOnce(&self::StartOnIOThread, base::Unretained(this), + start_run_loop.QuitClosure(), &status)); start_run_loop.Run(); ASSERT_EQ(expected_status, status); } @@ -716,8 +715,8 @@ base::RunLoop stop_run_loop; BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, - base::Bind(&self::StopOnIOThread, base::Unretained(this), - stop_run_loop.QuitClosure(), &status)); + base::BindOnce(&self::StopOnIOThread, base::Unretained(this), + stop_run_loop.QuitClosure(), &status)); stop_run_loop.Run(); ASSERT_EQ(expected_status, status); } @@ -729,8 +728,8 @@ base::RunLoop store_run_loop; BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, - base::Bind(&self::StoreOnIOThread, base::Unretained(this), - store_run_loop.QuitClosure(), &status, version_id)); + base::BindOnce(&self::StoreOnIOThread, base::Unretained(this), + store_run_loop.QuitClosure(), &status, version_id)); store_run_loop.Run(); ASSERT_EQ(expected_status, status); @@ -746,9 +745,9 @@ base::RunLoop run_loop; BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, - base::Bind(&self::FindRegistrationForIdOnIOThread, - base::Unretained(this), run_loop.QuitClosure(), &status, id, - origin)); + base::BindOnce(&self::FindRegistrationForIdOnIOThread, + base::Unretained(this), run_loop.QuitClosure(), &status, + id, origin)); run_loop.Run(); ASSERT_EQ(expected_status, status); } @@ -804,8 +803,8 @@ mojo::MakeRequest(&ptr_info); version_->event_dispatcher()->DispatchInstallEvent( std::move(ptr_info), - base::Bind(&self::ReceiveInstallEventOnIOThread, base::Unretained(this), - done, result, request_id)); + base::BindOnce(&self::ReceiveInstallEventOnIOThread, + base::Unretained(this), done, result, request_id)); } void ReceiveInstallEventOnIOThread(const base::Closure& done, @@ -937,8 +936,8 @@ base::RunLoop start_run_loop; BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, - base::Bind(&self::StartOnIOThread, base::Unretained(this), - start_run_loop.QuitClosure(), &status)); + base::BindOnce(&self::StartOnIOThread, base::Unretained(this), + start_run_loop.QuitClosure(), &status)); start_run_loop.Run(); ASSERT_EQ(SERVICE_WORKER_OK, status); @@ -947,8 +946,8 @@ base::RunLoop stop_run_loop; BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, - base::Bind(&self::StopOnIOThread, base::Unretained(this), - stop_run_loop.QuitClosure(), &status)); + base::BindOnce(&self::StopOnIOThread, base::Unretained(this), + stop_run_loop.QuitClosure(), &status)); stop_run_loop.Run(); ASSERT_EQ(SERVICE_WORKER_OK, status); } @@ -1121,8 +1120,8 @@ base::RunLoop install_run_loop; BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, - base::Bind(&self::InstallOnIOThread, base::Unretained(this), - install_run_loop.QuitClosure(), &status)); + base::BindOnce(&self::InstallOnIOThread, base::Unretained(this), + install_run_loop.QuitClosure(), &status)); install_run_loop.Run(); ASSERT_EQ(SERVICE_WORKER_ERROR_EVENT_WAITUNTIL_REJECTED, status); @@ -1166,8 +1165,8 @@ &wait_for_load)); BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, - base::Bind(&self::StartOnIOThread, base::Unretained(this), - start_run_loop.QuitClosure(), &status)); + base::BindOnce(&self::StartOnIOThread, base::Unretained(this), + start_run_loop.QuitClosure(), &status)); load_run_loop.Run(); RunOnIOThread(base::Bind(&EmbeddedWorkerInstance::RemoveListener, base::Unretained(version_->embedded_worker()), @@ -1198,8 +1197,8 @@ base::RunLoop start_run_loop; BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, - base::Bind(&self::StartOnIOThread, base::Unretained(this), - start_run_loop.QuitClosure(), &status)); + base::BindOnce(&self::StartOnIOThread, base::Unretained(this), + start_run_loop.QuitClosure(), &status)); start_run_loop.Run(); ASSERT_EQ(SERVICE_WORKER_OK, status); @@ -1207,8 +1206,8 @@ base::RunLoop install_run_loop; BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, - base::Bind(&self::InstallOnIOThread, base::Unretained(this), - install_run_loop.QuitClosure(), &status)); + base::BindOnce(&self::InstallOnIOThread, base::Unretained(this), + install_run_loop.QuitClosure(), &status)); // Simulate execution timeout. Use a delay to prevent killing the worker // before it's started execution. @@ -2622,8 +2621,9 @@ void OpenCacheOnIOThread(int* result, const base::Closure& continuation) { cache_storage_context_->cache_manager()->OpenCache( - origin_, cache_name_, base::Bind(&self::OnCacheStorageOpenCallback, - this, result, continuation)); + origin_, cache_name_, + base::BindOnce(&self::OnCacheStorageOpenCallback, this, result, + continuation)); } void OnCacheStorageOpenCallback( @@ -2638,8 +2638,8 @@ CacheStorageCache* cache = cache_handle->value(); cache->Match( std::move(scoped_request), CacheStorageCacheQueryParams(), - base::Bind(&self::OnCacheStorageCacheMatchCallback, this, result, - continuation, base::Passed(std::move(cache_handle)))); + base::BindOnce(&self::OnCacheStorageCacheMatchCallback, this, result, + continuation, base::Passed(std::move(cache_handle)))); } void OnCacheStorageCacheMatchCallback(
diff --git a/content/browser/service_worker/service_worker_client_utils.cc b/content/browser/service_worker/service_worker_client_utils.cc index 3a9318b..7154406 100644 --- a/content/browser/service_worker/service_worker_client_utils.cc +++ b/content/browser/service_worker/service_worker_client_utils.cc
@@ -94,7 +94,7 @@ BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, - base::Bind(callback_, render_process_id, render_frame_id)); + base::BindOnce(callback_, render_process_id, render_frame_id)); Observe(nullptr); base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this); } @@ -165,8 +165,8 @@ if (!web_contents) { BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, - base::Bind(callback, ChildProcessHost::kInvalidUniqueID, - MSG_ROUTING_NONE)); + base::BindOnce(callback, ChildProcessHost::kInvalidUniqueID, + MSG_ROUTING_NONE)); return; } @@ -205,8 +205,8 @@ if (render_process_host->IsForGuestsOnly()) { BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, - base::Bind(callback, ChildProcessHost::kInvalidUniqueID, - MSG_ROUTING_NONE)); + base::BindOnce(callback, ChildProcessHost::kInvalidUniqueID, + MSG_ROUTING_NONE)); return; } @@ -234,8 +234,8 @@ if (!rfhi || !web_contents) { BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, - base::Bind(callback, ChildProcessHost::kInvalidUniqueID, - MSG_ROUTING_NONE)); + base::BindOnce(callback, ChildProcessHost::kInvalidUniqueID, + MSG_ROUTING_NONE)); return; } @@ -355,7 +355,7 @@ } BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, - base::Bind(callback, base::Passed(&clients))); + base::BindOnce(callback, base::Passed(&clients))); } struct ServiceWorkerClientInfoSort { @@ -446,7 +446,7 @@ BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, - base::Bind( + base::BindOnce( &OnGetWindowClientsOnUI, clients_info, controller->script_url(), base::Bind(&DidGetWindowClients, controller, options, callback), base::Passed(&clients))); @@ -476,7 +476,7 @@ DCHECK_CURRENTLY_ON(BrowserThread::IO); BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, - base::Bind( + base::BindOnce( &OpenWindowOnUI, url, script_url, worker_process_id, make_scoped_refptr(context->wrapper()), disposition, base::Bind(&DidNavigate, context, script_url.GetOrigin(), callback))); @@ -491,7 +491,7 @@ DCHECK_CURRENTLY_ON(BrowserThread::IO); BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, - base::Bind( + base::BindOnce( &NavigateClientOnUI, url, script_url, process_id, frame_id, base::Bind(&DidNavigate, context, script_url.GetOrigin(), callback))); } @@ -523,7 +523,7 @@ base::TimeTicks(), provider_host->create_time(), provider_host->client_type()); BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, - base::Bind(callback, client_info)); + base::BindOnce(callback, client_info)); } void GetClients(const base::WeakPtr<ServiceWorkerVersion>& controller,
diff --git a/content/browser/service_worker/service_worker_context_core.cc b/content/browser/service_worker/service_worker_context_core.cc index 192fb408..9637087 100644 --- a/content/browser/service_worker/service_worker_context_core.cc +++ b/content/browser/service_worker/service_worker_context_core.cc
@@ -372,8 +372,8 @@ providers_.get(), base::Bind(IsSameOriginWindowProviderHost, origin)); if (provider_host_iterator.IsAtEnd()) { - base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, - base::Bind(callback, false)); + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(callback, false)); return; } @@ -487,9 +487,8 @@ } bool* overall_success = new bool(true); base::Closure barrier = base::BarrierClosure( - scopes.size(), - base::Bind( - &SuccessReportingCallback, base::Owned(overall_success), result)); + scopes.size(), base::BindOnce(&SuccessReportingCallback, + base::Owned(overall_success), result)); for (const GURL& scope : scopes) { UnregisterServiceWorker( @@ -666,7 +665,8 @@ storage_->Disable(); base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, - base::Bind(&ServiceWorkerContextWrapper::DeleteAndStartOver, wrapper_)); + base::BindOnce(&ServiceWorkerContextWrapper::DeleteAndStartOver, + wrapper_)); } void ServiceWorkerContextCore::DeleteAndStartOver(
diff --git a/content/browser/service_worker/service_worker_context_core.h b/content/browser/service_worker/service_worker_context_core.h index 29dcfc4..672e4d4 100644 --- a/content/browser/service_worker/service_worker_context_core.h +++ b/content/browser/service_worker/service_worker_context_core.h
@@ -58,7 +58,7 @@ // is the root of the containment hierarchy for service worker data // associated with a particular partition. class CONTENT_EXPORT ServiceWorkerContextCore - : NON_EXPORTED_BASE(public ServiceWorkerVersion::Listener) { + : public ServiceWorkerVersion::Listener { public: using BoolCallback = base::Callback<void(bool)>; using StatusCallback = base::Callback<void(ServiceWorkerStatusCode status)>;
diff --git a/content/browser/service_worker/service_worker_context_wrapper.cc b/content/browser/service_worker/service_worker_context_wrapper.cc index 5ca5bcb..7260627 100644 --- a/content/browser/service_worker/service_worker_context_wrapper.cc +++ b/content/browser/service_worker/service_worker_context_wrapper.cc
@@ -52,7 +52,7 @@ ServiceWorkerStatusCode status) { DCHECK_CURRENTLY_ON(BrowserThread::IO); BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, - base::Bind(callback, status)); + base::BindOnce(callback, status)); } void StartActiveWorkerOnIO( @@ -69,8 +69,9 @@ base::Bind(WorkerStarted, callback)); return; } - BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, - base::Bind(callback, SERVICE_WORKER_ERROR_NOT_FOUND)); + BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, + base::BindOnce(callback, SERVICE_WORKER_ERROR_NOT_FOUND)); } void SkipWaitingWorkerOnIO( @@ -210,9 +211,8 @@ storage_partition_ = nullptr; process_manager_->Shutdown(); BrowserThread::PostTask( - BrowserThread::IO, - FROM_HERE, - base::Bind(&ServiceWorkerContextWrapper::ShutdownOnIO, this)); + BrowserThread::IO, FROM_HERE, + base::BindOnce(&ServiceWorkerContextWrapper::ShutdownOnIO, this)); } void ServiceWorkerContextWrapper::InitializeResourceContext( @@ -256,9 +256,8 @@ int64_t registration_id) { DCHECK_CURRENTLY_ON(BrowserThread::IO); BrowserThread::PostTask( - BrowserThread::UI, - FROM_HERE, - base::Bind(continuation, status == SERVICE_WORKER_OK)); + BrowserThread::UI, FROM_HERE, + base::BindOnce(continuation, status == SERVICE_WORKER_OK)); } void ServiceWorkerContextWrapper::RegisterServiceWorker( @@ -267,18 +266,14 @@ const ResultCallback& continuation) { if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { BrowserThread::PostTask( - BrowserThread::IO, - FROM_HERE, - base::Bind(&ServiceWorkerContextWrapper::RegisterServiceWorker, - this, - pattern, - script_url, - continuation)); + BrowserThread::IO, FROM_HERE, + base::BindOnce(&ServiceWorkerContextWrapper::RegisterServiceWorker, + this, pattern, script_url, continuation)); return; } if (!context_core_) { BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, - base::Bind(continuation, false)); + base::BindOnce(continuation, false)); return; } ServiceWorkerRegistrationOptions options(net::SimplifyUrlForRequest(pattern)); @@ -293,9 +288,8 @@ ServiceWorkerStatusCode status) { DCHECK_CURRENTLY_ON(BrowserThread::IO); BrowserThread::PostTask( - BrowserThread::UI, - FROM_HERE, - base::Bind(continuation, status == SERVICE_WORKER_OK)); + BrowserThread::UI, FROM_HERE, + base::BindOnce(continuation, status == SERVICE_WORKER_OK)); } void ServiceWorkerContextWrapper::UnregisterServiceWorker( @@ -303,17 +297,14 @@ const ResultCallback& continuation) { if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { BrowserThread::PostTask( - BrowserThread::IO, - FROM_HERE, - base::Bind(&ServiceWorkerContextWrapper::UnregisterServiceWorker, - this, - pattern, - continuation)); + BrowserThread::IO, FROM_HERE, + base::BindOnce(&ServiceWorkerContextWrapper::UnregisterServiceWorker, + this, pattern, continuation)); return; } if (!context_core_) { BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, - base::Bind(continuation, false)); + base::BindOnce(continuation, false)); return; } @@ -326,8 +317,8 @@ if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, - base::Bind(&ServiceWorkerContextWrapper::UpdateRegistration, this, - pattern)); + base::BindOnce(&ServiceWorkerContextWrapper::UpdateRegistration, this, + pattern)); return; } if (!context_core_) @@ -344,13 +335,14 @@ if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, - base::Bind(&ServiceWorkerContextWrapper::StartServiceWorker, this, - pattern, callback)); + base::BindOnce(&ServiceWorkerContextWrapper::StartServiceWorker, this, + pattern, callback)); return; } if (!context_core_) { - BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, - base::Bind(callback, SERVICE_WORKER_ERROR_ABORT)); + BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, + base::BindOnce(callback, SERVICE_WORKER_ERROR_ABORT)); return; } context_core_->storage()->FindRegistrationForPattern( @@ -362,8 +354,8 @@ if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, - base::Bind(&ServiceWorkerContextWrapper::SkipWaitingWorker, this, - pattern)); + base::BindOnce(&ServiceWorkerContextWrapper::SkipWaitingWorker, this, + pattern)); return; } if (!context_core_) @@ -377,8 +369,8 @@ if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, - base::Bind(&ServiceWorkerContextWrapper::SetForceUpdateOnPageLoad, this, - force_update_on_page_load)); + base::BindOnce(&ServiceWorkerContextWrapper::SetForceUpdateOnPageLoad, + this, force_update_on_page_load)); return; } if (!context_core_) @@ -391,9 +383,8 @@ DCHECK_CURRENTLY_ON(BrowserThread::IO); if (!context_core_) { BrowserThread::PostTask( - BrowserThread::IO, - FROM_HERE, - base::Bind(callback, std::vector<ServiceWorkerUsageInfo>())); + BrowserThread::IO, FROM_HERE, + base::BindOnce(callback, std::vector<ServiceWorkerUsageInfo>())); return; } context()->storage()->GetAllRegistrationsInfos(base::Bind( @@ -431,7 +422,7 @@ DCHECK_CURRENTLY_ON(BrowserThread::IO); BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, - base::Bind(callback, capability)); + base::BindOnce(callback, capability)); } void ServiceWorkerContextWrapper::StopAllServiceWorkersForOrigin( @@ -439,8 +430,9 @@ if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, - base::Bind(&ServiceWorkerContextWrapper::StopAllServiceWorkersForOrigin, - this, origin)); + base::BindOnce( + &ServiceWorkerContextWrapper::StopAllServiceWorkersForOrigin, this, + origin)); return; } if (!context_core_.get()) { @@ -489,15 +481,13 @@ if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, - base::Bind(&ServiceWorkerContextWrapper::DeleteForOrigin, this, origin, - result)); + base::BindOnce(&ServiceWorkerContextWrapper::DeleteForOrigin, this, + origin, result)); return; } if (!context_core_) { - BrowserThread::PostTask( - BrowserThread::IO, - FROM_HERE, - base::Bind(result, false)); + BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, + base::BindOnce(result, false)); return; } context()->UnregisterServiceWorkers( @@ -511,14 +501,14 @@ if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, - base::Bind(&ServiceWorkerContextWrapper::CheckHasServiceWorker, this, - url, other_url, callback)); + base::BindOnce(&ServiceWorkerContextWrapper::CheckHasServiceWorker, + this, url, other_url, callback)); return; } if (!context_core_) { BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, - base::Bind(callback, ServiceWorkerCapability::NO_SERVICE_WORKER)); + base::BindOnce(callback, ServiceWorkerCapability::NO_SERVICE_WORKER)); return; } context()->CheckHasServiceWorker( @@ -533,8 +523,9 @@ if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, - base::Bind(&ServiceWorkerContextWrapper::CountExternalRequestsForTest, - this, origin, callback)); + base::BindOnce( + &ServiceWorkerContextWrapper::CountExternalRequestsForTest, this, + origin, callback)); return; } @@ -549,8 +540,9 @@ break; } } - BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, - base::Bind(callback, pending_external_request_count)); + BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, + base::BindOnce(callback, pending_external_request_count)); } void ServiceWorkerContextWrapper::ClearAllServiceWorkersForTest( @@ -558,8 +550,9 @@ if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, - base::Bind(&ServiceWorkerContextWrapper::ClearAllServiceWorkersForTest, - this, callback)); + base::BindOnce( + &ServiceWorkerContextWrapper::ClearAllServiceWorkersForTest, this, + callback)); return; } if (!context_core_) { @@ -606,8 +599,8 @@ const BoolCallback& callback) const { DCHECK_CURRENTLY_ON(BrowserThread::IO); if (!context_core_) { - base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, - base::Bind(callback, false)); + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(callback, false)); return; } context_core_->HasMainFrameProviderHost(origin, callback); @@ -856,12 +849,12 @@ if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, - base::Bind(&ServiceWorkerContextWrapper::InitInternal, this, - user_data_directory, std::move(database_task_runner), - base::RetainedRef(quota_manager_proxy), - base::RetainedRef(special_storage_policy), - base::RetainedRef(blob_context), - base::RetainedRef(loader_factory_getter))); + base::BindOnce(&ServiceWorkerContextWrapper::InitInternal, this, + user_data_directory, std::move(database_task_runner), + base::RetainedRef(quota_manager_proxy), + base::RetainedRef(special_storage_policy), + base::RetainedRef(blob_context), + base::RetainedRef(loader_factory_getter))); return; } // TODO(pkasting): Remove ScopedTracker below once crbug.com/477117 is fixed. @@ -943,7 +936,7 @@ BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, - base::Bind( + base::BindOnce( &ServiceWorkerContextWrapper::StartServiceWorkerForNavigationHintOnIO, this, document_url, base::Bind(&ServiceWorkerContextWrapper:: @@ -1023,7 +1016,7 @@ DCHECK_CURRENTLY_ON(BrowserThread::IO); ServiceWorkerMetrics::RecordStartServiceWorkerForNavigationHintResult(result); BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, - base::Bind(callback, result)); + base::BindOnce(callback, result)); } void ServiceWorkerContextWrapper::BindWorkerFetchContext(
diff --git a/content/browser/service_worker/service_worker_context_wrapper.h b/content/browser/service_worker/service_worker_context_wrapper.h index ed9a9f1..d6c47ebf 100644 --- a/content/browser/service_worker/service_worker_context_wrapper.h +++ b/content/browser/service_worker/service_worker_context_wrapper.h
@@ -44,7 +44,7 @@ // instance is strictly single threaded and is not refcounted, the core object // is what is used internally in the service worker lib. class CONTENT_EXPORT ServiceWorkerContextWrapper - : NON_EXPORTED_BASE(public ServiceWorkerContext), + : public ServiceWorkerContext, public ServiceWorkerContextCoreObserver, public base::RefCountedThreadSafe<ServiceWorkerContextWrapper> { public:
diff --git a/content/browser/service_worker/service_worker_data_pipe_reader.cc b/content/browser/service_worker/service_worker_data_pipe_reader.cc index fdfe88ca..99207bf 100644 --- a/content/browser/service_worker/service_worker_data_pipe_reader.cc +++ b/content/browser/service_worker/service_worker_data_pipe_reader.cc
@@ -25,7 +25,7 @@ TRACE_EVENT_ASYNC_BEGIN1("ServiceWorker", "ServiceWorkerDataPipeReader", this, "Url", owner->request()->url().spec()); streaming_version_->AddStreamingURLRequestJob(owner_); - binding_.set_connection_error_handler(base::Bind( + binding_.set_connection_error_handler(base::BindOnce( &ServiceWorkerDataPipeReader::OnAborted, base::Unretained(this))); }
diff --git a/content/browser/service_worker/service_worker_dispatcher_host.cc b/content/browser/service_worker/service_worker_dispatcher_host.cc index b000380fc..4f626f6 100644 --- a/content/browser/service_worker/service_worker_dispatcher_host.cc +++ b/content/browser/service_worker/service_worker_dispatcher_host.cc
@@ -102,9 +102,10 @@ void ServiceWorkerDispatcherHost::Init( ServiceWorkerContextWrapper* context_wrapper) { if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { - BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, - base::Bind(&ServiceWorkerDispatcherHost::Init, this, - base::RetainedRef(context_wrapper))); + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + base::BindOnce(&ServiceWorkerDispatcherHost::Init, this, + base::RetainedRef(context_wrapper))); return; }
diff --git a/content/browser/service_worker/service_worker_fetch_dispatcher.cc b/content/browser/service_worker/service_worker_fetch_dispatcher.cc index bbc170b..f2b75244 100644 --- a/content/browser/service_worker/service_worker_fetch_dispatcher.cc +++ b/content/browser/service_worker/service_worker_fetch_dispatcher.cc
@@ -63,7 +63,7 @@ // This unretained pointer is safe, because |binding_| is owned by |this| // and the callback will never be called after |this| is destroyed. binding_.set_connection_error_handler( - base::Bind(&DelegatingURLLoader::Cancel, base::Unretained(this))); + base::BindOnce(&DelegatingURLLoader::Cancel, base::Unretained(this))); return loader; } @@ -208,9 +208,10 @@ if (!worker_id_) return; while (!devtools_callbacks.empty()) { - BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, - base::Bind(std::move(devtools_callbacks.front()), - *worker_id_, devtools_request_id_)); + BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, + base::BindOnce(std::move(devtools_callbacks.front()), *worker_id_, + devtools_request_id_)); devtools_callbacks.pop(); } } @@ -537,9 +538,9 @@ version_->event_dispatcher()->DispatchFetchEvent( fetch_event_id, *request_, std::move(preload_handle_), std::move(response_callback_ptr), - base::Bind(&ServiceWorkerFetchDispatcher::OnFetchEventFinished, - base::Unretained(version_.get()), event_finish_id, - url_loader_assets_)); + base::BindOnce(&ServiceWorkerFetchDispatcher::OnFetchEventFinished, + base::Unretained(version_.get()), event_finish_id, + url_loader_assets_)); } void ServiceWorkerFetchDispatcher::DidFailToDispatch(
diff --git a/content/browser/service_worker/service_worker_handle.h b/content/browser/service_worker/service_worker_handle.h index 9cc393d..fd2697b6 100644 --- a/content/browser/service_worker/service_worker_handle.h +++ b/content/browser/service_worker/service_worker_handle.h
@@ -28,7 +28,7 @@ // Has references to the corresponding ServiceWorkerVersion in order to ensure // that the version is alive while this handle is around. class CONTENT_EXPORT ServiceWorkerHandle - : NON_EXPORTED_BASE(public ServiceWorkerVersion::Listener) { + : public ServiceWorkerVersion::Listener { public: // Creates a handle for a live version. This may return nullptr if any of // |context|, |provider_host| and |version| is nullptr.
diff --git a/content/browser/service_worker/service_worker_installed_scripts_sender_unittest.cc b/content/browser/service_worker/service_worker_installed_scripts_sender_unittest.cc index 01712571..55fb84e 100644 --- a/content/browser/service_worker/service_worker_installed_scripts_sender_unittest.cc +++ b/content/browser/service_worker/service_worker_installed_scripts_sender_unittest.cc
@@ -87,8 +87,8 @@ case MOJO_RESULT_SHOULD_WAIT: BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, - base::Bind(&ReadDataPipeInternal, handle, result, - base::Passed(&quit_closure))); + base::BindOnce(&ReadDataPipeInternal, handle, result, + base::Passed(&quit_closure))); return; case MOJO_RESULT_OK: EXPECT_NE(nullptr, buffer);
diff --git a/content/browser/service_worker/service_worker_internals_ui.cc b/content/browser/service_worker/service_worker_internals_ui.cc index 6a15cd4f..6014680 100644 --- a/content/browser/service_worker/service_worker_internals_ui.cc +++ b/content/browser/service_worker/service_worker_internals_ui.cc
@@ -52,10 +52,9 @@ int callback_id, ServiceWorkerStatusCode status) { if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { - BrowserThread::PostTask( - BrowserThread::UI, - FROM_HERE, - base::Bind(OperationCompleteCallback, internals, callback_id, status)); + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, + base::BindOnce(OperationCompleteCallback, internals, + callback_id, status)); return; } DCHECK_CURRENTLY_ON(BrowserThread::UI); @@ -73,13 +72,9 @@ const ServiceWorkerInternalsUI::StatusCallback& callback) { if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { BrowserThread::PostTask( - BrowserThread::IO, - FROM_HERE, - base::Bind(CallServiceWorkerVersionMethodWithVersionID, - method, - context, - version_id, - callback)); + BrowserThread::IO, FROM_HERE, + base::BindOnce(CallServiceWorkerVersionMethodWithVersionID, method, + context, version_id, callback)); return; } @@ -233,8 +228,8 @@ DCHECK_CURRENTLY_ON(BrowserThread::IO); BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, - base::Bind(callback, context->GetAllLiveRegistrationInfo(), - context->GetAllLiveVersionInfo(), stored_registrations)); + base::BindOnce(callback, context->GetAllLiveRegistrationInfo(), + context->GetAllLiveVersionInfo(), stored_registrations)); } void GetRegistrationsOnIOThread( @@ -455,10 +450,11 @@ BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, - base::Bind(GetRegistrationsOnIOThread, context, - base::Bind(DidGetRegistrations, AsWeakPtr(), partition_id, - context->is_incognito() ? base::FilePath() - : partition->GetPath()))); + base::BindOnce( + GetRegistrationsOnIOThread, context, + base::Bind(DidGetRegistrations, AsWeakPtr(), partition_id, + context->is_incognito() ? base::FilePath() + : partition->GetPath()))); } void ServiceWorkerInternalsUI::RemoveObserverFromStoragePartition( @@ -601,8 +597,8 @@ if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, - base::Bind(&ServiceWorkerInternalsUI::UnregisterWithScope, - base::Unretained(this), context, scope, callback)); + base::BindOnce(&ServiceWorkerInternalsUI::UnregisterWithScope, + base::Unretained(this), context, scope, callback)); return; }
diff --git a/content/browser/service_worker/service_worker_metrics.cc b/content/browser/service_worker/service_worker_metrics.cc index db50d53..7a1abc1 100644 --- a/content/browser/service_worker/service_worker_metrics.cc +++ b/content/browser/service_worker/service_worker_metrics.cc
@@ -483,7 +483,8 @@ } BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, - base::Bind(&RecordURLMetricOnUI, "ServiceWorker.ControlledPageUrl", url)); + base::BindOnce(&RecordURLMetricOnUI, "ServiceWorker.ControlledPageUrl", + url)); } void ServiceWorkerMetrics::RecordStartWorkerStatus( @@ -1067,10 +1068,10 @@ void ServiceWorkerMetrics::RecordUninstalledScriptImport(const GURL& url) { BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, - base::Bind(&RecordURLMetricOnUI, - "ServiceWorker.ContextRequestHandlerStatus." - "UninstalledScriptImport", - url)); + base::BindOnce(&RecordURLMetricOnUI, + "ServiceWorker.ContextRequestHandlerStatus." + "UninstalledScriptImport", + url)); } void ServiceWorkerMetrics::RecordStartServiceWorkerForNavigationHintResult(
diff --git a/content/browser/service_worker/service_worker_navigation_handle_core.cc b/content/browser/service_worker/service_worker_navigation_handle_core.cc index 279461f8..a840a8aa 100644 --- a/content/browser/service_worker/service_worker_navigation_handle_core.cc +++ b/content/browser/service_worker/service_worker_navigation_handle_core.cc
@@ -44,7 +44,7 @@ precreated_host_->provider_id(), this); BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, - base::Bind( + base::BindOnce( &ServiceWorkerNavigationHandle::DidCreateServiceWorkerProviderHost, ui_handle_, precreated_host_->provider_id())); }
diff --git a/content/browser/service_worker/service_worker_process_manager.cc b/content/browser/service_worker/service_worker_process_manager.cc index 8e193da3..ef13976 100644 --- a/content/browser/service_worker/service_worker_process_manager.cc +++ b/content/browser/service_worker/service_worker_process_manager.cc
@@ -90,7 +90,7 @@ for (std::map<int, ProcessInfo>::const_iterator it = instance_info_.begin(); it != instance_info_.end(); ++it) { RenderProcessHost::FromID(it->second.process_id) - ->DecrementServiceWorkerRefCount(); + ->DecrementKeepAliveRefCount(); } } instance_info_.clear(); @@ -105,12 +105,10 @@ const GURL& pattern, int process_id) { if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { BrowserThread::PostTask( - BrowserThread::UI, - FROM_HERE, - base::Bind(&ServiceWorkerProcessManager::AddProcessReferenceToPattern, - weak_this_, - pattern, - process_id)); + BrowserThread::UI, FROM_HERE, + base::BindOnce( + &ServiceWorkerProcessManager::AddProcessReferenceToPattern, + weak_this_, pattern, process_id)); return; } @@ -122,13 +120,10 @@ const GURL& pattern, int process_id) { if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { BrowserThread::PostTask( - BrowserThread::UI, - FROM_HERE, - base::Bind( - &ServiceWorkerProcessManager::RemoveProcessReferenceFromPattern, - weak_this_, - pattern, - process_id)); + BrowserThread::UI, FROM_HERE, + base::BindOnce( + &ServiceWorkerProcessManager::RemoveProcessReferenceFromPattern, + weak_this_, pattern, process_id)); return; } @@ -190,7 +185,7 @@ if (can_use_existing_process) { int process_id = FindAvailableProcess(pattern); if (process_id != ChildProcessHost::kInvalidUniqueID) { - RenderProcessHost::FromID(process_id)->IncrementServiceWorkerRefCount(); + RenderProcessHost::FromID(process_id)->IncrementKeepAliveRefCount(); instance_info_.insert( std::make_pair(embedded_worker_id, ProcessInfo(process_id))); out_info->process_id = process_id; @@ -243,7 +238,7 @@ instance_info_.insert( std::make_pair(embedded_worker_id, ProcessInfo(site_instance))); - rph->IncrementServiceWorkerRefCount(); + rph->IncrementKeepAliveRefCount(); out_info->process_id = rph->GetID(); out_info->start_situation = start_situation; return SERVICE_WORKER_OK; @@ -283,7 +278,7 @@ << "Process " << info->second.process_id << " was destroyed unexpectedly. Did we actually hold a reference?"; } - rph->DecrementServiceWorkerRefCount(); + rph->DecrementKeepAliveRefCount(); instance_info_.erase(info); }
diff --git a/content/browser/service_worker/service_worker_process_manager_unittest.cc b/content/browser/service_worker/service_worker_process_manager_unittest.cc index 90d65da5..a88ece9 100644 --- a/content/browser/service_worker/service_worker_process_manager_unittest.cc +++ b/content/browser/service_worker/service_worker_process_manager_unittest.cc
@@ -121,8 +121,8 @@ std::unique_ptr<MockRenderProcessHost> host2(CreateRenderProcessHost()); process_manager_->AddProcessReferenceToPattern(scope1, host1->GetID()); process_manager_->AddProcessReferenceToPattern(scope2, host2->GetID()); - ASSERT_EQ(0u, host1->GetWorkerRefCount()); - ASSERT_EQ(0u, host2->GetWorkerRefCount()); + ASSERT_EQ(0u, host1->GetKeepAliveRefCount()); + ASSERT_EQ(0u, host2->GetKeepAliveRefCount()); std::map<int, ServiceWorkerProcessManager::ProcessInfo>& instance_info = process_manager_->instance_info_; @@ -138,8 +138,8 @@ EXPECT_EQ(host1->GetID(), process_info.process_id); EXPECT_EQ(ServiceWorkerMetrics::StartSituation::EXISTING_READY_PROCESS, process_info.start_situation); - EXPECT_EQ(1u, host1->GetWorkerRefCount()); - EXPECT_EQ(0u, host2->GetWorkerRefCount()); + EXPECT_EQ(1u, host1->GetKeepAliveRefCount()); + EXPECT_EQ(0u, host2->GetKeepAliveRefCount()); EXPECT_EQ(1u, instance_info.size()); std::map<int, ServiceWorkerProcessManager::ProcessInfo>::iterator found = instance_info.find(kEmbeddedWorkerId1); @@ -157,8 +157,8 @@ EXPECT_EQ(host1->GetID(), process_info.process_id); EXPECT_EQ(ServiceWorkerMetrics::StartSituation::EXISTING_READY_PROCESS, process_info.start_situation); - EXPECT_EQ(2u, host1->GetWorkerRefCount()); - EXPECT_EQ(0u, host2->GetWorkerRefCount()); + EXPECT_EQ(2u, host1->GetKeepAliveRefCount()); + EXPECT_EQ(0u, host2->GetKeepAliveRefCount()); EXPECT_EQ(2u, instance_info.size()); found = instance_info.find(kEmbeddedWorkerId2); ASSERT_TRUE(found != instance_info.end()); @@ -175,8 +175,8 @@ EXPECT_EQ(host2->GetID(), process_info.process_id); EXPECT_EQ(ServiceWorkerMetrics::StartSituation::EXISTING_READY_PROCESS, process_info.start_situation); - EXPECT_EQ(2u, host1->GetWorkerRefCount()); - EXPECT_EQ(1u, host2->GetWorkerRefCount()); + EXPECT_EQ(2u, host1->GetKeepAliveRefCount()); + EXPECT_EQ(1u, host2->GetKeepAliveRefCount()); EXPECT_EQ(3u, instance_info.size()); found = instance_info.find(kEmbeddedWorkerId3); ASSERT_TRUE(found != instance_info.end()); @@ -184,21 +184,21 @@ // The instance map should be updated by process release. process_manager_->ReleaseWorkerProcess(kEmbeddedWorkerId3); - EXPECT_EQ(2u, host1->GetWorkerRefCount()); - EXPECT_EQ(0u, host2->GetWorkerRefCount()); + EXPECT_EQ(2u, host1->GetKeepAliveRefCount()); + EXPECT_EQ(0u, host2->GetKeepAliveRefCount()); EXPECT_EQ(2u, instance_info.size()); EXPECT_TRUE(base::ContainsKey(instance_info, kEmbeddedWorkerId1)); EXPECT_TRUE(base::ContainsKey(instance_info, kEmbeddedWorkerId2)); process_manager_->ReleaseWorkerProcess(kEmbeddedWorkerId1); - EXPECT_EQ(1u, host1->GetWorkerRefCount()); - EXPECT_EQ(0u, host2->GetWorkerRefCount()); + EXPECT_EQ(1u, host1->GetKeepAliveRefCount()); + EXPECT_EQ(0u, host2->GetKeepAliveRefCount()); EXPECT_EQ(1u, instance_info.size()); EXPECT_TRUE(base::ContainsKey(instance_info, kEmbeddedWorkerId2)); process_manager_->ReleaseWorkerProcess(kEmbeddedWorkerId2); - EXPECT_EQ(0u, host1->GetWorkerRefCount()); - EXPECT_EQ(0u, host2->GetWorkerRefCount()); + EXPECT_EQ(0u, host1->GetKeepAliveRefCount()); + EXPECT_EQ(0u, host2->GetKeepAliveRefCount()); EXPECT_TRUE(instance_info.empty()); } @@ -228,7 +228,7 @@ EXPECT_EQ(host->GetID(), process_info.process_id); EXPECT_EQ(ServiceWorkerMetrics::StartSituation::EXISTING_UNREADY_PROCESS, process_info.start_situation); - EXPECT_EQ(1u, host->GetWorkerRefCount()); + EXPECT_EQ(1u, host->GetKeepAliveRefCount()); EXPECT_EQ(1u, instance_info.size()); std::map<int, ServiceWorkerProcessManager::ProcessInfo>::iterator found = instance_info.find(kEmbeddedWorkerId); @@ -237,7 +237,7 @@ // Release the process. process_manager_->ReleaseWorkerProcess(kEmbeddedWorkerId); - EXPECT_EQ(0u, host->GetWorkerRefCount()); + EXPECT_EQ(0u, host->GetKeepAliveRefCount()); EXPECT_TRUE(instance_info.empty()); RenderProcessHostImpl::RemoveFrameWithSite(browser_context_.get(), host.get(), @@ -269,7 +269,7 @@ EXPECT_NE(host->GetID(), process_info.process_id); EXPECT_EQ(ServiceWorkerMetrics::StartSituation::NEW_PROCESS, process_info.start_situation); - EXPECT_EQ(0u, host->GetWorkerRefCount()); + EXPECT_EQ(0u, host->GetKeepAliveRefCount()); EXPECT_EQ(1u, instance_info.size()); std::map<int, ServiceWorkerProcessManager::ProcessInfo>::iterator found = instance_info.find(kEmbeddedWorkerId);
diff --git a/content/browser/service_worker/service_worker_provider_host.cc b/content/browser/service_worker/service_worker_provider_host.cc index ec07abbc..ef2c83c53 100644 --- a/content/browser/service_worker/service_worker_provider_host.cc +++ b/content/browser/service_worker/service_worker_provider_host.cc
@@ -19,6 +19,7 @@ #include "content/browser/service_worker/service_worker_dispatcher_host.h" #include "content/browser/service_worker/service_worker_handle.h" #include "content/browser/service_worker/service_worker_registration_handle.h" +#include "content/browser/service_worker/service_worker_script_url_loader_factory.h" #include "content/browser/service_worker/service_worker_version.h" #include "content/browser/url_loader_factory_getter.h" #include "content/common/service_worker/service_worker_messages.h" @@ -32,7 +33,6 @@ #include "content/public/common/origin_util.h" #include "content/public/common/resource_request_body.h" #include "mojo/public/cpp/bindings/strong_associated_binding.h" -#include "mojo/public/cpp/bindings/strong_binding.h" #include "net/base/url_util.h" #include "storage/browser/blob/blob_storage_context.h" @@ -97,225 +97,6 @@ context->RemoveProviderHost(process_id, provider_id); } -// Used by a Service Worker for script loading only during the installation -// time. For now this is just a proxy loader for the network loader. -// Eventually this should replace the existing URLRequestJob-based request -// interception for script loading, namely ServiceWorkerWriteToCacheJob. -// TODO(kinuko): Implement this. -class ScriptURLLoader : public mojom::URLLoader, public mojom::URLLoaderClient { - public: - ScriptURLLoader( - int32_t routing_id, - int32_t request_id, - uint32_t options, - const ResourceRequest& resource_request, - mojom::URLLoaderClientPtr client, - base::WeakPtr<ServiceWorkerContextCore> context, - base::WeakPtr<ServiceWorkerProviderHost> provider_host, - base::WeakPtr<storage::BlobStorageContext> blob_storage_context, - scoped_refptr<URLLoaderFactoryGetter> loader_factory_getter, - const net::MutableNetworkTrafficAnnotationTag& traffic_annotation) - : network_client_binding_(this), - forwarding_client_(std::move(client)), - provider_host_(provider_host) { - mojom::URLLoaderClientPtr network_client; - network_client_binding_.Bind(mojo::MakeRequest(&network_client)); - loader_factory_getter->GetNetworkFactory()->get()->CreateLoaderAndStart( - mojo::MakeRequest(&network_loader_), routing_id, request_id, options, - resource_request, std::move(network_client), traffic_annotation); - } - ~ScriptURLLoader() override {} - - // mojom::URLLoader: - void FollowRedirect() override { network_loader_->FollowRedirect(); } - void SetPriority(net::RequestPriority priority, - int32_t intra_priority_value) override { - network_loader_->SetPriority(priority, intra_priority_value); - } - - // mojom::URLLoaderClient for simply proxying network: - void OnReceiveResponse( - const ResourceResponseHead& response_head, - const base::Optional<net::SSLInfo>& ssl_info, - mojom::DownloadedTempFilePtr downloaded_file) override { - if (provider_host_) { - // We don't have complete info here, but fill in what we have now. - // At least we need headers and SSL info. - net::HttpResponseInfo response_info; - response_info.headers = response_head.headers; - if (ssl_info.has_value()) - response_info.ssl_info = *ssl_info; - response_info.was_fetched_via_spdy = response_head.was_fetched_via_spdy; - response_info.was_alpn_negotiated = response_head.was_alpn_negotiated; - response_info.alpn_negotiated_protocol = - response_head.alpn_negotiated_protocol; - response_info.connection_info = response_head.connection_info; - response_info.socket_address = response_head.socket_address; - - DCHECK(provider_host_->IsHostToRunningServiceWorker()); - provider_host_->running_hosted_version()->SetMainScriptHttpResponseInfo( - response_info); - } - forwarding_client_->OnReceiveResponse(response_head, ssl_info, - std::move(downloaded_file)); - } - void OnReceiveRedirect(const net::RedirectInfo& redirect_info, - const ResourceResponseHead& response_head) override { - forwarding_client_->OnReceiveRedirect(redirect_info, response_head); - } - void OnDataDownloaded(int64_t data_len, int64_t encoded_data_len) override { - forwarding_client_->OnDataDownloaded(data_len, encoded_data_len); - } - void OnUploadProgress(int64_t current_position, - int64_t total_size, - OnUploadProgressCallback ack_callback) override { - forwarding_client_->OnUploadProgress(current_position, total_size, - std::move(ack_callback)); - } - void OnReceiveCachedMetadata(const std::vector<uint8_t>& data) override { - forwarding_client_->OnReceiveCachedMetadata(data); - } - void OnTransferSizeUpdated(int32_t transfer_size_diff) override { - forwarding_client_->OnTransferSizeUpdated(transfer_size_diff); - } - void OnStartLoadingResponseBody( - mojo::ScopedDataPipeConsumerHandle body) override { - forwarding_client_->OnStartLoadingResponseBody(std::move(body)); - } - void OnComplete(const ResourceRequestCompletionStatus& status) override { - forwarding_client_->OnComplete(status); - } - - private: - mojom::URLLoaderPtr network_loader_; - mojo::Binding<mojom::URLLoaderClient> network_client_binding_; - mojom::URLLoaderClientPtr forwarding_client_; - base::WeakPtr<ServiceWorkerProviderHost> provider_host_; - - DISALLOW_COPY_AND_ASSIGN(ScriptURLLoader); -}; - -// Created per one controller worker for script loading (only during -// installation, eventually). This is kept alive while -// ServiceWorkerNetworkProvider in the renderer process is alive. -// Used only when IsServicificationEnabled is true. -class ScriptURLLoaderFactory : public mojom::URLLoaderFactory { - public: - ScriptURLLoaderFactory( - base::WeakPtr<ServiceWorkerContextCore> context, - base::WeakPtr<ServiceWorkerProviderHost> provider_host, - base::WeakPtr<storage::BlobStorageContext> blob_storage_context, - scoped_refptr<URLLoaderFactoryGetter> loader_factory_getter) - : context_(context), - provider_host_(provider_host), - blob_storage_context_(blob_storage_context), - loader_factory_getter_(loader_factory_getter) {} - ~ScriptURLLoaderFactory() override {} - - // mojom::URLLoaderFactory: - void CreateLoaderAndStart(mojom::URLLoaderRequest request, - int32_t routing_id, - int32_t request_id, - uint32_t options, - const ResourceRequest& resource_request, - mojom::URLLoaderClientPtr client, - const net::MutableNetworkTrafficAnnotationTag& - traffic_annotation) override { - if (!ShouldHandleScriptRequest(resource_request)) { - // If the request should not be handled by ScriptURLLoader, just - // fallback to the network. This needs a relaying as we use different - // associated message pipes. - // TODO(kinuko): Record the reason like what we do with netlog in - // ServiceWorkerContextRequestHandler. - (*loader_factory_getter_->GetNetworkFactory()) - ->CreateLoaderAndStart(std::move(request), routing_id, request_id, - options, resource_request, std::move(client), - traffic_annotation); - return; - } - mojo::MakeStrongBinding( - base::MakeUnique<ScriptURLLoader>( - routing_id, request_id, options, resource_request, - std::move(client), context_, provider_host_, blob_storage_context_, - loader_factory_getter_, traffic_annotation), - std::move(request)); - } - - void Clone(mojom::URLLoaderFactoryRequest request) override { - // This method is required to support synchronous requests which are not - // performed during installation. - NOTREACHED(); - } - - private: - bool ShouldHandleScriptRequest(const ResourceRequest& resource_request) { - if (!context_ || !provider_host_) - return false; - - // We only use the script cache for main script loading and - // importScripts(), even if a cached script is xhr'd, we don't - // retrieve it from the script cache. - if (resource_request.resource_type != RESOURCE_TYPE_SERVICE_WORKER && - resource_request.resource_type != RESOURCE_TYPE_SCRIPT) { - // TODO: Record bad message, we shouldn't come here for other - // request types. - return false; - } - - scoped_refptr<ServiceWorkerVersion> version = - provider_host_->running_hosted_version(); - - // This could happen if browser-side has set the status to redundant but - // the worker has not yet stopped. The worker is already doomed so just - // reject the request. Handle it specially here because otherwise it'd be - // unclear whether "REDUNDANT" should count as installed or not installed - // when making decisions about how to handle the request and logging UMA. - if (!version || version->status() == ServiceWorkerVersion::REDUNDANT) - return false; - - // TODO: Make sure we don't handle the redirected request. - - // If script streaming is enabled, for installed service workers, typically - // all the scripts are served via script streaming, so we don't come here. - // However, we still come here when the service worker is A) importing a - // script that was never installed, or B) loading the same script twice. - // For now, return false here to fallback to network. Eventually, A) should - // be deprecated (https://crbug.com/719052), and B) should be handled by - // script streaming as well, see the TODO in - // WebServiceWorkerInstalledScriptsManagerImpl::GetRawScriptData(). - // - // When script streaming is not enabled, we get here even for the main - // script. Therefore, ScriptURLLoader must handle the request (even though - // it currently just does a network fetch for now), because it sets the - // main script's HTTP Response Info (via - // ServiceWorkerVersion::SetMainScriptHttpResponseInfo()) which otherwise - // would never be set. - if (ServiceWorkerVersion::IsInstalled(version->status()) && - ServiceWorkerUtils::IsScriptStreamingEnabled()) { - return false; - } - - // TODO: Make sure we come here only for new / unknown scripts - // once script streaming manager in the renderer side stops sending - // resource requests for the known script URLs, i.e. add DCHECK for - // version->script_cache_map()->LookupResourceId(url) == - // kInvalidServiceWorkerResourceId. - // - // Currently this could be false for the installing worker that imports - // the same script twice (e.g. importScripts('dupe.js'); - // importScripts('dupe.js');). - - // Request should be served by ScriptURLLoader. - return true; - } - - base::WeakPtr<ServiceWorkerContextCore> context_; - base::WeakPtr<ServiceWorkerProviderHost> provider_host_; - base::WeakPtr<storage::BlobStorageContext> blob_storage_context_; - scoped_refptr<URLLoaderFactoryGetter> loader_factory_getter_; - DISALLOW_COPY_AND_ASSIGN(ScriptURLLoaderFactory); -}; - } // anonymous namespace ServiceWorkerProviderHost::OneShotGetReadyCallback::OneShotGetReadyCallback( @@ -374,8 +155,8 @@ mojom::ServiceWorkerWorkerClientAssociatedPtr client; client.Bind(std::move(client_ptr_info)); client.set_connection_error_handler( - base::Bind(&ServiceWorkerProviderHost::UnregisterWorkerFetchContext, - base::Unretained(this), client.get())); + base::BindOnce(&ServiceWorkerProviderHost::UnregisterWorkerFetchContext, + base::Unretained(this), client.get())); if (controlling_version_) client->SetControllerServiceWorker(controlling_version_->version_id()); @@ -434,7 +215,7 @@ provider_.Bind(std::move(info_.client_ptr_info)); binding_.Bind(std::move(info_.host_request)); - binding_.set_connection_error_handler(base::Bind( + binding_.set_connection_error_handler(base::BindOnce( &RemoveProviderHost, context_, render_process_id, info_.provider_id)); } @@ -840,8 +621,8 @@ provider_.Bind(provisional_host->provider_.PassInterface()); binding_.Bind(provisional_host->binding_.Unbind()); binding_.set_connection_error_handler( - base::Bind(&RemoveProviderHost, context_, provisional_host->process_id(), - provider_id())); + base::BindOnce(&RemoveProviderHost, context_, + provisional_host->process_id(), provider_id())); for (const GURL& pattern : associated_patterns_) IncreaseProcessReference(pattern); @@ -874,7 +655,7 @@ provider_.Bind(std::move(info.client_ptr_info)); binding_.Bind(std::move(info.host_request)); binding_.set_connection_error_handler( - base::Bind(&RemoveProviderHost, context_, process_id, provider_id())); + base::BindOnce(&RemoveProviderHost, context_, process_id, provider_id())); info_.route_id = info.route_id; render_process_id_ = process_id; dispatcher_host_ = dispatcher_host; @@ -934,7 +715,7 @@ mojom::URLLoaderFactoryAssociatedPtrInfo script_loader_factory_ptr_info; if (ServiceWorkerUtils::IsServicificationEnabled()) { mojo::MakeStrongAssociatedBinding( - base::MakeUnique<ScriptURLLoaderFactory>( + base::MakeUnique<ServiceWorkerScriptURLLoaderFactory>( context_, AsWeakPtr(), context_->blob_storage_context(), context_->loader_factory_getter()), mojo::MakeRequest(&script_loader_factory_ptr_info)); @@ -944,7 +725,7 @@ binding_.Bind(mojo::MakeRequest(&provider_info->host_ptr_info)); binding_.set_connection_error_handler( - base::Bind(&RemoveProviderHost, context_, process_id, provider_id())); + base::BindOnce(&RemoveProviderHost, context_, process_id, provider_id())); // Set the document URL to the script url in order to allow // register/unregister/getRegistration on ServiceWorkerGlobalScope.
diff --git a/content/browser/service_worker/service_worker_provider_host.h b/content/browser/service_worker/service_worker_provider_host.h index 99c6d08e..c429189 100644 --- a/content/browser/service_worker/service_worker_provider_host.h +++ b/content/browser/service_worker/service_worker_provider_host.h
@@ -79,9 +79,9 @@ // disconnection of the Mojo's pipe from the renderer side regardless of what // the provider is for. class CONTENT_EXPORT ServiceWorkerProviderHost - : public NON_EXPORTED_BASE(ServiceWorkerRegistration::Listener), + : public ServiceWorkerRegistration::Listener, public base::SupportsWeakPtr<ServiceWorkerProviderHost>, - public NON_EXPORTED_BASE(mojom::ServiceWorkerProviderHost) { + public mojom::ServiceWorkerProviderHost { public: using GetRegistrationForReadyCallback = base::Callback<void(ServiceWorkerRegistration* reigstration)>;
diff --git a/content/browser/service_worker/service_worker_read_from_cache_job.cc b/content/browser/service_worker/service_worker_read_from_cache_job.cc index 46835d5..466c55c 100644 --- a/content/browser/service_worker/service_worker_read_from_cache_job.cc +++ b/content/browser/service_worker/service_worker_read_from_cache_job.cc
@@ -53,8 +53,8 @@ void ServiceWorkerReadFromCacheJob::Start() { TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("ServiceWorker", "ReadInfo", this); base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(&ServiceWorkerReadFromCacheJob::StartAsync, - weak_factory_.GetWeakPtr())); + FROM_HERE, base::BindOnce(&ServiceWorkerReadFromCacheJob::StartAsync, + weak_factory_.GetWeakPtr())); } void ServiceWorkerReadFromCacheJob::Kill() {
diff --git a/content/browser/service_worker/service_worker_register_job.cc b/content/browser/service_worker/service_worker_register_job.cc index aa9725eb0..6514a0b 100644 --- a/content/browser/service_worker/service_worker_register_job.cc +++ b/content/browser/service_worker/service_worker_register_job.cc
@@ -124,8 +124,8 @@ start_time_ = base::TimeTicks::Now(); BrowserThread::PostAfterStartupTask( FROM_HERE, base::ThreadTaskRunnerHandle::Get(), - base::Bind(&ServiceWorkerRegisterJob::StartImpl, - weak_factory_.GetWeakPtr())); + base::BindOnce(&ServiceWorkerRegisterJob::StartImpl, + weak_factory_.GetWeakPtr())); } void ServiceWorkerRegisterJob::StartImpl() { @@ -460,9 +460,9 @@ install_methods_receiver->BindInterface(&ptr_info); new_version()->event_dispatcher()->DispatchInstallEvent( std::move(ptr_info), - base::Bind(&ServiceWorkerRegisterJob::OnInstallFinished, - weak_factory_.GetWeakPtr(), request_id, - base::Passed(&install_methods_receiver))); + base::BindOnce(&ServiceWorkerRegisterJob::OnInstallFinished, + weak_factory_.GetWeakPtr(), request_id, + base::Passed(&install_methods_receiver))); } void ServiceWorkerRegisterJob::OnInstallFinished(
diff --git a/content/browser/service_worker/service_worker_registration.cc b/content/browser/service_worker/service_worker_registration.cc index ca1ca39..a433364 100644 --- a/content/browser/service_worker/service_worker_registration.cc +++ b/content/browser/service_worker/service_worker_registration.cc
@@ -377,8 +377,9 @@ // failures, wait a bit before continuing. if (delay) { task_runner_->PostDelayedTask( - FROM_HERE, base::Bind(&ServiceWorkerRegistration::ContinueActivation, - this, activating_version), + FROM_HERE, + base::BindOnce(&ServiceWorkerRegistration::ContinueActivation, this, + activating_version), base::TimeDelta::FromSeconds(1)); } else { ContinueActivation(std::move(activating_version));
diff --git a/content/browser/service_worker/service_worker_registration.h b/content/browser/service_worker/service_worker_registration.h index e78d181..ecbe251 100644 --- a/content/browser/service_worker/service_worker_registration.h +++ b/content/browser/service_worker/service_worker_registration.h
@@ -30,8 +30,8 @@ // to this class. This is refcounted via ServiceWorkerRegistrationHandle to // facilitate multiple controllees being associated with the same registration. class CONTENT_EXPORT ServiceWorkerRegistration - : public NON_EXPORTED_BASE(base::RefCounted<ServiceWorkerRegistration>), - public NON_EXPORTED_BASE(ServiceWorkerVersion::Listener) { + : public base::RefCounted<ServiceWorkerRegistration>, + public ServiceWorkerVersion::Listener { public: typedef base::Callback<void(ServiceWorkerStatusCode status)> StatusCallback;
diff --git a/content/browser/service_worker/service_worker_script_url_loader.cc b/content/browser/service_worker/service_worker_script_url_loader.cc new file mode 100644 index 0000000..3e802a2 --- /dev/null +++ b/content/browser/service_worker/service_worker_script_url_loader.cc
@@ -0,0 +1,114 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/service_worker/service_worker_script_url_loader.h" + +#include <memory> +#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/url_loader_factory_getter.h" +#include "content/public/common/resource_response.h" +#include "storage/browser/blob/blob_storage_context.h" + +namespace content { + +ServiceWorkerScriptURLLoader::ServiceWorkerScriptURLLoader( + int32_t routing_id, + int32_t request_id, + uint32_t options, + const ResourceRequest& resource_request, + mojom::URLLoaderClientPtr client, + base::WeakPtr<ServiceWorkerContextCore> context, + base::WeakPtr<ServiceWorkerProviderHost> provider_host, + base::WeakPtr<storage::BlobStorageContext> blob_storage_context, + scoped_refptr<URLLoaderFactoryGetter> loader_factory_getter, + const net::MutableNetworkTrafficAnnotationTag& traffic_annotation) + : network_client_binding_(this), + forwarding_client_(std::move(client)), + provider_host_(provider_host) { + mojom::URLLoaderClientPtr network_client; + network_client_binding_.Bind(mojo::MakeRequest(&network_client)); + loader_factory_getter->GetNetworkFactory()->get()->CreateLoaderAndStart( + mojo::MakeRequest(&network_loader_), routing_id, request_id, options, + resource_request, std::move(network_client), traffic_annotation); +} + +ServiceWorkerScriptURLLoader::~ServiceWorkerScriptURLLoader() = default; + +void ServiceWorkerScriptURLLoader::FollowRedirect() { + network_loader_->FollowRedirect(); +} + +void ServiceWorkerScriptURLLoader::SetPriority(net::RequestPriority priority, + int32_t intra_priority_value) { + network_loader_->SetPriority(priority, intra_priority_value); +} + +void ServiceWorkerScriptURLLoader::OnReceiveResponse( + const ResourceResponseHead& response_head, + const base::Optional<net::SSLInfo>& ssl_info, + mojom::DownloadedTempFilePtr downloaded_file) { + if (provider_host_) { + // We don't have complete info here, but fill in what we have now. + // At least we need headers and SSL info. + net::HttpResponseInfo response_info; + response_info.headers = response_head.headers; + if (ssl_info.has_value()) + response_info.ssl_info = *ssl_info; + response_info.was_fetched_via_spdy = response_head.was_fetched_via_spdy; + response_info.was_alpn_negotiated = response_head.was_alpn_negotiated; + response_info.alpn_negotiated_protocol = + response_head.alpn_negotiated_protocol; + response_info.connection_info = response_head.connection_info; + response_info.socket_address = response_head.socket_address; + + DCHECK(provider_host_->IsHostToRunningServiceWorker()); + provider_host_->running_hosted_version()->SetMainScriptHttpResponseInfo( + response_info); + } + forwarding_client_->OnReceiveResponse(response_head, ssl_info, + std::move(downloaded_file)); +} + +void ServiceWorkerScriptURLLoader::OnReceiveRedirect( + const net::RedirectInfo& redirect_info, + const ResourceResponseHead& response_head) { + forwarding_client_->OnReceiveRedirect(redirect_info, response_head); +} + +void ServiceWorkerScriptURLLoader::OnDataDownloaded(int64_t data_len, + int64_t encoded_data_len) { + forwarding_client_->OnDataDownloaded(data_len, encoded_data_len); +} + +void ServiceWorkerScriptURLLoader::OnUploadProgress( + int64_t current_position, + int64_t total_size, + OnUploadProgressCallback ack_callback) { + forwarding_client_->OnUploadProgress(current_position, total_size, + std::move(ack_callback)); +} + +void ServiceWorkerScriptURLLoader::OnReceiveCachedMetadata( + const std::vector<uint8_t>& data) { + forwarding_client_->OnReceiveCachedMetadata(data); +} + +void ServiceWorkerScriptURLLoader::OnTransferSizeUpdated( + int32_t transfer_size_diff) { + forwarding_client_->OnTransferSizeUpdated(transfer_size_diff); +} + +void ServiceWorkerScriptURLLoader::OnStartLoadingResponseBody( + mojo::ScopedDataPipeConsumerHandle body) { + forwarding_client_->OnStartLoadingResponseBody(std::move(body)); +} + +void ServiceWorkerScriptURLLoader::OnComplete( + const ResourceRequestCompletionStatus& status) { + forwarding_client_->OnComplete(status); +} + +} // namespace content
diff --git a/content/browser/service_worker/service_worker_script_url_loader.h b/content/browser/service_worker/service_worker_script_url_loader.h new file mode 100644 index 0000000..3847128 --- /dev/null +++ b/content/browser/service_worker/service_worker_script_url_loader.h
@@ -0,0 +1,79 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_SCRIPT_URL_LOADER_H_ +#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_SCRIPT_URL_LOADER_H_ + +#include "base/macros.h" +#include "content/browser/service_worker/service_worker_provider_host.h" +#include "content/public/common/resource_request.h" +#include "content/public/common/url_loader.mojom.h" +#include "mojo/public/cpp/bindings/binding.h" +#include "net/traffic_annotation/network_traffic_annotation.h" + +namespace storage { +class BlobStorageContext; +} // namespace storage + +namespace content { + +class ServiceWorkerContextCore; +class ServiceWorkerProviderHost; +class URLLoaderFactoryGetter; + +// S13nServiceWorker: +// Used by a Service Worker for script loading only during the installation +// time. For now this is just a proxy loader for the network loader. +// Eventually this should replace the existing URLRequestJob-based request +// interception for script loading, namely ServiceWorkerWriteToCacheJob. +// TODO(kinuko): Implement this. +class ServiceWorkerScriptURLLoader : public mojom::URLLoader, + public mojom::URLLoaderClient { + public: + ServiceWorkerScriptURLLoader( + int32_t routing_id, + int32_t request_id, + uint32_t options, + const ResourceRequest& resource_request, + mojom::URLLoaderClientPtr client, + base::WeakPtr<ServiceWorkerContextCore> context, + base::WeakPtr<ServiceWorkerProviderHost> provider_host, + base::WeakPtr<storage::BlobStorageContext> blob_storage_context, + scoped_refptr<URLLoaderFactoryGetter> loader_factory_getter, + const net::MutableNetworkTrafficAnnotationTag& traffic_annotation); + ~ServiceWorkerScriptURLLoader() override; + + // mojom::URLLoader: + void FollowRedirect() override; + void SetPriority(net::RequestPriority priority, + int32_t intra_priority_value) override; + + // mojom::URLLoaderClient for simply proxying network: + void OnReceiveResponse(const ResourceResponseHead& response_head, + const base::Optional<net::SSLInfo>& ssl_info, + mojom::DownloadedTempFilePtr downloaded_file) override; + void OnReceiveRedirect(const net::RedirectInfo& redirect_info, + const ResourceResponseHead& response_head) override; + void OnDataDownloaded(int64_t data_len, int64_t encoded_data_len) override; + void OnUploadProgress(int64_t current_position, + int64_t total_size, + OnUploadProgressCallback ack_callback) override; + void OnReceiveCachedMetadata(const std::vector<uint8_t>& data) override; + void OnTransferSizeUpdated(int32_t transfer_size_diff) override; + void OnStartLoadingResponseBody( + mojo::ScopedDataPipeConsumerHandle body) override; + void OnComplete(const ResourceRequestCompletionStatus& status) override; + + private: + mojom::URLLoaderPtr network_loader_; + mojo::Binding<mojom::URLLoaderClient> network_client_binding_; + mojom::URLLoaderClientPtr forwarding_client_; + base::WeakPtr<ServiceWorkerProviderHost> provider_host_; + + DISALLOW_COPY_AND_ASSIGN(ServiceWorkerScriptURLLoader); +}; + +} // namespace content + +#endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_SCRIPT_URL_LOADER_H_
diff --git a/content/browser/service_worker/service_worker_script_url_loader_factory.cc b/content/browser/service_worker/service_worker_script_url_loader_factory.cc new file mode 100644 index 0000000..271c3b9 --- /dev/null +++ b/content/browser/service_worker/service_worker_script_url_loader_factory.cc
@@ -0,0 +1,130 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/service_worker/service_worker_script_url_loader_factory.h" + +#include <memory> +#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_script_url_loader.h" +#include "content/browser/service_worker/service_worker_version.h" +#include "content/browser/url_loader_factory_getter.h" +#include "content/common/service_worker/service_worker_utils.h" +#include "content/public/common/resource_response.h" +#include "mojo/public/cpp/bindings/strong_binding.h" +#include "storage/browser/blob/blob_storage_context.h" + +namespace content { + +ServiceWorkerScriptURLLoaderFactory::ServiceWorkerScriptURLLoaderFactory( + base::WeakPtr<ServiceWorkerContextCore> context, + base::WeakPtr<ServiceWorkerProviderHost> provider_host, + base::WeakPtr<storage::BlobStorageContext> blob_storage_context, + scoped_refptr<URLLoaderFactoryGetter> loader_factory_getter) + : context_(context), + provider_host_(provider_host), + blob_storage_context_(blob_storage_context), + loader_factory_getter_(loader_factory_getter) {} + +ServiceWorkerScriptURLLoaderFactory::~ServiceWorkerScriptURLLoaderFactory() = + default; + +void ServiceWorkerScriptURLLoaderFactory::CreateLoaderAndStart( + mojom::URLLoaderRequest request, + int32_t routing_id, + int32_t request_id, + uint32_t options, + const ResourceRequest& resource_request, + mojom::URLLoaderClientPtr client, + const net::MutableNetworkTrafficAnnotationTag& traffic_annotation) { + if (!ShouldHandleScriptRequest(resource_request)) { + // If the request should not be handled by ServiceWorkerScriptURLLoader, + // just fallback to the network. This needs a relaying as we use different + // associated message pipes. + // TODO(kinuko): Record the reason like what we do with netlog in + // ServiceWorkerContextRequestHandler. + (*loader_factory_getter_->GetNetworkFactory()) + ->CreateLoaderAndStart(std::move(request), routing_id, request_id, + options, resource_request, std::move(client), + traffic_annotation); + return; + } + mojo::MakeStrongBinding( + base::MakeUnique<ServiceWorkerScriptURLLoader>( + routing_id, request_id, options, resource_request, std::move(client), + context_, provider_host_, blob_storage_context_, + loader_factory_getter_, traffic_annotation), + std::move(request)); +} + +void ServiceWorkerScriptURLLoaderFactory::Clone( + mojom::URLLoaderFactoryRequest request) { + // This method is required to support synchronous requests which are not + // performed during installation. + NOTREACHED(); +} + +bool ServiceWorkerScriptURLLoaderFactory::ShouldHandleScriptRequest( + const ResourceRequest& resource_request) { + if (!context_ || !provider_host_) + return false; + + // We only use the script cache for main script loading and + // importScripts(), even if a cached script is xhr'd, we don't + // retrieve it from the script cache. + if (resource_request.resource_type != RESOURCE_TYPE_SERVICE_WORKER && + resource_request.resource_type != RESOURCE_TYPE_SCRIPT) { + // TODO: Record bad message, we shouldn't come here for other + // request types. + return false; + } + + scoped_refptr<ServiceWorkerVersion> version = + provider_host_->running_hosted_version(); + + // This could happen if browser-side has set the status to redundant but + // the worker has not yet stopped. The worker is already doomed so just + // reject the request. Handle it specially here because otherwise it'd be + // unclear whether "REDUNDANT" should count as installed or not installed + // when making decisions about how to handle the request and logging UMA. + if (!version || version->status() == ServiceWorkerVersion::REDUNDANT) + return false; + + // TODO: Make sure we don't handle the redirected request. + + // If script streaming is enabled, for installed service workers, typically + // all the scripts are served via script streaming, so we don't come here. + // However, we still come here when the service worker is A) importing a + // script that was never installed, or B) loading the same script twice. + // For now, return false here to fallback to network. Eventually, A) should + // be deprecated (https://crbug.com/719052), and B) should be handled by + // script streaming as well, see the TODO in + // WebServiceWorkerInstalledScriptsManagerImpl::GetRawScriptData(). + // + // When script streaming is not enabled, we get here even for the main + // script. Therefore, ServiceWorkerScriptURLLoader must handle the request + // (even though it currently just does a network fetch for now), because it + // sets the main script's HTTP Response Info (via + // ServiceWorkerVersion::SetMainScriptHttpResponseInfo()) which otherwise + // would never be set. + if (ServiceWorkerVersion::IsInstalled(version->status()) && + ServiceWorkerUtils::IsScriptStreamingEnabled()) { + return false; + } + + // TODO: Make sure we come here only for new / unknown scripts + // once script streaming manager in the renderer side stops sending + // resource requests for the known script URLs, i.e. add DCHECK for + // version->script_cache_map()->LookupResourceId(url) == + // kInvalidServiceWorkerResourceId. + // + // Currently this could be false for the installing worker that imports + // the same script twice (e.g. importScripts('dupe.js'); + // importScripts('dupe.js');). + + // Request should be served by ServiceWorkerScriptURLLoader. + return true; +} + +} // namespace content
diff --git a/content/browser/service_worker/service_worker_script_url_loader_factory.h b/content/browser/service_worker/service_worker_script_url_loader_factory.h new file mode 100644 index 0000000..9b0f768e --- /dev/null +++ b/content/browser/service_worker/service_worker_script_url_loader_factory.h
@@ -0,0 +1,59 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_SCRIPT_URL_LOADER_FACTORY_H_ +#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_SCRIPT_URL_LOADER_FACTORY_H_ + +#include "base/macros.h" +#include "content/public/common/url_loader_factory.mojom.h" + +namespace storage { +class BlobStorageContext; +} // namespace storage + +namespace content { + +class ServiceWorkerContextCore; +class ServiceWorkerProviderHost; +class URLLoaderFactoryGetter; + +// S13nServiceWorker: +// Created per one controller worker for script loading (only during +// installation, eventually). This is kept alive while +// ServiceWorkerNetworkProvider in the renderer process is alive. +// Used only when IsServicificationEnabled is true. +class ServiceWorkerScriptURLLoaderFactory : public mojom::URLLoaderFactory { + public: + ServiceWorkerScriptURLLoaderFactory( + base::WeakPtr<ServiceWorkerContextCore> context, + base::WeakPtr<ServiceWorkerProviderHost> provider_host, + base::WeakPtr<storage::BlobStorageContext> blob_storage_context, + scoped_refptr<URLLoaderFactoryGetter> loader_factory_getter); + ~ServiceWorkerScriptURLLoaderFactory() override; + + // mojom::URLLoaderFactory: + void CreateLoaderAndStart(mojom::URLLoaderRequest request, + int32_t routing_id, + int32_t request_id, + uint32_t options, + const ResourceRequest& resource_request, + mojom::URLLoaderClientPtr client, + const net::MutableNetworkTrafficAnnotationTag& + traffic_annotation) override; + void Clone(mojom::URLLoaderFactoryRequest request) override; + + private: + bool ShouldHandleScriptRequest(const ResourceRequest& resource_request); + + base::WeakPtr<ServiceWorkerContextCore> context_; + base::WeakPtr<ServiceWorkerProviderHost> provider_host_; + base::WeakPtr<storage::BlobStorageContext> blob_storage_context_; + scoped_refptr<URLLoaderFactoryGetter> loader_factory_getter_; + + DISALLOW_COPY_AND_ASSIGN(ServiceWorkerScriptURLLoaderFactory); +}; + +} // namespace content + +#endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_SCRIPT_URL_LOADER_FACTORY_H_
diff --git a/content/browser/service_worker/service_worker_storage.cc b/content/browser/service_worker/service_worker_storage.cc index 1bc1b23..585d157 100644 --- a/content/browser/service_worker/service_worker_storage.cc +++ b/content/browser/service_worker/service_worker_storage.cc
@@ -185,7 +185,7 @@ callback_id, "URL", document_url.spec()); database_task_runner_->PostTask( FROM_HERE, - base::Bind( + base::BindOnce( &FindForDocumentInDB, database_.get(), base::ThreadTaskRunnerHandle::Get(), document_url, base::Bind(&ServiceWorkerStorage::DidFindRegistrationForDocument, @@ -222,7 +222,7 @@ database_task_runner_->PostTask( FROM_HERE, - base::Bind( + base::BindOnce( &FindForPatternInDB, database_.get(), base::ThreadTaskRunnerHandle::Get(), scope, base::Bind(&ServiceWorkerStorage::DidFindRegistrationForPattern, @@ -278,10 +278,11 @@ database_task_runner_->PostTask( FROM_HERE, - base::Bind(&FindForIdInDB, database_.get(), - base::ThreadTaskRunnerHandle::Get(), registration_id, origin, - base::Bind(&ServiceWorkerStorage::DidFindRegistrationForId, - weak_factory_.GetWeakPtr(), callback))); + base::BindOnce(&FindForIdInDB, database_.get(), + base::ThreadTaskRunnerHandle::Get(), registration_id, + origin, + base::Bind(&ServiceWorkerStorage::DidFindRegistrationForId, + weak_factory_.GetWeakPtr(), callback))); } void ServiceWorkerStorage::FindRegistrationForIdOnly( @@ -311,10 +312,10 @@ database_task_runner_->PostTask( FROM_HERE, - base::Bind(&FindForIdOnlyInDB, database_.get(), - base::ThreadTaskRunnerHandle::Get(), registration_id, - base::Bind(&ServiceWorkerStorage::DidFindRegistrationForId, - weak_factory_.GetWeakPtr(), callback))); + base::BindOnce(&FindForIdOnlyInDB, database_.get(), + base::ThreadTaskRunnerHandle::Get(), registration_id, + base::Bind(&ServiceWorkerStorage::DidFindRegistrationForId, + weak_factory_.GetWeakPtr(), callback))); } void ServiceWorkerStorage::GetRegistrationsForOrigin( @@ -421,10 +422,10 @@ database_task_runner_->PostTask( FROM_HERE, - base::Bind(&WriteRegistrationInDB, database_.get(), - base::ThreadTaskRunnerHandle::Get(), data, resources, - base::Bind(&ServiceWorkerStorage::DidStoreRegistration, - weak_factory_.GetWeakPtr(), callback, data))); + base::BindOnce(&WriteRegistrationInDB, database_.get(), + base::ThreadTaskRunnerHandle::Get(), data, resources, + base::Bind(&ServiceWorkerStorage::DidStoreRegistration, + weak_factory_.GetWeakPtr(), callback, data))); registration->set_is_deleted(false); } @@ -458,7 +459,7 @@ database_task_runner_->PostTask( FROM_HERE, - base::Bind( + base::BindOnce( base::IgnoreResult(&ServiceWorkerDatabase::UpdateLastCheckTime), base::Unretained(database_.get()), registration->id(), registration->pattern().GetOrigin(), @@ -522,10 +523,11 @@ database_task_runner_->PostTask( FROM_HERE, - base::Bind(&DeleteRegistrationFromDB, database_.get(), - base::ThreadTaskRunnerHandle::Get(), registration_id, origin, - base::Bind(&ServiceWorkerStorage::DidDeleteRegistration, - weak_factory_.GetWeakPtr(), params))); + base::BindOnce(&DeleteRegistrationFromDB, database_.get(), + base::ThreadTaskRunnerHandle::Get(), registration_id, + origin, + base::Bind(&ServiceWorkerStorage::DidDeleteRegistration, + weak_factory_.GetWeakPtr(), params))); // The registration should no longer be findable. pending_deletions_.insert(registration_id); @@ -657,10 +659,10 @@ database_task_runner_->PostTask( FROM_HERE, - base::Bind(&ServiceWorkerStorage::GetUserDataInDB, database_.get(), - base::ThreadTaskRunnerHandle::Get(), registration_id, keys, - base::Bind(&ServiceWorkerStorage::DidGetUserData, - weak_factory_.GetWeakPtr(), callback))); + base::BindOnce(&ServiceWorkerStorage::GetUserDataInDB, database_.get(), + base::ThreadTaskRunnerHandle::Get(), registration_id, keys, + base::Bind(&ServiceWorkerStorage::DidGetUserData, + weak_factory_.GetWeakPtr(), callback))); } void ServiceWorkerStorage::GetUserDataByKeyPrefix( @@ -691,11 +693,11 @@ database_task_runner_->PostTask( FROM_HERE, - base::Bind(&ServiceWorkerStorage::GetUserDataByKeyPrefixInDB, - database_.get(), base::ThreadTaskRunnerHandle::Get(), - registration_id, key_prefix, - base::Bind(&ServiceWorkerStorage::DidGetUserData, - weak_factory_.GetWeakPtr(), callback))); + base::BindOnce(&ServiceWorkerStorage::GetUserDataByKeyPrefixInDB, + database_.get(), base::ThreadTaskRunnerHandle::Get(), + registration_id, key_prefix, + base::Bind(&ServiceWorkerStorage::DidGetUserData, + weak_factory_.GetWeakPtr(), callback))); } void ServiceWorkerStorage::ClearUserData(int64_t registration_id, @@ -760,7 +762,7 @@ database_task_runner_->PostTask( FROM_HERE, - base::Bind( + base::BindOnce( &ServiceWorkerStorage::GetUserDataForAllRegistrationsInDB, database_.get(), base::ThreadTaskRunnerHandle::Get(), key, base::Bind(&ServiceWorkerStorage::DidGetUserDataForAllRegistrations, @@ -793,7 +795,7 @@ database_task_runner_->PostTask( FROM_HERE, - base::Bind( + base::BindOnce( &ServiceWorkerStorage::GetUserDataForAllRegistrationsByKeyPrefixInDB, database_.get(), base::ThreadTaskRunnerHandle::Get(), key_prefix, base::Bind(&ServiceWorkerStorage::DidGetUserDataForAllRegistrations, @@ -954,10 +956,10 @@ state_ = INITIALIZING; database_task_runner_->PostTask( FROM_HERE, - base::Bind(&ReadInitialDataFromDB, database_.get(), - base::ThreadTaskRunnerHandle::Get(), - base::Bind(&ServiceWorkerStorage::DidReadInitialData, - weak_factory_.GetWeakPtr()))); + base::BindOnce(&ReadInitialDataFromDB, database_.get(), + base::ThreadTaskRunnerHandle::Get(), + base::Bind(&ServiceWorkerStorage::DidReadInitialData, + weak_factory_.GetWeakPtr()))); return false; } @@ -1523,7 +1525,7 @@ std::set<int64_t> ids = {id}; database_task_runner_->PostTask( FROM_HERE, - base::Bind( + base::BindOnce( base::IgnoreResult(&ServiceWorkerDatabase::ClearPurgeableResourceIds), base::Unretained(database_.get()), ids)); @@ -1536,10 +1538,10 @@ has_checked_for_stale_resources_ = true; database_task_runner_->PostTask( FROM_HERE, - base::Bind(&ServiceWorkerStorage::CollectStaleResourcesFromDB, - database_.get(), base::ThreadTaskRunnerHandle::Get(), - base::Bind(&ServiceWorkerStorage::DidCollectStaleResources, - weak_factory_.GetWeakPtr()))); + base::BindOnce(&ServiceWorkerStorage::CollectStaleResourcesFromDB, + database_.get(), base::ThreadTaskRunnerHandle::Get(), + base::Bind(&ServiceWorkerStorage::DidCollectStaleResources, + weak_factory_.GetWeakPtr()))); } void ServiceWorkerStorage::DidCollectStaleResources( @@ -1568,8 +1570,8 @@ } database_task_runner_->PostTask( - FROM_HERE, base::Bind(&DeleteAllDataForOriginsFromDB, database_.get(), - session_only_origins)); + FROM_HERE, base::BindOnce(&DeleteAllDataForOriginsFromDB, database_.get(), + session_only_origins)); } // static @@ -1583,8 +1585,8 @@ if (status != ServiceWorkerDatabase::STATUS_OK) { original_task_runner->PostTask( FROM_HERE, - base::Bind(callback, std::vector<int64_t>(ids.begin(), ids.end()), - status)); + base::BindOnce(callback, std::vector<int64_t>(ids.begin(), ids.end()), + status)); return; } @@ -1592,8 +1594,8 @@ if (status != ServiceWorkerDatabase::STATUS_OK) { original_task_runner->PostTask( FROM_HERE, - base::Bind(callback, std::vector<int64_t>(ids.begin(), ids.end()), - status)); + base::BindOnce(callback, std::vector<int64_t>(ids.begin(), ids.end()), + status)); return; } @@ -1601,8 +1603,8 @@ status = database->GetPurgeableResourceIds(&ids); original_task_runner->PostTask( FROM_HERE, - base::Bind(callback, std::vector<int64_t>(ids.begin(), ids.end()), - status)); + base::BindOnce(callback, std::vector<int64_t>(ids.begin(), ids.end()), + status)); } // static @@ -1620,21 +1622,24 @@ &data->next_resource_id); if (status != ServiceWorkerDatabase::STATUS_OK) { original_task_runner->PostTask( - FROM_HERE, base::Bind(callback, base::Passed(std::move(data)), status)); + FROM_HERE, + base::BindOnce(callback, base::Passed(std::move(data)), status)); return; } status = database->GetOriginsWithRegistrations(&data->origins); if (status != ServiceWorkerDatabase::STATUS_OK) { original_task_runner->PostTask( - FROM_HERE, base::Bind(callback, base::Passed(std::move(data)), status)); + FROM_HERE, + base::BindOnce(callback, base::Passed(std::move(data)), status)); return; } status = database->GetOriginsWithForeignFetchRegistrations( &data->foreign_fetch_origins); original_task_runner->PostTask( - FROM_HERE, base::Bind(callback, base::Passed(std::move(data)), status)); + FROM_HERE, + base::BindOnce(callback, base::Passed(std::move(data)), status)); } void ServiceWorkerStorage::DeleteRegistrationFromDB( @@ -1651,8 +1656,9 @@ registration_id, origin, &deleted_version, &newly_purgeable_resources); if (status != ServiceWorkerDatabase::STATUS_OK) { original_task_runner->PostTask( - FROM_HERE, base::Bind(callback, OriginState::KEEP_ALL, deleted_version, - std::vector<int64_t>(), status)); + FROM_HERE, + base::BindOnce(callback, OriginState::KEEP_ALL, deleted_version, + std::vector<int64_t>(), status)); return; } @@ -1662,8 +1668,9 @@ status = database->GetRegistrationsForOrigin(origin, ®istrations, nullptr); if (status != ServiceWorkerDatabase::STATUS_OK) { original_task_runner->PostTask( - FROM_HERE, base::Bind(callback, OriginState::KEEP_ALL, deleted_version, - std::vector<int64_t>(), status)); + FROM_HERE, + base::BindOnce(callback, OriginState::KEEP_ALL, deleted_version, + std::vector<int64_t>(), status)); return; } @@ -1680,8 +1687,8 @@ } } original_task_runner->PostTask( - FROM_HERE, base::Bind(callback, origin_state, deleted_version, - newly_purgeable_resources, status)); + FROM_HERE, base::BindOnce(callback, origin_state, deleted_version, + newly_purgeable_resources, status)); } void ServiceWorkerStorage::WriteRegistrationInDB( @@ -1695,12 +1702,10 @@ std::vector<int64_t> newly_purgeable_resources; ServiceWorkerDatabase::Status status = database->WriteRegistration( data, resources, &deleted_version, &newly_purgeable_resources); - original_task_runner->PostTask(FROM_HERE, - base::Bind(callback, - data.script.GetOrigin(), - deleted_version, - newly_purgeable_resources, - status)); + original_task_runner->PostTask( + FROM_HERE, + base::BindOnce(callback, data.script.GetOrigin(), deleted_version, + newly_purgeable_resources, status)); } // static @@ -1716,10 +1721,8 @@ if (status != ServiceWorkerDatabase::STATUS_OK) { original_task_runner->PostTask( FROM_HERE, - base::Bind(callback, - ServiceWorkerDatabase::RegistrationData(), - ResourceList(), - status)); + base::BindOnce(callback, ServiceWorkerDatabase::RegistrationData(), + ResourceList(), status)); return; } @@ -1737,8 +1740,7 @@ status = database->ReadRegistration(match, origin, &data, &resources); original_task_runner->PostTask( - FROM_HERE, - base::Bind(callback, data, resources, status)); + FROM_HERE, base::BindOnce(callback, data, resources, status)); } // static @@ -1754,10 +1756,8 @@ if (status != ServiceWorkerDatabase::STATUS_OK) { original_task_runner->PostTask( FROM_HERE, - base::Bind(callback, - ServiceWorkerDatabase::RegistrationData(), - ResourceList(), - status)); + base::BindOnce(callback, ServiceWorkerDatabase::RegistrationData(), + ResourceList(), status)); return; } @@ -1774,8 +1774,7 @@ } original_task_runner->PostTask( - FROM_HERE, - base::Bind(callback, data, resources, status)); + FROM_HERE, base::BindOnce(callback, data, resources, status)); } // static @@ -1790,7 +1789,7 @@ ServiceWorkerDatabase::Status status = database->ReadRegistration(registration_id, origin, &data, &resources); original_task_runner->PostTask( - FROM_HERE, base::Bind(callback, data, resources, status)); + FROM_HERE, base::BindOnce(callback, data, resources, status)); } // static @@ -1805,8 +1804,8 @@ if (status != ServiceWorkerDatabase::STATUS_OK) { original_task_runner->PostTask( FROM_HERE, - base::Bind(callback, ServiceWorkerDatabase::RegistrationData(), - ResourceList(), status)); + base::BindOnce(callback, ServiceWorkerDatabase::RegistrationData(), + ResourceList(), status)); return; } FindForIdInDB(database, original_task_runner, registration_id, origin, @@ -1823,7 +1822,7 @@ ServiceWorkerDatabase::Status status = database->ReadUserData(registration_id, keys, &values); original_task_runner->PostTask(FROM_HERE, - base::Bind(callback, values, status)); + base::BindOnce(callback, values, status)); } void ServiceWorkerStorage::GetUserDataByKeyPrefixInDB( @@ -1836,7 +1835,7 @@ ServiceWorkerDatabase::Status status = database->ReadUserDataByKeyPrefix(registration_id, key_prefix, &values); original_task_runner->PostTask(FROM_HERE, - base::Bind(callback, values, status)); + base::BindOnce(callback, values, status)); } void ServiceWorkerStorage::GetUserDataForAllRegistrationsInDB( @@ -1848,7 +1847,7 @@ ServiceWorkerDatabase::Status status = database->ReadUserDataForAllRegistrations(key, &user_data); original_task_runner->PostTask(FROM_HERE, - base::Bind(callback, user_data, status)); + base::BindOnce(callback, user_data, status)); } void ServiceWorkerStorage::GetUserDataForAllRegistrationsByKeyPrefixInDB( @@ -1861,7 +1860,7 @@ database->ReadUserDataForAllRegistrationsByKeyPrefix(key_prefix, &user_data); original_task_runner->PostTask(FROM_HERE, - base::Bind(callback, user_data, status)); + base::BindOnce(callback, user_data, status)); } void ServiceWorkerStorage::DeleteAllDataForOriginsFromDB(
diff --git a/content/browser/service_worker/service_worker_storage.h b/content/browser/service_worker/service_worker_storage.h index 243428f..3c52693 100644 --- a/content/browser/service_worker/service_worker_storage.h +++ b/content/browser/service_worker/service_worker_storage.h
@@ -51,7 +51,7 @@ // disabled and all subsequent requests are aborted until the context core is // restarted. class CONTENT_EXPORT ServiceWorkerStorage - : NON_EXPORTED_BASE(public ServiceWorkerVersion::Listener) { + : public ServiceWorkerVersion::Listener { public: typedef std::vector<ServiceWorkerDatabase::ResourceRecord> ResourceList; typedef base::Callback<void(ServiceWorkerStatusCode status)> StatusCallback;
diff --git a/content/browser/service_worker/service_worker_url_loader_job.cc b/content/browser/service_worker/service_worker_url_loader_job.cc index d391354..b714e79 100644 --- a/content/browser/service_worker/service_worker_url_loader_job.cc +++ b/content/browser/service_worker/service_worker_url_loader_job.cc
@@ -256,9 +256,9 @@ ssl_info_ = main_script_http_info->ssl_info; std::move(loader_callback_) - .Run(base::Bind(&ServiceWorkerURLLoaderJob::StartResponse, - weak_factory_.GetWeakPtr(), response, - base::Passed(std::move(body_as_stream)))); + .Run(base::BindOnce(&ServiceWorkerURLLoaderJob::StartResponse, + weak_factory_.GetWeakPtr(), response, + base::Passed(std::move(body_as_stream)))); } void ServiceWorkerURLLoaderJob::StartResponse( @@ -268,8 +268,8 @@ mojom::URLLoaderClientPtr client) { DCHECK(!binding_.is_bound()); binding_.Bind(std::move(request)); - binding_.set_connection_error_handler( - base::Bind(&ServiceWorkerURLLoaderJob::Cancel, base::Unretained(this))); + binding_.set_connection_error_handler(base::BindOnce( + &ServiceWorkerURLLoaderJob::Cancel, base::Unretained(this))); url_loader_client_ = std::move(client); SaveResponseInfo(response);
diff --git a/content/browser/service_worker/service_worker_url_request_job.cc b/content/browser/service_worker/service_worker_url_request_job.cc index 308c212d..b823d19 100644 --- a/content/browser/service_worker/service_worker_url_request_job.cc +++ b/content/browser/service_worker/service_worker_url_request_job.cc
@@ -510,8 +510,8 @@ if (is_started_ && response_type_ != NOT_DETERMINED) { // Start asynchronously. base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(&ServiceWorkerURLRequestJob::StartRequest, - weak_factory_.GetWeakPtr())); + FROM_HERE, base::BindOnce(&ServiceWorkerURLRequestJob::StartRequest, + weak_factory_.GetWeakPtr())); } }
diff --git a/content/browser/service_worker/service_worker_url_request_job_unittest.cc b/content/browser/service_worker/service_worker_url_request_job_unittest.cc index aeee1fc..5791896 100644 --- a/content/browser/service_worker/service_worker_url_request_job_unittest.cc +++ b/content/browser/service_worker/service_worker_url_request_job_unittest.cc
@@ -353,8 +353,8 @@ // it might respond synchronously, and the TestDelegate would complain that // the message loop isn't being run. base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(&ServiceWorkerVersion::SetStatus, version_, - ServiceWorkerVersion::REDUNDANT)); + FROM_HERE, base::BindOnce(&ServiceWorkerVersion::SetStatus, version_, + ServiceWorkerVersion::REDUNDANT)); base::RunLoop().RunUntilIdle(); }
diff --git a/content/browser/service_worker/service_worker_version.cc b/content/browser/service_worker/service_worker_version.cc index 2287915..c55a06862 100644 --- a/content/browser/service_worker/service_worker_version.cc +++ b/content/browser/service_worker/service_worker_version.cc
@@ -1110,9 +1110,9 @@ if (!url.is_valid()) { DVLOG(1) << "Received unexpected invalid URL from renderer process."; BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, - base::Bind(&KillEmbeddedWorkerProcess, - embedded_worker_->process_id(), - RESULT_CODE_KILLED_BAD_MESSAGE)); + base::BindOnce(&KillEmbeddedWorkerProcess, + embedded_worker_->process_id(), + RESULT_CODE_KILLED_BAD_MESSAGE)); return; } @@ -1273,10 +1273,10 @@ if (!url.is_valid() || !base::IsValidGUID(client_uuid)) { DVLOG(1) << "Received unexpected invalid URL/UUID from renderer process."; - BrowserThread::PostTask( - BrowserThread::UI, FROM_HERE, - base::Bind(&KillEmbeddedWorkerProcess, embedded_worker_->process_id(), - RESULT_CODE_KILLED_BAD_MESSAGE)); + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, + base::BindOnce(&KillEmbeddedWorkerProcess, + embedded_worker_->process_id(), + RESULT_CODE_KILLED_BAD_MESSAGE)); return; } @@ -1388,20 +1388,20 @@ !base::StartsWith(url.path(), scope_path, base::CompareCase::SENSITIVE)) { DVLOG(1) << "Received unexpected invalid URL from renderer process."; - BrowserThread::PostTask( - BrowserThread::UI, FROM_HERE, - base::Bind(&KillEmbeddedWorkerProcess, embedded_worker_->process_id(), - RESULT_CODE_KILLED_BAD_MESSAGE)); + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, + base::BindOnce(&KillEmbeddedWorkerProcess, + embedded_worker_->process_id(), + RESULT_CODE_KILLED_BAD_MESSAGE)); return; } } for (const url::Origin& url : origins) { if (url.unique()) { DVLOG(1) << "Received unexpected unique origin from renderer process."; - BrowserThread::PostTask( - BrowserThread::UI, FROM_HERE, - base::Bind(&KillEmbeddedWorkerProcess, embedded_worker_->process_id(), - RESULT_CODE_KILLED_BAD_MESSAGE)); + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, + base::BindOnce(&KillEmbeddedWorkerProcess, + embedded_worker_->process_id(), + RESULT_CODE_KILLED_BAD_MESSAGE)); return; } } @@ -1525,7 +1525,7 @@ mojo::MakeRequest(&event_dispatcher_), std::move(installed_scripts_info), base::Bind(&ServiceWorkerVersion::OnStartSentAndScriptEvaluated, weak_factory_.GetWeakPtr())); - event_dispatcher_.set_connection_error_handler(base::Bind( + event_dispatcher_.set_connection_error_handler(base::BindOnce( &OnEventDispatcherConnectionError, embedded_worker_->AsWeakPtr())); } @@ -1666,8 +1666,8 @@ DCHECK(running_status() == EmbeddedWorkerStatus::STARTING || running_status() == EmbeddedWorkerStatus::RUNNING); // base::Unretained here is safe because event_dispatcher is owned by |this|. - event_dispatcher()->Ping(base::Bind(&ServiceWorkerVersion::OnPongFromWorker, - base::Unretained(this))); + event_dispatcher()->Ping(base::BindOnce( + &ServiceWorkerVersion::OnPongFromWorker, base::Unretained(this))); } void ServiceWorkerVersion::OnPingTimeout() {
diff --git a/content/browser/service_worker/service_worker_version.h b/content/browser/service_worker/service_worker_version.h index 4c455a9..6766abe 100644 --- a/content/browser/service_worker/service_worker_version.h +++ b/content/browser/service_worker/service_worker_version.h
@@ -67,7 +67,7 @@ // one of them is activated. This class connects the actual script with a // running worker. class CONTENT_EXPORT ServiceWorkerVersion - : NON_EXPORTED_BASE(public base::RefCounted<ServiceWorkerVersion>), + : public base::RefCounted<ServiceWorkerVersion>, public EmbeddedWorkerInstance::Listener { public: using StatusCallback = base::Callback<void(ServiceWorkerStatusCode)>;
diff --git a/content/browser/service_worker/service_worker_write_to_cache_job.cc b/content/browser/service_worker/service_worker_write_to_cache_job.cc index 988c3d4b..85efd96 100644 --- a/content/browser/service_worker/service_worker_write_to_cache_job.cc +++ b/content/browser/service_worker/service_worker_write_to_cache_job.cc
@@ -98,8 +98,8 @@ void ServiceWorkerWriteToCacheJob::Start() { base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(&ServiceWorkerWriteToCacheJob::StartAsync, - weak_factory_.GetWeakPtr())); + FROM_HERE, base::BindOnce(&ServiceWorkerWriteToCacheJob::StartAsync, + weak_factory_.GetWeakPtr())); } void ServiceWorkerWriteToCacheJob::StartAsync() {
diff --git a/content/browser/service_worker/service_worker_write_to_cache_job_unittest.cc b/content/browser/service_worker/service_worker_write_to_cache_job_unittest.cc index eb622080..86a14a0 100644 --- a/content/browser/service_worker/service_worker_write_to_cache_job_unittest.cc +++ b/content/browser/service_worker/service_worker_write_to_cache_job_unittest.cc
@@ -117,8 +117,8 @@ weak_factory_(this) {} void Start() override { base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(&SSLCertificateErrorJob::NotifyError, - weak_factory_.GetWeakPtr())); + FROM_HERE, base::BindOnce(&SSLCertificateErrorJob::NotifyError, + weak_factory_.GetWeakPtr())); } void NotifyError() { net::SSLInfo info; @@ -127,8 +127,8 @@ } void ContinueDespiteLastError() override { base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(&SSLCertificateErrorJob::StartAsync, - weak_factory_.GetWeakPtr())); + FROM_HERE, base::BindOnce(&SSLCertificateErrorJob::StartAsync, + weak_factory_.GetWeakPtr())); } protected:
diff --git a/content/browser/shared_worker/shared_worker_content_settings_proxy_impl.h b/content/browser/shared_worker/shared_worker_content_settings_proxy_impl.h index e991507c..6d29404 100644 --- a/content/browser/shared_worker/shared_worker_content_settings_proxy_impl.h +++ b/content/browser/shared_worker/shared_worker_content_settings_proxy_impl.h
@@ -21,7 +21,7 @@ // at the moment. // Kept alive while the connection is held in the renderer. class CONTENT_EXPORT SharedWorkerContentSettingsProxyImpl - : NON_EXPORTED_BASE(public blink::mojom::WorkerContentSettingsProxy) { + : public blink::mojom::WorkerContentSettingsProxy { public: ~SharedWorkerContentSettingsProxyImpl() override;
diff --git a/content/browser/shared_worker/shared_worker_host.cc b/content/browser/shared_worker/shared_worker_host.cc index b938494..ee96638 100644 --- a/content/browser/shared_worker/shared_worker_host.cc +++ b/content/browser/shared_worker/shared_worker_host.cc
@@ -26,11 +26,9 @@ void NotifyWorkerReadyForInspection(int worker_process_id, int worker_route_id) { if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { - BrowserThread::PostTask(BrowserThread::UI, - FROM_HERE, - base::Bind(NotifyWorkerReadyForInspection, - worker_process_id, - worker_route_id)); + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, + base::BindOnce(NotifyWorkerReadyForInspection, + worker_process_id, worker_route_id)); return; } SharedWorkerDevToolsManager::GetInstance()->WorkerReadyForInspection( @@ -39,10 +37,9 @@ void NotifyWorkerDestroyed(int worker_process_id, int worker_route_id) { if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { - BrowserThread::PostTask( - BrowserThread::UI, - FROM_HERE, - base::Bind(NotifyWorkerDestroyed, worker_process_id, worker_route_id)); + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, + base::BindOnce(NotifyWorkerDestroyed, + worker_process_id, worker_route_id)); return; } SharedWorkerDevToolsManager::GetInstance()->WorkerDestroyed(
diff --git a/content/browser/shared_worker/shared_worker_service_impl.cc b/content/browser/shared_worker/shared_worker_service_impl.cc index 2fb572b..7150ea7e 100644 --- a/content/browser/shared_worker/shared_worker_service_impl.cc +++ b/content/browser/shared_worker/shared_worker_service_impl.cc
@@ -32,7 +32,7 @@ bool IsHostAlive(RenderProcessHostImpl* host) { return host && !host->FastShutdownStarted() && - !host->IsWorkerRefCountDisabled(); + !host->IsKeepAliveRefCountDisabled(); } namespace { @@ -63,8 +63,9 @@ worker_process_id, worker_route_id, is_new_worker, instance)); BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, - base::Bind(&SharedWorkerReserver::TryReserveOnUI, std::move(reserver), - success_cb, failure_cb, try_increment_worker_ref_count)); + base::BindOnce(&SharedWorkerReserver::TryReserveOnUI, + std::move(reserver), success_cb, failure_cb, + try_increment_worker_ref_count)); } private: @@ -99,8 +100,8 @@ DCHECK_CURRENTLY_ON(BrowserThread::UI); BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, - base::Bind(callback, worker_process_id_, worker_route_id_, - is_new_worker_, pause_on_start)); + base::BindOnce(callback, worker_process_id_, worker_route_id_, + is_new_worker_, pause_on_start)); } const int worker_process_id_; @@ -135,37 +136,36 @@ static_cast<RenderProcessHostImpl*>(RenderProcessHost::FromID(id)); if (!IsHostAlive(render_process_host_impl)) continue; - render_process_host_impl->IncrementSharedWorkerRefCount(); + render_process_host_impl->IncrementKeepAliveRefCount(); } for (int id : removed_ids) { RenderProcessHostImpl* render_process_host_impl = static_cast<RenderProcessHostImpl*>(RenderProcessHost::FromID(id)); if (!IsHostAlive(render_process_host_impl)) continue; - render_process_host_impl->DecrementSharedWorkerRefCount(); + render_process_host_impl->DecrementKeepAliveRefCount(); } } void UpdateWorkerDependency(const std::vector<int>& added_ids, const std::vector<int>& removed_ids) { BrowserThread::PostTask( - BrowserThread::UI, - FROM_HERE, - base::Bind(&UpdateWorkerDependencyOnUI, added_ids, removed_ids)); + BrowserThread::UI, FROM_HERE, + base::BindOnce(&UpdateWorkerDependencyOnUI, added_ids, removed_ids)); } void DecrementWorkerRefCount(int process_id) { if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { - BrowserThread::PostTask(BrowserThread::UI, - FROM_HERE, - base::Bind(&DecrementWorkerRefCount, process_id)); + BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, + base::BindOnce(&DecrementWorkerRefCount, process_id)); return; } RenderProcessHostImpl* render_process_host_impl = static_cast<RenderProcessHostImpl*>( RenderProcessHost::FromID(process_id)); if (IsHostAlive(render_process_host_impl)) - render_process_host_impl->DecrementSharedWorkerRefCount(); + render_process_host_impl->DecrementKeepAliveRefCount(); } bool TryIncrementWorkerRefCount(int worker_process_id) { @@ -173,7 +173,7 @@ RenderProcessHost::FromID(worker_process_id)); if (!IsHostAlive(render_process)) return false; - render_process->IncrementSharedWorkerRefCount(); + render_process->IncrementKeepAliveRefCount(); return true; }
diff --git a/content/browser/shared_worker/shared_worker_service_impl.h b/content/browser/shared_worker/shared_worker_service_impl.h index c9a5d4f..b8ae503 100644 --- a/content/browser/shared_worker/shared_worker_service_impl.h +++ b/content/browser/shared_worker/shared_worker_service_impl.h
@@ -34,8 +34,7 @@ // The implementation of WorkerService. We try to place workers in an existing // renderer process when possible. -class CONTENT_EXPORT SharedWorkerServiceImpl - : public NON_EXPORTED_BASE(WorkerService) { +class CONTENT_EXPORT SharedWorkerServiceImpl : public WorkerService { public: // Returns the SharedWorkerServiceImpl singleton. static SharedWorkerServiceImpl* GetInstance();
diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc index e159471..36344912 100644 --- a/content/browser/site_per_process_browsertest.cc +++ b/content/browser/site_per_process_browsertest.cc
@@ -30,6 +30,7 @@ #include "build/build_config.h" #include "cc/input/touch_action.h" #include "components/network_session_configurator/common/network_switches.h" +#include "content/browser/child_process_importance.h" #include "content/browser/frame_host/cross_process_frame_connector.h" #include "content/browser/frame_host/frame_navigation_entry.h" #include "content/browser/frame_host/frame_tree.h" @@ -8491,12 +8492,12 @@ // Prevent b.com process from terminating right away once the subframe // navigates away from b.com below. This is necessary so that the renderer // process has time to process the closings of RenderWidget and RenderView, - // which is where the original bug was triggered. Incrementing worker - // RefCount will cause RenderProcessHostImpl::Cleanup to forego process + // which is where the original bug was triggered. Incrementing the keep alive + // ref count will cause RenderProcessHostImpl::Cleanup to forego process // termination. RenderProcessHost* subframe_process = root->child_at(0)->current_frame_host()->GetProcess(); - subframe_process->IncrementSharedWorkerRefCount(); + subframe_process->IncrementKeepAliveRefCount(); // Navigate the subframe away from b.com. Since this is the last active // frame in the b.com process, this causes the RenderWidget and RenderView to @@ -8518,7 +8519,7 @@ // process hasn't heard the OnChannelError yet). This race will need to be // fixed. - subframe_process->DecrementSharedWorkerRefCount(); + subframe_process->DecrementKeepAliveRefCount(); } // Tests that an input event targeted to a out-of-process iframe correctly @@ -10984,6 +10985,98 @@ ->GetProcess()); } +IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, TestChildProcessImportance) { + web_contents()->SetImportance(ChildProcessImportance::MODERATE); + + // Construct root page with one child in different domain. + GURL main_url(embedded_test_server()->GetURL( + "a.com", "/cross_site_iframe_factory.html?a(b)")); + EXPECT_TRUE(NavigateToURL(shell(), main_url)); + FrameTreeNode* root = web_contents()->GetFrameTree()->root(); + ASSERT_EQ(1u, root->child_count()); + FrameTreeNode* child = root->child_at(0); + + // Importance should survive initial navigation. + EXPECT_EQ(ChildProcessImportance::MODERATE, + static_cast<RenderProcessHostImpl*>( + root->current_frame_host()->GetProcess()) + ->GetWidgetImportanceForTesting()); + EXPECT_EQ(ChildProcessImportance::MODERATE, + static_cast<RenderProcessHostImpl*>( + child->current_frame_host()->GetProcess()) + ->GetWidgetImportanceForTesting()); + + // Check setting importance. + web_contents()->SetImportance(ChildProcessImportance::NORMAL); + EXPECT_EQ(ChildProcessImportance::NORMAL, + static_cast<RenderProcessHostImpl*>( + root->current_frame_host()->GetProcess()) + ->GetWidgetImportanceForTesting()); + EXPECT_EQ(ChildProcessImportance::NORMAL, + static_cast<RenderProcessHostImpl*>( + child->current_frame_host()->GetProcess()) + ->GetWidgetImportanceForTesting()); + web_contents()->SetImportance(ChildProcessImportance::IMPORTANT); + EXPECT_EQ(ChildProcessImportance::IMPORTANT, + static_cast<RenderProcessHostImpl*>( + root->current_frame_host()->GetProcess()) + ->GetWidgetImportanceForTesting()); + EXPECT_EQ(ChildProcessImportance::IMPORTANT, + static_cast<RenderProcessHostImpl*>( + child->current_frame_host()->GetProcess()) + ->GetWidgetImportanceForTesting()); + + // Check importance is maintained if child navigates to new domain. + int old_child_process_id = child->current_frame_host()->GetProcess()->GetID(); + GURL url = embedded_test_server()->GetURL("foo.com", "/title2.html"); + { + RenderFrameDeletedObserver deleted_observer(child->current_frame_host()); + NavigateFrameToURL(root->child_at(0), url); + deleted_observer.WaitUntilDeleted(); + } + int new_child_process_id = child->current_frame_host()->GetProcess()->GetID(); + EXPECT_NE(old_child_process_id, new_child_process_id); + EXPECT_EQ(ChildProcessImportance::IMPORTANT, + static_cast<RenderProcessHostImpl*>( + child->current_frame_host()->GetProcess()) + ->GetWidgetImportanceForTesting()); + + // Check importance is maintained if root navigates to new domain. + int old_root_process_id = root->current_frame_host()->GetProcess()->GetID(); + child = nullptr; // Going to navigate root to page without any child. + { + RenderFrameDeletedObserver deleted_observer(root->current_frame_host()); + NavigateFrameToURL(root, url); + deleted_observer.WaitUntilDeleted(); + } + EXPECT_EQ(0u, root->child_count()); + int new_root_process_id = root->current_frame_host()->GetProcess()->GetID(); + EXPECT_NE(old_root_process_id, new_root_process_id); + EXPECT_EQ(ChildProcessImportance::IMPORTANT, + static_cast<RenderProcessHostImpl*>( + root->current_frame_host()->GetProcess()) + ->GetWidgetImportanceForTesting()); + + // Check interstitial maintains importance. + TestInterstitialDelegate* delegate = new TestInterstitialDelegate; + WebContentsImpl* contents_impl = + static_cast<WebContentsImpl*>(web_contents()); + GURL interstitial_url("http://interstitial"); + InterstitialPageImpl* interstitial = new InterstitialPageImpl( + contents_impl, contents_impl, true, interstitial_url, delegate); + interstitial->Show(); + WaitForInterstitialAttach(contents_impl); + RenderProcessHostImpl* interstitial_process = + static_cast<RenderProcessHostImpl*>( + interstitial->GetMainFrame()->GetProcess()); + EXPECT_EQ(ChildProcessImportance::IMPORTANT, + interstitial_process->GetWidgetImportanceForTesting()); + + web_contents()->SetImportance(ChildProcessImportance::MODERATE); + EXPECT_EQ(ChildProcessImportance::MODERATE, + interstitial_process->GetWidgetImportanceForTesting()); +} + #if defined(OS_ANDROID) // Tests for Android TouchSelectionEditing. class TouchSelectionControllerClientAndroidSiteIsolationTest
diff --git a/content/browser/speech/speech_recognition_manager_impl.h b/content/browser/speech/speech_recognition_manager_impl.h index 8c18de8c..7626cfe 100644 --- a/content/browser/speech/speech_recognition_manager_impl.h +++ b/content/browser/speech/speech_recognition_manager_impl.h
@@ -50,9 +50,9 @@ // corresponding listener (demuxing on the base of their session_id). // - Relays also recognition results/status/error events of every session to // the catch-all snoop listener (optionally) provided by the delegate. -class CONTENT_EXPORT SpeechRecognitionManagerImpl : - public NON_EXPORTED_BASE(SpeechRecognitionManager), - public SpeechRecognitionEventListener { +class CONTENT_EXPORT SpeechRecognitionManagerImpl + : public SpeechRecognitionManager, + public SpeechRecognitionEventListener { public: // Returns the current SpeechRecognitionManagerImpl or NULL if the call is // issued when it is not created yet or destroyed (by BrowserMainLoop).
diff --git a/content/browser/speech/speech_recognizer_impl.h b/content/browser/speech/speech_recognizer_impl.h index 711b501..74d97c2 100644 --- a/content/browser/speech/speech_recognizer_impl.h +++ b/content/browser/speech/speech_recognizer_impl.h
@@ -35,7 +35,7 @@ : public SpeechRecognizer, public media::AudioInputController::EventHandler, public media::AudioInputController::SyncWriter, - public NON_EXPORTED_BASE(SpeechRecognitionEngine::Delegate) { + public SpeechRecognitionEngine::Delegate { public: static const int kAudioSampleRate; static const media::ChannelLayout kChannelLayout;
diff --git a/content/browser/storage_partition_impl.h b/content/browser/storage_partition_impl.h index 511f0771..ebeffa7 100644 --- a/content/browser/storage_partition_impl.h +++ b/content/browser/storage_partition_impl.h
@@ -47,7 +47,7 @@ class CONTENT_EXPORT StoragePartitionImpl : public StoragePartition, - public NON_EXPORTED_BASE(mojom::StoragePartitionService) { + public mojom::StoragePartitionService { public: // It is guaranteed that storage partitions are destructed before the // browser context starts shutting down its corresponding IO thread residents
diff --git a/content/browser/utility_process_host_impl.cc b/content/browser/utility_process_host_impl.cc index 5d89664..8bcbc8ce0 100644 --- a/content/browser/utility_process_host_impl.cc +++ b/content/browser/utility_process_host_impl.cc
@@ -278,6 +278,7 @@ #endif switches::kUseFakeDeviceForMediaStream, switches::kUseFileForFakeVideoCapture, + switches::kUtilityStartupDialog, }; cmd_line->CopySwitchesFrom(browser_command_line, kSwitchNames, arraysize(kSwitchNames));
diff --git a/content/browser/utility_process_host_impl.h b/content/browser/utility_process_host_impl.h index b0a37bb9..ecfc91c 100644 --- a/content/browser/utility_process_host_impl.h +++ b/content/browser/utility_process_host_impl.h
@@ -29,7 +29,7 @@ const InProcessChildThreadParams&); class CONTENT_EXPORT UtilityProcessHostImpl - : public NON_EXPORTED_BASE(UtilityProcessHost), + : public UtilityProcessHost, public BrowserChildProcessHostDelegate { public: static void RegisterUtilityMainThreadFactory(
diff --git a/content/browser/web_contents/web_contents_android.cc b/content/browser/web_contents/web_contents_android.cc index 192af3a2..caed2345 100644 --- a/content/browser/web_contents/web_contents_android.cc +++ b/content/browser/web_contents/web_contents_android.cc
@@ -338,6 +338,13 @@ web_contents_->WasShown(); } +void WebContentsAndroid::SetImportance( + JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj, + jint importance) { + web_contents_->SetImportance(static_cast<ChildProcessImportance>(importance)); +} + void WebContentsAndroid::SuspendAllMediaPlayers( JNIEnv* env, const JavaParamRef<jobject>& jobj) {
diff --git a/content/browser/web_contents/web_contents_android.h b/content/browser/web_contents/web_contents_android.h index 693da85..fa942a9 100644 --- a/content/browser/web_contents/web_contents_android.h +++ b/content/browser/web_contents/web_contents_android.h
@@ -84,6 +84,9 @@ void OnHide(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj); void OnShow(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj); + void SetImportance(JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj, + jint importance); void SuspendAllMediaPlayers(JNIEnv* env, const base::android::JavaParamRef<jobject>& jobj); void SetAudioMuted(JNIEnv* env,
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index bec99bd..2cc0af0e 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc
@@ -1539,6 +1539,25 @@ should_normally_be_visible_ = false; } +void WebContentsImpl::SetImportance(ChildProcessImportance importance) { + // Not calling GetRenderWidgetHostView since importance should be set on both + // the interstitial and underlying page. + std::set<RenderWidgetHostImpl*> set; + if (ShowingInterstitialPage()) { + set.insert( + static_cast<RenderFrameHostImpl*>(interstitial_page_->GetMainFrame()) + ->GetRenderWidgetHost()); + } + for (RenderFrameHost* rfh : GetAllFrames()) + set.insert(static_cast<RenderFrameHostImpl*>(rfh)->GetRenderWidgetHost()); + for (RenderWidgetHostImpl* host : set) { + DCHECK(host); + host->SetImportance(importance); + } + // TODO(boliu): If this is ever used on platforms other than Android, make + // sure to also update inner WebContents. +} + bool WebContentsImpl::IsVisible() const { return should_normally_be_visible_; } @@ -2957,6 +2976,11 @@ GetRenderManager()->SetRWHViewForInnerContents(view); } } + + // Update importance of the interstitial. + static_cast<RenderFrameHostImpl*>(interstitial_page_->GetMainFrame()) + ->GetRenderWidgetHost() + ->SetImportance(GetMainFrame()->GetRenderWidgetHost()->importance()); } void WebContentsImpl::DidProceedOnInterstitial() { @@ -4446,6 +4470,17 @@ void WebContentsImpl::NotifyFrameSwapped(RenderFrameHost* old_host, RenderFrameHost* new_host) { + // Try to copy importance from either |old_host| or parent of |new_host|. + // If both are null, then this is the very first frame host created from Init. + // There is no need to pass importance in this case because there is no chance + // for anything to call SetImportance yet. + RenderFrameHostImpl* importance_host = static_cast<RenderFrameHostImpl*>( + old_host ? old_host : new_host->GetParent()); + if (importance_host) { + static_cast<RenderFrameHostImpl*>(new_host) + ->GetRenderWidgetHost() + ->SetImportance(importance_host->GetRenderWidgetHost()->importance()); + } for (auto& observer : observers_) observer.RenderFrameHostChanged(old_host, new_host); }
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h index bf33494..4310d773 100644 --- a/content/browser/web_contents/web_contents_impl.h +++ b/content/browser/web_contents/web_contents_impl.h
@@ -20,6 +20,7 @@ #include "base/process/process.h" #include "base/values.h" #include "build/build_config.h" +#include "content/browser/child_process_importance.h" #include "content/browser/frame_host/frame_tree.h" #include "content/browser/frame_host/frame_tree_node.h" #include "content/browser/frame_host/navigation_controller_delegate.h" @@ -119,15 +120,14 @@ WebContentsViewDelegate* delegate, RenderViewHostDelegateView** render_view_host_delegate_view); -class CONTENT_EXPORT WebContentsImpl - : public NON_EXPORTED_BASE(WebContents), - public NON_EXPORTED_BASE(RenderFrameHostDelegate), - public RenderViewHostDelegate, - public RenderWidgetHostDelegate, - public RenderFrameHostManager::Delegate, - public NotificationObserver, - public NON_EXPORTED_BASE(NavigationControllerDelegate), - public NON_EXPORTED_BASE(NavigatorDelegate) { +class CONTENT_EXPORT WebContentsImpl : public WebContents, + public RenderFrameHostDelegate, + public RenderViewHostDelegate, + public RenderWidgetHostDelegate, + public RenderFrameHostManager::Delegate, + public NotificationObserver, + public NavigationControllerDelegate, + public NavigatorDelegate { public: class FriendWrapper; @@ -296,6 +296,13 @@ void NotifyManifestUrlChanged(const base::Optional<GURL>& manifest_url); + // Set importance of WebContents that's independent from visibility. + // + // Note this is only used by and implemented on Android which exposes this API + // through public java code. If this is useful on other platforms, then this + // can be moved to the public class. + void SetImportance(ChildProcessImportance importance); + // WebContents ------------------------------------------------------ WebContentsDelegate* GetDelegate() override; void SetDelegate(WebContentsDelegate* delegate) override;
diff --git a/content/browser/web_contents/web_contents_view_aura.h b/content/browser/web_contents/web_contents_view_aura.h index 55a55dc2..7979b48 100644 --- a/content/browser/web_contents/web_contents_view_aura.h +++ b/content/browser/web_contents/web_contents_view_aura.h
@@ -42,7 +42,7 @@ class WebDragDestDelegate; class CONTENT_EXPORT WebContentsViewAura - : NON_EXPORTED_BASE(public WebContentsView), + : public WebContentsView, public RenderViewHostDelegateView, public OverscrollControllerDelegate, public aura::WindowDelegate,
diff --git a/content/browser/web_contents/web_contents_view_mac.mm b/content/browser/web_contents/web_contents_view_mac.mm index f5eefa1..a9111f9 100644 --- a/content/browser/web_contents/web_contents_view_mac.mm +++ b/content/browser/web_contents/web_contents_view_mac.mm
@@ -677,6 +677,9 @@ - (void)setFrameSize:(NSSize)newSize { [super setFrameSize:newSize]; + if (webContentsView_ && webContentsView_->delegate()) + webContentsView_->delegate()->SizeChanged(gfx::Size(newSize)); + // Perform manual layout of subviews, e.g., when the window size changes. for (NSView* subview in [self subviews]) [subview setFrame:[self bounds]];
diff --git a/content/browser/webauth/authenticator_impl.h b/content/browser/webauth/authenticator_impl.h index 99ae045c..3a2dbd09 100644 --- a/content/browser/webauth/authenticator_impl.h +++ b/content/browser/webauth/authenticator_impl.h
@@ -20,8 +20,7 @@ class RenderFrameHost; // Implementation of the public Authenticator interface. -class CONTENT_EXPORT AuthenticatorImpl - : public NON_EXPORTED_BASE(webauth::mojom::Authenticator) { +class CONTENT_EXPORT AuthenticatorImpl : public webauth::mojom::Authenticator { public: static void Create(RenderFrameHost* render_frame_host, webauth::mojom::AuthenticatorRequest request); @@ -46,4 +45,4 @@ } // namespace content -#endif // CONTENT_BROWSER_WEBAUTH_AUTHENTICATOR_IMPL_H_ \ No newline at end of file +#endif // CONTENT_BROWSER_WEBAUTH_AUTHENTICATOR_IMPL_H_
diff --git a/content/browser/webrtc/webrtc_internals_message_handler.h b/content/browser/webrtc/webrtc_internals_message_handler.h index d5d2128..1e8d14d7 100644 --- a/content/browser/webrtc/webrtc_internals_message_handler.h +++ b/content/browser/webrtc/webrtc_internals_message_handler.h
@@ -23,7 +23,7 @@ // It delegates all its work to WebRTCInternalsProxy on the IO thread. class CONTENT_EXPORT WebRTCInternalsMessageHandler : public WebUIMessageHandler, - public NON_EXPORTED_BASE(WebRTCInternalsUIObserver) { + public WebRTCInternalsUIObserver { public: WebRTCInternalsMessageHandler(); ~WebRTCInternalsMessageHandler() override;
diff --git a/content/browser/webrtc/webrtc_internals_message_handler_unittest.cc b/content/browser/webrtc/webrtc_internals_message_handler_unittest.cc index f4e6ef3..f830440b 100644 --- a/content/browser/webrtc/webrtc_internals_message_handler_unittest.cc +++ b/content/browser/webrtc/webrtc_internals_message_handler_unittest.cc
@@ -36,7 +36,7 @@ ~WebRTCInternalsMessageHandlerForTest() override {} }; -class WebRTCInternalsForTest : public NON_EXPORTED_BASE(WebRTCInternals) { +class WebRTCInternalsForTest : public WebRTCInternals { public: WebRTCInternalsForTest() : WebRTCInternals(0, false) {} ~WebRTCInternalsForTest() override {}
diff --git a/content/browser/webrtc/webrtc_internals_unittest.cc b/content/browser/webrtc/webrtc_internals_unittest.cc index 6e4fb8a5..ef2c502 100644 --- a/content/browser/webrtc/webrtc_internals_unittest.cc +++ b/content/browser/webrtc/webrtc_internals_unittest.cc
@@ -72,7 +72,7 @@ // Derived class for testing only. Allows the tests to have their own instance // for testing and control the period for which WebRTCInternals will bulk up // updates (changes down from 500ms to 1ms). -class WebRTCInternalsForTest : public NON_EXPORTED_BASE(WebRTCInternals) { +class WebRTCInternalsForTest : public WebRTCInternals { public: WebRTCInternalsForTest() : WebRTCInternals(1, true),
diff --git a/content/browser/websockets/websocket_impl.h b/content/browser/websockets/websocket_impl.h index 7ca1180..da6225b 100644 --- a/content/browser/websockets/websocket_impl.h +++ b/content/browser/websockets/websocket_impl.h
@@ -32,8 +32,7 @@ namespace content { // Host of net::WebSocketChannel. -class CONTENT_EXPORT WebSocketImpl - : NON_EXPORTED_BASE(public blink::mojom::WebSocket) { +class CONTENT_EXPORT WebSocketImpl : public blink::mojom::WebSocket { public: class Delegate { public:
diff --git a/content/browser/websockets/websocket_manager.h b/content/browser/websockets/websocket_manager.h index e42bc17..6a0f0f86 100644 --- a/content/browser/websockets/websocket_manager.h +++ b/content/browser/websockets/websocket_manager.h
@@ -24,8 +24,8 @@ // WebSocketImpl objects for each WebSocketRequest and throttling the number of // WebSocketImpl objects in use. class CONTENT_EXPORT WebSocketManager - : NON_EXPORTED_BASE(public WebSocketImpl::Delegate), - NON_EXPORTED_BASE(public net::URLRequestContextGetterObserver) { + : public WebSocketImpl::Delegate, + public net::URLRequestContextGetterObserver { public: // Called on the UI thread: static void CreateWebSocket(
diff --git a/content/browser/webui/web_ui_data_source_impl.h b/content/browser/webui/web_ui_data_source_impl.h index 2ef7552f..93bdfe9 100644 --- a/content/browser/webui/web_ui_data_source_impl.h +++ b/content/browser/webui/web_ui_data_source_impl.h
@@ -25,9 +25,8 @@ // A data source that can help with implementing the common operations // needed by the chrome WEBUI settings/history/downloads pages. -class CONTENT_EXPORT WebUIDataSourceImpl - : public NON_EXPORTED_BASE(URLDataSourceImpl), - public NON_EXPORTED_BASE(WebUIDataSource) { +class CONTENT_EXPORT WebUIDataSourceImpl : public URLDataSourceImpl, + public WebUIDataSource { public: // WebUIDataSource implementation: void AddString(const std::string& name, const base::string16& value) override;
diff --git a/content/child/appcache/web_application_cache_host_impl.h b/content/child/appcache/web_application_cache_host_impl.h index 21d9e431..1c2fa073 100644 --- a/content/child/appcache/web_application_cache_host_impl.h +++ b/content/child/appcache/web_application_cache_host_impl.h
@@ -16,8 +16,7 @@ namespace content { -class WebApplicationCacheHostImpl - : NON_EXPORTED_BASE(public blink::WebApplicationCacheHost) { +class WebApplicationCacheHostImpl : public blink::WebApplicationCacheHost { public: // Returns the host having given id or NULL if there is no such host. static WebApplicationCacheHostImpl* FromId(int id);
diff --git a/content/child/blink_platform_impl.h b/content/child/blink_platform_impl.h index 4e2e2f6..5f27dde 100644 --- a/content/child/blink_platform_impl.h +++ b/content/child/blink_platform_impl.h
@@ -50,8 +50,7 @@ class ThreadSafeSender; class WebCryptoImpl; -class CONTENT_EXPORT BlinkPlatformImpl - : NON_EXPORTED_BASE(public blink::Platform) { +class CONTENT_EXPORT BlinkPlatformImpl : public blink::Platform { public: BlinkPlatformImpl(); explicit BlinkPlatformImpl(
diff --git a/content/child/child_thread_impl.h b/content/child/child_thread_impl.h index 9c4fc20..73d9916 100644 --- a/content/child/child_thread_impl.h +++ b/content/child/child_thread_impl.h
@@ -69,8 +69,8 @@ : public IPC::Listener, virtual public ChildThread, private base::FieldTrialList::Observer, - NON_EXPORTED_BASE(public mojom::RouteProvider), - NON_EXPORTED_BASE(public mojom::AssociatedInterfaceProvider) { + public mojom::RouteProvider, + public mojom::AssociatedInterfaceProvider { public: struct CONTENT_EXPORT Options;
diff --git a/content/child/fileapi/webfilewriter_base.h b/content/child/fileapi/webfilewriter_base.h index 92290ca..150c699a 100644 --- a/content/child/fileapi/webfilewriter_base.h +++ b/content/child/fileapi/webfilewriter_base.h
@@ -18,8 +18,7 @@ namespace content { -class CONTENT_EXPORT WebFileWriterBase - : public NON_EXPORTED_BASE(blink::WebFileWriter) { +class CONTENT_EXPORT WebFileWriterBase : public blink::WebFileWriter { public: WebFileWriterBase(const GURL& path, blink::WebFileWriterClient* client); ~WebFileWriterBase() override;
diff --git a/content/child/indexed_db/webidbcursor_impl.h b/content/child/indexed_db/webidbcursor_impl.h index 128fa8cd..c870bca7 100644 --- a/content/child/indexed_db/webidbcursor_impl.h +++ b/content/child/indexed_db/webidbcursor_impl.h
@@ -27,8 +27,7 @@ namespace content { -class CONTENT_EXPORT WebIDBCursorImpl - : NON_EXPORTED_BASE(public blink::WebIDBCursor) { +class CONTENT_EXPORT WebIDBCursorImpl : public blink::WebIDBCursor { public: WebIDBCursorImpl(indexed_db::mojom::CursorAssociatedPtrInfo cursor, int64_t transaction_id,
diff --git a/content/child/indexed_db/webidbdatabase_impl.h b/content/child/indexed_db/webidbdatabase_impl.h index 540bc84..6b34bf3 100644 --- a/content/child/indexed_db/webidbdatabase_impl.h +++ b/content/child/indexed_db/webidbdatabase_impl.h
@@ -26,8 +26,7 @@ namespace content { -class CONTENT_EXPORT WebIDBDatabaseImpl - : public NON_EXPORTED_BASE(blink::WebIDBDatabase) { +class CONTENT_EXPORT WebIDBDatabaseImpl : public blink::WebIDBDatabase { public: WebIDBDatabaseImpl(indexed_db::mojom::DatabaseAssociatedPtrInfo database, scoped_refptr<base::SingleThreadTaskRunner> io_runner);
diff --git a/content/child/memory/child_memory_coordinator_impl.h b/content/child/memory/child_memory_coordinator_impl.h index 96da729..716875f 100644 --- a/content/child/memory/child_memory_coordinator_impl.h +++ b/content/child/memory/child_memory_coordinator_impl.h
@@ -28,7 +28,7 @@ // to its clients. class CONTENT_EXPORT ChildMemoryCoordinatorImpl : base::MemoryCoordinator, - NON_EXPORTED_BASE(public mojom::ChildMemoryCoordinator) { + public mojom::ChildMemoryCoordinator { public: // Returns the instance of ChildMemoryCoordinatorImpl. Could be nullptr. static ChildMemoryCoordinatorImpl* GetInstance();
diff --git a/content/child/request_extra_data.h b/content/child/request_extra_data.h index 44e18f58..c72c3e0 100644 --- a/content/child/request_extra_data.h +++ b/content/child/request_extra_data.h
@@ -26,8 +26,7 @@ // Can be used by callers to store extra data on every ResourceRequest // which will be incorporated into the ResourceHostMsg_RequestResource message // sent by ResourceDispatcher. -class CONTENT_EXPORT RequestExtraData - : public NON_EXPORTED_BASE(blink::WebURLRequest::ExtraData) { +class CONTENT_EXPORT RequestExtraData : public blink::WebURLRequest::ExtraData { public: RequestExtraData(); ~RequestExtraData() override;
diff --git a/content/child/service_worker/service_worker_dispatcher.cc b/content/child/service_worker/service_worker_dispatcher.cc index 6ec92852..87f8fd09 100644 --- a/content/child/service_worker/service_worker_dispatcher.cc +++ b/content/child/service_worker/service_worker_dispatcher.cc
@@ -807,9 +807,8 @@ ProviderContextMap::iterator provider = provider_contexts_.find(params.provider_id); if (provider != provider_contexts_.end()) { - provider->second->OnSetControllerServiceWorker( - std::move(handle_ref), params.used_features, - std::move(event_dispatcher_ptr_info)); + provider->second->SetController(std::move(handle_ref), params.used_features, + std::move(event_dispatcher_ptr_info)); } ProviderClientMap::iterator found =
diff --git a/content/child/service_worker/service_worker_message_filter.h b/content/child/service_worker/service_worker_message_filter.h index 06cb680..dc55284a 100644 --- a/content/child/service_worker/service_worker_message_filter.h +++ b/content/child/service_worker/service_worker_message_filter.h
@@ -21,7 +21,7 @@ struct ServiceWorkerVersionAttributes; class CONTENT_EXPORT ServiceWorkerMessageFilter - : public NON_EXPORTED_BASE(WorkerThreadMessageFilter) { + : public WorkerThreadMessageFilter { public: explicit ServiceWorkerMessageFilter(ThreadSafeSender* thread_safe_sender);
diff --git a/content/child/service_worker/service_worker_provider_context.cc b/content/child/service_worker/service_worker_provider_context.cc index 2b18d46a..7c9e08e 100644 --- a/content/child/service_worker/service_worker_provider_context.cc +++ b/content/child/service_worker/service_worker_provider_context.cc
@@ -17,108 +17,28 @@ namespace content { -class ServiceWorkerProviderContext::Delegate { - public: - virtual ~Delegate() {} - virtual void SetRegistration( - std::unique_ptr<ServiceWorkerRegistrationHandleReference> registration, - std::unique_ptr<ServiceWorkerHandleReference> installing, - std::unique_ptr<ServiceWorkerHandleReference> waiting, - std::unique_ptr<ServiceWorkerHandleReference> active) = 0; - virtual void GetRegistration(ServiceWorkerRegistrationObjectInfo* info, - ServiceWorkerVersionAttributes* attrs) = 0; - virtual void SetController( - std::unique_ptr<ServiceWorkerHandleReference> controller) = 0; - virtual ServiceWorkerHandleReference* controller() = 0; +// Holds state for service worker clients. +struct ServiceWorkerProviderContext::ControlleeState { + ControlleeState() = default; + ~ControlleeState() = default; + + std::unique_ptr<ServiceWorkerHandleReference> controller; + + // Used to dispatch events to the controller. + mojom::ServiceWorkerEventDispatcherPtr event_dispatcher; + + // Tracks feature usage for UseCounter. + std::set<uint32_t> used_features; }; -// Delegate class for ServiceWorker client (Document, SharedWorker, etc) to -// keep the controller until ServiceWorkerContainer is initialized. -class ServiceWorkerProviderContext::ControlleeDelegate - : public ServiceWorkerProviderContext::Delegate { - public: - ControlleeDelegate() {} - ~ControlleeDelegate() override {} - - void SetRegistration( - std::unique_ptr<ServiceWorkerRegistrationHandleReference> registration, - std::unique_ptr<ServiceWorkerHandleReference> /* installing */, - std::unique_ptr<ServiceWorkerHandleReference> /* waiting */, - std::unique_ptr<ServiceWorkerHandleReference> /* active */) override { - NOTREACHED(); - } - - void SetController( - std::unique_ptr<ServiceWorkerHandleReference> controller) override { - DCHECK(!controller || - controller->handle_id() != kInvalidServiceWorkerHandleId); - controller_ = std::move(controller); - } - - void GetRegistration(ServiceWorkerRegistrationObjectInfo* /* info */, - ServiceWorkerVersionAttributes* /* attrs */) override { - NOTREACHED(); - } - - ServiceWorkerHandleReference* controller() override { - return controller_.get(); - } - - private: - std::unique_ptr<ServiceWorkerHandleReference> controller_; - - DISALLOW_COPY_AND_ASSIGN(ControlleeDelegate); -}; - -// Delegate class for ServiceWorkerGlobalScope to keep the associated -// registration and its versions until the execution context is initialized. -class ServiceWorkerProviderContext::ControllerDelegate - : public ServiceWorkerProviderContext::Delegate { - public: - ControllerDelegate() {} - ~ControllerDelegate() override {} - - void SetRegistration( - std::unique_ptr<ServiceWorkerRegistrationHandleReference> registration, - std::unique_ptr<ServiceWorkerHandleReference> installing, - std::unique_ptr<ServiceWorkerHandleReference> waiting, - std::unique_ptr<ServiceWorkerHandleReference> active) override { - DCHECK(!registration_); - registration_ = std::move(registration); - installing_ = std::move(installing); - waiting_ = std::move(waiting); - active_ = std::move(active); - } - - void SetController( - std::unique_ptr<ServiceWorkerHandleReference> /* controller */) override { - NOTREACHED(); - } - - void GetRegistration(ServiceWorkerRegistrationObjectInfo* info, - ServiceWorkerVersionAttributes* attrs) override { - DCHECK(registration_); - *info = registration_->info(); - if (installing_) - attrs->installing = installing_->info(); - if (waiting_) - attrs->waiting = waiting_->info(); - if (active_) - attrs->active = active_->info(); - } - - ServiceWorkerHandleReference* controller() override { - NOTREACHED(); - return nullptr; - } - - private: - std::unique_ptr<ServiceWorkerRegistrationHandleReference> registration_; - std::unique_ptr<ServiceWorkerHandleReference> installing_; - std::unique_ptr<ServiceWorkerHandleReference> waiting_; - std::unique_ptr<ServiceWorkerHandleReference> active_; - - DISALLOW_COPY_AND_ASSIGN(ControllerDelegate); +// Holds state for service worker execution contexts. +struct ServiceWorkerProviderContext::ControllerState { + ControllerState() = default; + ~ControllerState() = default; + std::unique_ptr<ServiceWorkerRegistrationHandleReference> registration; + std::unique_ptr<ServiceWorkerHandleReference> installing; + std::unique_ptr<ServiceWorkerHandleReference> waiting; + std::unique_ptr<ServiceWorkerHandleReference> active; }; ServiceWorkerProviderContext::ServiceWorkerProviderContext( @@ -130,9 +50,9 @@ main_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()), binding_(this, std::move(request)) { if (provider_type == SERVICE_WORKER_PROVIDER_FOR_CONTROLLER) - delegate_.reset(new ControllerDelegate); + controller_state_ = base::MakeUnique<ControllerState>(); else - delegate_.reset(new ControlleeDelegate); + controllee_state_ = base::MakeUnique<ControlleeState>(); dispatcher->AddProviderContext(this); } @@ -151,38 +71,70 @@ std::unique_ptr<ServiceWorkerHandleReference> waiting, std::unique_ptr<ServiceWorkerHandleReference> active) { DCHECK(main_thread_task_runner_->RunsTasksInCurrentSequence()); - delegate_->SetRegistration(std::move(registration), std::move(installing), - std::move(waiting), std::move(active)); -} - -void ServiceWorkerProviderContext::OnSetControllerServiceWorker( - std::unique_ptr<ServiceWorkerHandleReference> controller, - const std::set<uint32_t>& used_features, - mojom::ServiceWorkerEventDispatcherPtrInfo event_dispatcher_ptr_info) { - DCHECK(main_thread_task_runner_->RunsTasksInCurrentSequence()); - delegate_->SetController(std::move(controller)); - used_features_ = used_features; - if (event_dispatcher_ptr_info.is_valid()) - event_dispatcher_.Bind(std::move(event_dispatcher_ptr_info)); + ControllerState* state = controller_state_.get(); + DCHECK(state); + DCHECK(!state->registration); + DCHECK(!state->installing && !state->waiting && !state->active); + state->registration = std::move(registration); + state->installing = std::move(installing); + state->waiting = std::move(waiting); + state->active = std::move(active); } void ServiceWorkerProviderContext::GetRegistration( ServiceWorkerRegistrationObjectInfo* info, ServiceWorkerVersionAttributes* attrs) { DCHECK(!main_thread_task_runner_->RunsTasksInCurrentSequence()); - delegate_->GetRegistration(info, attrs); + ControllerState* state = controller_state_.get(); + DCHECK(state); + DCHECK(state->registration); + *info = state->registration->info(); + if (state->installing) + attrs->installing = state->installing->info(); + if (state->waiting) + attrs->waiting = state->waiting->info(); + if (state->active) + attrs->active = state->active->info(); +} + +void ServiceWorkerProviderContext::SetController( + std::unique_ptr<ServiceWorkerHandleReference> controller, + const std::set<uint32_t>& used_features, + mojom::ServiceWorkerEventDispatcherPtrInfo event_dispatcher_ptr_info) { + DCHECK(main_thread_task_runner_->RunsTasksInCurrentSequence()); + ControlleeState* state = controllee_state_.get(); + DCHECK(state); + DCHECK(!state->controller || + state->controller->handle_id() != kInvalidServiceWorkerHandleId); + state->controller = std::move(controller); + state->used_features = used_features; + if (event_dispatcher_ptr_info.is_valid()) + state->event_dispatcher.Bind(std::move(event_dispatcher_ptr_info)); } ServiceWorkerHandleReference* ServiceWorkerProviderContext::controller() { DCHECK(main_thread_task_runner_->RunsTasksInCurrentSequence()); - return delegate_->controller(); + DCHECK(controllee_state_); + return controllee_state_->controller.get(); +} + +mojom::ServiceWorkerEventDispatcher* +ServiceWorkerProviderContext::event_dispatcher() { + DCHECK(controllee_state_); + return controllee_state_->event_dispatcher.get(); } void ServiceWorkerProviderContext::CountFeature(uint32_t feature) { // ServiceWorkerProviderContext keeps track of features in order to propagate // it to WebServiceWorkerProviderClient, which actually records the // UseCounter. - used_features_.insert(feature); + DCHECK(controllee_state_); + controllee_state_->used_features.insert(feature); +} + +const std::set<uint32_t>& ServiceWorkerProviderContext::used_features() const { + DCHECK(controllee_state_); + return controllee_state_->used_features; } void ServiceWorkerProviderContext::DestructOnMainThread() const {
diff --git a/content/child/service_worker/service_worker_provider_context.h b/content/child/service_worker/service_worker_provider_context.h index fbb37fd..d64a5419 100644 --- a/content/child/service_worker/service_worker_provider_context.h +++ b/content/child/service_worker/service_worker_provider_context.h
@@ -29,39 +29,32 @@ class ServiceWorkerRegistrationHandleReference; struct ServiceWorkerProviderContextDeleter; -// ServiceWorkerProviderContext has different roles depending on if it's for a -// "controllee" (a Document or Worker execution context), or a "controller" (a -// service worker execution context). The roles are described below. +// ServiceWorkerProviderContext stores common state for service worker +// "providers" (currently WebServiceWorkerProviderImpl and +// ServiceWorkerNetworkProvider). Providers for the same underlying entity hold +// strong references to a shared instance of this class. // -// WebServiceWorkerProviderImpl has a ServiceWorkerProviderContext. Because -// WebServiceWorkerProviderImpl is used for both controllees and controllers, -// this class allows WebServiceWorkerProviderImpl to implement different -// behaviors for controllees vs controllers. -// -// Created and destructed on the main thread. Unless otherwise noted, all -// methods are called on the main thread. The lifetime of this class is equals -// to the corresponding ServiceWorkerNetworkProvider. -// -// The role of this class varies for controllees and controllers: -// - For controllees, this is used for keeping the controller alive to create -// controllee's ServiceWorkerContainer#controller. -// The reference to the controller is kept until -// OnSetControllerServiceWorker() is called with an invalid worker info. +// The ServiceWorkerProviderContext has different roles depending on if it's for +// a "controllee" (a Document or Worker execution context), or a "controller" (a +// service worker execution context). +// - For controllees, it's used for keeping the controller alive to create +// controllee's ServiceWorkerContainer#controller. The reference to the +// controller is kept until SetController() is called with an +// invalid worker info. // - For controllers, this is used for keeping the associated registration and // its versions alive to create the controller's // ServiceWorkerGlobalScope#registration. // -// These operations are actually done in delegate classes owned by this class: -// ControlleeDelegate and ControllerDelegate. +// Created and destructed on the main thread. Unless otherwise noted, all +// methods are called on the main thread. class CONTENT_EXPORT ServiceWorkerProviderContext : public base::RefCountedThreadSafe<ServiceWorkerProviderContext, ServiceWorkerProviderContextDeleter>, - NON_EXPORTED_BASE(public mojom::ServiceWorkerProvider) { + public mojom::ServiceWorkerProvider { public: - // |provider_id| specifies which host will receive the message from this - // provider. |provider_type| changes the behavior of this provider - // context. |request| is an endpoint which is connected to - // content::ServiceWorkerProviderHost which notifies changes of the + // |provider_id| is used to identify this provider in IPC messages to the + // browser process. |request| is an endpoint which is connected to + // the content::ServiceWorkerProviderHost that notifies of changes to the // registration's and workers' status. |request| is bound with |binding_|. // The new instance is registered to |dispatcher|, which is not owned. ServiceWorkerProviderContext( @@ -70,64 +63,62 @@ mojom::ServiceWorkerProviderAssociatedRequest request, ServiceWorkerDispatcher* dispatcher); + int provider_id() const { return provider_id_; } + // For service worker execution contexts. Sets the registration for - // ServiceWorkerGlobalScope#registration. Called on the main thread. + // ServiceWorkerGlobalScope#registration. Unlike GetRegistration(), + // called on the main thread. SetRegistration() is called during + // the setup for service worker startup, so it is guaranteed to be called + // before GetRegistration(). void SetRegistration( std::unique_ptr<ServiceWorkerRegistrationHandleReference> registration, std::unique_ptr<ServiceWorkerHandleReference> installing, std::unique_ptr<ServiceWorkerHandleReference> waiting, std::unique_ptr<ServiceWorkerHandleReference> active); - // For service worker clients. Sets the controller for - // ServiceWorkerContainer#controller. Called on the main thread. - void OnSetControllerServiceWorker( - std::unique_ptr<ServiceWorkerHandleReference> controller, - const std::set<uint32_t>& used_features, - mojom::ServiceWorkerEventDispatcherPtrInfo event_dispatcher_ptr_info); - - // Called on the worker thread. Used for initializing - // ServiceWorkerGlobalScope#registration. + // For service worker execution contexts. Used for initializing + // ServiceWorkerGlobalScope#registration. Called on the worker thread. void GetRegistration(ServiceWorkerRegistrationObjectInfo* info, ServiceWorkerVersionAttributes* attrs); - int provider_id() const { return provider_id_; } - - mojom::ServiceWorkerEventDispatcher* event_dispatcher() { - return event_dispatcher_.get(); - } - + // For service worker clients. The controller for + // ServiceWorkerContainer#controller. + void SetController( + std::unique_ptr<ServiceWorkerHandleReference> controller, + const std::set<uint32_t>& used_features, + mojom::ServiceWorkerEventDispatcherPtrInfo event_dispatcher_ptr_info); ServiceWorkerHandleReference* controller(); + + // For service worker clients. Gets the ServiceWorkerEventDispatcher + // for dispatching events to the controller ServiceWorker. + mojom::ServiceWorkerEventDispatcher* event_dispatcher(); + + // For service worker clients. Keeps track of feature usage for UseCounter. void CountFeature(uint32_t feature); - const std::set<uint32_t>& used_features() const { return used_features_; } + const std::set<uint32_t>& used_features() const; private: friend class base::DeleteHelper<ServiceWorkerProviderContext>; friend class base::RefCountedThreadSafe<ServiceWorkerProviderContext, ServiceWorkerProviderContextDeleter>; friend struct ServiceWorkerProviderContextDeleter; - - class Delegate; - class ControlleeDelegate; - class ControllerDelegate; + struct ControlleeState; + struct ControllerState; ~ServiceWorkerProviderContext() override; void DestructOnMainThread() const; const int provider_id_; scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_; + // Mojo binding for the |request| passed to the constructor. This keeps the // connection to the content::ServiceWorkerProviderHost in the browser process // alive. mojo::AssociatedBinding<mojom::ServiceWorkerProvider> binding_; - // Only used for controllee contexts. Used to dispatch events to the - // controller ServiceWorker. - mojom::ServiceWorkerEventDispatcherPtr event_dispatcher_; - - std::unique_ptr<Delegate> delegate_; - - // Only used for controllee contexts. - std::set<uint32_t> used_features_; + // Either |controllee_state_| or |controller_state_| is non-null. + std::unique_ptr<ControlleeState> controllee_state_; + std::unique_ptr<ControllerState> controller_state_; DISALLOW_COPY_AND_ASSIGN(ServiceWorkerProviderContext); };
diff --git a/content/child/service_worker/web_service_worker_impl.h b/content/child/service_worker/web_service_worker_impl.h index ba082662..d487ded2 100644 --- a/content/child/service_worker/web_service_worker_impl.h +++ b/content/child/service_worker/web_service_worker_impl.h
@@ -34,7 +34,7 @@ // corresponding ServiceWorkerHandle doesn't go away in the browser process // while the ServiceWorker object is alive. class CONTENT_EXPORT WebServiceWorkerImpl - : NON_EXPORTED_BASE(public blink::WebServiceWorker), + : public blink::WebServiceWorker, public base::RefCounted<WebServiceWorkerImpl> { public: WebServiceWorkerImpl(std::unique_ptr<ServiceWorkerHandleReference> handle_ref,
diff --git a/content/child/service_worker/web_service_worker_provider_impl.h b/content/child/service_worker/web_service_worker_provider_impl.h index 7efa741..6c2ddd8 100644 --- a/content/child/service_worker/web_service_worker_provider_impl.h +++ b/content/child/service_worker/web_service_worker_provider_impl.h
@@ -25,8 +25,7 @@ // This class corresponds to one ServiceWorkerContainer interface in // JS context (i.e. navigator.serviceWorker). -class WebServiceWorkerProviderImpl - : NON_EXPORTED_BASE(public blink::WebServiceWorkerProvider) { +class WebServiceWorkerProviderImpl : public blink::WebServiceWorkerProvider { public: WebServiceWorkerProviderImpl(ThreadSafeSender* thread_safe_sender, ServiceWorkerProviderContext* context);
diff --git a/content/child/service_worker/web_service_worker_registration_impl.h b/content/child/service_worker/web_service_worker_registration_impl.h index c2772a0b..1248aff77 100644 --- a/content/child/service_worker/web_service_worker_registration_impl.h +++ b/content/child/service_worker/web_service_worker_registration_impl.h
@@ -33,7 +33,7 @@ // corresponding ServiceWorkerRegistrationHandle doesn't go away in the browser // process while the ServiceWorkerRegistration object is alive. class CONTENT_EXPORT WebServiceWorkerRegistrationImpl - : NON_EXPORTED_BASE(public blink::WebServiceWorkerRegistration), + : public blink::WebServiceWorkerRegistration, public base::RefCounted<WebServiceWorkerRegistrationImpl> { public: explicit WebServiceWorkerRegistrationImpl(
diff --git a/content/child/shared_memory_data_consumer_handle.h b/content/child/shared_memory_data_consumer_handle.h index b2213638..b1b1af7 100644 --- a/content/child/shared_memory_data_consumer_handle.h +++ b/content/child/shared_memory_data_consumer_handle.h
@@ -20,7 +20,7 @@ // This class is a WebDataConsumerHandle that accepts RequestPeer::ReceivedData. class CONTENT_EXPORT SharedMemoryDataConsumerHandle final - : public NON_EXPORTED_BASE(blink::WebDataConsumerHandle) { + : public blink::WebDataConsumerHandle { private: class Context;
diff --git a/content/child/web_data_consumer_handle_impl.h b/content/child/web_data_consumer_handle_impl.h index af0187d53a..e40ff796 100644 --- a/content/child/web_data_consumer_handle_impl.h +++ b/content/child/web_data_consumer_handle_impl.h
@@ -17,12 +17,12 @@ namespace content { class CONTENT_EXPORT WebDataConsumerHandleImpl final - : public NON_EXPORTED_BASE(blink::WebDataConsumerHandle) { + : public blink::WebDataConsumerHandle { typedef mojo::ScopedDataPipeConsumerHandle Handle; class Context; public: - class CONTENT_EXPORT ReaderImpl final : public NON_EXPORTED_BASE(Reader) { + class CONTENT_EXPORT ReaderImpl final : public Reader { public: ReaderImpl(scoped_refptr<Context> context, Client* client); ~ReaderImpl() override;
diff --git a/content/child/web_url_loader_impl.h b/content/child/web_url_loader_impl.h index d82d3a1..f127b7b 100644 --- a/content/child/web_url_loader_impl.h +++ b/content/child/web_url_loader_impl.h
@@ -49,8 +49,7 @@ base::OnceCallback<void(const GURL&)> on_delete; }; -class CONTENT_EXPORT WebURLLoaderImpl - : public NON_EXPORTED_BASE(blink::WebURLLoader) { +class CONTENT_EXPORT WebURLLoaderImpl : public blink::WebURLLoader { public: WebURLLoaderImpl(ResourceDispatcher* resource_dispatcher, scoped_refptr<base::SingleThreadTaskRunner> task_runner,
diff --git a/content/child/webfileutilities_impl.h b/content/child/webfileutilities_impl.h index 5c6ed26..ef9b6df 100644 --- a/content/child/webfileutilities_impl.h +++ b/content/child/webfileutilities_impl.h
@@ -11,8 +11,7 @@ namespace content { -class CONTENT_EXPORT WebFileUtilitiesImpl - : NON_EXPORTED_BASE(public blink::WebFileUtilities) { +class CONTENT_EXPORT WebFileUtilitiesImpl : public blink::WebFileUtilities { public: WebFileUtilitiesImpl(); virtual ~WebFileUtilitiesImpl();
diff --git a/content/child/weburlresponse_extradata_impl.h b/content/child/weburlresponse_extradata_impl.h index 58b75d1..79746ba5 100644 --- a/content/child/weburlresponse_extradata_impl.h +++ b/content/child/weburlresponse_extradata_impl.h
@@ -17,8 +17,8 @@ namespace content { -class CONTENT_EXPORT WebURLResponseExtraDataImpl : - public NON_EXPORTED_BASE(blink::WebURLResponse::ExtraData) { +class CONTENT_EXPORT WebURLResponseExtraDataImpl + : public blink::WebURLResponse::ExtraData { public: WebURLResponseExtraDataImpl(); ~WebURLResponseExtraDataImpl() override;
diff --git a/content/common/input/synthetic_web_input_event_builders.h b/content/common/input/synthetic_web_input_event_builders.h index 782260c..9985c43 100644 --- a/content/common/input/synthetic_web_input_event_builders.h +++ b/content/common/input/synthetic_web_input_event_builders.h
@@ -81,8 +81,7 @@ blink::WebGestureDevice source_device); }; -class CONTENT_EXPORT SyntheticWebTouchEvent - : public NON_EXPORTED_BASE(blink::WebTouchEvent) { +class CONTENT_EXPORT SyntheticWebTouchEvent : public blink::WebTouchEvent { public: SyntheticWebTouchEvent();
diff --git a/content/common/sandbox_linux/sandbox_linux.cc b/content/common/sandbox_linux/sandbox_linux.cc index 530fd5a..e10be7d 100644 --- a/content/common/sandbox_linux/sandbox_linux.cc +++ b/content/common/sandbox_linux/sandbox_linux.cc
@@ -37,6 +37,7 @@ #include "content/public/common/content_features.h" #include "content/public/common/content_switches.h" #include "content/public/common/sandbox_linux.h" +#include "content/public/common/sandbox_type.h" #include "sandbox/linux/services/credentials.h" #include "sandbox/linux/services/namespace_sandbox.h" #include "sandbox/linux/services/proc_util.h" @@ -383,9 +384,8 @@ (void) process_type; #if !defined(ANY_OF_AMTLU_SANITIZER) base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); - if (command_line->HasSwitch(switches::kNoSandbox)) { + if (SandboxTypeFromCommandLine(*command_line) == SANDBOX_TYPE_NO_SANDBOX) return false; - } // Limit the address space to 4GB. // This is in the hope of making some kernel exploits more complex and less
diff --git a/content/public/android/BUILD.gn b/content/public/android/BUILD.gn index 23452f5..3a0c40a 100644 --- a/content/public/android/BUILD.gn +++ b/content/public/android/BUILD.gn
@@ -299,6 +299,7 @@ sources = [ "//content/browser/android/content_view_core.cc", "//content/browser/android/gesture_event_type.h", + "//content/browser/child_process_importance.h", "//content/public/browser/android/motion_event_action.h", "//content/public/browser/download_item.h", "//content/public/browser/invalidate_type.h",
diff --git a/content/public/android/java/src/org/chromium/content/browser/BindingManagerImpl.java b/content/public/android/java/src/org/chromium/content/browser/BindingManagerImpl.java index a0564bc..a2ac85b7 100644 --- a/content/public/android/java/src/org/chromium/content/browser/BindingManagerImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/BindingManagerImpl.java
@@ -100,12 +100,9 @@ } void addConnection(ManagedConnection managedConnection) { + assert !mConnections.contains(managedConnection); managedConnection.addModerateBinding(); - if (managedConnection.mConnection.isModerateBindingBound()) { - addConnectionImpl(managedConnection); - } else { - removeConnectionImpl(managedConnection); - } + addConnectionImpl(managedConnection); } void removeConnection(ManagedConnection managedConnection) { @@ -193,10 +190,6 @@ // This currently maps exactly to the initial binding. private boolean mBoostPriorityForPendingViews = true; - // True iff there is a strong binding kept on the service because it was bound for the - // application background period. - private boolean mBoundForBackgroundPeriod; - /** Adds a strong service binding. */ private void addStrongBinding() { mConnection.addStrongBinding(); @@ -205,8 +198,7 @@ /** Removes a strong service binding. */ private void removeStrongBinding(final boolean keepAsModerate) { - // We have to fail gracefully if the strong binding is not present, as on low-end the - // binding could have been removed by dropOomBindings() when a new service was started. + // We have to fail gracefully if the strong binding is not present. if (!mConnection.isStrongBindingBound()) return; // This runnable performs the actual unbinding. It will be executed synchronously when @@ -252,15 +244,6 @@ mConnection.addModerateBinding(); } - /** - * Drops the service bindings. This is used on low-end to drop bindings of the current - * service when a new one is used in foreground. - */ - private void dropBindings() { - assert mIsLowMemoryDevice; - mConnection.dropOomBindings(); - } - ManagedConnection(ChildProcessConnection connection) { mConnection = connection; } @@ -288,35 +271,11 @@ mInForeground = foreground; mBoostPriorityForPendingViews = boostForPendingViews; } - - /** - * Sets or removes additional binding when the service is main service during the embedder - * background period. - */ - void setBoundForBackgroundPeriod(boolean boundForBackgroundPeriod) { - if (boundForBackgroundPeriod == mBoundForBackgroundPeriod) return; - - if (boundForBackgroundPeriod) { - addStrongBinding(); - } else { - removeStrongBinding(false); - } - mBoundForBackgroundPeriod = boundForBackgroundPeriod; - } } private final SparseArray<ManagedConnection> mManagedConnections = new SparseArray<ManagedConnection>(); - // The connection that was most recently set as foreground (using setInForeground()). This is - // used to add additional binding on it when the embedder goes to background. On low-end, this - // is also used to drop process bindings when a new one is created, making sure that only one - // renderer process at a time is protected from oom killing. - private ManagedConnection mLastConnectionInForeground; - - // The connection bound with additional binding in onSentToBackground(). - private ManagedConnection mConnectionBoundForBackgroundPeriod; - // Whether this instance is used on testing. private final boolean mOnTesting; @@ -362,35 +321,18 @@ return; } - if (foreground && mIsLowMemoryDevice && mLastConnectionInForeground != null - && mLastConnectionInForeground != managedConnection) { - mLastConnectionInForeground.dropBindings(); - } - managedConnection.setPriority(foreground, boostForPendingViews); - if (foreground) mLastConnectionInForeground = managedConnection; } @Override public void onSentToBackground() { assert LauncherThread.runningOnLauncherThread(); - assert mConnectionBoundForBackgroundPeriod == null; - // mLastConnectionInForeground can be null at this point as the embedding application could - // be used in foreground without spawning any renderers. - if (mLastConnectionInForeground != null) { - mLastConnectionInForeground.setBoundForBackgroundPeriod(true); - mConnectionBoundForBackgroundPeriod = mLastConnectionInForeground; - } if (mModerateBindingPool != null) mModerateBindingPool.onSentToBackground(mOnTesting); } @Override public void onBroughtToForeground() { assert LauncherThread.runningOnLauncherThread(); - if (mConnectionBoundForBackgroundPeriod != null) { - mConnectionBoundForBackgroundPeriod.setBoundForBackgroundPeriod(false); - mConnectionBoundForBackgroundPeriod = null; - } if (mModerateBindingPool != null) mModerateBindingPool.onBroughtToForeground(); } @@ -401,12 +343,6 @@ if (managedConnection == null) return; mManagedConnections.remove(pid); - if (mLastConnectionInForeground == managedConnection) { - mLastConnectionInForeground = null; - } - if (mConnectionBoundForBackgroundPeriod == managedConnection) { - mConnectionBoundForBackgroundPeriod = null; - } if (mModerateBindingPool != null) mModerateBindingPool.removeConnection(managedConnection); }
diff --git a/content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncherHelper.java b/content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncherHelper.java index 8e8bf78..4383850 100644 --- a/content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncherHelper.java +++ b/content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncherHelper.java
@@ -28,6 +28,7 @@ import org.chromium.content.app.ChromiumLinkerParams; import org.chromium.content.app.SandboxedProcessService; import org.chromium.content.common.ContentSwitches; +import org.chromium.content_public.browser.ChildProcessImportance; import java.io.IOException; import java.util.HashMap; @@ -150,6 +151,8 @@ // Note native pointer is only guaranteed live until nativeOnChildProcessStarted. private long mNativeChildProcessLauncherHelper; + private @ChildProcessImportance int mImportance = ChildProcessImportance.NORMAL; + @CalledByNative private static FileDescriptorInfo makeFdInfo( int id, int fd, boolean autoClose, long offset, long size) { @@ -458,10 +461,48 @@ } @CalledByNative - private void setInForeground(int pid, boolean foreground, boolean boostForPendingViews) { + private void setPriority(int pid, boolean foreground, boolean boostForPendingViews, + @ChildProcessImportance int importance) { assert LauncherThread.runningOnLauncherThread(); assert mLauncher.getPid() == pid; getBindingManager().setPriority(pid, foreground, boostForPendingViews); + + if (mImportance == importance) return; + ChildProcessConnection connection = mLauncher.getConnection(); + // Add first and remove second. + switch (importance) { + case ChildProcessImportance.NORMAL: + // Nothing to add. + break; + case ChildProcessImportance.MODERATE: + connection.addModerateBinding(); + break; + case ChildProcessImportance.IMPORTANT: + connection.addStrongBinding(); + break; + case ChildProcessImportance.COUNT: + assert false; + break; + default: + assert false; + } + switch (mImportance) { + case ChildProcessImportance.NORMAL: + // Nothing to remove. + break; + case ChildProcessImportance.MODERATE: + connection.removeModerateBinding(); + break; + case ChildProcessImportance.IMPORTANT: + connection.removeStrongBinding(); + break; + case ChildProcessImportance.COUNT: + assert false; + break; + default: + assert false; + } + mImportance = importance; } @CalledByNative @@ -552,6 +593,12 @@ } // Testing only related methods. + + @VisibleForTesting + public static Map<Integer, ChildProcessLauncherHelper> getAllProcessesForTesting() { + return sLauncherByPid; + } + @VisibleForTesting public static ChildProcessLauncherHelper createAndStartForTesting( ChildProcessCreationParams creationParams, String[] commandLine,
diff --git a/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsImpl.java b/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsImpl.java index 5a7ca4c..a07ed5a6 100644 --- a/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsImpl.java
@@ -25,6 +25,7 @@ import org.chromium.content.browser.framehost.RenderFrameHostImpl; import org.chromium.content_public.browser.AccessibilitySnapshotCallback; import org.chromium.content_public.browser.AccessibilitySnapshotNode; +import org.chromium.content_public.browser.ChildProcessImportance; import org.chromium.content_public.browser.ContentBitmapCallback; import org.chromium.content_public.browser.ImageDownloadCallback; import org.chromium.content_public.browser.JavaScriptCallback; @@ -301,6 +302,11 @@ } @Override + public void setImportance(@ChildProcessImportance int importance) { + nativeSetImportance(mNativeWebContentsAndroid, importance); + } + + @Override public void suspendAllMediaPlayers() { nativeSuspendAllMediaPlayers(mNativeWebContentsAndroid); } @@ -643,6 +649,7 @@ private native void nativeCollapseSelection(long nativeWebContentsAndroid); private native void nativeOnHide(long nativeWebContentsAndroid); private native void nativeOnShow(long nativeWebContentsAndroid); + private native void nativeSetImportance(long nativeWebContentsAndroid, int importance); private native void nativeSuspendAllMediaPlayers(long nativeWebContentsAndroid); private native void nativeSetAudioMuted(long nativeWebContentsAndroid, boolean mute); private native int nativeGetBackgroundColor(long nativeWebContentsAndroid);
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/WebContents.java b/content/public/android/java/src/org/chromium/content_public/browser/WebContents.java index f172b22..d6c24ff 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/WebContents.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/WebContents.java
@@ -144,6 +144,12 @@ */ void onShow(); + /** + * ChildProcessImportance on Android allows controls of the renderer process bindings + * independent of visibility. + */ + void setImportance(@ChildProcessImportance int importance); + // TODO (amaralp): Only used in content. Should be moved out of public interface. /** * Removes handles used in text selection.
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/ChildProcessLauncherIntegrationTest.java b/content/public/android/javatests/src/org/chromium/content/browser/ChildProcessLauncherIntegrationTest.java index 639af9f..46c46d0d 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/ChildProcessLauncherIntegrationTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/ChildProcessLauncherIntegrationTest.java
@@ -84,14 +84,6 @@ } @Override - public void dropOomBindings() { - super.dropOomBindings(); - if (mRemovedBothInitialAndStrongBinding == null) { - mRemovedBothInitialAndStrongBinding = new RuntimeException("dropOomBindings"); - } - } - - @Override public void removeStrongBinding() { super.removeStrongBinding(); if (mRemovedBothInitialAndStrongBinding == null && !isInitialBindingBound()) {
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/webcontents/WebContentsTest.java b/content/public/android/javatests/src/org/chromium/content/browser/webcontents/WebContentsTest.java index 6b01ef2..df6738e0 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/webcontents/WebContentsTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/webcontents/WebContentsTest.java
@@ -16,12 +16,16 @@ import org.junit.runner.RunWith; import org.chromium.base.ThreadUtils; +import org.chromium.base.process_launcher.ChildProcessConnection; import org.chromium.base.test.BaseJUnit4ClassRunner; import org.chromium.base.test.util.UrlUtils; +import org.chromium.content.browser.ChildProcessLauncherHelper; +import org.chromium.content_public.browser.ChildProcessImportance; import org.chromium.content_public.browser.RenderFrameHost; import org.chromium.content_public.browser.WebContents; import org.chromium.content_public.browser.WebContentsStatics; import org.chromium.content_shell.Shell; +import org.chromium.content_shell_apk.ChildProcessLauncherTestUtils; import org.chromium.content_shell_apk.ContentShellActivity; import org.chromium.content_shell_apk.ContentShellActivityTestRule; @@ -364,6 +368,53 @@ }); } + @Test + @SmallTest + public void testChildProcessImportance() { + final ContentShellActivity activity = + mActivityTestRule.launchContentShellWithUrl(TEST_URL_1); + mActivityTestRule.waitForActiveShellToBeDoneLoading(); + final WebContents webContents = activity.getActiveWebContents(); + + Callable<ChildProcessConnection> getConnectionCallable = + new Callable<ChildProcessConnection>() { + @Override + public ChildProcessConnection call() { + for (ChildProcessLauncherHelper process : + ChildProcessLauncherHelper.getAllProcessesForTesting().values()) { + ChildProcessConnection connection = process.getChildProcessConnection(); + if (connection.getServiceName().getClassName().indexOf("Sandbox") + != -1) { + return connection; + } + } + Assert.assertTrue(false); + return null; + } + }; + final ChildProcessConnection connection = + ChildProcessLauncherTestUtils.runOnLauncherAndGetResult(getConnectionCallable); + ChildProcessLauncherTestUtils.runOnLauncherThreadBlocking(new Runnable() { + @Override + public void run() { + Assert.assertFalse(connection.isModerateBindingBound()); + } + }); + + ThreadUtils.runOnUiThreadBlocking(new Runnable() { + @Override + public void run() { + webContents.setImportance(ChildProcessImportance.MODERATE); + } + }); + ChildProcessLauncherTestUtils.runOnLauncherThreadBlocking(new Runnable() { + @Override + public void run() { + Assert.assertTrue(connection.isModerateBindingBound()); + } + }); + } + private boolean isWebContentsDestroyed(final WebContents webContents) { return ThreadUtils.runOnUiThreadBlockingNoException(new Callable<Boolean>() { @Override
diff --git a/content/public/android/junit/src/org/chromium/content/browser/BindingManagerImplTest.java b/content/public/android/junit/src/org/chromium/content/browser/BindingManagerImplTest.java index 59da387..843c293 100644 --- a/content/public/android/junit/src/org/chromium/content/browser/BindingManagerImplTest.java +++ b/content/public/android/junit/src/org/chromium/content/browser/BindingManagerImplTest.java
@@ -109,38 +109,6 @@ } /** - * Verifies that when running on low-end, the binding manager drops the oom bindings for the - * previously bound connection when a new connection is used in foreground. - */ - @Test - @Feature({"ProcessManagement"}) - public void testNewConnectionDropsPreviousOnLowEnd() { - // This test applies only to the low-end manager. - BindingManagerImpl manager = mLowEndManager; - - // Add a connection to the manager. - ChildProcessConnection firstConnection = - createTestChildProcessConnection(1 /* pid */, manager); - - // Bind a strong binding on the connection. - manager.setPriority(firstConnection.getPid(), true /* foreground */, false /* boost */); - Assert.assertTrue(firstConnection.isStrongBindingBound()); - - // Add a new connection. - ChildProcessConnection secondConnection = - createTestChildProcessConnection(2 /* pid */, manager); - - // Verify that the strong binding for the first connection wasn't dropped. - Assert.assertTrue(firstConnection.isStrongBindingBound()); - - // Verify that the strong binding for the first connection was dropped when a new connection - // got used in foreground. - manager.setPriority(secondConnection.getPid(), true /* foreground */, false /* boost */); - Assert.assertFalse(firstConnection.isStrongBindingBound()); - Assert.assertTrue(secondConnection.isStrongBindingBound()); - } - - /** * Verifies the strong binding removal policies for low end devices: * - removal of a strong binding should be executed synchronously */ @@ -279,68 +247,6 @@ } /** - * Verifies that onSentToBackground() / onBroughtToForeground() correctly attach and remove - * additional strong binding kept on the most recently bound renderer for the background - * period. - * - * The renderer that will be bound for the background period should be the one that was most - * recendly bound using .setPriority(), even if there is one that was added using - * .addNewConnection() after that. Otherwise we would bound a background renderer when user - * loads a new tab in background and leaves the browser. - */ - @Test - @Feature({"ProcessManagement"}) - public void testBackgroundPeriodBinding() { - // This test applies to low-end, high-end and moderate-binding policies. - for (ManagerEntry managerEntry : mAllManagers) { - BindingManagerImpl manager = managerEntry.mManager; - String message = managerEntry.getErrorMessage(); - - // Add two connections, bind and release each. - ChildProcessConnection firstConnection = - createTestChildProcessConnection(1 /* pid */, manager); - manager.setPriority(firstConnection.getPid(), true /* foreground */, false /* boost */); - manager.setPriority( - firstConnection.getPid(), false /* foreground */, false /* boost */); - - ChildProcessConnection secondConnection = - createTestChildProcessConnection(2 /* pid */, manager); - manager.setPriority( - secondConnection.getPid(), true /* foreground */, false /* boost */); - manager.setPriority( - secondConnection.getPid(), false /* foreground */, false /* boost */); - - // Add third connection, do not bind it. - ChildProcessConnection thirdConnection = - createTestChildProcessConnection(3 /* pid */, manager); - manager.setPriority( - thirdConnection.getPid(), false /* foreground */, false /* boost */); - - // Sanity check: verify that no connection has a strong binding. - ShadowLooper.runUiThreadTasksIncludingDelayedTasks(); - Assert.assertFalse(message, firstConnection.isStrongBindingBound()); - Assert.assertFalse(message, secondConnection.isStrongBindingBound()); - Assert.assertFalse(message, thirdConnection.isStrongBindingBound()); - - // Call onSentToBackground() and verify that a strong binding was added for the second - // connection: - // - not the first one, because it was bound earlier than the second - // - not the thirs one, because it was never bound at all - manager.onSentToBackground(); - Assert.assertFalse(message, firstConnection.isStrongBindingBound()); - Assert.assertTrue(message, secondConnection.isStrongBindingBound()); - Assert.assertFalse(message, thirdConnection.isStrongBindingBound()); - - // Call onBroughtToForeground() and verify that the strong binding was removed. - manager.onBroughtToForeground(); - ShadowLooper.runUiThreadTasksIncludingDelayedTasks(); - Assert.assertFalse(message, firstConnection.isStrongBindingBound()); - Assert.assertFalse(message, secondConnection.isStrongBindingBound()); - Assert.assertFalse(message, thirdConnection.isStrongBindingBound()); - } - } - - /** * Verifies that onSentToBackground() drops all the moderate bindings after some delay, and * onBroughtToForeground() doesn't recover them. */ @@ -364,13 +270,6 @@ Assert.assertTrue(connection.isModerateBindingBound()); } - // Exclude lastInForeground because it will be kept in foreground when onSentToBackground() - // is called as |mLastInForeground|. - ChildProcessConnection lastInForeground = - createTestChildProcessConnection(0 /* pid */, manager); - manager.setPriority(lastInForeground.getPid(), true /* foreground */, false /* boost */); - manager.setPriority(lastInForeground.getPid(), false /* foreground */, false /* boost */); - ShadowLooper.runUiThreadTasksIncludingDelayedTasks(); // Verify that leaving the application for a short time doesn't clear the moderate bindings. @@ -378,8 +277,6 @@ for (ChildProcessConnection connection : connections) { Assert.assertTrue(connection.isModerateBindingBound()); } - Assert.assertTrue(lastInForeground.isStrongBindingBound()); - Assert.assertFalse(lastInForeground.isModerateBindingBound()); manager.onBroughtToForeground(); ShadowLooper.runUiThreadTasksIncludingDelayedTasks(); for (ChildProcessConnection connection : connections) { @@ -392,8 +289,6 @@ for (ChildProcessConnection connection : connections) { Assert.assertTrue(connection.isModerateBindingBound()); } - Assert.assertTrue(lastInForeground.isStrongBindingBound()); - Assert.assertFalse(lastInForeground.isModerateBindingBound()); ShadowLooper.runUiThreadTasksIncludingDelayedTasks(); for (ChildProcessConnection connection : connections) { Assert.assertFalse(connection.isModerateBindingBound());
diff --git a/content/public/browser/native_web_keyboard_event.h b/content/public/browser/native_web_keyboard_event.h index bf6692a..a1987c6 100644 --- a/content/public/browser/native_web_keyboard_event.h +++ b/content/public/browser/native_web_keyboard_event.h
@@ -25,8 +25,7 @@ // Owns a platform specific event; used to pass own and pass event through // platform independent code. -struct CONTENT_EXPORT NativeWebKeyboardEvent : - NON_EXPORTED_BASE(public blink::WebKeyboardEvent) { +struct CONTENT_EXPORT NativeWebKeyboardEvent : public blink::WebKeyboardEvent { NativeWebKeyboardEvent(blink::WebInputEvent::Type type, int modifiers, base::TimeTicks timestamp);
diff --git a/content/public/browser/provision_fetcher_impl.h b/content/public/browser/provision_fetcher_impl.h index 724fa8f..5e58a29 100644 --- a/content/public/browser/provision_fetcher_impl.h +++ b/content/public/browser/provision_fetcher_impl.h
@@ -23,7 +23,7 @@ // A media::mojom::ProvisionFetcher implementation based on // media::ProvisionFetcher. class CONTENT_EXPORT ProvisionFetcherImpl - : NON_EXPORTED_BASE(public media::mojom::ProvisionFetcher) { + : public media::mojom::ProvisionFetcher { public: static void Create(net::URLRequestContextGetter* context_getter, media::mojom::ProvisionFetcherRequest request);
diff --git a/content/public/browser/render_process_host.h b/content/public/browser/render_process_host.h index da30dc5..488a1dc 100644 --- a/content/public/browser/render_process_host.h +++ b/content/public/browser/render_process_host.h
@@ -48,6 +48,7 @@ class RenderWidgetHost; class RendererAudioOutputStreamFactoryContext; class StoragePartition; +enum class ChildProcessImportance; struct GlobalRequestID; namespace mojom { @@ -228,6 +229,10 @@ virtual void AddWidget(RenderWidgetHost* widget) = 0; virtual void RemoveWidget(RenderWidgetHost* widget) = 0; + // Called by an already added widget when its importance changes. + virtual void UpdateWidgetImportance(ChildProcessImportance old_value, + ChildProcessImportance new_value) = 0; + // Sets a flag indicating that the process can be abnormally terminated. virtual void SetSuddenTerminationAllowed(bool allowed) = 0; // Returns true if the process can be abnormally terminated. @@ -316,38 +321,38 @@ // Returns true if this process currently has backgrounded priority. virtual bool IsProcessBackgrounded() const = 0; - // Returns the sum of the shared worker and service worker ref counts. - virtual size_t GetWorkerRefCount() const = 0; + // "Keep alive ref count" represents the number of the customers of this + // render process who wish the renderer process to be alive. While the ref + // count is positive, |this| object will keep the renderer process alive, + // unless DisableKeepAliveRefCount() is called. + // + // Here is the list of users: + // - Service Worker: + // While there are service workers who live on this process, they wish + // the renderer process alive. The ref count is incremented when this + // process is allocated to the worker, and decremented when worker's + // shutdown sequence is completed. + // - Shared Worker: + // The ref count is incremented in two cases: + // - there was no external renderer connected to a shared worker in this + // process, and now there is at least one + // - a new worker is being created in this process. + // The ref count is decremented in two cases: + // - there was an external renderer connected to a shared worker in this + // process, and now there is none + // - a new worker finished being created in this process. + virtual void IncrementKeepAliveRefCount() = 0; + virtual void DecrementKeepAliveRefCount() = 0; - // Counts the number of service workers who live on this process. The service - // worker ref count is incremented when this process is allocated to the - // worker, and decremented when worker's shutdown sequence is completed. - virtual void IncrementServiceWorkerRefCount() = 0; - virtual void DecrementServiceWorkerRefCount() = 0; - - // The shared worker ref count is non-zero if any other process is connected - // to a shared worker in this process, or a new shared worker is being created - // in this process. - // IncrementSharedWorkerRefCount is called in two cases: - // - there was no external renderer connected to a shared worker in this - // process, and now there is at least one - // - a new worker is being created in this process. - // DecrementSharedWorkerRefCount is called in two cases: - // - there was an external renderer connected to a shared worker in this - // process, and now there is none - // - a new worker finished being created in this process. - virtual void IncrementSharedWorkerRefCount() = 0; - virtual void DecrementSharedWorkerRefCount() = 0; - - // Sets worker ref counts to zero. Called when the browser context will be + // Sets keep alive ref counts to zero. Called when the browser context will be // destroyed so this RenderProcessHost can immediately die. // - // After this is called, the Increment/DecrementWorkerRefCount functions must - // not be called. - virtual void ForceReleaseWorkerRefCounts() = 0; + // After this is called, the Increment/DecrementKeepAliveRefCount() functions + // must not be called. + virtual void DisableKeepAliveRefCount() = 0; - // Returns true if ForceReleaseWorkerRefCounts was called. - virtual bool IsWorkerRefCountDisabled() = 0; + // Returns true if DisableKeepAliveRefCount() was called. + virtual bool IsKeepAliveRefCountDisabled() = 0; // Purges and suspends the renderer process. virtual void PurgeAndSuspend() = 0;
diff --git a/content/public/renderer/document_state.h b/content/public/renderer/document_state.h index 6cc6f557e..b4c5a38 100644 --- a/content/public/renderer/document_state.h +++ b/content/public/renderer/document_state.h
@@ -22,9 +22,8 @@ // The RenderView stores an instance of this class in the "extra data" of each // WebDocumentLoader (see RenderView::DidCreateDataSource). -class CONTENT_EXPORT DocumentState - : NON_EXPORTED_BASE(public blink::WebDocumentLoader::ExtraData), - public base::SupportsUserData { +class CONTENT_EXPORT DocumentState : public blink::WebDocumentLoader::ExtraData, + public base::SupportsUserData { public: DocumentState(); ~DocumentState() override;
diff --git a/content/public/test/browser_test_utils.cc b/content/public/test/browser_test_utils.cc index 1ec480d..9229bf0 100644 --- a/content/public/test/browser_test_utils.cc +++ b/content/public/test/browser_test_utils.cc
@@ -5,6 +5,8 @@ #include "content/public/test/browser_test_utils.h" #include <stddef.h> + +#include <set> #include <tuple> #include <utility> @@ -275,6 +277,112 @@ ->ForwardKeyboardEvent(event); } +int SimulateModifierKeysDown(WebContents* web_contents, + bool control, + bool shift, + bool alt, + bool command) { + int modifiers = 0; + + // The order of these key down events shouldn't matter for our simulation. + // For our simulation we can use either the left keys or the right keys. + if (control) { + modifiers |= blink::WebInputEvent::kControlKey; + InjectRawKeyEvent(web_contents, blink::WebInputEvent::kRawKeyDown, + ui::DomKey::CONTROL, ui::DomCode::CONTROL_LEFT, + ui::VKEY_CONTROL, modifiers); + } + if (shift) { + modifiers |= blink::WebInputEvent::kShiftKey; + InjectRawKeyEvent(web_contents, blink::WebInputEvent::kRawKeyDown, + ui::DomKey::SHIFT, ui::DomCode::SHIFT_LEFT, + ui::VKEY_SHIFT, modifiers); + } + if (alt) { + modifiers |= blink::WebInputEvent::kAltKey; + InjectRawKeyEvent(web_contents, blink::WebInputEvent::kRawKeyDown, + ui::DomKey::ALT, ui::DomCode::ALT_LEFT, ui::VKEY_MENU, + modifiers); + } + if (command) { + modifiers |= blink::WebInputEvent::kMetaKey; + InjectRawKeyEvent(web_contents, blink::WebInputEvent::kRawKeyDown, + ui::DomKey::META, ui::DomCode::META_LEFT, + ui::VKEY_COMMAND, modifiers); + } + return modifiers; +} + +int SimulateModifierKeysUp(WebContents* web_contents, + bool control, + bool shift, + bool alt, + bool command, + int modifiers) { + // The order of these key releases shouldn't matter for our simulation. + if (control) { + modifiers &= ~blink::WebInputEvent::kControlKey; + InjectRawKeyEvent(web_contents, blink::WebInputEvent::kKeyUp, + ui::DomKey::CONTROL, ui::DomCode::CONTROL_LEFT, + ui::VKEY_CONTROL, modifiers); + } + + if (shift) { + modifiers &= ~blink::WebInputEvent::kShiftKey; + InjectRawKeyEvent(web_contents, blink::WebInputEvent::kKeyUp, + ui::DomKey::SHIFT, ui::DomCode::SHIFT_LEFT, + ui::VKEY_SHIFT, modifiers); + } + + if (alt) { + modifiers &= ~blink::WebInputEvent::kAltKey; + InjectRawKeyEvent(web_contents, blink::WebInputEvent::kKeyUp, + ui::DomKey::ALT, ui::DomCode::ALT_LEFT, ui::VKEY_MENU, + modifiers); + } + + if (command) { + modifiers &= ~blink::WebInputEvent::kMetaKey; + InjectRawKeyEvent(web_contents, blink::WebInputEvent::kKeyUp, + ui::DomKey::META, ui::DomCode::META_LEFT, + ui::VKEY_COMMAND, modifiers); + } + return modifiers; +} + +void SimulateKeyEvent(WebContents* web_contents, + ui::DomKey key, + ui::DomCode code, + ui::KeyboardCode key_code, + bool send_char, + int modifiers) { + InjectRawKeyEvent(web_contents, blink::WebInputEvent::kRawKeyDown, key, code, + key_code, modifiers); + if (send_char) { + InjectRawKeyEvent(web_contents, blink::WebInputEvent::kChar, key, code, + key_code, modifiers); + } + InjectRawKeyEvent(web_contents, blink::WebInputEvent::kKeyUp, key, code, + key_code, modifiers); +} + +void SimulateKeyPressImpl(WebContents* web_contents, + ui::DomKey key, + ui::DomCode code, + ui::KeyboardCode key_code, + bool control, + bool shift, + bool alt, + bool command, + bool send_char) { + int modifiers = + SimulateModifierKeysDown(web_contents, control, shift, alt, command); + SimulateKeyEvent(web_contents, key, code, key_code, send_char, modifiers); + modifiers = SimulateModifierKeysUp(web_contents, control, shift, alt, command, + modifiers); + ASSERT_EQ(modifiers, 0); +} + void GetCookiesCallback(std::string* cookies_out, base::WaitableEvent* event, const std::string& cookies) { @@ -749,76 +857,65 @@ bool shift, bool alt, bool command) { - int modifiers = 0; + SimulateKeyPressImpl(web_contents, key, code, key_code, control, shift, alt, + command, /*send_char=*/true); +} - // The order of these key down events shouldn't matter for our simulation. - // For our simulation we can use either the left keys or the right keys. - if (control) { - modifiers |= blink::WebInputEvent::kControlKey; - InjectRawKeyEvent(web_contents, blink::WebInputEvent::kRawKeyDown, - ui::DomKey::CONTROL, ui::DomCode::CONTROL_LEFT, - ui::VKEY_CONTROL, modifiers); - } +void SimulateKeyPressWithoutChar(WebContents* web_contents, + ui::DomKey key, + ui::DomCode code, + ui::KeyboardCode key_code, + bool control, + bool shift, + bool alt, + bool command) { + SimulateKeyPressImpl(web_contents, key, code, key_code, control, shift, alt, + command, /*send_char=*/false); +} - if (shift) { - modifiers |= blink::WebInputEvent::kShiftKey; - InjectRawKeyEvent(web_contents, blink::WebInputEvent::kRawKeyDown, - ui::DomKey::SHIFT, ui::DomCode::SHIFT_LEFT, - ui::VKEY_SHIFT, modifiers); - } +ScopedSimulateModifierKeyPress::ScopedSimulateModifierKeyPress( + WebContents* web_contents, + bool control, + bool shift, + bool alt, + bool command) + : web_contents_(web_contents), + modifiers_(0), + control_(control), + shift_(shift), + alt_(alt), + command_(command) { + modifiers_ = + SimulateModifierKeysDown(web_contents_, control_, shift_, alt_, command_); +} - if (alt) { - modifiers |= blink::WebInputEvent::kAltKey; - InjectRawKeyEvent(web_contents, blink::WebInputEvent::kRawKeyDown, - ui::DomKey::ALT, ui::DomCode::ALT_LEFT, ui::VKEY_MENU, - modifiers); - } +ScopedSimulateModifierKeyPress::~ScopedSimulateModifierKeyPress() { + modifiers_ = SimulateModifierKeysUp(web_contents_, control_, shift_, alt_, + command_, modifiers_); + DCHECK_EQ(0, modifiers_); +} - if (command) { - modifiers |= blink::WebInputEvent::kMetaKey; - InjectRawKeyEvent(web_contents, blink::WebInputEvent::kRawKeyDown, - ui::DomKey::META, ui::DomCode::META_LEFT, - ui::VKEY_COMMAND, modifiers); - } - InjectRawKeyEvent(web_contents, blink::WebInputEvent::kRawKeyDown, key, code, - key_code, modifiers); +void ScopedSimulateModifierKeyPress::MouseClickAt( + int additional_modifiers, + blink::WebMouseEvent::Button button, + const gfx::Point& point) { + SimulateMouseClickAt(web_contents_, modifiers_ | additional_modifiers, button, + point); +} - InjectRawKeyEvent(web_contents, blink::WebInputEvent::kChar, key, code, - key_code, modifiers); +void ScopedSimulateModifierKeyPress::KeyPress(ui::DomKey key, + ui::DomCode code, + ui::KeyboardCode key_code) { + SimulateKeyEvent(web_contents_, key, code, key_code, /*send_char=*/true, + modifiers_); +} - InjectRawKeyEvent(web_contents, blink::WebInputEvent::kKeyUp, key, code, - key_code, modifiers); - - // The order of these key releases shouldn't matter for our simulation. - if (control) { - modifiers &= ~blink::WebInputEvent::kControlKey; - InjectRawKeyEvent(web_contents, blink::WebInputEvent::kKeyUp, - ui::DomKey::CONTROL, ui::DomCode::CONTROL_LEFT, - ui::VKEY_CONTROL, modifiers); - } - - if (shift) { - modifiers &= ~blink::WebInputEvent::kShiftKey; - InjectRawKeyEvent(web_contents, blink::WebInputEvent::kKeyUp, - ui::DomKey::SHIFT, ui::DomCode::SHIFT_LEFT, - ui::VKEY_SHIFT, modifiers); - } - - if (alt) { - modifiers &= ~blink::WebInputEvent::kAltKey; - InjectRawKeyEvent(web_contents, blink::WebInputEvent::kKeyUp, - ui::DomKey::ALT, ui::DomCode::ALT_LEFT, ui::VKEY_MENU, - modifiers); - } - - if (command) { - modifiers &= ~blink::WebInputEvent::kMetaKey; - InjectRawKeyEvent(web_contents, blink::WebInputEvent::kKeyUp, - ui::DomKey::META, ui::DomCode::META_LEFT, - ui::VKEY_COMMAND, modifiers); - } - - ASSERT_EQ(modifiers, 0); +void ScopedSimulateModifierKeyPress::KeyPressWithoutChar( + ui::DomKey key, + ui::DomCode code, + ui::KeyboardCode key_code) { + SimulateKeyEvent(web_contents_, key, code, key_code, /*send_char=*/false, + modifiers_); } bool IsWebcamAvailableOnSystem(WebContents* web_contents) { @@ -1329,7 +1426,7 @@ class SurfaceHitTestReadyNotifier { public: - SurfaceHitTestReadyNotifier(RenderWidgetHostViewBase* target_view); + explicit SurfaceHitTestReadyNotifier(RenderWidgetHostViewBase* target_view); ~SurfaceHitTestReadyNotifier() {} void WaitForSurfaceReady(RenderWidgetHostViewBase* root_container);
diff --git a/content/public/test/browser_test_utils.h b/content/public/test/browser_test_utils.h index cb6cb488..4d7bde8 100644 --- a/content/public/test/browser_test_utils.h +++ b/content/public/test/browser_test_utils.h
@@ -5,6 +5,7 @@ #ifndef CONTENT_PUBLIC_TEST_BROWSER_TEST_UTILS_H_ #define CONTENT_PUBLIC_TEST_BROWSER_TEST_UTILS_H_ +#include <memory> #include <queue> #include <string> #include <vector> @@ -172,6 +173,8 @@ // |key_code| alone is good enough for scenarios that only need the char // value represented by a key event and not the physical key on the keyboard // or the keyboard layout. +// If set to true, the modifiers |control|, |shift|, |alt|, and |command| are +// pressed down first before the key event, and released after. void SimulateKeyPress(WebContents* web_contents, ui::DomKey key, ui::DomCode code, @@ -181,6 +184,54 @@ bool alt, bool command); +// Like SimulateKeyPress(), but does not send the char (AKA keypress) event. +// This is useful for arrow keys and other key presses that do not generate +// characters. +void SimulateKeyPressWithoutChar(WebContents* web_contents, + ui::DomKey key, + ui::DomCode code, + ui::KeyboardCode key_code, + bool control, + bool shift, + bool alt, + bool command); + +// Holds down modifier keys for the duration of its lifetime and releases them +// upon destruction. This allows simulating multiple input events without +// simulating modifier key releases in between. +class ScopedSimulateModifierKeyPress { + public: + ScopedSimulateModifierKeyPress(WebContents* web_contents, + bool control, + bool shift, + bool alt, + bool command); + ~ScopedSimulateModifierKeyPress(); + + // Similar to SimulateMouseClickAt(). + void MouseClickAt(int additional_modifiers, + blink::WebMouseEvent::Button button, + const gfx::Point& point); + + // Similar to SimulateKeyPress(). + void KeyPress(ui::DomKey key, ui::DomCode code, ui::KeyboardCode key_code); + + // Similar to SimulateKeyPressWithoutChar(). + void KeyPressWithoutChar(ui::DomKey key, + ui::DomCode code, + ui::KeyboardCode key_code); + + private: + WebContents* const web_contents_; + int modifiers_; + const bool control_; + const bool shift_; + const bool alt_; + const bool command_; + + DISALLOW_COPY_AND_ASSIGN(ScopedSimulateModifierKeyPress); +}; + // Method to check what devices we have on the system. bool IsWebcamAvailableOnSystem(WebContents* web_contents); @@ -421,8 +472,7 @@ // safe to assume that events sent to the top-level RenderWidgetHostView can // be expected to properly hit-test to this surface, if appropriate. void WaitForGuestSurfaceReady(content::WebContents* web_contents); - -#endif +#endif // defined(USE_AURA) // Waits until the cc::Surface associated with a cross-process child frame // has been drawn for the first time. Once this method returns it should be
diff --git a/content/public/test/mock_render_process_host.cc b/content/public/test/mock_render_process_host.cc index dcc3163..05759e3 100644 --- a/content/public/test/mock_render_process_host.cc +++ b/content/public/test/mock_render_process_host.cc
@@ -16,6 +16,7 @@ #include "base/threading/thread_task_runner_handle.h" #include "base/time/time.h" #include "components/viz/service/display_embedder/server_shared_bitmap_manager.h" +#include "content/browser/child_process_importance.h" #include "content/browser/child_process_security_policy_impl.h" #include "content/browser/renderer_host/render_process_host_impl.h" #include "content/browser/renderer_host/render_view_host_impl.h" @@ -50,7 +51,7 @@ is_for_guests_only_(false), is_process_backgrounded_(false), is_unused_(true), - worker_ref_count_(0), + keep_alive_ref_count_(0), shared_bitmap_allocation_notifier_impl_( viz::ServerSharedBitmapManager::current()), weak_ptr_factory_(this) { @@ -252,6 +253,10 @@ void MockRenderProcessHost::RemoveWidget(RenderWidgetHost* widget) { } +void MockRenderProcessHost::UpdateWidgetImportance( + ChildProcessImportance old_value, + ChildProcessImportance new_value) {} + void MockRenderProcessHost::SetSuddenTerminationAllowed(bool allowed) { } @@ -307,31 +312,23 @@ return is_process_backgrounded_; } -size_t MockRenderProcessHost::GetWorkerRefCount() const { - return worker_ref_count_; +size_t MockRenderProcessHost::GetKeepAliveRefCount() const { + return keep_alive_ref_count_; } -void MockRenderProcessHost::IncrementServiceWorkerRefCount() { - ++worker_ref_count_; +void MockRenderProcessHost::IncrementKeepAliveRefCount() { + ++keep_alive_ref_count_; } -void MockRenderProcessHost::DecrementServiceWorkerRefCount() { - --worker_ref_count_; +void MockRenderProcessHost::DecrementKeepAliveRefCount() { + --keep_alive_ref_count_; } -void MockRenderProcessHost::IncrementSharedWorkerRefCount() { - ++worker_ref_count_; +void MockRenderProcessHost::DisableKeepAliveRefCount() { + keep_alive_ref_count_ = 0; } -void MockRenderProcessHost::DecrementSharedWorkerRefCount() { - --worker_ref_count_; -} - -void MockRenderProcessHost::ForceReleaseWorkerRefCounts() { - worker_ref_count_ = 0; -} - -bool MockRenderProcessHost::IsWorkerRefCountDisabled() { +bool MockRenderProcessHost::IsKeepAliveRefCountDisabled() { return false; } @@ -376,7 +373,7 @@ } bool MockRenderProcessHost::HostHasNotBeenUsed() { - return IsUnused() && listeners_.IsEmpty() && GetWorkerRefCount() == 0; + return IsUnused() && listeners_.IsEmpty() && GetKeepAliveRefCount() == 0; } void MockRenderProcessHost::FilterURL(bool empty_allowed, GURL* url) {
diff --git a/content/public/test/mock_render_process_host.h b/content/public/test/mock_render_process_host.h index d67bd9d..86b60be 100644 --- a/content/public/test/mock_render_process_host.h +++ b/content/public/test/mock_render_process_host.h
@@ -85,6 +85,8 @@ void RemovePendingView() override; void AddWidget(RenderWidgetHost* widget) override; void RemoveWidget(RenderWidgetHost* widget) override; + void UpdateWidgetImportance(ChildProcessImportance old_value, + ChildProcessImportance new_value) override; void SetSuddenTerminationAllowed(bool allowed) override; bool SuddenTerminationAllowed() const override; BrowserContext* GetBrowserContext() const override; @@ -115,13 +117,11 @@ override; const base::TimeTicks& GetInitTimeForNavigationMetrics() const override; bool IsProcessBackgrounded() const override; - size_t GetWorkerRefCount() const override; - void IncrementServiceWorkerRefCount() override; - void DecrementServiceWorkerRefCount() override; - void IncrementSharedWorkerRefCount() override; - void DecrementSharedWorkerRefCount() override; - void ForceReleaseWorkerRefCounts() override; - bool IsWorkerRefCountDisabled() override; + size_t GetKeepAliveRefCount() const; + void IncrementKeepAliveRefCount() override; + void DecrementKeepAliveRefCount() override; + void DisableKeepAliveRefCount() override; + bool IsKeepAliveRefCountDisabled() override; void PurgeAndSuspend() override; void Resume() override; mojom::Renderer* GetRendererInterface() override; @@ -183,7 +183,7 @@ bool is_process_backgrounded_; bool is_unused_; std::unique_ptr<base::ProcessHandle> process_handle; - int worker_ref_count_; + int keep_alive_ref_count_; std::unique_ptr<mojo::AssociatedInterfacePtr<mojom::Renderer>> renderer_interface_; std::map<std::string, InterfaceBinder> binder_overrides_;
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn index b0d4dbe..49c519e6 100644 --- a/content/renderer/BUILD.gn +++ b/content/renderer/BUILD.gn
@@ -482,7 +482,6 @@ "//ppapi/features", "//printing/features", "//sandbox", - "//services/device/public/cpp/generic_sensor", "//services/device/public/interfaces", "//services/device/public/interfaces:constants", "//services/metrics/public/cpp:metrics_cpp",
diff --git a/content/renderer/android/synchronous_layer_tree_frame_sink.h b/content/renderer/android/synchronous_layer_tree_frame_sink.h index 08f5d2c..424f227 100644 --- a/content/renderer/android/synchronous_layer_tree_frame_sink.h +++ b/content/renderer/android/synchronous_layer_tree_frame_sink.h
@@ -64,7 +64,7 @@ // This class can be created only on the main thread, but then becomes pinned // to a fixed thread when BindToClient is called. class SynchronousLayerTreeFrameSink - : NON_EXPORTED_BASE(public cc::LayerTreeFrameSink), + : public cc::LayerTreeFrameSink, public viz::CompositorFrameSinkSupportClient { public: SynchronousLayerTreeFrameSink(
diff --git a/content/renderer/browser_plugin/browser_plugin.h b/content/renderer/browser_plugin/browser_plugin.h index 74abac0..f0cd261 100644 --- a/content/renderer/browser_plugin/browser_plugin.h +++ b/content/renderer/browser_plugin/browser_plugin.h
@@ -30,9 +30,8 @@ class BrowserPluginManager; class ChildFrameCompositingHelper; -class CONTENT_EXPORT BrowserPlugin : - NON_EXPORTED_BASE(public blink::WebPlugin), - public MouseLockDispatcher::LockTarget { +class CONTENT_EXPORT BrowserPlugin : public blink::WebPlugin, + public MouseLockDispatcher::LockTarget { public: static BrowserPlugin* GetFromNode(blink::WebNode& node);
diff --git a/content/renderer/device_sensors/device_motion_event_pump.cc b/content/renderer/device_sensors/device_motion_event_pump.cc index 27cb4b67..94d7f3f 100644 --- a/content/renderer/device_sensors/device_motion_event_pump.cc +++ b/content/renderer/device_sensors/device_motion_event_pump.cc
@@ -2,309 +2,38 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "content/renderer/device_sensors/device_motion_event_pump.h" +#include "device_motion_event_pump.h" -#include "base/memory/ptr_util.h" -#include "content/public/common/service_names.mojom.h" -#include "content/public/renderer/render_frame.h" #include "content/public/renderer/render_thread.h" -#include "mojo/public/cpp/bindings/interface_request.h" -#include "services/device/public/cpp/generic_sensor/sensor_reading_shared_buffer_reader.h" -#include "services/device/public/cpp/generic_sensor/sensor_traits.h" -#include "services/device/public/interfaces/constants.mojom.h" -#include "services/service_manager/public/cpp/connector.h" -#include "services/service_manager/public/cpp/interface_provider.h" #include "third_party/WebKit/public/platform/modules/device_orientation/WebDeviceMotionListener.h" namespace content { -DeviceMotionEventPump::DeviceMotionEventPump(RenderThread* thread, - RenderFrame* render_frame) - : PlatformEventObserver<blink::WebDeviceMotionListener>(thread), - accelerometer_(this, device::mojom::SensorType::ACCELEROMETER), - linear_acceleration_sensor_( - this, - device::mojom::SensorType::LINEAR_ACCELERATION), - gyroscope_(this, device::mojom::SensorType::GYROSCOPE), - render_frame_(render_frame), - state_(PumpState::STOPPED) {} +DeviceMotionEventPump::DeviceMotionEventPump(RenderThread* thread) + : DeviceSensorMojoClientMixin< + DeviceSensorEventPump<blink::WebDeviceMotionListener>, + device::mojom::MotionSensor>(thread) {} DeviceMotionEventPump::~DeviceMotionEventPump() { - PlatformEventObserver<blink::WebDeviceMotionListener>::StopIfObserving(); } -void DeviceMotionEventPump::Start(blink::WebPlatformEventListener* listener) { - DVLOG(2) << "requested start"; - - if (state_ != PumpState::STOPPED) - return; - - DCHECK(!timer_.IsRunning()); - - state_ = PumpState::PENDING_START; - PlatformEventObserver<blink::WebDeviceMotionListener>::Start(listener); +void DeviceMotionEventPump::FireEvent() { + DCHECK(listener()); + device::MotionData data; + if (reader_->GetLatestData(&data) && data.all_available_sensors_are_active) + listener()->DidChangeDeviceMotion(data); } -void DeviceMotionEventPump::Stop() { - DVLOG(2) << "requested stop"; - - if (state_ == PumpState::STOPPED) - return; - - DCHECK((state_ == PumpState::PENDING_START && !timer_.IsRunning()) || - (state_ == PumpState::RUNNING && timer_.IsRunning())); - - if (timer_.IsRunning()) - timer_.Stop(); - - PlatformEventObserver<blink::WebDeviceMotionListener>::Stop(); - state_ = PumpState::STOPPED; -} - -void DeviceMotionEventPump::SendStartMessage() { - auto request = mojo::MakeRequest(&sensor_provider_); - - // When running layout tests, those observers should not listen to the - // actual hardware changes. In order to make that happen, don't connect - // the other end of the mojo pipe to anything. - if (!RenderThreadImpl::current() || - RenderThreadImpl::current()->layout_test_mode()) { - return; - } - - if (!accelerometer_.sensor && !linear_acceleration_sensor_.sensor && - !gyroscope_.sensor) { - DCHECK(render_frame_); - render_frame_->GetRemoteInterfaces()->GetInterface(std::move(request)); - sensor_provider_.set_connection_error_handler( - base::Bind(&DeviceMotionEventPump::HandleSensorProviderError, - base::Unretained(this))); - GetSensor(&accelerometer_); - GetSensor(&linear_acceleration_sensor_); - GetSensor(&gyroscope_); - } else { - if (accelerometer_.sensor) - accelerometer_.sensor->Resume(); - - if (linear_acceleration_sensor_.sensor) - linear_acceleration_sensor_.sensor->Resume(); - - if (gyroscope_.sensor) - gyroscope_.sensor->Resume(); - - DidStartIfPossible(); - } -} - -void DeviceMotionEventPump::SendStopMessage() { - // SendStopMessage() gets called both when the page visibility changes and if - // all device motion event listeners are unregistered. Since removing the - // event listener is more rare than the page visibility changing, - // Sensor::Suspend() is used to optimize this case for not doing extra work. - if (accelerometer_.sensor) - accelerometer_.sensor->Suspend(); - - if (linear_acceleration_sensor_.sensor) - linear_acceleration_sensor_.sensor->Suspend(); - - if (gyroscope_.sensor) - gyroscope_.sensor->Suspend(); +bool DeviceMotionEventPump::InitializeReader(base::SharedMemoryHandle handle) { + if (!reader_) + reader_.reset(new DeviceMotionSharedMemoryReader()); + return reader_->Initialize(handle); } void DeviceMotionEventPump::SendFakeDataForTesting(void* fake_data) { device::MotionData data = *static_cast<device::MotionData*>(fake_data); + listener()->DidChangeDeviceMotion(data); } -DeviceMotionEventPump::SensorEntry::SensorEntry( - DeviceMotionEventPump* pump, - device::mojom::SensorType sensor_type) - : event_pump(pump), type(sensor_type), client_binding(this) {} - -DeviceMotionEventPump::SensorEntry::~SensorEntry() {} - -void DeviceMotionEventPump::SensorEntry::RaiseError() { - HandleSensorError(); -} - -void DeviceMotionEventPump::SensorEntry::SensorReadingChanged() { - // Since DeviceMotionEventPump::FireEvent is called in a fixed - // frequency, the |shared_buffer| is read frequently, and - // Sensor::ConfigureReadingChangeNotifications() is set to false, - // so this method is not called and doesn't need to be implemented. - NOTREACHED(); -} - -void DeviceMotionEventPump::SensorEntry::OnSensorCreated( - device::mojom::SensorInitParamsPtr params, - device::mojom::SensorClientRequest client_request) { - if (!params) { - HandleSensorError(); - event_pump->DidStartIfPossible(); - return; - } - - constexpr size_t kReadBufferSize = sizeof(device::SensorReadingSharedBuffer); - - DCHECK_EQ(0u, params->buffer_offset % kReadBufferSize); - - mode = params->mode; - default_config = params->default_configuration; - - DCHECK(sensor.is_bound()); - client_binding.Bind(std::move(client_request)); - - shared_buffer_handle = std::move(params->memory); - DCHECK(!shared_buffer); - shared_buffer = - shared_buffer_handle->MapAtOffset(kReadBufferSize, params->buffer_offset); - - if (!shared_buffer) { - HandleSensorError(); - event_pump->DidStartIfPossible(); - return; - } - - const device::SensorReadingSharedBuffer* buffer = - static_cast<const device::SensorReadingSharedBuffer*>( - shared_buffer.get()); - shared_buffer_reader.reset( - new device::SensorReadingSharedBufferReader(buffer)); - - DCHECK_GT(params->minimum_frequency, 0.0); - DCHECK_GE(params->maximum_frequency, params->minimum_frequency); - DCHECK_GE(device::GetSensorMaxAllowedFrequency(type), - params->maximum_frequency); - - default_config.set_frequency(kDefaultPumpFrequencyHz); - - sensor->ConfigureReadingChangeNotifications(false /* disabled */); - sensor->AddConfiguration(default_config, - base::Bind(&SensorEntry::OnSensorAddConfiguration, - base::Unretained(this))); -} - -void DeviceMotionEventPump::SensorEntry::OnSensorAddConfiguration( - bool success) { - if (!success) - HandleSensorError(); - event_pump->DidStartIfPossible(); -} - -void DeviceMotionEventPump::SensorEntry::HandleSensorError() { - sensor.reset(); - shared_buffer_handle.reset(); - shared_buffer.reset(); - client_binding.Close(); -} - -bool DeviceMotionEventPump::SensorEntry::SensorReadingCouldBeRead() { - if (!sensor) - return false; - - DCHECK(shared_buffer); - - if (!shared_buffer_handle->is_valid() || - !shared_buffer_reader->GetReading(&reading)) { - HandleSensorError(); - return false; - } - - return true; -} - -void DeviceMotionEventPump::FireEvent() { - device::MotionData data; - // The device orientation spec states that interval should be in milliseconds. - // https://w3c.github.io/deviceorientation/spec-source-orientation.html#devicemotion - data.interval = kDefaultPumpDelayMicroseconds / 1000; - - DCHECK(listener()); - - GetDataFromSharedMemory(&data); - listener()->DidChangeDeviceMotion(data); -} - -void DeviceMotionEventPump::DidStartIfPossible() { - DVLOG(2) << "did start sensor event pump"; - - if (state_ != PumpState::PENDING_START) - return; - - // After the DeviceMotionEventPump::SendStartMessage() is called and before - // the DeviceMotionEventPump::SensorEntry::OnSensorCreated() callback has - // been executed, it is possible that the |sensor| is already initialized - // but its |shared_buffer| is not initialized yet. And in that case when - // DeviceMotionEventPump::SendStartMessage() is called again, - // SensorSharedBuffersReady() is used to make sure that the - // DeviceMotionEventPump can not be started when |shared_buffer| is not - // initialized. - if (!SensorSharedBuffersReady()) - return; - - DCHECK(!timer_.IsRunning()); - - timer_.Start(FROM_HERE, - base::TimeDelta::FromMicroseconds(kDefaultPumpDelayMicroseconds), - this, &DeviceMotionEventPump::FireEvent); - state_ = PumpState::RUNNING; -} - -bool DeviceMotionEventPump::SensorSharedBuffersReady() const { - if (accelerometer_.sensor && !accelerometer_.shared_buffer) - return false; - - if (linear_acceleration_sensor_.sensor && - !linear_acceleration_sensor_.shared_buffer) { - return false; - } - - if (gyroscope_.sensor && !gyroscope_.shared_buffer) - return false; - - return true; -} - -void DeviceMotionEventPump::GetDataFromSharedMemory(device::MotionData* data) { - if (accelerometer_.SensorReadingCouldBeRead()) { - data->acceleration_including_gravity_x = accelerometer_.reading.accel.x; - data->acceleration_including_gravity_y = accelerometer_.reading.accel.y; - data->acceleration_including_gravity_z = accelerometer_.reading.accel.z; - data->has_acceleration_including_gravity_x = true; - data->has_acceleration_including_gravity_y = true; - data->has_acceleration_including_gravity_z = true; - } - - if (linear_acceleration_sensor_.SensorReadingCouldBeRead()) { - data->acceleration_x = linear_acceleration_sensor_.reading.accel.x; - data->acceleration_y = linear_acceleration_sensor_.reading.accel.y; - data->acceleration_z = linear_acceleration_sensor_.reading.accel.z; - data->has_acceleration_x = true; - data->has_acceleration_y = true; - data->has_acceleration_z = true; - } - - if (gyroscope_.SensorReadingCouldBeRead()) { - data->rotation_rate_alpha = gyroscope_.reading.gyro.x; - data->rotation_rate_beta = gyroscope_.reading.gyro.y; - data->rotation_rate_gamma = gyroscope_.reading.gyro.z; - data->has_rotation_rate_alpha = true; - data->has_rotation_rate_beta = true; - data->has_rotation_rate_gamma = true; - } -} - -void DeviceMotionEventPump::GetSensor(SensorEntry* sensor_entry) { - auto request = mojo::MakeRequest(&sensor_entry->sensor); - sensor_provider_->GetSensor(sensor_entry->type, std::move(request), - base::Bind(&SensorEntry::OnSensorCreated, - base::Unretained(sensor_entry))); - sensor_entry->sensor.set_connection_error_handler(base::Bind( - &SensorEntry::HandleSensorError, base::Unretained(sensor_entry))); -} - -void DeviceMotionEventPump::HandleSensorProviderError() { - sensor_provider_.reset(); -} - } // namespace content
diff --git a/content/renderer/device_sensors/device_motion_event_pump.h b/content/renderer/device_sensors/device_motion_event_pump.h index b6a1401..5846db1 100644 --- a/content/renderer/device_sensors/device_motion_event_pump.h +++ b/content/renderer/device_sensors/device_motion_event_pump.h
@@ -6,117 +6,38 @@ #define CONTENT_RENDERER_DEVICE_SENSORS_DEVICE_MOTION_EVENT_PUMP_H_ #include <memory> -#include <utility> -#include <vector> -#include "base/bind.h" -#include "base/bind_helpers.h" #include "base/macros.h" -#include "base/time/time.h" -#include "base/timer/timer.h" -#include "content/public/renderer/platform_event_observer.h" -#include "content/renderer/render_thread_impl.h" +#include "content/renderer/device_sensors/device_sensor_event_pump.h" +#include "content/renderer/shared_memory_seqlock_reader.h" #include "device/sensors/public/cpp/motion_data.h" -#include "mojo/public/cpp/bindings/binding.h" -#include "services/device/public/cpp/generic_sensor/sensor_reading.h" -#include "services/device/public/interfaces/sensor.mojom.h" -#include "services/device/public/interfaces/sensor_provider.mojom.h" -#include "third_party/WebKit/public/platform/modules/device_orientation/WebDeviceMotionListener.h" +#include "device/sensors/public/interfaces/motion.mojom.h" -namespace device { -class SensorReadingSharedBufferReader; +namespace blink { +class WebDeviceMotionListener; } namespace content { -class RenderFrame; +typedef SharedMemorySeqLockReader<device::MotionData> + DeviceMotionSharedMemoryReader; class CONTENT_EXPORT DeviceMotionEventPump - : NON_EXPORTED_BASE( - public PlatformEventObserver<blink::WebDeviceMotionListener>) { + : public DeviceSensorMojoClientMixin< + DeviceSensorEventPump<blink::WebDeviceMotionListener>, + device::mojom::MotionSensor> { public: - DeviceMotionEventPump(RenderThread* thread, RenderFrame* render_frame); + explicit DeviceMotionEventPump(RenderThread* thread); ~DeviceMotionEventPump() override; - // PlatformEventObserver: - void Start(blink::WebPlatformEventListener* listener) override; - void Stop() override; - void SendStartMessage() override; - void SendStopMessage() override; + // PlatformEventObserver. void SendFakeDataForTesting(void* fake_data) override; protected: - // Default rate for firing events. - static constexpr int kDefaultPumpFrequencyHz = 60; - static constexpr int kDefaultPumpDelayMicroseconds = - base::Time::kMicrosecondsPerSecond / kDefaultPumpFrequencyHz; + void FireEvent() override; + bool InitializeReader(base::SharedMemoryHandle handle) override; - struct SensorEntry : public device::mojom::SensorClient { - SensorEntry(DeviceMotionEventPump* pump, - device::mojom::SensorType sensor_type); - ~SensorEntry() override; - - // device::mojom::SensorClient: - void RaiseError() override; - void SensorReadingChanged() override; - - // Mojo callback for SensorProvider::GetSensor(). - void OnSensorCreated(device::mojom::SensorInitParamsPtr params, - device::mojom::SensorClientRequest client_request); - - // Mojo callback for Sensor::AddConfiguration(). - void OnSensorAddConfiguration(bool success); - - void HandleSensorError(); - - bool SensorReadingCouldBeRead(); - - DeviceMotionEventPump* event_pump; - device::mojom::SensorPtr sensor; - device::mojom::SensorType type; - device::mojom::ReportingMode mode; - device::PlatformSensorConfiguration default_config; - mojo::ScopedSharedBufferHandle shared_buffer_handle; - mojo::ScopedSharedBufferMapping shared_buffer; - std::unique_ptr<device::SensorReadingSharedBufferReader> - shared_buffer_reader; - device::SensorReading reading; - mojo::Binding<device::mojom::SensorClient> client_binding; - }; - - friend struct SensorEntry; - - virtual void FireEvent(); - - void DidStartIfPossible(); - - SensorEntry accelerometer_; - SensorEntry linear_acceleration_sensor_; - SensorEntry gyroscope_; - - private: - FRIEND_TEST_ALL_PREFIXES(DeviceMotionEventPumpTest, - SensorInitializedButItsSharedBufferIsNot); - - // TODO(juncai): refactor DeviceMotionEventPump to use DeviceSensorEventPump - // when refactoring DeviceOrientation. - // - // The pump is a tri-state automaton with allowed transitions as follows: - // STOPPED -> PENDING_START - // PENDING_START -> RUNNING - // PENDING_START -> STOPPED - // RUNNING -> STOPPED - enum class PumpState { STOPPED, RUNNING, PENDING_START }; - - bool SensorSharedBuffersReady() const; - void GetDataFromSharedMemory(device::MotionData* data); - void GetSensor(SensorEntry* sensor_entry); - void HandleSensorProviderError(); - - RenderFrame* const render_frame_; - device::mojom::SensorProviderPtr sensor_provider_; - PumpState state_; - base::RepeatingTimer timer_; + std::unique_ptr<DeviceMotionSharedMemoryReader> reader_; DISALLOW_COPY_AND_ASSIGN(DeviceMotionEventPump); };
diff --git a/content/renderer/device_sensors/device_motion_event_pump_unittest.cc b/content/renderer/device_sensors/device_motion_event_pump_unittest.cc index a93e5b5..58f274c 100644 --- a/content/renderer/device_sensors/device_motion_event_pump_unittest.cc +++ b/content/renderer/device_sensors/device_motion_event_pump_unittest.cc
@@ -11,33 +11,16 @@ #include "base/location.h" #include "base/logging.h" #include "base/macros.h" -#include "base/memory/ptr_util.h" #include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "base/single_thread_task_runner.h" #include "base/threading/thread_task_runner_handle.h" -#include "base/time/time.h" #include "content/public/test/test_utils.h" -#include "device/sensors/public/cpp/motion_data.h" -#include "mojo/public/cpp/bindings/interface_request.h" +#include "device/sensors/public/cpp/device_motion_hardware_buffer.h" #include "mojo/public/cpp/system/buffer.h" -#include "services/device/public/cpp/generic_sensor/sensor_reading.h" -#include "services/device/public/cpp/generic_sensor/sensor_reading_shared_buffer_reader.h" -#include "services/device/public/interfaces/sensor.mojom.h" -#include "services/device/public/interfaces/sensor_provider.mojom.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/WebKit/public/platform/modules/device_orientation/WebDeviceMotionListener.h" -namespace { - -constexpr uint64_t kReadingBufferSize = - sizeof(device::SensorReadingSharedBuffer); - -constexpr uint64_t kSharedBufferSizeInBytes = - kReadingBufferSize * static_cast<uint64_t>(device::mojom::SensorType::LAST); - -} // namespace - namespace content { class MockDeviceMotionListener : public blink::WebDeviceMotionListener { @@ -73,112 +56,22 @@ class DeviceMotionEventPumpForTesting : public DeviceMotionEventPump { public: DeviceMotionEventPumpForTesting() - : DeviceMotionEventPump(nullptr, nullptr), stop_on_fire_event_(true) {} + : DeviceMotionEventPump(0), stop_on_fire_event_(true) {} ~DeviceMotionEventPumpForTesting() override {} - // DeviceMotionEventPump: - void SendStartMessage() override { - accelerometer_.mode = device::mojom::ReportingMode::CONTINUOUS; - linear_acceleration_sensor_.mode = device::mojom::ReportingMode::ON_CHANGE; - gyroscope_.mode = device::mojom::ReportingMode::CONTINUOUS; - - shared_memory_ = mojo::SharedBufferHandle::Create(kSharedBufferSizeInBytes); - - accelerometer_.shared_buffer_handle = shared_memory_->Clone(); - accelerometer_.shared_buffer = shared_memory_->MapAtOffset( - kReadingBufferSize, - device::SensorReadingSharedBuffer::GetOffset(accelerometer_.type)); - accelerometer_buffer_ = static_cast<device::SensorReadingSharedBuffer*>( - accelerometer_.shared_buffer.get()); - accelerometer_.shared_buffer_reader.reset( - new device::SensorReadingSharedBufferReader(accelerometer_buffer_)); - - linear_acceleration_sensor_.shared_buffer_handle = shared_memory_->Clone(); - linear_acceleration_sensor_.shared_buffer = shared_memory_->MapAtOffset( - kReadingBufferSize, device::SensorReadingSharedBuffer::GetOffset( - linear_acceleration_sensor_.type)); - linear_acceleration_sensor_buffer_ = - static_cast<device::SensorReadingSharedBuffer*>( - linear_acceleration_sensor_.shared_buffer.get()); - linear_acceleration_sensor_.shared_buffer_reader.reset( - new device::SensorReadingSharedBufferReader( - linear_acceleration_sensor_buffer_)); - - gyroscope_.shared_buffer_handle = shared_memory_->Clone(); - gyroscope_.shared_buffer = shared_memory_->MapAtOffset( - kReadingBufferSize, - device::SensorReadingSharedBuffer::GetOffset(gyroscope_.type)); - gyroscope_buffer_ = static_cast<device::SensorReadingSharedBuffer*>( - gyroscope_.shared_buffer.get()); - gyroscope_.shared_buffer_reader.reset( - new device::SensorReadingSharedBufferReader(gyroscope_buffer_)); - } - - void StartFireEvent() { DeviceMotionEventPump::DidStartIfPossible(); } - - void SetAccelerometerSensorData(bool active, double x, double y, double z) { - if (active) { - mojo::MakeRequest(&accelerometer_.sensor); - accelerometer_buffer_->reading.accel.timestamp = - (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF(); - accelerometer_buffer_->reading.accel.x = x; - accelerometer_buffer_->reading.accel.y = y; - accelerometer_buffer_->reading.accel.z = z; - } else { - accelerometer_.sensor.reset(); - } - } - - void InitializeAccelerometerSensorPtr() { - mojo::MakeRequest(&accelerometer_.sensor); - } - - void InitializeAccelerometerSharedBuffer() { - shared_memory_ = mojo::SharedBufferHandle::Create(kSharedBufferSizeInBytes); - accelerometer_.shared_buffer = shared_memory_->MapAtOffset( - kReadingBufferSize, - device::SensorReadingSharedBuffer::GetOffset(accelerometer_.type)); - } - - void SetLinearAccelerationSensorData(bool active, - double x, - double y, - double z) { - if (active) { - mojo::MakeRequest(&linear_acceleration_sensor_.sensor); - linear_acceleration_sensor_buffer_->reading.accel.timestamp = - (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF(); - linear_acceleration_sensor_buffer_->reading.accel.x = x; - linear_acceleration_sensor_buffer_->reading.accel.y = y; - linear_acceleration_sensor_buffer_->reading.accel.z = z; - } else { - linear_acceleration_sensor_.sensor.reset(); - } - } - - void SetGyroscopeSensorData(bool active, double x, double y, double z) { - if (active) { - mojo::MakeRequest(&gyroscope_.sensor); - gyroscope_buffer_->reading.gyro.timestamp = - (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF(); - gyroscope_buffer_->reading.gyro.x = x; - gyroscope_buffer_->reading.gyro.y = y; - gyroscope_buffer_->reading.gyro.z = z; - } else { - gyroscope_.sensor.reset(); - } - } - void set_stop_on_fire_event(bool stop_on_fire_event) { stop_on_fire_event_ = stop_on_fire_event; } bool stop_on_fire_event() { return stop_on_fire_event_; } - int pump_delay_microseconds() const { return kDefaultPumpDelayMicroseconds; } + int pump_delay_microseconds() const { return pump_delay_microseconds_; } - protected: - // DeviceMotionEventPump: + void DidStart(mojo::ScopedSharedBufferHandle renderer_handle) { + DeviceMotionEventPump::DidStart(std::move(renderer_handle)); + } + void SendStartMessage() override {} + void SendStopMessage() override {} void FireEvent() override { DeviceMotionEventPump::FireEvent(); if (stop_on_fire_event_) { @@ -189,10 +82,6 @@ private: bool stop_on_fire_event_; - mojo::ScopedSharedBufferHandle shared_memory_; - device::SensorReadingSharedBuffer* accelerometer_buffer_; - device::SensorReadingSharedBuffer* linear_acceleration_sensor_buffer_; - device::SensorReadingSharedBuffer* gyroscope_buffer_; DISALLOW_COPY_AND_ASSIGN(DeviceMotionEventPumpForTesting); }; @@ -204,102 +93,90 @@ protected: void SetUp() override { listener_.reset(new MockDeviceMotionListener); - motion_pump_.reset(new DeviceMotionEventPumpForTesting()); + motion_pump_.reset(new DeviceMotionEventPumpForTesting); + shared_memory_ = mojo::SharedBufferHandle::Create( + sizeof(device::DeviceMotionHardwareBuffer)); + mapping_ = shared_memory_->Map(sizeof(device::DeviceMotionHardwareBuffer)); + ASSERT_TRUE(mapping_); + memset(buffer(), 0, sizeof(device::DeviceMotionHardwareBuffer)); + } + + void InitBuffer(bool allAvailableSensorsActive) { + device::MotionData& data = buffer()->data; + data.acceleration_x = 1; + data.has_acceleration_x = true; + data.acceleration_y = 2; + data.has_acceleration_y = true; + data.acceleration_z = 3; + data.has_acceleration_z = true; + data.all_available_sensors_are_active = allAvailableSensorsActive; } MockDeviceMotionListener* listener() { return listener_.get(); } DeviceMotionEventPumpForTesting* motion_pump() { return motion_pump_.get(); } + mojo::ScopedSharedBufferHandle handle() { + return shared_memory_->Clone( + mojo::SharedBufferHandle::AccessMode::READ_ONLY); + } + device::DeviceMotionHardwareBuffer* buffer() { + return reinterpret_cast<device::DeviceMotionHardwareBuffer*>( + mapping_.get()); + } private: base::MessageLoop loop_; std::unique_ptr<MockDeviceMotionListener> listener_; std::unique_ptr<DeviceMotionEventPumpForTesting> motion_pump_; + mojo::ScopedSharedBufferHandle shared_memory_; + mojo::ScopedSharedBufferMapping mapping_; DISALLOW_COPY_AND_ASSIGN(DeviceMotionEventPumpTest); }; -TEST_F(DeviceMotionEventPumpTest, AllSensorsAreActive) { +TEST_F(DeviceMotionEventPumpTest, DidStartPolling) { + InitBuffer(true); + motion_pump()->Start(listener()); - motion_pump()->SetAccelerometerSensorData(true /* active */, 1, 2, 3); - motion_pump()->SetLinearAccelerationSensorData(true /* active */, 4, 5, 6); - motion_pump()->SetGyroscopeSensorData(true /* active */, 7, 8, 9); - motion_pump()->StartFireEvent(); + motion_pump()->DidStart(handle()); base::RunLoop().Run(); - device::MotionData received_data = listener()->data(); + const device::MotionData& received_data = listener()->data(); EXPECT_TRUE(listener()->did_change_device_motion()); - - EXPECT_TRUE(received_data.has_acceleration_including_gravity_x); - EXPECT_EQ(1, received_data.acceleration_including_gravity_x); - EXPECT_TRUE(received_data.has_acceleration_including_gravity_y); - EXPECT_EQ(2, received_data.acceleration_including_gravity_y); - EXPECT_TRUE(received_data.has_acceleration_including_gravity_z); - EXPECT_EQ(3, received_data.acceleration_including_gravity_z); - EXPECT_TRUE(received_data.has_acceleration_x); - EXPECT_EQ(4, received_data.acceleration_x); + EXPECT_EQ(1, static_cast<double>(received_data.acceleration_x)); + EXPECT_TRUE(received_data.has_acceleration_x); + EXPECT_EQ(2, static_cast<double>(received_data.acceleration_y)); EXPECT_TRUE(received_data.has_acceleration_y); - EXPECT_EQ(5, received_data.acceleration_y); + EXPECT_EQ(3, static_cast<double>(received_data.acceleration_z)); EXPECT_TRUE(received_data.has_acceleration_z); - EXPECT_EQ(6, received_data.acceleration_z); - - EXPECT_TRUE(received_data.has_rotation_rate_alpha); - EXPECT_EQ(7, received_data.rotation_rate_alpha); - EXPECT_TRUE(received_data.has_rotation_rate_beta); - EXPECT_EQ(8, received_data.rotation_rate_beta); - EXPECT_TRUE(received_data.has_rotation_rate_gamma); - EXPECT_EQ(9, received_data.rotation_rate_gamma); -} - -TEST_F(DeviceMotionEventPumpTest, TwoSensorsAreActive) { - motion_pump()->Start(listener()); - motion_pump()->SetAccelerometerSensorData(true /* active */, 1, 2, 3); - motion_pump()->SetLinearAccelerationSensorData(false /* active */, 4, 5, 6); - motion_pump()->SetGyroscopeSensorData(true /* active */, 7, 8, 9); - motion_pump()->StartFireEvent(); - - base::RunLoop().Run(); - - device::MotionData received_data = listener()->data(); - EXPECT_TRUE(listener()->did_change_device_motion()); - - EXPECT_TRUE(received_data.has_acceleration_including_gravity_x); - EXPECT_EQ(1, received_data.acceleration_including_gravity_x); - EXPECT_TRUE(received_data.has_acceleration_including_gravity_y); - EXPECT_EQ(2, received_data.acceleration_including_gravity_y); - EXPECT_TRUE(received_data.has_acceleration_including_gravity_z); - EXPECT_EQ(3, received_data.acceleration_including_gravity_z); - - EXPECT_FALSE(received_data.has_acceleration_x); - EXPECT_FALSE(received_data.has_acceleration_y); - EXPECT_FALSE(received_data.has_acceleration_z); - - EXPECT_TRUE(received_data.has_rotation_rate_alpha); - EXPECT_EQ(7, received_data.rotation_rate_alpha); - EXPECT_TRUE(received_data.has_rotation_rate_beta); - EXPECT_EQ(8, received_data.rotation_rate_beta); - EXPECT_TRUE(received_data.has_rotation_rate_gamma); - EXPECT_EQ(9, received_data.rotation_rate_gamma); -} - -TEST_F(DeviceMotionEventPumpTest, NoActiveSensors) { - motion_pump()->Start(listener()); - motion_pump()->StartFireEvent(); - - base::RunLoop().Run(); - - device::MotionData received_data = listener()->data(); - EXPECT_TRUE(listener()->did_change_device_motion()); - - EXPECT_FALSE(received_data.has_acceleration_x); - EXPECT_FALSE(received_data.has_acceleration_y); - EXPECT_FALSE(received_data.has_acceleration_z); - EXPECT_FALSE(received_data.has_acceleration_including_gravity_x); EXPECT_FALSE(received_data.has_acceleration_including_gravity_y); EXPECT_FALSE(received_data.has_acceleration_including_gravity_z); + EXPECT_FALSE(received_data.has_rotation_rate_alpha); + EXPECT_FALSE(received_data.has_rotation_rate_beta); + EXPECT_FALSE(received_data.has_rotation_rate_gamma); +} +TEST_F(DeviceMotionEventPumpTest, DidStartPollingNotAllSensorsActive) { + InitBuffer(false); + + motion_pump()->Start(listener()); + motion_pump()->DidStart(handle()); + + base::RunLoop().Run(); + + const device::MotionData& received_data = listener()->data(); + // No change in device motion because all_available_sensors_are_active is + // false. + EXPECT_FALSE(listener()->did_change_device_motion()); + EXPECT_FALSE(received_data.has_acceleration_x); + EXPECT_FALSE(received_data.has_acceleration_x); + EXPECT_FALSE(received_data.has_acceleration_y); + EXPECT_FALSE(received_data.has_acceleration_z); + EXPECT_FALSE(received_data.has_acceleration_including_gravity_x); + EXPECT_FALSE(received_data.has_acceleration_including_gravity_y); + EXPECT_FALSE(received_data.has_acceleration_including_gravity_z); EXPECT_FALSE(received_data.has_rotation_rate_alpha); EXPECT_FALSE(received_data.has_rotation_rate_beta); EXPECT_FALSE(received_data.has_rotation_rate_gamma); @@ -312,11 +189,11 @@ EXPECT_GE(60, base::Time::kMicrosecondsPerSecond / motion_pump()->pump_delay_microseconds()); - motion_pump()->Start(listener()); - motion_pump()->SetLinearAccelerationSensorData(true /* active */, 4, 5, 6); + InitBuffer(true); motion_pump()->set_stop_on_fire_event(false); - motion_pump()->StartFireEvent(); + motion_pump()->Start(listener()); + motion_pump()->DidStart(handle()); base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( FROM_HERE, base::MessageLoop::QuitWhenIdleClosure(), @@ -330,23 +207,4 @@ EXPECT_GE(6, listener()->number_of_events()); } -TEST_F(DeviceMotionEventPumpTest, SensorInitializedButItsSharedBufferIsNot) { - // Initialize the |sensor|, but do not initialize its |shared_buffer|, this - // is to test the state when |sensor| is already initialized but its - // |shared_buffer| is not initialized yet, and make sure that the - // DeviceMotionEventPump can not be started until |shared_buffer| is - // initialized. - EXPECT_FALSE(motion_pump()->accelerometer_.sensor); - motion_pump()->InitializeAccelerometerSensorPtr(); - EXPECT_TRUE(motion_pump()->accelerometer_.sensor); - EXPECT_FALSE(motion_pump()->accelerometer_.shared_buffer); - EXPECT_FALSE(motion_pump()->SensorSharedBuffersReady()); - - // Initialize |shared_buffer| and make sure that now DeviceMotionEventPump - // can be started. - motion_pump()->InitializeAccelerometerSharedBuffer(); - EXPECT_TRUE(motion_pump()->accelerometer_.shared_buffer); - EXPECT_TRUE(motion_pump()->SensorSharedBuffersReady()); -} - } // namespace content
diff --git a/content/renderer/device_sensors/device_sensor_event_pump.h b/content/renderer/device_sensors/device_sensor_event_pump.h index 17a8ff9..5180f1e 100644 --- a/content/renderer/device_sensors/device_sensor_event_pump.h +++ b/content/renderer/device_sensors/device_sensor_event_pump.h
@@ -59,7 +59,7 @@ template <typename ListenerType> class CONTENT_EXPORT DeviceSensorEventPump - : NON_EXPORTED_BASE(public PlatformEventObserver<ListenerType>) { + : public PlatformEventObserver<ListenerType> { public: // Default rate for firing events. static const int kDefaultPumpFrequencyHz = 60;
diff --git a/content/renderer/devtools/devtools_agent.h b/content/renderer/devtools/devtools_agent.h index 2785179..a9ad365 100644 --- a/content/renderer/devtools/devtools_agent.h +++ b/content/renderer/devtools/devtools_agent.h
@@ -32,9 +32,8 @@ // DevToolsAgent belongs to the inspectable RenderFrameImpl and communicates // with WebDevToolsAgent. There is a corresponding DevToolsAgentHost // on the browser side. -class CONTENT_EXPORT DevToolsAgent - : public RenderFrameObserver, - NON_EXPORTED_BASE(public blink::WebDevToolsAgentClient) { +class CONTENT_EXPORT DevToolsAgent : public RenderFrameObserver, + public blink::WebDevToolsAgentClient { public: explicit DevToolsAgent(RenderFrameImpl* frame); ~DevToolsAgent() override;
diff --git a/content/renderer/devtools/devtools_client.h b/content/renderer/devtools/devtools_client.h index ed74ec5..7c32dee 100644 --- a/content/renderer/devtools/devtools_client.h +++ b/content/renderer/devtools/devtools_client.h
@@ -27,9 +27,8 @@ // corresponding DevToolsAgent object. // TODO(yurys): now the client is almost empty later it will delegate calls to // code in glue -class CONTENT_EXPORT DevToolsClient - : public RenderFrameObserver, - NON_EXPORTED_BASE(public blink::WebDevToolsFrontendClient) { +class CONTENT_EXPORT DevToolsClient : public RenderFrameObserver, + public blink::WebDevToolsFrontendClient { public: DevToolsClient(RenderFrame* render_frame, const std::string& api_script); ~DevToolsClient() override;
diff --git a/content/renderer/gpu/render_widget_compositor.cc b/content/renderer/gpu/render_widget_compositor.cc index eb49179..0bbf97c7 100644 --- a/content/renderer/gpu/render_widget_compositor.cc +++ b/content/renderer/gpu/render_widget_compositor.cc
@@ -311,10 +311,10 @@ float device_scale_factor, const ScreenInfo& screen_info) { base::CommandLine* cmd = base::CommandLine::ForCurrentProcess(); - cc::LayerTreeSettings settings = GenerateLayerTreeSettings( - *cmd, deps, device_scale_factor, client->IsForSubframe(), screen_info); - const bool is_threaded = !!deps->GetCompositorImplThreadTaskRunner(); + cc::LayerTreeSettings settings = GenerateLayerTreeSettings( + *cmd, deps, device_scale_factor, client->IsForSubframe(), screen_info, + is_threaded); std::unique_ptr<cc::LayerTreeHost> layer_tree_host; @@ -350,9 +350,11 @@ CompositorDependencies* compositor_deps, float device_scale_factor, bool is_for_subframe, - const ScreenInfo& screen_info) { + const ScreenInfo& screen_info, + bool is_threaded) { cc::LayerTreeSettings settings; + settings.commit_to_active_tree = !is_threaded; settings.is_layer_tree_for_subframe = is_for_subframe; // For web contents, layer transforms should scale up the contents of layers @@ -511,6 +513,9 @@ // TODO(danakj): Only do this on low end devices. settings.create_low_res_tiling = true; + + if (base::SysInfo::AmountOfPhysicalMemoryMB() <= 512) + settings.use_half_width_tiles_for_gpu_rasterization = true; #else // defined(OS_ANDROID) bool using_synchronous_compositor = false; // Only for Android WebView. // On desktop, we never use the low memory policy unless we are simulating
diff --git a/content/renderer/gpu/render_widget_compositor.h b/content/renderer/gpu/render_widget_compositor.h index cdcd003..42c0d30 100644 --- a/content/renderer/gpu/render_widget_compositor.h +++ b/content/renderer/gpu/render_widget_compositor.h
@@ -51,9 +51,9 @@ struct ScreenInfo; class CONTENT_EXPORT RenderWidgetCompositor - : NON_EXPORTED_BASE(public blink::WebLayerTreeView), - NON_EXPORTED_BASE(public cc::LayerTreeHostClient), - NON_EXPORTED_BASE(public cc::LayerTreeHostSingleThreadClient) { + : public blink::WebLayerTreeView, + public cc::LayerTreeHostClient, + public cc::LayerTreeHostSingleThreadClient { using ReportTimeCallback = base::Callback<void(blink::WebLayerTreeView::SwapResult, double)>; @@ -71,7 +71,8 @@ CompositorDependencies* compositor_deps, float device_scale_factor, bool is_for_subframe, - const ScreenInfo& screen_info); + const ScreenInfo& screen_info, + bool is_threaded); static std::unique_ptr<cc::LayerTreeHost> CreateLayerTreeHost( cc::LayerTreeHostClient* client, cc::LayerTreeHostSingleThreadClient* single_thread_client,
diff --git a/content/renderer/image_capture/image_capture_frame_grabber.h b/content/renderer/image_capture/image_capture_frame_grabber.h index 056b80f..e64afd2 100644 --- a/content/renderer/image_capture/image_capture_frame_grabber.h +++ b/content/renderer/image_capture/image_capture_frame_grabber.h
@@ -26,8 +26,8 @@ // thread and converts it into the appropriate SkBitmap which is sent back to // OnSkBitmap(). This class is single threaded throughout. class CONTENT_EXPORT ImageCaptureFrameGrabber final - : NON_EXPORTED_BASE(public blink::WebImageCaptureFrameGrabber), - NON_EXPORTED_BASE(public MediaStreamVideoSink) { + : public blink::WebImageCaptureFrameGrabber, + public MediaStreamVideoSink { public: using SkImageDeliverCB = base::Callback<void(sk_sp<SkImage>)>;
diff --git a/content/renderer/installedapp/related_apps_fetcher.h b/content/renderer/installedapp/related_apps_fetcher.h index 1d210fa3..379a9f5 100644 --- a/content/renderer/installedapp/related_apps_fetcher.h +++ b/content/renderer/installedapp/related_apps_fetcher.h
@@ -17,8 +17,7 @@ struct ManifestDebugInfo; class ManifestManager; -class CONTENT_EXPORT RelatedAppsFetcher - : public NON_EXPORTED_BASE(blink::WebRelatedAppsFetcher) { +class CONTENT_EXPORT RelatedAppsFetcher : public blink::WebRelatedAppsFetcher { public: explicit RelatedAppsFetcher(ManifestManager* manifest_manager); ~RelatedAppsFetcher() override;
diff --git a/content/renderer/media/audio_input_message_filter.cc b/content/renderer/media/audio_input_message_filter.cc index 9c69e3e..ec41681 100644 --- a/content/renderer/media/audio_input_message_filter.cc +++ b/content/renderer/media/audio_input_message_filter.cc
@@ -29,8 +29,7 @@ namespace content { -class AudioInputMessageFilter::AudioInputIPCImpl - : public NON_EXPORTED_BASE(media::AudioInputIPC) { +class AudioInputMessageFilter::AudioInputIPCImpl : public media::AudioInputIPC { public: AudioInputIPCImpl(const scoped_refptr<AudioInputMessageFilter>& filter, int render_frame_id);
diff --git a/content/renderer/media/audio_message_filter.cc b/content/renderer/media/audio_message_filter.cc index 8aa3698..9524bf1a 100644 --- a/content/renderer/media/audio_message_filter.cc +++ b/content/renderer/media/audio_message_filter.cc
@@ -20,8 +20,7 @@ const int kStreamIDNotSet = -1; } -class AudioMessageFilter::AudioOutputIPCImpl - : public NON_EXPORTED_BASE(media::AudioOutputIPC) { +class AudioMessageFilter::AudioOutputIPCImpl : public media::AudioOutputIPC { public: AudioOutputIPCImpl(const scoped_refptr<AudioMessageFilter>& filter, int render_frame_id);
diff --git a/content/renderer/media/cdm/ppapi_decryptor.cc b/content/renderer/media/cdm/ppapi_decryptor.cc index 7ffa5014..3b1601b2 100644 --- a/content/renderer/media/cdm/ppapi_decryptor.cc +++ b/content/renderer/media/cdm/ppapi_decryptor.cc
@@ -114,7 +114,7 @@ DCHECK(render_task_runner_->BelongsToCurrentThread()); if (!CdmDelegate()) { - promise->reject(media::CdmPromise::INVALID_STATE_ERROR, 0, + promise->reject(media::CdmPromise::Exception::INVALID_STATE_ERROR, 0, "CDM has failed."); return; } @@ -129,7 +129,7 @@ DCHECK(render_task_runner_->BelongsToCurrentThread()); if (!CdmDelegate()) { - promise->reject(media::CdmPromise::INVALID_STATE_ERROR, 0, + promise->reject(media::CdmPromise::Exception::INVALID_STATE_ERROR, 0, "CDM has failed."); return; } @@ -146,7 +146,7 @@ DCHECK(render_task_runner_->BelongsToCurrentThread()); if (!CdmDelegate()) { - promise->reject(media::CdmPromise::INVALID_STATE_ERROR, 0, + promise->reject(media::CdmPromise::Exception::INVALID_STATE_ERROR, 0, "CDM has failed."); return; } @@ -163,7 +163,7 @@ DCHECK(render_task_runner_->BelongsToCurrentThread()); if (!CdmDelegate()) { - promise->reject(media::CdmPromise::INVALID_STATE_ERROR, 0, + promise->reject(media::CdmPromise::Exception::INVALID_STATE_ERROR, 0, "CDM has failed."); return; } @@ -178,7 +178,7 @@ DCHECK(render_task_runner_->BelongsToCurrentThread()); if (!CdmDelegate()) { - promise->reject(media::CdmPromise::INVALID_STATE_ERROR, 0, + promise->reject(media::CdmPromise::Exception::INVALID_STATE_ERROR, 0, "CDM has failed."); return; } @@ -192,7 +192,7 @@ DCHECK(render_task_runner_->BelongsToCurrentThread()); if (!CdmDelegate()) { - promise->reject(media::CdmPromise::INVALID_STATE_ERROR, 0, + promise->reject(media::CdmPromise::Exception::INVALID_STATE_ERROR, 0, "CDM has failed."); return; } @@ -207,7 +207,7 @@ DCHECK(render_task_runner_->BelongsToCurrentThread()); if (!CdmDelegate()) { - promise->reject(media::CdmPromise::INVALID_STATE_ERROR, 0, + promise->reject(media::CdmPromise::Exception::INVALID_STATE_ERROR, 0, "CDM has failed."); return; }
diff --git a/content/renderer/media/external_media_stream_audio_source.h b/content/renderer/media/external_media_stream_audio_source.h index 615508f8..eaf1e3a 100644 --- a/content/renderer/media/external_media_stream_audio_source.h +++ b/content/renderer/media/external_media_stream_audio_source.h
@@ -17,8 +17,8 @@ // MediaStream framework. Audio data is transported directly to the tracks // (i.e., there is no audio processing). class CONTENT_EXPORT ExternalMediaStreamAudioSource final - : NON_EXPORTED_BASE(public MediaStreamAudioSource), - NON_EXPORTED_BASE(public media::AudioCapturerSource::CaptureCallback) { + : public MediaStreamAudioSource, + public media::AudioCapturerSource::CaptureCallback { public: ExternalMediaStreamAudioSource( scoped_refptr<media::AudioCapturerSource> source,
diff --git a/content/renderer/media/gpu/rtc_video_decoder.h b/content/renderer/media/gpu/rtc_video_decoder.h index c61cb62..cddee8b 100644 --- a/content/renderer/media/gpu/rtc_video_decoder.h +++ b/content/renderer/media/gpu/rtc_video_decoder.h
@@ -49,7 +49,7 @@ // Decode() is non-blocking and queues the buffers. Decoded frames are // delivered to WebRTC on the media task runner. class CONTENT_EXPORT RTCVideoDecoder - : NON_EXPORTED_BASE(public webrtc::VideoDecoder), + : public webrtc::VideoDecoder, public media::VideoDecodeAccelerator::Client { public: ~RTCVideoDecoder() override;
diff --git a/content/renderer/media/gpu/rtc_video_decoder_factory.h b/content/renderer/media/gpu/rtc_video_decoder_factory.h index 5d53b2b..7a4e45b 100644 --- a/content/renderer/media/gpu/rtc_video_decoder_factory.h +++ b/content/renderer/media/gpu/rtc_video_decoder_factory.h
@@ -23,7 +23,7 @@ // TODO(wuchengli): add unittest. class CONTENT_EXPORT RTCVideoDecoderFactory - : NON_EXPORTED_BASE(public cricket::WebRtcVideoDecoderFactory) { + : public cricket::WebRtcVideoDecoderFactory { public: explicit RTCVideoDecoderFactory( media::GpuVideoAcceleratorFactories* gpu_factories);
diff --git a/content/renderer/media/gpu/rtc_video_encoder.h b/content/renderer/media/gpu/rtc_video_encoder.h index a5c09fd5..9612e025 100644 --- a/content/renderer/media/gpu/rtc_video_encoder.h +++ b/content/renderer/media/gpu/rtc_video_encoder.h
@@ -38,8 +38,7 @@ // the media thread. RTCVideoEncoder is sychronized by webrtc::VideoSender. // webrtc::VideoEncoder methods do not run concurrently. RtcVideoEncoder needs // to synchronize RegisterEncodeCompleteCallback and encode complete callback. -class CONTENT_EXPORT RTCVideoEncoder - : NON_EXPORTED_BASE(public webrtc::VideoEncoder) { +class CONTENT_EXPORT RTCVideoEncoder : public webrtc::VideoEncoder { public: RTCVideoEncoder(media::VideoCodecProfile profile, media::GpuVideoAcceleratorFactories* gpu_factories);
diff --git a/content/renderer/media/gpu/rtc_video_encoder_factory.h b/content/renderer/media/gpu/rtc_video_encoder_factory.h index c5bcde0..baf30df9 100644 --- a/content/renderer/media/gpu/rtc_video_encoder_factory.h +++ b/content/renderer/media/gpu/rtc_video_encoder_factory.h
@@ -23,7 +23,7 @@ // This class creates RTCVideoEncoder instances (each wrapping a // media::VideoEncodeAccelerator) on behalf of the WebRTC stack. class CONTENT_EXPORT RTCVideoEncoderFactory - : NON_EXPORTED_BASE(public cricket::WebRtcVideoEncoderFactory) { + : public cricket::WebRtcVideoEncoderFactory { public: explicit RTCVideoEncoderFactory( media::GpuVideoAcceleratorFactories* gpu_factories);
diff --git a/content/renderer/media/local_media_stream_audio_source.h b/content/renderer/media/local_media_stream_audio_source.h index ad44f3c..4aabddad 100644 --- a/content/renderer/media/local_media_stream_audio_source.h +++ b/content/renderer/media/local_media_stream_audio_source.h
@@ -16,8 +16,8 @@ // first track is connected. Audio data is transported directly to the tracks // (i.e., there is no audio processing). class CONTENT_EXPORT LocalMediaStreamAudioSource - : NON_EXPORTED_BASE(public MediaStreamAudioSource), - NON_EXPORTED_BASE(public media::AudioCapturerSource::CaptureCallback) { + : public MediaStreamAudioSource, + public media::AudioCapturerSource::CaptureCallback { public: // |consumer_render_frame_id| references the RenderFrame that will consume the // audio data. Audio parameters and (optionally) a pre-existing audio session
diff --git a/content/renderer/media/media_stream.h b/content/renderer/media/media_stream.h index c702366..0d39ca9 100644 --- a/content/renderer/media/media_stream.h +++ b/content/renderer/media/media_stream.h
@@ -33,8 +33,7 @@ // MediaStream is the Chrome representation of blink::WebMediaStream. // It is owned by blink::WebMediaStream as blink::WebMediaStream::ExtraData. // Its lifetime is the same as the blink::WebMediaStream instance it belongs to. -class CONTENT_EXPORT MediaStream - : NON_EXPORTED_BASE(public blink::WebMediaStream::ExtraData) { +class CONTENT_EXPORT MediaStream : public blink::WebMediaStream::ExtraData { public: MediaStream(); ~MediaStream() override;
diff --git a/content/renderer/media/media_stream_audio_processor.h b/content/renderer/media/media_stream_audio_processor.h index e02c3ad..d8fb6c0 100644 --- a/content/renderer/media/media_stream_audio_processor.h +++ b/content/renderer/media/media_stream_audio_processor.h
@@ -59,10 +59,10 @@ // processing components like AGC, AEC and NS. It enables the components based // on the getUserMedia constraints, processes the data and outputs it in a unit // of 10 ms data chunk. -class CONTENT_EXPORT MediaStreamAudioProcessor : - NON_EXPORTED_BASE(public WebRtcPlayoutDataSource::Sink), - NON_EXPORTED_BASE(public AudioProcessorInterface), - NON_EXPORTED_BASE(public AecDumpMessageFilter::AecDumpDelegate) { +class CONTENT_EXPORT MediaStreamAudioProcessor + : public WebRtcPlayoutDataSource::Sink, + public AudioProcessorInterface, + public AecDumpMessageFilter::AecDumpDelegate { public: // |playout_data_source| is used to register this class as a sink to the // WebRtc playout data for processing AEC. If clients do not enable AEC,
diff --git a/content/renderer/media/media_stream_audio_source.h b/content/renderer/media/media_stream_audio_source.h index 5b8a001..4707421 100644 --- a/content/renderer/media/media_stream_audio_source.h +++ b/content/renderer/media/media_stream_audio_source.h
@@ -56,8 +56,7 @@ // // Regardless of whether ConnectToTrack() succeeds, there will always be a // // MediaStreamAudioTrack instance created. // CHECK(MediaStreamAudioTrack::From(blink_track)); -class CONTENT_EXPORT MediaStreamAudioSource - : NON_EXPORTED_BASE(public MediaStreamSource) { +class CONTENT_EXPORT MediaStreamAudioSource : public MediaStreamSource { public: explicit MediaStreamAudioSource(bool is_local_source); ~MediaStreamAudioSource() override;
diff --git a/content/renderer/media/media_stream_center.h b/content/renderer/media/media_stream_center.h index eb08acd..c5e7402 100644 --- a/content/renderer/media/media_stream_center.h +++ b/content/renderer/media/media_stream_center.h
@@ -23,8 +23,7 @@ namespace content { class PeerConnectionDependencyFactory; -class CONTENT_EXPORT MediaStreamCenter - : NON_EXPORTED_BASE(public blink::WebMediaStreamCenter) { +class CONTENT_EXPORT MediaStreamCenter : public blink::WebMediaStreamCenter { public: // TODO(miu): Remove these constructor args. They are no longer used. // http://crbug.com/577874
diff --git a/content/renderer/media/media_stream_source.h b/content/renderer/media/media_stream_source.h index c476ad7..9a6011a9 100644 --- a/content/renderer/media/media_stream_source.h +++ b/content/renderer/media/media_stream_source.h
@@ -17,7 +17,7 @@ namespace content { class CONTENT_EXPORT MediaStreamSource - : NON_EXPORTED_BASE(public blink::WebMediaStreamSource::ExtraData) { + : public blink::WebMediaStreamSource::ExtraData { public: typedef base::Callback<void(const blink::WebMediaStreamSource& source)> SourceStoppedCallback;
diff --git a/content/renderer/media/media_stream_track.h b/content/renderer/media/media_stream_track.h index 5080d9e71..ae7fc1f 100644 --- a/content/renderer/media/media_stream_track.h +++ b/content/renderer/media/media_stream_track.h
@@ -20,7 +20,7 @@ // It is owned by blink::WebMediaStreamTrack as // blink::WebMediaStreamTrack::ExtraData. class CONTENT_EXPORT MediaStreamTrack - : NON_EXPORTED_BASE(public blink::WebMediaStreamTrack::TrackData) { + : public blink::WebMediaStreamTrack::TrackData { public: explicit MediaStreamTrack(bool is_local_track); ~MediaStreamTrack() override;
diff --git a/content/renderer/media/media_stream_video_renderer_sink.h b/content/renderer/media/media_stream_video_renderer_sink.h index e12bb38..2d57f721 100644 --- a/content/renderer/media/media_stream_video_renderer_sink.h +++ b/content/renderer/media/media_stream_video_renderer_sink.h
@@ -40,8 +40,8 @@ // http://src.chromium.org/viewvc/chrome/trunk/src/content/renderer/media/rtc_vi // deo_decoder_unittest.cc?revision=180591&view=markup class CONTENT_EXPORT MediaStreamVideoRendererSink - : NON_EXPORTED_BASE(public MediaStreamVideoRenderer), - NON_EXPORTED_BASE(public MediaStreamVideoSink) { + : public MediaStreamVideoRenderer, + public MediaStreamVideoSink { public: MediaStreamVideoRendererSink( const blink::WebMediaStreamTrack& video_track,
diff --git a/content/renderer/media/remote_media_stream_impl.cc b/content/renderer/media/remote_media_stream_impl.cc index 3404923b..12730562 100644 --- a/content/renderer/media/remote_media_stream_impl.cc +++ b/content/renderer/media/remote_media_stream_impl.cc
@@ -51,7 +51,7 @@ } // namespace class RemoteMediaStreamImpl::Observer - : NON_EXPORTED_BASE(public webrtc::ObserverInterface), + : public webrtc::ObserverInterface, public base::RefCountedThreadSafe<Observer> { public: Observer(
diff --git a/content/renderer/media/renderer_webaudiodevice_impl.h b/content/renderer/media/renderer_webaudiodevice_impl.h index ecadadcb..b573e2fa 100644 --- a/content/renderer/media/renderer_webaudiodevice_impl.h +++ b/content/renderer/media/renderer_webaudiodevice_impl.h
@@ -28,8 +28,8 @@ namespace content { class CONTENT_EXPORT RendererWebAudioDeviceImpl - : NON_EXPORTED_BASE(public blink::WebAudioDevice), - NON_EXPORTED_BASE(public media::AudioRendererSink::RenderCallback) { + : public blink::WebAudioDevice, + public media::AudioRendererSink::RenderCallback { public: ~RendererWebAudioDeviceImpl() override;
diff --git a/content/renderer/media/renderer_webmediaplayer_delegate.h b/content/renderer/media/renderer_webmediaplayer_delegate.h index 5ccfae4a..d20f2367 100644 --- a/content/renderer/media/renderer_webmediaplayer_delegate.h +++ b/content/renderer/media/renderer_webmediaplayer_delegate.h
@@ -32,7 +32,7 @@ // the MediaPlayerDelegateHost. class CONTENT_EXPORT RendererWebMediaPlayerDelegate : public content::RenderFrameObserver, - public NON_EXPORTED_BASE(WebMediaPlayerDelegate), + public WebMediaPlayerDelegate, public NON_EXPORTED_BASE( base::SupportsWeakPtr<RendererWebMediaPlayerDelegate>) { public:
diff --git a/content/renderer/media/rtc_certificate.h b/content/renderer/media/rtc_certificate.h index 2da1ff0..da68d07 100644 --- a/content/renderer/media/rtc_certificate.h +++ b/content/renderer/media/rtc_certificate.h
@@ -19,8 +19,7 @@ // Chromium's WebRTCCertificate implementation; wraps a rtc::scoped_refptr to an // rtc::RTCCertificate. This abstraction layer is necessary because blink does // not have direct access to WebRTC. -class CONTENT_EXPORT RTCCertificate - : public NON_EXPORTED_BASE(blink::WebRTCCertificate) { +class CONTENT_EXPORT RTCCertificate : public blink::WebRTCCertificate { public: RTCCertificate(const rtc::scoped_refptr<rtc::RTCCertificate>& certificate); ~RTCCertificate() override;
diff --git a/content/renderer/media/rtc_data_channel_handler.h b/content/renderer/media/rtc_data_channel_handler.h index 5bf8ad2c..eb9554a 100644 --- a/content/renderer/media/rtc_data_channel_handler.h +++ b/content/renderer/media/rtc_data_channel_handler.h
@@ -27,7 +27,7 @@ // Callbacks to the webrtc::DataChannelObserver implementation also occur on // the main render thread. class CONTENT_EXPORT RtcDataChannelHandler - : NON_EXPORTED_BASE(public blink::WebRTCDataChannelHandler) { + : public blink::WebRTCDataChannelHandler { public: // This object can* be constructed on libjingle's signaling thread and then // ownership is passed to the UI thread where it's eventually given to WebKit. @@ -70,7 +70,7 @@ class CONTENT_EXPORT Observer : public NON_EXPORTED_BASE( base::RefCountedThreadSafe<RtcDataChannelHandler::Observer>), - public NON_EXPORTED_BASE(webrtc::DataChannelObserver) { + public webrtc::DataChannelObserver { public: Observer(RtcDataChannelHandler* handler, const scoped_refptr<base::SingleThreadTaskRunner>& main_thread,
diff --git a/content/renderer/media/rtc_dtmf_sender_handler.h b/content/renderer/media/rtc_dtmf_sender_handler.h index fe9923a0..2aa7e22d 100644 --- a/content/renderer/media/rtc_dtmf_sender_handler.h +++ b/content/renderer/media/rtc_dtmf_sender_handler.h
@@ -25,7 +25,7 @@ // Callbacks to the webrtc::DtmfSenderObserverInterface implementation also // occur on the main render thread. class CONTENT_EXPORT RtcDtmfSenderHandler - : NON_EXPORTED_BASE(public blink::WebRTCDTMFSenderHandler) { + : public blink::WebRTCDTMFSenderHandler { public: explicit RtcDtmfSenderHandler(webrtc::DtmfSenderInterface* dtmf_sender); ~RtcDtmfSenderHandler() override;
diff --git a/content/renderer/media/rtc_peer_connection_handler.h b/content/renderer/media/rtc_peer_connection_handler.h index 5b7434c..b6a80a5 100644 --- a/content/renderer/media/rtc_peer_connection_handler.h +++ b/content/renderer/media/rtc_peer_connection_handler.h
@@ -46,8 +46,7 @@ class RtcDataChannelHandler; // Mockable wrapper for blink::WebRTCStatsResponse -class CONTENT_EXPORT LocalRTCStatsResponse - : public NON_EXPORTED_BASE(rtc::RefCountInterface) { +class CONTENT_EXPORT LocalRTCStatsResponse : public rtc::RefCountInterface { public: explicit LocalRTCStatsResponse(const blink::WebRTCStatsResponse& impl) : impl_(impl) { @@ -66,8 +65,7 @@ }; // Mockable wrapper for blink::WebRTCStatsRequest -class CONTENT_EXPORT LocalRTCStatsRequest - : public NON_EXPORTED_BASE(rtc::RefCountInterface) { +class CONTENT_EXPORT LocalRTCStatsRequest : public rtc::RefCountInterface { public: explicit LocalRTCStatsRequest(blink::WebRTCStatsRequest impl); // Constructor for testing. @@ -92,7 +90,7 @@ // Callbacks to the webrtc::PeerConnectionObserver implementation also occur on // the main render thread. class CONTENT_EXPORT RTCPeerConnectionHandler - : NON_EXPORTED_BASE(public blink::WebRTCPeerConnectionHandler) { + : public blink::WebRTCPeerConnectionHandler { public: RTCPeerConnectionHandler( blink::WebRTCPeerConnectionHandlerClient* client,
diff --git a/content/renderer/media/speech_recognition_audio_sink.h b/content/renderer/media/speech_recognition_audio_sink.h index a7fa280..b0c0369 100644 --- a/content/renderer/media/speech_recognition_audio_sink.h +++ b/content/renderer/media/speech_recognition_audio_sink.h
@@ -34,8 +34,8 @@ // and notifies it via SyncSocket followed by incrementing the |buffer_index_|. // WebSpeechRecognizer increments the shared buffer index to synchronize. class CONTENT_EXPORT SpeechRecognitionAudioSink - : NON_EXPORTED_BASE(public media::AudioConverter::InputCallback), - NON_EXPORTED_BASE(public MediaStreamAudioSink) { + : public media::AudioConverter::InputCallback, + public MediaStreamAudioSink { public: typedef base::Callback<void()> OnStoppedCB;
diff --git a/content/renderer/media/track_audio_renderer.h b/content/renderer/media/track_audio_renderer.h index 87547107..40666c53 100644 --- a/content/renderer/media/track_audio_renderer.h +++ b/content/renderer/media/track_audio_renderer.h
@@ -50,9 +50,9 @@ // and skip audio to maintain time synchronization between the producer and // consumer. class CONTENT_EXPORT TrackAudioRenderer - : NON_EXPORTED_BASE(public MediaStreamAudioRenderer), - NON_EXPORTED_BASE(public MediaStreamAudioSink), - NON_EXPORTED_BASE(public media::AudioRendererSink::RenderCallback) { + : public MediaStreamAudioRenderer, + public MediaStreamAudioSink, + public media::AudioRendererSink::RenderCallback { public: // Creates a renderer for the given |audio_track|. |playout_render_frame_id| // refers to the RenderFrame that owns this instance (e.g., it contains the
diff --git a/content/renderer/media/user_media_client_impl.h b/content/renderer/media/user_media_client_impl.h index 8b3508f..e3cd054 100644 --- a/content/renderer/media/user_media_client_impl.h +++ b/content/renderer/media/user_media_client_impl.h
@@ -51,7 +51,7 @@ // render thread. class CONTENT_EXPORT UserMediaClientImpl : public RenderFrameObserver, - NON_EXPORTED_BASE(public blink::WebUserMediaClient), + public blink::WebUserMediaClient, public MediaStreamDispatcherEventHandler { public: // |render_frame| and |dependency_factory| must outlive this instance.
diff --git a/content/renderer/media/webaudio_media_stream_source.h b/content/renderer/media/webaudio_media_stream_source.h index 03939ca7..915126a2 100644 --- a/content/renderer/media/webaudio_media_stream_source.h +++ b/content/renderer/media/webaudio_media_stream_source.h
@@ -22,7 +22,7 @@ // MediaStreamAudioTracks. Audio data is transported directly to the tracks in // 10 ms chunks. class WebAudioMediaStreamSource final - : NON_EXPORTED_BASE(public MediaStreamAudioSource), + : public MediaStreamAudioSource, public blink::WebAudioDestinationConsumer { public: explicit WebAudioMediaStreamSource(blink::WebMediaStreamSource* blink_source);
diff --git a/content/renderer/media/webmediaplayer_ms.h b/content/renderer/media/webmediaplayer_ms.h index 07c84c2..d687a18 100644 --- a/content/renderer/media/webmediaplayer_ms.h +++ b/content/renderer/media/webmediaplayer_ms.h
@@ -63,10 +63,10 @@ // blink::WebMediaPlayerClient // WebKit client of this media player object. class CONTENT_EXPORT WebMediaPlayerMS - : public NON_EXPORTED_BASE(MediaStreamObserver), - public NON_EXPORTED_BASE(blink::WebMediaPlayer), - public NON_EXPORTED_BASE(media::WebMediaPlayerDelegate::Observer), - public NON_EXPORTED_BASE(base::SupportsWeakPtr<WebMediaPlayerMS>) { + : public MediaStreamObserver, + public blink::WebMediaPlayer, + public media::WebMediaPlayerDelegate::Observer, + public base::SupportsWeakPtr<WebMediaPlayerMS> { public: // Construct a WebMediaPlayerMS with reference to the client, and // a MediaStreamClient which provides MediaStreamVideoRenderer.
diff --git a/content/renderer/media/webmediaplayer_ms_compositor.h b/content/renderer/media/webmediaplayer_ms_compositor.h index 90cbc53..314a757 100644 --- a/content/renderer/media/webmediaplayer_ms_compositor.h +++ b/content/renderer/media/webmediaplayer_ms_compositor.h
@@ -49,7 +49,7 @@ // Otherwise, WebMediaPlayerMSCompositor will simply store the most recent // frame, and submit it whenever asked by the compositor. class CONTENT_EXPORT WebMediaPlayerMSCompositor - : public NON_EXPORTED_BASE(cc::VideoFrameProvider), + : public cc::VideoFrameProvider, public base::RefCountedThreadSafe<WebMediaPlayerMSCompositor> { public: // This |url| represents the media stream we are rendering. |url| is used to
diff --git a/content/renderer/media/webrtc/peer_connection_dependency_factory.h b/content/renderer/media/webrtc/peer_connection_dependency_factory.h index 049bcc1..743f1ba 100644 --- a/content/renderer/media/webrtc/peer_connection_dependency_factory.h +++ b/content/renderer/media/webrtc/peer_connection_dependency_factory.h
@@ -46,7 +46,7 @@ // Object factory for RTC PeerConnections. class CONTENT_EXPORT PeerConnectionDependencyFactory - : NON_EXPORTED_BASE(base::MessageLoop::DestructionObserver) { + : base::MessageLoop::DestructionObserver { public: PeerConnectionDependencyFactory( P2PSocketDispatcher* p2p_socket_dispatcher);
diff --git a/content/renderer/media/webrtc/peer_connection_remote_audio_source.h b/content/renderer/media/webrtc/peer_connection_remote_audio_source.h index aa4f15d..42484d15 100644 --- a/content/renderer/media/webrtc/peer_connection_remote_audio_source.h +++ b/content/renderer/media/webrtc/peer_connection_remote_audio_source.h
@@ -21,8 +21,7 @@ // PeerConnectionRemoteAudioTrack is a WebRTC specific implementation of an // audio track whose data is sourced from a PeerConnection. -class PeerConnectionRemoteAudioTrack final - : NON_EXPORTED_BASE(public MediaStreamAudioTrack) { +class PeerConnectionRemoteAudioTrack final : public MediaStreamAudioTrack { public: explicit PeerConnectionRemoteAudioTrack( scoped_refptr<webrtc::AudioTrackInterface> track_interface); @@ -54,8 +53,8 @@ // Represents the audio provided by the receiving end of a PeerConnection. class PeerConnectionRemoteAudioSource final - : NON_EXPORTED_BASE(public MediaStreamAudioSource), - NON_EXPORTED_BASE(protected webrtc::AudioTrackSinkInterface) { + : public MediaStreamAudioSource, + protected webrtc::AudioTrackSinkInterface { public: explicit PeerConnectionRemoteAudioSource( scoped_refptr<webrtc::AudioTrackInterface> track_interface);
diff --git a/content/renderer/media/webrtc/processed_local_audio_source.h b/content/renderer/media/webrtc/processed_local_audio_source.h index ad54656..4a6acef 100644 --- a/content/renderer/media/webrtc/processed_local_audio_source.h +++ b/content/renderer/media/webrtc/processed_local_audio_source.h
@@ -32,8 +32,8 @@ // MediaStreamProcessor that modifies its audio. Modified audio is delivered to // one or more MediaStreamAudioTracks. class CONTENT_EXPORT ProcessedLocalAudioSource final - : NON_EXPORTED_BASE(public MediaStreamAudioSource), - NON_EXPORTED_BASE(public media::AudioCapturerSource::CaptureCallback) { + : public MediaStreamAudioSource, + public media::AudioCapturerSource::CaptureCallback { public: // |consumer_render_frame_id| references the RenderFrame that will consume the // audio data. Audio parameters and (optionally) a pre-existing audio session
diff --git a/content/renderer/media/webrtc/track_observer.cc b/content/renderer/media/webrtc/track_observer.cc index 4e552ac..64b611bf 100644 --- a/content/renderer/media/webrtc/track_observer.cc +++ b/content/renderer/media/webrtc/track_observer.cc
@@ -11,7 +11,7 @@ class CONTENT_EXPORT TrackObserver::TrackObserverImpl : public base::RefCountedThreadSafe<TrackObserver::TrackObserverImpl>, - NON_EXPORTED_BASE(public webrtc::ObserverInterface) { + public webrtc::ObserverInterface { public: TrackObserverImpl( const scoped_refptr<base::SingleThreadTaskRunner>& main_thread,
diff --git a/content/renderer/media/webrtc/webrtc_media_stream_adapter.h b/content/renderer/media/webrtc/webrtc_media_stream_adapter.h index 33cd630c..66772c4c 100644 --- a/content/renderer/media/webrtc/webrtc_media_stream_adapter.h +++ b/content/renderer/media/webrtc/webrtc_media_stream_adapter.h
@@ -29,8 +29,7 @@ // added to an RTCPeerConnection object // Instances of this class is owned by the RTCPeerConnectionHandler object that // created it. -class CONTENT_EXPORT WebRtcMediaStreamAdapter - : NON_EXPORTED_BASE(public MediaStreamObserver) { +class CONTENT_EXPORT WebRtcMediaStreamAdapter : public MediaStreamObserver { public: WebRtcMediaStreamAdapter( PeerConnectionDependencyFactory* factory,
diff --git a/content/renderer/media/webrtc/webrtc_video_capturer_adapter.h b/content/renderer/media/webrtc/webrtc_video_capturer_adapter.h index d3f1c7c..4e5c55d 100644 --- a/content/renderer/media/webrtc/webrtc_video_capturer_adapter.h +++ b/content/renderer/media/webrtc/webrtc_video_capturer_adapter.h
@@ -30,7 +30,7 @@ // webrtc::VideoTrackSourceInterface guarantees that this object is not deleted // while it is still used in libJingle. class CONTENT_EXPORT WebRtcVideoCapturerAdapter - : NON_EXPORTED_BASE(public cricket::VideoCapturer) { + : public cricket::VideoCapturer { public: WebRtcVideoCapturerAdapter( bool is_screencast,
diff --git a/content/renderer/media/webrtc_audio_device_impl.h b/content/renderer/media/webrtc_audio_device_impl.h index 1e3f05f1..c2939fa 100644 --- a/content/renderer/media/webrtc_audio_device_impl.h +++ b/content/renderer/media/webrtc_audio_device_impl.h
@@ -250,10 +250,9 @@ // Note that this class inherits from webrtc::AudioDeviceModule but due to // the high number of non-implemented methods, we move the cruft over to the // WebRtcAudioDeviceNotImpl. -class CONTENT_EXPORT WebRtcAudioDeviceImpl - : NON_EXPORTED_BASE(public WebRtcAudioDeviceNotImpl), - NON_EXPORTED_BASE(public WebRtcAudioRendererSource), - NON_EXPORTED_BASE(public WebRtcPlayoutDataSource) { +class CONTENT_EXPORT WebRtcAudioDeviceImpl : public WebRtcAudioDeviceNotImpl, + public WebRtcAudioRendererSource, + public WebRtcPlayoutDataSource { public: // The maximum volume value WebRtc uses. static const int kMaxVolumeLevel = 255;
diff --git a/content/renderer/media/webrtc_audio_device_not_impl.h b/content/renderer/media/webrtc_audio_device_not_impl.h index bff479c..30cf28ec 100644 --- a/content/renderer/media/webrtc_audio_device_not_impl.h +++ b/content/renderer/media/webrtc_audio_device_not_impl.h
@@ -22,7 +22,7 @@ // a separate unit is to make WebRtcAudioDeviceImpl more readable and easier // to maintain. class CONTENT_EXPORT WebRtcAudioDeviceNotImpl - : NON_EXPORTED_BASE(public webrtc::AudioDeviceModule) { + : public webrtc::AudioDeviceModule { public: WebRtcAudioDeviceNotImpl();
diff --git a/content/renderer/media/webrtc_audio_renderer.h b/content/renderer/media/webrtc_audio_renderer.h index c8d99d0..c95ffae4 100644 --- a/content/renderer/media/webrtc_audio_renderer.h +++ b/content/renderer/media/webrtc_audio_renderer.h
@@ -37,8 +37,8 @@ // This renderer handles calls from the pipeline and WebRtc ADM. It is used // for connecting WebRtc MediaStream with the audio pipeline. class CONTENT_EXPORT WebRtcAudioRenderer - : NON_EXPORTED_BASE(public media::AudioRendererSink::RenderCallback), - NON_EXPORTED_BASE(public MediaStreamAudioRenderer) { + : public media::AudioRendererSink::RenderCallback, + public MediaStreamAudioRenderer { public: // This is a little utility class that holds the configured state of an audio // stream.
diff --git a/content/renderer/media/webrtc_local_audio_source_provider.h b/content/renderer/media/webrtc_local_audio_source_provider.h index 1e46460..6917cf2 100644 --- a/content/renderer/media/webrtc_local_audio_source_provider.h +++ b/content/renderer/media/webrtc_local_audio_source_provider.h
@@ -49,9 +49,9 @@ // // All calls are protected by a lock. class CONTENT_EXPORT WebRtcLocalAudioSourceProvider - : NON_EXPORTED_BASE(public blink::WebAudioSourceProvider), - NON_EXPORTED_BASE(public media::AudioConverter::InputCallback), - NON_EXPORTED_BASE(public MediaStreamAudioSink) { + : public blink::WebAudioSourceProvider, + public media::AudioConverter::InputCallback, + public MediaStreamAudioSink { public: static const size_t kWebAudioRenderBufferSize;
diff --git a/content/renderer/media_capture_from_element/canvas_capture_handler.h b/content/renderer/media_capture_from_element/canvas_capture_handler.h index c6ed548..54842659 100644 --- a/content/renderer/media_capture_from_element/canvas_capture_handler.h +++ b/content/renderer/media_capture_from_element/canvas_capture_handler.h
@@ -37,7 +37,7 @@ // i.e. the Main Render thread. Note that a CanvasCaptureHandlerDelegate is // used to send back frames to |io_task_runner_|, i.e. IO thread. class CONTENT_EXPORT CanvasCaptureHandler final - : public NON_EXPORTED_BASE(blink::WebCanvasCaptureHandler) { + : public blink::WebCanvasCaptureHandler { public: ~CanvasCaptureHandler() override;
diff --git a/content/renderer/media_capture_from_element/html_audio_element_capturer_source.h b/content/renderer/media_capture_from_element/html_audio_element_capturer_source.h index 351e18e..fd5e0ad 100644 --- a/content/renderer/media_capture_from_element/html_audio_element_capturer_source.h +++ b/content/renderer/media_capture_from_element/html_audio_element_capturer_source.h
@@ -27,7 +27,7 @@ // intended for rendering. This copied data is received on OnAudioBus() and sent // to all the registered Tracks. class CONTENT_EXPORT HtmlAudioElementCapturerSource final - : NON_EXPORTED_BASE(public MediaStreamAudioSource) { + : public MediaStreamAudioSource { public: static HtmlAudioElementCapturerSource* CreateFromWebMediaPlayerImpl(blink::WebMediaPlayer* player);
diff --git a/content/renderer/media_recorder/audio_track_recorder.h b/content/renderer/media_recorder/audio_track_recorder.h index 1b9554a..6ee2a57 100644 --- a/content/renderer/media_recorder/audio_track_recorder.h +++ b/content/renderer/media_recorder/audio_track_recorder.h
@@ -30,8 +30,7 @@ // the "capture thread"). It owns an internal thread to use for encoding, on // which lives an AudioEncoder (a private nested class of ATR) with its own // threading subtleties, see the implementation file. -class CONTENT_EXPORT AudioTrackRecorder - : NON_EXPORTED_BASE(public MediaStreamAudioSink) { +class CONTENT_EXPORT AudioTrackRecorder : public MediaStreamAudioSink { public: using OnEncodedAudioCB = base::Callback<void(const media::AudioParameters& params,
diff --git a/content/renderer/media_recorder/media_recorder_handler.h b/content/renderer/media_recorder/media_recorder_handler.h index d9affd90e..b24ef92 100644 --- a/content/renderer/media_recorder/media_recorder_handler.h +++ b/content/renderer/media_recorder/media_recorder_handler.h
@@ -43,7 +43,7 @@ // i.e. the Main Render thread. (Note that a BindToCurrentLoop is used to // guarantee this, since VideoTrackRecorder sends back frames on IO thread.) class CONTENT_EXPORT MediaRecorderHandler final - : public NON_EXPORTED_BASE(blink::WebMediaRecorderHandler) { + : public blink::WebMediaRecorderHandler { public: MediaRecorderHandler(); ~MediaRecorderHandler() override;
diff --git a/content/renderer/media_recorder/video_track_recorder.h b/content/renderer/media_recorder/video_track_recorder.h index 9efa4e61..64bc28d 100644 --- a/content/renderer/media_recorder/video_track_recorder.h +++ b/content/renderer/media_recorder/video_track_recorder.h
@@ -49,8 +49,7 @@ // MediaStreamVideo* classes that are constructed/configured on Main Render // thread but that pass frames on Render IO thread. It has an internal Encoder // with its own threading subtleties, see the implementation file. -class CONTENT_EXPORT VideoTrackRecorder - : NON_EXPORTED_BASE(public MediaStreamVideoSink) { +class CONTENT_EXPORT VideoTrackRecorder : public MediaStreamVideoSink { public: // Do not change the order of codecs; add new ones right before LAST. enum class CodecId {
diff --git a/content/renderer/origin_trials/web_trial_token_validator_impl.h b/content/renderer/origin_trials/web_trial_token_validator_impl.h index b67ee6e..ad6890dc 100644 --- a/content/renderer/origin_trials/web_trial_token_validator_impl.h +++ b/content/renderer/origin_trials/web_trial_token_validator_impl.h
@@ -18,7 +18,7 @@ // // This class is thread-safe. class CONTENT_EXPORT WebTrialTokenValidatorImpl - : public NON_EXPORTED_BASE(blink::WebTrialTokenValidator) { + : public blink::WebTrialTokenValidator { public: WebTrialTokenValidatorImpl(); ~WebTrialTokenValidatorImpl() override;
diff --git a/content/renderer/pepper/content_decryptor_delegate.cc b/content/renderer/pepper/content_decryptor_delegate.cc index 4a6bae00..d03c5d3 100644 --- a/content/renderer/pepper/content_decryptor_delegate.cc +++ b/content/renderer/pepper/content_decryptor_delegate.cc
@@ -334,22 +334,16 @@ PP_CdmExceptionCode exception_code) { switch (exception_code) { case PP_CDMEXCEPTIONCODE_NOTSUPPORTEDERROR: - return CdmPromise::NOT_SUPPORTED_ERROR; + return CdmPromise::Exception::NOT_SUPPORTED_ERROR; case PP_CDMEXCEPTIONCODE_INVALIDSTATEERROR: - return CdmPromise::INVALID_STATE_ERROR; - case PP_CDMEXCEPTIONCODE_INVALIDACCESSERROR: - return CdmPromise::INVALID_ACCESS_ERROR; + return CdmPromise::Exception::INVALID_STATE_ERROR; + case PP_CDMEXCEPTIONCODE_TYPEERROR: + return CdmPromise::Exception::TYPE_ERROR; case PP_CDMEXCEPTIONCODE_QUOTAEXCEEDEDERROR: - return CdmPromise::QUOTA_EXCEEDED_ERROR; - case PP_CDMEXCEPTIONCODE_UNKNOWNERROR: - return CdmPromise::UNKNOWN_ERROR; - case PP_CDMEXCEPTIONCODE_CLIENTERROR: - return CdmPromise::CLIENT_ERROR; - case PP_CDMEXCEPTIONCODE_OUTPUTERROR: - return CdmPromise::OUTPUT_ERROR; + return CdmPromise::Exception::QUOTA_EXCEEDED_ERROR; default: NOTREACHED(); - return CdmPromise::UNKNOWN_ERROR; + return CdmPromise::Exception::NOT_SUPPORTED_ERROR; } } @@ -458,7 +452,7 @@ std::unique_ptr<media::SimpleCdmPromise> promise) { if (certificate.size() < media::limits::kMinCertificateLength || certificate.size() > media::limits::kMaxCertificateLength) { - promise->reject(CdmPromise::INVALID_ACCESS_ERROR, 0, + promise->reject(CdmPromise::Exception::TYPE_ERROR, 0, "Incorrect certificate."); return; } @@ -521,7 +515,7 @@ const std::string& session_id, std::unique_ptr<SimpleCdmPromise> promise) { if (session_id.length() > media::limits::kMaxSessionIdLength) { - promise->reject(CdmPromise::INVALID_ACCESS_ERROR, 0, "Incorrect session."); + promise->reject(CdmPromise::Exception::TYPE_ERROR, 0, "Incorrect session."); return; } @@ -534,7 +528,7 @@ const std::string& session_id, std::unique_ptr<SimpleCdmPromise> promise) { if (session_id.length() > media::limits::kMaxSessionIdLength) { - promise->reject(CdmPromise::INVALID_ACCESS_ERROR, 0, "Incorrect session."); + promise->reject(CdmPromise::Exception::TYPE_ERROR, 0, "Incorrect session."); return; }
diff --git a/content/renderer/pepper/pepper_plugin_instance_impl.h b/content/renderer/pepper/pepper_plugin_instance_impl.h index 11e1961d..a5607b72 100644 --- a/content/renderer/pepper/pepper_plugin_instance_impl.h +++ b/content/renderer/pepper/pepper_plugin_instance_impl.h
@@ -126,11 +126,11 @@ // ResourceTracker. class CONTENT_EXPORT PepperPluginInstanceImpl : public base::RefCounted<PepperPluginInstanceImpl>, - public NON_EXPORTED_BASE(PepperPluginInstance), + public PepperPluginInstance, public ppapi::PPB_Instance_Shared, - public NON_EXPORTED_BASE(cc::TextureLayerClient), + public cc::TextureLayerClient, public RenderFrameObserver, - public NON_EXPORTED_BASE(PluginInstanceThrottler::Observer) { + public PluginInstanceThrottler::Observer { public: // Create and return a PepperPluginInstanceImpl object which supports the most // recent version of PPP_Instance possible by querying the given
diff --git a/content/renderer/pepper/pepper_websocket_host.h b/content/renderer/pepper/pepper_websocket_host.h index aded6ab..dfeafcf 100644 --- a/content/renderer/pepper/pepper_websocket_host.h +++ b/content/renderer/pepper/pepper_websocket_host.h
@@ -25,7 +25,7 @@ class CONTENT_EXPORT PepperWebSocketHost : public ppapi::host::ResourceHost, - public NON_EXPORTED_BASE(::blink::WebPepperSocketClient) { + public ::blink::WebPepperSocketClient { public: explicit PepperWebSocketHost(RendererPpapiHost* host, PP_Instance instance,
diff --git a/content/renderer/pepper/ppb_image_data_impl.h b/content/renderer/pepper/ppb_image_data_impl.h index 8b5390c2..682f9a4 100644 --- a/content/renderer/pepper/ppb_image_data_impl.h +++ b/content/renderer/pepper/ppb_image_data_impl.h
@@ -30,7 +30,7 @@ class CONTENT_EXPORT PPB_ImageData_Impl : public ppapi::Resource, public ppapi::PPB_ImageData_Shared, - public NON_EXPORTED_BASE(ppapi::thunk::PPB_ImageData_API) { + public ppapi::thunk::PPB_ImageData_API { public: // We delegate most of our implementation to a back-end class that either uses // a PlatformCanvas (for most trusted stuff) or bare shared memory (for use by
diff --git a/content/renderer/presentation/presentation_connection_proxy.h b/content/renderer/presentation/presentation_connection_proxy.h index 3cd5c81..fa588a4a 100644 --- a/content/renderer/presentation/presentation_connection_proxy.h +++ b/content/renderer/presentation/presentation_connection_proxy.h
@@ -69,8 +69,8 @@ // Instance of this class is created for both offscreen and non offscreen // presentations. class CONTENT_EXPORT PresentationConnectionProxy - : public NON_EXPORTED_BASE(blink::WebPresentationConnectionProxy), - public NON_EXPORTED_BASE(blink::mojom::PresentationConnection) { + : public blink::WebPresentationConnectionProxy, + public blink::mojom::PresentationConnection { public: using OnMessageCallback = base::OnceCallback<void(bool)>;
diff --git a/content/renderer/presentation/presentation_dispatcher.h b/content/renderer/presentation/presentation_dispatcher.h index 7eb4c0d9..8288d29 100644 --- a/content/renderer/presentation/presentation_dispatcher.h +++ b/content/renderer/presentation/presentation_dispatcher.h
@@ -41,8 +41,8 @@ // Blink. It forwards the calls to the Mojo PresentationService. class CONTENT_EXPORT PresentationDispatcher : public RenderFrameObserver, - public NON_EXPORTED_BASE(blink::WebPresentationClient), - public NON_EXPORTED_BASE(blink::mojom::PresentationServiceClient) { + public blink::WebPresentationClient, + public blink::mojom::PresentationServiceClient { public: explicit PresentationDispatcher(RenderFrame* render_frame); ~PresentationDispatcher() override;
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h index 8b5770dd..862c0e9 100644 --- a/content/renderer/render_frame_impl.h +++ b/content/renderer/render_frame_impl.h
@@ -176,14 +176,14 @@ class CONTENT_EXPORT RenderFrameImpl : public RenderFrame, - NON_EXPORTED_BASE(blink::mojom::EngagementClient), - NON_EXPORTED_BASE(blink::mojom::MediaEngagementClient), - NON_EXPORTED_BASE(mojom::Frame), - NON_EXPORTED_BASE(mojom::HostZoom), - NON_EXPORTED_BASE(mojom::FrameBindingsControl), - NON_EXPORTED_BASE(public blink::WebFrameClient), - NON_EXPORTED_BASE(public blink::WebFrameSerializerClient), - NON_EXPORTED_BASE(service_manager::mojom::InterfaceProvider) { + blink::mojom::EngagementClient, + blink::mojom::MediaEngagementClient, + mojom::Frame, + mojom::HostZoom, + mojom::FrameBindingsControl, + public blink::WebFrameClient, + public blink::WebFrameSerializerClient, + service_manager::mojom::InterfaceProvider { public: // Creates a new RenderFrame as the main frame of |render_view|. static RenderFrameImpl* CreateMainFrame(
diff --git a/content/renderer/render_frame_proxy.h b/content/renderer/render_frame_proxy.h index d6dc03c9..cbde0285 100644 --- a/content/renderer/render_frame_proxy.h +++ b/content/renderer/render_frame_proxy.h
@@ -56,10 +56,9 @@ // RenderFrameProxy will be deleted when the node in the frame tree is deleted // or when navigating the frame causes it to return to this process and a new // RenderFrame is created for it. -class CONTENT_EXPORT RenderFrameProxy - : public IPC::Listener, - public IPC::Sender, - NON_EXPORTED_BASE(public blink::WebRemoteFrameClient) { +class CONTENT_EXPORT RenderFrameProxy : public IPC::Listener, + public IPC::Sender, + public blink::WebRemoteFrameClient { public: // This method should be used to create a RenderFrameProxy, which will replace // an existing RenderFrame during its cross-process navigation from the
diff --git a/content/renderer/render_thread_impl.h b/content/renderer/render_thread_impl.h index 71992eb..cfab7ab 100644 --- a/content/renderer/render_thread_impl.h +++ b/content/renderer/render_thread_impl.h
@@ -174,8 +174,8 @@ public blink::scheduler::RendererScheduler::RAILModeObserver, public ChildMemoryCoordinatorDelegate, public base::MemoryCoordinatorClient, - NON_EXPORTED_BASE(public mojom::Renderer), - NON_EXPORTED_BASE(public CompositorDependencies) { + public mojom::Renderer, + public CompositorDependencies { public: static RenderThreadImpl* Create(const InProcessChildThreadParams& params); static RenderThreadImpl* Create(
diff --git a/content/renderer/render_view_impl.h b/content/renderer/render_view_impl.h index e833192..8db41974 100644 --- a/content/renderer/render_view_impl.h +++ b/content/renderer/render_view_impl.h
@@ -111,11 +111,10 @@ // // For context, please see https://crbug.com/467770 and // http://www.chromium.org/developers/design-documents/site-isolation. -class CONTENT_EXPORT RenderViewImpl - : public RenderWidget, - NON_EXPORTED_BASE(public blink::WebViewClient), - public RenderWidgetOwnerDelegate, - public RenderView { +class CONTENT_EXPORT RenderViewImpl : public RenderWidget, + public blink::WebViewClient, + public RenderWidgetOwnerDelegate, + public RenderView { public: // Creates a new RenderView. Note that if the original opener has been closed, // |params.window_was_created_with_opener| will be true and
diff --git a/content/renderer/render_widget.h b/content/renderer/render_widget.h index 3785f02..9fb118ec 100644 --- a/content/renderer/render_widget.h +++ b/content/renderer/render_widget.h
@@ -131,7 +131,7 @@ class CONTENT_EXPORT RenderWidget : public IPC::Listener, public IPC::Sender, - NON_EXPORTED_BASE(virtual public blink::WebWidgetClient), + virtual public blink::WebWidgetClient, public mojom::Widget, public RenderWidgetCompositorDelegate, public RenderWidgetInputHandlerDelegate,
diff --git a/content/renderer/renderer_blink_platform_impl.cc b/content/renderer/renderer_blink_platform_impl.cc index ffb43607..3e17f8e1 100644 --- a/content/renderer/renderer_blink_platform_impl.cc +++ b/content/renderer/renderer_blink_platform_impl.cc
@@ -1179,14 +1179,8 @@ thread = NULL; switch (type) { - case blink::kWebPlatformEventTypeDeviceMotion: { - blink::WebLocalFrame* const web_frame = - blink::WebLocalFrame::FrameForCurrentContext(); - RenderFrame* const render_frame = RenderFrame::FromWebFrame(web_frame); - if (!render_frame) - return nullptr; - return base::MakeUnique<DeviceMotionEventPump>(thread, render_frame); - } + case blink::kWebPlatformEventTypeDeviceMotion: + return base::MakeUnique<DeviceMotionEventPump>(thread); case blink::kWebPlatformEventTypeDeviceOrientation: return base::MakeUnique<DeviceOrientationEventPump>(thread); case blink::kWebPlatformEventTypeDeviceOrientationAbsolute:
diff --git a/content/renderer/renderer_main_platform_delegate_mac.mm b/content/renderer/renderer_main_platform_delegate_mac.mm index c4d1da8d..3d828fc 100644 --- a/content/renderer/renderer_main_platform_delegate_mac.mm +++ b/content/renderer/renderer_main_platform_delegate_mac.mm
@@ -25,6 +25,9 @@ void CGSSetDenyWindowServerConnections(bool); void CGSShutdownServerConnections(); OSStatus SetApplicationIsDaemon(Boolean isDaemon); +void _LSSetApplicationLaunchServicesServerConnectionStatus( + uint64_t flags, + bool (^connection_allowed)(CFDictionaryRef)); }; namespace content { @@ -45,6 +48,8 @@ // launchservicesd to get an ASN. By setting this flag, HIServices skips // that. SetApplicationIsDaemon(true); + // Tell LaunchServices to continue without a connection to the daemon. + _LSSetApplicationLaunchServicesServerConnectionStatus(0, nullptr); } // You are about to read a pretty disgusting hack. In a static initializer,
diff --git a/content/renderer/screen_orientation/screen_orientation_dispatcher.h b/content/renderer/screen_orientation/screen_orientation_dispatcher.h index ab23b89f..7c334dff 100644 --- a/content/renderer/screen_orientation/screen_orientation_dispatcher.h +++ b/content/renderer/screen_orientation/screen_orientation_dispatcher.h
@@ -29,9 +29,9 @@ // which handles screen lock. It sends lock (or unlock) requests to the browser // process and listens for responses and let Blink know about the result of the // request via WebLockOrientationCallback. -class CONTENT_EXPORT ScreenOrientationDispatcher : - public RenderFrameObserver, - NON_EXPORTED_BASE(public blink::WebScreenOrientationClient) { +class CONTENT_EXPORT ScreenOrientationDispatcher + : public RenderFrameObserver, + public blink::WebScreenOrientationClient { public: explicit ScreenOrientationDispatcher(RenderFrame* render_frame); ~ScreenOrientationDispatcher() override;
diff --git a/content/renderer/service_worker/embedded_worker_instance_client_impl.cc b/content/renderer/service_worker/embedded_worker_instance_client_impl.cc index 7ecea8a5..69d3ed3c 100644 --- a/content/renderer/service_worker/embedded_worker_instance_client_impl.cc +++ b/content/renderer/service_worker/embedded_worker_instance_client_impl.cc
@@ -109,7 +109,7 @@ : binding_(this, std::move(request)), temporal_self_(this), io_thread_runner_(std::move(io_thread_runner)) { - binding_.set_connection_error_handler(base::Bind( + binding_.set_connection_error_handler(base::BindOnce( &EmbeddedWorkerInstanceClientImpl::OnError, base::Unretained(this))); }
diff --git a/content/renderer/service_worker/service_worker_context_client.cc b/content/renderer/service_worker/service_worker_context_client.cc index d875f68..fa3465f5 100644 --- a/content/renderer/service_worker/service_worker_context_client.cc +++ b/content/renderer/service_worker/service_worker_context_client.cc
@@ -788,8 +788,8 @@ // so that at the time we send it we can be sure that the // worker run loop has been started. worker_task_runner_->PostTask( - FROM_HERE, base::Bind(&ServiceWorkerContextClient::SendWorkerStarted, - GetWeakPtr())); + FROM_HERE, base::BindOnce(&ServiceWorkerContextClient::SendWorkerStarted, + GetWeakPtr())); TRACE_EVENT_NESTABLE_ASYNC_END1("ServiceWorker", "EVALUATE_SCRIPT", this, "Status", success ? "Success" : "Failure"); @@ -859,8 +859,8 @@ DCHECK(embedded_worker_client_); main_thread_task_runner_->PostTask( FROM_HERE, - base::Bind(&EmbeddedWorkerInstanceClientImpl::WorkerContextDestroyed, - base::Passed(&embedded_worker_client_))); + base::BindOnce(&EmbeddedWorkerInstanceClientImpl::WorkerContextDestroyed, + base::Passed(&embedded_worker_client_))); return; }
diff --git a/content/renderer/service_worker/web_service_worker_installed_scripts_manager_impl.h b/content/renderer/service_worker/web_service_worker_installed_scripts_manager_impl.h index e86d8c2..b22a338 100644 --- a/content/renderer/service_worker/web_service_worker_installed_scripts_manager_impl.h +++ b/content/renderer/service_worker/web_service_worker_installed_scripts_manager_impl.h
@@ -15,7 +15,7 @@ namespace content { class CONTENT_EXPORT WebServiceWorkerInstalledScriptsManagerImpl final - : NON_EXPORTED_BASE(public blink::WebServiceWorkerInstalledScriptsManager) { + : public blink::WebServiceWorkerInstalledScriptsManager { public: // Called on the main thread. static std::unique_ptr<blink::WebServiceWorkerInstalledScriptsManager> Create(
diff --git a/content/renderer/service_worker/web_service_worker_installed_scripts_manager_impl_unittest.cc b/content/renderer/service_worker/web_service_worker_installed_scripts_manager_impl_unittest.cc index 444b6012..1a4507e 100644 --- a/content/renderer/service_worker/web_service_worker_installed_scripts_manager_impl_unittest.cc +++ b/content/renderer/service_worker/web_service_worker_installed_scripts_manager_impl_unittest.cc
@@ -120,7 +120,7 @@ bool* out_installed) { worker_task_runner_->PostTask( FROM_HERE, - base::Bind( + base::BindOnce( [](blink::WebServiceWorkerInstalledScriptsManager* installed_scripts_manager, const blink::WebURL& script_url, bool* out_installed, @@ -139,7 +139,7 @@ std::unique_ptr<RawScriptData>* out_data) { worker_task_runner_->PostTask( FROM_HERE, - base::Bind( + base::BindOnce( [](blink::WebServiceWorkerInstalledScriptsManager* installed_scripts_manager, const blink::WebURL& script_url,
diff --git a/content/renderer/webgraphicscontext3d_provider_impl.h b/content/renderer/webgraphicscontext3d_provider_impl.h index 6855b25..d143876 100644 --- a/content/renderer/webgraphicscontext3d_provider_impl.h +++ b/content/renderer/webgraphicscontext3d_provider_impl.h
@@ -23,7 +23,7 @@ namespace content { class CONTENT_EXPORT WebGraphicsContext3DProviderImpl - : public NON_EXPORTED_BASE(blink::WebGraphicsContext3DProvider) { + : public blink::WebGraphicsContext3DProvider { public: explicit WebGraphicsContext3DProviderImpl( scoped_refptr<ui::ContextProviderCommandBuffer> provider,
diff --git a/content/shell/test_runner/app_banner_service.h b/content/shell/test_runner/app_banner_service.h index 9e040d7..c9b47806 100644 --- a/content/shell/test_runner/app_banner_service.h +++ b/content/shell/test_runner/app_banner_service.h
@@ -19,7 +19,7 @@ // Test app banner service that is registered as a Mojo service for // BeforeInstallPromptEvents to look up when the test runner is executed. class TEST_RUNNER_EXPORT AppBannerService - : public NON_EXPORTED_BASE(blink::mojom::AppBannerService) { + : public blink::mojom::AppBannerService { public: AppBannerService(); ~AppBannerService() override;
diff --git a/content/shell/test_runner/mock_screen_orientation_client.h b/content/shell/test_runner/mock_screen_orientation_client.h index 8a0e678..726c814 100644 --- a/content/shell/test_runner/mock_screen_orientation_client.h +++ b/content/shell/test_runner/mock_screen_orientation_client.h
@@ -22,7 +22,7 @@ namespace test_runner { class TEST_RUNNER_EXPORT MockScreenOrientationClient - : public NON_EXPORTED_BASE(blink::WebScreenOrientationClient) { + : public blink::WebScreenOrientationClient { public: explicit MockScreenOrientationClient(); ~MockScreenOrientationClient() override;
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index dadb9dc..85cfef0a 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -1608,7 +1608,6 @@ "//ppapi/features", "//printing", "//services/catalog:lib", - "//services/device/public/cpp/generic_sensor", "//services/file:lib", "//services/file/public/interfaces", "//services/metrics/public/interfaces",
diff --git a/content/test/DEPS b/content/test/DEPS index 077a69d..9be8a4dc 100644 --- a/content/test/DEPS +++ b/content/test/DEPS
@@ -20,7 +20,6 @@ # For loading V8's initial snapshot from external files. "+gin/v8_initializer.h", "+services/catalog", - "+services/device/generic_sensor/public/cpp", "+ui/base/resource/data_pack.h", "+ui/base/resource/resource_bundle.h", "!v8/include/v8.h",
diff --git a/content/test/data/device_sensors/device_motion_only_some_sensors_are_available_test.html b/content/test/data/device_sensors/device_motion_only_some_sensors_are_available_test.html deleted file mode 100644 index b0286e7..0000000 --- a/content/test/data/device_sensors/device_motion_only_some_sensors_are_available_test.html +++ /dev/null
@@ -1,41 +0,0 @@ -<html> - <head> - <title>DeviceMotion only some sensors are available test</title> - <script type="text/javascript"> - let expectedInterval = Math.floor(1000 / 60); - function checkMotionEvent(event) { - return event.acceleration.x == 1 && - event.acceleration.y == 2 && - event.acceleration.z == 3 && - event.accelerationIncludingGravity.x == null && - event.accelerationIncludingGravity.y == null && - event.accelerationIncludingGravity.z == null && - event.rotationRate.alpha == 7 && - event.rotationRate.beta == 8 && - event.rotationRate.gamma == 9 && - event.interval == expectedInterval; - } - - function onMotion(event) { - if (checkMotionEvent(event)) { - window.removeEventListener('devicemotion', onMotion); - pass(); - } else { - fail(); - } - } - - function pass() { - document.getElementById('status').innerHTML = 'PASS'; - document.location = '#pass'; - } - - function fail() { - document.location = '#fail'; - } - </script> - </head> - <body onLoad="window.addEventListener('devicemotion', onMotion)"> - <div id="status">FAIL</div> - </body> -</html>
diff --git a/content/test/data/device_sensors/device_motion_test.html b/content/test/data/device_sensors/device_motion_test.html index e98aa40..11b4e05 100644 --- a/content/test/data/device_sensors/device_motion_test.html +++ b/content/test/data/device_sensors/device_motion_test.html
@@ -2,7 +2,6 @@ <head> <title>DeviceMotion test</title> <script type="text/javascript"> - let expectedInterval = Math.floor(1000 / 60); function checkMotionEvent(event) { return event.acceleration.x == 1 && event.acceleration.y == 2 && @@ -13,7 +12,7 @@ event.rotationRate.alpha == 7 && event.rotationRate.beta == 8 && event.rotationRate.gamma == 9 && - event.interval == expectedInterval; + event.interval == 100; } function onMotion(event) {
diff --git a/content/test/test_render_view_host.h b/content/test/test_render_view_host.h index 1aa6354..66c0710d 100644 --- a/content/test/test_render_view_host.h +++ b/content/test/test_render_view_host.h
@@ -61,9 +61,8 @@ // Subclass the RenderViewHost's view so that we can call Show(), etc., // without having side-effects. -class TestRenderWidgetHostView - : public RenderWidgetHostViewBase, - public NON_EXPORTED_BASE(viz::HostFrameSinkClient) { +class TestRenderWidgetHostView : public RenderWidgetHostViewBase, + public viz::HostFrameSinkClient { public: explicit TestRenderWidgetHostView(RenderWidgetHost* rwh); ~TestRenderWidgetHostView() override;
diff --git a/device/bluetooth/test/fake_bluetooth.h b/device/bluetooth/test/fake_bluetooth.h index 7f177b3..544e25f 100644 --- a/device/bluetooth/test/fake_bluetooth.h +++ b/device/bluetooth/test/fake_bluetooth.h
@@ -17,7 +17,7 @@ // src/device/bluetooth/public/interfaces/test/fake_bluetooth.mojom. // Implemented on top of the C++ device/bluetooth API, mainly // device/bluetooth/bluetooth_adapter_factory.h. -class FakeBluetooth : NON_EXPORTED_BASE(public mojom::FakeBluetooth) { +class FakeBluetooth : public mojom::FakeBluetooth { public: FakeBluetooth(); ~FakeBluetooth() override;
diff --git a/device/bluetooth/test/fake_central.h b/device/bluetooth/test/fake_central.h index 5aa27f22..bc2e700 100644 --- a/device/bluetooth/test/fake_central.h +++ b/device/bluetooth/test/fake_central.h
@@ -24,8 +24,7 @@ // src/device/bluetooth/public/interfaces/test/fake_bluetooth.mojom. // Implemented on top of the C++ device/bluetooth API, mainly // device/bluetooth/bluetooth_adapter.h. -class FakeCentral : NON_EXPORTED_BASE(public mojom::FakeCentral), - public device::BluetoothAdapter { +class FakeCentral : public mojom::FakeCentral, public device::BluetoothAdapter { public: FakeCentral(mojom::CentralState state, mojom::FakeCentralRequest request);
diff --git a/device/gamepad/gamepad_monitor.h b/device/gamepad/gamepad_monitor.h index eab2fa08..b043474a 100644 --- a/device/gamepad/gamepad_monitor.h +++ b/device/gamepad/gamepad_monitor.h
@@ -13,9 +13,8 @@ namespace device { -class DEVICE_GAMEPAD_EXPORT GamepadMonitor - : public GamepadConsumer, - NON_EXPORTED_BASE(public mojom::GamepadMonitor) { +class DEVICE_GAMEPAD_EXPORT GamepadMonitor : public GamepadConsumer, + public mojom::GamepadMonitor { public: GamepadMonitor(); ~GamepadMonitor() override;
diff --git a/device/geolocation/geolocation_config.h b/device/geolocation/geolocation_config.h index 586ce46..5c00ee7a 100644 --- a/device/geolocation/geolocation_config.h +++ b/device/geolocation/geolocation_config.h
@@ -19,7 +19,7 @@ // Implements the GeolocationConfig Mojo interface. class DEVICE_GEOLOCATION_EXPORT GeolocationConfig - : public NON_EXPORTED_BASE(mojom::GeolocationConfig) { + : public mojom::GeolocationConfig { public: GeolocationConfig(); ~GeolocationConfig() override;
diff --git a/device/geolocation/geolocation_provider_impl.h b/device/geolocation/geolocation_provider_impl.h index 4f9c4da..2d1bf56 100644 --- a/device/geolocation/geolocation_provider_impl.h +++ b/device/geolocation/geolocation_provider_impl.h
@@ -27,7 +27,7 @@ namespace device { class DEVICE_GEOLOCATION_EXPORT GeolocationProviderImpl - : public NON_EXPORTED_BASE(GeolocationProvider), + : public GeolocationProvider, public base::Thread { public: // GeolocationProvider implementation:
diff --git a/device/sensors/device_sensor_host.h b/device/sensors/device_sensor_host.h index d6d5493..fd4fe3ac 100644 --- a/device/sensors/device_sensor_host.h +++ b/device/sensors/device_sensor_host.h
@@ -17,7 +17,7 @@ // A base class for device sensor related mojo interface implementations. template <typename MojoInterface, ConsumerType consumer_type> -class DeviceSensorHost : NON_EXPORTED_BASE(public MojoInterface) { +class DeviceSensorHost : public MojoInterface { public: static void Create(mojo::InterfaceRequest<MojoInterface> request);
diff --git a/docs/component_build.md b/docs/component_build.md index 650cd83..13fdb10 100644 --- a/docs/component_build.md +++ b/docs/component_build.md
@@ -136,7 +136,7 @@ For example: ```c++ -class YourClass : public NON_EXPORTED_BASE(Base) { ... }; +class YourClass : public Base { ... }; ``` ## Creating components from multiple targets
diff --git a/docs/fuchsia_sdk_updates.md b/docs/fuchsia_sdk_updates.md index a3bda8b..ecda30db 100644 --- a/docs/fuchsia_sdk_updates.md +++ b/docs/fuchsia_sdk_updates.md
@@ -9,6 +9,6 @@ 0. Upload the roll CL, making sure to include the `fuchsia` trybot. Tag the roll with `Bug: 707030`. -(Old revisions of this document have the old manual steps for building a Fuchsia -SDK if for some reason you want to do that locally. They'll probably -increasingly go out of date as the steps for building the SDK changes though.) +If you would like to build an SDK locally, `tools/fuchsia/local-sdk.py` tries to +do this (so you can iterate on ToT Fuchsia against your Chromium build), however +it's simply a copy of the steps run on the bot above, and so may be out of date.
diff --git a/docs/speed/perf_regression_sheriffing.md b/docs/speed/perf_regression_sheriffing.md index 05d791490..d502d8c 100644 --- a/docs/speed/perf_regression_sheriffing.md +++ b/docs/speed/perf_regression_sheriffing.md
@@ -62,8 +62,7 @@ and press the triage button. * If one of the alerts already has a bug id, click "existing bug" and use that bug id. - * Otherwise click "new bug". Be sure to cc the - [test owner](http://go/perf-owners) on the bug. + * Otherwise click "new bug". 5. **Look at the revision range** for the regression. You can see it in the tooltip on the graph. If you see any likely culprits, cc the authors on the bug.
diff --git a/extensions/browser/api/declarative_net_request/flat_ruleset_indexer.cc b/extensions/browser/api/declarative_net_request/flat_ruleset_indexer.cc index 181ef5f..f42e63e4 100644 --- a/extensions/browser/api/declarative_net_request/flat_ruleset_indexer.cc +++ b/extensions/browser/api/declarative_net_request/flat_ruleset_indexer.cc
@@ -47,7 +47,7 @@ } if (!indexed_rule.redirect_url.empty()) return dnr_api::RULE_ACTION_TYPE_REDIRECT; - return dnr_api::RULE_ACTION_TYPE_BLOCK; + return dnr_api::RULE_ACTION_TYPE_BLACKLIST; } } // namespace @@ -118,7 +118,7 @@ FlatRulesetIndexer::UrlPatternIndexBuilder* FlatRulesetIndexer::GetBuilder( dnr_api::RuleActionType type) { switch (type) { - case dnr_api::RULE_ACTION_TYPE_BLOCK: + case dnr_api::RULE_ACTION_TYPE_BLACKLIST: return &blacklist_index_builder_; case dnr_api::RULE_ACTION_TYPE_WHITELIST: return &whitelist_index_builder_;
diff --git a/extensions/browser/api/declarative_net_request/indexed_rule_unittest.cc b/extensions/browser/api/declarative_net_request/indexed_rule_unittest.cc index 651b6cb..d4d8e7dc 100644 --- a/extensions/browser/api/declarative_net_request/indexed_rule_unittest.cc +++ b/extensions/browser/api/declarative_net_request/indexed_rule_unittest.cc
@@ -29,7 +29,7 @@ auto rule = base::MakeUnique<dnr_api::Rule>(); rule->id = kMinValidID; rule->condition.url_filter = base::MakeUnique<std::string>("filter"); - rule->action.type = dnr_api::RULE_ACTION_TYPE_BLOCK; + rule->action.type = dnr_api::RULE_ACTION_TYPE_BLACKLIST; return rule; } @@ -120,7 +120,7 @@ std::unique_ptr<bool> is_url_filter_case_sensitive; const uint8_t expected_options; } cases[] = { - {dnr_api::DOMAIN_TYPE_NONE, dnr_api::RULE_ACTION_TYPE_BLOCK, nullptr, + {dnr_api::DOMAIN_TYPE_NONE, dnr_api::RULE_ACTION_TYPE_BLACKLIST, nullptr, flat_rule::OptionFlag_APPLIES_TO_THIRD_PARTY | flat_rule::OptionFlag_APPLIES_TO_FIRST_PARTY}, {dnr_api::DOMAIN_TYPE_FIRSTPARTY, dnr_api::RULE_ACTION_TYPE_WHITELIST,
diff --git a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.cc b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.cc index 38d3544a..6f2b56d0 100644 --- a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.cc +++ b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.cc
@@ -195,6 +195,10 @@ return false; } +bool MimeHandlerViewGuest::ShouldDestroyOnDetach() const { + return true; +} + WebContents* MimeHandlerViewGuest::OpenURLFromTab( WebContents* source, const content::OpenURLParams& params) {
diff --git a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h index 5c919a772..df25eca4 100644 --- a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h +++ b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h
@@ -87,6 +87,7 @@ void DidAttachToEmbedder() override; void DidInitialize(const base::DictionaryValue& create_params) final; bool ZoomPropagatesFromEmbedderToGuest() const final; + bool ShouldDestroyOnDetach() const final; // WebContentsDelegate implementation. content::WebContents* OpenURLFromTab(
diff --git a/extensions/common/api/_api_features.json b/extensions/common/api/_api_features.json index 8f00335d..82d3751 100644 --- a/extensions/common/api/_api_features.json +++ b/extensions/common/api/_api_features.json
@@ -332,6 +332,7 @@ "matches": [ "chrome://network/*", "chrome://oobe/*", + "chrome://proxy-settings/*", "chrome://settings/*" ] }],
diff --git a/extensions/common/api/_manifest_features.json b/extensions/common/api/_manifest_features.json index 03d06b9c..aa29ae67 100644 --- a/extensions/common/api/_manifest_features.json +++ b/extensions/common/api/_manifest_features.json
@@ -28,12 +28,12 @@ "whitelist": [ // Keep this list in sync with extensions_misc::kHangoutsExtensionIds but // omit the Packaged App ids. - "nckgahadagoaajjgafhacjanaoiihapd", // Hangouts Production. - "ljclpkphhpbpinifbeabbhlfddcpfdde", // Hangouts Debug. - "ppleadejekpmccmnpjdimmlfljlkdfej", // Hangouts Alpha. - "eggnbpckecmjlblplehfpjjdhhidfdoj", // Hangouts Beta. + "53041A2FA309EECED01FFC751E7399186E860B2C", // Hangouts Production. + "312745D9BF916161191143F6490085EEA0434997", // Hangouts Debug. + "E7E2461CE072DF036CF9592740196159E2D7C089", // Hangouts Alpha. + "A74A4D44C7CFCD8844830E6140C8D763E12DD8F3", // Hangouts Beta. - "lphgohfeebnhcpiohjndkgbhhkoapkjc" // Apps Debugger + "5107DE9024C329EEA9C9A72D94C16723790C6422" // Apps Debugger ] }, "app.background": { @@ -229,20 +229,20 @@ "channel": "stable", "extension_types": [ "extension", "legacy_packaged_app", "platform_app" ], "whitelist": [ - "oickdpebdnfbgkcaoklfcdhjniefkcji", // browser_tests - "gbkeegbaiigmenfmjfclcdgdpimamgkj", // QuickOffice - "ionpfmkccalenbmnddpbmocokhaknphg", // QuickOffice Dev - "bpmcpldpdmajfigpchkicefoigmkfalc", // Quickoffice component extension - "ehibbfinohgbchlgdbfpikodjaojhccn", // Editor - "mhjfbmdgcfjbbpaeojofohoefgiehjai" // PDF + "787000072C6FBB934AF5A42275CDE73FC977D995", // browser_tests + "2FC374607C2DF285634B67C64A2E356C607091C3", // QuickOffice + "5D3851BEFF680AB6D954B76678EFCCE834465C23", // QuickOffice Dev + "12E618C3C6E97495AAECF2AC12DEB082353241C6", // Quickoffice component extension + "3727DD3E564B6055387425027AD74C58784ACC15", // Editor + "CBCC42ABED43A4B58FE3810E62AFFA010EB0349F" // PDF ] }, "mime_types_handler": { "channel": "stable", "extension_types": [ "extension", "legacy_packaged_app", "platform_app" ], "whitelist": [ - "oickdpebdnfbgkcaoklfcdhjniefkcji", // browser_tests - "mhjfbmdgcfjbbpaeojofohoefgiehjai" // PDF + "787000072C6FBB934AF5A42275CDE73FC977D995", // browser_tests + "CBCC42ABED43A4B58FE3810E62AFFA010EB0349F" // PDF ] }, "nacl_modules": { @@ -267,9 +267,9 @@ "extension", "platform_app" ], "whitelist": [ - "mdbihdcgjmagbcapkhhkjbbdlkflmbfo", // unit_tests - "pafkbggdmjlpgkdkcbjmhmfcdpncadgh", // Google Now - "nmmhkkegccagdldgiimedpiccmgmieda", // In-app payments support app. + "F57FDBA2822F21B82A4C417405ABC51241CC6426", // unit_tests + "C41AD9DCD670210295614257EF8C9945AD68D86E", // Google Now + "64291898C201DAF15B090EC4B9EC270BEB6BE6FF", // In-app payments support app. "4B1D0E19C6C43C008C44A8278C8B5BFE15ABEB3C", "F7FA7ABC1ECB89BA8EE6656847EFABBF43BB9BCA",
diff --git a/extensions/common/api/declarative_net_request.idl b/extensions/common/api/declarative_net_request.idl index 4e0b014..42dc503 100644 --- a/extensions/common/api/declarative_net_request.idl +++ b/extensions/common/api/declarative_net_request.idl
@@ -33,9 +33,8 @@ // Describes the kind of action to take if a given RuleCondition matches. enum RuleActionType { - // TODO(crbug.com/696822): Rename to blacklist. // Block the network request. - block, + blacklist, // Redirect the network request. redirect, // Whitelist the network request. The request won't be blocked even if there @@ -61,7 +60,7 @@ DOMString? urlFilter; // Whether the |urlFilter| is case sensitive. Default is false. - boolean? IsUrlFilterCaseSensitive; + boolean? isUrlFilterCaseSensitive; // The rule will only match network requests originating from the list of // |domains|. If the list is omitted, the rule is applied to requests from
diff --git a/extensions/common/api/networking_onc.idl b/extensions/common/api/networking_onc.idl index 72fcbd7..cee468c 100644 --- a/extensions/common/api/networking_onc.idl +++ b/extensions/common/api/networking_onc.idl
@@ -634,10 +634,14 @@ DOMString? BSSID; // See $(ref:WiFiProperties.Frequency). long? Frequency; + // See $(ref:WiFiProperties.HexSSID). + DOMString? HexSSID; // See $(ref:WiFiProperties.Security). DOMString Security; // See $(ref:WiFiProperties.SignalStrength). long? SignalStrength; + // See $(ref:WiFiProperties.SSID). + DOMString? SSID; }; dictionary WiMAXProperties {
diff --git a/extensions/common/api/networking_private.idl b/extensions/common/api/networking_private.idl index 69caaf5..2ec75df 100644 --- a/extensions/common/api/networking_private.idl +++ b/extensions/common/api/networking_private.idl
@@ -652,8 +652,10 @@ dictionary WiFiStateProperties { DOMString? BSSID; long? Frequency; + DOMString? HexSSID; DOMString Security; long? SignalStrength; + DOMString? SSID; }; dictionary WiMAXProperties {
diff --git a/extensions/renderer/api/mojo_private/mojo_private_unittest.cc b/extensions/renderer/api/mojo_private/mojo_private_unittest.cc index 344cbe9..a1de8d96 100644 --- a/extensions/renderer/api/mojo_private/mojo_private_unittest.cc +++ b/extensions/renderer/api/mojo_private/mojo_private_unittest.cc
@@ -5,6 +5,8 @@ #include "extensions/renderer/api_test_base.h" #include "base/macros.h" +#include "extensions/common/extension_builder.h" +#include "extensions/common/value_builder.h" #include "gin/modules/module_registry.h" // A test launcher for tests for the mojoPrivate API defined in @@ -20,6 +22,20 @@ return gin::ModuleRegistry::From(env()->context()->v8_context()); } + scoped_refptr<const Extension> CreateExtension() override { + std::unique_ptr<base::DictionaryValue> manifest = + DictionaryBuilder() + .Set("name", "test") + .Set("version", "1.0") + .Set("manifest_version", 2) + .Build(); + // Return an extension whitelisted for the mojoPrivate API. + return ExtensionBuilder() + .SetManifest(std::move(manifest)) + .SetID("pkedcjkdefgpdelpbcmbmeomcjbeemfm") + .Build(); + } + private: DISALLOW_COPY_AND_ASSIGN(MojoPrivateApiTest); };
diff --git a/extensions/renderer/module_system_test.cc b/extensions/renderer/module_system_test.cc index c267e46..5883414 100644 --- a/extensions/renderer/module_system_test.cc +++ b/extensions/renderer/module_system_test.cc
@@ -19,8 +19,10 @@ #include "base/memory/ptr_util.h" #include "base/path_service.h" #include "base/strings/string_piece.h" +#include "extensions/common/extension_builder.h" #include "extensions/common/extension_paths.h" #include "extensions/common/feature_switch.h" +#include "extensions/common/value_builder.h" #include "extensions/renderer/ipc_message_sender.h" #include "extensions/renderer/logging_native_handler.h" #include "extensions/renderer/native_extension_bindings_system.h" @@ -122,23 +124,23 @@ ModuleSystemTestEnvironment::ModuleSystemTestEnvironment( v8::Isolate* isolate, - ScriptContextSet* context_set) + ScriptContextSet* context_set, + scoped_refptr<const Extension> extension) : isolate_(isolate), context_holder_(new gin::ContextHolder(isolate_)), handle_scope_(isolate_), + extension_(extension), context_set_(context_set), source_map_(new StringSourceMap()) { context_holder_->SetContext(v8::Context::New( isolate, TestV8ExtensionConfiguration::GetConfiguration())); { - auto context = - base::MakeUnique<ScriptContext>(context_holder_->context(), - nullptr, // WebFrame - nullptr, // Extension - Feature::BLESSED_EXTENSION_CONTEXT, - nullptr, // Effective Extension - Feature::BLESSED_EXTENSION_CONTEXT); + auto context = base::MakeUnique<ScriptContext>( + context_holder_->context(), + nullptr, // WebFrame + extension_.get(), Feature::BLESSED_EXTENSION_CONTEXT, extension_.get(), + Feature::BLESSED_EXTENSION_CONTEXT); context_ = context.get(); context_set_->AddForTesting(std::move(context)); } @@ -242,6 +244,7 @@ } void ModuleSystemTest::SetUp() { + extension_ = CreateExtension(); env_ = CreateEnvironment(); base::CommandLine::ForCurrentProcess()->AppendSwitch("test-type"); } @@ -269,9 +272,20 @@ } } +scoped_refptr<const Extension> ModuleSystemTest::CreateExtension() { + std::unique_ptr<base::DictionaryValue> manifest = + DictionaryBuilder() + .Set("name", "test") + .Set("version", "1.0") + .Set("manifest_version", 2) + .Build(); + return ExtensionBuilder().SetManifest(std::move(manifest)).Build(); +} + std::unique_ptr<ModuleSystemTestEnvironment> ModuleSystemTest::CreateEnvironment() { - return base::MakeUnique<ModuleSystemTestEnvironment>(isolate_, &context_set_); + return base::MakeUnique<ModuleSystemTestEnvironment>(isolate_, &context_set_, + extension_); } void ModuleSystemTest::ExpectNoAssertionsMade() {
diff --git a/extensions/renderer/module_system_test.h b/extensions/renderer/module_system_test.h index b0a2bf21a..4181d04 100644 --- a/extensions/renderer/module_system_test.h +++ b/extensions/renderer/module_system_test.h
@@ -8,6 +8,7 @@ #include <set> #include "base/macros.h" +#include "base/memory/ref_counted.h" #include "base/test/scoped_task_environment.h" #include "extensions/renderer/module_system.h" #include "extensions/renderer/script_context.h" @@ -18,6 +19,7 @@ #include "v8/include/v8.h" namespace extensions { +class Extension; class NativeExtensionBindingsSystem; class StringSourceMap; @@ -26,7 +28,8 @@ class AssertNatives; ModuleSystemTestEnvironment(v8::Isolate* isolate, - ScriptContextSet* context_set); + ScriptContextSet* context_set, + scoped_refptr<const Extension> extension); ~ModuleSystemTestEnvironment(); // Register a named JS module in the module system. @@ -67,6 +70,7 @@ std::unique_ptr<gin::ContextHolder> context_holder_; v8::HandleScope handle_scope_; + scoped_refptr<const Extension> extension_; ScriptContextSet* context_set_; ScriptContext* context_; AssertNatives* assert_natives_; @@ -100,6 +104,10 @@ protected: ModuleSystemTestEnvironment* env() { return env_.get(); } + // Create the extension used with the ModuleSystemTestEnvironment. Virtual so + // that subclasses can return extensions with different features. + virtual scoped_refptr<const Extension> CreateExtension(); + std::unique_ptr<ModuleSystemTestEnvironment> CreateEnvironment(); // Make the test fail if any asserts are called. By default a test will fail @@ -118,6 +126,7 @@ std::set<std::string> extension_ids_; ScriptContextSet context_set_; TestExtensionsRendererClient renderer_client_; + scoped_refptr<const Extension> extension_; std::unique_ptr<ModuleSystemTestEnvironment> env_; bool should_assertions_be_made_;
diff --git a/extensions/renderer/mojo/keep_alive_client_unittest.cc b/extensions/renderer/mojo/keep_alive_client_unittest.cc index 87d38203d..64af454 100644 --- a/extensions/renderer/mojo/keep_alive_client_unittest.cc +++ b/extensions/renderer/mojo/keep_alive_client_unittest.cc
@@ -6,7 +6,9 @@ #include "base/macros.h" #include "base/memory/ptr_util.h" +#include "extensions/common/extension_builder.h" #include "extensions/common/mojo/keep_alive.mojom.h" +#include "extensions/common/value_builder.h" #include "extensions/grit/extensions_renderer_resources.h" #include "extensions/renderer/api_test_base.h" #include "extensions/renderer/string_source_map.h" @@ -79,6 +81,24 @@ env()->source_map()->RegisterModule("serial", kFakeSerialBindings); } + scoped_refptr<const Extension> CreateExtension() override { + // Create a platform app with the serial permission. + DictionaryBuilder background; + background.Set("scripts", ListBuilder().Append("test.js").Build()); + + std::unique_ptr<base::DictionaryValue> manifest = + DictionaryBuilder() + .Set("name", "test") + .Set("version", "1.0") + .Set("app", DictionaryBuilder() + .Set("background", background.Build()) + .Build()) + .Set("permissions", ListBuilder().Append("serial").Build()) + .Set("manifest_version", 2) + .Build(); + return ExtensionBuilder().SetManifest(std::move(manifest)).Build(); + } + void WaitForKeepAlive() { // Wait for a keep-alive to be created and destroyed. while (!created_keep_alive_ || !destroyed_keep_alive_) {
diff --git a/extensions/renderer/native_extension_bindings_system.cc b/extensions/renderer/native_extension_bindings_system.cc index b05c083..516dd69 100644 --- a/extensions/renderer/native_extension_bindings_system.cc +++ b/extensions/renderer/native_extension_bindings_system.cc
@@ -289,9 +289,14 @@ // else use an empty object (so we can still instantiate 'app.runtime'). v8::Local<v8::Object> root_binding; if (lower->first == root_name) { + const Feature* feature = lower->second.get(); if (script_context->IsAnyFeatureAvailableToContext( - *lower->second, CheckAliasStatus::NOT_ALLOWED)) { - root_binding = CreateRootBinding(context, script_context, root_name, + *feature, CheckAliasStatus::NOT_ALLOWED)) { + // If this feature is an alias for a different API, use the other binding + // as the basis for the API contents. + const std::string& source_name = + feature->source().empty() ? root_name : feature->source(); + root_binding = CreateRootBinding(context, script_context, source_name, bindings_system); } ++lower;
diff --git a/extensions/renderer/native_extension_bindings_system_unittest.cc b/extensions/renderer/native_extension_bindings_system_unittest.cc index 972779e..a2c14d3 100644 --- a/extensions/renderer/native_extension_bindings_system_unittest.cc +++ b/extensions/renderer/native_extension_bindings_system_unittest.cc
@@ -37,8 +37,10 @@ PLATFORM_APP, }; -// Creates an extension with the given |name| and |permissions|. -scoped_refptr<Extension> CreateExtension( +// Creates an extension of the given |type| with the given |id| and +// |permissions|. +scoped_refptr<Extension> CreateExtensionWithId( + const std::string& id, const std::string& name, ItemType type, const std::vector<std::string>& permissions) { @@ -66,10 +68,19 @@ return ExtensionBuilder() .SetManifest(manifest.Build()) .SetLocation(Manifest::INTERNAL) - .SetID(crx_file::id_util::GenerateId(name)) + .SetID(id) .Build(); } +// Same as CreateExtensionWithId(), but generates the id from |name|. +scoped_refptr<Extension> CreateExtension( + const std::string& name, + ItemType type, + const std::vector<std::string>& permissions) { + return CreateExtensionWithId(name, crx_file::id_util::GenerateId(name), type, + permissions); +} + class EventChangeHandler { public: MOCK_METHOD5(OnChange, @@ -1119,4 +1130,84 @@ ::testing::Mock::VerifyAndClearExpectations(ipc_message_sender()); } +// Tests that a context having access to an aliased API (like networking.onc) +// does not allow for accessing the source API (networkingPrivate) directly. +TEST_F(NativeExtensionBindingsSystemUnittest, + AccessToAliasSourceDoesntGiveAliasAccess) { + const char kWhitelistedId[] = "pkedcjkdefgpdelpbcmbmeomcjbeemfm"; + scoped_refptr<Extension> extension = CreateExtension( + kWhitelistedId, ItemType::EXTENSION, {"networkingPrivate"}); + RegisterExtension(extension); + + v8::HandleScope handle_scope(isolate()); + v8::Local<v8::Context> context = MainContext(); + ScriptContext* script_context = CreateScriptContext( + context, extension.get(), Feature::BLESSED_EXTENSION_CONTEXT); + + bindings_system()->UpdateBindingsForContext(script_context); + + // The extension only has access to networkingPrivate, so networking.onc + // (and chrome.networking in general) should be undefined. + EXPECT_EQ("object", gin::V8ToString(V8ValueFromScriptSource( + context, "typeof chrome.networkingPrivate"))); + EXPECT_EQ("undefined", gin::V8ToString(V8ValueFromScriptSource( + context, "typeof chrome.networking"))); +} + +// Tests that a context having access to the source for an aliased API does not +// allow for accessing the alias. +TEST_F(NativeExtensionBindingsSystemUnittest, + AccessToAliasDoesntGiveAliasSourceAccess) { + const char kWhitelistedId[] = "pkedcjkdefgpdelpbcmbmeomcjbeemfm"; + scoped_refptr<Extension> extension = + CreateExtension(kWhitelistedId, ItemType::EXTENSION, {"networking.onc"}); + RegisterExtension(extension); + + v8::HandleScope handle_scope(isolate()); + v8::Local<v8::Context> context = MainContext(); + ScriptContext* script_context = CreateScriptContext( + context, extension.get(), Feature::BLESSED_EXTENSION_CONTEXT); + + bindings_system()->UpdateBindingsForContext(script_context); + + // The extension only has access to networking.onc, so networkingPrivate + // should be undefined. + EXPECT_EQ("undefined", gin::V8ToString(V8ValueFromScriptSource( + context, "typeof chrome.networkingPrivate"))); + EXPECT_EQ("object", gin::V8ToString(V8ValueFromScriptSource( + context, "typeof chrome.networking.onc"))); +} + +// Test that if an extension has access to both an alias and an alias source, +// the objects on the API are different. +TEST_F(NativeExtensionBindingsSystemUnittest, AliasedAPIsAreDifferentObjects) { + const char kWhitelistedId[] = "pkedcjkdefgpdelpbcmbmeomcjbeemfm"; + scoped_refptr<Extension> extension = + CreateExtension(kWhitelistedId, ItemType::EXTENSION, + {"networkingPrivate", "networking.onc"}); + RegisterExtension(extension); + + v8::HandleScope handle_scope(isolate()); + v8::Local<v8::Context> context = MainContext(); + ScriptContext* script_context = CreateScriptContext( + context, extension.get(), Feature::BLESSED_EXTENSION_CONTEXT); + + bindings_system()->UpdateBindingsForContext(script_context); + + // Both APIs should be defined, since the extension has access to each. + EXPECT_EQ("object", gin::V8ToString(V8ValueFromScriptSource( + context, "typeof chrome.networkingPrivate"))); + EXPECT_EQ("object", gin::V8ToString(V8ValueFromScriptSource( + context, "typeof chrome.networking.onc"))); + + // The APIs should not be equal. + bool equal = true; + EXPECT_TRUE(gin::ConvertFromV8( + isolate(), + V8ValueFromScriptSource( + context, "chrome.networkingPrivate == chrome.networking.onc"), + &equal)); + EXPECT_FALSE(equal); +} + } // namespace extensions
diff --git a/gin/public/v8_platform.h b/gin/public/v8_platform.h index e86f77d5..616e1b1b 100644 --- a/gin/public/v8_platform.h +++ b/gin/public/v8_platform.h
@@ -14,7 +14,7 @@ namespace gin { // A v8::Platform implementation to use with gin. -class GIN_EXPORT V8Platform : public NON_EXPORTED_BASE(v8::Platform) { +class GIN_EXPORT V8Platform : public v8::Platform { public: static V8Platform* Get();
diff --git a/gin/v8_platform_unittest.cc b/gin/v8_platform_unittest.cc index 3a5abe3..fe12bac 100644 --- a/gin/v8_platform_unittest.cc +++ b/gin/v8_platform_unittest.cc
@@ -8,7 +8,7 @@ #include "testing/gtest/include/gtest/gtest.h" class TestTraceStateObserver - : public NON_EXPORTED_BASE(v8::TracingController::TraceStateObserver) { + : public v8::TracingController::TraceStateObserver { public: void OnTraceEnabled() final { ++enabled_; } void OnTraceDisabled() final { ++disabled_; }
diff --git a/gpu/command_buffer/client/cmd_buffer_helper.cc b/gpu/command_buffer/client/cmd_buffer_helper.cc index afa6c390..759978cc 100644 --- a/gpu/command_buffer/client/cmd_buffer_helper.cc +++ b/gpu/command_buffer/client/cmd_buffer_helper.cc
@@ -390,12 +390,12 @@ GetTotalFreeEntriesNoWaiting() * sizeof(CommandBufferEntry)); base::UnguessableToken shared_memory_guid = ring_buffer_->backing()->shared_memory_handle().GetGUID(); - auto guid = GetBufferGUIDForTracing(tracing_process_id, ring_buffer_id_); const int kImportance = 2; if (!shared_memory_guid.is_empty()) { - pmd->CreateSharedMemoryOwnershipEdge(dump->guid(), guid, - shared_memory_guid, kImportance); + pmd->CreateSharedMemoryOwnershipEdge(dump->guid(), shared_memory_guid, + kImportance); } else { + auto guid = GetBufferGUIDForTracing(tracing_process_id, ring_buffer_id_); pmd->CreateSharedGlobalAllocatorDump(guid); pmd->AddOwnershipEdge(dump->guid(), guid, kImportance); }
diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc index f63d6df..da23555 100644 --- a/gpu/command_buffer/client/gles2_implementation.cc +++ b/gpu/command_buffer/client/gles2_implementation.cc
@@ -470,15 +470,15 @@ if (args.level_of_detail != MemoryDumpLevelOfDetail::BACKGROUND) { dump->AddScalar("free_size", MemoryAllocatorDump::kUnitsBytes, transfer_buffer_->GetFreeSize()); - auto guid = GetBufferGUIDForTracing(tracing_process_id, - transfer_buffer_->GetShmId()); auto shared_memory_guid = transfer_buffer_->shared_memory_handle().GetGUID(); const int kImportance = 2; if (!shared_memory_guid.is_empty()) { - pmd->CreateSharedMemoryOwnershipEdge(dump->guid(), guid, - shared_memory_guid, kImportance); + pmd->CreateSharedMemoryOwnershipEdge(dump->guid(), shared_memory_guid, + kImportance); } else { + auto guid = GetBufferGUIDForTracing(tracing_process_id, + transfer_buffer_->GetShmId()); pmd->CreateSharedGlobalAllocatorDump(guid); pmd->AddOwnershipEdge(dump->guid(), guid, kImportance); }
diff --git a/gpu/command_buffer/client/gles2_implementation.h b/gpu/command_buffer/client/gles2_implementation.h index 2a39412..ec2f3568 100644 --- a/gpu/command_buffer/client/gles2_implementation.h +++ b/gpu/command_buffer/client/gles2_implementation.h
@@ -120,10 +120,10 @@ // GLES2CmdHelper but that entails changing your code to use and deal with // shared memory and synchronization issues. class GLES2_IMPL_EXPORT GLES2Implementation - : NON_EXPORTED_BASE(public GLES2Interface), - NON_EXPORTED_BASE(public ContextSupport), - NON_EXPORTED_BASE(public GpuControlClient), - NON_EXPORTED_BASE(public base::trace_event::MemoryDumpProvider) { + : public GLES2Interface, + public ContextSupport, + public GpuControlClient, + public base::trace_event::MemoryDumpProvider { public: // Stores GL state that never changes. struct GLES2_IMPL_EXPORT GLStaticState {
diff --git a/gpu/command_buffer/client/gles2_implementation_impl_autogen.h b/gpu/command_buffer/client/gles2_implementation_impl_autogen.h index 055575a..71a6edb0 100644 --- a/gpu/command_buffer/client/gles2_implementation_impl_autogen.h +++ b/gpu/command_buffer/client/gles2_implementation_impl_autogen.h
@@ -3122,9 +3122,10 @@ GPU_CLIENT_SINGLE_THREAD_CHECK(); GPU_CLIENT_LOG( "[" << GetLogPrefix() << "] glCopyTextureCHROMIUM(" << source_id << ", " - << source_level << ", " << GLES2Util::GetStringEnum(dest_target) - << ", " << dest_id << ", " << dest_level << ", " << internalformat - << ", " << GLES2Util::GetStringPixelType(dest_type) << ", " + << source_level << ", " + << GLES2Util::GetStringTextureTarget(dest_target) << ", " << dest_id + << ", " << dest_level << ", " << internalformat << ", " + << GLES2Util::GetStringPixelType(dest_type) << ", " << GLES2Util::GetStringBool(unpack_flip_y) << ", " << GLES2Util::GetStringBool(unpack_premultiply_alpha) << ", " << GLES2Util::GetStringBool(unpack_unmultiply_alpha) << ")"); @@ -3154,9 +3155,9 @@ GPU_CLIENT_LOG( "[" << GetLogPrefix() << "] glCopySubTextureCHROMIUM(" << source_id << ", " << source_level << ", " - << GLES2Util::GetStringEnum(dest_target) << ", " << dest_id << ", " - << dest_level << ", " << xoffset << ", " << yoffset << ", " << x - << ", " << y << ", " << width << ", " << height << ", " + << GLES2Util::GetStringTextureTarget(dest_target) << ", " << dest_id + << ", " << dest_level << ", " << xoffset << ", " << yoffset << ", " + << x << ", " << y << ", " << width << ", " << height << ", " << GLES2Util::GetStringBool(unpack_flip_y) << ", " << GLES2Util::GetStringBool(unpack_premultiply_alpha) << ", " << GLES2Util::GetStringBool(unpack_unmultiply_alpha) << ")"); @@ -3198,11 +3199,11 @@ GLenum internalformat, GLint imageId) { GPU_CLIENT_SINGLE_THREAD_CHECK(); - GPU_CLIENT_LOG("[" << GetLogPrefix() - << "] glBindTexImage2DWithInternalformatCHROMIUM(" - << GLES2Util::GetStringTextureBindTarget(target) << ", " - << GLES2Util::GetStringEnum(internalformat) << ", " - << imageId << ")"); + GPU_CLIENT_LOG( + "[" << GetLogPrefix() << "] glBindTexImage2DWithInternalformatCHROMIUM(" + << GLES2Util::GetStringTextureBindTarget(target) << ", " + << GLES2Util::GetStringTextureInternalFormat(internalformat) << ", " + << imageId << ")"); helper_->BindTexImage2DWithInternalformatCHROMIUM(target, internalformat, imageId); CheckGLError();
diff --git a/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h b/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h index cdde29d7..e157a11 100644 --- a/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h +++ b/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h
@@ -2717,11 +2717,11 @@ cmds::CopyTextureCHROMIUM cmd; }; Cmds expected; - expected.cmd.Init(1, 2, 3, 4, 5, GL_ALPHA, GL_UNSIGNED_BYTE, true, true, - true); + expected.cmd.Init(1, 2, GL_TEXTURE_2D, 4, 5, GL_ALPHA, GL_UNSIGNED_BYTE, true, + true, true); - gl_->CopyTextureCHROMIUM(1, 2, 3, 4, 5, GL_ALPHA, GL_UNSIGNED_BYTE, true, - true, true); + gl_->CopyTextureCHROMIUM(1, 2, GL_TEXTURE_2D, 4, 5, GL_ALPHA, + GL_UNSIGNED_BYTE, true, true, true); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); } @@ -2730,10 +2730,11 @@ cmds::CopySubTextureCHROMIUM cmd; }; Cmds expected; - expected.cmd.Init(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, true, true, true); + expected.cmd.Init(1, 2, GL_TEXTURE_2D, 4, 5, 6, 7, 8, 9, 10, 11, true, true, + true); - gl_->CopySubTextureCHROMIUM(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, true, true, - true); + gl_->CopySubTextureCHROMIUM(1, 2, GL_TEXTURE_2D, 4, 5, 6, 7, 8, 9, 10, 11, + true, true, true); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); } @@ -2786,9 +2787,9 @@ cmds::BindTexImage2DWithInternalformatCHROMIUM cmd; }; Cmds expected; - expected.cmd.Init(GL_TEXTURE_2D, 2, 3); + expected.cmd.Init(GL_TEXTURE_2D, GL_ALPHA, 3); - gl_->BindTexImage2DWithInternalformatCHROMIUM(GL_TEXTURE_2D, 2, 3); + gl_->BindTexImage2DWithInternalformatCHROMIUM(GL_TEXTURE_2D, GL_ALPHA, 3); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); }
diff --git a/gpu/command_buffer/client/gles2_trace_implementation.h b/gpu/command_buffer/client/gles2_trace_implementation.h index 780a608..9af6bada 100644 --- a/gpu/command_buffer/client/gles2_trace_implementation.h +++ b/gpu/command_buffer/client/gles2_trace_implementation.h
@@ -13,8 +13,7 @@ namespace gles2 { // GLES2TraceImplementation is calls TRACE for every GL call. -class GLES2_IMPL_EXPORT GLES2TraceImplementation - : NON_EXPORTED_BASE(public GLES2Interface) { +class GLES2_IMPL_EXPORT GLES2TraceImplementation : public GLES2Interface { public: explicit GLES2TraceImplementation(GLES2Interface* gl); ~GLES2TraceImplementation() override;
diff --git a/gpu/command_buffer/client/mapped_memory.cc b/gpu/command_buffer/client/mapped_memory.cc index d6c7244..e65cdf7 100644 --- a/gpu/command_buffer/client/mapped_memory.cc +++ b/gpu/command_buffer/client/mapped_memory.cc
@@ -186,15 +186,14 @@ dump->AddScalar("free_size", MemoryAllocatorDump::kUnitsBytes, chunk->GetFreeSize()); - auto guid = GetBufferGUIDForTracing(tracing_process_id, chunk->shm_id()); - auto shared_memory_guid = chunk->shared_memory()->backing()->shared_memory_handle().GetGUID(); const int kImportance = 2; if (!shared_memory_guid.is_empty()) { - pmd->CreateSharedMemoryOwnershipEdge(dump->guid(), guid, - shared_memory_guid, kImportance); + pmd->CreateSharedMemoryOwnershipEdge(dump->guid(), shared_memory_guid, + kImportance); } else { + auto guid = GetBufferGUIDForTracing(tracing_process_id, chunk->shm_id()); pmd->CreateSharedGlobalAllocatorDump(guid); pmd->AddOwnershipEdge(dump->guid(), guid, kImportance); }
diff --git a/gpu/command_buffer/cmd_buffer_functions.txt b/gpu/command_buffer/cmd_buffer_functions.txt index d285480d..6b32f39 100644 --- a/gpu/command_buffer/cmd_buffer_functions.txt +++ b/gpu/command_buffer/cmd_buffer_functions.txt
@@ -279,8 +279,8 @@ GL_APICALL void GL_APIENTRY glDescheduleUntilFinishedCHROMIUM (void); GL_APICALL void GL_APIENTRY glGetTranslatedShaderSourceANGLE (GLidShader shader, GLsizeiNotNegative bufsize, GLsizeiOptional* length, char* source); GL_APICALL void GL_APIENTRY glPostSubBufferCHROMIUM (GLint x, GLint y, GLint width, GLint height); -GL_APICALL void GL_APIENTRY glCopyTextureCHROMIUM (GLuint source_id, GLint source_level, GLenum dest_target, GLuint dest_id, GLint dest_level, GLintTextureInternalFormat internalformat, GLenumPixelType dest_type, GLboolean unpack_flip_y, GLboolean unpack_premultiply_alpha, GLboolean unpack_unmultiply_alpha); -GL_APICALL void GL_APIENTRY glCopySubTextureCHROMIUM (GLuint source_id, GLint source_level, GLenum dest_target, GLuint dest_id, GLint dest_level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, GLboolean unpack_flip_y, GLboolean unpack_premultiply_alpha, GLboolean unpack_unmultiply_alpha); +GL_APICALL void GL_APIENTRY glCopyTextureCHROMIUM (GLuint source_id, GLint source_level, GLenumTextureTarget dest_target, GLuint dest_id, GLint dest_level, GLintTextureInternalFormat internalformat, GLenumPixelType dest_type, GLboolean unpack_flip_y, GLboolean unpack_premultiply_alpha, GLboolean unpack_unmultiply_alpha); +GL_APICALL void GL_APIENTRY glCopySubTextureCHROMIUM (GLuint source_id, GLint source_level, GLenumTextureTarget dest_target, GLuint dest_id, GLint dest_level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, GLboolean unpack_flip_y, GLboolean unpack_premultiply_alpha, GLboolean unpack_unmultiply_alpha); GL_APICALL void GL_APIENTRY glCompressedCopyTextureCHROMIUM (GLuint source_id, GLuint dest_id); GL_APICALL void GL_APIENTRY glDrawArraysInstancedANGLE (GLenumDrawMode mode, GLint first, GLsizei count, GLsizei primcount); GL_APICALL void GL_APIENTRY glDrawElementsInstancedANGLE (GLenumDrawMode mode, GLsizei count, GLenumIndexType type, const void* indices, GLsizei primcount); @@ -293,7 +293,7 @@ GL_APICALL void GL_APIENTRY glCreateAndConsumeTextureINTERNAL (GLenumTextureBindTarget target, GLuint texture, const GLbyte* mailbox); GL_APICALL void GL_APIENTRY glBindUniformLocationCHROMIUM (GLidProgram program, GLint location, const char* name); GL_APICALL void GL_APIENTRY glBindTexImage2DCHROMIUM (GLenumTextureBindTarget target, GLint imageId); -GL_APICALL void GL_APIENTRY glBindTexImage2DWithInternalformatCHROMIUM (GLenumTextureBindTarget target, GLenum internalformat, GLint imageId); +GL_APICALL void GL_APIENTRY glBindTexImage2DWithInternalformatCHROMIUM (GLenumTextureBindTarget target, GLenumTextureInternalFormat internalformat, GLint imageId); GL_APICALL void GL_APIENTRY glReleaseTexImage2DCHROMIUM (GLenumTextureBindTarget target, GLint imageId); GL_APICALL void GL_APIENTRY glTraceBeginCHROMIUM (const char* category_name, const char* trace_name); GL_APICALL void GL_APIENTRY glTraceEndCHROMIUM (void);
diff --git a/gpu/command_buffer/service/buffer_manager.cc b/gpu/command_buffer/service/buffer_manager.cc index e625cc0..4668db7 100644 --- a/gpu/command_buffer/service/buffer_manager.cc +++ b/gpu/command_buffer/service/buffer_manager.cc
@@ -737,17 +737,17 @@ MemoryAllocatorDump::kUnitsBytes, static_cast<uint64_t>(buffer->size())); - auto guid = gl::GetGLBufferGUIDForTracing(share_group_tracing_guid, - client_buffer_id); auto* mapped_range = buffer->GetMappedRange(); if (!mapped_range) continue; auto shared_memory_guid = mapped_range->shm->backing()->shared_memory_handle().GetGUID(); if (!shared_memory_guid.is_empty()) { - pmd->CreateSharedMemoryOwnershipEdge( - dump->guid(), guid, shared_memory_guid, 0 /* importance */); + pmd->CreateSharedMemoryOwnershipEdge(dump->guid(), shared_memory_guid, + 0 /* importance */); } else { + auto guid = gl::GetGLBufferGUIDForTracing(share_group_tracing_guid, + client_buffer_id); pmd->CreateSharedGlobalAllocatorDump(guid); pmd->AddOwnershipEdge(dump->guid(), guid); }
diff --git a/gpu/command_buffer/service/framebuffer_manager.cc b/gpu/command_buffer/service/framebuffer_manager.cc index e2333d1..366c5085 100644 --- a/gpu/command_buffer/service/framebuffer_manager.cc +++ b/gpu/command_buffer/service/framebuffer_manager.cc
@@ -986,7 +986,7 @@ void Framebuffer::AttachRenderbuffer( GLenum attachment, Renderbuffer* renderbuffer) { - DCHECK(attachment != GL_DEPTH_STENCIL_ATTACHMENT); + DCHECK_NE(static_cast<GLenum>(GL_DEPTH_STENCIL_ATTACHMENT), attachment); const Attachment* a = GetAttachment(attachment); if (a) a->DetachFromFramebuffer(this, attachment); @@ -1003,7 +1003,7 @@ void Framebuffer::AttachTexture( GLenum attachment, TextureRef* texture_ref, GLenum target, GLint level, GLsizei samples) { - DCHECK(attachment != GL_DEPTH_STENCIL_ATTACHMENT); + DCHECK_NE(static_cast<GLenum>(GL_DEPTH_STENCIL_ATTACHMENT), attachment); const Attachment* a = GetAttachment(attachment); if (a) a->DetachFromFramebuffer(this, attachment); @@ -1020,7 +1020,7 @@ void Framebuffer::AttachTextureLayer( GLenum attachment, TextureRef* texture_ref, GLenum target, GLint level, GLint layer) { - DCHECK(attachment != GL_DEPTH_STENCIL_ATTACHMENT); + DCHECK_NE(static_cast<GLenum>(GL_DEPTH_STENCIL_ATTACHMENT), attachment); const Attachment* a = GetAttachment(attachment); if (a) a->DetachFromFramebuffer(this, attachment);
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.h b/gpu/command_buffer/service/gles2_cmd_decoder.h index 8035e93a..85e663e 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder.h
@@ -113,8 +113,7 @@ // This class implements the AsyncAPIInterface interface, decoding GLES2 // commands and calling GL. -class GPU_EXPORT GLES2Decoder : public CommonDecoder, - NON_EXPORTED_BASE(public AsyncAPIInterface) { +class GPU_EXPORT GLES2Decoder : public CommonDecoder, public AsyncAPIInterface { public: typedef error::Error Error;
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h index 8cd6cd21..1109545 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
@@ -4571,6 +4571,11 @@ static_cast<GLboolean>(c.unpack_premultiply_alpha); GLboolean unpack_unmultiply_alpha = static_cast<GLboolean>(c.unpack_unmultiply_alpha); + if (!validators_->texture_target.IsValid(dest_target)) { + LOCAL_SET_GL_ERROR_INVALID_ENUM("glCopyTextureCHROMIUM", dest_target, + "dest_target"); + return error::kNoError; + } if (!validators_->texture_internal_format.IsValid(internalformat)) { LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "internalformat GL_INVALID_VALUE"); @@ -4609,6 +4614,11 @@ static_cast<GLboolean>(c.unpack_premultiply_alpha); GLboolean unpack_unmultiply_alpha = static_cast<GLboolean>(c.unpack_unmultiply_alpha); + if (!validators_->texture_target.IsValid(dest_target)) { + LOCAL_SET_GL_ERROR_INVALID_ENUM("glCopySubTextureCHROMIUM", dest_target, + "dest_target"); + return error::kNoError; + } if (width < 0) { LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCopySubTextureCHROMIUM", "width < 0"); @@ -4782,6 +4792,12 @@ "glBindTexImage2DWithInternalformatCHROMIUM", target, "target"); return error::kNoError; } + if (!validators_->texture_internal_format.IsValid(internalformat)) { + LOCAL_SET_GL_ERROR_INVALID_ENUM( + "glBindTexImage2DWithInternalformatCHROMIUM", internalformat, + "internalformat"); + return error::kNoError; + } DoBindTexImage2DWithInternalformatCHROMIUM(target, internalformat, imageId); return error::kNoError; }
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc index 14d80f13..a5568b9 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc
@@ -831,6 +831,47 @@ INSTANTIATE_PATCH_NUMERIC_RESULTS(GLboolean); #undef INSTANTIATE_PATCH_NUMERIC_RESULTS +template <typename T> +error::Error GLES2DecoderPassthroughImpl::PatchGetBufferResults(GLenum target, + GLenum pname, + GLsizei bufsize, + GLsizei* length, + T* params) { + if (pname != GL_BUFFER_ACCESS_FLAGS) { + return error::kNoError; + } + + // If there was no error, the buffer target should exist + DCHECK(bound_buffers_.find(target) != bound_buffers_.end()); + GLuint current_client_buffer = bound_buffers_[target]; + + auto mapped_buffer_info_iter = + resources_->mapped_buffer_map.find(current_client_buffer); + if (mapped_buffer_info_iter == resources_->mapped_buffer_map.end()) { + // Buffer is not mapped, nothing to do + return error::kNoError; + } + + // Buffer is mapped, patch the result with the original access flags + DCHECK(bufsize >= 1); + DCHECK(*length == 1); + params[0] = mapped_buffer_info_iter->second.original_access; + return error::kNoError; +} + +template error::Error GLES2DecoderPassthroughImpl::PatchGetBufferResults( + GLenum target, + GLenum pname, + GLsizei bufsize, + GLsizei* length, + GLint64* params); +template error::Error GLES2DecoderPassthroughImpl::PatchGetBufferResults( + GLenum target, + GLenum pname, + GLsizei bufsize, + GLsizei* length, + GLint* params); + error::Error GLES2DecoderPassthroughImpl::PatchGetFramebufferAttachmentParameter( GLenum target,
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h index f78184e..e7ba614 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h
@@ -33,7 +33,8 @@ struct MappedBuffer { GLsizeiptr size; - GLbitfield access; + GLbitfield original_access; + GLbitfield filtered_access; uint8_t* map_ptr; int32_t data_shm_id; uint32_t data_shm_offset; @@ -288,6 +289,13 @@ GLsizei length, GLint* params); + template <typename T> + error::Error PatchGetBufferResults(GLenum target, + GLenum pname, + GLsizei bufsize, + GLsizei* length, + T* params); + void InsertError(GLenum error, const std::string& message); GLenum PopError(); bool FlushErrors();
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc index 10ffaf7..31978a1 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc
@@ -1204,7 +1204,12 @@ GLsizei bufsize, GLsizei* length, GLint64* params) { + FlushErrors(); glGetBufferParameteri64vRobustANGLE(target, pname, bufsize, length, params); + if (FlushErrors()) { + return error::kNoError; + } + PatchGetBufferResults(target, pname, bufsize, length, params); return error::kNoError; } @@ -1214,7 +1219,12 @@ GLsizei bufsize, GLsizei* length, GLint* params) { + FlushErrors(); glGetBufferParameterivRobustANGLE(target, pname, bufsize, length, params); + if (FlushErrors()) { + return error::kNoError; + } + PatchGetBufferResults(target, pname, bufsize, length, params); return error::kNoError; } @@ -2914,7 +2924,8 @@ MappedBuffer mapped_buffer_info; mapped_buffer_info.size = size; - mapped_buffer_info.access = filtered_access; + mapped_buffer_info.original_access = access; + mapped_buffer_info.filtered_access = filtered_access; mapped_buffer_info.map_ptr = static_cast<uint8_t*>(mapped_ptr); mapped_buffer_info.data_shm_id = data_shm_id; mapped_buffer_info.data_shm_offset = data_shm_offset; @@ -2945,8 +2956,8 @@ } const MappedBuffer& map_info = mapped_buffer_info_iter->second; - if ((map_info.access & GL_MAP_WRITE_BIT) != 0 && - (map_info.access & GL_MAP_FLUSH_EXPLICIT_BIT) == 0) { + if ((map_info.filtered_access & GL_MAP_WRITE_BIT) != 0 && + (map_info.filtered_access & GL_MAP_FLUSH_EXPLICIT_BIT) == 0) { uint8_t* mem = GetSharedMemoryAs<uint8_t*>( map_info.data_shm_id, map_info.data_shm_offset, map_info.size); if (!mem) {
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_textures.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_textures.cc index a3ef80fa..ce9fb8c 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_textures.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_textures.cc
@@ -2222,7 +2222,43 @@ EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); } +TEST_P(GLES2DecoderTest, CopyTextureCHROMIUMBadTarget) { + DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId); + DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 17, 0, GL_RGBA, GL_UNSIGNED_BYTE, + 0, 0); + EXPECT_CALL(*gl_, GenTextures(_, _)) + .WillOnce(SetArgPointee<1>(kNewServiceId)) + .RetiresOnSaturation(); + GenHelper<GenTexturesImmediate>(kNewClientId); + + const GLenum kBadTarget = GL_RGB; + CopyTextureCHROMIUM cmd; + cmd.Init(client_texture_id_, 0, kBadTarget, kNewClientId, 0, GL_RGBA, + GL_UNSIGNED_BYTE, GL_FALSE, GL_FALSE, GL_FALSE); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); +} + +TEST_P(GLES2DecoderTest, CopySubTextureCHROMIUMBadTarget) { + DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId); + DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 17, 0, GL_RGBA, GL_UNSIGNED_BYTE, + 0, 0); + + EXPECT_CALL(*gl_, GenTextures(_, _)) + .WillOnce(SetArgPointee<1>(kNewServiceId)) + .RetiresOnSaturation(); + DoBindTexture(GL_TEXTURE_2D, kNewClientId, kNewServiceId); + DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 17, 0, GL_RGBA, GL_UNSIGNED_BYTE, + 0, 0); + + const GLenum kBadTarget = GL_RGB; + CopySubTextureCHROMIUM cmd; + cmd.Init(client_texture_id_, 0, kBadTarget, kNewClientId, 0, 1, 1, 2, 2, 3, 3, + GL_FALSE, GL_FALSE, GL_FALSE); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); +} TEST_P(GLES2DecoderManualInitTest, EGLImageExternalBindTexture) { InitState init; @@ -3605,6 +3641,18 @@ EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); } +TEST_P(GLES2DecoderTest, + BindTexImage2DWithInternalformatCHROMIUMBadInternalFormat) { + scoped_refptr<gl::GLImage> image(new gl::GLImageStub); + GetImageManagerForTest()->AddImage(image.get(), 1); + DoBindTexture(GL_TEXTURE_CUBE_MAP, client_texture_id_, kServiceTextureId); + + BindTexImage2DWithInternalformatCHROMIUM bind_tex_image_2d_cmd; + bind_tex_image_2d_cmd.Init(GL_TEXTURE_2D, GL_BACK, 1); // Invalid enum + EXPECT_EQ(error::kNoError, ExecuteCmd(bind_tex_image_2d_cmd)); + EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); +} + TEST_P(GLES2DecoderTest, OrphanGLImageWithTexImage2D) { scoped_refptr<gl::GLImage> image(new gl::GLImageStub); GetImageManagerForTest()->AddImage(image.get(), 1);
diff --git a/gpu/command_buffer/service/renderbuffer_manager.cc b/gpu/command_buffer/service/renderbuffer_manager.cc index 111569a..ecdb81a 100644 --- a/gpu/command_buffer/service/renderbuffer_manager.cc +++ b/gpu/command_buffer/service/renderbuffer_manager.cc
@@ -166,12 +166,14 @@ void Renderbuffer::AddFramebufferAttachmentPoint(Framebuffer* framebuffer, GLenum attachment) { + DCHECK_NE(static_cast<GLenum>(GL_DEPTH_STENCIL_ATTACHMENT), attachment); framebuffer_attachment_points_.insert( std::make_pair(framebuffer, attachment)); } void Renderbuffer::RemoveFramebufferAttachmentPoint(Framebuffer* framebuffer, GLenum attachment) { + DCHECK_NE(static_cast<GLenum>(GL_DEPTH_STENCIL_ATTACHMENT), attachment); framebuffer_attachment_points_.erase(std::make_pair(framebuffer, attachment)); }
diff --git a/gpu/command_buffer/service/shader_translator.h b/gpu/command_buffer/service/shader_translator.h index a0a9c90e..5d34463 100644 --- a/gpu/command_buffer/service/shader_translator.h +++ b/gpu/command_buffer/service/shader_translator.h
@@ -74,8 +74,7 @@ }; // Implementation of ShaderTranslatorInterface -class GPU_EXPORT ShaderTranslator - : NON_EXPORTED_BASE(public ShaderTranslatorInterface) { +class GPU_EXPORT ShaderTranslator : public ShaderTranslatorInterface { public: class DestructionObserver { public:
diff --git a/gpu/command_buffer/service/shader_translator_cache.h b/gpu/command_buffer/service/shader_translator_cache.h index b764b75..1b8cd588 100644 --- a/gpu/command_buffer/service/shader_translator_cache.h +++ b/gpu/command_buffer/service/shader_translator_cache.h
@@ -27,7 +27,7 @@ // TODO(backer): Investigate using glReleaseShaderCompiler as an alternative to // to this cache. class GPU_EXPORT ShaderTranslatorCache - : public NON_EXPORTED_BASE(ShaderTranslator::DestructionObserver) { + : public ShaderTranslator::DestructionObserver { public: explicit ShaderTranslatorCache(const GpuPreferences& gpu_preferences); ~ShaderTranslatorCache() override;
diff --git a/gpu/command_buffer/service/transfer_buffer_manager.cc b/gpu/command_buffer/service/transfer_buffer_manager.cc index 34b164a8..29359bd4 100644 --- a/gpu/command_buffer/service/transfer_buffer_manager.cc +++ b/gpu/command_buffer/service/transfer_buffer_manager.cc
@@ -130,14 +130,14 @@ dump->AddScalar(MemoryAllocatorDump::kNameSize, MemoryAllocatorDump::kUnitsBytes, buffer->size()); - auto guid = - GetBufferGUIDForTracing(memory_tracker_->ClientTracingId(), buffer_id); auto shared_memory_guid = buffer->backing()->shared_memory_handle().GetGUID(); if (!shared_memory_guid.is_empty()) { - pmd->CreateSharedMemoryOwnershipEdge( - dump->guid(), guid, shared_memory_guid, 0 /* importance */); + pmd->CreateSharedMemoryOwnershipEdge(dump->guid(), shared_memory_guid, + 0 /* importance */); } else { + auto guid = GetBufferGUIDForTracing(memory_tracker_->ClientTracingId(), + buffer_id); pmd->CreateSharedGlobalAllocatorDump(guid); pmd->AddOwnershipEdge(dump->guid(), guid); }
diff --git a/gpu/command_buffer/tests/gl_map_buffer_range_unittest.cc b/gpu/command_buffer/tests/gl_map_buffer_range_unittest.cc index 7634cd3..4d238db 100644 --- a/gpu/command_buffer/tests/gl_map_buffer_range_unittest.cc +++ b/gpu/command_buffer/tests/gl_map_buffer_range_unittest.cc
@@ -412,13 +412,6 @@ if (ShouldSkipTest()) return; - if (gl_.gpu_preferences().use_passthrough_cmd_decoder) { - // TODO(geofflang): crbug.com/754000 - LOG(INFO) - << "Passthrough command decoder expected failure. Skipping test..."; - return; - } - GLuint transform_feedback = 0; glGenTransformFeedbacks(1, &transform_feedback); glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, transform_feedback); @@ -484,13 +477,6 @@ if (ShouldSkipTest()) return; - if (gl_.gpu_preferences().use_passthrough_cmd_decoder) { - // TODO(geofflang): crbug.com/754000 - LOG(INFO) - << "Passthrough command decoder expected failure. Skipping test..."; - return; - } - GLuint buffer; glGenBuffers(1, &buffer); EXPECT_LT(0u, buffer);
diff --git a/gpu/ipc/client/gpu_memory_buffer_impl_shared_memory.cc b/gpu/ipc/client/gpu_memory_buffer_impl_shared_memory.cc index 3deb043..8bf7cd6 100644 --- a/gpu/ipc/client/gpu_memory_buffer_impl_shared_memory.cc +++ b/gpu/ipc/client/gpu_memory_buffer_impl_shared_memory.cc
@@ -8,11 +8,12 @@ #include <utility> #include "base/bind.h" +#include "base/format_macros.h" #include "base/memory/ptr_util.h" #include "base/numerics/safe_math.h" #include "base/process/memory.h" +#include "base/strings/stringprintf.h" #include "ui/gfx/buffer_format_util.h" -#include "ui/gfx/gpu_memory_buffer_tracing.h" #include "ui/gl/gl_bindings.h" namespace gpu { @@ -217,7 +218,8 @@ base::trace_event::MemoryAllocatorDumpGuid GpuMemoryBufferImplSharedMemory::GetGUIDForTracing( uint64_t tracing_process_id) const { - return gfx::GetSharedMemoryGUIDForTracing(tracing_process_id, id_); + return base::trace_event::MemoryAllocatorDumpGuid(base::StringPrintf( + "shared_memory_gpu/%" PRIx64 "/%d", tracing_process_id, id_.id)); } } // namespace gpu
diff --git a/gpu/ipc/gpu_in_process_thread_service.h b/gpu/ipc/gpu_in_process_thread_service.h index fdf2703..6dbed869 100644 --- a/gpu/ipc/gpu_in_process_thread_service.h +++ b/gpu/ipc/gpu_in_process_thread_service.h
@@ -17,7 +17,7 @@ // Default Service class when no service is specified. GpuInProcessThreadService // is used by Mus and unit tests. class GPU_EXPORT GpuInProcessThreadService - : public NON_EXPORTED_BASE(gpu::InProcessCommandBuffer::Service), + : public gpu::InProcessCommandBuffer::Service, public base::RefCountedThreadSafe<GpuInProcessThreadService> { public: GpuInProcessThreadService(
diff --git a/gpu/ipc/host/shader_disk_cache.h b/gpu/ipc/host/shader_disk_cache.h index d144319..1e8756e6 100644 --- a/gpu/ipc/host/shader_disk_cache.h +++ b/gpu/ipc/host/shader_disk_cache.h
@@ -105,7 +105,7 @@ // ShaderCacheFactory maintains a cache of ShaderDiskCache objects // so we only create one per profile directory. -class ShaderCacheFactory : NON_EXPORTED_BASE(public base::ThreadChecker) { +class ShaderCacheFactory : public base::ThreadChecker { public: ShaderCacheFactory(); ~ShaderCacheFactory();
diff --git a/headless/lib/browser/headless_browser_impl.cc b/headless/lib/browser/headless_browser_impl.cc index 0f64f11b9..08ba287a 100644 --- a/headless/lib/browser/headless_browser_impl.cc +++ b/headless/lib/browser/headless_browser_impl.cc
@@ -30,6 +30,10 @@ #include "ui/events/devices/device_data_manager.h" #include "ui/gfx/geometry/size.h" +#if defined(USE_NSS_CERTS) +#include "net/cert_net/nss_ocsp.h" +#endif + namespace content { class DevToolsAgentHost; } @@ -131,6 +135,11 @@ } void HeadlessBrowserImpl::RunOnStartCallback() { +#if defined(USE_NSS_CERTS) + content::BrowserThread::PostTask( + content::BrowserThread::IO, FROM_HERE, + base::Bind(&net::SetMessageLoopForNSSHttpIO)); +#endif // We don't support the tethering domain on this agent host. agent_host_ = content::DevToolsAgentHost::CreateForBrowser( nullptr, content::DevToolsAgentHost::CreateServerSocketCallback());
diff --git a/headless/lib/headless_browser_browsertest.cc b/headless/lib/headless_browser_browsertest.cc index 5354eb3..c3ab709 100644 --- a/headless/lib/headless_browser_browsertest.cc +++ b/headless/lib/headless_browser_browsertest.cc
@@ -610,7 +610,7 @@ .SetSecure(true) .SetHttpOnly(true) .SetSameSite(network::CookieSameSite::EXACT) - .SetExpirationDate(0) + .SetExpires(0) .Build(); CookieSetter cookie_setter(this, web_contents, std::move(set_cookie_params));
diff --git a/headless/lib/headless_content_main_delegate.cc b/headless/lib/headless_content_main_delegate.cc index 2553153..b9ae0332 100644 --- a/headless/lib/headless_content_main_delegate.cc +++ b/headless/lib/headless_content_main_delegate.cc
@@ -269,11 +269,6 @@ // static void HeadlessContentMainDelegate::InitializeResourceBundle() { - base::FilePath dir_module; - base::FilePath pak_file; - bool result = PathService::Get(base::DIR_MODULE, &dir_module); - DCHECK(result); - base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); const std::string locale = command_line->GetSwitchValueASCII(switches::kLang); ui::ResourceBundle::InitSharedInstanceWithLocale( @@ -285,21 +280,51 @@ reinterpret_cast<const char*>(kHeadlessResourcePak.contents), kHeadlessResourcePak.length), ui::SCALE_FACTOR_NONE); + #else + + base::FilePath dir_module; + bool result = PathService::Get(base::DIR_MODULE, &dir_module); + DCHECK(result); + // Try loading the headless library pak file first. If it doesn't exist (i.e., // when we're running with the --headless switch), fall back to the browser's // resource pak. - pak_file = dir_module.Append(FILE_PATH_LITERAL("headless_lib.pak")); - if (!base::PathExists(pak_file)) - pak_file = dir_module.Append(FILE_PATH_LITERAL("resources.pak")); + base::FilePath headless_pak = + dir_module.Append(FILE_PATH_LITERAL("headless_lib.pak")); + if (base::PathExists(headless_pak)) { + ResourceBundle::GetSharedInstance().AddDataPackFromPath( + headless_pak, ui::SCALE_FACTOR_NONE); + return; + } + + // Otherwise, load resources.pak, chrome_100 and chrome_200. + base::FilePath resources_pak = + dir_module.Append(FILE_PATH_LITERAL("resources.pak")); + base::FilePath chrome_100_pak = + dir_module.Append(FILE_PATH_LITERAL("chrome_100_percent.pak")); + base::FilePath chrome_200_pak = + dir_module.Append(FILE_PATH_LITERAL("chrome_200_percent.pak")); + #if defined(OS_MACOSX) && !defined(COMPONENT_BUILD) // In non component builds, check if fall back in Resources/ folder is // available. - if (!base::PathExists(pak_file)) - pak_file = dir_module.Append(FILE_PATH_LITERAL("Resources/resources.pak")); + if (!base::PathExists(resources_pak)) { + resources_pak = + dir_module.Append(FILE_PATH_LITERAL("Resources/resources.pak")); + chrome_100_pak = dir_module.Append( + FILE_PATH_LITERAL("Resources/chrome_100_percent.pak")); + chrome_200_pak = dir_module.Append( + FILE_PATH_LITERAL("Resources/chrome_200_percent.pak")); + } #endif + ResourceBundle::GetSharedInstance().AddDataPackFromPath( - pak_file, ui::SCALE_FACTOR_NONE); + resources_pak, ui::SCALE_FACTOR_NONE); + ResourceBundle::GetSharedInstance().AddDataPackFromPath( + chrome_100_pak, ui::SCALE_FACTOR_100P); + ResourceBundle::GetSharedInstance().AddDataPackFromPath( + chrome_200_pak, ui::SCALE_FACTOR_200P); #endif }
diff --git a/ios/chrome/browser/content_suggestions/content_suggestions_header_view_controller.mm b/ios/chrome/browser/content_suggestions/content_suggestions_header_view_controller.mm index 148748a..34963b61 100644 --- a/ios/chrome/browser/content_suggestions/content_suggestions_header_view_controller.mm +++ b/ios/chrome/browser/content_suggestions/content_suggestions_header_view_controller.mm
@@ -17,6 +17,7 @@ #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_synchronizing.h" #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils.h" #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view_controller_delegate.h" +#import "ios/chrome/browser/ui/content_suggestions/ntp_home_constant.h" #import "ios/chrome/browser/ui/ntp/new_tab_page_header_view.h" #import "ios/chrome/browser/ui/toolbar/web_toolbar_controller.h" #import "ios/chrome/browser/ui/uikit_ui_util.h" @@ -127,7 +128,7 @@ #pragma mark - ContentSuggestionsHeaderControlling -- (void)updateFakeOmniboxForOffset:(CGFloat)offset { +- (void)updateFakeOmniboxForOffset:(CGFloat)offset width:(CGFloat)width { NSArray* constraints = @[ self.hintLabelLeadingConstraint, self.voiceTapTrailingConstraint ]; @@ -136,7 +137,8 @@ topMargin:self.fakeOmniboxTopMarginConstraint subviewConstraints:constraints logoIsShowing:self.logoIsShowing - forOffset:offset]; + forOffset:offset + width:width]; } - (void)updateFakeOmniboxForWidth:(CGFloat)width { @@ -205,16 +207,13 @@ [self.fakeOmnibox addTarget:self action:@selector(fakeOmniboxTapped:) forControlEvents:UIControlEventTouchUpInside]; - UILongPressGestureRecognizer* longPressRecognizer = [ - [UILongPressGestureRecognizer alloc] initWithTarget:self - action:@selector(doNothing)]; - longPressRecognizer.numberOfTouchesRequired = 1; - [self.fakeOmnibox addGestureRecognizer:longPressRecognizer]; [self.fakeOmnibox setAccessibilityLabel:l10n_util::GetNSString(IDS_OMNIBOX_EMPTY_HINT)]; // Set isAccessibilityElement to NO so that Voice Search button is accessible. [self.fakeOmnibox setIsAccessibilityElement:NO]; + self.fakeOmnibox.accessibilityIdentifier = + ntp_home::FakeOmniboxAccessibilityID(); // Set up fakebox hint label. UILabel* searchHintLabel = [[UILabel alloc] init]; @@ -336,9 +335,6 @@ [self.collectionSynchronizer shiftTilesUpWithCompletionBlock:completionBlock]; } -- (void)doNothing { -} - #pragma mark - ToolbarOwner - (ToolbarController*)relinquishedToolbarController {
diff --git a/ios/chrome/browser/content_suggestions/content_suggestions_mediator.mm b/ios/chrome/browser/content_suggestions/content_suggestions_mediator.mm index 80e518b..9391c7d 100644 --- a/ios/chrome/browser/content_suggestions/content_suggestions_mediator.mm +++ b/ios/chrome/browser/content_suggestions/content_suggestions_mediator.mm
@@ -196,7 +196,11 @@ if (!self.sectionInformationByCategory[categoryWrapper]) { [self addSectionInformationForCategory:category]; } - [sectionsInfo addObject:self.sectionInformationByCategory[categoryWrapper]]; + if (IsCategoryStatusAvailable( + self.contentService->GetCategoryStatus(category))) { + [sectionsInfo + addObject:self.sectionInformationByCategory[categoryWrapper]]; + } } [sectionsInfo addObject:self.learnMoreSectionInfo]; @@ -340,15 +344,21 @@ (ntp_snippets::ContentSuggestionsService*)suggestionsService category:(ntp_snippets::Category)category statusChangedTo:(ntp_snippets::CategoryStatus)status { + ContentSuggestionsCategoryWrapper* wrapper = + [[ContentSuggestionsCategoryWrapper alloc] initWithCategory:category]; if (!ntp_snippets::IsCategoryStatusInitOrAvailable(status)) { // Remove the category from the UI if it is not available. - ContentSuggestionsCategoryWrapper* wrapper = - [[ContentSuggestionsCategoryWrapper alloc] initWithCategory:category]; ContentSuggestionsSectionInformation* sectionInfo = self.sectionInformationByCategory[wrapper]; [self.dataSink clearSection:sectionInfo]; [self.sectionInformationByCategory removeObjectForKey:wrapper]; + } else { + if (!self.sectionInformationByCategory[wrapper]) { + [self addSectionInformationForCategory:category]; + } + [self.dataSink + dataAvailableForSection:self.sectionInformationByCategory[wrapper]]; } }
diff --git a/ios/chrome/browser/context_menu/BUILD.gn b/ios/chrome/browser/context_menu/BUILD.gn index 4de5c20..86fffe7 100644 --- a/ios/chrome/browser/context_menu/BUILD.gn +++ b/ios/chrome/browser/context_menu/BUILD.gn
@@ -15,6 +15,7 @@ "//ios/chrome/test/app:test_support", "//ios/chrome/test/earl_grey:test_support", "//ios/testing:ios_test_support", + "//ios/testing/earl_grey:earl_grey_support", "//ios/third_party/earl_grey", "//ios/web:earl_grey_test_support", "//ios/web/public/test/http_server",
diff --git a/ios/chrome/browser/context_menu/context_menu_egtest.mm b/ios/chrome/browser/context_menu/context_menu_egtest.mm index 29f0765..243d1b5 100644 --- a/ios/chrome/browser/context_menu/context_menu_egtest.mm +++ b/ios/chrome/browser/context_menu/context_menu_egtest.mm
@@ -17,6 +17,7 @@ #import "ios/chrome/test/earl_grey/chrome_earl_grey_ui.h" #import "ios/chrome/test/earl_grey/chrome_matchers.h" #import "ios/chrome/test/earl_grey/chrome_test_case.h" +#import "ios/testing/earl_grey/disabled_test_macros.h" #import "ios/testing/wait_util.h" #import "ios/web/public/test/earl_grey/web_view_matchers.h" #import "ios/web/public/test/http_server/http_server.h" @@ -189,6 +190,13 @@ // on the page to verify that context menu can be properly triggered in the // current screen view. - (void)testContextMenuOpenInNewTabFromTallPage { +// TODO(crbug.com/755888): Reenable this test. +#if !TARGET_IPHONE_SIMULATOR + if (!IsIPadIdiom()) { + EARL_GREY_TEST_DISABLED(@"Failing constently on iPhone devices."); + } +#endif + // Set up test simple http server. std::map<GURL, std::string> responses; GURL initialURL =
diff --git a/ios/chrome/browser/experimental_flags.h b/ios/chrome/browser/experimental_flags.h index 5d052d02..a30c4e36 100644 --- a/ios/chrome/browser/experimental_flags.h +++ b/ios/chrome/browser/experimental_flags.h
@@ -78,10 +78,6 @@ // Whether viewing and copying passwords is enabled. bool IsViewCopyPasswordsEnabled(); -// Whether password generation fields are determined using local heuristics -// only. -bool UseOnlyLocalHeuristicsForPasswordGeneration(); - // Whether the Suggestions UI is enabled. bool IsSuggestionsUIEnabled();
diff --git a/ios/chrome/browser/experimental_flags.mm b/ios/chrome/browser/experimental_flags.mm index 3dc5c4ac..10fccf22 100644 --- a/ios/chrome/browser/experimental_flags.mm +++ b/ios/chrome/browser/experimental_flags.mm
@@ -7,8 +7,9 @@ #include "ios/chrome/browser/experimental_flags.h" -#include <dispatch/dispatch.h> #import <Foundation/Foundation.h> +#import <UIKit/UIKit.h> +#include <dispatch/dispatch.h> #include <string> @@ -184,12 +185,6 @@ return ![viewCopyPasswordFlag isEqualToString:@"Disabled"]; } -bool UseOnlyLocalHeuristicsForPasswordGeneration() { - // TODO(crbug.com/752077): Remove this function and its associated code. - // Either by replacing it with a base::Feature or by removing all its uses. - return false; -} - bool IsSuggestionsUIEnabled() { // Check if the experimental flag is forced on or off. base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); @@ -219,7 +214,8 @@ // Check if the experimental flag is forced on or off. base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); if (command_line->HasSwitch(switches::kEnableBookmarkReordering)) - return true; + // Enabled only on iPhone for now. + return true && (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone); if (command_line->HasSwitch(switches::kDisableBookmarkReordering)) return false;
diff --git a/ios/chrome/browser/passwords/password_generation_agent.mm b/ios/chrome/browser/passwords/password_generation_agent.mm index 53248e82..8eb8284 100644 --- a/ios/chrome/browser/passwords/password_generation_agent.mm +++ b/ios/chrome/browser/passwords/password_generation_agent.mm
@@ -287,10 +287,8 @@ // If the form origin hasn't been cleared by both the autofill and the // password manager, wait. GURL origin = _possibleAccountCreationForm->origin; - if (!experimental_flags::UseOnlyLocalHeuristicsForPasswordGeneration()) { - if (!base::ContainsValue(_allowedGenerationFormOrigins, origin)) - return; - } + if (!base::ContainsValue(_allowedGenerationFormOrigins, origin)) + return; // Use the first password field in the form as the generation field. _passwordGenerationField.reset(
diff --git a/ios/chrome/browser/reading_list/reading_list_distiller_page.mm b/ios/chrome/browser/reading_list/reading_list_distiller_page.mm index 5b8bed9..8c278a4 100644 --- a/ios/chrome/browser/reading_list/reading_list_distiller_page.mm +++ b/ios/chrome/browser/reading_list/reading_list_distiller_page.mm
@@ -108,7 +108,7 @@ favicon::WebFaviconDriver* favicon_driver = favicon::WebFaviconDriver::FromWebState(CurrentWebState()); DCHECK(favicon_driver); - favicon_driver->FetchFavicon(page_url); + favicon_driver->FetchFavicon(page_url, /*is_same_document=*/false); } void ReadingListDistillerPage::OnDistillationDone(const GURL& page_url,
diff --git a/ios/chrome/browser/tabs/tab.mm b/ios/chrome/browser/tabs/tab.mm index 6c12045..37851d8 100644 --- a/ios/chrome/browser/tabs/tab.mm +++ b/ios/chrome/browser/tabs/tab.mm
@@ -647,7 +647,7 @@ favicon::FaviconDriver* faviconDriver = favicon::WebFaviconDriver::FromWebState(self.webState); if (faviconDriver) - faviconDriver->FetchFavicon(url); + faviconDriver->FetchFavicon(url, /*is_same_document=*/false); } - (void)setFavicon:(const gfx::Image*)image { @@ -1141,7 +1141,8 @@ // Fetch the favicon for the new URL. auto* faviconDriver = favicon::WebFaviconDriver::FromWebState(webState); if (faviconDriver) - faviconDriver->FetchFavicon(navigation->GetUrl()); + faviconDriver->FetchFavicon(navigation->GetUrl(), + /*is_same_document=*/true); } if (!navigation->GetError()) { @@ -1430,7 +1431,7 @@ favicon::FaviconDriver* faviconDriver = favicon::WebFaviconDriver::FromWebState(webState); if (faviconDriver) - faviconDriver->FetchFavicon(lastCommittedURL); + faviconDriver->FetchFavicon(lastCommittedURL, details.is_in_page); [_parentTabModel notifyTabChanged:self]; if (_parentTabModel) { [[NSNotificationCenter defaultCenter]
diff --git a/ios/chrome/browser/ui/BUILD.gn b/ios/chrome/browser/ui/BUILD.gn index 8d11eacc..a585df6e 100644 --- a/ios/chrome/browser/ui/BUILD.gn +++ b/ios/chrome/browser/ui/BUILD.gn
@@ -269,7 +269,6 @@ "//ios/chrome/browser/ui/overscroll_actions", "//ios/chrome/browser/ui/payments", "//ios/chrome/browser/ui/print", - "//ios/chrome/browser/ui/qr_scanner", "//ios/chrome/browser/ui/reading_list", "//ios/chrome/browser/ui/stack_view", "//ios/chrome/browser/ui/static_content", @@ -399,7 +398,8 @@ "//ios/chrome/browser/ui/overscroll_actions", "//ios/chrome/browser/ui/payments", "//ios/chrome/browser/ui/print", - "//ios/chrome/browser/ui/qr_scanner", + "//ios/chrome/browser/ui/qr_scanner:coordinator", + "//ios/chrome/browser/ui/qr_scanner/requirements", "//ios/chrome/browser/ui/reading_list", "//ios/chrome/browser/ui/stack_view", "//ios/chrome/browser/ui/static_content", @@ -518,6 +518,7 @@ "//base", "//components/strings", "//ios/chrome/app/strings", + "//ios/chrome/browser", "//ios/chrome/browser/ui/commands", "//ios/chrome/browser/ui/ntp:ntp_controller", "//ios/chrome/browser/ui/toolbar",
diff --git a/ios/chrome/browser/ui/authentication/signin_interaction_controller_egtest.mm b/ios/chrome/browser/ui/authentication/signin_interaction_controller_egtest.mm index 64a0a75..b27206f 100644 --- a/ios/chrome/browser/ui/authentication/signin_interaction_controller_egtest.mm +++ b/ios/chrome/browser/ui/authentication/signin_interaction_controller_egtest.mm
@@ -502,6 +502,9 @@ // new tab. Ensures that the sign in screen is correctly dismissed. // Regression test for crbug.com/596029. - (void)testSignInCancelFromBookmarks { + if (experimental_flags::IsBookmarkReorderingEnabled()) { + EARL_GREY_TEST_SKIPPED(@"Only enabled with old Bookmarks UI."); + } ChromeIdentity* identity = GetFakeIdentity1(); ios::FakeChromeIdentityService::GetInstanceFromChromeProvider()->AddIdentity( identity);
diff --git a/ios/chrome/browser/ui/bookmarks/BUILD.gn b/ios/chrome/browser/ui/bookmarks/BUILD.gn index 91ce5d6..a397b9e 100644 --- a/ios/chrome/browser/ui/bookmarks/BUILD.gn +++ b/ios/chrome/browser/ui/bookmarks/BUILD.gn
@@ -57,6 +57,8 @@ "bookmark_promo_controller.mm", "bookmark_signin_promo_cell.h", "bookmark_signin_promo_cell.mm", + "bookmark_table_view.h", + "bookmark_table_view.mm", "bookmark_utils_ios.h", "bookmark_utils_ios.mm", "undo_manager_bridge_observer.h",
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_home_handset_view_controller.mm b/ios/chrome/browser/ui/bookmarks/bookmark_home_handset_view_controller.mm index 03d26d5..2bed4ce 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmark_home_handset_view_controller.mm +++ b/ios/chrome/browser/ui/bookmarks/bookmark_home_handset_view_controller.mm
@@ -15,6 +15,7 @@ #include "ios/chrome/browser/bookmarks/bookmark_model_factory.h" #include "ios/chrome/browser/bookmarks/bookmarks_utils.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" +#include "ios/chrome/browser/experimental_flags.h" #import "ios/chrome/browser/ui/alert_coordinator/action_sheet_coordinator.h" #import "ios/chrome/browser/ui/bookmarks/bars/bookmark_editing_bar.h" #import "ios/chrome/browser/ui/bookmarks/bars/bookmark_navigation_bar.h" @@ -31,6 +32,7 @@ #import "ios/chrome/browser/ui/bookmarks/bookmark_panel_view.h" #import "ios/chrome/browser/ui/bookmarks/bookmark_position_cache.h" #import "ios/chrome/browser/ui/bookmarks/bookmark_promo_controller.h" +#import "ios/chrome/browser/ui/bookmarks/bookmark_table_view.h" #import "ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.h" #include "ios/chrome/browser/ui/ui_util.h" #import "ios/chrome/browser/ui/uikit_ui_util.h" @@ -93,13 +95,15 @@ - (void)viewDidLoad { [super viewDidLoad]; - self.navigationBar.frame = [self navigationBarFrame]; - [self.navigationBar setMenuTarget:self - action:@selector(navigationBarToggledMenu:)]; - [self.navigationBar setCancelTarget:self - action:@selector(navigationBarCancel:)]; - [self.view addSubview:self.navigationBar]; - [self.view bringSubviewToFront:self.navigationBar]; + if (!experimental_flags::IsBookmarkReorderingEnabled()) { + self.navigationBar.frame = [self navigationBarFrame]; + [self.navigationBar setMenuTarget:self + action:@selector(navigationBarToggledMenu:)]; + [self.navigationBar setCancelTarget:self + action:@selector(navigationBarCancel:)]; + [self.view addSubview:self.navigationBar]; + [self.view bringSubviewToFront:self.navigationBar]; + } if (self.bookmarks->loaded()) [self loadBookmarkViews]; @@ -171,36 +175,38 @@ DCHECK(self.bookmarks->loaded()); DCHECK([self isViewLoaded]); - self.menuView.delegate = self; + if (!experimental_flags::IsBookmarkReorderingEnabled()) { + self.menuView.delegate = self; - // Set view frames and add them to hierarchy. - [self.panelView setFrame:[self frameForPanelView]]; - self.panelView.delegate = self; - [self.view insertSubview:self.panelView atIndex:0]; - self.folderView.frame = self.panelView.contentView.bounds; - [self.panelView.contentView addSubview:self.folderView]; - [self.panelView.menuView addSubview:self.menuView]; - [self.menuView setFrame:self.panelView.menuView.bounds]; + // Set view frames and add them to hierarchy. + [self.panelView setFrame:[self frameForPanelView]]; + self.panelView.delegate = self; + [self.view insertSubview:self.panelView atIndex:0]; + self.folderView.frame = self.panelView.contentView.bounds; + [self.panelView.contentView addSubview:self.folderView]; + [self.panelView.menuView addSubview:self.menuView]; + [self.menuView setFrame:self.panelView.menuView.bounds]; - // Load the last primary menu item which the user had active. - BookmarkMenuItem* item = nil; - CGFloat position = 0; - BOOL found = - bookmark_utils_ios::GetPositionCache(self.bookmarks, &item, &position); - if (!found) - item = [self.menuView defaultMenuItem]; + // Load the last primary menu item which the user had active. + BookmarkMenuItem* item = nil; + CGFloat position = 0; + BOOL found = + bookmark_utils_ios::GetPositionCache(self.bookmarks, &item, &position); + if (!found) + item = [self.menuView defaultMenuItem]; - [self updatePrimaryMenuItem:item animated:NO]; + [self updatePrimaryMenuItem:item animated:NO]; - if (found) { - // If the view has already been laid out, then immediately apply the content - // position. - if (self.view.window) { - [self.folderView applyContentPosition:position]; - } else { - // Otherwise, save the position to be applied once the view has been laid - // out. - self.cachedContentPosition = [NSNumber numberWithFloat:position]; + if (found) { + // If the view has already been laid out, then immediately apply the + // content position. + if (self.view.window) { + [self.folderView applyContentPosition:position]; + } else { + // Otherwise, save the position to be applied once the view has been + // laid out. + self.cachedContentPosition = [NSNumber numberWithFloat:position]; + } } } }
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller.h b/ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller.h index 611ea568..7553733 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller.h +++ b/ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller.h
@@ -46,6 +46,9 @@ // Bridge to register for bookmark changes. std::unique_ptr<bookmarks::BookmarkModelBridge> _bridge; + + // The root node, whose child nodes are shown in the bookmark table view. + const bookmarks::BookmarkNode* _rootNode; } - (instancetype)initWithNibName:(NSString*)nibNameOrNil @@ -56,6 +59,9 @@ browserState:(ios::ChromeBrowserState*)browserState NS_DESIGNATED_INITIALIZER; +// Setter to set _rootNode value. +- (void)setRootNode:(const bookmarks::BookmarkNode*)rootNode; + // Delegate for presenters. Note that this delegate is currently being set only // in case of handset, and not tablet. In the future it will be used by both // cases. @@ -65,6 +71,7 @@ // method is currently used in case of handset only. In the future it // will be used by both cases. - (void)dismissModals; +- (void)setRootNode:(const bookmarks::BookmarkNode*)rootNode; @end
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller.mm b/ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller.mm index dc6d4a8a..b01a9f2 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller.mm +++ b/ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller.mm
@@ -10,11 +10,13 @@ #include "ios/chrome/browser/bookmarks/bookmark_model_factory.h" #include "ios/chrome/browser/bookmarks/bookmarks_utils.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" +#include "ios/chrome/browser/experimental_flags.h" #import "ios/chrome/browser/metrics/new_tab_page_uma.h" #import "ios/chrome/browser/ui/alert_coordinator/action_sheet_coordinator.h" #import "ios/chrome/browser/ui/bookmarks/bars/bookmark_editing_bar.h" #import "ios/chrome/browser/ui/bookmarks/bars/bookmark_navigation_bar.h" #import "ios/chrome/browser/ui/bookmarks/bookmark_collection_view.h" +#import "ios/chrome/browser/ui/bookmarks/bookmark_controller_factory.h" #import "ios/chrome/browser/ui/bookmarks/bookmark_edit_view_controller.h" #import "ios/chrome/browser/ui/bookmarks/bookmark_folder_editor_view_controller.h" #import "ios/chrome/browser/ui/bookmarks/bookmark_folder_view_controller.h" @@ -27,6 +29,7 @@ #import "ios/chrome/browser/ui/bookmarks/bookmark_navigation_controller.h" #import "ios/chrome/browser/ui/bookmarks/bookmark_panel_view.h" #import "ios/chrome/browser/ui/bookmarks/bookmark_promo_controller.h" +#import "ios/chrome/browser/ui/bookmarks/bookmark_table_view.h" #import "ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.h" #import "ios/chrome/browser/ui/rtl_geometry.h" #import "ios/chrome/browser/ui/ui_util.h" @@ -50,7 +53,8 @@ BookmarkFolderEditorViewControllerDelegate, BookmarkFolderViewControllerDelegate, BookmarkModelBridgeObserver, - BookmarkPromoControllerDelegate> + BookmarkPromoControllerDelegate, + BookmarkTableViewDelegate> @end @@ -76,6 +80,7 @@ @synthesize sideSwipingPossible = _sideSwipingPossible; @synthesize waitForModelView = _waitForModelView; @synthesize homeDelegate = _homeDelegate; +@synthesize bookmarksTableView = _bookmarksTableView; #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -107,14 +112,22 @@ return self; } +- (void)setRootNode:(const bookmarks::BookmarkNode*)rootNode { + _rootNode = rootNode; +} + #pragma mark - UIViewController - (void)viewDidLoad { [super viewDidLoad]; - self.navigationBar = [[BookmarkNavigationBar alloc] initWithFrame:CGRectZero]; - [self.navigationBar setEditTarget:self - action:@selector(navigationBarWantsEditing:)]; - [self.navigationBar setBackTarget:self action:@selector(navigationBarBack:)]; + if (!experimental_flags::IsBookmarkReorderingEnabled()) { + self.navigationBar = + [[BookmarkNavigationBar alloc] initWithFrame:CGRectZero]; + [self.navigationBar setEditTarget:self + action:@selector(navigationBarWantsEditing:)]; + [self.navigationBar setBackTarget:self + action:@selector(navigationBarBack:)]; + } } #pragma mark - Public @@ -127,32 +140,67 @@ #pragma mark - Protected - (void)loadBookmarkViews { - LayoutRect menuLayout = - LayoutRectMake(0, self.view.bounds.size.width, 0, self.menuWidth, - self.view.bounds.size.height); + if (experimental_flags::IsBookmarkReorderingEnabled()) { + // Set up new UI view. TODO(crbug.com/695749): Polish UI according to mocks. + self.bookmarksTableView = + [[BookmarkTableView alloc] initWithBrowserState:self.browserState + delegate:self + rootNode:_rootNode + frame:self.view.bounds]; + self.bookmarksTableView.autoresizingMask = + UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; - // Create menu view. - self.menuView = [[BookmarkMenuView alloc] - initWithBrowserState:self.browserState - frame:LayoutRectGetRect(menuLayout)]; - self.menuView.autoresizingMask = - UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + // Set up the navigation bar. + NSString* doneTitle = + l10n_util::GetNSString(IDS_IOS_NAVIGATION_BAR_DONE_BUTTON) + .uppercaseString; + UIBarButtonItem* doneButton = + [[UIBarButtonItem alloc] initWithTitle:doneTitle + style:UIBarButtonItemStyleDone + target:self + action:@selector(navigationBarCancel:)]; + self.navigationItem.rightBarButtonItem = doneButton; + self.navigationItem.backBarButtonItem = + [[UIBarButtonItem alloc] initWithTitle:@"" + style:UIBarButtonItemStylePlain + target:nil + action:nil]; + self.navigationItem.title = + bookmark_utils_ios::TitleForBookmarkNode(_rootNode); + self.navigationController.navigationBar.tintColor = UIColor.blackColor; + self.navigationController.navigationBar.backgroundColor = + bookmark_utils_ios::mainBackgroundColor(); - // Create panel view. - self.panelView = [[BookmarkPanelView alloc] initWithFrame:CGRectZero - menuViewWidth:self.menuWidth]; - self.panelView.autoresizingMask = - UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + [self.view addSubview:self.bookmarksTableView]; + } else { + // Set up old UI view. + LayoutRect menuLayout = + LayoutRectMake(0, self.view.bounds.size.width, 0, self.menuWidth, + self.view.bounds.size.height); - // Create folder view. - BookmarkCollectionView* view = - [[BookmarkCollectionView alloc] initWithBrowserState:self.browserState - frame:CGRectZero]; - self.folderView = view; - [self.folderView setEditing:self.editing animated:NO]; - self.folderView.autoresizingMask = - UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; - self.folderView.delegate = self; + // Create menu view. + self.menuView = [[BookmarkMenuView alloc] + initWithBrowserState:self.browserState + frame:LayoutRectGetRect(menuLayout)]; + self.menuView.autoresizingMask = + UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + + // Create panel view. + self.panelView = [[BookmarkPanelView alloc] initWithFrame:CGRectZero + menuViewWidth:self.menuWidth]; + self.panelView.autoresizingMask = + UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + + // Create folder view. + BookmarkCollectionView* view = + [[BookmarkCollectionView alloc] initWithBrowserState:self.browserState + frame:CGRectZero]; + self.folderView = view; + [self.folderView setEditing:self.editing animated:NO]; + self.folderView.autoresizingMask = + UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; + self.folderView.delegate = self; + } } - (void)updatePrimaryMenuItem:(BookmarkMenuItem*)menuItem @@ -344,6 +392,26 @@ [self updatePrimaryMenuItem:menuItem animated:YES]; } +#pragma mark - BookmarkTableViewDelegate + +- (void)bookmarkTableView:(BookmarkTableView*)view + selectedUrlForNavigation:(const GURL&)url { + [self dismissWithURL:url]; +} + +- (void)bookmarkTableView:(BookmarkTableView*)view + selectedFolderForNavigation:(const bookmarks::BookmarkNode*)folder { + BookmarkControllerFactory* bookmarkControllerFactory = + [[BookmarkControllerFactory alloc] init]; + BookmarkHomeViewController* controller = + (BookmarkHomeViewController*)[bookmarkControllerFactory + bookmarkControllerWithBrowserState:self.browserState + loader:_loader]; + [controller setRootNode:folder]; + controller.homeDelegate = self.homeDelegate; + [self.navigationController pushViewController:controller animated:YES]; +} + #pragma mark - BookmarkFolderViewControllerDelegate - (void)folderPicker:(BookmarkFolderViewController*)folderPicker
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller_protected.h b/ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller_protected.h index 5637238..0279c3b 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller_protected.h +++ b/ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller_protected.h
@@ -24,6 +24,7 @@ @class BookmarkNavigationBar; @class BookmarkPanelView; @class BookmarkPromoController; +@class BookmarkTableView; // BookmarkHomeViewController class extension for protected read/write // properties and methods for subclasses. @@ -38,6 +39,9 @@ // The main view showing all the bookmarks. @property(nonatomic, strong) BookmarkCollectionView* folderView; +// The main view showing all the bookmarks. +@property(nonatomic, strong) BookmarkTableView* bookmarksTableView; + // The view controller used to pick a folder in which to move the selected // bookmarks. @property(nonatomic, strong) BookmarkFolderViewController* folderSelector;
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_interaction_controller.mm b/ios/chrome/browser/ui/bookmarks/bookmark_interaction_controller.mm index 71663324..010052c 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmark_interaction_controller.mm +++ b/ios/chrome/browser/ui/bookmarks/bookmark_interaction_controller.mm
@@ -19,6 +19,7 @@ #include "components/prefs/pref_service.h" #include "ios/chrome/browser/bookmarks/bookmark_model_factory.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" +#include "ios/chrome/browser/experimental_flags.h" #import "ios/chrome/browser/metrics/new_tab_page_uma.h" #include "ios/chrome/browser/pref_names.h" #import "ios/chrome/browser/tabs/tab.h" @@ -228,10 +229,21 @@ bookmarkControllerWithBrowserState:_currentBrowserState loader:_loader]; self.bookmarkBrowser.homeDelegate = self; - self.bookmarkBrowser.modalPresentationStyle = UIModalPresentationFormSheet; - [_parentController presentViewController:self.bookmarkBrowser - animated:YES - completion:nil]; + + if (experimental_flags::IsBookmarkReorderingEnabled()) { + UINavigationController* navController = [[UINavigationController alloc] + initWithRootViewController:self.bookmarkBrowser]; + [self.bookmarkBrowser setRootNode:self.bookmarkModel->root_node()]; + [navController setModalPresentationStyle:UIModalPresentationFormSheet]; + [_parentController presentViewController:navController + animated:YES + completion:nil]; + } else { + self.bookmarkBrowser.modalPresentationStyle = UIModalPresentationFormSheet; + [_parentController presentViewController:self.bookmarkBrowser + animated:YES + completion:nil]; + } } - (void)dismissBookmarkBrowserAnimated:(BOOL)animated {
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_table_view.h b/ios/chrome/browser/ui/bookmarks/bookmark_table_view.h new file mode 100644 index 0000000..03b955ac --- /dev/null +++ b/ios/chrome/browser/ui/bookmarks/bookmark_table_view.h
@@ -0,0 +1,51 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_BOOKMARKS_BOOKMARK_TABLE_VIEW_H_ +#define IOS_CHROME_BROWSER_UI_BOOKMARKS_BOOKMARK_TABLE_VIEW_H_ + +#import <UIKit/UIKit.h> + +class GURL; + +namespace bookmarks { +class BookmarkNode; +} // namespace bookmarks + +namespace ios { +class ChromeBrowserState; +} + +@class BookmarkNavBar; +@class BookmarkTableView; + +// Delegate to handle actions on the table. +@protocol BookmarkTableViewDelegate<NSObject> +// Tells the delegate that a URL was selected for navigation. +- (void)bookmarkTableView:(BookmarkTableView*)view + selectedUrlForNavigation:(const GURL&)url; + +// Tells the delegate that a Folder was selected for navigation. +- (void)bookmarkTableView:(BookmarkTableView*)view + selectedFolderForNavigation:(const bookmarks::BookmarkNode*)folder; + +@end + +@interface BookmarkTableView : UIView + +- (instancetype)initWithBrowserState:(ios::ChromeBrowserState*)browserState + delegate:(id<BookmarkTableViewDelegate>)delegate + rootNode:(const bookmarks::BookmarkNode*)rootNode + frame:(CGRect)frame NS_DESIGNATED_INITIALIZER; + +- (instancetype)initWithFrame:(CGRect)frame NS_UNAVAILABLE; +- (instancetype)initWithFrame:(CGRect)frame + style:(UITableViewStyle)style NS_UNAVAILABLE; +- (instancetype)initWithCoder:(NSCoder*)aDecoder NS_UNAVAILABLE; +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype) new NS_UNAVAILABLE; + +@end + +#endif // IOS_CHROME_BROWSER_UI_BOOKMARKS_BOOKMARK_TABLE_VIEW_H_
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_table_view.mm b/ios/chrome/browser/ui/bookmarks/bookmark_table_view.mm new file mode 100644 index 0000000..80d0a20 --- /dev/null +++ b/ios/chrome/browser/ui/bookmarks/bookmark_table_view.mm
@@ -0,0 +1,188 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/ui/bookmarks/bookmark_table_view.h" + +#include "components/bookmarks/browser/bookmark_model.h" +#include "ios/chrome/browser/bookmarks/bookmark_model_factory.h" +#include "ios/chrome/browser/bookmarks/bookmarks_utils.h" +#include "ios/chrome/browser/ui/bookmarks/bookmark_collection_view_background.h" +#import "ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.h" +#include "ios/chrome/grit/ios_strings.h" +#include "ui/base/l10n/l10n_util_mac.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +using bookmarks::BookmarkNode; + +@interface BookmarkTableView ()<UITableViewDataSource, UITableViewDelegate> { + // A vector of bookmark nodes to display in the table view. + std::vector<const BookmarkNode*> _bookmarkItems; + const BookmarkNode* _currentRootNode; +} + +// The UITableView to show bookmarks. +@property(nonatomic, strong) UITableView* tableView; +// The model holding bookmark data. +@property(nonatomic, assign) bookmarks::BookmarkModel* bookmarkModel; +// The browser state. +@property(nonatomic, assign) ios::ChromeBrowserState* browserState; +// The delegate for actions on the table. +@property(nonatomic, assign) id<BookmarkTableViewDelegate> delegate; +// Background view of the collection view shown when there is no items. +@property(nonatomic, strong) + BookmarkCollectionViewBackground* emptyTableBackgroundView; + +@end + +@implementation BookmarkTableView + +@synthesize bookmarkModel = _bookmarkModel; +@synthesize browserState = _browserState; +@synthesize tableView = _tableView; +@synthesize delegate = _delegate; +@synthesize emptyTableBackgroundView = _emptyTableBackgroundView; + +// TODO(crbug.com/695749) Add promo section, bottom context bar, +// promo view and register kIosBookmarkSigninPromoDisplayedCount. + +- (instancetype)initWithBrowserState:(ios::ChromeBrowserState*)browserState + delegate:(id<BookmarkTableViewDelegate>)delegate + rootNode:(const BookmarkNode*)rootNode + frame:(CGRect)frame { + self = [super initWithFrame:frame]; + if (self) { + _browserState = browserState; + _delegate = delegate; + _currentRootNode = rootNode; + + // Set up connection to the BookmarkModel. + _bookmarkModel = + ios::BookmarkModelFactory::GetForBrowserState(browserState); + [self computeBookmarkTableViewData]; + + self.tableView = + [[UITableView alloc] initWithFrame:frame style:UITableViewStylePlain]; + self.tableView.dataSource = self; + self.tableView.delegate = self; + // Remove extra rows. + self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero]; + self.tableView.autoresizingMask = + UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + [self addSubview:self.tableView]; + [self bringSubviewToFront:self.tableView]; + + // Set up the background view shown when the table is empty. + self.emptyTableBackgroundView = + [[BookmarkCollectionViewBackground alloc] initWithFrame:frame]; + self.emptyTableBackgroundView.autoresizingMask = + UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; + self.emptyTableBackgroundView.text = + l10n_util::GetNSString(IDS_IOS_BOOKMARK_NO_BOOKMARKS_LABEL); + self.emptyTableBackgroundView.alpha = + _currentRootNode->child_count() == 0 ? 1 : 0; + [self addSubview:self.emptyTableBackgroundView]; + } + return self; +} + +#pragma mark - UITableViewDataSource + +- (NSInteger)numberOfSectionsInTableView:(UITableView*)tableView { + // TODO(crbug.com/695749) Add promo section check here. + return 1; +} + +- (NSInteger)tableView:(UITableView*)tableView + numberOfRowsInSection:(NSInteger)section { + // TODO(crbug.com/695749) Add promo section check here. + return _bookmarkItems.size(); +} + +- (UITableViewCell*)tableView:(UITableView*)tableView + cellForRowAtIndexPath:(NSIndexPath*)indexPath { + const BookmarkNode* node = [self nodeAtIndexPath:indexPath]; + static NSString* bookmarkCellIdentifier = @"bookmarkCellIdentifier"; + + // TODO(crbug.com/695749) Use custom cells. + UITableViewCell* cell = + [tableView dequeueReusableCellWithIdentifier:bookmarkCellIdentifier]; + + if (cell == nil) { + cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault + reuseIdentifier:bookmarkCellIdentifier]; + } + + cell.textLabel.text = bookmark_utils_ios::TitleForBookmarkNode(node); + if (node->is_folder()) { + [cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator]; + } else { + [cell setAccessoryType:UITableViewCellAccessoryNone]; + } + return cell; +} + +- (BOOL)tableView:(UITableView*)tableView + canEditRowAtIndexPath:(NSIndexPath*)indexPath { + return YES; +} + +- (void)tableView:(UITableView*)tableView + commitEditingStyle:(UITableViewCellEditingStyle)editingStyle + forRowAtIndexPath:(NSIndexPath*)indexPath { + if (editingStyle == UITableViewCellEditingStyleDelete) { + // TODO(crbug.com/695749) Implement the deletion of bookmark/folder and + // insertion of folder here. + } +} + +#pragma mark - UITableViewDelegate + +- (void)tableView:(UITableView*)tableView + didSelectRowAtIndexPath:(NSIndexPath*)indexPath { + // TODO(crbug.com/695749) Add promo section check here. + const BookmarkNode* node = [self nodeAtIndexPath:indexPath]; + DCHECK(node); + if (node->is_folder()) { + [self.delegate bookmarkTableView:self selectedFolderForNavigation:node]; + } else { + // Open URL. Pass this to the delegate. + [self.delegate bookmarkTableView:self selectedUrlForNavigation:node->url()]; + } +} + +#pragma mark - Private + +// Returns the bookmark node associated with |indexPath|. +- (const BookmarkNode*)nodeAtIndexPath:(NSIndexPath*)indexPath { + // TODO(crbug.com/695749) Add check if section is bookmarks. + return _bookmarkItems[indexPath.row]; + + NOTREACHED(); + return nullptr; +} + +// Computes the bookmarks table view based on the current root node. +- (void)computeBookmarkTableViewData { + if (!self.bookmarkModel->loaded()) + return; + + // Regenerate the list of all bookmarks, if current root node is not set, + // then reset to model's root node. + if (!_currentRootNode) { + _currentRootNode = self.bookmarkModel->root_node(); + } + if (_currentRootNode) { + _bookmarkItems.clear(); + int childCount = _currentRootNode->child_count(); + for (int i = 0; i < childCount; ++i) { + const BookmarkNode* node = _currentRootNode->GetChild(i); + _bookmarkItems.push_back(node); + } + } +} + +@end
diff --git a/ios/chrome/browser/ui/bookmarks/bookmarks_egtest.mm b/ios/chrome/browser/ui/bookmarks/bookmarks_egtest.mm index bb64711..50d2b702 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmarks_egtest.mm +++ b/ios/chrome/browser/ui/bookmarks/bookmarks_egtest.mm
@@ -219,6 +219,9 @@ // Tests that tapping a bookmark on the NTP navigates to the proper URL. - (void)testTapBookmark { + if (experimental_flags::IsBookmarkReorderingEnabled()) { + EARL_GREY_TEST_SKIPPED(@"Only enabled with old UI."); + } const GURL bookmarkURL = web::test::HttpServer::MakeUrl( "http://ios/testing/data/http_server_files/destination.html"); NSString* bookmarkTitle = @"smokeTapBookmark"; @@ -279,6 +282,9 @@ // Try deleting a bookmark, then undoing that delete. - (void)testUndoDeleteBookmark { + if (experimental_flags::IsBookmarkReorderingEnabled()) { + EARL_GREY_TEST_SKIPPED(@"Only enabled with old UI."); + } [BookmarksTestCase setupStandardBookmarks]; [BookmarksTestCase openMobileBookmarks]; @@ -304,6 +310,9 @@ // Try deleting a bookmark from the edit screen, then undoing that delete. - (void)testUndoDeleteBookmarkFromEditScreen { + if (experimental_flags::IsBookmarkReorderingEnabled()) { + EARL_GREY_TEST_SKIPPED(@"Only enabled with old UI."); + } [BookmarksTestCase setupStandardBookmarks]; [BookmarksTestCase openMobileBookmarks]; @@ -341,6 +350,9 @@ // Try moving bookmarks, then undoing that move. - (void)testUndoMoveBookmark { + if (experimental_flags::IsBookmarkReorderingEnabled()) { + EARL_GREY_TEST_SKIPPED(@"Only enabled with old UI."); + } [BookmarksTestCase setupStandardBookmarks]; [BookmarksTestCase openMobileBookmarks]; @@ -393,6 +405,9 @@ } - (void)testLabelUpdatedUponMove { + if (experimental_flags::IsBookmarkReorderingEnabled()) { + EARL_GREY_TEST_SKIPPED(@"Only enabled with old UI."); + } [BookmarksTestCase setupStandardBookmarks]; [BookmarksTestCase openMobileBookmarks]; @@ -476,6 +491,9 @@ // Tests that changing a folder's title in edit mode works as expected. - (void)testChangeFolderTitle { + if (experimental_flags::IsBookmarkReorderingEnabled()) { + EARL_GREY_TEST_SKIPPED(@"Only enabled with old UI."); + } NSString* existingFolderTitle = @"Folder 1"; NSString* newFolderTitle = @"New Folder Title"; @@ -502,6 +520,9 @@ // Tests that the default folder bookmarks are saved in is updated to the last // used folder. - (void)testStickyDefaultFolder { + if (experimental_flags::IsBookmarkReorderingEnabled()) { + EARL_GREY_TEST_SKIPPED(@"Only enabled with old UI."); + } [BookmarksTestCase setupStandardBookmarks]; [BookmarksTestCase openMobileBookmarks]; @@ -577,6 +598,9 @@ // Tests that changes to the parent folder from the Single Bookmark Controller // are saved to the bookmark only when saving the results. - (void)testMoveDoesSaveOnSave { + if (experimental_flags::IsBookmarkReorderingEnabled()) { + EARL_GREY_TEST_SKIPPED(@"Only enabled with old UI."); + } [BookmarksTestCase setupStandardBookmarks]; [BookmarksTestCase openTopLevelBookmarksFolder]; @@ -626,6 +650,9 @@ // Test thats editing a single bookmark correctly persists data. - (void)testSingleBookmarkEdit { + if (experimental_flags::IsBookmarkReorderingEnabled()) { + EARL_GREY_TEST_SKIPPED(@"Only enabled with old UI."); + } [BookmarksTestCase setupStandardBookmarks]; [BookmarksTestCase openTopLevelBookmarksFolder]; @@ -660,6 +687,9 @@ // Tests that cancelling editing a single bookmark correctly doesn't persist // data. - (void)testSingleBookmarkCancelEdit { + if (experimental_flags::IsBookmarkReorderingEnabled()) { + EARL_GREY_TEST_SKIPPED(@"Only enabled with old UI."); + } [BookmarksTestCase setupStandardBookmarks]; [BookmarksTestCase openTopLevelBookmarksFolder]; @@ -693,6 +723,9 @@ // Tests that long pressing a bookmark selects it and gives access to editing, // as does the Info menu. - (void)testLongPressBookmark { + if (experimental_flags::IsBookmarkReorderingEnabled()) { + EARL_GREY_TEST_SKIPPED(@"Only enabled with old UI."); + } [BookmarksTestCase setupStandardBookmarks]; [BookmarksTestCase openTopLevelBookmarksFolder]; @@ -723,6 +756,9 @@ // Tests the editing of a folder. - (void)testEditFolder { + if (experimental_flags::IsBookmarkReorderingEnabled()) { + EARL_GREY_TEST_SKIPPED(@"Only enabled with old UI."); + } [BookmarksTestCase setupStandardBookmarks]; [BookmarksTestCase openBookmarkFolder:@"Folder 1"]; @@ -759,6 +795,9 @@ // Tests the deletion of a folder. - (void)testDeleteFolder { + if (experimental_flags::IsBookmarkReorderingEnabled()) { + EARL_GREY_TEST_SKIPPED(@"Only enabled with old UI."); + } [BookmarksTestCase setupStandardBookmarks]; [BookmarksTestCase openBookmarkFolder:@"Folder 1"]; @@ -772,6 +811,9 @@ // Navigates to a deeply nested folder, deletes it and makes sure the UI is // consistent. - (void)testDeleteCurrentSubfolder { + if (experimental_flags::IsBookmarkReorderingEnabled()) { + EARL_GREY_TEST_SKIPPED(@"Only enabled with old UI."); + } [BookmarksTestCase setupStandardBookmarks]; [BookmarksTestCase openBookmarkFolder:@"Folder 1"]; [[EarlGrey selectElementWithMatcher:ButtonWithAccessibilityLabel(@"Folder 2")] @@ -794,6 +836,9 @@ // Navigates to a deeply nested folder, delete its parent programatically. // Verifies that the UI is as expected. - (void)testDeleteParentFolder { + if (experimental_flags::IsBookmarkReorderingEnabled()) { + EARL_GREY_TEST_SKIPPED(@"Only enabled with old UI."); + } [BookmarksTestCase setupStandardBookmarks]; [BookmarksTestCase openBookmarkFolder:@"Folder 1"]; [[EarlGrey selectElementWithMatcher:ButtonWithAccessibilityLabel(@"Folder 2")] @@ -837,6 +882,9 @@ // Tests that the menu button changes to a back button as expected when browsing // nested folders. - (void)testBrowseNestedFolders { + if (experimental_flags::IsBookmarkReorderingEnabled()) { + EARL_GREY_TEST_SKIPPED(@"Only enabled with old UI."); + } [BookmarksTestCase setupStandardBookmarks]; [BookmarksTestCase openMobileBookmarks]; @@ -877,6 +925,9 @@ // Tests moving a bookmark into a new folder created in the moving process. - (void)testCreateNewFolderWhileMovingBookmark { + if (experimental_flags::IsBookmarkReorderingEnabled()) { + EARL_GREY_TEST_SKIPPED(@"Only enabled with old UI."); + } [BookmarksTestCase setupStandardBookmarks]; [BookmarksTestCase openMobileBookmarks]; @@ -956,6 +1007,9 @@ // Navigates to a deeply nested folder, deletes its root ancestor and checks // that the UI is on the top level folder. - (void)testDeleteRootFolder { + if (experimental_flags::IsBookmarkReorderingEnabled()) { + EARL_GREY_TEST_SKIPPED(@"Only enabled with old UI."); + } [BookmarksTestCase setupStandardBookmarks]; [BookmarksTestCase openBookmarkFolder:@"Folder 1"]; [[EarlGrey selectElementWithMatcher:grey_text(@"Folder 2")] @@ -1039,6 +1093,9 @@ // Tests that tapping No thanks on the promo make it disappear. - (void)testPromoNoThanksMakeItDisappear { + if (experimental_flags::IsBookmarkReorderingEnabled()) { + EARL_GREY_TEST_SKIPPED(@"Only enabled with old UI."); + } [BookmarksTestCase setupStandardBookmarks]; [BookmarksTestCase openTopLevelBookmarksFolder]; @@ -1068,6 +1125,9 @@ // Tests that tapping Sign in on the promo make the Sign in sheet appear and // the promo still appears after dismissing the Sign in sheet. - (void)testUIPromoSignIn { + if (experimental_flags::IsBookmarkReorderingEnabled()) { + EARL_GREY_TEST_SKIPPED(@"Only enabled with old UI."); + } [BookmarksTestCase setupStandardBookmarks]; [BookmarksTestCase openTopLevelBookmarksFolder]; // Set up a fake identity. @@ -1103,6 +1163,9 @@ // Tests that all elements on the bookmarks landing page are accessible. - (void)testAccessibilityOnBookmarksLandingPage { + if (experimental_flags::IsBookmarkReorderingEnabled()) { + EARL_GREY_TEST_SKIPPED(@"Only enabled with old UI."); + } [BookmarksTestCase openMobileBookmarksPrepopulatedWithOneBookmark]; chrome_test_util::VerifyAccessibilityForCurrentScreen(); @@ -1115,6 +1178,9 @@ // Tests that all elements on the bookmarks Edit page are accessible. - (void)testAccessibilityOnBookmarksEditPage { + if (experimental_flags::IsBookmarkReorderingEnabled()) { + EARL_GREY_TEST_SKIPPED(@"Only enabled with old UI."); + } [BookmarksTestCase openMobileBookmarksPrepopulatedWithOneBookmark]; // Load the menu for a bookmark. @@ -1136,6 +1202,9 @@ // Tests that all elements on the bookmarks Move page are accessible. - (void)testAccessibilityOnBookmarksMovePage { + if (experimental_flags::IsBookmarkReorderingEnabled()) { + EARL_GREY_TEST_SKIPPED(@"Only enabled with old UI."); + } [BookmarksTestCase openMobileBookmarksPrepopulatedWithOneBookmark]; // Load the menu for a bookmark. @@ -1158,6 +1227,9 @@ // Tests that all elements on the bookmarks Move to New Folder page are // accessible. - (void)testAccessibilityOnBookmarksMoveToNewFolderPage { + if (experimental_flags::IsBookmarkReorderingEnabled()) { + EARL_GREY_TEST_SKIPPED(@"Only enabled with old UI."); + } [BookmarksTestCase openMobileBookmarksPrepopulatedWithOneBookmark]; // Load the menu for a bookmark. @@ -1183,6 +1255,9 @@ // Tests that all elements on bookmarks Delete and Undo are accessible. - (void)testAccessibilityOnBookmarksDeleteUndo { + if (experimental_flags::IsBookmarkReorderingEnabled()) { + EARL_GREY_TEST_SKIPPED(@"Only enabled with old UI."); + } [BookmarksTestCase openMobileBookmarksPrepopulatedWithOneBookmark]; // Load the menu for a bookmark. @@ -1202,6 +1277,9 @@ // Tests that all elements on the bookmarks Select page are accessible. - (void)testAccessibilityOnBookmarksSelect { + if (experimental_flags::IsBookmarkReorderingEnabled()) { + EARL_GREY_TEST_SKIPPED(@"Only enabled with old UI."); + } [BookmarksTestCase openMobileBookmarksPrepopulatedWithOneBookmark]; // Load the menu for a bookmark. @@ -1237,6 +1315,15 @@ // Navigates to the bookmark manager UI, and selects |bookmarkFolder|. + (void)openBookmarkFolder:(NSString*)bookmarkFolder { [BookmarksTestCase openBookmarks]; + if (experimental_flags::IsBookmarkReorderingEnabled()) { + [[EarlGrey + selectElementWithMatcher:grey_allOf(grey_kindOfClass(NSClassFromString( + @"UITableViewCell")), + grey_descendant( + grey_text(@"Mobile Bookmarks")), + nil)] performAction:grey_tap()]; + return; + } if (IsCompact()) { // Opens the bookmark manager sidebar on handsets. [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Menu")]
diff --git a/ios/chrome/browser/ui/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view_controller.mm index 5f25134..dc388e0 100644 --- a/ios/chrome/browser/ui/browser_view_controller.mm +++ b/ios/chrome/browser/ui/browser_view_controller.mm
@@ -135,7 +135,8 @@ #import "ios/chrome/browser/ui/page_not_available_controller.h" #import "ios/chrome/browser/ui/payments/payment_request_manager.h" #import "ios/chrome/browser/ui/print/print_controller.h" -#import "ios/chrome/browser/ui/qr_scanner/qr_scanner_view_controller.h" +#import "ios/chrome/browser/ui/qr_scanner/qr_scanner_legacy_coordinator.h" +#import "ios/chrome/browser/ui/qr_scanner/requirements/qr_scanner_presenting.h" #import "ios/chrome/browser/ui/reading_list/offline_page_native_content.h" #import "ios/chrome/browser/ui/reading_list/reading_list_coordinator.h" #import "ios/chrome/browser/ui/reading_list/reading_list_menu_notifier.h" @@ -356,6 +357,7 @@ OverscrollActionsControllerDelegate, PassKitDialogProvider, PreloadControllerDelegate, + QRScannerPresenting, SKStoreProductViewControllerDelegate, SnapshotOverlayProvider, StoreKitLauncher, @@ -425,9 +427,6 @@ // Used to display the Voice Search UI. Nil if not visible. scoped_refptr<VoiceSearchController> _voiceSearchController; - // Used to display the QR Scanner UI. Nil if not visible. - QRScannerViewController* _qrScannerViewController; - // Used to display the Reading List. ReadingListCoordinator* _readingListCoordinator; @@ -525,6 +524,9 @@ // Coordinator for displaying alerts. AlertCoordinator* _alertCoordinator; + // Coordinator for the QR scanner. + QRScannerLegacyCoordinator* _qrScannerCoordinator; + // Coordinator for Tab History Popup. TabHistoryCoordinator* _tabHistoryCoordinator; } @@ -1357,7 +1359,6 @@ self.typingShield = nil; if (_voiceSearchController) _voiceSearchController->SetDelegate(nil); - _qrScannerViewController = nil; _readingListCoordinator = nil; _toolbarController = nil; _toolbarModelDelegate = nil; @@ -1740,6 +1741,7 @@ // Disconnect child coordinators. [_activityServiceCoordinator disconnect]; + [_qrScannerCoordinator disconnect]; [_tabHistoryCoordinator disconnect]; // The file remover needs the browser state, so needs to be destroyed now. @@ -1847,6 +1849,12 @@ _activityServiceCoordinator.presentationProvider = self; _activityServiceCoordinator.snackbarProvider = self; + _qrScannerCoordinator = + [[QRScannerLegacyCoordinator alloc] initWithBaseViewController:self]; + _qrScannerCoordinator.dispatcher = _dispatcher; + _qrScannerCoordinator.loadProvider = _toolbarController; + _qrScannerCoordinator.presentationProvider = self; + _tabHistoryCoordinator = [[TabHistoryCoordinator alloc] initWithBaseViewController:self]; _tabHistoryCoordinator.dispatcher = _dispatcher; @@ -4248,15 +4256,6 @@ [self addToReadingListURL:[command URL] title:[command title]]; } -- (void)showQRScanner { - _qrScannerViewController = - [[QRScannerViewController alloc] initWithDelegate:_toolbarController]; - [self presentViewController:[_qrScannerViewController - getViewControllerToPresent] - animated:YES - completion:nil]; -} - - (void)showReadingList { _readingListCoordinator = [[ReadingListCoordinator alloc] initWithBaseViewController:self @@ -5134,6 +5133,18 @@ [self.dialogPresenter tryToPresent]; } +#pragma mark - QRScanner Requirements + +- (void)presentQRScannerViewController:(UIViewController*)controller { + [self presentViewController:controller animated:YES completion:nil]; +} + +- (void)dismissQRScannerViewController:(UIViewController*)controller + completion:(void (^)(void))completion { + DCHECK_EQ(controller, self.presentedViewController); + [self dismissViewControllerAnimated:YES completion:completion]; +} + #pragma mark - TabHistoryPresenter - (void)prepareForTabHistoryPresentation {
diff --git a/ios/chrome/browser/ui/commands/BUILD.gn b/ios/chrome/browser/ui/commands/BUILD.gn index 3f20de2..d165a0b 100644 --- a/ios/chrome/browser/ui/commands/BUILD.gn +++ b/ios/chrome/browser/ui/commands/BUILD.gn
@@ -20,6 +20,7 @@ "open_new_tab_command.mm", "open_url_command.h", "open_url_command.mm", + "qr_scanner_commands.h", "reading_list_add_command.h", "reading_list_add_command.mm", "show_mail_composer_command.h",
diff --git a/ios/chrome/browser/ui/commands/browser_commands.h b/ios/chrome/browser/ui/commands/browser_commands.h index 990c7758..05f87669 100644 --- a/ios/chrome/browser/ui/commands/browser_commands.h +++ b/ios/chrome/browser/ui/commands/browser_commands.h
@@ -9,14 +9,17 @@ #import "ios/chrome/browser/ui/commands/activity_service_commands.h" #import "ios/chrome/browser/ui/commands/history_popup_commands.h" +#import "ios/chrome/browser/ui/commands/qr_scanner_commands.h" @class OpenNewTabCommand; @class ReadingListAddCommand; // Protocol for commands that will generally be handled by the "current tab", // which in practice is the BrowserViewController instance displaying the tab. -@protocol - BrowserCommands<NSObject, ActivityServiceCommands, TabHistoryPopupCommands> +@protocol BrowserCommands<NSObject, + ActivityServiceCommands, + QRScannerCommands, + TabHistoryPopupCommands> // Closes the current tab. - (void)closeCurrentTab; @@ -48,9 +51,6 @@ // Adds a page to the reading list using data in |command|. - (void)addToReadingList:(ReadingListAddCommand*)command; -// Shows the QR scanner UI. -- (void)showQRScanner; - // Shows the Reading List UI. - (void)showReadingList;
diff --git a/ios/chrome/browser/ui/commands/qr_scanner_commands.h b/ios/chrome/browser/ui/commands/qr_scanner_commands.h new file mode 100644 index 0000000..012c2d69 --- /dev/null +++ b/ios/chrome/browser/ui/commands/qr_scanner_commands.h
@@ -0,0 +1,16 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_COMMANDS_QR_SCANNER_COMMANDS_H_ +#define IOS_CHROME_BROWSER_UI_COMMANDS_QR_SCANNER_COMMANDS_H_ + +// QRScannerCommands contains commands related to scanning QR codes. +@protocol QRScannerCommands<NSObject> + +// Shows the QR scanner UI. +- (void)showQRScanner; + +@end + +#endif // IOS_CHROME_BROWSER_UI_COMMANDS_QR_SCANNER_COMMANDS_H_
diff --git a/ios/chrome/browser/ui/content_suggestions/BUILD.gn b/ios/chrome/browser/ui/content_suggestions/BUILD.gn index 36777211..f19a502 100644 --- a/ios/chrome/browser/ui/content_suggestions/BUILD.gn +++ b/ios/chrome/browser/ui/content_suggestions/BUILD.gn
@@ -50,6 +50,8 @@ sources = [ "content_suggestions_collection_utils.h", "content_suggestions_collection_utils.mm", + "ntp_home_constant.h", + "ntp_home_constant.mm", ] deps = [ "//base", @@ -93,9 +95,13 @@ testonly = true sources = [ "content_suggestions_egtest.mm", + "ntp_home_egtest.mm", + "ntp_home_provider_test_singleton.h", + "ntp_home_provider_test_singleton.mm", ] deps = [ ":content_suggestions", + ":content_suggestions_util", "//base", "//base/test:test_support", "//components/keyed_service/ios",
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_updater.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_updater.mm index 967abb0..5aa5a63 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_updater.mm +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_updater.mm
@@ -343,6 +343,8 @@ NSInteger sectionIdentifier = SectionIdentifierForInfo(sectionInfo); if (suggestions.count == 0) { + // No suggestions for this section. Add the item signaling this section is + // empty if there is currently no item in it. if ([model hasSectionForSectionIdentifier:sectionIdentifier] && [model numberOfItemsInSection:[model sectionForSectionIdentifier: sectionIdentifier]] == 0) { @@ -356,6 +358,35 @@ return indexPaths; } + if (sectionIdentifier == SectionIdentifierLearnMore) { + // The "Learn more" items should only be displayed if there is at least one + // ContentSuggestions section. + if ((![model hasSectionForSectionIdentifier:SectionIdentifierArticles] && + ! + [model hasSectionForSectionIdentifier:SectionIdentifierReadingList]) || + [model itemsInSectionWithIdentifier:sectionIdentifier].count > 0) { + return @[]; + } + } else if (IsFromContentSuggestions(sectionIdentifier)) { + // If the section is a ContentSuggestions section, add the "Learn more" + // items if they are not already present. + if ([model hasSectionForSectionIdentifier:SectionIdentifierLearnMore] && + [model itemsInSectionWithIdentifier:SectionIdentifierLearnMore].count == + 0) { + ContentSuggestionsSectionInformation* learnMoreSectionInfo = + self.sectionInfoBySectionIdentifier[@(SectionIdentifierLearnMore)]; + for (CSCollectionViewItem* item in + [self.dataSource itemsForSectionInfo:learnMoreSectionInfo]) { + item.type = ItemTypeForInfo(learnMoreSectionInfo); + NSIndexPath* addedIndexPath = [self addItem:item + toSectionWithIdentifier:SectionIdentifierLearnMore]; + + [indexPaths addObject:addedIndexPath]; + } + } + } + + // Add the items from this section. [suggestions enumerateObjectsUsingBlock:^(CSCollectionViewItem* item, NSUInteger index, BOOL* stop) { NSInteger section = [model sectionForSectionIdentifier:sectionIdentifier];
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_egtest.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_egtest.mm index 528d263..56d462a 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_egtest.mm +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_egtest.mm
@@ -25,6 +25,7 @@ #include "ios/chrome/browser/reading_list/reading_list_model_factory.h" #import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_learn_more_item.h" #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.h" +#import "ios/chrome/browser/ui/content_suggestions/ntp_home_provider_test_singleton.h" #include "ios/chrome/browser/ui/ui_util.h" #include "ios/chrome/grit/ios_strings.h" #import "ios/chrome/test/app/chrome_test_util.h" @@ -73,53 +74,11 @@ } // namespace -// Singleton allowing to register the provider in the +setup and still access it -// from inside the tests. -@interface ContentSuggestionsTestSingleton : NSObject - -// Shared instance of this singleton. -+ (instancetype)sharedInstance; - -// Returns the provider registered. -- (MockContentSuggestionsProvider*)provider; -// Registers a provider in the |service|. -- (void)registerArticleProvider:(ContentSuggestionsService*)service; - -@end - -@implementation ContentSuggestionsTestSingleton { - MockContentSuggestionsProvider* _provider; -} - -+ (instancetype)sharedInstance { - static ContentSuggestionsTestSingleton* sharedInstance = nil; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - sharedInstance = [[self alloc] init]; - }); - return sharedInstance; -} - -- (MockContentSuggestionsProvider*)provider { - return _provider; -} - -- (void)registerArticleProvider:(ContentSuggestionsService*)service { - Category articles = Category::FromKnownCategory(KnownCategories::ARTICLES); - std::unique_ptr<MockContentSuggestionsProvider> provider = - base::MakeUnique<MockContentSuggestionsProvider>( - service, std::vector<Category>{articles}); - _provider = provider.get(); - service->RegisterProvider(std::move(provider)); -} - -@end - #pragma mark - TestCase // Test case for the ContentSuggestion UI. @interface ContentSuggestionsTestCase : ChromeTestCase { - base::test::ScopedCommandLine _scopedCommandLine; + std::unique_ptr<base::test::ScopedCommandLine> _scopedCommandLine; } // Current non-incognito browser state. @@ -171,7 +130,8 @@ - (void)setUp { // The command line is set up before [super setUp] in order to have the NTP // opened with the command line already setup. - base::CommandLine* commandLine = _scopedCommandLine.GetProcessCommandLine(); + _scopedCommandLine = base::MakeUnique<base::test::ScopedCommandLine>(); + base::CommandLine* commandLine = _scopedCommandLine->GetProcessCommandLine(); commandLine->AppendSwitch(switches::kEnableSuggestionsUI); self.provider->FireCategoryStatusChanged(self.category, CategoryStatus::AVAILABLE); @@ -185,6 +145,7 @@ - (void)tearDown { self.provider->FireCategoryStatusChanged( self.category, CategoryStatus::ALL_SUGGESTIONS_EXPLICITLY_DISABLED); + _scopedCommandLine.reset(); [super tearDown]; } @@ -224,8 +185,24 @@ assertWithMatcher:grey_sufficientlyVisible()]; } -// Tests that the "Learn More" cell is present. +// Tests that the "Learn More" cell is present only if there is a suggestion in +// the section. - (void)testLearnMore { + [[EarlGrey + selectElementWithMatcher:grey_accessibilityID( + [ContentSuggestionsViewController + collectionAccessibilityIdentifier])] + performAction:grey_scrollToContentEdge(kGREYContentEdgeBottom)]; + [[EarlGrey selectElementWithMatcher:grey_accessibilityID( + [ContentSuggestionsLearnMoreItem + accessibilityIdentifier])] + assertWithMatcher:grey_nil()]; + + std::vector<ContentSuggestion> suggestions; + suggestions.emplace_back( + Suggestion(self.category, "chromium", GURL("http://chromium.org"))); + self.provider->FireSuggestionsChanged(self.category, std::move(suggestions)); + [CellWithMatcher(grey_accessibilityID( [ContentSuggestionsLearnMoreItem accessibilityIdentifier])) assertWithMatcher:grey_sufficientlyVisible()];
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_controlling.h b/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_controlling.h index 9f48ca4..8fa8643 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_controlling.h +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_controlling.h
@@ -14,8 +14,9 @@ @property(nonatomic, assign, getter=isOmniboxFocused, readonly) BOOL omniboxFocused; -// Updates the iPhone fakebox's frame based on the current scroll view |offset|. -- (void)updateFakeOmniboxForOffset:(CGFloat)offset; +// Updates the iPhone fakebox's frame based on the current scroll view |offset| +// and |width|. |width| can be 0 to use the current view width. +- (void)updateFakeOmniboxForOffset:(CGFloat)offset width:(CGFloat)width; // Updates the fakeomnibox's width in order to be adapted to the new |width|, // without taking the y-position into account.
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_synchronizer.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_synchronizer.mm index c86b675..fe12b82 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_synchronizer.mm +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_synchronizer.mm
@@ -163,14 +163,16 @@ if (self.shouldAnimateHeader) { [self.headerController - updateFakeOmniboxForOffset:self.collectionView.contentOffset.y]; + updateFakeOmniboxForOffset:self.collectionView.contentOffset.y + width:0]; } } - (void)updateFakeOmniboxOnNewWidth:(CGFloat)width { if (self.shouldAnimateHeader && !IsIPadIdiom()) { [self.headerController - updateFakeOmniboxForOffset:self.collectionView.contentOffset.y]; + updateFakeOmniboxForOffset:self.collectionView.contentOffset.y + width:width]; } else { [self.headerController updateFakeOmniboxForWidth:width]; }
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_synchronizer_unittest.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_synchronizer_unittest.mm index a44323e1..1de0b59 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_synchronizer_unittest.mm +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_synchronizer_unittest.mm
@@ -67,7 +67,8 @@ // Setup. id headerController = HeaderController(); OCMExpect([[[headerController stub] ignoringNonObjectArgs] - updateFakeOmniboxForOffset:10]); + updateFakeOmniboxForOffset:10 + width:0]); SetAsIPhone(); // Action.
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm index fc6c4d4..f0be5b65 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm
@@ -20,6 +20,7 @@ #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_layout.h" #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller_audience.h" #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller_delegate.h" +#import "ios/chrome/browser/ui/content_suggestions/ntp_home_constant.h" #import "ios/chrome/browser/ui/overscroll_actions/overscroll_actions_controller.h" #import "ios/chrome/browser/ui/uikit_ui_util.h" #import "ios/chrome/browser/ui/util/constraints_ui_util.h" @@ -39,7 +40,7 @@ } } -@interface ContentSuggestionsViewController () +@interface ContentSuggestionsViewController ()<UIGestureRecognizerDelegate> @property(nonatomic, strong) ContentSuggestionsCollectionUpdater* collectionUpdater; @@ -190,7 +191,7 @@ [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPress:)]; - longPressRecognizer.numberOfTouchesRequired = 1; + longPressRecognizer.delegate = self; [self.collectionView addGestureRecognizer:longPressRecognizer]; if (!IsIPadIdiom()) { @@ -455,6 +456,16 @@ targetContentOffset:targetContentOffset]; } +#pragma mark - UIGestureRecognizerDelegate + +- (BOOL)gestureRecognizer:(UIGestureRecognizer*)gestureRecognizer + shouldReceiveTouch:(UITouch*)touch { + return touch.view.accessibilityIdentifier != + ntp_home::FakeOmniboxAccessibilityID() && + touch.view.superview.accessibilityIdentifier != + ntp_home::FakeOmniboxAccessibilityID(); +} + #pragma mark - Private - (void)handleLongPress:(UILongPressGestureRecognizer*)gestureRecognizer {
diff --git a/ios/chrome/browser/ui/content_suggestions/ntp_home_constant.h b/ios/chrome/browser/ui/content_suggestions/ntp_home_constant.h new file mode 100644 index 0000000..41c1f0c --- /dev/null +++ b/ios/chrome/browser/ui/content_suggestions/ntp_home_constant.h
@@ -0,0 +1,17 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_NTP_HOME_CONSTANT_H_ +#define IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_NTP_HOME_CONSTANT_H_ + +#import <Foundation/Foundation.h> + +namespace ntp_home { + +// Returns the accessibility identifier used by the fake omnibox. +NSString* FakeOmniboxAccessibilityID(); + +} // namespace ntp_home + +#endif // IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_NTP_HOME_CONSTANT_H_
diff --git a/ios/chrome/browser/ui/content_suggestions/ntp_home_constant.mm b/ios/chrome/browser/ui/content_suggestions/ntp_home_constant.mm new file mode 100644 index 0000000..207cd8b --- /dev/null +++ b/ios/chrome/browser/ui/content_suggestions/ntp_home_constant.mm
@@ -0,0 +1,15 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/ui/content_suggestions/ntp_home_constant.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +namespace ntp_home { +NSString* FakeOmniboxAccessibilityID() { + return @"NTPHomeFakeOmniboxAccessibilityID"; +} +} // namespace ntp_home
diff --git a/ios/chrome/browser/ui/content_suggestions/ntp_home_egtest.mm b/ios/chrome/browser/ui/content_suggestions/ntp_home_egtest.mm new file mode 100644 index 0000000..5a29677e --- /dev/null +++ b/ios/chrome/browser/ui/content_suggestions/ntp_home_egtest.mm
@@ -0,0 +1,292 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import <EarlGrey/EarlGrey.h> +#import <XCTest/XCTest.h> + +#include "base/test/scoped_command_line.h" +#include "components/reading_list/core/reading_list_model.h" +#include "ios/chrome/browser/browser_state/chrome_browser_state.h" +#include "ios/chrome/browser/chrome_switches.h" +#include "ios/chrome/browser/ntp_snippets/ios_chrome_content_suggestions_service_factory.h" +#include "ios/chrome/browser/ntp_snippets/ios_chrome_content_suggestions_service_factory_util.h" +#include "ios/chrome/browser/reading_list/reading_list_model_factory.h" +#import "ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils.h" +#import "ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.h" +#import "ios/chrome/browser/ui/content_suggestions/ntp_home_constant.h" +#import "ios/chrome/browser/ui/content_suggestions/ntp_home_provider_test_singleton.h" +#include "ios/chrome/browser/ui/ui_util.h" +#include "ios/chrome/grit/ios_strings.h" +#import "ios/chrome/test/app/chrome_test_util.h" +#import "ios/chrome/test/earl_grey/chrome_earl_grey.h" +#import "ios/chrome/test/earl_grey/chrome_earl_grey_ui.h" +#import "ios/chrome/test/earl_grey/chrome_matchers.h" +#import "ios/chrome/test/earl_grey/chrome_test_case.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +using namespace content_suggestions; +using namespace ntp_home; +using namespace ntp_snippets; + +namespace { +// Returns a matcher, which is true if the view has its width equals to |width|. +id<GREYMatcher> OmniboxWidth(CGFloat width) { + MatchesBlock matches = ^BOOL(UIView* view) { + return view.bounds.size.width == width; + }; + DescribeToBlock describe = ^void(id<GREYDescription> description) { + [description + appendText:[NSString stringWithFormat:@"Omnibox has correct width: %g", + width]]; + }; + + return [[GREYElementMatcherBlock alloc] initWithMatchesBlock:matches + descriptionBlock:describe]; +} + +// Returns a matcher, which is true if the view has its width equals to |width| +// plus or minus |margin|. +id<GREYMatcher> OmniboxWidthBetween(CGFloat width, CGFloat margin) { + MatchesBlock matches = ^BOOL(UIView* view) { + return view.bounds.size.width >= width - margin && + view.bounds.size.width <= width + margin; + }; + DescribeToBlock describe = ^void(id<GREYDescription> description) { + [description + appendText:[NSString + stringWithFormat: + @"Omnibox has correct width: %g with margin: %g", + width, margin]]; + }; + + return [[GREYElementMatcherBlock alloc] initWithMatchesBlock:matches + descriptionBlock:describe]; +} + +// Returns the subview of |parentView| corresponding to the +// ContentSuggestionsViewController. Returns nil if it is not in its subviews. +UIView* SubviewWithCollectionViewIdentifier(UIView* parentView) { + if (parentView.accessibilityIdentifier == + [ContentSuggestionsViewController collectionAccessibilityIdentifier]) { + return parentView; + } + if (parentView.subviews.count == 0) + return nil; + for (UIView* view in parentView.subviews) { + UIView* resultView = SubviewWithCollectionViewIdentifier(view); + if (resultView) + return resultView; + } + return nil; +} + +// Returns the view corresponding to the ContentSuggestionsViewController. +// Returns nil if it is not in the view hierarchy. +UIView* CollectionView() { + return SubviewWithCollectionViewIdentifier( + [[UIApplication sharedApplication] keyWindow]); +} +} // namespace + +// Test case for the NTP home UI. More precisely, this tests the positions of +// the elements after interacting with the device. +@interface NTPHomeTestCase : ChromeTestCase { + std::unique_ptr<base::test::ScopedCommandLine> _scopedCommandLine; +} + +// Current non-incognito browser state. +@property(nonatomic, assign, readonly) ios::ChromeBrowserState* browserState; +// Mock provider from the singleton. +@property(nonatomic, assign, readonly) MockContentSuggestionsProvider* provider; +// Article category, used by the singleton. +@property(nonatomic, assign, readonly) Category category; + +@end + +@implementation NTPHomeTestCase + ++ (void)setUp { + [super setUp]; + [self closeAllTabs]; + ios::ChromeBrowserState* browserState = + chrome_test_util::GetOriginalBrowserState(); + + // Sets the ContentSuggestionsService associated with this browserState to a + // service with no provider registered, allowing to register fake providers + // which do not require internet connection. The previous service is deleted. + IOSChromeContentSuggestionsServiceFactory::GetInstance()->SetTestingFactory( + browserState, CreateChromeContentSuggestionsService); + + ContentSuggestionsService* service = + IOSChromeContentSuggestionsServiceFactory::GetForBrowserState( + browserState); + RegisterReadingListProvider(service, browserState); + [[ContentSuggestionsTestSingleton sharedInstance] + registerArticleProvider:service]; +} + ++ (void)tearDown { + [self closeAllTabs]; + ios::ChromeBrowserState* browserState = + chrome_test_util::GetOriginalBrowserState(); + ReadingListModelFactory::GetForBrowserState(browserState)->DeleteAllEntries(); + + // Resets the Service associated with this browserState to a service with + // default providers. The previous service is deleted. + IOSChromeContentSuggestionsServiceFactory::GetInstance()->SetTestingFactory( + browserState, CreateChromeContentSuggestionsServiceWithProviders); + [super tearDown]; +} + +- (void)setUp { + // The command line is set up before [super setUp] in order to have the NTP + // opened with the command line already setup. + _scopedCommandLine = base::MakeUnique<base::test::ScopedCommandLine>(); + base::CommandLine* commandLine = _scopedCommandLine->GetProcessCommandLine(); + commandLine->AppendSwitch(switches::kEnableSuggestionsUI); + self.provider->FireCategoryStatusChanged(self.category, + CategoryStatus::AVAILABLE); + + ReadingListModel* readingListModel = + ReadingListModelFactory::GetForBrowserState(self.browserState); + readingListModel->DeleteAllEntries(); + [super setUp]; +} + +- (void)tearDown { + self.provider->FireCategoryStatusChanged( + self.category, CategoryStatus::ALL_SUGGESTIONS_EXPLICITLY_DISABLED); + [EarlGrey rotateDeviceToOrientation:UIDeviceOrientationPortrait + errorOrNil:nil]; + _scopedCommandLine.reset(); + [super tearDown]; +} + +#pragma mark - Properties + +- (ios::ChromeBrowserState*)browserState { + return chrome_test_util::GetOriginalBrowserState(); +} + +- (MockContentSuggestionsProvider*)provider { + return [[ContentSuggestionsTestSingleton sharedInstance] provider]; +} + +- (Category)category { + return Category::FromKnownCategory(KnownCategories::ARTICLES); +} + +#pragma mark - Tests + +// Tests that the fake omnibox width is correctly updated after a rotation. +- (void)testOmniboxWidthRotation { + // TODO(crbug.com/652465): Enable the test for iPad when rotation bug is + // fixed. + if (IsIPadIdiom()) { + EARL_GREY_TEST_DISABLED(@"Disabled for iPad due to device rotation bug."); + } + [[GREYUIThreadExecutor sharedInstance] drainUntilIdle]; + CGFloat collectionWidth = CollectionView().bounds.size.width; + GREYAssertTrue(collectionWidth > 0, @"The collection width is nil."); + CGFloat fakeOmniboxWidth = searchFieldWidth(collectionWidth); + + [[EarlGrey selectElementWithMatcher:grey_accessibilityID( + FakeOmniboxAccessibilityID())] + assertWithMatcher:OmniboxWidth(fakeOmniboxWidth)]; + + [EarlGrey rotateDeviceToOrientation:UIDeviceOrientationLandscapeLeft + errorOrNil:nil]; + [[GREYUIThreadExecutor sharedInstance] drainUntilIdle]; + + CGFloat collectionWidthAfterRotation = CollectionView().bounds.size.width; + GREYAssertNotEqual(collectionWidth, collectionWidthAfterRotation, + @"The collection width has not changed."); + fakeOmniboxWidth = searchFieldWidth(collectionWidthAfterRotation); + + [[EarlGrey selectElementWithMatcher:grey_accessibilityID( + FakeOmniboxAccessibilityID())] + assertWithMatcher:OmniboxWidth(fakeOmniboxWidth)]; +} + +// Tests that the fake omnibox width is correctly updated after a rotation done +// while the settings screen is shown. +- (void)testOmniboxWidthRotationBehindSettings { + // TODO(crbug.com/652465): Enable the test for iPad when rotation bug is + // fixed. + if (IsIPadIdiom()) { + EARL_GREY_TEST_DISABLED(@"Disabled for iPad due to device rotation bug."); + } + [[GREYUIThreadExecutor sharedInstance] drainUntilIdle]; + CGFloat collectionWidth = CollectionView().bounds.size.width; + GREYAssertTrue(collectionWidth > 0, @"The collection width is nil."); + CGFloat fakeOmniboxWidth = searchFieldWidth(collectionWidth); + + [[EarlGrey selectElementWithMatcher:grey_accessibilityID( + FakeOmniboxAccessibilityID())] + assertWithMatcher:OmniboxWidth(fakeOmniboxWidth)]; + + [ChromeEarlGreyUI openSettingsMenu]; + + [EarlGrey rotateDeviceToOrientation:UIDeviceOrientationLandscapeLeft + errorOrNil:nil]; + [[GREYUIThreadExecutor sharedInstance] drainUntilIdle]; + + [[EarlGrey + selectElementWithMatcher:chrome_test_util::ButtonWithAccessibilityLabelId( + IDS_IOS_NAVIGATION_BAR_DONE_BUTTON)] + performAction:grey_tap()]; + + CGFloat collectionWidthAfterRotation = CollectionView().bounds.size.width; + GREYAssertNotEqual(collectionWidth, collectionWidthAfterRotation, + @"The collection width has not changed."); + fakeOmniboxWidth = searchFieldWidth(collectionWidthAfterRotation); + + [[EarlGrey selectElementWithMatcher:grey_accessibilityID( + FakeOmniboxAccessibilityID())] + assertWithMatcher:OmniboxWidth(fakeOmniboxWidth)]; +} + +// Tests that the fake omnibox width is correctly updated after a rotation done +// while the fake omnibox is pinned to the top. +- (void)testOmniboxPinnedWidthRotation { + // TODO(crbug.com/652465): Enable the test for iPad when rotation bug is + // fixed. + if (IsIPadIdiom()) { + EARL_GREY_TEST_DISABLED(@"Disabled for iPad due to device rotation bug."); + } + + [[EarlGrey + selectElementWithMatcher:grey_accessibilityID( + [ContentSuggestionsViewController + collectionAccessibilityIdentifier])] + performAction:grey_swipeFastInDirection(kGREYDirectionUp)]; + + [[GREYUIThreadExecutor sharedInstance] drainUntilIdle]; + CGFloat collectionWidth = CollectionView().bounds.size.width; + GREYAssertTrue(collectionWidth > 0, @"The collection width is nil."); + + // The fake omnibox might be slightly bigger than the screen in order to cover + // it for all screen scale. + [[EarlGrey selectElementWithMatcher:grey_accessibilityID( + FakeOmniboxAccessibilityID())] + assertWithMatcher:OmniboxWidthBetween(collectionWidth + 1, 1)]; + + [EarlGrey rotateDeviceToOrientation:UIDeviceOrientationLandscapeLeft + errorOrNil:nil]; + + [[GREYUIThreadExecutor sharedInstance] drainUntilIdle]; + CGFloat collectionWidthAfterRotation = CollectionView().bounds.size.width; + GREYAssertNotEqual(collectionWidth, collectionWidthAfterRotation, + @"The collection width has not changed."); + + [[EarlGrey selectElementWithMatcher:grey_accessibilityID( + FakeOmniboxAccessibilityID())] + assertWithMatcher:OmniboxWidthBetween(collectionWidthAfterRotation + 1, + 1)]; +} + +@end
diff --git a/ios/chrome/browser/ui/content_suggestions/ntp_home_provider_test_singleton.h b/ios/chrome/browser/ui/content_suggestions/ntp_home_provider_test_singleton.h new file mode 100644 index 0000000..a8c81c8 --- /dev/null +++ b/ios/chrome/browser/ui/content_suggestions/ntp_home_provider_test_singleton.h
@@ -0,0 +1,28 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_NTP_HOME_PROVIDER_TEST_SINGLETON_H_ +#define IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_NTP_HOME_PROVIDER_TEST_SINGLETON_H_ + +#import <UIKit/UIKit.h> + +#include "components/ntp_snippets/content_suggestions_service.h" +#include "components/ntp_snippets/mock_content_suggestions_provider.h" + +// Singleton allowing to register the provider in the +setup and still access it +// from inside the tests. +@interface ContentSuggestionsTestSingleton : NSObject + +// Shared instance of this singleton. ++ (instancetype)sharedInstance; + +// Returns the provider registered. +- (ntp_snippets::MockContentSuggestionsProvider*)provider; +// Registers a provider in the |service|. +- (void)registerArticleProvider: + (ntp_snippets::ContentSuggestionsService*)service; + +@end + +#endif // IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_NTP_HOME_PROVIDER_TEST_SINGLETON_H_
diff --git a/ios/chrome/browser/ui/content_suggestions/ntp_home_provider_test_singleton.mm b/ios/chrome/browser/ui/content_suggestions/ntp_home_provider_test_singleton.mm new file mode 100644 index 0000000..2204392c --- /dev/null +++ b/ios/chrome/browser/ui/content_suggestions/ntp_home_provider_test_singleton.mm
@@ -0,0 +1,41 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/ui/content_suggestions/ntp_home_provider_test_singleton.h" + +#include "base/memory/ptr_util.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +using namespace ntp_snippets; + +@implementation ContentSuggestionsTestSingleton { + MockContentSuggestionsProvider* _provider; +} + ++ (instancetype)sharedInstance { + static ContentSuggestionsTestSingleton* sharedInstance = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + sharedInstance = [[self alloc] init]; + }); + return sharedInstance; +} + +- (MockContentSuggestionsProvider*)provider { + return _provider; +} + +- (void)registerArticleProvider:(ContentSuggestionsService*)service { + Category articles = Category::FromKnownCategory(KnownCategories::ARTICLES); + std::unique_ptr<MockContentSuggestionsProvider> provider = + base::MakeUnique<MockContentSuggestionsProvider>( + service, std::vector<Category>{articles}); + _provider = provider.get(); + service->RegisterProvider(std::move(provider)); +} + +@end
diff --git a/ios/shared/chrome/browser/ui/coordinators/BUILD.gn b/ios/chrome/browser/ui/coordinators/BUILD.gn similarity index 100% rename from ios/shared/chrome/browser/ui/coordinators/BUILD.gn rename to ios/chrome/browser/ui/coordinators/BUILD.gn
diff --git a/ios/chrome/browser/ui/coordinators/browser_coordinator+internal.h b/ios/chrome/browser/ui/coordinators/browser_coordinator+internal.h new file mode 100644 index 0000000..4235802 --- /dev/null +++ b/ios/chrome/browser/ui/coordinators/browser_coordinator+internal.h
@@ -0,0 +1,97 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_COORDINATORS_BROWSER_COORDINATOR_INTERNAL_H_ +#define IOS_CHROME_BROWSER_UI_COORDINATORS_BROWSER_COORDINATOR_INTERNAL_H_ + +#import "ios/chrome/browser/ui/coordinators/browser_coordinator.h" + +// Internal API for subclasses and categories of BrowserCoordinator. +// +// This API can be used to create and manage 'overlay coordinators'. +// Overlay coordinators are intended to be used for UI elements that +// sit on top of the regular UI, and which may need to be dismissed +// by coordinators that don't have direct access to them. Typical uses +// would be alerts, login prompts, or other UI that might be dismissed +// if (for example) an external event causes a web page to load. +// Overlay coordinators can be added by any coordinator in the coordinator +// hierarchy, but they will be children of (generally) the topmost +// coordinator, regardless of which coordinator added them. +@interface BrowserCoordinator (Internal) + +// Managed view controller of this object. Subclasses must define a +// property named |viewController| that has the specific UIViewController +// subclass they use; the subclass API will be able to access that view +// controller through this property. +@property(nonatomic, readonly) UIViewController* viewController; + +// The child coordinators of this coordinator. To add or remove from this set, +// use the -addChildCoordinator: and -removeChildCoordinator: methods. +@property(nonatomic, readonly) NSSet<BrowserCoordinator*>* children; + +// The coordinator that added this coordinator as a child, if any. +@property(nonatomic, readonly) BrowserCoordinator* parentCoordinator; + +// YES if the receiver has been started; NO (the default) otherwise. Stopping +// the receiver resets this property to NO. +@property(nonatomic, readonly) BOOL started; + +// YES if the receiver is acting as an overlay coordinator; NO (the default) +// otherwise. +@property(nonatomic, readonly) BOOL overlaying; + +// The coordinator (if any) in the coordinator hierarchy (starting with +// the receiver) that is overlaying. If the receiver isn't overlaying, +// it recursively asks its children. +@property(nonatomic, readonly) BrowserCoordinator* overlayCoordinator; + +// Adds |coordinator| as a child, taking ownership of it, setting the receiver's +// viewController (if any) as the child's baseViewController, and setting +// the receiver's |browser| as the child's |browser|. +- (void)addChildCoordinator:(BrowserCoordinator*)childCoordinator; + +// Removes |coordinator| as a child, relinquishing ownership of it. If +// |coordinator| isn't a child of the receiver, this method does nothing. +- (void)removeChildCoordinator:(BrowserCoordinator*)childCoordinator; + +// Called when this coordinator is added to a parent coordinator. +- (void)wasAddedToParentCoordinator:(BrowserCoordinator*)parentCoordinator; + +// Called when this coordinator is going to be removed from its parent +// coordinator. +- (void)willBeRemovedFromParentCoordinator; + +// Called when a child coordinator did start. This is a blank template method. +// Subclasses can override this method when they need to know when their +// children start. +- (void)childCoordinatorDidStart:(BrowserCoordinator*)childCoordinator; + +// Called when a child coordinator will stop. This is a blank template method. +// Subclasses can override this method when they need to know when their +// children start. +- (void)childCoordinatorWillStop:(BrowserCoordinator*)childCoordinator; + +// Methods for adding overlay coordinators. + +// Returns YES if the receiver will take |overlayCoordinator| as a child. +// The default is to return YES only if the receiver has no children, if +// the receiver has a nil -overlayCoordinator, and if |overlayCoordinator| +// is not already overlaying. +- (BOOL)canAddOverlayCoordinator:(BrowserCoordinator*)overlayCoordinator; + +// Adds |overlayCoordinator| as a child to the receiver, or if it cannot be +// added, recursively add it to the receiver's child. If a receiver has +// multiple children and returns YES from -canAddOverlayCoordinator:, it +// must override this method to determines how the overlay is added. +// If neither the receiver or any child can add |overlayCoordinator|, then +// nothing happens. +- (void)addOverlayCoordinator:(BrowserCoordinator*)overlayCoordinator; + +// Removes the current overlay coordinator (if any) as a child from its +// parent. +- (void)removeOverlayCoordinator; + +@end + +#endif // IOS_CHROME_BROWSER_UI_COORDINATORS_BROWSER_COORDINATOR_INTERNAL_H_
diff --git a/ios/chrome/browser/ui/coordinators/browser_coordinator.h b/ios/chrome/browser/ui/coordinators/browser_coordinator.h new file mode 100644 index 0000000..c7fa248 --- /dev/null +++ b/ios/chrome/browser/ui/coordinators/browser_coordinator.h
@@ -0,0 +1,55 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_COORDINATORS_BROWSER_COORDINATOR_H_ +#define IOS_CHROME_BROWSER_UI_COORDINATORS_BROWSER_COORDINATOR_H_ + +#import <UIKit/UIKit.h> + +class Browser; + +// An object that manages a UI component via a view controller. +// This is the public interface to this class; subclasses should also import +// the Internal category header (browser_coordinator+internal.h). This header +// file declares all the methods and properties a subclass must either override, +// call, or reset. +@interface BrowserCoordinator : NSObject + +// The browser object used by this coordinator and passed into any child +// coordinators added to it. This is a weak pointer, and setting this property +// doesn't transfer ownership of the browser. +@property(nonatomic, assign) Browser* browser; + +// The basic lifecycle methods for coordinators are -start and -stop. These +// implementations notify the parent coordinator when this coordinator did start +// and will stop. Child classes are expected to override and call the superclass +// method at the end of -start and at the beginning of -stop. +// If the receiver is already started, -start is a no-op. If the receiver is +// already stopped or never started, -stop is a no-op. In those cases, the +// overriding implementations can early return withotu calling the superclass +// method: +// SubCoordinator.mm: +// - (void)start { +// if (self.started) return; +// ... +// [super start]; +// } + +// Starts the user interaction managed by the receiver. Typical implementations +// will create a view controller and then use |baseViewController| to present +// it. This method needs to be called at the end of the overriding +// implementation. +// Starting a started coordinator is a no-op in this implementation. +- (void)start NS_REQUIRES_SUPER; + +// Stops the user interaction managed by the receiver. This method needs to be +// called at the beginning of the overriding implementation. +// Calling stop on a coordinator transitively calls stop on its children. +// Stopping a non-started or stopped coordinator is a no-op in this +// implementation. +- (void)stop NS_REQUIRES_SUPER; + +@end + +#endif // IOS_CHROME_BROWSER_UI_COORDINATORS_BROWSER_COORDINATOR_H_
diff --git a/ios/chrome/browser/ui/coordinators/browser_coordinator.mm b/ios/chrome/browser/ui/coordinators/browser_coordinator.mm new file mode 100644 index 0000000..1d578df3 --- /dev/null +++ b/ios/chrome/browser/ui/coordinators/browser_coordinator.mm
@@ -0,0 +1,161 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/ui/coordinators/browser_coordinator.h" + +#import "base/logging.h" +#import "ios/chrome/browser/ui/coordinators/browser_coordinator+internal.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +@interface BrowserCoordinator () +// Child coordinators owned by this object. +@property(nonatomic, strong) + NSMutableSet<BrowserCoordinator*>* childCoordinators; +// Parent coordinator of this object, if any. +@property(nonatomic, readwrite, weak) BrowserCoordinator* parentCoordinator; +@property(nonatomic, readwrite) BOOL started; +@property(nonatomic, readwrite) BOOL overlaying; +@end + +@implementation BrowserCoordinator + +@synthesize browser = _browser; +@synthesize childCoordinators = _childCoordinators; +@synthesize parentCoordinator = _parentCoordinator; +@synthesize started = _started; +@synthesize overlaying = _overlaying; + +- (instancetype)init { + if (self = [super init]) { + _childCoordinators = [NSMutableSet set]; + } + return self; +} + +#pragma mark - Public API + +- (void)start { + if (self.started) { + return; + } + self.started = YES; + [self.parentCoordinator childCoordinatorDidStart:self]; +} + +- (void)stop { + if (!self.started) { + return; + } + [self.parentCoordinator childCoordinatorWillStop:self]; + self.started = NO; + for (BrowserCoordinator* child in self.children) { + [child stop]; + } +} + +- (void)dealloc { + for (BrowserCoordinator* child in self.children) { + [self removeChildCoordinator:child]; + } +} + +@end + +@implementation BrowserCoordinator (Internal) +// Concrete implementations must implement a |viewController| property. +@dynamic viewController; + +- (NSSet*)children { + return [self.childCoordinators copy]; +} + +- (void)addChildCoordinator:(BrowserCoordinator*)childCoordinator { + CHECK([self respondsToSelector:@selector(viewController)]) + << "BrowserCoordinator implementations must provide a viewController " + "property."; + [self.childCoordinators addObject:childCoordinator]; + childCoordinator.parentCoordinator = self; + childCoordinator.browser = self.browser; + [childCoordinator wasAddedToParentCoordinator:self]; +} + +- (BrowserCoordinator*)overlayCoordinator { + if (self.overlaying) + return self; + for (BrowserCoordinator* child in self.children) { + BrowserCoordinator* overlay = child.overlayCoordinator; + if (overlay) + return overlay; + } + return nil; +} + +- (void)addOverlayCoordinator:(BrowserCoordinator*)overlayCoordinator { + // If this object has no children, then add |overlayCoordinator| as a child + // and mark it as such. + if ([self canAddOverlayCoordinator:overlayCoordinator]) { + [self addChildCoordinator:overlayCoordinator]; + overlayCoordinator.overlaying = YES; + } else if (self.childCoordinators.count == 1) { + [[self.childCoordinators anyObject] + addOverlayCoordinator:overlayCoordinator]; + } else if (self.childCoordinators.count > 1) { + CHECK(NO) << "Coordinators with multiple children must explicitly " + << "handle -addOverlayCoordinator: or return NO to " + << "-canAddOverlayCoordinator:"; + } + // If control reaches here, the terminal child of the coordinator hierarchy + // has returned NO to -canAddOverlayCoordinator, so no overlay can be added. + // This is by default a silent no-op. +} + +- (void)removeOverlayCoordinator { + BrowserCoordinator* overlay = self.overlayCoordinator; + [overlay.parentCoordinator removeChildCoordinator:overlay]; + overlay.overlaying = NO; +} + +- (BOOL)canAddOverlayCoordinator:(BrowserCoordinator*)overlayCoordinator { + // By default, a hierarchy with an overlay can't add a new one. + // By default, coordinators with parents can't be added as overlays. + // By default, coordinators with no other children can add an overlay. + return self.overlayCoordinator == nil && + overlayCoordinator.parentCoordinator == nil && + self.childCoordinators.count == 0; +} + +- (void)removeChildCoordinator:(BrowserCoordinator*)childCoordinator { + if (![self.childCoordinators containsObject:childCoordinator]) + return; + // Remove the grand-children first. + for (BrowserCoordinator* grandChild in childCoordinator.children) { + [childCoordinator removeChildCoordinator:grandChild]; + } + // Remove the child. + [childCoordinator willBeRemovedFromParentCoordinator]; + [self.childCoordinators removeObject:childCoordinator]; + childCoordinator.parentCoordinator = nil; + childCoordinator.browser = nil; +} + +- (void)wasAddedToParentCoordinator:(BrowserCoordinator*)parentCoordinator { + // Default implementation is a no-op. +} + +- (void)willBeRemovedFromParentCoordinator { + // Default implementation is a no-op. +} + +- (void)childCoordinatorDidStart:(BrowserCoordinator*)childCoordinator { + // Default implementation is a no-op. +} + +- (void)childCoordinatorWillStop:(BrowserCoordinator*)childCoordinator { + // Default implementation is a no-op. +} + +@end
diff --git a/ios/chrome/browser/ui/coordinators/browser_coordinator_test.h b/ios/chrome/browser/ui/coordinators/browser_coordinator_test.h new file mode 100644 index 0000000..668c6c1 --- /dev/null +++ b/ios/chrome/browser/ui/coordinators/browser_coordinator_test.h
@@ -0,0 +1,27 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_COORDINATORS_BROWSER_COORDINATOR_TEST_H_ +#define IOS_CHROME_BROWSER_UI_COORDINATORS_BROWSER_COORDINATOR_TEST_H_ + +#include <memory> + +#include "testing/platform_test.h" + +class Browser; +class TestChromeBrowserState; + +class BrowserCoordinatorTest : public PlatformTest { + protected: + BrowserCoordinatorTest(); + ~BrowserCoordinatorTest() override; + + Browser* GetBrowser() { return browser_.get(); } + + private: + std::unique_ptr<Browser> browser_; + std::unique_ptr<TestChromeBrowserState> chrome_browser_state_; +}; + +#endif // IOS_CHROME_BROWSER_UI_COORDINATORS_BROWSER_COORDINATOR_TEST_H_
diff --git a/ios/chrome/browser/ui/coordinators/browser_coordinator_test.mm b/ios/chrome/browser/ui/coordinators/browser_coordinator_test.mm new file mode 100644 index 0000000..bb4441b5 --- /dev/null +++ b/ios/chrome/browser/ui/coordinators/browser_coordinator_test.mm
@@ -0,0 +1,22 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/ui/coordinators/browser_coordinator_test.h" + +#include "base/memory/ptr_util.h" +#include "ios/chrome/browser/browser_state/test_chrome_browser_state.h" +#import "ios/chrome/browser/ui/browser_list/browser.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +BrowserCoordinatorTest::BrowserCoordinatorTest() { + // Initialize the browser. + TestChromeBrowserState::Builder builder; + chrome_browser_state_ = builder.Build(); + browser_ = base::MakeUnique<Browser>(chrome_browser_state_.get()); +} + +BrowserCoordinatorTest::~BrowserCoordinatorTest() = default;
diff --git a/ios/chrome/browser/ui/coordinators/browser_coordinator_unittest.mm b/ios/chrome/browser/ui/coordinators/browser_coordinator_unittest.mm new file mode 100644 index 0000000..2134a614 --- /dev/null +++ b/ios/chrome/browser/ui/coordinators/browser_coordinator_unittest.mm
@@ -0,0 +1,305 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/ui/coordinators/browser_coordinator.h" +#import "ios/chrome/browser/ui/coordinators/browser_coordinator+internal.h" + +#import "ios/chrome/browser/ui/coordinators/browser_coordinator_test.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +@interface TestCoordinator : BrowserCoordinator +@property(nonatomic) UIViewController* viewController; +@property(nonatomic, copy) void (^stopHandler)(); +@property(nonatomic) BOOL wasAddedCalled; +@property(nonatomic) BOOL willBeRemovedCalled; +@property(nonatomic, copy) void (^willBeRemovedHandler)(); +@property(nonatomic) BOOL removeCalled; +@property(nonatomic) BOOL childDidStartCalled; +@property(nonatomic) BOOL childWillStopCalled; +@end + +@implementation TestCoordinator +@synthesize viewController = _viewController; +@synthesize stopHandler = _stopHandler; +@synthesize wasAddedCalled = _wasAddedCalled; +@synthesize willBeRemovedCalled = _willBeRemovedCalled; +@synthesize willBeRemovedHandler = _willBeRemovedHandler; +@synthesize removeCalled = _removeCalled; +@synthesize childDidStartCalled = _childDidStartCalled; +@synthesize childWillStopCalled = _childWillStopCalled; + +- (instancetype)init { + if (!(self = [super init])) + return nil; + + _viewController = [[UIViewController alloc] init]; + return self; +} + +- (void)stop { + [super stop]; + if (self.stopHandler) + self.stopHandler(); +} + +- (void)wasAddedToParentCoordinator:(BrowserCoordinator*)parentCoordinator { + [super wasAddedToParentCoordinator:parentCoordinator]; + self.wasAddedCalled = YES; +} + +- (void)willBeRemovedFromParentCoordinator { + [super willBeRemovedFromParentCoordinator]; + self.willBeRemovedCalled = YES; + if (self.willBeRemovedHandler) + self.willBeRemovedHandler(); +} + +- (void)removeChildCoordinator:(BrowserCoordinator*)childCoordinator { + [super removeChildCoordinator:childCoordinator]; + self.removeCalled = YES; +} + +- (void)childCoordinatorDidStart:(BrowserCoordinator*)childCoordinator { + [super childCoordinatorDidStart:childCoordinator]; + self.childDidStartCalled = YES; +} + +- (void)childCoordinatorWillStop:(BrowserCoordinator*)childCoordinator { + [super childCoordinatorWillStop:childCoordinator]; + self.childWillStopCalled = YES; +} + +@end + +@interface NonOverlayableCoordinator : TestCoordinator +@end + +@implementation NonOverlayableCoordinator + +- (BOOL)canAddOverlayCoordinator:(BrowserCoordinator*)overlayCoordinator { + return NO; +} + +@end + +TEST_F(BrowserCoordinatorTest, TestDontStopOnDealloc) { + __block BOOL called = NO; + + { + TestCoordinator* coordinator = [[TestCoordinator alloc] init]; + coordinator.stopHandler = ^{ + called = YES; + }; + } + + EXPECT_FALSE(called); +} + +TEST_F(BrowserCoordinatorTest, TestChildren) { + TestCoordinator* parent = [[TestCoordinator alloc] init]; + TestCoordinator* child = [[TestCoordinator alloc] init]; + + [parent addChildCoordinator:child]; + EXPECT_TRUE([parent.children containsObject:child]); + EXPECT_EQ(parent, child.parentCoordinator); + + [parent removeChildCoordinator:child]; + EXPECT_FALSE([parent.children containsObject:child]); + EXPECT_EQ(nil, child.parentCoordinator); + + TestCoordinator* otherParent = [[TestCoordinator alloc] init]; + TestCoordinator* otherChild = [[TestCoordinator alloc] init]; + [otherParent addChildCoordinator:otherChild]; + + // -removeChildCoordinator of a non-child should have no affect. + [parent removeChildCoordinator:otherChild]; + EXPECT_TRUE([otherParent.children containsObject:otherChild]); + EXPECT_EQ(otherParent, otherChild.parentCoordinator); +} + +TEST_F(BrowserCoordinatorTest, TestOverlay) { + TestCoordinator* parent = [[TestCoordinator alloc] init]; + TestCoordinator* child = [[TestCoordinator alloc] init]; + TestCoordinator* grandchild = [[TestCoordinator alloc] init]; + TestCoordinator* overlay = [[TestCoordinator alloc] init]; + TestCoordinator* secondOverlay = [[TestCoordinator alloc] init]; + + EXPECT_TRUE([parent canAddOverlayCoordinator:overlay]); + [parent addChildCoordinator:child]; + [child addChildCoordinator:grandchild]; + EXPECT_FALSE([parent canAddOverlayCoordinator:overlay]); + EXPECT_FALSE([child canAddOverlayCoordinator:overlay]); + EXPECT_TRUE([grandchild canAddOverlayCoordinator:overlay]); + EXPECT_FALSE([grandchild canAddOverlayCoordinator:child]); + + EXPECT_FALSE(overlay.overlaying); + [parent addOverlayCoordinator:overlay]; + EXPECT_TRUE(overlay.overlaying); + EXPECT_EQ(overlay, parent.overlayCoordinator); + EXPECT_EQ(overlay, child.overlayCoordinator); + EXPECT_EQ(overlay, grandchild.overlayCoordinator); + EXPECT_TRUE([grandchild.children containsObject:overlay]); + EXPECT_EQ(grandchild, overlay.parentCoordinator); + + // Shouldn't be able to add a second overlaying coordinator. + EXPECT_FALSE([grandchild canAddOverlayCoordinator:secondOverlay]); + EXPECT_FALSE(secondOverlay.overlaying); + [parent addOverlayCoordinator:secondOverlay]; + EXPECT_FALSE(secondOverlay.overlaying); + + [child removeOverlayCoordinator]; + EXPECT_FALSE(overlay.overlaying); + EXPECT_EQ(nil, parent.overlayCoordinator); + EXPECT_EQ(nil, child.overlayCoordinator); + EXPECT_EQ(nil, grandchild.overlayCoordinator); + EXPECT_FALSE([grandchild.children containsObject:overlay]); + EXPECT_EQ(nil, overlay.parentCoordinator); + + // An implementation that doesn't allow any overlays shouldn't get one. + NonOverlayableCoordinator* noOverlays = + [[NonOverlayableCoordinator alloc] init]; + TestCoordinator* thirdOverlay = [[TestCoordinator alloc] init]; + + EXPECT_FALSE([noOverlays canAddOverlayCoordinator:thirdOverlay]); + EXPECT_FALSE(thirdOverlay.overlaying); + [noOverlays addOverlayCoordinator:thirdOverlay]; + EXPECT_FALSE(thirdOverlay.overlaying); +} + +TEST_F(BrowserCoordinatorTest, AddedRemoved) { + TestCoordinator* parent = [[TestCoordinator alloc] init]; + TestCoordinator* child = [[TestCoordinator alloc] init]; + + // Add to the parent. + EXPECT_FALSE(child.wasAddedCalled); + EXPECT_FALSE(child.willBeRemovedCalled); + [parent addChildCoordinator:child]; + EXPECT_TRUE(child.wasAddedCalled); + EXPECT_FALSE(child.willBeRemovedCalled); + + // Remove from the parent. + [parent removeChildCoordinator:child]; + EXPECT_TRUE(child.willBeRemovedCalled); +} + +TEST_F(BrowserCoordinatorTest, DidStartWillStop) { + TestCoordinator* parent = [[TestCoordinator alloc] init]; + TestCoordinator* child = [[TestCoordinator alloc] init]; + [parent addChildCoordinator:child]; + EXPECT_FALSE(parent.childDidStartCalled); + EXPECT_FALSE(parent.childWillStopCalled); + + [child start]; + EXPECT_TRUE(parent.childDidStartCalled); + EXPECT_FALSE(parent.childWillStopCalled); + + [child stop]; + EXPECT_TRUE(parent.childDidStartCalled); + EXPECT_TRUE(parent.childWillStopCalled); +} + +TEST_F(BrowserCoordinatorTest, StopStopsStartedChildren) { + TestCoordinator* parent = [[TestCoordinator alloc] init]; + TestCoordinator* child = [[TestCoordinator alloc] init]; + [parent addChildCoordinator:child]; + [parent start]; + [child start]; + __block BOOL called = NO; + child.stopHandler = ^{ + called = YES; + }; + EXPECT_FALSE(called); + + // Call stop on the parent. + [parent stop]; + + // It should have called stop on the child. + EXPECT_TRUE(called); +} + +TEST_F(BrowserCoordinatorTest, StopStopsNonStartedChildren) { + TestCoordinator* parent = [[TestCoordinator alloc] init]; + TestCoordinator* child = [[TestCoordinator alloc] init]; + [parent addChildCoordinator:child]; + [parent start]; + __block BOOL called = NO; + child.stopHandler = ^{ + called = YES; + }; + EXPECT_FALSE(called); + + // Call stop on the parent. + [parent stop]; + + // It should not have called stop on the child. + EXPECT_TRUE(called); +} + +TEST_F(BrowserCoordinatorTest, BrowserIsNilAfterCoordinatorIsRemoved) { + TestCoordinator* parent = [[TestCoordinator alloc] init]; + TestCoordinator* child = [[TestCoordinator alloc] init]; + parent.browser = GetBrowser(); + [parent addChildCoordinator:child]; + + EXPECT_NE(nil, child.browser); + + // Remove the child. + [parent removeChildCoordinator:child]; + + EXPECT_EQ(nil, child.browser); +} + +TEST_F(BrowserCoordinatorTest, RemoveRemovesGrandChildren) { + TestCoordinator* parent = [[TestCoordinator alloc] init]; + TestCoordinator* child = [[TestCoordinator alloc] init]; + TestCoordinator* grandChild = [[TestCoordinator alloc] init]; + [child addChildCoordinator:grandChild]; + [parent addChildCoordinator:child]; + + EXPECT_FALSE(grandChild.willBeRemovedCalled); + EXPECT_FALSE(child.removeCalled); + + // Remove the child. + [parent removeChildCoordinator:child]; + + EXPECT_TRUE(grandChild.willBeRemovedCalled); + EXPECT_TRUE(child.removeCalled); +} + +TEST_F(BrowserCoordinatorTest, + RemoveRemovesGrandChildThenCallWillRemoveOnChild) { + TestCoordinator* parent = [[TestCoordinator alloc] init]; + TestCoordinator* child = [[TestCoordinator alloc] init]; + TestCoordinator* grandChild = [[TestCoordinator alloc] init]; + [child addChildCoordinator:grandChild]; + [parent addChildCoordinator:child]; + EXPECT_FALSE(grandChild.willBeRemovedCalled); + EXPECT_FALSE(child.removeCalled); + __weak TestCoordinator* weakChild = child; + child.willBeRemovedHandler = ^{ + EXPECT_TRUE(grandChild.willBeRemovedCalled); + EXPECT_TRUE(weakChild.removeCalled); + }; + + // Remove the child. + [parent removeChildCoordinator:child]; + + EXPECT_TRUE(child.willBeRemovedCalled); +} + +TEST_F(BrowserCoordinatorTest, RemoveChildWithMultipleGrandChildren) { + TestCoordinator* parent = [[TestCoordinator alloc] init]; + TestCoordinator* child = [[TestCoordinator alloc] init]; + TestCoordinator* grandChild1 = [[TestCoordinator alloc] init]; + TestCoordinator* grandChild2 = [[TestCoordinator alloc] init]; + [child addChildCoordinator:grandChild1]; + [child addChildCoordinator:grandChild2]; + [parent addChildCoordinator:child]; + + // Remove the child. + [parent removeChildCoordinator:child]; +}
diff --git a/ios/chrome/browser/ui/dialogs/javascript_dialog_egtest.mm b/ios/chrome/browser/ui/dialogs/javascript_dialog_egtest.mm index 54472e42..d024aca 100644 --- a/ios/chrome/browser/ui/dialogs/javascript_dialog_egtest.mm +++ b/ios/chrome/browser/ui/dialogs/javascript_dialog_egtest.mm
@@ -406,6 +406,12 @@ @"correctly."); #endif + // TODO(crbug.com/753098): Re-enable this test on iOS 11 iPad once + // grey_typeText works on iOS 11. + if (base::ios::IsRunningOnIOS11OrLater() && IsIPadIdiom()) { + EARL_GREY_TEST_DISABLED(@"Test disabled on iOS 11."); + } + // Load the blank test page and show a prompt dialog. [self loadBlankTestPage]; ShowJavaScriptDialog(JavaScriptAlertType::PROMPT); @@ -560,11 +566,6 @@ @"correctly."); #endif - // TODO(crbug.com/747439): re-enable this test on iOS 11. - if (base::ios::IsRunningOnIOS11OrLater()) { - EARL_GREY_TEST_DISABLED(@"Disabled on iOS 11."); - } - // Load the test page with a link to kOnLoadAlertURL and long tap on the link. [self loadPageWithLink];
diff --git a/ios/chrome/browser/ui/keyboard_commands_egtest.mm b/ios/chrome/browser/ui/keyboard_commands_egtest.mm index db85067..e727149 100644 --- a/ios/chrome/browser/ui/keyboard_commands_egtest.mm +++ b/ios/chrome/browser/ui/keyboard_commands_egtest.mm
@@ -6,6 +6,7 @@ #import <XCTest/XCTest.h> #include "components/strings/grit/components_strings.h" +#include "ios/chrome/browser/experimental_flags.h" #import "ios/chrome/browser/ui/browser_view_controller.h" #import "ios/chrome/browser/ui/commands/generic_chrome_command.h" #include "ios/chrome/browser/ui/commands/ios_command_ids.h" @@ -176,6 +177,9 @@ // Tests that keyboard commands are not registered when the Bookmarks UI is // shown on iPhone and registered on iPad. - (void)testKeyboardCommandsNotRegistered_BookmarksPresented { + if (experimental_flags::IsBookmarkReorderingEnabled()) { + EARL_GREY_TEST_SKIPPED(@"Only enabled with old Bookmarks UI."); + } // Open Bookmarks [self selectToolsMenuItem:grey_accessibilityID(kToolsMenuBookmarksId)];
diff --git a/ios/chrome/browser/ui/ntp/BUILD.gn b/ios/chrome/browser/ui/ntp/BUILD.gn index 60758f88..db3c9cb 100644 --- a/ios/chrome/browser/ui/ntp/BUILD.gn +++ b/ios/chrome/browser/ui/ntp/BUILD.gn
@@ -267,6 +267,7 @@ ":ntp_internal", "//components/strings", "//ios/chrome/app/strings", + "//ios/chrome/browser", "//ios/chrome/browser/ui", "//ios/chrome/browser/ui/commands", "//ios/chrome/test/app:test_support",
diff --git a/ios/chrome/browser/ui/ntp/google_landing_view_controller.mm b/ios/chrome/browser/ui/ntp/google_landing_view_controller.mm index 4f399f8..576c4b1 100644 --- a/ios/chrome/browser/ui/ntp/google_landing_view_controller.mm +++ b/ios/chrome/browser/ui/ntp/google_landing_view_controller.mm
@@ -496,7 +496,8 @@ topMargin:_searchFieldTopMarginConstraint subviewConstraints:constraints logoIsShowing:self.logoIsShowing - forOffset:[_mostVisitedView contentOffset].y]; + forOffset:[_mostVisitedView contentOffset].y + width:0]; } - (void)addOverscrollActions {
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_egtest.mm b/ios/chrome/browser/ui/ntp/new_tab_page_egtest.mm index 5e9afa3..bc965b2d 100644 --- a/ios/chrome/browser/ui/ntp/new_tab_page_egtest.mm +++ b/ios/chrome/browser/ui/ntp/new_tab_page_egtest.mm
@@ -7,6 +7,7 @@ #include "base/ios/ios_util.h" #include "components/strings/grit/components_strings.h" +#include "ios/chrome/browser/experimental_flags.h" #import "ios/chrome/browser/ui/commands/generic_chrome_command.h" #include "ios/chrome/browser/ui/commands/ios_command_ids.h" #import "ios/chrome/browser/ui/ntp/new_tab_page_controller.h" @@ -121,6 +122,9 @@ // Tests that all items are accessible on the bookmarks page. - (void)testAccessibilityOnBookmarks { + if (experimental_flags::IsBookmarkReorderingEnabled()) { + EARL_GREY_TEST_SKIPPED(@"Only enabled with old Bookmarks UI."); + } SelectNewTabPagePanel(NewTabPage::kBookmarksPanel); chrome_test_util::VerifyAccessibilityForCurrentScreen(); DismissNewTabPagePanel();
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_header_view.h b/ios/chrome/browser/ui/ntp/new_tab_page_header_view.h index c8974821..9c3db90a 100644 --- a/ios/chrome/browser/ui/ntp/new_tab_page_header_view.h +++ b/ios/chrome/browser/ui/ntp/new_tab_page_header_view.h
@@ -27,12 +27,15 @@ // Changes the constraints of searchField based on its initialFrame and the // scroll view's y |offset|. Also adjust the alpha values for |_searchBoxBorder| // and |_shadow| and the constant values for the |constraints|. +// If |width| is > 0, it is used as the width to compute the new fake omnibox +// width. - (void)updateSearchFieldWidth:(NSLayoutConstraint*)widthConstraint height:(NSLayoutConstraint*)heightConstraint topMargin:(NSLayoutConstraint*)topMarginConstraint subviewConstraints:(NSArray*)constraints logoIsShowing:(BOOL)logoIsShowing - forOffset:(CGFloat)offset; + forOffset:(CGFloat)offset + width:(CGFloat)width; // Initializes |_searchBoxBorder| and |_shadow| and adds them to |searchField|. - (void)addViewsToSearchField:(UIView*)searchField;
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_header_view.mm b/ios/chrome/browser/ui/ntp/new_tab_page_header_view.mm index 8d122f4..12b4c022 100644 --- a/ios/chrome/browser/ui/ntp/new_tab_page_header_view.mm +++ b/ios/chrome/browser/ui/ntp/new_tab_page_header_view.mm
@@ -121,7 +121,9 @@ topMargin:(NSLayoutConstraint*)topMarginConstraint subviewConstraints:(NSArray*)constraints logoIsShowing:(BOOL)logoIsShowing - forOffset:(CGFloat)offset { + forOffset:(CGFloat)offset + width:(CGFloat)width { + CGFloat screenWidth = width > 0 ? width : self.bounds.size.width; // The scroll offset at which point searchField's frame should stop growing. CGFloat maxScaleOffset = self.frame.size.height - ntp_header::kMinHeaderHeight; @@ -134,16 +136,16 @@ percent = MIN(1, MAX(0, animatingOffset / ntp_header::kAnimationDistance)); } - if (self.bounds.size.height == 0) + if (screenWidth == 0) return; CGFloat searchFieldNormalWidth = - content_suggestions::searchFieldWidth(self.bounds.size.width); + content_suggestions::searchFieldWidth(screenWidth); // Calculate the amount to grow the width and height of searchField so that // its frame covers the entire toolbar area. CGFloat maxXInset = ui::AlignValueToUpperPixel( - (searchFieldNormalWidth - self.bounds.size.width) / 2 - 1); + (searchFieldNormalWidth - screenWidth) / 2 - 1); CGFloat maxHeightDiff = ntp_header::kToolbarHeight - content_suggestions::kSearchFieldHeight;
diff --git a/ios/chrome/browser/ui/qr_scanner/BUILD.gn b/ios/chrome/browser/ui/qr_scanner/BUILD.gn index 7e74d40..dcd4435 100644 --- a/ios/chrome/browser/ui/qr_scanner/BUILD.gn +++ b/ios/chrome/browser/ui/qr_scanner/BUILD.gn
@@ -27,6 +27,7 @@ "//ios/chrome/browser", "//ios/chrome/browser/ui", "//ios/chrome/browser/ui/icons", + "//ios/chrome/browser/ui/qr_scanner/requirements", "//ios/chrome/common:ios_app_bundle_id_prefix_header", "//ios/third_party/material_components_ios", "//ui/base", @@ -37,6 +38,23 @@ ] } +source_set("coordinator") { + configs += [ "//build/config/compiler:enable_arc" ] + sources = [ + "qr_scanner_legacy_coordinator.h", + "qr_scanner_legacy_coordinator.mm", + ] + deps = [ + ":qr_scanner", + "//ios/chrome/browser", + "//ios/chrome/browser/browser_state", + "//ios/chrome/browser/tabs", + "//ios/chrome/browser/ui/commands", + "//ios/chrome/browser/ui/qr_scanner/requirements", + "//ios/shared/chrome/browser/ui/commands", + ] +} + source_set("eg_tests") { configs += [ "//build/config/compiler:enable_arc" ] testonly = true
diff --git a/ios/chrome/browser/ui/qr_scanner/qr_scanner_legacy_coordinator.h b/ios/chrome/browser/ui/qr_scanner/qr_scanner_legacy_coordinator.h new file mode 100644 index 0000000..93b44b2 --- /dev/null +++ b/ios/chrome/browser/ui/qr_scanner/qr_scanner_legacy_coordinator.h
@@ -0,0 +1,32 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_QR_SCANNER_QR_SCANNER_LEGACY_COORDINATOR_H_ +#define IOS_CHROME_BROWSER_UI_QR_SCANNER_QR_SCANNER_LEGACY_COORDINATOR_H_ + +#import "ios/chrome/browser/chrome_coordinator.h" + +@class CommandDispatcher; +@protocol QRScannerPresenting; +@protocol QRScannerResultLoading; + +// QRScannerLegacyCoordinator presents the public interface for the QR scanner +// feature. +@interface QRScannerLegacyCoordinator : ChromeCoordinator + +// Models. +@property(nonatomic, readwrite, weak) CommandDispatcher* dispatcher; + +// Requirements. +@property(nonatomic, readwrite, weak) id<QRScannerPresenting> + presentationProvider; +@property(nonatomic, readwrite, weak) id<QRScannerResultLoading> loadProvider; + +// Removes references to any weak objects that this coordinator holds pointers +// to. +- (void)disconnect; + +@end + +#endif // IOS_CHROME_BROWSER_UI_QR_SCANNER_QR_SCANNER_LEGACY_COORDINATOR_H_
diff --git a/ios/chrome/browser/ui/qr_scanner/qr_scanner_legacy_coordinator.mm b/ios/chrome/browser/ui/qr_scanner/qr_scanner_legacy_coordinator.mm new file mode 100644 index 0000000..34858325 --- /dev/null +++ b/ios/chrome/browser/ui/qr_scanner/qr_scanner_legacy_coordinator.mm
@@ -0,0 +1,56 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/ui/qr_scanner/qr_scanner_legacy_coordinator.h" + +#import "ios/chrome/browser/ui/commands/browser_commands.h" +#import "ios/chrome/browser/ui/qr_scanner/qr_scanner_view_controller.h" +#import "ios/chrome/browser/ui/qr_scanner/requirements/qr_scanner_presenting.h" +#import "ios/shared/chrome/browser/ui/commands/command_dispatcher.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +@interface QRScannerLegacyCoordinator () + +@property(nonatomic, readwrite, strong) QRScannerViewController* viewController; + +@end + +@implementation QRScannerLegacyCoordinator + +@synthesize dispatcher = _dispatcher; +@synthesize loadProvider = _loadProvider; +@synthesize presentationProvider = _presentationProvider; +@synthesize viewController = _viewController; + +- (void)disconnect { + self.dispatcher = nil; +} + +- (void)setDispatcher:(CommandDispatcher*)dispatcher { + if (dispatcher == self.dispatcher) { + return; + } + + if (self.dispatcher) { + [self.dispatcher stopDispatchingToTarget:self]; + } + + [dispatcher startDispatchingToTarget:self + forSelector:@selector(showQRScanner)]; + _dispatcher = dispatcher; +} + +- (void)showQRScanner { + self.viewController = [[QRScannerViewController alloc] + initWithPresentationProvider:self.presentationProvider + loadProvider:self.loadProvider]; + [self.presentationProvider + presentQRScannerViewController:[self.viewController + getViewControllerToPresent]]; +} + +@end
diff --git a/ios/chrome/browser/ui/qr_scanner/qr_scanner_view_controller.h b/ios/chrome/browser/ui/qr_scanner/qr_scanner_view_controller.h index 973b6ef..6fc2671 100644 --- a/ios/chrome/browser/ui/qr_scanner/qr_scanner_view_controller.h +++ b/ios/chrome/browser/ui/qr_scanner/qr_scanner_view_controller.h
@@ -9,26 +9,14 @@ #include "ios/chrome/browser/ui/qr_scanner/camera_controller.h" -@protocol QRScannerViewControllerDelegate - -// Called when the scanner detects a valid code. Camera recording is stopped -// when a result is scanned and the QRScannerViewController is dismissed. This -// function is called when the dismissal completes. A valid code is any -// non-empty string. If |load| is YES, the scanned code was of a type which can -// only encode digits, and the delegate can load the result immediately, instead -// of prompting the user to confirm the result. -- (void)receiveQRScannerResult:(NSString*)qrScannerResult - loadImmediately:(BOOL)load; - -@end +@protocol QRScannerPresenting; +@protocol QRScannerResultLoading; @interface QRScannerViewController : UIViewController<CameraControllerDelegate> -// The delegate which receives the scanned result after the view controller is -// dismissed. -@property(nonatomic, weak) id<QRScannerViewControllerDelegate> delegate; - -- (instancetype)initWithDelegate:(id<QRScannerViewControllerDelegate>)delegate +- (instancetype) +initWithPresentationProvider:(id<QRScannerPresenting>)presentationProvider + loadProvider:(id<QRScannerResultLoading>)loadProvider NS_DESIGNATED_INITIALIZER; - (instancetype)initWithNibName:(NSString*)name
diff --git a/ios/chrome/browser/ui/qr_scanner/qr_scanner_view_controller.mm b/ios/chrome/browser/ui/qr_scanner/qr_scanner_view_controller.mm index c39eec38..c9a8bd2f 100644 --- a/ios/chrome/browser/ui/qr_scanner/qr_scanner_view_controller.mm +++ b/ios/chrome/browser/ui/qr_scanner/qr_scanner_view_controller.mm
@@ -12,6 +12,8 @@ #include "ios/chrome/browser/ui/qr_scanner/qr_scanner_alerts.h" #include "ios/chrome/browser/ui/qr_scanner/qr_scanner_transitioning_delegate.h" #include "ios/chrome/browser/ui/qr_scanner/qr_scanner_view.h" +#include "ios/chrome/browser/ui/qr_scanner/requirements/qr_scanner_presenting.h" +#include "ios/chrome/browser/ui/qr_scanner/requirements/qr_scanner_result_loading.h" #include "ios/chrome/grit/ios_strings.h" #include "ui/base/l10n/l10n_util.h" @@ -49,6 +51,10 @@ QRScannerTransitioningDelegate* _transitioningDelegate; } +@property(nonatomic, readwrite, weak) id<QRScannerPresenting> + presentationProvider; +@property(nonatomic, readwrite, weak) id<QRScannerResultLoading> loadProvider; + // Dismisses the QRScannerViewController and runs |completion| on completion. // Logs metrics according to the |reason| for dismissal. - (void)dismissForReason:(DismissalReason)reason @@ -72,15 +78,18 @@ @implementation QRScannerViewController -@synthesize delegate = _delegate; +@synthesize loadProvider = _loadProvider; +@synthesize presentationProvider = _presentationProvider; #pragma mark lifecycle -- (instancetype)initWithDelegate:(id<QRScannerViewControllerDelegate>)delegate { +- (instancetype) +initWithPresentationProvider:(id<QRScannerPresenting>)presentationProvider + loadProvider:(id<QRScannerResultLoading>)loadProvider { self = [super initWithNibName:nil bundle:nil]; if (self) { - DCHECK(delegate); - _delegate = delegate; + _loadProvider = loadProvider; + _presentationProvider = presentationProvider; _cameraController = [CameraController cameraControllerWithDelegate:self]; } return self; @@ -235,8 +244,9 @@ case IMPOSSIBLY_UNLIKELY_AUTHORIZATION_CHANGE: break; } - [[self presentingViewController] dismissViewControllerAnimated:YES - completion:completion]; + + [self.presentationProvider dismissQRScannerViewController:self + completion:completion]; } - (void)startReceivingNotifications { @@ -279,8 +289,8 @@ DCHECK(_result); [self dismissForReason:SCANNED_CODE withCompletion:^{ - [[self delegate] receiveQRScannerResult:_result - loadImmediately:_loadResultImmediately]; + [self.loadProvider receiveQRScannerResult:_result + loadImmediately:_loadResultImmediately]; }]; } } @@ -346,8 +356,8 @@ [_qrScannerView animateScanningResultWithCompletion:^void(void) { [self dismissForReason:SCANNED_CODE withCompletion:^{ - [[self delegate] receiveQRScannerResult:result - loadImmediately:load]; + [self.loadProvider receiveQRScannerResult:result + loadImmediately:load]; }]; }]; }
diff --git a/ios/chrome/browser/ui/qr_scanner/requirements/BUILD.gn b/ios/chrome/browser/ui/qr_scanner/requirements/BUILD.gn new file mode 100644 index 0000000..370741b6 --- /dev/null +++ b/ios/chrome/browser/ui/qr_scanner/requirements/BUILD.gn
@@ -0,0 +1,11 @@ +# Copyright 2017 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +source_set("requirements") { + configs += [ "//build/config/compiler:enable_arc" ] + sources = [ + "qr_scanner_presenting.h", + "qr_scanner_result_loading.h", + ] +}
diff --git a/ios/chrome/browser/ui/qr_scanner/requirements/qr_scanner_presenting.h b/ios/chrome/browser/ui/qr_scanner/requirements/qr_scanner_presenting.h new file mode 100644 index 0000000..8e22110 --- /dev/null +++ b/ios/chrome/browser/ui/qr_scanner/requirements/qr_scanner_presenting.h
@@ -0,0 +1,22 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_QR_SCANNER_REQUIREMENTS_QR_SCANNER_PRESENTING_H_ +#define IOS_CHROME_BROWSER_UI_QR_SCANNER_REQUIREMENTS_QR_SCANNER_PRESENTING_H_ + +// QRScannerPresenting contains methods that control how the QR scanner UI is +// presented and dismissed on screen. +@protocol QRScannerPresenting + +// Asks the implementer to present the given |controller|. +- (void)presentQRScannerViewController:(UIViewController*)controller; + +// Asks the implementer to dismiss the given |controller| and call the given +// |completion| afterwards. +- (void)dismissQRScannerViewController:(UIViewController*)controller + completion:(void (^)(void))completion; + +@end + +#endif // IOS_CHROME_BROWSER_UI_QR_SCANNER_REQUIREMENTS_QR_SCANNER_PRESENTING_H_
diff --git a/ios/chrome/browser/ui/qr_scanner/requirements/qr_scanner_result_loading.h b/ios/chrome/browser/ui/qr_scanner/requirements/qr_scanner_result_loading.h new file mode 100644 index 0000000..ef16745 --- /dev/null +++ b/ios/chrome/browser/ui/qr_scanner/requirements/qr_scanner_result_loading.h
@@ -0,0 +1,23 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_QR_SCANNER_REQUIREMENTS_QR_SCANNER_RESULT_LOADING_H_ +#define IOS_CHROME_BROWSER_UI_QR_SCANNER_REQUIREMENTS_QR_SCANNER_RESULT_LOADING_H_ + +// QRScannerResultLoading contains methods that allow the QR scanner to load +// pages when valid QR codes are detected. +@protocol QRScannerResultLoading + +// Called when the scanner detects a valid code. Camera recording is stopped +// when a result is scanned and the QRScannerViewController is dismissed. This +// function is called when the dismissal completes. A valid code is any +// non-empty string. If |load| is YES, the scanned code was of a type which can +// only encode digits, and the delegate can load the result immediately, instead +// of prompting the user to confirm the result. +- (void)receiveQRScannerResult:(NSString*)qrScannerResult + loadImmediately:(BOOL)load; + +@end + +#endif // IOS_CHROME_BROWSER_UI_QR_SCANNER_REQUIREMENTS_QR_SCANNER_RESULT_LOADING_H_
diff --git a/ios/chrome/browser/ui/toolbar/BUILD.gn b/ios/chrome/browser/ui/toolbar/BUILD.gn index 3b3854242..b5af691 100644 --- a/ios/chrome/browser/ui/toolbar/BUILD.gn +++ b/ios/chrome/browser/ui/toolbar/BUILD.gn
@@ -68,7 +68,7 @@ "//ios/chrome/browser/ui/history_popup/requirements", "//ios/chrome/browser/ui/keyboard", "//ios/chrome/browser/ui/popup_menu", - "//ios/chrome/browser/ui/qr_scanner", + "//ios/chrome/browser/ui/qr_scanner/requirements", "//ios/chrome/browser/ui/toolbar/keyboard_assist", "//ios/chrome/browser/ui/tools_menu", "//ios/chrome/browser/ui/tools_menu:configuration",
diff --git a/ios/chrome/browser/ui/toolbar/toolbar_egtest.mm b/ios/chrome/browser/ui/toolbar/toolbar_egtest.mm index 519caa69..6e2eecf 100644 --- a/ios/chrome/browser/ui/toolbar/toolbar_egtest.mm +++ b/ios/chrome/browser/ui/toolbar/toolbar_egtest.mm
@@ -288,6 +288,12 @@ EARL_GREY_TEST_DISABLED(@"Disabled on iOS 9."); } + // TODO(crbug.com/755782): Re-enable this test. It is failing on some iOS 11 + // configurations. + if (base::ios::IsRunningOnIOS10OrLater()) { + EARL_GREY_TEST_DISABLED(@"Disabled on iOS 11."); + } + // Clear generalPasteboard before and after the test. [UIPasteboard generalPasteboard].string = @""; [self setTearDownHandler:^{
diff --git a/ios/chrome/browser/ui/toolbar/web_toolbar_controller.h b/ios/chrome/browser/ui/toolbar/web_toolbar_controller.h index 36d2a142..bc93d48 100644 --- a/ios/chrome/browser/ui/toolbar/web_toolbar_controller.h +++ b/ios/chrome/browser/ui/toolbar/web_toolbar_controller.h
@@ -10,7 +10,7 @@ #import "ios/chrome/browser/ui/history_popup/requirements/tab_history_positioner.h" #import "ios/chrome/browser/ui/history_popup/requirements/tab_history_ui_updater.h" #include "ios/chrome/browser/ui/omnibox/omnibox_popup_positioner.h" -#include "ios/chrome/browser/ui/qr_scanner/qr_scanner_view_controller.h" +#include "ios/chrome/browser/ui/qr_scanner/requirements/qr_scanner_result_loading.h" #import "ios/chrome/browser/ui/toolbar/toolbar_controller.h" #include "ios/public/provider/chrome/browser/voice/voice_search_controller_delegate.h" #include "ios/web/public/navigation_item_list.h" @@ -85,7 +85,7 @@ // omnibox, etc. @interface WebToolbarController : ToolbarController<OmniboxFocuser, - QRScannerViewControllerDelegate, + QRScannerResultLoading, TabHistoryPositioner, TabHistoryUIUpdater, VoiceSearchControllerDelegate>
diff --git a/ios/chrome/browser/ui/toolbar/web_toolbar_controller.mm b/ios/chrome/browser/ui/toolbar/web_toolbar_controller.mm index fc165bc..000b3a3 100644 --- a/ios/chrome/browser/ui/toolbar/web_toolbar_controller.mm +++ b/ios/chrome/browser/ui/toolbar/web_toolbar_controller.mm
@@ -1368,7 +1368,7 @@ } #pragma mark - -#pragma mark QRScannerViewControllerDelegate methods. +#pragma mark QRScanner Requirements. - (void)receiveQRScannerResult:(NSString*)result loadImmediately:(BOOL)load { DCHECK(result);
diff --git a/ios/chrome/browser/web/BUILD.gn b/ios/chrome/browser/web/BUILD.gn index ff86093b..935fc7d 100644 --- a/ios/chrome/browser/web/BUILD.gn +++ b/ios/chrome/browser/web/BUILD.gn
@@ -270,6 +270,7 @@ "//ios/web/public/test", "//ios/web/public/test/http_server", "//net", + "//net:test_support", "//ui/base", "//url", ]
diff --git a/ios/chrome/browser/web/navigation_egtest.mm b/ios/chrome/browser/web/navigation_egtest.mm index 8ba939e..e3ab459 100644 --- a/ios/chrome/browser/web/navigation_egtest.mm +++ b/ios/chrome/browser/web/navigation_egtest.mm
@@ -10,9 +10,8 @@ #import "ios/chrome/test/earl_grey/chrome_earl_grey.h" #import "ios/chrome/test/earl_grey/chrome_matchers.h" #import "ios/chrome/test/earl_grey/chrome_test_case.h" -#include "ios/web/public/test/http_server/data_response_provider.h" -#import "ios/web/public/test/http_server/http_server.h" -#include "ios/web/public/test/http_server/http_server_util.h" +#include "net/test/embedded_test_server/http_request.h" +#include "net/test/embedded_test_server/http_response.h" #include "ui/base/l10n/l10n_util.h" #if !defined(__has_feature) || !__has_feature(objc_arc) @@ -39,12 +38,9 @@ // When a button on the page is tapped, all pre-existing div text is cleared, // so matching against this webview text after a button is tapped ensures that // the state is set in response to the most recently executed script. -const char kWindowHistoryGoTestURL[] = - "http://ios/testing/data/http_server_files/history_go.html"; - -// URL of a sample file-based page. -const char kSampleFileBasedURL[] = - "http://ios/testing/data/http_server_files/chromium_logo_page.html"; +const char kWindowHistoryGoTestURL[] = "/history_go.html"; +// URL for a file based test page which gives a simple string response. +const char kSimpleFileBasedTestURL[] = "/pony.html"; // Strings used by history_go.html. const char kOnLoadText[] = "OnLoadText"; @@ -53,26 +49,18 @@ // Button ids for history_go.html. NSString* const kGoNoParameterID = @"go-no-parameter"; NSString* const kGoZeroID = @"go-zero"; +NSString* const kGoForwardID = @"go-forward"; NSString* const kGoTwoID = @"go-2"; +NSString* const kGoBackID = @"go-back"; NSString* const kGoBackTwoID = @"go-back-2"; -// URLs and labels for tests that navigate back and forward. -const char kBackHTMLButtonLabel[] = "BackHTMLButton"; -const char kForwardHTMLButtonLabel[] = "ForwardHTMLButton"; -const char kForwardHTMLSentinel[] = "Forward page loaded"; -const char kTestPageSentinel[] = "Test Page"; -const char kBackURL[] = "http://back"; -const char kForwardURL[] = "http://forward"; -const char kTestURL[] = "http://test"; - -// URLs and labels for scenarioWindowLocation* tests. +// URLs and labels for testWindowLocation* tests. const char kHashChangeWithHistoryLabel[] = "hashChangedWithHistory"; const char kHashChangeWithoutHistoryLabel[] = "hashChangedWithoutHistory"; -const char kPage1URL[] = "http://page1"; -const char kHashChangedWithHistoryURL[] = - "http://page1/#hashChangedWithHistory"; +const char kPage1URL[] = "/page1/"; +const char kHashChangedWithHistoryURL[] = "/page1/#hashChangedWithHistory"; const char kHashChangedWithoutHistoryURL[] = - "http://page1/#hashChangedWithoutHistory"; + "/page1/#hashChangedWithoutHistory"; const char kNoHashChangeText[] = "No hash change"; // An HTML page with two links that run JavaScript when they're clicked. The // first link updates |window.location.hash|, the second link changes @@ -86,97 +74,53 @@ " id=\"hashChangedWithoutHistory\">hashChangedWithoutHistory</a>" "</body></html>"; -void SetupBackAndForwardResponseProvider() { - std::map<GURL, std::string> responses; - GURL testURL = web::test::HttpServer::MakeUrl(kTestURL); - GURL backURL = web::test::HttpServer::MakeUrl(kBackURL); - GURL forwardURL = web::test::HttpServer::MakeUrl(kForwardURL); - responses[testURL] = "<html>Test Page</html>"; - responses[backURL] = - "<html>" - "<input type=\"button\" value=\"BackHTMLButton\" id=\"BackHTMLButton\"" - "onclick=\"window.history.back()\" />" - "</html>"; - responses[forwardURL] = - "<html>" - "<input type=\"button\" value=\"ForwardHTMLButton\"" - "id=\"ForwardHTMLButton\" onclick=\"window.history.forward()\" /></br>" - "Forward page loaded</html>"; - web::test::SetUpSimpleHttpServer(responses); +// URLs for server redirect tests. +const char kRedirectIndexURL[] = "/redirect"; +const char kRedirectWindowURL[] = "/redirectWindow.html"; +const char kDestinationURL[] = "/destination.html"; +// Default URL for a sample html page. It is registered in the default handlers. +const char kDefaultPageURL[] = "/defaultresponse"; + +// Provides responses for redirect and changed window location URLs. +std::unique_ptr<net::test_server::HttpResponse> RedirectHandlers( + const net::test_server::HttpRequest& request) { + std::unique_ptr<net::test_server::BasicHttpResponse> http_response( + new net::test_server::BasicHttpResponse); + http_response->set_code(net::HTTP_OK); + if (request.relative_url == kRedirectIndexURL) { + http_response->set_content( + "<p><a href=\"server-redirect?destination.html\"" + " id=\"redirect301\">redirect301</a></p>" + "<p><a href=\"client-redirect?destination.html\"" + " id=\"redirectRefresh\">redirectRefresh</a></p>" + "<p><a href=\"redirectWindow.html\"" + " id=\"redirectWindow\">redirectWindow</a></p>"); + } else if (request.relative_url == kRedirectWindowURL) { + http_response->set_content( + "<head>" + " <meta HTTP-EQUIV=\"REFRESH\" content=\"0; url=destination.html\">" + "</head>" + "<body>Redirecting" + " <script>window.open(\"destination.html\", \"_self\");</script>" + "</body>"); + } else { + return nullptr; + } + return std::move(http_response); } -// URLs for server redirect tests. -const char kRedirectIndexURL[] = "http://redirect"; -const char kRedirect301URL[] = "http://redirect/redirect?code=301"; -const char kRedirectWindowURL[] = "http://redirect/redirectWindow.html"; -const char kRedirectRefreshURL[] = "http://redirect/redirectRefresh.html"; -const char kDestinationURL[] = "http://redirect/destination.html"; -const char kLastURL[] = "http://redirect/last.html"; - -class RedirectResponseProvider : public web::DataResponseProvider { - public: - RedirectResponseProvider() - : index_url_(web::test::HttpServer::MakeUrl(kRedirectIndexURL)), - redirect_301_url_(web::test::HttpServer::MakeUrl(kRedirect301URL)), - redirect_refresh_url_( - web::test::HttpServer::MakeUrl(kRedirectRefreshURL)), - redirect_window_url_( - web::test::HttpServer::MakeUrl(kRedirectWindowURL)), - destination_url_(web::test::HttpServer::MakeUrl(kDestinationURL)) {} - - private: - bool CanHandleRequest(const Request& request) override { - return request.url == index_url_ || request.url == redirect_window_url_ || - request.url == redirect_refresh_url_ || - request.url == redirect_301_url_ || request.url == destination_url_; +// Provides responses for redirect and changed window location URLs. +std::unique_ptr<net::test_server::HttpResponse> WindowLocationHashHandlers( + const net::test_server::HttpRequest& request) { + std::unique_ptr<net::test_server::BasicHttpResponse> http_response( + new net::test_server::BasicHttpResponse); + http_response->set_code(net::HTTP_OK); + if (request.relative_url != kPage1URL) { + return nullptr; } - void GetResponseHeadersAndBody( - const Request& request, - scoped_refptr<net::HttpResponseHeaders>* headers, - std::string* response_body) override { - *headers = GetDefaultResponseHeaders(); - if (request.url == index_url_) { - *response_body = - "<p><a href=\"redirect?code=301\"" - " id=\"redirect301\">redirect301</a></p>" - "<p><a href=\"redirectRefresh.html\"" - " id=\"redirectRefresh\">redirectRefresh</a></p>" - "<p><a href=\"redirectWindow.html\"" - " id=\"redirectWindow\">redirectWindow</a></p>"; - } else if (request.url == redirect_301_url_) { - *headers = GetRedirectResponseHeaders(destination_url_.spec(), - net::HTTP_MOVED_PERMANENTLY); - } else if (request.url == redirect_refresh_url_) { - *response_body = - "<head>" - " <meta HTTP-EQUIV=\"REFRESH\" content=\"0; url=destination.html\">" - "</head>" - "<body><p>Redirecting</p></body>"; - } else if (request.url == redirect_window_url_) { - *response_body = - "<head>" - " <meta HTTP-EQUIV=\"REFRESH\" content=\"0; url=destination.html\">" - "</head>" - "<body>Redirecting" - " <script>window.open(\"destination.html\", \"_self\");</script>" - "</body>"; - } else if (request.url == destination_url_) { - *response_body = "<html><body><p>You've arrived</p></body></html>"; - } else if (request.url == last_url_) { - *response_body = "<html><body><p>Go back from here</p></body></html>"; - } else { - NOTREACHED(); - } - } - - // Member variables for test URLs. - const GURL index_url_; - const GURL redirect_301_url_; - const GURL redirect_refresh_url_; - const GURL redirect_window_url_; - const GURL destination_url_; - const GURL last_url_; -}; + http_response->set_content(kHashChangedHTML); + return std::move(http_response); +} } // namespace @@ -201,11 +145,10 @@ // Tests reloading the current page via window.history.go() with no parameters. - (void)testHistoryGoNoParameter { - web::test::SetUpFileBasedHttpServer(); - + GREYAssertTrue(self.testServer->Start(), @"Test server failed to start."); // Load the history test page and ensure that its onload text is visible. const GURL windowHistoryURL = - web::test::HttpServer::MakeUrl(kWindowHistoryGoTestURL); + self.testServer->GetURL(kWindowHistoryGoTestURL); [ChromeEarlGrey loadURL:windowHistoryURL]; [ChromeEarlGrey waitForWebViewContainingText:kOnLoadText]; @@ -220,11 +163,10 @@ // Tests reloading the current page via history.go(0). - (void)testHistoryGoDeltaZero { - web::test::SetUpFileBasedHttpServer(); - + GREYAssertTrue(self.testServer->Start(), @"Test server failed to start."); // Load the history test page and ensure that its onload text is visible. const GURL windowHistoryURL = - web::test::HttpServer::MakeUrl(kWindowHistoryGoTestURL); + self.testServer->GetURL(kWindowHistoryGoTestURL); [ChromeEarlGrey loadURL:windowHistoryURL]; [ChromeEarlGrey waitForWebViewContainingText:kOnLoadText]; @@ -240,11 +182,10 @@ // Tests that calling window.history.go() with an offset that is out of bounds // is a no-op. - (void)testHistoryGoOutOfBounds { - web::test::SetUpFileBasedHttpServer(); - + GREYAssertTrue(self.testServer->Start(), @"Test server failed to start."); // Load the history test page and ensure that its onload text is visible. const GURL windowHistoryURL = - web::test::HttpServer::MakeUrl(kWindowHistoryGoTestURL); + self.testServer->GetURL(kWindowHistoryGoTestURL); [ChromeEarlGrey loadURL:windowHistoryURL]; [ChromeEarlGrey waitForWebViewContainingText:kOnLoadText]; @@ -263,38 +204,29 @@ // Tests going back and forward via history.go(). - (void)testHistoryGoDelta { - std::map<GURL, std::string> responses; - const GURL firstURL = web::test::HttpServer::MakeUrl("http://page1"); - const GURL secondURL = web::test::HttpServer::MakeUrl("http://page2"); - const GURL thirdURL = web::test::HttpServer::MakeUrl("http://page3"); - const GURL fourthURL = web::test::HttpServer::MakeUrl("http://page4"); - responses[firstURL] = - "page1 <input type='button' value='goForward' id='goForward' " - "onclick='window.history.go(2)' />"; - responses[secondURL] = "page2"; - responses[thirdURL] = "page3"; - responses[fourthURL] = - "page4 <input type='button' value='goBack' id='goBack' " - "onclick='window.history.go(-3)' />"; - web::test::SetUpSimpleHttpServer(responses); + GREYAssertTrue(self.testServer->Start(), @"Test server failed to start."); + const GURL firstURL = self.testServer->GetURL(kWindowHistoryGoTestURL); + const GURL secondURL = self.testServer->GetURL("/memory_usage.html"); + const GURL thirdURL = self.testServer->GetURL(kSimpleFileBasedTestURL); + const GURL fourthURL = self.testServer->GetURL("/history.html"); // Load 4 pages. [ChromeEarlGrey loadURL:firstURL]; [ChromeEarlGrey loadURL:secondURL]; [ChromeEarlGrey loadURL:thirdURL]; [ChromeEarlGrey loadURL:fourthURL]; - [ChromeEarlGrey waitForWebViewContainingText:"page4"]; + [ChromeEarlGrey waitForWebViewContainingText:"onload"]; // Tap button to go back 3 pages. - TapWebViewElementWithId("goBack"); - [ChromeEarlGrey waitForWebViewContainingText:"page1"]; + [ChromeEarlGrey tapWebViewElementWithID:@"goBack3"]; + [ChromeEarlGrey waitForWebViewContainingText:kOnLoadText]; [[EarlGrey selectElementWithMatcher:chrome_test_util::OmniboxText( firstURL.GetContent())] assertWithMatcher:grey_notNil()]; // Tap button to go forward 2 pages. - TapWebViewElementWithId("goForward"); - [ChromeEarlGrey waitForWebViewContainingText:"page3"]; + [ChromeEarlGrey tapWebViewElementWithID:kGoTwoID]; + [ChromeEarlGrey waitForWebViewContainingText:"pony"]; [[EarlGrey selectElementWithMatcher:chrome_test_util::OmniboxText( thirdURL.GetContent())] assertWithMatcher:grey_notNil()]; @@ -303,15 +235,14 @@ // Tests that calls to window.history.go() that span multiple documents causes // a load to occur. - (void)testHistoryCrossDocumentLoad { - web::test::SetUpFileBasedHttpServer(); - + GREYAssertTrue(self.testServer->Start(), @"Test server failed to start."); // Load the history test page and ensure that its onload text is visible. const GURL windowHistoryURL = - web::test::HttpServer::MakeUrl(kWindowHistoryGoTestURL); + self.testServer->GetURL(kWindowHistoryGoTestURL); [ChromeEarlGrey loadURL:windowHistoryURL]; [ChromeEarlGrey waitForWebViewContainingText:kOnLoadText]; - const GURL sampleURL = web::test::HttpServer::MakeUrl(kSampleFileBasedURL); + const GURL sampleURL = self.testServer->GetURL(kSimpleFileBasedTestURL); [ChromeEarlGrey loadURL:sampleURL]; [ChromeEarlGrey loadURL:windowHistoryURL]; @@ -328,18 +259,17 @@ // Tests going back via history.back() then forward via forward button. - (void)testHistoryBackNavigation { - SetupBackAndForwardResponseProvider(); - + GREYAssertTrue(self.testServer->Start(), @"Test server failed to start."); // Navigate to a URL. - const GURL firstURL = web::test::HttpServer::MakeUrl(kTestURL); + const GURL firstURL = self.testServer->GetURL(kSimpleFileBasedTestURL); [ChromeEarlGrey loadURL:firstURL]; // Navigate to an HTML page with a back button. - const GURL secondURL = web::test::HttpServer::MakeUrl(kBackURL); + const GURL secondURL = self.testServer->GetURL(kWindowHistoryGoTestURL); [ChromeEarlGrey loadURL:secondURL]; // Tap the back button in the HTML and verify the first URL is loaded. - TapWebViewElementWithId(kBackHTMLButtonLabel); + [ChromeEarlGrey tapWebViewElementWithID:kGoBackID]; [[EarlGrey selectElementWithMatcher:chrome_test_util::OmniboxText( firstURL.GetContent())] assertWithMatcher:grey_notNil()]; @@ -354,27 +284,26 @@ // Tests going back via back button then forward via history.forward(). - (void)testHistoryForwardNavigation { - SetupBackAndForwardResponseProvider(); - + GREYAssertTrue(self.testServer->Start(), @"Test server failed to start."); // Navigate to an HTML page with a forward button. - const GURL firstURL = web::test::HttpServer::MakeUrl(kForwardURL); + const GURL firstURL = self.testServer->GetURL(kWindowHistoryGoTestURL); [ChromeEarlGrey loadURL:firstURL]; // Navigate to some other page. - const GURL secondURL = web::test::HttpServer::MakeUrl(kTestURL); + const GURL secondURL = self.testServer->GetURL(kSimpleFileBasedTestURL); [ChromeEarlGrey loadURL:secondURL]; // Tap the back button in the toolbar and verify the page with forward button // is loaded. [[EarlGrey selectElementWithMatcher:BackButton()] performAction:grey_tap()]; - [ChromeEarlGrey waitForWebViewContainingText:kForwardHTMLSentinel]; + [ChromeEarlGrey waitForWebViewContainingText:kOnLoadText]; [[EarlGrey selectElementWithMatcher:chrome_test_util::OmniboxText( firstURL.GetContent())] assertWithMatcher:grey_notNil()]; // Tap the forward button in the HTML and verify the second URL is loaded. - TapWebViewElementWithId(kForwardHTMLButtonLabel); - [ChromeEarlGrey waitForWebViewContainingText:kTestPageSentinel]; + [ChromeEarlGrey tapWebViewElementWithID:kGoForwardID]; + [ChromeEarlGrey waitForWebViewContainingText:"pony"]; [[EarlGrey selectElementWithMatcher:chrome_test_util::OmniboxText( secondURL.GetContent())] assertWithMatcher:grey_notNil()]; @@ -405,11 +334,10 @@ #if !TARGET_IPHONE_SIMULATOR EARL_GREY_TEST_DISABLED(@"Test disabled on device."); #endif - - SetupBackAndForwardResponseProvider(); + GREYAssertTrue(self.testServer->Start(), @"Test server failed to start."); // Go to page 1 with a button which calls window.history.forward(). - const GURL forwardURL = web::test::HttpServer::MakeUrl(kForwardURL); + const GURL forwardURL = self.testServer->GetURL(kWindowHistoryGoTestURL); [ChromeEarlGrey loadURL:forwardURL]; // Go to page 2: 'www.badurljkljkljklfloofy.com'. This page should display a @@ -426,7 +354,7 @@ // Go forward to page 2 by calling window.history.forward() and assert that // the error page is shown. - TapWebViewElementWithId(kForwardHTMLButtonLabel); + [ChromeEarlGrey tapWebViewElementWithID:kGoForwardID]; [ChromeEarlGrey waitForErrorPage]; } @@ -435,13 +363,13 @@ // Loads a URL and modifies window.location.hash, then goes back and forward // and verifies the URLs and that hashchange event is fired. - (void)testWindowLocationChangeHash { - std::map<GURL, std::string> responses; - const GURL page1URL = web::test::HttpServer::MakeUrl(kPage1URL); + self.testServer->RegisterRequestHandler( + base::Bind(&WindowLocationHashHandlers)); + GREYAssertTrue(self.testServer->Start(), @"Test server failed to start."); + const GURL page1URL = self.testServer->GetURL(kPage1URL); const GURL hashChangedWithHistoryURL = - web::test::HttpServer::MakeUrl(kHashChangedWithHistoryURL); - responses[page1URL] = kHashChangedHTML; - responses[hashChangedWithHistoryURL] = kHashChangedHTML; - web::test::SetUpSimpleHttpServer(responses); + self.testServer->GetURL(kHashChangedWithHistoryURL); + [ChromeEarlGrey loadURL:page1URL]; // Click link to update location.hash and go to new URL (same page). @@ -477,14 +405,15 @@ // Loads a URL and replaces its location, then updates its location.hash // and verifies that going back returns to the replaced entry. - (void)testWindowLocationReplaceAndChangeHash { - std::map<GURL, std::string> responses; - const GURL page1URL = web::test::HttpServer::MakeUrl(kPage1URL); - const GURL hashChangedWithoutHistoryURL = - web::test::HttpServer::MakeUrl(kHashChangedWithoutHistoryURL); + self.testServer->RegisterRequestHandler( + base::Bind(&WindowLocationHashHandlers)); + GREYAssertTrue(self.testServer->Start(), @"Test server failed to start."); + const GURL page1URL = self.testServer->GetURL(kPage1URL); const GURL hashChangedWithHistoryURL = - web::test::HttpServer::MakeUrl(kHashChangedWithHistoryURL); - responses[page1URL] = kHashChangedHTML; - web::test::SetUpSimpleHttpServer(responses); + self.testServer->GetURL(kHashChangedWithHistoryURL); + const GURL hashChangedWithoutHistoryURL = + self.testServer->GetURL(kHashChangedWithoutHistoryURL); + [ChromeEarlGrey loadURL:page1URL]; // Tap link to replace the location value. @@ -513,12 +442,13 @@ // Loads a URL and modifies window.location.hash twice, verifying that there is // only one entry in the history by navigating back. - (void)testWindowLocationChangeToSameHash { - std::map<GURL, std::string> responses; - const GURL page1URL = web::test::HttpServer::MakeUrl(kPage1URL); + self.testServer->RegisterRequestHandler( + base::Bind(&WindowLocationHashHandlers)); + GREYAssertTrue(self.testServer->Start(), @"Test server failed to start."); + const GURL page1URL = self.testServer->GetURL(kPage1URL); const GURL hashChangedWithHistoryURL = - web::test::HttpServer::MakeUrl(kHashChangedWithHistoryURL); - responses[page1URL] = kHashChangedHTML; - web::test::SetUpSimpleHttpServer(responses); + self.testServer->GetURL(kHashChangedWithHistoryURL); + [ChromeEarlGrey loadURL:page1URL]; // Tap link to update location.hash with a new value. @@ -551,20 +481,14 @@ // Navigates to a page that immediately redirects to another page via JavaScript // then verifies the browsing history. - (void)testJavaScriptRedirect { - std::map<GURL, std::string> responses; + self.testServer->RegisterRequestHandler(base::Bind(&RedirectHandlers)); + GREYAssertTrue(self.testServer->Start(), @"Test server failed to start."); // A starting page. - const GURL initialURL = web::test::HttpServer::MakeUrl("http://initialURL"); + const GURL initialURL = self.testServer->GetURL(kDefaultPageURL); // A page that redirects immediately via the window.open JavaScript method. - const GURL originURL = web::test::HttpServer::MakeUrl( - "http://scenarioJavaScriptRedirect_origin"); - const GURL destinationURL = - web::test::HttpServer::MakeUrl("http://destination"); - responses[initialURL] = "<html><body>Initial page</body></html>"; - responses[originURL] = - "<script>window.open('" + destinationURL.spec() + "', '_self');</script>"; - responses[destinationURL] = "scenarioJavaScriptRedirect destination"; + const GURL originURL = self.testServer->GetURL(kRedirectWindowURL); + const GURL destinationURL = self.testServer->GetURL(kDestinationURL); - web::test::SetUpSimpleHttpServer(responses); [ChromeEarlGrey loadURL:initialURL]; [ChromeEarlGrey loadURL:originURL]; [[EarlGrey selectElementWithMatcher:chrome_test_util::OmniboxText( @@ -588,27 +512,18 @@ // Test to load a page that contains a redirect window, then does multiple back // and forth navigations. - (void)testRedirectWindow { - std::unique_ptr<web::DataResponseProvider> provider( - new RedirectResponseProvider()); - web::test::SetUpHttpServer(std::move(provider)); [self verifyBackAndForwardAfterRedirect:"redirectWindow"]; } // Test to load a page that contains a redirect refresh, then does multiple back // and forth navigations. - (void)testRedirectRefresh { - std::unique_ptr<web::DataResponseProvider> provider( - new RedirectResponseProvider()); - web::test::SetUpHttpServer(std::move(provider)); [self verifyBackAndForwardAfterRedirect:"redirectRefresh"]; } // Test to load a page that performs a 301 redirect, then does multiple back and // forth navigations. - (void)test301Redirect { - std::unique_ptr<web::DataResponseProvider> provider( - new RedirectResponseProvider()); - web::test::SetUpHttpServer(std::move(provider)); [self verifyBackAndForwardAfterRedirect:"redirect301"]; } @@ -628,9 +543,11 @@ } - (void)verifyBackAndForwardAfterRedirect:(std::string)redirectLabel { - const GURL indexURL(web::test::HttpServer::MakeUrl(kRedirectIndexURL)); - const GURL destinationURL(web::test::HttpServer::MakeUrl(kDestinationURL)); - const GURL lastURL(web::test::HttpServer::MakeUrl(kLastURL)); + self.testServer->RegisterRequestHandler(base::Bind(&RedirectHandlers)); + GREYAssertTrue(self.testServer->Start(), @"Test server failed to start."); + const GURL indexURL(self.testServer->GetURL(kRedirectIndexURL)); + const GURL destinationURL(self.testServer->GetURL(kDestinationURL)); + const GURL lastURL(self.testServer->GetURL(kDefaultPageURL)); // Load index, tap on redirect link, and assert that the page is redirected // to the proper destination.
diff --git a/ios/chrome/test/BUILD.gn b/ios/chrome/test/BUILD.gn index cce1532..3ddc019e 100644 --- a/ios/chrome/test/BUILD.gn +++ b/ios/chrome/test/BUILD.gn
@@ -176,6 +176,7 @@ "//ios/chrome/browser/ui/context_menu:unit_tests", "//ios/chrome/browser/ui/contextual_search:unit_tests", "//ios/chrome/browser/ui/contextual_search/settings:unit_tests", + "//ios/chrome/browser/ui/coordinators:unit_tests", "//ios/chrome/browser/ui/dialogs:unit_tests", "//ios/chrome/browser/ui/dialogs:unit_tests_internal", "//ios/chrome/browser/ui/downloads:unit_tests", @@ -217,7 +218,6 @@ "//ios/chrome/test/base:unit_tests", "//ios/shared/chrome/browser/ui/broadcaster:unit_tests", "//ios/shared/chrome/browser/ui/commands:unit_tests", - "//ios/shared/chrome/browser/ui/coordinators:unit_tests", "//ios/shared/chrome/browser/ui/dialogs:unit_tests", "//ios/testing:http_server_bundle_data", ]
diff --git a/ios/chrome/test/earl_grey/BUILD.gn b/ios/chrome/test/earl_grey/BUILD.gn index bee6b5d..23d95f1e 100644 --- a/ios/chrome/test/earl_grey/BUILD.gn +++ b/ios/chrome/test/earl_grey/BUILD.gn
@@ -207,6 +207,7 @@ "//build/config/ios:xctest", "//ios/third_party/earl_grey", "//ios/web/public/test/fakes", + "//net:test_support", ] libs = [
diff --git a/ios/chrome/test/earl_grey/chrome_test_case.h b/ios/chrome/test/earl_grey/chrome_test_case.h index 7799f05..c907dcf5 100644 --- a/ios/chrome/test/earl_grey/chrome_test_case.h +++ b/ios/chrome/test/earl_grey/chrome_test_case.h
@@ -9,20 +9,24 @@ #import "base/ios/block_types.h" #import "ios/testing/earl_grey/disabled_test_macros.h" +#include "net/test/embedded_test_server/embedded_test_server.h" // Base class for all Chrome Earl Grey tests. @interface ChromeTestCase : XCTestCase -// Sets a block to always be executed at the end of a test during tearDown, -// whether the test passes or fails. This shall only be set once per test. -- (void)setTearDownHandler:(ProceduralBlock)tearDownHandler; - // Removes any UI elements that are present, to ensure it is in a clean state. + (void)removeAnyOpenMenusAndInfoBars; // Closes all tabs, and waits for the UI to synchronize. + (void)closeAllTabs; +// The EmbeddedTestServer instance that hosts HTTP requests for tests. +@property(nonatomic, readonly) net::test_server::EmbeddedTestServer* testServer; + +// Sets a block to always be executed at the end of a test during tearDown, +// whether the test passes or fails. This shall only be set once per test. +- (void)setTearDownHandler:(ProceduralBlock)tearDownHandler; + // Turns off mock authentication. It will automatically be re-enabled at the // end of the test. This shall only be called once per test. - (void)disableMockAuthentication;
diff --git a/ios/chrome/test/earl_grey/chrome_test_case.mm b/ios/chrome/test/earl_grey/chrome_test_case.mm index 6da92b8..6e337f1 100644 --- a/ios/chrome/test/earl_grey/chrome_test_case.mm +++ b/ios/chrome/test/earl_grey/chrome_test_case.mm
@@ -76,6 +76,7 @@ ]; const CFTimeInterval kDrainTimeout = 5; + } // namespace @interface ChromeTestCase () { @@ -84,6 +85,7 @@ BOOL _isHTTPServerStopped; BOOL _isMockAuthenticationDisabled; + std::unique_ptr<net::EmbeddedTestServer> _testServer; } // Cleans up mock authentication. @@ -156,6 +158,15 @@ [super tearDown]; } +- (net::EmbeddedTestServer*)testServer { + if (!_testServer) { + _testServer = base::MakeUnique<net::EmbeddedTestServer>(); + _testServer->AddDefaultHandlers(base::FilePath( + FILE_PATH_LITERAL("ios/testing/data/http_server_files/"))); + } + return _testServer.get(); +} + // Set up called once per test, to open a new tab. - (void)setUp { [super setUp];
diff --git a/ios/clean/README.md b/ios/clean/README.md index 8c41156..9f592eb 100644 --- a/ios/clean/README.md +++ b/ios/clean/README.md
@@ -66,7 +66,7 @@ Since view controllers are heavily encapsulated, another object is responsible for creating them and connecting them to other objects. This object is a coordinator, and in this architecture all coordinators are subclasses of -[BrowserCoordinator](/ios/shared/chrome/browser/ui/coordinators/). Coordinators +[BrowserCoordinator](/ios/chrome/browser/ui/coordinators/). Coordinators exist in a hierarchy, roughly parallel to the view controller hierarchy; each coordinator can have multiple child coordinators, and there is a single root coordinator that is created when the application launches.
diff --git a/ios/clean/chrome/app/BUILD.gn b/ios/clean/chrome/app/BUILD.gn index e261dfe..ad2da4a 100644 --- a/ios/clean/chrome/app/BUILD.gn +++ b/ios/clean/chrome/app/BUILD.gn
@@ -104,9 +104,9 @@ deps = [ "//base", + "//ios/chrome/browser/ui/coordinators", "//ios/clean/chrome/app/steps:step_runner", "//ios/clean/chrome/app/steps:steps", - "//ios/shared/chrome/browser/ui/coordinators", "//ios/testing/perf:startup", ] }
diff --git a/ios/clean/chrome/app/steps/BUILD.gn b/ios/clean/chrome/app/steps/BUILD.gn index c6640336..721503e 100644 --- a/ios/clean/chrome/app/steps/BUILD.gn +++ b/ios/clean/chrome/app/steps/BUILD.gn
@@ -56,11 +56,11 @@ "//ios/chrome/browser/browser_state:browser_state_impl", "//ios/chrome/browser/content_settings", "//ios/chrome/browser/ui/browser_list", + "//ios/chrome/browser/ui/coordinators", "//ios/chrome/browser/web:web_internal", "//ios/chrome/browser/web_state_list", "//ios/clean/chrome/browser/ui/root", "//ios/net", - "//ios/shared/chrome/browser/ui/coordinators", "//ios/web:web_arc", ] }
diff --git a/ios/clean/chrome/app/steps/root_coordinator+application_step.mm b/ios/clean/chrome/app/steps/root_coordinator+application_step.mm index 29ce9606..f7a1f51 100644 --- a/ios/clean/chrome/app/steps/root_coordinator+application_step.mm +++ b/ios/clean/chrome/app/steps/root_coordinator+application_step.mm
@@ -11,10 +11,10 @@ #import "ios/chrome/browser/ui/browser_list/browser_list.h" #import "ios/chrome/browser/ui/browser_list/browser_list_session_service.h" #import "ios/chrome/browser/ui/browser_list/browser_list_session_service_factory.h" +#import "ios/chrome/browser/ui/coordinators/browser_coordinator+internal.h" #import "ios/chrome/browser/web_state_list/web_state_list.h" #import "ios/chrome/browser/web_state_list/web_state_opener.h" #import "ios/clean/chrome/app/application_state.h" -#import "ios/shared/chrome/browser/ui/coordinators/browser_coordinator+internal.h" #import "ios/web/public/navigation_manager.h" #include "ios/web/public/web_state/web_state.h"
diff --git a/ios/clean/chrome/app/steps/root_coordinator_initializer.mm b/ios/clean/chrome/app/steps/root_coordinator_initializer.mm index 0feba6b..b2f03a5 100644 --- a/ios/clean/chrome/app/steps/root_coordinator_initializer.mm +++ b/ios/clean/chrome/app/steps/root_coordinator_initializer.mm
@@ -10,12 +10,12 @@ #import "ios/chrome/browser/ui/browser_list/browser_list.h" #import "ios/chrome/browser/ui/browser_list/browser_list_session_service.h" #import "ios/chrome/browser/ui/browser_list/browser_list_session_service_factory.h" +#import "ios/chrome/browser/ui/coordinators/browser_coordinator+internal.h" #import "ios/chrome/browser/web_state_list/web_state_list.h" #import "ios/chrome/browser/web_state_list/web_state_opener.h" #import "ios/clean/chrome/app/steps/step_context.h" #import "ios/clean/chrome/app/steps/step_features.h" #import "ios/clean/chrome/browser/ui/root/root_coordinator.h" -#import "ios/shared/chrome/browser/ui/coordinators/browser_coordinator+internal.h" #include "ios/web/public/web_state/web_state.h" @protocol StepContext;
diff --git a/ios/clean/chrome/browser/ui/bookmarks/BUILD.gn b/ios/clean/chrome/browser/ui/bookmarks/BUILD.gn index 591d83f..6fa9e645 100644 --- a/ios/clean/chrome/browser/ui/bookmarks/BUILD.gn +++ b/ios/clean/chrome/browser/ui/bookmarks/BUILD.gn
@@ -14,7 +14,7 @@ "//ios/chrome/browser/ui", "//ios/chrome/browser/ui/bookmarks", "//ios/chrome/browser/ui/browser_list", - "//ios/shared/chrome/browser/ui/coordinators", + "//ios/chrome/browser/ui/coordinators", ] }
diff --git a/ios/clean/chrome/browser/ui/bookmarks/bookmarks_coordinator.h b/ios/clean/chrome/browser/ui/bookmarks/bookmarks_coordinator.h index 1493cf9..4db8223 100644 --- a/ios/clean/chrome/browser/ui/bookmarks/bookmarks_coordinator.h +++ b/ios/clean/chrome/browser/ui/bookmarks/bookmarks_coordinator.h
@@ -7,7 +7,7 @@ #import <UIKit/UIKit.h> -#import "ios/shared/chrome/browser/ui/coordinators/browser_coordinator.h" +#import "ios/chrome/browser/ui/coordinators/browser_coordinator.h" // A coordinator for the bookmarks UI, which can be presented modally on its // own or inside the NTP.
diff --git a/ios/clean/chrome/browser/ui/bookmarks/bookmarks_coordinator.mm b/ios/clean/chrome/browser/ui/bookmarks/bookmarks_coordinator.mm index 63b16bc..deee9b79 100644 --- a/ios/clean/chrome/browser/ui/bookmarks/bookmarks_coordinator.mm +++ b/ios/clean/chrome/browser/ui/bookmarks/bookmarks_coordinator.mm
@@ -8,8 +8,8 @@ #import "ios/chrome/browser/ui/bookmarks/bookmark_home_handset_view_controller.h" #import "ios/chrome/browser/ui/bookmarks/bookmark_home_tablet_ntp_controller.h" #import "ios/chrome/browser/ui/browser_list/browser.h" +#import "ios/chrome/browser/ui/coordinators/browser_coordinator+internal.h" #include "ios/chrome/browser/ui/ui_util.h" -#import "ios/shared/chrome/browser/ui/coordinators/browser_coordinator+internal.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support."
diff --git a/ios/clean/chrome/browser/ui/context_menu/BUILD.gn b/ios/clean/chrome/browser/ui/context_menu/BUILD.gn index ec87bff..1f78852e 100644 --- a/ios/clean/chrome/browser/ui/context_menu/BUILD.gn +++ b/ios/clean/chrome/browser/ui/context_menu/BUILD.gn
@@ -17,10 +17,10 @@ deps = [ ":context_menu_ui", "//ios/chrome/browser/ui/browser_list", + "//ios/chrome/browser/ui/coordinators", "//ios/chrome/browser/web_state_list:web_state_list", "//ios/clean/chrome/browser/ui/commands:commands", "//ios/shared/chrome/browser/ui/commands", - "//ios/shared/chrome/browser/ui/coordinators", "//ios/web", "//ui/base", "//url",
diff --git a/ios/clean/chrome/browser/ui/context_menu/web_context_menu_coordinator.h b/ios/clean/chrome/browser/ui/context_menu/web_context_menu_coordinator.h index c5fa923..920dbe5 100644 --- a/ios/clean/chrome/browser/ui/context_menu/web_context_menu_coordinator.h +++ b/ios/clean/chrome/browser/ui/context_menu/web_context_menu_coordinator.h
@@ -7,7 +7,7 @@ #import <Foundation/Foundation.h> -#import "ios/shared/chrome/browser/ui/coordinators/browser_coordinator.h" +#import "ios/chrome/browser/ui/coordinators/browser_coordinator.h" @class ContextMenuContextImpl;
diff --git a/ios/clean/chrome/browser/ui/context_menu/web_context_menu_coordinator.mm b/ios/clean/chrome/browser/ui/context_menu/web_context_menu_coordinator.mm index 253777b..f790720 100644 --- a/ios/clean/chrome/browser/ui/context_menu/web_context_menu_coordinator.mm +++ b/ios/clean/chrome/browser/ui/context_menu/web_context_menu_coordinator.mm
@@ -6,12 +6,12 @@ #include "base/logging.h" #import "ios/chrome/browser/ui/browser_list/browser.h" +#import "ios/chrome/browser/ui/coordinators/browser_coordinator+internal.h" #import "ios/clean/chrome/browser/ui/commands/context_menu_commands.h" #import "ios/clean/chrome/browser/ui/context_menu/context_menu_context_impl.h" #import "ios/clean/chrome/browser/ui/context_menu/context_menu_mediator.h" #import "ios/clean/chrome/browser/ui/context_menu/context_menu_view_controller.h" #import "ios/shared/chrome/browser/ui/commands/command_dispatcher.h" -#import "ios/shared/chrome/browser/ui/coordinators/browser_coordinator+internal.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support."
diff --git a/ios/clean/chrome/browser/ui/find_in_page/BUILD.gn b/ios/clean/chrome/browser/ui/find_in_page/BUILD.gn index 918c16d..c0cb1b7 100644 --- a/ios/clean/chrome/browser/ui/find_in_page/BUILD.gn +++ b/ios/clean/chrome/browser/ui/find_in_page/BUILD.gn
@@ -17,12 +17,12 @@ "//base", "//ios/chrome/browser/find_in_page", "//ios/chrome/browser/ui/browser_list", + "//ios/chrome/browser/ui/coordinators", "//ios/chrome/browser/web_state_list", "//ios/clean/chrome/browser", "//ios/clean/chrome/browser/ui/actions", "//ios/clean/chrome/browser/ui/commands", "//ios/shared/chrome/browser/ui/commands", - "//ios/shared/chrome/browser/ui/coordinators", "//ios/web", ] }
diff --git a/ios/clean/chrome/browser/ui/find_in_page/find_in_page_coordinator.h b/ios/clean/chrome/browser/ui/find_in_page/find_in_page_coordinator.h index d55f6c8..d418b7b5 100644 --- a/ios/clean/chrome/browser/ui/find_in_page/find_in_page_coordinator.h +++ b/ios/clean/chrome/browser/ui/find_in_page/find_in_page_coordinator.h
@@ -7,7 +7,7 @@ #import <UIKit/UIKit.h> -#import "ios/shared/chrome/browser/ui/coordinators/browser_coordinator.h" +#import "ios/chrome/browser/ui/coordinators/browser_coordinator.h" // Coordinator that runs find in page: A find bar with a search field and // previous/next buttons.
diff --git a/ios/clean/chrome/browser/ui/find_in_page/find_in_page_coordinator.mm b/ios/clean/chrome/browser/ui/find_in_page/find_in_page_coordinator.mm index 01ec12e..4b7c2aeb 100644 --- a/ios/clean/chrome/browser/ui/find_in_page/find_in_page_coordinator.mm +++ b/ios/clean/chrome/browser/ui/find_in_page/find_in_page_coordinator.mm
@@ -9,12 +9,12 @@ #include "base/logging.h" #import "ios/chrome/browser/find_in_page/find_tab_helper.h" #import "ios/chrome/browser/ui/browser_list/browser.h" +#import "ios/chrome/browser/ui/coordinators/browser_coordinator+internal.h" #include "ios/chrome/browser/web_state_list/web_state_list.h" #import "ios/clean/chrome/browser/ui/commands/find_in_page_visibility_commands.h" #import "ios/clean/chrome/browser/ui/find_in_page/find_in_page_mediator.h" #import "ios/clean/chrome/browser/ui/find_in_page/find_in_page_view_controller.h" #import "ios/shared/chrome/browser/ui/commands/command_dispatcher.h" -#import "ios/shared/chrome/browser/ui/coordinators/browser_coordinator+internal.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support."
diff --git a/ios/clean/chrome/browser/ui/ntp/BUILD.gn b/ios/clean/chrome/browser/ui/ntp/BUILD.gn index d1972ca..0d1ef9d 100644 --- a/ios/clean/chrome/browser/ui/ntp/BUILD.gn +++ b/ios/clean/chrome/browser/ui/ntp/BUILD.gn
@@ -36,6 +36,7 @@ "//ios/chrome/browser/ui/content_suggestions", "//ios/chrome/browser/ui/content_suggestions:content_suggestions_util", "//ios/chrome/browser/ui/content_suggestions/cells", + "//ios/chrome/browser/ui/coordinators", "//ios/chrome/browser/ui/ntp", "//ios/chrome/browser/ui/ntp:ntp_controller", "//ios/chrome/browser/ui/ntp:ntp_internal", @@ -44,7 +45,6 @@ "//ios/clean/chrome/browser/ui/commands", "//ios/clean/chrome/browser/ui/recent_tabs", "//ios/shared/chrome/browser/ui/commands", - "//ios/shared/chrome/browser/ui/coordinators", "//ios/web:web_arc", "//ui/base:base", "//url:url",
diff --git a/ios/clean/chrome/browser/ui/ntp/ntp_coordinator.h b/ios/clean/chrome/browser/ui/ntp/ntp_coordinator.h index b17e815..72b43d7 100644 --- a/ios/clean/chrome/browser/ui/ntp/ntp_coordinator.h +++ b/ios/clean/chrome/browser/ui/ntp/ntp_coordinator.h
@@ -6,7 +6,7 @@ #define IOS_CLEAN_CHROME_BROWSER_UI_NTP_NTP_COORDINATOR_H_ #import <UIKit/UIKit.h> -#import "ios/shared/chrome/browser/ui/coordinators/browser_coordinator.h" +#import "ios/chrome/browser/ui/coordinators/browser_coordinator.h" // Coordinator that runs a "New Tab Page" : The UI displayed instead of a web // page when a new tab is created.
diff --git a/ios/clean/chrome/browser/ui/ntp/ntp_coordinator.mm b/ios/clean/chrome/browser/ui/ntp/ntp_coordinator.mm index 365ab19c..7ac26e1 100644 --- a/ios/clean/chrome/browser/ui/ntp/ntp_coordinator.mm +++ b/ios/clean/chrome/browser/ui/ntp/ntp_coordinator.mm
@@ -6,6 +6,7 @@ #include "base/logging.h" #import "ios/chrome/browser/ui/browser_list/browser.h" +#import "ios/chrome/browser/ui/coordinators/browser_coordinator+internal.h" #include "ios/chrome/browser/ui/ui_util.h" #import "ios/clean/chrome/browser/ui/bookmarks/bookmarks_coordinator.h" #import "ios/clean/chrome/browser/ui/commands/ntp_commands.h" @@ -14,7 +15,6 @@ #import "ios/clean/chrome/browser/ui/ntp/ntp_view_controller.h" #import "ios/clean/chrome/browser/ui/recent_tabs/recent_tabs_coordinator.h" #import "ios/shared/chrome/browser/ui/commands/command_dispatcher.h" -#import "ios/shared/chrome/browser/ui/coordinators/browser_coordinator+internal.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support."
diff --git a/ios/clean/chrome/browser/ui/ntp/ntp_home_coordinator.h b/ios/clean/chrome/browser/ui/ntp/ntp_home_coordinator.h index 54f734cb..952ba4fd 100644 --- a/ios/clean/chrome/browser/ui/ntp/ntp_home_coordinator.h +++ b/ios/clean/chrome/browser/ui/ntp/ntp_home_coordinator.h
@@ -6,7 +6,7 @@ #define IOS_CLEAN_CHROME_BROWSER_UI_NTP_NTP_HOME_COORDINATOR_H_ #import <UIKit/UIKit.h> -#import "ios/shared/chrome/browser/ui/coordinators/browser_coordinator.h" +#import "ios/chrome/browser/ui/coordinators/browser_coordinator.h" // Coordinator that runs the chrome home panel of the NTP. @interface NTPHomeCoordinator : BrowserCoordinator
diff --git a/ios/clean/chrome/browser/ui/ntp/ntp_home_coordinator.mm b/ios/clean/chrome/browser/ui/ntp/ntp_home_coordinator.mm index 19a27c76..a07fcf3 100644 --- a/ios/clean/chrome/browser/ui/ntp/ntp_home_coordinator.mm +++ b/ios/clean/chrome/browser/ui/ntp/ntp_home_coordinator.mm
@@ -32,6 +32,7 @@ #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.h" #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller_audience.h" #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller_delegate.h" +#import "ios/chrome/browser/ui/coordinators/browser_coordinator+internal.h" #import "ios/chrome/browser/ui/ntp/google_landing_mediator.h" #import "ios/chrome/browser/ui/ntp/google_landing_view_controller.h" #import "ios/chrome/browser/ui/ntp/new_tab_page_header_constants.h" @@ -40,7 +41,6 @@ #include "ios/chrome/grit/ios_strings.h" #import "ios/clean/chrome/browser/ui/ntp/ntp_home_header_coordinator.h" #import "ios/shared/chrome/browser/ui/commands/command_dispatcher.h" -#import "ios/shared/chrome/browser/ui/coordinators/browser_coordinator+internal.h" #import "ios/third_party/material_components_ios/src/components/Snackbar/src/MaterialSnackbar.h" #include "ui/base/l10n/l10n_util.h"
diff --git a/ios/clean/chrome/browser/ui/ntp/ntp_home_header_coordinator.h b/ios/clean/chrome/browser/ui/ntp/ntp_home_header_coordinator.h index 5bec29c0..2c43487 100644 --- a/ios/clean/chrome/browser/ui/ntp/ntp_home_header_coordinator.h +++ b/ios/clean/chrome/browser/ui/ntp/ntp_home_header_coordinator.h
@@ -6,7 +6,7 @@ #define IOS_CLEAN_CHROME_BROWSER_UI_NTP_NTP_HOME_HEADER_COORDINATOR_H_ #import <UIKit/UIKit.h> -#import "ios/shared/chrome/browser/ui/coordinators/browser_coordinator.h" +#import "ios/chrome/browser/ui/coordinators/browser_coordinator.h" @protocol ContentSuggestionsHeaderControlling; @protocol ContentSuggestionsHeaderProvider;
diff --git a/ios/clean/chrome/browser/ui/ntp/ntp_home_header_mediator.mm b/ios/clean/chrome/browser/ui/ntp/ntp_home_header_mediator.mm index 148692a..0fa1aa7 100644 --- a/ios/clean/chrome/browser/ui/ntp/ntp_home_header_mediator.mm +++ b/ios/clean/chrome/browser/ui/ntp/ntp_home_header_mediator.mm
@@ -45,7 +45,7 @@ #pragma mark - ContentSuggestionsHeaderControlling -- (void)updateFakeOmniboxForOffset:(CGFloat)offset { +- (void)updateFakeOmniboxForOffset:(CGFloat)offset width:(CGFloat)width { [self.headerViewController updateFakeOmniboxForOffset:offset]; }
diff --git a/ios/clean/chrome/browser/ui/ntp/ntp_home_header_view_controller.mm b/ios/clean/chrome/browser/ui/ntp/ntp_home_header_view_controller.mm index 1e79d4ca..0bd225b 100644 --- a/ios/clean/chrome/browser/ui/ntp/ntp_home_header_view_controller.mm +++ b/ios/clean/chrome/browser/ui/ntp/ntp_home_header_view_controller.mm
@@ -9,6 +9,7 @@ #include "components/strings/grit/components_strings.h" #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_synchronizing.h" #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils.h" +#import "ios/chrome/browser/ui/content_suggestions/ntp_home_constant.h" #import "ios/chrome/browser/ui/image_util.h" #import "ios/chrome/browser/ui/ntp/new_tab_page_header_constants.h" #import "ios/chrome/browser/ui/uikit_ui_util.h" @@ -173,16 +174,13 @@ [self.fakeOmnibox addTarget:self action:@selector(fakeOmniboxTapped:) forControlEvents:UIControlEventTouchUpInside]; - UILongPressGestureRecognizer* longPressRecognizer = [ - [UILongPressGestureRecognizer alloc] initWithTarget:self - action:@selector(doNothing)]; - longPressRecognizer.numberOfTouchesRequired = 1; - [self.fakeOmnibox addGestureRecognizer:longPressRecognizer]; [self.fakeOmnibox setAccessibilityLabel:l10n_util::GetNSString(IDS_OMNIBOX_EMPTY_HINT)]; // Set isAccessibilityElement to NO so that Voice Search button is accessible. [self.fakeOmnibox setIsAccessibilityElement:NO]; + self.fakeOmnibox.accessibilityIdentifier = + ntp_home::FakeOmniboxAccessibilityID(); // Set up fakebox hint label. UILabel* searchHintLabel = [[UILabel alloc] init]; @@ -295,9 +293,6 @@ [self.fakeOmniboxShadow setAlpha:0]; } -- (void)doNothing { -} - // TODO(crbug.com/740793): Remove this method once no item is using it. - (void)showAlert:(NSString*)title { UIAlertController* alertController =
diff --git a/ios/clean/chrome/browser/ui/omnibox/BUILD.gn b/ios/clean/chrome/browser/ui/omnibox/BUILD.gn index 1b75b9f..7b8474b 100644 --- a/ios/clean/chrome/browser/ui/omnibox/BUILD.gn +++ b/ios/clean/chrome/browser/ui/omnibox/BUILD.gn
@@ -15,11 +15,11 @@ "//components/toolbar", "//ios/chrome/browser/ssl", "//ios/chrome/browser/ui/browser_list", + "//ios/chrome/browser/ui/coordinators", "//ios/chrome/browser/ui/omnibox:omnibox_internal", "//ios/chrome/browser/ui/toolbar", "//ios/chrome/browser/web_state_list", "//ios/clean/chrome/browser", - "//ios/shared/chrome/browser/ui/coordinators", "//ios/shared/chrome/browser/ui/omnibox", "//ios/web", ]
diff --git a/ios/clean/chrome/browser/ui/omnibox/location_bar_coordinator.h b/ios/clean/chrome/browser/ui/omnibox/location_bar_coordinator.h index 273c3837..cafa82d 100644 --- a/ios/clean/chrome/browser/ui/omnibox/location_bar_coordinator.h +++ b/ios/clean/chrome/browser/ui/omnibox/location_bar_coordinator.h
@@ -5,7 +5,7 @@ #ifndef IOS_CLEAN_CHROME_BROWSER_UI_OMNIBOX_LOCATION_BAR_COORDINATOR_H_ #define IOS_CLEAN_CHROME_BROWSER_UI_OMNIBOX_LOCATION_BAR_COORDINATOR_H_ -#import "ios/shared/chrome/browser/ui/coordinators/browser_coordinator.h" +#import "ios/chrome/browser/ui/coordinators/browser_coordinator.h" // Coordinator for the location bar, which contains the omnibox and associated // decorations (such as the security icon, voice search icon, and bookmark
diff --git a/ios/clean/chrome/browser/ui/omnibox/location_bar_coordinator.mm b/ios/clean/chrome/browser/ui/omnibox/location_bar_coordinator.mm index 4e5ab50..daa0003 100644 --- a/ios/clean/chrome/browser/ui/omnibox/location_bar_coordinator.mm +++ b/ios/clean/chrome/browser/ui/omnibox/location_bar_coordinator.mm
@@ -6,11 +6,11 @@ #include "base/memory/ptr_util.h" #import "ios/chrome/browser/ui/browser_list/browser.h" +#import "ios/chrome/browser/ui/coordinators/browser_coordinator+internal.h" #import "ios/chrome/browser/ui/omnibox/location_bar_controller_impl.h" #include "ios/chrome/browser/ui/toolbar/toolbar_model_ios.h" #import "ios/clean/chrome/browser/ui/omnibox/location_bar_mediator.h" #import "ios/clean/chrome/browser/ui/omnibox/location_bar_view_controller.h" -#import "ios/shared/chrome/browser/ui/coordinators/browser_coordinator+internal.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support."
diff --git a/ios/clean/chrome/browser/ui/recent_tabs/BUILD.gn b/ios/clean/chrome/browser/ui/recent_tabs/BUILD.gn index 0fc25c9..9b2148f 100644 --- a/ios/clean/chrome/browser/ui/recent_tabs/BUILD.gn +++ b/ios/clean/chrome/browser/ui/recent_tabs/BUILD.gn
@@ -13,8 +13,8 @@ deps = [ "//ios/chrome/browser/ui", "//ios/chrome/browser/ui/browser_list", + "//ios/chrome/browser/ui/coordinators", "//ios/chrome/browser/ui/ntp/recent_tabs", - "//ios/shared/chrome/browser/ui/coordinators", ] }
diff --git a/ios/clean/chrome/browser/ui/recent_tabs/recent_tabs_coordinator.h b/ios/clean/chrome/browser/ui/recent_tabs/recent_tabs_coordinator.h index cdf85ae4..d095fc5 100644 --- a/ios/clean/chrome/browser/ui/recent_tabs/recent_tabs_coordinator.h +++ b/ios/clean/chrome/browser/ui/recent_tabs/recent_tabs_coordinator.h
@@ -6,7 +6,7 @@ #define IOS_CLEAN_CHROME_BROWSER_UI_RECENT_TABS_RECENT_TABS_COORDINATOR_H_ #import <UIKit/UIKit.h> -#import "ios/shared/chrome/browser/ui/coordinators/browser_coordinator.h" +#import "ios/chrome/browser/ui/coordinators/browser_coordinator.h" // A coordinator for the recent tabs UI, which can be presented modally on its // own or inside the NTP.
diff --git a/ios/clean/chrome/browser/ui/recent_tabs/recent_tabs_coordinator.mm b/ios/clean/chrome/browser/ui/recent_tabs/recent_tabs_coordinator.mm index d7bd8ceb..186b1dc5 100644 --- a/ios/clean/chrome/browser/ui/recent_tabs/recent_tabs_coordinator.mm +++ b/ios/clean/chrome/browser/ui/recent_tabs/recent_tabs_coordinator.mm
@@ -5,10 +5,10 @@ #import "ios/clean/chrome/browser/ui/recent_tabs/recent_tabs_coordinator.h" #import "ios/chrome/browser/ui/browser_list/browser.h" +#import "ios/chrome/browser/ui/coordinators/browser_coordinator+internal.h" #import "ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_panel_controller.h" #import "ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_panel_view_controller.h" #include "ios/chrome/browser/ui/ui_util.h" -#import "ios/shared/chrome/browser/ui/coordinators/browser_coordinator+internal.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support."
diff --git a/ios/clean/chrome/browser/ui/root/BUILD.gn b/ios/clean/chrome/browser/ui/root/BUILD.gn index c9c6460..a562aa5d 100644 --- a/ios/clean/chrome/browser/ui/root/BUILD.gn +++ b/ios/clean/chrome/browser/ui/root/BUILD.gn
@@ -10,11 +10,11 @@ deps = [ ":root_ui", "//ios/chrome/browser/ui/browser_list", + "//ios/chrome/browser/ui/coordinators", "//ios/clean/chrome/browser", "//ios/clean/chrome/browser/ui/commands", "//ios/clean/chrome/browser/ui/tab_grid", "//ios/shared/chrome/browser/ui/commands", - "//ios/shared/chrome/browser/ui/coordinators", ] configs += [ "//build/config/compiler:enable_arc" ] }
diff --git a/ios/clean/chrome/browser/ui/root/root_coordinator.h b/ios/clean/chrome/browser/ui/root/root_coordinator.h index bbd8821..95ad80d5 100644 --- a/ios/clean/chrome/browser/ui/root/root_coordinator.h +++ b/ios/clean/chrome/browser/ui/root/root_coordinator.h
@@ -5,8 +5,8 @@ #ifndef IOS_CLEAN_CHROME_BROWSER_UI_ROOT_ROOT_COORDINATOR_H_ #define IOS_CLEAN_CHROME_BROWSER_UI_ROOT_ROOT_COORDINATOR_H_ +#import "ios/chrome/browser/ui/coordinators/browser_coordinator.h" #import "ios/clean/chrome/browser/url_opening.h" -#import "ios/shared/chrome/browser/ui/coordinators/browser_coordinator.h" // Coordinator that runs the root container. @interface RootCoordinator : BrowserCoordinator<URLOpening>
diff --git a/ios/clean/chrome/browser/ui/root/root_coordinator.mm b/ios/clean/chrome/browser/ui/root/root_coordinator.mm index 12de61a..06ae726 100644 --- a/ios/clean/chrome/browser/ui/root/root_coordinator.mm +++ b/ios/clean/chrome/browser/ui/root/root_coordinator.mm
@@ -9,9 +9,9 @@ #endif #import "ios/chrome/browser/ui/browser_list/browser.h" +#import "ios/chrome/browser/ui/coordinators/browser_coordinator+internal.h" #import "ios/clean/chrome/browser/ui/root/root_container_view_controller.h" #import "ios/clean/chrome/browser/ui/tab_grid/tab_grid_coordinator.h" -#import "ios/shared/chrome/browser/ui/coordinators/browser_coordinator+internal.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support."
diff --git a/ios/clean/chrome/browser/ui/settings/BUILD.gn b/ios/clean/chrome/browser/ui/settings/BUILD.gn index ddace90..ce23161d 100644 --- a/ios/clean/chrome/browser/ui/settings/BUILD.gn +++ b/ios/clean/chrome/browser/ui/settings/BUILD.gn
@@ -18,11 +18,11 @@ "//base:base", "//ios/chrome/browser/browser_state", "//ios/chrome/browser/ui/browser_list", + "//ios/chrome/browser/ui/coordinators", "//ios/chrome/browser/ui/settings", "//ios/clean/chrome/browser/ui/actions", "//ios/clean/chrome/browser/ui/commands", "//ios/shared/chrome/browser/ui/commands", - "//ios/shared/chrome/browser/ui/coordinators", ] } @@ -38,8 +38,8 @@ ":settings", "//ios/chrome/browser/browser_state:test_support", "//ios/chrome/browser/ui/browser_list", + "//ios/chrome/browser/ui/coordinators:test_support", "//ios/chrome/browser/ui/settings", - "//ios/shared/chrome/browser/ui/coordinators:test_support", "//testing/gtest", ] }
diff --git a/ios/clean/chrome/browser/ui/settings/material_cell_catalog_coordinator.h b/ios/clean/chrome/browser/ui/settings/material_cell_catalog_coordinator.h index 2f1db71..2562a2e 100644 --- a/ios/clean/chrome/browser/ui/settings/material_cell_catalog_coordinator.h +++ b/ios/clean/chrome/browser/ui/settings/material_cell_catalog_coordinator.h
@@ -5,7 +5,7 @@ #ifndef IOS_CLEAN_CHROME_BROWSER_UI_SETTINGS_MATERIAL_CELL_CATALOG_COORDINATOR_H_ #define IOS_CLEAN_CHROME_BROWSER_UI_SETTINGS_MATERIAL_CELL_CATALOG_COORDINATOR_H_ -#import "ios/shared/chrome/browser/ui/coordinators/browser_coordinator.h" +#import "ios/chrome/browser/ui/coordinators/browser_coordinator.h" // A coordinator for the Material Cell Catalog in Settings. That screen is // usually pushed onto a navigation controller.
diff --git a/ios/clean/chrome/browser/ui/settings/material_cell_catalog_coordinator_unittest.mm b/ios/clean/chrome/browser/ui/settings/material_cell_catalog_coordinator_unittest.mm index f860231..aed7e94 100644 --- a/ios/clean/chrome/browser/ui/settings/material_cell_catalog_coordinator_unittest.mm +++ b/ios/clean/chrome/browser/ui/settings/material_cell_catalog_coordinator_unittest.mm
@@ -4,7 +4,7 @@ #import "ios/clean/chrome/browser/ui/settings/material_cell_catalog_coordinator.h" -#import "ios/shared/chrome/browser/ui/coordinators/browser_coordinator_test.h" +#import "ios/chrome/browser/ui/coordinators/browser_coordinator_test.h" #include "testing/gtest/include/gtest/gtest.h" #if !defined(__has_feature) || !__has_feature(objc_arc)
diff --git a/ios/clean/chrome/browser/ui/settings/settings_coordinator.h b/ios/clean/chrome/browser/ui/settings/settings_coordinator.h index 502733e..ea84cc0 100644 --- a/ios/clean/chrome/browser/ui/settings/settings_coordinator.h +++ b/ios/clean/chrome/browser/ui/settings/settings_coordinator.h
@@ -7,7 +7,7 @@ #import <UIKit/UIKit.h> -#import "ios/shared/chrome/browser/ui/coordinators/browser_coordinator.h" +#import "ios/chrome/browser/ui/coordinators/browser_coordinator.h" // A coordinator for the Settings UI, which is usually presented modally // on top of whatever other UI is currently active.
diff --git a/ios/clean/chrome/browser/ui/settings/settings_coordinator.mm b/ios/clean/chrome/browser/ui/settings/settings_coordinator.mm index 26958214..9a85c5c 100644 --- a/ios/clean/chrome/browser/ui/settings/settings_coordinator.mm +++ b/ios/clean/chrome/browser/ui/settings/settings_coordinator.mm
@@ -7,11 +7,11 @@ #include "base/logging.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" #import "ios/chrome/browser/ui/browser_list/browser.h" +#import "ios/chrome/browser/ui/coordinators/browser_coordinator+internal.h" #import "ios/chrome/browser/ui/settings/settings_navigation_controller.h" #import "ios/clean/chrome/browser/ui/commands/settings_commands.h" #import "ios/clean/chrome/browser/ui/settings/settings_main_page_coordinator.h" #import "ios/shared/chrome/browser/ui/commands/command_dispatcher.h" -#import "ios/shared/chrome/browser/ui/coordinators/browser_coordinator+internal.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support."
diff --git a/ios/clean/chrome/browser/ui/settings/settings_main_page_coordinator.h b/ios/clean/chrome/browser/ui/settings/settings_main_page_coordinator.h index bdb8d445..2f84653 100644 --- a/ios/clean/chrome/browser/ui/settings/settings_main_page_coordinator.h +++ b/ios/clean/chrome/browser/ui/settings/settings_main_page_coordinator.h
@@ -5,7 +5,7 @@ #ifndef IOS_CLEAN_CHROME_BROWSER_UI_SETTINGS_SETTINGS_MAIN_PAGE_COORDINATOR_H_ #define IOS_CLEAN_CHROME_BROWSER_UI_SETTINGS_SETTINGS_MAIN_PAGE_COORDINATOR_H_ -#import "ios/shared/chrome/browser/ui/coordinators/browser_coordinator.h" +#import "ios/chrome/browser/ui/coordinators/browser_coordinator.h" // A coordinator for the Settings main screen. That screen is usually pushed // onto a navigation controller.
diff --git a/ios/clean/chrome/browser/ui/settings/settings_main_page_coordinator.mm b/ios/clean/chrome/browser/ui/settings/settings_main_page_coordinator.mm index f8cb709f..86a36ec 100644 --- a/ios/clean/chrome/browser/ui/settings/settings_main_page_coordinator.mm +++ b/ios/clean/chrome/browser/ui/settings/settings_main_page_coordinator.mm
@@ -7,10 +7,10 @@ #include "base/logging.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" #import "ios/chrome/browser/ui/browser_list/browser.h" +#import "ios/chrome/browser/ui/coordinators/browser_coordinator+internal.h" #import "ios/chrome/browser/ui/settings/settings_collection_view_controller.h" #import "ios/clean/chrome/browser/ui/settings/material_cell_catalog_coordinator.h" #import "ios/shared/chrome/browser/ui/commands/command_dispatcher.h" -#import "ios/shared/chrome/browser/ui/coordinators/browser_coordinator+internal.h" #import "ios/shared/chrome/browser/ui/settings/settings_main_page_commands.h" #if !defined(__has_feature) || !__has_feature(objc_arc)
diff --git a/ios/clean/chrome/browser/ui/tab/BUILD.gn b/ios/clean/chrome/browser/ui/tab/BUILD.gn index d04dfb4..b619b2f2 100644 --- a/ios/clean/chrome/browser/ui/tab/BUILD.gn +++ b/ios/clean/chrome/browser/ui/tab/BUILD.gn
@@ -17,6 +17,7 @@ "//base", "//ios/chrome/browser", "//ios/chrome/browser/ui/browser_list", + "//ios/chrome/browser/ui/coordinators", "//ios/chrome/browser/web_state_list", "//ios/clean/chrome/browser/ui/actions", "//ios/clean/chrome/browser/ui/commands", @@ -28,7 +29,6 @@ "//ios/clean/chrome/browser/ui/web_contents", "//ios/shared/chrome/browser/ui/broadcaster", "//ios/shared/chrome/browser/ui/commands", - "//ios/shared/chrome/browser/ui/coordinators", "//ios/web", ] } @@ -65,9 +65,9 @@ ":tab_ui", "//base", "//ios/chrome/browser/ui/browser_list", + "//ios/chrome/browser/ui/coordinators", + "//ios/chrome/browser/ui/coordinators:test_support", "//ios/chrome/browser/ui/toolbar/test", - "//ios/shared/chrome/browser/ui/coordinators", - "//ios/shared/chrome/browser/ui/coordinators:test_support", "//ios/shared/chrome/browser/ui/tab:test_support", "//ios/web/public/test", "//testing/gtest",
diff --git a/ios/clean/chrome/browser/ui/tab/tab_coordinator.h b/ios/clean/chrome/browser/ui/tab/tab_coordinator.h index fae4ec2a..4f1ca4c 100644 --- a/ios/clean/chrome/browser/ui/tab/tab_coordinator.h +++ b/ios/clean/chrome/browser/ui/tab/tab_coordinator.h
@@ -6,7 +6,7 @@ #define IOS_CLEAN_CHROME_BROWSER_UI_TAB_TAB_COORDINATOR_H_ #import <UIKit/UIKit.h> -#import "ios/shared/chrome/browser/ui/coordinators/browser_coordinator.h" +#import "ios/chrome/browser/ui/coordinators/browser_coordinator.h" namespace web { class WebState;
diff --git a/ios/clean/chrome/browser/ui/tab/tab_coordinator.mm b/ios/clean/chrome/browser/ui/tab/tab_coordinator.mm index 01e9139c..1ce23780 100644 --- a/ios/clean/chrome/browser/ui/tab/tab_coordinator.mm +++ b/ios/clean/chrome/browser/ui/tab/tab_coordinator.mm
@@ -11,6 +11,7 @@ #include "base/scoped_observer.h" #include "ios/chrome/browser/chrome_url_constants.h" #import "ios/chrome/browser/ui/browser_list/browser.h" +#import "ios/chrome/browser/ui/coordinators/browser_coordinator+internal.h" #include "ios/chrome/browser/web_state_list/web_state_list.h" #include "ios/chrome/browser/web_state_list/web_state_list_observer_bridge.h" #import "ios/clean/chrome/browser/ui/commands/tab_commands.h" @@ -25,7 +26,6 @@ #import "ios/clean/chrome/browser/ui/web_contents/web_coordinator.h" #import "ios/shared/chrome/browser/ui/broadcaster/chrome_broadcaster.h" #import "ios/shared/chrome/browser/ui/commands/command_dispatcher.h" -#import "ios/shared/chrome/browser/ui/coordinators/browser_coordinator+internal.h" #import "ios/web/public/web_state/web_state.h" #import "ios/web/public/web_state/web_state_observer_bridge.h"
diff --git a/ios/clean/chrome/browser/ui/tab/tab_coordinator_unittest.mm b/ios/clean/chrome/browser/ui/tab/tab_coordinator_unittest.mm index 5b4f1fe..106f38fa 100644 --- a/ios/clean/chrome/browser/ui/tab/tab_coordinator_unittest.mm +++ b/ios/clean/chrome/browser/ui/tab/tab_coordinator_unittest.mm
@@ -8,10 +8,10 @@ #include "base/message_loop/message_loop.h" #include "base/run_loop.h" #import "ios/chrome/browser/ui/browser_list/browser.h" +#import "ios/chrome/browser/ui/coordinators/browser_coordinator+internal.h" +#import "ios/chrome/browser/ui/coordinators/browser_coordinator_test.h" #import "ios/chrome/browser/ui/toolbar/test/toolbar_test_web_state.h" #import "ios/clean/chrome/browser/ui/tab/tab_container_view_controller.h" -#import "ios/shared/chrome/browser/ui/coordinators/browser_coordinator+internal.h" -#import "ios/shared/chrome/browser/ui/coordinators/browser_coordinator_test.h" #import "ios/shared/chrome/browser/ui/tab/tab_test_util.h" #include "ios/web/public/test/test_web_thread.h" #include "testing/gtest/include/gtest/gtest.h"
diff --git a/ios/clean/chrome/browser/ui/tab_grid/BUILD.gn b/ios/clean/chrome/browser/ui/tab_grid/BUILD.gn index 9d2b93cf9..e100aad 100644 --- a/ios/clean/chrome/browser/ui/tab_grid/BUILD.gn +++ b/ios/clean/chrome/browser/ui/tab_grid/BUILD.gn
@@ -18,6 +18,7 @@ "//ios/chrome/browser/browser_state", "//ios/chrome/browser/snapshots", "//ios/chrome/browser/ui/browser_list", + "//ios/chrome/browser/ui/coordinators", "//ios/chrome/browser/ui/tools_menu:configuration", "//ios/chrome/browser/web_state_list", "//ios/clean/chrome/browser", @@ -29,7 +30,6 @@ "//ios/clean/chrome/browser/ui/tab_collection:tab_collection_ui", "//ios/clean/chrome/browser/ui/tools", "//ios/shared/chrome/browser/ui/commands", - "//ios/shared/chrome/browser/ui/coordinators", "//ios/web", "//net", "//ui/base",
diff --git a/ios/clean/chrome/browser/ui/tab_grid/tab_grid_coordinator.h b/ios/clean/chrome/browser/ui/tab_grid/tab_grid_coordinator.h index 50bc03c..acbd79b 100644 --- a/ios/clean/chrome/browser/ui/tab_grid/tab_grid_coordinator.h +++ b/ios/clean/chrome/browser/ui/tab_grid/tab_grid_coordinator.h
@@ -5,8 +5,8 @@ #ifndef IOS_CLEAN_CHROME_BROWSER_UI_TAB_GRID_TAB_GRID_COORDINATOR_H_ #define IOS_CLEAN_CHROME_BROWSER_UI_TAB_GRID_TAB_GRID_COORDINATOR_H_ +#import "ios/chrome/browser/ui/coordinators/browser_coordinator.h" #import "ios/clean/chrome/browser/url_opening.h" -#import "ios/shared/chrome/browser/ui/coordinators/browser_coordinator.h" // Coordinator that drives a UI showing a scrollable grid of tabs, // which each represent a web browsing tab that can be expanded by tapping.
diff --git a/ios/clean/chrome/browser/ui/tab_grid/tab_grid_coordinator.mm b/ios/clean/chrome/browser/ui/tab_grid/tab_grid_coordinator.mm index cb9f9e77..64be33f04 100644 --- a/ios/clean/chrome/browser/ui/tab_grid/tab_grid_coordinator.mm +++ b/ios/clean/chrome/browser/ui/tab_grid/tab_grid_coordinator.mm
@@ -11,6 +11,7 @@ #include "ios/chrome/browser/browser_state/chrome_browser_state.h" #import "ios/chrome/browser/snapshots/snapshot_cache_factory.h" #import "ios/chrome/browser/ui/browser_list/browser.h" +#import "ios/chrome/browser/ui/coordinators/browser_coordinator+internal.h" #import "ios/chrome/browser/ui/tools_menu/tools_menu_configuration.h" #import "ios/chrome/browser/web_state_list/web_state_list.h" #import "ios/chrome/browser/web_state_list/web_state_opener.h" @@ -25,7 +26,6 @@ #import "ios/clean/chrome/browser/ui/tab_grid/tab_grid_view_controller.h" #import "ios/clean/chrome/browser/ui/tools/tools_coordinator.h" #import "ios/shared/chrome/browser/ui/commands/command_dispatcher.h" -#import "ios/shared/chrome/browser/ui/coordinators/browser_coordinator+internal.h" #import "ios/web/public/navigation_manager.h" #include "ios/web/public/web_state/web_state.h" #import "net/base/mac/url_conversions.h"
diff --git a/ios/clean/chrome/browser/ui/tab_strip/BUILD.gn b/ios/clean/chrome/browser/ui/tab_strip/BUILD.gn index 074ebaf..cb0ad050 100644 --- a/ios/clean/chrome/browser/ui/tab_strip/BUILD.gn +++ b/ios/clean/chrome/browser/ui/tab_strip/BUILD.gn
@@ -11,11 +11,11 @@ ":tab_strip_ui", "//ios/chrome/browser/browser_state", "//ios/chrome/browser/ui/browser_list", + "//ios/chrome/browser/ui/coordinators", "//ios/chrome/browser/web_state_list", "//ios/clean/chrome/browser/ui/commands", "//ios/clean/chrome/browser/ui/tab_collection", "//ios/shared/chrome/browser/ui/commands", - "//ios/shared/chrome/browser/ui/coordinators", "//ios/web", ] configs += [ "//build/config/compiler:enable_arc" ]
diff --git a/ios/clean/chrome/browser/ui/tab_strip/tab_strip_coordinator.h b/ios/clean/chrome/browser/ui/tab_strip/tab_strip_coordinator.h index bc27455..0206e08 100644 --- a/ios/clean/chrome/browser/ui/tab_strip/tab_strip_coordinator.h +++ b/ios/clean/chrome/browser/ui/tab_strip/tab_strip_coordinator.h
@@ -5,7 +5,7 @@ #ifndef IOS_CLEAN_CHROME_BROWSER_UI_TAB_STRIP_TAB_STRIP_COORDINATOR_H_ #define IOS_CLEAN_CHROME_BROWSER_UI_TAB_STRIP_TAB_STRIP_COORDINATOR_H_ -#import "ios/shared/chrome/browser/ui/coordinators/browser_coordinator.h" +#import "ios/chrome/browser/ui/coordinators/browser_coordinator.h" // Coordinator that drives a UI showing a horizontal scrolling strip of tabs. @interface TabStripCoordinator : BrowserCoordinator
diff --git a/ios/clean/chrome/browser/ui/toolbar/BUILD.gn b/ios/clean/chrome/browser/ui/toolbar/BUILD.gn index e517ef7..1ac2893d 100644 --- a/ios/clean/chrome/browser/ui/toolbar/BUILD.gn +++ b/ios/clean/chrome/browser/ui/toolbar/BUILD.gn
@@ -17,6 +17,7 @@ "//base", "//ios/chrome/browser", "//ios/chrome/browser/ui/browser_list", + "//ios/chrome/browser/ui/coordinators", "//ios/chrome/browser/ui/tools_menu:configuration", "//ios/chrome/browser/web_state_list", "//ios/clean/chrome/browser/ui/commands", @@ -24,7 +25,6 @@ "//ios/clean/chrome/browser/ui/tools", "//ios/shared/chrome/browser/ui/broadcaster", "//ios/shared/chrome/browser/ui/commands", - "//ios/shared/chrome/browser/ui/coordinators", "//ios/web", ] }
diff --git a/ios/clean/chrome/browser/ui/toolbar/toolbar_coordinator.h b/ios/clean/chrome/browser/ui/toolbar/toolbar_coordinator.h index 6972762..bb33c58 100644 --- a/ios/clean/chrome/browser/ui/toolbar/toolbar_coordinator.h +++ b/ios/clean/chrome/browser/ui/toolbar/toolbar_coordinator.h
@@ -5,7 +5,7 @@ #ifndef IOS_CLEAN_CHROME_BROWSER_UI_TOOLBAR_TOOLBAR_COORDINATOR_H_ #define IOS_CLEAN_CHROME_BROWSER_UI_TOOLBAR_TOOLBAR_COORDINATOR_H_ -#import "ios/shared/chrome/browser/ui/coordinators/browser_coordinator.h" +#import "ios/chrome/browser/ui/coordinators/browser_coordinator.h" namespace web { class WebState;
diff --git a/ios/clean/chrome/browser/ui/toolbar/toolbar_coordinator.mm b/ios/clean/chrome/browser/ui/toolbar/toolbar_coordinator.mm index 50079c6..556a2ed 100644 --- a/ios/clean/chrome/browser/ui/toolbar/toolbar_coordinator.mm +++ b/ios/clean/chrome/browser/ui/toolbar/toolbar_coordinator.mm
@@ -6,6 +6,7 @@ #include "ios/chrome/browser/chrome_url_constants.h" #import "ios/chrome/browser/ui/browser_list/browser.h" +#import "ios/chrome/browser/ui/coordinators/browser_coordinator+internal.h" #import "ios/chrome/browser/ui/tools_menu/tools_menu_configuration.h" #import "ios/clean/chrome/browser/ui/commands/tools_menu_commands.h" #import "ios/clean/chrome/browser/ui/omnibox/location_bar_coordinator.h" @@ -14,7 +15,6 @@ #import "ios/clean/chrome/browser/ui/tools/tools_coordinator.h" #import "ios/shared/chrome/browser/ui/broadcaster/chrome_broadcaster.h" #import "ios/shared/chrome/browser/ui/commands/command_dispatcher.h" -#import "ios/shared/chrome/browser/ui/coordinators/browser_coordinator+internal.h" #import "ios/web/public/web_state/web_state.h" #if !defined(__has_feature) || !__has_feature(objc_arc)
diff --git a/ios/clean/chrome/browser/ui/tools/BUILD.gn b/ios/clean/chrome/browser/ui/tools/BUILD.gn index d9c569bf..0394e3b7 100644 --- a/ios/clean/chrome/browser/ui/tools/BUILD.gn +++ b/ios/clean/chrome/browser/ui/tools/BUILD.gn
@@ -17,10 +17,10 @@ ":tools_ui", "//base", "//ios/chrome/browser/ui/browser_list", + "//ios/chrome/browser/ui/coordinators", "//ios/chrome/browser/ui/tools_menu:configuration", "//ios/clean/chrome/browser/ui/commands", "//ios/clean/chrome/browser/ui/transitions", - "//ios/shared/chrome/browser/ui/coordinators", "//ios/web", "//ui/base", ]
diff --git a/ios/clean/chrome/browser/ui/tools/tools_coordinator.h b/ios/clean/chrome/browser/ui/tools/tools_coordinator.h index b7b89fe..0e8bcc3 100644 --- a/ios/clean/chrome/browser/ui/tools/tools_coordinator.h +++ b/ios/clean/chrome/browser/ui/tools/tools_coordinator.h
@@ -5,7 +5,7 @@ #ifndef IOS_CLEAN_CHROME_BROWSER_UI_TOOLS_TOOLS_COORDINATOR_H_ #define IOS_CLEAN_CHROME_BROWSER_UI_TOOLS_TOOLS_COORDINATOR_H_ -#import "ios/shared/chrome/browser/ui/coordinators/browser_coordinator.h" +#import "ios/chrome/browser/ui/coordinators/browser_coordinator.h" @class ToolsMenuConfiguration; namespace web {
diff --git a/ios/clean/chrome/browser/ui/web_contents/BUILD.gn b/ios/clean/chrome/browser/ui/web_contents/BUILD.gn index 36ae90d..51238db 100644 --- a/ios/clean/chrome/browser/ui/web_contents/BUILD.gn +++ b/ios/clean/chrome/browser/ui/web_contents/BUILD.gn
@@ -16,10 +16,10 @@ ":web_contents_ui", "//ios/chrome/browser", "//ios/chrome/browser/ui/browser_list", + "//ios/chrome/browser/ui/coordinators", "//ios/clean/chrome/browser/ui/commands", "//ios/clean/chrome/browser/ui/context_menu", "//ios/shared/chrome/browser/ui/commands", - "//ios/shared/chrome/browser/ui/coordinators", "//ios/web", "//ui/base", "//url", @@ -50,8 +50,8 @@ ":web_contents_ui", "//base", "//base/test:test_support", + "//ios/chrome/browser/ui/coordinators", "//ios/chrome/test/base", - "//ios/shared/chrome/browser/ui/coordinators", "//ios/shared/chrome/browser/ui/tab:test_support", "//ios/web/public/test/fakes", "//testing/gtest",
diff --git a/ios/clean/chrome/browser/ui/web_contents/web_coordinator.h b/ios/clean/chrome/browser/ui/web_contents/web_coordinator.h index 1cb424d..78c5b7e 100644 --- a/ios/clean/chrome/browser/ui/web_contents/web_coordinator.h +++ b/ios/clean/chrome/browser/ui/web_contents/web_coordinator.h
@@ -5,7 +5,7 @@ #ifndef IOS_CLEAN_CHROME_BROWSER_UI_WEB_CONTENTS_WEB_COORDINATOR_H_ #define IOS_CLEAN_CHROME_BROWSER_UI_WEB_CONTENTS_WEB_COORDINATOR_H_ -#import "ios/shared/chrome/browser/ui/coordinators/browser_coordinator.h" +#import "ios/chrome/browser/ui/coordinators/browser_coordinator.h" namespace web { class WebState;
diff --git a/ios/clean/chrome/browser/ui/web_contents/web_coordinator.mm b/ios/clean/chrome/browser/ui/web_contents/web_coordinator.mm index a7ea49c..be03cdd 100644 --- a/ios/clean/chrome/browser/ui/web_contents/web_coordinator.mm +++ b/ios/clean/chrome/browser/ui/web_contents/web_coordinator.mm
@@ -7,13 +7,13 @@ #include "base/mac/foundation_util.h" #include "base/memory/ptr_util.h" #import "ios/chrome/browser/ui/browser_list/browser.h" +#import "ios/chrome/browser/ui/coordinators/browser_coordinator+internal.h" #import "ios/clean/chrome/browser/ui/commands/context_menu_commands.h" #import "ios/clean/chrome/browser/ui/context_menu/context_menu_context_impl.h" #import "ios/clean/chrome/browser/ui/context_menu/web_context_menu_coordinator.h" #import "ios/clean/chrome/browser/ui/web_contents/web_contents_mediator.h" #import "ios/clean/chrome/browser/ui/web_contents/web_contents_view_controller.h" #import "ios/shared/chrome/browser/ui/commands/command_dispatcher.h" -#import "ios/shared/chrome/browser/ui/coordinators/browser_coordinator+internal.h" #include "ios/web/public/navigation_manager.h" #include "ios/web/public/web_state/web_state.h" #import "ios/web/public/web_state/web_state_delegate_bridge.h"
diff --git a/ios/clean/chrome/browser/ui/web_contents/web_coordinator_unittest.mm b/ios/clean/chrome/browser/ui/web_contents/web_coordinator_unittest.mm index 2abeebc..cbd2830 100644 --- a/ios/clean/chrome/browser/ui/web_contents/web_coordinator_unittest.mm +++ b/ios/clean/chrome/browser/ui/web_contents/web_coordinator_unittest.mm
@@ -5,7 +5,7 @@ #import "ios/clean/chrome/browser/ui/web_contents/web_coordinator.h" #include "base/memory/ptr_util.h" -#import "ios/shared/chrome/browser/ui/coordinators/browser_coordinator+internal.h" +#import "ios/chrome/browser/ui/coordinators/browser_coordinator+internal.h" #import "ios/shared/chrome/browser/ui/tab/tab_test_util.h" #import "ios/web/public/test/fakes/test_web_state.h" #include "testing/gtest/include/gtest/gtest.h"
diff --git a/ios/shared/chrome/browser/ui/coordinators/browser_coordinator+internal.h b/ios/shared/chrome/browser/ui/coordinators/browser_coordinator+internal.h deleted file mode 100644 index 358135b0..0000000 --- a/ios/shared/chrome/browser/ui/coordinators/browser_coordinator+internal.h +++ /dev/null
@@ -1,97 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef IOS_SHARED_CHROME_BROWSER_UI_COORDINATORS_BROWSER_COORDINATOR_INTERNAL_H_ -#define IOS_SHARED_CHROME_BROWSER_UI_COORDINATORS_BROWSER_COORDINATOR_INTERNAL_H_ - -#import "ios/shared/chrome/browser/ui/coordinators/browser_coordinator.h" - -// Internal API for subclasses and categories of BrowserCoordinator. -// -// This API can be used to create and manage 'overlay coordinators'. -// Overlay coordinators are intended to be used for UI elements that -// sit on top of the regular UI, and which may need to be dismissed -// by coordinators that don't have direct access to them. Typical uses -// would be alerts, login prompts, or other UI that might be dismissed -// if (for example) an external event causes a web page to load. -// Overlay coordinators can be added by any coordinator in the coordinator -// hierarchy, but they will be children of (generally) the topmost -// coordinator, regardless of which coordinator added them. -@interface BrowserCoordinator (Internal) - -// Managed view controller of this object. Subclasses must define a -// property named |viewController| that has the specific UIViewController -// subclass they use; the subclass API will be able to access that view -// controller through this property. -@property(nonatomic, readonly) UIViewController* viewController; - -// The child coordinators of this coordinator. To add or remove from this set, -// use the -addChildCoordinator: and -removeChildCoordinator: methods. -@property(nonatomic, readonly) NSSet<BrowserCoordinator*>* children; - -// The coordinator that added this coordinator as a child, if any. -@property(nonatomic, readonly) BrowserCoordinator* parentCoordinator; - -// YES if the receiver has been started; NO (the default) otherwise. Stopping -// the receiver resets this property to NO. -@property(nonatomic, readonly) BOOL started; - -// YES if the receiver is acting as an overlay coordinator; NO (the default) -// otherwise. -@property(nonatomic, readonly) BOOL overlaying; - -// The coordinator (if any) in the coordinator hierarchy (starting with -// the receiver) that is overlaying. If the receiver isn't overlaying, -// it recursively asks its children. -@property(nonatomic, readonly) BrowserCoordinator* overlayCoordinator; - -// Adds |coordinator| as a child, taking ownership of it, setting the receiver's -// viewController (if any) as the child's baseViewController, and setting -// the receiver's |browser| as the child's |browser|. -- (void)addChildCoordinator:(BrowserCoordinator*)childCoordinator; - -// Removes |coordinator| as a child, relinquishing ownership of it. If -// |coordinator| isn't a child of the receiver, this method does nothing. -- (void)removeChildCoordinator:(BrowserCoordinator*)childCoordinator; - -// Called when this coordinator is added to a parent coordinator. -- (void)wasAddedToParentCoordinator:(BrowserCoordinator*)parentCoordinator; - -// Called when this coordinator is going to be removed from its parent -// coordinator. -- (void)willBeRemovedFromParentCoordinator; - -// Called when a child coordinator did start. This is a blank template method. -// Subclasses can override this method when they need to know when their -// children start. -- (void)childCoordinatorDidStart:(BrowserCoordinator*)childCoordinator; - -// Called when a child coordinator will stop. This is a blank template method. -// Subclasses can override this method when they need to know when their -// children start. -- (void)childCoordinatorWillStop:(BrowserCoordinator*)childCoordinator; - -// Methods for adding overlay coordinators. - -// Returns YES if the receiver will take |overlayCoordinator| as a child. -// The default is to return YES only if the receiver has no children, if -// the receiver has a nil -overlayCoordinator, and if |overlayCoordinator| -// is not already overlaying. -- (BOOL)canAddOverlayCoordinator:(BrowserCoordinator*)overlayCoordinator; - -// Adds |overlayCoordinator| as a child to the receiver, or if it cannot be -// added, recursively add it to the receiver's child. If a receiver has -// multiple children and returns YES from -canAddOverlayCoordinator:, it -// must override this method to determines how the overlay is added. -// If neither the receiver or any child can add |overlayCoordinator|, then -// nothing happens. -- (void)addOverlayCoordinator:(BrowserCoordinator*)overlayCoordinator; - -// Removes the current overlay coordinator (if any) as a child from its -// parent. -- (void)removeOverlayCoordinator; - -@end - -#endif // IOS_SHARED_CHROME_BROWSER_UI_COORDINATORS_BROWSER_COORDINATOR_INTERNAL_H_
diff --git a/ios/shared/chrome/browser/ui/coordinators/browser_coordinator.h b/ios/shared/chrome/browser/ui/coordinators/browser_coordinator.h deleted file mode 100644 index 4102a3c..0000000 --- a/ios/shared/chrome/browser/ui/coordinators/browser_coordinator.h +++ /dev/null
@@ -1,55 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef IOS_SHARED_CHROME_BROWSER_UI_COORDINATORS_BROWSER_COORDINATOR_H_ -#define IOS_SHARED_CHROME_BROWSER_UI_COORDINATORS_BROWSER_COORDINATOR_H_ - -#import <UIKit/UIKit.h> - -class Browser; - -// An object that manages a UI component via a view controller. -// This is the public interface to this class; subclasses should also import -// the Internal category header (browser_coordinator+internal.h). This header -// file declares all the methods and properties a subclass must either override, -// call, or reset. -@interface BrowserCoordinator : NSObject - -// The browser object used by this coordinator and passed into any child -// coordinators added to it. This is a weak pointer, and setting this property -// doesn't transfer ownership of the browser. -@property(nonatomic, assign) Browser* browser; - -// The basic lifecycle methods for coordinators are -start and -stop. These -// implementations notify the parent coordinator when this coordinator did start -// and will stop. Child classes are expected to override and call the superclass -// method at the end of -start and at the beginning of -stop. -// If the receiver is already started, -start is a no-op. If the receiver is -// already stopped or never started, -stop is a no-op. In those cases, the -// overriding implementations can early return withotu calling the superclass -// method: -// SubCoordinator.mm: -// - (void)start { -// if (self.started) return; -// ... -// [super start]; -// } - -// Starts the user interaction managed by the receiver. Typical implementations -// will create a view controller and then use |baseViewController| to present -// it. This method needs to be called at the end of the overriding -// implementation. -// Starting a started coordinator is a no-op in this implementation. -- (void)start NS_REQUIRES_SUPER; - -// Stops the user interaction managed by the receiver. This method needs to be -// called at the beginning of the overriding implementation. -// Calling stop on a coordinator transitively calls stop on its children. -// Stopping a non-started or stopped coordinator is a no-op in this -// implementation. -- (void)stop NS_REQUIRES_SUPER; - -@end - -#endif // IOS_SHARED_CHROME_BROWSER_UI_COORDINATORS_BROWSER_COORDINATOR_H_
diff --git a/ios/shared/chrome/browser/ui/coordinators/browser_coordinator.mm b/ios/shared/chrome/browser/ui/coordinators/browser_coordinator.mm deleted file mode 100644 index 2917b42..0000000 --- a/ios/shared/chrome/browser/ui/coordinators/browser_coordinator.mm +++ /dev/null
@@ -1,161 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "ios/shared/chrome/browser/ui/coordinators/browser_coordinator.h" - -#import "base/logging.h" -#import "ios/shared/chrome/browser/ui/coordinators/browser_coordinator+internal.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -@interface BrowserCoordinator () -// Child coordinators owned by this object. -@property(nonatomic, strong) - NSMutableSet<BrowserCoordinator*>* childCoordinators; -// Parent coordinator of this object, if any. -@property(nonatomic, readwrite, weak) BrowserCoordinator* parentCoordinator; -@property(nonatomic, readwrite) BOOL started; -@property(nonatomic, readwrite) BOOL overlaying; -@end - -@implementation BrowserCoordinator - -@synthesize browser = _browser; -@synthesize childCoordinators = _childCoordinators; -@synthesize parentCoordinator = _parentCoordinator; -@synthesize started = _started; -@synthesize overlaying = _overlaying; - -- (instancetype)init { - if (self = [super init]) { - _childCoordinators = [NSMutableSet set]; - } - return self; -} - -#pragma mark - Public API - -- (void)start { - if (self.started) { - return; - } - self.started = YES; - [self.parentCoordinator childCoordinatorDidStart:self]; -} - -- (void)stop { - if (!self.started) { - return; - } - [self.parentCoordinator childCoordinatorWillStop:self]; - self.started = NO; - for (BrowserCoordinator* child in self.children) { - [child stop]; - } -} - -- (void)dealloc { - for (BrowserCoordinator* child in self.children) { - [self removeChildCoordinator:child]; - } -} - -@end - -@implementation BrowserCoordinator (Internal) -// Concrete implementations must implement a |viewController| property. -@dynamic viewController; - -- (NSSet*)children { - return [self.childCoordinators copy]; -} - -- (void)addChildCoordinator:(BrowserCoordinator*)childCoordinator { - CHECK([self respondsToSelector:@selector(viewController)]) - << "BrowserCoordinator implementations must provide a viewController " - "property."; - [self.childCoordinators addObject:childCoordinator]; - childCoordinator.parentCoordinator = self; - childCoordinator.browser = self.browser; - [childCoordinator wasAddedToParentCoordinator:self]; -} - -- (BrowserCoordinator*)overlayCoordinator { - if (self.overlaying) - return self; - for (BrowserCoordinator* child in self.children) { - BrowserCoordinator* overlay = child.overlayCoordinator; - if (overlay) - return overlay; - } - return nil; -} - -- (void)addOverlayCoordinator:(BrowserCoordinator*)overlayCoordinator { - // If this object has no children, then add |overlayCoordinator| as a child - // and mark it as such. - if ([self canAddOverlayCoordinator:overlayCoordinator]) { - [self addChildCoordinator:overlayCoordinator]; - overlayCoordinator.overlaying = YES; - } else if (self.childCoordinators.count == 1) { - [[self.childCoordinators anyObject] - addOverlayCoordinator:overlayCoordinator]; - } else if (self.childCoordinators.count > 1) { - CHECK(NO) << "Coordinators with multiple children must explicitly " - << "handle -addOverlayCoordinator: or return NO to " - << "-canAddOverlayCoordinator:"; - } - // If control reaches here, the terminal child of the coordinator hierarchy - // has returned NO to -canAddOverlayCoordinator, so no overlay can be added. - // This is by default a silent no-op. -} - -- (void)removeOverlayCoordinator { - BrowserCoordinator* overlay = self.overlayCoordinator; - [overlay.parentCoordinator removeChildCoordinator:overlay]; - overlay.overlaying = NO; -} - -- (BOOL)canAddOverlayCoordinator:(BrowserCoordinator*)overlayCoordinator { - // By default, a hierarchy with an overlay can't add a new one. - // By default, coordinators with parents can't be added as overlays. - // By default, coordinators with no other children can add an overlay. - return self.overlayCoordinator == nil && - overlayCoordinator.parentCoordinator == nil && - self.childCoordinators.count == 0; -} - -- (void)removeChildCoordinator:(BrowserCoordinator*)childCoordinator { - if (![self.childCoordinators containsObject:childCoordinator]) - return; - // Remove the grand-children first. - for (BrowserCoordinator* grandChild in childCoordinator.children) { - [childCoordinator removeChildCoordinator:grandChild]; - } - // Remove the child. - [childCoordinator willBeRemovedFromParentCoordinator]; - [self.childCoordinators removeObject:childCoordinator]; - childCoordinator.parentCoordinator = nil; - childCoordinator.browser = nil; -} - -- (void)wasAddedToParentCoordinator:(BrowserCoordinator*)parentCoordinator { - // Default implementation is a no-op. -} - -- (void)willBeRemovedFromParentCoordinator { - // Default implementation is a no-op. -} - -- (void)childCoordinatorDidStart:(BrowserCoordinator*)childCoordinator { - // Default implementation is a no-op. -} - -- (void)childCoordinatorWillStop:(BrowserCoordinator*)childCoordinator { - // Default implementation is a no-op. -} - -@end
diff --git a/ios/shared/chrome/browser/ui/coordinators/browser_coordinator_test.h b/ios/shared/chrome/browser/ui/coordinators/browser_coordinator_test.h deleted file mode 100644 index 618010d..0000000 --- a/ios/shared/chrome/browser/ui/coordinators/browser_coordinator_test.h +++ /dev/null
@@ -1,27 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef IOS_SHARED_CHROME_BROWSER_UI_COORDINATORS_BROWSER_COORDINATOR_TEST_H_ -#define IOS_SHARED_CHROME_BROWSER_UI_COORDINATORS_BROWSER_COORDINATOR_TEST_H_ - -#include <memory> - -#include "testing/platform_test.h" - -class Browser; -class TestChromeBrowserState; - -class BrowserCoordinatorTest : public PlatformTest { - protected: - BrowserCoordinatorTest(); - ~BrowserCoordinatorTest() override; - - Browser* GetBrowser() { return browser_.get(); } - - private: - std::unique_ptr<Browser> browser_; - std::unique_ptr<TestChromeBrowserState> chrome_browser_state_; -}; - -#endif // IOS_SHARED_CHROME_BROWSER_UI_COORDINATORS_BROWSER_COORDINATOR_TEST_H_
diff --git a/ios/shared/chrome/browser/ui/coordinators/browser_coordinator_test.mm b/ios/shared/chrome/browser/ui/coordinators/browser_coordinator_test.mm deleted file mode 100644 index 4d54d95..0000000 --- a/ios/shared/chrome/browser/ui/coordinators/browser_coordinator_test.mm +++ /dev/null
@@ -1,22 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "ios/shared/chrome/browser/ui/coordinators/browser_coordinator_test.h" - -#include "base/memory/ptr_util.h" -#include "ios/chrome/browser/browser_state/test_chrome_browser_state.h" -#import "ios/chrome/browser/ui/browser_list/browser.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -BrowserCoordinatorTest::BrowserCoordinatorTest() { - // Initialize the browser. - TestChromeBrowserState::Builder builder; - chrome_browser_state_ = builder.Build(); - browser_ = base::MakeUnique<Browser>(chrome_browser_state_.get()); -} - -BrowserCoordinatorTest::~BrowserCoordinatorTest() = default;
diff --git a/ios/shared/chrome/browser/ui/coordinators/browser_coordinator_unittest.mm b/ios/shared/chrome/browser/ui/coordinators/browser_coordinator_unittest.mm deleted file mode 100644 index b9ca22fc..0000000 --- a/ios/shared/chrome/browser/ui/coordinators/browser_coordinator_unittest.mm +++ /dev/null
@@ -1,305 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "ios/shared/chrome/browser/ui/coordinators/browser_coordinator+internal.h" -#import "ios/shared/chrome/browser/ui/coordinators/browser_coordinator.h" - -#import "ios/shared/chrome/browser/ui/coordinators/browser_coordinator_test.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -@interface TestCoordinator : BrowserCoordinator -@property(nonatomic) UIViewController* viewController; -@property(nonatomic, copy) void (^stopHandler)(); -@property(nonatomic) BOOL wasAddedCalled; -@property(nonatomic) BOOL willBeRemovedCalled; -@property(nonatomic, copy) void (^willBeRemovedHandler)(); -@property(nonatomic) BOOL removeCalled; -@property(nonatomic) BOOL childDidStartCalled; -@property(nonatomic) BOOL childWillStopCalled; -@end - -@implementation TestCoordinator -@synthesize viewController = _viewController; -@synthesize stopHandler = _stopHandler; -@synthesize wasAddedCalled = _wasAddedCalled; -@synthesize willBeRemovedCalled = _willBeRemovedCalled; -@synthesize willBeRemovedHandler = _willBeRemovedHandler; -@synthesize removeCalled = _removeCalled; -@synthesize childDidStartCalled = _childDidStartCalled; -@synthesize childWillStopCalled = _childWillStopCalled; - -- (instancetype)init { - if (!(self = [super init])) - return nil; - - _viewController = [[UIViewController alloc] init]; - return self; -} - -- (void)stop { - [super stop]; - if (self.stopHandler) - self.stopHandler(); -} - -- (void)wasAddedToParentCoordinator:(BrowserCoordinator*)parentCoordinator { - [super wasAddedToParentCoordinator:parentCoordinator]; - self.wasAddedCalled = YES; -} - -- (void)willBeRemovedFromParentCoordinator { - [super willBeRemovedFromParentCoordinator]; - self.willBeRemovedCalled = YES; - if (self.willBeRemovedHandler) - self.willBeRemovedHandler(); -} - -- (void)removeChildCoordinator:(BrowserCoordinator*)childCoordinator { - [super removeChildCoordinator:childCoordinator]; - self.removeCalled = YES; -} - -- (void)childCoordinatorDidStart:(BrowserCoordinator*)childCoordinator { - [super childCoordinatorDidStart:childCoordinator]; - self.childDidStartCalled = YES; -} - -- (void)childCoordinatorWillStop:(BrowserCoordinator*)childCoordinator { - [super childCoordinatorWillStop:childCoordinator]; - self.childWillStopCalled = YES; -} - -@end - -@interface NonOverlayableCoordinator : TestCoordinator -@end - -@implementation NonOverlayableCoordinator - -- (BOOL)canAddOverlayCoordinator:(BrowserCoordinator*)overlayCoordinator { - return NO; -} - -@end - -TEST_F(BrowserCoordinatorTest, TestDontStopOnDealloc) { - __block BOOL called = NO; - - { - TestCoordinator* coordinator = [[TestCoordinator alloc] init]; - coordinator.stopHandler = ^{ - called = YES; - }; - } - - EXPECT_FALSE(called); -} - -TEST_F(BrowserCoordinatorTest, TestChildren) { - TestCoordinator* parent = [[TestCoordinator alloc] init]; - TestCoordinator* child = [[TestCoordinator alloc] init]; - - [parent addChildCoordinator:child]; - EXPECT_TRUE([parent.children containsObject:child]); - EXPECT_EQ(parent, child.parentCoordinator); - - [parent removeChildCoordinator:child]; - EXPECT_FALSE([parent.children containsObject:child]); - EXPECT_EQ(nil, child.parentCoordinator); - - TestCoordinator* otherParent = [[TestCoordinator alloc] init]; - TestCoordinator* otherChild = [[TestCoordinator alloc] init]; - [otherParent addChildCoordinator:otherChild]; - - // -removeChildCoordinator of a non-child should have no affect. - [parent removeChildCoordinator:otherChild]; - EXPECT_TRUE([otherParent.children containsObject:otherChild]); - EXPECT_EQ(otherParent, otherChild.parentCoordinator); -} - -TEST_F(BrowserCoordinatorTest, TestOverlay) { - TestCoordinator* parent = [[TestCoordinator alloc] init]; - TestCoordinator* child = [[TestCoordinator alloc] init]; - TestCoordinator* grandchild = [[TestCoordinator alloc] init]; - TestCoordinator* overlay = [[TestCoordinator alloc] init]; - TestCoordinator* secondOverlay = [[TestCoordinator alloc] init]; - - EXPECT_TRUE([parent canAddOverlayCoordinator:overlay]); - [parent addChildCoordinator:child]; - [child addChildCoordinator:grandchild]; - EXPECT_FALSE([parent canAddOverlayCoordinator:overlay]); - EXPECT_FALSE([child canAddOverlayCoordinator:overlay]); - EXPECT_TRUE([grandchild canAddOverlayCoordinator:overlay]); - EXPECT_FALSE([grandchild canAddOverlayCoordinator:child]); - - EXPECT_FALSE(overlay.overlaying); - [parent addOverlayCoordinator:overlay]; - EXPECT_TRUE(overlay.overlaying); - EXPECT_EQ(overlay, parent.overlayCoordinator); - EXPECT_EQ(overlay, child.overlayCoordinator); - EXPECT_EQ(overlay, grandchild.overlayCoordinator); - EXPECT_TRUE([grandchild.children containsObject:overlay]); - EXPECT_EQ(grandchild, overlay.parentCoordinator); - - // Shouldn't be able to add a second overlaying coordinator. - EXPECT_FALSE([grandchild canAddOverlayCoordinator:secondOverlay]); - EXPECT_FALSE(secondOverlay.overlaying); - [parent addOverlayCoordinator:secondOverlay]; - EXPECT_FALSE(secondOverlay.overlaying); - - [child removeOverlayCoordinator]; - EXPECT_FALSE(overlay.overlaying); - EXPECT_EQ(nil, parent.overlayCoordinator); - EXPECT_EQ(nil, child.overlayCoordinator); - EXPECT_EQ(nil, grandchild.overlayCoordinator); - EXPECT_FALSE([grandchild.children containsObject:overlay]); - EXPECT_EQ(nil, overlay.parentCoordinator); - - // An implementation that doesn't allow any overlays shouldn't get one. - NonOverlayableCoordinator* noOverlays = - [[NonOverlayableCoordinator alloc] init]; - TestCoordinator* thirdOverlay = [[TestCoordinator alloc] init]; - - EXPECT_FALSE([noOverlays canAddOverlayCoordinator:thirdOverlay]); - EXPECT_FALSE(thirdOverlay.overlaying); - [noOverlays addOverlayCoordinator:thirdOverlay]; - EXPECT_FALSE(thirdOverlay.overlaying); -} - -TEST_F(BrowserCoordinatorTest, AddedRemoved) { - TestCoordinator* parent = [[TestCoordinator alloc] init]; - TestCoordinator* child = [[TestCoordinator alloc] init]; - - // Add to the parent. - EXPECT_FALSE(child.wasAddedCalled); - EXPECT_FALSE(child.willBeRemovedCalled); - [parent addChildCoordinator:child]; - EXPECT_TRUE(child.wasAddedCalled); - EXPECT_FALSE(child.willBeRemovedCalled); - - // Remove from the parent. - [parent removeChildCoordinator:child]; - EXPECT_TRUE(child.willBeRemovedCalled); -} - -TEST_F(BrowserCoordinatorTest, DidStartWillStop) { - TestCoordinator* parent = [[TestCoordinator alloc] init]; - TestCoordinator* child = [[TestCoordinator alloc] init]; - [parent addChildCoordinator:child]; - EXPECT_FALSE(parent.childDidStartCalled); - EXPECT_FALSE(parent.childWillStopCalled); - - [child start]; - EXPECT_TRUE(parent.childDidStartCalled); - EXPECT_FALSE(parent.childWillStopCalled); - - [child stop]; - EXPECT_TRUE(parent.childDidStartCalled); - EXPECT_TRUE(parent.childWillStopCalled); -} - -TEST_F(BrowserCoordinatorTest, StopStopsStartedChildren) { - TestCoordinator* parent = [[TestCoordinator alloc] init]; - TestCoordinator* child = [[TestCoordinator alloc] init]; - [parent addChildCoordinator:child]; - [parent start]; - [child start]; - __block BOOL called = NO; - child.stopHandler = ^{ - called = YES; - }; - EXPECT_FALSE(called); - - // Call stop on the parent. - [parent stop]; - - // It should have called stop on the child. - EXPECT_TRUE(called); -} - -TEST_F(BrowserCoordinatorTest, StopStopsNonStartedChildren) { - TestCoordinator* parent = [[TestCoordinator alloc] init]; - TestCoordinator* child = [[TestCoordinator alloc] init]; - [parent addChildCoordinator:child]; - [parent start]; - __block BOOL called = NO; - child.stopHandler = ^{ - called = YES; - }; - EXPECT_FALSE(called); - - // Call stop on the parent. - [parent stop]; - - // It should not have called stop on the child. - EXPECT_TRUE(called); -} - -TEST_F(BrowserCoordinatorTest, BrowserIsNilAfterCoordinatorIsRemoved) { - TestCoordinator* parent = [[TestCoordinator alloc] init]; - TestCoordinator* child = [[TestCoordinator alloc] init]; - parent.browser = GetBrowser(); - [parent addChildCoordinator:child]; - - EXPECT_NE(nil, child.browser); - - // Remove the child. - [parent removeChildCoordinator:child]; - - EXPECT_EQ(nil, child.browser); -} - -TEST_F(BrowserCoordinatorTest, RemoveRemovesGrandChildren) { - TestCoordinator* parent = [[TestCoordinator alloc] init]; - TestCoordinator* child = [[TestCoordinator alloc] init]; - TestCoordinator* grandChild = [[TestCoordinator alloc] init]; - [child addChildCoordinator:grandChild]; - [parent addChildCoordinator:child]; - - EXPECT_FALSE(grandChild.willBeRemovedCalled); - EXPECT_FALSE(child.removeCalled); - - // Remove the child. - [parent removeChildCoordinator:child]; - - EXPECT_TRUE(grandChild.willBeRemovedCalled); - EXPECT_TRUE(child.removeCalled); -} - -TEST_F(BrowserCoordinatorTest, - RemoveRemovesGrandChildThenCallWillRemoveOnChild) { - TestCoordinator* parent = [[TestCoordinator alloc] init]; - TestCoordinator* child = [[TestCoordinator alloc] init]; - TestCoordinator* grandChild = [[TestCoordinator alloc] init]; - [child addChildCoordinator:grandChild]; - [parent addChildCoordinator:child]; - EXPECT_FALSE(grandChild.willBeRemovedCalled); - EXPECT_FALSE(child.removeCalled); - __weak TestCoordinator* weakChild = child; - child.willBeRemovedHandler = ^{ - EXPECT_TRUE(grandChild.willBeRemovedCalled); - EXPECT_TRUE(weakChild.removeCalled); - }; - - // Remove the child. - [parent removeChildCoordinator:child]; - - EXPECT_TRUE(child.willBeRemovedCalled); -} - -TEST_F(BrowserCoordinatorTest, RemoveChildWithMultipleGrandChildren) { - TestCoordinator* parent = [[TestCoordinator alloc] init]; - TestCoordinator* child = [[TestCoordinator alloc] init]; - TestCoordinator* grandChild1 = [[TestCoordinator alloc] init]; - TestCoordinator* grandChild2 = [[TestCoordinator alloc] init]; - [child addChildCoordinator:grandChild1]; - [child addChildCoordinator:grandChild2]; - [parent addChildCoordinator:child]; - - // Remove the child. - [parent removeChildCoordinator:child]; -}
diff --git a/ios/testing/data/http_server_files/history.html b/ios/testing/data/http_server_files/history.html index b2c2e4d..6d08717 100644 --- a/ios/testing/data/http_server_files/history.html +++ b/ios/testing/data/http_server_files/history.html
@@ -46,6 +46,7 @@ <input type="button" value="goBack" id="goBack" onclick="goBack()" /><br> <input type="button" value="goBack2" id="goBack2" onclick="goBack2()" /><br> +<input type="button" value="goBack3" id="goBack3" onclick="goBack3()" /><br> <input type="button" value="goBack4" id="goBack4" onclick="goBack4()" /><br> <input type="button" value="goForward" id="goForward" onclick="goForward()" /><br>
diff --git a/ios/testing/data/http_server_files/history.js b/ios/testing/data/http_server_files/history.js index d4057cc..8fd1eb0 100644 --- a/ios/testing/data/http_server_files/history.js +++ b/ios/testing/data/http_server_files/history.js
@@ -128,6 +128,11 @@ window.history.go(-2); }; +function goBack3() { + clearOnloadDivText(); + window.history.go(-3); +}; + function goBack4() { clearOnloadDivText(); window.history.go(-4);
diff --git a/ipc/ipc_channel_mojo.h b/ipc/ipc_channel_mojo.h index 5aa06901..e8b7b92 100644 --- a/ipc/ipc_channel_mojo.h +++ b/ipc/ipc_channel_mojo.h
@@ -40,10 +40,9 @@ // TODO(morrita): Add APIs to create extra MessagePipes to let // Mojo-based objects talk over this Channel. // -class IPC_EXPORT ChannelMojo - : public Channel, - public Channel::AssociatedInterfaceSupport, - public NON_EXPORTED_BASE(internal::MessagePipeReader::Delegate) { +class IPC_EXPORT ChannelMojo : public Channel, + public Channel::AssociatedInterfaceSupport, + public internal::MessagePipeReader::Delegate { public: // Creates a ChannelMojo. static std::unique_ptr<ChannelMojo>
diff --git a/ipc/ipc_message_pipe_reader.h b/ipc/ipc_message_pipe_reader.h index ceb62fe..3fca2bb 100644 --- a/ipc/ipc_message_pipe_reader.h +++ b/ipc/ipc_message_pipe_reader.h
@@ -42,7 +42,7 @@ // be called on any thread. All |Delegate| functions will be called on the IO // thread. // -class IPC_EXPORT MessagePipeReader : public NON_EXPORTED_BASE(mojom::Channel) { +class IPC_EXPORT MessagePipeReader : public mojom::Channel { public: class Delegate { public:
diff --git a/mash/session/session.cc b/mash/session/session.cc index 088cd5f..080ad76 100644 --- a/mash/session/session.cc +++ b/mash/session/session.cc
@@ -20,7 +20,13 @@ void Session::OnStart() { StartWindowManager(); - StartQuickLaunch(); + // TODO(jonross): Re-enable when QuickLaunch for all builds once it no longer + // deadlocks with ServiceManager shutdown in mash_browser_tests. + // (crbug.com/594852) + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + quick_launch::mojom::kServiceName)) { + StartQuickLaunch(); + } } void Session::StartWindowManager() {
diff --git a/media/audio/audio_debug_recording_helper.h b/media/audio/audio_debug_recording_helper.h index b0f4c12..362b07f8 100644 --- a/media/audio/audio_debug_recording_helper.h +++ b/media/audio/audio_debug_recording_helper.h
@@ -47,8 +47,7 @@ // soundcard thread -> control thread -> file thread, // and with the merge we should be able to do // soundcard thread -> file thread. -class MEDIA_EXPORT AudioDebugRecordingHelper - : public NON_EXPORTED_BASE(AudioDebugRecorder) { +class MEDIA_EXPORT AudioDebugRecordingHelper : public AudioDebugRecorder { public: AudioDebugRecordingHelper( const AudioParameters& params,
diff --git a/media/audio/audio_input_device.h b/media/audio/audio_input_device.h index d656256..baee663 100644 --- a/media/audio/audio_input_device.h +++ b/media/audio/audio_input_device.h
@@ -76,10 +76,9 @@ // TODO(henrika): Add support for event handling (e.g. OnStateChanged, // OnCaptureStopped etc.) and ensure that we can deliver these notifications // to any clients using this class. -class MEDIA_EXPORT AudioInputDevice - : NON_EXPORTED_BASE(public AudioCapturerSource), - NON_EXPORTED_BASE(public AudioInputIPCDelegate), - NON_EXPORTED_BASE(public ScopedTaskRunnerObserver) { +class MEDIA_EXPORT AudioInputDevice : public AudioCapturerSource, + public AudioInputIPCDelegate, + public ScopedTaskRunnerObserver { public: // NOTE: Clients must call Initialize() before using. AudioInputDevice(
diff --git a/media/audio/audio_output_controller.h b/media/audio/audio_output_controller.h index 0b19326..537bf0325 100644 --- a/media/audio/audio_output_controller.h +++ b/media/audio/audio_output_controller.h
@@ -66,7 +66,7 @@ : public base::RefCountedThreadSafe<AudioOutputController>, public AudioOutputStream::AudioSourceCallback, public AudioSourceDiverter, - NON_EXPORTED_BASE(public AudioManager::AudioDeviceListener) { + public AudioManager::AudioDeviceListener { public: // An event handler that receives events from the AudioOutputController. The // following methods are called on the audio manager thread.
diff --git a/media/audio/audio_output_device.h b/media/audio/audio_output_device.h index 9a88392..af3d11fa 100644 --- a/media/audio/audio_output_device.h +++ b/media/audio/audio_output_device.h
@@ -83,10 +83,9 @@ namespace media { -class MEDIA_EXPORT AudioOutputDevice - : NON_EXPORTED_BASE(public AudioRendererSink), - NON_EXPORTED_BASE(public AudioOutputIPCDelegate), - NON_EXPORTED_BASE(public ScopedTaskRunnerObserver) { +class MEDIA_EXPORT AudioOutputDevice : public AudioRendererSink, + public AudioOutputIPCDelegate, + public ScopedTaskRunnerObserver { public: // NOTE: Clients must call Initialize() before using. AudioOutputDevice(
diff --git a/media/audio/audio_output_stream_sink.h b/media/audio/audio_output_stream_sink.h index 19a5c46..8407e9e 100644 --- a/media/audio/audio_output_stream_sink.h +++ b/media/audio/audio_output_stream_sink.h
@@ -27,7 +27,7 @@ // TODO(dalecurtis): Delete this class once we have a proper mojo audio service; // tracked by http://crbug.com/425368 class MEDIA_EXPORT AudioOutputStreamSink - : NON_EXPORTED_BASE(public RestartableAudioRendererSink), + : public RestartableAudioRendererSink, public AudioOutputStream::AudioSourceCallback { public: AudioOutputStreamSink();
diff --git a/media/audio/clockless_audio_sink.h b/media/audio/clockless_audio_sink.h index c5e01a75..fec3dd5 100644 --- a/media/audio/clockless_audio_sink.h +++ b/media/audio/clockless_audio_sink.h
@@ -17,8 +17,7 @@ // Implementation of an AudioRendererSink that consumes the audio as fast as // possible. This class does not support multiple Play()/Pause() events. -class MEDIA_EXPORT ClocklessAudioSink - : NON_EXPORTED_BASE(public AudioRendererSink) { +class MEDIA_EXPORT ClocklessAudioSink : public AudioRendererSink { public: ClocklessAudioSink(); explicit ClocklessAudioSink(const OutputDeviceInfo& device_info);
diff --git a/media/audio/fake_audio_log_factory.h b/media/audio/fake_audio_log_factory.h index d78d533..2a6d62a9 100644 --- a/media/audio/fake_audio_log_factory.h +++ b/media/audio/fake_audio_log_factory.h
@@ -13,8 +13,7 @@ namespace media { // Creates stub AudioLog instances, for testing, which do nothing. -class MEDIA_EXPORT FakeAudioLogFactory - : NON_EXPORTED_BASE(public AudioLogFactory) { +class MEDIA_EXPORT FakeAudioLogFactory : public AudioLogFactory { public: FakeAudioLogFactory(); ~FakeAudioLogFactory() override;
diff --git a/media/audio/null_audio_sink.h b/media/audio/null_audio_sink.h index 84e0263..9a2eb64 100644 --- a/media/audio/null_audio_sink.h +++ b/media/audio/null_audio_sink.h
@@ -20,8 +20,7 @@ class AudioHash; class FakeAudioWorker; -class MEDIA_EXPORT NullAudioSink - : NON_EXPORTED_BASE(public SwitchableAudioRendererSink) { +class MEDIA_EXPORT NullAudioSink : public SwitchableAudioRendererSink { public: NullAudioSink(const scoped_refptr<base::SingleThreadTaskRunner>& task_runner);
diff --git a/media/base/android/BUILD.gn b/media/base/android/BUILD.gn index 093a9c0..f263405 100644 --- a/media/base/android/BUILD.gn +++ b/media/base/android/BUILD.gn
@@ -73,6 +73,12 @@ "//ui/gl", "//url", ] + if (proprietary_codecs) { + sources += [ + "extract_sps_and_pps.cc", + "extract_sps_and_pps.h", + ] + } } source_set("unit_tests") {
diff --git a/media/base/android/extract_sps_and_pps.cc b/media/base/android/extract_sps_and_pps.cc new file mode 100644 index 0000000..213b419 --- /dev/null +++ b/media/base/android/extract_sps_and_pps.cc
@@ -0,0 +1,37 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "media/base/android/extract_sps_and_pps.h" + +#include <array> + +#include "media/formats/mp4/box_definitions.h" + +namespace media { + +void ExtractSpsAndPps(const std::vector<uint8_t>& avcc, + std::vector<uint8_t>* sps_out, + std::vector<uint8_t>* pps_out) { + if (avcc.empty()) + return; + + mp4::AVCDecoderConfigurationRecord record; + if (!record.Parse(avcc.data(), avcc.size())) { + DVLOG(1) << "Failed to extract SPS and PPS"; + return; + } + + constexpr std::array<uint8_t, 4> prefix = {{0, 0, 0, 1}}; + for (const std::vector<uint8_t>& sps : record.sps_list) { + sps_out->insert(sps_out->end(), prefix.begin(), prefix.end()); + sps_out->insert(sps_out->end(), sps.begin(), sps.end()); + } + + for (const std::vector<uint8_t>& pps : record.pps_list) { + pps_out->insert(pps_out->end(), prefix.begin(), prefix.end()); + pps_out->insert(pps_out->end(), pps.begin(), pps.end()); + } +} + +} // namespace media
diff --git a/media/base/android/extract_sps_and_pps.h b/media/base/android/extract_sps_and_pps.h new file mode 100644 index 0000000..d3310a6 --- /dev/null +++ b/media/base/android/extract_sps_and_pps.h
@@ -0,0 +1,25 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MEDIA_BASE_ANDROID_EXTRACT_SPS_AND_PPS_H_ +#define MEDIA_BASE_ANDROID_EXTRACT_SPS_AND_PPS_H_ + +#include <stdint.h> + +#include <vector> + +#include "media/base/media_export.h" + +namespace media { + +// Extracts the SPS and PPS lists from the given AVCC. Each SPS and +// PPS is prefixed with the Annex B framing bytes (0x0001). The out parameters +// are not modified on failure. +void MEDIA_EXPORT ExtractSpsAndPps(const std::vector<uint8_t>& avcc, + std::vector<uint8_t>* sps_out, + std::vector<uint8_t>* pps_out); + +} // namespace media + +#endif // MEDIA_BASE_ANDROID_EXTRACT_SPS_AND_PPS_H_
diff --git a/media/base/android/media_drm_bridge.cc b/media/base/android/media_drm_bridge.cc index c9c4b4dd..cdf2a69 100644 --- a/media/base/android/media_drm_bridge.cc +++ b/media/base/android/media_drm_bridge.cc
@@ -445,7 +445,7 @@ j_certificate)) { promise->resolve(); } else { - promise->reject(CdmPromise::INVALID_ACCESS_ERROR, 0, + promise->reject(CdmPromise::Exception::TYPE_ERROR, 0, "Set server certificate failed."); } } @@ -472,7 +472,7 @@ if (!delegate->OnCreateSession(init_data_type, init_data, &init_data_from_delegate, &optional_parameters_from_delegate)) { - promise->reject(CdmPromise::INVALID_ACCESS_ERROR, 0, + promise->reject(CdmPromise::Exception::TYPE_ERROR, 0, "Invalid init data."); return; } @@ -514,7 +514,7 @@ if (session_type != CdmSessionType::PERSISTENT_LICENSE_SESSION) { promise->reject( - CdmPromise::NOT_SUPPORTED_ERROR, 0, + CdmPromise::Exception::NOT_SUPPORTED_ERROR, 0, "LoadSession() is only supported for 'persistent-license'."); return; } @@ -636,8 +636,8 @@ void MediaDrmBridge::RejectPromise(uint32_t promise_id, const std::string& error_message) { DVLOG(2) << __func__; - cdm_promise_adapter_.RejectPromise(promise_id, CdmPromise::UNKNOWN_ERROR, 0, - error_message); + cdm_promise_adapter_.RejectPromise( + promise_id, CdmPromise::Exception::NOT_SUPPORTED_ERROR, 0, error_message); } void MediaDrmBridge::SetMediaCryptoReadyCB(
diff --git a/media/base/audio_renderer_mixer.h b/media/base/audio_renderer_mixer.h index d058ebf..f81e69a 100644 --- a/media/base/audio_renderer_mixer.h +++ b/media/base/audio_renderer_mixer.h
@@ -24,7 +24,7 @@ // which is funneled into a single shared AudioRendererSink; saving a bundle // on renderer side resources. class MEDIA_EXPORT AudioRendererMixer - : NON_EXPORTED_BASE(public AudioRendererSink::RenderCallback) { + : public AudioRendererSink::RenderCallback { public: typedef base::Callback<void(int)> UmaLogCallback;
diff --git a/media/base/audio_renderer_mixer_input.h b/media/base/audio_renderer_mixer_input.h index a1997dec..62ae3a7d 100644 --- a/media/base/audio_renderer_mixer_input.h +++ b/media/base/audio_renderer_mixer_input.h
@@ -32,7 +32,7 @@ class AudioRendererMixer; class MEDIA_EXPORT AudioRendererMixerInput - : NON_EXPORTED_BASE(public SwitchableAudioRendererSink), + : public SwitchableAudioRendererSink, public AudioConverter::InputCallback { public: AudioRendererMixerInput(AudioRendererMixerPool* mixer_pool,
diff --git a/media/base/bit_reader.h b/media/base/bit_reader.h index b3f230b..dd980ff1 100644 --- a/media/base/bit_reader.h +++ b/media/base/bit_reader.h
@@ -15,8 +15,7 @@ namespace media { -class MEDIA_EXPORT BitReader - : NON_EXPORTED_BASE(private BitReaderCore::ByteStreamProvider) { +class MEDIA_EXPORT BitReader : private BitReaderCore::ByteStreamProvider { public: // Initialize the reader to start reading at |data|, |size| being size // of |data| in bytes.
diff --git a/media/base/cdm_promise.h b/media/base/cdm_promise.h index 566bd59..9467973e 100644 --- a/media/base/cdm_promise.h +++ b/media/base/cdm_promise.h
@@ -32,17 +32,12 @@ // the pepper interface. class MEDIA_EXPORT CdmPromise { public: - // TODO(jrummell): Remove deprecated errors. See - // http://crbug.com/570216 - enum Exception { + enum class Exception { NOT_SUPPORTED_ERROR, INVALID_STATE_ERROR, - INVALID_ACCESS_ERROR, QUOTA_EXCEEDED_ERROR, - UNKNOWN_ERROR, - CLIENT_ERROR, - OUTPUT_ERROR, - EXCEPTION_MAX = OUTPUT_ERROR + TYPE_ERROR, + EXCEPTION_MAX = TYPE_ERROR }; enum ResolveParameterType { @@ -130,7 +125,7 @@ std::string message = "Unfulfilled promise rejected automatically during destruction."; DVLOG(1) << message; - reject(INVALID_STATE_ERROR, 0, message); + reject(Exception::INVALID_STATE_ERROR, 0, message); DCHECK(is_settled_); }
diff --git a/media/base/cdm_promise_adapter.cc b/media/base/cdm_promise_adapter.cc index f860d54..4455fea8 100644 --- a/media/base/cdm_promise_adapter.cc +++ b/media/base/cdm_promise_adapter.cc
@@ -61,7 +61,8 @@ // Reject all outstanding promises. DCHECK(thread_checker_.CalledOnValidThread()); for (auto& promise : promises_) - promise.second->reject(CdmPromise::UNKNOWN_ERROR, 0, "Operation aborted."); + promise.second->reject(CdmPromise::Exception::INVALID_STATE_ERROR, 0, + "Operation aborted."); promises_.clear(); }
diff --git a/media/base/content_decryption_module.cc b/media/base/content_decryption_module.cc index 782c34e..0b13a30 100644 --- a/media/base/content_decryption_module.cc +++ b/media/base/content_decryption_module.cc
@@ -16,7 +16,7 @@ void ContentDecryptionModule::GetStatusForPolicy( HdcpVersion min_hdcp_version, std::unique_ptr<KeyStatusCdmPromise> promise) { - promise->reject(CdmPromise::NOT_SUPPORTED_ERROR, 0, + promise->reject(CdmPromise::Exception::NOT_SUPPORTED_ERROR, 0, "GetStatusForPolicy() is not supported."); }
diff --git a/media/base/ipc/media_param_traits_macros.h b/media/base/ipc/media_param_traits_macros.h index 5d80897b..1695e6f 100644 --- a/media/base/ipc/media_param_traits_macros.h +++ b/media/base/ipc/media_param_traits_macros.h
@@ -48,7 +48,7 @@ media::CdmMessageType::MESSAGE_TYPE_MAX) IPC_ENUM_TRAITS_MAX_VALUE(media::CdmPromise::Exception, - media::CdmPromise::EXCEPTION_MAX) + media::CdmPromise::Exception::EXCEPTION_MAX) IPC_ENUM_TRAITS_MAX_VALUE(media::CdmSessionType, media::CdmSessionType::SESSION_TYPE_MAX)
diff --git a/media/base/silent_sink_suspender.h b/media/base/silent_sink_suspender.h index 5fad221..df396cc 100644 --- a/media/base/silent_sink_suspender.h +++ b/media/base/silent_sink_suspender.h
@@ -32,7 +32,7 @@ // physical hardwasre usage. Note: The transition from real to fake audio output // and vice versa may result in some irregular Render() callbacks. class MEDIA_EXPORT SilentSinkSuspender - : NON_EXPORTED_BASE(public AudioRendererSink::RenderCallback) { + : public AudioRendererSink::RenderCallback { public: // |callback| is the true producer of audio data, |params| are the parameters // used to initialize |sink|, |sink| is the sink to monitor for idle, and
diff --git a/media/blink/cdm_result_promise_helper.cc b/media/blink/cdm_result_promise_helper.cc index e45d29f..b65a2247 100644 --- a/media/blink/cdm_result_promise_helper.cc +++ b/media/blink/cdm_result_promise_helper.cc
@@ -12,50 +12,33 @@ CdmResultForUMA ConvertCdmExceptionToResultForUMA( CdmPromise::Exception exception_code) { switch (exception_code) { - case CdmPromise::NOT_SUPPORTED_ERROR: + case CdmPromise::Exception::NOT_SUPPORTED_ERROR: return NOT_SUPPORTED_ERROR; - case CdmPromise::INVALID_STATE_ERROR: + case CdmPromise::Exception::INVALID_STATE_ERROR: return INVALID_STATE_ERROR; - case CdmPromise::INVALID_ACCESS_ERROR: - return INVALID_ACCESS_ERROR; - case CdmPromise::QUOTA_EXCEEDED_ERROR: + case CdmPromise::Exception::QUOTA_EXCEEDED_ERROR: return QUOTA_EXCEEDED_ERROR; - case CdmPromise::UNKNOWN_ERROR: - return UNKNOWN_ERROR; - case CdmPromise::CLIENT_ERROR: - return CLIENT_ERROR; - case CdmPromise::OUTPUT_ERROR: - return OUTPUT_ERROR; + case CdmPromise::Exception::TYPE_ERROR: + return TYPE_ERROR; } NOTREACHED(); - return UNKNOWN_ERROR; + return INVALID_STATE_ERROR; } blink::WebContentDecryptionModuleException ConvertCdmException( CdmPromise::Exception exception_code) { switch (exception_code) { - case CdmPromise::NOT_SUPPORTED_ERROR: + case CdmPromise::Exception::NOT_SUPPORTED_ERROR: return blink::kWebContentDecryptionModuleExceptionNotSupportedError; - case CdmPromise::INVALID_STATE_ERROR: + case CdmPromise::Exception::INVALID_STATE_ERROR: return blink::kWebContentDecryptionModuleExceptionInvalidStateError; - - // TODO(jrummell): Since InvalidAccess is not returned, thus should be - // renamed to TYPE_ERROR. http://crbug.com/570216#c11. - case CdmPromise::INVALID_ACCESS_ERROR: - return blink::kWebContentDecryptionModuleExceptionTypeError; - case CdmPromise::QUOTA_EXCEEDED_ERROR: + case CdmPromise::Exception::QUOTA_EXCEEDED_ERROR: return blink::kWebContentDecryptionModuleExceptionQuotaExceededError; - case CdmPromise::UNKNOWN_ERROR: - return blink::kWebContentDecryptionModuleExceptionUnknownError; - - // These are deprecated, and should be removed. - // http://crbug.com/570216#c11. - case CdmPromise::CLIENT_ERROR: - case CdmPromise::OUTPUT_ERROR: - break; + case CdmPromise::Exception::TYPE_ERROR: + return blink::kWebContentDecryptionModuleExceptionTypeError; } NOTREACHED(); - return blink::kWebContentDecryptionModuleExceptionUnknownError; + return blink::kWebContentDecryptionModuleExceptionInvalidStateError; } blink::WebEncryptedMediaKeyInformation::KeyStatus ConvertCdmKeyStatus(
diff --git a/media/blink/cdm_result_promise_helper.h b/media/blink/cdm_result_promise_helper.h index 617a9547..98a9177 100644 --- a/media/blink/cdm_result_promise_helper.h +++ b/media/blink/cdm_result_promise_helper.h
@@ -18,17 +18,17 @@ // A superset of media::ContentDecryptionModule::Exception for UMA reporting. // These values should never be changed as it will affect existing reporting, // and must match the values for CdmPromiseResult in -// tools/metrics/histograms/histograms.xml. +// tools/metrics/histograms/enums.xml. Deprecated values should never be reused. enum CdmResultForUMA { SUCCESS = 0, NOT_SUPPORTED_ERROR = 1, INVALID_STATE_ERROR = 2, - INVALID_ACCESS_ERROR = 3, + TYPE_ERROR = 3, QUOTA_EXCEEDED_ERROR = 4, - UNKNOWN_ERROR = 5, - CLIENT_ERROR = 6, - OUTPUT_ERROR = 7, - NUM_RESULT_CODES + // UNKNOWN_ERROR = 5, // Deprecated. + // CLIENT_ERROR = 6, // Deprecated. + // OUTPUT_ERROR = 7, // Deprecated. + NUM_RESULT_CODES // Must be last. }; MEDIA_BLINK_EXPORT CdmResultForUMA
diff --git a/media/blink/multibuffer_reader.h b/media/blink/multibuffer_reader.h index 8135d562..e0a76ef1 100644 --- a/media/blink/multibuffer_reader.h +++ b/media/blink/multibuffer_reader.h
@@ -20,8 +20,7 @@ // Wrapper for MultiBuffer that offers a simple byte-reading // interface with prefetch. -class MEDIA_BLINK_EXPORT MultiBufferReader - : NON_EXPORTED_BASE(public MultiBuffer::Reader) { +class MEDIA_BLINK_EXPORT MultiBufferReader : public MultiBuffer::Reader { public: // Note that |progress_callback| is guaranteed to be called if // a redirect happens and the url_data is updated. Otherwise
diff --git a/media/blink/new_session_cdm_result_promise.cc b/media/blink/new_session_cdm_result_promise.cc index f2757d0d..adca254c 100644 --- a/media/blink/new_session_cdm_result_promise.cc +++ b/media/blink/new_session_cdm_result_promise.cc
@@ -52,7 +52,8 @@ new_session_created_cb_.Run(session_id, &status); if (status == SessionInitStatus::UNKNOWN_STATUS) { - reject(INVALID_STATE_ERROR, 0, "Cannot finish session initialization"); + reject(Exception::INVALID_STATE_ERROR, 0, + "Cannot finish session initialization"); return; }
diff --git a/media/blink/resource_multibuffer_data_provider.h b/media/blink/resource_multibuffer_data_provider.h index 53d7a8fc..06836d71 100644 --- a/media/blink/resource_multibuffer_data_provider.h +++ b/media/blink/resource_multibuffer_data_provider.h
@@ -27,8 +27,8 @@ namespace media { class MEDIA_BLINK_EXPORT ResourceMultiBufferDataProvider - : NON_EXPORTED_BASE(public MultiBuffer::DataProvider), - NON_EXPORTED_BASE(public blink::WebAssociatedURLLoaderClient) { + : public MultiBuffer::DataProvider, + public blink::WebAssociatedURLLoaderClient { public: // NUmber of times we'll retry if the connection fails. enum { kMaxRetries = 30 };
diff --git a/media/blink/url_index.h b/media/blink/url_index.h index c3f17a9..b8111f6 100644 --- a/media/blink/url_index.h +++ b/media/blink/url_index.h
@@ -30,8 +30,7 @@ // A multibuffer for loading media resources which knows // how to create MultiBufferDataProviders to load data // into the cache. -class MEDIA_BLINK_EXPORT ResourceMultiBuffer - : NON_EXPORTED_BASE(public MultiBuffer) { +class MEDIA_BLINK_EXPORT ResourceMultiBuffer : public MultiBuffer { public: ResourceMultiBuffer(UrlData* url_data_, int block_shift); ~ResourceMultiBuffer() override;
diff --git a/media/blink/video_frame_compositor.h b/media/blink/video_frame_compositor.h index 0068933..ec438ea7 100644 --- a/media/blink/video_frame_compositor.h +++ b/media/blink/video_frame_compositor.h
@@ -54,9 +54,8 @@ // // VideoFrameCompositor must live on the same thread as the compositor, though // it may be constructed on any thread. -class MEDIA_BLINK_EXPORT VideoFrameCompositor - : public VideoRendererSink, - NON_EXPORTED_BASE(public cc::VideoFrameProvider) { +class MEDIA_BLINK_EXPORT VideoFrameCompositor : public VideoRendererSink, + public cc::VideoFrameProvider { public: // Used to report back the time when the new frame has been processed. using OnNewProcessedFrameCB = base::Callback<void(base::TimeTicks)>;
diff --git a/media/blink/webaudiosourceprovider_impl.h b/media/blink/webaudiosourceprovider_impl.h index 1950854..5420c73b 100644 --- a/media/blink/webaudiosourceprovider_impl.h +++ b/media/blink/webaudiosourceprovider_impl.h
@@ -41,8 +41,8 @@ // // All calls are protected by a lock. class MEDIA_BLINK_EXPORT WebAudioSourceProviderImpl - : NON_EXPORTED_BASE(public blink::WebAudioSourceProvider), - NON_EXPORTED_BASE(public SwitchableAudioRendererSink) { + : public blink::WebAudioSourceProvider, + public SwitchableAudioRendererSink { public: using CopyAudioCB = base::Callback<void(std::unique_ptr<AudioBus>, uint32_t frames_delayed,
diff --git a/media/blink/webmediacapabilitiesclient_impl.h b/media/blink/webmediacapabilitiesclient_impl.h index e47464a32..97d3c0f 100644 --- a/media/blink/webmediacapabilitiesclient_impl.h +++ b/media/blink/webmediacapabilitiesclient_impl.h
@@ -13,7 +13,7 @@ namespace media { class MEDIA_BLINK_EXPORT WebMediaCapabilitiesClientImpl - : NON_EXPORTED_BASE(public blink::WebMediaCapabilitiesClient) { + : public blink::WebMediaCapabilitiesClient { public: WebMediaCapabilitiesClientImpl(); ~WebMediaCapabilitiesClientImpl() override;
diff --git a/media/blink/webmediaplayer_impl.h b/media/blink/webmediaplayer_impl.h index 1d5ecc3..6087b90 100644 --- a/media/blink/webmediaplayer_impl.h +++ b/media/blink/webmediaplayer_impl.h
@@ -86,9 +86,9 @@ // Pipeline. Handles normal resource loading, Media Source, and // Encrypted Media. class MEDIA_BLINK_EXPORT WebMediaPlayerImpl - : public NON_EXPORTED_BASE(blink::WebMediaPlayer), - public NON_EXPORTED_BASE(WebMediaPlayerDelegate::Observer), - public NON_EXPORTED_BASE(Pipeline::Client), + : public blink::WebMediaPlayer, + public WebMediaPlayerDelegate::Observer, + public Pipeline::Client, public MediaObserverClient, public base::SupportsWeakPtr<WebMediaPlayerImpl> { public:
diff --git a/media/blink/webmediasource_impl.h b/media/blink/webmediasource_impl.h index 025fc56a..da450946 100644 --- a/media/blink/webmediasource_impl.h +++ b/media/blink/webmediasource_impl.h
@@ -15,8 +15,7 @@ namespace media { class ChunkDemuxer; -class MEDIA_BLINK_EXPORT WebMediaSourceImpl - : NON_EXPORTED_BASE(public blink::WebMediaSource) { +class MEDIA_BLINK_EXPORT WebMediaSourceImpl : public blink::WebMediaSource { public: WebMediaSourceImpl(ChunkDemuxer* demuxer); ~WebMediaSourceImpl() override;
diff --git a/media/cdm/aes_decryptor.cc b/media/cdm/aes_decryptor.cc index f7dfca3..7fdeb8f 100644 --- a/media/cdm/aes_decryptor.cc +++ b/media/cdm/aes_decryptor.cc
@@ -293,7 +293,7 @@ void AesDecryptor::SetServerCertificate( const std::vector<uint8_t>& certificate, std::unique_ptr<SimpleCdmPromise> promise) { - promise->reject(CdmPromise::NOT_SUPPORTED_ERROR, 0, + promise->reject(CdmPromise::Exception::NOT_SUPPORTED_ERROR, 0, "SetServerCertificate() is not supported."); } @@ -313,7 +313,8 @@ // |init_data| is simply the key needed. if (init_data.size() < limits::kMinKeyIdLength || init_data.size() > limits::kMaxKeyIdLength) { - promise->reject(CdmPromise::NOT_SUPPORTED_ERROR, 0, "Incorrect length"); + promise->reject(CdmPromise::Exception::TYPE_ERROR, 0, + "Incorrect length"); return; } keys.push_back(init_data); @@ -322,13 +323,13 @@ #if BUILDFLAG(USE_PROPRIETARY_CODECS) // |init_data| is a set of 0 or more concatenated 'pssh' boxes. if (!GetKeyIdsForCommonSystemId(init_data, &keys)) { - promise->reject(CdmPromise::NOT_SUPPORTED_ERROR, 0, + promise->reject(CdmPromise::Exception::NOT_SUPPORTED_ERROR, 0, "No supported PSSH box found."); return; } break; #else - promise->reject(CdmPromise::NOT_SUPPORTED_ERROR, 0, + promise->reject(CdmPromise::Exception::NOT_SUPPORTED_ERROR, 0, "Initialization data type CENC is not supported."); return; #endif @@ -337,14 +338,14 @@ std::string error_message; if (!ExtractKeyIdsFromKeyIdsInitData(init_data_string, &keys, &error_message)) { - promise->reject(CdmPromise::NOT_SUPPORTED_ERROR, 0, error_message); + promise->reject(CdmPromise::Exception::TYPE_ERROR, 0, error_message); return; } break; } default: NOTREACHED(); - promise->reject(CdmPromise::NOT_SUPPORTED_ERROR, 0, + promise->reject(CdmPromise::Exception::NOT_SUPPORTED_ERROR, 0, "init_data_type not supported."); return; } @@ -362,7 +363,7 @@ // the session state. Should not be called as blink should not allow // persistent sessions for ClearKey. NOTREACHED(); - promise->reject(CdmPromise::NOT_SUPPORTED_ERROR, 0, + promise->reject(CdmPromise::Exception::NOT_SUPPORTED_ERROR, 0, "LoadSession() is not supported."); } @@ -376,17 +377,18 @@ // could get called on a closed session. // https://github.com/w3c/encrypted-media/issues/365 if (open_sessions_.find(session_id) == open_sessions_.end()) { - promise->reject(CdmPromise::INVALID_ACCESS_ERROR, 0, + promise->reject(CdmPromise::Exception::INVALID_STATE_ERROR, 0, "Session does not exist."); return; } bool key_added = false; + CdmPromise::Exception exception; std::string error_message; if (!UpdateSessionWithJWK(session_id, std::string(response.begin(), response.end()), - &key_added, &error_message)) { - promise->reject(CdmPromise::INVALID_ACCESS_ERROR, 0, error_message); + &key_added, &exception, &error_message)) { + promise->reject(exception, 0, error_message); return; } @@ -396,6 +398,7 @@ bool AesDecryptor::UpdateSessionWithJWK(const std::string& session_id, const std::string& json_web_key_set, bool* key_added, + CdmPromise::Exception* exception, std::string* error_message) { auto open_session = open_sessions_.find(session_id); DCHECK(open_session != open_sessions_.end()); @@ -403,12 +406,14 @@ KeyIdAndKeyPairs keys; if (!ExtractKeysFromJWKSet(json_web_key_set, &keys, &session_type)) { + *exception = CdmPromise::Exception::TYPE_ERROR; error_message->assign("Invalid JSON Web Key Set."); return false; } // Make sure that at least one key was extracted. if (keys.empty()) { + *exception = CdmPromise::Exception::TYPE_ERROR; error_message->assign("JSON Web Key Set does not contain any keys."); return false; } @@ -418,6 +423,7 @@ if (it->second.length() != static_cast<size_t>(DecryptConfig::kDecryptionKeySize)) { DVLOG(1) << "Invalid key length: " << it->second.length(); + *exception = CdmPromise::Exception::TYPE_ERROR; error_message->assign("Invalid key length."); return false; } @@ -428,6 +434,7 @@ local_key_added = true; if (!AddDecryptionKey(session_id, it->first, it->second)) { + *exception = CdmPromise::Exception::INVALID_STATE_ERROR; error_message->assign("Unable to add key."); return false; } @@ -495,7 +502,7 @@ if (it == open_sessions_.end()) { // Session doesn't exist. Since this should only be called if the session // existed at one time, this must mean the session has been closed. - promise->reject(CdmPromise::INVALID_STATE_ERROR, 0, + promise->reject(CdmPromise::Exception::INVALID_STATE_ERROR, 0, "The session is already closed."); return; }
diff --git a/media/cdm/aes_decryptor.h b/media/cdm/aes_decryptor.h index b4f5633..ddab596f 100644 --- a/media/cdm/aes_decryptor.h +++ b/media/cdm/aes_decryptor.h
@@ -18,6 +18,7 @@ #include "base/synchronization/lock.h" #include "media/base/cdm_context.h" #include "media/base/cdm_key_information.h" +#include "media/base/cdm_promise.h" #include "media/base/content_decryption_module.h" #include "media/base/decryptor.h" #include "media/base/media_export.h" @@ -108,6 +109,7 @@ bool UpdateSessionWithJWK(const std::string& session_id, const std::string& json_web_key_set, bool* key_added, + CdmPromise::Exception* exception, std::string* error_message); // Performs the final steps of UpdateSession (notify any listeners for keys
diff --git a/media/cdm/cdm_adapter.cc b/media/cdm/cdm_adapter.cc index f2bb0e8be..6feb43b 100644 --- a/media/cdm/cdm_adapter.cc +++ b/media/cdm/cdm_adapter.cc
@@ -96,17 +96,17 @@ CdmPromise::Exception ToMediaExceptionType(cdm::Exception exception) { switch (exception) { case cdm::kExceptionTypeError: - return CdmPromise::INVALID_ACCESS_ERROR; + return CdmPromise::Exception::TYPE_ERROR; case cdm::kExceptionNotSupportedError: - return CdmPromise::NOT_SUPPORTED_ERROR; + return CdmPromise::Exception::NOT_SUPPORTED_ERROR; case cdm::kExceptionInvalidStateError: - return CdmPromise::INVALID_STATE_ERROR; + return CdmPromise::Exception::INVALID_STATE_ERROR; case cdm::kExceptionQuotaExceededError: - return CdmPromise::QUOTA_EXCEEDED_ERROR; + return CdmPromise::Exception::QUOTA_EXCEEDED_ERROR; } NOTREACHED() << "Unexpected cdm::Exception " << exception; - return CdmPromise::INVALID_STATE_ERROR; + return CdmPromise::Exception::INVALID_STATE_ERROR; } cdm::Exception ToCdmExceptionType(cdm::Error error) { @@ -114,15 +114,18 @@ case cdm::kNotSupportedError: return cdm::kExceptionNotSupportedError; case cdm::kInvalidStateError: - return cdm::kExceptionTypeError; - case cdm::kInvalidAccessError: return cdm::kExceptionInvalidStateError; + case cdm::kInvalidAccessError: + return cdm::kExceptionTypeError; case cdm::kQuotaExceededError: return cdm::kExceptionQuotaExceededError; + + // TODO(jrummell): Remove these once CDM_8 is no longer supported. + // https://crbug.com/737296. case cdm::kUnknownError: case cdm::kClientError: case cdm::kOutputError: - break; + return cdm::kExceptionNotSupportedError; } NOTREACHED() << "Unexpected cdm::Error " << error; @@ -453,7 +456,7 @@ void CdmAdapter::Initialize(std::unique_ptr<media::SimpleCdmPromise> promise) { cdm_.reset(CreateCdmInstance(key_system_)); if (!cdm_) { - promise->reject(CdmPromise::INVALID_ACCESS_ERROR, 0, + promise->reject(CdmPromise::Exception::INVALID_STATE_ERROR, 0, "Unable to create CDM."); return; } @@ -470,7 +473,7 @@ if (certificate.size() < limits::kMinCertificateLength || certificate.size() > limits::kMaxCertificateLength) { - promise->reject(CdmPromise::INVALID_ACCESS_ERROR, 0, + promise->reject(CdmPromise::Exception::TYPE_ERROR, 0, "Incorrect certificate."); return; } @@ -487,9 +490,9 @@ uint32_t promise_id = cdm_promise_adapter_.SavePromise(std::move(promise)); if (!cdm_->GetStatusForPolicy(promise_id, ToCdmHdcpVersion(min_hdcp_version))) { - cdm_promise_adapter_.RejectPromise(promise_id, - CdmPromise::NOT_SUPPORTED_ERROR, 0, - "GetStatusForPolicy not supported."); + cdm_promise_adapter_.RejectPromise( + promise_id, CdmPromise::Exception::NOT_SUPPORTED_ERROR, 0, + "GetStatusForPolicy not supported."); } }
diff --git a/media/cdm/cdm_adapter.h b/media/cdm/cdm_adapter.h index 1b7e2d1..150d17a 100644 --- a/media/cdm/cdm_adapter.h +++ b/media/cdm/cdm_adapter.h
@@ -48,8 +48,8 @@ class MEDIA_EXPORT CdmAdapter : public ContentDecryptionModule, public CdmContext, public Decryptor, - NON_EXPORTED_BASE(public cdm::Host_8), - NON_EXPORTED_BASE(public cdm::Host_9) { + public cdm::Host_8, + public cdm::Host_9 { public: // Creates the CDM and initialize it using |key_system| and |cdm_config|. // |allocator| is to be used whenever the CDM needs memory and to create
diff --git a/media/cdm/cdm_file_adapter.h b/media/cdm/cdm_file_adapter.h index dbdfaa7b..c170500e 100644 --- a/media/cdm/cdm_file_adapter.h +++ b/media/cdm/cdm_file_adapter.h
@@ -20,8 +20,7 @@ namespace media { // This class provides the ability to read and write a file using cdm::FileIO. -class MEDIA_EXPORT CdmFileAdapter - : NON_EXPORTED_BASE(public cdm::FileIOClient) { +class MEDIA_EXPORT CdmFileAdapter : public cdm::FileIOClient { public: enum class Status { kSuccess, kInUse, kError }; using FileOpenedCB = base::OnceCallback<void(Status status)>;
diff --git a/media/cdm/cdm_file_io.h b/media/cdm/cdm_file_io.h index 812bf5f..21571fb8 100644 --- a/media/cdm/cdm_file_io.h +++ b/media/cdm/cdm_file_io.h
@@ -14,7 +14,7 @@ // Implements a version of cdm::FileIO with a public destructor so it can be // used with std::unique_ptr. -class MEDIA_EXPORT CdmFileIO : NON_EXPORTED_BASE(public cdm::FileIO) { +class MEDIA_EXPORT CdmFileIO : public cdm::FileIO { public: ~CdmFileIO() override;
diff --git a/media/cdm/cdm_helpers.h b/media/cdm/cdm_helpers.h index 6713d12..198c0885 100644 --- a/media/cdm/cdm_helpers.h +++ b/media/cdm/cdm_helpers.h
@@ -42,8 +42,7 @@ DISALLOW_COPY_AND_ASSIGN(DecryptedBlockImpl); }; -class MEDIA_CDM_EXPORT VideoFrameImpl - : NON_EXPORTED_BASE(public cdm::VideoFrame) { +class MEDIA_CDM_EXPORT VideoFrameImpl : public cdm::VideoFrame { public: VideoFrameImpl(); ~VideoFrameImpl() override;
diff --git a/media/cdm/ppapi/external_clear_key/clear_key_cdm.cc b/media/cdm/ppapi/external_clear_key/clear_key_cdm.cc index e98c8e2e..0b73a4b 100644 --- a/media/cdm/ppapi/external_clear_key/clear_key_cdm.cc +++ b/media/cdm/ppapi/external_clear_key/clear_key_cdm.cc
@@ -132,21 +132,17 @@ static cdm::Exception ConvertException( media::CdmPromise::Exception exception_code) { switch (exception_code) { - case media::CdmPromise::NOT_SUPPORTED_ERROR: - return cdm::Exception::kExceptionNotSupportedError; - case media::CdmPromise::INVALID_STATE_ERROR: - return cdm::Exception::kExceptionInvalidStateError; - case media::CdmPromise::INVALID_ACCESS_ERROR: - return cdm::Exception::kExceptionTypeError; - case media::CdmPromise::QUOTA_EXCEEDED_ERROR: - return cdm::Exception::kExceptionQuotaExceededError; - case media::CdmPromise::UNKNOWN_ERROR: - case media::CdmPromise::CLIENT_ERROR: - case media::CdmPromise::OUTPUT_ERROR: - break; + case media::CdmPromise::Exception::NOT_SUPPORTED_ERROR: + return cdm::kExceptionNotSupportedError; + case media::CdmPromise::Exception::INVALID_STATE_ERROR: + return cdm::kExceptionInvalidStateError; + case media::CdmPromise::Exception::TYPE_ERROR: + return cdm::kExceptionTypeError; + case media::CdmPromise::Exception::QUOTA_EXCEEDED_ERROR: + return cdm::kExceptionQuotaExceededError; } NOTREACHED(); - return cdm::Exception::kExceptionNotSupportedError; + return cdm::kExceptionInvalidStateError; } static media::CdmSessionType ConvertSessionType(cdm::SessionType session_type) { @@ -400,7 +396,7 @@ DVLOG(1) << __func__; if (session_type != cdm::kTemporary && !allow_persistent_state_) { - OnPromiseFailed(promise_id, CdmPromise::INVALID_STATE_ERROR, 0, + OnPromiseFailed(promise_id, CdmPromise::Exception::INVALID_STATE_ERROR, 0, "Persistent state not allowed."); return; }
diff --git a/media/cdm/ppapi/external_clear_key/clear_key_persistent_session_cdm.cc b/media/cdm/ppapi/external_clear_key/clear_key_persistent_session_cdm.cc index 91d02ec..c10b61b 100644 --- a/media/cdm/ppapi/external_clear_key/clear_key_persistent_session_cdm.cc +++ b/media/cdm/ppapi/external_clear_key/clear_key_persistent_session_cdm.cc
@@ -180,7 +180,7 @@ CdmSessionType::PERSISTENT_LICENSE_SESSION)) { // If the session can't be created it's due to an already existing session // with the same name. - promise->reject(CdmPromise::QUOTA_EXCEEDED_ERROR, 0, + promise->reject(CdmPromise::Exception::QUOTA_EXCEEDED_ERROR, 0, "Session already exists."); return; } @@ -188,10 +188,11 @@ // Set the session's state using the data just read. bool key_added = false; + CdmPromise::Exception exception; std::string error_message; if (!cdm_->UpdateSessionWithJWK(session_id, std::string(data.begin(), data.end()), - &key_added, &error_message)) { + &key_added, &exception, &error_message)) { NOTREACHED() << "Saved session data is not usable, error = " << error_message; // Return an empty string to indicate that the session was not found. @@ -219,11 +220,12 @@ } bool key_added = false; + CdmPromise::Exception exception; std::string error_message; if (!cdm_->UpdateSessionWithJWK(session_id, std::string(response.begin(), response.end()), - &key_added, &error_message)) { - promise->reject(CdmPromise::INVALID_ACCESS_ERROR, 0, error_message); + &key_added, &exception, &error_message)) { + promise->reject(exception, 0, error_message); return; } @@ -245,7 +247,7 @@ CdmFileAdapter::Status status) { if (status != CdmFileAdapter::Status::kSuccess) { // Unable to open the file, so the state can't be saved. - promise->reject(CdmPromise::INVALID_ACCESS_ERROR, 0, + promise->reject(CdmPromise::Exception::INVALID_STATE_ERROR, 0, "Unable to save session state."); return; } @@ -269,7 +271,7 @@ bool success) { if (!success) { // Unable to save the state. - promise->reject(CdmPromise::INVALID_ACCESS_ERROR, 0, + promise->reject(CdmPromise::Exception::INVALID_STATE_ERROR, 0, "Unable to save session state."); return; }
diff --git a/media/cdm/ppapi/ppapi_cdm_adapter.cc b/media/cdm/ppapi/ppapi_cdm_adapter.cc index f858e20..f7601903 100644 --- a/media/cdm/ppapi/ppapi_cdm_adapter.cc +++ b/media/cdm/ppapi/ppapi_cdm_adapter.cc
@@ -289,7 +289,7 @@ case cdm::Exception::kExceptionInvalidStateError: return PP_CDMEXCEPTIONCODE_INVALIDSTATEERROR; case cdm::Exception::kExceptionTypeError: - return PP_CDMEXCEPTIONCODE_INVALIDACCESSERROR; + return PP_CDMEXCEPTIONCODE_TYPEERROR; case cdm::Exception::kExceptionQuotaExceededError: return PP_CDMEXCEPTIONCODE_QUOTAEXCEEDEDERROR; } @@ -308,6 +308,9 @@ return cdm::Exception::kExceptionTypeError; case cdm::kQuotaExceededError: return cdm::Exception::kExceptionQuotaExceededError; + + // TODO(jrummell): Remove these once CDM_8 is no longer supported. + // https://crbug.com/737296. case cdm::kUnknownError: case cdm::kClientError: case cdm::kOutputError:
diff --git a/media/filters/gpu_video_decoder.cc b/media/filters/gpu_video_decoder.cc index 9f80c99..7002082 100644 --- a/media/filters/gpu_video_decoder.cc +++ b/media/filters/gpu_video_decoder.cc
@@ -33,44 +33,11 @@ #include "media/renderers/gpu_video_accelerator_factories.h" #include "third_party/skia/include/core/SkBitmap.h" -#if BUILDFLAG(USE_PROPRIETARY_CODECS) -#include "media/formats/mp4/box_definitions.h" +#if defined(OS_ANDROID) && BUILDFLAG(USE_PROPRIETARY_CODECS) +#include "media/base/android/extract_sps_and_pps.h" #endif namespace media { -namespace { - -#if defined(OS_ANDROID) && BUILDFLAG(USE_PROPRIETARY_CODECS) -// Extract the SPS and PPS lists from |extra_data|. Each SPS and PPS is prefixed -// with 0x0001, the Annex B framing bytes. The out parameters are not modified -// on failure. -void ExtractSpsAndPps(const std::vector<uint8_t>& extra_data, - std::vector<uint8_t>* sps_out, - std::vector<uint8_t>* pps_out) { - if (extra_data.empty()) - return; - - mp4::AVCDecoderConfigurationRecord record; - if (!record.Parse(extra_data.data(), extra_data.size())) { - DVLOG(1) << "Failed to extract the SPS and PPS from extra_data"; - return; - } - - constexpr std::array<uint8_t, 4> prefix = {{0, 0, 0, 1}}; - for (const std::vector<uint8_t>& sps : record.sps_list) { - sps_out->insert(sps_out->end(), prefix.begin(), prefix.end()); - sps_out->insert(sps_out->end(), sps.begin(), sps.end()); - } - - for (const std::vector<uint8_t>& pps : record.pps_list) { - pps_out->insert(pps_out->end(), prefix.begin(), prefix.end()); - pps_out->insert(pps_out->end(), pps.begin(), pps.end()); - } -} -#endif - -} // namespace - const char GpuVideoDecoder::kDecoderName[] = "GpuVideoDecoder"; // Maximum number of concurrent VDA::Decode() operations GVD will maintain.
diff --git a/media/gpu/android/media_codec_video_decoder.cc b/media/gpu/android/media_codec_video_decoder.cc index 64dfb33..8c38938 100644 --- a/media/gpu/android/media_codec_video_decoder.cc +++ b/media/gpu/android/media_codec_video_decoder.cc
@@ -19,6 +19,10 @@ #include "media/gpu/avda_codec_allocator.h" #include "media/gpu/content_video_view_overlay.h" +#if BUILDFLAG(USE_PROPRIETARY_CODECS) +#include "media/base/android/extract_sps_and_pps.h" +#endif + namespace media { namespace { @@ -166,7 +170,14 @@ } codec_config_->initial_expected_coded_size = config.coded_size(); - // TODO(watk): Parse config.extra_data(). +#if BUILDFLAG(USE_PROPRIETARY_CODECS) + // We pass the SPS and PPS because it makes MediaCodec initialization + // more reliable (http://crbug.com/649185). + if (config.codec() == kCodecH264) { + ExtractSpsAndPps(config.extra_data(), &codec_config_->csd0, + &codec_config_->csd1); + } +#endif // We defer initialization of the Surface and MediaCodec until we // receive a Decode() call to avoid consuming those resources in cases where
diff --git a/media/midi/midi_manager_usb.h b/media/midi/midi_manager_usb.h index 093dfd0..745c96a 100644 --- a/media/midi/midi_manager_usb.h +++ b/media/midi/midi_manager_usb.h
@@ -32,10 +32,9 @@ class MidiService; // MidiManager for USB-MIDI. -class USB_MIDI_EXPORT MidiManagerUsb - : public MidiManager, - public UsbMidiDeviceDelegate, - NON_EXPORTED_BASE(public UsbMidiInputStream::Delegate) { +class USB_MIDI_EXPORT MidiManagerUsb : public MidiManager, + public UsbMidiDeviceDelegate, + public UsbMidiInputStream::Delegate { public: MidiManagerUsb(MidiService* service, std::unique_ptr<UsbMidiDevice::Factory> device_factory);
diff --git a/media/mojo/clients/mojo_cdm.cc b/media/mojo/clients/mojo_cdm.cc index d227b5b..8e7f8ca 100644 --- a/media/mojo/clients/mojo_cdm.cc +++ b/media/mojo/clients/mojo_cdm.cc
@@ -105,7 +105,7 @@ // If connection error has happened, fail immediately. if (remote_cdm_.encountered_error()) { LOG(ERROR) << "Remote CDM encountered error."; - promise->reject(CdmPromise::NOT_SUPPORTED_ERROR, 0, + promise->reject(CdmPromise::Exception::INVALID_STATE_ERROR, 0, "Mojo CDM creation failed."); return; } @@ -132,7 +132,7 @@ // Handle initial connection error. if (pending_init_promise_) { DCHECK(!cdm_session_tracker_.HasRemainingSessions()); - pending_init_promise_->reject(CdmPromise::NOT_SUPPORTED_ERROR, 0, + pending_init_promise_->reject(CdmPromise::Exception::INVALID_STATE_ERROR, 0, "Mojo CDM creation failed."); // Dropping the promise could cause |this| to be destructed. pending_init_promise_.reset(); @@ -151,7 +151,7 @@ DCHECK(thread_checker_.CalledOnValidThread()); if (!remote_cdm_) { - promise->reject(media::CdmPromise::INVALID_STATE_ERROR, 0, + promise->reject(media::CdmPromise::Exception::INVALID_STATE_ERROR, 0, "CDM connection lost."); return; } @@ -168,7 +168,7 @@ DCHECK(thread_checker_.CalledOnValidThread()); if (!remote_cdm_) { - promise->reject(media::CdmPromise::INVALID_STATE_ERROR, 0, + promise->reject(media::CdmPromise::Exception::INVALID_STATE_ERROR, 0, "CDM connection lost."); return; } @@ -188,7 +188,7 @@ DCHECK(thread_checker_.CalledOnValidThread()); if (!remote_cdm_) { - promise->reject(media::CdmPromise::INVALID_STATE_ERROR, 0, + promise->reject(media::CdmPromise::Exception::INVALID_STATE_ERROR, 0, "CDM connection lost."); return; } @@ -207,7 +207,7 @@ DCHECK(thread_checker_.CalledOnValidThread()); if (!remote_cdm_) { - promise->reject(media::CdmPromise::INVALID_STATE_ERROR, 0, + promise->reject(media::CdmPromise::Exception::INVALID_STATE_ERROR, 0, "CDM connection lost."); return; } @@ -225,7 +225,7 @@ DCHECK(thread_checker_.CalledOnValidThread()); if (!remote_cdm_) { - promise->reject(media::CdmPromise::INVALID_STATE_ERROR, 0, + promise->reject(media::CdmPromise::Exception::INVALID_STATE_ERROR, 0, "CDM connection lost."); return; } @@ -242,7 +242,7 @@ DCHECK(thread_checker_.CalledOnValidThread()); if (!remote_cdm_) { - promise->reject(media::CdmPromise::INVALID_STATE_ERROR, 0, + promise->reject(media::CdmPromise::Exception::INVALID_STATE_ERROR, 0, "CDM connection lost."); return; } @@ -259,7 +259,7 @@ DCHECK(thread_checker_.CalledOnValidThread()); if (!remote_cdm_) { - promise->reject(media::CdmPromise::INVALID_STATE_ERROR, 0, + promise->reject(media::CdmPromise::Exception::INVALID_STATE_ERROR, 0, "CDM connection lost."); return; }
diff --git a/media/mojo/clients/mojo_cdm_unittest.cc b/media/mojo/clients/mojo_cdm_unittest.cc index c5352df..d70f8a7f 100644 --- a/media/mojo/clients/mojo_cdm_unittest.cc +++ b/media/mojo/clients/mojo_cdm_unittest.cc
@@ -293,7 +293,7 @@ break; case FAILURE: - promise->reject(media::CdmPromise::UNKNOWN_ERROR, 0, + promise->reject(media::CdmPromise::Exception::NOT_SUPPORTED_ERROR, 0, "Promise rejected"); break; @@ -329,7 +329,7 @@ break; case FAILURE: - promise->reject(media::CdmPromise::UNKNOWN_ERROR, 0, + promise->reject(media::CdmPromise::Exception::NOT_SUPPORTED_ERROR, 0, "Promise rejected"); break;
diff --git a/media/mojo/services/media_interface_provider.h b/media/mojo/services/media_interface_provider.h index 8c2064eb..669bdf94 100644 --- a/media/mojo/services/media_interface_provider.h +++ b/media/mojo/services/media_interface_provider.h
@@ -13,7 +13,7 @@ namespace media { class MEDIA_MOJO_EXPORT MediaInterfaceProvider - : public NON_EXPORTED_BASE(service_manager::mojom::InterfaceProvider) { + : public service_manager::mojom::InterfaceProvider { public: explicit MediaInterfaceProvider( service_manager::mojom::InterfaceProviderRequest request);
diff --git a/media/mojo/services/media_service.h b/media/mojo/services/media_service.h index c667a4e..9625994e 100644 --- a/media/mojo/services/media_service.h +++ b/media/mojo/services/media_service.h
@@ -28,9 +28,8 @@ class MojoMediaClient; -class MEDIA_MOJO_EXPORT MediaService - : public NON_EXPORTED_BASE(service_manager::Service), - public NON_EXPORTED_BASE(mojom::MediaService) { +class MEDIA_MOJO_EXPORT MediaService : public service_manager::Service, + public mojom::MediaService { public: explicit MediaService(std::unique_ptr<MojoMediaClient> mojo_media_client); ~MediaService() final;
diff --git a/media/mojo/services/mojo_audio_decoder_service.h b/media/mojo/services/mojo_audio_decoder_service.h index 37b27957..a095993 100644 --- a/media/mojo/services/mojo_audio_decoder_service.h +++ b/media/mojo/services/mojo_audio_decoder_service.h
@@ -21,8 +21,7 @@ class MojoCdmServiceContext; class MojoDecoderBufferReader; -class MEDIA_MOJO_EXPORT MojoAudioDecoderService - : NON_EXPORTED_BASE(public mojom::AudioDecoder) { +class MEDIA_MOJO_EXPORT MojoAudioDecoderService : public mojom::AudioDecoder { public: MojoAudioDecoderService( base::WeakPtr<MojoCdmServiceContext> mojo_cdm_service_context,
diff --git a/media/mojo/services/mojo_audio_output_stream.h b/media/mojo/services/mojo_audio_output_stream.h index a62ccea..f5f9970 100644 --- a/media/mojo/services/mojo_audio_output_stream.h +++ b/media/mojo/services/mojo_audio_output_stream.h
@@ -19,8 +19,8 @@ // This class handles IPC for single audio output stream by delegating method // calls to its AudioOutputDelegate. class MEDIA_MOJO_EXPORT MojoAudioOutputStream - : NON_EXPORTED_BASE(public mojom::AudioOutputStream), - NON_EXPORTED_BASE(public AudioOutputDelegate::EventHandler) { + : public mojom::AudioOutputStream, + public AudioOutputDelegate::EventHandler { public: using StreamCreatedCallback = mojom::AudioOutputStreamProvider::AcquireCallback;
diff --git a/media/mojo/services/mojo_audio_output_stream_provider.h b/media/mojo/services/mojo_audio_output_stream_provider.h index 2d014d6..c67a895a9 100644 --- a/media/mojo/services/mojo_audio_output_stream_provider.h +++ b/media/mojo/services/mojo_audio_output_stream_provider.h
@@ -19,7 +19,7 @@ // Provides a single AudioOutput, given the audio parameters to use. class MEDIA_MOJO_EXPORT MojoAudioOutputStreamProvider - : NON_EXPORTED_BASE(public mojom::AudioOutputStreamProvider) { + : public mojom::AudioOutputStreamProvider { public: using CreateDelegateCallback = base::OnceCallback<std::unique_ptr<AudioOutputDelegate>(
diff --git a/media/mojo/services/mojo_audio_output_stream_unittest.cc b/media/mojo/services/mojo_audio_output_stream_unittest.cc index 40a59a4..66b55178 100644 --- a/media/mojo/services/mojo_audio_output_stream_unittest.cc +++ b/media/mojo/services/mojo_audio_output_stream_unittest.cc
@@ -54,7 +54,7 @@ DISALLOW_COPY_AND_ASSIGN(TestCancelableSyncSocket); }; -class MockDelegate : NON_EXPORTED_BASE(public AudioOutputDelegate) { +class MockDelegate : public AudioOutputDelegate { public: MockDelegate() {} ~MockDelegate() {}
diff --git a/media/mojo/services/mojo_cdm_service.h b/media/mojo/services/mojo_cdm_service.h index 0434ddf..a9acf3d 100644 --- a/media/mojo/services/mojo_cdm_service.h +++ b/media/mojo/services/mojo_cdm_service.h
@@ -28,8 +28,7 @@ // A mojom::ContentDecryptionModule implementation backed by a // media::ContentDecryptionModule. -class MEDIA_MOJO_EXPORT MojoCdmService - : NON_EXPORTED_BASE(public mojom::ContentDecryptionModule) { +class MEDIA_MOJO_EXPORT MojoCdmService : public mojom::ContentDecryptionModule { public: // Get the CDM associated with |cdm_id|, which is unique per process. // Can be called on any thread. The returned CDM is not guaranteed to be
diff --git a/media/mojo/services/mojo_decryptor_service.h b/media/mojo/services/mojo_decryptor_service.h index be49029..691f03e 100644 --- a/media/mojo/services/mojo_decryptor_service.h +++ b/media/mojo/services/mojo_decryptor_service.h
@@ -26,8 +26,7 @@ // A mojom::Decryptor implementation. This object is owned by the creator, // and uses a weak binding across the mojo interface. -class MEDIA_MOJO_EXPORT MojoDecryptorService - : NON_EXPORTED_BASE(public mojom::Decryptor) { +class MEDIA_MOJO_EXPORT MojoDecryptorService : public mojom::Decryptor { public: using StreamType = media::Decryptor::StreamType; using Status = media::Decryptor::Status;
diff --git a/media/mojo/services/mojo_media_drm_storage.h b/media/mojo/services/mojo_media_drm_storage.h index 84e53bd..4446b9b 100644 --- a/media/mojo/services/mojo_media_drm_storage.h +++ b/media/mojo/services/mojo_media_drm_storage.h
@@ -17,8 +17,7 @@ namespace media { // A MediaDrmStorage that proxies to a mojom::MediaDrmStoragePtr. -class MEDIA_MOJO_EXPORT MojoMediaDrmStorage - : NON_EXPORTED_BASE(public MediaDrmStorage) { +class MEDIA_MOJO_EXPORT MojoMediaDrmStorage : public MediaDrmStorage { public: explicit MojoMediaDrmStorage(mojom::MediaDrmStoragePtr media_drm_storage_ptr); ~MojoMediaDrmStorage() final;
diff --git a/media/mojo/services/mojo_provision_fetcher.h b/media/mojo/services/mojo_provision_fetcher.h index 2e2f832..907f7a37 100644 --- a/media/mojo/services/mojo_provision_fetcher.h +++ b/media/mojo/services/mojo_provision_fetcher.h
@@ -15,8 +15,7 @@ namespace media { // A ProvisionFetcher that proxies to a mojom::ProvisionFetcherPtr. -class MEDIA_MOJO_EXPORT MojoProvisionFetcher - : NON_EXPORTED_BASE(public ProvisionFetcher) { +class MEDIA_MOJO_EXPORT MojoProvisionFetcher : public ProvisionFetcher { public: explicit MojoProvisionFetcher( mojom::ProvisionFetcherPtr provision_fetcher_ptr);
diff --git a/media/mojo/services/mojo_renderer_service.h b/media/mojo/services/mojo_renderer_service.h index de32abf..ad1cc79 100644 --- a/media/mojo/services/mojo_renderer_service.h +++ b/media/mojo/services/mojo_renderer_service.h
@@ -34,9 +34,8 @@ // A mojom::Renderer implementation that use a media::Renderer to render // media streams. -class MEDIA_MOJO_EXPORT MojoRendererService - : NON_EXPORTED_BASE(public mojom::Renderer), - public RendererClient { +class MEDIA_MOJO_EXPORT MojoRendererService : public mojom::Renderer, + public RendererClient { public: using InitiateSurfaceRequestCB = base::Callback<base::UnguessableToken()>;
diff --git a/media/mojo/services/mojo_video_encode_accelerator_provider.h b/media/mojo/services/mojo_video_encode_accelerator_provider.h index f5a1cac..ee9c65b8 100644 --- a/media/mojo/services/mojo_video_encode_accelerator_provider.h +++ b/media/mojo/services/mojo_video_encode_accelerator_provider.h
@@ -20,7 +20,7 @@ // This class implements the interface mojom::VideoEncodeAcceleratorProvider, // holds on to the necessary objects to create mojom::VideoEncodeAccelerators. class MEDIA_MOJO_EXPORT MojoVideoEncodeAcceleratorProvider - : public NON_EXPORTED_BASE(mojom::VideoEncodeAcceleratorProvider) { + : public mojom::VideoEncodeAcceleratorProvider { public: using CreateAndInitializeVideoEncodeAcceleratorCallback = MojoVideoEncodeAcceleratorService::
diff --git a/media/mojo/services/mojo_video_encode_accelerator_service.h b/media/mojo/services/mojo_video_encode_accelerator_service.h index c4ed933..8c6991f7 100644 --- a/media/mojo/services/mojo_video_encode_accelerator_service.h +++ b/media/mojo/services/mojo_video_encode_accelerator_service.h
@@ -27,7 +27,7 @@ // This class implements the interface mojom::VideoEncodeAccelerator. class MEDIA_MOJO_EXPORT MojoVideoEncodeAcceleratorService - : public NON_EXPORTED_BASE(mojom::VideoEncodeAccelerator), + : public mojom::VideoEncodeAccelerator, public VideoEncodeAccelerator::Client { public: // Create and initialize a VEA. Returns nullptr if either part fails.
diff --git a/media/mojo/services/watch_time_recorder.h b/media/mojo/services/watch_time_recorder.h index ed3931dc..b11481e 100644 --- a/media/mojo/services/watch_time_recorder.h +++ b/media/mojo/services/watch_time_recorder.h
@@ -20,8 +20,7 @@ namespace media { // See mojom::WatchTimeRecorder for documentation. -class MEDIA_MOJO_EXPORT WatchTimeRecorder - : NON_EXPORTED_BASE(public mojom::WatchTimeRecorder) { +class MEDIA_MOJO_EXPORT WatchTimeRecorder : public mojom::WatchTimeRecorder { public: explicit WatchTimeRecorder(mojom::PlaybackPropertiesPtr properties); ~WatchTimeRecorder() override;
diff --git a/media/muxers/webm_muxer.h b/media/muxers/webm_muxer.h index 7066890..d5b175d 100644 --- a/media/muxers/webm_muxer.h +++ b/media/muxers/webm_muxer.h
@@ -42,7 +42,7 @@ // WebmMuxer is designed for use on a single thread. // [1] http://www.webmproject.org/docs/container/ // [2] http://www.matroska.org/technical/specs/index.html -class MEDIA_EXPORT WebmMuxer : public NON_EXPORTED_BASE(mkvmuxer::IMkvWriter) { +class MEDIA_EXPORT WebmMuxer : public mkvmuxer::IMkvWriter { public: // Callback to be called when WebmMuxer is ready to write a chunk of data, // either any file header or a SingleBlock.
diff --git a/media/remoting/proto_enum_utils.cc b/media/remoting/proto_enum_utils.cc index 95b3749b..eaea1a2 100644 --- a/media/remoting/proto_enum_utils.cc +++ b/media/remoting/proto_enum_utils.cc
@@ -470,31 +470,33 @@ base::Optional<CdmPromise::Exception> ToCdmPromiseException( pb::CdmException value) { using OriginType = pb::CdmException; - using OtherType = CdmPromise; + using OtherType = CdmPromise::Exception; switch (value) { CASE_RETURN_OTHER(NOT_SUPPORTED_ERROR); CASE_RETURN_OTHER(INVALID_STATE_ERROR); - CASE_RETURN_OTHER(INVALID_ACCESS_ERROR); CASE_RETURN_OTHER(QUOTA_EXCEEDED_ERROR); - CASE_RETURN_OTHER(UNKNOWN_ERROR); - CASE_RETURN_OTHER(CLIENT_ERROR); - CASE_RETURN_OTHER(OUTPUT_ERROR); + CASE_RETURN_OTHER(TYPE_ERROR); + + // The following were generated with previous versions of the CDM and are + // no longer used by CdmPromise. + case OriginType::INVALID_ACCESS_ERROR: + case OriginType::UNKNOWN_ERROR: + case OriginType::CLIENT_ERROR: + case OriginType::OUTPUT_ERROR: + return OtherType::NOT_SUPPORTED_ERROR; } return base::nullopt; // Not a 'default' to ensure compile-time checks. } base::Optional<pb::CdmException> ToProtoCdmException( CdmPromise::Exception value) { - using OriginType = CdmPromise; + using OriginType = CdmPromise::Exception; using OtherType = pb::CdmException; switch (value) { CASE_RETURN_OTHER(NOT_SUPPORTED_ERROR); CASE_RETURN_OTHER(INVALID_STATE_ERROR); - CASE_RETURN_OTHER(INVALID_ACCESS_ERROR); CASE_RETURN_OTHER(QUOTA_EXCEEDED_ERROR); - CASE_RETURN_OTHER(UNKNOWN_ERROR); - CASE_RETURN_OTHER(CLIENT_ERROR); - CASE_RETURN_OTHER(OUTPUT_ERROR); + CASE_RETURN_OTHER(TYPE_ERROR); } return base::nullopt; // Not a 'default' to ensure compile-time checks. }
diff --git a/media/remoting/proto_utils.cc b/media/remoting/proto_utils.cc index 3920163..426fa69 100644 --- a/media/remoting/proto_utils.cc +++ b/media/remoting/proto_utils.cc
@@ -420,7 +420,7 @@ return true; } - CdmPromise::Exception exception = CdmPromise::UNKNOWN_ERROR; + CdmPromise::Exception exception = CdmPromise::Exception::NOT_SUPPORTED_ERROR; uint32_t system_code = 0; std::string error_message; @@ -452,7 +452,7 @@ //============================================================================== CdmPromiseResult::CdmPromiseResult() - : CdmPromiseResult(CdmPromise::UNKNOWN_ERROR, 0, "") {} + : CdmPromiseResult(CdmPromise::Exception::NOT_SUPPORTED_ERROR, 0, "") {} CdmPromiseResult::CdmPromiseResult(CdmPromise::Exception exception, uint32_t system_code,
diff --git a/media/remoting/rpc.proto b/media/remoting/rpc.proto index baceb6a..7d21923 100644 --- a/media/remoting/rpc.proto +++ b/media/remoting/rpc.proto
@@ -280,11 +280,12 @@ enum CdmException { NOT_SUPPORTED_ERROR = 0; INVALID_STATE_ERROR = 1; - INVALID_ACCESS_ERROR = 2; + INVALID_ACCESS_ERROR = 2 [deprecated = true]; QUOTA_EXCEEDED_ERROR = 3; - UNKNOWN_ERROR = 4; - CLIENT_ERROR = 5; - OUTPUT_ERROR = 6; + UNKNOWN_ERROR = 4 [deprecated = true]; + CLIENT_ERROR = 5 [deprecated = true]; + OUTPUT_ERROR = 6 [deprecated = true]; + TYPE_ERROR = 7; } // Proto version of media::CdmMessageType.
diff --git a/media/renderers/audio_renderer_impl.h b/media/renderers/audio_renderer_impl.h index 9a3b992..dd3f03f 100644 --- a/media/renderers/audio_renderer_impl.h +++ b/media/renderers/audio_renderer_impl.h
@@ -54,7 +54,7 @@ : public AudioRenderer, public TimeSource, public base::PowerObserver, - NON_EXPORTED_BASE(public AudioRendererSink::RenderCallback) { + public AudioRendererSink::RenderCallback { public: // |task_runner| is the thread on which AudioRendererImpl will execute. //
diff --git a/media/renderers/video_renderer_impl.h b/media/renderers/video_renderer_impl.h index 0cf59f82..3b7da08c 100644 --- a/media/renderers/video_renderer_impl.h +++ b/media/renderers/video_renderer_impl.h
@@ -44,7 +44,7 @@ // ready for rendering. class MEDIA_EXPORT VideoRendererImpl : public VideoRenderer, - public NON_EXPORTED_BASE(VideoRendererSink::RenderCallback) { + public VideoRendererSink::RenderCallback { public: // |decoders| contains the VideoDecoders to use when initializing. //
diff --git a/media/video/gpu_memory_buffer_video_frame_pool.cc b/media/video/gpu_memory_buffer_video_frame_pool.cc index 9d7b0ac..64a5669 100644 --- a/media/video/gpu_memory_buffer_video_frame_pool.cc +++ b/media/video/gpu_memory_buffer_video_frame_pool.cc
@@ -499,15 +499,15 @@ dump->AddScalar("free_size", base::trace_event::MemoryAllocatorDump::kUnitsBytes, frame_resources->is_used() ? 0 : buffer_size_in_bytes); - auto shared_buffer_guid = - plane_resource.gpu_memory_buffer->GetGUIDForTracing( - tracing_process_id); auto shared_memory_guid = plane_resource.gpu_memory_buffer->GetHandle().handle.GetGUID(); if (!shared_memory_guid.is_empty()) { - pmd->CreateSharedMemoryOwnershipEdge(dump->guid(), shared_buffer_guid, - shared_memory_guid, kImportance); + pmd->CreateSharedMemoryOwnershipEdge(dump->guid(), shared_memory_guid, + kImportance); } else { + auto shared_buffer_guid = + plane_resource.gpu_memory_buffer->GetGUIDForTracing( + tracing_process_id); pmd->CreateSharedGlobalAllocatorDump(shared_buffer_guid); pmd->AddOwnershipEdge(dump->guid(), shared_buffer_guid, kImportance); }
diff --git a/mojo/edk/system/user_message_impl.h b/mojo/edk/system/user_message_impl.h index cb92a03e..b708f44 100644 --- a/mojo/edk/system/user_message_impl.h +++ b/mojo/edk/system/user_message_impl.h
@@ -32,8 +32,7 @@ // A UserMessageImpl may be either serialized or unserialized. Unserialized // instances are serialized lazily only when necessary, i.e., if and when // Serialize() is called to obtain a serialized message for wire transfer. -class MOJO_SYSTEM_IMPL_EXPORT UserMessageImpl - : public NON_EXPORTED_BASE(ports::UserMessage) { +class MOJO_SYSTEM_IMPL_EXPORT UserMessageImpl : public ports::UserMessage { public: static const TypeInfo kUserMessageTypeInfo;
diff --git a/mojo/public/cpp/bindings/connector.h b/mojo/public/cpp/bindings/connector.h index 4531843..b08985b 100644 --- a/mojo/public/cpp/bindings/connector.h +++ b/mojo/public/cpp/bindings/connector.h
@@ -38,8 +38,7 @@ // - Sending messages can be configured to be thread safe (please see comments // of the constructor). Other than that, the object should only be accessed // on the creating sequence. -class MOJO_CPP_BINDINGS_EXPORT Connector - : NON_EXPORTED_BASE(public MessageReceiver) { +class MOJO_CPP_BINDINGS_EXPORT Connector : public MessageReceiver { public: enum ConnectorConfig { // Connector::Accept() is only called from a single sequence.
diff --git a/mojo/public/cpp/bindings/filter_chain.h b/mojo/public/cpp/bindings/filter_chain.h index 1262f39b8..b678f65 100644 --- a/mojo/public/cpp/bindings/filter_chain.h +++ b/mojo/public/cpp/bindings/filter_chain.h
@@ -16,8 +16,7 @@ namespace mojo { -class MOJO_CPP_BINDINGS_EXPORT FilterChain - : NON_EXPORTED_BASE(public MessageReceiver) { +class MOJO_CPP_BINDINGS_EXPORT FilterChain : public MessageReceiver { public: // Doesn't take ownership of |sink|. Therefore |sink| has to stay alive while // this object is alive.
diff --git a/mojo/public/cpp/bindings/interface_endpoint_client.h b/mojo/public/cpp/bindings/interface_endpoint_client.h index 891039d..6842c7c 100644 --- a/mojo/public/cpp/bindings/interface_endpoint_client.h +++ b/mojo/public/cpp/bindings/interface_endpoint_client.h
@@ -38,7 +38,7 @@ // endpoint, either the implementation side or the client side. // It should only be accessed and destructed on the creating sequence. class MOJO_CPP_BINDINGS_EXPORT InterfaceEndpointClient - : NON_EXPORTED_BASE(public MessageReceiverWithResponder) { + : public MessageReceiverWithResponder { public: // |receiver| is okay to be null. If it is not null, it must outlive this // object.
diff --git a/mojo/public/cpp/bindings/lib/control_message_handler.h b/mojo/public/cpp/bindings/lib/control_message_handler.h index 5d1f716..daa884b 100644 --- a/mojo/public/cpp/bindings/lib/control_message_handler.h +++ b/mojo/public/cpp/bindings/lib/control_message_handler.h
@@ -18,7 +18,7 @@ // Handlers for request messages defined in interface_control_messages.mojom. class MOJO_CPP_BINDINGS_EXPORT ControlMessageHandler - : NON_EXPORTED_BASE(public MessageReceiverWithResponderStatus) { + : public MessageReceiverWithResponderStatus { public: static bool IsControlMessage(const Message* message);
diff --git a/mojo/public/cpp/bindings/lib/multiplex_router.h b/mojo/public/cpp/bindings/lib/multiplex_router.h index bf21aabf..10950b3 100644 --- a/mojo/public/cpp/bindings/lib/multiplex_router.h +++ b/mojo/public/cpp/bindings/lib/multiplex_router.h
@@ -53,9 +53,9 @@ // NOTE: CloseMessagePipe() or PassMessagePipe() MUST be called on |runner|'s // sequence before this object is destroyed. class MOJO_CPP_BINDINGS_EXPORT MultiplexRouter - : NON_EXPORTED_BASE(public MessageReceiver), + : public MessageReceiver, public AssociatedGroupController, - NON_EXPORTED_BASE(public PipeControlMessageHandlerDelegate) { + public PipeControlMessageHandlerDelegate { public: enum Config { // There is only the master interface running on this router. Please note
diff --git a/mojo/public/cpp/bindings/message.h b/mojo/public/cpp/bindings/message.h index 64439e1..4ddc50c 100644 --- a/mojo/public/cpp/bindings/message.h +++ b/mojo/public/cpp/bindings/message.h
@@ -290,8 +290,7 @@ responder) WARN_UNUSED_RESULT = 0; }; -class MOJO_CPP_BINDINGS_EXPORT PassThroughFilter - : NON_EXPORTED_BASE(public MessageReceiver) { +class MOJO_CPP_BINDINGS_EXPORT PassThroughFilter : public MessageReceiver { public: PassThroughFilter(); ~PassThroughFilter() override;
diff --git a/mojo/public/cpp/bindings/message_header_validator.h b/mojo/public/cpp/bindings/message_header_validator.h index 50c19dbe..d99264c 100644 --- a/mojo/public/cpp/bindings/message_header_validator.h +++ b/mojo/public/cpp/bindings/message_header_validator.h
@@ -11,8 +11,7 @@ namespace mojo { -class MOJO_CPP_BINDINGS_EXPORT MessageHeaderValidator - : NON_EXPORTED_BASE(public MessageReceiver) { +class MOJO_CPP_BINDINGS_EXPORT MessageHeaderValidator : public MessageReceiver { public: MessageHeaderValidator(); explicit MessageHeaderValidator(const std::string& description);
diff --git a/mojo/public/cpp/bindings/pipe_control_message_handler.h b/mojo/public/cpp/bindings/pipe_control_message_handler.h index a5c04da..071d9fe4 100644 --- a/mojo/public/cpp/bindings/pipe_control_message_handler.h +++ b/mojo/public/cpp/bindings/pipe_control_message_handler.h
@@ -18,7 +18,7 @@ // Handler for messages defined in pipe_control_messages.mojom. class MOJO_CPP_BINDINGS_EXPORT PipeControlMessageHandler - : NON_EXPORTED_BASE(public MessageReceiver) { + : public MessageReceiver { public: explicit PipeControlMessageHandler( PipeControlMessageHandlerDelegate* delegate);
diff --git a/mojo/public/cpp/system/buffer.h b/mojo/public/cpp/system/buffer.h index 1ae923c..0664902 100644 --- a/mojo/public/cpp/system/buffer.h +++ b/mojo/public/cpp/system/buffer.h
@@ -42,8 +42,7 @@ // A strongly-typed representation of a |MojoHandle| referring to a shared // buffer. -class MOJO_CPP_SYSTEM_EXPORT SharedBufferHandle - : NON_EXPORTED_BASE(public Handle) { +class MOJO_CPP_SYSTEM_EXPORT SharedBufferHandle : public Handle { public: enum class AccessMode { READ_WRITE,
diff --git a/mojo/public/tools/bindings/chromium_bindings_configuration.gni b/mojo/public/tools/bindings/chromium_bindings_configuration.gni index ad7f1b3..7072eaa7 100644 --- a/mojo/public/tools/bindings/chromium_bindings_configuration.gni +++ b/mojo/public/tools/bindings/chromium_bindings_configuration.gni
@@ -52,8 +52,7 @@ _typemap_imports_mac = [ "//content/common/typemaps_mac.gni" ] -_typemap_imports_chromeos = - [ "//ui/display/manager/chromeos/mojo/typemaps.gni" ] +_typemap_imports_chromeos = [] _typemaps = [] foreach(typemap_import, _typemap_imports) {
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/interface_request_validator_declaration.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/interface_request_validator_declaration.tmpl index a00d1488..6440519b 100644 --- a/mojo/public/tools/bindings/generators/cpp_templates/interface_request_validator_declaration.tmpl +++ b/mojo/public/tools/bindings/generators/cpp_templates/interface_request_validator_declaration.tmpl
@@ -1,4 +1,4 @@ -class {{export_attribute}} {{interface.name}}RequestValidator : public NON_EXPORTED_BASE(mojo::MessageReceiver) { +class {{export_attribute}} {{interface.name}}RequestValidator : public mojo::MessageReceiver { public: bool Accept(mojo::Message* message) override; };
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/interface_response_validator_declaration.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/interface_response_validator_declaration.tmpl index e2caa02c..759726d 100644 --- a/mojo/public/tools/bindings/generators/cpp_templates/interface_response_validator_declaration.tmpl +++ b/mojo/public/tools/bindings/generators/cpp_templates/interface_response_validator_declaration.tmpl
@@ -1,4 +1,4 @@ -class {{export_attribute}} {{interface.name}}ResponseValidator : public NON_EXPORTED_BASE(mojo::MessageReceiver) { +class {{export_attribute}} {{interface.name}}ResponseValidator : public mojo::MessageReceiver { public: bool Accept(mojo::Message* message) override; };
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl index 79ab46f..7253c0a 100644 --- a/mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl +++ b/mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl
@@ -10,7 +10,7 @@ template <typename ImplRefTraits = mojo::RawPtrImplRefTraits<{{interface.name}}>> class {{interface.name}}Stub - : public NON_EXPORTED_BASE(mojo::MessageReceiverWithResponderStatus) { + : public mojo::MessageReceiverWithResponderStatus { public: using ImplPointerType = typename ImplRefTraits::PointerType;
diff --git a/net/base/network_throttle_manager_impl.cc b/net/base/network_throttle_manager_impl.cc index 4ca235a..3448fcd 100644 --- a/net/base/network_throttle_manager_impl.cc +++ b/net/base/network_throttle_manager_impl.cc
@@ -153,13 +153,11 @@ NetworkThrottleManagerImpl::NetworkThrottleManagerImpl() : lifetime_median_estimate_(PercentileEstimator::kMedianPercentile, kInitialMedianInMs), - outstanding_recomputation_timer_(false /* retain_user_task */, - false /* is_repeating */), + outstanding_recomputation_timer_( + base::MakeUnique<base::Timer>(false /* retain_user_task */, + false /* is_repeating */)), tick_clock_(new base::DefaultTickClock()), - weak_ptr_factory_(this) { - outstanding_recomputation_timer_.SetTaskRunner( - base::ThreadTaskRunnerHandle::Get()); -} + weak_ptr_factory_(this) {} NetworkThrottleManagerImpl::~NetworkThrottleManagerImpl() {} @@ -192,17 +190,21 @@ void NetworkThrottleManagerImpl::SetTickClockForTesting( std::unique_ptr<base::TickClock> tick_clock) { tick_clock_ = std::move(tick_clock); + DCHECK(!outstanding_recomputation_timer_->IsRunning()); + outstanding_recomputation_timer_ = base::MakeUnique<base::Timer>( + false /* retain_user_task */, false /* is_repeating */, + tick_clock_.get()); } bool NetworkThrottleManagerImpl::ConditionallyTriggerTimerForTesting() { - if (!outstanding_recomputation_timer_.IsRunning() || + if (!outstanding_recomputation_timer_->IsRunning() || (tick_clock_->NowTicks() < - outstanding_recomputation_timer_.desired_run_time())) { + outstanding_recomputation_timer_->desired_run_time())) { return false; } - base::Closure timer_callback(outstanding_recomputation_timer_.user_task()); - outstanding_recomputation_timer_.Stop(); + base::Closure timer_callback(outstanding_recomputation_timer_->user_task()); + outstanding_recomputation_timer_->Stop(); timer_callback.Run(); return true; } @@ -278,14 +280,16 @@ // currently set. // This addresses, e.g., situations where a RecomputeOutstanding() races // with a running timer which would unblock blocked throttles. - if (outstanding_recomputation_timer_.IsRunning()) + if (outstanding_recomputation_timer_->IsRunning()) return; ThrottleImpl* first_throttle(*outstanding_throttles_.begin()); DCHECK_GE(first_throttle->start_time() + age_horizon, now); - outstanding_recomputation_timer_.Start( - FROM_HERE, ((first_throttle->start_time() + age_horizon) - now + - base::TimeDelta::FromMilliseconds(kTimerFudgeInMs)), + + outstanding_recomputation_timer_->Start( + FROM_HERE, + ((first_throttle->start_time() + age_horizon) - now + + base::TimeDelta::FromMilliseconds(kTimerFudgeInMs)), // Unretained use of |this| is safe because the timer is // owned by this object, and will be torn down if this object // is destroyed.
diff --git a/net/base/network_throttle_manager_impl.h b/net/base/network_throttle_manager_impl.h index 47afcc46f..a388032d 100644 --- a/net/base/network_throttle_manager_impl.h +++ b/net/base/network_throttle_manager_impl.h
@@ -129,7 +129,7 @@ // throttles are outstanding. This guarantees that the class will // eventually detect aging out of outstanding throttles and unblock // throttles blocked on those outstanding throttles. - base::Timer outstanding_recomputation_timer_; + std::unique_ptr<base::Timer> outstanding_recomputation_timer_; // FIFO of OUTSTANDING throttles (ordered by time of entry into the // OUTSTANDING state).
diff --git a/net/dns/dns_session.h b/net/dns/dns_session.h index a97132ee..7b9b26f8 100644 --- a/net/dns/dns_session.h +++ b/net/dns/dns_session.h
@@ -36,7 +36,7 @@ // Ref-counted so that DnsClient::Request can keep working in absence of // DnsClient. A DnsSession must be recreated when DnsConfig changes. class NET_EXPORT_PRIVATE DnsSession - : NON_EXPORTED_BASE(public base::RefCounted<DnsSession>), + : public base::RefCounted<DnsSession>, public NetworkChangeNotifier::ConnectionTypeObserver { public: typedef base::Callback<int()> RandCallback;
diff --git a/net/dns/serial_worker.h b/net/dns/serial_worker.h index 14398a8e..d06598c 100644 --- a/net/dns/serial_worker.h +++ b/net/dns/serial_worker.h
@@ -38,7 +38,7 @@ // // TODO(szym): update to WorkerPool::PostTaskAndReply once available. class NET_EXPORT_PRIVATE SerialWorker - : NON_EXPORTED_BASE(public base::RefCountedThreadSafe<SerialWorker>) { + : public base::RefCountedThreadSafe<SerialWorker> { public: SerialWorker();
diff --git a/net/http/bidirectional_stream.h b/net/http/bidirectional_stream.h index 043ce80b..e25dce0 100644 --- a/net/http/bidirectional_stream.h +++ b/net/http/bidirectional_stream.h
@@ -38,9 +38,8 @@ // ReadData or SendData/SendvData should be in flight until the operation // completes. The BidirectionalStream must be torn down before the // HttpNetworkSession. -class NET_EXPORT BidirectionalStream - : public NON_EXPORTED_BASE(BidirectionalStreamImpl::Delegate), - public NON_EXPORTED_BASE(HttpStreamRequest::Delegate) { +class NET_EXPORT BidirectionalStream : public BidirectionalStreamImpl::Delegate, + public HttpStreamRequest::Delegate { public: // Delegate interface to get notified of success of failure. Callbacks will be // invoked asynchronously.
diff --git a/net/http/http_stream_factory_impl_job.cc b/net/http/http_stream_factory_impl_job.cc index 68a186d..d8c2f087 100644 --- a/net/http/http_stream_factory_impl_job.cc +++ b/net/http/http_stream_factory_impl_job.cc
@@ -826,9 +826,8 @@ void HttpStreamFactoryImpl::Job::ResumeInitConnection() { if (init_connection_already_resumed_) return; + DCHECK_EQ(next_state_, STATE_INIT_CONNECTION); net_log_.AddEvent(NetLogEventType::HTTP_STREAM_JOB_RESUME_INIT_CONNECTION); - // TODO(xunjieli): Change this to a DCHECK once crbug.com/718576 is stable. - CHECK_EQ(next_state_, STATE_INIT_CONNECTION); init_connection_already_resumed_ = true; OnIOComplete(OK); }
diff --git a/net/http/http_stream_factory_impl_job_controller.cc b/net/http/http_stream_factory_impl_job_controller.cc index 5660ab3..1dac727 100644 --- a/net/http/http_stream_factory_impl_job_controller.cc +++ b/net/http/http_stream_factory_impl_job_controller.cc
@@ -657,8 +657,7 @@ void HttpStreamFactoryImpl::JobController:: RemoveRequestFromSpdySessionRequestMap() { - // TODO(xunjieli): Use a DCHECK once https://crbug.com/718576 is fixed. - CHECK(request_); + DCHECK(request_); session_->spdy_session_pool()->RemoveRequestFromSpdySessionRequestMap( request_); }
diff --git a/net/quic/chromium/quic_chromium_client_session.cc b/net/quic/chromium/quic_chromium_client_session.cc index 89c1547..957745b 100644 --- a/net/quic/chromium/quic_chromium_client_session.cc +++ b/net/quic/chromium/quic_chromium_client_session.cc
@@ -755,11 +755,6 @@ static_cast<base::HistogramBase::Sample>(stats.max_sequence_reordering)); } -std::unique_ptr<QuicStream> QuicChromiumClientSession::CreateStream( - QuicStreamId id) { - return QuicMakeUnique<QuicChromiumClientStream>(id, this, net_log_); -} - void QuicChromiumClientSession::Initialize() { QuicSpdyClientSessionBase::Initialize(); SetHpackEncoderDebugVisitor(
diff --git a/net/quic/chromium/quic_chromium_client_session.h b/net/quic/chromium/quic_chromium_client_session.h index 6247e88..3485561 100644 --- a/net/quic/chromium/quic_chromium_client_session.h +++ b/net/quic/chromium/quic_chromium_client_session.h
@@ -297,8 +297,6 @@ NetLog* net_log); ~QuicChromiumClientSession() override; - std::unique_ptr<QuicStream> CreateStream(QuicStreamId id) override; - void Initialize() override; void AddHandle(Handle* handle);
diff --git a/net/quic/chromium/quic_connection_logger.cc b/net/quic/chromium/quic_connection_logger.cc index 5a09f21..38990ae7 100644 --- a/net/quic/chromium/quic_connection_logger.cc +++ b/net/quic/chromium/quic_connection_logger.cc
@@ -563,7 +563,8 @@ } void QuicConnectionLogger::OnWindowUpdateFrame( - const QuicWindowUpdateFrame& frame) { + const QuicWindowUpdateFrame& frame, + const QuicTime& receive_time) { net_log_.AddEvent(NetLogEventType::QUIC_SESSION_WINDOW_UPDATE_FRAME_RECEIVED, base::Bind(&NetLogQuicWindowUpdateFrameCallback, &frame)); }
diff --git a/net/quic/chromium/quic_connection_logger.h b/net/quic/chromium/quic_connection_logger.h index 3b18d25..204a50e 100644 --- a/net/quic/chromium/quic_connection_logger.h +++ b/net/quic/chromium/quic_connection_logger.h
@@ -64,7 +64,8 @@ void OnStopWaitingFrame(const QuicStopWaitingFrame& frame) override; void OnRstStreamFrame(const QuicRstStreamFrame& frame) override; void OnConnectionCloseFrame(const QuicConnectionCloseFrame& frame) override; - void OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) override; + void OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame, + const QuicTime& receive_time) override; void OnBlockedFrame(const QuicBlockedFrame& frame) override; void OnGoAwayFrame(const QuicGoAwayFrame& frame) override; void OnPingFrame(const QuicPingFrame& frame) override;
diff --git a/net/quic/core/congestion_control/tcp_cubic_sender_base.cc b/net/quic/core/congestion_control/tcp_cubic_sender_base.cc index d83062b..337f1aa 100644 --- a/net/quic/core/congestion_control/tcp_cubic_sender_base.cc +++ b/net/quic/core/congestion_control/tcp_cubic_sender_base.cc
@@ -21,7 +21,6 @@ const QuicByteCount kMaxBurstBytes = 3 * kDefaultTCPMSS; const float kRenoBeta = 0.7f; // Reno backoff factor. const uint32_t kDefaultNumConnections = 2; // N-connection emulation. -const float kRateBasedExtraCwnd = 1.5f; // CWND for rate based sending. } // namespace TcpCubicSenderBase::TcpCubicSenderBase(const QuicClock* clock, @@ -38,7 +37,6 @@ min4_mode_(false), last_cutback_exited_slowstart_(false), slow_start_large_reduction_(false), - rate_based_sending_(false), no_prr_(false) {} TcpCubicSenderBase::~TcpCubicSenderBase() {} @@ -87,11 +85,6 @@ // Use unity pacing instead of PRR. no_prr_ = true; } - if (config.HasReceivedConnectionOptions() && - ContainsQuicTag(config.ReceivedConnectionOptions(), kRATE)) { - // Rate based sending experiment - rate_based_sending_ = true; - } } } @@ -196,15 +189,11 @@ if (min4_mode_ && bytes_in_flight < 4 * kDefaultTCPMSS) { return QuicTime::Delta::Zero(); } - if (rate_based_sending_ && - GetCongestionWindow() * kRateBasedExtraCwnd > bytes_in_flight) { - return QuicTime::Delta::Zero(); - } return QuicTime::Delta::Infinite(); } QuicBandwidth TcpCubicSenderBase::PacingRate( - QuicByteCount bytes_in_flight) const { + QuicByteCount /* bytes_in_flight */) const { // We pace at twice the rate of the underlying sender's bandwidth estimate // during slow start and 1.25x during congestion avoidance to ensure pacing // doesn't prevent us from filling the window. @@ -214,11 +203,6 @@ } const QuicBandwidth bandwidth = QuicBandwidth::FromBytesAndTimeDelta(GetCongestionWindow(), srtt); - if (rate_based_sending_ && bytes_in_flight > GetCongestionWindow()) { - // Rate based sending allows sending more than CWND, but reduces the pacing - // rate when the bytes in flight is more than the CWND to 75% of bandwidth. - return 0.75 * bandwidth; - } return bandwidth * (InSlowStart() ? 2 : (no_prr_ && InRecovery() ? 1 : 1.25)); }
diff --git a/net/quic/core/congestion_control/tcp_cubic_sender_base.h b/net/quic/core/congestion_control/tcp_cubic_sender_base.h index eaa4357..ab4c3b6 100644 --- a/net/quic/core/congestion_control/tcp_cubic_sender_base.h +++ b/net/quic/core/congestion_control/tcp_cubic_sender_base.h
@@ -147,9 +147,6 @@ // When true, exit slow start with large cutback of congestion window. bool slow_start_large_reduction_; - // When true, use rate based sending instead of only sending if there's CWND. - bool rate_based_sending_; - // When true, use unity pacing instead of PRR. bool no_prr_;
diff --git a/net/quic/core/congestion_control/tcp_cubic_sender_bytes_test.cc b/net/quic/core/congestion_control/tcp_cubic_sender_bytes_test.cc index f6ff010..cef26838 100644 --- a/net/quic/core/congestion_control/tcp_cubic_sender_bytes_test.cc +++ b/net/quic/core/congestion_control/tcp_cubic_sender_bytes_test.cc
@@ -751,38 +751,6 @@ sender_->PacingRate(kRenoBeta * kDefaultWindowTCP)); } -TEST_F(TcpCubicSenderBytesTest, PaceSlowerAboveCwnd) { - QuicTime::Delta rtt(QuicTime::Delta::FromMilliseconds(60)); - sender_->rtt_stats_.UpdateRtt(rtt, QuicTime::Delta::Zero(), clock_.Now()); - - QuicConfig config; - QuicTagVector options; - options.push_back(kRATE); - QuicConfigPeer::SetReceivedConnectionOptions(&config, options); - sender_->SetFromConfig(config, Perspective::IS_SERVER); - EXPECT_EQ(10 * kDefaultTCPMSS, sender_->GetCongestionWindow()); - sender_->SetNumEmulatedConnections(1); - // Lose a packet to exit slow start. - LoseNPackets(1); - const QuicPacketCount cwnd = 7; - EXPECT_EQ(cwnd * kDefaultTCPMSS, sender_->GetCongestionWindow()); - - EXPECT_TRUE( - sender_->TimeUntilSend(QuicTime::Zero(), kDefaultTCPMSS).IsZero()); - EXPECT_EQ( - sender_->PacingRate(kDefaultTCPMSS), - QuicBandwidth::FromBytesAndTimeDelta(7 * kDefaultTCPMSS, rtt) * 1.25); - for (QuicPacketCount i = cwnd + 1; i < 1.5 * cwnd; ++i) { - EXPECT_TRUE( - sender_->TimeUntilSend(QuicTime::Zero(), i * kDefaultTCPMSS).IsZero()); - EXPECT_EQ(sender_->PacingRate(i * kDefaultTCPMSS), - QuicBandwidth::FromBytesAndTimeDelta(cwnd * kDefaultTCPMSS, rtt) * - 0.75); - } - EXPECT_FALSE( - sender_->TimeUntilSend(QuicTime::Zero(), 11 * kDefaultTCPMSS).IsZero()); -} - TEST_F(TcpCubicSenderBytesTest, ResetAfterConnectionMigration) { // Starts from slow start. sender_->SetNumEmulatedConnections(1);
diff --git a/net/quic/core/congestion_control/tcp_cubic_sender_packets_test.cc b/net/quic/core/congestion_control/tcp_cubic_sender_packets_test.cc index 57847ca..bac65c7 100644 --- a/net/quic/core/congestion_control/tcp_cubic_sender_packets_test.cc +++ b/net/quic/core/congestion_control/tcp_cubic_sender_packets_test.cc
@@ -854,38 +854,6 @@ sender_->PacingRate(kRenoBeta * kDefaultWindowTCP)); } -TEST_F(TcpCubicSenderPacketsTest, PaceSlowerAboveCwnd) { - QuicTime::Delta rtt(QuicTime::Delta::FromMilliseconds(60)); - sender_->rtt_stats_.UpdateRtt(rtt, QuicTime::Delta::Zero(), clock_.Now()); - - QuicConfig config; - QuicTagVector options; - options.push_back(kRATE); - QuicConfigPeer::SetReceivedConnectionOptions(&config, options); - sender_->SetFromConfig(config, Perspective::IS_SERVER); - EXPECT_EQ(10u, sender_->congestion_window()); - sender_->SetNumEmulatedConnections(1); - // Lose a packet to exit slow start. - LoseNPackets(1); - const QuicPacketCount cwnd = 7; - EXPECT_EQ(cwnd * kDefaultTCPMSS, sender_->GetCongestionWindow()); - - EXPECT_TRUE( - sender_->TimeUntilSend(QuicTime::Zero(), kDefaultTCPMSS).IsZero()); - EXPECT_EQ( - sender_->PacingRate(kDefaultTCPMSS), - QuicBandwidth::FromBytesAndTimeDelta(7 * kDefaultTCPMSS, rtt) * 1.25); - for (QuicPacketCount i = cwnd + 1; i < 1.5 * cwnd; ++i) { - EXPECT_TRUE( - sender_->TimeUntilSend(QuicTime::Zero(), i * kDefaultTCPMSS).IsZero()); - EXPECT_EQ(sender_->PacingRate(i * kDefaultTCPMSS), - QuicBandwidth::FromBytesAndTimeDelta(cwnd * kDefaultTCPMSS, rtt) * - 0.75); - } - EXPECT_FALSE( - sender_->TimeUntilSend(QuicTime::Zero(), 11 * kDefaultTCPMSS).IsZero()); -} - TEST_F(TcpCubicSenderPacketsTest, ResetAfterConnectionMigration) { EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow()); EXPECT_EQ(kMaxCongestionWindowPackets, sender_->slowstart_threshold());
diff --git a/net/quic/core/crypto/crypto_protocol.h b/net/quic/core/crypto/crypto_protocol.h index c408070..d3b6930 100644 --- a/net/quic/core/crypto/crypto_protocol.h +++ b/net/quic/core/crypto/crypto_protocol.h
@@ -90,7 +90,6 @@ const QuicTag kTPCC = TAG('P', 'C', 'C', '\0'); // Performance-Oriented // Congestion Control const QuicTag kBYTE = TAG('B', 'Y', 'T', 'E'); // TCP cubic or reno in bytes -const QuicTag kRATE = TAG('R', 'A', 'T', 'E'); // TCP cubic rate based sending const QuicTag kIW03 = TAG('I', 'W', '0', '3'); // Force ICWND to 3 const QuicTag kIW10 = TAG('I', 'W', '1', '0'); // Force ICWND to 10 const QuicTag kIW20 = TAG('I', 'W', '2', '0'); // Force ICWND to 20
diff --git a/net/quic/core/frames/quic_ack_frame.cc b/net/quic/core/frames/quic_ack_frame.cc index 385500a7..c9c4d2e 100644 --- a/net/quic/core/frames/quic_ack_frame.cc +++ b/net/quic/core/frames/quic_ack_frame.cc
@@ -4,10 +4,15 @@ #include "net/quic/core/frames/quic_ack_frame.h" +#include <algorithm> + #include "net/quic/core/quic_constants.h" #include "net/quic/platform/api/quic_bug_tracker.h" #include "net/quic/platform/api/quic_flag_utils.h" +using std::max; +using std::min; + namespace net { PacketNumberQueue::const_iterator::const_iterator(const const_iterator& other) = @@ -67,9 +72,9 @@ return os; } PacketNumberQueue::PacketNumberQueue() - : use_deque_(FLAGS_quic_reloadable_flag_quic_frames_deque) { + : use_deque_(FLAGS_quic_reloadable_flag_quic_frames_deque2) { if (use_deque_) { - QUIC_FLAG_COUNT(quic_reloadable_flag_quic_frames_deque); + QUIC_FLAG_COUNT(quic_reloadable_flag_quic_frames_deque2); } } @@ -122,23 +127,21 @@ // to find a proper place for the packet while (i >= 0) { Interval<QuicPacketNumber> packet_interval = packet_number_deque_[i]; + DCHECK(packet_interval.min() < packet_interval.max()); // Check if the packet is contained in an interval already - if (packet_interval.max() > packet_number && - packet_interval.min() <= packet_number) { + if (packet_interval.Contains(packet_number)) { return; } - // Check if the packet can extend an interval - // and merges two intervals if needed + // Check if the packet can extend an interval. if (packet_interval.max() == packet_number) { packet_number_deque_[i].SetMax(packet_number + 1); - if (static_cast<size_t>(i) < packet_number_deque_.size() - 1 && - packet_number + 1 == packet_number_deque_[i + 1].min()) { - packet_number_deque_[i].SetMax(packet_number_deque_[i + 1].max()); - packet_number_deque_.erase(packet_number_deque_.begin() + i + 1); - } return; } + // Check if the packet can extend an interval + // and merge two intervals if needed. + // There is no need to merge an interval in the previous + // if statement, as all merges will happen here. if (packet_interval.min() == packet_number + 1) { packet_number_deque_[i].SetMin(packet_number); if (i > 0 && packet_number == packet_number_deque_[i - 1].max()) { @@ -189,7 +192,7 @@ Interval<QuicPacketNumber> front = packet_number_deque_.front(); // Check if the packets are being added in reverse order if (front.min() == higher) { - packet_number_deque_.front().SetMax(lower); + packet_number_deque_.front().SetMin(lower); } else if (front.min() > higher) { packet_number_deque_.push_front( Interval<QuicPacketNumber>(lower, higher)); @@ -204,11 +207,11 @@ // extended, which would reduce the compexity of the following for loop. if (higher >= back.max()) { packet_number_deque_.back().SetMax(higher); - higher = back.min(); + higher = max(lower, back.min()); } if (lower < front.min()) { packet_number_deque_.front().SetMin(lower); - lower = front.max() - 1; + lower = min(higher, front.max()); } for (size_t i = lower; i < higher; i++) {
diff --git a/net/quic/core/frames/quic_ack_frame.h b/net/quic/core/frames/quic_ack_frame.h index f8b9ef0..54f95a3 100644 --- a/net/quic/core/frames/quic_ack_frame.h +++ b/net/quic/core/frames/quic_ack_frame.h
@@ -244,7 +244,7 @@ private: // TODO(lilika): Remove QuicIntervalSet<QuicPacketNumber> - // once FLAGS_quic_reloadable_flag_quic_frames_deque is removed + // once FLAGS_quic_reloadable_flag_quic_frames_deque2 is removed QuicIntervalSet<QuicPacketNumber> packet_number_intervals_; std::deque<Interval<QuicPacketNumber>> packet_number_deque_; bool use_deque_;
diff --git a/net/quic/core/frames/quic_frames_test.cc b/net/quic/core/frames/quic_frames_test.cc index 9312e58..323e8cd 100644 --- a/net/quic/core/frames/quic_frames_test.cc +++ b/net/quic/core/frames/quic_frames_test.cc
@@ -224,7 +224,7 @@ EXPECT_EQ(expected_intervals, actual_intervals); - if (FLAGS_quic_reloadable_flag_quic_frames_deque) { + if (FLAGS_quic_reloadable_flag_quic_frames_deque2) { EXPECT_QUIC_BUG(ack_frame1.packets.AddRange(20, 30), ""); } else { ack_frame1.packets.AddRange(20, 30); @@ -241,7 +241,7 @@ EXPECT_EQ(3u, ack_frame1.packets.NumIntervals()); EXPECT_EQ(expected_intervals2, actual_intervals2); - if (FLAGS_quic_reloadable_flag_quic_frames_deque) { + if (FLAGS_quic_reloadable_flag_quic_frames_deque2) { EXPECT_QUIC_BUG(ack_frame1.packets.AddRange(15, 20), ""); EXPECT_QUIC_BUG(ack_frame1.packets.AddRange(30, 35), ""); } else { @@ -259,7 +259,7 @@ EXPECT_EQ(expected_intervals3, actual_intervals3); - if (FLAGS_quic_reloadable_flag_quic_frames_deque) { + if (FLAGS_quic_reloadable_flag_quic_frames_deque2) { EXPECT_QUIC_BUG(ack_frame1.packets.AddRange(20, 35), ""); } else { ack_frame1.packets.AddRange(20, 35); @@ -269,7 +269,7 @@ ack_frame1.packets.begin(), ack_frame1.packets.end()); EXPECT_EQ(expected_intervals3, actual_intervals4); - if (FLAGS_quic_reloadable_flag_quic_frames_deque) { + if (FLAGS_quic_reloadable_flag_quic_frames_deque2) { EXPECT_QUIC_BUG(ack_frame1.packets.AddRange(12, 20), ""); EXPECT_QUIC_BUG(ack_frame1.packets.AddRange(30, 38), ""); } else { @@ -286,7 +286,7 @@ expected_intervals5.push_back(Interval<QuicPacketNumber>(50, 100)); EXPECT_EQ(expected_intervals5, actual_intervals5); - if (FLAGS_quic_reloadable_flag_quic_frames_deque) { + if (FLAGS_quic_reloadable_flag_quic_frames_deque2) { EXPECT_QUIC_BUG(ack_frame1.packets.AddRange(8, 55), ""); } else { ack_frame1.packets.AddRange(8, 55); @@ -300,7 +300,7 @@ EXPECT_EQ(expected_intervals6, actual_intervals6); - if (FLAGS_quic_reloadable_flag_quic_frames_deque) { + if (FLAGS_quic_reloadable_flag_quic_frames_deque2) { EXPECT_QUIC_BUG(ack_frame1.packets.AddRange(0, 200), ""); } else { ack_frame1.packets.AddRange(0, 200); @@ -334,11 +334,57 @@ EXPECT_EQ(expected_intervals8, actual_intervals8); } +TEST_F(QuicFramesTest, AddAdjacentReverse) { + QuicAckFrame ack_frame1; + ack_frame1.packets.AddRange(70, 100); + ack_frame1.packets.AddRange(60, 70); + ack_frame1.packets.AddRange(50, 60); + ack_frame1.packets.Add(49); + + std::vector<Interval<QuicPacketNumber>> expected_intervals; + expected_intervals.push_back(Interval<QuicPacketNumber>(49, 100)); + + const std::vector<Interval<QuicPacketNumber>> actual_intervals( + ack_frame1.packets.begin(), ack_frame1.packets.end()); + + EXPECT_EQ(expected_intervals, actual_intervals); +} + +TEST_F(QuicFramesTest, AddMerges) { + QuicAckFrame ack_frame1; + ack_frame1.packets.AddRange(110, 112); + ack_frame1.packets.AddRange(106, 108); + ack_frame1.packets.AddRange(102, 104); + ack_frame1.packets.AddRange(1, 2); + ack_frame1.packets.AddRange(4, 7); + ack_frame1.packets.AddRange(10, 20); + ack_frame1.packets.AddRange(21, 30); + ack_frame1.packets.Add(20); + ack_frame1.packets.AddRange(40, 50); + ack_frame1.packets.AddRange(30, 35); + ack_frame1.packets.AddRange(35, 40); + ack_frame1.packets.AddRange(108, 110); + if (FLAGS_quic_reloadable_flag_quic_frames_deque2) { + EXPECT_QUIC_BUG(ack_frame1.packets.AddRange(50, 106), ""); + } else { + ack_frame1.packets.AddRange(50, 106); + } + ack_frame1.packets.AddRange(2, 4); + ack_frame1.packets.AddRange(7, 11); + std::vector<Interval<QuicPacketNumber>> expected_intervals; + expected_intervals.push_back(Interval<QuicPacketNumber>(1, 112)); + + const std::vector<Interval<QuicPacketNumber>> actual_intervals( + ack_frame1.packets.begin(), ack_frame1.packets.end()); + + EXPECT_EQ(expected_intervals, actual_intervals); +} + TEST_F(QuicFramesTest, AddIntervalBig) { QuicAckFrame ack_frame1; ack_frame1.packets.AddRange(20, 30); ack_frame1.packets.AddRange(70, 100); - if (FLAGS_quic_reloadable_flag_quic_frames_deque) { + if (FLAGS_quic_reloadable_flag_quic_frames_deque2) { EXPECT_QUIC_BUG(ack_frame1.packets.AddRange(56, 58), ""); EXPECT_QUIC_BUG(ack_frame1.packets.AddRange(65, 69), ""); EXPECT_QUIC_BUG(ack_frame1.packets.AddRange(59, 64), ""); @@ -362,7 +408,7 @@ ack_frame1.packets.begin(), ack_frame1.packets.end()); EXPECT_EQ(expected_intervals, actual_intervals); - if (FLAGS_quic_reloadable_flag_quic_frames_deque) { + if (FLAGS_quic_reloadable_flag_quic_frames_deque2) { EXPECT_QUIC_BUG(ack_frame1.packets.AddRange(10, 60), ""); } else { ack_frame1.packets.AddRange(10, 60); @@ -378,7 +424,7 @@ EXPECT_EQ(expected_intervals2, actual_intervals2); - if (FLAGS_quic_reloadable_flag_quic_frames_deque) { + if (FLAGS_quic_reloadable_flag_quic_frames_deque2) { EXPECT_QUIC_BUG(ack_frame1.packets.AddRange(68, 1000), ""); } else { ack_frame1.packets.AddRange(68, 1000); @@ -392,7 +438,7 @@ ack_frame1.packets.begin(), ack_frame1.packets.end()); EXPECT_EQ(expected_intervals3, actual_intervals3); - if (FLAGS_quic_reloadable_flag_quic_frames_deque) { + if (FLAGS_quic_reloadable_flag_quic_frames_deque2) { EXPECT_QUIC_BUG(ack_frame1.packets.AddRange(0, 10000), ""); } else { ack_frame1.packets.AddRange(0, 10000);
diff --git a/net/quic/core/frames/quic_stream_frame.h b/net/quic/core/frames/quic_stream_frame.h index dec3407a..4d280fc 100644 --- a/net/quic/core/frames/quic_stream_frame.h +++ b/net/quic/core/frames/quic_stream_frame.h
@@ -65,7 +65,7 @@ const char* data_buffer; QuicStreamOffset offset; // Location of this data in the stream. // TODO(fayang): When deprecating - // quic_reloadable_flag_quic_save_data_before_consumption: (1) Remove buffer + // quic_reloadable_flag_quic_save_data_before_consumption2: (1) Remove buffer // from QuicStreamFrame; (2) remove the constructor uses UniqueStreamBuffer // and (3) Move definition of UniqueStreamBuffer to QuicStreamSendBuffer. // nullptr when the QuicStreamFrame is received, and non-null when sent.
diff --git a/net/quic/core/quic_connection.cc b/net/quic/core/quic_connection.cc index 6260660..afd80bdd 100644 --- a/net/quic/core/quic_connection.cc +++ b/net/quic/core/quic_connection.cc
@@ -543,9 +543,7 @@ return; } - if (FLAGS_quic_reloadable_flag_quic_to_backend_multi_version) { - server_supported_versions_ = packet.versions; - } + server_supported_versions_ = packet.versions; if (!SelectMutualVersion(packet.versions)) { CloseConnection( @@ -560,9 +558,6 @@ QUIC_DLOG(INFO) << ENDPOINT << "Negotiated version: " << QuicVersionToString(version()); - if (!FLAGS_quic_reloadable_flag_quic_to_backend_multi_version) { - server_supported_versions_ = packet.versions; - } version_negotiation_state_ = NEGOTIATION_IN_PROGRESS; RetransmitUnackedPackets(ALL_UNACKED_RETRANSMISSION); } @@ -910,7 +905,7 @@ bool QuicConnection::OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) { DCHECK(connected_); if (debug_visitor_ != nullptr) { - debug_visitor_->OnWindowUpdateFrame(frame); + debug_visitor_->OnWindowUpdateFrame(frame, time_of_last_received_packet_); } QUIC_DLOG(INFO) << ENDPOINT << "WINDOW_UPDATE_FRAME received for stream: " << frame.stream_id @@ -1548,7 +1543,7 @@ if (result.status == WRITE_STATUS_BLOCKED) { visitor_->OnWriteBlocked(); - // If the socket buffers the the data, then the packet should not + // If the socket buffers the data, then the packet should not // be queued and sent again, which would result in an unnecessary // duplicate packet being sent. The helper must call OnCanWrite // when the write completes, and OnWriteError if an error occurs.
diff --git a/net/quic/core/quic_connection.h b/net/quic/core/quic_connection.h index 80c76bb..fc180415 100644 --- a/net/quic/core/quic_connection.h +++ b/net/quic/core/quic_connection.h
@@ -230,7 +230,8 @@ virtual void OnConnectionCloseFrame(const QuicConnectionCloseFrame& frame) {} // Called when a WindowUpdate has been parsed. - virtual void OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) {} + virtual void OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame, + const QuicTime& receive_time) {} // Called when a BlockedFrame has been parsed. virtual void OnBlockedFrame(const QuicBlockedFrame& frame) {}
diff --git a/net/quic/core/quic_crypto_client_stream_test.cc b/net/quic/core/quic_crypto_client_stream_test.cc index 2453761..0c04daa 100644 --- a/net/quic/core/quic_crypto_client_stream_test.cc +++ b/net/quic/core/quic_crypto_client_stream_test.cc
@@ -225,8 +225,7 @@ reinterpret_cast<char*>(scfg), arraysize(scfg)); QuicStreamSequencer* sequencer = QuicStreamPeer::sequencer(stream()); - EXPECT_NE(FLAGS_quic_reloadable_flag_quic_release_crypto_stream_buffer, - QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(sequencer)); + EXPECT_FALSE(QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(sequencer)); } TEST_F(QuicCryptoClientStreamTest, ServerConfigUpdateWithCert) {
diff --git a/net/quic/core/quic_crypto_stream.cc b/net/quic/core/quic_crypto_stream.cc index 6d5b4e6..197a170 100644 --- a/net/quic/core/quic_crypto_stream.cc +++ b/net/quic/core/quic_crypto_stream.cc
@@ -57,9 +57,7 @@ } sequencer()->MarkConsumed(iov.iov_len); if (handshake_confirmed() && - crypto_message_parser()->InputBytesRemaining() == 0 && - FLAGS_quic_reloadable_flag_quic_release_crypto_stream_buffer) { - QUIC_FLAG_COUNT(quic_reloadable_flag_quic_release_crypto_stream_buffer); + crypto_message_parser()->InputBytesRemaining() == 0) { // If the handshake is complete and the current message has been fully // processed then no more handshake messages are likely to arrive soon // so release the memory in the stream sequencer.
diff --git a/net/quic/core/quic_data_writer.cc b/net/quic/core/quic_data_writer.cc index e4716b3..7e831d8b 100644 --- a/net/quic/core/quic_data_writer.cc +++ b/net/quic/core/quic_data_writer.cc
@@ -59,6 +59,17 @@ return WriteBytes(&value, sizeof(value)); } +bool QuicDataWriter::WriteUInt8AtOffset(uint8_t value, size_t offset) { + if (offset > length_) { + return false; + } + size_t old_length = length_; + length_ = offset; + bool result = WriteBytes(&value, sizeof(value)); + length_ = old_length; + return result; +} + bool QuicDataWriter::WriteBytesToUInt64(size_t num_bytes, uint64_t value) { if (num_bytes > sizeof(value)) { return false;
diff --git a/net/quic/core/quic_data_writer.h b/net/quic/core/quic_data_writer.h index 46df686..b2de22d68 100644 --- a/net/quic/core/quic_data_writer.h +++ b/net/quic/core/quic_data_writer.h
@@ -48,6 +48,10 @@ bool WriteUInt32(uint32_t value); bool WriteUInt64(uint64_t value); + // Writes |value| to the position |offset| from the start of the data. + // |offset| must be less than the current length of the writer. + bool WriteUInt8AtOffset(uint8_t value, size_t offset); + // Writes least significant |num_bytes| of a 64-bit unsigned integer in the // correct byte order. bool WriteBytesToUInt64(size_t num_bytes, uint64_t value);
diff --git a/net/quic/core/quic_data_writer_test.cc b/net/quic/core/quic_data_writer_test.cc index c6c2d7c3..0baba76 100644 --- a/net/quic/core/quic_data_writer_test.cc +++ b/net/quic/core/quic_data_writer_test.cc
@@ -587,6 +587,35 @@ } } +TEST_P(QuicDataWriterTest, WriteBytes) { + char bytes[] = {0, 1, 2, 3, 4, 5, 6, 7, 8}; + char buf[arraysize(bytes)]; + QuicDataWriter writer(arraysize(buf), buf, GetParam().perspective, + GetParam().endianness); + EXPECT_TRUE(writer.WriteBytes(bytes, arraysize(bytes))); + for (unsigned int i = 0; i < arraysize(bytes); ++i) { + EXPECT_EQ(bytes[i], buf[i]); + } +} + +TEST_P(QuicDataWriterTest, WriteUInt8AtOffset) { + char bytes[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'}; + char buf[arraysize(bytes)]; + for (unsigned int i = 0; i < arraysize(bytes); ++i) { + QuicDataWriter writer(arraysize(buf), buf, GetParam().perspective, + GetParam().endianness); + EXPECT_TRUE(writer.WriteBytes(bytes, arraysize(bytes))); + EXPECT_TRUE(writer.WriteUInt8AtOffset('I', i)); + for (unsigned int j = 0; j < arraysize(bytes); ++j) { + if (j == i) { + EXPECT_EQ('I', buf[j]); + } else { + EXPECT_EQ(bytes[j], buf[j]); + } + } + } +} + } // namespace } // namespace test } // namespace net
diff --git a/net/quic/core/quic_flags_list.h b/net/quic/core/quic_flags_list.h index 2ce2872c..2de3340 100644 --- a/net/quic/core/quic_flags_list.h +++ b/net/quic/core/quic_flags_list.h
@@ -61,12 +61,6 @@ FLAGS_quic_reloadable_flag_quic_limit_num_new_sessions_per_epoll_loop, true) -// If true, release QuicCryptoStream\'s read buffer when stream are less -// frequently used. -QUIC_FLAG(bool, - FLAGS_quic_reloadable_flag_quic_release_crypto_stream_buffer, - true) - // If true, v33 QUIC client uses 1 bit to specify 8-byte connection id in // public flag. QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_remove_v33_hacks2, false) @@ -114,9 +108,6 @@ // compressed for QUIC version >= 38. QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_enable_random_padding, true) -// If enabled, use refactored stream creation methods. -QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_refactor_stream_creation, false) - // If true, export a varz mapping QUIC non 0-rtt handshake with corresponding // frontend service. QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_account_handshake, false) @@ -149,23 +140,20 @@ false) // If true, disables support for QUIC version 36. -QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_disable_version_36, false) +QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_disable_version_36, true) // If true, disables support for the packets-based QUIC congestion control // algorithms. QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_disable_packets_based_cc, false) // When enabled, ack frame uses a deque internally instead of a set. -QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_frames_deque, false) - -// If true, server supported versions is updated before SelectMutualVersion. -QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_to_backend_multi_version, true) +QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_frames_deque2, false) // If true, QUIC packet creator passes a stack allocated SerializedPacket to the // connection. QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_clear_packet_before_handed_over, - true) + false) // If true, enable QUIC v41. QUIC_FLAG(bool, FLAGS_quic_enable_version_41, false) @@ -182,7 +170,7 @@ // If true, application data is saved before consumption in QUIC. QUIC_FLAG(bool, - FLAGS_quic_reloadable_flag_quic_save_data_before_consumption, + FLAGS_quic_reloadable_flag_quic_save_data_before_consumption2, false) // If buffered data in QUIC stream is less than this threshold, buffers all @@ -204,3 +192,10 @@ // Enables using the ConsumeDataFastPath more often for large transfers. QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_consuming_data_faster, false) + +// If true, in QUIC, set dispatcher framer\'s version to client packet's +// version in QuicDispatcher::OnStatelessRejectorProcessDone. +QUIC_FLAG( + bool, + FLAGS_quic_reloadable_flag_quic_set_version_on_async_get_proof_returns, + false)
diff --git a/net/quic/core/quic_framer.cc b/net/quic/core/quic_framer.cc index d460c0e6..99ffb5b 100644 --- a/net/quic/core/quic_framer.cc +++ b/net/quic/core/quic_framer.cc
@@ -121,8 +121,8 @@ } QuicPacketNumberLength ReadSequenceNumberLength(uint8_t flags) { - switch (flags & PACKET_FLAGS_6BYTE_PACKET) { - case PACKET_FLAGS_6BYTE_PACKET: + switch (flags & PACKET_FLAGS_8BYTE_PACKET) { + case PACKET_FLAGS_8BYTE_PACKET: return PACKET_6BYTE_PACKET_NUMBER; case PACKET_FLAGS_4BYTE_PACKET: return PACKET_4BYTE_PACKET_NUMBER; @@ -136,6 +136,24 @@ } } +QuicPacketNumberLength ReadAckPacketNumberLength(QuicVersion version, + uint8_t flags) { + switch (flags & PACKET_FLAGS_8BYTE_PACKET) { + case PACKET_FLAGS_8BYTE_PACKET: + return version <= QUIC_VERSION_39 ? PACKET_6BYTE_PACKET_NUMBER + : PACKET_8BYTE_PACKET_NUMBER; + case PACKET_FLAGS_4BYTE_PACKET: + return PACKET_4BYTE_PACKET_NUMBER; + case PACKET_FLAGS_2BYTE_PACKET: + return PACKET_2BYTE_PACKET_NUMBER; + case PACKET_FLAGS_1BYTE_PACKET: + return PACKET_1BYTE_PACKET_NUMBER; + default: + QUIC_BUG << "Unreachable case statement."; + return PACKET_6BYTE_PACKET_NUMBER; + } +} + } // namespace QuicFramer::QuicFramer(const QuicVersionVector& supported_versions, @@ -876,6 +894,7 @@ // static QuicPacketNumberLength QuicFramer::GetMinPacketNumberLength( + QuicVersion version, QuicPacketNumber packet_number) { if (packet_number < 1 << (PACKET_1BYTE_PACKET_NUMBER * 8)) { return PACKET_1BYTE_PACKET_NUMBER; @@ -884,7 +903,8 @@ } else if (packet_number < UINT64_C(1) << (PACKET_4BYTE_PACKET_NUMBER * 8)) { return PACKET_4BYTE_PACKET_NUMBER; } else { - return PACKET_6BYTE_PACKET_NUMBER; + return version <= QUIC_VERSION_39 ? PACKET_6BYTE_PACKET_NUMBER + : PACKET_8BYTE_PACKET_NUMBER; } } @@ -899,10 +919,11 @@ case PACKET_4BYTE_PACKET_NUMBER: return PACKET_FLAGS_4BYTE_PACKET; case PACKET_6BYTE_PACKET_NUMBER: - return PACKET_FLAGS_6BYTE_PACKET; + case PACKET_8BYTE_PACKET_NUMBER: + return PACKET_FLAGS_8BYTE_PACKET; default: QUIC_BUG << "Unreachable case statement."; - return PACKET_FLAGS_6BYTE_PACKET; + return PACKET_FLAGS_8BYTE_PACKET; } } @@ -1272,18 +1293,31 @@ bool QuicFramer::ProcessAckFrame(QuicDataReader* reader, uint8_t frame_type, QuicAckFrame* ack_frame) { - // Determine the two lengths from the frame type: largest acked length, - // ack block length. - const QuicPacketNumberLength ack_block_length = - ReadSequenceNumberLength(ExtractBits( - frame_type, kQuicSequenceNumberLengthNumBits, kActBlockLengthOffset)); - const QuicPacketNumberLength largest_acked_length = - ReadSequenceNumberLength(ExtractBits( - frame_type, kQuicSequenceNumberLengthNumBits, kLargestAckedOffset)); bool has_ack_blocks = !!ExtractBits( frame_type, kBooleanNumBits, quic_version_ < QUIC_VERSION_40 ? kQuicHasMultipleAckBlocksOffset_Pre40 : kQuicHasMultipleAckBlocksOffset); + uint8_t num_ack_blocks = 0; + uint8_t num_received_packets = 0; + if (quic_version_ > QUIC_VERSION_39) { + if (has_ack_blocks && !reader->ReadUInt8(&num_ack_blocks)) { + set_detailed_error("Unable to read num of ack blocks."); + return false; + } + if (!reader->ReadUInt8(&num_received_packets)) { + set_detailed_error("Unable to read num received packets."); + return false; + } + } + + // Determine the two lengths from the frame type: largest acked length, + // ack block length. + const QuicPacketNumberLength ack_block_length = ReadAckPacketNumberLength( + quic_version_, ExtractBits(frame_type, kQuicSequenceNumberLengthNumBits, + kActBlockLengthOffset)); + const QuicPacketNumberLength largest_acked_length = ReadAckPacketNumberLength( + quic_version_, ExtractBits(frame_type, kQuicSequenceNumberLengthNumBits, + kLargestAckedOffset)); if (!reader->ReadBytesToUInt64(largest_acked_length, &ack_frame->largest_observed)) { @@ -1304,9 +1338,9 @@ QuicTime::Delta::FromMicroseconds(ack_delay_time_us); } - uint8_t num_ack_blocks = 0; if (has_ack_blocks) { - if (!reader->ReadUInt8(&num_ack_blocks)) { + if (quic_version_ <= QUIC_VERSION_39 && + !reader->ReadUInt8(&num_ack_blocks)) { set_detailed_error("Unable to read num of ack blocks."); return false; } @@ -1341,21 +1375,22 @@ } } - if (!ProcessTimestampsInAckFrame(reader, ack_frame)) { + if (quic_version_ <= QUIC_VERSION_39 && + !reader->ReadUInt8(&num_received_packets)) { + set_detailed_error("Unable to read num received packets."); + return false; + } + + if (!ProcessTimestampsInAckFrame(num_received_packets, reader, ack_frame)) { return false; } return true; } -bool QuicFramer::ProcessTimestampsInAckFrame(QuicDataReader* reader, +bool QuicFramer::ProcessTimestampsInAckFrame(uint8_t num_received_packets, + QuicDataReader* reader, QuicAckFrame* ack_frame) { - uint8_t num_received_packets; - if (!reader->ReadUInt8(&num_received_packets)) { - set_detailed_error("Unable to read num received packets."); - return false; - } - if (num_received_packets > 0) { uint8_t delta_from_largest_observed; if (!reader->ReadUInt8(&delta_from_largest_observed)) { @@ -1746,9 +1781,9 @@ AckFrameInfo ack_info = GetAckFrameInfo(ack); QuicPacketNumberLength largest_acked_length = - GetMinPacketNumberLength(ack.largest_observed); + GetMinPacketNumberLength(quic_version_, ack.largest_observed); QuicPacketNumberLength ack_block_length = - GetMinPacketNumberLength(ack_info.max_block_length); + GetMinPacketNumberLength(quic_version_, ack_info.max_block_length); ack_size = GetMinAckFrameSize(quic_version_, largest_acked_length); // First ack block length. @@ -1896,7 +1931,7 @@ QuicPacketNumber packet_number, QuicDataWriter* writer) { size_t length = packet_number_length; - if (length != 1 && length != 2 && length != 4 && length != 6) { + if (length != 1 && length != 2 && length != 4 && length != 6 && length != 8) { QUIC_BUG << "Invalid packet_number_length: " << length; return false; } @@ -1993,9 +2028,9 @@ const AckFrameInfo new_ack_info = GetAckFrameInfo(frame); QuicPacketNumber largest_acked = frame.largest_observed; QuicPacketNumberLength largest_acked_length = - GetMinPacketNumberLength(largest_acked); + GetMinPacketNumberLength(quic_version_, largest_acked); QuicPacketNumberLength ack_block_length = - GetMinPacketNumberLength(new_ack_info.max_block_length); + GetMinPacketNumberLength(quic_version_, new_ack_info.max_block_length); // Calculate available bytes for timestamps and ack blocks. int32_t available_timestamp_and_ack_block_bytes = writer->capacity() - writer->length() - ack_block_length - @@ -2028,6 +2063,31 @@ return false; } + size_t num_timestamps_offset = 0; + size_t max_num_ack_blocks = available_timestamp_and_ack_block_bytes / + (ack_block_length + PACKET_1BYTE_PACKET_NUMBER); + + // Number of ack blocks. + size_t num_ack_blocks = + std::min(new_ack_info.num_ack_blocks, max_num_ack_blocks); + if (num_ack_blocks > std::numeric_limits<uint8_t>::max()) { + num_ack_blocks = std::numeric_limits<uint8_t>::max(); + } + + if (quic_version_ > QUIC_VERSION_39) { + if (num_ack_blocks > 0 && !writer->WriteBytes(&num_ack_blocks, 1)) { + return false; + } + + // Write a placeholder for the number of timestamps which will be + // overwritten after the ack blocks have been written. + num_timestamps_offset = writer->length(); + uint8_t num_timestamps = 0; + if (!writer->WriteUInt8(num_timestamps)) { + return false; + } + } + // Largest acked. if (!AppendPacketNumber(largest_acked_length, largest_acked, writer)) { return false; @@ -2043,19 +2103,11 @@ return false; } - size_t max_num_ack_blocks = available_timestamp_and_ack_block_bytes / - (ack_block_length + PACKET_1BYTE_PACKET_NUMBER); - - // Number of ack blocks. - size_t num_ack_blocks = - std::min(new_ack_info.num_ack_blocks, max_num_ack_blocks); - if (num_ack_blocks > std::numeric_limits<uint8_t>::max()) { - num_ack_blocks = std::numeric_limits<uint8_t>::max(); - } - - if (num_ack_blocks > 0) { - if (!writer->WriteBytes(&num_ack_blocks, 1)) { - return false; + if (quic_version_ <= QUIC_VERSION_39) { + if (num_ack_blocks > 0) { + if (!writer->WriteBytes(&num_ack_blocks, 1)) { + return false; + } } } @@ -2126,7 +2178,7 @@ // append any of them. if (writer->capacity() - writer->length() >= GetAckFrameTimeStampSize(frame)) { - if (!AppendTimestampToAckFrame(frame, writer)) { + if (!AppendTimestampsToAckFrame(frame, num_timestamps_offset, writer)) { return false; } } else { @@ -2139,8 +2191,9 @@ return true; } -bool QuicFramer::AppendTimestampToAckFrame(const QuicAckFrame& frame, - QuicDataWriter* writer) { +bool QuicFramer::AppendTimestampsToAckFrame(const QuicAckFrame& frame, + size_t num_timestamps_offset, + QuicDataWriter* writer) { DCHECK_GE(std::numeric_limits<uint8_t>::max(), frame.received_packet_times.size()); // num_received_packets is only 1 byte. @@ -2150,8 +2203,15 @@ } uint8_t num_received_packets = frame.received_packet_times.size(); - if (!writer->WriteBytes(&num_received_packets, 1)) { - return false; + if (quic_version_ <= QUIC_VERSION_39) { + if (!writer->WriteBytes(&num_received_packets, 1)) { + return false; + } + } else { + if (!writer->WriteUInt8AtOffset(num_received_packets, + num_timestamps_offset)) { + return false; + } } if (num_received_packets == 0) { return true;
diff --git a/net/quic/core/quic_framer.h b/net/quic/core/quic_framer.h index 65a848e..513505e 100644 --- a/net/quic/core/quic_framer.h +++ b/net/quic/core/quic_framer.h
@@ -326,6 +326,7 @@ // The minimum packet number length required to represent |packet_number|. static QuicPacketNumberLength GetMinPacketNumberLength( + QuicVersion version, QuicPacketNumber packet_number); void SetSupportedVersions(const QuicVersionVector& versions) { @@ -405,7 +406,9 @@ bool ProcessAckFrame(QuicDataReader* reader, uint8_t frame_type, QuicAckFrame* frame); - bool ProcessTimestampsInAckFrame(QuicDataReader* reader, QuicAckFrame* frame); + bool ProcessTimestampsInAckFrame(uint8_t num_received_packets, + QuicDataReader* reader, + QuicAckFrame* ack_frame); bool ProcessStopWaitingFrame(QuicDataReader* reader, const QuicPacketHeader& public_header, QuicStopWaitingFrame* stop_waiting); @@ -482,8 +485,9 @@ bool AppendAckFrameAndTypeByte(const QuicAckFrame& frame, QuicDataWriter* builder); - bool AppendTimestampToAckFrame(const QuicAckFrame& frame, - QuicDataWriter* builder); + bool AppendTimestampsToAckFrame(const QuicAckFrame& frame, + size_t num_timestamps_offset, + QuicDataWriter* writer); bool AppendStopWaitingFrame(const QuicPacketHeader& header, const QuicStopWaitingFrame& frame, QuicDataWriter* builder);
diff --git a/net/quic/core/quic_framer_test.cc b/net/quic/core/quic_framer_test.cc index 976d1917..8e12326 100644 --- a/net/quic/core/quic_framer_test.cc +++ b/net/quic/core/quic_framer_test.cc
@@ -2030,14 +2030,14 @@ // frame type (ack frame) // (one ack block, 2 byte largest observed, 2 byte block length) 0xA5, + // num timestamps. + 0x00, // largest acked 0x12, 0x34, // Zero delta time. 0x00, 0x00, // first ack block length. 0x12, 0x34, - // num timestamps. - 0x00, }; // clang-format on @@ -2074,14 +2074,160 @@ kFirstAckBlockLengthOffset + PACKET_2BYTE_PACKET_NUMBER; for (size_t i = kQuicFrameTypeSize; i < ack_frame_size; ++i) { string expected_error; - if (i < kLargestAckedDeltaTimeOffset) { - expected_error = "Unable to read largest acked."; - } else if (i < kFirstAckBlockLengthOffset) { - expected_error = "Unable to read ack delay time."; - } else if (i < kNumTimestampsOffset) { - expected_error = "Unable to read first ack block length."; + if (framer_.version() > QUIC_VERSION_39) { + if (i < 2) { + expected_error = "Unable to read num received packets."; + } else if (i < 2 + PACKET_2BYTE_PACKET_NUMBER) { + expected_error = "Unable to read largest acked."; + } else if (i < 2 + PACKET_2BYTE_PACKET_NUMBER + + kQuicDeltaTimeLargestObservedSize) { + expected_error = "Unable to read ack delay time."; + } else { + expected_error = "Unable to read first ack block length."; + } } else { - expected_error = "Unable to read num received packets."; + if (i < kLargestAckedDeltaTimeOffset) { + expected_error = "Unable to read largest acked."; + } else if (i < kFirstAckBlockLengthOffset) { + expected_error = "Unable to read ack delay time."; + } else if (i < kNumTimestampsOffset) { + expected_error = "Unable to read first ack block length."; + } else { + expected_error = "Unable to read num received packets."; + } + } + CheckProcessingFails( + p, + i + GetPacketHeaderSize(framer_.version(), PACKET_8BYTE_CONNECTION_ID, + !kIncludeVersion, !kIncludeDiversificationNonce, + PACKET_6BYTE_PACKET_NUMBER), + expected_error, QUIC_INVALID_ACK_DATA); + } +} + +TEST_P(QuicFramerTest, AckFrameOneAckBlockMaxLength) { + // clang-format off + unsigned char packet[] = { + // public flags (8 byte connection_id) + 0x3C, + // connection_id + 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, + // packet number + 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, + + // frame type (ack frame) + // (one ack block, 6 byte largest observed, 2 byte block length) + 0x4D, + // largest acked + 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, + // Zero delta time. + 0x00, 0x00, + // first ack block length. + 0x34, 0x12, + // num timestamps. + 0x00, + }; + + unsigned char packet39[] = { + // public flags (8 byte connection_id) + 0x3C, + // connection_id + 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, + // packet number + 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, + + // frame type (ack frame) + // (one ack block, 6 byte largest observed, 2 byte block length) + 0x4D, + // largest acked + 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, + // Zero delta time. + 0x00, 0x00, + // first ack block length. + 0x12, 0x34, + // num timestamps. + 0x00, + }; + + unsigned char packet40[] = { + // public flags (8 byte connection_id) + 0x3C, + // connection_id + 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, + // packet number + 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, + + // frame type (ack frame) + // (one ack block, 8 byte largest observed, 2 byte block length) + 0xAD, + // num timestamps. + 0x00, + // largest acked + 0x00, 0x00, 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, + // Zero delta time. + 0x00, 0x00, + // first ack block length. + 0x12, 0x34 + }; + // clang-format on + + unsigned char* p = packet; + size_t packet_size = arraysize(packet); + if (framer_.version() > QUIC_VERSION_39) { + p = packet40; + packet_size = arraysize(packet40); + } else if (framer_.version() > QUIC_VERSION_38) { + p = packet39; + packet_size = arraysize(packet39); + } + + QuicEncryptedPacket encrypted(AsChars(p), packet_size, false); + EXPECT_TRUE(framer_.ProcessPacket(encrypted)); + + EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); + ASSERT_TRUE(visitor_.header_.get()); + EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion, + !kIncludeDiversificationNonce)); + + EXPECT_EQ(0u, visitor_.stream_frames_.size()); + ASSERT_EQ(1u, visitor_.ack_frames_.size()); + const QuicAckFrame& frame = *visitor_.ack_frames_[0]; + EXPECT_EQ(kPacketNumber, frame.largest_observed); + ASSERT_EQ(4660u, frame.packets.NumPacketsSlow()); + + const size_t kLargestAckedOffset = kQuicFrameTypeSize; + const size_t kLargestAckedDeltaTimeOffset = + kLargestAckedOffset + PACKET_6BYTE_PACKET_NUMBER; + const size_t kFirstAckBlockLengthOffset = + kLargestAckedDeltaTimeOffset + kQuicDeltaTimeLargestObservedSize; + const size_t kNumTimestampsOffset = + kFirstAckBlockLengthOffset + PACKET_2BYTE_PACKET_NUMBER; + // Now test framing boundaries. + const size_t ack_frame_size = + kFirstAckBlockLengthOffset + PACKET_2BYTE_PACKET_NUMBER; + for (size_t i = kQuicFrameTypeSize; i < ack_frame_size; ++i) { + string expected_error; + if (framer_.version() > QUIC_VERSION_39) { + if (i < 2) { + expected_error = "Unable to read num received packets."; + } else if (i < 2 + PACKET_8BYTE_PACKET_NUMBER) { + expected_error = "Unable to read largest acked."; + } else if (i < 2 + PACKET_8BYTE_PACKET_NUMBER + + kQuicDeltaTimeLargestObservedSize) { + expected_error = "Unable to read ack delay time."; + } else { + expected_error = "Unable to read first ack block length."; + } + } else { + if (i < kLargestAckedDeltaTimeOffset) { + expected_error = "Unable to read largest acked."; + } else if (i < kFirstAckBlockLengthOffset) { + expected_error = "Unable to read ack delay time."; + } else if (i < kNumTimestampsOffset) { + expected_error = "Unable to read first ack block length."; + } else { + expected_error = "Unable to read num received packets."; + } } CheckProcessingFails( p, @@ -2199,12 +2345,14 @@ // frame type (ack frame) // (more than one ack block, 2 byte largest observed, 2 byte block length) 0xB5, + // num ack blocks ranges. + 0x04, + // Number of timestamps. + 0x02, // largest acked 0x12, 0x34, // Zero delta time. 0x00, 0x00, - // num ack blocks ranges. - 0x04, // first ack block length. 0x00, 0x01, // gap to next block. @@ -2223,8 +2371,6 @@ 0x05, // ack block length. 0x00, 0x04, - // Number of timestamps. - 0x02, // Delta from largest observed. 0x01, // Delta time. @@ -2291,41 +2437,109 @@ kAckBlockLengthOffset4 + PACKET_2BYTE_PACKET_NUMBER; for (size_t i = kQuicFrameTypeSize; i < ack_frame_size; ++i) { string expected_error; - if (i < kLargestAckedDeltaTimeOffset) { - expected_error = "Unable to read largest acked."; - } else if (i < kNumberOfAckBlocksOffset) { - expected_error = "Unable to read ack delay time."; - } else if (i < kFirstAckBlockLengthOffset) { - expected_error = "Unable to read num of ack blocks."; - } else if (i < kGapToNextBlockOffset1) { - expected_error = "Unable to read first ack block length."; - } else if (i < kAckBlockLengthOffset1) { - expected_error = "Unable to read gap to next ack block."; - } else if (i < kGapToNextBlockOffset2) { - expected_error = "Unable to ack block length."; - } else if (i < kAckBlockLengthOffset2) { - expected_error = "Unable to read gap to next ack block."; - } else if (i < kGapToNextBlockOffset3) { - expected_error = "Unable to ack block length."; - } else if (i < kAckBlockLengthOffset3) { - expected_error = "Unable to read gap to next ack block."; - } else if (i < kGapToNextBlockOffset4) { - expected_error = "Unable to ack block length."; - } else if (i < kAckBlockLengthOffset4) { - expected_error = "Unable to read gap to next ack block."; - } else if (i < kNumTimestampsOffset) { - expected_error = "Unable to ack block length."; - } else if (i < kTimestampDeltaLargestObserved1) { - expected_error = "Unable to read num received packets."; - } else if (i < kTimestampTimeDeltaLargestObserved1) { - expected_error = "Unable to read sequence delta in received packets."; - } else if (i < kTimestampDeltaLargestObserved2) { - expected_error = "Unable to read time delta in received packets."; - } else if (i < kTimestampTimeDeltaLargestObserved2) { - expected_error = "Unable to read sequence delta in received packets."; + if (framer_.version() <= QUIC_VERSION_39) { + if (i < kLargestAckedDeltaTimeOffset) { + expected_error = "Unable to read largest acked."; + } else if (i < kNumberOfAckBlocksOffset) { + expected_error = "Unable to read ack delay time."; + } else if (i < kFirstAckBlockLengthOffset) { + expected_error = "Unable to read num of ack blocks."; + } else if (i < kGapToNextBlockOffset1) { + expected_error = "Unable to read first ack block length."; + } else if (i < kAckBlockLengthOffset1) { + expected_error = "Unable to read gap to next ack block."; + } else if (i < kGapToNextBlockOffset2) { + expected_error = "Unable to ack block length."; + } else if (i < kAckBlockLengthOffset2) { + expected_error = "Unable to read gap to next ack block."; + } else if (i < kGapToNextBlockOffset3) { + expected_error = "Unable to ack block length."; + } else if (i < kAckBlockLengthOffset3) { + expected_error = "Unable to read gap to next ack block."; + } else if (i < kGapToNextBlockOffset4) { + expected_error = "Unable to ack block length."; + } else if (i < kAckBlockLengthOffset4) { + expected_error = "Unable to read gap to next ack block."; + } else if (i < kNumTimestampsOffset) { + expected_error = "Unable to ack block length."; + } else if (i < kTimestampDeltaLargestObserved1) { + expected_error = "Unable to read num received packets."; + } else if (i < kTimestampTimeDeltaLargestObserved1) { + expected_error = "Unable to read sequence delta in received packets."; + } else if (i < kTimestampDeltaLargestObserved2) { + expected_error = "Unable to read time delta in received packets."; + } else if (i < kTimestampTimeDeltaLargestObserved2) { + expected_error = "Unable to read sequence delta in received packets."; + } else { + expected_error = + "Unable to read incremental time delta in received packets."; + } } else { - expected_error = - "Unable to read incremental time delta in received packets."; + const size_t kNumberOfAckBlocksOffset = kQuicFrameTypeSize; + const size_t kNumTimestampsOffset = kNumberOfAckBlocksOffset + 1; + const size_t kLargestAckedOffset = kNumTimestampsOffset + 1; + const size_t kLargestAckedDeltaTimeOffset = + kLargestAckedOffset + PACKET_2BYTE_PACKET_NUMBER; + const size_t kFirstAckBlockLengthOffset = + kLargestAckedDeltaTimeOffset + kQuicDeltaTimeLargestObservedSize; + const size_t kGapToNextBlockOffset1 = + kFirstAckBlockLengthOffset + PACKET_2BYTE_PACKET_NUMBER; + const size_t kAckBlockLengthOffset1 = kGapToNextBlockOffset1 + 1; + const size_t kGapToNextBlockOffset2 = + kAckBlockLengthOffset1 + PACKET_2BYTE_PACKET_NUMBER; + const size_t kAckBlockLengthOffset2 = kGapToNextBlockOffset2 + 1; + const size_t kGapToNextBlockOffset3 = + kAckBlockLengthOffset2 + PACKET_2BYTE_PACKET_NUMBER; + const size_t kAckBlockLengthOffset3 = kGapToNextBlockOffset3 + 1; + const size_t kGapToNextBlockOffset4 = + kAckBlockLengthOffset3 + PACKET_2BYTE_PACKET_NUMBER; + const size_t kAckBlockLengthOffset4 = kGapToNextBlockOffset3 + 1; + const size_t kTimestampDeltaLargestObserved1 = + kNumTimestampsOffset + kQuicNumTimestampsSize; + const size_t kTimestampTimeDeltaLargestObserved1 = + kTimestampDeltaLargestObserved1 + 1; + const size_t kTimestampDeltaLargestObserved2 = + kTimestampTimeDeltaLargestObserved1 + 4; + const size_t kTimestampTimeDeltaLargestObserved2 = + kTimestampDeltaLargestObserved2 + 1; + if (i < kNumTimestampsOffset) { + expected_error = "Unable to read num of ack blocks."; + } else if (i < kLargestAckedOffset) { + expected_error = "Unable to read num received packets."; + } else if (i < kLargestAckedDeltaTimeOffset) { + expected_error = "Unable to read largest acked."; + } else if (i < kFirstAckBlockLengthOffset) { + expected_error = "Unable to read ack delay time."; + } else if (i < kGapToNextBlockOffset1) { + expected_error = "Unable to read first ack block length."; + } else if (i < kAckBlockLengthOffset1) { + expected_error = "Unable to read gap to next ack block."; + } else if (i < kGapToNextBlockOffset2) { + expected_error = "Unable to ack block length."; + } else if (i < kAckBlockLengthOffset2) { + expected_error = "Unable to read gap to next ack block."; + } else if (i < kGapToNextBlockOffset3) { + expected_error = "Unable to ack block length."; + } else if (i < kAckBlockLengthOffset3) { + expected_error = "Unable to read gap to next ack block."; + } else if (i < kGapToNextBlockOffset4) { + expected_error = "Unable to ack block length."; + } else if (i < kAckBlockLengthOffset4) { + expected_error = "Unable to read gap to next ack block."; + } else if (i < kNumTimestampsOffset) { + expected_error = "Unable to ack block length."; + } else if (i < kTimestampDeltaLargestObserved1) { + expected_error = "Unable to read num received packets."; + } else if (i < kTimestampTimeDeltaLargestObserved1) { + expected_error = "Unable to read sequence delta in received packets."; + } else if (i < kTimestampDeltaLargestObserved2) { + expected_error = "Unable to read time delta in received packets."; + } else if (i < kTimestampTimeDeltaLargestObserved2) { + expected_error = "Unable to read sequence delta in received packets."; + } else { + expected_error = + "Unable to read incremental time delta in received packets."; + } } CheckProcessingFails( @@ -3799,14 +4013,14 @@ // frame type (ack frame) // (no ack blocks, 2 byte largest observed, 2 byte block length) 0xA5, + // num timestamps. + 0x00, // largest acked 0x12, 0x34, // Zero delta time. 0x00, 0x00, // first ack block length. 0x12, 0x34, - // num timestamps. - 0x00, }; // clang-format on unsigned char* p = packet; @@ -3823,6 +4037,101 @@ arraysize(packet)); } +TEST_P(QuicFramerTest, BuildAckFramePacketOneAckBlockMaxLength) { + QuicPacketHeader header; + header.public_header.connection_id = kConnectionId; + header.public_header.reset_flag = false; + header.public_header.version_flag = false; + header.packet_number = kPacketNumber; + + QuicAckFrame ack_frame; + FLAGS_quic_reloadable_flag_quic_frames_deque2 = true; + ack_frame.largest_observed = kPacketNumber; + ack_frame.ack_delay_time = QuicTime::Delta::Zero(); + ack_frame.packets.AddRange(1, kPacketNumber + 1); + + QuicFrames frames = {QuicFrame(&ack_frame)}; + + // clang-format off + unsigned char packet[] = { + // public flags (8 byte connection_id) + 0x38, + // connection_id + 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, + // packet number + 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, + + // frame type (ack frame) + // (no ack blocks, 6 byte largest observed, 6 byte block length) + 0x4F, + // largest acked + 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, + // Zero delta time. + 0x00, 0x00, + // first ack block length. + 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, + // num timestamps. + 0x00, + }; + + unsigned char packet39[] = { + // public flags (8 byte connection_id) + 0x38, + // connection_id + 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, + // packet number + 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, + + // frame type (ack frame) + // (no ack blocks, 6 byte largest observed, 6 byte block length) + 0x4F, + // largest acked + 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, + // Zero delta time. + 0x00, 0x00, + // first ack block length. + 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, + // num timestamps. + 0x00, + }; + + unsigned char packet40[] = { + // public flags (8 byte connection_id) + 0x38, + // connection_id + 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, + // packet number + 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, + + // frame type (ack frame) + // (no ack blocks, 8 byte largest observed, 8 byte block length) + 0xAF, + // num timestamps. + 0x00, + // largest acked + 0x00, 0x00, 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, + // Zero delta time. + 0x00, 0x00, + // first ack block length. + 0x00, 0x00, 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, + }; + // clang-format on + unsigned char* p = packet; + size_t packet_size = arraysize(packet); + if (framer_.version() > QUIC_VERSION_39) { + p = packet40; + packet_size = arraysize(packet40); + } else if (framer_.version() > QUIC_VERSION_38) { + p = packet39; + packet_size = arraysize(packet39); + } + + std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames)); + ASSERT_TRUE(data != nullptr); + test::CompareCharArraysWithHexError("constructed packet", data->data(), + data->length(), AsChars(p), packet_size); +} + TEST_P(QuicFramerTest, BuildAckFramePacketMultipleAckBlocks) { QuicPacketHeader header; header.public_header.connection_id = kConnectionId; @@ -3932,12 +4241,14 @@ // frame type (ack frame) // (has ack blocks, 2 byte largest observed, 2 byte block length) 0xB5, + // num ack blocks ranges. + 0x04, + // num timestamps. + 0x00, // largest acked 0x12, 0x34, // Zero delta time. 0x00, 0x00, - // num ack blocks ranges. - 0x04, // first ack block length. 0x00, 0x01, // gap to next block. @@ -3956,8 +4267,6 @@ 0x05, // ack block length. 0x00, 0x04, - // num timestamps. - 0x00, }; // clang-format on unsigned char* p = packet; @@ -4191,12 +4500,14 @@ // frame type (ack frame) // (has ack blocks, 2 byte largest observed, 2 byte block length) 0xB5, + // num ack blocks ranges. + 0xff, + // num timestamps. + 0x00, // largest acked 0x12, 0x34, // Zero delta time. 0x00, 0x00, - // num ack blocks ranges. - 0xff, // first ack block length. 0x0f, 0xdd, // 255 = 4 * 63 + 3 @@ -4270,8 +4581,6 @@ 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, - // num timestamps. - 0x00, }; // clang-format on unsigned char* p = packet;
diff --git a/net/quic/core/quic_packet_creator.cc b/net/quic/core/quic_packet_creator.cc index cd4993c..a3ed7ee 100644 --- a/net/quic/core/quic_packet_creator.cc +++ b/net/quic/core/quic_packet_creator.cc
@@ -116,7 +116,7 @@ packet_.packet_number + 1 - least_packet_awaited_by_peer; const uint64_t delta = std::max(current_delta, max_packets_in_flight); packet_.packet_number_length = - QuicFramer::GetMinPacketNumberLength(delta * 4); + QuicFramer::GetMinPacketNumberLength(framer_->version(), delta * 4); } bool QuicPacketCreator::ConsumeData(QuicStreamId id,
diff --git a/net/quic/core/quic_packet_creator_test.cc b/net/quic/core/quic_packet_creator_test.cc index e09e5ff..c5a3c63 100644 --- a/net/quic/core/quic_packet_creator_test.cc +++ b/net/quic/core/quic_packet_creator_test.cc
@@ -51,7 +51,7 @@ framer_has_data_producer(framer_has_data_producer) {} friend std::ostream& operator<<(std::ostream& os, const TestParams& p) { - os << "{ client_version: " << QuicVersionToString(p.version) + os << "{ version: " << QuicVersionToString(p.version) << " connection id length: " << p.connection_id_length << " include version: " << p.version_serialization << " framer_has_data_producer: " << p.framer_has_data_producer << " }"; @@ -735,8 +735,13 @@ QuicPacketCreatorPeer::SetPacketNumber(&creator_, UINT64_C(64) * 256 * 256 * 256 * 256); creator_.UpdatePacketNumberLength(2, 10000 / kDefaultMaxPacketSize); - EXPECT_EQ(PACKET_6BYTE_PACKET_NUMBER, - QuicPacketCreatorPeer::GetPacketNumberLength(&creator_)); + if (GetParam().version <= QUIC_VERSION_39) { + EXPECT_EQ(PACKET_6BYTE_PACKET_NUMBER, + QuicPacketCreatorPeer::GetPacketNumberLength(&creator_)); + } else { + EXPECT_EQ(PACKET_8BYTE_PACKET_NUMBER, + QuicPacketCreatorPeer::GetPacketNumberLength(&creator_)); + } } TEST_P(QuicPacketCreatorTest, UpdatePacketSequenceNumberLengthCwnd) { @@ -758,8 +763,13 @@ creator_.UpdatePacketNumberLength( 1, UINT64_C(1000) * 256 * 256 * 256 * 256 / kDefaultMaxPacketSize); - EXPECT_EQ(PACKET_6BYTE_PACKET_NUMBER, - QuicPacketCreatorPeer::GetPacketNumberLength(&creator_)); + if (GetParam().version <= QUIC_VERSION_39) { + EXPECT_EQ(PACKET_6BYTE_PACKET_NUMBER, + QuicPacketCreatorPeer::GetPacketNumberLength(&creator_)); + } else { + EXPECT_EQ(PACKET_8BYTE_PACKET_NUMBER, + QuicPacketCreatorPeer::GetPacketNumberLength(&creator_)); + } } TEST_P(QuicPacketCreatorTest, SerializeFrame) {
diff --git a/net/quic/core/quic_packet_generator.cc b/net/quic/core/quic_packet_generator.cc index 2c36419..8f1e372 100644 --- a/net/quic/core/quic_packet_generator.cc +++ b/net/quic/core/quic_packet_generator.cc
@@ -9,6 +9,8 @@ #include "net/quic/core/crypto/quic_random.h" #include "net/quic/core/quic_utils.h" #include "net/quic/platform/api/quic_bug_tracker.h" +#include "net/quic/platform/api/quic_flag_utils.h" +#include "net/quic/platform/api/quic_flags.h" #include "net/quic/platform/api/quic_logging.h" namespace net { @@ -131,6 +133,7 @@ } if (run_fast_path) { + QUIC_FLAG_COUNT(quic_reloadable_flag_quic_consuming_data_faster); return ConsumeDataFastPath(id, iov, offset, state != NO_FIN, total_bytes_consumed, std::move(ack_listener)); }
diff --git a/net/quic/core/quic_packet_generator_test.cc b/net/quic/core/quic_packet_generator_test.cc index 5e7acc58..2e5c8fba 100644 --- a/net/quic/core/quic_packet_generator_test.cc +++ b/net/quic/core/quic_packet_generator_test.cc
@@ -173,7 +173,7 @@ creator_->SetEncrypter(ENCRYPTION_FORWARD_SECURE, new NullEncrypter(Perspective::IS_CLIENT)); creator_->set_encryption_level(ENCRYPTION_FORWARD_SECURE); - if (FLAGS_quic_reloadable_flag_quic_save_data_before_consumption) { + if (FLAGS_quic_reloadable_flag_quic_save_data_before_consumption2) { framer_.set_data_producer(&producer_); } }
diff --git a/net/quic/core/quic_server_session_base.cc b/net/quic/core/quic_server_session_base.cc index a7ba3ec6..2a352ca8 100644 --- a/net/quic/core/quic_server_session_base.cc +++ b/net/quic/core/quic_server_session_base.cc
@@ -194,7 +194,6 @@ } bool QuicServerSessionBase::ShouldCreateIncomingDynamicStream(QuicStreamId id) { - DCHECK(!FLAGS_quic_reloadable_flag_quic_refactor_stream_creation); if (!connection()->connected()) { QUIC_BUG << "ShouldCreateIncomingDynamicStream called when disconnected"; return false; @@ -211,7 +210,6 @@ } bool QuicServerSessionBase::ShouldCreateOutgoingDynamicStream() { - DCHECK(!FLAGS_quic_reloadable_flag_quic_refactor_stream_creation); if (!connection()->connected()) { QUIC_BUG << "ShouldCreateOutgoingDynamicStream called when disconnected"; return false;
diff --git a/net/quic/core/quic_server_session_base_test.cc b/net/quic/core/quic_server_session_base_test.cc index 3758855..8182bd6 100644 --- a/net/quic/core/quic_server_session_base_test.cc +++ b/net/quic/core/quic_server_session_base_test.cc
@@ -80,8 +80,6 @@ ~TestServerSession() override { delete connection(); }; protected: - // TODO(ckrasic) - for two below, remove when - // quic_reloadable_flag_quic_refactor_stream_creation is deprecated. QuicSpdyStream* CreateIncomingDynamicStream(QuicStreamId id) override { if (!ShouldCreateIncomingDynamicStream(id)) { return nullptr; @@ -104,10 +102,6 @@ return stream; } - std::unique_ptr<QuicStream> CreateStream(QuicStreamId id) override { - return QuicMakeUnique<QuicSimpleServerStream>(id, this, response_cache_); - } - QuicCryptoServerStreamBase* CreateQuicCryptoServerStream( const QuicCryptoServerConfig* crypto_config, QuicCompressedCertsCache* compressed_certs_cache) override { @@ -357,15 +351,9 @@ TEST_P(QuicServerSessionBaseTest, GetStreamDisconnected) { // Don't create new streams if the connection is disconnected. QuicConnectionPeer::TearDownLocalConnectionState(connection_); - if (FLAGS_quic_reloadable_flag_quic_refactor_stream_creation) { - EXPECT_EQ(nullptr, QuicServerSessionBasePeer::GetOrCreateDynamicStream( - session_.get(), GetNthClientInitiatedId(0))); - } else { - EXPECT_QUIC_BUG( - QuicServerSessionBasePeer::GetOrCreateDynamicStream( - session_.get(), GetNthClientInitiatedId(0)), - "ShouldCreateIncomingDynamicStream called when disconnected"); - } + EXPECT_QUIC_BUG(QuicServerSessionBasePeer::GetOrCreateDynamicStream( + session_.get(), GetNthClientInitiatedId(0)), + "ShouldCreateIncomingDynamicStream called when disconnected"); } class MockQuicCryptoServerStream : public QuicCryptoServerStream {
diff --git a/net/quic/core/quic_session.cc b/net/quic/core/quic_session.cc index 295bc40..f2da800 100644 --- a/net/quic/core/quic_session.cc +++ b/net/quic/core/quic_session.cc
@@ -10,6 +10,7 @@ #include "net/quic/core/quic_connection.h" #include "net/quic/core/quic_flow_controller.h" #include "net/quic/platform/api/quic_bug_tracker.h" +#include "net/quic/platform/api/quic_flag_utils.h" #include "net/quic/platform/api/quic_flags.h" #include "net/quic/platform/api/quic_logging.h" #include "net/quic/platform/api/quic_map_util.h" @@ -45,12 +46,11 @@ perspective() == Perspective::IS_SERVER, nullptr), currently_writing_stream_id_(0), - respect_goaway_(true), use_stream_notifier_( FLAGS_quic_reloadable_flag_quic_use_stream_notifier2), save_data_before_consumption_( use_stream_notifier_ && - FLAGS_quic_reloadable_flag_quic_save_data_before_consumption) {} + FLAGS_quic_reloadable_flag_quic_save_data_before_consumption2) {} void QuicSession::Initialize() { connection_->set_visitor(this); @@ -744,11 +744,6 @@ if (!MaybeIncreaseLargestPeerStreamId(stream_id)) { return nullptr; } - - if (FLAGS_quic_reloadable_flag_quic_refactor_stream_creation) { - return MaybeCreateIncomingDynamicStream(stream_id); - } - // Check if the new number of open streams would cause the number of // open streams to exceed the limit. if (GetNumOpenIncomingStreams() >= max_open_incoming_streams()) { @@ -895,78 +890,6 @@ return id % 2 != next_outgoing_stream_id_ % 2; } -bool QuicSession::ShouldCreateIncomingDynamicStream2(QuicStreamId id) { - DCHECK(FLAGS_quic_reloadable_flag_quic_refactor_stream_creation); - if (goaway_received() && respect_goaway_) { - QUIC_DLOG(INFO) << "Failed to create a new outgoing stream. " - << "Already received goaway."; - return false; - } - if (!IsIncomingStream(id)) { - QUIC_DLOG(INFO) << "invalid incoming stream id: " << id; - return false; - } - if (!connection()->connected()) { - QUIC_DLOG(INFO) - << "ShouldCreateIncomingDynamicStream called when disconnected"; - return false; - } - if (GetNumOpenIncomingStreams() >= max_open_incoming_streams()) { - DVLOG(1) << "Reset stream (refused) " << id; - SendRstStream(id, QUIC_REFUSED_STREAM, 0); - return false; - } - - return true; -} - -bool QuicSession::ShouldCreateOutgoingDynamicStream2() { - DCHECK(FLAGS_quic_reloadable_flag_quic_refactor_stream_creation); - if (!connection()->connected()) { - QUIC_DLOG(INFO) - << "ShouldCreateOutgoingDynamicStream called when disconnected"; - return false; - } - if (!IsEncryptionEstablished()) { - QUIC_DLOG(INFO) << "Encryption not established so no outgoing stream " - << "created."; - return false; - } - if (goaway_received() && respect_goaway_) { - QUIC_DLOG(INFO) << "Failed to create a new outgoing stream. " - << "Already received goaway."; - return false; - } - if (GetNumOpenOutgoingStreams() >= max_open_outgoing_streams()) { - QUIC_DLOG(INFO) << "Failed to create a new outgoing stream. " - << "Already " << GetNumOpenOutgoingStreams() << " open."; - return false; - } - return true; -} - -QuicStream* QuicSession::MaybeCreateIncomingDynamicStream(QuicStreamId id) { - if (!ShouldCreateIncomingDynamicStream2(id)) { - return nullptr; - } - return CreateAndActivateStream(id); -} - -QuicStream* QuicSession::MaybeCreateOutgoingDynamicStream( - SpdyPriority priority) { - if (!ShouldCreateOutgoingDynamicStream2()) { - return nullptr; - } - return CreateAndActivateStream(GetNextOutgoingStreamId()); -} - -QuicStream* QuicSession::CreateAndActivateStream(QuicStreamId id) { - std::unique_ptr<QuicStream> stream = CreateStream(id); - QuicStream* stream_ptr = stream.get(); - ActivateStream(std::move(stream)); - return stream_ptr; -} - void QuicSession::OnStreamDoneWaitingForAcks(QuicStreamId id) { auto it = zombie_streams_.find(id); if (it == zombie_streams_.end()) { @@ -1025,6 +948,7 @@ ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET); return; } + QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_use_stream_notifier2, 3, 3); stream->OnStreamFrameDiscarded(frame); }
diff --git a/net/quic/core/quic_session.h b/net/quic/core/quic_session.h index 2f0e403..839668c5 100644 --- a/net/quic/core/quic_session.h +++ b/net/quic/core/quic_session.h
@@ -270,10 +270,6 @@ // Returns true if this stream should yield writes to another blocked stream. bool ShouldYield(QuicStreamId stream_id); - void set_respect_goaway(bool respect_goaway) { - respect_goaway_ = respect_goaway; - } - bool use_stream_notifier() const { return use_stream_notifier_; } bool save_data_before_consumption() const { @@ -291,28 +287,6 @@ using ZombieStreamMap = QuicSmallMap<QuicStreamId, std::unique_ptr<QuicStream>, 10>; - // TODO(ckrasic) - For all *DynamicStream2 below, rename after - // quic_reloadable_flag_quic_refactor_stream_creation is deprecated. - - // Returns true if an incoming stream can be created. - virtual bool ShouldCreateIncomingDynamicStream2(QuicStreamId id); - - // Returns true if an outgoing stream can be created. - virtual bool ShouldCreateOutgoingDynamicStream2(); - - // Creates a new stream to handle a peer-initiated stream. - // Caller does not own the returned stream. - // Returns nullptr and does error handling if the stream can not be created. - virtual QuicStream* MaybeCreateIncomingDynamicStream(QuicStreamId id); - - // Create a new stream to handle a locally-initiated stream. - // Caller does not own the returned stream. - // Returns nullptr if max streams have already been opened. - virtual QuicStream* MaybeCreateOutgoingDynamicStream(SpdyPriority priority); - - // TODO(ckrasic) - For all Create*DynamicStream below, remove when - // quic_reloadable_flag_quic_refactor_stream_creation is deprecated. - // Creates a new stream to handle a peer-initiated stream. // Caller does not own the returned stream. // Returns nullptr and does error handling if the stream can not be created. @@ -358,14 +332,6 @@ // Return true if given stream is peer initiated. bool IsIncomingStream(QuicStreamId id) const; - // Unconditionally creates a stream. Subclasses should use this to - // provide streams appropriately subclassed from |QuicStream|, - // e.g. |QuicSpdySession::CreateStream()| creates a |QuicSpdyStream|. - virtual std::unique_ptr<QuicStream> CreateStream(QuicStreamId id) = 0; - - // Creates a stream and activates it, owned by the session. - QuicStream* CreateAndActivateStream(QuicStreamId id); - StaticStreamMap& static_streams() { return static_stream_map_; } const StaticStreamMap& static_streams() const { return static_stream_map_; } @@ -424,8 +390,6 @@ virtual void HandleRstOnValidNonexistentStream( const QuicRstStreamFrame& frame); - bool respect_goaway() const { return respect_goaway_; } - private: friend class test::QuicSessionPeer; @@ -519,11 +483,6 @@ // call stack of OnCanWrite. QuicStreamId currently_writing_stream_id_; - // If this is set to false, the session will ignore peer GOAWAYs and - // allow the creation of outgoing streams regardless of the high - // chance they will fail. - bool respect_goaway_; - // This session is notified on every ack or loss. const bool use_stream_notifier_;
diff --git a/net/quic/core/quic_session_test.cc b/net/quic/core/quic_session_test.cc index 928e15a..11f2d25 100644 --- a/net/quic/core/quic_session_test.cc +++ b/net/quic/core/quic_session_test.cc
@@ -77,10 +77,6 @@ session()->OnCryptoHandshakeEvent(QuicSession::HANDSHAKE_CONFIRMED); } - void set_encryption_established(bool value) { - encryption_established_ = value; - } - // QuicCryptoStream implementation bool encryption_established() const override { return encryption_established_; @@ -188,15 +184,6 @@ bool ShouldCreateOutgoingDynamicStream() override { return true; } - TestStream* MaybeCreateOutgoingDynamicStream(SpdyPriority priority) override { - return static_cast<TestStream*>( - QuicSpdySession::MaybeCreateOutgoingDynamicStream(priority)); - } - - std::unique_ptr<QuicStream> CreateStream(QuicStreamId id) override { - return QuicMakeUnique<TestStream>(id, this); - } - bool IsClosedStream(QuicStreamId id) { return QuicSession::IsClosedStream(id); } @@ -305,9 +292,6 @@ "EFFlEYHsBQ98rXImL8ySDycdLEFvBPdtctPmWCfTxwmoSMLHU2SCVDhbqMWU5b0yr" "JBCScs_ejbKaqBDoB7ZGxTvqlrB__2ZmnHHjCr8RgMRtKNtIeuZAo "; connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1)); - if (FLAGS_quic_reloadable_flag_quic_refactor_stream_creation) { - session_.GetMutableCryptoStream()->set_encryption_established(true); - } } void CheckClosedStreams() {
diff --git a/net/quic/core/quic_spdy_session.cc b/net/quic/core/quic_spdy_session.cc index d98e710..0bdb240d 100644 --- a/net/quic/core/quic_spdy_session.cc +++ b/net/quic/core/quic_spdy_session.cc
@@ -803,20 +803,4 @@ error, details, ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET); } -QuicSpdyStream* QuicSpdySession::MaybeCreateIncomingDynamicStream( - QuicStreamId id) { - return static_cast<QuicSpdyStream*>( - QuicSession::MaybeCreateIncomingDynamicStream(id)); -} - -QuicSpdyStream* QuicSpdySession::MaybeCreateOutgoingDynamicStream( - SpdyPriority priority) { - auto* stream = static_cast<QuicSpdyStream*>( - QuicSession::MaybeCreateOutgoingDynamicStream(priority)); - if (stream) { - stream->SetPriority(priority); - } - return stream; -} - } // namespace net
diff --git a/net/quic/core/quic_spdy_session.h b/net/quic/core/quic_spdy_session.h index 5f56842..ae446f4 100644 --- a/net/quic/core/quic_spdy_session.h +++ b/net/quic/core/quic_spdy_session.h
@@ -148,8 +148,6 @@ // aggressively. virtual bool ShouldReleaseHeadersStreamSequencerBuffer(); - SpdyFramer* spdy_framer() { return &spdy_framer_; } - void CloseConnectionWithDetails(QuicErrorCode error, const std::string& details); @@ -169,9 +167,6 @@ } protected: - // TODO(ckrasic) - remove these two when - // FLAGS_quic_reloadable_flag_quic_refactor_stream_creation is - // deprecated. // Override CreateIncomingDynamicStream() and CreateOutgoingDynamicStream() // with QuicSpdyStream return type to make sure that all data streams are // QuicSpdyStreams. @@ -179,16 +174,8 @@ QuicSpdyStream* CreateOutgoingDynamicStream(SpdyPriority priority) override = 0; - QuicSpdyStream* MaybeCreateIncomingDynamicStream(QuicStreamId id) override; - QuicSpdyStream* MaybeCreateOutgoingDynamicStream( - SpdyPriority priority) override; - QuicSpdyStream* GetSpdyDataStream(const QuicStreamId stream_id); - // TODO(ckrasic) - remove these two when - // FLAGS_quic_reloadable_flag_quic_refactor_stream_creation is - // depreacted. - // If an incoming stream can be created, return true. virtual bool ShouldCreateIncomingDynamicStream(QuicStreamId id) = 0;
diff --git a/net/quic/core/quic_stream.cc b/net/quic/core/quic_stream.cc index aaf39371..4afb5c24 100644 --- a/net/quic/core/quic_stream.cc +++ b/net/quic/core/quic_stream.cc
@@ -7,6 +7,7 @@ #include "net/quic/core/quic_flow_controller.h" #include "net/quic/core/quic_session.h" #include "net/quic/platform/api/quic_bug_tracker.h" +#include "net/quic/platform/api/quic_flag_utils.h" #include "net/quic/platform/api/quic_flags.h" #include "net/quic/platform/api/quic_logging.h" @@ -231,6 +232,8 @@ } if (!had_buffered_data && (HasBufferedData() || fin_buffered_)) { // Write data if there is no buffered data before. + QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_save_data_before_consumption2, + 2, 4); WriteBufferedData(); } return; @@ -260,6 +263,8 @@ return; } if (HasBufferedData() || (fin_buffered_ && !fin_sent_)) { + QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_save_data_before_consumption2, + 3, 4); WriteBufferedData(); } if (!fin_buffered_ && !fin_sent_ && CanWriteNewData()) { @@ -363,6 +368,8 @@ if (!had_buffered_data && (HasBufferedData() || fin_buffered_)) { // Write data if there is no buffered data before. + QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_save_data_before_consumption2, + 1, 4); WriteBufferedData(); } @@ -586,12 +593,14 @@ QuicTime::Delta ack_delay_time) { OnStreamFrameDiscarded(frame); if (ack_listener_ != nullptr) { + QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_use_stream_notifier2, 1, 3); ack_listener_->OnPacketAcked(frame.data_length, ack_delay_time); } } void QuicStream::OnStreamFrameRetransmitted(const QuicStreamFrame& frame) { if (ack_listener_ != nullptr) { + QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_use_stream_notifier2, 2, 3); ack_listener_->OnPacketRetransmitted(frame.data_length); } }
diff --git a/net/quic/core/quic_stream.h b/net/quic/core/quic_stream.h index e315f7ca..be60503 100644 --- a/net/quic/core/quic_stream.h +++ b/net/quic/core/quic_stream.h
@@ -115,15 +115,11 @@ bool fin_sent() { return fin_sent_; } // TODO(fayang): Rename this function to BufferedDataBytes() when - // deprecating quic_reloadable_flag_quic_save_data_before_consumption. + // deprecating quic_reloadable_flag_quic_save_data_before_consumption2. uint64_t queued_data_bytes() const; uint64_t stream_bytes_read() const { return stream_bytes_read_; } uint64_t stream_bytes_written() const { return stream_bytes_written_; } - // For tests that override WritevData. - void set_stream_bytes_written(uint64_t bytes_written) { - stream_bytes_written_ = bytes_written; - } size_t busy_counter() const { return busy_counter_; } void set_busy_counter(size_t busy_counter) { busy_counter_ = busy_counter; } @@ -217,12 +213,12 @@ // If |ack_listener| is provided, then it will be notified once all // the ACKs for this write have been received. // Returns the number of bytes consumed by the connection. - // Please note: when quic_reloadable_flag_quic_save_data_before_consumption is - // true, returned consumed data is the amount of data saved in send buffer. + // Please note: when quic_reloadable_flag_quic_save_data_before_consumption2 + // is true, returned consumed data is the amount of data saved in send buffer. // The data is not necessarily consumed by the connection. So write side is // closed when FIN is sent. // TODO(fayang): Let WritevData return boolean when deprecating - // quic_reloadable_flag_quic_save_data_before_consumption. + // quic_reloadable_flag_quic_save_data_before_consumption2. QuicConsumedData WritevData( const struct iovec* iov, int iov_count, @@ -309,13 +305,13 @@ // Write buffered data in send buffer. TODO(fayang): Consider combine // WriteOrBufferData, Writev and WriteBufferedData when deprecating - // quic_reloadable_flag_quic_save_data_before_consumption. + // quic_reloadable_flag_quic_save_data_before_consumption2. void WriteBufferedData(); std::list<PendingData> queued_data_; // How many bytes are queued? // TODO(fayang): Remove this variable when deprecating - // quic_reloadable_flag_quic_save_data_before_consumption. + // quic_reloadable_flag_quic_save_data_before_consumption2. uint64_t queued_data_bytes_; QuicStreamSequencer sequencer_;
diff --git a/net/quic/core/quic_stream_sequencer_test.cc b/net/quic/core/quic_stream_sequencer_test.cc index f65394d..8ca75ff1 100644 --- a/net/quic/core/quic_stream_sequencer_test.cc +++ b/net/quic/core/quic_stream_sequencer_test.cc
@@ -27,8 +27,6 @@ using testing::AnyNumber; using testing::CreateFunctor; using testing::InSequence; -using testing::Return; -using testing::StrEq; namespace net { namespace test { @@ -43,7 +41,6 @@ void(QuicErrorCode error, const string& details)); MOCK_METHOD1(Reset, void(QuicRstStreamErrorCode error)); MOCK_METHOD0(OnCanWrite, void()); - virtual bool IsFlowControlEnabled() const { return true; } const QuicSocketAddress& PeerAddressOfLatestPacket() const override { return peer_address_;
diff --git a/net/quic/core/quic_stream_test.cc b/net/quic/core/quic_stream_test.cc index 1a71b8d5b..77164b0 100644 --- a/net/quic/core/quic_stream_test.cc +++ b/net/quic/core/quic_stream_test.cc
@@ -48,17 +48,10 @@ class TestStream : public QuicStream { public: TestStream(QuicStreamId id, QuicSession* session, bool should_process_data) - : QuicStream(id, session), should_process_data_(should_process_data) {} + : QuicStream(id, session) {} void OnDataAvailable() override {} - uint32_t ProcessRawData(const char* data, uint32_t data_len) { - EXPECT_NE(0u, data_len); - QUIC_DVLOG(1) << "ProcessData data_len: " << data_len; - data_ += string(data, data_len); - return should_process_data_ ? data_len : 0; - } - MOCK_METHOD0(OnCanWriteNewData, void()); using QuicStream::CanWriteNewData; @@ -68,7 +61,6 @@ using QuicStream::OnClose; private: - bool should_process_data_; string data_; };
diff --git a/net/quic/core/quic_time.h b/net/quic/core/quic_time.h index 18ef46f..2bbdc180 100644 --- a/net/quic/core/quic_time.h +++ b/net/quic/core/quic_time.h
@@ -206,9 +206,6 @@ inline bool operator>=(QuicTime::Delta lhs, QuicTime::Delta rhs) { return !(lhs < rhs); } -inline QuicTime::Delta operator<<(QuicTime::Delta lhs, size_t rhs) { - return QuicTime::Delta(lhs.time_offset_ << rhs); -} inline QuicTime::Delta operator>>(QuicTime::Delta lhs, size_t rhs) { return QuicTime::Delta(lhs.time_offset_ >> rhs); }
diff --git a/net/quic/core/quic_types.h b/net/quic/core/quic_types.h index eab0bc8..f7e9f9a 100644 --- a/net/quic/core/quic_types.h +++ b/net/quic/core/quic_types.h
@@ -140,7 +140,9 @@ PACKET_1BYTE_PACKET_NUMBER = 1, PACKET_2BYTE_PACKET_NUMBER = 2, PACKET_4BYTE_PACKET_NUMBER = 4, - PACKET_6BYTE_PACKET_NUMBER = 6 + // TODO(rch): Remove this when we remove QUIC_VERSION_39. + PACKET_6BYTE_PACKET_NUMBER = 6, + PACKET_8BYTE_PACKET_NUMBER = 8 }; // Used to indicate a QuicSequenceNumberLength using two flag bits. @@ -148,7 +150,7 @@ PACKET_FLAGS_1BYTE_PACKET = 0, // 00 PACKET_FLAGS_2BYTE_PACKET = 1, // 01 PACKET_FLAGS_4BYTE_PACKET = 1 << 1, // 10 - PACKET_FLAGS_6BYTE_PACKET = 1 << 1 | 1, // 11 + PACKET_FLAGS_8BYTE_PACKET = 1 << 1 | 1, // 11 }; // The public flags are specified in one byte. @@ -180,7 +182,7 @@ PACKET_PUBLIC_FLAGS_1BYTE_PACKET = PACKET_FLAGS_1BYTE_PACKET << 4, PACKET_PUBLIC_FLAGS_2BYTE_PACKET = PACKET_FLAGS_2BYTE_PACKET << 4, PACKET_PUBLIC_FLAGS_4BYTE_PACKET = PACKET_FLAGS_4BYTE_PACKET << 4, - PACKET_PUBLIC_FLAGS_6BYTE_PACKET = PACKET_FLAGS_6BYTE_PACKET << 4, + PACKET_PUBLIC_FLAGS_6BYTE_PACKET = PACKET_FLAGS_8BYTE_PACKET << 4, // Reserved, unimplemented flags:
diff --git a/net/quic/core/quic_versions.h b/net/quic/core/quic_versions.h index 8e5989b..3f9e112 100644 --- a/net/quic/core/quic_versions.h +++ b/net/quic/core/quic_versions.h
@@ -33,7 +33,7 @@ // endian. Dot not ack acks. Send a connection level // WINDOW_UPDATE every 20 sent packets which do not // contain retransmittable frames. - QUIC_VERSION_40 = 40, // RST_STREAM and STREAM_FRAME frame match IETF format. + QUIC_VERSION_40 = 40, // RST_STREAM, ACK and STREAM frames match IETF format. QUIC_VERSION_41 = 41, // Use IETF packet header format. // IMPORTANT: if you are adding to this list, follow the instructions at
diff --git a/net/quic/core/spdy_utils.h b/net/quic/core/spdy_utils.h index cb11c93a..724136af 100644 --- a/net/quic/core/spdy_utils.h +++ b/net/quic/core/spdy_utils.h
@@ -54,8 +54,6 @@ static bool PopulateHeaderBlockFromUrl(const std::string url, SpdyHeaderBlock* headers); - static bool IsServerPushStream(QuicStreamId id) { return id % 2 == 0; } - private: DISALLOW_COPY_AND_ASSIGN(SpdyUtils); };
diff --git a/net/quic/quartc/quartc_session.cc b/net/quic/quartc/quartc_session.cc index 005f123..5136153 100644 --- a/net/quic/quartc/quartc_session.cc +++ b/net/quic/quartc/quartc_session.cc
@@ -294,10 +294,6 @@ return ActivateDataStream(CreateDataStream(id, kDefaultPriority)); } -std::unique_ptr<QuicStream> QuartcSession::CreateStream(QuicStreamId id) { - return CreateDataStream(id, kDefaultPriority); -} - std::unique_ptr<QuartcStream> QuartcSession::CreateDataStream( QuicStreamId id, SpdyPriority priority) {
diff --git a/net/quic/quartc/quartc_session.h b/net/quic/quartc/quartc_session.h index fb2eddb..51311b0 100644 --- a/net/quic/quartc/quartc_session.h +++ b/net/quic/quartc/quartc_session.h
@@ -99,7 +99,6 @@ protected: // QuicSession override. QuicStream* CreateIncomingDynamicStream(QuicStreamId id) override; - std::unique_ptr<QuicStream> CreateStream(QuicStreamId id) override; std::unique_ptr<QuartcStream> CreateDataStream(QuicStreamId id, SpdyPriority priority);
diff --git a/net/quic/quartc/quartc_stream_test.cc b/net/quic/quartc/quartc_stream_test.cc index 313c771..4413d0c 100644 --- a/net/quic/quartc/quartc_stream_test.cc +++ b/net/quic/quartc/quartc_stream_test.cc
@@ -98,11 +98,6 @@ ActivateStream(std::move(stream)); } - protected: - std::unique_ptr<QuicStream> CreateStream(QuicStreamId id) override { - return nullptr; - } - private: // Stores written data from ReliableQuicStreamAdapter. std::string* write_buffer_;
diff --git a/net/quic/test_tools/quic_test_utils.h b/net/quic/test_tools/quic_test_utils.h index 1f721c8..f84a401c 100644 --- a/net/quic/test_tools/quic_test_utils.h +++ b/net/quic/test_tools/quic_test_utils.h
@@ -471,9 +471,6 @@ ConnectionCloseSource source)); MOCK_METHOD1(CreateIncomingDynamicStream, QuicStream*(QuicStreamId id)); MOCK_METHOD1(CreateOutgoingDynamicStream, QuicStream*(SpdyPriority priority)); - MOCK_METHOD1(MaybeCreateIncomingDynamicStream, QuicStream*(QuicStreamId id)); - MOCK_METHOD1(MaybeCreateOutgoingDynamicStream, - QuicStream*(SpdyPriority priority)); MOCK_METHOD1(ShouldCreateIncomingDynamicStream2, bool(QuicStreamId id)); MOCK_METHOD0(ShouldCreateOutgoingDynamicStream2, bool()); MOCK_METHOD6( @@ -497,7 +494,6 @@ MOCK_METHOD3(OnStreamHeadersComplete, void(QuicStreamId stream_id, bool fin, size_t frame_len)); MOCK_CONST_METHOD0(IsCryptoHandshakeConfirmed, bool()); - MOCK_METHOD1(CreateStream, std::unique_ptr<QuicStream>(QuicStreamId id)); using QuicSession::ActivateStream; @@ -555,7 +551,6 @@ QuicSpdyStream*(SpdyPriority priority)); MOCK_METHOD1(ShouldCreateIncomingDynamicStream, bool(QuicStreamId id)); MOCK_METHOD0(ShouldCreateOutgoingDynamicStream, bool()); - MOCK_METHOD1(CreateStream, std::unique_ptr<QuicStream>(QuicStreamId id)); MOCK_METHOD6( WritevData, QuicConsumedData( @@ -615,24 +610,6 @@ OnStreamFrameData, void(QuicStreamId stream_id, const char* data, size_t len, bool fin)); - QuicSpdyStream* QuicSpdySessionMaybeCreateIncomingDynamicStream( - QuicStreamId id) { - return QuicSpdySession::MaybeCreateIncomingDynamicStream(id); - } - - bool QuicSpdySessionShouldCreateIncomingDynamicStream2(QuicStreamId id) { - return QuicSpdySession::ShouldCreateIncomingDynamicStream2(id); - } - - QuicSpdyStream* QuicSpdySessionMaybeCreateOutgoingDynamicStream( - SpdyPriority priority) { - return QuicSpdySession::MaybeCreateOutgoingDynamicStream(priority); - } - - bool QuicSpdySessionShouldCreateOutgoingDynamicStream2() { - return QuicSpdySession::ShouldCreateOutgoingDynamicStream2(); - } - using QuicSession::ActivateStream; private: @@ -654,7 +631,6 @@ MOCK_METHOD1(CreateIncomingDynamicStream, QuicSpdyStream*(QuicStreamId id)); MOCK_METHOD1(CreateOutgoingDynamicStream, QuicSpdyStream*(SpdyPriority priority)); - MOCK_METHOD1(CreateStream, std::unique_ptr<QuicStream>(QuicStreamId id)); QuicCryptoServerStreamBase* CreateQuicCryptoServerStream( const QuicCryptoServerConfig* crypto_config, QuicCompressedCertsCache* compressed_certs_cache) override; @@ -717,8 +693,6 @@ MOCK_METHOD1(ShouldCreateIncomingDynamicStream, bool(QuicStreamId id)); MOCK_METHOD0(ShouldCreateOutgoingDynamicStream, bool()); - MOCK_METHOD1(CreateStream, std::unique_ptr<QuicStream>(QuicStreamId id)); - QuicCryptoClientStream* GetMutableCryptoStream() override; const QuicCryptoClientStream* GetCryptoStream() const override;
diff --git a/net/socket/socket_posix.cc b/net/socket/socket_posix.cc index 5900a5c..ae9bb1e 100644 --- a/net/socket/socket_posix.cc +++ b/net/socket/socket_posix.cc
@@ -21,6 +21,11 @@ #include "net/base/sockaddr_storage.h" #include "net/base/trace_constants.h" +#if defined(OS_FUCHSIA) +#include <poll.h> +#include <sys/ioctl.h> +#endif // OS_FUCHSIA + namespace net { namespace { @@ -229,6 +234,7 @@ if (socket_fd_ == kInvalidSocket || waiting_connect_) return false; +#if !defined(OS_FUCHSIA) // Checks if connection is alive. char c; int rv = HANDLE_EINTR(recv(socket_fd_, &c, 1, MSG_PEEK)); @@ -238,6 +244,31 @@ return false; return true; + +#else // OS_FUCHSIA + // Fuchsia currently doesn't support MSG_PEEK flag in recv(), so the code + // above doesn't work on Fuchsia. IsConnected() must return true if the + // connection is alive or if it was terminated but there is still data pending + // in the incoming buffer. + // 1. Check if the connection is alive using poll(POLLRDHUP). + // 2. If closed, then use ioctl(FIONREAD) to check if there is data to be + // read. + // TODO(bug 738275): Remove once MSG_PEEK is implemented on Fuchsia. + struct pollfd pollfd; + pollfd.fd = socket_fd_; + pollfd.events = POLLRDHUP; + pollfd.revents = 0; + const int poll_result = HANDLE_EINTR(poll(&pollfd, 1, 0)); + + if (poll_result == 1) { + int bytes_available; + int ioctl_result = + HANDLE_EINTR(ioctl(socket_fd_, FIONREAD, &bytes_available)); + return ioctl_result == 0 && bytes_available > 0; + } + + return poll_result == 0; +#endif // OS_FUCHSIA } bool SocketPosix::IsConnectedAndIdle() const { @@ -246,6 +277,7 @@ if (socket_fd_ == kInvalidSocket || waiting_connect_) return false; +#if !defined(OS_FUCHSIA) // Check if connection is alive and we haven't received any data // unexpectedly. char c; @@ -256,6 +288,21 @@ return false; return true; + +#else // OS_FUCHSIA + // Fuchsia currently doesn't support MSG_PEEK flag in recv(), so the code + // above doesn't work on Fuchsia. Use poll(POLLIN) to check state of the + // socket. POLLIN is signaled if the socket is readable or if it was closed by + // the peer, i.e. the socket is connected and idle if and only if POLLIN is + // not signaled. + // TODO(bug 738275): Remove once MSG_PEEK is implemented. + struct pollfd pollfd; + pollfd.fd = socket_fd_; + pollfd.events = POLLIN; + pollfd.revents = 0; + const int poll_result = HANDLE_EINTR(poll(&pollfd, 1, 0)); + return poll_result == 0; +#endif // OS_FUCHSIA } int SocketPosix::Read(IOBuffer* buf,
diff --git a/net/socket/stream_socket.h b/net/socket/stream_socket.h index cb979b6..6ee0e40a 100644 --- a/net/socket/stream_socket.h +++ b/net/socket/stream_socket.h
@@ -68,12 +68,14 @@ virtual void Disconnect() = 0; // Called to test if the connection is still alive. Returns false if a - // connection wasn't established or the connection is dead. + // connection wasn't established or the connection is dead. True is returned + // if the connection was terminated, but there is unread data in the incoming + // buffer. virtual bool IsConnected() const = 0; // Called to test if the connection is still alive and idle. Returns false - // if a connection wasn't established, the connection is dead, or some data - // have been received. + // if a connection wasn't established, the connection is dead, or there is + // unread data in the incoming buffer. virtual bool IsConnectedAndIdle() const = 0; // Copies the peer address to |address| and returns a network error code.
diff --git a/net/socket/udp_socket_win.h b/net/socket/udp_socket_win.h index d7f8419..150e72e 100644 --- a/net/socket/udp_socket_win.h +++ b/net/socket/udp_socket_win.h
@@ -34,8 +34,7 @@ class NetLog; struct NetLogSource; -class NET_EXPORT UDPSocketWin - : NON_EXPORTED_BASE(public base::win::ObjectWatcher::Delegate) { +class NET_EXPORT UDPSocketWin : public base::win::ObjectWatcher::Delegate { public: UDPSocketWin(DatagramSocket::BindType bind_type, const RandIntCallback& rand_int_cb,
diff --git a/net/spdy/core/spdy_protocol.h b/net/spdy/core/spdy_protocol.h index af3686e..890fa09 100644 --- a/net/spdy/core/spdy_protocol.h +++ b/net/spdy/core/spdy_protocol.h
@@ -439,7 +439,7 @@ // Abstract class intended to be inherited by IRs that contain a header // block. Implies SpdyFrameWithFinIR. class SPDY_EXPORT_PRIVATE SpdyFrameWithHeaderBlockIR - : public NON_EXPORTED_BASE(SpdyFrameWithFinIR) { + : public SpdyFrameWithFinIR { public: ~SpdyFrameWithHeaderBlockIR() override; @@ -465,8 +465,7 @@ DISALLOW_COPY_AND_ASSIGN(SpdyFrameWithHeaderBlockIR); }; -class SPDY_EXPORT_PRIVATE SpdyDataIR - : public NON_EXPORTED_BASE(SpdyFrameWithFinIR) { +class SPDY_EXPORT_PRIVATE SpdyDataIR : public SpdyFrameWithFinIR { public: // Performs a deep copy on data. SpdyDataIR(SpdyStreamId stream_id, SpdyStringPiece data);
diff --git a/net/tools/quic/end_to_end_test.cc b/net/tools/quic/end_to_end_test.cc index 9409dae..185566be 100644 --- a/net/tools/quic/end_to_end_test.cc +++ b/net/tools/quic/end_to_end_test.cc
@@ -605,7 +605,6 @@ size_t chlo_multiplier_; QuicTestServer::StreamFactory* stream_factory_; bool support_server_push_; - bool force_hol_blocking_; }; // Run all end to end tests with all supported versions. @@ -619,16 +618,14 @@ QuicCryptoStream* crypto_stream = QuicSessionPeer::GetMutableCryptoStream( client_->client()->client_session()); QuicStreamSequencer* sequencer = QuicStreamPeer::sequencer(crypto_stream); - EXPECT_NE(FLAGS_quic_reloadable_flag_quic_release_crypto_stream_buffer, - QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(sequencer)); + EXPECT_FALSE(QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(sequencer)); server_thread_->Pause(); QuicDispatcher* dispatcher = QuicServerPeer::GetDispatcher(server_thread_->server()); QuicSession* server_session = dispatcher->session_map().begin()->second.get(); crypto_stream = QuicSessionPeer::GetMutableCryptoStream(server_session); sequencer = QuicStreamPeer::sequencer(crypto_stream); - EXPECT_NE(FLAGS_quic_reloadable_flag_quic_release_crypto_stream_buffer, - QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(sequencer)); + EXPECT_FALSE(QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(sequencer)); } TEST_P(EndToEndTest, SimpleRequestResponsev6) { @@ -1549,25 +1546,6 @@ EXPECT_EQ(QUIC_NO_ERROR, client_->connection_error()); } -class WrongAddressWriter : public QuicPacketWriterWrapper { - public: - WrongAddressWriter() { self_address_.FromString("127.0.0.2"); } - - WriteResult WritePacket(const char* buffer, - size_t buf_len, - const QuicIpAddress& /*real_self_address*/, - const QuicSocketAddress& peer_address, - PerPacketOptions* options) override { - // Use wrong address! - return QuicPacketWriterWrapper::WritePacket(buffer, buf_len, self_address_, - peer_address, options); - } - - bool IsWriteBlockedDataBuffered() const override { return false; } - - QuicIpAddress self_address_; -}; - TEST_P(EndToEndTest, ConnectionMigrationClientIPChanged) { ASSERT_TRUE(Initialize()); EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo")); @@ -2451,9 +2429,6 @@ return QuicMakeUnique<ClientStreamThatDropsBody>(GetNextOutgoingStreamId(), this); } - std::unique_ptr<QuicStream> CreateStream(QuicStreamId id) override { - return QuicMakeUnique<ClientStreamThatDropsBody>(id, this); - } }; class MockableQuicClientThatDropsBody : public MockableQuicClient { @@ -2984,7 +2959,8 @@ size_t num_window_update_frames() const { return num_window_update_frames_; } - void OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) override { + void OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame, + const QuicTime& receive_time) override { ++num_window_update_frames_; }
diff --git a/net/tools/quic/quic_dispatcher.cc b/net/tools/quic/quic_dispatcher.cc index 0fec950..23726d6 100644 --- a/net/tools/quic/quic_dispatcher.cc +++ b/net/tools/quic/quic_dispatcher.cc
@@ -115,7 +115,7 @@ helper->GetStreamFrameBufferAllocator(), &collector_), time_wait_list_manager_(time_wait_list_manager) { - if (FLAGS_quic_reloadable_flag_quic_save_data_before_consumption) { + if (FLAGS_quic_reloadable_flag_quic_save_data_before_consumption2) { framer_->set_data_producer(&collector_); } } @@ -156,6 +156,8 @@ QuicIOVector iov(&iovec, 1, iovec.iov_len); QuicStreamOffset offset = 0; if (framer_->HasDataProducer()) { + QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_save_data_before_consumption2, + 4, 4); collector_.SaveStatelessRejectFrameData(iov, 0, reject.length()); } while (offset < iovec.iov_len) { @@ -973,6 +975,11 @@ current_server_address_ = current_server_address; current_packet_ = current_packet.get(); current_connection_id_ = rejector->connection_id(); + if (FLAGS_quic_reloadable_flag_quic_set_version_on_async_get_proof_returns) { + QUIC_FLAG_COUNT( + quic_reloadable_flag_quic_set_version_on_async_get_proof_returns); + framer_.set_version(first_version); + } ProcessStatelessRejectorState(std::move(rejector), first_version); }
diff --git a/net/tools/quic/quic_dispatcher.h b/net/tools/quic/quic_dispatcher.h index 13bb50b..59779cd 100644 --- a/net/tools/quic/quic_dispatcher.h +++ b/net/tools/quic/quic_dispatcher.h
@@ -312,7 +312,8 @@ void ProcessUnauthenticatedHeaderFate(QuicPacketFate fate, QuicConnectionId connection_id); - // Invoked when StatelessRejector::Process completes. + // Invoked when StatelessRejector::Process completes. |first_version| is the + // version of the packet which initiated the stateless reject. void OnStatelessRejectorProcessDone( std::unique_ptr<StatelessRejector> rejector, const QuicSocketAddress& current_client_address,
diff --git a/net/tools/quic/quic_dispatcher_test.cc b/net/tools/quic/quic_dispatcher_test.cc index 5d4e9fd..28e0660b 100644 --- a/net/tools/quic/quic_dispatcher_test.cc +++ b/net/tools/quic/quic_dispatcher_test.cc
@@ -81,7 +81,6 @@ MOCK_METHOD1(CreateIncomingDynamicStream, QuicSpdyStream*(QuicStreamId id)); MOCK_METHOD1(CreateOutgoingDynamicStream, QuicSpdyStream*(SpdyPriority priority)); - MOCK_METHOD1(CreateStream, std::unique_ptr<QuicStream>(QuicStreamId id)); QuicCryptoServerStreamBase* CreateQuicCryptoServerStream( const QuicCryptoServerConfig* crypto_config, @@ -2152,6 +2151,37 @@ EXPECT_FALSE(time_wait_list_manager_->IsConnectionIdInTimeWait(conn_id)); } +// Regression test for +// https://bugs.chromium.org/p/chromium/issues/detail?id=748289 +TEST_F(AsyncGetProofTest, DispatcherFailedToPickUpVersionForAsyncProof) { + // This test mimics the scenario that dispatcher's framer can have different + // version when async proof returns. + // When dispatcher sends SREJ, the SREJ frame can be serialized in + // different endianness which causes the client to close the connection + // because of QUIC_INVALID_STREAM_DATA. + + // Send a CHLO with v39. Dispatcher framer's version is set to v39. + ProcessPacket(client_addr_, 1, true, QUIC_VERSION_39, SerializeCHLO(), + PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER, 1); + + // Send another CHLO with v37. Dispatcher framer's version is set to v37. + ProcessPacket(client_addr_, 2, true, QUIC_VERSION_37, SerializeCHLO(), + PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER, 1); + ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 2); + + // Complete the ProofSource::GetProof call for v39. This would cause the + // version mismatch between the CHLO packet and the dispatcher. + if (FLAGS_quic_reloadable_flag_quic_set_version_on_async_get_proof_returns) { + GetFakeProofSource()->InvokePendingCallback(0); + } else { + EXPECT_QUIC_BUG( + GetFakeProofSource()->InvokePendingCallback(0), + "SREJ: Client's version: QUIC_VERSION_39 is different " + "from current dispatcher framer's version: QUIC_VERSION_37"); + } + ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1); +} + } // namespace } // namespace test } // namespace net
diff --git a/net/tools/quic/quic_http_response_cache.cc b/net/tools/quic/quic_http_response_cache.cc index 01ac373c..8ad7b7a 100644 --- a/net/tools/quic/quic_http_response_cache.cc +++ b/net/tools/quic/quic_http_response_cache.cc
@@ -166,7 +166,7 @@ if (it == responses_.end()) { DVLOG(1) << "Get response for resource failed: host " << host << " path " << path; - if (default_response_.get()) { + if (default_response_) { return default_response_.get(); } return nullptr;
diff --git a/net/tools/quic/quic_simple_server_session.cc b/net/tools/quic/quic_simple_server_session.cc index c4392c1..4f3ed4b4 100644 --- a/net/tools/quic/quic_simple_server_session.cc +++ b/net/tools/quic/quic_simple_server_session.cc
@@ -114,11 +114,6 @@ return stream; } -std::unique_ptr<QuicStream> QuicSimpleServerSession::CreateStream( - QuicStreamId id) { - return QuicMakeUnique<QuicSimpleServerStream>(id, this, response_cache_); -} - void QuicSimpleServerSession::CloseStreamInner(QuicStreamId stream_id, bool locally_reset) { QuicSpdySession::CloseStreamInner(stream_id, locally_reset); @@ -187,10 +182,7 @@ } void QuicSimpleServerSession::HandlePromisedPushRequests() { - while (!promised_streams_.empty() && - (FLAGS_quic_reloadable_flag_quic_refactor_stream_creation - ? ShouldCreateOutgoingDynamicStream2() - : ShouldCreateOutgoingDynamicStream())) { + while (!promised_streams_.empty() && ShouldCreateOutgoingDynamicStream()) { PromisedStreamInfo& promised_info = promised_streams_.front(); DCHECK_EQ(next_outgoing_stream_id(), promised_info.stream_id); @@ -203,9 +195,7 @@ QuicSimpleServerStream* promised_stream = static_cast<QuicSimpleServerStream*>( - FLAGS_quic_reloadable_flag_quic_refactor_stream_creation - ? MaybeCreateOutgoingDynamicStream(promised_info.priority) - : CreateOutgoingDynamicStream(promised_info.priority)); + CreateOutgoingDynamicStream(promised_info.priority)); DCHECK_NE(promised_stream, nullptr); DCHECK_EQ(promised_info.stream_id, promised_stream->id()); QUIC_DLOG(INFO) << "created server push stream " << promised_stream->id();
diff --git a/net/tools/quic/quic_simple_server_session.h b/net/tools/quic/quic_simple_server_session.h index d1c4f854..f9ff7da 100644 --- a/net/tools/quic/quic_simple_server_session.h +++ b/net/tools/quic/quic_simple_server_session.h
@@ -82,14 +82,9 @@ protected: // QuicSession methods: - // TODO(ckrasic) - remove these two when - // FLAGS_quic_reloadable_flag_quic_refactor_stream_creation is - // deprecated. QuicSpdyStream* CreateIncomingDynamicStream(QuicStreamId id) override; QuicSimpleServerStream* CreateOutgoingDynamicStream( SpdyPriority priority) override; - std::unique_ptr<QuicStream> CreateStream(QuicStreamId id) override; - // Closing an outgoing stream can reduce open outgoing stream count, try // to handle queued promised streams right now. void CloseStreamInner(QuicStreamId stream_id, bool locally_reset) override;
diff --git a/net/tools/quic/quic_simple_server_session_test.cc b/net/tools/quic/quic_simple_server_session_test.cc index 3349def..c9e3cf80 100644 --- a/net/tools/quic/quic_simple_server_session_test.cc +++ b/net/tools/quic/quic_simple_server_session_test.cc
@@ -56,18 +56,13 @@ static QuicSpdyStream* CreateIncomingDynamicStream(QuicSimpleServerSession* s, QuicStreamId id) { - return FLAGS_quic_reloadable_flag_quic_refactor_stream_creation - ? s->MaybeCreateIncomingDynamicStream(id) - : s->CreateIncomingDynamicStream(id); + return s->CreateIncomingDynamicStream(id); } static QuicSimpleServerStream* CreateOutgoingDynamicStream( QuicSimpleServerSession* s, SpdyPriority priority) { - return FLAGS_quic_reloadable_flag_quic_refactor_stream_creation - ? static_cast<QuicSimpleServerStream*>( - s->MaybeCreateOutgoingDynamicStream(priority)) - : s->CreateOutgoingDynamicStream(priority); + return s->CreateOutgoingDynamicStream(priority); } static std::deque<PromisedStreamInfo>* promised_streams( @@ -326,24 +321,13 @@ // Tests that incoming stream creation fails when connection is not connected. size_t initial_num_open_stream = session_->GetNumOpenIncomingStreams(); QuicConnectionPeer::TearDownLocalConnectionState(connection_); - if (FLAGS_quic_reloadable_flag_quic_refactor_stream_creation) { - EXPECT_EQ(nullptr, QuicSimpleServerSessionPeer::CreateIncomingDynamicStream( - session_.get(), GetNthClientInitiatedId(0))); - } else { - EXPECT_QUIC_BUG(QuicSimpleServerSessionPeer::CreateIncomingDynamicStream( - session_.get(), GetNthClientInitiatedId(0)), - "ShouldCreateIncomingDynamicStream called when " - "disconnected"); - } + EXPECT_QUIC_BUG(QuicSimpleServerSessionPeer::CreateIncomingDynamicStream( + session_.get(), GetNthClientInitiatedId(0)), + "ShouldCreateIncomingDynamicStream called when disconnected"); EXPECT_EQ(initial_num_open_stream, session_->GetNumOpenIncomingStreams()); } TEST_P(QuicSimpleServerSessionTest, CreateEvenIncomingDynamicStream) { - if (FLAGS_quic_reloadable_flag_quic_refactor_stream_creation) { - EXPECT_EQ(nullptr, QuicSimpleServerSessionPeer::CreateIncomingDynamicStream( - session_.get(), 2)); - return; - } // Tests that incoming stream creation fails when given stream id is even. size_t initial_num_open_stream = session_->GetNumOpenIncomingStreams(); EXPECT_CALL(*connection_, @@ -365,15 +349,9 @@ // Tests that outgoing stream creation fails when connection is not connected. size_t initial_num_open_stream = session_->GetNumOpenOutgoingStreams(); QuicConnectionPeer::TearDownLocalConnectionState(connection_); - if (FLAGS_quic_reloadable_flag_quic_refactor_stream_creation) { - EXPECT_EQ(nullptr, QuicSimpleServerSessionPeer::CreateOutgoingDynamicStream( - session_.get(), kDefaultPriority)); - } else { - EXPECT_QUIC_BUG(QuicSimpleServerSessionPeer::CreateOutgoingDynamicStream( - session_.get(), kDefaultPriority), - "ShouldCreateOutgoingDynamicStream called when " - "disconnected"); - } + EXPECT_QUIC_BUG(QuicSimpleServerSessionPeer::CreateOutgoingDynamicStream( + session_.get(), kDefaultPriority), + "ShouldCreateOutgoingDynamicStream called when disconnected"); EXPECT_EQ(initial_num_open_stream, session_->GetNumOpenOutgoingStreams()); } @@ -382,15 +360,9 @@ // Tests that outgoing stream creation fails when encryption has not yet been // established. size_t initial_num_open_stream = session_->GetNumOpenOutgoingStreams(); - if (FLAGS_quic_reloadable_flag_quic_refactor_stream_creation) { - EXPECT_EQ(nullptr, QuicSimpleServerSessionPeer::CreateOutgoingDynamicStream( - session_.get(), kDefaultPriority)); - } else { - EXPECT_QUIC_BUG(QuicSimpleServerSessionPeer::CreateOutgoingDynamicStream( - session_.get(), kDefaultPriority), - "Encryption not established so no outgoing stream " - "created."); - } + EXPECT_QUIC_BUG(QuicSimpleServerSessionPeer::CreateOutgoingDynamicStream( + session_.get(), kDefaultPriority), + "Encryption not established so no outgoing stream created."); EXPECT_EQ(initial_num_open_stream, session_->GetNumOpenOutgoingStreams()); }
diff --git a/net/tools/quic/quic_spdy_client_base.cc b/net/tools/quic/quic_spdy_client_base.cc index 7fc0ab6..4c44874 100644 --- a/net/tools/quic/quic_spdy_client_base.cc +++ b/net/tools/quic/quic_spdy_client_base.cc
@@ -151,9 +151,7 @@ } auto* stream = static_cast<QuicSpdyClientStream*>( - FLAGS_quic_reloadable_flag_quic_refactor_stream_creation - ? client_session()->MaybeCreateOutgoingDynamicStream(kDefaultPriority) - : client_session()->CreateOutgoingDynamicStream(kDefaultPriority)); + client_session()->CreateOutgoingDynamicStream(kDefaultPriority)); if (stream) { stream->set_visitor(this); } @@ -231,7 +229,7 @@ if (stream) { stream->set_visitor(this); stream->OnDataAvailable(); - } else if (data_to_resend.get()) { + } else if (data_to_resend) { data_to_resend->Resend(); } }
diff --git a/net/tools/quic/quic_spdy_client_session.cc b/net/tools/quic/quic_spdy_client_session.cc index d13a84e..b8c30364 100644 --- a/net/tools/quic/quic_spdy_client_session.cc +++ b/net/tools/quic/quic_spdy_client_session.cc
@@ -26,7 +26,8 @@ QuicClientPushPromiseIndex* push_promise_index) : QuicSpdyClientSessionBase(connection, push_promise_index, config), server_id_(server_id), - crypto_config_(crypto_config) {} + crypto_config_(crypto_config), + respect_goaway_(true) {} QuicSpdyClientSession::~QuicSpdyClientSession() {} @@ -42,7 +43,6 @@ const ProofVerifyDetails& /*verify_details*/) {} bool QuicSpdyClientSession::ShouldCreateOutgoingDynamicStream() { - DCHECK(!FLAGS_quic_reloadable_flag_quic_refactor_stream_creation); if (!crypto_stream_->encryption_established()) { QUIC_DLOG(INFO) << "Encryption not active so no outgoing stream created."; return false; @@ -52,7 +52,7 @@ << "Already " << GetNumOpenOutgoingStreams() << " open."; return false; } - if (goaway_received() && respect_goaway()) { + if (goaway_received() && respect_goaway_) { QUIC_DLOG(INFO) << "Failed to create a new outgoing stream. " << "Already received goaway."; return false; @@ -100,12 +100,11 @@ } bool QuicSpdyClientSession::ShouldCreateIncomingDynamicStream(QuicStreamId id) { - DCHECK(!FLAGS_quic_reloadable_flag_quic_refactor_stream_creation); if (!connection()->connected()) { QUIC_BUG << "ShouldCreateIncomingDynamicStream called when disconnected"; return false; } - if (goaway_received() && respect_goaway()) { + if (goaway_received() && respect_goaway_) { QUIC_DLOG(INFO) << "Failed to create a new outgoing stream. " << "Already received goaway."; return false; @@ -142,26 +141,4 @@ return true; } -QuicSpdyClientStream* QuicSpdyClientSession::MaybeCreateOutgoingDynamicStream( - SpdyPriority priority) { - return static_cast<QuicSpdyClientStream*>( - QuicSpdySession::MaybeCreateOutgoingDynamicStream(priority)); -} - -QuicSpdyStream* QuicSpdyClientSession::MaybeCreateIncomingDynamicStream( - QuicStreamId id) { - QuicSpdyStream* stream = - QuicSpdySession::MaybeCreateIncomingDynamicStream(id); - if (stream) { - // Push streams start half-closed. - stream->CloseWriteSide(); - } - return stream; -} - -std::unique_ptr<QuicStream> QuicSpdyClientSession::CreateStream( - QuicStreamId id) { - return QuicMakeUnique<QuicSpdyClientStream>(id, this); -} - } // namespace net
diff --git a/net/tools/quic/quic_spdy_client_session.h b/net/tools/quic/quic_spdy_client_session.h index 1a252ac..5dd2247a 100644 --- a/net/tools/quic/quic_spdy_client_session.h +++ b/net/tools/quic/quic_spdy_client_session.h
@@ -37,8 +37,6 @@ // QuicSession methods: QuicSpdyClientStream* CreateOutgoingDynamicStream( SpdyPriority priority) override; - QuicSpdyClientStream* MaybeCreateOutgoingDynamicStream( - SpdyPriority priority) override; QuicCryptoClientStreamBase* GetMutableCryptoStream() override; const QuicCryptoClientStreamBase* GetCryptoStream() const override; @@ -59,6 +57,10 @@ int GetNumReceivedServerConfigUpdates() const; + void set_respect_goaway(bool respect_goaway) { + respect_goaway_ = respect_goaway; + } + protected: // QuicSession methods: QuicSpdyStream* CreateIncomingDynamicStream(QuicStreamId id) override; @@ -67,14 +69,10 @@ // If an incoming stream can be created, return true. bool ShouldCreateIncomingDynamicStream(QuicStreamId id) override; - QuicSpdyStream* MaybeCreateIncomingDynamicStream(QuicStreamId id) override; - std::unique_ptr<QuicStream> CreateStream(QuicStreamId id) override; // Create the crypto stream. Called by Initialize(). virtual std::unique_ptr<QuicCryptoClientStreamBase> CreateQuicCryptoStream(); - // TODO(ckrasic) remove when - // quic_reloadable_flag_quic_refactor_stream_creation is deprecated. // Unlike CreateOutgoingDynamicStream, which applies a bunch of sanity checks, // this simply returns a new QuicSpdyClientStream. This may be used by // subclasses which want to use a subclass of QuicSpdyClientStream for streams @@ -89,6 +87,10 @@ QuicServerId server_id_; QuicCryptoClientConfig* crypto_config_; + // If this is set to false, the client will ignore server GOAWAYs and allow + // the creation of streams regardless of the high chance they will fail. + bool respect_goaway_; + DISALLOW_COPY_AND_ASSIGN(QuicSpdyClientSession); };
diff --git a/net/tools/quic/quic_spdy_client_session_test.cc b/net/tools/quic/quic_spdy_client_session_test.cc index cba8935..db0bc20 100644 --- a/net/tools/quic/quic_spdy_client_session_test.cc +++ b/net/tools/quic/quic_spdy_client_session_test.cc
@@ -55,23 +55,12 @@ this); } - std::unique_ptr<QuicStream> CreateStream(QuicStreamId id) override { - return QuicMakeUnique<MockQuicSpdyClientStream>(id, this); - } - MockQuicSpdyClientStream* CreateIncomingDynamicStream( QuicStreamId id) override { MockQuicSpdyClientStream* stream = new MockQuicSpdyClientStream(id, this); ActivateStream(QuicWrapUnique(stream)); return stream; } - - QuicSpdyClientStream* CreateOutgoingDynamicStream( - SpdyPriority priority) override { - return FLAGS_quic_reloadable_flag_quic_refactor_stream_creation - ? MaybeCreateOutgoingDynamicStream(priority) - : QuicSpdyClientSession::CreateOutgoingDynamicStream(priority); - } }; class QuicSpdyClientSessionTest : public QuicTestWithParam<QuicVersion> { @@ -177,12 +166,8 @@ QuicPacketCreatorPeer::GetEncryptionLevel( QuicConnectionPeer::GetPacketCreator(connection_))); // Verify that no new streams may be created. - if (FLAGS_quic_reloadable_flag_quic_refactor_stream_creation) { - EXPECT_EQ(nullptr, session_->CreateOutgoingDynamicStream(kDefaultPriority)); - } else { - EXPECT_TRUE(session_->CreateOutgoingDynamicStream(kDefaultPriority) == - nullptr); - } + EXPECT_TRUE(session_->CreateOutgoingDynamicStream(kDefaultPriority) == + nullptr); // Verify that no data may be send on existing streams. char data[] = "hello world"; struct iovec iov = {data, arraysize(data)};
diff --git a/net/tools/quic/test_tools/quic_test_server.cc b/net/tools/quic/test_tools/quic_test_server.cc index a2a497377..c7d7caa6 100644 --- a/net/tools/quic/test_tools/quic_test_server.cc +++ b/net/tools/quic/test_tools/quic_test_server.cc
@@ -38,7 +38,6 @@ crypto_stream_factory_(crypto_stream_factory) {} QuicSpdyStream* CreateIncomingDynamicStream(QuicStreamId id) override { - DCHECK(!FLAGS_quic_reloadable_flag_quic_refactor_stream_creation); if (!ShouldCreateIncomingDynamicStream(id)) { return nullptr; } @@ -51,14 +50,6 @@ return QuicSimpleServerSession::CreateIncomingDynamicStream(id); } - std::unique_ptr<QuicStream> CreateStream(QuicStreamId id) override { - if (stream_factory_) { - return QuicWrapUnique<QuicSpdyStream>( - stream_factory_->CreateStream(id, this, response_cache())); - } - return QuicSimpleServerSession::CreateStream(id); - } - QuicCryptoServerStreamBase* CreateQuicCryptoServerStream( const QuicCryptoServerConfig* crypto_config, QuicCompressedCertsCache* compressed_certs_cache) override {
diff --git a/net/url_request/url_request_file_dir_job.h b/net/url_request/url_request_file_dir_job.h index 458faac..7389122 100644 --- a/net/url_request/url_request_file_dir_job.h +++ b/net/url_request/url_request_file_dir_job.h
@@ -20,7 +20,7 @@ class NET_EXPORT_PRIVATE URLRequestFileDirJob : public URLRequestJob, - public NON_EXPORTED_BASE(DirectoryLister::DirectoryListerDelegate) { + public DirectoryLister::DirectoryListerDelegate { public: URLRequestFileDirJob(URLRequest* request, NetworkDelegate* network_delegate,
diff --git a/pdf/pdfium/pdfium_engine.cc b/pdf/pdfium/pdfium_engine.cc index 58843581..e1d51335f 100644 --- a/pdf/pdfium/pdfium_engine.cc +++ b/pdf/pdfium/pdfium_engine.cc
@@ -2136,10 +2136,9 @@ if (event.GetKeyCode() == ui::VKEY_BACK || event.GetKeyCode() == ui::VKEY_ESCAPE) { - // Chrome doesn't send char events for backspace or escape keys, see - // PlatformKeyboardEventBuilder::isCharacterKey() and - // http://chrome-corpsvn.mtv.corp.google.com/viewvc?view=rev&root=chrome&revision=31805 - // for more information. So just fake one since PDFium uses it. + // Blink does not send char events for backspace or escape keys, see + // WebKeyboardEvent::IsCharacterKey() and b/961192 for more information. + // So just fake one since PDFium uses it. std::string str; str.push_back(event.GetKeyCode()); pp::KeyboardInputEvent synthesized(pp::KeyboardInputEvent(
diff --git a/ppapi/api/private/pp_content_decryptor.idl b/ppapi/api/private/pp_content_decryptor.idl index 0f536f7..96bd254 100644 --- a/ppapi/api/private/pp_content_decryptor.idl +++ b/ppapi/api/private/pp_content_decryptor.idl
@@ -452,12 +452,9 @@ enum PP_CdmExceptionCode { PP_CDMEXCEPTIONCODE_NOTSUPPORTEDERROR = 1, PP_CDMEXCEPTIONCODE_INVALIDSTATEERROR = 2, - PP_CDMEXCEPTIONCODE_INVALIDACCESSERROR = 3, + PP_CDMEXCEPTIONCODE_TYPEERROR = 3, PP_CDMEXCEPTIONCODE_QUOTAEXCEEDEDERROR = 4, - PP_CDMEXCEPTIONCODE_UNKNOWNERROR = 5, - PP_CDMEXCEPTIONCODE_CLIENTERROR = 6, - PP_CDMEXCEPTIONCODE_OUTPUTERROR = 7, - PP_CDMEXCEPTIONCODE_MAX = PP_CDMEXCEPTIONCODE_OUTPUTERROR + PP_CDMEXCEPTIONCODE_MAX = PP_CDMEXCEPTIONCODE_QUOTAEXCEEDEDERROR }; /**
diff --git a/ppapi/c/private/pp_content_decryptor.h b/ppapi/c/private/pp_content_decryptor.h index caee404d..5359d94d 100644 --- a/ppapi/c/private/pp_content_decryptor.h +++ b/ppapi/c/private/pp_content_decryptor.h
@@ -3,7 +3,7 @@ * found in the LICENSE file. */ -/* From private/pp_content_decryptor.idl modified Mon Nov 21 11:44:43 2016. */ +/* From private/pp_content_decryptor.idl modified Wed Jun 14 16:48:35 2017. */ #ifndef PPAPI_C_PRIVATE_PP_CONTENT_DECRYPTOR_H_ #define PPAPI_C_PRIVATE_PP_CONTENT_DECRYPTOR_H_ @@ -501,12 +501,9 @@ typedef enum { PP_CDMEXCEPTIONCODE_NOTSUPPORTEDERROR = 1, PP_CDMEXCEPTIONCODE_INVALIDSTATEERROR = 2, - PP_CDMEXCEPTIONCODE_INVALIDACCESSERROR = 3, + PP_CDMEXCEPTIONCODE_TYPEERROR = 3, PP_CDMEXCEPTIONCODE_QUOTAEXCEEDEDERROR = 4, - PP_CDMEXCEPTIONCODE_UNKNOWNERROR = 5, - PP_CDMEXCEPTIONCODE_CLIENTERROR = 6, - PP_CDMEXCEPTIONCODE_OUTPUTERROR = 7, - PP_CDMEXCEPTIONCODE_MAX = PP_CDMEXCEPTIONCODE_OUTPUTERROR + PP_CDMEXCEPTIONCODE_MAX = PP_CDMEXCEPTIONCODE_QUOTAEXCEEDEDERROR } PP_CdmExceptionCode; PP_COMPILE_ASSERT_SIZE_IN_BYTES(PP_CdmExceptionCode, 4);
diff --git a/ppapi/proxy/file_chooser_resource.h b/ppapi/proxy/file_chooser_resource.h index 05d01d3..9c31c70 100644 --- a/ppapi/proxy/file_chooser_resource.h +++ b/ppapi/proxy/file_chooser_resource.h
@@ -26,7 +26,7 @@ class PPAPI_PROXY_EXPORT FileChooserResource : public PluginResource, - public NON_EXPORTED_BASE(thunk::PPB_FileChooser_API) { + public thunk::PPB_FileChooser_API { public: FileChooserResource(Connection connection, PP_Instance instance,
diff --git a/ppapi/proxy/file_system_resource.h b/ppapi/proxy/file_system_resource.h index c03765c..051bc74 100644 --- a/ppapi/proxy/file_system_resource.h +++ b/ppapi/proxy/file_system_resource.h
@@ -28,9 +28,8 @@ namespace proxy { -class PPAPI_PROXY_EXPORT FileSystemResource - : public PluginResource, - public NON_EXPORTED_BASE(thunk::PPB_FileSystem_API) { +class PPAPI_PROXY_EXPORT FileSystemResource : public PluginResource, + public thunk::PPB_FileSystem_API { public: // Creates a new FileSystemResource. The resource must be subsequently opened // via Open() before use.
diff --git a/ppapi/proxy/flash_clipboard_resource.h b/ppapi/proxy/flash_clipboard_resource.h index ba17e41f..601b94dd 100644 --- a/ppapi/proxy/flash_clipboard_resource.h +++ b/ppapi/proxy/flash_clipboard_resource.h
@@ -16,9 +16,8 @@ namespace ppapi { namespace proxy { -class FlashClipboardResource - : public PluginResource, - public NON_EXPORTED_BASE(thunk::PPB_Flash_Clipboard_API) { +class FlashClipboardResource : public PluginResource, + public thunk::PPB_Flash_Clipboard_API { public: FlashClipboardResource(Connection connection, PP_Instance instance); ~FlashClipboardResource() override;
diff --git a/ppapi/proxy/graphics_2d_resource.h b/ppapi/proxy/graphics_2d_resource.h index 3fa6b76..ee9f1ab 100644 --- a/ppapi/proxy/graphics_2d_resource.h +++ b/ppapi/proxy/graphics_2d_resource.h
@@ -19,9 +19,8 @@ namespace proxy { -class PPAPI_PROXY_EXPORT Graphics2DResource - : public PluginResource, - public NON_EXPORTED_BASE(thunk::PPB_Graphics2D_API) { +class PPAPI_PROXY_EXPORT Graphics2DResource : public PluginResource, + public thunk::PPB_Graphics2D_API { public: Graphics2DResource(Connection connection, PP_Instance instance,
diff --git a/ppapi/proxy/ppb_image_data_proxy.h b/ppapi/proxy/ppb_image_data_proxy.h index 8201b44..5effda73 100644 --- a/ppapi/proxy/ppb_image_data_proxy.h +++ b/ppapi/proxy/ppb_image_data_proxy.h
@@ -42,10 +42,9 @@ // ImageData is an abstract base class for image data resources. Unlike most // resources, ImageData must be public in the header since a number of other // resources need to access it. -class PPAPI_PROXY_EXPORT ImageData - : public ppapi::Resource, - public NON_EXPORTED_BASE(ppapi::thunk::PPB_ImageData_API), - public ppapi::PPB_ImageData_Shared { +class PPAPI_PROXY_EXPORT ImageData : public ppapi::Resource, + public ppapi::thunk::PPB_ImageData_API, + public ppapi::PPB_ImageData_Shared { public: ~ImageData() override;
diff --git a/ppapi/proxy/printing_resource.h b/ppapi/proxy/printing_resource.h index 0ef5c77..a6598dab 100644 --- a/ppapi/proxy/printing_resource.h +++ b/ppapi/proxy/printing_resource.h
@@ -17,9 +17,8 @@ namespace ppapi { namespace proxy { -class PPAPI_PROXY_EXPORT PrintingResource - : public PluginResource, - public NON_EXPORTED_BASE(thunk::PPB_Printing_API) { +class PPAPI_PROXY_EXPORT PrintingResource : public PluginResource, + public thunk::PPB_Printing_API { public: PrintingResource(Connection connection, PP_Instance instance);
diff --git a/ppapi/proxy/url_loader_resource.h b/ppapi/proxy/url_loader_resource.h index ce2bb322..1fa7db7 100644 --- a/ppapi/proxy/url_loader_resource.h +++ b/ppapi/proxy/url_loader_resource.h
@@ -26,9 +26,8 @@ class URLResponseInfoResource; -class PPAPI_PROXY_EXPORT URLLoaderResource - : public PluginResource, - public NON_EXPORTED_BASE(thunk::PPB_URLLoader_API) { +class PPAPI_PROXY_EXPORT URLLoaderResource : public PluginResource, + public thunk::PPB_URLLoader_API { public: // Constructor for plugin-initiated loads. URLLoaderResource(Connection connection,
diff --git a/ppapi/proxy/url_response_info_resource.h b/ppapi/proxy/url_response_info_resource.h index 506b4d36..6b0678b7 100644 --- a/ppapi/proxy/url_response_info_resource.h +++ b/ppapi/proxy/url_response_info_resource.h
@@ -18,7 +18,7 @@ class PPAPI_PROXY_EXPORT URLResponseInfoResource : public PluginResource, - public NON_EXPORTED_BASE(thunk::PPB_URLResponseInfo_API) { + public thunk::PPB_URLResponseInfo_API { public: // The file_ref_resource should be the body_as_file_ref host resource in the // |data| converted to a resource valid in the current process (if we're
diff --git a/ppapi/proxy/vpn_provider_resource.h b/ppapi/proxy/vpn_provider_resource.h index fd017a37..fa4c3bb8 100644 --- a/ppapi/proxy/vpn_provider_resource.h +++ b/ppapi/proxy/vpn_provider_resource.h
@@ -19,7 +19,7 @@ class PPAPI_PROXY_EXPORT VpnProviderResource : public PluginResource, - public NON_EXPORTED_BASE(thunk::PPB_VpnProvider_API) { + public thunk::PPB_VpnProvider_API { public: VpnProviderResource(Connection connection, PP_Instance instance); virtual ~VpnProviderResource();
diff --git a/ppapi/proxy/websocket_resource.h b/ppapi/proxy/websocket_resource.h index 2cb43b8..b876d55 100644 --- a/ppapi/proxy/websocket_resource.h +++ b/ppapi/proxy/websocket_resource.h
@@ -24,9 +24,8 @@ // This class contains protocol checks which doesn't affect security when it // run with untrusted code. -class PPAPI_PROXY_EXPORT WebSocketResource - : public PluginResource, - public NON_EXPORTED_BASE(thunk::PPB_WebSocket_API) { +class PPAPI_PROXY_EXPORT WebSocketResource : public PluginResource, + public thunk::PPB_WebSocket_API { public: WebSocketResource(Connection connection, PP_Instance instance); ~WebSocketResource() override;
diff --git a/ppapi/shared_impl/ppb_instance_shared.h b/ppapi/shared_impl/ppb_instance_shared.h index bcd284e4..6fd63fe6 100644 --- a/ppapi/shared_impl/ppb_instance_shared.h +++ b/ppapi/shared_impl/ppb_instance_shared.h
@@ -12,8 +12,7 @@ namespace ppapi { -class PPAPI_SHARED_EXPORT PPB_Instance_Shared - : NON_EXPORTED_BASE(public thunk::PPB_Instance_API) { +class PPAPI_SHARED_EXPORT PPB_Instance_Shared : public thunk::PPB_Instance_API { public: ~PPB_Instance_Shared() override;
diff --git a/ppapi/shared_impl/ppb_video_decoder_shared.h b/ppapi/shared_impl/ppb_video_decoder_shared.h index ad431a7..2726dbad 100644 --- a/ppapi/shared_impl/ppb_video_decoder_shared.h +++ b/ppapi/shared_impl/ppb_video_decoder_shared.h
@@ -29,7 +29,7 @@ // events. Both the proxy and the renderer implementation share this code. class PPAPI_SHARED_EXPORT PPB_VideoDecoder_Shared : public Resource, - NON_EXPORTED_BASE(public thunk::PPB_VideoDecoder_Dev_API) { + public thunk::PPB_VideoDecoder_Dev_API { public: explicit PPB_VideoDecoder_Shared(PP_Instance instance); explicit PPB_VideoDecoder_Shared(const HostResource& host_resource);
diff --git a/printing/backend/OWNERS b/printing/backend/OWNERS new file mode 100644 index 0000000..574fd32 --- /dev/null +++ b/printing/backend/OWNERS
@@ -0,0 +1,2 @@ +# CUPS-specific code. +per-file *cups*=skau@chromium.org
diff --git a/printing/backend/cups_jobs.cc b/printing/backend/cups_jobs.cc index 18c303a9..5bae8920 100644 --- a/printing/backend/cups_jobs.cc +++ b/printing/backend/cups_jobs.cc
@@ -97,6 +97,13 @@ const char kInterpreterResourceUnavailable[] = "interpreter-resource-unavailable"; +constexpr char kIppScheme[] = "ipp"; +constexpr char kIppsScheme[] = "ipps"; + +// Timeout for establishing a HTTP connection in milliseconds. Anecdotally, +// some print servers are slow and can use the extra time. +constexpr int kHttpConnectTimeoutMs = 1000; + constexpr std::array<const char* const, 3> kPrinterAttributes{ {kPrinterState, kPrinterStateReasons, kPrinterStateMessage}}; @@ -308,7 +315,6 @@ for (ipp_attribute_t* attr = ippFirstAttribute(response); attr != nullptr; attr = ippNextAttribute(response)) { base::StringPiece name = ippGetName(attr); - if (name == base::StringPiece(kPrinterMakeAndModel)) { DCHECK_EQ(IPP_TAG_TEXT, ippGetValueTag(attr)); printer_info->make_and_model = ippGetString(attr, 0, nullptr); @@ -388,9 +394,11 @@ : "/" + resource_path; auto request = WrapIpp(ippNewRequest(IPP_OP_GET_PRINTER_ATTRIBUTES)); + // We support IPP up to 2.2 but are compatible down to v1.1. + ippSetVersion(request.get(), 1, 1); ippAddString(request.get(), IPP_TAG_OPERATION, IPP_TAG_URI, kPrinterUri, - nullptr, printer_uri.data()); + nullptr, printer_uri.c_str()); ippAddStrings(request.get(), IPP_TAG_OPERATION, IPP_TAG_KEYWORD, kRequestedAttributes, num_attributes, nullptr, attributes); @@ -434,18 +442,22 @@ base::ThreadRestrictions::AssertIOAllowed(); ScopedHttpPtr http = ScopedHttpPtr(httpConnect2( - address.data(), port, nullptr, AF_INET, + address.c_str(), port, nullptr, AF_INET, encrypted ? HTTP_ENCRYPTION_REQUIRED : HTTP_ENCRYPTION_IF_REQUESTED, 0, - 200, nullptr)); + kHttpConnectTimeoutMs, nullptr)); if (!http) { LOG(WARNING) << "Could not connect to host"; return false; } + std::string printer_uri = + base::StringPrintf("%s://%s:%d/%s", encrypted ? kIppsScheme : kIppScheme, + address.c_str(), port, resource.c_str()); + ipp_status_t status; ScopedIppPtr response = - GetPrinterAttributes(http.get(), resource, resource, kPrinterInfo.size(), - kPrinterInfo.data(), &status); + GetPrinterAttributes(http.get(), printer_uri, resource, + kPrinterInfo.size(), kPrinterInfo.data(), &status); if (status != IPP_STATUS_OK || response.get() == nullptr) { LOG(WARNING) << "Get attributes failure: " << status; return false; @@ -485,7 +497,7 @@ auto request = WrapIpp(ippNewRequest(IPP_OP_GET_JOBS)); const std::string printer_uri = PrinterUriFromName(printer_id); ippAddString(request.get(), IPP_TAG_OPERATION, IPP_TAG_URI, kPrinterUri, - nullptr, printer_uri.data()); + nullptr, printer_uri.c_str()); ippAddInteger(request.get(), IPP_TAG_OPERATION, IPP_TAG_INTEGER, kLimit, limit);
diff --git a/printing/features/features.gni b/printing/features/features.gni index a41202a2..b3d6967 100644 --- a/printing/features/features.gni +++ b/printing/features/features.gni
@@ -7,11 +7,11 @@ declare_args() { # Enable basic printing support and UI. - enable_basic_printing = !is_chromecast && !is_ios + enable_basic_printing = !is_chromecast && !is_ios && !is_fuchsia # Enable printing with print preview. It does not imply # enable_basic_printing. It's possible to build Chrome with preview only. - enable_print_preview = !is_android && !is_chromecast && !is_ios + enable_print_preview = !is_android && !is_chromecast && !is_ios && !is_fuchsia - use_cups = (is_desktop_linux || is_mac) && !is_chromecast + use_cups = (is_desktop_linux || is_mac) && !is_chromecast && !is_fuchsia }
diff --git a/services/catalog/BUILD.gn b/services/catalog/BUILD.gn index d3bf8a1..dc33437b 100644 --- a/services/catalog/BUILD.gn +++ b/services/catalog/BUILD.gn
@@ -61,7 +61,7 @@ "entry_unittest.cc", ] data = [ - "//services/catalog/data/", + "//services/catalog/test_data/", ] deps = [ ":lib",
diff --git a/services/catalog/data/required_files b/services/catalog/data/required_files deleted file mode 100644 index f0eba90..0000000 --- a/services/catalog/data/required_files +++ /dev/null
@@ -1,17 +0,0 @@ -{ - "name": "foo", - "display_name": "Foo", - "interface_provider_specs": { }, - "required_files": { - "all_platforms": [ - { "path": "/all/platforms/linux", "platform": "linux" }, - { "path": "/all/platforms/windows", "platform": "windows" }, - { "path": "/all/platforms/macosx", "platform": "macosx" }, - { "path": "/all/platforms/android", "platform": "android" } - ], - "linux_only": [{ "path": "/linux/only", "platform": "linux" }], - "windows_only": [{ "path" : "/windows/only", "platform": "windows" }], - "macosx_only": [{ "path" : "/macosx/only", "platform": "macosx" }], - "android_only": [{ "path" : "/android/only", "platform": "android" }] - } -}
diff --git a/services/catalog/entry_unittest.cc b/services/catalog/entry_unittest.cc index 66ac84c..e5dba1b 100644 --- a/services/catalog/entry_unittest.cc +++ b/services/catalog/entry_unittest.cc
@@ -9,6 +9,7 @@ #include "base/macros.h" #include "base/path_service.h" #include "base/values.h" +#include "build/build_config.h" #include "services/service_manager/public/cpp/interface_provider_spec.h" #include "services/service_manager/public/interfaces/interface_provider_spec.mojom.h" #include "testing/gtest/include/gtest/gtest.h" @@ -34,8 +35,8 @@ std::unique_ptr<base::Value> ReadManifest(const std::string& manifest) { base::FilePath manifest_path; PathService::Get(base::DIR_SOURCE_ROOT, &manifest_path); - manifest_path = manifest_path.AppendASCII( - "services/catalog/data/" + manifest); + manifest_path = + manifest_path.AppendASCII("services/catalog/test_data/" + manifest); JSONFileValueDeserializer deserializer(manifest_path); int error = 0; @@ -94,6 +95,12 @@ ASSERT_NE(required_files.end(), iter); EXPECT_EQ(base::FilePath(L"/windows/only"), iter->second); checked_platform_specific_file = true; +#elif defined(OS_FUCHSIA) + EXPECT_EQ(base::FilePath("/all/platforms/fuchsia"), iter->second); + iter = required_files.find("fuchsia_only"); + ASSERT_NE(required_files.end(), iter); + EXPECT_EQ(base::FilePath("/fuchsia/only"), iter->second); + checked_platform_specific_file = true; #elif defined(OS_LINUX) EXPECT_EQ(base::FilePath("/all/platforms/linux"), iter->second); iter = required_files.find("linux_only");
diff --git a/services/catalog/data/connection_spec b/services/catalog/test_data/connection_spec similarity index 100% rename from services/catalog/data/connection_spec rename to services/catalog/test_data/connection_spec
diff --git a/services/catalog/data/instance b/services/catalog/test_data/instance similarity index 100% rename from services/catalog/data/instance rename to services/catalog/test_data/instance
diff --git a/services/catalog/data/malformed b/services/catalog/test_data/malformed similarity index 100% rename from services/catalog/data/malformed rename to services/catalog/test_data/malformed
diff --git a/services/catalog/test_data/required_files b/services/catalog/test_data/required_files new file mode 100644 index 0000000..2e45d97e --- /dev/null +++ b/services/catalog/test_data/required_files
@@ -0,0 +1,19 @@ +{ + "name": "foo", + "display_name": "Foo", + "interface_provider_specs": { }, + "required_files": { + "all_platforms": [ + { "path": "/all/platforms/fuchsia", "platform": "fuchsia" }, + { "path": "/all/platforms/linux", "platform": "linux" }, + { "path": "/all/platforms/windows", "platform": "windows" }, + { "path": "/all/platforms/macosx", "platform": "macosx" }, + { "path": "/all/platforms/android", "platform": "android" } + ], + "fuchsia_only": [{ "path": "/fuchsia/only", "platform": "fuchsia" }], + "linux_only": [{ "path": "/linux/only", "platform": "linux" }], + "windows_only": [{ "path" : "/windows/only", "platform": "windows" }], + "macosx_only": [{ "path" : "/macosx/only", "platform": "macosx" }], + "android_only": [{ "path" : "/android/only", "platform": "android" }] + } +}
diff --git a/services/catalog/data/serialization b/services/catalog/test_data/serialization similarity index 100% rename from services/catalog/data/serialization rename to services/catalog/test_data/serialization
diff --git a/services/catalog/data/simple b/services/catalog/test_data/simple similarity index 100% rename from services/catalog/data/simple rename to services/catalog/test_data/simple
diff --git a/services/device/device_service.cc b/services/device/device_service.cc index ff5fbd9..6716286 100644 --- a/services/device/device_service.cc +++ b/services/device/device_service.cc
@@ -7,6 +7,7 @@ #include <utility> #include "base/bind.h" +#include "base/feature_list.h" #include "base/memory/ptr_util.h" #include "base/memory/weak_ptr.h" #include "base/single_thread_task_runner.h" @@ -17,6 +18,7 @@ #include "services/device/fingerprint/fingerprint.h" #include "services/device/generic_sensor/sensor_provider_impl.h" #include "services/device/power_monitor/power_monitor_message_broadcaster.h" +#include "services/device/public/cpp/device_features.h" #include "services/device/public/interfaces/battery_monitor.mojom.h" #include "services/device/serial/serial_device_enumerator_impl.h" #include "services/device/time_zone_monitor/time_zone_monitor.h" @@ -89,6 +91,8 @@ void DeviceService::OnStart() { registry_.AddInterface<mojom::Fingerprint>(base::Bind( &DeviceService::BindFingerprintRequest, base::Unretained(this))); + registry_.AddInterface<mojom::MotionSensor>(base::Bind( + &DeviceService::BindMotionSensorRequest, base::Unretained(this))); registry_.AddInterface<mojom::OrientationSensor>(base::Bind( &DeviceService::BindOrientationSensorRequest, base::Unretained(this))); registry_.AddInterface<mojom::OrientationAbsoluteSensor>( @@ -99,8 +103,10 @@ registry_.AddInterface<mojom::ScreenOrientationListener>( base::Bind(&DeviceService::BindScreenOrientationListenerRequest, base::Unretained(this))); - registry_.AddInterface<mojom::SensorProvider>(base::Bind( - &DeviceService::BindSensorProviderRequest, base::Unretained(this))); + if (base::FeatureList::IsEnabled(features::kGenericSensor)) { + registry_.AddInterface<mojom::SensorProvider>(base::Bind( + &DeviceService::BindSensorProviderRequest, base::Unretained(this))); + } registry_.AddInterface<mojom::TimeZoneMonitor>(base::Bind( &DeviceService::BindTimeZoneMonitorRequest, base::Unretained(this))); registry_.AddInterface<mojom::WakeLockProvider>(base::Bind( @@ -155,6 +161,22 @@ Fingerprint::Create(std::move(request)); } +void DeviceService::BindMotionSensorRequest( + mojom::MotionSensorRequest request) { +#if defined(OS_ANDROID) + // On Android the device sensors implementations need to run on the UI thread + // to communicate to Java. + DeviceMotionHost::Create(std::move(request)); +#else + // On platforms other than Android the device sensors implementations run on + // the IO thread. + if (io_task_runner_) { + io_task_runner_->PostTask(FROM_HERE, base::Bind(&DeviceMotionHost::Create, + base::Passed(&request))); + } +#endif // defined(OS_ANDROID) +} + void DeviceService::BindOrientationSensorRequest( mojom::OrientationSensorRequest request) { #if defined(OS_ANDROID)
diff --git a/services/device/device_service.h b/services/device/device_service.h index 721ae52c..e1446ee5 100644 --- a/services/device/device_service.h +++ b/services/device/device_service.h
@@ -7,6 +7,7 @@ #include "base/memory/ref_counted.h" #include "device/screen_orientation/public/interfaces/screen_orientation.mojom.h" +#include "device/sensors/public/interfaces/motion.mojom.h" #include "device/sensors/public/interfaces/orientation.mojom.h" #include "mojo/public/cpp/bindings/binding_set.h" #include "services/device/public/interfaces/battery_monitor.mojom.h" @@ -73,6 +74,8 @@ void BindFingerprintRequest(mojom::FingerprintRequest request); + void BindMotionSensorRequest(mojom::MotionSensorRequest request); + void BindOrientationSensorRequest(mojom::OrientationSensorRequest request); void BindOrientationAbsoluteSensorRequest(
diff --git a/services/device/fingerprint/fingerprint_chromeos.h b/services/device/fingerprint/fingerprint_chromeos.h index 943e03a..b43b4018 100644 --- a/services/device/fingerprint/fingerprint_chromeos.h +++ b/services/device/fingerprint/fingerprint_chromeos.h
@@ -19,7 +19,7 @@ // This is used to connect to biod(through dbus) and perform fingerprint related // operations. It observes signals from biod. class SERVICES_DEVICE_FINGERPRINT_EXPORT FingerprintChromeOS - : public NON_EXPORTED_BASE(mojom::Fingerprint), + : public mojom::Fingerprint, public chromeos::BiodClient::Observer { public: enum class FingerprintSession {
diff --git a/services/device/generic_sensor/BUILD.gn b/services/device/generic_sensor/BUILD.gn index 3b2c1a8..5d79d1c9 100644 --- a/services/device/generic_sensor/BUILD.gn +++ b/services/device/generic_sensor/BUILD.gn
@@ -67,7 +67,6 @@ deps = [ "//base", "//device/base/synchronization", - "//services/device/public/cpp:device_features", ] public_deps = [
diff --git a/services/device/generic_sensor/DEPS b/services/device/generic_sensor/DEPS index 79cb4cdf..162bc1c 100644 --- a/services/device/generic_sensor/DEPS +++ b/services/device/generic_sensor/DEPS
@@ -1,6 +1,5 @@ include_rules = [ "+device/base/synchronization", "+jni", - "+services/device/public/cpp/device_features.h", "+third_party/sudden_motion_sensor", ]
diff --git a/services/device/generic_sensor/platform_sensor_accelerometer_mac.cc b/services/device/generic_sensor/platform_sensor_accelerometer_mac.cc index 2eaa9c9..2b2f6da 100644 --- a/services/device/generic_sensor/platform_sensor_accelerometer_mac.cc +++ b/services/device/generic_sensor/platform_sensor_accelerometer_mac.cc
@@ -17,9 +17,7 @@ namespace { -constexpr double kMeanGravity = 9.80665; - -constexpr double kGravityThreshold = kMeanGravity * 0.01; +constexpr double kGravityThreshold = device::kMeanGravity * 0.01; bool IsSignificantlyDifferent(const device::SensorReading& reading1, const device::SensorReading& reading2) {
diff --git a/services/device/generic_sensor/platform_sensor_provider_mac.cc b/services/device/generic_sensor/platform_sensor_provider_mac.cc index ffd7540..4f9bc285 100644 --- a/services/device/generic_sensor/platform_sensor_provider_mac.cc +++ b/services/device/generic_sensor/platform_sensor_provider_mac.cc
@@ -48,8 +48,8 @@ auto relative_orientation_euler_angles_fusion_algorithm_using_accelerometer = base::MakeUnique< RelativeOrientationEulerAnglesFusionAlgorithmUsingAccelerometer>(); - // If a PlatformSensorFusion object is created successfully, the caller - // of this function holds the reference to the object. + // If this PlatformSensorFusion object is successfully initialized, + // |callback| will be run with a reference to this object. base::MakeRefCounted<PlatformSensorFusion>( std::move(mapping), this, callback, source_sensor_types, mojom::SensorType::RELATIVE_ORIENTATION_EULER_ANGLES, @@ -63,8 +63,8 @@ auto orientation_quaternion_fusion_algorithm_using_euler_angles = base::MakeUnique< OrientationQuaternionFusionAlgorithmUsingEulerAngles>(); - // If a PlatformSensorFusion object is created successfully, the caller - // of this function holds the reference to the object. + // If this PlatformSensorFusion object is successfully initialized, + // |callback| will be run with a reference to this object. base::MakeRefCounted<PlatformSensorFusion>( std::move(mapping), this, callback, source_sensor_types, mojom::SensorType::RELATIVE_ORIENTATION_QUATERNION,
diff --git a/services/device/generic_sensor/platform_sensor_provider_win.cc b/services/device/generic_sensor/platform_sensor_provider_win.cc index eb26846..bf52ae81 100644 --- a/services/device/generic_sensor/platform_sensor_provider_win.cc +++ b/services/device/generic_sensor/platform_sensor_provider_win.cc
@@ -48,6 +48,8 @@ mojom::SensorType::ACCELEROMETER}; auto linear_acceleration_fusion_algorithm = base::MakeUnique< LinearAccelerationFusionAlgorithmUsingAccelerometer>(); + // If this PlatformSensorFusion object is successfully initialized, + // |callback| will be run with a reference to this object. base::MakeRefCounted<PlatformSensorFusion>( std::move(mapping), this, callback, source_sensor_types, type, std::move(linear_acceleration_fusion_algorithm));
diff --git a/services/device/generic_sensor/sensor_provider_impl.cc b/services/device/generic_sensor/sensor_provider_impl.cc index 71a9b48..d546d2e 100644 --- a/services/device/generic_sensor/sensor_provider_impl.cc +++ b/services/device/generic_sensor/sensor_provider_impl.cc
@@ -6,13 +6,11 @@ #include <utility> -#include "base/feature_list.h" #include "base/memory/ptr_util.h" #include "base/threading/thread_task_runner_handle.h" #include "mojo/public/cpp/bindings/strong_binding.h" #include "services/device/generic_sensor/platform_sensor_provider.h" #include "services/device/generic_sensor/sensor_impl.h" -#include "services/device/public/cpp/device_features.h" #include "services/device/public/cpp/generic_sensor/sensor_traits.h" namespace device { @@ -57,17 +55,6 @@ void SensorProviderImpl::GetSensor(mojom::SensorType type, mojom::SensorRequest sensor_request, GetSensorCallback callback) { - // TODO(juncai): remove when the GenericSensor feature goes stable. - // For sensors that are used by DeviceMotionEvent, don't check the - // features::kGenericSensor flag. - if (!base::FeatureList::IsEnabled(features::kGenericSensor) && - !(type == mojom::SensorType::ACCELEROMETER || - type == mojom::SensorType::LINEAR_ACCELERATION || - type == mojom::SensorType::GYROSCOPE)) { - NotifySensorCreated(nullptr, nullptr, std::move(callback)); - return; - } - auto cloned_handle = provider_->CloneSharedBufferHandle(); if (!cloned_handle.is_valid()) { NotifySensorCreated(nullptr, nullptr, std::move(callback));
diff --git a/services/device/public/cpp/generic_sensor/sensor_reading.h b/services/device/public/cpp/generic_sensor/sensor_reading.h index ed146db..d0f8087 100644 --- a/services/device/public/cpp/generic_sensor/sensor_reading.h +++ b/services/device/public/cpp/generic_sensor/sensor_reading.h
@@ -117,7 +117,7 @@ // ABSOLUTE_ORIENTATION_EULER_ANGLES: // orientation_euler.x: x-axis angle in degrees representing the orientation of // the device in 3D space. It corresponds to the beta value in the W3C -// DeviceOrientation Event Specification. This value is in [180, 180). +// DeviceOrientation Event Specification. This value is in [-180, 180). // orientation_euler.y: y-axis angle in degrees representing the orientation of // the device in 3D space. It corresponds to the gamma value in the W3C // DeviceOrientation Event Specification. This value is in [-90, 90). @@ -140,7 +140,7 @@ // the geomagnetic field.) // orientation_euler.x: x-axis angle in degrees representing the orientation of // the device in 3D space. It corresponds to the beta value in the W3C -// DeviceOrientation Event Specification. This value is in [180, 180). +// DeviceOrientation Event Specification. This value is in [-180, 180). // orientation_euler.y: y-axis angle in degrees representing the orientation of // the device in 3D space. It corresponds to the gamma value in the W3C // DeviceOrientation Event Specification. This value is in [-90, 90).
diff --git a/services/metrics/public/cpp/ukm_entry_builder_base.cc b/services/metrics/public/cpp/ukm_entry_builder_base.cc index f7297f7e..1e15bf33 100644 --- a/services/metrics/public/cpp/ukm_entry_builder_base.cc +++ b/services/metrics/public/cpp/ukm_entry_builder_base.cc
@@ -26,7 +26,10 @@ } void UkmEntryBuilderBase::Record(UkmRecorder* recorder) { - recorder->AddEntry(std::move(entry_)); + if (recorder) + recorder->AddEntry(std::move(entry_)); + else + entry_.reset(); } } // namespace internal
diff --git a/services/metrics/public/cpp/ukm_entry_builder_base.h b/services/metrics/public/cpp/ukm_entry_builder_base.h index fc7ca7b..b602f7a 100644 --- a/services/metrics/public/cpp/ukm_entry_builder_base.h +++ b/services/metrics/public/cpp/ukm_entry_builder_base.h
@@ -22,6 +22,8 @@ public: virtual ~UkmEntryBuilderBase(); + // Records the complete entry into the recorder. If recorder is null, the + // entry is simply discarded. void Record(UkmRecorder* recorder); protected:
diff --git a/services/preferences/public/cpp/pref_service_factory.cc b/services/preferences/public/cpp/pref_service_factory.cc index d7868021..c83795c 100644 --- a/services/preferences/public/cpp/pref_service_factory.cc +++ b/services/preferences/public/cpp/pref_service_factory.cc
@@ -111,7 +111,7 @@ auto pref_service = base::MakeUnique<PrefService>( pref_notifier, pref_value_store, user_pref_store.get(), pref_registry.get(), base::Bind(&DoNothingHandleReadError), true); - switch (pref_service->GetInitializationStatus()) { + switch (pref_service->GetAllPrefStoresInitializationStatus()) { case PrefService::INITIALIZATION_STATUS_WAITING: pref_service->AddPrefInitObserver(base::Bind(&OnPrefServiceInit, base::Passed(&pref_service), @@ -138,14 +138,12 @@ } // namespace -void ConnectToPrefService( - service_manager::Connector* connector, - scoped_refptr<PrefRegistry> pref_registry, - ConnectCallback callback, - base::StringPiece service_name) { +void ConnectToPrefService(mojom::PrefStoreConnectorPtr connector, + scoped_refptr<PrefRegistry> pref_registry, + ConnectCallback callback) { auto connector_ptr = make_scoped_refptr( new RefCountedInterfacePtr<mojom::PrefStoreConnector>()); - connector->BindInterface(service_name.as_string(), &connector_ptr->get()); + connector_ptr->get() = std::move(connector); connector_ptr->get().set_connection_error_handler(base::Bind( &OnConnectError, connector_ptr, base::Passed(ConnectCallback{callback}))); auto serialized_pref_registry = SerializePrefRegistry(*pref_registry); @@ -155,4 +153,14 @@ std::move(callback))); } +void ConnectToPrefService(service_manager::Connector* connector, + scoped_refptr<PrefRegistry> pref_registry, + ConnectCallback callback, + base::StringPiece service_name) { + mojom::PrefStoreConnectorPtr pref_connector; + connector->BindInterface(service_name.as_string(), &pref_connector); + ConnectToPrefService(std::move(pref_connector), std::move(pref_registry), + std::move(callback)); +} + } // namespace prefs
diff --git a/services/preferences/public/cpp/pref_service_factory.h b/services/preferences/public/cpp/pref_service_factory.h index 9bae432..aeed45c 100644 --- a/services/preferences/public/cpp/pref_service_factory.h +++ b/services/preferences/public/cpp/pref_service_factory.h
@@ -32,6 +32,14 @@ using ConnectCallback = base::Callback<void(std::unique_ptr<::PrefService>)>; // Create a |PrefService| object acting as a client library for the pref +// service, using the provided |connector|. Connecting is asynchronous and +// |callback| will be called when it has been established. All preferences that +// will be accessed need to be registered in |pref_registry| first. +void ConnectToPrefService(mojom::PrefStoreConnectorPtr connector, + scoped_refptr<PrefRegistry> pref_registry, + ConnectCallback callback); + +// Create a |PrefService| object acting as a client library for the pref // service, by connecting to the service using |connector|. Connecting is // asynchronous and |callback| will be called when it has been established. All // preferences that will be accessed need to be registered in |pref_registry|
diff --git a/services/preferences/public/interfaces/preferences.mojom b/services/preferences/public/interfaces/preferences.mojom index 02a8bf9..c6385e7 100644 --- a/services/preferences/public/interfaces/preferences.mojom +++ b/services/preferences/public/interfaces/preferences.mojom
@@ -11,7 +11,6 @@ const string kServiceName = "preferences"; const string kLocalStateServiceName = "local_state"; -const string kForwarderServiceName = "preferences_forwarder"; // The know pref store types. //
diff --git a/services/resource_coordinator/BUILD.gn b/services/resource_coordinator/BUILD.gn index d1dbea1..c0f9c37 100644 --- a/services/resource_coordinator/BUILD.gn +++ b/services/resource_coordinator/BUILD.gn
@@ -83,6 +83,7 @@ "memory_instrumentation/coordinator_impl_unittest.cc", "memory_instrumentation/process_map_unittest.cc", "public/cpp/memory_instrumentation/os_metrics_unittest.cc", + "public/cpp/memory_instrumentation/struct_traits_unittest.cc", "public/cpp/memory_instrumentation/tracing_integration_unittest.cc", "public/cpp/tracing/chrome_trace_event_agent_unittest.cc", "tracing/agent_registry_unittest.cc",
diff --git a/services/resource_coordinator/public/cpp/memory_instrumentation/client_process_impl.h b/services/resource_coordinator/public/cpp/memory_instrumentation/client_process_impl.h index b61118c..6e52334 100644 --- a/services/resource_coordinator/public/cpp/memory_instrumentation/client_process_impl.h +++ b/services/resource_coordinator/public/cpp/memory_instrumentation/client_process_impl.h
@@ -29,7 +29,7 @@ // local dump manager remotely connects to the Coordinator service. In the // browser process, it locally connects to the Coordinator service. class SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_EXPORT ClientProcessImpl - : public NON_EXPORTED_BASE(mojom::ClientProcess) { + : public mojom::ClientProcess { public: struct SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_EXPORT Config { public:
diff --git a/services/resource_coordinator/public/cpp/memory_instrumentation/struct_traits_unittest.cc b/services/resource_coordinator/public/cpp/memory_instrumentation/struct_traits_unittest.cc new file mode 100644 index 0000000..6d441b4a0 --- /dev/null +++ b/services/resource_coordinator/public/cpp/memory_instrumentation/struct_traits_unittest.cc
@@ -0,0 +1,42 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <utility> + +#include "base/trace_event/heap_profiler_serialization_state.h" +#include "base/trace_event/memory_dump_request_args.h" +#include "services/resource_coordinator/public/cpp/memory_instrumentation/memory_instrumentation_struct_traits.h" +#include "services/resource_coordinator/public/interfaces/memory_instrumentation/memory_instrumentation.mojom.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace memory_instrumentation { + +using base::trace_event::MemoryDumpRequestArgs; +using base::trace_event::MemoryDumpLevelOfDetail; +using base::trace_event::MemoryDumpType; + +namespace { + +using StructTraitsTest = testing::Test; + +// Test StructTrait serialization and deserialization for copyable type. |input| +// will be serialized and then deserialized into |output|. +template <class MojomType, class Type> +void SerializeAndDeserialize(const Type& input, Type* output) { + MojomType::Deserialize(MojomType::Serialize(&input), output); +} + +} // namespace + +TEST_F(StructTraitsTest, MemoryDumpRequestArgs) { + MemoryDumpRequestArgs input{10u, MemoryDumpType::SUMMARY_ONLY, + MemoryDumpLevelOfDetail::DETAILED}; + MemoryDumpRequestArgs output; + SerializeAndDeserialize<mojom::RequestArgs>(input, &output); + EXPECT_EQ(output.dump_guid, 10u); + EXPECT_EQ(output.dump_type, MemoryDumpType::SUMMARY_ONLY); + EXPECT_EQ(output.level_of_detail, MemoryDumpLevelOfDetail::DETAILED); +} + +} // namespace memory_instrumentation
diff --git a/services/ui/input_devices/BUILD.gn b/services/ui/input_devices/BUILD.gn index a03e55c0..f99b761 100644 --- a/services/ui/input_devices/BUILD.gn +++ b/services/ui/input_devices/BUILD.gn
@@ -25,6 +25,7 @@ "touch_device_server.cc", "touch_device_server.h", ] + deps += [ "//ui/display/manager" ] } }
diff --git a/services/ui/input_devices/touch_device_server.cc b/services/ui/input_devices/touch_device_server.cc index 30c7dc5..c32de4c 100644 --- a/services/ui/input_devices/touch_device_server.cc +++ b/services/ui/input_devices/touch_device_server.cc
@@ -28,11 +28,8 @@ } void TouchDeviceServer::ConfigureTouchDevices( - const std::unordered_map<int32_t, double>& transport_scales, - const std::vector<display::TouchDeviceTransform>& transforms) { - std::map<int32_t, double> scales(transport_scales.begin(), - transport_scales.end()); - touch_transform_setter_->ConfigureTouchDevices(scales, transforms); + const std::vector<ui::TouchDeviceTransform>& transforms) { + touch_transform_setter_->ConfigureTouchDevices(transforms); } void TouchDeviceServer::BindTouchDeviceServerRequest(
diff --git a/services/ui/input_devices/touch_device_server.h b/services/ui/input_devices/touch_device_server.h index acb4e78..b27fd0f 100644 --- a/services/ui/input_devices/touch_device_server.h +++ b/services/ui/input_devices/touch_device_server.h
@@ -32,8 +32,7 @@ // mojom::TouchDeviceServer: void ConfigureTouchDevices( - const std::unordered_map<int32_t, double>& transport_scales, - const std::vector<display::TouchDeviceTransform>& transforms) override; + const std::vector<ui::TouchDeviceTransform>& transforms) override; private: void BindTouchDeviceServerRequest(
diff --git a/services/ui/public/interfaces/input_devices/BUILD.gn b/services/ui/public/interfaces/input_devices/BUILD.gn index f4e7e5d..e5bb0ec 100644 --- a/services/ui/public/interfaces/input_devices/BUILD.gn +++ b/services/ui/public/interfaces/input_devices/BUILD.gn
@@ -16,7 +16,7 @@ if (is_chromeos) { sources += [ "touch_device_server.mojom" ] - public_deps += [ "//ui/display/manager/chromeos/mojo:interfaces" ] + public_deps += [ "//ui/events/devices/mojo" ] if (use_ozone) { sources += [ "input_device_controller.mojom" ] public_deps += [ "//mojo/common:common_custom_types" ]
diff --git a/services/ui/public/interfaces/input_devices/touch_device_server.mojom b/services/ui/public/interfaces/input_devices/touch_device_server.mojom index 9b59791..fefcb6f8 100644 --- a/services/ui/public/interfaces/input_devices/touch_device_server.mojom +++ b/services/ui/public/interfaces/input_devices/touch_device_server.mojom
@@ -4,10 +4,9 @@ module ui.mojom; -import "ui/display/manager/chromeos/mojo/touch_device_transform.mojom"; +import "ui/events/devices/mojo/touch_device_transform.mojom"; interface TouchDeviceServer { - // Reset the touch configuration. |scales| maps from touch_id to the scale. - ConfigureTouchDevices(map<int32, double> scales, - array<display.mojom.TouchDeviceTransform> transforms); + // Reset the touch configuration. + ConfigureTouchDevices(array<ui.mojom.TouchDeviceTransform> transforms); };
diff --git a/services/viz/public/cpp/compositing/begin_frame_args.typemap b/services/viz/public/cpp/compositing/begin_frame_args.typemap new file mode 100644 index 0000000..c680d482 --- /dev/null +++ b/services/viz/public/cpp/compositing/begin_frame_args.typemap
@@ -0,0 +1,19 @@ +# Copyright 2016 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +mojom = "//services/viz/public/interfaces/compositing/begin_frame_args.mojom" +public_headers = [ "//components/viz/common/frame_sinks/begin_frame_args.h" ] +traits_headers = + [ "//services/viz/public/cpp/compositing/begin_frame_args_struct_traits.h" ] +deps = [ + "//components/viz/common", + "//mojo/common:struct_traits", +] +sources = [ + "//services/viz/public/cpp/compositing/begin_frame_args_struct_traits.cc", +] +type_mappings = [ + "viz.mojom.BeginFrameArgs=viz::BeginFrameArgs", + "viz.mojom.BeginFrameAck=viz::BeginFrameAck", +]
diff --git a/services/viz/public/cpp/compositing/begin_frame_args_for_blink.typemap b/services/viz/public/cpp/compositing/begin_frame_args_for_blink.typemap new file mode 100644 index 0000000..25f893f1 --- /dev/null +++ b/services/viz/public/cpp/compositing/begin_frame_args_for_blink.typemap
@@ -0,0 +1,17 @@ +# Copyright 2016 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +mojom = "//services/viz/public/interfaces/compositing/begin_frame_args.mojom" + +public_headers = [ "//components/viz/common/frame_sinks/begin_frame_args.h" ] +traits_headers = + [ "//services/viz/public/cpp/compositing/begin_frame_args_struct_traits.h" ] +deps = [ + "//cc", + "//mojo/common:struct_traits", +] +type_mappings = [ + "viz.mojom.BeginFrameArgs=viz::BeginFrameArgs", + "viz.mojom.BeginFrameAck=viz::BeginFrameAck", +]
diff --git a/services/viz/public/cpp/compositing/begin_frame_args_struct_traits.cc b/services/viz/public/cpp/compositing/begin_frame_args_struct_traits.cc new file mode 100644 index 0000000..5e5f617 --- /dev/null +++ b/services/viz/public/cpp/compositing/begin_frame_args_struct_traits.cc
@@ -0,0 +1,39 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "services/viz/public/cpp/compositing/begin_frame_args_struct_traits.h" + +#include "ipc/ipc_message_utils.h" +#include "mojo/common/common_custom_types_struct_traits.h" + +namespace mojo { + +// static +bool StructTraits<viz::mojom::BeginFrameArgsDataView, viz::BeginFrameArgs>:: + Read(viz::mojom::BeginFrameArgsDataView data, viz::BeginFrameArgs* out) { + if (!data.ReadFrameTime(&out->frame_time) || + !data.ReadDeadline(&out->deadline) || + !data.ReadInterval(&out->interval)) { + return false; + } + out->source_id = data.source_id(); + out->sequence_number = data.sequence_number(); + // TODO(eseckler): Use EnumTraits for |type|. + out->type = static_cast<viz::BeginFrameArgs::BeginFrameArgsType>(data.type()); + out->on_critical_path = data.on_critical_path(); + return true; +} + +// static +bool StructTraits<viz::mojom::BeginFrameAckDataView, viz::BeginFrameAck>::Read( + viz::mojom::BeginFrameAckDataView data, + viz::BeginFrameAck* out) { + if (data.sequence_number() < viz::BeginFrameArgs::kStartingFrameNumber) + return false; + out->source_id = data.source_id(); + out->sequence_number = data.sequence_number(); + return true; +} + +} // namespace mojo
diff --git a/services/viz/public/cpp/compositing/begin_frame_args_struct_traits.h b/services/viz/public/cpp/compositing/begin_frame_args_struct_traits.h new file mode 100644 index 0000000..f30937d --- /dev/null +++ b/services/viz/public/cpp/compositing/begin_frame_args_struct_traits.h
@@ -0,0 +1,63 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SERVICES_VIZ_PUBLIC_CPP_COMPOSITING_BEGIN_FRAME_ARGS_STRUCT_TRAITS_H_ +#define SERVICES_VIZ_PUBLIC_CPP_COMPOSITING_BEGIN_FRAME_ARGS_STRUCT_TRAITS_H_ + +#include "components/viz/common/frame_sinks/begin_frame_args.h" +#include "services/viz/public/interfaces/compositing/begin_frame_args.mojom-shared.h" + +namespace mojo { + +template <> +struct StructTraits<viz::mojom::BeginFrameArgsDataView, viz::BeginFrameArgs> { + static base::TimeTicks frame_time(const viz::BeginFrameArgs& args) { + return args.frame_time; + } + + static base::TimeTicks deadline(const viz::BeginFrameArgs& args) { + return args.deadline; + } + + static base::TimeDelta interval(const viz::BeginFrameArgs& args) { + return args.interval; + } + + static uint64_t sequence_number(const viz::BeginFrameArgs& args) { + return args.sequence_number; + } + + static uint32_t source_id(const viz::BeginFrameArgs& args) { + return args.source_id; + } + + static viz::mojom::BeginFrameArgsType type(const viz::BeginFrameArgs& args) { + return static_cast<viz::mojom::BeginFrameArgsType>(args.type); + } + + static bool on_critical_path(const viz::BeginFrameArgs& args) { + return args.on_critical_path; + } + + static bool Read(viz::mojom::BeginFrameArgsDataView data, + viz::BeginFrameArgs* out); +}; + +template <> +struct StructTraits<viz::mojom::BeginFrameAckDataView, viz::BeginFrameAck> { + static uint64_t sequence_number(const viz::BeginFrameAck& ack) { + return ack.sequence_number; + } + + static uint32_t source_id(const viz::BeginFrameAck& ack) { + return ack.source_id; + } + + static bool Read(viz::mojom::BeginFrameAckDataView data, + viz::BeginFrameAck* out); +}; + +} // namespace mojo + +#endif // SERVICES_VIZ_PUBLIC_CPP_COMPOSITING_BEGIN_FRAME_ARGS_STRUCT_TRAITS_H_
diff --git a/services/viz/public/cpp/compositing/compositor_frame_metadata_struct_traits.cc b/services/viz/public/cpp/compositing/compositor_frame_metadata_struct_traits.cc index 9b03e5b..f36c61ea 100644 --- a/services/viz/public/cpp/compositing/compositor_frame_metadata_struct_traits.cc +++ b/services/viz/public/cpp/compositing/compositor_frame_metadata_struct_traits.cc
@@ -4,8 +4,8 @@ #include "services/viz/public/cpp/compositing/compositor_frame_metadata_struct_traits.h" -#include "cc/ipc/begin_frame_args_struct_traits.h" #include "cc/ipc/surface_id_struct_traits.h" +#include "services/viz/public/cpp/compositing/begin_frame_args_struct_traits.h" #include "services/viz/public/cpp/compositing/selection_struct_traits.h" #include "ui/gfx/mojo/selection_bound_struct_traits.h" #include "ui/latency/mojo/latency_info_struct_traits.h"
diff --git a/services/viz/public/cpp/compositing/compositor_frame_metadata_struct_traits.h b/services/viz/public/cpp/compositing/compositor_frame_metadata_struct_traits.h index aaba32e..6b44627 100644 --- a/services/viz/public/cpp/compositing/compositor_frame_metadata_struct_traits.h +++ b/services/viz/public/cpp/compositing/compositor_frame_metadata_struct_traits.h
@@ -8,6 +8,7 @@ #include <vector> #include "cc/output/compositor_frame_metadata.h" +#include "services/viz/public/cpp/compositing/begin_frame_args_struct_traits.h" #include "services/viz/public/interfaces/compositing/compositor_frame_metadata.mojom-shared.h" namespace mojo {
diff --git a/services/viz/public/cpp/compositing/struct_traits_unittest.cc b/services/viz/public/cpp/compositing/struct_traits_unittest.cc index 2b5a97c..92332bf 100644 --- a/services/viz/public/cpp/compositing/struct_traits_unittest.cc +++ b/services/viz/public/cpp/compositing/struct_traits_unittest.cc
@@ -5,7 +5,6 @@ #include <utility> #include "base/message_loop/message_loop.h" -#include "cc/ipc/begin_frame_args_struct_traits.h" #include "cc/ipc/copy_output_request_struct_traits.h" #include "cc/ipc/copy_output_result_struct_traits.h" #include "cc/ipc/filter_operation_struct_traits.h" @@ -32,6 +31,7 @@ #include "ipc/ipc_message_utils.h" #include "mojo/common/common_custom_types_struct_traits.h" #include "mojo/public/cpp/bindings/binding_set.h" +#include "services/viz/public/cpp/compositing/begin_frame_args_struct_traits.h" #include "services/viz/public/cpp/compositing/compositor_frame_metadata_struct_traits.h" #include "services/viz/public/cpp/compositing/compositor_frame_struct_traits.h" #include "services/viz/public/cpp/compositing/render_pass_struct_traits.h" @@ -41,6 +41,7 @@ #include "services/viz/public/cpp/compositing/surface_info_struct_traits.h" #include "services/viz/public/cpp/compositing/surface_sequence_struct_traits.h" #include "services/viz/public/cpp/compositing/transferable_resource_struct_traits.h" +#include "services/viz/public/interfaces/compositing/begin_frame_args.mojom.h" #include "services/viz/public/interfaces/compositing/compositor_frame.mojom.h" #include "services/viz/public/interfaces/compositing/returned_resource.mojom.h" #include "services/viz/public/interfaces/compositing/surface_info.mojom.h" @@ -79,6 +80,53 @@ } // namespace +TEST_F(StructTraitsTest, BeginFrameArgs) { + const base::TimeTicks frame_time = base::TimeTicks::Now(); + const base::TimeTicks deadline = base::TimeTicks::Now(); + const base::TimeDelta interval = base::TimeDelta::FromMilliseconds(1337); + const BeginFrameArgs::BeginFrameArgsType type = BeginFrameArgs::NORMAL; + const bool on_critical_path = true; + const uint32_t source_id = 5; + const uint64_t sequence_number = 10; + BeginFrameArgs input; + input.source_id = source_id; + input.sequence_number = sequence_number; + input.frame_time = frame_time; + input.deadline = deadline; + input.interval = interval; + input.type = type; + input.on_critical_path = on_critical_path; + + BeginFrameArgs output; + SerializeAndDeserialize<mojom::BeginFrameArgs>(input, &output); + + EXPECT_EQ(source_id, output.source_id); + EXPECT_EQ(sequence_number, output.sequence_number); + EXPECT_EQ(frame_time, output.frame_time); + EXPECT_EQ(deadline, output.deadline); + EXPECT_EQ(interval, output.interval); + EXPECT_EQ(type, output.type); + EXPECT_EQ(on_critical_path, output.on_critical_path); +} + +TEST_F(StructTraitsTest, BeginFrameAck) { + const uint32_t source_id = 5; + const uint64_t sequence_number = 10; + const bool has_damage = true; + BeginFrameAck input; + input.source_id = source_id; + input.sequence_number = sequence_number; + input.has_damage = has_damage; + + BeginFrameAck output; + SerializeAndDeserialize<mojom::BeginFrameAck>(input, &output); + + EXPECT_EQ(source_id, output.source_id); + EXPECT_EQ(sequence_number, output.sequence_number); + // |has_damage| is not transmitted. + EXPECT_FALSE(output.has_damage); +} + TEST_F(StructTraitsTest, ResourceSettings) { constexpr size_t kArbitrarySize = 32; constexpr bool kArbitraryBool = true;
diff --git a/services/viz/public/cpp/compositing/typemaps.gni b/services/viz/public/cpp/compositing/typemaps.gni index f0c8342..253d8c93 100644 --- a/services/viz/public/cpp/compositing/typemaps.gni +++ b/services/viz/public/cpp/compositing/typemaps.gni
@@ -3,6 +3,7 @@ # found in the LICENSE file. typemaps = [ + "//services/viz/public/cpp/compositing/begin_frame_args.typemap", "//services/viz/public/cpp/compositing/compositor_frame.typemap", "//services/viz/public/cpp/compositing/compositor_frame_metadata.typemap", "//services/viz/public/cpp/compositing/render_pass.typemap",
diff --git a/services/viz/public/interfaces/compositing/BUILD.gn b/services/viz/public/interfaces/compositing/BUILD.gn index 5e99e8f..e9052fa 100644 --- a/services/viz/public/interfaces/compositing/BUILD.gn +++ b/services/viz/public/interfaces/compositing/BUILD.gn
@@ -6,6 +6,7 @@ mojom("compositing") { sources = [ + "begin_frame_args.mojom", "compositor_frame.mojom", "compositor_frame_metadata.mojom", "compositor_frame_sink.mojom", @@ -23,6 +24,7 @@ public_deps = [ "//cc/ipc:interfaces", "//gpu/ipc/common:interfaces", + "//mojo/common:common_custom_types", "//services/viz/public/interfaces/hit_test", "//ui/gfx/geometry/mojo", "//ui/gfx/mojo",
diff --git a/services/viz/public/interfaces/compositing/begin_frame_args.mojom b/services/viz/public/interfaces/compositing/begin_frame_args.mojom new file mode 100644 index 0000000..9c94a4a --- /dev/null +++ b/services/viz/public/interfaces/compositing/begin_frame_args.mojom
@@ -0,0 +1,32 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +module viz.mojom; + +import "mojo/common/time.mojom"; + +enum BeginFrameArgsType { + INVALID, + NORMAL, + MISSED, + BEGIN_FRAME_ARGS_TYPE_MAX +}; + +// See cc/output/begin_frame_args.h. +struct BeginFrameArgs { + mojo.common.mojom.TimeTicks frame_time; + mojo.common.mojom.TimeTicks deadline; + mojo.common.mojom.TimeDelta interval; + uint64 sequence_number; + uint32 source_id; + BeginFrameArgsType type; + bool on_critical_path; +}; + +// See cc/output/begin_frame_args.h. +struct BeginFrameAck { + uint64 sequence_number; + uint32 source_id; + // |has_damage| is implicit through IPC message name, so not transmitted. +};
diff --git a/services/viz/public/interfaces/compositing/compositor_frame_metadata.mojom b/services/viz/public/interfaces/compositing/compositor_frame_metadata.mojom index 31afeb8..9084ec9 100644 --- a/services/viz/public/interfaces/compositing/compositor_frame_metadata.mojom +++ b/services/viz/public/interfaces/compositing/compositor_frame_metadata.mojom
@@ -4,8 +4,8 @@ module viz.mojom; -import "cc/ipc/begin_frame_args.mojom"; import "cc/ipc/surface_id.mojom"; +import "services/viz/public/interfaces/compositing/begin_frame_args.mojom"; import "services/viz/public/interfaces/compositing/selection.mojom"; import "ui/latency/mojo/latency_info.mojom"; import "ui/gfx/geometry/mojo/geometry.mojom"; @@ -34,6 +34,6 @@ array<cc.mojom.SurfaceId> activation_dependencies; bool can_activate_before_dependencies; uint32 content_source_id; - cc.mojom.BeginFrameAck begin_frame_ack; + BeginFrameAck begin_frame_ack; uint32 frame_token; };
diff --git a/services/viz/public/interfaces/compositing/compositor_frame_sink.mojom b/services/viz/public/interfaces/compositing/compositor_frame_sink.mojom index fde38d4f..80139533 100644 --- a/services/viz/public/interfaces/compositing/compositor_frame_sink.mojom +++ b/services/viz/public/interfaces/compositing/compositor_frame_sink.mojom
@@ -4,14 +4,14 @@ module viz.mojom; -import "cc/ipc/begin_frame_args.mojom"; import "cc/ipc/copy_output_request.mojom"; import "cc/ipc/frame_sink_id.mojom"; import "cc/ipc/local_surface_id.mojom"; import "cc/ipc/surface_id.mojom"; -import "services/viz/public/interfaces/hit_test/hit_test_region_list.mojom"; +import "services/viz/public/interfaces/compositing/begin_frame_args.mojom"; import "services/viz/public/interfaces/compositing/compositor_frame.mojom"; import "services/viz/public/interfaces/compositing/returned_resource.mojom"; +import "services/viz/public/interfaces/hit_test/hit_test_region_list.mojom"; import "ui/gfx/geometry/mojo/geometry.mojom"; // A CompositorFrameSink is an interface for receiving CompositorFrame @@ -37,13 +37,13 @@ // DidReceiveCompositorFrameAck() asynchronously when the frame has been // processed in order to unthrottle the next frame. SubmitCompositorFrame(cc.mojom.LocalSurfaceId local_surface_id, - viz.mojom.CompositorFrame frame, - viz.mojom.HitTestRegionList? hit_test_region_list, + CompositorFrame frame, + HitTestRegionList? hit_test_region_list, uint64 submit_time); // Notifies the frame sink that a BeginFrame was completed, but that no // CompositorFrame was produced as a result of it. - DidNotProduceFrame(cc.mojom.BeginFrameAck ack); + DidNotProduceFrame(BeginFrameAck ack); }; interface CompositorFrameSinkClient { @@ -57,7 +57,7 @@ DidReceiveCompositorFrameAck(array<ReturnedResource> resources); // Notification for the client to generate a CompositorFrame. - OnBeginFrame(cc.mojom.BeginFrameArgs args); + OnBeginFrame(BeginFrameArgs args); // Inform the client that OnBeginFrame may not be called for some time. OnBeginFramePausedChanged(bool paused);
diff --git a/skia/config/SkUserConfig.h b/skia/config/SkUserConfig.h index bb1edca..72f8a952 100644 --- a/skia/config/SkUserConfig.h +++ b/skia/config/SkUserConfig.h
@@ -198,6 +198,10 @@ # define SK_SUPPORT_LEGACY_ANISOTROPIC_MIPMAP_SCALE #endif +#ifndef SK_SUPPORT_LEGACY_BILERP2 +#define SK_SUPPORT_LEGACY_BILERP2 +#endif + // Remove this after we fixed all the issues related to the new SDF algorithm // (https://codereview.chromium.org/1643143002) #ifndef SK_USE_LEGACY_DISTANCE_FIELDS @@ -224,11 +228,6 @@ #define SK_SUPPORT_LEGACY_RP_BLENDS #endif -// Transition from Gaussian filtering for small sigma to linear filtering -#ifndef SK_SUPPORT_LEGACY_USE_GAUSS_FOR_SMALL_RADII -#define SK_SUPPORT_LEGACY_USE_GAUSS_FOR_SMALL_RADII -#endif - ///////////////////////// Imported from BUILD.gn and skia_common.gypi /* In some places Skia can use static initializers for global initialization,
diff --git a/storage/browser/blob/upload_blob_element_reader.h b/storage/browser/blob/upload_blob_element_reader.h index 6dd9119..8d5bedf 100644 --- a/storage/browser/blob/upload_blob_element_reader.h +++ b/storage/browser/blob/upload_blob_element_reader.h
@@ -27,8 +27,7 @@ // This class is a wrapper around the BlobReader to make it conform // to the net::UploadElementReader interface, and it also holds around the // handle to the blob so it stays in memory while we read it. -class STORAGE_EXPORT UploadBlobElementReader - : NON_EXPORTED_BASE(public net::UploadElementReader) { +class STORAGE_EXPORT UploadBlobElementReader : public net::UploadElementReader { public: UploadBlobElementReader(std::unique_ptr<BlobDataHandle> handle, FileSystemContext* file_system_context);
diff --git a/storage/browser/fileapi/async_file_util_adapter.h b/storage/browser/fileapi/async_file_util_adapter.h index 4777d92..4a3649f 100644 --- a/storage/browser/fileapi/async_file_util_adapter.h +++ b/storage/browser/fileapi/async_file_util_adapter.h
@@ -27,8 +27,7 @@ // // This instance (as thus this->sync_file_util_) is guaranteed to be alive // as far as FileSystemOperationContext given to each operation is kept alive. -class STORAGE_EXPORT AsyncFileUtilAdapter - : public NON_EXPORTED_BASE(AsyncFileUtil) { +class STORAGE_EXPORT AsyncFileUtilAdapter : public AsyncFileUtil { public: // Creates a new AsyncFileUtil for |sync_file_util|. This takes the // ownership of |sync_file_util|. (This doesn't take std::unique_ptr<> just
diff --git a/storage/browser/fileapi/file_system_file_stream_reader.h b/storage/browser/fileapi/file_system_file_stream_reader.h index ba69b1f..1c4ede0 100644 --- a/storage/browser/fileapi/file_system_file_stream_reader.h +++ b/storage/browser/fileapi/file_system_file_stream_reader.h
@@ -37,7 +37,7 @@ // on FileSystemOperation::GetSnapshotFile() which may force downloading // the entire contents for remote files. class STORAGE_EXPORT FileSystemFileStreamReader - : public NON_EXPORTED_BASE(storage::FileStreamReader) { + : public storage::FileStreamReader { public: ~FileSystemFileStreamReader() override;
diff --git a/storage/browser/fileapi/file_system_operation_impl.h b/storage/browser/fileapi/file_system_operation_impl.h index 77e9248..eed8df5 100644 --- a/storage/browser/fileapi/file_system_operation_impl.h +++ b/storage/browser/fileapi/file_system_operation_impl.h
@@ -28,8 +28,7 @@ class RecursiveOperationDelegate; // The default implementation of FileSystemOperation for file systems. -class STORAGE_EXPORT FileSystemOperationImpl - : public NON_EXPORTED_BASE(FileSystemOperation) { +class STORAGE_EXPORT FileSystemOperationImpl : public FileSystemOperation { public: ~FileSystemOperationImpl() override;
diff --git a/storage/browser/fileapi/file_system_quota_client.h b/storage/browser/fileapi/file_system_quota_client.h index 563184a..67adb9a 100644 --- a/storage/browser/fileapi/file_system_quota_client.h +++ b/storage/browser/fileapi/file_system_quota_client.h
@@ -31,8 +31,7 @@ // is called. // All of the public methods of this class are called by the quota manager // (except for the constructor/destructor). -class STORAGE_EXPORT FileSystemQuotaClient - : public NON_EXPORTED_BASE(storage::QuotaClient) { +class STORAGE_EXPORT FileSystemQuotaClient : public storage::QuotaClient { public: FileSystemQuotaClient( FileSystemContext* file_system_context,
diff --git a/storage/browser/fileapi/local_file_stream_reader.h b/storage/browser/fileapi/local_file_stream_reader.h index 9e9cd81..1cc8292a0 100644 --- a/storage/browser/fileapi/local_file_stream_reader.h +++ b/storage/browser/fileapi/local_file_stream_reader.h
@@ -33,8 +33,7 @@ // A thin wrapper of net::FileStream with range support for sliced file // handling. -class STORAGE_EXPORT LocalFileStreamReader - : public NON_EXPORTED_BASE(FileStreamReader) { +class STORAGE_EXPORT LocalFileStreamReader : public FileStreamReader { public: ~LocalFileStreamReader() override;
diff --git a/storage/browser/fileapi/local_file_stream_writer.h b/storage/browser/fileapi/local_file_stream_writer.h index dce2f80..47821db1 100644 --- a/storage/browser/fileapi/local_file_stream_writer.h +++ b/storage/browser/fileapi/local_file_stream_writer.h
@@ -30,8 +30,7 @@ namespace storage { // This class is a thin wrapper around net::FileStream for writing local files. -class STORAGE_EXPORT LocalFileStreamWriter - : public NON_EXPORTED_BASE(FileStreamWriter) { +class STORAGE_EXPORT LocalFileStreamWriter : public FileStreamWriter { public: ~LocalFileStreamWriter() override;
diff --git a/storage/browser/fileapi/sandbox_file_stream_writer.h b/storage/browser/fileapi/sandbox_file_stream_writer.h index 1a8f97e..9421fb9 100644 --- a/storage/browser/fileapi/sandbox_file_stream_writer.h +++ b/storage/browser/fileapi/sandbox_file_stream_writer.h
@@ -26,8 +26,7 @@ class FileSystemContext; class FileStreamWriter; -class STORAGE_EXPORT SandboxFileStreamWriter - : public NON_EXPORTED_BASE(FileStreamWriter) { +class STORAGE_EXPORT SandboxFileStreamWriter : public FileStreamWriter { public: SandboxFileStreamWriter(FileSystemContext* file_system_context, const FileSystemURL& url,
diff --git a/storage/browser/quota/quota_settings.cc b/storage/browser/quota/quota_settings.cc index 8f4a4a33..68598c2f 100644 --- a/storage/browser/quota/quota_settings.cc +++ b/storage/browser/quota/quota_settings.cc
@@ -11,6 +11,7 @@ #include "base/sys_info.h" #include "base/task_scheduler/post_task.h" #include "base/threading/thread_restrictions.h" +#include "build/build_config.h" #define UMA_HISTOGRAM_MBYTES(name, sample) \ UMA_HISTOGRAM_CUSTOM_COUNTS((name), static_cast<int>((sample) / kMBytes), 1, \ @@ -79,6 +80,8 @@ 1000 * kMBytes; #elif defined(OS_CHROMEOS) 1000 * kMBytes; +#elif defined(OS_FUCHSIA) + 1000 * kMBytes; #elif defined(OS_WIN) || defined(OS_LINUX) || defined(OS_MACOSX) 10000 * kMBytes; #else
diff --git a/styleguide/c++/c++11.html b/styleguide/c++/c++11.html index 0055ef7..d7f2a19 100644 --- a/styleguide/c++/c++11.html +++ b/styleguide/c++/c++11.html
@@ -590,8 +590,6 @@ <h2 id="whitelist"><a name="library-whitelist-14"></a>C++14 Allowed Library Features</h2> -<p>Nothing yet. Suggest something!</p> -<!-- <p>The following library features are currently allowed.</p> <table id="whitelist_lib_list" class="unlined striped"> @@ -605,9 +603,16 @@ <th style='width:240px;'>Notes and Discussion Thread</th> </tr> +<tr> +<td><code>std::make_unique</code></td> +<td><code>auto widget = std::make_unique<Widget>();</code></td> +<td>Allocates objects on the heap and immediately constructs an <code>std::unique_ptr</code> to assume ownership.</td> +<td><a href="http://en.cppreference.com/w/cpp/memory/unique_ptr/make_unique">std::make_unique</a></td> +<td>Should replace <code>base::MakeUnique</code> and <code>WTF::MakeUnique</code>. <a href="https://groups.google.com/a/chromium.org/d/msg/cxx/ow7hmdDm4yw/EDEvBRi_BQAJ">Discussion thread</a></td> +</tr> + </tbody> </table> ---> <h2 id="blacklist">C++11 and C++14 Blacklist (Disallowed and Banned Features)</h2> @@ -1190,15 +1195,6 @@ <td>This also includes the alias, <code>std::index_sequence</code>, which is the specialization for <code>size_t</code>. Should replace <code>base::IndexSequence</code>.</td> </tr> -<tr> -<td><code>std::make_unique</code></td> -<td><code>auto widget = std::make_unique<Widget>();</code></td> -<td>Allocates objects on the heap and immediately constructs an <code>std::unique_ptr</code> to assume ownership.</td> -<td><a href="http://en.cppreference.com/w/cpp/memory/unique_ptr/make_unique">std::make_unique</a></td> -<td>Should replace <code>base::MakeUnique</code> and <code>WTF::MakeUnique</code>.</td> -</tr> - -<tr> <td><code>std::string</code> literals</td> <td><code> #include <string><br>
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json index 45851ef5..627821b 100644 --- a/testing/buildbot/chromium.chromiumos.json +++ b/testing/buildbot/chromium.chromiumos.json
@@ -4,487 +4,6 @@ "All" ] }, - "Linux ChromiumOS Ozone Tests (1)": { - "gtest_tests": [ - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "accessibility_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "angle_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "app_list_presenter_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "app_list_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "app_shell_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "ash_content_unittests" - }, - { - "args": [ - "--mash", - "--test-launcher-filter-file=../../testing/buildbot/filters/ash_unittests_mash.filter" - ], - "name": "ash_unittests-mash", - "override_isolate_target": "ash_unittests", - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "ash_unittests" - }, - { - "args": [ - "--mus", - "--test-launcher-filter-file=../../testing/buildbot/filters/ash_unittests_mus.filter" - ], - "name": "ash_unittests-mus", - "override_isolate_target": "ash_unittests", - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "ash_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "ash_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "aura_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "base_unittests" - }, - { - "args": [ - "--ozone-platform=headless" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "shards": 5 - }, - "test": "browser_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "cacheinvalidation_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "capture_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "chrome_app_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "chromeos_components_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "chromeos_unittests" - }, - { - "args": [ - "--ozone-platform=headless" - ], - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "chromevox_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "components_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "compositor_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true, - "shards": 2 - }, - "test": "content_browsertests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "content_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "crypto_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "device_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "display_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "events_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "exo_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "extensions_browsertests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "extensions_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "gcm_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "gfx_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "gl_unittests_ozone" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "google_apis_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "gpu_ipc_service_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "gpu_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true, - "shards": 3 - }, - "test": "interactive_ui_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "ipc_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "jingle_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "keyboard_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "latency_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "mash_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "media_blink_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "media_service_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "media_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "message_center_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "midi_unittests" - }, - { - "args": [ - "--ozone-platform=headless", - "--override-use-software-gl-for-tests", - "--test-launcher-filter-file=../../testing/buildbot/filters/mus.browser_tests.filter" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "hard_timeout": 900 - }, - "test": "mus_browser_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "nacl_helper_nonsfi_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "nacl_loader_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "native_theme_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "net_unittests" - }, - { - "args": [ - "--ozone-platform=headless" - ], - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "ozone_gl_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "ozone_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "pdf_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "ppapi_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "printing_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "remoting_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "sandbox_linux_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "services_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "skia_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "sql_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "storage_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "sync_integration_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "ui_arc_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "ui_base_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "ui_chromeos_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "ui_touch_selection_unittests" - }, - { - "args": [ - "--ozone-platform=headless" - ], - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "url_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "views_mus_interactive_ui_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "views_mus_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "views_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "viz_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "wm_unittests" - } - ] - }, "Linux ChromiumOS Tests (1)": { "gtest_tests": [ { @@ -622,7 +141,8 @@ }, { "swarming": { - "can_use_on_swarming_builders": true + "can_use_on_swarming_builders": true, + "shards": 2 }, "test": "content_browsertests" }, @@ -690,6 +210,12 @@ "swarming": { "can_use_on_swarming_builders": true }, + "test": "gl_unittests_ozone" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, "test": "google_apis_unittests" }, {
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index cf86565..99376f46 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -10576,19 +10576,95 @@ }, "Fuchsia (dbg)": { "additional_compile_targets": [ - "base_unittests", - "crypto_unittests", "gl_unittests", - "ipc_tests", "media_unittests", - "mojo_common_unittests", - "mojo_js_unittests", - "mojo_public_bindings_unittests", - "mojo_public_system_unittests", - "mojo_system_unittests", - "net_unittests", - "skia_unittests", - "ui_base_unittests" + "net_unittests" + ], + "gtest_tests": [ + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.base_unittests.filter" + ], + "swarming": { + "can_use_on_swarming_builders": false + }, + "test": "base_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": false + }, + "test": "crypto_unittests" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.ipc_tests.filter" + ], + "swarming": { + "can_use_on_swarming_builders": false + }, + "test": "ipc_tests" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.media_unittests.filter" + ], + "swarming": { + "can_use_on_swarming_builders": false + }, + "test": "media_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": false + }, + "test": "mojo_common_unittests" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.mojo_js_unittests.filter" + ], + "swarming": { + "can_use_on_swarming_builders": false + }, + "test": "mojo_js_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": false + }, + "test": "mojo_public_bindings_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": false + }, + "test": "mojo_public_system_unittests" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.mojo_system_unittests.filter" + ], + "swarming": { + "can_use_on_swarming_builders": false + }, + "test": "mojo_system_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": false + }, + "test": "skia_unittests" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.ui_base_unittests.filter" + ], + "swarming": { + "can_use_on_swarming_builders": false + }, + "test": "ui_base_unittests" + } ] }, "Fuchsia Compile": { @@ -13629,26 +13705,37 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { + "gpu": "none", + "os": "Mac-10.9.5", + "pool": "Chrome" + }, + { + "gpu": "none", + "os": "Mac-10.10.5", + "pool": "Chrome" + }, + { + "gpu": "none", + "os": "Mac-10.11.6", + "pool": "Chrome" + }, + { "gpu": "8086:0d26", "hidpi": "1", - "os": "Mac-10.12.5" - }, - { - "gpu": "none", - "os": "Mac-10.9.5" - }, - { - "gpu": "none", - "os": "Mac-10.10.5" - }, - { - "gpu": "none", - "os": "Mac-10.11.6" + "os": "Mac-10.11.6", + "pool": "Chrome-perf" }, { "gpu": "8086:0a2e", "hidpi": "0", - "os": "Mac-10.12.5" + "os": "Mac-10.12.5", + "pool": "Chrome" + }, + { + "gpu": "8086:0d26", + "hidpi": "1", + "os": "Mac-10.12.5", + "pool": "Chrome" } ], "shards": 2
diff --git a/testing/buildbot/chromium.perf.fyi.json b/testing/buildbot/chromium.perf.fyi.json index 9ea3f75..126feea 100644 --- a/testing/buildbot/chromium.perf.fyi.json +++ b/testing/buildbot/chromium.perf.fyi.json
@@ -548,6 +548,68 @@ }, { "args": [ + "blink_perf.owp_storage", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release_x64" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.owp_storage", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:22b1", + "id": "build139-b1", + "os": "Windows-10-10586", + "pool": "Chrome-perf-fyi" + } + ], + "expiration": 72000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ + "blink_perf.owp_storage", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--max-failures=5", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.owp_storage.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:22b1", + "id": "build139-b1", + "os": "Windows-10-10586", + "pool": "Chrome-perf-fyi" + } + ], + "expiration": 72000, + "hard_timeout": 10800, + "ignore_task_failure": true, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ "blink_perf.paint", "-v", "--upload-results", @@ -5833,6 +5895,68 @@ }, { "args": [ + "blink_perf.owp_storage", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release_x64" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.owp_storage", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "1002:9874", + "id": "build203-b4", + "os": "Windows-10-10586", + "pool": "Chrome-perf-fyi" + } + ], + "expiration": 72000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ + "blink_perf.owp_storage", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--max-failures=5", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.owp_storage.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "1002:9874", + "id": "build203-b4", + "os": "Windows-10-10586", + "pool": "Chrome-perf-fyi" + } + ], + "expiration": 72000, + "hard_timeout": 10800, + "ignore_task_failure": true, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ "blink_perf.paint", "-v", "--upload-results",
diff --git a/testing/buildbot/chromium.perf.json b/testing/buildbot/chromium.perf.json index 2a10826..86be2079 100644 --- a/testing/buildbot/chromium.perf.json +++ b/testing/buildbot/chromium.perf.json
@@ -506,6 +506,68 @@ }, { "args": [ + "blink_perf.owp_storage", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-chromium" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.owp_storage", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build13-b1--device3", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 72000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ + "blink_perf.owp_storage", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--max-failures=5", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.owp_storage.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build13-b1--device3", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 72000, + "hard_timeout": 10800, + "ignore_task_failure": true, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ "blink_perf.paint", "-v", "--upload-results", @@ -4174,130 +4236,6 @@ }, { "args": [ - "start_with_ext.cold.blank_page", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-chromium" - ], - "isolate_name": "telemetry_perf_tests", - "name": "start_with_ext.cold.blank_page", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build48-b1--device4", - "os": "Android", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600, - "upload_test_results": false - } - }, - { - "args": [ - "start_with_ext.cold.blank_page", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=reference", - "--max-failures=5", - "--output-trace-tag=_ref" - ], - "isolate_name": "telemetry_perf_tests", - "name": "start_with_ext.cold.blank_page.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build48-b1--device4", - "os": "Android", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": true, - "io_timeout": 3600, - "upload_test_results": false - } - }, - { - "args": [ - "start_with_ext.warm.blank_page", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-chromium" - ], - "isolate_name": "telemetry_perf_tests", - "name": "start_with_ext.warm.blank_page", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build13-b1--device7", - "os": "Android", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600, - "upload_test_results": false - } - }, - { - "args": [ - "start_with_ext.warm.blank_page", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=reference", - "--max-failures=5", - "--output-trace-tag=_ref" - ], - "isolate_name": "telemetry_perf_tests", - "name": "start_with_ext.warm.blank_page.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build13-b1--device7", - "os": "Android", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": true, - "io_timeout": 3600, - "upload_test_results": false - } - }, - { - "args": [ "start_with_url.cold.startup_pages", "-v", "--upload-results", @@ -6059,6 +5997,68 @@ }, { "args": [ + "blink_perf.owp_storage", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-chromium" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.owp_storage", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build73-b1--device3", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 72000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ + "blink_perf.owp_storage", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--max-failures=5", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.owp_storage.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build73-b1--device3", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 72000, + "hard_timeout": 10800, + "ignore_task_failure": true, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ "blink_perf.paint", "-v", "--upload-results", @@ -9644,130 +9644,6 @@ }, { "args": [ - "start_with_ext.cold.blank_page", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-chromium" - ], - "isolate_name": "telemetry_perf_tests", - "name": "start_with_ext.cold.blank_page", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build75-b1--device4", - "os": "Android", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600, - "upload_test_results": false - } - }, - { - "args": [ - "start_with_ext.cold.blank_page", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=reference", - "--max-failures=5", - "--output-trace-tag=_ref" - ], - "isolate_name": "telemetry_perf_tests", - "name": "start_with_ext.cold.blank_page.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build75-b1--device4", - "os": "Android", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": true, - "io_timeout": 3600, - "upload_test_results": false - } - }, - { - "args": [ - "start_with_ext.warm.blank_page", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-chromium" - ], - "isolate_name": "telemetry_perf_tests", - "name": "start_with_ext.warm.blank_page", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build73-b1--device7", - "os": "Android", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600, - "upload_test_results": false - } - }, - { - "args": [ - "start_with_ext.warm.blank_page", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=reference", - "--max-failures=5", - "--output-trace-tag=_ref" - ], - "isolate_name": "telemetry_perf_tests", - "name": "start_with_ext.warm.blank_page.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build73-b1--device7", - "os": "Android", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": true, - "io_timeout": 3600, - "upload_test_results": false - } - }, - { - "args": [ "start_with_url.cold.startup_pages", "-v", "--upload-results", @@ -11281,6 +11157,37 @@ }, { "args": [ + "blink_perf.owp_storage", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "blink_perf.owp_storage", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build164-b1--device3", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 72000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ "blink_perf.paint", "-v", "--upload-results", @@ -13079,68 +12986,6 @@ }, { "args": [ - "start_with_ext.cold.blank_page", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "start_with_ext.cold.blank_page", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build166-b1--device4", - "os": "Android", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600, - "upload_test_results": false - } - }, - { - "args": [ - "start_with_ext.warm.blank_page", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "start_with_ext.warm.blank_page", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build164-b1--device7", - "os": "Android", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600, - "upload_test_results": false - } - }, - { - "args": [ "start_with_url.cold.startup_pages", "-v", "--upload-results", @@ -14261,6 +14106,68 @@ }, { "args": [ + "blink_perf.owp_storage", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-chromium" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.owp_storage", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build15-b1--device3", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 72000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ + "blink_perf.owp_storage", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--max-failures=5", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.owp_storage.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build15-b1--device3", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 72000, + "hard_timeout": 10800, + "ignore_task_failure": true, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ "blink_perf.paint", "-v", "--upload-results", @@ -17929,130 +17836,6 @@ }, { "args": [ - "start_with_ext.cold.blank_page", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-chromium" - ], - "isolate_name": "telemetry_perf_tests", - "name": "start_with_ext.cold.blank_page", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build45-b1--device4", - "os": "Android", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600, - "upload_test_results": false - } - }, - { - "args": [ - "start_with_ext.cold.blank_page", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=reference", - "--max-failures=5", - "--output-trace-tag=_ref" - ], - "isolate_name": "telemetry_perf_tests", - "name": "start_with_ext.cold.blank_page.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build45-b1--device4", - "os": "Android", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": true, - "io_timeout": 3600, - "upload_test_results": false - } - }, - { - "args": [ - "start_with_ext.warm.blank_page", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-chromium" - ], - "isolate_name": "telemetry_perf_tests", - "name": "start_with_ext.warm.blank_page", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build15-b1--device7", - "os": "Android", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600, - "upload_test_results": false - } - }, - { - "args": [ - "start_with_ext.warm.blank_page", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=reference", - "--max-failures=5", - "--output-trace-tag=_ref" - ], - "isolate_name": "telemetry_perf_tests", - "name": "start_with_ext.warm.blank_page.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build15-b1--device7", - "os": "Android", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": true, - "io_timeout": 3600, - "upload_test_results": false - } - }, - { - "args": [ "start_with_url.cold.startup_pages", "-v", "--upload-results", @@ -19566,6 +19349,37 @@ }, { "args": [ + "blink_perf.owp_storage", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "blink_perf.owp_storage", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build112-b1--device3", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 72000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ "blink_perf.paint", "-v", "--upload-results", @@ -21395,68 +21209,6 @@ }, { "args": [ - "start_with_ext.cold.blank_page", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "start_with_ext.cold.blank_page", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build114-b1--device4", - "os": "Android", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600, - "upload_test_results": false - } - }, - { - "args": [ - "start_with_ext.warm.blank_page", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-webview", - "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" - ], - "isolate_name": "telemetry_perf_webview_tests", - "name": "start_with_ext.warm.blank_page", - "override_compile_targets": [ - "telemetry_perf_webview_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build112-b1--device7", - "os": "Android", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600, - "upload_test_results": false - } - }, - { - "args": [ "start_with_url.cold.startup_pages", "-v", "--upload-results", @@ -22577,6 +22329,68 @@ }, { "args": [ + "blink_perf.owp_storage", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-chromium" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.owp_storage", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build9-b1--device3", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 72000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ + "blink_perf.owp_storage", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--max-failures=5", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.owp_storage.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build9-b1--device3", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 72000, + "hard_timeout": 10800, + "ignore_task_failure": true, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ "blink_perf.paint", "-v", "--upload-results", @@ -26245,130 +26059,6 @@ }, { "args": [ - "start_with_ext.cold.blank_page", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-chromium" - ], - "isolate_name": "telemetry_perf_tests", - "name": "start_with_ext.cold.blank_page", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build49-b1--device4", - "os": "Android", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600, - "upload_test_results": false - } - }, - { - "args": [ - "start_with_ext.cold.blank_page", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=reference", - "--max-failures=5", - "--output-trace-tag=_ref" - ], - "isolate_name": "telemetry_perf_tests", - "name": "start_with_ext.cold.blank_page.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build49-b1--device4", - "os": "Android", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": true, - "io_timeout": 3600, - "upload_test_results": false - } - }, - { - "args": [ - "start_with_ext.warm.blank_page", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-chromium" - ], - "isolate_name": "telemetry_perf_tests", - "name": "start_with_ext.warm.blank_page", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build9-b1--device7", - "os": "Android", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600, - "upload_test_results": false - } - }, - { - "args": [ - "start_with_ext.warm.blank_page", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=reference", - "--max-failures=5", - "--output-trace-tag=_ref" - ], - "isolate_name": "telemetry_perf_tests", - "name": "start_with_ext.warm.blank_page.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build9-b1--device7", - "os": "Android", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": true, - "io_timeout": 3600, - "upload_test_results": false - } - }, - { - "args": [ "start_with_url.cold.startup_pages", "-v", "--upload-results", @@ -28006,6 +27696,68 @@ }, { "args": [ + "blink_perf.owp_storage", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-chromium" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.owp_storage", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build17-b1--device3", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 72000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ + "blink_perf.owp_storage", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--max-failures=5", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.owp_storage.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build17-b1--device3", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 72000, + "hard_timeout": 10800, + "ignore_task_failure": true, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ "blink_perf.parser", "-v", "--upload-results", @@ -31591,130 +31343,6 @@ }, { "args": [ - "start_with_ext.cold.blank_page", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-chromium" - ], - "isolate_name": "telemetry_perf_tests", - "name": "start_with_ext.cold.blank_page", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build47-b1--device4", - "os": "Android", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600, - "upload_test_results": false - } - }, - { - "args": [ - "start_with_ext.cold.blank_page", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=reference", - "--max-failures=5", - "--output-trace-tag=_ref" - ], - "isolate_name": "telemetry_perf_tests", - "name": "start_with_ext.cold.blank_page.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build47-b1--device4", - "os": "Android", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": true, - "io_timeout": 3600, - "upload_test_results": false - } - }, - { - "args": [ - "start_with_ext.warm.blank_page", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-chromium" - ], - "isolate_name": "telemetry_perf_tests", - "name": "start_with_ext.warm.blank_page", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build17-b1--device7", - "os": "Android", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600, - "upload_test_results": false - } - }, - { - "args": [ - "start_with_ext.warm.blank_page", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=reference", - "--max-failures=5", - "--output-trace-tag=_ref" - ], - "isolate_name": "telemetry_perf_tests", - "name": "start_with_ext.warm.blank_page.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "android_devices": "1", - "id": "build17-b1--device7", - "os": "Android", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": true, - "io_timeout": 3600, - "upload_test_results": false - } - }, - { - "args": [ "start_with_url.cold.startup_pages", "-v", "--upload-results", @@ -33481,6 +33109,68 @@ }, { "args": [ + "blink_perf.owp_storage", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.owp_storage", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "102b:0534", + "id": "build149-m1", + "os": "Ubuntu-14.04", + "pool": "Chrome-perf" + } + ], + "expiration": 72000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ + "blink_perf.owp_storage", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--max-failures=5", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.owp_storage.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "102b:0534", + "id": "build149-m1", + "os": "Ubuntu-14.04", + "pool": "Chrome-perf" + } + ], + "expiration": 72000, + "hard_timeout": 10800, + "ignore_task_failure": true, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ "blink_perf.paint", "-v", "--upload-results", @@ -38745,6 +38435,68 @@ }, { "args": [ + "blink_perf.owp_storage", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.owp_storage", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0166", + "id": "build103-b1", + "os": "Mac-10.11", + "pool": "Chrome-perf" + } + ], + "expiration": 72000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ + "blink_perf.owp_storage", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--max-failures=5", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.owp_storage.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0166", + "id": "build103-b1", + "os": "Mac-10.11", + "pool": "Chrome-perf" + } + ], + "expiration": 72000, + "hard_timeout": 10800, + "ignore_task_failure": true, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ "blink_perf.paint", "-v", "--upload-results", @@ -43946,6 +43698,68 @@ }, { "args": [ + "blink_perf.owp_storage", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.owp_storage", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a2e", + "id": "build159-m1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 72000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ + "blink_perf.owp_storage", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--max-failures=5", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.owp_storage.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a2e", + "id": "build159-m1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 72000, + "hard_timeout": 10800, + "ignore_task_failure": true, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ "blink_perf.paint", "-v", "--upload-results", @@ -49147,6 +48961,68 @@ }, { "args": [ + "blink_perf.owp_storage", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.owp_storage", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:1626", + "id": "build124-b1", + "os": "Mac-10.11", + "pool": "Chrome-perf" + } + ], + "expiration": 72000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ + "blink_perf.owp_storage", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--max-failures=5", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.owp_storage.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:1626", + "id": "build124-b1", + "os": "Mac-10.11", + "pool": "Chrome-perf" + } + ], + "expiration": 72000, + "hard_timeout": 10800, + "ignore_task_failure": true, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ "blink_perf.paint", "-v", "--upload-results", @@ -54348,6 +54224,68 @@ }, { "args": [ + "blink_perf.owp_storage", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.owp_storage", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 72000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ + "blink_perf.owp_storage", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--max-failures=5", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.owp_storage.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a26", + "id": "build25-b1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 72000, + "hard_timeout": 10800, + "ignore_task_failure": true, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ "blink_perf.paint", "-v", "--upload-results", @@ -59528,6 +59466,68 @@ }, { "args": [ + "blink_perf.owp_storage", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.owp_storage", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "1002:6821", + "id": "build129-b1", + "os": "Mac-10.11", + "pool": "Chrome-perf" + } + ], + "expiration": 72000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ + "blink_perf.owp_storage", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--max-failures=5", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.owp_storage.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "1002:6821", + "id": "build129-b1", + "os": "Mac-10.11", + "pool": "Chrome-perf" + } + ], + "expiration": 72000, + "hard_timeout": 10800, + "ignore_task_failure": true, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ "blink_perf.paint", "-v", "--upload-results", @@ -64729,6 +64729,68 @@ }, { "args": [ + "blink_perf.owp_storage", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.owp_storage", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0d26", + "id": "build5-b1", + "os": "Mac-10.11", + "pool": "Chrome-perf" + } + ], + "expiration": 72000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ + "blink_perf.owp_storage", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--max-failures=5", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.owp_storage.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0d26", + "id": "build5-b1", + "os": "Mac-10.11", + "pool": "Chrome-perf" + } + ], + "expiration": 72000, + "hard_timeout": 10800, + "ignore_task_failure": true, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ "blink_perf.paint", "-v", "--upload-results", @@ -69930,6 +69992,68 @@ }, { "args": [ + "blink_perf.owp_storage", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release_x64" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.owp_storage", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:1616", + "id": "build118-b1", + "os": "Windows-10-10240", + "pool": "Chrome-perf" + } + ], + "expiration": 72000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ + "blink_perf.owp_storage", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--max-failures=5", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.owp_storage.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:1616", + "id": "build118-b1", + "os": "Windows-10-10240", + "pool": "Chrome-perf" + } + ], + "expiration": 72000, + "hard_timeout": 10800, + "ignore_task_failure": true, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ "blink_perf.paint", "-v", "--upload-results", @@ -75110,6 +75234,68 @@ }, { "args": [ + "blink_perf.owp_storage", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release_x64" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.owp_storage", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "102b:0534", + "id": "build133-m1", + "os": "Windows-10-10240", + "pool": "Chrome-perf" + } + ], + "expiration": 72000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ + "blink_perf.owp_storage", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--max-failures=5", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.owp_storage.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "102b:0534", + "id": "build133-m1", + "os": "Windows-10-10240", + "pool": "Chrome-perf" + } + ], + "expiration": 72000, + "hard_timeout": 10800, + "ignore_task_failure": true, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ "blink_perf.paint", "-v", "--upload-results", @@ -80332,6 +80518,68 @@ }, { "args": [ + "blink_perf.owp_storage", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release_x64" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.owp_storage", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "1002:6613", + "id": "build102-m1", + "os": "Windows-2008ServerR2-SP1", + "pool": "Chrome-perf" + } + ], + "expiration": 72000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ + "blink_perf.owp_storage", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--max-failures=5", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.owp_storage.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "1002:6613", + "id": "build102-m1", + "os": "Windows-2008ServerR2-SP1", + "pool": "Chrome-perf" + } + ], + "expiration": 72000, + "hard_timeout": 10800, + "ignore_task_failure": true, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ "blink_perf.paint", "-v", "--upload-results", @@ -85596,6 +85844,68 @@ }, { "args": [ + "blink_perf.owp_storage", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release_x64" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.owp_storage", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:041a", + "id": "build165-m1", + "os": "Windows-2008ServerR2-SP1", + "pool": "Chrome-perf" + } + ], + "expiration": 72000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ + "blink_perf.owp_storage", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--max-failures=5", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.owp_storage.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:041a", + "id": "build165-m1", + "os": "Windows-2008ServerR2-SP1", + "pool": "Chrome-perf" + } + ], + "expiration": 72000, + "hard_timeout": 10800, + "ignore_task_failure": true, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ "blink_perf.paint", "-v", "--upload-results", @@ -90839,6 +91149,68 @@ }, { "args": [ + "blink_perf.owp_storage", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release_x64" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.owp_storage", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "10de:104a", + "id": "build93-m1", + "os": "Windows-2008ServerR2-SP1", + "pool": "Chrome-perf" + } + ], + "expiration": 72000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ + "blink_perf.owp_storage", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--max-failures=5", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.owp_storage.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "10de:104a", + "id": "build93-m1", + "os": "Windows-2008ServerR2-SP1", + "pool": "Chrome-perf" + } + ], + "expiration": 72000, + "hard_timeout": 10800, + "ignore_task_failure": true, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ "blink_perf.paint", "-v", "--upload-results", @@ -96061,6 +96433,68 @@ }, { "args": [ + "blink_perf.owp_storage", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.owp_storage", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "102b:0532", + "id": "build186-m1", + "os": "Windows-2008ServerR2-SP1", + "pool": "Chrome-perf" + } + ], + "expiration": 72000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ + "blink_perf.owp_storage", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--max-failures=5", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.owp_storage.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "102b:0532", + "id": "build186-m1", + "os": "Windows-2008ServerR2-SP1", + "pool": "Chrome-perf" + } + ], + "expiration": 72000, + "hard_timeout": 10800, + "ignore_task_failure": true, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ "blink_perf.paint", "-v", "--upload-results", @@ -101283,6 +101717,68 @@ }, { "args": [ + "blink_perf.owp_storage", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release_x64" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.owp_storage", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "102b:0532", + "id": "build139-m1", + "os": "Windows-2008ServerR2-SP1", + "pool": "Chrome-perf" + } + ], + "expiration": 72000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ + "blink_perf.owp_storage", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--max-failures=5", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.owp_storage.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "102b:0532", + "id": "build139-m1", + "os": "Windows-2008ServerR2-SP1", + "pool": "Chrome-perf" + } + ], + "expiration": 72000, + "hard_timeout": 10800, + "ignore_task_failure": true, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ "blink_perf.paint", "-v", "--upload-results", @@ -106505,6 +107001,68 @@ }, { "args": [ + "blink_perf.owp_storage", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=release_x64" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.owp_storage", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "102b:0532", + "id": "build144-m1", + "os": "Windows-2012ServerR2-SP0", + "pool": "Chrome-perf" + } + ], + "expiration": 72000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ + "blink_perf.owp_storage", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--max-failures=5", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "blink_perf.owp_storage.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "102b:0532", + "id": "build144-m1", + "os": "Windows-2012ServerR2-SP0", + "pool": "Chrome-perf" + } + ], + "expiration": 72000, + "hard_timeout": 10800, + "ignore_task_failure": true, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ "blink_perf.paint", "-v", "--upload-results",
diff --git a/testing/buildbot/chromium.webkit.json b/testing/buildbot/chromium.webkit.json index e646b46..24279556 100644 --- a/testing/buildbot/chromium.webkit.json +++ b/testing/buildbot/chromium.webkit.json
@@ -356,6 +356,38 @@ "test": "wtf_unittests" } ], + "isolated_scripts": [ + { + "isolate_name": "webkit_layout_tests_exparchive", + "merge": { + "args": [ + "--verbose", + "--results-json-override-with-build-property", + "build_number", + "buildnumber", + "--results-json-override-with-build-property", + "builder_name", + "buildername", + "--results-json-override-with-build-property", + "chromium_revision", + "got_revision_cp" + ], + "script": "//third_party/WebKit/Tools/Scripts/merge-layout-test-results" + }, + "name": "webkit_layout_tests", + "results_handler": "layout tests", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "none", + "os": "Mac-10.10.5" + } + ], + "shards": 2 + } + } + ], "scripts": [ { "name": "webkit_lint", @@ -382,6 +414,38 @@ "test": "wtf_unittests" } ], + "isolated_scripts": [ + { + "isolate_name": "webkit_layout_tests_exparchive", + "merge": { + "args": [ + "--verbose", + "--results-json-override-with-build-property", + "build_number", + "buildnumber", + "--results-json-override-with-build-property", + "builder_name", + "buildername", + "--results-json-override-with-build-property", + "chromium_revision", + "got_revision_cp" + ], + "script": "//third_party/WebKit/Tools/Scripts/merge-layout-test-results" + }, + "name": "webkit_layout_tests", + "results_handler": "layout tests", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "none", + "os": "Mac-10.11.6" + } + ], + "shards": 2 + } + } + ], "scripts": [ { "name": "webkit_lint", @@ -460,6 +524,39 @@ "test": "wtf_unittests" } ], + "isolated_scripts": [ + { + "isolate_name": "webkit_layout_tests_exparchive", + "merge": { + "args": [ + "--verbose", + "--results-json-override-with-build-property", + "build_number", + "buildnumber", + "--results-json-override-with-build-property", + "builder_name", + "buildername", + "--results-json-override-with-build-property", + "chromium_revision", + "got_revision_cp" + ], + "script": "//third_party/WebKit/Tools/Scripts/merge-layout-test-results" + }, + "name": "webkit_layout_tests", + "results_handler": "layout tests", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a2e", + "hidpi": "0", + "os": "Mac-10.12.5" + } + ], + "shards": 2 + } + } + ], "scripts": [ { "name": "webkit_lint",
diff --git a/testing/buildbot/filters/ash_unittests_mash.filter b/testing/buildbot/filters/ash_unittests_mash.filter index b236062..803d141c 100644 --- a/testing/buildbot/filters/ash_unittests_mash.filter +++ b/testing/buildbot/filters/ash_unittests_mash.filter
@@ -130,6 +130,8 @@ -ExtendedesktopTest.CaptureventocationHighP -ExtendedesktopTest.KeyventsOnockScreen -LockActionHandlerLayoutManagerTest.KeyboardBounds +-LockLayoutManagerTest.AccessibilityPanel +-LockLayoutManagerTest.AccessibilityPanelWithMultipleMonitors -LockLayoutManagerTest.KeyboardBounds -LockLayoutManagerTest.MaximizedFullscreenWindowBoundsAreEqualToScreen -LockLayoutManagerTest.MultipleMonitors @@ -216,6 +218,7 @@ -PointerWatcherdapterClassicTest.Mousevents -PointerWatcherdapterClassicTest.Touchvents -ResizeShadowAndCursorTest.MaximizeRestore +-ResizeShadowAndCursorTest.Minimize -ResizeShadowAndCursorTest.MouseDrag -ResizeShadowAndCursorTest.MouseHover -ResizeShadowAndCursorTest.Touch
diff --git a/testing/buildbot/filters/fuchsia.net_unittests.filter b/testing/buildbot/filters/fuchsia.net_unittests.filter index e92f1f1..3a0b105 100644 --- a/testing/buildbot/filters/fuchsia.net_unittests.filter +++ b/testing/buildbot/filters/fuchsia.net_unittests.filter
@@ -20,7 +20,6 @@ -NetworkInterfacesTest.GetNetworkList -NetworkQualitiesPrefManager* -NetworkQualityEstimatorTest* --NetworkThrottleManager* -Proxy* -PythonUtils* -QuicSimpleClientTest*
diff --git a/testing/buildbot/filters/mojo.fyi.network_content_browsertests.filter b/testing/buildbot/filters/mojo.fyi.network_content_browsertests.filter index d2e1074..8ddfbfd 100644 --- a/testing/buildbot/filters/mojo.fyi.network_content_browsertests.filter +++ b/testing/buildbot/filters/mojo.fyi.network_content_browsertests.filter
@@ -55,6 +55,7 @@ -DataUrlNavigationBrowserTest.UnknownMimeType_Navigation_Download -DataUrlNavigationBrowserTest.UnknownMimeType_WindowOpen_Download -DevToolsProtocolTest.CertificateError +-DevToolsProtocolTest.CertificateExplanations -DevToolsProtocolTest.ControlNavigationsMainFrame -DevToolsProtocolTest.SubresourceWithCertificateError -GenericSensorBrowserTest.AmbientLightSensorTest
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index da02396..3ede3f5 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -1331,6 +1331,21 @@ ] } ], + "MacV2Sandbox": [ + { + "platforms": [ + "mac" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "MacV2Sandbox" + ] + } + ] + } + ], "MaxDelayableRequestsNetworkOverride": [ { "platforms": [
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG index 5fefa909..4827c17 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG +++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
@@ -2514,7 +2514,6 @@ crbug.com/591099 editing/execCommand/5432254-2.html [ Crash Failure ] crbug.com/591099 editing/execCommand/5458246.html [ Crash Failure ] crbug.com/591099 editing/execCommand/5469868.html [ Crash Failure ] -crbug.com/591099 editing/execCommand/5481523.html [ Failure ] crbug.com/591099 editing/execCommand/5569741.html [ Crash Failure ] crbug.com/591099 editing/execCommand/5575101-1.html [ Crash Failure ] crbug.com/591099 editing/execCommand/5575101-2.html [ Crash Failure ] @@ -6711,7 +6710,6 @@ crbug.com/591099 fast/dynamic/view-overflow.html [ Failure ] crbug.com/591099 fast/dynamic/window-resize-scrollbars-test.html [ Failure ] crbug.com/591099 fast/dynamic/window-scrollbars-test.html [ Failure ] -crbug.com/591099 fast/encoding/GBK/EUC-CN.html [ Failure ] crbug.com/591099 fast/encoding/GBK/chinese.html [ Failure ] crbug.com/591099 fast/encoding/GBK/close-gbk-converter.html [ Failure ] crbug.com/591099 fast/encoding/GBK/csgb2312.html [ Failure ] @@ -12329,7 +12327,6 @@ crbug.com/591099 http/tests/workers/worker-workerScriptNotThere.html [ Failure ] crbug.com/591099 http/tests/xmlhttprequest/XMLHttpRequestException.html [ Failure ] crbug.com/591099 http/tests/xmlhttprequest/abort-should-destroy-responseText.html [ Failure ] -crbug.com/591099 http/tests/xmlhttprequest/access-control-and-redirects-async.html [ Failure Timeout ] crbug.com/591099 http/tests/xmlhttprequest/access-control-basic-denied-preflight-cache.html [ Crash Failure ] crbug.com/591099 http/tests/xmlhttprequest/access-control-basic-post-success-no-content-type.html [ Failure ] crbug.com/591099 http/tests/xmlhttprequest/access-control-preflight-credential-async.html [ Failure ] @@ -17149,10 +17146,9 @@ crbug.com/591099 xmlviewer/extensions-api.html [ Failure ] # Need support for getBoundingClientRect() with LayoutNG. -# TODO(xiaochengh): Investigate and file a new bug to replace 699017 -crbug.com/699017 accessibility/selection-affinity.html [ Failure ] -crbug.com/699017 fast/multicol/float-truncation.html [ Failure ] -crbug.com/699017 fast/multicol/vertical-lr/float-truncation.html [ Failure ] +crbug.com/755750 accessibility/selection-affinity.html [ Failure ] +crbug.com/755750 fast/multicol/float-truncation.html [ Failure ] +crbug.com/755750 fast/multicol/vertical-lr/float-truncation.html [ Failure ] # We currently write back whitespace-collapsed strings to LayoutText, causing # the following failures. Once we can paint inlines directly from fragment tree,
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2 b/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2 index 3d87abae..36795b00 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2 +++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2
@@ -103,6 +103,7 @@ # Fail on SPv1, but succeed on SPv2 crbug.com/472330 fast/borders/border-image-outset-split-inline-vertical-lr.html [ Pass ] crbug.com/736052 compositing/overflow/composited-scroll-with-fractional-translation.html [ Pass ] +crbug.com/754927 compositing/overflow/fixed-pos-escape-clip-and-apply-noncomposited-clip.html [ Pass ] Bug(none) paint/transparency/compositing-alpha-fold-crash.html [ Failure ] Bug(none) paint/invalidation/clip-flex-text.html [ Pass Failure ]
diff --git a/third_party/WebKit/LayoutTests/SlowTests b/third_party/WebKit/LayoutTests/SlowTests index 22deb70..07b766a 100644 --- a/third_party/WebKit/LayoutTests/SlowTests +++ b/third_party/WebKit/LayoutTests/SlowTests
@@ -398,12 +398,14 @@ crbug.com/726075 [ Win ] virtual/gpu/fast/canvas/canvas-blending-color-over-pattern.html [ Slow ] crbug.com/726075 [ Win ] virtual/gpu/fast/canvas/canvas-blending-gradient-over-image.html [ Slow ] crbug.com/726075 [ Win ] virtual/gpu/fast/canvas/canvas-blending-gradient-over-pattern.html [ Slow ] +crbug.com/726075 [ Win ] virtual/gpu/fast/canvas/canvas-blending-gradient-over-gradient.html [ Slow ] crbug.com/726075 [ Win ] virtual/gpu/fast/canvas/canvas-blending-pattern-over-gradient.html [ Slow ] crbug.com/726075 [ Win ] virtual/gpu/fast/canvas/canvas-blending-pattern-over-image.html [ Slow ] crbug.com/726075 [ Win ] virtual/gpu/fast/canvas/canvas-blending-pattern-over-pattern.html [ Slow ] crbug.com/726075 [ Win ] virtual/gpu/fast/canvas/canvas-composite-shadow.html [ Slow ] crbug.com/726075 [ Win ] virtual/gpu/fast/canvas/canvas-composite-video-shadow.html [ Slow ] crbug.com/726075 [ Win ] virtual/gpu/fast/canvas/canvas-fillPath-alpha-shadow.html [ Slow ] +crbug.com/726075 [ Win ] virtual/gpu/fast/canvas/canvas-fillPath-gradient-shadow.html [ Slow ] crbug.com/726075 [ Win ] virtual/gpu/fast/canvas/canvas-fillPath-pattern-shadow.html [ Slow ] crbug.com/726075 [ Win ] virtual/gpu/fast/canvas/canvas-filter-origin-clean.html [ Slow ] crbug.com/726075 [ Win ] virtual/gpu/fast/canvas/canvas-filter-removed.html [ Slow ] @@ -421,7 +423,6 @@ crbug.com/726075 [ Win Debug ] virtual/gpu/fast/canvas/canvas-blending-fill-style.html [ Slow ] crbug.com/726075 [ Win Debug ] virtual/gpu/fast/canvas/canvas-blending-global-alpha.html [ Slow ] crbug.com/726075 [ Win Debug ] virtual/gpu/fast/canvas/canvas-blending-gradient-over-color.html [ Slow ] -crbug.com/726075 [ Win Debug ] virtual/gpu/fast/canvas/canvas-blending-gradient-over-gradient.html [ Slow ] crbug.com/726075 [ Win Debug ] virtual/gpu/fast/canvas/canvas-blending-image-over-color.html [ Slow ] crbug.com/726075 [ Win Debug ] virtual/gpu/fast/canvas/canvas-blending-image-over-gradient.html [ Slow ] crbug.com/726075 [ Win Debug ] virtual/gpu/fast/canvas/canvas-blending-image-over-image.html [ Slow ]
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index 95b7cf4b..bf1a5ee 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -1186,10 +1186,6 @@ crbug.com/504706 [ Linux ] inspector/profiler/heap-snapshot-containment-expansion-preserved-when-sorting.html [ Pass ] crbug.com/504706 [ Linux ] inspector/profiler/heap-snapshot-containment-sorting.html [ Pass ] -crbug.com/755104 inspector-protocol/runtime/runtime-callFunctionOn-async.js [ NeedsManualRebaseline ] -crbug.com/755104 inspector-protocol/runtime/runtime-evaluate-async.js [ NeedsManualRebaseline ] -crbug.com/755104 inspector-protocol/runtime/runtime-runScript-async.js [ NeedsManualRebaseline ] - # When drawing subpixel smoothed glyphs, CoreGraphics will fake bold the glyphs. # In this configuration, the pixel smoothed glyphs will be created from subpixel smoothed glyphs. # This means that CoreGraphics may draw outside the reported glyph bounds, and in this case does. @@ -2912,6 +2908,9 @@ # Sheriff failures 2017-05-29 crbug.com/727252 [ Win7 ] external/wpt/media-source/mediasource-endofstream.html [ Pass Timeout ] +crbug.com/754927 compositing/overflow/fixed-pos-escape-clip-and-apply-noncomposited-clip.html [ Failure ] +crbug.com/754927 virtual/prefer_compositing_to_lcd_text/compositing/overflow/fixed-pos-escape-clip-and-apply-noncomposited-clip.html [ Failure ] + # Failures when using libc++. Rebaseline after landing https://codereview.chromium.org/2933573002/ crbug.com/734873 [ Linux ] fast/backgrounds/size/contain-and-cover.html [ Pass Failure ] @@ -3129,7 +3128,7 @@ crbug.com/750310 [ Win7 Debug ] virtual/off-main-thread-fetch/http/tests/inspector/network/network-blocked-reason.html [ Timeout ] # Sheriff failures 2017-08-04 -crbug.com/626703 [ Win7 ] external/wpt/html/semantics/tabular-data/processing-model-1/span-limits.html [ Timeout ] +crbug.com/626703 [ Win7 Mac10.11 ] external/wpt/html/semantics/tabular-data/processing-model-1/span-limits.html [ Timeout ] # Sheriff failure 2017-08-07 crbug.com/708499 [ Win7 Mac10.11 Retina Debug ] virtual/wheelscrolllatching/fast/compositor-wheel-scroll-latching/touchpad-scroll-impl-to-main.html [ Failure Pass ]
diff --git a/third_party/WebKit/LayoutTests/bluetooth/script-tests/service/reconnect-during.js b/third_party/WebKit/LayoutTests/bluetooth/script-tests/service/reconnect-during.js index 5a773f99..21e824f 100644 --- a/third_party/WebKit/LayoutTests/bluetooth/script-tests/service/reconnect-during.js +++ b/third_party/WebKit/LayoutTests/bluetooth/script-tests/service/reconnect-during.js
@@ -1,25 +1,38 @@ 'use strict'; promise_test(() => { - return setBluetoothFakeAdapter('HeartRateAdapter') - .then(() => requestDeviceWithKeyDown({ - filters: [{services: ['heart_rate']}]})) - .then(device => device.gatt.connect()) - .then(gatt => { - return gatt.getPrimaryService('heart_rate') - .then(service => { - let promise = assert_promise_rejects_with_message( - service.CALLS([ - getCharacteristic('heart_rate_measurement')| - getCharacteristics()| - getCharacteristics('heart_rate_measurement')[UUID] - ]), - new DOMException( - 'GATT Server is disconnected. Cannot retrieve characteristics. ' + - '(Re)connect first with `device.gatt.connect`.', - 'NetworkError')); - gatt.disconnect(); - return gatt.connect().then(() => promise); - }); + let device, service; + return getHealthThermometerDeviceWithServicesDiscovered({ + filters: [{services: [health_thermometer.name]}], + }) + .then(_ => ({device} = _)) + .then(() => device.gatt.getPrimaryService(health_thermometer.name)) + .then(_ => service = _) + .then(() => { + // 1. Make a call to service.FUNCTION_NAME, while the service is still + // valid. + let promise = assert_promise_rejects_with_message(service.CALLS([ + getCharacteristic(measurement_interval.name)| + getCharacteristics()| + getCharacteristics(measurement_interval.name)[UUID] + ]), new DOMException( + 'GATT Server is disconnected. Cannot retrieve characteristics. ' + + '(Re)connect first with `device.gatt.connect`.', + 'NetworkError')); + + // 2. disconnect() and connect before the initial call completes. + // This is accomplished by making the calls without waiting for the + // earlier promises to resolve. + // connect() guarantees on OS-level connection, but disconnect() + // only disconnects the current instance. + // getHealthThermometerDeviceWithServicesDiscovered holds another + // connection in an iframe, so disconnect() and connect() are certain to + // reconnect. However, disconnect() will invalidate the service object so + // the subsequent calls made to it will fail, even after reconnecting. + device.gatt.disconnect(); + return device.gatt.connect() + // 3. Check that the initial call did eventually fail. To do that, we + // must hold a reference to the first promise. + .then(() => promise); }); }, 'disconnect() and connect() called during FUNCTION_NAME. Reject with ' + 'NetworkError.');
diff --git a/third_party/WebKit/LayoutTests/bluetooth/service/getCharacteristic/gen-reconnect-during.html b/third_party/WebKit/LayoutTests/bluetooth/service/getCharacteristic/gen-reconnect-during.html index e4c22b8..660f94a 100644 --- a/third_party/WebKit/LayoutTests/bluetooth/service/getCharacteristic/gen-reconnect-during.html +++ b/third_party/WebKit/LayoutTests/bluetooth/service/getCharacteristic/gen-reconnect-during.html
@@ -8,22 +8,35 @@ <script> 'use strict'; promise_test(() => { - return setBluetoothFakeAdapter('HeartRateAdapter') - .then(() => requestDeviceWithKeyDown({ - filters: [{services: ['heart_rate']}]})) - .then(device => device.gatt.connect()) - .then(gatt => { - return gatt.getPrimaryService('heart_rate') - .then(service => { - let promise = assert_promise_rejects_with_message( - service.getCharacteristic('heart_rate_measurement'), - new DOMException( - 'GATT Server is disconnected. Cannot retrieve characteristics. ' + - '(Re)connect first with `device.gatt.connect`.', - 'NetworkError')); - gatt.disconnect(); - return gatt.connect().then(() => promise); - }); + let device, service; + return getHealthThermometerDeviceWithServicesDiscovered({ + filters: [{services: [health_thermometer.name]}], + }) + .then(_ => ({device} = _)) + .then(() => device.gatt.getPrimaryService(health_thermometer.name)) + .then(_ => service = _) + .then(() => { + // 1. Make a call to service.getCharacteristic, while the service is still + // valid. + let promise = assert_promise_rejects_with_message(service.getCharacteristic(measurement_interval.name), new DOMException( + 'GATT Server is disconnected. Cannot retrieve characteristics. ' + + '(Re)connect first with `device.gatt.connect`.', + 'NetworkError')); + + // 2. disconnect() and connect before the initial call completes. + // This is accomplished by making the calls without waiting for the + // earlier promises to resolve. + // connect() guarantees on OS-level connection, but disconnect() + // only disconnects the current instance. + // getHealthThermometerDeviceWithServicesDiscovered holds another + // connection in an iframe, so disconnect() and connect() are certain to + // reconnect. However, disconnect() will invalidate the service object so + // the subsequent calls made to it will fail, even after reconnecting. + device.gatt.disconnect(); + return device.gatt.connect() + // 3. Check that the initial call did eventually fail. To do that, we + // must hold a reference to the first promise. + .then(() => promise); }); }, 'disconnect() and connect() called during getCharacteristic. Reject with ' + 'NetworkError.');
diff --git a/third_party/WebKit/LayoutTests/bluetooth/service/getCharacteristics/gen-reconnect-during-with-uuid.html b/third_party/WebKit/LayoutTests/bluetooth/service/getCharacteristics/gen-reconnect-during-with-uuid.html index 1a684ac..55fdc91 100644 --- a/third_party/WebKit/LayoutTests/bluetooth/service/getCharacteristics/gen-reconnect-during-with-uuid.html +++ b/third_party/WebKit/LayoutTests/bluetooth/service/getCharacteristics/gen-reconnect-during-with-uuid.html
@@ -8,22 +8,35 @@ <script> 'use strict'; promise_test(() => { - return setBluetoothFakeAdapter('HeartRateAdapter') - .then(() => requestDeviceWithKeyDown({ - filters: [{services: ['heart_rate']}]})) - .then(device => device.gatt.connect()) - .then(gatt => { - return gatt.getPrimaryService('heart_rate') - .then(service => { - let promise = assert_promise_rejects_with_message( - service.getCharacteristics('heart_rate_measurement'), - new DOMException( - 'GATT Server is disconnected. Cannot retrieve characteristics. ' + - '(Re)connect first with `device.gatt.connect`.', - 'NetworkError')); - gatt.disconnect(); - return gatt.connect().then(() => promise); - }); + let device, service; + return getHealthThermometerDeviceWithServicesDiscovered({ + filters: [{services: [health_thermometer.name]}], + }) + .then(_ => ({device} = _)) + .then(() => device.gatt.getPrimaryService(health_thermometer.name)) + .then(_ => service = _) + .then(() => { + // 1. Make a call to service.getCharacteristics, while the service is still + // valid. + let promise = assert_promise_rejects_with_message(service.getCharacteristics(measurement_interval.name), new DOMException( + 'GATT Server is disconnected. Cannot retrieve characteristics. ' + + '(Re)connect first with `device.gatt.connect`.', + 'NetworkError')); + + // 2. disconnect() and connect before the initial call completes. + // This is accomplished by making the calls without waiting for the + // earlier promises to resolve. + // connect() guarantees on OS-level connection, but disconnect() + // only disconnects the current instance. + // getHealthThermometerDeviceWithServicesDiscovered holds another + // connection in an iframe, so disconnect() and connect() are certain to + // reconnect. However, disconnect() will invalidate the service object so + // the subsequent calls made to it will fail, even after reconnecting. + device.gatt.disconnect(); + return device.gatt.connect() + // 3. Check that the initial call did eventually fail. To do that, we + // must hold a reference to the first promise. + .then(() => promise); }); }, 'disconnect() and connect() called during getCharacteristics. Reject with ' + 'NetworkError.');
diff --git a/third_party/WebKit/LayoutTests/bluetooth/service/getCharacteristics/gen-reconnect-during.html b/third_party/WebKit/LayoutTests/bluetooth/service/getCharacteristics/gen-reconnect-during.html index 0018212..dff2cab 100644 --- a/third_party/WebKit/LayoutTests/bluetooth/service/getCharacteristics/gen-reconnect-during.html +++ b/third_party/WebKit/LayoutTests/bluetooth/service/getCharacteristics/gen-reconnect-during.html
@@ -8,22 +8,35 @@ <script> 'use strict'; promise_test(() => { - return setBluetoothFakeAdapter('HeartRateAdapter') - .then(() => requestDeviceWithKeyDown({ - filters: [{services: ['heart_rate']}]})) - .then(device => device.gatt.connect()) - .then(gatt => { - return gatt.getPrimaryService('heart_rate') - .then(service => { - let promise = assert_promise_rejects_with_message( - service.getCharacteristics(), - new DOMException( - 'GATT Server is disconnected. Cannot retrieve characteristics. ' + - '(Re)connect first with `device.gatt.connect`.', - 'NetworkError')); - gatt.disconnect(); - return gatt.connect().then(() => promise); - }); + let device, service; + return getHealthThermometerDeviceWithServicesDiscovered({ + filters: [{services: [health_thermometer.name]}], + }) + .then(_ => ({device} = _)) + .then(() => device.gatt.getPrimaryService(health_thermometer.name)) + .then(_ => service = _) + .then(() => { + // 1. Make a call to service.getCharacteristics, while the service is still + // valid. + let promise = assert_promise_rejects_with_message(service.getCharacteristics(), new DOMException( + 'GATT Server is disconnected. Cannot retrieve characteristics. ' + + '(Re)connect first with `device.gatt.connect`.', + 'NetworkError')); + + // 2. disconnect() and connect before the initial call completes. + // This is accomplished by making the calls without waiting for the + // earlier promises to resolve. + // connect() guarantees on OS-level connection, but disconnect() + // only disconnects the current instance. + // getHealthThermometerDeviceWithServicesDiscovered holds another + // connection in an iframe, so disconnect() and connect() are certain to + // reconnect. However, disconnect() will invalidate the service object so + // the subsequent calls made to it will fail, even after reconnecting. + device.gatt.disconnect(); + return device.gatt.connect() + // 3. Check that the initial call did eventually fail. To do that, we + // must hold a reference to the first promise. + .then(() => promise); }); }, 'disconnect() and connect() called during getCharacteristics. Reject with ' + 'NetworkError.');
diff --git a/third_party/WebKit/LayoutTests/compositing/composite-scrollable-fixed-position-when-descendants-composite-expected.txt b/third_party/WebKit/LayoutTests/compositing/composite-scrollable-fixed-position-when-descendants-composite-expected.txt deleted file mode 100644 index 3839aba..0000000 --- a/third_party/WebKit/LayoutTests/compositing/composite-scrollable-fixed-position-when-descendants-composite-expected.txt +++ /dev/null
@@ -1,2 +0,0 @@ -Any errors will show below this line. -
diff --git a/third_party/WebKit/LayoutTests/compositing/composite-scrollable-fixed-position-when-descendants-composite.html b/third_party/WebKit/LayoutTests/compositing/composite-scrollable-fixed-position-when-descendants-composite.html index 412c876..7963b01 100644 --- a/third_party/WebKit/LayoutTests/compositing/composite-scrollable-fixed-position-when-descendants-composite.html +++ b/third_party/WebKit/LayoutTests/compositing/composite-scrollable-fixed-position-when-descendants-composite.html
@@ -1,17 +1,20 @@ <!doctype HTML> -Any errors will show below this line. -<!-- Having a composited child should be a position:fixed compositing trigger when scrollable --> +<head> + <script src="../resources/testharness.js"></script> + <script src="../resources/testharnessreport.js"></script> +</head> + <div style="position: fixed; width: 100px; height: 100px; background: lightgray"> - <div style="will-change: transform; margin: 50px; width: 50px; height: 50px; background: lightblue"> - </div> + <div style="will-change: transform; margin: 50px; width: 50px; height: 50px; background: lightblue"></div> </div> -<div style="height: 2000px;"></div> -<script src="../resources/testharness.js"></script> + +<div id="force_document_scroll" style="height: 5000px;"></div> + <script> -if (window.testRunner) - testRunner.dumpAsText(); -if (window.internals) { - var layers = JSON.parse(internals.layerTreeAsText(document)); - assert_true(layers["layers"].length == 3); -} + test(function() { + assert_not_equals(window.internals, null, 'This test requires window.internals'); + var layers_text = internals.layerTreeAsText(document); + var layers = JSON.parse(layers_text); + assert_equals(layers['layers'].length, 3); + }, 'Having a composited child should be a position:fixed compositing trigger and should result in the fixed element getting a layer.'); </script>
diff --git a/third_party/WebKit/LayoutTests/compositing/overflow/fixed-pos-escape-clip-and-apply-noncomposited-clip-expected.html b/third_party/WebKit/LayoutTests/compositing/overflow/fixed-pos-escape-clip-and-apply-noncomposited-clip-expected.html new file mode 100644 index 0000000..ab20a0f2 --- /dev/null +++ b/third_party/WebKit/LayoutTests/compositing/overflow/fixed-pos-escape-clip-and-apply-noncomposited-clip-expected.html
@@ -0,0 +1,4 @@ +<!DOCTYPE html> +This test verifies fixed-pos element escapes clip correctly, and then apply clip from its true clipping container even if the container is not composited. +It succeeds if a 100x100 green box is shown below. +<div style="width:100px; height:100px; background:green;"></div>
diff --git a/third_party/WebKit/LayoutTests/compositing/overflow/fixed-pos-escape-clip-and-apply-noncomposited-clip.html b/third_party/WebKit/LayoutTests/compositing/overflow/fixed-pos-escape-clip-and-apply-noncomposited-clip.html new file mode 100644 index 0000000..ab98daf2 --- /dev/null +++ b/third_party/WebKit/LayoutTests/compositing/overflow/fixed-pos-escape-clip-and-apply-noncomposited-clip.html
@@ -0,0 +1,14 @@ +<!DOCTYPE html> +This test verifies fixed-pos element escapes clip correctly, and then apply clip from its true clipping container even if the container is not composited. +It succeeds if a 100x100 green box is shown below. +<div style="overflow:hidden; width:100px; height:100px;"> + <div style="transform:translateX(0); width:100px; height:100px;"> + <div style="position:relative; width:10px; height:10px; overflow:hidden;"> + <div style="will-change:transform;">Promote</div> + <div style="position:absolute; z-index:0; top:0; left:0; width:300px; height:200px;"> + <div style="position:fixed; left:0; top:0; width:200px; height:200px; background:green;"> + </div> + </div> + </div> + </div> +</div>
diff --git a/third_party/WebKit/LayoutTests/compositing/overflow/fixed-pos-escape-clip-having-non-stacking-context-clipping-container-expected.html b/third_party/WebKit/LayoutTests/compositing/overflow/fixed-pos-escape-clip-having-non-stacking-context-clipping-container-expected.html new file mode 100644 index 0000000..430063a --- /dev/null +++ b/third_party/WebKit/LayoutTests/compositing/overflow/fixed-pos-escape-clip-having-non-stacking-context-clipping-container-expected.html
@@ -0,0 +1,4 @@ +<!DOCTYPE html> +This test verifies fixed-pos element escapes clip correctly, even if its true clipping container is not a stacking context. +It succeeds if a 50x50 green box is shown below. +<div style="width:50px; height:50px; background:green;"></div>
diff --git a/third_party/WebKit/LayoutTests/compositing/overflow/fixed-pos-escape-clip-having-non-stacking-context-clipping-container.html b/third_party/WebKit/LayoutTests/compositing/overflow/fixed-pos-escape-clip-having-non-stacking-context-clipping-container.html new file mode 100644 index 0000000..0ac0617 --- /dev/null +++ b/third_party/WebKit/LayoutTests/compositing/overflow/fixed-pos-escape-clip-having-non-stacking-context-clipping-container.html
@@ -0,0 +1,14 @@ +<!DOCTYPE html> +This test verifies fixed-pos element escapes clip correctly, even if its true clipping container is not a stacking context. +It succeeds if a 50x50 green box is shown below. +<div style="overflow:hidden; width:100px; height:100px;"> + <div style="transform:translateX(0); width:100px; height:100px;"> + <div style="position:relative; width:10px; height:10px; overflow:hidden;"> + <div style="will-change:transform;">Promote</div> + <div style="position:absolute; z-index:0; top:0; left:0; width:300px; height:200px;"> + <div style="position:fixed; left:0; top:0; width:50px; height:50px; background:green;"> + </div> + </div> + </div> + </div> +</div>
diff --git a/third_party/WebKit/LayoutTests/css3/flexbox/change-column-flex-width.html b/third_party/WebKit/LayoutTests/css3/flexbox/change-column-flex-width.html new file mode 100644 index 0000000..1b85fd0 --- /dev/null +++ b/third_party/WebKit/LayoutTests/css3/flexbox/change-column-flex-width.html
@@ -0,0 +1,20 @@ +<!DOCTYPE html> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<script src="../../resources/check-layout-th.js"></script> +<p>There should be a green square below. No red.</p> +<!-- #container is just here to make sure the test fails more reliably visually if the bug is present. --> +<div id="container" style="width:500px;"> + <div id="flex" style="display:flex; flex-direction:column; width:70px;" data-expected-height="100"> + <div style="background:red;" data-expected-height="100"> + <div style="float:left; width:50px; height:100px; background:green;"></div> + <div style="float:left; width:50px; height:100px; background:green;"></div> + </div> + </div> +</div> +<script> + document.body.offsetTop; + var flex = document.getElementById("flex"); + flex.style.width = "100px"; + checkLayout("#container"); +</script>
diff --git a/third_party/WebKit/LayoutTests/editing/assert_selection.js b/third_party/WebKit/LayoutTests/editing/assert_selection.js index dfce7ae0..54327a8 100644 --- a/third_party/WebKit/LayoutTests/editing/assert_selection.js +++ b/third_party/WebKit/LayoutTests/editing/assert_selection.js
@@ -86,7 +86,7 @@ } /** - * @param {!DOMSelection} selection + * @param {!Selection} selection * @return !SampleSelection */ fromDOMSelection(selection) { @@ -109,7 +109,7 @@ firstChildOf(node) { return node.firstChild; } /** - * @param {!DOMSelection} selection + * @param {!Selection} selection * @return !SampleSelection */ fromDOMSelection(selection) { @@ -129,10 +129,10 @@ * @param {!Node} node * @return {Node} */ - firstChildOf(node) { return internals.firstChildInFlatTree(node); } + firstChildOf(node) { return window.internals.firstChildInFlatTree(node); } /** - * @param {!DOMSelection} selection + * @param {!Selection} selection * @return !SampleSelection */ fromDOMSelection(selection) { @@ -145,7 +145,7 @@ * @param {!Node} node * @return {Node} */ - nextSiblingOf(node) { return internals.nextSiblingInFlatTree(node); } + nextSiblingOf(node) { return window.internals.nextSiblingInFlatTree(node); } } /** @@ -478,7 +478,7 @@ constructor(selection, traversal) { /** @type {!SampleSelection} */ this.selection_ = selection; - /** @type {!Array<strings>} */ + /** @type {!Array<string>} */ this.strings_ = []; /** @type {!Traversal} */ this.traversal_ = traversal; @@ -593,7 +593,7 @@ /** * @private - * @param {!HTMLTextArea} + * @param {!HTMLTextAreaElement} textArea */ handleTextArea(textArea) { /** @type {string} */ @@ -690,7 +690,7 @@ } /** - * @this {!DOMSelection} + * @this {!Selection} * @param {string} html * @param {string=} opt_text */ @@ -721,7 +721,7 @@ * @param {string} sampleText */ constructor(sampleText) { - /** @const @type {!HTMLIFame} */ + /** @const @type {!HTMLIFrameElement} */ this.iframe_ = document.createElement('iframe'); if (!document.body) document.body = document.createElement("body"); @@ -894,8 +894,8 @@ /** * @param {string} passedInputText - * @param {function(!Selection)|string} - * @param {string} passedExpectedText + * @param {function(!Selection)|string} tester + * @param {string} expectedText * @param {Object=} opt_options * @return {!Sample} */
diff --git a/third_party/WebKit/LayoutTests/editing/execCommand/5080333-1.html b/third_party/WebKit/LayoutTests/editing/execCommand/5080333-1.html deleted file mode 100644 index 4423d95c..0000000 --- a/third_party/WebKit/LayoutTests/editing/execCommand/5080333-1.html +++ /dev/null
@@ -1,23 +0,0 @@ -<!DOCTYPE html> -<script src="../../resources/testharness.js"></script> -<script src="../../resources/testharnessreport.js"></script> -<p>This tests for a bug where changing the alignment of an image would result in a selection that wasn't the one that was present before the alignment change. The image should be centered and the caret should be the same before and after the operation.</p> -<div id="div" contenteditable="true">foo<br><img src="../resources/abe.png"><br>baz</div> -<div id="log"></div> -<script> -test(function() { - var div = document.getElementById('div'); - var selection = window.getSelection(); - - selection.collapse(div, 0); - selection.modify('move', 'forward', 'paragraphBoundary'); - selection.modify('move', 'forward', 'character'); - - document.execCommand('JustifyCenter'); - - assert_equals(div.innerHTML, 'foo<br><div style="text-align: center;"><img src="../resources/abe.png"></div>baz'); - assert_true(selection.isCollapsed); - assert_equals(selection.anchorNode, div.childNodes[2]); - assert_equals(selection.anchorOffset, 0); -}); -</script>
diff --git a/third_party/WebKit/LayoutTests/editing/execCommand/5080333-2.html b/third_party/WebKit/LayoutTests/editing/execCommand/5080333-2.html deleted file mode 100644 index 4d907bf..0000000 --- a/third_party/WebKit/LayoutTests/editing/execCommand/5080333-2.html +++ /dev/null
@@ -1,25 +0,0 @@ -<!DOCTYPE html> -<script src="../../resources/testharness.js"></script> -<script src="../../resources/testharnessreport.js"></script> -<p>This tests for a bug where changing the alignment of an image would result in a selection that wasn't the one that was present before the alignment change. The image should be centered and the selection should be the same before and after the operation.</p> -<div id="div" contenteditable="true">foo<br><img src="../resources/abe.png"><br>baz</div> -<div id="log"></div> -<script> -test(function() { - var div = document.getElementById("div"); - var selection = window.getSelection(); - - selection.collapse(div, 0); - selection.modify("move", "forward", "paragraphBoundary"); - selection.modify("move", "forward", "character"); - selection.modify("extend", "forward", "character"); - - document.execCommand("JustifyCenter"); - - assert_equals(div.innerHTML, 'foo<br><div style="text-align: center;"><img src="../resources/abe.png"></div>baz'); - assert_equals(selection.anchorNode, div.childNodes[2]); - assert_equals(selection.anchorOffset, 0); - assert_equals(selection.focusNode, div.childNodes[2]); - assert_equals(selection.focusOffset, 1); -}); -</script>
diff --git a/third_party/WebKit/LayoutTests/editing/execCommand/5481523.html b/third_party/WebKit/LayoutTests/editing/execCommand/5481523.html deleted file mode 100644 index 9d22cfc8..0000000 --- a/third_party/WebKit/LayoutTests/editing/execCommand/5481523.html +++ /dev/null
@@ -1,16 +0,0 @@ -<p>This tests for a hang when indenting a fully selected table twice. You should see a twice indented table, with four cells, below.</p> - -<div id="div" contenteditable="true"> - <table border="1"> - <tr><td>One</td><td>Two</td></tr> - <tr><td>Three</td><td>Four</td></tr> - </table> -</div> - -<script> -div = document.getElementById("div"); -div.focus(); -document.execCommand("SelectAll"); -document.execCommand("Indent"); -document.execCommand("Indent"); -</script>
diff --git a/third_party/WebKit/LayoutTests/editing/execCommand/insert-ordered-list-expected.txt b/third_party/WebKit/LayoutTests/editing/execCommand/insert-ordered-list-expected.txt deleted file mode 100644 index 7997d039..0000000 --- a/third_party/WebKit/LayoutTests/editing/execCommand/insert-ordered-list-expected.txt +++ /dev/null
@@ -1,3 +0,0 @@ -SUCCESS -text -
diff --git a/third_party/WebKit/LayoutTests/editing/execCommand/insert-ordered-list.html b/third_party/WebKit/LayoutTests/editing/execCommand/insert-ordered-list.html deleted file mode 100644 index ed988953..0000000 --- a/third_party/WebKit/LayoutTests/editing/execCommand/insert-ordered-list.html +++ /dev/null
@@ -1,23 +0,0 @@ -<BODY contentEditable="true"> -<u> - <img><br> - <div> - <ul> - <li> - <span><u> - <div style="text-align:right; display: inline;"> - <span><u>text</u></span> - </div> - </u></span> - </li> - </ul> - </div> -</u> -</BODY> -<SCRIPT> - if (window.testRunner) - testRunner.dumpAsText(); - document.execCommand("selectall"); - document.execCommand("insertorderedlist"); - document.getElementsByTagName('u')[0].innerHTML = 'SUCCESS'; -</SCRIPT>
diff --git a/third_party/WebKit/LayoutTests/editing/execCommand/insert_ordered_list.html b/third_party/WebKit/LayoutTests/editing/execCommand/insert_ordered_list.html new file mode 100644 index 0000000..5a7ec17b --- /dev/null +++ b/third_party/WebKit/LayoutTests/editing/execCommand/insert_ordered_list.html
@@ -0,0 +1,50 @@ +<!doctype html> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<script src="../assert_selection.js"></script> +<script> +// This is a regression test for https://bugs.webkit.org/show_bug.cgi?id=32131 +test(() => assert_selection( + [ + '<div contenteditable>', + '^<u>', + '<img><br>', + '<div>', + '<ul>', + '<li>', + '<span><u>', + '<div style="text-align:right; display: inline;">', + '<span><u>text|</u></span>', + '</div>', + '</u></span>', + '</li>', + '</ul>', + '</div>', + '</u>', + '</div>' + ], + 'insertorderedlist', + [ + '<div contenteditable>', + '<ol>', + '<li>', + '<u>', + '^<img>', + '</u>', + '</li>', + '</ol>', + '<u>', + '<ol>', + '<li>', + '<span><u>', + '<div style="text-align:right; display: inline;">', + '<span><u>text|</u></span>', + '</div>', + '</u></span>', + '</li>', + '</ol>', + '</u>', + '</div>' + ]), + "indertOrderedList shoud work when the selection is crossing ul."); +</script>
diff --git a/third_party/WebKit/LayoutTests/editing/execCommand/selection_image_after_alignment_change.html b/third_party/WebKit/LayoutTests/editing/execCommand/selection_image_after_alignment_change.html new file mode 100644 index 0000000..5625cb77 --- /dev/null +++ b/third_party/WebKit/LayoutTests/editing/execCommand/selection_image_after_alignment_change.html
@@ -0,0 +1,45 @@ +<!doctype html> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<script src="../assert_selection.js"></script> +<script> +test(() => assert_selection( + [ + '<div contenteditable>', + 'foo<br>', + '|<img src="../resources/abe.png"><br>', + 'baz', + '</div>', + ], + 'JustifyCenter', + [ + '<div contenteditable>', + 'foo<br>', + '<div style="text-align: center;">', + '|<img src="../resources/abe.png">', + '</div>', + 'baz', + '</div>', + ]), + '1 JustifyCenter shoudld centralize the image without changing the selection.'); + +test(() => assert_selection( + [ + '<div contenteditable>', + 'foo<br>', + '^<img src="../resources/abe.png">|<br>', + 'baz', + '</div>', + ], + 'JustifyCenter', + [ + '<div contenteditable>', + 'foo<br>', + '<div style="text-align: center;">', + '^<img src="../resources/abe.png">|', + '</div>', + 'baz', + '</div>', + ]), + "2 JustifyCenter shoudld centralize the image without changing the selection."); +</script>
diff --git a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json index 3fbd775..3b59355 100644 --- a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json +++ b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
@@ -5439,6 +5439,18 @@ {} ] ], + "css-paint-api/hidpi/device-pixel-ratio.html": [ + [ + "/css-paint-api/hidpi/device-pixel-ratio.html", + [ + [ + "/css-paint-api/hidpi/device-pixel-ratio-ref.html", + "==" + ] + ], + {} + ] + ], "css-paint-api/invalid-image-constructor-error.html": [ [ "/css-paint-api/invalid-image-constructor-error.html", @@ -59567,42 +59579,6 @@ {} ] ], - "fonts/variations/variable-box-font.html": [ - [ - "/fonts/variations/variable-box-font.html", - [ - [ - "/fonts/variations/variable-box-font-ref.html", - "==" - ] - ], - {} - ] - ], - "fonts/variations/variable-gpos-m2b.html": [ - [ - "/fonts/variations/variable-gpos-m2b.html", - [ - [ - "/fonts/variations/variable-gpos-m2b-ref.html", - "==" - ] - ], - {} - ] - ], - "fonts/variations/variable-gsub.html": [ - [ - "/fonts/variations/variable-gsub.html", - [ - [ - "/fonts/variations/variable-gsub-ref.html", - "==" - ] - ], - {} - ] - ], "html/dom/elements/global-attributes/dir_auto-EN-L.html": [ [ "/html/dom/elements/global-attributes/dir_auto-EN-L.html", @@ -71327,6 +71303,11 @@ {} ] ], + "css-paint-api/hidpi/device-pixel-ratio-ref.html": [ + [ + {} + ] + ], "css-paint-api/invalid-image-constructor-error-ref.html": [ [ {} @@ -97757,26 +97738,6 @@ {} ] ], - "fonts/variations/resources/variabletest_box.ttf": [ - [ - {} - ] - ], - "fonts/variations/variable-box-font-ref.html": [ - [ - {} - ] - ], - "fonts/variations/variable-gpos-m2b-ref.html": [ - [ - {} - ] - ], - "fonts/variations/variable-gsub-ref.html": [ - [ - {} - ] - ], "fullscreen/OWNERS": [ [ {} @@ -98332,6 +98293,11 @@ {} ] ], + "html/browsers/browsing-the-web/scroll-to-fragid/navigate-helpers.js": [ + [ + {} + ] + ], "html/browsers/browsing-the-web/scroll-to-fragid/scroll-frag-percent-encoded-expected.txt": [ [ {} @@ -116962,31 +116928,11 @@ {} ] ], - "streams/piping/pipe-through-expected.txt": [ - [ - {} - ] - ], - "streams/piping/pipe-through.dedicatedworker-expected.txt": [ - [ - {} - ] - ], "streams/piping/pipe-through.js": [ [ {} ] ], - "streams/piping/pipe-through.serviceworker.https-expected.txt": [ - [ - {} - ] - ], - "streams/piping/pipe-through.sharedworker-expected.txt": [ - [ - {} - ] - ], "streams/piping/transform-streams-expected.txt": [ [ {} @@ -142892,6 +142838,18 @@ } ] ], + "html/browsers/browsing-the-web/scroll-to-fragid/forward-triggers-hashchange.html": [ + [ + "/html/browsers/browsing-the-web/scroll-to-fragid/forward-triggers-hashchange.html", + {} + ] + ], + "html/browsers/browsing-the-web/scroll-to-fragid/replacement-enabled.html": [ + [ + "/html/browsers/browsing-the-web/scroll-to-fragid/replacement-enabled.html", + {} + ] + ], "html/browsers/browsing-the-web/scroll-to-fragid/scroll-frag-percent-encoded.html": [ [ "/html/browsers/browsing-the-web/scroll-to-fragid/scroll-frag-percent-encoded.html", @@ -196497,6 +196455,14 @@ "a2d9214ac53508c5e551547be9beb953be7ab141", "reftest" ], + "css-paint-api/hidpi/device-pixel-ratio-ref.html": [ + "18f9d4d369de750ceb92c2e275ede5fcb3bf6f49", + "support" + ], + "css-paint-api/hidpi/device-pixel-ratio.html": [ + "470ec454e18e5398718f3117171b172208f84fee", + "reftest" + ], "css-paint-api/invalid-image-constructor-error-ref.html": [ "b0c34ee1480fe1108fe8dc53f2bbb2f3ffa1c408", "support" @@ -245845,34 +245811,6 @@ "eb192c5fe03811a1b69578c92bf77d8abab89f29", "support" ], - "fonts/variations/resources/variabletest_box.ttf": [ - "2fc122ff444d3ddef1f29ebde9a87827244ceeb0", - "support" - ], - "fonts/variations/variable-box-font-ref.html": [ - "65ccabcdeaa322eeceaa646863eba52654e3149b", - "support" - ], - "fonts/variations/variable-box-font.html": [ - "f3836fd9ea898b84bcef5dc259eeadbd4ecaeb68", - "reftest" - ], - "fonts/variations/variable-gpos-m2b-ref.html": [ - "769b04d218db5f7d882512b17c70683281499481", - "support" - ], - "fonts/variations/variable-gpos-m2b.html": [ - "af751a58338e49cc18b0b54c9451662d223f4977", - "reftest" - ], - "fonts/variations/variable-gsub-ref.html": [ - "1b80955335d4a14f3e0d545a6b5165aadff05a87", - "support" - ], - "fonts/variations/variable-gsub.html": [ - "2ae8392efc584c909f11ca04fb33a77f1b3c65ba", - "reftest" - ], "fullscreen/OWNERS": [ "80579a1e88af8e60c7446f34446b90bd3e9cf8c7", "support" @@ -246889,6 +246827,18 @@ "7e24cd47a4ae882b40f7f8798a44faf05f034c3d", "testharness" ], + "html/browsers/browsing-the-web/scroll-to-fragid/forward-triggers-hashchange.html": [ + "fb63063e0ff1ca6aaa350fae9b8f01bed5f9771f", + "testharness" + ], + "html/browsers/browsing-the-web/scroll-to-fragid/navigate-helpers.js": [ + "5b318196cb31c35e1b39eccd9e6a131a882f1a90", + "support" + ], + "html/browsers/browsing-the-web/scroll-to-fragid/replacement-enabled.html": [ + "99a355c63562aded2e2b252d989de332e8c12a0d", + "testharness" + ], "html/browsers/browsing-the-web/scroll-to-fragid/scroll-frag-percent-encoded-expected.txt": [ "6349211d6b05514f0a95da22fbb05a001bc5bf3e", "support" @@ -250702,7 +250652,7 @@ "support" ], "html/dom/interfaces-expected.txt": [ - "a07fcdd70e00fb7c2bf710b9baca69f1627d7597", + "b374b40edab710c459dd4ebf4124bfe0292347d3", "support" ], "html/dom/interfaces.html": [ @@ -250710,7 +250660,7 @@ "testharness" ], "html/dom/interfaces.worker-expected.txt": [ - "50bb938066a9efc63799c7e05a0d7a25dfc89d05", + "a24a8a102888593d0d3650f4ce3def44bcbe4c94", "support" ], "html/dom/interfaces.worker.js": [ @@ -261522,11 +261472,11 @@ "testharness" ], "html/webappapis/scripting/events/messageevent-constructor.https-expected.txt": [ - "8f38c7e45d05ca6a205ddaf9aa0f98a48d743152", + "366f77614a40444dafc4a50e3338d302e47177e1", "support" ], "html/webappapis/scripting/events/messageevent-constructor.https.html": [ - "78d9fe8ca88a24621890aee14d33694aa76c6a27", + "41b986c878176f99ef150c12ef6b74d00ef1f7cb", "testharness" ], "html/webappapis/scripting/events/onerroreventhandler-expected.txt": [ @@ -283901,14 +283851,6 @@ "a2aaf43f0d2eb831bd9f8e379fbf0076eee76633", "testharness" ], - "streams/piping/pipe-through-expected.txt": [ - "be12efb52e04d9e3c1b890a0eeb75a27a2a41d67", - "support" - ], - "streams/piping/pipe-through.dedicatedworker-expected.txt": [ - "be12efb52e04d9e3c1b890a0eeb75a27a2a41d67", - "support" - ], "streams/piping/pipe-through.dedicatedworker.html": [ "ed05dd7416cc07e178e481375c2372ce1094905e", "testharness" @@ -283921,18 +283863,10 @@ "df36e48e468e526d2d77e80906d62d1ec8e6d276", "support" ], - "streams/piping/pipe-through.serviceworker.https-expected.txt": [ - "3379509d63688229b4318c0947cb25bd4abdb595", - "support" - ], "streams/piping/pipe-through.serviceworker.https.html": [ "e6604dc4e7f4404ee9dea5ab237fb4636bf9e85a", "testharness" ], - "streams/piping/pipe-through.sharedworker-expected.txt": [ - "be12efb52e04d9e3c1b890a0eeb75a27a2a41d67", - "support" - ], "streams/piping/pipe-through.sharedworker.html": [ "8ecb019e754fd4239cb35c27787897efc2dacccb", "testharness" @@ -286474,7 +286408,7 @@ "testharness" ], "webmessaging/Channel_postMessage_ports_readonly_array.htm": [ - "9483112ff0962b068d69758f959627a9c9d299c5", + "2e23f79e2997ffa88b88651be6f2c355574f5de2", "testharness" ], "webmessaging/Channel_postMessage_target_source.htm": [ @@ -292406,7 +292340,7 @@ "testharness" ], "workers/postMessage_ports_readonly_array.htm": [ - "421c9ef573548559dad40272370150487c0aed8a", + "31c0e1779c7054dc6fa4137427b81d9c72229f73", "testharness" ], "workers/postMessage_target_source.htm": [
diff --git a/third_party/WebKit/LayoutTests/external/wpt/XMLHttpRequest/access-control-and-redirects-async.htm b/third_party/WebKit/LayoutTests/external/wpt/XMLHttpRequest/access-control-and-redirects-async.htm new file mode 100644 index 0000000..bf16c3c8 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/XMLHttpRequest/access-control-and-redirects-async.htm
@@ -0,0 +1,89 @@ +<!DOCTYPE html> +<html> + <head> + <title>Tests that asynchronous XMLHttpRequests handle redirects according to the CORS standard.</title> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="/common/get-host-info.sub.js"></script> + </head> + <body> + <script> + function runTest(test, destination, parameters, customHeader, local, expectSuccess) { + const xhr = new XMLHttpRequest(); + const url = (local ? get_host_info().HTTP_ORIGIN : get_host_info().HTTP_REMOTE_ORIGIN) + + "/XMLHttpRequest/resources/redirect-cors.py?location=" + destination + "&" + parameters; + + xhr.open("GET", url, true); + + if (customHeader) + xhr.setRequestHeader("x-test", "test"); + + xhr.onload = test.step_func_done(function() { + assert_true(expectSuccess); + assert_true(xhr.responseText.startsWith("PASS")); + }); + xhr.onerror = test.step_func_done(function() { + assert_false(expectSuccess); + assert_equals(xhr.status, 0); + }); + xhr.send(); + } + + const withCustomHeader = true; + const withoutCustomHeader = false; + const local = true; + const remote = false; + const succeeds = true; + const fails = false; + + // Test simple cross origin requests that receive redirects. + + // The redirect response fails the access check because the redirect lacks a CORS header. + async_test(t => { + runTest(t, get_host_info().HTTP_REMOTE_ORIGIN + + "/XMLHttpRequest/resources/access-control-basic-allow-star.py", "", + withoutCustomHeader, remote, fails) + }, "Request is redirected without CORS headers to a response with Access-Control-Allow-Origin=*"); + + // The redirect response passes the access check. + async_test(t => { + runTest(t, get_host_info().HTTP_REMOTE_ORIGIN + + "/XMLHttpRequest/resources/access-control-basic-allow-star.py", "allow_origin=true", + withoutCustomHeader, remote, succeeds) + }, "Request is redirected to a response with Access-Control-Allow-Origin=*"); + + // The redirect response fails the access check because user info was sent. + async_test(t => { + runTest(t, get_host_info().HTTP_REMOTE_ORIGIN.replace("http://", "http://username:password@") + + "/XMLHttpRequest/resources/access-control-basic-allow-star.py", "allow_origin=true", + withoutCustomHeader, remote, fails) + }, "Request with user info is redirected to a response with Access-Control-Allow-Origin=*"); + + // The redirect response fails the access check because the URL scheme is unsupported. + async_test(t => { + runTest(t, "foo://bar.cgi", "allow_origin=true", withoutCustomHeader, remote, fails) + }, "Request is redirect to a bad URL"); + + // The preflighted redirect response fails the access check because of preflighting. + async_test(t => { + runTest(t, get_host_info().HTTP_REMOTE_ORIGIN + + "/XMLHttpRequest/resources/access-control-basic-allow-star.py", + "allow_origin=true&redirect_preflight=true", withCustomHeader, remote, fails) + }, "Preflighted request is redirected to a response with Access-Control-Allow-Origin=*"); + + // The preflighted redirect response fails the access check after successful preflighting. + async_test(t => { + runTest(t, get_host_info().HTTP_REMOTE_ORIGIN + + "/XMLHttpRequest/resources/access-control-basic-allow-star.py", + "allow_origin=true&allow_header=x-test&redirect_preflight=true", + withCustomHeader, remote, fails) + }, "Preflighted request is redirected to a response with Access-Control-Allow-Origin=* and header allowed"); + + // The same-origin redirect response passes the access check. + async_test(t => { + runTest(t, get_host_info().HTTP_ORIGIN + "/XMLHttpRequest/resources/pass.txt", + "", withCustomHeader, local, succeeds) + }, "Request is redirected to a same-origin resource file"); + </script> + </body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/XMLHttpRequest/resources/pass.txt b/third_party/WebKit/LayoutTests/external/wpt/XMLHttpRequest/resources/pass.txt new file mode 100644 index 0000000..7ef22e9 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/XMLHttpRequest/resources/pass.txt
@@ -0,0 +1 @@ +PASS
diff --git a/third_party/WebKit/LayoutTests/external/wpt/XMLHttpRequest/resources/redirect-cors.py b/third_party/WebKit/LayoutTests/external/wpt/XMLHttpRequest/resources/redirect-cors.py index 1439fc57..27609b8 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/XMLHttpRequest/resources/redirect-cors.py +++ b/third_party/WebKit/LayoutTests/external/wpt/XMLHttpRequest/resources/redirect-cors.py
@@ -1,7 +1,20 @@ def main(request, response): - response.status = 302 location = request.GET.first("location") - response.headers.set("Location", location) + + if request.method == "OPTIONS": + if "redirect_preflight" in request.GET: + response.status = 302 + response.headers.set("Location", location) + else: + response.status = 200 + response.headers.set("Access-Control-Allow-Methods", "GET") + response.headers.set("Access-Control-Max-Age", 1) + elif request.method == "GET": + response.status = 302 + response.headers.set("Location", location) if "allow_origin" in request.GET: response.headers.set("Access-Control-Allow-Origin", request.headers.get("origin")) + + if "allow_header" in request.GET: + response.headers.set("Access-Control-Allow-Headers", request.GET.first("allow_header"))
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css-backgrounds/background-clip-color-ref.html b/third_party/WebKit/LayoutTests/external/wpt/css-backgrounds/background-clip-color-ref.html new file mode 100644 index 0000000..0bd414c --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css-backgrounds/background-clip-color-ref.html
@@ -0,0 +1,19 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Test Reference</title> +<link rel="author" title="Rune Lillesveen" href="mailto:rune@opera.com"> +<style> + .refSquare { + margin: 10px; + width: 30px; + height: 30px; + background-color: green; + } +</style> +<p>There should be three green 30x30 px squares below.</p> +<div>border-box</div> +<div class="refSquare"></div> +<div>padding-box</div> +<div class="refSquare"></div> +<duv>content-box</div> +<div class="refSquare"></div>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css-backgrounds/background-clip-color-repaint-ref.html b/third_party/WebKit/LayoutTests/external/wpt/css-backgrounds/background-clip-color-repaint-ref.html new file mode 100644 index 0000000..81e95173 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css-backgrounds/background-clip-color-repaint-ref.html
@@ -0,0 +1,6 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Test Reference</title> +<link rel="author" title="Rune Lillesveen" href="mailto:rune@opera.com"> +<p>There should be a green square below.</p> +<div style="background-color:green;width:150px;height:150px"></div>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css-backgrounds/background-clip-color-repaint.html b/third_party/WebKit/LayoutTests/external/wpt/css-backgrounds/background-clip-color-repaint.html new file mode 100644 index 0000000..6052db52 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css-backgrounds/background-clip-color-repaint.html
@@ -0,0 +1,35 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<meta charset="utf-8"> +<title>CSS Backgrounds and Borders: background-clip color background repaint</title> +<link rel="author" title="Rune Lillesveen" href="mailto:rune@opera.com"> +<link rel="match" href="background-clip-color-repaint-ref.html"> +<link rel="help" href="https://drafts.csswg.org/css-backgrounds/#the-background-clip"> +<style> + #outer { + width: 150px; + height: 150px; + background-color: red; + } + #inner { + border: 30px dashed green; + padding: 30px; + width: 30px; + height: 30px; + background-color: green; + background-clip: content-box; + } +</style> +<p>There should be a green square below.</p> +<div id="outer"> + <div id="inner"></div> +</div> +<script> + requestAnimationFrame(function(){ + requestAnimationFrame(function(){ + inner.style.backgroundClip = "border-box"; + document.documentElement.classList.remove("reftest-wait"); + }); + }); + inner.style.backgroundClip = "border-box"; +</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css-backgrounds/background-clip-color.html b/third_party/WebKit/LayoutTests/external/wpt/css-backgrounds/background-clip-color.html new file mode 100644 index 0000000..b09d8086 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css-backgrounds/background-clip-color.html
@@ -0,0 +1,60 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Backgrounds and Borders: background-clip color backgrounds</title> +<link rel="author" title="Rune Lillesveen" href="mailto:rune@opera.com"> +<link rel="match" href="background-clip-color-ref.html"> +<link rel="help" href="https://drafts.csswg.org/css-backgrounds/#the-background-clip"> +<style> + #borderBoxHelper { + margin: 10px; + width: 30px; + height: 30px; + background-color: red; + } + #borderBox { + border: 6px dashed green; + padding: 6px; + width: 6px; + height: 6px; + background-color: green; + background-clip: border-box; + } + #paddingBoxHelper { + width: 30px; + height: 30px; + background-color: red; + } + #paddingBox { + border: 10px dashed white; + padding: 10px; + width: 10px; + height: 10px; + background-color: green; + background-clip: padding-box; + } + #contentBoxHelper { + width: 30px; + height: 30px; + background-color: red; + } + #contentBox { + padding: 10px; + width: 30px; + height: 30px; + background-color: green; + background-clip: content-box; + } +</style> +<p>There should be three green 30x30 px squares below.</p> +<div>border-box</div> +<div id="borderBoxHelper"> + <div id="borderBox"></div> +</div> +<div>padding-box</div> +<div class="paddingBoxHelper"> + <div id="paddingBox"></div> +</div> +<div>content-box</div> +<div class="contentgBoxHelper"> + <div id="contentBox"></div> +</div>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/fonts/variations/resources/variabletest_box.ttf b/third_party/WebKit/LayoutTests/external/wpt/fonts/variations/resources/variabletest_box.ttf deleted file mode 100644 index 53b5b242..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/fonts/variations/resources/variabletest_box.ttf +++ /dev/null Binary files differ
diff --git a/third_party/WebKit/LayoutTests/external/wpt/fonts/variations/variable-box-font-ref.html b/third_party/WebKit/LayoutTests/external/wpt/fonts/variations/variable-box-font-ref.html deleted file mode 100644 index 142b0aa..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/fonts/variations/variable-box-font-ref.html +++ /dev/null
@@ -1,20 +0,0 @@ -<!DOCTYPE html> -<html class="reftest-wait"> -<meta charset="utf-8"> -<style> - @font-face { - font-family: variabletest_box; - src: url(resources/variabletest_box.ttf); - } - - body { - font-family: variabletest_box, sans-serif; - font-size: 200px; - } -</style> -â–„ â–€ -<script> - document.fonts.ready.then( - () => { document.documentElement.classList.remove("reftest-wait"); }); -</script> -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/fonts/variations/variable-box-font.html b/third_party/WebKit/LayoutTests/external/wpt/fonts/variations/variable-box-font.html deleted file mode 100644 index a9023fab..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/fonts/variations/variable-box-font.html +++ /dev/null
@@ -1,31 +0,0 @@ -<!DOCTYPE html> -<html class="reftest-wait"> -<link rel="match" href="variable-box-font-ref.html"> -<meta charset="utf-8"> -<style> - @font-face { - font-family: variabletest_box; - src: url(resources/variabletest_box.ttf); - } - - body { - font-family: variabletest_box, - sans-serif; - font-size: 200px; - } - - .a_up { - font-variation-settings: "UPWD" 350; - } -</style> -<!-- The variabletest_box font has an A glyph that looks like a lower half box, - with deltas on the 'UPWD' variation axis that allow shifting the box up. At - 350, the box is at the top. The font also has two glyphs for UPPER HALF BLOCK - and LOWER HALF BLOCK, which look identical to the respective variations of A. ---> -A <span class="a_up">A</span> -<script> - document.fonts.ready.then( - () => { document.documentElement.classList.remove("reftest-wait"); }); -</script> -</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/fonts/variations/variable-gpos-m2b-ref.html b/third_party/WebKit/LayoutTests/external/wpt/fonts/variations/variable-gpos-m2b-ref.html deleted file mode 100644 index c6b80b1b..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/fonts/variations/variable-gpos-m2b-ref.html +++ /dev/null
@@ -1,21 +0,0 @@ -<!DOCTYPE html> -<html class="reftest-wait"> -<meta charset="utf-8"> -<style> - @font-face { - font-family: variabletest_box; - src: url(resources/variabletest_box.ttf); - } - - body { - font-family: variabletest_box, sans-serif; - sans-serif; - font-size: 100px; - } -</style> -M̻ N̻ O̻ -<script> - document.fonts.ready.then( - () => { document.documentElement.classList.remove("reftest-wait"); }); -</script> -</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/fonts/variations/variable-gpos-m2b.html b/third_party/WebKit/LayoutTests/external/wpt/fonts/variations/variable-gpos-m2b.html deleted file mode 100644 index 9b976e1..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/fonts/variations/variable-gpos-m2b.html +++ /dev/null
@@ -1,45 +0,0 @@ -<!DOCTYPE html> -<html class="reftest-wait"> -<link rel="match" href="variable-gpos-m2b-ref.html"> -<meta charset="utf-8"> -<style> - @font-face { - font-family: variabletest_box; - src: url(resources/variabletest_box.ttf); - } - - body { - font-family: variabletest_box, sans-serif; - sans-serif; - font-size: 100px; - } - - .gpos_m2b_left { - font-variation-settings: "VM2B" 0; - } - - .gpos_m2b_middle { - font-variation-settings: "VM2B" 500; - } - - .gpos_m2b_right { - font-variation-settings: "VM2B" 1000; - } -</style> -<!-- The variabletest_box font has an M glyph saying "m2b pos" that combines - with the combining box below. And it has a glyph for combining box below - whose mark anchor can be shifted horizontally using the VM2B axis. The font - also has N and O glyphs which have fixed shifted base anchor points at the - middle and at the right position. In this ref test we check whether - applying the VM2B axis works as expected and shifts the mark anchor point - left so that the combining mark is placed correctly at the middle and at - the right position. The VM2B rendering must be identical to the - conventional rendering with the fixed base anchor points. --> -<span class="gpos_m2b_left">M̻</span> -<span class="gpos_m2b_middle">M̻</span> -<span class="gpos_m2b_right">M̻</span> -<script> - document.fonts.ready.then( - () => { document.documentElement.classList.remove("reftest-wait"); }); -</script> -</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/fonts/variations/variable-gsub-ref.html b/third_party/WebKit/LayoutTests/external/wpt/fonts/variations/variable-gsub-ref.html deleted file mode 100644 index 3b1f7f43..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/fonts/variations/variable-gsub-ref.html +++ /dev/null
@@ -1,21 +0,0 @@ -<!DOCTYPE html> -<html class="reftest-wait"> -<meta charset="utf-8"> -<style> - @font-face { - font-family: variabletest_box; - src: url(resources/variabletest_box.ttf); - } - - body { - font-family: variabletest_box, sans-serif; - sans-serif; - font-size: 100px; - } -</style> -r R -<script> - document.fonts.ready.then( - () => { document.documentElement.classList.remove("reftest-wait"); }); -</script> -</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/fonts/variations/variable-gsub.html b/third_party/WebKit/LayoutTests/external/wpt/fonts/variations/variable-gsub.html deleted file mode 100644 index ed432f6..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/fonts/variations/variable-gsub.html +++ /dev/null
@@ -1,34 +0,0 @@ -<!DOCTYPE html> -<html class="reftest-wait"> -<link rel="match" href="variable-gsub-ref.html"> -<meta charset="utf-8"> -<style> - @font-face { - font-family: variabletest_box; - src: url(resources/variabletest_box.ttf); - } - - body { - font-family: variabletest_box, sans-serif; - sans-serif; - font-size: 100px; - } - - .rvrn_replaced { - font-variation-settings: "FVTT" 10; - } -</style> -<!-- The variabletest_box font has an r glyph that says "rvrn base" and has - this as a name as well. And it has a glyph for R that says "rvrn subst" - where rvrn stands for the required Required Variation Alternates - feature. The font has an 'FVTT' axis ranging from 0 to 10, where it uses - a single substitution glyph lookup table for axis values starting from - 5, which then replaces the rvrn_base glyph with the rvrn_subst - glyph. So in this reftest the substituted glyph for lowercase r - should visually match the uppercase R glyph, both show "rvrn subst". --> -r <span class="rvrn_replaced">r</span> -<script> - document.fonts.ready.then( - () => { document.documentElement.classList.remove("reftest-wait"); }); -</script> -</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/browsers/browsing-the-web/scroll-to-fragid/forward-triggers-hashchange.html b/third_party/WebKit/LayoutTests/external/wpt/html/browsers/browsing-the-web/scroll-to-fragid/forward-triggers-hashchange.html new file mode 100644 index 0000000..45f7e38 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/html/browsers/browsing-the-web/scroll-to-fragid/forward-triggers-hashchange.html
@@ -0,0 +1,44 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Navigating forward after replace() should still trigger hashchange</title> +<link rel="help" href="https://html.spec.whatwg.org/multipage/#history-traversal"> +<link rel="author" href="mailto:d@domenic.me" title="Domenic Denicola"> + +<!-- While writing ./replacement-enabled.html, a bug was discovered in Firefox where it does not +fire hashchange when using history.forward(), at least under certain conditions. So, this test +exercises that specifically. --> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="navigate-helpers.js"></script> + +<body> + +<script> +"use strict"; +let resolve, iframe; +promise_test(() => { + iframe = document.createElement("iframe"); + iframe.src = "/common/blank.html"; + iframe.addEventListener("load", runTest); + document.body.appendChild(iframe); + + return new Promise(r => resolve = r); +}); + +function runTest() { + iframe.removeEventListener("load", runTest); + const frameWindow = iframe.contentWindow; + + resolve((async () => { + await navigateAndWaitForChange(frameWindow, w => w.location.href = "/common/blank.html#apple"); + await navigateAndWaitForChange(frameWindow, w => w.location.href = "/common/blank.html#banana"); + await navigateAndWaitForChange(frameWindow, w => w.location.href = "/common/blank.html#cat"); + + await navigateAndWaitForChange(frameWindow, w => w.history.back()); + await navigateAndWaitForChange(frameWindow, + w => w.location.replace("/common/blank.html#zebra")); + await navigateAndWaitForChange(frameWindow, w => w.history.forward()); + })()); +} +</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/browsers/browsing-the-web/scroll-to-fragid/navigate-helpers.js b/third_party/WebKit/LayoutTests/external/wpt/html/browsers/browsing-the-web/scroll-to-fragid/navigate-helpers.js new file mode 100644 index 0000000..7a9adeb --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/html/browsers/browsing-the-web/scroll-to-fragid/navigate-helpers.js
@@ -0,0 +1,23 @@ +"use strict"; + +// Usage examples: +// navigateAndWaitForChange(frameWindow, w => w.location.href = "..."); +// navigateAndWaitForChange(frameWindow, w => w.history.back()); +// navigateAndWaitForChange(frameWindow, w => w.history.back(), { assumeSuccessAfter: 100 }); + +window.navigateAndWaitForChange = (w, navigationAction, { assumeSuccessAfter } = {}) => { + return new Promise(resolve => { + w.addEventListener("hashchange", listener); + + function listener() { + w.removeEventListener("hashchange", listener); + resolve(); + } + + if (assumeSuccessAfter !== undefined) { + step_timeout(resolve, assumeSuccessAfter); + } + + navigationAction(w); + }); +};
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/browsers/browsing-the-web/scroll-to-fragid/replacement-enabled.html b/third_party/WebKit/LayoutTests/external/wpt/html/browsers/browsing-the-web/scroll-to-fragid/replacement-enabled.html new file mode 100644 index 0000000..f684bcb3 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/html/browsers/browsing-the-web/scroll-to-fragid/replacement-enabled.html
@@ -0,0 +1,69 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Navigating to a fragment should not clear forward history</title> +<link rel="help" href="https://html.spec.whatwg.org/multipage/#scroll-to-fragid"> +<link rel="help" href="https://github.com/whatwg/html/issues/2796"> +<link rel="help" href="https://github.com/whatwg/html/pull/2869"> +<link rel="author" href="mailto:d@domenic.me" title="Domenic Denicola"> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="navigate-helpers.js"></script> + +<body> + +<script> +"use strict"; +let resolve, iframe; +promise_test(() => { + iframe = document.createElement("iframe"); + iframe.src = "/common/blank.html"; + iframe.addEventListener("load", runTest); + document.body.appendChild(iframe); + + return new Promise(r => resolve = r); +}); + +function runTest() { + iframe.removeEventListener("load", runTest); + const frameWindow = iframe.contentWindow; + + resolve((async () => { + await navigateAndWaitForChange(frameWindow, w => w.location.href = "/common/blank.html#apple"); + await navigateAndWaitForChange(frameWindow, w => w.location.href = "/common/blank.html#banana"); + await navigateAndWaitForChange(frameWindow, w => w.location.href = "/common/blank.html#cat"); + + assert_equals(frameWindow.location.hash, "#cat"); + + // Might not be 4 (= 3 for iframe + 1 initial) due to cross-browser differences or if people are + // running this test in a window that has previously been places. The important thing for this + // test is the delta from this value. + const afterThreeNavigations = frameWindow.history.length; + + await navigateAndWaitForChange(frameWindow, w => w.history.back()); + + assert_equals(frameWindow.location.hash, "#banana"); + assert_equals(frameWindow.history.length, afterThreeNavigations, + "back() must not change the history length"); + + await navigateAndWaitForChange(frameWindow, + w => w.location.replace("/common/blank.html#zebra")); + + assert_equals(frameWindow.location.hash, "#zebra"); + assert_equals(frameWindow.history.length, afterThreeNavigations, + "replace() must not change the history length"); + + // As of the time of this writing (2017-08-14), Firefox is not firing hashchange on forward, so + // we automatically assume navigation succeeded after 100 ms. A sibling test will test this + // particular Firefox bug. + await navigateAndWaitForChange(frameWindow, w => w.history.forward(), + { assumeSuccessAfter: 100 }); + + assert_equals(frameWindow.location.hash, "#cat"); + assert_equals(frameWindow.history.length, afterThreeNavigations, + "forward() must not change the history length"); + + })()); +} + +</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/dom/interfaces-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/html/dom/interfaces-expected.txt index 7a7ba5c8..64d36cc 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/html/dom/interfaces-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/html/dom/interfaces-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 5323 tests; 5124 PASS, 199 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 5323 tests; 5125 PASS, 198 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS Test driver PASS Document interface: attribute domain PASS Document interface: attribute referrer @@ -5004,7 +5004,7 @@ PASS MessageEvent interface: new MessageEvent("message", { data: 5 }) must inherit property "origin" with the proper type PASS MessageEvent interface: new MessageEvent("message", { data: 5 }) must inherit property "lastEventId" with the proper type FAIL MessageEvent interface: new MessageEvent("message", { data: 5 }) must inherit property "source" with the proper type Unrecognized type WindowProxy -FAIL MessageEvent interface: new MessageEvent("message", { data: 5 }) must inherit property "ports" with the proper type assert_true: Value should be array expected true got false +PASS MessageEvent interface: new MessageEvent("message", { data: 5 }) must inherit property "ports" with the proper type PASS MessageEvent interface: new MessageEvent("message", { data: 5 }) must inherit property "initMessageEvent(DOMString, boolean, boolean, any, USVString, DOMString, MessageEventSource, [object Object])" with the proper type FAIL MessageEvent interface: calling initMessageEvent(DOMString, boolean, boolean, any, USVString, DOMString, MessageEventSource, [object Object]) on new MessageEvent("message", { data: 5 }) with too few arguments must throw TypeError assert_throws: Called with 0 arguments function "function () { fn.apply(obj, args);
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/dom/interfaces.worker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/html/dom/interfaces.worker-expected.txt index 2d3637b0..7065b85 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/html/dom/interfaces.worker-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/html/dom/interfaces.worker-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 589 tests; 539 PASS, 50 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 589 tests; 540 PASS, 49 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS Test driver PASS EventListener interface: existence and properties of interface object PASS NodeList interface: existence and properties of interface object @@ -316,7 +316,7 @@ PASS MessageEvent interface: new MessageEvent("message", { data: 5 }) must inherit property "origin" with the proper type PASS MessageEvent interface: new MessageEvent("message", { data: 5 }) must inherit property "lastEventId" with the proper type FAIL MessageEvent interface: new MessageEvent("message", { data: 5 }) must inherit property "source" with the proper type Unrecognized type WindowProxy -FAIL MessageEvent interface: new MessageEvent("message", { data: 5 }) must inherit property "ports" with the proper type assert_true: Value should be array expected true got false +PASS MessageEvent interface: new MessageEvent("message", { data: 5 }) must inherit property "ports" with the proper type PASS MessageEvent interface: new MessageEvent("message", { data: 5 }) must inherit property "initMessageEvent(DOMString, boolean, boolean, any, USVString, DOMString, MessageEventSource, [object Object])" with the proper type FAIL MessageEvent interface: calling initMessageEvent(DOMString, boolean, boolean, any, USVString, DOMString, MessageEventSource, [object Object]) on new MessageEvent("message", { data: 5 }) with too few arguments must throw TypeError assert_throws: Called with 0 arguments function "function () { fn.apply(obj, args);
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/webappapis/scripting/events/messageevent-constructor.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/html/webappapis/scripting/events/messageevent-constructor.https-expected.txt index 083fa34..111169d 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/html/webappapis/scripting/events/messageevent-constructor.https-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/html/webappapis/scripting/events/messageevent-constructor.https-expected.txt
@@ -1,10 +1,8 @@ This is a testharness.js-based test. -FAIL Default event values Cannot read property 'length' of null +PASS Default event values PASS MessageEventInit dictionary -FAIL Passing null for ports member assert_throws: function "function () { - new MessageEvent("test", { ports: null }) - }" did not throw -FAIL ports attribute should be a FrozenArray assert_true: Object.isFrozen() should return true expected true got false +PASS Passing null for ports member +PASS ports attribute should be a FrozenArray PASS initMessageEvent operation FAIL Passing null for ports parameter to initMessageEvent assert_throws: function "function () { ev.initMessageEvent("test", true, false, "testData", "testOrigin", "testId", window, null)
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/webappapis/scripting/events/messageevent-constructor.https.html b/third_party/WebKit/LayoutTests/external/wpt/html/webappapis/scripting/events/messageevent-constructor.https.html index 479127d..70b5ff6 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/html/webappapis/scripting/events/messageevent-constructor.https.html +++ b/third_party/WebKit/LayoutTests/external/wpt/html/webappapis/scripting/events/messageevent-constructor.https.html
@@ -45,6 +45,10 @@ assert_true(Array.isArray(ev.ports), "Array.isArray() should return true") assert_true(Object.isFrozen(ev.ports), "Object.isFrozen() should return true") assert_true(ev.ports === ev.ports, "ev.ports should return the same object") + + const oldPorts = ev.ports; + ev.initMessageEvent("test", false, false, null, "", "", null, ev.ports); + assert_not_equals(oldPorts, ev.ports, "initMessageEvent() changes ev.ports"); }, "ports attribute should be a FrozenArray") test(function() {
diff --git a/third_party/WebKit/LayoutTests/external/wpt/mediacapture-streams/MediaStream-idl.https.html b/third_party/WebKit/LayoutTests/external/wpt/mediacapture-streams/MediaStream-idl.https.html index 81cce51..21ab468 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/mediacapture-streams/MediaStream-idl.https.html +++ b/third_party/WebKit/LayoutTests/external/wpt/mediacapture-streams/MediaStream-idl.https.html
@@ -36,15 +36,19 @@ assert_equals(stream4.getTrackById(audioTrack1.id), audioTrack1, "a non-ended track gets added via the MediaStream constructor"); var audioTrack2 = audioTrack1.clone(); - audioTrack2.addEventListener("ended", t.step_func(function () { - var stream3 = new MediaStream([audioTrack2, videoTrack]); - assert_equals(stream3.getTrackById(audioTrack2.id), null, "an ended track doesn't get added via the MediaStream constructor"); - assert_equals(stream3.getTrackById(videoTrack.id), videoTrack, "a non-ended track gets added via the MediaStream constructor even if the previous track was ended"); - var stream5 = new MediaStream([audioTrack2]); - assert_false(stream5.active, "a MediaStream created using the MediaStream() constructor whose arguments are lists of MediaStreamTrack objects that are all ended, the MediaStream object MUST be created with its active attribute set to false"); - t.done(); - }), false); + audioTrack2.addEventListener("ended", t.unreached_func("ended event should not be fired by MediaStreamTrack.stop().")); audioTrack2.stop(); + + var stream3 = new MediaStream([audioTrack2, videoTrack]); + assert_array_equals(stream3.getTracks(), [videoTrack], "an ended track doesn't get added via the MediaStream constructor"); + assert_equals(stream3.getTrackById(videoTrack.id), videoTrack, "a non-ended track gets added via the MediaStream constructor even if the previous track was ended"); + + var stream5 = new MediaStream([audioTrack2]); + assert_array_equals(stream5.getTracks(), [], "an ended track doesn't get added via the MediaStream constructor") + assert_false(stream5.active, "a MediaStream created using the MediaStream() constructor whose arguments are lists of MediaStreamTrack objects that are all ended, the MediaStream object MUST be created with its active attribute set to false"); + + // Use a timeout to detect a misfire of the ended event. + t.step_timeout(t.step_func_done()); }), function(error) {}); }); </script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/pipe-through-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/pipe-through-expected.txt deleted file mode 100644 index 9345061a0..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/pipe-through-expected.txt +++ /dev/null
@@ -1,16 +0,0 @@ -This is a testharness.js-based test. -PASS Piping through a duck-typed pass-through transform stream should work -PASS Piping through a transform errored on the writable end does not cause an unhandled promise rejection -PASS pipeThrough generically calls pipeTo with the appropriate args -PASS pipeThrough can handle calling a pipeTo that returns a non-promise object -PASS pipeThrough can handle calling a pipeTo that returns a non-promise thenable object -PASS pipeThrough should mark a real promise from a fake readable as handled -PASS pipeThrough should not be fooled by an object whose instanceof Promise returns true -FAIL undefined readable or writable arguments should cause pipeThrough to throw assert_throws: pipeThrough should throw for argument {} (index 0); function "() => rs.pipeThrough(pair)" did not throw -PASS invalid but not undefined arguments should not cause pipeThrough to throw -PASS pipeThrough should throw when its first argument is not convertible to an object -PASS pipeThrough should throw when "this" has no pipeTo method -PASS pipeThrough should rethrow errors from accessing pipeTo, readable, or writable -PASS pipeThrough should work with no options argument -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/pipe-through.dedicatedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/pipe-through.dedicatedworker-expected.txt deleted file mode 100644 index 9345061a0..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/pipe-through.dedicatedworker-expected.txt +++ /dev/null
@@ -1,16 +0,0 @@ -This is a testharness.js-based test. -PASS Piping through a duck-typed pass-through transform stream should work -PASS Piping through a transform errored on the writable end does not cause an unhandled promise rejection -PASS pipeThrough generically calls pipeTo with the appropriate args -PASS pipeThrough can handle calling a pipeTo that returns a non-promise object -PASS pipeThrough can handle calling a pipeTo that returns a non-promise thenable object -PASS pipeThrough should mark a real promise from a fake readable as handled -PASS pipeThrough should not be fooled by an object whose instanceof Promise returns true -FAIL undefined readable or writable arguments should cause pipeThrough to throw assert_throws: pipeThrough should throw for argument {} (index 0); function "() => rs.pipeThrough(pair)" did not throw -PASS invalid but not undefined arguments should not cause pipeThrough to throw -PASS pipeThrough should throw when its first argument is not convertible to an object -PASS pipeThrough should throw when "this" has no pipeTo method -PASS pipeThrough should rethrow errors from accessing pipeTo, readable, or writable -PASS pipeThrough should work with no options argument -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/pipe-through.serviceworker.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/pipe-through.serviceworker.https-expected.txt deleted file mode 100644 index 684eb45..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/pipe-through.serviceworker.https-expected.txt +++ /dev/null
@@ -1,17 +0,0 @@ -This is a testharness.js-based test. -PASS Service worker test setup -PASS Piping through a duck-typed pass-through transform stream should work -PASS Piping through a transform errored on the writable end does not cause an unhandled promise rejection -PASS pipeThrough generically calls pipeTo with the appropriate args -PASS pipeThrough can handle calling a pipeTo that returns a non-promise object -PASS pipeThrough can handle calling a pipeTo that returns a non-promise thenable object -PASS pipeThrough should mark a real promise from a fake readable as handled -PASS pipeThrough should not be fooled by an object whose instanceof Promise returns true -FAIL undefined readable or writable arguments should cause pipeThrough to throw assert_throws: pipeThrough should throw for argument {} (index 0); function "() => rs.pipeThrough(pair)" did not throw -PASS invalid but not undefined arguments should not cause pipeThrough to throw -PASS pipeThrough should throw when its first argument is not convertible to an object -PASS pipeThrough should throw when "this" has no pipeTo method -PASS pipeThrough should rethrow errors from accessing pipeTo, readable, or writable -PASS pipeThrough should work with no options argument -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/pipe-through.sharedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/piping/pipe-through.sharedworker-expected.txt deleted file mode 100644 index 9345061a0..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/streams/piping/pipe-through.sharedworker-expected.txt +++ /dev/null
@@ -1,16 +0,0 @@ -This is a testharness.js-based test. -PASS Piping through a duck-typed pass-through transform stream should work -PASS Piping through a transform errored on the writable end does not cause an unhandled promise rejection -PASS pipeThrough generically calls pipeTo with the appropriate args -PASS pipeThrough can handle calling a pipeTo that returns a non-promise object -PASS pipeThrough can handle calling a pipeTo that returns a non-promise thenable object -PASS pipeThrough should mark a real promise from a fake readable as handled -PASS pipeThrough should not be fooled by an object whose instanceof Promise returns true -FAIL undefined readable or writable arguments should cause pipeThrough to throw assert_throws: pipeThrough should throw for argument {} (index 0); function "() => rs.pipeThrough(pair)" did not throw -PASS invalid but not undefined arguments should not cause pipeThrough to throw -PASS pipeThrough should throw when its first argument is not convertible to an object -PASS pipeThrough should throw when "this" has no pipeTo method -PASS pipeThrough should rethrow errors from accessing pipeTo, readable, or writable -PASS pipeThrough should work with no options argument -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webmessaging/Channel_postMessage_ports_readonly_array.htm b/third_party/WebKit/LayoutTests/external/wpt/webmessaging/Channel_postMessage_ports_readonly_array.htm index de2952dc..4ccf3ac 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/webmessaging/Channel_postMessage_ports_readonly_array.htm +++ b/third_party/WebKit/LayoutTests/external/wpt/webmessaging/Channel_postMessage_ports_readonly_array.htm
@@ -8,6 +8,7 @@ <body> <div id=log></div> <script> + "use strict"; var TargetPort = null; var description = "The postMessage() method - Make new ports into a read only array."; @@ -27,9 +28,9 @@ function TestMessageEvent(evt) { var channel3 = new MessageChannel(); - evt.ports.push(channel3.port1); - evt.ports.push(channel3.port1); - + assert_throws(new TypeError(), () => { + evt.ports.push(channel3.port1); + }, "ports is a frozen object"); assert_equals(evt.ports.length, 1, "ports is a read only array with length == 1."); t.done(); }
diff --git a/third_party/WebKit/LayoutTests/external/wpt/workers/postMessage_ports_readonly_array.htm b/third_party/WebKit/LayoutTests/external/wpt/workers/postMessage_ports_readonly_array.htm index 5e2b905..0645ea7 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/workers/postMessage_ports_readonly_array.htm +++ b/third_party/WebKit/LayoutTests/external/wpt/workers/postMessage_ports_readonly_array.htm
@@ -4,14 +4,16 @@ <script src="/resources/testharnessreport.js"></script> <div id=log></div> <script> +"use strict"; async_test(function(t) { var channel = new MessageChannel(); var targetPort = channel.port2; targetPort.start(); targetPort.addEventListener("message", t.step_func_done(function(e) { var channel3 = new MessageChannel(); - e.ports.push(channel3.port1); - e.ports.push(channel3.port1); + assert_throws(new TypeError(), () => { + e.ports.push(channel3.port1); + }, "ports is a frozen object"); assert_equals(e.ports.length, 1, "ports is a read only array with length == 1."); }), true); var channel2 = new MessageChannel();
diff --git a/third_party/WebKit/LayoutTests/fast/borders/border-radius-with-box-shadow-expected.png b/third_party/WebKit/LayoutTests/fast/borders/border-radius-with-box-shadow-expected.png index c6ed049..86921b2 100644 --- a/third_party/WebKit/LayoutTests/fast/borders/border-radius-with-box-shadow-expected.png +++ b/third_party/WebKit/LayoutTests/fast/borders/border-radius-with-box-shadow-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/box-shadow/single-pixel-shadow-expected.png b/third_party/WebKit/LayoutTests/fast/box-shadow/single-pixel-shadow-expected.png index 21df61f9..9eb4ea4 100644 --- a/third_party/WebKit/LayoutTests/fast/box-shadow/single-pixel-shadow-expected.png +++ b/third_party/WebKit/LayoutTests/fast/box-shadow/single-pixel-shadow-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/encoding/GBK/EUC-CN-expected.txt b/third_party/WebKit/LayoutTests/fast/encoding/GBK/EUC-CN-expected.txt deleted file mode 100644 index ec39154..0000000 --- a/third_party/WebKit/LayoutTests/fast/encoding/GBK/EUC-CN-expected.txt +++ /dev/null
@@ -1,5 +0,0 @@ -The following two lines should look identically: - -一熀镕 - -一熀镕
diff --git a/third_party/WebKit/LayoutTests/fast/encoding/GBK/EUC-CN.html b/third_party/WebKit/LayoutTests/fast/encoding/GBK/EUC-CN.html deleted file mode 100644 index cba92cc..0000000 --- a/third_party/WebKit/LayoutTests/fast/encoding/GBK/EUC-CN.html +++ /dev/null
@@ -1,10 +0,0 @@ -<head> - <meta content="text/html; charset=EUC-CN" http-equiv="Content-Type"/> -</head> -<script> -if (window.testRunner) - testRunner.dumpAsText(); -</script> -<p>The following two lines should look identically:</p> -<p>Ò»¹P€éF</p> -<p>一筆€镕</p>
diff --git a/third_party/WebKit/LayoutTests/fast/encoding/char-decoding.html b/third_party/WebKit/LayoutTests/fast/encoding/char-decoding.html index 0d12d2c..920ef94 100644 --- a/third_party/WebKit/LayoutTests/fast/encoding/char-decoding.html +++ b/third_party/WebKit/LayoutTests/fast/encoding/char-decoding.html
@@ -18,7 +18,6 @@ testDecode('gbk', '%A3%A0', 'U+3000'); testDecode('x-gbk', '%A3%A0', 'U+3000'); testDecode('gb18030', '%A3%A0', 'U+3000'); -testDecode('EUC-CN', '%A3%A0', 'U+3000'); // Align GBK with GB18030 testDecode('gbk', '%A8%BF', 'U+01F9');
diff --git a/third_party/WebKit/LayoutTests/fast/encoding/char-encoding.html b/third_party/WebKit/LayoutTests/fast/encoding/char-encoding.html index 34b48ffd..6ad1a1ca 100644 --- a/third_party/WebKit/LayoutTests/fast/encoding/char-encoding.html +++ b/third_party/WebKit/LayoutTests/fast/encoding/char-encoding.html
@@ -17,12 +17,10 @@ testEncode('GBK', 'U+00A5', '%A3%A4'); testEncode('gb2312', 'U+00A5', '%A3%A4'); testEncode('GB_2312-80', 'U+00A5', '%A3%A4'); -testEncode('EUC-CN', 'U+00A5', '%A3%A4'); //Euro symbol in gbk testEncode('GBK', 'U+20AC', '%80'); testEncode('gb2312', 'U+20AC', '%80'); testEncode('GB_2312-80', 'U+20AC', '%80'); -testEncode('EUC-CN', 'U+20AC', '%80'); //Align GBK with gb18030 // See https://www.w3.org/Bugs/Public/show_bug.cgi?id=28740#c3 testEncode('GBK', 'U+01F9', '%A8%BF');
diff --git a/third_party/WebKit/LayoutTests/fast/encoding/supported-encodings-expected.txt b/third_party/WebKit/LayoutTests/fast/encoding/supported-encodings-expected.txt index cea10f6..d810d00 100644 --- a/third_party/WebKit/LayoutTests/fast/encoding/supported-encodings-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/encoding/supported-encodings-expected.txt
@@ -55,7 +55,6 @@ PASS Supported label: koi8_r PASS Supported label: windows-31j PASS Supported label: iso_8859-4:1988 -FAIL Supported label: gb2312-1980 assert_true: gb2312-1980 should only be supported if it is specified expected true got false PASS Supported label: iso88597 PASS Supported label: shift-jis PASS Supported label: iso-ir-148 @@ -67,7 +66,6 @@ PASS Supported label: iso-2022-cn FAIL Supported label: windows-1257-html assert_true: windows-1257-html should only be supported if it is specified expected true got false PASS Supported label: windows-1257 -PASS Supported label: windows-1252 PASS Supported label: arabic PASS Supported label: windows-1251 PASS Supported label: csisolatincyrillic @@ -80,7 +78,7 @@ PASS Supported label: x-mac-ukrainian PASS Supported label: logical PASS Supported label: koi8-r -FAIL Supported label: windows-54936 assert_true: windows-54936 should only be supported if it is specified expected true got false +PASS Supported label: windows-1252 PASS Supported label: csiso2022jp PASS Supported label: elot_928 PASS Supported label: koi8 @@ -116,8 +114,8 @@ FAIL Supported label: windows-1258-html assert_true: windows-1258-html should only be supported if it is specified expected true got false PASS Supported label: iso_8859-1 PASS Supported label: x-cp1254 +PASS Supported label: iso8859-2 PASS Supported label: iso8859-11 -FAIL Supported label: windows-936 assert_true: windows-936 should only be supported if it is specified expected true got false PASS Supported label: big5 FAIL Supported label: iso-8859-4-html assert_true: iso-8859-4-html should only be supported if it is specified expected true got false PASS Supported label: iso-8859-1 @@ -126,7 +124,6 @@ PASS Supported label: csisolatin2 PASS Supported label: iso-8859-7 PASS Supported label: iso-8859-8-i -FAIL Supported label: cp936 assert_true: cp936 should only be supported if it is specified expected true got false PASS Supported label: iso88591 PASS Supported label: windows-1258 PASS Supported label: iso_8859-8:1988 @@ -138,7 +135,6 @@ FAIL Supported label: koi8-r-html assert_true: koi8-r-html should only be supported if it is specified expected true got false PASS Supported label: iso-8859-4 FAIL Supported label: windows-1252-html assert_true: windows-1252-html should only be supported if it is specified expected true got false -FAIL Supported label: ibm-1392 assert_true: ibm-1392 should only be supported if it is specified expected true got false PASS Supported label: iso-ir-144 PASS Supported label: iso-ir-109 PASS Supported label: csiso88596i @@ -147,7 +143,6 @@ PASS Supported label: iso885914 PASS Supported label: l6 PASS Supported label: iso_8859-5 -FAIL Supported label: ms936 assert_true: ms936 should only be supported if it is specified expected true got false PASS Supported label: gbk PASS Supported label: l5 PASS Supported label: iso-ir-100 @@ -178,7 +173,6 @@ PASS Supported label: iso-2022-jp PASS Supported label: l9 PASS Supported label: iso-8859-5 -PASS Supported label: cseuckr PASS Supported label: iso-ir-101 PASS Supported label: iso-ir-127 PASS Supported label: iso8859-4 @@ -203,7 +197,7 @@ PASS Supported label: iso885915 PASS Supported label: cp1252 PASS Supported label: iso8859-6 -PASS Supported label: iso8859-2 +PASS Supported label: cseuckr PASS Supported label: x-cp1253 PASS Supported label: iso88593 PASS Supported label: csisolatin3 @@ -263,7 +257,6 @@ PASS Supported label: cp1257 PASS Supported label: x-mac-cyrillic FAIL Supported label: windows-1250-html assert_true: windows-1250-html should only be supported if it is specified expected true got false -FAIL Supported label: euc-cn assert_true: euc-cn should only be supported if it is specified expected true got false PASS Supported label: iso8859-1 PASS Supported label: gb18030 Harness: the test ran to completion.
diff --git a/third_party/WebKit/LayoutTests/fast/events/constructors/message-event-constructor-expected.txt b/third_party/WebKit/LayoutTests/fast/events/constructors/message-event-constructor-expected.txt index d73a00d..50c4f60 100644 --- a/third_party/WebKit/LayoutTests/fast/events/constructors/message-event-constructor-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/events/constructors/message-event-constructor-expected.txt
@@ -9,7 +9,7 @@ PASS new MessageEvent('eventType').origin is "" PASS new MessageEvent('eventType').lastEventId is "" PASS new MessageEvent('eventType').source is null -PASS new MessageEvent('eventType').ports is null +PASS new MessageEvent('eventType').ports is [] PASS new MessageEvent('eventType', { bubbles: false }).bubbles is false PASS new MessageEvent('eventType', { bubbles: true }).bubbles is true PASS new MessageEvent('eventType', { cancelable: false }).cancelable is false @@ -81,8 +81,7 @@ PASS new MessageEvent('eventType', { ports: [channel.port1, channel.port2, channel2.port1] }).ports[1] is channel.port2 PASS new MessageEvent('eventType', { ports: [channel.port1, channel.port2, channel2.port1] }).ports[2] is channel2.port1 PASS new MessageEvent('eventType', { ports: [] }).ports is [] -PASS new MessageEvent('eventType', { ports: undefined }).ports is null -PASS new MessageEvent('eventType', { ports: null }).ports is null +PASS new MessageEvent('eventType', { ports: undefined }).ports is [] PASS new MessageEvent('eventType', { ports: [1, 2, 3] }).ports[2] threw exception TypeError: Failed to construct 'MessageEvent': Failed to convert value to 'MessagePort'.. PASS new MessageEvent('eventType', { ports: test_object }).ports threw exception TypeError: Failed to construct 'MessageEvent': Iterator getter is not callable.. PASS new MessageEvent('eventType', { ports: document }).ports threw exception TypeError: Failed to construct 'MessageEvent': Iterator getter is not callable.. @@ -95,6 +94,7 @@ PASS new MessageEvent('eventType', { ports: NaN }).ports threw exception TypeError: Failed to construct 'MessageEvent': The provided value cannot be converted to a sequence.. PASS new MessageEvent('eventType', { get ports() { return 123; } }).ports threw exception TypeError: Failed to construct 'MessageEvent': The provided value cannot be converted to a sequence.. PASS new MessageEvent('eventType', { get ports() { throw 'MessageEvent Error'; } }) threw exception MessageEvent Error. +PASS new MessageEvent('eventType', { ports: null }).ports threw exception TypeError: Failed to construct 'MessageEvent': The provided value cannot be converted to a sequence.. PASS new MessageEvent('eventType', { ports: {valueOf: function () { return [channel.port1, channel.port2, channel.port2]; } } }).ports[0] threw exception TypeError: Failed to construct 'MessageEvent': Iterator getter is not callable.. PASS new MessageEvent('eventType', { bubbles: true, cancelable: true, data: test_object, origin: 'wonderful', lastEventId: 'excellent', source: window, ports: {length: 3, 0: channel.port1, 1: channel.port2, 2: channel2.port1} }).ports[2] threw exception TypeError: Failed to construct 'MessageEvent': Iterator getter is not callable.. PASS new MessageEvent('eventType', { bubbles: true, cancelable: true, data: test_object, origin: 'wonderful', lastEventId: 'excellent', source: window, ports: [channel.port1, channel.port2, channel2.port1] }).bubbles is true
diff --git a/third_party/WebKit/LayoutTests/fast/events/constructors/message-event-constructor.html b/third_party/WebKit/LayoutTests/fast/events/constructors/message-event-constructor.html index 9061746d..6624e25 100644 --- a/third_party/WebKit/LayoutTests/fast/events/constructors/message-event-constructor.html +++ b/third_party/WebKit/LayoutTests/fast/events/constructors/message-event-constructor.html
@@ -17,7 +17,7 @@ shouldBeEqualToString("new MessageEvent('eventType').origin", ""); shouldBeEqualToString("new MessageEvent('eventType').lastEventId", ""); shouldBe("new MessageEvent('eventType').source", "null"); -shouldBe("new MessageEvent('eventType').ports", "null"); +shouldBe("new MessageEvent('eventType').ports", "[]"); // bubbles is passed. shouldBe("new MessageEvent('eventType', { bubbles: false }).bubbles", "false"); @@ -101,8 +101,7 @@ shouldBe("new MessageEvent('eventType', { ports: [channel.port1, channel.port2, channel2.port1] }).ports[1]", "channel.port2"); shouldBe("new MessageEvent('eventType', { ports: [channel.port1, channel.port2, channel2.port1] }).ports[2]", "channel2.port1"); shouldBe("new MessageEvent('eventType', { ports: [] }).ports", "[]"); -shouldBe("new MessageEvent('eventType', { ports: undefined }).ports", "null"); -shouldBe("new MessageEvent('eventType', { ports: null }).ports", "null"); +shouldBe("new MessageEvent('eventType', { ports: undefined }).ports", "[]"); // Invalid message ports. shouldThrow("new MessageEvent('eventType', { ports: [1, 2, 3] }).ports[2]"); @@ -117,6 +116,7 @@ shouldThrow("new MessageEvent('eventType', { ports: NaN }).ports"); shouldThrow("new MessageEvent('eventType', { get ports() { return 123; } }).ports"); shouldThrow("new MessageEvent('eventType', { get ports() { throw 'MessageEvent Error'; } })"); +shouldThrow("new MessageEvent('eventType', { ports: null }).ports"); // Note that valueOf() is not called, when the left hand side is evaluated. shouldThrow("new MessageEvent('eventType', { ports: {valueOf: function () { return [channel.port1, channel.port2, channel.port2]; } } }).ports[0]"); shouldThrow("new MessageEvent('eventType', { bubbles: true, cancelable: true, data: test_object, origin: 'wonderful', lastEventId: 'excellent', source: window, ports: {length: 3, 0: channel.port1, 1: channel.port2, 2: channel2.port1} }).ports[2]");
diff --git a/third_party/WebKit/LayoutTests/fast/mediastream/MediaStreamTrack-expected.txt b/third_party/WebKit/LayoutTests/fast/mediastream/MediaStreamTrack-expected.txt deleted file mode 100644 index decd735c..0000000 --- a/third_party/WebKit/LayoutTests/fast/mediastream/MediaStreamTrack-expected.txt +++ /dev/null
@@ -1,19 +0,0 @@ -Tests MediaStreamTrack callbacks. - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - - -PASS getUserMedia succeeded. -PASS track.readyState is "live" -PASS Track onmute callback succeeded. -PASS track.readyState is "live" -PASS track.muted is true -PASS Track onunmute callback succeeded. -PASS track.readyState is "live" -PASS track.muted is false -PASS Track onended callback succeeded. -PASS track.readyState is "ended" -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/WebKit/LayoutTests/fast/mediastream/MediaStreamTrack-observer-iterate-no-crash-expected.txt b/third_party/WebKit/LayoutTests/fast/mediastream/MediaStreamTrack-observer-iterate-no-crash-expected.txt deleted file mode 100644 index d7c8c995..0000000 --- a/third_party/WebKit/LayoutTests/fast/mediastream/MediaStreamTrack-observer-iterate-no-crash-expected.txt +++ /dev/null
@@ -1,10 +0,0 @@ -Verify that MediaStreamTracks created while dispatching MediaStreamSource events do not crash. - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - - -PASS Test did not crash. -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/WebKit/LayoutTests/fast/mediastream/MediaStreamTrack-observer-iterate-no-crash.html b/third_party/WebKit/LayoutTests/fast/mediastream/MediaStreamTrack-observer-iterate-no-crash.html index f91618b..84d6708f 100644 --- a/third_party/WebKit/LayoutTests/fast/mediastream/MediaStreamTrack-observer-iterate-no-crash.html +++ b/third_party/WebKit/LayoutTests/fast/mediastream/MediaStreamTrack-observer-iterate-no-crash.html
@@ -1,41 +1,30 @@ -<!DOCTYPE html> -<html> -<head> -<script src="../../resources/js-test.js"></script> -</head> -<body> +<!DOCTYPE HTML> +<title>Verify that MediaStreamTracks created while dispatching MediaStreamSource + events do not crash.</title> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> <script> -description("Verify that MediaStreamTracks created while dispatching MediaStreamSource events do not crash."); + async_test(test => { + navigator.mediaDevices.getUserMedia({audio:true, video: true}) + .then(test.step_func(stream => { + // |track| may be any of the audio or video tracks. + var track = stream.getTracks()[0]; + assert_equals(track.readyState, "live"); + track.onended = test.unreached_func("ended event should not be fired."); + track.onmute = test.step_func(() => { + assert_equals(track.readyState, "live"); + track.clone(); + track.stop(); + assert_equals(track.readyState, "ended"); + track.clone(); -if (window.testRunner) { - testRunner.dumpAsText(); - testRunner.waitUntilDone(); -} - -var jsTestIsAsync = true; - -function getUserMedia(constraints, callback) { - try { - navigator.webkitGetUserMedia(constraints, callback, function () { }); - } catch (e) { - testFailed("Unexpected exception: " + e.toString()); - finishJSTest(); - } -} - -getUserMedia({audio: true,video: true}, function (stream) { - var track = stream.getTracks()[0]; - track.onmute = function () { - track.clone(); - track.stop(); - }; - track.onended = function () { - track.clone(undefined); - testPassed("Test did not crash."); - finishJSTest(); - }; - track.enabled = false; -}); + // Use a timeout to detect a misfire of the ended event. + test.step_timeout(test.step_func_done(() => { + assert_equals(track.readyState, "ended"); + })); + }); + track.enabled = false; + })) + .catch(test.unreached_func("getUserMedia failed")); + }); </script> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/fast/mediastream/MediaStreamTrack.html b/third_party/WebKit/LayoutTests/fast/mediastream/MediaStreamTrack.html index 28a4e1a4..7dd11ad 100644 --- a/third_party/WebKit/LayoutTests/fast/mediastream/MediaStreamTrack.html +++ b/third_party/WebKit/LayoutTests/fast/mediastream/MediaStreamTrack.html
@@ -1,78 +1,37 @@ -<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> -<html> -<head> -<script src="../../resources/js-test.js"></script> -</head> -<body> -<p id="description"></p> -<div id="console"></div> +<!DOCTYPE HTML> +<title>Tests MediaStreamTrack callbacks.</title> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> <script> -description("Tests MediaStreamTrack callbacks."); + async_test(test => { + navigator.mediaDevices.getUserMedia({audio:true, video: true}) + .then(test.step_func(stream => { + // |track| may be any of the audio or video tracks. + var track = stream.getTracks()[0]; + assert_equals(track.readyState, "live"); -// Note that the below behaviour doesn't reflect how it works outside of LayoutTests. -// The underlying mock is modified to trigger the events when certain functions are called. -// This modified behaviour allows us to test the MediaStreamTrack class properly. + track.onmute = test.step_func(() => { + assert_equals(track.readyState, "live"); + assert_true(track.muted); -var track; + track.onunmute = test.step_func(() => { + assert_equals(track.readyState, "live"); + assert_false(track.muted); + track.stop(); + assert_equals(track.readyState, "ended"); -function error() { - testFailed('Stream generation failed.'); - finishJSTest(); -} + // Use a timeout to detect a misfire of the ended event. + test.step_timeout(test.step_func_done(() => { + assert_equals(track.readyState, "ended"); + })); + }); -function getUserMedia(constraints, callback) { - try { - navigator.webkitGetUserMedia(constraints, callback, error); - } catch (e) { - testFailed('webkitGetUserMedia threw exception :' + e); - finishJSTest(); - } -} + track.enabled = true; + }); -function onTrackEnded() { - testPassed('Track onended callback succeeded.'); - - shouldBeEqualToString('track.readyState', 'ended'); - - finishJSTest(); -} - -function onTrackUnmute() { - testPassed('Track onunmute callback succeeded.'); - - shouldBeEqualToString('track.readyState', 'live'); - shouldBeFalse('track.muted'); - - track.stop(); -} - -function onTrackMute() { - testPassed('Track onmute callback succeeded.'); - - shouldBeEqualToString('track.readyState', 'live'); - shouldBeTrue('track.muted'); - - track.enabled = true; -} - -function gotStream(stream) { - testPassed('getUserMedia succeeded.'); - - track = stream.getVideoTracks()[0]; - - shouldBeEqualToString('track.readyState', 'live'); - - track.onunmute = onTrackUnmute; - track.onmute = onTrackMute; - track.onended = onTrackEnded; - - track.enabled = false; -} - -getUserMedia({audio:true, video:true}, gotStream); - -window.jsTestIsAsync = true; -window.successfullyParsed = true; + track.onended = test.unreached_func("ended event should not be fired."); + track.enabled = false; + })) + .catch(test.unreached_func("getUserMedia failed")); + }); </script> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/cookies-protocol-test-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/cookies-protocol-test-expected.txt index b09bf5d0..35d2458 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/cookies-protocol-test-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/cookies-protocol-test-expected.txt
@@ -7,87 +7,39 @@ Logging Cookies Success: true Num of cookies 1 - Cookie: - Domain: 127.0.0.1 - Name: foo - Value: bar1 - Path: / - HttpOnly: false - Secure: false - Session: true +name: foo, value: bar1, domain: 127.0.0.1, path: /, session Running test: simpleCookieChange Setting Cookie Logging Cookies Success: true Num of cookies 1 - Cookie: - Domain: 127.0.0.1 - Name: foo - Value: second bar2 - Path: / - HttpOnly: false - Secure: false - Session: true +name: foo, value: second bar2, domain: 127.0.0.1, path: /, session Running test: anotherSimpleCookieAdd Setting Cookie Logging Cookies Success: true Num of cookies 2 - Cookie: - Domain: 127.0.0.1 - Name: foo2 - Value: bar1 - Path: / - HttpOnly: false - Secure: false - Session: true - Cookie: - Domain: 127.0.0.1 - Name: foo - Value: second bar2 - Path: / - HttpOnly: false - Secure: false - Session: true +name: foo, value: second bar2, domain: 127.0.0.1, path: /, session +name: foo2, value: bar1, domain: 127.0.0.1, path: /, session Running test: simpleCookieDelete Deleting Cookie Logging Cookies Num of cookies 1 - Cookie: - Domain: 127.0.0.1 - Name: foo2 - Value: bar1 - Path: / - HttpOnly: false - Secure: false - Session: true +name: foo2, value: bar1, domain: 127.0.0.1, path: /, session Running test: deleteAllCookies -Removing All Cookies -Logging Cookies -Num of cookies 0 Running test: sessionCookieAdd Setting Cookie Logging Cookies Success: true Num of cookies 1 - Cookie: - Domain: 127.0.0.1 - Name: foo - Value: bar4 - Path: / - HttpOnly: false - Secure: false - Session: true +name: foo, value: bar4, domain: 127.0.0.1, path: /, session Running test: deleteAllCookies -Removing All Cookies -Logging Cookies -Num of cookies 0 Running test: nonSessionCookieZeroAdd Setting Cookie @@ -96,34 +48,24 @@ Num of cookies 0 Running test: deleteAllCookies -Removing All Cookies -Logging Cookies -Num of cookies 0 Running test: nonSessionCookieAdd Setting Cookie Logging Cookies Success: true Num of cookies 1 - Cookie: - Domain: 127.0.0.1 - Name: foo - Value: bar6 - Path: / - HttpOnly: false - Secure: false - Session: false +name: foo, value: bar6, domain: 127.0.0.1, path: / Running test: deleteAllCookies -Removing All Cookies -Logging Cookies -Num of cookies 0 Running test: differentOriginCookieAdd Setting Cookie Logging Cookies Success: true -Num of cookies 0 +Num of cookies 1 +name: foo, value: bar7, domain: example.com, path: /, session + +Running test: deleteAllCookies Running test: invalidCookieAddDomain Setting Cookie @@ -131,6 +73,8 @@ Success: false Num of cookies 0 +Running test: deleteAllCookies + Running test: invalidCookieAddName Setting Cookie Logging Cookies @@ -138,9 +82,6 @@ Num of cookies 0 Running test: deleteAllCookies -Removing All Cookies -Logging Cookies -Num of cookies 0 Running test: secureCookieAdd Setting Cookie @@ -149,59 +90,45 @@ Num of cookies 0 Running test: deleteAllCookies -Removing All Cookies -Logging Cookies -Num of cookies 0 Running test: cookieAddHttpOnly Setting Cookie Logging Cookies Success: true Num of cookies 1 - Cookie: - Domain: 127.0.0.1 - Name: foo - Value: bar - Path: / - HttpOnly: true - Secure: false - Session: true +name: foo, value: bar, domain: 127.0.0.1, path: /, httpOnly, session Running test: deleteAllCookies -Removing All Cookies -Logging Cookies -Num of cookies 0 Running test: cookieAddSameSiteLax Setting Cookie Logging Cookies Success: true Num of cookies 1 - Cookie: - Domain: 127.0.0.1 - Name: foo - Value: bar - Path: / - HttpOnly: false - Secure: false - Session: true +name: foo, value: bar, domain: 127.0.0.1, path: /, session, Lax Running test: deleteAllCookies -Removing All Cookies -Logging Cookies -Num of cookies 0 Running test: cookieAddSameSiteLax Setting Cookie Logging Cookies Success: true Num of cookies 1 - Cookie: - Domain: 127.0.0.1 - Name: foo - Value: bar - Path: / - HttpOnly: false - Secure: false - Session: true +name: foo, value: bar, domain: 127.0.0.1, path: /, session, Strict + +Running test: deleteAllCookies + +Running test: setCookiesBasic +Adding multiple cookies +Logging Cookies +Num of cookies 7 +name: foo1, value: bar1, domain: 127.0.0.1, path: /, session +name: foo2, value: bar2, domain: 127.0.0.1, path: /, httpOnly, session +name: foo3, value: bar3, domain: 127.0.0.1, path: /, secure, session +name: foo4, value: bar4, domain: 127.0.0.1, path: /, session, Lax +name: foo5, value: bar5, domain: 127.0.0.1, path: /, session +name: foo6, value: bar6, domain: .chromium.org, path: /path +name: foo7, value: bar7, domain: www.chromium.org, path: /, secure + +Running test: deleteAllCookies
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/cookies-protocol-test.js b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/cookies-protocol-test.js index cf779a4..ef8e74d 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/cookies-protocol-test.js +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/cookies-protocol-test.js
@@ -6,17 +6,20 @@ testRunner.log('Logging Cookies'); if (success !== undefined) testRunner.log('Success: ' + success); - var data = (await dp.Network.getCookies()).result; + var data = (await dp.Network.getAllCookies()).result; testRunner.log('Num of cookies ' + data.cookies.length); + data.cookies.sort((a, b) => a.name.localeCompare(b.name)); for (var cookie of data.cookies) { - testRunner.log(' Cookie: '); - testRunner.log(' Domain: ' + cookie.domain); - testRunner.log(' Name: ' + cookie.name); - testRunner.log(' Value: ' + cookie.value); - testRunner.log(' Path: ' + cookie.path); - testRunner.log(' HttpOnly: ' + cookie.httpOnly); - testRunner.log(' Secure: ' + cookie.secure); - testRunner.log(' Session: ' + cookie.session); + var suffix = '' + if (cookie.secure) + suffix += `, secure`; + if (cookie.httpOnly) + suffix += `, httpOnly`; + if (cookie.session) + suffix += `, session`; + if (cookie.sameSite) + suffix += `, ${cookie.sameSite}`; + testRunner.log(`name: ${cookie.name}, value: ${cookie.value}, domain: ${cookie.domain}, path: ${cookie.path}${suffix}`); } } @@ -32,16 +35,20 @@ await logCookies(); } + async function setCookies(cookies) { + testRunner.log('Adding multiple cookies'); + var response = await dp.Network.setCookies({cookies}); + await logCookies(); + } + async function deleteAllCookies() { - testRunner.log('Removing All Cookies'); - var data = (await dp.Network.getCookies()).result; + var data = (await dp.Network.getAllCookies()).result; var promises = []; for (var cookie of data.cookies) { var url = 'http://' + cookie.domain + '/' + cookie.path; promises.push(dp.Network.deleteCookie({url, cookieName: cookie.name})); } await Promise.all(promises); - await logCookies(); } testRunner.log('Test started'); @@ -68,19 +75,19 @@ deleteAllCookies, async function sessionCookieAdd() { - await setCookie({url: 'http://127.0.0.1', name: 'foo', value: 'bar4', expirationDate: undefined}); + await setCookie({url: 'http://127.0.0.1', name: 'foo', value: 'bar4', expires: undefined}); }, deleteAllCookies, async function nonSessionCookieZeroAdd() { - await setCookie({url: 'http://127.0.0.1', name: 'foo', value: 'bar5', expirationDate: 0}); + await setCookie({url: 'http://127.0.0.1', name: 'foo', value: 'bar5', expires: 0}); }, deleteAllCookies, async function nonSessionCookieAdd() { - await setCookie({url: 'http://127.0.0.1', name: 'foo', value: 'bar6', expirationDate: new Date().getTime() + 1000000}); + await setCookie({url: 'http://127.0.0.1', name: 'foo', value: 'bar6', expires: Date.now() + 1000000}); }, deleteAllCookies, @@ -90,10 +97,14 @@ await setCookie({url: 'http://example.com', name: 'foo', value: 'bar7'}); }, + deleteAllCookies, + async function invalidCookieAddDomain() { await setCookie({url: 'ht2tp://127.0.0.1', name: 'foo', value: 'bar8'}); }, + deleteAllCookies, + async function invalidCookieAddName() { await setCookie({url: 'http://127.0.0.1', name: 'foo\0\r\na', value: 'bar9'}); }, @@ -121,6 +132,21 @@ async function cookieAddSameSiteLax() { await setCookie({url: 'http://127.0.0.1', sameSite: 'Strict', name: 'foo', value: 'bar'}); - } + }, + + deleteAllCookies, + + async function setCookiesBasic() { + await setCookies([{name: 'foo1', value: 'bar1', domain: '127.0.0.1', path: '/', }, + {name: 'foo2', value: 'bar2', domain: '127.0.0.1', path: '/', httpOnly: true }, + {name: 'foo3', value: 'bar3', domain: '127.0.0.1', path: '/', secure: true }, + {name: 'foo4', value: 'bar4', domain: '127.0.0.1', path: '/', sameSite: 'Lax' }, + {name: 'foo5', value: 'bar5', domain: '127.0.0.1', path: '/' }, + {name: 'foo6', value: 'bar6', domain: '.chromium.org', path: '/path', expires: Date.now() + 1000 }, + {name: 'foo7', value: 'bar7', url: 'https://www.chromium.org/foo', expires: Date.now() + 1000 }]); + }, + + deleteAllCookies, + ]); })
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-unit/preprocess-top-level-awaits-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector-unit/preprocess-top-level-awaits-expected.txt index 08d17d8..cec1d3e 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-unit/preprocess-top-level-awaits-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-unit/preprocess-top-level-awaits-expected.txt
@@ -1,4 +1,3 @@ -CONSOLE ERROR: line 497: Walk order not defined for ArrayPattern This tests preprocessTopLevelAwaitExpressions. -------------- 0
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/script-tag-null-char-expected.txt b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/script-tag-null-char-expected.txt index 297e444..e0efed8d 100644 --- a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/script-tag-null-char-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/script-tag-null-char-expected.txt
@@ -1,2 +1,2 @@ -CONSOLE ERROR: line 4: The XSS Auditor refused to execute a script in 'http://localhost:8000/security/xssAuditor/resources/echo-intertag.pl?q=%3Cscript%3Eal%00ert(0)%3C/script%3E' because its source code was found within the request. The server sent an 'X-XSS-Protection' header requesting this behavior. +CONSOLE ERROR: line 4: The XSS Auditor refused to execute a script in 'http://localhost:8000/security/xssAuditor/resources/echo-intertag.pl?q=%3Cp%3E%00%00%00%00%00%00%00%3Cscript%3Ealert(%27%00%27)%3C/script%3E' because its source code was found within the request. The server sent an 'X-XSS-Protection' header requesting this behavior.
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/script-tag-null-char.html b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/script-tag-null-char.html index 394d859..c7c3d61 100644 --- a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/script-tag-null-char.html +++ b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/script-tag-null-char.html
@@ -9,7 +9,7 @@ </script> </head> <body> -<iframe src="http://localhost:8000/security/xssAuditor/resources/echo-intertag.pl?q=<script>al%00ert(0)</script>"> +<iframe src="http://localhost:8000/security/xssAuditor/resources/echo-intertag.pl?q=<p>%00%00%00%00%00%00%00<script>alert('%00')</script>"> </iframe> </body> </html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-and-redirects-async-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-and-redirects-async-expected.txt deleted file mode 100644 index 9f5f77c..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-and-redirects-async-expected.txt +++ /dev/null
@@ -1,30 +0,0 @@ -CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/resources/redirect-cors.php?url=http://localhost:8000/xmlhttprequest/resources/access-control-basic-allow-star.cgi: Redirect from 'http://localhost:8000/xmlhttprequest/resources/redirect-cors.php?url=http://localhost:8000/xmlhttprequest/resources/access-control-basic-allow-star.cgi' to 'http://localhost:8000/xmlhttprequest/resources/access-control-basic-allow-star.cgi' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access. -CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/resources/redirect-cors.php?url=http://username:password@localhost:8000/xmlhttprequest/resources/access-control-basic-allow-star.cgi&%20%20access-control-allow-origin=http://127.0.0.1:8000: Redirect from 'http://localhost:8000/xmlhttprequest/resources/redirect-cors.php?url=http://username:password@localhost:8000/xmlhttprequest/resources/access-control-basic-allow-star.cgi&%20%20access-control-allow-origin=http://127.0.0.1:8000' has been blocked by CORS policy: Redirect location 'http://username:password@localhost:8000/xmlhttprequest/resources/access-control-basic-allow-star.cgi' contains a username and password, which is disallowed for cross-origin requests. -CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/resources/redirect-cors.php?url=foo://bar.cgi&%20%20access-control-allow-origin=http://127.0.0.1:8000: Redirect from 'http://localhost:8000/xmlhttprequest/resources/redirect-cors.php?url=foo://bar.cgi&%20%20access-control-allow-origin=http://127.0.0.1:8000' has been blocked by CORS policy: Redirect location 'foo://bar.cgi' has a disallowed scheme for cross-origin requests. -CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/resources/redirect-cors.php?redirect-preflight=true&%20%20url=http://localhost:8000/xmlhttprequest/resources/access-control-basic-allow-star.cgi&%20%20access-control-allow-origin=*: Response for preflight is invalid (redirect) -CONSOLE ERROR: Failed to load http://localhost:8000/xmlhttprequest/resources/access-control-basic-allow-star.cgi: Request header field x-webkit is not allowed by Access-Control-Allow-Headers in preflight response. -Tests that asynchronous XMLHttpRequests handle redirects according to the CORS standard. - -Testing http://localhost:8000/xmlhttprequest/resources/redirect-cors.php?url=http://localhost:8000/xmlhttprequest/resources/access-control-basic-allow-star.cgi without credentials -Expecting success: false -PASS: 0 -Testing http://localhost:8000/xmlhttprequest/resources/redirect-cors.php?url=http://localhost:8000/xmlhttprequest/resources/access-control-basic-allow-star.cgi& access-control-allow-origin=http://127.0.0.1:8000 without credentials -Expecting success: true -PASS: PASS: Cross-domain access allowed. - -Testing http://localhost:8000/xmlhttprequest/resources/redirect-cors.php?url=http://username:password@localhost:8000/xmlhttprequest/resources/access-control-basic-allow-star.cgi& access-control-allow-origin=http://127.0.0.1:8000 without credentials -Expecting success: false -PASS: 0 -Testing http://localhost:8000/xmlhttprequest/resources/redirect-cors.php?url=foo://bar.cgi& access-control-allow-origin=http://127.0.0.1:8000 without credentials -Expecting success: false -PASS: 0 -Testing http://localhost:8000/xmlhttprequest/resources/redirect-cors.php?redirect-preflight=true& url=http://localhost:8000/xmlhttprequest/resources/access-control-basic-allow-star.cgi& access-control-allow-origin=* without credentials -Expecting success: false -PASS: 0 -Testing http://localhost:8000/xmlhttprequest/resources/redirect-cors.php?redirect-preflight=false& url=http://localhost:8000/xmlhttprequest/resources/access-control-basic-allow-star.cgi& access-control-allow-origin=*& access-control-allow-headers=x-webkit without credentials -Expecting success: false -PASS: 0 -Testing resources/redirect-cors.php?url=http://127.0.0.1:8000/xmlhttprequest/resources/get.txt without credentials -Expecting success: true -PASS: PASS -
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-and-redirects-async.html b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-and-redirects-async.html deleted file mode 100644 index be73388..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-and-redirects-async.html +++ /dev/null
@@ -1,97 +0,0 @@ -<p>Tests that asynchronous XMLHttpRequests handle redirects according to the CORS standard.</p> - -<pre id="console"></pre> -<script> -if (window.testRunner) { - testRunner.dumpAsText(); - testRunner.waitUntilDone(); -} - -function log(message) -{ - document.getElementById('console').appendChild(document.createTextNode(message + '\n')); -} - -function runTestAsync(url, credentials, addCustomHeader, expectSuccess) { - log("Testing " + url + (credentials ? " with " : " without ") + "credentials"); - log("Expecting success: " + expectSuccess); - - xhr = new XMLHttpRequest(); - xhr.withCredentials = credentials; - xhr.open("GET", url, true); - if (addCustomHeader) - xhr.setRequestHeader("x-webkit", "foo"); - - xhr.onload = function() { - log((expectSuccess ? "PASS" : "FAIL") + ": " + xhr.responseText); - nextTest(); - } - xhr.onerror = function() { - log((expectSuccess ? "FAIL" : "PASS") + ": " + xhr.status); - nextTest(); - } - xhr.send(null); -} - -var withoutCredentials = false; -var withCredentials = true; -var noCustomHeader = false; -var addCustomHeader = true; -var succeeds = true; -var fails = false; - -var tests = [ -// 1) Test simple cross origin requests that receive redirects. - -// Receives a redirect response without CORS headers. The redirect response fails the access check. -["http://localhost:8000/xmlhttprequest/resources/redirect-cors.php?url=http://localhost:8000/xmlhttprequest/resources/access-control-basic-allow-star.cgi", - withoutCredentials, noCustomHeader, fails], - -// Receives a redirect response with CORS headers. The redirect response passes the access check and the resource response -// passes the access check. -["http://localhost:8000/xmlhttprequest/resources/redirect-cors.php?url=http://localhost:8000/xmlhttprequest/resources/access-control-basic-allow-star.cgi&\ - access-control-allow-origin=http://127.0.0.1:8000", - withoutCredentials, noCustomHeader, succeeds], - -// Receives a redirect response with a URL containing the userinfo production. -["http://localhost:8000/xmlhttprequest/resources/redirect-cors.php?url=http://username:password@localhost:8000/xmlhttprequest/resources/access-control-basic-allow-star.cgi&\ - access-control-allow-origin=http://127.0.0.1:8000", - withoutCredentials, noCustomHeader, fails], - -// Receives a redirect response with a URL with an unsupported scheme. -["http://localhost:8000/xmlhttprequest/resources/redirect-cors.php?url=foo://bar.cgi&\ - access-control-allow-origin=http://127.0.0.1:8000", - withoutCredentials, noCustomHeader, fails], - -// 2) Test preflighted cross origin requests that receive redirects. - -// Receives a redirect response to the preflight request and fails. -["http://localhost:8000/xmlhttprequest/resources/redirect-cors.php?redirect-preflight=true&\ - url=http://localhost:8000/xmlhttprequest/resources/access-control-basic-allow-star.cgi&\ - access-control-allow-origin=*", - withoutCredentials, addCustomHeader, fails], - -// Successful preflight and receives a redirect response to the actual request and fails. -["http://localhost:8000/xmlhttprequest/resources/redirect-cors.php?redirect-preflight=false&\ - url=http://localhost:8000/xmlhttprequest/resources/access-control-basic-allow-star.cgi&\ - access-control-allow-origin=*&\ - access-control-allow-headers=x-webkit", - withoutCredentials, addCustomHeader, fails], - -// 3) Test same origin requests with a custom header that receive a same origin redirect. -["resources/redirect-cors.php?url=http://127.0.0.1:8000/xmlhttprequest/resources/get.txt", - withoutCredentials, addCustomHeader, succeeds], - -] - -var currentTest = 0; - -function nextTest() { - if (currentTest < tests.length) - runTestAsync.apply(null, tests[currentTest++]); - else if (window.testRunner) - testRunner.notifyDone(); -} - -nextTest(); -</script>
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/input/dispatchMouseEvent-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/input/dispatchMouseEvent-expected.txt index 912f9b6c..9b9ae2f 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/input/dispatchMouseEvent-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/input/dispatchMouseEvent-expected.txt
@@ -30,4 +30,11 @@ button: 2 x: 100 y: 200 +-----Event----- +type: mousewheel +button: 0 +x: 100 +y: 200 +deltaX: 50 +deltaY: 70
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/input/dispatchMouseEvent.js b/third_party/WebKit/LayoutTests/inspector-protocol/input/dispatchMouseEvent.js index 1e0d53a..328a0895 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/input/dispatchMouseEvent.js +++ b/third_party/WebKit/LayoutTests/inspector-protocol/input/dispatchMouseEvent.js
@@ -15,6 +15,10 @@ log('shiftKey'); log('x: ' + event.x); log('y: ' + event.y); + if (event.type === 'mousewheel') { + log('deltaX: ' + event.deltaX); + log('deltaY: ' + event.deltaY); + } event.preventDefault(); } @@ -22,6 +26,7 @@ window.addEventListener('mouseup', logEvent); window.addEventListener('mousemove', logEvent); window.addEventListener('contextmenu', logEvent); + window.addEventListener('mousewheel', logEvent); `); function dumpError(message) { @@ -63,6 +68,13 @@ x: 100, y: 200 })); + dumpError(await dp.Input.dispatchMouseEvent({ + type: 'mouseWheel', + x: 100, + y: 200, + deltaX: 50, + deltaY: 70 + })); testRunner.log(await session.evaluate(`window.logs.join('\\n')`)); testRunner.completeTest();
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/background-position-no-image-expected.txt b/third_party/WebKit/LayoutTests/paint/invalidation/background-position-no-image-expected.txt new file mode 100644 index 0000000..f700373f --- /dev/null +++ b/third_party/WebKit/LayoutTests/paint/invalidation/background-position-no-image-expected.txt
@@ -0,0 +1,11 @@ +{ + "layers": [ + { + "name": "LayoutView #document", + "bounds": [800, 600], + "contentsOpaque": true, + "drawsContent": true + } + ] +} +
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/background-position-no-image.html b/third_party/WebKit/LayoutTests/paint/invalidation/background-position-no-image.html new file mode 100644 index 0000000..1e64ab56 --- /dev/null +++ b/third_party/WebKit/LayoutTests/paint/invalidation/background-position-no-image.html
@@ -0,0 +1,18 @@ +<!DOCTYPE html> +<script src="resources/text-based-repaint.js"></script> +<script> + function repaintTest() { + // Changing the background position for an element without a background + // image should not trigger a repaint. + document.getElementById("container").style.backgroundPosition = "30% 30%"; + } + window.onload = runRepaintTest; +</script> +<style> + #container { + width: 100px; + height: 100px; + background-color: green; + } +</style> +<div id="container"></div>
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/compositing/composited-float-under-composited-inline-individual-expected.html b/third_party/WebKit/LayoutTests/paint/invalidation/compositing/composited-float-under-composited-inline-individual-expected.html new file mode 100644 index 0000000..2abd3f6f --- /dev/null +++ b/third_party/WebKit/LayoutTests/paint/invalidation/compositing/composited-float-under-composited-inline-individual-expected.html
@@ -0,0 +1,3 @@ +<!DOCTYPE html> +<div style="position: relative; top: 50px; left: 50px; width: 100px; height: 100px; background-color: green"></div> +
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/compositing/composited-float-under-composited-inline-individual-expected.txt b/third_party/WebKit/LayoutTests/paint/invalidation/compositing/composited-float-under-composited-inline-individual-expected.txt new file mode 100644 index 0000000..353e6353 --- /dev/null +++ b/third_party/WebKit/LayoutTests/paint/invalidation/compositing/composited-float-under-composited-inline-individual-expected.txt
@@ -0,0 +1,37 @@ +{ + "layers": [ + { + "name": "LayoutView #document", + "bounds": [800, 600], + "contentsOpaque": true, + "drawsContent": true + }, + { + "name": "LayoutInline (relative positioned) SPAN", + "position": [108, 108], + "drawsContent": true + }, + { + "name": "LayoutBlockFlow (relative positioned) (floating) DIV id='float'", + "position": [-50, -50], + "bounds": [100, 100], + "contentsOpaque": true, + "drawsContent": true, + "backgroundColor": "#008000", + "paintInvalidations": [ + { + "object": "LayoutBlockFlow (relative positioned) (floating) DIV id='float'", + "rect": [0, 0, 100, 100], + "reason": "style change" + } + ] + } + ], + "objectPaintInvalidations": [ + { + "object": "LayoutBlockFlow (relative positioned) (floating) DIV id='float'", + "reason": "style change" + } + ] +} +
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/compositing/composited-float-under-composited-inline-individual.html b/third_party/WebKit/LayoutTests/paint/invalidation/compositing/composited-float-under-composited-inline-individual.html new file mode 100644 index 0000000..04127bf --- /dev/null +++ b/third_party/WebKit/LayoutTests/paint/invalidation/compositing/composited-float-under-composited-inline-individual.html
@@ -0,0 +1,12 @@ +<!DOCTYPE html> +<span style="position: relative; top: 100px; left: 100px; will-change: translate"> + <div id="float" style="float: left; position: relative; will-change: scale; top: 50px; left: 50px; width: 100px; height: 100px; background-color: red"></div> +</span> +<script src="../resources/text-based-repaint.js"></script> +<script> +function repaintTest() { + float.style.backgroundColor = 'green'; +} +onload = runRepaintAndPixelTest; +</script> +
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/compositing/containing-block-added-individual-expected.png b/third_party/WebKit/LayoutTests/paint/invalidation/compositing/containing-block-added-individual-expected.png new file mode 100644 index 0000000..fbe3c719 --- /dev/null +++ b/third_party/WebKit/LayoutTests/paint/invalidation/compositing/containing-block-added-individual-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/compositing/containing-block-added-individual-expected.txt b/third_party/WebKit/LayoutTests/paint/invalidation/compositing/containing-block-added-individual-expected.txt new file mode 100644 index 0000000..df25721 --- /dev/null +++ b/third_party/WebKit/LayoutTests/paint/invalidation/compositing/containing-block-added-individual-expected.txt
@@ -0,0 +1,65 @@ +{ + "layers": [ + { + "name": "LayoutView #document", + "bounds": [800, 600], + "contentsOpaque": true, + "drawsContent": true, + "paintInvalidations": [ + { + "object": "LayoutBlockFlow (positioned) DIV class='fixed'", + "rect": [50, 50, 75, 75], + "reason": "subtree" + } + ] + }, + { + "name": "LayoutBlockFlow (positioned) DIV id='container'", + "position": [200, 100], + "transformOrigin": [50, 50], + "bounds": [125, 125], + "drawsContent": true, + "backgroundColor": "#0000FF", + "paintInvalidations": [ + { + "object": "LayoutBlockFlow (positioned) DIV id='container'", + "rect": [0, 0, 100, 100], + "reason": "style change" + }, + { + "object": "LayoutBlockFlow (positioned) DIV id='container'", + "rect": [0, 0, 100, 100], + "reason": "subtree" + }, + { + "object": "LayoutBlockFlow (positioned) DIV class='fixed'", + "rect": [50, 50, 75, 75], + "reason": "style change" + } + ] + } + ], + "objectPaintInvalidations": [ + { + "object": "LayoutBlockFlow (positioned) DIV class='fixed'", + "reason": "subtree" + }, + { + "object": "LayoutBlockFlow (positioned) DIV id='container'", + "reason": "subtree" + }, + { + "object": "LayoutBlockFlow (positioned) DIV class='fixed'", + "reason": "subtree" + }, + { + "object": "LayoutBlockFlow (positioned) DIV id='container'", + "reason": "style change" + }, + { + "object": "LayoutBlockFlow (positioned) DIV class='fixed'", + "reason": "style change" + } + ] +} +
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/compositing/containing-block-added-individual.html b/third_party/WebKit/LayoutTests/paint/invalidation/compositing/containing-block-added-individual.html new file mode 100644 index 0000000..dc0d942 --- /dev/null +++ b/third_party/WebKit/LayoutTests/paint/invalidation/compositing/containing-block-added-individual.html
@@ -0,0 +1,43 @@ +<!DOCTYPE html> +<html> +<head> + <style> + #container { + will-change: top; + position: absolute; + left: 200px; + top: 100px; + width: 100px; + height: 100px; + background-color: blue; + } + + .fixed { + position: fixed; + left: 50px; + top: 50px; + width: 75px; + height: 75px; + background-color: green + } + </style> + <script src="../resources/text-based-repaint.js"></script> + <script> + function repaintTest() + { + // Adding "will-change: rotate" to the container div should + // make this div become the containing block for its fixed position + // descendant. + document.getElementById("container").style.willChange = "rotate"; + } + onload = runRepaintAndPixelTest; + </script> +</head> + +<body> + <div id="container"> + <div class="fixed"></div> + </div> +</body> + +</html>
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/compositing/containing-block-removed-individual-expected.png b/third_party/WebKit/LayoutTests/paint/invalidation/compositing/containing-block-removed-individual-expected.png new file mode 100644 index 0000000..eb14be6 --- /dev/null +++ b/third_party/WebKit/LayoutTests/paint/invalidation/compositing/containing-block-removed-individual-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/compositing/containing-block-removed-individual-expected.txt b/third_party/WebKit/LayoutTests/paint/invalidation/compositing/containing-block-removed-individual-expected.txt new file mode 100644 index 0000000..73face3 --- /dev/null +++ b/third_party/WebKit/LayoutTests/paint/invalidation/compositing/containing-block-removed-individual-expected.txt
@@ -0,0 +1,66 @@ +CONSOLE MESSAGE: line 30: debug +{ + "layers": [ + { + "name": "LayoutView #document", + "bounds": [800, 600], + "contentsOpaque": true, + "drawsContent": true, + "paintInvalidations": [ + { + "object": "LayoutBlockFlow (positioned) DIV class='fixed'", + "rect": [50, 50, 75, 75], + "reason": "style change" + } + ] + }, + { + "name": "LayoutBlockFlow (positioned) DIV id='container'", + "position": [200, 100], + "bounds": [100, 100], + "contentsOpaque": true, + "drawsContent": true, + "backgroundColor": "#0000FF", + "paintInvalidations": [ + { + "object": "LayoutBlockFlow (positioned) DIV id='container'", + "rect": [0, 0, 100, 100], + "reason": "style change" + }, + { + "object": "LayoutBlockFlow (positioned) DIV id='container'", + "rect": [0, 0, 100, 100], + "reason": "subtree" + }, + { + "object": "LayoutBlockFlow (positioned) DIV class='fixed'", + "rect": [50, 50, 75, 75], + "reason": "subtree" + } + ] + } + ], + "objectPaintInvalidations": [ + { + "object": "LayoutBlockFlow (positioned) DIV class='fixed'", + "reason": "subtree" + }, + { + "object": "LayoutBlockFlow (positioned) DIV id='container'", + "reason": "subtree" + }, + { + "object": "LayoutBlockFlow (positioned) DIV class='fixed'", + "reason": "subtree" + }, + { + "object": "LayoutBlockFlow (positioned) DIV id='container'", + "reason": "style change" + }, + { + "object": "LayoutBlockFlow (positioned) DIV class='fixed'", + "reason": "style change" + } + ] +} +
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/compositing/containing-block-removed-individual.html b/third_party/WebKit/LayoutTests/paint/invalidation/compositing/containing-block-removed-individual.html new file mode 100644 index 0000000..cadcf127 --- /dev/null +++ b/third_party/WebKit/LayoutTests/paint/invalidation/compositing/containing-block-removed-individual.html
@@ -0,0 +1,43 @@ +<!DOCTYPE html> +<html> +<head> + <style> + #container { + will-change: scale; + position: absolute; + left: 200px; + top: 100px; + width: 100px; + height: 100px; + background-color: blue; + } + + .fixed { + position: fixed; + left: 50px; + top: 50px; + width: 75px; + height: 75px; + background-color: green + } + </style> + <script src="../resources/text-based-repaint.js"></script> + <script> + function repaintTest() + { + // Removing "will-change: scale" to the container div should make this + // div no longer be the containing block for its fixed position descendant. + console.log('debug'); + document.getElementById("container").style.willChange = "top"; + } + onload = runRepaintAndPixelTest; + </script> +</head> + +<body> + <div id="container"> + <div class="fixed"></div> + </div> +</body> + +</html>
diff --git a/third_party/WebKit/LayoutTests/platform/android/external/wpt/IndexedDB/idbobjectstore_add2-expected.txt b/third_party/WebKit/LayoutTests/platform/android/external/wpt/IndexedDB/idbobjectstore_add2-expected.txt new file mode 100644 index 0000000..cdc4d5b --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/android/external/wpt/IndexedDB/idbobjectstore_add2-expected.txt
@@ -0,0 +1,5 @@ +layer at (0,0) size 980x735 + LayoutView at (0,0) size 980x735 +layer at (0,0) size 980x735 + LayoutBlockFlow {HTML} at (0,0) size 980x735 + LayoutBlockFlow {BODY} at (8,8) size 964x719
diff --git a/third_party/WebKit/LayoutTests/platform/linux/compositing/shadows/shadow-drawing-expected.png b/third_party/WebKit/LayoutTests/platform/linux/compositing/shadows/shadow-drawing-expected.png index fcc7588..fadd552f 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/compositing/shadows/shadow-drawing-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/compositing/shadows/shadow-drawing-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/editing/execCommand/5481523-expected.png b/third_party/WebKit/LayoutTests/platform/linux/editing/execCommand/5481523-expected.png deleted file mode 100644 index cc51ddd..0000000 --- a/third_party/WebKit/LayoutTests/platform/linux/editing/execCommand/5481523-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/editing/execCommand/5481523-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/editing/execCommand/5481523-expected.txt deleted file mode 100644 index ceaa11b..0000000 --- a/third_party/WebKit/LayoutTests/platform/linux/editing/execCommand/5481523-expected.txt +++ /dev/null
@@ -1,31 +0,0 @@ -layer at (0,0) size 800x600 - LayoutView at (0,0) size 800x600 -layer at (0,0) size 800x600 - LayoutBlockFlow {HTML} at (0,0) size 800x600 - LayoutBlockFlow {BODY} at (8,8) size 784x584 - LayoutBlockFlow {P} at (0,0) size 784x40 - LayoutText {#text} at (0,0) size 747x39 - text run at (0,0) width 407: "This tests for a hang when indenting a fully selected table twice. " - text run at (407,0) width 340: "You should see a twice indented table, with four cells," - text run at (0,20) width 42: "below." - LayoutBlockFlow {DIV} at (0,56) size 784x56 - LayoutBlockFlow {BLOCKQUOTE} at (40,0) size 744x56 - LayoutBlockFlow {BLOCKQUOTE} at (40,0) size 704x56 - LayoutTable {TABLE} at (0,0) size 83x56 [border: (1px outset #808080)] - LayoutTableSection {TBODY} at (1,1) size 81x54 - LayoutTableRow {TR} at (0,2) size 81x24 - LayoutTableCell {TD} at (2,2) size 41x24 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=1] - LayoutText {#text} at (2,2) size 27x19 - text run at (2,2) width 27: "One" - LayoutTableCell {TD} at (45,2) size 34x24 [border: (1px inset #808080)] [r=0 c=1 rs=1 cs=1] - LayoutText {#text} at (2,2) size 29x19 - text run at (2,2) width 29: "Two" - LayoutTableRow {TR} at (0,28) size 81x24 - LayoutTableCell {TD} at (2,28) size 41x24 [border: (1px inset #808080)] [r=1 c=0 rs=1 cs=1] - LayoutText {#text} at (2,2) size 37x19 - text run at (2,2) width 37: "Three" - LayoutTableCell {TD} at (45,28) size 34x24 [border: (1px inset #808080)] [r=1 c=1 rs=1 cs=1] - LayoutText {#text} at (2,2) size 30x19 - text run at (2,2) width 30: "Four" -selection start: position 0 of child 0 {TABLE} of child 0 {BLOCKQUOTE} of child 1 {BLOCKQUOTE} of child 2 {DIV} of body -selection end: position 2 of child 0 {TABLE} of child 0 {BLOCKQUOTE} of child 1 {BLOCKQUOTE} of child 2 {DIV} of body
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-radius-split-inline-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-radius-split-inline-expected.png index d2bb7cc..4f8095d 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-radius-split-inline-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-radius-split-inline-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/box-shadow/basic-shadows-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/box-shadow/basic-shadows-expected.png index 2781bf6..a9e254d 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/box-shadow/basic-shadows-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/box-shadow/basic-shadows-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/box-shadow/inset-box-shadows-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/box-shadow/inset-box-shadows-expected.png index e6fdf4a..a64f2e6 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/box-shadow/inset-box-shadows-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/box-shadow/inset-box-shadows-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/box-shadow/inset-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/box-shadow/inset-expected.png index b7733b4..29c0e45 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/box-shadow/inset-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/box-shadow/inset-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/box-shadow/inset-subpixel-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/box-shadow/inset-subpixel-expected.png index 58dfb580..af79355 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/box-shadow/inset-subpixel-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/box-shadow/inset-subpixel-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/css/color-correction-on-text-shadow-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/css/color-correction-on-text-shadow-expected.png index e1c4a5f..e0247165 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/css/color-correction-on-text-shadow-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/css/color-correction-on-text-shadow-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/css/shadow-multiple-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/css/shadow-multiple-expected.png index 2418c04e..b5fcea9 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/css/shadow-multiple-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/css/shadow-multiple-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png index 26a486a..90cb99d 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png index 0218ad5..af2bb2b 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-expected.png index 310277c0..216cfa6c 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png index 34b1e79e..b803863 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png index 7187f13..1e4bd0c 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png index 88d77a5..821f1f4f 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png index d146fa8b..c8070171 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png index 0267aeb..4ad9b46 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png index 573d6800..9f73302 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-zoom200-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-zoom200-expected.png index 377de2f..4ea1384 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-zoom200-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-zoom200-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/month-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/month-picker-appearance-expected.png index ce00d71..1e3c159 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/month-picker-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/month-picker-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/month-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/month-picker-appearance-step-expected.png index 852bea6..59acdc5 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/month-picker-appearance-step-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/month-picker-appearance-step-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/week-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/week-picker-appearance-expected.png index 02e82e4..6f51f8c 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/week-picker-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/week-picker-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/week-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/week-picker-appearance-step-expected.png index a71d5b5..8484e98 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/week-picker-appearance-step-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/week-picker-appearance-step-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/checkbox/checkbox-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/checkbox/checkbox-appearance-basic-expected.png index 061b8df94..5950f8d5 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/checkbox/checkbox-appearance-basic-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/checkbox/checkbox-appearance-basic-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/color/color-suggestion-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/color/color-suggestion-picker-appearance-expected.png index 397038bc..763cb49 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/color/color-suggestion-picker-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/color/color-suggestion-picker-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/color/color-suggestion-picker-appearance-zoom125-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/color/color-suggestion-picker-appearance-zoom125-expected.png index 3af3bc8..2ebbc80 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/color/color-suggestion-picker-appearance-zoom125-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/color/color-suggestion-picker-appearance-zoom125-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/color/color-suggestion-picker-one-row-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/color/color-suggestion-picker-one-row-appearance-expected.png index 6036dfc1..57f55dec 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/color/color-suggestion-picker-one-row-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/color/color-suggestion-picker-one-row-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/color/color-suggestion-picker-two-row-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/color/color-suggestion-picker-two-row-appearance-expected.png index 6c674d42..ef4f5361 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/color/color-suggestion-picker-two-row-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/color/color-suggestion-picker-two-row-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/radio/radio-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/radio/radio-appearance-basic-expected.png index e2c23f6..0a0cd2df 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/radio/radio-appearance-basic-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/radio/radio-appearance-basic-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/range/range-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/range/range-appearance-basic-expected.png index ebc4e158..e7187cf 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/range/range-appearance-basic-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/range/range-appearance-basic-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/search/search-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/search/search-appearance-basic-expected.png index 49a4879..0ba07d0 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/search/search-appearance-basic-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/search/search-appearance-basic-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select/listbox-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select/listbox-appearance-basic-expected.png index 6892754..370bbc9 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select/listbox-appearance-basic-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select/listbox-appearance-basic-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select/menulist-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select/menulist-appearance-basic-expected.png index d0c4825..ffbf10449 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select/menulist-appearance-basic-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select/menulist-appearance-basic-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/submit/submit-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/submit/submit-appearance-basic-expected.png index e5c47d3c..13bc6d5 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/submit/submit-appearance-basic-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/submit/submit-appearance-basic-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/text/text-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/text/text-appearance-basic-expected.png index 1f5c1e2..62c397ba 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/text/text-appearance-basic-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/text/text-appearance-basic-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/textarea/textarea-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/textarea/textarea-appearance-basic-expected.png index 6cd52fc..781e276 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/textarea/textarea-appearance-basic-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/textarea/textarea-appearance-basic-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/validation-bubble-appearance-edge-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/validation-bubble-appearance-edge-expected.png index d2cee2e9..058c16c7 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/validation-bubble-appearance-edge-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/validation-bubble-appearance-edge-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/validation-bubble-appearance-iframe-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/validation-bubble-appearance-iframe-expected.png index 192b7d5b..9adbbad 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/validation-bubble-appearance-iframe-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/validation-bubble-appearance-iframe-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/validation-bubble-appearance-rtl-ui-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/validation-bubble-appearance-rtl-ui-expected.png index ce84e269..34022e16 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/validation-bubble-appearance-rtl-ui-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/validation-bubble-appearance-rtl-ui-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/text/shadow-translucent-fill-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/text/shadow-translucent-fill-expected.png index 237428f28..e76e4ba4 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/text/shadow-translucent-fill-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/text/shadow-translucent-fill-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/writing-mode/english-lr-text-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/writing-mode/english-lr-text-expected.png index 3c9e08a..bad1473 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/writing-mode/english-lr-text-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/writing-mode/english-lr-text-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/ietestcenter/css3/text/textshadow-001-expected.png b/third_party/WebKit/LayoutTests/platform/linux/ietestcenter/css3/text/textshadow-001-expected.png index d0b6f9f..be1038bd 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/ietestcenter/css3/text/textshadow-001-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/ietestcenter/css3/text/textshadow-001-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/ietestcenter/css3/text/textshadow-002-expected.png b/third_party/WebKit/LayoutTests/platform/linux/ietestcenter/css3/text/textshadow-002-expected.png index 2affcbd..dc98f8f 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/ietestcenter/css3/text/textshadow-002-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/ietestcenter/css3/text/textshadow-002-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/ietestcenter/css3/text/textshadow-003-expected.png b/third_party/WebKit/LayoutTests/platform/linux/ietestcenter/css3/text/textshadow-003-expected.png index 5859339..ebf897b 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/ietestcenter/css3/text/textshadow-003-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/ietestcenter/css3/text/textshadow-003-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/ietestcenter/css3/text/textshadow-004-expected.png b/third_party/WebKit/LayoutTests/platform/linux/ietestcenter/css3/text/textshadow-004-expected.png index 8416aa6..e21242f 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/ietestcenter/css3/text/textshadow-004-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/ietestcenter/css3/text/textshadow-004-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/ietestcenter/css3/text/textshadow-010-expected.png b/third_party/WebKit/LayoutTests/platform/linux/ietestcenter/css3/text/textshadow-010-expected.png index c8a188e2d..8027343 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/ietestcenter/css3/text/textshadow-010-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/ietestcenter/css3/text/textshadow-010-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/inspector-protocol/input/dispatchMouseEvent-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/inspector-protocol/input/dispatchMouseEvent-expected.txt index 912f9b6c..9b9ae2f 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/inspector-protocol/input/dispatchMouseEvent-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/inspector-protocol/input/dispatchMouseEvent-expected.txt
@@ -30,4 +30,11 @@ button: 2 x: 100 y: 200 +-----Event----- +type: mousewheel +button: 0 +x: 100 +y: 200 +deltaX: 50 +deltaY: 70
diff --git a/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/shadow-multiple-expected.png b/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/shadow-multiple-expected.png index 8705d5d8..776e29bb 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/shadow-multiple-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/shadow-multiple-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/paint/roundedrects/circle-with-shadow-expected.png b/third_party/WebKit/LayoutTests/platform/linux/paint/roundedrects/circle-with-shadow-expected.png index 81af2556..088a81f 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/paint/roundedrects/circle-with-shadow-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/paint/roundedrects/circle-with-shadow-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/paint/roundedrects/input-with-rounded-rect-and-shadow-expected.png b/third_party/WebKit/LayoutTests/platform/linux/paint/roundedrects/input-with-rounded-rect-and-shadow-expected.png index 7d6bda3f..949a43c9 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/paint/roundedrects/input-with-rounded-rect-and-shadow-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/paint/roundedrects/input-with-rounded-rect-and-shadow-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/css/text-shadow-multiple-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/css/text-shadow-multiple-expected.png index a467c6a..c1e5496 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/css/text-shadow-multiple-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/css/text-shadow-multiple-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/transforms/shadows-expected.png b/third_party/WebKit/LayoutTests/platform/linux/transforms/shadows-expected.png index a212eba..e0a260f 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/transforms/shadows-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/transforms/shadows-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/scalefactor150/fast/hidpi/static/calendar-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/scalefactor150/fast/hidpi/static/calendar-picker-appearance-expected.png index 7e49bbc0..2e47370 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/scalefactor150/fast/hidpi/static/calendar-picker-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/scalefactor150/fast/hidpi/static/calendar-picker-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/scalefactor200/fast/hidpi/static/calendar-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/scalefactor200/fast/hidpi/static/calendar-picker-appearance-expected.png index eb2d2df0..ef9ad47 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/scalefactor200/fast/hidpi/static/calendar-picker-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/scalefactor200/fast/hidpi/static/calendar-picker-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/scalefactor200withzoom/fast/hidpi/static/calendar-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/scalefactor200withzoom/fast/hidpi/static/calendar-picker-appearance-expected.png index eb2d2df0..ef9ad47 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/scalefactor200withzoom/fast/hidpi/static/calendar-picker-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/scalefactor200withzoom/fast/hidpi/static/calendar-picker-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/compositing/shadows/shadow-drawing-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/compositing/shadows/shadow-drawing-expected.png index 08e0f8d..1c3947c 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/compositing/shadows/shadow-drawing-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/compositing/shadows/shadow-drawing-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/css/color-correction-on-text-shadow-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/css/color-correction-on-text-shadow-expected.png index be56616f..8d36640 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/css/color-correction-on-text-shadow-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/css/color-correction-on-text-shadow-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/css/shadow-multiple-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/css/shadow-multiple-expected.png index 1ac203c..1704909 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/css/shadow-multiple-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/css/shadow-multiple-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png index 2aa2728c..4ac053f 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png index 162d8ff..32fb08f 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-expected.png index 4af7111..a91c4d6 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png index da79b76b..6cd0c80 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png index 0efee052..4b5cfb8 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png index 1255d5c..c445e477 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png index 0b72b43..8219523 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png index 81967a8ae..422359d 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png index be94f57..6df63ac4 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-zoom200-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-zoom200-expected.png index 78d669b..ddf653c 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-zoom200-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-zoom200-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/month-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/month-picker-appearance-expected.png index 1221089c..d78a37861 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/month-picker-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/month-picker-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/month-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/month-picker-appearance-step-expected.png index 609c1b0d..0caa065 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/month-picker-appearance-step-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/month-picker-appearance-step-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/week-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/week-picker-appearance-expected.png index 9d1f969..7b4fc86 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/week-picker-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/week-picker-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/week-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/week-picker-appearance-step-expected.png index 902bd52e..3b7e1a5b 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/week-picker-appearance-step-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/week-picker-appearance-step-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/color/color-suggestion-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/color/color-suggestion-picker-appearance-expected.png index 736dca26..f3d9ee0 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/color/color-suggestion-picker-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/color/color-suggestion-picker-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/color/color-suggestion-picker-appearance-zoom125-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/color/color-suggestion-picker-appearance-zoom125-expected.png index 1d2f3b2..1554452 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/color/color-suggestion-picker-appearance-zoom125-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/color/color-suggestion-picker-appearance-zoom125-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/color/color-suggestion-picker-appearance-zoom200-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/color/color-suggestion-picker-appearance-zoom200-expected.png index 1a5f72e..a191da7 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/color/color-suggestion-picker-appearance-zoom200-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/color/color-suggestion-picker-appearance-zoom200-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/color/color-suggestion-picker-one-row-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/color/color-suggestion-picker-one-row-appearance-expected.png index d90c9df..ab1e119 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/color/color-suggestion-picker-one-row-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/color/color-suggestion-picker-one-row-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/color/color-suggestion-picker-two-row-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/color/color-suggestion-picker-two-row-appearance-expected.png index c6eaf82f..d8f0582 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/color/color-suggestion-picker-two-row-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/color/color-suggestion-picker-two-row-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/select/listbox-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/select/listbox-appearance-basic-expected.png index f1a2638..958745f1 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/select/listbox-appearance-basic-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/select/listbox-appearance-basic-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/submit/submit-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/submit/submit-appearance-basic-expected.png index 1dfe561..824393d 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/submit/submit-appearance-basic-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/submit/submit-appearance-basic-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/text/text-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/text/text-appearance-basic-expected.png index e8b9bccc..a5011e2 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/text/text-appearance-basic-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/text/text-appearance-basic-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/textarea/textarea-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/textarea/textarea-appearance-basic-expected.png index 1b06206..e828031 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/textarea/textarea-appearance-basic-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/textarea/textarea-appearance-basic-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/validation-bubble-appearance-edge-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/validation-bubble-appearance-edge-expected.png index c5243c6..4a46f036 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/validation-bubble-appearance-edge-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/validation-bubble-appearance-edge-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/validation-bubble-appearance-iframe-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/validation-bubble-appearance-iframe-expected.png index 10bbe65..3d22669 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/validation-bubble-appearance-iframe-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/validation-bubble-appearance-iframe-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/validation-bubble-appearance-rtl-ui-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/validation-bubble-appearance-rtl-ui-expected.png index 37f2d563..2592ef9 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/validation-bubble-appearance-rtl-ui-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/validation-bubble-appearance-rtl-ui-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/shadow-translucent-fill-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/shadow-translucent-fill-expected.png index f5dacf6..7d32e0b 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/shadow-translucent-fill-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/shadow-translucent-fill-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/writing-mode/english-lr-text-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/writing-mode/english-lr-text-expected.png index fd1d092..0a9f3e507 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/writing-mode/english-lr-text-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/writing-mode/english-lr-text-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/ietestcenter/css3/text/textshadow-002-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/ietestcenter/css3/text/textshadow-002-expected.png index b2d9526e..8f335f6 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/ietestcenter/css3/text/textshadow-002-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/ietestcenter/css3/text/textshadow-002-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/ietestcenter/css3/text/textshadow-003-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/ietestcenter/css3/text/textshadow-003-expected.png index e211b482..7c5f5874 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/ietestcenter/css3/text/textshadow-003-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/ietestcenter/css3/text/textshadow-003-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/ietestcenter/css3/text/textshadow-004-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/ietestcenter/css3/text/textshadow-004-expected.png index 379cf45..fc316ad 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/ietestcenter/css3/text/textshadow-004-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/ietestcenter/css3/text/textshadow-004-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/ietestcenter/css3/text/textshadow-010-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/ietestcenter/css3/text/textshadow-010-expected.png index 3ad0b83..9f7133e 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/ietestcenter/css3/text/textshadow-010-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/ietestcenter/css3/text/textshadow-010-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/paint/invalidation/shadow-multiple-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/paint/invalidation/shadow-multiple-expected.png index c9fdd9c..3949bac 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/paint/invalidation/shadow-multiple-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/paint/invalidation/shadow-multiple-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/svg/css/text-shadow-multiple-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/svg/css/text-shadow-multiple-expected.png index bb7cf879..893b1a6 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/svg/css/text-shadow-multiple-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/svg/css/text-shadow-multiple-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png index 7cf328b5..32275ff3 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png index 4b2f97ea..36a315b6 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-expected.png index 3d1fbc6..a043609d 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png index e629bbc..4d80345f 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png index aa87c6f..45f785d 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png index 870d39a..fc19d890 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png index 9d10d67..15451c87 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png index b6c0e35..2aa82dc467 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png index 7b86fbd..5f4557e4 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-zoom200-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-zoom200-expected.png index b0f3885e..63d9d7f 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-zoom200-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-zoom200-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/month-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/month-picker-appearance-expected.png index f0a29a339..861c19b 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/month-picker-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/month-picker-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/month-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/month-picker-appearance-step-expected.png index 237f813..919fd17 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/month-picker-appearance-step-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/month-picker-appearance-step-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/week-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/week-picker-appearance-expected.png index 39a21177..8e43099 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/week-picker-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/week-picker-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/week-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/week-picker-appearance-step-expected.png index 04897923..0fc27f1 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/week-picker-appearance-step-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/week-picker-appearance-step-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/checkbox/checkbox-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/checkbox/checkbox-appearance-basic-expected.png new file mode 100644 index 0000000..f376015 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/checkbox/checkbox-appearance-basic-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/color/color-suggestion-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/color/color-suggestion-picker-appearance-expected.png index aef878f..2d9cc22c 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/color/color-suggestion-picker-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/color/color-suggestion-picker-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/color/color-suggestion-picker-appearance-zoom125-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/color/color-suggestion-picker-appearance-zoom125-expected.png index 553ac8fc..9e89996d 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/color/color-suggestion-picker-appearance-zoom125-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/color/color-suggestion-picker-appearance-zoom125-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/color/color-suggestion-picker-appearance-zoom200-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/color/color-suggestion-picker-appearance-zoom200-expected.png index f517220a..01077a15 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/color/color-suggestion-picker-appearance-zoom200-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/color/color-suggestion-picker-appearance-zoom200-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/color/color-suggestion-picker-one-row-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/color/color-suggestion-picker-one-row-appearance-expected.png index 2a94aa5..54272b4 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/color/color-suggestion-picker-one-row-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/color/color-suggestion-picker-one-row-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/color/color-suggestion-picker-two-row-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/color/color-suggestion-picker-two-row-appearance-expected.png index 37df68d8..9b546ae 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/color/color-suggestion-picker-two-row-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/color/color-suggestion-picker-two-row-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/radio/radio-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/radio/radio-appearance-basic-expected.png new file mode 100644 index 0000000..494ff37 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/radio/radio-appearance-basic-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/select/listbox-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/select/listbox-appearance-basic-expected.png index fe67dd5c..9a73921c 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/select/listbox-appearance-basic-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/select/listbox-appearance-basic-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/submit/submit-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/submit/submit-appearance-basic-expected.png index 24b73e3..6c6cdee 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/submit/submit-appearance-basic-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/submit/submit-appearance-basic-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/text/text-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/text/text-appearance-basic-expected.png index 1f70dfd7..cdffa9c 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/text/text-appearance-basic-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/text/text-appearance-basic-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/textarea/textarea-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/textarea/textarea-appearance-basic-expected.png index 828f9d79a..3da4cc6 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/textarea/textarea-appearance-basic-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/textarea/textarea-appearance-basic-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/validation-bubble-appearance-edge-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/validation-bubble-appearance-edge-expected.png index d01b0001..5dfa80e3 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/validation-bubble-appearance-edge-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/validation-bubble-appearance-edge-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/validation-bubble-appearance-iframe-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/validation-bubble-appearance-iframe-expected.png index 686787c..42afea1 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/validation-bubble-appearance-iframe-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/validation-bubble-appearance-iframe-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/validation-bubble-appearance-rtl-ui-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/validation-bubble-appearance-rtl-ui-expected.png index 2eaa61a..5ceb0b2 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/validation-bubble-appearance-rtl-ui-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/validation-bubble-appearance-rtl-ui-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/box-shadow/basic-shadows-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/box-shadow/basic-shadows-expected.png index 4a20c759..6c617c2 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/box-shadow/basic-shadows-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/box-shadow/basic-shadows-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/css/shadow-multiple-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/css/shadow-multiple-expected.png index ba3212f..8cb70d5 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/css/shadow-multiple-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/css/shadow-multiple-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png index 7b004ca..1610c08 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png index ea0dc5e2..76990e2 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-expected.png index 78f8557d..f899c5a8 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png index 645e59d..3a4148c 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png index 348210a..e7e70dc1 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png index 1f4b3e4..cb3cbd2 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png index bfff98e..9a612487 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png index 4af814ead..55c2043 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/month-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/month-picker-appearance-expected.png index 55d0dae2..7bcee863 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/month-picker-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/month-picker-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/month-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/month-picker-appearance-step-expected.png index b41c18f..b01c8d1 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/month-picker-appearance-step-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/month-picker-appearance-step-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/week-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/week-picker-appearance-expected.png index e0cbd5b..ff5d2b1b 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/week-picker-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/week-picker-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/week-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/week-picker-appearance-step-expected.png index bb74ae6..72338d4 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/week-picker-appearance-step-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/week-picker-appearance-step-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/checkbox/checkbox-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/checkbox/checkbox-appearance-basic-expected.png index ce6bbe82..598a6ba 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/checkbox/checkbox-appearance-basic-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/checkbox/checkbox-appearance-basic-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/color/color-suggestion-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/color/color-suggestion-picker-appearance-expected.png index 8e810b761..ca22e27 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/color/color-suggestion-picker-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/color/color-suggestion-picker-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/color/color-suggestion-picker-appearance-zoom125-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/color/color-suggestion-picker-appearance-zoom125-expected.png index d32aa66..dd6fcd6 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/color/color-suggestion-picker-appearance-zoom125-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/color/color-suggestion-picker-appearance-zoom125-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/color/color-suggestion-picker-appearance-zoom200-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/color/color-suggestion-picker-appearance-zoom200-expected.png index 7e0f2f0..5de0e24 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/color/color-suggestion-picker-appearance-zoom200-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/color/color-suggestion-picker-appearance-zoom200-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/color/color-suggestion-picker-one-row-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/color/color-suggestion-picker-one-row-appearance-expected.png index eeb422c3..de14398 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/color/color-suggestion-picker-one-row-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/color/color-suggestion-picker-one-row-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/color/color-suggestion-picker-two-row-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/color/color-suggestion-picker-two-row-appearance-expected.png index 9bdf154a..a0e30913 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/color/color-suggestion-picker-two-row-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/color/color-suggestion-picker-two-row-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/radio/radio-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/radio/radio-appearance-basic-expected.png index 7745917..b9aa228c 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/radio/radio-appearance-basic-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/radio/radio-appearance-basic-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/select/listbox-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/select/listbox-appearance-basic-expected.png index ef8c28296..9d95c64 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/select/listbox-appearance-basic-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/select/listbox-appearance-basic-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/submit/submit-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/submit/submit-appearance-basic-expected.png index d7a43200..081923b 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/submit/submit-appearance-basic-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/submit/submit-appearance-basic-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/text/text-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/text/text-appearance-basic-expected.png index 32520ece..7779dcb0d 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/text/text-appearance-basic-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/text/text-appearance-basic-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/textarea/textarea-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/textarea/textarea-appearance-basic-expected.png index a9d78cc..28d933f 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/textarea/textarea-appearance-basic-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/textarea/textarea-appearance-basic-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/validation-bubble-appearance-edge-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/validation-bubble-appearance-edge-expected.png index c3706439..c124322 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/validation-bubble-appearance-edge-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/validation-bubble-appearance-edge-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/validation-bubble-appearance-iframe-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/validation-bubble-appearance-iframe-expected.png index 414d9a24..01b2747 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/validation-bubble-appearance-iframe-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/validation-bubble-appearance-iframe-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/validation-bubble-appearance-rtl-ui-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/validation-bubble-appearance-rtl-ui-expected.png index 9f783963..0f34080 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/validation-bubble-appearance-rtl-ui-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/validation-bubble-appearance-rtl-ui-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/text/shadow-translucent-fill-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/text/shadow-translucent-fill-expected.png index 975af90..55e5a50 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/text/shadow-translucent-fill-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/text/shadow-translucent-fill-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/ietestcenter/css3/text/textshadow-003-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/ietestcenter/css3/text/textshadow-003-expected.png index 94bae83b..826cd30 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/ietestcenter/css3/text/textshadow-003-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/ietestcenter/css3/text/textshadow-003-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/ietestcenter/css3/text/textshadow-004-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/ietestcenter/css3/text/textshadow-004-expected.png index 1b1375b..d01ad9f 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/ietestcenter/css3/text/textshadow-004-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/ietestcenter/css3/text/textshadow-004-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png index 7cf328b5..32275ff3 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png index 4b2f97ea..36a315b6 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-expected.png index 3d1fbc6..a043609d 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png index e629bbc..4d80345f 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png index aa87c6f..45f785d 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png index 870d39a..fc19d890 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png index 9d10d67..15451c87 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png index b6c0e35..2aa82dc467 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png index 7b86fbd..5f4557e4 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-zoom200-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-zoom200-expected.png index b0f3885e..63d9d7f 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-zoom200-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-zoom200-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/month-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/month-picker-appearance-expected.png index f0a29a339..861c19b 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/month-picker-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/month-picker-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/month-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/month-picker-appearance-step-expected.png index 237f813..919fd17 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/month-picker-appearance-step-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/month-picker-appearance-step-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/week-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/week-picker-appearance-expected.png index 39a21177..8e43099 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/week-picker-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/week-picker-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/week-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/week-picker-appearance-step-expected.png index 04897923..0fc27f1 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/week-picker-appearance-step-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/week-picker-appearance-step-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/color/color-suggestion-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/color/color-suggestion-picker-appearance-expected.png index aef878f..2d9cc22c 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/color/color-suggestion-picker-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/color/color-suggestion-picker-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/color/color-suggestion-picker-appearance-zoom125-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/color/color-suggestion-picker-appearance-zoom125-expected.png index 553ac8fc..9e89996d 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/color/color-suggestion-picker-appearance-zoom125-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/color/color-suggestion-picker-appearance-zoom125-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/color/color-suggestion-picker-appearance-zoom200-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/color/color-suggestion-picker-appearance-zoom200-expected.png index f517220a..01077a15 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/color/color-suggestion-picker-appearance-zoom200-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/color/color-suggestion-picker-appearance-zoom200-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/color/color-suggestion-picker-one-row-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/color/color-suggestion-picker-one-row-appearance-expected.png index 2a94aa5..54272b4 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/color/color-suggestion-picker-one-row-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/color/color-suggestion-picker-one-row-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/color/color-suggestion-picker-two-row-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/color/color-suggestion-picker-two-row-appearance-expected.png index 37df68d8..9b546ae 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/color/color-suggestion-picker-two-row-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/color/color-suggestion-picker-two-row-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/select/listbox-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/select/listbox-appearance-basic-expected.png index fe67dd5c..9a73921c 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/select/listbox-appearance-basic-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/select/listbox-appearance-basic-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/submit/submit-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/submit/submit-appearance-basic-expected.png index 24b73e3..6c6cdee 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/submit/submit-appearance-basic-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/submit/submit-appearance-basic-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/text/text-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/text/text-appearance-basic-expected.png index 1f70dfd7..cdffa9c 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/text/text-appearance-basic-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/text/text-appearance-basic-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/textarea/textarea-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/textarea/textarea-appearance-basic-expected.png index 828f9d79a..3da4cc6 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/textarea/textarea-appearance-basic-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/textarea/textarea-appearance-basic-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/validation-bubble-appearance-edge-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/validation-bubble-appearance-edge-expected.png index d01b0001..5dfa80e3 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/validation-bubble-appearance-edge-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/validation-bubble-appearance-edge-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/validation-bubble-appearance-iframe-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/validation-bubble-appearance-iframe-expected.png index 686787c..42afea1 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/validation-bubble-appearance-iframe-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/validation-bubble-appearance-iframe-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/validation-bubble-appearance-rtl-ui-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/validation-bubble-appearance-rtl-ui-expected.png index 2eaa61a..5ceb0b2 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/validation-bubble-appearance-rtl-ui-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/validation-bubble-appearance-rtl-ui-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/compositing/shadows/shadow-drawing-expected.png b/third_party/WebKit/LayoutTests/platform/mac/compositing/shadows/shadow-drawing-expected.png index fed0043..fa338d7 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/compositing/shadows/shadow-drawing-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/compositing/shadows/shadow-drawing-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/editing/execCommand/5481523-expected.png b/third_party/WebKit/LayoutTests/platform/mac/editing/execCommand/5481523-expected.png deleted file mode 100644 index 6c9ce17..0000000 --- a/third_party/WebKit/LayoutTests/platform/mac/editing/execCommand/5481523-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/editing/execCommand/5481523-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/editing/execCommand/5481523-expected.txt deleted file mode 100644 index 938be8e..0000000 --- a/third_party/WebKit/LayoutTests/platform/mac/editing/execCommand/5481523-expected.txt +++ /dev/null
@@ -1,31 +0,0 @@ -layer at (0,0) size 800x600 - LayoutView at (0,0) size 800x600 -layer at (0,0) size 800x600 - LayoutBlockFlow {HTML} at (0,0) size 800x600 - LayoutBlockFlow {BODY} at (8,8) size 784x584 - LayoutBlockFlow {P} at (0,0) size 784x36 - LayoutText {#text} at (0,0) size 761x36 - text run at (0,0) width 416: "This tests for a hang when indenting a fully selected table twice. " - text run at (415,0) width 346: "You should see a twice indented table, with four cells," - text run at (0,18) width 43: "below." - LayoutBlockFlow {DIV} at (0,52) size 784x52 - LayoutBlockFlow {BLOCKQUOTE} at (40,0) size 744x52 - LayoutBlockFlow {BLOCKQUOTE} at (40,0) size 704x52 - LayoutTable {TABLE} at (0,0) size 85x52 [border: (1px outset #808080)] - LayoutTableSection {TBODY} at (1,1) size 83x50 - LayoutTableRow {TR} at (0,2) size 83x22 - LayoutTableCell {TD} at (2,2) size 42x22 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=1] - LayoutText {#text} at (2,2) size 27x18 - text run at (2,2) width 27: "One" - LayoutTableCell {TD} at (46,2) size 35x22 [border: (1px inset #808080)] [r=0 c=1 rs=1 cs=1] - LayoutText {#text} at (2,2) size 29x18 - text run at (2,2) width 29: "Two" - LayoutTableRow {TR} at (0,26) size 83x22 - LayoutTableCell {TD} at (2,26) size 42x22 [border: (1px inset #808080)] [r=1 c=0 rs=1 cs=1] - LayoutText {#text} at (2,2) size 38x18 - text run at (2,2) width 38: "Three" - LayoutTableCell {TD} at (46,26) size 35x22 [border: (1px inset #808080)] [r=1 c=1 rs=1 cs=1] - LayoutText {#text} at (2,2) size 31x18 - text run at (2,2) width 31: "Four" -selection start: position 0 of child 0 {TABLE} of child 0 {BLOCKQUOTE} of child 1 {BLOCKQUOTE} of child 2 {DIV} of body -selection end: position 2 of child 0 {TABLE} of child 0 {BLOCKQUOTE} of child 1 {BLOCKQUOTE} of child 2 {DIV} of body
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-radius-split-inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-radius-split-inline-expected.png index 9661059e..4e1efe3 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-radius-split-inline-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-radius-split-inline-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/box-shadow/basic-shadows-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/box-shadow/basic-shadows-expected.png index ae81dfe5..57fe18b 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/box-shadow/basic-shadows-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/box-shadow/basic-shadows-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/box-shadow/inset-box-shadows-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/box-shadow/inset-box-shadows-expected.png index 4480a755..148e730 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/box-shadow/inset-box-shadows-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/box-shadow/inset-box-shadows-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/box-shadow/inset-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/box-shadow/inset-expected.png index 30b359a2..6d444dd6 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/box-shadow/inset-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/box-shadow/inset-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/box-shadow/inset-subpixel-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/box-shadow/inset-subpixel-expected.png index e458c4f..3cfa618 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/box-shadow/inset-subpixel-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/box-shadow/inset-subpixel-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/css/color-correction-on-text-shadow-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/css/color-correction-on-text-shadow-expected.png index fc49a02..0047b5c 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/css/color-correction-on-text-shadow-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/css/color-correction-on-text-shadow-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/css/shadow-multiple-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/css/shadow-multiple-expected.png index f397a8f..c5738bc 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/css/shadow-multiple-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/css/shadow-multiple-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png index 8787fa8..18234f6 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png index bdbabf5..76ed782 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-expected.png index dc58bf8..4f62e85 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png index f0473b0..f0ca101 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png index 81af37e..2562bd773 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png index 872604f..bd4a358 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png index c8a12ff..08cb4fa 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png index 40df768..b2bd6af 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png index d75c0743..e7cfb5a 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-zoom200-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-zoom200-expected.png index c5305380..71782830 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-zoom200-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-zoom200-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/month-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/month-picker-appearance-expected.png index 81616a7..06dfa36d 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/month-picker-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/month-picker-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/month-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/month-picker-appearance-step-expected.png index 3f7bbcc..cd1a864 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/month-picker-appearance-step-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/month-picker-appearance-step-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/week-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/week-picker-appearance-expected.png index f13fe40..a8573ed 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/week-picker-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/week-picker-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/week-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/week-picker-appearance-step-expected.png index b06dc4d6..f999a9c 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/week-picker-appearance-step-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/week-picker-appearance-step-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/color/color-suggestion-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/color/color-suggestion-picker-appearance-expected.png index ac942bd..b3b1190b 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/color/color-suggestion-picker-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/color/color-suggestion-picker-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/color/color-suggestion-picker-appearance-zoom125-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/color/color-suggestion-picker-appearance-zoom125-expected.png index 582d732d..6ae201a8 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/color/color-suggestion-picker-appearance-zoom125-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/color/color-suggestion-picker-appearance-zoom125-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/color/color-suggestion-picker-appearance-zoom200-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/color/color-suggestion-picker-appearance-zoom200-expected.png index 5f9c32e..e6ed010 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/color/color-suggestion-picker-appearance-zoom200-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/color/color-suggestion-picker-appearance-zoom200-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/color/color-suggestion-picker-one-row-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/color/color-suggestion-picker-one-row-appearance-expected.png index 12cb88e..96eeaa0 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/color/color-suggestion-picker-one-row-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/color/color-suggestion-picker-one-row-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/color/color-suggestion-picker-two-row-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/color/color-suggestion-picker-two-row-appearance-expected.png index 6472a3d..d5c2dd77 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/color/color-suggestion-picker-two-row-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/color/color-suggestion-picker-two-row-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/datalist/input-appearance-range-with-datalist-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/datalist/input-appearance-range-with-datalist-expected.png index f8331a1f..e7206cd 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/datalist/input-appearance-range-with-datalist-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/datalist/input-appearance-range-with-datalist-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/datalist/input-appearance-range-with-datalist-zoomed-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/datalist/input-appearance-range-with-datalist-zoomed-expected.png index 2c36327..8131244 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/datalist/input-appearance-range-with-datalist-zoomed-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/datalist/input-appearance-range-with-datalist-zoomed-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/datalist/input-appearance-range-with-padding-with-datalist-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/datalist/input-appearance-range-with-padding-with-datalist-expected.png index 9fd62bf..f0baca12 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/datalist/input-appearance-range-with-padding-with-datalist-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/datalist/input-appearance-range-with-padding-with-datalist-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/range/input-appearance-range-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/range/input-appearance-range-expected.png index 733192d..f887d25c 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/range/input-appearance-range-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/range/input-appearance-range-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/range/range-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/range/range-appearance-basic-expected.png index 5829ea5..d9a97e0 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/range/range-appearance-basic-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/range/range-appearance-basic-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/range/range-update-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/range/range-update-expected.png index ffc5a2be..cf5d5cde 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/range/range-update-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/range/range-update-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/range/slider-padding-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/range/slider-padding-expected.png index 9a8e8ea..6a25534 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/range/slider-padding-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/range/slider-padding-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/range/slider-thumb-shared-style-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/range/slider-thumb-shared-style-expected.png index fae3532..4e288aa 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/range/slider-thumb-shared-style-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/range/slider-thumb-shared-style-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/range/thumbslider-no-parent-slider-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/range/thumbslider-no-parent-slider-expected.png index 60ea126..72720cc 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/range/thumbslider-no-parent-slider-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/range/thumbslider-no-parent-slider-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/select/listbox-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/select/listbox-appearance-basic-expected.png index 6e1b8bc..0172cb64 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/select/listbox-appearance-basic-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/select/listbox-appearance-basic-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/submit/submit-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/submit/submit-appearance-basic-expected.png index c311a6c1..d566f75 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/submit/submit-appearance-basic-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/submit/submit-appearance-basic-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/text/text-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/text/text-appearance-basic-expected.png index ed6fbcb..8a014b1 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/text/text-appearance-basic-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/text/text-appearance-basic-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/textarea/textarea-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/textarea/textarea-appearance-basic-expected.png index f83486c7..8333fa1 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/textarea/textarea-appearance-basic-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/textarea/textarea-appearance-basic-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/validation-bubble-appearance-edge-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/validation-bubble-appearance-edge-expected.png index 1ce7d346..99934d8 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/validation-bubble-appearance-edge-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/validation-bubble-appearance-edge-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/validation-bubble-appearance-iframe-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/validation-bubble-appearance-iframe-expected.png index 3d90b321..af8bcfe5 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/validation-bubble-appearance-iframe-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/validation-bubble-appearance-iframe-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/validation-bubble-appearance-rtl-ui-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/validation-bubble-appearance-rtl-ui-expected.png index 3103f19d..d2c61732 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/validation-bubble-appearance-rtl-ui-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/validation-bubble-appearance-rtl-ui-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/text/shadow-translucent-fill-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/text/shadow-translucent-fill-expected.png index 3a163be..4773ed57 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/text/shadow-translucent-fill-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/text/shadow-translucent-fill-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/writing-mode/english-lr-text-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/writing-mode/english-lr-text-expected.png index 1a1705b..2088324 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/writing-mode/english-lr-text-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/writing-mode/english-lr-text-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/text/textshadow-001-expected.png b/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/text/textshadow-001-expected.png index 9747a966..74cad211 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/text/textshadow-001-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/text/textshadow-001-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/text/textshadow-002-expected.png b/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/text/textshadow-002-expected.png index bfbe4d4..33daa2f 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/text/textshadow-002-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/text/textshadow-002-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/text/textshadow-003-expected.png b/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/text/textshadow-003-expected.png index 2bbefde..952eef6e 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/text/textshadow-003-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/text/textshadow-003-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/text/textshadow-004-expected.png b/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/text/textshadow-004-expected.png index a87de60..39adac6 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/text/textshadow-004-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/text/textshadow-004-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/text/textshadow-010-expected.png b/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/text/textshadow-010-expected.png index edd5e2b..53c6d4a 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/text/textshadow-010-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/text/textshadow-010-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/forms/range-focus-by-mouse-then-keydown-expected.png b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/forms/range-focus-by-mouse-then-keydown-expected.png index 4d8a7be..387700c4 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/forms/range-focus-by-mouse-then-keydown-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/forms/range-focus-by-mouse-then-keydown-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/shadow-multiple-expected.png b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/shadow-multiple-expected.png index d3dd3e8..9b1d7510 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/shadow-multiple-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/shadow-multiple-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/slider-thumb-drag-release-expected.png b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/slider-thumb-drag-release-expected.png index ffc5a2be..cf5d5cde 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/slider-thumb-drag-release-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/slider-thumb-drag-release-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/svg/repaint-shadow-expected.png b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/svg/repaint-shadow-expected.png index e3a3cabd..d975277 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/svg/repaint-shadow-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/svg/repaint-shadow-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/paint/roundedrects/circle-with-shadow-expected.png b/third_party/WebKit/LayoutTests/platform/mac/paint/roundedrects/circle-with-shadow-expected.png index 5b6153f6..acf52659 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/paint/roundedrects/circle-with-shadow-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/paint/roundedrects/circle-with-shadow-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/paint/roundedrects/input-with-rounded-rect-and-shadow-expected.png b/third_party/WebKit/LayoutTests/platform/mac/paint/roundedrects/input-with-rounded-rect-and-shadow-expected.png index b0dda988..a1881785 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/paint/roundedrects/input-with-rounded-rect-and-shadow-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/paint/roundedrects/input-with-rounded-rect-and-shadow-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/css/text-shadow-multiple-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/css/text-shadow-multiple-expected.png index 3d6ce71..1577f229 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/svg/css/text-shadow-multiple-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/svg/css/text-shadow-multiple-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/transforms/shadows-expected.png b/third_party/WebKit/LayoutTests/platform/mac/transforms/shadows-expected.png index 21b0aab..370afda 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/transforms/shadows-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/transforms/shadows-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/stable/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/stable/webexposed/global-interface-listing-expected.txt index 4fc09b51..f08dedd 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/stable/webexposed/global-interface-listing-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/stable/webexposed/global-interface-listing-expected.txt
@@ -26,11 +26,6 @@ getter animationName getter elapsedTime method constructor -interface AppBannerPromptResult - attribute @@toStringTag - getter outcome - getter platform - method constructor interface ApplicationCache : EventTarget attribute @@toStringTag attribute CHECKING
diff --git a/third_party/WebKit/LayoutTests/platform/win/compositing/shadows/shadow-drawing-expected.png b/third_party/WebKit/LayoutTests/platform/win/compositing/shadows/shadow-drawing-expected.png index a1bba5bd..e34c9d5 100644 --- a/third_party/WebKit/LayoutTests/platform/win/compositing/shadows/shadow-drawing-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/compositing/shadows/shadow-drawing-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/editing/execCommand/5481523-expected.png b/third_party/WebKit/LayoutTests/platform/win/editing/execCommand/5481523-expected.png deleted file mode 100644 index 930e13f0..0000000 --- a/third_party/WebKit/LayoutTests/platform/win/editing/execCommand/5481523-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/editing/execCommand/5481523-expected.txt b/third_party/WebKit/LayoutTests/platform/win/editing/execCommand/5481523-expected.txt deleted file mode 100644 index 617df48..0000000 --- a/third_party/WebKit/LayoutTests/platform/win/editing/execCommand/5481523-expected.txt +++ /dev/null
@@ -1,30 +0,0 @@ -layer at (0,0) size 800x600 - LayoutView at (0,0) size 800x600 -layer at (0,0) size 800x600 - LayoutBlockFlow {HTML} at (0,0) size 800x600 - LayoutBlockFlow {BODY} at (8,8) size 784x584 - LayoutBlockFlow {P} at (0,0) size 784x20 - LayoutText {#text} at (0,0) size 748x19 - text run at (0,0) width 382: "This tests for a hang when indenting a fully selected table twice. " - text run at (382,0) width 366: "You should see a twice indented table, with four cells, below." - LayoutBlockFlow {DIV} at (0,36) size 784x56 - LayoutBlockFlow {BLOCKQUOTE} at (40,0) size 744x56 - LayoutBlockFlow {BLOCKQUOTE} at (40,0) size 704x56 - LayoutTable {TABLE} at (0,0) size 80x56 [border: (1px outset #808080)] - LayoutTableSection {TBODY} at (1,1) size 78x54 - LayoutTableRow {TR} at (0,2) size 78x24 - LayoutTableCell {TD} at (2,2) size 39x24 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=1] - LayoutText {#text} at (2,2) size 26x19 - text run at (2,2) width 26: "One" - LayoutTableCell {TD} at (43,2) size 33x24 [border: (1px inset #808080)] [r=0 c=1 rs=1 cs=1] - LayoutText {#text} at (2,2) size 27x19 - text run at (2,2) width 27: "Two" - LayoutTableRow {TR} at (0,28) size 78x24 - LayoutTableCell {TD} at (2,28) size 39x24 [border: (1px inset #808080)] [r=1 c=0 rs=1 cs=1] - LayoutText {#text} at (2,2) size 35x19 - text run at (2,2) width 35: "Three" - LayoutTableCell {TD} at (43,28) size 33x24 [border: (1px inset #808080)] [r=1 c=1 rs=1 cs=1] - LayoutText {#text} at (2,2) size 29x19 - text run at (2,2) width 29: "Four" -selection start: position 0 of child 0 {TABLE} of child 0 {BLOCKQUOTE} of child 1 {BLOCKQUOTE} of child 2 {DIV} of body -selection end: position 2 of child 0 {TABLE} of child 0 {BLOCKQUOTE} of child 1 {BLOCKQUOTE} of child 2 {DIV} of body
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-radius-split-inline-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-radius-split-inline-expected.png index 32d7384..3db5e34 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-radius-split-inline-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-radius-split-inline-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/box-shadow/basic-shadows-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/box-shadow/basic-shadows-expected.png index 7bf1ec4..42bd214 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/box-shadow/basic-shadows-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/box-shadow/basic-shadows-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/box-shadow/inset-box-shadows-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/box-shadow/inset-box-shadows-expected.png index 5b6d67bc..38dc53e 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/box-shadow/inset-box-shadows-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/box-shadow/inset-box-shadows-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/box-shadow/inset-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/box-shadow/inset-expected.png index 83bdd2e..83ed37a 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/box-shadow/inset-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/box-shadow/inset-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/box-shadow/inset-subpixel-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/box-shadow/inset-subpixel-expected.png index 9549542..a2db537c2 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/box-shadow/inset-subpixel-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/box-shadow/inset-subpixel-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/css/color-correction-on-text-shadow-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/css/color-correction-on-text-shadow-expected.png index e4299f0..6f4b775c 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/css/color-correction-on-text-shadow-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/css/color-correction-on-text-shadow-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/css/shadow-multiple-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/css/shadow-multiple-expected.png index 78cd183b..999dc92 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/css/shadow-multiple-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/css/shadow-multiple-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png index 80430fb..fff0a4c 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png index c3efdde..0437553 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-expected.png index 128ea36..901adffe 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png index c588837c..c15fb53 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png index 25a380b..178e5360 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png index 2b2c4094..196067f 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png index 6206addc..6876000c 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png index a52f93d..de3c1202 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png index 71516b9..68cb2d9 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-zoom200-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-zoom200-expected.png index 8a65888..ddf25bf4 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-zoom200-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-zoom200-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/month-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/month-picker-appearance-expected.png index a9fdd400..0fb4ed2 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/month-picker-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/month-picker-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/month-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/month-picker-appearance-step-expected.png index 33a180c6..c20e292 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/month-picker-appearance-step-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/month-picker-appearance-step-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/week-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/week-picker-appearance-expected.png index 1294d86..fda95b9 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/week-picker-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/week-picker-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/week-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/week-picker-appearance-step-expected.png index bc0c8f89..36a4a9a 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/week-picker-appearance-step-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/week-picker-appearance-step-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/checkbox/checkbox-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/checkbox/checkbox-appearance-basic-expected.png index 89dc8f1..b9b8e07 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/checkbox/checkbox-appearance-basic-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/checkbox/checkbox-appearance-basic-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/color/color-suggestion-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/color/color-suggestion-picker-appearance-expected.png index 8cabbd0..a2155dd 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/color/color-suggestion-picker-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/color/color-suggestion-picker-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/color/color-suggestion-picker-appearance-zoom125-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/color/color-suggestion-picker-appearance-zoom125-expected.png index f82c7053..7898152 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/color/color-suggestion-picker-appearance-zoom125-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/color/color-suggestion-picker-appearance-zoom125-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/color/color-suggestion-picker-one-row-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/color/color-suggestion-picker-one-row-appearance-expected.png index eeea8cb..e80cbe9d 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/color/color-suggestion-picker-one-row-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/color/color-suggestion-picker-one-row-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/color/color-suggestion-picker-two-row-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/color/color-suggestion-picker-two-row-appearance-expected.png index f03f748..d94d8c6 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/color/color-suggestion-picker-two-row-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/color/color-suggestion-picker-two-row-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/radio/radio-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/radio/radio-appearance-basic-expected.png index ef33c03..2d821b3 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/radio/radio-appearance-basic-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/radio/radio-appearance-basic-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/range/range-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/range/range-appearance-basic-expected.png index b17b1163..fe4c680 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/range/range-appearance-basic-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/range/range-appearance-basic-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/search/search-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/search/search-appearance-basic-expected.png index 50e298d..6f0eb63f 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/search/search-appearance-basic-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/search/search-appearance-basic-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/select/listbox-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/select/listbox-appearance-basic-expected.png index 853153cb..9c2270e 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/select/listbox-appearance-basic-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/select/listbox-appearance-basic-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/select/menulist-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/select/menulist-appearance-basic-expected.png index e8159b3..a943221 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/select/menulist-appearance-basic-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/select/menulist-appearance-basic-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/submit/submit-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/submit/submit-appearance-basic-expected.png index 89831e6..5dbae4d5 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/submit/submit-appearance-basic-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/submit/submit-appearance-basic-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/text/text-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/text/text-appearance-basic-expected.png index 67421b6..a6954eb 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/text/text-appearance-basic-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/text/text-appearance-basic-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/textarea/textarea-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/textarea/textarea-appearance-basic-expected.png index 1eb201b23..07a5a75 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/textarea/textarea-appearance-basic-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/textarea/textarea-appearance-basic-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/validation-bubble-appearance-edge-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/validation-bubble-appearance-edge-expected.png index eff64b9..20c5d18 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/validation-bubble-appearance-edge-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/validation-bubble-appearance-edge-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/validation-bubble-appearance-iframe-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/validation-bubble-appearance-iframe-expected.png index 9c71554d..00c725c35 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/validation-bubble-appearance-iframe-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/validation-bubble-appearance-iframe-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/validation-bubble-appearance-rtl-ui-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/validation-bubble-appearance-rtl-ui-expected.png index 146c1573..00239fef 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/validation-bubble-appearance-rtl-ui-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/validation-bubble-appearance-rtl-ui-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/text/shadow-translucent-fill-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/text/shadow-translucent-fill-expected.png index a867e4c..8637ef7 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/text/shadow-translucent-fill-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/text/shadow-translucent-fill-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/writing-mode/english-lr-text-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/writing-mode/english-lr-text-expected.png index 70f4093..570862ef 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/writing-mode/english-lr-text-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/writing-mode/english-lr-text-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/ietestcenter/css3/text/textshadow-001-expected.png b/third_party/WebKit/LayoutTests/platform/win/ietestcenter/css3/text/textshadow-001-expected.png index 9f51acc..d7f46e07 100644 --- a/third_party/WebKit/LayoutTests/platform/win/ietestcenter/css3/text/textshadow-001-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/ietestcenter/css3/text/textshadow-001-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/ietestcenter/css3/text/textshadow-002-expected.png b/third_party/WebKit/LayoutTests/platform/win/ietestcenter/css3/text/textshadow-002-expected.png index bde8eead..79d23e1 100644 --- a/third_party/WebKit/LayoutTests/platform/win/ietestcenter/css3/text/textshadow-002-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/ietestcenter/css3/text/textshadow-002-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/ietestcenter/css3/text/textshadow-003-expected.png b/third_party/WebKit/LayoutTests/platform/win/ietestcenter/css3/text/textshadow-003-expected.png index 06054cc..cb42ee9 100644 --- a/third_party/WebKit/LayoutTests/platform/win/ietestcenter/css3/text/textshadow-003-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/ietestcenter/css3/text/textshadow-003-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/ietestcenter/css3/text/textshadow-004-expected.png b/third_party/WebKit/LayoutTests/platform/win/ietestcenter/css3/text/textshadow-004-expected.png index c008a336..5b08376 100644 --- a/third_party/WebKit/LayoutTests/platform/win/ietestcenter/css3/text/textshadow-004-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/ietestcenter/css3/text/textshadow-004-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/ietestcenter/css3/text/textshadow-010-expected.png b/third_party/WebKit/LayoutTests/platform/win/ietestcenter/css3/text/textshadow-010-expected.png index 5863a56..cb7a60f1 100644 --- a/third_party/WebKit/LayoutTests/platform/win/ietestcenter/css3/text/textshadow-010-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/ietestcenter/css3/text/textshadow-010-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/inspector-protocol/input/dispatchMouseEvent-expected.txt b/third_party/WebKit/LayoutTests/platform/win/inspector-protocol/input/dispatchMouseEvent-expected.txt index 91036d1..0338f72 100644 --- a/third_party/WebKit/LayoutTests/platform/win/inspector-protocol/input/dispatchMouseEvent-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/win/inspector-protocol/input/dispatchMouseEvent-expected.txt
@@ -30,4 +30,11 @@ button: 2 x: 100 y: 200 +-----Event----- +type: mousewheel +button: 0 +x: 100 +y: 200 +deltaX: 50 +deltaY: 70
diff --git a/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/shadow-multiple-expected.png b/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/shadow-multiple-expected.png index 5b21835..5e53f36 100644 --- a/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/shadow-multiple-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/shadow-multiple-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/svg/repaint-shadow-expected.png b/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/svg/repaint-shadow-expected.png index 4684be0..75c1833 100644 --- a/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/svg/repaint-shadow-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/svg/repaint-shadow-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/paint/roundedrects/circle-with-shadow-expected.png b/third_party/WebKit/LayoutTests/platform/win/paint/roundedrects/circle-with-shadow-expected.png index 0d6cd097..67676dd7 100644 --- a/third_party/WebKit/LayoutTests/platform/win/paint/roundedrects/circle-with-shadow-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/paint/roundedrects/circle-with-shadow-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/paint/roundedrects/input-with-rounded-rect-and-shadow-expected.png b/third_party/WebKit/LayoutTests/platform/win/paint/roundedrects/input-with-rounded-rect-and-shadow-expected.png index e4234cb..51ac3cb 100644 --- a/third_party/WebKit/LayoutTests/platform/win/paint/roundedrects/input-with-rounded-rect-and-shadow-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/paint/roundedrects/input-with-rounded-rect-and-shadow-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/css/text-shadow-multiple-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/css/text-shadow-multiple-expected.png index cdc2ce5b..b920ba36 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/css/text-shadow-multiple-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/svg/css/text-shadow-multiple-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/transforms/shadows-expected.png b/third_party/WebKit/LayoutTests/platform/win/transforms/shadows-expected.png index 4221517d..86fd2c8 100644 --- a/third_party/WebKit/LayoutTests/platform/win/transforms/shadows-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/transforms/shadows-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/scalefactor150/fast/hidpi/static/calendar-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/scalefactor150/fast/hidpi/static/calendar-picker-appearance-expected.png index bb86572d..b78f63da 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/scalefactor150/fast/hidpi/static/calendar-picker-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/scalefactor150/fast/hidpi/static/calendar-picker-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/scalefactor200/fast/hidpi/static/calendar-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/scalefactor200/fast/hidpi/static/calendar-picker-appearance-expected.png index 1a6b12b..4a68c33a 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/scalefactor200/fast/hidpi/static/calendar-picker-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/scalefactor200/fast/hidpi/static/calendar-picker-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/scalefactor200withzoom/fast/hidpi/static/calendar-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/scalefactor200withzoom/fast/hidpi/static/calendar-picker-appearance-expected.png index 1a6b12b..4a68c33a 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/scalefactor200withzoom/fast/hidpi/static/calendar-picker-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/scalefactor200withzoom/fast/hidpi/static/calendar-picker-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/stable/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/platform/win/virtual/stable/webexposed/global-interface-listing-expected.txt index 444cf8e8..51a1d00 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/stable/webexposed/global-interface-listing-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/stable/webexposed/global-interface-listing-expected.txt
@@ -26,11 +26,6 @@ getter animationName getter elapsedTime method constructor -interface AppBannerPromptResult - attribute @@toStringTag - getter outcome - getter platform - method constructor interface ApplicationCache : EventTarget attribute @@toStringTag attribute CHECKING
diff --git a/third_party/WebKit/LayoutTests/platform/win7/compositing/shadows/shadow-drawing-expected.png b/third_party/WebKit/LayoutTests/platform/win7/compositing/shadows/shadow-drawing-expected.png index fa890d45..19d94c2 100644 --- a/third_party/WebKit/LayoutTests/platform/win7/compositing/shadows/shadow-drawing-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win7/compositing/shadows/shadow-drawing-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/fast/css/color-correction-on-text-shadow-expected.png b/third_party/WebKit/LayoutTests/platform/win7/fast/css/color-correction-on-text-shadow-expected.png index 5dfb9c8..42348af 100644 --- a/third_party/WebKit/LayoutTests/platform/win7/fast/css/color-correction-on-text-shadow-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win7/fast/css/color-correction-on-text-shadow-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/fast/css/shadow-multiple-expected.png b/third_party/WebKit/LayoutTests/platform/win7/fast/css/shadow-multiple-expected.png index 85e1596..da68cb5 100644 --- a/third_party/WebKit/LayoutTests/platform/win7/fast/css/shadow-multiple-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win7/fast/css/shadow-multiple-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png index 165aee9..6f16a3a 100644 --- a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png index c3e75273..1703dfd 100644 --- a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-expected.png index 2e49bbf..d683da2 100644 --- a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png index be108c3..cb800a9c8 100644 --- a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png index 28dc3ba..c81730b 100644 --- a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png index af7a4e8b..eafb8cd 100644 --- a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png index 6701d54e..dfd80b5a 100644 --- a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png index 3e7af0c..87f5b3d 100644 --- a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-zoom200-expected.png b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-zoom200-expected.png index 43aa22e8..77d919b 100644 --- a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-zoom200-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-zoom200-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/month-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/month-picker-appearance-expected.png index cd369cb9..dc129cf 100644 --- a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/month-picker-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/month-picker-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/month-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/month-picker-appearance-step-expected.png index ece940c3..8f3ff94 100644 --- a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/month-picker-appearance-step-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/month-picker-appearance-step-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/week-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/week-picker-appearance-expected.png index 19b9eed..ff17f1b 100644 --- a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/week-picker-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/week-picker-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/week-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/week-picker-appearance-step-expected.png index 2b3b31f..f395a3e 100644 --- a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/week-picker-appearance-step-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/week-picker-appearance-step-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/search/search-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/search/search-appearance-basic-expected.png index 550c0fdd..182a5726 100644 --- a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/search/search-appearance-basic-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/search/search-appearance-basic-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/fast/text/shadow-translucent-fill-expected.png b/third_party/WebKit/LayoutTests/platform/win7/fast/text/shadow-translucent-fill-expected.png index 41d72ef..ba5dc77 100644 --- a/third_party/WebKit/LayoutTests/platform/win7/fast/text/shadow-translucent-fill-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win7/fast/text/shadow-translucent-fill-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/ietestcenter/css3/text/textshadow-001-expected.png b/third_party/WebKit/LayoutTests/platform/win7/ietestcenter/css3/text/textshadow-001-expected.png index 974147a..927f4a1 100644 --- a/third_party/WebKit/LayoutTests/platform/win7/ietestcenter/css3/text/textshadow-001-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win7/ietestcenter/css3/text/textshadow-001-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/ietestcenter/css3/text/textshadow-002-expected.png b/third_party/WebKit/LayoutTests/platform/win7/ietestcenter/css3/text/textshadow-002-expected.png index b6e92e9b..64e0a51 100644 --- a/third_party/WebKit/LayoutTests/platform/win7/ietestcenter/css3/text/textshadow-002-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win7/ietestcenter/css3/text/textshadow-002-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/ietestcenter/css3/text/textshadow-003-expected.png b/third_party/WebKit/LayoutTests/platform/win7/ietestcenter/css3/text/textshadow-003-expected.png index 64a8cf9..af8f6a84 100644 --- a/third_party/WebKit/LayoutTests/platform/win7/ietestcenter/css3/text/textshadow-003-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win7/ietestcenter/css3/text/textshadow-003-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/ietestcenter/css3/text/textshadow-004-expected.png b/third_party/WebKit/LayoutTests/platform/win7/ietestcenter/css3/text/textshadow-004-expected.png index 02ee3bd4..0267eed4 100644 --- a/third_party/WebKit/LayoutTests/platform/win7/ietestcenter/css3/text/textshadow-004-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win7/ietestcenter/css3/text/textshadow-004-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/ietestcenter/css3/text/textshadow-010-expected.png b/third_party/WebKit/LayoutTests/platform/win7/ietestcenter/css3/text/textshadow-010-expected.png index b8dae3f4..b111a6e 100644 --- a/third_party/WebKit/LayoutTests/platform/win7/ietestcenter/css3/text/textshadow-010-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win7/ietestcenter/css3/text/textshadow-010-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/paint/invalidation/shadow-multiple-expected.png b/third_party/WebKit/LayoutTests/platform/win7/paint/invalidation/shadow-multiple-expected.png index c517e47..a1b9068 100644 --- a/third_party/WebKit/LayoutTests/platform/win7/paint/invalidation/shadow-multiple-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win7/paint/invalidation/shadow-multiple-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/paint/invalidation/svg/repaint-shadow-expected.png b/third_party/WebKit/LayoutTests/platform/win7/paint/invalidation/svg/repaint-shadow-expected.png index bcf2e4d..420278d 100644 --- a/third_party/WebKit/LayoutTests/platform/win7/paint/invalidation/svg/repaint-shadow-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win7/paint/invalidation/svg/repaint-shadow-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/svg/css/text-shadow-multiple-expected.png b/third_party/WebKit/LayoutTests/platform/win7/svg/css/text-shadow-multiple-expected.png index d4da7ef..92a0e5ce 100644 --- a/third_party/WebKit/LayoutTests/platform/win7/svg/css/text-shadow-multiple-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win7/svg/css/text-shadow-multiple-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/transforms/shadows-expected.png b/third_party/WebKit/LayoutTests/platform/win7/transforms/shadows-expected.png index 234138e4e..5eb695a54 100644 --- a/third_party/WebKit/LayoutTests/platform/win7/transforms/shadows-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win7/transforms/shadows-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/virtual/scalefactor150/fast/hidpi/static/calendar-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/win7/virtual/scalefactor150/fast/hidpi/static/calendar-picker-appearance-expected.png index ad1e738f..c41c9867 100644 --- a/third_party/WebKit/LayoutTests/platform/win7/virtual/scalefactor150/fast/hidpi/static/calendar-picker-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win7/virtual/scalefactor150/fast/hidpi/static/calendar-picker-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/virtual/scalefactor200/fast/hidpi/static/calendar-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/win7/virtual/scalefactor200/fast/hidpi/static/calendar-picker-appearance-expected.png index 5b9d962..41369fbe 100644 --- a/third_party/WebKit/LayoutTests/platform/win7/virtual/scalefactor200/fast/hidpi/static/calendar-picker-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win7/virtual/scalefactor200/fast/hidpi/static/calendar-picker-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/virtual/scalefactor200withzoom/fast/hidpi/static/calendar-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/win7/virtual/scalefactor200withzoom/fast/hidpi/static/calendar-picker-appearance-expected.png index 5b9d962..41369fbe 100644 --- a/third_party/WebKit/LayoutTests/platform/win7/virtual/scalefactor200withzoom/fast/hidpi/static/calendar-picker-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win7/virtual/scalefactor200withzoom/fast/hidpi/static/calendar-picker-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/resources/bluetooth/bluetooth-helpers.js b/third_party/WebKit/LayoutTests/resources/bluetooth/bluetooth-helpers.js index 240b102..a03175d 100644 --- a/third_party/WebKit/LayoutTests/resources/bluetooth/bluetooth-helpers.js +++ b/third_party/WebKit/LayoutTests/resources/bluetooth/bluetooth-helpers.js
@@ -486,33 +486,13 @@ // discovered. // TODO(crbug.com/719816): Add descriptors. function getHealthThermometerDevice(options) { - let device; - let fake_peripheral; - let fake_generic_access; - let fake_health_thermometer; - let fake_measurement_interval; - let fake_user_description; + let result; return getConnectedHealthThermometerDevice(options) - .then(result => { - ({ - device, - fake_peripheral, - fake_generic_access, - fake_health_thermometer, - fake_measurement_interval, - fake_user_description, - } = result); - }) - .then(() => fake_peripheral.setNextGATTDiscoveryResponse({ - code: HCI_SUCCESS})) - .then(() => ({ - device: device, - fake_peripheral: fake_peripheral, - fake_generic_access: fake_generic_access, - fake_health_thermometer: fake_health_thermometer, - fake_measurement_interval: fake_measurement_interval, - fake_user_description: fake_user_description, - })); + .then(_ => result = _) + .then(() => result.fake_peripheral.setNextGATTDiscoveryResponse({ + code: HCI_SUCCESS, + })) + .then(() => result); } // Similar to getHealthThermometerDevice except that the peripheral has @@ -585,93 +565,108 @@ })); } +// Populates a fake_peripheral with various fakes appropriate for a health +// thermometer. This resolves to an associative array composed of the fakes, +// including the |fake_peripheral|. +function populateHealthThermometerFakes(fake_peripheral) { + let fake_generic_access, fake_health_thermometer, fake_measurement_interval, + fake_user_description, fake_temperature_measurement, + fake_temperature_type; + return fake_peripheral.addFakeService({uuid: 'generic_access'}) + .then(_ => fake_generic_access = _) + .then(() => fake_peripheral.addFakeService({ + uuid: 'health_thermometer', + })) + .then(_ => fake_health_thermometer = _) + .then(() => fake_health_thermometer.addFakeCharacteristic({ + uuid: 'measurement_interval', + properties: ['read', 'write', 'indicate'], + })) + .then(_ => fake_measurement_interval = _) + .then(() => fake_measurement_interval.addFakeDescriptor({ + uuid: 'gatt.characteristic_user_description', + })) + .then(_ => fake_user_description = _) + .then(() => fake_health_thermometer.addFakeCharacteristic({ + uuid: 'temperature_measurement', + properties: ['indicate'], + })) + .then(_ => fake_temperature_measurement = _) + .then(() => fake_health_thermometer.addFakeCharacteristic({ + uuid: 'temperature_type', + properties: ['read'], + })) + .then(_ => fake_temperature_type = _) + .then(() => ({ + fake_peripheral, + fake_generic_access, + fake_health_thermometer, + fake_measurement_interval, + fake_user_description, + fake_temperature_measurement, + fake_temperature_type, + })); +} + // Similar to getHealthThermometerDevice except the GATT discovery // response has not been set yet so more attributes can still be added. function getConnectedHealthThermometerDevice(options) { - let device; - let fake_peripheral; - let fake_generic_access; - let fake_health_thermometer; - let fake_measurement_interval; - let fake_user_description; - let fake_temperature_measurement; - let fake_temperature_type; + let device, fake_peripheral, fakes; return getDiscoveredHealthThermometerDevice(options) - .then(result => { - ({device, fake_peripheral} = result); - }) + .then(_ => ({device, fake_peripheral} = _)) .then(() => fake_peripheral.setNextGATTConnectionResponse({ - code: HCI_SUCCESS})) + code: HCI_SUCCESS, + })) + .then(() => populateHealthThermometerFakes(fake_peripheral)) + .then(_ => fakes = _) .then(() => device.gatt.connect()) - .then(() => fake_peripheral.addFakeService({uuid: 'generic_access'})) - .then(s => fake_generic_access = s) - .then(() => fake_peripheral.addFakeService({ - uuid: 'health_thermometer'})) - .then(s => fake_health_thermometer = s) - .then(() => fake_health_thermometer.addFakeCharacteristic({ - uuid: 'measurement_interval', properties: ['read', 'write', 'indicate']})) - .then(c => fake_measurement_interval = c) - .then(() => fake_measurement_interval.addFakeDescriptor({ - uuid: 'gatt.characteristic_user_description'})) - .then(d => fake_user_description = d) - .then(() => fake_health_thermometer.addFakeCharacteristic({ - uuid: 'temperature_measurement', properties: ['indicate']})) - .then(c => fake_temperature_measurement = c) - .then(() => fake_health_thermometer.addFakeCharacteristic({ - uuid: 'temperature_type', properties: ['read']})) - .then(c => fake_temperature_type = c) - .then(() => ({ - device: device, - fake_peripheral: fake_peripheral, - fake_generic_access: fake_generic_access, - fake_health_thermometer: fake_health_thermometer, - fake_measurement_interval: fake_measurement_interval, - fake_user_description: fake_user_description, - fake_temperature_measurement: fake_temperature_measurement, - fake_temperature_type: fake_temperature_type, - })); + .then(() => Object.assign({device}, fakes)); } // Returns the same device and fake peripheral as getHealthThermometerDevice() // after another frame (an iframe we insert) discovered the device, // connected to it and discovered its services. function getHealthThermometerDeviceWithServicesDiscovered(options) { + let device, fake_peripheral, fakes; return setUpPreconnectedDevice({ - address: '09:09:09:09:09:09', - name: 'Health Thermometer', - knownServiceUUIDs: ['generic_access', 'health_thermometer'], - }) - .then(fake_peripheral => { - return fake_peripheral.setNextGATTConnectionResponse({code: HCI_SUCCESS}) - .then(() => fake_peripheral.setNextGATTDiscoveryResponse({ - code: HCI_SUCCESS})) - .then(() => new Promise(resolve => { - let iframe = document.createElement('iframe'); - let messageHandler = messageEvent => { - if (messageEvent.data === 'Ready') { - callWithKeyDown(() => iframe.contentWindow.postMessage({ - type: 'DiscoverServices', - options: options - }, '*')); - } else if (messageEvent.data === 'DiscoveryComplete') { - window.removeEventListener('message', messageHandler); - resolve(); - } else { - console.log(messageEvent.data); - } - } - window.addEventListener('message', messageHandler); - iframe.src = - '../../../resources/bluetooth/health-thermometer-iframe.html'; - document.body.appendChild(iframe); - })) - .then(() => requestDeviceWithKeyDown(options)) - .then(device => device.gatt.connect()) - .then(gatt => ({ - device: gatt.device, - fake_peripheral: fake_peripheral - })); - }); + address: '09:09:09:09:09:09', + name: 'Health Thermometer', + knownServiceUUIDs: ['generic_access', 'health_thermometer'], + }) + .then(_ => fake_peripheral = _) + .then(() => fake_peripheral.setNextGATTConnectionResponse({ + code: HCI_SUCCESS, + })) + .then(() => fake_peripheral.setNextGATTDiscoveryResponse({ + code: HCI_SUCCESS, + })) + .then(() => populateHealthThermometerFakes(fake_peripheral)) + .then(_ => fakes = _) + .then(() => new Promise(resolve => { + let iframe = document.createElement('iframe'); + function messageHandler(messageEvent) { + if (messageEvent.data === 'Ready') { + callWithKeyDown(() => iframe.contentWindow.postMessage({ + type: 'DiscoverServices', + options: options + }, '*')); + } else if (messageEvent.data === 'DiscoveryComplete') { + window.removeEventListener('message', messageHandler); + resolve(); + } else { + console.log(messageEvent.data); + resolve(); + } + } + window.addEventListener('message', messageHandler); + iframe.src = + '../../../resources/bluetooth/health-thermometer-iframe.html'; + document.body.appendChild(iframe); + })) + .then(() => requestDeviceWithKeyDown(options)) + .then(_ => device = _) + .then(device => device.gatt.connect()) + .then(_ => Object.assign({device}, fakes)); } // Similar to getHealthThermometerDevice() except the device has no services,
diff --git a/third_party/WebKit/LayoutTests/svg/text/position-update-on-font-size-change-expected.html b/third_party/WebKit/LayoutTests/svg/text/position-update-on-font-size-change-expected.html new file mode 100644 index 0000000..f2bb1a4c1 --- /dev/null +++ b/third_party/WebKit/LayoutTests/svg/text/position-update-on-font-size-change-expected.html
@@ -0,0 +1,5 @@ +<!DOCTYPE html> + <script src="../../resources/ahem.js"></script> + <svg> + <text font-family="Ahem" font-size="100" fill="green"><tspan dy="0.8em">X</tspan></text> + </svg>
diff --git a/third_party/WebKit/LayoutTests/svg/text/position-update-on-font-size-change.html b/third_party/WebKit/LayoutTests/svg/text/position-update-on-font-size-change.html new file mode 100644 index 0000000..57fee834 --- /dev/null +++ b/third_party/WebKit/LayoutTests/svg/text/position-update-on-font-size-change.html
@@ -0,0 +1,11 @@ +<!DOCTYPE html> + <script src="../../resources/ahem.js"></script> + <script src="../../resources/run-after-layout-and-paint.js"></script> + <svg> + <text font-family="Ahem" font-size="10" fill="green"><tspan dy="0.8em">X</tspan></text> + </svg> + <script> + runAfterLayoutAndPaint(_ => { + document.querySelector('text').setAttribute('font-size', 100); + }, true); + </script>
diff --git a/third_party/WebKit/LayoutTests/virtual/android/fast/rootscroller/nested-rootscroller-browser-controls-bounds-hidden-expected.html b/third_party/WebKit/LayoutTests/virtual/android/fast/rootscroller/nested-rootscroller-browser-controls-bounds-hidden-expected.html new file mode 100644 index 0000000..3910d4f --- /dev/null +++ b/third_party/WebKit/LayoutTests/virtual/android/fast/rootscroller/nested-rootscroller-browser-controls-bounds-hidden-expected.html
@@ -0,0 +1,33 @@ +<!DOCTYPE html> +<meta name="viewport" content="width=device-width, user-scalable=no" /> +<style> + html, body { + height: 100%; + width: 100%; + margin: 0; + } + body { + background-color: #808080; + } + #bottom { + position: fixed; + left: 50px; + right: 50px; + height: 20px; + bottom: 0px; + background-color: coral; + z-index: 2; + } + #innerbottom { + position: fixed; + left: 100px; + right: 100px; + height: 30px; + bottom: 0px; + background-color: green; + z-index: 1; + } +</style> + +<div id="bottom"></div> +<div id="innerbottom"></div>
diff --git a/third_party/WebKit/LayoutTests/virtual/android/fast/rootscroller/nested-rootscroller-browser-controls-bounds-hidden.html b/third_party/WebKit/LayoutTests/virtual/android/fast/rootscroller/nested-rootscroller-browser-controls-bounds-hidden.html new file mode 100644 index 0000000..ffe35d5 --- /dev/null +++ b/third_party/WebKit/LayoutTests/virtual/android/fast/rootscroller/nested-rootscroller-browser-controls-bounds-hidden.html
@@ -0,0 +1,71 @@ +<!DOCTYPE html> +<meta name="viewport" content="width=device-width, user-scalable=no" /> +<script> + // Set the browser controls to be 100px and showing. + // NOTE: It is important that this test be run with the Android viewport + // flags turned on. + if (window.internals) { + window.internals.setBrowserControlsState(100, 0, true); + window.internals.setBrowserControlsShownRatio(0); + } + + addEventListener("load", function() { + var iframe = document.getElementById("iframe"); + document.rootScroller = iframe; + iframe.contentDocument.rootScroller = iframe.contentDocument.getElementById("scroller"); + }); +</script> +<style> + html, body { + height: 100%; + width: 100%; + margin: 0; + } + body { + background-color: red; + } + #iframe { + position: absolute; + width: 100%; + height: 100%; + border: 0; + } + #bottom { + position: fixed; + left: 50px; + right: 50px; + height: 20px; + bottom: 0px; + background-color: coral; + } +</style> + +<iframe id="iframe" srcdoc=" + <style> + html,body { + height: 100%; + width: 100%; + margin:0; + background-color: blue; + } + #scroller { + position: absolute; + width: 100%; + height: 100%; + background-color: #808080; + overflow: auto; + } + #bottom { + position: fixed; + left: 100px; + right: 100px; + height: 30px; + bottom: 0px; + background-color: green; + } + </style> + <div id='scroller'> + <div style='height:2000px'></div> + </div> + <div id='bottom'></div>"></iframe> +<div id="bottom"></div>
diff --git a/third_party/WebKit/LayoutTests/virtual/android/fast/rootscroller/nested-rootscroller-browser-controls-bounds-shown-expected.html b/third_party/WebKit/LayoutTests/virtual/android/fast/rootscroller/nested-rootscroller-browser-controls-bounds-shown-expected.html new file mode 100644 index 0000000..61139bd --- /dev/null +++ b/third_party/WebKit/LayoutTests/virtual/android/fast/rootscroller/nested-rootscroller-browser-controls-bounds-shown-expected.html
@@ -0,0 +1,42 @@ +<!DOCTYPE html> +<meta name="viewport" content="width=device-width, user-scalable=no" /> +<style> + html, body { + height: 100%; + width: 100%; + margin: 0; + } + body { + background-color: white; + } + #bottom { + position: fixed; + left: 50px; + right: 50px; + height: 20px; + bottom: 0px; + background-color: coral; + z-index: 2; + } + #innerbottom { + position: fixed; + left: 100px; + right: 100px; + height: 30px; + bottom: 0px; + background-color: green; + z-index: 1; + } + #container { + width: 100%; + height: 500px; + background-color: #808080; + transform: translateZ(0); + } +</style> + +<div id="container"> + <div id="bottom"></div> + <div id="innerbottom"></div> + <div style="height: 2000px"></div> +</div>
diff --git a/third_party/WebKit/LayoutTests/virtual/android/fast/rootscroller/nested-rootscroller-browser-controls-bounds-shown.html b/third_party/WebKit/LayoutTests/virtual/android/fast/rootscroller/nested-rootscroller-browser-controls-bounds-shown.html new file mode 100644 index 0000000..ba19c0c --- /dev/null +++ b/third_party/WebKit/LayoutTests/virtual/android/fast/rootscroller/nested-rootscroller-browser-controls-bounds-shown.html
@@ -0,0 +1,71 @@ +<!DOCTYPE html> +<meta name="viewport" content="width=device-width, user-scalable=no" /> +<script> + // Set the browser controls to be 100px and showing. + // NOTE: It is important that this test be run with the Android viewport + // flags turned on. + if (window.internals) { + window.internals.setBrowserControlsState(100, 0, false); + window.internals.setBrowserControlsShownRatio(1); + } + + addEventListener("load", function() { + var iframe = document.getElementById("iframe"); + document.rootScroller = iframe; + iframe.contentDocument.rootScroller = iframe.contentDocument.getElementById("scroller"); + }); +</script> +<style> + html, body { + height: 100%; + width: 100%; + margin: 0; + } + body { + background-color: red; + } + #iframe { + position: absolute; + width: 100%; + height: 100%; + border: 0; + } + #bottom { + position: fixed; + left: 50px; + right: 50px; + height: 20px; + bottom: 0px; + background-color: coral; + } +</style> + +<iframe id="iframe" srcdoc=" + <style> + html,body { + height: 100%; + width: 100%; + margin:0; + background-color: blue; + } + #scroller { + position: absolute; + width: 100%; + height: 100%; + background-color: #808080; + overflow: auto; + } + #bottom { + position: fixed; + left: 100px; + right: 100px; + height: 30px; + bottom: 0px; + background-color: green; + } + </style> + <div id='scroller'> + <div style='height:2000px'></div> + </div> + <div id='bottom'></div>"></iframe> +<div id="bottom"></div>
diff --git a/third_party/WebKit/LayoutTests/webaudio/constructor/dynamicscompressor.html b/third_party/WebKit/LayoutTests/webaudio/constructor/dynamicscompressor.html index c225f976..330206b05 100644 --- a/third_party/WebKit/LayoutTests/webaudio/constructor/dynamicscompressor.html +++ b/third_party/WebKit/LayoutTests/webaudio/constructor/dynamicscompressor.html
@@ -49,7 +49,86 @@ }); audit.define('test AudioNodeOptions', (task, should) => { - testAudioNodeOptions(should, context, 'DynamicsCompressorNode'); + // Can't use testAudioNodeOptions because the constraints for this node + // are not supported there. + + // Array of test options to be run. Each entry is a dictionary where + // |testAttribute| is the name of the attribute to be tested, + // |testValue| is the value to be used, and |expectedErrorType| is the + // error type if the test is expected to throw an error. + // |expectedErrorType| should be set only if the test does throw. + let testOptions = [ + // Test channel count + { + testAttribute: 'channelCount', + testValue: 1, + }, + { + testAttribute: 'channelCount', + testValue: 2, + }, + { + testAttribute: 'channelCount', + testValue: 0, + expectedErrorType: 'NotSupportedError' + }, + { + testAttribute: 'channelCount', + testValue: 3, + expectedErrorType: 'NotSupportedError' + }, + { + testAttribute: 'channelCount', + testValue: 99, + expectedErrorType: 'NotSupportedError' + }, + // Test channel count mode + { + testAttribute: 'channelCountMode', + testValue: 'clamped-max', + }, + { + testAttribute: 'channelCountMode', + testValue: 'explicit', + }, + { + testAttribute: 'channelCountMode', + testValue: 'max', + expectedErrorType: 'NotSupportedError' + }, + { + testAttribute: 'channelCountMode', + testValue: 'foobar', + expectedErrorType: 'TypeError' + }, + // Test channel interpretation + { + testAttribute: 'channelInterpretation', + testValue: 'speakers', + }, + { + testAttribute: 'channelInterpretation', + testValue: 'discrete', + }, + { + testAttribute: 'channelInterpretation', + testValue: 'foobar', + expectedErrorType: 'TypeError' + } + ]; + + testOptions.forEach((option) => { + let nodeOptions = {}; + nodeOptions[option.testAttribute] = option.testValue; + + testNode(should, context, { + nodeOptions: nodeOptions, + testAttribute: option.testAttribute, + expectedValue: option.testValue, + expectedErrorType: option.expectedErrorType + }); + }); + task.done(); }); @@ -89,6 +168,29 @@ }); audit.run(); + + // Test possible options for DynamicsCompressor constructor. + function testNode(should, context, options) { + // Node to be tested + let node; + + let createNodeFunction = () => { + return () => node = + new DynamicsCompressorNode(context, options.nodeOptions); + }; + + let message = 'new DynamicsCompressorNode(c, ' + + JSON.stringify(options.nodeOptions) + ')'; + + if (options.expectedErrorType) { + should(createNodeFunction(), message) + .throw(options.expectedErrorType); + } else { + should(createNodeFunction(), message).notThrow(); + should(node[options.testAttribute], 'node.' + options.testAttribute) + .beEqualTo(options.expectedValue); + } + } </script> </body> </html>
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt index ff1ddb4..c26092c 100644 --- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt +++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
@@ -217,11 +217,6 @@ attribute @@toStringTag getter currentTime method constructor -interface AppBannerPromptResult - attribute @@toStringTag - getter outcome - getter platform - method constructor interface ApplicationCache : EventTarget attribute @@toStringTag attribute CHECKING
diff --git a/third_party/WebKit/Source/bindings/templates/methods.cpp.tmpl b/third_party/WebKit/Source/bindings/templates/methods.cpp.tmpl index cd4e1990..6df9af8 100644 --- a/third_party/WebKit/Source/bindings/templates/methods.cpp.tmpl +++ b/third_party/WebKit/Source/bindings/templates/methods.cpp.tmpl
@@ -494,7 +494,7 @@ {##############################################################################} {% macro method_callback(method, world_suffix) %} void {{v8_class_or_partial}}::{{method.name}}MethodCallback{{world_suffix}}(const v8::FunctionCallbackInfo<v8::Value>& info) { - {% if method.extended_attribute_defined %} + {% if method.runtime_call_stats.extended_attribute_defined %} {{ runtime_timer_scope(method.runtime_call_stats.method_counter) | indent(2) }} {% else %} {{ runtime_timer_scope_disabled_by_default(method.runtime_call_stats.method_counter) }}
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestObject.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestObject.cpp index b1be1571..6644805c 100644 --- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestObject.cpp +++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestObject.cpp
@@ -13265,8 +13265,7 @@ } void V8TestObject::RuntimeCallStatsCounterMethodMethodCallback(const v8::FunctionCallbackInfo<v8::Value>& info) { - RUNTIME_CALL_TIMER_SCOPE_DISABLED_BY_DEFAULT(info.GetIsolate(), "kRuntimeCallStatsCounterMethod"); - + RUNTIME_CALL_TIMER_SCOPE(info.GetIsolate(), RuntimeCallStats::CounterId::kRuntimeCallStatsCounterMethod); TestObjectV8Internal::RuntimeCallStatsCounterMethodMethod(info); }
diff --git a/third_party/WebKit/Source/core/BUILD.gn b/third_party/WebKit/Source/core/BUILD.gn index ef7bd85..44fb9ca 100644 --- a/third_party/WebKit/Source/core/BUILD.gn +++ b/third_party/WebKit/Source/core/BUILD.gn
@@ -549,7 +549,6 @@ "$blink_core_output_dir/css/properties/CSSPropertyAPIMask.h", "$blink_core_output_dir/css/properties/CSSPropertyAPIMaskSourceType.h", "$blink_core_output_dir/css/properties/CSSPropertyAPIMaxWidthOrHeight.h", - "$blink_core_output_dir/css/properties/CSSPropertyAPIMinWidthOrHeight.h", "$blink_core_output_dir/css/properties/CSSPropertyAPIObjectPosition.h", "$blink_core_output_dir/css/properties/CSSPropertyAPIOffset.h", "$blink_core_output_dir/css/properties/CSSPropertyAPIOffsetAnchor.h", @@ -1309,6 +1308,7 @@ "css/invalidation/StyleInvalidatorTest.cpp", "css/parser/CSSLazyParsingTest.cpp", "css/parser/CSSParserFastPathsTest.cpp", + "css/parser/CSSParserTokenStreamTest.cpp", "css/parser/CSSParserTokenTest.cpp", "css/parser/CSSPropertyParserTest.cpp", "css/parser/CSSSelectorParserTest.cpp",
diff --git a/third_party/WebKit/Source/core/css/BUILD.gn b/third_party/WebKit/Source/core/css/BUILD.gn index 7205daa..41c51b1 100644 --- a/third_party/WebKit/Source/core/css/BUILD.gn +++ b/third_party/WebKit/Source/core/css/BUILD.gn
@@ -351,6 +351,7 @@ "parser/CSSParserToken.h", "parser/CSSParserTokenRange.cpp", "parser/CSSParserTokenRange.h", + "parser/CSSParserTokenStream.cpp", "parser/CSSParserTokenStream.h", "parser/CSSPropertyParser.cpp", "parser/CSSPropertyParser.h", @@ -451,7 +452,6 @@ "properties/CSSPropertyAPIMarker.cpp", "properties/CSSPropertyAPIMask.cpp", "properties/CSSPropertyAPIMaskSourceType.cpp", - "properties/CSSPropertyAPIMinWidthOrHeight.cpp", "properties/CSSPropertyAPIObjectPosition.cpp", "properties/CSSPropertyAPIOffset.cpp", "properties/CSSPropertyAPIOffsetAnchor.cpp",
diff --git a/third_party/WebKit/Source/core/css/CSSProperties.json5 b/third_party/WebKit/Source/core/css/CSSProperties.json5 index 7e1c5d4..769ae8cb 100644 --- a/third_party/WebKit/Source/core/css/CSSProperties.json5 +++ b/third_party/WebKit/Source/core/css/CSSProperties.json5
@@ -1534,6 +1534,7 @@ { name: "height", api_class: "CSSPropertyAPIWidthOrHeight", + api_methods: ["ParseSingleValue"], converter: "ConvertLengthSizing", is_descriptor: true, interpolable: true, @@ -1817,7 +1818,8 @@ }, { name: "min-height", - api_class: "CSSPropertyAPIMinWidthOrHeight", + api_class: "CSSPropertyAPIWidthOrHeight", + api_methods: ["ParseSingleValue"], converter: "ConvertLengthSizing", is_descriptor: true, interpolable: true, @@ -1827,7 +1829,8 @@ }, { name: "min-width", - api_class: "CSSPropertyAPIMinWidthOrHeight", + api_class: "CSSPropertyAPIWidthOrHeight", + api_methods: ["ParseSingleValue"], converter: "ConvertLengthSizing", is_descriptor: true, interpolable: true, @@ -3547,6 +3550,7 @@ { name: "width", api_class: "CSSPropertyAPIWidthOrHeight", + api_methods: ["ParseSingleValue"], converter: "ConvertLengthSizing", is_descriptor: true, interpolable: true,
diff --git a/third_party/WebKit/Source/core/css/parser/CSSParserImpl.cpp b/third_party/WebKit/Source/core/css/parser/CSSParserImpl.cpp index 9d9803f..5e68393 100644 --- a/third_party/WebKit/Source/core/css/parser/CSSParserImpl.cpp +++ b/third_party/WebKit/Source/core/css/parser/CSSParserImpl.cpp
@@ -169,8 +169,7 @@ CSSParserImpl parser(context, document.ElementSheet().Contents()); CSSTokenizer tokenizer(string); CSSParserTokenStream stream(tokenizer); - // TODO(shend): Use streams instead of ranges - parser.ConsumeDeclarationList(stream.MakeRangeToEOF(), StyleRule::kStyle); + parser.ConsumeDeclarationList(stream, StyleRule::kStyle); return CreateStylePropertySet(parser.parsed_properties_, mode); } @@ -183,8 +182,7 @@ rule_type = StyleRule::kViewport; CSSTokenizer tokenizer(string); CSSParserTokenStream stream(tokenizer); - // TODO(shend): Use streams instead of ranges - parser.ConsumeDeclarationList(stream.MakeRangeToEOF(), rule_type); + parser.ConsumeDeclarationList(stream, rule_type); if (parser.parsed_properties_.IsEmpty()) return false; @@ -848,6 +846,57 @@ CreateStylePropertySet(parsed_properties_, context_->Mode())); } +void CSSParserImpl::ConsumeDeclarationList(CSSParserTokenStream& stream, + StyleRule::RuleType rule_type) { + DCHECK(parsed_properties_.IsEmpty()); + + bool use_observer = observer_wrapper_ && (rule_type == StyleRule::kStyle || + rule_type == StyleRule::kKeyframe); + DCHECK(!use_observer); // TODO(shend): Implement streaming with observers. + + while (!stream.AtEnd()) { + switch (stream.UncheckedPeek().GetType()) { + case kWhitespaceToken: + case kSemicolonToken: + stream.UncheckedConsume(); + break; + case kIdentToken: { + // TODO(shend): Use streams instead of ranges + auto range = stream.MakeRangeToEOF(); + + const CSSParserToken* declaration_start = &range.Peek(); + while (!range.AtEnd() && range.Peek().GetType() != kSemicolonToken) + range.ConsumeComponentValue(); + + ConsumeDeclaration(range.MakeSubRange(declaration_start, &range.Peek()), + rule_type); + + stream.UpdatePositionFromRange(range); + break; + } + case kAtKeywordToken: { + AllowedRulesType allowed_rules = + rule_type == StyleRule::kStyle && + RuntimeEnabledFeatures::CSSApplyAtRulesEnabled() + ? kApplyRules + : kNoRules; + + // TODO(shend): Use streams instead of ranges + auto range = stream.MakeRangeToEOF(); + StyleRuleBase* rule = ConsumeAtRule(range, allowed_rules); + stream.UpdatePositionFromRange(range); + DCHECK(!rule); + break; + } + default: // Parse error, unexpected token in declaration list + while (!stream.AtEnd() && + stream.UncheckedPeek().GetType() != kSemicolonToken) + stream.UncheckedConsumeComponentValue(); + break; + } + } +} + void CSSParserImpl::ConsumeDeclarationList(CSSParserTokenRange range, StyleRule::RuleType rule_type) { DCHECK(parsed_properties_.IsEmpty());
diff --git a/third_party/WebKit/Source/core/css/parser/CSSParserImpl.h b/third_party/WebKit/Source/core/css/parser/CSSParserImpl.h index df169ad..a467eea3f 100644 --- a/third_party/WebKit/Source/core/css/parser/CSSParserImpl.h +++ b/third_party/WebKit/Source/core/css/parser/CSSParserImpl.h
@@ -21,6 +21,7 @@ class CSSParserContext; class CSSParserObserver; class CSSParserObserverWrapper; +class CSSParserTokenStream; class StyleRule; class StyleRuleBase; class StyleRuleCharset; @@ -140,6 +141,8 @@ StyleRule* ConsumeStyleRule(CSSParserTokenRange prelude, CSSParserTokenRange block); + void ConsumeDeclarationList(CSSParserTokenStream&, StyleRule::RuleType); + // TODO(shend): Remove this overload once we switch over to streams. void ConsumeDeclarationList(CSSParserTokenRange, StyleRule::RuleType); void ConsumeDeclaration(CSSParserTokenRange, StyleRule::RuleType); void ConsumeDeclarationValue(CSSParserTokenRange,
diff --git a/third_party/WebKit/Source/core/css/parser/CSSParserTokenStream.cpp b/third_party/WebKit/Source/core/css/parser/CSSParserTokenStream.cpp new file mode 100644 index 0000000..0a2eaf1 --- /dev/null +++ b/third_party/WebKit/Source/core/css/parser/CSSParserTokenStream.cpp
@@ -0,0 +1,20 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "core/css/parser/CSSParserTokenStream.h" + +namespace blink { + +void CSSParserTokenStream::UncheckedConsumeComponentValue() { + unsigned nesting_level = 0; + do { + const CSSParserToken& token = UncheckedConsume(); + if (token.GetBlockType() == CSSParserToken::kBlockStart) + nesting_level++; + else if (token.GetBlockType() == CSSParserToken::kBlockEnd) + nesting_level--; + } while (nesting_level && !AtEnd()); +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/core/css/parser/CSSParserTokenStream.h b/third_party/WebKit/Source/core/css/parser/CSSParserTokenStream.h index ba4c05b..6f085979 100644 --- a/third_party/WebKit/Source/core/css/parser/CSSParserTokenStream.h +++ b/third_party/WebKit/Source/core/css/parser/CSSParserTokenStream.h
@@ -6,23 +6,76 @@ #define CSSParserTokenStream_h #include "CSSTokenizer.h" +#include "core/css/parser/CSSParserTokenRange.h" namespace blink { // A streaming interface to CSSTokenizer that tokenizes on demand. -class CSSParserTokenStream { +// Methods prefixed with "Unchecked" can only be called after Peek() +// returns a non-EOF token or after AtEnd() returns false, with no +// subsequent modifications to the stream such as a consume. +class CORE_EXPORT CSSParserTokenStream { DISALLOW_NEW(); public: explicit CSSParserTokenStream(CSSTokenizer& tokenizer) - : tokenizer_(tokenizer) { + : tokenizer_(tokenizer), next_index_(0) { DCHECK_EQ(tokenizer.tokens_.size(), 0U); } - CSSParserTokenRange MakeRangeToEOF() { return tokenizer_.TokenRange(); } + // TODO(shend): Remove this method. We should never convert from a range to a + // stream. We can remove this once all the functions in CSSParserImpl.h accept + // streams. + void UpdatePositionFromRange(const CSSParserTokenRange& range) { + next_index_ = range.begin() - tokenizer_.tokens_.begin(); + } + + const CSSParserToken& Peek() const { + if (next_index_ == tokenizer_.tokens_.size()) { + // Reached end of token buffer, but might not be end of input. + if (tokenizer_.TokenizeSingle().IsEOF()) + return g_static_eof_token; + } + DCHECK_LT(next_index_, tokenizer_.tokens_.size()); + return UncheckedPeek(); + } + + const CSSParserToken& UncheckedPeek() const { + DCHECK_LT(next_index_, tokenizer_.tokens_.size()); + return tokenizer_.tokens_[next_index_]; + } + + const CSSParserToken& Consume() { + const CSSParserToken& token = Peek(); + if (!token.IsEOF()) + next_index_++; + + DCHECK_LE(next_index_, tokenizer_.tokens_.size()); + return token; + } + + const CSSParserToken& UncheckedConsume() { + DCHECK_LE(next_index_, tokenizer_.tokens_.size()); + return tokenizer_.tokens_[next_index_++]; + } + + bool AtEnd() const { return Peek().IsEOF(); } + + // Range represents all tokens from current position to EOF. + // Eagerly consumes all the remaining input. + // TODO(shend): Remove this method once we switch over to using streams + // completely. + CSSParserTokenRange MakeRangeToEOF() { + const auto range = tokenizer_.TokenRange(); + return range.MakeSubRange(tokenizer_.tokens_.begin() + next_index_, + tokenizer_.tokens_.end()); + } + + void UncheckedConsumeComponentValue(); private: CSSTokenizer& tokenizer_; + size_t next_index_; // Index of next token to be consumed. }; } // namespace blink
diff --git a/third_party/WebKit/Source/core/css/parser/CSSParserTokenStreamTest.cpp b/third_party/WebKit/Source/core/css/parser/CSSParserTokenStreamTest.cpp new file mode 100644 index 0000000..1c9152b3 --- /dev/null +++ b/third_party/WebKit/Source/core/css/parser/CSSParserTokenStreamTest.cpp
@@ -0,0 +1,110 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "core/css/parser/CSSParserTokenStream.h" + +#include "testing/gtest/include/gtest/gtest.h" + +namespace blink { + +TEST(CSSParserTokenStreamTest, EmptyStream) { + CSSTokenizer tokenizer(""); + CSSParserTokenStream stream(tokenizer); + EXPECT_TRUE(stream.Consume().IsEOF()); + EXPECT_TRUE(stream.Peek().IsEOF()); + EXPECT_TRUE(stream.AtEnd()); + EXPECT_TRUE(stream.MakeRangeToEOF().AtEnd()); +} + +TEST(CSSParserTokenStreamTest, PeekThenConsume) { + CSSTokenizer tokenizer("A"); // kIdent + CSSParserTokenStream stream(tokenizer); + EXPECT_EQ(kIdentToken, stream.Peek().GetType()); + EXPECT_EQ(kIdentToken, stream.Consume().GetType()); + EXPECT_TRUE(stream.AtEnd()); +} + +TEST(CSSParserTokenStreamTest, ConsumeThenPeek) { + CSSTokenizer tokenizer("A"); // kIdent + CSSParserTokenStream stream(tokenizer); + EXPECT_EQ(kIdentToken, stream.Consume().GetType()); + EXPECT_TRUE(stream.AtEnd()); +} + +TEST(CSSParserTokenStreamTest, ConsumeMultipleTokens) { + CSSTokenizer tokenizer("A 1"); // kIdent kWhitespace kNumber + CSSParserTokenStream stream(tokenizer); + EXPECT_EQ(kIdentToken, stream.Consume().GetType()); + EXPECT_EQ(kWhitespaceToken, stream.Consume().GetType()); + EXPECT_EQ(kNumberToken, stream.Consume().GetType()); + EXPECT_TRUE(stream.AtEnd()); +} + +TEST(CSSParserTokenStreamTest, UncheckedPeekAndConsumeAfterPeek) { + CSSTokenizer tokenizer("A"); // kIdent + CSSParserTokenStream stream(tokenizer); + EXPECT_EQ(kIdentToken, stream.Peek().GetType()); + EXPECT_EQ(kIdentToken, stream.UncheckedPeek().GetType()); + EXPECT_EQ(kIdentToken, stream.UncheckedConsume().GetType()); + EXPECT_TRUE(stream.AtEnd()); +} + +TEST(CSSParserTokenStreamTest, UncheckedPeekAndConsumeAfterAtEnd) { + CSSTokenizer tokenizer("A"); // kIdent + CSSParserTokenStream stream(tokenizer); + EXPECT_FALSE(stream.AtEnd()); + EXPECT_EQ(kIdentToken, stream.UncheckedPeek().GetType()); + EXPECT_EQ(kIdentToken, stream.UncheckedConsume().GetType()); + EXPECT_TRUE(stream.AtEnd()); +} + +TEST(CSSParserTokenStreamTest, MakeRangeToEOF) { + CSSTokenizer tokenizer("A 1"); // kIdent kWhitespace kNumber + CSSParserTokenStream stream(tokenizer); + EXPECT_EQ(kIdentToken, stream.Consume().GetType()); + + auto range = stream.MakeRangeToEOF(); + EXPECT_FALSE(stream.AtEnd()); + EXPECT_EQ(kWhitespaceToken, range.Consume().GetType()); + EXPECT_FALSE(stream.AtEnd()); + EXPECT_EQ(kNumberToken, range.Consume().GetType()); + EXPECT_TRUE(range.AtEnd()); + + EXPECT_FALSE(stream.AtEnd()); +} + +TEST(CSSParserTokenStreamTest, MakeLargeRangeToEOF) { + String s = ""; + for (int i = 0; i < 100; i++) + s.append("A "); + + CSSTokenizer tokenizer(s); + CSSParserTokenStream stream(tokenizer); + + auto range = stream.MakeRangeToEOF(); + while (!range.AtEnd()) { + EXPECT_EQ(kIdentToken, range.Consume().GetType()); + EXPECT_EQ(kWhitespaceToken, range.Consume().GetType()); + } + + EXPECT_FALSE(stream.AtEnd()); +} + +TEST(CSSParserTokenStreamTest, UncheckedConsumeComponentValue) { + CSSTokenizer tokenizer("A{1}{2{3}}B"); + CSSParserTokenStream stream(tokenizer); + + EXPECT_EQ(kIdentToken, stream.Peek().GetType()); + stream.UncheckedConsumeComponentValue(); + EXPECT_EQ(kLeftBraceToken, stream.Peek().GetType()); + stream.UncheckedConsumeComponentValue(); + EXPECT_EQ(kLeftBraceToken, stream.Peek().GetType()); + stream.UncheckedConsumeComponentValue(); + EXPECT_EQ(kIdentToken, stream.Peek().GetType()); + stream.UncheckedConsumeComponentValue(); + + EXPECT_TRUE(stream.AtEnd()); +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp index ef4185dc..7caa6884 100644 --- a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp +++ b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
@@ -409,12 +409,6 @@ case CSSPropertyMaxHeight: return CSSPropertyLengthUtils::ConsumeMaxWidthOrHeight( range_, *context_, UnitlessQuirk::kAllow); - case CSSPropertyMinWidth: - case CSSPropertyMinHeight: - case CSSPropertyWidth: - case CSSPropertyHeight: - return CSSPropertyLengthUtils::ConsumeWidthOrHeight( - range_, *context_, UnitlessQuirk::kAllow); case CSSPropertyTextDecoration: DCHECK(!RuntimeEnabledFeatures::CSS3TextDecorationsEnabled()); return CSSPropertyTextDecorationLineUtils::ConsumeTextDecorationLine( @@ -862,7 +856,8 @@ CSSPropertyDescriptor::Get(property); if (css_property_desc.ParseShorthand) { return css_property_desc.ParseShorthand( - important, range_, *context_, isPropertyAlias(unresolved_property), + important, range_, *context_, + CSSParserLocalContext(isPropertyAlias(unresolved_property), property), *parsed_properties_); }
diff --git a/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIMethods.json5 b/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIMethods.json5 index 0f00918..a244e0f5 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIMethods.json5 +++ b/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIMethods.json5
@@ -35,7 +35,7 @@ { name: "ParseShorthand", return_type: "bool", - parameters: "(bool, CSSParserTokenRange&, const CSSParserContext&, bool, HeapVector<CSSProperty, 256>&)", + parameters: "(bool, CSSParserTokenRange&, const CSSParserContext&, const CSSParserLocalContext&, HeapVector<CSSProperty, 256>&)", description: "Returns true if the property can be parsed as a shorthand.", }, ]
diff --git a/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIMinWidthOrHeight.cpp b/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIMinWidthOrHeight.cpp deleted file mode 100644 index 1259251..0000000 --- a/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIMinWidthOrHeight.cpp +++ /dev/null
@@ -1,7 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "core/css/properties/CSSPropertyAPIMinWidthOrHeight.h" - -namespace blink {} // namespace blink
diff --git a/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIWidthOrHeight.cpp b/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIWidthOrHeight.cpp index 393f3e2..73d4231 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIWidthOrHeight.cpp +++ b/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIWidthOrHeight.cpp
@@ -4,4 +4,18 @@ #include "core/css/properties/CSSPropertyAPIWidthOrHeight.h" -namespace blink {} // namespace blink +#include "core/css/parser/CSSPropertyParserHelpers.h" +#include "core/css/properties/CSSPropertyLengthUtils.h" + +namespace blink { +class CSSParserLocalContext; + +const CSSValue* CSSPropertyAPIWidthOrHeight::ParseSingleValue( + CSSParserTokenRange& range, + const CSSParserContext& context, + const CSSParserLocalContext&) { + return CSSPropertyLengthUtils::ConsumeWidthOrHeight( + range, context, CSSPropertyParserHelpers::UnitlessQuirk::kAllow); +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIAnimation.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIAnimation.cpp index 657f94b..c104b953 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIAnimation.cpp +++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIAnimation.cpp
@@ -61,7 +61,7 @@ bool important, CSSParserTokenRange& range, const CSSParserContext& context, - bool use_legacy_parsing, + const CSSParserLocalContext& local_context, HeapVector<CSSProperty, 256>& properties) { const StylePropertyShorthand shorthand = animationShorthandForParsing(); const unsigned longhand_count = shorthand.length(); @@ -70,7 +70,7 @@ longhand_count); if (!CSSPropertyAnimationUtils::ConsumeAnimationShorthand( shorthand, longhands, ConsumeAnimationValue, range, context, - use_legacy_parsing)) { + local_context.UseAliasParsing())) { return false; }
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIBackgroundPosition.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIBackgroundPosition.cpp index 5f1c64f..aa805d305 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIBackgroundPosition.cpp +++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIBackgroundPosition.cpp
@@ -14,7 +14,7 @@ bool important, CSSParserTokenRange& range, const CSSParserContext& context, - bool, + const CSSParserLocalContext&, HeapVector<CSSProperty, 256>& properties) { CSSValue* result_x = nullptr; CSSValue* result_y = nullptr;
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIBorder.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIBorder.cpp index b95f80f2..a77e5f38 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIBorder.cpp +++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIBorder.cpp
@@ -14,7 +14,7 @@ bool important, CSSParserTokenRange& range, const CSSParserContext& context, - bool use_legacy_parsing, + const CSSParserLocalContext&, HeapVector<CSSProperty, 256>& properties) { CSSValue* width = nullptr; const CSSValue* style = nullptr;
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIBorderBottom.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIBorderBottom.cpp index 4653dc55..e38a285 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIBorderBottom.cpp +++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIBorderBottom.cpp
@@ -12,7 +12,7 @@ bool important, CSSParserTokenRange& range, const CSSParserContext& context, - bool, + const CSSParserLocalContext&, HeapVector<CSSProperty, 256>& properties) { return CSSPropertyParserHelpers::ConsumeShorthandGreedilyViaLonghandAPIs( borderBottomShorthand(), important, context, range, properties);
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIBorderColor.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIBorderColor.cpp index c7da66d..e12abe9 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIBorderColor.cpp +++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIBorderColor.cpp
@@ -13,7 +13,7 @@ bool important, CSSParserTokenRange& range, const CSSParserContext& context, - bool, + const CSSParserLocalContext&, HeapVector<CSSProperty, 256>& properties) { return CSSPropertyParserHelpers::ConsumeShorthandVia4LonghandAPIs( borderColorShorthand(), important, context, range, properties);
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIBorderImage.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIBorderImage.cpp index 7153ba8..532f29c 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIBorderImage.cpp +++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIBorderImage.cpp
@@ -15,7 +15,7 @@ bool important, CSSParserTokenRange& range, const CSSParserContext& context, - bool, + const CSSParserLocalContext&, HeapVector<CSSProperty, 256>& properties) { CSSValue* source = nullptr; CSSValue* slice = nullptr;
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIBorderLeft.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIBorderLeft.cpp index af0cf44..ec977e42 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIBorderLeft.cpp +++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIBorderLeft.cpp
@@ -12,7 +12,7 @@ bool important, CSSParserTokenRange& range, const CSSParserContext& context, - bool, + const CSSParserLocalContext&, HeapVector<CSSProperty, 256>& properties) { return CSSPropertyParserHelpers::ConsumeShorthandGreedilyViaLonghandAPIs( borderLeftShorthand(), important, context, range, properties);
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIBorderRadius.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIBorderRadius.cpp index 2f79e96..0bc570f 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIBorderRadius.cpp +++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIBorderRadius.cpp
@@ -6,6 +6,7 @@ #include "core/css/CSSValuePair.h" #include "core/css/parser/CSSParserContext.h" +#include "core/css/parser/CSSParserLocalContext.h" #include "core/css/parser/CSSPropertyParserHelpers.h" #include "core/css/properties/CSSPropertyShapeUtils.h" @@ -15,14 +16,14 @@ bool important, CSSParserTokenRange& range, const CSSParserContext& context, - bool use_alias_parsing, + const CSSParserLocalContext& local_context, HeapVector<CSSProperty, 256>& properties) { CSSValue* horizontal_radii[4] = {0}; CSSValue* vertical_radii[4] = {0}; if (!CSSPropertyShapeUtils::ConsumeRadii(horizontal_radii, vertical_radii, range, context.Mode(), - use_alias_parsing)) + local_context.UseAliasParsing())) return false; CSSPropertyParserHelpers::AddProperty(
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIBorderRight.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIBorderRight.cpp index b05d477..3343944 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIBorderRight.cpp +++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIBorderRight.cpp
@@ -12,7 +12,7 @@ bool important, CSSParserTokenRange& range, const CSSParserContext& context, - bool, + const CSSParserLocalContext&, HeapVector<CSSProperty, 256>& properties) { return CSSPropertyParserHelpers::ConsumeShorthandGreedilyViaLonghandAPIs( borderRightShorthand(), important, context, range, properties);
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIBorderSpacing.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIBorderSpacing.cpp index 6fe7f770..81758f8 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIBorderSpacing.cpp +++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIBorderSpacing.cpp
@@ -13,7 +13,7 @@ bool important, CSSParserTokenRange& range, const CSSParserContext& context, - bool, + const CSSParserLocalContext&, HeapVector<CSSProperty, 256>& properties) { CSSValue* horizontal_spacing = ConsumeLength(range, context.Mode(), kValueRangeNonNegative,
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIBorderStyle.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIBorderStyle.cpp index 3defc8e..af348f7 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIBorderStyle.cpp +++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIBorderStyle.cpp
@@ -13,7 +13,7 @@ bool important, CSSParserTokenRange& range, const CSSParserContext& context, - bool, + const CSSParserLocalContext&, HeapVector<CSSProperty, 256>& properties) { return CSSPropertyParserHelpers::ConsumeShorthandVia4LonghandAPIs( borderStyleShorthand(), important, context, range, properties);
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIBorderTop.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIBorderTop.cpp index f07af355..4d6c457 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIBorderTop.cpp +++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIBorderTop.cpp
@@ -12,7 +12,7 @@ bool important, CSSParserTokenRange& range, const CSSParserContext& context, - bool, + const CSSParserLocalContext&, HeapVector<CSSProperty, 256>& properties) { return CSSPropertyParserHelpers::ConsumeShorthandGreedilyViaLonghandAPIs( borderTopShorthand(), important, context, range, properties);
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIBorderWidth.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIBorderWidth.cpp index 662daa2..5932d6e4 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIBorderWidth.cpp +++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIBorderWidth.cpp
@@ -13,7 +13,7 @@ bool important, CSSParserTokenRange& range, const CSSParserContext& context, - bool, + const CSSParserLocalContext&, HeapVector<CSSProperty, 256>& properties) { return CSSPropertyParserHelpers::ConsumeShorthandVia4LonghandAPIs( borderWidthShorthand(), important, context, range, properties);
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIColumnRule.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIColumnRule.cpp index 5d77a7f..cdff383 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIColumnRule.cpp +++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIColumnRule.cpp
@@ -12,7 +12,7 @@ bool important, CSSParserTokenRange& range, const CSSParserContext& context, - bool, + const CSSParserLocalContext&, HeapVector<CSSProperty, 256>& properties) { return CSSPropertyParserHelpers::ConsumeShorthandGreedilyViaLonghandAPIs( columnRuleShorthand(), important, context, range, properties);
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIColumns.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIColumns.cpp index 4f4c56e..950ad13 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIColumns.cpp +++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIColumns.cpp
@@ -15,7 +15,7 @@ bool important, CSSParserTokenRange& range, const CSSParserContext&, - bool, + const CSSParserLocalContext&, HeapVector<CSSProperty, 256>& properties) { CSSValue* column_width = nullptr; CSSValue* column_count = nullptr;
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIFlex.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIFlex.cpp index 2685fac1..e847bd0e 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIFlex.cpp +++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIFlex.cpp
@@ -15,7 +15,7 @@ bool important, CSSParserTokenRange& range, const CSSParserContext& context, - bool, + const CSSParserLocalContext&, HeapVector<CSSProperty, 256>& properties) { static const double kUnsetValue = -1; double flex_grow = kUnsetValue;
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIFlexFlow.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIFlexFlow.cpp index ef17033..8591e02 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIFlexFlow.cpp +++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIFlexFlow.cpp
@@ -12,7 +12,7 @@ bool important, CSSParserTokenRange& range, const CSSParserContext& context, - bool, + const CSSParserLocalContext&, HeapVector<CSSProperty, 256>& properties) { return CSSPropertyParserHelpers::ConsumeShorthandGreedilyViaLonghandAPIs( flexFlowShorthand(), important, context, range, properties);
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIFont.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIFont.cpp index 1db9c390..afcacd1 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIFont.cpp +++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIFont.cpp
@@ -217,7 +217,7 @@ bool important, CSSParserTokenRange& range, const CSSParserContext& context, - bool, + const CSSParserLocalContext&, HeapVector<CSSProperty, 256>& properties) { const CSSParserToken& token = range.Peek(); if (token.Id() >= CSSValueCaption && token.Id() <= CSSValueStatusBar)
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIFontVariant.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIFontVariant.cpp index 82234cf..5b1bd31 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIFontVariant.cpp +++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIFontVariant.cpp
@@ -15,7 +15,7 @@ bool important, CSSParserTokenRange& range, const CSSParserContext&, - bool, + const CSSParserLocalContext&, HeapVector<CSSProperty, 256>& properties) { if (CSSPropertyParserHelpers::IdentMatches<CSSValueNormal, CSSValueNone>( range.Peek().Id())) {
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIGrid.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIGrid.cpp index d7a20a5..54da62d 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIGrid.cpp +++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIGrid.cpp
@@ -41,7 +41,7 @@ bool important, CSSParserTokenRange& range, const CSSParserContext& context, - bool, + const CSSParserLocalContext&, HeapVector<CSSProperty, 256>& properties) { DCHECK(RuntimeEnabledFeatures::CSSGridLayoutEnabled()); DCHECK_EQ(shorthandForProperty(CSSPropertyGrid).length(), 8u);
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIGridArea.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIGridArea.cpp index 89fb562..7f5c47ee 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIGridArea.cpp +++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIGridArea.cpp
@@ -15,7 +15,7 @@ bool important, CSSParserTokenRange& range, const CSSParserContext&, - bool use_legacy_parsing, + const CSSParserLocalContext&, HeapVector<CSSProperty, 256>& properties) { DCHECK(RuntimeEnabledFeatures::CSSGridLayoutEnabled()); DCHECK_EQ(gridAreaShorthand().length(), 4u);
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIGridColumn.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIGridColumn.cpp index 8a6a4bfe..df16721 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIGridColumn.cpp +++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIGridColumn.cpp
@@ -15,7 +15,7 @@ bool important, CSSParserTokenRange& range, const CSSParserContext&, - bool, + const CSSParserLocalContext&, HeapVector<CSSProperty, 256>& properties) { const StylePropertyShorthand& shorthand = shorthandForProperty(CSSPropertyGridColumn);
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIGridGap.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIGridGap.cpp index 643ae50f..28516b12 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIGridGap.cpp +++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIGridGap.cpp
@@ -15,7 +15,7 @@ bool important, CSSParserTokenRange& range, const CSSParserContext& context, - bool use_legacy_parsing, + const CSSParserLocalContext&, HeapVector<CSSProperty, 256>& properties) { DCHECK(RuntimeEnabledFeatures::CSSGridLayoutEnabled()); DCHECK_EQ(shorthandForProperty(CSSPropertyGridGap).length(), 2u);
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIGridRow.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIGridRow.cpp index 554bdc9..a0353da 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIGridRow.cpp +++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIGridRow.cpp
@@ -15,7 +15,7 @@ bool important, CSSParserTokenRange& range, const CSSParserContext&, - bool, + const CSSParserLocalContext&, HeapVector<CSSProperty, 256>& properties) { const StylePropertyShorthand& shorthand = shorthandForProperty(CSSPropertyGridRow);
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIGridTemplate.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIGridTemplate.cpp index 8dfaecf..9e3944b 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIGridTemplate.cpp +++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIGridTemplate.cpp
@@ -14,7 +14,7 @@ bool important, CSSParserTokenRange& range, const CSSParserContext& context, - bool use_legacy_parsing, + const CSSParserLocalContext&, HeapVector<CSSProperty, 256>& properties) { CSSValue* template_rows = nullptr; CSSValue* template_columns = nullptr;
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIListStyle.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIListStyle.cpp index aaa54c65..232dd9e 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIListStyle.cpp +++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIListStyle.cpp
@@ -12,7 +12,7 @@ bool important, CSSParserTokenRange& range, const CSSParserContext& context, - bool, + const CSSParserLocalContext&, HeapVector<CSSProperty, 256>& properties) { return CSSPropertyParserHelpers::ConsumeShorthandGreedilyViaLonghandAPIs( listStyleShorthand(), important, context, range, properties);
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIMargin.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIMargin.cpp index 32794c6..55a46fb 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIMargin.cpp +++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIMargin.cpp
@@ -13,7 +13,7 @@ bool important, CSSParserTokenRange& range, const CSSParserContext& context, - bool, + const CSSParserLocalContext&, HeapVector<CSSProperty, 256>& properties) { return CSSPropertyParserHelpers::ConsumeShorthandVia4LonghandAPIs( marginShorthand(), important, context, range, properties);
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIMarker.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIMarker.cpp index c063e38..0e9ea4c 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIMarker.cpp +++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIMarker.cpp
@@ -12,7 +12,7 @@ bool important, CSSParserTokenRange& range, const CSSParserContext& context, - bool use_legacy_parsing, + const CSSParserLocalContext&, HeapVector<CSSProperty, 256>& properties) { bool needs_legacy_parsing = false; const CSSValue* marker = CSSPropertyParserHelpers::ParseLonghandViaAPI(
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIOffset.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIOffset.cpp index cbd8952..86826a3 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIOffset.cpp +++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIOffset.cpp
@@ -19,7 +19,7 @@ bool important, CSSParserTokenRange& range, const CSSParserContext& context, - bool, + const CSSParserLocalContext&, HeapVector<CSSProperty, 256>& properties) { const CSSValue* offset_position = CSSPropertyAPIOffsetPosition::ParseSingleValue(range, context,
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIOutline.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIOutline.cpp index 095b3236..eb556512 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIOutline.cpp +++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIOutline.cpp
@@ -12,7 +12,7 @@ bool important, CSSParserTokenRange& range, const CSSParserContext& context, - bool, + const CSSParserLocalContext&, HeapVector<CSSProperty, 256>& properties) { return CSSPropertyParserHelpers::ConsumeShorthandGreedilyViaLonghandAPIs( outlineShorthand(), important, context, range, properties);
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIOverflow.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIOverflow.cpp index bd9fb622..efc8971 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIOverflow.cpp +++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIOverflow.cpp
@@ -15,7 +15,7 @@ bool important, CSSParserTokenRange& range, const CSSParserContext& context, - bool, + const CSSParserLocalContext&, HeapVector<CSSProperty, 256>& properties) { CSSValueID id = range.ConsumeIncludingWhitespace().Id(); if (!CSSParserFastPaths::IsValidKeywordPropertyAndValue(CSSPropertyOverflowY,
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIPadding.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIPadding.cpp index 56109c5..1e6425a9 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIPadding.cpp +++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIPadding.cpp
@@ -13,7 +13,7 @@ bool important, CSSParserTokenRange& range, const CSSParserContext& context, - bool, + const CSSParserLocalContext&, HeapVector<CSSProperty, 256>& properties) { return CSSPropertyParserHelpers::ConsumeShorthandVia4LonghandAPIs( paddingShorthand(), important, context, range, properties);
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIPageBreakAfter.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIPageBreakAfter.cpp index 8c15900..3abd714 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIPageBreakAfter.cpp +++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIPageBreakAfter.cpp
@@ -13,7 +13,7 @@ bool important, CSSParserTokenRange& range, const CSSParserContext&, - bool use_legacy_parsing, + const CSSParserLocalContext&, HeapVector<CSSProperty, 256>& properties) { CSSValueID value; if (!CSSPropertyLegacyBreakUtils::ConsumeFromPageBreakBetween(range, value)) {
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIPageBreakBefore.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIPageBreakBefore.cpp index 46d94fd..ec02e18 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIPageBreakBefore.cpp +++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIPageBreakBefore.cpp
@@ -13,7 +13,7 @@ bool important, CSSParserTokenRange& range, const CSSParserContext&, - bool use_legacy_parsing, + const CSSParserLocalContext&, HeapVector<CSSProperty, 256>& properties) { CSSValueID value; if (!CSSPropertyLegacyBreakUtils::ConsumeFromPageBreakBetween(range, value)) {
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIPageBreakInside.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIPageBreakInside.cpp index a581f1a2..93c0254 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIPageBreakInside.cpp +++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIPageBreakInside.cpp
@@ -13,7 +13,7 @@ bool important, CSSParserTokenRange& range, const CSSParserContext&, - bool use_legacy_parsing, + const CSSParserLocalContext&, HeapVector<CSSProperty, 256>& properties) { CSSValueID value; if (!CSSPropertyLegacyBreakUtils::ConsumeFromColumnOrPageBreakInside(range,
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIPlaceContent.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIPlaceContent.cpp index 0f380edb..271d236f 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIPlaceContent.cpp +++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIPlaceContent.cpp
@@ -16,7 +16,7 @@ bool important, CSSParserTokenRange& range, const CSSParserContext&, - bool, + const CSSParserLocalContext&, HeapVector<CSSProperty, 256>& properties) { DCHECK(RuntimeEnabledFeatures::CSSGridLayoutEnabled()); DCHECK_EQ(shorthandForProperty(CSSPropertyPlaceContent).length(), 2u);
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIPlaceItems.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIPlaceItems.cpp index 9508a0e..82ee044 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIPlaceItems.cpp +++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIPlaceItems.cpp
@@ -16,7 +16,7 @@ bool important, CSSParserTokenRange& range, const CSSParserContext&, - bool, + const CSSParserLocalContext&, HeapVector<CSSProperty, 256>& properties) { DCHECK(RuntimeEnabledFeatures::CSSGridLayoutEnabled()); DCHECK_EQ(shorthandForProperty(CSSPropertyPlaceItems).length(), 2u);
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIPlaceSelf.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIPlaceSelf.cpp index cd798646..b17f90bc 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIPlaceSelf.cpp +++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIPlaceSelf.cpp
@@ -16,7 +16,7 @@ bool important, CSSParserTokenRange& range, const CSSParserContext&, - bool, + const CSSParserLocalContext&, HeapVector<CSSProperty, 256>& properties) { DCHECK(RuntimeEnabledFeatures::CSSGridLayoutEnabled()); DCHECK_EQ(shorthandForProperty(CSSPropertyPlaceSelf).length(), 2u);
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIScrollBoundaryBehavior.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIScrollBoundaryBehavior.cpp index 3750955e..745e7e7 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIScrollBoundaryBehavior.cpp +++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIScrollBoundaryBehavior.cpp
@@ -13,7 +13,7 @@ bool important, CSSParserTokenRange& range, const CSSParserContext& context, - bool, + const CSSParserLocalContext&, HeapVector<CSSProperty, 256>& properties) { return CSSPropertyParserHelpers::ConsumeShorthandVia2LonghandAPIs( scrollBoundaryBehaviorShorthand(), important, context, range, properties);
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIScrollPadding.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIScrollPadding.cpp index 76d7219..7c11c5c2 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIScrollPadding.cpp +++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIScrollPadding.cpp
@@ -13,7 +13,7 @@ bool important, CSSParserTokenRange& range, const CSSParserContext& context, - bool, + const CSSParserLocalContext&, HeapVector<CSSProperty, 256>& properties) { return CSSPropertyParserHelpers::ConsumeShorthandVia4LonghandAPIs( scrollPaddingShorthand(), important, context, range, properties);
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIScrollPaddingBlock.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIScrollPaddingBlock.cpp index 333d563..969700cd 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIScrollPaddingBlock.cpp +++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIScrollPaddingBlock.cpp
@@ -13,7 +13,7 @@ bool important, CSSParserTokenRange& range, const CSSParserContext& context, - bool, + const CSSParserLocalContext&, HeapVector<CSSProperty, 256>& properties) { return CSSPropertyParserHelpers::ConsumeShorthandVia2LonghandAPIs( scrollPaddingBlockShorthand(), important, context, range, properties);
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIScrollPaddingInline.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIScrollPaddingInline.cpp index b18a139..5bd8ec4 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIScrollPaddingInline.cpp +++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIScrollPaddingInline.cpp
@@ -13,7 +13,7 @@ bool important, CSSParserTokenRange& range, const CSSParserContext& context, - bool, + const CSSParserLocalContext&, HeapVector<CSSProperty, 256>& properties) { return CSSPropertyParserHelpers::ConsumeShorthandVia2LonghandAPIs( scrollPaddingInlineShorthand(), important, context, range, properties);
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIScrollSnapMargin.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIScrollSnapMargin.cpp index 94e6f6ed..1ba6b98 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIScrollSnapMargin.cpp +++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIScrollSnapMargin.cpp
@@ -13,7 +13,7 @@ bool important, CSSParserTokenRange& range, const CSSParserContext& context, - bool, + const CSSParserLocalContext&, HeapVector<CSSProperty, 256>& properties) { return CSSPropertyParserHelpers::ConsumeShorthandVia4LonghandAPIs( scrollSnapMarginShorthand(), important, context, range, properties);
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIScrollSnapMarginBlock.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIScrollSnapMarginBlock.cpp index 1cbb6f9c..5c7fab3b 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIScrollSnapMarginBlock.cpp +++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIScrollSnapMarginBlock.cpp
@@ -13,7 +13,7 @@ bool important, CSSParserTokenRange& range, const CSSParserContext& context, - bool, + const CSSParserLocalContext&, HeapVector<CSSProperty, 256>& properties) { return CSSPropertyParserHelpers::ConsumeShorthandVia2LonghandAPIs( scrollSnapMarginBlockShorthand(), important, context, range, properties);
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIScrollSnapMarginInline.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIScrollSnapMarginInline.cpp index e754bb2..d4a8ef15 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIScrollSnapMarginInline.cpp +++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIScrollSnapMarginInline.cpp
@@ -13,7 +13,7 @@ bool important, CSSParserTokenRange& range, const CSSParserContext& context, - bool, + const CSSParserLocalContext&, HeapVector<CSSProperty, 256>& properties) { return CSSPropertyParserHelpers::ConsumeShorthandVia2LonghandAPIs( scrollSnapMarginInlineShorthand(), important, context, range, properties);
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPITextDecoration.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPITextDecoration.cpp index 71e28a3..4caddbc5 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPITextDecoration.cpp +++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPITextDecoration.cpp
@@ -13,7 +13,7 @@ bool important, CSSParserTokenRange& range, const CSSParserContext& context, - bool, + const CSSParserLocalContext&, HeapVector<CSSProperty, 256>& properties) { DCHECK(RuntimeEnabledFeatures::CSS3TextDecorationsEnabled()); return CSSPropertyParserHelpers::ConsumeShorthandGreedilyViaLonghandAPIs(
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPITransition.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPITransition.cpp index 86fad63..e8d4ff18 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPITransition.cpp +++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPITransition.cpp
@@ -45,7 +45,7 @@ bool important, CSSParserTokenRange& range, const CSSParserContext& context, - bool use_legacy_parsing, + const CSSParserLocalContext& local_context, HeapVector<CSSProperty, 256>& properties) { const StylePropertyShorthand shorthand = transitionShorthandForParsing(); const unsigned longhand_count = shorthand.length(); @@ -54,7 +54,7 @@ longhand_count); if (!CSSPropertyAnimationUtils::ConsumeAnimationShorthand( shorthand, longhands, ConsumeTransitionValue, range, context, - use_legacy_parsing)) { + local_context.UseAliasParsing())) { return false; }
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIWebkitBorderAfter.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIWebkitBorderAfter.cpp index 4a60b19..1bcab70 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIWebkitBorderAfter.cpp +++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIWebkitBorderAfter.cpp
@@ -12,7 +12,7 @@ bool important, CSSParserTokenRange& range, const CSSParserContext& context, - bool, + const CSSParserLocalContext&, HeapVector<CSSProperty, 256>& properties) { return CSSPropertyParserHelpers::ConsumeShorthandGreedilyViaLonghandAPIs( webkitBorderAfterShorthand(), important, context, range, properties);
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIWebkitBorderBefore.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIWebkitBorderBefore.cpp index e73e0a33..1eeb60c 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIWebkitBorderBefore.cpp +++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIWebkitBorderBefore.cpp
@@ -12,7 +12,7 @@ bool important, CSSParserTokenRange& range, const CSSParserContext& context, - bool, + const CSSParserLocalContext&, HeapVector<CSSProperty, 256>& properties) { return CSSPropertyParserHelpers::ConsumeShorthandGreedilyViaLonghandAPIs( webkitBorderBeforeShorthand(), important, context, range, properties);
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIWebkitBorderEnd.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIWebkitBorderEnd.cpp index 21a72e94..4c499fe 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIWebkitBorderEnd.cpp +++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIWebkitBorderEnd.cpp
@@ -12,7 +12,7 @@ bool important, CSSParserTokenRange& range, const CSSParserContext& context, - bool, + const CSSParserLocalContext&, HeapVector<CSSProperty, 256>& properties) { return CSSPropertyParserHelpers::ConsumeShorthandGreedilyViaLonghandAPIs( webkitBorderEndShorthand(), important, context, range, properties);
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIWebkitBorderStart.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIWebkitBorderStart.cpp index 001ab694..72d71173 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIWebkitBorderStart.cpp +++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIWebkitBorderStart.cpp
@@ -12,7 +12,7 @@ bool important, CSSParserTokenRange& range, const CSSParserContext& context, - bool, + const CSSParserLocalContext&, HeapVector<CSSProperty, 256>& properties) { return CSSPropertyParserHelpers::ConsumeShorthandGreedilyViaLonghandAPIs( webkitBorderStartShorthand(), important, context, range, properties);
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIWebkitColumnBreakAfter.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIWebkitColumnBreakAfter.cpp index 74e9972..89e347d 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIWebkitColumnBreakAfter.cpp +++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIWebkitColumnBreakAfter.cpp
@@ -13,7 +13,7 @@ bool important, CSSParserTokenRange& range, const CSSParserContext&, - bool use_legacy_parsing, + const CSSParserLocalContext&, HeapVector<CSSProperty, 256>& properties) { CSSValueID value; if (!CSSPropertyLegacyBreakUtils::ConsumeFromColumnBreakBetween(range,
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIWebkitColumnBreakBefore.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIWebkitColumnBreakBefore.cpp index 9f3043b..83f0fde 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIWebkitColumnBreakBefore.cpp +++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIWebkitColumnBreakBefore.cpp
@@ -13,7 +13,7 @@ bool important, CSSParserTokenRange& range, const CSSParserContext&, - bool use_legacy_parsing, + const CSSParserLocalContext&, HeapVector<CSSProperty, 256>& properties) { CSSValueID value; if (!CSSPropertyLegacyBreakUtils::ConsumeFromColumnBreakBetween(range,
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIWebkitColumnBreakInside.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIWebkitColumnBreakInside.cpp index b632d79..01dae7e4 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIWebkitColumnBreakInside.cpp +++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIWebkitColumnBreakInside.cpp
@@ -13,7 +13,7 @@ bool important, CSSParserTokenRange& range, const CSSParserContext&, - bool use_legacy_parsing, + const CSSParserLocalContext&, HeapVector<CSSProperty, 256>& properties) { CSSValueID value; if (!CSSPropertyLegacyBreakUtils::ConsumeFromColumnOrPageBreakInside(range,
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIWebkitMarginCollapse.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIWebkitMarginCollapse.cpp index 6f8a38d8..3cd3da75 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIWebkitMarginCollapse.cpp +++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIWebkitMarginCollapse.cpp
@@ -15,7 +15,7 @@ bool important, CSSParserTokenRange& range, const CSSParserContext& context, - bool, + const CSSParserLocalContext&, HeapVector<CSSProperty, 256>& properties) { CSSValueID id = range.ConsumeIncludingWhitespace().Id(); if (!CSSParserFastPaths::IsValidKeywordPropertyAndValue(
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIWebkitMaskBoxImage.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIWebkitMaskBoxImage.cpp index 7cb87e6..62116d9f 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIWebkitMaskBoxImage.cpp +++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIWebkitMaskBoxImage.cpp
@@ -15,7 +15,7 @@ bool important, CSSParserTokenRange& range, const CSSParserContext& context, - bool, + const CSSParserLocalContext&, HeapVector<CSSProperty, 256>& properties) { CSSValue* source = nullptr; CSSValue* slice = nullptr;
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIWebkitMaskPosition.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIWebkitMaskPosition.cpp index 597e140..1d341fb2 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIWebkitMaskPosition.cpp +++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIWebkitMaskPosition.cpp
@@ -14,7 +14,7 @@ bool important, CSSParserTokenRange& range, const CSSParserContext& context, - bool, + const CSSParserLocalContext&, HeapVector<CSSProperty, 256>& properties) { CSSValue* result_x = nullptr; CSSValue* result_y = nullptr;
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIWebkitTextEmphasis.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIWebkitTextEmphasis.cpp index 5861f74e..2db863d1 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIWebkitTextEmphasis.cpp +++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIWebkitTextEmphasis.cpp
@@ -12,7 +12,7 @@ bool important, CSSParserTokenRange& range, const CSSParserContext& context, - bool, + const CSSParserLocalContext&, HeapVector<CSSProperty, 256>& properties) { return CSSPropertyParserHelpers::ConsumeShorthandGreedilyViaLonghandAPIs( webkitTextEmphasisShorthand(), important, context, range, properties);
diff --git a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIWebkitTextStroke.cpp b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIWebkitTextStroke.cpp index 038b493..a5e382d 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIWebkitTextStroke.cpp +++ b/third_party/WebKit/Source/core/css/properties/CSSShorthandPropertyAPIWebkitTextStroke.cpp
@@ -12,7 +12,7 @@ bool important, CSSParserTokenRange& range, const CSSParserContext& context, - bool, + const CSSParserLocalContext&, HeapVector<CSSProperty, 256>& properties) { return CSSPropertyParserHelpers::ConsumeShorthandGreedilyViaLonghandAPIs( webkitTextStrokeShorthand(), important, context, range, properties);
diff --git a/third_party/WebKit/Source/core/dom/ContextFeaturesClientImpl.h b/third_party/WebKit/Source/core/dom/ContextFeaturesClientImpl.h index df0a7ac..cc3f589 100644 --- a/third_party/WebKit/Source/core/dom/ContextFeaturesClientImpl.h +++ b/third_party/WebKit/Source/core/dom/ContextFeaturesClientImpl.h
@@ -40,7 +40,7 @@ namespace blink { class CORE_EXPORT ContextFeaturesClientImpl final - : public NON_EXPORTED_BASE(ContextFeaturesClient) { + : public ContextFeaturesClient { public: static std::unique_ptr<ContextFeaturesClientImpl> Create() { return WTF::WrapUnique(new ContextFeaturesClientImpl());
diff --git a/third_party/WebKit/Source/core/dom/DocumentTest.cpp b/third_party/WebKit/Source/core/dom/DocumentTest.cpp index d0f31e5..b83b792 100644 --- a/third_party/WebKit/Source/core/dom/DocumentTest.cpp +++ b/third_party/WebKit/Source/core/dom/DocumentTest.cpp
@@ -319,8 +319,7 @@ // DEFINE_INLINE_VIRTUAL_TRACE() { ValidationMessageClient::trace(visitor); } }; -class MockWebApplicationCacheHost - : NON_EXPORTED_BASE(public blink::WebApplicationCacheHost) { +class MockWebApplicationCacheHost : public blink::WebApplicationCacheHost { public: MockWebApplicationCacheHost() {} ~MockWebApplicationCacheHost() override {}
diff --git a/third_party/WebKit/Source/core/dom/README.md b/third_party/WebKit/Source/core/dom/README.md index 3d43537..985c5c7 100644 --- a/third_party/WebKit/Source/core/dom/README.md +++ b/third_party/WebKit/Source/core/dom/README.md
@@ -2,6 +2,8 @@ [Rendered](https://chromium.googlesource.com/chromium/src/+/master/third_party/WebKit/Source/core/dom/README.md) +Author: hayato@chromium.org + The `Source/core/dom` directory contains the implementation of [DOM]. [DOM]: https://dom.spec.whatwg.org/ @@ -24,7 +26,7 @@ - See [crbug.com/738794](http://crbug.com/738794) for tracking our efforts. -# Node and DOM Tree +# Node and Node Tree In this README, we draw a tree in left-to-right direction. `A` is the root of the tree. @@ -38,7 +40,8 @@ └───F ``` -`Node` is a base class of all kinds of nodes in DOM tree. Each `Node` has following 3 pointers (but not limited to): + +`Node` is a base class of all kinds of nodes in a node tree. Each `Node` has following 3 pointers (but not limited to): - `parent_or_shadow_host_node_`: Points to the parent (or the shadow host if it is a shadow root; explained later) - `previous_`: Points to the previous sibling @@ -61,13 +64,15 @@ You can traverse a tree manually: ``` c++ +// In C++ + // Traverse a children. for (Node* child = parent.firstChild(); child; child = child->nextSibling()) { ... } -``` -``` c++ +// ... + // Traverse nodes in tree order, depth-first traversal. void foo(const Node& node) { ... @@ -81,6 +86,7 @@ Instead, you can use `NodeTraversal` and `ElementTraversal`. They provides a C++11's range-based for loops, such as: ``` c++ +// In C++ for (Node& child : NodeTraversal::childrenOf(parent) { ... } @@ -90,6 +96,7 @@ ``` c++ +// In C++ for (Node& node : NodeTraversal::startsAt(root)) { ... } @@ -107,7 +114,77 @@ # Shadow Tree -TODO(hayato): Explain. +A **shadow tree** is a node tree whose root is a `ShadowRoot`. +From web developer's perspective, a shadow root can be created by calling `element.attachShadow{ ... }` API. +The *element* here is called a **shadow host**, or just a **host** if the context is clear. + +- A shadow root is always attached to another node tree through its host. A shadow tree is therefore never alone. +- The node tree of a shadow root’s host is sometimes referred to as the **light tree**. + +For example, given the example node tree: + +``` text +A +├───B +├───C +│ ├───D +│ └───E +└───F +``` + +Web developers can create a shadow root, and manipulate the shadow tree in the following way: + +``` javascript +// In JavaScript +const b = document.querySelector('#B'); +const shadowRoot = b.attachShadow({ mode: 'open'} ) +const sb = document.createElement('div'); +shadowRoot.appendChild(sb); +``` + +The resulting shadow tree would be: + +``` text +shadowRoot +└── sb +``` + +The *shadowRoot* has one child, *sb*. This shadow tree is being *attached* to B: + +``` text +A +└── B + ├──/shadowRoot + │ └── sb + ├── C + │ ├── D + │ └── E + └── F +``` + +In this README, a notation (`──/`) is used to represent a *shadowhost-shadowroot* relationship, in a **composed tree**. +A composed tree will be explained later. A *shadowhost-shadowroot* is 1:1 relationship. + +Though a shadow root has always a corresponding shadow host element, a light tree and a shadow tree should be considered separately, from a node tree's perspective. (`──/`) is *NOT* a parent-child relationship in a node tree. + +For example, even though *B* *hosts* the shadow tree, *shadowRoot* is not considered as a *child* of *B*. +The means the following traversal: + + +``` c++ +// In C++ +for (Node& node : NodeTraversal::startsAt(A)) { + ... +} +``` + +traverses only *A*, *B*, *C*, *D*, *E* and *F* nodes. It never visits *shadowRoot* nor *sb*. +NodeTraversal never cross a shadow boundary, `──/`. + +Further info: + +- `ShadowRoot` +- `Element#attachShadow` # TreeScope
diff --git a/third_party/WebKit/Source/core/dom/TextTest.cpp b/third_party/WebKit/Source/core/dom/TextTest.cpp index 197ee7a..98f00ec5 100644 --- a/third_party/WebKit/Source/core/dom/TextTest.cpp +++ b/third_party/WebKit/Source/core/dom/TextTest.cpp
@@ -11,7 +11,6 @@ namespace blink { -// TODO(xiaochengh): Use a new testing base class. class TextTest : public EditingTestBase {}; TEST_F(TextTest, SetDataToChangeFirstLetterTextNode) {
diff --git a/third_party/WebKit/Source/core/editing/Editor.cpp b/third_party/WebKit/Source/core/editing/Editor.cpp index 27958091..43f150f 100644 --- a/third_party/WebKit/Source/core/editing/Editor.cpp +++ b/third_party/WebKit/Source/core/editing/Editor.cpp
@@ -686,7 +686,6 @@ input_type); } -// TODO(xiaochengh): Merge it with |replaceSelectionWithFragment()|. void Editor::ReplaceSelectionAfterDragging(DocumentFragment* fragment, InsertMode insert_mode, DragSourceType drag_source_type) {
diff --git a/third_party/WebKit/Source/core/editing/VisiblePosition.h b/third_party/WebKit/Source/core/editing/VisiblePosition.h index 20c95aa2..27c2b1a 100644 --- a/third_party/WebKit/Source/core/editing/VisiblePosition.h +++ b/third_party/WebKit/Source/core/editing/VisiblePosition.h
@@ -86,9 +86,10 @@ bool IsValid() const; - // TODO(xiaochengh): We should have |DCHECK(isValid())| in the following + // TODO(editing-dev): We should have |DCHECK(isValid())| in the following // functions. However, there are some clients storing a VisiblePosition and // inspecting its properties after mutation. This should be fixed. + // See crbug.com/648949 for details. bool IsNull() const { return position_with_affinity_.IsNull(); } bool IsNotNull() const { return position_with_affinity_.IsNotNull(); } bool IsOrphan() const { return DeepEquivalent().IsOrphan(); }
diff --git a/third_party/WebKit/Source/core/editing/VisibleUnits.cpp b/third_party/WebKit/Source/core/editing/VisibleUnits.cpp index 737eee43..6f6c0fb 100644 --- a/third_party/WebKit/Source/core/editing/VisibleUnits.cpp +++ b/third_party/WebKit/Source/core/editing/VisibleUnits.cpp
@@ -354,9 +354,6 @@ int run_offset = 0; do { run_offset += it.CopyTextTo(&string, run_offset, string.Capacity()); - // TODO(xiaochengh): The following line takes O(string.size()) time, - // which makes quadratic overall running time in the worst case. - // Should improve it in some way. next = search_function(string.Data(), string.Size(), string.Size() - suffix_length, kMayHaveMoreContext, need_more_context); @@ -377,7 +374,6 @@ // The last search returned the beginning of the buffer and asked for // more context, but there is no earlier text. Force a search with // what's available. - // TODO(xiaochengh): Do we have to search the whole string? next = search_function(string.Data(), string.Size(), string.Size() - suffix_length, kDontHaveMoreContext, need_more_context); @@ -481,7 +477,6 @@ // The last search returned the end of the buffer and asked for more // context, but there is no further text. Force a search with what's // available. - // TODO(xiaochengh): Do we still have to search the whole string? next = search_function(string.Data(), string.Size(), prefix_length, kDontHaveMoreContext, need_more_context); DCHECK(!need_more_context); @@ -1189,7 +1184,6 @@ static bool IsVisuallyEmpty(const LayoutObject* layout) { for (LayoutObject* child = layout->SlowFirstChild(); child; child = child->NextSibling()) { - // TODO(xiaochengh): Replace type-based conditioning by virtual function. if (child->IsBox()) { if (!ToLayoutBox(child)->Size().IsEmpty()) return false;
diff --git a/third_party/WebKit/Source/core/editing/VisibleUnitsParagraph.cpp b/third_party/WebKit/Source/core/editing/VisibleUnitsParagraph.cpp index 0ec742d..9eb57a8 100644 --- a/third_party/WebKit/Source/core/editing/VisibleUnitsParagraph.cpp +++ b/third_party/WebKit/Source/core/editing/VisibleUnitsParagraph.cpp
@@ -389,7 +389,7 @@ const Position& paragraph_end = EndOfParagraph(end).DeepEquivalent(); DCHECK(paragraph_end.IsNotNull()) << range.EndPosition(); - // TODO(xiaochengh): There are some cases (crbug.com/640112) where we get + // TODO(editing-dev): There are some cases (crbug.com/640112) where we get // |paragraphStart > paragraphEnd|, which is the reason we cannot directly // return |EphemeralRange(paragraphStart, paragraphEnd)|. This is not // desired, though. We should do more investigation to ensure that why
diff --git a/third_party/WebKit/Source/core/editing/VisibleUnitsSentence.cpp b/third_party/WebKit/Source/core/editing/VisibleUnitsSentence.cpp index a88e9d7..3a9d0bce 100644 --- a/third_party/WebKit/Source/core/editing/VisibleUnitsSentence.cpp +++ b/third_party/WebKit/Source/core/editing/VisibleUnitsSentence.cpp
@@ -111,7 +111,7 @@ CreateVisiblePosition(range.EndPosition()); DCHECK(visible_end.IsNotNull()); const Position& sentence_end = EndOfSentence(visible_end).DeepEquivalent(); - // TODO(xiaochengh): |sentenceEnd < range.endPosition()| is possible, + // TODO(editing-dev): |sentenceEnd < range.endPosition()| is possible, // which would trigger a DCHECK in EphemeralRange's constructor if we return // it directly. However, this shouldn't happen and needs to be fixed. return EphemeralRange( @@ -128,7 +128,7 @@ DCHECK(visible_start.IsNotNull()); const Position& sentence_start = StartOfSentence(visible_start).DeepEquivalent(); - // TODO(xiaochengh): |sentenceStart > range.startPosition()| is possible, + // TODO(editing-dev): |sentenceStart > range.startPosition()| is possible, // which would trigger a DCHECK in EphemeralRange's constructor if we return // it directly. However, this shouldn't happen and needs to be fixed. return ExpandEndToSentenceBoundary(EphemeralRange(
diff --git a/third_party/WebKit/Source/core/editing/commands/ApplyBlockElementCommand.cpp b/third_party/WebKit/Source/core/editing/commands/ApplyBlockElementCommand.cpp index c9f6f1f1..6309bef9 100644 --- a/third_party/WebKit/Source/core/editing/commands/ApplyBlockElementCommand.cpp +++ b/third_party/WebKit/Source/core/editing/commands/ApplyBlockElementCommand.cpp
@@ -89,7 +89,7 @@ const SelectionInDOMTree& new_selection = builder.Build(); if (new_selection.IsNone()) return; - SetEndingSelection(new_selection); + SetEndingSelection(SelectionForUndoStep::From(new_selection)); } VisibleSelection selection = @@ -117,12 +117,12 @@ VisiblePosition start(VisiblePositionForIndex(start_index, start_scope)); VisiblePosition end(VisiblePositionForIndex(end_index, end_scope)); if (start.IsNotNull() && end.IsNotNull()) { - SetEndingSelection( + SetEndingSelection(SelectionForUndoStep::From( SelectionInDOMTree::Builder() .Collapse(start.ToPositionWithAffinity()) .Extend(end.DeepEquivalent()) .SetIsDirectional(EndingSelection().IsDirectional()) - .Build()); + .Build())); } } } @@ -150,10 +150,11 @@ AppendNode(placeholder, blockquote, editing_state); if (editing_state->IsAborted()) return; - SetEndingSelection(SelectionInDOMTree::Builder() - .Collapse(Position::BeforeNode(*placeholder)) - .SetIsDirectional(EndingSelection().IsDirectional()) - .Build()); + SetEndingSelection(SelectionForUndoStep::From( + SelectionInDOMTree::Builder() + .Collapse(Position::BeforeNode(*placeholder)) + .SetIsDirectional(EndingSelection().IsDirectional()) + .Build())); return; }
diff --git a/third_party/WebKit/Source/core/editing/commands/ApplyStyleCommand.cpp b/third_party/WebKit/Source/core/editing/commands/ApplyStyleCommand.cpp index 8590a11..a93fd3b 100644 --- a/third_party/WebKit/Source/core/editing/commands/ApplyStyleCommand.cpp +++ b/third_party/WebKit/Source/core/editing/commands/ApplyStyleCommand.cpp
@@ -282,7 +282,7 @@ NextPositionOf(EndOfParagraph(paragraph_start))); Position beyond_end = NextPositionOf(EndOfParagraph(visible_end)).DeepEquivalent(); - // TODO(xiaochengh): Use a saner approach (e.g., temporary Ranges) to keep + // TODO(editing-dev): Use a saner approach (e.g., temporary Ranges) to keep // these positions in document instead of iteratively performing orphan checks // and recalculating them when they become orphans. while (paragraph_start.IsNotNull() && @@ -323,8 +323,9 @@ GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets(); // Make the VisiblePositions valid again after style changes. - // TODO(xiaochengh): We shouldn't store VisiblePositions and inspect their - // properties after they have been invalidated by mutations. + // TODO(editing-dev): We shouldn't store VisiblePositions and inspect + // their properties after they have been invalidated by mutations. See + // crbug.com/648949 for details. DCHECK(!paragraph_start.IsOrphan()) << paragraph_start; paragraph_start = CreateVisiblePosition(paragraph_start.ToPositionWithAffinity());
diff --git a/third_party/WebKit/Source/core/editing/commands/CompositeEditCommand.cpp b/third_party/WebKit/Source/core/editing/commands/CompositeEditCommand.cpp index 62a98b3..73a2d795 100644 --- a/third_party/WebKit/Source/core/editing/commands/CompositeEditCommand.cpp +++ b/third_party/WebKit/Source/core/editing/commands/CompositeEditCommand.cpp
@@ -209,12 +209,12 @@ void CompositeEditCommand::ApplyCommandToComposite( CompositeEditCommand* command, - const VisibleSelection& selection, + const SelectionForUndoStep& selection, EditingState* editing_state) { command->SetParent(this); - if (selection != command->EndingVisibleSelection()) { + if (selection != command->EndingSelection()) { command->SetStartingSelection(selection); - command->SetEndingVisibleSelection(selection); + command->SetEndingSelection(selection); } command->DoApply(editing_state); if (!editing_state->IsAborted())
diff --git a/third_party/WebKit/Source/core/editing/commands/CompositeEditCommand.h b/third_party/WebKit/Source/core/editing/commands/CompositeEditCommand.h index ef6c898..cec4648 100644 --- a/third_party/WebKit/Source/core/editing/commands/CompositeEditCommand.h +++ b/third_party/WebKit/Source/core/editing/commands/CompositeEditCommand.h
@@ -97,7 +97,7 @@ void AppendNode(Node*, ContainerNode* parent, EditingState*); void ApplyCommandToComposite(EditCommand*, EditingState*); void ApplyCommandToComposite(CompositeEditCommand*, - const VisibleSelection&, + const SelectionForUndoStep&, EditingState*); void ApplyStyle(const EditingStyle*, EditingState*); void ApplyStyle(const EditingStyle*,
diff --git a/third_party/WebKit/Source/core/editing/commands/IndentOutdentCommand.cpp b/third_party/WebKit/Source/core/editing/commands/IndentOutdentCommand.cpp index 45f57de2..05e1b65 100644 --- a/third_party/WebKit/Source/core/editing/commands/IndentOutdentCommand.cpp +++ b/third_party/WebKit/Source/core/editing/commands/IndentOutdentCommand.cpp
@@ -306,16 +306,18 @@ // Re-canonicalize visible{Start,End}OfParagraph, make them valid again // after DOM change. - // TODO(xiaochengh): We should not store a VisiblePosition and later inspect - // its properties when it is already invalidated. + // TODO(editing-dev): We should not store a VisiblePosition and later + // inspect its properties when it is already invalidated. + // See crbug.com/648949 for details. visible_start_of_paragraph = CreateVisiblePosition( visible_start_of_paragraph.ToPositionWithAffinity()); visible_end_of_paragraph = CreateVisiblePosition( visible_end_of_paragraph.ToPositionWithAffinity()); } - // TODO(xiaochengh): We should not store a VisiblePosition and later inspect - // its properties when it is already invalidated. + // TODO(editing-dev): We should not store a VisiblePosition and later + // inspect its properties when it is already invalidated. + // See crbug.com/648949 for details. VisiblePosition start_of_paragraph_to_move = StartOfParagraph(visible_start_of_paragraph); VisiblePosition end_of_paragraph_to_move =
diff --git a/third_party/WebKit/Source/core/editing/commands/InsertLineBreakCommand.cpp b/third_party/WebKit/Source/core/editing/commands/InsertLineBreakCommand.cpp index ce72cd1..99b6b9dd 100644 --- a/third_party/WebKit/Source/core/editing/commands/InsertLineBreakCommand.cpp +++ b/third_party/WebKit/Source/core/editing/commands/InsertLineBreakCommand.cpp
@@ -73,7 +73,8 @@ if (!selection.IsNonOrphanedCaretOrRange()) return; - // TODO(xiaochengh): Stop storing VisiblePositions through mutations. + // TODO(editing-dev): Stop storing VisiblePositions through mutations. + // See crbug.com/648949 for details. VisiblePosition caret(selection.VisibleStart()); // FIXME: If the node is hidden, we should still be able to insert text. For // now, we return to avoid a crash.
diff --git a/third_party/WebKit/Source/core/editing/commands/InsertListCommand.cpp b/third_party/WebKit/Source/core/editing/commands/InsertListCommand.cpp index a35bf36..2abb917 100644 --- a/third_party/WebKit/Source/core/editing/commands/InsertListCommand.cpp +++ b/third_party/WebKit/Source/core/editing/commands/InsertListCommand.cpp
@@ -250,7 +250,7 @@ // exit early immediately because we've lost the loop invariant. DCHECK(visible_end_of_selection.IsNotNull()); if (visible_end_of_selection.IsNull() || - !RootEditableElementOf(visible_end_of_selection)) + !RootEditableElementOf(visible_end_of_selection.DeepEquivalent())) return; start_of_last_paragraph = StartOfParagraph(visible_end_of_selection, @@ -665,7 +665,8 @@ MergeWithNeighboringLists(list_element, editing_state); } -// TODO(xiaochengh): Stop storing VisiblePositions through mutations. +// TODO(editing-dev): Stop storing VisiblePositions through mutations. +// See crbug.com/648949 for details. void InsertListCommand::MoveParagraphOverPositionIntoEmptyListItem( const VisiblePosition& pos, HTMLLIElement* list_item_element,
diff --git a/third_party/WebKit/Source/core/editing/commands/ReplaceSelectionCommand.cpp b/third_party/WebKit/Source/core/editing/commands/ReplaceSelectionCommand.cpp index 1e05b64..61c9ccc9 100644 --- a/third_party/WebKit/Source/core/editing/commands/ReplaceSelectionCommand.cpp +++ b/third_party/WebKit/Source/core/editing/commands/ReplaceSelectionCommand.cpp
@@ -794,7 +794,7 @@ VisiblePosition ReplaceSelectionCommand::PositionAtEndOfInsertedContent() const { - // TODO(xiaochengh): Hoist the call and change it into a DCHECK. + // TODO(editing-dev): Hoist the call and change it into a DCHECK. GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets(); // TODO(yosin): We should set |m_endOfInsertedContent| not in SELECT // element, since contents of SELECT elements, e.g. OPTION, OPTGROUP, are @@ -810,7 +810,7 @@ VisiblePosition ReplaceSelectionCommand::PositionAtStartOfInsertedContent() const { - // TODO(xiaochengh): Hoist the call and change it into a DCHECK. + // TODO(editing-dev): Hoist the call and change it into a DCHECK. GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets(); if (start_of_inserted_content_.IsOrphan()) return VisiblePosition(); @@ -913,7 +913,8 @@ VisiblePosition destination = merge_forward ? NextPositionOf(end_of_inserted_content) : end_of_inserted_content; - // TODO(xiaochengh): Stop storing VisiblePositions through mutations. + // TODO(editing-dev): Stop storing VisiblePositions through mutations. + // See crbug.com/648949 for details. VisiblePosition start_of_paragraph_to_move = merge_forward ? StartOfParagraph(end_of_inserted_content) : NextPositionOf(end_of_inserted_content);
diff --git a/third_party/WebKit/Source/core/editing/commands/SelectionForUndoStep.cpp b/third_party/WebKit/Source/core/editing/commands/SelectionForUndoStep.cpp index 2352dc0..5dd84a8 100644 --- a/third_party/WebKit/Source/core/editing/commands/SelectionForUndoStep.cpp +++ b/third_party/WebKit/Source/core/editing/commands/SelectionForUndoStep.cpp
@@ -42,6 +42,21 @@ return *this; } +bool SelectionForUndoStep::operator==(const SelectionForUndoStep& other) const { + if (IsNone()) + return other.IsNone(); + if (other.IsNone()) + return false; + return base_ == other.base_ && extent_ == other.extent_ && + affinity_ == other.affinity_ && + is_base_first_ == other.is_base_first_ && + is_directional_ == other.is_directional_; +} + +bool SelectionForUndoStep::operator!=(const SelectionForUndoStep& other) const { + return !operator==(other); +} + SelectionInDOMTree SelectionForUndoStep::AsSelection() const { if (IsNone()) { return SelectionInDOMTree::Builder()
diff --git a/third_party/WebKit/Source/core/editing/commands/SelectionForUndoStep.h b/third_party/WebKit/Source/core/editing/commands/SelectionForUndoStep.h index 009777ef..d7e0314 100644 --- a/third_party/WebKit/Source/core/editing/commands/SelectionForUndoStep.h +++ b/third_party/WebKit/Source/core/editing/commands/SelectionForUndoStep.h
@@ -32,6 +32,9 @@ SelectionForUndoStep& operator=(const SelectionForUndoStep&); + bool operator==(const SelectionForUndoStep&) const; + bool operator!=(const SelectionForUndoStep&) const; + TextAffinity Affinity() const { return affinity_; } Position Base() const { return base_; } Position Extent() const { return extent_; }
diff --git a/third_party/WebKit/Source/core/editing/commands/TypingCommand.cpp b/third_party/WebKit/Source/core/editing/commands/TypingCommand.cpp index 7e25869..2fbb6d73 100644 --- a/third_party/WebKit/Source/core/editing/commands/TypingCommand.cpp +++ b/third_party/WebKit/Source/core/editing/commands/TypingCommand.cpp
@@ -619,7 +619,7 @@ : InsertTextCommand::kRebalanceAllWhitespaces); } - ApplyCommandToComposite(command, EndingVisibleSelection(), editing_state); + ApplyCommandToComposite(command, EndingSelection(), editing_state); if (editing_state->IsAborted()) return;
diff --git a/third_party/WebKit/Source/core/editing/iterators/SearchBuffer.cpp b/third_party/WebKit/Source/core/editing/iterators/SearchBuffer.cpp index 47369b2c..5160fc443 100644 --- a/third_party/WebKit/Source/core/editing/iterators/SearchBuffer.cpp +++ b/third_party/WebKit/Source/core/editing/iterators/SearchBuffer.cpp
@@ -345,7 +345,6 @@ } while (!it.AtEnd()) { - // TODO(xiaochengh): Should allow copying text to SearchBuffer directly ForwardsTextBuffer characters; it.CopyTextTo(&characters); buffer.Append(characters.Data(), characters.Size());
diff --git a/third_party/WebKit/Source/core/editing/iterators/SimplifiedBackwardsTextIterator.h b/third_party/WebKit/Source/core/editing/iterators/SimplifiedBackwardsTextIterator.h index a8139d9..df652b1 100644 --- a/third_party/WebKit/Source/core/editing/iterators/SimplifiedBackwardsTextIterator.h +++ b/third_party/WebKit/Source/core/editing/iterators/SimplifiedBackwardsTextIterator.h
@@ -64,11 +64,9 @@ // Calculate the minimum |actualLength >= minLength| such that code units // with offset range [position, position + actualLength) are whole code // points. Prepend these code points to |output| and return |actualLength|. - // TODO(xiaochengh): Use (start, end) instead of (start, length). int CopyTextTo(BackwardsTextBuffer* output, int position, int min_length) const; - // TODO(xiaochengh): Avoid default parameters. int CopyTextTo(BackwardsTextBuffer* output, int position = 0) const; Node* StartContainer() const;
diff --git a/third_party/WebKit/Source/core/editing/iterators/TextIterator.h b/third_party/WebKit/Source/core/editing/iterators/TextIterator.h index e453ee1..c6b73de 100644 --- a/third_party/WebKit/Source/core/editing/iterators/TextIterator.h +++ b/third_party/WebKit/Source/core/editing/iterators/TextIterator.h
@@ -95,7 +95,6 @@ // Calculate the minimum |actualLength >= minLength| such that code units // with offset range [position, position + actualLength) are whole code // points. Append these code points to |output| and return |actualLength|. - // TODO(xiaochengh): Use (start, end) instead of (start, length). int CopyTextTo(ForwardsTextBuffer* output, int position, int min_length) const;
diff --git a/third_party/WebKit/Source/core/editing/spellcheck/SpellCheckRequester.h b/third_party/WebKit/Source/core/editing/spellcheck/SpellCheckRequester.h index 0b90abc..6341226 100644 --- a/third_party/WebKit/Source/core/editing/spellcheck/SpellCheckRequester.h +++ b/third_party/WebKit/Source/core/editing/spellcheck/SpellCheckRequester.h
@@ -43,7 +43,6 @@ class SpellCheckRequester; class TextCheckerClient; -// TODO(xiaochengh): Move this class to dedicated files. class CORE_EXPORT SpellCheckRequest final : public TextCheckingRequest { public: static SpellCheckRequest* Create(const EphemeralRange& checking_range,
diff --git a/third_party/WebKit/Source/core/editing/spellcheck/SpellChecker.cpp b/third_party/WebKit/Source/core/editing/spellcheck/SpellChecker.cpp index ab0fdd4..fb53748 100644 --- a/third_party/WebKit/Source/core/editing/spellcheck/SpellChecker.cpp +++ b/third_party/WebKit/Source/core/editing/spellcheck/SpellChecker.cpp
@@ -1129,9 +1129,6 @@ GetFrame().GetDocument()->Markers().RemoveMarkersInRange(range, marker_types); } -// TODO(xiaochengh): This function is only used by unit tests. We should move it -// to IdleSpellCheckCallback and modify unit tests to cope with idle time spell -// checker. void SpellChecker::CancelCheck() { spell_check_requester_->CancelCheck(); }
diff --git a/third_party/WebKit/Source/core/editing/spellcheck/SpellCheckerClientImpl.h b/third_party/WebKit/Source/core/editing/spellcheck/SpellCheckerClientImpl.h index d148fc1..61d3c89 100644 --- a/third_party/WebKit/Source/core/editing/spellcheck/SpellCheckerClientImpl.h +++ b/third_party/WebKit/Source/core/editing/spellcheck/SpellCheckerClientImpl.h
@@ -38,8 +38,7 @@ class WebViewImpl; -class CORE_EXPORT SpellCheckerClientImpl final - : public NON_EXPORTED_BASE(SpellCheckerClient) { +class CORE_EXPORT SpellCheckerClientImpl final : public SpellCheckerClient { public: explicit SpellCheckerClientImpl(WebViewImpl*); ~SpellCheckerClientImpl() override;
diff --git a/third_party/WebKit/Source/core/events/MessageEvent.cpp b/third_party/WebKit/Source/core/events/MessageEvent.cpp index dc95c2d..e65009c 100644 --- a/third_party/WebKit/Source/core/events/MessageEvent.cpp +++ b/third_party/WebKit/Source/core/events/MessageEvent.cpp
@@ -171,6 +171,7 @@ last_event_id_ = last_event_id; source_ = source; ports_ = ports; + is_ports_dirty_ = true; suborigin_ = ""; } @@ -194,6 +195,7 @@ last_event_id_ = last_event_id; source_ = source; ports_ = ports; + is_ports_dirty_ = true; suborigin_ = ""; if (data_as_serialized_script_value_) @@ -220,6 +222,7 @@ last_event_id_ = last_event_id; source_ = source; ports_ = ports; + is_ports_dirty_ = true; suborigin_ = ""; } @@ -227,26 +230,18 @@ return EventNames::MessageEvent; } -MessagePortArray MessageEvent::ports(bool& is_null) const { +MessagePortArray MessageEvent::ports() { // TODO(bashi): Currently we return a copied array because the binding // layer could modify the content of the array while executing JS callbacks. // Avoid copying once we can make sure that the binding layer won't // modify the content. - if (ports_) { - is_null = false; - return *ports_; - } - is_null = true; - return MessagePortArray(); -} - -MessagePortArray MessageEvent::ports() const { - bool unused; - return ports(unused); + is_ports_dirty_ = false; + return ports_ ? *ports_ : MessagePortArray(); } void MessageEvent::EntangleMessagePorts(ExecutionContext* context) { ports_ = MessagePort::EntanglePorts(*context, std::move(channels_)); + is_ports_dirty_ = true; } DEFINE_TRACE(MessageEvent) {
diff --git a/third_party/WebKit/Source/core/events/MessageEvent.h b/third_party/WebKit/Source/core/events/MessageEvent.h index c28e53e..a3ac8fd 100644 --- a/third_party/WebKit/Source/core/events/MessageEvent.h +++ b/third_party/WebKit/Source/core/events/MessageEvent.h
@@ -122,8 +122,8 @@ const String& suborigin() const { return suborigin_; } const String& lastEventId() const { return last_event_id_; } EventTarget* source() const { return source_.Get(); } - MessagePortArray ports(bool& is_null) const; - MessagePortArray ports() const; + MessagePortArray ports(); + bool isPortsDirty() const { return is_ports_dirty_; } MessagePortChannelArray ReleaseChannels() { return std::move(channels_); } @@ -211,10 +211,11 @@ String origin_; String last_event_id_; Member<EventTarget> source_; - // m_ports are the MessagePorts in an entangled state, and m_channels are + // ports_ are the MessagePorts in an entangled state, and channels_ are // the MessageChannels in a disentangled state. Only one of them can be - // non-empty at a time. entangleMessagePorts() moves between the states. + // non-empty at a time. EntangleMessagePorts() moves between the states. Member<MessagePortArray> ports_; + bool is_ports_dirty_ = true; MessagePortChannelArray channels_; String suborigin_; };
diff --git a/third_party/WebKit/Source/core/events/MessageEvent.idl b/third_party/WebKit/Source/core/events/MessageEvent.idl index 791cf0fd..c6cbbad 100644 --- a/third_party/WebKit/Source/core/events/MessageEvent.idl +++ b/third_party/WebKit/Source/core/events/MessageEvent.idl
@@ -37,12 +37,12 @@ readonly attribute DOMString lastEventId; // TODO(bashi): |source| should be (WindowProxy or MessagePort)? readonly attribute EventTarget? source; - // TODO(foolip): |ports| should be FrozenArray<MessagePort>? - readonly attribute MessagePort[]? ports; + [CachedAttribute=isPortsDirty] readonly attribute FrozenArray<MessagePort> ports; [RuntimeEnabled=Suborigins] readonly attribute DOMString suborigin; - // TODO(foolip): None of the initMessageEvent() arguments should be - // optional, and |sourceArg| and |portsArg| are of the wrong type. + // TODO(foolip): |typeArg| should not be optional, none of the arguments + // should have [Default=Undefined] (they have other default values in the + // spec) and |sourceArg|'s type is wrong. [Custom, MeasureAs=InitMessageEvent] void initMessageEvent([Default=Undefined] optional DOMString typeArg, [Default=Undefined] optional boolean canBubbleArg, [Default=Undefined] optional boolean cancelableArg,
diff --git a/third_party/WebKit/Source/core/events/MessageEventInit.idl b/third_party/WebKit/Source/core/events/MessageEventInit.idl index 6b4fbd6..bab4872 100644 --- a/third_party/WebKit/Source/core/events/MessageEventInit.idl +++ b/third_party/WebKit/Source/core/events/MessageEventInit.idl
@@ -10,7 +10,5 @@ DOMString lastEventId; // TODO(bashi): |source| should be (WindowProxy or MessagePort)? EventTarget? source; - // Per spec, |ports| isn't nullable, but it seems it should be. - // https://www.w3.org/Bugs/Public/show_bug.cgi?id=23176 - sequence<MessagePort>? ports; + sequence<MessagePort> ports = []; };
diff --git a/third_party/WebKit/Source/core/events/WebInputEventConversion.h b/third_party/WebKit/Source/core/events/WebInputEventConversion.h index a1a9b92..135bb94 100644 --- a/third_party/WebKit/Source/core/events/WebInputEventConversion.h +++ b/third_party/WebKit/Source/core/events/WebInputEventConversion.h
@@ -53,8 +53,7 @@ // These classes are used to convert from WebInputEvent subclasses to // corresponding WebCore events. -class CORE_EXPORT WebMouseEventBuilder - : NON_EXPORTED_BASE(public WebMouseEvent) { +class CORE_EXPORT WebMouseEventBuilder : public WebMouseEvent { public: // Converts a MouseEvent to a corresponding WebMouseEvent. // NOTE: This is only implemented for mousemove, mouseover, mouseout, @@ -72,8 +71,7 @@ // NOTE: For KeyboardEvent, this is only implemented for keydown, // keyup, and keypress. If the event mapping fails, the event type will be set // to Undefined. -class CORE_EXPORT WebKeyboardEventBuilder - : NON_EXPORTED_BASE(public WebKeyboardEvent) { +class CORE_EXPORT WebKeyboardEventBuilder : public WebKeyboardEvent { public: WebKeyboardEventBuilder(const KeyboardEvent&); }; @@ -81,8 +79,7 @@ // Converts a TouchEvent to a corresponding WebTouchEvent. // NOTE: WebTouchEvents have a cap on the number of WebTouchPoints. Any points // exceeding that cap will be dropped. -class CORE_EXPORT WebTouchEventBuilder - : NON_EXPORTED_BASE(public WebTouchEvent) { +class CORE_EXPORT WebTouchEventBuilder : public WebTouchEvent { public: WebTouchEventBuilder(const LayoutItem, const TouchEvent&); };
diff --git a/third_party/WebKit/Source/core/exported/WebDevToolsAgentImpl.h b/third_party/WebKit/Source/core/exported/WebDevToolsAgentImpl.h index c7dfa1d5..6416a67 100644 --- a/third_party/WebKit/Source/core/exported/WebDevToolsAgentImpl.h +++ b/third_party/WebKit/Source/core/exported/WebDevToolsAgentImpl.h
@@ -62,12 +62,12 @@ class CORE_EXPORT WebDevToolsAgentImpl final : public GarbageCollectedFinalized<WebDevToolsAgentImpl>, - public NON_EXPORTED_BASE(WebDevToolsAgent), - public NON_EXPORTED_BASE(InspectorEmulationAgent::Client), - public NON_EXPORTED_BASE(InspectorTracingAgent::Client), - public NON_EXPORTED_BASE(InspectorPageAgent::Client), - public NON_EXPORTED_BASE(InspectorSession::Client), - public NON_EXPORTED_BASE(InspectorLayerTreeAgent::Client), + public WebDevToolsAgent, + public InspectorEmulationAgent::Client, + public InspectorTracingAgent::Client, + public InspectorPageAgent::Client, + public InspectorSession::Client, + public InspectorLayerTreeAgent::Client, private WebThread::TaskObserver { public: static WebDevToolsAgentImpl* Create(WebLocalFrameImpl*,
diff --git a/third_party/WebKit/Source/core/exported/WebDevToolsFrontendImpl.h b/third_party/WebKit/Source/core/exported/WebDevToolsFrontendImpl.h index 02d4bfc..6f409f98 100644 --- a/third_party/WebKit/Source/core/exported/WebDevToolsFrontendImpl.h +++ b/third_party/WebKit/Source/core/exported/WebDevToolsFrontendImpl.h
@@ -45,8 +45,8 @@ class WebLocalFrameImpl; class CORE_EXPORT WebDevToolsFrontendImpl final - : public NON_EXPORTED_BASE(WebDevToolsFrontend), - public NON_EXPORTED_BASE(InspectorFrontendClient) { + : public WebDevToolsFrontend, + public InspectorFrontendClient { WTF_MAKE_NONCOPYABLE(WebDevToolsFrontendImpl); public:
diff --git a/third_party/WebKit/Source/core/exported/WebFileChooserCompletionImpl.h b/third_party/WebKit/Source/core/exported/WebFileChooserCompletionImpl.h index 94c3f99a..16ac410 100644 --- a/third_party/WebKit/Source/core/exported/WebFileChooserCompletionImpl.h +++ b/third_party/WebKit/Source/core/exported/WebFileChooserCompletionImpl.h
@@ -41,7 +41,7 @@ namespace blink { class CORE_EXPORT WebFileChooserCompletionImpl final - : public NON_EXPORTED_BASE(WebFileChooserCompletion) { + : public WebFileChooserCompletion { public: explicit WebFileChooserCompletionImpl(RefPtr<FileChooser>); ~WebFileChooserCompletionImpl() override;
diff --git a/third_party/WebKit/Source/core/exported/WebFormElementObserverImpl.h b/third_party/WebKit/Source/core/exported/WebFormElementObserverImpl.h index 50983ba..9249290 100644 --- a/third_party/WebKit/Source/core/exported/WebFormElementObserverImpl.h +++ b/third_party/WebKit/Source/core/exported/WebFormElementObserverImpl.h
@@ -19,7 +19,7 @@ class CORE_EXPORT WebFormElementObserverImpl final : public GarbageCollectedFinalized<WebFormElementObserverImpl>, - NON_EXPORTED_BASE(public WebFormElementObserver) { + public WebFormElementObserver { WTF_MAKE_NONCOPYABLE(WebFormElementObserverImpl); public:
diff --git a/third_party/WebKit/Source/core/exported/WebInputMethodControllerImpl.h b/third_party/WebKit/Source/core/exported/WebInputMethodControllerImpl.h index 001d1c6..6dbf5d4 100644 --- a/third_party/WebKit/Source/core/exported/WebInputMethodControllerImpl.h +++ b/third_party/WebKit/Source/core/exported/WebInputMethodControllerImpl.h
@@ -21,7 +21,7 @@ class WebString; class CORE_EXPORT WebInputMethodControllerImpl - : public NON_EXPORTED_BASE(WebInputMethodController) { + : public WebInputMethodController { WTF_MAKE_NONCOPYABLE(WebInputMethodControllerImpl); DISALLOW_NEW();
diff --git a/third_party/WebKit/Source/core/exported/WebPagePopupImpl.h b/third_party/WebKit/Source/core/exported/WebPagePopupImpl.h index 949a233..8397da2 100644 --- a/third_party/WebKit/Source/core/exported/WebPagePopupImpl.h +++ b/third_party/WebKit/Source/core/exported/WebPagePopupImpl.h
@@ -52,11 +52,10 @@ class WebViewImpl; class LocalDOMWindow; -class CORE_EXPORT WebPagePopupImpl final - : public NON_EXPORTED_BASE(WebPagePopup), - public NON_EXPORTED_BASE(PageWidgetEventHandler), - public NON_EXPORTED_BASE(PagePopup), - public NON_EXPORTED_BASE(RefCounted<WebPagePopupImpl>) { +class CORE_EXPORT WebPagePopupImpl final : public WebPagePopup, + public PageWidgetEventHandler, + public PagePopup, + public RefCounted<WebPagePopupImpl> { WTF_MAKE_NONCOPYABLE(WebPagePopupImpl); USING_FAST_MALLOC(WebPagePopupImpl);
diff --git a/third_party/WebKit/Source/core/exported/WebPluginContainerImpl.h b/third_party/WebKit/Source/core/exported/WebPluginContainerImpl.h index 5c390505..3776b539 100644 --- a/third_party/WebKit/Source/core/exported/WebPluginContainerImpl.h +++ b/third_party/WebKit/Source/core/exported/WebPluginContainerImpl.h
@@ -65,7 +65,7 @@ class CORE_EXPORT WebPluginContainerImpl final : public GarbageCollectedFinalized<WebPluginContainerImpl>, public PluginView, - NON_EXPORTED_BASE(public WebPluginContainer), + public WebPluginContainer, public ContextClient { USING_GARBAGE_COLLECTED_MIXIN(WebPluginContainerImpl); USING_PRE_FINALIZER(WebPluginContainerImpl, PreFinalize);
diff --git a/third_party/WebKit/Source/core/exported/WebRemoteFrameImpl.h b/third_party/WebKit/Source/core/exported/WebRemoteFrameImpl.h index 944e2a6..fc1fb15 100644 --- a/third_party/WebKit/Source/core/exported/WebRemoteFrameImpl.h +++ b/third_party/WebKit/Source/core/exported/WebRemoteFrameImpl.h
@@ -22,8 +22,8 @@ class WebView; class CORE_EXPORT WebRemoteFrameImpl final - : public NON_EXPORTED_BASE(GarbageCollectedFinalized<WebRemoteFrameImpl>), - public NON_EXPORTED_BASE(WebRemoteFrame) { + : public GarbageCollectedFinalized<WebRemoteFrameImpl>, + public WebRemoteFrame { public: static WebRemoteFrameImpl* Create(WebTreeScopeType, WebRemoteFrameClient*); static WebRemoteFrameImpl* CreateMainFrame(WebView*,
diff --git a/third_party/WebKit/Source/core/exported/WebSettingsImpl.h b/third_party/WebKit/Source/core/exported/WebSettingsImpl.h index 92dbea6..89361798 100644 --- a/third_party/WebKit/Source/core/exported/WebSettingsImpl.h +++ b/third_party/WebKit/Source/core/exported/WebSettingsImpl.h
@@ -41,8 +41,7 @@ class DevToolsEmulator; class Settings; -class CORE_EXPORT WebSettingsImpl final - : NON_EXPORTED_BASE(public WebSettings) { +class CORE_EXPORT WebSettingsImpl final : public WebSettings { public: WebSettingsImpl(Settings*, DevToolsEmulator*); virtual ~WebSettingsImpl() {}
diff --git a/third_party/WebKit/Source/core/exported/WebTextCheckingCompletionImpl.h b/third_party/WebKit/Source/core/exported/WebTextCheckingCompletionImpl.h index 683af3d..798597df 100644 --- a/third_party/WebKit/Source/core/exported/WebTextCheckingCompletionImpl.h +++ b/third_party/WebKit/Source/core/exported/WebTextCheckingCompletionImpl.h
@@ -40,7 +40,7 @@ namespace blink { class CORE_EXPORT WebTextCheckingCompletionImpl final - : public NON_EXPORTED_BASE(WebTextCheckingCompletion) { + : public WebTextCheckingCompletion { public: explicit WebTextCheckingCompletionImpl(TextCheckingRequest* request) : request_(request) {}
diff --git a/third_party/WebKit/Source/core/exported/WebViewImpl.h b/third_party/WebKit/Source/core/exported/WebViewImpl.h index dde3c42..cfbd48a0 100644 --- a/third_party/WebKit/Source/core/exported/WebViewImpl.h +++ b/third_party/WebKit/Source/core/exported/WebViewImpl.h
@@ -98,9 +98,9 @@ class WebViewScheduler; class CORE_EXPORT WebViewImpl final - : NON_EXPORTED_BASE(public WebView), + : public WebView, public RefCounted<WebViewImpl>, - NON_EXPORTED_BASE(public WebGestureCurveTarget), + public WebGestureCurveTarget, public PageWidgetEventHandler, public WebScheduler::InterventionReporter, public WebViewScheduler::WebViewSchedulerDelegate {
diff --git a/third_party/WebKit/Source/core/exported/WorkerShadowPage.h b/third_party/WebKit/Source/core/exported/WorkerShadowPage.h index 3f446ef..da513ca 100644 --- a/third_party/WebKit/Source/core/exported/WorkerShadowPage.h +++ b/third_party/WebKit/Source/core/exported/WorkerShadowPage.h
@@ -34,7 +34,7 @@ // TODO(kinuko): Make this go away (https://crbug.com/538751). class CORE_EXPORT WorkerShadowPage : public WebFrameClient { public: - class CORE_EXPORT Client : NON_EXPORTED_BASE(public WebDevToolsAgentClient) { + class CORE_EXPORT Client : public WebDevToolsAgentClient { public: virtual ~Client() {}
diff --git a/third_party/WebKit/Source/core/frame/LocalFrame.cpp b/third_party/WebKit/Source/core/frame/LocalFrame.cpp index f260ad81..806d1436 100644 --- a/third_party/WebKit/Source/core/frame/LocalFrame.cpp +++ b/third_party/WebKit/Source/core/frame/LocalFrame.cpp
@@ -145,6 +145,8 @@ void LocalFrame::SetView(LocalFrameView* view) { DCHECK(!view_ || view_ != view); DCHECK(!GetDocument() || !GetDocument()->IsActive()); + if (view_) + view_->WillBeRemovedFromFrame(); view_ = view; }
diff --git a/third_party/WebKit/Source/core/frame/LocalFrameView.cpp b/third_party/WebKit/Source/core/frame/LocalFrameView.cpp index 55a1532..b7b41332 100644 --- a/third_party/WebKit/Source/core/frame/LocalFrameView.cpp +++ b/third_party/WebKit/Source/core/frame/LocalFrameView.cpp
@@ -2929,6 +2929,11 @@ return result; } +void LocalFrameView::WillBeRemovedFromFrame() { + if (paint_artifact_compositor_) + paint_artifact_compositor_->WillBeRemovedFromFrame(); +} + LocalFrameView* LocalFrameView::ParentFrameView() const { if (!is_attached_) return nullptr;
diff --git a/third_party/WebKit/Source/core/frame/LocalFrameView.h b/third_party/WebKit/Source/core/frame/LocalFrameView.h index 4ecd90d..93e7cdf 100644 --- a/third_party/WebKit/Source/core/frame/LocalFrameView.h +++ b/third_party/WebKit/Source/core/frame/LocalFrameView.h
@@ -288,6 +288,10 @@ Color DocumentBackgroundColor() const; + // Called when this view is going to be removed from its owning + // LocalFrame. + void WillBeRemovedFromFrame(); + // Run all needed lifecycle stages. After calling this method, all frames will // be in the lifecycle state PaintClean. If lifecycle throttling is allowed // (see DocumentLifecycle::AllowThrottlingScope), some frames may skip the
diff --git a/third_party/WebKit/Source/core/frame/WebFrameWidgetBase.h b/third_party/WebKit/Source/core/frame/WebFrameWidgetBase.h index e80246a..4a3d5e5 100644 --- a/third_party/WebKit/Source/core/frame/WebFrameWidgetBase.h +++ b/third_party/WebKit/Source/core/frame/WebFrameWidgetBase.h
@@ -29,7 +29,7 @@ class CORE_EXPORT WebFrameWidgetBase : public GarbageCollectedFinalized<WebFrameWidgetBase>, - public NON_EXPORTED_BASE(WebFrameWidget) { + public WebFrameWidget { public: virtual ~WebFrameWidgetBase() {}
diff --git a/third_party/WebKit/Source/core/frame/WebLocalFrameImpl.h b/third_party/WebKit/Source/core/frame/WebLocalFrameImpl.h index 548d045..664361ea 100644 --- a/third_party/WebKit/Source/core/frame/WebLocalFrameImpl.h +++ b/third_party/WebKit/Source/core/frame/WebLocalFrameImpl.h
@@ -81,8 +81,8 @@ // Implementation of WebFrame, note that this is a reference counted object. class CORE_EXPORT WebLocalFrameImpl final - : public NON_EXPORTED_BASE(GarbageCollectedFinalized<WebLocalFrameImpl>), - public NON_EXPORTED_BASE(WebLocalFrame) { + : public GarbageCollectedFinalized<WebLocalFrameImpl>, + public WebLocalFrame { public: // WebFrame methods: // TODO(dcheng): Fix sorting here; a number of method have been moved to
diff --git a/third_party/WebKit/Source/core/html/forms/ColorChooserUIController.h b/third_party/WebKit/Source/core/html/forms/ColorChooserUIController.h index 82c14ffd..7dbedfb 100644 --- a/third_party/WebKit/Source/core/html/forms/ColorChooserUIController.h +++ b/third_party/WebKit/Source/core/html/forms/ColorChooserUIController.h
@@ -41,7 +41,7 @@ class CORE_EXPORT ColorChooserUIController : public GarbageCollectedFinalized<ColorChooserUIController>, - NON_EXPORTED_BASE(public WebColorChooserClient), + public WebColorChooserClient, public ColorChooser { USING_GARBAGE_COLLECTED_MIXIN(ColorChooserUIController);
diff --git a/third_party/WebKit/Source/core/html/forms/DateTimeChooserImpl.h b/third_party/WebKit/Source/core/html/forms/DateTimeChooserImpl.h index e0404230..3dc4899c 100644 --- a/third_party/WebKit/Source/core/html/forms/DateTimeChooserImpl.h +++ b/third_party/WebKit/Source/core/html/forms/DateTimeChooserImpl.h
@@ -42,9 +42,8 @@ class DateTimeChooserClient; class PagePopup; -class CORE_EXPORT DateTimeChooserImpl final - : public NON_EXPORTED_BASE(DateTimeChooser), - public NON_EXPORTED_BASE(PagePopupClient) { +class CORE_EXPORT DateTimeChooserImpl final : public DateTimeChooser, + public PagePopupClient { public: static DateTimeChooserImpl* Create(ChromeClient*, DateTimeChooserClient*,
diff --git a/third_party/WebKit/Source/core/html/forms/ExternalPopupMenu.h b/third_party/WebKit/Source/core/html/forms/ExternalPopupMenu.h index 2a556b7..b7ab6aa 100644 --- a/third_party/WebKit/Source/core/html/forms/ExternalPopupMenu.h +++ b/third_party/WebKit/Source/core/html/forms/ExternalPopupMenu.h
@@ -51,7 +51,7 @@ // The ExternalPopupMenu is a PopupMenu implementation for macOS and Android. // It uses a OS-native menu implementation. -class CORE_EXPORT ExternalPopupMenu final : NON_EXPORTED_BASE(public PopupMenu), +class CORE_EXPORT ExternalPopupMenu final : public PopupMenu, public WebExternalPopupMenuClient { public: ExternalPopupMenu(LocalFrame&, HTMLSelectElement&, WebView&);
diff --git a/third_party/WebKit/Source/core/html/forms/InternalPopupMenu.h b/third_party/WebKit/Source/core/html/forms/InternalPopupMenu.h index 56072f8..bc67d535 100644 --- a/third_party/WebKit/Source/core/html/forms/InternalPopupMenu.h +++ b/third_party/WebKit/Source/core/html/forms/InternalPopupMenu.h
@@ -21,7 +21,7 @@ // InternalPopupMenu is a PopupMenu implementation for platforms other than // macOS and Android. The UI is built with an HTML page inside a PagePopup. -class CORE_EXPORT InternalPopupMenu final : NON_EXPORTED_BASE(public PopupMenu), +class CORE_EXPORT InternalPopupMenu final : public PopupMenu, public PagePopupClient { public: static InternalPopupMenu* Create(ChromeClient*, HTMLSelectElement&);
diff --git a/third_party/WebKit/Source/core/html/parser/XSSAuditor.cpp b/third_party/WebKit/Source/core/html/parser/XSSAuditor.cpp index b97d63f..2a979d14 100644 --- a/third_party/WebKit/Source/core/html/parser/XSSAuditor.cpp +++ b/third_party/WebKit/Source/core/html/parser/XSSAuditor.cpp
@@ -786,11 +786,20 @@ String XSSAuditor::CanonicalizedSnippetForTagName( const FilterTokenRequest& request) { + String source = request.source_tracker.SourceForToken(request.token); + + // TODO(tsepez): fix HTMLSourceTracker not to include NULs. + // Beware that the source tracker may include leading NULs as part of + // the souce for the token. + unsigned start = 0; + for (start = 0; start < source.length() && source[start] == '\0'; ++start) + continue; + // Grab a fixed number of characters equal to the length of the token's name // plus one (to account for the "<"). - return Canonicalize(request.source_tracker.SourceForToken(request.token) - .Substring(0, request.token.GetName().size() + 1), - kNoTruncation); + return Canonicalize( + source.Substring(start, request.token.GetName().size() + 1), + kNoTruncation); } String XSSAuditor::NameFromAttribute(const FilterTokenRequest& request,
diff --git a/third_party/WebKit/Source/core/inspector/InspectorOverlayAgent.h b/third_party/WebKit/Source/core/inspector/InspectorOverlayAgent.h index 8c8740c..60e249e 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorOverlayAgent.h +++ b/third_party/WebKit/Source/core/inspector/InspectorOverlayAgent.h
@@ -61,8 +61,8 @@ class WebTouchEvent; class CORE_EXPORT InspectorOverlayAgent final - : public NON_EXPORTED_BASE(InspectorBaseAgent<protocol::Overlay::Metainfo>), - public NON_EXPORTED_BASE(InspectorOverlayHost::Listener) { + : public InspectorBaseAgent<protocol::Overlay::Metainfo>, + public InspectorOverlayHost::Listener { WTF_MAKE_NONCOPYABLE(InspectorOverlayAgent); USING_GARBAGE_COLLECTED_MIXIN(InspectorOverlayAgent);
diff --git a/third_party/WebKit/Source/core/inspector/browser_protocol.json b/third_party/WebKit/Source/core/inspector/browser_protocol.json index 0591283..0565267 100644 --- a/third_party/WebKit/Source/core/inspector/browser_protocol.json +++ b/third_party/WebKit/Source/core/inspector/browser_protocol.json
@@ -1420,6 +1420,23 @@ "experimental": true }, { + "id": "CookieParam", + "type": "object", + "description": "Cookie parameter object", + "properties": [ + { "name": "name", "type": "string", "description": "Cookie name." }, + { "name": "value", "type": "string", "description": "Cookie value." }, + { "name": "url", "type": "string", "optional": true, "description": "The request-URI to associate with the setting of the cookie. This value can affect the default domain and path values of the created cookie." }, + { "name": "domain", "type": "string", "optional": true, "description": "Cookie domain." }, + { "name": "path", "type": "string", "optional": true, "description": "Cookie path." }, + { "name": "secure", "type": "boolean", "optional": true, "description": "True if cookie is secure." }, + { "name": "httpOnly", "type": "boolean", "optional": true, "description": "True if cookie is http-only." }, + { "name": "sameSite", "$ref": "CookieSameSite", "optional": true, "description": "Cookie SameSite type." }, + { "name": "expires", "$ref": "TimeSinceEpoch", "optional": true, "description": "Cookie expiration date, session cookie if not set" } + ], + "experimental": true + }, + { "id": "AuthChallenge", "type": "object", "description": "Authorization challenge for HTTP status code 401 or 407.", @@ -1550,15 +1567,15 @@ { "name": "setCookie", "parameters": [ - { "name": "url", "type": "string", "description": "The request-URI to associate with the setting of the cookie. This value can affect the default domain and path values of the created cookie." }, - { "name": "name", "type": "string", "description": "The name of the cookie." }, - { "name": "value", "type": "string", "description": "The value of the cookie." }, - { "name": "domain", "type": "string", "optional": true, "description": "If omitted, the cookie becomes a host-only cookie." }, - { "name": "path", "type": "string", "optional": true, "description": "Defaults to the path portion of the url parameter." }, - { "name": "secure", "type": "boolean", "optional": true, "description": "Defaults ot false." }, - { "name": "httpOnly", "type": "boolean", "optional": true, "description": "Defaults to false." }, - { "name": "sameSite", "$ref": "CookieSameSite", "optional": true, "description": "Defaults to browser default behavior." }, - { "name": "expirationDate", "$ref": "TimeSinceEpoch", "optional": true, "description": "If omitted, the cookie becomes a session cookie." } + { "name": "name", "type": "string", "description": "Cookie name." }, + { "name": "value", "type": "string", "description": "Cookie value." }, + { "name": "url", "type": "string", "optional": true, "description": "The request-URI to associate with the setting of the cookie. This value can affect the default domain and path values of the created cookie." }, + { "name": "domain", "type": "string", "optional": true, "description": "Cookie domain." }, + { "name": "path", "type": "string", "optional": true, "description": "Cookie path." }, + { "name": "secure", "type": "boolean", "optional": true, "description": "True if cookie is secure." }, + { "name": "httpOnly", "type": "boolean", "optional": true, "description": "True if cookie is http-only." }, + { "name": "sameSite", "$ref": "CookieSameSite", "optional": true, "description": "Cookie SameSite type." }, + { "name": "expires", "$ref": "TimeSinceEpoch", "optional": true, "description": "Cookie expiration date, session cookie if not set" } ], "returns": [ { "name": "success", "type": "boolean", "description": "True if successfully set cookie." } @@ -1567,6 +1584,14 @@ "experimental": true }, { + "name": "setCookies", + "parameters": [ + { "name": "cookies", "type": "array", "items": { "$ref": "CookieParam" }, "description": "Cookies to be set." } + ], + "description": "Sets given cookies.", + "experimental": true + }, + { "name": "canEmulateNetworkConditions", "description": "Tells whether emulation of network conditions is supported.", "returns": [ @@ -4081,13 +4106,15 @@ { "name": "dispatchMouseEvent", "parameters": [ - { "name": "type", "type": "string", "enum": ["mousePressed", "mouseReleased", "mouseMoved"], "description": "Type of the mouse event." }, + { "name": "type", "type": "string", "enum": ["mousePressed", "mouseReleased", "mouseMoved", "mouseWheel"], "description": "Type of the mouse event." }, { "name": "x", "type": "number", "description": "X coordinate of the event relative to the main frame's viewport in CSS pixels."}, { "name": "y", "type": "number", "description": "Y coordinate of the event relative to the main frame's viewport in CSS pixels. 0 refers to the top of the viewport and Y increases as it proceeds towards the bottom of the viewport."}, { "name": "modifiers", "type": "integer", "optional": true, "description": "Bit field representing pressed modifier keys. Alt=1, Ctrl=2, Meta/Command=4, Shift=8 (default: 0)." }, { "name": "timestamp", "$ref": "TimeSinceEpoch", "optional": true, "description": "Time at which the event occurred." }, { "name": "button", "type": "string", "enum": ["none", "left", "middle", "right"], "optional": true, "description": "Mouse button (default: \"none\")." }, - { "name": "clickCount", "type": "integer", "optional": true, "description": "Number of times the mouse button was clicked (default: 0)." } + { "name": "clickCount", "type": "integer", "optional": true, "description": "Number of times the mouse button was clicked (default: 0)." }, + { "name": "deltaX", "type": "number", "optional": true, "description": "X delta in CSS pixels for mouse wheel event (default: 0)."}, + { "name": "deltaY", "type": "number", "optional": true, "description": "Y delta in CSS pixels for mouse wheel event (default: 0)."} ], "description": "Dispatches a mouse event to the page." },
diff --git a/third_party/WebKit/Source/core/inspector/inspector_protocol_config.json b/third_party/WebKit/Source/core/inspector/inspector_protocol_config.json index e33b4d8..6882d6d 100644 --- a/third_party/WebKit/Source/core/inspector/inspector_protocol_config.json +++ b/third_party/WebKit/Source/core/inspector/inspector_protocol_config.json
@@ -95,7 +95,7 @@ }, { "domain": "Network", - "exclude": ["clearBrowserCache", "clearBrowserCookies", "getCookies", "getAllCookies", "deleteCookie", "setCookie", "canEmulateNetworkConditions", + "exclude": ["clearBrowserCache", "clearBrowserCookies", "getCookies", "getAllCookies", "deleteCookie", "setCookie", "setCookies", "canEmulateNetworkConditions", "setRequestInterceptionEnabled", "continueInterceptedRequest"], "async": ["getResponseBody"] },
diff --git a/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp b/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp index 23fccaf..75f77e9 100644 --- a/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp
@@ -1184,7 +1184,7 @@ // min/max/preferred size, run layout on it now to make sure its logical // height and scroll bars are up to date. if (layout_type != kNeverLayout && ChildHasIntrinsicMainAxisSize(child) && - child.NeedsLayout()) { + (child.NeedsLayout() || IsColumnFlow())) { child.ClearOverrideSize(); child.ForceChildLayout(); CacheChildMainSize(child);
diff --git a/third_party/WebKit/Source/core/layout/ScrollbarsTest.cpp b/third_party/WebKit/Source/core/layout/ScrollbarsTest.cpp index fd5d223..9134e73 100644 --- a/third_party/WebKit/Source/core/layout/ScrollbarsTest.cpp +++ b/third_party/WebKit/Source/core/layout/ScrollbarsTest.cpp
@@ -5,6 +5,7 @@ #include "build/build_config.h" #include "core/frame/LocalFrameView.h" #include "core/frame/WebLocalFrameImpl.h" +#include "core/input/EventHandler.h" #include "core/layout/LayoutView.h" #include "core/paint/PaintLayerScrollableArea.h" #include "core/testing/sim/SimDisplayItemList.h" @@ -140,6 +141,43 @@ public SimTest { public: ParameterizedScrollbarsTest() : ScopedRootLayerScrollingForTest(GetParam()) {} + + HitTestResult HitTest(int x, int y) { + return WebView().CoreHitTestResultAt(WebPoint(x, y)); + } + + EventHandler& EventHandler() { + return GetDocument().GetFrame()->GetEventHandler(); + } + + void HandleMouseMoveEvent(int x, int y) { + WebMouseEvent event( + WebInputEvent::kMouseMove, WebFloatPoint(x, y), WebFloatPoint(x, y), + WebPointerProperties::Button::kNoButton, 0, WebInputEvent::kNoModifiers, + TimeTicks::Now().InSeconds()); + event.SetFrameScale(1); + EventHandler().HandleMouseMoveEvent(event, Vector<WebMouseEvent>()); + } + + void HandleMousePressEvent(int x, int y) { + WebMouseEvent event(WebInputEvent::kMouseDown, WebFloatPoint(x, y), + WebFloatPoint(x, y), + WebPointerProperties::Button::kLeft, 0, + WebInputEvent::Modifiers::kLeftButtonDown, + TimeTicks::Now().InSeconds()); + event.SetFrameScale(1); + EventHandler().HandleMousePressEvent(event); + } + + void HandleMouseReleaseEvent(int x, int y) { + WebMouseEvent event(WebInputEvent::kMouseUp, WebFloatPoint(x, y), + WebFloatPoint(x, y), + WebPointerProperties::Button::kLeft, 0, + WebInputEvent::Modifiers::kLeftButtonDown, + TimeTicks::Now().InSeconds()); + event.SetFrameScale(1); + EventHandler().HandleMouseReleaseEvent(event); + } }; INSTANTIATE_TEST_CASE_P(All, ParameterizedScrollbarsTest, ::testing::Bool()); @@ -217,6 +255,56 @@ EXPECT_TRUE(scrollable_root->HorizontalScrollbar()->FrameRect().IsEmpty()); } +// Ensure hit test correct for scrollbar of element with translateZ(0) +TEST_P(ParameterizedScrollbarsTest, HitTestTranslateZElementScrollbar) { + RuntimeEnabledFeatures::SetOverlayScrollbarsEnabled(false); + + WebView().Resize(WebSize(200, 200)); + SimRequest request("https://example.com/test.html", "text/html"); + LoadURL("https://example.com/test.html"); + request.Complete( + "<!DOCTYPE html>" + "<style>" + "body {" + " margin: 0;" + "}" + "#trans {" + " overflow: auto;" + " transform: translateZ(0);" + " position: absolute;" + " top: 0;" + " bottom: 0;" + " left: 20px;" + " width: 100px;" + " height: 100px;" + "}" + "#long {" + " height: 1000px;" + "}" + "</style>" + "<div id='trans'>" + " <div id='long'></div>" + "</div>"); + Compositor().BeginFrame(); + + Document& document = GetDocument(); + Element* div = document.getElementById("trans"); + + // Ensure we have scrollbar for trans-z div. + ScrollableArea* scrollable_div = + ToLayoutBox(div->GetLayoutObject())->GetScrollableArea(); + + DCHECK(scrollable_div->VerticalScrollbar()); + DCHECK(!scrollable_div->VerticalScrollbar()->IsOverlayScrollbar()); + + HitTestResult result = HitTest(110, 10); + DCHECK(result.GetScrollbar()); + + HandleMouseMoveEvent(110, 10); + EXPECT_EQ(scrollable_div->VerticalScrollbar()->HoveredPart(), + ScrollbarPart::kThumbPart); +} + typedef bool TestParamOverlayScrollbar; class ScrollbarAppearanceTest : public SimTest, @@ -241,6 +329,13 @@ return WebSize(); } } + void GetOverlayScrollbarStyle(ScrollbarStyle* style) override { + style->fade_out_delay_seconds = 0; + style->fade_out_duration_seconds = 0; + style->thumb_thickness = 3; + style->scrollbar_margin = 0; + style->color = SkColorSetARGB(128, 64, 64, 64); + } static constexpr int kMinimumHorizontalLength = 51; static constexpr int kMinimumVerticalLength = 52; }; @@ -285,6 +380,38 @@ EXPECT_EQ(StubWebThemeEngine::kMinimumVerticalLength, theme.ThumbLength(*scrollable_area->VerticalScrollbar())); } + +// Ensure thumb position is correctly calculated even at ridiculously large +// scales. +TEST_P(ScrollbarAppearanceTest, HugeScrollingThumbPosition) { + ScopedTestingPlatformSupport<ScrollbarTestingPlatformSupport> platform; + + v8::HandleScope handle_scope(v8::Isolate::GetCurrent()); + WebView().Resize(WebSize(1000, 1000)); + SimRequest request("https://example.com/test.html", "text/html"); + LoadURL("https://example.com/test.html"); + request.Complete( + "<style> body { margin: 0px; height: 10000000px; } </style>"); + ScrollableArea* scrollable_area = + GetDocument().View()->LayoutViewportScrollableArea(); + + Compositor().BeginFrame(); + + scrollable_area->SetScrollOffset(ScrollOffset(0, 10000000), + kProgrammaticScroll); + + int scroll_y = scrollable_area->GetScrollOffset().Height(); + ASSERT_EQ(9999000, scroll_y); + + Scrollbar* scrollbar = scrollable_area->VerticalScrollbar(); + ASSERT_TRUE(scrollbar); + + int maximumThumbPosition = + WebView().Size().height - StubWebThemeEngine::kMinimumVerticalLength; + + EXPECT_EQ(maximumThumbPosition, + scrollbar->GetTheme().ThumbPosition(*scrollbar)); +} #endif } // namespace
diff --git a/third_party/WebKit/Source/core/layout/api/LayoutSliderItem.h b/third_party/WebKit/Source/core/layout/api/LayoutSliderItem.h index 0e32e417..cc4c7890 100644 --- a/third_party/WebKit/Source/core/layout/api/LayoutSliderItem.h +++ b/third_party/WebKit/Source/core/layout/api/LayoutSliderItem.h
@@ -12,7 +12,7 @@ class LayoutSlider; -class CORE_EXPORT LayoutSliderItem : NON_EXPORTED_BASE(public LayoutBlockItem) { +class CORE_EXPORT LayoutSliderItem : public LayoutBlockItem { public: explicit LayoutSliderItem(LayoutSlider*);
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_offset_mapping_result.h b/third_party/WebKit/Source/core/layout/ng/inline/ng_offset_mapping_result.h index a59cc61..32d86d7 100644 --- a/third_party/WebKit/Source/core/layout/ng/inline/ng_offset_mapping_result.h +++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_offset_mapping_result.h
@@ -54,12 +54,9 @@ // Ideally, we should store |Node| as owner, instead of |LayoutObject|. // However, we need to ensure the invariant that, units of the same owner are - // consecutive in |NGOffsetMappingResult::units|. This might have a subtle - // conflict with :first-letter if, during inline collection, there there are - // other strings collected between the first letter and the remaining text of - // the node. - // TODO(xiaochengh): Figure out if this the issue really exists. If not, then - // we should use |Node| as owner. + // consecutive in |NGOffsetMappingResult::units|. There is a tricky case in + // ::first-letter handling that, the first letter and remaining text are not + // even laid out in the same block. As a workaround, we store |LayoutObject|. const LayoutText* const owner_; const unsigned dom_start_;
diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGText.cpp b/third_party/WebKit/Source/core/layout/svg/LayoutSVGText.cpp index 9d19e43b..f676c6c0 100644 --- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGText.cpp +++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGText.cpp
@@ -201,6 +201,11 @@ // update them before updating the layout attributes. if (needs_text_metrics_update_) { UpdateFontAndMetrics(*this); + // Font changes may change the size of the "em" unit, so we need to + // update positions that might depend on the font size. This is a big + // hammer but we have no simple way to determine if the positions of + // children depend on the font size. + needs_positioning_values_update_ = true; needs_text_metrics_update_ = false; update_parent_boundaries = true; }
diff --git a/third_party/WebKit/Source/core/loader/EmptyClients.h b/third_party/WebKit/Source/core/loader/EmptyClients.h index dce0445..aba21ce8 100644 --- a/third_party/WebKit/Source/core/loader/EmptyClients.h +++ b/third_party/WebKit/Source/core/loader/EmptyClients.h
@@ -451,8 +451,7 @@ void ClearContextMenu() override {} }; -class CORE_EXPORT EmptyRemoteFrameClient - : NON_EXPORTED_BASE(public RemoteFrameClient) { +class CORE_EXPORT EmptyRemoteFrameClient : public RemoteFrameClient { WTF_MAKE_NONCOPYABLE(EmptyRemoteFrameClient); public:
diff --git a/third_party/WebKit/Source/core/loader/appcache/ApplicationCacheHost.h b/third_party/WebKit/Source/core/loader/appcache/ApplicationCacheHost.h index 0dbd6a08..4a468a01 100644 --- a/third_party/WebKit/Source/core/loader/appcache/ApplicationCacheHost.h +++ b/third_party/WebKit/Source/core/loader/appcache/ApplicationCacheHost.h
@@ -48,7 +48,7 @@ class CORE_EXPORT ApplicationCacheHost final : public GarbageCollectedFinalized<ApplicationCacheHost>, - NON_EXPORTED_BASE(public WebApplicationCacheHostClient) { + public WebApplicationCacheHostClient { WTF_MAKE_NONCOPYABLE(ApplicationCacheHost); public:
diff --git a/third_party/WebKit/Source/core/page/ChromeClient.h b/third_party/WebKit/Source/core/page/ChromeClient.h index 97edcc1..e34a1c1 100644 --- a/third_party/WebKit/Source/core/page/ChromeClient.h +++ b/third_party/WebKit/Source/core/page/ChromeClient.h
@@ -280,6 +280,7 @@ virtual void SetBrowserControlsState(float top_height, float bottom_height, bool shrinks_layout){}; + virtual void SetBrowserControlsShownRatio(float){}; virtual String AcceptLanguages() = 0;
diff --git a/third_party/WebKit/Source/core/page/ChromeClientImpl.cpp b/third_party/WebKit/Source/core/page/ChromeClientImpl.cpp index 4dbecac..979d760 100644 --- a/third_party/WebKit/Source/core/page/ChromeClientImpl.cpp +++ b/third_party/WebKit/Source/core/page/ChromeClientImpl.cpp
@@ -45,6 +45,7 @@ #include "core/exported/WebRemoteFrameImpl.h" #include "core/exported/WebSettingsImpl.h" #include "core/exported/WebViewImpl.h" +#include "core/frame/BrowserControls.h" #include "core/frame/LocalFrameView.h" #include "core/frame/Settings.h" #include "core/frame/UseCounter.h" @@ -813,6 +814,11 @@ shrinks_layout); } +void ChromeClientImpl::SetBrowserControlsShownRatio(float ratio) { + web_view_->GetBrowserControls().SetShownRatio(ratio); + web_view_->DidUpdateBrowserControls(); +} + bool ChromeClientImpl::ShouldOpenModalDialogDuringPageDismissal( LocalFrame& frame, DialogType dialog_type,
diff --git a/third_party/WebKit/Source/core/page/ChromeClientImpl.h b/third_party/WebKit/Source/core/page/ChromeClientImpl.h index c74cbde..98cdc86a 100644 --- a/third_party/WebKit/Source/core/page/ChromeClientImpl.h +++ b/third_party/WebKit/Source/core/page/ChromeClientImpl.h
@@ -186,6 +186,7 @@ void SetBrowserControlsState(float top_height, float bottom_height, bool shrinks_layout) override; + void SetBrowserControlsShownRatio(float) override; bool ShouldOpenModalDialogDuringPageDismissal( LocalFrame&,
diff --git a/third_party/WebKit/Source/core/page/ValidationMessageClientImpl.h b/third_party/WebKit/Source/core/page/ValidationMessageClientImpl.h index ec65f0a..2a3e93a 100644 --- a/third_party/WebKit/Source/core/page/ValidationMessageClientImpl.h +++ b/third_party/WebKit/Source/core/page/ValidationMessageClientImpl.h
@@ -43,7 +43,7 @@ class CORE_EXPORT ValidationMessageClientImpl final : public GarbageCollectedFinalized<ValidationMessageClientImpl>, - public NON_EXPORTED_BASE(ValidationMessageClient), + public ValidationMessageClient, private PopupOpeningObserver { USING_GARBAGE_COLLECTED_MIXIN(ValidationMessageClientImpl);
diff --git a/third_party/WebKit/Source/core/page/scrolling/README.md b/third_party/WebKit/Source/core/page/scrolling/README.md index d02436d..f76fc89 100644 --- a/third_party/WebKit/Source/core/page/scrolling/README.md +++ b/third_party/WebKit/Source/core/page/scrolling/README.md
@@ -15,7 +15,7 @@ to an arbitrary scroller. See the [explainer doc](https://github.com/bokand/NonDocumentRootScroller/blob/master/explainer.md) for a quick overview. -##### Implementation Details +### Implementation Details There are three notions of `rootScroller`: the _document rootScroller_, the _effective rootScroller_, and the _global rootScroller_. @@ -52,6 +52,96 @@ applyScroll callback. The _global rootScroller_ will always have the ViewportScrollCallback set as its applyScroll. +### Composition and iframes + +The rootScroller can be composed across documents. For example, suppose we have +the following document structure: + +``` ++--------------------------------------+ +| Root Document | +| +-----------------------------+ | +| | iFrame | | +| | +------------------+ | | +| | | <scrolling div> | | | +| | +------------------+ | | +| +-----------------------------+ | ++--------------------------------------+ +``` + +We want to make the scrolling div be the global rootScroller (scrolling it +should move the URL bar). + +Iframes are special when computing rootScrollers, they delegate computation of +the _global rootScroller_ to the _effective rootScroller_ of their content +document. In the above case, we'd need to set: + +``` +rootDocument.rootScroller = iframe; +iframeDocument.rootScroller = scrollingDiv; +``` + +If both the iframe and scrollingDiv are valid _effective rootScrollers_ then +the scrolling div will become the _global rootScroller_. + +One complication here has to do with clipping. Since the iframe must be a valid +rootScroller, it must have `width: 100%; height: 100%`. This means that when +the URL bar is hidden, the iframe wont fill the viewport and so it'll normally +clip the contents of the _global rootScroller_ (`height 100%` is statically +sized to fill the viewport when the URL bar is showing). We compensate for this +by making the iframe geometry match its parent frame when it is the _effective +rootScroller_. We also set the layout size to match the parent's layout size so +that we preserve the URL bar semantics of the root frame WRT layout. i.e. +`100vh` is larger than `height: 100%` by the size of the URL bar. + +We also disabling clipping (`SetMasksToBounds(false)`) on any iframes that have +the _global RootScroller_ as a descendant during the compositing stage of the +document lifecycle. This prevents clipping during URL bar movement, before +Blink receives a resize. + +### position: fixed + +position: fixed Elements are statically positioned relative to any viewport +scrolling. Generally, they'll be positioned relative to the viewport container +layer so they don't move with scrolling. + +When the URL bar is shown or hidden, the viewport will resize and so any +bottom-fixed layers will need move to account for the newly exposed or hidden +space (since they're positioned relative to the layer top). i.e. They appear to +stay fixed to the bottom of the device viewport. However, this is all done +from Blink when a Resize message is received. For URL bar resizes, a resize +message is sent to Blink only once the user has lifted their finger from the +screen. While the user has their finger down and is scrolling, moving the URL +bar, Blink isn't notified of these changes. Since the layers are positioned +relative to their container's origin (the top), if we want position: bottom +layers to appear fixed to the bottom during the scroll we need to adjust their +position dynamically on the compositor. + +This adjustment happens in CC in +LayerTreeHostImpl::UpdateViewportContainerSizes. The inner and outer viewports +have their bounds modified by setting a "bounds delta". This delta is non-0 +only while the URL bar is being moved, before the Resize is sent to Blink, and +accounts for changes that Blink doesn't know about yet. Once Blink gets the +resize, the layers' true bounds are updated and the delta is cleared. The +bounds\_delta is used by the TransformTree to create a transform node that +will translate bottom-fixed layers to compensate for the URL bar resize before +Blink has a chance to resize and reposition them. + +For a non-defualt document.rootScroller, we want position: fixed layers to +behave the same way. When we set a _global rootScroller_, Blink sets it as +CC's _outer viewport_. This means that we get the container resize and +position: fixed behaviors for free. However, we also want position: fixed +Elements in parent frames to also behave as if they're fixed to the viewport. +For example, a page may want to embed an iframe with some content that's +semantically the rootScroller. However, it may want to add a position: fixed +banner at the bottom of the page. It can't insert it into the iframe because it +may be cross-origin but we still want it to stay fixed to the bottom of the +viewport, not the iframe. To solve this, all rootScroller's ancestor frames are +marked with a special bit, is\_resized\_by\_browser\_controls. The transform +tree construction relative to the outer viewport's bounds\_delta mentioned +above will apply to any layer marked with this bit. This makes position: fixed +layers for all rootScroller ancestors get translated by the URL bar delta. + ## ViewportScrollCallback The ViewportScrollCallback is a Scroll Customization apply-scroll callback
diff --git a/third_party/WebKit/Source/core/page/scrolling/TopDocumentRootScrollerController.cpp b/third_party/WebKit/Source/core/page/scrolling/TopDocumentRootScrollerController.cpp index 698d5d6..485550e 100644 --- a/third_party/WebKit/Source/core/page/scrolling/TopDocumentRootScrollerController.cpp +++ b/third_party/WebKit/Source/core/page/scrolling/TopDocumentRootScrollerController.cpp
@@ -107,6 +107,24 @@ return element; } +void SetNeedsCompositingUpdateOnAncestors(ScrollableArea* area) { + if (!area || !area->Layer()) + return; + + Frame* frame = area->Layer()->GetLayoutObject().GetFrame(); + for (; frame; frame = frame->Tree().Parent()) { + if (!frame->IsLocalFrame()) + continue; + + PaintLayerCompositor* plc = + ToLocalFrame(frame)->View()->GetLayoutView()->Compositor(); + if (plc) { + plc->SetNeedsCompositingUpdate( + kCompositingUpdateAfterCompositingInputChange); + } + } +} + void TopDocumentRootScrollerController::RecomputeGlobalRootScroller() { if (!viewport_apply_scroll_) return; @@ -141,6 +159,9 @@ // in RootFrameViewport. viewport_apply_scroll_->SetScroller(target_scroller); + SetNeedsCompositingUpdateOnAncestors(old_root_scroller_area); + SetNeedsCompositingUpdateOnAncestors(target_scroller); + if (old_root_scroller_area) old_root_scroller_area->DidChangeGlobalRootScroller();
diff --git a/third_party/WebKit/Source/core/paint/FragmentData.h b/third_party/WebKit/Source/core/paint/FragmentData.h index bae141b..e0ca84a 100644 --- a/third_party/WebKit/Source/core/paint/FragmentData.h +++ b/third_party/WebKit/Source/core/paint/FragmentData.h
@@ -15,7 +15,7 @@ // Represents the data for a particular fragment of a LayoutObject. // Only LayoutObjects with a self-painting PaintLayer may have more than one -// FragmentDeta, and even then only when they are inside of multicol. +// FragmentData, and even then only when they are inside of multicol. // See README.md. class CORE_EXPORT FragmentData { public: @@ -29,9 +29,9 @@ ObjectPaintProperties& EnsurePaintProperties(); void ClearPaintProperties(); - // The complete set of property nodes that should be used as a starting point - // to paint this fragment. See also the comment for - // RarePaintData::local_border_box_properties_. + // The complete set of property nodes that should be used as a + // starting point to paint this fragment. See also the comment for + // |local_border_box_properties_|. PropertyTreeState* LocalBorderBoxProperties() const { return local_border_box_properties_.get(); } @@ -39,10 +39,10 @@ void ClearLocalBorderBoxProperties(); void SetLocalBorderBoxProperties(PropertyTreeState&); - // This is the complete set of property nodes that can be used to paint the - // contents of this fragment. It is similar to local_border_box_properties_ - // but includes properties (e.g., overflow clip, scroll translation) that - // apply to contents. + // This is the complete set of property nodes that can be used to + // paint the contents of this fragment. It is similar to + // |local_border_box_properties_| but includes properties (e.g., + // overflow clip, scroll translation) that apply to contents. PropertyTreeState ContentsProperties() const; FragmentData* NextFragment() { return next_fragment_.get(); }
diff --git a/third_party/WebKit/Source/core/paint/PaintLayer.cpp b/third_party/WebKit/Source/core/paint/PaintLayer.cpp index 6521afb..2e2a19c 100644 --- a/third_party/WebKit/Source/core/paint/PaintLayer.cpp +++ b/third_party/WebKit/Source/core/paint/PaintLayer.cpp
@@ -2084,7 +2084,7 @@ DCHECK(frame_view); IntPoint frame_point = - frame_view->ContentsToFrame(RoundedIntPoint(hit_test_location.Point())); + frame_view->ContentsToFrame(result.RoundedPointInContent()); IntPoint local_point = frame_view->ConvertToLayoutItem( LayoutBoxItem(GetLayoutBox()), frame_point); @@ -2093,7 +2093,7 @@ // If hit overflow controls, innerNode should be the scrollable_area_ node. if (hit_overflow_controls) { - if (scrollable_area_ && scrollable_area_->GetLayoutBox() && + if (scrollable_area_->GetLayoutBox() && scrollable_area_->GetLayoutBox()->GetNode()) { Node* node = scrollable_area_->GetLayoutBox()->GetNode();
diff --git a/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilderTest.cpp b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilderTest.cpp index 499036b..578d00d 100644 --- a/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilderTest.cpp +++ b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilderTest.cpp
@@ -554,7 +554,7 @@ "</div>"); LayoutObject* node_without_opacity = - GetDocument().getElementById("nodeWithoutOpacity")->GetLayoutObject(); + GetLayoutObjectByElementId("nodeWithoutOpacity"); const FragmentData* node_without_opacity_properties = node_without_opacity->FirstFragment(); EXPECT_EQ(nullptr, node_without_opacity_properties); @@ -562,7 +562,7 @@ GetDocument().View()->GetLayoutView()); LayoutObject* child_with_opacity = - GetDocument().getElementById("childWithOpacity")->GetLayoutObject(); + GetLayoutObjectByElementId("childWithOpacity"); const ObjectPaintProperties* child_with_opacity_properties = child_with_opacity->FirstFragment()->PaintProperties(); EXPECT_EQ(0.5f, child_with_opacity_properties->Effect()->Opacity()); @@ -620,7 +620,7 @@ "</div>"); LayoutObject* node_with_opacity = - GetDocument().getElementById("nodeWithOpacity")->GetLayoutObject(); + GetLayoutObjectByElementId("nodeWithOpacity"); const ObjectPaintProperties* node_with_opacity_properties = node_with_opacity->FirstFragment()->PaintProperties(); EXPECT_EQ(0.6f, node_with_opacity_properties->Effect()->Opacity()); @@ -630,7 +630,7 @@ GetDocument().View()->GetLayoutView()); LayoutObject* child_with_transform = - GetDocument().getElementById("childWithTransform")->GetLayoutObject(); + GetLayoutObjectByElementId("childWithTransform"); const ObjectPaintProperties* child_with_transform_properties = child_with_transform->FirstFragment()->PaintProperties(); EXPECT_EQ(nullptr, child_with_transform_properties->Effect()); @@ -640,7 +640,7 @@ GetDocument().View()->GetLayoutView()); LayoutObject* grand_child_with_opacity = - GetDocument().getElementById("grandChildWithOpacity")->GetLayoutObject(); + GetLayoutObjectByElementId("grandChildWithOpacity"); const ObjectPaintProperties* grand_child_with_opacity_properties = grand_child_with_opacity->FirstFragment()->PaintProperties(); EXPECT_EQ(0.4f, grand_child_with_opacity_properties->Effect()->Opacity()); @@ -663,7 +663,7 @@ "</div>"); LayoutObject* node_with_opacity = - GetDocument().getElementById("nodeWithOpacity")->GetLayoutObject(); + GetLayoutObjectByElementId("nodeWithOpacity"); const ObjectPaintProperties* node_with_opacity_properties = node_with_opacity->FirstFragment()->PaintProperties(); EXPECT_EQ(0.6f, node_with_opacity_properties->Effect()->Opacity()); @@ -683,7 +683,7 @@ GetDocument().View()->GetLayoutView()); LayoutObject* grand_child_with_opacity = - GetDocument().getElementById("grandChildWithOpacity")->GetLayoutObject(); + GetLayoutObjectByElementId("grandChildWithOpacity"); const ObjectPaintProperties* grand_child_with_opacity_properties = grand_child_with_opacity->FirstFragment()->PaintProperties(); EXPECT_EQ(0.4f, grand_child_with_opacity_properties->Effect()->Opacity()); @@ -707,20 +707,20 @@ "</svg>"); LOG(ERROR) << "here"; LayoutObject* group_with_opacity = - GetDocument().getElementById("groupWithOpacity")->GetLayoutObject(); + GetLayoutObjectByElementId("groupWithOpacity"); const ObjectPaintProperties* group_with_opacity_properties = group_with_opacity->FirstFragment()->PaintProperties(); EXPECT_EQ(0.6f, group_with_opacity_properties->Effect()->Opacity()); EXPECT_NE(nullptr, group_with_opacity_properties->Effect()->Parent()); LayoutObject& rect_without_opacity = - *GetDocument().getElementById("rectWithoutOpacity")->GetLayoutObject(); + *GetLayoutObjectByElementId("rectWithoutOpacity"); const FragmentData* rect_without_opacity_properties = rect_without_opacity.FirstFragment(); EXPECT_EQ(nullptr, rect_without_opacity_properties); LayoutObject& rect_with_opacity = - *GetDocument().getElementById("rectWithOpacity")->GetLayoutObject(); + *GetLayoutObjectByElementId("rectWithOpacity"); const ObjectPaintProperties* rect_with_opacity_properties = rect_with_opacity.FirstFragment()->PaintProperties(); EXPECT_EQ(0.4f, rect_with_opacity_properties->Effect()->Opacity()); @@ -730,7 +730,7 @@ // Ensure that opacity nodes are created for LayoutSVGText which inherits from // LayoutSVGBlock instead of LayoutSVGModelObject. LayoutObject& text_with_opacity = - *GetDocument().getElementById("textWithOpacity")->GetLayoutObject(); + *GetLayoutObjectByElementId("textWithOpacity"); const ObjectPaintProperties* text_with_opacity_properties = text_with_opacity.FirstFragment()->PaintProperties(); EXPECT_EQ(0.2f, text_with_opacity_properties->Effect()->Opacity()); @@ -740,7 +740,7 @@ // Ensure that opacity nodes are created for LayoutSVGTSpan which inherits // from LayoutSVGInline instead of LayoutSVGModelObject. LayoutObject& tspan_with_opacity = - *GetDocument().getElementById("tspanWithOpacity")->GetLayoutObject(); + *GetLayoutObjectByElementId("tspanWithOpacity"); const ObjectPaintProperties* tspan_with_opacity_properties = tspan_with_opacity.FirstFragment()->PaintProperties(); EXPECT_EQ(0.1f, tspan_with_opacity_properties->Effect()->Opacity()); @@ -757,14 +757,14 @@ "</div>"); LayoutObject& div_with_opacity = - *GetDocument().getElementById("divWithOpacity")->GetLayoutObject(); + *GetLayoutObjectByElementId("divWithOpacity"); const ObjectPaintProperties* div_with_opacity_properties = div_with_opacity.FirstFragment()->PaintProperties(); EXPECT_EQ(0.2f, div_with_opacity_properties->Effect()->Opacity()); EXPECT_NE(nullptr, div_with_opacity_properties->Effect()->Parent()); LayoutObject& svg_root_with_opacity = - *GetDocument().getElementById("svgRootWithOpacity")->GetLayoutObject(); + *GetLayoutObjectByElementId("svgRootWithOpacity"); const ObjectPaintProperties* svg_root_with_opacity_properties = svg_root_with_opacity.FirstFragment()->PaintProperties(); EXPECT_EQ(0.3f, svg_root_with_opacity_properties->Effect()->Opacity()); @@ -772,7 +772,7 @@ svg_root_with_opacity_properties->Effect()->Parent()); LayoutObject& rect_with_opacity = - *GetDocument().getElementById("rectWithOpacity")->GetLayoutObject(); + *GetLayoutObjectByElementId("rectWithOpacity"); const ObjectPaintProperties* rect_with_opacity_properties = rect_with_opacity.FirstFragment()->PaintProperties(); EXPECT_EQ(0.4f, rect_with_opacity_properties->Effect()->Opacity()); @@ -791,7 +791,7 @@ "</svg>"); LayoutObject& svg_root_with_opacity = - *GetDocument().getElementById("svgRootWithOpacity")->GetLayoutObject(); + *GetLayoutObjectByElementId("svgRootWithOpacity"); const ObjectPaintProperties* svg_root_with_opacity_properties = svg_root_with_opacity.FirstFragment()->PaintProperties(); EXPECT_EQ(0.3f, svg_root_with_opacity_properties->Effect()->Opacity()); @@ -808,7 +808,7 @@ foreign_object_with_opacity_properties->Effect()->Parent()); LayoutObject& span_with_opacity = - *GetDocument().getElementById("spanWithOpacity")->GetLayoutObject(); + *GetLayoutObjectByElementId("spanWithOpacity"); const ObjectPaintProperties* span_with_opacity_properties = span_with_opacity.FirstFragment()->PaintProperties(); EXPECT_EQ(0.5f, span_with_opacity_properties->Effect()->Opacity()); @@ -858,7 +858,7 @@ svg_root_with3d_transform_properties->PaintOffsetTranslation()->Parent()); LayoutObject& rect_with2d_transform = - *GetDocument().getElementById("rectWith2dTransform")->GetLayoutObject(); + *GetLayoutObjectByElementId("rectWith2dTransform"); const ObjectPaintProperties* rect_with2d_transform_properties = rect_with2d_transform.FirstFragment()->PaintProperties(); TransformationMatrix matrix; @@ -897,7 +897,7 @@ "</svg>"); LayoutObject& svg_with_view_box = - *GetDocument().getElementById("svgWithViewBox")->GetLayoutObject(); + *GetLayoutObjectByElementId("svgWithViewBox"); const ObjectPaintProperties* svg_with_view_box_properties = svg_with_view_box.FirstFragment()->PaintProperties(); EXPECT_EQ(TransformationMatrix().Translate3d(1, 2, 3), @@ -909,7 +909,7 @@ svg_with_view_box_properties->SvgLocalToBorderBoxTransform()->Parent(), svg_with_view_box_properties->Transform()); - LayoutObject& rect = *GetDocument().getElementById("rect")->GetLayoutObject(); + LayoutObject& rect = *GetLayoutObjectByElementId("rect"); const ObjectPaintProperties* rect_properties = rect.FirstFragment()->PaintProperties(); EXPECT_EQ(TransformationMatrix().Translate(100, 100), @@ -931,7 +931,7 @@ "</style>" "<svg id='svg' />"); - LayoutObject& svg = *GetDocument().getElementById("svg")->GetLayoutObject(); + LayoutObject& svg = *GetLayoutObjectByElementId("svg"); const ObjectPaintProperties* svg_properties = svg.FirstFragment()->PaintProperties(); // Ensure that a paint offset transform is not unnecessarily emitted. @@ -957,7 +957,7 @@ " <rect id='rect' transform='translate(17 19)' />" "</svg>"); - LayoutObject& svg = *GetDocument().getElementById("svg")->GetLayoutObject(); + LayoutObject& svg = *GetLayoutObjectByElementId("svg"); const ObjectPaintProperties* svg_properties = svg.FirstFragment()->PaintProperties(); EXPECT_EQ(TransformationMatrix().Translate(2, 3), @@ -973,7 +973,7 @@ // Ensure the rect's transform is a child of the local to border box // transform. - LayoutObject& rect = *GetDocument().getElementById("rect")->GetLayoutObject(); + LayoutObject& rect = *GetLayoutObjectByElementId("rect"); const ObjectPaintProperties* rect_properties = rect.FirstFragment()->PaintProperties(); EXPECT_EQ(TransformationMatrix().Translate(17, 19), @@ -992,7 +992,7 @@ " </svg>" "</svg>"); - LayoutObject& svg = *GetDocument().getElementById("svg")->GetLayoutObject(); + LayoutObject& svg = *GetLayoutObjectByElementId("svg"); const ObjectPaintProperties* svg_properties = svg.FirstFragment()->PaintProperties(); EXPECT_EQ(TransformationMatrix().Translate(11, 11), @@ -1000,8 +1000,7 @@ EXPECT_EQ(TransformationMatrix().Scale(2), svg_properties->SvgLocalToBorderBoxTransform()->Matrix()); - LayoutObject& nested_svg = - *GetDocument().getElementById("nestedSvg")->GetLayoutObject(); + LayoutObject& nested_svg = *GetLayoutObjectByElementId("nestedSvg"); const ObjectPaintProperties* nested_svg_properties = nested_svg.FirstFragment()->PaintProperties(); EXPECT_EQ(TransformationMatrix().Scale(10), @@ -1010,7 +1009,7 @@ EXPECT_EQ(svg_properties->SvgLocalToBorderBoxTransform(), nested_svg_properties->Transform()->Parent()); - LayoutObject& rect = *GetDocument().getElementById("rect")->GetLayoutObject(); + LayoutObject& rect = *GetLayoutObjectByElementId("rect"); const ObjectPaintProperties* rect_properties = rect.FirstFragment()->PaintProperties(); EXPECT_EQ(TransformationMatrix().Translate(13, 13), @@ -1033,14 +1032,14 @@ "</svg>"); LayoutObject& svg_with_transform = - *GetDocument().getElementById("svgWithTransform")->GetLayoutObject(); + *GetLayoutObjectByElementId("svgWithTransform"); const ObjectPaintProperties* svg_with_transform_properties = svg_with_transform.FirstFragment()->PaintProperties(); EXPECT_EQ(TransformationMatrix().Translate3d(1, 2, 3), svg_with_transform_properties->Transform()->Matrix()); LayoutObject& div_with_transform = - *GetDocument().getElementById("divWithTransform")->GetLayoutObject(); + *GetLayoutObjectByElementId("divWithTransform"); const ObjectPaintProperties* div_with_transform_properties = div_with_transform.FirstFragment()->PaintProperties(); EXPECT_EQ(TransformationMatrix().Translate3d(3, 4, 5), @@ -1065,14 +1064,13 @@ " </g>" "</svg>"); - LayoutObject& svg = *GetDocument().getElementById("svg")->GetLayoutObject(); + LayoutObject& svg = *GetLayoutObjectByElementId("svg"); const ObjectPaintProperties* svg_properties = svg.FirstFragment()->PaintProperties(); EXPECT_EQ(TransformationMatrix().Translate3d(1, 2, 3), svg_properties->Transform()->Matrix()); - LayoutObject& container = - *GetDocument().getElementById("container")->GetLayoutObject(); + LayoutObject& container = *GetLayoutObjectByElementId("container"); const ObjectPaintProperties* container_properties = container.FirstFragment()->PaintProperties(); EXPECT_EQ(TransformationMatrix().Translate(20, 30), @@ -1104,8 +1102,7 @@ "<input id='button' type='button'" " style='width:345px; height:123px' value='some text'/>"); - LayoutObject& button = - *GetDocument().getElementById("button")->GetLayoutObject(); + LayoutObject& button = *GetLayoutObjectByElementId("button"); const ObjectPaintProperties* button_properties = button.FirstFragment()->PaintProperties(); // No scroll translation because the document does not scroll (not enough @@ -1139,7 +1136,7 @@ "</style>" "<div id='div'></div>"); - LayoutObject& div = *GetDocument().getElementById("div")->GetLayoutObject(); + LayoutObject& div = *GetLayoutObjectByElementId("div"); const ObjectPaintProperties* div_properties = div.FirstFragment()->PaintProperties(); // No scroll translation because the document does not scroll (not enough @@ -1203,7 +1200,7 @@ frame_view->UpdateAllLifecyclePhases(); LayoutObject* div_with_transform = - GetDocument().getElementById("divWithTransform")->GetLayoutObject(); + GetLayoutObjectByElementId("divWithTransform"); const ObjectPaintProperties* div_with_transform_properties = div_with_transform->FirstFragment()->PaintProperties(); EXPECT_EQ(TransformationMatrix().Translate3d(1, 2, 3), @@ -1313,7 +1310,7 @@ div_with_transform_transform->Matrix()); LayoutObject* div_with_transform = - GetDocument().getElementById("divWithTransform")->GetLayoutObject(); + GetLayoutObjectByElementId("divWithTransform"); EXPECT_EQ( div_with_transform_transform, div_with_transform->FirstFragment()->PaintProperties()->Transform()); @@ -1334,12 +1331,10 @@ "</div>"); LocalFrameView* frame_view = GetDocument().View(); - LayoutObject* scroller = - GetDocument().getElementById("scroller")->GetLayoutObject(); + LayoutObject* scroller = GetLayoutObjectByElementId("scroller"); const ObjectPaintProperties* scroller_properties = scroller->FirstFragment()->PaintProperties(); - LayoutObject* child = - GetDocument().getElementById("child")->GetLayoutObject(); + LayoutObject* child = GetLayoutObjectByElementId("child"); EXPECT_EQ(scroller_properties->OverflowClip(), child->FirstFragment()->LocalBorderBoxProperties()->Clip()); @@ -1380,11 +1375,10 @@ " <div id='forceScroll' style='height:10000px;'></div>" "</div>"); - auto& scroller = *GetDocument().getElementById("scroller")->GetLayoutObject(); + auto& scroller = *GetLayoutObjectByElementId("scroller"); const ObjectPaintProperties* scroller_properties = scroller.FirstFragment()->PaintProperties(); - LayoutObject& child = - *GetDocument().getElementById("child")->GetLayoutObject(); + LayoutObject& child = *GetLayoutObjectByElementId("child"); EXPECT_EQ(FrameContentClip(), child.FirstFragment()->LocalBorderBoxProperties()->Clip()); @@ -1429,8 +1423,7 @@ " <tr><td></td><td><div id='target'></div></td></tr>" "</table>"); - LayoutObject& target = - *GetDocument().getElementById("target")->GetLayoutObject(); + LayoutObject& target = *GetLayoutObjectByElementId("target"); EXPECT_EQ(LayoutPoint(170, 170), target.PaintOffset()); EXPECT_EQ(FramePreTranslation(), target.FirstFragment()->LocalBorderBoxProperties()->Transform()); @@ -1465,7 +1458,7 @@ LayoutRect absolute_clip_rect = local_clip_rect; absolute_clip_rect.Move(123, 456); - LayoutObject& clip = *GetDocument().getElementById("clip")->GetLayoutObject(); + LayoutObject& clip = *GetLayoutObjectByElementId("clip"); const ObjectPaintProperties* clip_properties = clip.FirstFragment()->PaintProperties(); EXPECT_EQ(FrameContentClip(), clip_properties->CssClip()->Parent()); @@ -1479,8 +1472,7 @@ // doesn't apply css clip on the object itself. LayoutUnit::Max()); - LayoutObject* fixed = - GetDocument().getElementById("fixed")->GetLayoutObject(); + LayoutObject* fixed = GetLayoutObjectByElementId("fixed"); EXPECT_EQ(clip_properties->CssClip(), fixed->FirstFragment()->LocalBorderBoxProperties()->Clip()); EXPECT_EQ(FramePreTranslation(), @@ -1521,7 +1513,7 @@ LayoutRect absolute_clip_rect = local_clip_rect; absolute_clip_rect.Move(123, 456); - auto* clip = GetDocument().getElementById("clip")->GetLayoutObject(); + auto* clip = GetLayoutObjectByElementId("clip"); const ObjectPaintProperties* clip_properties = clip->FirstFragment()->PaintProperties(); EXPECT_EQ(FrameContentClip(), clip_properties->CssClip()->Parent()); @@ -1538,7 +1530,7 @@ // doesn't apply css clip on the object itself. LayoutUnit::Max()); - auto* absolute = GetDocument().getElementById("absolute")->GetLayoutObject(); + auto* absolute = GetLayoutObjectByElementId("absolute"); EXPECT_EQ(clip_properties->CssClip(), absolute->FirstFragment()->LocalBorderBoxProperties()->Clip()); EXPECT_EQ(FramePreTranslation(), @@ -1586,8 +1578,7 @@ LayoutRect absolute_clip_rect = local_clip_rect; absolute_clip_rect.Move(123, 456); - LayoutObject& overflow = - *GetDocument().getElementById("overflow")->GetLayoutObject(); + LayoutObject& overflow = *GetLayoutObjectByElementId("overflow"); const ObjectPaintProperties* overflow_properties = overflow.FirstFragment()->PaintProperties(); EXPECT_EQ(FrameContentClip(), overflow_properties->OverflowClip()->Parent()); @@ -1599,7 +1590,7 @@ CHECK_EXACT_VISUAL_RECT(LayoutRect(0, 0, 50, 50), &overflow, GetDocument().View()->GetLayoutView()); - LayoutObject* clip = GetDocument().getElementById("clip")->GetLayoutObject(); + LayoutObject* clip = GetLayoutObjectByElementId("clip"); const ObjectPaintProperties* clip_properties = clip->FirstFragment()->PaintProperties(); EXPECT_EQ(overflow_properties->OverflowClip(), @@ -1617,8 +1608,7 @@ CHECK_EXACT_VISUAL_RECT(LayoutRect(), clip, GetDocument().View()->GetLayoutView()); - LayoutObject* fixed = - GetDocument().getElementById("fixed")->GetLayoutObject(); + LayoutObject* fixed = GetLayoutObjectByElementId("fixed"); EXPECT_EQ(clip_properties->CssClipFixedPosition(), fixed->FirstFragment()->LocalBorderBoxProperties()->Clip()); EXPECT_EQ(FramePreTranslation(), @@ -1675,14 +1665,14 @@ "</div>"); LocalFrameView* frame_view = GetDocument().View(); - LayoutObject* a = GetDocument().getElementById("a")->GetLayoutObject(); + LayoutObject* a = GetLayoutObjectByElementId("a"); LayoutPoint a_paint_offset = LayoutPoint(FloatPoint(0.1, 0.3)); EXPECT_EQ(a_paint_offset, a->PaintOffset()); CHECK_EXACT_VISUAL_RECT(LayoutRect(LayoutUnit(0.1), LayoutUnit(0.3), LayoutUnit(70), LayoutUnit(70)), a, frame_view->GetLayoutView()); - LayoutObject* b = GetDocument().getElementById("b")->GetLayoutObject(); + LayoutObject* b = GetLayoutObjectByElementId("b"); LayoutPoint b_paint_offset = a_paint_offset + LayoutPoint(FloatPoint(0.5, 11.1)); EXPECT_EQ(b_paint_offset, b->PaintOffset()); @@ -1721,7 +1711,7 @@ "</div>"); LocalFrameView* frame_view = GetDocument().View(); - LayoutObject* b = GetDocument().getElementById("b")->GetLayoutObject(); + LayoutObject* b = GetLayoutObjectByElementId("b"); const ObjectPaintProperties* b_properties = b->FirstFragment()->PaintProperties(); EXPECT_EQ(TransformationMatrix().Translate3d(0, 0, 0), @@ -1736,7 +1726,7 @@ frame_view->GetLayoutView()); // c's painted should start at subpixelAccumulation + (0.1,0.1) = (0.4,0.4). - LayoutObject* c = GetDocument().getElementById("c")->GetLayoutObject(); + LayoutObject* c = GetLayoutObjectByElementId("c"); LayoutPoint c_paint_offset = subpixel_accumulation + LayoutPoint(FloatPoint(0.1, 0.1)); EXPECT_EQ(c_paint_offset, c->PaintOffset()); @@ -1778,7 +1768,7 @@ "</div>"); LocalFrameView* frame_view = GetDocument().View(); - LayoutObject* b = GetDocument().getElementById("b")->GetLayoutObject(); + LayoutObject* b = GetLayoutObjectByElementId("b"); const ObjectPaintProperties* b_properties = b->FirstFragment()->PaintProperties(); EXPECT_EQ(TransformationMatrix().Translate3d(0, 0, 0), @@ -1795,7 +1785,7 @@ b, frame_view->GetLayoutView()); // c's painting should start at subpixelAccumulation + (0.7,0.7) = (0.4,0.4). - LayoutObject* c = GetDocument().getElementById("c")->GetLayoutObject(); + LayoutObject* c = GetLayoutObjectByElementId("c"); LayoutPoint c_paint_offset = subpixel_accumulation + LayoutPoint(FloatPoint(0.7, 0.7)); EXPECT_EQ(c_paint_offset, c->PaintOffset()); @@ -1840,7 +1830,7 @@ "</div>"); LocalFrameView* frame_view = GetDocument().View(); - LayoutObject* b = GetDocument().getElementById("b")->GetLayoutObject(); + LayoutObject* b = GetLayoutObjectByElementId("b"); const ObjectPaintProperties* b_properties = b->FirstFragment()->PaintProperties(); EXPECT_EQ(TransformationMatrix().Scale(10), @@ -1857,7 +1847,7 @@ b, frame_view->GetLayoutView(), 1); // c's painting should start at c_offset. - LayoutObject* c = GetDocument().getElementById("c")->GetLayoutObject(); + LayoutObject* c = GetLayoutObjectByElementId("c"); LayoutUnit c_offset = LayoutUnit(0.6); EXPECT_EQ(LayoutPoint(c_offset, c_offset), c->PaintOffset()); // Visual rects via the non-paint properties system use enclosingIntRect @@ -1908,7 +1898,7 @@ "</div>"); LocalFrameView* frame_view = GetDocument().View(); - LayoutObject* b = GetDocument().getElementById("b")->GetLayoutObject(); + LayoutObject* b = GetLayoutObjectByElementId("b"); const ObjectPaintProperties* b_properties = b->FirstFragment()->PaintProperties(); EXPECT_EQ(TransformationMatrix().Translate3d(5, 7, 0), @@ -1924,7 +1914,7 @@ LayoutUnit(40), LayoutUnit(40)), b, frame_view->GetLayoutView()); - LayoutObject* c = GetDocument().getElementById("c")->GetLayoutObject(); + LayoutObject* c = GetLayoutObjectByElementId("c"); const ObjectPaintProperties* c_properties = c->FirstFragment()->PaintProperties(); EXPECT_EQ(TransformationMatrix().Translate3d(11, 13, 0), @@ -1941,7 +1931,7 @@ // d should be painted starting at subpixelAccumulation + (0.7,0.7) = // (0.4,0.4). - LayoutObject* d = GetDocument().getElementById("d")->GetLayoutObject(); + LayoutObject* d = GetLayoutObjectByElementId("d"); LayoutPoint d_paint_offset = subpixel_accumulation + LayoutPoint(FloatPoint(0.7, 0.7)); EXPECT_EQ(d_paint_offset, d->PaintOffset()); @@ -1991,7 +1981,7 @@ "</div>"); LocalFrameView* frame_view = GetDocument().View(); - LayoutObject* b = GetDocument().getElementById("b")->GetLayoutObject(); + LayoutObject* b = GetLayoutObjectByElementId("b"); const ObjectPaintProperties* b_properties = b->FirstFragment()->PaintProperties(); EXPECT_EQ(TransformationMatrix().Translate(0, 0), @@ -2007,8 +1997,7 @@ LayoutUnit(40), LayoutUnit(40)), b, frame_view->GetLayoutView()); - LayoutObject* fixed = - GetDocument().getElementById("fixed")->GetLayoutObject(); + LayoutObject* fixed = GetLayoutObjectByElementId("fixed"); // The residual subpixel adjustment should still be (-0.3,0). EXPECT_EQ(subpixel_accumulation, fixed->PaintOffset()); CHECK_EXACT_VISUAL_RECT(LayoutRect(LayoutUnit(0.7), LayoutUnit(0), @@ -2016,7 +2005,7 @@ fixed, frame_view->GetLayoutView()); // d should be painted starting at subpixelAccumulation + (0.7,0) = (0.4,0). - LayoutObject* d = GetDocument().getElementById("d")->GetLayoutObject(); + LayoutObject* d = GetLayoutObjectByElementId("d"); LayoutPoint d_paint_offset = subpixel_accumulation + LayoutPoint(FloatPoint(0.7, 0)); EXPECT_EQ(d_paint_offset, d->PaintOffset()); @@ -2041,8 +2030,7 @@ " <rect id='rect' transform='translate(1, 1)'/>" "</svg>"); - LayoutObject& svg_with_transform = - *GetDocument().getElementById("svg")->GetLayoutObject(); + LayoutObject& svg_with_transform = *GetLayoutObjectByElementId("svg"); const ObjectPaintProperties* svg_with_transform_properties = svg_with_transform.FirstFragment()->PaintProperties(); EXPECT_EQ(TransformationMatrix(), @@ -2051,8 +2039,7 @@ EXPECT_TRUE(svg_with_transform_properties->SvgLocalToBorderBoxTransform() == nullptr); - LayoutObject& rect_with_transform = - *GetDocument().getElementById("rect")->GetLayoutObject(); + LayoutObject& rect_with_transform = *GetLayoutObjectByElementId("rect"); const ObjectPaintProperties* rect_with_transform_properties = rect_with_transform.FirstFragment()->PaintProperties(); EXPECT_EQ(TransformationMatrix().Translate(1, 1), @@ -2120,10 +2107,10 @@ "</div>"); LocalFrameView* frame_view = GetDocument().View(); - LayoutObject* a = GetDocument().getElementById("a")->GetLayoutObject(); + LayoutObject* a = GetLayoutObjectByElementId("a"); const ObjectPaintProperties* a_properties = a->FirstFragment()->PaintProperties(); - LayoutObject* b = GetDocument().getElementById("b")->GetLayoutObject(); + LayoutObject* b = GetLayoutObjectByElementId("b"); const ObjectPaintProperties* b_properties = b->FirstFragment()->PaintProperties(); ASSERT_TRUE(a_properties->Transform() && b_properties->Transform()); @@ -2159,10 +2146,10 @@ "</div>"); LocalFrameView* frame_view = GetDocument().View(); - LayoutObject* a = GetDocument().getElementById("a")->GetLayoutObject(); + LayoutObject* a = GetLayoutObjectByElementId("a"); const ObjectPaintProperties* a_properties = a->FirstFragment()->PaintProperties(); - LayoutObject* b = GetDocument().getElementById("b")->GetLayoutObject(); + LayoutObject* b = GetLayoutObjectByElementId("b"); const ObjectPaintProperties* b_properties = b->FirstFragment()->PaintProperties(); ASSERT_FALSE(a->StyleRef().Preserves3D()); @@ -2193,10 +2180,10 @@ "</div>"); LocalFrameView* frame_view = GetDocument().View(); - LayoutObject* a = GetDocument().getElementById("a")->GetLayoutObject(); + LayoutObject* a = GetLayoutObjectByElementId("a"); const ObjectPaintProperties* a_properties = a->FirstFragment()->PaintProperties(); - LayoutObject* b = GetDocument().getElementById("b")->GetLayoutObject(); + LayoutObject* b = GetLayoutObjectByElementId("b"); const ObjectPaintProperties* b_properties = b->FirstFragment()->PaintProperties(); ASSERT_FALSE(a->StyleRef().Preserves3D()); @@ -2260,8 +2247,8 @@ "</div>"); LocalFrameView* frame_view = GetDocument().View(); - LayoutObject* a = GetDocument().getElementById("a")->GetLayoutObject(); - LayoutObject* b = GetDocument().getElementById("b")->GetLayoutObject(); + LayoutObject* a = GetLayoutObjectByElementId("a"); + LayoutObject* b = GetLayoutObjectByElementId("b"); const auto* a_transform = a->FirstFragment()->PaintProperties()->Transform(); ASSERT_TRUE(a_transform); const auto* b_transform = b->FirstFragment()->PaintProperties()->Transform(); @@ -2298,8 +2285,8 @@ "</div>"); LocalFrameView* frame_view = GetDocument().View(); - LayoutObject* a = GetDocument().getElementById("a")->GetLayoutObject(); - LayoutObject* b = GetDocument().getElementById("b")->GetLayoutObject(); + LayoutObject* a = GetLayoutObjectByElementId("a"); + LayoutObject* b = GetLayoutObjectByElementId("b"); const auto* a_transform = a->FirstFragment()->PaintProperties()->Transform(); ASSERT_TRUE(a_transform); const auto* b_transform = b->FirstFragment()->PaintProperties()->Transform(); @@ -2327,8 +2314,8 @@ "</div>"); LocalFrameView* frame_view = GetDocument().View(); - LayoutObject* a = GetDocument().getElementById("a")->GetLayoutObject(); - LayoutObject* b = GetDocument().getElementById("b")->GetLayoutObject(); + LayoutObject* a = GetLayoutObjectByElementId("a"); + LayoutObject* b = GetLayoutObjectByElementId("b"); const ObjectPaintProperties* a_properties = a->FirstFragment()->PaintProperties(); const ObjectPaintProperties* b_properties = @@ -2358,8 +2345,8 @@ "</div>"); LocalFrameView* frame_view = GetDocument().View(); - LayoutObject* a = GetDocument().getElementById("a")->GetLayoutObject(); - LayoutObject* b = GetDocument().getElementById("b")->GetLayoutObject(); + LayoutObject* a = GetLayoutObjectByElementId("a"); + LayoutObject* b = GetLayoutObjectByElementId("b"); const ObjectPaintProperties* a_properties = a->FirstFragment()->PaintProperties(); const ObjectPaintProperties* b_properties = @@ -2515,12 +2502,11 @@ " style='position: relative; width: 500px; height: 600px;'></div>" "</div>"); - LayoutBoxModelObject* clipper = ToLayoutBoxModelObject( - GetDocument().getElementById("clipper")->GetLayoutObject()); + LayoutBoxModelObject* clipper = + ToLayoutBoxModelObject(GetLayoutObjectByElementId("clipper")); const ObjectPaintProperties* clip_properties = clipper->FirstFragment()->PaintProperties(); - LayoutObject* child = - GetDocument().getElementById("child")->GetLayoutObject(); + LayoutObject* child = GetLayoutObjectByElementId("child"); // No scroll translation because the document does not scroll (not enough // content). @@ -2554,12 +2540,11 @@ " style='position: relative; width: 400px; height: 500px;'></div>" "</div>"); - LayoutBoxModelObject* clipper = ToLayoutBoxModelObject( - GetDocument().getElementById("clipper")->GetLayoutObject()); + LayoutBoxModelObject* clipper = + ToLayoutBoxModelObject(GetLayoutObjectByElementId("clipper")); const ObjectPaintProperties* clip_properties = clipper->FirstFragment()->PaintProperties(); - LayoutObject* child = - GetDocument().getElementById("child")->GetLayoutObject(); + LayoutObject* child = GetLayoutObjectByElementId("child"); // No scroll translation because the document does not scroll (not enough // content). @@ -2604,8 +2589,7 @@ ToLayoutBoxModelObject(clipper_element->GetLayoutObject()); const ObjectPaintProperties* clip_properties = clipper->FirstFragment()->PaintProperties(); - LayoutObject* child = - GetDocument().getElementById("child")->GetLayoutObject(); + LayoutObject* child = GetLayoutObjectByElementId("child"); EXPECT_EQ(FrameScrollTranslation(), clipper->FirstFragment()->LocalBorderBoxProperties()->Transform()); @@ -2652,8 +2636,7 @@ " <div id='roundedBoxChild'></div>" "</div>"); - LayoutObject& rounded_box = - *GetDocument().getElementById("roundedBox")->GetLayoutObject(); + LayoutObject& rounded_box = *GetLayoutObjectByElementId("roundedBox"); const ObjectPaintProperties* rounded_box_properties = rounded_box.FirstFragment()->PaintProperties(); EXPECT_EQ( @@ -2683,12 +2666,11 @@ "500px;'></div>" "</div>"); - LayoutBoxModelObject* clipper = ToLayoutBoxModelObject( - GetDocument().getElementById("clipper")->GetLayoutObject()); + LayoutBoxModelObject* clipper = + ToLayoutBoxModelObject(GetLayoutObjectByElementId("clipper")); const ObjectPaintProperties* clip_properties = clipper->FirstFragment()->PaintProperties(); - LayoutObject* child = - GetDocument().getElementById("child")->GetLayoutObject(); + LayoutObject* child = GetLayoutObjectByElementId("child"); // No scroll translation because the document does not scroll (not enough // content). @@ -2727,7 +2709,7 @@ "</svg>"); LayoutObject& svg_with_view_box = - *GetDocument().getElementById("svgWithViewBox")->GetLayoutObject(); + *GetLayoutObjectByElementId("svgWithViewBox"); EXPECT_EQ(FramePreTranslation(), svg_with_view_box.FirstFragment() ->LocalBorderBoxProperties() ->Transform()); @@ -3253,8 +3235,7 @@ "<div id='transform'></div>" "<div id='willChange'></div>"); - auto* transform = - GetDocument().getElementById("transform")->GetLayoutObject(); + auto* transform = GetLayoutObjectByElementId("transform"); EXPECT_EQ( TransformationMatrix().Translate3d(100, 200, 0), transform->FirstFragment()->PaintProperties()->Transform()->Matrix()); @@ -3262,8 +3243,7 @@ FloatPoint3D(300, 75, 0), transform->FirstFragment()->PaintProperties()->Transform()->Origin()); - auto* will_change = - GetDocument().getElementById("willChange")->GetLayoutObject(); + auto* will_change = GetLayoutObjectByElementId("willChange"); EXPECT_EQ( TransformationMatrix().Translate3d(0, 0, 0), will_change->FirstFragment()->PaintProperties()->Transform()->Matrix()); @@ -3295,8 +3275,7 @@ "<div id='motionPath'></div>" "<div id='willChange'></div>"); - auto* motion_path = - GetDocument().getElementById("motionPath")->GetLayoutObject(); + auto* motion_path = GetLayoutObjectByElementId("motionPath"); EXPECT_EQ( TransformationMatrix().Translate3d(50, 150, 0), motion_path->FirstFragment()->PaintProperties()->Transform()->Matrix()); @@ -3304,8 +3283,7 @@ FloatPoint3D(50, 50, 0), motion_path->FirstFragment()->PaintProperties()->Transform()->Origin()); - auto* will_change = - GetDocument().getElementById("willChange")->GetLayoutObject(); + auto* will_change = GetLayoutObjectByElementId("willChange"); EXPECT_EQ( TransformationMatrix().Translate3d(0, 0, 0), will_change->FirstFragment()->PaintProperties()->Transform()->Matrix()); @@ -3420,8 +3398,8 @@ " width: 400px; height: 300px; left: 1.5px'>" "</div>"); - LayoutBoxModelObject* clipper = ToLayoutBoxModelObject( - GetDocument().getElementById("clipper")->GetLayoutObject()); + LayoutBoxModelObject* clipper = + ToLayoutBoxModelObject(GetLayoutObjectByElementId("clipper")); const ObjectPaintProperties* clip_properties = clipper->FirstFragment()->PaintProperties(); @@ -3440,8 +3418,7 @@ const ObjectPaintProperties* properties = PaintPropertiesForElement("target"); const ClipPaintPropertyNode* output_clip = properties->MaskClip(); - const auto* target = - GetDocument().getElementById("target")->GetLayoutObject(); + const auto* target = GetLayoutObjectByElementId("target"); EXPECT_EQ(output_clip, target->FirstFragment()->LocalBorderBoxProperties()->Clip()); EXPECT_EQ(FrameContentClip(), output_clip->Parent()); @@ -3476,8 +3453,7 @@ properties->MaskClip()->Parent(); const ClipPaintPropertyNode* mask_clip = properties->MaskClip(); const ClipPaintPropertyNode* overflow_clip2 = properties->OverflowClip(); - const auto* target = - GetDocument().getElementById("target")->GetLayoutObject(); + const auto* target = GetLayoutObjectByElementId("target"); const TransformPaintPropertyNode* scroll_translation = target->FirstFragment()->LocalBorderBoxProperties()->Transform(); @@ -3505,8 +3481,7 @@ EXPECT_EQ(SkBlendMode::kDstIn, properties->Mask()->BlendMode()); EXPECT_EQ(mask_clip, properties->Mask()->OutputClip()); - const auto* absolute = - GetDocument().getElementById("absolute")->GetLayoutObject(); + const auto* absolute = GetLayoutObjectByElementId("absolute"); EXPECT_EQ(FramePreTranslation(), absolute->FirstFragment()->LocalBorderBoxProperties()->Transform()); EXPECT_EQ(mask_clip, @@ -3531,8 +3506,7 @@ const ObjectPaintProperties* properties = PaintPropertiesForElement("target"); const ClipPaintPropertyNode* output_clip = properties->MaskClip(); - const auto* target = - GetDocument().getElementById("target")->GetLayoutObject(); + const auto* target = GetLayoutObjectByElementId("target"); EXPECT_EQ(output_clip, target->FirstFragment()->LocalBorderBoxProperties()->Clip()); @@ -3549,8 +3523,7 @@ EXPECT_EQ(SkBlendMode::kDstIn, properties->Mask()->BlendMode()); EXPECT_EQ(output_clip, properties->Mask()->OutputClip()); - const auto* overflowing = - GetDocument().getElementById("overflowing")->GetLayoutObject(); + const auto* overflowing = GetLayoutObjectByElementId("overflowing"); EXPECT_EQ(output_clip, overflowing->FirstFragment()->LocalBorderBoxProperties()->Clip()); EXPECT_EQ(properties->Effect(), @@ -3659,8 +3632,7 @@ " style='mix-blend-mode: difference'/>" "</svg>"); - LayoutObject& svg_root = - *GetDocument().getElementById("svgroot")->GetLayoutObject(); + LayoutObject& svg_root = *GetLayoutObjectByElementId("svgroot"); const ObjectPaintProperties* svg_root_properties = svg_root.FirstFragment()->PaintProperties(); EXPECT_TRUE(svg_root_properties->Effect());
diff --git a/third_party/WebKit/Source/core/paint/PaintPropertyTreeUpdateTests.cpp b/third_party/WebKit/Source/core/paint/PaintPropertyTreeUpdateTests.cpp index 4b5b4a6..9236ec83 100644 --- a/third_party/WebKit/Source/core/paint/PaintPropertyTreeUpdateTests.cpp +++ b/third_party/WebKit/Source/core/paint/PaintPropertyTreeUpdateTests.cpp
@@ -304,7 +304,7 @@ frame_view->UpdateAllLifecyclePhases(); LayoutObject* div_with_transform = - GetDocument().getElementById("divWithTransform")->GetLayoutObject(); + GetLayoutObjectByElementId("divWithTransform"); LayoutObject* child_layout_view = ChildDocument().GetLayoutView(); LayoutObject* inner_div_with_transform = ChildDocument().getElementById("transform")->GetLayoutObject(); @@ -384,8 +384,7 @@ EXPECT_FALSE(GetDocument().View()->IsHiddenForThrottling()); EXPECT_TRUE(ChildDocument().View()->IsHiddenForThrottling()); - auto* transform = - GetDocument().getElementById("transform")->GetLayoutObject(); + auto* transform = GetLayoutObjectByElementId("transform"); auto* iframe_layout_view = ChildDocument().GetLayoutView(); auto* iframe_transform = ChildDocument().getElementById("iframeTransform")->GetLayoutObject(); @@ -664,8 +663,7 @@ " <div id='contents'></div>" "</div>"); - auto* perspective = - GetDocument().getElementById("perspective")->GetLayoutObject(); + auto* perspective = GetLayoutObjectByElementId("perspective"); EXPECT_EQ( TransformationMatrix().ApplyPerspective(100), perspective->FirstFragment()->PaintProperties()->Perspective()->Matrix());
diff --git a/third_party/WebKit/Source/core/paint/compositing/CompositingInputsUpdater.cpp b/third_party/WebKit/Source/core/paint/compositing/CompositingInputsUpdater.cpp index b9e592f..4c4fa9c 100644 --- a/third_party/WebKit/Source/core/paint/compositing/CompositingInputsUpdater.cpp +++ b/third_party/WebKit/Source/core/paint/compositing/CompositingInputsUpdater.cpp
@@ -75,22 +75,19 @@ const PaintLayer* clipping_layer) { if (layer == clipping_layer) return false; - bool found_intervening_clip = false; const LayoutObject& clipping_layout_object = clipping_layer->GetLayoutObject(); for (const PaintLayer* current = layer->CompositingContainer(); current; current = current->CompositingContainer()) { - if (current == clipping_layer) - return found_intervening_clip; + if (clipping_layout_object.IsDescendantOf(¤t->GetLayoutObject())) + break; - if (current->GetLayoutObject().HasClipRelatedProperty() && - !clipping_layout_object.IsDescendantOf(¤t->GetLayoutObject())) - found_intervening_clip = true; + if (current->GetLayoutObject().HasClipRelatedProperty()) + return true; if (const LayoutObject* container = current->ClippingContainer()) { - if (&clipping_layout_object != container && - !clipping_layout_object.IsDescendantOf(container)) - found_intervening_clip = true; + if (!clipping_layout_object.IsDescendantOf(container)) + return true; } } return false;
diff --git a/third_party/WebKit/Source/core/paint/compositing/PaintLayerCompositor.cpp b/third_party/WebKit/Source/core/paint/compositing/PaintLayerCompositor.cpp index bb56b73b..561d7ea 100644 --- a/third_party/WebKit/Source/core/paint/compositing/PaintLayerCompositor.cpp +++ b/third_party/WebKit/Source/core/paint/compositing/PaintLayerCompositor.cpp
@@ -513,6 +513,24 @@ } } + if (!RuntimeEnabledFeatures::RootLayerScrollingEnabled()) { + bool is_root_scroller_ancestor = IsRootScrollerAncestor(); + + if (scroll_layer_) + scroll_layer_->SetIsResizedByBrowserControls(is_root_scroller_ancestor); + + // Clip a frame's overflow controls layer only if it's not an ancestor of + // the root scroller. If it is an ancestor, then it's guaranteed to be + // viewport sized and so will be appropriately clipped by the visual + // viewport. We don't want to clip here in this case so that URL bar + // expansion doesn't need to resize the clip. + + if (overflow_controls_host_layer_) { + overflow_controls_host_layer_->SetMasksToBounds( + !is_root_scroller_ancestor); + } + } + // Inform the inspector that the layer tree has changed. if (IsMainFrame()) probe::layerTreeDidChange(layout_view_.GetFrame()); @@ -1347,6 +1365,28 @@ return layout_view_.GetFrameView()->GetPage()->GetVisualViewport(); } +bool PaintLayerCompositor::IsRootScrollerAncestor() const { + const TopDocumentRootScrollerController& global_rsc = + layout_view_.GetDocument().GetPage()->GlobalRootScrollerController(); + PaintLayer* root_scroller_layer = global_rsc.RootScrollerPaintLayer(); + + if (root_scroller_layer) { + Frame* frame = root_scroller_layer->GetLayoutObject().GetFrame(); + while (frame) { + if (frame->IsLocalFrame()) { + PaintLayerCompositor* plc = + ToLocalFrame(frame)->View()->GetLayoutView()->Compositor(); + if (plc == this) + return true; + } + + frame = frame->Tree().Parent(); + } + } + + return false; +} + String PaintLayerCompositor::DebugName( const GraphicsLayer* graphics_layer) const { String name;
diff --git a/third_party/WebKit/Source/core/paint/compositing/PaintLayerCompositor.h b/third_party/WebKit/Source/core/paint/compositing/PaintLayerCompositor.h index f1cf7baa..ce2b4f3 100644 --- a/third_party/WebKit/Source/core/paint/compositing/PaintLayerCompositor.h +++ b/third_party/WebKit/Source/core/paint/compositing/PaintLayerCompositor.h
@@ -254,6 +254,8 @@ VisualViewport& GetVisualViewport() const; GraphicsLayer* ParentForContentLayers() const; + bool IsRootScrollerAncestor() const; + LayoutView& layout_view_; CompositingReasonFinder compositing_reason_finder_;
diff --git a/third_party/WebKit/Source/core/streams/ReadableStream.js b/third_party/WebKit/Source/core/streams/ReadableStream.js index 069e957..8022039 100644 --- a/third_party/WebKit/Source/core/streams/ReadableStream.js +++ b/third_party/WebKit/Source/core/streams/ReadableStream.js
@@ -98,6 +98,12 @@ const errCannotPipeLockedStream = 'Cannot pipe a locked stream'; const errCannotPipeToALockedStream = 'Cannot pipe to a locked stream'; const errDestinationStreamClosed = 'Destination stream closed'; + const errPipeThroughUndefinedWritable = + 'Failed to execute \'pipeThrough\' on \'ReadableStream\': parameter ' + + '1\'s \'writable\' property is undefined.'; + const errPipeThroughUndefinedReadable = + 'Failed to execute \'pipeThrough\' on \'ReadableStream\': parameter ' + + '1\'s \'readable\' property is undefined.'; class ReadableStream { constructor() { @@ -178,6 +184,12 @@ } pipeThrough({writable, readable}, options) { + if (writable === undefined) { + throw new TypeError(errPipeThroughUndefinedWritable); + } + if (readable === undefined) { + throw new TypeError(errPipeThroughUndefinedReadable); + } const promise = this.pipeTo(writable, options); if (v8.isPromise(promise)) { markPromiseAsHandled(promise);
diff --git a/third_party/WebKit/Source/core/style/ComputedStyle.cpp b/third_party/WebKit/Source/core/style/ComputedStyle.cpp index 9e46017..a506c46 100644 --- a/third_party/WebKit/Source/core/style/ComputedStyle.cpp +++ b/third_party/WebKit/Source/core/style/ComputedStyle.cpp
@@ -600,8 +600,7 @@ return true; if (!BorderVisuallyEqual(other) || !RadiiEqual(other) || - (BackgroundInternal() != other.BackgroundInternal() || - BackgroundColorInternal() != other.BackgroundColorInternal())) + !BackgroundVisuallyEqual(other)) return true; if (PaintImagesInternal()) { @@ -802,6 +801,9 @@ case CSSPropertyOpacity: case CSSPropertyTransform: case CSSPropertyAliasWebkitTransform: + case CSSPropertyTranslate: + case CSSPropertyScale: + case CSSPropertyRotate: case CSSPropertyTop: case CSSPropertyLeft: case CSSPropertyBottom:
diff --git a/third_party/WebKit/Source/core/style/ComputedStyle.h b/third_party/WebKit/Source/core/style/ComputedStyle.h index b97cc88b..7e50824 100644 --- a/third_party/WebKit/Source/core/style/ComputedStyle.h +++ b/third_party/WebKit/Source/core/style/ComputedStyle.h
@@ -1741,6 +1741,11 @@ return BorderImage().Outset() == o.BorderImage().Outset(); } + bool BackgroundVisuallyEqual(const ComputedStyle& o) const { + return BackgroundColorInternal() == o.BackgroundColorInternal() && + BackgroundInternal().VisuallyEqual(o.BackgroundInternal()); + } + void ResetBorder() { ResetBorderImage(); ResetBorderTop();
diff --git a/third_party/WebKit/Source/core/style/FillLayer.cpp b/third_party/WebKit/Source/core/style/FillLayer.cpp index 1a78c91..b7b4e6e 100644 --- a/third_party/WebKit/Source/core/style/FillLayer.cpp +++ b/third_party/WebKit/Source/core/style/FillLayer.cpp
@@ -180,6 +180,12 @@ ((next_ && o.next_) ? *next_ == *o.next_ : next_ == o.next_); } +bool FillLayer::VisuallyEqual(const FillLayer& o) const { + if (!image_ && !o.image_ && clip_ == o.clip_) + return true; + return *this == o; +} + void FillLayer::FillUnsetProperties() { FillLayer* curr; for (curr = this; curr && curr->IsXPositionSet(); curr = curr->Next()) {
diff --git a/third_party/WebKit/Source/core/style/FillLayer.h b/third_party/WebKit/Source/core/style/FillLayer.h index 16b2865..97453b6 100644 --- a/third_party/WebKit/Source/core/style/FillLayer.h +++ b/third_party/WebKit/Source/core/style/FillLayer.h
@@ -210,6 +210,8 @@ bool operator==(const FillLayer&) const; bool operator!=(const FillLayer& o) const { return !(*this == o); } + bool VisuallyEqual(const FillLayer&) const; + bool ContainsImage(StyleImage*) const; bool ImagesAreLoaded() const;
diff --git a/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp b/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp index 5b1de43f..832fd70 100644 --- a/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp +++ b/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp
@@ -314,8 +314,11 @@ }); } -void SVGImage::PopulateImageForCurrentFrame(PaintImageBuilder& builder) { +PaintImage SVGImage::PaintImageForCurrentFrame() { + PaintImageBuilder builder; + InitPaintImageBuilder(builder); PopulatePaintRecordForCurrentFrameForContainer(builder, NullURL(), Size()); + return builder.TakePaintImage(); } void SVGImage::DrawPatternForContainer(GraphicsContext& context,
diff --git a/third_party/WebKit/Source/core/svg/graphics/SVGImage.h b/third_party/WebKit/Source/core/svg/graphics/SVGImage.h index 7ccf3f4..b680d11 100644 --- a/third_party/WebKit/Source/core/svg/graphics/SVGImage.h +++ b/third_party/WebKit/Source/core/svg/graphics/SVGImage.h
@@ -104,8 +104,7 @@ const IntRect& draw_dst_rect, bool flip_y) override; - protected: - void PopulateImageForCurrentFrame(PaintImageBuilder&) override; + PaintImage PaintImageForCurrentFrame() override; private: // Accesses m_page.
diff --git a/third_party/WebKit/Source/core/svg/graphics/SVGImageForContainer.cpp b/third_party/WebKit/Source/core/svg/graphics/SVGImageForContainer.cpp index e78d0033..2b692086 100644 --- a/third_party/WebKit/Source/core/svg/graphics/SVGImageForContainer.cpp +++ b/third_party/WebKit/Source/core/svg/graphics/SVGImageForContainer.cpp
@@ -61,9 +61,11 @@ local_matrix); } -void SVGImageForContainer::PopulateImageForCurrentFrame( - PaintImageBuilder& builder) { +PaintImage SVGImageForContainer::PaintImageForCurrentFrame() { + PaintImageBuilder builder; + InitPaintImageBuilder(builder); image_->PopulatePaintRecordForCurrentFrameForContainer(builder, url_, Size()); + return builder.TakePaintImage(); } } // namespace blink
diff --git a/third_party/WebKit/Source/core/svg/graphics/SVGImageForContainer.h b/third_party/WebKit/Source/core/svg/graphics/SVGImageForContainer.h index c4a1e05..c509236 100644 --- a/third_party/WebKit/Source/core/svg/graphics/SVGImageForContainer.h +++ b/third_party/WebKit/Source/core/svg/graphics/SVGImageForContainer.h
@@ -90,6 +90,8 @@ return false; } + PaintImage PaintImageForCurrentFrame() override; + protected: void DrawPattern(GraphicsContext&, const FloatRect&, @@ -99,8 +101,6 @@ const FloatRect&, const FloatSize& repeat_spacing) override; - void PopulateImageForCurrentFrame(PaintImageBuilder&) override; - private: SVGImageForContainer(SVGImage* image, const FloatSize& container_size,
diff --git a/third_party/WebKit/Source/core/testing/Internals.cpp b/third_party/WebKit/Source/core/testing/Internals.cpp index d36b562..320ad5b 100644 --- a/third_party/WebKit/Source/core/testing/Internals.cpp +++ b/third_party/WebKit/Source/core/testing/Internals.cpp
@@ -741,6 +741,10 @@ top_height, bottom_height, shrinks_layout); } +void Internals::setBrowserControlsShownRatio(float ratio) { + document_->GetPage()->GetChromeClient().SetBrowserControlsShownRatio(ratio); +} + ShadowRoot* Internals::shadowRoot(Element* host) { // FIXME: Internals::shadowRoot() in tests should be converted to // youngestShadowRoot() or oldestShadowRoot().
diff --git a/third_party/WebKit/Source/core/testing/Internals.h b/third_party/WebKit/Source/core/testing/Internals.h index 43cde4c..9c4fdb7 100644 --- a/third_party/WebKit/Source/core/testing/Internals.h +++ b/third_party/WebKit/Source/core/testing/Internals.h
@@ -111,6 +111,7 @@ void setBrowserControlsState(float top_height, float bottom_height, bool shrinks_layout); + void setBrowserControlsShownRatio(float); ShadowRoot* createUserAgentShadowRoot(Element* host);
diff --git a/third_party/WebKit/Source/core/testing/Internals.idl b/third_party/WebKit/Source/core/testing/Internals.idl index c1ae7f4..d5d797eb 100644 --- a/third_party/WebKit/Source/core/testing/Internals.idl +++ b/third_party/WebKit/Source/core/testing/Internals.idl
@@ -56,6 +56,7 @@ [RaisesException] ShadowRoot youngerShadowRoot(Node root); void setBrowserControlsState(float top_height, float bottom_height, boolean shrinksLayout); + void setBrowserControlsShownRatio(float ratio); [RaisesException] DOMString shadowRootType(Node root); [RaisesException] boolean hasShadowInsertionPoint(Node root);
diff --git a/third_party/WebKit/Source/core/workers/ThreadedWorkletMessagingProxy.cpp b/third_party/WebKit/Source/core/workers/ThreadedWorkletMessagingProxy.cpp index 6e7949d..e9e0e88 100644 --- a/third_party/WebKit/Source/core/workers/ThreadedWorkletMessagingProxy.cpp +++ b/third_party/WebKit/Source/core/workers/ThreadedWorkletMessagingProxy.cpp
@@ -84,7 +84,7 @@ WorkerClients* worker_clients) : ThreadedMessagingProxyBase(execution_context, worker_clients) { worklet_object_proxy_ = - ThreadedWorkletObjectProxy::Create(this, GetParentFrameTaskRunners()); + CreateObjectProxy(this, GetParentFrameTaskRunners()); } void ThreadedWorkletMessagingProxy::Initialize() { @@ -152,6 +152,14 @@ TerminateGlobalScope(); } +std::unique_ptr<ThreadedWorkletObjectProxy> + ThreadedWorkletMessagingProxy::CreateObjectProxy( + ThreadedWorkletMessagingProxy* messaging_proxy, + ParentFrameTaskRunners* parent_frame_task_runners) { + return ThreadedWorkletObjectProxy::Create(messaging_proxy, + parent_frame_task_runners); +} + void ThreadedWorkletMessagingProxy::NotifyLoadingFinished( WorkletScriptLoader* loader) { loaders_.erase(loader);
diff --git a/third_party/WebKit/Source/core/workers/ThreadedWorkletMessagingProxy.h b/third_party/WebKit/Source/core/workers/ThreadedWorkletMessagingProxy.h index 076bdd37..c5ebf5e7 100644 --- a/third_party/WebKit/Source/core/workers/ThreadedWorkletMessagingProxy.h +++ b/third_party/WebKit/Source/core/workers/ThreadedWorkletMessagingProxy.h
@@ -47,6 +47,10 @@ friend class ThreadedWorkletMessagingProxyForTest; class LoaderClient; + virtual std::unique_ptr<ThreadedWorkletObjectProxy> CreateObjectProxy( + ThreadedWorkletMessagingProxy*, + ParentFrameTaskRunners*); + void NotifyLoadingFinished(WorkletScriptLoader*); void EvaluateScript(const ScriptSourceCode&);
diff --git a/third_party/WebKit/Source/core/workers/ThreadedWorkletObjectProxy.cpp b/third_party/WebKit/Source/core/workers/ThreadedWorkletObjectProxy.cpp index 5b5bfe4..92238a30 100644 --- a/third_party/WebKit/Source/core/workers/ThreadedWorkletObjectProxy.cpp +++ b/third_party/WebKit/Source/core/workers/ThreadedWorkletObjectProxy.cpp
@@ -5,8 +5,6 @@ #include "core/workers/ThreadedWorkletObjectProxy.h" #include <memory> -#include "bindings/core/v8/ScriptSourceCode.h" -#include "bindings/core/v8/WorkerOrWorkletScriptController.h" #include "core/workers/ThreadedWorkletGlobalScope.h" #include "core/workers/ThreadedWorkletMessagingProxy.h" #include "core/workers/WorkerThread.h" @@ -27,10 +25,9 @@ void ThreadedWorkletObjectProxy::EvaluateScript(const String& source, const KURL& script_url, WorkerThread* worker_thread) { - ThreadedWorkletGlobalScope* global_scope = - ToThreadedWorkletGlobalScope(worker_thread->GlobalScope()); - global_scope->ScriptController()->Evaluate( - ScriptSourceCode(source, script_url)); + worker_thread->GlobalScope()->EvaluateClassicScript( + script_url, source, nullptr /* cached_meta_data */, + kV8CacheOptionsDefault); } ThreadedWorkletObjectProxy::ThreadedWorkletObjectProxy(
diff --git a/third_party/WebKit/Source/core/workers/ThreadedWorkletObjectProxy.h b/third_party/WebKit/Source/core/workers/ThreadedWorkletObjectProxy.h index b930da9..979a3a9b 100644 --- a/third_party/WebKit/Source/core/workers/ThreadedWorkletObjectProxy.h +++ b/third_party/WebKit/Source/core/workers/ThreadedWorkletObjectProxy.h
@@ -28,9 +28,9 @@ ParentFrameTaskRunners*); ~ThreadedWorkletObjectProxy() override; - void EvaluateScript(const String& source, - const KURL& script_url, - WorkerThread*); + virtual void EvaluateScript(const String& source, + const KURL& script_url, + WorkerThread*); // ThreadedObjectProxyBase overrides. void ReportException(const String& error_message,
diff --git a/third_party/WebKit/Source/core/workers/WorkerGlobalScope.cpp b/third_party/WebKit/Source/core/workers/WorkerGlobalScope.cpp index 03842d7..21c98ecf0 100644 --- a/third_party/WebKit/Source/core/workers/WorkerGlobalScope.cpp +++ b/third_party/WebKit/Source/core/workers/WorkerGlobalScope.cpp
@@ -88,8 +88,26 @@ return KURL(url_, url); } +void WorkerGlobalScope::EvaluateClassicScript( + const KURL& script_url, + String source_code, + std::unique_ptr<Vector<char>> cached_meta_data, + V8CacheOptions v8_cache_options) { + DCHECK(IsContextThread()); + CachedMetadataHandler* handler = CreateWorkerScriptCachedMetadataHandler( + script_url, cached_meta_data.get()); + DCHECK(!source_code.IsNull()); + GetThread()->GetWorkerReportingProxy().WillEvaluateWorkerScript( + source_code.length(), + cached_meta_data.get() ? cached_meta_data->size() : 0); + bool success = ScriptController()->Evaluate( + ScriptSourceCode(source_code, script_url), nullptr /* error_event */, + handler, v8_cache_options); + GetThread()->GetWorkerReportingProxy().DidEvaluateWorkerScript(success); +} + void WorkerGlobalScope::Dispose() { - DCHECK(GetThread()->IsCurrentThread()); + DCHECK(IsContextThread()); // Event listeners would keep DOMWrapperWorld objects alive for too long. // Also, they have references to JS objects, which become dangling once Heap
diff --git a/third_party/WebKit/Source/core/workers/WorkerGlobalScope.h b/third_party/WebKit/Source/core/workers/WorkerGlobalScope.h index 40f364f..09f56d8 100644 --- a/third_party/WebKit/Source/core/workers/WorkerGlobalScope.h +++ b/third_party/WebKit/Source/core/workers/WorkerGlobalScope.h
@@ -80,6 +80,10 @@ KURL CompleteURL(const String&) const; // WorkerOrWorkletGlobalScope + void EvaluateClassicScript(const KURL& script_url, + String source_code, + std::unique_ptr<Vector<char>> cached_meta_data, + V8CacheOptions) final; bool IsClosing() const final { return closing_; } virtual void Dispose(); void ReportFeature(WebFeature) final;
diff --git a/third_party/WebKit/Source/core/workers/WorkerOrWorkletGlobalScope.h b/third_party/WebKit/Source/core/workers/WorkerOrWorkletGlobalScope.h index 4810215..f28fe1a 100644 --- a/third_party/WebKit/Source/core/workers/WorkerOrWorkletGlobalScope.h +++ b/third_party/WebKit/Source/core/workers/WorkerOrWorkletGlobalScope.h
@@ -5,6 +5,7 @@ #ifndef WorkerOrWorkletGlobalScope_h #define WorkerOrWorkletGlobalScope_h +#include "bindings/core/v8/V8CacheOptions.h" #include "core/dom/ExecutionContext.h" #include "core/frame/UseCounter.h" #include "core/workers/WorkerClients.h" @@ -29,6 +30,15 @@ virtual ScriptWrappable* GetScriptWrappable() const = 0; + // Evaluates the given main script as a classic script (as opposed to a module + // script). + // https://html.spec.whatwg.org/multipage/webappapis.html#classic-script + virtual void EvaluateClassicScript( + const KURL& script_url, + String source_code, + std::unique_ptr<Vector<char>> cached_meta_data, + V8CacheOptions) = 0; + // Returns true when the WorkerOrWorkletGlobalScope is closing (e.g. via // WorkerGlobalScope#close() method). If this returns true, the worker is // going to be shutdown after the current task execution. Globals that
diff --git a/third_party/WebKit/Source/core/workers/WorkerThread.cpp b/third_party/WebKit/Source/core/workers/WorkerThread.cpp index 6d90b7d..b8941bc 100644 --- a/third_party/WebKit/Source/core/workers/WorkerThread.cpp +++ b/third_party/WebKit/Source/core/workers/WorkerThread.cpp
@@ -501,21 +501,11 @@ return; } - if (!GlobalScope()->IsWorkerGlobalScope()) - return; - DCHECK(!source_code.IsNull()); - - WorkerGlobalScope* worker_global_scope = ToWorkerGlobalScope(GlobalScope()); - CachedMetadataHandler* handler = - worker_global_scope->CreateWorkerScriptCachedMetadataHandler( - script_url, cached_meta_data.get()); - worker_reporting_proxy_.WillEvaluateWorkerScript( - source_code.length(), - cached_meta_data.get() ? cached_meta_data->size() : 0); - bool success = worker_global_scope->ScriptController()->Evaluate( - ScriptSourceCode(source_code, script_url), nullptr, handler, - v8_cache_options); - worker_reporting_proxy_.DidEvaluateWorkerScript(success); + // TODO(nhiroki): Start module loading for workers here. + // (https://crbug.com/680046) + GlobalScope()->EvaluateClassicScript(script_url, std::move(source_code), + std::move(cached_meta_data), + v8_cache_options); } void WorkerThread::PrepareForShutdownOnWorkerThread() {
diff --git a/third_party/WebKit/Source/core/workers/WorkerThread.h b/third_party/WebKit/Source/core/workers/WorkerThread.h index 103fa1d..e75af1c 100644 --- a/third_party/WebKit/Source/core/workers/WorkerThread.h +++ b/third_party/WebKit/Source/core/workers/WorkerThread.h
@@ -236,14 +236,16 @@ // the main thread. void EnsureScriptExecutionTerminates(ExitCode); + // These are called in this order during worker thread startup. void InitializeSchedulerOnWorkerThread(WaitableEvent*); void InitializeOnWorkerThread( std::unique_ptr<GlobalScopeCreationParams>, const WTF::Optional<WorkerBackingThreadStartupData>&); + + // These are called in this order during worker thread termination. void PrepareForShutdownOnWorkerThread(); void PerformShutdownOnWorkerThread(); - template <WTF::FunctionThreadAffinity threadAffinity> - void PerformTaskOnWorkerThread(Function<void(), threadAffinity> task); + void PerformDebuggerTaskOnWorkerThread(CrossThreadClosure); void PerformDebuggerTaskDontWaitOnWorkerThread();
diff --git a/third_party/WebKit/Source/core/workers/WorkletGlobalScope.cpp b/third_party/WebKit/Source/core/workers/WorkletGlobalScope.cpp index 99e935b..87da7b6 100644 --- a/third_party/WebKit/Source/core/workers/WorkletGlobalScope.cpp +++ b/third_party/WebKit/Source/core/workers/WorkletGlobalScope.cpp
@@ -5,6 +5,7 @@ #include "core/workers/WorkletGlobalScope.h" #include <memory> +#include "bindings/core/v8/ScriptSourceCode.h" #include "bindings/core/v8/SourceLocation.h" #include "bindings/core/v8/WorkerOrWorkletScriptController.h" #include "core/dom/Modulator.h" @@ -30,7 +31,25 @@ SetSecurityOrigin(std::move(security_origin)); } -WorkletGlobalScope::~WorkletGlobalScope() {} +WorkletGlobalScope::~WorkletGlobalScope() = default; + +void WorkletGlobalScope::EvaluateClassicScript( + const KURL& script_url, + String source_code, + std::unique_ptr<Vector<char>> cached_meta_data, + V8CacheOptions v8_cache_options) { + if (source_code.IsNull()) { + // |source_code| is null when this is called during worker thread startup. + // Worklet will evaluate the script later via Worklet.addModule(). + // TODO(nhiroki): Add NOTREACHED() once threaded worklet supports module + // loading. + return; + } + DCHECK(!cached_meta_data); + ScriptController()->Evaluate(ScriptSourceCode(source_code, script_url), + nullptr /* error_event */, + nullptr /* cache_handler */, v8_cache_options); +} v8::Local<v8::Object> WorkletGlobalScope::Wrap( v8::Isolate*,
diff --git a/third_party/WebKit/Source/core/workers/WorkletGlobalScope.h b/third_party/WebKit/Source/core/workers/WorkletGlobalScope.h index aebbb8ee..65aa9b2 100644 --- a/third_party/WebKit/Source/core/workers/WorkletGlobalScope.h +++ b/third_party/WebKit/Source/core/workers/WorkletGlobalScope.h
@@ -45,6 +45,11 @@ return const_cast<WorkletGlobalScope*>(this); } + void EvaluateClassicScript(const KURL& script_url, + String source_code, + std::unique_ptr<Vector<char>> cached_meta_data, + V8CacheOptions) final; + // Always returns false here as worklets don't have a #close() method on // the global. bool IsClosing() const final { return false; }
diff --git a/third_party/WebKit/Source/devtools/front_end/application_test_runner/AppcacheTestRunner.js b/third_party/WebKit/Source/devtools/front_end/application_test_runner/AppcacheTestRunner.js index 17c8274..cf9439b 100644 --- a/third_party/WebKit/Source/devtools/front_end/application_test_runner/AppcacheTestRunner.js +++ b/third_party/WebKit/Source/devtools/front_end/application_test_runner/AppcacheTestRunner.js
@@ -185,7 +185,7 @@ ApplicationTestRunner.awaitedFrameStatusEventsCount[frameId] = {count: eventsLeft, callback: callback}; }; -(async function() { +TestRunner.initAsync(async function() { await TestRunner.evaluateInPagePromise(` var framesCount = 0; @@ -212,4 +212,4 @@ iframe.contentWindow.applicationCache.swapCache(); } `); -})(); +});
diff --git a/third_party/WebKit/Source/devtools/front_end/application_test_runner/CacheStorageTestRunner.js b/third_party/WebKit/Source/devtools/front_end/application_test_runner/CacheStorageTestRunner.js index 2a290155..5f4cc7c 100644 --- a/third_party/WebKit/Source/devtools/front_end/application_test_runner/CacheStorageTestRunner.js +++ b/third_party/WebKit/Source/devtools/front_end/application_test_runner/CacheStorageTestRunner.js
@@ -130,7 +130,7 @@ return TestRunner.callFunctionInPageAsync('clearAllCaches'); }; -(async function() { +TestRunner.initAsync(async function() { await TestRunner.evaluateInPagePromise(` function onCacheStorageError(e) { console.error('CacheStorage error: ' + e); @@ -170,4 +170,4 @@ return caches.keys().then(keys => Promise.all(keys.map(key => caches.delete(key)))).catch(onCacheStorageError.bind(this, undefined)); } `); -})(); +});
diff --git a/third_party/WebKit/Source/devtools/front_end/application_test_runner/IndexedDBTestRunner.js b/third_party/WebKit/Source/devtools/front_end/application_test_runner/IndexedDBTestRunner.js index 696bf91..acd69323 100644 --- a/third_party/WebKit/Source/devtools/front_end/application_test_runner/IndexedDBTestRunner.js +++ b/third_party/WebKit/Source/devtools/front_end/application_test_runner/IndexedDBTestRunner.js
@@ -133,7 +133,7 @@ 'addIDBValueAsync(\'' + databaseName + '\', \'' + objectStoreName + '\', \'' + key + '\', \'' + value + '\')'); }; -(async function() { +TestRunner.initAsync(async function() { await TestRunner.evaluateInPagePromise(` function dispatchCallback(callbackId) { console.log(callbackId); @@ -353,4 +353,4 @@ return promise; } `); -})(); +});
diff --git a/third_party/WebKit/Source/devtools/front_end/application_test_runner/ResourcesTestRunner.js b/third_party/WebKit/Source/devtools/front_end/application_test_runner/ResourcesTestRunner.js index 7c620763..f22e15a 100644 --- a/third_party/WebKit/Source/devtools/front_end/application_test_runner/ResourcesTestRunner.js +++ b/third_party/WebKit/Source/devtools/front_end/application_test_runner/ResourcesTestRunner.js
@@ -100,10 +100,10 @@ return TestRunner.mainTarget.model(Resources.IndexedDBModel); }; -(async function() { +TestRunner.initAsync(async function() { await TestRunner.evaluateInPagePromise(` function _openWebSQLDatabase(name) { return new Promise(resolve => openDatabase(name, '1.0', '', 1024 * 1024, resolve)); } `); -})(); +});
diff --git a/third_party/WebKit/Source/devtools/front_end/application_test_runner/ServiceWorkersTestRunner.js b/third_party/WebKit/Source/devtools/front_end/application_test_runner/ServiceWorkersTestRunner.js index 51158e46..9696b83b 100644 --- a/third_party/WebKit/Source/devtools/front_end/application_test_runner/ServiceWorkersTestRunner.js +++ b/third_party/WebKit/Source/devtools/front_end/application_test_runner/ServiceWorkersTestRunner.js
@@ -57,7 +57,7 @@ TestRunner.callFunctionInPageAsync('makeFetchInServiceWorker', [scope, url, requestInitializer]).then(callback); }; -(async function() { +TestRunner.initAsync(async function() { await TestRunner.evaluateInPagePromise(` var registrations = {}; @@ -101,4 +101,4 @@ }); } `); -})(); +});
diff --git a/third_party/WebKit/Source/devtools/front_end/extensions_test_runner/ExtensionsTestRunner.js b/third_party/WebKit/Source/devtools/front_end/extensions_test_runner/ExtensionsTestRunner.js index 21cb4d88..24ea15c 100644 --- a/third_party/WebKit/Source/devtools/front_end/extensions_test_runner/ExtensionsTestRunner.js +++ b/third_party/WebKit/Source/devtools/front_end/extensions_test_runner/ExtensionsTestRunner.js
@@ -48,7 +48,7 @@ Extensions.extensionServer.initializeExtensions(); }; -(async function() { +TestRunner.initAsync(async function() { await TestRunner.evaluateInPagePromise(` function extensionFunctions() { var functions = ''; @@ -72,4 +72,4 @@ InspectorTest.runExtensionTests(); }; `); -})(); +});
diff --git a/third_party/WebKit/Source/devtools/front_end/formatter_worker/ESTreeWalker.js b/third_party/WebKit/Source/devtools/front_end/formatter_worker/ESTreeWalker.js index f3e79dc..964a53e 100644 --- a/third_party/WebKit/Source/devtools/front_end/formatter_worker/ESTreeWalker.js +++ b/third_party/WebKit/Source/devtools/front_end/formatter_worker/ESTreeWalker.js
@@ -93,6 +93,7 @@ FormatterWorker.ESTreeWalker._walkOrder = { 'AwaitExpression': ['arguments'], 'ArrayExpression': ['elements'], + 'ArrayPattern': ['elements'], 'ArrowFunctionExpression': ['params', 'body'], 'AssignmentExpression': ['left', 'right'], 'BinaryExpression': ['left', 'right'],
diff --git a/third_party/WebKit/Source/devtools/front_end/network_test_runner/NetworkTestRunner.js b/third_party/WebKit/Source/devtools/front_end/network_test_runner/NetworkTestRunner.js index 3adcce4..6570ae5 100644 --- a/third_party/WebKit/Source/devtools/front_end/network_test_runner/NetworkTestRunner.js +++ b/third_party/WebKit/Source/devtools/front_end/network_test_runner/NetworkTestRunner.js
@@ -146,7 +146,7 @@ NetworkTestRunner.HARPropertyFormattersWithSize = JSON.parse(JSON.stringify(NetworkTestRunner.HARPropertyFormatters)); NetworkTestRunner.HARPropertyFormattersWithSize.size = 'formatAsTypeName'; -(async function() { +TestRunner.initAsync(async function() { await TestRunner.evaluateInPagePromise(` var lastXHRIndex = 0; @@ -225,4 +225,4 @@ }); } `); -})(); +});
diff --git a/third_party/WebKit/Source/devtools/front_end/performance_test_runner/TimelineTestRunner.js b/third_party/WebKit/Source/devtools/front_end/performance_test_runner/TimelineTestRunner.js index 2f8442b..ad30b4f 100644 --- a/third_party/WebKit/Source/devtools/front_end/performance_test_runner/TimelineTestRunner.js +++ b/third_party/WebKit/Source/devtools/front_end/performance_test_runner/TimelineTestRunner.js
@@ -371,7 +371,7 @@ return promise; }; -(async function() { +TestRunner.initAsync(async function() { await TestRunner.evaluateInPagePromise(` function wrapCallFunctionForTimeline(f) { var script = document.createElement('script'); @@ -405,4 +405,4 @@ return promise; } `); -})(); +});
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/CookieModel.js b/third_party/WebKit/Source/devtools/front_end/sdk/CookieModel.js index c4e44da..8102071 100644 --- a/third_party/WebKit/Source/devtools/front_end/sdk/CookieModel.js +++ b/third_party/WebKit/Source/devtools/front_end/sdk/CookieModel.js
@@ -20,7 +20,7 @@ cookie.addAttribute('path', protocolCookie['path']); cookie.addAttribute('port', protocolCookie['port']); if (protocolCookie['expires']) - cookie.addAttribute('expires', protocolCookie['expires']); + cookie.addAttribute('expires', String(protocolCookie['expires'] * 1000)); if (protocolCookie['httpOnly']) cookie.addAttribute('httpOnly'); if (protocolCookie['secure']) @@ -96,7 +96,7 @@ return this.target() .networkAgent() .setCookie( - cookie.url(), cookie.name(), cookie.value(), domain, cookie.path(), cookie.secure(), cookie.httpOnly(), + cookie.name(), cookie.value(), cookie.url(), domain, cookie.path(), cookie.secure(), cookie.httpOnly(), cookie.sameSite(), expires) .then(success => !!success); }
diff --git a/third_party/WebKit/Source/devtools/front_end/sources_test_runner/DebuggerTestRunner.js b/third_party/WebKit/Source/devtools/front_end/sources_test_runner/DebuggerTestRunner.js index 3f52c02..d132a059 100644 --- a/third_party/WebKit/Source/devtools/front_end/sources_test_runner/DebuggerTestRunner.js +++ b/third_party/WebKit/Source/devtools/front_end/sources_test_runner/DebuggerTestRunner.js
@@ -748,10 +748,10 @@ } }; -(async function() { +TestRunner.initAsync(async function() { await TestRunner.evaluateInPagePromise(` function scheduleTestFunction() { setTimeout(testFunction, 0); } `); -})(); +});
diff --git a/third_party/WebKit/Source/devtools/front_end/sources_test_runner/SearchTestRunner.js b/third_party/WebKit/Source/devtools/front_end/sources_test_runner/SearchTestRunner.js index 588523a..c155e55 100644 --- a/third_party/WebKit/Source/devtools/front_end/sources_test_runner/SearchTestRunner.js +++ b/third_party/WebKit/Source/devtools/front_end/sources_test_runner/SearchTestRunner.js
@@ -140,9 +140,9 @@ } }; -(async function() { +TestRunner.initAsync(async function() { await TestRunner.evaluateInPagePromise(` if (window.GCController) GCController.collect(); `); -})(); +});
diff --git a/third_party/WebKit/Source/devtools/front_end/test_runner/TestRunner.js b/third_party/WebKit/Source/devtools/front_end/test_runner/TestRunner.js index 0d217cd..9b756af5 100644 --- a/third_party/WebKit/Source/devtools/front_end/test_runner/TestRunner.js +++ b/third_party/WebKit/Source/devtools/front_end/test_runner/TestRunner.js
@@ -154,12 +154,33 @@ }); }; +/** @type {number} */ +TestRunner._pendingInits = 0; + +/** @type {function():void} */ +TestRunner._resolveOnFinishInits; + +/** + * @param {function():!Promise} asyncFunction + */ +TestRunner.initAsync = async function(asyncFunction) { + TestRunner._pendingInits++; + await asyncFunction(); + TestRunner._pendingInits--; + if (!TestRunner._pendingInits) + TestRunner._resolveOnFinishInits(); +}; + /** * @param {string} module * @return {!Promise<undefined>} */ -TestRunner.loadModule = function(module) { - return self.runtime.loadModulePromise(module); +TestRunner.loadModule = async function(module) { + var promise = new Promise(resolve => TestRunner._resolveOnFinishInits = resolve); + await self.runtime.loadModulePromise(module); + if (!TestRunner._pendingInits) + return; + return promise; }; /**
diff --git a/third_party/WebKit/Source/modules/app_banner/AppBannerPromptResult.cpp b/third_party/WebKit/Source/modules/app_banner/AppBannerPromptResult.cpp deleted file mode 100644 index 9df48c9..0000000 --- a/third_party/WebKit/Source/modules/app_banner/AppBannerPromptResult.cpp +++ /dev/null
@@ -1,28 +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. - -#include "modules/app_banner/AppBannerPromptResult.h" - -namespace blink { - -AppBannerPromptResult::~AppBannerPromptResult() {} - -String AppBannerPromptResult::outcome() const { - switch (outcome_) { - case Outcome::kAccepted: - return "accepted"; - - case Outcome::kDismissed: - return "dismissed"; - } - - NOTREACHED(); - return ""; -} - -AppBannerPromptResult::AppBannerPromptResult(const String& platform, - Outcome outcome) - : platform_(platform), outcome_(outcome) {} - -} // namespace blink
diff --git a/third_party/WebKit/Source/modules/app_banner/AppBannerPromptResult.h b/third_party/WebKit/Source/modules/app_banner/AppBannerPromptResult.h deleted file mode 100644 index 1db97f2..0000000 --- a/third_party/WebKit/Source/modules/app_banner/AppBannerPromptResult.h +++ /dev/null
@@ -1,44 +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. - -#ifndef AppBannerPromptResult_h -#define AppBannerPromptResult_h - -#include "platform/bindings/ScriptWrappable.h" -#include "platform/wtf/Noncopyable.h" -#include "platform/wtf/text/WTFString.h" - -namespace blink { - -class AppBannerPromptResult final - : public GarbageCollectedFinalized<AppBannerPromptResult>, - public ScriptWrappable { - DEFINE_WRAPPERTYPEINFO(); - WTF_MAKE_NONCOPYABLE(AppBannerPromptResult); - - public: - enum class Outcome { kAccepted, kDismissed }; - - static AppBannerPromptResult* Create(const String& platform, - Outcome outcome) { - return new AppBannerPromptResult(platform, outcome); - } - - virtual ~AppBannerPromptResult(); - - String platform() const { return platform_; } - String outcome() const; - - DEFINE_INLINE_VIRTUAL_TRACE() {} - - private: - AppBannerPromptResult(const String& platform, Outcome); - - String platform_; - Outcome outcome_; -}; - -} // namespace blink - -#endif // AppBannerPromptResult_h
diff --git a/third_party/WebKit/Source/modules/app_banner/AppBannerPromptResult.idl b/third_party/WebKit/Source/modules/app_banner/AppBannerPromptResult.idl index 2b25182..51804cb 100644 --- a/third_party/WebKit/Source/modules/app_banner/AppBannerPromptResult.idl +++ b/third_party/WebKit/Source/modules/app_banner/AppBannerPromptResult.idl
@@ -4,7 +4,7 @@ enum AppBannerPromptOutcome { "accepted", "dismissed" }; -interface AppBannerPromptResult { - readonly attribute DOMString platform; - readonly attribute AppBannerPromptOutcome outcome; +dictionary AppBannerPromptResult { + required DOMString platform; + required AppBannerPromptOutcome outcome; };
diff --git a/third_party/WebKit/Source/modules/app_banner/BUILD.gn b/third_party/WebKit/Source/modules/app_banner/BUILD.gn index f02298c5..e130df81 100644 --- a/third_party/WebKit/Source/modules/app_banner/BUILD.gn +++ b/third_party/WebKit/Source/modules/app_banner/BUILD.gn
@@ -8,8 +8,6 @@ sources = [ "AppBannerController.cpp", "AppBannerController.h", - "AppBannerPromptResult.cpp", - "AppBannerPromptResult.h", "BeforeInstallPromptEvent.cpp", "BeforeInstallPromptEvent.h", "DOMWindowInstallation.h",
diff --git a/third_party/WebKit/Source/modules/app_banner/BeforeInstallPromptEvent.cpp b/third_party/WebKit/Source/modules/app_banner/BeforeInstallPromptEvent.cpp index 79505c1..c537c13 100644 --- a/third_party/WebKit/Source/modules/app_banner/BeforeInstallPromptEvent.cpp +++ b/third_party/WebKit/Source/modules/app_banner/BeforeInstallPromptEvent.cpp
@@ -107,13 +107,17 @@ } void BeforeInstallPromptEvent::BannerAccepted(const String& platform) { - user_choice_->Resolve(AppBannerPromptResult::Create( - platform, AppBannerPromptResult::Outcome::kAccepted)); + AppBannerPromptResult result; + result.setPlatform(platform); + result.setOutcome("accepted"); + user_choice_->Resolve(result); } void BeforeInstallPromptEvent::BannerDismissed() { - user_choice_->Resolve(AppBannerPromptResult::Create( - g_empty_atom, AppBannerPromptResult::Outcome::kDismissed)); + AppBannerPromptResult result; + result.setPlatform(g_empty_atom); + result.setOutcome("dismissed"); + user_choice_->Resolve(result); } DEFINE_TRACE(BeforeInstallPromptEvent) {
diff --git a/third_party/WebKit/Source/modules/app_banner/BeforeInstallPromptEvent.h b/third_party/WebKit/Source/modules/app_banner/BeforeInstallPromptEvent.h index 37469f0..b8179f5 100644 --- a/third_party/WebKit/Source/modules/app_banner/BeforeInstallPromptEvent.h +++ b/third_party/WebKit/Source/modules/app_banner/BeforeInstallPromptEvent.h
@@ -23,7 +23,7 @@ using UserChoiceProperty = ScriptPromiseProperty<Member<BeforeInstallPromptEvent>, - Member<AppBannerPromptResult>, + AppBannerPromptResult, ToV8UndefinedGenerator>; class BeforeInstallPromptEvent final
diff --git a/third_party/WebKit/Source/modules/audio_output_devices/AudioOutputDeviceClientImpl.h b/third_party/WebKit/Source/modules/audio_output_devices/AudioOutputDeviceClientImpl.h index 86d6fe3..4bd5e3e 100644 --- a/third_party/WebKit/Source/modules/audio_output_devices/AudioOutputDeviceClientImpl.h +++ b/third_party/WebKit/Source/modules/audio_output_devices/AudioOutputDeviceClientImpl.h
@@ -14,7 +14,7 @@ class MODULES_EXPORT AudioOutputDeviceClientImpl : public GarbageCollectedFinalized<AudioOutputDeviceClientImpl>, - public NON_EXPORTED_BASE(AudioOutputDeviceClient) { + public AudioOutputDeviceClient { USING_GARBAGE_COLLECTED_MIXIN(AudioOutputDeviceClientImpl); WTF_MAKE_NONCOPYABLE(AudioOutputDeviceClientImpl);
diff --git a/third_party/WebKit/Source/modules/mediastream/MediaStreamTrack.cpp b/third_party/WebKit/Source/modules/mediastream/MediaStreamTrack.cpp index 028ced2..9fffb07 100644 --- a/third_party/WebKit/Source/modules/mediastream/MediaStreamTrack.cpp +++ b/third_party/WebKit/Source/modules/mediastream/MediaStreamTrack.cpp
@@ -207,7 +207,6 @@ ready_state_ = MediaStreamSource::kReadyStateEnded; MediaStreamCenter::Instance().DidStopMediaStreamTrack(Component()); - DispatchEvent(Event::Create(EventTypeNames::ended)); PropagateTrackEnded(); }
diff --git a/third_party/WebKit/Source/modules/modules_idl_files.gni b/third_party/WebKit/Source/modules/modules_idl_files.gni index 16be8f3..e2d03d3a 100644 --- a/third_party/WebKit/Source/modules/modules_idl_files.gni +++ b/third_party/WebKit/Source/modules/modules_idl_files.gni
@@ -39,7 +39,6 @@ modules_idl_files = get_path_info([ - "app_banner/AppBannerPromptResult.idl", "app_banner/BeforeInstallPromptEvent.idl", "background_fetch/BackgroundFetchClickEvent.idl", "background_fetch/BackgroundFetchEvent.idl", @@ -406,6 +405,7 @@ modules_dictionary_idl_files = get_path_info([ + "app_banner/AppBannerPromptResult.idl", "app_banner/BeforeInstallPromptEventInit.idl", "background_fetch/BackgroundFetchClickEventInit.idl", "background_fetch/BackgroundFetchEventInit.idl",
diff --git a/third_party/WebKit/Source/modules/payments/PaymentRequest.h b/third_party/WebKit/Source/modules/payments/PaymentRequest.h index cd1236d..4b195ff2 100644 --- a/third_party/WebKit/Source/modules/payments/PaymentRequest.h +++ b/third_party/WebKit/Source/modules/payments/PaymentRequest.h
@@ -36,7 +36,7 @@ class MODULES_EXPORT PaymentRequest final : public EventTargetWithInlineData, - NON_EXPORTED_BASE(public payments::mojom::blink::PaymentRequestClient), + public payments::mojom::blink::PaymentRequestClient, public PaymentCompleter, public PaymentUpdater, public ContextLifecycleObserver,
diff --git a/third_party/WebKit/Source/modules/peerconnection/RTCDataChannel.h b/third_party/WebKit/Source/modules/peerconnection/RTCDataChannel.h index e0b557a..0baadb2 100644 --- a/third_party/WebKit/Source/modules/peerconnection/RTCDataChannel.h +++ b/third_party/WebKit/Source/modules/peerconnection/RTCDataChannel.h
@@ -49,7 +49,7 @@ class MODULES_EXPORT RTCDataChannel final : public EventTargetWithInlineData, - NON_EXPORTED_BASE(public WebRTCDataChannelHandlerClient), + public WebRTCDataChannelHandlerClient, public ActiveScriptWrappable<RTCDataChannel>, public SuspendableObject { USING_GARBAGE_COLLECTED_MIXIN(RTCDataChannel);
diff --git a/third_party/WebKit/Source/modules/remoteplayback/RemotePlayback.h b/third_party/WebKit/Source/modules/remoteplayback/RemotePlayback.h index 836e14a..383ceebd 100644 --- a/third_party/WebKit/Source/modules/remoteplayback/RemotePlayback.h +++ b/third_party/WebKit/Source/modules/remoteplayback/RemotePlayback.h
@@ -39,9 +39,9 @@ class MODULES_EXPORT RemotePlayback final : public EventTargetWithInlineData, public ActiveScriptWrappable<RemotePlayback>, - NON_EXPORTED_BASE(public WebRemotePlaybackClient), + public WebRemotePlaybackClient, public WebPresentationAvailabilityObserver, - public NON_EXPORTED_BASE(WebPresentationConnection) { + public WebPresentationConnection { DEFINE_WRAPPERTYPEINFO(); USING_GARBAGE_COLLECTED_MIXIN(RemotePlayback);
diff --git a/third_party/WebKit/Source/modules/serviceworkers/ClientQueryOptions.idl b/third_party/WebKit/Source/modules/serviceworkers/ClientQueryOptions.idl index 8e97388..e8408391 100644 --- a/third_party/WebKit/Source/modules/serviceworkers/ClientQueryOptions.idl +++ b/third_party/WebKit/Source/modules/serviceworkers/ClientQueryOptions.idl
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// https://w3c.github.io/ServiceWorker/#client-type-enum +// https://w3c.github.io/ServiceWorker/#enumdef-clienttype enum ClientType { "window", "worker", @@ -10,7 +10,7 @@ "all" }; -// https://w3c.github.io/ServiceWorker/#serviceworker-client-query-options-dictionary +// https://w3c.github.io/ServiceWorker/#dictdef-clientqueryoptions dictionary ClientQueryOptions { boolean includeUncontrolled = false; ClientType type = "window";
diff --git a/third_party/WebKit/Source/modules/serviceworkers/ExtendableEvent.idl b/third_party/WebKit/Source/modules/serviceworkers/ExtendableEvent.idl index a89ad17c..a55175d6 100644 --- a/third_party/WebKit/Source/modules/serviceworkers/ExtendableEvent.idl +++ b/third_party/WebKit/Source/modules/serviceworkers/ExtendableEvent.idl
@@ -28,7 +28,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -// https://w3c.github.io/ServiceWorker/#extendable-event-interface +// https://w3c.github.io/ServiceWorker/#extendableevent-interface [ Constructor(DOMString type, optional ExtendableEventInit eventInitDict), Exposed=ServiceWorker
diff --git a/third_party/WebKit/Source/modules/serviceworkers/ExtendableEventInit.idl b/third_party/WebKit/Source/modules/serviceworkers/ExtendableEventInit.idl index b12d644..bef230b 100644 --- a/third_party/WebKit/Source/modules/serviceworkers/ExtendableEventInit.idl +++ b/third_party/WebKit/Source/modules/serviceworkers/ExtendableEventInit.idl
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// https://w3c.github.io/ServiceWorker/#extendable-event-interface +// https://w3c.github.io/ServiceWorker/#dictdef-extendableeventinit dictionary ExtendableEventInit : EventInit { // Defined for the forward compatibility across the derived events
diff --git a/third_party/WebKit/Source/modules/serviceworkers/ExtendableMessageEvent.idl b/third_party/WebKit/Source/modules/serviceworkers/ExtendableMessageEvent.idl index 2a907c96..a508c35 100644 --- a/third_party/WebKit/Source/modules/serviceworkers/ExtendableMessageEvent.idl +++ b/third_party/WebKit/Source/modules/serviceworkers/ExtendableMessageEvent.idl
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// https://w3c.github.io/ServiceWorker/#extendablemessage-event-section +// https://w3c.github.io/ServiceWorker/#extendablemessageevent-interface [ // TODO(bashi): Stop using CustomConstructor once we solve reference
diff --git a/third_party/WebKit/Source/modules/serviceworkers/ExtendableMessageEventInit.idl b/third_party/WebKit/Source/modules/serviceworkers/ExtendableMessageEventInit.idl index 7d04fdf26..765cda3 100644 --- a/third_party/WebKit/Source/modules/serviceworkers/ExtendableMessageEventInit.idl +++ b/third_party/WebKit/Source/modules/serviceworkers/ExtendableMessageEventInit.idl
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// https://w3c.github.io/ServiceWorker/#extendablemessage-event-section +// https://w3c.github.io/ServiceWorker/#dictdef-extendablemessageeventinit dictionary ExtendableMessageEventInit : ExtendableEventInit { any data;
diff --git a/third_party/WebKit/Source/modules/serviceworkers/FetchEvent.idl b/third_party/WebKit/Source/modules/serviceworkers/FetchEvent.idl index c9d63b6f..3529ee3b 100644 --- a/third_party/WebKit/Source/modules/serviceworkers/FetchEvent.idl +++ b/third_party/WebKit/Source/modules/serviceworkers/FetchEvent.idl
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// https://w3c.github.io/ServiceWorker/#fetch-event-interface +// https://w3c.github.io/ServiceWorker/#fetchevent-interface [ ActiveScriptWrappable, DependentLifetime,
diff --git a/third_party/WebKit/Source/modules/serviceworkers/FetchEventInit.idl b/third_party/WebKit/Source/modules/serviceworkers/FetchEventInit.idl index fbbba5d..c373916 100644 --- a/third_party/WebKit/Source/modules/serviceworkers/FetchEventInit.idl +++ b/third_party/WebKit/Source/modules/serviceworkers/FetchEventInit.idl
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// https://w3c.github.io/ServiceWorker/#fetch-event-interface +// https://w3c.github.io/ServiceWorker/#dictdef-fetcheventinit dictionary FetchEventInit : ExtendableEventInit { required Request request;
diff --git a/third_party/WebKit/Source/modules/serviceworkers/ForeignFetchEvent.idl b/third_party/WebKit/Source/modules/serviceworkers/ForeignFetchEvent.idl index 2f0b3fb..815af4b 100644 --- a/third_party/WebKit/Source/modules/serviceworkers/ForeignFetchEvent.idl +++ b/third_party/WebKit/Source/modules/serviceworkers/ForeignFetchEvent.idl
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// https://w3c.github.io/ServiceWorker/#foreign-fetch-event-section +// https://w3c.github.io/ServiceWorker/#foreignfetchevent-interface [ Constructor(DOMString type, ForeignFetchEventInit eventInitDict), ConstructorCallWith=ScriptState,
diff --git a/third_party/WebKit/Source/modules/serviceworkers/ForeignFetchEventInit.idl b/third_party/WebKit/Source/modules/serviceworkers/ForeignFetchEventInit.idl index 41c32f7..af8274c 100644 --- a/third_party/WebKit/Source/modules/serviceworkers/ForeignFetchEventInit.idl +++ b/third_party/WebKit/Source/modules/serviceworkers/ForeignFetchEventInit.idl
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// https://w3c.github.io/ServiceWorker/#dictdef-foreignfetchevent-foreignfetcheventinit +// https://w3c.github.io/ServiceWorker/#dictdef-foreignfetcheventinit dictionary ForeignFetchEventInit : ExtendableEventInit { required Request request;
diff --git a/third_party/WebKit/Source/modules/serviceworkers/ForeignFetchOptions.idl b/third_party/WebKit/Source/modules/serviceworkers/ForeignFetchOptions.idl index af372b5..2a7b72a6 100644 --- a/third_party/WebKit/Source/modules/serviceworkers/ForeignFetchOptions.idl +++ b/third_party/WebKit/Source/modules/serviceworkers/ForeignFetchOptions.idl
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// https://w3c.github.io/ServiceWorker/#dictdef-installevent-foreignfetchoptions +// https://w3c.github.io/ServiceWorker/#dictdef-foreignfetchoptions dictionary ForeignFetchOptions { required sequence<USVString> scopes;
diff --git a/third_party/WebKit/Source/modules/serviceworkers/ForeignFetchResponse.idl b/third_party/WebKit/Source/modules/serviceworkers/ForeignFetchResponse.idl index ea6bfbe5..53ac924f 100644 --- a/third_party/WebKit/Source/modules/serviceworkers/ForeignFetchResponse.idl +++ b/third_party/WebKit/Source/modules/serviceworkers/ForeignFetchResponse.idl
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// https://w3c.github.io/ServiceWorker/#dictdef-foreignfetchevent-foreignfetchresponse +// https://w3c.github.io/ServiceWorker/#dictdef-foreignfetchresponse dictionary ForeignFetchResponse { required Response response;
diff --git a/third_party/WebKit/Source/modules/serviceworkers/InstallEvent.idl b/third_party/WebKit/Source/modules/serviceworkers/InstallEvent.idl index 7f96c0fe..2113e2f 100644 --- a/third_party/WebKit/Source/modules/serviceworkers/InstallEvent.idl +++ b/third_party/WebKit/Source/modules/serviceworkers/InstallEvent.idl
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// https://w3c.github.io/ServiceWorker/#installevent-installevent +// https://w3c.github.io/ServiceWorker/#installevent [ Constructor(DOMString type, optional ExtendableEventInit eventInitDict),
diff --git a/third_party/WebKit/Source/modules/serviceworkers/NavigatorServiceWorker.idl b/third_party/WebKit/Source/modules/serviceworkers/NavigatorServiceWorker.idl index 3d987003..3c194b5 100644 --- a/third_party/WebKit/Source/modules/serviceworkers/NavigatorServiceWorker.idl +++ b/third_party/WebKit/Source/modules/serviceworkers/NavigatorServiceWorker.idl
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// https://w3c.github.io/ServiceWorker/#navigator-service-worker +// https://w3c.github.io/ServiceWorker/#navigator-serviceworker partial interface Navigator { [RaisesException, CallWith=ScriptState] readonly attribute ServiceWorkerContainer serviceWorker; };
diff --git a/third_party/WebKit/Source/modules/serviceworkers/RegistrationOptions.idl b/third_party/WebKit/Source/modules/serviceworkers/RegistrationOptions.idl index 291737e..afc7562d 100644 --- a/third_party/WebKit/Source/modules/serviceworkers/RegistrationOptions.idl +++ b/third_party/WebKit/Source/modules/serviceworkers/RegistrationOptions.idl
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// https://w3c.github.io/ServiceWorker/#registration-option-list-dictionary +// https://w3c.github.io/ServiceWorker/#dictdef-registrationoptions dictionary RegistrationOptions { USVString scope; };
diff --git a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorker.h b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorker.h index c835c2d..509bab6 100644 --- a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorker.h +++ b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorker.h
@@ -48,7 +48,7 @@ class MODULES_EXPORT ServiceWorker final : public AbstractWorker, public ActiveScriptWrappable<ServiceWorker>, - NON_EXPORTED_BASE(public WebServiceWorkerProxy) { + public WebServiceWorkerProxy { DEFINE_WRAPPERTYPEINFO(); USING_GARBAGE_COLLECTED_MIXIN(ServiceWorker);
diff --git a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerContainer.h b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerContainer.h index afe691fe..8a9fd5ea 100644 --- a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerContainer.h +++ b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerContainer.h
@@ -56,7 +56,7 @@ class MODULES_EXPORT ServiceWorkerContainer final : public EventTargetWithInlineData, public ContextLifecycleObserver, - NON_EXPORTED_BASE(public WebServiceWorkerProviderClient) { + public WebServiceWorkerProviderClient { DEFINE_WRAPPERTYPEINFO(); USING_GARBAGE_COLLECTED_MIXIN(ServiceWorkerContainer);
diff --git a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerContainer.idl b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerContainer.idl index 36f21a7..135059b 100644 --- a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerContainer.idl +++ b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerContainer.idl
@@ -28,7 +28,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -// https://w3c.github.io/ServiceWorker/#service-worker-container-interface +// https://w3c.github.io/ServiceWorker/#serviceworkercontainer-interface interface ServiceWorkerContainer : EventTarget { readonly attribute ServiceWorker? controller; [CallWith=ScriptState] readonly attribute Promise<ServiceWorkerRegistration> ready;
diff --git a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerGlobalScope.idl b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerGlobalScope.idl index 2c2e0fb9..4efdf5a 100644 --- a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerGlobalScope.idl +++ b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerGlobalScope.idl
@@ -28,7 +28,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -// https://w3c.github.io/ServiceWorker/#service-worker-global-scope-interface +// https://w3c.github.io/ServiceWorker/#serviceworkerglobalscope-interface [ Exposed=ServiceWorker,
diff --git a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerRegistration.idl b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerRegistration.idl index dbc4412..bd9d3c6 100644 --- a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerRegistration.idl +++ b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerRegistration.idl
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// https://w3c.github.io/ServiceWorker/#service-worker-registration-obj +// https://w3c.github.io/ServiceWorker/#serviceworkerregistration-interface [ ActiveScriptWrappable, DependentLifetime,
diff --git a/third_party/WebKit/Source/modules/serviceworkers/WindowClient.idl b/third_party/WebKit/Source/modules/serviceworkers/WindowClient.idl index 1dcd0c65..5b310450 100644 --- a/third_party/WebKit/Source/modules/serviceworkers/WindowClient.idl +++ b/third_party/WebKit/Source/modules/serviceworkers/WindowClient.idl
@@ -10,7 +10,7 @@ "none" }; -// https://w3c.github.io/ServiceWorker/#window-client-interface +// https://w3c.github.io/ServiceWorker/#windowclient [ Exposed=ServiceWorker, ImplementedAs=ServiceWorkerWindowClient
diff --git a/third_party/WebKit/Source/modules/speech/SpeechRecognitionClientProxy.h b/third_party/WebKit/Source/modules/speech/SpeechRecognitionClientProxy.h index 1c8a95d..b12eff3 100644 --- a/third_party/WebKit/Source/modules/speech/SpeechRecognitionClientProxy.h +++ b/third_party/WebKit/Source/modules/speech/SpeechRecognitionClientProxy.h
@@ -40,7 +40,7 @@ class WebString; class MODULES_EXPORT SpeechRecognitionClientProxy final - : public NON_EXPORTED_BASE(SpeechRecognitionClient), + : public SpeechRecognitionClient, public WebSpeechRecognizerClient { public: ~SpeechRecognitionClientProxy() override;
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioContext.cpp b/third_party/WebKit/Source/modules/webaudio/AudioContext.cpp index a30318d0..dc8f14c 100644 --- a/third_party/WebKit/Source/modules/webaudio/AudioContext.cpp +++ b/third_party/WebKit/Source/modules/webaudio/AudioContext.cpp
@@ -106,7 +106,8 @@ AudioContext::AudioContext(Document& document, const WebAudioLatencyHint& latency_hint) - : BaseAudioContext(&document), context_id_(g_context_id++) { + : BaseAudioContext(&document, kRealtimeContext), + context_id_(g_context_id++) { destination_node_ = DefaultAudioDestinationNode::Create(this, latency_hint); Initialize(); }
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioWorkletGlobalScope.h b/third_party/WebKit/Source/modules/webaudio/AudioWorkletGlobalScope.h index 2935d973..9023bef 100644 --- a/third_party/WebKit/Source/modules/webaudio/AudioWorkletGlobalScope.h +++ b/third_party/WebKit/Source/modules/webaudio/AudioWorkletGlobalScope.h
@@ -71,6 +71,12 @@ ProcessorInstances processor_instances_; }; +DEFINE_TYPE_CASTS(AudioWorkletGlobalScope, + ExecutionContext, + context, + context->IsAudioWorkletGlobalScope(), + context.IsAudioWorkletGlobalScope()); + } // namespace blink #endif // AudioWorkletGlobalScope_h
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioWorkletMessagingProxy.cpp b/third_party/WebKit/Source/modules/webaudio/AudioWorkletMessagingProxy.cpp index 231f151..f9d23c1 100644 --- a/third_party/WebKit/Source/modules/webaudio/AudioWorkletMessagingProxy.cpp +++ b/third_party/WebKit/Source/modules/webaudio/AudioWorkletMessagingProxy.cpp
@@ -4,7 +4,7 @@ #include "modules/webaudio/AudioWorkletMessagingProxy.h" -#include "core/workers/ThreadedWorkletObjectProxy.h" +#include "modules/webaudio/AudioWorkletObjectProxy.h" #include "modules/webaudio/AudioWorkletThread.h" namespace blink { @@ -16,6 +16,23 @@ AudioWorkletMessagingProxy::~AudioWorkletMessagingProxy() {} +void AudioWorkletMessagingProxy::SynchronizeWorkletData() { + DCHECK(IsMainThread()); + + // TODO(crbug.com/755566): the argument will be a set of a node name and + // parameter descriptors. Use the information to update the copy in + // AudioWorkletMessagingProxy. +} + +std::unique_ptr<ThreadedWorkletObjectProxy> + AudioWorkletMessagingProxy::CreateObjectProxy( + ThreadedWorkletMessagingProxy* messaging_proxy, + ParentFrameTaskRunners* parent_frame_task_runners) { + return WTF::MakeUnique<AudioWorkletObjectProxy>( + static_cast<AudioWorkletMessagingProxy*>(messaging_proxy), + parent_frame_task_runners); +} + std::unique_ptr<WorkerThread> AudioWorkletMessagingProxy::CreateWorkerThread() { return AudioWorkletThread::Create(CreateThreadableLoadingContext(), WorkletObjectProxy());
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioWorkletMessagingProxy.h b/third_party/WebKit/Source/modules/webaudio/AudioWorkletMessagingProxy.h index 818656f7..216f208 100644 --- a/third_party/WebKit/Source/modules/webaudio/AudioWorkletMessagingProxy.h +++ b/third_party/WebKit/Source/modules/webaudio/AudioWorkletMessagingProxy.h
@@ -13,13 +13,25 @@ class ExecutionContext; class WorkerThread; +// AudioWorkletMessagingProxy is a main thread interface for +// AudioWorkletGlobalScope. The proxy communicates with the associated global +// scope via AudioWorkletObjectProxy. class AudioWorkletMessagingProxy final : public ThreadedWorkletMessagingProxy { public: AudioWorkletMessagingProxy(ExecutionContext*, WorkerClients*); + // Invoked by AudioWorkletObjectProxy to synchronize the information from + // AudioWorkletGlobalScope after the script code evaluation. + void SynchronizeWorkletData(); + private: ~AudioWorkletMessagingProxy() override; + // Implements ThreadedWorkletMessagingProxy. + std::unique_ptr<ThreadedWorkletObjectProxy> CreateObjectProxy( + ThreadedWorkletMessagingProxy*, + ParentFrameTaskRunners*) override; + std::unique_ptr<WorkerThread> CreateWorkerThread() override; };
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioWorkletObjectProxy.cpp b/third_party/WebKit/Source/modules/webaudio/AudioWorkletObjectProxy.cpp new file mode 100644 index 0000000..247b290 --- /dev/null +++ b/third_party/WebKit/Source/modules/webaudio/AudioWorkletObjectProxy.cpp
@@ -0,0 +1,50 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "modules/webaudio/AudioWorkletObjectProxy.h" + +#include "bindings/core/v8/ScriptSourceCode.h" +#include "bindings/core/v8/WorkerOrWorkletScriptController.h" +#include "core/workers/ThreadedWorkletMessagingProxy.h" +#include "core/workers/WorkerThread.h" +#include "modules/webaudio/AudioWorkletGlobalScope.h" +#include "modules/webaudio/AudioWorkletMessagingProxy.h" + +#include "platform/CrossThreadFunctional.h" + +namespace blink { + +AudioWorkletObjectProxy::AudioWorkletObjectProxy( + AudioWorkletMessagingProxy* messaging_proxy_weak_ptr, + ParentFrameTaskRunners* parent_frame_task_runners) + : ThreadedWorkletObjectProxy( + static_cast<ThreadedWorkletMessagingProxy*>(messaging_proxy_weak_ptr), + parent_frame_task_runners) {} + +void AudioWorkletObjectProxy::EvaluateScript(const String& source, + const KURL& script_url, + WorkerThread* worker_thread) { + AudioWorkletGlobalScope* global_scope = + ToAudioWorkletGlobalScope(worker_thread->GlobalScope()); + global_scope->ScriptController()->Evaluate( + ScriptSourceCode(source, script_url)); + + // TODO(crbug.com/755566): Extract/build the information for synchronization + // and send it to the associated AudioWorkletMessagingProxy. Currently this + // is an empty cross-thread call for the future implementation. + GetParentFrameTaskRunners()->Get(TaskType::kUnthrottled) + ->PostTask( + BLINK_FROM_HERE, + CrossThreadBind( + &AudioWorkletMessagingProxy::SynchronizeWorkletData, + GetAudioWorkletMessagingProxyWeakPtr())); +} + +CrossThreadWeakPersistent<AudioWorkletMessagingProxy> +AudioWorkletObjectProxy::GetAudioWorkletMessagingProxyWeakPtr() { + return static_cast<AudioWorkletMessagingProxy*>( + MessagingProxyWeakPtr().Get()); +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioWorkletObjectProxy.h b/third_party/WebKit/Source/modules/webaudio/AudioWorkletObjectProxy.h new file mode 100644 index 0000000..6286710 --- /dev/null +++ b/third_party/WebKit/Source/modules/webaudio/AudioWorkletObjectProxy.h
@@ -0,0 +1,32 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef AudioWorkletObjectProxy_h +#define AudioWorkletObjectProxy_h + +#include "core/workers/ThreadedWorkletObjectProxy.h" +#include "modules/ModulesExport.h" + +namespace blink { + +class AudioWorkletMessagingProxy; + +class MODULES_EXPORT AudioWorkletObjectProxy final + : public ThreadedWorkletObjectProxy { + public: + AudioWorkletObjectProxy(AudioWorkletMessagingProxy*, + ParentFrameTaskRunners*); + + void EvaluateScript(const String& source, + const KURL& script_url, + WorkerThread*) final; + + private: + CrossThreadWeakPersistent<AudioWorkletMessagingProxy> + GetAudioWorkletMessagingProxyWeakPtr(); +}; + +} // namespace blink + +#endif // AudioWorkletObjectProxy_h
diff --git a/third_party/WebKit/Source/modules/webaudio/BUILD.gn b/third_party/WebKit/Source/modules/webaudio/BUILD.gn index 153daaf..fe0f3da4 100644 --- a/third_party/WebKit/Source/modules/webaudio/BUILD.gn +++ b/third_party/WebKit/Source/modules/webaudio/BUILD.gn
@@ -48,6 +48,8 @@ "AudioWorkletGlobalScope.h", "AudioWorkletMessagingProxy.cpp", "AudioWorkletMessagingProxy.h", + "AudioWorkletObjectProxy.cpp", + "AudioWorkletObjectProxy.h", "AudioWorkletProcessor.cpp", "AudioWorkletProcessor.h", "AudioWorkletProcessorDefinition.cpp",
diff --git a/third_party/WebKit/Source/modules/webaudio/BaseAudioContext.cpp b/third_party/WebKit/Source/modules/webaudio/BaseAudioContext.cpp index a50a9a8..bf5ac51 100644 --- a/third_party/WebKit/Source/modules/webaudio/BaseAudioContext.cpp +++ b/third_party/WebKit/Source/modules/webaudio/BaseAudioContext.cpp
@@ -89,11 +89,9 @@ return AudioContext::Create(document, context_options, exception_state); } -// FIXME(dominicc): Devolve these constructors to AudioContext -// and OfflineAudioContext respectively. - // Constructor for rendering to the audio hardware. -BaseAudioContext::BaseAudioContext(Document* document) +BaseAudioContext::BaseAudioContext(Document* document, + enum ContextType context_type) : SuspendableObject(document), destination_node_(nullptr), is_cleared_(false), @@ -109,44 +107,34 @@ periodic_wave_sawtooth_(nullptr), periodic_wave_triangle_(nullptr), output_position_() { - switch (GetAutoplayPolicy()) { - case AutoplayPolicy::Type::kNoUserGestureRequired: - break; - case AutoplayPolicy::Type::kUserGestureRequired: - case AutoplayPolicy::Type::kUserGestureRequiredForCrossOrigin: - if (document->GetFrame() && - document->GetFrame()->IsCrossOriginSubframe()) { - autoplay_status_ = AutoplayStatus::kAutoplayStatusFailed; - user_gesture_required_ = true; + switch (context_type) { + case kRealtimeContext: + switch (GetAutoplayPolicy()) { + case AutoplayPolicy::Type::kNoUserGestureRequired: + break; + case AutoplayPolicy::Type::kUserGestureRequired: + case AutoplayPolicy::Type::kUserGestureRequiredForCrossOrigin: + if (document->GetFrame() && + document->GetFrame()->IsCrossOriginSubframe()) { + autoplay_status_ = AutoplayStatus::kAutoplayStatusFailed; + user_gesture_required_ = true; + } + break; + case AutoplayPolicy::Type::kDocumentUserActivationRequired: + autoplay_status_ = AutoplayStatus::kAutoplayStatusFailed; + user_gesture_required_ = true; + break; } break; - case AutoplayPolicy::Type::kDocumentUserActivationRequired: - autoplay_status_ = AutoplayStatus::kAutoplayStatusFailed; - user_gesture_required_ = true; + case kOfflineContext: + // Nothing needed for offline context + break; + default: + NOTREACHED(); break; } } -// Constructor for offline (non-realtime) rendering. -BaseAudioContext::BaseAudioContext(Document* document, - unsigned number_of_channels, - size_t number_of_frames, - float sample_rate) - : SuspendableObject(document), - destination_node_(nullptr), - is_cleared_(false), - is_resolving_resume_promises_(false), - user_gesture_required_(false), - connection_count_(0), - deferred_task_handler_(DeferredTaskHandler::Create()), - context_state_(kSuspended), - closed_context_sample_rate_(-1), - periodic_wave_sine_(nullptr), - periodic_wave_square_(nullptr), - periodic_wave_sawtooth_(nullptr), - periodic_wave_triangle_(nullptr), - output_position_() {} - BaseAudioContext::~BaseAudioContext() { GetDeferredTaskHandler().ContextWillBeDestroyed(); // AudioNodes keep a reference to their context, so there should be no way to
diff --git a/third_party/WebKit/Source/modules/webaudio/BaseAudioContext.h b/third_party/WebKit/Source/modules/webaudio/BaseAudioContext.h index 7106bfb..c29bd10d 100644 --- a/third_party/WebKit/Source/modules/webaudio/BaseAudioContext.h +++ b/third_party/WebKit/Source/modules/webaudio/BaseAudioContext.h
@@ -334,11 +334,9 @@ void MaybeRecordStartAttempt(); protected: - explicit BaseAudioContext(Document*); - BaseAudioContext(Document*, - unsigned number_of_channels, - size_t number_of_frames, - float sample_rate); + enum ContextType { kRealtimeContext, kOfflineContext }; + + explicit BaseAudioContext(Document*, enum ContextType); void Initialize(); void Uninitialize();
diff --git a/third_party/WebKit/Source/modules/webaudio/DynamicsCompressorNode.cpp b/third_party/WebKit/Source/modules/webaudio/DynamicsCompressorNode.cpp index 031b484..680770f 100644 --- a/third_party/WebKit/Source/modules/webaudio/DynamicsCompressorNode.cpp +++ b/third_party/WebKit/Source/modules/webaudio/DynamicsCompressorNode.cpp
@@ -24,6 +24,8 @@ */ #include "modules/webaudio/DynamicsCompressorNode.h" +#include "bindings/core/v8/ExceptionMessages.h" +#include "bindings/core/v8/ExceptionState.h" #include "modules/webaudio/AudioNodeInput.h" #include "modules/webaudio/AudioNodeOutput.h" #include "modules/webaudio/DynamicsCompressorOptions.h" @@ -133,6 +135,55 @@ return dynamics_compressor_->LatencyTime(); } +void DynamicsCompressorHandler::SetChannelCount( + unsigned long channel_count, + ExceptionState& exception_state) { + DCHECK(IsMainThread()); + BaseAudioContext::AutoLocker locker(Context()); + + // A DynamicsCompressorNode only supports 1 or 2 channels + if (channel_count > 0 && channel_count <= 2) { + if (channel_count_ != channel_count) { + channel_count_ = channel_count; + if (InternalChannelCountMode() != kMax) + UpdateChannelsForInputs(); + } + } else { + exception_state.ThrowDOMException( + kNotSupportedError, ExceptionMessages::IndexOutsideRange<unsigned long>( + "channelCount", channel_count, 1, + ExceptionMessages::kInclusiveBound, 2, + ExceptionMessages::kInclusiveBound)); + } +} + +void DynamicsCompressorHandler::SetChannelCountMode( + const String& mode, + ExceptionState& exception_state) { + DCHECK(IsMainThread()); + BaseAudioContext::AutoLocker locker(Context()); + + ChannelCountMode old_mode = InternalChannelCountMode(); + + if (mode == "clamped-max") { + new_channel_count_mode_ = kClampedMax; + } else if (mode == "explicit") { + new_channel_count_mode_ = kExplicit; + } else if (mode == "max") { + // This is not supported for a DynamicsCompressorNode, which can + // only handle 1 or 2 channels. + exception_state.ThrowDOMException(kNotSupportedError, + "The provided value 'max' is not an " + "allowed value for ChannelCountMode"); + new_channel_count_mode_ = old_mode; + } else { + // Do nothing for other invalid values. + new_channel_count_mode_ = old_mode; + } + + if (new_channel_count_mode_ != old_mode) + Context()->GetDeferredTaskHandler().AddChangedChannelCountMode(this); +} // ---------------------------------------------------------------- DynamicsCompressorNode::DynamicsCompressorNode(BaseAudioContext& context)
diff --git a/third_party/WebKit/Source/modules/webaudio/DynamicsCompressorNode.h b/third_party/WebKit/Source/modules/webaudio/DynamicsCompressorNode.h index f488178..73eb91f 100644 --- a/third_party/WebKit/Source/modules/webaudio/DynamicsCompressorNode.h +++ b/third_party/WebKit/Source/modules/webaudio/DynamicsCompressorNode.h
@@ -59,6 +59,9 @@ float ReductionValue() const { return reduction_; } + void SetChannelCount(unsigned long, ExceptionState&) final; + void SetChannelCountMode(const String&, ExceptionState&) final; + private: DynamicsCompressorHandler(AudioNode&, float sample_rate,
diff --git a/third_party/WebKit/Source/modules/webaudio/OfflineAudioContext.cpp b/third_party/WebKit/Source/modules/webaudio/OfflineAudioContext.cpp index 3fcb847..58dae0ef 100644 --- a/third_party/WebKit/Source/modules/webaudio/OfflineAudioContext.cpp +++ b/third_party/WebKit/Source/modules/webaudio/OfflineAudioContext.cpp
@@ -136,10 +136,7 @@ size_t number_of_frames, float sample_rate, ExceptionState& exception_state) - : BaseAudioContext(document, - number_of_channels, - number_of_frames, - sample_rate), + : BaseAudioContext(document, kOfflineContext), is_rendering_started_(false), total_render_frames_(number_of_frames) { destination_node_ = OfflineAudioDestinationNode::Create(
diff --git a/third_party/WebKit/Source/platform/DragImageTest.cpp b/third_party/WebKit/Source/platform/DragImageTest.cpp index 807d0807..d48738c 100644 --- a/third_party/WebKit/Source/platform/DragImageTest.cpp +++ b/third_party/WebKit/Source/platform/DragImageTest.cpp
@@ -82,11 +82,14 @@ // Image pure virtual stub. } - private: - void PopulateImageForCurrentFrame(PaintImageBuilder& builder) override { + PaintImage PaintImageForCurrentFrame() override { + PaintImageBuilder builder; + InitPaintImageBuilder(builder); builder.set_image(image_); + return builder.TakePaintImage(); } + private: explicit TestImage(sk_sp<SkImage> image) : image_(image) {} explicit TestImage(IntSize size) : image_(nullptr) {
diff --git a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5 b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5 index feca85c..892dc7d 100644 --- a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5 +++ b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5
@@ -1048,7 +1048,7 @@ }, { name: "UpdateHoverPostLayout", - status: "experimental", + status: "stable", }, { name: "V8IdleTasks",
diff --git a/third_party/WebKit/Source/platform/graphics/AcceleratedStaticBitmapImage.cpp b/third_party/WebKit/Source/platform/graphics/AcceleratedStaticBitmapImage.cpp index eedcbe9..3d920d11 100644 --- a/third_party/WebKit/Source/platform/graphics/AcceleratedStaticBitmapImage.cpp +++ b/third_party/WebKit/Source/platform/graphics/AcceleratedStaticBitmapImage.cpp
@@ -153,17 +153,19 @@ dest_gl->DeleteTextures(1, &source_texture_id); } -void AcceleratedStaticBitmapImage::PopulateImageForCurrentFrame( - PaintImageBuilder& builder) { +PaintImage AcceleratedStaticBitmapImage::PaintImageForCurrentFrame() { // TODO(ccameron): This function should not ignore |colorBehavior|. // https://crbug.com/672306 CheckThread(); if (!IsValid()) { - builder.set_image(nullptr); - return; + return PaintImage(); } CreateImageFromMailboxIfNeeded(); + + PaintImageBuilder builder; + InitPaintImageBuilder(builder); builder.set_image(texture_holder_->GetSkImage()); + return builder.TakePaintImage(); } void AcceleratedStaticBitmapImage::Draw(PaintCanvas* canvas,
diff --git a/third_party/WebKit/Source/platform/graphics/AcceleratedStaticBitmapImage.h b/third_party/WebKit/Source/platform/graphics/AcceleratedStaticBitmapImage.h index 5346a62..fda686f 100644 --- a/third_party/WebKit/Source/platform/graphics/AcceleratedStaticBitmapImage.h +++ b/third_party/WebKit/Source/platform/graphics/AcceleratedStaticBitmapImage.h
@@ -77,8 +77,7 @@ // was a snapshot of an SkSurface that may be rendered to after void RetainOriginalSkImageForCopyOnWrite(); - protected: - void PopulateImageForCurrentFrame(PaintImageBuilder&) override; + PaintImage PaintImageForCurrentFrame() override; private: AcceleratedStaticBitmapImage(sk_sp<SkImage>,
diff --git a/third_party/WebKit/Source/platform/graphics/BitmapImage.cpp b/third_party/WebKit/Source/platform/graphics/BitmapImage.cpp index efda67c..31e2194a 100644 --- a/third_party/WebKit/Source/platform/graphics/BitmapImage.cpp +++ b/third_party/WebKit/Source/platform/graphics/BitmapImage.cpp
@@ -76,7 +76,7 @@ } void BitmapImage::DestroyDecodedData() { - cached_frame_.reset(); + cached_frame_ = PaintImage(); for (size_t i = 0; i < frames_.size(); ++i) frames_[i].Clear(true); source_.ClearCacheExceptFrame(kNotFound); @@ -100,17 +100,15 @@ return total_bytes; } -sk_sp<PaintImageGenerator> BitmapImage::CreateAndCacheFrameGenerator( - size_t index) { +PaintImage BitmapImage::CreateAndCacheFrame(size_t index) { + sk_sp<PaintImageGenerator> generator = source_.CreateGeneratorAtIndex(index); + if (!generator) + return PaintImage(); + size_t num_frames = FrameCount(); if (frames_.size() < num_frames) frames_.Grow(num_frames); - // We are caching frame snapshots. This is OK even for partially decoded - // frames, as they are cleared by dataChanged() when new data arrives. - cached_frame_ = source_.CreateGeneratorAtIndex(index); - cached_frame_index_ = index; - frames_[index].orientation_ = source_.OrientationAtIndex(index); frames_[index].have_metadata_ = true; frames_[index].is_complete_ = source_.FrameIsReceivedAtIndex(index); @@ -119,6 +117,48 @@ frames_[index].has_alpha_ = source_.FrameHasAlphaAtIndex(index); frames_[index].frame_bytes_ = source_.FrameBytesAtIndex(index); + PaintImageBuilder builder; + InitPaintImageBuilder(builder); + + // The caching of the decoded image data by the external users of this image + // is keyed based on the uniqueID of the underlying SkImage for this + // PaintImage. For this reason once the decoded output of an image becomes + // constant, we want use the same uniqueID for repeated calls to create a + // PaintImage. + // The decoded bitmap for a PaintImage can be considered constant in the + // following cases: + // 1) Once all data for this image has been received, each frame of the image + // is constant. + // 2) For multi-frame images, each frame represents a unique constant bitmap + // once all data for that frame has been received. + // + // TODO(khushalsagar): This reliance on SkImage ids should be removed once cc + // is responsible for decoding all images and can rely on inputs provided in + // PaintImage/PaintImageGenerator. See crbug.com/753639. + const bool frame_complete = all_data_received_ || frames_[index].is_complete_; + if (frames_[index].sk_image_unique_id_ != + SkiaPaintImageGenerator::kNeedNewImageUniqueID) { + // If the id was previously set, the frame must be complete. Continue using + // the same id. + DCHECK(frame_complete); + builder.set_paint_image_generator(std::move(generator), + frames_[index].sk_image_unique_id_); + } else if (frame_complete) { + // If this is the first time we have encountered a complete frame when + // creating a PaintImage, store the generated uniqueID to reuse later. + builder.set_paint_image_generator( + std::move(generator), SkiaPaintImageGenerator::kNeedNewImageUniqueID, + &frames_[index].sk_image_unique_id_); + } else { + // Continue generating new ids for partial decodes of this image. + builder.set_paint_image_generator(std::move(generator)); + } + + // We are caching frame snapshots. This is OK even for partially decoded + // frames, as they are cleared by dataChanged() when new data arrives. + cached_frame_ = builder.TakePaintImage(); + cached_frame_index_ = index; + NotifyMemoryChanged(); return cached_frame_; } @@ -191,7 +231,7 @@ if (frames_[i].have_metadata_ && !frames_[i].is_complete_) { frames_[i].Clear(true); if (i == cached_frame_index_) - cached_frame_.reset(); + cached_frame_ = PaintImage(); } } @@ -298,14 +338,14 @@ return size_available_; } -sk_sp<PaintImageGenerator> BitmapImage::FrameAtIndex(size_t index) { +PaintImage BitmapImage::FrameAtIndex(size_t index) { if (index >= FrameCount()) - return nullptr; + return PaintImage(); if (index == cached_frame_index_ && cached_frame_) return cached_frame_; - return CreateAndCacheFrameGenerator(index); + return CreateAndCacheFrame(index); } bool BitmapImage::FrameIsReceivedAtIndex(size_t index) const { @@ -323,53 +363,13 @@ return source_.FrameDurationAtIndex(index); } -void BitmapImage::PopulateImageForCurrentFrame(PaintImageBuilder& builder) { - size_t index = current_frame_index_; - sk_sp<PaintImageGenerator> generator = FrameAtIndex(index); - if (!generator) - return; - - // The caching of the decoded image data by the external users of this image - // is keyed based on the uniqueID of the underlying SkImage for this - // PaintImage. For this reason once the decoded output of an image becomes - // constant, we want use the same uniqueID for repeated calls to create a - // PaintImage. - // The decoded bitmap for a PaintImage can be considered constant in the - // following cases: - // 1) Once all data for this image has been received, each frame of the image - // is constant. - // 2) For multi-frame images, each frame represents a unique constant bitmap - // once all data for that frame has been received. - // - // TODO(khushalsagar): This reliance on SkImage ids should be removed once cc - // is responsible for decoding all images and can rely on inputs provided in - // PaintImage/PaintImageGenerator. See crbug.com/753639. - const bool frame_complete = all_data_received_ || frames_[index].is_complete_; - if (frames_[index].sk_image_unique_id_ != - SkiaPaintImageGenerator::kNeedNewImageUniqueID) { - // If the id was previously set, the frame must be complete. Continue using - // the same id. - DCHECK(frame_complete); - builder.set_paint_image_generator(std::move(generator), - frames_[index].sk_image_unique_id_); - } else if (frame_complete) { - // If this is the first time we have encountered a complete frame when - // creating a PaintImage, store the generated uniqueID to reuse later. - builder.set_paint_image_generator( - std::move(generator), SkiaPaintImageGenerator::kNeedNewImageUniqueID, - &frames_[index].sk_image_unique_id_); - } else { - // Continue generating new ids for partial decodes of this image. - builder.set_paint_image_generator(std::move(generator)); - } +PaintImage BitmapImage::PaintImageForCurrentFrame() { + return FrameAtIndex(current_frame_index_); } PassRefPtr<Image> BitmapImage::ImageForDefaultFrame() { if (FrameCount() > 1) { - sk_sp<SkImage> first_frame = SkImage::MakeFromGenerator( - base::MakeUnique<SkiaPaintImageGenerator>(FrameAtIndex(0))); - if (first_frame) - return StaticBitmapImage::Create(std::move(first_frame)); + return StaticBitmapImage::Create(FrameAtIndex(0u)); } return Image::ImageForDefaultFrame(); @@ -553,7 +553,7 @@ repetitions_complete_ = 0; desired_frame_start_time_ = 0; animation_finished_ = false; - cached_frame_.reset(); + cached_frame_ = PaintImage(); } bool BitmapImage::MaybeAnimated() {
diff --git a/third_party/WebKit/Source/platform/graphics/BitmapImage.h b/third_party/WebKit/Source/platform/graphics/BitmapImage.h index 213b11f..09535d8 100644 --- a/third_party/WebKit/Source/platform/graphics/BitmapImage.h +++ b/third_party/WebKit/Source/platform/graphics/BitmapImage.h
@@ -95,8 +95,7 @@ // Advance the image animation by one frame. void AdvanceAnimationForTesting() override { InternalAdvanceAnimation(); } - protected: - void PopulateImageForCurrentFrame(PaintImageBuilder&) override; + PaintImage PaintImageForCurrentFrame() override; private: enum RepetitionCountStatus : uint8_t { @@ -117,14 +116,14 @@ RespectImageOrientationEnum, ImageClampingMode) override; - sk_sp<PaintImageGenerator> FrameAtIndex(size_t); + PaintImage FrameAtIndex(size_t); bool FrameIsReceivedAtIndex(size_t) const; float FrameDurationAtIndex(size_t) const; bool FrameHasAlphaAtIndex(size_t); ImageOrientation FrameOrientationAtIndex(size_t); - sk_sp<PaintImageGenerator> CreateAndCacheFrameGenerator(size_t index); + PaintImage CreateAndCacheFrame(size_t index); void UpdateSize() const; // Returns the total number of bytes allocated for all framebuffers, i.e. @@ -185,7 +184,7 @@ // animation. We have to ref frames to pin // them in the cache. - sk_sp<PaintImageGenerator> + PaintImage cached_frame_; // A cached copy of the most recently-accessed frame. size_t cached_frame_index_; // Index of the frame that is cached.
diff --git a/third_party/WebKit/Source/platform/graphics/BitmapImageTest.cpp b/third_party/WebKit/Source/platform/graphics/BitmapImageTest.cpp index 75dee289..cbea42a 100644 --- a/third_party/WebKit/Source/platform/graphics/BitmapImageTest.cpp +++ b/third_party/WebKit/Source/platform/graphics/BitmapImageTest.cpp
@@ -257,6 +257,66 @@ EXPECT_EQ(0, LastDecodedSizeChange()); } +TEST_F(BitmapImageTest, ConstantSkImageIdForPartiallyLoadedImages) { + RefPtr<SharedBuffer> image_data = + ReadFile("/LayoutTests/images/resources/green.jpg"); + ASSERT_TRUE(image_data.Get()); + + // Create a new buffer to partially supply the data. + RefPtr<SharedBuffer> partial_buffer = SharedBuffer::Create(); + partial_buffer->Append(image_data->Data(), image_data->size() - 4); + + // First partial load. Repeated calls for a PaintImage should have the same + // image until the data changes or the decoded data is destroyed. + ASSERT_EQ(image_->SetData(partial_buffer, false), Image::kSizeAvailable); + auto sk_image1 = image_->PaintImageForCurrentFrame().GetSkImage(); + auto sk_image2 = image_->PaintImageForCurrentFrame().GetSkImage(); + EXPECT_EQ(sk_image1, sk_image2); + + // Destroy the decoded data. This generates a new id since we don't cache + // image ids for partial decodes. + DestroyDecodedData(); + auto sk_image3 = image_->PaintImageForCurrentFrame().GetSkImage(); + EXPECT_NE(sk_image1, sk_image3); + EXPECT_NE(sk_image1->uniqueID(), sk_image3->uniqueID()); + + // Load complete. This should generate a new image id. + image_->SetData(image_data, true); + auto complete_image = image_->PaintImageForCurrentFrame().GetSkImage(); + EXPECT_NE(sk_image3, complete_image); + EXPECT_NE(sk_image3->uniqueID(), complete_image->uniqueID()); + + // Destroy the decoded data and re-create the PaintImage. The SkImage id used + // should remain consistent, even if a new image is created. + DestroyDecodedData(); + auto new_complete_image = image_->PaintImageForCurrentFrame().GetSkImage(); + EXPECT_NE(new_complete_image, complete_image); + EXPECT_EQ(new_complete_image->uniqueID(), complete_image->uniqueID()); +} + +TEST_F(BitmapImageTest, ImageForDefaultFrame_MultiFrame) { + LoadImage("/LayoutTests/images/resources/anim_none.gif", false); + + // Multi-frame images create new StaticBitmapImages for each call. + auto default_image1 = image_->ImageForDefaultFrame(); + auto default_image2 = image_->ImageForDefaultFrame(); + EXPECT_NE(default_image1, default_image2); + + // But the PaintImage should be the same. + auto paint_image1 = default_image1->PaintImageForCurrentFrame(); + auto paint_image2 = default_image2->PaintImageForCurrentFrame(); + EXPECT_EQ(paint_image1, paint_image2); + EXPECT_EQ(paint_image1.GetSkImage()->uniqueID(), + paint_image2.GetSkImage()->uniqueID()); +} + +TEST_F(BitmapImageTest, ImageForDefaultFrame_SingleFrame) { + LoadImage("/LayoutTests/images/resources/green.jpg"); + + // Default frame images for single-frame cases is the image itself. + EXPECT_EQ(image_->ImageForDefaultFrame(), image_); +} + template <typename HistogramEnumType> struct HistogramTestParams { const char* filename;
diff --git a/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.cpp b/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.cpp index f7b3175..d0f8478 100644 --- a/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.cpp +++ b/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.cpp
@@ -105,7 +105,6 @@ gr_context->resetContext(kTextureBinding_GrGLBackendState); } -#if USE_IOSURFACE_FOR_2D_CANVAS // Releases all resources associated with a CHROMIUM image. static void DeleteCHROMIUMImage( WeakPtr<blink::WebGraphicsContext3DProviderWrapper> @@ -130,13 +129,11 @@ ResetSkiaTextureBinding(context_provider_wrapper); } } -#endif // USE_IOSURFACE_FOR_2D_CANVAS } // namespace namespace blink { -#if USE_IOSURFACE_FOR_2D_CANVAS struct Canvas2DLayerBridge::ImageInfo : public RefCounted<ImageInfo> { ImageInfo(std::unique_ptr<gfx::GpuMemoryBuffer>, GLuint image_id, @@ -152,7 +149,6 @@ // The id of the texture bound to the CHROMIUM image. const GLuint texture_id_; }; -#endif // USE_IOSURFACE_FOR_2D_CANVAS static sk_sp<SkSurface> CreateSkSurface(GrContext* gr, const IntSize& size, @@ -243,9 +239,8 @@ Canvas2DLayerBridge::~Canvas2DLayerBridge() { BeginDestruction(); DCHECK(destruction_in_progress_); -#if USE_IOSURFACE_FOR_2D_CANVAS - ClearCHROMIUMImageCache(); -#endif // USE_IOSURFACE_FOR_2D_CANVAS + if (RuntimeEnabledFeatures::Canvas2dImageChromiumEnabled()) + ClearCHROMIUMImageCache(); layer_.reset(); } @@ -325,7 +320,6 @@ return filter_quality_ == kNone_SkFilterQuality ? GL_NEAREST : GL_LINEAR; } -#if USE_IOSURFACE_FOR_2D_CANVAS bool Canvas2DLayerBridge::PrepareIOSurfaceMailboxFromImage( SkImage* image, MailboxInfo* info, @@ -439,7 +433,6 @@ } image_info_cache_.clear(); } -#endif // USE_IOSURFACE_FOR_2D_CANVAS bool Canvas2DLayerBridge::PrepareMailboxFromImage( sk_sp<SkImage> image, @@ -456,7 +449,6 @@ return true; } -#if USE_IOSURFACE_FOR_2D_CANVAS if (RuntimeEnabledFeatures::Canvas2dImageChromiumEnabled()) { if (PrepareIOSurfaceMailboxFromImage(image.get(), mailbox_info, out_mailbox)) @@ -464,7 +456,6 @@ // Note: if IOSurface backed texture creation failed we fall back to the // non-IOSurface path. } -#endif // USE_IOSURFACE_FOR_2D_CANVAS mailbox_info->image_ = std::move(image); @@ -590,9 +581,8 @@ hibernation_image_ = temp_hibernation_surface->makeImageSnapshot(); ResetSurface(); layer_->ClearTexture(); -#if USE_IOSURFACE_FOR_2D_CANVAS - ClearCHROMIUMImageCache(); -#endif // USE_IOSURFACE_FOR_2D_CANVAS + if (RuntimeEnabledFeatures::Canvas2dImageChromiumEnabled()) + ClearCHROMIUMImageCache(); // shouldBeDirectComposited() may have changed. if (image_buffer_) image_buffer_->SetNeedsCompositingUpdate(); @@ -1064,25 +1054,24 @@ ->GetGraphicsResetStatusKHR() != GL_NO_ERROR); } -#if USE_IOSURFACE_FOR_2D_CANVAS - RefPtr<ImageInfo> info = released_mailbox_info->image_info_; - if (info && !lost_resource) { - if (context_or_layer_bridge_lost) { - DeleteCHROMIUMImage(context_provider_wrapper, - std::move(info->gpu_memory_buffer_), info->image_id_, - info->texture_id_); - } else { - layer_bridge->image_info_cache_.push_back(info); + if (RuntimeEnabledFeatures::Canvas2dImageChromiumEnabled()) { + RefPtr<ImageInfo> info = released_mailbox_info->image_info_; + if (info && !lost_resource) { + if (context_or_layer_bridge_lost) { + DeleteCHROMIUMImage(context_provider_wrapper, + std::move(info->gpu_memory_buffer_), + info->image_id_, info->texture_id_); + } else { + layer_bridge->image_info_cache_.push_back(info); + } } } -#endif // USE_IOSURFACE_FOR_2D_CANVAS // Invalidate texture state in case the compositor altered it since the // copy-on-write. if (released_mailbox_info->image_) { -#if USE_IOSURFACE_FOR_2D_CANVAS - DCHECK(!released_mailbox_info->image_info_); -#endif // USE_IOSURFACE_FOR_2D_CANVAS + if (RuntimeEnabledFeatures::Canvas2dImageChromiumEnabled()) + DCHECK(!released_mailbox_info->image_info_); bool layer_bridge_with_valid_context = layer_bridge && !context_or_layer_bridge_lost; if (layer_bridge_with_valid_context || !layer_bridge) { @@ -1180,7 +1169,6 @@ SkipQueuedDrawCommands(); } -#if USE_IOSURFACE_FOR_2D_CANVAS Canvas2DLayerBridge::ImageInfo::ImageInfo( std::unique_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer, GLuint image_id, @@ -1194,7 +1182,6 @@ } Canvas2DLayerBridge::ImageInfo::~ImageInfo() {} -#endif // USE_IOSURFACE_FOR_2D_CANVAS Canvas2DLayerBridge::MailboxInfo::MailboxInfo() = default; Canvas2DLayerBridge::MailboxInfo::MailboxInfo(const MailboxInfo& other) =
diff --git a/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.h b/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.h index 0c6df98..d4dbee5c 100644 --- a/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.h +++ b/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.h
@@ -66,20 +66,15 @@ // Canvas hibernation is currently disabled on MacOS X due to a bug that causes // content loss. TODO: Find a better fix for crbug.com/588434 #define CANVAS2D_HIBERNATION_ENABLED 0 - -// IOSurfaces are a primitive only present on OS X. -#define USE_IOSURFACE_FOR_2D_CANVAS 1 #else #define CANVAS2D_HIBERNATION_ENABLED 1 -#define USE_IOSURFACE_FOR_2D_CANVAS 0 #endif // TODO: Fix background rendering and remove this workaround. crbug.com/600386 #define CANVAS2D_BACKGROUND_RENDER_SWITCH_TO_CPU 0 -class PLATFORM_EXPORT Canvas2DLayerBridge - : public NON_EXPORTED_BASE(cc::TextureLayerClient), - public ImageBufferSurface { +class PLATFORM_EXPORT Canvas2DLayerBridge : public cc::TextureLayerClient, + public ImageBufferSurface { WTF_MAKE_NONCOPYABLE(Canvas2DLayerBridge); public: @@ -174,20 +169,16 @@ void FlushInternal(); void FlushGpuInternal(); -#if USE_IOSURFACE_FOR_2D_CANVAS // All information associated with a CHROMIUM image. struct ImageInfo; -#endif // USE_IOSURFACE_FOR_2D_CANVAS struct MailboxInfo { gpu::Mailbox mailbox_; sk_sp<SkImage> image_; -#if USE_IOSURFACE_FOR_2D_CANVAS // If this mailbox wraps an IOSurface-backed texture, the ids of the // CHROMIUM image and the texture. RefPtr<ImageInfo> image_info_; -#endif // USE_IOSURFACE_FOR_2D_CANVAS MailboxInfo(const MailboxInfo&); MailboxInfo(); @@ -214,7 +205,6 @@ // Returns the GL filter associated with |m_filterQuality|. GLenum GetGLFilter(); -#if USE_IOSURFACE_FOR_2D_CANVAS // Creates an IOSurface-backed texture. Copies |image| into the texture. // Prepares a mailbox from the texture. The caller must have created a new // MailboxInfo, and prepended it to |m_mailboxs|. Returns whether the @@ -230,7 +220,6 @@ // Releases all resources in the CHROMIUM image cache. void ClearCHROMIUMImageCache(); -#endif // USE_IOSURFACE_FOR_2D_CANVAS // Returns whether the mailbox was successfully prepared from the SkImage. // The mailbox is an out parameter only populated on success. @@ -282,12 +271,10 @@ CanvasColorParams color_params_; int recording_pixel_count_; -#if USE_IOSURFACE_FOR_2D_CANVAS // Each element in this vector represents an IOSurface backed texture that // is ready to be reused. // Elements in this vector can safely be purged in low memory conditions. Vector<RefPtr<ImageInfo>> image_info_cache_; -#endif // USE_IOSURFACE_FOR_2D_CANVAS }; } // namespace blink
diff --git a/third_party/WebKit/Source/platform/graphics/DeferredImageDecoderTest.cpp b/third_party/WebKit/Source/platform/graphics/DeferredImageDecoderTest.cpp index e4b8345..eb6dd8c 100644 --- a/third_party/WebKit/Source/platform/graphics/DeferredImageDecoderTest.cpp +++ b/third_party/WebKit/Source/platform/graphics/DeferredImageDecoderTest.cpp
@@ -134,14 +134,21 @@ IntSize DecodedSize() const override { return decoded_size_; } - sk_sp<SkImage> CreateFrameAtIndex(size_t index) { - return CreateFrameAtIndex(lazy_decoder_.get(), index); + PaintImage CreatePaintImageAtIndex( + size_t index, + PaintImage::CompletionState state = PaintImage::CompletionState::DONE) { + return CreatePaintImageAtIndex(lazy_decoder_.get(), index, state); } - sk_sp<SkImage> CreateFrameAtIndex(DeferredImageDecoder* decoder, - size_t index) { - return SkImage::MakeFromGenerator(base::MakeUnique<SkiaPaintImageGenerator>( - decoder->CreateGeneratorAtIndex(index))); + PaintImage CreatePaintImageAtIndex( + DeferredImageDecoder* decoder, + size_t index, + PaintImage::CompletionState state = PaintImage::CompletionState::DONE) { + return PaintImageBuilder() + .set_id(PaintImage::GetNextId()) + .set_completion_state(state) + .set_paint_image_generator(decoder->CreateGeneratorAtIndex(index)) + .TakePaintImage(); } protected: @@ -166,18 +173,14 @@ TEST_F(DeferredImageDecoderTest, drawIntoPaintRecord) { lazy_decoder_->SetData(data_, true); - sk_sp<SkImage> image = CreateFrameAtIndex(0); + PaintImage image = CreatePaintImageAtIndex(0); ASSERT_TRUE(image); - EXPECT_EQ(1, image->width()); - EXPECT_EQ(1, image->height()); + EXPECT_EQ(1, image.width()); + EXPECT_EQ(1, image.height()); PaintRecorder recorder; PaintCanvas* temp_canvas = recorder.beginRecording(100, 100); - temp_canvas->drawImage(PaintImageBuilder() - .set_id(PaintImage::GetNextId()) - .set_image(std::move(image)) - .TakePaintImage(), - 0, 0); + temp_canvas->drawImage(image, 0, 0); sk_sp<PaintRecord> record = recorder.finishRecordingAsPicture(); EXPECT_EQ(0, decode_request_count_); @@ -192,30 +195,19 @@ // Received only half the file. lazy_decoder_->SetData(partial_data, false); - sk_sp<SkImage> image = CreateFrameAtIndex(0); - ASSERT_TRUE(image); PaintRecorder recorder; PaintCanvas* temp_canvas = recorder.beginRecording(100, 100); - PaintImage::Id stable_id = PaintImage::GetNextId(); - temp_canvas->drawImage( - PaintImageBuilder() - .set_id(stable_id) - .set_image(std::move(image)) - .set_completion_state(PaintImage::CompletionState::PARTIALLY_DONE) - .TakePaintImage(), - 0, 0); + PaintImage image = + CreatePaintImageAtIndex(0, PaintImage::CompletionState::PARTIALLY_DONE); + temp_canvas->drawImage(image, 0, 0); canvas_->drawPicture(recorder.finishRecordingAsPicture()); // Fully received the file and draw the PaintRecord again. lazy_decoder_->SetData(data_, true); - image = CreateFrameAtIndex(0); + image = CreatePaintImageAtIndex(0); ASSERT_TRUE(image); temp_canvas = recorder.beginRecording(100, 100); - temp_canvas->drawImage(PaintImageBuilder() - .set_id(stable_id) - .set_image(std::move(image)) - .TakePaintImage(), - 0, 0); + temp_canvas->drawImage(image, 0, 0); canvas_->drawPicture(recorder.finishRecordingAsPicture()); EXPECT_EQ(SkColorSetARGB(255, 255, 255, 255), bitmap_.getColor(0, 0)); } @@ -226,18 +218,14 @@ TEST_F(DeferredImageDecoderTest, decodeOnOtherThread) { lazy_decoder_->SetData(data_, true); - sk_sp<SkImage> image = CreateFrameAtIndex(0); + PaintImage image = CreatePaintImageAtIndex(0); ASSERT_TRUE(image); - EXPECT_EQ(1, image->width()); - EXPECT_EQ(1, image->height()); + EXPECT_EQ(1, image.width()); + EXPECT_EQ(1, image.height()); PaintRecorder recorder; PaintCanvas* temp_canvas = recorder.beginRecording(100, 100); - temp_canvas->drawImage(PaintImageBuilder() - .set_id(PaintImage::GetNextId()) - .set_image(std::move(image)) - .TakePaintImage(), - 0, 0); + temp_canvas->drawImage(image, 0, 0); sk_sp<PaintRecord> record = recorder.finishRecordingAsPicture(); EXPECT_EQ(0, decode_request_count_); @@ -257,9 +245,8 @@ status_ = ImageFrame::kFramePartial; lazy_decoder_->SetData(data_, false); EXPECT_FALSE(lazy_decoder_->FrameIsReceivedAtIndex(0)); - sk_sp<SkImage> image = CreateFrameAtIndex(0); + PaintImage image = CreatePaintImageAtIndex(0); ASSERT_TRUE(image); - unsigned first_id = image->uniqueID(); EXPECT_FALSE(lazy_decoder_->FrameIsReceivedAtIndex(0)); EXPECT_TRUE(actual_decoder_); @@ -269,11 +256,9 @@ EXPECT_FALSE(actual_decoder_); EXPECT_TRUE(lazy_decoder_->FrameIsReceivedAtIndex(0)); - image = CreateFrameAtIndex(0); + image = CreatePaintImageAtIndex(0); ASSERT_TRUE(image); - unsigned second_id = image->uniqueID(); EXPECT_FALSE(decode_request_count_); - EXPECT_NE(first_id, second_id); } TEST_F(DeferredImageDecoderTest, multiFrameImageLoading) { @@ -283,9 +268,8 @@ status_ = ImageFrame::kFramePartial; lazy_decoder_->SetData(data_, false); - sk_sp<SkImage> image = CreateFrameAtIndex(0); + PaintImage image = CreatePaintImageAtIndex(0); ASSERT_TRUE(image); - unsigned first_id = image->uniqueID(); EXPECT_FALSE(lazy_decoder_->FrameIsReceivedAtIndex(0)); EXPECT_EQ(10.0f, lazy_decoder_->FrameDurationAtIndex(0)); @@ -295,10 +279,8 @@ data_->Append(" ", 1u); lazy_decoder_->SetData(data_, false); - image = CreateFrameAtIndex(0); + image = CreatePaintImageAtIndex(0); ASSERT_TRUE(image); - unsigned second_id = image->uniqueID(); - EXPECT_NE(first_id, second_id); EXPECT_TRUE(lazy_decoder_->FrameIsReceivedAtIndex(0)); EXPECT_TRUE(lazy_decoder_->FrameIsReceivedAtIndex(1)); EXPECT_EQ(20.0f, lazy_decoder_->FrameDurationAtIndex(1)); @@ -321,21 +303,17 @@ TEST_F(DeferredImageDecoderTest, decodedSize) { decoded_size_ = IntSize(22, 33); lazy_decoder_->SetData(data_, true); - sk_sp<SkImage> image = CreateFrameAtIndex(0); + PaintImage image = CreatePaintImageAtIndex(0); ASSERT_TRUE(image); - EXPECT_EQ(decoded_size_.Width(), image->width()); - EXPECT_EQ(decoded_size_.Height(), image->height()); + EXPECT_EQ(decoded_size_.Width(), image.width()); + EXPECT_EQ(decoded_size_.Height(), image.height()); UseMockImageDecoderFactory(); // The following code should not fail any assert. PaintRecorder recorder; PaintCanvas* temp_canvas = recorder.beginRecording(100, 100); - temp_canvas->drawImage(PaintImageBuilder() - .set_id(PaintImage::GetNextId()) - .set_image(std::move(image)) - .TakePaintImage(), - 0, 0); + temp_canvas->drawImage(image, 0, 0); sk_sp<PaintRecord> record = recorder.finishRecordingAsPicture(); EXPECT_EQ(0, decode_request_count_); canvas_->drawPicture(record); @@ -373,7 +351,8 @@ SkPixmap pixmap(pix_info, storage.data(), row_bytes); // Before decoding, the frame is not known to be opaque. - sk_sp<SkImage> frame = CreateFrameAtIndex(decoder.get(), 0); + sk_sp<SkImage> frame = + CreatePaintImageAtIndex(decoder.get(), 0).GetSkImage(); ASSERT_TRUE(frame); EXPECT_FALSE(frame->isOpaque()); @@ -381,7 +360,7 @@ EXPECT_TRUE(frame->readPixels(pixmap, 0, 0)); // After decoding, the frame is known to be opaque. - frame = CreateFrameAtIndex(decoder.get(), 0); + frame = CreatePaintImageAtIndex(decoder.get(), 0).GetSkImage(); ASSERT_TRUE(frame); EXPECT_TRUE(frame->isOpaque()); @@ -399,8 +378,8 @@ frame_count_ = 2; ForceFirstFrameToBeEmpty(); lazy_decoder_->SetData(data_, false); - CreateFrameAtIndex(0); - CreateFrameAtIndex(1); + CreatePaintImageAtIndex(0); + CreatePaintImageAtIndex(1); lazy_decoder_->SetData(data_, true); // Clears only the first frame (0 bytes). If DeferredImageDecoder doesn't // check with the actual decoder it reports 4 bytes instead.
diff --git a/third_party/WebKit/Source/platform/graphics/GeneratedImage.cpp b/third_party/WebKit/Source/platform/graphics/GeneratedImage.cpp index 39b2a42..f5ac8f1 100644 --- a/third_party/WebKit/Source/platform/graphics/GeneratedImage.cpp +++ b/third_party/WebKit/Source/platform/graphics/GeneratedImage.cpp
@@ -69,8 +69,8 @@ dest_context.DrawRect(dest_rect, fill_flags); } -void GeneratedImage::PopulateImageForCurrentFrame(PaintImageBuilder& builder) { - builder.set_image(nullptr); +PaintImage GeneratedImage::PaintImageForCurrentFrame() { + return PaintImage(); } } // namespace blink
diff --git a/third_party/WebKit/Source/platform/graphics/GeneratedImage.h b/third_party/WebKit/Source/platform/graphics/GeneratedImage.h index a6720d94..bf806d19 100644 --- a/third_party/WebKit/Source/platform/graphics/GeneratedImage.h +++ b/third_party/WebKit/Source/platform/graphics/GeneratedImage.h
@@ -44,9 +44,9 @@ // Assume that generated content has no decoded data we need to worry about void DestroyDecodedData() override {} - protected: - void PopulateImageForCurrentFrame(PaintImageBuilder&) override; + PaintImage PaintImageForCurrentFrame() override; + protected: void DrawPattern(GraphicsContext&, const FloatRect&, const FloatSize&,
diff --git a/third_party/WebKit/Source/platform/graphics/GraphicsLayer.cpp b/third_party/WebKit/Source/platform/graphics/GraphicsLayer.cpp index 7a501d2..4ff6e77 100644 --- a/third_party/WebKit/Source/platform/graphics/GraphicsLayer.cpp +++ b/third_party/WebKit/Source/platform/graphics/GraphicsLayer.cpp
@@ -154,6 +154,12 @@ layer_->Layer()->SetScrollBoundaryBehavior(behavior); } +void GraphicsLayer::SetIsResizedByBrowserControls( + bool is_resized_by_browser_controls) { + PlatformLayer()->SetIsResizedByBrowserControls( + is_resized_by_browser_controls); +} + void GraphicsLayer::SetParent(GraphicsLayer* layer) { #if DCHECK_IS_ON() DCHECK(!layer || !layer->HasAncestor(this));
diff --git a/third_party/WebKit/Source/platform/graphics/GraphicsLayer.h b/third_party/WebKit/Source/platform/graphics/GraphicsLayer.h index 9825d71..c2e378ef 100644 --- a/third_party/WebKit/Source/platform/graphics/GraphicsLayer.h +++ b/third_party/WebKit/Source/platform/graphics/GraphicsLayer.h
@@ -281,6 +281,7 @@ void SetHasWillChangeTransformHint(bool); void SetScrollBoundaryBehavior(const WebScrollBoundaryBehavior&); + void SetIsResizedByBrowserControls(bool); protected: String DebugName(cc::Layer*) const;
diff --git a/third_party/WebKit/Source/platform/graphics/Image.cpp b/third_party/WebKit/Source/platform/graphics/Image.cpp index 51e9aac..0032f98 100644 --- a/third_party/WebKit/Source/platform/graphics/Image.cpp +++ b/third_party/WebKit/Source/platform/graphics/Image.cpp
@@ -349,20 +349,17 @@ return image; } -PaintImage Image::PaintImageForCurrentFrame() { +void Image::InitPaintImageBuilder(PaintImageBuilder& builder) { auto animation_type = MaybeAnimated() ? PaintImage::AnimationType::ANIMATED : PaintImage::AnimationType::STATIC; auto completion_state = CurrentFrameIsComplete() ? PaintImage::CompletionState::DONE : PaintImage::CompletionState::PARTIALLY_DONE; - PaintImageBuilder builder; builder.set_id(stable_image_id_) .set_animation_type(animation_type) .set_completion_state(completion_state) .set_frame_count(FrameCount()) .set_is_multipart(is_multipart_); - PopulateImageForCurrentFrame(builder); - return builder.TakePaintImage(); } bool Image::ApplyShader(PaintFlags& flags, const SkMatrix& local_matrix) {
diff --git a/third_party/WebKit/Source/platform/graphics/Image.h b/third_party/WebKit/Source/platform/graphics/Image.h index 9c24d35..749c382 100644 --- a/third_party/WebKit/Source/platform/graphics/Image.h +++ b/third_party/WebKit/Source/platform/graphics/Image.h
@@ -174,7 +174,7 @@ virtual PassRefPtr<Image> ImageForDefaultFrame(); - PaintImage PaintImageForCurrentFrame(); + virtual PaintImage PaintImageForCurrentFrame() = 0; enum ImageClampingMode { kClampImageToSourceRect, @@ -250,7 +250,8 @@ const FloatRect&, const FloatSize& repeat_spacing); - virtual void PopulateImageForCurrentFrame(PaintImageBuilder&) = 0; + // Initializes a PaintImageBuilder with the metadata flags for the PaintImage. + void InitPaintImageBuilder(PaintImageBuilder&); private: bool image_observer_disabled_;
diff --git a/third_party/WebKit/Source/platform/graphics/ImageLayerChromiumTest.cpp b/third_party/WebKit/Source/platform/graphics/ImageLayerChromiumTest.cpp index 5ec7fd0d..44befae8 100644 --- a/third_party/WebKit/Source/platform/graphics/ImageLayerChromiumTest.cpp +++ b/third_party/WebKit/Source/platform/graphics/ImageLayerChromiumTest.cpp
@@ -64,6 +64,13 @@ // Image pure virtual stub. } + PaintImage PaintImageForCurrentFrame() override { + PaintImageBuilder builder; + InitPaintImageBuilder(builder); + builder.set_image(image_); + return builder.TakePaintImage(); + } + private: TestImage(IntSize size, bool opaque) : Image(0), size_(size) { sk_sp<SkSurface> surface = CreateSkSurface(size, opaque); @@ -80,10 +87,6 @@ opaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType)); } - void PopulateImageForCurrentFrame(PaintImageBuilder& builder) override { - builder.set_image(image_); - } - IntSize size_; sk_sp<SkImage> image_; };
diff --git a/third_party/WebKit/Source/platform/graphics/OffscreenCanvasFrameDispatcherImpl.h b/third_party/WebKit/Source/platform/graphics/OffscreenCanvasFrameDispatcherImpl.h index f88c4cf2..de555a8 100644 --- a/third_party/WebKit/Source/platform/graphics/OffscreenCanvasFrameDispatcherImpl.h +++ b/third_party/WebKit/Source/platform/graphics/OffscreenCanvasFrameDispatcherImpl.h
@@ -18,7 +18,7 @@ class PLATFORM_EXPORT OffscreenCanvasFrameDispatcherImpl final : public OffscreenCanvasFrameDispatcher, - NON_EXPORTED_BASE(public viz::mojom::blink::CompositorFrameSinkClient) { + public viz::mojom::blink::CompositorFrameSinkClient { public: OffscreenCanvasFrameDispatcherImpl(OffscreenCanvasFrameDispatcherClient*, uint32_t client_id,
diff --git a/third_party/WebKit/Source/platform/graphics/PlaceholderImage.cpp b/third_party/WebKit/Source/platform/graphics/PlaceholderImage.cpp index 8149719..4c9ae67f 100644 --- a/third_party/WebKit/Source/platform/graphics/PlaceholderImage.cpp +++ b/third_party/WebKit/Source/platform/graphics/PlaceholderImage.cpp
@@ -26,13 +26,14 @@ PlaceholderImage::~PlaceholderImage() {} -void PlaceholderImage::PopulateImageForCurrentFrame( - PaintImageBuilder& builder) { - const IntRect dest_rect(0, 0, size_.Width(), size_.Height()); +PaintImage PlaceholderImage::PaintImageForCurrentFrame() { + PaintImageBuilder builder; + InitPaintImageBuilder(builder); + const IntRect dest_rect(0, 0, size_.Width(), size_.Height()); if (paint_record_for_current_frame_) { builder.set_paint_record(paint_record_for_current_frame_, dest_rect); - return; + return builder.TakePaintImage(); } PaintRecorder paint_recorder; @@ -42,6 +43,7 @@ paint_record_for_current_frame_ = paint_recorder.finishRecordingAsPicture(); builder.set_paint_record(paint_record_for_current_frame_, dest_rect); + return builder.TakePaintImage(); } void PlaceholderImage::Draw(PaintCanvas* canvas,
diff --git a/third_party/WebKit/Source/platform/graphics/PlaceholderImage.h b/third_party/WebKit/Source/platform/graphics/PlaceholderImage.h index d6cf9c6..bd6a50c1 100644 --- a/third_party/WebKit/Source/platform/graphics/PlaceholderImage.h +++ b/third_party/WebKit/Source/platform/graphics/PlaceholderImage.h
@@ -42,11 +42,12 @@ void DestroyDecodedData() override; + PaintImage PaintImageForCurrentFrame() override; + private: PlaceholderImage(ImageObserver*, const IntSize&); bool CurrentFrameHasSingleSecurityOrigin() const override { return true; } - void PopulateImageForCurrentFrame(PaintImageBuilder&) override; bool CurrentFrameKnownToBeOpaque( MetadataMode = kUseCurrentMetadata) override {
diff --git a/third_party/WebKit/Source/platform/graphics/StaticBitmapImage.cpp b/third_party/WebKit/Source/platform/graphics/StaticBitmapImage.cpp index 66c5d0f..17c387d 100644 --- a/third_party/WebKit/Source/platform/graphics/StaticBitmapImage.cpp +++ b/third_party/WebKit/Source/platform/graphics/StaticBitmapImage.cpp
@@ -26,6 +26,11 @@ return UnacceleratedStaticBitmapImage::Create(image); } +RefPtr<StaticBitmapImage> StaticBitmapImage::Create(PaintImage image) { + DCHECK(!image.GetSkImage()->isTextureBacked()); + return UnacceleratedStaticBitmapImage::Create(std::move(image)); +} + void StaticBitmapImage::DrawHelper(PaintCanvas* canvas, const PaintFlags& flags, const FloatRect& dst_rect,
diff --git a/third_party/WebKit/Source/platform/graphics/StaticBitmapImage.h b/third_party/WebKit/Source/platform/graphics/StaticBitmapImage.h index bdbd176..c458539 100644 --- a/third_party/WebKit/Source/platform/graphics/StaticBitmapImage.h +++ b/third_party/WebKit/Source/platform/graphics/StaticBitmapImage.h
@@ -26,6 +26,7 @@ static RefPtr<StaticBitmapImage> Create( sk_sp<SkImage>, WeakPtr<WebGraphicsContext3DProviderWrapper>&& = nullptr); + static RefPtr<StaticBitmapImage> Create(PaintImage); bool IsStaticBitmapImage() const override { return true; }
diff --git a/third_party/WebKit/Source/platform/graphics/UnacceleratedStaticBitmapImage.cpp b/third_party/WebKit/Source/platform/graphics/UnacceleratedStaticBitmapImage.cpp index 51920f4..1242c48 100644 --- a/third_party/WebKit/Source/platform/graphics/UnacceleratedStaticBitmapImage.cpp +++ b/third_party/WebKit/Source/platform/graphics/UnacceleratedStaticBitmapImage.cpp
@@ -15,19 +15,33 @@ } UnacceleratedStaticBitmapImage::UnacceleratedStaticBitmapImage( - sk_sp<SkImage> image) - : image_(std::move(image)) { - DCHECK(image_); + sk_sp<SkImage> image) { + DCHECK(!image->isLazyGenerated()); + + PaintImageBuilder builder; + InitPaintImageBuilder(builder); + builder.set_image(std::move(image)); + paint_image_ = builder.TakePaintImage(); +} + +PassRefPtr<UnacceleratedStaticBitmapImage> +UnacceleratedStaticBitmapImage::Create(PaintImage image) { + return AdoptRef(new UnacceleratedStaticBitmapImage(std::move(image))); +} + +UnacceleratedStaticBitmapImage::UnacceleratedStaticBitmapImage(PaintImage image) + : paint_image_(std::move(image)) { + DCHECK(paint_image_); } UnacceleratedStaticBitmapImage::~UnacceleratedStaticBitmapImage() {} IntSize UnacceleratedStaticBitmapImage::Size() const { - return IntSize(image_->width(), image_->height()); + return IntSize(paint_image_.width(), paint_image_.height()); } bool UnacceleratedStaticBitmapImage::CurrentFrameKnownToBeOpaque(MetadataMode) { - return image_->isOpaque(); + return paint_image_.GetSkImage()->isOpaque(); } void UnacceleratedStaticBitmapImage::Draw(PaintCanvas* canvas, @@ -40,9 +54,8 @@ PaintImageForCurrentFrame()); } -void UnacceleratedStaticBitmapImage::PopulateImageForCurrentFrame( - PaintImageBuilder& builder) { - builder.set_image(image_); +PaintImage UnacceleratedStaticBitmapImage::PaintImageForCurrentFrame() { + return paint_image_; } } // namespace blink
diff --git a/third_party/WebKit/Source/platform/graphics/UnacceleratedStaticBitmapImage.h b/third_party/WebKit/Source/platform/graphics/UnacceleratedStaticBitmapImage.h index 774aba7..6750d26 100644 --- a/third_party/WebKit/Source/platform/graphics/UnacceleratedStaticBitmapImage.h +++ b/third_party/WebKit/Source/platform/graphics/UnacceleratedStaticBitmapImage.h
@@ -14,6 +14,7 @@ public: ~UnacceleratedStaticBitmapImage() override; static PassRefPtr<UnacceleratedStaticBitmapImage> Create(sk_sp<SkImage>); + static PassRefPtr<UnacceleratedStaticBitmapImage> Create(PaintImage); bool CurrentFrameKnownToBeOpaque(MetadataMode = kUseCurrentMetadata) override; IntSize Size() const override; @@ -25,11 +26,13 @@ RespectImageOrientationEnum, ImageClampingMode) override; - private: - void PopulateImageForCurrentFrame(PaintImageBuilder&) override; + PaintImage PaintImageForCurrentFrame() override; + private: UnacceleratedStaticBitmapImage(sk_sp<SkImage>); - sk_sp<SkImage> image_; + UnacceleratedStaticBitmapImage(PaintImage); + + PaintImage paint_image_; }; } // namespace blink
diff --git a/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.cpp b/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.cpp index 41168cf..4ec42e82 100644 --- a/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.cpp +++ b/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.cpp
@@ -43,13 +43,43 @@ root_layer_.get()); } -PaintArtifactCompositor::~PaintArtifactCompositor() {} +PaintArtifactCompositor::~PaintArtifactCompositor() { + for (auto child : root_layer_->children()) + DCHECK(!child->element_id()); +} + +void PaintArtifactCompositor::EnableExtraDataForTesting() { + extra_data_for_testing_enabled_ = true; + extra_data_for_testing_ = WTF::WrapUnique(new ExtraDataForTesting); +} void PaintArtifactCompositor::SetTracksRasterInvalidations(bool should_track) { for (auto& client : content_layer_clients_) client->SetTracksRasterInvalidations(should_track); } +void PaintArtifactCompositor::WillBeRemovedFromFrame() { + RemoveChildLayers(); +} + +void PaintArtifactCompositor::RemoveChildLayers() { + // Unregister element ids for all layers. For now we rely on the + // element id being set on the layer, but we'll be removing that for + // SPv2 soon. We may also shift to having multiple element ids per + // layer. When we do either of these, we'll need to keep around the + // element ids for unregistering in some other manner. + cc::LayerTreeHost* host = root_layer_->layer_tree_host(); + if (!host) + return; + for (auto child : root_layer_->children()) { + host->UnregisterElement(child->element_id(), cc::ElementListType::ACTIVE, + child.get()); + } + root_layer_->RemoveAllChildren(); + if (extra_data_for_testing_enabled_) + extra_data_for_testing_->content_layers.clear(); +} + std::unique_ptr<JSONObject> PaintArtifactCompositor::LayersAsJSON( LayerTreeFlags flags) const { std::unique_ptr<JSONArray> layers_json = JSONArray::Create(); @@ -510,19 +540,9 @@ return; if (extra_data_for_testing_enabled_) - extra_data_for_testing_ = WTF::WrapUnique(new ExtraDataForTesting); + extra_data_for_testing_.reset(new ExtraDataForTesting); - // Unregister element ids for all layers. For now we rely on the - // element id being set on the layer, but we'll both be removing - // that for SPv2 soon. We may also shift to having multiple element - // ids per layer. When we do either of these, we'll need to keep - // around the element ids for unregistering in some other manner. - for (auto child : root_layer_->children()) { - host->UnregisterElement(child->element_id(), cc::ElementListType::ACTIVE, - child.get()); - } - root_layer_->RemoveAllChildren(); - + RemoveChildLayers(); root_layer_->set_property_tree_sequence_number( g_s_property_tree_sequence_number);
diff --git a/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.h b/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.h index 937c7e3b..d3e310d 100644 --- a/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.h +++ b/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.h
@@ -78,13 +78,17 @@ Vector<scoped_refptr<cc::Layer>> content_layers; Vector<scoped_refptr<cc::Layer>> synthesized_clip_layers; }; - void EnableExtraDataForTesting() { extra_data_for_testing_enabled_ = true; } + void EnableExtraDataForTesting(); ExtraDataForTesting* GetExtraDataForTesting() const { return extra_data_for_testing_.get(); } void SetTracksRasterInvalidations(bool); + // Called when the local frame view that owns this compositor is + // going to be removed from its frame. + void WillBeRemovedFromFrame(); + std::unique_ptr<JSONObject> LayersAsJSON(LayerTreeFlags) const; #ifndef NDEBUG @@ -119,6 +123,8 @@ PaintArtifactCompositor(); + void RemoveChildLayers(); + // Collects the PaintChunks into groups which will end up in the same // cc layer. This is the entry point of the layerization algorithm. void CollectPendingLayers(const PaintArtifact&,
diff --git a/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositorTest.cpp b/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositorTest.cpp index 844aa27..a448fc5a 100644 --- a/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositorTest.cpp +++ b/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositorTest.cpp
@@ -94,6 +94,12 @@ *paint_artifact_compositor_->GetWebLayer()); } + void TearDown() override { + // Make sure we remove all child layers to satisfy destructor + // child layer element id DCHECK. + WillBeRemovedFromFrame(); + } + const cc::PropertyTrees& GetPropertyTrees() { return *web_layer_tree_view_->GetLayerTreeHost()->property_trees(); } @@ -136,6 +142,10 @@ web_layer_tree_view_->GetLayerTreeHost()->LayoutAndUpdateLayers(); } + void WillBeRemovedFromFrame() { + paint_artifact_compositor_->WillBeRemovedFromFrame(); + } + cc::Layer* RootLayer() { return paint_artifact_compositor_->RootLayer(); } size_t ContentLayerCount() { @@ -2799,4 +2809,22 @@ ASSERT_EQ(mask_isolation_2_id, mask_effect_2.parent_id); EXPECT_EQ(SkBlendMode::kDstIn, mask_effect_2.blend_mode); } + +TEST_F(PaintArtifactCompositorTestWithPropertyTrees, WillBeRemovedFromFrame) { + RefPtr<EffectPaintPropertyNode> effect = + CreateSampleEffectNodeWithElementId(); + TestPaintArtifact artifact; + artifact + .Chunk(TransformPaintPropertyNode::Root(), ClipPaintPropertyNode::Root(), + effect.Get()) + .RectDrawing(FloatRect(100, 100, 200, 100), Color::kBlack); + Update(artifact.Build()); + + ASSERT_EQ(1u, ContentLayerCount()); + WillBeRemovedFromFrame(); + // We would need a fake or mock LayerTreeHost to validate that we + // unregister all element ids, so just check layer count for now. + EXPECT_EQ(0u, ContentLayerCount()); +} + } // namespace blink
diff --git a/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.h b/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.h index f78bacf..442c277 100644 --- a/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.h +++ b/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.h
@@ -76,9 +76,8 @@ // Manages a rendering target (framebuffer + attachment) for a canvas. Can // publish its rendering results to a WebLayer for compositing. -class PLATFORM_EXPORT DrawingBuffer - : public NON_EXPORTED_BASE(cc::TextureLayerClient), - public RefCounted<DrawingBuffer> { +class PLATFORM_EXPORT DrawingBuffer : public cc::TextureLayerClient, + public RefCounted<DrawingBuffer> { WTF_MAKE_NONCOPYABLE(DrawingBuffer); public:
diff --git a/third_party/WebKit/Source/platform/graphics/gpu/ImageLayerBridge.h b/third_party/WebKit/Source/platform/graphics/gpu/ImageLayerBridge.h index ae84855..4bd13a0 100644 --- a/third_party/WebKit/Source/platform/graphics/gpu/ImageLayerBridge.h +++ b/third_party/WebKit/Source/platform/graphics/gpu/ImageLayerBridge.h
@@ -22,7 +22,7 @@ class PLATFORM_EXPORT ImageLayerBridge : public GarbageCollectedFinalized<ImageLayerBridge>, - NON_EXPORTED_BASE(public cc::TextureLayerClient) { + public cc::TextureLayerClient { WTF_MAKE_NONCOPYABLE(ImageLayerBridge); public:
diff --git a/third_party/WebKit/Source/platform/scroll/ScrollbarThemeOverlay.cpp b/third_party/WebKit/Source/platform/scroll/ScrollbarThemeOverlay.cpp index ed205a6d..2e4aa07f 100644 --- a/third_party/WebKit/Source/platform/scroll/ScrollbarThemeOverlay.cpp +++ b/third_party/WebKit/Source/platform/scroll/ScrollbarThemeOverlay.cpp
@@ -103,17 +103,6 @@ return style.fade_out_duration_seconds; } -int ScrollbarThemeOverlay::ThumbPosition(const ScrollbarThemeClient& scrollbar, - float scroll_position) { - if (!scrollbar.TotalSize()) - return 0; - - int track_len = TrackLength(scrollbar); - float proportion = - static_cast<float>(scroll_position) / scrollbar.TotalSize(); - return round(proportion * track_len); -} - int ScrollbarThemeOverlay::ThumbLength(const ScrollbarThemeClient& scrollbar) { int track_len = TrackLength(scrollbar);
diff --git a/third_party/WebKit/Source/platform/scroll/ScrollbarThemeOverlay.h b/third_party/WebKit/Source/platform/scroll/ScrollbarThemeOverlay.h index 8a95f522..c82d5666 100644 --- a/third_party/WebKit/Source/platform/scroll/ScrollbarThemeOverlay.h +++ b/third_party/WebKit/Source/platform/scroll/ScrollbarThemeOverlay.h
@@ -59,8 +59,6 @@ double OverlayScrollbarFadeOutDelaySeconds() const override; double OverlayScrollbarFadeOutDurationSeconds() const override; - int ThumbPosition(const ScrollbarThemeClient&, - float scroll_position) override; int ThumbLength(const ScrollbarThemeClient&) override; bool HasButtons(const ScrollbarThemeClient&) override { return false; }
diff --git a/third_party/WebKit/Source/platform/wtf/LinkedHashSet.h b/third_party/WebKit/Source/platform/wtf/LinkedHashSet.h index 83826b4..2b78d242 100644 --- a/third_party/WebKit/Source/platform/wtf/LinkedHashSet.h +++ b/third_party/WebKit/Source/platform/wtf/LinkedHashSet.h
@@ -647,6 +647,46 @@ friend class LinkedHashSet; }; +inline void SwapAnchor(LinkedHashSetNodeBase& a, LinkedHashSetNodeBase& b) { + DCHECK(a.prev_); + DCHECK(a.next_); + DCHECK(b.prev_); + DCHECK(b.next_); + swap(a.prev_, b.prev_); + swap(a.next_, b.next_); + if (b.next_ == &a) { + DCHECK_EQ(b.prev_, &a); + b.next_ = &b; + b.prev_ = &b; + } else { + b.next_->prev_ = &b; + b.prev_->next_ = &b; + } + if (a.next_ == &b) { + DCHECK_EQ(a.prev_, &b); + a.next_ = &a; + a.prev_ = &a; + } else { + a.next_->prev_ = &a; + a.prev_->next_ = &a; + } +} + +inline void swap(LinkedHashSetNodeBase& a, LinkedHashSetNodeBase& b) { + DCHECK_NE(a.next_, &a); + DCHECK_NE(b.next_, &b); + swap(a.prev_, b.prev_); + swap(a.next_, b.next_); + if (b.next_) { + b.next_->prev_ = &b; + b.prev_->next_ = &b; + } + if (a.next_) { + a.next_->prev_ = &a; + a.prev_->next_ = &a; + } +} + template <typename T, typename U, typename V, typename Allocator> inline LinkedHashSet<T, U, V, Allocator>::LinkedHashSet() { static_assert( @@ -877,46 +917,6 @@ erase(find(value)); } -inline void SwapAnchor(LinkedHashSetNodeBase& a, LinkedHashSetNodeBase& b) { - DCHECK(a.prev_); - DCHECK(a.next_); - DCHECK(b.prev_); - DCHECK(b.next_); - swap(a.prev_, b.prev_); - swap(a.next_, b.next_); - if (b.next_ == &a) { - DCHECK_EQ(b.prev_, &a); - b.next_ = &b; - b.prev_ = &b; - } else { - b.next_->prev_ = &b; - b.prev_->next_ = &b; - } - if (a.next_ == &b) { - DCHECK_EQ(a.prev_, &b); - a.next_ = &a; - a.prev_ = &a; - } else { - a.next_->prev_ = &a; - a.prev_->next_ = &a; - } -} - -inline void swap(LinkedHashSetNodeBase& a, LinkedHashSetNodeBase& b) { - DCHECK_NE(a.next_, &a); - DCHECK_NE(b.next_, &b); - swap(a.prev_, b.prev_); - swap(a.next_, b.next_); - if (b.next_) { - b.next_->prev_ = &b; - b.prev_->next_ = &b; - } - if (a.next_) { - a.next_->prev_ = &a; - a.prev_->next_ = &a; - } -} - template <typename T, typename Allocator> inline void swap(LinkedHashSetNode<T, Allocator>& a, LinkedHashSetNode<T, Allocator>& b) {
diff --git a/third_party/WebKit/Source/platform/wtf/PtrUtil.h b/third_party/WebKit/Source/platform/wtf/PtrUtil.h index 0162612a..81b4a6d 100644 --- a/third_party/WebKit/Source/platform/wtf/PtrUtil.h +++ b/third_party/WebKit/Source/platform/wtf/PtrUtil.h
@@ -29,14 +29,15 @@ return std::unique_ptr<T[]>(ptr); } -// WTF::makeUnique is base::MakeUnique. See base/ptr_util.h for documentation. +// TODO(crbug.com/755727): Inline all uses (even though this will lose the +// static_assert). template <typename T, typename... Args> auto MakeUnique(Args&&... args) - -> decltype(base::MakeUnique<T>(std::forward<Args>(args)...)) { + -> decltype(std::make_unique<T>(std::forward<Args>(args)...)) { static_assert( !WTF::IsGarbageCollectedType<typename std::remove_extent<T>::type>::value, "Garbage collected types should not be stored in std::unique_ptr!"); - return base::MakeUnique<T>(std::forward<Args>(args)...); + return std::make_unique<T>(std::forward<Args>(args)...); } } // namespace WTF
diff --git a/third_party/WebKit/Source/platform/wtf/text/TextCodecICU.cpp b/third_party/WebKit/Source/platform/wtf/text/TextCodecICU.cpp index 6f1e35d..1999a4a0 100644 --- a/third_party/WebKit/Source/platform/wtf/text/TextCodecICU.cpp +++ b/third_party/WebKit/Source/platform/wtf/text/TextCodecICU.cpp
@@ -85,13 +85,15 @@ continue; } +#if defined(USING_SYSTEM_ICU) // Explicitly do not support UTF-32. https://crbug.com/417850 - // TODO(jshin): Remove when ICU is updated. + // Bundled ICU does not return these names. if (!strcmp(standard_name, "UTF-32") || !strcmp(standard_name, "UTF-32LE") || !strcmp(standard_name, "UTF-32BE")) { continue; } +#endif // A number of these aliases are handled in Chrome's copy of ICU, but // Chromium can be compiled with the system ICU. @@ -250,13 +252,15 @@ if (!U_SUCCESS(error) || !standard_name) continue; } +#if defined(USING_SYSTEM_ICU) // Explicitly do not support UTF-32. https://crbug.com/417850 - // TODO(jshin): Remove when ICU is updated. + // Bundled ICU does not return these names. if (!strcmp(standard_name, "UTF-32") || !strcmp(standard_name, "UTF-32LE") || !strcmp(standard_name, "UTF-32BE")) { continue; } +#endif registrar(standard_name, Create, 0); } }
diff --git a/third_party/WebKit/Tools/Scripts/merge-layout-test-results b/third_party/WebKit/Tools/Scripts/merge-layout-test-results index e4980d73..fda1453e 100755 --- a/third_party/WebKit/Tools/Scripts/merge-layout-test-results +++ b/third_party/WebKit/Tools/Scripts/merge-layout-test-results
@@ -18,6 +18,19 @@ from webkitpy.common.system.log_utils import configure_logging from webkitpy.layout_tests import merge_results + +# The output JSON has the following arguments overwritten with a value from +# build properties. This occurs when '--build-properties' argument is provided +# and is mainly used when merging on build bots to provide better information +# about the build to the test results server. +# Format is a list of ('result json key', 'build property key'). +RESULTS_JSON_VALUE_OVERRIDE_WITH_BUILD_PROPERTY = [ + ("build_number", "buildnumber"), + ("builder_name", "buildername"), + ("chromium_revision", "got_revision_cp"), +] + + # ------------------------------------------------------------------------ def ensure_empty_dir(fs, directory, allow_existing, remove_existing): """Ensure an empty directory exists. @@ -134,21 +147,17 @@ logging_level = logging.INFO configure_logging(logging_level=logging_level) - results_json_value_overrides = {} - # Map the isolate arguments back to our output / input arguments. if args.output_json: logging.info('Running with isolated arguments') assert args.positional + # TODO(tansell): Once removed everywhere, these lines can be removed. + # For now we just check nobody is supply arguments we didn't expect. if args.results_json_override_with_build_property: - if not args.build_properties: - parser.error( - '--results-json-override-with-build-property given' - ' but --build-properties was not.') - build_properties = json.loads(args.build_properties) for result_key, build_prop_key in args.results_json_override_with_build_property: - results_json_value_overrides[result_key] = build_properties[build_prop_key] + assert (result_key, build_prop_key) in RESULTS_JSON_VALUE_OVERRIDE_WITH_BUILD_PROPERTY, ( + "%s not in %s" % (result_key, RESULTS_JSON_VALUE_OVERRIDE_WITH_BUILD_PROPERTY)) if not args.output_directory: args.output_directory = os.getcwd() @@ -170,13 +179,16 @@ assert args.output_directory assert args.input_directories - for k, v in args.results_json_override_value: - assert k not in results_json_value_overrides - try: - results_json_value_overrides[k] = eval(v) - except NameError: - results_json_value_overrides[k] = v - logging.debug('results_json_value_overrides: %r', results_json_value_overrides) + results_json_value_overrides = {} + if args.build_properties: + build_properties = json.loads(args.build_properties) + + for result_key, build_prop_key in RESULTS_JSON_VALUE_OVERRIDE_WITH_BUILD_PROPERTY: + if build_prop_key not in build_properties: + logging.warn('Required build property key "%s" was not found!', build_prop_key) + continue + results_json_value_overrides[result_key] = build_properties[build_prop_key] + logging.debug('results_json_value_overrides: %r', results_json_value_overrides) merger = merge_results.LayoutTestDirMerger( results_json_value_overrides=results_json_value_overrides,
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/path_finder.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/path_finder.py index 0495b0d0..24b1e7d 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/path_finder.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/path_finder.py
@@ -116,29 +116,6 @@ def path_from_layout_tests(self, *comps): return self._filesystem.join(self.layout_tests_dir(), *comps) - def layout_test_name(self, file_path): - """Returns a layout test name, given the path from the repo root. - - Note: this appears to not work on Windows; see crbug.com/658795. - Also, this function duplicates functionality that's in - Port.relative_test_filename. - - TODO(qyearsley): De-duplicate this and Port.relative_test_filename, - and ensure that it works properly with Windows paths. - - Args: - file_path: A relative path from the root of the Chromium repo. - - Returns: - The normalized layout test name, which is just the relative path from - the LayoutTests directory, using forward slash as the path separator. - Returns None if the given file is not in the LayoutTests directory. - """ - layout_tests_rel_path = self._filesystem.relpath(self.layout_tests_dir(), self.chromium_base()) - if not file_path.startswith(layout_tests_rel_path): - return None - return file_path[len(layout_tests_rel_path) + 1:] - @memoized def depot_tools_base(self): """Returns the path to depot_tools, or None if not found.
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/path_finder_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/path_finder_unittest.py index c5a30d7..dfaa512 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/path_finder_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/path_finder_unittest.py
@@ -48,17 +48,6 @@ finder.path_from_layout_tests('external', 'wpt'), '/mock-checkout/third_party/WebKit/LayoutTests/external/wpt') - def test_layout_test_name(self): - finder = PathFinder(MockFileSystem()) - self.assertEqual( - finder.layout_test_name('third_party/WebKit/LayoutTests/test/name.html'), - 'test/name.html') - - def test_layout_test_name_not_in_layout_tests_dir(self): - finder = PathFinder(MockFileSystem()) - self.assertIsNone( - finder.layout_test_name('some/other/path/file.html')) - def test_depot_tools_base_not_found(self): finder = PathFinder(MockFileSystem(), sys_path=['/foo'], env_path=['/bar']) self.assertIsNone(finder.depot_tools_base())
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/base.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/base.py index 11fae00..aac64bae 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/base.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/base.py
@@ -999,7 +999,6 @@ Ports may legitimately return absolute paths here if no relative path makes sense. - TODO(qyearsley): De-duplicate this and PathFinder.layout_test_name. """ # Ports that run on windows need to override this method to deal with # filenames with backslashes in them.
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests.py index f5449300..981faf04 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests.py
@@ -38,7 +38,6 @@ from webkitpy.layout_tests.controllers.manager import Manager from webkitpy.layout_tests.models import test_run_results from webkitpy.layout_tests.port.factory import configuration_options, platform_options -from webkitpy.layout_tests.views import buildbot_results from webkitpy.layout_tests.views import printing _log = logging.getLogger(__name__) @@ -592,14 +591,6 @@ run_details = _run_tests(port, options, args, printer) printer.flush() - if (not options.dry_run and - (run_details.exit_code not in exit_codes.ERROR_CODES or - run_details.exit_code == exit_codes.EARLY_EXIT_STATUS) and - not run_details.initial_results.keyboard_interrupted): - bot_printer = buildbot_results.BuildBotPrinter(stdout, options.debug_rwt_logging) - bot_printer.print_results(run_details) - stdout.flush() - _log.debug('') _log.debug('Testing completed. Exit status: %d', run_details.exit_code) return run_details
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests_unittest.py index 3bb1ffa..87c3b98 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests_unittest.py
@@ -1043,20 +1043,6 @@ json_failing_test_results = host.filesystem.read_text_file('/tmp/json_failing_results.json') self.assertEqual(json.loads(json_failing_test_results), details.summarized_failing_results) - def test_buildbot_results_are_printed_on_early_exit(self): - stdout = StringIO.StringIO() - stderr = StringIO.StringIO() - res = run_webkit_tests.main(['--platform', 'test', '--exit-after-n-failures', '1', - '--order', 'natural', - 'failures/unexpected/missing_text.html', - 'failures/unexpected/missing_image.html'], - stdout, stderr) - self.assertEqual(res, exit_codes.EARLY_EXIT_STATUS) - self.assertEqual(stdout.getvalue(), - ('\n' - 'Regressions: Unexpected missing results (1)\n' - ' failures/unexpected/missing_image.html [ Missing ]\n\n')) - def test_image_first_flag_initialized_from_file(self): host = MockHost() image_first_tests_filename = test.LAYOUT_TEST_DIR + '/ImageFirstTests'
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/views/buildbot_results.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/views/buildbot_results.py deleted file mode 100644 index d7a4078..0000000 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/views/buildbot_results.py +++ /dev/null
@@ -1,165 +0,0 @@ -# Copyright (C) 2012 Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -from webkitpy.layout_tests.models import test_expectations -from webkitpy.layout_tests.models.test_expectations import TestExpectations, TestExpectationLine - -from webkitpy.common.net.layout_test_results import LayoutTestResults - - -class BuildBotPrinter(object): - # This output was previously parsed on buildbot runs by - # build/scripts/master/log_parser/webkit_test_command.py, - # but this is no longer the case. - # TODO(qyearsley): Remove this module, and potentially - # move any useful printing to printing.py. - - def __init__(self, stream, debug_logging): - self.stream = stream - self.debug_logging = debug_logging - - def print_results(self, run_details): - if self.debug_logging: - self.print_run_results(run_details.initial_results) - self.print_unexpected_results(run_details.summarized_full_results, run_details.enabled_pixel_tests_in_retry) - - def _print(self, msg): - self.stream.write(msg + '\n') - - def print_run_results(self, run_results): - failed = run_results.total_failures - total = run_results.total - passed = total - failed - run_results.remaining - percent_passed = 0.0 - if total > 0: - percent_passed = float(passed) * 100 / total - - self._print('=> Results: %d/%d tests passed (%.1f%%)' % (passed, total, percent_passed)) - self._print('') - self._print_run_results_entry(run_results, test_expectations.NOW, 'Tests to be fixed') - - self._print('') - self._print('') - - def _print_run_results_entry(self, run_results, timeline, heading): - total = len(run_results.tests_by_timeline[timeline]) - not_passing = (total - - len(run_results.tests_by_expectation[test_expectations.PASS] & - run_results.tests_by_timeline[timeline])) - self._print('=> %s (%d):' % (heading, not_passing)) - - for result in TestExpectations.EXPECTATION_DESCRIPTIONS.keys(): - if result in (test_expectations.PASS, test_expectations.SKIP): - continue - results = (run_results.tests_by_expectation[result] & run_results.tests_by_timeline[timeline]) - desc = TestExpectations.EXPECTATION_DESCRIPTIONS[result] - if not_passing and len(results): - pct = len(results) * 100.0 / not_passing - self._print(' %5d %-24s (%4.1f%%)' % (len(results), desc, pct)) - - def print_unexpected_results(self, summarized_results, enabled_pixel_tests_in_retry=False): - passes = {} - flaky = {} - regressions = {} - - def add_to_dict_of_lists(dict, key, value): - dict.setdefault(key, []).append(value) - - def add_result(result): - test = result.test_name() - actual = result.actual_results().split(' ') - expected = result.expected_results().split(' ') - - if result.did_run_as_expected(): - # Don't print anything for tests that ran as expected. - return - - if actual == ['PASS']: - if 'CRASH' in expected: - add_to_dict_of_lists(passes, 'Expected to crash, but passed', test) - elif 'TIMEOUT' in expected: - add_to_dict_of_lists(passes, 'Expected to timeout, but passed', test) - else: - add_to_dict_of_lists(passes, 'Expected to fail, but passed', test) - elif enabled_pixel_tests_in_retry and actual == ['TEXT', 'IMAGE+TEXT']: - add_to_dict_of_lists(regressions, actual[0], test) - elif len(actual) > 1 and bool(set(actual[1:]) & set(expected)): - # We group flaky tests by the first actual result we got. - add_to_dict_of_lists(flaky, actual[0], test) - else: - add_to_dict_of_lists(regressions, actual[0], test) - - test_results = LayoutTestResults(summarized_results) - test_results.for_each_test(add_result) - - if len(passes) or len(flaky) or len(regressions): - self._print('') - if len(passes): - for key, tests in passes.iteritems(): - self._print('%s: (%d)' % (key, len(tests))) - tests.sort() - for test in tests: - self._print(' %s' % test) - self._print('') - self._print('') - - if len(flaky): - descriptions = TestExpectations.EXPECTATION_DESCRIPTIONS - for key, tests in flaky.iteritems(): - result_type = TestExpectations.EXPECTATIONS[key.lower()] - self._print('Unexpected flakiness: %s (%d)' % (descriptions[result_type], len(tests))) - tests.sort() - - for test in tests: - result = test_results.result_for_test(test) - actual = result.actual_results().split(' ') - expected = result.expected_results().split(' ') - # FIXME: clean this up once the old syntax is gone - new_expectations_list = [TestExpectationLine.inverted_expectation_tokens[exp] - for exp in list(set(actual) | set(expected))] - self._print(' %s [ %s ]' % (test, ' '.join(new_expectations_list))) - self._print('') - self._print('') - - if len(regressions): - descriptions = TestExpectations.EXPECTATION_DESCRIPTIONS - for key, tests in regressions.iteritems(): - result_type = TestExpectations.EXPECTATIONS[key.lower()] - self._print('Regressions: Unexpected %s (%d)' % (descriptions[result_type], len(tests))) - tests.sort() - for test in tests: - result = test_results.result_for_test(test) - actual = result.actual_results().split(' ') - expected = result.expected_results().split(' ') - new_expectations_list = [TestExpectationLine.inverted_expectation_tokens[exp] for exp in actual] - self._print(' %s [ %s ]' % (test, ' '.join(new_expectations_list))) - self._print('') - - if len(summarized_results['tests']) and self.debug_logging: - self._print('%s' % ('-' * 78))
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/views/buildbot_results_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/views/buildbot_results_unittest.py deleted file mode 100644 index 757f632..0000000 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/views/buildbot_results_unittest.py +++ /dev/null
@@ -1,113 +0,0 @@ -# Copyright (C) 2012 Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -import StringIO -import unittest - -from webkitpy.common.host_mock import MockHost -from webkitpy.layout_tests.models import test_run_results -from webkitpy.layout_tests.models import test_run_results_unittest -from webkitpy.layout_tests.views import buildbot_results - - -class BuildBotPrinterTests(unittest.TestCase): - - def assertNotEmpty(self, stream): - self.assertTrue(stream.getvalue()) - - def get_printer(self): - stream = StringIO.StringIO() - printer = buildbot_results.BuildBotPrinter(stream, debug_logging=True) - return printer, stream - - def test_print_unexpected_results(self): - port = MockHost().port_factory.get('test') - printer, out = self.get_printer() - - # test everything running as expected - DASHED_LINE = "-" * 78 + "\n" - summary = test_run_results_unittest.summarized_results(port, expected=True, passing=False, flaky=False) - printer.print_unexpected_results(summary) - self.assertEqual(out.getvalue(), DASHED_LINE) - - # test failures - printer, out = self.get_printer() - summary = test_run_results_unittest.summarized_results(port, expected=False, passing=False, flaky=False) - printer.print_unexpected_results(summary) - self.assertNotEmpty(out) - - # test unexpected flaky - printer, out = self.get_printer() - summary = test_run_results_unittest.summarized_results(port, expected=False, passing=False, flaky=True) - printer.print_unexpected_results(summary) - self.assertNotEmpty(out) - self.assertNotIn('failures/expected/crash.html', out.getvalue()) - - printer, out = self.get_printer() - summary = test_run_results_unittest.summarized_results(port, expected=False, passing=False, flaky=False) - printer.print_unexpected_results(summary) - self.assertNotEmpty(out) - - printer, out = self.get_printer() - summary = test_run_results_unittest.summarized_results(port, expected=False, passing=False, flaky=False) - printer.print_unexpected_results(summary) - self.assertNotEmpty(out) - - printer, out = self.get_printer() - summary = test_run_results_unittest.summarized_results(port, expected=False, passing=True, flaky=False) - printer.print_unexpected_results(summary) - output = out.getvalue() - self.assertTrue(output) - self.assertTrue('Skip' not in output) - - def test_print_unexpected_results_fail_on_retry_also(self): - port = MockHost().port_factory.get('test') - printer, out = self.get_printer() - summary = test_run_results_unittest.summarized_results(port, expected=False, passing=False, flaky=False) - printer.print_unexpected_results(summary) - output = out.getvalue() - self.assertIn( - 'Regressions: Unexpected crashes (1)\n' - ' failures/expected/audio.html [ Crash Leak Leak Leak ]', - output) - self.assertIn( - 'Regressions: Unexpected text-only failures (1)\n' - ' failures/expected/timeout.html [ Failure Failure Crash Leak ]', - output) - - def test_print_results(self): - port = MockHost().port_factory.get('test') - printer, out = self.get_printer() - initial_results = test_run_results_unittest.run_results(port) - full_summary = test_run_results_unittest.summarized_results(port, expected=False, passing=True, flaky=False) - failing_summary = test_run_results_unittest.summarized_results( - port, expected=False, passing=True, flaky=False, only_include_failing=True) - details = test_run_results.RunDetails(failing_summary['num_regressions'], - full_summary, failing_summary, initial_results, None) - printer.print_results(details) - self.assertTrue(out.getvalue().find('but passed') != -1)
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/directory_owners_extractor.py b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/directory_owners_extractor.py index a48b18e..c689821 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/directory_owners_extractor.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/directory_owners_extractor.py
@@ -37,14 +37,15 @@ """ email_map = collections.defaultdict(set) for relpath in changed_files: - if self.finder.layout_test_name(relpath) is None: + absolute_path = self.finder.path_from_chromium_base(relpath) + if not absolute_path.startswith(self.finder.layout_tests_dir()): continue owners_file, owners = self.find_and_extract_owners(self.filesystem.dirname(relpath)) if not owners_file: continue - owners_file_relpath = self.filesystem.relpath(owners_file, self.finder.chromium_base()) - owned_directory = self.finder.layout_test_name(self.filesystem.dirname(owners_file_relpath)) - email_map[tuple(owners)].add(owned_directory) + owned_directory = self.filesystem.dirname(owners_file) + owned_directory_relpath = self.filesystem.relpath(owned_directory, self.finder.layout_tests_dir()) + email_map[tuple(owners)].add(owned_directory_relpath) return {owners: sorted(owned_directories) for owners, owned_directories in email_map.iteritems()} def find_and_extract_owners(self, start_directory):
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer.py b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer.py index 9e93d3b..d38d47f 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer.py
@@ -498,8 +498,8 @@ """List of layout tests that have been deleted.""" out = self.check_run(['git', 'diff', 'origin/master', '-M100%', '--diff-filter=D', '--name-only']) deleted_tests = [] - for line in out.splitlines(): - test = self.finder.layout_test_name(line) + for path in out.splitlines(): + test = self._relative_to_layout_test_dir(path) if test: deleted_tests.append(test) return deleted_tests @@ -513,8 +513,15 @@ renamed_tests = {} for line in out.splitlines(): _, source_path, dest_path = line.split() - source_test = self.finder.layout_test_name(source_path) - dest_test = self.finder.layout_test_name(dest_path) + source_test = self._relative_to_layout_test_dir(source_path) + dest_test = self._relative_to_layout_test_dir(dest_path) if source_test and dest_test: renamed_tests[source_test] = dest_test return renamed_tests + + def _relative_to_layout_test_dir(self, path_relative_to_repo_root): + """Returns a path that's relative to the layout tests directory.""" + abs_path = self.finder.path_from_chromium_base(path_relative_to_repo_root) + if not abs_path.startswith(self.finder.layout_tests_dir()): + return None + return self.fs.relpath(abs_path, self.finder.layout_tests_dir())
diff --git a/third_party/WebKit/public/blink_typemaps.gni b/third_party/WebKit/public/blink_typemaps.gni index 0349611..dbd97fe 100644 --- a/third_party/WebKit/public/blink_typemaps.gni +++ b/third_party/WebKit/public/blink_typemaps.gni
@@ -3,12 +3,12 @@ # found in the LICENSE file. typemaps = [ - "//cc/ipc/begin_frame_args_for_blink.typemap", "//cc/ipc/frame_sink_id.typemap", "//cc/ipc/local_surface_id.typemap", "//cc/ipc/surface_id.typemap", "//gpu/ipc/common/mailbox_holder_for_blink.typemap", "//gpu/ipc/common/sync_token.typemap", + "//services/viz/public/cpp/compositing/begin_frame_args_for_blink.typemap", "//services/viz/public/cpp/compositing/compositor_frame_for_blink.typemap", "//services/viz/public/cpp/compositing/returned_resource.typemap", "//services/viz/public/cpp/compositing/surface_info.typemap",
diff --git a/third_party/WebKit/public/platform/WebLayer.h b/third_party/WebKit/public/platform/WebLayer.h index bca2777..00a04a22 100644 --- a/third_party/WebKit/public/platform/WebLayer.h +++ b/third_party/WebKit/public/platform/WebLayer.h
@@ -195,6 +195,8 @@ virtual void SetIsContainerForFixedPositionLayers(bool) = 0; virtual bool IsContainerForFixedPositionLayers() const = 0; + virtual void SetIsResizedByBrowserControls(bool) = 0; + // This function sets layer position constraint. The constraint will be used // to adjust layer position during threaded scrolling. virtual void SetPositionConstraint(const WebLayerPositionConstraint&) = 0;
diff --git a/third_party/closure_compiler/compiled_resources2.gyp b/third_party/closure_compiler/compiled_resources2.gyp index 268eef04..9bf0cc27 100644 --- a/third_party/closure_compiler/compiled_resources2.gyp +++ b/third_party/closure_compiler/compiled_resources2.gyp
@@ -23,7 +23,6 @@ '<(DEPTH)/chrome/browser/resources/chromeos/select_to_speak/compiled_resources2.gyp:*', '<(DEPTH)/chrome/browser/resources/chromeos/switch_access/compiled_resources2.gyp:*', '<(DEPTH)/chrome/browser/resources/extensions/compiled_resources2.gyp:*', - '<(DEPTH)/chrome/browser/resources/help/compiled_resources2.gyp:*', '<(DEPTH)/chrome/browser/resources/md_bookmarks/compiled_resources2.gyp:*', '<(DEPTH)/chrome/browser/resources/md_downloads/compiled_resources2.gyp:*', '<(DEPTH)/chrome/browser/resources/md_extensions/compiled_resources2.gyp:*', @@ -33,7 +32,6 @@ '<(DEPTH)/chrome/browser/resources/media_router/compiled_resources2.gyp:*', '<(DEPTH)/chrome/browser/resources/ntp4/compiled_resources2.gyp:*', '<(DEPTH)/chrome/browser/resources/offline_pages/compiled_resources2.gyp:*', - '<(DEPTH)/chrome/browser/resources/options/compiled_resources2.gyp:*', '<(DEPTH)/chrome/browser/resources/pdf/compiled_resources2.gyp:*', '<(DEPTH)/chrome/browser/resources/print_preview/compiled_resources2.gyp:*', '<(DEPTH)/chrome/browser/resources/settings/compiled_resources2.gyp:*',
diff --git a/third_party/closure_compiler/externs/networking_private.js b/third_party/closure_compiler/externs/networking_private.js index 584e045..961262a8 100644 --- a/third_party/closure_compiler/externs/networking_private.js +++ b/third_party/closure_compiler/externs/networking_private.js
@@ -860,8 +860,10 @@ * @typedef {{ * BSSID: (string|undefined), * Frequency: (number|undefined), + * HexSSID: (string|undefined), * Security: string, - * SignalStrength: (number|undefined) + * SignalStrength: (number|undefined), + * SSID: (string|undefined) * }} * @see https://developer.chrome.com/extensions/networkingPrivate#type-WiFiStateProperties */
diff --git a/third_party/harfbuzz-ng/README.chromium b/third_party/harfbuzz-ng/README.chromium index 5b79456f..f76c18b 100644 --- a/third_party/harfbuzz-ng/README.chromium +++ b/third_party/harfbuzz-ng/README.chromium
@@ -2,7 +2,7 @@ Short Name: harfbuzz-ng URL: http://harfbuzz.org Version: 1.4.8 -Date: 20170808 +Date: 20170815 Security Critical: yes License: MIT License File: COPYING
diff --git a/third_party/harfbuzz-ng/src/hb-buffer-private.hh b/third_party/harfbuzz-ng/src/hb-buffer-private.hh index bca308d..37380b40 100644 --- a/third_party/harfbuzz-ng/src/hb-buffer-private.hh +++ b/third_party/harfbuzz-ng/src/hb-buffer-private.hh
@@ -50,6 +50,7 @@ HB_MARK_AS_FLAG_T (hb_buffer_flags_t); HB_MARK_AS_FLAG_T (hb_buffer_serialize_flags_t); +HB_MARK_AS_FLAG_T (hb_buffer_diff_flags_t); enum hb_buffer_scratch_flags_t { HB_BUFFER_SCRATCH_FLAG_DEFAULT = 0x00000000u, @@ -57,6 +58,8 @@ HB_BUFFER_SCRATCH_FLAG_HAS_DEFAULT_IGNORABLES = 0x00000002u, HB_BUFFER_SCRATCH_FLAG_HAS_SPACE_FALLBACK = 0x00000004u, HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT = 0x00000008u, + HB_BUFFER_SCRATCH_FLAG_HAS_UNSAFE_TO_BREAK = 0x00000010u, + /* Reserved for complex shapers' internal use. */ HB_BUFFER_SCRATCH_FLAG_COMPLEX0 = 0x01000000u, HB_BUFFER_SCRATCH_FLAG_COMPLEX1 = 0x02000000u, @@ -232,25 +235,31 @@ for (unsigned int j = 0; j < len; j++) info[j].mask |= mask; } - HB_INTERNAL void set_masks (hb_mask_t value, - hb_mask_t mask, - unsigned int cluster_start, - unsigned int cluster_end); + HB_INTERNAL void set_masks (hb_mask_t value, hb_mask_t mask, + unsigned int cluster_start, unsigned int cluster_end); - HB_INTERNAL void merge_clusters (unsigned int start, - unsigned int end) + inline void merge_clusters (unsigned int start, unsigned int end) { if (end - start < 2) return; merge_clusters_impl (start, end); } - HB_INTERNAL void merge_clusters_impl (unsigned int start, - unsigned int end); - HB_INTERNAL void merge_out_clusters (unsigned int start, - unsigned int end); + HB_INTERNAL void merge_clusters_impl (unsigned int start, unsigned int end); + HB_INTERNAL void merge_out_clusters (unsigned int start, unsigned int end); /* Merge clusters for deleting current glyph, and skip it. */ HB_INTERNAL void delete_glyph (void); + inline void unsafe_to_break (unsigned int start, + unsigned int end) + { + if (end - start < 2) + return; + unsafe_to_break_impl (start, end); + } + HB_INTERNAL void unsafe_to_break_impl (unsigned int start, unsigned int end); + HB_INTERNAL void unsafe_to_break_from_outbuffer (unsigned int start, unsigned int end); + + /* Internal methods */ HB_INTERNAL bool enlarge (unsigned int size); @@ -282,9 +291,66 @@ return ret; } HB_INTERNAL bool message_impl (hb_font_t *font, const char *fmt, va_list ap) HB_PRINTF_FUNC(3, 0); + + static inline void + set_cluster (hb_glyph_info_t &info, unsigned int cluster, unsigned int mask = 0) + { + if (info.cluster != cluster) + { + if (mask & HB_GLYPH_FLAG_UNSAFE_TO_BREAK) + info.mask |= HB_GLYPH_FLAG_UNSAFE_TO_BREAK; + else + info.mask &= ~HB_GLYPH_FLAG_UNSAFE_TO_BREAK; + } + info.cluster = cluster; + } + + int + _unsafe_to_break_find_min_cluster (const hb_glyph_info_t *info, + unsigned int start, unsigned int end, + unsigned int cluster) const + { + for (unsigned int i = start; i < end; i++) + cluster = MIN (cluster, info[i].cluster); + return cluster; + } + void + _unsafe_to_break_set_mask (hb_glyph_info_t *info, + unsigned int start, unsigned int end, + unsigned int cluster) + { + for (unsigned int i = start; i < end; i++) + if (cluster != info[i].cluster) + { + scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_UNSAFE_TO_BREAK; + info[i].mask |= HB_GLYPH_FLAG_UNSAFE_TO_BREAK; + } + } }; +/* Loop over clusters. Duplicated in foreach_syllable(). */ +#define foreach_cluster(buffer, start, end) \ + for (unsigned int \ + _count = buffer->len, \ + start = 0, end = _count ? _next_cluster (buffer, 0) : 0; \ + start < _count; \ + start = end, end = _next_cluster (buffer, start)) + +static inline unsigned int +_next_cluster (hb_buffer_t *buffer, unsigned int start) +{ + hb_glyph_info_t *info = buffer->info; + unsigned int count = buffer->len; + + unsigned int cluster = info[start].cluster; + while (++start < count && cluster == info[start].cluster) + ; + + return start; +} + + #define HB_BUFFER_XALLOCATE_VAR(b, func, var) \ b->func (offsetof (hb_glyph_info_t, var) - offsetof(hb_glyph_info_t, var1), \ sizeof (b->info[0].var))
diff --git a/third_party/harfbuzz-ng/src/hb-buffer-serialize.cc b/third_party/harfbuzz-ng/src/hb-buffer-serialize.cc index 85696c58..517d746e 100644 --- a/third_party/harfbuzz-ng/src/hb-buffer-serialize.cc +++ b/third_party/harfbuzz-ng/src/hb-buffer-serialize.cc
@@ -145,10 +145,16 @@ if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS)) { - p += snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"dx\":%d,\"dy\":%d", - pos[i].x_offset, pos[i].y_offset); - p += snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"ax\":%d,\"ay\":%d", - pos[i].x_advance, pos[i].y_advance); + p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"dx\":%d,\"dy\":%d", + pos[i].x_offset, pos[i].y_offset)); + p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"ax\":%d,\"ay\":%d", + pos[i].x_advance, pos[i].y_advance)); + } + + if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_FLAGS) + { + if (info[i].mask & HB_GLYPH_FLAG_DEFINED) + p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"fl\":%u", info[i].mask & HB_GLYPH_FLAG_DEFINED)); } if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS) @@ -156,9 +162,9 @@ hb_glyph_extents_t extents; hb_font_get_glyph_extents(font, info[i].codepoint, &extents); p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"xb\":%d,\"yb\":%d", - extents.x_bearing, extents.y_bearing)); + extents.x_bearing, extents.y_bearing)); p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"w\":%d,\"h\":%d", - extents.width, extents.height)); + extents.width, extents.height)); } *p++ = '}'; @@ -226,6 +232,12 @@ p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",%d", pos[i].y_advance)); } + if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_FLAGS) + { + if (info[i].mask &HB_GLYPH_FLAG_DEFINED) + p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "#%X", info[i].mask &HB_GLYPH_FLAG_DEFINED)); + } + if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS) { hb_glyph_extents_t extents;
diff --git a/third_party/harfbuzz-ng/src/hb-buffer.cc b/third_party/harfbuzz-ng/src/hb-buffer.cc index 3777f7f..9007cd0d 100644 --- a/third_party/harfbuzz-ng/src/hb-buffer.cc +++ b/third_party/harfbuzz-ng/src/hb-buffer.cc
@@ -267,7 +267,7 @@ memset (glyph, 0, sizeof (*glyph)); glyph->codepoint = codepoint; - glyph->mask = 1; + glyph->mask = 0; glyph->cluster = cluster; len++; @@ -550,9 +550,12 @@ unsigned int end) { if (cluster_level == HB_BUFFER_CLUSTER_LEVEL_CHARACTERS) + { + unsafe_to_break (start, end); return; + } - uint32_t cluster = info[start].cluster; + unsigned int cluster = info[start].cluster; for (unsigned int i = start + 1; i < end; i++) cluster = MIN (cluster, info[i].cluster); @@ -568,10 +571,10 @@ /* If we hit the start of buffer, continue in out-buffer. */ if (idx == start) for (unsigned int i = out_len; i && out_info[i - 1].cluster == info[start].cluster; i--) - out_info[i - 1].cluster = cluster; + set_cluster (out_info[i - 1], cluster); for (unsigned int i = start; i < end; i++) - info[i].cluster = cluster; + set_cluster (info[i], cluster); } void hb_buffer_t::merge_out_clusters (unsigned int start, @@ -583,7 +586,7 @@ if (unlikely (end - start < 2)) return; - uint32_t cluster = out_info[start].cluster; + unsigned int cluster = out_info[start].cluster; for (unsigned int i = start + 1; i < end; i++) cluster = MIN (cluster, out_info[i].cluster); @@ -599,14 +602,16 @@ /* If we hit the end of out-buffer, continue in buffer. */ if (end == out_len) for (unsigned int i = idx; i < len && info[i].cluster == out_info[end - 1].cluster; i++) - info[i].cluster = cluster; + set_cluster (info[i], cluster); for (unsigned int i = start; i < end; i++) - out_info[i].cluster = cluster; + set_cluster (out_info[i], cluster); } void hb_buffer_t::delete_glyph () { + /* The logic here is duplicated in hb_ot_hide_default_ignorables(). */ + unsigned int cluster = info[idx].cluster; if (idx + 1 < len && cluster == info[idx + 1].cluster) { @@ -619,9 +624,10 @@ /* Merge cluster backward. */ if (cluster < out_info[out_len - 1].cluster) { + unsigned int mask = info[idx].mask; unsigned int old_cluster = out_info[out_len - 1].cluster; for (unsigned i = out_len; i && out_info[i - 1].cluster == old_cluster; i--) - out_info[i - 1].cluster = cluster; + set_cluster (out_info[i - 1], cluster, mask); } goto done; } @@ -638,6 +644,32 @@ } void +hb_buffer_t::unsafe_to_break_impl (unsigned int start, unsigned int end) +{ + unsigned int cluster = (unsigned int) -1; + cluster = _unsafe_to_break_find_min_cluster (info, start, end, cluster); + _unsafe_to_break_set_mask (info, start, end, cluster); +} +void +hb_buffer_t::unsafe_to_break_from_outbuffer (unsigned int start, unsigned int end) +{ + if (!have_output) + { + unsafe_to_break_impl (start, end); + return; + } + + assert (start <= out_len); + assert (idx <= end); + + unsigned int cluster = (unsigned int) -1; + cluster = _unsafe_to_break_find_min_cluster (out_info, start, out_len, cluster); + cluster = _unsafe_to_break_find_min_cluster (info, idx, end, cluster); + _unsafe_to_break_set_mask (out_info, start, out_len, cluster); + _unsafe_to_break_set_mask (info, idx, end, cluster); +} + +void hb_buffer_t::guess_segment_properties (void) { assert (content_type == HB_BUFFER_CONTENT_TYPE_UNICODE || @@ -1666,6 +1698,58 @@ } +/** + * hb_buffer_append: + * @buffer: an #hb_buffer_t. + * @source: source #hb_buffer_t. + * @start: start index into source buffer to copy. Use 0 to copy from start of buffer. + * @end: end index into source buffer to copy. Use (unsigned int) -1 to copy to end of buffer. + * + * Append (part of) contents of another buffer to this buffer. + * + * Since: 1.5.0 + **/ +HB_EXTERN void +hb_buffer_append (hb_buffer_t *buffer, + hb_buffer_t *source, + unsigned int start, + unsigned int end) +{ + assert (!buffer->have_output && !source->have_output); + assert (buffer->have_positions == source->have_positions || + !buffer->len || !source->len); + assert (buffer->content_type == source->content_type || + !buffer->len || !source->len); + + if (end > source->len) + end = source->len; + if (start > end) + start = end; + if (start == end) + return; + + if (!buffer->len) + buffer->content_type = source->content_type; + if (!buffer->have_positions && source->have_positions) + buffer->clear_positions (); + + if (buffer->len + (end - start) < buffer->len) /* Overflows. */ + { + buffer->in_error = true; + return; + } + + unsigned int orig_len = buffer->len; + hb_buffer_set_length (buffer, buffer->len + (end - start)); + if (buffer->in_error) + return; + + memcpy (buffer->info + orig_len, source->info + start, (end - start) * sizeof (buffer->info[0])); + if (buffer->have_positions) + memcpy (buffer->pos + orig_len, source->pos + start, (end - start) * sizeof (buffer->pos[0])); +} + + static int compare_info_codepoint (const hb_glyph_info_t *pa, const hb_glyph_info_t *pb) @@ -1736,7 +1820,8 @@ hb_buffer_normalize_glyphs (hb_buffer_t *buffer) { assert (buffer->have_positions); - assert (buffer->content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS); + assert (buffer->content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS || + (!buffer->len && buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID)); bool backward = HB_DIRECTION_IS_BACKWARD (buffer->props.direction); @@ -1775,6 +1860,88 @@ } } + +/* + * Comparing buffers. + */ + +hb_buffer_diff_flags_t +hb_buffer_diff (hb_buffer_t *buffer, + hb_buffer_t *reference, + hb_codepoint_t dottedcircle_glyph, + unsigned int position_fuzz) +{ + if (buffer->content_type != reference->content_type) + return HB_BUFFER_DIFF_FLAG_CONTENT_TYPE_MISMATCH; + + hb_buffer_diff_flags_t result = HB_BUFFER_DIFF_FLAG_EQUAL; + + unsigned int count = reference->len; + + if (buffer->len != count) + { + /* + * we can't compare glyph-by-glyph, but we do want to know if there + * are .notdef or dottedcircle glyphs present in the reference buffer + */ + const hb_glyph_info_t *info = reference->info; + unsigned int i; + for (i = 0; i < count; i++) + { + if (info[i].codepoint == dottedcircle_glyph) + result |= HB_BUFFER_DIFF_FLAG_DOTTED_CIRCLE_PRESENT; + else if (info[i].codepoint == 0) + result |= HB_BUFFER_DIFF_FLAG_NOTDEF_PRESENT; + } + result |= HB_BUFFER_DIFF_FLAG_LENGTH_MISMATCH; + return hb_buffer_diff_flags_t (result); + } + + if (!count) + return hb_buffer_diff_flags_t (result); + + const hb_glyph_info_t *buf_info = buffer->info; + const hb_glyph_info_t *ref_info = reference->info; + for (unsigned int i = 0; i < count; i++) + { + if (buf_info->codepoint != ref_info->codepoint) + result |= HB_BUFFER_DIFF_FLAG_CODEPOINT_MISMATCH; + if (buf_info->cluster != ref_info->cluster) + result |= HB_BUFFER_DIFF_FLAG_CLUSTER_MISMATCH; + if ((buf_info->mask & HB_GLYPH_FLAG_DEFINED) != (ref_info->mask & HB_GLYPH_FLAG_DEFINED)) + result |= HB_BUFFER_DIFF_FLAG_MASK_MISMATCH; + if (ref_info->codepoint == dottedcircle_glyph) + result |= HB_BUFFER_DIFF_FLAG_DOTTED_CIRCLE_PRESENT; + else if (ref_info->codepoint == 0) + result |= HB_BUFFER_DIFF_FLAG_NOTDEF_PRESENT; + buf_info++; + ref_info++; + } + + if (buffer->content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS) + { + assert (buffer->have_positions); + const hb_glyph_position_t *buf_pos = buffer->pos; + const hb_glyph_position_t *ref_pos = reference->pos; + for (unsigned int i = 0; i < count; i++) + { + if ((unsigned int) abs (buf_pos->x_advance - ref_pos->x_advance) > position_fuzz || + (unsigned int) abs (buf_pos->y_advance - ref_pos->y_advance) > position_fuzz || + (unsigned int) abs (buf_pos->x_offset - ref_pos->x_offset) > position_fuzz || + (unsigned int) abs (buf_pos->y_offset - ref_pos->y_offset) > position_fuzz) + { + result |= HB_BUFFER_DIFF_FLAG_POSITION_MISMATCH; + break; + } + buf_pos++; + ref_pos++; + } + } + + return result; +} + + /* * Debugging. */
diff --git a/third_party/harfbuzz-ng/src/hb-buffer.h b/third_party/harfbuzz-ng/src/hb-buffer.h index bf289c19..98f83ff 100644 --- a/third_party/harfbuzz-ng/src/hb-buffer.h +++ b/third_party/harfbuzz-ng/src/hb-buffer.h
@@ -63,7 +63,7 @@ */ typedef struct hb_glyph_info_t { hb_codepoint_t codepoint; - hb_mask_t mask; + hb_mask_t mask; /* Holds hb_glyph_flags_t after hb_shape() */ uint32_t cluster; /*< private >*/ @@ -71,6 +71,12 @@ hb_var_int_t var2; } hb_glyph_info_t; +typedef enum { /*< flags >*/ + HB_GLYPH_FLAG_UNSAFE_TO_BREAK = 0x00000001, + + HB_GLYPH_FLAG_DEFINED = 0x00000001 /* OR of all defined flags */ +} hb_glyph_flags_t; + /** * hb_glyph_position_t: * @x_advance: how much the line advances after drawing this glyph when setting @@ -163,6 +169,7 @@ hb_buffer_get_user_data (hb_buffer_t *buffer, hb_user_data_key_t *key); + /** * hb_buffer_content_type_t: * @HB_BUFFER_CONTENT_TYPE_INVALID: Initial value for new buffer. @@ -359,6 +366,11 @@ unsigned int item_offset, int item_length); +HB_EXTERN void +hb_buffer_append (hb_buffer_t *buffer, + hb_buffer_t *source, + unsigned int start, + unsigned int end); HB_EXTERN hb_bool_t hb_buffer_set_length (hb_buffer_t *buffer, @@ -403,7 +415,8 @@ HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS = 0x00000001u, HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS = 0x00000002u, HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES = 0x00000004u, - HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS = 0x00000008u + HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS = 0x00000008u, + HB_BUFFER_SERIALIZE_FLAG_GLYPH_FLAGS = 0x00000010u } hb_buffer_serialize_flags_t; /** @@ -453,6 +466,45 @@ /* + * Compare buffers + */ + +typedef enum { /*< flags >*/ + HB_BUFFER_DIFF_FLAG_EQUAL = 0x0000, + + /* Buffers with different content_type cannot be meaningfully compared + * in any further detail. */ + HB_BUFFER_DIFF_FLAG_CONTENT_TYPE_MISMATCH = 0X0001, + + /* For buffers with differing length, the per-glyph comparison is not + * attempted, though we do still scan reference for dottedcircle / .notdef + * glyphs. */ + HB_BUFFER_DIFF_FLAG_LENGTH_MISMATCH = 0X0002, + + /* We want to know if dottedcircle / .notdef glyphs are present in the + * reference, as we may not care so much about other differences in this + * case. */ + HB_BUFFER_DIFF_FLAG_NOTDEF_PRESENT = 0x0004, + HB_BUFFER_DIFF_FLAG_DOTTED_CIRCLE_PRESENT = 0x0008, + + /* If the buffers have the same length, we compare them glyph-by-glyph + * and report which aspect(s) of the glyph info/position are different. */ + HB_BUFFER_DIFF_FLAG_CODEPOINT_MISMATCH = 0x0010, + HB_BUFFER_DIFF_FLAG_CLUSTER_MISMATCH = 0x0020, + HB_BUFFER_DIFF_FLAG_MASK_MISMATCH = 0x0040, + HB_BUFFER_DIFF_FLAG_POSITION_MISMATCH = 0x0080 + +} hb_buffer_diff_flags_t; + +/* Compare the contents of two buffers, report types of differences. */ +hb_buffer_diff_flags_t +hb_buffer_diff (hb_buffer_t *buffer, + hb_buffer_t *reference, + hb_codepoint_t dottedcircle_glyph, + unsigned int position_fuzz); + + +/* * Debugging. */
diff --git a/third_party/harfbuzz-ng/src/hb-coretext.cc b/third_party/harfbuzz-ng/src/hb-coretext.cc index e237335..ba96d399 100644 --- a/third_party/harfbuzz-ng/src/hb-coretext.cc +++ b/third_party/harfbuzz-ng/src/hb-coretext.cc
@@ -1180,6 +1180,9 @@ pos->x_advance = info->mask; pos->x_offset = info->var1.i32; pos->y_offset = info->var2.i32; + + info->mask = HB_GLYPH_FLAG_UNSAFE_TO_BREAK; + info++, pos++; } else @@ -1188,6 +1191,9 @@ pos->y_advance = info->mask; pos->x_offset = info->var1.i32; pos->y_offset = info->var2.i32; + + info->mask = HB_GLYPH_FLAG_UNSAFE_TO_BREAK; + info++, pos++; }
diff --git a/third_party/harfbuzz-ng/src/hb-face-private.hh b/third_party/harfbuzz-ng/src/hb-face-private.hh index eb0e850..72f08a59 100644 --- a/third_party/harfbuzz-ng/src/hb-face-private.hh +++ b/third_party/harfbuzz-ng/src/hb-face-private.hh
@@ -55,10 +55,10 @@ mutable unsigned int num_glyphs; /* Number of glyphs. */ enum dirty_t { - NOTHING = 0x0000, - INDEX = 0x0001, - UPEM = 0x0002, - NUM_GLYPHS = 0x0004, + DIRTY_NOTHING = 0x0000, + DIRTY_INDEX = 0x0001, + DIRTY_UPEM = 0x0002, + DIRTY_NUM_GLYPHS = 0x0004, } dirty; struct hb_shaper_data_t shaper_data; /* Various shaper data. */
diff --git a/third_party/harfbuzz-ng/src/hb-face.cc b/third_party/harfbuzz-ng/src/hb-face.cc index 1800c995..22998f0 100644 --- a/third_party/harfbuzz-ng/src/hb-face.cc +++ b/third_party/harfbuzz-ng/src/hb-face.cc
@@ -51,7 +51,7 @@ 1000, /* upem */ 0, /* num_glyphs */ - hb_face_t::NOTHING, /* dirty */ + hb_face_t::DIRTY_NOTHING, /* dirty */ { #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID, @@ -370,7 +370,7 @@ if (face->index == index) return; - face->dirty |= face->INDEX; + face->dirty |= face->DIRTY_INDEX; face->index = index; } @@ -410,7 +410,7 @@ if (face->upem == upem) return; - face->dirty |= face->UPEM; + face->dirty |= face->DIRTY_UPEM; face->upem = upem; } @@ -459,7 +459,7 @@ if (face->num_glyphs == glyph_count) return; - face->dirty |= face->NUM_GLYPHS; + face->dirty |= face->DIRTY_NUM_GLYPHS; face->num_glyphs = glyph_count; }
diff --git a/third_party/harfbuzz-ng/src/hb-font-private.hh b/third_party/harfbuzz-ng/src/hb-font-private.hh index fbb16a0..ed9f2c5 100644 --- a/third_party/harfbuzz-ng/src/hb-font-private.hh +++ b/third_party/harfbuzz-ng/src/hb-font-private.hh
@@ -117,13 +117,13 @@ hb_destroy_func_t destroy; enum dirty_t { - NOTHING = 0x0000, - FACE = 0x0001, - PARENT = 0x0002, - FUNCS = 0x0004, - SCALE = 0x0008, - PPEM = 0x0010, - VARIATIONS = 0x0020, + DIRTY_NOTHING = 0x0000, + DIRTY_FACE = 0x0001, + DIRTY_PARENT = 0x0002, + DIRTY_FUNCS = 0x0004, + DIRTY_SCALE = 0x0008, + DIRTY_PPEM = 0x0010, + DIRTY_VARIATIONS = 0x0020, } dirty; struct hb_shaper_data_t shaper_data;
diff --git a/third_party/harfbuzz-ng/src/hb-font.cc b/third_party/harfbuzz-ng/src/hb-font.cc index e900bd3..a684c234 100644 --- a/third_party/harfbuzz-ng/src/hb-font.cc +++ b/third_party/harfbuzz-ng/src/hb-font.cc
@@ -1196,7 +1196,7 @@ NULL, /* user_data */ NULL, /* destroy */ - hb_font_t::NOTHING, /* dirty */ + hb_font_t::DIRTY_NOTHING, /* dirty */ { #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID, @@ -1353,7 +1353,7 @@ if (parent == font->parent) return; - font->dirty |= font->PARENT; + font->dirty |= font->DIRTY_PARENT; hb_font_t *old = font->parent; @@ -1400,7 +1400,7 @@ if (font->face == face) return; - font->dirty |= font->FACE; + font->dirty |= font->DIRTY_FACE; hb_face_t *old = font->face; @@ -1455,7 +1455,7 @@ if (!klass) klass = hb_font_funcs_get_empty (); - font->dirty |= font->FUNCS; + font->dirty |= font->DIRTY_FUNCS; hb_font_funcs_reference (klass); hb_font_funcs_destroy (font->klass); @@ -1515,7 +1515,7 @@ if (font->x_scale == x_scale && font->y_scale == y_scale) return; - font->dirty |= font->SCALE; + font->dirty |= font->DIRTY_SCALE; font->x_scale = x_scale; font->y_scale = y_scale; @@ -1561,7 +1561,7 @@ if (font->x_ppem == x_ppem && font->y_ppem == y_ppem) return; - font->dirty |= font->PPEM; + font->dirty |= font->DIRTY_PPEM; font->x_ppem = x_ppem; font->y_ppem = y_ppem; @@ -1603,7 +1603,7 @@ return; } - font->dirty |= font->VARIATIONS; + font->dirty |= font->DIRTY_VARIATIONS; free (font->coords);
diff --git a/third_party/harfbuzz-ng/src/hb-ft.cc b/third_party/harfbuzz-ng/src/hb-ft.cc index 48d6a0e..492992ee 100644 --- a/third_party/harfbuzz-ng/src/hb-ft.cc +++ b/third_party/harfbuzz-ng/src/hb-ft.cc
@@ -493,7 +493,7 @@ return NULL; buffer = (FT_Byte *) malloc (length); - if (buffer == NULL) + if (!buffer) return NULL; error = FT_Load_Sfnt_Table (ft_face, tag, 0, buffer, &length); @@ -521,7 +521,7 @@ { hb_face_t *face; - if (ft_face->stream->read == NULL) { + if (!ft_face->stream->read) { hb_blob_t *blob; blob = hb_blob_create ((const char *) ft_face->stream->base, @@ -632,9 +632,9 @@ hb_font_set_var_coords_normalized (font, coords, mm_var->num_axis); } - free (coords); - free (ft_coords); } + free (coords); + free (ft_coords); free (mm_var); } #endif
diff --git a/third_party/harfbuzz-ng/src/hb-graphite2.cc b/third_party/harfbuzz-ng/src/hb-graphite2.cc index c9799e9..9e0761e63 100644 --- a/third_party/harfbuzz-ng/src/hb-graphite2.cc +++ b/third_party/harfbuzz-ng/src/hb-graphite2.cc
@@ -355,6 +355,7 @@ hb_glyph_info_t *info = &buffer->info[clusters[i].base_glyph + j]; info->codepoint = gids[clusters[i].base_glyph + j]; info->cluster = clusters[i].cluster; + info->mask = HB_GLYPH_FLAG_UNSAFE_TO_BREAK; info->var1.i32 = clusters[i].advance; // all glyphs in the cluster get the same advance } } @@ -365,7 +366,7 @@ float yscale = (float) font->y_scale / upem; yscale *= yscale / xscale; /* Positioning. */ - int currclus = -1; + unsigned int currclus = (unsigned int) -1; const hb_glyph_info_t *info = buffer->info; hb_glyph_position_t *pPos = hb_buffer_get_glyph_positions (buffer, NULL); if (!HB_DIRECTION_IS_BACKWARD(buffer->props.direction))
diff --git a/third_party/harfbuzz-ng/src/hb-ot-font.cc b/third_party/harfbuzz-ng/src/hb-ot-font.cc index 2ce29cd..d3251ca 100644 --- a/third_party/harfbuzz-ng/src/hb-ot-font.cc +++ b/third_party/harfbuzz-ng/src/hb-ot-font.cc
@@ -224,7 +224,7 @@ const OT::CBDT *cbdt; unsigned int cbdt_len; - float upem; + unsigned int upem; inline void init (hb_face_t *face) { @@ -254,11 +254,11 @@ { unsigned int x_ppem = upem, y_ppem = upem; /* TODO Use font ppem if available. */ - if (cblc == NULL) + if (!cblc) return false; // Not a color bitmap font. const OT::IndexSubtableRecord *subtable_record = this->cblc->find_table(glyph, &x_ppem, &y_ppem); - if (subtable_record == NULL) + if (!subtable_record || !x_ppem || !y_ppem) return false; if (subtable_record->get_extents (extents))
diff --git a/third_party/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh b/third_party/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh index 952fd60fe..738ca8c4 100644 --- a/third_party/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh +++ b/third_party/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh
@@ -432,6 +432,7 @@ hb_position_t mark_x, mark_y, base_x, base_y; + buffer->unsafe_to_break (glyph_pos, buffer->idx); mark_anchor.get_anchor (c, buffer->cur().codepoint, &mark_x, &mark_y); glyph_anchor.get_anchor (c, buffer->info[glyph_pos].codepoint, &base_x, &base_y); @@ -643,6 +644,7 @@ min = mid + 1; else { + buffer->unsafe_to_break (buffer->idx, pos + 1); valueFormats[0].apply_value (c, this, &record->values[0], buffer->cur_pos()); valueFormats[1].apply_value (c, this, &record->values[len1], buffer->pos[pos]); if (len2) @@ -790,6 +792,7 @@ unsigned int klass2 = (this+classDef2).get_class (buffer->info[skippy_iter.idx].codepoint); if (unlikely (klass1 >= class1Count || klass2 >= class2Count)) return_trace (false); + buffer->unsafe_to_break (buffer->idx, skippy_iter.idx + 1); const Value *v = &values[record_len * (klass1 * class2Count + klass2)]; valueFormat1.apply_value (c, this, v, buffer->cur_pos()); valueFormat2.apply_value (c, this, v + len1, buffer->pos[skippy_iter.idx]); @@ -929,6 +932,7 @@ unsigned int i = buffer->idx; unsigned int j = skippy_iter.idx; + buffer->unsafe_to_break (i, j); hb_position_t entry_x, entry_y, exit_x, exit_y; (this+this_record.exitAnchor).get_anchor (c, buffer->info[i].codepoint, &exit_x, &exit_y); (this+next_record.entryAnchor).get_anchor (c, buffer->info[j].codepoint, &entry_x, &entry_y);
diff --git a/third_party/harfbuzz-ng/src/hb-ot-layout-gsub-table.hh b/third_party/harfbuzz-ng/src/hb-ot-layout-gsub-table.hh index 66fcb3f3..85be7e7 100644 --- a/third_party/harfbuzz-ng/src/hb-ot-layout-gsub-table.hh +++ b/third_party/harfbuzz-ng/src/hb-ot-layout-gsub-table.hh
@@ -1014,14 +1014,17 @@ const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack); const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID> > (lookahead); + unsigned int start_index = 0, end_index = 0; if (match_backtrack (c, backtrack.len, (USHORT *) backtrack.array, - match_coverage, this) && + match_coverage, this, + &start_index) && match_lookahead (c, lookahead.len, (USHORT *) lookahead.array, match_coverage, this, - 1)) + 1, &end_index)) { + c->buffer->unsafe_to_break_from_outbuffer (start_index, end_index); c->replace_glyph_inplace (substitute[index]); /* Note: We DON'T decrease buffer->idx. The main loop does it * for us. This is useful for preventing surprises if someone
diff --git a/third_party/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh b/third_party/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh index 2235d3a..472628a 100644 --- a/third_party/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh +++ b/third_party/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh
@@ -891,7 +891,8 @@ unsigned int count, const USHORT backtrack[], match_func_t match_func, - const void *match_data) + const void *match_data, + unsigned int *match_start) { TRACE_APPLY (NULL); @@ -903,6 +904,8 @@ if (!skippy_iter.prev ()) return_trace (false); + *match_start = skippy_iter.idx; + return_trace (true); } @@ -911,7 +914,8 @@ const USHORT lookahead[], match_func_t match_func, const void *match_data, - unsigned int offset) + unsigned int offset, + unsigned int *end_index) { TRACE_APPLY (NULL); @@ -923,6 +927,8 @@ if (!skippy_iter.next ()) return_trace (false); + *end_index = skippy_iter.idx + 1; + return_trace (true); } @@ -1145,10 +1151,11 @@ inputCount, input, lookup_context.funcs.match, lookup_context.match_data, &match_length, match_positions) - && apply_lookup (c, + && (c->buffer->unsafe_to_break (c->buffer->idx, c->buffer->idx + match_length), + apply_lookup (c, inputCount, match_positions, lookupCount, lookupRecord, - match_length); + match_length)); } struct Rule @@ -1666,7 +1673,7 @@ const LookupRecord lookupRecord[], ChainContextApplyLookupContext &lookup_context) { - unsigned int match_length = 0; + unsigned int start_index = 0, match_length = 0, end_index = 0; unsigned int match_positions[HB_MAX_CONTEXT_LENGTH]; return match_input (c, inputCount, input, @@ -1674,15 +1681,17 @@ &match_length, match_positions) && match_backtrack (c, backtrackCount, backtrack, - lookup_context.funcs.match, lookup_context.match_data[0]) + lookup_context.funcs.match, lookup_context.match_data[0], + &start_index) && match_lookahead (c, lookaheadCount, lookahead, lookup_context.funcs.match, lookup_context.match_data[2], - match_length) - && apply_lookup (c, + match_length, &end_index) + && (c->buffer->unsafe_to_break_from_outbuffer (start_index, end_index), + apply_lookup (c, inputCount, match_positions, lookupCount, lookupRecord, - match_length); + match_length)); } struct ChainRule
diff --git a/third_party/harfbuzz-ng/src/hb-ot-layout-private.hh b/third_party/harfbuzz-ng/src/hb-ot-layout-private.hh index b476339..d4ac60b 100644 --- a/third_party/harfbuzz-ng/src/hb-ot-layout-private.hh +++ b/third_party/harfbuzz-ng/src/hb-ot-layout-private.hh
@@ -197,8 +197,7 @@ #define syllable() var1.u8[3] /* GSUB/GPOS shaping boundaries */ -/* loop over syllables */ - +/* Loop over syllables. Based on foreach_cluster(). */ #define foreach_syllable(buffer, start, end) \ for (unsigned int \ _count = buffer->len, \
diff --git a/third_party/harfbuzz-ng/src/hb-ot-map.cc b/third_party/harfbuzz-ng/src/hb-ot-map.cc index 014e443..5764a110 100644 --- a/third_party/harfbuzz-ng/src/hb-ot-map.cc +++ b/third_party/harfbuzz-ng/src/hb-ot-map.cc
@@ -138,7 +138,11 @@ const int *coords, unsigned int num_coords) { - m.global_mask = 1; + ASSERT_STATIC (!(HB_GLYPH_FLAG_DEFINED & (HB_GLYPH_FLAG_DEFINED + 1))); + unsigned int global_bit_mask = HB_GLYPH_FLAG_DEFINED + 1; + unsigned int global_bit_shift = _hb_popcount32 (HB_GLYPH_FLAG_DEFINED); + + m.global_mask = global_bit_mask; unsigned int required_feature_index[2]; hb_tag_t required_feature_tag[2]; @@ -190,7 +194,8 @@ /* Allocate bits now */ - unsigned int next_bit = 1; + unsigned int next_bit = global_bit_shift + 1; + for (unsigned int i = 0; i < feature_infos.len; i++) { const feature_info_t *info = &feature_infos[i]; @@ -249,8 +254,8 @@ map->auto_zwj = !(info->flags & F_MANUAL_ZWJ); if ((info->flags & F_GLOBAL) && info->max_value == 1) { /* Uses the global bit */ - map->shift = 0; - map->mask = 1; + map->shift = global_bit_shift; + map->mask = global_bit_mask; } else { map->shift = next_bit; map->mask = (1u << (next_bit + bits_needed)) - (1u << next_bit); @@ -287,7 +292,7 @@ add_lookups (m, face, table_index, required_feature_index[table_index], variations_index, - 1 /* mask */); + global_bit_mask); for (unsigned i = 0; i < m.features.len; i++) if (m.features[i].stage[table_index] == stage)
diff --git a/third_party/harfbuzz-ng/src/hb-ot-shape-complex-arabic.cc b/third_party/harfbuzz-ng/src/hb-ot-shape-complex-arabic.cc index 5dbbcd9a..ed7b3f2 100644 --- a/third_party/harfbuzz-ng/src/hb-ot-shape-complex-arabic.cc +++ b/third_party/harfbuzz-ng/src/hb-ot-shape-complex-arabic.cc
@@ -321,7 +321,10 @@ const arabic_state_table_entry *entry = &arabic_state_table[state][this_type]; if (entry->prev_action != NONE && prev != (unsigned int) -1) + { info[prev].arabic_shaping_action() = entry->prev_action; + buffer->unsafe_to_break (prev, i + 1); + } info[i].arabic_shaping_action() = entry->curr_action;
diff --git a/third_party/harfbuzz-ng/src/hb-ot-shape-complex-hangul.cc b/third_party/harfbuzz-ng/src/hb-ot-shape-complex-hangul.cc index 23e07e59..0e74802 100644 --- a/third_party/harfbuzz-ng/src/hb-ot-shape-complex-hangul.cc +++ b/third_party/harfbuzz-ng/src/hb-ot-shape-complex-hangul.cc
@@ -202,6 +202,7 @@ if (start < end && end == buffer->out_len) { /* Tone mark follows a valid syllable; move it in front, unless it's zero width. */ + buffer->unsafe_to_break_from_outbuffer (start, buffer->idx); buffer->next_glyph (); if (!is_zero_width_char (font, u)) { @@ -258,6 +259,7 @@ else t = 0; /* The next character was not a trailing jamo. */ } + buffer->unsafe_to_break (buffer->idx, buffer->idx + (t ? 3 : 2)); /* We've got a syllable <L,V,T?>; see if it can potentially be composed. */ if (isCombiningL (l) && isCombiningV (v) && (t == 0 || isCombiningT (t))) @@ -322,6 +324,8 @@ end = start + 1; continue; } + else + buffer->unsafe_to_break (buffer->idx, buffer->idx + 2); /* Mark unsafe between LV and T. */ } /* Otherwise, decompose if font doesn't support <LV> or <LVT>, @@ -368,6 +372,8 @@ buffer->merge_out_clusters (start, end); continue; } + else if ((!tindex && buffer->idx + 1 < count && isT (buffer->cur(+1).codepoint))) + buffer->unsafe_to_break (buffer->idx, buffer->idx + 2); /* Mark unsafe between LV and T. */ } if (has_glyph)
diff --git a/third_party/harfbuzz-ng/src/hb-ot-shape-complex-indic.cc b/third_party/harfbuzz-ng/src/hb-ot-shape-complex-indic.cc index 02aab08..3cd8fd6 100644 --- a/third_party/harfbuzz-ng/src/hb-ot-shape-complex-indic.cc +++ b/third_party/harfbuzz-ng/src/hb-ot-shape-complex-indic.cc
@@ -624,6 +624,8 @@ hb_buffer_t *buffer) { find_syllables (buffer); + foreach_syllable (buffer, start, end) + buffer->unsafe_to_break (start, end); } static int
diff --git a/third_party/harfbuzz-ng/src/hb-ot-shape-complex-myanmar-machine.hh b/third_party/harfbuzz-ng/src/hb-ot-shape-complex-myanmar-machine.hh index d2fe742..29fdf9a 100644 --- a/third_party/harfbuzz-ng/src/hb-ot-shape-complex-myanmar-machine.hh +++ b/third_party/harfbuzz-ng/src/hb-ot-shape-complex-myanmar-machine.hh
@@ -1,5 +1,5 @@ -#line 1 "../../src/hb-ot-shape-complex-myanmar-machine.rl" +#line 1 "hb-ot-shape-complex-myanmar-machine.rl" /* * Copyright © 2011,2012 Google, Inc. * @@ -32,7 +32,7 @@ #include "hb-private.hh" -#line 36 "../../src/hb-ot-shape-complex-myanmar-machine.hh.tmp" +#line 36 "hb-ot-shape-complex-myanmar-machine.hh" static const unsigned char _myanmar_syllable_machine_trans_keys[] = { 1u, 31u, 3u, 30u, 5u, 29u, 5u, 8u, 5u, 29u, 3u, 25u, 5u, 25u, 5u, 25u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 1u, 16u, 3u, 29u, 3u, 29u, 3u, 29u, @@ -261,11 +261,11 @@ static const int myanmar_syllable_machine_en_main = 0; -#line 36 "../../src/hb-ot-shape-complex-myanmar-machine.rl" +#line 36 "hb-ot-shape-complex-myanmar-machine.rl" -#line 93 "../../src/hb-ot-shape-complex-myanmar-machine.rl" +#line 93 "hb-ot-shape-complex-myanmar-machine.rl" #define found_syllable(syllable_type) \ @@ -285,7 +285,7 @@ int cs; hb_glyph_info_t *info = buffer->info; -#line 289 "../../src/hb-ot-shape-complex-myanmar-machine.hh.tmp" +#line 289 "hb-ot-shape-complex-myanmar-machine.hh" { cs = myanmar_syllable_machine_start; ts = 0; @@ -293,7 +293,7 @@ act = 0; } -#line 114 "../../src/hb-ot-shape-complex-myanmar-machine.rl" +#line 114 "hb-ot-shape-complex-myanmar-machine.rl" p = 0; @@ -302,7 +302,7 @@ unsigned int last = 0; unsigned int syllable_serial = 1; -#line 306 "../../src/hb-ot-shape-complex-myanmar-machine.hh.tmp" +#line 306 "hb-ot-shape-complex-myanmar-machine.hh" { int _slen; int _trans; @@ -316,7 +316,7 @@ #line 1 "NONE" {ts = p;} break; -#line 320 "../../src/hb-ot-shape-complex-myanmar-machine.hh.tmp" +#line 320 "hb-ot-shape-complex-myanmar-machine.hh" } _keys = _myanmar_syllable_machine_trans_keys + (cs<<1); @@ -335,38 +335,38 @@ switch ( _myanmar_syllable_machine_trans_actions[_trans] ) { case 7: -#line 85 "../../src/hb-ot-shape-complex-myanmar-machine.rl" +#line 85 "hb-ot-shape-complex-myanmar-machine.rl" {te = p+1;{ found_syllable (consonant_syllable); }} break; case 5: -#line 86 "../../src/hb-ot-shape-complex-myanmar-machine.rl" +#line 86 "hb-ot-shape-complex-myanmar-machine.rl" {te = p+1;{ found_syllable (non_myanmar_cluster); }} break; case 10: -#line 87 "../../src/hb-ot-shape-complex-myanmar-machine.rl" +#line 87 "hb-ot-shape-complex-myanmar-machine.rl" {te = p+1;{ found_syllable (punctuation_cluster); }} break; case 4: -#line 88 "../../src/hb-ot-shape-complex-myanmar-machine.rl" +#line 88 "hb-ot-shape-complex-myanmar-machine.rl" {te = p+1;{ found_syllable (broken_cluster); }} break; case 3: -#line 89 "../../src/hb-ot-shape-complex-myanmar-machine.rl" +#line 89 "hb-ot-shape-complex-myanmar-machine.rl" {te = p+1;{ found_syllable (non_myanmar_cluster); }} break; case 6: -#line 85 "../../src/hb-ot-shape-complex-myanmar-machine.rl" +#line 85 "hb-ot-shape-complex-myanmar-machine.rl" {te = p;p--;{ found_syllable (consonant_syllable); }} break; case 8: -#line 88 "../../src/hb-ot-shape-complex-myanmar-machine.rl" +#line 88 "hb-ot-shape-complex-myanmar-machine.rl" {te = p;p--;{ found_syllable (broken_cluster); }} break; case 9: -#line 89 "../../src/hb-ot-shape-complex-myanmar-machine.rl" +#line 89 "hb-ot-shape-complex-myanmar-machine.rl" {te = p;p--;{ found_syllable (non_myanmar_cluster); }} break; -#line 370 "../../src/hb-ot-shape-complex-myanmar-machine.hh.tmp" +#line 370 "hb-ot-shape-complex-myanmar-machine.hh" } _again: @@ -375,7 +375,7 @@ #line 1 "NONE" {ts = 0;} break; -#line 379 "../../src/hb-ot-shape-complex-myanmar-machine.hh.tmp" +#line 379 "hb-ot-shape-complex-myanmar-machine.hh" } if ( ++p != pe ) @@ -391,7 +391,7 @@ } -#line 123 "../../src/hb-ot-shape-complex-myanmar-machine.rl" +#line 123 "hb-ot-shape-complex-myanmar-machine.rl" }
diff --git a/third_party/harfbuzz-ng/src/hb-ot-shape-complex-myanmar.cc b/third_party/harfbuzz-ng/src/hb-ot-shape-complex-myanmar.cc index 4e912c3..ebd2b40 100644 --- a/third_party/harfbuzz-ng/src/hb-ot-shape-complex-myanmar.cc +++ b/third_party/harfbuzz-ng/src/hb-ot-shape-complex-myanmar.cc
@@ -297,6 +297,8 @@ hb_buffer_t *buffer) { find_syllables (buffer); + foreach_syllable (buffer, start, end) + buffer->unsafe_to_break (start, end); } static int
diff --git a/third_party/harfbuzz-ng/src/hb-ot-shape-complex-thai.cc b/third_party/harfbuzz-ng/src/hb-ot-shape-complex-thai.cc index e75b353..924247f 100644 --- a/third_party/harfbuzz-ng/src/hb-ot-shape-complex-thai.cc +++ b/third_party/harfbuzz-ng/src/hb-ot-shape-complex-thai.cc
@@ -244,6 +244,7 @@ /* At least one of the above/below actions is NOP. */ thai_action_t action = above_edge.action != NOP ? above_edge.action : below_edge.action; + buffer->unsafe_to_break (base, i); if (action == RD) info[base].codepoint = thai_pua_shape (info[base].codepoint, action, font); else
diff --git a/third_party/harfbuzz-ng/src/hb-ot-shape-complex-use.cc b/third_party/harfbuzz-ng/src/hb-ot-shape-complex-use.cc index af68706..a5ab0ab 100644 --- a/third_party/harfbuzz-ng/src/hb-ot-shape-complex-use.cc +++ b/third_party/harfbuzz-ng/src/hb-ot-shape-complex-use.cc
@@ -354,6 +354,8 @@ hb_buffer_t *buffer) { find_syllables (buffer); + foreach_syllable (buffer, start, end) + buffer->unsafe_to_break (start, end); setup_rphf_mask (plan, buffer); setup_topographical_masks (plan, buffer); }
diff --git a/third_party/harfbuzz-ng/src/hb-ot-shape-fallback.cc b/third_party/harfbuzz-ng/src/hb-ot-shape-fallback.cc index ea8312b2..4da53f4 100644 --- a/third_party/harfbuzz-ng/src/hb-ot-shape-fallback.cc +++ b/third_party/harfbuzz-ng/src/hb-ot-shape-fallback.cc
@@ -307,6 +307,9 @@ unsigned int end) { hb_direction_t horiz_dir = HB_DIRECTION_INVALID; + + buffer->unsafe_to_break (base, end); + hb_glyph_extents_t base_extents; if (!font->get_glyph_extents (buffer->info[base].codepoint, &base_extents))
diff --git a/third_party/harfbuzz-ng/src/hb-ot-shape.cc b/third_party/harfbuzz-ng/src/hb-ot-shape.cc index 29f5e58..bc536696 100644 --- a/third_party/harfbuzz-ng/src/hb-ot-shape.cc +++ b/third_party/harfbuzz-ng/src/hb-ot-shape.cc
@@ -509,9 +509,10 @@ /* Merge cluster backward. */ if (cluster < info[j - 1].cluster) { + unsigned int mask = info[i].mask; unsigned int old_cluster = info[j - 1].cluster; for (unsigned k = j; k && info[k - 1].cluster == old_cluster; k--) - info[k - 1].cluster = cluster; + buffer->set_cluster (info[k - 1], cluster, mask); } continue; } @@ -782,6 +783,31 @@ _hb_buffer_deallocate_gsubgpos_vars (c->buffer); } +static inline void +hb_propagate_flags (hb_buffer_t *buffer) +{ + /* Propagate cluster-level glyph flags to be the same on all cluster glyphs. + * Simplifies using them. */ + + if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_UNSAFE_TO_BREAK)) + return; + + hb_glyph_info_t *info = buffer->info; + + foreach_cluster (buffer, start, end) + { + unsigned int mask = 0; + for (unsigned int i = start; i < end; i++) + if (info[i].mask & HB_GLYPH_FLAG_UNSAFE_TO_BREAK) + { + mask = HB_GLYPH_FLAG_UNSAFE_TO_BREAK; + break; + } + if (mask) + for (unsigned int i = start; i < end; i++) + info[i].mask |= mask; + } +} /* Pull it all together! */ @@ -825,6 +851,8 @@ if (c->plan->shaper->postprocess_glyphs) c->plan->shaper->postprocess_glyphs (c->plan, c->buffer, c->font); + hb_propagate_flags (c->buffer); + _hb_buffer_deallocate_unicode_vars (c->buffer); c->buffer->props.direction = c->target_direction;
diff --git a/third_party/harfbuzz-ng/src/hb-shape-plan.cc b/third_party/harfbuzz-ng/src/hb-shape-plan.cc index 61737669..3abf555 100644 --- a/third_party/harfbuzz-ng/src/hb-shape-plan.cc +++ b/third_party/harfbuzz-ng/src/hb-shape-plan.cc
@@ -160,7 +160,7 @@ assert (props->direction != HB_DIRECTION_INVALID); hb_face_make_immutable (face); - shape_plan->default_shaper_list = shaper_list == NULL; + shape_plan->default_shaper_list = !shaper_list; shape_plan->face_unsafe = face; shape_plan->props = *props; shape_plan->num_user_features = num_user_features; @@ -423,7 +423,7 @@ return hb_segment_properties_equal (&shape_plan->props, &proposal->props) && hb_shape_plan_user_features_match (shape_plan, proposal) && hb_shape_plan_coords_match (shape_plan, proposal) && - ((shape_plan->default_shaper_list && proposal->shaper_list == NULL) || + ((shape_plan->default_shaper_list && !proposal->shaper_list) || (shape_plan->shaper_func == proposal->shaper_func)); }
diff --git a/third_party/harfbuzz-ng/src/hb-unicode-private.hh b/third_party/harfbuzz-ng/src/hb-unicode-private.hh index aa86a72..34513e1 100644 --- a/third_party/harfbuzz-ng/src/hb-unicode-private.hh +++ b/third_party/harfbuzz-ng/src/hb-unicode-private.hh
@@ -105,6 +105,10 @@ inline unsigned int modified_combining_class (hb_codepoint_t unicode) { + /* XXX This hack belongs to the Arabic shaper: + * Put HAMZA ABOVE in the same class as SHADDA. */ + if (unlikely (unicode == 0x0654u)) unicode = 0x0651u; + /* XXX This hack belongs to the Myanmar shaper. */ if (unlikely (unicode == 0x1037u)) unicode = 0x103Au;
diff --git a/third_party/webdriver/atoms.cc b/third_party/webdriver/atoms.cc index 0096357..e818dfdf 100644 --- a/third_party/webdriver/atoms.cc +++ b/third_party/webdriver/atoms.cc
@@ -5780,463 +5780,478 @@ "is,b)}}function p(a){var b=q;function c(){}c.prototype=b.prototype;a.oa", "=b.prototype;a.prototype=new c;a.prototype.constructor=a;a.na=function(", "a,c,f){for(var d=Array(arguments.length-2),e=2;e<arguments.length;e++)d", - "[e-2]=arguments[e];return b.prototype[c].apply(a,d)}};var r;function t(", - "a,b){for(var c=a.length,d=m(a)?a.split(\"\"):a,e=0;e<c;e++)e in d&&b.ca", - "ll(void 0,d[e],e,a)}function u(a,b,c){var d=c;t(a,function(c,f){d=b.cal", - "l(void 0,d,c,f,a)});return d}function v(a,b){for(var c=a.length,d=m(a)?", - "a.split(\"\"):a,e=0;e<c;e++)if(e in d&&b.call(void 0,d[e],e,a))return!0", - ";return!1}function ia(a){return Array.prototype.concat.apply([],argumen", - "ts)}function ja(a){var b=a.length;if(0<b){for(var c=Array(b),d=0;d<b;d+", - "+)c[d]=a[d];return c}return[]}\nfunction ka(a,b,c){return 2>=arguments.", - "length?Array.prototype.slice.call(a,b):Array.prototype.slice.call(a,b,c", - ")};function w(a,b){this.x=void 0!==a?a:0;this.y=void 0!==b?b:0}h=w.prot", - "otype;h.clone=function(){return new w(this.x,this.y)};h.toString=functi", - "on(){return\"(\"+this.x+\", \"+this.y+\")\"};h.ceil=function(){this.x=M", - "ath.ceil(this.x);this.y=Math.ceil(this.y);return this};h.floor=function", - "(){this.x=Math.floor(this.x);this.y=Math.floor(this.y);return this};h.r", - "ound=function(){this.x=Math.round(this.x);this.y=Math.round(this.y);ret", - "urn this};\nh.translate=function(a,b){a instanceof w?(this.x+=a.x,this.", - "y+=a.y):(this.x+=Number(a),n(b)&&(this.y+=b));return this};h.scale=func", - "tion(a,b){b=n(b)?b:a;this.x*=a;this.y*=b;return this};function x(a,b){t", - "his.width=a;this.height=b}h=x.prototype;h.clone=function(){return new x", - "(this.width,this.height)};h.toString=function(){return\"(\"+this.width+", - "\" x \"+this.height+\")\"};h.ceil=function(){this.width=Math.ceil(this.", - "width);this.height=Math.ceil(this.height);return this};h.floor=function", - "(){this.width=Math.floor(this.width);this.height=Math.floor(this.height", - ");return this};h.round=function(){this.width=Math.round(this.width);thi", - "s.height=Math.round(this.height);return this};\nh.scale=function(a,b){b", - "=n(b)?b:a;this.width*=a;this.height*=b;return this};function la(a,b,c){", - "function d(c){c&&b.appendChild(m(c)?a.createTextNode(c):c)}for(var e=1;", - "e<c.length;e++){var f=c[e];!ca(f)||da(f)&&0<f.nodeType?d(f):t(ma(f)?ja(", - "f):f,d)}}function na(a,b){if(!a||!b)return!1;if(a.contains&&1==b.nodeTy", - "pe)return a==b||a.contains(b);if(\"undefined\"!=typeof a.compareDocumen", - "tPosition)return a==b||!!(a.compareDocumentPosition(b)&16);for(;b&&a!=b", - ";)b=b.parentNode;return b==a}\nfunction oa(a,b){if(a==b)return 0;if(a.c", - "ompareDocumentPosition)return a.compareDocumentPosition(b)&2?1:-1;if(\"", - "sourceIndex\"in a||a.parentNode&&\"sourceIndex\"in a.parentNode){var c=", - "1==a.nodeType,d=1==b.nodeType;if(c&&d)return a.sourceIndex-b.sourceInde", - "x;var e=a.parentNode,f=b.parentNode;return e==f?pa(a,b):!c&&na(e,b)?-1*", - "qa(a,b):!d&&na(f,a)?qa(b,a):(c?a.sourceIndex:e.sourceIndex)-(d?b.source", - "Index:f.sourceIndex)}d=z(a);c=d.createRange();c.selectNode(a);c.collaps", - "e(!0);a=d.createRange();a.selectNode(b);\na.collapse(!0);return c.compa", - "reBoundaryPoints(k.Range.START_TO_END,a)}function qa(a,b){var c=a.paren", - "tNode;if(c==b)return-1;for(;b.parentNode!=c;)b=b.parentNode;return pa(b", - ",a)}function pa(a,b){for(;b=b.previousSibling;)if(b==a)return-1;return ", - "1}function z(a){return 9==a.nodeType?a:a.ownerDocument||a.document}func", - "tion ma(a){if(a&&\"number\"==typeof a.length){if(da(a))return\"function", - "\"==typeof a.item||\"string\"==typeof a.item;if(\"function\"==ba(a))ret", - "urn\"function\"==typeof a.item}return!1}\nfunction A(a){this.D=a||k.doc", - "ument||document}h=A.prototype;h.getElementsByTagName=function(a,b){retu", - "rn(b||this.D).getElementsByTagName(String(a))};function ra(a){a=a.D;a=(", - "a.parentWindow||a.defaultView||window).document;a=\"CSS1Compat\"==a.com", - "patMode?a.documentElement:a.body;return new x(a.clientWidth,a.clientHei", - "ght)}h.createElement=function(a){return this.D.createElement(String(a))", - "};h.createTextNode=function(a){return this.D.createTextNode(String(a))}", - ";h.appendChild=function(a,b){a.appendChild(b)};\nh.append=function(a,b)", - "{la(z(a),a,arguments)};h.canHaveChildren=function(a){if(1!=a.nodeType)r", - "eturn!1;switch(a.tagName){case \"APPLET\":case \"AREA\":case \"BASE\":c", - "ase \"BR\":case \"COL\":case \"COMMAND\":case \"EMBED\":case \"FRAME\":", - "case \"HR\":case \"IMG\":case \"INPUT\":case \"IFRAME\":case \"ISINDEX", - "\":case \"KEYGEN\":case \"LINK\":case \"NOFRAMES\":case \"NOSCRIPT\":ca", - "se \"META\":case \"OBJECT\":case \"PARAM\":case \"SCRIPT\":case \"SOURC", - "E\":case \"STYLE\":case \"TRACK\":case \"WBR\":return!1}return!0};\nh.r", - "emoveNode=function(a){return a&&a.parentNode?a.parentNode.removeChild(a", - "):null};h.contains=na;/*\n\n The MIT License\n\n Copyright (c) 2007 Cyb", - "ozu Labs, Inc.\n Copyright (c) 2012 Google Inc.\n\n Permission is hereb", - "y granted, free of charge, to any person obtaining a copy\n of this sof", - "tware and associated documentation files (the \"Software\"), to\n deal ", - "in the Software without restriction, including without limitation the\n", - " rights to use, copy, modify, merge, publish, distribute, sublicense, a", - "nd/or\n sell copies of the Software, and to permit persons to whom the ", - "Software is\n furnished to do so, subject to the following conditions:", - "\n\n The above copyright notice and this permission notice shall be inc", - "luded in\n all copies or substantial portions of the Software.\n\n THE ", - "SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS O", - "R\n IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABI", - "LITY,\n FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVE", - "NT SHALL THE\n AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DA", - "MAGES OR OTHER\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR O", - "THERWISE, ARISING\n FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR ", - "THE USE OR OTHER DEALINGS\n IN THE SOFTWARE.\n*/\nfunction B(a,b,c){thi", - "s.l=a;this.la=b||1;this.j=c||1};function C(a){this.T=a;this.J=0}functio", - "n sa(a){a=a.match(ta);for(var b=0;b<a.length;b++)ua.test(a[b])&&a.splic", - "e(b,1);return new C(a)}var ta=/\\$?(?:(?![0-9-\\.])(?:\\*|[\\w-\\.]+):)", - "?(?![0-9-\\.])(?:\\*|[\\w-\\.]+)|\\/\\/|\\.\\.|::|\\d+(?:\\.\\d*)?|\\.", - "\\d+|\"[^\"]*\"|'[^']*'|[!<>]=|\\s+|./g,ua=/^\\s/;function D(a,b){retur", - "n a.T[a.J+(b||0)]}C.prototype.next=function(){return this.T[this.J++]};", - "C.prototype.back=function(){this.J--};C.prototype.empty=function(){retu", - "rn this.T.length<=this.J};function E(a){var b=null,c=a.nodeType;1==c&&(", - "b=a.textContent,b=void 0==b||null==b?a.innerText:b,b=void 0==b||null==b", - "?\"\":b);if(\"string\"!=typeof b)if(9==c||1==c){a=9==c?a.documentElemen", - "t:a.firstChild;for(var c=0,d=[],b=\"\";a;){do 1!=a.nodeType&&(b+=a.node", - "Value),d[c++]=a;while(a=a.firstChild);for(;c&&!(a=d[--c].nextSibling);)", - ";}}else b=a.nodeValue;return\"\"+b}\nfunction F(a,b,c){if(null===b)retu", - "rn!0;try{if(!a.getAttribute)return!1}catch(d){return!1}return null==c?!", - "!a.getAttribute(b):a.getAttribute(b,2)==c}function G(a,b,c,d,e){return ", - "va.call(null,a,b,m(c)?c:null,m(d)?d:null,e||new H)}\nfunction va(a,b,c,", - "d,e){b.getElementsByName&&d&&\"name\"==c?(b=b.getElementsByName(d),t(b,", - "function(b){a.matches(b)&&e.add(b)})):b.getElementsByClassName&&d&&\"cl", - "ass\"==c?(b=b.getElementsByClassName(d),t(b,function(b){b.className==d&", - "&a.matches(b)&&e.add(b)})):a instanceof I?wa(a,b,c,d,e):b.getElementsBy", - "TagName&&(b=b.getElementsByTagName(a.getName()),t(b,function(a){F(a,c,d", - ")&&e.add(a)}));return e}function wa(a,b,c,d,e){for(b=b.firstChild;b;b=b", - ".nextSibling)F(b,c,d)&&a.matches(b)&&e.add(b),wa(a,b,c,d,e)};function H", - "(){this.j=this.g=null;this.F=0}function xa(a){this.node=a;this.next=thi", - "s.w=null}function za(a,b){if(!a.g)return b;if(!b.g)return a;var c=a.g;b", - "=b.g;for(var d=null,e,f=0;c&&b;)c.node==b.node?(e=c,c=c.next,b=b.next):", - "0<oa(c.node,b.node)?(e=b,b=b.next):(e=c,c=c.next),(e.w=d)?d.next=e:a.g=", - "e,d=e,f++;for(e=c||b;e;)e.w=d,d=d.next=e,f++,e=e.next;a.j=d;a.F=f;retur", - "n a}H.prototype.unshift=function(a){a=new xa(a);a.next=this.g;this.j?th", - "is.g.w=a:this.g=this.j=a;this.g=a;this.F++};\nH.prototype.add=function(", - "a){a=new xa(a);a.w=this.j;this.g?this.j.next=a:this.g=this.j=a;this.j=a", - ";this.F++};function J(a){return(a=a.g)?a.node:null}H.prototype.m=functi", - "on(){return this.F};function K(a){return(a=J(a))?E(a):\"\"}H.prototype.", - "iterator=function(a){return new Aa(this,!!a)};function Aa(a,b){this.ha=", - "a;this.U=(this.A=b)?a.j:a.g;this.P=null}Aa.prototype.next=function(){va", - "r a=this.U;if(null==a)return null;var b=this.P=a;this.U=this.A?a.w:a.ne", - "xt;return b.node};\nAa.prototype.remove=function(){var a=this.ha,b=this", - ".P;if(!b)throw Error(\"Next must be called at least once before remove.", - "\");var c=b.w,b=b.next;c?c.next=b:a.g=b;b?b.w=c:a.j=c;a.F--;this.P=null", - "};function q(a){this.f=a;this.h=this.o=!1;this.G=null}function L(a){ret", - "urn\"\\n \"+a.toString().split(\"\\n\").join(\"\\n \")}q.prototype.c=", - "function(){return this.o};function Ba(a,b){a.o=b}function Ca(a,b){a.h=b", - "}q.prototype.u=function(){return this.G};function M(a,b){a=a.evaluate(b", - ");return a instanceof H?+K(a):+a}function N(a,b){a=a.evaluate(b);return", - " a instanceof H?K(a):\"\"+a}function O(a,b){a=a.evaluate(b);return a in", - "stanceof H?!!a.m():!!a};function P(a,b,c){q.call(this,a.f);this.S=a;thi", - "s.X=b;this.ba=c;this.o=b.c()||c.c();this.h=b.h||c.h;this.S==Da&&(c.h||c", - ".c()||4==c.f||0==c.f||!b.u()?b.h||b.c()||4==b.f||0==b.f||!c.u()||(this.", - "G={name:c.u().name,C:b}):this.G={name:b.u().name,C:c})}p(P);\nfunction ", - "Q(a,b,c,d,e){b=b.evaluate(d);c=c.evaluate(d);var f;if(b instanceof H&&c", - " instanceof H){b=b.iterator();for(d=b.next();d;d=b.next())for(e=c.itera", - "tor(),f=e.next();f;f=e.next())if(a(E(d),E(f)))return!0;return!1}if(b in", - "stanceof H||c instanceof H){b instanceof H?(e=b,d=c):(e=c,d=b);f=e.iter", - "ator();for(var g=typeof d,l=f.next();l;l=f.next()){switch(g){case \"num", - "ber\":l=+E(l);break;case \"boolean\":l=!!E(l);break;case \"string\":l=E", - "(l);break;default:throw Error(\"Illegal primitive type for comparison.", - "\");\n}if(e==b&&a(l,d)||e==c&&a(d,l))return!0}return!1}return e?\"boole", - "an\"==typeof b||\"boolean\"==typeof c?a(!!b,!!c):\"number\"==typeof b||", - "\"number\"==typeof c?a(+b,+c):a(b,c):a(+b,+c)}P.prototype.evaluate=func", - "tion(a){return this.S.v(this.X,this.ba,a)};P.prototype.toString=functio", - "n(){var a=\"Binary Expression: \"+this.S,a=a+L(this.X);return a+=L(this", - ".ba)};function Ea(a,b,c,d){this.ka=a;this.$=b;this.f=c;this.v=d}Ea.prot", - "otype.toString=function(){return this.ka};var Fa={};\nfunction R(a,b,c,", - "d){if(Fa.hasOwnProperty(a))throw Error(\"Binary operator already create", - "d: \"+a);a=new Ea(a,b,c,d);return Fa[a.toString()]=a}R(\"div\",6,1,func", - "tion(a,b,c){return M(a,c)/M(b,c)});R(\"mod\",6,1,function(a,b,c){return", - " M(a,c)%M(b,c)});R(\"*\",6,1,function(a,b,c){return M(a,c)*M(b,c)});R(", - "\"+\",5,1,function(a,b,c){return M(a,c)+M(b,c)});R(\"-\",5,1,function(a", - ",b,c){return M(a,c)-M(b,c)});R(\"<\",4,2,function(a,b,c){return Q(funct", - "ion(a,b){return a<b},a,b,c)});\nR(\">\",4,2,function(a,b,c){return Q(fu", - "nction(a,b){return a>b},a,b,c)});R(\"<=\",4,2,function(a,b,c){return Q(", - "function(a,b){return a<=b},a,b,c)});R(\">=\",4,2,function(a,b,c){return", - " Q(function(a,b){return a>=b},a,b,c)});var Da=R(\"=\",3,2,function(a,b,", - "c){return Q(function(a,b){return a==b},a,b,c,!0)});R(\"!=\",3,2,functio", - "n(a,b,c){return Q(function(a,b){return a!=b},a,b,c,!0)});R(\"and\",2,2,", - "function(a,b,c){return O(a,c)&&O(b,c)});R(\"or\",1,2,function(a,b,c){re", - "turn O(a,c)||O(b,c)});function Ga(a,b){if(b.m()&&4!=a.f)throw Error(\"P", - "rimary expression must evaluate to nodeset if filter has predicate(s).", - "\");q.call(this,a.f);this.aa=a;this.b=b;this.o=a.c();this.h=a.h}p(Ga);G", - "a.prototype.evaluate=function(a){a=this.aa.evaluate(a);return Ha(this.b", - ",a)};Ga.prototype.toString=function(){var a=\"Filter:\"+L(this.aa);retu", - "rn a+=L(this.b)};function Ia(a,b){if(b.length<a.Z)throw Error(\"Functio", - "n \"+a.i+\" expects at least\"+a.Z+\" arguments, \"+b.length+\" given\"", - ");if(null!==a.R&&b.length>a.R)throw Error(\"Function \"+a.i+\" expects ", - "at most \"+a.R+\" arguments, \"+b.length+\" given\");a.ia&&t(b,function", - "(b,d){if(4!=b.f)throw Error(\"Argument \"+d+\" to function \"+a.i+\" is", - " not of type Nodeset: \"+b);});q.call(this,a.f);this.I=a;this.N=b;Ba(th", - "is,a.o||v(b,function(a){return a.c()}));Ca(this,a.ga&&!b.length||a.fa&&", - "!!b.length||v(b,function(a){return a.h}))}p(Ia);\nIa.prototype.evaluate", - "=function(a){return this.I.v.apply(null,ia(a,this.N))};Ia.prototype.toS", - "tring=function(){var a=\"Function: \"+this.I;if(this.N.length)var b=u(t", - "his.N,function(a,b){return a+L(b)},\"Arguments:\"),a=a+L(b);return a};f", - "unction Ja(a,b,c,d,e,f,g,l,y){this.i=a;this.f=b;this.o=c;this.ga=d;this", - ".fa=e;this.v=f;this.Z=g;this.R=void 0!==l?l:g;this.ia=!!y}Ja.prototype.", - "toString=function(){return this.i};var Ka={};\nfunction S(a,b,c,d,e,f,g", - ",l){if(Ka.hasOwnProperty(a))throw Error(\"Function already created: \"+", - "a+\".\");Ka[a]=new Ja(a,b,c,d,!1,e,f,g,l)}S(\"boolean\",2,!1,!1,functio", - "n(a,b){return O(b,a)},1);S(\"ceiling\",1,!1,!1,function(a,b){return Mat", - "h.ceil(M(b,a))},1);S(\"concat\",3,!1,!1,function(a,b){return u(ka(argum", - "ents,1),function(b,d){return b+N(d,a)},\"\")},2,null);S(\"contains\",2,", - "!1,!1,function(a,b,c){b=N(b,a);a=N(c,a);return-1!=b.indexOf(a)},2);S(\"", - "count\",1,!1,!1,function(a,b){return b.evaluate(a).m()},1,1,!0);\nS(\"f", - "alse\",2,!1,!1,function(){return!1},0);S(\"floor\",1,!1,!1,function(a,b", - "){return Math.floor(M(b,a))},1);S(\"id\",4,!1,!1,function(a,b){var c=a.", - "l,d=9==c.nodeType?c:c.ownerDocument;a=N(b,a).split(/\\s+/);var e=[];t(a", - ",function(a){a=d.getElementById(a);var b;if(!(b=!a)){a:if(m(e))b=m(a)&&", - "1==a.length?e.indexOf(a,0):-1;else{for(b=0;b<e.length;b++)if(b in e&&e[", - "b]===a)break a;b=-1}b=0<=b}b||e.push(a)});e.sort(oa);var f=new H;t(e,fu", - "nction(a){f.add(a)});return f},1);S(\"lang\",2,!1,!1,function(){return!", - "1},1);\nS(\"last\",1,!0,!1,function(a){if(1!=arguments.length)throw Err", - "or(\"Function last expects ()\");return a.j},0);S(\"local-name\",3,!1,!", - "0,function(a,b){return(a=b?J(b.evaluate(a)):a.l)?a.localName||a.nodeNam", - "e.toLowerCase():\"\"},0,1,!0);S(\"name\",3,!1,!0,function(a,b){return(a", - "=b?J(b.evaluate(a)):a.l)?a.nodeName.toLowerCase():\"\"},0,1,!0);S(\"nam", - "espace-uri\",3,!0,!1,function(){return\"\"},0,1,!0);\nS(\"normalize-spa", - "ce\",3,!1,!0,function(a,b){return(b?N(b,a):E(a.l)).replace(/[\\s\\xa0]+", - "/g,\" \").replace(/^\\s+|\\s+$/g,\"\")},0,1);S(\"not\",2,!1,!1,function", - "(a,b){return!O(b,a)},1);S(\"number\",1,!1,!0,function(a,b){return b?M(b", - ",a):+E(a.l)},0,1);S(\"position\",1,!0,!1,function(a){return a.la},0);S(", - "\"round\",1,!1,!1,function(a,b){return Math.round(M(b,a))},1);S(\"start", - "s-with\",2,!1,!1,function(a,b,c){b=N(b,a);a=N(c,a);return 0==b.lastInde", - "xOf(a,0)},2);S(\"string\",3,!1,!0,function(a,b){return b?N(b,a):E(a.l)}", - ",0,1);\nS(\"string-length\",1,!1,!0,function(a,b){return(b?N(b,a):E(a.l", - ")).length},0,1);S(\"substring\",3,!1,!1,function(a,b,c,d){c=M(c,a);if(i", - "sNaN(c)||Infinity==c||-Infinity==c)return\"\";d=d?M(d,a):Infinity;if(is", - "NaN(d)||-Infinity===d)return\"\";c=Math.round(c)-1;var e=Math.max(c,0);", - "a=N(b,a);return Infinity==d?a.substring(e):a.substring(e,c+Math.round(d", - "))},2,3);S(\"substring-after\",3,!1,!1,function(a,b,c){b=N(b,a);a=N(c,a", - ");c=b.indexOf(a);return-1==c?\"\":b.substring(c+a.length)},2);\nS(\"sub", - "string-before\",3,!1,!1,function(a,b,c){b=N(b,a);a=N(c,a);a=b.indexOf(a", - ");return-1==a?\"\":b.substring(0,a)},2);S(\"sum\",1,!1,!1,function(a,b)", - "{a=b.evaluate(a).iterator();b=0;for(var c=a.next();c;c=a.next())b+=+E(c", - ");return b},1,1,!0);S(\"translate\",3,!1,!1,function(a,b,c,d){b=N(b,a);", - "c=N(c,a);var e=N(d,a);d={};for(var f=0;f<c.length;f++)a=c.charAt(f),a i", - "n d||(d[a]=e.charAt(f));c=\"\";for(f=0;f<b.length;f++)a=b.charAt(f),c+=", - "a in d?d[a]:a;return c},3);S(\"true\",2,!1,!1,function(){return!0},0);f", - "unction I(a,b){this.da=a;this.Y=void 0!==b?b:null;this.B=null;switch(a)", - "{case \"comment\":this.B=8;break;case \"text\":this.B=3;break;case \"pr", - "ocessing-instruction\":this.B=7;break;case \"node\":break;default:throw", - " Error(\"Unexpected argument\");}}function La(a){return\"comment\"==a||", - "\"text\"==a||\"processing-instruction\"==a||\"node\"==a}I.prototype.mat", - "ches=function(a){return null===this.B||this.B==a.nodeType};I.prototype.", - "getName=function(){return this.da};\nI.prototype.toString=function(){va", - "r a=\"Kind Test: \"+this.da;null===this.Y||(a+=L(this.Y));return a};fun", - "ction Ma(a){q.call(this,3);this.ca=a.substring(1,a.length-1)}p(Ma);Ma.p", - "rototype.evaluate=function(){return this.ca};Ma.prototype.toString=func", - "tion(){return\"Literal: \"+this.ca};function T(a,b){this.i=a.toLowerCas", - "e();a=\"*\"==this.i?\"*\":\"http://www.w3.org/1999/xhtml\";this.K=b?b.t", - "oLowerCase():a}T.prototype.matches=function(a){var b=a.nodeType;if(1!=b", - "&&2!=b)return!1;b=void 0!==a.localName?a.localName:a.nodeName;return\"*", - "\"!=this.i&&this.i!=b.toLowerCase()?!1:\"*\"==this.K?!0:this.K==(a.name", - "spaceURI?a.namespaceURI.toLowerCase():\"http://www.w3.org/1999/xhtml\")", - "};T.prototype.getName=function(){return this.i};\nT.prototype.toString=", - "function(){return\"Name Test: \"+(\"http://www.w3.org/1999/xhtml\"==thi", - "s.K?\"\":this.K+\":\")+this.i};function Na(a){q.call(this,1);this.ea=a}", - "p(Na);Na.prototype.evaluate=function(){return this.ea};Na.prototype.toS", - "tring=function(){return\"Number: \"+this.ea};function Oa(a,b){q.call(th", - "is,a.f);this.W=a;this.H=b;this.o=a.c();this.h=a.h;1==this.H.length&&(a=", - "this.H[0],a.O||a.s!=Pa||(a=a.M,\"*\"!=a.getName()&&(this.G={name:a.getN", - "ame(),C:null})))}p(Oa);function U(){q.call(this,4)}p(U);U.prototype.eva", - "luate=function(a){var b=new H;a=a.l;9==a.nodeType?b.add(a):b.add(a.owne", - "rDocument);return b};U.prototype.toString=function(){return\"Root Helpe", - "r Expression\"};function Qa(){q.call(this,4)}p(Qa);Qa.prototype.evaluat", - "e=function(a){var b=new H;b.add(a.l);return b};\nQa.prototype.toString=", - "function(){return\"Context Helper Expression\"};function Ra(a){return\"", - "/\"==a||\"//\"==a}\nOa.prototype.evaluate=function(a){var b=this.W.eval", - "uate(a);if(!(b instanceof H))throw Error(\"Filter expression must evalu", - "ate to nodeset.\");a=this.H;for(var c=0,d=a.length;c<d&&b.m();c++){var ", - "e=a[c],f=b.iterator(e.s.A);if(e.c()||e.s!=Sa)if(e.c()||e.s!=Ta){var g=f", - ".next();for(b=e.evaluate(new B(g));null!=(g=f.next());)g=e.evaluate(new", - " B(g)),b=za(b,g)}else g=f.next(),b=e.evaluate(new B(g));else{for(g=f.ne", - "xt();(b=f.next())&&(!g.contains||g.contains(b))&&b.compareDocumentPosit", - "ion(g)&8;g=b);b=e.evaluate(new B(g))}}return b};\nOa.prototype.toString", - "=function(){var a=\"Path Expression:\"+L(this.W);if(this.H.length){var ", - "b=u(this.H,function(a,b){return a+L(b)},\"Steps:\");a+=L(b)}return a};f", - "unction V(a,b){this.b=a;this.A=!!b}function Ha(a,b,c){for(c=c||0;c<a.b.", - "length;c++)for(var d=a.b[c],e=b.iterator(),f=b.m(),g,l=0;g=e.next();l++", - "){var y=a.A?f-l:l+1;g=d.evaluate(new B(g,y,f));if(\"number\"==typeof g)", - "y=y==g;else if(\"string\"==typeof g||\"boolean\"==typeof g)y=!!g;else i", - "f(g instanceof H)y=0<g.m();else throw Error(\"Predicate.evaluate return", - "ed an unexpected type.\");y||e.remove()}return b}V.prototype.u=function", - "(){return 0<this.b.length?this.b[0].u():null};\nV.prototype.c=function(", - "){for(var a=0;a<this.b.length;a++){var b=this.b[a];if(b.c()||1==b.f||0=", - "=b.f)return!0}return!1};V.prototype.m=function(){return this.b.length};", - "V.prototype.toString=function(){return u(this.b,function(a,b){return a+", - "L(b)},\"Predicates:\")};function W(a,b,c,d){q.call(this,4);this.s=a;thi", - "s.M=b;this.b=c||new V([]);this.O=!!d;b=this.b.u();a.ma&&b&&(this.G={nam", - "e:b.name,C:b.C});this.o=this.b.c()}p(W);\nW.prototype.evaluate=function", - "(a){var b=a.l,c=this.u(),d=null,e=null,f=0;c&&(d=c.name,e=c.C?N(c.C,a):", - "null,f=1);if(this.O)if(this.c()||this.s!=Ua)if(b=(new W(Va,new I(\"node", - "\"))).evaluate(a).iterator(),c=b.next())for(a=this.v(c,d,e,f);null!=(c=", - "b.next());)a=za(a,this.v(c,d,e,f));else a=new H;else a=G(this.M,b,d,e),", - "a=Ha(this.b,a,f);else a=this.v(a.l,d,e,f);return a};W.prototype.v=funct", - "ion(a,b,c,d){a=this.s.I(this.M,a,b,c);return a=Ha(this.b,a,d)};\nW.prot", - "otype.toString=function(){var a=\"Step:\"+L(\"Operator: \"+(this.O?\"//", - "\":\"/\"));this.s.i&&(a+=L(\"Axis: \"+this.s));a+=L(this.M);if(this.b.m", - "()){var b=u(this.b.b,function(a,b){return a+L(b)},\"Predicates:\");a+=L", - "(b)}return a};function Wa(a,b,c,d){this.i=a;this.I=b;this.A=c;this.ma=d", - "}Wa.prototype.toString=function(){return this.i};var Xa={};function X(a", - ",b,c,d){if(Xa.hasOwnProperty(a))throw Error(\"Axis already created: \"+", - "a);b=new Wa(a,b,c,!!d);return Xa[a]=b}\nX(\"ancestor\",function(a,b){fo", - "r(var c=new H;b=b.parentNode;)a.matches(b)&&c.unshift(b);return c},!0);", - "X(\"ancestor-or-self\",function(a,b){var c=new H;do a.matches(b)&&c.uns", - "hift(b);while(b=b.parentNode);return c},!0);\nvar Pa=X(\"attribute\",fu", - "nction(a,b){var c=new H,d=a.getName();if(b=b.attributes)if(a instanceof", - " I&&null===a.B||\"*\"==d)for(d=0;a=b[d];d++)c.add(a);else(a=b.getNamedI", - "tem(d))&&c.add(a);return c},!1),Ua=X(\"child\",function(a,b,c,d,e){c=m(", - "c)?c:null;d=m(d)?d:null;e=e||new H;for(b=b.firstChild;b;b=b.nextSibling", - ")F(b,c,d)&&a.matches(b)&&e.add(b);return e},!1,!0);X(\"descendant\",G,!", - "1,!0);\nvar Va=X(\"descendant-or-self\",function(a,b,c,d){var e=new H;F", - "(b,c,d)&&a.matches(b)&&e.add(b);return G(a,b,c,d,e)},!1,!0),Sa=X(\"foll", - "owing\",function(a,b,c,d){var e=new H;do for(var f=b;f=f.nextSibling;)F", - "(f,c,d)&&a.matches(f)&&e.add(f),e=G(a,f,c,d,e);while(b=b.parentNode);re", - "turn e},!1,!0);X(\"following-sibling\",function(a,b){for(var c=new H;b=", - "b.nextSibling;)a.matches(b)&&c.add(b);return c},!1);X(\"namespace\",fun", - "ction(){return new H},!1);\nvar Ya=X(\"parent\",function(a,b){var c=new", - " H;if(9==b.nodeType)return c;if(2==b.nodeType)return c.add(b.ownerEleme", - "nt),c;b=b.parentNode;a.matches(b)&&c.add(b);return c},!1),Ta=X(\"preced", - "ing\",function(a,b,c,d){var e=new H,f=[];do f.unshift(b);while(b=b.pare", - "ntNode);for(var g=1,l=f.length;g<l;g++){var y=[];for(b=f[g];b=b.previou", - "sSibling;)y.unshift(b);for(var ya=0,sb=y.length;ya<sb;ya++)b=y[ya],F(b,", - "c,d)&&a.matches(b)&&e.add(b),e=G(a,b,c,d,e)}return e},!0,!0);\nX(\"prec", - "eding-sibling\",function(a,b){for(var c=new H;b=b.previousSibling;)a.ma", - "tches(b)&&c.unshift(b);return c},!0);var Za=X(\"self\",function(a,b){va", - "r c=new H;a.matches(b)&&c.add(b);return c},!1);function $a(a){q.call(th", - "is,1);this.V=a;this.o=a.c();this.h=a.h}p($a);$a.prototype.evaluate=func", - "tion(a){return-M(this.V,a)};$a.prototype.toString=function(){return\"Un", - "ary Expression: -\"+L(this.V)};function ab(a){q.call(this,4);this.L=a;B", - "a(this,v(this.L,function(a){return a.c()}));Ca(this,v(this.L,function(a", - "){return a.h}))}p(ab);ab.prototype.evaluate=function(a){var b=new H;t(t", - "his.L,function(c){c=c.evaluate(a);if(!(c instanceof H))throw Error(\"Pa", - "th expression must evaluate to NodeSet.\");b=za(b,c)});return b};ab.pro", - "totype.toString=function(){return u(this.L,function(a,b){return a+L(b)}", - ",\"Union Expression:\")};function bb(a,b){this.a=a;this.ja=b}function c", - "b(a){for(var b,c=[];;){Y(a,\"Missing right hand side of binary expressi", - "on.\");b=db(a);var d=a.a.next();if(!d)break;var e=(d=Fa[d]||null)&&d.$;", - "if(!e){a.a.back();break}for(;c.length&&e<=c[c.length-1].$;)b=new P(c.po", - "p(),c.pop(),b);c.push(b,d)}for(;c.length;)b=new P(c.pop(),c.pop(),b);re", - "turn b}function Y(a,b){if(a.a.empty())throw Error(b);}function eb(a,b){", - "a=a.a.next();if(a!=b)throw Error(\"Bad token, expected: \"+b+\" got: \"", - "+a);}\nfunction fb(a){a=a.a.next();if(\")\"!=a)throw Error(\"Bad token:", - " \"+a);}function gb(a){a=a.a.next();if(2>a.length)throw Error(\"Unclose", - "d literal string\");return new Ma(a)}\nfunction hb(a){var b=[];if(Ra(D(", - "a.a))){var c=a.a.next();var d=D(a.a);if(\"/\"==c&&(a.a.empty()||\".\"!=", - "d&&\"..\"!=d&&\"@\"!=d&&\"*\"!=d&&!/(?![0-9])[\\w]/.test(d)))return new", - " U;d=new U;Y(a,\"Missing next location step.\");c=ib(a,c);b.push(c)}els", - "e{a:{c=D(a.a);d=c.charAt(0);switch(d){case \"$\":throw Error(\"Variable", - " reference not allowed in HTML XPath\");case \"(\":a.a.next();c=cb(a);Y", - "(a,'unclosed \"(\"');eb(a,\")\");break;case '\"':case \"'\":c=gb(a);bre", - "ak;default:if(isNaN(+c))if(!La(c)&&/(?![0-9])[\\w]/.test(d)&&\"(\"==D(a", - ".a,\n1)){c=a.a.next();c=Ka[c]||null;a.a.next();for(d=[];\")\"!=D(a.a);)", - "{Y(a,\"Missing function argument list.\");d.push(cb(a));if(\",\"!=D(a.a", - "))break;a.a.next()}Y(a,\"Unclosed function argument list.\");fb(a);c=ne", - "w Ia(c,d)}else{c=null;break a}else c=new Na(+a.a.next())}\"[\"==D(a.a)&", - "&(d=new V(jb(a)),c=new Ga(c,d))}if(c)if(Ra(D(a.a)))d=c;else return c;el", - "se c=ib(a,\"/\"),d=new Qa,b.push(c)}for(;Ra(D(a.a));)c=a.a.next(),Y(a,", - "\"Missing next location step.\"),c=ib(a,c),b.push(c);return new Oa(d,b)", - "}\nfunction ib(a,b){if(\"/\"!=b&&\"//\"!=b)throw Error('Step op should ", - "be \"/\" or \"//\"');if(\".\"==D(a.a)){var c=new W(Za,new I(\"node\"));", - "a.a.next();return c}if(\"..\"==D(a.a))return c=new W(Ya,new I(\"node\")", - "),a.a.next(),c;if(\"@\"==D(a.a)){var d=Pa;a.a.next();Y(a,\"Missing attr", - "ibute name\")}else if(\"::\"==D(a.a,1)){if(!/(?![0-9])[\\w]/.test(D(a.a", - ").charAt(0)))throw Error(\"Bad token: \"+a.a.next());var e=a.a.next();d", - "=Xa[e]||null;if(!d)throw Error(\"No axis with name: \"+e);a.a.next();Y(", - "a,\"Missing node name\")}else d=Ua;e=\nD(a.a);if(/(?![0-9])[\\w\\*]/.te", - "st(e.charAt(0)))if(\"(\"==D(a.a,1)){if(!La(e))throw Error(\"Invalid nod", - "e type: \"+e);e=a.a.next();if(!La(e))throw Error(\"Invalid type name: ", - "\"+e);eb(a,\"(\");Y(a,\"Bad nodetype\");var f=D(a.a).charAt(0),g=null;i", - "f('\"'==f||\"'\"==f)g=gb(a);Y(a,\"Bad nodetype\");fb(a);e=new I(e,g)}el", - "se if(e=a.a.next(),f=e.indexOf(\":\"),-1==f)e=new T(e);else{var g=e.sub", - "string(0,f);if(\"*\"==g)var l=\"*\";else if(l=a.ja(g),!l)throw Error(\"", - "Namespace prefix not declared: \"+g);e=e.substr(f+1);e=new T(e,l)}else ", - "throw Error(\"Bad token: \"+\na.a.next());a=new V(jb(a),d.A);return c||", - "new W(d,e,a,\"//\"==b)}function jb(a){for(var b=[];\"[\"==D(a.a);){a.a.", - "next();Y(a,\"Missing predicate expression.\");var c=cb(a);b.push(c);Y(a", - ",\"Unclosed predicate expression.\");eb(a,\"]\")}return b}function db(a", - "){if(\"-\"==D(a.a))return a.a.next(),new $a(db(a));var b=hb(a);if(\"|\"", - "!=D(a.a))a=b;else{for(b=[b];\"|\"==a.a.next();)Y(a,\"Missing next union", - " location path.\"),b.push(hb(a));a.a.back();a=new ab(b)}return a};funct", - "ion kb(a){switch(a.nodeType){case 1:return ha(lb,a);case 9:return kb(a.", - "documentElement);case 11:case 10:case 6:case 12:return mb;default:retur", - "n a.parentNode?kb(a.parentNode):mb}}function mb(){return null}function ", - "lb(a,b){if(a.prefix==b)return a.namespaceURI||\"http://www.w3.org/1999/", - "xhtml\";var c=a.getAttributeNode(\"xmlns:\"+b);return c&&c.specified?c.", - "value||null:a.parentNode&&9!=a.parentNode.nodeType?lb(a.parentNode,b):n", - "ull};function nb(a,b){if(!a.length)throw Error(\"Empty XPath expression", - ".\");a=sa(a);if(a.empty())throw Error(\"Invalid XPath expression.\");b?", - "\"function\"==ba(b)||(b=ga(b.lookupNamespaceURI,b)):b=function(){return", - " null};var c=cb(new bb(a,b));if(!a.empty())throw Error(\"Bad token: \"+", - "a.next());this.evaluate=function(a,b){a=c.evaluate(new B(a));return new", - " Z(a,b)}}\nfunction Z(a,b){if(0==b)if(a instanceof H)b=4;else if(\"stri", - "ng\"==typeof a)b=2;else if(\"number\"==typeof a)b=1;else if(\"boolean\"", - "==typeof a)b=3;else throw Error(\"Unexpected evaluation result.\");if(2", - "!=b&&1!=b&&3!=b&&!(a instanceof H))throw Error(\"value could not be con", - "verted to the specified type\");this.resultType=b;switch(b){case 2:this", - ".stringValue=a instanceof H?K(a):\"\"+a;break;case 1:this.numberValue=a", - " instanceof H?+K(a):+a;break;case 3:this.booleanValue=a instanceof H?0<", - "a.m():!!a;break;case 4:case 5:case 6:case 7:var c=\na.iterator();var d=", - "[];for(var e=c.next();e;e=c.next())d.push(e);this.snapshotLength=a.m();", - "this.invalidIteratorState=!1;break;case 8:case 9:this.singleNodeValue=J", - "(a);break;default:throw Error(\"Unknown XPathResult type.\");}var f=0;t", - "his.iterateNext=function(){if(4!=b&&5!=b)throw Error(\"iterateNext call", - "ed with wrong result type\");return f>=d.length?null:d[f++]};this.snaps", - "hotItem=function(a){if(6!=b&&7!=b)throw Error(\"snapshotItem called wit", - "h wrong result type\");return a>=d.length||0>a?null:d[a]}}\nZ.ANY_TYPE=", - "0;Z.NUMBER_TYPE=1;Z.STRING_TYPE=2;Z.BOOLEAN_TYPE=3;Z.UNORDERED_NODE_ITE", - "RATOR_TYPE=4;Z.ORDERED_NODE_ITERATOR_TYPE=5;Z.UNORDERED_NODE_SNAPSHOT_T", - "YPE=6;Z.ORDERED_NODE_SNAPSHOT_TYPE=7;Z.ANY_UNORDERED_NODE_TYPE=8;Z.FIRS", - "T_ORDERED_NODE_TYPE=9;function ob(a){this.lookupNamespaceURI=kb(a)}\naa", - "(\"wgxpath.install\",function(a,b){a=a||k;var c=a.Document&&a.Document.", - "prototype||a.document;if(!c.evaluate||b)a.XPathResult=Z,c.evaluate=func", - "tion(a,b,c,g){return(new nb(a,c)).evaluate(b,g)},c.createExpression=fun", - "ction(a,b){return new nb(a,b)},c.createNSResolver=function(a){return ne", - "w ob(a)}});function pb(a,b,c,d){this.top=a;this.right=b;this.bottom=c;t", - "his.left=d}h=pb.prototype;h.clone=function(){return new pb(this.top,thi", - "s.right,this.bottom,this.left)};h.toString=function(){return\"(\"+this.", - "top+\"t, \"+this.right+\"r, \"+this.bottom+\"b, \"+this.left+\"l)\"};h.", - "contains=function(a){return this&&a?a instanceof pb?a.left>=this.left&&", - "a.right<=this.right&&a.top>=this.top&&a.bottom<=this.bottom:a.x>=this.l", - "eft&&a.x<=this.right&&a.y>=this.top&&a.y<=this.bottom:!1};\nh.expand=fu", - "nction(a,b,c,d){da(a)?(this.top-=a.top,this.right+=a.right,this.bottom+", - "=a.bottom,this.left-=a.left):(this.top-=a,this.right+=Number(b),this.bo", - "ttom+=Number(c),this.left-=Number(d));return this};h.ceil=function(){th", - "is.top=Math.ceil(this.top);this.right=Math.ceil(this.right);this.bottom", - "=Math.ceil(this.bottom);this.left=Math.ceil(this.left);return this};\nh", - ".floor=function(){this.top=Math.floor(this.top);this.right=Math.floor(t", - "his.right);this.bottom=Math.floor(this.bottom);this.left=Math.floor(thi", - "s.left);return this};h.round=function(){this.top=Math.round(this.top);t", - "his.right=Math.round(this.right);this.bottom=Math.round(this.bottom);th", - "is.left=Math.round(this.left);return this};h.translate=function(a,b){a ", - "instanceof w?(this.left+=a.x,this.right+=a.x,this.top+=a.y,this.bottom+", - "=a.y):(this.left+=a,this.right+=a,n(b)&&(this.top+=b,this.bottom+=b));r", - "eturn this};\nh.scale=function(a,b){b=n(b)?b:a;this.left*=a;this.right*", - "=a;this.top*=b;this.bottom*=b;return this};function qb(a,b,c,d){this.le", - "ft=a;this.top=b;this.width=c;this.height=d}h=qb.prototype;h.clone=funct", - "ion(){return new qb(this.left,this.top,this.width,this.height)};h.toStr", - "ing=function(){return\"(\"+this.left+\", \"+this.top+\" - \"+this.width", - "+\"w x \"+this.height+\"h)\"};h.contains=function(a){return a instanceo", - "f w?a.x>=this.left&&a.x<=this.left+this.width&&a.y>=this.top&&a.y<=this", - ".top+this.height:this.left<=a.left&&this.left+this.width>=a.left+a.widt", - "h&&this.top<=a.top&&this.top+this.height>=a.top+a.height};\nh.ceil=func", - "tion(){this.left=Math.ceil(this.left);this.top=Math.ceil(this.top);this", - ".width=Math.ceil(this.width);this.height=Math.ceil(this.height);return ", - "this};h.floor=function(){this.left=Math.floor(this.left);this.top=Math.", - "floor(this.top);this.width=Math.floor(this.width);this.height=Math.floo", - "r(this.height);return this};h.round=function(){this.left=Math.round(thi", - "s.left);this.top=Math.round(this.top);this.width=Math.round(this.width)", - ";this.height=Math.round(this.height);return this};\nh.translate=functio", - "n(a,b){a instanceof w?(this.left+=a.x,this.top+=a.y):(this.left+=a,n(b)", - "&&(this.top+=b));return this};h.scale=function(a,b){b=n(b)?b:a;this.lef", - "t*=a;this.width*=a;this.top*=b;this.height*=b;return this};function rb(", - "a,b){var c=z(a);return c.defaultView&&c.defaultView.getComputedStyle&&(", - "a=c.defaultView.getComputedStyle(a,null))?a[b]||a.getPropertyValue(b)||", - "\"\":\"\"}function tb(a){try{var b=a.getBoundingClientRect()}catch(c){r", - "eturn{left:0,top:0,right:0,bottom:0}}return b}\nfunction ub(a){var b=z(", - "a),c=new w(0,0);if(a==(b?z(b):document).documentElement)return c;a=tb(a", - ");var d=(b?new A(z(b)):r||(r=new A)).D,b=d.scrollingElement?d.scrolling", - "Element:d.body||d.documentElement,d=d.parentWindow||d.defaultView,b=new", - " w(d.pageXOffset||b.scrollLeft,d.pageYOffset||b.scrollTop);c.x=a.left+b", - ".x;c.y=a.top+b.y;return c}function vb(a){if(1==a.nodeType)return a=tb(a", - "),new w(a.left,a.top);a=a.changedTouches?a.changedTouches[0]:a;return n", - "ew w(a.clientX,a.clientY)};var wb=\"function\"===typeof ShadowRoot;func", - "tion xb(a,b){b=ub(b);var c=ub(a);b=new w(b.x-c.x,b.y-c.y);var d=rb(a,\"", - "borderLeftWidth\");var e=rb(a,\"borderRightWidth\");c=rb(a,\"borderTopW", - "idth\");a=rb(a,\"borderBottomWidth\");a=new pb(parseFloat(c),parseFloat", - "(e),parseFloat(a),parseFloat(d));b.x-=a.left;b.y-=a.top;return b}\nfunc", - "tion yb(a,b,c){function d(a,b,c,d,e){d=new qb(c.x+d.left,c.y+d.top,d.wi", - "dth,d.height);c=[0,0];b=[b.width,b.height];var f=[d.left,d.top];d=[d.wi", - "dth,d.height];for(var g=0;2>g;g++)if(d[g]>b[g])c[g]=e?f[g]+d[g]/2-b[g]/", - "2:f[g];else{var l=f[g]-b[g]+d[g];0<l?c[g]=l:0>f[g]&&(c[g]=f[g])}e=new w", - "(c[0],c[1]);a.scrollLeft+=e.x;a.scrollTop+=e.y}function e(a){var b=a.pa", - "rentNode;wb&&b instanceof ShadowRoot&&(b=a.host);return b}for(var f=z(a", - "),g=e(a),l;g&&g!=f.documentElement&&g!=f.body;)l=xb(g,a),d(g,new x(g.cl", - "ientWidth,\ng.clientHeight),l,b,c),g=e(g);l=vb(a);a=ra(a?new A(z(a)):r|", - "|(r=new A));d(f.body,a,l,b,c)};aa(\"_\",function(a,b,c){c||(c=new qb(0,", - "0,a.offsetWidth,a.offsetHeight));yb(a,c,b);a=vb(a);return new w(a.x+c.l", - "eft,a.y+c.top)});; return this._.apply(null,arguments);}.apply({navigat", - "or:typeof window!='undefined'?window.navigator:null,document:typeof win", - "dow!='undefined'?window.document:null}, arguments);}", + "[e-2]=arguments[e];return b.prototype[c].apply(a,d)}};var r;var ia=Stri", + "ng.prototype.trim?function(a){return a.trim()}:function(a){return a.rep", + "lace(/^[\\s\\xa0]+|[\\s\\xa0]+$/g,\"\")};function ja(a,b){return a<b?-1", + ":a>b?1:0};function t(a,b){for(var c=a.length,d=m(a)?a.split(\"\"):a,e=0", + ";e<c;e++)e in d&&b.call(void 0,d[e],e,a)}function u(a,b,c){var d=c;t(a,", + "function(c,f){d=b.call(void 0,d,c,f,a)});return d}function v(a,b){for(v", + "ar c=a.length,d=m(a)?a.split(\"\"):a,e=0;e<c;e++)if(e in d&&b.call(void", + " 0,d[e],e,a))return!0;return!1}function ka(a){return Array.prototype.co", + "ncat.apply([],arguments)}function la(a){var b=a.length;if(0<b){for(var ", + "c=Array(b),d=0;d<b;d++)c[d]=a[d];return c}return[]}\nfunction ma(a,b,c)", + "{return 2>=arguments.length?Array.prototype.slice.call(a,b):Array.proto", + "type.slice.call(a,b,c)};var w;a:{var na=k.navigator;if(na){var oa=na.us", + "erAgent;if(oa){w=oa;break a}}w=\"\"};function pa(a){return(a=a.exec(w))", + "?a[1]:\"\"}var qa=-1!=w.indexOf(\"iPhone\")&&-1==w.indexOf(\"iPod\")&&-", + "1==w.indexOf(\"iPad\")||-1!=w.indexOf(\"iPad\")||-1!=w.indexOf(\"iPod\"", + ")?pa(/CriOS\\/([0-9.]+)/):pa(/Chrome\\/([0-9.]+)/);\nfunction ra(){for(", + "var a=0,b=ia(String(qa)).split(\".\"),c=ia(\"61\").split(\".\"),d=Math.", + "max(b.length,c.length),e=0;0==a&&e<d;e++){var f=b[e]||\"\",g=c[e]||\"\"", + ";do{f=/(\\d*)(\\D*)(.*)/.exec(f)||[\"\",\"\",\"\",\"\"];g=/(\\d*)(\\D*)", + "(.*)/.exec(g)||[\"\",\"\",\"\",\"\"];if(0==f[0].length&&0==g[0].length)", + "break;a=ja(0==f[1].length?0:parseInt(f[1],10),0==g[1].length?0:parseInt", + "(g[1],10))||ja(0==f[2].length,0==g[2].length)||ja(f[2],g[2]);f=f[3];g=g", + "[3]}while(0==a)}return 0<=a};function x(a,b){this.x=void 0!==a?a:0;this", + ".y=void 0!==b?b:0}h=x.prototype;h.clone=function(){return new x(this.x,", + "this.y)};h.toString=function(){return\"(\"+this.x+\", \"+this.y+\")\"};", + "h.ceil=function(){this.x=Math.ceil(this.x);this.y=Math.ceil(this.y);ret", + "urn this};h.floor=function(){this.x=Math.floor(this.x);this.y=Math.floo", + "r(this.y);return this};h.round=function(){this.x=Math.round(this.x);thi", + "s.y=Math.round(this.y);return this};\nh.translate=function(a,b){a insta", + "nceof x?(this.x+=a.x,this.y+=a.y):(this.x+=Number(a),n(b)&&(this.y+=b))", + ";return this};h.scale=function(a,b){b=n(b)?b:a;this.x*=a;this.y*=b;retu", + "rn this};function z(a,b){this.width=a;this.height=b}h=z.prototype;h.clo", + "ne=function(){return new z(this.width,this.height)};h.toString=function", + "(){return\"(\"+this.width+\" x \"+this.height+\")\"};h.ceil=function(){", + "this.width=Math.ceil(this.width);this.height=Math.ceil(this.height);ret", + "urn this};h.floor=function(){this.width=Math.floor(this.width);this.hei", + "ght=Math.floor(this.height);return this};h.round=function(){this.width=", + "Math.round(this.width);this.height=Math.round(this.height);return this}", + ";\nh.scale=function(a,b){b=n(b)?b:a;this.width*=a;this.height*=b;return", + " this};function sa(a,b,c){function d(c){c&&b.appendChild(m(c)?a.createT", + "extNode(c):c)}for(var e=1;e<c.length;e++){var f=c[e];!ca(f)||da(f)&&0<f", + ".nodeType?d(f):t(ta(f)?la(f):f,d)}}function ua(a,b){if(!a||!b)return!1;", + "if(a.contains&&1==b.nodeType)return a==b||a.contains(b);if(\"undefined", + "\"!=typeof a.compareDocumentPosition)return a==b||!!(a.compareDocumentP", + "osition(b)&16);for(;b&&a!=b;)b=b.parentNode;return b==a}\nfunction va(a", + ",b){if(a==b)return 0;if(a.compareDocumentPosition)return a.compareDocum", + "entPosition(b)&2?1:-1;if(\"sourceIndex\"in a||a.parentNode&&\"sourceInd", + "ex\"in a.parentNode){var c=1==a.nodeType,d=1==b.nodeType;if(c&&d)return", + " a.sourceIndex-b.sourceIndex;var e=a.parentNode,f=b.parentNode;return e", + "==f?wa(a,b):!c&&ua(e,b)?-1*xa(a,b):!d&&ua(f,a)?xa(b,a):(c?a.sourceIndex", + ":e.sourceIndex)-(d?b.sourceIndex:f.sourceIndex)}d=A(a);c=d.createRange(", + ");c.selectNode(a);c.collapse(!0);a=d.createRange();a.selectNode(b);\na.", + "collapse(!0);return c.compareBoundaryPoints(k.Range.START_TO_END,a)}fun", + "ction xa(a,b){var c=a.parentNode;if(c==b)return-1;for(;b.parentNode!=c;", + ")b=b.parentNode;return wa(b,a)}function wa(a,b){for(;b=b.previousSiblin", + "g;)if(b==a)return-1;return 1}function A(a){return 9==a.nodeType?a:a.own", + "erDocument||a.document}function ta(a){if(a&&\"number\"==typeof a.length", + "){if(da(a))return\"function\"==typeof a.item||\"string\"==typeof a.item", + ";if(\"function\"==ba(a))return\"function\"==typeof a.item}return!1}\nfu", + "nction B(a){this.D=a||k.document||document}h=B.prototype;h.getElementsB", + "yTagName=function(a,b){return(b||this.D).getElementsByTagName(String(a)", + ")};function ya(a){a=a.D;a=(a.parentWindow||a.defaultView||window).docum", + "ent;a=\"CSS1Compat\"==a.compatMode?a.documentElement:a.body;return new ", + "z(a.clientWidth,a.clientHeight)}h.createElement=function(a){return this", + ".D.createElement(String(a))};h.createTextNode=function(a){return this.D", + ".createTextNode(String(a))};h.appendChild=function(a,b){a.appendChild(b", + ")};\nh.append=function(a,b){sa(A(a),a,arguments)};h.canHaveChildren=fun", + "ction(a){if(1!=a.nodeType)return!1;switch(a.tagName){case \"APPLET\":ca", + "se \"AREA\":case \"BASE\":case \"BR\":case \"COL\":case \"COMMAND\":cas", + "e \"EMBED\":case \"FRAME\":case \"HR\":case \"IMG\":case \"INPUT\":case", + " \"IFRAME\":case \"ISINDEX\":case \"KEYGEN\":case \"LINK\":case \"NOFRA", + "MES\":case \"NOSCRIPT\":case \"META\":case \"OBJECT\":case \"PARAM\":ca", + "se \"SCRIPT\":case \"SOURCE\":case \"STYLE\":case \"TRACK\":case \"WBR", + "\":return!1}return!0};\nh.removeNode=function(a){return a&&a.parentNode", + "?a.parentNode.removeChild(a):null};h.contains=ua;/*\n\n The MIT License", + "\n\n Copyright (c) 2007 Cybozu Labs, Inc.\n Copyright (c) 2012 Google I", + "nc.\n\n Permission is hereby granted, free of charge, to any person obt", + "aining a copy\n of this software and associated documentation files (th", + "e \"Software\"), to\n deal in the Software without restriction, includi", + "ng without limitation the\n rights to use, copy, modify, merge, publish", + ", distribute, sublicense, and/or\n sell copies of the Software, and to ", + "permit persons to whom the Software is\n furnished to do so, subject to", + " the following conditions:\n\n The above copyright notice and this perm", + "ission notice shall be included in\n all copies or substantial portions", + " of the Software.\n\n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRA", + "NTY OF ANY KIND, EXPRESS OR\n IMPLIED, INCLUDING BUT NOT LIMITED TO THE", + " WARRANTIES OF MERCHANTABILITY,\n FITNESS FOR A PARTICULAR PURPOSE AND ", + "NONINFRINGEMENT. IN NO EVENT SHALL THE\n AUTHORS OR COPYRIGHT HOLDERS B", + "E LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n LIABILITY, WHETHER IN AN ACT", + "ION OF CONTRACT, TORT OR OTHERWISE, ARISING\n FROM, OUT OF OR IN CONNEC", + "TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n IN THE SOFTWARE.", + "\n*/\nfunction C(a,b,c){this.l=a;this.la=b||1;this.j=c||1};function D(a", + "){this.T=a;this.J=0}function za(a){a=a.match(Ba);for(var b=0;b<a.length", + ";b++)Ca.test(a[b])&&a.splice(b,1);return new D(a)}var Ba=/\\$?(?:(?![0-", + "9-\\.])(?:\\*|[\\w-\\.]+):)?(?![0-9-\\.])(?:\\*|[\\w-\\.]+)|\\/\\/|\\.", + "\\.|::|\\d+(?:\\.\\d*)?|\\.\\d+|\"[^\"]*\"|'[^']*'|[!<>]=|\\s+|./g,Ca=/", + "^\\s/;function E(a,b){return a.T[a.J+(b||0)]}D.prototype.next=function(", + "){return this.T[this.J++]};D.prototype.back=function(){this.J--};D.prot", + "otype.empty=function(){return this.T.length<=this.J};function F(a){var ", + "b=null,c=a.nodeType;1==c&&(b=a.textContent,b=void 0==b||null==b?a.inner", + "Text:b,b=void 0==b||null==b?\"\":b);if(\"string\"!=typeof b)if(9==c||1=", + "=c){a=9==c?a.documentElement:a.firstChild;for(var c=0,d=[],b=\"\";a;){d", + "o 1!=a.nodeType&&(b+=a.nodeValue),d[c++]=a;while(a=a.firstChild);for(;c", + "&&!(a=d[--c].nextSibling););}}else b=a.nodeValue;return\"\"+b}\nfunctio", + "n G(a,b,c){if(null===b)return!0;try{if(!a.getAttribute)return!1}catch(d", + "){return!1}return null==c?!!a.getAttribute(b):a.getAttribute(b,2)==c}fu", + "nction H(a,b,c,d,e){return Da.call(null,a,b,m(c)?c:null,m(d)?d:null,e||", + "new I)}\nfunction Da(a,b,c,d,e){b.getElementsByName&&d&&\"name\"==c?(b=", + "b.getElementsByName(d),t(b,function(b){a.matches(b)&&e.add(b)})):b.getE", + "lementsByClassName&&d&&\"class\"==c?(b=b.getElementsByClassName(d),t(b,", + "function(b){b.className==d&&a.matches(b)&&e.add(b)})):a instanceof J?Ea", + "(a,b,c,d,e):b.getElementsByTagName&&(b=b.getElementsByTagName(a.getName", + "()),t(b,function(a){G(a,c,d)&&e.add(a)}));return e}function Ea(a,b,c,d,", + "e){for(b=b.firstChild;b;b=b.nextSibling)G(b,c,d)&&a.matches(b)&&e.add(b", + "),Ea(a,b,c,d,e)};function I(){this.j=this.g=null;this.F=0}function Fa(a", + "){this.node=a;this.next=this.w=null}function Ga(a,b){if(!a.g)return b;i", + "f(!b.g)return a;var c=a.g;b=b.g;for(var d=null,e,f=0;c&&b;)c.node==b.no", + "de?(e=c,c=c.next,b=b.next):0<va(c.node,b.node)?(e=b,b=b.next):(e=c,c=c.", + "next),(e.w=d)?d.next=e:a.g=e,d=e,f++;for(e=c||b;e;)e.w=d,d=d.next=e,f++", + ",e=e.next;a.j=d;a.F=f;return a}I.prototype.unshift=function(a){a=new Fa", + "(a);a.next=this.g;this.j?this.g.w=a:this.g=this.j=a;this.g=a;this.F++};", + "\nI.prototype.add=function(a){a=new Fa(a);a.w=this.j;this.g?this.j.next", + "=a:this.g=this.j=a;this.j=a;this.F++};function K(a){return(a=a.g)?a.nod", + "e:null}I.prototype.m=function(){return this.F};function Ha(a){return(a=", + "K(a))?F(a):\"\"}I.prototype.iterator=function(a){return new Ia(this,!!a", + ")};function Ia(a,b){this.ha=a;this.U=(this.A=b)?a.j:a.g;this.P=null}Ia.", + "prototype.next=function(){var a=this.U;if(null==a)return null;var b=thi", + "s.P=a;this.U=this.A?a.w:a.next;return b.node};\nIa.prototype.remove=fun", + "ction(){var a=this.ha,b=this.P;if(!b)throw Error(\"Next must be called ", + "at least once before remove.\");var c=b.w,b=b.next;c?c.next=b:a.g=b;b?b", + ".w=c:a.j=c;a.F--;this.P=null};function q(a){this.f=a;this.h=this.o=!1;t", + "his.G=null}function L(a){return\"\\n \"+a.toString().split(\"\\n\").jo", + "in(\"\\n \")}q.prototype.c=function(){return this.o};function Ja(a,b){", + "a.o=b}function Ka(a,b){a.h=b}q.prototype.u=function(){return this.G};fu", + "nction M(a,b){a=a.evaluate(b);return a instanceof I?+Ha(a):+a}function ", + "N(a,b){a=a.evaluate(b);return a instanceof I?Ha(a):\"\"+a}function O(a,", + "b){a=a.evaluate(b);return a instanceof I?!!a.m():!!a};function P(a,b,c)", + "{q.call(this,a.f);this.S=a;this.X=b;this.ba=c;this.o=b.c()||c.c();this.", + "h=b.h||c.h;this.S==La&&(c.h||c.c()||4==c.f||0==c.f||!b.u()?b.h||b.c()||", + "4==b.f||0==b.f||!c.u()||(this.G={name:c.u().name,C:b}):this.G={name:b.u", + "().name,C:c})}p(P);\nfunction Q(a,b,c,d,e){b=b.evaluate(d);c=c.evaluate", + "(d);var f;if(b instanceof I&&c instanceof I){b=b.iterator();for(d=b.nex", + "t();d;d=b.next())for(e=c.iterator(),f=e.next();f;f=e.next())if(a(F(d),F", + "(f)))return!0;return!1}if(b instanceof I||c instanceof I){b instanceof ", + "I?(e=b,d=c):(e=c,d=b);f=e.iterator();for(var g=typeof d,l=f.next();l;l=", + "f.next()){switch(g){case \"number\":l=+F(l);break;case \"boolean\":l=!!", + "F(l);break;case \"string\":l=F(l);break;default:throw Error(\"Illegal p", + "rimitive type for comparison.\");\n}if(e==b&&a(l,d)||e==c&&a(d,l))retur", + "n!0}return!1}return e?\"boolean\"==typeof b||\"boolean\"==typeof c?a(!!", + "b,!!c):\"number\"==typeof b||\"number\"==typeof c?a(+b,+c):a(b,c):a(+b,", + "+c)}P.prototype.evaluate=function(a){return this.S.v(this.X,this.ba,a)}", + ";P.prototype.toString=function(){var a=\"Binary Expression: \"+this.S,a", + "=a+L(this.X);return a+=L(this.ba)};function Ma(a,b,c,d){this.ka=a;this.", + "$=b;this.f=c;this.v=d}Ma.prototype.toString=function(){return this.ka};", + "var Na={};\nfunction R(a,b,c,d){if(Na.hasOwnProperty(a))throw Error(\"B", + "inary operator already created: \"+a);a=new Ma(a,b,c,d);return Na[a.toS", + "tring()]=a}R(\"div\",6,1,function(a,b,c){return M(a,c)/M(b,c)});R(\"mod", + "\",6,1,function(a,b,c){return M(a,c)%M(b,c)});R(\"*\",6,1,function(a,b,", + "c){return M(a,c)*M(b,c)});R(\"+\",5,1,function(a,b,c){return M(a,c)+M(b", + ",c)});R(\"-\",5,1,function(a,b,c){return M(a,c)-M(b,c)});R(\"<\",4,2,fu", + "nction(a,b,c){return Q(function(a,b){return a<b},a,b,c)});\nR(\">\",4,2", + ",function(a,b,c){return Q(function(a,b){return a>b},a,b,c)});R(\"<=\",4", + ",2,function(a,b,c){return Q(function(a,b){return a<=b},a,b,c)});R(\">=", + "\",4,2,function(a,b,c){return Q(function(a,b){return a>=b},a,b,c)});var", + " La=R(\"=\",3,2,function(a,b,c){return Q(function(a,b){return a==b},a,b", + ",c,!0)});R(\"!=\",3,2,function(a,b,c){return Q(function(a,b){return a!=", + "b},a,b,c,!0)});R(\"and\",2,2,function(a,b,c){return O(a,c)&&O(b,c)});R(", + "\"or\",1,2,function(a,b,c){return O(a,c)||O(b,c)});function Oa(a,b){if(", + "b.m()&&4!=a.f)throw Error(\"Primary expression must evaluate to nodeset", + " if filter has predicate(s).\");q.call(this,a.f);this.aa=a;this.b=b;thi", + "s.o=a.c();this.h=a.h}p(Oa);Oa.prototype.evaluate=function(a){a=this.aa.", + "evaluate(a);return Pa(this.b,a)};Oa.prototype.toString=function(){var a", + "=\"Filter:\"+L(this.aa);return a+=L(this.b)};function Qa(a,b){if(b.leng", + "th<a.Z)throw Error(\"Function \"+a.i+\" expects at least\"+a.Z+\" argum", + "ents, \"+b.length+\" given\");if(null!==a.R&&b.length>a.R)throw Error(", + "\"Function \"+a.i+\" expects at most \"+a.R+\" arguments, \"+b.length+", + "\" given\");a.ia&&t(b,function(b,d){if(4!=b.f)throw Error(\"Argument \"", + "+d+\" to function \"+a.i+\" is not of type Nodeset: \"+b);});q.call(thi", + "s,a.f);this.I=a;this.N=b;Ja(this,a.o||v(b,function(a){return a.c()}));K", + "a(this,a.ga&&!b.length||a.fa&&!!b.length||v(b,function(a){return a.h}))", + "}p(Qa);\nQa.prototype.evaluate=function(a){return this.I.v.apply(null,k", + "a(a,this.N))};Qa.prototype.toString=function(){var a=\"Function: \"+thi", + "s.I;if(this.N.length)var b=u(this.N,function(a,b){return a+L(b)},\"Argu", + "ments:\"),a=a+L(b);return a};function Ra(a,b,c,d,e,f,g,l,y){this.i=a;th", + "is.f=b;this.o=c;this.ga=d;this.fa=e;this.v=f;this.Z=g;this.R=void 0!==l", + "?l:g;this.ia=!!y}Ra.prototype.toString=function(){return this.i};var Sa", + "={};\nfunction S(a,b,c,d,e,f,g,l){if(Sa.hasOwnProperty(a))throw Error(", + "\"Function already created: \"+a+\".\");Sa[a]=new Ra(a,b,c,d,!1,e,f,g,l", + ")}S(\"boolean\",2,!1,!1,function(a,b){return O(b,a)},1);S(\"ceiling\",1", + ",!1,!1,function(a,b){return Math.ceil(M(b,a))},1);S(\"concat\",3,!1,!1,", + "function(a,b){return u(ma(arguments,1),function(b,d){return b+N(d,a)},", + "\"\")},2,null);S(\"contains\",2,!1,!1,function(a,b,c){b=N(b,a);a=N(c,a)", + ";return-1!=b.indexOf(a)},2);S(\"count\",1,!1,!1,function(a,b){return b.", + "evaluate(a).m()},1,1,!0);\nS(\"false\",2,!1,!1,function(){return!1},0);", + "S(\"floor\",1,!1,!1,function(a,b){return Math.floor(M(b,a))},1);S(\"id", + "\",4,!1,!1,function(a,b){var c=a.l,d=9==c.nodeType?c:c.ownerDocument;a=", + "N(b,a).split(/\\s+/);var e=[];t(a,function(a){a=d.getElementById(a);var", + " b;if(!(b=!a)){a:if(m(e))b=m(a)&&1==a.length?e.indexOf(a,0):-1;else{for", + "(b=0;b<e.length;b++)if(b in e&&e[b]===a)break a;b=-1}b=0<=b}b||e.push(a", + ")});e.sort(va);var f=new I;t(e,function(a){f.add(a)});return f},1);S(\"", + "lang\",2,!1,!1,function(){return!1},1);\nS(\"last\",1,!0,!1,function(a)", + "{if(1!=arguments.length)throw Error(\"Function last expects ()\");retur", + "n a.j},0);S(\"local-name\",3,!1,!0,function(a,b){return(a=b?K(b.evaluat", + "e(a)):a.l)?a.localName||a.nodeName.toLowerCase():\"\"},0,1,!0);S(\"name", + "\",3,!1,!0,function(a,b){return(a=b?K(b.evaluate(a)):a.l)?a.nodeName.to", + "LowerCase():\"\"},0,1,!0);S(\"namespace-uri\",3,!0,!1,function(){return", + "\"\"},0,1,!0);\nS(\"normalize-space\",3,!1,!0,function(a,b){return(b?N(", + "b,a):F(a.l)).replace(/[\\s\\xa0]+/g,\" \").replace(/^\\s+|\\s+$/g,\"\")", + "},0,1);S(\"not\",2,!1,!1,function(a,b){return!O(b,a)},1);S(\"number\",1", + ",!1,!0,function(a,b){return b?M(b,a):+F(a.l)},0,1);S(\"position\",1,!0,", + "!1,function(a){return a.la},0);S(\"round\",1,!1,!1,function(a,b){return", + " Math.round(M(b,a))},1);S(\"starts-with\",2,!1,!1,function(a,b,c){b=N(b", + ",a);a=N(c,a);return 0==b.lastIndexOf(a,0)},2);S(\"string\",3,!1,!0,func", + "tion(a,b){return b?N(b,a):F(a.l)},0,1);\nS(\"string-length\",1,!1,!0,fu", + "nction(a,b){return(b?N(b,a):F(a.l)).length},0,1);S(\"substring\",3,!1,!", + "1,function(a,b,c,d){c=M(c,a);if(isNaN(c)||Infinity==c||-Infinity==c)ret", + "urn\"\";d=d?M(d,a):Infinity;if(isNaN(d)||-Infinity===d)return\"\";c=Mat", + "h.round(c)-1;var e=Math.max(c,0);a=N(b,a);return Infinity==d?a.substrin", + "g(e):a.substring(e,c+Math.round(d))},2,3);S(\"substring-after\",3,!1,!1", + ",function(a,b,c){b=N(b,a);a=N(c,a);c=b.indexOf(a);return-1==c?\"\":b.su", + "bstring(c+a.length)},2);\nS(\"substring-before\",3,!1,!1,function(a,b,c", + "){b=N(b,a);a=N(c,a);a=b.indexOf(a);return-1==a?\"\":b.substring(0,a)},2", + ");S(\"sum\",1,!1,!1,function(a,b){a=b.evaluate(a).iterator();b=0;for(va", + "r c=a.next();c;c=a.next())b+=+F(c);return b},1,1,!0);S(\"translate\",3,", + "!1,!1,function(a,b,c,d){b=N(b,a);c=N(c,a);var e=N(d,a);d={};for(var f=0", + ";f<c.length;f++)a=c.charAt(f),a in d||(d[a]=e.charAt(f));c=\"\";for(f=0", + ";f<b.length;f++)a=b.charAt(f),c+=a in d?d[a]:a;return c},3);S(\"true\",", + "2,!1,!1,function(){return!0},0);function J(a,b){this.da=a;this.Y=void 0", + "!==b?b:null;this.B=null;switch(a){case \"comment\":this.B=8;break;case ", + "\"text\":this.B=3;break;case \"processing-instruction\":this.B=7;break;", + "case \"node\":break;default:throw Error(\"Unexpected argument\");}}func", + "tion Ta(a){return\"comment\"==a||\"text\"==a||\"processing-instruction", + "\"==a||\"node\"==a}J.prototype.matches=function(a){return null===this.B", + "||this.B==a.nodeType};J.prototype.getName=function(){return this.da};\n", + "J.prototype.toString=function(){var a=\"Kind Test: \"+this.da;null===th", + "is.Y||(a+=L(this.Y));return a};function Ua(a){q.call(this,3);this.ca=a.", + "substring(1,a.length-1)}p(Ua);Ua.prototype.evaluate=function(){return t", + "his.ca};Ua.prototype.toString=function(){return\"Literal: \"+this.ca};f", + "unction T(a,b){this.i=a.toLowerCase();a=\"*\"==this.i?\"*\":\"http://ww", + "w.w3.org/1999/xhtml\";this.K=b?b.toLowerCase():a}T.prototype.matches=fu", + "nction(a){var b=a.nodeType;if(1!=b&&2!=b)return!1;b=void 0!==a.localNam", + "e?a.localName:a.nodeName;return\"*\"!=this.i&&this.i!=b.toLowerCase()?!", + "1:\"*\"==this.K?!0:this.K==(a.namespaceURI?a.namespaceURI.toLowerCase()", + ":\"http://www.w3.org/1999/xhtml\")};T.prototype.getName=function(){retu", + "rn this.i};\nT.prototype.toString=function(){return\"Name Test: \"+(\"h", + "ttp://www.w3.org/1999/xhtml\"==this.K?\"\":this.K+\":\")+this.i};functi", + "on Va(a){q.call(this,1);this.ea=a}p(Va);Va.prototype.evaluate=function(", + "){return this.ea};Va.prototype.toString=function(){return\"Number: \"+t", + "his.ea};function Wa(a,b){q.call(this,a.f);this.W=a;this.H=b;this.o=a.c(", + ");this.h=a.h;1==this.H.length&&(a=this.H[0],a.O||a.s!=Xa||(a=a.M,\"*\"!", + "=a.getName()&&(this.G={name:a.getName(),C:null})))}p(Wa);function U(){q", + ".call(this,4)}p(U);U.prototype.evaluate=function(a){var b=new I;a=a.l;9", + "==a.nodeType?b.add(a):b.add(a.ownerDocument);return b};U.prototype.toSt", + "ring=function(){return\"Root Helper Expression\"};function Ya(){q.call(", + "this,4)}p(Ya);Ya.prototype.evaluate=function(a){var b=new I;b.add(a.l);", + "return b};\nYa.prototype.toString=function(){return\"Context Helper Exp", + "ression\"};function Za(a){return\"/\"==a||\"//\"==a}\nWa.prototype.eval", + "uate=function(a){var b=this.W.evaluate(a);if(!(b instanceof I))throw Er", + "ror(\"Filter expression must evaluate to nodeset.\");a=this.H;for(var c", + "=0,d=a.length;c<d&&b.m();c++){var e=a[c],f=b.iterator(e.s.A);if(e.c()||", + "e.s!=$a)if(e.c()||e.s!=ab){var g=f.next();for(b=e.evaluate(new C(g));nu", + "ll!=(g=f.next());)g=e.evaluate(new C(g)),b=Ga(b,g)}else g=f.next(),b=e.", + "evaluate(new C(g));else{for(g=f.next();(b=f.next())&&(!g.contains||g.co", + "ntains(b))&&b.compareDocumentPosition(g)&8;g=b);b=e.evaluate(new C(g))}", + "}return b};\nWa.prototype.toString=function(){var a=\"Path Expression:", + "\"+L(this.W);if(this.H.length){var b=u(this.H,function(a,b){return a+L(", + "b)},\"Steps:\");a+=L(b)}return a};function V(a,b){this.b=a;this.A=!!b}f", + "unction Pa(a,b,c){for(c=c||0;c<a.b.length;c++)for(var d=a.b[c],e=b.iter", + "ator(),f=b.m(),g,l=0;g=e.next();l++){var y=a.A?f-l:l+1;g=d.evaluate(new", + " C(g,y,f));if(\"number\"==typeof g)y=y==g;else if(\"string\"==typeof g|", + "|\"boolean\"==typeof g)y=!!g;else if(g instanceof I)y=0<g.m();else thro", + "w Error(\"Predicate.evaluate returned an unexpected type.\");y||e.remov", + "e()}return b}V.prototype.u=function(){return 0<this.b.length?this.b[0].", + "u():null};\nV.prototype.c=function(){for(var a=0;a<this.b.length;a++){v", + "ar b=this.b[a];if(b.c()||1==b.f||0==b.f)return!0}return!1};V.prototype.", + "m=function(){return this.b.length};V.prototype.toString=function(){retu", + "rn u(this.b,function(a,b){return a+L(b)},\"Predicates:\")};function W(a", + ",b,c,d){q.call(this,4);this.s=a;this.M=b;this.b=c||new V([]);this.O=!!d", + ";b=this.b.u();a.ma&&b&&(this.G={name:b.name,C:b.C});this.o=this.b.c()}p", + "(W);\nW.prototype.evaluate=function(a){var b=a.l,c=this.u(),d=null,e=nu", + "ll,f=0;c&&(d=c.name,e=c.C?N(c.C,a):null,f=1);if(this.O)if(this.c()||thi", + "s.s!=bb)if(b=(new W(cb,new J(\"node\"))).evaluate(a).iterator(),c=b.nex", + "t())for(a=this.v(c,d,e,f);null!=(c=b.next());)a=Ga(a,this.v(c,d,e,f));e", + "lse a=new I;else a=H(this.M,b,d,e),a=Pa(this.b,a,f);else a=this.v(a.l,d", + ",e,f);return a};W.prototype.v=function(a,b,c,d){a=this.s.I(this.M,a,b,c", + ");return a=Pa(this.b,a,d)};\nW.prototype.toString=function(){var a=\"St", + "ep:\"+L(\"Operator: \"+(this.O?\"//\":\"/\"));this.s.i&&(a+=L(\"Axis: ", + "\"+this.s));a+=L(this.M);if(this.b.m()){var b=u(this.b.b,function(a,b){", + "return a+L(b)},\"Predicates:\");a+=L(b)}return a};function db(a,b,c,d){", + "this.i=a;this.I=b;this.A=c;this.ma=d}db.prototype.toString=function(){r", + "eturn this.i};var eb={};function X(a,b,c,d){if(eb.hasOwnProperty(a))thr", + "ow Error(\"Axis already created: \"+a);b=new db(a,b,c,!!d);return eb[a]", + "=b}\nX(\"ancestor\",function(a,b){for(var c=new I;b=b.parentNode;)a.mat", + "ches(b)&&c.unshift(b);return c},!0);X(\"ancestor-or-self\",function(a,b", + "){var c=new I;do a.matches(b)&&c.unshift(b);while(b=b.parentNode);retur", + "n c},!0);\nvar Xa=X(\"attribute\",function(a,b){var c=new I,d=a.getName", + "();if(b=b.attributes)if(a instanceof J&&null===a.B||\"*\"==d)for(d=0;a=", + "b[d];d++)c.add(a);else(a=b.getNamedItem(d))&&c.add(a);return c},!1),bb=", + "X(\"child\",function(a,b,c,d,e){c=m(c)?c:null;d=m(d)?d:null;e=e||new I;", + "for(b=b.firstChild;b;b=b.nextSibling)G(b,c,d)&&a.matches(b)&&e.add(b);r", + "eturn e},!1,!0);X(\"descendant\",H,!1,!0);\nvar cb=X(\"descendant-or-se", + "lf\",function(a,b,c,d){var e=new I;G(b,c,d)&&a.matches(b)&&e.add(b);ret", + "urn H(a,b,c,d,e)},!1,!0),$a=X(\"following\",function(a,b,c,d){var e=new", + " I;do for(var f=b;f=f.nextSibling;)G(f,c,d)&&a.matches(f)&&e.add(f),e=H", + "(a,f,c,d,e);while(b=b.parentNode);return e},!1,!0);X(\"following-siblin", + "g\",function(a,b){for(var c=new I;b=b.nextSibling;)a.matches(b)&&c.add(", + "b);return c},!1);X(\"namespace\",function(){return new I},!1);\nvar fb=", + "X(\"parent\",function(a,b){var c=new I;if(9==b.nodeType)return c;if(2==", + "b.nodeType)return c.add(b.ownerElement),c;b=b.parentNode;a.matches(b)&&", + "c.add(b);return c},!1),ab=X(\"preceding\",function(a,b,c,d){var e=new I", + ",f=[];do f.unshift(b);while(b=b.parentNode);for(var g=1,l=f.length;g<l;", + "g++){var y=[];for(b=f[g];b=b.previousSibling;)y.unshift(b);for(var Aa=0", + ",Ab=y.length;Aa<Ab;Aa++)b=y[Aa],G(b,c,d)&&a.matches(b)&&e.add(b),e=H(a,", + "b,c,d,e)}return e},!0,!0);\nX(\"preceding-sibling\",function(a,b){for(v", + "ar c=new I;b=b.previousSibling;)a.matches(b)&&c.unshift(b);return c},!0", + ");var gb=X(\"self\",function(a,b){var c=new I;a.matches(b)&&c.add(b);re", + "turn c},!1);function hb(a){q.call(this,1);this.V=a;this.o=a.c();this.h=", + "a.h}p(hb);hb.prototype.evaluate=function(a){return-M(this.V,a)};hb.prot", + "otype.toString=function(){return\"Unary Expression: -\"+L(this.V)};func", + "tion ib(a){q.call(this,4);this.L=a;Ja(this,v(this.L,function(a){return ", + "a.c()}));Ka(this,v(this.L,function(a){return a.h}))}p(ib);ib.prototype.", + "evaluate=function(a){var b=new I;t(this.L,function(c){c=c.evaluate(a);i", + "f(!(c instanceof I))throw Error(\"Path expression must evaluate to Node", + "Set.\");b=Ga(b,c)});return b};ib.prototype.toString=function(){return u", + "(this.L,function(a,b){return a+L(b)},\"Union Expression:\")};function j", + "b(a,b){this.a=a;this.ja=b}function kb(a){for(var b,c=[];;){Y(a,\"Missin", + "g right hand side of binary expression.\");b=lb(a);var d=a.a.next();if(", + "!d)break;var e=(d=Na[d]||null)&&d.$;if(!e){a.a.back();break}for(;c.leng", + "th&&e<=c[c.length-1].$;)b=new P(c.pop(),c.pop(),b);c.push(b,d)}for(;c.l", + "ength;)b=new P(c.pop(),c.pop(),b);return b}function Y(a,b){if(a.a.empty", + "())throw Error(b);}function mb(a,b){a=a.a.next();if(a!=b)throw Error(\"", + "Bad token, expected: \"+b+\" got: \"+a);}\nfunction nb(a){a=a.a.next();", + "if(\")\"!=a)throw Error(\"Bad token: \"+a);}function ob(a){a=a.a.next()", + ";if(2>a.length)throw Error(\"Unclosed literal string\");return new Ua(a", + ")}\nfunction pb(a){var b=[];if(Za(E(a.a))){var c=a.a.next();var d=E(a.a", + ");if(\"/\"==c&&(a.a.empty()||\".\"!=d&&\"..\"!=d&&\"@\"!=d&&\"*\"!=d&&!", + "/(?![0-9])[\\w]/.test(d)))return new U;d=new U;Y(a,\"Missing next locat", + "ion step.\");c=qb(a,c);b.push(c)}else{a:{c=E(a.a);d=c.charAt(0);switch(", + "d){case \"$\":throw Error(\"Variable reference not allowed in HTML XPat", + "h\");case \"(\":a.a.next();c=kb(a);Y(a,'unclosed \"(\"');mb(a,\")\");br", + "eak;case '\"':case \"'\":c=ob(a);break;default:if(isNaN(+c))if(!Ta(c)&&", + "/(?![0-9])[\\w]/.test(d)&&\"(\"==E(a.a,\n1)){c=a.a.next();c=Sa[c]||null", + ";a.a.next();for(d=[];\")\"!=E(a.a);){Y(a,\"Missing function argument li", + "st.\");d.push(kb(a));if(\",\"!=E(a.a))break;a.a.next()}Y(a,\"Unclosed f", + "unction argument list.\");nb(a);c=new Qa(c,d)}else{c=null;break a}else ", + "c=new Va(+a.a.next())}\"[\"==E(a.a)&&(d=new V(rb(a)),c=new Oa(c,d))}if(", + "c)if(Za(E(a.a)))d=c;else return c;else c=qb(a,\"/\"),d=new Ya,b.push(c)", + "}for(;Za(E(a.a));)c=a.a.next(),Y(a,\"Missing next location step.\"),c=q", + "b(a,c),b.push(c);return new Wa(d,b)}\nfunction qb(a,b){if(\"/\"!=b&&\"/", + "/\"!=b)throw Error('Step op should be \"/\" or \"//\"');if(\".\"==E(a.a", + ")){var c=new W(gb,new J(\"node\"));a.a.next();return c}if(\"..\"==E(a.a", + "))return c=new W(fb,new J(\"node\")),a.a.next(),c;if(\"@\"==E(a.a)){var", + " d=Xa;a.a.next();Y(a,\"Missing attribute name\")}else if(\"::\"==E(a.a,", + "1)){if(!/(?![0-9])[\\w]/.test(E(a.a).charAt(0)))throw Error(\"Bad token", + ": \"+a.a.next());var e=a.a.next();d=eb[e]||null;if(!d)throw Error(\"No ", + "axis with name: \"+e);a.a.next();Y(a,\"Missing node name\")}else d=bb;e", + "=\nE(a.a);if(/(?![0-9])[\\w\\*]/.test(e.charAt(0)))if(\"(\"==E(a.a,1)){", + "if(!Ta(e))throw Error(\"Invalid node type: \"+e);e=a.a.next();if(!Ta(e)", + ")throw Error(\"Invalid type name: \"+e);mb(a,\"(\");Y(a,\"Bad nodetype", + "\");var f=E(a.a).charAt(0),g=null;if('\"'==f||\"'\"==f)g=ob(a);Y(a,\"Ba", + "d nodetype\");nb(a);e=new J(e,g)}else if(e=a.a.next(),f=e.indexOf(\":\"", + "),-1==f)e=new T(e);else{var g=e.substring(0,f);if(\"*\"==g)var l=\"*\";", + "else if(l=a.ja(g),!l)throw Error(\"Namespace prefix not declared: \"+g)", + ";e=e.substr(f+1);e=new T(e,l)}else throw Error(\"Bad token: \"+\na.a.ne", + "xt());a=new V(rb(a),d.A);return c||new W(d,e,a,\"//\"==b)}function rb(a", + "){for(var b=[];\"[\"==E(a.a);){a.a.next();Y(a,\"Missing predicate expre", + "ssion.\");var c=kb(a);b.push(c);Y(a,\"Unclosed predicate expression.\")", + ";mb(a,\"]\")}return b}function lb(a){if(\"-\"==E(a.a))return a.a.next()", + ",new hb(lb(a));var b=pb(a);if(\"|\"!=E(a.a))a=b;else{for(b=[b];\"|\"==a", + ".a.next();)Y(a,\"Missing next union location path.\"),b.push(pb(a));a.a", + ".back();a=new ib(b)}return a};function sb(a){switch(a.nodeType){case 1:", + "return ha(tb,a);case 9:return sb(a.documentElement);case 11:case 10:cas", + "e 6:case 12:return ub;default:return a.parentNode?sb(a.parentNode):ub}}", + "function ub(){return null}function tb(a,b){if(a.prefix==b)return a.name", + "spaceURI||\"http://www.w3.org/1999/xhtml\";var c=a.getAttributeNode(\"x", + "mlns:\"+b);return c&&c.specified?c.value||null:a.parentNode&&9!=a.paren", + "tNode.nodeType?tb(a.parentNode,b):null};function vb(a,b){if(!a.length)t", + "hrow Error(\"Empty XPath expression.\");a=za(a);if(a.empty())throw Erro", + "r(\"Invalid XPath expression.\");b?\"function\"==ba(b)||(b=ga(b.lookupN", + "amespaceURI,b)):b=function(){return null};var c=kb(new jb(a,b));if(!a.e", + "mpty())throw Error(\"Bad token: \"+a.next());this.evaluate=function(a,b", + "){a=c.evaluate(new C(a));return new Z(a,b)}}\nfunction Z(a,b){if(0==b)i", + "f(a instanceof I)b=4;else if(\"string\"==typeof a)b=2;else if(\"number", + "\"==typeof a)b=1;else if(\"boolean\"==typeof a)b=3;else throw Error(\"U", + "nexpected evaluation result.\");if(2!=b&&1!=b&&3!=b&&!(a instanceof I))", + "throw Error(\"value could not be converted to the specified type\");thi", + "s.resultType=b;switch(b){case 2:this.stringValue=a instanceof I?Ha(a):", + "\"\"+a;break;case 1:this.numberValue=a instanceof I?+Ha(a):+a;break;cas", + "e 3:this.booleanValue=a instanceof I?0<a.m():!!a;break;case 4:case 5:ca", + "se 6:case 7:var c=\na.iterator();var d=[];for(var e=c.next();e;e=c.next", + "())d.push(e);this.snapshotLength=a.m();this.invalidIteratorState=!1;bre", + "ak;case 8:case 9:this.singleNodeValue=K(a);break;default:throw Error(\"", + "Unknown XPathResult type.\");}var f=0;this.iterateNext=function(){if(4!", + "=b&&5!=b)throw Error(\"iterateNext called with wrong result type\");ret", + "urn f>=d.length?null:d[f++]};this.snapshotItem=function(a){if(6!=b&&7!=", + "b)throw Error(\"snapshotItem called with wrong result type\");return a>", + "=d.length||0>a?null:d[a]}}\nZ.ANY_TYPE=0;Z.NUMBER_TYPE=1;Z.STRING_TYPE=", + "2;Z.BOOLEAN_TYPE=3;Z.UNORDERED_NODE_ITERATOR_TYPE=4;Z.ORDERED_NODE_ITER", + "ATOR_TYPE=5;Z.UNORDERED_NODE_SNAPSHOT_TYPE=6;Z.ORDERED_NODE_SNAPSHOT_TY", + "PE=7;Z.ANY_UNORDERED_NODE_TYPE=8;Z.FIRST_ORDERED_NODE_TYPE=9;function w", + "b(a){this.lookupNamespaceURI=sb(a)}\naa(\"wgxpath.install\",function(a,", + "b){a=a||k;var c=a.Document&&a.Document.prototype||a.document;if(!c.eval", + "uate||b)a.XPathResult=Z,c.evaluate=function(a,b,c,g){return(new vb(a,c)", + ").evaluate(b,g)},c.createExpression=function(a,b){return new vb(a,b)},c", + ".createNSResolver=function(a){return new wb(a)}});function xb(a,b,c,d){", + "this.top=a;this.right=b;this.bottom=c;this.left=d}h=xb.prototype;h.clon", + "e=function(){return new xb(this.top,this.right,this.bottom,this.left)};", + "h.toString=function(){return\"(\"+this.top+\"t, \"+this.right+\"r, \"+t", + "his.bottom+\"b, \"+this.left+\"l)\"};h.contains=function(a){return this", + "&&a?a instanceof xb?a.left>=this.left&&a.right<=this.right&&a.top>=this", + ".top&&a.bottom<=this.bottom:a.x>=this.left&&a.x<=this.right&&a.y>=this.", + "top&&a.y<=this.bottom:!1};\nh.expand=function(a,b,c,d){da(a)?(this.top-", + "=a.top,this.right+=a.right,this.bottom+=a.bottom,this.left-=a.left):(th", + "is.top-=a,this.right+=Number(b),this.bottom+=Number(c),this.left-=Numbe", + "r(d));return this};h.ceil=function(){this.top=Math.ceil(this.top);this.", + "right=Math.ceil(this.right);this.bottom=Math.ceil(this.bottom);this.lef", + "t=Math.ceil(this.left);return this};\nh.floor=function(){this.top=Math.", + "floor(this.top);this.right=Math.floor(this.right);this.bottom=Math.floo", + "r(this.bottom);this.left=Math.floor(this.left);return this};h.round=fun", + "ction(){this.top=Math.round(this.top);this.right=Math.round(this.right)", + ";this.bottom=Math.round(this.bottom);this.left=Math.round(this.left);re", + "turn this};h.translate=function(a,b){a instanceof x?(this.left+=a.x,thi", + "s.right+=a.x,this.top+=a.y,this.bottom+=a.y):(this.left+=a,this.right+=", + "a,n(b)&&(this.top+=b,this.bottom+=b));return this};\nh.scale=function(a", + ",b){b=n(b)?b:a;this.left*=a;this.right*=a;this.top*=b;this.bottom*=b;re", + "turn this};function yb(a,b,c,d){this.left=a;this.top=b;this.width=c;thi", + "s.height=d}h=yb.prototype;h.clone=function(){return new yb(this.left,th", + "is.top,this.width,this.height)};h.toString=function(){return\"(\"+this.", + "left+\", \"+this.top+\" - \"+this.width+\"w x \"+this.height+\"h)\"};h.", + "contains=function(a){return a instanceof x?a.x>=this.left&&a.x<=this.le", + "ft+this.width&&a.y>=this.top&&a.y<=this.top+this.height:this.left<=a.le", + "ft&&this.left+this.width>=a.left+a.width&&this.top<=a.top&&this.top+thi", + "s.height>=a.top+a.height};\nh.ceil=function(){this.left=Math.ceil(this.", + "left);this.top=Math.ceil(this.top);this.width=Math.ceil(this.width);thi", + "s.height=Math.ceil(this.height);return this};h.floor=function(){this.le", + "ft=Math.floor(this.left);this.top=Math.floor(this.top);this.width=Math.", + "floor(this.width);this.height=Math.floor(this.height);return this};h.ro", + "und=function(){this.left=Math.round(this.left);this.top=Math.round(this", + ".top);this.width=Math.round(this.width);this.height=Math.round(this.hei", + "ght);return this};\nh.translate=function(a,b){a instanceof x?(this.left", + "+=a.x,this.top+=a.y):(this.left+=a,n(b)&&(this.top+=b));return this};h.", + "scale=function(a,b){b=n(b)?b:a;this.left*=a;this.width*=a;this.top*=b;t", + "his.height*=b;return this};function zb(a,b){var c=A(a);return c.default", + "View&&c.defaultView.getComputedStyle&&(a=c.defaultView.getComputedStyle", + "(a,null))?a[b]||a.getPropertyValue(b)||\"\":\"\"}function Bb(a){try{var", + " b=a.getBoundingClientRect()}catch(c){return{left:0,top:0,right:0,botto", + "m:0}}return b}\nfunction Cb(a){var b=A(a),c=new x(0,0);if(a==(b?A(b):do", + "cument).documentElement)return c;a=Bb(a);var d=(b?new B(A(b)):r||(r=new", + " B)).D,b=d.scrollingElement?d.scrollingElement:d.body||d.documentElemen", + "t,d=d.parentWindow||d.defaultView,b=new x(d.pageXOffset||b.scrollLeft,d", + ".pageYOffset||b.scrollTop);c.x=a.left+b.x;c.y=a.top+b.y;return c}functi", + "on Db(a){if(1==a.nodeType)return a=Bb(a),new x(a.left,a.top);a=a.change", + "dTouches?a.changedTouches[0]:a;return new x(a.clientX,a.clientY)};var E", + "b=\"function\"===typeof ShadowRoot;function Fb(a,b){b=Cb(b);var c=Cb(a)", + ";b=new x(b.x-c.x,b.y-c.y);var d=zb(a,\"borderLeftWidth\");var e=zb(a,\"", + "borderRightWidth\");c=zb(a,\"borderTopWidth\");a=zb(a,\"borderBottomWid", + "th\");a=new xb(parseFloat(c),parseFloat(e),parseFloat(a),parseFloat(d))", + ";b.x-=a.left;b.y-=a.top;return b}\nfunction Gb(a,b,c){function d(a,b,c,", + "d,e){d=new yb(c.x+d.left,c.y+d.top,d.width,d.height);c=[0,0];b=[b.width", + ",b.height];var f=[d.left,d.top];d=[d.width,d.height];for(var g=0;2>g;g+", + "+)if(d[g]>b[g])c[g]=e?f[g]+d[g]/2-b[g]/2:f[g];else{var l=f[g]-b[g]+d[g]", + ";0<l?c[g]=l:0>f[g]&&(c[g]=f[g])}e=new x(c[0],c[1]);a.scrollLeft+=e.x;a.", + "scrollTop+=e.y}function e(a){var b=a.parentNode;Eb&&b instanceof Shadow", + "Root&&(b=a.host);return b}for(var f=A(a),g=e(a),l;g&&g!=f.documentEleme", + "nt&&g!=f.body;)l=Fb(g,a),d(g,new z(g.clientWidth,\ng.clientHeight),l,b,", + "c),g=e(g);l=Db(a);a=ya(a?new B(A(a)):r||(r=new B));f=ra()&&\"BackCompat", + "\"!=f.compatMode?f.documentElement:f.body;d(f,a,l,b,c)};aa(\"_\",functi", + "on(a,b,c){c||(c=new yb(0,0,a.offsetWidth,a.offsetHeight));Gb(a,c,b);a=D", + "b(a);return new x(a.x+c.left,a.y+c.top)});; return this._.apply(null,ar", + "guments);}.apply({navigator:typeof window!='undefined'?window.navigator", + ":null,document:typeof window!='undefined'?window.document:null}, argume", + "nts);}", NULL };
diff --git a/third_party/webdriver/patch.diff b/third_party/webdriver/patch.diff index 9f505b1..c96ab3cf 100644 --- a/third_party/webdriver/patch.diff +++ b/third_party/webdriver/patch.diff
@@ -43,6 +43,25 @@ } else { buttonValueMap[bot.events.EventType.CLICK] = [0, 1, 2, null]; buttonValueMap[bot.events.EventType.CONTEXTMENU] = [null, null, 2, null]; +diff --git a/javascript/chrome-driver/atoms.js b/javascript/chrome-driver/atoms.js +index 5cf4416460..3ae27d2b11 100644 +--- a/javascript/chrome-driver/atoms.js ++++ b/javascript/chrome-driver/atoms.js +@@ -142,7 +142,13 @@ webdriver.chrome.scrollIntoView_ = function(elem, region, center) { + + offset = goog.style.getClientPosition(elem); + var windowSize = goog.dom.getDomHelper(elem).getViewportSize(); +- scrollHelper(doc.body, windowSize, offset, region, center); ++ var scrollable; ++ if (goog.userAgent.product.isVersion(61) && doc.compatMode != "BackCompat") { ++ scrollable = doc.documentElement; ++ } else { ++ scrollable = doc.body; ++ } ++ scrollHelper(scrollable, windowSize, offset, region, center); + }; + + diff --git a/rake-tasks/crazy_fun/mappings/javascript.rb b/rake-tasks/crazy_fun/mappings/javascript.rb index 982d36314e..ae0c3e460b 100644 --- a/rake-tasks/crazy_fun/mappings/javascript.rb
diff --git a/tools/fuchsia/local-sdk.py b/tools/fuchsia/local-sdk.py new file mode 100755 index 0000000..5e747dc --- /dev/null +++ b/tools/fuchsia/local-sdk.py
@@ -0,0 +1,71 @@ +#!/usr/bin/env python + +# Copyright 2017 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import os +import shutil +import subprocess +import sys +import tarfile +import tempfile + + +SELF_FILE = os.path.normpath(os.path.abspath(__file__)) +REPOSITORY_ROOT = os.path.abspath(os.path.join( + os.path.dirname(__file__), '..', '..')) + + +def Run(*args): + print 'Run:', ' '.join(args) + subprocess.check_call(args) + + +def EnsureEmptyDir(path): + if os.path.isdir(path): + shutil.rmtree(path) + if not os.path.exists(path): + print 'Creating directory', path + os.makedirs(path) + + +def main(args): + if len(args) != 1 or not os.path.isdir(args[0]): + print 'usage: %s <path_to_fuchsia_tree>' % SELF_FILE + return 1 + + original_dir = os.getcwd() + + fuchsia_root = args[0] + + # Switch to the Fuchsia tree and build an SDK. + os.chdir(fuchsia_root) + Run('scripts/build-magenta.sh', '-t', 'x86_64') + Run('scripts/build-magenta.sh', '-t', 'aarch64') + Run('packages/gn/gen.py', '--target_cpu=x86-64', '--modules=sdk', + '--ignore-skia', '--release') + Run('packages/gn/build.py', '--release') + tempdir = tempfile.mkdtemp() + sdk_tar = os.path.join(tempdir, 'fuchsia-sdk.tgz') + Run('go', 'run', 'scripts/makesdk.go', '-output', sdk_tar, '.') + + # Nuke the SDK from DEPS, put our just-built one there, and set a fake .hash + # file. This means that on next gclient runhooks, we'll restore to the + # real DEPS-determined SDK. + output_dir = os.path.join(REPOSITORY_ROOT, 'third_party', 'fuchsia-sdk') + EnsureEmptyDir(output_dir) + tarfile.open(sdk_tar, mode='r:gz').extractall(path=output_dir) + hash_filename = os.path.join(output_dir, '.hash') + with open(hash_filename, 'w') as f: + f.write('locally-built-sdk') + + # Clean up. + shutil.rmtree(tempdir) + os.chdir(original_dir) + + return 0 + + +if __name__ == '__main__': + sys.exit(main(sys.argv[1:]))
diff --git a/tools/gn/xcode_writer.cc b/tools/gn/xcode_writer.cc index 28ea355..73924d9 100644 --- a/tools/gn/xcode_writer.cc +++ b/tools/gn/xcode_writer.cc
@@ -132,21 +132,12 @@ base::CompareCase::SENSITIVE); } -// TODO(crbug.com/741147) Remove this function and switch to use -// test_application_name once the bug is fixed and GN has rolled past it. -const Target* FindXCTestApplicationTarget( - const Target* xctest_module_target, +const Target* FindApplicationTargetByName( + const std::string& target_name, const std::vector<const Target*>& targets) { - DCHECK(IsXCTestModuleTarget(xctest_module_target)); - DCHECK(base::EndsWith(xctest_module_target->label().name(), - kXCTestModuleTargetNamePostfix, - base::CompareCase::SENSITIVE)); - std::string application_target_name = - xctest_module_target->label().name().substr( - 0, xctest_module_target->label().name().size() - - strlen(kXCTestModuleTargetNamePostfix)); for (const Target* target : targets) { - if (target->label().name() == application_target_name) { + if (target->label().name() == target_name) { + DCHECK(IsApplicationTarget(target)); return target; } } @@ -177,8 +168,8 @@ if (!IsXCTestModuleTarget(target)) continue; - const Target* test_application_target = - FindXCTestApplicationTarget(target, targets); + const Target* test_application_target = FindApplicationTargetByName( + target->bundle_data().xcode_test_application_name(), targets); const PBXTarget* test_application_pbxtarget = bundle_target_to_pbxtarget.at(test_application_target); PBXTarget* module_pbxtarget = bundle_target_to_pbxtarget.at(target); @@ -529,18 +520,6 @@ PBXAttributes xcode_extra_attributes = target->bundle_data().xcode_extra_attributes(); - // TODO(crbug.com/740800): Remove the following comment and code once - // the bug is fixed and gn has rolled past it. - // Test files need to be known to Xcode for proper indexing and for - // discovery of tests function for XCTest, but the compilation is done - // via ninja and thus must prevent Xcode from linking object files via - // this hack. - if (IsXCTestModuleTarget(target)) { - xcode_extra_attributes["OTHER_LDFLAGS"] = "-help"; - xcode_extra_attributes["ONLY_ACTIVE_ARCH"] = "YES"; - xcode_extra_attributes["DEBUG_INFORMATION_FORMAT"] = "dwarf"; - } - const std::string& target_output_name = RebasePath(target->bundle_data() .GetBundleRootDirOutput(target->settings()) @@ -560,8 +539,8 @@ continue; // For XCTest, test files are compiled into the application bundle. - const Target* test_application_target = - FindXCTestApplicationTarget(target, targets); + const Target* test_application_target = FindApplicationTargetByName( + target->bundle_data().xcode_test_application_name(), targets); SearchXCTestFilesForTarget(test_application_target, &xctest_files_per_target); const Target::FileList& xctest_file_list =
diff --git a/tools/grit/grit/testdata/tools/grit/resource_ids b/tools/grit/grit/testdata/tools/grit/resource_ids index d8f71ff..7c2c9fcc 100644 --- a/tools/grit/grit/testdata/tools/grit/resource_ids +++ b/tools/grit/grit/testdata/tools/grit/resource_ids
@@ -153,9 +153,6 @@ "chrome/browser/debugger/frontend/devtools_frontend_resources.grd": { "includes": [21500], }, - "chrome/browser/resources/options_resources.grd": { - "includes": [22000], - }, "cloud_print/virtual_driver/win/install/virtual_driver_setup_resources.grd": { "messages": [22500], },
diff --git a/tools/gritsettings/resource_ids b/tools/gritsettings/resource_ids index 22725ab..d837bd7 100644 --- a/tools/gritsettings/resource_ids +++ b/tools/gritsettings/resource_ids
@@ -93,10 +93,6 @@ "chrome/browser/resources/net_internals_resources.grd": { "includes": [11960], }, - "chrome/browser/resources/options_resources.grd": { - "includes": [11970], - "structures": [11980], - }, "chrome/browser/resources/password_manager_internals_resources.grd": { "includes": [12040], },
diff --git a/tools/json_schema_compiler/feature_compiler.py b/tools/json_schema_compiler/feature_compiler.py index 81a60b6..d6d8f16 100644 --- a/tools/json_schema_compiler/feature_compiler.py +++ b/tools/json_schema_compiler/feature_compiler.py
@@ -70,6 +70,12 @@ } // namespace extensions """ +# Returns true if the list 'l' does not contain any strings that look like +# extension ids. +def ListDoesNotContainPlainExtensionIds(l): + # For now, let's just say anything 32 characters in length is an id. + return len(filter(lambda s: len(s) == 32, l)) == 0 + # A "grammar" for what is and isn't allowed in the features.json files. This # grammar has to list all possible keys and the requirements for each. The # format of each entry is: @@ -96,6 +102,13 @@ # assign the list of Feature::BLESSED_EXTENSION_CONTEXT, # Feature::BLESSED_WEB_PAGE_CONTEXT et al for contexts. If not # specified, defaults to false. +# 'validators': A list of (function, str) pairs with a function to run on the +# value for a feature. Validators allow for more flexible or +# one-off style validation than just what's in the grammar (such +# as validating the content of a string). The validator function +# should return True if the value is valid, and False otherwise. +# If the value is invalid, the specified error will be added for +# that key. # 'values': A list of all possible allowed values for a given key. # 'shared': Boolean that, if set, ensures that only one of the associated # features has the feature property set. Used primarily for complex @@ -110,7 +123,13 @@ 'shared': True }, 'blacklist': { - list: {'subtype': unicode} + list: { + 'subtype': unicode, + 'validators': [ + (ListDoesNotContainPlainExtensionIds, + 'list should only have hex-encoded SHA1 hashes of extension ids') + ] + } }, 'channel': { unicode: { @@ -211,7 +230,13 @@ 'shared': True }, 'whitelist': { - list: {'subtype': unicode} + list: { + 'subtype': unicode, + 'validators': [ + (ListDoesNotContainPlainExtensionIds, + 'list should only have hex-encoded SHA1 hashes of extension ids') + ] + } }, }) @@ -478,6 +503,12 @@ cpp_value = self._GetCheckedValue(key, expected_type, expected_values, enum_map, v) + if 'validators' in expected: + validators = expected['validators'] + for validator, error in validators: + if not validator(v): + self._AddKeyError(key, error) + if cpp_value: if 'shared' in grammar: shared_values[key] = cpp_value
diff --git a/tools/json_schema_compiler/feature_compiler_test.py b/tools/json_schema_compiler/feature_compiler_test.py index 7cf821c40..c9c58f6 100755 --- a/tools/json_schema_compiler/feature_compiler_test.py +++ b/tools/json_schema_compiler/feature_compiler_test.py
@@ -347,5 +347,15 @@ 'No default parent found for bookmarks'): c._CompileFeature('bookmarks.export', { "whitelist": ["asdf"] }) + def testRealIdsDisallowedInWhitelist(self): + fake_id = 'a' * 32; + f = self._parseFeature({'whitelist': [fake_id], + 'extension_types': ['extension'], + 'channel': 'beta'}) + f.Validate('PermissionFeature', {}) + self._hasError( + f, 'list should only have hex-encoded SHA1 hashes of extension ids') + + if __name__ == '__main__': unittest.main()
diff --git a/tools/metrics/histograms/PRESUBMIT.py b/tools/metrics/histograms/PRESUBMIT.py index cb0a613..2bcedd0f 100644 --- a/tools/metrics/histograms/PRESUBMIT.py +++ b/tools/metrics/histograms/PRESUBMIT.py
@@ -20,15 +20,26 @@ def CheckChange(input_api, output_api): """Checks that histograms.xml is pretty-printed and well-formatted.""" + results = [] if ValidationNeeded(input_api): cwd = input_api.PresubmitLocalPath() + + exit_code = input_api.subprocess.call( + ['python', 'pretty_print.py', '--presubmit', '--non-interactive'], + cwd=cwd) + if exit_code != 0: + results.append(output_api.PresubmitError( + 'histograms.xml is not formatted correctly; please run ' + 'git cl format %s to fix.' % cwd)) + exit_code = input_api.subprocess.call( ['python', 'validate_format.py'], cwd=cwd) if exit_code != 0: - return [output_api.PresubmitError( + results.append(output_api.PresubmitError( 'histograms.xml is not well formatted; run %s/validate_format.py ' - 'and fix the reported errors' % cwd)] - return [] + 'and fix the reported errors.' % cwd)) + + return results def CheckChangeOnUpload(input_api, output_api):
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 153d4ac..c60bf91 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -2627,6 +2627,7 @@ <int value="0" label="GVM_EMBEDDER_FORBIDDEN_ACCESS_TO_GUEST"/> <int value="1" label="GVM_INVALID_GUESTVIEW_TYPE"/> + <int value="2" label="GVMF_UNEXPECTED_MESSAGE_BEFORE_GVM_CREATION"/> </enum> <enum name="BadMessageReasonNaCl"> @@ -4110,11 +4111,11 @@ <int value="0" label="Success"/> <int value="1" label="NotSupportedError"/> <int value="2" label="InvalidStateError"/> - <int value="3" label="InvalidAccessError"/> + <int value="3" label="TypeError"/> <int value="4" label="QuotaExceededError"/> - <int value="5" label="UnknownError"/> - <int value="6" label="ClientError"/> - <int value="7" label="OutputError"/> + <int value="5" label="UnknownError (deprecated)"/> + <int value="6" label="ClientError (deprecated)"/> + <int value="7" label="OutputError (deprecated)"/> </enum> <enum name="CertificateChainPosition"> @@ -7375,6 +7376,8 @@ <int value="5" label="Compressed-video requested (resources)"/> <int value="6" label="Original image ('identity') requested (resources)"/> <int value="7" label="Original image ('identity') received (resources)"/> + <int value="8" label="Compressed-video received (resources)"/> + <int value="9" label="Unknown transform received (resources/pages)"/> </enum> <enum name="DataReductionProxyProtocolNotAcceptingTransformReason"> @@ -7722,6 +7725,7 @@ <int value="0" label="Not Default"/> <int value="1" label="Default"/> <int value="2" label="Unknown"/> + <int value="3" label="Other Mode is Default"/> </enum> <enum name="DefaultSearchChangeOrigin"> @@ -7754,6 +7758,10 @@ <int value="2" label="Unknown default"> Chrome is in a unknown default state. </int> + <int value="3" label="Other mode is default"> + The current install of Chrome is not the default web client, yet another + side-by-side install of Chrome is. + </int> </enum> <enum name="DelayBasedEchoQuality"> @@ -22812,6 +22820,7 @@ <int value="-1887862464" label="SpannableInlineAutocomplete:disabled"/> <int value="-1887053262" label="enable-zero-suggest-most-visited-without-serp"/> + <int value="-1884385890" label="AutofillUpstreamShowGoogleLogo:enabled"/> <int value="-1882330924" label="NTPArticleSuggestions:enabled"/> <int value="-1880355454" label="disable-topchrome-md"/> <int value="-1876881908" @@ -23804,6 +23813,7 @@ <int value="1318073661" label="MaterialDesignExtensions:enabled"/> <int value="1319725131" label="enable-distance-field-text"/> <int value="1320201920" label="enable-touchpad-three-finger-click"/> + <int value="1330029351" label="AutofillUpstreamShowGoogleLogo:disabled"/> <int value="1330264457" label="OmniboxUIExperimentVerticalLayout:disabled"/> <int value="1340690624" label="WebPaymentsMethodSectionOrderV2:disabled"/> <int value="1344833841" label="ImeThread:enabled"/> @@ -24292,6 +24302,9 @@ <int value="1" label="Dialog closed without explicit choice"/> <int value="2" label="Other browser selected"/> <int value="3" label="Chrome made default + Relaunch in Metro (obsolete)"/> + <int value="4"> + A side-by-side install of Chrome was made default (not this one). + </int> </enum> <enum name="ManagedUserPasswordChange"> @@ -25312,6 +25325,7 @@ <int value="17" label="SearchSinks"/> <int value="18" label="ProvideSinks"/> <int value="19" label="CreateMediaRouteController"/> + <int value="20" label="RouteControllerCommand"/> </enum> <enum name="MediaRouteProviderWakeup"> @@ -32187,6 +32201,7 @@ <int value="4" label="The response code indicated failure"/> <int value="5" label="IO exception while fetching the url"/> <int value="6" label="Unknown media type"/> + <int value="7" label="HttpUrlConnection crash"/> </enum> <enum name="RemoteProcessInteractionResult">
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 6f2cf77a..720fead 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -2597,16 +2597,24 @@ <histogram name="Ash.Shelf.Palette.Usage" enum="PaletteTrayOptions"> <owner>xiaoyinh@chromium.org</owner> <summary> - Tracks the usage of each pen palette option when palette is not - automatically opened by a stylus eject event. + Recorded every time that the palette option has been selected from the + palette that has been opened manually (not via a stylus eject event). </summary> </histogram> <histogram name="Ash.Shelf.Palette.Usage.AutoOpened" enum="PaletteTrayOptions"> <owner>xiaoyinh@chromium.org</owner> <summary> - Tracks the usage of each pen palette option when palette is automatically - opened by a stylus eject event. + Recorded every time that the palette option has been selected from the + palette that has been opened automatically (by a stylus eject event). + </summary> +</histogram> + +<histogram name="Ash.Shelf.Palette.Usage.Shortcut" enum="PaletteTrayOptions"> + <owner>kaznacheev@chromium.org</owner> + <summary> + Recorded every time that the palette option has been selected by means other + that the palette menu (e.g. stylus barrel button or a keyboard accelerator). </summary> </histogram> @@ -13218,6 +13226,17 @@ </summary> </histogram> +<histogram name="Dialog.DialogDelegate.Duration" units="ms"> + <owner>pdyson@chromium.org</owner> + <summary> + How long dialog boxes are open, for dialog boxes created using the parent + class DialogDelegate. This will include bubbles that use + BubbleDialogDelegateView as a parent class, and dialogs that use + DialogDelegateView as a parent class. This is logged on delegate + destruction. + </summary> +</histogram> + <histogram name="DirectWrite.Fonts.BuildCache.File.Size" units="KB"> <owner>shrikant@chromium.org</owner> <summary> @@ -56032,6 +56051,16 @@ </summary> </histogram> +<histogram name="Platform.ServiceFailureHashes"> + <owner>ddavenport@chromium.org</owner> + <summary> + The 32-bit hash of the name of the service that failed. The name of the + service is hashed using the same algorithm as used for the hashes in + Platform.KernelWarningHashes. The first instance of each service failure is + also collected separately via the crash reporter. + </summary> +</histogram> + <histogram name="Platform.SmartTransferErrors"> <owner>gwendal@google.com</owner> <summary>Disk communication errors (SMART 199), sent at boot.</summary>
diff --git a/tools/metrics/ukm/ukm.xml b/tools/metrics/ukm/ukm.xml index 4ef64bd5..6bf6dd2 100644 --- a/tools/metrics/ukm/ukm.xml +++ b/tools/metrics/ukm/ukm.xml
@@ -617,6 +617,11 @@ Size of process' working set. </summary> </metric> + <metric name="Total2.PrivateMemoryFootprint"> + <summary> + Measure of total memory consumed by all processes. + </summary> + </metric> <metric name="V8"> <summary> Measure of memory consumed by V8.
diff --git a/tools/perf/BUILD.gn b/tools/perf/BUILD.gn index 241454e..55dacdd 100644 --- a/tools/perf/BUILD.gn +++ b/tools/perf/BUILD.gn
@@ -30,6 +30,9 @@ # For indexeddb_perf "//chrome/test/data/indexeddb/", + + # For Pylib used by VR tests + "//build/android/pylib/", ] }
diff --git a/tools/perf/PRESUBMIT.py b/tools/perf/PRESUBMIT.py index 2d484c9..37c1676 100644 --- a/tools/perf/PRESUBMIT.py +++ b/tools/perf/PRESUBMIT.py
@@ -36,12 +36,15 @@ chromium_src_dir, 'third_party', 'catapult', 'tracing') py_utils_dir = input_api.os_path.join( chromium_src_dir, 'third_party', 'catapult', 'common', 'py_utils') + android_pylib_dir = input_api.os_path.join( + chromium_src_dir, 'build', 'android') return [ telemetry_dir, input_api.os_path.join(telemetry_dir, 'third_party', 'mock'), experimental_dir, tracing_dir, - py_utils_dir + py_utils_dir, + android_pylib_dir, ]
diff --git a/tools/perf/benchmarks/blink_perf.py b/tools/perf/benchmarks/blink_perf.py index 55914c9..7a3b5cc 100644 --- a/tools/perf/benchmarks/blink_perf.py +++ b/tools/perf/benchmarks/blink_perf.py
@@ -453,7 +453,6 @@ @benchmark.Owner(emails=['dmurph@chromium.org']) -@benchmark.Disabled('all') class BlinkPerfOWPStorage(_BlinkPerfBenchmark): tag = 'owp_storage' subdir = 'OWPStorage'
diff --git a/tools/perf/benchmarks/media.py b/tools/perf/benchmarks/media.py index 0def70b7..1b0ef206 100644 --- a/tools/perf/benchmarks/media.py +++ b/tools/perf/benchmarks/media.py
@@ -229,5 +229,9 @@ def GetExpectations(self): class StoryExpectations(story.expectations.StoryExpectations): def SetExpectations(self): - pass # Nothing disabled. + self.DisableStory( + 'startup_test.html?testType=A&doNotWaitForBodyOnLoad=true', + [story.expectations.ANDROID_WEBVIEW], + 'crbug.com/755639') + return StoryExpectations()
diff --git a/tools/perf/benchmarks/smoothness.py b/tools/perf/benchmarks/smoothness.py index 8b5cac5..45fc314 100644 --- a/tools/perf/benchmarks/smoothness.py +++ b/tools/perf/benchmarks/smoothness.py
@@ -152,6 +152,9 @@ self.DisableStory('http://geoapis.appspot.com/agdnZW9hcGlzchMLEgtFeGFtcGxlQ29kZRjh1wIM', [story_module.expectations.ANDROID_NEXUS5], 'crbug.com/364248') + self.DisableStory('tough_canvas_cases/canvas_toBlob.html', + [story_module.expectations.ANDROID_ONE], + 'crbug.com/755657') return StoryExpectations()
diff --git a/tools/perf/benchmarks/start_with_ext.py b/tools/perf/benchmarks/start_with_ext.py index 27ca5f1..c251088 100644 --- a/tools/perf/benchmarks/start_with_ext.py +++ b/tools/perf/benchmarks/start_with_ext.py
@@ -31,6 +31,8 @@ @benchmark.Enabled('has tabs') +@benchmark.Disabled('mac') # crbug.com/563424 +@benchmark.Disabled('win', 'linux', 'reference', 'android') class StartWithExtCold(_StartWithExt): """Measure time to start Chrome cold with extensions.""" options = {'pageset_repeat': 5} @@ -43,12 +45,13 @@ def GetExpectations(self): class StoryExpectations(story.expectations.StoryExpectations): def SetExpectations(self): - self.DisableStory('blank_page.html', [story.expectations.ALL_WIN], - 'crbug.com/753408') + pass # blank_page.html not disabled. return StoryExpectations() @benchmark.Enabled('has tabs') +@benchmark.Disabled('mac') # crbug.com/563424 +@benchmark.Disabled('win', 'linux', 'reference', 'android') class StartWithExtWarm(_StartWithExt): """Measure time to start Chrome warm with extensions.""" options = {'pageset_repeat': 20} @@ -61,6 +64,5 @@ def GetExpectations(self): class StoryExpectations(story.expectations.StoryExpectations): def SetExpectations(self): - self.DisableStory('blank_page.html', [story.expectations.ALL_WIN], - 'crbug.com/753408') + pass # blank_page.html not disabled. return StoryExpectations()
diff --git a/tools/perf/benchmarks/system_health_smoke_test.py b/tools/perf/benchmarks/system_health_smoke_test.py index 931a8c3..67812ce 100644 --- a/tools/perf/benchmarks/system_health_smoke_test.py +++ b/tools/perf/benchmarks/system_health_smoke_test.py
@@ -72,6 +72,9 @@ 'benchmarks.system_health_smoke_test.SystemHealthBenchmarkSmokeTest.system_health.memory_mobile.load:news:cnn', # pylint: disable=line-too-long 'benchmarks.system_health_smoke_test.SystemHealthBenchmarkSmokeTest.system_health.memory_desktop.browse:news:hackernews', # pylint: disable=line-too-long 'benchmarks.system_health_smoke_test.SystemHealthBenchmarkSmokeTest.system_health.memory_desktop.browse:media:imgur', # pylint: disable=line-too-long + + # crbug.com/755969 + 'benchmarks.system_health_smoke_test.SystemHealthBenchmarkSmokeTest.system_health.memory_desktop.browse:search:google', # pylint: disable=line-too-long })
diff --git a/tools/perf/benchmarks/v8_browsing.py b/tools/perf/benchmarks/v8_browsing.py index bcd1dee..89623a43 100644 --- a/tools/perf/benchmarks/v8_browsing.py +++ b/tools/perf/benchmarks/v8_browsing.py
@@ -71,6 +71,8 @@ # which enables memory-infra V8 code stats in V8 code size benchmarks # only (to not slow down detailed memory dumps in other benchmarks). 'disabled-by-default-memory-infra.v8.code_stats', + # Blink categories. + 'blink_gc', ] options = timeline_based_measurement.Options( chrome_trace_category_filter.ChromeTraceCategoryFilter( @@ -81,7 +83,7 @@ memory_dump_config.AddTrigger('light', 1000) options.config.chrome_trace_config.SetMemoryDumpConfig(memory_dump_config) options.SetTimelineBasedMetrics([ - 'expectedQueueingTimeMetric', 'v8AndMemoryMetrics']) + 'expectedQueueingTimeMetric', 'v8AndMemoryMetrics', 'blinkGcMetric']) return options @classmethod @@ -126,6 +128,8 @@ 'v8', 'webkit.console', 'disabled-by-default-v8.runtime_stats', + # Blink categories. + 'blink_gc', ] options = timeline_based_measurement.Options( chrome_trace_category_filter.ChromeTraceCategoryFilter( @@ -137,7 +141,8 @@ options.config.chrome_trace_config.SetMemoryDumpConfig(memory_dump_config) options.SetTimelineBasedMetrics([ - 'expectedQueueingTimeMetric', 'runtimeStatsTotalMetric', 'gcMetric']) + 'expectedQueueingTimeMetric', 'runtimeStatsTotalMetric', 'gcMetric', + 'blinkGcMetric']) return options
diff --git a/tools/perf/contrib/vr_benchmarks/run_benchmark b/tools/perf/contrib/vr_benchmarks/run_benchmark index f7eacc1..58ded5b 100755 --- a/tools/perf/contrib/vr_benchmarks/run_benchmark +++ b/tools/perf/contrib/vr_benchmarks/run_benchmark
@@ -30,27 +30,11 @@ 'found') dev = attached_devices[0] - # Reinstall VrCore - # TODO(bsheedy): Change this to work if VrCore is still installed as a system - # app - dev.Install(os.path.join(host_paths.DIR_SOURCE_ROOT, 'third_party', - 'gvr-android-sdk', 'test-apks', 'vr_services', - 'vr_services_current.apk')) - # Install the NFC simulator APK # TODO(bsheedy): Find a better way to get path to generated APK dev.Install(os.path.join(host_paths.DIR_SOURCE_ROOT, 'out', 'Release', 'apks', 'VrNfcSimulator.apk')) - # Setup VrCore - # TODO(bsheedy): Support different files to allow tests to be run on both - # Daydream ready and non-Daydream-ready devices - preferences = shared_preference_utils.ExtractSettingsFromJson(os.path.join( - host_paths.DIR_SOURCE_ROOT, 'chrome', 'android', - 'shared_preference_files', 'test', 'vr_ddview_skipdon_setupcomplete.json' - )) - shared_preference_utils.ApplySharedPreferenceSettings(dev, preferences) - # Start the benchmarks return benchmark_runner.main(vr_config.Config(['vr_benchmarks']))
diff --git a/tools/perf/contrib/vr_benchmarks/vr_benchmarks/vr_memory.py b/tools/perf/contrib/vr_benchmarks/vr_benchmarks/vr_memory.py index 5b03bb1b..0c72eb482 100644 --- a/tools/perf/contrib/vr_benchmarks/vr_benchmarks/vr_memory.py +++ b/tools/perf/contrib/vr_benchmarks/vr_benchmarks/vr_memory.py
@@ -4,10 +4,11 @@ from benchmarks import memory from core import perf_benchmark from telemetry import benchmark +# TODO(bsheedy): Remove the try/except once the VR-specific run_benchmark +# is replaced with the regular run_benchmark try: from vr_page_sets import webvr_sample_pages except ImportError: - # Make Pylint happy - doesn't think vr_page_sets can be imported from contrib.vr_benchmarks.vr_page_sets import webvr_sample_pages @@ -15,6 +16,15 @@ class WebVrMemorySamplePages(perf_benchmark.PerfBenchmark): """Measures WebVR memory on an official sample page with settings tweaked.""" + @classmethod + def AddBenchmarkCommandLineArgs(cls, parser): + parser.add_option('--shared-prefs-file', + help='The path relative to the Chromium source root ' + 'to a file containing a JSON list of shared ' + 'preference files to edit and how to do so. ' + 'See examples in //chrome/android/' + 'shared_preference_files/test/') + def CreateCoreTimelineBasedMeasurementOptions(self): return memory.CreateCoreTimelineBasedMemoryMeasurementOptions()
diff --git a/tools/perf/contrib/vr_benchmarks/vr_page_sets/shared_android_vr_page_state.py b/tools/perf/contrib/vr_benchmarks/vr_page_sets/shared_android_vr_page_state.py new file mode 100644 index 0000000..9e78509 --- /dev/null +++ b/tools/perf/contrib/vr_benchmarks/vr_page_sets/shared_android_vr_page_state.py
@@ -0,0 +1,63 @@ +# Copyright 2017 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import os +from core import path_util +path_util.AddAndroidPylibToPath() +from pylib.utils import shared_preference_utils +from telemetry.core import android_platform +from telemetry.core import platform +from telemetry.page import shared_page_state +from telemetry.internal.platform import android_device + + +class SharedAndroidVrPageState(shared_page_state.SharedPageState): + """SharedPageState for VR Telemetry tests. + + Performs the same functionality as SharedPageState, but with two main + differences: + 1. It is currently restricted to Android + 2. It performs VR-specific setup such as installing and configuring + additional APKs that are necessary for testing + """ + def __init__(self, test, finder_options, story_set): + # TODO(bsheedy): See about making this a cross-platform SharedVrPageState - + # Seems like we should be able to use SharedPageState's default platform + # property instead of specifying AndroidPlatform, and then just perform + # different setup based off the platform type + device = android_device.GetDevice(finder_options) + assert device, 'Android device is required for this story' + self._platform = platform.GetPlatformForDevice(device, finder_options) + assert self._platform, 'Unable to create Android platform' + assert isinstance(self._platform, android_platform.AndroidPlatform) + + super(SharedAndroidVrPageState, self).__init__(test, finder_options, + story_set) + self._PerformAndroidVrSetup() + + def _PerformAndroidVrSetup(self): + self._InstallVrCore() + self._ConfigureVrCore() + + def _InstallVrCore(self): + # TODO(bsheedy): Add support for temporarily replacing it if it's still + # installed as a system app on the test device + self._platform.InstallApplication( + os.path.join(path_util.GetChromiumSrcDir(), 'third_party', + 'gvr-android-sdk', 'test-apks', 'vr_services', + 'vr_services_current.apk')) + + def _ConfigureVrCore(self): + settings = shared_preference_utils.ExtractSettingsFromJson( + os.path.join(path_util.GetChromiumSrcDir(), + self._finder_options.shared_prefs_file)) + for setting in settings: + shared_pref = self._platform.GetSharedPrefs(setting['package'], + setting['filename']) + shared_preference_utils.ApplySharedPreferenceSetting( + shared_pref, setting) + + @property + def platform(self): + return self._platform
diff --git a/tools/perf/contrib/vr_benchmarks/vr_page_sets/webvr_sample_pages.py b/tools/perf/contrib/vr_benchmarks/vr_page_sets/webvr_sample_pages.py index 8d00a63a..afc162f7 100644 --- a/tools/perf/contrib/vr_benchmarks/vr_page_sets/webvr_sample_pages.py +++ b/tools/perf/contrib/vr_benchmarks/vr_page_sets/webvr_sample_pages.py
@@ -6,6 +6,13 @@ import os +# TODO(bsheedy): Remove the try/except once the VR-specific run_benchmark +# is replaced with the regular run_benchmark +try: + from vr_page_sets import shared_android_vr_page_state as vr_state +except ImportError: + from contrib.vr_benchmarks.vr_page_sets import ( + shared_android_vr_page_state as vr_state) SAMPLE_DIR = os.path.join(os.path.dirname(__file__), '..', '..', '..', '..', '..', @@ -20,8 +27,9 @@ url += '?' + '&'.join(get_parameters) name = url.replace('.html', '') url = 'file://' + os.path.join(SAMPLE_DIR, url) - super(WebVrSamplePage, self).__init__(url=url, page_set=page_set, - name=name) + super(WebVrSamplePage, self).__init__( + url=url, page_set=page_set, name=name, + shared_page_state_class=vr_state.SharedAndroidVrPageState) def RunPageInteractions(self, action_runner): action_runner.TapElement(selector='canvas[id="webgl-canvas"]') @@ -33,6 +41,7 @@ def __init__(self): super(WebVrSamplePageSet, self).__init__() + # Standard sample app with no changes self.AddStory(WebVrSamplePage(['canvasClickPresents=1', 'renderScale=1'], self))
diff --git a/tools/perf/core/benchmark_sharding_map.json b/tools/perf/core/benchmark_sharding_map.json index c0c6a29..bb6a9e0 100644 --- a/tools/perf/core/benchmark_sharding_map.json +++ b/tools/perf/core/benchmark_sharding_map.json
@@ -17,7 +17,8 @@ "build13-b1--device3": { "benchmarks": [ "page_cycler_v2.intl_ja_zh", - "v8.runtimestats.browsing_mobile_classic" + "v8.runtimestats.browsing_mobile_classic", + "blink_perf.owp_storage" ] }, "build13-b1--device4": { @@ -247,7 +248,8 @@ "build73-b1--device3": { "benchmarks": [ "page_cycler_v2.intl_ja_zh", - "v8.runtimestats.browsing_mobile_classic" + "v8.runtimestats.browsing_mobile_classic", + "blink_perf.owp_storage" ] }, "build73-b1--device4": { @@ -475,7 +477,8 @@ }, "build164-b1--device3": { "benchmarks": [ - "system_health.common_desktop" + "system_health.common_desktop", + "blink_perf.owp_storage" ] }, "build164-b1--device4": { @@ -682,7 +685,8 @@ "build15-b1--device3": { "benchmarks": [ "page_cycler_v2.intl_ja_zh", - "v8.runtimestats.browsing_mobile_classic" + "v8.runtimestats.browsing_mobile_classic", + "blink_perf.owp_storage" ] }, "build15-b1--device4": { @@ -910,7 +914,8 @@ }, "build112-b1--device3": { "benchmarks": [ - "system_health.common_desktop" + "system_health.common_desktop", + "blink_perf.owp_storage" ] }, "build112-b1--device4": { @@ -1290,7 +1295,8 @@ "build9-b1--device3": { "benchmarks": [ "page_cycler_v2.intl_ja_zh", - "v8.runtimestats.browsing_mobile_classic" + "v8.runtimestats.browsing_mobile_classic", + "blink_perf.owp_storage" ] }, "build9-b1--device4": { @@ -1347,7 +1353,8 @@ "build17-b1--device3": { "benchmarks": [ "page_cycler_v2.intl_ja_zh", - "v8.runtimestats.browsing_mobile_classic" + "v8.runtimestats.browsing_mobile_classic", + "blink_perf.owp_storage" ] }, "build17-b1--device4": { @@ -1577,7 +1584,8 @@ "build245-m4--device3": { "benchmarks": [ "page_cycler_v2.intl_ja_zh", - "v8.runtimestats.browsing_mobile_classic" + "v8.runtimestats.browsing_mobile_classic", + "blink_perf.owp_storage" ] }, "build245-m4--device4": { @@ -1817,6 +1825,7 @@ "blink_perf.bindings", "blink_perf.blink_gc", "blink_perf.canvas", + "blink_perf.owp_storage", "dummy_benchmark.noisy_benchmark_1", "loading.desktop", "octane", @@ -1986,6 +1995,7 @@ "blink_perf.bindings", "blink_perf.blink_gc", "blink_perf.canvas", + "blink_perf.owp_storage", "dummy_benchmark.noisy_benchmark_1", "loading.desktop", "octane", @@ -2152,6 +2162,7 @@ "blink_perf.bindings", "blink_perf.blink_gc", "blink_perf.canvas", + "blink_perf.owp_storage", "dummy_benchmark.noisy_benchmark_1", "loading.desktop", "octane", @@ -2317,6 +2328,7 @@ "blink_perf.bindings", "blink_perf.blink_gc", "blink_perf.canvas", + "blink_perf.owp_storage", "dummy_benchmark.noisy_benchmark_1", "loading.desktop", "octane", @@ -2484,6 +2496,7 @@ "blink_perf.bindings", "blink_perf.blink_gc", "blink_perf.canvas", + "blink_perf.owp_storage", "dummy_benchmark.noisy_benchmark_1", "loading.desktop", "octane", @@ -2650,6 +2663,7 @@ "blink_perf.bindings", "blink_perf.blink_gc", "blink_perf.canvas", + "blink_perf.owp_storage", "dummy_benchmark.noisy_benchmark_1", "loading.desktop", "octane", @@ -2852,6 +2866,7 @@ "blink_perf.bindings", "blink_perf.blink_gc", "blink_perf.canvas", + "blink_perf.owp_storage", "dummy_benchmark.noisy_benchmark_1", "loading.desktop", "octane", @@ -2978,6 +2993,7 @@ }, "build139-b1": { "benchmarks": [ + "blink_perf.owp_storage", "page_cycler_v2.typical_25", "speedometer-turbo", "system_health.common_mobile", @@ -3216,6 +3232,7 @@ "blink_perf.bindings", "blink_perf.blink_gc", "blink_perf.canvas", + "blink_perf.owp_storage", "dummy_benchmark.noisy_benchmark_1", "loading.desktop", "octane", @@ -3378,6 +3395,7 @@ }, "build203-b4": { "benchmarks": [ + "blink_perf.owp_storage", "page_cycler_v2.typical_25", "speedometer-turbo", "system_health.common_mobile", @@ -3616,6 +3634,7 @@ "blink_perf.bindings", "blink_perf.blink_gc", "blink_perf.canvas", + "blink_perf.owp_storage", "dummy_benchmark.noisy_benchmark_1", "loading.desktop", "octane", @@ -3782,6 +3801,7 @@ "blink_perf.bindings", "blink_perf.blink_gc", "blink_perf.canvas", + "blink_perf.owp_storage", "dummy_benchmark.noisy_benchmark_1", "loading.desktop", "octane", @@ -3948,6 +3968,7 @@ "blink_perf.bindings", "blink_perf.blink_gc", "blink_perf.canvas", + "blink_perf.owp_storage", "dummy_benchmark.noisy_benchmark_1", "loading.desktop", "octane", @@ -4114,6 +4135,7 @@ "blink_perf.bindings", "blink_perf.blink_gc", "blink_perf.canvas", + "blink_perf.owp_storage", "dummy_benchmark.noisy_benchmark_1", "loading.desktop", "octane", @@ -4280,6 +4302,7 @@ "blink_perf.bindings", "blink_perf.blink_gc", "blink_perf.canvas", + "blink_perf.owp_storage", "dummy_benchmark.noisy_benchmark_1", "loading.desktop", "octane", @@ -4446,6 +4469,7 @@ "blink_perf.bindings", "blink_perf.blink_gc", "blink_perf.canvas", + "blink_perf.owp_storage", "dummy_benchmark.noisy_benchmark_1", "loading.desktop", "octane", @@ -4612,6 +4636,7 @@ "blink_perf.bindings", "blink_perf.blink_gc", "blink_perf.canvas", + "blink_perf.owp_storage", "dummy_benchmark.noisy_benchmark_1", "loading.desktop", "octane", @@ -4756,6 +4781,7 @@ "blink_perf.dom", "blink_perf.events", "blink_perf.layout", + "blink_perf.owp_storage", "blink_perf.paint", "blink_perf.parser", "blink_perf.shadow_dom",
diff --git a/tools/perf/core/desktop_benchmark_avg_times.json b/tools/perf/core/desktop_benchmark_avg_times.json index 1cf1e62..19b0ffc 100644 --- a/tools/perf/core/desktop_benchmark_avg_times.json +++ b/tools/perf/core/desktop_benchmark_avg_times.json
@@ -9,6 +9,7 @@ "blink_perf.dom": 98.51104682236321, "blink_perf.events": 66.05652102455497, "blink_perf.layout": 453.38422619201697, + "blink_perf.owp_storage": 30.0, "blink_perf.paint": 51.07198746293505, "blink_perf.parser": 400.27208882935196, "blink_perf.shadow_dom": 81.56559749378646,
diff --git a/tools/perf/core/path_util.py b/tools/perf/core/path_util.py index 348d7a0..acb100c 100644 --- a/tools/perf/core/path_util.py +++ b/tools/perf/core/path_util.py
@@ -32,6 +32,10 @@ return os.path.join(GetPerfDir(), 'contrib') +def GetAndroidPylibDir(): + return os.path.join(GetChromiumSrcDir(), 'build', 'android') + + def AddTelemetryToPath(): telemetry_path = GetTelemetryDir() if telemetry_path not in sys.path: @@ -60,3 +64,9 @@ def GetWprGoDir(): return os.path.join( GetChromiumSrcDir(), 'third_party', 'catapult', 'web_page_replay_go') + + +def AddAndroidPylibToPath(): + android_pylib_path = GetAndroidPylibDir() + if android_pylib_path not in sys.path: + sys.path.insert(1, android_pylib_path)
diff --git a/tools/perf/core/story_expectation_validator.py b/tools/perf/core/story_expectation_validator.py index b14fe08..4c30b2c 100755 --- a/tools/perf/core/story_expectation_validator.py +++ b/tools/perf/core/story_expectation_validator.py
@@ -8,6 +8,7 @@ from core import benchmark_finders from core import path_util path_util.AddTelemetryToPath() +path_util.AddAndroidPylibToPath() from telemetry.internal.browser import browser_options @@ -31,6 +32,8 @@ options.tabset_repeat = 1 # test_path required for blink_perf benchmark in contrib/. options.test_path = '' + # shared_prefs_file required for benchmarks in contrib/vr_benchmarks/ + options.shared_prefs_file = '' story_set = b.CreateStorySet(options) failed_stories = b.GetBrokenExpectations(story_set) assert not failed_stories, 'Incorrect story names: %s' % str(failed_stories)
diff --git a/tools/perf/validate_wpr_archives b/tools/perf/validate_wpr_archives index d43c782..f5a7e28ed 100755 --- a/tools/perf/validate_wpr_archives +++ b/tools/perf/validate_wpr_archives
@@ -13,6 +13,8 @@ from py_utils import cloud_storage +path_util.AddAndroidPylibToPath() + def GetAllStorySets(): story_sets = []
diff --git a/tools/resources/dummy.c b/tools/resources/dummy.c deleted file mode 100644 index e285de2..0000000 --- a/tools/resources/dummy.c +++ /dev/null
@@ -1,7 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -int main(int argc, char** argv) { - return 0; -}
diff --git a/tools/resources/generate_resource_whitelist.gni b/tools/resources/generate_resource_whitelist.gni index f45b1ea..33bc4b87a 100644 --- a/tools/resources/generate_resource_whitelist.gni +++ b/tools/resources/generate_resource_whitelist.gni
@@ -21,32 +21,17 @@ # output = "$target_gen_dir/pak_whitelist.txt" # } template("generate_resource_whitelist") { - # Wrap the shared_library in an executable so that it does not get added - # as a data_dep. - # TODO(crbug/748113): Remove once GN has a way to specify compile-only deps. - _deps = invoker.deps - _toolchain = get_label_info(_deps[0], "toolchain") - assert(current_toolchain == _toolchain, - "See crbug.com/748113, crbug.com/749003 for context") - executable("${target_name}__exec") { - forward_variables_from(invoker, [ "deps" ]) - sources = [ - "//tools/resources/dummy.c", - ] - - # dummy.c should be built without -finstrument-functions (crbug.com/750120). - configs -= [ "//build/config/android:default_cygprofile_instrumentation" ] - configs += [ "//build/config/android:no_cygprofile_instrumentation" ] - } action(target_name) { - deps = [ - ":${target_name}__exec($_toolchain)", - ] + forward_variables_from(invoker, [ "deps" ]) assert(is_android, "Resource whitelist currently implemented only on Android") script = "//tools/resources/generate_resource_whitelist.py" + inputs = [ + invoker.input, + ] + outputs = [ invoker.output, ]
diff --git a/tools/roll_webrtc.py b/tools/roll_webrtc.py index 0f2f56f..37c1bc57 100755 --- a/tools/roll_webrtc.py +++ b/tools/roll_webrtc.py
@@ -20,7 +20,6 @@ find_depot_tools.add_depot_tools_to_path() import rietveld import roll_dep_svn -from gclient import GClientKeywords from third_party import upload # Avoid depot_tools/third_party/upload.py print verbose messages. @@ -62,6 +61,10 @@ CLInfo = collections.namedtuple('CLInfo', ['issue', 'url', 'rietveld_server']) +def _VarLookup(local_scope): + return lambda var_name: local_scope['vars'][var_name] + + def _PosixPath(path): """Convert a possibly-Windows path to a posix-style path.""" (_, path) = os.path.splitdrive(path) @@ -94,9 +97,8 @@ def _ParseDepsDict(deps_content): local_scope = {} - var = GClientKeywords.VarImpl({}, local_scope) global_scope = { - 'Var': var.Lookup, + 'Var': _VarLookup(local_scope), 'deps_os': {}, } exec(deps_content, global_scope, local_scope)
diff --git a/ui/accessibility/BUILD.gn b/ui/accessibility/BUILD.gn index 324df01..c4169a08 100644 --- a/ui/accessibility/BUILD.gn +++ b/ui/accessibility/BUILD.gn
@@ -51,6 +51,8 @@ "ax_tree_update.h", "platform/ax_android_constants.cc", "platform/ax_android_constants.h", + "platform/ax_platform_node.cc", + "platform/ax_platform_node.h", "platform/ax_platform_unique_id.cc", "platform/ax_platform_unique_id.h", "platform/ax_snapshot_node_android_platform.cc", @@ -59,8 +61,6 @@ if (has_native_accessibility) { sources += [ - "platform/ax_platform_node.cc", - "platform/ax_platform_node.h", "platform/ax_platform_node_base.cc", "platform/ax_platform_node_base.h", "platform/ax_platform_node_delegate.h",
diff --git a/ui/accessibility/ax_mode_observer.h b/ui/accessibility/ax_mode_observer.h new file mode 100644 index 0000000..c1fa63c9 --- /dev/null +++ b/ui/accessibility/ax_mode_observer.h
@@ -0,0 +1,23 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_ACCESSIBILITY_PLATFORM_AX_MODE_OBSERVER_H_ +#define UI_ACCESSIBILITY_PLATFORM_AX_MODE_OBSERVER_H_ + +#include "ui/accessibility/ax_export.h" +#include "ui/accessibility/ax_modes.h" + +namespace ui { + +class AX_EXPORT AXModeObserver { + public: + virtual ~AXModeObserver() {} + + // Notifies when accessibility mode changes. + virtual void OnAXModeAdded(ui::AXMode mode) = 0; +}; + +} // namespace ui + +#endif // UI_ACCESSIBILITY_PLATFORM_AX_MODE_OBSERVER_H_ \ No newline at end of file
diff --git a/ui/accessibility/platform/ax_platform_node.cc b/ui/accessibility/platform/ax_platform_node.cc index b35ecb9..e891223c 100644 --- a/ui/accessibility/platform/ax_platform_node.cc +++ b/ui/accessibility/platform/ax_platform_node.cc
@@ -12,6 +12,10 @@ namespace ui { +// static +base::LazyInstance<base::ObserverList<AXModeObserver>>::Leaky + ui::AXPlatformNode::ax_mode_observers_ = LAZY_INSTANCE_INITIALIZER; + AXPlatformNode::AXPlatformNode() {} AXPlatformNode::~AXPlatformNode() { @@ -20,4 +24,20 @@ void AXPlatformNode::Destroy() { } +// static +void AXPlatformNode::AddAXModeObserver(AXModeObserver* observer) { + ax_mode_observers_.Get().AddObserver(observer); +} + +// static +void AXPlatformNode::RemoveAXModeObserver(AXModeObserver* observer) { + ax_mode_observers_.Get().RemoveObserver(observer); +} + +// static +void AXPlatformNode::NotifyAddAXModeFlags(ui::AXMode mode_flags) { + for (auto& observer : ax_mode_observers_.Get()) + observer.OnAXModeAdded(mode_flags); +} + } // namespace ui
diff --git a/ui/accessibility/platform/ax_platform_node.h b/ui/accessibility/platform/ax_platform_node.h index 5c1f26f..9753a313 100644 --- a/ui/accessibility/platform/ax_platform_node.h +++ b/ui/accessibility/platform/ax_platform_node.h
@@ -5,9 +5,12 @@ #ifndef UI_ACCESSIBILITY_PLATFORM_AX_PLATFORM_NODE_H_ #define UI_ACCESSIBILITY_PLATFORM_AX_PLATFORM_NODE_H_ +#include "base/lazy_instance.h" +#include "base/observer_list.h" #include "build/build_config.h" #include "ui/accessibility/ax_enums.h" #include "ui/accessibility/ax_export.h" +#include "ui/accessibility/ax_mode_observer.h" #include "ui/gfx/native_widget_types.h" namespace ui { @@ -30,6 +33,15 @@ static AXPlatformNode* FromNativeViewAccessible( gfx::NativeViewAccessible accessible); + // Register and unregister to receive notifications about AXMode changes + // for this node. + static void AddAXModeObserver(ui::AXModeObserver* observer); + static void RemoveAXModeObserver(ui::AXModeObserver* observer); + + // Helper static function to notify all global observers about + // the addition of an AXMode flag. + static void NotifyAddAXModeFlags(ui::AXMode mode_flags); + // Call Destroy rather than deleting this, because the subclass may // use reference counting. virtual void Destroy(); @@ -49,6 +61,11 @@ protected: AXPlatformNode(); virtual ~AXPlatformNode(); + + private: + // Global ObserverList for AXMode changes. + static base::LazyInstance<base::ObserverList<AXModeObserver>>::Leaky + ax_mode_observers_; }; } // namespace ui
diff --git a/ui/accessibility/platform/ax_platform_node_win.cc b/ui/accessibility/platform/ax_platform_node_win.cc index 88902b9..d6884db 100644 --- a/ui/accessibility/platform/ax_platform_node_win.cc +++ b/ui/accessibility/platform/ax_platform_node_win.cc
@@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "ui/accessibility/platform/ax_platform_node_win.h" #include "base/containers/hash_tables.h" #include "base/lazy_instance.h" #include "base/strings/string_number_conversions.h" @@ -13,12 +14,12 @@ #include "third_party/iaccessible2/ia2_api_all.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/accessibility/ax_action_data.h" +#include "ui/accessibility/ax_mode_observer.h" #include "ui/accessibility/ax_node_data.h" #include "ui/accessibility/ax_role_properties.h" #include "ui/accessibility/ax_text_utils.h" #include "ui/accessibility/ax_tree_data.h" #include "ui/accessibility/platform/ax_platform_node_delegate.h" -#include "ui/accessibility/platform/ax_platform_node_win.h" #include "ui/accessibility/platform/ax_platform_unique_id.h" #include "ui/base/win/atl_module.h" #include "ui/gfx/geometry/rect_conversions.h" @@ -134,6 +135,12 @@ const WCHAR* const IA2_RELATION_DETAILS_FOR = L"detailsFor"; const WCHAR* const IA2_RELATION_ERROR_MESSAGE = L"errorMessage"; +// There is no easy way to decouple |kScreenReader| and |kHTML| accessibility +// modes when Windows screen readers are used. For example, certain roles use +// the HTML tag name. Input fields require their type attribute to be exposed. +const uint32_t kScreenReaderAndHTMLAccessibilityModes = + ui::AXMode::kScreenReader | ui::AXMode::kHTML; + namespace ui { namespace { @@ -828,6 +835,7 @@ WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_ACC_DEFAULT_ACTION); AXPlatformNodeWin* target; COM_OBJECT_VALIDATE_VAR_ID_1_ARG_AND_GET_TARGET(var_id, def_action, target); + AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes); int action; if (!target->GetIntAttribute(AX_ATTR_DEFAULT_ACTION_VERB, &action)) { @@ -1169,6 +1177,8 @@ STDMETHODIMP AXPlatformNodeWin::get_states(AccessibleStates* states) { WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_STATES); COM_OBJECT_VALIDATE_1_ARG(states); + AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes); + *states = ComputeIA2State(); return S_OK; } @@ -1262,6 +1272,8 @@ STDMETHODIMP AXPlatformNodeWin::get_nRelations(LONG* n_relations) { COM_OBJECT_VALIDATE_1_ARG(n_relations); + WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_N_RELATIONS); + AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes); *n_relations = static_cast<LONG>(relations_.size()); return S_OK; } @@ -1269,6 +1281,8 @@ STDMETHODIMP AXPlatformNodeWin::get_relation(LONG relation_index, IAccessibleRelation** relation) { COM_OBJECT_VALIDATE_1_ARG(relation); + WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_RELATION); + AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes); if (relation_index < 0 || relation_index >= static_cast<long>(relations_.size())) { return E_INVALIDARG; @@ -1283,6 +1297,9 @@ IAccessibleRelation** relations, LONG* n_relations) { COM_OBJECT_VALIDATE_2_ARGS(relations, n_relations); + WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_RELATIONS); + AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes); + long count = static_cast<long>(relations_.size()); *n_relations = count; if (count == 0) @@ -1368,6 +1385,8 @@ long column, IUnknown** accessible) { WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_ACCESSIBLE_AT); + AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes); + if (!accessible) return E_INVALIDARG; @@ -1387,6 +1406,8 @@ STDMETHODIMP AXPlatformNodeWin::get_caption(IUnknown** accessible) { WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_CAPTION); + AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes); + if (!accessible) return E_INVALIDARG; @@ -1399,6 +1420,8 @@ long column, long* cell_index) { WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_CHILD_INDEX); + AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes); + if (!cell_index) return E_INVALIDARG; @@ -1416,6 +1439,8 @@ STDMETHODIMP AXPlatformNodeWin::get_columnDescription(long column, BSTR* description) { WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_COLUMN_DESCRIPTION); + AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes); + if (!description) return E_INVALIDARG; @@ -1454,6 +1479,8 @@ long column, long* n_columns_spanned) { WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_COLUMN_EXTENT_AT); + AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes); + if (!n_columns_spanned) return E_INVALIDARG; @@ -1470,6 +1497,8 @@ IAccessibleTable** accessible_table, long* starting_row_index) { WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_COLUMN_HEADER); + AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes); + // TODO(dmazzoni): implement return E_NOTIMPL; } @@ -1477,6 +1506,8 @@ STDMETHODIMP AXPlatformNodeWin::get_columnIndex(long cell_index, long* column_index) { WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_COLUMN_INDEX); + AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes); + if (!column_index) return E_INVALIDARG; @@ -1489,6 +1520,8 @@ STDMETHODIMP AXPlatformNodeWin::get_nColumns(long* column_count) { WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_N_COLUMNS); + AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes); + if (!column_count) return E_INVALIDARG; @@ -1498,6 +1531,8 @@ STDMETHODIMP AXPlatformNodeWin::get_nRows(long* row_count) { WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_N_ROWS); + AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes); + if (!row_count) return E_INVALIDARG; @@ -1507,6 +1542,8 @@ STDMETHODIMP AXPlatformNodeWin::get_nSelectedChildren(long* cell_count) { WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_N_SELECTED_CHILDREN); + AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes); + if (!cell_count) return E_INVALIDARG; *cell_count = 0; @@ -1530,6 +1567,8 @@ STDMETHODIMP AXPlatformNodeWin::get_nSelectedColumns(long* column_count) { WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_N_SELECTED_COLUMNS); + AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes); + if (!column_count) return E_INVALIDARG; *column_count = 0; @@ -1558,6 +1597,8 @@ STDMETHODIMP AXPlatformNodeWin::get_nSelectedRows(long* row_count) { WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_N_SELECTED_ROWS); + AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes); + if (!row_count) return E_INVALIDARG; *row_count = 0; @@ -1587,6 +1628,8 @@ STDMETHODIMP AXPlatformNodeWin::get_rowDescription(long row, BSTR* description) { WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_ROW_DESCRIPTION); + AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes); + if (!description) return E_INVALIDARG; @@ -1623,6 +1666,8 @@ long column, long* n_rows_spanned) { WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_ROW_EXTENT_AT); + AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes); + if (!n_rows_spanned) return E_INVALIDARG; @@ -1638,11 +1683,16 @@ IAccessibleTable** accessible_table, long* starting_column_index) { WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_ROW_HEADER); + AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes); + // TODO(dmazzoni): implement return E_NOTIMPL; } STDMETHODIMP AXPlatformNodeWin::get_rowIndex(long cell_index, long* row_index) { + // TODO(dougt) WIN_ACCESSIBILITY_API_HISTOGRAM? + AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes); + if (!row_index) return E_INVALIDARG; @@ -1657,6 +1707,9 @@ STDMETHODIMP AXPlatformNodeWin::get_selectedChildren(long max_children, long** children, long* n_children) { + // TODO(dougt) WIN_ACCESSIBILITY_API_HISTOGRAM? + AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes); + if (!children || !n_children || max_children <= 0) return E_INVALIDARG; @@ -1682,6 +1735,9 @@ STDMETHODIMP AXPlatformNodeWin::get_selectedColumns(long max_columns, long** columns, long* n_columns) { + // TODO(dougt) WIN_ACCESSIBILITY_API_HISTOGRAM? + AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes); + if (!columns || !n_columns || max_columns <= 0) return E_INVALIDARG; @@ -1708,6 +1764,8 @@ STDMETHODIMP AXPlatformNodeWin::get_selectedRows(long max_rows, long** rows, long* n_rows) { + // TODO(dougt) WIN_ACCESSIBILITY_API_HISTOGRAM? + AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes); if (!rows || !n_rows || max_rows <= 0) return E_INVALIDARG; @@ -1732,6 +1790,9 @@ } STDMETHODIMP AXPlatformNodeWin::get_summary(IUnknown** accessible) { + // TODO(dougt) WIN_ACCESSIBILITY_API_HISTOGRAM? + AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes); + if (!accessible) return E_INVALIDARG; @@ -1742,6 +1803,8 @@ STDMETHODIMP AXPlatformNodeWin::get_isColumnSelected(long column, boolean* is_selected) { + // TODO(dougt) WIN_ACCESSIBILITY_API_HISTOGRAM? + AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes); if (!is_selected) return E_INVALIDARG; *is_selected = false; @@ -1763,6 +1826,8 @@ STDMETHODIMP AXPlatformNodeWin::get_isRowSelected(long row, boolean* is_selected) { + // TODO(dougt) WIN_ACCESSIBILITY_API_HISTOGRAM? + AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes); if (!is_selected) return E_INVALIDARG; *is_selected = false; @@ -1785,6 +1850,8 @@ STDMETHODIMP AXPlatformNodeWin::get_isSelected(long row, long column, boolean* is_selected) { + // TODO(dougt) WIN_ACCESSIBILITY_API_HISTOGRAM? + AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes); if (!is_selected) return E_INVALIDARG; *is_selected = false; @@ -1809,6 +1876,9 @@ long* row_extents, long* column_extents, boolean* is_selected) { + // TODO(dougt) WIN_ACCESSIBILITY_API_HISTOGRAM? + AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes); + if (!row || !column || !row_extents || !column_extents || !is_selected) return E_INVALIDARG; @@ -1826,23 +1896,36 @@ } STDMETHODIMP AXPlatformNodeWin::selectRow(long row) { + // TODO(dougt) WIN_ACCESSIBILITY_API_HISTOGRAM? + AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes); + return E_NOTIMPL; } STDMETHODIMP AXPlatformNodeWin::selectColumn(long column) { + // TODO(dougt) WIN_ACCESSIBILITY_API_HISTOGRAM? + AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes); + return E_NOTIMPL; } STDMETHODIMP AXPlatformNodeWin::unselectRow(long row) { + // TODO(dougt) WIN_ACCESSIBILITY_API_HISTOGRAM? + AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes); + return E_NOTIMPL; } STDMETHODIMP AXPlatformNodeWin::unselectColumn(long column) { + // TODO(dougt) WIN_ACCESSIBILITY_API_HISTOGRAM? + AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes); + return E_NOTIMPL; } STDMETHODIMP AXPlatformNodeWin::get_modelChange(IA2TableModelChange* model_change) { + // TODO(dougt) WIN_ACCESSIBILITY_API_HISTOGRAM? return E_NOTIMPL; } @@ -1853,6 +1936,8 @@ STDMETHODIMP AXPlatformNodeWin::get_cellAt(long row, long column, IUnknown** cell) { + // TODO(dougt) WIN_ACCESSIBILITY_API_HISTOGRAM? + AXPlatformNode::NotifyAddAXModeFlags(ui::AXMode::kScreenReader); if (!cell) return E_INVALIDARG; @@ -1870,11 +1955,16 @@ } STDMETHODIMP AXPlatformNodeWin::get_nSelectedCells(long* cell_count) { + // TODO(dougt) WIN_ACCESSIBILITY_API_HISTOGRAM? + // Note that this method does not need to set any ax mode since it + // calls into get_nSelectedChildren() which does. return get_nSelectedChildren(cell_count); } STDMETHODIMP AXPlatformNodeWin::get_selectedCells(IUnknown*** cells, long* n_selected_cells) { + // TODO(dougt) WIN_ACCESSIBILITY_API_HISTOGRAM? + AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes); if (!cells || !n_selected_cells) return E_INVALIDARG; @@ -1885,6 +1975,8 @@ STDMETHODIMP AXPlatformNodeWin::get_selectedColumns(long** columns, long* n_columns) { + // TODO(dougt) WIN_ACCESSIBILITY_API_HISTOGRAM? + AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes); if (!columns || !n_columns) return E_INVALIDARG; @@ -1894,6 +1986,8 @@ } STDMETHODIMP AXPlatformNodeWin::get_selectedRows(long** rows, long* n_rows) { + // TODO(dougt) WIN_ACCESSIBILITY_API_HISTOGRAM? + AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes); if (!rows || !n_rows) return E_INVALIDARG; @@ -1907,6 +2001,8 @@ // STDMETHODIMP AXPlatformNodeWin::get_columnExtent(long* n_columns_spanned) { + // TODO(dougt) WIN_ACCESSIBILITY_API_HISTOGRAM? + AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes); if (!n_columns_spanned) return E_INVALIDARG; @@ -1917,6 +2013,8 @@ STDMETHODIMP AXPlatformNodeWin::get_columnHeaderCells( IUnknown*** cell_accessibles, long* n_column_header_cells) { + // TODO(dougt) WIN_ACCESSIBILITY_API_HISTOGRAM? + AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes); if (!cell_accessibles || !n_column_header_cells) return E_INVALIDARG; @@ -1956,6 +2054,9 @@ } STDMETHODIMP AXPlatformNodeWin::get_columnIndex(long* column_index) { + // TODO(dougt) WIN_ACCESSIBILITY_API_HISTOGRAM? + AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes); + if (!column_index) return E_INVALIDARG; @@ -1964,6 +2065,9 @@ } STDMETHODIMP AXPlatformNodeWin::get_rowExtent(long* n_rows_spanned) { + // TODO(dougt) WIN_ACCESSIBILITY_API_HISTOGRAM? + AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes); + if (!n_rows_spanned) return E_INVALIDARG; @@ -1973,6 +2077,9 @@ STDMETHODIMP AXPlatformNodeWin::get_rowHeaderCells(IUnknown*** cell_accessibles, long* n_row_header_cells) { + // TODO(dougt) WIN_ACCESSIBILITY_API_HISTOGRAM? + AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes); + if (!cell_accessibles || !n_row_header_cells) return E_INVALIDARG; @@ -2012,6 +2119,9 @@ } STDMETHODIMP AXPlatformNodeWin::get_rowIndex(long* row_index) { + // TODO(dougt) WIN_ACCESSIBILITY_API_HISTOGRAM? + AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes); + if (!row_index) return E_INVALIDARG; @@ -2020,6 +2130,9 @@ } STDMETHODIMP AXPlatformNodeWin::get_isSelected(boolean* is_selected) { + // TODO(dougt) WIN_ACCESSIBILITY_API_HISTOGRAM? + AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes); + if (!is_selected) return E_INVALIDARG; @@ -2032,6 +2145,9 @@ long* row_extents, long* column_extents, boolean* is_selected) { + // TODO(dougt) WIN_ACCESSIBILITY_API_HISTOGRAM? + AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes); + if (!row_index || !column_index || !row_extents || !column_extents || !is_selected) { return E_INVALIDARG; @@ -2047,6 +2163,9 @@ } STDMETHODIMP AXPlatformNodeWin::get_table(IUnknown** table) { + // TODO(dougt) WIN_ACCESSIBILITY_API_HISTOGRAM? + AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes); + if (!table) return E_INVALIDARG;
diff --git a/ui/accessibility/platform/ax_platform_node_win.h b/ui/accessibility/platform/ax_platform_node_win.h index d7fc09b..4bf7e04 100644 --- a/ui/accessibility/platform/ax_platform_node_win.h +++ b/ui/accessibility/platform/ax_platform_node_win.h
@@ -248,17 +248,16 @@ }; class AX_EXPORT __declspec(uuid("26f5641a-246d-457b-a96d-07f3fae6acf2")) - AXPlatformNodeWin - : public NON_EXPORTED_BASE(CComObjectRootEx<CComMultiThreadModel>), - public IDispatchImpl<IAccessible2_2, - &IID_IAccessible2, - &LIBID_IAccessible2Lib>, - public IAccessibleText, - public IAccessibleTable, - public IAccessibleTable2, - public IAccessibleTableCell, - public IServiceProvider, - public AXPlatformNodeBase { + AXPlatformNodeWin : public CComObjectRootEx<CComMultiThreadModel>, + public IDispatchImpl<IAccessible2_2, + &IID_IAccessible2, + &LIBID_IAccessible2Lib>, + public IAccessibleText, + public IAccessibleTable, + public IAccessibleTable2, + public IAccessibleTableCell, + public IServiceProvider, + public AXPlatformNodeBase { public: BEGIN_COM_MAP(AXPlatformNodeWin) COM_INTERFACE_ENTRY2(IDispatch, IAccessible2_2)
diff --git a/ui/app_list/views/app_list_view.cc b/ui/app_list/views/app_list_view.cc index 565836ed..6ccfbe0 100644 --- a/ui/app_list/views/app_list_view.cc +++ b/ui/app_list/views/app_list_view.cc
@@ -177,7 +177,8 @@ : delegate_(delegate), is_fullscreen_app_list_enabled_(features::IsFullscreenAppListEnabled()), display_observer_(this), - animation_observer_(new HideViewAnimationObserver()) { + animation_observer_(new HideViewAnimationObserver()), + app_list_animation_duration_ms_(kAppListAnimationDurationMs) { CHECK(delegate); delegate_->GetSpeechUI()->AddObserver(this); @@ -988,7 +989,7 @@ std::unique_ptr<ui::LayerAnimationElement> bounds_animation_element = ui::LayerAnimationElement::CreateBoundsElement( target_bounds, - base::TimeDelta::FromMilliseconds(kAppListAnimationDurationMs)); + base::TimeDelta::FromMilliseconds(app_list_animation_duration_ms_)); bounds_animation_element->set_tween_type(gfx::Tween::EASE_OUT);
diff --git a/ui/app_list/views/app_list_view.h b/ui/app_list/views/app_list_view.h index d36aad6..e5161ba 100644 --- a/ui/app_list/views/app_list_view.h +++ b/ui/app_list/views/app_list_view.h
@@ -188,6 +188,11 @@ int work_area_bottom() const { return work_area_bottom_; } + void set_app_list_animation_duration_ms_for_testing( + int app_list_animation_duration_ms) { + app_list_animation_duration_ms_ = app_list_animation_duration_ms; + } + private: // A widget observer that is responsible for keeping the AppListView state up // to date on closing. @@ -321,6 +326,9 @@ // For UMA and testing. If non-null, triggered when the app list is painted. base::Closure next_paint_callback_; + // Animation duration in milliseconds. + int app_list_animation_duration_ms_; + DISALLOW_COPY_AND_ASSIGN(AppListView); };
diff --git a/ui/app_list/views/apps_grid_view.cc b/ui/app_list/views/apps_grid_view.cc index facb7c3..90cf5e16 100644 --- a/ui/app_list/views/apps_grid_view.cc +++ b/ui/app_list/views/apps_grid_view.cc
@@ -37,6 +37,8 @@ #include "ui/base/l10n/l10n_util.h" #include "ui/compositor/paint_recorder.h" #include "ui/compositor/scoped_layer_animation_settings.h" +#include "ui/display/display.h" +#include "ui/display/screen.h" #include "ui/events/event.h" #include "ui/gfx/animation/animation.h" #include "ui/gfx/geometry/vector2d.h" @@ -81,6 +83,9 @@ // Delay in milliseconds to do the page flip. constexpr int kPageFlipDelayInMs = 1000; +// Delay in milliseconds to do the page flip in fullscreen app list. +constexpr int kPageFlipDelayInMsFullscreen = 500; + // The drag and drop proxy should get scaled by this factor. constexpr float kDragAndDropProxyScale = 1.2f; @@ -294,9 +299,11 @@ AppsGridView::AppsGridView(ContentsView* contents_view) : contents_view_(contents_view), - page_flip_delay_in_ms_(kPageFlipDelayInMs), bounds_animator_(this), - is_fullscreen_app_list_enabled_(features::IsFullscreenAppListEnabled()) { + is_fullscreen_app_list_enabled_(features::IsFullscreenAppListEnabled()), + page_flip_delay_in_ms_(is_fullscreen_app_list_enabled_ + ? kPageFlipDelayInMsFullscreen + : kPageFlipDelayInMs) { DCHECK(contents_view_); SetPaintToLayer(); // Clip any icons that are outside the grid view's bounds. These icons would @@ -2132,6 +2139,14 @@ } bool AppsGridView::IsPointWithinDragBuffer(const gfx::Point& point) const { + if (is_fullscreen_app_list_enabled_) { + gfx::Point point_in_screen = point; + ConvertPointToScreen(this, &point_in_screen); + const display::Display display = + display::Screen::GetScreen()->GetDisplayNearestView( + GetWidget()->GetNativeView()); + return display.work_area().Contains(point_in_screen); + } gfx::Rect rect(GetLocalBounds()); rect.Inset(-kDragBufferPx, -kDragBufferPx, -kDragBufferPx, -kDragBufferPx); return rect.Contains(point);
diff --git a/ui/app_list/views/apps_grid_view.h b/ui/app_list/views/apps_grid_view.h index 68c04cad..b7fd7c1 100644 --- a/ui/app_list/views/apps_grid_view.h +++ b/ui/app_list/views/apps_grid_view.h
@@ -225,6 +225,10 @@ return suggestions_container_; } + void set_page_flip_delay_in_ms_for_testing(int page_flip_delay_in_ms) { + page_flip_delay_in_ms_ = page_flip_delay_in_ms; + } + private: class FadeoutLayerDelegate; friend class test::AppsGridViewTestApi; @@ -572,10 +576,6 @@ // Target page to switch to when |page_flip_timer_| fires. int page_flip_target_ = -1; - // Delay in milliseconds of when |page_flip_timer_| should fire after user - // drags an item near the edges. - int page_flip_delay_in_ms_; - views::BoundsAnimator bounds_animator_; // The most recent activated folder item view. @@ -593,6 +593,10 @@ // True if the fullscreen app list feature is enabled. const bool is_fullscreen_app_list_enabled_; + // Delay in milliseconds of when |page_flip_timer_| should fire after user + // drags an item near the edges. + int page_flip_delay_in_ms_; + // True if it is the end gesture from shelf dragging. bool is_end_gesture_ = false;
diff --git a/ui/app_list/views/apps_grid_view_unittest.cc b/ui/app_list/views/apps_grid_view_unittest.cc index f5e6f57..af7958b4 100644 --- a/ui/app_list/views/apps_grid_view_unittest.cc +++ b/ui/app_list/views/apps_grid_view_unittest.cc
@@ -121,6 +121,7 @@ gfx::NativeView parent = GetContext(); delegate_.reset(new AppListTestViewDelegate); app_list_view_ = new AppListView(delegate_.get()); + app_list_view_->set_app_list_animation_duration_ms_for_testing(0); app_list_view_->Initialize(parent, 0, false, false); ContentsView* contents_view = @@ -142,9 +143,14 @@ // Needed to update suggestions from |model_|. apps_grid_view_->ResetForShowApps(); - // Set app list view to show all apps page to test AppsGridView. - contents_view->SetActiveState(AppListModel::STATE_APPS); - contents_view->Layout(); + if (test_with_fullscreen_) { + app_list_view_->SetState(AppListView::FULLSCREEN_ALL_APPS); + app_list_view_->Layout(); + } else { + // Set app list view to show all apps page to test AppsGridView. + contents_view->SetActiveState(AppListModel::STATE_APPS); + contents_view->Layout(); + } test_api_.reset(new AppsGridViewTestApi(apps_grid_view_)); } @@ -635,7 +641,7 @@ // TODO(warx): enable this test for |test_with_fullscreen_|, crbug.com/742581. TEST_F(AppsGridViewTest, MouseDragFlipPage) { - test_api_->SetPageFlipDelay(10); + apps_grid_view_->set_page_flip_delay_in_ms_for_testing(10); GetPaginationModel()->SetTransitionDurations(10, 10); PageFlipWaiter page_flip_waiter(GetPaginationModel());
diff --git a/ui/app_list/views/search_result_tile_item_list_view.cc b/ui/app_list/views/search_result_tile_item_list_view.cc index ae8d31b..21f2d92a 100644 --- a/ui/app_list/views/search_result_tile_item_list_view.cc +++ b/ui/app_list/views/search_result_tile_item_list_view.cc
@@ -48,27 +48,27 @@ is_play_store_app_search_enabled_( features::IsPlayStoreAppSearchEnabled()), is_fullscreen_app_list_enabled_(features::IsFullscreenAppListEnabled()) { - if (is_play_store_app_search_enabled_) { + if (is_fullscreen_app_list_enabled_) { SetLayoutManager(new views::BoxLayout( views::BoxLayout::kHorizontal, gfx::Insets(kItemListVerticalSpacing, kItemListHorizontalSpacing), kBetweenItemSpacing)); for (size_t i = 0; i < kMaxNumSearchResultTiles; ++i) { - views::Separator* separator = new views::Separator; - separator->SetVisible(false); - separator->SetBorder(views::CreateEmptyBorder( - 0, kSeparatorLeftRightPadding, kSearchTileHeight - kSeparatorHeight, - kSeparatorLeftRightPadding)); - separator->SetColor(kSeparatorColor); + if (is_play_store_app_search_enabled_) { + views::Separator* separator = new views::Separator; + separator->SetVisible(false); + separator->SetBorder(views::CreateEmptyBorder( + 0, kSeparatorLeftRightPadding, kSearchTileHeight - kSeparatorHeight, + kSeparatorLeftRightPadding)); + separator->SetColor(kSeparatorColor); - separator_views_.push_back(separator); - AddChildView(separator); + separator_views_.push_back(separator); + AddChildView(separator); + } SearchResultTileItemView* tile_item = new SearchResultTileItemView(this, view_delegate); - tile_item->SetParentBackgroundColor(is_fullscreen_app_list_enabled_ - ? kCardBackgroundColorFullscreen - : kCardBackgroundColor); + tile_item->SetParentBackgroundColor(kCardBackgroundColorFullscreen); tile_views_.push_back(tile_item); AddChildView(tile_item); } @@ -79,9 +79,7 @@ for (size_t i = 0; i < kNumSearchResultTiles; ++i) { SearchResultTileItemView* tile_item = new SearchResultTileItemView(this, view_delegate); - tile_item->SetParentBackgroundColor(is_fullscreen_app_list_enabled_ - ? kCardBackgroundColorFullscreen - : kCardBackgroundColor); + tile_item->SetParentBackgroundColor(kCardBackgroundColor); tile_item->SetBorder( views::CreateEmptyBorder(kTopBottomPadding, 0, kTopBottomPadding, 0)); tile_views_.push_back(tile_item); @@ -118,15 +116,16 @@ std::vector<SearchResult*> display_results = AppListModel::FilterSearchResultsByDisplayType( results(), SearchResult::DISPLAY_TILE, - is_play_store_app_search_enabled_ ? kMaxNumSearchResultTiles - : kNumSearchResultTiles); + is_fullscreen_app_list_enabled_ ? kMaxNumSearchResultTiles + : kNumSearchResultTiles); - if (is_play_store_app_search_enabled_) { + if (is_fullscreen_app_list_enabled_) { SearchResult::ResultType previous_type = SearchResult::RESULT_UNKNOWN; for (size_t i = 0; i < kMaxNumSearchResultTiles; ++i) { if (i >= display_results.size()) { - separator_views_[i]->SetVisible(false); + if (is_play_store_app_search_enabled_) + separator_views_[i]->SetVisible(false); tile_views_[i]->SetSearchResult(nullptr); continue; } @@ -134,15 +133,17 @@ SearchResult* item = display_results[i]; tile_views_[i]->SetSearchResult(item); - if (i > 0 && item->result_type() != previous_type) { - // Add a separator to separate search results of different types. - // The strategy here is to only add a separator only if current search - // result type is different from the previous one. The strategy is - // based on the assumption that the search results are already - // separated in groups based on their result types. - separator_views_[i]->SetVisible(true); - } else { - separator_views_[i]->SetVisible(false); + if (is_play_store_app_search_enabled_) { + if (i > 0 && item->result_type() != previous_type) { + // Add a separator to separate search results of different types. + // The strategy here is to only add a separator only if current search + // result type is different from the previous one. The strategy is + // based on the assumption that the search results are already + // separated in groups based on their result types. + separator_views_[i]->SetVisible(true); + } else { + separator_views_[i]->SetVisible(false); + } } previous_type = item->result_type();
diff --git a/ui/app_list/views/search_result_tile_item_list_view_unittest.cc b/ui/app_list/views/search_result_tile_item_list_view_unittest.cc index e70252d9..f3318476 100644 --- a/ui/app_list/views/search_result_tile_item_list_view_unittest.cc +++ b/ui/app_list/views/search_result_tile_item_list_view_unittest.cc
@@ -25,8 +25,6 @@ namespace app_list { namespace { -constexpr int kNumSearchResultTiles = 8; -// Constants when the Play Store app search feature is enabled. constexpr int kMaxNumSearchResultTiles = 6; constexpr int kInstalledApps = 4; constexpr int kPlayStoreApps = 2; @@ -36,20 +34,24 @@ : public views::ViewsTestBase, public ::testing::WithParamInterface<bool> { public: - SearchResultTileItemListViewTest() {} - ~SearchResultTileItemListViewTest() override {} + SearchResultTileItemListViewTest() = default; + ~SearchResultTileItemListViewTest() override = default; protected: void CreateSearchResultTileItemListView() { - // Switches on/off the Play Store app search feature. + // Enable fullscreen app list for parameterized Play Store app search + // feature. if (IsPlayStoreAppSearchEnabled()) { - scoped_feature_list_.InitAndEnableFeature( - app_list::features::kEnablePlayStoreAppSearch); + scoped_feature_list_.InitWithFeatures( + {features::kEnableFullscreenAppList, + features::kEnablePlayStoreAppSearch}, + {}); } else { - scoped_feature_list_.InitAndDisableFeature( - app_list::features::kEnablePlayStoreAppSearch); + scoped_feature_list_.InitWithFeatures( + {features::kEnableFullscreenAppList}, + {features::kEnablePlayStoreAppSearch}); } - EXPECT_EQ(IsPlayStoreAppSearchEnabled(), + ASSERT_EQ(IsPlayStoreAppSearchEnabled(), features::IsPlayStoreAppSearchEnabled()); // Sets up the views. @@ -142,7 +144,7 @@ // we added a separator for result type grouping. const int expected_child_count = IsPlayStoreAppSearchEnabled() ? kMaxNumSearchResultTiles * 2 - : kNumSearchResultTiles; + : kMaxNumSearchResultTiles; EXPECT_EQ(expected_child_count, view()->child_count()); // Tests item indexing by pressing TAB.
diff --git a/ui/app_list/views/search_result_view.h b/ui/app_list/views/search_result_view.h index c1b5358c..245708d 100644 --- a/ui/app_list/views/search_result_view.h +++ b/ui/app_list/views/search_result_view.h
@@ -44,7 +44,7 @@ public views::ButtonListener, public views::ContextMenuController, public SearchResultObserver, - NON_EXPORTED_BASE(public SearchResultActionsViewDelegate) { + public SearchResultActionsViewDelegate { public: // Internal class name. static const char kViewClassName[];
diff --git a/ui/app_list/views/test/apps_grid_view_test_api.cc b/ui/app_list/views/test/apps_grid_view_test_api.cc index 06d79c4..2a945e2d7 100644 --- a/ui/app_list/views/test/apps_grid_view_test_api.cc +++ b/ui/app_list/views/test/apps_grid_view_test_api.cc
@@ -40,10 +40,6 @@ return view_->GetExpectedTileBounds(row, col); } -void AppsGridViewTestApi::SetPageFlipDelay(int page_flip_delay_in_ms) { - view_->page_flip_delay_in_ms_ = page_flip_delay_in_ms; -} - void AppsGridViewTestApi::PressItemAt(int index) { GetViewAtModelIndex(index)->OnKeyPressed( ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_RETURN, ui::EF_NONE));
diff --git a/ui/app_list/views/test/apps_grid_view_test_api.h b/ui/app_list/views/test/apps_grid_view_test_api.h index 65571fe..a778f93 100644 --- a/ui/app_list/views/test/apps_grid_view_test_api.h +++ b/ui/app_list/views/test/apps_grid_view_test_api.h
@@ -32,8 +32,6 @@ gfx::Rect GetItemTileRectAt(int row, int col) const; - void SetPageFlipDelay(int page_flip_delay_in_ms); - void PressItemAt(int index); bool HasPendingPageFlip() const;
diff --git a/ui/arc/BUILD.gn b/ui/arc/BUILD.gn index 2028c689..6c5deab 100644 --- a/ui/arc/BUILD.gn +++ b/ui/arc/BUILD.gn
@@ -62,12 +62,14 @@ deps = [ ":arc", + "//ash:test_support_without_content", "//base", "//base/test:test_support", "//components/arc:arc_test_support", "//components/exo", "//components/exo:test_support", "//mojo/edk/system", + "//testing/gmock", "//testing/gtest", "//ui/aura:test_support", "//ui/base:test_support",
diff --git a/ui/arc/notification/arc_notification_content_view_unittest.cc b/ui/arc/notification/arc_notification_content_view_unittest.cc index bd25a1b..593bec8d 100644 --- a/ui/arc/notification/arc_notification_content_view_unittest.cc +++ b/ui/arc/notification/arc_notification_content_view_unittest.cc
@@ -8,12 +8,17 @@ #include <string> #include <utility> +#include "ash/shell.h" +#include "ash/test/ash_test_base.h" #include "base/strings/utf_string_conversions.h" #include "components/exo/buffer.h" +#include "components/exo/keyboard.h" +#include "components/exo/keyboard_delegate.h" #include "components/exo/notification_surface.h" #include "components/exo/surface.h" #include "components/exo/test/exo_test_helper.h" #include "components/exo/wm_helper_ash.h" +#include "testing/gmock/include/gmock/gmock.h" #include "ui/arc/notification/arc_notification_content_view.h" #include "ui/arc/notification/arc_notification_delegate.h" #include "ui/arc/notification/arc_notification_item.h" @@ -22,6 +27,8 @@ #include "ui/arc/notification/arc_notification_view.h" #include "ui/aura/test/test_window_delegate.h" #include "ui/aura/window.h" +#include "ui/events/keycodes/dom/dom_code.h" +#include "ui/events/test/event_generator.h" #include "ui/message_center/notification.h" #include "ui/message_center/views/message_center_controller.h" #include "ui/message_center/views/message_view_factory.h" @@ -34,6 +41,21 @@ namespace { constexpr char kNotificationIdPrefix[] = "ARC_NOTIFICATION_"; +constexpr gfx::Rect kNotificationSurfaceBounds(100, 100, 300, 300); + +class MockKeyboardDelegate : public exo::KeyboardDelegate { + public: + MockKeyboardDelegate() = default; + + // Overridden from KeyboardDelegate: + MOCK_METHOD1(OnKeyboardDestroying, void(exo::Keyboard*)); + MOCK_CONST_METHOD1(CanAcceptKeyboardEventsForSurface, bool(exo::Surface*)); + MOCK_METHOD2(OnKeyboardEnter, + void(exo::Surface*, const std::vector<ui::DomCode>&)); + MOCK_METHOD1(OnKeyboardLeave, void(exo::Surface*)); + MOCK_METHOD3(OnKeyboardKey, uint32_t(base::TimeTicks, ui::DomCode, bool)); + MOCK_METHOD1(OnKeyboardModifiers, void(int)); +}; class TestWMHelper : public exo::WMHelper { public: @@ -68,6 +90,11 @@ DISALLOW_COPY_AND_ASSIGN(TestWMHelper); }; +aura::Window* GetFocusedWindow() { + DCHECK(exo::WMHelper::HasInstance()); + return exo::WMHelper::GetInstance()->GetFocusedWindow(); +} + } // anonymous namespace class MockArcNotificationItem : public ArcNotificationItem { @@ -183,15 +210,17 @@ ~DummyEvent() override = default; }; -class ArcNotificationContentViewTest : public views::ViewsTestBase { +class ArcNotificationContentViewTest : public ash::AshTestBase { public: ArcNotificationContentViewTest() = default; ~ArcNotificationContentViewTest() override = default; void SetUp() override { - views::ViewsTestBase::SetUp(); + ash::AshTestBase::SetUp(); - exo::WMHelper::SetInstance(&wm_helper_); + wm_helper_ = base::MakeUnique<exo::WMHelperAsh>(); + exo::WMHelper::SetInstance(wm_helper_.get()); + DCHECK(exo::WMHelper::HasInstance()); surface_manager_ = base::MakeUnique<ArcNotificationSurfaceManagerImpl>(); } @@ -208,9 +237,11 @@ surface_manager_.reset(); + DCHECK(exo::WMHelper::HasInstance()); exo::WMHelper::SetInstance(nullptr); + wm_helper_.reset(); - views::ViewsTestBase::TearDown(); + ash::AshTestBase::TearDown(); } void PressCloseButton() { @@ -242,10 +273,10 @@ message_center::MessageViewFactory::Create(controller(), notification, true))); notification_view->set_owned_by_client(); - views::Widget::InitParams params( - CreateParams(views::Widget::InitParams::TYPE_POPUP)); + views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP); params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; + params.context = ash::Shell::GetPrimaryRootWindow(); auto wrapper_widget = base::MakeUnique<views::Widget>(); wrapper_widget->Init(params); wrapper_widget->SetContentsView(notification_view.get()); @@ -268,9 +299,9 @@ surface_manager(), surface_.get(), notification_key); exo::test::ExoTestHelper exo_test_helper; - const gfx::Rect bounds(100, 100, 300, 300); - surface_buffer_ = base::MakeUnique<exo::Buffer>( - exo_test_helper.CreateGpuMemoryBuffer(bounds.size())); + surface_buffer_ = + base::MakeUnique<exo::Buffer>(exo_test_helper.CreateGpuMemoryBuffer( + kNotificationSurfaceBounds.size())); surface_->Attach(surface_buffer_.get()); surface_->Commit(); @@ -295,16 +326,31 @@ } views::Widget* widget() { return notification_view_->GetWidget(); } exo::Surface* surface() { return surface_.get(); } + ArcNotificationView* notification_view() { return notification_view_.get(); } - ArcNotificationContentView* GetArcNotificationContentView() { + message_center::NotificationControlButtonsView* GetControlButtonsView() + const { + DCHECK(GetArcNotificationContentView()); + DCHECK(GetArcNotificationContentView()->control_buttons_view_); + return GetArcNotificationContentView()->control_buttons_view_; + } + views::Widget* GetControlButtonsWidget() const { + DCHECK(GetControlButtonsView()->GetWidget()); + return GetControlButtonsView()->GetWidget(); + } + + ArcNotificationContentView* GetArcNotificationContentView() const { views::View* view = notification_view_->contents_view_; EXPECT_EQ(ArcNotificationContentView::kViewClassName, view->GetClassName()); return static_cast<ArcNotificationContentView*>(view); } + void ActivateArcNotification() { + GetArcNotificationContentView()->Activate(); + } private: TestMessageCenterController controller_; - TestWMHelper wm_helper_; + std::unique_ptr<exo::WMHelper> wm_helper_; std::unique_ptr<ArcNotificationSurfaceManagerImpl> surface_manager_; std::unique_ptr<exo::Buffer> surface_buffer_; std::unique_ptr<exo::Surface> surface_; @@ -450,4 +496,211 @@ CloseNotificationView(); } +TEST_F(ArcNotificationContentViewTest, Activate) { + std::string key("notification id"); + auto notification_item = base::MakeUnique<MockArcNotificationItem>(key); + auto notification = CreateNotification(notification_item.get()); + + PrepareSurface(key); + CreateAndShowNotificationView(notification); + + EXPECT_FALSE(GetFocusedWindow()); + ActivateArcNotification(); + EXPECT_EQ(surface()->window(), GetFocusedWindow()); + + CloseNotificationView(); +} + +TEST_F(ArcNotificationContentViewTest, ActivateOnClick) { + std::string key("notification id"); + auto notification_item = base::MakeUnique<MockArcNotificationItem>(key); + auto notification = CreateNotification(notification_item.get()); + + PrepareSurface(key); + CreateAndShowNotificationView(notification); + + EXPECT_FALSE(GetFocusedWindow()); + ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow(), + kNotificationSurfaceBounds.CenterPoint()); + generator.PressLeftButton(); + EXPECT_EQ(surface()->window(), GetFocusedWindow()); + + CloseNotificationView(); +} + +TEST_F(ArcNotificationContentViewTest, AcceptInputTextWithActivate) { + std::string key("notification id"); + auto notification_item = base::MakeUnique<MockArcNotificationItem>(key); + auto notification = CreateNotification(notification_item.get()); + + PrepareSurface(key); + CreateAndShowNotificationView(notification); + + EXPECT_FALSE(GetFocusedWindow()); + ActivateArcNotification(); + EXPECT_EQ(surface()->window(), GetFocusedWindow()); + + MockKeyboardDelegate delegate; + EXPECT_CALL(delegate, CanAcceptKeyboardEventsForSurface(surface())) + .WillOnce(testing::Return(true)); + auto keyboard = base::MakeUnique<exo::Keyboard>(&delegate); + + ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow()); + EXPECT_CALL(delegate, OnKeyboardKey(testing::_, ui::DomCode::US_A, true)); + generator.PressKey(ui::VKEY_A, 0); + + keyboard.reset(); + + CloseNotificationView(); +} + +TEST_F(ArcNotificationContentViewTest, NotAcceptInputTextWithoutActivate) { + std::string key("notification id"); + auto notification_item = base::MakeUnique<MockArcNotificationItem>(key); + auto notification = CreateNotification(notification_item.get()); + + PrepareSurface(key); + CreateAndShowNotificationView(notification); + EXPECT_FALSE(GetFocusedWindow()); + + MockKeyboardDelegate delegate; + EXPECT_CALL(delegate, CanAcceptKeyboardEventsForSurface(surface())).Times(0); + auto keyboard = base::MakeUnique<exo::Keyboard>(&delegate); + + ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow()); + EXPECT_CALL(delegate, OnKeyboardKey(testing::_, testing::_, testing::_)) + .Times(0); + generator.PressKey(ui::VKEY_A, 0); + + keyboard.reset(); + + CloseNotificationView(); +} + +TEST_F(ArcNotificationContentViewTest, TraversalFocus) { + const bool reverse = false; + + std::string key("notification id"); + auto notification_item = base::MakeUnique<MockArcNotificationItem>(key); + PrepareSurface(key); + auto notification = CreateNotification(notification_item.get()); + CreateAndShowNotificationView(notification); + + views::FocusManager* focus_manager = notification_view()->GetFocusManager(); + + views::View* view = + focus_manager->GetNextFocusableView(nullptr, widget(), reverse, true); + EXPECT_EQ(GetArcNotificationContentView(), view); + + view = focus_manager->GetNextFocusableView(view, nullptr, reverse, true); + EXPECT_EQ(GetControlButtonsView()->settings_button(), view); + + view = focus_manager->GetNextFocusableView(view, nullptr, reverse, true); + EXPECT_EQ(GetControlButtonsView()->close_button(), view); + + view = focus_manager->GetNextFocusableView(view, nullptr, reverse, true); + EXPECT_EQ(nullptr, view); + + CloseNotificationView(); +} + +TEST_F(ArcNotificationContentViewTest, TraversalFocusReverse) { + const bool reverse = true; + + std::string key("notification id"); + auto notification_item = base::MakeUnique<MockArcNotificationItem>(key); + PrepareSurface(key); + auto notification = CreateNotification(notification_item.get()); + CreateAndShowNotificationView(notification); + + views::FocusManager* focus_manager = notification_view()->GetFocusManager(); + + views::View* view = + focus_manager->GetNextFocusableView(nullptr, widget(), reverse, true); + EXPECT_EQ(GetControlButtonsView()->close_button(), view); + + view = focus_manager->GetNextFocusableView(view, nullptr, reverse, true); + EXPECT_EQ(GetControlButtonsView()->settings_button(), view); + + view = focus_manager->GetNextFocusableView(view, nullptr, reverse, true); + EXPECT_EQ(GetArcNotificationContentView(), view); + + view = focus_manager->GetNextFocusableView(view, nullptr, reverse, true); + EXPECT_EQ(nullptr, view); + + CloseNotificationView(); +} + +TEST_F(ArcNotificationContentViewTest, TraversalFocusByTabKey) { + const std::string key("notification id"); + auto notification_item = base::MakeUnique<MockArcNotificationItem>(key); + PrepareSurface(key); + auto notification = CreateNotification(notification_item.get()); + CreateAndShowNotificationView(notification); + ActivateArcNotification(); + + views::FocusManager* focus_manager = notification_view()->GetFocusManager(); + ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow()); + + focus_manager->ClearFocus(); + EXPECT_FALSE(focus_manager->GetFocusedView()); + + generator.PressKey(ui::VKEY_TAB, 0); + EXPECT_TRUE(focus_manager->GetFocusedView()); + EXPECT_EQ(GetArcNotificationContentView(), focus_manager->GetFocusedView()); + + generator.PressKey(ui::VKEY_TAB, 0); + EXPECT_TRUE(focus_manager->GetFocusedView()); + EXPECT_EQ(GetControlButtonsView()->settings_button(), + focus_manager->GetFocusedView()); + + generator.PressKey(ui::VKEY_TAB, 0); + EXPECT_TRUE(focus_manager->GetFocusedView()); + EXPECT_EQ(GetControlButtonsView()->close_button(), + focus_manager->GetFocusedView()); + + generator.PressKey(ui::VKEY_TAB, 0); + EXPECT_TRUE(focus_manager->GetFocusedView()); + EXPECT_EQ(GetArcNotificationContentView(), focus_manager->GetFocusedView()); + + CloseNotificationView(); +} + +TEST_F(ArcNotificationContentViewTest, TraversalFocusReverseByShiftTab) { + std::string key("notification id"); + + auto notification_item = base::MakeUnique<MockArcNotificationItem>(key); + PrepareSurface(key); + auto notification = CreateNotification(notification_item.get()); + CreateAndShowNotificationView(notification); + ActivateArcNotification(); + + views::FocusManager* focus_manager = notification_view()->GetFocusManager(); + ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow()); + + focus_manager->ClearFocus(); + EXPECT_FALSE(focus_manager->GetFocusedView()); + + generator.PressKey(ui::VKEY_TAB, ui::EF_SHIFT_DOWN); + EXPECT_TRUE(focus_manager->GetFocusedView()); + EXPECT_EQ(GetControlButtonsView()->close_button(), + focus_manager->GetFocusedView()); + + generator.PressKey(ui::VKEY_TAB, ui::EF_SHIFT_DOWN); + EXPECT_TRUE(focus_manager->GetFocusedView()); + EXPECT_EQ(GetControlButtonsView()->settings_button(), + focus_manager->GetFocusedView()); + + generator.PressKey(ui::VKEY_TAB, ui::EF_SHIFT_DOWN); + EXPECT_TRUE(focus_manager->GetFocusedView()); + EXPECT_EQ(GetArcNotificationContentView(), focus_manager->GetFocusedView()); + + generator.PressKey(ui::VKEY_TAB, ui::EF_SHIFT_DOWN); + EXPECT_TRUE(focus_manager->GetFocusedView()); + EXPECT_EQ(GetControlButtonsView()->close_button(), + focus_manager->GetFocusedView()); + + CloseNotificationView(); +} + } // namespace arc
diff --git a/ui/arc/test/run_all_unittests.cc b/ui/arc/test/run_all_unittests.cc index db674b8..e8b27a5 100644 --- a/ui/arc/test/run_all_unittests.cc +++ b/ui/arc/test/run_all_unittests.cc
@@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "ash/test/ash_test_suite.h" #include "base/bind.h" #include "base/path_service.h" #include "base/test/launcher/unit_test_launcher.h" @@ -12,40 +13,11 @@ #include "ui/base/ui_base_paths.h" #include "ui/gl/test/gl_surface_test_support.h" -namespace { - -class UiArcTestSuite : public base::TestSuite { - public: - UiArcTestSuite(int argc, char** argv) : base::TestSuite(argc, argv) {} - - protected: - void Initialize() override { - base::TestSuite::Initialize(); - gl::GLSurfaceTestSupport::InitializeOneOff(); - - // To use resource bundles - ui::RegisterPathProvider(); - base::FilePath ui_test_pak_path; - ASSERT_TRUE(PathService::Get(ui::UI_TEST_PAK, &ui_test_pak_path)); - ui::ResourceBundle::InitSharedInstanceWithPakPath(ui_test_pak_path); - } - - void Shutdown() override { - ui::ResourceBundle::CleanupSharedInstance(); - base::TestSuite::Shutdown(); - } - - private: - DISALLOW_COPY_AND_ASSIGN(UiArcTestSuite); -}; - -} // namespace - int main(int argc, char** argv) { - UiArcTestSuite test_suite(argc, argv); + ash::AshTestSuite test_suite(argc, argv); mojo::edk::Init(); return base::LaunchUnitTests( argc, argv, - base::Bind(&UiArcTestSuite::Run, base::Unretained(&test_suite))); + base::Bind(&ash::AshTestSuite::Run, base::Unretained(&test_suite))); }
diff --git a/ui/aura/local/layer_tree_frame_sink_local.cc b/ui/aura/local/layer_tree_frame_sink_local.cc index 6a036918..7c3db73 100644 --- a/ui/aura/local/layer_tree_frame_sink_local.cc +++ b/ui/aura/local/layer_tree_frame_sink_local.cc
@@ -57,6 +57,11 @@ cc::LayerTreeFrameSink::DetachFromClient(); } +void LayerTreeFrameSinkLocal::SetLocalSurfaceId( + const viz::LocalSurfaceId& local_surface_id) { + local_surface_id_ = local_surface_id; +} + void LayerTreeFrameSinkLocal::SubmitCompositorFrame(cc::CompositorFrame frame) { DCHECK(thread_checker_); DCHECK(thread_checker_->CalledOnValidThread());
diff --git a/ui/aura/local/layer_tree_frame_sink_local.h b/ui/aura/local/layer_tree_frame_sink_local.h index b30cf31..3f638cb 100644 --- a/ui/aura/local/layer_tree_frame_sink_local.h +++ b/ui/aura/local/layer_tree_frame_sink_local.h
@@ -42,6 +42,7 @@ // cc::LayerTreeFrameSink: bool BindToClient(cc::LayerTreeFrameSinkClient* client) override; void DetachFromClient() override; + void SetLocalSurfaceId(const viz::LocalSurfaceId& local_surface_id) override; void SubmitCompositorFrame(cc::CompositorFrame frame) override; void DidNotProduceFrame(const viz::BeginFrameAck& ack) override;
diff --git a/ui/aura/mus/user_activity_forwarder.h b/ui/aura/mus/user_activity_forwarder.h index d1890424..58d2852 100644 --- a/ui/aura/mus/user_activity_forwarder.h +++ b/ui/aura/mus/user_activity_forwarder.h
@@ -24,7 +24,7 @@ // downstream of ui::UserActivityDetector) instead observe UserActivityMonitor // directly: http://crbug.com/626899 class AURA_EXPORT UserActivityForwarder - : NON_EXPORTED_BASE(public ui::mojom::UserActivityObserver) { + : public ui::mojom::UserActivityObserver { public: UserActivityForwarder(ui::mojom::UserActivityMonitorPtr monitor, ui::UserActivityDetector* detector);
diff --git a/ui/aura/mus/window_tree_client.h b/ui/aura/mus/window_tree_client.h index 545d90083..c343903c 100644 --- a/ui/aura/mus/window_tree_client.h +++ b/ui/aura/mus/window_tree_client.h
@@ -89,8 +89,8 @@ // When WindowTreeClient is deleted all windows are deleted (and observers // notified). class AURA_EXPORT WindowTreeClient - : NON_EXPORTED_BASE(public ui::mojom::WindowTreeClient), - NON_EXPORTED_BASE(public ui::mojom::WindowManager), + : public ui::mojom::WindowTreeClient, + public ui::mojom::WindowManager, public CaptureSynchronizerDelegate, public FocusSynchronizerDelegate, public DragDropControllerHost,
diff --git a/ui/aura/test/mus/test_window_manager_client.cc b/ui/aura/test/mus/test_window_manager_client.cc index e42dcb3..c0b18cc 100644 --- a/ui/aura/test/mus/test_window_manager_client.cc +++ b/ui/aura/test/mus/test_window_manager_client.cc
@@ -4,6 +4,8 @@ #include "ui/aura/test/mus/test_window_manager_client.h" +#include <algorithm> + namespace aura { TestWindowManagerClient::TestWindowManagerClient() {} @@ -20,6 +22,13 @@ return count; } +size_t TestWindowManagerClient::IndexOfFirstChangeOfType( + WindowManagerClientChangeType type) const { + auto iter = std::find(changes_.begin(), changes_.end(), type); + return iter == changes_.end() ? static_cast<size_t>(-1) + : iter - changes_.begin(); +} + void TestWindowManagerClient::AddActivationParent(Id transport_window_id) { changes_.push_back(WindowManagerClientChangeType::ADD_ACTIVATION_PARENT); } @@ -75,7 +84,9 @@ void TestWindowManagerClient::WmRequestClose(Id transport_window_id) {} void TestWindowManagerClient::WmSetFrameDecorationValues( - ui::mojom::FrameDecorationValuesPtr values) {} + ui::mojom::FrameDecorationValuesPtr values) { + changes_.push_back(WindowManagerClientChangeType::SET_FRAME_DECORATIONS); +} void TestWindowManagerClient::WmSetNonClientCursor(uint32_t window_id, ui::CursorData cursor_data) {
diff --git a/ui/aura/test/mus/test_window_manager_client.h b/ui/aura/test/mus/test_window_manager_client.h index 8f11a4e..bb49143 100644 --- a/ui/aura/test/mus/test_window_manager_client.h +++ b/ui/aura/test/mus/test_window_manager_client.h
@@ -18,6 +18,7 @@ enum class WindowManagerClientChangeType { ADD_ACTIVATION_PARENT, SET_DISPLAY_CONFIGURATION, + SET_FRAME_DECORATIONS, }; // WindowManagerClient implementation for tests. @@ -28,6 +29,7 @@ size_t GetChangeCountForType(WindowManagerClientChangeType type); int64_t last_internal_display_id() const { return last_internal_display_id_; } + size_t IndexOfFirstChangeOfType(WindowManagerClientChangeType type) const; private: // ui::mojom::WindowManagerClient:
diff --git a/ui/aura/window_tree_host_platform.h b/ui/aura/window_tree_host_platform.h index 0734078..13ef6ca1 100644 --- a/ui/aura/window_tree_host_platform.h +++ b/ui/aura/window_tree_host_platform.h
@@ -21,9 +21,8 @@ // The unified WindowTreeHost implementation for platforms // that implement PlatformWindow. -class AURA_EXPORT WindowTreeHostPlatform - : public WindowTreeHost, - public NON_EXPORTED_BASE(ui::PlatformWindowDelegate) { +class AURA_EXPORT WindowTreeHostPlatform : public WindowTreeHost, + public ui::PlatformWindowDelegate { public: explicit WindowTreeHostPlatform(const gfx::Rect& bounds); ~WindowTreeHostPlatform() override;
diff --git a/ui/base/clipboard/clipboard.h b/ui/base/clipboard/clipboard.h index e176419c..94236ad 100644 --- a/ui/base/clipboard/clipboard.h +++ b/ui/base/clipboard/clipboard.h
@@ -42,7 +42,7 @@ class TestClipboard; class ScopedClipboardWriter; -class UI_BASE_EXPORT Clipboard : NON_EXPORTED_BASE(public base::ThreadChecker) { +class UI_BASE_EXPORT Clipboard : public base::ThreadChecker { public: // MIME type constants. static const char kMimeTypeText[];
diff --git a/ui/base/clipboard/clipboard_monitor.h b/ui/base/clipboard/clipboard_monitor.h index cd6ed1e..1330aaf 100644 --- a/ui/base/clipboard/clipboard_monitor.h +++ b/ui/base/clipboard/clipboard_monitor.h
@@ -17,8 +17,7 @@ // A singleton instance to monitor and notify ClipboardObservers for clipboard // changes. -class UI_BASE_EXPORT ClipboardMonitor - : NON_EXPORTED_BASE(public base::ThreadChecker) { +class UI_BASE_EXPORT ClipboardMonitor : public base::ThreadChecker { public: static ClipboardMonitor* GetInstance();
diff --git a/ui/base/ime/composition_text.cc b/ui/base/ime/composition_text.cc index 3ee2ae3..ab2136e9 100644 --- a/ui/base/ime/composition_text.cc +++ b/ui/base/ime/composition_text.cc
@@ -14,19 +14,4 @@ CompositionText::~CompositionText() { } -void CompositionText::Clear() { - text.clear(); - ime_text_spans.clear(); - selection = gfx::Range(); -} - -void CompositionText::CopyFrom(const CompositionText& obj) { - Clear(); - text = obj.text; - for (size_t i = 0; i < obj.ime_text_spans.size(); i++) { - ime_text_spans.push_back(obj.ime_text_spans[i]); - } - selection = obj.selection; -} - } // namespace ui
diff --git a/ui/base/ime/composition_text.h b/ui/base/ime/composition_text.h index f46dc3c..272535b 100644 --- a/ui/base/ime/composition_text.h +++ b/ui/base/ime/composition_text.h
@@ -35,10 +35,6 @@ return !(*this == rhs); } - void Clear(); - - void CopyFrom(const CompositionText& obj); - // Content of the composition text. base::string16 text;
diff --git a/ui/base/ime/composition_text_unittest.cc b/ui/base/ime/composition_text_unittest.cc index 3906fc1f..18852d6b 100644 --- a/ui/base/ime/composition_text_unittest.cc +++ b/ui/base/ime/composition_text_unittest.cc
@@ -31,8 +31,7 @@ text.selection.set_start(30); text.selection.set_end(40); - CompositionText text2; - text2.CopyFrom(text); + CompositionText text2 = text; EXPECT_EQ(text.text, text2.text); EXPECT_EQ(text.ime_text_spans.size(), text2.ime_text_spans.size());
diff --git a/ui/base/ime/composition_text_util_pango.cc b/ui/base/ime/composition_text_util_pango.cc index 46a0e24..8d89f58 100644 --- a/ui/base/ime/composition_text_util_pango.cc +++ b/ui/base/ime/composition_text_util_pango.cc
@@ -18,7 +18,7 @@ PangoAttrList* attrs, int cursor_position, CompositionText* composition) { - composition->Clear(); + *composition = CompositionText(); composition->text = base::UTF8ToUTF16(utf8_text); if (composition->text.empty())
diff --git a/ui/base/ime/input_method_auralinux.cc b/ui/base/ime/input_method_auralinux.cc index 03833c1..01893d57 100644 --- a/ui/base/ime/input_method_auralinux.cc +++ b/ui/base/ime/input_method_auralinux.cc
@@ -125,7 +125,7 @@ base::string16* result_text, bool is_handled) { composition_changed_ = composition_changed; - composition_.CopyFrom(*composition); + composition_ = *composition; result_text_ = *result_text; ignore_result(ProcessKeyEventDone(event, filtered, is_handled)); } @@ -201,7 +201,7 @@ // Makes sure the cached composition is cleared after committing any text or // cleared composition. if (client && !client->HasCompositionText()) - composition_.Clear(); + composition_ = CompositionText(); if (!filtered) { details = DispatchKeyEventPostIME(event); @@ -317,7 +317,7 @@ context_->Focus(); } - composition_.Clear(); + composition_ = CompositionText(); result_text_.clear(); is_sync_mode_ = false; composition_changed_ = false; @@ -349,7 +349,7 @@ return; if (!event.stopped_propagation() && !details.target_destroyed) GetTextInputClient()->InsertText(text); - composition_.Clear(); + composition_ = CompositionText(); } } @@ -379,7 +379,7 @@ if (is_sync_mode_) { if (!composition_.text.empty()) { - composition_.Clear(); + composition_ = CompositionText(); composition_changed_ = true; } } else { @@ -392,7 +392,7 @@ if (!event.stopped_propagation() && !details.target_destroyed) client->ClearCompositionText(); } - composition_.Clear(); + composition_ = CompositionText(); } }
diff --git a/ui/base/ime/input_method_base.h b/ui/base/ime/input_method_base.h index dbf9df4..77c95ef 100644 --- a/ui/base/ime/input_method_base.h +++ b/ui/base/ime/input_method_base.h
@@ -29,7 +29,7 @@ // A helper class providing functionalities shared among ui::InputMethod // implementations. class UI_BASE_IME_EXPORT InputMethodBase - : NON_EXPORTED_BASE(public InputMethod), + : public InputMethod, public base::SupportsWeakPtr<InputMethodBase>, public IMEInputContextHandlerInterface { public:
diff --git a/ui/base/ime/input_method_chromeos.cc b/ui/base/ime/input_method_chromeos.cc index f15d2d0..b46749a 100644 --- a/ui/base/ime/input_method_chromeos.cc +++ b/ui/base/ime/input_method_chromeos.cc
@@ -289,7 +289,7 @@ if (!IsNonPasswordInputFieldFocused() || !GetTextInputClient()) return; - composition_.Clear(); + composition_ = CompositionText(); result_text_.clear(); composing_text_ = false; composition_changed_ = false; @@ -534,7 +534,7 @@ GetTextInputClient()->SetCompositionText(composition_); SendFakeProcessKeyEvent(false); composition_changed_ = false; - composition_.Clear(); + composition_ = CompositionText(); } } @@ -544,7 +544,7 @@ // Intentionally leaves |composing_text_| unchanged. composition_changed_ = true; - composition_.Clear(); + composition_ = CompositionText(); if (!handling_key_event_) { TextInputClient* client = GetTextInputClient(); @@ -588,7 +588,7 @@ const CompositionText& text, uint32_t cursor_position, CompositionText* out_composition) const { - out_composition->Clear(); + *out_composition = CompositionText(); out_composition->text = text.text; if (out_composition->text.empty())
diff --git a/ui/base/ime/mock_ime_input_context_handler.cc b/ui/base/ime/mock_ime_input_context_handler.cc index 4c6045d..b0ef49d 100644 --- a/ui/base/ime/mock_ime_input_context_handler.cc +++ b/ui/base/ime/mock_ime_input_context_handler.cc
@@ -26,7 +26,7 @@ uint32_t cursor_pos, bool visible) { ++update_preedit_text_call_count_; - last_update_composition_arg_.composition_text.CopyFrom(text); + last_update_composition_arg_.composition_text = text; last_update_composition_arg_.cursor_pos = cursor_pos; last_update_composition_arg_.is_visible = visible; }
diff --git a/ui/base/ime/mock_input_method.h b/ui/base/ime/mock_input_method.h index f703e4a0..b841a7a 100644 --- a/ui/base/ime/mock_input_method.h +++ b/ui/base/ime/mock_input_method.h
@@ -23,8 +23,7 @@ // of this class as the global input method with calling // SetUpInputMethodFactoryForTesting() which is declared in // ui/base/ime/input_method_factory.h -class UI_BASE_IME_EXPORT MockInputMethod - : NON_EXPORTED_BASE(public InputMethod) { +class UI_BASE_IME_EXPORT MockInputMethod : public InputMethod { public: explicit MockInputMethod(internal::InputMethodDelegate* delegate); ~MockInputMethod() override;
diff --git a/ui/base/models/button_menu_item_model.h b/ui/base/models/button_menu_item_model.h index 0b15d9c..22595e6 100644 --- a/ui/base/models/button_menu_item_model.h +++ b/ui/base/models/button_menu_item_model.h
@@ -26,8 +26,7 @@ TYPE_BUTTON_LABEL }; - class UI_BASE_EXPORT Delegate - : NON_EXPORTED_BASE(public AcceleratorProvider) { + class UI_BASE_EXPORT Delegate : public AcceleratorProvider { public: // Some command ids have labels that change over time. virtual bool IsItemForCommandIdDynamic(int command_id) const;
diff --git a/ui/base/models/simple_menu_model.h b/ui/base/models/simple_menu_model.h index 9a9f350..7c54a24e 100644 --- a/ui/base/models/simple_menu_model.h +++ b/ui/base/models/simple_menu_model.h
@@ -28,8 +28,7 @@ // The breadth of MenuModel is not exposed through this API. class UI_BASE_EXPORT SimpleMenuModel : public MenuModel { public: - class UI_BASE_EXPORT Delegate - : NON_EXPORTED_BASE(public AcceleratorProvider) { + class UI_BASE_EXPORT Delegate : public AcceleratorProvider { public: ~Delegate() override {}
diff --git a/ui/base/ui_base_switches.cc b/ui/base/ui_base_switches.cc index 4267481..1793a82 100644 --- a/ui/base/ui_base_switches.cc +++ b/ui/base/ui_base_switches.cc
@@ -104,6 +104,9 @@ // Red: Overdrawn four or more times. const char kShowOverdrawFeedback[] = "show-overdraw-feedback"; +// Use SkiaRenderer instead of GLRenderer for direct rendering. +const char kUseSkiaRenderer[] = "use-skia-renderer"; + // Disable re-use of non-exact resources to fulfill ResourcePool requests. // Intended only for use in layout or pixel tests to reduce noise. const char kDisallowNonExactResourceReuse[] =
diff --git a/ui/base/ui_base_switches.h b/ui/base/ui_base_switches.h index b3a4634..ad45b7e 100644 --- a/ui/base/ui_base_switches.h +++ b/ui/base/ui_base_switches.h
@@ -45,6 +45,7 @@ UI_BASE_EXPORT extern const char kExtendMdToSecondaryUi[]; UI_BASE_EXPORT extern const char kUIDisablePartialSwap[]; UI_BASE_EXPORT extern const char kShowOverdrawFeedback[]; +UI_BASE_EXPORT extern const char kUseSkiaRenderer[]; // Test related. UI_BASE_EXPORT extern const char kDisallowNonExactResourceReuse[];
diff --git a/ui/base/win/accessibility_misc_utils.h b/ui/base/win/accessibility_misc_utils.h index bb5befce..23c9ca97 100644 --- a/ui/base/win/accessibility_misc_utils.h +++ b/ui/base/win/accessibility_misc_utils.h
@@ -17,7 +17,7 @@ // UIA Text provider implementation for edit controls. class UI_BASE_EXPORT UIATextProvider - : public NON_EXPORTED_BASE(CComObjectRootEx<CComMultiThreadModel>), + : public CComObjectRootEx<CComMultiThreadModel>, public IValueProvider, public ITextProvider { public:
diff --git a/ui/chromeos/BUILD.gn b/ui/chromeos/BUILD.gn index e83d1d043..0b7d6c0 100644 --- a/ui/chromeos/BUILD.gn +++ b/ui/chromeos/BUILD.gn
@@ -11,6 +11,8 @@ sources = [ "accelerometer/accelerometer_util.cc", "accelerometer/accelerometer_util.h", + "devicetype_utils.cc", + "devicetype_utils.h", "ime/candidate_view.cc", "ime/candidate_view.h", "ime/candidate_window_constants.h",
diff --git a/ui/chromeos/devicetype_utils.cc b/ui/chromeos/devicetype_utils.cc new file mode 100644 index 0000000..6e1859d2 --- /dev/null +++ b/ui/chromeos/devicetype_utils.cc
@@ -0,0 +1,40 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/chromeos/devicetype_utils.h" + +#include "base/logging.h" +#include "chromeos/system/devicetype.h" +#include "ui/base/l10n/l10n_util.h" +#include "ui/chromeos/strings/grit/ui_chromeos_strings.h" + +namespace ui { + +base::string16 SubstituteChromeOSDeviceType(int resource_id) { + return l10n_util::GetStringFUTF16(resource_id, GetChromeOSDeviceName()); +} + +base::string16 GetChromeOSDeviceName() { + return l10n_util::GetStringUTF16(GetChromeOSDeviceTypeResourceId()); +} + +int GetChromeOSDeviceTypeResourceId() { + switch (chromeos::GetDeviceType()) { + case chromeos::DeviceType::kChromebase: + return IDS_CHROMEBASE_DEVICE_NAME; + case chromeos::DeviceType::kChromebook: + return IDS_CHROMEBOOK_DEVICE_NAME; + case chromeos::DeviceType::kChromebox: + return IDS_CHROMEBOX_DEVICE_NAME; + case chromeos::DeviceType::kChromebit: + return IDS_CHROMEBIT_DEVICE_NAME; + case chromeos::DeviceType::kUnknown: + return IDS_GENERIC_CHROMEOS_DEVICE_NAME; + } + + NOTREACHED(); + return IDS_GENERIC_CHROMEOS_DEVICE_NAME; +} + +} // namespace ui
diff --git a/ui/chromeos/devicetype_utils.h b/ui/chromeos/devicetype_utils.h new file mode 100644 index 0000000..68f2a0e --- /dev/null +++ b/ui/chromeos/devicetype_utils.h
@@ -0,0 +1,26 @@ +// 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. + +#ifndef UI_CHROMEOS_DEVICETYPE_UTILS_H_ +#define UI_CHROMEOS_DEVICETYPE_UTILS_H_ + +#include "base/strings/string16.h" +#include "ui/chromeos/ui_chromeos_export.h" + +namespace ui { + +// Assuming the given localization resources takes a device type parameter, this +// will substitute the appropriate device in (e.g. Chromebook, Chromebox). +UI_CHROMEOS_EXPORT base::string16 SubstituteChromeOSDeviceType(int resource_id); + +// Returns the name of the Chrome device type (e.g. Chromebook, Chromebox). +UI_CHROMEOS_EXPORT base::string16 GetChromeOSDeviceName(); + +// Returns the resource ID for the current Chrome device type (e.g. Chromebook, +// Chromebox). +UI_CHROMEOS_EXPORT int GetChromeOSDeviceTypeResourceId(); + +} // namespace ui + +#endif // UI_CHROMEOS_DEVICETYPE_UTILS_H_
diff --git a/ui/chromeos/ui_chromeos_strings.grd b/ui/chromeos/ui_chromeos_strings.grd index 25f1ac3..70a9de4b 100644 --- a/ui/chromeos/ui_chromeos_strings.grd +++ b/ui/chromeos/ui_chromeos_strings.grd
@@ -432,6 +432,23 @@ <message translateable="false" name="IDS_LOGIN_DEFAULT_USER_WEBSITE_33"> </message> + <!-- Generic device type names --> + <message name="IDS_CHROMEBASE_DEVICE_NAME" desc="The device name for a Chromebase (versus say Chromebox)"> + Chromebase + </message> + <message name="IDS_CHROMEBIT_DEVICE_NAME" desc="The device name for a Chromebit (versus say Chromebox)"> + Chromebit + </message> + <message name="IDS_CHROMEBOOK_DEVICE_NAME" desc="The device name for a Chromebook (versus say Chromebox)"> + Chromebook + </message> + <message name="IDS_CHROMEBOX_DEVICE_NAME" desc="The device name for a Chromebox (versus say Chromebook)"> + Chromebox + </message> + <message name="IDS_GENERIC_CHROMEOS_DEVICE_NAME" desc="The device name for a generic Chrome device"> + Chrome device + </message> + <!-- Input method strings. --> <message name="IDS_CHROMEOS_IME_INFOLIST_WINDOW_TITLE" desc="The title of the infolist window where the meanings and the usages of words are displayed."> Information
diff --git a/ui/compositor/compositor.h b/ui/compositor/compositor.h index b01b4116..e33bc48 100644 --- a/ui/compositor/compositor.h +++ b/ui/compositor/compositor.h
@@ -183,11 +183,10 @@ // displayable form of pixels comprising a single widget's contents. It draws an // appropriately transformed texture for each transformed view in the widget's // view hierarchy. -class COMPOSITOR_EXPORT Compositor - : NON_EXPORTED_BASE(public cc::LayerTreeHostClient), - NON_EXPORTED_BASE(public cc::LayerTreeHostSingleThreadClient), - NON_EXPORTED_BASE(public CompositorLockDelegate), - NON_EXPORTED_BASE(public viz::HostFrameSinkClient) { +class COMPOSITOR_EXPORT Compositor : public cc::LayerTreeHostClient, + public cc::LayerTreeHostSingleThreadClient, + public CompositorLockDelegate, + public viz::HostFrameSinkClient { public: Compositor(const viz::FrameSinkId& frame_sink_id, ui::ContextFactory* context_factory,
diff --git a/ui/compositor/compositor_unittest.cc b/ui/compositor/compositor_unittest.cc index 42491420..83878b0 100644 --- a/ui/compositor/compositor_unittest.cc +++ b/ui/compositor/compositor_unittest.cc
@@ -115,8 +115,7 @@ bool locked_ = false; }; -class MockCompositorLockClient - : NON_EXPORTED_BASE(public ui::CompositorLockClient) { +class MockCompositorLockClient : public ui::CompositorLockClient { public: MOCK_METHOD0(CompositorLockTimedOut, void()); };
diff --git a/ui/compositor/layer.h b/ui/compositor/layer.h index 3aa0427..fb04e99 100644 --- a/ui/compositor/layer.h +++ b/ui/compositor/layer.h
@@ -63,11 +63,10 @@ // NOTE: Unlike Views, each Layer does *not* own its child Layers. If you // delete a Layer and it has children, the parent of each child Layer is set to // NULL, but the children are not deleted. -class COMPOSITOR_EXPORT Layer - : public LayerAnimationDelegate, - NON_EXPORTED_BASE(public cc::ContentLayerClient), - NON_EXPORTED_BASE(public cc::TextureLayerClient), - NON_EXPORTED_BASE(public cc::LayerClient) { +class COMPOSITOR_EXPORT Layer : public LayerAnimationDelegate, + public cc::ContentLayerClient, + public cc::TextureLayerClient, + public cc::LayerClient { public: Layer(); explicit Layer(LayerType type);
diff --git a/ui/compositor/layer_animator.h b/ui/compositor/layer_animator.h index a3a2768..a86864c 100644 --- a/ui/compositor/layer_animator.h +++ b/ui/compositor/layer_animator.h
@@ -53,10 +53,9 @@ // ensure that it is not disposed of until it finishes executing. It does this // by holding a reference to itself for the duration of methods for which it // must guarantee that |this| is valid. -class COMPOSITOR_EXPORT LayerAnimator - : public base::RefCounted<LayerAnimator>, - public LayerThreadedAnimationDelegate, - NON_EXPORTED_BASE(public cc::AnimationDelegate) { +class COMPOSITOR_EXPORT LayerAnimator : public base::RefCounted<LayerAnimator>, + public LayerThreadedAnimationDelegate, + public cc::AnimationDelegate { public: enum PreemptionStrategy { IMMEDIATELY_SET_NEW_TARGET,
diff --git a/ui/display/BUILD.gn b/ui/display/BUILD.gn index dcede94..f4a4f5b 100644 --- a/ui/display/BUILD.gn +++ b/ui/display/BUILD.gn
@@ -145,7 +145,6 @@ "manager/chromeos/configure_displays_task_unittest.cc", "manager/chromeos/display_change_observer_unittest.cc", "manager/chromeos/display_configurator_unittest.cc", - "manager/chromeos/mojo/touch_device_transform_struct_traits_unittest.cc", "manager/chromeos/query_content_protection_task_unittest.cc", "manager/chromeos/touch_transform_controller_unittest.cc", "manager/chromeos/touchscreen_util_unittest.cc", @@ -171,10 +170,10 @@ "//testing/gmock", "//testing/gtest", "//ui/display/manager", - "//ui/display/manager/chromeos/mojo:interfaces", "//ui/display/mojo:interfaces", "//ui/display/types", "//ui/display/util", + "//ui/events:test_support", "//ui/events/devices", "//ui/gfx:test_support", "//ui/gfx/geometry",
diff --git a/ui/display/manager/BUILD.gn b/ui/display/manager/BUILD.gn index 2684860..ba0f5911 100644 --- a/ui/display/manager/BUILD.gn +++ b/ui/display/manager/BUILD.gn
@@ -21,8 +21,6 @@ "chromeos/display_util.h", "chromeos/query_content_protection_task.cc", "chromeos/query_content_protection_task.h", - "chromeos/touch_device_transform.cc", - "chromeos/touch_device_transform.h", "chromeos/touch_transform_controller.cc", "chromeos/touch_transform_controller.h", "chromeos/touch_transform_setter.h",
diff --git a/ui/display/manager/chromeos/DEPS b/ui/display/manager/chromeos/DEPS index 5943a4f..5663dc26 100644 --- a/ui/display/manager/chromeos/DEPS +++ b/ui/display/manager/chromeos/DEPS
@@ -15,5 +15,6 @@ ], "touch_transform_controller_unittest.cc": [ "+ui/events/devices/device_data_manager.h", + "+ui/events/test/device_data_manager_test_api.h", ], }
diff --git a/ui/display/manager/chromeos/default_touch_transform_setter.cc b/ui/display/manager/chromeos/default_touch_transform_setter.cc index cd94a89..1e9f12c 100644 --- a/ui/display/manager/chromeos/default_touch_transform_setter.cc +++ b/ui/display/manager/chromeos/default_touch_transform_setter.cc
@@ -4,8 +4,8 @@ #include "ui/display/manager/chromeos/default_touch_transform_setter.h" -#include "ui/display/manager/chromeos/touch_device_transform.h" #include "ui/events/devices/device_data_manager.h" +#include "ui/events/devices/touch_device_transform.h" namespace display { @@ -14,18 +14,8 @@ DefaultTouchTransformSetter::~DefaultTouchTransformSetter() = default; void DefaultTouchTransformSetter::ConfigureTouchDevices( - const std::map<int32_t, double>& scales, - const std::vector<TouchDeviceTransform>& transforms) { - ui::DeviceDataManager* device_manager = ui::DeviceDataManager::GetInstance(); - device_manager->ClearTouchDeviceAssociations(); - for (auto& device_scale_pair : scales) { - device_manager->UpdateTouchRadiusScale(device_scale_pair.first, - device_scale_pair.second); - } - for (const TouchDeviceTransform& transform : transforms) { - device_manager->UpdateTouchInfoForDisplay( - transform.display_id, transform.device_id, transform.transform); - } + const std::vector<ui::TouchDeviceTransform>& transforms) { + ui::DeviceDataManager::GetInstance()->ConfigureTouchDevices(transforms); } } // namespace display
diff --git a/ui/display/manager/chromeos/default_touch_transform_setter.h b/ui/display/manager/chromeos/default_touch_transform_setter.h index aa451f7..7f64f27 100644 --- a/ui/display/manager/chromeos/default_touch_transform_setter.h +++ b/ui/display/manager/chromeos/default_touch_transform_setter.h
@@ -18,8 +18,7 @@ // TouchTransformSetter: void ConfigureTouchDevices( - const std::map<int32_t, double>& scales, - const std::vector<TouchDeviceTransform>& transforms) override; + const std::vector<ui::TouchDeviceTransform>& transforms) override; private: DISALLOW_COPY_AND_ASSIGN(DefaultTouchTransformSetter);
diff --git a/ui/display/manager/chromeos/mojo/BUILD.gn b/ui/display/manager/chromeos/mojo/BUILD.gn deleted file mode 100644 index e29b518..0000000 --- a/ui/display/manager/chromeos/mojo/BUILD.gn +++ /dev/null
@@ -1,15 +0,0 @@ -# Copyright 2017 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -import("//mojo/public/tools/bindings/mojom.gni") - -mojom("interfaces") { - sources = [ - "touch_device_transform.mojom", - ] - - public_deps = [ - "//ui/gfx/mojo", - ] -}
diff --git a/ui/display/manager/chromeos/mojo/OWNERS b/ui/display/manager/chromeos/mojo/OWNERS deleted file mode 100644 index e75daf74..0000000 --- a/ui/display/manager/chromeos/mojo/OWNERS +++ /dev/null
@@ -1,8 +0,0 @@ -per-file *_struct_traits*.*=set noparent -per-file *_struct_traits*.*=file://ipc/SECURITY_OWNERS - -per-file *.mojom=set noparent -per-file *.mojom=file://ipc/SECURITY_OWNERS - -per-file *.typemap=set noparent -per-file *.typemap=file://ipc/SECURITY_OWNERS
diff --git a/ui/display/manager/chromeos/mojo/touch_device_transform.mojom b/ui/display/manager/chromeos/mojo/touch_device_transform.mojom deleted file mode 100644 index 3daa9913..0000000 --- a/ui/display/manager/chromeos/mojo/touch_device_transform.mojom +++ /dev/null
@@ -1,13 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -module display.mojom; - -import "ui/gfx/mojo/transform.mojom"; - -struct TouchDeviceTransform { - int64 display_id; - int32 device_id; - gfx.mojom.Transform transform; -};
diff --git a/ui/display/manager/chromeos/mojo/touch_device_transform.typemap b/ui/display/manager/chromeos/mojo/touch_device_transform.typemap deleted file mode 100644 index 3a0a962..0000000 --- a/ui/display/manager/chromeos/mojo/touch_device_transform.typemap +++ /dev/null
@@ -1,15 +0,0 @@ -# Copyright 2017 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -mojom = "//ui/display/manager/chromeos/mojo/touch_device_transform.mojom" -public_headers = [ "//ui/display/manager/chromeos/touch_device_transform.h" ] -traits_headers = [ "//ui/display/manager/chromeos/mojo/touch_device_transform_struct_traits.h" ] -deps = [ - "//ui/gfx/mojo:struct_traits", -] -public_deps = [ - "//ui/display/manager", -] -type_mappings = - [ "display.mojom.TouchDeviceTransform=display::TouchDeviceTransform" ]
diff --git a/ui/display/manager/chromeos/mojo/touch_device_transform_struct_traits.h b/ui/display/manager/chromeos/mojo/touch_device_transform_struct_traits.h deleted file mode 100644 index 296ed50..0000000 --- a/ui/display/manager/chromeos/mojo/touch_device_transform_struct_traits.h +++ /dev/null
@@ -1,43 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef UI_DISPLAY_MANAGER_CHROMEOS_MOJO_TOUCH_DEVICE_TRANSFORM_STRUCT_TRAITS_H_ -#define UI_DISPLAY_MANAGER_CHROMEOS_MOJO_TOUCH_DEVICE_TRANSFORM_STRUCT_TRAITS_H_ - -#include <stdint.h> - -#include "ui/display/manager/chromeos/mojo/touch_device_transform.mojom.h" -#include "ui/display/manager/chromeos/touch_device_transform.h" -#include "ui/gfx/mojo/transform_struct_traits.h" - -namespace mojo { - -template <> -struct StructTraits<display::mojom::TouchDeviceTransformDataView, - display::TouchDeviceTransform> { - public: - static int64_t display_id(const display::TouchDeviceTransform& r) { - return r.display_id; - } - static int32_t device_id(const display::TouchDeviceTransform& r) { - return r.device_id; - } - static const gfx::Transform& transform( - const display::TouchDeviceTransform& r) { - return r.transform; - } - - static bool Read(display::mojom::TouchDeviceTransformDataView data, - display::TouchDeviceTransform* out) { - out->display_id = data.display_id(); - out->device_id = data.device_id(); - if (!data.ReadTransform(&(out->transform))) - return false; - return true; - } -}; - -} // namespace mojo - -#endif // UI_DISPLAY_MANAGER_CHROMEOS_MOJO_TOUCH_DEVICE_TRANSFORM_STRUCT_TRAITS_H_
diff --git a/ui/display/manager/chromeos/mojo/touch_device_transform_struct_traits_unittest.cc b/ui/display/manager/chromeos/mojo/touch_device_transform_struct_traits_unittest.cc deleted file mode 100644 index 42d18da..0000000 --- a/ui/display/manager/chromeos/mojo/touch_device_transform_struct_traits_unittest.cc +++ /dev/null
@@ -1,28 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/display/manager/chromeos/mojo/touch_device_transform_struct_traits.h" - -#include "testing/gtest/include/gtest/gtest.h" -#include "ui/display/manager/chromeos/mojo/touch_device_transform.mojom.h" -#include "ui/display/manager/chromeos/touch_device_transform.h" - -namespace display { - -TEST(TouchDeviceTransformStructTraitsTest, SerializeAndDeserialize) { - TouchDeviceTransform touch_device_transform; - touch_device_transform.display_id = 101; - touch_device_transform.device_id = 202; - touch_device_transform.transform = - gfx::Transform(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); - TouchDeviceTransform deserialized; - ASSERT_TRUE(mojom::TouchDeviceTransform::Deserialize( - mojom::TouchDeviceTransform::Serialize(&touch_device_transform), - &deserialized)); - EXPECT_EQ(touch_device_transform.display_id, deserialized.display_id); - EXPECT_EQ(touch_device_transform.device_id, deserialized.device_id); - EXPECT_EQ(touch_device_transform.transform, deserialized.transform); -} - -} // namespace display
diff --git a/ui/display/manager/chromeos/mojo/typemaps.gni b/ui/display/manager/chromeos/mojo/typemaps.gni deleted file mode 100644 index 21a671b..0000000 --- a/ui/display/manager/chromeos/mojo/typemaps.gni +++ /dev/null
@@ -1,6 +0,0 @@ -# Copyright 2017 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -typemaps = - [ "//ui/display/manager/chromeos/mojo/touch_device_transform.typemap" ]
diff --git a/ui/display/manager/chromeos/touch_device_transform.cc b/ui/display/manager/chromeos/touch_device_transform.cc deleted file mode 100644 index 50e8c20e..0000000 --- a/ui/display/manager/chromeos/touch_device_transform.cc +++ /dev/null
@@ -1,13 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/display/manager/chromeos/touch_device_transform.h" - -namespace display { - -TouchDeviceTransform::TouchDeviceTransform() = default; - -TouchDeviceTransform::~TouchDeviceTransform() = default; - -} // namespace display
diff --git a/ui/display/manager/chromeos/touch_device_transform.h b/ui/display/manager/chromeos/touch_device_transform.h deleted file mode 100644 index c9eee51..0000000 --- a/ui/display/manager/chromeos/touch_device_transform.h +++ /dev/null
@@ -1,26 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef UI_DISPLAY_MANAGER_CHROMEOS_TOUCH_DEVICE_TRANSFORM_H_ -#define UI_DISPLAY_MANAGER_CHROMEOS_TOUCH_DEVICE_TRANSFORM_H_ - -#include <stdint.h> - -#include "ui/display/manager/display_manager_export.h" -#include "ui/gfx/transform.h" - -namespace display { - -struct DISPLAY_MANAGER_EXPORT TouchDeviceTransform { - TouchDeviceTransform(); - ~TouchDeviceTransform(); - - int64_t display_id; - int32_t device_id; - gfx::Transform transform; -}; - -} // namespace display - -#endif // UI_DISPLAY_MANAGER_CHROMEOS_TOUCH_DEVICE_TRANSFORM_H_
diff --git a/ui/display/manager/chromeos/touch_transform_controller.cc b/ui/display/manager/chromeos/touch_transform_controller.cc index c546922..3ed5de8 100644 --- a/ui/display/manager/chromeos/touch_transform_controller.cc +++ b/ui/display/manager/chromeos/touch_transform_controller.cc
@@ -10,7 +10,6 @@ #include "third_party/skia/include/core/SkMatrix44.h" #include "ui/display/display_layout.h" #include "ui/display/manager/chromeos/display_configurator.h" -#include "ui/display/manager/chromeos/touch_device_transform.h" #include "ui/display/manager/chromeos/touch_transform_setter.h" #include "ui/display/manager/display_manager.h" #include "ui/display/manager/managed_display_info.h" @@ -18,6 +17,7 @@ #include "ui/display/types/display_constants.h" #include "ui/display/types/display_snapshot.h" #include "ui/events/devices/input_device_manager.h" +#include "ui/events/devices/touch_device_transform.h" namespace display { @@ -292,8 +292,7 @@ void TouchTransformController::UpdateTouchTransforms() const { UpdateData update_data; UpdateTouchTransforms(&update_data); - setter_->ConfigureTouchDevices(update_data.device_to_scale, - update_data.touch_device_transforms); + setter_->ConfigureTouchDevices(update_data.touch_device_transforms); } void TouchTransformController::UpdateTouchRadius( @@ -311,12 +310,15 @@ const ManagedDisplayInfo& touch_display, const ManagedDisplayInfo& target_display, UpdateData* update_data) const { - TouchDeviceTransform touch_device_transform; + ui::TouchDeviceTransform touch_device_transform; touch_device_transform.display_id = target_display_id; for (const auto& device_id : touch_display.input_devices()) { touch_device_transform.device_id = device_id; touch_device_transform.transform = GetTouchTransform( target_display, touch_display, FindTouchscreenById(device_id)); + auto device_to_scale_iter = update_data->device_to_scale.find(device_id); + if (device_to_scale_iter != update_data->device_to_scale.end()) + touch_device_transform.radius_scale = device_to_scale_iter->second; update_data->touch_device_transforms.push_back(touch_device_transform); } }
diff --git a/ui/display/manager/chromeos/touch_transform_controller.h b/ui/display/manager/chromeos/touch_transform_controller.h index ec653b7..1d089e4e 100644 --- a/ui/display/manager/chromeos/touch_transform_controller.h +++ b/ui/display/manager/chromeos/touch_transform_controller.h
@@ -17,6 +17,7 @@ namespace ui { struct TouchscreenDevice; +struct TouchDeviceTransform; } namespace display { @@ -26,8 +27,6 @@ class ManagedDisplayInfo; class TouchTransformSetter; -struct TouchDeviceTransform; - namespace test { class TouchTransformControllerTest; } @@ -59,7 +58,7 @@ ~UpdateData(); std::map<int32_t, double> device_to_scale; - std::vector<TouchDeviceTransform> touch_device_transforms; + std::vector<ui::TouchDeviceTransform> touch_device_transforms; }; void UpdateTouchTransforms(UpdateData* data) const;
diff --git a/ui/display/manager/chromeos/touch_transform_controller_unittest.cc b/ui/display/manager/chromeos/touch_transform_controller_unittest.cc index a15c0bef..2860c0855 100644 --- a/ui/display/manager/chromeos/touch_transform_controller_unittest.cc +++ b/ui/display/manager/chromeos/touch_transform_controller_unittest.cc
@@ -41,6 +41,19 @@ return info; } +ui::TouchDeviceTransform CreateTouchDeviceTransform( + int64_t display_id, + int32_t device_id, + const gfx::Transform& transform, + double radius_scale = 1.0) { + ui::TouchDeviceTransform touch_device_transform; + touch_device_transform.display_id = display_id; + touch_device_transform.device_id = device_id; + touch_device_transform.transform = transform; + touch_device_transform.radius_scale = radius_scale; + return touch_device_transform; +} + ui::TouchscreenDevice CreateTouchscreenDevice(unsigned int id, const gfx::Size& size) { return ui::TouchscreenDevice(id, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, @@ -170,15 +183,16 @@ ui::DeviceDataManager* device_manager = ui::DeviceDataManager::GetInstance(); - device_manager->UpdateTouchInfoForDisplay( + std::vector<ui::TouchDeviceTransform> transforms; + transforms.push_back(CreateTouchDeviceTransform( internal_display_info.id(), internal_touchscreen.id, GetTouchTransform(internal_display_info, internal_display_info, - internal_touchscreen)); - - device_manager->UpdateTouchInfoForDisplay( + internal_touchscreen))); + transforms.push_back(CreateTouchDeviceTransform( internal_display_info.id(), external_touchscreen.id, GetTouchTransform(external_display_info, external_display_info, - external_touchscreen)); + external_touchscreen))); + device_manager->ConfigureTouchDevices(transforms); EXPECT_EQ(1, device_manager->GetTargetDisplayForTouchDevice(10)); EXPECT_EQ(1, device_manager->GetTargetDisplayForTouchDevice(11)); @@ -235,16 +249,18 @@ CreateTouchscreenDevice(11, fb_size); ui::DeviceDataManager* device_manager = ui::DeviceDataManager::GetInstance(); + std::vector<ui::TouchDeviceTransform> transforms; - device_manager->UpdateTouchInfoForDisplay( + transforms.push_back(CreateTouchDeviceTransform( internal_display_info.id(), internal_touchscreen.id, GetTouchTransform(internal_display_info, internal_display_info, - internal_touchscreen)); + internal_touchscreen))); - device_manager->UpdateTouchInfoForDisplay( + transforms.push_back(CreateTouchDeviceTransform( internal_display_info.id(), external_touchscreen.id, GetTouchTransform(external_display_info, external_display_info, - external_touchscreen)); + external_touchscreen))); + device_manager->ConfigureTouchDevices(transforms); EXPECT_EQ(1, device_manager->GetTargetDisplayForTouchDevice(10)); EXPECT_EQ(1, device_manager->GetTargetDisplayForTouchDevice(11)); @@ -306,14 +322,17 @@ CreateTouchscreenDevice(11, fb_size); ui::DeviceDataManager* device_manager = ui::DeviceDataManager::GetInstance(); + std::vector<ui::TouchDeviceTransform> transforms; - device_manager->UpdateTouchInfoForDisplay( + transforms.push_back(CreateTouchDeviceTransform( display1_info.id(), display1_touchscreen.id, - GetTouchTransform(display1_info, display1_info, display1_touchscreen)); + GetTouchTransform(display1_info, display1_info, display1_touchscreen))); - device_manager->UpdateTouchInfoForDisplay( + transforms.push_back(CreateTouchDeviceTransform( display1_info.id(), display2_touchscreen.id, - GetTouchTransform(display1_info, display2_info, display2_touchscreen)); + GetTouchTransform(display1_info, display2_info, display2_touchscreen))); + + device_manager->ConfigureTouchDevices(transforms); EXPECT_EQ(1, device_manager->GetTargetDisplayForTouchDevice(10)); EXPECT_EQ(1, device_manager->GetTargetDisplayForTouchDevice(11)); @@ -372,14 +391,15 @@ ui::TouchscreenDevice touchscreen2 = CreateTouchscreenDevice(6, fb_size); ui::DeviceDataManager* device_manager = ui::DeviceDataManager::GetInstance(); - - device_manager->UpdateTouchInfoForDisplay( + std::vector<ui::TouchDeviceTransform> transforms; + transforms.push_back(CreateTouchDeviceTransform( display1.id(), touchscreen1.id, - GetTouchTransform(display1, display1, touchscreen1)); + GetTouchTransform(display1, display1, touchscreen1))); - device_manager->UpdateTouchInfoForDisplay( + transforms.push_back(CreateTouchDeviceTransform( display2.id(), touchscreen2.id, - GetTouchTransform(display2, display2, touchscreen2)); + GetTouchTransform(display2, display2, touchscreen2))); + device_manager->ConfigureTouchDevices(transforms); EXPECT_EQ(1, device_manager->GetTargetDisplayForTouchDevice(5)); EXPECT_EQ(2, device_manager->GetTargetDisplayForTouchDevice(6)); @@ -449,15 +469,17 @@ CreateTouchscreenDevice(kTouchId2, kDisplaySize); ui::DeviceDataManager* device_manager = ui::DeviceDataManager::GetInstance(); + std::vector<ui::TouchDeviceTransform> transforms; // Mirror displays. Touch screen 2 is associated to display 1. - device_manager->UpdateTouchInfoForDisplay( + transforms.push_back(CreateTouchDeviceTransform( display1.id(), touchscreen1.id, - GetTouchTransform(display1, display1, touchscreen1)); + GetTouchTransform(display1, display1, touchscreen1))); - device_manager->UpdateTouchInfoForDisplay( + transforms.push_back(CreateTouchDeviceTransform( display1.id(), touchscreen2.id, - GetTouchTransform(display1, display2, touchscreen2)); + GetTouchTransform(display1, display2, touchscreen2))); + device_manager->ConfigureTouchDevices(transforms); EXPECT_EQ(kDisplayId1, device_manager->GetTargetDisplayForTouchDevice(kTouchId1)); @@ -489,9 +511,10 @@ EXPECT_NEAR(1200, y, 0.5); // Remove mirroring of displays. - device_manager->UpdateTouchInfoForDisplay( + transforms.push_back(CreateTouchDeviceTransform( display2.id(), touchscreen2.id, - GetTouchTransform(display2, display2, touchscreen2)); + GetTouchTransform(display2, display2, touchscreen2))); + device_manager->ConfigureTouchDevices(transforms); x = 1920.0; y = 1200.0; @@ -532,10 +555,11 @@ CreateTouchscreenDevice(kTouchId1, kTouchSize); ui::DeviceDataManager* device_manager = ui::DeviceDataManager::GetInstance(); - - device_manager->UpdateTouchInfoForDisplay( + std::vector<ui::TouchDeviceTransform> transforms; + transforms.push_back(CreateTouchDeviceTransform( display.id(), touchscreen.id, - GetTouchTransform(display, display, touchscreen)); + GetTouchTransform(display, display, touchscreen))); + device_manager->ConfigureTouchDevices(transforms); EXPECT_EQ(kDisplayId1, device_manager->GetTargetDisplayForTouchDevice(kTouchId1)); @@ -575,10 +599,11 @@ CreateTouchscreenDevice(kTouchId1, kTouchSize); ui::DeviceDataManager* device_manager = ui::DeviceDataManager::GetInstance(); - - device_manager->UpdateTouchInfoForDisplay( + std::vector<ui::TouchDeviceTransform> transforms; + transforms.push_back(CreateTouchDeviceTransform( display.id(), touchscreen.id, - GetTouchTransform(display, display, touchscreen)); + GetTouchTransform(display, display, touchscreen))); + device_manager->ConfigureTouchDevices(transforms); EXPECT_EQ(kDisplayId1, device_manager->GetTargetDisplayForTouchDevice(kTouchId1)); @@ -620,10 +645,11 @@ CreateTouchscreenDevice(kTouchId1, kTouchSize); ui::DeviceDataManager* device_manager = ui::DeviceDataManager::GetInstance(); - - device_manager->UpdateTouchInfoForDisplay( + std::vector<ui::TouchDeviceTransform> transforms; + transforms.push_back(CreateTouchDeviceTransform( display.id(), touchscreen.id, - GetTouchTransform(display, display, touchscreen)); + GetTouchTransform(display, display, touchscreen))); + device_manager->ConfigureTouchDevices(transforms); EXPECT_EQ(kDisplayId1, device_manager->GetTargetDisplayForTouchDevice(kTouchId1)); @@ -661,9 +687,11 @@ ui::DeviceDataManager* device_manager = ui::DeviceDataManager::GetInstance(); - device_manager->UpdateTouchInfoForDisplay( + std::vector<ui::TouchDeviceTransform> transforms; + transforms.push_back(CreateTouchDeviceTransform( display.id(), touchscreen.id, - GetTouchTransform(display, display, touchscreen)); + GetTouchTransform(display, display, touchscreen))); + device_manager->ConfigureTouchDevices(transforms); EXPECT_EQ(kDisplayId1, device_manager->GetTargetDisplayForTouchDevice(kTouchId1)); @@ -715,10 +743,12 @@ internal_display_info.SetTouchCalibrationData(touch_data); EXPECT_TRUE(internal_display_info.has_touch_calibration_data()); - device_manager->UpdateTouchInfoForDisplay( + std::vector<ui::TouchDeviceTransform> transforms; + transforms.push_back(CreateTouchDeviceTransform( internal_display_info.id(), internal_touchscreen.id, GetTouchTransform(internal_display_info, internal_display_info, - internal_touchscreen)); + internal_touchscreen))); + device_manager->ConfigureTouchDevices(transforms); EXPECT_EQ(kDisplayId1, device_manager->GetTargetDisplayForTouchDevice(kTouchId1)); @@ -786,10 +816,12 @@ internal_display_info.SetTouchCalibrationData(touch_data); EXPECT_TRUE(internal_display_info.has_touch_calibration_data()); - device_manager->UpdateTouchInfoForDisplay( + std::vector<ui::TouchDeviceTransform> transforms; + transforms.push_back(CreateTouchDeviceTransform( internal_display_info.id(), internal_touchscreen.id, GetTouchTransform(internal_display_info, internal_display_info, - internal_touchscreen)); + internal_touchscreen))); + device_manager->ConfigureTouchDevices(transforms); EXPECT_EQ(kDisplayId1, device_manager->GetTargetDisplayForTouchDevice(kTouchId1));
diff --git a/ui/display/manager/chromeos/touch_transform_setter.h b/ui/display/manager/chromeos/touch_transform_setter.h index 4e87b07..efbb8e12 100644 --- a/ui/display/manager/chromeos/touch_transform_setter.h +++ b/ui/display/manager/chromeos/touch_transform_setter.h
@@ -5,15 +5,16 @@ #ifndef UI_DISPLAY_MANAGER_CHROMEOS_TOUCH_TRANSFORM_SETTER_H_ #define UI_DISPLAY_MANAGER_CHROMEOS_TOUCH_TRANSFORM_SETTER_H_ -#include <map> #include <vector> #include "base/macros.h" #include "ui/display/manager/display_manager_export.h" -namespace display { - +namespace ui { struct TouchDeviceTransform; +} + +namespace display { // TouchTransformSetter is used by TouchTransformController to apply the actual // settings. @@ -21,11 +22,9 @@ public: virtual ~TouchTransformSetter() {} - // |scales| maps from the touch device id to the touch radius scale and // |transforms| contains the transform for each device and display pair. virtual void ConfigureTouchDevices( - const std::map<int32_t, double>& scales, - const std::vector<TouchDeviceTransform>& transforms) = 0; + const std::vector<ui::TouchDeviceTransform>& transforms) = 0; }; } // namespace display
diff --git a/ui/display/manager/forwarding_display_delegate.h b/ui/display/manager/forwarding_display_delegate.h index 761e9c67..bc741bf2 100644 --- a/ui/display/manager/forwarding_display_delegate.h +++ b/ui/display/manager/forwarding_display_delegate.h
@@ -26,7 +26,7 @@ // implemented by Ozone DRM, other method won't do anything. class DISPLAY_MANAGER_EXPORT ForwardingDisplayDelegate : public NativeDisplayDelegate, - public NON_EXPORTED_BASE(mojom::NativeDisplayObserver) { + public mojom::NativeDisplayObserver { public: explicit ForwardingDisplayDelegate(mojom::NativeDisplayDelegatePtr delegate); ~ForwardingDisplayDelegate() override;
diff --git a/ui/events/BUILD.gn b/ui/events/BUILD.gn index ca2f3a9..d5847daa 100644 --- a/ui/events/BUILD.gn +++ b/ui/events/BUILD.gn
@@ -409,7 +409,9 @@ "blink/input_scroll_elasticity_controller_unittest.cc", "blink/web_input_event_traits_unittest.cc", "blink/web_input_event_unittest.cc", + "devices/device_data_manager_unittest.cc", "devices/mojo/device_struct_traits_unittest.cc", + "devices/mojo/touch_device_transform_struct_traits_unittest.cc", "gestures/blink/web_gesture_curve_impl_unittest.cc", "mojo/struct_traits_unittest.cc", ]
diff --git a/ui/events/blink/input_handler_proxy.h b/ui/events/blink/input_handler_proxy.h index e281332..c8a0f09 100644 --- a/ui/events/blink/input_handler_proxy.h +++ b/ui/events/blink/input_handler_proxy.h
@@ -48,10 +48,9 @@ // the compositor's input handling logic. InputHandlerProxy instances live // entirely on the compositor thread. Each InputHandler instance handles input // events intended for a specific WebWidget. -class InputHandlerProxy - : public cc::InputHandlerClient, - public SynchronousInputHandlerProxy, - public NON_EXPORTED_BASE(blink::WebGestureCurveTarget) { +class InputHandlerProxy : public cc::InputHandlerClient, + public SynchronousInputHandlerProxy, + public blink::WebGestureCurveTarget { public: InputHandlerProxy(cc::InputHandler* input_handler, InputHandlerProxyClient* client,
diff --git a/ui/events/devices/BUILD.gn b/ui/events/devices/BUILD.gn index ca8c4e8..5913ef1a 100644 --- a/ui/events/devices/BUILD.gn +++ b/ui/events/devices/BUILD.gn
@@ -25,6 +25,8 @@ "input_device_observer_win.cc", "input_device_observer_win.h", "stylus_state.h", + "touch_device_transform.cc", + "touch_device_transform.h", "touchscreen_device.cc", "touchscreen_device.h", ] @@ -32,6 +34,7 @@ defines = [ "EVENTS_DEVICES_IMPLEMENTATION" ] public_deps = [ + "//ui/display/types", "//ui/gfx", ] @@ -39,7 +42,7 @@ "//base", "//base/third_party/dynamic_annotations", "//skia", - "//ui/display/types", + "//ui/gfx:geometry_skia", "//ui/gfx/geometry", ]
diff --git a/ui/events/devices/device_data_manager.cc b/ui/events/devices/device_data_manager.cc index d66744f3..f80a0c8 100644 --- a/ui/events/devices/device_data_manager.cc +++ b/ui/events/devices/device_data_manager.cc
@@ -9,6 +9,7 @@ #include "base/logging.h" #include "ui/display/types/display_constants.h" #include "ui/events/devices/input_device_event_observer.h" +#include "ui/events/devices/touch_device_transform.h" #include "ui/gfx/geometry/point3_f.h" // This macro provides the implementation for the observer notification methods. @@ -28,16 +29,6 @@ } // namespace -DeviceDataManager::TouchscreenInfo::TouchscreenInfo() { - Reset(); -} - -void DeviceDataManager::TouchscreenInfo::Reset() { - radius_scale = 1.0; - target_display = display::kInvalidDisplayId; - device_transform = gfx::Transform(); -} - // static DeviceDataManager* DeviceDataManager::instance_ = nullptr; @@ -90,30 +81,37 @@ return instance_ != nullptr; } +void DeviceDataManager::ConfigureTouchDevices( + const std::vector<ui::TouchDeviceTransform>& transforms) { + ClearTouchDeviceAssociations(); + for (const TouchDeviceTransform& transform : transforms) + UpdateTouchInfoFromTransform(transform); +} + void DeviceDataManager::ClearTouchDeviceAssociations() { - for (auto& touch_info : touch_map_) - touch_info.Reset(); + for (size_t i = 0; i < touch_map_.size(); ++i) + touch_map_[i] = TouchDeviceTransform(); + for (TouchscreenDevice& touchscreen_device : touchscreen_devices_) + touchscreen_device.target_display_id = display::kInvalidDisplayId; } -bool DeviceDataManager::IsTouchDeviceIdValid( - int touch_device_id) const { - return (touch_device_id > 0 && touch_device_id < kMaxDeviceNum); -} +void DeviceDataManager::UpdateTouchInfoFromTransform( + const ui::TouchDeviceTransform& touch_device_transform) { + if (!IsTouchDeviceIdValid(touch_device_transform.device_id)) + return; -void DeviceDataManager::UpdateTouchInfoForDisplay( - int64_t target_display_id, - int touch_device_id, - const gfx::Transform& touch_transformer) { - if (IsTouchDeviceIdValid(touch_device_id)) { - touch_map_[touch_device_id].target_display = target_display_id; - touch_map_[touch_device_id].device_transform = touch_transformer; + touch_map_[touch_device_transform.device_id] = touch_device_transform; + + for (TouchscreenDevice& touchscreen_device : touchscreen_devices_) { + if (touchscreen_device.id == touch_device_transform.device_id) { + touchscreen_device.target_display_id = touch_device_transform.display_id; + return; + } } } -void DeviceDataManager::UpdateTouchRadiusScale(int touch_device_id, - double scale) { - if (IsTouchDeviceIdValid(touch_device_id)) - touch_map_[touch_device_id].radius_scale = scale; +bool DeviceDataManager::IsTouchDeviceIdValid(int touch_device_id) const { + return (touch_device_id > 0 && touch_device_id < kMaxDeviceNum); } void DeviceDataManager::ApplyTouchRadiusScale(int touch_device_id, @@ -127,7 +125,7 @@ float* y) { if (IsTouchDeviceIdValid(touch_device_id)) { gfx::Point3F point(*x, *y, 0.0); - const gfx::Transform& trans = touch_map_[touch_device_id].device_transform; + const gfx::Transform& trans = touch_map_[touch_device_id].transform; trans.TransformPoint(&point); *x = point.x(); *y = point.y(); @@ -158,7 +156,7 @@ int64_t DeviceDataManager::GetTargetDisplayForTouchDevice( int touch_device_id) const { if (IsTouchDeviceIdValid(touch_device_id)) - return touch_map_[touch_device_id].target_display; + return touch_map_[touch_device_id].display_id; return display::kInvalidDisplayId; } @@ -172,6 +170,10 @@ return; } touchscreen_devices_ = devices; + for (TouchscreenDevice& touchscreen_device : touchscreen_devices_) { + touchscreen_device.target_display_id = + GetTargetDisplayForTouchDevice(touchscreen_device.id); + } NotifyObserversTouchscreenDeviceConfigurationChanged(); }
diff --git a/ui/events/devices/device_data_manager.h b/ui/events/devices/device_data_manager.h index 01e62aa..bcda9b48 100644 --- a/ui/events/devices/device_data_manager.h +++ b/ui/events/devices/device_data_manager.h
@@ -16,8 +16,8 @@ #include "ui/events/devices/device_hotplug_event_observer.h" #include "ui/events/devices/events_devices_export.h" #include "ui/events/devices/input_device_manager.h" +#include "ui/events/devices/touch_device_transform.h" #include "ui/events/devices/touchscreen_device.h" -#include "ui/gfx/transform.h" namespace ui { @@ -40,16 +40,16 @@ static DeviceDataManager* GetInstance(); static bool HasInstance(); - void ClearTouchDeviceAssociations(); - void UpdateTouchInfoForDisplay(int64_t target_display_id, - int touch_device_id, - const gfx::Transform& touch_transformer); + // Configures the touch devices. |transforms| contains the transform for each + // device and display pair. + void ConfigureTouchDevices( + const std::vector<ui::TouchDeviceTransform>& transforms); + void ApplyTouchTransformer(int touch_device_id, float* x, float* y); // Gets the display that touches from |touch_device_id| should be sent to. int64_t GetTargetDisplayForTouchDevice(int touch_device_id) const; - void UpdateTouchRadiusScale(int touch_device_id, double scale); void ApplyTouchRadiusScale(int touch_device_id, double* radius); void SetTouchscreensEnabled(bool enabled); @@ -85,20 +85,11 @@ void OnStylusStateChanged(StylusState state) override; private: - // Information related to a touchscreen device. - struct TouchscreenInfo { - TouchscreenInfo(); - void Reset(); - - double radius_scale; - int64_t target_display; - gfx::Transform device_transform; - }; - friend class test::DeviceDataManagerTestAPI; - static DeviceDataManager* instance_; - + void ClearTouchDeviceAssociations(); + void UpdateTouchInfoFromTransform( + const ui::TouchDeviceTransform& touch_device_transform); bool IsTouchDeviceIdValid(int touch_device_id) const; void NotifyObserversTouchscreenDeviceConfigurationChanged(); @@ -108,6 +99,8 @@ void NotifyObserversDeviceListsComplete(); void NotifyObserversStylusStateChanged(StylusState stylus_state); + static DeviceDataManager* instance_; + std::vector<TouchscreenDevice> touchscreen_devices_; std::vector<InputDevice> keyboard_devices_; std::vector<InputDevice> mouse_devices_; @@ -121,7 +114,7 @@ // Contains touchscreen device info for each device mapped by device ID. Will // have default values if the device with corresponding ID isn't a touchscreen // or doesn't exist. - std::array<TouchscreenInfo, kMaxDeviceNum> touch_map_; + std::array<TouchDeviceTransform, kMaxDeviceNum> touch_map_; DISALLOW_COPY_AND_ASSIGN(DeviceDataManager); };
diff --git a/ui/events/devices/device_data_manager_unittest.cc b/ui/events/devices/device_data_manager_unittest.cc new file mode 100644 index 0000000..3743a91 --- /dev/null +++ b/ui/events/devices/device_data_manager_unittest.cc
@@ -0,0 +1,54 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/events/devices/device_data_manager.h" + +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/display/types/display_constants.h" +#include "ui/events/devices/device_hotplug_event_observer.h" +#include "ui/events/devices/input_device.h" +#include "ui/events/devices/input_device_event_observer.h" +#include "ui/events/devices/touch_device_transform.h" +#include "ui/events/devices/touchscreen_device.h" +#include "ui/events/test/device_data_manager_test_api.h" +#include "ui/gfx/transform.h" + +namespace ui { + +class DeviceDataManagerTest : public testing::Test { + public: + DeviceDataManagerTest() {} + ~DeviceDataManagerTest() override {} + + // testing::Test: + void SetUp() override { DeviceDataManager::CreateInstance(); } + void TearDown() override { DeviceDataManager::DeleteInstance(); } + + private: + DISALLOW_COPY_AND_ASSIGN(DeviceDataManagerTest); +}; + +TEST_F(DeviceDataManagerTest, DisplayIdUpdated) { + DeviceDataManager* device_data_manager = DeviceDataManager::GetInstance(); + std::vector<TouchscreenDevice> touchscreen_devices(1); + // Default id is invalid, need something other than 0 (0 is invalid). + constexpr int kTouchId = 1; + touchscreen_devices[0].id = kTouchId; + static_cast<DeviceHotplugEventObserver*>(device_data_manager) + ->OnTouchscreenDevicesUpdated(touchscreen_devices); + ASSERT_EQ(1u, device_data_manager->GetTouchscreenDevices().size()); + EXPECT_EQ(display::kInvalidDisplayId, + device_data_manager->GetTouchscreenDevices()[0].target_display_id); + + constexpr int64_t kDisplayId = 2; + std::vector<TouchDeviceTransform> touch_device_transforms(1); + touch_device_transforms[0].display_id = kDisplayId; + touch_device_transforms[0].device_id = kTouchId; + device_data_manager->ConfigureTouchDevices(touch_device_transforms); + ASSERT_EQ(1u, device_data_manager->GetTouchscreenDevices().size()); + EXPECT_EQ(kDisplayId, + device_data_manager->GetTouchscreenDevices()[0].target_display_id); +} + +} // namespace ui
diff --git a/ui/events/devices/mojo/BUILD.gn b/ui/events/devices/mojo/BUILD.gn index fe65d7d1..ee7bc48 100644 --- a/ui/events/devices/mojo/BUILD.gn +++ b/ui/events/devices/mojo/BUILD.gn
@@ -7,10 +7,12 @@ mojom("mojo") { sources = [ "input_devices.mojom", + "touch_device_transform.mojom", ] public_deps = [ "//ui/gfx/geometry/mojo", + "//ui/gfx/mojo", ] }
diff --git a/ui/events/devices/mojo/OWNERS b/ui/events/devices/mojo/OWNERS index 1841ff61..e75daf74 100644 --- a/ui/events/devices/mojo/OWNERS +++ b/ui/events/devices/mojo/OWNERS
@@ -3,3 +3,6 @@ per-file *.mojom=set noparent per-file *.mojom=file://ipc/SECURITY_OWNERS + +per-file *.typemap=set noparent +per-file *.typemap=file://ipc/SECURITY_OWNERS
diff --git a/ui/events/devices/mojo/touch_device_transform.mojom b/ui/events/devices/mojo/touch_device_transform.mojom new file mode 100644 index 0000000..5b8e9c2 --- /dev/null +++ b/ui/events/devices/mojo/touch_device_transform.mojom
@@ -0,0 +1,14 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +module ui.mojom; + +import "ui/gfx/mojo/transform.mojom"; + +struct TouchDeviceTransform { + int64 display_id; + int32 device_id; + gfx.mojom.Transform transform; + double radius_scale; +};
diff --git a/ui/events/devices/mojo/touch_device_transform.typemap b/ui/events/devices/mojo/touch_device_transform.typemap new file mode 100644 index 0000000..689eb3b --- /dev/null +++ b/ui/events/devices/mojo/touch_device_transform.typemap
@@ -0,0 +1,14 @@ +# Copyright 2017 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +mojom = "//ui/events/devices/mojo/touch_device_transform.mojom" +public_headers = [ "//ui/events/devices/touch_device_transform.h" ] +traits_headers = + [ "//ui/events/devices/mojo/touch_device_transform_struct_traits.h" ] +deps = [] +public_deps = [ + "//ui/gfx", + "//ui/gfx/mojo", +] +type_mappings = [ "ui.mojom.TouchDeviceTransform=ui::TouchDeviceTransform" ]
diff --git a/ui/events/devices/mojo/touch_device_transform_struct_traits.h b/ui/events/devices/mojo/touch_device_transform_struct_traits.h new file mode 100644 index 0000000..b9dd450 --- /dev/null +++ b/ui/events/devices/mojo/touch_device_transform_struct_traits.h
@@ -0,0 +1,46 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_DISPLAY_MANAGER_CHROMEOS_MOJO_TOUCH_DEVICE_TRANSFORM_STRUCT_TRAITS_H_ +#define UI_DISPLAY_MANAGER_CHROMEOS_MOJO_TOUCH_DEVICE_TRANSFORM_STRUCT_TRAITS_H_ + +#include <stdint.h> + +#include "ui/events/devices/mojo/touch_device_transform.mojom.h" +#include "ui/events/devices/touch_device_transform.h" +#include "ui/gfx/mojo/transform_struct_traits.h" + +namespace mojo { + +template <> +struct StructTraits<ui::mojom::TouchDeviceTransformDataView, + ui::TouchDeviceTransform> { + public: + static int64_t display_id(const ui::TouchDeviceTransform& r) { + return r.display_id; + } + static int32_t device_id(const ui::TouchDeviceTransform& r) { + return r.device_id; + } + static const gfx::Transform& transform(const ui::TouchDeviceTransform& r) { + return r.transform; + } + static double radius_scale(const ui::TouchDeviceTransform& r) { + return r.radius_scale; + } + + static bool Read(ui::mojom::TouchDeviceTransformDataView data, + ui::TouchDeviceTransform* out) { + out->display_id = data.display_id(); + out->device_id = data.device_id(); + if (!data.ReadTransform(&(out->transform))) + return false; + out->radius_scale = data.radius_scale(); + return true; + } +}; + +} // namespace mojo + +#endif // UI_DISPLAY_MANAGER_CHROMEOS_MOJO_TOUCH_DEVICE_TRANSFORM_STRUCT_TRAITS_H_
diff --git a/ui/events/devices/mojo/touch_device_transform_struct_traits_unittest.cc b/ui/events/devices/mojo/touch_device_transform_struct_traits_unittest.cc new file mode 100644 index 0000000..c9453d5c --- /dev/null +++ b/ui/events/devices/mojo/touch_device_transform_struct_traits_unittest.cc
@@ -0,0 +1,30 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/events/devices/mojo/touch_device_transform_struct_traits.h" + +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/events/devices/mojo/touch_device_transform.mojom.h" +#include "ui/events/devices/touch_device_transform.h" + +namespace ui { + +TEST(TouchDeviceTransformStructTraitsTest, SerializeAndDeserialize) { + TouchDeviceTransform touch_device_transform; + touch_device_transform.display_id = 101; + touch_device_transform.device_id = 202; + touch_device_transform.transform = + gfx::Transform(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); + touch_device_transform.radius_scale = 4; + TouchDeviceTransform deserialized; + ASSERT_TRUE(mojom::TouchDeviceTransform::Deserialize( + mojom::TouchDeviceTransform::Serialize(&touch_device_transform), + &deserialized)); + EXPECT_EQ(touch_device_transform.display_id, deserialized.display_id); + EXPECT_EQ(touch_device_transform.device_id, deserialized.device_id); + EXPECT_EQ(touch_device_transform.transform, deserialized.transform); + EXPECT_EQ(touch_device_transform.radius_scale, deserialized.radius_scale); +} + +} // namespace ui
diff --git a/ui/events/devices/mojo/typemaps.gni b/ui/events/devices/mojo/typemaps.gni index 7ce719a..727e53f 100644 --- a/ui/events/devices/mojo/typemaps.gni +++ b/ui/events/devices/mojo/typemaps.gni
@@ -2,4 +2,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -typemaps = [ "//ui/events/devices/mojo/input_device.typemap" ] +typemaps = [ + "//ui/events/devices/mojo/input_device.typemap", + "//ui/events/devices/mojo/touch_device_transform.typemap", +]
diff --git a/ui/events/devices/touch_device_transform.cc b/ui/events/devices/touch_device_transform.cc new file mode 100644 index 0000000..dd8c410 --- /dev/null +++ b/ui/events/devices/touch_device_transform.cc
@@ -0,0 +1,13 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/events/devices/touch_device_transform.h" + +namespace ui { + +TouchDeviceTransform::TouchDeviceTransform() = default; + +TouchDeviceTransform::~TouchDeviceTransform() = default; + +} // namespace ui
diff --git a/ui/events/devices/touch_device_transform.h b/ui/events/devices/touch_device_transform.h new file mode 100644 index 0000000..767fe50b --- /dev/null +++ b/ui/events/devices/touch_device_transform.h
@@ -0,0 +1,30 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_EVENTS_DEVICES_TOUCH_DEVICE_TRANSFORM_H_ +#define UI_EVENTS_DEVICES_TOUCH_DEVICE_TRANSFORM_H_ + +#include <stdint.h> + +#include "ui/display/types/display_constants.h" +#include "ui/events/devices/events_devices_export.h" +#include "ui/events/devices/input_device.h" +#include "ui/gfx/transform.h" + +namespace ui { + +struct EVENTS_DEVICES_EXPORT TouchDeviceTransform { + TouchDeviceTransform(); + ~TouchDeviceTransform(); + + int64_t display_id = display::kInvalidDisplayId; + int32_t device_id = InputDevice::kInvalidId; + gfx::Transform transform; + // Amount to scale the touch radius by. + double radius_scale = 1; +}; + +} // namespace ui + +#endif // UI_EVENTS_DEVICES_TOUCH_DEVICE_TRANSFORM_H_
diff --git a/ui/events/devices/touchscreen_device.cc b/ui/events/devices/touchscreen_device.cc index b840b96..3c2a4a6 100644 --- a/ui/events/devices/touchscreen_device.cc +++ b/ui/events/devices/touchscreen_device.cc
@@ -10,27 +10,19 @@ namespace ui { -TouchscreenDevice::TouchscreenDevice() : touch_points(0), is_stylus(false) {} +TouchscreenDevice::TouchscreenDevice() : touch_points(0) {} TouchscreenDevice::TouchscreenDevice(int id, InputDeviceType type, const std::string& name, const gfx::Size& size, int touch_points) - : InputDevice(id, type, name), - size(size), - touch_points(touch_points), - is_stylus(false) { -} + : InputDevice(id, type, name), size(size), touch_points(touch_points) {} TouchscreenDevice::TouchscreenDevice(const InputDevice& input_device, const gfx::Size& size, int touch_points) - : InputDevice(input_device), - size(size), - touch_points(touch_points), - is_stylus(false) { -} + : InputDevice(input_device), size(size), touch_points(touch_points) {} TouchscreenDevice::~TouchscreenDevice() {}
diff --git a/ui/events/devices/touchscreen_device.h b/ui/events/devices/touchscreen_device.h index ee024a0..3fca42b9 100644 --- a/ui/events/devices/touchscreen_device.h +++ b/ui/events/devices/touchscreen_device.h
@@ -5,8 +5,11 @@ #ifndef UI_EVENTS_DEVICES_TOUCHSCREEN_DEVICE_H_ #define UI_EVENTS_DEVICES_TOUCHSCREEN_DEVICE_H_ +#include <stdint.h> + #include <string> +#include "ui/display/types/display_constants.h" #include "ui/events/devices/events_devices_export.h" #include "ui/events/devices/input_device.h" #include "ui/gfx/geometry/size.h" @@ -33,8 +36,10 @@ gfx::Size size; // Size of the touch screen area. int touch_points; // The number of touch points this device supports (0 if // unknown). - bool is_stylus; // True if the specified touchscreen device is stylus - // capable. + // True if the specified touchscreen device is stylus capable. + bool is_stylus = false; + // Id of the display the touch device targets. + int64_t target_display_id = display::kInvalidDisplayId; }; } // namespace ui
diff --git a/ui/events/gestures/blink/web_gesture_curve_impl.h b/ui/events/gestures/blink/web_gesture_curve_impl.h index 6ad113a7..ecadeeb 100644 --- a/ui/events/gestures/blink/web_gesture_curve_impl.h +++ b/ui/events/gestures/blink/web_gesture_curve_impl.h
@@ -22,7 +22,7 @@ namespace ui { class GestureCurve; -class WebGestureCurveImpl : public NON_EXPORTED_BASE(blink::WebGestureCurve) { +class WebGestureCurveImpl : public blink::WebGestureCurve { public: static std::unique_ptr<blink::WebGestureCurve> CreateFromDefaultPlatformCurve( blink::WebGestureDevice device_source,
diff --git a/ui/events/test/device_data_manager_test_api.h b/ui/events/test/device_data_manager_test_api.h index 92d26a3..9eb2443b 100644 --- a/ui/events/test/device_data_manager_test_api.h +++ b/ui/events/test/device_data_manager_test_api.h
@@ -11,6 +11,10 @@ #include "base/macros.h" #include "ui/events/devices/events_devices_export.h" +namespace gfx { +class Transform; +} + namespace ui { class DeviceDataManager; @@ -44,6 +48,10 @@ void SetMouseDevices(const std::vector<InputDevice>& devices); void SetTouchpadDevices(const std::vector<InputDevice>& devices); + void UpdateTouchInfoForDisplay(int64_t target_display_id, + int touch_device_id, + const gfx::Transform& touch_transformer); + private: DISALLOW_COPY_AND_ASSIGN(DeviceDataManagerTestAPI); };
diff --git a/ui/events/test/device_data_manager_test_api_impl.cc b/ui/events/test/device_data_manager_test_api_impl.cc index 58fbde5..a037280e 100644 --- a/ui/events/test/device_data_manager_test_api_impl.cc +++ b/ui/events/test/device_data_manager_test_api_impl.cc
@@ -5,6 +5,7 @@ #include "ui/events/test/device_data_manager_test_api.h" #include "ui/events/devices/device_data_manager.h" +#include "ui/gfx/transform.h" namespace ui { namespace test {
diff --git a/ui/file_manager/file_manager/foreground/js/main_window_component.js b/ui/file_manager/file_manager/foreground/js/main_window_component.js index f72d1d5..2aaa024 100644 --- a/ui/file_manager/file_manager/foreground/js/main_window_component.js +++ b/ui/file_manager/file_manager/foreground/js/main_window_component.js
@@ -169,6 +169,11 @@ // TODO(yamaguchi): Revise TapHandler.handleTouchEvents to delete the param. this.tapHandler_.handleTouchEvents(event, -1, function(e, index, eventType) { if (eventType == FileTapHandler.TapEvent.TAP) { + if (e.target.classList.contains('detail-checkmark')) { + // Tap on the checkmark should only toggle select the item just like a + // mouse click on it. + return false; + } // The selection model has the single selection at this point. // When using touchscreen, the selection should be cleared because // we don't want show the file selected when not in check-select
diff --git a/ui/file_manager/file_manager/foreground/js/ui/file_table_list.js b/ui/file_manager/file_manager/foreground/js/ui/file_table_list.js index 471a762..fda2bfa 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/file_table_list.js +++ b/ui/file_manager/file_manager/foreground/js/ui/file_table_list.js
@@ -237,6 +237,12 @@ (this.selectionModel); var isTap = eventType == FileTapHandler.TapEvent.TAP || eventType == FileTapHandler.TapEvent.LONG_TAP; + if (eventType == FileTapHandler.TapEvent.TAP && + e.target.classList.contains('detail-checkmark')) { + // Single tap on the checkbox in the list view mode should toggle select, + // just like a mouse click on it. + return false; + } if (sm.multiple && sm.getCheckSelectMode() && isTap && !e.shiftKey) { // toggle item selection. Equivalent to mouse click on checkbox. sm.beginChange(); @@ -246,7 +252,7 @@ sm.anchorIndex = index; sm.endChange(); return true; - } else if (sm.multiple && eventType == FileTapHandler.TapEvent.LONG_PRESS) { + } else if (sm.multiple && (eventType == FileTapHandler.TapEvent.LONG_PRESS)) { sm.beginChange(); if (!sm.getCheckSelectMode()) { // Make sure to unselect the leading item that was not the touch target.
diff --git a/ui/gfx/BUILD.gn b/ui/gfx/BUILD.gn index 3e49b15..1f0e9d3 100644 --- a/ui/gfx/BUILD.gn +++ b/ui/gfx/BUILD.gn
@@ -536,8 +536,6 @@ sources += [ "gpu_memory_buffer.cc", "gpu_memory_buffer.h", - "gpu_memory_buffer_tracing.cc", - "gpu_memory_buffer_tracing.h", ] }
diff --git a/ui/gfx/gpu_memory_buffer_tracing.cc b/ui/gfx/gpu_memory_buffer_tracing.cc deleted file mode 100644 index 5f587074..0000000 --- a/ui/gfx/gpu_memory_buffer_tracing.cc +++ /dev/null
@@ -1,21 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/gfx/gpu_memory_buffer_tracing.h" - -#include "base/format_macros.h" -#include "base/strings/stringprintf.h" - -namespace gfx { - -base::trace_event::MemoryAllocatorDumpGuid GetSharedMemoryGUIDForTracing( - uint64_t tracing_process_id, - GpuMemoryBufferId buffer_id) { - // TODO(hajimehoshi): This should be unified to shared memory GUIDs in - // base/memory/shared_memory_tracker.cc - return base::trace_event::MemoryAllocatorDumpGuid(base::StringPrintf( - "shared_memory_gpu/%" PRIx64 "/%d", tracing_process_id, buffer_id.id)); -} - -} // namespace gfx
diff --git a/ui/gfx/gpu_memory_buffer_tracing.h b/ui/gfx/gpu_memory_buffer_tracing.h deleted file mode 100644 index 0b66a91a..0000000 --- a/ui/gfx/gpu_memory_buffer_tracing.h +++ /dev/null
@@ -1,15 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/trace_event/memory_allocator_dump_guid.h" -#include "ui/gfx/gfx_export.h" -#include "ui/gfx/gpu_memory_buffer.h" - -namespace gfx { - -base::trace_event::MemoryAllocatorDumpGuid GFX_EXPORT -GetSharedMemoryGUIDForTracing(uint64_t tracing_process_id, - GpuMemoryBufferId buffer_id); - -} // namespace gfx
diff --git a/ui/gfx/image/image.cc b/ui/gfx/image/image.cc index 7b4d93cf..7b49776f 100644 --- a/ui/gfx/image/image.cc +++ b/ui/gfx/image/image.cc
@@ -248,23 +248,23 @@ } Image::RepresentationType default_representation_type() const { - DCHECK(thread_checking_disabled() || IsOnValidSequence()); + DCHECK(IsOnValidSequence()); return default_representation_type_; } bool HasRepresentation(Image::RepresentationType type) const { - DCHECK(thread_checking_disabled() || IsOnValidSequence()); + DCHECK(IsOnValidSequence()); return representations_.count(type) != 0; } size_t RepresentationCount() const { - DCHECK(thread_checking_disabled() || IsOnValidSequence()); + DCHECK(IsOnValidSequence()); return representations_.size(); } const ImageRep* GetRepresentation(Image::RepresentationType rep_type, bool must_exist) const { - DCHECK(thread_checking_disabled() || IsOnValidSequence()); + DCHECK(IsOnValidSequence()); RepresentationMap::const_iterator it = representations_.find(rep_type); if (it == representations_.end()) { CHECK(!must_exist); @@ -274,7 +274,7 @@ } const ImageRep* AddRepresentation(std::unique_ptr<ImageRep> rep) const { - DCHECK(thread_checking_disabled() || IsOnValidSequence()); + DCHECK(IsOnValidSequence()); Image::RepresentationType type = rep->type(); auto result = representations_.insert(std::make_pair(type, std::move(rep))); @@ -287,35 +287,20 @@ #if defined(OS_MACOSX) && !defined(OS_IOS) void set_default_representation_color_space(CGColorSpaceRef color_space) { - DCHECK(thread_checking_disabled() || IsOnValidSequence()); + DCHECK(IsOnValidSequence()); default_representation_color_space_ = color_space; } CGColorSpaceRef default_representation_color_space() const { - DCHECK(thread_checking_disabled() || IsOnValidSequence()); + DCHECK(IsOnValidSequence()); return default_representation_color_space_; } #endif // defined(OS_MACOSX) && !defined(OS_IOS) - void DisableThreadChecking() { - DCHECK(thread_checking_disabled() || IsOnValidSequence()); -#if DCHECK_IS_ON() - thread_checking_disabled_ = true; -#endif - } - private: friend class base::RefCounted<ImageStorage>; ~ImageStorage() {} - bool thread_checking_disabled() const { -#if DCHECK_IS_ON() - return thread_checking_disabled_; -#else - return true; -#endif - } - // The type of image that was passed to the constructor. This key will always // exist in the |representations_| map. Image::RepresentationType default_representation_type_; @@ -332,10 +317,6 @@ // more for any converted representations. mutable RepresentationMap representations_; -#if DCHECK_IS_ON() - bool thread_checking_disabled_ = false; -#endif - DISALLOW_COPY_AND_ASSIGN(ImageStorage); }; @@ -676,10 +657,6 @@ } #endif // defined(OS_MACOSX) && !defined(OS_IOS) -void Image::DisableThreadChecking() { - storage_->DisableThreadChecking(); -} - Image::RepresentationType Image::DefaultRepresentationType() const { CHECK(storage()); return storage()->default_representation_type();
diff --git a/ui/gfx/image/image.h b/ui/gfx/image/image.h index 908547d..f0d6cbb 100644 --- a/ui/gfx/image/image.h +++ b/ui/gfx/image/image.h
@@ -181,13 +181,6 @@ void SetSourceColorSpace(CGColorSpaceRef color_space); #endif // defined(OS_MACOSX) && !defined(OS_IOS) - // Turns off thread checking on this Image (and all Images sharing its backing - // store). This should be used to mark code that is not currently thread-safe - // and any usage of this method should be considered a bug and accompanied by - // a TODO. - // TODO(mgiuca): Remove this method after all uses of Image are thread-safe. - void DisableThreadChecking(); - private: // Returns the type of the default representation. RepresentationType DefaultRepresentationType() const;
diff --git a/ui/gfx/image/image_family.cc b/ui/gfx/image/image_family.cc index 7eb39c1..0adc66923 100644 --- a/ui/gfx/image/image_family.cc +++ b/ui/gfx/image/image_family.cc
@@ -145,11 +145,6 @@ return CreateExact(size.width(), size.height()); } -void ImageFamily::DisableThreadChecking() { - for (auto& item : map_) - item.second.DisableThreadChecking(); -} - const gfx::Image* ImageFamily::GetWithExactAspect(float aspect, int width) const { // Find the two images of given aspect ratio on either side of |width|.
diff --git a/ui/gfx/image/image_family.h b/ui/gfx/image/image_family.h index dff2dee..3d0890a4 100644 --- a/ui/gfx/image/image_family.h +++ b/ui/gfx/image/image_family.h
@@ -154,9 +154,6 @@ // desired size. If there are no images in the family, returns an empty image. gfx::Image CreateExact(const gfx::Size& size) const; - // Calls DisableThreadChecking() on all images. - void DisableThreadChecking(); - private: // Find the closest aspect ratio in the map to |desired_aspect|. // Ties are broken by the thinner aspect.
diff --git a/ui/gfx/mojo/BUILD.gn b/ui/gfx/mojo/BUILD.gn index 9722968c..b71ee25 100644 --- a/ui/gfx/mojo/BUILD.gn +++ b/ui/gfx/mojo/BUILD.gn
@@ -29,15 +29,3 @@ ":mojo", ] } - -source_set("struct_traits") { - sources = [ - "selection_bound_struct_traits.h", - "transform_struct_traits.h", - ] - public_deps = [ - ":mojo_shared_cpp_sources", - "//mojo/public/cpp/bindings", - "//ui/gfx", - ] -}
diff --git a/ui/gfx/mojo/selection_bound.typemap b/ui/gfx/mojo/selection_bound.typemap index d188a3a..e2b16f7 100644 --- a/ui/gfx/mojo/selection_bound.typemap +++ b/ui/gfx/mojo/selection_bound.typemap
@@ -5,7 +5,4 @@ mojom = "//ui/gfx/mojo/selection_bound.mojom" public_headers = [ "//ui/gfx/selection_bound.h" ] traits_headers = [ "//ui/gfx/mojo/selection_bound_struct_traits.h" ] -deps = [ - "//ui/gfx/mojo:struct_traits", -] type_mappings = [ "gfx.mojom.SelectionBound=gfx::SelectionBound" ]
diff --git a/ui/gfx/mojo/transform.typemap b/ui/gfx/mojo/transform.typemap index 28da309..b675c8f 100644 --- a/ui/gfx/mojo/transform.typemap +++ b/ui/gfx/mojo/transform.typemap
@@ -5,7 +5,4 @@ mojom = "//ui/gfx/mojo/transform.mojom" public_headers = [ "//ui/gfx/transform.h" ] traits_headers = [ "//ui/gfx/mojo/transform_struct_traits.h" ] -deps = [ - "//ui/gfx/mojo:struct_traits", -] type_mappings = [ "gfx.mojom.Transform=gfx::Transform" ]
diff --git a/ui/gl/gl_image_shared_memory.cc b/ui/gl/gl_image_shared_memory.cc index cef422b4..3b832c9e 100644 --- a/ui/gl/gl_image_shared_memory.cc +++ b/ui/gl/gl_image_shared_memory.cc
@@ -13,7 +13,6 @@ #include "base/trace_event/memory_dump_manager.h" #include "base/trace_event/process_memory_dump.h" #include "ui/gfx/buffer_format_util.h" -#include "ui/gfx/gpu_memory_buffer_tracing.h" namespace gl { @@ -87,11 +86,9 @@ base::trace_event::MemoryAllocatorDump::kUnitsBytes, static_cast<uint64_t>(size_in_bytes)); - auto guid = - gfx::GetSharedMemoryGUIDForTracing(process_tracing_id, shared_memory_id_); auto shared_memory_guid = shared_memory_->mapped_id(); if (!shared_memory_guid.is_empty()) { - pmd->CreateSharedMemoryOwnershipEdge(dump->guid(), guid, shared_memory_guid, + pmd->CreateSharedMemoryOwnershipEdge(dump->guid(), shared_memory_guid, 0 /* importance */); } }
diff --git a/ui/message_center/views/notification_header_view.cc b/ui/message_center/views/notification_header_view.cc index 0c3cb8b8..931589152 100644 --- a/ui/message_center/views/notification_header_view.cc +++ b/ui/message_center/views/notification_header_view.cc
@@ -8,6 +8,7 @@ #include "base/strings/string_number_conversions.h" #include "base/strings/utf_string_conversions.h" #include "base/time/time.h" +#include "ui/accessibility/ax_node_data.h" #include "ui/base/l10n/l10n_util.h" #include "ui/gfx/color_palette.h" #include "ui/gfx/font_list.h" @@ -59,9 +60,11 @@ ExpandButton(); ~ExpandButton() override; + // Overridden from views::ImageView: void OnPaint(gfx::Canvas* canvas) override; void OnFocus() override; void OnBlur() override; + void GetAccessibleNodeData(ui::AXNodeData* node_data) override; private: std::unique_ptr<views::Painter> focus_painter_; @@ -90,6 +93,11 @@ SchedulePaint(); } +void ExpandButton::GetAccessibleNodeData(ui::AXNodeData* node_data) { + node_data->role = ui::AX_ROLE_BUTTON; + node_data->SetName(views::ImageView::GetTooltipText()); +} + // Do relative time string formatting that is similar to // com.java.android.widget.DateTimeView.updateRelativeTime. // Chromium has its own base::TimeFormat::Simple(), but none of the formats @@ -278,6 +286,10 @@ expand_button_->SetImage(gfx::CreateVectorIcon( expanded ? kNotificationExpandLessIcon : kNotificationExpandMoreIcon, kExpandIconSize, accent_color_)); + // TODO(tetsui): Replace by more helpful accessibility strings. + // https://crbug.com/755855 + expand_button_->SetTooltipText(l10n_util::GetStringUTF16( + expanded ? IDS_APP_ACCNAME_MINIMIZE : IDS_APP_ACCNAME_MAXIMIZE)); } void NotificationHeaderView::SetAccentColor(SkColor color) {
diff --git a/ui/message_center/views/notification_header_view.h b/ui/message_center/views/notification_header_view.h index 73c6f79..201fca2 100644 --- a/ui/message_center/views/notification_header_view.h +++ b/ui/message_center/views/notification_header_view.h
@@ -51,6 +51,8 @@ views::ImageView* expand_button() { return expand_button_; } + SkColor accent_color_for_testing() { return accent_color_; } + private: // Update visibility for both |summary_text_view_| and |timestamp_view_|. void UpdateSummaryTextVisibility();
diff --git a/ui/message_center/views/notification_view.cc b/ui/message_center/views/notification_view.cc index 0a1ad48..9e00b5e2 100644 --- a/ui/message_center/views/notification_view.cc +++ b/ui/message_center/views/notification_view.cc
@@ -289,6 +289,7 @@ // Top views. int top_height = top_view_->GetHeightForWidth(content_width); top_view_->SetBounds(insets.left(), insets.top(), content_width, top_height); + ShrinkTopmostLabel(); // Icon. icon_view_->SetBounds(insets.left(), insets.top(), kNotificationIconSize, @@ -340,10 +341,6 @@ return views::GetNativeHandCursor(); } -void NotificationView::OnMouseMoved(const ui::MouseEvent& event) { - MessageView::OnMouseMoved(event); - UpdateControlButtonsVisibility(); -} void NotificationView::OnMouseEntered(const ui::MouseEvent& event) { MessageView::OnMouseEntered(event); @@ -722,4 +719,18 @@ message_view_->GetSizeForWidthAndLines(width, limit).height() : 0; } +void NotificationView::ShrinkTopmostLabel() { +// Reduce width of the topmost label not to be covered by the control buttons +// only on non Chrome OS platform. +#if !defined(OS_CHROMEOS) + const int content_width = width() - GetInsets().width(); + const int buttons_width = control_buttons_view_->GetPreferredSize().width(); + if (top_view_->child_count() > 0) { + gfx::Rect bounds = top_view_->child_at(0)->bounds(); + bounds.set_width(content_width - buttons_width); + top_view_->child_at(0)->SetBoundsRect(bounds); + } +#endif +} + } // namespace message_center
diff --git a/ui/message_center/views/notification_view.h b/ui/message_center/views/notification_view.h index 23e1850..47e8eb68 100644 --- a/ui/message_center/views/notification_view.h +++ b/ui/message_center/views/notification_view.h
@@ -47,7 +47,6 @@ void OnFocus() override; void ScrollRectToVisible(const gfx::Rect& rect) override; gfx::NativeCursor GetCursor(const ui::MouseEvent& event) override; - void OnMouseMoved(const ui::MouseEvent& event) override; void OnMouseEntered(const ui::MouseEvent& event) override; void OnMouseExited(const ui::MouseEvent& event) override; @@ -99,6 +98,9 @@ // notification. base::string16 FormatContextMessage(const Notification& notification) const; + // Shrink the topmost label not to be covered by the control button. + void ShrinkTopmostLabel(); + // Describes whether the view should display a hand pointer or not. bool clickable_;
diff --git a/ui/message_center/views/notification_view_md.cc b/ui/message_center/views/notification_view_md.cc index 21eead2..119c587f 100644 --- a/ui/message_center/views/notification_view_md.cc +++ b/ui/message_center/views/notification_view_md.cc
@@ -32,7 +32,6 @@ #include "ui/views/animation/ink_drop_highlight.h" #include "ui/views/background.h" #include "ui/views/border.h" -#include "ui/views/controls/button/label_button.h" #include "ui/views/controls/image_view.h" #include "ui/views/controls/label.h" #include "ui/views/controls/progress_bar.h" @@ -206,61 +205,6 @@ views::View::OnPaint(canvas); } -// NotificationButtonMD //////////////////////////////////////////////////////// - -// This class is needed in addition to LabelButton mainly becuase we want to set -// visible_opacity of InkDropHighlight. -// This button capitalizes the given label string. -class NotificationButtonMD : public views::LabelButton { - public: - NotificationButtonMD(views::ButtonListener* listener, - const base::string16& text); - ~NotificationButtonMD() override; - - void SetText(const base::string16& text) override; - const char* GetClassName() const override; - - std::unique_ptr<views::InkDropHighlight> CreateInkDropHighlight() - const override; - - private: - DISALLOW_COPY_AND_ASSIGN(NotificationButtonMD); -}; - -NotificationButtonMD::NotificationButtonMD(views::ButtonListener* listener, - const base::string16& text) - : views::LabelButton(listener, - base::i18n::ToUpper(text), - views::style::CONTEXT_BUTTON_MD) { - SetHorizontalAlignment(gfx::ALIGN_CENTER); - SetInkDropMode(views::LabelButton::InkDropMode::ON); - set_has_ink_drop_action_on_click(true); - set_ink_drop_base_color(kActionButtonInkDropBaseColor); - set_ink_drop_visible_opacity(kActionButtonInkDropRippleVisibleOpacity); - SetEnabledTextColors(kActionButtonTextColor); - SetBorder(views::CreateEmptyBorder(kActionButtonPadding)); - SetMinSize(kActionButtonMinSize); - SetFocusForPlatform(); -} - -NotificationButtonMD::~NotificationButtonMD() = default; - -void NotificationButtonMD::SetText(const base::string16& text) { - views::LabelButton::SetText(base::i18n::ToUpper(text)); -} - -const char* NotificationButtonMD::GetClassName() const { - return "NotificationButtonMD"; -} - -std::unique_ptr<views::InkDropHighlight> -NotificationButtonMD::CreateInkDropHighlight() const { - std::unique_ptr<views::InkDropHighlight> highlight = - views::LabelButton::CreateInkDropHighlight(); - highlight->set_visible_opacity(kActionButtonInkDropHighlightVisibleOpacity); - return highlight; -} - // LargeImageView ////////////////////////////////////////////////////////////// class LargeImageView : public views::View { @@ -376,6 +320,42 @@ } // anonymous namespace +// NotificationButtonMD //////////////////////////////////////////////////////// + +NotificationButtonMD::NotificationButtonMD(views::ButtonListener* listener, + const base::string16& text) + : views::LabelButton(listener, + base::i18n::ToUpper(text), + views::style::CONTEXT_BUTTON_MD) { + SetHorizontalAlignment(gfx::ALIGN_CENTER); + SetInkDropMode(views::LabelButton::InkDropMode::ON); + set_has_ink_drop_action_on_click(true); + set_ink_drop_base_color(kActionButtonInkDropBaseColor); + set_ink_drop_visible_opacity(kActionButtonInkDropRippleVisibleOpacity); + SetEnabledTextColors(kActionButtonTextColor); + SetBorder(views::CreateEmptyBorder(kActionButtonPadding)); + SetMinSize(kActionButtonMinSize); + SetFocusForPlatform(); +} + +NotificationButtonMD::~NotificationButtonMD() = default; + +void NotificationButtonMD::SetText(const base::string16& text) { + views::LabelButton::SetText(base::i18n::ToUpper(text)); +} + +const char* NotificationButtonMD::GetClassName() const { + return "NotificationButtonMD"; +} + +std::unique_ptr<views::InkDropHighlight> +NotificationButtonMD::CreateInkDropHighlight() const { + std::unique_ptr<views::InkDropHighlight> highlight = + views::LabelButton::CreateInkDropHighlight(); + highlight->set_visible_opacity(kActionButtonInkDropHighlightVisibleOpacity); + return highlight; +} + // //////////////////////////////////////////////////////////// // NotificationViewMD // ////////////////////////////////////////////////////////////
diff --git a/ui/message_center/views/notification_view_md.h b/ui/message_center/views/notification_view_md.h index 34781422..2c8bc6a 100644 --- a/ui/message_center/views/notification_view_md.h +++ b/ui/message_center/views/notification_view_md.h
@@ -12,6 +12,7 @@ #include "ui/message_center/message_center_export.h" #include "ui/message_center/views/message_view.h" #include "ui/views/controls/button/button.h" +#include "ui/views/controls/button/label_button.h" #include "ui/views/view_targeter_delegate.h" namespace views { @@ -32,6 +33,27 @@ class LargeImageContainerView; } +// This class is needed in addition to LabelButton mainly becuase we want to set +// visible_opacity of InkDropHighlight. +// This button capitalizes the given label string. +class NotificationButtonMD : public views::LabelButton { + public: + NotificationButtonMD(views::ButtonListener* listener, + const base::string16& text); + ~NotificationButtonMD() override; + + void SetText(const base::string16& text) override; + const char* GetClassName() const override; + + std::unique_ptr<views::InkDropHighlight> CreateInkDropHighlight() + const override; + + SkColor enabled_color_for_testing() { return label()->enabled_color(); } + + private: + DISALLOW_COPY_AND_ASSIGN(NotificationButtonMD); +}; + // View that displays all current types of notification (web, basic, image, and // list) except the custom notification. Future notification types may be // handled by other classes, in which case instances of those classes would be @@ -70,6 +92,7 @@ FRIEND_TEST_ALL_PREFIXES(NotificationViewMDTest, UpdateButtonsStateTest); FRIEND_TEST_ALL_PREFIXES(NotificationViewMDTest, UpdateButtonCountTest); FRIEND_TEST_ALL_PREFIXES(NotificationViewMDTest, ExpandLongMessage); + FRIEND_TEST_ALL_PREFIXES(NotificationViewMDTest, TestAccentColor); friend class NotificationViewMDTest; @@ -121,7 +144,7 @@ views::Label* status_view_ = nullptr; ProportionalImageView* icon_view_ = nullptr; LargeImageContainerView* image_container_view_ = nullptr; - std::vector<views::LabelButton*> action_buttons_; + std::vector<NotificationButtonMD*> action_buttons_; std::vector<ItemView*> item_views_; views::ProgressBar* progress_bar_view_ = nullptr; CompactTitleMessageView* compact_title_message_view_ = nullptr;
diff --git a/ui/message_center/views/notification_view_md_unittest.cc b/ui/message_center/views/notification_view_md_unittest.cc index 66a3b38..45faa83b 100644 --- a/ui/message_center/views/notification_view_md_unittest.cc +++ b/ui/message_center/views/notification_view_md_unittest.cc
@@ -549,4 +549,42 @@ notification_view()->GetPreferredSize().height()); } +TEST_F(NotificationViewMDTest, TestAccentColor) { + const SkColor kActionButtonTextColor = SkColorSetRGB(0x33, 0x67, 0xD6); + const SkColor kCustomAccentColor = SkColorSetRGB(0xea, 0x61, 0x0); + + notification()->set_buttons(CreateButtons(2)); + UpdateNotificationViews(); + widget()->Show(); + + // Action buttons are hidden by collapsed state. + if (!notification_view()->expanded_) + notification_view()->ToggleExpanded(); + EXPECT_TRUE(notification_view()->actions_row_->visible()); + + // By default, header does not have accent color (default grey), and + // buttons have default accent color. + EXPECT_EQ(message_center::kNotificationDefaultAccentColor, + notification_view()->header_row_->accent_color_for_testing()); + EXPECT_EQ( + kActionButtonTextColor, + notification_view()->action_buttons_[0]->enabled_color_for_testing()); + EXPECT_EQ( + kActionButtonTextColor, + notification_view()->action_buttons_[1]->enabled_color_for_testing()); + + // If custom accent color is set, the header and the buttons should have the + // same accent color. + notification()->set_accent_color(kCustomAccentColor); + UpdateNotificationViews(); + EXPECT_EQ(kCustomAccentColor, + notification_view()->header_row_->accent_color_for_testing()); + EXPECT_EQ( + kCustomAccentColor, + notification_view()->action_buttons_[0]->enabled_color_for_testing()); + EXPECT_EQ( + kCustomAccentColor, + notification_view()->action_buttons_[1]->enabled_color_for_testing()); +} + } // namespace message_center
diff --git a/ui/platform_window/stub/stub_window.h b/ui/platform_window/stub/stub_window.h index 080e945c..b171e0a8 100644 --- a/ui/platform_window/stub/stub_window.h +++ b/ui/platform_window/stub/stub_window.h
@@ -15,7 +15,7 @@ class PlatformWindowDelegate; -class STUB_WINDOW_EXPORT StubWindow : NON_EXPORTED_BASE(public PlatformWindow) { +class STUB_WINDOW_EXPORT StubWindow : public PlatformWindow { public: explicit StubWindow(PlatformWindowDelegate* delegate, bool use_default_accelerated_widget = true,
diff --git a/ui/platform_window/win/win_window.h b/ui/platform_window/win/win_window.h index d91d8086..5e4859c 100644 --- a/ui/platform_window/win/win_window.h +++ b/ui/platform_window/win/win_window.h
@@ -15,7 +15,7 @@ class PlatformWindowDelegate; -class WIN_WINDOW_EXPORT WinWindow : public NON_EXPORTED_BASE(PlatformWindow), +class WIN_WINDOW_EXPORT WinWindow : public PlatformWindow, public gfx::WindowImpl { public: WinWindow(PlatformWindowDelegate* delegate, const gfx::Rect& bounds);
diff --git a/ui/views/bubble/bubble_frame_view_unittest.cc b/ui/views/bubble/bubble_frame_view_unittest.cc index 92072dfe..068b206 100644 --- a/ui/views/bubble/bubble_frame_view_unittest.cc +++ b/ui/views/bubble/bubble_frame_view_unittest.cc
@@ -8,6 +8,7 @@ #include "base/macros.h" #include "build/build_config.h" +#include "ui/base/material_design/material_design_controller.h" #include "ui/gfx/geometry/insets.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/size.h" @@ -26,6 +27,10 @@ namespace { +bool UseMd() { + return ui::MaterialDesignController::IsSecondaryUiMaterial(); +} + const BubbleBorder::Arrow kArrow = BubbleBorder::TOP_LEFT; const SkColor kColor = SK_ColorRED; const int kMargin = 6; @@ -359,15 +364,25 @@ TEST_F(BubbleFrameViewTest, GetUpdatedWindowBoundsCenterArrows) { TestBubbleFrameView frame(this); gfx::Rect window_bounds; + // Bubbles have a thicker shadow on the bottom in MD. + // Match definition of kLargeShadowVerticalOffset in bubble_border.cc. + const int kLargeShadowVerticalOffset = UseMd() ? 2 : 0; + + // Some of these tests may go away once --secondary-ui-md becomes the + // default. Under Material Design mode, the BubbleBorder doesn't support all + // "arrow" positions. If this changes, then the tests should be updated or + // added for MD mode. // Test that the bubble displays normally when it fits. - frame.bubble_border()->set_arrow(BubbleBorder::TOP_CENTER); - window_bounds = frame.GetUpdatedWindowBounds( - gfx::Rect(500, 100, 50, 50), // |anchor_rect| - gfx::Size(500, 500), // |client_size| - true); // |adjust_if_offscreen| - EXPECT_EQ(BubbleBorder::TOP_CENTER, frame.bubble_border()->arrow()); - EXPECT_EQ(window_bounds.x() + window_bounds.width() / 2, 525); + if (!UseMd()) { // TOP_CENTER isn't supported by the bubble_border() in MD. + frame.bubble_border()->set_arrow(BubbleBorder::TOP_CENTER); + window_bounds = frame.GetUpdatedWindowBounds( + gfx::Rect(500, 100, 50, 50), // |anchor_rect| + gfx::Size(500, 500), // |client_size| + true); // |adjust_if_offscreen| + EXPECT_EQ(BubbleBorder::TOP_CENTER, frame.bubble_border()->arrow()); + EXPECT_EQ(window_bounds.x() + window_bounds.width() / 2, 525); + } frame.bubble_border()->set_arrow(BubbleBorder::BOTTOM_CENTER); window_bounds = frame.GetUpdatedWindowBounds( @@ -383,7 +398,8 @@ gfx::Size(500, 500), // |client_size| true); // |adjust_if_offscreen| EXPECT_EQ(BubbleBorder::LEFT_CENTER, frame.bubble_border()->arrow()); - EXPECT_EQ(window_bounds.y() + window_bounds.height() / 2, 425); + EXPECT_EQ(window_bounds.y() + window_bounds.height() / 2, + 425 + kLargeShadowVerticalOffset); frame.bubble_border()->set_arrow(BubbleBorder::RIGHT_CENTER); window_bounds = frame.GetUpdatedWindowBounds( @@ -391,18 +407,22 @@ gfx::Size(500, 500), // |client_size| true); // |adjust_if_offscreen| EXPECT_EQ(BubbleBorder::RIGHT_CENTER, frame.bubble_border()->arrow()); - EXPECT_EQ(window_bounds.y() + window_bounds.height() / 2, 425); + EXPECT_EQ(window_bounds.y() + window_bounds.height() / 2, + 425 + kLargeShadowVerticalOffset); // Test bubble not fitting left screen edge. - frame.bubble_border()->set_arrow(BubbleBorder::TOP_CENTER); - window_bounds = frame.GetUpdatedWindowBounds( - gfx::Rect(100, 100, 50, 50), // |anchor_rect| - gfx::Size(500, 500), // |client_size| - true); // |adjust_if_offscreen| - EXPECT_EQ(BubbleBorder::TOP_CENTER, frame.bubble_border()->arrow()); - EXPECT_EQ(window_bounds.x(), 0); - EXPECT_EQ(window_bounds.x() + - frame.bubble_border()->GetArrowOffset(window_bounds.size()), 125); + if (!UseMd()) { // TOP_CENTER isn't supported by the bubble_border() in MD. + frame.bubble_border()->set_arrow(BubbleBorder::TOP_CENTER); + window_bounds = frame.GetUpdatedWindowBounds( + gfx::Rect(100, 100, 50, 50), // |anchor_rect| + gfx::Size(500, 500), // |client_size| + true); // |adjust_if_offscreen| + EXPECT_EQ(BubbleBorder::TOP_CENTER, frame.bubble_border()->arrow()); + EXPECT_EQ(window_bounds.x(), 0); + EXPECT_EQ(window_bounds.x() + + frame.bubble_border()->GetArrowOffset(window_bounds.size()), + 125); + } frame.bubble_border()->set_arrow(BubbleBorder::BOTTOM_CENTER); window_bounds = frame.GetUpdatedWindowBounds( @@ -411,19 +431,25 @@ true); // |adjust_if_offscreen| EXPECT_EQ(BubbleBorder::BOTTOM_CENTER, frame.bubble_border()->arrow()); EXPECT_EQ(window_bounds.x(), 0); - EXPECT_EQ(window_bounds.x() + - frame.bubble_border()->GetArrowOffset(window_bounds.size()), 125); + if (!UseMd()) { // There is no arrow offset in MD mode. + EXPECT_EQ(window_bounds.x() + + frame.bubble_border()->GetArrowOffset(window_bounds.size()), + 125); + } // Test bubble not fitting right screen edge. - frame.bubble_border()->set_arrow(BubbleBorder::TOP_CENTER); - window_bounds = frame.GetUpdatedWindowBounds( - gfx::Rect(900, 100, 50, 50), // |anchor_rect| - gfx::Size(500, 500), // |client_size| - true); // |adjust_if_offscreen| - EXPECT_EQ(BubbleBorder::TOP_CENTER, frame.bubble_border()->arrow()); - EXPECT_EQ(window_bounds.right(), 1000); - EXPECT_EQ(window_bounds.x() + - frame.bubble_border()->GetArrowOffset(window_bounds.size()), 925); + if (!UseMd()) { // TOP_CENTER isn't supported by the bubble_border() in MD. + frame.bubble_border()->set_arrow(BubbleBorder::TOP_CENTER); + window_bounds = frame.GetUpdatedWindowBounds( + gfx::Rect(900, 100, 50, 50), // |anchor_rect| + gfx::Size(500, 500), // |client_size| + true); // |adjust_if_offscreen| + EXPECT_EQ(BubbleBorder::TOP_CENTER, frame.bubble_border()->arrow()); + EXPECT_EQ(window_bounds.right(), 1000); + EXPECT_EQ(window_bounds.x() + + frame.bubble_border()->GetArrowOffset(window_bounds.size()), + 925); + } frame.bubble_border()->set_arrow(BubbleBorder::BOTTOM_CENTER); window_bounds = frame.GetUpdatedWindowBounds( @@ -432,50 +458,60 @@ true); // |adjust_if_offscreen| EXPECT_EQ(BubbleBorder::BOTTOM_CENTER, frame.bubble_border()->arrow()); EXPECT_EQ(window_bounds.right(), 1000); - EXPECT_EQ(window_bounds.x() + - frame.bubble_border()->GetArrowOffset(window_bounds.size()), 925); + if (!UseMd()) { // There is no arrow offset in MD mode. + EXPECT_EQ(window_bounds.x() + + frame.bubble_border()->GetArrowOffset(window_bounds.size()), + 925); + } // Test bubble not fitting top screen edge. - frame.bubble_border()->set_arrow(BubbleBorder::LEFT_CENTER); - window_bounds = frame.GetUpdatedWindowBounds( - gfx::Rect(100, 100, 50, 50), // |anchor_rect| - gfx::Size(500, 500), // |client_size| - true); // |adjust_if_offscreen| - EXPECT_EQ(BubbleBorder::LEFT_CENTER, frame.bubble_border()->arrow()); - EXPECT_EQ(window_bounds.y(), 0); - EXPECT_EQ(window_bounds.y() + - frame.bubble_border()->GetArrowOffset(window_bounds.size()), 125); + if (!UseMd()) { // Moving the bubble by setting the arrow offset doesn't work + // in MD mode since there is no arrow displayed. + frame.bubble_border()->set_arrow(BubbleBorder::LEFT_CENTER); + window_bounds = frame.GetUpdatedWindowBounds( + gfx::Rect(100, 100, 50, 50), // |anchor_rect| + gfx::Size(500, 500), // |client_size| + true); // |adjust_if_offscreen| + EXPECT_EQ(BubbleBorder::LEFT_CENTER, frame.bubble_border()->arrow()); + EXPECT_EQ(window_bounds.y(), 0); + EXPECT_EQ(window_bounds.y() + + frame.bubble_border()->GetArrowOffset(window_bounds.size()), + 125); - frame.bubble_border()->set_arrow(BubbleBorder::RIGHT_CENTER); - window_bounds = frame.GetUpdatedWindowBounds( - gfx::Rect(900, 100, 50, 50), // |anchor_rect| - gfx::Size(500, 500), // |client_size| - true); // |adjust_if_offscreen| - EXPECT_EQ(BubbleBorder::RIGHT_CENTER, frame.bubble_border()->arrow()); - EXPECT_EQ(window_bounds.y(), 0); - EXPECT_EQ(window_bounds.y() + - frame.bubble_border()->GetArrowOffset(window_bounds.size()), 125); + frame.bubble_border()->set_arrow(BubbleBorder::RIGHT_CENTER); + window_bounds = frame.GetUpdatedWindowBounds( + gfx::Rect(900, 100, 50, 50), // |anchor_rect| + gfx::Size(500, 500), // |client_size| + true); // |adjust_if_offscreen| + EXPECT_EQ(BubbleBorder::RIGHT_CENTER, frame.bubble_border()->arrow()); + EXPECT_EQ(window_bounds.y(), 0); + EXPECT_EQ(window_bounds.y() + + frame.bubble_border()->GetArrowOffset(window_bounds.size()), + 125); - // Test bubble not fitting bottom screen edge. - frame.bubble_border()->set_arrow(BubbleBorder::LEFT_CENTER); - window_bounds = frame.GetUpdatedWindowBounds( - gfx::Rect(100, 900, 50, 50), // |anchor_rect| - gfx::Size(500, 500), // |client_size| - true); // |adjust_if_offscreen| - EXPECT_EQ(BubbleBorder::LEFT_CENTER, frame.bubble_border()->arrow()); - EXPECT_EQ(window_bounds.bottom(), 1000); - EXPECT_EQ(window_bounds.y() + - frame.bubble_border()->GetArrowOffset(window_bounds.size()), 925); + // Test bubble not fitting bottom screen edge. + frame.bubble_border()->set_arrow(BubbleBorder::LEFT_CENTER); + window_bounds = frame.GetUpdatedWindowBounds( + gfx::Rect(100, 900, 50, 50), // |anchor_rect| + gfx::Size(500, 500), // |client_size| + true); // |adjust_if_offscreen| + EXPECT_EQ(BubbleBorder::LEFT_CENTER, frame.bubble_border()->arrow()); + EXPECT_EQ(window_bounds.bottom(), 1000); + EXPECT_EQ(window_bounds.y() + + frame.bubble_border()->GetArrowOffset(window_bounds.size()), + 925); - frame.bubble_border()->set_arrow(BubbleBorder::RIGHT_CENTER); - window_bounds = frame.GetUpdatedWindowBounds( - gfx::Rect(900, 900, 50, 50), // |anchor_rect| - gfx::Size(500, 500), // |client_size| - true); // |adjust_if_offscreen| - EXPECT_EQ(BubbleBorder::RIGHT_CENTER, frame.bubble_border()->arrow()); - EXPECT_EQ(window_bounds.bottom(), 1000); - EXPECT_EQ(window_bounds.y() + - frame.bubble_border()->GetArrowOffset(window_bounds.size()), 925); + frame.bubble_border()->set_arrow(BubbleBorder::RIGHT_CENTER); + window_bounds = frame.GetUpdatedWindowBounds( + gfx::Rect(900, 900, 50, 50), // |anchor_rect| + gfx::Size(500, 500), // |client_size| + true); // |adjust_if_offscreen| + EXPECT_EQ(BubbleBorder::RIGHT_CENTER, frame.bubble_border()->arrow()); + EXPECT_EQ(window_bounds.bottom(), 1000); + EXPECT_EQ(window_bounds.y() + + frame.bubble_border()->GetArrowOffset(window_bounds.size()), + 925); + } } TEST_F(BubbleFrameViewTest, GetPreferredSize) {
diff --git a/ui/views/cocoa/bridged_content_view.mm b/ui/views/cocoa/bridged_content_view.mm index 6d05846..15cb99be 100644 --- a/ui/views/cocoa/bridged_content_view.mm +++ b/ui/views/cocoa/bridged_content_view.mm
@@ -622,6 +622,13 @@ ui::MouseEvent event(theEvent); + // ui::EventLocationFromNative() assumes the event hit the contentView. + // Adjust if that's not the case (e.g. for reparented views). + if ([theEvent window] && [[self window] contentView] != self) { + NSPoint p = [self convertPoint:[theEvent locationInWindow] fromView:nil]; + event.set_location(gfx::Point(p.x, NSHeight([self frame]) - p.y)); + } + // Aura updates tooltips with the help of aura::Window::AddPreTargetHandler(). // Mac hooks in here. [self updateTooltipIfRequiredAt:event.location()]; @@ -669,7 +676,7 @@ // window containing it, since AppKit requires a titlebar to give frameless // windows correct shadows and rounded corners. NSWindow* window = [self window]; - if (window) + if (window && [window contentView] == self) newSize = [window contentRectForFrameRect:[window frame]].size; [super setFrameSize:newSize];
diff --git a/ui/views/cocoa/bridged_native_widget.mm b/ui/views/cocoa/bridged_native_widget.mm index e4d1ee9..8e4ab6c 100644 --- a/ui/views/cocoa/bridged_native_widget.mm +++ b/ui/views/cocoa/bridged_native_widget.mm
@@ -126,6 +126,20 @@ return widget && widget->is_top_level(); } +// Returns true if the content_view is reparented. +bool PositionWindowInNativeViewParent(NSView* content_view) { + return [[content_view window] contentView] != content_view; +} + +// Return the offset of the parent native view from the window. +gfx::Vector2d GetNativeViewParentOffset(NSView* content_view) { + NSWindow* window = [content_view window]; + NSView* parent_view = [content_view superview]; + NSPoint p = NSMakePoint(0, NSHeight([parent_view frame])); + p = [parent_view convertPoint:p toView:nil]; + return gfx::Vector2d(p.x, NSHeight([window frame]) - p.y); +} + // Return the content size for a minimum or maximum widget size. gfx::Size GetClientSizeForWindowSize(NSWindow* window, const gfx::Size& window_size) { @@ -520,6 +534,9 @@ if (parent_ && !PositionWindowInScreenCoordinates(widget, widget_type_)) actual_new_bounds.Offset(parent_->GetChildWindowOffset()); + if (PositionWindowInNativeViewParent(bridged_view_)) + actual_new_bounds.Offset(GetNativeViewParentOffset(bridged_view_)); + [window_ setFrame:gfx::ScreenRectToNSRect(actual_new_bounds) display:YES animate:NO];
diff --git a/ui/views/controls/button/md_text_button.cc b/ui/views/controls/button/md_text_button.cc index d38353f..d24bb2d9 100644 --- a/ui/views/controls/button/md_text_button.cc +++ b/ui/views/controls/button/md_text_button.cc
@@ -305,8 +305,8 @@ } else { // These alpha values will take the enabled button colors, 5a5a5a @ 1.0 // alpha for non-Harmony, 757575 @ 1.0 alpha for Harmony and turn it into - // an effective cccccc @ 1.0 alpha or 000000 @ 0.2 for the stroke_color. - stroke_alpha = UseMaterialSecondaryButtons() ? 0x5f : 0x4e; + // an effective b2b2b2 @ 1.0 alpha or 000000 @ 0.3 for the stroke_color. + stroke_alpha = UseMaterialSecondaryButtons() ? 0x8f : 0x77; } stroke_color = SkColorSetA(text_color, stroke_alpha); }
diff --git a/ui/views/controls/menu/menu_runner_impl.h b/ui/views/controls/menu/menu_runner_impl.h index 78fcff7..22e490a 100644 --- a/ui/views/controls/menu/menu_runner_impl.h +++ b/ui/views/controls/menu/menu_runner_impl.h
@@ -32,9 +32,8 @@ namespace internal { // A menu runner implementation that uses views::MenuItemView to show a menu. -class VIEWS_EXPORT MenuRunnerImpl - : NON_EXPORTED_BASE(public MenuRunnerImplInterface), - NON_EXPORTED_BASE(public MenuControllerDelegate) { +class VIEWS_EXPORT MenuRunnerImpl : public MenuRunnerImplInterface, + public MenuControllerDelegate { public: explicit MenuRunnerImpl(MenuItemView* menu);
diff --git a/ui/views/controls/menu/menu_runner_impl_adapter.h b/ui/views/controls/menu/menu_runner_impl_adapter.h index bcb31cf..e70d7b60 100644 --- a/ui/views/controls/menu/menu_runner_impl_adapter.h +++ b/ui/views/controls/menu/menu_runner_impl_adapter.h
@@ -20,8 +20,7 @@ class MenuRunnerImpl; // Given a MenuModel, adapts MenuRunnerImpl which expects a MenuItemView. -class VIEWS_EXPORT MenuRunnerImplAdapter - : public NON_EXPORTED_BASE(MenuRunnerImplInterface) { +class VIEWS_EXPORT MenuRunnerImplAdapter : public MenuRunnerImplInterface { public: MenuRunnerImplAdapter(ui::MenuModel* menu_model, const base::Closure& on_menu_closed_callback);
diff --git a/ui/views/controls/textfield/textfield_unittest.cc b/ui/views/controls/textfield/textfield_unittest.cc index 3d355e0..8fef282 100644 --- a/ui/views/controls/textfield/textfield_unittest.cc +++ b/ui/views/controls/textfield/textfield_unittest.cc
@@ -258,7 +258,7 @@ } void MockInputMethod::ClearComposition() { - composition_.Clear(); + composition_ = ui::CompositionText(); result_text_.clear(); }
diff --git a/ui/views/examples/box_layout_example.h b/ui/views/examples/box_layout_example.h index 7695045..d6b0a2cf 100644 --- a/ui/views/examples/box_layout_example.h +++ b/ui/views/examples/box_layout_example.h
@@ -38,7 +38,7 @@ void CreateExampleView(View* container) override; private: - friend class ChildPanel; + friend class views::examples::ChildPanel; // ButtonListener void ButtonPressed(Button* sender, const ui::Event& event) override;
diff --git a/ui/views/mus/screen_mus.h b/ui/views/mus/screen_mus.h index a1eae31..4987b07e 100644 --- a/ui/views/mus/screen_mus.h +++ b/ui/views/mus/screen_mus.h
@@ -19,9 +19,8 @@ class ScreenMusDelegate; // Screen implementation backed by ui::mojom::DisplayManager. -class VIEWS_MUS_EXPORT ScreenMus - : public display::ScreenBase, - public NON_EXPORTED_BASE(ui::mojom::DisplayManagerObserver) { +class VIEWS_MUS_EXPORT ScreenMus : public display::ScreenBase, + public ui::mojom::DisplayManagerObserver { public: explicit ScreenMus(ScreenMusDelegate* delegate); ~ScreenMus() override;
diff --git a/ui/views/view_unittest.cc b/ui/views/view_unittest.cc index d1eb371..7cd753b 100644 --- a/ui/views/view_unittest.cc +++ b/ui/views/view_unittest.cc
@@ -2395,16 +2395,9 @@ DISALLOW_COPY_AND_ASSIGN(ToplevelWidgetObserverView); }; -// No ReparentNativeView on Mac. See http://crbug.com/514920. -#if defined(OS_MACOSX) && !defined(USE_AURA) -#define MAYBE_NativeViewHierarchyChanged DISABLED_NativeViewHierarchyChanged -#else -#define MAYBE_NativeViewHierarchyChanged NativeViewHierarchyChanged -#endif - // Test that a view can track the current top level widget by overriding // View::ViewHierarchyChanged() and View::NativeViewHierarchyChanged(). -TEST_F(ViewTest, MAYBE_NativeViewHierarchyChanged) { +TEST_F(ViewTest, NativeViewHierarchyChanged) { std::unique_ptr<Widget> toplevel1(new Widget); Widget::InitParams toplevel1_params = CreateParams(Widget::InitParams::TYPE_POPUP);
diff --git a/ui/views/widget/native_widget_mac.mm b/ui/views/widget/native_widget_mac.mm index 7494b20..ce35a6a 100644 --- a/ui/views/widget/native_widget_mac.mm +++ b/ui/views/widget/native_widget_mac.mm
@@ -742,14 +742,37 @@ // static void NativeWidgetPrivate::ReparentNativeView(gfx::NativeView native_view, gfx::NativeView new_parent) { - BridgedNativeWidget* bridge = - NativeWidgetMac::GetBridgeForNativeWindow([native_view window]); - if (bridge && bridge->parent() && - bridge->parent()->GetNSWindow() == [new_parent window]) - return; // Nothing to do. + DCHECK_NE(native_view, new_parent); + if (!new_parent) { + NOTREACHED(); + return; + } - // Not supported. See http://crbug.com/514920. - NOTREACHED(); + if ([native_view superview] == new_parent) + return; + + Widget::Widgets widgets; + GetAllChildWidgets(native_view, &widgets); + + // First notify all the widgets that they are being disassociated + // from their previous parent. + for (auto* child : widgets) + child->NotifyNativeViewHierarchyWillChange(); + + // Make native_view be a child of new_parent by adding it as a subview. + // The window of the native_view must remain visible because it controls the + // bounds and visibility of the ui::Layer. So just hide it by setting alpha + // value to zero. + // It is assumed that native_view is BridgedContentView and BridgedContentView + // handles the reparented behavior. + NSWindow* native_window = [native_view window]; + [new_parent addSubview:native_view]; + [native_window setAlphaValue:0]; + [native_window setIgnoresMouseEvents:YES]; + + // And now, notify them that they have a brand new parent. + for (auto* child : widgets) + child->NotifyNativeViewHierarchyChanged(); } // static
diff --git a/ui/views/widget/native_widget_mac_unittest.mm b/ui/views/widget/native_widget_mac_unittest.mm index 50a6655..9454e2c7 100644 --- a/ui/views/widget/native_widget_mac_unittest.mm +++ b/ui/views/widget/native_widget_mac_unittest.mm
@@ -1703,6 +1703,46 @@ widget->CloseNow(); } +// Ensure reparented native view has correct bounds. +TEST_F(NativeWidgetMacTest, ReparentNativeViewBounds) { + Widget* parent = CreateTopLevelFramelessPlatformWidget(); + gfx::Rect parent_rect(100, 100, 300, 200); + parent->SetBounds(parent_rect); + + Widget::InitParams params(Widget::InitParams::TYPE_CONTROL); + params.parent = parent->GetNativeView(); + Widget* widget = new Widget; + widget->Init(params); + widget->SetContentsView(new View); + + NSView* child_view = widget->GetNativeView(); + Widget::ReparentNativeView(child_view, parent->GetNativeView()); + + // Reparented content view has the size of the Widget that created it. + gfx::Rect widget_rect(0, 0, 200, 100); + widget->SetBounds(widget_rect); + EXPECT_EQ(200, NSWidth([child_view frame])); + EXPECT_EQ(100, NSHeight([child_view frame])); + + // Reparented widget has bounds relative to the native parent + NSRect native_parent_rect = NSMakeRect(50, 100, 200, 70); + base::scoped_nsobject<NSView> native_parent( + [[NSView alloc] initWithFrame:native_parent_rect]); + [parent->GetNativeView() addSubview:native_parent]; + + gfx::Rect screen_rect = widget->GetWindowBoundsInScreen(); + EXPECT_EQ(100, screen_rect.x()); + EXPECT_EQ(100, screen_rect.y()); + + Widget::ReparentNativeView(child_view, native_parent); + widget->SetBounds(widget_rect); + screen_rect = widget->GetWindowBoundsInScreen(); + EXPECT_EQ(150, screen_rect.x()); + EXPECT_EQ(130, screen_rect.y()); + + parent->CloseNow(); +} + // Test class for Full Keyboard Access related tests. class NativeWidgetMacFullKeyboardAccessTest : public NativeWidgetMacTest { public:
diff --git a/ui/views/window/dialog_delegate.cc b/ui/views/window/dialog_delegate.cc index fcc122f..ee398d80 100644 --- a/ui/views/window/dialog_delegate.cc +++ b/ui/views/window/dialog_delegate.cc
@@ -38,9 +38,13 @@ // margins. margins_(0) { UMA_HISTOGRAM_BOOLEAN("Dialog.DialogDelegate.Create", true); + creation_time_ = base::TimeTicks::Now(); } -DialogDelegate::~DialogDelegate() {} +DialogDelegate::~DialogDelegate() { + UMA_HISTOGRAM_LONG_TIMES("Dialog.DialogDelegate.Duration", + base::TimeTicks::Now() - creation_time_); +} // static Widget* DialogDelegate::CreateDialogWidget(WidgetDelegate* delegate,
diff --git a/ui/views/window/dialog_delegate.h b/ui/views/window/dialog_delegate.h index 1c8d57c..598e8bae52 100644 --- a/ui/views/window/dialog_delegate.h +++ b/ui/views/window/dialog_delegate.h
@@ -8,6 +8,7 @@ #include "base/compiler_specific.h" #include "base/macros.h" #include "base/strings/string16.h" +#include "base/time/time.h" #include "ui/accessibility/ax_enums.h" #include "ui/base/models/dialog_model.h" #include "ui/base/ui_base_types.h" @@ -130,6 +131,11 @@ // The margins between the content and the inside of the border. gfx::Insets margins_; + + // The time the dialog is created. + base::TimeTicks creation_time_; + + DISALLOW_COPY_AND_ASSIGN(DialogDelegate); }; // A DialogDelegate implementation that is-a View. Used to override GetWidget()
diff --git a/ui/webui/resources/cr_components/chromeos/network/network_property_list.html b/ui/webui/resources/cr_components/chromeos/network/network_property_list.html index 121d487..0d73594 100644 --- a/ui/webui/resources/cr_components/chromeos/network/network_property_list.html +++ b/ui/webui/resources/cr_components/chromeos/network/network_property_list.html
@@ -21,6 +21,11 @@ padding: 0; } + .secondary { + color: var(--paper-grey-600); + font-weight: 400; + } + cr-policy-network-indicator { -webkit-margin-start: var(--settings-controlled-by-spacing); }
diff --git a/ui/webui/resources/cr_components/chromeos/network/network_proxy.js b/ui/webui/resources/cr_components/chromeos/network/network_proxy.js index 2e125759..a1f2056 100644 --- a/ui/webui/resources/cr_components/chromeos/network/network_proxy.js +++ b/ui/webui/resources/cr_components/chromeos/network/network_proxy.js
@@ -122,6 +122,15 @@ */ proxyModified_: false, + /** @override */ + attached: function() { + this.reset(); + }, + + /** + * Called any time the page is refreshed or navigated to so that the proxy + * is updated correctly. + */ reset: function() { this.proxyModified_ = false; this.proxy_ = this.createDefaultProxySettings_();
diff --git a/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_picture_list.html b/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_picture_list.html index 5c9e3eb..d7926ee 100644 --- a/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_picture_list.html +++ b/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_picture_list.html
@@ -56,6 +56,7 @@ on-keys-pressed="onKeysPressed_"> </iron-a11y-keys> <iron-selector id="selector" on-iron-activate="onIronActivate_" + on-selected-item-changed="onSelectedItemChanged_" selected-item="{{selectedItem}}" role="radiogroup"> <!-- Selects the camera as the picture source. --> <iron-icon id="cameraImage" role="radio"
diff --git a/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_picture_list.js b/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_picture_list.js index c840537..165f98e 100644 --- a/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_picture_list.js +++ b/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_picture_list.js
@@ -227,6 +227,15 @@ }, /** + * @param {!Event} event + * @private + */ + onSelectedItemChanged_: function(event) { + if (event.target.selectedItem) + event.target.selectedItem.scrollIntoViewIfNeeded(false); + }, + + /** * Returns the image to use for 'src'. * @param {string} url * @return {string}
diff --git a/ui/webui/resources/cr_elements/icons.html b/ui/webui/resources/cr_elements/icons.html index 22aa991..bc0eae7 100644 --- a/ui/webui/resources/cr_elements/icons.html +++ b/ui/webui/resources/cr_elements/icons.html
@@ -33,6 +33,7 @@ <g id="camera-alt"><circle cx="12" cy="12" r="3.2"></circle><path d="M9 2L7.17 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2h-3.17L15 2H9zm3 15c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5z"></path></g> <g id="check"><path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"></path></g> </if> + <g id="account-child-invert" viewBox="0 0 48 48"><path d="M24 4c3.31 0 6 2.69 6 6s-2.69 6-6 6-6-2.69-6-6 2.69-6 6-6z"></path><path fill="none" d="M0 0h48v48H0V0z"></path><circle fill="none" cx="24" cy="26" r="4"></circle><path d="M24 18c-6.16 0-13 3.12-13 7.23v11.54c0 2.32 2.19 4.33 5.2 5.63 2.32 1 5.12 1.59 7.8 1.59.66 0 1.33-.06 2-.14v-5.2c-.67.08-1.34.14-2 .14-2.63 0-5.39-.57-7.68-1.55.67-2.12 4.34-3.65 7.68-3.65.86 0 1.75.11 2.6.29 2.79.62 5.2 2.15 5.2 4.04v4.47c3.01-1.31 5.2-3.31 5.2-5.63V25.23C37 21.12 30.16 18 24 18zm0 12c-2.21 0-4-1.79-4-4s1.79-4 4-4 4 1.79 4 4-1.79 4-4 4z"></path></g> <g id="chevron-right"><path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"></path></g> <g id="clear"><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"></path></g> <g id="close"><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"></path></g> @@ -54,6 +55,7 @@ suffix prevents the naming conflict. --> <g id="settings_icon"><path d="M19.43 12.98c.04-.32.07-.64.07-.98s-.03-.66-.07-.98l2.11-1.65c.19-.15.24-.42.12-.64l-2-3.46c-.12-.22-.39-.3-.61-.22l-2.49 1c-.52-.4-1.08-.73-1.69-.98l-.38-2.65C14.46 2.18 14.25 2 14 2h-4c-.25 0-.46.18-.49.42l-.38 2.65c-.61.25-1.17.59-1.69.98l-2.49-1c-.23-.09-.49 0-.61.22l-2 3.46c-.13.22-.07.49.12.64l2.11 1.65c-.04.32-.07.65-.07.98s.03.66.07.98l-2.11 1.65c-.19.15-.24.42-.12.64l2 3.46c.12.22.39.3.61.22l2.49-1c.52.4 1.08.73 1.69.98l.38 2.65c.03.24.24.42.49.42h4c.25 0 .46-.18.49-.42l.38-2.65c.61-.25 1.17-.59 1.69-.98l2.49 1c.23.09.49 0 .61-.22l2-3.46c.12-.22.07-.49-.12-.64l-2.11-1.65zM12 15.5c-1.93 0-3.5-1.57-3.5-3.5s1.57-3.5 3.5-3.5 3.5 1.57 3.5 3.5-1.57 3.5-3.5 3.5z"></path></g> <g id="star"><path d="M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z"></path></g> + <g id="supervisor-account" viewBox="0 0 48 48"><path d="M0 0h48v48H0z" fill="none"></path><path d="M33 24c2.76 0 4.98-2.24 4.98-5s-2.22-5-4.98-5c-2.76 0-5 2.24-5 5s2.24 5 5 5zm-15-2c3.31 0 5.98-2.69 5.98-6s-2.67-6-5.98-6c-3.31 0-6 2.69-6 6s2.69 6 6 6zm15 6c-3.67 0-11 1.84-11 5.5V38h22v-4.5c0-3.66-7.33-5.5-11-5.5zm-15-2c-4.67 0-14 2.34-14 7v5h14v-4.5c0-1.7.67-4.67 4.74-6.94C21 26.19 19.31 26 18 26z"></path></g> <g id="warning"><path d="M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z"></path></g> </defs> </svg>