diff --git a/DEPS b/DEPS index 3bfe9800..9aa8ddf 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': 'cf79ee5626ddf9c5fb5315a560d10c25f4270c6f', + 'skia_revision': 'fc4ee229a653d0e9d71f828e513c9d458c1eab57', # 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': '3921afc2b86b11cdcddadfa8098278caf3b0dfa8', + 'v8_revision': '1115d8724ce832a77e1a85e0ba3fbee527ea7eb0', # 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. @@ -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': '57f228d7527594de55951fa05e6082ba62382c57', + 'pdfium_revision': '21dd189fe50d297dd1224c06319e166c1ac6bae2', # 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': 'b63abe05c65413bfc03a8ff398d66d0846ffb644', + 'catapult_revision': 'ebf00ecf2e8397f7774dcd90c73f40fcba8097d5', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other.
diff --git a/android_webview/BUILD.gn b/android_webview/BUILD.gn index a63bd08..945df0d 100644 --- a/android_webview/BUILD.gn +++ b/android_webview/BUILD.gn
@@ -180,8 +180,6 @@ } } -webview_license_path = "$target_gen_dir/webview_licenses.notice" - android_assets("pak_file_assets") { sources = [ "$target_gen_dir/chrome_100_percent.pak", @@ -222,28 +220,10 @@ } android_assets("license_assets") { - sources = [ - webview_license_path, - ] + renaming_sources = [ "$root_gen_dir/components/resources/about_credits.html" ] + renaming_destinations = [ "webview_licenses.notice" ] deps = [ - ":generate_webview_license_notice", - ] -} - -action("generate_webview_license_notice") { - script = "tools/webview_licenses.py" - depfile = "$target_gen_dir/$target_name.d" - inputs = [ - "tools/licenses_notice.tmpl", - ] - outputs = [ - webview_license_path, - ] - args = [ - "notice", - rebase_path(webview_license_path, root_build_dir), - "--depfile", - rebase_path(depfile, root_build_dir), + "//components/resources:about_credits", ] }
diff --git a/android_webview/browser/aw_autofill_client.cc b/android_webview/browser/aw_autofill_client.cc index 8920c51..2a0dd210 100644 --- a/android_webview/browser/aw_autofill_client.cc +++ b/android_webview/browser/aw_autofill_client.cc
@@ -217,6 +217,10 @@ void AwAutofillClient::ShowHttpNotSecureExplanation() {} +bool AwAutofillClient::IsAutofillSupported() { + return true; +} + void AwAutofillClient::Dismissed(JNIEnv* env, const JavaParamRef<jobject>& obj) { anchor_view_.Reset();
diff --git a/android_webview/browser/aw_autofill_client.h b/android_webview/browser/aw_autofill_client.h index cfa3770..70cd6f16 100644 --- a/android_webview/browser/aw_autofill_client.h +++ b/android_webview/browser/aw_autofill_client.h
@@ -107,6 +107,7 @@ bool ShouldShowSigninPromo() override; void StartSigninFlow() override; void ShowHttpNotSecureExplanation() override; + bool IsAutofillSupported() override; void Dismissed(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj); void SuggestionSelected(JNIEnv* env,
diff --git a/android_webview/browser/aw_browser_context.cc b/android_webview/browser/aw_browser_context.cc index 03b8edff..ea499630 100644 --- a/android_webview/browser/aw_browser_context.cc +++ b/android_webview/browser/aw_browser_context.cc
@@ -29,6 +29,7 @@ #include "components/prefs/in_memory_pref_store.h" #include "components/prefs/pref_service.h" #include "components/prefs/pref_service_factory.h" +#include "components/safe_browsing/common/safe_browsing_prefs.h" #include "components/safe_browsing/triggers/trigger_manager.h" #include "components/url_formatter/url_fixer.h" #include "components/user_prefs/user_prefs.h" @@ -200,8 +201,8 @@ web_restriction_provider_->SetAuthority( user_pref_service_->GetString(prefs::kWebRestrictionsAuthority)); - safe_browsing_ui_manager_ = - new AwSafeBrowsingUIManager(GetAwURLRequestContext()); + safe_browsing_ui_manager_ = new AwSafeBrowsingUIManager( + GetAwURLRequestContext(), user_pref_service_.get()); safe_browsing_db_manager_ = new safe_browsing::RemoteSafeBrowsingDatabaseManager(); safe_browsing_trigger_manager_ = @@ -251,6 +252,7 @@ std::string()); metrics::MetricsService::RegisterPrefs(pref_registry); + safe_browsing::RegisterProfilePrefs(pref_registry); PrefServiceFactory pref_service_factory; pref_service_factory.set_user_prefs(make_scoped_refptr(
diff --git a/android_webview/browser/aw_safe_browsing_blocking_page.cc b/android_webview/browser/aw_safe_browsing_blocking_page.cc index c45f6bd5..391eb21 100644 --- a/android_webview/browser/aw_safe_browsing_blocking_page.cc +++ b/android_webview/browser/aw_safe_browsing_blocking_page.cc
@@ -7,6 +7,7 @@ #include "android_webview/browser/aw_browser_context.h" #include "android_webview/browser/aw_safe_browsing_ui_manager.h" #include "android_webview/browser/net/aw_url_request_context_getter.h" +#include "components/prefs/pref_service.h" #include "components/safe_browsing/browser/threat_details.h" #include "components/safe_browsing/triggers/trigger_manager.h" #include "components/security_interstitials/content/security_interstitial_controller_client.h" @@ -71,7 +72,7 @@ void AwSafeBrowsingBlockingPage::ShowBlockingPage( AwSafeBrowsingUIManager* ui_manager, const UnsafeResource& unsafe_resource, - bool extended_reporting_allowed) { + PrefService* pref_service) { DVLOG(1) << __func__ << " " << unsafe_resource.url.spec(); WebContents* web_contents = unsafe_resource.web_contents_getter.Run(); @@ -89,11 +90,13 @@ const UnsafeResourceList unsafe_resources{unsafe_resource}; BaseSafeBrowsingErrorUI::SBErrorDisplayOptions display_options = BaseSafeBrowsingErrorUI::SBErrorDisplayOptions( - IsMainPageLoadBlocked(unsafe_resources), extended_reporting_allowed, - false, // is_off_the_record - false, // is_extended_reporting - false, // is_scout - false, // kSafeBrowsingProceedAnywayDisabled + IsMainPageLoadBlocked(unsafe_resources), + safe_browsing::IsExtendedReportingOptInAllowed(*pref_service), + false, // is_off_the_record + safe_browsing::IsExtendedReportingEnabled(*pref_service), + safe_browsing::IsScout(*pref_service), + pref_service->GetBoolean( + ::prefs::kSafeBrowsingProceedAnywayDisabled), false, // should_open_links_in_new_tab "cpn_safe_browsing_wv"); // help_center_article_link @@ -103,7 +106,8 @@ AwSafeBrowsingBlockingPage* blocking_page = new AwSafeBrowsingBlockingPage( ui_manager, web_contents, entry ? entry->GetURL() : GURL(), unsafe_resources, - CreateControllerClient(web_contents, unsafe_resources, ui_manager), + CreateControllerClient(web_contents, unsafe_resources, ui_manager, + pref_service), display_options, errorType); blocking_page->Show(); }
diff --git a/android_webview/browser/aw_safe_browsing_blocking_page.h b/android_webview/browser/aw_safe_browsing_blocking_page.h index 9084d1a..b65c192 100644 --- a/android_webview/browser/aw_safe_browsing_blocking_page.h +++ b/android_webview/browser/aw_safe_browsing_blocking_page.h
@@ -8,6 +8,8 @@ #include "components/safe_browsing/base_blocking_page.h" #include "components/security_interstitials/core/base_safe_browsing_error_ui.h" +class PrefService; + namespace security_interstitials { struct UnsafeResource; } // namespace security_interstitials @@ -22,7 +24,7 @@ static void ShowBlockingPage(AwSafeBrowsingUIManager* ui_manager, const UnsafeResource& unsafe_resource, - bool extended_reporting_allowed); + PrefService* pref_service); protected: // Used to specify which BaseSafeBrowsingErrorUI to instantiate, and
diff --git a/android_webview/browser/aw_safe_browsing_resource_throttle.cc b/android_webview/browser/aw_safe_browsing_resource_throttle.cc index 4a30851..1f54c40 100644 --- a/android_webview/browser/aw_safe_browsing_resource_throttle.cc +++ b/android_webview/browser/aw_safe_browsing_resource_throttle.cc
@@ -89,9 +89,9 @@ SafeBrowsingAction action, bool reporting) { if (!reporting) { - AwSafeBrowsingUIManager* casted_ui_manager = + AwSafeBrowsingUIManager* aw_ui_manager = static_cast<AwSafeBrowsingUIManager*>(ui_manager.get()); - casted_ui_manager->set_extended_reporting_allowed(false); + aw_ui_manager->SetExtendedReportingAllowed(false); } // TODO(ntfschr): fully handle reporting once we add support (crbug/688629) bool proceed;
diff --git a/android_webview/browser/aw_safe_browsing_ui_manager.cc b/android_webview/browser/aw_safe_browsing_ui_manager.cc index 5346c56..ca87019 100644 --- a/android_webview/browser/aw_safe_browsing_ui_manager.cc +++ b/android_webview/browser/aw_safe_browsing_ui_manager.cc
@@ -9,6 +9,7 @@ #include "android_webview/common/aw_paths.h" #include "base/command_line.h" #include "base/path_service.h" +#include "components/prefs/pref_service.h" #include "components/safe_browsing/base_ping_manager.h" #include "components/safe_browsing/base_ui_manager.h" #include "components/safe_browsing/browser/safe_browsing_url_request_context_getter.h" @@ -31,7 +32,9 @@ namespace android_webview { AwSafeBrowsingUIManager::AwSafeBrowsingUIManager( - AwURLRequestContextGetter* browser_url_request_context_getter) { + AwURLRequestContextGetter* browser_url_request_context_getter, + PrefService* pref_service) + : pref_service_(pref_service) { DCHECK_CURRENTLY_ON(BrowserThread::UI); // TODO(timvolodine): verify this is what we want regarding the directory. @@ -65,8 +68,12 @@ void AwSafeBrowsingUIManager::ShowBlockingPageForResource( const UnsafeResource& resource) { - AwSafeBrowsingBlockingPage::ShowBlockingPage(this, resource, - extended_reporting_allowed_); + AwSafeBrowsingBlockingPage::ShowBlockingPage(this, resource, pref_service_); +} + +void AwSafeBrowsingUIManager::SetExtendedReportingAllowed(bool allowed) { + pref_service_->SetBoolean(::prefs::kSafeBrowsingExtendedReportingOptInAllowed, + allowed); } int AwSafeBrowsingUIManager::GetErrorUiType(
diff --git a/android_webview/browser/aw_safe_browsing_ui_manager.h b/android_webview/browser/aw_safe_browsing_ui_manager.h index 688ea3b..3bfeb06 100644 --- a/android_webview/browser/aw_safe_browsing_ui_manager.h +++ b/android_webview/browser/aw_safe_browsing_ui_manager.h
@@ -12,6 +12,8 @@ #include "components/safe_browsing/base_ui_manager.h" #include "content/public/browser/web_contents.h" +class PrefService; + namespace safe_browsing { class BasePingManager; class SafeBrowsingURLRequestContextGetter; @@ -35,7 +37,8 @@ // Construction needs to happen on the UI thread. explicit AwSafeBrowsingUIManager( - AwURLRequestContextGetter* browser_url_request_context_getter); + AwURLRequestContextGetter* browser_url_request_context_getter, + PrefService* pref_service); // Gets the correct ErrorUiType for the web contents int GetErrorUiType(const UnsafeResource& resource) const; @@ -47,9 +50,7 @@ // protocol buffer, so the service can send it over. void SendSerializedThreatDetails(const std::string& serialized) override; - void set_extended_reporting_allowed(bool allowed) { - extended_reporting_allowed_ = allowed; - } + void SetExtendedReportingAllowed(bool allowed); protected: ~AwSafeBrowsingUIManager() override; @@ -65,7 +66,8 @@ scoped_refptr<safe_browsing::SafeBrowsingURLRequestContextGetter> url_request_context_getter_; - bool extended_reporting_allowed_ = false; + // non-owning + PrefService* pref_service_; DISALLOW_COPY_AND_ASSIGN(AwSafeBrowsingUIManager); };
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AndroidScrollIntegrationTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AndroidScrollIntegrationTest.java index db8d51d..4ff65e9 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/AndroidScrollIntegrationTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/AndroidScrollIntegrationTest.java
@@ -19,7 +19,7 @@ import org.chromium.base.test.util.CallbackHelper; import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.RetryOnFailure; -import org.chromium.base.test.util.parameter.ParameterizedTest; +import org.chromium.base.test.util.parameter.SkipCommandLineParameterization; import org.chromium.content_public.browser.GestureStateListener; import org.chromium.net.test.util.TestWebServer; import org.chromium.ui.display.DisplayAndroid; @@ -442,7 +442,7 @@ @SmallTest @Feature({"AndroidWebView"}) - @ParameterizedTest.Set // crbug.com/616505 + @SkipCommandLineParameterization // crbug.com/616505 @RetryOnFailure public void testTouchScrollCanBeAlteredByUi() throws Throwable { final TestAwContentsClient contentsClient = new TestAwContentsClient();
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientCallbackHelperTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientCallbackHelperTest.java index 23a1c9a..2e562d1 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientCallbackHelperTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientCallbackHelperTest.java
@@ -16,7 +16,7 @@ import org.chromium.android_webview.test.TestAwContentsClient.PictureListenerHelper; import org.chromium.base.test.util.CallbackHelper; import org.chromium.base.test.util.Feature; -import org.chromium.base.test.util.parameter.ParameterizedTest; +import org.chromium.base.test.util.parameter.SkipCommandLineParameterization; import org.chromium.content.browser.test.util.TestCallbackHelperContainer.OnPageStartedHelper; import org.chromium.content.browser.test.util.TestCallbackHelperContainer.OnReceivedErrorHelper; @@ -25,7 +25,7 @@ /** * Test suite for AwContentsClientCallbackHelper. */ -@ParameterizedTest.Set // These are unit tests. No need to repeat for multiprocess. +@SkipCommandLineParameterization // These are unit tests. No need to repeat for multiprocess. public class AwContentsClientCallbackHelperTest extends AwTestBase { /** * Callback helper for OnLoadedResource.
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientFullScreenTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientFullScreenTest.java index 36a08c2..8c7658c 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientFullScreenTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientFullScreenTest.java
@@ -150,7 +150,7 @@ /* @MediumTest @Feature({"AndroidWebView"}) - @ParameterizedTest.Set // crbug.com/616501 + @SkipCommandLineParameterization // crbug.com/616501 */ @DisabledTest(message = "crbug.com/618749") public void testOnShowAndHideCustomViewWithBackKey_video() throws Throwable {
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientOnRenderProcessGoneTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientOnRenderProcessGoneTest.java index 1e8a2bc..cc54555 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientOnRenderProcessGoneTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientOnRenderProcessGoneTest.java
@@ -14,7 +14,7 @@ import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; -import org.chromium.base.test.util.parameter.ParameterizedTest; +import org.chromium.base.test.util.parameter.SkipCommandLineParameterization; import java.util.concurrent.TimeUnit; @@ -56,12 +56,11 @@ } } - @DisabledTest // http://crbug.com/689292 + @DisabledTest // http://crbug.com/689292 @Feature({"AndroidWebView"}) @SmallTest - @CommandLineFlags - .Add(AwSwitches.WEBVIEW_SANDBOXED_RENDERER) - @ParameterizedTest.Set + @CommandLineFlags.Add(AwSwitches.WEBVIEW_SANDBOXED_RENDERER) + @SkipCommandLineParameterization public void testOnRenderProcessCrash() throws Throwable { RenderProcessGoneTestAwContentsClient contentsClient = new RenderProcessGoneTestAwContentsClient(); @@ -80,9 +79,8 @@ @Feature({"AndroidWebView"}) @SmallTest - @CommandLineFlags - .Add(AwSwitches.WEBVIEW_SANDBOXED_RENDERER) - @ParameterizedTest.Set + @CommandLineFlags.Add(AwSwitches.WEBVIEW_SANDBOXED_RENDERER) + @SkipCommandLineParameterization public void testOnRenderProcessKill() throws Throwable { RenderProcessGoneTestAwContentsClient contentsClient = new RenderProcessGoneTestAwContentsClient();
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsTest.java index e9a8012..ce37246 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsTest.java
@@ -31,7 +31,7 @@ import org.chromium.base.test.util.CallbackHelper; import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.Feature; -import org.chromium.base.test.util.parameter.ParameterizedTest; +import org.chromium.base.test.util.parameter.SkipCommandLineParameterization; import org.chromium.content.browser.BindingManager; import org.chromium.content.browser.ChildProcessLauncherHelper; import org.chromium.content_public.common.ContentUrlConstants; @@ -615,7 +615,7 @@ @Feature({"AndroidWebView"}) @SmallTest @CommandLineFlags.Add(AwSwitches.WEBVIEW_SANDBOXED_RENDERER) - @ParameterizedTest.Set + @SkipCommandLineParameterization public void testSandboxedRendererWorks() throws Throwable { MockBindingManager bindingManager = new MockBindingManager(); ChildProcessLauncherHelper.setBindingManagerForTesting(bindingManager); @@ -644,7 +644,7 @@ @Feature({"AndroidWebView"}) @SmallTest @CommandLineFlags.Add(AwSwitches.WEBVIEW_SANDBOXED_RENDERER) - @ParameterizedTest.Set + @SkipCommandLineParameterization public void testRendererPriorityStartsHigh() throws Throwable { MockBindingManager bindingManager = new MockBindingManager(); ChildProcessLauncherHelper.setBindingManagerForTesting(bindingManager); @@ -666,7 +666,7 @@ @Feature({"AndroidWebView"}) @SmallTest @CommandLineFlags.Add(AwSwitches.WEBVIEW_SANDBOXED_RENDERER) - @ParameterizedTest.Set + @SkipCommandLineParameterization public void testRendererPriorityLow() throws Throwable { MockBindingManager bindingManager = new MockBindingManager(); ChildProcessLauncherHelper.setBindingManagerForTesting(bindingManager); @@ -696,7 +696,7 @@ @Feature({"AndroidWebView"}) @SmallTest @CommandLineFlags.Add(AwSwitches.WEBVIEW_SANDBOXED_RENDERER) - @ParameterizedTest.Set + @SkipCommandLineParameterization public void testRendererPriorityManaged() throws Throwable { MockBindingManager bindingManager = new MockBindingManager(); ChildProcessLauncherHelper.setBindingManagerForTesting(bindingManager); @@ -729,7 +729,7 @@ @SmallTest @UiThreadTest @CommandLineFlags.Add(AwSwitches.WEBVIEW_SANDBOXED_RENDERER) - @ParameterizedTest.Set + @SkipCommandLineParameterization public void testPauseDestroyResume() throws Throwable { AwContents awContents; awContents = createAwTestContainerView(mContentsClient).getAwContents();
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwDebugTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwDebugTest.java index 691ed0a..aa6fb19 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/AwDebugTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwDebugTest.java
@@ -8,7 +8,7 @@ import org.chromium.android_webview.AwDebug; import org.chromium.base.test.util.Feature; -import org.chromium.base.test.util.parameter.ParameterizedTest; +import org.chromium.base.test.util.parameter.SkipCommandLineParameterization; import java.io.File; import java.io.FileInputStream; @@ -19,7 +19,7 @@ * A test suite for AwDebug class. */ // Only works in single-process mode, crbug.com/568825. -@ParameterizedTest.Set +@SkipCommandLineParameterization public class AwDebugTest extends AwTestBase { private static final String TAG = "cr_AwDebugTest"; private static final String WHITELISTED_DEBUG_KEY = "AW_WHITELISTED_DEBUG_KEY";
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwTestBase.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwTestBase.java index 92ade85..f67a272 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/AwTestBase.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwTestBase.java
@@ -27,11 +27,9 @@ import org.chromium.base.ThreadUtils; import org.chromium.base.test.BaseActivityInstrumentationTestCase; import org.chromium.base.test.util.CallbackHelper; -import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.InMemorySharedPreferences; import org.chromium.base.test.util.MinAndroidSdkLevel; -import org.chromium.base.test.util.parameter.Parameter; -import org.chromium.base.test.util.parameter.ParameterizedTest; +import org.chromium.base.test.util.parameter.CommandLineParameter; import org.chromium.content.browser.test.util.Criteria; import org.chromium.content.browser.test.util.CriteriaHelper; import org.chromium.content.browser.test.util.TestCallbackHelperContainer.OnPageFinishedHelper; @@ -56,23 +54,11 @@ * If a test doesn't yet work with sandboxed renderer, an entire class, or an individual test * method can be marked for single-process testing only by adding the following annotation: * - * @ParameterizedTest.Set + * @SkipCommandLineParameterization */ @MinAndroidSdkLevel(Build.VERSION_CODES.KITKAT) -@ParameterizedTest.Set(tests = { - @ParameterizedTest(parameters = { - @Parameter( - tag = CommandLineFlags.Parameter.PARAMETER_TAG)}), - @ParameterizedTest(parameters = { - @Parameter( - tag = CommandLineFlags.Parameter.PARAMETER_TAG, - arguments = { - @Parameter.Argument( - name = CommandLineFlags.Parameter.ADD_ARG, - stringArray = {AwSwitches.WEBVIEW_SANDBOXED_RENDERER}) - })})}) -public class AwTestBase - extends BaseActivityInstrumentationTestCase<AwTestRunnerActivity> { +@CommandLineParameter({"", AwSwitches.WEBVIEW_SANDBOXED_RENDERER}) +public class AwTestBase extends BaseActivityInstrumentationTestCase<AwTestRunnerActivity> { public static final long WAIT_TIMEOUT_MS = scaleTimeout(15000); public static final int CHECK_INTERVAL = 100; private static final String TAG = "AwTestBase";
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/PolicyUrlFilteringTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/PolicyUrlFilteringTest.java index 5fb81ffc..724bc0f 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/PolicyUrlFilteringTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/PolicyUrlFilteringTest.java
@@ -14,7 +14,7 @@ import org.chromium.base.ThreadUtils; import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.RetryOnFailure; -import org.chromium.base.test.util.parameter.ParameterizedTest; +import org.chromium.base.test.util.parameter.SkipCommandLineParameterization; import org.chromium.content.browser.test.util.TestCallbackHelperContainer; import org.chromium.net.test.util.TestWebServer; import org.chromium.policy.AbstractAppRestrictionsProvider; @@ -63,7 +63,7 @@ @MediumTest @Feature({"AndroidWebView", "Policy"}) // Run in single process only. crbug.com/615484 - @ParameterizedTest.Set + @SkipCommandLineParameterization @RetryOnFailure public void testBlacklistedUrl() throws Throwable { final AwPolicyProvider testProvider = @@ -91,7 +91,7 @@ @Policies.Item(key = sBlacklistPolicyName, stringArray = {"*"}), @Policies.Item(key = sWhitelistPolicyName, stringArray = {sFooWhitelistFilter})}) // Run in single process only. crbug.com/660517 - @ParameterizedTest.Set + @SkipCommandLineParameterization public void testWhitelistedUrl() throws Throwable { navigateAndCheckOutcome(mFooTestUrl, 0 /* error count before */, 0 /* error count after */);
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/crash/VisualStateCallbackTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/crash/VisualStateCallbackTest.java index 373be1fc..b63c4ed4 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/crash/VisualStateCallbackTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/crash/VisualStateCallbackTest.java
@@ -27,7 +27,7 @@ import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.RetryOnFailure; -import org.chromium.base.test.util.parameter.ParameterizedTest; +import org.chromium.base.test.util.parameter.SkipCommandLineParameterization; import org.chromium.content_public.common.ContentUrlConstants; import java.util.concurrent.TimeUnit; @@ -152,9 +152,8 @@ // process gone, but before the AwContentsClient knows about it. @Feature({"AndroidWebView"}) @SmallTest - @CommandLineFlags - .Add(AwSwitches.WEBVIEW_SANDBOXED_RENDERER) - @ParameterizedTest.Set + @CommandLineFlags.Add(AwSwitches.WEBVIEW_SANDBOXED_RENDERER) + @SkipCommandLineParameterization public void testAddVisualStateCallbackAfterRendererGone() throws Throwable { final VisualStateCallbackImpl vsImpl = new VisualStateCallbackImpl(); mHelper.setOnRenderProcessGoneTask(new Runnable() { @@ -177,11 +176,9 @@ @Feature({"AndroidWebView"}) @SmallTest @RetryOnFailure - @CommandLineFlags - .Add(AwSwitches.WEBVIEW_SANDBOXED_RENDERER) - @ParameterizedTest.Set + @CommandLineFlags.Add(AwSwitches.WEBVIEW_SANDBOXED_RENDERER) + @SkipCommandLineParameterization public void testVisualStateCallbackNotCalledAfterRendererGone() throws Throwable { - VisualStateCallbackImpl vsImpl = new VisualStateCallbackImpl(); insertVisualStateCallbackOnUIThread(mAwContents, vsImpl.requestId(), vsImpl); VisualStateCallbackHelper vsCallbackHelper = mAwContents.getVisualStateCallbackHelper();
diff --git a/android_webview/tools/PRESUBMIT.py b/android_webview/tools/PRESUBMIT.py index 1df3894f..935205d 100644 --- a/android_webview/tools/PRESUBMIT.py +++ b/android_webview/tools/PRESUBMIT.py
@@ -15,7 +15,6 @@ input_api, output_api, pylintrc='pylintrc', # TODO: lint these and eliminate the blacklist. black_list=[ - r'webview_licenses.py', r'webview_repack_locales.py', ])) return input_api.RunTests(checks, False)
diff --git a/android_webview/tools/webview_licenses.py b/android_webview/tools/webview_licenses.py deleted file mode 100755 index 0e5d37c..0000000 --- a/android_webview/tools/webview_licenses.py +++ /dev/null
@@ -1,303 +0,0 @@ -#!/usr/bin/python -# 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. - -"""Checks third-party licenses for the purposes of the Android WebView build. - -The Android tree includes a snapshot of Chromium in order to power the system -WebView. This tool checks that all code uses open-source licenses compatible -with Android, and that we meet the requirements of those licenses. It can also -be used to generate an Android NOTICE file for the third-party code. - -It makes use of src/tools/licenses.py and the README.chromium files on which -it depends. It also makes use of a data file, third_party_files_whitelist.txt, -which whitelists individual files which contain third-party code but which -aren't in a third-party directory with a README.chromium file. -""" - -import imp -import json -import multiprocessing -import optparse -import os -import re -import sys -import textwrap - - -REPOSITORY_ROOT = os.path.abspath(os.path.join( - os.path.dirname(__file__), '..', '..')) - -# Import third_party/PRESUBMIT.py via imp to avoid importing a random -# PRESUBMIT.py from $PATH, also make sure we don't generate a .pyc file. -sys.dont_write_bytecode = True -third_party = \ - imp.load_source('PRESUBMIT', \ - os.path.join(REPOSITORY_ROOT, 'third_party', 'PRESUBMIT.py')) - -sys.path.append(os.path.join(REPOSITORY_ROOT, 'build/android/gyp/util')) -import build_utils -sys.path.append(os.path.join(REPOSITORY_ROOT, 'third_party')) -import jinja2 -sys.path.append(os.path.join(REPOSITORY_ROOT, 'tools')) -from copyright_scanner import copyright_scanner -import licenses - - -class InputApi(object): - def __init__(self): - self.os_path = os.path - self.os_walk = os.walk - self.re = re - self.ReadFile = _ReadFile - self.change = InputApiChange() - -class InputApiChange(object): - def __init__(self): - self.RepositoryRoot = lambda: REPOSITORY_ROOT - -class ScanResult(object): - Ok, Warnings, Errors = range(3) - -# Needs to be a top-level function for multiprocessing -def _FindCopyrightViolations(files_to_scan_as_string): - return copyright_scanner.FindCopyrightViolations( - InputApi(), REPOSITORY_ROOT, files_to_scan_as_string) - -def _ShardList(l, shard_len): - return [l[i:i + shard_len] for i in range(0, len(l), shard_len)] - -def _CheckLicenseHeaders(excluded_dirs_list, whitelisted_files): - """Checks that all files which are not in a listed third-party directory, - and which do not use the standard Chromium license, are whitelisted. - Args: - excluded_dirs_list: The list of directories to exclude from scanning. - whitelisted_files: The whitelist of files. - Returns: - ScanResult.Ok if all files with non-standard license headers are whitelisted - and the whitelist contains no stale entries; - ScanResult.Warnings if there are stale entries; - ScanResult.Errors if new non-whitelisted entries found. - """ - input_api = InputApi() - files_to_scan = copyright_scanner.FindFiles( - input_api, REPOSITORY_ROOT, ['.'], excluded_dirs_list) - sharded_files_to_scan = _ShardList(files_to_scan, 2000) - pool = multiprocessing.Pool() - offending_files_chunks = pool.map_async( - _FindCopyrightViolations, sharded_files_to_scan).get(999999) - pool.close() - pool.join() - # Flatten out the result - offending_files = \ - [item for sublist in offending_files_chunks for item in sublist] - - (unknown, missing, stale) = copyright_scanner.AnalyzeScanResults( - input_api, whitelisted_files, offending_files) - - if unknown: - print 'The following files contain a third-party license but are not in ' \ - 'a listed third-party directory and are not whitelisted. You must ' \ - 'add the following files to the whitelist.\n' \ - '(Note that if the code you are adding does not actually contain ' \ - 'any third-party code, it may contain the word "copyright", which ' \ - 'should be masked out, e.g. by writing it as "copy-right")\n%s' % \ - '\n'.join(sorted(unknown)) - if missing: - print 'The following files are whitelisted, but do not exist.\n%s' % \ - '\n'.join(sorted(missing)) - if stale: - print 'The following files are whitelisted unnecessarily. You must ' \ - 'remove the following files from the whitelist.\n%s' % \ - '\n'.join(sorted(stale)) - - if unknown: - code = ScanResult.Errors - elif stale or missing: - code = ScanResult.Warnings - else: - code = ScanResult.Ok - - problem_paths = sorted(set(unknown + missing + stale)) - return (code, problem_paths) - - -def _ReadFile(full_path, mode='rU'): - """Reads a file from disk. This emulates presubmit InputApi.ReadFile func. - Args: - full_path: The path of the file to read. - Returns: - The contents of the file as a string. - """ - - with open(full_path, mode) as f: - return f.read() - - -def _Scan(): - """Checks that license meta-data is present for all third-party code and - that all non third-party code doesn't contain external copyrighted code. - Returns: - ScanResult.Ok if everything is in order; - ScanResult.Warnings if there are non-fatal problems (e.g. stale whitelist - entries) - ScanResult.Errors otherwise. - """ - - third_party_dirs = licenses.FindThirdPartyDirsWithFiles(REPOSITORY_ROOT) - - problem_paths = [] - - # First, check designated third-party directories using src/tools/licenses.py. - all_licenses_valid = True - for path in sorted(third_party_dirs): - try: - licenses.ParseDir(path, REPOSITORY_ROOT) - except licenses.LicenseError, e: - print 'Got LicenseError "%s" while scanning %s' % (e, path) - problem_paths.append(path) - all_licenses_valid = False - - # Second, check for non-standard license text. - whitelisted_files = copyright_scanner.LoadWhitelistedFilesList(InputApi()) - licenses_check, more_problem_paths = _CheckLicenseHeaders( - third_party_dirs, whitelisted_files) - - problem_paths.extend(more_problem_paths) - - return (licenses_check if all_licenses_valid else ScanResult.Errors, - problem_paths) - - -class TemplateEntryGenerator(object): - def __init__(self): - self._toc_index = 0 - - def _ReadFileGuessEncoding(self, name): - contents = '' - with open(name, 'rb') as input_file: - contents = input_file.read() - try: - return contents.decode('utf8') - except UnicodeDecodeError: - pass - # If it's not UTF-8, it must be CP-1252. Fail otherwise. - return contents.decode('cp1252') - - def MetadataToTemplateEntry(self, metadata): - self._toc_index += 1 - return { - 'name': metadata['Name'], - 'url': metadata['URL'], - 'license_file': metadata['License File'], - 'license': self._ReadFileGuessEncoding(metadata['License File']), - 'toc_href': 'entry' + str(self._toc_index), - } - - -def GenerateNoticeFile(): - """Generates the contents of an Android NOTICE file for the third-party code. - This is used by the snapshot tool. - Returns: - A tuple of (input paths, contents of the NOTICE file). - """ - generator = TemplateEntryGenerator() - # Start from Chromium's LICENSE file - entries = [generator.MetadataToTemplateEntry({ - 'Name': 'The Chromium Project', - 'URL': 'http://www.chromium.org', - 'License File': os.path.join(REPOSITORY_ROOT, 'LICENSE') }) - ] - - third_party_dirs = licenses.FindThirdPartyDirsWithFiles(REPOSITORY_ROOT) - # We provide attribution for all third-party directories. - # TODO(mnaganov): Limit this to only code used by the WebView binary. - for directory in sorted(third_party_dirs): - try: - metadata = licenses.ParseDir(directory, REPOSITORY_ROOT, - require_license_file=False) - except licenses.LicenseError: - # Since this code is called during project files generation, - # we don't want to break the it. But we assume that release - # WebView apks are built using checkouts that pass - # 'webview_licenses.py scan' check, thus they don't contain - # projects with non-compatible licenses. - continue - license_file = metadata['License File'] - if license_file and license_file != licenses.NOT_SHIPPED: - entries.append(generator.MetadataToTemplateEntry(metadata)) - - entries.sort(key=lambda entry: entry['name']) - - license_file_list = sorted(set([entry['license_file'] for entry in entries])) - license_file_list = [os.path.relpath(p) for p in license_file_list] - env = jinja2.Environment( - loader=jinja2.FileSystemLoader(os.path.dirname(__file__)), - extensions=['jinja2.ext.autoescape']) - template = env.get_template('licenses_notice.tmpl') - notice_file_contents = template.render({'entries': entries}).encode('utf8') - return (license_file_list, notice_file_contents) - - -def main(): - class FormatterWithNewLines(optparse.IndentedHelpFormatter): - def format_description(self, description): - paras = description.split('\n') - formatted_paras = [textwrap.fill(para, self.width) for para in paras] - return '\n'.join(formatted_paras) + '\n' - - parser = optparse.OptionParser(formatter=FormatterWithNewLines(), - usage='%prog [options]') - parser.add_option('--json', help='Path to JSON output file') - build_utils.AddDepfileOption(parser) - parser.description = (__doc__ + - '\nCommands:\n' - ' scan Check licenses.\n' - 'Android NOTICE file.\n' - ' notice [file] Generate Android NOTICE file on ' - 'stdout or into |file|.\n' - ' display_copyrights Display autorship on the files' - ' using names provided via stdin.\n') - options, args = parser.parse_args() - if len(args) < 1: - parser.print_help() - return ScanResult.Errors - - if args[0] == 'scan': - scan_result, problem_paths = _Scan() - if scan_result == ScanResult.Ok: - print 'OK!' - if options.json: - with open(options.json, 'w') as f: - json.dump(problem_paths, f) - return scan_result - elif args[0] == 'notice': - license_file_list, notice_file_contents = GenerateNoticeFile() - if len(args) == 1: - print notice_file_contents - else: - with open(args[1], 'w') as output_file: - output_file.write(notice_file_contents) - if options.depfile: - assert args[1] - # Add in build.ninja so that the target will be considered dirty whenever - # gn gen is run. Otherwise, it will fail to notice new files being added. - # This is still no perfect, as it will fail if no build files are changed, - # but a new README.chromium / LICENSE is added. This shouldn't happen in - # practice however. - build_utils.WriteDepfile(options.depfile, args[1], - license_file_list + ['build.ninja']) - - return ScanResult.Ok - elif args[0] == 'display_copyrights': - files = sys.stdin.read().splitlines() - for f, c in \ - zip(files, copyright_scanner.FindCopyrights(InputApi(), '.', files)): - print f, '\t', ' / '.join(sorted(c)) - return ScanResult.Ok - parser.print_help() - return ScanResult.Errors - -if __name__ == '__main__': - sys.exit(main())
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index 1fb9216..f090447 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -1107,6 +1107,7 @@ "//components/quirks", "//components/signin/core/account_id", "//components/user_manager", + "//components/viz/test:test_support", "//content/public/browser", "//content/test:test_support", "//device/bluetooth", @@ -1457,11 +1458,13 @@ "//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", @@ -1534,7 +1537,9 @@ "//ash/public/cpp:ash_public_cpp", "//ash/test:test_support_without_content", "//base/test:test_support", + "//cc:test_support", "//cc/base", + "//components/viz/test:test_support", "//mojo/edk/embedder:headers", "//testing/gtest", "//testing/perf",
diff --git a/ash/system/network/network_icon.cc b/ash/system/network/network_icon.cc index f096341..b19b3a0 100644 --- a/ash/system/network/network_icon.cc +++ b/ash/system/network/network_icon.cc
@@ -21,12 +21,10 @@ #include "third_party/skia/include/core/SkPaint.h" #include "third_party/skia/include/core/SkPath.h" #include "ui/base/l10n/l10n_util.h" -#include "ui/gfx/canvas.h" #include "ui/gfx/color_palette.h" #include "ui/gfx/geometry/insets.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/size_conversions.h" -#include "ui/gfx/image/canvas_image_source.h" #include "ui/gfx/image/image_skia_operations.h" #include "ui/gfx/image/image_skia_source.h" #include "ui/gfx/paint_vector_icon.h" @@ -184,10 +182,6 @@ //------------------------------------------------------------------------------ // Utilities for generating icon images. -// 'NONE' will default to ARCS behavior where appropriate (e.g. no network or -// if a new type gets added). -enum ImageType { ARCS, BARS, NONE }; - // Amount to fade icons while connecting. const double kConnectingImageAlpha = 0.5; @@ -198,6 +192,14 @@ // Number of discrete images to use for alpha fade animation const int kNumFadeImages = 10; +// Padding between outside of icon and edge of the canvas, in dp. This value +// stays the same regardless of the canvas size. +static constexpr int kSignalStrengthImageInset = 2; + +// TODO(estade): share this alpha with other things in ash (battery, etc.). +// See crbug.com/623987 and crbug.com/632827 +static constexpr int kSignalStrengthImageBgAlpha = 0x4D; + SkColor GetDefaultColorForIconType(IconType icon_type) { return icon_type == ICON_TYPE_TRAY ? kTrayIconColor : kMenuIconColor; } @@ -285,141 +287,6 @@ DISALLOW_COPY_AND_ASSIGN(NetworkIconImageSource); }; -// Depicts a given signal strength using arcs (e.g. for WiFi connections) or -// bars (e.g. for cell connections). -class SignalStrengthImageSource : public gfx::CanvasImageSource { - public: - SignalStrengthImageSource(ImageType image_type, - IconType icon_type, - int signal_strength) - : CanvasImageSource(GetSizeForIconType(icon_type), false), - image_type_(image_type), - icon_type_(icon_type), - color_(GetDefaultColorForIconType(icon_type_)), - signal_strength_(signal_strength) { - if (image_type_ == NONE) - image_type_ = ARCS; - - DCHECK_GE(signal_strength, 0); - DCHECK_LT(signal_strength, kNumNetworkImages); - } - ~SignalStrengthImageSource() override {} - - void set_color(SkColor color) { color_ = color; } - - // gfx::CanvasImageSource: - void Draw(gfx::Canvas* canvas) override { - if (image_type_ == ARCS) - DrawArcs(canvas); - else - DrawBars(canvas); - } - - bool HasRepresentationAtAllScales() const override { return true; } - - private: - static gfx::Size GetSizeForIconType(IconType icon_type) { - int side = icon_type == ICON_TYPE_TRAY ? kTrayIconSize : kMenuIconSize; - return gfx::Size(side, side); - } - - void DrawArcs(gfx::Canvas* canvas) { - gfx::RectF oval_bounds((gfx::Rect(size()))); - oval_bounds.Inset(gfx::Insets(kIconInset)); - // Double the width and height. The new midpoint should be the former - // bottom center. - oval_bounds.Inset(-oval_bounds.width() / 2, 0, -oval_bounds.width() / 2, - -oval_bounds.height()); - - const SkScalar kAngleAboveHorizontal = 51.f; - const SkScalar kStartAngle = 180.f + kAngleAboveHorizontal; - const SkScalar kSweepAngle = 180.f - 2 * kAngleAboveHorizontal; - - cc::PaintFlags flags; - flags.setAntiAlias(true); - flags.setStyle(cc::PaintFlags::kFill_Style); - // Background. Skip drawing for full signal. - if (signal_strength_ != kNumNetworkImages - 1) { - flags.setColor(SkColorSetA(color_, kBgAlpha)); - canvas->sk_canvas()->drawArc(gfx::RectFToSkRect(oval_bounds), kStartAngle, - kSweepAngle, true, flags); - } - // Foreground (signal strength). - if (signal_strength_ != 0) { - flags.setColor(color_); - // Percent of the height of the background wedge that we draw the - // foreground wedge, indexed by signal strength. - static const float kWedgeHeightPercentages[] = {0.f, 0.375f, 0.5833f, - 0.75f, 1.f}; - const float wedge_percent = kWedgeHeightPercentages[signal_strength_]; - oval_bounds.Inset( - gfx::InsetsF((oval_bounds.height() / 2) * (1.f - wedge_percent))); - canvas->sk_canvas()->drawArc(gfx::RectFToSkRect(oval_bounds), kStartAngle, - kSweepAngle, true, flags); - } - } - - void DrawBars(gfx::Canvas* canvas) { - // Undo the canvas's device scaling and round values to the nearest whole - // number so we can draw on exact pixel boundaries. - const float dsf = canvas->UndoDeviceScaleFactor(); - auto scale = [dsf](SkScalar dimension) { - return std::round(dimension * dsf); - }; - - // Length of short side of an isosceles right triangle, in dip. - const SkScalar kFullTriangleSide = - SkIntToScalar(size().width()) - kIconInset * 2; - - auto make_triangle = [scale, kFullTriangleSide](SkScalar side) { - SkPath triangle; - triangle.moveTo(scale(kIconInset), scale(kIconInset + kFullTriangleSide)); - triangle.rLineTo(scale(side), 0); - triangle.rLineTo(0, -scale(side)); - triangle.close(); - return triangle; - }; - - cc::PaintFlags flags; - flags.setAntiAlias(true); - flags.setStyle(cc::PaintFlags::kFill_Style); - // Background. Skip drawing for full signal. - if (signal_strength_ != kNumNetworkImages - 1) { - flags.setColor(SkColorSetA(color_, kBgAlpha)); - canvas->DrawPath(make_triangle(kFullTriangleSide), flags); - } - // Foreground (signal strength). - if (signal_strength_ != 0) { - flags.setColor(color_); - // As a percentage of the bg triangle, the length of one of the short - // sides of the fg triangle, indexed by signal strength. - static const float kTriangleSidePercents[] = {0.f, 0.5f, 0.625f, 0.75f, - 1.f}; - canvas->DrawPath(make_triangle(kTriangleSidePercents[signal_strength_] * - kFullTriangleSide), - flags); - } - } - - ImageType image_type_; - IconType icon_type_; - SkColor color_; - - // On a scale of 0 to kNum{Arcs,Bars}Images - 1, how connected we are. - int signal_strength_; - - // Padding between outside of icon and edge of the canvas, in dp. This value - // stays the same regardless of the canvas size (which depends on - // |icon_type_|). - static constexpr int kIconInset = 2; - - // TODO(estade): share this alpha with other things in ash (battery, etc.). - // See crbug.com/623987 and crbug.com/632827 - static constexpr int kBgAlpha = 0x4D; - - DISALLOW_COPY_AND_ASSIGN(SignalStrengthImageSource); -}; - //------------------------------------------------------------------------------ // Utilities for extracting icon images. @@ -770,6 +637,134 @@ } // namespace //------------------------------------------------------------------------------ +// SignalStrengthImageSource + +SignalStrengthImageSource::SignalStrengthImageSource(ImageType image_type, + SkColor color, + const gfx::Size& size, + int signal_strength) + : CanvasImageSource(size, false), + image_type_(image_type /* is_opaque */), + color_(color), + signal_strength_(signal_strength) { + if (image_type_ == NONE) + image_type_ = ARCS; + + DCHECK_GE(signal_strength, 0); + DCHECK_LT(signal_strength, kNumNetworkImages); +} + +SignalStrengthImageSource::SignalStrengthImageSource(ImageType image_type, + IconType icon_type, + int signal_strength) + : SignalStrengthImageSource(image_type, + GetDefaultColorForIconType(icon_type), + GetSizeForIconType(icon_type), + signal_strength) {} + +SignalStrengthImageSource::~SignalStrengthImageSource() {} + +void SignalStrengthImageSource::set_color(SkColor color) { + color_ = color; +} + +// gfx::CanvasImageSource: +void SignalStrengthImageSource::Draw(gfx::Canvas* canvas) { + if (image_type_ == ARCS) + DrawArcs(canvas); + else + DrawBars(canvas); +} + +bool SignalStrengthImageSource::HasRepresentationAtAllScales() const { + return true; +} + +gfx::Size SignalStrengthImageSource::GetSizeForIconType(IconType icon_type) { + int side = icon_type == ICON_TYPE_TRAY ? kTrayIconSize : kMenuIconSize; + return gfx::Size(side, side); +} + +void SignalStrengthImageSource::DrawArcs(gfx::Canvas* canvas) { + gfx::RectF oval_bounds((gfx::Rect(size()))); + oval_bounds.Inset(gfx::Insets(kSignalStrengthImageInset)); + // Double the width and height. The new midpoint should be the former + // bottom center. + oval_bounds.Inset(-oval_bounds.width() / 2, 0, -oval_bounds.width() / 2, + -oval_bounds.height()); + + const SkScalar kAngleAboveHorizontal = 51.f; + const SkScalar kStartAngle = 180.f + kAngleAboveHorizontal; + const SkScalar kSweepAngle = 180.f - 2 * kAngleAboveHorizontal; + + cc::PaintFlags flags; + flags.setAntiAlias(true); + flags.setStyle(cc::PaintFlags::kFill_Style); + // Background. Skip drawing for full signal. + if (signal_strength_ != kNumNetworkImages - 1) { + flags.setColor(SkColorSetA(color_, kSignalStrengthImageBgAlpha)); + canvas->sk_canvas()->drawArc(gfx::RectFToSkRect(oval_bounds), kStartAngle, + kSweepAngle, true, flags); + } + // Foreground (signal strength). + if (signal_strength_ != 0) { + flags.setColor(color_); + // Percent of the height of the background wedge that we draw the + // foreground wedge, indexed by signal strength. + static constexpr float kWedgeHeightPercentages[] = {0.f, 0.375f, 0.5833f, + 0.75f, 1.f}; + const float wedge_percent = kWedgeHeightPercentages[signal_strength_]; + oval_bounds.Inset( + gfx::InsetsF((oval_bounds.height() / 2) * (1.f - wedge_percent))); + canvas->sk_canvas()->drawArc(gfx::RectFToSkRect(oval_bounds), kStartAngle, + kSweepAngle, true, flags); + } +} + +void SignalStrengthImageSource::DrawBars(gfx::Canvas* canvas) { + // Undo the canvas's device scaling and round values to the nearest whole + // number so we can draw on exact pixel boundaries. + const float dsf = canvas->UndoDeviceScaleFactor(); + auto scale = [dsf](SkScalar dimension) { + return std::round(dimension * dsf); + }; + + // Length of short side of an isosceles right triangle, in dip. + const SkScalar kFullTriangleSide = + SkIntToScalar(size().width()) - kSignalStrengthImageInset * 2; + + auto make_triangle = [scale, kFullTriangleSide](SkScalar side) { + SkPath triangle; + triangle.moveTo(scale(kSignalStrengthImageInset), + scale(kSignalStrengthImageInset + kFullTriangleSide)); + triangle.rLineTo(scale(side), 0); + triangle.rLineTo(0, -scale(side)); + triangle.close(); + return triangle; + }; + + cc::PaintFlags flags; + flags.setAntiAlias(true); + flags.setStyle(cc::PaintFlags::kFill_Style); + // Background. Skip drawing for full signal. + if (signal_strength_ != kNumNetworkImages - 1) { + flags.setColor(SkColorSetA(color_, kSignalStrengthImageBgAlpha)); + canvas->DrawPath(make_triangle(kFullTriangleSide), flags); + } + // Foreground (signal strength). + if (signal_strength_ != 0) { + flags.setColor(color_); + // As a percentage of the bg triangle, the length of one of the short + // sides of the fg triangle, indexed by signal strength. + static constexpr float kTriangleSidePercents[] = {0.f, 0.5f, 0.625f, 0.75f, + 1.f}; + canvas->DrawPath(make_triangle(kTriangleSidePercents[signal_strength_] * + kFullTriangleSide), + flags); + } +} + +//------------------------------------------------------------------------------ // Public interface gfx::ImageSkia GetImageForNetwork(const NetworkState* network,
diff --git a/ash/system/network/network_icon.h b/ash/system/network/network_icon.h index a7b2640..448f986 100644 --- a/ash/system/network/network_icon.h +++ b/ash/system/network/network_icon.h
@@ -9,6 +9,8 @@ #include "ash/ash_export.h" #include "base/strings/string16.h" +#include "ui/gfx/canvas.h" +#include "ui/gfx/image/canvas_image_source.h" #include "ui/gfx/image/image_skia.h" namespace chromeos { @@ -26,6 +28,46 @@ ICON_TYPE_MENU_LIST, // dark icons without VPN badges; separate status }; +// 'NONE' will default to ARCS behavior where appropriate (e.g. no network or +// if a new type gets added). +enum ImageType { ARCS, BARS, NONE }; + +// Depicts a given signal strength using arcs (e.g. for WiFi connections) or +// bars (e.g. for cell connections). +class SignalStrengthImageSource : public gfx::CanvasImageSource { + public: + ASH_EXPORT SignalStrengthImageSource(ImageType image_type, + SkColor color, + const gfx::Size& size, + int signal_strength); + + // This version intuits color and size from icon_type. + ASH_EXPORT SignalStrengthImageSource(ImageType image_type, + IconType icon_type, + int signal_strength); + + ~SignalStrengthImageSource() override; + + void set_color(SkColor color); + + // gfx::CanvasImageSource: + void Draw(gfx::Canvas* canvas) override; + bool HasRepresentationAtAllScales() const override; + + private: + static gfx::Size GetSizeForIconType(IconType icon_type); + void DrawArcs(gfx::Canvas* canvas); + void DrawBars(gfx::Canvas* canvas); + + ImageType image_type_; + SkColor color_; + + // On a scale of 0 to kNumNetworkImages - 1, how connected we are. + int signal_strength_; + + DISALLOW_COPY_AND_ASSIGN(SignalStrengthImageSource); +}; + // Gets the image for provided |network|. |network| must not be NULL. // |icon_type| determines the color theme and whether or not to show the VPN // badge. This caches badged icons per network per |icon_type|.
diff --git a/ash/test/DEPS b/ash/test/DEPS index 5178d95..f15a004 100644 --- a/ash/test/DEPS +++ b/ash/test/DEPS
@@ -1,5 +1,7 @@ include_rules = [ # In general files in this directory should not depend upon content. + "+cc/test", + "+components/viz/test", "+mojo/edk", ]
diff --git a/ash/test/ash_test_suite.cc b/ash/test/ash_test_suite.cc index a14aed95..76c38033 100644 --- a/ash/test/ash_test_suite.cc +++ b/ash/test/ash_test_suite.cc
@@ -4,6 +4,8 @@ #include "ash/test/ash_test_suite.h" +#include <set> + #include "ash/public/cpp/config.h" #include "ash/test/ash_test_environment.h" #include "ash/test/ash_test_helper.h" @@ -13,6 +15,9 @@ #include "base/metrics/statistics_recorder.h" #include "base/path_service.h" #include "build/build_config.h" +#include "cc/test/fake_output_surface.h" +#include "cc/test/test_context_provider.h" +#include "components/viz/test/test_layer_tree_frame_sink.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/resource/resource_bundle.h" #include "ui/base/ui_base_paths.h" @@ -22,6 +27,68 @@ namespace ash { namespace test { +namespace { + +class FrameSinkClient : public viz::TestLayerTreeFrameSinkClient { + public: + explicit FrameSinkClient( + scoped_refptr<cc::ContextProvider> display_context_provider) + : display_context_provider_(std::move(display_context_provider)) {} + + std::unique_ptr<cc::OutputSurface> CreateDisplayOutputSurface( + scoped_refptr<cc::ContextProvider> compositor_context_provider) override { + return cc::FakeOutputSurface::Create3d( + std::move(display_context_provider_)); + } + + void DisplayReceivedLocalSurfaceId( + const viz::LocalSurfaceId& local_surface_id) override {} + void DisplayReceivedCompositorFrame( + const cc::CompositorFrame& frame) override {} + void DisplayWillDrawAndSwap( + bool will_draw_and_swap, + const cc::RenderPassList& render_passes) override {} + void DisplayDidDrawAndSwap() override {} + + private: + scoped_refptr<cc::ContextProvider> display_context_provider_; + + DISALLOW_COPY_AND_ASSIGN(FrameSinkClient); +}; + +class AshTestContextFactory : public ui::FakeContextFactory { + public: + AshTestContextFactory() = default; + ~AshTestContextFactory() override = default; + + // ui::FakeContextFactory + void CreateLayerTreeFrameSink( + base::WeakPtr<ui::Compositor> compositor) override { + scoped_refptr<cc::TestContextProvider> context_provider = + cc::TestContextProvider::Create(); + std::unique_ptr<FrameSinkClient> frame_sink_client = + base::MakeUnique<FrameSinkClient>(context_provider); + constexpr bool synchronous_composite = false; + constexpr bool disable_display_vsync = false; + const double refresh_rate = GetRefreshRate(); + auto frame_sink = base::MakeUnique<viz::TestLayerTreeFrameSink>( + context_provider, cc::TestContextProvider::CreateWorker(), nullptr, + GetGpuMemoryBufferManager(), renderer_settings(), + base::ThreadTaskRunnerHandle::Get().get(), synchronous_composite, + disable_display_vsync, refresh_rate); + frame_sink->SetClient(frame_sink_client.get()); + compositor->SetLayerTreeFrameSink(std::move(frame_sink)); + frame_sink_clients_.insert(std::move(frame_sink_client)); + } + + private: + std::set<std::unique_ptr<viz::TestLayerTreeFrameSinkClient>> + frame_sink_clients_; + + DISALLOW_COPY_AND_ASSIGN(AshTestContextFactory); +}; + +} // namespace AshTestSuite::AshTestSuite(int argc, char** argv) : TestSuite(argc, argv) {} @@ -71,7 +138,7 @@ : aura::Env::Mode::LOCAL); if (is_mus || is_mash) { - context_factory_ = base::MakeUnique<ui::FakeContextFactory>(); + context_factory_ = base::MakeUnique<AshTestContextFactory>(); env_->set_context_factory(context_factory_.get()); env_->set_context_factory_private(nullptr); }
diff --git a/ash/test/ash_test_suite.h b/ash/test/ash_test_suite.h index d42ec0e..4fac428 100644 --- a/ash/test/ash_test_suite.h +++ b/ash/test/ash_test_suite.h
@@ -13,7 +13,7 @@ #include "ui/aura/env.h" namespace ui { -class FakeContextFactory; +class ContextFactory; } namespace ash { @@ -34,9 +34,9 @@ base::TestDiscardableMemoryAllocator discardable_memory_allocator_; - // Only used when running in Config::MUS, and is set as the context_factory + // Only used when running in mus/mash, and is set as the context_factory // on aura::Env. - std::unique_ptr<ui::FakeContextFactory> context_factory_; + std::unique_ptr<ui::ContextFactory> context_factory_; DISALLOW_COPY_AND_ASSIGN(AshTestSuite); };
diff --git a/base/BUILD.gn b/base/BUILD.gn index b1f6bcc..df4abcc 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -2723,11 +2723,8 @@ "test/android/javatests/src/org/chromium/base/test/util/TimeoutScale.java", "test/android/javatests/src/org/chromium/base/test/util/UserActionTester.java", "test/android/javatests/src/org/chromium/base/test/util/UrlUtils.java", - "test/android/javatests/src/org/chromium/base/test/util/parameter/BaseParameter.java", - "test/android/javatests/src/org/chromium/base/test/util/parameter/Parameter.java", - "test/android/javatests/src/org/chromium/base/test/util/parameter/Parameterizable.java", - "test/android/javatests/src/org/chromium/base/test/util/parameter/ParameterizedTest.java", - "test/android/javatests/src/org/chromium/base/test/util/parameter/parameters/MethodParameter.java", + "test/android/javatests/src/org/chromium/base/test/util/parameter/CommandLineParameter.java", + "test/android/javatests/src/org/chromium/base/test/util/parameter/SkipCommandLineParameterization.java", ] }
diff --git a/base/test/android/javatests/src/org/chromium/base/test/BaseActivityInstrumentationTestCase.java b/base/test/android/javatests/src/org/chromium/base/test/BaseActivityInstrumentationTestCase.java index 7937284..275671c 100644 --- a/base/test/android/javatests/src/org/chromium/base/test/BaseActivityInstrumentationTestCase.java +++ b/base/test/android/javatests/src/org/chromium/base/test/BaseActivityInstrumentationTestCase.java
@@ -7,24 +7,13 @@ import android.app.Activity; import android.test.ActivityInstrumentationTestCase2; -import org.chromium.base.test.util.parameter.BaseParameter; -import org.chromium.base.test.util.parameter.Parameter; -import org.chromium.base.test.util.parameter.Parameterizable; -import org.chromium.base.test.util.parameter.parameters.MethodParameter; - -import java.util.HashMap; -import java.util.Map; - /** * Base class for all Activity-based Instrumentation tests. * * @param <T> The Activity type. */ public class BaseActivityInstrumentationTestCase<T extends Activity> - extends ActivityInstrumentationTestCase2<T> implements Parameterizable { - private Parameter.Reader mParameterReader; - private Map<String, BaseParameter> mAvailableParameters; - + extends ActivityInstrumentationTestCase2<T> { /** * Creates a instance for running tests against an Activity of the given class. * @@ -33,57 +22,4 @@ public BaseActivityInstrumentationTestCase(Class<T> activityClass) { super(activityClass); } - - /** - * Creates the {@link Map} of available parameters for the test to use. - * - * @return a {@link Map} of {@link BaseParameter} objects. - */ - protected Map<String, BaseParameter> createAvailableParameters() { - Map<String, BaseParameter> availableParameters = new HashMap<>(); - availableParameters - .put(MethodParameter.PARAMETER_TAG, new MethodParameter(getParameterReader())); - return availableParameters; - } - - /** - * Gets the {@link Map} of available parameters that inherited classes can use. - * - * @return a {@link Map} of {@link BaseParameter} objects to set as the available parameters. - */ - public Map<String, BaseParameter> getAvailableParameters() { - return mAvailableParameters; - } - - /** - * Gets a specific parameter from the current test. - * - * @param parameterTag a string with the name of the {@link BaseParameter} we want. - * @return a parameter that extends {@link BaseParameter} that has the matching parameterTag. - */ - @SuppressWarnings("unchecked") - public <T extends BaseParameter> T getAvailableParameter(String parameterTag) { - return (T) mAvailableParameters.get(parameterTag); - } - - /** - * Setter method for {@link Parameter.Reader}. - * - * @param parameterReader the {@link Parameter.Reader} to set. - */ - public void setParameterReader(Parameter.Reader parameterReader) { - mParameterReader = parameterReader; - mAvailableParameters = createAvailableParameters(); - } - - /** - * Getter method for {@link Parameter.Reader} object to be used by test cases reading the - * parameter. - * - * @return the {@link Parameter.Reader} for the current {@link - * org.chromium.base.test.util.parameter.ParameterizedTest} being run. - */ - protected Parameter.Reader getParameterReader() { - return mParameterReader; - } }
diff --git a/base/test/android/javatests/src/org/chromium/base/test/BaseTestResult.java b/base/test/android/javatests/src/org/chromium/base/test/BaseTestResult.java index 7e31a5d..a80e0cc 100644 --- a/base/test/android/javatests/src/org/chromium/base/test/BaseTestResult.java +++ b/base/test/android/javatests/src/org/chromium/base/test/BaseTestResult.java
@@ -9,27 +9,15 @@ import android.os.Bundle; import android.os.SystemClock; -import junit.framework.AssertionFailedError; import junit.framework.TestCase; import junit.framework.TestResult; import org.chromium.base.Log; -import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.SkipCheck; -import org.chromium.base.test.util.parameter.BaseParameter; -import org.chromium.base.test.util.parameter.Parameter; -import org.chromium.base.test.util.parameter.Parameterizable; -import org.chromium.base.test.util.parameter.ParameterizedTest; -import java.io.PrintWriter; -import java.io.StringWriter; import java.lang.reflect.Method; import java.util.ArrayList; -import java.util.Arrays; -import java.util.Iterator; import java.util.List; -import java.util.Map; -import java.util.Map.Entry; /** * A test result that can skip tests. @@ -119,250 +107,7 @@ endTest(test); } else { - if (test instanceof Parameterizable) { - try { - runParameterized(test); - } catch (ThreadDeath e) { - Log.e(TAG, "Parameterized test run failed: %s", e); - } - } else { - super.run(test); - } - } - } - - @SuppressWarnings("unchecked") - private <T extends TestCase & Parameterizable> void runParameterized(TestCase test) - throws ThreadDeath { - T testCase = (T) test; - - // Prepare test. - Parameter.Reader parameterReader = new Parameter.Reader(test); - testCase.setParameterReader(parameterReader); - List<ParameterizedTest> parameterizedTests = parameterReader.getParameterizedTests(); - List<ParameterError> errors = new ArrayList<>(); - List<ParameterError> failures = new ArrayList<>(); - Map<String, BaseParameter> availableParameters = testCase.getAvailableParameters(); - - // Remove all @ParameterizedTests that contain CommandLineFlags.Parameter -- those - // are handled in test_runner.py as it is needed to re-launch the whole test activity - // to apply command-line args correctly. Note that this way we will also ignore any - // other parameters that may present in these @ParameterizedTests. - for (Iterator<ParameterizedTest> iter = parameterizedTests.iterator(); iter.hasNext();) { - ParameterizedTest paramTest = iter.next(); - for (Parameter p: paramTest.parameters()) { - if (CommandLineFlags.Parameter.PARAMETER_TAG.equals(p.tag())) { - iter.remove(); - } - } - } - - if (parameterizedTests.isEmpty()) { super.run(test); - } else { - // Start test. - startTest(testCase); - for (ParameterizedTest parameterizedTest : parameterizedTests) { - parameterReader.setCurrentParameterizedTest(parameterizedTest); - try { - setUpParameters(availableParameters, parameterReader); - testCase.runBare(); - tearDownParameters(availableParameters, parameterReader); - } catch (AssertionFailedError e) { - failures.add(new ParameterError(e, parameterizedTest)); - } catch (ThreadDeath e) { - throw e; - } catch (Throwable e) { - errors.add(new ParameterError(e, parameterizedTest)); - } - } - - // Generate failures and errors. - if (!failures.isEmpty()) { - addFailure(test, new ParameterizedTestFailure(failures)); - } - if (!errors.isEmpty()) { - addError(test, new ParameterizedTestError(errors)); - } - - // End test. - endTest(testCase); - } - } - - private static <T extends TestCase & Parameterizable> void setUpParameters( - Map<String, BaseParameter> availableParameters, Parameter.Reader reader) - throws Exception { - for (Entry<String, BaseParameter> entry : availableParameters.entrySet()) { - if (reader.getParameter(entry.getValue().getTag()) != null) { - entry.getValue().setUp(); - } - } - } - - private static <T extends TestCase & Parameterizable> void tearDownParameters( - Map<String, BaseParameter> availableParameters, Parameter.Reader reader) - throws Exception { - for (Entry<String, BaseParameter> entry : availableParameters.entrySet()) { - if (reader.getParameter(entry.getValue().getTag()) != null) { - entry.getValue().tearDown(); - } - } - } - - private static class ParameterError { - private final Throwable mThrowable; - private final ParameterizedTest mParameterizedTest; - - public ParameterError(Throwable throwable, ParameterizedTest parameterizedTest) { - mThrowable = throwable; - mParameterizedTest = parameterizedTest; - } - - private Throwable getThrowable() { - return mThrowable; - } - - private ParameterizedTest getParameterizedTest() { - return mParameterizedTest; - } - } - - private static class ParameterizedTestFailure extends AssertionFailedError { - public ParameterizedTestFailure(List<ParameterError> failures) { - super(new ParameterizedTestError(failures).toString()); - } - } - - private static class ParameterizedTestError extends Exception { - private final List<ParameterError> mErrors; - - public ParameterizedTestError(List<ParameterError> errors) { - mErrors = errors; - } - - /** - * Error output is as follows. - * - * DEFINITIONS: - * {{ERROR}} is the standard error output from - * {@link ParameterError#getThrowable().toString()}. - * {{PARAMETER_TAG}} is the {@link Parameter#tag()} value associated with the parameter. - * {{ARGUMENT_NAME}} is the {@link Parameter.Argument#name()} associated with the argument. - * {{ARGUMENT_VALUE}} is the value associated with the {@link Parameter.Argument}. This can - * be a String, int, String[], or int[]. - * - * With no {@link Parameter}: - * {{ERROR}} (with no parameters) - * - * With Single {@link Parameter} and no {@link Parameter.Argument}: - * {{ERROR}} (with parameters: {{PARAMETER_TAG}} with no arguments) - * - * With Single {@link Parameter} and one {@link Parameter.Argument}: - * {{ERROR}} (with parameters: {{PARAMETER_TAG}} with arguments: - * {{ARGUMENT_NAME}}={{ARGUMENT_VALUE}}) - * - * With Single {@link Parameter} and multiple {@link Parameter.Argument}s: - * {{ERROR}} (with parameters: {{PARAMETER_TAG}} with arguments: - * {{ARGUMENT_NAME}}={{ARGUMENT_VALUE}}, {{ARGUMENT_NAME}}={{ARGUMENT_VALUE}}, ...) - * - * DEFINITION: - * {{PARAMETER_ERROR}} is the output of a single {@link Parameter}'s error. Format: - * {{PARAMETER_TAG}} with arguments: {{ARGUMENT_NAME}}={{ARGUMENT_NAME}}, ... - * - * With Multiple {@link Parameter}s: - * {{ERROR}} (with parameters: {{PARAMETER_ERROR}}; {{PARAMETER_ERROR}}; ...) - * - * There will be a trace after this. And this is shown for every possible {@link - * ParameterizedTest} that is failed in the {@link ParameterizedTest.Set} if there is one. - * - * @return the error message and trace of the test failures. - */ - @Override - public String toString() { - if (mErrors.isEmpty()) return "\n"; - StringBuilder builder = new StringBuilder(); - Iterator<ParameterError> iter = mErrors.iterator(); - if (iter.hasNext()) { - builder.append(createErrorBuilder(iter.next())); - } - while (iter.hasNext()) { - builder.append("\n").append(createErrorBuilder(iter.next())); - } - return builder.toString(); - } - - private static StringBuilder createErrorBuilder(ParameterError error) { - StringBuilder builder = new StringBuilder("\n").append(error.getThrowable().toString()); - List<Parameter> parameters = - Arrays.asList(error.getParameterizedTest().parameters()); - if (parameters.isEmpty()) { - builder.append(" (with no parameters)"); - } else { - Iterator<Parameter> iter = parameters.iterator(); - builder.append(" (with parameters: ").append(createParameterBuilder(iter.next())); - while (iter.hasNext()) { - builder.append("; ").append(createParameterBuilder(iter.next())); - } - builder.append(")"); - } - return builder.append("\n").append(trace(error)); - } - - private static StringBuilder createParameterBuilder(Parameter parameter) { - StringBuilder builder = new StringBuilder(parameter.tag()); - List<Parameter.Argument> arguments = Arrays.asList(parameter.arguments()); - if (arguments.isEmpty()) { - builder.append(" with no arguments"); - } else { - Iterator<Parameter.Argument> iter = arguments.iterator(); - builder.append(" with arguments: ").append(createArgumentBuilder(iter.next())); - while (iter.hasNext()) { - builder.append(", ").append(createArgumentBuilder(iter.next())); - } - } - return builder; - } - - private static StringBuilder createArgumentBuilder(Parameter.Argument argument) { - StringBuilder builder = new StringBuilder(argument.name()).append("="); - if (!Parameter.ArgumentDefault.STRING.equals(argument.stringVar())) { - builder.append(argument.stringVar()); - } else if (Parameter.ArgumentDefault.INT != argument.intVar()) { - builder.append(argument.intVar()); - } else if (argument.stringArray().length > 0) { - builder.append(Arrays.toString(argument.stringArray())); - } else if (argument.intArray().length > 0) { - builder.append(Arrays.toString(argument.intArray())); - } - return builder; - } - - /** - * @return the trace without the error message - */ - private static StringBuilder trace(ParameterError error) { - StringWriter stringWriter = new StringWriter(); - PrintWriter writer = new PrintWriter(stringWriter); - error.getThrowable().printStackTrace(writer); - StringBuilder builder = new StringBuilder(stringWriter.getBuffer()); - return trim(deleteFirstLine(builder)); - } - - private static StringBuilder deleteFirstLine(StringBuilder builder) { - return builder.delete(0, builder.indexOf("\n") + 1); - } - - private static StringBuilder trim(StringBuilder sb) { - if (sb == null || sb.length() == 0) return sb; - for (int i = sb.length() - 1; i >= 0; i--) { - if (Character.isWhitespace(sb.charAt(i))) { - sb.deleteCharAt(i); - } else { - return sb; - } - } - return sb; } }
diff --git a/base/test/android/javatests/src/org/chromium/base/test/util/CommandLineFlags.java b/base/test/android/javatests/src/org/chromium/base/test/util/CommandLineFlags.java index a140ff1..bd23f26 100644 --- a/base/test/android/javatests/src/org/chromium/base/test/util/CommandLineFlags.java +++ b/base/test/android/javatests/src/org/chromium/base/test/util/CommandLineFlags.java
@@ -12,7 +12,6 @@ import org.chromium.base.BaseChromiumApplication; import org.chromium.base.CommandLine; import org.chromium.base.test.BaseTestResult.PreTestHook; -import org.chromium.base.test.util.parameter.BaseParameter; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; @@ -168,36 +167,4 @@ }; } - - /** - * Instructs the test runner to execute the test with modified command-line flags. - * Flags to add are specified using 'stringArray' of argument named 'add', - * and flags to remove -- in the argument named 'remove'. A parameter without arguments - * instructs to run the test with default command-line flags. - * - * Example: - * - * @ParameterizedTest.Set(tests = { - * @ParameterizedTest(parameters = { - * @Parameter( tag = CommandLineFlags.Parameter.PARAMETER_TAG)}), - * @ParameterizedTest(parameters = { - * @Parameter( tag = CommandLineFlags.Parameter.PARAMETER_TAG, - * arguments = { - * @Parameter.Argument( name = CommandLineFlags.Parameter.ADD_ARG, - * stringArray = {'arg1', 'arg2'}) - * })})}) - * - * Note that because the entire instrumentation test process needs to be restarted to apply - * modified command-line arguments, this annotation is handled by test_runner.py, not by - * BaseTestResult class. - */ - public static class Parameter extends BaseParameter { - public static final String PARAMETER_TAG = "cmdlinearg-parameter"; - public static final String ADD_ARG = "add"; - public static final String REMOVE_ARG = "remove"; - - public Parameter(org.chromium.base.test.util.parameter.Parameter.Reader parameterReader) { - super(PARAMETER_TAG, parameterReader); - } - } }
diff --git a/base/test/android/javatests/src/org/chromium/base/test/util/parameter/BaseParameter.java b/base/test/android/javatests/src/org/chromium/base/test/util/parameter/BaseParameter.java deleted file mode 100644 index bc4c8e4..0000000 --- a/base/test/android/javatests/src/org/chromium/base/test/util/parameter/BaseParameter.java +++ /dev/null
@@ -1,80 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.base.test.util.parameter; - -/** - * The attributes of a single parameter. - */ -public class BaseParameter { - private final String mTag; - private final Parameter.Reader mParameterReader; - - public BaseParameter(String tag, Parameter.Reader parameterReader) { - mTag = tag; - mParameterReader = parameterReader; - } - - public String getTag() { - return mTag; - } - - public String getStringArgument(String argumentName, String defaultString) { - Parameter.Argument parameterArgument = getArgument(argumentName); - return parameterArgument != null ? parameterArgument.stringVar() : defaultString; - } - - public String getStringArgument(String argumentName) { - Parameter.Argument parameterArgument = getArgument(argumentName); - checkArgumentExists(parameterArgument); - return parameterArgument.stringVar(); - } - - public int getIntArgument(String argumentName, int defaultInt) { - Parameter.Argument parameterArgument = getArgument(argumentName); - return parameterArgument != null ? parameterArgument.intVar() : defaultInt; - } - - public int getIntArgument(String argumentName) { - Parameter.Argument parameterArgument = getArgument(argumentName); - checkArgumentExists(parameterArgument); - return parameterArgument.intVar(); - } - - public String[] getStringArrayArgument(String argumentName, String[] defaultStringArray) { - Parameter.Argument parameterArgument = getArgument(argumentName); - return parameterArgument != null ? parameterArgument.stringArray() : defaultStringArray; - } - - public String[] getStringArrayArgument(String argumentName) { - Parameter.Argument parameterArgument = getArgument(argumentName); - checkArgumentExists(parameterArgument); - return parameterArgument.stringArray(); - } - - public int[] getIntArrayArgument(String argumentName, int[] defaultIntArray) { - Parameter.Argument parameterArgument = getArgument(argumentName); - return parameterArgument != null ? parameterArgument.intArray() : defaultIntArray; - } - - public int[] getIntArrayArgument(String argumentName) { - Parameter.Argument parameterArgument = getArgument(argumentName); - checkArgumentExists(parameterArgument); - return parameterArgument.intArray(); - } - - private Parameter.Argument getArgument(String argumentName) { - return mParameterReader.getParameterArgument(getTag(), argumentName); - } - - private static void checkArgumentExists(Parameter.Argument parameterArgument) { - if (parameterArgument == null) { - throw new IllegalArgumentException("Argument must be specified"); - } - } - - public void setUp() throws Exception {} - - public void tearDown() throws Exception {} -}
diff --git a/base/test/android/javatests/src/org/chromium/base/test/util/parameter/CommandLineParameter.java b/base/test/android/javatests/src/org/chromium/base/test/util/parameter/CommandLineParameter.java new file mode 100644 index 0000000..e6f5506 --- /dev/null +++ b/base/test/android/javatests/src/org/chromium/base/test/util/parameter/CommandLineParameter.java
@@ -0,0 +1,32 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.base.test.util.parameter; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * The annotation for parametering CommandLineFlags in JUnit3 instrumentation tests. + * + * E.g. if you add the following annotation to your test class: + * + * <code> + * @CommandLineParameter({"", FLAG_A, FLAG_B}) + * public class MyTestClass + * </code> + * + * The test harness would run the test 3 times with each of the flag added to commandline + * file. + */ + +@Inherited +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.METHOD, ElementType.TYPE}) +public @interface CommandLineParameter { + String[] value() default {}; +}
diff --git a/base/test/android/javatests/src/org/chromium/base/test/util/parameter/Parameter.java b/base/test/android/javatests/src/org/chromium/base/test/util/parameter/Parameter.java deleted file mode 100644 index 0d122d20..0000000 --- a/base/test/android/javatests/src/org/chromium/base/test/util/parameter/Parameter.java +++ /dev/null
@@ -1,199 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.base.test.util.parameter; - -import junit.framework.TestCase; - -import java.lang.annotation.Annotation; -import java.lang.reflect.AnnotatedElement; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -/** - * The annotation for an individual parameter in a {@link ParameterizedTest}. - * - * Contains all annotations required to run tests ParameterizedTests. - */ -public @interface Parameter { - String tag(); - Argument[] arguments() default {}; - - /** - * The annotation for an individual argument in a {@link Parameter}. - */ - @interface Argument { - String name(); - String stringVar() default Parameter.ArgumentDefault.STRING; - String[] stringArray() default {}; - int intVar() default Parameter.ArgumentDefault.INT; - int[] intArray() default {}; - } - - /** - * Default values for {@link Parameter.Argument}s. - * - * TODO (crbug.com/520232): Move to within {@link Parameter.Argument} and rename to Default - * when fixed. - */ - final class ArgumentDefault { - public static final String STRING = ""; - public static final int INT = 0; - } - - /** - * The tool to read Parameter related annotations. - */ - class Reader { - private Class mAnnotatedTestClass; - private AnnotatedElement mAnnotatedTestMethod; - private ParameterizedTest mParameterizedTest; - - public Reader(TestCase testCase) { - try { - mAnnotatedTestClass = testCase.getClass(); - mAnnotatedTestMethod = testCase.getClass().getMethod(testCase.getName()); - } catch (NoSuchMethodException e) { - // ignore - } - } - - /** - * Gets the {@link ParameterizedTest}s for the current test. - * - * @return a list of all the {@link ParameterizedTest}s for the current test. - */ - public List<ParameterizedTest> getParameterizedTests() { - return new ArrayList<ParameterizedTest>(getParameterizedTestsImpl()); - } - - /** - * Gets the {@link ParameterizedTest}s for the current test as immutable list. - * - * @return a list of all the {@link ParameterizedTest}s for the current test. - */ - private List<ParameterizedTest> getParameterizedTestsImpl() { - // Note: this must be aligned with Python code in - // instrumentation_test_instance.ParseCommandLineFlagParameters (regarding priority of - // ParameterizedTest.Set vs. ParameterizedTest) and in test_jar._GetProguardData - // (regarding composition of method annotations with class and superclasses - // annotations). Composition precedes selecting the annotation to process. - if (mAnnotatedTestMethod.isAnnotationPresent(ParameterizedTest.Set.class)) { - return Arrays.asList(getParameterizedTestSet(mAnnotatedTestMethod).tests()); - } - AnnotatedElement classWithAnnotation = findClassWithAnnotation( - mAnnotatedTestClass, ParameterizedTest.Set.class); - if (classWithAnnotation != null) { - return Arrays.asList(getParameterizedTestSet(classWithAnnotation).tests()); - } - if (mAnnotatedTestMethod.isAnnotationPresent(ParameterizedTest.class)) { - return Collections.singletonList(getParameterizedTest(mAnnotatedTestMethod)); - } - classWithAnnotation = findClassWithAnnotation( - mAnnotatedTestClass, ParameterizedTest.class); - if (classWithAnnotation != null) { - return Collections.singletonList(getParameterizedTest(classWithAnnotation)); - } - return Collections.emptyList(); - } - - /** - * Finds a class with the given annotation class starting from the given clazz. - * - * @return the class as {@link AnnotatedElement} or null if the class is not found. - */ - private AnnotatedElement findClassWithAnnotation( - Class<?> clazz, Class<? extends Annotation> annotationClass) { - if (clazz == null || clazz.isAnnotationPresent(annotationClass)) { - return clazz; - } else { - return findClassWithAnnotation(clazz.getSuperclass(), annotationClass); - } - } - - /** - * Gets the {@link ParameterizedTest} annotation of the current test. - * - * @return a {@link ParameterizedTest} of the current test's parameters. - */ - private ParameterizedTest getParameterizedTest(AnnotatedElement element) { - return element.getAnnotation(ParameterizedTest.class); - } - - /** - * Gets the {@link ParameterizedTest.Set} annotation of the current test. - * - * @return a {@link ParameterizedTest.Set} of the current test's parameters. - */ - private ParameterizedTest.Set getParameterizedTestSet(AnnotatedElement element) { - return element.getAnnotation(ParameterizedTest.Set.class); - } - - public boolean isParameterizedTest() { - return mAnnotatedTestMethod.isAnnotationPresent(ParameterizedTest.Set.class) - || mAnnotatedTestMethod.isAnnotationPresent(ParameterizedTest.class) - || findClassWithAnnotation( - mAnnotatedTestClass, ParameterizedTest.Set.class) != null - || findClassWithAnnotation( - mAnnotatedTestClass, ParameterizedTest.class) != null; - } - - public void setCurrentParameterizedTest(ParameterizedTest parameterizedTest) { - mParameterizedTest = parameterizedTest; - } - - /** - * Gets a {@link Parameter} object for a given target parameter. - * - * @param targetParameter the name of the {@link Parameter} to get in the current - * parameterized test. - * @return the {@link Parameter} for a given {@link ParameterizedTest} with the - * targetParameter as its tag if it exists, otherwise returns null. - */ - public Parameter getParameter(String targetParameter) { - if (mParameterizedTest == null || targetParameter == null) { - return null; - } - for (Parameter parameter : mParameterizedTest.parameters()) { - if (targetParameter.equals(parameter.tag())) { - return parameter; - } - } - return null; - } - - /** - * Gets the {@link Parameter.Argument} for a given {@link Parameter}. - * - * @param targetParameter the name of the {@link Parameter} to search for when looking for - * a {@link Parameter.Argument}. - * @param targetArgument the name of the {@link Parameter.Argument} to look for in the - * target {@link Parameter}. - * @return the {@link Parameter.Argument} for a given {@link ParameterizedTest} for the - * {@link Parameter} with the tag matching targetParameter and the argument name being - * targetArgument if it exists, otherwise returns null. - */ - public Parameter.Argument getParameterArgument(String targetParameter, - String targetArgument) { - Parameter parameter = getParameter(targetParameter); - return (parameter == null) ? null : getParameterArgument(parameter, targetArgument); - } - - public static Parameter.Argument getParameterArgument(Parameter parameter, - String targetArgument) { - if (targetArgument == null) { - return null; - } - for (Parameter.Argument argument : parameter.arguments()) { - if (targetArgument.equals(argument.name())) { - return argument; - } - } - return null; - } - } -} -
diff --git a/base/test/android/javatests/src/org/chromium/base/test/util/parameter/Parameterizable.java b/base/test/android/javatests/src/org/chromium/base/test/util/parameter/Parameterizable.java deleted file mode 100644 index f5c8ce8..0000000 --- a/base/test/android/javatests/src/org/chromium/base/test/util/parameter/Parameterizable.java +++ /dev/null
@@ -1,36 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.base.test.util.parameter; - -import java.util.Map; - -/** - * An interface to implement on test cases to run {@link ParameterizedTest}s. - */ -public interface Parameterizable { - - /** - * Gets the {@link Map} of available parameters for the test to use. - * - * @return a {@link Map} of {@link BaseParameter} objects. - */ - Map<String, BaseParameter> getAvailableParameters(); - - - /** - * Setter method for {@link Parameter.Reader}. - * - * @param parameterReader the {@link Parameter.Reader} to set. - */ - void setParameterReader(Parameter.Reader parameterReader); - - /** - * Gets a specific parameter from the current test. - * - * @param parameterTag a string with the name of the {@link BaseParameter} we want. - * @return a parameter that extends {@link BaseParameter} that has the matching parameterTag. - */ - <T extends BaseParameter> T getAvailableParameter(String parameterTag); -}
diff --git a/base/test/android/javatests/src/org/chromium/base/test/util/parameter/ParameterizedTest.java b/base/test/android/javatests/src/org/chromium/base/test/util/parameter/ParameterizedTest.java deleted file mode 100644 index 65e929fb..0000000 --- a/base/test/android/javatests/src/org/chromium/base/test/util/parameter/ParameterizedTest.java +++ /dev/null
@@ -1,32 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.base.test.util.parameter; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Inherited; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * The annotation for an individual set of {@link Parameter}s to run on a single test. - */ -@Inherited -@Retention(RetentionPolicy.RUNTIME) -@Target({ElementType.METHOD, ElementType.TYPE}) -public @interface ParameterizedTest { - Parameter[] parameters() default {}; - - /** - * The annotation that contains a set of {@link ParameterizedTest}s to run. A test method - * is attempted for every set of {@link Parameter}s in each {@link ParameterizedTest}. - */ - @Inherited - @Retention(RetentionPolicy.RUNTIME) - @Target({ElementType.METHOD, ElementType.TYPE}) - @interface Set { - ParameterizedTest[] tests() default {}; - } -}
diff --git a/base/test/android/javatests/src/org/chromium/base/test/util/parameter/SkipCommandLineParameterization.java b/base/test/android/javatests/src/org/chromium/base/test/util/parameter/SkipCommandLineParameterization.java new file mode 100644 index 0000000..2181031 --- /dev/null +++ b/base/test/android/javatests/src/org/chromium/base/test/util/parameter/SkipCommandLineParameterization.java
@@ -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. +package org.chromium.base.test.util.parameter; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * BaseJUnit4ClassRunner and host side test harness skips commandline parameterization for test + * classes or methods annotated with SkipCommandLineParameterization. + * + * This usually used by test that only runs in WebView javatests that only runs in sandboxed mode + * or single process mode. + */ + +@Inherited +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.METHOD, ElementType.TYPE}) +public @interface SkipCommandLineParameterization {}
diff --git a/base/test/android/javatests/src/org/chromium/base/test/util/parameter/parameters/MethodParameter.java b/base/test/android/javatests/src/org/chromium/base/test/util/parameter/parameters/MethodParameter.java deleted file mode 100644 index c314540..0000000 --- a/base/test/android/javatests/src/org/chromium/base/test/util/parameter/parameters/MethodParameter.java +++ /dev/null
@@ -1,21 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.base.test.util.parameter.parameters; - -import org.chromium.base.test.util.parameter.BaseParameter; -import org.chromium.base.test.util.parameter.Parameter; - -/** - * Allows for passing of certain parameters arguments to function when this parameter is used. - */ -public class MethodParameter extends BaseParameter { - public static final String PARAMETER_TAG = "method-parameter"; - - public MethodParameter(Parameter.Reader parameterReader) { - super(PARAMETER_TAG, parameterReader); - } -} - -
diff --git a/base/test/launcher/test_launcher.cc b/base/test/launcher/test_launcher.cc index 8959e1e0..e087d93 100644 --- a/base/test/launcher/test_launcher.cc +++ b/base/test/launcher/test_launcher.cc
@@ -1193,13 +1193,10 @@ CommandLine* command_line = CommandLine::ForCurrentProcess(); CommandLine::SwitchMap switches = command_line->GetSwitches(); - size_t jobs = 0U; + if (command_line->HasSwitch(switches::kTestLauncherJobs)) { + // If the number of test launcher jobs was specified, return that number. + size_t jobs = 0U; - if (command_line->HasSwitch(kGTestFilterFlag) && !BotModeEnabled()) { - // Do not run jobs in parallel by default if we are running a subset of - // the tests and if bot mode is off. - return 1U; - } else if (command_line->HasSwitch(switches::kTestLauncherJobs)) { if (!StringToSizeT( command_line->GetSwitchValueASCII(switches::kTestLauncherJobs), &jobs) || @@ -1207,10 +1204,13 @@ LOG(ERROR) << "Invalid value for " << switches::kTestLauncherJobs; return 0U; } - - return jobs; + } else if (command_line->HasSwitch(kGTestFilterFlag) && !BotModeEnabled()) { + // Do not run jobs in parallel by default if we are running a subset of + // the tests and if bot mode is off. + return 1U; } + // Default to the number of processor cores. return base::checked_cast<size_t>(SysInfo::NumberOfProcessors()); }
diff --git a/build/android/play_services/update.py b/build/android/play_services/update.py index d1ec955..5297b3cf 100755 --- a/build/android/play_services/update.py +++ b/build/android/play_services/update.py
@@ -47,7 +47,7 @@ LICENSE_FILE_NAME = 'LICENSE' ZIP_FILE_NAME = 'google_play_services_library.zip' -GMS_PACKAGE_ID = 'extra-google-m2repository' # used by sdk manager +GMS_PACKAGE_ID = 'extras;google;m2repository' # used by sdk manager LICENSE_PATTERN = re.compile(r'^Pkg\.License=(?P<text>.*)$', re.MULTILINE) @@ -256,9 +256,8 @@ with open(paths.source_prop, 'w') as prop_file: prop_file.write('Pkg.Revision=0.0.0\n') - sdk_manager = os.path.join(args.sdk_root, 'tools', 'android') - cmd = [sdk_manager, 'update', 'sdk', '--no-ui', '--filter', GMS_PACKAGE_ID] - cmd_helper.Call(cmd) + sdk_manager = os.path.join(args.sdk_root, 'tools', 'bin', 'sdkmanager') + cmd_helper.Call([sdk_manager, GMS_PACKAGE_ID]) # If no update is needed, it still returns successfully so we just do nothing return 0
diff --git a/build/android/pylib/instrumentation/instrumentation_test_instance.py b/build/android/pylib/instrumentation/instrumentation_test_instance.py index d6077404..2443384 100644 --- a/build/android/pylib/instrumentation/instrumentation_test_instance.py +++ b/build/android/pylib/instrumentation/instrumentation_test_instance.py
@@ -2,7 +2,6 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -import collections import copy import logging import os @@ -47,12 +46,12 @@ _EXTRA_TIMEOUT_SCALE = ( 'org.chromium.test.driver.OnDeviceInstrumentationDriver.TimeoutScale') -_PARAMETERIZED_TEST_ANNOTATION = 'ParameterizedTest' -_PARAMETERIZED_TEST_SET_ANNOTATION = 'ParameterizedTest$Set' +_SKIP_PARAMETERIZATION = 'SkipCommandLineParameterization' +_COMMANDLINE_PARAMETERIZATION = 'CommandLineParameter' _NATIVE_CRASH_RE = re.compile('(process|native) crash', re.IGNORECASE) _CMDLINE_NAME_SEGMENT_RE = re.compile( r' with(?:out)? \{[^\}]*\}') -_PICKLE_FORMAT_VERSION = 11 +_PICKLE_FORMAT_VERSION = 12 class MissingSizeAnnotationError(test_exception.TestException): @@ -157,56 +156,6 @@ return results -def ParseCommandLineFlagParameters(annotations): - """Determines whether the test is parameterized to be run with different - command-line flags. - - Args: - annotations: The annotations of the test. - - Returns: - If the test is parameterized, returns a list of named tuples - with lists of flags, e.g.: - - [(add=['--flag-to-add']), (remove=['--flag-to-remove']), ()] - - That means, the test must be run three times, the first time with - "--flag-to-add" added to command-line, the second time with - "--flag-to-remove" to be removed from command-line, and the third time - with default command-line args. If the same flag is listed both for adding - and for removing, it is left unchanged. - - If the test is not parametrized, returns None. - - """ - ParamsTuple = collections.namedtuple('ParamsTuple', ['add', 'remove']) - parameterized_tests = [] - if _PARAMETERIZED_TEST_SET_ANNOTATION in annotations: - if annotations[_PARAMETERIZED_TEST_SET_ANNOTATION]: - parameterized_tests = annotations[ - _PARAMETERIZED_TEST_SET_ANNOTATION].get('tests', []) - elif _PARAMETERIZED_TEST_ANNOTATION in annotations: - parameterized_tests = [annotations[_PARAMETERIZED_TEST_ANNOTATION]] - else: - return None - - result = [] - for pt in parameterized_tests: - if not pt: - continue - for p in pt['parameters']: - if p['tag'] == _COMMAND_LINE_PARAMETER: - to_add = [] - to_remove = [] - for a in p.get('arguments', []): - if a['name'] == 'add': - to_add = ['--%s' % f for f in a['stringArray']] - elif a['name'] == 'remove': - to_remove = ['--%s' % f for f in a['stringArray']] - result.append(ParamsTuple(to_add, to_remove)) - return result if result else None - - def FilterTests(tests, test_filter=None, annotations=None, excluded_annotations=None): """Filter a list of tests @@ -313,7 +262,6 @@ _SaveTestsToPickle(pickle_path, test_apk, tests) return tests - def _GetTestsFromPickle(pickle_path, jar_path): if not os.path.exists(pickle_path): raise TestListPickleException('%s does not exist.' % pickle_path) @@ -332,6 +280,7 @@ return pickle_data['TEST_METHODS'] +# TODO(yolandyan): remove this once the test listing from java runner lands def _GetTestsFromProguard(jar_path): p = proguard.Dump(jar_path) class_lookup = dict((c['class'], c) for c in p['classes']) @@ -443,12 +392,8 @@ The unique test name as a string. """ display_name = GetTestName(test, sep=sep) - if 'flags' in test: - flags = test['flags'] - if flags.add: - display_name = '%s with {%s}' % (display_name, ' '.join(flags.add)) - if flags.remove: - display_name = '%s without {%s}' % (display_name, ' '.join(flags.remove)) + if test.get('flags', [None])[0]: + display_name = '%s with %s' % (display_name, ' '.join(test['flags'])) return display_name @@ -574,23 +519,23 @@ self._test_package = self._test_apk.GetPackageName() all_instrumentations = self._test_apk.GetAllInstrumentations() - junit3_runners = [ + test_runners = [ x for x in all_instrumentations if ('true' not in x.get( 'chromium-junit4', ''))] - junit4_runners = [ + test_runners_junit4 = [ x for x in all_instrumentations if ('true' in x.get( 'chromium-junit4', ''))] - if len(junit3_runners) > 1: + if len(test_runners) > 1: logging.warning('This test apk has more than one JUnit3 instrumentation') - if len(junit4_runners) > 1: + if len(test_runners_junit4) > 1: logging.warning('This test apk has more than one JUnit4 instrumentation') self._test_runner = ( - junit3_runners[0]['android:name'] if junit3_runners else + test_runners[0]['android:name'] if test_runners else self.test_apk.GetInstrumentationName()) self._test_runner_junit4 = ( - junit4_runners[0]['android:name'] if junit4_runners else None) + test_runners_junit4[0]['android:name'] if test_runners_junit4 else None) self._package_info = None if self._apk_under_test: @@ -828,7 +773,7 @@ tests = GetAllTestsFromJar(self.test_jar) else: tests = GetAllTestsFromApk(self.test_apk.path) - inflated_tests = self._ParametrizeTestsWithFlags(self._InflateTests(tests)) + inflated_tests = self._ParameterizeTestsWithFlags(self._InflateTests(tests)) if self._test_runner_junit4 is None and any( t['is_junit4'] for t in inflated_tests): raise MissingJUnit4RunnerException() @@ -856,15 +801,19 @@ }) return inflated_tests - def _ParametrizeTestsWithFlags(self, tests): + def _ParameterizeTestsWithFlags(self, tests): new_tests = [] for t in tests: - parameters = ParseCommandLineFlagParameters(t['annotations']) + annotations = t['annotations'] + parameters = None + if (annotations.get(_COMMANDLINE_PARAMETERIZATION) + and _SKIP_PARAMETERIZATION not in annotations): + parameters = annotations[_COMMANDLINE_PARAMETERIZATION]['value'] if parameters: - t['flags'] = parameters[0] + t['flags'] = [parameters[0]] for p in parameters[1:]: parameterized_t = copy.copy(t) - parameterized_t['flags'] = p + parameterized_t['flags'] = [p] new_tests.append(parameterized_t) return tests + new_tests
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 b51330d2..7ba90321 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
@@ -319,7 +319,6 @@ extras = {} flags_to_add = [] - flags_to_remove = [] test_timeout_scale = None if self._test_instance.coverage_directory: coverage_basename = '%s.ec' % ('%s_group' % test[0]['method'] @@ -375,9 +374,8 @@ target = '%s/%s' % ( self._test_instance.test_package, self._test_instance.test_runner) extras['class'] = test_name - if 'flags' in test: - flags_to_add.extend(test['flags'].add) - flags_to_remove.extend(test['flags'].remove) + if 'flags' in test and test['flags']: + flags_to_add.extend(test['flags']) timeout = self._GetTimeoutFromAnnotations( test['annotations'], test_display_name) @@ -398,10 +396,9 @@ flags_to_add.append('--render-test-output-dir=%s' % render_tests_device_output_dir) - if flags_to_add or flags_to_remove: + if flags_to_add: self._CreateFlagChangerIfNeeded(device) - self._flag_changers[str(device)].PushFlags( - add=flags_to_add, remove=flags_to_remove) + self._flag_changers[str(device)].PushFlags(add=flags_to_add) time_ms = lambda: int(time.time() * 1e3) start_ms = time_ms() @@ -433,7 +430,7 @@ result_code, result_bundle, statuses, start_ms, duration_ms) def restore_flags(): - if flags_to_add or flags_to_remove: + if flags_to_add: self._flag_changers[str(device)].Restore() def restore_timeout_scale(): @@ -480,7 +477,7 @@ result.SetLink('logcat', logcat_url) # Update the result name if the test used flags. - if flags_to_add or flags_to_remove: + if flags_to_add: for r in results: if r.GetName() == test_name: r.SetName(test_display_name)
diff --git a/cc/BUILD.gn b/cc/BUILD.gn index d9ac8bd..7995d39 100644 --- a/cc/BUILD.gn +++ b/cc/BUILD.gn
@@ -841,7 +841,6 @@ "surfaces/referenced_surface_tracker_unittest.cc", "surfaces/surface_hittest_unittest.cc", "surfaces/surface_manager_ref_unittest.cc", - "surfaces/surface_sequence_generator_unittest.cc", "surfaces/surface_synchronization_unittest.cc", "surfaces/surface_unittest.cc",
diff --git a/cc/test/test_context_provider.cc b/cc/test/test_context_provider.cc index 37e6eaed..a34e731a7 100644 --- a/cc/test/test_context_provider.cc +++ b/cc/test/test_context_provider.cc
@@ -8,6 +8,7 @@ #include <stdint.h> #include <set> +#include <string> #include <vector> #include "base/bind.h" @@ -17,24 +18,90 @@ #include "cc/output/context_cache_controller.h" #include "cc/test/test_gles2_interface.h" #include "cc/test/test_web_graphics_context_3d.h" +#include "gpu/skia_bindings/grcontext_for_gles2_interface.h" #include "third_party/skia/include/gpu/GrContext.h" #include "third_party/skia/include/gpu/gl/GrGLInterface.h" namespace cc { +namespace { + +// Various tests rely on functionality (capabilities) enabled by these extension +// strings. +const char* const kExtensions[] = {"GL_EXT_stencil_wrap", + "GL_EXT_texture_format_BGRA8888", + "GL_OES_rgb8_rgba8"}; + +class TestGLES2InterfaceForContextProvider : public TestGLES2Interface { + public: + TestGLES2InterfaceForContextProvider() + : extension_string_(BuildExtensionString()) {} + ~TestGLES2InterfaceForContextProvider() override = default; + + // TestGLES2Interface: + const GLubyte* GetString(GLenum name) override { + switch (name) { + case GL_EXTENSIONS: + return reinterpret_cast<const GLubyte*>(extension_string_.c_str()); + case GL_VERSION: + return reinterpret_cast<const GrGLubyte*>("4.0 Null GL"); + case GL_SHADING_LANGUAGE_VERSION: + return reinterpret_cast<const GrGLubyte*>("4.20.8 Null GLSL"); + case GL_VENDOR: + return reinterpret_cast<const GrGLubyte*>("Null Vendor"); + case GL_RENDERER: + return reinterpret_cast<const GrGLubyte*>("The Null (Non-)Renderer"); + } + return nullptr; + } + const GrGLubyte* GetStringi(GrGLenum name, GrGLuint i) override { + if (name == GL_EXTENSIONS && i < arraysize(kExtensions)) + return reinterpret_cast<const GLubyte*>(kExtensions[i]); + return nullptr; + } + void GetIntegerv(GLenum name, GLint* params) override { + switch (name) { + case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: + *params = 8; + return; + default: + break; + } + TestGLES2Interface::GetIntegerv(name, params); + } + + private: + static std::string BuildExtensionString() { + std::string extension_string = kExtensions[0]; + for (size_t i = 1; i < arraysize(kExtensions); ++i) { + extension_string += " "; + extension_string += kExtensions[i]; + } + return extension_string; + } + + const std::string extension_string_; + + DISALLOW_COPY_AND_ASSIGN(TestGLES2InterfaceForContextProvider); +}; + +} // namespace + // static scoped_refptr<TestContextProvider> TestContextProvider::Create() { - return new TestContextProvider(base::MakeUnique<TestContextSupport>(), - base::MakeUnique<TestGLES2Interface>(), - TestWebGraphicsContext3D::Create()); + return new TestContextProvider( + base::MakeUnique<TestContextSupport>(), + base::MakeUnique<TestGLES2InterfaceForContextProvider>(), + TestWebGraphicsContext3D::Create()); } // static scoped_refptr<TestContextProvider> TestContextProvider::CreateWorker() { scoped_refptr<TestContextProvider> worker_context_provider( - new TestContextProvider(base::MakeUnique<TestContextSupport>(), - base::MakeUnique<TestGLES2Interface>(), - TestWebGraphicsContext3D::Create())); + new TestContextProvider( + base::MakeUnique<TestContextSupport>(), + base::MakeUnique<TestGLES2InterfaceForContextProvider>(), + TestWebGraphicsContext3D::Create())); // Worker contexts are bound to the thread they are created on. if (!worker_context_provider->BindToCurrentThread()) return nullptr; @@ -45,9 +112,10 @@ scoped_refptr<TestContextProvider> TestContextProvider::Create( std::unique_ptr<TestWebGraphicsContext3D> context) { DCHECK(context); - return new TestContextProvider(base::MakeUnique<TestContextSupport>(), - base::MakeUnique<TestGLES2Interface>(), - std::move(context)); + return new TestContextProvider( + base::MakeUnique<TestContextSupport>(), + base::MakeUnique<TestGLES2InterfaceForContextProvider>(), + std::move(context)); } // static @@ -65,9 +133,10 @@ std::unique_ptr<TestContextSupport> support) { DCHECK(context); DCHECK(support); - return new TestContextProvider(std::move(support), - base::MakeUnique<TestGLES2Interface>(), - std::move(context)); + return new TestContextProvider( + std::move(support), + base::MakeUnique<TestGLES2InterfaceForContextProvider>(), + std::move(context)); } TestContextProvider::TestContextProvider( @@ -141,20 +210,17 @@ DCHECK(context_thread_checker_.CalledOnValidThread()); if (gr_context_) - return gr_context_.get(); + return gr_context_->get(); - sk_sp<const GrGLInterface> gl_interface(GrGLCreateNullInterface()); - gr_context_ = sk_sp<::GrContext>(GrContext::Create( - kOpenGL_GrBackend, - reinterpret_cast<GrBackendContext>(gl_interface.get()))); - - cache_controller_->SetGrContext(gr_context_.get()); + gr_context_ = base::MakeUnique<skia_bindings::GrContextForGLES2Interface>( + context_gl_.get(), context3d_->test_capabilities()); + cache_controller_->SetGrContext(gr_context_->get()); // If GlContext is already lost, also abandon the new GrContext. if (ContextGL()->GetGraphicsResetStatusKHR() != GL_NO_ERROR) - gr_context_->abandonContext(); + gr_context_->get()->abandonContext(); - return gr_context_.get(); + return gr_context_->get(); } ContextCacheController* TestContextProvider::CacheController() { @@ -167,7 +233,7 @@ DCHECK(context_thread_checker_.CalledOnValidThread()); if (gr_context_) - gr_context_.get()->resetContext(state); + gr_context_->get()->resetContext(state); } base::Lock* TestContextProvider::GetLock() { @@ -179,7 +245,7 @@ if (!lost_context_callback_.is_null()) lost_context_callback_.Run(); if (gr_context_) - gr_context_->abandonContext(); + gr_context_->get()->abandonContext(); } TestWebGraphicsContext3D* TestContextProvider::TestContext3d() {
diff --git a/cc/test/test_context_provider.h b/cc/test/test_context_provider.h index 816c9ae..7d47431 100644 --- a/cc/test/test_context_provider.h +++ b/cc/test/test_context_provider.h
@@ -20,6 +20,10 @@ #include "gpu/command_buffer/client/gles2_interface_stub.h" #include "third_party/skia/include/core/SkRefCnt.h" +namespace skia_bindings { +class GrContextForGLES2Interface; +} + namespace cc { class TestWebGraphicsContext3D; class TestGLES2Interface; @@ -75,7 +79,7 @@ std::unique_ptr<TestContextSupport> support_; std::unique_ptr<TestWebGraphicsContext3D> context3d_; std::unique_ptr<TestGLES2Interface> context_gl_; - sk_sp<class GrContext> gr_context_; + std::unique_ptr<skia_bindings::GrContextForGLES2Interface> gr_context_; std::unique_ptr<ContextCacheController> cache_controller_; bool bound_ = false;
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc index 21047c5..d0a6196f 100644 --- a/cc/trees/layer_tree_host_impl_unittest.cc +++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -8805,7 +8805,7 @@ TEST_F(LayerTreeHostImplTest, ShutdownReleasesContext) { scoped_refptr<TestContextProvider> context_provider = TestContextProvider::Create(); - FrameSinkClient test_client_(context_provider); + FrameSinkClient test_client(context_provider); constexpr bool synchronous_composite = true; constexpr bool disable_display_vsync = false; @@ -8814,7 +8814,7 @@ context_provider, TestContextProvider::CreateWorker(), nullptr, nullptr, RendererSettings(), base::ThreadTaskRunnerHandle::Get().get(), synchronous_composite, disable_display_vsync, refresh_rate); - layer_tree_frame_sink->SetClient(&test_client_); + layer_tree_frame_sink->SetClient(&test_client); CreateHostImpl(DefaultSettings(), std::move(layer_tree_frame_sink));
diff --git a/chrome/android/java/AndroidManifest.xml b/chrome/android/java/AndroidManifest.xml index fa08d14..9b433783 100644 --- a/chrome/android/java/AndroidManifest.xml +++ b/chrome/android/java/AndroidManifest.xml
@@ -422,6 +422,16 @@ android:windowSoftInputMode="stateHidden|adjustPan" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|mcc|mnc|screenLayout|smallestScreenSize"> </activity> + {% if enable_vr == "true" %} + <activity android:name="org.chromium.chrome.browser.vr_shell.VrFirstRunActivity" + android:exported="false" + android:theme="@style/VrActivityTheme" + android:excludeFromRecents="true" + android:enableVrMode="@string/gvr_vr_mode_component" + android:configChanges="orientation|keyboardHidden|keyboard|screenSize|mcc|mnc|screenLayout|smallestScreenSize|uiMode"> + {{ self.supports_vr() }} + </activity> + {% endif %} <activity android:name="org.chromium.chrome.browser.signin.AccountSigninActivity" android:theme="@style/DialogWhenLarge" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|mcc|mnc|screenLayout|smallestScreenSize">
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java index 87b04a0..540a1a4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java
@@ -1143,6 +1143,16 @@ mToolbarManager = null; } + if (mBottomSheet != null) { + mBottomSheet.destroy(); + mBottomSheet = null; + } + + if (mBottomSheetContentController != null) { + mBottomSheetContentController.destroy(); + mBottomSheetContentController = null; + } + if (mTabModelsInitialized) { TabModelSelector selector = getTabModelSelector(); if (selector != null) selector.destroy();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenu.java b/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenu.java index 47b25c28..60d705e0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenu.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenu.java
@@ -63,6 +63,7 @@ private final int mVerticalFadeDistance; private final int mNegativeSoftwareVerticalOffset; private final int[] mTempLocation; + private final boolean mTranslateMenuItemsOnShow; private PopupWindow mPopup; private ListView mListView; @@ -82,9 +83,11 @@ * @param itemDividerHeight Desired height for the divider between app menu items. * @param handler AppMenuHandler receives callbacks from AppMenu. * @param res Resources object used to get dimensions and style attributes. + * @param translateMenuItemsOnShow Whether menu items should be translated during the animation + * that is run when the menu is shown. */ AppMenu(Menu menu, int itemRowHeight, int itemDividerHeight, AppMenuHandler handler, - Resources res) { + Resources res, boolean translateMenuItemsOnShow) { mMenu = menu; mItemRowHeight = itemRowHeight; @@ -100,6 +103,7 @@ mVerticalFadeDistance = res.getDimensionPixelSize(R.dimen.menu_vertical_fade_distance); mTempLocation = new int[2]; + mTranslateMenuItemsOnShow = translateMenuItemsOnShow; } /** @@ -237,8 +241,8 @@ // A List adapter for visible items in the Menu. The first row is added as a header to the // list view. - mAdapter = new AppMenuAdapter( - this, menuItems, LayoutInflater.from(context), highlightedItemId); + mAdapter = new AppMenuAdapter(this, menuItems, LayoutInflater.from(context), + highlightedItemId, mTranslateMenuItemsOnShow); ViewGroup contentView = (ViewGroup) LayoutInflater.from(context).inflate(R.layout.app_menu_layout, null);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuAdapter.java index e2b5d39..56214441 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuAdapter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuAdapter.java
@@ -103,6 +103,7 @@ private final int mNumMenuItems; private final Integer mHighlightedItemId; private final float mDpToPx; + private final boolean mTranslateMenuItemsOnShow; // Use a single PulseDrawable to spawn the other drawables so that the ConstantState gets // shared. This allows the animation to stay in step even as the views are recycled and the @@ -111,12 +112,13 @@ private PulseDrawable mHighlightDrawableSource; public AppMenuAdapter(AppMenu appMenu, List<MenuItem> menuItems, LayoutInflater inflater, - Integer highlightedItemId) { + Integer highlightedItemId, boolean translateMenuItemsOnShow) { mAppMenu = appMenu; mMenuItems = menuItems; mInflater = inflater; mHighlightedItemId = highlightedItemId; mNumMenuItems = menuItems.size(); + mTranslateMenuItemsOnShow = translateMenuItemsOnShow; mDpToPx = inflater.getContext().getResources().getDisplayMetrics().density; } @@ -376,15 +378,18 @@ * @return The {@link Animator}. */ private Animator buildStandardItemEnterAnimator(final View view, int position) { - final float offsetYPx = ENTER_STANDARD_ITEM_OFFSET_Y_DP * mDpToPx; final int startDelay = ENTER_ITEM_BASE_DELAY_MS + ENTER_ITEM_ADDL_DELAY_MS * position; AnimatorSet animation = new AnimatorSet(); - animation.playTogether( - ObjectAnimator.ofFloat(view, View.ALPHA, 0.f, 1.f), - ObjectAnimator.ofFloat(view, View.TRANSLATION_Y, offsetYPx, 0.f)); + if (mTranslateMenuItemsOnShow) { + final float offsetYPx = ENTER_STANDARD_ITEM_OFFSET_Y_DP * mDpToPx; + animation.playTogether(ObjectAnimator.ofFloat(view, View.ALPHA, 0.f, 1.f), + ObjectAnimator.ofFloat(view, View.TRANSLATION_Y, offsetYPx, 0.f)); + animation.setStartDelay(startDelay); + } else { + animation.playTogether(ObjectAnimator.ofFloat(view, View.ALPHA, 0.f, 1.f)); + } animation.setDuration(ENTER_ITEM_DURATION_MS); - animation.setStartDelay(startDelay); animation.setInterpolator(BakedBezierInterpolator.FADE_IN_CURVE); animation.addListener(new AnimatorListenerAdapter() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuHandler.java index 150a279..ca4c2e4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuHandler.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuHandler.java
@@ -18,6 +18,7 @@ import org.chromium.base.metrics.RecordUserAction; import org.chromium.chrome.R; +import org.chromium.chrome.browser.ChromeActivity; import java.util.ArrayList; @@ -139,8 +140,10 @@ Drawable itemDivider = a.getDrawable(1); int itemDividerHeight = itemDivider != null ? itemDivider.getIntrinsicHeight() : 0; a.recycle(); + boolean translateMenuItemsOnShow = !(mActivity instanceof ChromeActivity) + || ((ChromeActivity) mActivity).getBottomSheet() == null; mAppMenu = new AppMenu(mMenu, itemRowHeight, itemDividerHeight, this, - mActivity.getResources()); + mActivity.getResources(), translateMenuItemsOnShow); mAppMenuDragHelper = new AppMenuDragHelper(mActivity, mAppMenu, itemRowHeight); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencer.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencer.java index 3de96e67..de4082e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencer.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencer.java
@@ -29,6 +29,7 @@ import org.chromium.chrome.browser.signin.SigninManager; import org.chromium.chrome.browser.util.FeatureUtilities; import org.chromium.chrome.browser.util.IntentUtils; +import org.chromium.chrome.browser.vr_shell.VrShellDelegate; import org.chromium.components.signin.AccountManagerHelper; import org.chromium.components.signin.ChromeSigninController; @@ -396,12 +397,19 @@ } } + boolean isVrIntent = VrShellDelegate.isVrIntent(intent); + if (isVrIntent) { + // Remove VR-specific extras from the intent to Chrome because we don't want the + // VR intent to auto-present after the FRE is complete. + VrShellDelegate.removeVrExtras(intent); + } // Add a PendingIntent so that the intent used to launch Chrome will be resent when // First Run is completed or canceled. addPendingIntent(caller, freIntent, intent, requiresBroadcast); freIntent.putExtra(FirstRunActivity.EXTRA_FINISH_ON_TOUCH_OUTSIDE, true); if (!(caller instanceof Activity)) freIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + if (isVrIntent) freIntent = VrShellDelegate.setupVrFreIntent(caller, freIntent); IntentUtils.safeStartActivity(caller, freIntent); } else { // First Run requires that the Intent contains NEW_TASK so that it doesn't sit on top
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrFirstRunActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrFirstRunActivity.java new file mode 100644 index 0000000..add3c6cb --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrFirstRunActivity.java
@@ -0,0 +1,74 @@ +// 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.vr_shell; + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.os.Handler; + +import org.chromium.chrome.browser.util.IntentUtils; + +/** + * Handles the DOFF flow when Chrome is launched in VR mode and the FRE is not complete. This is + * needed because VrCore doesn't allow calling DOFF from a non-active VR activity (b/63435686), so + * we can't do it from {@link FirstRunActivity}. The android:enableVrMode attribute in the manifest + * makes this a VR activity allowing us to call DOFF before triggering the standard 2D FRE flow. + * This should be removed when b/63435686 is fixed. + */ +public class VrFirstRunActivity extends Activity { + private static final long SHOW_DOFF_TIMEOUT_MS = 500; + + private VrDaydreamApi mApi; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + assert VrShellDelegate.isVrIntent(getIntent()); + VrClassesWrapper wrapper = VrShellDelegate.createVrClassesWrapper(); + if (wrapper == null) { + showFre(); + return; + } + + // VrCore version M21 allows a transitioning VR activity to call DOFF and requires that + // we set VR mode programmatically. Up until then, this hack of having a pure VR activity + // works, but there's still a race every now and then that causes Chrome to crash and + // that's why we have a timeout below before we call DOFF. Redundantly setting VR mode + // here ensures that this never happens for users running the latest version of VrCore. + wrapper.setVrModeEnabled(this, true); + mApi = wrapper.createVrDaydreamApi(this); + if (!mApi.isDaydreamCurrentViewer()) { + showFre(); + return; + } + // Show DOFF with a timeout so that this activity has enough time to be the active VR app. + new Handler().postDelayed(new Runnable() { + @Override + public void run() { + mApi.exitFromVr(VrShellDelegate.EXIT_VR_RESULT, new Intent()); + } + }, SHOW_DOFF_TIMEOUT_MS); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent intent) { + if (requestCode != VrShellDelegate.EXIT_VR_RESULT) return; + if (resultCode == Activity.RESULT_OK) { + showFre(); + return; + } + finish(); + mApi.launchVrHomescreen(); + } + + private void showFre() { + // Start the actual 2D FRE if the user successfully exited VR. + Intent freIntent = (Intent) IntentUtils.safeGetParcelableExtra( + getIntent(), VrShellDelegate.VR_FRE_INTENT_EXTRA); + IntentUtils.safeStartActivity(this, freIntent); + finish(); + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java index 3d675a7..0652f6c73 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java
@@ -94,6 +94,7 @@ private static final String DAYDREAM_VR_EXTRA = "android.intent.extra.VR_LAUNCH"; private static final String DAYDREAM_HOME_PACKAGE = "com.google.android.vr.home"; + static final String VR_FRE_INTENT_EXTRA = "org.chromium.chrome.browser.vr_shell.VR_FRE"; // Linter and formatter disagree on how the line below should be formatted. /* package */ @@ -420,7 +421,7 @@ } @SuppressWarnings("unchecked") - private static VrClassesWrapper createVrClassesWrapper() { + /* package */ static VrClassesWrapper createVrClassesWrapper() { try { Class<? extends VrClassesWrapper> vrClassesBuilderClass = (Class<? extends VrClassesWrapper>) Class.forName( @@ -484,6 +485,13 @@ return ChromeFeatureList.isEnabled(ChromeFeatureList.VR_SHELL); } + /** + * @return Whether or not VR is supported on this platform. + */ + private static boolean isVrEnabled() { + return getVrClassesWrapper() != null; + } + private class VSyncEstimator { private static final long NANOS_PER_SECOND = 1000000000; @@ -869,12 +877,33 @@ } /** + * @return An intent that will launch a VR activity that will prompt the + * user to take off their headset and foward the freIntent to the standard + * 2D FRE activity. + */ + public static Intent setupVrFreIntent(Context context, Intent freIntent) { + if (!isVrEnabled()) return freIntent; + Intent intent = new Intent(); + intent.setClassName(context, VrFirstRunActivity.class.getName()); + intent.putExtra(VR_FRE_INTENT_EXTRA, new Intent(freIntent)); + intent.putExtra(DAYDREAM_VR_EXTRA, true); + return intent; + } + + /** * @return Whether or not the given intent is a VR-specific intent. */ public static boolean isVrIntent(Intent intent) { return IntentUtils.safeGetBooleanExtra(intent, DAYDREAM_VR_EXTRA, false); } + /* + * Remove VR-specific extras from the given intent. + */ + public static void removeVrExtras(Intent intent) { + intent.removeExtra(DAYDREAM_VR_EXTRA); + } + /** * @return Options that a VR-specific Chrome activity should be launched with. */ @@ -1066,7 +1095,7 @@ if (mInVr) mVSyncEstimator.pause(); - cancelPendingVrEntry(); + if (!mInVr) cancelPendingVrEntry(); // When the active web page has a vrdisplayactivate event handler, // mListeningForWebVrActivate should be set to true, which means a vrdisplayactive event
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java index c73dc37..7f3eed3d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java
@@ -245,6 +245,9 @@ /** Whether or not the back button was used to enter the tab switcher. */ private boolean mBackButtonDismissesChrome; + /** Whether {@link #destroy()} has been called. **/ + private boolean mIsDestroyed; + /** * An interface defining content that can be displayed inside of the bottom sheet for Chrome * Home. @@ -488,6 +491,16 @@ } /** + * Called when the activity containing the {@link BottomSheet} is destroyed. + */ + public void destroy() { + mIsDestroyed = true; + mIsTouchEnabled = false; + mObservers.clear(); + endAnimations(); + } + + /** * Handle a back press event. * - If the navigation stack is empty, the sheet will be opened to the half state. * - If the tab switcher is visible, {@link ChromeActivity} will handle the event. @@ -530,6 +543,13 @@ setSheetState(BottomSheet.SHEET_STATE_HALF, true); } + /** Immediately end all animations and null the animators. */ + public void endAnimations() { + if (mSettleAnimator != null) mSettleAnimator.end(); + mSettleAnimator = null; + endTransitionAnimations(); + } + /** * Immediately end the bottom sheet content transition animations and null the animator. */ @@ -895,6 +915,8 @@ mContentSwapAnimatorSet.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { + if (mIsDestroyed) return; + mSheetContent = content; for (BottomSheetObserver o : mObservers) { o.onSheetContentChanged(content); @@ -1094,6 +1116,8 @@ mSettleAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animator) { + if (mIsDestroyed) return; + mSettleAnimator = null; setInternalCurrentState(targetState); mTargetState = SHEET_STATE_NONE; @@ -1491,12 +1515,4 @@ mHasShownTextBubble = true; preferences.edit().putBoolean(BOTTOM_SHEET_HELP_BUBBLE_SHOWN, true).apply(); } - - /** Ends all animations. */ - @VisibleForTesting - public void endAnimationsForTests() { - if (mSettleAnimator != null) mSettleAnimator.end(); - mSettleAnimator = null; - endTransitionAnimations(); - } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetContentController.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetContentController.java index 3a6cc75..7d321f806 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetContentController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetContentController.java
@@ -34,6 +34,7 @@ import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver; import org.chromium.chrome.browser.tabmodel.TabModel; import org.chromium.chrome.browser.tabmodel.TabModelSelector; +import org.chromium.chrome.browser.tabmodel.TabModelSelectorObserver; import org.chromium.chrome.browser.util.MathUtils; import org.chromium.chrome.browser.widget.bottomsheet.BottomSheet.BottomSheetContent; @@ -103,7 +104,7 @@ if (mSelectedItemId != 0 && mSelectedItemId != R.id.action_home) { showBottomSheetContent(R.id.action_home); } else { - clearBottomSheetContents(); + clearBottomSheetContents(false); } // TODO(twellington): determine a policy for destroying the // SuggestionsBottomSheetContent. @@ -122,7 +123,7 @@ } if (mBottomSheet.getSheetState() == BottomSheet.SHEET_STATE_PEEK) { - clearBottomSheetContents(); + clearBottomSheetContents(false); } } @@ -142,6 +143,7 @@ private boolean mShouldOpenSheetOnNextContentChange; private PlaceholderSheetContent mPlaceholderContent; private boolean mOmniboxHasFocus; + private TabModelSelectorObserver mTabModelSelectorObserver; public BottomSheetContentController(Context context, AttributeSet atts) { super(context, atts); @@ -149,6 +151,19 @@ mPlaceholderContent = new PlaceholderSheetContent(context); } + /** Called when the activity containing the bottom sheet is destroyed. */ + public void destroy() { + clearBottomSheetContents(true); + if (mPlaceholderContent != null) { + mPlaceholderContent.destroy(); + mPlaceholderContent = null; + } + if (mTabModelSelector != null) { + mTabModelSelector.removeObserver(mTabModelSelectorObserver); + mTabModelSelector = null; + } + } + /** * Initializes the {@link BottomSheetContentController}. * @param bottomSheet The {@link BottomSheet} associated with this bottom nav. @@ -162,7 +177,7 @@ mBottomSheet.addObserver(mBottomSheetObserver); mActivity = activity; mTabModelSelector = tabModelSelector; - mTabModelSelector.addObserver(new EmptyTabModelSelectorObserver() { + mTabModelSelectorObserver = new EmptyTabModelSelectorObserver() { @Override public void onTabModelSelected(TabModel newModel, TabModel oldModel) { updateVisuals(newModel.isIncognito()); @@ -176,7 +191,8 @@ mBottomSheetContents.remove(INCOGNITO_HOME_ID); } } - }); + }; + mTabModelSelector.addObserver(mTabModelSelectorObserver); Resources res = getContext().getResources(); mDistanceBelowToolbarPx = controlContainerHeight @@ -349,12 +365,14 @@ return mSelectedItemId; } - public void clearBottomSheetContents() { + private void clearBottomSheetContents(boolean destroyHomeContent) { Iterator<Entry<Integer, BottomSheetContent>> contentIterator = mBottomSheetContents.entrySet().iterator(); while (contentIterator.hasNext()) { Entry<Integer, BottomSheetContent> entry = contentIterator.next(); - if (entry.getKey() == R.id.action_home || entry.getKey() == INCOGNITO_HOME_ID) { + if (!destroyHomeContent + && (entry.getKey() == R.id.action_home + || entry.getKey() == INCOGNITO_HOME_ID)) { continue; }
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni index 46e91dee..ebabaca5 100644 --- a/chrome/android/java_sources.gni +++ b/chrome/android/java_sources.gni
@@ -1168,6 +1168,7 @@ "java/src/org/chromium/chrome/browser/vr_shell/VrDaydreamApi.java", "java/src/org/chromium/chrome/browser/vr_shell/VrFeedbackStatus.java", "java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java", + "java/src/org/chromium/chrome/browser/vr_shell/VrFirstRunActivity.java", "java/src/org/chromium/chrome/browser/vr_shell/VrShell.java", "java/src/org/chromium/chrome/browser/webapps/ActivityAssigner.java", "java/src/org/chromium/chrome/browser/webapps/AddToHomescreenDialog.java", @@ -1314,13 +1315,6 @@ chrome_test_java_sources = [ "javatests/src/org/chromium/chrome/browser/compositor/CompositorVisibilityTest.java", - "javatests/src/org/chromium/base/test/util/parameter/ParameterizedTestAnnotationTest.java", - "javatests/src/org/chromium/base/test/util/parameter/ParameterizedTestClassAnnotationInheritanceTest.java", - "javatests/src/org/chromium/base/test/util/parameter/ParameterizedTestClassAnnotationParameterSetAndTest.java", - "javatests/src/org/chromium/base/test/util/parameter/ParameterizedTestClassAnnotationParametersTest.java", - "javatests/src/org/chromium/base/test/util/parameter/ParameterizedTestClassAnnotationParametersTestSetInheritanceTest.java", - "javatests/src/org/chromium/base/test/util/parameter/ParameterizedTestClassAnnotationParametersTestSetTest.java", - "javatests/src/org/chromium/base/test/util/parameter/ParameterizedTestClassAnnotationTest.java", "javatests/src/org/chromium/chrome/browser/AudioTest.java", "javatests/src/org/chromium/chrome/browser/BackgroundSyncLauncherTest.java", "javatests/src/org/chromium/chrome/browser/BindingManagerIntegrationTest.java", @@ -1718,10 +1712,8 @@ "javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetObserverTest.java", "javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetNewTabControllerTest.java", "javatests/src/org/chromium/chrome/browser/widget/findinpage/FindTest.java", - "javatests/src/org/chromium/chrome/test/ParametersOnMultiTest.java", "javatests/src/org/chromium/chrome/test/crash/IntentionalCrashTest.java", "javatests/src/org/chromium/chrome/test/util/ChromeSigninUtilsTest.java", - "javatests/src/org/chromium/chrome/test/util/parameters/SigninParametersTest.java", ] chrome_junit_test_java_sources = [
diff --git a/chrome/android/javatests/src/org/chromium/base/test/util/parameter/ParameterizedTestAnnotationTest.java b/chrome/android/javatests/src/org/chromium/base/test/util/parameter/ParameterizedTestAnnotationTest.java deleted file mode 100644 index ae133dc..0000000 --- a/chrome/android/javatests/src/org/chromium/base/test/util/parameter/ParameterizedTestAnnotationTest.java +++ /dev/null
@@ -1,388 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.base.test.util.parameter; - -import android.app.Activity; -import android.support.test.filters.SmallTest; -import android.test.MoreAsserts; - -import org.chromium.base.test.BaseActivityInstrumentationTestCase; -import org.chromium.base.test.util.parameter.parameters.MethodParameter; - -/** - * Tester class for the {@link ParameterizedTest} annotation and the {@link ParameterizedTest.Set} - * annotation. - * - * Also, tests the {@link MethodParameter} parameter. - */ -public class ParameterizedTestAnnotationTest extends - BaseActivityInstrumentationTestCase<Activity> { - public ParameterizedTestAnnotationTest() { - super(Activity.class); - } - - @SmallTest - public void testNoParameterizedTestAnnotation() { - assertFalse("This is a parameterized test when it should not be.", getParameterReader() - .isParameterizedTest()); - assertNull("someParameter should not exist.", getParameterReader() - .getParameter("someParameter")); - assertNull("someParameterArgument should not exist.", getParameterReader() - .getParameterArgument("someParameter", "someParameterArgument")); - } - - @SmallTest - @ParameterizedTest() - public void testEmptyParameterizedTestAnnotation() { - assertTrue("This is not a parameterized test.", getParameterReader() - .isParameterizedTest()); - assertNull("someParameter should not exist.", getParameterReader() - .getParameter("someParameter")); - assertNull("someParameterArgument should not exist.", getParameterReader() - .getParameterArgument("someParameter", "someParameterArgument")); - } - - @SmallTest - @ParameterizedTest(parameters = {}) - public void testParameterizedTestWithEmptyParameters() { - assertTrue("This is not a parameterized test.", getParameterReader() - .isParameterizedTest()); - assertNull("someParameter should not exist.", getParameterReader() - .getParameter("someParameter")); - assertNull("someParameterArgument should not exist.", getParameterReader() - .getParameterArgument("someParameter", "someParameterArgument")); - } - - @SmallTest - @ParameterizedTest(parameters = {}) - public void testParameterDoesNotExist() { - Parameter parameter = getParameterReader().getParameter(MethodParameter.PARAMETER_TAG); - assertNull("method-parameter should not exist.", parameter); - } - - @SmallTest - @ParameterizedTest(parameters = {@Parameter(tag = MethodParameter.PARAMETER_TAG)}) - public void testGetParameter() { - String expected = "method-parameter"; - String actual = getParameterReader().getParameter(MethodParameter.PARAMETER_TAG).tag(); - assertEquals("Parameter tag did not match expected.", expected, actual); - } - - @SmallTest - @ParameterizedTest(parameters = {@Parameter(tag = MethodParameter.PARAMETER_TAG)}) - public void testParameterArgumentDoesNotExist() { - Parameter.Argument actual = getArgument("arg"); - assertNull("arg should not exist.", actual); - } - - @SmallTest - @ParameterizedTest(parameters = { - @Parameter(tag = MethodParameter.PARAMETER_TAG, - arguments = {@Parameter.Argument(name = "string", stringVar = "value")})}) - public void testMethodParametersWithOneStringValue() { - String expected = "value"; - String actual = getArgument("string").stringVar(); - assertEquals(mismatchMessage("string"), expected, actual); - } - - @SmallTest - @ParameterizedTest(parameters = { - @Parameter(tag = MethodParameter.PARAMETER_TAG, - arguments = {@Parameter.Argument(name = "int", intVar = 0)})}) - public void testMethodParametersWithOneIntValue() { - int expected = 0; - int actual = getArgument("int").intVar(); - assertEquals(mismatchMessage("int"), expected, actual); - } - - @SmallTest - @ParameterizedTest(parameters = { - @Parameter(tag = MethodParameter.PARAMETER_TAG, - arguments = { - @Parameter.Argument(name = "intArray", intArray = {5, 10, -6, 0, -1})}) - }) - public void testMethodParametersWithOneIntArrayValue() { - int[] expected = new int[] {5, 10, -6, 0, -1}; - int[] actual = getArgument("intArray").intArray(); - assertEquals("Expected length and actual length are different.", expected.length, - actual.length); - MoreAsserts.assertEquals(mismatchMessage("intArray"), expected, actual); - } - - @SmallTest - @ParameterizedTest(parameters = { - @Parameter(tag = MethodParameter.PARAMETER_TAG, - arguments = {@Parameter.Argument(name = "stringArray", stringArray = { - "apple", "banana", "orange", "melon", "lemon"})})}) - public void testMethodParametersWithOneStringArrayValue() { - String[] expected = new String[] {"apple", "banana", "orange", "melon", "lemon"}; - String[] actual = getArgument("stringArray").stringArray(); - assertEquals("Expected length and actual length are different.", expected.length, - actual.length); - MoreAsserts.assertEquals(mismatchMessage("stringArary"), expected, actual); - } - - @SmallTest - @ParameterizedTest(parameters = { - @Parameter(tag = MethodParameter.PARAMETER_TAG, - arguments = { - @Parameter.Argument(name = "string1", stringVar = "has vowel"), - @Parameter.Argument(name = "string2", stringVar = "hs vwl"), - @Parameter.Argument(name = "stringArray1", stringArray = { - "apple", "banana", "orange", "melon", "lemon"}), - @Parameter.Argument(name = "stringArray2", stringArray = { - "ppl", "bnn", "mln", "lmn"}), - @Parameter.Argument(name = "int1", intVar = 2), - @Parameter.Argument(name = "int2", intVar = 10), - @Parameter.Argument(name = "intArray1", intArray = { - 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37}), - @Parameter.Argument(name = "intArray2", intArray = {4})})}) - public void testMethodParametersWithMultipleArguments1() { - String stringVar = getArgument("string1").stringVar(); - assertEquals(mismatchMessage("string1"), "has vowel", stringVar); - - stringVar = getArgument("string2").stringVar(); - assertEquals(mismatchMessage("string2"), "hs vwl", stringVar); - - int intVar = getArgument("int1").intVar(); - assertEquals(mismatchMessage("int1"), 2, intVar); - - intVar = getArgument("int2").intVar(); - assertEquals(mismatchMessage("int2"), 10, intVar); - - String[] stringArray = getArgument("stringArray1").stringArray(); - String[] expectedStringArray = new String[] {"apple", "banana", "orange", "melon", "lemon"}; - MoreAsserts.assertEquals("stringArray1 did not match", expectedStringArray, stringArray); - - stringArray = getArgument("stringArray2").stringArray(); - expectedStringArray = new String[] {"ppl", "bnn", "mln", "lmn"}; - MoreAsserts.assertEquals("stringArray2 did not match", expectedStringArray, stringArray); - - int[] intArray = getArgument("intArray1").intArray(); - int[] expectedIntArray = new int[] {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37}; - MoreAsserts.assertEquals("intArray1 did not match", expectedIntArray, intArray); - - intArray = getArgument("intArray2").intArray(); - expectedIntArray = new int[] {4}; - MoreAsserts.assertEquals("intArray2 did not match", expectedIntArray, intArray); - } - - @SmallTest - @ParameterizedTest(parameters = { - @Parameter( - tag = MethodParameter.PARAMETER_TAG, - arguments = { - @Parameter.Argument(name = "string1", stringVar = "testvalue"), - @Parameter.Argument(name = "string2", stringVar = "blahblah"), - @Parameter.Argument(name = "int1", intVar = 4), - @Parameter.Argument(name = "int2", intVar = 0)})}) - public void testMethodParametersWithMultipleArguments2() { - assertEquals("bar variable should equals \"testvalue\"", "testvalue", - getArgument("string1").stringVar()); - assertEquals("foo variable should equals \"blahblah\"", "blahblah", - getArgument("string2").stringVar()); - assertEquals("intArg1 variable should equals 4", 4, - getArgument("int1").intVar()); - assertEquals("intArg2 variable should equals 0", 0, - getArgument("int2").intVar()); - } - - @SmallTest - @ParameterizedTest(parameters = { - @Parameter(tag = MethodParameter.PARAMETER_TAG, - arguments = {@Parameter.Argument(name = "string", stringVar = "t_val")})}) - @ParameterizedTest.Set(tests = { - @ParameterizedTest(parameters = { - @Parameter( - tag = MethodParameter.PARAMETER_TAG, - arguments = { - @Parameter.Argument(name = "string", stringVar = "s_val")})})}) - public void testParameterizedSetOverridesParameterizedTest() { - String expected = "s_val"; - String actual = getArgument("string").stringVar(); - assertEquals("Expected the value set via @ParameterizedTest.Set", expected, actual); - } - - @SmallTest - @ParameterizedTest.Set(tests = { - @ParameterizedTest(parameters = { - @Parameter( - tag = MethodParameter.PARAMETER_TAG, - arguments = { - @Parameter.Argument(name = "string1", stringVar = "testvalue"), - @Parameter.Argument(name = "string2", stringVar = "blahblah"), - @Parameter.Argument(name = "int1", intVar = 4), - @Parameter.Argument(name = "int2", intVar = 0)})})}) - public void testParameterArgumentsWithParameterSetOfOneTest() { - assertEquals("bar variable should equals \"testvalue\"", "testvalue", - getArgument("string1").stringVar()); - assertEquals("foo variable should equals \"blahblah\"", "blahblah", - getArgument("string2").stringVar()); - assertEquals("intArg1 variable should equals 4", 4, - getArgument("int1").intVar()); - assertEquals("intArg2 variable should equals 0", 0, - getArgument("int2").intVar()); - } - - /** - * These next three tests all accomplish the same task but in different ways. - * - * testParameterArgumentsWithParameterSetOfMoreThanOneTest tests fib() by having a set for - * each possible input. While this is fine, it is rather verbose. - * - * Continued @ testSingleTestParameterArgumentsWithParameterSet - */ - @SmallTest - @ParameterizedTest.Set(tests = { - @ParameterizedTest(parameters = { - @Parameter( - tag = MethodParameter.PARAMETER_TAG, - arguments = { - @Parameter.Argument(name = "input", intVar = 1), - @Parameter.Argument(name = "output", intVar = 0)})}), - @ParameterizedTest(parameters = { - @Parameter( - tag = MethodParameter.PARAMETER_TAG, - arguments = { - @Parameter.Argument(name = "input", intVar = 2), - @Parameter.Argument(name = "output", intVar = 1)})}), - @ParameterizedTest(parameters = { - @Parameter( - tag = MethodParameter.PARAMETER_TAG, - arguments = { - @Parameter.Argument(name = "input", intVar = 3), - @Parameter.Argument(name = "output", intVar = 1)})}), - @ParameterizedTest(parameters = { - @Parameter( - tag = MethodParameter.PARAMETER_TAG, - arguments = { - @Parameter.Argument(name = "input", intVar = 4), - @Parameter.Argument(name = "output", intVar = 2)})}), - @ParameterizedTest(parameters = { - @Parameter( - tag = MethodParameter.PARAMETER_TAG, - arguments = { - @Parameter.Argument(name = "input", intVar = 5), - @Parameter.Argument(name = "output", intVar = 3)})}), - @ParameterizedTest(parameters = { - @Parameter( - tag = MethodParameter.PARAMETER_TAG, - arguments = { - @Parameter.Argument(name = "input", intVar = 6), - @Parameter.Argument(name = "output", intVar = 5)})}), - @ParameterizedTest(parameters = { - @Parameter( - tag = MethodParameter.PARAMETER_TAG, - arguments = { - @Parameter.Argument(name = "input", intVar = 7), - @Parameter.Argument(name = "output", intVar = 8)})}), - @ParameterizedTest(parameters = { - @Parameter( - tag = MethodParameter.PARAMETER_TAG, - arguments = { - @Parameter.Argument(name = "input", intVar = 8), - @Parameter.Argument(name = "output", intVar = 13)})}), - @ParameterizedTest(parameters = { - @Parameter( - tag = MethodParameter.PARAMETER_TAG, - arguments = { - @Parameter.Argument(name = "input", intVar = 9), - @Parameter.Argument(name = "output", intVar = 21)})}), - @ParameterizedTest(parameters = { - @Parameter( - tag = MethodParameter.PARAMETER_TAG, - arguments = { - @Parameter.Argument(name = "input", intVar = 10), - @Parameter.Argument(name = "output", intVar = 34)})})}) - public void testParameterArgumentsWithParameterSetOfMoreThanOneTest() { - int input = getArgument("input").intVar(); - int expected = getArgument("output").intVar(); - int actual = fib(input); - assertEquals("Output should be the fibonacci number at index input.", expected, actual); - } - - /** - * This is better than the implementation of - * testParameterArgumentsWithParameterSetOfMoreThanOneTest. It reduces the number of - * {@link ParameterizedTest} annotations by using an intArray instead of an intVar. - * Computationally, this will be faster too because it only has to set up the parameters once - * for the single ParameterizedTest. - * - * Continued @ testSingleTestParameterArgumentsWithParameterSet - */ - @SmallTest - @ParameterizedTest.Set(tests = { - @ParameterizedTest(parameters = { - @Parameter( - tag = MethodParameter.PARAMETER_TAG, - arguments = { - @Parameter.Argument(name = "input", - intArray = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}), - @Parameter.Argument(name = "expected", - intArray = {0, 1, 1, 2, 3, 5, 8, 13, 21, 34})})})}) - public void testSingleTestParameterArgumentsWithParameterSet() { - int[] input = getArgument("input").intArray(); - int[] expected = getArgument("expected").intArray(); - int[] actual = new int[input.length]; - for (int i = 0; i < input.length; i++) { - actual[i] = fib(input[i]); - } - MoreAsserts.assertEquals("Output should be the fibonacci number at each index input.", - expected, actual); - } - - /** - * This is the best implementation to test fibonacci. - * - * It's computationally the same speed at testSingleTestParameterArgumentsWithParameterSet. But - * we don't need to actually have a ParameterizedTestSet. - */ - @SmallTest - @ParameterizedTest(parameters = { - @Parameter( - tag = MethodParameter.PARAMETER_TAG, - arguments = { - @Parameter.Argument(name = "input", - intArray = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}), - @Parameter.Argument(name = "expected", - intArray = {0, 1, 1, 2, 3, 5, 8, 13, 21, 34})})}) - public void testSingleTestParameterArgumentsWithoutParameterSet() { - int[] input = getArgument("input").intArray(); - int[] expected = getArgument("expected").intArray(); - int[] actual = new int[input.length]; - for (int i = 0; i < input.length; i++) { - actual[i] = fib(input[i]); - } - MoreAsserts.assertEquals("Output should be the fibonacci number at each index input.", - expected, actual); - } - - private static String mismatchMessage(String name) { - return String.format("The ParameterArgument %s does not match expected value.", name); - } - - private static int fib(int input) { - if (input <= 0) { - throw new IllegalArgumentException("Input must be greater than 0."); - } - if (input == 1) { - return 0; - } - if (input == 2) { - return 1; - } - int[] temp = new int[input]; - temp[0] = 0; - temp[1] = 1; - for (int i = 2; i < input; i++) { - temp[i] = temp[i - 1] + temp[i - 2]; - } - return temp[input - 1]; - } - - private Parameter.Argument getArgument(String name) { - return getParameterReader().getParameterArgument(MethodParameter.PARAMETER_TAG, name); - } -}
diff --git a/chrome/android/javatests/src/org/chromium/base/test/util/parameter/ParameterizedTestClassAnnotationInheritanceTest.java b/chrome/android/javatests/src/org/chromium/base/test/util/parameter/ParameterizedTestClassAnnotationInheritanceTest.java deleted file mode 100644 index 95fafd0d..0000000 --- a/chrome/android/javatests/src/org/chromium/base/test/util/parameter/ParameterizedTestClassAnnotationInheritanceTest.java +++ /dev/null
@@ -1,50 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.base.test.util.parameter; - -import android.support.test.filters.SmallTest; - -import org.chromium.base.test.util.parameter.parameters.MethodParameter; - -/** - * Tester class for inheritance of the {@link ParameterizedTest} annotation applied to a TestCase - * class. - */ -public class ParameterizedTestClassAnnotationInheritanceTest extends - ParameterizedTestClassAnnotationTest { - public ParameterizedTestClassAnnotationInheritanceTest() { - super(); - } - - @SmallTest - public void testNoParameterizedTestAnnotation() { - super.testNoParameterizedTestAnnotation(); - } - - @SmallTest - @ParameterizedTest() - public void testEmptyParameterizedTestAnnotation() { - super.testEmptyParameterizedTestAnnotation(); - } - - @SmallTest - @ParameterizedTest(parameters = { - @Parameter(tag = MethodParameter.PARAMETER_TAG, - arguments = {@Parameter.Argument(name = "string", stringVar = "value")})}) - public void testMethodParametersWithOneStringValue() { - super.testMethodParametersWithOneStringValue(); - } - - @SmallTest - @ParameterizedTest.Set(tests = { - @ParameterizedTest(parameters = { - @Parameter( - tag = MethodParameter.PARAMETER_TAG, - arguments = { - @Parameter.Argument(name = "string", stringVar = "s_val")})})}) - public void testParameterizedSetOverridesParameterizedTest() { - super.testParameterizedSetOverridesParameterizedTest(); - } -}
diff --git a/chrome/android/javatests/src/org/chromium/base/test/util/parameter/ParameterizedTestClassAnnotationParameterSetAndTest.java b/chrome/android/javatests/src/org/chromium/base/test/util/parameter/ParameterizedTestClassAnnotationParameterSetAndTest.java deleted file mode 100644 index adf3f97..0000000 --- a/chrome/android/javatests/src/org/chromium/base/test/util/parameter/ParameterizedTestClassAnnotationParameterSetAndTest.java +++ /dev/null
@@ -1,42 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.base.test.util.parameter; - -import android.app.Activity; -import android.support.test.filters.SmallTest; - -import org.chromium.base.test.BaseActivityInstrumentationTestCase; -import org.chromium.base.test.util.parameter.parameters.MethodParameter; - -/** - * Tester class for priority of {@link ParameterizedTest} and {@link ParameterizedTest.Set} - * annotations applied to a TestCase class. - */ -@ParameterizedTest(parameters = { - @Parameter(tag = MethodParameter.PARAMETER_TAG, - arguments = {@Parameter.Argument(name = "string", stringVar = "t_val")})}) -@ParameterizedTest.Set(tests = { - @ParameterizedTest(parameters = { - @Parameter( - tag = MethodParameter.PARAMETER_TAG, - arguments = { - @Parameter.Argument(name = "string", stringVar = "s_val")})})}) -public class ParameterizedTestClassAnnotationParameterSetAndTest extends - BaseActivityInstrumentationTestCase<Activity> { - public ParameterizedTestClassAnnotationParameterSetAndTest() { - super(Activity.class); - } - - @SmallTest - public void testParameterizedSetOverridesParameterizedTest() { - String expected = "s_val"; - String actual = getArgument("string").stringVar(); - assertEquals("Expected the value set via @ParameterizedTest.Set", expected, actual); - } - - private Parameter.Argument getArgument(String name) { - return getParameterReader().getParameterArgument(MethodParameter.PARAMETER_TAG, name); - } -}
diff --git a/chrome/android/javatests/src/org/chromium/base/test/util/parameter/ParameterizedTestClassAnnotationParametersTest.java b/chrome/android/javatests/src/org/chromium/base/test/util/parameter/ParameterizedTestClassAnnotationParametersTest.java deleted file mode 100644 index f916b0e8..0000000 --- a/chrome/android/javatests/src/org/chromium/base/test/util/parameter/ParameterizedTestClassAnnotationParametersTest.java +++ /dev/null
@@ -1,59 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.base.test.util.parameter; - -import android.app.Activity; -import android.support.test.filters.SmallTest; - -import org.chromium.base.test.BaseActivityInstrumentationTestCase; -import org.chromium.base.test.util.parameter.parameters.MethodParameter; - -/** - * Tester class for the {@link ParameterizedTest} annotation with parameters - * applied to a TestCase class. - */ -@ParameterizedTest(parameters = { - @Parameter(tag = MethodParameter.PARAMETER_TAG, - arguments = { - @Parameter.Argument(name = "c_string", stringVar = "value"), - @Parameter.Argument(name = "c_int", intVar = 0)})}) -public class ParameterizedTestClassAnnotationParametersTest extends - BaseActivityInstrumentationTestCase<Activity> { - public ParameterizedTestClassAnnotationParametersTest() { - super(Activity.class); - } - - @SmallTest - public void testClassParametersFromClassAnnotation() { - String expectedString = "value"; - String actualString = getArgument("c_string").stringVar(); - assertEquals(mismatchMessage("c_string"), expectedString, actualString); - int expectedInt = 0; - int actualInt = getArgument("c_int").intVar(); - assertEquals(mismatchMessage("c_int"), expectedInt, actualInt); - } - - @SmallTest - @ParameterizedTest(parameters = { - @Parameter(tag = MethodParameter.PARAMETER_TAG, - arguments = {@Parameter.Argument(name = "m_string", stringVar = "value")})}) - public void testMethodParametersWithOneStringValue() { - // Method parameter overrides class parameter. - assertNotNull("m_string parameter should exist", getArgument("m_string")); - String expected = "value"; - String actual = getArgument("m_string").stringVar(); - assertEquals(mismatchMessage("m_string"), expected, actual); - assertNull("c_string parameter should not exist", getArgument("c_string")); - assertNull("c_int parameter should not exist", getArgument("c_int")); - } - - private static String mismatchMessage(String name) { - return String.format("The ParameterArgument %s does not match expected value.", name); - } - - private Parameter.Argument getArgument(String name) { - return getParameterReader().getParameterArgument(MethodParameter.PARAMETER_TAG, name); - } -}
diff --git a/chrome/android/javatests/src/org/chromium/base/test/util/parameter/ParameterizedTestClassAnnotationParametersTestSetInheritanceTest.java b/chrome/android/javatests/src/org/chromium/base/test/util/parameter/ParameterizedTestClassAnnotationParametersTestSetInheritanceTest.java deleted file mode 100644 index f1e77c2..0000000 --- a/chrome/android/javatests/src/org/chromium/base/test/util/parameter/ParameterizedTestClassAnnotationParametersTestSetInheritanceTest.java +++ /dev/null
@@ -1,45 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.base.test.util.parameter; - -import android.support.test.filters.SmallTest; - -import org.chromium.base.test.util.parameter.parameters.MethodParameter; - -/** - * Tester class for inheritance of the {@link ParameterizedTest.Set} annotation applied to a - * TestCase class. - */ -public class ParameterizedTestClassAnnotationParametersTestSetInheritanceTest extends - ParameterizedTestClassAnnotationParametersTestSetTest { - public ParameterizedTestClassAnnotationParametersTestSetInheritanceTest() { - super(); - } - - @SmallTest - public void testMethodParametersFromClassAnnotation() { - super.testMethodParametersFromClassAnnotation(); - } - - @SmallTest - @ParameterizedTest.Set(tests = { - @ParameterizedTest(parameters = { - @Parameter( - tag = MethodParameter.PARAMETER_TAG, - arguments = { - @Parameter.Argument(name = "m_string", stringVar = "value"), - @Parameter.Argument(name = "m_int", intVar = 0)})})}) - public void testClassAndMethodParameterSets() { - super.testClassAndMethodParameterSets(); - } - - @SmallTest - @ParameterizedTest(parameters = { - @Parameter(tag = MethodParameter.PARAMETER_TAG, - arguments = {@Parameter.Argument(name = "c_string1", stringVar = "t_val")})}) - public void testParameterizedSetOverridesParameterizedTest() { - super.testParameterizedSetOverridesParameterizedTest(); - } -}
diff --git a/chrome/android/javatests/src/org/chromium/base/test/util/parameter/ParameterizedTestClassAnnotationParametersTestSetTest.java b/chrome/android/javatests/src/org/chromium/base/test/util/parameter/ParameterizedTestClassAnnotationParametersTestSetTest.java deleted file mode 100644 index e86bb58..0000000 --- a/chrome/android/javatests/src/org/chromium/base/test/util/parameter/ParameterizedTestClassAnnotationParametersTestSetTest.java +++ /dev/null
@@ -1,81 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.base.test.util.parameter; - -import android.app.Activity; -import android.support.test.filters.SmallTest; - -import org.chromium.base.test.BaseActivityInstrumentationTestCase; -import org.chromium.base.test.util.parameter.parameters.MethodParameter; - -/** - * Tester class for the {@link ParameterizedTest.Set} annotation applied to a TestCase class. - */ -@ParameterizedTest.Set(tests = { - @ParameterizedTest(parameters = { - @Parameter( - tag = MethodParameter.PARAMETER_TAG, - arguments = { - @Parameter.Argument(name = "c_string1", stringVar = "testvalue"), - @Parameter.Argument(name = "c_string2", stringVar = "blahblah"), - @Parameter.Argument(name = "c_int1", intVar = 4), - @Parameter.Argument(name = "c_int2", intVar = 0)})})}) -public class ParameterizedTestClassAnnotationParametersTestSetTest extends - BaseActivityInstrumentationTestCase<Activity> { - public ParameterizedTestClassAnnotationParametersTestSetTest() { - super(Activity.class); - } - - @SmallTest - public void testMethodParametersFromClassAnnotation() { - assertEquals("c_string1 variable should equals \"testvalue\"", "testvalue", - getArgument("c_string1").stringVar()); - assertEquals("c_string2 variable should equals \"blahblah\"", "blahblah", - getArgument("c_string2").stringVar()); - assertEquals("c_int1 variable should equals 4", 4, getArgument("c_int1").intVar()); - assertEquals("c_int2 variable should equals 0", 0, getArgument("c_int2").intVar()); - } - - @SmallTest - @ParameterizedTest.Set(tests = { - @ParameterizedTest(parameters = { - @Parameter( - tag = MethodParameter.PARAMETER_TAG, - arguments = { - @Parameter.Argument(name = "m_string", stringVar = "value"), - @Parameter.Argument(name = "m_int", intVar = 0)})})}) - public void testClassAndMethodParameterSets() { - // Method parameter overrides class parameter. - assertNotNull("m_string parameter should exist", getArgument("m_string")); - String expectedString = "value"; - String actualString = getArgument("m_string").stringVar(); - assertEquals(mismatchMessage("m_string"), expectedString, actualString); - int expectedInt = 0; - int actualInt = getArgument("m_int").intVar(); - assertEquals(mismatchMessage("m_int"), expectedInt, actualInt); - assertNull("c_string1 parameter should not exist", getArgument("c_string1")); - assertNull("c_string2 parameter should not exist", getArgument("c_string2")); - assertNull("c_int1 parameter should not exist", getArgument("c_int1")); - assertNull("c_int2 parameter should not exist", getArgument("c_int2")); - } - - @SmallTest - @ParameterizedTest(parameters = { - @Parameter(tag = MethodParameter.PARAMETER_TAG, - arguments = {@Parameter.Argument(name = "c_string1", stringVar = "t_val")})}) - public void testParameterizedSetOverridesParameterizedTest() { - String expected = "testvalue"; - String actual = getArgument("c_string1").stringVar(); - assertEquals("Expected the value set via @ParameterizedTest.Set", expected, actual); - } - - private static String mismatchMessage(String name) { - return String.format("The ParameterArgument %s does not match expected value.", name); - } - - private Parameter.Argument getArgument(String name) { - return getParameterReader().getParameterArgument(MethodParameter.PARAMETER_TAG, name); - } -}
diff --git a/chrome/android/javatests/src/org/chromium/base/test/util/parameter/ParameterizedTestClassAnnotationTest.java b/chrome/android/javatests/src/org/chromium/base/test/util/parameter/ParameterizedTestClassAnnotationTest.java deleted file mode 100644 index b7c1fcce..0000000 --- a/chrome/android/javatests/src/org/chromium/base/test/util/parameter/ParameterizedTestClassAnnotationTest.java +++ /dev/null
@@ -1,84 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.base.test.util.parameter; - -import android.app.Activity; -import android.support.test.filters.SmallTest; - -import org.chromium.base.test.BaseActivityInstrumentationTestCase; -import org.chromium.base.test.util.parameter.parameters.MethodParameter; - -/** - * Tester class for the {@link ParameterizedTest} annotation applied to a TestCase class. - */ -@ParameterizedTest(parameters = {@Parameter(tag = MethodParameter.PARAMETER_TAG)}) -public class ParameterizedTestClassAnnotationTest extends - BaseActivityInstrumentationTestCase<Activity> { - public ParameterizedTestClassAnnotationTest() { - super(Activity.class); - } - - @SmallTest - public void testNoParameterizedTestAnnotation() { - // The test is parametrized because the entire test case class is parametrized. - assertTrue("This is not a parameterized test.", getParameterReader() - .isParameterizedTest()); - assertEquals(0, - getParameterReader().getParameter( - MethodParameter.PARAMETER_TAG).arguments().length); - assertNull("someParameter should not exist.", getParameterReader() - .getParameter("someParameter")); - assertNull("someParameterArgument should not exist.", getParameterReader() - .getParameterArgument("someParameter", "someParameterArgument")); - } - - @SmallTest - @ParameterizedTest() - public void testEmptyParameterizedTestAnnotation() { - assertTrue("This is not a parameterized test.", getParameterReader() - .isParameterizedTest()); - assertNull("someParameter should not exist.", getParameterReader() - .getParameter("someParameter")); - assertNull("someParameterArgument should not exist.", getParameterReader() - .getParameterArgument("someParameter", "someParameterArgument")); - } - - @SmallTest - @ParameterizedTest(parameters = { - @Parameter(tag = MethodParameter.PARAMETER_TAG, - arguments = {@Parameter.Argument(name = "string", stringVar = "value")})}) - public void testMethodParametersWithOneStringValue() { - // Method parameter overrides class parameter. - assertNotNull("string parameter should exist.", getArgument("string")); - String expected = "value"; - String actual = getArgument("string").stringVar(); - assertEquals(mismatchMessage("string"), expected, actual); - assertNull("someParameter should not exist.", getParameterReader() - .getParameter("someParameter")); - assertNull("someParameterArgument should not exist.", getParameterReader() - .getParameterArgument("someParameter", "someParameterArgument")); - } - - @SmallTest - @ParameterizedTest.Set(tests = { - @ParameterizedTest(parameters = { - @Parameter( - tag = MethodParameter.PARAMETER_TAG, - arguments = { - @Parameter.Argument(name = "string", stringVar = "s_val")})})}) - public void testParameterizedSetOverridesParameterizedTest() { - String expected = "s_val"; - String actual = getArgument("string").stringVar(); - assertEquals("Expected the value set via @ParameterizedTest.Set", expected, actual); - } - - private static String mismatchMessage(String name) { - return String.format("The ParameterArgument %s does not match expected value.", name); - } - - private Parameter.Argument getArgument(String name) { - return getParameterReader().getParameterArgument(MethodParameter.PARAMETER_TAG, name); - } -}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/OmniboxTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/OmniboxTest.java index 0e897e1..b667c9a 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/OmniboxTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/OmniboxTest.java
@@ -35,8 +35,7 @@ import org.chromium.base.test.util.MinAndroidSdkLevel; import org.chromium.base.test.util.RetryOnFailure; import org.chromium.base.test.util.ScalableTimeout; -import org.chromium.base.test.util.parameter.Parameter; -import org.chromium.base.test.util.parameter.ParameterizedTest; +import org.chromium.base.test.util.parameter.CommandLineParameter; import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeActivity; import org.chromium.chrome.browser.ChromeFeatureList; @@ -69,23 +68,14 @@ /** * Tests of the Omnibox. + * + * TODO(yolandyan): Replace the CommandLineParameter with new JUnit4 parameterized + * framework once it supports Test Rule Parameterization */ @RunWith(ChromeJUnit4ClassRunner.class) @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE, ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG}) -@ParameterizedTest.Set(tests = { - @ParameterizedTest(parameters = { - @Parameter( - tag = CommandLineFlags.Parameter.PARAMETER_TAG)}), - @ParameterizedTest(parameters = { - @Parameter( - tag = CommandLineFlags.Parameter.PARAMETER_TAG, - arguments = { - @Parameter.Argument( - name = CommandLineFlags.Parameter.ADD_ARG, - stringArray = {"enable-features=" - + ChromeFeatureList.SPANNABLE_INLINE_AUTOCOMPLETE}) - })})}) +@CommandLineParameter({"", "enable-features=" + ChromeFeatureList.SPANNABLE_INLINE_AUTOCOMPLETE}) public class OmniboxTest { @Rule public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/UrlBarTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/UrlBarTest.java index 01225c1..932c3ee 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/UrlBarTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/UrlBarTest.java
@@ -31,8 +31,7 @@ import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.Restriction; import org.chromium.base.test.util.RetryOnFailure; -import org.chromium.base.test.util.parameter.Parameter; -import org.chromium.base.test.util.parameter.ParameterizedTest; +import org.chromium.base.test.util.parameter.CommandLineParameter; import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeActivity; import org.chromium.chrome.browser.ChromeFeatureList; @@ -54,23 +53,14 @@ /** * Tests for the URL bar UI component. + * + * TODO(yolandyan): Replace the CommandLineParameter with new JUnit4 parameterized + * framework once it supports Test Rule Parameterization */ @RunWith(ChromeJUnit4ClassRunner.class) @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE, ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG}) -@ParameterizedTest.Set(tests = { - @ParameterizedTest(parameters = { - @Parameter( - tag = CommandLineFlags.Parameter.PARAMETER_TAG)}), - @ParameterizedTest(parameters = { - @Parameter( - tag = CommandLineFlags.Parameter.PARAMETER_TAG, - arguments = { - @Parameter.Argument( - name = CommandLineFlags.Parameter.ADD_ARG, - stringArray = {"enable-features=" - + ChromeFeatureList.SPANNABLE_INLINE_AUTOCOMPLETE}) - })})}) +@CommandLineParameter({"", "enable-features=" + ChromeFeatureList.SPANNABLE_INLINE_AUTOCOMPLETE}) public class UrlBarTest { // 9000+ chars of goodness
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetBackBehaviorTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetBackBehaviorTest.java index 7320f19..6f6eacf9 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetBackBehaviorTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetBackBehaviorTest.java
@@ -275,7 +275,7 @@ ThreadUtils.runOnUiThreadBlocking(new Runnable() { @Override public void run() { - mBottomSheet.endAnimationsForTests(); + mBottomSheet.endAnimations(); } }); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetNewTabControllerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetNewTabControllerTest.java index 80ae4b39..982449c 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetNewTabControllerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetNewTabControllerTest.java
@@ -520,7 +520,7 @@ ThreadUtils.runOnUiThreadBlocking(new Runnable() { @Override public void run() { - mBottomSheet.endAnimationsForTests(); + mBottomSheet.endAnimations(); } });
diff --git a/chrome/android/javatests/src/org/chromium/chrome/test/ParametersOnMultiTest.java b/chrome/android/javatests/src/org/chromium/chrome/test/ParametersOnMultiTest.java deleted file mode 100644 index d346bb0..0000000 --- a/chrome/android/javatests/src/org/chromium/chrome/test/ParametersOnMultiTest.java +++ /dev/null
@@ -1,557 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.test; - -import android.support.test.filters.SmallTest; -import android.test.MoreAsserts; - -import org.chromium.base.test.util.EnormousTest; -import org.chromium.base.test.util.FlakyTest; -import org.chromium.base.test.util.Restriction; -import org.chromium.base.test.util.RetryOnFailure; -import org.chromium.base.test.util.parameter.Parameter; -import org.chromium.base.test.util.parameter.ParameterizedTest; -import org.chromium.base.test.util.parameter.parameters.MethodParameter; -import org.chromium.chrome.test.util.parameters.AddFakeAccountToAppParameter; -import org.chromium.chrome.test.util.parameters.AddFakeAccountToOsParameter; -import org.chromium.chrome.test.util.parameters.AddGoogleAccountToOsParameter; - -/** - * Tester class for the {@link ParameterizedTest} annotation and the {@link ParameterizedTest.Set} - * annotation on {@link MultiActivityTestBase}. - * - * TODO (crbug.com/522503): Merge these tests with {@link ParameterizedTestAnnotationTest} when a - * parameter that runs tests on different test base activites exists. - */ -public class ParametersOnMultiTest extends MultiActivityTestBase { - private static final String GOOGLE_ACCOUNT_USERNAME = "chromiumforandroid01@gmail.com"; - private static final String GOOGLE_ACCOUNT_PASSWORD = "chromeforandroid"; - - private AddFakeAccountToAppParameter mAddFakeAccountToAppParameter; - private AddFakeAccountToOsParameter mAddFakeAccountToOsParameter; - private AddGoogleAccountToOsParameter mAddGoogleAccountToOsParameter; - - @Override - public void setUp() throws Exception { - super.setUp(); - mAddFakeAccountToAppParameter = - getAvailableParameter(AddFakeAccountToAppParameter.PARAMETER_TAG); - mAddFakeAccountToOsParameter = - getAvailableParameter(AddFakeAccountToOsParameter.PARAMETER_TAG); - mAddGoogleAccountToOsParameter = - getAvailableParameter(AddGoogleAccountToOsParameter.PARAMETER_TAG); - } - - @SmallTest - @RetryOnFailure - public void testNoParameterizedTestAnnotation() { - assertFalse("This is a parameterized test when it should not be.", getParameterReader() - .isParameterizedTest()); - assertNull("someParameter should not exist.", getParameterReader() - .getParameter("someParameter")); - assertNull("someParameterArgument should not exist.", getParameterReader() - .getParameterArgument("someParameter", "someParameterArgument")); - } - - @SmallTest - @ParameterizedTest() - @RetryOnFailure - public void testEmptyParameterizedTestAnnotation() { - assertTrue("This is not a parameterized test.", getParameterReader() - .isParameterizedTest()); - assertNull("someParameter should not exist.", getParameterReader() - .getParameter("someParameter")); - assertNull("someParameterArgument should not exist.", getParameterReader() - .getParameterArgument("someParameter", "someParameterArgument")); - } - - @SmallTest - @ParameterizedTest(parameters = {}) - @RetryOnFailure - public void testParameterizedTestWithEmptyParameters() { - assertTrue("This is not a parameterized test.", getParameterReader() - .isParameterizedTest()); - assertNull("someParameter should not exist.", getParameterReader() - .getParameter("someParameter")); - assertNull("someParameterArgument should not exist.", getParameterReader() - .getParameterArgument("someParameter", "someParameterArgument")); - } - - @SmallTest - @ParameterizedTest(parameters = {}) - @RetryOnFailure - public void testParameterDoesNotExist() { - Parameter parameter = getParameterReader().getParameter(MethodParameter.PARAMETER_TAG); - assertNull("method-parameter should not exist.", parameter); - } - - @SmallTest - @ParameterizedTest(parameters = {@Parameter(tag = MethodParameter.PARAMETER_TAG)}) - @RetryOnFailure - public void testGetParameter() { - String expected = "method-parameter"; - String actual = getParameterReader().getParameter(MethodParameter.PARAMETER_TAG).tag(); - assertEquals("Parameter tag did not match expected.", expected, actual); - } - - @SmallTest - @ParameterizedTest(parameters = {@Parameter(tag = MethodParameter.PARAMETER_TAG)}) - @RetryOnFailure - public void testParameterArgumentDoesNotExist() { - Parameter.Argument actual = getArgument("arg"); - assertNull("arg should not exist.", actual); - } - - @SmallTest - @ParameterizedTest(parameters = { - @Parameter(tag = MethodParameter.PARAMETER_TAG, - arguments = {@Parameter.Argument(name = "string", stringVar = "value")})}) - @RetryOnFailure - public void testMethodParametersWithOneStringValue() { - String expected = "value"; - String actual = getArgument("string").stringVar(); - assertEquals(mismatchMessage("string"), expected, actual); - } - - @SmallTest - @ParameterizedTest(parameters = { - @Parameter(tag = MethodParameter.PARAMETER_TAG, - arguments = {@Parameter.Argument(name = "int", intVar = 0)})}) - @RetryOnFailure - public void testMethodParametersWithOneIntValue() { - int expected = 0; - int actual = getArgument("int").intVar(); - assertEquals(mismatchMessage("int"), expected, actual); - } - - @SmallTest - @ParameterizedTest(parameters = { - @Parameter(tag = MethodParameter.PARAMETER_TAG, - arguments = { - @Parameter.Argument(name = "intArray", intArray = {5, 10, -6, 0, -1})}) - }) - @RetryOnFailure - public void testMethodParametersWithOneIntArrayValue() { - int[] expected = new int[] {5, 10, -6, 0, -1}; - int[] actual = getArgument("intArray").intArray(); - assertEquals("Expected length and actual length are different.", expected.length, - actual.length); - MoreAsserts.assertEquals(mismatchMessage("intArray"), expected, actual); - } - - @SmallTest - @ParameterizedTest(parameters = { - @Parameter(tag = MethodParameter.PARAMETER_TAG, - arguments = {@Parameter.Argument(name = "stringArray", stringArray = { - "apple", "banana", "orange", "melon", "lemon"})})}) - @RetryOnFailure - public void testMethodParametersWithOneStringArrayValue() { - String[] expected = new String[] {"apple", "banana", "orange", "melon", "lemon"}; - String[] actual = getArgument("stringArray").stringArray(); - assertEquals("Expected length and actual length are different.", expected.length, - actual.length); - MoreAsserts.assertEquals(mismatchMessage("stringArary"), expected, actual); - } - - @SmallTest - @ParameterizedTest(parameters = { - @Parameter(tag = MethodParameter.PARAMETER_TAG, - arguments = { - @Parameter.Argument(name = "string1", stringVar = "has vowel"), - @Parameter.Argument(name = "string2", stringVar = "hs vwl"), - @Parameter.Argument(name = "stringArray1", stringArray = { - "apple", "banana", "orange", "melon", "lemon"}), - @Parameter.Argument(name = "stringArray2", stringArray = { - "ppl", "bnn", "mln", "lmn"}), - @Parameter.Argument(name = "int1", intVar = 2), - @Parameter.Argument(name = "int2", intVar = 10), - @Parameter.Argument(name = "intArray1", intArray = { - 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37}), - @Parameter.Argument(name = "intArray2", intArray = {4})})}) - @RetryOnFailure - public void testMethodParametersWithMultipleArguments1() { - String stringVar = getArgument("string1").stringVar(); - assertEquals(mismatchMessage("string1"), "has vowel", stringVar); - - stringVar = getArgument("string2").stringVar(); - assertEquals(mismatchMessage("string2"), "hs vwl", stringVar); - - int intVar = getArgument("int1").intVar(); - assertEquals(mismatchMessage("int1"), 2, intVar); - - intVar = getArgument("int2").intVar(); - assertEquals(mismatchMessage("int2"), 10, intVar); - - String[] stringArray = getArgument("stringArray1").stringArray(); - String[] expectedStringArray = new String[] {"apple", "banana", "orange", "melon", "lemon"}; - MoreAsserts.assertEquals("stringArray1 did not match", expectedStringArray, stringArray); - - stringArray = getArgument("stringArray2").stringArray(); - expectedStringArray = new String[] {"ppl", "bnn", "mln", "lmn"}; - MoreAsserts.assertEquals("stringArray2 did not match", expectedStringArray, stringArray); - - int[] intArray = getArgument("intArray1").intArray(); - int[] expectedIntArray = new int[] {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37}; - MoreAsserts.assertEquals("intArray1 did not match", expectedIntArray, intArray); - - intArray = getArgument("intArray2").intArray(); - expectedIntArray = new int[] {4}; - MoreAsserts.assertEquals("intArray2 did not match", expectedIntArray, intArray); - } - - @SmallTest - @ParameterizedTest(parameters = { - @Parameter( - tag = MethodParameter.PARAMETER_TAG, - arguments = { - @Parameter.Argument(name = "string1", stringVar = "testvalue"), - @Parameter.Argument(name = "string2", stringVar = "blahblah"), - @Parameter.Argument(name = "int1", intVar = 4), - @Parameter.Argument(name = "int2", intVar = 0)})}) - @RetryOnFailure - public void testMethodParametersWithMultipleArguments2() { - assertEquals("bar variable should equals \"testvalue\"", "testvalue", - getArgument("string1").stringVar()); - assertEquals("foo variable should equals \"blahblah\"", "blahblah", - getArgument("string2").stringVar()); - assertEquals("intArg1 variable should equals 4", 4, - getArgument("int1").intVar()); - assertEquals("intArg2 variable should equals 0", 0, - getArgument("int2").intVar()); - } - - @SmallTest - @ParameterizedTest.Set(tests = { - @ParameterizedTest(parameters = { - @Parameter( - tag = MethodParameter.PARAMETER_TAG, - arguments = { - @Parameter.Argument(name = "string1", stringVar = "testvalue"), - @Parameter.Argument(name = "string2", stringVar = "blahblah"), - @Parameter.Argument(name = "int1", intVar = 4), - @Parameter.Argument(name = "int2", intVar = 0)})})}) - @RetryOnFailure - public void testParameterArgumentsWithParameterSetOfOneTest() { - assertEquals("bar variable should equals \"testvalue\"", "testvalue", - getArgument("string1").stringVar()); - assertEquals("foo variable should equals \"blahblah\"", "blahblah", - getArgument("string2").stringVar()); - assertEquals("intArg1 variable should equals 4", 4, - getArgument("int1").intVar()); - assertEquals("intArg2 variable should equals 0", 0, - getArgument("int2").intVar()); - } - - /** - * These next three tests all accomplish the same task but in different ways. - * - * testParameterArgumentsWithParameterSetOfMoreThanOneTest tests fib() by having a set for - * each possible input. While this is fine, it is rather verbose. - * - * Continued @ testSingleTestParameterArgumentsWithParameterSet - */ - @SmallTest - @ParameterizedTest.Set(tests = { - @ParameterizedTest(parameters = { - @Parameter( - tag = MethodParameter.PARAMETER_TAG, - arguments = { - @Parameter.Argument(name = "input", intVar = 1), - @Parameter.Argument(name = "output", intVar = 0)})}), - @ParameterizedTest(parameters = { - @Parameter( - tag = MethodParameter.PARAMETER_TAG, - arguments = { - @Parameter.Argument(name = "input", intVar = 2), - @Parameter.Argument(name = "output", intVar = 1)})}), - @ParameterizedTest(parameters = { - @Parameter( - tag = MethodParameter.PARAMETER_TAG, - arguments = { - @Parameter.Argument(name = "input", intVar = 3), - @Parameter.Argument(name = "output", intVar = 1)})}), - @ParameterizedTest(parameters = { - @Parameter( - tag = MethodParameter.PARAMETER_TAG, - arguments = { - @Parameter.Argument(name = "input", intVar = 4), - @Parameter.Argument(name = "output", intVar = 2)})}), - @ParameterizedTest(parameters = { - @Parameter( - tag = MethodParameter.PARAMETER_TAG, - arguments = { - @Parameter.Argument(name = "input", intVar = 5), - @Parameter.Argument(name = "output", intVar = 3)})}), - @ParameterizedTest(parameters = { - @Parameter( - tag = MethodParameter.PARAMETER_TAG, - arguments = { - @Parameter.Argument(name = "input", intVar = 6), - @Parameter.Argument(name = "output", intVar = 5)})}), - @ParameterizedTest(parameters = { - @Parameter( - tag = MethodParameter.PARAMETER_TAG, - arguments = { - @Parameter.Argument(name = "input", intVar = 7), - @Parameter.Argument(name = "output", intVar = 8)})}), - @ParameterizedTest(parameters = { - @Parameter( - tag = MethodParameter.PARAMETER_TAG, - arguments = { - @Parameter.Argument(name = "input", intVar = 8), - @Parameter.Argument(name = "output", intVar = 13)})}), - @ParameterizedTest(parameters = { - @Parameter( - tag = MethodParameter.PARAMETER_TAG, - arguments = { - @Parameter.Argument(name = "input", intVar = 9), - @Parameter.Argument(name = "output", intVar = 21)})}), - @ParameterizedTest(parameters = { - @Parameter( - tag = MethodParameter.PARAMETER_TAG, - arguments = { - @Parameter.Argument(name = "input", intVar = 10), - @Parameter.Argument(name = "output", intVar = 34)})})}) - @RetryOnFailure - public void testParameterArgumentsWithParameterSetOfMoreThanOneTest() { - int input = getArgument("input").intVar(); - int expected = getArgument("output").intVar(); - int actual = fib(input); - assertEquals("Output should be the fibonacci number at index input.", expected, actual); - } - - /** - * This is better than the implementation of - * testParameterArgumentsWithParameterSetOfMoreThanOneTest. It reduces the number of - * {@link ParameterizedTest} annotations by using an intArray instead of an intVar. - * Computationally, this will be faster too because it only has to set up the parameters once - * for the single ParameterizedTest. - * - * Continued @ testSingleTestParameterArgumentsWithParameterSet - */ - @SmallTest - @ParameterizedTest.Set(tests = { - @ParameterizedTest(parameters = { - @Parameter( - tag = MethodParameter.PARAMETER_TAG, - arguments = { - @Parameter.Argument(name = "input", - intArray = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}), - @Parameter.Argument(name = "expected", - intArray = {0, 1, 1, 2, 3, 5, 8, 13, 21, 34})})})}) - @RetryOnFailure - public void testSingleTestParameterArgumentsWithParameterSet() { - int[] input = getArgument("input").intArray(); - int[] expected = getArgument("expected").intArray(); - int[] actual = new int[input.length]; - for (int i = 0; i < input.length; i++) { - actual[i] = fib(input[i]); - } - MoreAsserts.assertEquals("Output should be the fibonacci number at each index input.", - expected, actual); - } - - /** - * This is the best implementation to test fibonacci. - * - * It's computationally the same speed at testSingleTestParameterArgumentsWithParameterSet. But - * we don't need to actually have a ParameterizedTestSet. - */ - @SmallTest - @ParameterizedTest(parameters = { - @Parameter( - tag = MethodParameter.PARAMETER_TAG, - arguments = { - @Parameter.Argument(name = "input", - intArray = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}), - @Parameter.Argument(name = "expected", - intArray = {0, 1, 1, 2, 3, 5, 8, 13, 21, 34})})}) - @RetryOnFailure - public void testSingleTestParameterArgumentsWithoutParameterSet() { - int[] input = getArgument("input").intArray(); - int[] expected = getArgument("expected").intArray(); - int[] actual = new int[input.length]; - for (int i = 0; i < input.length; i++) { - actual[i] = fib(input[i]); - } - MoreAsserts.assertEquals("Output should be the fibonacci number at each index input.", - expected, actual); - } - - private static String mismatchMessage(String name) { - return String.format("The ParameterArgument %s does not match expected value.", name); - } - - private static int fib(int input) { - if (input <= 0) { - throw new IllegalArgumentException("Input must be greater than 0."); - } - if (input == 1) { - return 0; - } - if (input == 2) { - return 1; - } - int[] temp = new int[input]; - temp[0] = 0; - temp[1] = 1; - for (int i = 2; i < input; i++) { - temp[i] = temp[i - 1] + temp[i - 2]; - } - return temp[input - 1]; - } - - /** - * These are from {@link org.chromium.chrome.test.util.parameters.SigninParametersTest. - * - * TODO (crbug.com/522503): Merge tests together when this is fixed. - */ - @SmallTest - @RetryOnFailure - public void testActivityIsNotSignedInOnAppOrFakeOSorGoogleOS() { - assertFalse("Should not be signed into app.", - mAddFakeAccountToAppParameter.isSignedIn()); - assertFalse("Should not be signed into OS with fake account.", - mAddFakeAccountToOsParameter.isSignedIn()); - assertFalse("Should not be signed in on OS with Google account.", - mAddGoogleAccountToOsParameter.isSignedIn(GOOGLE_ACCOUNT_USERNAME)); - } - - @SmallTest - @ParameterizedTest(parameters = { - @Parameter(tag = AddFakeAccountToAppParameter.PARAMETER_TAG)}) - @RetryOnFailure - public void testIsSignedInOnApp() { - assertTrue("Should not be signed into app.", - mAddFakeAccountToAppParameter.isSignedIn()); - assertFalse("Should not be signed into OS with fake account.", - mAddFakeAccountToOsParameter.isSignedIn()); - assertFalse("Should not be signed in on OS with Google account.", - mAddGoogleAccountToOsParameter.isSignedIn(GOOGLE_ACCOUNT_USERNAME)); - } - - @SmallTest - @ParameterizedTest(parameters = { - @Parameter(tag = AddFakeAccountToOsParameter.PARAMETER_TAG)}) - @RetryOnFailure - public void testIsSignedInOnFakeOS() { - assertFalse("Should not be signed in on app.", - mAddFakeAccountToAppParameter.isSignedIn()); - assertTrue("Should be signed in on OS with fake account.", - mAddFakeAccountToOsParameter.isSignedIn()); - assertFalse("Should not be signed in on OS with Google account.", - mAddGoogleAccountToOsParameter.isSignedIn(GOOGLE_ACCOUNT_USERNAME)); - } - - @FlakyTest - @EnormousTest - @Restriction(Restriction.RESTRICTION_TYPE_INTERNET) - @ParameterizedTest(parameters = { - @Parameter( - tag = AddGoogleAccountToOsParameter.PARAMETER_TAG, - arguments = { - @Parameter.Argument( - name = AddGoogleAccountToOsParameter.ARGUMENT.USERNAME, - stringVar = GOOGLE_ACCOUNT_USERNAME), - @Parameter.Argument( - name = AddGoogleAccountToOsParameter.ARGUMENT.PASSWORD, - stringVar = GOOGLE_ACCOUNT_PASSWORD)})}) - public void testIsSignedInOnGoogleOS() { - assertFalse("Should not be signed into app.", - mAddFakeAccountToAppParameter.isSignedIn()); - assertFalse("Should not be signed into OS with fake account.", - mAddFakeAccountToOsParameter.isSignedIn()); - assertTrue("Should be signed in on OS with Google account.", - mAddGoogleAccountToOsParameter.isSignedIn(GOOGLE_ACCOUNT_USERNAME)); - } - - @SmallTest - @ParameterizedTest(parameters = { - @Parameter(tag = AddFakeAccountToAppParameter.PARAMETER_TAG), - @Parameter(tag = AddFakeAccountToOsParameter.PARAMETER_TAG)}) - @RetryOnFailure - public void testIsSignedInOnFakeOSandApp() { - assertTrue("Should be signed in on app.", - mAddFakeAccountToAppParameter.isSignedIn()); - assertTrue("Should be signed in on OS with fake account.", - mAddFakeAccountToOsParameter.isSignedIn()); - assertFalse("Should not be signed in on OS with Google account.", - mAddGoogleAccountToOsParameter.isSignedIn(GOOGLE_ACCOUNT_USERNAME)); - } - - @FlakyTest - @EnormousTest - @Restriction(Restriction.RESTRICTION_TYPE_INTERNET) - @ParameterizedTest(parameters = { - @Parameter(tag = AddFakeAccountToAppParameter.PARAMETER_TAG), - @Parameter( - tag = AddGoogleAccountToOsParameter.PARAMETER_TAG, - arguments = { - @Parameter.Argument( - name = AddGoogleAccountToOsParameter.ARGUMENT.USERNAME, - stringVar = GOOGLE_ACCOUNT_USERNAME), - @Parameter.Argument( - name = AddGoogleAccountToOsParameter.ARGUMENT.PASSWORD, - stringVar = GOOGLE_ACCOUNT_PASSWORD)})}) - public void testIsSignedInOnAppAndGoogleOS() { - assertTrue("Should be signed into app.", - mAddFakeAccountToAppParameter.isSignedIn()); - assertFalse("Should not be signed into OS with fake account.", - mAddFakeAccountToOsParameter.isSignedIn()); - assertTrue("Should be signed in on OS with Google account.", - mAddGoogleAccountToOsParameter.isSignedIn(GOOGLE_ACCOUNT_USERNAME)); - } - - @FlakyTest - @EnormousTest - @Restriction(Restriction.RESTRICTION_TYPE_INTERNET) - @ParameterizedTest(parameters = { - @Parameter(tag = AddFakeAccountToOsParameter.PARAMETER_TAG), - @Parameter( - tag = AddGoogleAccountToOsParameter.PARAMETER_TAG, - arguments = { - @Parameter.Argument( - name = AddGoogleAccountToOsParameter.ARGUMENT.USERNAME, - stringVar = GOOGLE_ACCOUNT_USERNAME), - @Parameter.Argument( - name = AddGoogleAccountToOsParameter.ARGUMENT.PASSWORD, - stringVar = GOOGLE_ACCOUNT_PASSWORD)})}) - public void testIsSignedInOnFakeOSandGoogleOS() { - assertFalse("Should not be signed into app.", - mAddFakeAccountToAppParameter.isSignedIn()); - assertTrue("Should be signed into OS with fake account.", - mAddFakeAccountToOsParameter.isSignedIn()); - assertTrue("Should be signed in on OS with Google account.", - mAddGoogleAccountToOsParameter.isSignedIn(GOOGLE_ACCOUNT_USERNAME)); - } - - @FlakyTest - @EnormousTest - @Restriction(Restriction.RESTRICTION_TYPE_INTERNET) - @ParameterizedTest(parameters = { - @Parameter(tag = AddFakeAccountToAppParameter.PARAMETER_TAG), - @Parameter(tag = AddFakeAccountToOsParameter.PARAMETER_TAG), - @Parameter( - tag = AddGoogleAccountToOsParameter.PARAMETER_TAG, - arguments = { - @Parameter.Argument( - name = AddGoogleAccountToOsParameter.ARGUMENT.USERNAME, - stringVar = GOOGLE_ACCOUNT_USERNAME), - @Parameter.Argument( - name = AddGoogleAccountToOsParameter.ARGUMENT.PASSWORD, - stringVar = GOOGLE_ACCOUNT_PASSWORD)})}) - public void testIsSignedInOnAppAndFakeOSandGoogleOS() { - assertTrue("Should be signed into app.", - mAddFakeAccountToAppParameter.isSignedIn()); - assertTrue("Should be signed into OS with fake account.", - mAddFakeAccountToOsParameter.isSignedIn()); - assertTrue("Should be signed in on OS with Google account.", - mAddGoogleAccountToOsParameter.isSignedIn(GOOGLE_ACCOUNT_USERNAME)); - } - - private Parameter.Argument getArgument(String name) { - return getParameterReader().getParameterArgument(MethodParameter.PARAMETER_TAG, name); - } -}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/test/util/parameters/SigninParametersTest.java b/chrome/android/javatests/src/org/chromium/chrome/test/util/parameters/SigninParametersTest.java deleted file mode 100644 index 1fccb61..0000000 --- a/chrome/android/javatests/src/org/chromium/chrome/test/util/parameters/SigninParametersTest.java +++ /dev/null
@@ -1,201 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.test.util.parameters; - -import android.support.test.filters.SmallTest; - -import org.chromium.base.test.util.DisabledTest; -import org.chromium.base.test.util.EnormousTest; -import org.chromium.base.test.util.FlakyTest; -import org.chromium.base.test.util.Restriction; -import org.chromium.base.test.util.RetryOnFailure; -import org.chromium.base.test.util.parameter.Parameter; -import org.chromium.base.test.util.parameter.ParameterizedTest; -import org.chromium.chrome.browser.ChromeActivity; -import org.chromium.chrome.test.ChromeActivityTestCaseBase; - -/** - * Tester class for implementation of Signin testing and ParameterizedTest. - */ -@RetryOnFailure -public class SigninParametersTest extends ChromeActivityTestCaseBase<ChromeActivity> { - private static final String GOOGLE_ACCOUNT_USERNAME = "chromiumforandroid01@gmail.com"; - private static final String GOOGLE_ACCOUNT_PASSWORD = "chromeforandroid"; - - private AddFakeAccountToAppParameter mAddFakeAccountToAppParameter; - private AddFakeAccountToOsParameter mAddFakeAccountToOsParameter; - private AddGoogleAccountToOsParameter mAddGoogleAccountToOsParameter; - - public SigninParametersTest() { - super(ChromeActivity.class); - } - - @Override - public void setUp() throws Exception { - super.setUp(); - mAddFakeAccountToAppParameter = - getAvailableParameter(AddFakeAccountToAppParameter.PARAMETER_TAG); - mAddFakeAccountToOsParameter = - getAvailableParameter(AddFakeAccountToOsParameter.PARAMETER_TAG); - mAddGoogleAccountToOsParameter = - getAvailableParameter(AddGoogleAccountToOsParameter.PARAMETER_TAG); - } - - @SmallTest - public void testActivityIsNotSignedInOnAppOrFakeOSorGoogleOS() { - assertFalse("Should not be signed into app.", - mAddFakeAccountToAppParameter.isSignedIn()); - assertFalse("Should not be signed into OS with fake account.", - mAddFakeAccountToOsParameter.isSignedIn()); - assertFalse("Should not be signed in on OS with Google account.", - mAddGoogleAccountToOsParameter.isSignedIn(GOOGLE_ACCOUNT_USERNAME)); - } - - /* - @SmallTest - @ParameterizedTest(parameters = { - @Parameter(tag = AddFakeAccountToAppParameter.PARAMETER_TAG)}) - */ - @DisabledTest(message = "crbug.com/524189") - public void testIsSignedInOnApp() { - assertTrue("Should not be signed into app.", - mAddFakeAccountToAppParameter.isSignedIn()); - assertFalse("Should not be signed into OS with fake account.", - mAddFakeAccountToOsParameter.isSignedIn()); - assertFalse("Should not be signed in on OS with Google account.", - mAddGoogleAccountToOsParameter.isSignedIn(GOOGLE_ACCOUNT_USERNAME)); - } - - @SmallTest - @ParameterizedTest(parameters = { - @Parameter(tag = AddFakeAccountToOsParameter.PARAMETER_TAG)}) - public void testIsSignedInOnFakeOS() { - assertFalse("Should not be signed in on app.", - mAddFakeAccountToAppParameter.isSignedIn()); - assertTrue("Should be signed in on OS with fake account.", - mAddFakeAccountToOsParameter.isSignedIn()); - assertFalse("Should not be signed in on OS with Google account.", - mAddGoogleAccountToOsParameter.isSignedIn(GOOGLE_ACCOUNT_USERNAME)); - } - - @FlakyTest - @EnormousTest - @Restriction(Restriction.RESTRICTION_TYPE_INTERNET) - @ParameterizedTest(parameters = { - @Parameter( - tag = AddGoogleAccountToOsParameter.PARAMETER_TAG, - arguments = { - @Parameter.Argument( - name = AddGoogleAccountToOsParameter.ARGUMENT.USERNAME, - stringVar = GOOGLE_ACCOUNT_USERNAME), - @Parameter.Argument( - name = AddGoogleAccountToOsParameter.ARGUMENT.PASSWORD, - stringVar = GOOGLE_ACCOUNT_PASSWORD)})}) - public void testIsSignedInOnGoogleOS() { - assertFalse("Should not be signed into app.", - mAddFakeAccountToAppParameter.isSignedIn()); - assertFalse("Should not be signed into OS with fake account.", - mAddFakeAccountToOsParameter.isSignedIn()); - assertTrue("Should be signed in on OS with Google account.", - mAddGoogleAccountToOsParameter.isSignedIn(GOOGLE_ACCOUNT_USERNAME)); - } - - /* - @SmallTest - @ParameterizedTest(parameters = { - @Parameter(tag = AddFakeAccountToAppParameter.PARAMETER_TAG), - @Parameter(tag = AddFakeAccountToOsParameter.PARAMETER_TAG)}) - */ - @DisabledTest(message = "crbug.com/524189") - public void testIsSignedInOnFakeOSandApp() { - assertTrue("Should be signed in on app.", - mAddFakeAccountToAppParameter.isSignedIn()); - assertTrue("Should be signed in on OS with fake account.", - mAddFakeAccountToOsParameter.isSignedIn()); - assertFalse("Should not be signed in on OS with Google account.", - mAddGoogleAccountToOsParameter.isSignedIn(GOOGLE_ACCOUNT_USERNAME)); - } - - /* - @FlakyTest - @EnormousTest - @Restriction(Restriction.RESTRICTION_TYPE_INTERNET) - @ParameterizedTest(parameters = { - @Parameter(tag = AddFakeAccountToAppParameter.PARAMETER_TAG), - @Parameter( - tag = AddGoogleAccountToOsParameter.PARAMETER_TAG, - arguments = { - @Parameter.Argument( - name = AddGoogleAccountToOsParameter.ARGUMENT.USERNAME, - stringVar = GOOGLE_ACCOUNT_USERNAME), - @Parameter.Argument( - name = AddGoogleAccountToOsParameter.ARGUMENT.PASSWORD, - stringVar = GOOGLE_ACCOUNT_PASSWORD)})}) - */ - @DisabledTest(message = "crbug.com/524189") - public void testIsSignedInOnAppAndGoogleOS() { - assertTrue("Should be signed into app.", - mAddFakeAccountToAppParameter.isSignedIn()); - assertFalse("Should not be signed into OS with fake account.", - mAddFakeAccountToOsParameter.isSignedIn()); - assertTrue("Should be signed in on OS with Google account.", - mAddGoogleAccountToOsParameter.isSignedIn(GOOGLE_ACCOUNT_USERNAME)); - } - - @FlakyTest - @EnormousTest - @Restriction(Restriction.RESTRICTION_TYPE_INTERNET) - @ParameterizedTest(parameters = { - @Parameter(tag = AddFakeAccountToOsParameter.PARAMETER_TAG), - @Parameter( - tag = AddGoogleAccountToOsParameter.PARAMETER_TAG, - arguments = { - @Parameter.Argument( - name = AddGoogleAccountToOsParameter.ARGUMENT.USERNAME, - stringVar = GOOGLE_ACCOUNT_USERNAME), - @Parameter.Argument( - name = AddGoogleAccountToOsParameter.ARGUMENT.PASSWORD, - stringVar = GOOGLE_ACCOUNT_PASSWORD)})}) - public void testIsSignedInOnFakeOSandGoogleOS() { - assertFalse("Should not be signed into app.", - mAddFakeAccountToAppParameter.isSignedIn()); - assertTrue("Should be signed into OS with fake account.", - mAddFakeAccountToOsParameter.isSignedIn()); - assertTrue("Should be signed in on OS with Google account.", - mAddGoogleAccountToOsParameter.isSignedIn(GOOGLE_ACCOUNT_USERNAME)); - } - - /* - @FlakyTest - @EnormousTest - @Restriction(Restriction.RESTRICTION_TYPE_INTERNET) - @ParameterizedTest(parameters = { - @Parameter(tag = AddFakeAccountToAppParameter.PARAMETER_TAG), - @Parameter(tag = AddFakeAccountToOsParameter.PARAMETER_TAG), - @Parameter( - tag = AddGoogleAccountToOsParameter.PARAMETER_TAG, - arguments = { - @Parameter.Argument( - name = AddGoogleAccountToOsParameter.ARGUMENT.USERNAME, - stringVar = GOOGLE_ACCOUNT_USERNAME), - @Parameter.Argument( - name = AddGoogleAccountToOsParameter.ARGUMENT.PASSWORD, - stringVar = GOOGLE_ACCOUNT_PASSWORD)})}) - */ - @DisabledTest(message = "crbug.com/524189") - public void testIsSignedInOnAppAndFakeOSandGoogleOS() { - assertTrue("Should be signed into app.", - mAddFakeAccountToAppParameter.isSignedIn()); - assertTrue("Should be signed into OS with fake account.", - mAddFakeAccountToOsParameter.isSignedIn()); - assertTrue("Should be signed in on OS with Google account.", - mAddGoogleAccountToOsParameter.isSignedIn(GOOGLE_ACCOUNT_USERNAME)); - } - - @Override - public void startMainActivity() throws InterruptedException { - startMainActivityOnBlankPage(); - } -}
diff --git a/chrome/browser/chrome_browser_main_win.cc b/chrome/browser/chrome_browser_main_win.cc index 3e481f2..f0af59f6 100644 --- a/chrome/browser/chrome_browser_main_win.cc +++ b/chrome/browser/chrome_browser_main_win.cc
@@ -231,9 +231,14 @@ // base::Unretained() here because the ModuleDatabase is never freed. EnumerateShellExtensions( base::BindRepeating(&ModuleDatabase::OnShellExtensionEnumerated, - base::Unretained(module_database))); - EnumerateInputMethodEditors(base::BindRepeating( - &ModuleDatabase::OnImeEnumerated, base::Unretained(module_database))); + base::Unretained(module_database)), + base::BindOnce(&ModuleDatabase::OnShellExtensionEnumerationFinished, + base::Unretained(module_database))); + EnumerateInputMethodEditors( + base::BindRepeating(&ModuleDatabase::OnImeEnumerated, + base::Unretained(module_database)), + base::BindOnce(&ModuleDatabase::OnImeEnumerationFinished, + base::Unretained(module_database))); } void ShowCloseBrowserFirstMessageBox() {
diff --git a/chrome/browser/chromeos/login/bluetooth_host_pairing_browsertest.cc b/chrome/browser/chromeos/login/bluetooth_host_pairing_browsertest.cc index c662be2..3f9951e 100644 --- a/chrome/browser/chromeos/login/bluetooth_host_pairing_browsertest.cc +++ b/chrome/browser/chromeos/login/bluetooth_host_pairing_browsertest.cc
@@ -161,7 +161,7 @@ pairing_chromeos::BluetoothHostPairingController* controller_ = nullptr; bluez::FakeBluetoothDeviceClient* fake_bluetooth_device_client_ = nullptr; - base::MessageLoop message_loop_; + base::MessageLoopForUI message_loop_; DISALLOW_COPY_AND_ASSIGN(BluetoothHostPairingNoInputTest); };
diff --git a/chrome/browser/chromeos/net/DEPS b/chrome/browser/chromeos/net/DEPS index 7b42810..777e45bf 100644 --- a/chrome/browser/chromeos/net/DEPS +++ b/chrome/browser/chromeos/net/DEPS
@@ -2,6 +2,7 @@ # Chrome under mustash cannot call directly into ash internals. "-ash", "+ash/public", + "+ash/system/network", "+components/captive_portal", ]
diff --git a/chrome/browser/chromeos/net/tether_notification_presenter.cc b/chrome/browser/chromeos/net/tether_notification_presenter.cc index 590ac5f3..5f477a3 100644 --- a/chrome/browser/chromeos/net/tether_notification_presenter.cc +++ b/chrome/browser/chromeos/net/tether_notification_presenter.cc
@@ -12,6 +12,7 @@ #include "chrome/grit/generated_resources.h" #include "components/proximity_auth/logging/logging.h" #include "ui/base/l10n/l10n_util.h" +#include "ui/gfx/color_palette.h" #include "ui/gfx/image/image.h" #include "ui/message_center/message_center.h" #include "ui/message_center/notification_types.h" @@ -23,6 +24,12 @@ namespace { +// Mean value of NetworkStat's signal_strength() range. +const int kMediumSignalStrength = 50; + +// Dimensions of Tether notification icon in pixels. +constexpr gfx::Size kTetherSignalIconSize(40, 40); + const char kTetherSettingsSubpage[] = "networks?type=Tether"; class SettingsUiDelegateImpl @@ -37,6 +44,15 @@ } }; +// Gets the normalized signal strength that can range from 0 to 4. This return +// value is then used to get an appropriate image to display on the +// notification. Defaults to full signal strength (4) if |signal_strength| +// is out of bounds. +int GetNormalizedSignalStrength(int signal_strength) { + int normalized_signal_strength = signal_strength / 25; + return std::min(std::max(normalized_signal_strength, 0), 4); +} + } // namespace // static @@ -59,11 +75,13 @@ // static std::unique_ptr<message_center::Notification> -TetherNotificationPresenter::CreateNotification(const std::string& id, - const base::string16& title, - const base::string16& message) { +TetherNotificationPresenter::CreateNotificationWithMediumSignalStrengthIcon( + const std::string& id, + const base::string16& title, + const base::string16& message) { return CreateNotification(id, title, message, - message_center::RichNotificationData()); + message_center::RichNotificationData(), + kMediumSignalStrength); } // static @@ -72,13 +90,16 @@ const std::string& id, const base::string16& title, const base::string16& message, - const message_center::RichNotificationData rich_notification_data) { + const message_center::RichNotificationData rich_notification_data, + int signal_strength) { + auto source = base::MakeUnique<ash::network_icon::SignalStrengthImageSource>( + ash::network_icon::BARS, gfx::kGoogleBlue500, kTetherSignalIconSize, + GetNormalizedSignalStrength(signal_strength)); return base::MakeUnique<message_center::Notification>( message_center::NotificationType::NOTIFICATION_TYPE_SIMPLE, id, title, message, - // TODO(khorimoto): Add tether icon. - gfx::Image() /* icon */, base::string16() /* display_source */, - GURL() /* origin_url */, + gfx::Image(gfx::ImageSkia(std::move(source), kTetherSignalIconSize)), + base::string16() /* display_source */, GURL() /* origin_url */, message_center::NotifierId( message_center::NotifierId::NotifierType::SYSTEM_COMPONENT, kTetherNotifierId), @@ -102,7 +123,8 @@ } void TetherNotificationPresenter::NotifyPotentialHotspotNearby( - const cryptauth::RemoteDevice& remote_device) { + const cryptauth::RemoteDevice& remote_device, + int signal_strength) { PA_LOG(INFO) << "Displaying \"potential hotspot nearby\" notification for " << "device with name \"" << remote_device.name << "\". " << "Notification ID = " << kPotentialHotspotNotificationId; @@ -113,7 +135,6 @@ rich_notification_data.buttons.push_back( message_center::ButtonInfo(l10n_util::GetStringUTF16( IDS_TETHER_NOTIFICATION_WIFI_AVAILABLE_ONE_DEVICE_CONNECT))); - ShowNotification(CreateNotification( std::string(kPotentialHotspotNotificationId), l10n_util::GetStringUTF16( @@ -121,7 +142,7 @@ l10n_util::GetStringFUTF16( IDS_TETHER_NOTIFICATION_WIFI_AVAILABLE_ONE_DEVICE_MESSAGE, base::ASCIIToUTF16(hotspot_nearby_device_.name)), - rich_notification_data)); + rich_notification_data, signal_strength)); } void TetherNotificationPresenter::NotifyMultiplePotentialHotspotsNearby() { @@ -129,7 +150,7 @@ << "multiple devices. Notification ID = " << kPotentialHotspotNotificationId; - ShowNotification(CreateNotification( + ShowNotification(CreateNotificationWithMediumSignalStrengthIcon( std::string(kPotentialHotspotNotificationId), l10n_util::GetStringUTF16( IDS_TETHER_NOTIFICATION_WIFI_AVAILABLE_MULTIPLE_DEVICES_TITLE), @@ -150,7 +171,7 @@ PA_LOG(INFO) << "Displaying \"setup required\" notification. Notification " << "ID = " << kSetupRequiredNotificationId; - ShowNotification(CreateNotification( + ShowNotification(CreateNotificationWithMediumSignalStrengthIcon( std::string(kSetupRequiredNotificationId), l10n_util::GetStringFUTF16(IDS_TETHER_NOTIFICATION_SETUP_REQUIRED_TITLE, base::ASCIIToUTF16(device_name)), @@ -170,7 +191,7 @@ PA_LOG(INFO) << "Displaying \"connection attempt failed\" notification. " << "Notification ID = " << kActiveHostNotificationId; - ShowNotification(CreateNotification( + ShowNotification(CreateNotificationWithMediumSignalStrengthIcon( std::string(kActiveHostNotificationId), l10n_util::GetStringUTF16( IDS_TETHER_NOTIFICATION_CONNECTION_FAILED_TITLE),
diff --git a/chrome/browser/chromeos/net/tether_notification_presenter.h b/chrome/browser/chromeos/net/tether_notification_presenter.h index 53f0548..e883f987c 100644 --- a/chrome/browser/chromeos/net/tether_notification_presenter.h +++ b/chrome/browser/chromeos/net/tether_notification_presenter.h
@@ -8,12 +8,14 @@ #include <memory> #include <string> +#include "ash/system/network/network_icon.h" #include "base/callback.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/strings/string16.h" #include "chromeos/components/tether/notification_presenter.h" #include "chromeos/network/network_connect.h" +#include "chromeos/network/network_state.h" #include "components/cryptauth/remote_device.h" #include "ui/message_center/message_center_observer.h" #include "ui/message_center/notification.h" @@ -44,7 +46,8 @@ // NotificationPresenter: void NotifyPotentialHotspotNearby( - const cryptauth::RemoteDevice& remote_device) override; + const cryptauth::RemoteDevice& remote_device, + int signal_strength) override; void NotifyMultiplePotentialHotspotsNearby() override; void RemovePotentialHotspotNotification() override; void NotifySetupRequired(const std::string& device_name) override; @@ -73,15 +76,16 @@ static const char kActiveHostNotificationId[]; static const char kSetupRequiredNotificationId[]; - static std::unique_ptr<message_center::Notification> CreateNotification( - const std::string& id, - const base::string16& title, - const base::string16& message); + static std::unique_ptr<message_center::Notification> + CreateNotificationWithMediumSignalStrengthIcon(const std::string& id, + const base::string16& title, + const base::string16& message); static std::unique_ptr<message_center::Notification> CreateNotification( const std::string& id, const base::string16& title, const base::string16& message, - const message_center::RichNotificationData rich_notification_data); + const message_center::RichNotificationData rich_notification_data, + int signal_strength); friend class TetherNotificationPresenterTest;
diff --git a/chrome/browser/chromeos/net/tether_notification_presenter_unittest.cc b/chrome/browser/chromeos/net/tether_notification_presenter_unittest.cc index 0f4ad413..a5cd9f8 100644 --- a/chrome/browser/chromeos/net/tether_notification_presenter_unittest.cc +++ b/chrome/browser/chromeos/net/tether_notification_presenter_unittest.cc
@@ -16,6 +16,10 @@ #include "ui/message_center/fake_message_center.h" #include "ui/message_center/message_center_observer.h" +namespace { +const int kTestNetworkSignalStrength = 50; +} // namespace + namespace chromeos { namespace tether { @@ -202,7 +206,6 @@ std::unique_ptr<TestMessageCenter> test_message_center_; std::unique_ptr<TestNetworkConnect> test_network_connect_; TestSettingsUiDelegate* test_settings_ui_delegate_; - std::unique_ptr<TetherNotificationPresenter> notification_presenter_; private: @@ -272,7 +275,8 @@ TestSinglePotentialHotspotNotification_RemoveProgrammatically) { EXPECT_FALSE(test_message_center_->FindVisibleNotificationById( GetPotentialHotspotNotificationId())); - notification_presenter_->NotifyPotentialHotspotNearby(test_device_); + notification_presenter_->NotifyPotentialHotspotNearby( + test_device_, kTestNetworkSignalStrength); message_center::Notification* notification = test_message_center_->FindVisibleNotificationById( @@ -291,7 +295,8 @@ TestSinglePotentialHotspotNotification_TapNotification) { EXPECT_FALSE(test_message_center_->FindVisibleNotificationById( GetPotentialHotspotNotificationId())); - notification_presenter_->NotifyPotentialHotspotNearby(test_device_); + notification_presenter_->NotifyPotentialHotspotNearby( + test_device_, kTestNetworkSignalStrength); message_center::Notification* notification = test_message_center_->FindVisibleNotificationById( @@ -312,7 +317,8 @@ TestSinglePotentialHotspotNotification_TapNotificationButton) { EXPECT_FALSE(test_message_center_->FindVisibleNotificationById( GetPotentialHotspotNotificationId())); - notification_presenter_->NotifyPotentialHotspotNearby(test_device_); + notification_presenter_->NotifyPotentialHotspotNearby( + test_device_, kTestNetworkSignalStrength); message_center::Notification* notification = test_message_center_->FindVisibleNotificationById( @@ -375,7 +381,8 @@ TestPotentialHotspotNotifications_UpdatesOneNotification) { EXPECT_FALSE(test_message_center_->FindVisibleNotificationById( GetPotentialHotspotNotificationId())); - notification_presenter_->NotifyPotentialHotspotNearby(test_device_); + notification_presenter_->NotifyPotentialHotspotNearby( + test_device_, kTestNetworkSignalStrength); message_center::Notification* notification = test_message_center_->FindVisibleNotificationById(
diff --git a/chrome/browser/conflicts/enumerate_input_method_editors_win.cc b/chrome/browser/conflicts/enumerate_input_method_editors_win.cc index a6d2345..9fd77cb 100644 --- a/chrome/browser/conflicts/enumerate_input_method_editors_win.cc +++ b/chrome/browser/conflicts/enumerate_input_method_editors_win.cc
@@ -74,7 +74,8 @@ void EnumerateImesOnBlockingSequence( scoped_refptr<base::SequencedTaskRunner> task_runner, - OnImeEnumeratedCallback on_ime_enumerated) { + OnImeEnumeratedCallback on_ime_enumerated, + base::OnceClosure on_enumeration_finished) { int nb_imes = 0; for (base::win::RegistryKeyIterator iter(HKEY_LOCAL_MACHINE, kImeRegistryKey); iter.Valid(); ++iter) { @@ -101,6 +102,8 @@ size_of_image, time_date_stamp)); } + task_runner->PostTask(FROM_HERE, std::move(on_enumeration_finished)); + base::UmaHistogramCounts100("ThirdPartyModules.InputMethodEditorsCount", nb_imes); } @@ -109,12 +112,14 @@ const wchar_t kImeRegistryKey[] = L"SOFTWARE\\Microsoft\\CTF\\TIP"; -void EnumerateInputMethodEditors(OnImeEnumeratedCallback on_ime_enumerated) { +void EnumerateInputMethodEditors(OnImeEnumeratedCallback on_ime_enumerated, + base::OnceClosure on_enumeration_finished) { base::PostTaskWithTraits( FROM_HERE, {base::MayBlock(), base::TaskPriority::BACKGROUND, base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, base::BindOnce(&EnumerateImesOnBlockingSequence, base::SequencedTaskRunnerHandle::Get(), - std::move(on_ime_enumerated))); + std::move(on_ime_enumerated), + std::move(on_enumeration_finished))); }
diff --git a/chrome/browser/conflicts/enumerate_input_method_editors_win.h b/chrome/browser/conflicts/enumerate_input_method_editors_win.h index 7f400c563..db1fdcc 100644 --- a/chrome/browser/conflicts/enumerate_input_method_editors_win.h +++ b/chrome/browser/conflicts/enumerate_input_method_editors_win.h
@@ -18,9 +18,10 @@ // Finds third-party IMEs (Input Method Editor) installed on the computer by // enumerating the registry. In addition to the file path, the SizeOfImage and -// TimeDateStamp of the module is returned via the callback. +// TimeDateStamp of the module is returned via the |on_ime_enumerated| callback. using OnImeEnumeratedCallback = base::RepeatingCallback<void(const base::FilePath&, uint32_t, uint32_t)>; -void EnumerateInputMethodEditors(OnImeEnumeratedCallback callback); +void EnumerateInputMethodEditors(OnImeEnumeratedCallback on_ime_enumerated, + base::OnceClosure on_enumeration_finished); #endif // CHROME_BROWSER_CONFLICTS_ENUMERATE_INPUT_METHOD_EDITORS_WIN_H_
diff --git a/chrome/browser/conflicts/enumerate_input_method_editors_win_unittest.cc b/chrome/browser/conflicts/enumerate_input_method_editors_win_unittest.cc index 38c5604..3ad64cd 100644 --- a/chrome/browser/conflicts/enumerate_input_method_editors_win_unittest.cc +++ b/chrome/browser/conflicts/enumerate_input_method_editors_win_unittest.cc
@@ -23,9 +23,8 @@ EnumerateInputMethodEditorsTest() = default; ~EnumerateInputMethodEditorsTest() override = default; + // Override all registry hives so that real IMEs don't mess up the unit tests. void SetUp() override { - // Override all registry hives so that real IMEs don't mess up the unit - // tests. ASSERT_NO_FATAL_FAILURE( registry_override_manager_.OverrideRegistry(HKEY_CLASSES_ROOT)); ASSERT_NO_FATAL_FAILURE( @@ -66,6 +65,10 @@ imes->push_back(ime_path); } +void OnEnumerationFinished(bool* is_enumeration_finished) { + *is_enumeration_finished = true; +} + } // namespace // Registers a few fake IMEs then see if the enumeration finds them. @@ -78,12 +81,16 @@ // Do the asynchronous enumeration. std::vector<base::FilePath> imes; + bool is_enumeration_finished = false; EnumerateInputMethodEditors( - base::Bind(&OnImeEnumerated, base::Unretained(&imes))); + base::BindRepeating(&OnImeEnumerated, base::Unretained(&imes)), + base::BindOnce(&OnEnumerationFinished, + base::Unretained(&is_enumeration_finished))); RunUntilIdle(); - EXPECT_EQ(1u, imes.size()); + EXPECT_TRUE(is_enumeration_finished); + ASSERT_EQ(1u, imes.size()); EXPECT_EQ(file_exe, imes[0]); } @@ -97,10 +104,14 @@ // Do the asynchronous enumeration. std::vector<base::FilePath> imes; + bool is_enumeration_finished = false; EnumerateInputMethodEditors( - base::Bind(&OnImeEnumerated, base::Unretained(&imes))); + base::BindRepeating(&OnImeEnumerated, base::Unretained(&imes)), + base::BindOnce(&OnEnumerationFinished, + base::Unretained(&is_enumeration_finished))); RunUntilIdle(); + EXPECT_TRUE(is_enumeration_finished); EXPECT_TRUE(imes.empty()); }
diff --git a/chrome/browser/conflicts/enumerate_shell_extensions_win.cc b/chrome/browser/conflicts/enumerate_shell_extensions_win.cc index 795cbc7..ba3e1be 100644 --- a/chrome/browser/conflicts/enumerate_shell_extensions_win.cc +++ b/chrome/browser/conflicts/enumerate_shell_extensions_win.cc
@@ -23,7 +23,7 @@ void ReadShellExtensions( HKEY parent, - const base::Callback<void(const base::FilePath&)>& callback, + const base::RepeatingCallback<void(const base::FilePath&)>& callback, int* nb_shell_extensions) { for (base::win::RegistryValueIterator iter(parent, kShellExtensionRegistryKey); @@ -62,10 +62,13 @@ void EnumerateShellExtensionsOnBlockingSequence( scoped_refptr<base::SequencedTaskRunner> task_runner, - OnShellExtensionEnumeratedCallback on_shell_extension_enumerated) { - EnumerateShellExtensionPaths(base::BindRepeating( - &OnShellExtensionPathEnumerated, std::move(task_runner), - std::move(on_shell_extension_enumerated))); + OnShellExtensionEnumeratedCallback on_shell_extension_enumerated, + base::OnceClosure on_enumeration_finished) { + EnumerateShellExtensionPaths( + base::BindRepeating(&OnShellExtensionPathEnumerated, task_runner, + std::move(on_shell_extension_enumerated))); + + task_runner->PostTask(FROM_HERE, std::move(on_enumeration_finished)); } } // namespace @@ -74,7 +77,7 @@ L"Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved"; void EnumerateShellExtensionPaths( - const base::Callback<void(const base::FilePath&)>& callback) { + const base::RepeatingCallback<void(const base::FilePath&)>& callback) { base::ThreadRestrictions::AssertIOAllowed(); int nb_shell_extensions = 0; @@ -86,12 +89,14 @@ } void EnumerateShellExtensions( - OnShellExtensionEnumeratedCallback on_shell_extension_enumerated) { + OnShellExtensionEnumeratedCallback on_shell_extension_enumerated, + base::OnceClosure on_enumeration_finished) { base::PostTaskWithTraits( FROM_HERE, {base::MayBlock(), base::TaskPriority::BACKGROUND, base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, base::BindOnce(&EnumerateShellExtensionsOnBlockingSequence, base::SequencedTaskRunnerHandle::Get(), - std::move(on_shell_extension_enumerated))); + std::move(on_shell_extension_enumerated), + std::move(on_enumeration_finished))); }
diff --git a/chrome/browser/conflicts/enumerate_shell_extensions_win.h b/chrome/browser/conflicts/enumerate_shell_extensions_win.h index de74ef1..59ba43f 100644 --- a/chrome/browser/conflicts/enumerate_shell_extensions_win.h +++ b/chrome/browser/conflicts/enumerate_shell_extensions_win.h
@@ -21,14 +21,15 @@ // TODO(pmonette): Move this implementation detail to the .cc file when // enumerate_modules_model.cc gets deleted. void EnumerateShellExtensionPaths( - const base::Callback<void(const base::FilePath&)>& callback); + const base::RepeatingCallback<void(const base::FilePath&)>& callback); // Finds shell extensions installed on the computer by enumerating the registry. // In addition to the file path, the SizeOfImage and TimeDateStamp of the module -// is returned via the callback. +// is returned via the |on_shell_extension_enumerated| callback. using OnShellExtensionEnumeratedCallback = - base::Callback<void(const base::FilePath&, uint32_t, uint32_t)>; + base::RepeatingCallback<void(const base::FilePath&, uint32_t, uint32_t)>; void EnumerateShellExtensions( - OnShellExtensionEnumeratedCallback on_shell_extension_enumerated); + OnShellExtensionEnumeratedCallback on_shell_extension_enumerated, + base::OnceClosure on_enumeration_finished); #endif // CHROME_BROWSER_CONFLICTS_ENUMERATE_SHELL_EXTENSIONS_WIN_H_
diff --git a/chrome/browser/conflicts/enumerate_shell_extensions_win_unittest.cc b/chrome/browser/conflicts/enumerate_shell_extensions_win_unittest.cc index 52de0b26..3ea07bd 100644 --- a/chrome/browser/conflicts/enumerate_shell_extensions_win_unittest.cc +++ b/chrome/browser/conflicts/enumerate_shell_extensions_win_unittest.cc
@@ -22,7 +22,6 @@ class EnumerateShellExtensionsTest : public testing::Test { public: EnumerateShellExtensionsTest() = default; - ~EnumerateShellExtensionsTest() override = default; // Override all registry hives so that real shell extensions don't mess up @@ -77,6 +76,10 @@ shell_extension_paths->push_back(path); } +void OnEnumerationFinished(bool* is_enumeration_finished) { + *is_enumeration_finished = true; +} + } // namespace // Registers a few fake shell extensions then see if @@ -116,11 +119,16 @@ HKEY_LOCAL_MACHINE, L"{FAKE_GUID}", file_exe.value().c_str())); std::vector<base::FilePath> shell_extension_paths; - EnumerateShellExtensions(base::BindRepeating( - &OnShellExtensionEnumerated, base::Unretained(&shell_extension_paths))); + bool is_enumeration_finished = false; + EnumerateShellExtensions( + base::BindRepeating(&OnShellExtensionEnumerated, + base::Unretained(&shell_extension_paths)), + base::BindOnce(&OnEnumerationFinished, + base::Unretained(&is_enumeration_finished))); RunUntilIdle(); + EXPECT_TRUE(is_enumeration_finished); ASSERT_EQ(1u, shell_extension_paths.size()); EXPECT_EQ(file_exe, shell_extension_paths[0]); }
diff --git a/chrome/browser/conflicts/module_database_win.cc b/chrome/browser/conflicts/module_database_win.cc index 65417ec..980281e 100644 --- a/chrome/browser/conflicts/module_database_win.cc +++ b/chrome/browser/conflicts/module_database_win.cc
@@ -30,6 +30,8 @@ ModuleDatabase::ModuleDatabase( scoped_refptr<base::SequencedTaskRunner> task_runner) : task_runner_(std::move(task_runner)), + shell_extensions_enumerated_(false), + ime_enumerated_(false), // ModuleDatabase owns |module_inspector_|, so it is safe to use // base::Unretained(). module_inspector_(base::Bind(&ModuleDatabase::OnModuleInspected, @@ -63,8 +65,8 @@ } bool ModuleDatabase::IsIdle() { - return has_started_processing_ && !idle_timer_.IsRunning() && - module_inspector_.IsIdle(); + return has_started_processing_ && RegisteredModulesEnumerated() && + !idle_timer_.IsRunning() && module_inspector_.IsIdle(); } void ModuleDatabase::OnProcessStarted(uint32_t process_id, @@ -86,6 +88,16 @@ module_info->second.module_types |= ModuleInfoData::kTypeShellExtension; } +void ModuleDatabase::OnShellExtensionEnumerationFinished() { + DCHECK(task_runner_->RunsTasksInCurrentSequence()); + DCHECK(!shell_extensions_enumerated_); + + shell_extensions_enumerated_ = true; + + if (RegisteredModulesEnumerated()) + OnRegisteredModulesEnumerated(); +} + void ModuleDatabase::OnImeEnumerated(const base::FilePath& path, uint32_t size_of_image, uint32_t time_date_stamp) { @@ -98,6 +110,16 @@ module_info->second.module_types |= ModuleInfoData::kTypeIme; } +void ModuleDatabase::OnImeEnumerationFinished() { + DCHECK(task_runner_->RunsTasksInCurrentSequence()); + DCHECK(!ime_enumerated_); + + ime_enumerated_ = true; + + if (RegisteredModulesEnumerated()) + OnRegisteredModulesEnumerated(); +} + void ModuleDatabase::OnModuleLoad(uint32_t process_id, uint64_t creation_time, const base::FilePath& module_path, @@ -201,10 +223,13 @@ void ModuleDatabase::AddObserver(ModuleDatabaseObserver* observer) { observer_list_.AddObserver(observer); - for (const auto& module : modules_) { - if (module.second.inspection_result) - observer->OnNewModuleFound(module.first, module.second); - } + + // If the registered modules enumeration is not finished yet, the |observer| + // will be notified later in OnRegisteredModulesEnumerated(). + if (!RegisteredModulesEnumerated()) + return; + + NotifyLoadedModules(observer); if (IsIdle()) observer->OnModuleDatabaseIdle(); @@ -397,6 +422,18 @@ processes_.erase(key); } +bool ModuleDatabase::RegisteredModulesEnumerated() { + return shell_extensions_enumerated_ && ime_enumerated_; +} + +void ModuleDatabase::OnRegisteredModulesEnumerated() { + for (auto& observer : observer_list_) + NotifyLoadedModules(&observer); + + if (IsIdle()) + EnterIdleState(); +} + void ModuleDatabase::OnModuleInspected( const ModuleInfoKey& module_key, std::unique_ptr<ModuleInspectionResult> inspection_result) { @@ -408,8 +445,9 @@ it->second.inspection_result = std::move(inspection_result); - for (auto& observer : observer_list_) - observer.OnNewModuleFound(it->first, it->second); + if (RegisteredModulesEnumerated()) + for (auto& observer : observer_list_) + observer.OnNewModuleFound(it->first, it->second); // Notify the observers if this was the last outstanding module inspection and // the delay has already expired. @@ -428,6 +466,13 @@ observer.OnModuleDatabaseIdle(); } +void ModuleDatabase::NotifyLoadedModules(ModuleDatabaseObserver* observer) { + for (const auto& module : modules_) { + if (module.second.inspection_result) + observer->OnNewModuleFound(module.first, module.second); + } +} + // ModuleDatabase::ProcessInfoKey ---------------------------------------------- ModuleDatabase::ProcessInfoKey::ProcessInfoKey(
diff --git a/chrome/browser/conflicts/module_database_win.h b/chrome/browser/conflicts/module_database_win.h index ba1d1c2..cc7a6a9 100644 --- a/chrome/browser/conflicts/module_database_win.h +++ b/chrome/browser/conflicts/module_database_win.h
@@ -84,12 +84,18 @@ uint32_t size_of_image, uint32_t time_date_stamp); + // Indicates that all shell extensions have been enumerated. + void OnShellExtensionEnumerationFinished(); + // Indicates that a new registered input method editor was found. Must be // called in the same sequence as |task_runner_|. void OnImeEnumerated(const base::FilePath& path, uint32_t size_of_image, uint32_t time_date_stamp); + // Indicates that all input method editors have been enumerated. + void OnImeEnumerationFinished(); + // Indicates that a module has been loaded. The data passed to this function // is taken as gospel, so if it originates from a remote process it should be // independently validated first. (In practice, see ModuleEventSinkImpl for @@ -185,6 +191,20 @@ // Deletes a process info entry. void DeleteProcessInfo(uint32_t process_id, uint64_t creation_time); + // Returns true if the enumeration of the IMEs and the shell extensions is + // finished. + // + // To avoid sending an improperly tagged module to an observer (in case a race + // condition happens and the module is loaded before the enumeration is done), + // it's important that this function returns true before any calls to + // OnNewModuleFound() is made. + bool RegisteredModulesEnumerated(); + + // Called when RegisteredModulesEnumerated() becomes true. Notifies the + // observers of each already inspected modules and checks if the idle state + // should be entered. + void OnRegisteredModulesEnumerated(); + // Callback for ModuleInspector. void OnModuleInspected( const ModuleInfoKey& module_key, @@ -196,12 +216,22 @@ // Notifies the observers that ModuleDatabase is now idle. void EnterIdleState(); + // Notifies the |observer| of already found and inspected modules via + // OnNewModuleFound(). + void NotifyLoadedModules(ModuleDatabaseObserver* observer); + // The task runner to which this object is bound. scoped_refptr<base::SequencedTaskRunner> task_runner_; // A map of all known modules. ModuleMap modules_; + // Indicates if all shell extensions have been enumerated. + bool shell_extensions_enumerated_; + + // Indicates if all input method editors have been enumerated. + bool ime_enumerated_; + // Inspects new modules on a blocking task runner. ModuleInspector module_inspector_;
diff --git a/chrome/browser/conflicts/module_database_win_unittest.cc b/chrome/browser/conflicts/module_database_win_unittest.cc index a210828..50b4ca5 100644 --- a/chrome/browser/conflicts/module_database_win_unittest.cc +++ b/chrome/browser/conflicts/module_database_win_unittest.cc
@@ -94,7 +94,7 @@ mock_time_task_runner_->RunUntilIdle(); } - void FastForwardToModuleDatabaseIdle() { + void FastForwardToIdleTimer() { RunSchedulerUntilIdle(); mock_time_task_runner_->FastForwardBy(ModuleDatabase::kIdleTimeout); } @@ -552,6 +552,10 @@ }; TEST_F(ModuleDatabaseTest, Observers) { + // Assume there is no shell extensions or IMEs. + module_database()->OnShellExtensionEnumerationFinished(); + module_database()->OnImeEnumerationFinished(); + module_database()->OnProcessStarted(kPid1, kCreateTime1, content::PROCESS_TYPE_BROWSER); @@ -580,6 +584,10 @@ // Tests the idle cycle of the ModuleDatabase. TEST_F(ModuleDatabaseTest, IsIdle) { + // Assume there is no shell extensions or IMEs. + module_database()->OnShellExtensionEnumerationFinished(); + module_database()->OnImeEnumerationFinished(); + module_database()->OnProcessStarted(kPid1, kCreateTime1, content::PROCESS_TYPE_BROWSER); @@ -587,7 +595,7 @@ EXPECT_FALSE(module_database()->IsIdle()); // Can't fast forward to idle because a module load event is needed. - FastForwardToModuleDatabaseIdle(); + FastForwardToIdleTimer(); EXPECT_FALSE(module_database()->IsIdle()); // A load module event starts the timer. @@ -595,14 +603,14 @@ kGoodAddress1); EXPECT_FALSE(module_database()->IsIdle()); - FastForwardToModuleDatabaseIdle(); + FastForwardToIdleTimer(); EXPECT_TRUE(module_database()->IsIdle()); // A new shell extension resets the timer. module_database()->OnShellExtensionEnumerated(dll1_, kSize1, kTime1); EXPECT_FALSE(module_database()->IsIdle()); - FastForwardToModuleDatabaseIdle(); + FastForwardToIdleTimer(); EXPECT_TRUE(module_database()->IsIdle()); // Adding an observer while idle immediately calls OnModuleDatabaseIdle(). @@ -623,9 +631,48 @@ EXPECT_FALSE(is_busy_observer.on_module_database_idle_called()); // Fast forward will call OnModuleDatabaseIdle(). - FastForwardToModuleDatabaseIdle(); + FastForwardToIdleTimer(); EXPECT_TRUE(module_database()->IsIdle()); EXPECT_TRUE(is_busy_observer.on_module_database_idle_called()); module_database()->RemoveObserver(&is_busy_observer); } + +// The ModuleDatabase waits until shell extensions and IMEs are enumerated +// before notifying observers or going idle. +TEST_F(ModuleDatabaseTest, WaitUntilRegisteredModulesEnumerated) { + module_database()->OnProcessStarted(kPid1, kCreateTime1, + content::PROCESS_TYPE_BROWSER); + + // This observer is added before the first loaded module. + DummyObserver before_load_observer; + module_database()->AddObserver(&before_load_observer); + EXPECT_EQ(0, before_load_observer.new_module_count()); + + module_database()->OnModuleLoad(kPid1, kCreateTime1, dll1_, kSize1, kTime1, + kGoodAddress1); + FastForwardToIdleTimer(); + + // Idle state is prevented. + EXPECT_FALSE(module_database()->IsIdle()); + EXPECT_EQ(0, before_load_observer.new_module_count()); + EXPECT_FALSE(before_load_observer.on_module_database_idle_called()); + + // This observer is added after the first loaded module. + DummyObserver after_load_observer; + module_database()->AddObserver(&after_load_observer); + EXPECT_EQ(0, after_load_observer.new_module_count()); + EXPECT_FALSE(after_load_observer.on_module_database_idle_called()); + + // Simulate the enumerations ending. + module_database()->OnImeEnumerationFinished(); + module_database()->OnShellExtensionEnumerationFinished(); + + EXPECT_EQ(1, before_load_observer.new_module_count()); + EXPECT_TRUE(before_load_observer.on_module_database_idle_called()); + EXPECT_EQ(1, after_load_observer.new_module_count()); + EXPECT_TRUE(after_load_observer.on_module_database_idle_called()); + + module_database()->RemoveObserver(&after_load_observer); + module_database()->RemoveObserver(&before_load_observer); +}
diff --git a/chrome/browser/loader/chrome_resource_dispatcher_host_delegate_browsertest.cc b/chrome/browser/loader/chrome_resource_dispatcher_host_delegate_browsertest.cc index 7867326..b385c03 100644 --- a/chrome/browser/loader/chrome_resource_dispatcher_host_delegate_browsertest.cc +++ b/chrome/browser/loader/chrome_resource_dispatcher_host_delegate_browsertest.cc
@@ -420,7 +420,8 @@ const std::string& headers) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); // Ensure that a previous value is not overwritten. - EXPECT_FALSE(base::ContainsKey(*request_headers, url)); + EXPECT_FALSE(base::ContainsKey(*request_headers, url)) + << "URL: " << url << ", Headers: " << headers; (*request_headers)[url] = headers; }
diff --git a/chrome/browser/page_load_metrics/metrics_web_contents_observer.cc b/chrome/browser/page_load_metrics/metrics_web_contents_observer.cc index 0cf731de..0a3f29f 100644 --- a/chrome/browser/page_load_metrics/metrics_web_contents_observer.cc +++ b/chrome/browser/page_load_metrics/metrics_web_contents_observer.cc
@@ -68,7 +68,7 @@ const base::Optional<content::WebContents::CreateParams>& create_params, std::unique_ptr<PageLoadMetricsEmbedderInterface> embedder_interface) : content::WebContentsObserver(web_contents), - in_foreground_(create_params ? !create_params->initially_hidden : false), + in_foreground_(web_contents->IsVisible()), embedder_interface_(std::move(embedder_interface)), has_navigated_(false), page_load_metrics_binding_(web_contents, this) {
diff --git a/chrome/browser/page_load_metrics/observers/ads_page_load_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/ads_page_load_metrics_observer.cc index a355a05a..710ade67 100644 --- a/chrome/browser/page_load_metrics/observers/ads_page_load_metrics_observer.cc +++ b/chrome/browser/page_load_metrics/observers/ads_page_load_metrics_observer.cc
@@ -21,7 +21,20 @@ const base::Feature kAdsFeature{"AdsMetrics", base::FEATURE_ENABLED_BY_DEFAULT}; -bool FrameIsAd(content::NavigationHandle* navigation_handle) { +#define ADS_HISTOGRAM(suffix, hist_macro, ad_type, value) \ + switch (ad_type) { \ + case AdsPageLoadMetricsObserver::AD_TYPE_GOOGLE: \ + hist_macro("PageLoad.Clients.Ads.Google." suffix, value); \ + break; \ + case AdsPageLoadMetricsObserver::AD_TYPE_SUBRESOURCE_FILTER: \ + hist_macro("PageLoad.Clients.Ads.SubresourceFilter." suffix, value); \ + break; \ + case AdsPageLoadMetricsObserver::AD_TYPE_ALL: \ + hist_macro("PageLoad.Clients.Ads.All." suffix, value); \ + break; \ + } + +bool DetectGoogleAd(content::NavigationHandle* navigation_handle) { // Because sub-resource filtering isn't always enabled, and doesn't work // well in monitoring mode (no CSS enforcement), it's difficult to identify // ads. Google ads are prevalent and easy to track, so we'll start by @@ -55,18 +68,22 @@ base::CompareCase::SENSITIVE); } -void RecordParentExistsForSubFrame(bool parent_exists) { - UMA_HISTOGRAM_BOOLEAN("PageLoad.Clients.Ads.Google.ParentExistsForSubFrame", - parent_exists); +void RecordParentExistsForSubFrame( + bool parent_exists, + const AdsPageLoadMetricsObserver::AdTypes& ad_types) { + ADS_HISTOGRAM("ParentExistsForSubFrame", UMA_HISTOGRAM_BOOLEAN, + AdsPageLoadMetricsObserver::AD_TYPE_ALL, parent_exists); } } // namespace AdsPageLoadMetricsObserver::AdFrameData::AdFrameData( - FrameTreeNodeId frame_tree_node_id) + FrameTreeNodeId frame_tree_node_id, + AdTypes ad_types) : frame_bytes(0u), frame_bytes_uncached(0u), - frame_tree_node_id(frame_tree_node_id) {} + frame_tree_node_id(frame_tree_node_id), + ad_types(ad_types) {} // static std::unique_ptr<AdsPageLoadMetricsObserver> @@ -76,10 +93,27 @@ return base::MakeUnique<AdsPageLoadMetricsObserver>(); } -AdsPageLoadMetricsObserver::AdsPageLoadMetricsObserver() = default; +AdsPageLoadMetricsObserver::AdsPageLoadMetricsObserver() + : subresource_observer_(this) {} + AdsPageLoadMetricsObserver::~AdsPageLoadMetricsObserver() = default; page_load_metrics::PageLoadMetricsObserver::ObservePolicy +AdsPageLoadMetricsObserver::OnStart( + content::NavigationHandle* navigation_handle, + const GURL& currently_committed_url, + bool started_in_foreground) { + auto* observer_manager = + subresource_filter::SubresourceFilterObserverManager::FromWebContents( + navigation_handle->GetWebContents()); + // |observer_manager| isn't constructed if the feature for subresource + // filtering isn't enabled. + if (observer_manager) + subresource_observer_.Add(observer_manager); + return CONTINUE_OBSERVING; +} + +page_load_metrics::PageLoadMetricsObserver::ObservePolicy AdsPageLoadMetricsObserver::OnCommit( content::NavigationHandle* navigation_handle, ukm::SourceId source_id) { @@ -103,6 +137,8 @@ content::RenderFrameHost* parent_frame_host = navigation_handle->GetParentFrame(); + AdTypes ad_types = DetectAds(navigation_handle); + const auto& id_and_data = ad_frames_data_.find(frame_tree_node_id); if (id_and_data != ad_frames_data_.end()) { // An existing subframe is navigating again. @@ -112,17 +148,15 @@ if (frame_tree_node_id == id_and_data->second->frame_tree_node_id) { // This is the top-most frame in the ad. - UMA_HISTOGRAM_BOOLEAN( - "PageLoad.Clients.Ads.Google.Navigations.AdFrameRenavigatedToAd", - FrameIsAd(navigation_handle)); + ADS_HISTOGRAM("Navigations.AdFrameRenavigatedToAd", + UMA_HISTOGRAM_BOOLEAN, AD_TYPE_ALL, ad_types.any()); } return; } // This frame was previously not an ad, process it as usual. If it had // any child frames that were ads, those will still be recorded. - UMA_HISTOGRAM_BOOLEAN( - "PageLoad.Clients.Ads.Google.Navigations.NonAdFrameRenavigatedToAd", - FrameIsAd(navigation_handle)); + ADS_HISTOGRAM("Navigations.NonAdFrameRenavigatedToAd", + UMA_HISTOGRAM_BOOLEAN, AD_TYPE_ALL, ad_types.any()); } // Determine who the parent frame's ad ancestor is. @@ -131,17 +165,16 @@ if (parent_id_and_data == ad_frames_data_.end()) { // We don't know who the parent for this frame is. One possibility is that // it's a frame from a previous navigation. - RecordParentExistsForSubFrame(false /* parent_exists */); - + RecordParentExistsForSubFrame(false /* parent_exists */, ad_types); return; } - RecordParentExistsForSubFrame(true /* parent_exists */); + RecordParentExistsForSubFrame(true /* parent_exists */, ad_types); AdFrameData* ad_data = parent_id_and_data->second; - if (!ad_data && FrameIsAd(navigation_handle)) { + if (!ad_data && ad_types.any()) { // This frame is not nested within an ad frame but is itself an ad. - ad_frames_data_storage_.emplace_back(frame_tree_node_id); + ad_frames_data_storage_.emplace_back(frame_tree_node_id, ad_types); ad_data = &ad_frames_data_storage_.back(); } @@ -173,6 +206,40 @@ RecordHistograms(); } +void AdsPageLoadMetricsObserver::OnSubframeNavigationEvaluated( + content::NavigationHandle* navigation_handle, + subresource_filter::LoadPolicy load_policy) { + // We don't track DISALLOW frames because their resources won't be loaded + // and therefore would provide bad histogram data. Note that WOULD_DISALLOW + // is only seen in dry runs. + if (load_policy == subresource_filter::LoadPolicy::WOULD_DISALLOW) { + unfinished_subresource_ad_frames_.insert( + navigation_handle->GetFrameTreeNodeId()); + } +} + +void AdsPageLoadMetricsObserver::OnSubresourceFilterGoingAway() { + subresource_observer_.RemoveAll(); +} + +bool AdsPageLoadMetricsObserver::DetectSubresourceFilterAd( + FrameTreeNodeId frame_tree_node_id) { + return unfinished_subresource_ad_frames_.erase(frame_tree_node_id); +} + +AdsPageLoadMetricsObserver::AdTypes AdsPageLoadMetricsObserver::DetectAds( + content::NavigationHandle* navigation_handle) { + AdTypes ad_types; + + if (DetectGoogleAd(navigation_handle)) + ad_types.set(AD_TYPE_GOOGLE); + + if (DetectSubresourceFilterAd(navigation_handle->GetFrameTreeNodeId())) + ad_types.set(AD_TYPE_SUBRESOURCE_FILTER); + + return ad_types; +} + void AdsPageLoadMetricsObserver::ProcessLoadedResource( const page_load_metrics::ExtraRequestCompleteInfo& extra_request_info) { const auto& id_and_data = @@ -201,7 +268,7 @@ } if (committed_) { UMA_HISTOGRAM_ENUMERATION( - "PageLoad.Clients.Ads.Google.ResourceTypeWhenNoFrameFound", + "PageLoad.Clients.Ads.All.ResourceTypeWhenNoFrameFound", extra_request_info.resource_type, content::RESOURCE_TYPE_LAST_TYPE); } @@ -225,6 +292,12 @@ } void AdsPageLoadMetricsObserver::RecordHistograms() { + RecordHistogramsForType(AD_TYPE_GOOGLE); + RecordHistogramsForType(AD_TYPE_SUBRESOURCE_FILTER); + RecordHistogramsForType(AD_TYPE_ALL); +} + +void AdsPageLoadMetricsObserver::RecordHistogramsForType(int ad_type) { if (page_bytes_ == 0) return; @@ -236,59 +309,58 @@ if (ad_frame_data.frame_bytes == 0) continue; + // If this isn't the type of ad we're looking for, move on to the next. + if (ad_type != AD_TYPE_ALL && !ad_frame_data.ad_types.test(ad_type)) + continue; + non_zero_ad_frames += 1; total_ad_frame_bytes += ad_frame_data.frame_bytes; - uncached_ad_frame_bytes += ad_frame_data.frame_bytes_uncached; - PAGE_BYTES_HISTOGRAM( - "PageLoad.Clients.Ads.Google.Bytes.AdFrames.PerFrame.Total", - ad_frame_data.frame_bytes); - PAGE_BYTES_HISTOGRAM( - "PageLoad.Clients.Ads.Google.Bytes.AdFrames.PerFrame.Network", - ad_frame_data.frame_bytes_uncached); - UMA_HISTOGRAM_PERCENTAGE( - "PageLoad.Clients.Ads.Google.Bytes.AdFrames.PerFrame.PercentNetwork", + uncached_ad_frame_bytes += ad_frame_data.frame_bytes_uncached; + ADS_HISTOGRAM("Bytes.AdFrames.PerFrame.Total", PAGE_BYTES_HISTOGRAM, + ad_type, ad_frame_data.frame_bytes); + ADS_HISTOGRAM("Bytes.AdFrames.PerFrame.Network", PAGE_BYTES_HISTOGRAM, + ad_type, ad_frame_data.frame_bytes_uncached); + ADS_HISTOGRAM( + "Bytes.AdFrames.PerFrame.PercentNetwork", UMA_HISTOGRAM_PERCENTAGE, + ad_type, ad_frame_data.frame_bytes_uncached * 100 / ad_frame_data.frame_bytes); } - UMA_HISTOGRAM_COUNTS_1000( - "PageLoad.Clients.Ads.Google.FrameCounts.AnyParentFrame.AdFrames", - non_zero_ad_frames); + ADS_HISTOGRAM("FrameCounts.AnyParentFrame.AdFrames", + UMA_HISTOGRAM_COUNTS_1000, ad_type, non_zero_ad_frames); // Don't post UMA for pages that don't have ads. if (non_zero_ad_frames == 0) return; - PAGE_BYTES_HISTOGRAM( - "PageLoad.Clients.Ads.Google.Bytes.NonAdFrames.Aggregate.Total", - page_bytes_ - total_ad_frame_bytes); + ADS_HISTOGRAM("Bytes.NonAdFrames.Aggregate.Total", PAGE_BYTES_HISTOGRAM, + ad_type, page_bytes_ - total_ad_frame_bytes); - PAGE_BYTES_HISTOGRAM("PageLoad.Clients.Ads.Google.Bytes.FullPage.Total", - page_bytes_); - PAGE_BYTES_HISTOGRAM("PageLoad.Clients.Ads.Google.Bytes.FullPage.Network", - uncached_page_bytes_); + ADS_HISTOGRAM("Bytes.FullPage.Total", PAGE_BYTES_HISTOGRAM, ad_type, + page_bytes_); + ADS_HISTOGRAM("Bytes.FullPage.Network", PAGE_BYTES_HISTOGRAM, ad_type, + uncached_page_bytes_); + if (page_bytes_) { - UMA_HISTOGRAM_PERCENTAGE( - "PageLoad.Clients.Ads.Google.Bytes.FullPage.Total.PercentAds", - total_ad_frame_bytes * 100 / page_bytes_); + ADS_HISTOGRAM("Bytes.FullPage.Total.PercentAds", UMA_HISTOGRAM_PERCENTAGE, + ad_type, total_ad_frame_bytes * 100 / page_bytes_); } if (uncached_page_bytes_ > 0) { - UMA_HISTOGRAM_PERCENTAGE( - "PageLoad.Clients.Ads.Google.Bytes.FullPage.Network.PercentAds", - uncached_ad_frame_bytes * 100 / uncached_page_bytes_); + ADS_HISTOGRAM("Bytes.FullPage.Network.PercentAds", UMA_HISTOGRAM_PERCENTAGE, + ad_type, + uncached_ad_frame_bytes * 100 / uncached_page_bytes_); } - PAGE_BYTES_HISTOGRAM( - "PageLoad.Clients.Ads.Google.Bytes.AdFrames.Aggregate.Total", - total_ad_frame_bytes); - PAGE_BYTES_HISTOGRAM( - "PageLoad.Clients.Ads.Google.Bytes.AdFrames.Aggregate.Network", - uncached_ad_frame_bytes); + ADS_HISTOGRAM("Bytes.AdFrames.Aggregate.Total", PAGE_BYTES_HISTOGRAM, ad_type, + total_ad_frame_bytes); + ADS_HISTOGRAM("Bytes.AdFrames.Aggregate.Network", PAGE_BYTES_HISTOGRAM, + ad_type, uncached_ad_frame_bytes); if (total_ad_frame_bytes) { - UMA_HISTOGRAM_PERCENTAGE( - "PageLoad.Clients.Ads.Google.Bytes.AdFrames.Aggregate.PercentNetwork", - uncached_ad_frame_bytes * 100 / total_ad_frame_bytes); + ADS_HISTOGRAM("Bytes.AdFrames.Aggregate.PercentNetwork", + UMA_HISTOGRAM_PERCENTAGE, ad_type, + uncached_ad_frame_bytes * 100 / total_ad_frame_bytes); } }
diff --git a/chrome/browser/page_load_metrics/observers/ads_page_load_metrics_observer.h b/chrome/browser/page_load_metrics/observers/ads_page_load_metrics_observer.h index 3e42a42e..b48fb40 100644 --- a/chrome/browser/page_load_metrics/observers/ads_page_load_metrics_observer.h +++ b/chrome/browser/page_load_metrics/observers/ads_page_load_metrics_observer.h
@@ -5,20 +5,36 @@ #ifndef CHROME_BROWSER_PAGE_LOAD_METRICS_OBSERVERS_ADS_PAGE_LOAD_METRICS_OBSERVER_H_ #define CHROME_BROWSER_PAGE_LOAD_METRICS_OBSERVERS_ADS_PAGE_LOAD_METRICS_OBSERVER_H_ +#include <bitset> #include <list> #include <map> #include <memory> #include "base/macros.h" +#include "base/scoped_observer.h" #include "chrome/browser/page_load_metrics/page_load_metrics_observer.h" +#include "components/subresource_filter/content/browser/subresource_filter_observer.h" +#include "components/subresource_filter/content/browser/subresource_filter_observer_manager.h" +#include "components/subresource_filter/core/common/load_policy.h" #include "components/ukm/ukm_source.h" #include "net/http/http_response_info.h" // This observer labels each sub-frame as an ad or not, and keeps track of // relevant per-frame and whole-page byte statistics. class AdsPageLoadMetricsObserver - : public page_load_metrics::PageLoadMetricsObserver { + : public page_load_metrics::PageLoadMetricsObserver, + public subresource_filter::SubresourceFilterObserver { public: + // The types of ads that one can filter on. + enum AdType { + AD_TYPE_GOOGLE = 0, + AD_TYPE_SUBRESOURCE_FILTER = 1, + AD_TYPE_ALL = 2, + AD_TYPE_MAX = AD_TYPE_ALL + }; + + using AdTypes = std::bitset<AD_TYPE_MAX>; + // Returns a new AdsPageLoadMetricObserver. If the feature is disabled it // returns nullptr. static std::unique_ptr<AdsPageLoadMetricsObserver> CreateIfNeeded(); @@ -27,6 +43,9 @@ ~AdsPageLoadMetricsObserver() override; // page_load_metrics::PageLoadMetricsObserver + ObservePolicy OnStart(content::NavigationHandle* navigation_handle, + const GURL& currently_committed_url, + bool started_in_foreground) override; ObservePolicy OnCommit(content::NavigationHandle* navigation_handle, ukm::SourceId source_id) override; void OnDidFinishSubFrameNavigation( @@ -41,15 +60,33 @@ private: struct AdFrameData { - explicit AdFrameData(FrameTreeNodeId frame_tree_node_id); + AdFrameData(FrameTreeNodeId frame_tree_node_id, AdTypes ad_types); size_t frame_bytes; size_t frame_bytes_uncached; const FrameTreeNodeId frame_tree_node_id; + AdTypes ad_types; }; + // subresource_filter::SubresourceFilterObserver: + void OnSubframeNavigationEvaluated( + content::NavigationHandle* navigation_handle, + subresource_filter::LoadPolicy load_policy) override; + void OnSubresourceFilterGoingAway() override; + + // Determines if the URL of a frame matches the SubresourceFilter block + // list. Should only be called once per frame navigation. + bool DetectSubresourceFilterAd(FrameTreeNodeId frame_tree_node_id); + + // This should only be called once per frame navigation, as the + // SubresourceFilter detector clears its state about detected frames after + // each call in order to free up memory. + AdTypes DetectAds(content::NavigationHandle* navigation_handle); + void ProcessLoadedResource( const page_load_metrics::ExtraRequestCompleteInfo& extra_request_info); + void RecordHistograms(); + void RecordHistogramsForType(int ad_type); // Checks to see if a resource is waiting for a navigation with the given // |frame_tree_node_id| to commit before it can be processed. If so, call @@ -67,6 +104,11 @@ // nullptr. std::map<FrameTreeNodeId, AdFrameData*> ad_frames_data_; + // The set of frames that have yet to finish but that the SubresourceFilter + // has reported are ads. Once DetectSubresourceFilterAd is called the id is + // removed from the set. + std::set<FrameTreeNodeId> unfinished_subresource_ad_frames_; + // When the observer receives report of a document resource loading for a // sub-frame before the sub-frame commit occurs, hold onto the resource // request info (delay it) until the sub-frame commits. @@ -77,6 +119,10 @@ size_t uncached_page_bytes_ = 0u; bool committed_ = false; + ScopedObserver<subresource_filter::SubresourceFilterObserverManager, + subresource_filter::SubresourceFilterObserver> + subresource_observer_; + DISALLOW_COPY_AND_ASSIGN(AdsPageLoadMetricsObserver); };
diff --git a/chrome/browser/page_load_metrics/observers/ads_page_load_metrics_observer_unittest.cc b/chrome/browser/page_load_metrics/observers/ads_page_load_metrics_observer_unittest.cc index 08ae49f..73b94614 100644 --- a/chrome/browser/page_load_metrics/observers/ads_page_load_metrics_observer_unittest.cc +++ b/chrome/browser/page_load_metrics/observers/ads_page_load_metrics_observer_unittest.cc
@@ -7,11 +7,14 @@ #include <string> #include "base/macros.h" +#include "base/strings/stringprintf.h" #include "base/test/histogram_tester.h" #include "chrome/browser/page_load_metrics/metrics_web_contents_observer.h" #include "chrome/browser/page_load_metrics/observers/page_load_metrics_observer_test_harness.h" #include "chrome/browser/page_load_metrics/page_load_metrics_observer.h" #include "chrome/browser/page_load_metrics/page_load_tracker.h" +#include "components/subresource_filter/content/browser/subresource_filter_observer_manager.h" +#include "components/subresource_filter/core/common/load_policy.h" #include "content/public/browser/global_request_id.h" #include "content/public/browser/navigation_handle.h" #include "content/public/browser/navigation_throttle.h" @@ -36,10 +39,14 @@ size_t uncached_kb; }; +enum class AdType { GOOGLE = 0, SUBRESOURCE_FILTER = 1, ALL = 2 }; enum class ResourceCached { NOT_CACHED, CACHED }; enum class FrameType { AD = 0, NON_AD }; const char kAdUrl[] = "https://tpc.googlesyndication.com/safeframe/1"; +const char kSubresourceFilterWouldDisallowAdUrl[] = "https://ad.example.com/"; +const char kSubresourceFilterDisallowAdUrl[] = + "https://ad.example.com/disallow"; const char kNonAdUrl[] = "https://foo.com/"; const char kNonAdUrl2[] = "https://bar.com/"; @@ -117,13 +124,32 @@ DISALLOW_COPY_AND_ASSIGN(DelayWillProcessResponseObserver); }; +std::string AdTypeToString(AdType ad_type) { + switch (ad_type) { + case AdType::GOOGLE: + return "Google"; + case AdType::SUBRESOURCE_FILTER: + return "SubresourceFilter"; + case AdType::ALL: + return "All"; + } + ADD_FAILURE(); + return ""; +} + +std::string TypedHistogram(const std::string& suffix, AdType ad_type) { + return base::StringPrintf("PageLoad.Clients.Ads.%s.%s", + AdTypeToString(ad_type).c_str(), suffix.c_str()); +} + // Verifies that the histograms match what is expected given |google_ad_frames| // ad frame byte counts and non-ad counts (|other_cached_kb| and // |other_uncached_kb|). void TestHistograms(const base::HistogramTester& histograms, const std::vector<ExpectedFrameBytes>& google_ad_frames, size_t non_ad_cached_kb, - size_t non_ad_uncached_kb) { + size_t non_ad_uncached_kb, + AdType ad_type) { size_t total_ad_cached_kb = 0; size_t total_ad_uncached_kb = 0; size_t total_ad_kb = 0; @@ -155,7 +181,7 @@ // Test the histograms. histograms.ExpectUniqueSample( - "PageLoad.Clients.Ads.Google.FrameCounts.AnyParentFrame.AdFrames", + TypedHistogram("FrameCounts.AnyParentFrame.AdFrames", ad_type), ad_frame_count, 1); if (ad_frame_count == 0) @@ -163,46 +189,46 @@ for (const auto& total_bytes_and_count : frames_with_total_byte_count) { histograms.ExpectBucketCount( - "PageLoad.Clients.Ads.Google.Bytes.AdFrames.PerFrame.Total", + TypedHistogram("Bytes.AdFrames.PerFrame.Total", ad_type), total_bytes_and_count.first, total_bytes_and_count.second); } for (const auto& network_bytes_and_count : frames_with_network_byte_count) { histograms.ExpectBucketCount( - "PageLoad.Clients.Ads.Google.Bytes.AdFrames.PerFrame.Network", + TypedHistogram("Bytes.AdFrames.PerFrame.Network", ad_type), network_bytes_and_count.first, network_bytes_and_count.second); } for (const auto& percent_network_and_count : frames_with_percent_network_count) { histograms.ExpectBucketCount( - "PageLoad.Clients.Ads.Google.Bytes.AdFrames.PerFrame.PercentNetwork", + TypedHistogram("Bytes.AdFrames.PerFrame.PercentNetwork", ad_type), percent_network_and_count.first, percent_network_and_count.second); } histograms.ExpectUniqueSample( - "PageLoad.Clients.Ads.Google.Bytes.AdFrames.Aggregate.Total", total_ad_kb, + TypedHistogram("Bytes.AdFrames.Aggregate.Total", ad_type), total_ad_kb, 1); histograms.ExpectUniqueSample( - "PageLoad.Clients.Ads.Google.Bytes.AdFrames.Aggregate.Network", + TypedHistogram("Bytes.AdFrames.Aggregate.Network", ad_type), total_ad_uncached_kb, 1); histograms.ExpectUniqueSample( - "PageLoad.Clients.Ads.Google.Bytes.FullPage.Total", + TypedHistogram("Bytes.FullPage.Total", ad_type), non_ad_cached_kb + non_ad_uncached_kb + total_ad_kb, 1); histograms.ExpectUniqueSample( - "PageLoad.Clients.Ads.Google.Bytes.FullPage.Network", + TypedHistogram("Bytes.FullPage.Network", ad_type), non_ad_uncached_kb + total_ad_uncached_kb, 1); histograms.ExpectUniqueSample( - "PageLoad.Clients.Ads.Google.Bytes.NonAdFrames.Aggregate.Total", + TypedHistogram("Bytes.NonAdFrames.Aggregate.Total", ad_type), non_ad_cached_kb + non_ad_uncached_kb, 1); histograms.ExpectUniqueSample( - "PageLoad.Clients.Ads.Google.Bytes.FullPage.Total.PercentAds", + TypedHistogram("Bytes.FullPage.Total.PercentAds", ad_type), (total_ad_kb * 100) / (total_ad_kb + non_ad_cached_kb + non_ad_uncached_kb), 1); histograms.ExpectUniqueSample( - "PageLoad.Clients.Ads.Google.Bytes.AdFrames.Aggregate.PercentNetwork", + TypedHistogram("Bytes.AdFrames.Aggregate.PercentNetwork", ad_type), ((total_ad_uncached_kb * 100) / total_ad_kb), 1); histograms.ExpectUniqueSample( - "PageLoad.Clients.Ads.Google.Bytes.FullPage.Network.PercentAds", + TypedHistogram("Bytes.FullPage.Network.PercentAds", ad_type), (total_ad_uncached_kb * 100) / (total_ad_uncached_kb + non_ad_uncached_kb), 1); @@ -215,6 +241,15 @@ public: AdsPageLoadMetricsObserverTest() {} + void SetUp() override { + page_load_metrics::PageLoadMetricsObserverTestHarness::SetUp(); + subresource_filter::SubresourceFilterObserverManager::CreateForWebContents( + web_contents()); + subresource_observer_manager_ = + subresource_filter::SubresourceFilterObserverManager::FromWebContents( + web_contents()); + } + // Returns the final RenderFrameHost after navigation commits. RenderFrameHost* NavigateFrame(const std::string& url, content::RenderFrameHost* frame) { @@ -237,6 +272,22 @@ RenderFrameHostTester::For(parent)->AppendChild(frame_name); auto navigation_simulator = NavigationSimulator::CreateRendererInitiated(GURL(url), subframe); + navigation_simulator->Start(); + + // Simulate subresource filter evaluation. + content::NavigationHandle* handle = + navigation_simulator->GetNavigationHandle(); + if (url == kSubresourceFilterWouldDisallowAdUrl) { + subresource_observer_manager_->NotifySubframeNavigationEvaluated( + handle, subresource_filter::LoadPolicy::WOULD_DISALLOW); + } else if (url == kSubresourceFilterDisallowAdUrl) { + subresource_observer_manager_->NotifySubframeNavigationEvaluated( + handle, subresource_filter::LoadPolicy::DISALLOW); + } else { + subresource_observer_manager_->NotifySubframeNavigationEvaluated( + handle, subresource_filter::LoadPolicy::ALLOW); + } + navigation_simulator->Commit(); return navigation_simulator->GetFinalRenderFrameHost(); } @@ -252,11 +303,11 @@ if (frame_type == FrameType::AD) { tester.ExpectUniqueSample( - "PageLoad.Clients.Ads.Google.Navigations.AdFrameRenavigatedToAd", - bucket, 1); + "PageLoad.Clients.Ads.All.Navigations.AdFrameRenavigatedToAd", bucket, + 1); } else { tester.ExpectUniqueSample( - "PageLoad.Clients.Ads.Google.Navigations.NonAdFrameRenavigatedToAd", + "PageLoad.Clients.Ads.All.Navigations.NonAdFrameRenavigatedToAd", bucket, 1); } @@ -281,6 +332,8 @@ } private: + subresource_filter::SubresourceFilterObserverManager* + subresource_observer_manager_ = nullptr; DISALLOW_COPY_AND_ASSIGN(AdsPageLoadMetricsObserverTest); }; @@ -298,7 +351,8 @@ NavigateFrame(kNonAdUrl, main_frame); TestHistograms(histogram_tester(), std::vector<ExpectedFrameBytes>(), - 0 /* non_ad_cached_kb */, 30 /* non_ad_uncached_kb */); + 0 /* non_ad_cached_kb */, 30 /* non_ad_uncached_kb */, + AdType::GOOGLE); // Verify that other UMA wasn't written. histogram_tester().ExpectTotalCount( @@ -327,10 +381,10 @@ NavigateFrame(kNonAdUrl, main_frame); TestHistograms(histogram_tester(), {{0, 10}}, 0 /* non_ad_cached_kb */, - 10 /*non_ad_uncached_kb*/); + 10 /*non_ad_uncached_kb*/, AdType::GOOGLE); } -TEST_F(AdsPageLoadMetricsObserverTest, PageWithAdFrames) { +TEST_F(AdsPageLoadMetricsObserverTest, AllAdTypesInPage) { RenderFrameHost* main_frame = NavigateMainFrame(kNonAdUrl); RenderFrameHost* non_ad_frame = CreateAndNavigateSubFrame(kNonAdUrl, kNonAdName, main_frame); @@ -339,40 +393,54 @@ // nested ad frame doesn't get counted separately (but that its bytes are // still counted). Also verify that the various ad signals (urls and names) // are properly detected. - RenderFrameHost* ad_frame1 = + RenderFrameHost* google_frame1 = CreateAndNavigateSubFrame(kNonAdUrl, "google_ads_iframe_1", main_frame); - RenderFrameHost* ad_frame2 = - CreateAndNavigateSubFrame(kNonAdUrl, "google_ads_frame_2", main_frame); - RenderFrameHost* ad_frame3 = CreateAndNavigateSubFrame( - "https://tpc.googlesyndication.com/safeframe/", "", main_frame); - RenderFrameHost* ad_frame4 = CreateAndNavigateSubFrame( - "https://tpc.googlesyndication.com/safeframe/1", "", main_frame); - RenderFrameHost* nested_ad_frame4 = CreateAndNavigateSubFrame( - "https://tpc.googlesyndication.com/safeframe/2", "", ad_frame4); + RenderFrameHost* google_frame2 = + CreateAndNavigateSubFrame(kAdUrl, kNonAdName, main_frame); + RenderFrameHost* srf_frame1 = CreateAndNavigateSubFrame( + kSubresourceFilterWouldDisallowAdUrl, kNonAdName, main_frame); + RenderFrameHost* srf_frame2 = CreateAndNavigateSubFrame( + kSubresourceFilterWouldDisallowAdUrl, kNonAdName, main_frame); + RenderFrameHost* nested_srf_frame3 = CreateAndNavigateSubFrame( + kSubresourceFilterWouldDisallowAdUrl, kNonAdName, srf_frame2); + + // This frame should return DISALLOW by the SubresourceFilter so it won't + // count as an ad. + RenderFrameHost* disallowed_srf_frame = CreateAndNavigateSubFrame( + kSubresourceFilterDisallowAdUrl, kNonAdName, main_frame); // Create an addditional ad frame without content. It shouldn't be counted // as an ad frame. - CreateAndNavigateSubFrame(kAdUrl, kNonAdName, main_frame); + CreateAndNavigateSubFrame(kSubresourceFilterWouldDisallowAdUrl, kNonAdName, + main_frame); // 70KB total in page, 50 from ads, 40 from network, and 30 of those // are from ads. LoadResource(main_frame, ResourceCached::NOT_CACHED, 10); LoadResource(non_ad_frame, ResourceCached::CACHED, 10); - LoadResource(ad_frame1, ResourceCached::CACHED, 10); - LoadResource(ad_frame2, ResourceCached::NOT_CACHED, 10); - LoadResource(ad_frame3, ResourceCached::NOT_CACHED, 10); - LoadResource(ad_frame4, ResourceCached::NOT_CACHED, 10); - LoadResource(nested_ad_frame4, ResourceCached::CACHED, 10); + LoadResource(google_frame1, ResourceCached::CACHED, 10); + LoadResource(google_frame2, ResourceCached::NOT_CACHED, 10); + LoadResource(srf_frame1, ResourceCached::NOT_CACHED, 10); + LoadResource(srf_frame2, ResourceCached::NOT_CACHED, 10); + LoadResource(nested_srf_frame3, ResourceCached::CACHED, 10); + LoadResource(disallowed_srf_frame, ResourceCached::CACHED, 10); // Navigate again to trigger histograms. NavigateFrame(kNonAdUrl, main_frame); + TestHistograms(histogram_tester(), {{10, 0}, {0, 10}}, + 30 /* non_ad_cached_kb */, 30 /* non_ad_uncached_kb */, + AdType::GOOGLE); + TestHistograms(histogram_tester(), {{0, 10}, {10, 10}}, + 30 /* non_ad_cached_kb */, 20 /* non_ad_uncached_kb */, + AdType::SUBRESOURCE_FILTER); TestHistograms(histogram_tester(), {{10, 0}, {0, 10}, {0, 10}, {10, 10}}, - 10 /* non_ad_cached_kb */, 10 /* non_ad_uncached_kb */); + 20 /* non_ad_cached_kb */, 10 /* non_ad_uncached_kb */, + AdType::ALL); histogram_tester().ExpectBucketCount( - "PageLoad.Clients.Ads.Google.ParentExistsForSubFrame", 0, 0); + "PageLoad.Clients.Ads.All.ParentExistsForSubFrame", 0, 0); histogram_tester().ExpectTotalCount( - "PageLoad.Clients.Ads.Google.ResourceTypeWhenNoFrameFound", 0); + "PageLoad.Clients.Ads.All.ResourceTypeWhenNoFrameFound", 0); } TEST_F(AdsPageLoadMetricsObserverTest, PageLoadSubFrameRenavigationMetrics) { @@ -410,7 +478,7 @@ base::HistogramTester tester; ad_sub_sub_frame = NavigateFrame(kNonAdUrl2, ad_sub_sub_frame); tester.ExpectTotalCount( - "PageLoad.Clients.Ads.Google.Navigations.AdFrameRenavigatedToAd", 0); + "PageLoad.Clients.Ads.All.Navigations.AdFrameRenavigatedToAd", 0); } TEST_F(AdsPageLoadMetricsObserverTest, PageWithAdFrameThatRenavigates) { @@ -431,11 +499,11 @@ NavigateFrame(kNonAdUrl, main_frame); TestHistograms(histogram_tester(), {{0, 20}}, 0 /* non_ad_cached_kb */, - 10 /* non_ad_uncached_kb */); + 10 /* non_ad_uncached_kb */, AdType::GOOGLE); histogram_tester().ExpectBucketCount( - "PageLoad.Clients.Ads.Google.ParentExistsForSubFrame", 0, 0); + "PageLoad.Clients.Ads.All.ParentExistsForSubFrame", 0, 0); histogram_tester().ExpectTotalCount( - "PageLoad.Clients.Ads.Google.ResourceTypeWhenNoFrameFound", 0); + "PageLoad.Clients.Ads.All.ResourceTypeWhenNoFrameFound", 0); } TEST_F(AdsPageLoadMetricsObserverTest, PageWithNonAdFrameThatRenavigatesToAd) { @@ -466,11 +534,12 @@ NavigateFrame(kNonAdUrl, main_frame); TestHistograms(histogram_tester(), {{0, 10}, {0, 10}}, - 0 /* non_ad_cached_kb */, 20 /* non_ad_uncached_kb */); + 0 /* non_ad_cached_kb */, 20 /* non_ad_uncached_kb */, + AdType::GOOGLE); histogram_tester().ExpectBucketCount( - "PageLoad.Clients.Ads.Google.ParentExistsForSubFrame", 0, 0); + "PageLoad.Clients.Ads.All.ParentExistsForSubFrame", 0, 0); histogram_tester().ExpectTotalCount( - "PageLoad.Clients.Ads.Google.ResourceTypeWhenNoFrameFound", 0); + "PageLoad.Clients.Ads.All.ResourceTypeWhenNoFrameFound", 0); } TEST_F(AdsPageLoadMetricsObserverTest, CountAbortedNavigation) { @@ -497,7 +566,7 @@ NavigateFrame(kNonAdUrl, main_frame); TestHistograms(histogram_tester(), {{0, 20}}, 0 /* non_ad_cached_kb */, - 10 /* non_ad_uncached_kb */); + 10 /* non_ad_uncached_kb */, AdType::GOOGLE); } TEST_F(AdsPageLoadMetricsObserverTest, CountAbortedSecondNavigationForFrame) { @@ -526,7 +595,7 @@ NavigateFrame(kNonAdUrl, main_frame); TestHistograms(histogram_tester(), {{0, 20}}, 0 /* non_ad_cached_kb */, - 20 /* non_ad_uncached_kb */); + 20 /* non_ad_uncached_kb */, AdType::GOOGLE); } TEST_F(AdsPageLoadMetricsObserverTest, TwoResourceLoadsBeforeCommit) { @@ -561,12 +630,11 @@ NavigateFrame(kNonAdUrl, main_frame); TestHistograms(histogram_tester(), {{0, 20}}, 0 /* non_ad_cached_kb */, - 10 /* non_ad_uncached_kb */); - + 10 /* non_ad_uncached_kb */, AdType::GOOGLE); histogram_tester().ExpectBucketCount( - "PageLoad.Clients.Ads.Google.ParentExistsForSubFrame", 0, 0); + "PageLoad.Clients.Ads.All.ParentExistsForSubFrame", 0, 0); histogram_tester().ExpectUniqueSample( - "PageLoad.Clients.Ads.Google.ResourceTypeWhenNoFrameFound", + "PageLoad.Clients.Ads.All.ResourceTypeWhenNoFrameFound", content::RESOURCE_TYPE_SUB_FRAME, 1); } @@ -580,7 +648,7 @@ CreateAndNavigateSubFrame(kNonAdUrl, kNonAdName, main_frame); histogram_tester().ExpectBucketCount( - "PageLoad.Clients.Ads.Google.ParentExistsForSubFrame", 0, 0); + "PageLoad.Clients.Ads.All.ParentExistsForSubFrame", 0, 0); // Renavigate the child, but, while navigating, the main frame renavigates. RenderFrameHost* child_of_subframe = @@ -596,15 +664,15 @@ navigation_simulator->Commit(); child_of_subframe = navigation_simulator->GetFinalRenderFrameHost(); histogram_tester().ExpectBucketCount( - "PageLoad.Clients.Ads.Google.ParentExistsForSubFrame", 0, 1); + "PageLoad.Clients.Ads.All.ParentExistsForSubFrame", 0, 1); // Test that a resource loaded into an unknown frame doesn't cause any // issues. histogram_tester().ExpectTotalCount( - "PageLoad.Clients.Ads.Google.ResourceTypeWhenNoFrameFound", 0); + "PageLoad.Clients.Ads.All.ResourceTypeWhenNoFrameFound", 0); LoadResource(child_of_subframe, ResourceCached::NOT_CACHED, 10); histogram_tester().ExpectBucketCount( - "PageLoad.Clients.Ads.Google.ResourceTypeWhenNoFrameFound", + "PageLoad.Clients.Ads.All.ResourceTypeWhenNoFrameFound", content::RESOURCE_TYPE_SUB_FRAME, 1); } @@ -668,6 +736,6 @@ // There shouldn't be any histograms for an aborted main frame. EXPECT_EQ(0u, histogram_tester() - .GetTotalCountsForPrefix("PageLoad.Clients.Ads.") + .GetTotalCountsForPrefix("PageLoad.Clients.Ads.Google.") .size()); }
diff --git a/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc b/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc index c81c149..66e12c4 100644 --- a/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc +++ b/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc
@@ -11,16 +11,23 @@ #include "base/test/histogram_tester.h" #include "base/threading/thread_restrictions.h" #include "base/time/time.h" +#include "build/build_config.h" +#include "chrome/browser/lifetime/keep_alive_types.h" +#include "chrome/browser/lifetime/scoped_keep_alive.h" #include "chrome/browser/page_load_metrics/metrics_web_contents_observer.h" #include "chrome/browser/page_load_metrics/observers/aborts_page_load_metrics_observer.h" #include "chrome/browser/page_load_metrics/observers/core_page_load_metrics_observer.h" #include "chrome/browser/page_load_metrics/observers/document_write_page_load_metrics_observer.h" #include "chrome/browser/page_load_metrics/observers/no_state_prefetch_page_load_metrics_observer.h" #include "chrome/browser/page_load_metrics/page_load_tracker.h" +#include "chrome/browser/prefs/session_startup_pref.h" #include "chrome/browser/prerender/prerender_histograms.h" #include "chrome/browser/prerender/prerender_origin.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/sessions/session_service_factory.h" +#include "chrome/browser/sessions/session_service_test_helper.h" #include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_commands.h" #include "chrome/browser/ui/browser_navigator_params.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/common/chrome_features.h" @@ -1070,3 +1077,95 @@ histogram_tester_.ExpectUniqueSample(internal::kHistogramTotalBytes, 0, 1); } + +class SessionRestorePageLoadMetricsBrowserTest + : public PageLoadMetricsBrowserTest { + public: + SessionRestorePageLoadMetricsBrowserTest() {} + + // PageLoadMetricsBrowserTest: + void SetUpOnMainThread() override { + PageLoadMetricsBrowserTest::SetUpOnMainThread(); + SessionStartupPref::SetStartupPref( + browser()->profile(), SessionStartupPref(SessionStartupPref::LAST)); + ASSERT_TRUE(embedded_test_server()->Start()); +#if defined(OS_CHROMEOS) + SessionServiceTestHelper helper( + SessionServiceFactory::GetForProfile(browser()->profile())); + helper.SetForceBrowserNotAliveWithNoWindows(true); + helper.ReleaseService(); +#endif + } + + Browser* QuitBrowserAndRestore(Browser* browser) { + Profile* profile = browser->profile(); + + std::unique_ptr<ScopedKeepAlive> keep_alive(new ScopedKeepAlive( + KeepAliveOrigin::SESSION_RESTORE, KeepAliveRestartOption::DISABLED)); + CloseBrowserSynchronously(browser); + + // Create a new window, which should trigger session restore. + chrome::NewEmptyWindow(profile); + ui_test_utils::BrowserAddedObserver window_observer; + return window_observer.WaitForSingleNewBrowser(); + } + + void WaitForTabsToLoad(Browser* browser) { + for (int i = 0; i < browser->tab_strip_model()->count(); ++i) { + content::WebContents* contents = + browser->tab_strip_model()->GetWebContentsAt(i); + contents->GetController().LoadIfNecessary(); + content::WaitForLoadStop(contents); + } + } + + GURL GetTestURL() const { + return embedded_test_server()->GetURL("/title1.html"); + } + + private: + DISALLOW_COPY_AND_ASSIGN(SessionRestorePageLoadMetricsBrowserTest); +}; + +IN_PROC_BROWSER_TEST_F(SessionRestorePageLoadMetricsBrowserTest, + InitialVisibilityOfSingleRestoredTab) { + ui_test_utils::NavigateToURL(browser(), GetTestURL()); + histogram_tester_.ExpectTotalCount( + page_load_metrics::internal::kPageLoadStartedInForeground, 1); + histogram_tester_.ExpectBucketCount( + page_load_metrics::internal::kPageLoadStartedInForeground, true, 1); + + Browser* new_browser = QuitBrowserAndRestore(browser()); + WaitForTabsToLoad(new_browser); + + histogram_tester_.ExpectTotalCount( + page_load_metrics::internal::kPageLoadStartedInForeground, 2); + histogram_tester_.ExpectBucketCount( + page_load_metrics::internal::kPageLoadStartedInForeground, true, 2); +} + +IN_PROC_BROWSER_TEST_F(SessionRestorePageLoadMetricsBrowserTest, + InitialVisibilityOfMultipleRestoredTabs) { + ui_test_utils::NavigateToURL(browser(), GetTestURL()); + ui_test_utils::NavigateToURLWithDisposition( + browser(), GetTestURL(), WindowOpenDisposition::NEW_BACKGROUND_TAB, + ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); + histogram_tester_.ExpectTotalCount( + page_load_metrics::internal::kPageLoadStartedInForeground, 2); + histogram_tester_.ExpectBucketCount( + page_load_metrics::internal::kPageLoadStartedInForeground, false, 1); + + Browser* new_browser = QuitBrowserAndRestore(browser()); + WaitForTabsToLoad(new_browser); + + TabStripModel* tab_strip = new_browser->tab_strip_model(); + ASSERT_TRUE(tab_strip); + ASSERT_EQ(2, tab_strip->count()); + + histogram_tester_.ExpectTotalCount( + page_load_metrics::internal::kPageLoadStartedInForeground, 4); + histogram_tester_.ExpectBucketCount( + page_load_metrics::internal::kPageLoadStartedInForeground, true, 2); + histogram_tester_.ExpectBucketCount( + page_load_metrics::internal::kPageLoadStartedInForeground, false, 2); +}
diff --git a/chrome/browser/page_load_metrics/page_load_tracker.h b/chrome/browser/page_load_metrics/page_load_tracker.h index f8185b0..6146a09 100644 --- a/chrome/browser/page_load_metrics/page_load_tracker.h +++ b/chrome/browser/page_load_metrics/page_load_tracker.h
@@ -44,6 +44,7 @@ extern const char kAbortChainSizeNoCommit[]; extern const char kAbortChainSizeSameURL[]; extern const char kPageLoadCompletedAfterAppBackground[]; +extern const char kPageLoadStartedInForeground[]; } // namespace internal
diff --git a/chrome/browser/plugins/flash_permission_browsertest.cc b/chrome/browser/plugins/flash_permission_browsertest.cc index 508190b..d8f1dee 100644 --- a/chrome/browser/plugins/flash_permission_browsertest.cc +++ b/chrome/browser/plugins/flash_permission_browsertest.cc
@@ -2,21 +2,21 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "base/base_switches.h" #include "base/command_line.h" #include "base/memory/ptr_util.h" #include "base/path_service.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/permissions/permissions_browsertest.h" #include "chrome/browser/ui/permission_bubble/mock_permission_prompt_factory.h" +#include "chrome/common/chrome_features.h" #include "chrome/common/chrome_paths.h" #include "chrome/test/base/ui_test_utils.h" -#include "components/variations/variations_switches.h" #include "content/public/browser/render_frame_host.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/ppapi_test_utils.h" +#include "content/public/test/test_utils.h" #include "third_party/WebKit/public/platform/WebInputEvent.h" #include "url/gurl.h" @@ -55,13 +55,9 @@ // Set a high engagement threshhold so it doesn't interfere with testing the // permission. - command_line->AppendSwitchASCII(switches::kEnableFeatures, - "PreferHtmlOverPlugins<Study1"); - command_line->AppendSwitchASCII(switches::kForceFieldTrials, - "Study1/Enabled/"); - command_line->AppendSwitchASCII( - variations::switches::kForceFieldTrialParams, - "Study1.Enabled:engagement_threshold_for_flash/100"); + content::EnableFeatureWithParam(features::kPreferHtmlOverPlugins, + "engagement_threshold_for_flash", "100", + command_line); } void TriggerPrompt() override {
diff --git a/chrome/browser/policy/policy_browsertest.cc b/chrome/browser/policy/policy_browsertest.cc index fb5062f1..15be438 100644 --- a/chrome/browser/policy/policy_browsertest.cc +++ b/chrome/browser/policy/policy_browsertest.cc
@@ -12,7 +12,6 @@ #include <vector> #include "ash/accelerators/accelerator_controller_delegate_aura.h" -#include "base/base_switches.h" #include "base/bind.h" #include "base/bind_helpers.h" #include "base/callback.h" @@ -33,7 +32,6 @@ #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" -#include "base/test/scoped_feature_list.h" #include "base/test/test_file_util.h" #include "base/threading/thread_restrictions.h" #include "base/time/time.h" @@ -132,7 +130,6 @@ #include "components/update_client/url_request_post_interceptor.h" #include "components/user_prefs/user_prefs.h" #include "components/variations/service/variations_service.h" -#include "components/variations/variations_switches.h" #include "components/version_info/version_info.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_thread.h" @@ -4384,21 +4381,9 @@ class NetworkTimePolicyTest : public PolicyTest { public: void SetUpCommandLine(base::CommandLine* command_line) override { - command_line->AppendSwitchASCII( - switches::kForceFieldTrials, - "SSLNetworkTimeBrowserTestFieldTrial/Enabled/"); - command_line->AppendSwitchASCII( - variations::switches::kForceFieldTrialParams, - "SSLNetworkTimeBrowserTestFieldTrial.Enabled:FetchBehavior/" - "on-demand-only"); - } - - void SetUpOnMainThread() override { - PolicyTest::SetUpOnMainThread(); - scoped_feature_list_.InitFromCommandLine( - std::string(network_time::kNetworkTimeServiceQuerying.name) + - "<SSLNetworkTimeBrowserTestFieldTrial", - std::string()); + content::EnableFeatureWithParam(network_time::kNetworkTimeServiceQuerying, + "FetchBehavior", "on-demand-only", + command_line); } // A request handler that returns a dummy response and counts the number of @@ -4421,7 +4406,6 @@ private: uint32_t num_requests_ = 0; - base::test::ScopedFeatureList scoped_feature_list_; }; IN_PROC_BROWSER_TEST_F(NetworkTimePolicyTest, NetworkTimeQueriesDisabled) {
diff --git a/chrome/browser/predictors/resource_prefetch_predictor_browsertest.cc b/chrome/browser/predictors/resource_prefetch_predictor_browsertest.cc index 3915695..4ee5055c 100644 --- a/chrome/browser/predictors/resource_prefetch_predictor_browsertest.cc +++ b/chrome/browser/predictors/resource_prefetch_predictor_browsertest.cc
@@ -23,6 +23,7 @@ #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" #include "content/public/browser/browsing_data_remover.h" +#include "content/public/test/test_utils.h" #include "net/base/host_port_pair.h" #include "net/base/url_util.h" #include "net/dns/mock_host_resolver.h" @@ -321,13 +322,9 @@ using URLRequestSummary = URLRequestSummary; void SetUpCommandLine(base::CommandLine* command_line) override { - command_line->AppendSwitchASCII("force-fieldtrials", "trial/group"); - std::string parameter = base::StringPrintf( - "trial.group:%s/%s", kModeParamName, kExternalPrefetchingMode); - command_line->AppendSwitchASCII("force-fieldtrial-params", parameter); - std::string enabled_feature = base::StringPrintf( - "%s<trial", kSpeculativeResourcePrefetchingFeatureName); - command_line->AppendSwitchASCII("enable-features", enabled_feature); + content::EnableFeatureWithParam(kSpeculativeResourcePrefetchingFeature, + kModeParamName, kExternalPrefetchingMode, + command_line); } void SetUpOnMainThread() override {
diff --git a/chrome/browser/resources/settings/printing_page/cups_add_printer_dialog.js b/chrome/browser/resources/settings/printing_page/cups_add_printer_dialog.js index 2cccb4b..a04c9a79 100644 --- a/chrome/browser/resources/settings/printing_page/cups_add_printer_dialog.js +++ b/chrome/browser/resources/settings/printing_page/cups_add_printer_dialog.js
@@ -86,8 +86,10 @@ 'on-printer-discovered', this.onPrinterDiscovered_.bind(this)); this.addWebUIListener( 'on-printer-discovery-done', this.onPrinterDiscoveryDone_.bind(this)); - this.addWebUIListener( - 'on-printer-discovery-failed', this.onPrinterDiscoveryDone_.bind(this)); + }, + + close: function() { + this.$$('add-printer-dialog').close(); }, /** @@ -108,7 +110,10 @@ onPrinterDiscoveryDone_: function() { this.discovering_ = false; this.$$('add-printer-list').style.maxHeight = kPrinterListFullHeight + 'px'; - this.$.noPrinterMessage.hidden = !!this.discoveredPrinters; + this.$.noPrinterMessage.hidden = !!this.discoveredPrinters.length; + + if (!this.discoveredPrinters.length) + this.fire('no-detected-printer'); }, /** @private */ @@ -380,6 +385,7 @@ 'open-configuring-printer-dialog': 'openConfiguringPrinterDialog_', 'open-discovery-printers-dialog': 'openDiscoveryPrintersDialog_', 'open-manufacturer-model-dialog': 'openManufacturerModelDialog_', + 'no-detected-printer': 'onNoDetectedPrinter_', }, /** @override */ @@ -512,6 +518,17 @@ } }, + /** @private */ + onNoDetectedPrinter_: function() { + // If there is no detected printer, automatically open manually-add-printer + // dialog only when the user opens the discovery-dialog through the + // "ADD PRINTER" button. + if (!this.previousDialog_) { + this.$$('add-printer-discovery-dialog').close(); + this.openManuallyAddPrinterDialog_(); + } + }, + /** * Switch dialog from |fromDialog| to |toDialog|. * @param {string} fromDialog
diff --git a/chrome/browser/safe_browsing/certificate_reporting_service_browsertest.cc b/chrome/browser/safe_browsing/certificate_reporting_service_browsertest.cc index 468c1e69..89d6b6a 100644 --- a/chrome/browser/safe_browsing/certificate_reporting_service_browsertest.cc +++ b/chrome/browser/safe_browsing/certificate_reporting_service_browsertest.cc
@@ -4,7 +4,6 @@ #include "chrome/browser/safe_browsing/certificate_reporting_service.h" -#include "base/base_switches.h" #include "base/command_line.h" #include "base/macros.h" #include "base/test/histogram_tester.h" @@ -25,7 +24,7 @@ #include "components/certificate_reporting/error_report.h" #include "components/prefs/pref_service.h" #include "components/safe_browsing/common/safe_browsing_prefs.h" -#include "components/variations/variations_switches.h" +#include "components/variations/variations_params_manager.h" #include "content/public/browser/web_contents.h" #include "content/public/test/browser_test_utils.h" #include "content/public/test/test_utils.h" @@ -108,13 +107,10 @@ } void SetUpCommandLine(base::CommandLine* command_line) override { - command_line->AppendSwitchASCII( - switches::kForceFieldTrials, - "ReportCertificateErrors/ShowAndPossiblySend/"); // Setting the sending threshold to 1.0 ensures reporting is enabled. - command_line->AppendSwitchASCII( - variations::switches::kForceFieldTrialParams, - "ReportCertificateErrors.ShowAndPossiblySend:sendingThreshold/1.0"); + variations::testing::VariationParamsManager::AppendVariationParams( + "ReportCertificateErrors", "ShowAndPossiblySend", + {{"sendingThreshold", "1.0"}}, command_line); } CertificateReportingServiceTestHelper* test_helper() { return &test_helper_; }
diff --git a/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_win.cc b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_win.cc index b0f2d24..9777cb9 100644 --- a/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_win.cc +++ b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_win.cc
@@ -157,11 +157,6 @@ base::BindOnce(&OnChromeCleanerFetched, base::Passed(&fetched_callback))); } -bool ChromeCleanerControllerDelegate:: - SafeBrowsingExtendedReportingScoutEnabled() { - return safe_browsing::SafeBrowsingExtendedReportingScoutEnabled(); -} - bool ChromeCleanerControllerDelegate::IsMetricsAndCrashReportingEnabled() { return ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled(); } @@ -404,14 +399,8 @@ ? ChromeCleanerRunner::ChromeMetricsStatus::kEnabled : ChromeCleanerRunner::ChromeMetricsStatus::kDisabled; - ChromeCleanerRunner::CleanerLogsStatus cleaner_logs_status = - delegate_->SafeBrowsingExtendedReportingScoutEnabled() - ? ChromeCleanerRunner::CleanerLogsStatus::kUploadEnabled - : ChromeCleanerRunner::CleanerLogsStatus::kUploadDisabled; - ChromeCleanerRunner::RunChromeCleanerAndReplyWithExitCode( executable_path, *reporter_invocation_, metrics_status, - cleaner_logs_status, base::Bind(&ChromeCleanerController::WeakOnPromptUser, weak_factory_.GetWeakPtr()), base::Bind(&ChromeCleanerController::OnConnectionClosed,
diff --git a/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_win.h b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_win.h index 8ed8f3b..3715aa17 100644 --- a/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_win.h +++ b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_win.h
@@ -50,7 +50,6 @@ // extension. If the operation fails, the file name passed to // |fecthed_callback| will be empty. virtual void FetchAndVerifyChromeCleaner(FetchedCallback fetched_callback); - virtual bool SafeBrowsingExtendedReportingScoutEnabled(); virtual bool IsMetricsAndCrashReportingEnabled(); // Auxiliary methods for tagging and resetting open profiles.
diff --git a/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_win_unittest.cc b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_win_unittest.cc index d63a48c..95eb6dbc 100644 --- a/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_win_unittest.cc +++ b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_win_unittest.cc
@@ -84,11 +84,6 @@ kDisabled, }; -enum class ScoutStatus { - kEnabled, - kDisabled, -}; - // Simple test fixture that passes an invalid process handle back to the // ChromeCleanerRunner class and is intended for testing simple things like // command line flags that Chrome sends to the Chrome Cleaner process. @@ -96,10 +91,8 @@ // Parameters: // - metrics_status (MetricsStatus): whether Chrome metrics reporting is // enabled. -// - scout_status (ScoutStatus): whether logs upload in the Cleaner process -// should be enabled. class ChromeCleanerControllerSimpleTest - : public testing::TestWithParam<std::tuple<MetricsStatus, ScoutStatus>>, + : public testing::TestWithParam<MetricsStatus>, public ChromeCleanerRunnerTestDelegate, public ChromeCleanerControllerDelegate { public: @@ -109,12 +102,9 @@ ~ChromeCleanerControllerSimpleTest() override {} void SetUp() override { - MetricsStatus metrics_status; - ScoutStatus scout_status; - std::tie(metrics_status, scout_status) = GetParam(); + MetricsStatus metrics_status = GetParam(); metrics_enabled_ = metrics_status == MetricsStatus::kEnabled; - scout_enabled_ = scout_status == ScoutStatus::kEnabled; SetChromeCleanerRunnerTestDelegateForTesting(this); ChromeCleanerController::ResetInstanceForTesting(); @@ -136,10 +126,6 @@ .Run(base::FilePath(FILE_PATH_LITERAL("chrome_cleaner.exe"))); } - bool SafeBrowsingExtendedReportingScoutEnabled() override { - return scout_enabled_; - } - bool IsMetricsAndCrashReportingEnabled() override { return metrics_enabled_; } void TagForResetting(Profile* profile) override { @@ -174,7 +160,6 @@ base::test::ScopedFeatureList scoped_feature_list_; bool metrics_enabled_; - bool scout_enabled_; base::CommandLine command_line_; StrictMock<MockChromeCleanerControllerObserver> mock_observer_; @@ -212,17 +197,14 @@ command_line_.HasSwitch(chrome_cleaner::kUmaUserSwitch)); EXPECT_EQ(metrics_enabled_, command_line_.HasSwitch( chrome_cleaner::kEnableCrashReportingSwitch)); - EXPECT_EQ(scout_enabled_, command_line_.HasSwitch( - chrome_cleaner::kEnableCleanerLoggingSwitch)); controller->RemoveObserver(&mock_observer_); } -INSTANTIATE_TEST_CASE_P( - All, - ChromeCleanerControllerSimpleTest, - Combine(Values(MetricsStatus::kDisabled, MetricsStatus::kEnabled), - Values(ScoutStatus::kDisabled, ScoutStatus::kEnabled))); +INSTANTIATE_TEST_CASE_P(All, + ChromeCleanerControllerSimpleTest, + Values(MetricsStatus::kDisabled, + MetricsStatus::kEnabled)); enum class CleanerProcessStatus { kFetchFailure, @@ -290,12 +272,6 @@ : base::FilePath())); } - bool SafeBrowsingExtendedReportingScoutEnabled() override { - // Returning an arbitrary value since this is not being tested in this - // fixture. - return false; - } - bool IsMetricsAndCrashReportingEnabled() override { // Returning an arbitrary value since this is not being tested in this // fixture.
diff --git a/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_runner_win.cc b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_runner_win.cc index 8724e44..e5066b4 100644 --- a/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_runner_win.cc +++ b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_runner_win.cc
@@ -51,16 +51,14 @@ const base::FilePath& cleaner_executable_path, const SwReporterInvocation& reporter_invocation, ChromeMetricsStatus metrics_status, - CleanerLogsStatus cleaner_logs_status, ChromePromptImpl::OnPromptUser on_prompt_user, base::OnceClosure on_connection_closed, ChromeCleanerRunner::ProcessDoneCallback on_process_done, scoped_refptr<base::SequencedTaskRunner> task_runner) { auto cleaner_runner = make_scoped_refptr(new ChromeCleanerRunner( cleaner_executable_path, reporter_invocation, metrics_status, - cleaner_logs_status, std::move(on_prompt_user), - std::move(on_connection_closed), std::move(on_process_done), - std::move(task_runner))); + std::move(on_prompt_user), std::move(on_connection_closed), + std::move(on_process_done), std::move(task_runner))); auto launch_and_wait = base::BindOnce( &ChromeCleanerRunner::LaunchAndWaitForExitOnBackgroundThread, cleaner_runner); @@ -80,7 +78,6 @@ const base::FilePath& cleaner_executable_path, const SwReporterInvocation& reporter_invocation, ChromeMetricsStatus metrics_status, - CleanerLogsStatus cleaner_logs_status, ChromePromptImpl::OnPromptUser on_prompt_user, base::OnceClosure on_connection_closed, ProcessDoneCallback on_process_done, @@ -133,12 +130,6 @@ cleaner_command_line_.AppendSwitch( chrome_cleaner::kEnableCrashReportingSwitch); } - - // Enable logs upload for users who have opted into safe browsing extended - // reporting v2. - if (cleaner_logs_status == CleanerLogsStatus::kUploadEnabled) - cleaner_command_line_.AppendSwitch( - chrome_cleaner::kEnableCleanerLoggingSwitch); } ChromeCleanerRunner::ProcessStatus
diff --git a/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_runner_win.h b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_runner_win.h index 7e92607d..86985d1 100644 --- a/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_runner_win.h +++ b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_runner_win.h
@@ -54,11 +54,6 @@ kDisabled, }; - enum class CleanerLogsStatus { - kUploadEnabled, - kUploadDisabled, - }; - enum class LaunchStatus { // Got an invalid process when attempting to launch the Chrome Cleaner // process. As a result, the Mojo pipe was never set up and the @@ -94,11 +89,11 @@ // // This function will pass command line flags to the Chrome Cleaner executable // as appropriate based on the flags in |reporter_invocation| and the - // |metrics_status| and |cleaner_logs_status| parameters. The Cleaner process - // will communicate with Chrome via a Mojo IPC interface and any IPC requests - // or notifications are passed to the caller via the |on_prompt_user| and - // |on_connection_closed| callbacks. Finally, when the Chrome Cleaner process - // terminates, a ProcessStatus is passed along to |on_process_done|. + // |metrics_status| parameters The Cleaner process will communicate with + // Chrome via a Mojo IPC interface and any IPC requests or notifications are + // passed to the caller via the |on_prompt_user| and |on_connection_closed| + // callbacks. Finally, when the Chrome Cleaner process terminates, a + // ProcessStatus is passed along to |on_process_done|. // // The details of the mojo interface are documented in // "components/chrome_cleaner/public/interfaces/chrome_prompt.mojom.h". @@ -106,7 +101,6 @@ const base::FilePath& cleaner_executable_path, const SwReporterInvocation& reporter_invocation, ChromeMetricsStatus metrics_status, - CleanerLogsStatus cleaner_logs_status, ChromePromptImpl::OnPromptUser on_prompt_user, base::OnceClosure on_connection_closed, ChromeCleanerRunner::ProcessDoneCallback on_process_done, @@ -120,7 +114,6 @@ ChromeCleanerRunner(const base::FilePath& cleaner_executable_path, const SwReporterInvocation& reporter_invocation, ChromeMetricsStatus metrics_status, - CleanerLogsStatus cleaner_logs_status, ChromePromptImpl::OnPromptUser on_prompt_user, base::OnceClosure on_connection_closed, ChromeCleanerRunner::ProcessDoneCallback on_process_done,
diff --git a/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_runner_win_unittest.cc b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_runner_win_unittest.cc index 93f3539e..9a066ce 100644 --- a/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_runner_win_unittest.cc +++ b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_runner_win_unittest.cc
@@ -38,7 +38,6 @@ using ::testing::Combine; using ::testing::Values; using ChromeMetricsStatus = ChromeCleanerRunner::ChromeMetricsStatus; -using CleanerLogsStatus = ChromeCleanerRunner::CleanerLogsStatus; enum class ReporterEngine { kUnspecified, @@ -55,14 +54,11 @@ // Parameters: // - metrics_status (ChromeMetricsStatus): whether Chrome metrics reporting is // enabled -// - logs_upload_status (CleanerLogsStatus): whether logs upload in the Cleaner -// process should be enabled. // - reporter_engine (ReporterEngine): the type of Cleaner engine specified in // the SwReporterInvocation. class ChromeCleanerRunnerSimpleTest : public testing::TestWithParam< std::tuple<ChromeCleanerRunner::ChromeMetricsStatus, - ChromeCleanerRunner::CleanerLogsStatus, ReporterEngine>>, public ChromeCleanerRunnerTestDelegate { public: @@ -70,8 +66,7 @@ : command_line_(base::CommandLine::NO_PROGRAM) {} void SetUp() override { - std::tie(metrics_status_, logs_upload_status_, reporter_engine_) = - GetParam(); + std::tie(metrics_status_, reporter_engine_) = GetParam(); SetChromeCleanerRunnerTestDelegateForTesting(this); scoped_feature_list_.InitAndEnableFeature(kInBrowserCleanerUIFeature); @@ -95,7 +90,7 @@ ChromeCleanerRunner::RunChromeCleanerAndReplyWithExitCode( base::FilePath(FILE_PATH_LITERAL("cleaner.exe")), reporter_invocation, - metrics_status_, logs_upload_status_, + metrics_status_, base::BindOnce(&ChromeCleanerRunnerSimpleTest::OnPromptUser, base::Unretained(this)), base::BindOnce(&ChromeCleanerRunnerSimpleTest::OnConnectionClosed, @@ -137,7 +132,6 @@ // Test fixture parameters. ChromeCleanerRunner::ChromeMetricsStatus metrics_status_; - ChromeCleanerRunner::CleanerLogsStatus logs_upload_status_; ReporterEngine reporter_engine_; // Set by LaunchTestProcess. @@ -179,10 +173,6 @@ EXPECT_EQ( metrics_status_ == ChromeMetricsStatus::kEnabled, command_line_.HasSwitch(chrome_cleaner::kEnableCrashReportingSwitch)); - - EXPECT_EQ( - logs_upload_status_ == CleanerLogsStatus::kUploadEnabled, - command_line_.HasSwitch(chrome_cleaner::kEnableCleanerLoggingSwitch)); } INSTANTIATE_TEST_CASE_P( @@ -190,8 +180,6 @@ ChromeCleanerRunnerSimpleTest, Combine(Values(ChromeCleanerRunner::ChromeMetricsStatus::kEnabled, ChromeCleanerRunner::ChromeMetricsStatus::kDisabled), - Values(ChromeCleanerRunner::CleanerLogsStatus::kUploadEnabled, - ChromeCleanerRunner::CleanerLogsStatus::kUploadDisabled), Values(ReporterEngine::kUnspecified, ReporterEngine::kOldEngine, ReporterEngine::kNewEngine))); @@ -250,7 +238,6 @@ ChromeCleanerRunner::RunChromeCleanerAndReplyWithExitCode( base::FilePath(FILE_PATH_LITERAL("cleaner.exe")), SwReporterInvocation(), ChromeMetricsStatus::kDisabled, - CleanerLogsStatus::kUploadDisabled, base::BindOnce(&ChromeCleanerRunnerTest::OnPromptUser, base::Unretained(this)), base::BindOnce(&ChromeCleanerRunnerTest::OnConnectionClosed,
diff --git a/chrome/browser/safe_browsing/test_safe_browsing_blocking_page_quiet.cc b/chrome/browser/safe_browsing/test_safe_browsing_blocking_page_quiet.cc index 1cc4321..26626ea5 100644 --- a/chrome/browser/safe_browsing/test_safe_browsing_blocking_page_quiet.cc +++ b/chrome/browser/safe_browsing/test_safe_browsing_blocking_page_quiet.cc
@@ -20,13 +20,15 @@ const UnsafeResourceList& unsafe_resources, const BaseSafeBrowsingErrorUI::SBErrorDisplayOptions& display_options, bool is_giant_webview) - : BaseBlockingPage( - ui_manager, - web_contents, - main_frame_url, - unsafe_resources, - CreateControllerClient(web_contents, unsafe_resources, ui_manager), - display_options), + : BaseBlockingPage(ui_manager, + web_contents, + main_frame_url, + unsafe_resources, + CreateControllerClient(web_contents, + unsafe_resources, + ui_manager, + nullptr), + display_options), sb_error_ui_(unsafe_resources[0].url, main_frame_url, GetInterstitialReason(unsafe_resources),
diff --git a/chrome/browser/sessions/session_restore.cc b/chrome/browser/sessions/session_restore.cc index b8bf25a4..8d64156 100644 --- a/chrome/browser/sessions/session_restore.cc +++ b/chrome/browser/sessions/session_restore.cc
@@ -613,13 +613,12 @@ WebContents* web_contents = chrome::AddRestoredTab( browser, tab.navigations, tab_index, selected_index, - tab.extension_app_id, - false, // select - tab.pinned, true, session_storage_namespace.get(), - tab.user_agent_override); - // Regression check: check that the tab didn't start loading right away. The + tab.extension_app_id, is_selected_tab, tab.pinned, true, + session_storage_namespace.get(), tab.user_agent_override); + // Regression check: if the current tab |is_selected_tab|, it should load + // immediately, otherwise, tabs should not start loading right away. The // focused tab will be loaded by Browser, and TabLoader will load the rest. - DCHECK(web_contents->GetController().NeedsReload()); + DCHECK(is_selected_tab || web_contents->GetController().NeedsReload()); return web_contents; }
diff --git a/chrome/browser/sessions/session_restore_browsertest_chromeos.cc b/chrome/browser/sessions/session_restore_browsertest_chromeos.cc index de48f66..e2c1259771 100644 --- a/chrome/browser/sessions/session_restore_browsertest_chromeos.cc +++ b/chrome/browser/sessions/session_restore_browsertest_chromeos.cc
@@ -198,8 +198,8 @@ ++minimized_count; } EXPECT_EQ(2u, total_count); - // Chrome OS always activates the last browser window on login, which results - // in one window being restored. This seems reasonable as it reminds users - // they have a browser running instead of just showing them an empty desktop. - EXPECT_EQ(1u, minimized_count); + // Chrome OS always activates the last browser windows on login to remind + // users they have a browser running instead of just showing them an empty + // desktop. + EXPECT_EQ(0u, minimized_count); }
diff --git a/chrome/browser/ssl/captive_portal_blocking_page_browsertest.cc b/chrome/browser/ssl/captive_portal_blocking_page_browsertest.cc index e7f3115..e49edc877 100644 --- a/chrome/browser/ssl/captive_portal_blocking_page_browsertest.cc +++ b/chrome/browser/ssl/captive_portal_blocking_page_browsertest.cc
@@ -7,7 +7,6 @@ #include <string> #include <utility> -#include "base/base_switches.h" #include "base/bind_helpers.h" #include "base/callback.h" #include "base/command_line.h" @@ -28,7 +27,7 @@ #include "components/captive_portal/captive_portal_detector.h" #include "components/prefs/pref_service.h" #include "components/security_state/core/security_state.h" -#include "components/variations/variations_switches.h" +#include "components/variations/variations_params_manager.h" #include "content/public/browser/interstitial_page.h" #include "content/public/browser/web_contents.h" #include "content/public/test/browser_test_utils.h" @@ -100,13 +99,10 @@ } void SetUpCommandLine(base::CommandLine* command_line) override { - command_line->AppendSwitchASCII( - switches::kForceFieldTrials, - "ReportCertificateErrors/ShowAndPossiblySend/"); // Setting the sending threshold to 1.0 ensures reporting is enabled. - command_line->AppendSwitchASCII( - variations::switches::kForceFieldTrialParams, - "ReportCertificateErrors.ShowAndPossiblySend:sendingThreshold/1.0"); + variations::testing::VariationParamsManager::AppendVariationParams( + "ReportCertificateErrors", "ShowAndPossiblySend", + {{"sendingThreshold", "1.0"}}, command_line); } void TestInterstitial(bool is_wifi_connection,
diff --git a/chrome/browser/ssl/cert_report_helper.cc b/chrome/browser/ssl/cert_report_helper.cc index 923ee3d..02c67fb 100644 --- a/chrome/browser/ssl/cert_report_helper.cc +++ b/chrome/browser/ssl/cert_report_helper.cc
@@ -28,6 +28,12 @@ #include "content/public/browser/web_contents.h" #include "ui/base/l10n/l10n_util.h" +#if defined(OS_WIN) +#include "base/win/win_util.h" +#elif defined(OS_CHROMEOS) +#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" +#endif + namespace { // Certificate reports are only sent from official builds, but this flag can be @@ -128,6 +134,14 @@ report.AddChromeChannel(chrome::GetChannel()); +#if defined(OS_WIN) + report.SetIsEnterpriseManaged(base::win::IsEnterpriseManaged()); +#elif defined(OS_CHROMEOS) + report.SetIsEnterpriseManaged(g_browser_process->platform_part() + ->browser_policy_connector_chromeos() + ->IsEnterpriseManaged()); +#endif + report.SetInterstitialInfo( interstitial_reason_, user_proceeded, overridable_
diff --git a/chrome/browser/tracing/chrome_tracing_delegate_browsertest.cc b/chrome/browser/tracing/chrome_tracing_delegate_browsertest.cc index 7b4504cf..17a1177 100644 --- a/chrome/browser/tracing/chrome_tracing_delegate_browsertest.cc +++ b/chrome/browser/tracing/chrome_tracing_delegate_browsertest.cc
@@ -4,7 +4,6 @@ #include <utility> -#include "base/base_switches.h" #include "base/bind.h" #include "base/command_line.h" #include "build/build_config.h" @@ -17,7 +16,7 @@ #include "chrome/test/base/in_process_browser_test.h" #include "components/metrics/metrics_pref_names.h" #include "components/prefs/pref_service.h" -#include "components/variations/variations_switches.h" +#include "components/variations/variations_params_manager.h" #include "content/public/browser/background_tracing_config.h" #include "content/public/browser/background_tracing_manager.h" #include "content/public/browser/browser_thread.h" @@ -251,11 +250,9 @@ } void SetUpCommandLine(base::CommandLine* command_line) override { - base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( - switches::kForceFieldTrials, "BackgroundTracing/TestGroup/"); - base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( - variations::switches::kForceFieldTrialParams, - "BackgroundTracing.TestGroup:config/default_config_for_testing"); + variations::testing::VariationParamsManager::AppendVariationParams( + "BackgroundTracing", "TestGroup", + {{"config", "default_config_for_testing"}}, command_line); tracing::SetConfigTextFilterForTesting(&FieldTrialConfigTextFilter); }
diff --git a/chrome/browser/ui/app_list/search/answer_card/answer_card_web_contents.cc b/chrome/browser/ui/app_list/search/answer_card/answer_card_web_contents.cc index e8de4cb..34631a1 100644 --- a/chrome/browser/ui/app_list/search/answer_card/answer_card_web_contents.cc +++ b/chrome/browser/ui/app_list/search/answer_card/answer_card_web_contents.cc
@@ -71,6 +71,7 @@ web_contents_->SetDelegate(this); web_view_->set_owned_by_client(); web_view_->SetWebContents(web_contents_.get()); + web_view_->SetResizeBackgroundColor(SK_ColorTRANSPARENT); // Make the webview transparent since it's going to be shown on top of a // highlightable button.
diff --git a/chrome/browser/ui/ash/DEPS b/chrome/browser/ui/ash/DEPS index 367f2d98..86434f62 100644 --- a/chrome/browser/ui/ash/DEPS +++ b/chrome/browser/ui/ash/DEPS
@@ -11,13 +11,3 @@ "+mash/shelf/public/interfaces", "+media", ] -specific_include_rules = { - # Allow ash::SessionStateDelegate for SessionStateDelegateChromeOS. - # SessionStateDelegate is deprecated. Chrome code should not use it anymore. - # Instead, SessionManager/UserManager/SessionControllerClient should be used. - # This is temporary rule before SessionStateDelegate(ChromeOS) can be fully - # removed. - "session_state_delegate_chromeos\.(cc|h)": [ - "+ash/session", - ] -}
diff --git a/chrome/browser/ui/autofill/chrome_autofill_client.cc b/chrome/browser/ui/autofill/chrome_autofill_client.cc index 93c22f4..9768baf3 100644 --- a/chrome/browser/ui/autofill/chrome_autofill_client.cc +++ b/chrome/browser/ui/autofill/chrome_autofill_client.cc
@@ -27,6 +27,7 @@ #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/chrome_pages.h" #include "chrome/browser/ui/tabs/tab_strip_model_observer.h" +#include "chrome/browser/vr/vr_tab_helper.h" #include "chrome/browser/web_data_service_factory.h" #include "chrome/common/url_constants.h" #include "components/autofill/content/browser/content_autofill_driver.h" @@ -405,4 +406,12 @@ false /* is_renderer_initiated */)); } +bool ChromeAutofillClient::IsAutofillSupported() { + // VR browsing does not support popups at the moment. + if (vr::VrTabHelper::IsInVr(web_contents())) + return false; + + return true; +} + } // namespace autofill
diff --git a/chrome/browser/ui/autofill/chrome_autofill_client.h b/chrome/browser/ui/autofill/chrome_autofill_client.h index 0e9dd28..e3c2042 100644 --- a/chrome/browser/ui/autofill/chrome_autofill_client.h +++ b/chrome/browser/ui/autofill/chrome_autofill_client.h
@@ -90,6 +90,7 @@ bool ShouldShowSigninPromo() override; void StartSigninFlow() override; void ShowHttpNotSecureExplanation() override; + bool IsAutofillSupported() override; // content::WebContentsObserver implementation. void MainFrameWasResized(bool width_changed) override;
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc index 37094f1..37240d2 100644 --- a/chrome/browser/ui/views/frame/browser_view.cc +++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -1973,9 +1973,14 @@ if (!widget) return; - if (!initialized_ && details.is_add) { + bool init = !initialized_ && details.is_add; + if (init) { InitViews(); initialized_ = true; + } + +#if defined(USE_AURA) + if (init) { if (base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kEnableExperimentalFullscreenExitUI)) { widget->GetNativeView()->AddPreTargetHandler(GetFullscreenControlHost()); @@ -1985,6 +1990,7 @@ if (native_view) native_view->RemovePreTargetHandler(fullscreen_control_host_.get()); } +#endif } void BrowserView::PaintChildren(const ui::PaintContext& context) {
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index cfceb1c5a..cf44149 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -138,6 +138,7 @@ "//components/sync_sessions:test_support", "//components/toolbar:test_support", "//components/update_client:test_support", + "//components/variations:test_support", "//components/web_resource:test_support", "//content/public/app:both", "//content/public/child", @@ -3488,7 +3489,6 @@ "//components/sync:test_support_driver", "//components/sync:test_support_model", "//components/sync_sessions:test_support", - "//components/variations:test_support", "//components/version_info:generate_version_info", "//components/webdata_services:test_support", "//content/app/resources",
diff --git a/chrome/test/android/BUILD.gn b/chrome/test/android/BUILD.gn index 8220260..a0a7ef24 100644 --- a/chrome/test/android/BUILD.gn +++ b/chrome/test/android/BUILD.gn
@@ -63,9 +63,6 @@ "javatests/src/org/chromium/chrome/test/util/NewTabPageTestUtils.java", "javatests/src/org/chromium/chrome/test/util/OmniboxTestUtils.java", "javatests/src/org/chromium/chrome/test/util/OverviewModeBehaviorWatcher.java", - "javatests/src/org/chromium/chrome/test/util/parameters/AddFakeAccountToAppParameter.java", - "javatests/src/org/chromium/chrome/test/util/parameters/AddFakeAccountToOsParameter.java", - "javatests/src/org/chromium/chrome/test/util/parameters/AddGoogleAccountToOsParameter.java", "javatests/src/org/chromium/chrome/test/util/PrerenderTestHelper.java", "javatests/src/org/chromium/chrome/test/util/RenderTestRule.java", "javatests/src/org/chromium/chrome/test/util/TabStripUtils.java",
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/ChromeActivityTestCaseBase.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/ChromeActivityTestCaseBase.java index 60899e8..84d146a 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/ChromeActivityTestCaseBase.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/ChromeActivityTestCaseBase.java
@@ -12,7 +12,6 @@ import org.chromium.base.test.BaseActivityInstrumentationTestCase; import org.chromium.base.test.util.CommandLineFlags; -import org.chromium.base.test.util.parameter.BaseParameter; import org.chromium.chrome.browser.ChromeActivity; import org.chromium.chrome.browser.ChromeSwitches; import org.chromium.chrome.browser.infobar.InfoBar; @@ -21,14 +20,10 @@ import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.test.ChromeActivityTestCommon.ChromeTestCommonCallback; import org.chromium.chrome.test.util.ApplicationTestUtils; -import org.chromium.chrome.test.util.parameters.AddFakeAccountToAppParameter; -import org.chromium.chrome.test.util.parameters.AddFakeAccountToOsParameter; -import org.chromium.chrome.test.util.parameters.AddGoogleAccountToOsParameter; import org.chromium.content.browser.test.util.TestTouchUtils; import org.chromium.content.browser.test.util.TouchCommon; import java.util.List; -import java.util.Map; import java.util.concurrent.TimeoutException; /** @@ -376,18 +371,6 @@ return mTestCommon.runJavaScriptCodeInCurrentTab(code); } - @Override - protected Map<String, BaseParameter> createAvailableParameters() { - Map<String, BaseParameter> availableParameters = super.createAvailableParameters(); - availableParameters.put(AddFakeAccountToAppParameter.PARAMETER_TAG, - new AddFakeAccountToAppParameter(getParameterReader(), getInstrumentation())); - availableParameters.put(AddFakeAccountToOsParameter.PARAMETER_TAG, - new AddFakeAccountToOsParameter(getParameterReader(), getInstrumentation())); - availableParameters.put(AddGoogleAccountToOsParameter.PARAMETER_TAG, - new AddGoogleAccountToOsParameter(getParameterReader(), getInstrumentation())); - return availableParameters; - } - /** * Waits till the ContentViewCore receives the expected page scale factor * from the compositor and asserts that this happens.
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/MultiActivityTestBase.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/MultiActivityTestBase.java index 0b22331a..f2a2e966 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/MultiActivityTestBase.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/MultiActivityTestBase.java
@@ -8,32 +8,18 @@ import android.test.InstrumentationTestCase; import org.chromium.base.test.util.CommandLineFlags; -import org.chromium.base.test.util.parameter.BaseParameter; -import org.chromium.base.test.util.parameter.Parameter; -import org.chromium.base.test.util.parameter.Parameterizable; -import org.chromium.base.test.util.parameter.parameters.MethodParameter; import org.chromium.chrome.browser.ChromeActivity; import org.chromium.chrome.browser.ChromeSwitches; import org.chromium.chrome.test.util.browser.tabmodel.document.MockStorageDelegate; -import org.chromium.chrome.test.util.parameters.AddFakeAccountToAppParameter; -import org.chromium.chrome.test.util.parameters.AddFakeAccountToOsParameter; -import org.chromium.chrome.test.util.parameters.AddGoogleAccountToOsParameter; - -import java.util.HashMap; -import java.util.Map; /** * Base for testing and interacting with multiple Activities (e.g. Document or Webapp Activities). */ @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) public abstract class MultiActivityTestBase extends InstrumentationTestCase - implements Parameterizable, MultiActivityTestCommon.MultiActivityTestCommonCallback { + implements MultiActivityTestCommon.MultiActivityTestCommonCallback { private final MultiActivityTestCommon mTestCommon; - private Parameter.Reader mParameterReader; - - private Map<String, BaseParameter> mAvailableParameters; - public MultiActivityTestBase() { mTestCommon = new MultiActivityTestCommon(this); } @@ -73,66 +59,4 @@ boolean waitLongerForLoad) { mTestCommon.waitForFullLoad(activity, expectedTitle, waitLongerForLoad); } - - /** - * Creates the {@link Map} of available parameters for the test to use. - * - * @return a {@link Map} of {@link BaseParameter} objects. - */ - protected Map<String, BaseParameter> createAvailableParameters() { - Map<String, BaseParameter> availableParameters = new HashMap<>(); - availableParameters - .put(MethodParameter.PARAMETER_TAG, new MethodParameter(getParameterReader())); - availableParameters.put(AddFakeAccountToAppParameter.PARAMETER_TAG, - new AddFakeAccountToAppParameter(getParameterReader(), getInstrumentation())); - availableParameters.put(AddFakeAccountToOsParameter.PARAMETER_TAG, - new AddFakeAccountToOsParameter(getParameterReader(), getInstrumentation())); - availableParameters.put(AddGoogleAccountToOsParameter.PARAMETER_TAG, - new AddGoogleAccountToOsParameter(getParameterReader(), getInstrumentation())); - return availableParameters; - } - - /** - * Gets the {@link Map} of available parameters that inherited classes can use. - * - * @return a {@link Map} of {@link BaseParameter} objects to set as the available parameters. - */ - @Override - public Map<String, BaseParameter> getAvailableParameters() { - return mAvailableParameters; - } - - /** - * Gets a specific parameter from the current test. - * - * @param parameterTag a string with the name of the {@link BaseParameter} we want. - * @return a parameter that extends {@link BaseParameter} that has the matching parameterTag. - */ - @Override - @SuppressWarnings("unchecked") - public <T extends BaseParameter> T getAvailableParameter(String parameterTag) { - return (T) mAvailableParameters.get(parameterTag); - } - - /** - * Setter method for {@link Parameter.Reader}. - * - * @param parameterReader the {@link Parameter.Reader} to set. - */ - @Override - public void setParameterReader(Parameter.Reader parameterReader) { - mParameterReader = parameterReader; - mAvailableParameters = createAvailableParameters(); - } - - /** - * Getter method for {@link Parameter.Reader} object to be used by test cases reading the - * parameter. - * - * @return the {@link Parameter.Reader} for the current {@link - * org.chromium.base.test.util.parameter.ParameterizedTest} being run. - */ - protected Parameter.Reader getParameterReader() { - return mParameterReader; - } }
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/parameters/AddFakeAccountToAppParameter.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/parameters/AddFakeAccountToAppParameter.java deleted file mode 100644 index afd656c3c..0000000 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/parameters/AddFakeAccountToAppParameter.java +++ /dev/null
@@ -1,68 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.test.util.parameters; - -import android.app.Instrumentation; - -import org.chromium.base.ThreadUtils; -import org.chromium.base.test.util.parameter.BaseParameter; -import org.chromium.base.test.util.parameter.Parameter; -import org.chromium.chrome.browser.init.ProcessInitializationHandler; -import org.chromium.chrome.test.util.ChromeSigninUtils; -import org.chromium.components.signin.ChromeSigninController; - -/** - * Adds a fake account to app when this parameter is used. - */ -public class AddFakeAccountToAppParameter extends BaseParameter { - /** Adds a fake test account to app to run test as signed into the app. */ - public static final String PARAMETER_TAG = "add-fake-account-to-app-parameter"; - - /** The {@Parameter.Argument#name()} value. */ - public static final class ARGUMENT { - public static final String USERNAME = "username"; - private static final class DEFAULT { - private static final String USERNAME = "test@google.com"; - } - } - - private ChromeSigninController mSigninController; - private ChromeSigninUtils mSigninUtil; - - public AddFakeAccountToAppParameter(Parameter.Reader parameterReader, - Instrumentation instrumentation) { - super(PARAMETER_TAG, parameterReader); - ThreadUtils.runOnUiThreadBlocking(new Runnable() { - @Override - public void run() { - ProcessInitializationHandler.getInstance().initializePreNative(); - } - }); - mSigninController = ChromeSigninController.get(); - mSigninUtil = new ChromeSigninUtils(instrumentation); - } - - @Override - public void setUp() { - String username = getStringArgument(ARGUMENT.USERNAME, ARGUMENT.DEFAULT.USERNAME); - - mSigninController.setSignedInAccountName(null); - mSigninUtil.addAccountToApp(username); - } - - @Override - public void tearDown() { - mSigninController.setSignedInAccountName(null); - } - - /** - * Only affects Java tests. - * - * @return {@code true} if an account is on the app, {@code false} otherwise. - */ - public boolean isSignedIn() { - return mSigninController.isSignedIn(); - } -}
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/parameters/AddFakeAccountToOsParameter.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/parameters/AddFakeAccountToOsParameter.java deleted file mode 100644 index 2d09beb5..0000000 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/parameters/AddFakeAccountToOsParameter.java +++ /dev/null
@@ -1,59 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.test.util.parameters; - -import android.app.Instrumentation; - -import org.chromium.base.test.util.parameter.BaseParameter; -import org.chromium.base.test.util.parameter.Parameter; -import org.chromium.chrome.test.util.ChromeSigninUtils; - -/** - * Adds a fake account to OS when this parameter is used. - */ -public class AddFakeAccountToOsParameter extends BaseParameter { - /** Adds a fake test account to OS to run test as signed into the OS. */ - public static final String PARAMETER_TAG = "add-fake-account-to-os-parameter"; - - /** The {@Parameter.Argument#name()} value. */ - public static final class ARGUMENT { - public static final String USERNAME = "username"; - public static final String PASSWORD = "password"; - private static final class DEFAULT { - private static final String USERNAME = "test@google.com"; - private static final String PASSWORD = "$3cr3t"; - } - } - - private ChromeSigninUtils mSigninUtil; - - public AddFakeAccountToOsParameter(Parameter.Reader parameterReader, - Instrumentation instrumentation) { - super(PARAMETER_TAG, parameterReader); - mSigninUtil = new ChromeSigninUtils(instrumentation); - } - - @Override - public void setUp() { - String username = getStringArgument(ARGUMENT.USERNAME, ARGUMENT.DEFAULT.USERNAME); - String password = getStringArgument(ARGUMENT.PASSWORD, ARGUMENT.DEFAULT.PASSWORD); - - mSigninUtil.removeAllFakeAccountsFromOs(); - mSigninUtil.addFakeAccountToOs(username, password); - } - - @Override - public void tearDown() { - mSigninUtil.removeAllFakeAccountsFromOs(); - } - - public boolean isSignedIn() { - return isSignedIn(ARGUMENT.DEFAULT.USERNAME); - } - - public boolean isSignedIn(String username) { - return mSigninUtil.isExistingFakeAccountOnOs(username); - } -}
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/parameters/AddGoogleAccountToOsParameter.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/parameters/AddGoogleAccountToOsParameter.java deleted file mode 100644 index 34a3597..0000000 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/parameters/AddGoogleAccountToOsParameter.java +++ /dev/null
@@ -1,56 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.test.util.parameters; - -import android.app.Instrumentation; - -import org.chromium.base.test.util.parameter.BaseParameter; -import org.chromium.base.test.util.parameter.Parameter; -import org.chromium.chrome.test.util.ChromeSigninUtils; - -/** - * Adds a Google account to OS when this parameter is used. - */ -public class AddGoogleAccountToOsParameter extends BaseParameter { - /** Adds a Google account to OS to run test as signed into the OS. */ - public static final String PARAMETER_TAG = "add-google-account-to-os-parameter"; - - /** The {@Parameter.Argument#name()} value. */ - public static final class ARGUMENT { - public static final String USERNAME = "username"; - public static final String PASSWORD = "password"; - public static final String TYPE = "type"; - private static final class DEFAULT { - private static final String TYPE = "mail"; - } - } - - private ChromeSigninUtils mSigninUtil; - - public AddGoogleAccountToOsParameter(Parameter.Reader parameterReader, - Instrumentation instrumentation) { - super(PARAMETER_TAG, parameterReader); - mSigninUtil = new ChromeSigninUtils(instrumentation); - } - - @Override - public void setUp() { - String username = getStringArgument(ARGUMENT.USERNAME); - String password = getStringArgument(ARGUMENT.PASSWORD); - String type = getStringArgument(ARGUMENT.TYPE, ARGUMENT.DEFAULT.TYPE); - - mSigninUtil.removeAllGoogleAccountsFromOs(); - mSigninUtil.addGoogleAccountToOs(username, password, type); - } - - @Override - public void tearDown() { - mSigninUtil.removeAllGoogleAccountsFromOs(); - } - - public boolean isSignedIn(String username) { - return mSigninUtil.isExistingGoogleAccountOnOs(username); - } -}
diff --git a/chrome/test/chromedriver/chrome/adb_impl.cc b/chrome/test/chromedriver/chrome/adb_impl.cc index c592328..221c8a7 100644 --- a/chrome/test/chromedriver/chrome/adb_impl.cc +++ b/chrome/test/chromedriver/chrome/adb_impl.cc
@@ -72,6 +72,17 @@ base::Bind(&ResponseBuffer::OnResponse, response_buffer)); } +void SendFileOnIOThread(const std::string& device_serial, + const std::string& filename, + const std::string& content, + scoped_refptr<ResponseBuffer> response_buffer, + int port) { + CHECK(base::MessageLoopForIO::IsCurrent()); + AdbClientSocket::SendFile( + port, device_serial, filename, content, + base::Bind(&ResponseBuffer::OnResponse, response_buffer)); +} + } // namespace AdbImpl::AdbImpl( @@ -122,20 +133,16 @@ const std::string& exec_name, const std::string& args) { std::string response; - std::string quoted_command = - base::GetQuotedJSONString(exec_name + " " + args); - Status status = ExecuteHostShellCommand( - device_serial, - base::StringPrintf("echo %s > %s; echo $?", - quoted_command.c_str(), - command_line_file.c_str()), - &response); - if (!status.IsOk()) - return status; - if (response.find("0") == std::string::npos) - return Status(kUnknownError, "Failed to set command line file " + - command_line_file + " on device " + device_serial); - return Status(kOk); + std::string command(exec_name + " " + args + "\n"); + scoped_refptr<ResponseBuffer> response_buffer = new ResponseBuffer; + VLOG(1) << "Sending command line file: " << command_line_file; + io_task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&SendFileOnIOThread, device_serial, command_line_file, + command, response_buffer, port_)); + Status status = + response_buffer->GetResponse(&response, base::TimeDelta::FromSeconds(30)); + return status; } Status AdbImpl::CheckAppInstalled(
diff --git a/chrome/test/chromedriver/net/adb_client_socket.cc b/chrome/test/chromedriver/net/adb_client_socket.cc index 3d5ea5e6..448378f 100644 --- a/chrome/test/chromedriver/net/adb_client_socket.cc +++ b/chrome/test/chromedriver/net/adb_client_socket.cc
@@ -23,9 +23,14 @@ namespace { const int kBufferSize = 16 * 1024; +const size_t kAdbDataChunkSize = 32 * 1024; const char kOkayResponse[] = "OKAY"; const char kHostTransportCommand[] = "host:transport:%s"; const char kLocalAbstractCommand[] = "localabstract:%s"; +const char kSyncCommand[] = "sync:"; +const char kSendCommand[] = "SEND"; +const char kDataCommand[] = "DATA"; +const char kDoneCommand[] = "DONE"; typedef base::Callback<void(int, const std::string&)> CommandCallback; typedef base::Callback<void(int, net::StreamSocket*)> SocketCallback; @@ -301,6 +306,129 @@ CommandCallback callback_; }; +// Implement the ADB protocol to send a file to the device. +// The protocol consists of the following steps: +// * Send "host:transport" command with device serial +// * Send "sync:" command to initialize file transfer +// * Send "SEND" command with name and mode of the file +// * Send "DATA" command one or more times for the file content +// * Send "DONE" command to indicate end of file transfer +// The first two commands use normal ADB command format implemented by +// AdbClientSocket::SendCommand. The remaining commands use a special +// format implemented by AdbSendFileSocket::SendPayload. +class AdbSendFileSocket : AdbClientSocket { + public: + AdbSendFileSocket(int port, + const std::string& serial, + const std::string& filename, + const std::string& content, + const CommandCallback& callback) + : AdbClientSocket(port), + serial_(serial), + filename_(filename), + content_(content), + current_offset_(0), + callback_(callback) { + Connect( + base::Bind(&AdbSendFileSocket::SendTransport, base::Unretained(this))); + } + + private: + ~AdbSendFileSocket() {} + + void SendTransport(int result) { + if (!CheckNetResultOrDie(result)) + return; + SendCommand( + base::StringPrintf(kHostTransportCommand, serial_.c_str()), true, true, + base::Bind(&AdbSendFileSocket::SendSync, base::Unretained(this))); + } + + void SendSync(int result, const std::string& response) { + if (!CheckNetResultOrDie(result)) + return; + SendCommand( + kSyncCommand, true, true, + base::Bind(&AdbSendFileSocket::SendSend, base::Unretained(this))); + } + + void SendSend(int result, const std::string& response) { + if (!CheckNetResultOrDie(result)) + return; + // File mode. The following value is equivalent to S_IRUSR | S_IWUSR. + // Can't use the symbolic names since they are not available on Windows. + int mode = 0600; + std::string payload = base::StringPrintf("%s,%d", filename_.c_str(), mode); + SendPayload( + kSendCommand, payload.length(), payload.c_str(), payload.length(), + base::Bind(&AdbSendFileSocket::SendContent, base::Unretained(this))); + } + + void SendContent(int result) { + if (!CheckNetResultOrDie(result)) + return; + if (current_offset_ >= content_.length()) { + SendDone(); + return; + } + size_t offset = current_offset_; + size_t length = std::min(content_.length() - offset, kAdbDataChunkSize); + current_offset_ += length; + SendPayload( + kDataCommand, length, content_.c_str() + offset, length, + base::Bind(&AdbSendFileSocket::SendContent, base::Unretained(this))); + } + + void SendDone() { + int data = time(NULL); + SendPayload(kDoneCommand, data, nullptr, 0, + base::Bind(&AdbSendFileSocket::ReadFinalResponse, + base::Unretained(this))); + } + + void ReadFinalResponse(int result) { + ReadResponse(callback_, true, false, result); + } + + // Send a special payload command ("SEND", "DATA", or "DONE"). + // Each command consists of a command line, followed by a 4-byte integer + // sent in raw little-endian format, followed by an optional payload. + void SendPayload(const char* command, + int data, + const char* payload, + size_t payloadLength, + const net::CompletionCallback& callback) { + std::string buffer(command); + for (int i = 0; i < 4; i++) { + buffer.append(1, static_cast<char>(data & 0xff)); + data >>= 8; + } + if (payloadLength > 0) + buffer.append(payload, payloadLength); + + scoped_refptr<net::StringIOBuffer> request_buffer = + new net::StringIOBuffer(buffer); + int result = + socket_->Write(request_buffer.get(), request_buffer->size(), callback); + if (result != net::ERR_IO_PENDING) + callback.Run(result); + } + + bool CheckNetResultOrDie(int result) { + if (result >= 0) + return true; + callback_.Run(result, NULL); + delete this; + return false; + } + + std::string serial_; + std::string filename_; + std::string content_; + size_t current_offset_; + CommandCallback callback_; +}; + } // namespace // static @@ -310,6 +438,15 @@ new AdbQuerySocket(port, query, callback); } +// static +void AdbClientSocket::SendFile(int port, + const std::string& serial, + const std::string& filename, + const std::string& content, + const CommandCallback& callback) { + new AdbSendFileSocket(port, serial, filename, content, callback); +} + #if BUILDFLAG(DEBUG_DEVTOOLS) static void UseTransportQueryForDesktop(const SocketCallback& callback, net::StreamSocket* socket,
diff --git a/chrome/test/chromedriver/net/adb_client_socket.h b/chrome/test/chromedriver/net/adb_client_socket.h index 183f0f8e..2430d98 100644 --- a/chrome/test/chromedriver/net/adb_client_socket.h +++ b/chrome/test/chromedriver/net/adb_client_socket.h
@@ -37,6 +37,12 @@ const std::string& request, const SocketCallback& callback); + static void SendFile(int port, + const std::string& serial, + const std::string& filename, + const std::string& content, + const CommandCallback& callback); + explicit AdbClientSocket(int port); ~AdbClientSocket(); @@ -50,12 +56,12 @@ std::unique_ptr<net::StreamSocket> socket_; - private: void ReadResponse(const CommandCallback& callback, bool is_void, bool has_length, int result); + private: void OnResponseStatus(const CommandCallback& callback, bool is_void, bool has_length,
diff --git a/chromeos/components/tether/fake_notification_presenter.cc b/chromeos/components/tether/fake_notification_presenter.cc index 5106769..e08b1e42 100644 --- a/chromeos/components/tether/fake_notification_presenter.cc +++ b/chromeos/components/tether/fake_notification_presenter.cc
@@ -29,7 +29,8 @@ } void FakeNotificationPresenter::NotifyPotentialHotspotNearby( - const cryptauth::RemoteDevice& remote_device) { + const cryptauth::RemoteDevice& remote_device, + int signal_strength) { potential_hotspot_state_ = PotentialHotspotNotificationState::SINGLE_HOTSPOT_NEARBY_SHOWN; potential_hotspot_remote_device_ = remote_device;
diff --git a/chromeos/components/tether/fake_notification_presenter.h b/chromeos/components/tether/fake_notification_presenter.h index cf985f91..68e34db 100644 --- a/chromeos/components/tether/fake_notification_presenter.h +++ b/chromeos/components/tether/fake_notification_presenter.h
@@ -44,7 +44,8 @@ // NotificationPresenter: void NotifyPotentialHotspotNearby( - const cryptauth::RemoteDevice& remote_device) override; + const cryptauth::RemoteDevice& remote_device, + int signal_strength) override; void NotifyMultiplePotentialHotspotsNearby() override; void RemovePotentialHotspotNotification() override; void NotifySetupRequired(const std::string& device_name) override;
diff --git a/chromeos/components/tether/host_scanner.cc b/chromeos/components/tether/host_scanner.cc index 13af4f28..60cc1228b 100644 --- a/chromeos/components/tether/host_scanner.cc +++ b/chromeos/components/tether/host_scanner.cc
@@ -93,8 +93,14 @@ } if (scanned_device_list_so_far.size() == 1) { - notification_presenter_->NotifyPotentialHotspotNearby( - scanned_device_list_so_far.at(0).remote_device); + const cryptauth::RemoteDevice& remote_device = + scanned_device_list_so_far.at(0).remote_device; + int32_t signal_strength; + NormalizeDeviceStatus(scanned_device_list_so_far.at(0).device_status, + nullptr /* carrier */, + nullptr /* battery_percentage */, &signal_strength); + notification_presenter_->NotifyPotentialHotspotNearby(remote_device, + signal_strength); } else { notification_presenter_->NotifyMultiplePotentialHotspotsNearby(); }
diff --git a/chromeos/components/tether/notification_presenter.h b/chromeos/components/tether/notification_presenter.h index f59bd24..53045b8 100644 --- a/chromeos/components/tether/notification_presenter.h +++ b/chromeos/components/tether/notification_presenter.h
@@ -7,6 +7,7 @@ #include "base/macros.h" #include "base/observer_list.h" +#include "chromeos/network/network_state.h" #include "components/cryptauth/remote_device.h" namespace chromeos { @@ -19,9 +20,10 @@ virtual ~NotificationPresenter() {} // Notifies the user that a nearby device can potentially provide a tether - // hotspot. + // hotspot, and shows the signal strength with a blue icon. virtual void NotifyPotentialHotspotNearby( - const cryptauth::RemoteDevice& remote_device) = 0; + const cryptauth::RemoteDevice& remote_device, + int signal_strength) = 0; // Notifies the user that multiple nearby devices can potentially provide // tether hotspots.
diff --git a/components/autofill/core/browser/autofill_client.h b/components/autofill/core/browser/autofill_client.h index 9084f772..149b668 100644 --- a/components/autofill/core/browser/autofill_client.h +++ b/components/autofill/core/browser/autofill_client.h
@@ -199,6 +199,10 @@ // Shows the explanation of http not secure warning message. virtual void ShowHttpNotSecureExplanation() = 0; + + // Whether Autofill is currently supported by the client. If false, all + // features of Autofill are disabled, including Autocomplete. + virtual bool IsAutofillSupported() = 0; }; } // namespace autofill
diff --git a/components/autofill/core/browser/autofill_manager.cc b/components/autofill/core/browser/autofill_manager.cc index a63c720..3784b4da 100644 --- a/components/autofill/core/browser/autofill_manager.cc +++ b/components/autofill/core/browser/autofill_manager.cc
@@ -1165,7 +1165,8 @@ } bool AutofillManager::IsAutofillEnabled() const { - return ::autofill::IsAutofillEnabled(client_->GetPrefs()); + return ::autofill::IsAutofillEnabled(client_->GetPrefs()) && + client_->IsAutofillSupported(); } bool AutofillManager::IsCreditCardUploadEnabled() {
diff --git a/components/autofill/core/browser/autofill_manager.h b/components/autofill/core/browser/autofill_manager.h index 5efc4bc..f24f885 100644 --- a/components/autofill/core/browser/autofill_manager.h +++ b/components/autofill/core/browser/autofill_manager.h
@@ -190,7 +190,8 @@ const std::vector<base::string16>& labels) override; void Reset() override; - // Returns the value of the AutofillEnabled pref. + // Returns true if the value of the AutofillEnabled pref is true and the + // client supports Autofill. virtual bool IsAutofillEnabled() const; // Returns true if all the conditions for enabling the upload of credit card
diff --git a/components/autofill/core/browser/test_autofill_client.cc b/components/autofill/core/browser/test_autofill_client.cc index 61d05df..8dde20e85 100644 --- a/components/autofill/core/browser/test_autofill_client.cc +++ b/components/autofill/core/browser/test_autofill_client.cc
@@ -145,4 +145,8 @@ void TestAutofillClient::ShowHttpNotSecureExplanation() {} +bool TestAutofillClient::IsAutofillSupported() { + return true; +} + } // namespace autofill
diff --git a/components/autofill/core/browser/test_autofill_client.h b/components/autofill/core/browser/test_autofill_client.h index 965023d..a0bd9cb 100644 --- a/components/autofill/core/browser/test_autofill_client.h +++ b/components/autofill/core/browser/test_autofill_client.h
@@ -77,6 +77,7 @@ bool ShouldShowSigninPromo() override; void StartSigninFlow() override; void ShowHttpNotSecureExplanation() override; + bool IsAutofillSupported() override; void SetPrefs(std::unique_ptr<PrefService> prefs) { prefs_ = std::move(prefs);
diff --git a/components/certificate_reporting/cert_logger.proto b/components/certificate_reporting/cert_logger.proto index e28b3b9..8a3538f 100644 --- a/components/certificate_reporting/cert_logger.proto +++ b/components/certificate_reporting/cert_logger.proto
@@ -160,4 +160,8 @@ // The Chrome channel that this error occurred on. optional ChromeChannel chrome_channel = 12; + + // True if the machine is enterprise managed. Currently only available for + // Windows and ChromeOS clients. + optional bool is_enterprise_managed = 13; };
diff --git a/components/certificate_reporting/error_report.cc b/components/certificate_reporting/error_report.cc index e988ffc..a0e3a57 100644 --- a/components/certificate_reporting/error_report.cc +++ b/components/certificate_reporting/error_report.cc
@@ -200,6 +200,10 @@ } } +void ErrorReport::SetIsEnterpriseManaged(bool is_enterprise_managed) { + cert_report_->set_is_enterprise_managed(is_enterprise_managed); +} + void ErrorReport::SetIsRetryUpload(bool is_retry_upload) { cert_report_->set_is_retry_upload(is_retry_upload); } @@ -212,6 +216,10 @@ return cert_report_->chrome_channel(); } +bool ErrorReport::is_enterprise_managed() const { + return cert_report_->is_enterprise_managed(); +} + bool ErrorReport::is_retry_upload() const { return cert_report_->is_retry_upload(); }
diff --git a/components/certificate_reporting/error_report.h b/components/certificate_reporting/error_report.h index 801e75e..6c30f60 100644 --- a/components/certificate_reporting/error_report.h +++ b/components/certificate_reporting/error_report.h
@@ -78,6 +78,8 @@ void AddChromeChannel(version_info::Channel channel); + void SetIsEnterpriseManaged(bool is_enterprise_managed); + // Sets is_retry_upload field of the protobuf to |is_retry_upload|. void SetIsRetryUpload(bool is_retry_upload); @@ -87,6 +89,9 @@ // Gets the Chrome channel attached to this report. CertLoggerRequest::ChromeChannel chrome_channel() const; + // Returns true if the device that issued the report is a managed device. + bool is_enterprise_managed() const; + // Returns true if the report has been retried. bool is_retry_upload() const;
diff --git a/components/certificate_reporting/error_report_unittest.cc b/components/certificate_reporting/error_report_unittest.cc index 5818625..ab51025 100644 --- a/components/certificate_reporting/error_report_unittest.cc +++ b/components/certificate_reporting/error_report_unittest.cc
@@ -15,6 +15,7 @@ #include "base/threading/thread.h" #include "base/time/default_clock.h" #include "base/time/default_tick_clock.h" +#include "build/build_config.h" #include "components/certificate_reporting/cert_logger.pb.h" #include "components/network_time/network_time_test_utils.h" #include "components/prefs/testing_pref_service.h" @@ -279,6 +280,28 @@ } } +#if defined(OS_WIN) || defined(OS_CHROMEOS) +// Tests that the SetIsEnterpriseManaged() function populates +// is_enterprise_managed correctly on Windows, and that value is correctly +// extracted from the parsed report. +// These tests are OS specific because SetIsEnterpriseManaged is called only +// on the Windows and ChromeOS OS. +TEST(ErrorReportTest, TestIsEnterpriseManagedPopulatedOnWindows) { + SSLInfo ssl_info; + ASSERT_NO_FATAL_FAILURE( + GetTestSSLInfo(INCLUDE_UNVERIFIED_CERT_CHAIN, &ssl_info, kCertStatus)); + ErrorReport report(kDummyHostname, ssl_info); + + report.SetIsEnterpriseManaged(true); + std::string serialized_report; + ASSERT_TRUE(report.Serialize(&serialized_report)); + + CertLoggerRequest parsed; + ASSERT_TRUE(parsed.ParseFromString(serialized_report)); + EXPECT_EQ(true, parsed.is_enterprise_managed()); +} +#endif + #if defined(OS_ANDROID) // Tests that information about the Android AIA fetching feature is included in // the report.
diff --git a/components/chrome_cleaner/public/constants/constants.cc b/components/chrome_cleaner/public/constants/constants.cc index 2457c6f..3837e21f 100644 --- a/components/chrome_cleaner/public/constants/constants.cc +++ b/components/chrome_cleaner/public/constants/constants.cc
@@ -13,7 +13,6 @@ const char kChromePromptSwitch[] = "chrome-prompt"; const char kChromeSystemInstallSwitch[] = "chrome-system-install"; const char kChromeVersionSwitch[] = "chrome-version"; -const char kEnableCleanerLoggingSwitch[] = "enable-cleaner-logging"; const char kEnableCrashReportingSwitch[] = "enable-crash-reporting"; const char kEngineExperimentGroupSwitch[] = "engine-experiment-group"; const char kEngineSwitch[] = "engine";
diff --git a/components/chrome_cleaner/public/constants/constants.h b/components/chrome_cleaner/public/constants/constants.h index 4b4ed44..d28e875 100644 --- a/components/chrome_cleaner/public/constants/constants.h +++ b/components/chrome_cleaner/public/constants/constants.h
@@ -33,10 +33,6 @@ // The Chrome version string. extern const char kChromeVersionSwitch[]; -// Indicates whether logs upload is enabled in the cleaner process. -// Takes effect only if execution mode is ExecutionMode::kCleanup. -extern const char kEnableCleanerLoggingSwitch[]; - // Indicates that crash reporting is enabled for the current user. extern const char kEnableCrashReportingSwitch[]; @@ -116,9 +112,12 @@ // The cleaner will run in scanning mode. No UI will be shown to the user // (UI handled by Chrome) and logs will not be uploaded. kScanning = 1, - // The cleaner will run in cleanup mode only. No UI will be shown to the - // user (UI handled by Chrome) and logs should only be uploaded if - // |kEnableCleanerLoggingSwitch| is set. + // The cleaner will run in cleaning mode. No UI will be shown to the user + // (UI handled by Chrome) and logs will be uploaded if the user did not opt + // out of logs collection when it was offered by the Chrome UI. + // Chrome should not try to launch the Chrome Cleanup Tool with |kCleanup|. + // It should instead communicate through IPC with the cleaner launched with + // |kScanning| to ask it to start cleanup. kCleanup = 2, // Auxiliary enumerator for range checking.
diff --git a/components/exo/BUILD.gn b/components/exo/BUILD.gn index a496d19d..8a712ba 100644 --- a/components/exo/BUILD.gn +++ b/components/exo/BUILD.gn
@@ -183,6 +183,8 @@ "//ash/test:test_support_without_content", "//base", "//base/test:test_support", + "//cc:test_support", + "//components/viz/test:test_support", "//device/gamepad:test_helpers", "//mojo/edk/embedder:headers", "//testing/gtest",
diff --git a/components/exo/buffer.cc b/components/exo/buffer.cc index f9cd7b56..dd901d8 100644 --- a/components/exo/buffer.cc +++ b/components/exo/buffer.cc
@@ -411,7 +411,6 @@ bool Buffer::ProduceTransferableResource( LayerTreeFrameSinkHolder* layer_tree_frame_sink_holder, - cc::ResourceId resource_id, bool secure_output_only, bool client_usage, cc::TransferableResource* resource) { @@ -439,7 +438,7 @@ return false; } - resource->id = resource_id; + resource->id = layer_tree_frame_sink_holder->AllocateResourceId(); resource->format = viz::RGBA_8888; resource->filter = GL_LINEAR; resource->size = gpu_memory_buffer_->GetSize(); @@ -473,7 +472,7 @@ // The contents texture will be released when no longer used by the // compositor. layer_tree_frame_sink_holder->SetResourceReleaseCallback( - resource_id, + resource->id, base::Bind(&Buffer::Texture::ReleaseTexImage, base::Unretained(contents_texture), base::Bind(&Buffer::ReleaseContentsTexture, AsWeakPtr(), @@ -503,7 +502,7 @@ // The mailbox texture will be released when no longer used by the // compositor. layer_tree_frame_sink_holder->SetResourceReleaseCallback( - resource_id, + resource->id, base::Bind(&Buffer::Texture::Release, base::Unretained(texture), base::Bind(&Buffer::ReleaseTexture, AsWeakPtr(), base::Passed(&texture_))));
diff --git a/components/exo/buffer.h b/components/exo/buffer.h index 890edf4..f347582 100644 --- a/components/exo/buffer.h +++ b/components/exo/buffer.h
@@ -54,7 +54,6 @@ // |non_client_usage| is true. bool ProduceTransferableResource( LayerTreeFrameSinkHolder* layer_tree_frame_sink_holder, - cc::ResourceId resource_id, bool secure_output_only, bool client_usage, cc::TransferableResource* resource);
diff --git a/components/exo/buffer_unittest.cc b/components/exo/buffer_unittest.cc index 32c78ea..d5ce3d2 100644 --- a/components/exo/buffer_unittest.cc +++ b/components/exo/buffer_unittest.cc
@@ -8,7 +8,7 @@ #include "cc/output/context_provider.h" #include "cc/resources/single_release_callback.h" #include "components/exo/buffer.h" -#include "components/exo/surface.h" +#include "components/exo/surface_tree_host.h" #include "components/exo/test/exo_test_base.h" #include "components/exo/test/exo_test_helper.h" #include "gpu/command_buffer/client/gles2_interface.h" @@ -29,12 +29,12 @@ TEST_F(BufferTest, ReleaseCallback) { gfx::Size buffer_size(256, 256); - std::unique_ptr<Buffer> buffer( - new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size))); - std::unique_ptr<Surface> surface(new Surface); - const viz::FrameSinkId arbitrary_frame_sink_id(1, 1); - LayerTreeFrameSinkHolder* layer_tree_frame_sink_holder = - surface->layer_tree_frame_sink_holder(); + auto buffer = base::MakeUnique<Buffer>( + exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)); + auto surface_tree_host = + base::MakeUnique<SurfaceTreeHost>("BufferTest", nullptr); + LayerTreeFrameSinkHolder* frame_sink_holder = + surface_tree_host->layer_tree_frame_sink_holder(); // Set the release callback. int release_call_count = 0; @@ -44,8 +44,8 @@ buffer->OnAttach(); cc::TransferableResource resource; // Produce a transferable resource for the contents of the buffer. - bool rv = buffer->ProduceTransferableResource(layer_tree_frame_sink_holder, 0, - false, true, &resource); + bool rv = buffer->ProduceTransferableResource(frame_sink_holder, false, true, + &resource); ASSERT_TRUE(rv); // Release buffer. @@ -54,7 +54,7 @@ returned_resource.sync_token = resource.mailbox_holder.sync_token; returned_resource.lost = false; std::vector<cc::ReturnedResource> resources = {returned_resource}; - layer_tree_frame_sink_holder->ReclaimResources(resources); + frame_sink_holder->ReclaimResources(resources); RunAllPendingInMessageLoop(); ASSERT_EQ(release_call_count, 0); @@ -67,19 +67,18 @@ TEST_F(BufferTest, IsLost) { gfx::Size buffer_size(256, 256); - std::unique_ptr<Buffer> buffer( - new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size))); - const viz::FrameSinkId arbitrary_frame_sink_id(1, 1); - std::unique_ptr<Surface> surface(new Surface); - LayerTreeFrameSinkHolder* layer_tree_frame_sink_holder = - surface->layer_tree_frame_sink_holder(); - cc::ResourceId resource_id = 0; + auto buffer = base::MakeUnique<Buffer>( + exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)); + auto surface_tree_host = + base::MakeUnique<SurfaceTreeHost>("BufferTest", nullptr); + LayerTreeFrameSinkHolder* frame_sink_holder = + surface_tree_host->layer_tree_frame_sink_holder(); buffer->OnAttach(); // Acquire a texture transferable resource for the contents of the buffer. cc::TransferableResource resource; - bool rv = buffer->ProduceTransferableResource( - layer_tree_frame_sink_holder, resource_id, false, true, &resource); + bool rv = buffer->ProduceTransferableResource(frame_sink_holder, false, true, + &resource); ASSERT_TRUE(rv); scoped_refptr<cc::ContextProvider> context_provider = @@ -95,28 +94,27 @@ // Release buffer. bool is_lost = true; cc::ReturnedResource returned_resource; - returned_resource.id = resource_id; + returned_resource.id = resource.id; returned_resource.sync_token = gpu::SyncToken(); returned_resource.lost = is_lost; std::vector<cc::ReturnedResource> resources = {returned_resource}; - layer_tree_frame_sink_holder->ReclaimResources(resources); + frame_sink_holder->ReclaimResources(resources); RunAllPendingInMessageLoop(); // Producing a new texture transferable resource for the contents of the // buffer. - ++resource_id; cc::TransferableResource new_resource; - rv = buffer->ProduceTransferableResource( - layer_tree_frame_sink_holder, resource_id, false, false, &new_resource); + rv = buffer->ProduceTransferableResource(frame_sink_holder, false, false, + &new_resource); ASSERT_TRUE(rv); buffer->OnDetach(); cc::ReturnedResource returned_resource2; - returned_resource2.id = resource_id; + returned_resource2.id = new_resource.id; returned_resource2.sync_token = gpu::SyncToken(); returned_resource2.lost = false; std::vector<cc::ReturnedResource> resources2 = {returned_resource2}; - layer_tree_frame_sink_holder->ReclaimResources(resources2); + frame_sink_holder->ReclaimResources(resources2); RunAllPendingInMessageLoop(); }
diff --git a/components/exo/layer_tree_frame_sink_holder.cc b/components/exo/layer_tree_frame_sink_holder.cc index a750192d..fa4b2cf 100644 --- a/components/exo/layer_tree_frame_sink_holder.cc +++ b/components/exo/layer_tree_frame_sink_holder.cc
@@ -6,7 +6,7 @@ #include "cc/output/layer_tree_frame_sink.h" #include "cc/resources/returned_resource.h" -#include "components/exo/surface.h" +#include "components/exo/surface_tree_host.h" namespace exo { @@ -14,19 +14,16 @@ // LayerTreeFrameSinkHolder, public: LayerTreeFrameSinkHolder::LayerTreeFrameSinkHolder( - Surface* surface, + SurfaceTreeHost* surface_tree_host, std::unique_ptr<cc::LayerTreeFrameSink> frame_sink) - : surface_(surface), + : surface_tree_host_(surface_tree_host), frame_sink_(std::move(frame_sink)), weak_factory_(this) { - surface_->AddSurfaceObserver(this); frame_sink_->BindToClient(this); } LayerTreeFrameSinkHolder::~LayerTreeFrameSinkHolder() { frame_sink_->DetachFromClient(); - if (surface_) - surface_->RemoveSurfaceObserver(this); // Release all resources which aren't returned from LayerTreeFrameSink. for (auto& callback : release_callbacks_) @@ -58,8 +55,7 @@ void LayerTreeFrameSinkHolder::SetBeginFrameSource( cc::BeginFrameSource* source) { - if (surface_) - surface_->SetBeginFrameSource(source); + surface_tree_host_->SetBeginFrameSource(source); } void LayerTreeFrameSinkHolder::ReclaimResources( @@ -75,16 +71,7 @@ } void LayerTreeFrameSinkHolder::DidReceiveCompositorFrameAck() { - if (surface_) - surface_->DidReceiveCompositorFrameAck(); -} - -//////////////////////////////////////////////////////////////////////////////// -// SurfaceObserver overrides: - -void LayerTreeFrameSinkHolder::OnSurfaceDestroying(Surface* surface) { - surface_->RemoveSurfaceObserver(this); - surface_ = nullptr; + surface_tree_host_->DidReceiveCompositorFrameAck(); } } // namespace exo
diff --git a/components/exo/layer_tree_frame_sink_holder.h b/components/exo/layer_tree_frame_sink_holder.h index 12b0c45..2fb9b9a 100644 --- a/components/exo/layer_tree_frame_sink_holder.h +++ b/components/exo/layer_tree_frame_sink_holder.h
@@ -10,23 +10,19 @@ #include "base/containers/flat_map.h" #include "cc/output/layer_tree_frame_sink_client.h" #include "cc/resources/release_callback.h" -#include "components/exo/surface_observer.h" namespace cc { class LayerTreeFrameSink; } namespace exo { -class Surface; +class SurfaceTreeHost; // This class talks to CompositorFrameSink and keeps track of references to -// the contents of Buffers. It's keeped alive by references from -// release_callbacks_. It's destroyed when its owning Surface is destroyed and -// the last outstanding release callback is called. -class LayerTreeFrameSinkHolder : public cc::LayerTreeFrameSinkClient, - public SurfaceObserver { +// the contents of Buffers. +class LayerTreeFrameSinkHolder : public cc::LayerTreeFrameSinkClient { public: - LayerTreeFrameSinkHolder(Surface* surface, + LayerTreeFrameSinkHolder(SurfaceTreeHost* surface_tree_host, std::unique_ptr<cc::LayerTreeFrameSink> frame_sink); ~LayerTreeFrameSinkHolder() override; @@ -53,15 +49,12 @@ const gfx::Rect& viewport_rect, const gfx::Transform& transform) override {} - // Overridden from SurfaceObserver: - void OnSurfaceDestroying(Surface* surface) override; - private: // A collection of callbacks used to release resources. using ResourceReleaseCallbackMap = base::flat_map<int, cc::ReleaseCallback>; ResourceReleaseCallbackMap release_callbacks_; - Surface* surface_; + SurfaceTreeHost* surface_tree_host_; std::unique_ptr<cc::LayerTreeFrameSink> frame_sink_; // The next resource id the buffer is attached to.
diff --git a/components/exo/shell_surface.cc b/components/exo/shell_surface.cc index 3b32f0b..c44cf39 100644 --- a/components/exo/shell_surface.cc +++ b/components/exo/shell_surface.cc
@@ -956,6 +956,9 @@ void ShellSurface::OnWindowBoundsChanged(aura::Window* window, const gfx::Rect& old_bounds, const gfx::Rect& new_bounds) { + if (window == host_window()) + return; + // TODO(domlaskowski): For BoundsMode::CLIENT, the configure callback does not // yet support resizing. See crbug.com/699746. if (bounds_mode_ == BoundsMode::CLIENT) @@ -987,7 +990,23 @@ } } +void ShellSurface::OnWindowAddedToRootWindow(aura::Window* window) { + if (window == host_window()) + SurfaceTreeHost::OnWindowAddedToRootWindow(window); +} + +void ShellSurface::OnWindowRemovingFromRootWindow(aura::Window* window, + aura::Window* new_root) { + if (window == host_window()) + SurfaceTreeHost::OnWindowRemovingFromRootWindow(window, new_root); +} + void ShellSurface::OnWindowDestroying(aura::Window* window) { + if (window == host_window()) { + SurfaceTreeHost::OnWindowDestroying(window); + return; + } + if (window == parent_) { parent_ = nullptr; // |parent_| being set to null effects the ability to maximize the window.
diff --git a/components/exo/shell_surface.h b/components/exo/shell_surface.h index ab05c116..fc96631d 100644 --- a/components/exo/shell_surface.h +++ b/components/exo/shell_surface.h
@@ -16,7 +16,6 @@ #include "components/exo/surface_observer.h" #include "components/exo/surface_tree_host.h" #include "components/exo/wm_helper.h" -#include "ui/aura/window_observer.h" #include "ui/base/hit_test.h" #include "ui/gfx/geometry/point.h" #include "ui/gfx/geometry/rect.h" @@ -47,7 +46,6 @@ public views::WidgetDelegate, public views::View, public ash::wm::WindowStateObserver, - public aura::WindowObserver, public WMHelper::ActivationObserver, public WMHelper::DisplayConfigurationObserver { public: @@ -258,6 +256,9 @@ void OnWindowBoundsChanged(aura::Window* window, const gfx::Rect& old_bounds, const gfx::Rect& new_bounds) override; + void OnWindowAddedToRootWindow(aura::Window* window) override; + void OnWindowRemovingFromRootWindow(aura::Window* window, + aura::Window* new_root) override; void OnWindowDestroying(aura::Window* window) override; // Overridden from WMHelper::ActivationObserver:
diff --git a/components/exo/sub_surface.cc b/components/exo/sub_surface.cc index 1f8e2f30..f170dae 100644 --- a/components/exo/sub_surface.cc +++ b/components/exo/sub_surface.cc
@@ -96,7 +96,8 @@ if (IsSurfaceSynchronized()) return; - surface_->CommitSurfaceHierarchy(); + // TODO(penghuang): http://crbug.com/740110 Support async mode. + NOTIMPLEMENTED() << "Async subsurface is not supported!"; } bool SubSurface::IsSurfaceSynchronized() const {
diff --git a/components/exo/sub_surface_unittest.cc b/components/exo/sub_surface_unittest.cc index 1132dec..c569753 100644 --- a/components/exo/sub_surface_unittest.cc +++ b/components/exo/sub_surface_unittest.cc
@@ -5,6 +5,7 @@ #include "components/exo/sub_surface.h" #include "base/memory/ptr_util.h" +#include "components/exo/shell_surface.h" #include "components/exo/surface.h" #include "components/exo/test/exo_test_base.h" #include "components/exo/test/exo_test_helper.h" @@ -16,10 +17,10 @@ using SubSurfaceTest = test::ExoTestBase; TEST_F(SubSurfaceTest, SetPosition) { - std::unique_ptr<Surface> parent(new Surface); - std::unique_ptr<Surface> surface(new Surface); - std::unique_ptr<SubSurface> sub_surface( - new SubSurface(surface.get(), parent.get())); + auto parent = base::MakeUnique<Surface>(); + auto shell_surface = base::MakeUnique<ShellSurface>(parent.get()); + auto surface = base::MakeUnique<Surface>(); + auto sub_surface = base::MakeUnique<SubSurface>(surface.get(), parent.get()); // Initial position is at the origin. EXPECT_EQ(gfx::Point().ToString(), @@ -49,14 +50,15 @@ } TEST_F(SubSurfaceTest, PlaceAbove) { - std::unique_ptr<Surface> parent(new Surface); - std::unique_ptr<Surface> surface1(new Surface); - std::unique_ptr<Surface> surface2(new Surface); - std::unique_ptr<Surface> non_sibling_surface(new Surface); - std::unique_ptr<SubSurface> sub_surface1( - new SubSurface(surface1.get(), parent.get())); - std::unique_ptr<SubSurface> sub_surface2( - new SubSurface(surface2.get(), parent.get())); + auto parent = base::MakeUnique<Surface>(); + auto shell_surface = base::MakeUnique<ShellSurface>(parent.get()); + auto surface1 = base::MakeUnique<Surface>(); + auto surface2 = base::MakeUnique<Surface>(); + auto non_sibling_surface = base::MakeUnique<Surface>(); + auto sub_surface1 = + base::MakeUnique<SubSurface>(surface1.get(), parent.get()); + auto sub_surface2 = + base::MakeUnique<SubSurface>(surface2.get(), parent.get()); ASSERT_EQ(2u, parent->window()->children().size()); EXPECT_EQ(surface1->window(), parent->window()->children()[0]); @@ -80,14 +82,15 @@ } TEST_F(SubSurfaceTest, PlaceBelow) { - std::unique_ptr<Surface> parent(new Surface); - std::unique_ptr<Surface> surface1(new Surface); - std::unique_ptr<Surface> surface2(new Surface); - std::unique_ptr<Surface> non_sibling_surface(new Surface); - std::unique_ptr<SubSurface> sub_surface1( - new SubSurface(surface1.get(), parent.get())); - std::unique_ptr<SubSurface> sub_surface2( - new SubSurface(surface2.get(), parent.get())); + auto parent = base::MakeUnique<Surface>(); + auto shell_surface = base::MakeUnique<ShellSurface>(parent.get()); + auto surface1 = base::MakeUnique<Surface>(); + auto surface2 = base::MakeUnique<Surface>(); + auto non_sibling_surface = base::MakeUnique<Surface>(); + auto sub_surface1 = + base::MakeUnique<SubSurface>(surface1.get(), parent.get()); + auto sub_surface2 = + base::MakeUnique<SubSurface>(surface2.get(), parent.get()); ASSERT_EQ(2u, parent->window()->children().size()); EXPECT_EQ(surface1->window(), parent->window()->children()[0]); @@ -111,13 +114,14 @@ } TEST_F(SubSurfaceTest, SetCommitBehavior) { - std::unique_ptr<Surface> parent(new Surface); - std::unique_ptr<Surface> child(new Surface); - std::unique_ptr<Surface> grandchild(new Surface); - std::unique_ptr<SubSurface> child_sub_surface( - new SubSurface(child.get(), parent.get())); - std::unique_ptr<SubSurface> grandchild_sub_surface( - new SubSurface(grandchild.get(), child.get())); + auto parent = base::MakeUnique<Surface>(); + auto shell_surface = base::MakeUnique<ShellSurface>(parent.get()); + auto child = base::MakeUnique<Surface>(); + auto grandchild = base::MakeUnique<Surface>(); + auto child_sub_surface = + base::MakeUnique<SubSurface>(child.get(), parent.get()); + auto grandchild_sub_surface = + base::MakeUnique<SubSurface>(grandchild.get(), child.get()); // Initial position is at the origin. EXPECT_EQ(gfx::Point().ToString(), @@ -141,19 +145,20 @@ EXPECT_EQ(position1.ToString(), grandchild->window()->bounds().origin().ToString()); + // TODO(penghuang): http://crbug.com/740110 Support async mode. // Disable synchronous commit behavior. - bool synchronized = false; - child_sub_surface->SetCommitBehavior(synchronized); + // bool synchronized = false; + // child_sub_surface->SetCommitBehavior(synchronized); // Set position to 20, 20. - gfx::Point position2(20, 20); - grandchild_sub_surface->SetPosition(position2); - child->Commit(); + // gfx::Point position2(20, 20); + // grandchild_sub_surface->SetPosition(position2); + // child->Commit(); // A Commit() call on child should be sufficient for the position of // grandchild to take effect when synchronous is disabled. - EXPECT_EQ(position2.ToString(), - grandchild->window()->bounds().origin().ToString()); + // EXPECT_EQ(position2.ToString(), + // grandchild->window()->bounds().origin().ToString()); } } // namespace
diff --git a/components/exo/surface.cc b/components/exo/surface.cc index 40a23ab..9e711ab1 100644 --- a/components/exo/surface.cc +++ b/components/exo/surface.cc
@@ -7,6 +7,7 @@ #include <utility> #include "base/callback_helpers.h" +#include "base/containers/adapters.h" #include "base/logging.h" #include "base/macros.h" #include "base/memory/ptr_util.h" @@ -27,7 +28,6 @@ #include "components/viz/common/surfaces/sequence_surface_reference_factory.h" #include "third_party/khronos/GLES2/gl2.h" #include "ui/aura/client/aura_constants.h" -#include "ui/aura/env.h" #include "ui/aura/window_delegate.h" #include "ui/aura/window_targeter.h" #include "ui/base/class_property.h" @@ -189,42 +189,23 @@ window_->SetType(aura::client::WINDOW_TYPE_CONTROL); window_->SetName("ExoSurface"); window_->SetProperty(kSurfaceKey, this); - window_->Init(ui::LAYER_SOLID_COLOR); + window_->Init(ui::LAYER_NOT_DRAWN); window_->SetEventTargeter(base::WrapUnique(new CustomWindowTargeter)); window_->set_owned_by_parent(false); - window_->AddObserver(this); - aura::Env::GetInstance()->context_factory()->AddObserver(this); - layer_tree_frame_sink_holder_ = base::MakeUnique<LayerTreeFrameSinkHolder>( - this, window_->CreateLayerTreeFrameSink()); } Surface::~Surface() { - aura::Env::GetInstance()->context_factory()->RemoveObserver(this); for (SurfaceObserver& observer : observers_) observer.OnSurfaceDestroying(this); - window_->RemoveObserver(this); - if (window_->layer()->GetCompositor()) - window_->layer()->GetCompositor()->vsync_manager()->RemoveObserver(this); - window_->layer()->SetShowSolidColorContent(); - - frame_callbacks_.splice(frame_callbacks_.end(), pending_frame_callbacks_); - active_frame_callbacks_.splice(active_frame_callbacks_.end(), - frame_callbacks_); // Call all frame callbacks with a null frame time to indicate that they // have been cancelled. - for (const auto& frame_callback : active_frame_callbacks_) + for (const auto& frame_callback : pending_frame_callbacks_) frame_callback.Run(base::TimeTicks()); - presentation_callbacks_.splice(presentation_callbacks_.end(), - pending_presentation_callbacks_); - swapping_presentation_callbacks_.splice( - swapping_presentation_callbacks_.end(), presentation_callbacks_); - swapped_presentation_callbacks_.splice(swapped_presentation_callbacks_.end(), - swapping_presentation_callbacks_); // Call all presentation callbacks with a null presentation time to indicate // that they have been cancelled. - for (const auto& presentation_callback : swapped_presentation_callbacks_) + for (const auto& presentation_callback : pending_presentation_callbacks_) presentation_callback.Run(base::TimeTicks(), base::TimeDelta()); } @@ -233,10 +214,6 @@ return window->GetProperty(kSurfaceKey); } -viz::SurfaceId Surface::GetSurfaceId() const { - return window_->GetSurfaceId(); -} - void Surface::Attach(Buffer* buffer) { TRACE_EVENT1("exo", "Surface::Attach", "buffer", buffer ? buffer->GetSize().ToString() : "null"); @@ -290,11 +267,13 @@ DCHECK(!sub_surface->window()->parent()); DCHECK(!sub_surface->window()->IsVisible()); + sub_surface->window()->SetBounds( + gfx::Rect(sub_surface->window()->bounds().size())); window_->AddChild(sub_surface->window()); DCHECK(!ListContainsEntry(pending_sub_surfaces_, sub_surface)); pending_sub_surfaces_.push_back(std::make_pair(sub_surface, gfx::Point())); - has_pending_layer_changes_ = true; + sub_surfaces_.push_back(std::make_pair(sub_surface, gfx::Point())); } void Surface::RemoveSubSurface(Surface* sub_surface) { @@ -308,7 +287,8 @@ DCHECK(ListContainsEntry(pending_sub_surfaces_, sub_surface)); pending_sub_surfaces_.erase( FindListEntry(pending_sub_surfaces_, sub_surface)); - has_pending_layer_changes_ = true; + DCHECK(ListContainsEntry(sub_surfaces_, sub_surface)); + sub_surfaces_.erase(FindListEntry(sub_surfaces_, sub_surface)); } void Surface::SetSubSurfacePosition(Surface* sub_surface, @@ -321,7 +301,7 @@ if (it->second == position) return; it->second = position; - has_pending_layer_changes_ = true; + sub_surfaces_changed_ = true; } void Surface::PlaceSubSurfaceAbove(Surface* sub_surface, Surface* reference) { @@ -353,7 +333,7 @@ if (it == position_it) return; pending_sub_surfaces_.splice(position_it, pending_sub_surfaces_, it); - has_pending_layer_changes_ = true; + sub_surfaces_changed_ = true; } void Surface::PlaceSubSurfaceBelow(Surface* sub_surface, Surface* sibling) { @@ -378,7 +358,7 @@ if (it == sibling_it) return; pending_sub_surfaces_.splice(sibling_it, pending_sub_surfaces_, it); - has_pending_layer_changes_ = true; + sub_surfaces_changed_ = true; } void Surface::SetViewport(const gfx::Size& viewport) { @@ -421,108 +401,87 @@ TRACE_EVENT0("exo", "Surface::Commit"); needs_commit_surface_hierarchy_ = true; - - if (state_ != pending_state_) - has_pending_layer_changes_ = true; - - if (has_pending_contents_) { - if (pending_buffer_.buffer()) { - if (current_resource_.size != pending_buffer_.buffer()->GetSize()) - has_pending_layer_changes_ = true; - // Whether layer fills bounds opaquely or not might have changed. - if (current_resource_has_alpha_ != - FormatHasAlpha(pending_buffer_.buffer()->GetFormat())) - has_pending_layer_changes_ = true; - } else if (!current_resource_.size.IsEmpty()) { - has_pending_layer_changes_ = true; - } - } - - if (delegate_) { + if (delegate_) delegate_->OnSurfaceCommit(); - } else { - CommitSurfaceHierarchy(); - } - - if (current_begin_frame_ack_.sequence_number != - cc::BeginFrameArgs::kInvalidFrameNumber) { - if (!current_begin_frame_ack_.has_damage) { - layer_tree_frame_sink_holder_->frame_sink()->DidNotProduceFrame( - current_begin_frame_ack_); - } - current_begin_frame_ack_.sequence_number = - cc::BeginFrameArgs::kInvalidFrameNumber; - if (begin_frame_source_) - begin_frame_source_->DidFinishFrame(this); - } } -void Surface::CommitSurfaceHierarchy() { - DCHECK(needs_commit_surface_hierarchy_); - needs_commit_surface_hierarchy_ = false; - has_pending_layer_changes_ = false; +void Surface::CommitSurfaceHierarchy( + const gfx::Point& origin, + FrameType frame_type, + LayerTreeFrameSinkHolder* frame_sink_holder, + cc::CompositorFrame* frame, + std::list<FrameCallback>* frame_callbacks, + std::list<PresentationCallback>* presentation_callbacks) { + bool needs_commit = + frame_type == FRAME_TYPE_COMMIT && needs_commit_surface_hierarchy_; + if (needs_commit) { + needs_commit_surface_hierarchy_ = false; - state_ = pending_state_; - pending_state_.only_visible_on_secure_output = false; + state_ = pending_state_; + pending_state_.only_visible_on_secure_output = false; - // We update contents if Attach() has been called since last commit. - if (has_pending_contents_) { - has_pending_contents_ = false; + // We update contents if Attach() has been called since last commit. + if (has_pending_contents_) { + has_pending_contents_ = false; - current_buffer_ = std::move(pending_buffer_); + current_buffer_ = std::move(pending_buffer_); - UpdateResource(true); + UpdateResource(frame_sink_holder, true); + } + + // Move pending frame callbacks to the end of frame_callbacks. + frame_callbacks->splice(frame_callbacks->end(), pending_frame_callbacks_); + + // Move pending presentation callbacks to the end of presentation_callbacks. + presentation_callbacks->splice(presentation_callbacks->end(), + pending_presentation_callbacks_); + + UpdateContentSize(); + + // Synchronize window hierarchy. This will position and update the stacking + // order of all sub-surfaces after committing all pending state of + // sub-surface descendants. + if (sub_surfaces_changed_) { + sub_surfaces_.clear(); + aura::Window* stacking_target = nullptr; + for (const auto& sub_surface_entry : pending_sub_surfaces_) { + Surface* sub_surface = sub_surface_entry.first; + sub_surfaces_.push_back(sub_surface_entry); + // Move sub-surface to its new position in the stack. + if (stacking_target) + window_->StackChildAbove(sub_surface->window(), stacking_target); + + // Stack next sub-surface above this sub-surface. + stacking_target = sub_surface->window(); + + // Update sub-surface position relative to surface origin. + sub_surface->window()->SetBounds(gfx::Rect( + sub_surface_entry.second, sub_surface->window()->bounds().size())); + } + sub_surfaces_changed_ = false; + } } - // Move pending frame callbacks to the end of frame_callbacks_. - frame_callbacks_.splice(frame_callbacks_.end(), pending_frame_callbacks_); - - // Move pending presentation callbacks to the end of presentation_callbacks_. - presentation_callbacks_.splice(presentation_callbacks_.end(), - pending_presentation_callbacks_); - - UpdateSurface(false); - - window_->layer()->SetFillsBoundsOpaquely( - !current_resource_has_alpha_ || state_.blend_mode == SkBlendMode::kSrc || - state_.opaque_region.contains( - gfx::RectToSkIRect(gfx::Rect(content_size_)))); - - // Reset damage. - pending_damage_.setEmpty(); - DCHECK(!current_resource_.id || - layer_tree_frame_sink_holder_->HasReleaseCallbackForResource( - current_resource_.id)); - - // Synchronize window hierarchy. This will position and update the stacking - // order of all sub-surfaces after committing all pending state of sub-surface - // descendants. - aura::Window* stacking_target = nullptr; - for (auto& sub_surface_entry : pending_sub_surfaces_) { - Surface* sub_surface = sub_surface_entry.first; - + // The top most sub-surface is at the front of the RenderPass's quad_list, + // so we need composite sub-surface in reversed order. + for (const auto& sub_surface_entry : base::Reversed(sub_surfaces_)) { + auto* sub_surface = sub_surface_entry.first; // Synchronsouly commit all pending state of the sub-surface and its // decendents. - if (sub_surface->needs_commit_surface_hierarchy()) - sub_surface->CommitSurfaceHierarchy(); - - // Enable/disable sub-surface based on if it has contents. - if (sub_surface->has_contents()) - sub_surface->window()->Show(); - else - sub_surface->window()->Hide(); - - // Move sub-surface to its new position in the stack. - if (stacking_target) - window_->StackChildAbove(sub_surface->window(), stacking_target); - - // Stack next sub-surface above this sub-surface. - stacking_target = sub_surface->window(); - - // Update sub-surface position relative to surface origin. - sub_surface->window()->SetBounds( - gfx::Rect(sub_surface_entry.second, sub_surface->content_size_)); + sub_surface->CommitSurfaceHierarchy( + origin + sub_surface_entry.second.OffsetFromOrigin(), frame_type, + frame_sink_holder, frame, frame_callbacks, presentation_callbacks); } + + AppendContentsToFrame(origin, frame_type, frame); + + // Reset damage. + if (needs_commit) + pending_damage_.setEmpty(); + + DCHECK( + !current_resource_.id || + frame_sink_holder->HasReleaseCallbackForResource(current_resource_.id)); } bool Surface::IsSynchronized() const { @@ -599,49 +558,6 @@ return value; } -void Surface::DidReceiveCompositorFrameAck() { - active_frame_callbacks_.splice(active_frame_callbacks_.end(), - frame_callbacks_); - swapping_presentation_callbacks_.splice( - swapping_presentation_callbacks_.end(), presentation_callbacks_); - UpdateNeedsBeginFrame(); -} - -void Surface::SetBeginFrameSource(cc::BeginFrameSource* begin_frame_source) { - if (needs_begin_frame_) { - DCHECK(begin_frame_source_); - begin_frame_source_->RemoveObserver(this); - needs_begin_frame_ = false; - } - begin_frame_source_ = begin_frame_source; - UpdateNeedsBeginFrame(); -} - -void Surface::UpdateNeedsBeginFrame() { - if (!begin_frame_source_) - return; - - bool needs_begin_frame = !active_frame_callbacks_.empty(); - if (needs_begin_frame == needs_begin_frame_) - return; - - needs_begin_frame_ = needs_begin_frame; - if (needs_begin_frame_) - begin_frame_source_->AddObserver(this); - else - begin_frame_source_->RemoveObserver(this); -} - -bool Surface::OnBeginFrameDerivedImpl(const cc::BeginFrameArgs& args) { - current_begin_frame_ack_ = - cc::BeginFrameAck(args.source_id, args.sequence_number, false); - while (!active_frame_callbacks_.empty()) { - active_frame_callbacks_.front().Run(args.frame_time); - active_frame_callbacks_.pop_front(); - } - return true; -} - bool Surface::IsStylusOnly() { return window_->GetProperty(kStylusOnlyKey); } @@ -650,48 +566,17 @@ window_->SetProperty(kStylusOnlyKey, true); } -//////////////////////////////////////////////////////////////////////////////// -// ui::ContextFactoryObserver overrides: - -void Surface::OnLostResources() { - if (!window_->GetSurfaceId().is_valid()) - return; - UpdateResource(false); - UpdateSurface(true); +void Surface::RecreateResources(LayerTreeFrameSinkHolder* frame_sink_holder) { + UpdateResource(frame_sink_holder, false); + for (const auto& sub_surface : sub_surfaces_) + sub_surface.first->RecreateResources(frame_sink_holder); } -//////////////////////////////////////////////////////////////////////////////// -// aura::WindowObserver overrides: - -void Surface::OnWindowAddedToRootWindow(aura::Window* window) { - window->layer()->GetCompositor()->vsync_manager()->AddObserver(this); -} - -void Surface::OnWindowRemovingFromRootWindow(aura::Window* window, - aura::Window* new_root) { - window->layer()->GetCompositor()->vsync_manager()->RemoveObserver(this); -} - -//////////////////////////////////////////////////////////////////////////////// -// ui::CompositorVSyncManager::Observer overrides: - -void Surface::OnUpdateVSyncParameters(base::TimeTicks timebase, - base::TimeDelta interval) { - // Use current time if platform doesn't provide an accurate timebase. - if (timebase.is_null()) - timebase = base::TimeTicks::Now(); - - while (!swapped_presentation_callbacks_.empty()) { - swapped_presentation_callbacks_.front().Run(timebase, interval); - swapped_presentation_callbacks_.pop_front(); - } - - // VSync parameters updates are generated at the start of a new swap. Move - // the swapping presentation callbacks to swapped callbacks so they fire - // at the next VSync parameters update as that will contain the presentation - // time for the previous frame. - swapped_presentation_callbacks_.splice(swapped_presentation_callbacks_.end(), - swapping_presentation_callbacks_); +bool Surface::FillsBoundsOpaquely() const { + return !current_resource_has_alpha_ || + state_.blend_mode == SkBlendMode::kSrc || + state_.opaque_region.contains( + gfx::RectToSkIRect(gfx::Rect(content_size_))); } //////////////////////////////////////////////////////////////////////////////// @@ -741,12 +626,11 @@ buffer_ = buffer; } -void Surface::UpdateResource(bool client_usage) { +void Surface::UpdateResource(LayerTreeFrameSinkHolder* frame_sink_holder, + bool client_usage) { if (current_buffer_.buffer() && current_buffer_.buffer()->ProduceTransferableResource( - layer_tree_frame_sink_holder_.get(), - layer_tree_frame_sink_holder_->AllocateResourceId(), - state_.only_visible_on_secure_output, client_usage, + frame_sink_holder, state_.only_visible_on_secure_output, client_usage, ¤t_resource_)) { current_resource_has_alpha_ = FormatHasAlpha(current_buffer_.buffer()->GetFormat()); @@ -757,80 +641,47 @@ } } -void Surface::UpdateSurface(bool full_damage) { - gfx::Size buffer_size = current_resource_.size; - gfx::SizeF scaled_buffer_size( - gfx::ScaleSize(gfx::SizeF(buffer_size), 1.0f / state_.buffer_scale)); - - gfx::Size layer_size; // Size of the output layer, in DIP. - if (!state_.viewport.IsEmpty()) { - layer_size = state_.viewport; - } else if (!state_.crop.IsEmpty()) { - DLOG_IF(WARNING, !gfx::IsExpressibleAsInt(state_.crop.width()) || - !gfx::IsExpressibleAsInt(state_.crop.height())) - << "Crop rectangle size (" << state_.crop.size().ToString() - << ") most be expressible using integers when viewport is not set"; - layer_size = gfx::ToCeiledSize(state_.crop.size()); - } else { - layer_size = gfx::ToCeiledSize(scaled_buffer_size); - } - - content_size_ = layer_size; - // We need update window_'s bounds with content size, because the - // LayerTreeFrameSink may not update the window's size base the size of - // the lastest submitted CompositorFrame. - window_->SetBounds(gfx::Rect(window_->bounds().origin(), content_size_)); - // TODO(jbauman): Figure out how this interacts with the pixel size of - // CopyOutputRequests on the layer. - gfx::Size contents_surface_size = layer_size; - - gfx::PointF uv_top_left(0.f, 0.f); - gfx::PointF uv_bottom_right(1.f, 1.f); - if (!state_.crop.IsEmpty()) { - uv_top_left = state_.crop.origin(); - - uv_top_left.Scale(1.f / scaled_buffer_size.width(), - 1.f / scaled_buffer_size.height()); - uv_bottom_right = state_.crop.bottom_right(); - uv_bottom_right.Scale(1.f / scaled_buffer_size.width(), - 1.f / scaled_buffer_size.height()); - } - - gfx::Rect damage_rect; - gfx::Rect output_rect = gfx::Rect(contents_surface_size); - if (full_damage) { - damage_rect = output_rect; - } else { - // pending_damage_ is in Surface coordinates. - damage_rect = gfx::SkIRectToRect(pending_damage_.getBounds()); - damage_rect.Intersect(output_rect); - } - - const int kRenderPassId = 1; - std::unique_ptr<cc::RenderPass> render_pass = cc::RenderPass::Create(); - render_pass->SetNew(kRenderPassId, output_rect, damage_rect, - gfx::Transform()); - +void Surface::AppendContentsToFrame(const gfx::Point& origin, + FrameType frame_type, + cc::CompositorFrame* frame) { + 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; + } + + render_pass->damage_rect.Union(damage_rect); cc::SharedQuadState* quad_state = render_pass->CreateAndAppendSharedQuadState(); - quad_state->quad_layer_rect = gfx::Rect(contents_surface_size); + quad_state->quad_layer_rect = gfx::Rect(content_size_); quad_state->visible_quad_layer_rect = quad_rect; quad_state->opacity = state_.alpha; - cc::CompositorFrame frame; - // If we commit while we don't have an active BeginFrame, we acknowledge a - // manual one. - if (current_begin_frame_ack_.sequence_number == - cc::BeginFrameArgs::kInvalidFrameNumber) { - current_begin_frame_ack_ = cc::BeginFrameAck::CreateManualAckWithDamage(); - } else { - current_begin_frame_ack_.has_damage = true; - } - frame.metadata.begin_frame_ack = current_begin_frame_ack_; - frame.metadata.device_scale_factor = device_scale_factor_; - if (current_resource_.id) { + gfx::PointF uv_top_left(0.f, 0.f); + gfx::PointF uv_bottom_right(1.f, 1.f); + if (!state_.crop.IsEmpty()) { + gfx::SizeF scaled_buffer_size(gfx::ScaleSize( + gfx::SizeF(current_resource_.size), 1.0f / state_.buffer_scale)); + uv_top_left = state_.crop.origin(); + + uv_top_left.Scale(1.f / scaled_buffer_size.width(), + 1.f / scaled_buffer_size.height()); + uv_bottom_right = state_.crop.bottom_right(); + uv_bottom_right.Scale(1.f / scaled_buffer_size.width(), + 1.f / scaled_buffer_size.height()); + } // Texture quad is only needed if buffer is not fully transparent. if (state_.alpha) { cc::TextureDrawQuad* texture_quad = @@ -845,23 +696,46 @@ opaque_rect = gfx::SkIRectToRect(state_.opaque_region.getBounds()); } - texture_quad->SetNew(quad_state, quad_rect, opaque_rect, quad_rect, - current_resource_.id, true, uv_top_left, - uv_bottom_right, SK_ColorTRANSPARENT, vertex_opacity, - false, false, state_.only_visible_on_secure_output); + texture_quad->SetNew( + quad_state, quad_rect, opaque_rect, quad_rect, current_resource_.id, + true /* premultiplied_alpha */, uv_top_left, uv_bottom_right, + SK_ColorTRANSPARENT /* background_color */, vertex_opacity, + false /* y_flipped */, false /* nearest_neighbor */, + state_.only_visible_on_secure_output); if (current_resource_.is_overlay_candidate) texture_quad->set_resource_size_in_pixels(current_resource_.size); - frame.resource_list.push_back(current_resource_); + frame->resource_list.push_back(current_resource_); } } else { cc::SolidColorDrawQuad* solid_quad = render_pass->CreateAndAppendDrawQuad<cc::SolidColorDrawQuad>(); - solid_quad->SetNew(quad_state, quad_rect, quad_rect, SK_ColorBLACK, false); + solid_quad->SetNew(quad_state, quad_rect, quad_rect, SK_ColorBLACK, + false /* force_anti_aliasing_off */); } +} - frame.render_pass_list.push_back(std::move(render_pass)); - layer_tree_frame_sink_holder_->frame_sink()->SubmitCompositorFrame( - std::move(frame)); +void Surface::UpdateContentSize() { + gfx::Size buffer_size = current_resource_.size; + gfx::SizeF scaled_buffer_size( + gfx::ScaleSize(gfx::SizeF(buffer_size), 1.0f / state_.buffer_scale)); + if (!state_.viewport.IsEmpty()) { + content_size_ = state_.viewport; + } else if (!state_.crop.IsEmpty()) { + DLOG_IF(WARNING, !gfx::IsExpressibleAsInt(state_.crop.width()) || + !gfx::IsExpressibleAsInt(state_.crop.height())) + << "Crop rectangle size (" << state_.crop.size().ToString() + << ") most be expressible using integers when viewport is not set"; + content_size_ = gfx::ToCeiledSize(state_.crop.size()); + } else { + content_size_ = gfx::ToCeiledSize(scaled_buffer_size); + } + window_->SetBounds(gfx::Rect(window_->bounds().origin(), content_size_)); + + // Enable/disable sub-surface based on if it has contents. + if (has_contents()) + window_->Show(); + else + window_->Hide(); } } // namespace exo
diff --git a/components/exo/surface.h b/components/exo/surface.h index ae16873..5047d16 100644 --- a/components/exo/surface.h +++ b/components/exo/surface.h
@@ -15,13 +15,10 @@ #include "base/memory/weak_ptr.h" #include "base/observer_list.h" #include "cc/resources/transferable_resource.h" -#include "cc/scheduler/begin_frame_source.h" #include "components/exo/layer_tree_frame_sink_holder.h" #include "third_party/skia/include/core/SkBlendMode.h" #include "third_party/skia/include/core/SkRegion.h" #include "ui/aura/window.h" -#include "ui/aura/window_observer.h" -#include "ui/compositor/compositor_vsync_manager.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/native_widget_types.h" @@ -31,12 +28,17 @@ } } +namespace cc { +class CompositorFrame; +} + namespace gfx { class Path; } namespace exo { class Buffer; +class LayerTreeFrameSinkHolder; class Pointer; class SurfaceDelegate; class SurfaceObserver; @@ -52,28 +54,18 @@ // This class represents a rectangular area that is displayed on the screen. // It has a location, size and pixel contents. -class Surface : public ui::ContextFactoryObserver, - public aura::WindowObserver, - public ui::PropertyHandler, - public ui::CompositorVSyncManager::Observer, - public cc::BeginFrameObserverBase { +class Surface : public ui::PropertyHandler { public: using PropertyDeallocator = void (*)(int64_t value); Surface(); - ~Surface() override; + ~Surface(); // Type-checking downcast routine. static Surface* AsSurface(const aura::Window* window); aura::Window* window() { return window_.get(); } - viz::SurfaceId GetSurfaceId() const; - - LayerTreeFrameSinkHolder* layer_tree_frame_sink_holder() { - return layer_tree_frame_sink_holder_.get(); - } - // Set a buffer as the content of this surface. A buffer can only be attached // to one surface at a time. void Attach(Buffer* buffer); @@ -144,7 +136,17 @@ // This will synchronously commit all pending state of the surface and its // descendants by recursively calling CommitSurfaceHierarchy() for each // sub-surface with pending state. - void CommitSurfaceHierarchy(); + enum FrameType { + FRAME_TYPE_COMMIT, + FRAME_TYPE_RECREATED_RESOURCES, + }; + void CommitSurfaceHierarchy( + const gfx::Point& origin, + FrameType frame_type, + LayerTreeFrameSinkHolder* frame_sink_holder, + cc::CompositorFrame* frame, + std::list<FrameCallback>* frame_callbacks, + std::list<PresentationCallback>* presentation_callbacks); // Returns true if surface is in synchronized mode. bool IsSynchronized() const; @@ -186,10 +188,6 @@ // Returns a trace value representing the state of the surface. std::unique_ptr<base::trace_event::TracedValue> AsTracedValue() const; - // Call this to indicate that the previous CompositorFrame is processed and - // the surface is being scheduled for a draw. - void DidReceiveCompositorFrameAck(); - // Called when the begin frame source has changed. void SetBeginFrameSource(cc::BeginFrameSource* begin_frame_source); @@ -202,26 +200,16 @@ // Enables 'stylus-only' mode for the associated window. void SetStylusOnly(); - // Overridden from ui::ContextFactoryObserver: - void OnLostResources() override; + // Recreates resources for the surface and sub surfaces. + void RecreateResources(LayerTreeFrameSinkHolder* frame_sink_holder); - // Overridden from aura::WindowObserver: - void OnWindowAddedToRootWindow(aura::Window* window) override; - void OnWindowRemovingFromRootWindow(aura::Window* window, - aura::Window* new_root) override; - - // Overridden from ui::CompositorVSyncManager::Observer: - void OnUpdateVSyncParameters(base::TimeTicks timebase, - base::TimeDelta interval) override; + // Returns true if the surface's bounds should be filled opaquely. + bool FillsBoundsOpaquely() const; bool HasPendingDamageForTesting(const gfx::Rect& damage) const { return pending_damage_.contains(gfx::RectToSkIRect(damage)); } - // Overridden from cc::BeginFrameObserverBase: - bool OnBeginFrameDerivedImpl(const cc::BeginFrameArgs& args) override; - void OnBeginFrameSourcePausedChanged(bool paused) override {} - private: struct State { State(); @@ -269,14 +257,16 @@ // contents of the attached buffer (or id 0, if no buffer is attached). // UpdateSurface must be called afterwards to ensure the release callback // will be called. - void UpdateResource(bool client_usage); + void UpdateResource(LayerTreeFrameSinkHolder* frame_sink_holder, + bool client_usage); - // Updates the current Surface with a new frame referring to the resource in - // current_resource_. - void UpdateSurface(bool full_damage); + // 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); - // Adds/Removes begin frame observer based on state. - void UpdateNeedsBeginFrame(); + void UpdateContentSize(); // This returns true when the surface has some contents assigned to it. bool has_contents() const { return !!current_buffer_.buffer(); } @@ -284,10 +274,8 @@ // This window has the layer which contains the Surface contents. std::unique_ptr<aura::Window> window_; - // This is true if it's possible that the layer properties (size, opacity, - // etc.) may have been modified since the last commit. Attaching a new - // buffer with the same size as the old shouldn't set this to true. - bool has_pending_layer_changes_ = true; + // This true, if sub_surfaces_ has changes (order, position, etc). + bool sub_surfaces_changed_ = false; // This is the size of the last committed contents. gfx::Size content_size_; @@ -302,8 +290,6 @@ // The device scale factor sent in CompositorFrames. float device_scale_factor_ = 1.0f; - std::unique_ptr<LayerTreeFrameSinkHolder> layer_tree_frame_sink_holder_; - // The damage region to schedule paint for when Commit() is called. SkRegion pending_damage_; @@ -313,8 +299,6 @@ // |active_frame_callbacks_| when the effect of the Commit() is scheduled to // be drawn. They fire at the first begin frame notification after this. std::list<FrameCallback> pending_frame_callbacks_; - std::list<FrameCallback> frame_callbacks_; - std::list<FrameCallback> active_frame_callbacks_; // These lists contains the callbacks to notify the client when surface // contents have been presented. These callbacks move to @@ -324,9 +308,6 @@ // after receiving VSync parameters update for the previous frame. They fire // at the next VSync parameters update after that. std::list<PresentationCallback> pending_presentation_callbacks_; - std::list<PresentationCallback> presentation_callbacks_; - std::list<PresentationCallback> swapping_presentation_callbacks_; - std::list<PresentationCallback> swapped_presentation_callbacks_; // This is the state that has yet to be committed. State pending_state_; @@ -340,6 +321,7 @@ using SubSurfaceEntry = std::pair<Surface*, gfx::Point>; using SubSurfaceEntryList = std::list<SubSurfaceEntry>; SubSurfaceEntryList pending_sub_surfaces_; + SubSurfaceEntryList sub_surfaces_; // The buffer that is currently set as content of surface. BufferAttachment current_buffer_; @@ -369,11 +351,6 @@ // Surface observer list. Surface does not own the observers. base::ObserverList<SurfaceObserver, true> observers_; - // The begin frame source being observed. - cc::BeginFrameSource* begin_frame_source_ = nullptr; - bool needs_begin_frame_ = false; - cc::BeginFrameAck current_begin_frame_ack_; - DISALLOW_COPY_AND_ASSIGN(Surface); };
diff --git a/components/exo/surface_tree_host.cc b/components/exo/surface_tree_host.cc index 36442f58..24dff7f 100644 --- a/components/exo/surface_tree_host.cc +++ b/components/exo/surface_tree_host.cc
@@ -8,7 +8,11 @@ #include "base/macros.h" #include "base/memory/ptr_util.h" +#include "cc/output/compositor_frame.h" +#include "cc/output/layer_tree_frame_sink.h" +#include "components/exo/layer_tree_frame_sink_holder.h" #include "components/exo/surface.h" +#include "ui/aura/env.h" #include "ui/aura/window.h" #include "ui/aura/window_delegate.h" #include "ui/aura/window_event_dispatcher.h" @@ -73,15 +77,20 @@ host_window_ = base::MakeUnique<aura::Window>(window_delegate); host_window_->SetType(aura::client::WINDOW_TYPE_CONTROL); host_window_->SetName(window_name); - host_window_->Init(ui::LAYER_NOT_DRAWN); + host_window_->Init(ui::LAYER_SOLID_COLOR); host_window_->set_owned_by_parent(false); host_window_->SetEventTargeter(base::MakeUnique<CustomWindowTargeter>(this)); + layer_tree_frame_sink_holder_ = base::MakeUnique<LayerTreeFrameSinkHolder>( + this, host_window_->CreateLayerTreeFrameSink()); + aura::Env::GetInstance()->context_factory()->AddObserver(this); } SurfaceTreeHost::~SurfaceTreeHost() { - if (root_surface_) { - root_surface_->window()->Hide(); - root_surface_->SetSurfaceDelegate(nullptr); + aura::Env::GetInstance()->context_factory()->RemoveObserver(this); + SetRootSurface(nullptr); + if (host_window_->layer()->GetCompositor()) { + host_window_->layer()->GetCompositor()->vsync_manager()->RemoveObserver( + this); } } @@ -96,6 +105,28 @@ gfx::Rect(host_window_->bounds().origin(), gfx::Size())); root_surface_->SetSurfaceDelegate(nullptr); root_surface_ = nullptr; + + active_frame_callbacks_.splice(active_frame_callbacks_.end(), + frame_callbacks_); + // Call all frame callbacks with a null frame time to indicate that they + // have been cancelled. + while (!active_frame_callbacks_.empty()) { + active_frame_callbacks_.front().Run(base::TimeTicks()); + active_frame_callbacks_.pop_front(); + } + + swapping_presentation_callbacks_.splice( + swapping_presentation_callbacks_.end(), presentation_callbacks_); + swapped_presentation_callbacks_.splice( + swapped_presentation_callbacks_.end(), + swapping_presentation_callbacks_); + // Call all presentation callbacks with a null presentation time to indicate + // that they have been cancelled. + while (!swapped_presentation_callbacks_.empty()) { + swapped_presentation_callbacks_.front().Run(base::TimeTicks(), + base::TimeDelta()); + swapped_presentation_callbacks_.pop_front(); + } } if (root_surface) { @@ -125,14 +156,43 @@ return root_surface_ ? root_surface_->GetCursor() : ui::CursorType::kNull; } +void SurfaceTreeHost::DidReceiveCompositorFrameAck() { + active_frame_callbacks_.splice(active_frame_callbacks_.end(), + frame_callbacks_); + swapping_presentation_callbacks_.splice( + swapping_presentation_callbacks_.end(), presentation_callbacks_); + UpdateNeedsBeginFrame(); +} + +void SurfaceTreeHost::SetBeginFrameSource( + cc::BeginFrameSource* begin_frame_source) { + if (needs_begin_frame_) { + DCHECK(begin_frame_source_); + begin_frame_source_->RemoveObserver(this); + needs_begin_frame_ = false; + } + begin_frame_source_ = begin_frame_source; + UpdateNeedsBeginFrame(); +} + +void SurfaceTreeHost::UpdateNeedsBeginFrame() { + if (!begin_frame_source_) + return; + bool needs_begin_frame = !active_frame_callbacks_.empty(); + if (needs_begin_frame == needs_begin_frame_) + return; + needs_begin_frame_ = needs_begin_frame; + if (needs_begin_frame_) + begin_frame_source_->AddObserver(this); + else + begin_frame_source_->RemoveObserver(this); +} + //////////////////////////////////////////////////////////////////////////////// // SurfaceDelegate overrides: void SurfaceTreeHost::OnSurfaceCommit() { - DCHECK(root_surface_); - root_surface_->CommitSurfaceHierarchy(); - host_window_->SetBounds(gfx::Rect(host_window_->bounds().origin(), - root_surface_->content_size())); + SubmitCompositorFrame(Surface::FRAME_TYPE_COMMIT); } bool SurfaceTreeHost::IsSurfaceSynchronized() const { @@ -141,4 +201,111 @@ return false; } +//////////////////////////////////////////////////////////////////////////////// +// aura::WindowObserver overrides: + +void SurfaceTreeHost::OnWindowAddedToRootWindow(aura::Window* window) { + DCHECK_EQ(window, host_window()); + window->layer()->GetCompositor()->vsync_manager()->AddObserver(this); +} + +void SurfaceTreeHost::OnWindowRemovingFromRootWindow(aura::Window* window, + aura::Window* new_root) { + DCHECK_EQ(window, host_window()); + window->layer()->GetCompositor()->vsync_manager()->RemoveObserver(this); +} + +void SurfaceTreeHost::OnWindowDestroying(aura::Window* window) { + DCHECK_EQ(window, host_window()); + window->RemoveObserver(this); +} + +//////////////////////////////////////////////////////////////////////////////// +// cc::BeginFrameObserverBase overrides: + +bool SurfaceTreeHost::OnBeginFrameDerivedImpl(const cc::BeginFrameArgs& args) { + current_begin_frame_ack_ = + cc::BeginFrameAck(args.source_id, args.sequence_number, false); + while (!active_frame_callbacks_.empty()) { + active_frame_callbacks_.front().Run(args.frame_time); + active_frame_callbacks_.pop_front(); + } + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +// ui::CompositorVSyncManager::Observer overrides: + +void SurfaceTreeHost::OnUpdateVSyncParameters(base::TimeTicks timebase, + base::TimeDelta interval) { + // Use current time if platform doesn't provide an accurate timebase. + if (timebase.is_null()) + timebase = base::TimeTicks::Now(); + while (!swapped_presentation_callbacks_.empty()) { + swapped_presentation_callbacks_.front().Run(timebase, interval); + swapped_presentation_callbacks_.pop_front(); + } + // VSync parameters updates are generated at the start of a new swap. Move + // the swapping presentation callbacks to swapped callbacks so they fire + // at the next VSync parameters update as that will contain the presentation + // time for the previous frame. + swapped_presentation_callbacks_.splice(swapped_presentation_callbacks_.end(), + swapping_presentation_callbacks_); +} + +//////////////////////////////////////////////////////////////////////////////// +// ui::ContextFactoryObserver overrides: + +void SurfaceTreeHost::OnLostResources() { + if (!host_window_->GetSurfaceId().is_valid()) + return; + root_surface_->RecreateResources(layer_tree_frame_sink_holder_.get()); + SubmitCompositorFrame(Surface::FRAME_TYPE_RECREATED_RESOURCES); +} + +void SurfaceTreeHost::SubmitCompositorFrame(Surface::FrameType frame_type) { + DCHECK(root_surface_); + cc::CompositorFrame frame; + // If we commit while we don't have an active BeginFrame, we acknowledge a + // manual one. + if (current_begin_frame_ack_.sequence_number == + cc::BeginFrameArgs::kInvalidFrameNumber) { + current_begin_frame_ack_ = cc::BeginFrameAck::CreateManualAckWithDamage(); + } else { + current_begin_frame_ack_.has_damage = true; + } + + frame.metadata.begin_frame_ack = current_begin_frame_ack_; + frame.metadata.device_scale_factor = + host_window_->layer()->device_scale_factor(); + const int kRenderPassId = 1; + std::unique_ptr<cc::RenderPass> render_pass = cc::RenderPass::Create(); + render_pass->SetNew(kRenderPassId, gfx::Rect(), gfx::Rect(), + gfx::Transform()); + frame.render_pass_list.push_back(std::move(render_pass)); + root_surface_->CommitSurfaceHierarchy( + gfx::Point(), frame_type, layer_tree_frame_sink_holder_.get(), &frame, + &frame_callbacks_, &presentation_callbacks_); + frame.render_pass_list.back()->output_rect = + gfx::Rect(root_surface_->content_size()); + layer_tree_frame_sink_holder_->frame_sink()->SubmitCompositorFrame( + std::move(frame)); + host_window_->SetBounds(gfx::Rect(host_window_->bounds().origin(), + root_surface_->content_size())); + host_window_->layer()->SetFillsBoundsOpaquely( + root_surface_->FillsBoundsOpaquely()); + + if (current_begin_frame_ack_.sequence_number != + cc::BeginFrameArgs::kInvalidFrameNumber) { + if (!current_begin_frame_ack_.has_damage) { + layer_tree_frame_sink_holder_->frame_sink()->DidNotProduceFrame( + current_begin_frame_ack_); + } + current_begin_frame_ack_.sequence_number = + cc::BeginFrameArgs::kInvalidFrameNumber; + if (begin_frame_source_) + begin_frame_source_->DidFinishFrame(this); + } +} + } // namespace exo
diff --git a/components/exo/surface_tree_host.h b/components/exo/surface_tree_host.h index c92a434..e102766a 100644 --- a/components/exo/surface_tree_host.h +++ b/components/exo/surface_tree_host.h
@@ -8,8 +8,12 @@ #include <memory> #include "base/macros.h" +#include "cc/scheduler/begin_frame_source.h" +#include "components/exo/layer_tree_frame_sink_holder.h" #include "components/exo/surface.h" #include "components/exo/surface_delegate.h" +#include "ui/aura/window_observer.h" +#include "ui/compositor/compositor_vsync_manager.h" #include "ui/gfx/geometry/rect.h" namespace aura { @@ -17,15 +21,24 @@ class WindowDelegate; } // namespace aura +namespace cc { +class BeginFrameSource; +} // namespace cc + namespace gfx { class Path; } // namespace gfx namespace exo { +class LayerTreeFrameSinkHolder; // This class provides functionality for hosting a surface tree. The surface // tree is hosted in the |host_window_|. -class SurfaceTreeHost : public SurfaceDelegate { +class SurfaceTreeHost : public SurfaceDelegate, + public aura::WindowObserver, + public cc::BeginFrameObserverBase, + public ui::CompositorVSyncManager::Observer, + public ui::ContextFactoryObserver { public: SurfaceTreeHost(const std::string& window_name, aura::WindowDelegate* window_delegate); @@ -48,19 +61,77 @@ // registered then CursorType::kNull is returned. gfx::NativeCursor GetCursor(const gfx::Point& point) const; + // Call this to indicate that the previous CompositorFrame is processed and + // the surface is being scheduled for a draw. + void DidReceiveCompositorFrameAck(); + + // Called when the begin frame source has changed. + void SetBeginFrameSource(cc::BeginFrameSource* begin_frame_source); + + // Adds/Removes begin frame observer based on state. + void UpdateNeedsBeginFrame(); + aura::Window* host_window() { return host_window_.get(); } const aura::Window* host_window() const { return host_window_.get(); } Surface* root_surface() { return root_surface_; } const Surface* root_surface() const { return root_surface_; } + LayerTreeFrameSinkHolder* layer_tree_frame_sink_holder() { + return layer_tree_frame_sink_holder_.get(); + } + // Overridden from SurfaceDelegate: void OnSurfaceCommit() override; bool IsSurfaceSynchronized() const override; + // Overridden from aura::WindowObserver: + void OnWindowAddedToRootWindow(aura::Window* window) override; + void OnWindowRemovingFromRootWindow(aura::Window* window, + aura::Window* new_root) override; + void OnWindowDestroying(aura::Window* window) override; + + // Overridden from cc::BeginFrameObserverBase: + bool OnBeginFrameDerivedImpl(const cc::BeginFrameArgs& args) override; + void OnBeginFrameSourcePausedChanged(bool paused) override {} + + // Overridden from ui::CompositorVSyncManager::Observer: + void OnUpdateVSyncParameters(base::TimeTicks timebase, + base::TimeDelta interval) override; + + // Overridden from ui::ContextFactoryObserver: + void OnLostResources() override; + private: + void SubmitCompositorFrame(Surface::FrameType frame_type); + Surface* root_surface_ = nullptr; std::unique_ptr<aura::Window> host_window_; + std::unique_ptr<LayerTreeFrameSinkHolder> layer_tree_frame_sink_holder_; + + // The begin frame source being observed. + cc::BeginFrameSource* begin_frame_source_ = nullptr; + bool needs_begin_frame_ = false; + cc::BeginFrameAck current_begin_frame_ack_; + + // These lists contain the callbacks to notify the client when it is a good + // time to start producing a new frame. These callbacks move to + // |frame_callbacks_| when Commit() is called. Later they are moved to + // |active_frame_callbacks_| when the effect of the Commit() is scheduled to + // be drawn. They fire at the first begin frame notification after this. + std::list<Surface::FrameCallback> frame_callbacks_; + std::list<Surface::FrameCallback> active_frame_callbacks_; + + // These lists contains the callbacks to notify the client when surface + // contents have been presented. These callbacks move to + // |presentation_callbacks_| when Commit() is called. Later they are moved to + // |swapping_presentation_callbacks_| when the effect of the Commit() is + // scheduled to be drawn and then moved to |swapped_presentation_callbacks_| + // after receiving VSync parameters update for the previous frame. They fire + // at the next VSync parameters update after that. + std::list<Surface::PresentationCallback> presentation_callbacks_; + std::list<Surface::PresentationCallback> swapping_presentation_callbacks_; + std::list<Surface::PresentationCallback> swapped_presentation_callbacks_; DISALLOW_COPY_AND_ASSIGN(SurfaceTreeHost); };
diff --git a/components/exo/surface_unittest.cc b/components/exo/surface_unittest.cc index d638abc..d8f7f63 100644 --- a/components/exo/surface_unittest.cc +++ b/components/exo/surface_unittest.cc
@@ -9,11 +9,13 @@ #include "cc/test/begin_frame_args_test.h" #include "cc/test/fake_external_begin_frame_source.h" #include "components/exo/buffer.h" +#include "components/exo/shell_surface.h" #include "components/exo/surface.h" #include "components/exo/test/exo_test_base.h" #include "components/exo/test/exo_test_helper.h" #include "components/viz/service/frame_sinks/frame_sink_manager.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/khronos/GLES2/gl2.h" #include "ui/aura/env.h" #include "ui/compositor/layer_tree_owner.h" #include "ui/gfx/gpu_memory_buffer.h" @@ -99,8 +101,8 @@ EXPECT_TRUE(frame_time.is_null()); } -const cc::CompositorFrame& GetFrameFromSurface(Surface* surface) { - viz::SurfaceId surface_id = surface->GetSurfaceId(); +const cc::CompositorFrame& GetFrameFromSurface(ShellSurface* shell_surface) { + viz::SurfaceId surface_id = shell_surface->host_window()->GetSurfaceId(); cc::SurfaceManager* surface_manager = aura::Env::GetInstance() ->context_factory_private() ->GetFrameSinkManager() @@ -112,9 +114,10 @@ TEST_F(SurfaceTest, SetOpaqueRegion) { gfx::Size buffer_size(1, 1); - std::unique_ptr<Buffer> buffer( - new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size))); - std::unique_ptr<Surface> surface(new Surface); + auto buffer = base::MakeUnique<Buffer>( + exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)); + auto surface = base::MakeUnique<Surface>(); + auto shell_surface = base::MakeUnique<ShellSurface>(surface.get()); // Attaching a buffer with alpha channel. surface->Attach(buffer.get()); @@ -126,7 +129,7 @@ RunAllPendingInMessageLoop(); { - const cc::CompositorFrame& frame = GetFrameFromSurface(surface.get()); + const cc::CompositorFrame& frame = GetFrameFromSurface(shell_surface.get()); ASSERT_EQ(1u, frame.render_pass_list.size()); ASSERT_EQ(1u, frame.render_pass_list.back()->quad_list.size()); EXPECT_FALSE(frame.render_pass_list.back() @@ -140,7 +143,7 @@ RunAllPendingInMessageLoop(); { - const cc::CompositorFrame& frame = GetFrameFromSurface(surface.get()); + const cc::CompositorFrame& frame = GetFrameFromSurface(shell_surface.get()); ASSERT_EQ(1u, frame.render_pass_list.size()); ASSERT_EQ(1u, frame.render_pass_list.back()->quad_list.size()); EXPECT_TRUE(frame.render_pass_list.back() @@ -159,7 +162,7 @@ RunAllPendingInMessageLoop(); { - const cc::CompositorFrame& frame = GetFrameFromSurface(surface.get()); + const cc::CompositorFrame& frame = GetFrameFromSurface(shell_surface.get()); ASSERT_EQ(1u, frame.render_pass_list.size()); ASSERT_EQ(1u, frame.render_pass_list.back()->quad_list.size()); EXPECT_FALSE(frame.render_pass_list.back() @@ -180,9 +183,10 @@ TEST_F(SurfaceTest, SetBufferScale) { gfx::Size buffer_size(512, 512); - std::unique_ptr<Buffer> buffer( - new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size))); - std::unique_ptr<Surface> surface(new Surface); + auto buffer = base::MakeUnique<Buffer>( + exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)); + auto surface = base::MakeUnique<Surface>(); + auto shell_surface = base::MakeUnique<ShellSurface>(surface.get()); // This will update the bounds of the surface and take the buffer scale into // account. @@ -200,9 +204,10 @@ TEST_F(SurfaceTest, MirrorLayers) { gfx::Size buffer_size(512, 512); - std::unique_ptr<Buffer> buffer( - new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size))); - std::unique_ptr<Surface> surface(new Surface); + auto buffer = base::MakeUnique<Buffer>( + exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)); + auto surface = base::MakeUnique<Surface>(); + auto shell_surface = base::MakeUnique<ShellSurface>(surface.get()); surface->Attach(buffer.get()); surface->Commit(); @@ -210,19 +215,20 @@ EXPECT_EQ(buffer_size, surface->window()->bounds().size()); EXPECT_EQ(buffer_size, surface->window()->layer()->bounds().size()); std::unique_ptr<ui::LayerTreeOwner> old_layer_owner = - ::wm::MirrorLayers(surface->window(), false /* sync_bounds */); + ::wm::MirrorLayers(shell_surface->host_window(), false /* sync_bounds */); EXPECT_EQ(buffer_size, surface->window()->bounds().size()); EXPECT_EQ(buffer_size, surface->window()->layer()->bounds().size()); EXPECT_EQ(buffer_size, old_layer_owner->root()->bounds().size()); - EXPECT_TRUE(surface->window()->layer()->has_external_content()); + EXPECT_TRUE(shell_surface->host_window()->layer()->has_external_content()); EXPECT_TRUE(old_layer_owner->root()->has_external_content()); } TEST_F(SurfaceTest, SetViewport) { gfx::Size buffer_size(1, 1); - std::unique_ptr<Buffer> buffer( - new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size))); - std::unique_ptr<Surface> surface(new Surface); + auto buffer = base::MakeUnique<Buffer>( + exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)); + auto surface = base::MakeUnique<Surface>(); + auto shell_surface = base::MakeUnique<ShellSurface>(surface.get()); // This will update the bounds of the surface and take the viewport into // account. @@ -244,9 +250,10 @@ TEST_F(SurfaceTest, SetCrop) { gfx::Size buffer_size(16, 16); - std::unique_ptr<Buffer> buffer( - new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size))); - std::unique_ptr<Surface> surface(new Surface); + auto buffer = base::MakeUnique<Buffer>( + exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)); + auto surface = base::MakeUnique<Surface>(); + auto shell_surface = base::MakeUnique<ShellSurface>(surface.get()); surface->Attach(buffer.get()); gfx::Size crop_size(12, 12); @@ -259,16 +266,17 @@ TEST_F(SurfaceTest, SetBlendMode) { gfx::Size buffer_size(1, 1); - std::unique_ptr<Buffer> buffer( - new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size))); - std::unique_ptr<Surface> surface(new Surface); + auto buffer = base::MakeUnique<Buffer>( + exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)); + auto surface = base::MakeUnique<Surface>(); + auto shell_surface = base::MakeUnique<ShellSurface>(surface.get()); surface->Attach(buffer.get()); surface->SetBlendMode(SkBlendMode::kSrc); surface->Commit(); RunAllPendingInMessageLoop(); - const cc::CompositorFrame& frame = GetFrameFromSurface(surface.get()); + const cc::CompositorFrame& frame = GetFrameFromSurface(shell_surface.get()); ASSERT_EQ(1u, frame.render_pass_list.size()); ASSERT_EQ(1u, frame.render_pass_list.back()->quad_list.size()); EXPECT_FALSE(frame.render_pass_list.back() @@ -278,15 +286,17 @@ TEST_F(SurfaceTest, OverlayCandidate) { gfx::Size buffer_size(1, 1); - std::unique_ptr<Buffer> buffer(new Buffer( - exo_test_helper()->CreateGpuMemoryBuffer(buffer_size), 0, 0, true, true)); - std::unique_ptr<Surface> surface(new Surface); + auto buffer = base::MakeUnique<Buffer>( + exo_test_helper()->CreateGpuMemoryBuffer(buffer_size), GL_TEXTURE_2D, 0, + true, true); + auto surface = base::MakeUnique<Surface>(); + auto shell_surface = base::MakeUnique<ShellSurface>(surface.get()); surface->Attach(buffer.get()); surface->Commit(); RunAllPendingInMessageLoop(); - const cc::CompositorFrame& frame = GetFrameFromSurface(surface.get()); + const cc::CompositorFrame& frame = GetFrameFromSurface(shell_surface.get()); ASSERT_EQ(1u, frame.render_pass_list.size()); ASSERT_EQ(1u, frame.render_pass_list.back()->quad_list.size()); cc::DrawQuad* draw_quad = frame.render_pass_list.back()->quad_list.back(); @@ -299,9 +309,11 @@ TEST_F(SurfaceTest, SetAlpha) { gfx::Size buffer_size(1, 1); - std::unique_ptr<Buffer> buffer( - new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size))); - std::unique_ptr<Surface> surface(new Surface); + auto buffer = base::MakeUnique<Buffer>( + exo_test_helper()->CreateGpuMemoryBuffer(buffer_size), GL_TEXTURE_2D, 0, + true, true); + auto surface = base::MakeUnique<Surface>(); + auto shell_surface = base::MakeUnique<ShellSurface>(surface.get()); surface->Attach(buffer.get()); surface->SetAlpha(0.5f); @@ -318,10 +330,12 @@ TEST_F(SurfaceTest, SendsBeginFrameAcks) { cc::FakeExternalBeginFrameSource source(0.f, false); gfx::Size buffer_size(1, 1); - std::unique_ptr<Buffer> buffer( - new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size))); - std::unique_ptr<Surface> surface(new Surface); - surface->SetBeginFrameSource(&source); + auto buffer = base::MakeUnique<Buffer>( + exo_test_helper()->CreateGpuMemoryBuffer(buffer_size), GL_TEXTURE_2D, 0, + true, true); + auto surface = base::MakeUnique<Surface>(); + auto shell_surface = base::MakeUnique<ShellSurface>(surface.get()); + shell_surface->SetBeginFrameSource(&source); surface->Attach(buffer.get()); // Request a frame callback so that Surface now needs BeginFrames. @@ -333,7 +347,7 @@ // Surface should add itself as observer during // DidReceiveCompositorFrameAck(). - surface->DidReceiveCompositorFrameAck(); + shell_surface->DidReceiveCompositorFrameAck(); EXPECT_EQ(1u, source.num_observers()); cc::BeginFrameArgs args(source.CreateBeginFrameArgs(BEGINFRAME_FROM_HERE)); @@ -344,7 +358,7 @@ surface->Commit(); // Acknowledges the BeginFrame via CompositorFrame. RunAllPendingInMessageLoop(); - const cc::CompositorFrame& frame = GetFrameFromSurface(surface.get()); + const cc::CompositorFrame& frame = GetFrameFromSurface(shell_surface.get()); cc::BeginFrameAck expected_ack(args.source_id, args.sequence_number, true); EXPECT_EQ(expected_ack, frame.metadata.begin_frame_ack);
diff --git a/components/infobars/core/infobar_delegate.h b/components/infobars/core/infobar_delegate.h index f0c0fac..1405106 100644 --- a/components/infobars/core/infobar_delegate.h +++ b/components/infobars/core/infobar_delegate.h
@@ -122,9 +122,9 @@ AUTOFILL_CC_INFOBAR_DELEGATE = 49, TRANSLATE_INFOBAR_DELEGATE = 50, IOS_CHROME_SAVE_PASSWORD_INFOBAR_DELEGATE = 51, - NATIVE_APP_INSTALLER_INFOBAR_DELEGATE = 52, - NATIVE_APP_LAUNCHER_INFOBAR_DELEGATE = 53, - NATIVE_APP_OPEN_POLICY_INFOBAR_DELEGATE = 54, + // Removed: NATIVE_APP_INSTALLER_INFOBAR_DELEGATE = 52, + // Removed: NATIVE_APP_LAUNCHER_INFOBAR_DELEGATE = 53, + // Removed: NATIVE_APP_OPEN_POLICY_INFOBAR_DELEGATE = 54, RE_SIGN_IN_INFOBAR_DELEGATE = 55, SHOW_PASSKIT_INFOBAR_ERROR_DELEGATE = 56, READER_MODE_INFOBAR_DELEGATE_IOS = 57,
diff --git a/components/neterror/resources/neterror.css b/components/neterror/resources/neterror.css index 7ead318..c7cd42e 100644 --- a/components/neterror/resources/neterror.css +++ b/components/neterror/resources/neterror.css
@@ -531,7 +531,6 @@ left: 0; margin: auto; right: 0; - top: 0; transform-origin: top center; transition: transform 250ms cubic-bezier(0.4, 0.0, 1, 1) .4s; z-index: 2;
diff --git a/components/neterror/resources/offline.js b/components/neterror/resources/offline.js index e89c25d..f7235b3 100644 --- a/components/neterror/resources/offline.js +++ b/components/neterror/resources/offline.js
@@ -125,6 +125,7 @@ RESOURCE_TEMPLATE_ID: 'audio-resources', SPEED: 6, SPEED_DROP_COEFFICIENT: 3, + ARCADE_MODE_INITIAL_TOP_POSITION: 35, ARCADE_MODE_TOP_POSITION_PERCENT: 0.1 }; @@ -865,7 +866,8 @@ var scaledCanvasHeight = this.dimensions.HEIGHT * scale; // Positions the game container at 10% of the available vertical window // height minus the game container height. - var translateY = Math.max(0, (windowHeight - scaledCanvasHeight) * + var translateY = Math.max(0, (windowHeight - scaledCanvasHeight - + Runner.config.ARCADE_MODE_INITIAL_TOP_POSITION) * Runner.config.ARCADE_MODE_TOP_POSITION_PERCENT); this.containerEl.style.transform = 'scale(' + scale + ') translateY(' + translateY + 'px)';
diff --git a/components/password_manager/core/browser/password_form_metrics_recorder.cc b/components/password_manager/core/browser/password_form_metrics_recorder.cc index 497b5fa..fc0bfed 100644 --- a/components/password_manager/core/browser/password_form_metrics_recorder.cc +++ b/components/password_manager/core/browser/password_form_metrics_recorder.cc
@@ -237,6 +237,9 @@ GetHistogramSampleForSuppressedAccounts(best_match), kMaxSuppressedAccountStats); RecordUkmMetric("SuppressedAccount.Manual.SameOrganizationName", best_match); + + if (current_bubble_ != CurrentBubbleOfInterest::kNone) + RecordUIDismissalReason(metrics_util::NO_DIRECT_INTERACTION); } void PasswordFormMetricsRecorder::RecordPasswordBubbleShown( @@ -244,6 +247,7 @@ metrics_util::UIDisplayDisposition display_disposition) { if (credential_source_type == metrics_util::CredentialSourceType::kUnknown) return; + DCHECK_EQ(CurrentBubbleOfInterest::kNone, current_bubble_); BubbleTrigger automatic_trigger_type = credential_source_type == metrics_util::CredentialSourceType::kPasswordManager @@ -258,11 +262,13 @@ switch (display_disposition) { // New credential cases: case metrics_util::AUTOMATIC_WITH_PASSWORD_PENDING: + current_bubble_ = CurrentBubbleOfInterest::kSaveBubble; save_prompt_shown_ = true; RecordUkmMetric(kUkmSavingPromptTrigger, static_cast<int64_t>(automatic_trigger_type)); break; case metrics_util::MANUAL_WITH_PASSWORD_PENDING: + current_bubble_ = CurrentBubbleOfInterest::kSaveBubble; save_prompt_shown_ = true; RecordUkmMetric(kUkmSavingPromptTrigger, static_cast<int64_t>(manual_trigger_type)); @@ -270,11 +276,13 @@ // Update cases: case metrics_util::AUTOMATIC_WITH_PASSWORD_PENDING_UPDATE: + current_bubble_ = CurrentBubbleOfInterest::kUpdateBubble; update_prompt_shown_ = true; RecordUkmMetric(kUkmUpdatingPromptTrigger, static_cast<int64_t>(automatic_trigger_type)); break; case metrics_util::MANUAL_WITH_PASSWORD_PENDING_UPDATE: + current_bubble_ = CurrentBubbleOfInterest::kUpdateBubble; update_prompt_shown_ = true; RecordUkmMetric(kUkmUpdatingPromptTrigger, static_cast<int64_t>(manual_trigger_type)); @@ -298,11 +306,12 @@ void PasswordFormMetricsRecorder::RecordUIDismissalReason( metrics_util::UIDismissalReason ui_dismissal_reason) { - DCHECK(!(update_prompt_shown_ && save_prompt_shown_)); - if (!(update_prompt_shown_ || save_prompt_shown_)) + if (current_bubble_ != CurrentBubbleOfInterest::kUpdateBubble && + current_bubble_ != CurrentBubbleOfInterest::kSaveBubble) return; - const char* metric = update_prompt_shown_ ? kUkmUpdatingPromptInteraction - : kUkmSavingPromptInteraction; + const char* metric = current_bubble_ == CurrentBubbleOfInterest::kUpdateBubble + ? kUkmUpdatingPromptInteraction + : kUkmSavingPromptInteraction; switch (ui_dismissal_reason) { // Accepted by user. case metrics_util::CLICKED_SAVE: @@ -340,6 +349,8 @@ NOTREACHED(); break; } + + current_bubble_ = CurrentBubbleOfInterest::kNone; } void PasswordFormMetricsRecorder::RecordFillEvent(ManagerAutofillEvent event) {
diff --git a/components/password_manager/core/browser/password_form_metrics_recorder.h b/components/password_manager/core/browser/password_form_metrics_recorder.h index 9ea261a..00af1e6 100644 --- a/components/password_manager/core/browser/password_form_metrics_recorder.h +++ b/components/password_manager/core/browser/password_form_metrics_recorder.h
@@ -265,6 +265,17 @@ private: friend class base::RefCounted<PasswordFormMetricsRecorder>; + // Enum to track which password bubble is currently being displayed. + enum class CurrentBubbleOfInterest { + // This covers the cases that no password bubble is currently being + // displayed or the one displayed is none of the interesting cases. + kNone, + // The user is currently seeing a password save bubble. + kSaveBubble, + // The user is currently seeing a password update bubble. + kUpdateBubble, + }; + // Destructor reports a couple of UMA metrics as well as calls // RecordUkmMetric. ~PasswordFormMetricsRecorder(); @@ -309,6 +320,9 @@ // Whether this form has an auto generated password. bool has_generated_password_ = false; + // Tracks which bubble is currently being displayed to the user. + CurrentBubbleOfInterest current_bubble_ = CurrentBubbleOfInterest::kNone; + // Whether the user was shown a prompt to update a password. bool update_prompt_shown_ = false;
diff --git a/components/password_manager/core/browser/password_form_metrics_recorder_unittest.cc b/components/password_manager/core/browser/password_form_metrics_recorder_unittest.cc index 93f982c..6fdcd6b 100644 --- a/components/password_manager/core/browser/password_form_metrics_recorder_unittest.cc +++ b/components/password_manager/core/browser/password_form_metrics_recorder_unittest.cc
@@ -522,4 +522,47 @@ } } +// Verify that it is ok to open and close the password bubble more than once +// and still get accurate metrics. +TEST(PasswordFormMetricsRecorder, SequencesOfBubbles) { + using BubbleDismissalReason = + PasswordFormMetricsRecorder::BubbleDismissalReason; + using BubbleTrigger = PasswordFormMetricsRecorder::BubbleTrigger; + ukm::TestUkmRecorder test_ukm_recorder; + { + auto recorder = base::MakeRefCounted<PasswordFormMetricsRecorder>( + true /*is_main_frame_secure*/, + CreateUkmEntryBuilder(&test_ukm_recorder)); + // Open and confirm an automatically triggered saving prompt. + recorder->RecordPasswordBubbleShown( + metrics_util::CredentialSourceType::kPasswordManager, + metrics_util::AUTOMATIC_WITH_PASSWORD_PENDING); + recorder->RecordUIDismissalReason(metrics_util::CLICKED_SAVE); + // Open and confirm a manually triggered update prompt. + recorder->RecordPasswordBubbleShown( + metrics_util::CredentialSourceType::kPasswordManager, + metrics_util::MANUAL_WITH_PASSWORD_PENDING_UPDATE); + recorder->RecordUIDismissalReason(metrics_util::CLICKED_SAVE); + } + // Verify recorded UKM data. + const ukm::UkmSource* source = test_ukm_recorder.GetSourceForUrl(kTestUrl); + ASSERT_TRUE(source); + test_ukm_recorder.ExpectMetric( + *source, "PasswordForm", kUkmSavingPromptInteraction, + static_cast<int64_t>(BubbleDismissalReason::kAccepted)); + test_ukm_recorder.ExpectMetric( + *source, "PasswordForm", kUkmUpdatingPromptInteraction, + static_cast<int64_t>(BubbleDismissalReason::kAccepted)); + test_ukm_recorder.ExpectMetric(*source, "PasswordForm", + kUkmUpdatingPromptShown, 1); + test_ukm_recorder.ExpectMetric(*source, "PasswordForm", kUkmSavingPromptShown, + 1); + test_ukm_recorder.ExpectMetric( + *source, "PasswordForm", kUkmSavingPromptTrigger, + static_cast<int64_t>(BubbleTrigger::kPasswordManagerSuggestionAutomatic)); + test_ukm_recorder.ExpectMetric( + *source, "PasswordForm", kUkmUpdatingPromptTrigger, + static_cast<int64_t>(BubbleTrigger::kPasswordManagerSuggestionManual)); +} + } // namespace password_manager
diff --git a/components/safe_browsing/base_blocking_page.cc b/components/safe_browsing/base_blocking_page.cc index efecb26..6c16975 100644 --- a/components/safe_browsing/base_blocking_page.cc +++ b/components/safe_browsing/base_blocking_page.cc
@@ -104,7 +104,8 @@ BaseBlockingPage* blocking_page = new BaseBlockingPage( ui_manager, web_contents, entry ? entry->GetURL() : GURL(), unsafe_resources, - CreateControllerClient(web_contents, unsafe_resources, ui_manager), + CreateControllerClient(web_contents, unsafe_resources, ui_manager, + nullptr), CreateDefaultDisplayOptions(unsafe_resources)); blocking_page->Show(); } @@ -339,7 +340,8 @@ BaseBlockingPage::CreateControllerClient( content::WebContents* web_contents, const UnsafeResourceList& unsafe_resources, - BaseUIManager* ui_manager) { + BaseUIManager* ui_manager, + PrefService* pref_service) { history::HistoryService* history_service = ui_manager->history_service(web_contents); @@ -349,7 +351,7 @@ history_service); return base::MakeUnique<SecurityInterstitialControllerClient>( - web_contents, std::move(metrics_helper), nullptr, /* prefs */ + web_contents, std::move(metrics_helper), pref_service, ui_manager->app_locale(), ui_manager->default_safe_page()); }
diff --git a/components/safe_browsing/base_blocking_page.h b/components/safe_browsing/base_blocking_page.h index 1757d2e..837498b9 100644 --- a/components/safe_browsing/base_blocking_page.h +++ b/components/safe_browsing/base_blocking_page.h
@@ -119,7 +119,8 @@ security_interstitials::SecurityInterstitialControllerClient> CreateControllerClient(content::WebContents* web_contents, const UnsafeResourceList& unsafe_resources, - BaseUIManager* ui_manager); + BaseUIManager* ui_manager, + PrefService* pref_service); int GetHTMLTemplateId() override;
diff --git a/components/security_interstitials/core/controller_client.cc b/components/security_interstitials/core/controller_client.cc index b1ab274..e146d72 100644 --- a/components/security_interstitials/core/controller_client.cc +++ b/components/security_interstitials/core/controller_client.cc
@@ -35,6 +35,7 @@ } void ControllerClient::SetReportingPreference(bool report) { + DCHECK(GetPrefService()); GetPrefService()->SetBoolean(GetExtendedReportingPrefName(), report); metrics_helper_->RecordUserInteraction( report ? MetricsHelper::SET_EXTENDED_REPORTING_ENABLED
diff --git a/components/variations/BUILD.gn b/components/variations/BUILD.gn index 3fb8f8d1..7e2458ad 100644 --- a/components/variations/BUILD.gn +++ b/components/variations/BUILD.gn
@@ -111,6 +111,7 @@ ] deps = [ + "field_trial_config:field_trial_config", "//base/test:test_support", ] }
diff --git a/components/variations/field_trial_config/field_trial_util.cc b/components/variations/field_trial_config/field_trial_util.cc index b77180dab..761ba237 100644 --- a/components/variations/field_trial_config/field_trial_util.cc +++ b/components/variations/field_trial_config/field_trial_util.cc
@@ -21,7 +21,7 @@ namespace variations { namespace { -std::string EscapeValue(const std::string& value) { +std::string UnescapeValue(const std::string& value) { return net::UnescapeURLComponent( value, net::UnescapeRule::PATH_SEPARATORS | net::UnescapeRule::URL_SPECIAL_CHARS_EXCEPT_PATH_SEPARATORS); @@ -83,6 +83,12 @@ } // namespace +std::string EscapeValue(const std::string& value) { + // This needs to be the inverse of UnescapeValue in the anonymous namespace + // above. + return net::EscapeQueryParamValue(value, true /* use_plus */); +} + bool AssociateParamsFromString(const std::string& varations_string) { // Format: Trial1.Group1:k1/v1/k2/v2,Trial2.Group2:k1/v1/k2/v2 std::set<std::pair<std::string, std::string>> trial_groups; @@ -109,8 +115,8 @@ DLOG(ERROR) << "Param name and param value should be separated by '/'"; return false; } - std::string trial = EscapeValue(group_parts[0]); - std::string group = EscapeValue(group_parts[1]); + std::string trial = UnescapeValue(group_parts[0]); + std::string group = UnescapeValue(group_parts[1]); auto trial_group = std::make_pair(trial, group); if (trial_groups.find(trial_group) != trial_groups.end()) { DLOG(ERROR) << base::StringPrintf( @@ -121,8 +127,8 @@ trial_groups.insert(trial_group); std::map<std::string, std::string> params; for (size_t i = 0; i < key_values.size(); i += 2) { - std::string key = EscapeValue(key_values[i]); - std::string value = EscapeValue(key_values[i + 1]); + std::string key = UnescapeValue(key_values[i]); + std::string value = UnescapeValue(key_values[i + 1]); params[key] = value; } AssociateVariationParams(trial, group, params);
diff --git a/components/variations/field_trial_config/field_trial_util.h b/components/variations/field_trial_config/field_trial_util.h index e9487c4e..8bb44eded 100644 --- a/components/variations/field_trial_config/field_trial_util.h +++ b/components/variations/field_trial_config/field_trial_util.h
@@ -15,6 +15,10 @@ struct FieldTrialTestingConfig; +// Escapes the trial name, or parameter name, or parameter value in a way that +// makes it usable within variations::switches::kForceFieldTrialParams. +std::string EscapeValue(const std::string& value); + // Provides a mechanism to associate multiple set of params to multiple groups // with a formatted string specified from commandline. See // kForceFieldTrialParams in components/variations/variations_switches.cc for
diff --git a/components/variations/variations_params_manager.cc b/components/variations/variations_params_manager.cc index 27204b0c..be71186 100644 --- a/components/variations/variations_params_manager.cc +++ b/components/variations/variations_params_manager.cc
@@ -6,11 +6,14 @@ #include <utility> +#include "base/base_switches.h" #include "base/feature_list.h" #include "base/memory/ptr_util.h" #include "base/metrics/field_trial.h" #include "base/test/scoped_feature_list.h" +#include "components/variations/field_trial_config/field_trial_util.h" #include "components/variations/variations_associated_data.h" +#include "components/variations/variations_switches.h" namespace variations { namespace testing { @@ -91,5 +94,35 @@ field_trial_list_ = base::MakeUnique<base::FieldTrialList>(nullptr); } +// static +void VariationParamsManager::AppendVariationParams( + const std::string& trial_name, + const std::string& trial_group_name, + const std::map<std::string, std::string>& param_values, + base::CommandLine* command_line) { + // Register the trial group. + command_line->AppendSwitchASCII( + ::switches::kForceFieldTrials, + EscapeValue(trial_name) + "/" + EscapeValue(trial_group_name)); + + // Associate |param_values| with the trial group. + std::string params_arg = + EscapeValue(trial_name) + "." + EscapeValue(trial_group_name) + ":"; + bool first = true; + for (const auto& param : param_values) { + // Separate each |param|. + if (!first) + params_arg += "/"; + first = false; + + // Append each |param|. + const std::string& name = param.first; + const std::string& value = param.second; + params_arg += EscapeValue(name) + "/" + EscapeValue(value); + } + command_line->AppendSwitchASCII(variations::switches::kForceFieldTrialParams, + params_arg); +} + } // namespace testing } // namespace variations
diff --git a/components/variations/variations_params_manager.h b/components/variations/variations_params_manager.h index 6a65e18..2c61c52 100644 --- a/components/variations/variations_params_manager.h +++ b/components/variations/variations_params_manager.h
@@ -14,6 +14,7 @@ #include "base/metrics/field_trial.h" namespace base { +class CommandLine; class FieldTrialList; namespace test { @@ -70,6 +71,19 @@ // Clears all of the associated params. void ClearAllVariationParams(); + // Appends command line switches to |command_line| in a way that mimics + // SetVariationParams. + // + // This static method is useful in situations where using + // VariationParamsManager directly would have resulted in initializing + // FieldTrialList twice (once from ChromeBrowserMainParts::SetupFieldTrials + // and once from VariationParamsManager). + static void AppendVariationParams( + const std::string& trial_name, + const std::string& trial_group_name, + const std::map<std::string, std::string>& param_values, + base::CommandLine* command_line); + private: std::unique_ptr<base::FieldTrialList> field_trial_list_; std::unique_ptr<base::test::ScopedFeatureList> scoped_feature_list_;
diff --git a/components/viz/common/BUILD.gn b/components/viz/common/BUILD.gn index 8a9cd856..a0f0dc8 100644 --- a/components/viz/common/BUILD.gn +++ b/components/viz/common/BUILD.gn
@@ -67,6 +67,7 @@ "gl_helper_unittest.cc", "resources/buffer_to_texture_target_map_unittest.cc", "resources/platform_color_unittest.cc", + "surfaces/surface_sequence_generator_unittest.cc", "yuv_readback_unittest.cc", ]
diff --git a/cc/surfaces/surface_sequence_generator_unittest.cc b/components/viz/common/surfaces/surface_sequence_generator_unittest.cc similarity index 64% rename from cc/surfaces/surface_sequence_generator_unittest.cc rename to components/viz/common/surfaces/surface_sequence_generator_unittest.cc index 828a38a76..5d1913cc 100644 --- a/cc/surfaces/surface_sequence_generator_unittest.cc +++ b/components/viz/common/surfaces/surface_sequence_generator_unittest.cc
@@ -7,18 +7,18 @@ #include "components/viz/common/surfaces/surface_sequence.h" #include "testing/gtest/include/gtest/gtest.h" -namespace cc { +namespace viz { namespace { -static constexpr viz::FrameSinkId kArbitraryFrameSinkId(1, 1); +static constexpr FrameSinkId kArbitraryFrameSinkId(1, 1); TEST(SurfaceSequenceGeneratorTest, Basic) { - viz::SurfaceSequenceGenerator generator; + SurfaceSequenceGenerator generator; generator.set_frame_sink_id(kArbitraryFrameSinkId); - viz::SurfaceSequence sequence1 = generator.CreateSurfaceSequence(); - viz::SurfaceSequence sequence2 = generator.CreateSurfaceSequence(); + SurfaceSequence sequence1 = generator.CreateSurfaceSequence(); + SurfaceSequence sequence2 = generator.CreateSurfaceSequence(); EXPECT_NE(sequence1, sequence2); } } // namespace -} // namespace cc +} // namespace viz
diff --git a/components/viz/host/BUILD.gn b/components/viz/host/BUILD.gn index 7995512..e5d833e 100644 --- a/components/viz/host/BUILD.gn +++ b/components/viz/host/BUILD.gn
@@ -23,6 +23,10 @@ "//gpu/ipc/client", "//gpu/ipc/common", "//services/ui/gpu/interfaces", + + # TODO(kylechar): This is temporary and will be removed when all host to + # service communication is over Mojo. + "//components/viz/service", ] public_deps = [ @@ -50,5 +54,9 @@ "//services/ui/gpu/interfaces", "//testing/gmock", "//testing/gtest", + + # TODO(kylechar): This is temporary and will be removed when all host to + # service communication is over Mojo. + "//components/viz/service", ] }
diff --git a/components/viz/host/host_frame_sink_manager.cc b/components/viz/host/host_frame_sink_manager.cc index 6b4e26b..d6af712 100644 --- a/components/viz/host/host_frame_sink_manager.cc +++ b/components/viz/host/host_frame_sink_manager.cc
@@ -7,22 +7,38 @@ #include <utility> #include "base/sequenced_task_runner.h" -#include "cc/surfaces/surface_manager.h" #include "components/viz/common/surfaces/surface_info.h" +#include "components/viz/service/frame_sinks/compositor_frame_sink_support.h" +#include "components/viz/service/frame_sinks/compositor_frame_sink_support_client.h" +#include "components/viz/service/frame_sinks/frame_sink_manager.h" +#include "components/viz/service/frame_sinks/frame_sink_manager_impl.h" namespace viz { -HostFrameSinkManager::HostFrameSinkManager() : binding_(this) {} +HostFrameSinkManager::HostFrameSinkManager() + : binding_(this), weak_ptr_factory_(this) {} HostFrameSinkManager::~HostFrameSinkManager() = default; +void HostFrameSinkManager::SetLocalManager( + FrameSinkManagerImpl* frame_sink_manager_impl) { + DCHECK(!frame_sink_manager_ptr_); + frame_sink_manager_impl_ = frame_sink_manager_impl; + + frame_sink_manager_ = frame_sink_manager_impl; +} + void HostFrameSinkManager::BindAndSetManager( cc::mojom::FrameSinkManagerClientRequest request, scoped_refptr<base::SequencedTaskRunner> task_runner, cc::mojom::FrameSinkManagerPtr ptr) { + DCHECK(!frame_sink_manager_impl_); DCHECK(!binding_.is_bound()); + binding_.Bind(std::move(request), std::move(task_runner)); frame_sink_manager_ptr_ = std::move(ptr); + + frame_sink_manager_ = frame_sink_manager_ptr_.get(); } void HostFrameSinkManager::AddObserver(FrameSinkObserver* observer) { @@ -40,8 +56,9 @@ DCHECK_EQ(frame_sink_data_map_.count(frame_sink_id), 0u); FrameSinkData& data = frame_sink_data_map_[frame_sink_id]; + data.is_root = false; - frame_sink_manager_ptr_->CreateCompositorFrameSink( + frame_sink_manager_->CreateCompositorFrameSink( frame_sink_id, std::move(request), mojo::MakeRequest(&data.private_interface), std::move(client)); } @@ -62,9 +79,12 @@ void HostFrameSinkManager::RegisterFrameSinkHierarchy( const FrameSinkId& parent_frame_sink_id, const FrameSinkId& child_frame_sink_id) { - // Register and store the parent. - frame_sink_manager_ptr_->RegisterFrameSinkHierarchy(parent_frame_sink_id, - child_frame_sink_id); + DCHECK_EQ(frame_sink_data_map_.count(child_frame_sink_id), 1u); + + // Register and store the parent, either directly or over Mojo. + frame_sink_manager_->RegisterFrameSinkHierarchy(parent_frame_sink_id, + child_frame_sink_id); + frame_sink_data_map_[child_frame_sink_id].parent = parent_frame_sink_id; } @@ -77,15 +97,35 @@ FrameSinkData& data = iter->second; DCHECK_EQ(data.parent.value(), parent_frame_sink_id); - // Unregister and clear the stored parent. - frame_sink_manager_ptr_->UnregisterFrameSinkHierarchy(parent_frame_sink_id, - child_frame_sink_id); - data.parent.reset(); + // Unregister and clear the stored parent, either directly or over Mojo. + frame_sink_manager_->UnregisterFrameSinkHierarchy(parent_frame_sink_id, + child_frame_sink_id); - // If the client never called CreateCompositorFrameSink() then they won't - // call DestroyCompositorFrameSink() either, so cleanup map entry here. - if (!data.private_interface.is_bound()) - frame_sink_data_map_.erase(iter); + data.parent.reset(); +} + +std::unique_ptr<CompositorFrameSinkSupport> +HostFrameSinkManager::CreateCompositorFrameSinkSupport( + CompositorFrameSinkSupportClient* client, + const FrameSinkId& frame_sink_id, + bool is_root, + bool handles_frame_sink_id_invalidation, + bool needs_sync_points) { + DCHECK(frame_sink_manager_impl_); + DCHECK_EQ(frame_sink_data_map_.count(frame_sink_id), 0u); + + auto support = CompositorFrameSinkSupport::Create( + client, frame_sink_manager_impl_->frame_sink_manager(), frame_sink_id, + is_root, handles_frame_sink_id_invalidation, needs_sync_points); + support->SetDestructionCallback( + base::BindOnce(&HostFrameSinkManager::DestroyCompositorFrameSink, + weak_ptr_factory_.GetWeakPtr(), frame_sink_id)); + + FrameSinkData& data = frame_sink_data_map_[frame_sink_id]; + data.support = support.get(); + data.is_root = is_root; + + return support; } void HostFrameSinkManager::OnSurfaceCreated(const SurfaceInfo& surface_info) {
diff --git a/components/viz/host/host_frame_sink_manager.h b/components/viz/host/host_frame_sink_manager.h index ce09d0b5..db76c340 100644 --- a/components/viz/host/host_frame_sink_manager.h +++ b/components/viz/host/host_frame_sink_manager.h
@@ -9,12 +9,14 @@ #include "base/containers/flat_map.h" #include "base/macros.h" #include "base/memory/ref_counted.h" +#include "base/memory/weak_ptr.h" #include "base/observer_list.h" #include "base/optional.h" #include "cc/ipc/frame_sink_manager.mojom.h" #include "components/viz/common/surfaces/frame_sink_id.h" #include "components/viz/host/frame_sink_observer.h" #include "components/viz/host/viz_host_export.h" +#include "components/viz/service/frame_sinks/compositor_frame_sink_support_manager.h" #include "mojo/public/cpp/bindings/binding.h" namespace base { @@ -23,19 +25,30 @@ namespace cc { class SurfaceInfo; -class SurfaceManager; } // namespace cc namespace viz { +class CompositorFrameSinkSupport; +class CompositorFrameSinkSupportClient; +class FrameSinkManagerImpl; + +namespace test { +class HostFrameSinkManagerTest; +} + // Browser side wrapper of mojom::FrameSinkManager, to be used from the // UI thread. Manages frame sinks and is intended to replace SurfaceManager. class VIZ_HOST_EXPORT HostFrameSinkManager - : NON_EXPORTED_BASE(cc::mojom::FrameSinkManagerClient) { + : public NON_EXPORTED_BASE(cc::mojom::FrameSinkManagerClient), + public NON_EXPORTED_BASE(CompositorFrameSinkSupportManager) { public: HostFrameSinkManager(); ~HostFrameSinkManager() override; + // Sets a local FrameSinkManagerImpl instance and connects directly to it. + void SetLocalManager(FrameSinkManagerImpl* frame_sink_manager_impl); + // Binds |this| as a FrameSinkManagerClient for |request| on |task_runner|. On // Mac |task_runner| will be the resize helper task runner. May only be called // once. @@ -70,21 +83,38 @@ void UnregisterFrameSinkHierarchy(const FrameSinkId& parent_frame_sink_id, const FrameSinkId& child_frame_sink_id); + // CompositorFrameSinkSupportManager: + std::unique_ptr<CompositorFrameSinkSupport> CreateCompositorFrameSinkSupport( + CompositorFrameSinkSupportClient* client, + const FrameSinkId& frame_sink_id, + bool is_root, + bool handles_frame_sink_id_invalidation, + bool needs_sync_points) override; + private: + friend class test::HostFrameSinkManagerTest; + struct FrameSinkData { FrameSinkData(); FrameSinkData(FrameSinkData&& other); ~FrameSinkData(); FrameSinkData& operator=(FrameSinkData&& other); + // If the frame sink is a root that corresponds to a Display. + bool is_root = false; + // The FrameSinkId registered as the parent in the BeginFrame hierarchy. // This mirrors state in viz. base::Optional<FrameSinkId> parent; // The private interface that gives the host control over the - // CompositorFrameSink connection between the client and viz. + // CompositorFrameSink connection between the client and viz. This will be + // unbound if not using Mojo. cc::mojom::CompositorFrameSinkPrivatePtr private_interface; + // This will be null if using Mojo. + CompositorFrameSinkSupport* support = nullptr; + private: DISALLOW_COPY_AND_ASSIGN(FrameSinkData); }; @@ -93,18 +123,31 @@ void OnSurfaceCreated(const SurfaceInfo& surface_info) override; void OnClientConnectionClosed(const FrameSinkId& frame_sink_id) override; - // Mojo connection to the FrameSinkManager. + // This will point to |frame_sink_manager_ptr_| if using Mojo or + // |frame_sink_manager_impl_| if directly connected. Use this to make function + // calls. + cc::mojom::FrameSinkManager* frame_sink_manager_ = nullptr; + + // Mojo connection to the FrameSinkManager. If this is bound then + // |frame_sink_manager_impl_| must be null. cc::mojom::FrameSinkManagerPtr frame_sink_manager_ptr_; // Mojo connection back from the FrameSinkManager. mojo::Binding<cc::mojom::FrameSinkManagerClient> binding_; + // A direct connection to FrameSinkManagerImpl. If this is set then + // |frame_sink_manager_ptr_| must be unbound. For use in browser process only, + // viz process should not set this. + FrameSinkManagerImpl* frame_sink_manager_impl_ = nullptr; + // Per CompositorFrameSink data. base::flat_map<FrameSinkId, FrameSinkData> frame_sink_data_map_; // Local observers to that receive OnSurfaceCreated() messages from IPC. base::ObserverList<FrameSinkObserver> observers_; + base::WeakPtrFactory<HostFrameSinkManager> weak_ptr_factory_; + DISALLOW_COPY_AND_ASSIGN(HostFrameSinkManager); };
diff --git a/components/viz/host/host_frame_sink_manager_unittests.cc b/components/viz/host/host_frame_sink_manager_unittests.cc index 1717515d..c4c6cbe6 100644 --- a/components/viz/host/host_frame_sink_manager_unittests.cc +++ b/components/viz/host/host_frame_sink_manager_unittests.cc
@@ -12,6 +12,8 @@ #include "base/threading/sequenced_task_runner_handle.h" #include "cc/ipc/frame_sink_manager.mojom.h" #include "components/viz/common/surfaces/frame_sink_id.h" +#include "components/viz/service/frame_sinks/compositor_frame_sink_support.h" +#include "components/viz/service/frame_sinks/frame_sink_manager_impl.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -20,7 +22,7 @@ namespace { constexpr FrameSinkId kFrameSinkId1(1, 1); -constexpr FrameSinkId kFrameSinkId2(1, 1); +constexpr FrameSinkId kFrameSinkId2(2, 1); ACTION_P(InvokeClosure, closure) { closure.Run(); @@ -53,42 +55,21 @@ }; // A mock implementation of mojom::FrameSinkManager. -class MockFrameSinkManagerImpl : public cc::mojom::FrameSinkManager { +class MockFrameSinkManagerImpl : public FrameSinkManagerImpl { public: - MockFrameSinkManagerImpl() : binding_(this) {} + MockFrameSinkManagerImpl() : FrameSinkManagerImpl(false, nullptr) {} ~MockFrameSinkManagerImpl() override = default; - void BindAndSetClient(cc::mojom::FrameSinkManagerRequest request, - cc::mojom::FrameSinkManagerClientPtr client) { - binding_.Bind(std::move(request)); - client_ = std::move(client); - } - // cc::mojom::FrameSinkManager: - // TODO(kylechar): See if we can mock functions with InterfacePtrs parameters. - void CreateRootCompositorFrameSink( - const FrameSinkId& frame_sink_id, - gpu::SurfaceHandle surface_handle, - cc::mojom::CompositorFrameSinkAssociatedRequest request, - cc::mojom::CompositorFrameSinkPrivateRequest private_request, - cc::mojom::CompositorFrameSinkClientPtr client, - cc::mojom::DisplayPrivateAssociatedRequest display_private_request) - override {} - void CreateCompositorFrameSink( - const FrameSinkId& frame_sink_id, - cc::mojom::CompositorFrameSinkRequest request, - cc::mojom::CompositorFrameSinkPrivateRequest private_request, - cc::mojom::CompositorFrameSinkClientPtr client) override {} MOCK_METHOD2(RegisterFrameSinkHierarchy, void(const FrameSinkId& parent, const FrameSinkId& child)); MOCK_METHOD2(UnregisterFrameSinkHierarchy, void(const FrameSinkId& parent, const FrameSinkId& child)); MOCK_METHOD1(DropTemporaryReference, void(const SurfaceId& surface_id)); - private: - mojo::Binding<cc::mojom::FrameSinkManager> binding_; - cc::mojom::FrameSinkManagerClientPtr client_; + // TODO(kylechar): See if we can mock functions with InterfacePtr parameters. + private: DISALLOW_COPY_AND_ASSIGN(MockFrameSinkManagerImpl); }; @@ -103,23 +84,17 @@ MockFrameSinkManagerImpl& manager_impl() { return *manager_impl_; } + bool FrameSinkIdExists(const FrameSinkId& frame_sink_id) { + return host_manager_->frame_sink_data_map_.count(frame_sink_id) > 0; + } + // testing::Test: void SetUp() override { manager_impl_ = base::MakeUnique<MockFrameSinkManagerImpl>(); host_manager_ = base::MakeUnique<HostFrameSinkManager>(); - // Connect HostFrameSinkManager and FrameSinkManagerImpl. - cc::mojom::FrameSinkManagerClientPtr host_mojo; - cc::mojom::FrameSinkManagerClientRequest host_mojo_request = - mojo::MakeRequest(&host_mojo); - cc::mojom::FrameSinkManagerPtr manager_mojo; - cc::mojom::FrameSinkManagerRequest manager_impl_request = - mojo::MakeRequest(&manager_mojo); - manager_impl_->BindAndSetClient(std::move(manager_impl_request), - std::move(host_mojo)); - host_manager_->BindAndSetManager(std::move(host_mojo_request), - base::SequencedTaskRunnerHandle::Get(), - std::move(manager_mojo)); + manager_impl_->SetLocalClient(host_manager_.get()); + host_manager_->SetLocalManager(manager_impl_.get()); } private: @@ -132,7 +107,13 @@ // Verify that when destroying a CompositorFrameSink with registered FrameSink // hierarchy, the hierarchy is automatically unregistered. TEST_F(HostFrameSinkManagerTest, UnregisterHierarchyOnDestroy) { - base::RunLoop run_loop; + // Register is called explicitly. + EXPECT_CALL(manager_impl(), + RegisterFrameSinkHierarchy(kFrameSinkId2, kFrameSinkId1)); + + // Unregister should be called when DestroyCompositorFrameSink() is called. + EXPECT_CALL(manager_impl(), + UnregisterFrameSinkHierarchy(kFrameSinkId2, kFrameSinkId1)); cc::mojom::CompositorFrameSinkPtr frame_sink; StubCompositorFrameSinkClient frame_sink_client; @@ -141,17 +122,19 @@ frame_sink_client.GetInterfacePtr()); host_manager().RegisterFrameSinkHierarchy(kFrameSinkId2, kFrameSinkId1); host_manager().DestroyCompositorFrameSink(kFrameSinkId1); +} - // Register is called explicitly. - EXPECT_CALL(manager_impl(), - RegisterFrameSinkHierarchy(kFrameSinkId2, kFrameSinkId1)); +// Checks that creating a CompositorFrameSinkSupport registers it and destroying +// the CompositorFrameSinkSupport unregisters it. +TEST_F(HostFrameSinkManagerTest, CreateDestroyCompositorFrameSinkSupport) { + auto support = host_manager().CreateCompositorFrameSinkSupport( + nullptr /* client */, kFrameSinkId1, true /* is_root */, + true /* handles_frame_sink_id_invalidation */, + false /* needs_sync_points */); + EXPECT_TRUE(FrameSinkIdExists(support->frame_sink_id())); - // Unregister should be called when DestroyCompositorFrameSink() is called. - EXPECT_CALL(manager_impl(), - UnregisterFrameSinkHierarchy(kFrameSinkId2, kFrameSinkId1)) - .WillOnce(InvokeClosure(run_loop.QuitClosure())); - - run_loop.Run(); + support.reset(); + EXPECT_FALSE(FrameSinkIdExists(support->frame_sink_id())); } } // namespace test
diff --git a/components/viz/service/BUILD.gn b/components/viz/service/BUILD.gn index 5d8e588..81c6075f 100644 --- a/components/viz/service/BUILD.gn +++ b/components/viz/service/BUILD.gn
@@ -34,6 +34,7 @@ "frame_sinks/compositor_frame_sink_support.cc", "frame_sinks/compositor_frame_sink_support.h", "frame_sinks/compositor_frame_sink_support_client.h", + "frame_sinks/compositor_frame_sink_support_manager.h", "frame_sinks/direct_layer_tree_frame_sink.cc", "frame_sinks/direct_layer_tree_frame_sink.h", "frame_sinks/frame_eviction_manager.cc",
diff --git a/components/viz/service/frame_sinks/compositor_frame_sink_support.cc b/components/viz/service/frame_sinks/compositor_frame_sink_support.cc index 70ee3f77..7863532 100644 --- a/components/viz/service/frame_sinks/compositor_frame_sink_support.cc +++ b/components/viz/service/frame_sinks/compositor_frame_sink_support.cc
@@ -35,6 +35,9 @@ } CompositorFrameSinkSupport::~CompositorFrameSinkSupport() { + if (!destruction_callback_.is_null()) + std::move(destruction_callback_).Run(); + // Unregister |this| as a cc::BeginFrameObserver so that the // cc::BeginFrameSource does not call into |this| after it's deleted. SetNeedsBeginFrame(false); @@ -53,6 +56,11 @@ frame_sink_manager_->InvalidateFrameSinkId(frame_sink_id_); } +void CompositorFrameSinkSupport::SetDestructionCallback( + base::OnceCallback<void()> callback) { + destruction_callback_ = std::move(callback); +} + void CompositorFrameSinkSupport::OnSurfaceActivated(cc::Surface* surface) { DCHECK(surface->HasActiveFrame()); const cc::CompositorFrame& frame = surface->GetActiveFrame();
diff --git a/components/viz/service/frame_sinks/compositor_frame_sink_support.h b/components/viz/service/frame_sinks/compositor_frame_sink_support.h index 7c467c92..b77fa99 100644 --- a/components/viz/service/frame_sinks/compositor_frame_sink_support.h +++ b/components/viz/service/frame_sinks/compositor_frame_sink_support.h
@@ -9,6 +9,7 @@ #include <unordered_set> #include <vector> +#include "base/callback.h" #include "base/compiler_specific.h" #include "base/memory/weak_ptr.h" #include "cc/output/compositor_frame.h" @@ -52,6 +53,8 @@ FrameSinkManager* frame_sink_manager() { return frame_sink_manager_; } cc::SurfaceManager* surface_manager() { return surface_manager_; } + void SetDestructionCallback(base::OnceCallback<void()> callback); + // SurfaceClient implementation. void OnSurfaceActivated(cc::Surface* surface) override; void RefResources( @@ -157,6 +160,9 @@ // goes away and we can remove this bool. const bool handles_frame_sink_id_invalidation_; + // A callback that will be run at the start of the destructor if set. + base::OnceCallback<void()> destruction_callback_; + base::WeakPtrFactory<CompositorFrameSinkSupport> weak_factory_; DISALLOW_COPY_AND_ASSIGN(CompositorFrameSinkSupport);
diff --git a/components/viz/service/frame_sinks/compositor_frame_sink_support_manager.h b/components/viz/service/frame_sinks/compositor_frame_sink_support_manager.h new file mode 100644 index 0000000..91a4e80 --- /dev/null +++ b/components/viz/service/frame_sinks/compositor_frame_sink_support_manager.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 COMPONENTS_VIZ_SERVICE_FRAME_SINKS_COMPOSITOR_FRAME_SINK_SUPPORT_MANAGER_H_ +#define COMPONENTS_VIZ_SERVICE_FRAME_SINKS_COMPOSITOR_FRAME_SINK_SUPPORT_MANAGER_H_ + +#include <memory> + +#include "base/callback.h" + +namespace viz { + +class CompositorFrameSinkSupport; +class CompositorFrameSinkSupportClient; +class FrameSinkId; + +// This inteface provides a way for DirectLayerTreeFrameSink to create a +// CompositorFrameSinkSupport. +class CompositorFrameSinkSupportManager { + public: + virtual std::unique_ptr<CompositorFrameSinkSupport> + CreateCompositorFrameSinkSupport(CompositorFrameSinkSupportClient* client, + const FrameSinkId& frame_sink_id, + bool is_root, + bool handles_frame_sink_id_invalidation, + bool needs_sync_points) = 0; + + protected: + virtual ~CompositorFrameSinkSupportManager() {} +}; + +} // namespace viz + +#endif // COMPONENTS_VIZ_SERVICE_FRAME_SINKS_COMPOSITOR_FRAME_SINK_SUPPORT_MANAGER_H_
diff --git a/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.cc b/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.cc index 8d5c797..4c6b389 100644 --- a/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.cc +++ b/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.cc
@@ -11,12 +11,14 @@ #include "components/viz/common/surfaces/frame_sink_id.h" #include "components/viz/common/surfaces/local_surface_id_allocator.h" #include "components/viz/service/display/display.h" +#include "components/viz/service/frame_sinks/compositor_frame_sink_support_manager.h" #include "components/viz/service/frame_sinks/frame_sink_manager.h" namespace viz { DirectLayerTreeFrameSink::DirectLayerTreeFrameSink( const FrameSinkId& frame_sink_id, + CompositorFrameSinkSupportManager* support_manager, FrameSinkManager* frame_sink_manager, Display* display, scoped_refptr<cc::ContextProvider> context_provider, @@ -28,6 +30,7 @@ gpu_memory_buffer_manager, shared_bitmap_manager), frame_sink_id_(frame_sink_id), + support_manager_(support_manager), frame_sink_manager_(frame_sink_manager), display_(display) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); @@ -39,11 +42,13 @@ DirectLayerTreeFrameSink::DirectLayerTreeFrameSink( const FrameSinkId& frame_sink_id, + CompositorFrameSinkSupportManager* support_manager, FrameSinkManager* frame_sink_manager, Display* display, scoped_refptr<cc::VulkanContextProvider> vulkan_context_provider) : LayerTreeFrameSink(std::move(vulkan_context_provider)), frame_sink_id_(frame_sink_id), + support_manager_(support_manager), frame_sink_manager_(frame_sink_manager), display_(display) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); @@ -69,9 +74,8 @@ constexpr bool is_root = true; constexpr bool handles_frame_sink_id_invalidation = false; - support_ = CompositorFrameSinkSupport::Create( - this, frame_sink_manager_, frame_sink_id_, is_root, - handles_frame_sink_id_invalidation, + support_ = support_manager_->CreateCompositorFrameSinkSupport( + this, frame_sink_id_, is_root, handles_frame_sink_id_invalidation, capabilities_.delegated_sync_points_required); begin_frame_source_ = base::MakeUnique<cc::ExternalBeginFrameSource>(this); client_->SetBeginFrameSource(begin_frame_source_.get());
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 ab38247..30391ff 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
@@ -21,6 +21,7 @@ } // namespace cc namespace viz { +class CompositorFrameSinkSupportManager; class Display; // This class submits compositor frames to an in-process Display, with the @@ -35,6 +36,7 @@ // outlive this class. DirectLayerTreeFrameSink( const FrameSinkId& frame_sink_id, + CompositorFrameSinkSupportManager* support_manager, FrameSinkManager* frame_sink_manager, Display* display, scoped_refptr<cc::ContextProvider> context_provider, @@ -43,6 +45,7 @@ SharedBitmapManager* shared_bitmap_manager); DirectLayerTreeFrameSink( const FrameSinkId& frame_sink_id, + CompositorFrameSinkSupportManager* support_manager, FrameSinkManager* frame_sink_manager, Display* display, scoped_refptr<cc::VulkanContextProvider> vulkan_context_provider); @@ -81,6 +84,7 @@ const FrameSinkId frame_sink_id_; LocalSurfaceId local_surface_id_; + CompositorFrameSinkSupportManager* const support_manager_; FrameSinkManager* frame_sink_manager_; LocalSurfaceIdAllocator local_surface_id_allocator_; Display* display_;
diff --git a/components/viz/service/frame_sinks/direct_layer_tree_frame_sink_unittest.cc b/components/viz/service/frame_sinks/direct_layer_tree_frame_sink_unittest.cc index 6d96600..fc5fd11d 100644 --- a/components/viz/service/frame_sinks/direct_layer_tree_frame_sink_unittest.cc +++ b/components/viz/service/frame_sinks/direct_layer_tree_frame_sink_unittest.cc
@@ -23,6 +23,7 @@ #include "components/viz/common/surfaces/local_surface_id_allocator.h" #include "components/viz/service/display/display.h" #include "components/viz/service/display/display_scheduler.h" +#include "components/viz/service/frame_sinks/compositor_frame_sink_support_manager.h" #include "components/viz/service/frame_sinks/frame_sink_manager.h" #include "testing/gtest/include/gtest/gtest.h" @@ -38,6 +39,31 @@ CompositorFrameSinkSupport* support() const { return support_.get(); } }; +class TestCompositorFrameSinkSupportManager + : public CompositorFrameSinkSupportManager { + public: + explicit TestCompositorFrameSinkSupportManager( + FrameSinkManager* frame_sink_manager) + : frame_sink_manager_(frame_sink_manager) {} + ~TestCompositorFrameSinkSupportManager() override = default; + + std::unique_ptr<CompositorFrameSinkSupport> CreateCompositorFrameSinkSupport( + CompositorFrameSinkSupportClient* client, + const FrameSinkId& frame_sink_id, + bool is_root, + bool handles_frame_sink_id_invalidation, + bool needs_sync_points) override { + return CompositorFrameSinkSupport::Create( + client, frame_sink_manager_, frame_sink_id, is_root, + handles_frame_sink_id_invalidation, needs_sync_points); + } + + private: + FrameSinkManager* const frame_sink_manager_; + + DISALLOW_COPY_AND_ASSIGN(TestCompositorFrameSinkSupportManager); +}; + class DirectLayerTreeFrameSinkTest : public testing::Test { public: DirectLayerTreeFrameSinkTest() @@ -45,6 +71,7 @@ task_runner_(new cc::OrderedSimpleTaskRunner(now_src_.get(), true)), display_size_(1920, 1080), display_rect_(display_size_), + support_manager_(&frame_sink_manager_), context_provider_(cc::TestContextProvider::Create()) { frame_sink_manager_.RegisterFrameSinkId(kArbitraryFrameSinkId); @@ -64,8 +91,8 @@ std::move(scheduler), base::MakeUnique<cc::TextureMailboxDeleter>(task_runner_.get()))); layer_tree_frame_sink_ = base::MakeUnique<TestDirectLayerTreeFrameSink>( - kArbitraryFrameSinkId, &frame_sink_manager_, display_.get(), - context_provider_, nullptr, &gpu_memory_buffer_manager_, + kArbitraryFrameSinkId, &support_manager_, &frame_sink_manager_, + display_.get(), context_provider_, nullptr, &gpu_memory_buffer_manager_, &bitmap_manager_); layer_tree_frame_sink_->BindToClient(&layer_tree_frame_sink_client_); @@ -107,6 +134,7 @@ const gfx::Size display_size_; const gfx::Rect display_rect_; FrameSinkManager frame_sink_manager_; + TestCompositorFrameSinkSupportManager support_manager_; cc::TestSharedBitmapManager bitmap_manager_; cc::TestGpuMemoryBufferManager gpu_memory_buffer_manager_;
diff --git a/components/viz/service/frame_sinks/frame_sink_manager_impl.cc b/components/viz/service/frame_sinks/frame_sink_manager_impl.cc index 7b3de665..61a6ceb 100644 --- a/components/viz/service/frame_sinks/frame_sink_manager_impl.cc +++ b/components/viz/service/frame_sinks/frame_sink_manager_impl.cc
@@ -37,9 +37,19 @@ cc::mojom::FrameSinkManagerRequest request, scoped_refptr<base::SequencedTaskRunner> task_runner, cc::mojom::FrameSinkManagerClientPtr client) { + DCHECK(!client_); DCHECK(!binding_.is_bound()); binding_.Bind(std::move(request), std::move(task_runner)); - client_ = std::move(client); + client_ptr_ = std::move(client); + + client_ = client_ptr_.get(); +} + +void FrameSinkManagerImpl::SetLocalClient( + cc::mojom::FrameSinkManagerClient* client) { + DCHECK(!client_ptr_); + + client_ = client; } void FrameSinkManagerImpl::CreateRootCompositorFrameSink(
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 b97f905d..5dd3b25 100644 --- a/components/viz/service/frame_sinks/frame_sink_manager_impl.h +++ b/components/viz/service/frame_sinks/frame_sink_manager_impl.h
@@ -56,6 +56,9 @@ scoped_refptr<base::SequencedTaskRunner> task_runner, cc::mojom::FrameSinkManagerClientPtr client); + // Sets up a direction connection to |client| without using Mojo. + void SetLocalClient(cc::mojom::FrameSinkManagerClient* client); + // cc::mojom::FrameSinkManager implementation: void CreateRootCompositorFrameSink( const FrameSinkId& frame_sink_id, @@ -115,7 +118,11 @@ THREAD_CHECKER(thread_checker_); - cc::mojom::FrameSinkManagerClientPtr client_; + // This will point to |client_ptr_| if using Mojo or a provided client if + // directly connected. Use this to make function calls. + cc::mojom::FrameSinkManagerClient* client_ = nullptr; + + cc::mojom::FrameSinkManagerClientPtr client_ptr_; mojo::Binding<cc::mojom::FrameSinkManager> binding_; DISALLOW_COPY_AND_ASSIGN(FrameSinkManagerImpl);
diff --git a/content/DEPS b/content/DEPS index fd8706d..b34a6f4 100644 --- a/content/DEPS +++ b/content/DEPS
@@ -118,10 +118,20 @@ "+jni", ] -# content -> content/shell dependency is not allowed, except for browser tests. specific_include_rules = { ".*_browsertest[a-z_]*\.(cc|h)": [ + # content -> content/shell dependency is disallowed, except browser tests. "+content/shell/browser", "+content/shell/common", + + # components/variations/variations_params_manager.h is allowed from tests + # (it is part of //components/variations:test_support target). + "+components/variations/variations_params_manager.h", + ], + + "test_utils\.cc": [ + # components/variations/variations_params_manager.h is allowed from tests + # (it is part of //components/variations:test_support target). + "+components/variations/variations_params_manager.h", ], }
diff --git a/content/browser/browser_associated_interface_unittest.cc b/content/browser/browser_associated_interface_unittest.cc index d653010e..504474e 100644 --- a/content/browser/browser_associated_interface_unittest.cc +++ b/content/browser/browser_associated_interface_unittest.cc
@@ -92,6 +92,12 @@ return true; } + void OnFilterRemoved() override { + // Check that the bindings are cleared by + // BrowserAssociatedInterface::ClearBindings() callbacks. + EXPECT_FALSE(internal_state_->bindings_.get()); + } + // mojom::BrowserAssociatedInterfaceTestDriver: void ExpectString(const std::string& expected) override { next_expected_string_ = expected;
diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc index c2db985f..5d8124c 100644 --- a/content/browser/browser_main_loop.cc +++ b/content/browser/browser_main_loop.cc
@@ -1471,9 +1471,8 @@ // TODO(danakj): Don't make a FrameSinkManagerImpl when display is in the // Gpu process, instead get the mojo pointer from the Gpu process. - surface_utils::ConnectWithInProcessFrameSinkManager( - host_frame_sink_manager_.get(), frame_sink_manager_impl_.get(), - GetResizeTaskRunner()); + surface_utils::ConnectWithLocalFrameSinkManager( + host_frame_sink_manager_.get(), frame_sink_manager_impl_.get()); } #endif
diff --git a/content/browser/compositor/gpu_process_transport_factory.cc b/content/browser/compositor/gpu_process_transport_factory.cc index c12b2aeb..2e19825 100644 --- a/content/browser/compositor/gpu_process_transport_factory.cc +++ b/content/browser/compositor/gpu_process_transport_factory.cc
@@ -619,13 +619,13 @@ auto layer_tree_frame_sink = vulkan_context_provider ? base::MakeUnique<viz::DirectLayerTreeFrameSink>( - compositor->frame_sink_id(), GetFrameSinkManager(), - data->display.get(), + compositor->frame_sink_id(), GetHostFrameSinkManager(), + GetFrameSinkManager(), data->display.get(), static_cast<scoped_refptr<cc::VulkanContextProvider>>( vulkan_context_provider)) : base::MakeUnique<viz::DirectLayerTreeFrameSink>( - compositor->frame_sink_id(), GetFrameSinkManager(), - data->display.get(), context_provider, + compositor->frame_sink_id(), GetHostFrameSinkManager(), + GetFrameSinkManager(), data->display.get(), context_provider, shared_worker_context_provider_, GetGpuMemoryBufferManager(), viz::ServerSharedBitmapManager::current()); data->display->Resize(compositor->size());
diff --git a/content/browser/compositor/surface_utils.cc b/content/browser/compositor/surface_utils.cc index ee1d844..e70b74fe 100644 --- a/content/browser/compositor/surface_utils.cc +++ b/content/browser/compositor/surface_utils.cc
@@ -169,7 +169,7 @@ return CompositorImpl::GetFrameSinkManager(); #else ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); - if (factory == NULL) + if (!factory) return nullptr; return factory->GetContextFactoryPrivate()->GetFrameSinkManager(); #endif @@ -179,7 +179,10 @@ #if defined(OS_ANDROID) return CompositorImpl::GetHostFrameSinkManager(); #else - return BrowserMainLoop::GetInstance()->host_frame_sink_manager(); + ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); + if (!factory) + return nullptr; + return factory->GetContextFactoryPrivate()->GetHostFrameSinkManager(); #endif } @@ -237,6 +240,13 @@ std::move(manager_mojo)); } +void ConnectWithLocalFrameSinkManager( + viz::HostFrameSinkManager* host_frame_sink_manager, + viz::FrameSinkManagerImpl* frame_sink_manager_impl) { + host_frame_sink_manager->SetLocalManager(frame_sink_manager_impl); + frame_sink_manager_impl->SetLocalClient(host_frame_sink_manager); +} + } // namespace surface_utils } // namespace content
diff --git a/content/browser/compositor/surface_utils.h b/content/browser/compositor/surface_utils.h index 1662845..997edaf6 100644 --- a/content/browser/compositor/surface_utils.h +++ b/content/browser/compositor/surface_utils.h
@@ -44,9 +44,15 @@ namespace surface_utils { +// Directly connects HostFrameSinkManager to FrameSinkManagerImpl without Mojo. +CONTENT_EXPORT void ConnectWithLocalFrameSinkManager( + viz::HostFrameSinkManager* host_frame_sink_manager, + viz::FrameSinkManagerImpl* frame_sink_manager_impl); + +// Connects HostFrameSinkManager to FrameSinkManagerImpl using in process Mojo. CONTENT_EXPORT void ConnectWithInProcessFrameSinkManager( - viz::HostFrameSinkManager* host, - viz::FrameSinkManagerImpl* manager, + viz::HostFrameSinkManager* host_frame_sink_manager, + viz::FrameSinkManagerImpl* frame_sink_manager_impl, scoped_refptr<base::SequencedTaskRunner> task_runner); } // namespace surface_utils
diff --git a/content/browser/compositor/test/no_transport_image_transport_factory.cc b/content/browser/compositor/test/no_transport_image_transport_factory.cc index 2d1ac5e0..cc12f63 100644 --- a/content/browser/compositor/test/no_transport_image_transport_factory.cc +++ b/content/browser/compositor/test/no_transport_image_transport_factory.cc
@@ -22,9 +22,8 @@ : frame_sink_manager_(false /* use surface references */, nullptr), context_factory_(&host_frame_sink_manager_, frame_sink_manager_.frame_sink_manager()) { - surface_utils::ConnectWithInProcessFrameSinkManager( - &host_frame_sink_manager_, &frame_sink_manager_, - base::ThreadTaskRunnerHandle::Get()); + surface_utils::ConnectWithLocalFrameSinkManager(&host_frame_sink_manager_, + &frame_sink_manager_); // The context factory created here is for unit tests, thus using a higher // refresh rate to spend less time waiting for BeginFrames.
diff --git a/content/browser/frame_host/render_widget_host_view_child_frame.cc b/content/browser/frame_host/render_widget_host_view_child_frame.cc index 804d5ef..7e78825 100644 --- a/content/browser/frame_host/render_widget_host_view_child_frame.cc +++ b/content/browser/frame_host/render_widget_host_view_child_frame.cc
@@ -823,7 +823,7 @@ viz::SurfaceId RenderWidgetHostViewChildFrame::SurfaceIdForTesting() const { return viz::SurfaceId(frame_sink_id_, local_surface_id_); -}; +} void RenderWidgetHostViewChildFrame::CreateCompositorFrameSinkSupport() { if (service_manager::ServiceManagerIsRemote()) @@ -833,9 +833,9 @@ constexpr bool is_root = false; constexpr bool handles_frame_sink_id_invalidation = false; constexpr bool needs_sync_points = true; - support_ = viz::CompositorFrameSinkSupport::Create( - this, GetFrameSinkManager(), frame_sink_id_, is_root, - handles_frame_sink_id_invalidation, needs_sync_points); + support_ = GetHostFrameSinkManager()->CreateCompositorFrameSinkSupport( + this, frame_sink_id_, is_root, handles_frame_sink_id_invalidation, + needs_sync_points); if (parent_frame_sink_id_.is_valid()) { GetFrameSinkManager()->RegisterFrameSinkHierarchy(parent_frame_sink_id_, frame_sink_id_);
diff --git a/content/browser/memory/DEPS b/content/browser/memory/DEPS deleted file mode 100644 index 80f6f90..0000000 --- a/content/browser/memory/DEPS +++ /dev/null
@@ -1,3 +0,0 @@ -include_rules = [ - "+components/variations", -]
diff --git a/content/browser/memory/memory_condition_observer.cc b/content/browser/memory/memory_condition_observer.cc index a1ae7adc..e80d4b36 100644 --- a/content/browser/memory/memory_condition_observer.cc +++ b/content/browser/memory/memory_condition_observer.cc
@@ -6,7 +6,6 @@ #include "base/metrics/histogram_macros.h" #include "base/strings/string_number_conversions.h" -#include "components/variations/variations_associated_data.h" #include "content/browser/memory/memory_monitor.h" namespace content {
diff --git a/content/browser/renderer_host/DEPS b/content/browser/renderer_host/DEPS index ab29198..ecc46881 100644 --- a/content/browser/renderer_host/DEPS +++ b/content/browser/renderer_host/DEPS
@@ -3,7 +3,6 @@ "+components/viz/common", "+components/viz/host", "+components/viz/service", - "+components/variations", "+services/ui/public", "+third_party/zlib", "+ui/latency",
diff --git a/content/browser/renderer_host/compositor_impl_android.cc b/content/browser/renderer_host/compositor_impl_android.cc index 43a11663..ae765ed 100644 --- a/content/browser/renderer_host/compositor_impl_android.cc +++ b/content/browser/renderer_host/compositor_impl_android.cc
@@ -104,9 +104,8 @@ // Gpu process, instead get the mojo pointer from the Gpu process. frame_sink_manager_impl = base::MakeUnique<viz::FrameSinkManagerImpl>(false, nullptr); - surface_utils::ConnectWithInProcessFrameSinkManager( - &host_frame_sink_manager, frame_sink_manager_impl.get(), - base::ThreadTaskRunnerHandle::Get()); + surface_utils::ConnectWithLocalFrameSinkManager( + &host_frame_sink_manager, frame_sink_manager_impl.get()); } SingleThreadTaskGraphRunner task_graph_runner; @@ -837,10 +836,11 @@ auto layer_tree_frame_sink = vulkan_context_provider ? base::MakeUnique<viz::DirectLayerTreeFrameSink>( - frame_sink_id_, manager, display_.get(), - vulkan_context_provider) + frame_sink_id_, GetHostFrameSinkManager(), manager, + display_.get(), vulkan_context_provider) : base::MakeUnique<viz::DirectLayerTreeFrameSink>( - frame_sink_id_, manager, display_.get(), context_provider, + frame_sink_id_, GetHostFrameSinkManager(), manager, + display_.get(), context_provider, nullptr /* worker_context_provider */, gpu_memory_buffer_manager, viz::ServerSharedBitmapManager::current());
diff --git a/content/browser/renderer_host/delegated_frame_host.cc b/content/browser/renderer_host/delegated_frame_host.cc index 7805e3e..a27268b 100644 --- a/content/browser/renderer_host/delegated_frame_host.cc +++ b/content/browser/renderer_host/delegated_frame_host.cc
@@ -21,6 +21,7 @@ #include "cc/surfaces/surface_hittest.h" #include "components/viz/common/gl_helper.h" #include "components/viz/common/quads/texture_mailbox.h" +#include "components/viz/host/host_frame_sink_manager.h" #include "components/viz/service/frame_sinks/compositor_frame_sink_support.h" #include "components/viz/service/frame_sinks/frame_sink_manager.h" #include "content/browser/compositor/surface_utils.h" @@ -831,10 +832,11 @@ constexpr bool handles_frame_sink_id_invalidation = false; constexpr bool needs_sync_points = true; ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); - support_ = viz::CompositorFrameSinkSupport::Create( - this, factory->GetContextFactoryPrivate()->GetFrameSinkManager(), - frame_sink_id_, is_root, handles_frame_sink_id_invalidation, - needs_sync_points); + support_ = factory->GetContextFactoryPrivate() + ->GetHostFrameSinkManager() + ->CreateCompositorFrameSinkSupport( + this, frame_sink_id_, is_root, + handles_frame_sink_id_invalidation, needs_sync_points); if (compositor_) compositor_->AddFrameSink(frame_sink_id_); if (needs_begin_frame_)
diff --git a/content/browser/renderer_host/offscreen_canvas_provider_impl_unittest.cc b/content/browser/renderer_host/offscreen_canvas_provider_impl_unittest.cc index 2127ef35..628fc5d8 100644 --- a/content/browser/renderer_host/offscreen_canvas_provider_impl_unittest.cc +++ b/content/browser/renderer_host/offscreen_canvas_provider_impl_unittest.cc
@@ -154,9 +154,8 @@ // The FrameSinkManager implementation is in-process here for tests. frame_sink_manager_ = base::MakeUnique<viz::FrameSinkManagerImpl>(false, nullptr); - surface_utils::ConnectWithInProcessFrameSinkManager( - host_frame_sink_manager_.get(), frame_sink_manager_.get(), - message_loop_.task_runner()); + surface_utils::ConnectWithLocalFrameSinkManager( + host_frame_sink_manager_.get(), frame_sink_manager_.get()); provider_ = base::MakeUnique<OffscreenCanvasProviderImpl>( host_frame_sink_manager_.get(), kRendererClientId);
diff --git a/content/browser/renderer_host/render_view_host_impl.cc b/content/browser/renderer_host/render_view_host_impl.cc index f6b12ff8..7218c7f 100644 --- a/content/browser/renderer_host/render_view_host_impl.cc +++ b/content/browser/renderer_host/render_view_host_impl.cc
@@ -29,7 +29,6 @@ #include "base/values.h" #include "build/build_config.h" #include "cc/base/switches.h" -#include "components/variations/variations_associated_data.h" #include "content/browser/bad_message.h" #include "content/browser/child_process_security_policy_impl.h" #include "content/browser/dom_storage/session_storage_namespace_impl.h"
diff --git a/content/browser/renderer_host/render_widget_host_view_android.cc b/content/browser/renderer_host/render_widget_host_view_android.cc index 46bd35b..0082320 100644 --- a/content/browser/renderer_host/render_widget_host_view_android.cc +++ b/content/browser/renderer_host/render_widget_host_view_android.cc
@@ -478,7 +478,8 @@ viz::FrameSinkId frame_sink_id = host_->AllocateFrameSinkId(false /* is_guest_view_hack */); delegated_frame_host_.reset(new ui::DelegatedFrameHostAndroid( - &view_, CompositorImpl::GetFrameSinkManager(), this, frame_sink_id)); + &view_, CompositorImpl::GetHostFrameSinkManager(), + CompositorImpl::GetFrameSinkManager(), this, frame_sink_id)); // Let the page-level input event router know about our frame sink ID // for surface-based hit testing.
diff --git a/content/ppapi_plugin/DEPS b/content/ppapi_plugin/DEPS index 0e09ed9..644ecee 100644 --- a/content/ppapi_plugin/DEPS +++ b/content/ppapi_plugin/DEPS
@@ -1,6 +1,6 @@ include_rules = [ "+components/discardable_memory/client", - "+components/variations", + "+components/variations/child_process_field_trial_syncer.h", "+content/child", "+gin/public/isolate_holder.h", "+gin/v8_initializer.h",
diff --git a/content/public/browser/browser_associated_interface.h b/content/public/browser/browser_associated_interface.h index f804998..2b86e21 100644 --- a/content/public/browser/browser_associated_interface.h +++ b/content/public/browser/browser_associated_interface.h
@@ -58,14 +58,15 @@ internal_state_->Initialize(); filter->AddAssociatedInterface( Interface::Name_, - base::Bind(&InternalState::BindRequest, internal_state_)); + base::Bind(&InternalState::BindRequest, internal_state_), + base::BindOnce(&InternalState::ClearBindings, internal_state_)); } - ~BrowserAssociatedInterface() { - internal_state_->ShutDown(); - } + ~BrowserAssociatedInterface() { internal_state_->ClearBindings(); } private: + friend class TestDriverMessageFilter; + class InternalState : public base::RefCountedThreadSafe<InternalState> { public: explicit InternalState(Interface* impl) : impl_(impl) {} @@ -79,10 +80,11 @@ bindings_.reset(new mojo::AssociatedBindingSet<Interface>); } - void ShutDown() { + void ClearBindings() { if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { - BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, - base::Bind(&InternalState::ShutDown, this)); + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + base::Bind(&InternalState::ClearBindings, this)); return; } bindings_.reset(); @@ -99,6 +101,7 @@ private: friend class base::RefCountedThreadSafe<InternalState>; + friend class TestDriverMessageFilter; ~InternalState() {}
diff --git a/content/public/browser/browser_message_filter.cc b/content/public/browser/browser_message_filter.cc index c44bea6..fd4096e6 100644 --- a/content/public/browser/browser_message_filter.cc +++ b/content/public/browser/browser_message_filter.cc
@@ -37,7 +37,12 @@ filter_->OnFilterAdded(channel); } - void OnFilterRemoved() override { filter_->OnFilterRemoved(); } + void OnFilterRemoved() override { + for (auto& callback : filter_->filter_removed_callbacks_) + std::move(callback).Run(); + filter_->filter_removed_callbacks_.clear(); + filter_->OnFilterRemoved(); + } void OnChannelClosing() override { filter_->sender_ = nullptr; @@ -112,8 +117,10 @@ void BrowserMessageFilter::AddAssociatedInterface( const std::string& name, - const IPC::ChannelProxy::GenericAssociatedInterfaceFactory& factory) { + const IPC::ChannelProxy::GenericAssociatedInterfaceFactory& factory, + base::OnceClosure filter_removed_callback) { associated_interfaces_.emplace_back(name, factory); + filter_removed_callbacks_.emplace_back(std::move(filter_removed_callback)); } base::ProcessHandle BrowserMessageFilter::PeerHandle() {
diff --git a/content/public/browser/browser_message_filter.h b/content/public/browser/browser_message_filter.h index d112276..84b6cd5 100644 --- a/content/public/browser/browser_message_filter.h +++ b/content/public/browser/browser_message_filter.h
@@ -85,9 +85,13 @@ // Adds an associated interface factory to this filter. Must be called before // RegisterAssociatedInterfaces(). + // + // |filter_removed_callback| is called on the IO thread when this filter is + // removed. void AddAssociatedInterface( const std::string& name, - const IPC::ChannelProxy::GenericAssociatedInterfaceFactory& factory); + const IPC::ChannelProxy::GenericAssociatedInterfaceFactory& factory, + const base::OnceClosure filter_removed_callback); // Can be called on any thread, after OnChannelConnected is called. base::ProcessHandle PeerHandle(); @@ -142,6 +146,9 @@ std::vector<std::pair<std::string, IPC::ChannelProxy::GenericAssociatedInterfaceFactory>> associated_interfaces_; + + // Callbacks to be called in OnFilterRemoved(). + std::vector<base::OnceClosure> filter_removed_callbacks_; }; struct BrowserMessageFilterTraits {
diff --git a/content/public/test/test_utils.cc b/content/public/test/test_utils.cc index a50cc6c..cb8a3b0 100644 --- a/content/public/test/test_utils.cc +++ b/content/public/test/test_utils.cc
@@ -19,6 +19,7 @@ #include "base/threading/thread_task_runner_handle.h" #include "base/values.h" #include "build/build_config.h" +#include "components/variations/variations_params_manager.h" #include "content/common/site_isolation_policy.h" #include "content/common/url_schemes.h" #include "content/public/browser/browser_child_process_host_iterator.h" @@ -212,6 +213,23 @@ url::Initialize(); } +void EnableFeatureWithParam(const base::Feature& feature, + const std::string& param_name, + const std::string& param_value, + base::CommandLine* command_line) { + static const char kFakeTrialName[] = "TrialNameForTesting"; + static const char kFakeTrialGroupName[] = "TrialGroupForTesting"; + + // Enable all the |feature|, associating them with |trial_name|. + command_line->AppendSwitchASCII( + switches::kEnableFeatures, + std::string(feature.name) + "<" + kFakeTrialName); + + std::map<std::string, std::string> param_values = {{param_name, param_value}}; + variations::testing::VariationParamsManager::AppendVariationParams( + kFakeTrialName, kFakeTrialGroupName, param_values, command_line); +} + #if defined(OS_ANDROID) // Registers content/browser and mojo JNI bindings necessary for some types of // tests.
diff --git a/content/public/test/test_utils.h b/content/public/test/test_utils.h index f8afeece..330210f 100644 --- a/content/public/test/test_utils.h +++ b/content/public/test/test_utils.h
@@ -26,8 +26,9 @@ #endif namespace base { -class Value; class CommandLine; +class Value; +struct Feature; } // namespace base // A collection of functions designed for use with unit and browser tests. @@ -87,6 +88,17 @@ // Resets the internal secure schemes/origins whitelist. void ResetSchemesAndOriginsWhitelist(); +// Appends command line switches to |command_line| to enable the |feature| and +// to set field trial params associated with the feature as specified by +// |param_name| and |param_value|. +// +// Note that a dummy trial and trial group will be registered behind the scenes. +// See also variations::testing::VariationsParamsManager class. +void EnableFeatureWithParam(const base::Feature& feature, + const std::string& param_name, + const std::string& param_value, + base::CommandLine* command_line); + #if defined(OS_ANDROID) // Registers content/browser JNI bindings necessary for some types of tests. bool RegisterJniForTesting(JNIEnv* env);
diff --git a/content/renderer/DEPS b/content/renderer/DEPS index b803a5a..a77566d 100644 --- a/content/renderer/DEPS +++ b/content/renderer/DEPS
@@ -7,7 +7,7 @@ "+components/payments", "+components/scheduler", "+components/url_formatter", - "+components/variations", + "+components/variations/child_process_field_trial_syncer.h", "+components/viz/client", "+components/viz/common",
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index 65c23fb..ac1e5a06 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -234,6 +234,7 @@ ] public_deps = [ + "//components/variations:test_support", "//content/public/app:both", "//content/public/browser", "//content/public/common",
diff --git a/docs/adding_to_third_party.md b/docs/adding_to_third_party.md index 512c621..2f5d235 100644 --- a/docs/adding_to_third_party.md +++ b/docs/adding_to_third_party.md
@@ -67,10 +67,6 @@ about:credits page in Google Chrome builds. * `src/tools/checklicenses/checklicenses.py` - See below for info on how to handle possible failures. -* If you are adding code that will be present in the content layer, please make - sure that the license used is compliant with Android tree requirements because - this code will also be used in Android WebView. You need to run - `src/android_webview/tools/webview_licenses.py scan` See the ["Odds n' Ends"](adding_to_third_party.md#Odds-n_Ends) Section below if you run into any failures running these. @@ -187,16 +183,3 @@ resulting binaries can't use GPL code. Ideally we just shouldn't have those files at all in the tree. If in doubt, please ask mal@chromium.org -### Handling `webview_licenses.py` failures - -__If the failure looks like ... ... the right action is to ... __ - -* Missing license file - * Make sure that the license file is present. It should be called 'LICENSE', - or otherwise README.chromium file must point to it explicitly. -* The following files contain a third-party license but are not in a listed - third-party directory... - * Check if it's a false positive (e.g. 'copyright' word used in a string - literal), if so, update - [src/tools/copyright_scanner/third_party_files_whitelist.txt](https://code.google.com/p/chromium/codesearch#chromium/src/tools/copyright_scanner/third_party_files_whitelist.txt) - file. Otherwise, please move the code into third_party.
diff --git a/infra/config/cq.cfg b/infra/config/cq.cfg index c4f49c6..e914c07 100644 --- a/infra/config/cq.cfg +++ b/infra/config/cq.cfg
@@ -49,12 +49,7 @@ builders { name: "chromeos_daisy_chromium_compile_only_ng" } builders { name: "chromium_presubmit" } builders { name: "linux_chromium_asan_rel_ng" } - # TODO(dpranke): reenable ASAP; see crbug.com/669297. - #builders { name: "linux_chromium_chromeos_compile_dbg_ng" } - builders { name: "linux_chromium_chromeos_ozone_rel_ng" } builders { name: "linux_chromium_chromeos_rel_ng" } - # TODO(dpranke): reenable ASAP; see crbug.com/669297. - #builders { name: "linux_chromium_clobber_rel_ng" } builders { name: "linux_chromium_compile_dbg_ng" } builders { name: "linux_chromium_headless_rel" } builders { name: "linux_chromium_tsan_rel_ng" }
diff --git a/ios/build/xcode_install_wrapper.py b/ios/build/xcode_install_wrapper.py new file mode 100755 index 0000000..b7b53fcb --- /dev/null +++ b/ios/build/xcode_install_wrapper.py
@@ -0,0 +1,75 @@ +#!/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. + +"""Wrapper script to install Xcode. For use on the bots. + +Installing Xcode requires sudo. This script will be whitelisted in /etc/sudoers +so that we can easily update Xcode on our bots. +""" + +import argparse +import hashlib +import logging +import os +import subprocess +import sys + + +# List of sha256 hashes of Xcode package file +# Contents/Resources/Packages/XcodeSystemResources.pkg +WHITELISTED_PACKAGES = [ + # Xcode versions 8A218a-1, 8A218a-2 + '3d948c4bd7c8941478a60aece3cb98ef936a57a4cc1c8f8d5f7eef70d0ebbad1', + # Xcode versions 8B62-1, 8C1002-1 + '21ed3271af2ac7d67c6c09a9481a1fd5bb886950990365bb936dde7585e09061', + # Xcode versions 8E2002-1 + 'ff2377d3976f7acf2adfe5ca91c2e6cc59dd112647efa0bf39e9d9decd2ee1b3', + # Xcode versions 9M136h-1 + '2ec798b123bcfa7f8c0e5618c193ecd26ddce87f2e27f6b5d2fb0720926e5464', + # Xcode versions 9M137d-1 + '6c5f4a2fd6dc477f8f06ccd6f6119da540dd5fe3a6036357dbe9c13d611fc366', +] + +def main(): + logging.basicConfig(level=logging.DEBUG) + + parser = argparse.ArgumentParser( + description='Wrapper script to install Xcode.') + parser.add_argument( + '--package-path', + help='Path to Xcode package to install.', + required=True) + args = parser.parse_args() + + if not os.path.isfile(args.package_path): + logging.critical('Path %s is not a file.' % args.package_path) + return 1 + + sha256 = hashlib.sha256() + with open(args.package_path, 'rb') as f: + for chunk in iter(lambda: f.read(8192), b''): + sha256.update(chunk) + sha256_hash = sha256.hexdigest() + + if sha256_hash not in WHITELISTED_PACKAGES: + logging.critical('Attempted to install a non-whitelisted Xcode package.') + return 1 + + pipe = subprocess.Popen( + ['/usr/sbin/installer', '-pkg', args.package_path, '-target', '/'], + stdout=subprocess.PIPE, stderr=subprocess.PIPE) + stdout, stderr = pipe.communicate() + + for line in stdout.splitlines(): + logging.debug(line) + for line in stderr.splitlines(): + logging.error(line) + + return pipe.returncode + + +if __name__ == '__main__': + sys.exit(main())
diff --git a/ios/chrome/app/strings/ios_strings.grd b/ios/chrome/app/strings/ios_strings.grd index 55bab02e..e2da779 100644 --- a/ios/chrome/app/strings/ios_strings.grd +++ b/ios/chrome/app/strings/ios_strings.grd
@@ -195,24 +195,9 @@ <message name="IDS_IOS_APPLICATION_SHORTCUT_VOICE_SEARCH_TITLE" desc="Message when opening a Voice Search from springboard force touch static shortcuts. [Length: unlimited] [iOS only]." meaning="3D Touch entry to trigger a voice search."> Voice Search </message> - <message name="IDS_IOS_APP_LAUNCHER_INSTALL_APP_BUTTON_LABEL" desc="Label of a button to install an application. [Length: 10em] [iOS only]"> - Install - </message> - <message name="IDS_IOS_APP_LAUNCHER_OPEN_ALWAYS_BUTTON" desc="Label of a button to choose to launch an application always, as opposed to once. [Length: 12em] [iOS only]"> - Always - </message> <message name="IDS_IOS_APP_LAUNCHER_OPEN_APP_BUTTON_LABEL" desc="Label of a button to open an application. [Length: 10em] [iOS only]"> Open </message> - <message name="IDS_IOS_APP_LAUNCHER_OPEN_IN_APP_QUESTION_MESSAGE" desc="Message in the infobar asking the user if they want to open the current page in an external app. [Length: 40em] [iOS only]"> - Open this page in the <ph name="APP_NAME">$1<ex>Google Maps</ex></ph> app? - </message> - <message name="IDS_IOS_APP_LAUNCHER_OPEN_IN_LABEL" desc="Label in the infobar to launch an application. [Length: 20em] [iOS only]"> - Open in <ph name="APP_NAME">$1<ex>Google Maps</ex></ph> - </message> - <message name="IDS_IOS_APP_LAUNCHER_OPEN_ONCE_BUTTON" desc="Label of a button to choose to launch an application once, as opposed to always. [Length: 12em] [iOS only]"> - Just once - </message> <message name="IDS_IOS_AUTOFILL" desc="Title for the view in Settings for enabling/disabling Autofill. [Length: 15em] [iOS only]"> Autofill Forms </message>
diff --git a/ios/chrome/browser/native_app_launcher/BUILD.gn b/ios/chrome/browser/native_app_launcher/BUILD.gn index 39eebc79..aa2afa9 100644 --- a/ios/chrome/browser/native_app_launcher/BUILD.gn +++ b/ios/chrome/browser/native_app_launcher/BUILD.gn
@@ -7,45 +7,5 @@ sources = [ "ios_appstore_ids.h", "ios_appstore_ids.mm", - "native_app_infobar_controller.h", - "native_app_infobar_controller.mm", - "native_app_infobar_delegate.h", - "native_app_infobar_delegate.mm", - "native_app_navigation_controller_protocol.h", - ] - deps = [ - "//base", - "//components/infobars/core", - "//ios/chrome/app/strings", - "//ios/chrome/browser/infobars", - "//ios/chrome/browser/ui/infobars", - "//ios/public/provider/chrome/browser/native_app_launcher", - "//ui/base", - "//url", - ] -} - -source_set("unit_tests") { - configs += [ "//build/config/compiler:enable_arc" ] - testonly = true - sources = [ - "native_app_infobar_controller_unittest.mm", - "native_app_infobar_delegate_unittest.mm", - ] - deps = [ - ":native_app_launcher", - "//base", - "//base/test:test_support", - "//components/infobars/core", - "//ios/chrome/browser", - "//ios/chrome/test:test_support", - "//ios/public/provider/chrome/browser", - "//ios/public/provider/chrome/browser:test_support", - "//ios/public/provider/chrome/browser/native_app_launcher", - "//ios/web", - "//net:test_support", - "//testing/gmock", - "//testing/gtest", - "//url", ] }
diff --git a/ios/chrome/browser/native_app_launcher/native_app_infobar_controller.h b/ios/chrome/browser/native_app_launcher/native_app_infobar_controller.h deleted file mode 100644 index 873f2cd..0000000 --- a/ios/chrome/browser/native_app_launcher/native_app_infobar_controller.h +++ /dev/null
@@ -1,13 +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 IOS_CHROME_BROWSER_NATIVE_APP_LAUNCHER_NATIVE_APP_INFOBAR_CONTROLLER_H_ -#define IOS_CHROME_BROWSER_NATIVE_APP_LAUNCHER_NATIVE_APP_INFOBAR_CONTROLLER_H_ - -#include "ios/chrome/browser/infobars/infobar_controller.h" - -@interface NativeAppInfoBarController : InfoBarController -@end - -#endif // IOS_CHROME_BROWSER_NATIVE_APP_LAUNCHER_NATIVE_APP_INFOBAR_CONTROLLER_H_
diff --git a/ios/chrome/browser/native_app_launcher/native_app_infobar_controller.mm b/ios/chrome/browser/native_app_launcher/native_app_infobar_controller.mm deleted file mode 100644 index ae68f8c..0000000 --- a/ios/chrome/browser/native_app_launcher/native_app_infobar_controller.mm +++ /dev/null
@@ -1,129 +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. - -#import "ios/chrome/browser/native_app_launcher/native_app_infobar_controller.h" - -#include "base/logging.h" -#include "base/strings/sys_string_conversions.h" -#include "ios/chrome/browser/native_app_launcher/native_app_infobar_delegate.h" -#import "ios/chrome/browser/ui/infobars/infobar_view.h" -#include "ios/chrome/browser/ui/infobars/infobar_view.h" -#include "ios/chrome/grit/ios_strings.h" -#import "ios/public/provider/chrome/browser/native_app_launcher/native_app_types.h" -#include "ui/base/l10n/l10n_util.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -@interface NativeAppInfoBarController () - -// Action for any of the user defined buttons. -- (void)infoBarButtonDidPress:(UIButton*)button; - -// Notifies the delegate of which action the user took. -- (void)userPerformedAction:(NativeAppActionType)userAction; - -// For testing. -// Sets the infobar delegate. -- (void)setInfoBarDelegate:(NativeAppInfoBarDelegate*)delegate; - -@end - -@implementation NativeAppInfoBarController { - NativeAppInfoBarDelegate* nativeAppInfoBarDelegate_; // weak -} - -#pragma mark - InfoBarController - -- (InfoBarView*)viewForDelegate:(infobars::InfoBarDelegate*)delegate - frame:(CGRect)frame { - InfoBarView* infoBarView; - nativeAppInfoBarDelegate_ = static_cast<NativeAppInfoBarDelegate*>(delegate); - DCHECK(nativeAppInfoBarDelegate_); - infoBarView = - [[InfoBarView alloc] initWithFrame:frame delegate:self.delegate]; - - // Lays out widgets common to all NativeAppInfobars. - [infoBarView - addPlaceholderTransparentIcon:native_app_infobar::kSmallIconSize]; - nativeAppInfoBarDelegate_->FetchSmallAppIcon(^(UIImage* image) { - [infoBarView addLeftIconWithRoundedCornersAndShadow:image]; - }); - [infoBarView addCloseButtonWithTag:NATIVE_APP_ACTION_DISMISS - target:self - action:@selector(infoBarButtonDidPress:)]; - - auto type = nativeAppInfoBarDelegate_->GetControllerType(); - switch (type) { - case NATIVE_APP_INSTALLER_CONTROLLER: { - NSString* buttonMsg = - l10n_util::GetNSString(IDS_IOS_APP_LAUNCHER_INSTALL_APP_BUTTON_LABEL); - [infoBarView addButton:buttonMsg - tag:NATIVE_APP_ACTION_CLICK_INSTALL - target:self - action:@selector(infoBarButtonDidPress:)]; - DCHECK(nativeAppInfoBarDelegate_->GetInstallText().length()); - [infoBarView addLabel:base::SysUTF16ToNSString( - nativeAppInfoBarDelegate_->GetInstallText())]; - break; - } - case NATIVE_APP_LAUNCHER_CONTROLLER: { - NSString* buttonMsg = - l10n_util::GetNSString(IDS_IOS_APP_LAUNCHER_OPEN_APP_BUTTON_LABEL); - [infoBarView addButton:buttonMsg - tag:NATIVE_APP_ACTION_CLICK_LAUNCH - target:self - action:@selector(infoBarButtonDidPress:)]; - DCHECK(nativeAppInfoBarDelegate_->GetLaunchText().length()); - [infoBarView addLabel:base::SysUTF16ToNSString( - nativeAppInfoBarDelegate_->GetLaunchText())]; - break; - } - case NATIVE_APP_OPEN_POLICY_CONTROLLER: { - NSString* labelMsg = base::SysUTF16ToNSString( - nativeAppInfoBarDelegate_->GetOpenPolicyText()); - DCHECK(nativeAppInfoBarDelegate_->GetOpenPolicyText().length()); - NSString* buttonOnceString = base::SysUTF16ToNSString( - nativeAppInfoBarDelegate_->GetOpenOnceText()); - NSString* buttonAlwaysString = base::SysUTF16ToNSString( - nativeAppInfoBarDelegate_->GetOpenAlwaysText()); - [infoBarView addLabel:labelMsg]; - [infoBarView addButton1:buttonOnceString - tag1:NATIVE_APP_ACTION_CLICK_ONCE - button2:buttonAlwaysString - tag2:NATIVE_APP_ACTION_CLICK_ALWAYS - target:self - action:@selector(infoBarButtonDidPress:)]; - break; - } - } - return infoBarView; -} - -- (void)infoBarButtonDidPress:(UIButton*)button { - DCHECK(nativeAppInfoBarDelegate_); - DCHECK([button isKindOfClass:[UIButton class]]); - // This press might have occurred after the user has already pressed a button, - // in which case the view has been detached from the delegate and this press - // should be ignored. - if (!self.delegate) { - return; - } - self.delegate->InfoBarDidCancel(); - NativeAppActionType action = static_cast<NativeAppActionType>([button tag]); - [self userPerformedAction:action]; -} - -- (void)userPerformedAction:(NativeAppActionType)userAction { - nativeAppInfoBarDelegate_->UserPerformedAction(userAction); -} - -#pragma mark - Testing - -- (void)setInfoBarDelegate:(NativeAppInfoBarDelegate*)delegate { - nativeAppInfoBarDelegate_ = delegate; -} - -@end
diff --git a/ios/chrome/browser/native_app_launcher/native_app_infobar_controller_unittest.mm b/ios/chrome/browser/native_app_launcher/native_app_infobar_controller_unittest.mm deleted file mode 100644 index 5676ce2..0000000 --- a/ios/chrome/browser/native_app_launcher/native_app_infobar_controller_unittest.mm +++ /dev/null
@@ -1,105 +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. - -#import "ios/chrome/browser/native_app_launcher/native_app_infobar_controller.h" - -#include <memory> - -#include "base/mac/scoped_nsobject.h" -#import "ios/public/provider/chrome/browser/native_app_launcher/native_app_types.h" -#include "ios/chrome/browser/native_app_launcher/native_app_infobar_delegate.h" -#import "ios/chrome/browser/native_app_launcher/native_app_navigation_controller_protocol.h" -#include "testing/platform_test.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -@interface NativeAppInfoBarController (Testing) -- (void)infoBarButtonDidPress:(UIButton*)button; -- (void)setInfoBarDelegate:(NativeAppInfoBarDelegate*)delegate; -@end - -namespace { - -class NativeAppInfoBarControllerTest : public PlatformTest { - class MockNativeAppInfoBarDelegate : public NativeAppInfoBarDelegate { - public: - MockNativeAppInfoBarDelegate(NativeAppControllerType type) - : NativeAppInfoBarDelegate(nil, GURL(), type), - performedActionCount_(0), - userAction_(NATIVE_APP_ACTION_COUNT){}; - - void CheckIfPerformedActionIsCorrectAndResetCounter() { - EXPECT_EQ(expectedUserAction_, userAction_); - EXPECT_EQ(performedActionCount_, 1); - performedActionCount_ = 0; - } - - void UserPerformedAction(NativeAppActionType userAction) override { - userAction_ = userAction; - performedActionCount_++; - }; - - void SetExpectedUserAction(const NativeAppActionType expectedUserAction) { - expectedUserAction_ = expectedUserAction; - }; - - private: - int performedActionCount_; - NativeAppActionType userAction_; - NativeAppActionType expectedUserAction_; - }; - - class MockInfobarViewDelegate : public InfoBarViewDelegate { - public: - void SetInfoBarTargetHeight(int height) override {} - void InfoBarDidCancel() override {} - void InfoBarButtonDidPress(NSUInteger button_id) override {} - }; - - protected: - void SetUpWithType(NativeAppControllerType type) { - mockDelegate_.reset(new MockNativeAppInfoBarDelegate(type)); - mockInfoBarViewDelegate_.reset(new MockInfobarViewDelegate()); - infobarController_.reset([[NativeAppInfoBarController alloc] - initWithDelegate:mockInfoBarViewDelegate_.get()]); - [infobarController_ setInfoBarDelegate:mockDelegate_.get()]; - }; - - // Checks -userPerformedAction: for calls to the delegate's - // UserPerformedAction member function. - void ExpectUserPerformedAction(NativeAppActionType performedAction) { - mockDelegate_->SetExpectedUserAction(performedAction); - UIButton* mockButton = [UIButton buttonWithType:UIButtonTypeCustom]; - mockButton.tag = performedAction; - [infobarController_ infoBarButtonDidPress:mockButton]; - mockDelegate_->CheckIfPerformedActionIsCorrectAndResetCounter(); - }; - - base::scoped_nsobject<NativeAppInfoBarController> infobarController_; - std::unique_ptr<MockNativeAppInfoBarDelegate> mockDelegate_; - std::unique_ptr<MockInfobarViewDelegate> mockInfoBarViewDelegate_; -}; - -TEST_F(NativeAppInfoBarControllerTest, TestActionsWithInstallInfoBar) { - SetUpWithType(NATIVE_APP_INSTALLER_CONTROLLER); - ExpectUserPerformedAction(NATIVE_APP_ACTION_CLICK_INSTALL); - ExpectUserPerformedAction(NATIVE_APP_ACTION_DISMISS); -} - -TEST_F(NativeAppInfoBarControllerTest, TestActionsWithLaunchInfoBar) { - SetUpWithType(NATIVE_APP_LAUNCHER_CONTROLLER); - ExpectUserPerformedAction(NATIVE_APP_ACTION_CLICK_LAUNCH); - ExpectUserPerformedAction(NATIVE_APP_ACTION_DISMISS); -} - -TEST_F(NativeAppInfoBarControllerTest, TestActionsWithOpenPolicyInfoBar) { - SetUpWithType(NATIVE_APP_OPEN_POLICY_CONTROLLER); - ExpectUserPerformedAction(NATIVE_APP_ACTION_CLICK_ONCE); - ExpectUserPerformedAction(NATIVE_APP_ACTION_CLICK_ALWAYS); - ExpectUserPerformedAction(NATIVE_APP_ACTION_DISMISS); -} - -} // namespace
diff --git a/ios/chrome/browser/native_app_launcher/native_app_infobar_delegate.h b/ios/chrome/browser/native_app_launcher/native_app_infobar_delegate.h deleted file mode 100644 index 179d16d..0000000 --- a/ios/chrome/browser/native_app_launcher/native_app_infobar_delegate.h +++ /dev/null
@@ -1,74 +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 IOS_CHROME_BROWSER_NATIVE_APP_LAUNCHER_NATIVE_APP_INFOBAR_DELEGATE_H_ -#define IOS_CHROME_BROWSER_NATIVE_APP_LAUNCHER_NATIVE_APP_INFOBAR_DELEGATE_H_ - -#include "base/macros.h" -#include "base/strings/string16.h" -#include "components/infobars/core/infobar_delegate.h" -#include "ios/chrome/browser/infobars/infobar.h" -#import "ios/public/provider/chrome/browser/native_app_launcher/native_app_types.h" -#include "url/gurl.h" - -@class NativeAppNavigationController; -@protocol NativeAppNavigationControllerProtocol; -@class NSString; -@class UIImage; - -namespace infobars { -class InfoBarManager; -} // namespace infobars - -namespace net { -class URLRequestContextGetter; -} // namespace net - -namespace native_app_infobar { -extern const CGSize kSmallIconSize; -} // namespace native_app_infobar - -// The delegate contains the information to create a -// NativeAppInstallerInfoBarView, a NativeAppLauncherInfoBarView or a -// NativeAppOpenPolicyInfoBarView. -class NativeAppInfoBarDelegate : public infobars::InfoBarDelegate { - public: - NativeAppInfoBarDelegate(id<NativeAppNavigationControllerProtocol> controller, - const GURL& page_url, - NativeAppControllerType type); - ~NativeAppInfoBarDelegate() override; - - // Creates and adds a native app info bar to |manager|. - static bool Create(infobars::InfoBarManager* manager, - id<NativeAppNavigationControllerProtocol> controller, - const GURL& page_url, - NativeAppControllerType type); - - NativeAppInfoBarDelegate* AsNativeAppInfoBarDelegate() override; - base::string16 GetInstallText() const; - base::string16 GetLaunchText() const; - base::string16 GetOpenPolicyText() const; - base::string16 GetOpenOnceText() const; - base::string16 GetOpenAlwaysText() const; - const GURL& GetIconURL() const; - NSString* GetAppId() const; - infobars::InfoBarDelegate::Type GetInfoBarType() const override; - InfoBarIdentifier GetIdentifier() const override; - bool EqualsDelegate(infobars::InfoBarDelegate* delegate) const override; - net::URLRequestContextGetter* GetRequestContextGetter(); - void FetchSmallAppIcon(void (^block)(UIImage*)); - // This function is made virtual for tests. - virtual void UserPerformedAction(NativeAppActionType userAction); - NativeAppControllerType GetControllerType() const; - - private: - bool ShouldExpire(const NavigationDetails& details) const override; - __weak id<NativeAppNavigationControllerProtocol> controller_; - net::URLRequestContextGetter* requestContextGetter_; - GURL page_url_; - NativeAppControllerType type_; - DISALLOW_COPY_AND_ASSIGN(NativeAppInfoBarDelegate); -}; - -#endif // IOS_CHROME_BROWSER_NATIVE_APP_LAUNCHER_NATIVE_APP_INFOBAR_DELEGATE_H_
diff --git a/ios/chrome/browser/native_app_launcher/native_app_infobar_delegate.mm b/ios/chrome/browser/native_app_launcher/native_app_infobar_delegate.mm deleted file mode 100644 index 9e75ac9..0000000 --- a/ios/chrome/browser/native_app_launcher/native_app_infobar_delegate.mm +++ /dev/null
@@ -1,152 +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 "ios/chrome/browser/native_app_launcher/native_app_infobar_delegate.h" - -#import <Foundation/Foundation.h> - -#include <memory> -#include <utility> - -#include "base/memory/ptr_util.h" -#include "base/strings/sys_string_conversions.h" -#include "components/infobars/core/infobar_manager.h" -#import "ios/chrome/browser/native_app_launcher/native_app_infobar_controller.h" -#import "ios/chrome/browser/native_app_launcher/native_app_navigation_controller_protocol.h" -#include "ios/chrome/grit/ios_strings.h" -#include "ui/base/l10n/l10n_util.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -namespace native_app_infobar { -const CGSize kSmallIconSize = {29.0, 29.0}; -} // namespace native_app_infobar - -NativeAppInfoBarDelegate::NativeAppInfoBarDelegate( - id<NativeAppNavigationControllerProtocol> controller, - const GURL& page_url, - NativeAppControllerType type) - : controller_(controller), page_url_(page_url), type_(type) {} - -NativeAppInfoBarDelegate::~NativeAppInfoBarDelegate() {} - -// static -bool NativeAppInfoBarDelegate::Create( - infobars::InfoBarManager* manager, - id<NativeAppNavigationControllerProtocol> controller_protocol, - const GURL& page_url, - NativeAppControllerType type) { - DCHECK(manager); - auto infobar = - base::MakeUnique<InfoBarIOS>(base::MakeUnique<NativeAppInfoBarDelegate>( - controller_protocol, page_url, type)); - NativeAppInfoBarController* controller = - [[NativeAppInfoBarController alloc] initWithDelegate:infobar.get()]; - infobar->SetController(controller); - return !!manager->AddInfoBar(std::move(infobar)); -} - -bool NativeAppInfoBarDelegate::ShouldExpire( - const NavigationDetails& details) const { - return details.is_navigation_to_different_page; -} - -NativeAppInfoBarDelegate* -NativeAppInfoBarDelegate::AsNativeAppInfoBarDelegate() { - return this; -} - -base::string16 NativeAppInfoBarDelegate::GetInstallText() const { - return l10n_util::GetStringFUTF16( - IDS_IOS_APP_LAUNCHER_OPEN_IN_APP_QUESTION_MESSAGE, - base::SysNSStringToUTF16([controller_ appName])); -} - -base::string16 NativeAppInfoBarDelegate::GetLaunchText() const { - return l10n_util::GetStringFUTF16( - IDS_IOS_APP_LAUNCHER_OPEN_IN_APP_QUESTION_MESSAGE, - base::SysNSStringToUTF16([controller_ appName])); -} - -base::string16 NativeAppInfoBarDelegate::GetOpenPolicyText() const { - return l10n_util::GetStringFUTF16( - IDS_IOS_APP_LAUNCHER_OPEN_IN_LABEL, - base::SysNSStringToUTF16([controller_ appName])); -} - -base::string16 NativeAppInfoBarDelegate::GetOpenOnceText() const { - return l10n_util::GetStringUTF16(IDS_IOS_APP_LAUNCHER_OPEN_ONCE_BUTTON); -} - -base::string16 NativeAppInfoBarDelegate::GetOpenAlwaysText() const { - return l10n_util::GetStringUTF16(IDS_IOS_APP_LAUNCHER_OPEN_ALWAYS_BUTTON); -} - -NSString* NativeAppInfoBarDelegate::GetAppId() const { - return [controller_ appId]; -} - -infobars::InfoBarDelegate::Type NativeAppInfoBarDelegate::GetInfoBarType() - const { - return PAGE_ACTION_TYPE; -} - -infobars::InfoBarDelegate::InfoBarIdentifier -NativeAppInfoBarDelegate::GetIdentifier() const { - switch (type_) { - case NATIVE_APP_INSTALLER_CONTROLLER: - return NATIVE_APP_INSTALLER_INFOBAR_DELEGATE; - case NATIVE_APP_LAUNCHER_CONTROLLER: - return NATIVE_APP_LAUNCHER_INFOBAR_DELEGATE; - case NATIVE_APP_OPEN_POLICY_CONTROLLER: - return NATIVE_APP_OPEN_POLICY_INFOBAR_DELEGATE; - } -} - -bool NativeAppInfoBarDelegate::EqualsDelegate( - infobars::InfoBarDelegate* delegate) const { - NativeAppInfoBarDelegate* nativeAppInfoBarDelegate = - delegate->AsNativeAppInfoBarDelegate(); - return nativeAppInfoBarDelegate && - [nativeAppInfoBarDelegate->GetAppId() isEqualToString:GetAppId()]; -} - -void NativeAppInfoBarDelegate::FetchSmallAppIcon(void (^block)(UIImage*)) { - [controller_ fetchSmallIconWithCompletionBlock:block]; -} - -void NativeAppInfoBarDelegate::UserPerformedAction( - NativeAppActionType userAction) { - [controller_ updateMetadataWithUserAction:userAction]; - switch (userAction) { - case NATIVE_APP_ACTION_CLICK_INSTALL: - DCHECK(type_ == NATIVE_APP_INSTALLER_CONTROLLER); - [controller_ openStore]; - break; - case NATIVE_APP_ACTION_CLICK_LAUNCH: - DCHECK(type_ == NATIVE_APP_LAUNCHER_CONTROLLER); - [controller_ launchApp:page_url_]; - break; - case NATIVE_APP_ACTION_CLICK_ONCE: - DCHECK(type_ == NATIVE_APP_OPEN_POLICY_CONTROLLER); - [controller_ launchApp:page_url_]; - break; - case NATIVE_APP_ACTION_CLICK_ALWAYS: - DCHECK(type_ == NATIVE_APP_OPEN_POLICY_CONTROLLER); - [controller_ launchApp:page_url_]; - break; - case NATIVE_APP_ACTION_DISMISS: - break; - case NATIVE_APP_ACTION_IGNORE: - case NATIVE_APP_ACTION_COUNT: - NOTREACHED(); - break; - } -} - -NativeAppControllerType NativeAppInfoBarDelegate::GetControllerType() const { - return type_; -}
diff --git a/ios/chrome/browser/native_app_launcher/native_app_infobar_delegate_unittest.mm b/ios/chrome/browser/native_app_launcher/native_app_infobar_delegate_unittest.mm deleted file mode 100644 index 72b31ac..0000000 --- a/ios/chrome/browser/native_app_launcher/native_app_infobar_delegate_unittest.mm +++ /dev/null
@@ -1,44 +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. - -#import "ios/chrome/browser/native_app_launcher/native_app_infobar_delegate.h" - -#include <memory> - -#include "base/memory/ptr_util.h" -#import "ios/public/provider/chrome/browser/native_app_launcher/native_app_types.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "testing/platform_test.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -namespace { - -class NativeAppInfoBarDelegateTest : public PlatformTest {}; - -TEST_F(NativeAppInfoBarDelegateTest, TestIdentifiers) { - std::unique_ptr<NativeAppInfoBarDelegate> delegate; - - delegate = base::MakeUnique<NativeAppInfoBarDelegate>( - nil, GURL(), NATIVE_APP_INSTALLER_CONTROLLER); - EXPECT_EQ(infobars::InfoBarDelegate::InfoBarIdentifier:: - NATIVE_APP_INSTALLER_INFOBAR_DELEGATE, - delegate->GetIdentifier()); - - delegate = base::MakeUnique<NativeAppInfoBarDelegate>( - nil, GURL(), NATIVE_APP_LAUNCHER_CONTROLLER); - EXPECT_EQ(infobars::InfoBarDelegate::InfoBarIdentifier:: - NATIVE_APP_LAUNCHER_INFOBAR_DELEGATE, - delegate->GetIdentifier()); - - delegate = base::MakeUnique<NativeAppInfoBarDelegate>( - nil, GURL(), NATIVE_APP_OPEN_POLICY_CONTROLLER); - EXPECT_EQ(infobars::InfoBarDelegate::InfoBarIdentifier:: - NATIVE_APP_OPEN_POLICY_INFOBAR_DELEGATE, - delegate->GetIdentifier()); -} - -} // namespace
diff --git a/ios/chrome/browser/native_app_launcher/native_app_navigation_controller_protocol.h b/ios/chrome/browser/native_app_launcher/native_app_navigation_controller_protocol.h deleted file mode 100644 index c006f28..0000000 --- a/ios/chrome/browser/native_app_launcher/native_app_navigation_controller_protocol.h +++ /dev/null
@@ -1,30 +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 IOS_CHROME_BROWSER_NATIVE_APP_LAUNCHER_NATIVE_APP_NAVIGATION_CONTROLLER_PROTOCOL_H_ -#define IOS_CHROME_BROWSER_NATIVE_APP_LAUNCHER_NATIVE_APP_NAVIGATION_CONTROLLER_PROTOCOL_H_ - -#import "ios/public/provider/chrome/browser/native_app_launcher/native_app_types.h" - -class GURL; -@class NSString; -@class UIImage; - -// Protocol required for a controller to create a Native App Launcher infobar. -@protocol NativeAppNavigationControllerProtocol -// Returns app ID used to offer the installation of the application -- (NSString*)appId; -// Returns app name displayed in the infobar. -- (NSString*)appName; -// Asynchronously fetches icon and calls |block| when done. -- (void)fetchSmallIconWithCompletionBlock:(void (^)(UIImage*))block; -// Launches the application from the information extracted from |url|. -- (void)launchApp:(const GURL&)url; -// Opens store for the installation of the application. -- (void)openStore; -// Update metadata based on what the user did with the infobar. -- (void)updateMetadataWithUserAction:(NativeAppActionType)userAction; -@end - -#endif // IOS_CHROME_BROWSER_NATIVE_APP_LAUNCHER_NATIVE_APP_NAVIGATION_CONTROLLER_PROTOCOL_H_
diff --git a/ios/chrome/browser/ui/autofill/autofill_client_ios.h b/ios/chrome/browser/ui/autofill/autofill_client_ios.h index cb1a283..cb6b43ba 100644 --- a/ios/chrome/browser/ui/autofill/autofill_client_ios.h +++ b/ios/chrome/browser/ui/autofill/autofill_client_ios.h
@@ -99,6 +99,7 @@ bool ShouldShowSigninPromo() override; void StartSigninFlow() override; void ShowHttpNotSecureExplanation() override; + bool IsAutofillSupported() override; private: ios::ChromeBrowserState* browser_state_;
diff --git a/ios/chrome/browser/ui/autofill/autofill_client_ios.mm b/ios/chrome/browser/ui/autofill/autofill_client_ios.mm index 196df901..c938a2f 100644 --- a/ios/chrome/browser/ui/autofill/autofill_client_ios.mm +++ b/ios/chrome/browser/ui/autofill/autofill_client_ios.mm
@@ -226,4 +226,8 @@ NOTIMPLEMENTED(); } +bool AutofillClientIOS::IsAutofillSupported() { + return true; +} + } // namespace autofill
diff --git a/ios/chrome/browser/ui/infobars/infobar_view.h b/ios/chrome/browser/ui/infobars/infobar_view.h index 583552f3..8550e31 100644 --- a/ios/chrome/browser/ui/infobars/infobar_view.h +++ b/ios/chrome/browser/ui/infobars/infobar_view.h
@@ -35,13 +35,6 @@ // Adds icon subview. - (void)addLeftIcon:(UIImage*)image; -// Adds transparent icon of size |imageSize| as placeholder during the time when -// the icon is being downloaded. -- (void)addPlaceholderTransparentIcon:(CGSize const&)imageSize; - -// Adds an icon subview with rounded corners and a shadow. -- (void)addLeftIconWithRoundedCornersAndShadow:(UIImage*)image; - // Creates a new string from |string| that is interpreted as a link by // |addLabel:|. |tag| must not be 0. + (NSString*)stringAsLink:(NSString*)string tag:(NSUInteger)tag;
diff --git a/ios/chrome/browser/ui/infobars/infobar_view.mm b/ios/chrome/browser/ui/infobars/infobar_view.mm index d4b54623..9eb48b3 100644 --- a/ios/chrome/browser/ui/infobars/infobar_view.mm +++ b/ios/chrome/browser/ui/infobars/infobar_view.mm
@@ -33,13 +33,6 @@ const char kChromeInfobarURL[] = "chromeinternal://infobar/"; -// UX configuration constants for the shadow/rounded corners on the icon. -const CGFloat kBaseSizeForEffects = 57.0; -const CGFloat kCornerRadius = 10.0; -const CGFloat kShadowVerticalOffset = 1.0; -const CGFloat kShadowOpacity = 0.5; -const CGFloat kShadowRadius = 0.8; - // UX configuration for the layout of items. const CGFloat kLeftMarginOnFirstLineWhenIconAbsent = 20.0; const CGFloat kMinimumSpaceBetweenRightAndLeftAlignedWidgets = 30.0; @@ -689,31 +682,6 @@ [imageViewContainer_ addSubview:imageView_]; } -- (void)addPlaceholderTransparentIcon:(CGSize const&)imageSize { - UIGraphicsBeginImageContext(imageSize); - UIImage* placeholder = UIGraphicsGetImageFromCurrentImageContext(); - UIGraphicsEndImageContext(); - [self addLeftIcon:placeholder]; -} - -// Since shadows & rounded corners cannot be applied simultaneously to a -// UIView, this method adds rounded corners to the UIImageView and then adds -// drop shadow to the UIView containing the UIImageView. -- (void)addLeftIconWithRoundedCornersAndShadow:(UIImage*)image { - CGFloat effectScaleFactor = image.size.width / kBaseSizeForEffects; - [self addLeftIcon:image]; - CALayer* layer = [imageView_ layer]; - [layer setMasksToBounds:YES]; - [layer setCornerRadius:kCornerRadius * effectScaleFactor]; - layer = [imageViewContainer_ layer]; - [layer setShadowColor:[UIColor blackColor].CGColor]; - [layer - setShadowOffset:CGSizeMake(0, kShadowVerticalOffset * effectScaleFactor)]; - [layer setShadowOpacity:kShadowOpacity]; - [layer setShadowRadius:kShadowRadius * effectScaleFactor]; - [imageViewContainer_ setClipsToBounds:NO]; -} - - (NSString*)stripMarkersFromString:(NSString*)string { linkRanges_.clear(); for (;;) {
diff --git a/ios/chrome/browser/ui/payments/address_edit_coordinator.mm b/ios/chrome/browser/ui/payments/address_edit_coordinator.mm index 4e48fa85..5cb9352 100644 --- a/ios/chrome/browser/ui/payments/address_edit_coordinator.mm +++ b/ios/chrome/browser/ui/payments/address_edit_coordinator.mm
@@ -56,12 +56,6 @@ - (void)start { self.editViewController = [[PaymentRequestEditViewController alloc] init]; - // TODO(crbug.com/602666): Title varies depending on what field is missing. - // e.g., Add Email vs. Add Phone Number. - NSString* title = self.address - ? l10n_util::GetNSString(IDS_PAYMENTS_EDIT_ADDRESS) - : l10n_util::GetNSString(IDS_PAYMENTS_ADD_ADDRESS); - [self.editViewController setTitle:title]; [self.editViewController setDelegate:self]; [self.editViewController setValidatorDelegate:self]; self.mediator =
diff --git a/ios/chrome/browser/ui/payments/address_edit_mediator.mm b/ios/chrome/browser/ui/payments/address_edit_mediator.mm index 0a2ae33..99cb37e 100644 --- a/ios/chrome/browser/ui/payments/address_edit_mediator.mm +++ b/ios/chrome/browser/ui/payments/address_edit_mediator.mm
@@ -111,6 +111,13 @@ #pragma mark - CreditCardEditViewControllerDataSource +- (NSString*)title { + // TODO(crbug.com/602666): Title varies depending on what field is missing. + // e.g., Add Email vs. Add Phone Number. + return self.address ? l10n_util::GetNSString(IDS_PAYMENTS_EDIT_ADDRESS) + : l10n_util::GetNSString(IDS_PAYMENTS_ADD_ADDRESS); +} + - (CollectionViewItem*)headerItem { return nil; }
diff --git a/ios/chrome/browser/ui/payments/billing_address_selection_coordinator.mm b/ios/chrome/browser/ui/payments/billing_address_selection_coordinator.mm index 3335c86..3298c233 100644 --- a/ios/chrome/browser/ui/payments/billing_address_selection_coordinator.mm +++ b/ios/chrome/browser/ui/payments/billing_address_selection_coordinator.mm
@@ -61,8 +61,6 @@ selectedBillingProfile:self.selectedBillingProfile]; self.viewController = [[PaymentRequestSelectorViewController alloc] init]; - self.viewController.title = - l10n_util::GetNSString(IDS_PAYMENTS_BILLING_ADDRESS); self.viewController.delegate = self; self.viewController.dataSource = self.mediator; [self.viewController loadModel];
diff --git a/ios/chrome/browser/ui/payments/billing_address_selection_mediator.mm b/ios/chrome/browser/ui/payments/billing_address_selection_mediator.mm index 62df00f..f304761 100644 --- a/ios/chrome/browser/ui/payments/billing_address_selection_mediator.mm +++ b/ios/chrome/browser/ui/payments/billing_address_selection_mediator.mm
@@ -72,6 +72,10 @@ return YES; } +- (NSString*)title { + return l10n_util::GetNSString(IDS_PAYMENTS_BILLING_ADDRESS); +} + - (CollectionViewItem*)headerItem { return nil; }
diff --git a/ios/chrome/browser/ui/payments/contact_info_edit_coordinator.mm b/ios/chrome/browser/ui/payments/contact_info_edit_coordinator.mm index ee359bf1..01642f2 100644 --- a/ios/chrome/browser/ui/payments/contact_info_edit_coordinator.mm +++ b/ios/chrome/browser/ui/payments/contact_info_edit_coordinator.mm
@@ -51,13 +51,6 @@ - (void)start { self.editViewController = [[PaymentRequestEditViewController alloc] init]; - // TODO(crbug.com/602666): Title varies depending on what field is missing. - // e.g., Add Email vs. Add Phone Number. - NSString* title = - self.profile - ? l10n_util::GetNSString(IDS_PAYMENTS_EDIT_CONTACT_DETAILS_LABEL) - : l10n_util::GetNSString(IDS_PAYMENTS_ADD_CONTACT_DETAILS_LABEL); - [self.editViewController setTitle:title]; [self.editViewController setDelegate:self]; [self.editViewController setValidatorDelegate:self]; self.mediator = [[ContactInfoEditMediator alloc]
diff --git a/ios/chrome/browser/ui/payments/contact_info_edit_mediator.mm b/ios/chrome/browser/ui/payments/contact_info_edit_mediator.mm index af5c782..a6f2686 100644 --- a/ios/chrome/browser/ui/payments/contact_info_edit_mediator.mm +++ b/ios/chrome/browser/ui/payments/contact_info_edit_mediator.mm
@@ -67,6 +67,14 @@ #pragma mark - PaymentRequestEditViewControllerDataSource +- (NSString*)title { + // TODO(crbug.com/602666): Title varies depending on what field is missing. + // e.g., Add Email vs. Add Phone Number. + return self.profile + ? l10n_util::GetNSString(IDS_PAYMENTS_EDIT_CONTACT_DETAILS_LABEL) + : l10n_util::GetNSString(IDS_PAYMENTS_ADD_CONTACT_DETAILS_LABEL); +} + - (CollectionViewItem*)headerItem { return nil; }
diff --git a/ios/chrome/browser/ui/payments/contact_info_selection_coordinator.mm b/ios/chrome/browser/ui/payments/contact_info_selection_coordinator.mm index e73228e..f80cc9e 100644 --- a/ios/chrome/browser/ui/payments/contact_info_selection_coordinator.mm +++ b/ios/chrome/browser/ui/payments/contact_info_selection_coordinator.mm
@@ -63,8 +63,6 @@ initWithPaymentRequest:self.paymentRequest]; self.viewController = [[PaymentRequestSelectorViewController alloc] init]; - self.viewController.title = - l10n_util::GetNSString(IDS_PAYMENT_REQUEST_CONTACT_INFO_SECTION_NAME); self.viewController.delegate = self; self.viewController.dataSource = self.mediator; [self.viewController loadModel];
diff --git a/ios/chrome/browser/ui/payments/contact_info_selection_mediator.mm b/ios/chrome/browser/ui/payments/contact_info_selection_mediator.mm index 2e30016..082fb957 100644 --- a/ios/chrome/browser/ui/payments/contact_info_selection_mediator.mm +++ b/ios/chrome/browser/ui/payments/contact_info_selection_mediator.mm
@@ -64,6 +64,10 @@ return YES; } +- (NSString*)title { + return l10n_util::GetNSString(IDS_PAYMENT_REQUEST_CONTACT_INFO_SECTION_NAME); +} + - (CollectionViewItem*)headerItem { return nil; }
diff --git a/ios/chrome/browser/ui/payments/credit_card_edit_coordinator.mm b/ios/chrome/browser/ui/payments/credit_card_edit_coordinator.mm index 8ac85445..210b8984 100644 --- a/ios/chrome/browser/ui/payments/credit_card_edit_coordinator.mm +++ b/ios/chrome/browser/ui/payments/credit_card_edit_coordinator.mm
@@ -103,11 +103,6 @@ _creditCard = _paymentMethod ? _paymentMethod->credit_card() : nil; _editViewController = [[PaymentRequestEditViewController alloc] init]; - // TODO(crbug.com/602666): Title varies depending on the missing fields. - NSString* title = _creditCard - ? l10n_util::GetNSString(IDS_PAYMENTS_EDIT_CARD) - : l10n_util::GetNSString(IDS_PAYMENTS_ADD_CARD_LABEL); - [_editViewController setTitle:title]; [_editViewController setDelegate:self]; [_editViewController setValidatorDelegate:self]; _mediator = [[CreditCardEditViewControllerMediator alloc]
diff --git a/ios/chrome/browser/ui/payments/credit_card_edit_mediator.mm b/ios/chrome/browser/ui/payments/credit_card_edit_mediator.mm index cf087c9d..1113cd3 100644 --- a/ios/chrome/browser/ui/payments/credit_card_edit_mediator.mm +++ b/ios/chrome/browser/ui/payments/credit_card_edit_mediator.mm
@@ -103,6 +103,12 @@ #pragma mark - PaymentRequestEditViewControllerDataSource +- (NSString*)title { + // TODO(crbug.com/602666): Title varies depending on the missing fields. + return _creditCard ? l10n_util::GetNSString(IDS_PAYMENTS_EDIT_CARD) + : l10n_util::GetNSString(IDS_PAYMENTS_ADD_CARD_LABEL); +} + - (CollectionViewItem*)headerItem { if (_creditCard && !autofill::IsCreditCardLocal(*_creditCard)) { // Return an item that identifies the server card being edited.
diff --git a/ios/chrome/browser/ui/payments/payment_method_selection_coordinator.mm b/ios/chrome/browser/ui/payments/payment_method_selection_coordinator.mm index f4e2771..8e6f02b 100644 --- a/ios/chrome/browser/ui/payments/payment_method_selection_coordinator.mm +++ b/ios/chrome/browser/ui/payments/payment_method_selection_coordinator.mm
@@ -61,8 +61,6 @@ initWithPaymentRequest:self.paymentRequest]; self.viewController = [[PaymentRequestSelectorViewController alloc] init]; - self.viewController.title = - l10n_util::GetNSString(IDS_PAYMENTS_METHOD_OF_PAYMENT_LABEL); self.viewController.delegate = self; self.viewController.dataSource = self.mediator; [self.viewController loadModel];
diff --git a/ios/chrome/browser/ui/payments/payment_method_selection_mediator.mm b/ios/chrome/browser/ui/payments/payment_method_selection_mediator.mm index 3a202ea9..f1362e3a 100644 --- a/ios/chrome/browser/ui/payments/payment_method_selection_mediator.mm +++ b/ios/chrome/browser/ui/payments/payment_method_selection_mediator.mm
@@ -69,6 +69,10 @@ return YES; } +- (NSString*)title { + return l10n_util::GetNSString(IDS_PAYMENTS_METHOD_OF_PAYMENT_LABEL); +} + - (CollectionViewItem*)headerItem { base::string16 headerText = payments::GetCardTypesAreAcceptedText( _paymentRequest->supported_card_types_set());
diff --git a/ios/chrome/browser/ui/payments/payment_request_edit_view_controller.mm b/ios/chrome/browser/ui/payments/payment_request_edit_view_controller.mm index 5b5acb4..bd7fac9 100644 --- a/ios/chrome/browser/ui/payments/payment_request_edit_view_controller.mm +++ b/ios/chrome/browser/ui/payments/payment_request_edit_view_controller.mm
@@ -226,6 +226,8 @@ [super loadModel]; CollectionViewModel* model = self.collectionViewModel; + self.title = [_dataSource title]; + [self.pickerViews removeAllObjects]; CollectionViewItem* headerItem = [_dataSource headerItem];
diff --git a/ios/chrome/browser/ui/payments/payment_request_edit_view_controller_data_source.h b/ios/chrome/browser/ui/payments/payment_request_edit_view_controller_data_source.h index 9393b6e..e6ade2bb 100644 --- a/ios/chrome/browser/ui/payments/payment_request_edit_view_controller_data_source.h +++ b/ios/chrome/browser/ui/payments/payment_request_edit_view_controller_data_source.h
@@ -24,6 +24,9 @@ // The current state of the view controller. @property(nonatomic, assign) EditViewControllerState state; +// The title to display in the view controller. +- (NSString*)title; + // Returns the header item. May be nil. - (CollectionViewItem*)headerItem;
diff --git a/ios/chrome/browser/ui/payments/payment_request_edit_view_controller_unittest.mm b/ios/chrome/browser/ui/payments/payment_request_edit_view_controller_unittest.mm index b215901..d83a968a 100644 --- a/ios/chrome/browser/ui/payments/payment_request_edit_view_controller_unittest.mm +++ b/ios/chrome/browser/ui/payments/payment_request_edit_view_controller_unittest.mm
@@ -22,6 +22,10 @@ #error "This file requires ARC support." #endif +namespace { +NSString* const kTestTitle = @"title"; +} // namespace + @interface TestPaymentRequestEditMediator : NSObject<PaymentRequestEditViewControllerDataSource> @@ -34,6 +38,10 @@ @synthesize state = _state; @synthesize consumer = _consumer; +- (NSString*)title { + return kTestTitle; +} + - (CollectionViewItem*)headerItem { return [[CollectionViewTextItem alloc] init]; } @@ -101,6 +109,7 @@ CheckController(); [GetPaymentRequestEditViewController() loadModel]; + CheckTitle(kTestTitle); // There is one section containing the header item, In addition to that, there // is one section for every form field (there are three fields in total) and
diff --git a/ios/chrome/browser/ui/payments/payment_request_selector_view_controller.mm b/ios/chrome/browser/ui/payments/payment_request_selector_view_controller.mm index 0db5251..91fc0ff4 100644 --- a/ios/chrome/browser/ui/payments/payment_request_selector_view_controller.mm +++ b/ios/chrome/browser/ui/payments/payment_request_selector_view_controller.mm
@@ -115,6 +115,8 @@ [super loadModel]; CollectionViewModel* model = self.collectionViewModel; + self.title = [_dataSource title]; + // Set up trailing (edit or done) button. if (self.dataSource.state == PaymentRequestSelectorStateNormal && [self.dataSource allowsEditMode]) {
diff --git a/ios/chrome/browser/ui/payments/payment_request_selector_view_controller_data_source.h b/ios/chrome/browser/ui/payments/payment_request_selector_view_controller_data_source.h index 99a1acd..b2c24fe 100644 --- a/ios/chrome/browser/ui/payments/payment_request_selector_view_controller_data_source.h +++ b/ios/chrome/browser/ui/payments/payment_request_selector_view_controller_data_source.h
@@ -35,6 +35,9 @@ // Whether or not the view controller supports edit mode. - (BOOL)allowsEditMode; +// The title to display in the view controller. +- (NSString*)title; + // The header item to display in the collection, if any. - (CollectionViewItem*)headerItem;
diff --git a/ios/chrome/browser/ui/payments/payment_request_selector_view_controller_unittest.mm b/ios/chrome/browser/ui/payments/payment_request_selector_view_controller_unittest.mm index f0b8b26..3d0ff22 100644 --- a/ios/chrome/browser/ui/payments/payment_request_selector_view_controller_unittest.mm +++ b/ios/chrome/browser/ui/payments/payment_request_selector_view_controller_unittest.mm
@@ -15,6 +15,10 @@ #error "This file requires ARC support." #endif +namespace { +NSString* const kTestTitle = @"title"; +} // namespace + @interface TestPaymentRequestSelectorMediator : NSObject<PaymentRequestSelectorViewControllerDataSource> @@ -46,6 +50,10 @@ return NO; } +- (NSString*)title { + return kTestTitle; +} + - (CollectionViewItem*)headerItem { return [[CollectionViewItem alloc] init]; } @@ -89,6 +97,7 @@ CheckController(); [GetPaymentRequestSelectorViewController() loadModel]; + CheckTitle(kTestTitle); ASSERT_EQ(1, NumberOfSections()); // One header item, two selectable items, and one add button.
diff --git a/ios/chrome/browser/ui/payments/shipping_address_selection_coordinator.mm b/ios/chrome/browser/ui/payments/shipping_address_selection_coordinator.mm index e25258d..001a03e 100644 --- a/ios/chrome/browser/ui/payments/shipping_address_selection_coordinator.mm +++ b/ios/chrome/browser/ui/payments/shipping_address_selection_coordinator.mm
@@ -9,7 +9,6 @@ #include "base/logging.h" #include "base/strings/sys_string_conversions.h" #include "components/autofill/core/browser/autofill_profile.h" -#include "components/payments/core/strings_util.h" #include "ios/chrome/browser/payments/payment_request.h" #import "ios/chrome/browser/payments/payment_request_util.h" #import "ios/chrome/browser/ui/payments/cells/autofill_profile_item.h" @@ -21,10 +20,6 @@ #endif namespace { -using ::payment_request_util::GetShippingAddressSelectorErrorMessage; -using ::payments::GetShippingAddressSectionString; -using ::payments::GetShippingAddressSelectorInfoMessage; - // The delay in nano seconds before notifying the delegate of the selection. const int64_t kDelegateNotificationDelayInNanoSeconds = 0.2 * NSEC_PER_SEC; } // namespace @@ -63,15 +58,8 @@ - (void)start { self.mediator = [[ShippingAddressSelectionMediator alloc] initWithPaymentRequest:self.paymentRequest]; - self.mediator.headerText = - self.paymentRequest->shipping_options().empty() - ? base::SysUTF16ToNSString(GetShippingAddressSelectorInfoMessage( - self.paymentRequest->shipping_type())) - : nil; self.viewController = [[PaymentRequestSelectorViewController alloc] init]; - self.viewController.title = base::SysUTF16ToNSString( - GetShippingAddressSectionString(self.paymentRequest->shipping_type())); self.viewController.delegate = self; self.viewController.dataSource = self.mediator; [self.viewController loadModel]; @@ -96,8 +84,6 @@ self.viewController.view.userInteractionEnabled = YES; DCHECK(self.paymentRequest); - self.mediator.headerText = - GetShippingAddressSelectorErrorMessage(*self.paymentRequest); self.mediator.state = PaymentRequestSelectorStateError; [self.viewController loadModel]; [self.viewController.collectionView reloadData];
diff --git a/ios/chrome/browser/ui/payments/shipping_address_selection_mediator.h b/ios/chrome/browser/ui/payments/shipping_address_selection_mediator.h index bcec5314..882b0f0 100644 --- a/ios/chrome/browser/ui/payments/shipping_address_selection_mediator.h +++ b/ios/chrome/browser/ui/payments/shipping_address_selection_mediator.h
@@ -15,10 +15,6 @@ @interface ShippingAddressSelectionMediator : NSObject<PaymentRequestSelectorViewControllerDataSource> -// The text to display in the header item. If nil, the header item will also be -// nil. -@property(nonatomic, copy) NSString* headerText; - // Redefined to be read-write. @property(nonatomic, readwrite, assign) PaymentRequestSelectorState state;
diff --git a/ios/chrome/browser/ui/payments/shipping_address_selection_mediator.mm b/ios/chrome/browser/ui/payments/shipping_address_selection_mediator.mm index 086c2d3a..a2bbfc1 100644 --- a/ios/chrome/browser/ui/payments/shipping_address_selection_mediator.mm +++ b/ios/chrome/browser/ui/payments/shipping_address_selection_mediator.mm
@@ -8,6 +8,7 @@ #include "base/strings/sys_string_conversions.h" #include "components/autofill/core/browser/autofill_profile.h" +#include "components/payments/core/strings_util.h" #include "components/strings/grit/components_strings.h" #include "ios/chrome/browser/payments/payment_request.h" #import "ios/chrome/browser/payments/payment_request_util.h" @@ -22,6 +23,9 @@ #endif namespace { +using ::payments::GetShippingAddressSectionString; +using ::payments::GetShippingAddressSelectorInfoMessage; +using ::payment_request_util::GetShippingAddressSelectorErrorMessage; using ::payment_request_util::GetAddressNotificationLabelFromAutofillProfile; using ::payment_request_util::GetNameLabelFromAutofillProfile; using ::payment_request_util::GetPhoneNumberLabelFromAutofillProfile; @@ -42,7 +46,6 @@ @implementation ShippingAddressSelectionMediator -@synthesize headerText = _headerText; @synthesize state = _state; @synthesize selectedItemIndex = _selectedItemIndex; @synthesize paymentRequest = _paymentRequest; @@ -59,18 +62,34 @@ return self; } +- (NSString*)getHeaderText { + if (self.state == PaymentRequestSelectorStateError) { + return GetShippingAddressSelectorErrorMessage(*self.paymentRequest); + } else { + return self.paymentRequest->shipping_options().empty() + ? base::SysUTF16ToNSString(GetShippingAddressSelectorInfoMessage( + self.paymentRequest->shipping_type())) + : nil; + } +} + #pragma mark - PaymentRequestSelectorViewControllerDataSource - (BOOL)allowsEditMode { return YES; } +- (NSString*)title { + return base::SysUTF16ToNSString( + GetShippingAddressSectionString(self.paymentRequest->shipping_type())); +} + - (CollectionViewItem*)headerItem { - if (!self.headerText.length) + if (![self getHeaderText].length) return nil; PaymentsTextItem* headerItem = [[PaymentsTextItem alloc] init]; - headerItem.text = self.headerText; + headerItem.text = [self getHeaderText]; if (self.state == PaymentRequestSelectorStateError) headerItem.image = NativeImage(IDR_IOS_PAYMENTS_WARNING); return headerItem;
diff --git a/ios/chrome/browser/ui/payments/shipping_option_selection_coordinator.mm b/ios/chrome/browser/ui/payments/shipping_option_selection_coordinator.mm index d81b2af..9351689e 100644 --- a/ios/chrome/browser/ui/payments/shipping_option_selection_coordinator.mm +++ b/ios/chrome/browser/ui/payments/shipping_option_selection_coordinator.mm
@@ -6,7 +6,6 @@ #include "base/logging.h" #include "base/strings/sys_string_conversions.h" -#include "components/payments/core/strings_util.h" #include "ios/chrome/browser/payments/payment_request.h" #import "ios/chrome/browser/payments/payment_request_util.h" #include "ios/chrome/browser/ui/payments/shipping_option_selection_mediator.h" @@ -18,7 +17,6 @@ namespace { using ::payment_request_util::GetShippingOptionSelectorErrorMessage; -using ::payments::GetShippingOptionSectionString; // The delay in nano seconds before notifying the delegate of the selection. const int64_t kDelegateNotificationDelayInNanoSeconds = 0.2 * NSEC_PER_SEC; @@ -52,8 +50,6 @@ initWithPaymentRequest:self.paymentRequest]; self.viewController = [[PaymentRequestSelectorViewController alloc] init]; - self.viewController.title = base::SysUTF16ToNSString( - GetShippingOptionSectionString(self.paymentRequest->shipping_type())); self.viewController.delegate = self; self.viewController.dataSource = self.mediator; [self.viewController loadModel];
diff --git a/ios/chrome/browser/ui/payments/shipping_option_selection_mediator.mm b/ios/chrome/browser/ui/payments/shipping_option_selection_mediator.mm index e3bcaa20..cd59363 100644 --- a/ios/chrome/browser/ui/payments/shipping_option_selection_mediator.mm +++ b/ios/chrome/browser/ui/payments/shipping_option_selection_mediator.mm
@@ -9,6 +9,7 @@ #include "base/strings/sys_string_conversions.h" #include "base/strings/utf_string_conversions.h" #include "components/payments/core/currency_formatter.h" +#include "components/payments/core/strings_util.h" #include "ios/chrome/browser/payments/payment_request.h" #import "ios/chrome/browser/ui/payments/cells/payments_text_item.h" #include "ios/chrome/browser/ui/uikit_ui_util.h" @@ -19,6 +20,10 @@ #error "This file requires ARC support." #endif +namespace { +using payments::GetShippingOptionSectionString; +} // namespace + @interface ShippingOptionSelectionMediator () // The PaymentRequest object owning an instance of web::PaymentRequest as @@ -59,6 +64,11 @@ return NO; } +- (NSString*)title { + return base::SysUTF16ToNSString( + GetShippingOptionSectionString(self.paymentRequest->shipping_type())); +} + - (CollectionViewItem*)headerItem { if (!self.headerText.length) return nil;
diff --git a/ios/chrome/test/BUILD.gn b/ios/chrome/test/BUILD.gn index 4d7a12fc..a90c20f 100644 --- a/ios/chrome/test/BUILD.gn +++ b/ios/chrome/test/BUILD.gn
@@ -143,7 +143,6 @@ "//ios/chrome/browser/language:unit_tests", "//ios/chrome/browser/metrics:unit_tests", "//ios/chrome/browser/metrics:unit_tests_internal", - "//ios/chrome/browser/native_app_launcher:unit_tests", "//ios/chrome/browser/net:unit_tests", "//ios/chrome/browser/omaha:unit_tests", "//ios/chrome/browser/passwords:unit_tests",
diff --git a/ios/showcase/payments/sc_payments_editor_coordinator.mm b/ios/showcase/payments/sc_payments_editor_coordinator.mm index 1d4ca68e..40a8c8ee 100644 --- a/ios/showcase/payments/sc_payments_editor_coordinator.mm +++ b/ios/showcase/payments/sc_payments_editor_coordinator.mm
@@ -100,6 +100,10 @@ #pragma mark - PaymentRequestEditViewControllerDataSource +- (NSString*)title { + return nil; +} + - (CollectionViewItem*)headerItem { return nil; }
diff --git a/ios/showcase/payments/sc_payments_selector_coordinator.mm b/ios/showcase/payments/sc_payments_selector_coordinator.mm index bcb25ce..c41441a5 100644 --- a/ios/showcase/payments/sc_payments_selector_coordinator.mm +++ b/ios/showcase/payments/sc_payments_selector_coordinator.mm
@@ -74,6 +74,10 @@ return NO; } +- (NSString*)title { + return @"Title"; +} + - (CollectionViewItem*)headerItem { return [self createItemWithText:@"Header item"]; }
diff --git a/ios/web/web_state/navigation_callbacks_inttest.mm b/ios/web/web_state/navigation_callbacks_inttest.mm index ec7867d..9df911e 100644 --- a/ios/web/web_state/navigation_callbacks_inttest.mm +++ b/ios/web/web_state/navigation_callbacks_inttest.mm
@@ -87,15 +87,9 @@ EXPECT_FALSE((*context)->GetError()); ASSERT_FALSE((*context)->GetResponseHeaders()); ASSERT_TRUE(web_state->IsLoading()); - // TODO(crbug.com/676129): Reload does not create a pending item. Remove this - // workaround once the bug is fixed. - if (!ui::PageTransitionTypeIncludingQualifiersIs( - ui::PageTransition::PAGE_TRANSITION_RELOAD, - (*context)->GetPageTransition())) { - NavigationManager* navigation_manager = web_state->GetNavigationManager(); - NavigationItem* item = navigation_manager->GetPendingItem(); - EXPECT_EQ(url, item->GetURL()); - } + NavigationManager* navigation_manager = web_state->GetNavigationManager(); + NavigationItem* item = navigation_manager->GetPendingItem(); + EXPECT_EQ(url, item->GetURL()); } // Verifies correctness of |NavigationContext| (|arg0|) for navigations via POST @@ -217,9 +211,8 @@ EXPECT_FALSE((*context)->IsSameDocument()); EXPECT_FALSE((*context)->GetError()); EXPECT_FALSE((*context)->GetResponseHeaders()); - // TODO(crbug.com/676129): Reload does not create a pending item. Check - // pending item once the bug is fixed. - EXPECT_FALSE(web_state->GetNavigationManager()->GetPendingItem()); + EXPECT_EQ(web_state->GetNavigationManager()->GetPendingItem(), + web_state->GetNavigationManager()->GetLastCommittedItem()); } // Verifies correctness of |NavigationContext| (|arg0|) for reload navigation
diff --git a/ios/web/web_state/ui/crw_web_controller.mm b/ios/web/web_state/ui/crw_web_controller.mm index b08853ea..22cf740 100644 --- a/ios/web/web_state/ui/crw_web_controller.mm +++ b/ios/web/web_state/ui/crw_web_controller.mm
@@ -1520,11 +1520,18 @@ // Typically on PAGE_TRANSITION_CLIENT_REDIRECT. [[self sessionController] updatePendingItem:requestURL]; } else { - // A new session history entry needs to be created. - self.navigationManagerImpl->AddPendingItem( - requestURL, referrer, transition, - web::NavigationInitiationType::RENDERER_INITIATED, - web::NavigationManager::UserAgentOverrideOption::INHERIT); + // If this is a reload then there no need to create a new pending item, + // instead update the pending item to the last committed item. + if (PageTransitionCoreTypeIs(transition, ui::PAGE_TRANSITION_RELOAD)) { + self.sessionController.pendingItemIndex = + self.sessionController.lastCommittedItemIndex; + } else { + // A new session history entry needs to be created. + self.navigationManagerImpl->AddPendingItem( + requestURL, referrer, transition, + web::NavigationInitiationType::RENDERER_INITIATED, + web::NavigationManager::UserAgentOverrideOption::INHERIT); + } } std::unique_ptr<web::NavigationContextImpl> context = web::NavigationContextImpl::CreateNavigationContext( @@ -1979,6 +1986,11 @@ BOOL isChromeScheme = web::GetWebClient()->IsAppSpecificURL(currentNavigationURL); + // Since this is implicit reload, no new pending item should be created, set + // the pending item index to the last committed item. + self.sessionController.pendingItemIndex = + self.sessionController.lastCommittedItemIndex; + // Don't immediately load the web page if in overlay mode. Always load if // native. if (isChromeScheme || !_overlayPreviewMode) { @@ -2020,6 +2032,10 @@ _lastUserInteraction.reset(); base::RecordAction(UserMetricsAction("Reload")); GURL url = self.currentNavItem->GetURL(); + // Reloading shouldn't create create a new pending item, instead set the + // pending item index to the last committed item. + self.sessionController.pendingItemIndex = + self.sessionController.lastCommittedItemIndex; if ([self shouldLoadURLInNativeView:url]) { std::unique_ptr<web::NavigationContextImpl> navigationContext = [self registerLoadRequestForURL:url
diff --git a/net/socket/client_socket_pool_base.cc b/net/socket/client_socket_pool_base.cc index 9a2d752..c87d8e5 100644 --- a/net/socket/client_socket_pool_base.cc +++ b/net/socket/client_socket_pool_base.cc
@@ -1112,9 +1112,6 @@ NetLogEventType::SOCKET_POOL_REUSED_AN_EXISTING_SOCKET, NetLog::IntCallback("idle_ms", static_cast<int>(idle_time.InMilliseconds()))); - - UMA_HISTOGRAM_COUNTS_1000("Net.Socket.IdleSocketReuseTime", - idle_time.InSeconds()); } if (reuse_type != ClientSocketHandle::UNUSED) {
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json index f108173..45851ef5 100644 --- a/testing/buildbot/chromium.chromiumos.json +++ b/testing/buildbot/chromium.chromiumos.json
@@ -268,18 +268,6 @@ "test": "latency_unittests" }, { - "args": [ - "--ozone-platform=headless", - "--override-use-software-gl-for-tests", - "--test-launcher-filter-file=../../testing/buildbot/filters/mash.browser_tests.filter" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "hard_timeout": 900 - }, - "test": "mash_browser_tests" - }, - { "swarming": { "can_use_on_swarming_builders": true }, @@ -509,6 +497,12 @@ "swarming": { "can_use_on_swarming_builders": true }, + "test": "angle_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, "test": "app_list_presenter_unittests" }, { @@ -530,6 +524,30 @@ "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 }, @@ -688,7 +706,8 @@ }, { "swarming": { - "can_use_on_swarming_builders": true + "can_use_on_swarming_builders": true, + "shards": 3 }, "test": "interactive_ui_tests" }, @@ -720,12 +739,24 @@ "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" }, { @@ -741,6 +772,18 @@ "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 }, @@ -765,6 +808,21 @@ "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 }, @@ -780,6 +838,12 @@ "swarming": { "can_use_on_swarming_builders": true }, + "test": "printing_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, "test": "remoting_unittests" }, { @@ -861,6 +925,18 @@ "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" }, {
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index e6c0e68..ac5f7c6 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -4199,6 +4199,14 @@ } ] }, + "ClangToTLinux": { + "scripts": [ + { + "name": "check_gn_headers", + "script": "check_gn_headers.py" + } + ] + }, "ClangToTLinux tester": { "gtest_tests": [ {
diff --git a/testing/buildbot/chromium.memory.json b/testing/buildbot/chromium.memory.json index 506864e..f591bd8 100644 --- a/testing/buildbot/chromium.memory.json +++ b/testing/buildbot/chromium.memory.json
@@ -707,18 +707,6 @@ "swarming": { "can_use_on_swarming_builders": true }, - "test": "ash_content_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "ash_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, "test": "aura_unittests" }, { @@ -729,13 +717,6 @@ }, { "swarming": { - "can_use_on_swarming_builders": true, - "shards": 10 - }, - "test": "browser_tests" - }, - { - "swarming": { "can_use_on_swarming_builders": true }, "test": "cacheinvalidation_unittests" @@ -844,13 +825,6 @@ }, { "swarming": { - "can_use_on_swarming_builders": true, - "shards": 2 - }, - "test": "interactive_ui_tests" - }, - { - "swarming": { "can_use_on_swarming_builders": true }, "test": "ipc_tests" @@ -978,13 +952,6 @@ }, { "swarming": { - "can_use_on_swarming_builders": true, - "shards": 2 - }, - "test": "unit_tests" - }, - { - "swarming": { "can_use_on_swarming_builders": true }, "test": "url_unittests"
diff --git a/testing/buildbot/filters/ash_unittests_mus.filter b/testing/buildbot/filters/ash_unittests_mus.filter index dec585b..417488e 100644 --- a/testing/buildbot/filters/ash_unittests_mus.filter +++ b/testing/buildbot/filters/ash_unittests_mus.filter
@@ -1,11 +1,3 @@ -# TODO: fix these. They all timeout. http://crbug.com/734811. --ScreenRotationAnimatorSmoothAnimationTest.OverviewButtonTrayHideAnimationAlwaysCompletes --ScreenRotationAnimatorSmoothAnimationTest.RemoveExternalPrimaryDisplayBeforeSecondCopyCallback --ScreenRotationAnimatorSmoothAnimationTest.RemoveExternalPrimaryDisplayDuringAnimationChangedRootWindow --ScreenRotationAnimatorSmoothAnimationTest.RemoveExternalSecondaryDisplayBeforeSecondCopyCallback --ScreenRotationAnimatorSmoothAnimationTest.RotatesToDifferentRotationWithCopyCallback --ScreenRotationAnimatorSmoothAnimationTest.ShouldRotateAfterRecreateLayers - # TODO: fix these. They fail because DeviceDataManager isn't created. # http://crbug.com/734812. -TrayIMETest.HidesOnA11yEnabled
diff --git a/testing/scripts/check_gn_headers.py b/testing/scripts/check_gn_headers.py index cb2520c3..6530ada7 100755 --- a/testing/scripts/check_gn_headers.py +++ b/testing/scripts/check_gn_headers.py
@@ -44,4 +44,4 @@ 'run': main_run, 'compile_targets': main_compile_targets, } - sys.exit(common.run_script(sys.argv[1:], funcs)) + common.run_script(sys.argv[1:], funcs)
diff --git a/testing/scripts/webview_licenses.py b/testing/scripts/webview_licenses.py deleted file mode 100755 index 255c62e..0000000 --- a/testing/scripts/webview_licenses.py +++ /dev/null
@@ -1,43 +0,0 @@ -#!/usr/bin/env python -# 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. - -import json -import os -import sys - - -import common - - -def main_run(args): - with common.temporary_file() as tempfile_path: - rc = common.run_command([ - os.path.join(common.SRC_DIR, 'android_webview', 'tools', - 'webview_licenses.py'), - 'scan', - '--json', tempfile_path - ]) - - with open(tempfile_path) as f: - results = json.load(f) - - json.dump({ - 'valid': True, - 'failures': results, - }, args.output) - - return rc - - -def main_compile_targets(args): - json.dump([], args.output) - - -if __name__ == '__main__': - funcs = { - 'run': main_run, - 'compile_targets': main_compile_targets, - } - sys.exit(common.run_script(sys.argv[1:], funcs))
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index 7166869..6a8af3f 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -241,12 +241,6 @@ crbug.com/711807 external/wpt/css/CSS2/normal-flow/replaced-intrinsic-002.xht [ Skip ] crbug.com/711807 external/wpt/css/CSS2/normal-flow/width-inherit-001.xht [ Skip ] -#### third_party/WebKit/LayoutTests/external/wpt/css-paint-api -#### Passed: 50 -#### Skipped: 2 -crbug.com/578252 external/wpt/css-paint-api/background-image-tiled.html [ Skip ] -crbug.com/578252 external/wpt/css-paint-api/geometry-background-image-tiled-001.html [ Skip ] - #### third_party/WebKit/LayoutTests/overflow crbug.com/724697 overflow/overflow-basic-002.html [ Failure ] crbug.com/724701 overflow/overflow-basic-004.html [ Failure ] @@ -1660,6 +1654,9 @@ crbug.com/646644 [ Mac10.9 ] http/tests/media/video-buffered-range-contains-currentTime.html [ Failure Timeout ] crbug.com/646644 [ Mac10.9 ] virtual/mojo-loading/http/tests/media/video-buffered-range-contains-currentTime.html [ Failure Timeout ] +crbug.com/743068 [ Mac10.9 ] fast/forms/calendar-picker/calendar-picker-appearance-zoom125.html [ Pass Failure ] +crbug.com/743068 [ Mac10.9 ] fast/forms/calendar-picker/calendar-picker-appearance-zoom200.html [ Pass Failure ] + crbug.com/637930 http/tests/media/video-buffered.html [ Pass Failure ] crbug.com/637930 virtual/mojo-loading/http/tests/media/video-buffered.html [ Pass Failure ]
diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/script-src/script-src-multiple-policies-multiple-hashing-algorithms.html b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/script-src/script-src-multiple-policies-multiple-hashing-algorithms.html new file mode 100644 index 0000000..75ff342 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/script-src/script-src-multiple-policies-multiple-hashing-algorithms.html
@@ -0,0 +1,28 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Multiple policies with different hashing algorithms still work.</title> + <!-- nonces are here just to let all of our scripts run --> + <script nonce="abc" src='/resources/testharness.js'></script> + <script nonce="abc" src='/resources/testharnessreport.js'></script> +</head> +<body> + <script nonce="abc"> + var t = async_test("Test that script executes if allowed by proper hash values"); + document.addEventListener("securitypolicyviolation", t.unreached_func("Should not have triggered a security event")); + var executed = false; + </script> + + <!-- test will fail if this script is not allowed to run --> + <script>executed = true;</script> + + <script nonce="abc"> + t.step(function() { + assert_true(executed); + t.done(); + }); + </script> + + <script nonce="abc" async defer src='../support/checkReport.sub.js?reportExists=false'></script> +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/script-src/script-src-multiple-policies-multiple-hashing-algorithms.html.sub.headers b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/script-src/script-src-multiple-policies-multiple-hashing-algorithms.html.sub.headers new file mode 100644 index 0000000..36203b76 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/script-src/script-src-multiple-policies-multiple-hashing-algorithms.html.sub.headers
@@ -0,0 +1,7 @@ +Expires: Mon, 26 Jul 1997 05:00:00 GMT +Cache-Control: no-store, no-cache, must-revalidate +Cache-Control: post-check=0, pre-check=0, false +Pragma: no-cache +Set-Cookie: script-src-multiple-policies-multiple-hashing-algorithms={{$id:uuid()}}; Path=/content-security-policy/script-src/ +Content-Security-Policy: script-src 'sha256-EpVP4fTImWaRzBRBw/wrdfLhGTe/1U+CaBP1LNeKUIE=' 'nonce-abc'; report-uri ../support/report.py?op=put&reportID={{$id}} +Content-Security-Policy: script-src 'sha384-skw7BVxHbmE2umPGMd1kX+ye6qBeHAb875erPoD8ilKv1LkjKR+WFi7N85ORMdhS' 'nonce-abc'; report-uri ../support/report.py?op=put&reportID={{$id}} \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/script-src/script-src-multiple-policies-one-using-hashing-algorithms.html b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/script-src/script-src-multiple-policies-one-using-hashing-algorithms.html new file mode 100644 index 0000000..34fed6d9 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/script-src/script-src-multiple-policies-one-using-hashing-algorithms.html
@@ -0,0 +1,28 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Multiple policies some using hashes some not using hashes still work.</title> + <!-- nonces are here just to let all of our scripts run --> + <script nonce="abc" src='/resources/testharness.js'></script> + <script nonce="abc" src='/resources/testharnessreport.js'></script> +</head> +<body> + <script nonce="abc"> + var t = async_test("Test that script executes if allowed by proper hash values"); + document.addEventListener("securitypolicyviolation", t.unreached_func("Should not have triggered a security event")); + var executed = false; + </script> + + <!-- test will fail if this script is not allowed to run --> + <script>executed = true;</script> + + <script nonce="abc"> + t.step(function() { + assert_true(executed); + t.done(); + }); + </script> + + <script nonce="abc" async defer src='../support/checkReport.sub.js?reportExists=false'></script> +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/script-src/script-src-multiple-policies-one-using-hashing-algorithms.html.sub.headers b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/script-src/script-src-multiple-policies-one-using-hashing-algorithms.html.sub.headers new file mode 100644 index 0000000..114c560b2 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/script-src/script-src-multiple-policies-one-using-hashing-algorithms.html.sub.headers
@@ -0,0 +1,7 @@ +Expires: Mon, 26 Jul 1997 05:00:00 GMT +Cache-Control: no-store, no-cache, must-revalidate +Cache-Control: post-check=0, pre-check=0, false +Pragma: no-cache +Set-Cookie: script-src-multiple-policies-multiple-hashing-algorithms-work={{$id:uuid()}}; Path=/content-security-policy/script-src/ +Content-Security-Policy: script-src 'sha256-EpVP4fTImWaRzBRBw/wrdfLhGTe/1U+CaBP1LNeKUIE=' 'nonce-abc'; report-uri ../support/report.py?op=put&reportID={{$id}} +Content-Security-Policy: script-src 'self' 'unsafe-inline'; report-uri ../support/report.py?op=put&reportID={{$id}} \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/script-src/script-src-report-only-policy-works-with-external-hash-policy.html b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/script-src/script-src-report-only-policy-works-with-external-hash-policy.html new file mode 100644 index 0000000..f0f7bcb --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/script-src/script-src-report-only-policy-works-with-external-hash-policy.html
@@ -0,0 +1,23 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>A report-only policy that does not allow a script should not affect an enforcing policy using hashes.</title> + <!-- nonces are here just to let all of our scripts run --> + <script nonce="abc" src='/resources/testharness.js'></script> + <script nonce="abc" src='/resources/testharnessreport.js'></script> +</head> +<body> + <script nonce="abc"> + var externalRan = false; + </script> + <script src='./externalScript.js' + integrity="sha256-wIc3KtqOuTFEu6t17sIBuOswgkV406VJvhSk79Gw6U0="></script> + <script nonce="abc"> + test(function() { + assert_true(externalRan, 'External script ran.'); + }, 'External script in a script tag with matching SRI hash should run.'); + </script> + + <script nonce="abc" async defer src='../support/checkReport.sub.js?reportField=violated-directive&reportValue=script-src%20%27nonce-abc%27'></script> +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/script-src/script-src-report-only-policy-works-with-external-hash-policy.html.sub.headers b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/script-src/script-src-report-only-policy-works-with-external-hash-policy.html.sub.headers new file mode 100644 index 0000000..0ccfd50 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/script-src/script-src-report-only-policy-works-with-external-hash-policy.html.sub.headers
@@ -0,0 +1,7 @@ +Expires: Mon, 26 Jul 1997 05:00:00 GMT +Cache-Control: no-store, no-cache, must-revalidate +Cache-Control: post-check=0, pre-check=0, false +Pragma: no-cache +Set-Cookie: script-src-report-only-policy-works-with-external-hash-policy={{$id:uuid()}}; Path=/content-security-policy/script-src/ +Content-Security-Policy: script-src 'sha256-wIc3KtqOuTFEu6t17sIBuOswgkV406VJvhSk79Gw6U0=' 'nonce-abc' +Content-Security-Policy-Report-Only: script-src 'nonce-abc'; report-uri ../support/report.py?op=put&reportID={{$id}} \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/script-src/script-src-report-only-policy-works-with-hash-policy.html b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/script-src/script-src-report-only-policy-works-with-hash-policy.html new file mode 100644 index 0000000..82a88791 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/script-src/script-src-report-only-policy-works-with-hash-policy.html
@@ -0,0 +1,33 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>A report-only policy that does not allow a script should not affect an enforcing policy using hashes.</title> + <!-- nonces are here just to let all of our scripts run --> + <script nonce="abc" src='/resources/testharness.js'></script> + <script nonce="abc" src='/resources/testharnessreport.js'></script> +</head> +<body> + <script nonce="abc"> + var t = async_test("Test that script executes if allowed by proper hash values"); + var t_spv = async_test("Test that the securitypolicyviolation event is fired"); + document.addEventListener("securitypolicyviolation", t_spv.step_func_done(function(e) { + assert_equals(e.violatedDirective, "script-src"); + assert_equals(e.disposition, "report"); + assert_equals(e.blockedURI, "inline"); + })); + var executed = false; + </script> + + <!-- test will fail if this script is not allowed to run --> + <script>executed = true;</script> + + <script nonce="abc"> + t.step(function() { + assert_true(executed); + t.done(); + }); + </script> + + <script nonce="abc" async defer src='../support/checkReport.sub.js?reportField=violated-directive&reportValue=script-src%20%27nonce-abc%27'></script> +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/script-src/script-src-report-only-policy-works-with-hash-policy.html.sub.headers b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/script-src/script-src-report-only-policy-works-with-hash-policy.html.sub.headers new file mode 100644 index 0000000..eaf175a --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/script-src/script-src-report-only-policy-works-with-hash-policy.html.sub.headers
@@ -0,0 +1,7 @@ +Expires: Mon, 26 Jul 1997 05:00:00 GMT +Cache-Control: no-store, no-cache, must-revalidate +Cache-Control: post-check=0, pre-check=0, false +Pragma: no-cache +Set-Cookie: script-src-report-only-policy-works-with-hash-policy={{$id:uuid()}}; Path=/content-security-policy/script-src/ +Content-Security-Policy: script-src 'sha256-EpVP4fTImWaRzBRBw/wrdfLhGTe/1U+CaBP1LNeKUIE=' 'nonce-abc' +Content-Security-Policy-Report-Only: script-src 'nonce-abc'; report-uri ../support/report.py?op=put&reportID={{$id}} \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/style-src/style-src-multiple-policies-multiple-hashing-algorithms.html b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/style-src/style-src-multiple-policies-multiple-hashing-algorithms.html new file mode 100644 index 0000000..1575cd6 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/style-src/style-src-multiple-policies-multiple-hashing-algorithms.html
@@ -0,0 +1,19 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Multiple policies with different hashing algorithms still work.</title> + <script src='/resources/testharness.js'></script> + <script src='/resources/testharnessreport.js'></script> +</head> +<body> + <script> + var t = async_test("Test that style loads if allowed by proper hash values"); + document.addEventListener("securitypolicyviolation", t.unreached_func("Should not have triggered a security event")); + </script> + + <!-- test will time out if this style is not allowed to load --> + <style onload="t.done();" onerror="t.unreached_func('Should have loaded the style');">p {color:blue;}</style> + + <script async defer src='../support/checkReport.sub.js?reportExists=false'></script> +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/style-src/style-src-multiple-policies-multiple-hashing-algorithms.html.sub.headers b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/style-src/style-src-multiple-policies-multiple-hashing-algorithms.html.sub.headers new file mode 100644 index 0000000..8d83a34 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/style-src/style-src-multiple-policies-multiple-hashing-algorithms.html.sub.headers
@@ -0,0 +1,7 @@ +Expires: Mon, 26 Jul 1997 05:00:00 GMT +Cache-Control: no-store, no-cache, must-revalidate +Cache-Control: post-check=0, pre-check=0, false +Pragma: no-cache +Set-Cookie: style-src-multiple-policies-multiple-hashing-algorithms={{$id:uuid()}}; Path=/content-security-policy/style-src/ +Content-Security-Policy: style-src 'sha256-rB6kiow2O3eFUeTNyyLeK3wV0+l7vNB90J1aqllKvjg='; script-src 'unsafe-inline' 'self'; report-uri ../support/report.py?op=put&reportID={{$id}} +Content-Security-Policy: style-src 'sha384-DAShdG5sejEaOdWfT+TQMRP5mHssKiUNjFggNnElIvIoj048XQlacVRs+za2AM1a'; script-src 'unsafe-inline' 'self'; report-uri ../support/report.py?op=put&reportID={{$id}} \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css-paint-api/background-image-tiled-ref.html b/third_party/WebKit/LayoutTests/external/wpt/css-paint-api/background-image-tiled-ref.html index a0151d8..fe12f16 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/css-paint-api/background-image-tiled-ref.html +++ b/third_party/WebKit/LayoutTests/external/wpt/css-paint-api/background-image-tiled-ref.html
@@ -5,12 +5,9 @@ <canvas id ="two" width="100" height="100"></canvas> <script> function drawCircle(ctx, geom) { - var x = geom.width / 2; - var y = geom.height / 2; - ctx.fillStyle = 'green'; ctx.beginPath(); - ctx.ellipse(x, y, x - 1, y - 1, 0, 0, 2 * Math.PI); + ctx.rect(0, 0, geom.width, geom.height); ctx.fill(); }
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css-paint-api/background-image-tiled.html b/third_party/WebKit/LayoutTests/external/wpt/css-paint-api/background-image-tiled.html index 95d8c12..0497acf 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/css-paint-api/background-image-tiled.html +++ b/third_party/WebKit/LayoutTests/external/wpt/css-paint-api/background-image-tiled.html
@@ -29,12 +29,9 @@ <script id="code" type="text/worklet"> registerPaint('ellipse', class { paint(ctx, geom) { - var x = geom.width / 2; - var y = geom.height / 2; - ctx.fillStyle = 'green'; ctx.beginPath(); - ctx.ellipse(x, y, x - 1, y - 1, 0, 0, 2 * Math.PI); + ctx.rect(0, 0, geom.width, geom.height); ctx.fill(); } });
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css-paint-api/geometry-background-image-tiled-001-ref.html b/third_party/WebKit/LayoutTests/external/wpt/css-paint-api/geometry-background-image-tiled-001-ref.html index 9f633a9..ce7988f 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/css-paint-api/geometry-background-image-tiled-001-ref.html +++ b/third_party/WebKit/LayoutTests/external/wpt/css-paint-api/geometry-background-image-tiled-001-ref.html
@@ -8,10 +8,8 @@ <script> var canvas = document.getElementById('canvas'); var context = canvas.getContext("2d"); -context.strokeStyle = 'green'; -context.lineWidth = 4; -context.strokeRect(0, 0, 50, 50); -context.strokeRect(50, 0, 50, 50); +context.fillStyle = 'green'; +context.fillRect(0, 0, 100, 50); </script> </body> </html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css-paint-api/geometry-background-image-tiled-001.html b/third_party/WebKit/LayoutTests/external/wpt/css-paint-api/geometry-background-image-tiled-001.html index d2b7e92..5cf8eb7 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/css-paint-api/geometry-background-image-tiled-001.html +++ b/third_party/WebKit/LayoutTests/external/wpt/css-paint-api/geometry-background-image-tiled-001.html
@@ -21,9 +21,10 @@ <script id="code" type="text/worklet"> registerPaint('geometry', class { paint(ctx, geom) { - ctx.strokeStyle = 'green'; - ctx.lineWidth = 4; - ctx.strokeRect(0, 0, geom.width, geom.height); + ctx.fillStyle = 'green'; + ctx.beginPath(); + ctx.rect(0, 0, geom.width, geom.height); + ctx.fill(); } }); </script>
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_on_table_row-expected.html b/third_party/WebKit/LayoutTests/fast/table/backgr_on_table_row-expected.html new file mode 100644 index 0000000..0d1ff60a9 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/table/backgr_on_table_row-expected.html
@@ -0,0 +1,31 @@ +<!DOCTYPE html> +<html> + <head> + <title>Tests background image render for TR</title> + <style> + .selected { + background-repeat: repeat-x; + background-position: top; + background: linear-gradient(to bottom, #C0C0FF, #FFFFFF); + color: black; + } + </style> + </head> + <body> + <table cellspacing="0" cellpadding="0"> + <tr> + <td class="selected">Background set on row.</td> + </tr> + <tr> + <td class="selected">Background set on cell.</td> + </tr> + </table> + <p> + Background images should render the same whether set on the table + row or the table cell. + </p> + <p> + Test passes if backgrounds for the two rows above are identical. + </p> + </body> +</html>
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_on_table_row.html b/third_party/WebKit/LayoutTests/fast/table/backgr_on_table_row.html new file mode 100644 index 0000000..33540a5 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/table/backgr_on_table_row.html
@@ -0,0 +1,31 @@ +<!DOCTYPE html> +<html> + <head> + <title>Tests background image render for TR</title> + <style> + .selected { + background-repeat: repeat-x; + background-position: top; + background: linear-gradient(to bottom, #C0C0FF, #FFFFFF); + color: black; + } + </style> + </head> + <body> + <table cellspacing="0" cellpadding="0"> + <tr class="selected"> + <td>Background set on row.</td> + </tr> + <tr> + <td class="selected">Background set on cell.</td> + </tr> + </table> + <p> + Background images should render the same whether set on the table + row or the table cell. + </p> + <p> + Test passes if backgrounds for the two rows above are identical. + </p> + </body> +</html>
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png index c37aea6..c6c6214 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png Binary files differ
diff --git a/third_party/WebKit/Source/core/BUILD.gn b/third_party/WebKit/Source/core/BUILD.gn index 2087d79..ef3e81c 100644 --- a/third_party/WebKit/Source/core/BUILD.gn +++ b/third_party/WebKit/Source/core/BUILD.gn
@@ -1102,19 +1102,6 @@ foreach(current, targets_generating_sources) { sources += get_target_outputs(current) } - jumbo_excluded_sources = [ - # Same variables as HTMLElementFactory - "$blink_core_output_dir/SVGElementFactory.cpp", - - # Same variables (stringpool_t, stringpool_contents) as CSSValueKeywords - "$blink_core_output_dir/CSSPropertyNames.cpp", - - # Global "using namespace blink" and "using namespace XPath" - "$blink_core_output_dir/XPathGrammar.cpp", - - # Using global "using namespace WTF" - "//third_party/WebKit/Source/bindings/core/v8/custom/V8CSSStyleDeclarationCustom.cpp", - ] public_deps = [ ":all_generators", "//third_party/WebKit/Source/bindings/core/v8:bindings_core_impl",
diff --git a/third_party/WebKit/Source/core/dom/Element.cpp b/third_party/WebKit/Source/core/dom/Element.cpp index e5a9f5cf..a75f292 100644 --- a/third_party/WebKit/Source/core/dom/Element.cpp +++ b/third_party/WebKit/Source/core/dom/Element.cpp
@@ -4166,7 +4166,7 @@ ShadowRootType::kUserAgent) || GetDocument().GetContentSecurityPolicy()->AllowInlineStyle( this, GetDocument().Url(), String(), start_line_number, - new_style_string)) { + new_style_string, ContentSecurityPolicy::InlineType::kBlock)) { SetInlineStyleFromString(new_style_string); }
diff --git a/third_party/WebKit/Source/core/dom/MockScriptElementBase.h b/third_party/WebKit/Source/core/dom/MockScriptElementBase.h index 828e5c2e..9c7ccdb 100644 --- a/third_party/WebKit/Source/core/dom/MockScriptElementBase.h +++ b/third_party/WebKit/Source/core/dom/MockScriptElementBase.h
@@ -43,10 +43,11 @@ MOCK_CONST_METHOD0(HasChildren, bool()); MOCK_CONST_METHOD0(GetNonceForElement, const AtomicString&()); MOCK_CONST_METHOD0(InitiatorName, AtomicString()); - MOCK_METHOD3(AllowInlineScriptForCSP, + MOCK_METHOD4(AllowInlineScriptForCSP, bool(const AtomicString&, const WTF::OrdinalNumber&, - const String&)); + const String&, + ContentSecurityPolicy::InlineType)); MOCK_CONST_METHOD0(GetDocument, Document&()); MOCK_METHOD1(SetScriptElementForBinding, void(HTMLScriptElementOrSVGScriptElement&));
diff --git a/third_party/WebKit/Source/core/dom/ScriptElementBase.h b/third_party/WebKit/Source/core/dom/ScriptElementBase.h index 5b7a651..fd5a299 100644 --- a/third_party/WebKit/Source/core/dom/ScriptElementBase.h +++ b/third_party/WebKit/Source/core/dom/ScriptElementBase.h
@@ -22,6 +22,7 @@ #define ScriptElementBase_h #include "core/CoreExport.h" +#include "core/frame/csp/ContentSecurityPolicy.h" #include "platform/heap/Handle.h" #include "platform/heap/Heap.h" #include "platform/wtf/text/AtomicString.h" @@ -59,7 +60,8 @@ virtual bool AllowInlineScriptForCSP(const AtomicString& nonce, const WTF::OrdinalNumber&, - const String& script_content) = 0; + const String& script_content, + ContentSecurityPolicy::InlineType) = 0; virtual Document& GetDocument() const = 0; virtual void SetScriptElementForBinding( HTMLScriptElementOrSVGScriptElement&) = 0;
diff --git a/third_party/WebKit/Source/core/dom/ScriptLoader.cpp b/third_party/WebKit/Source/core/dom/ScriptLoader.cpp index 067b2a8e..43066d4 100644 --- a/third_party/WebKit/Source/core/dom/ScriptLoader.cpp +++ b/third_party/WebKit/Source/core/dom/ScriptLoader.cpp
@@ -822,17 +822,14 @@ return ExecuteScriptResult::kShouldFireNone; if (!is_external_script_) { - const ContentSecurityPolicy* csp = - element_document->GetContentSecurityPolicy(); bool should_bypass_main_world_csp = - (frame->GetScriptController().ShouldBypassMainWorldCSP()) || - csp->AllowScriptWithHash(script->InlineSourceTextForCSP(), - ContentSecurityPolicy::InlineType::kBlock); + (frame->GetScriptController().ShouldBypassMainWorldCSP()); AtomicString nonce = element_->GetNonceForElement(); if (!should_bypass_main_world_csp && - !element_->AllowInlineScriptForCSP(nonce, start_line_number_, - script->InlineSourceTextForCSP())) { + !element_->AllowInlineScriptForCSP( + nonce, start_line_number_, script->InlineSourceTextForCSP(), + ContentSecurityPolicy::InlineType::kBlock)) { return ExecuteScriptResult::kShouldFireErrorEvent; } }
diff --git a/third_party/WebKit/Source/core/dom/StyleElement.cpp b/third_party/WebKit/Source/core/dom/StyleElement.cpp index 8e883cf..6027697 100644 --- a/third_party/WebKit/Source/core/dom/StyleElement.cpp +++ b/third_party/WebKit/Source/core/dom/StyleElement.cpp
@@ -139,10 +139,9 @@ const ContentSecurityPolicy* csp = document.GetContentSecurityPolicy(); bool passes_content_security_policy_checks = ShouldBypassMainWorldCSP(element) || - csp->AllowStyleWithHash(text, - ContentSecurityPolicy::InlineType::kBlock) || csp->AllowInlineStyle(&element, document.Url(), element.nonce(), - start_position_.line_, text); + start_position_.line_, text, + ContentSecurityPolicy::InlineType::kBlock); // Clearing the current sheet may remove the cache entry so create the new // sheet first
diff --git a/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp b/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp index 4f1744f..8c35c32 100644 --- a/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp +++ b/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp
@@ -420,185 +420,11 @@ return headers; } -template < - bool (CSPDirectiveList::*allowed)(ScriptState* script_state, - SecurityViolationReportingPolicy, - ContentSecurityPolicy::ExceptionStatus, - const String& script_content) const> -bool IsAllowedByAll(const CSPDirectiveListVector& policies, - ScriptState* script_state, - SecurityViolationReportingPolicy reporting_policy, - ContentSecurityPolicy::ExceptionStatus exception_status, - const String& script_content) { - bool is_allowed = true; - for (const auto& policy : policies) { - is_allowed &= (policy.Get()->*allowed)(script_state, reporting_policy, - exception_status, script_content); - } - return is_allowed; -} - -template <bool (CSPDirectiveList::*allowed)(Element*, - const String&, - const String&, - const WTF::OrdinalNumber&, - SecurityViolationReportingPolicy) - const> -bool IsAllowedByAll(const CSPDirectiveListVector& policies, - Element* element, - const String& source, - const String& context_url, - const WTF::OrdinalNumber& context_line, - SecurityViolationReportingPolicy reporting_policy) { - bool is_allowed = true; - for (const auto& policy : policies) { - is_allowed &= (policy.Get()->*allowed)(element, source, context_url, - context_line, reporting_policy); - } - return is_allowed; -} - -template <bool (CSPDirectiveList::*allowed)(Element*, - const String&, - const String&, - const WTF::OrdinalNumber&, - SecurityViolationReportingPolicy, - const String& content) const> -bool IsAllowedByAll(const CSPDirectiveListVector& policies, - Element* element, - const String& context_url, - const String& nonce, - const WTF::OrdinalNumber& context_line, - SecurityViolationReportingPolicy reporting_policy, - const String& content) { - bool is_allowed = true; - for (const auto& policy : policies) { - is_allowed &= (policy.Get()->*allowed)( - element, context_url, nonce, context_line, reporting_policy, content); - } - return is_allowed; -} - -template <bool (CSPDirectiveList::*allowed)(const CSPHashValue&, - ContentSecurityPolicy::InlineType) - const> -bool IsAllowedByAll(const CSPDirectiveListVector& policies, - const CSPHashValue& hash_value, - ContentSecurityPolicy::InlineType type) { - bool is_allowed = true; - for (const auto& policy : policies) - is_allowed &= (policy.Get()->*allowed)(hash_value, type); - return is_allowed; -} - -template <bool (CSPDirectiveList::*allowFromURL)( - const KURL&, - RedirectStatus, - SecurityViolationReportingPolicy) const> -bool IsAllowedByAll(const CSPDirectiveListVector& policies, - const KURL& url, - RedirectStatus redirect_status, - SecurityViolationReportingPolicy reporting_policy, - ContentSecurityPolicy::CheckHeaderType check_header_type) { - if (ContentSecurityPolicy::ShouldBypassContentSecurityPolicy(url)) - return true; - - bool is_allowed = true; - for (const auto& policy : policies) { - if (!CheckHeaderTypeMatches(check_header_type, policy->HeaderType())) - continue; - is_allowed &= - (policy.Get()->*allowFromURL)(url, redirect_status, reporting_policy); - } - - return is_allowed; -} - -template <bool (CSPDirectiveList::*allowFromURLWithNonce)( - const KURL&, - const String& nonce, - RedirectStatus, - SecurityViolationReportingPolicy) const> -bool IsAllowedByAll(const CSPDirectiveListVector& policies, - const KURL& url, - const String& nonce, - RedirectStatus redirect_status, - SecurityViolationReportingPolicy reporting_policy, - ContentSecurityPolicy::CheckHeaderType check_header_type) { - if (ContentSecurityPolicy::ShouldBypassContentSecurityPolicy(url)) - return true; - - bool is_allowed = true; - for (const auto& policy : policies) { - if (!CheckHeaderTypeMatches(check_header_type, policy->HeaderType())) - continue; - is_allowed &= (policy.Get()->*allowFromURLWithNonce)( - url, nonce, redirect_status, reporting_policy); - } - return is_allowed; -} - -template <bool (CSPDirectiveList::*allowFromURLWithNonceAndParser)( - const KURL&, - const String& nonce, - const IntegrityMetadataSet& hashes, - ParserDisposition parser_disposition, - RedirectStatus, - SecurityViolationReportingPolicy) const> -bool IsAllowedByAll(const CSPDirectiveListVector& policies, - const KURL& url, - const String& nonce, - const IntegrityMetadataSet& hashes, - ParserDisposition parser_disposition, - RedirectStatus redirect_status, - SecurityViolationReportingPolicy reporting_policy, - ContentSecurityPolicy::CheckHeaderType check_header_type) { - if (ContentSecurityPolicy::ShouldBypassContentSecurityPolicy(url)) { - // If we're running experimental features, bypass CSP only for - // non-parser-inserted resources whose scheme otherwise bypasses CSP. If - // we're not running experimental features, bypass CSP for all resources - // regardless of parser state. Once we have more data via the - // 'ScriptWithCSPBypassingScheme*' metrics, make a decision about what - // behavior to ship. https://crbug.com/653521 - if (parser_disposition == kNotParserInserted || - !RuntimeEnabledFeatures:: - ExperimentalContentSecurityPolicyFeaturesEnabled()) { - return true; - } - } - - bool is_allowed = true; - for (const auto& policy : policies) { - if (!CheckHeaderTypeMatches(check_header_type, policy->HeaderType())) - continue; - is_allowed &= (policy.Get()->*allowFromURLWithNonceAndParser)( - url, nonce, hashes, parser_disposition, redirect_status, - reporting_policy); - } - return is_allowed; -} - -template <bool (CSPDirectiveList::*allowed)(LocalFrame*, - const KURL&, - SecurityViolationReportingPolicy) - const> -bool IsAllowedByAll(const CSPDirectiveListVector& policies, - LocalFrame* frame, - const KURL& url, - SecurityViolationReportingPolicy reporting_policy) { - bool is_allowed = true; - for (const auto& policy : policies) - is_allowed &= (policy.Get()->*allowed)(frame, url, reporting_policy); - return is_allowed; -} - -template <bool (CSPDirectiveList::*allowed)(const CSPHashValue&, - ContentSecurityPolicy::InlineType) - const> -bool CheckDigest(const String& source, - ContentSecurityPolicy::InlineType type, - uint8_t hash_algorithms_used, - const CSPDirectiveListVector& policies) { +// static +void ContentSecurityPolicy::FillInCSPHashValues( + const String& source, + uint8_t hash_algorithms_used, + Vector<CSPHashValue>& csp_hash_values) { // Any additions or subtractions from this struct should also modify the // respective entries in the kSupportedPrefixes array in // SourceListDirective::parseHash(). @@ -614,7 +440,7 @@ // Only bother normalizing the source/computing digests if there are any // checks to be done. if (hash_algorithms_used == kContentSecurityPolicyHashAlgorithmNone) - return false; + return; StringUTF8Adaptor utf8_source(source); @@ -624,14 +450,37 @@ bool digest_success = ComputeDigest(algorithm_map.algorithm, utf8_source.Data(), utf8_source.length(), digest); - if (digest_success && - IsAllowedByAll<allowed>( - policies, CSPHashValue(algorithm_map.csp_hash_algorithm, digest), - type)) - return true; + if (digest_success) { + csp_hash_values.push_back( + CSPHashValue(algorithm_map.csp_hash_algorithm, digest)); + } } } +} +// static +bool ContentSecurityPolicy::CheckScriptHashAgainstPolicy( + Vector<CSPHashValue>& csp_hash_values, + const Member<CSPDirectiveList>& policy, + InlineType inline_type) { + for (const auto& csp_hash_value : csp_hash_values) { + if (policy->AllowScriptHash(csp_hash_value, inline_type)) { + return true; + } + } + return false; +} + +// static +bool ContentSecurityPolicy::CheckStyleHashAgainstPolicy( + Vector<CSPHashValue>& csp_hash_values, + const Member<CSPDirectiveList>& policy, + InlineType inline_type) { + for (const auto& csp_hash_value : csp_hash_values) { + if (policy->AllowStyleHash(csp_hash_value, inline_type)) { + return true; + } + } return false; } @@ -641,8 +490,12 @@ const String& context_url, const WTF::OrdinalNumber& context_line, SecurityViolationReportingPolicy reporting_policy) const { - return IsAllowedByAll<&CSPDirectiveList::AllowJavaScriptURLs>( - policies_, element, source, context_url, context_line, reporting_policy); + bool is_allowed = true; + for (const auto& policy : policies_) { + is_allowed &= policy->AllowJavaScriptURLs(element, source, context_url, + context_line, reporting_policy); + } + return is_allowed; } bool ContentSecurityPolicy::AllowInlineEventHandler( @@ -653,14 +506,20 @@ SecurityViolationReportingPolicy reporting_policy) const { // Inline event handlers may be whitelisted by hash, if // 'unsafe-hash-attributes' is present in a policy. Check against the digest - // of the |source| first before proceeding on to checking whether inline - // script is allowed. - if (CheckDigest<&CSPDirectiveList::AllowScriptHash>( - source, InlineType::kAttribute, script_hash_algorithms_used_, - policies_)) - return true; - return IsAllowedByAll<&CSPDirectiveList::AllowInlineEventHandlers>( - policies_, element, source, context_url, context_line, reporting_policy); + // of the |source| and also check whether inline script is allowed. + Vector<CSPHashValue> csp_hash_values; + FillInCSPHashValues(source, script_hash_algorithms_used_, csp_hash_values); + + bool is_allowed = true; + for (const auto& policy : policies_) { + is_allowed &= + CheckScriptHashAgainstPolicy(csp_hash_values, policy, + InlineType::kAttribute) || + policy->AllowInlineEventHandlers(element, source, context_url, + context_line, reporting_policy); + } + + return is_allowed; } bool ContentSecurityPolicy::AllowInlineScript( @@ -669,11 +528,23 @@ const String& nonce, const WTF::OrdinalNumber& context_line, const String& script_content, + InlineType inline_type, SecurityViolationReportingPolicy reporting_policy) const { DCHECK(element); - return IsAllowedByAll<&CSPDirectiveList::AllowInlineScript>( - policies_, element, context_url, nonce, context_line, reporting_policy, - script_content); + + Vector<CSPHashValue> csp_hash_values; + FillInCSPHashValues(script_content, script_hash_algorithms_used_, + csp_hash_values); + + bool is_allowed = true; + for (const auto& policy : policies_) { + is_allowed &= + CheckScriptHashAgainstPolicy(csp_hash_values, policy, inline_type) || + policy->AllowInlineScript(element, context_url, nonce, context_line, + reporting_policy, script_content); + } + + return is_allowed; } bool ContentSecurityPolicy::AllowInlineStyle( @@ -682,13 +553,26 @@ const String& nonce, const WTF::OrdinalNumber& context_line, const String& style_content, + InlineType inline_type, SecurityViolationReportingPolicy reporting_policy) const { DCHECK(element); + if (override_inline_style_allowed_) return true; - return IsAllowedByAll<&CSPDirectiveList::AllowInlineStyle>( - policies_, element, context_url, nonce, context_line, reporting_policy, - style_content); + + Vector<CSPHashValue> csp_hash_values; + FillInCSPHashValues(style_content, style_hash_algorithms_used_, + csp_hash_values); + + bool is_allowed = true; + for (const auto& policy : policies_) { + is_allowed &= + CheckStyleHashAgainstPolicy(csp_hash_values, policy, inline_type) || + policy->AllowInlineStyle(element, context_url, nonce, context_line, + reporting_policy, style_content); + } + + return is_allowed; } bool ContentSecurityPolicy::AllowEval( @@ -696,9 +580,12 @@ SecurityViolationReportingPolicy reporting_policy, ContentSecurityPolicy::ExceptionStatus exception_status, const String& script_content) const { - return IsAllowedByAll<&CSPDirectiveList::AllowEval>( - policies_, script_state, reporting_policy, exception_status, - script_content); + bool is_allowed = true; + for (const auto& policy : policies_) { + is_allowed &= policy->AllowEval(script_state, reporting_policy, + exception_status, script_content); + } + return is_allowed; } String ContentSecurityPolicy::EvalDisabledErrorMessage() const { @@ -767,22 +654,29 @@ parser_disposition == kParserInserted ? WebFeature::kScriptWithCSPBypassingSchemeParserInserted : WebFeature::kScriptWithCSPBypassingSchemeNotParserInserted); + + // If we're running experimental features, bypass CSP only for + // non-parser-inserted resources whose scheme otherwise bypasses CSP. If + // we're not running experimental features, bypass CSP for all resources + // regardless of parser state. Once we have more data via the + // 'ScriptWithCSPBypassingScheme*' metrics, make a decision about what + // behavior to ship. https://crbug.com/653521 + if (parser_disposition == kNotParserInserted || + !RuntimeEnabledFeatures:: + ExperimentalContentSecurityPolicyFeaturesEnabled()) { + return true; + } } - return IsAllowedByAll<&CSPDirectiveList::AllowScriptFromSource>( - policies_, url, nonce, hashes, parser_disposition, redirect_status, - reporting_policy, check_header_type); -} -bool ContentSecurityPolicy::AllowScriptWithHash(const String& source, - InlineType type) const { - return CheckDigest<&CSPDirectiveList::AllowScriptHash>( - source, type, script_hash_algorithms_used_, policies_); -} - -bool ContentSecurityPolicy::AllowStyleWithHash(const String& source, - InlineType type) const { - return CheckDigest<&CSPDirectiveList::AllowStyleHash>( - source, type, style_hash_algorithms_used_, policies_); + bool is_allowed = true; + for (const auto& policy : policies_) { + if (!CheckHeaderTypeMatches(check_header_type, policy->HeaderType())) + continue; + is_allowed &= + policy->AllowScriptFromSource(url, nonce, hashes, parser_disposition, + redirect_status, reporting_policy); + } + return is_allowed; } bool ContentSecurityPolicy::AllowRequestWithoutIntegrity( @@ -892,8 +786,18 @@ RedirectStatus redirect_status, SecurityViolationReportingPolicy reporting_policy, CheckHeaderType check_header_type) const { - return IsAllowedByAll<&CSPDirectiveList::AllowObjectFromSource>( - policies_, url, redirect_status, reporting_policy, check_header_type); + if (ShouldBypassContentSecurityPolicy(url)) + return true; + + bool is_allowed = true; + for (const auto& policy : policies_) { + if (!CheckHeaderTypeMatches(check_header_type, policy->HeaderType())) + continue; + is_allowed &= + policy->AllowObjectFromSource(url, redirect_status, reporting_policy); + } + + return is_allowed; } bool ContentSecurityPolicy::AllowFrameFromSource( @@ -901,8 +805,18 @@ RedirectStatus redirect_status, SecurityViolationReportingPolicy reporting_policy, CheckHeaderType check_header_type) const { - return IsAllowedByAll<&CSPDirectiveList::AllowFrameFromSource>( - policies_, url, redirect_status, reporting_policy, check_header_type); + if (ShouldBypassContentSecurityPolicy(url)) + return true; + + bool is_allowed = true; + for (const auto& policy : policies_) { + if (!CheckHeaderTypeMatches(check_header_type, policy->HeaderType())) + continue; + is_allowed &= + policy->AllowFrameFromSource(url, redirect_status, reporting_policy); + } + + return is_allowed; } bool ContentSecurityPolicy::AllowImageFromSource( @@ -912,8 +826,16 @@ CheckHeaderType check_header_type) const { if (ShouldBypassContentSecurityPolicy(url, SchemeRegistry::kPolicyAreaImage)) return true; - return IsAllowedByAll<&CSPDirectiveList::AllowImageFromSource>( - policies_, url, redirect_status, reporting_policy, check_header_type); + + bool is_allowed = true; + for (const auto& policy : policies_) { + if (!CheckHeaderTypeMatches(check_header_type, policy->HeaderType())) + continue; + is_allowed &= + policy->AllowImageFromSource(url, redirect_status, reporting_policy); + } + + return is_allowed; } bool ContentSecurityPolicy::AllowStyleFromSource( @@ -924,9 +846,15 @@ CheckHeaderType check_header_type) const { if (ShouldBypassContentSecurityPolicy(url, SchemeRegistry::kPolicyAreaStyle)) return true; - return IsAllowedByAll<&CSPDirectiveList::AllowStyleFromSource>( - policies_, url, nonce, redirect_status, reporting_policy, - check_header_type); + + bool is_allowed = true; + for (const auto& policy : policies_) { + if (!CheckHeaderTypeMatches(check_header_type, policy->HeaderType())) + continue; + is_allowed &= policy->AllowStyleFromSource(url, nonce, redirect_status, + reporting_policy); + } + return is_allowed; } bool ContentSecurityPolicy::AllowFontFromSource( @@ -934,8 +862,18 @@ RedirectStatus redirect_status, SecurityViolationReportingPolicy reporting_policy, CheckHeaderType check_header_type) const { - return IsAllowedByAll<&CSPDirectiveList::AllowFontFromSource>( - policies_, url, redirect_status, reporting_policy, check_header_type); + if (ShouldBypassContentSecurityPolicy(url)) + return true; + + bool is_allowed = true; + for (const auto& policy : policies_) { + if (!CheckHeaderTypeMatches(check_header_type, policy->HeaderType())) + continue; + is_allowed &= + policy->AllowFontFromSource(url, redirect_status, reporting_policy); + } + + return is_allowed; } bool ContentSecurityPolicy::AllowMediaFromSource( @@ -943,8 +881,18 @@ RedirectStatus redirect_status, SecurityViolationReportingPolicy reporting_policy, CheckHeaderType check_header_type) const { - return IsAllowedByAll<&CSPDirectiveList::AllowMediaFromSource>( - policies_, url, redirect_status, reporting_policy, check_header_type); + if (ShouldBypassContentSecurityPolicy(url)) + return true; + + bool is_allowed = true; + for (const auto& policy : policies_) { + if (!CheckHeaderTypeMatches(check_header_type, policy->HeaderType())) + continue; + is_allowed &= + policy->AllowMediaFromSource(url, redirect_status, reporting_policy); + } + + return is_allowed; } bool ContentSecurityPolicy::AllowConnectToSource( @@ -952,8 +900,18 @@ RedirectStatus redirect_status, SecurityViolationReportingPolicy reporting_policy, CheckHeaderType check_header_type) const { - return IsAllowedByAll<&CSPDirectiveList::AllowConnectToSource>( - policies_, url, redirect_status, reporting_policy, check_header_type); + if (ShouldBypassContentSecurityPolicy(url)) + return true; + + bool is_allowed = true; + for (const auto& policy : policies_) { + if (!CheckHeaderTypeMatches(check_header_type, policy->HeaderType())) + continue; + is_allowed &= + policy->AllowConnectToSource(url, redirect_status, reporting_policy); + } + + return is_allowed; } bool ContentSecurityPolicy::AllowFormAction( @@ -961,8 +919,18 @@ RedirectStatus redirect_status, SecurityViolationReportingPolicy reporting_policy, CheckHeaderType check_header_type) const { - return IsAllowedByAll<&CSPDirectiveList::AllowFormAction>( - policies_, url, redirect_status, reporting_policy, check_header_type); + if (ShouldBypassContentSecurityPolicy(url)) + return true; + + bool is_allowed = true; + for (const auto& policy : policies_) { + if (!CheckHeaderTypeMatches(check_header_type, policy->HeaderType())) + continue; + is_allowed &= + policy->AllowFormAction(url, redirect_status, reporting_policy); + } + + return is_allowed; } bool ContentSecurityPolicy::AllowBaseURI( @@ -971,9 +939,18 @@ SecurityViolationReportingPolicy reporting_policy) const { // `base-uri` isn't affected by 'upgrade-insecure-requests', so we'll check // both report-only and enforce headers here. - return IsAllowedByAll<&CSPDirectiveList::AllowBaseURI>( - policies_, url, redirect_status, reporting_policy, - ContentSecurityPolicy::CheckHeaderType::kCheckAll); + if (ShouldBypassContentSecurityPolicy(url)) + return true; + + bool is_allowed = true; + for (const auto& policy : policies_) { + if (!CheckHeaderTypeMatches(CheckHeaderType::kCheckAll, + policy->HeaderType())) + continue; + is_allowed &= policy->AllowBaseURI(url, redirect_status, reporting_policy); + } + + return is_allowed; } bool ContentSecurityPolicy::AllowWorkerContextFromSource( @@ -986,22 +963,48 @@ // TODO(mkwst): We reverted this. if (Document* document = this->GetDocument()) { UseCounter::Count(*document, WebFeature::kWorkerSubjectToCSP); - if (IsAllowedByAll<&CSPDirectiveList::AllowWorkerFromSource>( - policies_, url, redirect_status, - SecurityViolationReportingPolicy::kSuppressReporting, - check_header_type) && - !IsAllowedByAll<&CSPDirectiveList::AllowScriptFromSource>( - policies_, url, AtomicString(), IntegrityMetadataSet(), - kNotParserInserted, redirect_status, - SecurityViolationReportingPolicy::kSuppressReporting, - check_header_type)) { + bool is_allowed_worker = true; + if (!ShouldBypassContentSecurityPolicy(url)) { + for (const auto& policy : policies_) { + if (!CheckHeaderTypeMatches(check_header_type, policy->HeaderType())) + continue; + is_allowed_worker &= policy->AllowWorkerFromSource( + url, redirect_status, + SecurityViolationReportingPolicy::kSuppressReporting); + } + } + + bool is_allowed_script = true; + + if (!ShouldBypassContentSecurityPolicy(url)) { + for (const auto& policy : policies_) { + if (!CheckHeaderTypeMatches(check_header_type, policy->HeaderType())) + continue; + is_allowed_script &= policy->AllowScriptFromSource( + url, AtomicString(), IntegrityMetadataSet(), kNotParserInserted, + redirect_status, + SecurityViolationReportingPolicy::kSuppressReporting); + } + } + + if (is_allowed_worker && !is_allowed_script) { UseCounter::Count(*document, WebFeature::kWorkerAllowedByChildBlockedByScript); } } - return IsAllowedByAll<&CSPDirectiveList::AllowWorkerFromSource>( - policies_, url, redirect_status, reporting_policy, check_header_type); + if (ShouldBypassContentSecurityPolicy(url)) + return true; + + bool is_allowed = true; + for (const auto& policy : policies_) { + if (!CheckHeaderTypeMatches(check_header_type, policy->HeaderType())) + continue; + is_allowed &= + policy->AllowWorkerFromSource(url, redirect_status, reporting_policy); + } + + return is_allowed; } bool ContentSecurityPolicy::AllowManifestFromSource( @@ -1009,16 +1012,28 @@ RedirectStatus redirect_status, SecurityViolationReportingPolicy reporting_policy, CheckHeaderType check_header_type) const { - return IsAllowedByAll<&CSPDirectiveList::AllowManifestFromSource>( - policies_, url, redirect_status, reporting_policy, check_header_type); + if (ShouldBypassContentSecurityPolicy(url)) + return true; + + bool is_allowed = true; + for (const auto& policy : policies_) { + if (!CheckHeaderTypeMatches(check_header_type, policy->HeaderType())) + continue; + is_allowed &= + policy->AllowManifestFromSource(url, redirect_status, reporting_policy); + } + + return is_allowed; } bool ContentSecurityPolicy::AllowAncestors( LocalFrame* frame, const KURL& url, SecurityViolationReportingPolicy reporting_policy) const { - return IsAllowedByAll<&CSPDirectiveList::AllowAncestors>( - policies_, frame, url, reporting_policy); + bool is_allowed = true; + for (const auto& policy : policies_) + is_allowed &= policy->AllowAncestors(frame, url, reporting_policy); + return is_allowed; } bool ContentSecurityPolicy::IsFrameAncestorsEnforced() const {
diff --git a/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.h b/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.h index 2de91b11..beda3e9 100644 --- a/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.h +++ b/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.h
@@ -270,6 +270,7 @@ const String& nonce, const WTF::OrdinalNumber& context_line, const String& script_content, + InlineType, SecurityViolationReportingPolicy = SecurityViolationReportingPolicy::kReport) const; bool AllowInlineStyle(Element*, @@ -277,6 +278,7 @@ const String& nonce, const WTF::OrdinalNumber& context_line, const String& style_content, + InlineType, SecurityViolationReportingPolicy = SecurityViolationReportingPolicy::kReport) const; @@ -292,18 +294,6 @@ SecurityViolationReportingPolicy::kReport) const; bool IsFrameAncestorsEnforced() const; - // The hash allow functions are guaranteed to not have any side - // effects, including reporting. - // Hash functions check all policies relating to use of a script/style - // with the given hash and return true all CSP policies allow it. - // If these return true, callers can then process the content or - // issue a load and be safe disabling any further CSP checks. - // - // TODO(mkwst): Fold hashes into 'allow{Script,Style}' checks above, just - // as we've done with nonces. https://crbug.com/617065 - bool AllowScriptWithHash(const String& source, InlineType) const; - bool AllowStyleWithHash(const String& source, InlineType) const; - bool AllowRequestWithoutIntegrity( WebURLRequest::RequestContext, const KURL&, @@ -467,6 +457,19 @@ LocalFrame*, const Vector<String>& report_endpoints); + static void FillInCSPHashValues(const String& source, + uint8_t hash_algorithms_used, + Vector<CSPHashValue>& csp_hash_values); + + // checks a vector of csp hashes against policy, probably a good idea + // to use in tandem with FillInCSPHashValues. + static bool CheckScriptHashAgainstPolicy(Vector<CSPHashValue>&, + const Member<CSPDirectiveList>&, + InlineType); + static bool CheckStyleHashAgainstPolicy(Vector<CSPHashValue>&, + const Member<CSPDirectiveList>&, + InlineType); + Member<ExecutionContext> execution_context_; bool override_inline_style_allowed_; CSPDirectiveListVector policies_;
diff --git a/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicyTest.cpp b/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicyTest.cpp index cc56529..974815ff 100644 --- a/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicyTest.cpp +++ b/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicyTest.cpp
@@ -737,9 +737,10 @@ policy->DidReceiveHeader(String("script-src ") + test.policy, kContentSecurityPolicyHeaderTypeEnforce, kContentSecurityPolicyHeaderSourceHTTP); - EXPECT_EQ(test.allowed, policy->AllowInlineScript(element, context_url, - String(test.nonce), - context_line, content)); + EXPECT_EQ(test.allowed, + policy->AllowInlineScript( + element, context_url, String(test.nonce), context_line, + content, ContentSecurityPolicy::InlineType::kBlock)); EXPECT_EQ(expected_reports, policy->violation_reports_sent_.size()); // Enforce 'style-src' @@ -749,8 +750,9 @@ kContentSecurityPolicyHeaderTypeEnforce, kContentSecurityPolicyHeaderSourceHTTP); EXPECT_EQ(test.allowed, - policy->AllowInlineStyle(element, context_url, String(test.nonce), - context_line, content)); + policy->AllowInlineStyle( + element, context_url, String(test.nonce), context_line, + content, ContentSecurityPolicy::InlineType::kBlock)); EXPECT_EQ(expected_reports, policy->violation_reports_sent_.size()); // Report 'script-src' @@ -760,7 +762,8 @@ kContentSecurityPolicyHeaderTypeReport, kContentSecurityPolicyHeaderSourceHTTP); EXPECT_TRUE(policy->AllowInlineScript( - element, context_url, String(test.nonce), context_line, content)); + element, context_url, String(test.nonce), context_line, content, + ContentSecurityPolicy::InlineType::kBlock)); EXPECT_EQ(expected_reports, policy->violation_reports_sent_.size()); // Report 'style-src' @@ -770,7 +773,8 @@ kContentSecurityPolicyHeaderTypeReport, kContentSecurityPolicyHeaderSourceHTTP); EXPECT_TRUE(policy->AllowInlineStyle( - element, context_url, String(test.nonce), context_line, content)); + element, context_url, String(test.nonce), context_line, content, + ContentSecurityPolicy::InlineType::kBlock)); EXPECT_EQ(expected_reports, policy->violation_reports_sent_.size()); } }
diff --git a/third_party/WebKit/Source/core/html/HTMLScriptElement.cpp b/third_party/WebKit/Source/core/html/HTMLScriptElement.cpp index e8db754..2787cca 100644 --- a/third_party/WebKit/Source/core/html/HTMLScriptElement.cpp +++ b/third_party/WebKit/Source/core/html/HTMLScriptElement.cpp
@@ -199,9 +199,11 @@ bool HTMLScriptElement::AllowInlineScriptForCSP( const AtomicString& nonce, const WTF::OrdinalNumber& context_line, - const String& script_content) { + const String& script_content, + ContentSecurityPolicy::InlineType inline_type) { return GetDocument().GetContentSecurityPolicy()->AllowInlineScript( - this, GetDocument().Url(), nonce, context_line, script_content); + this, GetDocument().Url(), nonce, context_line, script_content, + inline_type); } AtomicString HTMLScriptElement::InitiatorName() const {
diff --git a/third_party/WebKit/Source/core/html/HTMLScriptElement.h b/third_party/WebKit/Source/core/html/HTMLScriptElement.h index d9f1a4ca..119e7a5 100644 --- a/third_party/WebKit/Source/core/html/HTMLScriptElement.h +++ b/third_party/WebKit/Source/core/html/HTMLScriptElement.h
@@ -94,7 +94,8 @@ const AtomicString& GetNonceForElement() const override; bool AllowInlineScriptForCSP(const AtomicString& nonce, const WTF::OrdinalNumber&, - const String& script_content) override; + const String& script_content, + ContentSecurityPolicy::InlineType) override; AtomicString InitiatorName() const override; void DispatchLoadEvent() override; void DispatchErrorEvent() override;
diff --git a/third_party/WebKit/Source/core/loader/HttpEquiv.cpp b/third_party/WebKit/Source/core/loader/HttpEquiv.cpp index fe11fe2..01c58a1 100644 --- a/third_party/WebKit/Source/core/loader/HttpEquiv.cpp +++ b/third_party/WebKit/Source/core/loader/HttpEquiv.cpp
@@ -108,6 +108,7 @@ UseCounter::Count(document, WebFeature::kMetaRefresh); if (!document.GetContentSecurityPolicy()->AllowInlineScript( element, NullURL(), "", OrdinalNumber(), "", + ContentSecurityPolicy::InlineType::kBlock, SecurityViolationReportingPolicy::kSuppressReporting)) { UseCounter::Count(document, WebFeature::kMetaRefreshWhenCSPBlocksInlineScript); @@ -127,6 +128,7 @@ UseCounter::Count(document, WebFeature::kMetaSetCookie); if (!document.GetContentSecurityPolicy()->AllowInlineScript( element, NullURL(), "", OrdinalNumber(), "", + ContentSecurityPolicy::InlineType::kBlock, SecurityViolationReportingPolicy::kSuppressReporting)) { UseCounter::Count(document, WebFeature::kMetaSetCookieWhenCSPBlocksInlineScript);
diff --git a/third_party/WebKit/Source/core/paint/BackgroundImageGeometry.cpp b/third_party/WebKit/Source/core/paint/BackgroundImageGeometry.cpp index 5b7a70d..d50de163 100644 --- a/third_party/WebKit/Source/core/paint/BackgroundImageGeometry.cpp +++ b/third_party/WebKit/Source/core/paint/BackgroundImageGeometry.cpp
@@ -656,7 +656,7 @@ } const ImageResourceObserver& BackgroundImageGeometry::ImageClient() const { - return box_; + return coordinate_offset_by_paint_rect_ ? box_ : positioning_box_; } const Document& BackgroundImageGeometry::ImageDocument() const {
diff --git a/third_party/WebKit/Source/core/svg/SVGScriptElement.cpp b/third_party/WebKit/Source/core/svg/SVGScriptElement.cpp index dfce8152..41b555a 100644 --- a/third_party/WebKit/Source/core/svg/SVGScriptElement.cpp +++ b/third_party/WebKit/Source/core/svg/SVGScriptElement.cpp
@@ -137,9 +137,11 @@ bool SVGScriptElement::AllowInlineScriptForCSP( const AtomicString& nonce, const WTF::OrdinalNumber& context_line, - const String& script_content) { + const String& script_content, + ContentSecurityPolicy::InlineType inline_type) { return GetDocument().GetContentSecurityPolicy()->AllowInlineScript( - this, GetDocument().Url(), nonce, context_line, script_content); + this, GetDocument().Url(), nonce, context_line, script_content, + inline_type); } AtomicString SVGScriptElement::InitiatorName() const {
diff --git a/third_party/WebKit/Source/core/svg/SVGScriptElement.h b/third_party/WebKit/Source/core/svg/SVGScriptElement.h index 64d66950..f5469ee3c 100644 --- a/third_party/WebKit/Source/core/svg/SVGScriptElement.h +++ b/third_party/WebKit/Source/core/svg/SVGScriptElement.h
@@ -88,7 +88,8 @@ const AtomicString& GetNonceForElement() const override; bool AllowInlineScriptForCSP(const AtomicString& nonce, const WTF::OrdinalNumber&, - const String& script_content) override; + const String& script_content, + ContentSecurityPolicy::InlineType) override; AtomicString InitiatorName() const override; Document& GetDocument() const override; void DispatchLoadEvent() override;
diff --git a/third_party/WebKit/Source/platform/BUILD.gn b/third_party/WebKit/Source/platform/BUILD.gn index fbd8d97..d1974c0e 100644 --- a/third_party/WebKit/Source/platform/BUILD.gn +++ b/third_party/WebKit/Source/platform/BUILD.gn
@@ -1842,6 +1842,7 @@ "fonts/FontDescriptionTest.cpp", "fonts/FontPlatformDataTest.cpp", "fonts/FontTest.cpp", + "fonts/FontTestUtilities.cpp", "fonts/GenericFontFamilySettingsTest.cpp", "fonts/OrientationIteratorTest.cpp", "fonts/ScriptRunIteratorTest.cpp",
diff --git a/third_party/WebKit/Source/platform/fonts/FontTestUtilities.cpp b/third_party/WebKit/Source/platform/fonts/FontTestUtilities.cpp new file mode 100644 index 0000000..2f61bb5 --- /dev/null +++ b/third_party/WebKit/Source/platform/fonts/FontTestUtilities.cpp
@@ -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. + +#include "platform/fonts/FontTestUtilities.h" + +namespace blink { + +String To16Bit(const char* text, unsigned length) { + return String::Make16BitFrom8BitSource(reinterpret_cast<const LChar*>(text), + length); +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/platform/fonts/FontTestUtilities.h b/third_party/WebKit/Source/platform/fonts/FontTestUtilities.h new file mode 100644 index 0000000..d2ac809 --- /dev/null +++ b/third_party/WebKit/Source/platform/fonts/FontTestUtilities.h
@@ -0,0 +1,14 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FontTestUtilities_h +#define FontTestUtilities_h + +#include "platform/wtf/text/WTFString.h" + +namespace blink { +String To16Bit(const char* text, unsigned length); +} + +#endif // FontTestUtilities_h
diff --git a/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzShaperTest.cpp b/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzShaperTest.cpp index ef8cabe8..5082bf71 100644 --- a/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzShaperTest.cpp +++ b/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzShaperTest.cpp
@@ -9,6 +9,7 @@ #include "build/build_config.h" #include "platform/fonts/Font.h" #include "platform/fonts/FontCache.h" +#include "platform/fonts/FontTestUtilities.h" #include "platform/fonts/shaping/ShapeResultInlineHeaders.h" #include "platform/fonts/shaping/ShapeResultTestInfo.h" #include "platform/text/TextBreakIterator.h" @@ -41,11 +42,6 @@ return static_cast<ShapeResultTestInfo*>(result.Get()); } -static inline String To16Bit(const char* text, unsigned length) { - return String::Make16BitFrom8BitSource(reinterpret_cast<const LChar*>(text), - length); -} - TEST_F(HarfBuzzShaperTest, ResolveCandidateRunsLatin) { String latin_common = To16Bit("ABC DEF.", 8); HarfBuzzShaper shaper(latin_common.Characters16(), 8);
diff --git a/third_party/WebKit/Source/platform/fonts/shaping/ShapingLineBreakerTest.cpp b/third_party/WebKit/Source/platform/fonts/shaping/ShapingLineBreakerTest.cpp index c7bc639..cd53dea 100644 --- a/third_party/WebKit/Source/platform/fonts/shaping/ShapingLineBreakerTest.cpp +++ b/third_party/WebKit/Source/platform/fonts/shaping/ShapingLineBreakerTest.cpp
@@ -7,6 +7,7 @@ #include <unicode/uscript.h> #include "platform/fonts/Font.h" #include "platform/fonts/FontCache.h" +#include "platform/fonts/FontTestUtilities.h" #include "platform/fonts/shaping/ShapeResultInlineHeaders.h" #include "platform/fonts/shaping/ShapeResultTestInfo.h" #include "platform/text/TextBreakIterator.h" @@ -34,11 +35,6 @@ hb_script_t script = HB_SCRIPT_INVALID; }; -static inline String To16Bit(const char* text, unsigned length) { - return String::Make16BitFrom8BitSource(reinterpret_cast<const LChar*>(text), - length); -} - TEST_F(ShapingLineBreakerTest, ShapeLineLatin) { String string = To16Bit( "Test run with multiple words and breaking "
diff --git a/third_party/WebKit/Source/platform/loader/fetch/ResourceFetcher.cpp b/third_party/WebKit/Source/platform/loader/fetch/ResourceFetcher.cpp index ec17c1a6d..efb5dd3d 100644 --- a/third_party/WebKit/Source/platform/loader/fetch/ResourceFetcher.cpp +++ b/third_party/WebKit/Source/platform/loader/fetch/ResourceFetcher.cpp
@@ -633,10 +633,15 @@ params.Options().initiator_info.name); } - // An URL with the "cid" scheme can only be handled by an MHTML Archive. - // Abort the request when there is none. - if (!archive_ && resource_request.Url().ProtocolIs(kContentIdScheme)) + // A main resource request with the "cid" scheme can only be handled by an + // MHTML Archive. Abort the request when there is none. + // Note: There are some embedders of WebView that are using Content-ID + // URLs for sub-resources, even without any MHTMLArchive. Please see + // https://crbug.com/739658. + if (!archive_ && factory.GetType() == Resource::kMainResource && + resource_request.Url().ProtocolIs(kContentIdScheme)) { return nullptr; + } bool is_data_url = resource_request.Url().ProtocolIsData(); bool is_static_data = is_data_url || substitute_data.IsValid() || archive_;
diff --git a/third_party/WebKit/Source/platform/loader/fetch/ResourceFetcherTest.cpp b/third_party/WebKit/Source/platform/loader/fetch/ResourceFetcherTest.cpp index 5b9813cc..33c48fd5 100644 --- a/third_party/WebKit/Source/platform/loader/fetch/ResourceFetcherTest.cpp +++ b/third_party/WebKit/Source/platform/loader/fetch/ResourceFetcherTest.cpp
@@ -735,4 +735,38 @@ EXPECT_EQ("text/testmimetype", resource->GetResponse().HttpContentType()); } +TEST_F(ResourceFetcherTest, ContentIdURL) { + KURL url(kParsedURLString, "cid:0123456789@example.com"); + ResourceResponse response; + response.SetURL(url); + response.SetHTTPStatusCode(200); + RegisterMockedURLLoadWithCustomResponse(url, response); + + ResourceFetcher* fetcher = ResourceFetcher::Create(Context()); + + // Fetching a main resource with the Content-ID scheme must be canceled if + // there is no MHTMLArchive. + { + ResourceRequest resource_request(url); + resource_request.SetRequestContext(WebURLRequest::kRequestContextIframe); + resource_request.SetFrameType(WebURLRequest::kFrameTypeNested); + FetchParameters fetch_params(resource_request); + RawResource* resource = + RawResource::FetchMainResource(fetch_params, fetcher, SubstituteData()); + EXPECT_EQ(nullptr, resource); + } + + // For all the other resource type, it must not be canceled. + // Note: It is important not to cancel them because there are some embedders + // of WebView that are using Content-ID URLs for sub-resources, even without + // any MHTMLArchive. Please see https://crbug.com/739658. + { + ResourceRequest resource_request(url); + resource_request.SetRequestContext(WebURLRequest::kRequestContextVideo); + FetchParameters fetch_params(resource_request); + RawResource* resource = RawResource::FetchMedia(fetch_params, fetcher); + EXPECT_NE(nullptr, resource); + } +} + } // namespace blink
diff --git a/tools/OWNERS b/tools/OWNERS index f096352..945ca919 100644 --- a/tools/OWNERS +++ b/tools/OWNERS
@@ -39,7 +39,9 @@ per-file ipc_messages_log.py=yfriedman@chromium.org -per-file licenses.py=file://tools/copyright_scanner/OWNERS +per-file licenses.py=phajdan.jr@chromium.org +per-file licenses.py=sgurun@chromium.org +per-file licenses.py=torne@chromium.org per-file remove_stale_pyc_files.py=dtu@chromium.org
diff --git a/tools/copyright_scanner/PRESUBMIT.py b/tools/copyright_scanner/PRESUBMIT.py deleted file mode 100644 index 455701ec..0000000 --- a/tools/copyright_scanner/PRESUBMIT.py +++ /dev/null
@@ -1,29 +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. - -def CheckChangeOnUpload(input_api, output_api): - return _CommonChecks(input_api, output_api) - -def CheckChangeOnCommit(input_api, output_api): - return _CommonChecks(input_api, output_api) - -def _CommonChecks(input_api, output_api): - """Checks common to both upload and commit.""" - results = [] - - would_affect_tests = [ - 'PRESUBMIT.py', - 'copyright_scanner.py', - 'copyright_scanner_unittest.py' - ] - need_to_run_unittests = False - for f in input_api.AffectedFiles(): - if any(t for t in would_affect_tests if f.LocalPath().endswith(t)): - need_to_run_unittests = True - break - tests = [input_api.os_path.join( - input_api.PresubmitLocalPath(), 'copyright_scanner_unittest.py')] - results.extend( - input_api.canned_checks.RunUnitTests(input_api, output_api, tests)) - return results
diff --git a/tools/copyright_scanner/__init__.py b/tools/copyright_scanner/__init__.py deleted file mode 100755 index e6b8d8e..0000000 --- a/tools/copyright_scanner/__init__.py +++ /dev/null
@@ -1,6 +0,0 @@ -#!/usr/bin/env python -# 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. - -__all__ = ['copyright_scanner']
diff --git a/tools/copyright_scanner/copyright_scanner.py b/tools/copyright_scanner/copyright_scanner.py deleted file mode 100644 index 7577241..0000000 --- a/tools/copyright_scanner/copyright_scanner.py +++ /dev/null
@@ -1,400 +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. - -"""Utilities for scanning source files to determine code authorship. -""" - -import itertools - -def ForwardSlashesToOsPathSeps(input_api, path): - """Converts forward slashes ('/') in the input path to OS-specific - path separators. Used when the paths come from outside and are using - UNIX path separators. Only works for relative paths! - Args: - input_api: InputAPI, as in presubmit scripts. - path: The path to convert. - Returns: - Converted path. - """ - return input_api.os_path.join(*path.split('/')) - -def FindFiles(input_api, root_dir, start_paths_list, excluded_dirs_list): - """Similar to UNIX utility find(1), searches for files in the directories. - Automatically leaves out only source code files and excludes third_party - directories. - Args: - input_api: InputAPI, as in presubmit scripts. - root_dir: The root directory, to which all other paths are relative. - start_paths_list: The list of paths to start search from. Each path can - be a file or a directory. - excluded_dirs_list: The list of directories to skip. - Returns: - The list of source code files found, relative to |root_dir|. - """ - excluded_dirs_list = [d for d in excluded_dirs_list if not 'third_party' in d] - # Using a common pattern for third-partyies makes the ignore regexp shorter - excluded_dirs_list.append('third_party') - - path_join = input_api.os_path.join - EXTRA_EXCLUDED_DIRS = [ - # VCS dirs - path_join('.git'), - path_join('.svn'), - # Build output - path_join('out', 'Debug'), - path_join('out', 'Release'), - # 'Copyright' appears in license agreements - path_join('chrome', 'app', 'resources'), - # Quickoffice js files from internal src used on buildbots. - # crbug.com/350472. - path_join('chrome', 'browser', 'resources', 'chromeos', 'quickoffice'), - # blink style copy right headers. - path_join('content', 'shell', 'renderer', 'test_runner'), - # blink style copy right headers. - path_join('content', 'shell', 'tools', 'plugin'), - # This is tests directory, doesn't exist in the snapshot - path_join('content', 'test', 'data'), - # This is a tests directory that doesn't exist in the shipped product. - path_join('gin', 'test'), - # This is a test output directory - path_join('data', 'dom_perf'), - # This is a tests directory that doesn't exist in the shipped product. - path_join('tools', 'perf', 'page_sets'), - path_join('tools', 'perf', 'page_sets', 'tough_animation_cases'), - # Histogram tools, doesn't exist in the snapshot - path_join('tools', 'histograms'), - # Swarming tools, doesn't exist in the snapshot - path_join('tools', 'swarming_client'), - # Don't check downloaded goma client binaries. - path_join('build', 'goma', 'client'), - # Ignore sysroots. - path_join('build', 'linux', 'debian_jessie_arm64-sysroot'), - path_join('build', 'linux', 'debian_jessie_arm-sysroot'), - path_join('build', 'linux', 'debian_jessie_mips-sysroot'), - path_join('build', 'linux', 'debian_jessie_i386-sysroot'), - path_join('build', 'linux', 'debian_jessie_amd64-sysroot'), - # Data is not part of open source chromium, but are included on some bots. - path_join('data'), - # This is not part of open source chromium, but are included on some bots. - path_join('skia', 'tools', 'clusterfuzz-data'), - # Not shipped, only relates to Chrome for Android, but not to WebView - path_join('clank'), - # Internal-only repository. - path_join('remoting', 'android', 'internal'), - ] - excluded_dirs_list.extend(EXTRA_EXCLUDED_DIRS) - - # Surround the directory names with OS path separators. - dirs_blacklist = [path_join('.', d, '')[1:] for d in excluded_dirs_list if d] - def IsBlacklistedDir(d): - for item in dirs_blacklist: - if item in d: - return True - return False - - files_whitelist_re = input_api.re.compile( - r'\.(asm|c(c|pp|xx)?|h(h|pp|xx)?|p(l|m)|xs|sh|php|py(|x)' - '|rb|idl|java|el|sc(i|e)|cs|pas|inc|js|pac|html|dtd|xsl|mod|mm?' - '|tex|mli?)$') - files = [] - - base_path_len = len(root_dir) - for path in start_paths_list: - full_path = path_join(root_dir, path) - if input_api.os_path.isfile(full_path): - if files_whitelist_re.search(path) and \ - not IsBlacklistedDir(full_path[base_path_len:]): # Keep '/' prefix. - files.append(path) - else: - for dirpath, dirnames, filenames in input_api.os_walk(full_path): - # Remove excluded subdirs for faster scanning. - for item in dirnames[:]: - if IsBlacklistedDir( - path_join(dirpath, item)[base_path_len + 1:]): - dirnames.remove(item) - for filename in filenames: - filepath = \ - path_join(dirpath, filename)[base_path_len + 1:] - if files_whitelist_re.search(filepath) and \ - not IsBlacklistedDir(filepath): - files.append(filepath) - return files - - -class _GeneratedFilesDetector(object): - GENERATED_FILE = 'GENERATED FILE' - NO_COPYRIGHT = '*No copyright*' - - def __init__(self, input_api): - self.python_multiline_string_double_re = \ - input_api.re.compile(r'"""[^"]*(?:"""|$)', flags=input_api.re.MULTILINE) - self.python_multiline_string_single_re = \ - input_api.re.compile(r"'''[^']*(?:'''|$)", flags=input_api.re.MULTILINE) - self.automatically_generated_re = input_api.re.compile( - r'(All changes made in this file will be lost' - '|DO NOT (EDIT|delete this file)' - '|Generated (at|automatically|data)' - '|Automatically generated' - '|\Wgenerated\s+(?:\w+\s+)*file\W)', flags=input_api.re.IGNORECASE) - - def IsGeneratedFile(self, header): - header = header.upper() - if '"""' in header: - header = self.python_multiline_string_double_re.sub('', header) - if "'''" in header: - header = self.python_multiline_string_single_re.sub('', header) - # First do simple strings lookup to save time. - if 'ALL CHANGES MADE IN THIS FILE WILL BE LOST' in header: - return True - if 'DO NOT EDIT' in header or 'DO NOT DELETE' in header or \ - 'GENERATED' in header: - return self.automatically_generated_re.search(header) - return False - - -class _CopyrightsScanner(object): - @staticmethod - def StaticInit(input_api): - _CopyrightsScanner._c_comment_re = \ - input_api.re.compile(r'''"[^"\\]*(?:\\.[^"\\]*)*"''') - _CopyrightsScanner._copyright_indicator = \ - r'(?:copyright|copr\.|\xc2\xa9|\(c\))' - _CopyrightsScanner._full_copyright_indicator_re = input_api.re.compile( - r'(?:\W|^)' + _CopyrightsScanner._copyright_indicator + \ - r'(?::\s*|\s+)(\w.*)$', input_api.re.IGNORECASE) - _CopyrightsScanner._copyright_disindicator_re = input_api.re.compile( - r'\s*\b(?:info(?:rmation)?|notice|and|or)\b', input_api.re.IGNORECASE) - - def __init__(self, input_api): - self.max_line_numbers_proximity = 3 - self.last_a_item_line_number = -200 - self.last_b_item_line_number = -100 - self.re = input_api.re - - def _CloseLineNumbers(self, a, b): - return 0 <= a - b <= self.max_line_numbers_proximity - - def MatchLine(self, line_number, line): - if '"' in line: - line = _CopyrightsScanner._c_comment_re.sub('', line) - upcase_line = line.upper() - # Record '(a)' and '(b)' last occurences in C++ comments. - # This is to filter out '(c)' used as a list item inside C++ comments. - # E.g. "// blah-blah (a) blah\n// blah-blah (b) and (c) blah" - cpp_comment_idx = upcase_line.find('//') - if cpp_comment_idx != -1: - if upcase_line.find('(A)') > cpp_comment_idx: - self.last_a_item_line_number = line_number - if upcase_line.find('(B)') > cpp_comment_idx: - self.last_b_item_line_number = line_number - # Fast bailout, uses the same patterns as _copyright_indicator regexp. - if not 'COPYRIGHT' in upcase_line and not 'COPR.' in upcase_line \ - and not '\xc2\xa9' in upcase_line: - c_item_index = upcase_line.find('(C)') - if c_item_index == -1: - return None - if c_item_index > cpp_comment_idx and \ - self._CloseLineNumbers(line_number, - self.last_b_item_line_number) and \ - self._CloseLineNumbers(self.last_b_item_line_number, - self.last_a_item_line_number): - return None - copyr = None - m = _CopyrightsScanner._full_copyright_indicator_re.search(line) - if m and \ - not _CopyrightsScanner._copyright_disindicator_re.match(m.group(1)): - copyr = m.group(0) - # Prettify the authorship string. - copyr = self.re.sub(r'([,.])?\s*$/', '', copyr) - copyr = self.re.sub( - _CopyrightsScanner._copyright_indicator, '', copyr, \ - flags=self.re.IGNORECASE) - copyr = self.re.sub(r'^\s+', '', copyr) - copyr = self.re.sub(r'\s{2,}', ' ', copyr) - copyr = self.re.sub(r'\\@', '@', copyr) - return copyr - - -def FindCopyrights(input_api, root_dir, files_to_scan): - """Determines code autorship, and finds generated files. - Args: - input_api: InputAPI, as in presubmit scripts. - root_dir: The root directory, to which all other paths are relative. - files_to_scan: The list of file names to scan. - Returns: - The list of copyrights associated with each of the files given. - If the certain file is generated, the corresponding list consists a single - entry -- 'GENERATED_FILE' string. If the file has no copyright info, - the corresponding list contains 'NO_COPYRIGHT' string. - """ - generated_files_detector = _GeneratedFilesDetector(input_api) - _CopyrightsScanner.StaticInit(input_api) - copyrights = [] - for file_name in files_to_scan: - linenum = 0 - header = [] - file_copyrights = [] - scanner = _CopyrightsScanner(input_api) - contents = input_api.ReadFile( - input_api.os_path.join(root_dir, file_name), 'r') - for l in contents.split('\n'): - linenum += 1 - if linenum <= 25: - header.append(l) - c = scanner.MatchLine(linenum, l) - if c: - file_copyrights.append(c) - if generated_files_detector.IsGeneratedFile('\n'.join(header)): - copyrights.append([_GeneratedFilesDetector.GENERATED_FILE]) - elif file_copyrights: - copyrights.append(file_copyrights) - else: - copyrights.append([_GeneratedFilesDetector.NO_COPYRIGHT]) - return copyrights - - -def FindCopyrightViolations(input_api, root_dir, files_to_scan): - """Looks for files that are not belong exlusively to the Chromium Authors. - Args: - input_api: InputAPI, as in presubmit scripts. - root_dir: The root directory, to which all other paths are relative. - files_to_scan: The list of file names to scan. - Returns: - The list of file names that contain non-Chromium copyrights. - """ - copyrights = FindCopyrights(input_api, root_dir, files_to_scan) - offending_files = [] - allowed_copyrights_re = input_api.re.compile( - r'^(?:20[0-9][0-9](?:-20[0-9][0-9])? The Chromium Authors\. ' - 'All rights reserved.*)$') - for f, cs in itertools.izip(files_to_scan, copyrights): - if cs[0] == _GeneratedFilesDetector.GENERATED_FILE or \ - cs[0] == _GeneratedFilesDetector.NO_COPYRIGHT: - continue - for c in cs: - if not allowed_copyrights_re.match(c): - offending_files.append(input_api.os_path.normpath(f)) - break - return offending_files - - -def _GetWhitelistFileName(input_api): - return input_api.os_path.join( - 'tools', 'copyright_scanner', 'third_party_files_whitelist.txt') - -def _ProcessWhitelistedFilesList(input_api, lines): - whitelisted_files = [] - for line in lines: - match = input_api.re.match(r'([^#\s]+)', line) - if match: - whitelisted_files.append( - ForwardSlashesToOsPathSeps(input_api, match.group(1))) - return whitelisted_files - - -def LoadWhitelistedFilesList(input_api): - """Loads and parses the 3rd party code whitelist file. - input_api: InputAPI of presubmit scripts. - Returns: - The list of files. - """ - full_file_name = input_api.os_path.join( - input_api.change.RepositoryRoot(), _GetWhitelistFileName(input_api)) - file_data = input_api.ReadFile(full_file_name, 'rb') - return _ProcessWhitelistedFilesList(input_api, file_data.splitlines()) - - -def AnalyzeScanResults(input_api, whitelisted_files, offending_files): - """Compares whitelist contents with the results of file scanning. - input_api: InputAPI of presubmit scripts. - whitelisted_files: Whitelisted files list. - offending_files: Files that contain 3rd party code. - Returns: - A triplet of "unknown", "missing", and "stale" file lists. - "Unknown" are files that contain 3rd party code but not whitelisted. - "Missing" are files that are whitelisted but doesn't really exist. - "Stale" are files that are whitelisted unnecessarily. - """ - unknown = set(offending_files) - set(whitelisted_files) - missing = [f for f in whitelisted_files if not input_api.os_path.isfile( - input_api.os_path.join(input_api.change.RepositoryRoot(), f))] - stale = set(whitelisted_files) - set(offending_files) - set(missing) - return (list(unknown), missing, list(stale)) - - -def _GetDeletedContents(affected_file): - """Returns a list of all deleted lines. - AffectedFile class from presubmit_support is lacking this functionality. - """ - deleted_lines = [] - for line in affected_file.GenerateScmDiff().splitlines(): - if line.startswith('-') and not line.startswith('--'): - deleted_lines.append(line[1:]) - return deleted_lines - -def _DoScanAtPresubmit(input_api, whitelisted_files, files_to_check): - # We pass empty 'known third-party' dirs list here. Since this is a patch - # for the Chromium's src tree, it must contain properly licensed Chromium - # code. Any third-party code must be put into a directory named 'third_party', - # and such dirs are automatically excluded by FindFiles. - files_to_scan = FindFiles( - input_api, input_api.change.RepositoryRoot(), files_to_check, []) - offending_files = FindCopyrightViolations( - input_api, input_api.change.RepositoryRoot(), files_to_scan) - return AnalyzeScanResults( - input_api, whitelisted_files, offending_files) - -def ScanAtPresubmit(input_api, output_api): - """Invoked at change presubmit time. Verifies that updated non third-party - code doesn't contain external copyrighted code. - input_api: InputAPI of presubmit scripts. - output_api: OutputAPI of presubmit scripts. - """ - files_to_check = set([]) - deleted_files = set([]) - whitelist_contents_changed = False - for f in input_api.AffectedFiles(): - if f.LocalPath() == _GetWhitelistFileName(input_api): - whitelist_contents_changed = True - deleted_files |= set(_ProcessWhitelistedFilesList( - input_api, _GetDeletedContents(f))) - continue - if f.Action() != 'D': - files_to_check.add(f.LocalPath()) - else: - deleted_files.add(f.LocalPath()) - whitelisted_files = set(LoadWhitelistedFilesList(input_api)) - if not whitelist_contents_changed: - whitelisted_files &= files_to_check | deleted_files - else: - # Need to re-check the entire contents of the whitelist file. - # Also add files removed from the whitelist. If the file has indeed been - # deleted, the scanner will not complain. - files_to_check |= whitelisted_files | deleted_files - - (unknown_files, missing_files, stale_files) = _DoScanAtPresubmit( - input_api, list(whitelisted_files), list(files_to_check)) - results = [] - if unknown_files: - results.append(output_api.PresubmitError( - 'The following files contain a third-party license but are not in ' \ - 'a listed third-party directory and are not whitelisted. You must ' \ - 'add the following files to the whitelist file %s\n' \ - '(Note that if the code you are adding does not actually contain ' \ - 'any third-party code, it may contain the word "copyright", which ' \ - 'should be masked out, e.g. by writing it as "copy-right"):' \ - '' % _GetWhitelistFileName(input_api), - sorted(unknown_files))) - if missing_files: - results.append(output_api.PresubmitPromptWarning( - 'The following files are whitelisted in %s, ' \ - 'but do not exist or not files:' % _GetWhitelistFileName(input_api), - sorted(missing_files))) - if stale_files: - results.append(output_api.PresubmitPromptWarning( - 'The following files are whitelisted unnecessarily. You must ' \ - 'remove the following files from the whitelist file ' \ - '%s:' % _GetWhitelistFileName(input_api), - sorted(stale_files))) - return results
diff --git a/tools/copyright_scanner/copyright_scanner_unittest.py b/tools/copyright_scanner/copyright_scanner_unittest.py deleted file mode 100755 index 339abde..0000000 --- a/tools/copyright_scanner/copyright_scanner_unittest.py +++ /dev/null
@@ -1,308 +0,0 @@ -#!/usr/bin/env python -# 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. - -"""Unit tests for Copyright Scanner utilities.""" - -import os -import re -import sys -import unittest - -test_dir = os.path.dirname(os.path.abspath(__file__)) -sys.path.extend([ - os.path.normpath(os.path.join(test_dir, '..', '..', 'build')), - os.path.join(test_dir), -]) - -import find_depot_tools -from testing_support.super_mox import SuperMoxTestBase - -import copyright_scanner - -class FindCopyrightsTest(SuperMoxTestBase): - def setUp(self): - SuperMoxTestBase.setUp(self) - self.input_api = self.mox.CreateMockAnything() - self.input_api.re = re - self.input_api.os_path = os.path - self.input_api.os_walk = os.walk - - def ShouldMatchReferenceOutput(self, test_data, expected_output): - for data in test_data: - self.input_api.ReadFile = lambda _1, _2: data - actual_output = copyright_scanner.FindCopyrights(self.input_api, '', ['']) - self.assertEqual( - expected_output, - actual_output, - 'Input """\n%s""", expected output: "%s", actual: "%s"' % \ - (data, expected_output, actual_output)); - - def testCopyrightedFiles(self): - test_data = [ - '// (c) 2014 Google Inc.\n//\n// (a) One\n//\n// (b) Two\n//\n', - 'Copyright 2014 Google Inc.\n', - 'Copr. 2014 Google Inc.', - '\xc2\xa9 2014 Google Inc.', - 'Copyright 2014 Google Inc.' - ] - self.ShouldMatchReferenceOutput(test_data, [['2014 Google Inc.']]) - - def testGeneratedFiles(self): - test_data = [ - 'ALL CHANGES MADE IN THIS FILE WILL BE LOST\nCopyright 2014 Google\n', - 'GENERATED FILE. DO NOT EDIT\nCopyright 2014 Google\n', - 'GENERATED. DO NOT DELETE THIS FILE.\nCopyright 2014 Google\n', - 'DO NOT EDIT\nCopyright 2014 Google\n', - 'DO NOT DELETE THIS FILE\nCopyright 2014 Google\n', - 'All changes made in this file will be lost\nCopyright 2014 Google\n', - 'Automatically generated file\nCopyright 2014 Google\n', - 'Synthetically generated dummy file\nCopyright 2014 Google\n', - 'Generated data (by gnugnu)\nCopyright 2014 Google\n' - ] - self.ShouldMatchReferenceOutput(test_data, [['GENERATED FILE']]) - - def testNonCopyrightedFiles(self): - test_data = [ - 'std::cout << "Copyright 2014 Google"\n', - '// Several points can be made:\n//\n// (a) One\n//\n// (b) Two\n' - '//\n// (c) Three\n//\n', - 'See \'foo\' for copyright information.\n', - 'See \'foo\' for the copyright notice.\n', - 'See \'foo\' for the copyright and other things.\n' - ] - self.ShouldMatchReferenceOutput(test_data, [['*No copyright*']]) - - def testNonGeneratedFiles(self): - test_data = [ - 'This file was prohibited from being generated.\n', - 'Please do not delete our files! They are valuable to us.\n', - 'Manually generated from dice rolls.\n', - '"""This Python script produces generated data\n"""\n', - '\'\'\'This Python script produces generated data\n\'\'\'\n' - ] - self.ShouldMatchReferenceOutput(test_data, [['*No copyright*']]) - - -class FindFilesTest(SuperMoxTestBase): - def setUp(self): - SuperMoxTestBase.setUp(self) - self.input_api = self.mox.CreateMockAnything() - self.input_api.re = re - self.input_api.os_path = os.path - - def testFilesAsStartPaths(self): - join = self.input_api.os_path.join - self.input_api.os_path.isfile = lambda _: True - input_files = [ - 'a', - 'a.cc', - 'a.txt', - join('foo', 'a'), - join('foo', 'a.cc'), - join('foo', 'a.txt'), - join('third_party', 'a'), - join('third_party', 'a.cc'), - join('third_party', 'a.txt'), - join('foo', 'third_party', 'a'), - join('foo', 'third_party', 'a.cc'), - join('foo', 'third_party', 'a.txt'), - ] - root_dir = os.path.sep + 'src' - actual = copyright_scanner.FindFiles( - self.input_api, root_dir, input_files, ['']) - self.assertEqual(['a.cc', join('foo', 'a.cc')], actual) - actual = copyright_scanner.FindFiles( - self.input_api, root_dir, input_files, ['third_party']) - self.assertEqual(['a.cc', join('foo', 'a.cc')], actual) - actual = copyright_scanner.FindFiles( - self.input_api, root_dir, input_files, ['foo']) - self.assertEqual(['a.cc'], actual) - actual = copyright_scanner.FindFiles( - self.input_api, root_dir, input_files, ['foo', 'third_party']) - self.assertEqual(['a.cc'], actual) - actual = copyright_scanner.FindFiles( - self.input_api, root_dir, input_files, [join('foo', 'third_party')]) - self.assertEqual(['a.cc', join('foo', 'a.cc')], actual) - - def testDirAsStartPath(self): - self.input_api.os_path.isfile = lambda _: False - join = self.input_api.os_path.join - normpath = self.input_api.os_path.normpath - root_dir = os.path.sep + 'src' - scan_from = '.' - base_path = join(root_dir, scan_from) - - def mock_os_walk(path): - return lambda _: [(join(base_path, path), [''], ['a', 'a.cc', 'a.txt'])] - - self.input_api.os_walk = mock_os_walk('') - actual = map(normpath, copyright_scanner.FindFiles( - self.input_api, root_dir, [scan_from], [''])) - self.assertEqual(['a.cc'], actual) - - self.input_api.os_walk = mock_os_walk('third_party') - actual = map(normpath, copyright_scanner.FindFiles( - self.input_api, root_dir, [scan_from], [''])) - self.assertEqual([], actual) - - self.input_api.os_walk = mock_os_walk('foo') - actual = map(normpath, copyright_scanner.FindFiles( - self.input_api, root_dir, [scan_from], [''])) - self.assertEqual([join('foo', 'a.cc')], actual) - - self.input_api.os_walk = mock_os_walk('foo') - actual = map(normpath, copyright_scanner.FindFiles( - self.input_api, root_dir, [scan_from], ['foo'])) - self.assertEqual([], actual) - - self.input_api.os_walk = mock_os_walk(join('foo', 'bar')) - actual = map(normpath, copyright_scanner.FindFiles( - self.input_api, root_dir, [scan_from], ['foo'])) - self.assertEqual([], actual) - - self.input_api.os_walk = mock_os_walk(join('foo', 'third_party')) - actual = map(normpath, copyright_scanner.FindFiles( - self.input_api, root_dir, [scan_from], [''])) - self.assertEqual([], actual) - - self.input_api.os_walk = mock_os_walk(join('foo', 'third_party')) - actual = map(normpath, copyright_scanner.FindFiles( - self.input_api, root_dir, [scan_from], [join('foo', 'third_party')])) - self.assertEqual([], actual) - - -class AnalyzeScanResultsTest(SuperMoxTestBase): - def setUp(self): - SuperMoxTestBase.setUp(self) - self.input_api = self.mox.CreateMockAnything() - self.input_api.os_path = os.path - self.input_api.change = self.mox.CreateMockAnything() - self.input_api.change.RepositoryRoot = lambda: '' - - def testAnalyzeScanResults(self): - # Tests whitelisted vs. current files state logic. - # - # Whitelisted - in whitelist, and contains 3rd party code => OK - # Missing - in whitelist, but doesn't exist - # Stale - in whitelist, but is clean - # Unknown - not in whitelist, but contains 3rd party code - self.input_api.os_path.isfile = lambda x: x != 'Missing' - self.assertEqual( - (['Unknown'], ['Missing'], ['Stale']), - copyright_scanner.AnalyzeScanResults(self.input_api, \ - ['Whitelisted', 'Missing', 'Stale'], ['Whitelisted', 'Unknown'])) - - -class ScanAtPresubmitTest(SuperMoxTestBase): - def setUp(self): - SuperMoxTestBase.setUp(self) - self.input_api = self.mox.CreateMockAnything() - self.input_api.re = re - self.input_api.os_path = os.path - self.output_api = self.mox.CreateMockAnything() - def tearDown(self): - self.mox.UnsetStubs() - SuperMoxTestBase.tearDown(self) - - class AffectedFileMock(object): - def __init__(self, local_path, action): - self._local_path = local_path - self._action = action - def LocalPath(self): - return self._local_path - def Action(self): - return self._action - - def CreateAffectedFilesFunc(self, paths_and_actions): - result = [] - for i in range(0, len(paths_and_actions), 2): - result.append(ScanAtPresubmitTest.AffectedFileMock( - paths_and_actions[i], paths_and_actions[i + 1])) - return lambda: result - - def CreateDoScanAtPresubmitFunc(self): - self._whitelisted_files = None - self._files_to_check = None - def ScanAtPresubmitStub(_, whitelisted, to_check): - self._whitelisted_files = whitelisted - self._files_to_check = to_check - return ([], [], []) - return ScanAtPresubmitStub - - def GetWhitelistedFiles(self): - return sorted(self._whitelisted_files) - - def GetFilesToCheck(self): - return sorted(self._files_to_check) - - def testWhitelistedUntouched(self): - # When a change doesn't touch the whitelist file, any updated files - # (except deleted) must be checked. The whitelist used for analysis - # must be trimmed to the changed files subset. - # - # A_NW.cc - added, not whitelisted => check - # A_W.cc - added, whitelisted => check, remain on the trimmed whitelist - # D_NW.cc - deleted, not whitelisted => ignore - # D_W.cc - deleted and whitelisted => remain on w/l - # M_NW.cc - modified, not whitelisted => check - # M_W.cc - modified and whitelisted => check, remain on w/l - # NM_W.cc - not modified, whitelisted => trim from w/l - # W - the whitelist file - - self.input_api.AffectedFiles = self.CreateAffectedFilesFunc( - ['A_NW.cc', 'A', 'A_W.cc', 'A', 'D_NW.cc', 'D', 'D_W.cc', 'D', - 'M_NW.cc', 'M', 'M_W.cc', 'M']) - self.mox.StubOutWithMock(copyright_scanner, '_GetWhitelistFileName') - copyright_scanner._GetWhitelistFileName = lambda _: 'W' - self.mox.StubOutWithMock(copyright_scanner, 'LoadWhitelistedFilesList') - copyright_scanner.LoadWhitelistedFilesList = \ - lambda _: ['A_W.cc', 'D_W.cc', 'M_W.cc', 'NM_W.cc'] - self.mox.StubOutWithMock(copyright_scanner, '_DoScanAtPresubmit') - copyright_scanner._DoScanAtPresubmit = self.CreateDoScanAtPresubmitFunc() - self.mox.ReplayAll() - copyright_scanner.ScanAtPresubmit(self.input_api, self.output_api) - self.assertEqual( - ['A_W.cc', 'D_W.cc', 'M_W.cc'], self.GetWhitelistedFiles()) - self.assertEqual( - ['A_NW.cc', 'A_W.cc', 'M_NW.cc', 'M_W.cc'], self.GetFilesToCheck()) - - def testWhitelistTouched(self): - # When the whitelist file is touched by the change, all the files listed in - # it, including deleted entries, must be re-checked. All modified files - # (including the deleted ones) must be checked as well. The current contents - # of the whitelist are used for analysis. - # Whitelist addition or deletion are not considered. - # - # All the files from names testWhitelistedUntouched are re-used, but now - # action for all of them is 'check' (except for the w/l file itself). - # A_DW.cc - added, deleted from w/l => check - # D_DW.cc - deleted from repo and w/l => check - # M_DW.cc - modified, deleted from w/l => check - self.input_api.AffectedFiles = self.CreateAffectedFilesFunc( - ['A_DW.cc', 'A', 'A_NW.cc', 'A', 'A_W.cc', 'A', - 'D_DW.cc', 'D', 'D_NW.cc', 'D', 'D_W.cc', 'D', - 'M_DW.cc', 'M', 'M_NW.cc', 'M', 'M_W.cc', 'M', 'W', 'M']) - self.mox.StubOutWithMock(copyright_scanner, '_GetWhitelistFileName') - copyright_scanner._GetWhitelistFileName = lambda _: 'W' - self.mox.StubOutWithMock(copyright_scanner, '_GetDeletedContents') - def GetDeletedContentsStub(affected_file): - self.assertEqual('W', affected_file.LocalPath()) - return ['A_DW.cc', 'D_DW.cc', 'M_DW.cc'] - copyright_scanner._GetDeletedContents = GetDeletedContentsStub - self.mox.StubOutWithMock(copyright_scanner, 'LoadWhitelistedFilesList') - copyright_scanner.LoadWhitelistedFilesList = \ - lambda _: ['A_W.cc', 'D_W.cc', 'M_W.cc', 'NM_W.cc'] - self.mox.StubOutWithMock(copyright_scanner, '_DoScanAtPresubmit') - copyright_scanner._DoScanAtPresubmit = self.CreateDoScanAtPresubmitFunc() - self.mox.ReplayAll() - copyright_scanner.ScanAtPresubmit(self.input_api, self.output_api) - self.assertEqual( - ['A_W.cc', 'D_W.cc', 'M_W.cc', 'NM_W.cc'], self.GetWhitelistedFiles()) - self.assertEqual( - ['A_DW.cc', 'A_NW.cc', 'A_W.cc', 'D_DW.cc', 'D_NW.cc', 'D_W.cc', - 'M_DW.cc', 'M_NW.cc', 'M_W.cc', 'NM_W.cc' ], self.GetFilesToCheck()) - -if __name__ == '__main__': - unittest.main()
diff --git a/tools/copyright_scanner/third_party_files_whitelist.txt b/tools/copyright_scanner/third_party_files_whitelist.txt deleted file mode 100644 index 25fe15af..0000000 --- a/tools/copyright_scanner/third_party_files_whitelist.txt +++ /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. - -# This file records third-party licensing information for the purposes of the -# Android WebView build. See webview_licenses.py for details. -# -# New third-party code should be added under a directory named 'third_party', -# so additions to this file should be rare. See -# http://www.chromium.org/developers/adding-3rd-party-libraries. -# -# Please always use forward slashes '/' as path separators, even if you are -# on Windows. - -# Copyright IBM; MIT license. This third-party code is taken from ICU, the -# license for which we already pick up from third_party/icu/. -base/i18n/icu_string_conversions.cc -# Contains '(c)' in comments -base/logging.h -# Copyright Ron Rivest, public domain. -base/md5.cc -# Copyright Apple Inc; BSD license. Moved from third_party/WebKit/. -cc/input/scroll_elasticity_helper.h -# Copyright Netscape Communications Corporation; MPL, GPL v2 or LGPL v2 -# license. Not used on Android. -chrome/browser/importer/firefox_profile_lock.cc -# Copyright Netscape Communications Corporation; MPL, GPL v2 or LGPL v2 -# license. Not used on Android. -chrome/browser/importer/firefox_profile_lock.h -# Copyright Netscape Communications Corporation; MPL, GPL v2 or LGPL v2 -# license. Not used on Android. -chrome/browser/importer/firefox_profile_lock_posix.cc -# Copyright Netscape Communications Corporation; MPL, GPL v2 or LGPL v2 -# license. Not used on Android. -chrome/browser/importer/firefox_profile_lock_win.cc -# String 'copyright' used in code. -chrome/common/importer/firefox_importer_utils.cc -# Copyright Netscape Communications Corporation; MPL, GPL v2 or LGPL v2 -# license. Not used on Android. -chrome/utility/importer/nss_decryptor.cc -# Copyright Netscape Communications Corporation; MPL, GPL v2 or LGPL v2 -# license. Not used on Android. -chrome/utility/importer/nss_decryptor_mac.h -# Copyright Netscape Communications Corporation; MPL, GPL v2 or LGPL v2 -# license. Not used on Android. -chrome/utility/importer/nss_decryptor_system_nss.cc -# Copyright Netscape Communications Corporation; MPL, GPL v2 or LGPL v2 -# license. Not used on Android. -chrome/utility/importer/nss_decryptor_win.h -# Copyright Google Inc; BSD license. Test code only. -chrome/tools/test/generate_mime_tests.pl -# String 'copyright' used in the text presented to the user as part of -# Google Chrome terms of service. -components/resources/terms/chromeos/terms_en.html -components/resources/terms/terms_am.html -components/resources/terms/terms_ca.html -components/resources/terms/terms_cs.html -components/resources/terms/terms_da.html -components/resources/terms/terms_de.html -components/resources/terms/terms_en-GB.html -components/resources/terms/terms_en.html -components/resources/terms/terms_es-419.html -components/resources/terms/terms_es.html -components/resources/terms/terms_et.html -components/resources/terms/terms_fi.html -components/resources/terms/terms_fil.html -components/resources/terms/terms_fr.html -components/resources/terms/terms_he.html -components/resources/terms/terms_hr.html -components/resources/terms/terms_hu.html -components/resources/terms/terms_id.html -components/resources/terms/terms_it.html -components/resources/terms/terms_ja.html -components/resources/terms/terms_kn.html -components/resources/terms/terms_ko.html -components/resources/terms/terms_lt.html -components/resources/terms/terms_lv.html -components/resources/terms/terms_ml.html -components/resources/terms/terms_nb.html -components/resources/terms/terms_nl.html -components/resources/terms/terms_pl.html -components/resources/terms/terms_pt-BR.html -components/resources/terms/terms_pt-PT.html -components/resources/terms/terms_ro.html -components/resources/terms/terms_sk.html -components/resources/terms/terms_sl.html -components/resources/terms/terms_sr.html -components/resources/terms/terms_sv.html -components/resources/terms/terms_sw.html -components/resources/terms/terms_ta.html -components/resources/terms/terms_te.html -components/resources/terms/terms_th.html -components/resources/terms/terms_tr.html -components/resources/terms/terms_vi.html -# Copyright Apple Inc, Nokia Corporation and Torch Mobile Inc; BSD license. -# Contains code moved from third_party/WebKit/. -content/browser/frame_host/navigation_controller_impl.cc -# Copyright Apple, Inc, Google Inc; BSD license. Not used on Android. -# Moved from third_party/WebKit/. -content/browser/renderer_host/input/web_input_event_builders_mac.mm -# Copyright Apple Inc and Torch Mobile Inc; BSD license. Moved from -# third_party/WebKit/. -content/renderer/history_controller.h -# Copyright Apple Inc, Nokia Corporation and Torch Mobile Inc; BSD license. -# Moved from third_party/WebKit/. -content/renderer/history_controller.cc -# Copyright Apple Inc and Torch Mobile Inc; BSD license. Moved from -# third_party/WebKit/. -content/renderer/history_entry.h -# Copyright Apple Inc, Nokia Corporation and Torch Mobile Inc; BSD license. -# Moved from third_party/WebKit/. -content/renderer/history_entry.cc -# Copyright Google Inc, no license. Not used on Android. -google_update/google_update_idl.idl -# Copyright WebM Project authors; BSD license. Copied and modified from -# third_party/libvpx. Not used on Android. -media/filters/vp8_bool_decoder.h -media/filters/vp8_bool_decoder.cc -# Native client not used in Android. Contains the word "Copyright" -native_client_sdk/doc_generated/rest-devsite-examples.html -# String '(c)' used in certificates organization names -net/cert/x509_certificate_known_roots_win.h -net/quic/core/crypto/common_cert_set_2a.inc -net/quic/core/crypto/common_cert_set_2b.inc -net/quic/core/crypto/common_cert_set_3a.inc -net/quic/core/crypto/common_cert_set_3b.inc -# String '(c)' used in certificates organization names -net/test/test_certificate_data.h -# Copyright The Chromium Authors and Netscape Communications Corporation; BSD -# and (MPL, GPL v2 or LGPL v2) licenses. This third-party code is taken from -# Mozilla, the license for which we already pick up from third_party/npapi/. -net/cookies/cookie_monster.cc -# Copyright The Chromium Authors and Netscape Communications Corporation; BSD -# and (MPL, GPL v2 or LGPL v2) licenses. This third-party code is taken from -# Mozilla, the license for which we already pick up from third_party/npapi/. -net/cookies/canonical_cookie.cc -# Copyright The Chromium Authors and Netscape Communications Corporation; BSD -# and (MPL, GPL v2 or LGPL v2) licenses. This third-party code is taken from -# Mozilla, the license for which we already pick up from third_party/npapi/. -net/cookies/parsed_cookie.cc -# Copyright The Chromium Authors and Google Inc; BSD and (MPL, GPL v2 or LGPL -# v2) licenses. This third-party code is taken from Mozilla, the license for -# which we already pick up from third_party/npapi/. -net/base/registry_controlled_domains/registry_controlled_domain.cc -# Copyright The Chromium Authors and Google Inc; BSD and (MPL, GPL v2 or LGPL -# v2) licenses. This third-party code is taken from Mozilla, the license for -# which we already pick up from third_party/npapi/. -net/base/registry_controlled_domains/registry_controlled_domain.h -# Copyright The Chromium Authors and IBM Corporation; BSD and (MPL, GPL v2 or -# LGPL v2) licenses. This third-party code is taken from Mozilla, the license -# for which we already pick up from third_party/npapi/. -net/http/des.cc -# Copyright The Chromium Authors and IBM Corporation; BSD and (MPL, GPL v2 or -# LGPL v2) licenses. This third-party code is taken from Mozilla, the license -# for which we already pick up from third_party/npapi/. -net/http/http_auth_handler_ntlm_portable.cc -# Copyright The Chromium Authors and Netscape Communications; BSD and (MPL, GPL -# v2 or LGPL v2) licenses. This third-party code is taken from Mozilla, the -# license for which we already pick up from third_party/npapi/. -net/http/http_chunked_decoder.cc -# Copyright The Chromium Authors and Netscape Communications; BSD and (MPL, GPL -# v2 or LGPL v2) licenses. This third-party code is taken from Mozilla, the -# license for which we already pick up from third_party/npapi/. -net/http/http_chunked_decoder.h -# Copyright IBM Corporation; MPL, GPL v2 or LGPL v2 license. This third-party -# code is taken from Mozilla, the license for which we already pick up from -# third_party/npapi/. -net/http/md4.cc -# Copyright IBM Corporation; MPL, GPL v2 or LGPL v2 license. This third-party -# code is taken from Mozilla, the license for which we already pick up from -# third_party/npapi/. -net/http/md4.h -# Netscape Communications Corporation; MPL, GPL v2 or LGPL v2 license. This -# third-party code is taken from Mozilla, the license for which we already pick -# up from third_party/npapi/. -net/proxy/proxy_resolver_script.h -# Contains the word 'Copyright' in comments -ppapi/generators/idl_c_proto.py -ppapi/generators/idl_outfile.py -# Copyright (c) 2007-2009 The Khronos Group Inc. Not used on Android -ppapi/lib/gl/include/EGL/egl.h -ppapi/lib/gl/include/EGL/eglext.h -ppapi/lib/gl/include/EGL/eglplatform.h -ppapi/lib/gl/include/KHR/khrplatform.h -# Copyright The Android Open Source Project; ASL v2 license. -skia/config/SkUserConfig.h -# Generates copyright headers for Chromium. -tools/boilerplate.py -# Contains test strings that look like copyrights. -tools/copyright_scanner/copyright_scanner_unittest.py -# Contains word 'copyright' in comments. -tools/gen_keyboard_overlay_data/gen_keyboard_overlay_data.py -# This third-party code is taken from Mozilla, but is copyright Google and has -# been re-licensed under the Chromium license. -tools/imagediff/image_diff_png.cc -# Copyright Ero Carrera; BSD license. Tool only. -tools/symsrc/pefile.py -# Copyright The Chromium Authors, Sun Microsystems Inc, the V8 project authors; -# BSD license. Tool only. -tools/traceline/traceline/assembler.h -# Copyright Google Inc; BSD license. Tool only. -tools/traceline/traceline/sidestep/mini_disassembler.cc -# Copyright Marijn Haverbeke. MIT license. Tool only, not used on Android. -tools/win/sizeviewer/clike.js -# Copyright Marijn Haverbeke. MIT license. Tool only, not used on Android. -tools/win/sizeviewer/codemirror.js -# Copyright The Chromium Authors, Apple Inc; BSD license. Not used on Android. -ui/base/clipboard/clipboard_util_win.cc -# Copyright The Chromium Authors, Apple Inc and Graham Dennis; BSD license. Not -# used on Android. -ui/base/cocoa/tool_tip_base_view.mm -# Copyright The Chromium Authors, Apple Inc; BSD license. Not used on Android. -ui/base/dragdrop/os_exchange_data_provider_win.cc -# Copyright Apple Inc; BSD license. Moved from third_party/WebKit/. -ui/events/blink/input_scroll_elasticity_controller.cc -ui/events/blink/input_scroll_elasticity_controller.h -# Copyright The Chromium Authors, Michael Emmel, Google Inc; BSD license. This -# third-party code is taken from WebKit, the license for which we already pick -# up from webkit/. -ui/events/keycodes/keyboard_codes_posix.h -# String 'copyright' used in code. -ui/file_manager/file_manager/foreground/js/main_scripts.js -# String 'copyright' used in code. -ui/file_manager/gallery/js/gallery_scripts.js -# String 'copyright' used in code. -ui/file_manager/video_player/js/video_player_scripts.js -# This third-party code is taken from Mozilla, but is copyright Google and has -# been re-licensed under the Chromium license. -ui/gfx/codec/jpeg_codec.cc -# This third-party code is taken from Mozilla, but is copyright Google and has -# been re-licensed under the Chromium license. -ui/gfx/codec/png_codec.cc -# Copyright The Chromium Authors and Apple Inc; BSD license. This third-party -# code is taken from WebKit, the license for which we already pick up from -# webkit/. -content/browser/appcache/appcache_manifest_parser.cc -# Copyright The Chromium Authors and Apple Inc; BSD license. This third-party -# code is taken from WebKit, the license for which we already pick up from -# webkit/. -content/browser/appcache/appcache_manifest_parser.h -# String 'copyright' used in code. -ui/webui/resources/js/cr/ui/array_data_model.js -# Bundles of existing code. -chrome/browser/resources/md_downloads/vulcanized.html -chrome/browser/resources/md_history/app.vulcanized.html -chrome/browser/resources/md_history/lazy_load.vulcanized.html -# Generated config files, which are checked in outside of the third-party -# library they configure. Copyright The open-vcdiff Authors; Apache2 license. -sdch/ios/config.h -sdch/linux/config.h -sdch/mac/config.h -sdch/win/config.h
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl index b48fa8ea..756d74f 100644 --- a/tools/mb/mb_config.pyl +++ b/tools/mb/mb_config.pyl
@@ -91,7 +91,7 @@ 'Linux ChromiumOS Builder': 'chromeos_with_codecs_release_bot', 'Linux ChromiumOS Builder (dbg)': 'chromeos_with_codecs_debug_bot', 'Linux ChromiumOS Full': 'chromeos_with_codecs_release_bot', - 'Linux ChromiumOS Ozone Builder': 'chromeos_with_codecs_ozone_release_bot', + 'Linux ChromiumOS Ozone Builder': 'chromeos_with_codecs_release_bot', }, 'chromium.fyi': { @@ -205,10 +205,10 @@ 'Linux remote_run Tester': 'release_bot', 'Mac deterministic': 'release_bot_mac_strip', 'Mac deterministic (dbg)': 'debug_bot', - 'Mojo ChromiumOS': 'chromeos_with_codecs_ozone_release_trybot', + 'Mojo ChromiumOS': 'chromeos_with_codecs_release_trybot', 'Mojo Linux': 'release_trybot', 'Mojo Windows': 'release_bot_x86_minimal_symbols', - 'Ozone Linux': 'release_bot_ozone_linux', + 'Ozone Linux': 'ozone_linux_release_bot', 'Site Isolation Android': 'android_release_bot_minimal_symbols_arm64', 'Site Isolation Linux': 'release_trybot', 'Site Isolation Win': 'release_trybot_x86', @@ -259,7 +259,7 @@ 'GPU Win x64 Builder': 'gpu_tests_deqp_gles_release_trybot', 'GPU Win x64 Builder (dbg)': 'gpu_tests_deqp_gles_debug_trybot', 'Linux ChromiumOS Builder': 'gpu_fyi_tests_chromeos_release_trybot', - 'Linux ChromiumOS Ozone Builder': 'gpu_fyi_tests_chromeos_ozone_release_trybot', + 'Linux ChromiumOS Ozone Builder': 'gpu_fyi_tests_chromeos_release_trybot', 'Linux GPU TSAN Release': 'gpu_fyi_tests_release_trybot_tsan', 'Mac GPU ASAN Release': 'gpu_fyi_tests_release_trybot_asan', }, @@ -539,7 +539,7 @@ 'linux_chromium_chromeos_compile_rel_ng': 'chromeos_with_codecs_release_trybot', 'linux_chromium_chromeos_dbg_ng': 'chromeos_with_codecs_debug_trybot', 'linux_chromium_chromeos_msan_rel_ng': 'chromeos_msan_release_bot', - 'linux_chromium_chromeos_ozone_rel_ng': 'chromeos_with_codecs_ozone_release_trybot', + 'linux_chromium_chromeos_ozone_rel_ng': 'chromeos_with_codecs_release_trybot', 'linux_chromium_chromeos_rel_ng': 'chromeos_with_codecs_release_trybot', 'linux_chromium_clobber_deterministic': 'release_trybot', 'linux_chromium_clobber_rel_ng': 'release_trybot', @@ -947,7 +947,7 @@ ], 'asan_lsan_chromeos_release_trybot': [ - 'asan', 'lsan', 'chromeos', 'x11_cros', 'release_trybot', + 'asan', 'lsan', 'chromeos', 'release_trybot', ], 'asan_lsan_edge_debug_bot': [ @@ -1015,35 +1015,27 @@ ], 'chromeos_asan_lsan_edge_fuzzer_v8_heap_release_bot': [ - 'chromeos', 'x11_cros', 'asan', 'lsan', 'edge', 'fuzzer', 'v8_heap', 'release_bot', + 'chromeos', 'asan', 'lsan', 'edge', 'fuzzer', 'v8_heap', 'release_bot', ], 'chromeos_msan_release_bot': [ - 'chromeos', 'x11_cros', 'msan', 'release_bot', + 'chromeos', 'msan', 'release_bot', ], 'chromeos_with_codecs_debug_bot': [ - 'chromeos_with_codecs', 'x11_cros', 'debug_bot', + 'chromeos_with_codecs', 'debug_bot', ], 'chromeos_with_codecs_debug_trybot': [ - 'chromeos_with_codecs', 'x11_cros', 'debug_trybot', - ], - - 'chromeos_with_codecs_ozone_release_bot': [ - 'chromeos_with_codecs', 'ozone', 'release_bot', - ], - - 'chromeos_with_codecs_ozone_release_trybot': [ - 'chromeos_with_codecs', 'ozone', 'release_trybot', + 'chromeos_with_codecs', 'debug_trybot', ], 'chromeos_with_codecs_release_bot': [ - 'chromeos_with_codecs', 'x11_cros', 'release_bot', + 'chromeos_with_codecs', 'release_bot', ], 'chromeos_with_codecs_release_trybot': [ - 'chromeos_with_codecs', 'x11_cros', 'release_trybot', + 'chromeos_with_codecs', 'release_trybot', ], 'clang_debug_trybot_x86': [ @@ -1170,7 +1162,7 @@ ], 'codesearch_gen_chromium_chromiumos_bot': [ - 'goma', 'clang', 'shared', 'debug', 'minimal_symbols', 'x64', 'chromeos', 'ozone', + 'goma', 'clang', 'shared', 'debug', 'minimal_symbols', 'x64', 'chromeos', ], 'codesearch_gen_chromium_linux_bot': [ @@ -1234,12 +1226,8 @@ 'debug_trybot', 'x86', ], - 'gpu_fyi_tests_chromeos_ozone_release_trybot': [ - 'gpu_fyi_tests', 'release_trybot', 'ozone', 'ozone_linux', 'system_gbm_libdrm', - ], - 'gpu_fyi_tests_chromeos_release_trybot': [ - 'gpu_fyi_tests', 'release_trybot', 'chromeos', 'x11_cros', + 'gpu_fyi_tests', 'release_trybot', 'chromeos', 'system_gbm_libdrm', ], 'gpu_fyi_tests_debug_trybot': [ @@ -1368,7 +1356,7 @@ ], 'official_goma_chromeos': [ - 'official', 'goma', 'chromeos', 'x11_cros', + 'official', 'goma', 'chromeos', ], 'official_goma_thin_lto_use_lld': [ @@ -1403,16 +1391,12 @@ 'official_optimize', 'chrome_pgo_phase_2', 'x86', ], - 'release_bot_ozone_linux': [ - 'release_bot', 'ozone', 'ozone_linux', - ], - - 'release_bot_fuchsia': [ - 'release_bot', 'fuchsia', + 'ozone_linux_release_bot': [ + 'ozone_linux', 'release_bot', ], 'ozone_linux_release_trybot': [ - 'release_trybot', 'ozone', 'ozone_linux', + 'ozone_linux', 'release_trybot', ], 'release_afl_asan': [ @@ -1435,6 +1419,10 @@ 'release_bot', 'chrome_with_codecs', ], + 'release_bot_fuchsia': [ + 'release_bot', 'fuchsia', + ], + 'release_bot_mac_new_sdk': [ 'release_bot', 'mac_new_sdk', ], @@ -1851,11 +1839,6 @@ 'gn_args': 'symbol_level=0', }, - 'x11_cros': { - # When use_ozone=false then use_x11=true. - 'gn_args': 'use_ozone=false', - }, - 'official': { 'mixins': ['official_optimize'], 'gn_args': 'is_chrome_branded=true', @@ -1869,16 +1852,12 @@ 'gn_args': 'optimize_for_fuzzing=true', }, - 'ozone': { - 'gn_args': 'use_ozone=true', - }, - 'ozone_linux': { 'gn_args': ('ozone_auto_platforms=false ozone_platform_wayland=true ' 'ozone_platform="x11" ' 'ozone_platform_x11=true ozone_platform_gbm=true ' 'enable_package_mash_services=true use_ash=false ' - 'use_xkbcommon=true'), + 'use_xkbcommon=true use_ozone=true'), }, 'fuchsia': {
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index bde0ced..389d9cc 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -40732,6 +40732,9 @@ </histogram> <histogram name="Net.Socket.IdleSocketReuseTime" units="seconds"> + <obsolete> + Deprecated as of 7/2017. + </obsolete> <owner>mmenke@chromium.org</owner> <summary> Seconds a socket was idle before it was reused. Emitted upon reuse. Does not @@ -50201,8 +50204,7 @@ </summary> </histogram> -<histogram name="PageLoad.Clients.Ads.Google.Bytes.AdFrames.Aggregate.Network" - units="KB"> +<histogram name="PageLoad.Bytes.AdFrames.Aggregate.Network" units="KB"> <owner>jkarlin@chromium.org</owner> <summary> The size (in KB) of the resources loaded for all of the ad frames on the @@ -50216,9 +50218,7 @@ </summary> </histogram> -<histogram - name="PageLoad.Clients.Ads.Google.Bytes.AdFrames.Aggregate.PercentNetwork" - units="%"> +<histogram name="PageLoad.Bytes.AdFrames.Aggregate.PercentNetwork" units="%"> <owner>jkarlin@chromium.org</owner> <summary> The percentage of bytes loaded for all ad frames that were loaded over the @@ -50232,8 +50232,7 @@ </summary> </histogram> -<histogram name="PageLoad.Clients.Ads.Google.Bytes.AdFrames.Aggregate.Total" - units="KB"> +<histogram name="PageLoad.Bytes.AdFrames.Aggregate.Total" units="KB"> <owner>jkarlin@chromium.org</owner> <summary> The size (in KB) of the resources loaded for all of the ad frames on the @@ -50247,8 +50246,7 @@ </summary> </histogram> -<histogram name="PageLoad.Clients.Ads.Google.Bytes.AdFrames.PerFrame.Network" - units="KB"> +<histogram name="PageLoad.Bytes.AdFrames.PerFrame.Network" units="KB"> <owner>jkarlin@chromium.org</owner> <summary> The size (in KB) of the resources loaded for an ad frame from the network. @@ -50261,9 +50259,7 @@ </summary> </histogram> -<histogram - name="PageLoad.Clients.Ads.Google.Bytes.AdFrames.PerFrame.PercentNetwork" - units="%"> +<histogram name="PageLoad.Bytes.AdFrames.PerFrame.PercentNetwork" units="%"> <owner>jkarlin@chromium.org</owner> <summary> The percentage of bytes loaded for a single ad frame that were loaded over @@ -50277,8 +50273,7 @@ </summary> </histogram> -<histogram name="PageLoad.Clients.Ads.Google.Bytes.AdFrames.PerFrame.Total" - units="KB"> +<histogram name="PageLoad.Bytes.AdFrames.PerFrame.Total" units="KB"> <owner>jkarlin@chromium.org</owner> <summary> The size (in KB) of the resources loaded for an ad frame. @@ -50291,7 +50286,7 @@ </summary> </histogram> -<histogram name="PageLoad.Clients.Ads.Google.Bytes.FullPage.Network" units="KB"> +<histogram name="PageLoad.Bytes.FullPage.Network" units="KB"> <owner>jkarlin@chromium.org</owner> <summary> The size (in KB) of all of the page's resources that loaded over the @@ -50303,8 +50298,7 @@ </summary> </histogram> -<histogram name="PageLoad.Clients.Ads.Google.Bytes.FullPage.Network.PercentAds" - units="%"> +<histogram name="PageLoad.Bytes.FullPage.Network.PercentAds" units="%"> <owner>jkarlin@chromium.org</owner> <summary> The percentage of bytes loaded for the page (from the network) that came @@ -50318,7 +50312,7 @@ </summary> </histogram> -<histogram name="PageLoad.Clients.Ads.Google.Bytes.FullPage.Total" units="KB"> +<histogram name="PageLoad.Bytes.FullPage.Total" units="KB"> <owner>jkarlin@chromium.org</owner> <summary> The size (in KB) of all of the page's resources. @@ -50329,8 +50323,7 @@ </summary> </histogram> -<histogram name="PageLoad.Clients.Ads.Google.Bytes.FullPage.Total.PercentAds" - units="%"> +<histogram name="PageLoad.Bytes.FullPage.Total.PercentAds" units="%"> <owner>jkarlin@chromium.org</owner> <summary> The percentage of bytes loaded for the page that came from resource loads in @@ -50344,8 +50337,7 @@ </summary> </histogram> -<histogram name="PageLoad.Clients.Ads.Google.Bytes.NonAdFrames.Aggregate.Total" - units="KB"> +<histogram name="PageLoad.Bytes.NonAdFrames.Aggregate.Total" units="KB"> <owner>jkarlin@chromium.org</owner> <summary> The size (in KB) of all of the page's resources except for those loaded in @@ -50359,18 +50351,51 @@ </summary> </histogram> -<histogram - name="PageLoad.Clients.Ads.Google.FrameCounts.AnyParentFrame.AdFrames" - units="Ad frames"> +<histogram name="PageLoad.Clients.Ads.All.Navigations.AdFrameRenavigatedToAd" + enum="DidNavigateToAd"> <owner>jkarlin@chromium.org</owner> <summary> - The number of frames on the page identified as Google Ad Frames that have - loaded more than 0 bytes of content. + When a frame that is (or previously was) an ad frame renavigates, record + whether it renavigated to an ad frame or a non-ad frame. - For pages with zero ad frames, the other PageLoad.Clients.Ads metrics are - not recorded unless otherwise specified. + An ad frame consists of the identified ad frame and all of its children. Its + children (which may also be ads) are not counted when they renavigate. - Child frames of an ad frame are not included in the count. + This metric is recorded as the event happens. Note that this is unlike most + other Clients.Ads metrics, which are recorded when the page load is + complete. + </summary> +</histogram> + +<histogram + name="PageLoad.Clients.Ads.All.Navigations.NonAdFrameRenavigatedToAd" + enum="DidNavigateToAd"> + <owner>jkarlin@chromium.org</owner> + <summary> + When a frame that has never been part of an ad frame renavigates, record + whether it renavigated to an ad frame or a non-ad frame. + + This metric is recorded as the event happens. Note that this is unlike most + other Clients.Ads metrics, which are recorded when the page load is + complete. + </summary> +</histogram> + +<histogram name="PageLoad.Clients.Ads.All.ParentExistsForSubFrame" + enum="ParentFrameKnown"> + <owner>jkarlin@chromium.org</owner> + <summary> + Records whether or not a parent frame is found for a subframe that finishes + navigating. + </summary> +</histogram> + +<histogram name="PageLoad.Clients.Ads.All.ResourceTypeWhenNoFrameFound" + enum="ContentResourceType2"> + <owner>jkarlin@chromium.org</owner> + <summary> + Records the content::ResourceType when a resource finishes loading but the + ads metrics aren't aware of a committed frame for the resource. </summary> </histogram> @@ -50424,6 +50449,10 @@ <histogram name="PageLoad.Clients.Ads.Google.Navigations.AdFrameRenavigatedToAd" enum="DidNavigateToAd"> + <obsolete> + Deprecated In July 2017. Use + PageLoad.Clients.Ads.All.Navigations.AdFrameRenavigatedToAd instead. + </obsolete> <owner>jkarlin@chromium.org</owner> <summary> When a frame that is (or previously was) an ad frame renavigates, record @@ -50441,6 +50470,10 @@ <histogram name="PageLoad.Clients.Ads.Google.Navigations.NonAdFrameRenavigatedToAd" enum="DidNavigateToAd"> + <obsolete> + Deprecated In July 2017. Use + PageLoad.Clients.Ads.All.Navigations.NonAdFrameRenavigatedToAd instead. + </obsolete> <owner>jkarlin@chromium.org</owner> <summary> When a frame that has never been part of an ad frame renavigates, record @@ -50454,6 +50487,10 @@ <histogram name="PageLoad.Clients.Ads.Google.ParentExistsForSubFrame" enum="ParentFrameKnown"> + <obsolete> + Deprecated In July 2017. Use + PageLoad.Clients.Ads.All.ParentExistsForSubFrame instead. + </obsolete> <owner>jkarlin@chromium.org</owner> <summary> Records whether or not a parent frame is found for a subframe that finishes @@ -50463,6 +50500,10 @@ <histogram name="PageLoad.Clients.Ads.Google.ResourceTypeWhenNoFrameFound" enum="ContentResourceType2"> + <obsolete> + Deprecated In July 2017. Use + PageLoad.Clients.Ads.All.ResourceTypeWhenNoFrameFound instead. + </obsolete> <owner>jkarlin@chromium.org</owner> <summary> Records the content::ResourceType when a resource finishes loading but the @@ -51159,6 +51200,20 @@ </summary> </histogram> +<histogram name="PageLoad.FrameCounts.AnyParentFrame.AdFrames" + units="Ad frames"> + <owner>jkarlin@chromium.org</owner> + <summary> + The number of frames on the page that have loaded more than 0 bytes of + content. + + For pages with zero ad frames, the other PageLoad.Clients.Ads metrics are + not recorded unless otherwise specified. + + Child frames of an ad frame are not included in the count. + </summary> +</histogram> + <histogram name="PageLoad.InputTiming.NavigationToFirstNonScroll.AfterPaint" units="ms"> <owner>tdresser@chromium.org</owner> @@ -88712,6 +88767,25 @@ <affected-histogram name="MobileStartup.IntentToCreationTime"/> </histogram_suffixes> +<histogram_suffixes name="AdsPageLoadMetrics" separator="." ordering="prefix"> + <suffix name="Clients.Ads.Google" label="Includes only Google ads."/> + <suffix name="Clients.Ads.SubresourceFilter" + label="Includes only ads discovered by the SubResourceFilter."/> + <suffix name="Clients.Ads.All" label="Includes all discovered ads."/> + <affected-histogram name="PageLoad.Bytes.AdFrames.Aggregate.Network"/> + <affected-histogram name="PageLoad.Bytes.AdFrames.Aggregate.PercentNetwork"/> + <affected-histogram name="PageLoad.Bytes.AdFrames.Aggregate.Total"/> + <affected-histogram name="PageLoad.Bytes.AdFrames.PerFrame.Network"/> + <affected-histogram name="PageLoad.Bytes.AdFrames.PerFrame.PercentNetwork"/> + <affected-histogram name="PageLoad.Bytes.AdFrames.PerFrame.Total"/> + <affected-histogram name="PageLoad.Bytes.FullPage.Network"/> + <affected-histogram name="PageLoad.Bytes.FullPage.Network.PercentAds"/> + <affected-histogram name="PageLoad.Bytes.FullPage.Total"/> + <affected-histogram name="PageLoad.Bytes.FullPage.Total.PercentAds"/> + <affected-histogram name="PageLoad.Bytes.NonAdFrames.Aggregate.Total"/> + <affected-histogram name="PageLoad.FrameCounts.AnyParentFrame.AdFrames"/> +</histogram_suffixes> + <histogram_suffixes name="AffiliationDummyData" separator="."> <suffix name="OnStartup" label="with the dummy data being requested shortly after start-up"/>
diff --git a/tools/perf/page_sets/update_webrtc_cases b/tools/perf/page_sets/update_webrtc_cases index 03a8218..01f55fe5 100755 --- a/tools/perf/page_sets/update_webrtc_cases +++ b/tools/perf/page_sets/update_webrtc_cases
@@ -24,6 +24,7 @@ 'src/multiple-peerconnections', 'src/pause-play', ], + 'revision': 'cbb12a3994692c63c9d885c95db0f67c5e3e3465', }, 'samples': { 'dirs': [ @@ -35,11 +36,13 @@ 'files': [ 'src/js/common.js', ], + 'revision': '6f9a14c10ee9b990d56c309d86d4b9129a4aa626', }, 'adapter': { 'files': [ 'release/adapter.js', ], + 'revision': '5b7ce4bdce79b9cb754fe27b097106e9491e0354', }, } @@ -132,13 +135,18 @@ os.makedirs(args.destination) with TemporaryDirectory() as temp_dir: - for repo_name, test_dirs in TEST_PAGES_LOCATION_BY_REPO.items(): + for repo_name, repo_info in TEST_PAGES_LOCATION_BY_REPO.items(): p = subprocess.Popen(['git', 'clone', WEBRTC_GITHUB_URL + repo_name], cwd=temp_dir) p.wait() - for test_dir in test_dirs.get('dirs', []): - test_dir = os.path.join(temp_dir, repo_name, test_dir) + repo_dir = os.path.join(temp_dir, repo_name) + p = subprocess.Popen(['git', 'checkout', repo_info.get('revision')], + cwd=repo_dir) + p.wait() + + for test_dir in repo_info.get('dirs', []): + test_dir = os.path.join(repo_dir, test_dir) test_name = os.path.basename(test_dir) CopyJSFile(os.path.join(test_dir, 'js', 'main.js'), @@ -146,7 +154,7 @@ CopyHTMLFile(test_name, os.path.join(test_dir, 'index.html'), os.path.join(args.destination, test_name + '.html')) - for test_file in test_dirs.get('files', []): + for test_file in repo_info.get('files', []): file_name = os.path.basename(test_file) CopyJSFile(os.path.join(temp_dir, repo_name, test_file), os.path.join(args.destination, file_name), False)
diff --git a/tools/tests/OWNERS b/tools/tests/OWNERS index 68295e64..704ad91 100644 --- a/tools/tests/OWNERS +++ b/tools/tests/OWNERS
@@ -1 +1,3 @@ -per-file licenses_test.py=file://tools/copyright_scanner/OWNERS +per-file licenses_test.py=phajdan.jr@chromium.org +per-file licenses_test.py=sgurun@chromium.org +per-file licenses_test.py=torne@chromium.org
diff --git a/ui/android/BUILD.gn b/ui/android/BUILD.gn index d2cba5c..df55761 100644 --- a/ui/android/BUILD.gn +++ b/ui/android/BUILD.gn
@@ -62,6 +62,7 @@ "//cc", "//cc/surfaces", "//components/viz/common", + "//components/viz/host", "//components/viz/service", "//skia", "//ui/base",
diff --git a/ui/android/DEPS b/ui/android/DEPS index 7f7f43f..410819d26 100644 --- a/ui/android/DEPS +++ b/ui/android/DEPS
@@ -8,6 +8,7 @@ "+cc/test/test_task_graph_runner.h", "+cc/trees/layer_tree_host.h", "+components/viz/common", + "+components/viz/host", "+components/viz/service/frame_sinks", "+jni", "+skia/ext",
diff --git a/ui/android/delegated_frame_host_android.cc b/ui/android/delegated_frame_host_android.cc index 95b4fb5..0bf08b5 100644 --- a/ui/android/delegated_frame_host_android.cc +++ b/ui/android/delegated_frame_host_android.cc
@@ -13,6 +13,7 @@ #include "cc/output/copy_output_result.h" #include "cc/surfaces/surface.h" #include "components/viz/common/surfaces/surface_id.h" +#include "components/viz/host/host_frame_sink_manager.h" #include "components/viz/service/frame_sinks/frame_sink_manager.h" #include "ui/android/view_android.h" #include "ui/android/window_android_compositor.h" @@ -51,11 +52,13 @@ DelegatedFrameHostAndroid::DelegatedFrameHostAndroid( ui::ViewAndroid* view, + viz::HostFrameSinkManager* host_frame_sink_manager, viz::FrameSinkManager* frame_sink_manager, Client* client, const viz::FrameSinkId& frame_sink_id) : frame_sink_id_(frame_sink_id), view_(view), + host_frame_sink_manager_(host_frame_sink_manager), frame_sink_manager_(frame_sink_manager), client_(client), begin_frame_source_(this) { @@ -199,9 +202,9 @@ constexpr bool handles_frame_sink_id_invalidation = false; constexpr bool needs_sync_points = true; support_.reset(); - support_ = viz::CompositorFrameSinkSupport::Create( - this, frame_sink_manager_, frame_sink_id_, is_root, - handles_frame_sink_id_invalidation, needs_sync_points); + support_ = host_frame_sink_manager_->CreateCompositorFrameSinkSupport( + this, frame_sink_id_, is_root, handles_frame_sink_id_invalidation, + needs_sync_points); } viz::SurfaceId DelegatedFrameHostAndroid::SurfaceId() const {
diff --git a/ui/android/delegated_frame_host_android.h b/ui/android/delegated_frame_host_android.h index 25fbcdc..56656fc 100644 --- a/ui/android/delegated_frame_host_android.h +++ b/ui/android/delegated_frame_host_android.h
@@ -17,12 +17,16 @@ namespace cc { class CompositorFrame; -class FrameSinkManager; class SurfaceLayer; enum class SurfaceDrawStatus; } // namespace cc +namespace viz { +class FrameSinkManager; +class HostFrameSinkManager; +} // namespace viz + namespace ui { class ViewAndroid; class WindowAndroidCompositor; @@ -40,6 +44,7 @@ }; DelegatedFrameHostAndroid(ViewAndroid* view, + viz::HostFrameSinkManager* host_frame_sink_manager, viz::FrameSinkManager* frame_sink_manager, Client* client, const viz::FrameSinkId& frame_sink_id); @@ -91,6 +96,7 @@ ViewAndroid* view_; + viz::HostFrameSinkManager* const host_frame_sink_manager_; viz::FrameSinkManager* const frame_sink_manager_; WindowAndroidCompositor* registered_parent_compositor_ = nullptr; Client* client_;
diff --git a/ui/aura/BUILD.gn b/ui/aura/BUILD.gn index 4f937e6d..2d22535 100644 --- a/ui/aura/BUILD.gn +++ b/ui/aura/BUILD.gn
@@ -143,6 +143,7 @@ "//components/discardable_memory/client", "//components/discardable_memory/public/interfaces", "//components/viz/client", + "//components/viz/host", "//components/viz/service", "//gpu/ipc/client", "//mojo/public/cpp/system",
diff --git a/ui/aura/DEPS b/ui/aura/DEPS index 865926c..cad39bb 100644 --- a/ui/aura/DEPS +++ b/ui/aura/DEPS
@@ -3,6 +3,7 @@ "+cc/output", "+cc/surfaces", "+components/viz/common", + "+components/viz/host", "+mojo/common", "+mojo/public/cpp/bindings", "+net/base/filename_util.h",
diff --git a/ui/aura/local/layer_tree_frame_sink_local.cc b/ui/aura/local/layer_tree_frame_sink_local.cc index a9adb3d..0a2a064e 100644 --- a/ui/aura/local/layer_tree_frame_sink_local.cc +++ b/ui/aura/local/layer_tree_frame_sink_local.cc
@@ -5,6 +5,7 @@ #include "ui/aura/local/layer_tree_frame_sink_local.h" #include "cc/output/layer_tree_frame_sink_client.h" +#include "components/viz/host/host_frame_sink_manager.h" #include "components/viz/service/frame_sinks/compositor_frame_sink_support.h" #include "ui/aura/client/cursor_client.h" #include "ui/aura/env.h" @@ -17,10 +18,10 @@ LayerTreeFrameSinkLocal::LayerTreeFrameSinkLocal( const viz::FrameSinkId& frame_sink_id, - viz::FrameSinkManager* frame_sink_manager) + viz::HostFrameSinkManager* host_frame_sink_manager) : cc::LayerTreeFrameSink(nullptr, nullptr, nullptr, nullptr), frame_sink_id_(frame_sink_id), - frame_sink_manager_(frame_sink_manager) {} + host_frame_sink_manager_(host_frame_sink_manager) {} LayerTreeFrameSinkLocal::~LayerTreeFrameSinkLocal() {} @@ -31,8 +32,8 @@ DCHECK(!thread_checker_); thread_checker_ = base::MakeUnique<base::ThreadChecker>(); - support_ = viz::CompositorFrameSinkSupport::Create( - this, frame_sink_manager_, frame_sink_id_, false /* is_root */, + support_ = host_frame_sink_manager_->CreateCompositorFrameSinkSupport( + this, frame_sink_id_, false /* is_root */, true /* handles_frame_sink_id_invalidation */, true /* needs_sync_points */); begin_frame_source_ = base::MakeUnique<cc::ExternalBeginFrameSource>(this);
diff --git a/ui/aura/local/layer_tree_frame_sink_local.h b/ui/aura/local/layer_tree_frame_sink_local.h index 7a37fbe..c7b22d2c 100644 --- a/ui/aura/local/layer_tree_frame_sink_local.h +++ b/ui/aura/local/layer_tree_frame_sink_local.h
@@ -16,8 +16,8 @@ #include "ui/base/property_data.h" namespace viz { -class FrameSinkManager; class CompositorFrameSinkSupport; +class HostFrameSinkManager; } namespace aura { @@ -31,7 +31,7 @@ public cc::ExternalBeginFrameSourceClient { public: LayerTreeFrameSinkLocal(const viz::FrameSinkId& frame_sink_id, - viz::FrameSinkManager* frame_sink_manager); + viz::HostFrameSinkManager* host_frame_sink_manager); ~LayerTreeFrameSinkLocal() override; using SurfaceChangedCallback = @@ -59,7 +59,7 @@ private: const viz::FrameSinkId frame_sink_id_; - viz::FrameSinkManager* const frame_sink_manager_; + viz::HostFrameSinkManager* const host_frame_sink_manager_; std::unique_ptr<viz::CompositorFrameSinkSupport> support_; gfx::Size surface_size_; float device_scale_factor_ = 0;
diff --git a/ui/aura/local/window_port_local.cc b/ui/aura/local/window_port_local.cc index aeb7ebf..9c8e70a 100644 --- a/ui/aura/local/window_port_local.cc +++ b/ui/aura/local/window_port_local.cc
@@ -103,7 +103,7 @@ aura::Env::GetInstance()->context_factory_private(); frame_sink_id_ = context_factory_private->AllocateFrameSinkId(); auto frame_sink = base::MakeUnique<LayerTreeFrameSinkLocal>( - frame_sink_id_, context_factory_private->GetFrameSinkManager()); + frame_sink_id_, context_factory_private->GetHostFrameSinkManager()); frame_sink->SetSurfaceChangedCallback(base::Bind( &WindowPortLocal::OnSurfaceChanged, weak_factory_.GetWeakPtr())); if (window_->GetRootWindow())
diff --git a/ui/compositor/test/context_factories_for_test.cc b/ui/compositor/test/context_factories_for_test.cc index 75d15bd9..2ef06c0c 100644 --- a/ui/compositor/test/context_factories_for_test.cc +++ b/ui/compositor/test/context_factories_for_test.cc
@@ -6,9 +6,7 @@ #include "base/command_line.h" #include "base/sys_info.h" -#include "base/threading/sequenced_task_runner_handle.h" #include "components/viz/host/host_frame_sink_manager.h" -#include "components/viz/service/frame_sinks/frame_sink_manager.h" #include "components/viz/service/frame_sinks/frame_sink_manager_impl.h" #include "ui/compositor/compositor.h" #include "ui/compositor/compositor_switches.h" @@ -24,21 +22,9 @@ // Connect HostFrameSinkManager to FrameSinkManagerImpl. void ConnectFrameSinkManager() { - // Interfaces and requests to bind to each of the interfaces. - cc::mojom::FrameSinkManagerClientPtr host_mojo; - cc::mojom::FrameSinkManagerPtr manager_mojo; - cc::mojom::FrameSinkManagerClientRequest host_mojo_request = - mojo::MakeRequest(&host_mojo); - cc::mojom::FrameSinkManagerRequest manager_mojo_request = - mojo::MakeRequest(&manager_mojo); - - // Make the Mojo connections on both ends. - g_frame_sink_manager_impl->BindAndSetClient( - std::move(manager_mojo_request), base::SequencedTaskRunnerHandle::Get(), - std::move(host_mojo)); - g_host_frame_sink_manager->BindAndSetManager( - std::move(host_mojo_request), base::SequencedTaskRunnerHandle::Get(), - std::move(manager_mojo)); + // Directly connect without using Mojo. + g_frame_sink_manager_impl->SetLocalClient(g_host_frame_sink_manager); + g_host_frame_sink_manager->SetLocalManager(g_frame_sink_manager_impl); } } // namespace
diff --git a/ui/compositor/test/fake_context_factory.h b/ui/compositor/test/fake_context_factory.h index 5761aa2..a69a1fc 100644 --- a/ui/compositor/test/fake_context_factory.h +++ b/ui/compositor/test/fake_context_factory.h
@@ -40,6 +40,11 @@ void AddObserver(ui::ContextFactoryObserver* observer) override {} void RemoveObserver(ui::ContextFactoryObserver* observer) override {} + protected: + const cc::RendererSettings& renderer_settings() const { + return renderer_settings_; + } + private: cc::FakeLayerTreeFrameSink* frame_sink_ = nullptr; cc::TestTaskGraphRunner task_graph_runner_;
diff --git a/ui/compositor/test/in_process_context_factory.cc b/ui/compositor/test/in_process_context_factory.cc index b34ef4f..b36a7ac 100644 --- a/ui/compositor/test/in_process_context_factory.cc +++ b/ui/compositor/test/in_process_context_factory.cc
@@ -253,9 +253,10 @@ auto* display = per_compositor_data_[compositor.get()]->display.get(); auto layer_tree_frame_sink = base::MakeUnique<viz::DirectLayerTreeFrameSink>( - compositor->frame_sink_id(), GetFrameSinkManager(), display, - context_provider, shared_worker_context_provider_, - &gpu_memory_buffer_manager_, &shared_bitmap_manager_); + compositor->frame_sink_id(), GetHostFrameSinkManager(), + GetFrameSinkManager(), display, context_provider, + shared_worker_context_provider_, &gpu_memory_buffer_manager_, + &shared_bitmap_manager_); compositor->SetLayerTreeFrameSink(std::move(layer_tree_frame_sink)); data->display->Resize(compositor->size());