diff --git a/DEPS b/DEPS index fbc03ab..35cfd74 100644 --- a/DEPS +++ b/DEPS
@@ -44,7 +44,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': '11f9b0549e4409f0daab970f20be3c62cadecd4d', + 'v8_revision': '3d7c892d19ff27d4b8c046c50b68116814c4d746', # 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.
diff --git a/android_webview/tools/system_webview_shell/layout_tests/src/org/chromium/webview_shell/test/WebViewLayoutTest.java b/android_webview/tools/system_webview_shell/layout_tests/src/org/chromium/webview_shell/test/WebViewLayoutTest.java index e4dee47..03f8188 100644 --- a/android_webview/tools/system_webview_shell/layout_tests/src/org/chromium/webview_shell/test/WebViewLayoutTest.java +++ b/android_webview/tools/system_webview_shell/layout_tests/src/org/chromium/webview_shell/test/WebViewLayoutTest.java
@@ -193,7 +193,6 @@ @Test @MediumTest - @DisabledTest(message = "crbug.com/719974") public void testWebViewIncludedStableInterfaces() throws Exception { ensureJsTestCopied(); loadUrlWebViewAsync("file://" + PATH_BLINK_PREFIX
diff --git a/android_webview/tools/system_webview_shell/test/data/webexposed/not-webview-exposed.txt b/android_webview/tools/system_webview_shell/test/data/webexposed/not-webview-exposed.txt index e2db01cf..950ad60 100644 --- a/android_webview/tools/system_webview_shell/test/data/webexposed/not-webview-exposed.txt +++ b/android_webview/tools/system_webview_shell/test/data/webexposed/not-webview-exposed.txt
@@ -41,6 +41,7 @@ # web payments api not enabled in webiew, crbug.com/667069 interface HTMLIFrameElement : HTMLElement + getter allowPaymentRequest setter allowPaymentRequest # Android does not support switching the audio output device, crbug.com/589500
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/childaccounts/ChildAccountService.java b/chrome/android/java/src/org/chromium/chrome/browser/childaccounts/ChildAccountService.java index c3c9262e..1a91056 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/childaccounts/ChildAccountService.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/childaccounts/ChildAccountService.java
@@ -55,16 +55,6 @@ } /** - * Returns the previously determined value of whether there is a child account on the device. - * Should only be called after the native library and profile have been loaded. - * - * @return The previously determined value of whether there is a child account on the device. - */ - public static boolean isChildAccount() { - return nativeIsChildAccount(); - } - - /** * Set a callback to be called the next time a child account status change is received * @param callback the callback to be called when the status changes. */ @@ -97,8 +87,6 @@ }); } - private static native boolean nativeIsChildAccount(); - private static native void nativeListenForChildStatusReceived(Callback<Boolean> callback); private static native void nativeOnReauthenticationResult(
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SectionList.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SectionList.java index 53c63681..6150503 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SectionList.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SectionList.java
@@ -68,14 +68,11 @@ int categoryIndex = 0; for (int category : categories) { int categoryStatus = suggestionsSource.getCategoryStatus(category); - if (categoryStatus == CategoryStatus.LOADING_ERROR - || categoryStatus == CategoryStatus.NOT_PROVIDED - || categoryStatus == CategoryStatus.CATEGORY_EXPLICITLY_DISABLED) { - continue; + int suggestionsCount = 0; + if (SnippetsBridge.isCategoryEnabled(categoryStatus)) { + suggestionsCount = resetSection(category, categoryStatus, alwaysAllowEmptySections); } - - suggestionsPerCategory[categoryIndex] = - resetSection(category, categoryStatus, alwaysAllowEmptySections); + suggestionsPerCategory[categoryIndex] = suggestionsCount; ++categoryIndex; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/profiles/Profile.java b/chrome/android/java/src/org/chromium/chrome/browser/profiles/Profile.java index 9637c6a..fd5c15c2 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/profiles/Profile.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/profiles/Profile.java
@@ -64,6 +64,13 @@ } /** + * @return Whether the profile is signed in to a child account. + */ + public boolean isChild() { + return nativeIsChild(mNativeProfileAndroid); + } + + /** * @return Whether or not the native side profile exists. */ @VisibleForTesting @@ -97,4 +104,5 @@ private native Object nativeGetOffTheRecordProfile(long nativeProfileAndroid); private native boolean nativeHasOffTheRecordProfile(long nativeProfileAndroid); private native boolean nativeIsOffTheRecord(long nativeProfileAndroid); + private native boolean nativeIsChild(long nativeProfileAndroid); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountManagementFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountManagementFragment.java index 5b4e0af..3e7b971 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountManagementFragment.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountManagementFragment.java
@@ -38,7 +38,6 @@ import org.chromium.base.metrics.RecordUserAction; import org.chromium.chrome.R; import org.chromium.chrome.browser.AppHooks; -import org.chromium.chrome.browser.childaccounts.ChildAccountService; import org.chromium.chrome.browser.preferences.ChromeBasePreference; import org.chromium.chrome.browser.preferences.ManagedPreferenceDelegate; import org.chromium.chrome.browser.preferences.PrefServiceBridge; @@ -117,6 +116,8 @@ private ArrayList<Preference> mAccountsListPreferences = new ArrayList<Preference>(); + private Profile mProfile; + @Override public void onCreate(Bundle savedState) { super.onCreate(savedState); @@ -134,6 +135,8 @@ getArguments().getInt(SHOW_GAIA_SERVICE_TYPE_EXTRA, mGaiaServiceType); } + mProfile = Profile.getLastUsedProfile(); + AccountManagementScreenHelper.logEvent( ProfileAccountManagementMetrics.VIEW, mGaiaServiceType); @@ -233,10 +236,8 @@ } private void configureSignOutSwitch() { - boolean isChildAccount = ChildAccountService.isChildAccount(); - Preference signOutSwitch = findPreference(PREF_SIGN_OUT); - if (isChildAccount) { + if (mProfile.isChild()) { getPreferenceScreen().removePreference(signOutSwitch); } else { signOutSwitch.setEnabled(getSignOutAllowedPreferenceValue(getActivity())); @@ -301,7 +302,7 @@ private void configureGoogleActivityControls() { Preference pref = findPreference(PREF_GOOGLE_ACTIVITY_CONTROLS); - if (ChildAccountService.isChildAccount()) { + if (mProfile.isChild()) { pref.setSummary(R.string.sign_in_google_activity_controls_message_child_account); } pref.setOnPreferenceClickListener(new OnPreferenceClickListener() { @@ -319,7 +320,7 @@ private void configureAddAccountPreference() { ChromeBasePreference addAccount = (ChromeBasePreference) findPreference(PREF_ADD_ACCOUNT); - if (ChildAccountService.isChildAccount()) { + if (mProfile.isChild()) { getPreferenceScreen().removePreference(addAccount); } else { addAccount.setTitle(getResources().getString( @@ -356,7 +357,7 @@ private void configureChildAccountPreferences() { Preference parentAccounts = findPreference(PREF_PARENT_ACCOUNTS); Preference childContent = findPreference(PREF_CHILD_CONTENT); - if (ChildAccountService.isChildAccount()) { + if (mProfile.isChild()) { Resources res = getActivity().getResources(); PrefServiceBridge prefService = PrefServiceBridge.getInstance(); @@ -423,7 +424,7 @@ pref.setSelectable(false); pref.setTitle(account.name); - boolean isChildAccount = ChildAccountService.isChildAccount(); + boolean isChildAccount = mProfile.isChild(); pref.setUseReducedPadding(isChildAccount); pref.setIcon(new BitmapDrawable(getResources(), isChildAccount ? getBadgedUserPicture(account.name, getResources()) :
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/SyncController.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/SyncController.java index 14d8da28..ee09c158 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/sync/SyncController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/SyncController.java
@@ -16,10 +16,10 @@ import org.chromium.base.VisibleForTesting; import org.chromium.base.metrics.RecordHistogram; import org.chromium.chrome.browser.AppHooks; -import org.chromium.chrome.browser.childaccounts.ChildAccountService; import org.chromium.chrome.browser.identity.UniqueIdentificationGenerator; import org.chromium.chrome.browser.identity.UniqueIdentificationGeneratorFactory; import org.chromium.chrome.browser.invalidation.InvalidationController; +import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.signin.AccountManagementFragment; import org.chromium.chrome.browser.signin.SigninManager; import org.chromium.chrome.browser.sync.ui.PassphraseActivity; @@ -147,7 +147,7 @@ if (isSyncEnabled) { mProfileSyncService.requestStart(); } else { - if (ChildAccountService.isChildAccount()) { + if (Profile.getLastUsedProfile().isChild()) { // For child accounts, Sync needs to stay enabled, so we reenable it in settings. // TODO(bauerb): Remove the dependency on child account code and instead go through // prefs (here and in the Sync customization UI).
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/SyncCustomizationFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/SyncCustomizationFragment.java index 7e5abc0..e2de479 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/SyncCustomizationFragment.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/SyncCustomizationFragment.java
@@ -35,10 +35,10 @@ import org.chromium.base.metrics.RecordHistogram; import org.chromium.chrome.R; import org.chromium.chrome.browser.autofill.PersonalDataManager; -import org.chromium.chrome.browser.childaccounts.ChildAccountService; import org.chromium.chrome.browser.invalidation.InvalidationController; import org.chromium.chrome.browser.preferences.ChromeSwitchPreference; import org.chromium.chrome.browser.preferences.SyncedAccountPreference; +import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.signin.SigninManager; import org.chromium.chrome.browser.sync.GoogleServiceAuthError; import org.chromium.chrome.browser.sync.ProfileSyncService; @@ -253,7 +253,7 @@ * @return Whether Sync can be disabled. */ private boolean canDisableSync() { - return !ChildAccountService.isChildAccount(); + return !Profile.getLastUsedProfile().isChild(); } private boolean isSyncTypePreference(Preference preference) {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/history/HistoryActivityTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/history/HistoryActivityTest.java index 93f8ac9..e52f2f8 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/history/HistoryActivityTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/history/HistoryActivityTest.java
@@ -28,8 +28,8 @@ import org.chromium.base.test.util.Restriction; import org.chromium.chrome.R; import org.chromium.chrome.browser.IntentHandler; -import org.chromium.chrome.browser.childaccounts.ChildAccountService; import org.chromium.chrome.browser.preferences.PrefServiceBridge; +import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.signin.SigninManager; import org.chromium.chrome.browser.signin.SigninManager.SignInStateObserver; import org.chromium.chrome.browser.widget.TintedImageButton; @@ -511,7 +511,7 @@ @Override public Boolean call() throws Exception { PrefServiceBridge.getInstance().setSupervisedUserId("ChildAccountSUID"); - return ChildAccountService.isChildAccount() + return Profile.getLastUsedProfile().isChild() && !PrefServiceBridge.getInstance().canDeleteBrowsingHistory() && !PrefServiceBridge.getInstance().isIncognitoModeEnabled(); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/superviseduser/SupervisedUserContentProviderTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/superviseduser/SupervisedUserContentProviderTest.java index 209bb2ea..d3e02de 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/superviseduser/SupervisedUserContentProviderTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/superviseduser/SupervisedUserContentProviderTest.java
@@ -25,8 +25,8 @@ import org.chromium.base.test.util.RetryOnFailure; import org.chromium.chrome.browser.ChromeActivity; import org.chromium.chrome.browser.ChromeSwitches; -import org.chromium.chrome.browser.childaccounts.ChildAccountService; import org.chromium.chrome.browser.preferences.PrefServiceBridge; +import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.test.ChromeActivityTestRule; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.util.browser.signin.SigninTestUtil; @@ -99,7 +99,7 @@ @Override public Boolean call() throws Exception { PrefServiceBridge.getInstance().setSupervisedUserId(""); - return ChildAccountService.isChildAccount(); + return Profile.getLastUsedProfile().isChild(); } })); @@ -124,7 +124,7 @@ @Override public Boolean call() throws Exception { PrefServiceBridge.getInstance().setSupervisedUserId("ChildAccountSUID"); - return ChildAccountService.isChildAccount(); + return Profile.getLastUsedProfile().isChild(); } }));
diff --git a/chrome/android/webapk/shell_apk/BUILD.gn b/chrome/android/webapk/shell_apk/BUILD.gn index 2a9adc89..f1f4c0f0 100644 --- a/chrome/android/webapk/shell_apk/BUILD.gn +++ b/chrome/android/webapk/shell_apk/BUILD.gn
@@ -105,6 +105,9 @@ android_resources("shell_apk_resources") { resource_dirs = [ "res" ] custom_package = "org.chromium.webapk.shell_apk" + deps = [ + ":webapk_strings_grd", + ] } android_library("webapk_java") { @@ -152,6 +155,57 @@ } } +java_strings_grd("webapk_strings_grd") { + grd_file = "//chrome/android/webapk/strings/android_webapk_strings.grd" + + outputs = [ + "values-am/android_webapk_strings.xml", + "values-ar/android_webapk_strings.xml", + "values-bg/android_webapk_strings.xml", + "values-ca/android_webapk_strings.xml", + "values-cs/android_webapk_strings.xml", + "values-da/android_webapk_strings.xml", + "values-de/android_webapk_strings.xml", + "values-el/android_webapk_strings.xml", + "values/android_webapk_strings.xml", + "values-en-rGB/android_webapk_strings.xml", + "values-es/android_webapk_strings.xml", + "values-es-rUS/android_webapk_strings.xml", + "values-fa/android_webapk_strings.xml", + "values-fi/android_webapk_strings.xml", + "values-tl/android_webapk_strings.xml", + "values-fr/android_webapk_strings.xml", + "values-hi/android_webapk_strings.xml", + "values-hr/android_webapk_strings.xml", + "values-hu/android_webapk_strings.xml", + "values-in/android_webapk_strings.xml", + "values-it/android_webapk_strings.xml", + "values-iw/android_webapk_strings.xml", + "values-ja/android_webapk_strings.xml", + "values-ko/android_webapk_strings.xml", + "values-lt/android_webapk_strings.xml", + "values-lv/android_webapk_strings.xml", + "values-nl/android_webapk_strings.xml", + "values-nb/android_webapk_strings.xml", + "values-pl/android_webapk_strings.xml", + "values-pt-rBR/android_webapk_strings.xml", + "values-pt-rPT/android_webapk_strings.xml", + "values-ro/android_webapk_strings.xml", + "values-ru/android_webapk_strings.xml", + "values-sk/android_webapk_strings.xml", + "values-sl/android_webapk_strings.xml", + "values-sr/android_webapk_strings.xml", + "values-sv/android_webapk_strings.xml", + "values-sw/android_webapk_strings.xml", + "values-th/android_webapk_strings.xml", + "values-tr/android_webapk_strings.xml", + "values-uk/android_webapk_strings.xml", + "values-vi/android_webapk_strings.xml", + "values-zh-rCN/android_webapk_strings.xml", + "values-zh-rTW/android_webapk_strings.xml", + ] +} + # Template for WebAPK. When a WebAPK is generated: # - Android manifest is customized to the website. # - App icon is extracted from the website and added to the APK's resources.
diff --git a/chrome/android/webapk/strings/android_webapk_strings.grd b/chrome/android/webapk/strings/android_webapk_strings.grd new file mode 100644 index 0000000..8461366 --- /dev/null +++ b/chrome/android/webapk/strings/android_webapk_strings.grd
@@ -0,0 +1,106 @@ +<?xml version="1.0" encoding="UTF-8"?> +<grit latest_public_release="0" current_release="1" output_all_resource_defines="false"> + <outputs> + <output filename="values-am/android_webapk_strings.xml" lang="am" type="android" /> + <output filename="values-ar/android_webapk_strings.xml" lang="ar" type="android" /> + <output filename="values-bg/android_webapk_strings.xml" lang="bg" type="android" /> + <output filename="values-ca/android_webapk_strings.xml" lang="ca" type="android" /> + <output filename="values-cs/android_webapk_strings.xml" lang="cs" type="android" /> + <output filename="values-da/android_webapk_strings.xml" lang="da" type="android" /> + <output filename="values-de/android_webapk_strings.xml" lang="de" type="android" /> + <output filename="values-el/android_webapk_strings.xml" lang="el" type="android" /> + <output filename="values/android_webapk_strings.xml" lang="en" type="android" /> + <output filename="values-en-rGB/android_webapk_strings.xml" lang="en-GB" type="android" /> + <output filename="values-es/android_webapk_strings.xml" lang="es" type="android" /> + <output filename="values-es-rUS/android_webapk_strings.xml" lang="es-419" type="android" /> + <output filename="values-fa/android_webapk_strings.xml" lang="fa" type="android" /> + <output filename="values-fi/android_webapk_strings.xml" lang="fi" type="android" /> + <output filename="values-tl/android_webapk_strings.xml" lang="fil" type="android" /> + <output filename="values-fr/android_webapk_strings.xml" lang="fr" type="android" /> + <output filename="values-hi/android_webapk_strings.xml" lang="hi" type="android" /> + <output filename="values-hr/android_webapk_strings.xml" lang="hr" type="android" /> + <output filename="values-hu/android_webapk_strings.xml" lang="hu" type="android" /> + <output filename="values-in/android_webapk_strings.xml" lang="id" type="android" /> + <output filename="values-it/android_webapk_strings.xml" lang="it" type="android" /> + <output filename="values-iw/android_webapk_strings.xml" lang="iw" type="android" /> + <output filename="values-ja/android_webapk_strings.xml" lang="ja" type="android" /> + <output filename="values-ko/android_webapk_strings.xml" lang="ko" type="android" /> + <output filename="values-lt/android_webapk_strings.xml" lang="lt" type="android" /> + <output filename="values-lv/android_webapk_strings.xml" lang="lv" type="android" /> + <output filename="values-nl/android_webapk_strings.xml" lang="nl" type="android" /> + <output filename="values-nb/android_webapk_strings.xml" lang="no" type="android" /> + <output filename="values-pl/android_webapk_strings.xml" lang="pl" type="android" /> + <output filename="values-pt-rBR/android_webapk_strings.xml" lang="pt-BR" type="android" /> + <output filename="values-pt-rPT/android_webapk_strings.xml" lang="pt-PT" type="android" /> + <output filename="values-ro/android_webapk_strings.xml" lang="ro" type="android" /> + <output filename="values-ru/android_webapk_strings.xml" lang="ru" type="android" /> + <output filename="values-sk/android_webapk_strings.xml" lang="sk" type="android" /> + <output filename="values-sl/android_webapk_strings.xml" lang="sl" type="android" /> + <output filename="values-sr/android_webapk_strings.xml" lang="sr" type="android" /> + <output filename="values-sv/android_webapk_strings.xml" lang="sv" type="android" /> + <output filename="values-sw/android_webapk_strings.xml" lang="sw" type="android" /> + <output filename="values-th/android_webapk_strings.xml" lang="th" type="android" /> + <output filename="values-tr/android_webapk_strings.xml" lang="tr" type="android" /> + <output filename="values-uk/android_webapk_strings.xml" lang="uk" type="android" /> + <output filename="values-vi/android_webapk_strings.xml" lang="vi" type="android" /> + <output filename="values-zh-rCN/android_webapk_strings.xml" lang="zh-CN" type="android" /> + <output filename="values-zh-rTW/android_webapk_strings.xml" lang="zh-TW" type="android" /> + </outputs> + <translations> + <file lang="am" path="translations/android_webapk_strings_am.xtb" /> + <file lang="ar" path="translations/android_webapk_strings_ar.xtb" /> + <file lang="bg" path="translations/android_webapk_strings_bg.xtb" /> + <file lang="ca" path="translations/android_webapk_strings_ca.xtb" /> + <file lang="cs" path="translations/android_webapk_strings_cs.xtb" /> + <file lang="da" path="translations/android_webapk_strings_da.xtb" /> + <file lang="de" path="translations/android_webapk_strings_de.xtb" /> + <file lang="el" path="translations/android_webapk_strings_el.xtb" /> + <file lang="en-GB" path="translations/android_webapk_strings_en-GB.xtb" /> + <file lang="es" path="translations/android_webapk_strings_es.xtb" /> + <file lang="es-419" path="translations/android_webapk_strings_es-419.xtb" /> + <file lang="fa" path="translations/android_webapk_strings_fa.xtb" /> + <file lang="fi" path="translations/android_webapk_strings_fi.xtb" /> + <file lang="fil" path="translations/android_webapk_strings_fil.xtb" /> + <file lang="fr" path="translations/android_webapk_strings_fr.xtb" /> + <file lang="hi" path="translations/android_webapk_strings_hi.xtb" /> + <file lang="hr" path="translations/android_webapk_strings_hr.xtb" /> + <file lang="hu" path="translations/android_webapk_strings_hu.xtb" /> + <file lang="id" path="translations/android_webapk_strings_id.xtb" /> + <file lang="it" path="translations/android_webapk_strings_it.xtb" /> + <file lang="iw" path="translations/android_webapk_strings_iw.xtb" /> + <file lang="ja" path="translations/android_webapk_strings_ja.xtb" /> + <file lang="ko" path="translations/android_webapk_strings_ko.xtb" /> + <file lang="lt" path="translations/android_webapk_strings_lt.xtb" /> + <file lang="lv" path="translations/android_webapk_strings_lv.xtb" /> + <file lang="nl" path="translations/android_webapk_strings_nl.xtb" /> + <file lang="no" path="translations/android_webapk_strings_no.xtb" /> + <file lang="pl" path="translations/android_webapk_strings_pl.xtb" /> + <file lang="pt-BR" path="translations/android_webapk_strings_pt-BR.xtb" /> + <file lang="pt-PT" path="translations/android_webapk_strings_pt-PT.xtb" /> + <file lang="ro" path="translations/android_webapk_strings_ro.xtb" /> + <file lang="ru" path="translations/android_webapk_strings_ru.xtb" /> + <file lang="sk" path="translations/android_webapk_strings_sk.xtb" /> + <file lang="sl" path="translations/android_webapk_strings_sl.xtb" /> + <file lang="sr" path="translations/android_webapk_strings_sr.xtb" /> + <file lang="sv" path="translations/android_webapk_strings_sv.xtb" /> + <file lang="sw" path="translations/android_webapk_strings_sw.xtb" /> + <file lang="th" path="translations/android_webapk_strings_th.xtb" /> + <file lang="tr" path="translations/android_webapk_strings_tr.xtb" /> + <file lang="uk" path="translations/android_webapk_strings_uk.xtb" /> + <file lang="vi" path="translations/android_webapk_strings_vi.xtb" /> + <file lang="zh-CN" path="translations/android_webapk_strings_zh-CN.xtb" /> + <file lang="zh-TW" path="translations/android_webapk_strings_zh-TW.xtb" /> + </translations> + <release allow_pseudo="false" seq="1"> + <messages fallback_to_english="true"> + <!-- Select host browser dialog --> + <message name="IDS_CHOOSE_HOST_BROWSER_DIALOG_TITLE" desc="Title for the host browser picker dialog, which is used to ask users to pick a browser to launch the installed WebAPK."> + <ph name="WEBAPK_SITE">%1$s<ex>Housing.com</ex></ph> needs a Web browser to run + </message> + <message name="IDS_CHOOSE_HOST_BROWSER" desc="Content for the host browser picker dialog, which is used to ask users to pick a browser to launch the installed WebAPK."> + Please select the browser you'd like to use to run <ph name="WEBAPK_SITE">%1$s<ex>Housing.com</ex></ph> + </message> + + </messages> + </release> +</grit>
diff --git a/chrome/android/webapk/strings/translations/android_webapk_strings_am.xtb b/chrome/android/webapk/strings/translations/android_webapk_strings_am.xtb new file mode 100644 index 0000000..92406ec2 --- /dev/null +++ b/chrome/android/webapk/strings/translations/android_webapk_strings_am.xtb
@@ -0,0 +1,4 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="am"> +</translationbundle> \ No newline at end of file
diff --git a/chrome/android/webapk/strings/translations/android_webapk_strings_ar.xtb b/chrome/android/webapk/strings/translations/android_webapk_strings_ar.xtb new file mode 100644 index 0000000..198ea62 --- /dev/null +++ b/chrome/android/webapk/strings/translations/android_webapk_strings_ar.xtb
@@ -0,0 +1,4 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="ar"> +</translationbundle> \ No newline at end of file
diff --git a/chrome/android/webapk/strings/translations/android_webapk_strings_bg.xtb b/chrome/android/webapk/strings/translations/android_webapk_strings_bg.xtb new file mode 100644 index 0000000..6681995 --- /dev/null +++ b/chrome/android/webapk/strings/translations/android_webapk_strings_bg.xtb
@@ -0,0 +1,4 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="bg"> +</translationbundle> \ No newline at end of file
diff --git a/chrome/android/webapk/strings/translations/android_webapk_strings_ca.xtb b/chrome/android/webapk/strings/translations/android_webapk_strings_ca.xtb new file mode 100644 index 0000000..71cdd772 --- /dev/null +++ b/chrome/android/webapk/strings/translations/android_webapk_strings_ca.xtb
@@ -0,0 +1,4 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="ca"> +</translationbundle> \ No newline at end of file
diff --git a/chrome/android/webapk/strings/translations/android_webapk_strings_cs.xtb b/chrome/android/webapk/strings/translations/android_webapk_strings_cs.xtb new file mode 100644 index 0000000..dc153a85 --- /dev/null +++ b/chrome/android/webapk/strings/translations/android_webapk_strings_cs.xtb
@@ -0,0 +1,4 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="cs"> +</translationbundle> \ No newline at end of file
diff --git a/chrome/android/webapk/strings/translations/android_webapk_strings_da.xtb b/chrome/android/webapk/strings/translations/android_webapk_strings_da.xtb new file mode 100644 index 0000000..1256832 --- /dev/null +++ b/chrome/android/webapk/strings/translations/android_webapk_strings_da.xtb
@@ -0,0 +1,4 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="da"> +</translationbundle> \ No newline at end of file
diff --git a/chrome/android/webapk/strings/translations/android_webapk_strings_de.xtb b/chrome/android/webapk/strings/translations/android_webapk_strings_de.xtb new file mode 100644 index 0000000..43dd909 --- /dev/null +++ b/chrome/android/webapk/strings/translations/android_webapk_strings_de.xtb
@@ -0,0 +1,4 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="de"> +</translationbundle> \ No newline at end of file
diff --git a/chrome/android/webapk/strings/translations/android_webapk_strings_el.xtb b/chrome/android/webapk/strings/translations/android_webapk_strings_el.xtb new file mode 100644 index 0000000..1b096642 --- /dev/null +++ b/chrome/android/webapk/strings/translations/android_webapk_strings_el.xtb
@@ -0,0 +1,4 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="el"> +</translationbundle> \ No newline at end of file
diff --git a/chrome/android/webapk/strings/translations/android_webapk_strings_en-GB.xtb b/chrome/android/webapk/strings/translations/android_webapk_strings_en-GB.xtb new file mode 100644 index 0000000..12c3fa00 --- /dev/null +++ b/chrome/android/webapk/strings/translations/android_webapk_strings_en-GB.xtb
@@ -0,0 +1,4 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="en-GB"> +</translationbundle> \ No newline at end of file
diff --git a/chrome/android/webapk/strings/translations/android_webapk_strings_es-419.xtb b/chrome/android/webapk/strings/translations/android_webapk_strings_es-419.xtb new file mode 100644 index 0000000..b652ed0 --- /dev/null +++ b/chrome/android/webapk/strings/translations/android_webapk_strings_es-419.xtb
@@ -0,0 +1,4 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="es-419"> +</translationbundle> \ No newline at end of file
diff --git a/chrome/android/webapk/strings/translations/android_webapk_strings_es.xtb b/chrome/android/webapk/strings/translations/android_webapk_strings_es.xtb new file mode 100644 index 0000000..4d4f400 --- /dev/null +++ b/chrome/android/webapk/strings/translations/android_webapk_strings_es.xtb
@@ -0,0 +1,4 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="es"> +</translationbundle> \ No newline at end of file
diff --git a/chrome/android/webapk/strings/translations/android_webapk_strings_fa.xtb b/chrome/android/webapk/strings/translations/android_webapk_strings_fa.xtb new file mode 100644 index 0000000..4cff15d --- /dev/null +++ b/chrome/android/webapk/strings/translations/android_webapk_strings_fa.xtb
@@ -0,0 +1,4 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="fa"> +</translationbundle> \ No newline at end of file
diff --git a/chrome/android/webapk/strings/translations/android_webapk_strings_fi.xtb b/chrome/android/webapk/strings/translations/android_webapk_strings_fi.xtb new file mode 100644 index 0000000..60ba9aa --- /dev/null +++ b/chrome/android/webapk/strings/translations/android_webapk_strings_fi.xtb
@@ -0,0 +1,4 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="fi"> +</translationbundle> \ No newline at end of file
diff --git a/chrome/android/webapk/strings/translations/android_webapk_strings_fil.xtb b/chrome/android/webapk/strings/translations/android_webapk_strings_fil.xtb new file mode 100644 index 0000000..8f6a880 --- /dev/null +++ b/chrome/android/webapk/strings/translations/android_webapk_strings_fil.xtb
@@ -0,0 +1,4 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="fil"> +</translationbundle> \ No newline at end of file
diff --git a/chrome/android/webapk/strings/translations/android_webapk_strings_fr.xtb b/chrome/android/webapk/strings/translations/android_webapk_strings_fr.xtb new file mode 100644 index 0000000..bf48975a --- /dev/null +++ b/chrome/android/webapk/strings/translations/android_webapk_strings_fr.xtb
@@ -0,0 +1,4 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="fr"> +</translationbundle> \ No newline at end of file
diff --git a/chrome/android/webapk/strings/translations/android_webapk_strings_hi.xtb b/chrome/android/webapk/strings/translations/android_webapk_strings_hi.xtb new file mode 100644 index 0000000..279503cd --- /dev/null +++ b/chrome/android/webapk/strings/translations/android_webapk_strings_hi.xtb
@@ -0,0 +1,4 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="hi"> +</translationbundle> \ No newline at end of file
diff --git a/chrome/android/webapk/strings/translations/android_webapk_strings_hr.xtb b/chrome/android/webapk/strings/translations/android_webapk_strings_hr.xtb new file mode 100644 index 0000000..9ec62af --- /dev/null +++ b/chrome/android/webapk/strings/translations/android_webapk_strings_hr.xtb
@@ -0,0 +1,4 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="hr"> +</translationbundle> \ No newline at end of file
diff --git a/chrome/android/webapk/strings/translations/android_webapk_strings_hu.xtb b/chrome/android/webapk/strings/translations/android_webapk_strings_hu.xtb new file mode 100644 index 0000000..bdc02ee --- /dev/null +++ b/chrome/android/webapk/strings/translations/android_webapk_strings_hu.xtb
@@ -0,0 +1,4 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="hu"> +</translationbundle> \ No newline at end of file
diff --git a/chrome/android/webapk/strings/translations/android_webapk_strings_id.xtb b/chrome/android/webapk/strings/translations/android_webapk_strings_id.xtb new file mode 100644 index 0000000..5f2882d --- /dev/null +++ b/chrome/android/webapk/strings/translations/android_webapk_strings_id.xtb
@@ -0,0 +1,4 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="id"> +</translationbundle> \ No newline at end of file
diff --git a/chrome/android/webapk/strings/translations/android_webapk_strings_it.xtb b/chrome/android/webapk/strings/translations/android_webapk_strings_it.xtb new file mode 100644 index 0000000..e7df702 --- /dev/null +++ b/chrome/android/webapk/strings/translations/android_webapk_strings_it.xtb
@@ -0,0 +1,4 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="it"> +</translationbundle> \ No newline at end of file
diff --git a/chrome/android/webapk/strings/translations/android_webapk_strings_iw.xtb b/chrome/android/webapk/strings/translations/android_webapk_strings_iw.xtb new file mode 100644 index 0000000..a29d4ad --- /dev/null +++ b/chrome/android/webapk/strings/translations/android_webapk_strings_iw.xtb
@@ -0,0 +1,4 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="iw"> +</translationbundle> \ No newline at end of file
diff --git a/chrome/android/webapk/strings/translations/android_webapk_strings_ja.xtb b/chrome/android/webapk/strings/translations/android_webapk_strings_ja.xtb new file mode 100644 index 0000000..d8a3543 --- /dev/null +++ b/chrome/android/webapk/strings/translations/android_webapk_strings_ja.xtb
@@ -0,0 +1,4 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="ja"> +</translationbundle> \ No newline at end of file
diff --git a/chrome/android/webapk/strings/translations/android_webapk_strings_ko.xtb b/chrome/android/webapk/strings/translations/android_webapk_strings_ko.xtb new file mode 100644 index 0000000..558b05b --- /dev/null +++ b/chrome/android/webapk/strings/translations/android_webapk_strings_ko.xtb
@@ -0,0 +1,4 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="ko"> +</translationbundle> \ No newline at end of file
diff --git a/chrome/android/webapk/strings/translations/android_webapk_strings_lt.xtb b/chrome/android/webapk/strings/translations/android_webapk_strings_lt.xtb new file mode 100644 index 0000000..f20c0fa2 --- /dev/null +++ b/chrome/android/webapk/strings/translations/android_webapk_strings_lt.xtb
@@ -0,0 +1,4 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="lt"> +</translationbundle> \ No newline at end of file
diff --git a/chrome/android/webapk/strings/translations/android_webapk_strings_lv.xtb b/chrome/android/webapk/strings/translations/android_webapk_strings_lv.xtb new file mode 100644 index 0000000..6f3afbc --- /dev/null +++ b/chrome/android/webapk/strings/translations/android_webapk_strings_lv.xtb
@@ -0,0 +1,4 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="lv"> +</translationbundle> \ No newline at end of file
diff --git a/chrome/android/webapk/strings/translations/android_webapk_strings_nl.xtb b/chrome/android/webapk/strings/translations/android_webapk_strings_nl.xtb new file mode 100644 index 0000000..05ab957 --- /dev/null +++ b/chrome/android/webapk/strings/translations/android_webapk_strings_nl.xtb
@@ -0,0 +1,4 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="nl"> +</translationbundle> \ No newline at end of file
diff --git a/chrome/android/webapk/strings/translations/android_webapk_strings_no.xtb b/chrome/android/webapk/strings/translations/android_webapk_strings_no.xtb new file mode 100644 index 0000000..ede4de30 --- /dev/null +++ b/chrome/android/webapk/strings/translations/android_webapk_strings_no.xtb
@@ -0,0 +1,4 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="no"> +</translationbundle> \ No newline at end of file
diff --git a/chrome/android/webapk/strings/translations/android_webapk_strings_pl.xtb b/chrome/android/webapk/strings/translations/android_webapk_strings_pl.xtb new file mode 100644 index 0000000..1bf17bd5 --- /dev/null +++ b/chrome/android/webapk/strings/translations/android_webapk_strings_pl.xtb
@@ -0,0 +1,4 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="pl"> +</translationbundle> \ No newline at end of file
diff --git a/chrome/android/webapk/strings/translations/android_webapk_strings_pt-BR.xtb b/chrome/android/webapk/strings/translations/android_webapk_strings_pt-BR.xtb new file mode 100644 index 0000000..de39dfa --- /dev/null +++ b/chrome/android/webapk/strings/translations/android_webapk_strings_pt-BR.xtb
@@ -0,0 +1,4 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="pt-BR"> +</translationbundle> \ No newline at end of file
diff --git a/chrome/android/webapk/strings/translations/android_webapk_strings_pt-PT.xtb b/chrome/android/webapk/strings/translations/android_webapk_strings_pt-PT.xtb new file mode 100644 index 0000000..0b98ee77 --- /dev/null +++ b/chrome/android/webapk/strings/translations/android_webapk_strings_pt-PT.xtb
@@ -0,0 +1,4 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="pt-PT"> +</translationbundle> \ No newline at end of file
diff --git a/chrome/android/webapk/strings/translations/android_webapk_strings_ro.xtb b/chrome/android/webapk/strings/translations/android_webapk_strings_ro.xtb new file mode 100644 index 0000000..7129eb4 --- /dev/null +++ b/chrome/android/webapk/strings/translations/android_webapk_strings_ro.xtb
@@ -0,0 +1,4 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="ro"> +</translationbundle> \ No newline at end of file
diff --git a/chrome/android/webapk/strings/translations/android_webapk_strings_ru.xtb b/chrome/android/webapk/strings/translations/android_webapk_strings_ru.xtb new file mode 100644 index 0000000..6dfaa442 --- /dev/null +++ b/chrome/android/webapk/strings/translations/android_webapk_strings_ru.xtb
@@ -0,0 +1,4 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="ru"> +</translationbundle> \ No newline at end of file
diff --git a/chrome/android/webapk/strings/translations/android_webapk_strings_sk.xtb b/chrome/android/webapk/strings/translations/android_webapk_strings_sk.xtb new file mode 100644 index 0000000..202e515a --- /dev/null +++ b/chrome/android/webapk/strings/translations/android_webapk_strings_sk.xtb
@@ -0,0 +1,4 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="sk"> +</translationbundle> \ No newline at end of file
diff --git a/chrome/android/webapk/strings/translations/android_webapk_strings_sl.xtb b/chrome/android/webapk/strings/translations/android_webapk_strings_sl.xtb new file mode 100644 index 0000000..31b5a1a --- /dev/null +++ b/chrome/android/webapk/strings/translations/android_webapk_strings_sl.xtb
@@ -0,0 +1,4 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="sl"> +</translationbundle> \ No newline at end of file
diff --git a/chrome/android/webapk/strings/translations/android_webapk_strings_sr.xtb b/chrome/android/webapk/strings/translations/android_webapk_strings_sr.xtb new file mode 100644 index 0000000..984d7192 --- /dev/null +++ b/chrome/android/webapk/strings/translations/android_webapk_strings_sr.xtb
@@ -0,0 +1,4 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="sr"> +</translationbundle> \ No newline at end of file
diff --git a/chrome/android/webapk/strings/translations/android_webapk_strings_sv.xtb b/chrome/android/webapk/strings/translations/android_webapk_strings_sv.xtb new file mode 100644 index 0000000..9a787b8 --- /dev/null +++ b/chrome/android/webapk/strings/translations/android_webapk_strings_sv.xtb
@@ -0,0 +1,4 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="sv"> +</translationbundle> \ No newline at end of file
diff --git a/chrome/android/webapk/strings/translations/android_webapk_strings_sw.xtb b/chrome/android/webapk/strings/translations/android_webapk_strings_sw.xtb new file mode 100644 index 0000000..9aa61cb --- /dev/null +++ b/chrome/android/webapk/strings/translations/android_webapk_strings_sw.xtb
@@ -0,0 +1,4 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="sw"> +</translationbundle> \ No newline at end of file
diff --git a/chrome/android/webapk/strings/translations/android_webapk_strings_th.xtb b/chrome/android/webapk/strings/translations/android_webapk_strings_th.xtb new file mode 100644 index 0000000..dbe6a601 --- /dev/null +++ b/chrome/android/webapk/strings/translations/android_webapk_strings_th.xtb
@@ -0,0 +1,4 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="th"> +</translationbundle> \ No newline at end of file
diff --git a/chrome/android/webapk/strings/translations/android_webapk_strings_tr.xtb b/chrome/android/webapk/strings/translations/android_webapk_strings_tr.xtb new file mode 100644 index 0000000..d99480c0 --- /dev/null +++ b/chrome/android/webapk/strings/translations/android_webapk_strings_tr.xtb
@@ -0,0 +1,4 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="tr"> +</translationbundle> \ No newline at end of file
diff --git a/chrome/android/webapk/strings/translations/android_webapk_strings_uk.xtb b/chrome/android/webapk/strings/translations/android_webapk_strings_uk.xtb new file mode 100644 index 0000000..6e80099d --- /dev/null +++ b/chrome/android/webapk/strings/translations/android_webapk_strings_uk.xtb
@@ -0,0 +1,4 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="uk"> +</translationbundle> \ No newline at end of file
diff --git a/chrome/android/webapk/strings/translations/android_webapk_strings_vi.xtb b/chrome/android/webapk/strings/translations/android_webapk_strings_vi.xtb new file mode 100644 index 0000000..8a42ab1 --- /dev/null +++ b/chrome/android/webapk/strings/translations/android_webapk_strings_vi.xtb
@@ -0,0 +1,4 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="vi"> +</translationbundle> \ No newline at end of file
diff --git a/chrome/android/webapk/strings/translations/android_webapk_strings_zh-CN.xtb b/chrome/android/webapk/strings/translations/android_webapk_strings_zh-CN.xtb new file mode 100644 index 0000000..c7d76e8 --- /dev/null +++ b/chrome/android/webapk/strings/translations/android_webapk_strings_zh-CN.xtb
@@ -0,0 +1,4 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="zh-CN"> +</translationbundle> \ No newline at end of file
diff --git a/chrome/android/webapk/strings/translations/android_webapk_strings_zh-TW.xtb b/chrome/android/webapk/strings/translations/android_webapk_strings_zh-TW.xtb new file mode 100644 index 0000000..3e0c306 --- /dev/null +++ b/chrome/android/webapk/strings/translations/android_webapk_strings_zh-TW.xtb
@@ -0,0 +1,4 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="zh-TW"> +</translationbundle> \ No newline at end of file
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index a3a3e8c..1baf8743 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -693,14 +693,13 @@ }; #if !defined(OS_ANDROID) -const FeatureEntry::Choice kEnableDefaultMediaSessionChoices[] = { - {flag_descriptions::kEnableDefaultMediaSessionDisabled, "", ""}, - {flag_descriptions::kEnableDefaultMediaSessionEnabled, - switches::kEnableDefaultMediaSession, ""}, +const FeatureEntry::Choice kEnableAudioFocusChoices[] = { + {flag_descriptions::kEnableAudioFocusDisabled, "", ""}, + {flag_descriptions::kEnableAudioFocusEnabled, switches::kEnableAudioFocus, + ""}, #if BUILDFLAG(ENABLE_PLUGINS) - {flag_descriptions::kEnableDefaultMediaSessionEnabledDuckFlash, - switches::kEnableDefaultMediaSession, - switches::kEnableDefaultMediaSessionDuckFlash}, + {flag_descriptions::kEnableAudioFocusEnabledDuckFlash, + switches::kEnableAudioFocus, switches::kEnableAudioFocusDuckFlash}, #endif // BUILDFLAG(ENABLE_PLUGINS) }; #endif // !defined(OS_ANDROID) @@ -2539,10 +2538,9 @@ FEATURE_VALUE_TYPE(features::kEnumerateAudioDevices)}, #endif // OS_CHROMEOS #if !defined(OS_ANDROID) - {"enable-default-media-session", - flag_descriptions::kEnableDefaultMediaSessionName, - flag_descriptions::kEnableDefaultMediaSessionDescription, kOsDesktop, - MULTI_VALUE_TYPE(kEnableDefaultMediaSessionChoices)}, + {"enable-audio-focus", flag_descriptions::kEnableAudioFocusName, + flag_descriptions::kEnableAudioFocusDescription, kOsDesktop, + MULTI_VALUE_TYPE(kEnableAudioFocusChoices)}, #endif // !OS_ANDROID #if defined(OS_ANDROID) {"modal-permission-prompts", flag_descriptions::kModalPermissionPromptsName, @@ -2892,6 +2890,17 @@ FEATURE_VALUE_TYPE(features::kD3DVsync)}, #endif // defined(OS_WIN) +#if !defined(OS_ANDROID) && !defined(OS_IOS) + {"use-google-local-ntp", flag_descriptions::kUseGoogleLocalNtpName, + flag_descriptions::kUseGoogleLocalNtpDescription, kOsDesktop, + FEATURE_VALUE_TYPE(features::kUseGoogleLocalNtp)}, + + {"one-google-bar-on-local-ntp", + flag_descriptions::kOneGoogleBarOnLocalNtpName, + flag_descriptions::kOneGoogleBarOnLocalNtpDescription, kOsDesktop, + FEATURE_VALUE_TYPE(features::kOneGoogleBarOnLocalNtp)}, +#endif // !defined(OS_ANDROID) && !defined(OS_IOS) + // NOTE: Adding new command-line switches requires adding corresponding // entries to enum "LoginCustomFlags" in histograms/enums.xml. See note in // enums.xml and don't forget to run AboutFlagsHistogramTest unit test.
diff --git a/chrome/browser/android/vr_shell/vr_shell_gl.cc b/chrome/browser/android/vr_shell/vr_shell_gl.cc index a666358..3062ff6 100644 --- a/chrome/browser/android/vr_shell/vr_shell_gl.cc +++ b/chrome/browser/android/vr_shell/vr_shell_gl.cc
@@ -1044,38 +1044,25 @@ std::vector<const UiElement*> VrShellGl::GetElementsInDrawOrder( const vr::Mat4f& view_matrix, const std::vector<const UiElement*>& elements) { - typedef std::pair<float, const UiElement*> DistanceElementPair; - std::vector<DistanceElementPair> zOrderedElementPairs; - zOrderedElementPairs.reserve(elements.size()); - - for (const auto* element : elements) { - // Distance is the abs(z) value in view space. - gfx::Vector3dF element_position = - vr::GetTranslation(element->TransformMatrix()); - - float distance = - std::fabs(vr::MatrixVectorMul(view_matrix, element_position).z()); - zOrderedElementPairs.push_back(std::make_pair(distance, element)); - } + std::vector<const UiElement*> sorted_elements = elements; // Sort elements primarily based on their draw phase (lower draw phase first) - // and secondarily based on their distance (larger distance first). - std::sort( - zOrderedElementPairs.begin(), zOrderedElementPairs.end(), - [](const DistanceElementPair& first, const DistanceElementPair& second) { - if (first.second->draw_phase() != second.second->draw_phase()) { - return first.second->draw_phase() < second.second->draw_phase(); - } else { - return first.first > second.first; - } - }); + // and secondarily based on their z-axis distance (more distant first). + // TODO(mthiesse, crbug.com/721356): This will not work well for elements not + // directly in front of the user, but works well enough for our initial + // release, and provides a consistent ordering that we can easily design + // around. + std::sort(sorted_elements.begin(), sorted_elements.end(), + [](const UiElement* first, const UiElement* second) { + if (first->draw_phase() != second->draw_phase()) { + return first->draw_phase() < second->draw_phase(); + } else { + return vr::GetTranslation(first->TransformMatrix()).z() < + vr::GetTranslation(second->TransformMatrix()).z(); + } + }); - std::vector<const UiElement*> zOrderedElements; - zOrderedElements.reserve(elements.size()); - for (auto distanceElementPair : zOrderedElementPairs) { - zOrderedElements.push_back(distanceElementPair.second); - } - return zOrderedElements; + return sorted_elements; } void VrShellGl::DrawCursor(const vr::Mat4f& render_matrix) {
diff --git a/chrome/browser/chromeos/accessibility/accessibility_manager.cc b/chrome/browser/chromeos/accessibility/accessibility_manager.cc index 069ca6d6..954dcef 100644 --- a/chrome/browser/chromeos/accessibility/accessibility_manager.cc +++ b/chrome/browser/chromeos/accessibility/accessibility_manager.cc
@@ -1471,9 +1471,9 @@ } if (!base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kEnableDefaultMediaSession)) { + switches::kEnableAudioFocus)) { base::CommandLine::ForCurrentProcess()->AppendSwitch( - switches::kEnableDefaultMediaSession); + switches::kEnableAudioFocus); } }
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 8b0b6b0..ee29df2 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -2659,16 +2659,16 @@ #if !defined(OS_ANDROID) -const char kEnableDefaultMediaSessionName[] = "Manage audio focus across tabs"; +const char kEnableAudioFocusName[] = "Manage audio focus across tabs"; -const char kEnableDefaultMediaSessionDescription[] = +const char kEnableAudioFocusDescription[] = "Manage audio focus across tabs to improve the audio mixing."; -const char kEnableDefaultMediaSessionDisabled[] = "Disabled"; +const char kEnableAudioFocusDisabled[] = "Disabled"; -const char kEnableDefaultMediaSessionEnabled[] = "Enabled"; +const char kEnableAudioFocusEnabled[] = "Enabled"; -const char kEnableDefaultMediaSessionEnabledDuckFlash[] = +const char kEnableAudioFocusEnabledDuckFlash[] = "Enabled (Flash lowers volume when interrupted by other sound, " "experimental)"; @@ -3153,4 +3153,18 @@ #endif // defined(OS_WIN) +#if !defined(OS_ANDROID) && !defined(OS_IOS) + +const char kUseGoogleLocalNtpName[] = "Enable using the Google local NTP"; +const char kUseGoogleLocalNtpDescription[] = + "Use the local New Tab page if Google is the default search engine."; + +const char kOneGoogleBarOnLocalNtpName[] = + "Enable the OneGoogleBar on the local NTP"; +const char kOneGoogleBarOnLocalNtpDescription[] = + "Show a OneGoogleBar on the local New Tab page if Google is the default " + "search engine."; + +#endif // !defined(OS_ANDROID) && !defined(OS_IOS) + } // namespace flag_descriptions
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index 50ce589..7520fcd4 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -2888,20 +2888,20 @@ #if !defined(OS_ANDROID) -// Name for the flag to enable default MediaSession on desktop -extern const char kEnableDefaultMediaSessionName[]; +// Name for the flag to enable audio focus on desktop. +extern const char kEnableAudioFocusName[]; -// Desciption for the flag to enable default MediaSession on desktop -extern const char kEnableDefaultMediaSessionDescription[]; +// Desciption for the flag to enable audio focus on desktop. +extern const char kEnableAudioFocusDescription[]; -// Option for disabling the default MediaSession -extern const char kEnableDefaultMediaSessionDisabled[]; +// Option for disabling audio focus on desktop. +extern const char kEnableAudioFocusDisabled[]; -// Option for enabling the default MediaSession -extern const char kEnableDefaultMediaSessionEnabled[]; +// Option for enabling audio focus on desktop. +extern const char kEnableAudioFocusEnabled[]; -// Option for enabling the default MediaSession with Flash -extern const char kEnableDefaultMediaSessionEnabledDuckFlash[]; +// Option for enabling audio focus with Flash support on desktop. +extern const char kEnableAudioFocusEnabledDuckFlash[]; #endif // !defined(OS_ANDROID) @@ -3422,6 +3422,19 @@ #endif // defined(OS_WIN) +#if !defined(OS_ANDROID) && !defined(OS_IOS) + +// Name and description for the flag to use the local NTP if Google is the +// default search engine. +extern const char kUseGoogleLocalNtpName[]; +extern const char kUseGoogleLocalNtpDescription[]; + +// Name and description for the flag to show a OneGoogleBar on the local NTP. +extern const char kOneGoogleBarOnLocalNtpName[]; +extern const char kOneGoogleBarOnLocalNtpDescription[]; + +#endif + } // namespace flag_descriptions #endif // CHROME_BROWSER_FLAG_DESCRIPTIONS_H_
diff --git a/chrome/browser/profiles/profile_android.cc b/chrome/browser/profiles/profile_android.cc index 3bb20c5..ddcba395 100644 --- a/chrome/browser/profiles/profile_android.cc +++ b/chrome/browser/profiles/profile_android.cc
@@ -104,6 +104,12 @@ return profile_->IsOffTheRecord(); } +jboolean ProfileAndroid::IsChild( + JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj) { + return profile_->IsChild(); +} + // static ScopedJavaLocalRef<jobject> GetLastUsedProfile( JNIEnv* env,
diff --git a/chrome/browser/profiles/profile_android.h b/chrome/browser/profiles/profile_android.h index b7a55d3e7..8f881869 100644 --- a/chrome/browser/profiles/profile_android.h +++ b/chrome/browser/profiles/profile_android.h
@@ -52,6 +52,10 @@ jboolean IsOffTheRecord(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj); + // Whether this profile is signed in to a child account. + jboolean IsChild(JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj); + explicit ProfileAndroid(Profile* profile); ~ProfileAndroid() override;
diff --git a/chrome/browser/resources/chromeos/chromevox/chromevox/background/options.js b/chrome/browser/resources/chromeos/chromevox/chromevox/background/options.js index 7c8e8fca..9e154d20 100644 --- a/chrome/browser/resources/chromeos/chromevox/chromevox/background/options.js +++ b/chrome/browser/resources/chromeos/chromevox/chromevox/background/options.js
@@ -74,7 +74,7 @@ localStorage['brailleSideBySide'] === 'true' ? currentlyDisplayingSideBySide : currentlyDisplayingInterleave; - chrome.commandLinePrivate.hasSwitch('enable-default-media-session', + chrome.commandLinePrivate.hasSwitch('enable-audio-focus', function(result) { if (!result) { $('audioStrategy').hidden = true;
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/media_automation_handler.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/media_automation_handler.js index a06ac1f..ff6f1fa 100644 --- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/media_automation_handler.js +++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/media_automation_handler.js
@@ -5,7 +5,7 @@ /** * @fileoverview Handles media automation events. Note that to perform any of * the actions below such as ducking, and suspension of media sessions, the - * --enable-default-media-session flag must be passed at the command line. + * --enable-audio-focus flag must be passed at the command line. */ goog.provide('MediaAutomationHandler');
diff --git a/chrome/browser/search/local_ntp_source.cc b/chrome/browser/search/local_ntp_source.cc index 182a416..6fab4ea 100644 --- a/chrome/browser/search/local_ntp_source.cc +++ b/chrome/browser/search/local_ntp_source.cc
@@ -27,6 +27,7 @@ #include "chrome/browser/themes/theme_properties.h" #include "chrome/browser/themes/theme_service.h" #include "chrome/browser/themes/theme_service_factory.h" +#include "chrome/common/chrome_features.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/url_constants.h" #include "chrome/grit/browser_resources.h" @@ -48,9 +49,6 @@ namespace { -base::Feature kOneGoogleBarOnLocalNtpFeature{"OneGoogleBarOnLocalNtp", - base::FEATURE_DISABLED_BY_DEFAULT}; - // Signifies a locally constructed resource, i.e. not from grit/. const int kLocalResource = -1; @@ -240,7 +238,7 @@ weak_ptr_factory_(this) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - if (base::FeatureList::IsEnabled(kOneGoogleBarOnLocalNtpFeature)) { + if (base::FeatureList::IsEnabled(features::kOneGoogleBarOnLocalNtp)) { one_google_bar_service_ = OneGoogleBarServiceFactory::GetForProfile(profile_); }
diff --git a/chrome/browser/search/one_google_bar/one_google_bar_fetcher_impl.cc b/chrome/browser/search/one_google_bar/one_google_bar_fetcher_impl.cc index f5f3a58..41cdec8 100644 --- a/chrome/browser/search/one_google_bar/one_google_bar_fetcher_impl.cc +++ b/chrome/browser/search/one_google_bar/one_google_bar_fetcher_impl.cc
@@ -8,15 +8,16 @@ #include <utility> #include "base/callback.h" -#include "base/command_line.h" #include "base/json/json_writer.h" #include "base/memory/ptr_util.h" +#include "base/metrics/field_trial_params.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "base/values.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/search/one_google_bar/one_google_bar_data.h" #include "chrome/common/chrome_content_client.h" +#include "chrome/common/chrome_features.h" #include "components/google/core/browser/google_url_tracker.h" #include "components/safe_json/safe_json_parser.h" #include "components/signin/core/browser/access_token_fetcher.h" @@ -191,11 +192,12 @@ GURL OneGoogleBarFetcherImpl::AuthenticatedURLFetcher::GetApiUrl( bool use_oauth) const { - std::string api_url(kApiUrl); - // TODO(treib): Attach to feature instead of cmdline. - base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess(); - if (cmdline->HasSwitch("one-google-api-url")) - api_url = cmdline->GetSwitchValueASCII("one-google-api-url"); + std::string api_url = base::GetFieldTrialParamValueByFeature( + features::kOneGoogleBarOnLocalNtp, "one-google-api-url"); + if (api_url.empty()) { + api_url = kApiUrl; + } + // Append the API key only for unauthenticated requests. if (!use_oauth) { api_url += @@ -207,10 +209,11 @@ std::string OneGoogleBarFetcherImpl::AuthenticatedURLFetcher::GetRequestBody() const { - // TODO(treib): Attach to feature instead of cmdline. - base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess(); - if (cmdline->HasSwitch("one-google-bar-options")) - return cmdline->GetSwitchValueASCII("one-google-bar-options"); + std::string override_options = base::GetFieldTrialParamValueByFeature( + features::kOneGoogleBarOnLocalNtp, "one-google-bar-options"); + if (!override_options.empty()) { + return override_options; + } base::DictionaryValue dict; dict.SetInteger("subproduct", 243); @@ -303,8 +306,9 @@ void OneGoogleBarFetcherImpl::IssueRequestIfNoneOngoing() { // If there is an ongoing request, let it complete. - if (pending_request_.get()) + if (pending_request_.get()) { return; + } pending_request_ = base::MakeUnique<AuthenticatedURLFetcher>( signin_manager_, token_service_, request_context_,
diff --git a/chrome/browser/search/search.cc b/chrome/browser/search/search.cc index a3d0a8e3..e0bd3d89 100644 --- a/chrome/browser/search/search.cc +++ b/chrome/browser/search/search.cc
@@ -23,6 +23,7 @@ #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_instant_controller.h" #include "chrome/browser/ui/search/instant_search_prerenderer.h" +#include "chrome/common/chrome_features.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/features.h" #include "chrome/common/pref_names.h" @@ -81,10 +82,6 @@ NEW_TAB_URL_MAX }; -base::Feature kUseGoogleLocalNtp { - "UseGoogleLocalNtp", base::FEATURE_DISABLED_BY_DEFAULT -}; - const TemplateURL* GetDefaultSearchProviderTemplateURL(Profile* profile) { if (profile) { TemplateURLService* template_url_service = @@ -198,7 +195,7 @@ #endif // defined(OS_CHROMEOS) if (!profile->IsOffTheRecord() && - base::FeatureList::IsEnabled(kUseGoogleLocalNtp) && + base::FeatureList::IsEnabled(features::kUseGoogleLocalNtp) && DefaultSearchProviderIsGoogle(profile)) { return true; }
diff --git a/chrome/browser/subresource_filter/chrome_subresource_filter_client.cc b/chrome/browser/subresource_filter/chrome_subresource_filter_client.cc index 92d4e7d3b..6c1a9d1 100644 --- a/chrome/browser/subresource_filter/chrome_subresource_filter_client.cc +++ b/chrome/browser/subresource_filter/chrome_subresource_filter_client.cc
@@ -121,9 +121,18 @@ bool activated) { const GURL& url(navigation_handle->GetURL()); DCHECK(navigation_handle->IsInMainFrame()); + + // If the site is no longer activated, clear the metadata. This is to maintain + // the invariant that metadata implies activated. + if (!activated && url.SchemeIsHTTPOrHTTPS()) + settings_manager_->ClearSiteMetadata(url); + // Return whether the activation should be whitelisted. return whitelisted_hosts_.count(url.host()) || settings_manager_->GetSitePermission(url) == CONTENT_SETTING_BLOCK; + // TODO(csharrison): Consider setting the metadata to an empty dict here if + // the site is activated and not whitelisted. Need to be careful about various + // edge cases like |should_suppress_notification| and DRYRUN activation. } void ChromeSubresourceFilterClient::WhitelistByContentSettings(
diff --git a/chrome/browser/subresource_filter/subresource_filter_content_settings_manager.cc b/chrome/browser/subresource_filter/subresource_filter_content_settings_manager.cc index 0fec6e74..8aad111c 100644 --- a/chrome/browser/subresource_filter/subresource_filter_content_settings_manager.cc +++ b/chrome/browser/subresource_filter/subresource_filter_content_settings_manager.cc
@@ -52,11 +52,9 @@ DCHECK(settings_map_); settings_map_->AddObserver(this); - if (should_use_smart_ui()) { - if (auto* history_service = HistoryServiceFactory::GetForProfile( - profile, ServiceAccessType::EXPLICIT_ACCESS)) { - history_observer_.Add(history_service); - } + if (auto* history_service = HistoryServiceFactory::GetForProfile( + profile, ServiceAccessType::EXPLICIT_ACCESS)) { + history_observer_.Add(history_service); } } @@ -85,8 +83,6 @@ } void SubresourceFilterContentSettingsManager::OnDidShowUI(const GURL& url) { - if (!should_use_smart_ui()) - return; auto dict = base::MakeUnique<base::DictionaryValue>(); double now = clock_->Now().ToDoubleT(); dict->SetDouble(kInfobarLastShownTimeKey, now); @@ -111,6 +107,11 @@ return true; } +void SubresourceFilterContentSettingsManager::ClearSiteMetadata( + const GURL& url) { + SetSiteMetadata(url, nullptr); +} + std::unique_ptr<base::DictionaryValue> SubresourceFilterContentSettingsManager::GetSiteMetadata( const GURL& url) const { @@ -179,16 +180,13 @@ NOTREACHED(); } - if (!should_use_smart_ui()) - return; - if (!ShouldShowUIForSite(url)) { ChromeSubresourceFilterClient::LogAction( kActionContentSettingsBlockedWhileUISuppressed); } - - // Reset the smart UI to ensure the user can easily change their decision. - SetSiteMetadata(url, nullptr); + // Note: could potentially reset the smart UI here to enable the user to + // easily change their decision. If that code is added we should make sure not + // to delete the metadata, but merely remove / reset the timestamp. } // When history URLs are deleted, clear the metadata for the smart UI. @@ -198,7 +196,6 @@ bool expired, const history::URLRows& deleted_rows, const std::set<GURL>& favicon_urls) { - DCHECK(should_use_smart_ui()); if (all_history) { settings_map_->ClearSettingsForOneType( CONTENT_SETTINGS_TYPE_SUBRESOURCE_FILTER_DATA);
diff --git a/chrome/browser/subresource_filter/subresource_filter_content_settings_manager.h b/chrome/browser/subresource_filter/subresource_filter_content_settings_manager.h index 31be433..8f55ef6 100644 --- a/chrome/browser/subresource_filter/subresource_filter_content_settings_manager.h +++ b/chrome/browser/subresource_filter/subresource_filter_content_settings_manager.h
@@ -48,11 +48,16 @@ // the content setting to turn off the subresource filter. void WhitelistSite(const GURL& url); + // Public for testing. + std::unique_ptr<base::DictionaryValue> GetSiteMetadata(const GURL& url) const; + // Specific logic for more intelligent UI. void OnDidShowUI(const GURL& url); bool ShouldShowUIForSite(const GURL& url) const; bool should_use_smart_ui() const { return should_use_smart_ui_; } + void ClearSiteMetadata(const GURL& url); + void set_clock_for_testing(std::unique_ptr<base::Clock> tick_clock) { clock_ = std::move(tick_clock); } @@ -76,7 +81,6 @@ const history::URLRows& deleted_rows, const std::set<GURL>& favicon_urls) override; - std::unique_ptr<base::DictionaryValue> GetSiteMetadata(const GURL& url) const; void SetSiteMetadata(const GURL& url, std::unique_ptr<base::DictionaryValue> dict);
diff --git a/chrome/browser/subresource_filter/subresource_filter_unittest.cc b/chrome/browser/subresource_filter/subresource_filter_unittest.cc index 588dfc1..3dab716 100644 --- a/chrome/browser/subresource_filter/subresource_filter_unittest.cc +++ b/chrome/browser/subresource_filter/subresource_filter_unittest.cc
@@ -15,14 +15,20 @@ #include "chrome/browser/after_startup_task_utils.h" #include "chrome/browser/content_settings/tab_specific_content_settings.h" #include "chrome/browser/infobars/infobar_service.h" +#include "chrome/browser/profiles/profile.h" #include "chrome/browser/safe_browsing/test_safe_browsing_service.h" #include "chrome/browser/subresource_filter/chrome_subresource_filter_client.h" +#include "chrome/browser/subresource_filter/subresource_filter_content_settings_manager.h" +#include "chrome/browser/subresource_filter/subresource_filter_profile_context.h" +#include "chrome/browser/subresource_filter/subresource_filter_profile_context_factory.h" #include "chrome/browser/subresource_filter/test_ruleset_publisher.h" #include "chrome/test/base/chrome_render_view_host_test_harness.h" #include "chrome/test/base/testing_browser_process.h" +#include "chrome/test/base/testing_profile.h" #include "components/prefs/testing_pref_service.h" #include "components/safe_browsing_db/v4_protocol_manager_util.h" #include "components/subresource_filter/content/browser/content_ruleset_service.h" +#include "components/subresource_filter/content/browser/content_subresource_filter_driver_factory.h" #include "components/subresource_filter/content/browser/fake_safe_browsing_database_manager.h" #include "components/subresource_filter/core/browser/ruleset_service.h" #include "components/subresource_filter/core/browser/subresource_filter_features.h" @@ -154,6 +160,20 @@ return ChromeSubresourceFilterClient::FromWebContents(web_contents()); } + void RemoveURLFromBlacklist(const GURL& url) { + fake_safe_browsing_database_->RemoveBlacklistedUrl(url); + } + + SubresourceFilterContentSettingsManager* settings_manager() { + return SubresourceFilterProfileContextFactory::GetForProfile( + static_cast<Profile*>(profile())) + ->settings_manager(); + } + + ScopedSubresourceFilterConfigurator& scoped_configuration() { + return scoped_configuration_; + } + private: base::ScopedTempDir ruleset_service_dir_; TestingPrefServiceSimple pref_service_; @@ -179,3 +199,60 @@ EXPECT_FALSE(CreateAndNavigateDisallowedSubframe(main_rfh())); EXPECT_TRUE(client()->did_show_ui_for_navigation()); } + +TEST_F(SubresourceFilterTest, DeactivateUrl_ClearsSiteMetadata) { + GURL url("https://a.test"); + ConfigureAsSubresourceFilterOnlyURL(url); + SimulateNavigateAndCommit(url, main_rfh()); + EXPECT_FALSE(CreateAndNavigateDisallowedSubframe(main_rfh())); + + EXPECT_NE(nullptr, settings_manager()->GetSiteMetadata(url)); + + RemoveURLFromBlacklist(url); + + // Navigate to |url| again and expect the site metadata to clear. + SimulateNavigateAndCommit(url, main_rfh()); + EXPECT_TRUE(CreateAndNavigateDisallowedSubframe(main_rfh())); + + EXPECT_EQ(nullptr, settings_manager()->GetSiteMetadata(url)); +} + +// If the underlying configuration changes and a site only activates to DRYRUN, +// we should clear the metadata. +TEST_F(SubresourceFilterTest, ActivationToDryRun_ClearsSiteMetadata) { + GURL url("https://a.test"); + ConfigureAsSubresourceFilterOnlyURL(url); + SimulateNavigateAndCommit(url, main_rfh()); + EXPECT_FALSE(CreateAndNavigateDisallowedSubframe(main_rfh())); + + EXPECT_NE(nullptr, settings_manager()->GetSiteMetadata(url)); + + // If the site later activates as DRYRUN due to e.g. a configuration change, + // it should also be removed from the metadata. + scoped_configuration().ResetConfiguration(subresource_filter::Configuration( + subresource_filter::ActivationLevel::DRYRUN, + subresource_filter::ActivationScope::ACTIVATION_LIST, + subresource_filter::ActivationList::SUBRESOURCE_FILTER)); + + // Navigate to |url| again and expect the site metadata to clear. + SimulateNavigateAndCommit(url, main_rfh()); + EXPECT_TRUE(CreateAndNavigateDisallowedSubframe(main_rfh())); + + EXPECT_EQ(nullptr, settings_manager()->GetSiteMetadata(url)); +} + +TEST_F(SubresourceFilterTest, ExplicitWhitelisting_ShouldNotClearMetadata) { + GURL url("https://a.test"); + ConfigureAsSubresourceFilterOnlyURL(url); + SimulateNavigateAndCommit(url, main_rfh()); + EXPECT_FALSE(CreateAndNavigateDisallowedSubframe(main_rfh())); + + // Simulate explicit whitelisting and reload. + settings_manager()->WhitelistSite(url); + SimulateNavigateAndCommit(url, main_rfh()); + EXPECT_TRUE(CreateAndNavigateDisallowedSubframe(main_rfh())); + + // Should not have cleared the metadata, since the site is still on the SB + // blacklist. + EXPECT_NE(nullptr, settings_manager()->GetSiteMetadata(url)); +}
diff --git a/chrome/browser/supervised_user/child_accounts/child_account_service_android.cc b/chrome/browser/supervised_user/child_accounts/child_account_service_android.cc index cc6d860a0..097583f 100644 --- a/chrome/browser/supervised_user/child_accounts/child_account_service_android.cc +++ b/chrome/browser/supervised_user/child_accounts/child_account_service_android.cc
@@ -23,11 +23,6 @@ using base::android::RunCallbackAndroid; using base::android::ScopedJavaGlobalRef; -jboolean IsChildAccount(JNIEnv* env, const JavaParamRef<jclass>& jcaller) { - ProfileManager* profile_manager = g_browser_process->profile_manager(); - return profile_manager->GetLastUsedProfile()->IsChild(); -} - bool RegisterChildAccountService(JNIEnv* env) { return RegisterNativesImpl(env); }
diff --git a/chrome/browser/ui/views/payments/payment_request_views_util.cc b/chrome/browser/ui/views/payments/payment_request_views_util.cc index 405c62b5..2d3b335 100644 --- a/chrome/browser/ui/views/payments/payment_request_views_util.cc +++ b/chrome/browser/ui/views/payments/payment_request_views_util.cc
@@ -305,9 +305,10 @@ std::unique_ptr<views::View> base_label = GetShippingAddressLabel(type, locale, profile, /*disabled_state=*/false); - base_label->AddChildView(GetLabelForMissingInformation( - comp.GetStringForMissingShippingFields(profile)) - .release()); + base::string16 missing = comp.GetStringForMissingShippingFields(profile); + if (!missing.empty()) { + base_label->AddChildView(GetLabelForMissingInformation(missing).release()); + } return base_label; } @@ -339,9 +340,10 @@ std::unique_ptr<views::View> base_label = GetBaseProfileLabel(type, name, phone, email); - base_label->AddChildView(GetLabelForMissingInformation( - comp.GetStringForMissingContactFields(profile)) - .release()); + base::string16 missing = comp.GetStringForMissingContactFields(profile); + if (!missing.empty()) { + base_label->AddChildView(GetLabelForMissingInformation(missing).release()); + } return base_label; }
diff --git a/chrome/browser/ui/views/payments/shipping_option_view_controller_browsertest.cc b/chrome/browser/ui/views/payments/shipping_option_view_controller_browsertest.cc index 9e73b878..1dfe682f 100644 --- a/chrome/browser/ui/views/payments/shipping_option_view_controller_browsertest.cc +++ b/chrome/browser/ui/views/payments/shipping_option_view_controller_browsertest.cc
@@ -45,6 +45,10 @@ // Go to the shipping address screen and select the first address (MI state). OpenShippingAddressSectionScreen(); + // There is no error at the top of this screen, because no address has been + // selected yet. + EXPECT_EQ(nullptr, dialog_view()->GetViewByID(static_cast<int>( + DialogViewID::SHIPPING_ADDRESS_OPTION_ERROR))); ResetEventObserverForSequence(std::list<DialogEvent>{ DialogEvent::BACK_NAVIGATION, DialogEvent::SPEC_DONE_UPDATING}); ClickOnChildInListViewAndWait(
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc index f237984..3e1baaa 100644 --- a/chrome/common/chrome_features.cc +++ b/chrome/common/chrome_features.cc
@@ -249,6 +249,12 @@ const base::Feature kOfflinePageDownloadSuggestionsFeature{ "NTPOfflinePageDownloadSuggestions", base::FEATURE_ENABLED_BY_DEFAULT}; +#if !defined(OS_ANDROID) && !defined(OS_IOS) +// Enables or disabled the OneGoogleBar on the local NTP. +const base::Feature kOneGoogleBarOnLocalNtp{"OneGoogleBarOnLocalNtp", + base::FEATURE_DISABLED_BY_DEFAULT}; +#endif + // Enables Permissions Blacklisting via Safe Browsing. const base::Feature kPermissionsBlacklist{ "PermissionsBlacklist", base::FEATURE_DISABLED_BY_DEFAULT}; @@ -323,6 +329,10 @@ base::FEATURE_ENABLED_BY_DEFAULT}; #endif +// Enables using the local NTP if Google is the default search engine. +const base::Feature kUseGoogleLocalNtp{"UseGoogleLocalNtp", + base::FEATURE_DISABLED_BY_DEFAULT}; + // Experiment to use grouped permission infobars which could show and handle // multiple permission requests. const base::Feature kUseGroupedPermissionInfobars{
diff --git a/chrome/common/chrome_features.h b/chrome/common/chrome_features.h index ea7460a6..c3dae15b 100644 --- a/chrome/common/chrome_features.h +++ b/chrome/common/chrome_features.h
@@ -136,6 +136,10 @@ extern const base::Feature kOfflinePageDownloadSuggestionsFeature; +#if !defined(OS_ANDROID) && !defined(OS_IOS) +extern const base::Feature kOneGoogleBarOnLocalNtp; +#endif + extern const base::Feature kPermissionsBlacklist; #if defined(OS_WIN) @@ -178,6 +182,8 @@ extern const base::Feature kTabsInCbd; +extern const base::Feature kUseGoogleLocalNtp; + extern const base::Feature kUseGroupedPermissionInfobars; extern const base::Feature kUsePermissionManagerForMediaRequests;
diff --git a/chromecast/browser/cast_browser_main_parts.cc b/chromecast/browser/cast_browser_main_parts.cc index efb21bf..aab5d07 100644 --- a/chromecast/browser/cast_browser_main_parts.cc +++ b/chromecast/browser/cast_browser_main_parts.cc
@@ -225,8 +225,8 @@ #else // GPU shader disk cache disabling is largely to conserve disk space. {switches::kDisableGpuShaderDiskCache, ""}, - // Enable media sessions by default (even on non-Android platforms). - {switches::kEnableDefaultMediaSession, ""}, + // Enable audio focus by default (even on non-Android platforms). + {switches::kEnableAudioFocus, ""}, #endif #if BUILDFLAG(IS_CAST_AUDIO_ONLY) {switches::kDisableGpu, ""},
diff --git a/components/components_chromium_strings.grd b/components/components_chromium_strings.grd index 21ea9785..cb80238 100644 --- a/components/components_chromium_strings.grd +++ b/components/components_chromium_strings.grd
@@ -220,11 +220,6 @@ <message name="IDS_SESSION_CRASHED_VIEW_MESSAGE" desc="Message shown when the last session didn't exit cleanly."> Chromium didn't shut down correctly. </message> - - <!-- Strings describing Chromium security policy for DevTools security panel --> - <message name="IDS_PRIVATE_USER_DATA_INPUT_DESCRIPTION" desc="Description of a security problem where the site collects private user data on an insecure page, which results in an omnibox warning." translateable="false"> - This page includes a password or credit card input over HTTP. A warning has been added to the URL bar. - </message> </messages> </release> </grit>
diff --git a/components/components_google_chrome_strings.grd b/components/components_google_chrome_strings.grd index 061ab79..3c41235 100644 --- a/components/components_google_chrome_strings.grd +++ b/components/components_google_chrome_strings.grd
@@ -220,11 +220,6 @@ <message name="IDS_SESSION_CRASHED_VIEW_MESSAGE" desc="Message shown when the last session didn't exit cleanly."> Chrome didn't shut down correctly. </message> - - <!-- Strings describing Chrome security policy for DevTools security panel --> - <message name="IDS_PRIVATE_USER_DATA_INPUT_DESCRIPTION" desc="Description of a security problem where the site collects private user data on an insecure page, which results in an omnibox warning." translateable="false"> - This page includes a password or credit card input over HTTP. A warning has been added to the URL bar. - </message> </messages> </release> </grit>
diff --git a/components/content_settings/core/browser/website_settings_registry.cc b/components/content_settings/core/browser/website_settings_registry.cc index e019486..4d49cef9 100644 --- a/components/content_settings/core/browser/website_settings_registry.cc +++ b/components/content_settings/core/browser/website_settings_registry.cc
@@ -165,11 +165,14 @@ WebsiteSettingsInfo::UNSYNCABLE, WebsiteSettingsInfo::NOT_LOSSY, WebsiteSettingsInfo::REQUESTING_ORIGIN_ONLY_SCOPE, DESKTOP | PLATFORM_ANDROID, WebsiteSettingsInfo::INHERIT_IN_INCOGNITO); - Register(CONTENT_SETTINGS_TYPE_SUBRESOURCE_FILTER_DATA, - "subresource-filter-data", nullptr, WebsiteSettingsInfo::UNSYNCABLE, - WebsiteSettingsInfo::LOSSY, - WebsiteSettingsInfo::REQUESTING_ORIGIN_ONLY_SCOPE, PLATFORM_ANDROID, - WebsiteSettingsInfo::INHERIT_IN_INCOGNITO); + // Set when an origin is activated for subresource filtering and the + // associated UI is shown to the user. Cleared when a site is de-activated or + // the first URL matching the origin is removed from history. + Register( + CONTENT_SETTINGS_TYPE_SUBRESOURCE_FILTER_DATA, "subresource-filter-data", + nullptr, WebsiteSettingsInfo::UNSYNCABLE, WebsiteSettingsInfo::NOT_LOSSY, + WebsiteSettingsInfo::REQUESTING_ORIGIN_ONLY_SCOPE, + DESKTOP | PLATFORM_ANDROID, WebsiteSettingsInfo::INHERIT_IN_INCOGNITO); } } // namespace content_settings
diff --git a/components/content_settings/core/common/content_settings_types.h b/components/content_settings/core/common/content_settings_types.h index 3c31cde2e..580a94a 100644 --- a/components/content_settings/core/common/content_settings_types.h +++ b/components/content_settings/core/common/content_settings_types.h
@@ -51,8 +51,7 @@ CONTENT_SETTINGS_TYPE_SUBRESOURCE_FILTER, // Website setting which stores metadata for the subresource filter to aid in - // decisions for whether or not to show the UI. Currently only used on - // Android. + // decisions for whether or not to show the UI. CONTENT_SETTINGS_TYPE_SUBRESOURCE_FILTER_DATA, // This is special-cased in the permissions layer to always allow, and as
diff --git a/components/font_service/font_service_app.cc b/components/font_service/font_service_app.cc index 06c42a2..7a78c81a 100644 --- a/components/font_service/font_service_app.cc +++ b/components/font_service/font_service_app.cc
@@ -58,7 +58,7 @@ void FontServiceApp::MatchFamilyName(const std::string& family_name, mojom::TypefaceStylePtr requested_style, - const MatchFamilyNameCallback& callback) { + MatchFamilyNameCallback callback) { SkFontConfigInterface::FontIdentity result_identity; SkString result_family; SkFontStyle result_style; @@ -76,7 +76,7 @@ style->weight = SkFontStyle().weight(); style->width = SkFontStyle().width(); style->slant = static_cast<mojom::TypefaceSlant>(SkFontStyle().slant()); - callback.Run(nullptr, "", std::move(style)); + std::move(callback).Run(nullptr, "", std::move(style)); return; } @@ -94,17 +94,18 @@ style->width = result_style.width(); style->slant = static_cast<mojom::TypefaceSlant>(result_style.slant()); - callback.Run(std::move(identity), result_family.c_str(), std::move(style)); + std::move(callback).Run(std::move(identity), result_family.c_str(), + std::move(style)); } void FontServiceApp::OpenStream(uint32_t id_number, - const OpenStreamCallback& callback) { + OpenStreamCallback callback) { base::File file; if (id_number < static_cast<uint32_t>(paths_.size())) { file = GetFileForPath(base::FilePath(paths_[id_number].c_str())); } - callback.Run(std::move(file)); + std::move(callback).Run(std::move(file)); } void FontServiceApp::Create(const service_manager::BindSourceInfo& source_info,
diff --git a/components/font_service/font_service_app.h b/components/font_service/font_service_app.h index bafbbd1..c60c315 100644 --- a/components/font_service/font_service_app.h +++ b/components/font_service/font_service_app.h
@@ -33,9 +33,8 @@ // FontService: void MatchFamilyName(const std::string& family_name, mojom::TypefaceStylePtr requested_style, - const MatchFamilyNameCallback& callback) override; - void OpenStream(uint32_t id_number, - const OpenStreamCallback& callback) override; + MatchFamilyNameCallback callback) override; + void OpenStream(uint32_t id_number, OpenStreamCallback callback) override; void Create(const service_manager::BindSourceInfo& source_info, mojom::FontServiceRequest request);
diff --git a/components/font_service/public/interfaces/BUILD.gn b/components/font_service/public/interfaces/BUILD.gn index 206f3c1..12efaaf 100644 --- a/components/font_service/public/interfaces/BUILD.gn +++ b/components/font_service/public/interfaces/BUILD.gn
@@ -12,7 +12,4 @@ public_deps = [ "//mojo/common:common_custom_types", ] - - # TODO(crbug.com/714018): Convert the implementation to use OnceCallback. - use_once_callback = false }
diff --git a/components/payments/content/BUILD.gn b/components/payments/content/BUILD.gn index 7b6216a..49c1e13 100644 --- a/components/payments/content/BUILD.gn +++ b/components/payments/content/BUILD.gn
@@ -88,6 +88,7 @@ "//components/payments/core", "//components/payments/core:test_support", "//components/payments/mojom", + "//components/strings:components_strings_grit", "//content/test:test_support", "//net:test_support", "//testing/gtest",
diff --git a/components/payments/content/payment_request_spec.cc b/components/payments/content/payment_request_spec.cc index 2f7a7e4..5ba0670 100644 --- a/components/payments/content/payment_request_spec.cc +++ b/components/payments/content/payment_request_spec.cc
@@ -59,7 +59,7 @@ observer_for_testing_(nullptr) { if (observer) AddObserver(observer); - UpdateSelectedShippingOption(); + UpdateSelectedShippingOption(/*after_update=*/false); PopulateValidatedMethodData(method_data); } PaymentRequestSpec::~PaymentRequestSpec() {} @@ -67,7 +67,7 @@ void PaymentRequestSpec::UpdateWith(mojom::PaymentDetailsPtr details) { details_ = std::move(details); // We reparse the |details_| and update the observers. - UpdateSelectedShippingOption(); + UpdateSelectedShippingOption(/*after_update=*/true); NotifyOnSpecUpdated(); } @@ -170,13 +170,31 @@ supported_card_networks_.end()); } -void PaymentRequestSpec::UpdateSelectedShippingOption() { +void PaymentRequestSpec::UpdateSelectedShippingOption(bool after_update) { if (!request_shipping()) return; + selected_shipping_option_ = nullptr; selected_shipping_option_error_.clear(); + if (details().shipping_options.empty()) { + // No options are provided by the merchant. + if (after_update) { + // This is after an update, which means that the selected address is no + // supported. The merchant may have customized the error string, or a + // generic one is used. + if (!details().error.empty()) { + selected_shipping_option_error_ = base::UTF8ToUTF16(details().error); + } else { + selected_shipping_option_error_ = l10n_util::GetStringUTF16( + IDS_PAYMENTS_UNSUPPORTED_SHIPPING_ADDRESS); + } + } + return; + } + // As per the spec, the selected shipping option should initially be the last - // one in the array that has its selected field set to true. + // one in the array that has its selected field set to true. If none are + // selected by the merchant, |selected_shipping_option_| stays nullptr. auto selected_shipping_option_it = std::find_if( details().shipping_options.rbegin(), details().shipping_options.rend(), [](const payments::mojom::PaymentShippingOptionPtr& element) { @@ -184,15 +202,6 @@ }); if (selected_shipping_option_it != details().shipping_options.rend()) { selected_shipping_option_ = selected_shipping_option_it->get(); - } else { - // It's possible that there is no selected shipping option. - if (!details().error.empty()) { - selected_shipping_option_error_ = base::UTF8ToUTF16(details().error); - } else { - selected_shipping_option_error_ = - l10n_util::GetStringUTF16(IDS_PAYMENTS_UNSUPPORTED_SHIPPING_ADDRESS); - } - selected_shipping_option_ = nullptr; } }
diff --git a/components/payments/content/payment_request_spec.h b/components/payments/content/payment_request_spec.h index 98e7d67..e7bc5ff 100644 --- a/components/payments/content/payment_request_spec.h +++ b/components/payments/content/payment_request_spec.h
@@ -121,10 +121,13 @@ void PopulateValidatedMethodData( const std::vector<mojom::PaymentMethodDataPtr>& method_data); - // Updates the selected_shipping_option based on the data passed to this + // Updates the |selected_shipping_option| based on the data passed to this // payment request by the website. This will set selected_shipping_option_ to - // the last option marked selected in the options array. - void UpdateSelectedShippingOption(); + // the last option marked selected in the options array. If no options are + // provided and this method is called |after_update|, it means the merchant + // doesn't ship to this location. In this case, + // |selected_shipping_option_error_| will be set. + void UpdateSelectedShippingOption(bool after_update); // Will notify all observers that the spec has changed. void NotifyOnSpecUpdated();
diff --git a/components/payments/content/payment_request_spec_unittest.cc b/components/payments/content/payment_request_spec_unittest.cc index 7414a61..28d2774b 100644 --- a/components/payments/content/payment_request_spec_unittest.cc +++ b/components/payments/content/payment_request_spec_unittest.cc
@@ -7,8 +7,11 @@ #include <utility> #include "base/memory/weak_ptr.h" +#include "base/strings/utf_string_conversions.h" #include "components/payments/mojom/payment_request.mojom.h" +#include "components/strings/grit/components_strings.h" #include "testing/gtest/include/gtest/gtest.h" +#include "ui/base/l10n/l10n_util.h" namespace payments { @@ -281,22 +284,61 @@ RecreateSpecWithOptionsAndDetails(std::move(options), std::move(details)); EXPECT_EQ("option:2", spec()->selected_shipping_option()->id); + EXPECT_TRUE(spec()->selected_shipping_option_error().empty()); + // Call updateWith with option:1 now selected. std::vector<mojom::PaymentShippingOptionPtr> new_shipping_options; mojom::PaymentShippingOptionPtr new_option = mojom::PaymentShippingOption::New(); new_option->id = "option:1"; - new_option->selected = false; - shipping_options.push_back(std::move(new_option)); + new_option->selected = true; + new_shipping_options.push_back(std::move(new_option)); mojom::PaymentShippingOptionPtr new_option2 = mojom::PaymentShippingOption::New(); new_option2->id = "option:2"; - new_option2->selected = true; + new_option2->selected = false; new_shipping_options.push_back(std::move(new_option2)); mojom::PaymentDetailsPtr new_details = mojom::PaymentDetails::New(); new_details->shipping_options = std::move(new_shipping_options); spec()->UpdateWith(std::move(new_details)); + + EXPECT_EQ("option:1", spec()->selected_shipping_option()->id); + EXPECT_TRUE(spec()->selected_shipping_option_error().empty()); +} + +// Test that the last shipping option is selected, even in the case of +// updateWith. +TEST_F(PaymentRequestSpecTest, ShippingOptionsSelection_NoOptionsAtAll) { + // No options are provided at first. + mojom::PaymentOptionsPtr options = mojom::PaymentOptions::New(); + options->request_shipping = true; + RecreateSpecWithOptionsAndDetails(std::move(options), + mojom::PaymentDetails::New()); + + // No option selected, but no error either (the flow just started and no + // address has been selected yet). + EXPECT_EQ(nullptr, spec()->selected_shipping_option()); + EXPECT_TRUE(spec()->selected_shipping_option_error().empty()); + + // Call updateWith with still no options. + spec()->UpdateWith(mojom::PaymentDetails::New()); + + // Now it's more serious. No option selected, but there is a generic error. + EXPECT_EQ(nullptr, spec()->selected_shipping_option()); + EXPECT_EQ( + l10n_util::GetStringUTF16(IDS_PAYMENTS_UNSUPPORTED_SHIPPING_ADDRESS), + spec()->selected_shipping_option_error()); + + // Call updateWith with still no options, but a customized error string. + mojom::PaymentDetailsPtr details = mojom::PaymentDetails::New(); + details->error = "No can do shipping."; + spec()->UpdateWith(std::move(details)); + + // No option selected, but there is an error provided by the mercahnt. + EXPECT_EQ(nullptr, spec()->selected_shipping_option()); + EXPECT_EQ(base::ASCIIToUTF16("No can do shipping."), + spec()->selected_shipping_option_error()); } } // namespace payments
diff --git a/components/security_state_strings.grdp b/components/security_state_strings.grdp index d3580a9..8e94326f 100644 --- a/components/security_state_strings.grdp +++ b/components/security_state_strings.grdp
@@ -4,6 +4,9 @@ <message name="IDS_PRIVATE_USER_DATA_INPUT" desc="Summary phrase for a security problem where the site collects private user data on an insecure page." translateable="false"> Private User Data Input </message> + <message name="IDS_PRIVATE_USER_DATA_INPUT_DESCRIPTION" desc="Description of a security problem where the site collects private user data on an insecure page, which results in an omnibox warning." translateable="false"> + This page includes a password or credit card input over HTTP. A warning has been added to the URL bar. + </message> <message name="IDS_SAFEBROWSING_WARNING" desc="Summary phrase for a security problem where the site is deemed unsafe by the SafeBrowsing service." translateable="false"> This page is dangerous (flagged by Google Safe Browsing). </message>
diff --git a/components/subresource_filter/content/browser/fake_safe_browsing_database_manager.cc b/components/subresource_filter/content/browser/fake_safe_browsing_database_manager.cc index cfd968e..56cd2ba0 100644 --- a/components/subresource_filter/content/browser/fake_safe_browsing_database_manager.cc +++ b/components/subresource_filter/content/browser/fake_safe_browsing_database_manager.cc
@@ -19,6 +19,10 @@ url_to_threat_type_[url] = threat_type; } +void FakeSafeBrowsingDatabaseManager::RemoveBlacklistedUrl(const GURL& url) { + url_to_threat_type_.erase(url); +} + void FakeSafeBrowsingDatabaseManager::SimulateTimeout() { simulate_timeout_ = true; } @@ -53,6 +57,10 @@ return; client->OnCheckBrowseUrlResult(url, url_to_threat_type_[url], safe_browsing::ThreatMetadata()); + // Erase the client when a check is complete. Otherwise, it's possible + // subsequent clients that share an address with this one will DCHECK in + // CheckUrlForSubresourceFilter. + checks_.erase(client); } bool FakeSafeBrowsingDatabaseManager::CheckResourceUrl(const GURL& url,
diff --git a/components/subresource_filter/content/browser/fake_safe_browsing_database_manager.h b/components/subresource_filter/content/browser/fake_safe_browsing_database_manager.h index f36c437..d216217 100644 --- a/components/subresource_filter/content/browser/fake_safe_browsing_database_manager.h +++ b/components/subresource_filter/content/browser/fake_safe_browsing_database_manager.h
@@ -23,6 +23,7 @@ void AddBlacklistedUrl(const GURL& url, safe_browsing::SBThreatType threat_type); + void RemoveBlacklistedUrl(const GURL& url); void SimulateTimeout();
diff --git a/content/browser/media/session/audio_focus_delegate_default.cc b/content/browser/media/session/audio_focus_delegate_default.cc index b1ae90f..586bbf3 100644 --- a/content/browser/media/session/audio_focus_delegate_default.cc +++ b/content/browser/media/session/audio_focus_delegate_default.cc
@@ -42,7 +42,7 @@ bool AudioFocusDelegateDefault::RequestAudioFocus( AudioFocusManager::AudioFocusType audio_focus_type) { if (!base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kEnableDefaultMediaSession)) { + switches::kEnableAudioFocus)) { return true; }
diff --git a/content/browser/media/session/audio_focus_delegate_default_browsertest.cc b/content/browser/media/session/audio_focus_delegate_default_browsertest.cc index b84d388..ed4ec737 100644 --- a/content/browser/media/session/audio_focus_delegate_default_browsertest.cc +++ b/content/browser/media/session/audio_focus_delegate_default_browsertest.cc
@@ -15,7 +15,7 @@ class AudioFocusDelegateDefaultBrowserTest : public ContentBrowserTest { protected: void SetUpCommandLine(base::CommandLine* command_line) override { - command_line->AppendSwitch(switches::kEnableDefaultMediaSession); + command_line->AppendSwitch(switches::kEnableAudioFocus); } void Run(WebContents* start_contents, WebContents* interrupt_contents) {
diff --git a/content/browser/media/session/audio_focus_manager_unittest.cc b/content/browser/media/session/audio_focus_manager_unittest.cc index 6d476852..aa89b54 100644 --- a/content/browser/media/session/audio_focus_manager_unittest.cc +++ b/content/browser/media/session/audio_focus_manager_unittest.cc
@@ -39,7 +39,7 @@ void SetUp() override { base::CommandLine::ForCurrentProcess()->AppendSwitch( - switches::kEnableDefaultMediaSession); + switches::kEnableAudioFocus); rph_factory_.reset(new MockRenderProcessHostFactory()); RenderProcessHostImpl::set_render_process_host_factory(rph_factory_.get()); browser_context_.reset(new TestBrowserContext());
diff --git a/content/browser/media/session/media_session_controllers_manager.cc b/content/browser/media/session/media_session_controllers_manager.cc index 48f1377..79bf0f1 100644 --- a/content/browser/media/session/media_session_controllers_manager.cc +++ b/content/browser/media/session/media_session_controllers_manager.cc
@@ -17,7 +17,7 @@ return true; #else return base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kEnableDefaultMediaSession); + switches::kEnableAudioFocus); #endif }
diff --git a/content/browser/media/session/media_session_impl_visibility_browsertest.cc b/content/browser/media/session/media_session_impl_visibility_browsertest.cc index 18dee99..a5ad0b02 100644 --- a/content/browser/media/session/media_session_impl_visibility_browsertest.cc +++ b/content/browser/media/session/media_session_impl_visibility_browsertest.cc
@@ -99,7 +99,7 @@ void SetUpCommandLine(base::CommandLine* command_line) override { command_line->AppendSwitch(switches::kIgnoreAutoplayRestrictionsForTests); #if !defined(OS_ANDROID) - command_line->AppendSwitch(switches::kEnableDefaultMediaSession); + command_line->AppendSwitch(switches::kEnableAudioFocus); #endif // !defined(OS_ANDROID) VisibilityTestData params = GetVisibilityTestData();
diff --git a/content/browser/media/session/pepper_playback_observer.cc b/content/browser/media/session/pepper_playback_observer.cc index f854321..a60ba99 100644 --- a/content/browser/media/session/pepper_playback_observer.cc +++ b/content/browser/media/session/pepper_playback_observer.cc
@@ -19,8 +19,8 @@ bool ShouldDuckFlash() { return base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( - switches::kEnableDefaultMediaSession) == - switches::kEnableDefaultMediaSessionDuckFlash; + switches::kEnableAudioFocus) == + switches::kEnableAudioFocusDuckFlash; } } // anonymous namespace
diff --git a/content/browser/media/session/pepper_player_delegate.cc b/content/browser/media/session/pepper_player_delegate.cc index b34fe57..a36a4c301 100644 --- a/content/browser/media/session/pepper_player_delegate.cc +++ b/content/browser/media/session/pepper_player_delegate.cc
@@ -17,8 +17,8 @@ bool ShouldDuckFlash() { return base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( - switches::kEnableDefaultMediaSession) == - switches::kEnableDefaultMediaSessionDuckFlash; + switches::kEnableAudioFocus) == + switches::kEnableAudioFocusDuckFlash; } } // anonymous namespace
diff --git a/extensions/browser/api/web_request/web_request_permissions.cc b/extensions/browser/api/web_request/web_request_permissions.cc index 22dcaf58..033a0f11 100644 --- a/extensions/browser/api/web_request/web_request_permissions.cc +++ b/extensions/browser/api/web_request/web_request_permissions.cc
@@ -7,6 +7,8 @@ #include "base/strings/string_piece.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" +#include "chromeos/login/login_state.h" +#include "content/public/browser/child_process_security_policy.h" #include "content/public/browser/resource_request_info.h" #include "extensions/browser/extension_navigation_ui_data.h" #include "extensions/browser/guest_view/web_view/web_view_renderer_state.h" @@ -45,11 +47,14 @@ // Returns true if the URL is sensitive and requests to this URL must not be // modified/canceled by extensions, e.g. because it is targeted to the webstore // to check for updates, extension blacklisting, etc. -bool IsSensitiveURL(const GURL& url) { +bool IsSensitiveURL(const GURL& url, + bool is_request_from_browser_or_webui_renderer) { // TODO(battre) Merge this, CanExtensionAccessURL and // PermissionsData::CanAccessPage into one function. bool sensitive_chrome_url = false; - const base::StringPiece& host = url.host_piece(); + base::StringPiece host = url.host_piece(); + while (host.ends_with(".")) + host.remove_suffix(1u); const char kGoogleCom[] = "google.com"; const char kClient[] = "clients"; if (url.DomainIs(kGoogleCom)) { @@ -57,23 +62,34 @@ // This protects requests to several internal services such as sync, // extension update pings, captive portal detection, fraudulent certificate // reporting, autofill and others. - if (base::StartsWith(host, kClient, base::CompareCase::SENSITIVE)) { - bool match = true; - for (base::StringPiece::const_iterator - i = host.begin() + strlen(kClient), - end = host.end() - (strlen(kGoogleCom) + 1); - i != end; ++i) { - if (!isdigit(*i)) { + // + // These URLs are only protected for requests from the browser and webui + // renderers, not for requests from common renderers, because + // clients*.google.com are also used by websites. + if (is_request_from_browser_or_webui_renderer) { + base::StringPiece::size_type pos = host.rfind(kClient); + if (pos != base::StringPiece::npos) { + bool match = true; + if (pos > 0 && host[pos - 1] != '.') { match = false; - break; + } else { + for (base::StringPiece::const_iterator + i = host.begin() + pos + strlen(kClient), + end = host.end() - (strlen(kGoogleCom) + 1); + i != end; ++i) { + if (!isdigit(*i)) { + match = false; + break; + } + } } + sensitive_chrome_url = sensitive_chrome_url || match; } - sensitive_chrome_url = sensitive_chrome_url || match; } - // This protects requests to safe browsing, link doctor, and possibly - // others. + + // Safebrowsing and Chrome Webstore URLs are always protected, i.e. also + // for requests from common renderers. sensitive_chrome_url = sensitive_chrome_url || - url.DomainIs("clients.google.com") || url.DomainIs("sb-ssl.google.com") || (url.DomainIs("chrome.google.com") && base::StartsWith(url.path_piece(), "/webstore", @@ -88,8 +104,13 @@ const extensions::InfoMap* extension_info_map, const net::URLRequest* request, extensions::ExtensionNavigationUIData* navigation_ui_data) { - // Hide requests from the Chrome WebStore App or signin process. + // Hide requests from the Chrome WebStore App, signin process and WebUI. const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request); + + // Requests from the browser and webui get special protection for + // clients*.google.com URLs. + bool is_request_from_browser = true; + bool is_request_from_webui_renderer = false; if (info) { int process_id = info->GetChildID(); // Never hide requests from guest processes. @@ -103,10 +124,17 @@ process_id)) { return true; } + + is_request_from_browser = false; + is_request_from_webui_renderer = + content::ChildProcessSecurityPolicy::GetInstance()->HasWebUIBindings( + process_id); } const GURL& url = request->url(); - return IsSensitiveURL(url) || !HasWebRequestScheme(url); + return IsSensitiveURL( + url, is_request_from_browser || is_request_from_webui_renderer) || + !HasWebRequestScheme(url); } // static
diff --git a/extensions/browser/api/web_request/web_request_permissions.h b/extensions/browser/api/web_request/web_request_permissions.h index f708355..ee6ba29 100644 --- a/extensions/browser/api/web_request/web_request_permissions.h +++ b/extensions/browser/api/web_request/web_request_permissions.h
@@ -23,7 +23,8 @@ } // Exposed for unit testing. -bool IsSensitiveURL(const GURL& url); +bool IsSensitiveURL(const GURL& url, + bool is_request_from_browser_or_webui_renderer); // This class is used to test whether extensions may modify web requests. class WebRequestPermissions {
diff --git a/extensions/browser/api/web_request/web_request_permissions_unittest.cc b/extensions/browser/api/web_request/web_request_permissions_unittest.cc index d8b212d..c872e90 100644 --- a/extensions/browser/api/web_request/web_request_permissions_unittest.cc +++ b/extensions/browser/api/web_request/web_request_permissions_unittest.cc
@@ -12,28 +12,38 @@ TEST(ExtensionWebRequestPermissions, IsSensitiveURL) { struct TestCase { const char* url; - bool is_sensitive; + bool is_sensitive_if_request_from_common_renderer; + bool is_sensitive_if_request_from_browser_or_webui_renderer; } cases[] = { - {"http://www.google.com", false}, - {"http://www.example.com", false}, - {"http://clients.google.com", true}, - {"http://clients4.google.com", true}, - {"http://clients9999.google.com", true}, - {"http://clients9999..google.com", false}, - {"http://clients9999.example.google.com", false}, - {"http://clients.google.com.", true}, - {"http://.clients.google.com.", true}, - {"http://google.example.com", false}, - {"http://www.example.com", false}, - {"http://clients.google.com", true}, - {"http://sb-ssl.google.com", true}, - {"http://sb-ssl.random.google.com", false}, - {"http://chrome.google.com", false}, - {"http://chrome.google.com/webstore", true}, - {"http://chrome.google.com/webstore?query", true}, + {"http://www.google.com", false, false}, + {"http://www.example.com", false, false}, + {"http://clients.google.com", false, true}, + {"http://clients4.google.com", false, true}, + {"http://clients9999.google.com", false, true}, + {"http://clients9999..google.com", false, false}, + {"http://clients9999.example.google.com", false, false}, + {"http://clients.google.com.", false, true}, + {"http://.clients.google.com.", false, true}, + {"http://google.example.com", false, false}, + {"http://www.example.com", false, false}, + {"http://clients.google.com", false, true}, + {"http://sb-ssl.google.com", true, true}, + {"http://sb-ssl.random.google.com", false, false}, + {"http://chrome.google.com", false, false}, + {"http://chrome.google.com/webstore", true, true}, + {"http://chrome.google.com/webstore?query", true, true}, }; for (const TestCase& test : cases) { - EXPECT_EQ(test.is_sensitive, IsSensitiveURL(GURL(test.url))) << test.url; + EXPECT_EQ( + test.is_sensitive_if_request_from_common_renderer, + IsSensitiveURL(GURL(test.url), + false /* is_request_from_browser_or_webui_renderer */)) + << test.url; + EXPECT_EQ( + test.is_sensitive_if_request_from_browser_or_webui_renderer, + IsSensitiveURL(GURL(test.url), + true /* is_request_from_browser_or_webui_renderer */)) + << test.url; } }
diff --git a/ios/chrome/app/startup/setup_debugging.mm b/ios/chrome/app/startup/setup_debugging.mm index 24ae2994..7fe86d7 100644 --- a/ios/chrome/app/startup/setup_debugging.mm +++ b/ios/chrome/app/startup/setup_debugging.mm
@@ -33,6 +33,7 @@ [whiteList addObject:@"glif-google-to-dots_28"]; // TODO(crbug.com/721338): Add missing image. [whiteList addObject:@"voice_icon_keyboard_accessory"]; + [whiteList addObject:@"voice_icon"]; // The original implementation of [UIImage imageNamed:]. // Called by the new implementation.
diff --git a/ios/clean/chrome/browser/ui/tab_grid/tab_grid_view_controller.mm b/ios/clean/chrome/browser/ui/tab_grid/tab_grid_view_controller.mm index bdfcad6..bd7c3e1e 100644 --- a/ios/clean/chrome/browser/ui/tab_grid/tab_grid_view_controller.mm +++ b/ios/clean/chrome/browser/ui/tab_grid/tab_grid_view_controller.mm
@@ -85,6 +85,14 @@ UIEdgeInsetsMake(CGRectGetMaxY(self.toolbar.frame), 0, 0, 0); } +- (void)viewWillTransitionToSize:(CGSize)size + withTransitionCoordinator: + (id<UIViewControllerTransitionCoordinator>)coordinator { + // We need to dismiss the ToolsMenu everytime the Toolbar frame changes + // (e.g. Size changes, rotation changes, etc.) + [self.dispatcher closeToolsMenu]; +} + #pragma mark - SettingsActions - (void)showSettings:(id)sender {
diff --git a/ios/clean/chrome/browser/ui/toolbar/toolbar_view_controller.mm b/ios/clean/chrome/browser/ui/toolbar/toolbar_view_controller.mm index 50a9e6a7..7511cfd 100644 --- a/ios/clean/chrome/browser/ui/toolbar/toolbar_view_controller.mm +++ b/ios/clean/chrome/browser/ui/toolbar/toolbar_view_controller.mm
@@ -65,6 +65,8 @@ return self; } +#pragma mark - View lifecyle + - (void)viewDidLoad { self.view.backgroundColor = [UIColor lightGrayColor]; [self addChildViewController:self.locationBarViewController @@ -115,6 +117,14 @@ ]]; } +- (void)viewWillTransitionToSize:(CGSize)size + withTransitionCoordinator: + (id<UIViewControllerTransitionCoordinator>)coordinator { + // We need to dismiss the ToolsMenu everytime the Toolbar frame changes + // (e.g. Size changes, rotation changes, etc.) + [self.dispatcher closeToolsMenu]; +} + #pragma mark - Components Setup - (void)setUpToolbarButtons {
diff --git a/media/base/media_switches.cc b/media/base/media_switches.cc index 126b0d5..1011947 100644 --- a/media/base/media_switches.cc +++ b/media/base/media_switches.cc
@@ -69,17 +69,16 @@ #endif #if !defined(OS_ANDROID) || BUILDFLAG(ENABLE_PLUGINS) -// Use a media session for each tabs in a way that two tabs can't play on top of -// each other. This is different from the Media Session API as it is enabling a -// default behaviour for the browser. The allowed values are: "" (empty), -// |kEnableDefaultMediaSessionDuckFlash|. -const char kEnableDefaultMediaSession[] = "enable-default-media-session"; +// Enable a internal audio focus management between tabs in such a way that two +// tabs can't play on top of each other. +// The allowed values are: "" (empty) or |kEnableAudioFocusDuckFlash|. +const char kEnableAudioFocus[] = "enable-audio-focus"; #endif // !defined(OS_ANDROID) || BUILDFLAG(ENABLE_PLUGINS) #if BUILDFLAG(ENABLE_PLUGINS) -// This value is used as an option for |kEnableDefaultMediaSession|. Flash will +// This value is used as an option for |kEnableAudioFocus|. Flash will // be ducked when losing audio focus. -const char kEnableDefaultMediaSessionDuckFlash[] = "duck-flash"; +const char kEnableAudioFocusDuckFlash[] = "duck-flash"; #endif // BUILDFLAG(ENABLE_PLUGINS) #if BUILDFLAG(ENABLE_RUNTIME_MEDIA_RENDERER_SELECTION)
diff --git a/media/base/media_switches.h b/media/base/media_switches.h index a14e0d2..4ff9c98 100644 --- a/media/base/media_switches.h +++ b/media/base/media_switches.h
@@ -50,11 +50,11 @@ #endif #if !defined(OS_ANDROID) || BUILDFLAG(ENABLE_PLUGINS) -MEDIA_EXPORT extern const char kEnableDefaultMediaSession[]; +MEDIA_EXPORT extern const char kEnableAudioFocus[]; #endif // !defined(OS_ANDROID) || BUILDFLAG(ENABLE_PLUGINS) #if BUILDFLAG(ENABLE_PLUGINS) -MEDIA_EXPORT extern const char kEnableDefaultMediaSessionDuckFlash[]; +MEDIA_EXPORT extern const char kEnableAudioFocusDuckFlash[]; #endif // BUILDFLAG(ENABLE_PLUGINS) #if BUILDFLAG(ENABLE_RUNTIME_MEDIA_RENDERER_SELECTION)
diff --git a/net/disk_cache/backend_unittest.cc b/net/disk_cache/backend_unittest.cc index ca0e0ee..79fcdf7 100644 --- a/net/disk_cache/backend_unittest.cc +++ b/net/disk_cache/backend_unittest.cc
@@ -3886,6 +3886,41 @@ EXPECT_TRUE(keys_to_match.empty()); } +TEST_F(DiskCacheBackendTest, SimpleCacheIndexRecovery) { + // Make sure we can recover set of entries when the index was removed. + SetSimpleCacheMode(); + InitCache(); + std::set<std::string> key_pool; + ASSERT_TRUE(CreateSetOfRandomEntries(&key_pool)); + + cache_.reset(); + + // Give it a chance to write out the index, so we can delete it (rather + // than have it write it after we delete it). + disk_cache::SimpleBackendImpl::FlushWorkerPoolForTesting(); + base::RunLoop().RunUntilIdle(); + + base::FilePath index_path = + cache_path_.AppendASCII("index-dir").AppendASCII("the-real-index"); + ASSERT_TRUE(base::DeleteFile(index_path, false)); + + DisableFirstCleanup(); + InitCache(); + // A bit surprising, but it calls it "NEWCACHE" if there was no index, + // even if it reconstructed non-zero things. + EXPECT_EQ(disk_cache::SimpleIndex::INITIALIZE_METHOD_NEWCACHE, + simple_cache_impl_->index()->init_method()); + + // Check that enumeration returns all entries. + std::set<std::string> keys_to_match(key_pool); + std::unique_ptr<TestIterator> iter = CreateIterator(); + size_t count = 0; + ASSERT_TRUE(EnumerateAndMatchKeys(-1, iter.get(), &keys_to_match, &count)); + iter.reset(); + EXPECT_EQ(key_pool.size(), count); + EXPECT_TRUE(keys_to_match.empty()); +} + // Tests that the enumerations are not affected by dooming an entry in the // middle. TEST_F(DiskCacheBackendTest, SimpleCacheEnumerationWhileDoomed) {
diff --git a/net/spdy/core/spdy_framer.cc b/net/spdy/core/spdy_framer.cc index cc4362e..51689299 100644 --- a/net/spdy/core/spdy_framer.cc +++ b/net/spdy/core/spdy_framer.cc
@@ -17,7 +17,6 @@ #include "base/lazy_instance.h" #include "base/logging.h" -#include "base/memory/ptr_util.h" #include "base/metrics/histogram_macros.h" #include "base/strings/string_util.h" #include "net/quic/platform/api/quic_flags.h" @@ -254,7 +253,7 @@ return GetFrameHeaderSize() + 8; } -size_t SpdyFramer::GetHeadersMinimumSize() const { +size_t SpdyFramer::GetHeadersMinimumSize() const { // Size, in bytes, of a HEADERS frame not including the variable-length // header block. return GetFrameHeaderSize(); @@ -281,9 +280,9 @@ size_t SpdyFramer::GetAltSvcMinimumSize() const { // Size, in bytes, of an ALTSVC frame not including the Field-Value and - // (optional) Origin fields, both of which can vary in length. Note that this - // gives a lower bound on the frame size rather than a true minimum; the - // actual frame should always be larger than this. + // (optional) Origin fields, both of which can vary in length. Note that + // this gives a lower bound on the frame size rather than a true minimum; + // the actual frame should always be larger than this. // Calculated as frame prefix + 2 (origin_len). return GetFrameHeaderSize() + 2; } @@ -757,7 +756,7 @@ } break; case SpdyFrameType::SETTINGS: { - // Make sure that we have an integral number of 8-byte key/value pairs, + // Make sure that we have an integral number of 8-byte key/value pairs. // Size of each key/value pair in bytes. if (current_frame_length_ < GetSettingsMinimumSize() || (current_frame_length_ - GetFrameHeaderSize()) % @@ -961,7 +960,8 @@ CHANGE_STATE(SPDY_CONTROL_FRAME_PAYLOAD); } -size_t SpdyFramer::UpdateCurrentFrameBuffer(const char** data, size_t* len, +size_t SpdyFramer::UpdateCurrentFrameBuffer(const char** data, + size_t* len, size_t max_bytes) { size_t bytes_to_read = std::min(*len, max_bytes); if (bytes_to_read > 0) { @@ -972,8 +972,7 @@ return bytes_to_read; } -size_t SpdyFramer::GetSerializedLength( - const SpdyHeaderBlock* headers) { +size_t SpdyFramer::GetSerializedLength(const SpdyHeaderBlock* headers) { const size_t num_name_value_pairs_size = sizeof(uint32_t); const size_t length_of_name_size = num_name_value_pairs_size; const size_t length_of_value_size = num_name_value_pairs_size; @@ -994,8 +993,8 @@ const size_t original_len = len; if (remaining_control_header_ > 0) { - size_t bytes_read = UpdateCurrentFrameBuffer(&data, &len, - remaining_control_header_); + size_t bytes_read = + UpdateCurrentFrameBuffer(&data, &len, remaining_control_header_); remaining_control_header_ -= bytes_read; remaining_data_length_ -= bytes_read; } @@ -1301,8 +1300,8 @@ size_t SpdyFramer::ProcessControlFramePayload(const char* data, size_t len) { size_t original_len = len; - size_t bytes_read = UpdateCurrentFrameBuffer(&data, &len, - remaining_data_length_); + size_t bytes_read = + UpdateCurrentFrameBuffer(&data, &len, remaining_data_length_); remaining_data_length_ -= bytes_read; if (remaining_data_length_ == 0) { SpdyFrameReader reader(current_frame_buffer_.data(), @@ -1499,6 +1498,7 @@ set_error(SPDY_INVALID_PADDING); return 0; } + CHANGE_STATE(SPDY_FORWARD_STREAM_FRAME); return original_len - len; } @@ -1660,7 +1660,7 @@ SpdyFramer::SpdyFrameIterator::~SpdyFrameIterator() {} size_t SpdyFramer::SpdyFrameIterator::NextFrame(ZeroCopyOutputBuffer* output) { - SpdyFrameWithHeaderBlockIR* frame_ir = GetIR(); + const SpdyFrameWithHeaderBlockIR* frame_ir = GetIR(); if (frame_ir == nullptr) { LOG(WARNING) << "frame_ir doesn't exist."; return false; @@ -1694,15 +1694,14 @@ } } + framer_->SetIsLastFrame(!has_next_frame_); if (is_first_frame_) { is_first_frame_ = false; - frame_ir->set_end_headers(!has_next_frame_); size_t free_bytes_before = output->BytesFree(); bool ok = SerializeGivenEncoding(*encoding, output); return ok ? free_bytes_before - output->BytesFree() : 0; } else { SpdyContinuationIR continuation_ir(frame_ir->stream_id()); - continuation_ir.set_end_headers(!has_next_frame_); continuation_ir.take_encoding(std::move(encoding)); return framer_->SerializeContinuation(continuation_ir, output); } @@ -1714,14 +1713,16 @@ SpdyFramer::SpdyHeaderFrameIterator::SpdyHeaderFrameIterator( SpdyFramer* framer, - std::unique_ptr<SpdyHeadersIR> headers_ir) + std::unique_ptr<const SpdyHeadersIR> headers_ir) : SpdyFrameIterator(framer), headers_ir_(std::move(headers_ir)) { SetEncoder(headers_ir_.get()); + GetFramer()->SetOverwriteLastFrame(true); } SpdyFramer::SpdyHeaderFrameIterator::~SpdyHeaderFrameIterator() {} -SpdyFrameWithHeaderBlockIR* SpdyFramer::SpdyHeaderFrameIterator::GetIR() const { +const SpdyFrameWithHeaderBlockIR* SpdyFramer::SpdyHeaderFrameIterator::GetIR() + const { return headers_ir_.get(); } @@ -1738,15 +1739,16 @@ SpdyFramer::SpdyPushPromiseFrameIterator::SpdyPushPromiseFrameIterator( SpdyFramer* framer, - std::unique_ptr<SpdyPushPromiseIR> push_promise_ir) + std::unique_ptr<const SpdyPushPromiseIR> push_promise_ir) : SpdyFrameIterator(framer), push_promise_ir_(std::move(push_promise_ir)) { SetEncoder(push_promise_ir_.get()); + GetFramer()->SetOverwriteLastFrame(true); } SpdyFramer::SpdyPushPromiseFrameIterator::~SpdyPushPromiseFrameIterator() {} -SpdyFrameWithHeaderBlockIR* SpdyFramer::SpdyPushPromiseFrameIterator::GetIR() - const { +const SpdyFrameWithHeaderBlockIR* +SpdyFramer::SpdyPushPromiseFrameIterator::GetIR() const { return push_promise_ir_.get(); } @@ -1763,7 +1765,7 @@ SpdyFramer::SpdyControlFrameIterator::SpdyControlFrameIterator( SpdyFramer* framer, - std::unique_ptr<SpdyFrameIR> frame_ir) + std::unique_ptr<const SpdyFrameIR> frame_ir) : framer_(framer), frame_ir_(std::move(frame_ir)) {} SpdyFramer::SpdyControlFrameIterator::~SpdyControlFrameIterator() {} @@ -1779,10 +1781,10 @@ return frame_ir_ != nullptr; } -// TODO(yasong): remove all the down_casts. +// TODO(yasong): remove all the static_casts. std::unique_ptr<SpdyFrameSequence> SpdyFramer::CreateIterator( SpdyFramer* framer, - std::unique_ptr<SpdyFrameIR> frame_ir) { + std::unique_ptr<const SpdyFrameIR> frame_ir) { std::unique_ptr<SpdyFrameSequence> result = nullptr; switch (frame_ir->frame_type()) { case SpdyFrameType::DATA: { @@ -1791,20 +1793,20 @@ break; } case SpdyFrameType::HEADERS: { - result = base::MakeUnique<SpdyHeaderFrameIterator>( + result = SpdyMakeUnique<SpdyHeaderFrameIterator>( framer, - base::WrapUnique(static_cast<SpdyHeadersIR*>(frame_ir.get()))); + SpdyWrapUnique(static_cast<const SpdyHeadersIR*>(frame_ir.get()))); break; } case SpdyFrameType::PUSH_PROMISE: { - result = base::MakeUnique<SpdyPushPromiseFrameIterator>( - framer, - base::WrapUnique(static_cast<SpdyPushPromiseIR*>(frame_ir.get()))); + result = SpdyMakeUnique<SpdyPushPromiseFrameIterator>( + framer, SpdyWrapUnique( + static_cast<const SpdyPushPromiseIR*>(frame_ir.get()))); break; } default: { - result = base::MakeUnique<SpdyControlFrameIterator>(framer, - std::move(frame_ir)); + result = + SpdyMakeUnique<SpdyControlFrameIterator>(framer, std::move(frame_ir)); } } return result; @@ -2197,7 +2199,10 @@ const SpdyString& encoding = continuation.encoding(); size_t frame_size = GetContinuationMinimumSize() + encoding.size(); SpdyFrameBuilder builder(frame_size); - uint8_t flags = continuation.end_headers() ? HEADERS_FLAG_END_HEADERS : 0; + uint8_t flags = ((overwrite_last_frame_ && is_last_frame_) || + (!overwrite_last_frame_ && continuation.end_headers())) + ? HEADERS_FLAG_END_HEADERS + : 0; builder.BeginNewFrame(*this, SpdyFrameType::CONTINUATION, flags, continuation.stream_id()); DCHECK_EQ(GetFrameHeaderSize(), builder.length()); @@ -2648,7 +2653,10 @@ const SpdyString& encoding = continuation.encoding(); size_t frame_size = GetContinuationMinimumSize() + encoding.size(); SpdyFrameBuilder builder(frame_size, output); - uint8_t flags = continuation.end_headers() ? HEADERS_FLAG_END_HEADERS : 0; + uint8_t flags = ((overwrite_last_frame_ && is_last_frame_) || + (!overwrite_last_frame_ && continuation.end_headers())) + ? HEADERS_FLAG_END_HEADERS + : 0; bool ok = builder.BeginNewFrame(*this, SpdyFrameType::CONTINUATION, flags, continuation.stream_id(), frame_size - GetFrameHeaderSize()); @@ -2684,8 +2692,7 @@ ok = ok && builder.WriteUInt32(PackStreamDependencyValues( priority.exclusive(), priority.parent_stream_id())) && - // Per RFC 7540 section 6.3, serialized weight value is actual value - // - 1. + // Per RFC 7540 section 6.3, serialized weight value is actual value - 1. builder.WriteUInt8(priority.weight() - 1); DCHECK_EQ(GetPrioritySize(), builder.length()); return ok; @@ -2793,9 +2800,12 @@ if (header_ir.fin()) { flags |= CONTROL_FLAG_FIN; } - if (header_ir.end_headers()) { + + if ((overwrite_last_frame_ && is_last_frame_) || + (!overwrite_last_frame_ && header_ir.end_headers())) { flags |= HEADERS_FLAG_END_HEADERS; } + if (header_ir.padded()) { flags |= HEADERS_FLAG_PADDED; } @@ -2813,7 +2823,8 @@ flags = flags | PUSH_PROMISE_FLAG_PADDED; } - if (push_promise_ir.end_headers()) { + if ((overwrite_last_frame_ && is_last_frame_) || + (!overwrite_last_frame_ && push_promise_ir.end_headers())) { flags |= PUSH_PROMISE_FLAG_END_PUSH_PROMISE; } @@ -2836,8 +2847,8 @@ << FrameTypeToString(type); } - // Write all the padding payload and as much of the data payload as - // possible into the initial frame. + // Write all the padding payload and as much of the data payload as possible + // into the initial frame. size_t bytes_remaining = 0; bytes_remaining = hpack_encoding.size() -
diff --git a/net/spdy/core/spdy_framer.h b/net/spdy/core/spdy_framer.h index 87c6959..02ee43f 100644 --- a/net/spdy/core/spdy_framer.h +++ b/net/spdy/core/spdy_framer.h
@@ -396,7 +396,7 @@ // Create a SpdyFrameSequence to serialize |frame_ir|. static std::unique_ptr<SpdyFrameSequence> CreateIterator( SpdyFramer* framer, - std::unique_ptr<SpdyFrameIR> frame_ir); + std::unique_ptr<const SpdyFrameIR> frame_ir); // Serialize a data frame. SpdySerializedFrame SerializeData(const SpdyDataIR& data) const; @@ -593,12 +593,16 @@ void SetEncoderHeaderTableDebugVisitor( std::unique_ptr<HpackHeaderTable::DebugVisitorInterface> visitor); - // For use in SpdyFramerDecoderAdapter implementations; returns a HPACK + // For use in SpdyFramerDecoderAdapter implementations; returns the HPACK // decoder to be used. HpackDecoderInterface* GetHpackDecoderForAdapter() { return GetHpackDecoder(); } + void SetOverwriteLastFrame(bool value) { overwrite_last_frame_ = value; } + void SetIsLastFrame(bool value) { is_last_frame_ = value; } + bool ShouldOverwriteLastFrame() const { return overwrite_last_frame_; } + // Returns the estimate of dynamically allocated memory in bytes. size_t EstimateMemoryUsage() const; @@ -628,8 +632,9 @@ // } class SPDY_EXPORT_PRIVATE SpdyFrameIterator : public SpdyFrameSequence { public: - // Creates an iterator with the provided framer. Does not take ownership of - // |framer|, |framer| must outlive this instance. + // Creates an iterator with the provided framer. + // Does not take ownership of |framer|. + // |framer| must outlive this instance. explicit SpdyFrameIterator(SpdyFramer* framer); ~SpdyFrameIterator() override; @@ -645,13 +650,13 @@ SpdyFrameIterator& operator=(const SpdyFrameIterator&) = delete; protected: - virtual SpdyFrameWithHeaderBlockIR* GetIR() const = 0; + virtual const SpdyFrameWithHeaderBlockIR* GetIR() const = 0; virtual size_t GetFrameSizeSansBlock() const = 0; virtual bool SerializeGivenEncoding(const SpdyString& encoding, ZeroCopyOutputBuffer* output) const = 0; SpdyFramer* GetFramer() const { return framer_; } - void SetEncoder(SpdyFrameWithHeaderBlockIR* ir) { + void SetEncoder(const SpdyFrameWithHeaderBlockIR* ir) { encoder_ = framer_->GetHpackEncoder()->EncodeHeaderSet(ir->header_block()); } @@ -673,17 +678,17 @@ public: // Does not take ownership of |framer|. Take ownership of |headers_ir|. SpdyHeaderFrameIterator(SpdyFramer* framer, - std::unique_ptr<SpdyHeadersIR> headers_ir); + std::unique_ptr<const SpdyHeadersIR> headers_ir); ~SpdyHeaderFrameIterator() override; private: - SpdyFrameWithHeaderBlockIR* GetIR() const override; + const SpdyFrameWithHeaderBlockIR* GetIR() const override; size_t GetFrameSizeSansBlock() const override; bool SerializeGivenEncoding(const SpdyString& encoding, ZeroCopyOutputBuffer* output) const override; - const std::unique_ptr<SpdyHeadersIR> headers_ir_; + const std::unique_ptr<const SpdyHeadersIR> headers_ir_; }; // Iteratively converts a SpdyPushPromiseIR (with a possibly huge @@ -695,17 +700,17 @@ // Does not take ownership of |framer|. Take ownership of |push_promise_ir|. SpdyPushPromiseFrameIterator( SpdyFramer* framer, - std::unique_ptr<SpdyPushPromiseIR> push_promise_ir); + std::unique_ptr<const SpdyPushPromiseIR> push_promise_ir); ~SpdyPushPromiseFrameIterator() override; private: - SpdyFrameWithHeaderBlockIR* GetIR() const override; + const SpdyFrameWithHeaderBlockIR* GetIR() const override; size_t GetFrameSizeSansBlock() const override; bool SerializeGivenEncoding(const SpdyString& encoding, ZeroCopyOutputBuffer* output) const override; - const std::unique_ptr<SpdyPushPromiseIR> push_promise_ir_; + const std::unique_ptr<const SpdyPushPromiseIR> push_promise_ir_; }; // Converts a SpdyFrameIR into one Spdy frame (a sequence of length 1), and @@ -713,7 +718,7 @@ class SpdyControlFrameIterator : public SpdyFrameSequence { public: SpdyControlFrameIterator(SpdyFramer* framer, - std::unique_ptr<SpdyFrameIR> frame_ir); + std::unique_ptr<const SpdyFrameIR> frame_ir); ~SpdyControlFrameIterator() override; size_t NextFrame(ZeroCopyOutputBuffer* output) override; @@ -722,7 +727,7 @@ private: SpdyFramer* const framer_; - std::unique_ptr<SpdyFrameIR> frame_ir_; + std::unique_ptr<const SpdyFrameIR> frame_ir_; }; private: @@ -979,6 +984,14 @@ // If true, then ProcessInput returns after processing a full frame, // rather than reading all available input. bool process_single_input_frame_ = false; + + // TODO(yasong): Remove overwrite_last_frame_ and is_last_frame_ when we make + // Serialize<FrameType>() functions static and independent of SpdyFramer. And + // pass the last frame info in the arguments. + bool overwrite_last_frame_ = false; + // If the current frame to be serialized is the last frame. Will be valid iff + // overwrite_last_frame_ is true. + bool is_last_frame_ = false; }; } // namespace net
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index 9d518367..ebef1dc 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -3257,8 +3257,6 @@ crbug.com/701445 external/wpt/dom/events/EventListener-invoke-legacy.html [ Timeout Pass ] -crbug.com/718394 virtual/enable_asmjs/http/tests/asmjs/asm-warnings.html [ NeedsRebaseline ] - # When WebAssembly is exposed in V8 (soon), this test has the wrong number of expected Object.getOwnPropertyNames() for global object. crbug.com/681468 fast/forms/suggestion-picker/date-suggestion-picker-appearance-zoom125.html [ Failure Pass ]
diff --git a/third_party/WebKit/LayoutTests/external/wpt/media-capabilities/decodingInfo.html b/third_party/WebKit/LayoutTests/external/wpt/media-capabilities/decodingInfo.html index a0e0d342..85acfe7f 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/media-capabilities/decodingInfo.html +++ b/third_party/WebKit/LayoutTests/external/wpt/media-capabilities/decodingInfo.html
@@ -36,6 +36,131 @@ }, "Test that decodingInfo rejects if the MediaConfiguration does not have a type"); promise_test(t => { + return promise_rejects(t, new TypeError(), navigator.mediaCapabilities.decodingInfo({ + type: 'file', + })); +}, "Test that decodingInfo rejects if the configuration doesn't have an audio or video field"); + +promise_test(t => { + return promise_rejects(t, new TypeError(), navigator.mediaCapabilities.decodingInfo({ + type: 'file', + video: { + contentType: 'video/webm; codecs="vp9"', + width: 800, + height: 600, + bitrate: 3000, + framerate: -1, + }, + })); +}, "Test that decodingInfo rejects if the video configuration has a negative framerate"); + +promise_test(t => { + return promise_rejects(t, new TypeError(), navigator.mediaCapabilities.decodingInfo({ + type: 'file', + video: { + contentType: 'video/webm; codecs="vp9"', + width: 800, + height: 600, + bitrate: 3000, + framerate: 0, + }, + })); +}, "Test that decodingInfo rejects if the video configuration has a framerate set to 0"); + +promise_test(t => { + return promise_rejects(t, new TypeError(), navigator.mediaCapabilities.decodingInfo({ + type: 'file', + video: { + contentType: 'video/webm; codecs="vp9"', + width: 800, + height: 600, + bitrate: 3000, + framerate: Infinity, + }, + })); +}, "Test that decodingInfo rejects if the video configuration has a framerate set to Infinity"); + +promise_test(t => { + return promise_rejects(t, new TypeError(), navigator.mediaCapabilities.decodingInfo({ + type: 'file', + video: { + contentType: 'fgeoa', + width: 800, + height: 600, + bitrate: 3000, + framerate: 24, + }, + })); +}, "Test that decodingInfo rejects if the video configuration contentType doesn't parse"); + +promise_test(t => { + return promise_rejects(t, new TypeError(), navigator.mediaCapabilities.decodingInfo({ + type: 'file', + video: { + contentType: 'audio/fgeoa', + width: 800, + height: 600, + bitrate: 3000, + framerate: 24, + }, + })); +}, "Test that decodingInfo rejects if the video configuration contentType isn't of type video"); + +promise_test(t => { + return promise_rejects(t, new TypeError(), navigator.mediaCapabilities.decodingInfo({ + type: 'file', + video: { + contentType: 'video/webm; codecs="vp9"; foo="bar"', + width: 800, + height: 600, + bitrate: 3000, + framerate: 24, + }, + })); +}, "Test that decodingInfo rejects if the video configuration contentType has more than one parameter"); + +promise_test(t => { + return promise_rejects(t, new TypeError(), navigator.mediaCapabilities.decodingInfo({ + type: 'file', + video: { + contentType: 'video/webm; foo="bar"', + width: 800, + height: 600, + bitrate: 3000, + framerate: 24, + }, + })); +}, "Test that decodingInfo rejects if the video configuration contentType has one parameter that isn't codecs"); + +promise_test(t => { + return promise_rejects(t, new TypeError(), navigator.mediaCapabilities.decodingInfo({ + type: 'file', + audio: { contentType: 'fgeoa' }, + })); +}, "Test that decodingInfo rejects if the audio configuration contenType doesn't parse"); + +promise_test(t => { + return promise_rejects(t, new TypeError(), navigator.mediaCapabilities.decodingInfo({ + type: 'file', + audio: { contentType: 'video/fgeoa' }, + })); +}, "Test that decodingInfo rejects if the audio configuration contentType isn't of type audio"); + +promise_test(t => { + return promise_rejects(t, new TypeError(), navigator.mediaCapabilities.decodingInfo({ + type: 'file', + audio: { contentType: 'audio/webm; codecs="opus"; foo="bar"' }, + })); +}, "Test that decodingInfo rejects if the audio configuration contentType has more than one parameters"); + +promise_test(t => { + return promise_rejects(t, new TypeError(), navigator.mediaCapabilities.decodingInfo({ + type: 'file', + audio: { contentType: 'audio/webm; foo="bar"' }, + })); +}, "Test that decodingInfo rejects if the audio configuration contentType has one parameter that isn't codecs"); + +promise_test(t => { return navigator.mediaCapabilities.decodingInfo({ type: 'file', video: minimalVideoConfiguration,
diff --git a/third_party/WebKit/LayoutTests/http/tests/css/remove-blocking-with-loading-import-expected.html b/third_party/WebKit/LayoutTests/http/tests/css/remove-blocking-with-loading-import-expected.html new file mode 100644 index 0000000..cf3223f --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/css/remove-blocking-with-loading-import-expected.html
@@ -0,0 +1,2 @@ +<!DOCTYPE html> +<p>PASS</p>
diff --git a/third_party/WebKit/LayoutTests/http/tests/css/remove-blocking-with-loading-import.html b/third_party/WebKit/LayoutTests/http/tests/css/remove-blocking-with-loading-import.html new file mode 100644 index 0000000..1b1d9a20 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/css/remove-blocking-with-loading-import.html
@@ -0,0 +1,6 @@ +<!DOCTYPE html> +<script> + setTimeout(() => link.remove(), 0); +</script> +<link id="link" href="data:text/css,@import url(http://127.0.0.1:8000/css/resources/shared.css)" rel="stylesheet"> +<p>PASS</p>
diff --git a/third_party/WebKit/LayoutTests/media_capabilities/encodingInfo.html b/third_party/WebKit/LayoutTests/media_capabilities/encodingInfo.html index cc9ffdb..554e8e2d 100644 --- a/third_party/WebKit/LayoutTests/media_capabilities/encodingInfo.html +++ b/third_party/WebKit/LayoutTests/media_capabilities/encodingInfo.html
@@ -32,8 +32,10 @@ assert_equals(isSupported, result.supported, mimeType + 'supported?'); t.done(); }) - .catch(() => { - assert_unreached('encodingInfo() ' + mimeType); + .catch(e => { + assert_unreached('encodingInfo() failed with ' + e + + ' using mimeType ' + mimeType); + t.done(); }); }); }; @@ -49,12 +51,12 @@ [ 'video/webm;codecs=avc1', 'video/webm;codecs=avc1' ], // 'video/webm' supports audio codec specification, see // http://www.webmproject.org/docs/container/ - [ 'video/webm;codecs=vp8,opus', 'video/webm;codecs=vp8,opus' ], - [ 'video/WEBM;codecs=VP8,OPUS', 'video/WEBM;codecs=VP8,OPUS' ], - [ 'video/webm;codecs=vp9,opus', 'video/webm;codecs=vp9,opus' ], - [ 'video/webm;codecs=vp8,vp9,opus', 'video/webm;codecs=vp8,vp9,opus' ], - [ 'video/webm;codecs=h264,opus', 'video/webm;codecs=h264,opus' ], - [ 'video/webm;codecs=h264,vp9,opus', 'video/webm;codecs=h264,vp9,opus' ], + [ 'video/webm;codecs="vp8,opus"', 'video/webm;codecs="vp8,opus"' ], + [ 'video/WEBM;codecs="VP8,OPUS"', 'video/WEBM;codecs="VP8,OPUS"' ], + [ 'video/webm;codecs="vp9,opus"', 'video/webm;codecs="vp9,opus"' ], + [ 'video/webm;codecs="vp8,vp9,opus"', 'video/webm;codecs="vp8,vp9,opus"' ], + [ 'video/webm;codecs="h264,opus"', 'video/webm;codecs="h264,opus"' ], + [ 'video/webm;codecs="h264,vp9,opus"', 'video/webm;codecs="h264,vp9,opus"' ], // https://matroska.org/technical/specs/notes.html#MIME [ 'video/x-matroska;codecs=vorbis', 'video/x-matroska;codecs=opus' ], [ 'audio/webm', 'audio/webm' ],
diff --git a/third_party/WebKit/LayoutTests/virtual/enable_asmjs/http/tests/asmjs/asm-warnings-expected.txt b/third_party/WebKit/LayoutTests/virtual/enable_asmjs/http/tests/asmjs/asm-warnings-expected.txt deleted file mode 100644 index c9915986..0000000 --- a/third_party/WebKit/LayoutTests/virtual/enable_asmjs/http/tests/asmjs/asm-warnings-expected.txt +++ /dev/null
@@ -1,3 +0,0 @@ -CONSOLE WARNING: line 13: Invalid asm.js: Invalid type annotation - forbidden literal. -CONSOLE WARNING: line 5: Invalid asm.js: Invalid initializer for foreign import - unrecognized annotation. -
diff --git a/third_party/WebKit/Source/core/html/LinkStyle.cpp b/third_party/WebKit/Source/core/html/LinkStyle.cpp index 37ae854..7da5475 100644 --- a/third_party/WebKit/Source/core/html/LinkStyle.cpp +++ b/third_party/WebKit/Source/core/html/LinkStyle.cpp
@@ -402,11 +402,11 @@ } void LinkStyle::OwnerRemoved() { - if (sheet_) - ClearSheet(); - if (StyleSheetIsLoading()) RemovePendingSheet(); + + if (sheet_) + ClearSheet(); } DEFINE_TRACE(LinkStyle) {
diff --git a/third_party/WebKit/Source/devtools/front_end/audits2/Audits2Panel.js b/third_party/WebKit/Source/devtools/front_end/audits2/Audits2Panel.js index c4dfc8a..ff4db4b8 100644 --- a/third_party/WebKit/Source/devtools/front_end/audits2/Audits2Panel.js +++ b/third_party/WebKit/Source/devtools/front_end/audits2/Audits2Panel.js
@@ -441,12 +441,6 @@ * @param {string} message */ _sendProtocolMessage(message) { - var parsedMessage = JSON.parse(message); - if (parsedMessage['method'] === 'Emulation.setVisibleSize' || - parsedMessage['method'] === 'Emulation.setDeviceMetricsOverride') { - this._dispatchProtocolMessage(JSON.stringify({id: parsedMessage['id'], result: {}})); - return; - } this._rawConnection.sendMessage(message); }
diff --git a/third_party/WebKit/Source/devtools/front_end/audits2_worker/Audits2Service.js b/third_party/WebKit/Source/devtools/front_end/audits2_worker/Audits2Service.js index 1b8faf0..65dd354 100644 --- a/third_party/WebKit/Source/devtools/front_end/audits2_worker/Audits2Service.js +++ b/third_party/WebKit/Source/devtools/front_end/audits2_worker/Audits2Service.js
@@ -45,7 +45,7 @@ }); return Promise.resolve() - .then(_ => self.runLighthouseInWorker(this, params.url, {disableDeviceEmulation: true}, params.categoryIDs)) + .then(_ => self.runLighthouseInWorker(this, params.url, {}, params.categoryIDs)) .then(/** @type {!ReportRenderer.ReportJSON} */ result => { // Filter out artifacts except for screenshots in traces to minimize report size. var traces = result.artifacts.traces;
diff --git a/third_party/WebKit/Source/modules/media_capabilities/MediaCapabilities.cpp b/third_party/WebKit/Source/modules/media_capabilities/MediaCapabilities.cpp index 38f780f..c5088ac 100644 --- a/third_party/WebKit/Source/modules/media_capabilities/MediaCapabilities.cpp +++ b/third_party/WebKit/Source/modules/media_capabilities/MediaCapabilities.cpp
@@ -24,6 +24,62 @@ namespace { +constexpr const char* kApplicationMimeTypePrefix = "application/"; +constexpr const char* kAudioMimeTypePrefix = "audio/"; +constexpr const char* kVideoMimeTypePrefix = "video/"; +constexpr const char* kCodecsMimeTypeParam = "codecs"; + +bool IsValidMimeType(const String& content_type, const String& prefix) { + ParsedContentType parsed_content_type(content_type, + ParsedContentType::Mode::kStrict); + if (!parsed_content_type.IsValid()) + return false; + + if (!parsed_content_type.MimeType().StartsWith(prefix) && + !parsed_content_type.MimeType().StartsWith(kApplicationMimeTypePrefix)) { + return false; + } + + if (parsed_content_type.ParameterCount() > 1) + return false; + + if (parsed_content_type.ParameterCount() == 1 && + parsed_content_type.ParameterValueForName(kCodecsMimeTypeParam) + .IsNull()) { + return false; + } + + return true; +} + +bool IsValidMediaConfiguration(const MediaConfiguration& configuration) { + return configuration.hasAudio() || configuration.hasVideo(); +} + +bool IsValidVideoConfiguration(const VideoConfiguration& configuration) { + DCHECK(configuration.hasContentType()); + + if (!IsValidMimeType(configuration.contentType(), kVideoMimeTypePrefix)) + return false; + + DCHECK(configuration.hasFramerate()); + if (!std::isfinite(configuration.framerate()) || + configuration.framerate() <= 0) { + return false; + } + + return true; +} + +bool IsValidAudioConfiguration(const AudioConfiguration& configuration) { + DCHECK(configuration.hasContentType()); + + if (!IsValidMimeType(configuration.contentType(), kAudioMimeTypePrefix)) + return false; + + return true; +} + WebAudioConfiguration ToWebAudioConfiguration( const AudioConfiguration& configuration) { WebAudioConfiguration web_configuration; @@ -32,9 +88,7 @@ DCHECK(configuration.hasContentType()); ParsedContentType parsed_content_type(configuration.contentType(), ParsedContentType::Mode::kStrict); - - // TODO(chcunningham): Throw TypeError for invalid input. - // DCHECK(parsed_content_type.IsValid()); + DCHECK(parsed_content_type.IsValid()); DEFINE_STATIC_LOCAL(const String, codecs, ("codecs")); web_configuration.mime_type = parsed_content_type.MimeType().LowerASCII(); @@ -62,9 +116,7 @@ DCHECK(configuration.hasContentType()); ParsedContentType parsed_content_type(configuration.contentType(), ParsedContentType::Mode::kStrict); - - // TODO(chcunningham): Throw TypeError for invalid input. - // DCHECK(parsed_content_type.IsValid()); + DCHECK(parsed_content_type.IsValid()); DEFINE_STATIC_LOCAL(const String, codecs, ("codecs")); web_configuration.mime_type = parsed_content_type.MimeType().LowerASCII(); @@ -86,9 +138,37 @@ } WebMediaConfiguration ToWebMediaConfiguration( - const MediaConfiguration& configuration) { + const MediaDecodingConfiguration& configuration) { WebMediaConfiguration web_configuration; + // |type| is mandatory. + DCHECK(configuration.hasType()); + if (configuration.type() == "file") + web_configuration.type = MediaConfigurationType::kFile; + else if (configuration.type() == "media-source") + web_configuration.type = MediaConfigurationType::kMediaSource; + else + NOTREACHED(); + + if (configuration.hasAudio()) { + web_configuration.audio_configuration = + ToWebAudioConfiguration(configuration.audio()); + } + + if (configuration.hasVideo()) { + web_configuration.video_configuration = + ToWebVideoConfiguration(configuration.video()); + } + + return web_configuration; +} + +WebMediaConfiguration ToWebMediaConfiguration( + const MediaEncodingConfiguration& configuration) { + WebMediaConfiguration web_configuration; + + // TODO(mcasas): parse and set the type for encoding. + if (configuration.hasAudio()) { web_configuration.audio_configuration = ToWebAudioConfiguration(configuration.audio()); @@ -112,8 +192,29 @@ ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state); ScriptPromise promise = resolver->Promise(); - // |type| is mandatory. - DCHECK(configuration.hasType()); + if (!IsValidMediaConfiguration(configuration)) { + resolver->Reject(V8ThrowException::CreateTypeError( + script_state->GetIsolate(), + "The configuration dictionary has neither |video| nor |audio| " + "specified and needs at least one of them.")); + return promise; + } + + if (configuration.hasVideo() && + !IsValidVideoConfiguration(configuration.video())) { + resolver->Reject(V8ThrowException::CreateTypeError( + script_state->GetIsolate(), + "The video configuration dictionary is not valid.")); + return promise; + } + + if (configuration.hasAudio() && + !IsValidAudioConfiguration(configuration.audio())) { + resolver->Reject(V8ThrowException::CreateTypeError( + script_state->GetIsolate(), + "The audio configuration dictionary is not valid.")); + return promise; + } Platform::Current()->MediaCapabilitiesClient()->DecodingInfo( ToWebMediaConfiguration(configuration), @@ -129,14 +230,30 @@ ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state); ScriptPromise promise = resolver->Promise(); - if (!configuration.hasVideo() && !configuration.hasAudio()) { - resolver->Reject(DOMException::Create( - kSyntaxError, + if (!IsValidMediaConfiguration(configuration)) { + resolver->Reject(V8ThrowException::CreateTypeError( + script_state->GetIsolate(), "The configuration dictionary has neither |video| nor |audio| " "specified and needs at least one of them.")); return promise; } + if (configuration.hasVideo() && + !IsValidVideoConfiguration(configuration.video())) { + resolver->Reject(V8ThrowException::CreateTypeError( + script_state->GetIsolate(), + "The video configuration dictionary is not valid.")); + return promise; + } + + if (configuration.hasAudio() && + !IsValidAudioConfiguration(configuration.audio())) { + resolver->Reject(V8ThrowException::CreateTypeError( + script_state->GetIsolate(), + "The audio configuration dictionary is not valid.")); + return promise; + } + std::unique_ptr<WebMediaRecorderHandler> handler = Platform::Current()->CreateMediaRecorderHandler(); if (!handler) {
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioNode.h b/third_party/WebKit/Source/modules/webaudio/AudioNode.h index f1079d6..7deea47 100644 --- a/third_party/WebKit/Source/modules/webaudio/AudioNode.h +++ b/third_party/WebKit/Source/modules/webaudio/AudioNode.h
@@ -106,8 +106,8 @@ // Do not release resources used by an audio rendering thread in dispose(). virtual void Dispose(); - // node() returns a valid object until dispose() is called. This returns - // nullptr after dispose(). We must not call node() in an audio rendering + // GetNode() returns a valid object until dispose() is called. This returns + // nullptr after dispose(). We must not call GetNode() in an audio rendering // thread. AudioNode* GetNode() const; // context() returns a valid object until the BaseAudioContext dies, and @@ -259,8 +259,8 @@ NodeType node_type_; // The owner AudioNode. This untraced member is safe because dispose() is - // called before the AudioNode death, and it clears m_node. Do not access - // m_node directly, use node() instead. + // called before the AudioNode death, and it clears |node_|. Do not access + // |node_| directly, use GetNode() instead. // See http://crbug.com/404527 for the detail. UntracedMember<AudioNode> node_;
diff --git a/third_party/WebKit/Source/platform/BUILD.gn b/third_party/WebKit/Source/platform/BUILD.gn index 59f8d8d..82b6562 100644 --- a/third_party/WebKit/Source/platform/BUILD.gn +++ b/third_party/WebKit/Source/platform/BUILD.gn
@@ -1284,6 +1284,8 @@ "scheduler/base/time_converter.h", "scheduler/base/time_domain.cc", "scheduler/base/time_domain.h", + "scheduler/base/trace_helper.cc", + "scheduler/base/trace_helper.h", "scheduler/base/virtual_time_domain.cc", "scheduler/base/virtual_time_domain.h", "scheduler/base/work_queue.cc",
diff --git a/third_party/WebKit/Source/platform/scheduler/base/task_queue.h b/third_party/WebKit/Source/platform/scheduler/base/task_queue.h index 64c39a6..8ac280a 100644 --- a/third_party/WebKit/Source/platform/scheduler/base/task_queue.h +++ b/third_party/WebKit/Source/platform/scheduler/base/task_queue.h
@@ -37,6 +37,9 @@ // Can be called on any thread // All methods but SetObserver, SetTimeDomain and GetTimeDomain can be // called on |queue|. + // + // TODO(altimin): Make it base::Optional<base::TimeTicks> to tell + // observer about cancellations. virtual void OnQueueNextWakeUpChanged(TaskQueue* queue, base::TimeTicks next_wake_up) = 0; }; @@ -162,7 +165,7 @@ // Returns true if the queue has work that's ready to execute now. // NOTE: this must be called on the thread this TaskQueue was created by. - virtual bool HasPendingImmediateWork() const = 0; + virtual bool HasTaskToRunImmediately() const = 0; // Returns requested run time of next scheduled wake-up for a delayed task // which is not ready to run. If there are no such tasks or the queue is
diff --git a/third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.cc b/third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.cc index 5e5d7b74..2ead685 100644 --- a/third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.cc +++ b/third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.cc
@@ -402,7 +402,7 @@ return task_count; } -bool TaskQueueImpl::HasPendingImmediateWork() const { +bool TaskQueueImpl::HasTaskToRunImmediately() const { // Any work queue tasks count as immediate work. if (!main_thread_only().delayed_work_queue->Empty() || !main_thread_only().immediate_work_queue->Empty()) { @@ -821,8 +821,11 @@ return; if (enable) { - if (HasPendingImmediateWork()) - NotifyWakeUpChangedOnMainThread(base::TimeTicks()); + if (HasPendingImmediateWork() && main_thread_only().observer) { + // Delayed work notification will be issued via time domain. + main_thread_only().observer->OnQueueNextWakeUpChanged(this, + base::TimeTicks()); + } ScheduleDelayedWorkInTimeDomain(main_thread_only().time_domain->Now()); @@ -899,14 +902,33 @@ main_thread_only().time_domain->ScheduleDelayedWork( this, main_thread_only().delayed_incoming_queue.top().delayed_wake_up(), now); - - NotifyWakeUpChangedOnMainThread( - main_thread_only().delayed_incoming_queue.top().delayed_run_time); } -void TaskQueueImpl::NotifyWakeUpChangedOnMainThread(base::TimeTicks wake_up) { - if (main_thread_only().observer) - main_thread_only().observer->OnQueueNextWakeUpChanged(this, wake_up); +void TaskQueueImpl::SetScheduledTimeDomainWakeUp( + base::Optional<base::TimeTicks> scheduled_time_domain_wake_up) { + main_thread_only().scheduled_time_domain_wake_up = + scheduled_time_domain_wake_up; + + // If queue has immediate work an appropriate notification has already + // been issued. + if (!scheduled_time_domain_wake_up || !main_thread_only().observer || + HasPendingImmediateWork()) + return; + + main_thread_only().observer->OnQueueNextWakeUpChanged( + this, scheduled_time_domain_wake_up.value()); +} + +bool TaskQueueImpl::HasPendingImmediateWork() { + // Any work queue tasks count as immediate work. + if (!main_thread_only().delayed_work_queue->Empty() || + !main_thread_only().immediate_work_queue->Empty()) { + return true; + } + + // Finally tasks on |immediate_incoming_queue| count as immediate work. + base::AutoLock lock(immediate_incoming_queue_lock_); + return !immediate_incoming_queue().empty(); } } // namespace internal
diff --git a/third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.h b/third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.h index dc36b1c..fc20922a 100644 --- a/third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.h +++ b/third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.h
@@ -142,7 +142,7 @@ bool IsQueueEnabled() const override; bool IsEmpty() const override; size_t GetNumberOfPendingTasks() const override; - bool HasPendingImmediateWork() const override; + bool HasTaskToRunImmediately() const override; base::Optional<base::TimeTicks> GetNextScheduledWakeUp() override; void SetQueuePriority(QueuePriority priority) override; QueuePriority GetQueuePriority() const override; @@ -177,6 +177,18 @@ void NotifyWillProcessTask(const base::PendingTask& pending_task); void NotifyDidProcessTask(const base::PendingTask& pending_task); + // Called by TimeDomain when the wake-up for this queue has changed. + // There is only one wake-up, new wake-up cancels any previous wake-ups. + // If |scheduled_time_domain_wake_up| is base::nullopt then the wake-up + // has been cancelled. + // Must be called from the main thread. + void SetScheduledTimeDomainWakeUp( + base::Optional<base::TimeTicks> scheduled_time_domain_wake_up); + + // Check for available tasks in immediate work queues. + // Used to check if we need to generate notifications about delayed work. + bool HasPendingImmediateWork(); + WorkQueue* delayed_work_queue() { return main_thread_only().delayed_work_queue.get(); } @@ -202,16 +214,10 @@ // any. Must be called from the main thread. base::Optional<DelayedWakeUp> WakeUpForDelayedWork(LazyNow* lazy_now); - base::TimeTicks scheduled_time_domain_wake_up() const { + base::Optional<base::TimeTicks> scheduled_time_domain_wake_up() const { return main_thread_only().scheduled_time_domain_wake_up; } - void set_scheduled_time_domain_wake_up( - base::TimeTicks scheduled_time_domain_wake_up) { - main_thread_only().scheduled_time_domain_wake_up = - scheduled_time_domain_wake_up; - } - HeapHandle heap_handle() const { return main_thread_only().heap_handle; } void set_heap_handle(HeapHandle heap_handle) { @@ -285,7 +291,7 @@ int voter_refcount; base::trace_event::BlameContext* blame_context; // Not owned. EnqueueOrder current_fence; - base::TimeTicks scheduled_time_domain_wake_up; + base::Optional<base::TimeTicks> scheduled_time_domain_wake_up; }; ~TaskQueueImpl() override; @@ -347,8 +353,6 @@ // Schedules delayed work on time domain and calls the observer. void ScheduleDelayedWorkInTimeDomain(base::TimeTicks now); - void NotifyWakeUpChangedOnMainThread(base::TimeTicks wake_up); - const base::PlatformThreadId thread_id_; mutable base::Lock any_thread_lock_;
diff --git a/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager.cc b/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager.cc index c240f08..97ad1c53 100644 --- a/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager.cc +++ b/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager.cc
@@ -675,7 +675,7 @@ DCHECK(main_thread_checker_.CalledOnValidThread()); DCHECK(queue->IsQueueEnabled()); // Only schedule DoWork if there's something to do. - if (queue->HasPendingImmediateWork() && !queue->BlockedByFence()) + if (queue->HasTaskToRunImmediately() && !queue->BlockedByFence()) MaybeScheduleImmediateWork(FROM_HERE); }
diff --git a/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager_unittest.cc b/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager_unittest.cc index 68d0e53..0e1bec150 100644 --- a/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager_unittest.cc +++ b/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager_unittest.cc
@@ -359,9 +359,9 @@ Initialize(1u); std::vector<EnqueueOrder> run_order; - EXPECT_FALSE(runners_[0]->HasPendingImmediateWork()); + EXPECT_FALSE(runners_[0]->HasTaskToRunImmediately()); runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); - EXPECT_TRUE(runners_[0]->HasPendingImmediateWork()); + EXPECT_TRUE(runners_[0]->HasTaskToRunImmediately()); // Move the task into the |immediate_work_queue|. EXPECT_TRUE(runners_[0]->immediate_work_queue()->Empty()); @@ -370,12 +370,12 @@ voter->SetQueueEnabled(false); test_task_runner_->RunUntilIdle(); EXPECT_FALSE(runners_[0]->immediate_work_queue()->Empty()); - EXPECT_TRUE(runners_[0]->HasPendingImmediateWork()); + EXPECT_TRUE(runners_[0]->HasTaskToRunImmediately()); // Run the task, making the queue empty. voter->SetQueueEnabled(true); test_task_runner_->RunUntilIdle(); - EXPECT_FALSE(runners_[0]->HasPendingImmediateWork()); + EXPECT_FALSE(runners_[0]->HasTaskToRunImmediately()); } TEST_F(TaskQueueManagerTest, HasPendingImmediateWork_DelayedTask) { @@ -385,18 +385,18 @@ base::TimeDelta delay(base::TimeDelta::FromMilliseconds(10)); runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order), delay); - EXPECT_FALSE(runners_[0]->HasPendingImmediateWork()); + EXPECT_FALSE(runners_[0]->HasTaskToRunImmediately()); now_src_->Advance(delay); - EXPECT_TRUE(runners_[0]->HasPendingImmediateWork()); + EXPECT_TRUE(runners_[0]->HasTaskToRunImmediately()); // Move the task into the |delayed_work_queue|. WakeUpReadyDelayedQueues(LazyNow(now_src_.get())); EXPECT_FALSE(runners_[0]->delayed_work_queue()->Empty()); - EXPECT_TRUE(runners_[0]->HasPendingImmediateWork()); + EXPECT_TRUE(runners_[0]->HasTaskToRunImmediately()); // Run the task, making the queue empty. test_task_runner_->RunUntilIdle(); - EXPECT_FALSE(runners_[0]->HasPendingImmediateWork()); + EXPECT_FALSE(runners_[0]->HasTaskToRunImmediately()); } TEST_F(TaskQueueManagerTest, DelayedTaskPosting) { @@ -407,7 +407,7 @@ runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order), delay); EXPECT_EQ(delay, test_task_runner_->DelayToNextTaskTime()); - EXPECT_FALSE(runners_[0]->HasPendingImmediateWork()); + EXPECT_FALSE(runners_[0]->HasTaskToRunImmediately()); EXPECT_TRUE(run_order.empty()); // The task doesn't run before the delay has completed. @@ -417,7 +417,7 @@ // After the delay has completed, the task runs normally. test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(1)); EXPECT_THAT(run_order, ElementsAre(1)); - EXPECT_FALSE(runners_[0]->HasPendingImmediateWork()); + EXPECT_FALSE(runners_[0]->HasTaskToRunImmediately()); } bool MessageLoopTaskCounter(size_t* count) { @@ -551,7 +551,7 @@ EXPECT_FALSE(test_task_runner_->HasPendingTasks()); // However polling still works. - EXPECT_TRUE(runners_[0]->HasPendingImmediateWork()); + EXPECT_TRUE(runners_[0]->HasTaskToRunImmediately()); // After removing the fence the task runs normally. runners_[0]->RemoveFence(); @@ -1134,34 +1134,34 @@ TEST_F(TaskQueueManagerTest, HasPendingImmediateWork) { Initialize(1u); - EXPECT_FALSE(runners_[0]->HasPendingImmediateWork()); + EXPECT_FALSE(runners_[0]->HasTaskToRunImmediately()); runners_[0]->PostTask(FROM_HERE, base::Bind(NullTask)); - EXPECT_TRUE(runners_[0]->HasPendingImmediateWork()); + EXPECT_TRUE(runners_[0]->HasTaskToRunImmediately()); test_task_runner_->RunUntilIdle(); - EXPECT_FALSE(runners_[0]->HasPendingImmediateWork()); + EXPECT_FALSE(runners_[0]->HasTaskToRunImmediately()); } TEST_F(TaskQueueManagerTest, HasPendingImmediateWork_DelayedTasks) { Initialize(1u); - EXPECT_FALSE(runners_[0]->HasPendingImmediateWork()); + EXPECT_FALSE(runners_[0]->HasTaskToRunImmediately()); runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(NullTask), base::TimeDelta::FromMilliseconds(12)); - EXPECT_FALSE(runners_[0]->HasPendingImmediateWork()); + EXPECT_FALSE(runners_[0]->HasTaskToRunImmediately()); // Move time forwards until just before the delayed task should run. now_src_->Advance(base::TimeDelta::FromMilliseconds(10)); WakeUpReadyDelayedQueues(LazyNow(now_src_.get())); - EXPECT_FALSE(runners_[0]->HasPendingImmediateWork()); + EXPECT_FALSE(runners_[0]->HasTaskToRunImmediately()); // Force the delayed task onto the work queue. now_src_->Advance(base::TimeDelta::FromMilliseconds(2)); WakeUpReadyDelayedQueues(LazyNow(now_src_.get())); - EXPECT_TRUE(runners_[0]->HasPendingImmediateWork()); + EXPECT_TRUE(runners_[0]->HasTaskToRunImmediately()); test_task_runner_->RunUntilIdle(); - EXPECT_FALSE(runners_[0]->HasPendingImmediateWork()); + EXPECT_FALSE(runners_[0]->HasTaskToRunImmediately()); } void ExpensiveTestTask(int value, @@ -1748,12 +1748,14 @@ std::unique_ptr<TaskQueue::QueueEnabledVoter> voter = runners_[0]->CreateQueueEnabledVoter(); voter->SetQueueEnabled(false); + Mock::VerifyAndClearExpectations(&observer); // When a queue has been enabled, we may get a notification if the // TimeDomain's next scheduled wake-up has changed. EXPECT_CALL(observer, OnQueueNextWakeUpChanged(runners_[0].get(), start_time + delay1s)); voter->SetQueueEnabled(true); + Mock::VerifyAndClearExpectations(&observer); // Tidy up. runners_[0]->UnregisterTaskQueue(); @@ -1813,6 +1815,42 @@ runners_[1]->UnregisterTaskQueue(); } +TEST_F(TaskQueueManagerTest, TaskQueueObserver_DelayedWorkWhichCanRunNow) { + // This test checks that when delayed work becomes available + // the notification still fires. This usually happens when time advances + // and task becomes available in the middle of the scheduling code. + // For this test we rely on the fact that notification dispatching code + // is the same in all conditions and just change a time domain to + // trigger notification. + + Initialize(1u); + + base::TimeDelta delay1s(base::TimeDelta::FromSeconds(1)); + base::TimeDelta delay10s(base::TimeDelta::FromSeconds(10)); + + MockTaskQueueObserver observer; + runners_[0]->SetObserver(&observer); + + // We should get a notification when a delayed task is posted on an empty + // queue. + EXPECT_CALL(observer, OnQueueNextWakeUpChanged(_, _)); + runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&NopTask), delay1s); + Mock::VerifyAndClearExpectations(&observer); + + std::unique_ptr<TimeDomain> mock_time_domain = + base::MakeUnique<RealTimeDomain>(); + manager_->RegisterTimeDomain(mock_time_domain.get()); + + now_src_->Advance(delay10s); + + EXPECT_CALL(observer, OnQueueNextWakeUpChanged(_, _)); + runners_[0]->SetTimeDomain(mock_time_domain.get()); + Mock::VerifyAndClearExpectations(&observer); + + // Tidy up. + runners_[0]->UnregisterTaskQueue(); +} + class CancelableTask { public: explicit CancelableTask(base::TickClock* clock)
diff --git a/third_party/WebKit/Source/platform/scheduler/base/time_domain.cc b/third_party/WebKit/Source/platform/scheduler/base/time_domain.cc index bdf885b..66b7bae 100644 --- a/third_party/WebKit/Source/platform/scheduler/base/time_domain.cc +++ b/third_party/WebKit/Source/platform/scheduler/base/time_domain.cc
@@ -41,7 +41,7 @@ // We only want to store a single wake-up per queue, so we need to remove any // previously registered wake up for |queue|. if (queue->heap_handle().IsValid()) { - DCHECK_NE(queue->scheduled_time_domain_wake_up(), base::TimeTicks()); + DCHECK(queue->scheduled_time_domain_wake_up()); // O(log n) delayed_wake_up_queue_.ChangeKey(queue->heap_handle(), {wake_up, queue}); @@ -50,7 +50,7 @@ delayed_wake_up_queue_.insert({wake_up, queue}); } - queue->set_scheduled_time_domain_wake_up(wake_up.time); + queue->SetScheduledTimeDomainWakeUp(wake_up.time); // If |queue| is the first wake-up then request the wake-up. if (delayed_wake_up_queue_.Min().queue == queue) @@ -65,7 +65,7 @@ if (!queue->heap_handle().IsValid()) return; - DCHECK_NE(queue->scheduled_time_domain_wake_up(), base::TimeTicks()); + DCHECK(queue->scheduled_time_domain_wake_up()); DCHECK(!delayed_wake_up_queue_.empty()); base::TimeTicks prev_first_wake_up = delayed_wake_up_queue_.Min().wake_up.time; @@ -95,11 +95,11 @@ if (next_wake_up) { // O(log n) delayed_wake_up_queue_.ReplaceMin({*next_wake_up, queue}); - queue->set_scheduled_time_domain_wake_up(next_wake_up->time); + queue->SetScheduledTimeDomainWakeUp(next_wake_up->time); } else { // O(log n) delayed_wake_up_queue_.Pop(); - DCHECK_EQ(queue->scheduled_time_domain_wake_up(), base::TimeTicks()); + DCHECK(!queue->scheduled_time_domain_wake_up()); } } }
diff --git a/third_party/WebKit/Source/platform/scheduler/base/time_domain.h b/third_party/WebKit/Source/platform/scheduler/base/time_domain.h index 6f1abcf..19cec2d 100644 --- a/third_party/WebKit/Source/platform/scheduler/base/time_domain.h +++ b/third_party/WebKit/Source/platform/scheduler/base/time_domain.h
@@ -135,8 +135,8 @@ DCHECK(queue->heap_handle().IsValid()); queue->set_heap_handle(HeapHandle()); - DCHECK_NE(queue->scheduled_time_domain_wake_up(), base::TimeTicks()); - queue->set_scheduled_time_domain_wake_up(base::TimeTicks()); + DCHECK(queue->scheduled_time_domain_wake_up()); + queue->SetScheduledTimeDomainWakeUp(base::nullopt); } };
diff --git a/third_party/WebKit/Source/platform/scheduler/base/trace_helper.cc b/third_party/WebKit/Source/platform/scheduler/base/trace_helper.cc new file mode 100644 index 0000000..5fbb9f7 --- /dev/null +++ b/third_party/WebKit/Source/platform/scheduler/base/trace_helper.cc
@@ -0,0 +1,22 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "platform/scheduler/base/trace_helper.h" + +#include "base/format_macros.h" +#include "base/strings/stringprintf.h" + +namespace blink { +namespace scheduler { +namespace trace_helper { + +std::string PointerToString(const void* pointer) { + return base::StringPrintf( + "0x%" PRIx64, + static_cast<uint64_t>(reinterpret_cast<uintptr_t>(pointer))); +} + +} // namespace trace_helper +} // namespace scheduler +} // namespace blink
diff --git a/third_party/WebKit/Source/platform/scheduler/base/trace_helper.h b/third_party/WebKit/Source/platform/scheduler/base/trace_helper.h new file mode 100644 index 0000000..8f8fd26 --- /dev/null +++ b/third_party/WebKit/Source/platform/scheduler/base/trace_helper.h
@@ -0,0 +1,20 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_BASE_TRACE_HELPER_H +#define THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_BASE_TRACE_HELPER_H + +#include <string> + +namespace blink { +namespace scheduler { + +namespace trace_helper { +std::string PointerToString(const void* pointer); +}; + +} // namespace scheduler +} // namespace blink + +#endif // THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_BASE_TRACE_HELPER_H
diff --git a/third_party/WebKit/Source/platform/scheduler/child/idle_helper.cc b/third_party/WebKit/Source/platform/scheduler/child/idle_helper.cc index 0ce84fa..b61f373 100644 --- a/third_party/WebKit/Source/platform/scheduler/child/idle_helper.cc +++ b/third_party/WebKit/Source/platform/scheduler/child/idle_helper.cc
@@ -96,7 +96,7 @@ if (long_idle_period_duration >= base::TimeDelta::FromMilliseconds(kMinimumIdlePeriodDurationMillis)) { *next_long_idle_period_delay_out = long_idle_period_duration; - if (!idle_queue_->HasPendingImmediateWork()) { + if (!idle_queue_->HasTaskToRunImmediately()) { return IdlePeriodState::IN_LONG_IDLE_PERIOD_PAUSED; } else if (long_idle_period_duration == max_long_idle_period_duration) { return IdlePeriodState::IN_LONG_IDLE_PERIOD_WITH_MAX_DEADLINE; @@ -248,7 +248,7 @@ TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "UpdateLongIdlePeriodStateAfterIdleTask"); - if (!idle_queue_->HasPendingImmediateWork()) { + if (!idle_queue_->HasTaskToRunImmediately()) { // If there are no more idle tasks then pause long idle period ticks until a // new idle task is posted. state_.UpdateState(IdlePeriodState::IN_LONG_IDLE_PERIOD_PAUSED,
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/cpu_time_budget_pool.cc b/third_party/WebKit/Source/platform/scheduler/renderer/cpu_time_budget_pool.cc index 96eb942..dc86aa7 100644 --- a/third_party/WebKit/Source/platform/scheduler/renderer/cpu_time_budget_pool.cc +++ b/third_party/WebKit/Source/platform/scheduler/renderer/cpu_time_budget_pool.cc
@@ -6,26 +6,15 @@ #include <cstdint> -#include "base/format_macros.h" #include "base/logging.h" #include "base/memory/ptr_util.h" #include "base/optional.h" -#include "base/strings/stringprintf.h" +#include "platform/scheduler/base/trace_helper.h" #include "platform/scheduler/renderer/task_queue_throttler.h" namespace blink { namespace scheduler { -namespace { - -std::string PointerToId(void* pointer) { - return base::StringPrintf( - "0x%" PRIx64, - static_cast<uint64_t>(reinterpret_cast<uintptr_t>(pointer))); -} - -} // namespace - CPUTimeBudgetPool::CPUTimeBudgetPool( const char* name, BudgetPoolController* budget_pool_controller, @@ -153,7 +142,7 @@ state->BeginArray("task_queues"); for (TaskQueue* queue : associated_task_queues_) { - state->AppendString(PointerToId(queue)); + state->AppendString(trace_helper::PointerToString(queue)); } state->EndArray();
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.cc b/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.cc index c7e246c..168aca3 100644 --- a/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.cc +++ b/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.cc
@@ -9,7 +9,6 @@ #include "base/logging.h" #include "base/memory/ptr_util.h" #include "base/metrics/histogram_macros.h" -#include "base/strings/stringprintf.h" #include "base/threading/thread_task_runner_handle.h" #include "base/trace_event/trace_event.h" #include "base/trace_event/trace_event_argument.h" @@ -19,6 +18,7 @@ #include "platform/scheduler/base/task_queue_impl.h" #include "platform/scheduler/base/task_queue_selector.h" #include "platform/scheduler/base/time_converter.h" +#include "platform/scheduler/base/trace_helper.h" #include "platform/scheduler/base/virtual_time_domain.h" #include "platform/scheduler/child/scheduler_tqm_delegate.h" #include "platform/scheduler/renderer/auto_advancing_virtual_time_domain.h" @@ -77,12 +77,6 @@ "RendererScheduler.BackgroundRendererLoad", load_percentage); } -std::string PointerToId(void* pointer) { - return base::StringPrintf( - "0x%" PRIx64, - static_cast<uint64_t>(reinterpret_cast<uintptr_t>(pointer))); -} - } // namespace RendererSchedulerImpl::RendererSchedulerImpl( @@ -870,7 +864,7 @@ case UseCase::MAIN_THREAD_GESTURE: case UseCase::MAIN_THREAD_CUSTOM_INPUT_HANDLING: case UseCase::SYNCHRONIZED_GESTURE: - return compositor_task_queue_->HasPendingImmediateWork() || + return compositor_task_queue_->HasTaskToRunImmediately() || GetMainThreadOnly().touchstart_expected_soon; case UseCase::TOUCHSTART: @@ -1517,7 +1511,8 @@ state->BeginDictionary("web_view_schedulers"); for (WebViewSchedulerImpl* web_view_scheduler : GetMainThreadOnly().web_view_schedulers) { - state->BeginDictionaryWithCopiedName(PointerToId(web_view_scheduler)); + state->BeginDictionaryWithCopiedName( + trace_helper::PointerToString(web_view_scheduler)); web_view_scheduler->AsValueInto(state.get()); state->EndDictionary(); }
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/task_queue_throttler.cc b/third_party/WebKit/Source/platform/scheduler/renderer/task_queue_throttler.cc index 1c3cd00b..dd0bacca 100644 --- a/third_party/WebKit/Source/platform/scheduler/renderer/task_queue_throttler.cc +++ b/third_party/WebKit/Source/platform/scheduler/renderer/task_queue_throttler.cc
@@ -6,13 +6,12 @@ #include <cstdint> -#include "base/format_macros.h" #include "base/logging.h" #include "base/memory/ptr_util.h" #include "base/optional.h" -#include "base/strings/stringprintf.h" #include "platform/WebFrameScheduler.h" #include "platform/scheduler/base/real_time_domain.h" +#include "platform/scheduler/base/trace_helper.h" #include "platform/scheduler/child/scheduler_tqm_delegate.h" #include "platform/scheduler/renderer/budget_pool.h" #include "platform/scheduler/renderer/renderer_scheduler_impl.h" @@ -26,7 +25,7 @@ base::Optional<base::TimeTicks> NextTaskRunTime(LazyNow* lazy_now, TaskQueue* queue) { - if (queue->HasPendingImmediateWork()) + if (queue->HasTaskToRunImmediately()) return lazy_now->Now(); return queue->GetNextScheduledWakeUp(); } @@ -64,12 +63,6 @@ return std::max(a.value(), b.value()); } -std::string PointerToId(void* pointer) { - return base::StringPrintf( - "0x%" PRIx64, - static_cast<uint64_t>(reinterpret_cast<uintptr_t>(pointer))); -} - } // namespace TaskQueueThrottler::TaskQueueThrottler( @@ -441,7 +434,8 @@ state->BeginDictionary("queue_details"); for (const auto& map_entry : queue_details_) { - state->BeginDictionaryWithCopiedName(PointerToId(map_entry.first)); + state->BeginDictionaryWithCopiedName( + trace_helper::PointerToString(map_entry.first)); state->SetInteger("throttling_ref_count", map_entry.second.throttling_ref_count);
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/wake_up_budget_pool.cc b/third_party/WebKit/Source/platform/scheduler/renderer/wake_up_budget_pool.cc index f58039a..9d9274c 100644 --- a/third_party/WebKit/Source/platform/scheduler/renderer/wake_up_budget_pool.cc +++ b/third_party/WebKit/Source/platform/scheduler/renderer/wake_up_budget_pool.cc
@@ -6,23 +6,12 @@ #include <cstdint> -#include "base/format_macros.h" -#include "base/strings/stringprintf.h" +#include "platform/scheduler/base/trace_helper.h" #include "platform/scheduler/renderer/task_queue_throttler.h" namespace blink { namespace scheduler { -namespace { - -std::string PointerToId(void* pointer) { - return base::StringPrintf( - "0x%" PRIx64, - static_cast<uint64_t>(reinterpret_cast<uintptr_t>(pointer))); -} - -} // namespace - WakeUpBudgetPool::WakeUpBudgetPool(const char* name, BudgetPoolController* budget_pool_controller, base::TimeTicks now) @@ -109,7 +98,7 @@ state->BeginArray("task_queues"); for (TaskQueue* queue : associated_task_queues_) { - state->AppendString(PointerToId(queue)); + state->AppendString(trace_helper::PointerToString(queue)); } state->EndArray();
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl.cc b/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl.cc index 70e18c2..3dce41cf 100644 --- a/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl.cc +++ b/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl.cc
@@ -4,10 +4,10 @@ #include "platform/scheduler/renderer/web_frame_scheduler_impl.h" -#include "base/strings/stringprintf.h" #include "base/trace_event/blame_context.h" #include "platform/RuntimeEnabledFeatures.h" #include "platform/scheduler/base/real_time_domain.h" +#include "platform/scheduler/base/trace_helper.h" #include "platform/scheduler/base/virtual_time_domain.h" #include "platform/scheduler/child/web_task_runner_impl.h" #include "platform/scheduler/renderer/auto_advancing_virtual_time_domain.h" @@ -19,15 +19,6 @@ namespace blink { namespace scheduler { -namespace { - -std::string PointerToId(void* pointer) { - return base::StringPrintf( - "0x%" PRIx64, - static_cast<uint64_t>(reinterpret_cast<uintptr_t>(pointer))); -} - -} // namespace WebFrameSchedulerImpl::ActiveConnectionHandleImpl::ActiveConnectionHandleImpl( WebFrameSchedulerImpl* frame_scheduler) @@ -238,22 +229,26 @@ state->SetBoolean("cross_origin", cross_origin_); if (loading_task_queue_) { state->SetString("loading_task_queue", - PointerToId(loading_task_queue_.get())); + trace_helper::PointerToString(loading_task_queue_.get())); } if (timer_task_queue_) - state->SetString("timer_task_queue", PointerToId(timer_task_queue_.get())); + state->SetString("timer_task_queue", + trace_helper::PointerToString(timer_task_queue_.get())); if (unthrottled_task_queue_) { - state->SetString("unthrottled_task_queue", - PointerToId(unthrottled_task_queue_.get())); + state->SetString( + "unthrottled_task_queue", + trace_helper::PointerToString(unthrottled_task_queue_.get())); } if (suspendable_task_queue_) { - state->SetString("suspendable_task_queue", - PointerToId(suspendable_task_queue_.get())); + state->SetString( + "suspendable_task_queue", + trace_helper::PointerToString(suspendable_task_queue_.get())); } if (blame_context_) { state->BeginDictionary("blame_context"); - state->SetString( - "id_ref", PointerToId(reinterpret_cast<void*>(blame_context_->id()))); + state->SetString("id_ref", + trace_helper::PointerToString( + reinterpret_cast<void*>(blame_context_->id()))); state->SetString("scope", blame_context_->scope()); state->EndDictionary(); }
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/web_view_scheduler_impl.cc b/third_party/WebKit/Source/platform/scheduler/renderer/web_view_scheduler_impl.cc index fefee3e..f6b9706 100644 --- a/third_party/WebKit/Source/platform/scheduler/renderer/web_view_scheduler_impl.cc +++ b/third_party/WebKit/Source/platform/scheduler/renderer/web_view_scheduler_impl.cc
@@ -8,6 +8,7 @@ #include "base/strings/stringprintf.h" #include "platform/RuntimeEnabledFeatures.h" #include "platform/WebFrameScheduler.h" +#include "platform/scheduler/base/trace_helper.h" #include "platform/scheduler/base/virtual_time_domain.h" #include "platform/scheduler/child/scheduler_tqm_delegate.h" #include "platform/scheduler/renderer/auto_advancing_virtual_time_domain.h" @@ -84,12 +85,6 @@ return base::TimeDelta::FromSecondsD(initial_budget); } -std::string PointerToId(void* pointer) { - return base::StringPrintf( - "0x%" PRIx64, - static_cast<uint64_t>(reinterpret_cast<uintptr_t>(pointer))); -} - } // namespace WebViewSchedulerImpl::WebViewSchedulerImpl( @@ -328,7 +323,8 @@ state->BeginDictionary("frame_schedulers"); for (WebFrameSchedulerImpl* frame_scheduler : frame_schedulers_) { - state->BeginDictionaryWithCopiedName(PointerToId(frame_scheduler)); + state->BeginDictionaryWithCopiedName( + trace_helper::PointerToString(frame_scheduler)); frame_scheduler->AsValueInto(state); state->EndDictionary(); }
diff --git a/tools/binary_size/README.md b/tools/binary_size/README.md index 42d7372..19bf7f3 100644 --- a/tools/binary_size/README.md +++ b/tools/binary_size/README.md
@@ -3,11 +3,11 @@ These currently focus on Android and Linux platforms. However, some great tools for Windows exist and are documented here: -https://www.chromium.org/developers/windows-binary-sizes + * https://www.chromium.org/developers/windows-binary-sizes There is also a dedicated mailing-list for binary size discussions: -https://groups.google.com/a/chromium.org/forum/#!forum/binary-size + * https://groups.google.com/a/chromium.org/forum/#!forum/binary-size [TOC] @@ -19,10 +19,8 @@ ### How it Works 1. Builds multiple revisions using release GN args. - - * Default is to build just two revisions (before & after commit) - * Rather than building, can fetch build artifacts from perf bots (`--cloud`) - + * Default is to build just two revisions (before & after commit) + * Rather than building, can fetch build artifacts from perf bots (`--cloud`) 1. Measures all outputs using `resource_size.py` and `supersize`. 1. Saves & displays a breakdown of the difference in binary sizes. @@ -31,11 +29,11 @@ # Build and diff HEAD^ and HEAD. tools/binary_size/diagnose_bloat.py HEAD -v - # Diff OTHERREV and REV using downloaded build artifacts. - tools/binary_size/diagnose_bloat.py REV --reference-rev OTHERREV --cloud -v + # Diff BEFORE_REV and AFTER_REV using build artifacts downloaded from perf bots. + tools/binary_size/diagnose_bloat.py AFTER_REV --reference-rev BEFORE_REV --cloud -v - # Build and diff all contiguous revs in range OTHERREV..REV for src/v8. - tools/binary_size/diagnose_bloat.py REV --reference-rev OTHERREV --subrepo v8 --all -v + # Build and diff all contiguous revs in range BEFORE_REV..AFTER_REV for src/v8. + tools/binary_size/diagnose_bloat.py AFTER_REV --reference-rev BEFORE_REV --subrepo v8 --all -v # Display detailed usage info (there are many options). tools/binary_size/diagnose_bloat.py -h @@ -46,7 +44,11 @@ Supports Android and Linux (although Linux [has issues](https://bugs.chromium.org/p/chromium/issues/detail?id=717550)). -`.size` files are archived on perf bots as well as on official builders. +`.size` files are archived on perf builders so that regressions can be quickly +analyzed (via `diagnose_bloat.py --cloud`). + +`.size` files are archived on official builders so that symbols can be diff'ed +between milestones. ### Technical Details @@ -62,52 +64,50 @@ #### How are Symbols Collected? 1. Symbol list is Extracted from linker `.map` file. - - * Map files contain some unique pieces of information, such as - `** merge strings` entries, and the odd unnamed symbol (which map at least - lists a `.o` path). - + * Map files contain some unique pieces of information, such as + `** merge strings` entries, and the odd unnamed symbol (which map at least + lists a `.o` path). 1. `.o` files are mapped to `.cc` files by parsing `.ninja` files. - - * This means that `.h` files are never listed as sources. No information about - inlined symbols is gathered. - + * This means that `.h` files are never listed as sources. No information about + inlined symbols is gathered. 1. Symbol aliases (when multiple symbols share an address) are collected from debug information via `nm elf-file`. - - * Aliases have the same address and size, but report their `.pss` as - `.size / .num_aliases`. - + * Aliases have the same address and size, but report their `.pss` as + `.size / .num_aliases`. 1. Paths for shared symbols (those found in multiple `.o` files) are collected by running `nm` on every `.o` file. - - * Shared symbols do not store the complete list of `.o` files. Instead, the - common ancestor is computed and stored as the path (along with a - `{shared}/count` suffix). + * Shared symbols do not store the complete list of `.o` files. Instead, the + common ancestor is computed and stored as the path (along with a + `{shared}/count` suffix). #### What Other Processing Happens? 1. Path normalization: - - * Prefixes are removed: `out/Release/`, `gen/`, `obj/` - * Archive names made more pathy: `foo/bar.a(baz.o)` -> `foo/bar.a/baz.o` + * Prefixes are removed: `out/Release/`, `gen/`, `obj/` + * Archive names made more pathy: `foo/bar.a(baz.o)` -> `foo/bar.a/baz.o` 1. Name normalization: - - * `(anonymous::)` is removed from names. - * `vtable for FOO` -> `Foo [vtable]` - * Names split into: `name`, `template_name`, `full_name` + * `(anonymous::)` is removed from names. + * `vtable for FOO` -> `Foo [vtable]` + * Names split into: `name`, `template_name`, `full_name` 1. Clustering - - * Compiler optimizations can cause a symbol to be broken into multiple smaller - symbols. Clustering puts them back together. + * Compiler optimizations can cause a symbol to be broken into multiple + smaller symbols. Clustering puts them back together. 1. Diffing + * Some heuristics for matching up before/after symbols. - * Some heuristics for matching up before/after symbols. +#### Is Super Size a Generic Tool? -### Usage: `archive` +No. Most of the logic is would could work for any ELF executable. However, being +a generic tool is not a goal. Some examples of existing Chrome-specific logic: + + * Assumes `.ninja` build rules are available. + * Heuristic for locating `.so` given `.apk`. + * Roadmap includes `.pak` file analysis. + +### Usage: archive Collect size information and dump it into a `.size` file. @@ -127,7 +127,7 @@ ninja -C out/Release -j 1000 chrome tools/binary_size/supersize archive chrome.size --elf-file out/Release/chrome -v -### Usage: `html_report` +### Usage: html_report Creates an interactive size breakdown (by source path) as a stand-alone html report. @@ -137,7 +137,7 @@ tools/binary_size/supersize html_report chrome.size --report-dir size-report -v xdg-open size-report/index.html -### Usage: `console` +### Usage: console Starts a Python interpreter where you can run custom queries. @@ -149,7 +149,7 @@ # Enters a Python REPL (it will print more guidance). tools/binary_size/supersize console chrome.size -### Usage: `diff` +### Usage: diff A convenience command equivalent to: `console before.size after.size --query='Print(Diff(size_info1, size_info2))'` @@ -163,30 +163,22 @@ 1. [Better Linux support](https://bugs.chromium.org/p/chromium/issues/detail?id=717550) (clang+lld+lto vs gcc+gold). 1. More `archive` features: - - * Find out more about 0xffffffffffffffff addresses, and why such large - gaps exist after them. ([crbug/709050](https://bugs.chromium.org/p/chromium/issues/detail?id=709050)) - * Collect .pak file information (using .o.whitelist files) - * Collect java symbol information - * Collect .apk entry information - + * Find out more about 0xffffffffffffffff addresses, and why such large + gaps exist after them. ([crbug/709050](https://bugs.chromium.org/p/chromium/issues/detail?id=709050)) + * Collect .pak file information (using .o.whitelist files) + * Collect java symbol information + * Collect .apk entry information 1. More `console` features: - - * CSV output (for pasting into a spreadsheet). - * Add `SplitByName()` - Like `GroupByName()`, but recursive. - * A canned query, that does what ShowGlobals does (as described in [Windows Binary Sizes](https://www.chromium.org/developers/windows-binary-sizes)). - * Show symbol counts by bucket size. - - * 3 symbols < 64 bytes. 10 symbols < 128, 3 < 256, 5 < 512, 0 < 1024, 3 < 2048 - + * CSV output (for pasting into a spreadsheet). + * Add `SplitByName()` - Like `GroupByName()`, but recursive. + * A canned query, that does what ShowGlobals does (as described in [Windows Binary Sizes](https://www.chromium.org/developers/windows-binary-sizes)). + * Show symbol counts by bucket size. + * 3 symbols < 64 bytes. 10 symbols < 128, 3 < 256, 5 < 512, 0 < 1024, 3 < 2048 1. More `html_report` features: - - * Able to render size diffs (tint negative size red). - * Break down by other groupings (Create from result of `SplitByName()`) - * Render as simple tree view rather than 2d boxes - + * Able to render size diffs (tint negative size red). + * Break down by other groupings (Create from result of `SplitByName()`) + * Render as simple tree view rather than 2d boxes 1. Integrate with `resource_sizes.py` so that it tracks size of major components separately: chrome vs blink vs skia vs v8. 1. Add dependency graph info, perhaps just on a per-file basis. - - * No idea how to do this, but Windows can do it via `tools\win\linker_verbose_tracking.py` + * No idea how to do this, but Windows can do it via `tools\win\linker_verbose_tracking.py`
diff --git a/tools/gritsettings/translation_expectations.pyl b/tools/gritsettings/translation_expectations.pyl index 0ddd39d00..8fc2ff1 100644 --- a/tools/gritsettings/translation_expectations.pyl +++ b/tools/gritsettings/translation_expectations.pyl
@@ -57,6 +57,7 @@ "files": [ "android_webview/java/strings/android_webview_strings.grd", "chrome/android/java/strings/android_chrome_strings.grd", + "chrome/android/webapk/strings/android_webapk_strings.grd", "content/public/android/java/strings/android_content_strings.grd", "ui/android/java/strings/android_ui_strings.grd", ],
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index b5c057f7..982d45e 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -21217,6 +21217,7 @@ <int value="-1880355454" label="disable-topchrome-md"/> <int value="-1876881908" label="disable-infobar-for-protected-media-identifier"/> + <int value="-1875383510" label="UseGoogleLocalNtp:disabled"/> <int value="-1874908826" label="enable-instant-search-clicks"/> <int value="-1874141108" label="NewOmniboxAnswerTypes:enabled"/> <int value="-1872989945" label="enable-webview-based-signin"/> @@ -21305,6 +21306,7 @@ <int value="-1559789642" label="RunAllFlashInAllowMode:enabled"/> <int value="-1557527869" label="LoadingWithMojo:disabled"/> <int value="-1553477903" label="ash-disable-text-filtering-in-overview-mode"/> + <int value="-1549871007" label="OneGoogleBarOnLocalNtp:disabled"/> <int value="-1546903171" label="enable-touch-drag-drop"/> <int value="-1544248549" label="ArcUseAuthEndpoint:enabled"/> <int value="-1543316040" @@ -21981,6 +21983,7 @@ <int value="1081546525" label="ash-enable-docked-windows"/> <int value="1087235172" label="file-manager-enable-new-audio-player"/> <int value="1090377940" label="enable-quic-https"/> + <int value="1094506652" label="UseGoogleLocalNtp:enabled"/> <int value="1095061640" label="enable-prominent-url-app-flow"/> <int value="1098823967" label="ash-enable-window-cycle-ui"/> <int value="1104948452" label="manual-enhanced-bookmarks-optout"/> @@ -22121,6 +22124,7 @@ <int value="1511161758" label="BackgroundLoader:enabled"/> <int value="1515196403" label="fast-user-switching"/> <int value="1517863401" label="history-entry-requires-user-gesture"/> + <int value="1538690515" label="OneGoogleBarOnLocalNtp:enabled"/> <int value="1541723759" label="ServiceWorkerNavigationPreload:disabled"/> <int value="1548776701" label="AllBookmarks:disabled"/> <int value="1548942246" label="PassiveDocumentEventListeners:disabled"/> @@ -22262,6 +22266,7 @@ label="enable-supervised-user-managed-bookmarks-folder"/> <int value="2079672348" label="ExperimentalKeyboardLockUI:disabled"/> <int value="2085438501" label="ChromeHome:enabled"/> + <int value="2089897928" label="enable-audio-focus"/> <int value="2093235103" label="default-tile-width"/> <int value="2097048479" label="disable-auto-hiding-toolbar-threshold"/> <int value="2098714203" label="enable-generic-sensors"/>
diff --git a/tools/perf/docs/apk_size_regressions.md b/tools/perf/docs/apk_size_regressions.md index a196e80..8e60f241 100644 --- a/tools/perf/docs/apk_size_regressions.md +++ b/tools/perf/docs/apk_size_regressions.md
@@ -1,86 +1,126 @@ # How to Deal with Android Size Alerts -*Not all alerts should not have a bug created for them. Please read on...* + > + > Not all alerts should not have a bug created for them. Please read on... + > -### If the alert is for "other lib size" or "Unknown files size": - * File a bug against agrieve@ to fix - [resource_sizes.py](https://cs.chromium.org/chromium/src/build/android/resource_sizes.py). - * ...or fix it yourself. This script will output the list of unknown - filenames. +[TOC] -### If the alert is a downstream size alert (aka, for Monochrome.apk): +## Step 1: Identify the Commit + +### MonochromePublic.apk Alerts (Single Commit) + + * Zoom in on the graph to make sure the alert is not + [off-by-one](https://github.com/catapult-project/catapult/issues/3444) + * Replace `&num_points=XXXX` with `&rev=COMMIT_POSITION` in the URL. + * It will be obvious from this whether or not the point is off. Use the + "nudge" feature to correct it when this happens. + +### MonochromePublic.apk Alerts (Multiple Commits or Rolls) + + * Bisects [will not help you](https://bugs.chromium.org/p/chromium/issues/detail?id=678338). + * File a bug using template in Step 2. + * If you can afford to run a fire-and-forget command locally, use a + [local Android checkout](https://chromium.googlesource.com/chromium/src/+/master/docs/android_build_instructions.md) + along with [`//tools/binary_size/diagnose_bloat.py`](https://chromium.googlesource.com/chromium/src/+/master/tools/binary_size/README.md) + to build all commits locally and find the culprit. + +**Example:** + + tools/binary_size/diagnose_bloat.py AFTER_REV --reference-rev BEFORE_REV --subrepo v8 --all + +### Monochrome.apk Alerts + * The regression most likely already occurred in the upstream MonochromePublic.apk target. Look at the - [upstream graphs](https://chromeperf.appspot.com/report?sid=cfc29eed1238fd38fb5e6cf83bdba6c619be621b606e03e5dfc2e99db14c418b&num_points=1500) - to find the culprit & de-dupe with upstream alerts. + [graph of Monochrome.apk and MonochromePublic.apk overlaid](https://chromeperf.appspot.com/report?sid=cfc29eed1238fd38fb5e6cf83bdba6c619be621b606e03e5dfc2e99db14c418b&num_points=1500) + to find the culprit and de-dupe with upstream alert. * If no upstream regression was found, look through the downstream commits within the given date range to find the culprit. * Via `git log --format=fuller` (be sure to look at `CommitDate` and not `AuthorDate`) + * If the culprit is not obvious, follow the steps from the "multiple commits" + section above, filing a bug and running `diagnose_bloat.py` + (with `--subrepo=clank`). -### If the alert is for a roll, or has multiple commits listed: - * Use a bisect to try and determine a more precise commit. - * Except don't. Bisects for these alerts [are currently broken](https://bugs.chromium.org/p/chromium/issues/detail?id=678338). - * Until this is fixed, just file a bug and assign to agrieve@. +## Step 2: File Bug or Silence Alert -### What to do once the commit is identified: - * If the code seems to justify the size increase: - * Annotate the code review with the following (replacing **bold** parts): - > FYI - this added **20kb** to Chrome on Android. No action is required - > (unless you can think of an obvious way to reduce the overhead). - > - > Link to size graph: -[https://chromeperf.appspot.com/report?sid=cfc29eed1238fd38fb5e6cf83bdba6c619be621b606e03e5dfc2e99db14c418b&rev=**440074**](https://chromeperf.appspot.com/report?sid=cfc29eed1238fd38fb5e6cf83bdba6c619be621b606e03e5dfc2e99db14c418b&rev=440074) - * If the code might not justify the size increase: - * File a bug and assign to the author to follow-up. - * Change the bug's title from X% to XXkb - * Paste in link to commit or review URL that is at fault. - * Paste in link to [https://chromium.googlesource.com/chromium/src/+/master/tools/perf/docs/apk_size_regressions.md#Debugging-Apk-Size-Increase](https://chromium.googlesource.com/chromium/src/+/master/tools/perf/docs/apk_size_regressions.md#Debugging-Apk-Size-Increase). - * Remove label: `Restrict-View-Google` - * TODO(agrieve): [https://github.com/catapult-project/catapult/issues/3150](Change bug template to match these instructions) +If the code seems to justify the size increase: + + * Annotate the code review with the following (replacing **bold** parts): + > FYI - this added **20kb** to Chrome on Android. No action is required + > (unless you can think of an obvious way to reduce the overhead). + > + > Link to size graph: +[https://chromeperf.appspot.com/report?sid=a097e74b1aa288511afb4cb616efe0f95ba4d347ad61d5e835072f23450938ba&rev=**440074**](https://chromeperf.appspot.com/report?sid=cfc29eed1238fd38fb5e6cf83bdba6c619be621b606e03e5dfc2e99db14c418b&rev=440074) + * Silence the alert. + + +If the code might not justify the size increase: + + * File a bug (TODO: +[Make this template automatic](https://github.com/catapult-project/catapult/issues/3150)). + * Change the bug's title from `X%` to `XXkb` + * Remove label: `Restrict-View-Google` + * Assign to commit author + * Set description to (replacing **bold** parts): + > Alert caused by "**First line of commit message**" + > + > Commit: **abc123abc123abc123abc123abc123abc123abcd** + > + > Link to size graph: +[https://chromeperf.appspot.com/report?sid=a097e74b1aa288511afb4cb616efe0f95ba4d347ad61d5e835072f23450938ba&rev=**440074**](https://chromeperf.appspot.com/report?sid=cfc29eed1238fd38fb5e6cf83bdba6c619be621b606e03e5dfc2e99db14c418b&rev=440074) + > + > + > How to debug this size regressions is documented at: +https://chromium.googlesource.com/chromium/src/+/master/tools/perf/docs/apk_size_regressions.md#Debugging-Apk-Size-Increase # Debugging Apk Size Increase -## Step 1: Identify where the extra bytes came from +## Step 1: Identify what Grew -Figure out which file within the .apk increased by looking at the size graphs -showing the breakdowns. +Figure out which file within the `.apk` increased (native library, dex, pak +resources, etc) by looking at the breakdown in the size graphs linked to in the +bug (if it was not linked in the bug, see above). - * Refer to the chromeperf link that should have been posted to your code - review (see above). - * Alternatively, refer to [go/chrome-binary-size](https://goto.google.com/chrome-binary-size) (*googler only*). +## Step 2: Analyze -## Step 2: Reproduce build results locally +### Growth is from Translations -### Option 1: Build Locally - 1. Follow the normal [Android build instructions](https://chromium.googlesource.com/chromium/src/+/master/docs/android_build_instructions.md). - 1. Ensure you're using the same GN args as the bots by looking at the `generate_build_files` step of the build: - * https://luci-logdog.appspot.com/v/?s=chrome%2Fbb%2Fchromium.perf%2FAndroid_Builder%2F**134505**%2F%2B%2Frecipes%2Fsteps%2Fgenerate_build_files%2F0%2Fstdout - 3. Save artifacts you'll need for diffing: + * There is likely nothing that can be done. Translations are expensive. + * Close as `Won't Fix`. -```shell - mv out/Release/lib.unstripped out/Release/lib.unstripped.withchange - mv out/Release/apks out/Release/apks.withchange -``` +### Growth is from Images -### Option 2: Download artifacts from perf jobs (Googlers only)** - 1. Replace the bolded part of the following URL with the git commit hash: - [https://storage.cloud.google.com/chrome-perf/Android%20Builder/full-build-linux_**HASH**.zip](https://storage.cloud.google.com/chrome-perf/Android%20Builder/full-build-linux_**HASH**.zip) + * Would [a VectorDrawable](https://codereview.chromium.org/2857893003/) be better? + * If it's lossy, consider [using webp](https://codereview.chromium.org/2615243002/). + * Ensure you've optimized with + [tools/resources/optimize-png-files.sh](https://cs.chromium.org/chromium/src/tools/resources/optimize-png-files.sh). + * There is some [Googler-specific guidance](https://goto.google.com/clank/engineering/best-practices/adding-image-assets) as well. -## Step 3: Analyze +### Growth is from Native Code - * If the growth is from native code: - * Refer to techniques used in [crbug.com/681991](https://bugs.chromium.org/p/chromium/issues/detail?id=681991) - and [crbug.com/680973](https://bugs.chromium.org/p/chromium/issues/detail?id=680973). - * If the growth is from java code: - * Use [tools/android/dexdiffer/dexdiffer.py](https://cs.chromium.org/chromium/src/tools/android/dexdiffer/dexdiffer.py). - * This currently just shows a list of symbols added / removed rather than - taking into account method body sizes. - * Enhancements to this tool tracked at - [crbug/678044](https://bugs.chromium.org/p/chromium/issues/detail?id=678044). - * If the growth is from images, ensure they are optimized: - * Would it be smaller as a VectorDrawable? - * If it's lossy, consider using webp. - * Ensure you've optimized with - [tools/resources/optimize-png-files.sh](https://cs.chromium.org/chromium/src/tools/resources/optimize-png-files.sh). - * There is some [Googler-specific guidance](https://goto.google.com/clank/engineering/best-practices/adding-image-assets) as well. + * Use [//tools/binary_size/diagnose_bloat.py](https://chromium.googlesource.com/chromium/src/+/master/tools/binary_size/README.md) +to show a diff of ELF symbols. + * Paste the diff into the bug. + * If the diff looks reasonable, close as `Won't Fix`. + * Otherwise, try to refactor a bit (e.g. + [move code out of templates](https://bugs.chromium.org/p/chromium/issues/detail?id=716393)). + +### Growth is from Java code + + * Use [tools/android/dexdiffer/dexdiffer.py](https://cs.chromium.org/chromium/src/tools/android/dexdiffer/dexdiffer.py). + * This currently just shows a list of symbols added / removed rather than + taking into account method body sizes. + * Enhancements to this tool tracked at + [crbug/678044](https://bugs.chromium.org/p/chromium/issues/detail?id=678044). + +### Growth is from "other lib size" or "Unknown files size" + + * File a bug against agrieve@ to fix + [resource_sizes.py](https://cs.chromium.org/chromium/src/build/android/resource_sizes.py). + * ...or fix it yourself. This script will output the list of unknown filenames. + +### You Would Like Assistance + + * Feel free to email [binary-size@chromium.org](https://groups.google.com/a/chromium.org/forum/#!forum/binary-size).