diff --git a/ash/autoclick/mus/BUILD.gn b/ash/autoclick/mus/BUILD.gn index 558bd4d7..c69bc11 100644 --- a/ash/autoclick/mus/BUILD.gn +++ b/ash/autoclick/mus/BUILD.gn
@@ -22,7 +22,6 @@ "//mojo/common", "//mojo/public/cpp/bindings", "//services/service_manager/public/cpp", - "//services/service_manager/public/cpp", "//services/ui/public/cpp", "//services/ui/public/interfaces", "//ui/aura", @@ -45,7 +44,6 @@ "//base", "//mojo/public/cpp/bindings", "//services/service_manager/public/cpp", - "//services/service_manager/public/cpp", "//ui/views/mus:for_mojo_application", ]
diff --git a/ash/touch_hud/mus/BUILD.gn b/ash/touch_hud/mus/BUILD.gn index 1915e0e..8c82e8d 100644 --- a/ash/touch_hud/mus/BUILD.gn +++ b/ash/touch_hud/mus/BUILD.gn
@@ -21,7 +21,6 @@ "//mojo/common", "//mojo/public/cpp/bindings", "//services/service_manager/public/cpp", - "//services/service_manager/public/cpp", "//services/ui/public/cpp", "//services/ui/public/interfaces", "//ui/views", @@ -43,7 +42,6 @@ "//base", "//mojo/public/cpp/bindings", "//services/service_manager/public/cpp", - "//services/service_manager/public/cpp", "//ui/views/mus:for_mojo_application", ]
diff --git a/cc/BUILD.gn b/cc/BUILD.gn index fa0bd60..a957fa7 100644 --- a/cc/BUILD.gn +++ b/cc/BUILD.gn
@@ -942,7 +942,6 @@ "//cc/ipc", "//cc/ipc:interfaces", "//cc/paint", - "//cc/paint", "//cc/surfaces", "//cc/surfaces:surface_id", "//gpu",
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index 440dc93..493eb02 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -192,14 +192,12 @@ "//components/precache/android:precache_java", "//components/safe_browsing_db/android:safe_browsing_java", "//components/safe_json/android:safe_json_java", - "//components/safe_json/android:safe_json_java", "//components/signin/core/browser/android:java", "//components/spellcheck/browser/android:java", "//components/sync/android:sync_java", "//components/url_formatter/android:url_formatter_java", "//components/variations/android:variations_java", "//components/web_contents_delegate_android:web_contents_delegate_android_java", - "//components/web_contents_delegate_android:web_contents_delegate_android_java", "//components/web_restrictions:web_restrictions_java", "//content/public/android:content_java", "//device/geolocation:geolocation_java",
diff --git a/chrome/android/java/res/layout/default_search_engine_first_run_fragment.xml b/chrome/android/java/res/layout/default_search_engine_first_run_fragment.xml index b74e07d..bc59ef6e 100644 --- a/chrome/android/java/res/layout/default_search_engine_first_run_fragment.xml +++ b/chrome/android/java/res/layout/default_search_engine_first_run_fragment.xml
@@ -48,7 +48,7 @@ <View style="@style/Divider" /> <org.chromium.chrome.browser.widget.RadioButtonLayout - android:id="@+id/engine_controls" + android:id="@+id/default_search_engine_dialog_options" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginStart="12dp"
diff --git a/chrome/android/java/res/values/ids.xml b/chrome/android/java/res/values/ids.xml index 82c7330..db7bcb5e 100644 --- a/chrome/android/java/res/values/ids.xml +++ b/chrome/android/java/res/values/ids.xml
@@ -17,6 +17,7 @@ <item name="tabswitcher_multiple_drawable" type="id"/> <item name="tabswitcher_single_drawable" type="id"/> <item name="custom_tab_bottom_bar_wrapper" type="id"/> + <item name="default_search_engine_dialog_options" type="id"/> <!-- InfoBar constants --> <item type="id" name="button_primary" />
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/browseractions/BrowserActionActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/browseractions/BrowserActionActivity.java index 2ba8475..ff48198 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/browseractions/BrowserActionActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/browseractions/BrowserActionActivity.java
@@ -123,6 +123,6 @@ * Callback when Browser Actions menu dialog is shown. */ private void onMenuShown() { - beginLoadingLibrary(); + startNativeInitialization(); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/DefaultSearchEngineFirstRunFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/DefaultSearchEngineFirstRunFragment.java index ea4cad95..aa8996b2 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/DefaultSearchEngineFirstRunFragment.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/DefaultSearchEngineFirstRunFragment.java
@@ -33,7 +33,8 @@ LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate( R.layout.default_search_engine_first_run_fragment, container, false); - mEngineLayout = (RadioButtonLayout) rootView.findViewById(R.id.engine_controls); + mEngineLayout = (RadioButtonLayout) rootView.findViewById( + R.id.default_search_engine_dialog_options); mButton = (Button) rootView.findViewById(R.id.button_primary); mButton.setEnabled(false);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/init/AsyncInitializationActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/init/AsyncInitializationActivity.java index 0a3ced3..86fb779 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/init/AsyncInitializationActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/init/AsyncInitializationActivity.java
@@ -278,7 +278,7 @@ /** * Call to begin loading the library, if it was delayed. */ - protected void beginLoadingLibrary() { + protected void startNativeInitialization() { assert shouldDelayBrowserStartup(); ChromeBrowserInitializer.getInstance(this).handlePreNativeStartup(this); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/locale/DefaultSearchEnginePromoDialog.java b/chrome/android/java/src/org/chromium/chrome/browser/locale/DefaultSearchEnginePromoDialog.java index 0ee7f70..945d74d0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/locale/DefaultSearchEnginePromoDialog.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/locale/DefaultSearchEnginePromoDialog.java
@@ -11,6 +11,7 @@ import android.widget.Button; import org.chromium.base.Callback; +import org.chromium.base.VisibleForTesting; import org.chromium.base.library_loader.LibraryLoader; import org.chromium.chrome.R; import org.chromium.chrome.browser.locale.LocaleManager.SearchEnginePromoType; @@ -20,6 +21,12 @@ /** A dialog that forces the user to choose a default search engine. */ public class DefaultSearchEnginePromoDialog extends PromoDialog { + /** Notified about events happening to the dialog. */ + public static interface DefaultSearchEnginePromoDialogObserver { + void onDialogShown(DefaultSearchEnginePromoDialog shownDialog); + } + private static DefaultSearchEnginePromoDialogObserver sObserver; + /** Used to determine the promo dialog contents. */ @SearchEnginePromoType private final int mDialogType; @@ -83,6 +90,7 @@ okButton.setEnabled(false); RadioButtonLayout radioButtons = new RadioButtonLayout(getContext()); + radioButtons.setId(R.id.default_search_engine_dialog_options); addControl(radioButtons); Runnable dismissRunnable = new Runnable() { @@ -96,6 +104,12 @@ } @Override + public void show() { + super.show(); + if (sObserver != null) sObserver.onDialogShown(this); + } + + @Override public void onDismiss(DialogInterface dialog) { if (mHelper.getCurrentlySelectedKeyword() == null) { // This shouldn't happen, but in case it does, finish the Activity so that the user has @@ -107,4 +121,11 @@ mOnDismissed.onResult(mHelper.getCurrentlySelectedKeyword() != null); } } + + /** See {@link #sObserver}. */ + @VisibleForTesting + @Nullable + public static void setObserverForTests(DefaultSearchEnginePromoDialogObserver observer) { + sObserver = observer; + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/locale/OWNERS b/chrome/android/java/src/org/chromium/chrome/browser/locale/OWNERS new file mode 100644 index 0000000..c806110 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/locale/OWNERS
@@ -0,0 +1,7 @@ +set noparent + +dfalcantara@chromium.org +tedchoc@chromium.org +yusufo@chromium.org + +# COMPONENT: UI>Browser>Mobile>SearchWidget \ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/OWNERS b/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/OWNERS new file mode 100644 index 0000000..c806110 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/OWNERS
@@ -0,0 +1,7 @@ +set noparent + +dfalcantara@chromium.org +tedchoc@chromium.org +yusufo@chromium.org + +# COMPONENT: UI>Browser>Mobile>SearchWidget \ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchActivity.java index dbb7e91f..86b6ba1 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchActivity.java
@@ -4,6 +4,7 @@ package org.chromium.chrome.browser.searchwidget; +import android.app.Activity; import android.content.Intent; import android.net.Uri; import android.support.v4.app.ActivityOptionsCompat; @@ -38,24 +39,40 @@ public class SearchActivity extends AsyncInitializationActivity implements SnackbarManageable, SearchActivityLocationBarLayout.Delegate { /** Notified about events happening inside a SearchActivity. */ - public interface SearchActivityObserver { - /** Called when {@link SearchActivity#setContentView} is done. */ - void onSetContentView(); + public static class SearchActivityDelegate { + /** + * Called when {@link SearchActivity#setContentView} is deciding whether to continue loading + * the native library immediately. + * @return Whether or not native initialization should proceed immediately. + */ + boolean shouldDelayNativeInitialization() { + return false; + } - /** Called when {@link SearchActivity#finishNativeInitialization} is done. */ - void onFinishNativeInitialization(); + /** + * Called to launch the search engine dialog if it's needed. + * @param activity Activity that is launching the dialog. + * @param callback Called when the dialog has been dismissed. + * @return Whether or not the search dialog was shown. + */ + boolean showSearchEngineDialogIfNeeded(Activity activity, Callback<Boolean> callback) { + return LocaleManager.getInstance().showSearchEnginePromoIfNeeded(activity, callback); + } /** Called when {@link SearchActivity#finishDeferredInitialization} is done. */ - void onFinishDeferredInitialization(); + void onFinishDeferredInitialization() {} + + /** Returning true causes the Activity to finish itself immediately when starting up. */ + boolean isActivityDisabledForTests() { + return false; + } } private static final String TAG = "searchwidget"; - - /** Setting this field causes the Activity to finish itself immediately for tests. */ - private static boolean sIsDisabledForTest; + private static final Object DELEGATE_LOCK = new Object(); /** Notified about events happening for the SearchActivity. */ - private static SearchActivityObserver sObserver; + private static SearchActivityDelegate sDelegate; /** Main content view. */ private ViewGroup mContentView; @@ -75,7 +92,7 @@ @Override protected boolean isStartedUpCorrectly(Intent intent) { - if (sIsDisabledForTest) return false; + if (getActivityDelegate().isActivityDisabledForTests()) return false; return super.isStartedUpCorrectly(intent); } @@ -110,22 +127,18 @@ mSearchBox.initializeControls(new WindowDelegate(getWindow()), getWindowAndroid()); // Kick off everything needed for the user to type into the box. - // TODO(dfalcantara): We should prevent the user from doing anything while we're running the - // logic to determine if they need to see a search engine promo. Given - // that the logic requires native to be loaded, we'll have to make some - // easy Java-only first-pass checks. beginQuery(); mSearchBox.showCachedZeroSuggestResultsIfAvailable(); // Kick off loading of the native library. - mHandler.post(new Runnable() { - @Override - public void run() { - beginLoadingLibrary(); - } - }); - - if (sObserver != null) sObserver.onSetContentView(); + if (!getActivityDelegate().shouldDelayNativeInitialization()) { + mHandler.post(new Runnable() { + @Override + public void run() { + startNativeInitialization(); + } + }); + } } @Override @@ -146,28 +159,26 @@ final Callback<Boolean> deferredCallback = new Callback<Boolean>() { @Override public void onResult(Boolean result) { - finishDeferredInitialization(result); + if (result == null || !result.booleanValue()) { + Log.e(TAG, "User failed to select a default search engine."); + finish(); + return; + } + + finishDeferredInitialization(); } }; - if (!LocaleManager.getInstance().showSearchEnginePromoIfNeeded(this, deferredCallback)) { + if (!getActivityDelegate().showSearchEngineDialogIfNeeded(this, deferredCallback)) { mHandler.post(new Runnable() { @Override public void run() { - deferredCallback.onResult(true); + finishDeferredInitialization(); } }); } - - if (sObserver != null) sObserver.onFinishNativeInitialization(); } - private void finishDeferredInitialization(Boolean result) { - if (result == null || !result.booleanValue()) { - Log.e(TAG, "User failed to select a default search engine."); - finish(); - return; - } - + void finishDeferredInitialization() { mIsActivityUsable = true; if (mQueuedUrl != null) loadUrl(mQueuedUrl); @@ -175,7 +186,7 @@ CustomTabsConnection.getInstance(getApplication()).warmup(0); mSearchBox.onDeferredStartup(isVoiceSearchIntent()); - if (sObserver != null) sObserver.onFinishDeferredInitialization(); + getActivityDelegate().onFinishDeferredInitialization(); } @Override @@ -259,15 +270,22 @@ overridePendingTransition(0, R.anim.activity_close_exit); } - /** See {@link #sIsDisabledForTest}. */ + @Override @VisibleForTesting - static void disableForTests() { - sIsDisabledForTest = true; + public final void startNativeInitialization() { + super.startNativeInitialization(); } - /** See {@link #sObserver}. */ + private static SearchActivityDelegate getActivityDelegate() { + synchronized (DELEGATE_LOCK) { + if (sDelegate == null) sDelegate = new SearchActivityDelegate(); + } + return sDelegate; + } + + /** See {@link #sDelegate}. */ @VisibleForTesting - static void setObserverForTests(SearchActivityObserver observer) { - sObserver = observer; + static void setDelegateForTests(SearchActivityDelegate delegate) { + sDelegate = delegate; } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchActivityLocationBarLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchActivityLocationBarLayout.java index 16b7170..eeb225c7 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchActivityLocationBarLayout.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchActivityLocationBarLayout.java
@@ -6,6 +6,7 @@ import android.content.Context; import android.os.Handler; +import android.text.TextUtils; import android.util.AttributeSet; import android.view.View; @@ -68,6 +69,7 @@ void onDeferredStartup(boolean isVoiceSearchIntent) { SearchWidgetProvider.updateCachedVoiceSearchAvailability(isVoiceSearchEnabled()); if (isVoiceSearchIntent && mUrlBar.isFocused()) onUrlFocusChange(true); + if (!TextUtils.isEmpty(mUrlBar.getText())) onTextChangedForAutocomplete(false); } /** Begins a new query. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchWidgetProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchWidgetProvider.java index 2e9c804..9678cf2 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchWidgetProvider.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchWidgetProvider.java
@@ -392,7 +392,7 @@ /** Sets an {@link SearchWidgetProviderDelegate} to interact with. */ @VisibleForTesting - static void setDelegateForTest(SearchWidgetProviderDelegate delegate) { + static void setActivityDelegateForTest(SearchWidgetProviderDelegate delegate) { assert sDelegate == null; sDelegate = delegate; }
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni index 410ce8e..918e0ef5 100644 --- a/chrome/android/java_sources.gni +++ b/chrome/android/java_sources.gni
@@ -1425,6 +1425,7 @@ "javatests/src/org/chromium/chrome/browser/invalidation/DelayedInvalidationsControllerTest.java", "javatests/src/org/chromium/chrome/browser/invalidation/InvalidationServiceTest.java", "javatests/src/org/chromium/chrome/browser/locale/DefaultSearchEngineDialogHelperTest.java", + "javatests/src/org/chromium/chrome/browser/locale/DefaultSearchEngineDialogHelperUtils.java", "javatests/src/org/chromium/chrome/browser/media/RouterTestUtils.java", "javatests/src/org/chromium/chrome/browser/media/remote/CastNotificationTest.java", "javatests/src/org/chromium/chrome/browser/media/remote/CastPositionTransferTest.java",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/firstrun/FirstRunIntegrationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/firstrun/FirstRunIntegrationTest.java index 8884b7e6..ffbdd52e 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/firstrun/FirstRunIntegrationTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/firstrun/FirstRunIntegrationTest.java
@@ -15,7 +15,6 @@ import android.support.test.InstrumentationRegistry; import android.support.test.filters.MediumTest; import android.support.test.filters.SmallTest; -import android.view.ViewGroup; import android.widget.Button; import org.junit.After; @@ -31,9 +30,9 @@ import org.chromium.chrome.browser.ChromeTabbedActivity; import org.chromium.chrome.browser.customtabs.CustomTabActivity; import org.chromium.chrome.browser.document.ChromeLauncherActivity; +import org.chromium.chrome.browser.locale.DefaultSearchEngineDialogHelperUtils; import org.chromium.chrome.browser.locale.LocaleManager; import org.chromium.chrome.browser.locale.LocaleManager.SearchEnginePromoType; -import org.chromium.chrome.browser.search_engines.TemplateUrlService; import org.chromium.chrome.browser.searchwidget.SearchActivity; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.MultiActivityTestRule; @@ -52,7 +51,6 @@ private FirstRunActivityTestObserver mTestObserver = new FirstRunActivityTestObserver(); private Activity mActivity; - private String mSelectedEngine; @Before public void setUp() throws Exception { @@ -307,35 +305,8 @@ Assert.assertTrue("Search engine page wasn't shown.", freProperties.getBoolean(FirstRunActivity.SHOW_SEARCH_ENGINE_PAGE)); int jumpCallCount = mTestObserver.jumpToPageCallback.getCallCount(); - - // Click on the first search engine option available. - CriteriaHelper.pollUiThread(new Criteria() { - @Override - public boolean isSatisfied() { - ViewGroup options = (ViewGroup) mActivity.findViewById(R.id.engine_controls); - return options.getChildCount() > 0; - } - }); - ThreadUtils.runOnUiThreadBlocking(new Runnable() { - @Override - public void run() { - ViewGroup options = (ViewGroup) mActivity.findViewById(R.id.engine_controls); - options.getChildAt(0).performClick(); - mSelectedEngine = (String) (options.getChildAt(0).getTag()); - } - }); - - clickButton(mActivity, R.id.button_primary, "Failed to select default search engine"); - ThreadUtils.runOnUiThreadBlocking(new Runnable() { - @Override - public void run() { - Assert.assertEquals("Search engine wasn't set", - TemplateUrlService.getInstance() - .getDefaultSearchEngineTemplateUrl() - .getKeyword(), - mSelectedEngine); - } - }); + DefaultSearchEngineDialogHelperUtils.clickOnFirstEngine( + mActivity.findViewById(android.R.id.content)); mTestObserver.jumpToPageCallback.waitForCallback( "Failed to try moving to next screen", jumpCallCount);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/locale/DefaultSearchEngineDialogHelperUtils.java b/chrome/android/javatests/src/org/chromium/chrome/browser/locale/DefaultSearchEngineDialogHelperUtils.java new file mode 100644 index 0000000..a7d1ba7 --- /dev/null +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/locale/DefaultSearchEngineDialogHelperUtils.java
@@ -0,0 +1,78 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.locale; + +import android.view.View; +import android.view.ViewGroup; + +import org.junit.Assert; + +import org.chromium.base.ThreadUtils; +import org.chromium.chrome.R; +import org.chromium.chrome.browser.search_engines.TemplateUrlService; +import org.chromium.content.browser.test.util.Criteria; +import org.chromium.content.browser.test.util.CriteriaHelper; + +/** + * Utilities for interacting with a {@link DefaultSearchEngineDialogHelper}. + */ +public class DefaultSearchEngineDialogHelperUtils { + private static final int OPTION_LAYOUT_ID = R.id.default_search_engine_dialog_options; + private static final int OK_BUTTON_ID = R.id.button_primary; + + private static String sSelectedEngine; + + /** Clicks on the first search engine option available. */ + public static void clickOnFirstEngine(final View rootView) { + // Wait for the options to appear. + CriteriaHelper.pollUiThread(new Criteria() { + @Override + public boolean isSatisfied() { + ViewGroup options = (ViewGroup) rootView.findViewById(OPTION_LAYOUT_ID); + return options.getChildCount() > 0; + } + }); + + // Click on the first search engine option available. + ThreadUtils.runOnUiThreadBlocking(new Runnable() { + @Override + public void run() { + ViewGroup options = (ViewGroup) rootView.findViewById(OPTION_LAYOUT_ID); + options.getChildAt(0).performClick(); + sSelectedEngine = (String) (options.getChildAt(0).getTag()); + } + }); + + // Wait for the OK button to be clicakble. + CriteriaHelper.pollUiThread(new Criteria() { + @Override + public boolean isSatisfied() { + View view = rootView.findViewById(OK_BUTTON_ID); + return view != null && view.isEnabled(); + } + }); + + // Click on the OK button. + ThreadUtils.runOnUiThread(new Runnable() { + @Override + public void run() { + View view = rootView.findViewById(OK_BUTTON_ID); + view.performClick(); + } + }); + + // Confirm the engine was set appropriately. + ThreadUtils.runOnUiThreadBlocking(new Runnable() { + @Override + public void run() { + Assert.assertEquals("Search engine wasn't set", + TemplateUrlService.getInstance() + .getDefaultSearchEngineTemplateUrl() + .getKeyword(), + sSelectedEngine); + } + }); + } +}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/locale/OWNERS b/chrome/android/javatests/src/org/chromium/chrome/browser/locale/OWNERS new file mode 100644 index 0000000..64295110 --- /dev/null +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/locale/OWNERS
@@ -0,0 +1 @@ +file://chrome/android/java/src/org/chromium/chrome/browser/locale/OWNERS \ No newline at end of file
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/searchwidget/OWNERS b/chrome/android/javatests/src/org/chromium/chrome/browser/searchwidget/OWNERS new file mode 100644 index 0000000..d0dbd1eb --- /dev/null +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/searchwidget/OWNERS
@@ -0,0 +1 @@ +file://chrome/android/java/src/org/chromium/chrome/browser/searchwidget/OWNERS \ No newline at end of file
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/searchwidget/SearchActivityTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/searchwidget/SearchActivityTest.java index 853573cd..21eb45e4 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/searchwidget/SearchActivityTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/searchwidget/SearchActivityTest.java
@@ -21,6 +21,8 @@ import org.junit.Test; import org.junit.runner.RunWith; +import org.chromium.base.ApplicationStatus; +import org.chromium.base.Callback; import org.chromium.base.ThreadUtils; import org.chromium.base.annotations.SuppressFBWarnings; import org.chromium.base.test.util.CallbackHelper; @@ -28,8 +30,12 @@ import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeSwitches; import org.chromium.chrome.browser.ChromeTabbedActivity; +import org.chromium.chrome.browser.locale.DefaultSearchEngineDialogHelperUtils; +import org.chromium.chrome.browser.locale.DefaultSearchEnginePromoDialog; +import org.chromium.chrome.browser.locale.DefaultSearchEnginePromoDialog.DefaultSearchEnginePromoDialogObserver; +import org.chromium.chrome.browser.locale.LocaleManager; import org.chromium.chrome.browser.omnibox.UrlBar; -import org.chromium.chrome.browser.searchwidget.SearchActivity.SearchActivityObserver; +import org.chromium.chrome.browser.searchwidget.SearchActivity.SearchActivityDelegate; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.MultiActivityTestRule; @@ -38,64 +44,97 @@ import org.chromium.content.browser.test.util.CriteriaHelper; import org.chromium.content.browser.test.util.KeyUtils; +import java.util.concurrent.Callable; + /** * Tests the {@link SearchActivity}. * * TODO(dfalcantara): Add tests for: - * + Checking that user can type in the box before native has loaded and still - * have suggestions appear. - * * + Performing a search query. - * + Performing a search query while the SearchActivity is alive and the - * default search engine is changed outside the SearchActivity. * - * + Handling the promo dialog. + * + Performing a search query while the SearchActivity is alive and the + * default search engine is changed outside the SearchActivity. + * + * + Add microphone tests somehow (vague query + confident query). */ @RunWith(ChromeJUnit4ClassRunner.class) @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) public class SearchActivityTest { - private static class TestObserver implements SearchActivityObserver { - public final CallbackHelper onSetContentViewCallback = new CallbackHelper(); - public final CallbackHelper onFinishNativeInitializationCallback = new CallbackHelper(); + private static class TestDelegate + extends SearchActivityDelegate implements DefaultSearchEnginePromoDialogObserver { + public final CallbackHelper shouldDelayNativeInitializationCallback = new CallbackHelper(); + public final CallbackHelper showSearchEngineDialogIfNeededCallback = new CallbackHelper(); public final CallbackHelper onFinishDeferredInitializationCallback = new CallbackHelper(); + public final CallbackHelper onPromoDialogShownCallback = new CallbackHelper(); + + public boolean shouldDelayLoadingNative; + public boolean shouldDelayDeferredInitialization; + public boolean shouldShowRealSearchDialog; + + public DefaultSearchEnginePromoDialog shownPromoDialog; @Override - public void onSetContentView() { - onSetContentViewCallback.notifyCalled(); + boolean shouldDelayNativeInitialization() { + shouldDelayNativeInitializationCallback.notifyCalled(); + return shouldDelayLoadingNative; } @Override - public void onFinishNativeInitialization() { - onFinishNativeInitializationCallback.notifyCalled(); + boolean showSearchEngineDialogIfNeeded(Activity activity, Callback<Boolean> callback) { + showSearchEngineDialogIfNeededCallback.notifyCalled(); + + if (shouldShowRealSearchDialog) { + LocaleManager.setInstanceForTest(new LocaleManager() { + @Override + public int getSearchEnginePromoShowType() { + return SEARCH_ENGINE_PROMO_SHOW_EXISTING; + } + }); + return super.showSearchEngineDialogIfNeeded(activity, callback); + } + + return shouldDelayDeferredInitialization; } @Override public void onFinishDeferredInitialization() { onFinishDeferredInitializationCallback.notifyCalled(); } + + @Override + public void onDialogShown(DefaultSearchEnginePromoDialog dialog) { + shownPromoDialog = dialog; + onPromoDialogShownCallback.notifyCalled(); + } } @Rule @SuppressFBWarnings("URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD") public MultiActivityTestRule mTestRule = new MultiActivityTestRule(); - private TestObserver mTestObserver; + private TestDelegate mTestDelegate; @Before public void setUp() { - mTestObserver = new TestObserver(); - SearchActivity.setObserverForTests(mTestObserver); + mTestDelegate = new TestDelegate(); + SearchActivity.setDelegateForTests(mTestDelegate); + DefaultSearchEnginePromoDialog.setObserverForTests(mTestDelegate); } @After public void tearDown() { - SearchActivity.setObserverForTests(null); + SearchActivity.setDelegateForTests(null); } @Test @SmallTest public void testOmniboxSuggestionContainerAppears() throws Exception { - Activity searchActivity = fullyStartSearchActivity(); + SearchActivity searchActivity = startSearchActivity(); + + // Wait for the Activity to fully load. + mTestDelegate.shouldDelayNativeInitializationCallback.waitForCallback(0); + mTestDelegate.showSearchEngineDialogIfNeededCallback.waitForCallback(0); + mTestDelegate.onFinishDeferredInitializationCallback.waitForCallback(0); // Type in anything. It should force the suggestions to appear. setUrlBarText(searchActivity, "anything."); @@ -108,10 +147,15 @@ @Test @SmallTest public void testStartsBrowserAfterUrlSubmitted() throws Exception { - final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation(); - Activity searchActivity = fullyStartSearchActivity(); + SearchActivity searchActivity = startSearchActivity(); + + // Wait for the Activity to fully load. + mTestDelegate.shouldDelayNativeInitializationCallback.waitForCallback(0); + mTestDelegate.showSearchEngineDialogIfNeededCallback.waitForCallback(0); + mTestDelegate.onFinishDeferredInitializationCallback.waitForCallback(0); // Monitor for ChromeTabbedActivity. + final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation(); ActivityMonitor browserMonitor = new ActivityMonitor(ChromeTabbedActivity.class.getName(), null, false); instrumentation.addMonitor(browserMonitor); @@ -120,8 +164,249 @@ setUrlBarText(searchActivity, "about:blank"); final UrlBar urlBar = (UrlBar) searchActivity.findViewById(R.id.url_bar); KeyUtils.singleKeyEventView(instrumentation, urlBar, KeyEvent.KEYCODE_ENTER); + waitForChromeTabbedActivityToStart(browserMonitor); + } - // Wait for ChromeTabbedActivity to start. + @Test + @SmallTest + public void testTypeBeforeNativeIsLoaded() throws Exception { + // Wait for the activity to load, but don't let it load the native library. + mTestDelegate.shouldDelayLoadingNative = true; + final SearchActivity searchActivity = startSearchActivity(); + mTestDelegate.shouldDelayNativeInitializationCallback.waitForCallback(0); + Assert.assertEquals(0, mTestDelegate.showSearchEngineDialogIfNeededCallback.getCallCount()); + Assert.assertEquals(0, mTestDelegate.onFinishDeferredInitializationCallback.getCallCount()); + + // Set some text in the search box (but don't hit enter). + setUrlBarText(searchActivity, "about:blank"); + + // Start loading native, then let the activity finish initialization. + ThreadUtils.runOnUiThreadBlocking(new Runnable() { + @Override + public void run() { + searchActivity.startNativeInitialization(); + } + }); + + Assert.assertEquals( + 1, mTestDelegate.shouldDelayNativeInitializationCallback.getCallCount()); + mTestDelegate.showSearchEngineDialogIfNeededCallback.waitForCallback(0); + mTestDelegate.onFinishDeferredInitializationCallback.waitForCallback(0); + + // Omnibox suggestions should appear now. + final SearchActivityLocationBarLayout locationBar = + (SearchActivityLocationBarLayout) searchActivity.findViewById( + R.id.search_location_bar); + OmniboxTestUtils.waitForOmniboxSuggestions(locationBar); + + // Hitting enter should submit the URL and kick the user to the browser. + final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation(); + ActivityMonitor browserMonitor = + new ActivityMonitor(ChromeTabbedActivity.class.getName(), null, false); + instrumentation.addMonitor(browserMonitor); + UrlBar urlBar = (UrlBar) searchActivity.findViewById(R.id.url_bar); + KeyUtils.singleKeyEventView(instrumentation, urlBar, KeyEvent.KEYCODE_ENTER); + waitForChromeTabbedActivityToStart(browserMonitor); + } + + @Test + @SmallTest + public void testEnterUrlBeforeNativeIsLoaded() throws Exception { + // Wait for the activity to load, but don't let it load the native library. + mTestDelegate.shouldDelayLoadingNative = true; + final SearchActivity searchActivity = startSearchActivity(); + mTestDelegate.shouldDelayNativeInitializationCallback.waitForCallback(0); + Assert.assertEquals(0, mTestDelegate.showSearchEngineDialogIfNeededCallback.getCallCount()); + Assert.assertEquals(0, mTestDelegate.onFinishDeferredInitializationCallback.getCallCount()); + + // Submit a URL before native is loaded. The browser shouldn't start yet. + final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation(); + setUrlBarText(searchActivity, "about:blank"); + UrlBar urlBar = (UrlBar) searchActivity.findViewById(R.id.url_bar); + KeyUtils.singleKeyEventView(instrumentation, urlBar, KeyEvent.KEYCODE_ENTER); + Assert.assertEquals(searchActivity, ApplicationStatus.getLastTrackedFocusedActivity()); + Assert.assertFalse(searchActivity.isFinishing()); + + // Finish initialization. It should notice the URL is queued up and start the browser. + ActivityMonitor browserMonitor = + new ActivityMonitor(ChromeTabbedActivity.class.getName(), null, false); + instrumentation.addMonitor(browserMonitor); + ThreadUtils.runOnUiThreadBlocking(new Runnable() { + @Override + public void run() { + searchActivity.startNativeInitialization(); + } + }); + + Assert.assertEquals( + 1, mTestDelegate.shouldDelayNativeInitializationCallback.getCallCount()); + mTestDelegate.showSearchEngineDialogIfNeededCallback.waitForCallback(0); + mTestDelegate.onFinishDeferredInitializationCallback.waitForCallback(0); + waitForChromeTabbedActivityToStart(browserMonitor); + } + + @Test + @SmallTest + public void testTypeBeforeDeferredInitialization() throws Exception { + // Start the Activity. It should pause and assume that a promo dialog has appeared. + mTestDelegate.shouldDelayDeferredInitialization = true; + final SearchActivity searchActivity = startSearchActivity(); + mTestDelegate.shouldDelayNativeInitializationCallback.waitForCallback(0); + mTestDelegate.showSearchEngineDialogIfNeededCallback.waitForCallback(0); + Assert.assertEquals(0, mTestDelegate.onFinishDeferredInitializationCallback.getCallCount()); + + // Set some text in the search box, then continue startup. + setUrlBarText(searchActivity, "about:blank"); + ThreadUtils.runOnUiThreadBlocking(new Runnable() { + @Override + public void run() { + searchActivity.finishDeferredInitialization(); + } + }); + + // Let the initialization finish completely. + Assert.assertEquals( + 1, mTestDelegate.shouldDelayNativeInitializationCallback.getCallCount()); + Assert.assertEquals(1, mTestDelegate.showSearchEngineDialogIfNeededCallback.getCallCount()); + mTestDelegate.onFinishDeferredInitializationCallback.waitForCallback(0); + + // Omnibox suggestions should appear now. + final SearchActivityLocationBarLayout locationBar = + (SearchActivityLocationBarLayout) searchActivity.findViewById( + R.id.search_location_bar); + OmniboxTestUtils.waitForOmniboxSuggestions(locationBar); + + // Hitting enter should submit the URL and kick the user to the browser. + final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation(); + ActivityMonitor browserMonitor = + new ActivityMonitor(ChromeTabbedActivity.class.getName(), null, false); + instrumentation.addMonitor(browserMonitor); + UrlBar urlBar = (UrlBar) searchActivity.findViewById(R.id.url_bar); + KeyUtils.singleKeyEventView(instrumentation, urlBar, KeyEvent.KEYCODE_ENTER); + waitForChromeTabbedActivityToStart(browserMonitor); + } + + @Test + @SmallTest + public void testRealPromoDialogInterruption() throws Exception { + // Start the Activity. It should pause when the promo dialog appears. + mTestDelegate.shouldShowRealSearchDialog = true; + final SearchActivity searchActivity = startSearchActivity(); + mTestDelegate.shouldDelayNativeInitializationCallback.waitForCallback(0); + mTestDelegate.showSearchEngineDialogIfNeededCallback.waitForCallback(0); + mTestDelegate.onPromoDialogShownCallback.waitForCallback(0); + Assert.assertEquals(0, mTestDelegate.onFinishDeferredInitializationCallback.getCallCount()); + + // Set some text in the search box, then select the first engine to continue startup. + setUrlBarText(searchActivity, "about:blank"); + DefaultSearchEngineDialogHelperUtils.clickOnFirstEngine( + mTestDelegate.shownPromoDialog.findViewById(android.R.id.content)); + + // Let the initialization finish completely. + Assert.assertEquals( + 1, mTestDelegate.shouldDelayNativeInitializationCallback.getCallCount()); + Assert.assertEquals(1, mTestDelegate.showSearchEngineDialogIfNeededCallback.getCallCount()); + mTestDelegate.onFinishDeferredInitializationCallback.waitForCallback(0); + + // Omnibox suggestions should appear now. + final SearchActivityLocationBarLayout locationBar = + (SearchActivityLocationBarLayout) searchActivity.findViewById( + R.id.search_location_bar); + OmniboxTestUtils.waitForOmniboxSuggestions(locationBar); + + // Hitting enter should submit the URL and kick the user to the browser. + final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation(); + ActivityMonitor browserMonitor = + new ActivityMonitor(ChromeTabbedActivity.class.getName(), null, false); + instrumentation.addMonitor(browserMonitor); + UrlBar urlBar = (UrlBar) searchActivity.findViewById(R.id.url_bar); + KeyUtils.singleKeyEventView(instrumentation, urlBar, KeyEvent.KEYCODE_ENTER); + waitForChromeTabbedActivityToStart(browserMonitor); + } + + @Test + @SmallTest + public void testRealPromoDialogDismissWithoutSelection() throws Exception { + // Start the Activity. It should pause when the promo dialog appears. + mTestDelegate.shouldShowRealSearchDialog = true; + startSearchActivity(); + mTestDelegate.shouldDelayNativeInitializationCallback.waitForCallback(0); + mTestDelegate.showSearchEngineDialogIfNeededCallback.waitForCallback(0); + mTestDelegate.onPromoDialogShownCallback.waitForCallback(0); + Assert.assertEquals(0, mTestDelegate.onFinishDeferredInitializationCallback.getCallCount()); + + // Dismiss the dialog without acting on it. + mTestDelegate.shownPromoDialog.dismiss(); + + // SearchActivity should realize the failure case and prevent the user from using it. + CriteriaHelper.pollInstrumentationThread(Criteria.equals(0, new Callable<Integer>() { + @Override + public Integer call() throws Exception { + return ApplicationStatus.getRunningActivities().size(); + } + })); + Assert.assertEquals( + 1, mTestDelegate.shouldDelayNativeInitializationCallback.getCallCount()); + Assert.assertEquals(1, mTestDelegate.showSearchEngineDialogIfNeededCallback.getCallCount()); + Assert.assertEquals(0, mTestDelegate.onFinishDeferredInitializationCallback.getCallCount()); + } + + @Test + @SmallTest + public void testNewIntentDiscardsQuery() throws Exception { + final SearchActivity searchActivity = startSearchActivity(); + setUrlBarText(searchActivity, "first query"); + final SearchActivityLocationBarLayout locationBar = + (SearchActivityLocationBarLayout) searchActivity.findViewById( + R.id.search_location_bar); + OmniboxTestUtils.waitForOmniboxSuggestions(locationBar); + + // Start the Activity again by firing another copy of the same Intent. + SearchActivity restartedActivity = startSearchActivity(1); + Assert.assertEquals(searchActivity, restartedActivity); + + // The query should be wiped. + CriteriaHelper.pollUiThread(new Criteria() { + @Override + public boolean isSatisfied() { + UrlBar urlBar = (UrlBar) searchActivity.findViewById(R.id.url_bar); + return TextUtils.isEmpty(urlBar.getText()); + } + }); + } + + private SearchActivity startSearchActivity() throws Exception { + return startSearchActivity(0); + } + + private SearchActivity startSearchActivity(int expectedCallCount) throws Exception { + final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation(); + ActivityMonitor searchMonitor = + new ActivityMonitor(SearchActivity.class.getName(), null, false); + instrumentation.addMonitor(searchMonitor); + + // The SearchActivity shouldn't have started yet. + Assert.assertEquals(expectedCallCount, + mTestDelegate.shouldDelayNativeInitializationCallback.getCallCount()); + Assert.assertEquals(expectedCallCount, + mTestDelegate.showSearchEngineDialogIfNeededCallback.getCallCount()); + Assert.assertEquals(expectedCallCount, + mTestDelegate.onFinishDeferredInitializationCallback.getCallCount()); + + // Fire the Intent to start up the SearchActivity. + Intent intent = new Intent(); + SearchWidgetProvider.startSearchActivity(intent, false); + Activity searchActivity = instrumentation.waitForMonitorWithTimeout( + searchMonitor, CriteriaHelper.DEFAULT_MAX_TIME_TO_POLL); + Assert.assertNotNull("Activity didn't start", searchActivity); + Assert.assertTrue("Wrong activity started", searchActivity instanceof SearchActivity); + instrumentation.removeMonitor(searchMonitor); + return (SearchActivity) searchActivity; + } + + private void waitForChromeTabbedActivityToStart(ActivityMonitor browserMonitor) + throws Exception { + final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation(); final Activity browserActivity = instrumentation.waitForMonitorWithTimeout( browserMonitor, CriteriaHelper.DEFAULT_MAX_TIME_TO_POLL); Assert.assertNotNull("Activity didn't start", browserActivity); @@ -140,35 +425,6 @@ }); } - private Activity fullyStartSearchActivity() throws Exception { - final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation(); - - ActivityMonitor searchMonitor = - new ActivityMonitor(SearchActivity.class.getName(), null, false); - instrumentation.addMonitor(searchMonitor); - - // The SearchActivity shouldn't have started yet. - Assert.assertEquals(0, mTestObserver.onSetContentViewCallback.getCallCount()); - Assert.assertEquals(0, mTestObserver.onFinishNativeInitializationCallback.getCallCount()); - Assert.assertEquals(0, mTestObserver.onFinishDeferredInitializationCallback.getCallCount()); - - // Fire the Intent to start up the SearchActivity. - Intent intent = new Intent(); - SearchWidgetProvider.startSearchActivity(intent, false); - Activity searchActivity = instrumentation.waitForMonitorWithTimeout( - searchMonitor, CriteriaHelper.DEFAULT_MAX_TIME_TO_POLL); - Assert.assertNotNull("Activity didn't start", searchActivity); - Assert.assertTrue("Wrong activity started", searchActivity instanceof SearchActivity); - - // Wait for the Activity fully load. - mTestObserver.onSetContentViewCallback.waitForCallback(0); - mTestObserver.onFinishNativeInitializationCallback.waitForCallback(0); - mTestObserver.onFinishDeferredInitializationCallback.waitForCallback(0); - - instrumentation.removeMonitor(searchMonitor); - return searchActivity; - } - @SuppressLint("SetTextI18n") private void setUrlBarText(final Activity activity, final String url) { ThreadUtils.runOnUiThreadBlocking(new Runnable() {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/searchwidget/SearchWidgetProviderTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/searchwidget/SearchWidgetProviderTest.java index c7f970fb..5429068d 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/searchwidget/SearchWidgetProviderTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/searchwidget/SearchWidgetProviderTest.java
@@ -27,6 +27,7 @@ import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeSwitches; import org.chromium.chrome.browser.firstrun.FirstRunActivity; +import org.chromium.chrome.browser.searchwidget.SearchActivity.SearchActivityDelegate; import org.chromium.chrome.browser.util.IntentUtils; import org.chromium.chrome.test.util.ApplicationTestUtils; import org.chromium.content.browser.test.util.CriteriaHelper; @@ -39,6 +40,13 @@ */ @CommandLineFlags.Add(ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE) public class SearchWidgetProviderTest extends InstrumentationTestCase { + private static class TestSearchDelegate extends SearchActivityDelegate { + @Override + public boolean isActivityDisabledForTests() { + return true; + } + } + private static final class TestDelegate extends SearchWidgetProvider.SearchWidgetProviderDelegate { public static final int[] ALL_IDS = {11684, 20170525}; @@ -91,11 +99,11 @@ public void setUp() throws Exception { super.setUp(); ApplicationTestUtils.setUp(getInstrumentation().getTargetContext(), true); - SearchActivity.disableForTests(); + SearchActivity.setDelegateForTests(new TestSearchDelegate()); mContext = new TestContext(); mDelegate = new TestDelegate(mContext); - SearchWidgetProvider.setDelegateForTest(mDelegate); + SearchWidgetProvider.setActivityDelegateForTest(mDelegate); } @Override
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 62ceb693..9b02091c 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -68,6 +68,7 @@ #include "components/strings/grit/components_strings.h" #include "components/sync/driver/sync_driver_switches.h" #include "components/tracing/common/tracing_switches.h" +#include "components/translate/core/browser/translate_infobar_delegate.h" #include "components/translate/core/browser/translate_manager.h" #include "components/translate/core/browser/translate_prefs.h" #include "components/version_info/version_info.h" @@ -1636,6 +1637,9 @@ flag_descriptions::kPullToRefreshEffectName, flag_descriptions::kPullToRefreshEffectDescription, kOsAndroid, SINGLE_DISABLE_VALUE_TYPE(switches::kDisablePullToRefreshEffect)}, + {"translate-compact-infobar", flag_descriptions::kTranslateCompactUIName, + flag_descriptions::kTranslateCompactUIDescription, kOsAndroid, + FEATURE_VALUE_TYPE(translate::kTranslateCompactUI)}, #endif // OS_ANDROID #if defined(OS_MACOSX) {"enable-translate-new-ux", flag_descriptions::kTranslateNewUxName,
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd index e98b434fc..cd466e5 100644 --- a/chrome/browser/browser_resources.grd +++ b/chrome/browser/browser_resources.grd
@@ -271,6 +271,8 @@ <include name="IDR_MD_BOOKMARKS_APP_HTML" file="resources\md_bookmarks\app.html" type="BINDATA" /> <include name="IDR_MD_BOOKMARKS_APP_JS" file="resources\md_bookmarks\app.js" type="BINDATA" /> <include name="IDR_MD_BOOKMARKS_BOOKMARKS_HTML" file="resources\md_bookmarks\bookmarks.html" type="BINDATA" /> + <include name="IDR_MD_BOOKMARKS_COMMAND_MANAGER_HTML" file="resources\md_bookmarks\command_manager.html" type="BINDATA" /> + <include name="IDR_MD_BOOKMARKS_COMMAND_MANAGER_JS" file="resources\md_bookmarks\command_manager.js" type="BINDATA" /> <include name="IDR_MD_BOOKMARKS_CONSTANTS_HTML" file="resources\md_bookmarks\constants.html" type="BINDATA" /> <include name="IDR_MD_BOOKMARKS_CONSTANTS_JS" file="resources\md_bookmarks\constants.js" type="BINDATA" /> <include name="IDR_MD_BOOKMARKS_DND_MANAGER_HTML" file="resources\md_bookmarks\dnd_manager.html" type="BINDATA" />
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index b7dca30..48e50e0 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -1347,6 +1347,11 @@ const char kPullToRefreshEffectDescription[] = "Page reloads triggered by vertically overscrolling content."; +const char kTranslateCompactUIName[] = "New Translate Infobar"; + +const char kTranslateCompactUIDescription[] = + "Enable the new Translate compact infobar UI."; + #endif // defined(OS_ANDROID) #if defined(OS_MACOSX)
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index dba02b3..f8dd1a1 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -1495,6 +1495,12 @@ // Description of the flag for the pull-to-refresh effect. extern const char kPullToRefreshEffectDescription[]; +// Name of the flag for the translate compact infobar. +extern const char kTranslateCompactUIName[]; + +// Description of the flag for translate compact infobar. +extern const char kTranslateCompactUIDescription[]; + #endif // defined(OS_ANDROID) #if defined(OS_MACOSX)
diff --git a/chrome/browser/resources/md_bookmarks/app.html b/chrome/browser/resources/md_bookmarks/app.html index faea753..4d997e4 100644 --- a/chrome/browser/resources/md_bookmarks/app.html +++ b/chrome/browser/resources/md_bookmarks/app.html
@@ -1,6 +1,7 @@ <link rel="import" href="chrome://resources/html/polymer.html"> <link rel="import" href="chrome://resources/html/cr/ui/splitter.html"> <link rel="import" href="chrome://bookmarks/api_listener.html"> +<link rel="import" href="chrome://bookmarks/command_manager.html"> <link rel="import" href="chrome://bookmarks/constants.html"> <link rel="import" href="chrome://bookmarks/dnd_manager.html"> <link rel="import" href="chrome://bookmarks/list.html"> @@ -64,6 +65,7 @@ <bookmarks-list></bookmarks-list> </div> <bookmarks-router></bookmarks-router> + <bookmarks-command-manager></bookmarks-command-manager> </template> <script src="chrome://bookmarks/app.js"></script> </dom-module>
diff --git a/chrome/browser/resources/md_bookmarks/command_manager.html b/chrome/browser/resources/md_bookmarks/command_manager.html new file mode 100644 index 0000000..2ec008d --- /dev/null +++ b/chrome/browser/resources/md_bookmarks/command_manager.html
@@ -0,0 +1,35 @@ +<link rel="import" href="chrome://resources/html/polymer.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_action_menu/cr_action_menu.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_lazy_render/cr_lazy_render.html"> +<link rel="import" href="chrome://resources/polymer/v1_0/iron-a11y-keys-behavior/iron-a11y-keys-behavior.html"> +<link rel="import" href="chrome://bookmarks/edit_dialog.html"> +<link rel="import" href="chrome://bookmarks/store_client.html"> + +<dom-module id="bookmarks-command-manager"> + <template> + <dialog is="cr-action-menu" id="dropdown" on-mousedown="onMenuMousedown_"> + <button class="dropdown-item" + command="edit" + hidden$="[[!canExecute('edit', menuIds_)]]" + on-tap="onCommandClick_"> + [[getEditActionLabel_(menuIds_)]] + </button> + <button class="dropdown-item" + command="copy" + hidden$="[[!canExecute('copy', menuIds_)]]" + on-tap="onCommandClick_"> + $i18n{menuCopyURL} + </button> + <button class="dropdown-item" + command="delete" + hidden$="[[!canExecute('delete', menuIds_)]]" + on-tap="onCommandClick_"> + $i18n{menuDelete} + </button> + </dialog> + <template is="cr-lazy-render" id="editDialog"> + <bookmarks-edit-dialog></bookmarks-edit-dialog> + </template> + </template> + <script src="chrome://bookmarks/command_manager.js"></script> +</dom-module>
diff --git a/chrome/browser/resources/md_bookmarks/command_manager.js b/chrome/browser/resources/md_bookmarks/command_manager.js new file mode 100644 index 0000000..9c5e564 --- /dev/null +++ b/chrome/browser/resources/md_bookmarks/command_manager.js
@@ -0,0 +1,200 @@ +// 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. + +Polymer({ + is: 'bookmarks-command-manager', + + behaviors: [ + bookmarks.StoreClient, + ], + + properties: { + /** @type {Set<string>} */ + menuIds_: Object, + }, + + attached: function() { + /** @private {function(!Event)} */ + this.boundOnOpenItemMenu_ = this.onOpenItemMenu_.bind(this); + document.addEventListener('open-item-menu', this.boundOnOpenItemMenu_); + + /** @private {function(!Event)} */ + this.boundOnKeydown_ = this.onKeydown_.bind(this); + document.addEventListener('keydown', this.boundOnKeydown_); + + /** @private {Object<Command, string>} */ + this.shortcuts_ = {}; + this.shortcuts_[Command.EDIT] = cr.isMac ? 'enter' : 'f2'; + this.shortcuts_[Command.COPY] = cr.isMac ? 'meta+c' : 'ctrl+c'; + this.shortcuts_[Command.DELETE] = cr.isMac ? 'delete backspace' : 'delete'; + }, + + detached: function() { + document.removeEventListener('open-item-menu', this.boundOnOpenItemMenu_); + document.removeEventListener('keydown', this.boundOnKeydown_); + }, + + /** + * Display the command context menu at (|x|, |y|) in window co-ordinates. + * Commands will execute on the currently selected items. + * @param {number} x + * @param {number} y + */ + openCommandMenuAtPosition: function(x, y) { + this.menuIds_ = this.getState().selection.items; + /** @type {!CrActionMenuElement} */ (this.$.dropdown) + .showAtPosition({top: y, left: x}); + }, + + /** + * Display the command context menu positioned to cover the |target| + * element. Commands will execute on the currently selected items. + * @param {!Element} target + */ + openCommandMenuAtElement: function(target) { + this.menuIds_ = this.getState().selection.items; + /** @type {!CrActionMenuElement} */ (this.$.dropdown).showAt(target); + }, + + closeCommandMenu: function() { + /** @type {!CrActionMenuElement} */ (this.$.dropdown).close(); + }, + + //////////////////////////////////////////////////////////////////////////// + // Command handlers: + + /** + * @param {Command} command + * @param {!Set<string>} itemIds + * @return {boolean} + */ + canExecute: function(command, itemIds) { + switch (command) { + case Command.EDIT: + return itemIds.size == 1; + case Command.COPY: + return itemIds.size == 1 && + this.containsMatchingNode_(itemIds, function(node) { + return !!node.url; + }); + case Command.DELETE: + return itemIds.size > 0; + default: + return false; + } + }, + + /** + * @param {Command} command + * @param {!Set<string>} itemIds + */ + handle: function(command, itemIds) { + switch (command) { + case Command.EDIT: + var id = Array.from(itemIds)[0]; + /** @type {!BookmarksEditDialogElement} */ (this.$.editDialog.get()) + .showEditDialog(this.getState().nodes[id]); + break; + case Command.COPY: + var idList = Array.from(itemIds); + chrome.bookmarkManagerPrivate.copy(idList, function() { + // TODO(jiaxi): Add toast later. + }); + break; + case Command.DELETE: + // TODO(tsergeant): Filter IDs so we don't try to delete children of + // something else already being deleted. + chrome.bookmarkManagerPrivate.removeTrees( + Array.from(itemIds), function() { + // TODO(jiaxi): Add toast later. + }); + break; + } + + }, + + //////////////////////////////////////////////////////////////////////////// + // Private functions: + + /** + * @param {!Set<string>} itemIds + * @param {function(BookmarkNode):boolean} predicate + * @return {boolean} True if any node in |itemIds| returns true for + * |predicate|. + */ + containsMatchingNode_: function(itemIds, predicate) { + var nodes = this.getState().nodes; + + return Array.from(itemIds).some(function(id) { + return predicate(nodes[id]); + }); + }, + + /** + * @param {Event} e + * @private + */ + onOpenItemMenu_: function(e) { + if (e.detail.targetElement) { + this.openCommandMenuAtElement(e.detail.targetElement); + } else { + this.openCommandMenuAtPosition(e.detail.x, e.detail.y); + } + }, + + /** + * @param {Event} e + * @private + */ + onCommandClick_: function(e) { + this.closeCommandMenu(); + this.handle(e.target.getAttribute('command'), assert(this.menuIds_)); + }, + + /** + * @param {!Event} e + * @private + */ + onKeydown_: function(e) { + var selection = this.getState().selection.items; + // TODO(tsergeant): Prevent keyboard shortcuts when a dialog is open or text + // field is focused. + for (var commandName in this.shortcuts_) { + var shortcut = this.shortcuts_[commandName]; + if (Polymer.IronA11yKeysBehavior.keyboardEventMatchesKeys(e, shortcut) && + this.canExecute(commandName, selection)) { + this.handle(commandName, selection); + + e.stopPropagation(); + e.preventDefault(); + return; + } + } + }, + + /** + * Close the menu on mousedown so clicks can propagate to the underlying UI. + * This allows the user to right click the list while a context menu is + * showing and get another context menu. + * @param {Event} e + * @private + */ + onMenuMousedown_: function(e) { + if (e.path[0] != this.$.dropdown) + return; + + this.$.dropdown.close(); + }, + + /** @private */ + getEditActionLabel_: function() { + if (this.menuIds_.size > 1) + return; + + var id = Array.from(this.menuIds_)[0]; + var itemUrl = this.getState().nodes[id].url; + var label = itemUrl ? 'menuEdit' : 'menuRename'; + return loadTimeData.getString(label); + }, +});
diff --git a/chrome/browser/resources/md_bookmarks/compiled_resources2.gyp b/chrome/browser/resources/md_bookmarks/compiled_resources2.gyp index 957eacb..8bdfa9f 100644 --- a/chrome/browser/resources/md_bookmarks/compiled_resources2.gyp +++ b/chrome/browser/resources/md_bookmarks/compiled_resources2.gyp
@@ -38,6 +38,19 @@ 'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'], }, { + 'target_name': 'command_manager', + 'dependencies': [ + '<(DEPTH)/third_party/polymer/v1_0/components-chromium/iron-a11y-keys-behavior/compiled_resources2.gyp:iron-a11y-keys-behavior-extracted', + '<(DEPTH)/ui/webui/resources/cr_elements/cr_action_menu/compiled_resources2.gyp:cr_action_menu', + '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr', + '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:load_time_data', + '<(EXTERNS_GYP):bookmark_manager_private', + 'edit_dialog', + 'store_client', + ], + 'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'], + }, + { 'target_name': 'constants', 'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'] }, @@ -79,6 +92,7 @@ '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:icon', '<(EXTERNS_GYP):chrome_extensions', 'actions', + 'command_manager', 'store_client', ], 'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'], @@ -86,12 +100,8 @@ { 'target_name': 'list', 'dependencies': [ - '<(DEPTH)/ui/webui/resources/cr_elements/cr_action_menu/compiled_resources2.gyp:cr_action_menu', '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:load_time_data', - '<(EXTERNS_GYP):bookmark_manager_private', - '<(EXTERNS_GYP):chrome_extensions', 'actions', - 'edit_dialog', 'store_client', ], 'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'],
diff --git a/chrome/browser/resources/md_bookmarks/constants.js b/chrome/browser/resources/md_bookmarks/constants.js index 95949765..692cd352 100644 --- a/chrome/browser/resources/md_bookmarks/constants.js +++ b/chrome/browser/resources/md_bookmarks/constants.js
@@ -15,6 +15,16 @@ BELOW: 4, }; +/** + * @enum {string} + * @const + */ +var Command = { + EDIT: 'edit', + COPY: 'copy', + DELETE: 'delete', +}; + /** @const */ var LOCAL_STORAGE_CLOSED_FOLDERS_KEY = 'closedState';
diff --git a/chrome/browser/resources/md_bookmarks/item.js b/chrome/browser/resources/md_bookmarks/item.js index d04e0ac..c0be484 100644 --- a/chrome/browser/resources/md_bookmarks/item.js +++ b/chrome/browser/resources/md_bookmarks/item.js
@@ -71,7 +71,6 @@ this.fire('open-item-menu', { x: e.clientX, y: e.clientY, - item: this.item_, }); }, @@ -85,7 +84,6 @@ this.itemId, false, false, this.getState())); this.fire('open-item-menu', { targetElement: e.target, - item: this.item_, }); },
diff --git a/chrome/browser/resources/md_bookmarks/list.html b/chrome/browser/resources/md_bookmarks/list.html index 226eec07..a408a4b8 100644 --- a/chrome/browser/resources/md_bookmarks/list.html +++ b/chrome/browser/resources/md_bookmarks/list.html
@@ -1,9 +1,6 @@ <link rel="import" href="chrome://resources/html/polymer.html"> -<link rel="import" href="chrome://resources/cr_elements/cr_action_menu/cr_action_menu.html"> -<link rel="import" href="chrome://resources/cr_elements/cr_lazy_render/cr_lazy_render.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button-light.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/shadow.html"> -<link rel="import" href="chrome://bookmarks/edit_dialog.html"> <link rel="import" href="chrome://bookmarks/item.html"> <link rel="import" href="chrome://bookmarks/shared_style.html"> <link rel="import" href="chrome://bookmarks/store_client.html"> @@ -36,18 +33,6 @@ justify-content: center; } </style> - <dialog is="cr-action-menu" id="dropdown" on-mousedown="onMenuMousedown_"> - <button class="dropdown-item" on-tap="onEditTap_"> - [[getEditActionLabel_(menuItem_)]] - </button> - <button class="dropdown-item" on-tap="onCopyURLTap_" - hidden$="[[!menuItem_.url]]"> - $i18n{menuCopyURL} - </button> - <button class="dropdown-item" on-tap="onDeleteTap_"> - $i18n{menuDelete} - </button> - </dialog> <div id="bookmarksCard" hidden$="[[isEmptyList_(displayedList_.length)]]"> <template is="dom-repeat" items="[[displayedList_]]" as="id"> <bookmarks-item item-id="[[id]]" draggable="true"> @@ -58,9 +43,6 @@ hidden$="[[!isEmptyList_(displayedList_.length)]]"> [[emptyListMessage_(searchTerm_)]] </div> - <template is="cr-lazy-render" id="editDialog"> - <bookmarks-edit-dialog></bookmarks-edit-dialog> - </template> </template> <script src="chrome://bookmarks/list.js"></script> </dom-module>
diff --git a/chrome/browser/resources/md_bookmarks/list.js b/chrome/browser/resources/md_bookmarks/list.js index c38b6da..365487a 100644 --- a/chrome/browser/resources/md_bookmarks/list.js +++ b/chrome/browser/resources/md_bookmarks/list.js
@@ -10,9 +10,6 @@ ], properties: { - /** @type {BookmarkNode} */ - menuItem_: Object, - /** @private {Array<string>} */ displayedList_: { type: Array, @@ -29,7 +26,6 @@ listeners: { 'click': 'deselectItems_', - 'open-item-menu': 'onOpenItemMenu_', }, attached: function() { @@ -46,81 +42,6 @@ return this.$.message; }, - /** - * @param {Event} e - * @private - */ - onOpenItemMenu_: function(e) { - this.menuItem_ = e.detail.item; - var menu = /** @type {!CrActionMenuElement} */ ( - this.$.dropdown); - if (e.detail.targetElement) { - menu.showAt(/** @type {!Element} */ (e.detail.targetElement)); - } else { - menu.showAtPosition({ - top: e.detail.y, - left: e.detail.x, - }); - } - }, - - /** @private */ - onEditTap_: function() { - this.closeDropdownMenu_(); - /** @type {BookmarksEditDialogElement} */ (this.$.editDialog.get()) - .showEditDialog(this.menuItem_); - }, - - /** @private */ - onCopyURLTap_: function() { - var idList = [this.menuItem_.id]; - chrome.bookmarkManagerPrivate.copy(idList, function() { - // TODO(jiaxi): Add toast later. - }); - this.closeDropdownMenu_(); - }, - - /** @private */ - onDeleteTap_: function() { - if (this.menuItem_.url) { - chrome.bookmarks.remove(this.menuItem_.id, function() { - // TODO(jiaxi): Add toast later. - }.bind(this)); - } else { - chrome.bookmarks.removeTree(this.menuItem_.id, function() { - // TODO(jiaxi): Add toast later. - }.bind(this)); - } - this.closeDropdownMenu_(); - }, - - /** - * Close the menu on mousedown so clicks can propagate to the underlying UI. - * This allows the user to right click the list while a context menu is - * showing and get another context menu. - * @param {Event} e - * @private - */ - onMenuMousedown_: function(e) { - if (e.path[0] != this.$.dropdown) - return; - - this.closeDropdownMenu_(); - }, - - /** @private */ - closeDropdownMenu_: function() { - var menu = /** @type {!CrActionMenuElement} */ ( - this.$.dropdown); - menu.close(); - }, - - /** @private */ - getEditActionLabel_: function() { - var label = this.menuItem_.url ? 'menuEdit' : 'menuRename'; - return loadTimeData.getString(label); - }, - /** @private */ emptyListMessage_: function() { var emptyListMessage = this.searchTerm_ ? 'noSearchResults' : 'emptyList';
diff --git a/chrome/browser/safe_browsing/protocol_manager.cc b/chrome/browser/safe_browsing/protocol_manager.cc index 770e6cf..46e5382 100644 --- a/chrome/browser/safe_browsing/protocol_manager.cc +++ b/chrome/browser/safe_browsing/protocol_manager.cc
@@ -29,6 +29,7 @@ #include "net/base/net_errors.h" #include "net/http/http_response_headers.h" #include "net/http/http_status_code.h" +#include "net/traffic_annotation/network_traffic_annotation.h" #include "net/url_request/url_fetcher.h" #include "net/url_request/url_request_context_getter.h" #include "net/url_request/url_request_status.h" @@ -76,6 +77,37 @@ return base::TimeDelta::FromMinutes(finch_next_update_interval_minutes); } +constexpr net::NetworkTrafficAnnotationTag + kChunkBackupRequestTrafficAnnotation = net::DefineNetworkTrafficAnnotation( + "safe_browsing_chunk_backup_request", + R"( + semantics { + sender: "Safe Browsing" + description: + "Safe Browsing updates its local database of bad sites every 30 " + "minutes or so. It aims to keep all users up-to-date with the same " + "set of hash-prefixes of bad URLs." + trigger: + "On a timer, approximately every 30 minutes." + data: + "The state of the local DB is sent so the server can send just the " + "changes. This doesn't include any user data." + destination: GOOGLE_OWNED_SERVICE + } + policy { + cookies_allowed: true + cookies_store: "Safe Browsing cookie store" + setting: + "Users can disable Safe Browsing by unchecking 'Protect you and " + "your device from dangerous sites' in Chromium settings under " + "Privacy. The feature is enabled by default." + chrome_policy { + SafeBrowsingEnabled { + policy_options {mode: MANDATORY} + SafeBrowsingEnabled: false + } + } + })"); } // namespace namespace safe_browsing { @@ -219,8 +251,41 @@ return; } GURL gethash_url = GetHashUrl(reporting_level); - std::unique_ptr<net::URLFetcher> fetcher_ptr = net::URLFetcher::Create( - url_fetcher_id_++, gethash_url, net::URLFetcher::POST, this); + net::NetworkTrafficAnnotationTag traffic_annotation = + net::DefineNetworkTrafficAnnotation("safe_browsing_get_full_hash", R"( + semantics { + sender: "Safe Browsing" + description: + "When Safe Browsing detects that a URL might be dangerous based on " + "its local database, it sends a partial hash of that URL to Google " + "to verify it before showing a warning to the user. This partial " + "hash does not expose the URL to Google." + trigger: + "When a resource URL matches the local hash-prefix database of " + "potential threats (malware, phishing etc), and the full-hash " + "result is not already cached, this will be sent." + data: + "The 32-bit hash prefix of any potentially bad URLs. The URLs " + "themselves are not sent." + destination: GOOGLE_OWNED_SERVICE + } + policy { + cookies_allowed: true + cookies_store: "Safe Browsing cookie store" + setting: + "Users can disable Safe Browsing by unchecking 'Protect you and " + "your device from dangerous sites' in Chromium settings under " + "Privacy. The feature is enabled by default." + chrome_policy { + SafeBrowsingEnabled { + policy_options {mode: MANDATORY} + SafeBrowsingEnabled: false + } + } + })"); + std::unique_ptr<net::URLFetcher> fetcher_ptr = + net::URLFetcher::Create(url_fetcher_id_++, gethash_url, + net::URLFetcher::POST, this, traffic_annotation); net::URLFetcher* fetcher = fetcher_ptr.get(); data_use_measurement::DataUseUserData::AttachToFetcher( fetcher, data_use_measurement::DataUseUserData::SAFE_BROWSING); @@ -588,8 +653,37 @@ backup_update_reason_ = backup_update_reason; GURL backup_update_url = BackupUpdateUrl(backup_update_reason); - request_ = net::URLFetcher::Create(url_fetcher_id_++, backup_update_url, - net::URLFetcher::POST, this); + net::NetworkTrafficAnnotationTag traffic_annotation = + net::DefineNetworkTrafficAnnotation("safe_browsing_backup_request", R"( + semantics { + sender: "Safe Browsing" + description: + "Safe Browsing issues multi-step update requests to Google every " + "30 minutes or so to get the latest database of hashes of bad URLs." + trigger: + "On a timer, approximately every 30 minutes." + data: + "The state of the local DB is sent so the server can send just the " + "changes. This doesn't include any user data." + destination: GOOGLE_OWNED_SERVICE + } + policy { + cookies_allowed: true + cookies_store: "Safe Browsing cookie store" + setting: + "Users can disable Safe Browsing by unchecking 'Protect you and " + "your device from dangerous sites' in Chromium settings under " + "Privacy. The feature is enabled by default." + chrome_policy { + SafeBrowsingEnabled { + policy_options {mode: MANDATORY} + SafeBrowsingEnabled: false + } + } + })"); + request_ = + net::URLFetcher::Create(url_fetcher_id_++, backup_update_url, + net::URLFetcher::POST, this, traffic_annotation); data_use_measurement::DataUseUserData::AttachToFetcher( request_.get(), data_use_measurement::DataUseUserData::SAFE_BROWSING); request_->SetLoadFlags(net::LOAD_DISABLE_CACHE); @@ -617,7 +711,8 @@ GURL chunk_url = NextChunkUrl(next_chunk.url); request_type_ = CHUNK_REQUEST; request_ = net::URLFetcher::Create(url_fetcher_id_++, chunk_url, - net::URLFetcher::GET, this); + net::URLFetcher::GET, this, + kChunkBackupRequestTrafficAnnotation); data_use_measurement::DataUseUserData::AttachToFetcher( request_.get(), data_use_measurement::DataUseUserData::SAFE_BROWSING); request_->SetLoadFlags(net::LOAD_DISABLE_CACHE); @@ -670,7 +765,8 @@ GURL update_url = UpdateUrl(extended_reporting_level); request_ = net::URLFetcher::Create(url_fetcher_id_++, update_url, - net::URLFetcher::POST, this); + net::URLFetcher::POST, this, + kChunkBackupRequestTrafficAnnotation); data_use_measurement::DataUseUserData::AttachToFetcher( request_.get(), data_use_measurement::DataUseUserData::SAFE_BROWSING); request_->SetLoadFlags(net::LOAD_DISABLE_CACHE);
diff --git a/chrome/browser/ui/webui/md_bookmarks/md_bookmarks_ui.cc b/chrome/browser/ui/webui/md_bookmarks/md_bookmarks_ui.cc index f0f3c50..6dc90f2e 100644 --- a/chrome/browser/ui/webui/md_bookmarks/md_bookmarks_ui.cc +++ b/chrome/browser/ui/webui/md_bookmarks/md_bookmarks_ui.cc
@@ -80,6 +80,10 @@ source->AddResourcePath("api_listener.js", IDR_MD_BOOKMARKS_API_LISTENER_JS); source->AddResourcePath("app.html", IDR_MD_BOOKMARKS_APP_HTML); source->AddResourcePath("app.js", IDR_MD_BOOKMARKS_APP_JS); + source->AddResourcePath("command_manager.html", + IDR_MD_BOOKMARKS_COMMAND_MANAGER_HTML); + source->AddResourcePath("command_manager.js", + IDR_MD_BOOKMARKS_COMMAND_MANAGER_JS); source->AddResourcePath("constants.html", IDR_MD_BOOKMARKS_CONSTANTS_HTML); source->AddResourcePath("constants.js", IDR_MD_BOOKMARKS_CONSTANTS_JS); source->AddResourcePath("dnd_manager.html",
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index f3d8c032..4dd9237 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -157,7 +157,6 @@ "//skia", "//sql", "//sql:test_support", - "//sql:test_support", "//testing/gmock", "//testing/gtest", "//third_party/leveldatabase", @@ -3342,7 +3341,6 @@ "//components/browser_sync:test_support", "//components/component_updater:test_support", "//components/content_settings/core/test:test_support", - "//components/content_settings/core/test:test_support", "//components/data_reduction_proxy/core/browser:test_support", "//components/data_use_measurement/core", "//components/metrics/proto",
diff --git a/chrome/test/data/webui/md_bookmarks/command_manager_test.js b/chrome/test/data/webui/md_bookmarks/command_manager_test.js new file mode 100644 index 0000000..07e414cb --- /dev/null +++ b/chrome/test/data/webui/md_bookmarks/command_manager_test.js
@@ -0,0 +1,114 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +suite('<bookmarks-command-manager>', function() { + var commandManager; + var store; + var lastCommand; + var lastCommandIds; + + function assertLastCommand(command, ids) { + assertEquals(lastCommand, command); + if (ids) + assertDeepEquals(normalizeSet(lastCommandIds), ids); + lastCommand = null; + lastCommandIds = null; + } + + suiteSetup(function() { + // Overwrite bookmarkManagerPrivate APIs which will crash if called with + // fake data. + chrome.bookmarkManagerPrivate.copy = function() {}; + chrome.bookmarkManagerPrivate.removeTrees = function() {}; + }); + + setup(function() { + store = new bookmarks.TestStore({ + nodes: testTree(createFolder( + '1', + [ + createFolder('11', []), + createFolder('12', []), + createItem('13'), + ])), + }); + bookmarks.Store.instance_ = store; + + commandManager = document.createElement('bookmarks-command-manager'); + + var realHandle = commandManager.handle.bind(commandManager); + commandManager.handle = function(command, itemIds) { + lastCommand = command; + lastCommandIds = itemIds; + realHandle(command, itemIds); + }; + replaceBody(commandManager); + }); + + test('can only copy single URL items', function() { + assertFalse(commandManager.canExecute(Command.COPY, new Set(['11']))); + assertFalse(commandManager.canExecute(Command.COPY, new Set(['11', '13']))); + assertTrue(commandManager.canExecute(Command.COPY, new Set(['13']))); + }); + + test('context menu hides invalid commands', function() { + store.data.selection.items = new Set(['11', '13']); + store.notifyObservers(); + + commandManager.openCommandMenuAtPosition(0, 0); + var commandHidden = {}; + commandManager.root.querySelectorAll('.dropdown-item').forEach(element => { + commandHidden[element.getAttribute('command')] = element.hidden; + }); + + // With a folder and an item selected, the only available context menu item + // is 'Delete'. + assertTrue(commandHidden['edit']); + assertTrue(commandHidden['copy']); + assertFalse(commandHidden['delete']); + }); + + test('keyboard shortcuts trigger when valid', function() { + var modifier = cr.isMac ? 'meta' : 'ctrl'; + + store.data.selection.items = new Set(['13']); + store.notifyObservers(); + + MockInteractions.pressAndReleaseKeyOn(document, 67, modifier, 'c'); + assertLastCommand('copy', ['13']); + + // Doesn't trigger when a folder is selected. + store.data.selection.items = new Set(['11']); + store.notifyObservers(); + + MockInteractions.pressAndReleaseKeyOn(document, 67, modifier, 'c'); + assertLastCommand(null); + + // Doesn't trigger when nothing is selected. + store.data.selection.items = new Set(); + store.notifyObservers(); + + MockInteractions.pressAndReleaseKeyOn(document, 67, modifier, 'c'); + assertLastCommand(null); + }); + + test('delete command triggers', function() { + store.data.selection.items = new Set(['12', '13']); + store.notifyObservers(); + + MockInteractions.pressAndReleaseKeyOn(document, 46, '', 'Delete'); + assertLastCommand('delete', ['12', '13']); + }); + + test('edit command triggers', function() { + var key = cr.isMac ? 'Enter' : 'F2'; + var keyCode = cr.isMac ? 13 : 113; + + store.data.selection.items = new Set(['11']); + store.notifyObservers(); + + MockInteractions.pressAndReleaseKeyOn(document, keyCode, '', key); + assertLastCommand('edit', ['11']); + }); +});
diff --git a/chrome/test/data/webui/md_bookmarks/md_bookmarks_browsertest.js b/chrome/test/data/webui/md_bookmarks/md_bookmarks_browsertest.js index 745cf0b..9c017d5 100644 --- a/chrome/test/data/webui/md_bookmarks/md_bookmarks_browsertest.js +++ b/chrome/test/data/webui/md_bookmarks/md_bookmarks_browsertest.js
@@ -55,6 +55,20 @@ mocha.run(); }); +function MaterialBookmarksCommandManagerTest() {} + +MaterialBookmarksCommandManagerTest.prototype = { + __proto__: MaterialBookmarksBrowserTest.prototype, + + extraLibraries: MaterialBookmarksBrowserTest.prototype.extraLibraries.concat([ + 'command_manager_test.js', + ]), +}; + +TEST_F('MaterialBookmarksCommandManagerTest', 'All', function() { + mocha.run(); +}); + function MaterialBookmarksDNDManagerTest() {} MaterialBookmarksDNDManagerTest.prototype = {
diff --git a/chromecast/renderer/BUILD.gn b/chromecast/renderer/BUILD.gn index bb5a1c4..ea4bd19f 100644 --- a/chromecast/renderer/BUILD.gn +++ b/chromecast/renderer/BUILD.gn
@@ -30,7 +30,6 @@ "//chromecast/common/media", "//chromecast/crash", "//chromecast/media", - "//chromecast/media", "//components/network_hints/renderer", "//content/public/common", "//content/public/renderer",
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc index 9ffb7f87..ba98d5c 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc
@@ -249,7 +249,9 @@ data_use_measurement::DataUseUserData::AttachToFetcher( fetcher_.get(), data_use_measurement::DataUseUserData::DATA_REDUCTION_PROXY); - fetcher_->SetLoadFlags(net::LOAD_DISABLE_CACHE | net::LOAD_BYPASS_PROXY); + fetcher_->SetLoadFlags(net::LOAD_DISABLE_CACHE | net::LOAD_BYPASS_PROXY | + net::LOAD_DO_NOT_SEND_COOKIES | + net::LOAD_DO_NOT_SAVE_COOKIES); fetcher_->SetRequestContext(url_request_context_getter_.get()); // Configure max retries to be at most kMaxRetries times for 5xx errors. static const int kMaxRetries = 5; @@ -304,7 +306,9 @@ data_use_measurement::DataUseUserData::AttachToFetcher( fetcher_.get(), data_use_measurement::DataUseUserData::DATA_REDUCTION_PROXY); - fetcher_->SetLoadFlags(net::LOAD_BYPASS_CACHE); + fetcher_->SetLoadFlags(net::LOAD_BYPASS_CACHE | + net::LOAD_DO_NOT_SEND_COOKIES | + net::LOAD_DO_NOT_SAVE_COOKIES); fetcher_->SetRequestContext(url_request_context_getter_.get()); // |fetcher| should not retry on 5xx errors. fetcher_->SetAutomaticallyRetryOn5xx(false);
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client.cc index 2b58c6b1..26f38eb5 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client.cc
@@ -412,7 +412,8 @@ data_use_measurement::DataUseUserData::AttachToFetcher( fetcher.get(), data_use_measurement::DataUseUserData::DATA_REDUCTION_PROXY); - fetcher->SetLoadFlags(net::LOAD_BYPASS_PROXY); + fetcher->SetLoadFlags(net::LOAD_BYPASS_PROXY | net::LOAD_DO_NOT_SEND_COOKIES | + net::LOAD_DO_NOT_SAVE_COOKIES); fetcher->SetUploadData("application/x-protobuf", request_body); DCHECK(url_request_context_getter_); fetcher->SetRequestContext(url_request_context_getter_);
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_pingback_client.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_pingback_client.cc index 4d21e66..fb72e14 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_pingback_client.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_pingback_client.cc
@@ -196,7 +196,9 @@ data_use_measurement::DataUseUserData::AttachToFetcher( current_fetcher_.get(), data_use_measurement::DataUseUserData::DATA_REDUCTION_PROXY); - current_fetcher_->SetLoadFlags(net::LOAD_BYPASS_PROXY); + current_fetcher_->SetLoadFlags(net::LOAD_BYPASS_PROXY | + net::LOAD_DO_NOT_SEND_COOKIES | + net::LOAD_DO_NOT_SAVE_COOKIES); current_fetcher_->SetUploadData("application/x-protobuf", serialized_request); current_fetcher_->SetRequestContext(url_request_context_); // |current_fetcher_| should not retry on 5xx errors since the server may
diff --git a/components/safe_browsing_db/v4_get_hash_protocol_manager.cc b/components/safe_browsing_db/v4_get_hash_protocol_manager.cc index eba742b..77488c2c 100644 --- a/components/safe_browsing_db/v4_get_hash_protocol_manager.cc +++ b/components/safe_browsing_db/v4_get_hash_protocol_manager.cc
@@ -17,6 +17,7 @@ #include "net/base/load_flags.h" #include "net/http/http_response_headers.h" #include "net/http/http_status_code.h" +#include "net/traffic_annotation/network_traffic_annotation.h" #include "net/url_request/url_fetcher.h" #include "net/url_request/url_request_context_getter.h" @@ -301,8 +302,41 @@ net::HttpRequestHeaders headers; GetHashUrlAndHeaders(req_base64, &gethash_url, &headers); - std::unique_ptr<net::URLFetcher> owned_fetcher = net::URLFetcher::Create( - url_fetcher_id_++, gethash_url, net::URLFetcher::GET, this); + net::NetworkTrafficAnnotationTag traffic_annotation = + net::DefineNetworkTrafficAnnotation("safe_browsing_v4_get_hash", R"( + semantics { + sender: "Safe Browsing" + description: + "When Safe Browsing detects that a URL might be dangerous based on " + "its local database, it sends a partial hash of that URL to Google " + "to verify it before showing a warning to the user. This partial " + "hash does not expose the URL to Google." + trigger: + "When a resource URL matches the local hash-prefix database of " + "potential threats (malware, phishing etc), and the full-hash " + "result is not already cached, this will be sent." + data: + "The 32-bit hash prefix of any potentially bad URLs. The URLs " + "themselves are not sent." + destination: GOOGLE_OWNED_SERVICE + } + policy { + cookies_allowed: true + cookies_store: "Safe Browsing cookie store" + setting: + "Users can disable Safe Browsing by unchecking 'Protect you and " + "your device from dangerous sites' in Chromium settings under " + "Privacy. The feature is enabled by default." + chrome_policy { + SafeBrowsingEnabled { + policy_options {mode: MANDATORY} + SafeBrowsingEnabled: false + } + } + })"); + std::unique_ptr<net::URLFetcher> owned_fetcher = + net::URLFetcher::Create(url_fetcher_id_++, gethash_url, + net::URLFetcher::GET, this, traffic_annotation); net::URLFetcher* fetcher = owned_fetcher.get(); pending_hash_requests_[fetcher].reset(new FullHashCallbackInfo( cached_full_hash_infos, prefixes_to_request, std::move(owned_fetcher),
diff --git a/components/safe_browsing_db/v4_update_protocol_manager.cc b/components/safe_browsing_db/v4_update_protocol_manager.cc index e72eb44..3d485bdd 100644 --- a/components/safe_browsing_db/v4_update_protocol_manager.cc +++ b/components/safe_browsing_db/v4_update_protocol_manager.cc
@@ -17,6 +17,7 @@ #include "net/base/load_flags.h" #include "net/http/http_response_headers.h" #include "net/http/http_status_code.h" +#include "net/traffic_annotation/network_traffic_annotation.h" #include "net/url_request/url_fetcher.h" #include "net/url_request/url_request_context_getter.h" @@ -311,8 +312,37 @@ net::HttpRequestHeaders headers; GetUpdateUrlAndHeaders(req_base64, &update_url, &headers); - std::unique_ptr<net::URLFetcher> fetcher = net::URLFetcher::Create( - url_fetcher_id_++, update_url, net::URLFetcher::GET, this); + net::NetworkTrafficAnnotationTag traffic_annotation = + net::DefineNetworkTrafficAnnotation("safe_browsing_g4_update", R"( + semantics { + sender: "Safe Browsing" + description: + "Safe Browsing issues a request to Google every 30 minutes or so " + "to get the latest database of hashes of bad URLs." + trigger: + "On a timer, approximately every 30 minutes." + data: + "The state of the local DB is sent so the server can send just " + "the changes. This doesn't include any user data." + destination: GOOGLE_OWNED_SERVICE + } + policy { + cookies_allowed: true + cookies_store: "Safe Browsing cookie store" + setting: + "Users can disable Safe Browsing by unchecking 'Protect you and " + "your device from dangerous sites' in Chromium settings under " + "Privacy. The feature is enabled by default." + chrome_policy { + SafeBrowsingEnabled { + policy_options {mode: MANDATORY} + SafeBrowsingEnabled: false + } + } + })"); + std::unique_ptr<net::URLFetcher> fetcher = + net::URLFetcher::Create(url_fetcher_id_++, update_url, + net::URLFetcher::GET, this, traffic_annotation); fetcher->SetExtraRequestHeaders(headers.ToString()); data_use_measurement::DataUseUserData::AttachToFetcher( fetcher.get(), data_use_measurement::DataUseUserData::SAFE_BROWSING);
diff --git a/components/translate/core/browser/translate_infobar_delegate.cc b/components/translate/core/browser/translate_infobar_delegate.cc index c945a5c692..5fa42a5c 100644 --- a/components/translate/core/browser/translate_infobar_delegate.cc +++ b/components/translate/core/browser/translate_infobar_delegate.cc
@@ -28,10 +28,6 @@ namespace { -// Feature flag for "Translate UI Redesign" project. -const base::Feature kTranslateCompactUI{"TranslateCompactUI", - base::FEATURE_DISABLED_BY_DEFAULT}; - // Counts used to decide whether infobars should be shown. // Android and iOS implementations do not offer a drop down (for space reasons), // so we are more aggressive about showing the shortcut to never translate. @@ -52,6 +48,9 @@ } // namespace +const base::Feature kTranslateCompactUI{"TranslateCompactUI", + base::FEATURE_DISABLED_BY_DEFAULT}; + const size_t TranslateInfoBarDelegate::kNoIndex = TranslateUIDelegate::kNoIndex; TranslateInfoBarDelegate::~TranslateInfoBarDelegate() {
diff --git a/components/translate/core/browser/translate_infobar_delegate.h b/components/translate/core/browser/translate_infobar_delegate.h index eb74271..1e48a64 100644 --- a/components/translate/core/browser/translate_infobar_delegate.h +++ b/components/translate/core/browser/translate_infobar_delegate.h
@@ -29,6 +29,9 @@ namespace translate { +// Feature flag for "Translate Compact Infobar UI" project. +extern const base::Feature kTranslateCompactUI; + class TranslateDriver; class TranslateManager;
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index 16803c32..47c55207 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -1293,6 +1293,8 @@ "resource_context_impl.h", "screen_orientation/screen_orientation_provider.cc", "screen_orientation/screen_orientation_provider.h", + "service_manager/common_browser_interfaces.cc", + "service_manager/common_browser_interfaces.h", "service_manager/merge_dictionary.cc", "service_manager/merge_dictionary.h", "service_manager/service_manager_context.cc",
diff --git a/content/browser/browser_context.cc b/content/browser/browser_context.cc index 509baef..3f68fd7d 100644 --- a/content/browser/browser_context.cc +++ b/content/browser/browser_context.cc
@@ -29,6 +29,7 @@ #include "content/browser/indexed_db/indexed_db_context_impl.h" #include "content/browser/loader/resource_dispatcher_host_impl.h" #include "content/browser/push_messaging/push_messaging_router.h" +#include "content/browser/service_manager/common_browser_interfaces.h" #include "content/browser/storage_partition_impl_map.h" #include "content/common/child_process_host_impl.h" #include "content/public/browser/blob_handle.h" @@ -492,6 +493,8 @@ for (const auto& entry : services) { connection->AddEmbeddedService(entry.first, entry.second); } + + RegisterCommonBrowserInterfaces(connection); connection->Start(); } }
diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc index 4977be2..da5a242b 100644 --- a/content/browser/gpu/gpu_process_host.cc +++ b/content/browser/gpu/gpu_process_host.cc
@@ -346,12 +346,6 @@ auto task_runner = BrowserThread::GetTaskRunnerForThread(BrowserThread::UI); registry_.AddInterface(base::Bind(&FieldTrialRecorder::Create), task_runner); - registry_.AddInterface( - base::Bind( - &memory_instrumentation::CoordinatorImpl::BindCoordinatorRequest, - base::Unretained( - memory_instrumentation::CoordinatorImpl::GetInstance())), - task_runner); #if defined(OS_ANDROID) registry_.AddInterface( base::Bind(&BindJavaInterface<media::mojom::AndroidOverlayProvider>),
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index 3121685..5731df87c 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -52,7 +52,6 @@ #include "build/build_config.h" #include "cc/base/switches.h" #include "cc/output/buffer_to_texture_target_map.h" -#include "components/discardable_memory/service/discardable_shared_memory_manager.h" #include "components/metrics/single_sample_metrics.h" #include "components/tracing/common/tracing_switches.h" #include "content/browser/appcache/appcache_dispatcher_host.h" @@ -183,7 +182,6 @@ #include "mojo/public/cpp/bindings/strong_binding.h" #include "net/url_request/url_request_context_getter.h" #include "ppapi/features/features.h" -#include "services/resource_coordinator/memory/coordinator/coordinator_impl.h" #include "services/service_manager/embedder/switches.h" #include "services/service_manager/public/cpp/binder_registry.h" #include "services/service_manager/public/cpp/connector.h" @@ -1341,25 +1339,8 @@ base::Bind(&WebSocketManager::CreateWebSocket, GetID(), MSG_ROUTING_NONE)); - // Chrome browser process only provides DiscardableSharedMemory service when - // Chrome is not running in mus+ash. - if (!service_manager::ServiceManagerIsRemote()) { - discardable_memory::DiscardableSharedMemoryManager* manager = - BrowserMainLoop::GetInstance()->discardable_shared_memory_manager(); - registry->AddInterface( - base::Bind(&discardable_memory::DiscardableSharedMemoryManager::Bind, - base::Unretained(manager))); - } - AddUIThreadInterface(registry.get(), base::Bind(&FieldTrialRecorder::Create)); - AddUIThreadInterface( - registry.get(), - base::Bind( - &memory_instrumentation::CoordinatorImpl::BindCoordinatorRequest, - base::Unretained( - memory_instrumentation::CoordinatorImpl::GetInstance()))); - associated_interfaces_.reset(new AssociatedInterfaceRegistryImpl()); GetContentClient()->browser()->ExposeInterfacesToRenderer( registry.get(), associated_interfaces_.get(), this);
diff --git a/content/browser/service_manager/common_browser_interfaces.cc b/content/browser/service_manager/common_browser_interfaces.cc new file mode 100644 index 0000000..afc81bb --- /dev/null +++ b/content/browser/service_manager/common_browser_interfaces.cc
@@ -0,0 +1,98 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/service_manager/common_browser_interfaces.h" + +#include <memory> +#include <utility> + +#include "base/callback.h" +#include "base/memory/ptr_util.h" +#include "base/memory/ref_counted.h" +#include "base/task_runner.h" +#include "components/discardable_memory/service/discardable_shared_memory_manager.h" +#include "content/browser/browser_main_loop.h" +#include "content/public/common/connection_filter.h" +#include "content/public/common/service_manager_connection.h" +#include "mojo/public/cpp/bindings/interface_request.h" +#include "services/resource_coordinator/memory/coordinator/coordinator_impl.h" +#include "services/service_manager/public/cpp/binder_registry.h" + +namespace content { + +namespace { + +void BindMemoryCoordinatorRequest( + const service_manager::BindSourceInfo& source_info, + memory_instrumentation::mojom::CoordinatorRequest request) { + auto* coordinator = memory_instrumentation::CoordinatorImpl::GetInstance(); + if (coordinator) + coordinator->BindCoordinatorRequest(source_info, std::move(request)); +} + +class ConnectionFilterImpl : public ConnectionFilter { + public: + ConnectionFilterImpl() + : main_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()) { + RegisterMainThreadInterface(base::Bind(&BindMemoryCoordinatorRequest)); + + auto* browser_main_loop = BrowserMainLoop::GetInstance(); + if (browser_main_loop) { + auto* manager = browser_main_loop->discardable_shared_memory_manager(); + if (manager) { + registry_.AddInterface(base::Bind( + &discardable_memory::DiscardableSharedMemoryManager::Bind, + base::Unretained(manager))); + } + } + } + + ~ConnectionFilterImpl() override {} + + private: + template <typename Interface> + using InterfaceBinder = + base::Callback<void(const service_manager::BindSourceInfo&, + mojo::InterfaceRequest<Interface>)>; + + // ConnectionFilter: + void OnBindInterface(const service_manager::BindSourceInfo& source_info, + const std::string& interface_name, + mojo::ScopedMessagePipeHandle* interface_pipe, + service_manager::Connector* connector) override { + if (registry_.CanBindInterface(interface_name)) { + registry_.BindInterface(source_info, interface_name, + std::move(*interface_pipe)); + } + } + + template <typename Interface> + static void BindOnTaskRunner( + const scoped_refptr<base::TaskRunner>& task_runner, + const InterfaceBinder<Interface>& binder, + const service_manager::BindSourceInfo& source_info, + mojo::InterfaceRequest<Interface> request) { + task_runner->PostTask( + FROM_HERE, base::BindOnce(binder, source_info, std::move(request))); + } + + template <typename Interface> + void RegisterMainThreadInterface(const InterfaceBinder<Interface>& binder) { + registry_.AddInterface(base::Bind(&BindOnTaskRunner<Interface>, + main_thread_task_runner_, binder)); + } + + const scoped_refptr<base::TaskRunner> main_thread_task_runner_; + service_manager::BinderRegistry registry_; + + DISALLOW_COPY_AND_ASSIGN(ConnectionFilterImpl); +}; + +} // namespace + +void RegisterCommonBrowserInterfaces(ServiceManagerConnection* connection) { + connection->AddConnectionFilter(base::MakeUnique<ConnectionFilterImpl>()); +} + +} // namespace content
diff --git a/content/browser/service_manager/common_browser_interfaces.h b/content/browser/service_manager/common_browser_interfaces.h new file mode 100644 index 0000000..0e826dec --- /dev/null +++ b/content/browser/service_manager/common_browser_interfaces.h
@@ -0,0 +1,18 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_SERVICE_MANAGER_COMMON_BROWSER_INTERFACES_H_ +#define CONTENT_BROWSER_SERVICE_MANAGER_COMMON_BROWSER_INTERFACES_H_ + +namespace content { + +class ServiceManagerConnection; + +// Registers interface binders for browser-side interfaces that are common to +// all child process types. +void RegisterCommonBrowserInterfaces(ServiceManagerConnection* connection); + +} // namespace content + +#endif // CONTENT_BROWSER_SERVICE_MANAGER_COMMON_BROWSER_INTERFACES_H_
diff --git a/content/browser/service_manager/service_manager_context.cc b/content/browser/service_manager/service_manager_context.cc index 98372cb..eeb81396 100644 --- a/content/browser/service_manager/service_manager_context.cc +++ b/content/browser/service_manager/service_manager_context.cc
@@ -19,6 +19,7 @@ #include "base/strings/utf_string_conversions.h" #include "content/browser/child_process_launcher.h" #include "content/browser/gpu/gpu_process_host.h" +#include "content/browser/service_manager/common_browser_interfaces.h" #include "content/browser/service_manager/merge_dictionary.h" #include "content/browser/wake_lock/wake_lock_context_host.h" #include "content/common/service_manager/service_manager_connection_impl.h" @@ -275,6 +276,7 @@ ServiceManagerConnection::SetForProcess(ServiceManagerConnection::Create( mojo::MakeRequest(&root_browser_service), BrowserThread::GetTaskRunnerForThread(BrowserThread::IO))); + auto* browser_connection = ServiceManagerConnection::GetForProcess(); service_manager::mojom::PIDReceiverPtr pid_receiver; packaged_services_connection_->GetConnector()->StartService( @@ -313,8 +315,7 @@ // This is safe to assign directly from any thread, because // ServiceManagerContext must be constructed before anyone can call // GetConnectorForIOThread(). - g_io_thread_connector.Get() = - ServiceManagerConnection::GetForProcess()->GetConnector()->Clone(); + g_io_thread_connector.Get() = browser_connection->GetConnector()->Clone(); ContentBrowserClient::OutOfProcessServiceMap sandboxed_services; GetContentClient() @@ -360,12 +361,14 @@ shape_detection::mojom::kServiceName)); packaged_services_connection_->Start(); - ServiceManagerConnection::GetForProcess()->Start(); + + RegisterCommonBrowserInterfaces(browser_connection); + browser_connection->Start(); if (network_service_enabled) { // Start the network service process as soon as possible, since it is // critical to start up performance. - ServiceManagerConnection::GetForProcess()->GetConnector()->StartService( + browser_connection->GetConnector()->StartService( mojom::kNetworkServiceName); } }
diff --git a/content/child/DEPS b/content/child/DEPS index da61fe55..270ae0dd 100644 --- a/content/child/DEPS +++ b/content/child/DEPS
@@ -14,7 +14,6 @@ "+services/device/public/interfaces", "+services/resource_coordinator", "+services/service_manager", - "+services/service_manager", "+v8/include/v8.h" ]
diff --git a/content/renderer/gpu/render_widget_compositor.cc b/content/renderer/gpu/render_widget_compositor.cc index e3450e5..9733a8c 100644 --- a/content/renderer/gpu/render_widget_compositor.cc +++ b/content/renderer/gpu/render_widget_compositor.cc
@@ -87,6 +87,57 @@ namespace content { namespace { +using ReportTimeCallback = base::Callback<void(bool, double)>; + +double MonotonicallyIncreasingTime() { + return static_cast<double>(base::TimeTicks::Now().ToInternalValue()) / + base::Time::kMicrosecondsPerSecond; +} + +class ReportTimeSwapPromise : public cc::SwapPromise { + public: + ReportTimeSwapPromise( + ReportTimeCallback callback, + const scoped_refptr<base::SingleThreadTaskRunner>& task_runner); + ~ReportTimeSwapPromise() override; + + void DidActivate() override {} + void WillSwap(cc::CompositorFrameMetadata* metadata) override {} + void DidSwap() override; + DidNotSwapAction DidNotSwap(DidNotSwapReason reason) override; + + int64_t TraceId() const override; + + private: + ReportTimeCallback callback_; + scoped_refptr<base::SingleThreadTaskRunner> task_runner_; + + DISALLOW_COPY_AND_ASSIGN(ReportTimeSwapPromise); +}; + +ReportTimeSwapPromise::ReportTimeSwapPromise( + ReportTimeCallback callback, + const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) + : callback_(callback), task_runner_(task_runner) {} + +ReportTimeSwapPromise::~ReportTimeSwapPromise() {} + +void ReportTimeSwapPromise::DidSwap() { + task_runner_->PostTask( + FROM_HERE, + base::BindOnce(callback_, true, MonotonicallyIncreasingTime())); +} + +cc::SwapPromise::DidNotSwapAction ReportTimeSwapPromise::DidNotSwap( + cc::SwapPromise::DidNotSwapReason reason) { + task_runner_->PostTask(FROM_HERE, base::BindOnce(callback_, false, 0)); + return cc::SwapPromise::DidNotSwapAction::BREAK_PROMISE; +} + +int64_t ReportTimeSwapPromise::TraceId() const { + return 0; +} + bool GetSwitchValueAsInt(const base::CommandLine& command_line, const std::string& switch_string, int min_value, @@ -1152,4 +1203,9 @@ layer_tree_host_->SetLocalSurfaceId(local_surface_id); } +void RenderWidgetCompositor::NotifySwapTime(ReportTimeCallback callback) { + QueueSwapPromise(base::MakeUnique<ReportTimeSwapPromise>( + std::move(callback), base::ThreadTaskRunnerHandle::Get())); +} + } // namespace content
diff --git a/content/renderer/gpu/render_widget_compositor.h b/content/renderer/gpu/render_widget_compositor.h index a36b5f02..a2692a09 100644 --- a/content/renderer/gpu/render_widget_compositor.h +++ b/content/renderer/gpu/render_widget_compositor.h
@@ -53,6 +53,8 @@ : NON_EXPORTED_BASE(public blink::WebLayerTreeView), NON_EXPORTED_BASE(public cc::LayerTreeHostClient), NON_EXPORTED_BASE(public cc::LayerTreeHostSingleThreadClient) { + using ReportTimeCallback = base::Callback<void(bool, double)>; + public: // Attempt to construct and initialize a compositor instance for the widget // with the given settings. Returns NULL if initialization fails. @@ -167,6 +169,7 @@ void SetShowPaintRects(bool show) override; void SetShowDebugBorders(bool show) override; void SetShowScrollBottleneckRects(bool show) override; + void NotifySwapTime(ReportTimeCallback callback) override; void UpdateBrowserControlsState(blink::WebBrowserControlsState constraints, blink::WebBrowserControlsState current, @@ -240,6 +243,8 @@ cc::FrameSinkId frame_sink_id_; base::WeakPtrFactory<RenderWidgetCompositor> weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(RenderWidgetCompositor); }; } // namespace content
diff --git a/content/renderer/pepper/pepper_device_enumeration_host_helper.cc b/content/renderer/pepper/pepper_device_enumeration_host_helper.cc index 2fd9a3b..dc4967c 100644 --- a/content/renderer/pepper/pepper_device_enumeration_host_helper.cc +++ b/content/renderer/pepper/pepper_device_enumeration_host_helper.cc
@@ -35,6 +35,9 @@ if (!owner->document_url_.is_valid()) return; + if (!owner->delegate_) + return; + requested_ = true; // Note that the callback passed into @@ -44,7 +47,6 @@ // EnumerateDevicesCallbackBody() to ensure that we always call |callback| // asynchronously. sync_call_ = true; - DCHECK(owner->delegate_); owner->delegate_->EnumerateDevices( owner->device_type_, owner->document_url_, base::Bind(&ScopedEnumerationRequest::EnumerateDevicesCallbackBody, @@ -91,9 +93,11 @@ if (!owner_->document_url_.is_valid()) return; + if (!owner->delegate_) + return; + requested_ = true; - DCHECK(owner_->delegate_); // |callback| is never called synchronously by StartMonitoringDevices(), // so it is OK to pass it directly, even if |callback| destroys |this|. subscription_id_ = owner_->delegate_->StartMonitoringDevices(
diff --git a/content/utility/DEPS b/content/utility/DEPS index 26456d68..95eef3e 100644 --- a/content/utility/DEPS +++ b/content/utility/DEPS
@@ -5,7 +5,6 @@ "+content/public/utility", "+services/data_decoder", "+services/service_manager", - "+services/service_manager", "+services/shape_detection", "+sandbox/win/src", ]
diff --git a/headless/BUILD.gn b/headless/BUILD.gn index 7b3788b2..57342a3 100644 --- a/headless/BUILD.gn +++ b/headless/BUILD.gn
@@ -3,8 +3,8 @@ # found in the LICENSE file. import("//build/config/chrome_build.gni") -import("//headless/headless.gni") import("//build/util/process_version.gni") +import("//headless/headless.gni") import("//mojo/public/tools/bindings/mojom.gni") import("//printing/features/features.gni") import("//testing/test.gni") @@ -21,7 +21,7 @@ group("headless") { deps = [ - "//headless:headless_lib", + ":headless_lib", ] } @@ -69,7 +69,7 @@ action("embed_resources") { # TODO(altimin): Consider zipping file here, it can reduce size up to 80%. - script = "//headless/lib/embed_data.py" + script = "lib/embed_data.py" inputs = [ "$root_out_dir/headless_lib.pak", @@ -168,7 +168,7 @@ } action("gen_devtools_client_api") { - script = "//headless/lib/browser/devtools_api/client_api_generator.py" + script = "lib/browser/devtools_api/client_api_generator.py" deps = [ "//third_party/WebKit/Source/core/inspector:protocol_version", ] @@ -484,9 +484,9 @@ deps = [ ":embedder_mojo_for_testing", ":headless_browser_tests_pak", + ":headless_lib", "//base", "//content/test:test_support", - "//headless:headless_lib", "//testing/gmock", "//testing/gtest", ] @@ -504,7 +504,7 @@ ] deps = [ - "//headless:headless_lib", + ":headless_lib", ] configs += [ ":headless_implementation" ] @@ -516,7 +516,7 @@ ] deps = [ - "//headless:headless_shell_lib", + ":headless_shell_lib", ] if (is_win) { @@ -545,6 +545,6 @@ ] deps = [ - "//headless:headless_shell_lib", + ":headless_shell_lib", ] }
diff --git a/ios/chrome/browser/tabs/BUILD.gn b/ios/chrome/browser/tabs/BUILD.gn index 0555e75..113d24f 100644 --- a/ios/chrome/browser/tabs/BUILD.gn +++ b/ios/chrome/browser/tabs/BUILD.gn
@@ -153,7 +153,6 @@ "//ios/chrome/browser/browser_state", "//ios/chrome/browser/favicon", "//ios/chrome/browser/find_in_page", - "//ios/chrome/browser/find_in_page", "//ios/chrome/browser/history", "//ios/chrome/browser/infobars", "//ios/chrome/browser/reading_list",
diff --git a/ios/web_view/BUILD.gn b/ios/web_view/BUILD.gn index 9d053cd..334aee2 100644 --- a/ios/web_view/BUILD.gn +++ b/ios/web_view/BUILD.gn
@@ -80,7 +80,6 @@ ":packed_resources", "//base", "//components/infobars/core", - "//components/infobars/core", "//components/keyed_service/core", "//components/keyed_service/ios", "//components/pref_registry", @@ -90,17 +89,14 @@ "//components/translate/ios/browser", "//google_apis", "//ios/net", - "//ios/net", "//ios/web", "//ios/web:reload_type", "//ios/web:user_agent", - "//ios/web:user_agent", "//ios/web/public/app", "//net", "//net:extras", "//ui/base", "//url", - "//url", ] ios_framework_bundle("web_view") {
diff --git a/mash/catalog_viewer/BUILD.gn b/mash/catalog_viewer/BUILD.gn index cd8d1f4..71979a3 100644 --- a/mash/catalog_viewer/BUILD.gn +++ b/mash/catalog_viewer/BUILD.gn
@@ -19,7 +19,6 @@ "//mojo/public/cpp/bindings", "//services/catalog/public/interfaces", "//services/service_manager/public/cpp", - "//services/service_manager/public/cpp", "//services/service_manager/public/interfaces", "//ui/resources", "//ui/views", @@ -41,7 +40,6 @@ "//base", "//mojo/public/cpp/bindings", "//services/service_manager/public/cpp", - "//services/service_manager/public/cpp", "//services/service_manager/public/interfaces", "//ui/views/mus:for_mojo_application", ]
diff --git a/mash/example/views_examples/BUILD.gn b/mash/example/views_examples/BUILD.gn index 1da75c5..c531369 100644 --- a/mash/example/views_examples/BUILD.gn +++ b/mash/example/views_examples/BUILD.gn
@@ -20,7 +20,6 @@ "//mash/public/interfaces", "//mojo/public/cpp/bindings", "//services/service_manager/public/cpp", - "//services/service_manager/public/cpp", "//services/ui/public/interfaces", "//skia", "//ui/gfx",
diff --git a/mash/session/BUILD.gn b/mash/session/BUILD.gn index b2052a79..5aa3ecf4 100644 --- a/mash/session/BUILD.gn +++ b/mash/session/BUILD.gn
@@ -22,7 +22,6 @@ "//mojo/common", "//mojo/public/cpp/bindings", "//services/service_manager/public/cpp", - "//services/service_manager/public/cpp", ] data_deps = [ @@ -47,7 +46,6 @@ "//mojo/common", "//mojo/public/cpp/bindings", "//services/service_manager/public/cpp", - "//services/service_manager/public/cpp", ] }
diff --git a/mash/task_viewer/BUILD.gn b/mash/task_viewer/BUILD.gn index d0cec0e..790e6b0 100644 --- a/mash/task_viewer/BUILD.gn +++ b/mash/task_viewer/BUILD.gn
@@ -36,7 +36,6 @@ "//base", "//mojo/public/cpp/bindings", "//services/service_manager/public/cpp", - "//services/service_manager/public/cpp", "//services/service_manager/public/interfaces", "//ui/views/mus:for_mojo_application", ]
diff --git a/pdf/DEPS b/pdf/DEPS index c62be37..b7a8a17 100644 --- a/pdf/DEPS +++ b/pdf/DEPS
@@ -1,6 +1,5 @@ include_rules = [ "+chrome/common/content_restriction.h", - "+chrome/common/url_constants.h", "+net", "+ppapi", "+ui/base/window_open_disposition.h",
diff --git a/pdf/out_of_process_instance.cc b/pdf/out_of_process_instance.cc index f9c2e98d..8a597e5 100644 --- a/pdf/out_of_process_instance.cc +++ b/pdf/out_of_process_instance.cc
@@ -21,7 +21,6 @@ #include "base/strings/utf_string_conversions.h" #include "base/values.h" #include "chrome/common/content_restriction.h" -#include "chrome/common/url_constants.h" #include "net/base/escape.h" #include "pdf/pdf.h" #include "ppapi/c/dev/ppb_cursor_control_dev.h" @@ -49,6 +48,7 @@ namespace { +const char kChromePrint[] = "chrome://print/"; const char kChromeExtension[] = "chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai"; @@ -221,8 +221,8 @@ int ExtractPrintPreviewPageIndex(base::StringPiece src_url) { // Sample |src_url| format: chrome://print/id/page_index/print.pdf std::vector<base::StringPiece> url_substr = - base::SplitStringPiece(src_url.substr(strlen(chrome::kChromeUIPrintURL)), - "/", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); + base::SplitStringPiece(src_url.substr(strlen(kChromePrint)), "/", + base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); if (url_substr.size() != 3) return -1; @@ -236,7 +236,7 @@ } bool IsPrintPreviewUrl(base::StringPiece url) { - return url.starts_with(chrome::kChromeUIPrintURL); + return url.starts_with(kChromePrint); } void ScalePoint(float scale, pp::Point* point) {
diff --git a/services/service_manager/public/cpp/service_context.cc b/services/service_manager/public/cpp/service_context.cc index 74683c57..4e81468a 100644 --- a/services/service_manager/public/cpp/service_context.cc +++ b/services/service_manager/public/cpp/service_context.cc
@@ -41,12 +41,7 @@ ServiceContext::~ServiceContext() {} void ServiceContext::SetQuitClosure(const base::Closure& closure) { - if (service_quit_) { - // CAUTION: May delete |this|. - closure.Run(); - } else { - quit_closure_ = closure; - } + quit_closure_ = closure; } void ServiceContext::RequestQuit() { @@ -61,7 +56,6 @@ } void ServiceContext::QuitNow() { - service_quit_ = true; if (binding_.is_bound()) binding_.Close(); if (!quit_closure_.is_null()) {
diff --git a/services/service_manager/public/cpp/service_context.h b/services/service_manager/public/cpp/service_context.h index bec2ba18..451f1ad 100644 --- a/services/service_manager/public/cpp/service_context.h +++ b/services/service_manager/public/cpp/service_context.h
@@ -129,14 +129,6 @@ // is unbound and therefore invalid until OnStart() is called. mojom::ServiceControlAssociatedPtr service_control_; - // The Service may call QuitNow() before SetConnectionLostClosure(), and the - // latter is expected to invoke the closure immediately in that case. This is - // used to track that condition. - // - // TODO(rockot): Figure out who depends on this behavior and make them stop. - // It's weird and shouldn't be necessary. - bool service_quit_ = false; - // The closure to run when QuitNow() is invoked. May delete |this|. base::Closure quit_closure_;
diff --git a/services/service_manager/tests/lifecycle/package.cc b/services/service_manager/tests/lifecycle/package.cc index 799cf1d..ece551b 100644 --- a/services/service_manager/tests/lifecycle/package.cc +++ b/services/service_manager/tests/lifecycle/package.cc
@@ -72,8 +72,7 @@ service_manager_connection_closed_callback_.Run(); context()->QuitNow(); // This only closed our relationship with the service manager, existing - // |bindings_| - // remain active. + // |bindings_| remain active. } void BindingLost() {
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index 7dd724db..ad0f0ac 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -2340,26 +2340,14 @@ crbug.com/698077 inspector/sources/debugger/debug-inlined-scripts.html [ NeedsManualRebaseline ] # Working on getting the CSP tests going: -crbug.com/694525 external/wpt/content-security-policy [ Skip ] -crbug.com/694525 external/wpt/content-security-policy/child-src [ Pass ] -crbug.com/694525 external/wpt/content-security-policy/connect-src [ Pass ] -crbug.com/694525 external/wpt/content-security-policy/embedded-enforcement [ Pass ] +crbug.com/694525 external/wpt/content-security-policy/base-uri [ Skip ] +crbug.com/694525 external/wpt/content-security-policy/blink-contrib [ Skip ] +crbug.com/694525 external/wpt/content-security-policy/blink-contrib-2 [ Skip ] crbug.com/694525 external/wpt/content-security-policy/embedded-enforcement/embedding_csp-header-invalid-format.html [ Skip ] -crbug.com/694525 external/wpt/content-security-policy/font-src [ Pass ] -crbug.com/694525 external/wpt/content-security-policy/frame-ancestors [ Pass ] -crbug.com/694525 external/wpt/content-security-policy/generic [ Pass ] -crbug.com/694525 external/wpt/content-security-policy/img-src [ Pass ] -crbug.com/694525 external/wpt/content-security-policy/inside-worker [ Pass ] -crbug.com/694525 external/wpt/content-security-policy/media-src [ Pass ] -crbug.com/694525 external/wpt/content-security-policy/meta [ Pass ] -crbug.com/694525 external/wpt/content-security-policy/navigation [ Pass ] -crbug.com/694525 external/wpt/content-security-policy/script-src [ Pass ] +crbug.com/694525 external/wpt/content-security-policy/object-src [ Skip ] +crbug.com/694525 external/wpt/content-security-policy/reporting [ Skip ] crbug.com/694525 external/wpt/content-security-policy/script-src/script-src-1_10.html [ Skip ] crbug.com/694525 external/wpt/content-security-policy/script-src/script-src-strict_dynamic_in_img-src.html [ Skip ] -crbug.com/694525 external/wpt/content-security-policy/securitypolicyviolation [ Pass ] -crbug.com/694525 external/wpt/content-security-policy/style-src [ Pass ] -crbug.com/694525 external/wpt/content-security-policy/svg [ Pass ] -crbug.com/694525 external/wpt/content-security-policy/worker-src [ Pass ] # These policies are not implemented yet. crbug.com/627968 external/wpt/referrer-policy/same-origin/ [ Skip ] @@ -2471,9 +2459,6 @@ crbug.com/626703 external/wpt/XMLHttpRequest/abort-after-stop.htm [ Timeout ] crbug.com/626703 external/wpt/XMLHttpRequest/event-readystatechange-loaded.htm [ Failure Timeout ] crbug.com/626703 external/wpt/XMLHttpRequest/send-authentication-existing-session-manual.htm [ Skip ] -crbug.com/626703 external/wpt/content-security-policy/inside-worker/shared-inheritance.html [ Timeout ] -crbug.com/626703 external/wpt/content-security-policy/inside-worker/shared-script.html [ Timeout ] -crbug.com/626703 external/wpt/content-security-policy/securitypolicyviolation/inside-shared-worker.html [ Timeout ] crbug.com/626703 crbug.com/717157 external/wpt/fetch/api/basic/integrity-sharedworker.html [ Crash Timeout ] crbug.com/626703 external/wpt/html/browsers/offline/no-appcache-in-shared-workers-historical.html [ Timeout ] crbug.com/626703 external/wpt/html/webappapis/scripting/processing-model-2/unhandled-promise-rejections/promise-rejection-events.sharedworker.html [ Timeout ]
diff --git a/third_party/WebKit/LayoutTests/http/tests/worklet/webexposed/global-interface-listing-paint-worklet-expected.txt b/third_party/WebKit/LayoutTests/http/tests/worklet/webexposed/global-interface-listing-paint-worklet-expected.txt index c6197ad..29f90cea 100644 --- a/third_party/WebKit/LayoutTests/http/tests/worklet/webexposed/global-interface-listing-paint-worklet-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/worklet/webexposed/global-interface-listing-paint-worklet-expected.txt
@@ -94,6 +94,9 @@ CONSOLE MESSAGE: line 138: getter y CONSOLE MESSAGE: line 138: getter z CONSOLE MESSAGE: line 138: method constructor +CONSOLE MESSAGE: line 138: setter x +CONSOLE MESSAGE: line 138: setter y +CONSOLE MESSAGE: line 138: setter z CONSOLE MESSAGE: line 138: interface CSSSimpleLength : CSSLengthValue CONSOLE MESSAGE: line 138: getter type CONSOLE MESSAGE: line 138: getter value
diff --git a/third_party/WebKit/LayoutTests/typedcssom/cssScale.html b/third_party/WebKit/LayoutTests/typedcssom/cssScale.html index 30ff36b..cb8ed48 100644 --- a/third_party/WebKit/LayoutTests/typedcssom/cssScale.html +++ b/third_party/WebKit/LayoutTests/typedcssom/cssScale.html
@@ -91,4 +91,13 @@ } }, "Test that asMatrix is constructed correctly for CSSScale."); +test(function() { + var actual = new CSSScale(0, 0, 0); + actual.x = 1; + actual.y = 2; + actual.z = 3; + assert_equals(actual.x, 1); + assert_equals(actual.y, 2); + assert_equals(actual.z, 3); +}, "Test that x, y, z are mutable attributes."); </script>
diff --git a/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload-disabled/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload-disabled/webexposed/global-interface-listing-expected.txt index c5afde5..7fe4d666 100644 --- a/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload-disabled/webexposed/global-interface-listing-expected.txt +++ b/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload-disabled/webexposed/global-interface-listing-expected.txt
@@ -682,6 +682,9 @@ getter y getter z method constructor + setter x + setter y + setter z interface CSSSimpleLength : CSSLengthValue attribute @@toStringTag getter type
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt index 245d07c8..c3d44eb 100644 --- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt +++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
@@ -682,6 +682,9 @@ getter y getter z method constructor + setter x + setter y + setter z interface CSSSimpleLength : CSSLengthValue attribute @@toStringTag getter type
diff --git a/third_party/WebKit/Source/build/scripts/templates/CSSPropertyAPI.h.tmpl b/third_party/WebKit/Source/build/scripts/templates/CSSPropertyAPI.h.tmpl index 1fc68266..40ee4e918 100644 --- a/third_party/WebKit/Source/build/scripts/templates/CSSPropertyAPI.h.tmpl +++ b/third_party/WebKit/Source/build/scripts/templates/CSSPropertyAPI.h.tmpl
@@ -14,20 +14,21 @@ class CSSParserContext; class CSSParserTokenRange; -// We will use this API to represent all functions used for property-specific -// logic inside the blink style engine. All specific properties are subclasses -// of CSSPropertyAPI. +// Base class for property APIs that contain logic for handling individual +// properties. +// The methods declared here are standard methods among property APIs, and can +// be called on a particular property API through a CSSPropertyDescriptor +// object. +// Note that not all methods are implemented by all property APIs. Methods that +// are not implemented on a property API will return nullptr when accessed +// through a CSSPropertyDescriptor. +// See the api_methods field on properties defined in CSSProperties.json5 for a +// definition of which methods are implemented on a property. // -// To add a new implementation of this API for a property: -// - Make a class that implements CSSPropertyAPI. -// - For each method that you wish to implement in this class, add this method -// name to the api_methods flag in CSSProperties.json5. -// - Implement these methods in the .cpp file. -// -// To add new functions to this API: -// - Add the function to the struct below. -// - Add the function name to the valid_values field for api_methods in -// CSSProperties.json5. +// Status (5th May 2017): Eventually, all property specific logic will be +// contained within property APIs that inherit from CSSPropertyAPI. +// Currently, the code base is in a transitional state and property specific +// logic is still scattered around the code base. class CSSPropertyAPI { STATIC_ONLY(CSSPropertyAPI);
diff --git a/third_party/WebKit/Source/core/css/BUILD.gn b/third_party/WebKit/Source/core/css/BUILD.gn index 565344f..fff8235 100644 --- a/third_party/WebKit/Source/core/css/BUILD.gn +++ b/third_party/WebKit/Source/core/css/BUILD.gn
@@ -507,6 +507,8 @@ "properties/CSSPropertyPositionUtils.h", "properties/CSSPropertyShapeUtils.cpp", "properties/CSSPropertyShapeUtils.h", + "properties/CSSPropertyWebkitBorderWidthUtils.cpp", + "properties/CSSPropertyWebkitBorderWidthUtils.h", "resolver/AnimatedStyleBuilder.cpp", "resolver/AnimatedStyleBuilder.h", "resolver/CSSPropertyPriority.h",
diff --git a/third_party/WebKit/Source/core/css/CSSProperties.json5 b/third_party/WebKit/Source/core/css/CSSProperties.json5 index 8c214fa..c9d2a8ed 100644 --- a/third_party/WebKit/Source/core/css/CSSProperties.json5 +++ b/third_party/WebKit/Source/core/css/CSSProperties.json5
@@ -2524,6 +2524,7 @@ { name: "-webkit-border-end-width", api_class: "CSSPropertyAPIWebkitBorderWidth", + api_methods: ["parseSingleValue"], direction_aware: true, }, { @@ -2539,6 +2540,7 @@ { name: "-webkit-border-start-width", api_class: "CSSPropertyAPIWebkitBorderWidth", + api_methods: ["parseSingleValue"], direction_aware: true, }, { @@ -2554,6 +2556,7 @@ { name: "-webkit-border-before-width", api_class: "CSSPropertyAPIWebkitBorderWidth", + api_methods: ["parseSingleValue"], direction_aware: true, }, { @@ -2569,6 +2572,7 @@ { name: "-webkit-border-after-width", api_class: "CSSPropertyAPIWebkitBorderWidth", + api_methods: ["parseSingleValue"], direction_aware: true, }, {
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSScale.h b/third_party/WebKit/Source/core/css/cssom/CSSScale.h index 8f509db5..5f15568 100644 --- a/third_party/WebKit/Source/core/css/cssom/CSSScale.h +++ b/third_party/WebKit/Source/core/css/cssom/CSSScale.h
@@ -27,6 +27,10 @@ double y() const { return y_; } double z() const { return z_; } + void setX(double x) { x_ = x; } + void setY(double y) { y_ = y; } + void setZ(double z) { z_ = z; } + TransformComponentType GetType() const override { return is2d_ ? kScaleType : kScale3DType; }
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSScale.idl b/third_party/WebKit/Source/core/css/cssom/CSSScale.idl index 0971515..f1d029f9 100644 --- a/third_party/WebKit/Source/core/css/cssom/CSSScale.idl +++ b/third_party/WebKit/Source/core/css/cssom/CSSScale.idl
@@ -8,7 +8,7 @@ Exposed=(Window,PaintWorklet), RuntimeEnabled=CSSTypedOM ] interface CSSScale : CSSTransformComponent { - readonly attribute double x; - readonly attribute double y; - readonly attribute double z; + attribute double x; + attribute double y; + attribute double z; };
diff --git a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp index 615c20f8..370f3736 100644 --- a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp +++ b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
@@ -49,6 +49,7 @@ #include "core/css/properties/CSSPropertyOffsetPathUtils.h" #include "core/css/properties/CSSPropertyPositionUtils.h" #include "core/css/properties/CSSPropertyShapeUtils.h" +#include "core/css/properties/CSSPropertyWebkitBorderWidthUtils.h" #include "core/frame/UseCounter.h" #include "core/layout/LayoutTheme.h" #include "platform/wtf/text/StringBuilder.h" @@ -750,12 +751,6 @@ return true; } -static CSSValue* ConsumeBorderWidth(CSSParserTokenRange& range, - CSSParserMode css_parser_mode, - UnitlessQuirk unitless) { - return ConsumeLineWidth(range, css_parser_mode, unitless); -} - static CSSValue* ConsumeNoneOrURI(CSSParserTokenRange& range, const CSSParserContext* context) { if (range.Peek().Id() == CSSValueNone) @@ -1710,12 +1705,6 @@ case CSSPropertyColor: case CSSPropertyBackgroundColor: return ConsumeColor(range_, context_->Mode(), InQuirksMode()); - case CSSPropertyWebkitBorderStartWidth: - case CSSPropertyWebkitBorderEndWidth: - case CSSPropertyWebkitBorderBeforeWidth: - case CSSPropertyWebkitBorderAfterWidth: - return ConsumeBorderWidth(range_, context_->Mode(), - UnitlessQuirk::kForbid); case CSSPropertyBorderBottomColor: case CSSPropertyBorderLeftColor: case CSSPropertyBorderRightColor: @@ -1734,7 +1723,8 @@ current_shorthand == CSSPropertyBorderWidth); UnitlessQuirk unitless = allow_quirky_lengths ? UnitlessQuirk::kAllow : UnitlessQuirk::kForbid; - return ConsumeBorderWidth(range_, context_->Mode(), unitless); + return CSSPropertyWebkitBorderWidthUtils::ConsumeBorderWidth( + range_, context_->Mode(), unitless); } case CSSPropertyTextShadow: return ConsumeShadow(range_, context_->Mode(), false);
diff --git a/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIWebkitBorderWidth.cpp b/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIWebkitBorderWidth.cpp index 399f5f4..8cffddd 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIWebkitBorderWidth.cpp +++ b/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIWebkitBorderWidth.cpp
@@ -4,4 +4,18 @@ #include "core/css/properties/CSSPropertyAPIWebkitBorderWidth.h" -namespace blink {} // namespace blink +#include "core/css/parser/CSSParserContext.h" +#include "core/css/parser/CSSPropertyParserHelpers.h" +#include "core/css/properties/CSSPropertyWebkitBorderWidthUtils.h" + +namespace blink { + +const CSSValue* CSSPropertyAPIWebkitBorderWidth::parseSingleValue( + CSSParserTokenRange& range, + const CSSParserContext& context, + CSSPropertyID) { + return CSSPropertyWebkitBorderWidthUtils::ConsumeBorderWidth( + range, context.Mode(), CSSPropertyParserHelpers::UnitlessQuirk::kForbid); +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/core/css/properties/CSSPropertyWebkitBorderWidthUtils.cpp b/third_party/WebKit/Source/core/css/properties/CSSPropertyWebkitBorderWidthUtils.cpp new file mode 100644 index 0000000..cf8e4c3 --- /dev/null +++ b/third_party/WebKit/Source/core/css/properties/CSSPropertyWebkitBorderWidthUtils.cpp
@@ -0,0 +1,17 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "core/css/properties/CSSPropertyWebkitBorderWidthUtils.h" + +namespace blink { + +CSSValue* CSSPropertyWebkitBorderWidthUtils::ConsumeBorderWidth( + CSSParserTokenRange& range, + CSSParserMode css_parser_mode, + CSSPropertyParserHelpers::UnitlessQuirk unitless) { + return CSSPropertyParserHelpers::ConsumeLineWidth(range, css_parser_mode, + unitless); +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/core/css/properties/CSSPropertyWebkitBorderWidthUtils.h b/third_party/WebKit/Source/core/css/properties/CSSPropertyWebkitBorderWidthUtils.h new file mode 100644 index 0000000..264a023 --- /dev/null +++ b/third_party/WebKit/Source/core/css/properties/CSSPropertyWebkitBorderWidthUtils.h
@@ -0,0 +1,23 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CSSPropertyWebkitBorderWidthUtils_h +#define CSSPropertyWebkitBorderWidthUtils_h + +#include "core/css/parser/CSSPropertyParserHelpers.h" +#include "platform/wtf/Allocator.h" + +namespace blink { + +class CSSPropertyWebkitBorderWidthUtils { + STATIC_ONLY(CSSPropertyWebkitBorderWidthUtils); + + static CSSValue* ConsumeBorderWidth(CSSParserTokenRange&, + CSSParserMode, + CSSPropertyParserHelpers::UnitlessQuirk); +}; + +} // namespace blink + +#endif // CSSPropertyWebkitBorderWidthUtils_h
diff --git a/third_party/WebKit/Source/core/exported/WebViewBase.h b/third_party/WebKit/Source/core/exported/WebViewBase.h index 64a9b2a..ebe4165 100644 --- a/third_party/WebKit/Source/core/exported/WebViewBase.h +++ b/third_party/WebKit/Source/core/exported/WebViewBase.h
@@ -66,9 +66,6 @@ virtual Page* GetPage() const = 0; virtual Frame* FocusedCoreFrame() const = 0; - // PLATFORM_EXPORT static WebViewBase* Create(WebViewClient*, - // WebPageVisibilityState); - static WebViewBase* FromPage(Page*); static HashSet<WebViewBase*>& AllInstances();
diff --git a/third_party/WebKit/Source/core/paint/PaintTiming.cpp b/third_party/WebKit/Source/core/paint/PaintTiming.cpp index fae6893..d0d77477 100644 --- a/third_party/WebKit/Source/core/paint/PaintTiming.cpp +++ b/third_party/WebKit/Source/core/paint/PaintTiming.cpp
@@ -9,10 +9,13 @@ #include "core/frame/LocalDOMWindow.h" #include "core/frame/LocalFrame.h" #include "core/loader/DocumentLoader.h" +#include "core/page/ChromeClient.h" +#include "core/page/Page.h" #include "core/timing/DOMWindowPerformance.h" #include "core/timing/Performance.h" #include "platform/WebFrameScheduler.h" #include "platform/instrumentation/tracing/TraceEvent.h" +#include "public/platform/WebLayerTreeView.h" namespace blink { @@ -100,6 +103,7 @@ TraceEvent::ToTraceTimestamp(first_meaningful_paint_), "frame", GetFrame()); NotifyPaintTimingChanged(); + RegisterNotifySwapTime(PaintEvent::kFirstMeaningfulPaint); } void PaintTiming::NotifyPaint(bool is_first_paint, @@ -142,6 +146,7 @@ TRACE_EVENT_INSTANT1("loading,rail,devtools.timeline", "firstPaint", TRACE_EVENT_SCOPE_PROCESS, "frame", GetFrame()); + RegisterNotifySwapTime(PaintEvent::kFirstPaint); } void PaintTiming::SetFirstContentfulPaint(double stamp) { @@ -152,8 +157,43 @@ Performance* performance = GetPerformanceInstance(GetFrame()); if (performance) performance->AddFirstContentfulPaintTiming(first_contentful_paint_); + TRACE_EVENT_INSTANT1("loading,rail,devtools.timeline", "firstContentfulPaint", TRACE_EVENT_SCOPE_PROCESS, "frame", GetFrame()); + RegisterNotifySwapTime(PaintEvent::kFirstContentfulPaint); +} + +void PaintTiming::RegisterNotifySwapTime(PaintEvent event) { + // ReportSwapTime on layerTreeView will queue a swap-promise, the callback is + // called when the swap for current render frame completes or fails to happen. + if (!GetFrame() || !GetFrame()->GetPage()) + return; + if (WebLayerTreeView* layerTreeView = + GetFrame()->GetPage()->GetChromeClient().GetWebLayerTreeView( + GetFrame())) { + layerTreeView->NotifySwapTime(ConvertToBaseCallback( + WTF::Bind(&PaintTiming::ReportSwapTime, + WrapCrossThreadWeakPersistent(this), event))); + } +} + +void PaintTiming::ReportSwapTime(PaintEvent event, + bool did_swap, + double timestamp) { + if (!did_swap) + return; + switch (event) { + case PaintEvent::kFirstPaint: + first_paint_swap_ = timestamp; + return; + case PaintEvent::kFirstContentfulPaint: + first_contentful_paint_swap_ = timestamp; + return; + case PaintEvent::kFirstMeaningfulPaint: + first_meaningful_paint_swap_ = timestamp; + return; + } + NOTREACHED(); } } // namespace blink
diff --git a/third_party/WebKit/Source/core/paint/PaintTiming.h b/third_party/WebKit/Source/core/paint/PaintTiming.h index ba2d02f7..a9105d5 100644 --- a/third_party/WebKit/Source/core/paint/PaintTiming.h +++ b/third_party/WebKit/Source/core/paint/PaintTiming.h
@@ -26,6 +26,12 @@ public: virtual ~PaintTiming() {} + enum class PaintEvent { + kFirstPaint, + kFirstContentfulPaint, + kFirstMeaningfulPaint + }; + static PaintTiming& From(Document&); // mark*() methods record the time for the given paint event, record a trace @@ -82,6 +88,8 @@ return *fmp_detector_; } + void ReportSwapTime(PaintEvent, bool did_swap, double timestamp); + DECLARE_VIRTUAL_TRACE(); private: @@ -101,11 +109,16 @@ // time has not yet been recorded. void SetFirstContentfulPaint(double stamp); + void RegisterNotifySwapTime(PaintEvent); + double first_paint_ = 0.0; + double first_paint_swap_ = 0.0; double first_text_paint_ = 0.0; double first_image_paint_ = 0.0; double first_contentful_paint_ = 0.0; + double first_contentful_paint_swap_ = 0.0; double first_meaningful_paint_ = 0.0; + double first_meaningful_paint_swap_ = 0.0; double first_meaningful_paint_candidate_ = 0.0; Member<FirstMeaningfulPaintDetector> fmp_detector_;
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/SourceMap.js b/third_party/WebKit/Source/devtools/front_end/sdk/SourceMap.js index c8239016..53a38625 100644 --- a/third_party/WebKit/Source/devtools/front_end/sdk/SourceMap.js +++ b/third_party/WebKit/Source/devtools/front_end/sdk/SourceMap.js
@@ -320,26 +320,10 @@ * @return {?SDK.SourceMapEntry} */ findEntry(lineNumber, columnNumber) { - var first = 0; var mappings = this.mappings(); - var count = mappings.length; - while (count > 1) { - var step = count >> 1; - var middle = first + step; - var mapping = mappings[middle]; - if (lineNumber < mapping.lineNumber || - (lineNumber === mapping.lineNumber && columnNumber < mapping.columnNumber)) { - count = step; - } else { - first = middle; - count -= step; - } - } - var entry = mappings[first]; - if (!first && entry && - (lineNumber < entry.lineNumber || (lineNumber === entry.lineNumber && columnNumber < entry.columnNumber))) - return null; - return entry; + var index = mappings.upperBound( + undefined, (unused, entry) => lineNumber - entry.lineNumber || columnNumber - entry.columnNumber); + return index ? mappings[index - 1] : null; } /**
diff --git a/third_party/WebKit/public/platform/DEPS b/third_party/WebKit/public/platform/DEPS index cf0e7d8a..3824dc7 100644 --- a/third_party/WebKit/public/platform/DEPS +++ b/third_party/WebKit/public/platform/DEPS
@@ -1,4 +1,5 @@ include_rules = [ + "+base/callback.h", "+base/callback_forward.h", "+base/location.h", "+base/logging.h",
diff --git a/third_party/WebKit/public/platform/WebLayerTreeView.h b/third_party/WebKit/public/platform/WebLayerTreeView.h index 35b27082..19e128c1 100644 --- a/third_party/WebKit/public/platform/WebLayerTreeView.h +++ b/third_party/WebKit/public/platform/WebLayerTreeView.h
@@ -33,6 +33,7 @@ #include "WebEventListenerProperties.h" #include "WebFloatPoint.h" #include "WebSize.h" +#include "base/callback.h" #include "cc/surfaces/frame_sink_id.h" namespace cc { @@ -48,6 +49,8 @@ class WebSelection; class WebLayerTreeView { + using ReportTimeCallback = base::Callback<void(bool, double)>; + public: virtual ~WebLayerTreeView() {} @@ -181,6 +184,10 @@ // Toggles scroll bottleneck rects on the HUD layer virtual void SetShowScrollBottleneckRects(bool) {} + + // ReportTimeCallback is a callback that should be fired when the + // corresponding Swap completes (either with DidSwap or DidNotSwap). + virtual void NotifySwapTime(ReportTimeCallback callback) {} }; } // namespace blink
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index a436e705..acef7c5 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -21997,6 +21997,7 @@ <int value="1586022426" label="AutofillCreditCardAssist:enabled"/> <int value="1589341623" label="disable-easy-unlock"/> <int value="1594247626" label="ContentSuggestionsSettings:enabled"/> + <int value="1600926040" label="TranslateCompactUI:enabled"/> <int value="1605611615" label="enable-webrtc-srtp-aes-gcm"/> <int value="1612446645" label="enable-weak-memorycache"/> <int value="1612871297" label="WebPayments:disabled"/> @@ -22040,6 +22041,7 @@ <int value="1783837132" label="enable-threaded-gpu-rasterization"/> <int value="1785093465" label="enable-document-passive-event-listeners"/> <int value="1786229999" label="disable-md-downloads"/> + <int value="1786386775" label="TranslateCompactUI:disabled"/> <int value="1791904609" label="disable-autofill-keyboard-accessory-view"/> <int value="1803465156" label="enable-zero-suggest-most-visited"/> <int value="1809940714" label="SpeculativeLaunchServiceWorker:disabled"/>