diff --git a/AUTHORS b/AUTHORS index bf2bffe9..7ad2718 100644 --- a/AUTHORS +++ b/AUTHORS
@@ -36,6 +36,7 @@ Alexandre Abreu <wiss1976@gmail.com> Alexandru Chiculita <achicu@adobe.com> Alexey Korepanov <alexkorep@gmail.com> +Alexey Kuts <kruntuid@gmail.com> Alexis Brenon <brenon.alexis@gmail.com> Alexis Menard <alexis.menard@intel.com> Alfredo Hernandez <ahernandez.miralles@gmail.com>
diff --git a/DEPS b/DEPS index a6b6d9b3..182078d 100644 --- a/DEPS +++ b/DEPS
@@ -43,7 +43,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': 'ec21f831870e79aef0417eb1718eefcef9456bff', + 'v8_revision': 'a964163e6ac4f1124b22ea7e46b8afe26dec02e0', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other. @@ -95,7 +95,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': '03fbd54d8fdb0defa1a677b71d67a9f46544fa86', + 'catapult_revision': 'f332dd6dd55d4754ecf770f5edc7cc606b13a161', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other.
diff --git a/android_webview/glue/BUILD.gn b/android_webview/glue/BUILD.gn index 4347ccd..ab52954 100644 --- a/android_webview/glue/BUILD.gn +++ b/android_webview/glue/BUILD.gn
@@ -41,13 +41,7 @@ android_library("glue") { # Change deps? please modify glue_library_deps variable. deps = glue_library_deps - srcjar_deps = [ - ":glue_resource_rewriter", - "//base:base_build_config_gen", - ] - - # New versions of BuildConfig.java will be created when creating an apk. - jar_excluded_patterns = [ "*/BuildConfig.class" ] + srcjar_deps = [ ":glue_resource_rewriter" ] # Always build upstream or downstream target with public or internal # framework jar respectively.
diff --git a/base/BUILD.gn b/base/BUILD.gn index b704fa9..0cf620f37 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -2359,6 +2359,7 @@ deps = [ ":base_java", "//testing/android/reporter:reporter_java", + "//third_party/hamcrest:hamcrest_core_java", ] java_files = [ "test/android/javatests/src/org/chromium/base/test/BaseActivityInstrumentationTestCase.java", @@ -2377,6 +2378,7 @@ "test/android/javatests/src/org/chromium/base/test/util/InstrumentationUtils.java", "test/android/javatests/src/org/chromium/base/test/util/IntegrationTest.java", "test/android/javatests/src/org/chromium/base/test/util/Manual.java", + "test/android/javatests/src/org/chromium/base/test/util/Matchers.java", "test/android/javatests/src/org/chromium/base/test/util/MetricsUtils.java", "test/android/javatests/src/org/chromium/base/test/util/MinAndroidSdkLevel.java", "test/android/javatests/src/org/chromium/base/test/util/MinAndroidSdkLevelSkipCheck.java",
diff --git a/base/allocator/winheap_stubs_win.cc b/base/allocator/winheap_stubs_win.cc index 7298bb94..593e386e 100644 --- a/base/allocator/winheap_stubs_win.cc +++ b/base/allocator/winheap_stubs_win.cc
@@ -35,8 +35,11 @@ return nullptr; } -void WinHeapFree(void* size) { - HeapFree(get_heap_handle(), 0, size); +void WinHeapFree(void* ptr) { + if (!ptr) + return; + + HeapFree(get_heap_handle(), 0, ptr); } void* WinHeapRealloc(void* ptr, size_t size) {
diff --git a/base/mac/scoped_block.h b/base/mac/scoped_block.h index 8199677..10ab4b4e 100644 --- a/base/mac/scoped_block.h +++ b/base/mac/scoped_block.h
@@ -36,9 +36,33 @@ // ScopedBlock<> is patterned after ScopedCFTypeRef<>, but uses Block_copy() and // Block_release() instead of CFRetain() and CFRelease(). - template <typename B> -using ScopedBlock = ScopedTypeRef<B, internal::ScopedBlockTraits<B>>; +class ScopedBlock : public ScopedTypeRef<B, internal::ScopedBlockTraits<B>> { + public: + using Traits = internal::ScopedBlockTraits<B>; + +#if !defined(__has_feature) || !__has_feature(objc_arc) + explicit ScopedBlock( + B block = Traits::InvalidValue(), + base::scoped_policy::OwnershipPolicy policy = base::scoped_policy::ASSUME) + : ScopedTypeRef<B, Traits>(block, policy) {} +#else + explicit ScopedBlock(B block = Traits::InvalidValue()) + : ScopedTypeRef<B, Traits>(block, base::scoped_policy::RETAIN) {} +#endif + +#if !defined(__has_feature) || !__has_feature(objc_arc) + void reset(B block = Traits::InvalidValue(), + base::scoped_policy::OwnershipPolicy policy = + base::scoped_policy::ASSUME) { + ScopedTypeRef<B, Traits>::reset(block, policy); + } +#else + void reset(B block = Traits::InvalidValue()) { + ScopedTypeRef<B, Traits>::reset(block, base::scoped_policy::RETAIN); + } +#endif +}; } // namespace mac } // namespace base
diff --git a/base/test/android/javatests/src/org/chromium/base/test/util/Matchers.java b/base/test/android/javatests/src/org/chromium/base/test/util/Matchers.java new file mode 100644 index 0000000..fc9d6890 --- /dev/null +++ b/base/test/android/javatests/src/org/chromium/base/test/util/Matchers.java
@@ -0,0 +1,44 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.base.test.util; + +import org.hamcrest.CoreMatchers; +import org.hamcrest.Description; +import org.hamcrest.Matcher; +import org.hamcrest.TypeSafeMatcher; + +/** + * Helper class containing Hamcrest matchers. + */ +public class Matchers extends CoreMatchers { + private static class GreaterThanOrEqualTo<T extends Comparable<T>> + extends TypeSafeMatcher<T> { + + private final T mComparisonValue; + + public GreaterThanOrEqualTo(T comparisonValue) { + mComparisonValue = comparisonValue; + } + + @Override + public void describeTo(Description description) { + description.appendText("greater than or equal to ").appendValue(mComparisonValue); + } + + @Override + protected boolean matchesSafely(T item) { + return item.compareTo(mComparisonValue) >= 0; + } + } + + /** + * @param <T> A Comparable type. + * @param comparisonValue The value to be compared against. + * @return A matcher that expects the value to be greater than the |comparisonValue|. + */ + public static <T extends Comparable<T>> Matcher<T> greaterThanOrEqualTo(T comparisonValue) { + return new GreaterThanOrEqualTo<>(comparisonValue); + } +}
diff --git a/build/config/android/internal_rules.gni b/build/config/android/internal_rules.gni index 67e84c0..ad42da6 100644 --- a/build/config/android/internal_rules.gni +++ b/build/config/android/internal_rules.gni
@@ -1827,11 +1827,23 @@ } generate_interface_jar(_ijar_target_name) { - input_jar = _jar_path + if (!defined(invoker.proguard_preprocess) || + !invoker.proguard_preprocess) { + # Always used the unfiltered .jar to create the interface jar so that + # other targets will resolve filtered classes when depending on + # BuildConfig, NativeLibraries, etc. + input_jar = invoker.jar_path + deps = _deps + _jar_deps + } else { + # However, still apply pre-proguarding, since ignoring that can break + # compiles. + input_jar = _jar_path + deps = [ + ":$_process_jar_target_name", + ] + } + output_jar = _ijar_path - deps = [ - ":$_process_jar_target_name", - ] } if (_supports_android) { @@ -2128,17 +2140,24 @@ } generate_interface_jar(_ijar_target_name) { - input_jar = _final_jar_path - output_jar = _final_ijar_path - if (_emma_instrument) { + if (!defined(invoker.proguard_preprocess) || + !invoker.proguard_preprocess) { + # Always used the unfiltered .jar to create the interface jar so that + # other targets will resolve filtered classes when depending on + # BuildConfig, NativeLibraries, etc. + input_jar = _javac_jar_path deps = [ - ":$_emma_instr_target_name", + ":$_javac_target_name", ] } else { + # However, still apply pre-proguarding, since ignoring that can break + # compiles. + input_jar = _process_prebuilt_jar_path deps = [ ":$_process_prebuilt_target_name", ] } + output_jar = _final_ijar_path } group(_final_target_name) {
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index fad3c78f..8a22ed7 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -246,16 +246,12 @@ ":chrome_android_java_google_api_keys_srcjar", ":chrome_version_srcjar", ":resource_id_javagen", - "//base:base_build_config_gen", "//chrome:content_setting_javagen", "//chrome:content_settings_type_javagen", "//chrome:data_use_ui_message_enum_javagen", "//chrome:signin_metrics_enum_javagen", ] - # New versions of BuildConfig.java will be created when creating an apk. - jar_excluded_patterns = [ "*/BuildConfig.class" ] - # Manifest used for linting (determining unused resources). android_manifest = chrome_public_android_manifest
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java index 9404990..6931d99 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java
@@ -1779,6 +1779,13 @@ mContextMenuCloseObservers.addObserver(callback); } + @Override + public void onContextMenuClosed(Menu menu) { + for (Callback<Menu> callback : mContextMenuCloseObservers) { + callback.onResult(menu); + } + } + /** * Removes a {@link Callback} from the list of callbacks that will be triggered when a * ContextMenu is closed.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationBuilderBase.java b/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationBuilderBase.java index 657b0e06..3043f53089 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationBuilderBase.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationBuilderBase.java
@@ -7,6 +7,7 @@ import android.annotation.TargetApi; import android.app.Notification; import android.app.PendingIntent; +import android.app.RemoteInput; import android.content.Context; import android.content.res.Resources; import android.graphics.Bitmap; @@ -32,21 +33,46 @@ */ public abstract class NotificationBuilderBase { protected static class Action { + enum Type { + /** + * Regular action that triggers the provided intent when tapped. + */ + BUTTON, + + /** + * Action that triggers a remote input when tapped, for Android Wear input and inline + * replies from Android N. + */ + TEXT + } + public int iconId; public Bitmap iconBitmap; public CharSequence title; public PendingIntent intent; + public Type type; - Action(int iconId, CharSequence title, PendingIntent intent) { + /** + * If the action.type is TEXT, this corresponds to the placeholder text for the input. + */ + public String placeholder; + + Action(int iconId, CharSequence title, PendingIntent intent, Type type, + String placeholder) { this.iconId = iconId; this.title = title; this.intent = intent; + this.type = type; + this.placeholder = placeholder; } - Action(Bitmap iconBitmap, CharSequence title, PendingIntent intent) { + Action(Bitmap iconBitmap, CharSequence title, PendingIntent intent, Type type, + String placeholder) { this.iconBitmap = iconBitmap; this.title = title; this.intent = intent; + this.type = type; + this.placeholder = placeholder; } } @@ -202,11 +228,28 @@ } /** - * Adds an action to the notification. Actions are typically displayed as a button adjacent to - * the notification content. + * Adds an action to the notification, displayed as a button adjacent to the notification + * content. */ - public NotificationBuilderBase addAction(@Nullable Bitmap iconBitmap, + public NotificationBuilderBase addButtonAction(@Nullable Bitmap iconBitmap, @Nullable CharSequence title, @Nullable PendingIntent intent) { + addAuthorProvidedAction(iconBitmap, title, intent, Action.Type.BUTTON, null); + return this; + } + + /** + * Adds an action to the notification, displayed as a button adjacent to the notification + * content, which when tapped will trigger a remote input. This enables Android Wear input and, + * from Android N, displays a text box within the notification for inline replies. + */ + public NotificationBuilderBase addTextAction(@Nullable Bitmap iconBitmap, + @Nullable CharSequence title, @Nullable PendingIntent intent, String placeholder) { + addAuthorProvidedAction(iconBitmap, title, intent, Action.Type.TEXT, placeholder); + return this; + } + + private void addAuthorProvidedAction(@Nullable Bitmap iconBitmap, @Nullable CharSequence title, + @Nullable PendingIntent intent, Action.Type actionType, @Nullable String placeholder) { if (mActions.size() == MAX_AUTHOR_PROVIDED_ACTION_BUTTONS) { throw new IllegalStateException( "Cannot add more than " + MAX_AUTHOR_PROVIDED_ACTION_BUTTONS + " actions."); @@ -214,8 +257,7 @@ if (iconBitmap != null) { applyWhiteOverlayToBitmap(iconBitmap); } - mActions.add(new Action(iconBitmap, limitLength(title), intent)); - return this; + mActions.add(new Action(iconBitmap, limitLength(title), intent, actionType, placeholder)); } /** @@ -223,7 +265,7 @@ */ public NotificationBuilderBase addSettingsAction( int iconId, @Nullable CharSequence title, @Nullable PendingIntent intent) { - mSettingsAction = new Action(iconId, limitLength(title), intent); + mSettingsAction = new Action(iconId, limitLength(title), intent, Action.Type.BUTTON, null); return this; } @@ -369,17 +411,38 @@ * level is high enough, otherwise a resource id is used. */ @SuppressWarnings("deprecation") // For addAction(int, CharSequence, PendingIntent) - @TargetApi(Build.VERSION_CODES.M) // For the Icon class. protected static void addActionToBuilder(Notification.Builder builder, Action action) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && action.iconBitmap != null) { - Icon icon = Icon.createWithBitmap(action.iconBitmap); - builder.addAction( - new Notification.Action.Builder(icon, action.title, action.intent).build()); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) { + // Notification.Action.Builder and RemoteInput were added in KITKAT_WATCH. + Notification.Action.Builder actionBuilder = getActionBuilder(action); + if (action.type == Action.Type.TEXT) { + assert action.placeholder != null; + actionBuilder.addRemoteInput( + new RemoteInput.Builder(NotificationConstants.KEY_TEXT_REPLY) + .setLabel(action.placeholder) + .build()); + } + builder.addAction(actionBuilder.build()); } else { builder.addAction(action.iconId, action.title, action.intent); } } + @TargetApi(Build.VERSION_CODES.KITKAT_WATCH) // For Notification.Action.Builder + @SuppressWarnings("deprecation") // For Builder(int, CharSequence, PendingIntent) + private static Notification.Action.Builder getActionBuilder(Action action) { + Notification.Action.Builder actionBuilder; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && action.iconBitmap != null) { + // Icon was added in Android M. + Icon icon = Icon.createWithBitmap(action.iconBitmap); + actionBuilder = new Notification.Action.Builder(icon, action.title, action.intent); + } else { + actionBuilder = + new Notification.Action.Builder(action.iconId, action.title, action.intent); + } + return actionBuilder; + } + /** * Paints {@code bitmap} white. This processing should be performed if the Android system * expects a bitmap to be white, and the bitmap is not already known to be white. The bitmap
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationConstants.java b/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationConstants.java index d44b897..521d7de94 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationConstants.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationConstants.java
@@ -54,4 +54,9 @@ * developer specified tag. */ public static final String NOTIFICATION_TAG_SEPARATOR = ";"; + + /** + * Key for retrieving the results of user input from notification text action intents. + */ + static final String KEY_TEXT_REPLY = "key_text_reply"; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationPlatformBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationPlatformBridge.java index afc5c96..0381041 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationPlatformBridge.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationPlatformBridge.java
@@ -441,6 +441,7 @@ /** * Displays a notification with the given details. * + * TODO(crbug.com/650302): Combine the 'action*' parameters into a single array of objects. * @param notificationId The id of the notification. * @param origin Full text of the origin, including the protocol, owning this notification. * @param profileId Id of the profile that showed the notification. @@ -466,13 +467,16 @@ * @param silent Whether the default sound, vibration and lights should be suppressed. * @param actionTitles Titles of actions to display alongside the notification. * @param actionIcons Icons of actions to display alongside the notification. + * @param actionTypes Types of actions to display alongside the notification. + * @param actionPlaceholders Placeholders of actions to display alongside the notification. * @see https://developer.android.com/reference/android/app/Notification.html */ @CalledByNative private void displayNotification(String notificationId, String origin, String profileId, boolean incognito, String tag, String webApkPackage, String title, String body, Bitmap image, Bitmap icon, Bitmap badge, int[] vibrationPattern, long timestamp, - boolean renotify, boolean silent, String[] actionTitles, Bitmap[] actionIcons) { + boolean renotify, boolean silent, String[] actionTitles, Bitmap[] actionIcons, + String[] actionTypes, String[] actionPlaceholders) { if (actionTitles.length != actionIcons.length) { throw new IllegalArgumentException("The number of action titles and icons must match."); } @@ -519,10 +523,17 @@ origin, false /* showScheme */)); for (int actionIndex = 0; actionIndex < actionTitles.length; actionIndex++) { - notificationBuilder.addAction(actionIcons[actionIndex], actionTitles[actionIndex], - makePendingIntent(NotificationConstants.ACTION_CLICK_NOTIFICATION, - notificationId, origin, profileId, incognito, tag, - webApkPackage, actionIndex)); + PendingIntent intent = makePendingIntent( + NotificationConstants.ACTION_CLICK_NOTIFICATION, notificationId, origin, + profileId, incognito, tag, webApkPackage, actionIndex); + // TODO(crbug.com/650302): Encode actionTypes with an enum, not a magic string! + if (actionTypes[actionIndex].equals("text")) { + notificationBuilder.addTextAction(actionIcons[actionIndex], + actionTitles[actionIndex], intent, actionPlaceholders[actionIndex]); + } else { + notificationBuilder.addButtonAction( + actionIcons[actionIndex], actionTitles[actionIndex], intent); + } } // If action buttons are displayed, there isn't room for the full Site Settings button
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/TitleUtil.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/TitleUtil.java index df8190b..6285823b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/TitleUtil.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/TitleUtil.java
@@ -5,10 +5,9 @@ package org.chromium.chrome.browser.ntp; import android.net.Uri; +import android.support.annotation.Nullable; import android.text.TextUtils; -import javax.annotation.Nullable; - /** * Provides functions for working with link titles. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapter.java index 886dd20d..3701ed4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapter.java
@@ -442,7 +442,7 @@ /** * Returns an unmodifiable list containing all items in the adapter. */ - public List<NewTabPageItem> getItems() { + private List<NewTabPageItem> getItems() { List<NewTabPageItem> items = new ArrayList<>(); for (ItemGroup group : mGroups) { items.addAll(group.getItems()); @@ -466,7 +466,8 @@ return Collections.unmodifiableList(mGroups); } - private int getGroupPositionOffset(ItemGroup group) { + @VisibleForTesting + int getGroupPositionOffset(ItemGroup group) { int positionOffset = 0; for (ItemGroup candidateGroup : mGroups) { if (candidateGroup == group) return positionOffset; @@ -474,4 +475,9 @@ } return RecyclerView.NO_POSITION; } + + @VisibleForTesting + SnippetArticle getSuggestionAt(int position) { + return (SnippetArticle) getItems().get(position); + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageRecyclerView.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageRecyclerView.java index 99b19a5cd..351e0d4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageRecyclerView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageRecyclerView.java
@@ -52,7 +52,7 @@ /** View used to calculate the position of the cards' snap point. */ private View mAboveTheFoldView; - /** Whether the RecyclerView should react to touch events. */ + /** Whether the RecyclerView and its children should react to touch events. */ private boolean mTouchEnabled = true; /** Whether the above-the-fold left space for a peeking card to be displayed. */ @@ -89,6 +89,7 @@ @Override public boolean onInterceptTouchEvent(MotionEvent ev) { mGestureDetector.onTouchEvent(ev); + if (!mTouchEnabled) return true; return super.onInterceptTouchEvent(ev); } @@ -423,7 +424,7 @@ * Animates the card being swiped to the right as if the user had dismissed it. Any changes to * the animation here should be reflected also in * {@link #updateViewStateForDismiss(float, ViewHolder)} and reset in - * {@link CardViewHolder#onBindViewHolder(NewTabPageItem)}. + * {@link CardViewHolder#onBindViewHolder()}. * @param suggestion The item to be dismissed. */ public void dismissItemWithAnimation(SnippetArticle suggestion) {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/notifications/CustomNotificationBuilderTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/notifications/CustomNotificationBuilderTest.java index 1c9d80d..1aa94896 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/notifications/CustomNotificationBuilderTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/notifications/CustomNotificationBuilderTest.java
@@ -4,6 +4,7 @@ package org.chromium.chrome.browser.notifications; +import android.annotation.TargetApi; import android.app.Notification; import android.app.PendingIntent; import android.content.Context; @@ -23,6 +24,7 @@ import android.widget.TextView; import org.chromium.base.test.util.Feature; +import org.chromium.base.test.util.MinAndroidSdkLevel; import org.chromium.chrome.R; import org.chromium.content.browser.test.NativeLibraryTestBase; @@ -59,23 +61,24 @@ new int[] {Color.WHITE}, 1 /* width */, 1 /* height */, Bitmap.Config.ARGB_8888); actionIcon = actionIcon.copy(Bitmap.Config.ARGB_8888, true /* isMutable */); - Notification notification = - new CustomNotificationBuilder(context) - .setSmallIcon(R.drawable.ic_chrome) - .setLargeIcon(largeIcon) - .setTitle("title") - .setBody("body") - .setOrigin("origin") - .setTicker("ticker") - .setDefaults(Notification.DEFAULT_ALL) - .setVibrate(new long[] {100L}) - .setContentIntent(contentIntent) - .setDeleteIntent(deleteIntent) - .addAction(actionIcon, "button", createIntent(context, "ActionButtonOne")) - .addAction(actionIcon, "button", createIntent(context, "ActionButtonTwo")) - .addSettingsAction( - 0 /* iconId */, "settings", createIntent(context, "SettingsButton")) - .build(); + Notification notification = new CustomNotificationBuilder(context) + .setSmallIcon(R.drawable.ic_chrome) + .setLargeIcon(largeIcon) + .setTitle("title") + .setBody("body") + .setOrigin("origin") + .setTicker("ticker") + .setDefaults(Notification.DEFAULT_ALL) + .setVibrate(new long[] {100L}) + .setContentIntent(contentIntent) + .setDeleteIntent(deleteIntent) + .addButtonAction(actionIcon, "button", + createIntent(context, "ActionButtonOne")) + .addButtonAction(actionIcon, "button", + createIntent(context, "ActionButtonTwo")) + .addSettingsAction(0 /* iconId */, "settings", + createIntent(context, "SettingsButton")) + .build(); assertSmallNotificationIconAsExpected(context, notification, smallIcon); assertLargeNotificationIconAsExpected(context, notification, largeIcon); @@ -137,12 +140,12 @@ public void testMaxActionButtons() { Context context = getInstrumentation().getTargetContext(); NotificationBuilderBase builder = new CustomNotificationBuilder(context) - .addAction(null /* iconBitmap */, "button", + .addButtonAction(null /* iconBitmap */, "button", createIntent(context, "ActionButtonOne")) - .addAction(null /* iconBitmap */, "button", + .addButtonAction(null /* iconBitmap */, "button", createIntent(context, "ActionButtonTwo")); try { - builder.addAction( + builder.addButtonAction( null /* iconBitmap */, "button", createIntent(context, "ActionButtonThree")); fail("This statement should not be reached as the previous statement should throw."); } catch (IllegalStateException e) { @@ -173,12 +176,12 @@ new int[] {Color.RED}, 1 /* width */, 1 /* height */, Bitmap.Config.ARGB_8888); actionIcon = actionIcon.copy(Bitmap.Config.ARGB_8888, true /* isMutable */); - Notification notification = - new CustomNotificationBuilder(context) - .setLargeIcon(largeIcon) - .setSmallIcon(smallIcon) - .addAction(actionIcon, "button", createIntent(context, "ActionButton")) - .build(); + Notification notification = new CustomNotificationBuilder(context) + .setLargeIcon(largeIcon) + .setSmallIcon(smallIcon) + .addButtonAction(actionIcon, "button", + createIntent(context, "ActionButton")) + .build(); // The large icon should be unchanged. assertLargeNotificationIconAsExpected(context, notification, largeIcon); @@ -207,7 +210,7 @@ .setBody(createString('b', maxLength + 1)) .setOrigin(createString('c', maxLength + 1)) .setTicker(createString('d', maxLength + 1)) - .addAction(null /* iconBitmap */, createString('e', maxLength + 1), + .addButtonAction(null /* iconBitmap */, createString('e', maxLength + 1), createIntent(context, "ActionButtonOne")) .build(); View compactView = notification.contentView.apply(context, new LinearLayout(context)); @@ -279,6 +282,30 @@ assertLargeNotificationIconAsExpected(context, notification, expectedIcon); } + /** + * Tests that adding a text action results in a notification action with a RemoteInput attached. + * + * Note that the action buttons in custom layouts will not trigger an inline reply, but we can + * still check the notification's action properties since these are used on Android Wear. + */ + @MinAndroidSdkLevel(Build.VERSION_CODES.KITKAT_WATCH) + @TargetApi(Build.VERSION_CODES.KITKAT_WATCH) // RemoteInputs were only added in KITKAT_WATCH. + @SmallTest + @Feature({"Browser", "Notifications"}) + public void testAddTextActionSetsRemoteInput() { + Context context = getInstrumentation().getTargetContext(); + NotificationBuilderBase notificationBuilder = new CustomNotificationBuilder( + context).addTextAction(null, "Action Title", null, "Placeholder"); + + Notification notification = notificationBuilder.build(); + + assertEquals(1, notification.actions.length); + assertEquals("Action Title", notification.actions[0].title); + assertNotNull(notification.actions[0].getRemoteInputs()); + assertEquals(1, notification.actions[0].getRemoteInputs().length); + assertEquals("Placeholder", notification.actions[0].getRemoteInputs()[0].getLabel()); + } + private static void assertLargeNotificationIconAsExpected( Context context, Notification notification, Bitmap expectedIcon) { // 1. Check large icon property on the notification.
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/notifications/NotificationPlatformBridgeTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/notifications/NotificationPlatformBridgeTest.java index d22cfc5..110831c 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/notifications/NotificationPlatformBridgeTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/notifications/NotificationPlatformBridgeTest.java
@@ -6,6 +6,7 @@ import static org.chromium.base.test.util.ScalableTimeout.scaleTimeout; +import android.annotation.TargetApi; import android.app.Notification; import android.content.Context; import android.graphics.Bitmap; @@ -17,7 +18,9 @@ import org.chromium.base.ThreadUtils; import org.chromium.base.annotations.SuppressFBWarnings; +import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.Feature; +import org.chromium.base.test.util.MinAndroidSdkLevel; import org.chromium.base.test.util.RetryOnFailure; import org.chromium.chrome.R; import org.chromium.chrome.browser.infobar.InfoBar; @@ -228,6 +231,32 @@ } /** + * Verifies that specifying a notification action with type: 'text' results in a notification + * with a remote input on the action. + */ + @CommandLineFlags.Add("enable-experimental-web-platform-features") + @MinAndroidSdkLevel(Build.VERSION_CODES.KITKAT_WATCH) + @TargetApi(Build.VERSION_CODES.KITKAT_WATCH) // RemoteInputs were only added in KITKAT_WATCH. + @MediumTest + @Feature({"Browser", "Notifications"}) + public void testNotificationWithTextAction() throws Exception { + setNotificationContentSettingForCurrentOrigin(ContentSetting.ALLOW); + + Notification notification = showAndGetNotification("MyNotification", "{ " + + " actions: [{action: 'myAction', title: 'reply', type: 'text'," + + " placeholder: 'hi' }]}"); + + // The specified action should be present, as well as a default settings action. + assertEquals(2, notification.actions.length); + + Notification.Action action = notification.actions[0]; + assertEquals("reply", action.title); + assertNotNull(notification.actions[0].getRemoteInputs()); + assertEquals(1, action.getRemoteInputs().length); + assertEquals("hi", action.getRemoteInputs()[0].getLabel()); + } + + /** * Verifies that the ONLY_ALERT_ONCE flag is not set when renotify is true. */ @MediumTest
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/notifications/StandardNotificationBuilderTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/notifications/StandardNotificationBuilderTest.java index 24c6ac5..2a5f2ef 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/notifications/StandardNotificationBuilderTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/notifications/StandardNotificationBuilderTest.java
@@ -4,6 +4,7 @@ package org.chromium.chrome.browser.notifications; +import android.annotation.TargetApi; import android.app.Notification; import android.app.PendingIntent; import android.content.Context; @@ -16,6 +17,7 @@ import android.text.SpannableStringBuilder; import org.chromium.base.test.util.Feature; +import org.chromium.base.test.util.MinAndroidSdkLevel; import org.chromium.chrome.R; import org.chromium.chrome.browser.util.UrlUtilities; import org.chromium.chrome.browser.widget.RoundedIconGenerator; @@ -76,8 +78,8 @@ .setVibrate(new long[] {100L}) .setContentIntent(outContentAndDeleteIntents[0]) .setDeleteIntent(outContentAndDeleteIntents[1]) - .addAction(actionIcon, "button 1", null /* intent */) - .addAction(actionIcon, "button 2", null /* intent */) + .addButtonAction(actionIcon, "button 1", null /* intent */) + .addButtonAction(actionIcon, "button 2", null /* intent */) .addSettingsAction(0 /* iconId */, "settings", null /* intent */); } @@ -184,4 +186,22 @@ assertTrue(expected.sameAs(result)); } } + + @MinAndroidSdkLevel(Build.VERSION_CODES.KITKAT_WATCH) + @TargetApi(Build.VERSION_CODES.KITKAT_WATCH) // RemoteInputs were only added in KITKAT_WATCH. + @SmallTest + @Feature({"Browser", "Notifications"}) + public void testAddTextActionSetsRemoteInput() { + Context context = getInstrumentation().getTargetContext(); + NotificationBuilderBase notificationBuilder = new StandardNotificationBuilder( + context).addTextAction(null, "Action Title", null, "Placeholder"); + + Notification notification = notificationBuilder.build(); + + assertEquals(1, notification.actions.length); + assertEquals("Action Title", notification.actions[0].title); + assertNotNull(notification.actions[0].getRemoteInputs()); + assertEquals(1, notification.actions[0].getRemoteInputs().length); + assertEquals("Placeholder", notification.actions[0].getRemoteInputs()[0].getLabel()); + } }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapterTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapterTest.java index 1cc0028..956e6f0 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapterTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapterTest.java
@@ -4,10 +4,12 @@ package org.chromium.chrome.browser.ntp.cards; +import static org.chromium.base.test.util.Matchers.greaterThanOrEqualTo; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -31,7 +33,6 @@ import org.chromium.chrome.browser.ntp.snippets.ContentSuggestionsCardLayout; import org.chromium.chrome.browser.ntp.snippets.FakeSuggestionsSource; import org.chromium.chrome.browser.ntp.snippets.KnownCategories; -import org.chromium.chrome.browser.ntp.snippets.SectionHeader; import org.chromium.chrome.browser.ntp.snippets.SnippetArticle; import org.chromium.chrome.browser.ntp.snippets.SuggestionsSource; import org.chromium.chrome.browser.profiles.MostVisitedSites.MostVisitedURLsObserver; @@ -86,47 +87,43 @@ * expressed as a sequence of calls to the {@link #expect} methods. */ private static class ItemsMatcher { // TODO(pke): Find better name. - private final List<NewTabPageItem> mItems; + private final NewTabPageAdapter mAdapter; private int mCurrentIndex; - public ItemsMatcher(List<NewTabPageItem> items) { - mItems = items; + public ItemsMatcher(NewTabPageAdapter adapter, int startingIndex) { + mAdapter = adapter; + mCurrentIndex = startingIndex; } - public void expect(Class<? extends NewTabPageItem> itemType) { - if (mCurrentIndex >= mItems.size()) { - fail("Expected another " + itemType.getSimpleName() + " after the following items: " - + mItems); + public void expect(@NewTabPageItem.ViewType int expectedItemType) { + if (mCurrentIndex >= mAdapter.getItemCount()) { + fail("Expected item of type " + expectedItemType + " but encountered end of list"); } - NewTabPageItem item = mItems.get(mCurrentIndex); - if (!itemType.isInstance(item)) { - fail("Expected the element at position " + mCurrentIndex + " to be a " - + itemType.getSimpleName() + " instead of a " - + item.getClass().getSimpleName() + "; full list: " + mItems); - } + @NewTabPageItem.ViewType int itemType = mAdapter.getItemViewType(mCurrentIndex); + assertEquals("Type mismatch at position " + mCurrentIndex, expectedItemType, itemType); mCurrentIndex++; } public void expect(SectionDescriptor descriptor) { - expect(SectionHeader.class); + expect(NewTabPageItem.VIEW_TYPE_HEADER); if (descriptor.mStatusCard) { - expect(StatusItem.class); + expect(NewTabPageItem.VIEW_TYPE_STATUS); if (descriptor.mMoreButton) { - expect(ActionItem.class); + expect(NewTabPageItem.VIEW_TYPE_ACTION); } - expect(ProgressItem.class); + expect(NewTabPageItem.VIEW_TYPE_PROGRESS); } else { for (int i = 1; i <= descriptor.mNumSuggestions; i++) { - expect(SnippetArticle.class); + expect(NewTabPageItem.VIEW_TYPE_SNIPPET); } if (descriptor.mMoreButton) { - expect(ActionItem.class); + expect(NewTabPageItem.VIEW_TYPE_ACTION); } } } - public void expectFinished() { - assertEquals(mItems.size(), mCurrentIndex); + public void expectPosition(int expectedPosition) { + assertEquals(expectedPosition, mCurrentIndex); } } @@ -137,9 +134,10 @@ * @param itemGroup The items from the adapter. */ private void assertMatches(SectionDescriptor descriptor, ItemGroup itemGroup) { - ItemsMatcher matcher = new ItemsMatcher(itemGroup.getItems()); + int offset = mAdapter.getGroupPositionOffset(itemGroup); + ItemsMatcher matcher = new ItemsMatcher(mAdapter, offset); matcher.expect(descriptor); - matcher.expectFinished(); + matcher.expectPosition(offset + itemGroup.getItems().size()); } /** @@ -149,14 +147,14 @@ * the UI. */ private void assertItemsFor(SectionDescriptor... descriptors) { - ItemsMatcher matcher = new ItemsMatcher(mAdapter.getItems()); - matcher.expect(AboveTheFoldItem.class); + ItemsMatcher matcher = new ItemsMatcher(mAdapter, 0); + matcher.expect(NewTabPageItem.VIEW_TYPE_ABOVE_THE_FOLD); for (SectionDescriptor descriptor : descriptors) matcher.expect(descriptor); if (descriptors.length > 0) { - matcher.expect(Footer.class); - matcher.expect(SpacingItem.class); + matcher.expect(NewTabPageItem.VIEW_TYPE_FOOTER); + matcher.expect(NewTabPageItem.VIEW_TYPE_SPACING); } - matcher.expectFinished(); + matcher.expectPosition(mAdapter.getItemCount()); } /** @@ -235,22 +233,25 @@ mSource.setStatusForCategory(KnownCategories.ARTICLES, CategoryStatus.AVAILABLE); mSource.setSuggestionsForCategory(KnownCategories.ARTICLES, suggestions); - List<NewTabPageItem> loadedItems = new ArrayList<>(mAdapter.getItems()); + int numItems = mAdapter.getItemCount(); + + // From the loaded items, cut out aboveTheFold and header from the front, + // and footer and bottom spacer from the back. assertEquals(NewTabPageItem.VIEW_TYPE_ABOVE_THE_FOLD, mAdapter.getItemViewType(0)); assertEquals(NewTabPageItem.VIEW_TYPE_HEADER, mAdapter.getItemViewType(1)); - // From the loadedItems, cut out aboveTheFold and header from the front, - // and footer and bottom spacer from the back. - assertEquals(suggestions, loadedItems.subList(2, loadedItems.size() - 2)); - assertEquals( - NewTabPageItem.VIEW_TYPE_FOOTER, mAdapter.getItemViewType(loadedItems.size() - 2)); - assertEquals( - NewTabPageItem.VIEW_TYPE_SPACING, mAdapter.getItemViewType(loadedItems.size() - 1)); + assertArticlesEqual(suggestions, 2, numItems - 2); + assertEquals(NewTabPageItem.VIEW_TYPE_FOOTER, mAdapter.getItemViewType(numItems - 2)); + assertEquals(NewTabPageItem.VIEW_TYPE_SPACING, mAdapter.getItemViewType(numItems - 1)); // The adapter should ignore any new incoming data. mSource.setSuggestionsForCategory(KnownCategories.ARTICLES, Arrays.asList(new SnippetArticle[] {new SnippetArticle(0, "foo", "title1", "pub1", "txt1", "foo", "bar", 0, 0, 0, ContentSuggestionsCardLayout.FULL_CARD)})); - assertEquals(loadedItems, mAdapter.getItems()); + assertEquals(NewTabPageItem.VIEW_TYPE_ABOVE_THE_FOLD, mAdapter.getItemViewType(0)); + assertEquals(NewTabPageItem.VIEW_TYPE_HEADER, mAdapter.getItemViewType(1)); + assertArticlesEqual(suggestions, 2, numItems - 2); + assertEquals(NewTabPageItem.VIEW_TYPE_FOOTER, mAdapter.getItemViewType(numItems - 2)); + assertEquals(NewTabPageItem.VIEW_TYPE_SPACING, mAdapter.getItemViewType(numItems - 1)); } /** @@ -275,22 +276,26 @@ List<SnippetArticle> suggestions = createDummySuggestions(5); mSource.setStatusForCategory(KnownCategories.ARTICLES, CategoryStatus.AVAILABLE); mSource.setSuggestionsForCategory(KnownCategories.ARTICLES, suggestions); - List<NewTabPageItem> loadedItems = new ArrayList<>(mAdapter.getItems()); + + int numItems = mAdapter.getItemCount(); + + // From the loaded items, cut out aboveTheFold and header from the front, + // and footer and bottom spacer from the back. assertEquals(NewTabPageItem.VIEW_TYPE_ABOVE_THE_FOLD, mAdapter.getItemViewType(0)); assertEquals(NewTabPageItem.VIEW_TYPE_HEADER, mAdapter.getItemViewType(1)); - // From the loadedItems, cut out aboveTheFold and header from the front, - // and footer and bottom spacer from the back. - assertEquals(suggestions, loadedItems.subList(2, loadedItems.size() - 2)); - assertEquals( - NewTabPageItem.VIEW_TYPE_FOOTER, mAdapter.getItemViewType(loadedItems.size() - 2)); - assertEquals( - NewTabPageItem.VIEW_TYPE_SPACING, mAdapter.getItemViewType(loadedItems.size() - 1)); + assertArticlesEqual(suggestions, 2, numItems - 2); + assertEquals(NewTabPageItem.VIEW_TYPE_FOOTER, mAdapter.getItemViewType(numItems - 2)); + assertEquals(NewTabPageItem.VIEW_TYPE_SPACING, mAdapter.getItemViewType(numItems - 1)); // The adapter should ignore any new incoming data. mSource.setSuggestionsForCategory(KnownCategories.ARTICLES, Arrays.asList(new SnippetArticle[] {new SnippetArticle(0, "foo", "title1", "pub1", "txt1", "foo", "bar", 0, 0, 0, ContentSuggestionsCardLayout.FULL_CARD)})); - assertEquals(loadedItems, mAdapter.getItems()); + assertEquals(NewTabPageItem.VIEW_TYPE_ABOVE_THE_FOLD, mAdapter.getItemViewType(0)); + assertEquals(NewTabPageItem.VIEW_TYPE_HEADER, mAdapter.getItemViewType(1)); + assertArticlesEqual(suggestions, 2, numItems - 2); + assertEquals(NewTabPageItem.VIEW_TYPE_FOOTER, mAdapter.getItemViewType(numItems - 2)); + assertEquals(NewTabPageItem.VIEW_TYPE_SPACING, mAdapter.getItemViewType(numItems - 1)); } /** @@ -365,7 +370,9 @@ @Feature({"Ntp"}) public void testProgressIndicatorDisplay() { int progressPos = mAdapter.getLastContentItemPosition() - 1; - ProgressItem progress = (ProgressItem) mAdapter.getItems().get(progressPos); + SuggestionsSection section = (SuggestionsSection) mAdapter.getGroup(progressPos); + List<NewTabPageItem> items = section.getItems(); + ProgressItem progress = (ProgressItem) items.get(items.size() - 1); mSource.setStatusForCategory(KnownCategories.ARTICLES, CategoryStatus.INITIALIZING); assertTrue(progress.isVisible()); @@ -435,6 +442,7 @@ assertItemsFor(); } + /** Tests whether a section stays visible if empty, if required. */ @Test @Feature({"Ntp"}) public void testSectionVisibleIfEmpty() { @@ -552,6 +560,13 @@ assertItemsFor(sectionWithStatusCard()); } + private void assertArticlesEqual(List<SnippetArticle> articles, int start, int end) { + assertThat(mAdapter.getItemCount(), greaterThanOrEqualTo(end)); + for (int i = start; i < end; i++) { + assertEquals(articles.get(i - start), mAdapter.getSuggestionAt(i)); + } + } + /** * Tests that invalidated suggestions are immediately removed. */ @@ -562,11 +577,11 @@ mSource.setStatusForCategory(KnownCategories.ARTICLES, CategoryStatus.AVAILABLE); mSource.setSuggestionsForCategory(KnownCategories.ARTICLES, articles); assertItemsFor(section(3)); - assertEquals(articles, mAdapter.getItems().subList(2, 5)); + assertArticlesEqual(articles, 2, 5); SnippetArticle removed = articles.remove(1); mSource.fireSuggestionInvalidated(KnownCategories.ARTICLES, removed.mId); - assertEquals(articles, mAdapter.getItems().subList(2, 4)); + assertArticlesEqual(articles, 2, 4); } /**
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 1a604c7..28c1112b 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -12144,6 +12144,9 @@ <message name="IDS_FLAGS_ENABLE_WEB_NOTIFICATION_CUSTOM_LAYOUTS_DESCRIPTION" desc="Description for the flag to enable custom layouts for Web Notifications."> Enable custom layouts for Web Notifications. They will have subtle layout improvements that are otherwise not possible. </message> + <message name="IDS_NOTIFICATION_REPLY_PLACEHOLDER" desc="Placeholder text shown in the text box before any text is entered when replying directly to a notification."> + Send message + </message> </if> <!-- Mac AppleScript -->
diff --git a/chrome/browser/android/vr_shell/ui_scene.cc b/chrome/browser/android/vr_shell/ui_scene.cc index 95429af..66af8897 100644 --- a/chrome/browser/android/vr_shell/ui_scene.cc +++ b/chrome/browser/android/vr_shell/ui_scene.cc
@@ -217,7 +217,7 @@ } void UiScene::AddAnimationFromDict(const base::DictionaryValue& dict, - int64_t time) { + int64_t time_in_micro) { int animation_id; int element_id; Animation::Property property; @@ -249,7 +249,7 @@ ParseEndpointToFloats(property, *from_dict, &from); } - int64_t start = time + (long)(start_time_ms * 1000.0); + int64_t start = time_in_micro + (long)(start_time_ms * 1000.0); int64_t duration = duration_ms * 1000.0; ContentRectangle* element = GetUiElementById(element_id); @@ -273,8 +273,9 @@ } } -void UiScene::HandleCommands(const base::ListValue& commands, int64_t time) { - for (auto& item : commands) { +void UiScene::HandleCommands(const base::ListValue* commands, + int64_t time_in_micro) { + for (auto& item : *commands) { base::DictionaryValue* dict; CHECK(item->GetAsDictionary(&dict)); @@ -297,7 +298,7 @@ break; } case Command::ADD_ANIMATION: - AddAnimationFromDict(*data, time); + AddAnimationFromDict(*data, time_in_micro); break; case Command::REMOVE_ANIMATION: { int element_id, animation_id; @@ -310,10 +311,10 @@ } } -void UiScene::UpdateTransforms(float screen_tilt, int64_t time) { +void UiScene::UpdateTransforms(float screen_tilt, int64_t time_in_micro) { // Process all animations before calculating object transforms. for (auto& element : ui_elements_) { - element->Animate(time); + element->Animate(time_in_micro); } for (auto& element : ui_elements_) { element->transform.MakeIdentity(); @@ -341,6 +342,11 @@ UiScene::~UiScene() = default; +int64_t UiScene::TimeInMicroseconds() { + return std::chrono::duration_cast<std::chrono::microseconds>( + std::chrono::steady_clock::now().time_since_epoch()).count(); +} + void UiScene::ApplyRecursiveTransforms(const ContentRectangle& element, ReversibleTransform* transform) { transform->Scale(element.scale.x, element.scale.y, element.scale.z);
diff --git a/chrome/browser/android/vr_shell/ui_scene.h b/chrome/browser/android/vr_shell/ui_scene.h index 905fbe4..a5a33d8 100644 --- a/chrome/browser/android/vr_shell/ui_scene.h +++ b/chrome/browser/android/vr_shell/ui_scene.h
@@ -41,7 +41,8 @@ void AddAnimation(int element_id, std::unique_ptr<Animation>& animation); // Add an animation according to a dictionary passed from the UI HTML. - void AddAnimationFromDict(const base::DictionaryValue& dict, int64_t time); + void AddAnimationFromDict(const base::DictionaryValue& dict, + int64_t time_in_micro); // Remove |animation_id| from element |element_id|. void RemoveAnimation(int element_id, int animation_id); @@ -49,15 +50,18 @@ // Update the positions of all elements in the scene, according to active // animations, desired screen tilt and time. The units of time are // arbitrary, but must match the unit used in animations. - void UpdateTransforms(float screen_tilt, int64_t time); + void UpdateTransforms(float screen_tilt, int64_t time_in_micro); // Handle a batch of commands passed from the UI HTML. - void HandleCommands(const base::ListValue& commands, int64_t time); + void HandleCommands(const base::ListValue* commands, int64_t time_in_micro); const std::vector<std::unique_ptr<ContentRectangle>>& GetUiElements() const; ContentRectangle* GetUiElementById(int element_id); + // Return a monotonic time in microseconds for coordinating animations. + static int64_t TimeInMicroseconds(); + private: void ApplyRecursiveTransforms(const ContentRectangle& element, ReversibleTransform* transform);
diff --git a/chrome/browser/android/vr_shell/vr_shell.cc b/chrome/browser/android/vr_shell/vr_shell.cc index 8a6b659..6ee0767 100644 --- a/chrome/browser/android/vr_shell/vr_shell.cc +++ b/chrome/browser/android/vr_shell/vr_shell.cc
@@ -275,14 +275,14 @@ if (webvr_mode_) { DrawWebVr(); } else { - DrawVrShell(target_time.monotonic_system_time_nanos); + DrawVrShell(); } frame.Unbind(); frame.Submit(*buffer_viewport_list_, head_pose_); } -void VrShell::DrawVrShell(int64_t time) { +void VrShell::DrawVrShell() { float screen_tilt = desktop_screen_tilt_ * M_PI / 180.0f; gvr::Vec3f headPos = getTranslation(head_pose_); @@ -299,8 +299,10 @@ desktop_plane_->translation = desktop_position_; + HandleQueuedTasks(); + // Update the render position of all UI elements (including desktop). - scene_.UpdateTransforms(screen_tilt, time); + scene_.UpdateTransforms(screen_tilt, UiScene::TimeInMicroseconds()); UpdateController(); @@ -366,8 +368,13 @@ copy_rect = {0, 0, 1, 1}; texture_handle = content_texture_id_; } else { - // TODO(cjgrant): Populate UI texture and allow rendering. - continue; + copy_rect.x = static_cast<float>(rect->copy_rect.x) / ui_tex_width_; + copy_rect.y = static_cast<float>(rect->copy_rect.y) / ui_tex_height_; + copy_rect.width = static_cast<float>(rect->copy_rect.width) / + ui_tex_width_; + copy_rect.height = static_cast<float>(rect->copy_rect.height) / + ui_tex_height_; + texture_handle = ui_texture_id_; } vr_shell_renderer_->GetTexturedQuadRenderer()->Draw( @@ -507,6 +514,32 @@ ui_compositor_->SurfaceChanged((int)width, (int)height, surface); } +UiScene* VrShell::GetScene() { + return &scene_; +} + +void VrShell::QueueTask(base::Callback<void()>& callback) { + base::AutoLock lock(task_queue_lock_); + task_queue_.push(callback); +} + +void VrShell::HandleQueuedTasks() { + // To protect a stream of tasks from blocking rendering indefinitely, + // process only the number of tasks present when first checked. + std::vector<base::Callback<void()>> tasks; + { + base::AutoLock lock(task_queue_lock_); + const size_t count = task_queue_.size(); + for (size_t i = 0; i < count; i++) { + tasks.push_back(task_queue_.front()); + task_queue_.pop(); + } + } + for (auto &task : tasks) { + task.Run(); + } +} + // ---------------------------------------------------------------------------- // Native JNI methods // ----------------------------------------------------------------------------
diff --git a/chrome/browser/android/vr_shell/vr_shell.h b/chrome/browser/android/vr_shell/vr_shell.h index 518ec83..0f18ae2e 100644 --- a/chrome/browser/android/vr_shell/vr_shell.h +++ b/chrome/browser/android/vr_shell/vr_shell.h
@@ -12,6 +12,7 @@ #include "base/android/jni_weak_ref.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" +#include "base/synchronization/lock.h" #include "chrome/browser/android/vr_shell/ui_elements.h" #include "chrome/browser/android/vr_shell/ui_scene.h" #include "device/vr/android/gvr/gvr_delegate.h" @@ -62,6 +63,7 @@ // html/js UI hooks. static base::WeakPtr<VrShell> GetWeakPtr(); + UiScene* GetScene(); void OnDomContentsLoaded(); void SetUiTextureSize(int width, int height); @@ -84,10 +86,14 @@ jint height, const base::android::JavaParamRef<jobject>& surface); + // Called from non-render thread to queue a callback onto the render thread. + // The render thread checks for callbacks and processes them between frames. + void QueueTask(base::Callback<void()>& callback); + private: virtual ~VrShell(); void LoadUIContent(); - void DrawVrShell(int64_t time); + void DrawVrShell(); void DrawEye(const gvr::Mat4f& view_matrix, const gvr::BufferViewport& params); void DrawContentRect(); @@ -97,6 +103,8 @@ void UpdateController(); + void HandleQueuedTasks(); + // samplerExternalOES texture data for UI content image. jint ui_texture_id_ = 0; // samplerExternalOES texture data for main content image. @@ -124,6 +132,9 @@ gvr::Sizei render_size_; float cursor_distance_; + std::queue<base::Callback<void()>> task_queue_; + base::Lock task_queue_lock_; + std::unique_ptr<VrCompositor> content_compositor_; content::ContentViewCore* content_cvc_; std::unique_ptr<VrCompositor> ui_compositor_;
diff --git a/chrome/browser/chromeos/extensions/device_local_account_management_policy_provider.cc b/chrome/browser/chromeos/extensions/device_local_account_management_policy_provider.cc index fbb3fe3..b43173d 100644 --- a/chrome/browser/chromeos/extensions/device_local_account_management_policy_provider.cc +++ b/chrome/browser/chromeos/extensions/device_local_account_management_policy_provider.cc
@@ -37,6 +37,7 @@ "ngjnkanfphagcaokhjecbgkboelgfcnf", // Print button "gbchcmhmhahfdphkhkmpfmihenigjmpp", // Chrome Remote Desktop "cjanmonomjogheabiocdamfpknlpdehm", // HP printer driver + "ioofdkhojeeimmagbjbknkejkgbphdfl", // RICOH Print for Chrome "pmnllmkmjilbojkpgplbdmckghmaocjh", // Scan app by François Beaufort "khpfeaanjngmcnplbdlpegiifgpfgdco", // Smart Card Connector App "haeblkpifdemlfnkogkipmghfcbonief", // Charismathics Smart Card Middleware
diff --git a/chrome/browser/media/webrtc/webrtc_browsertest.cc b/chrome/browser/media/webrtc/webrtc_browsertest.cc index f2abe3de..10ead6a 100644 --- a/chrome/browser/media/webrtc/webrtc_browsertest.cc +++ b/chrome/browser/media/webrtc/webrtc_browsertest.cc
@@ -49,6 +49,12 @@ // Flag used by TestWebAudioMediaStream to force garbage collection. command_line->AppendSwitchASCII(switches::kJavaScriptFlags, "--expose-gc"); + + // Flag used by |RunsAudioVideoWebRTCCallInTwoTabsGetStatsPromise|. + // TODO(hbos): Remove this when bug crbug.com/627816 is resolved (when this + // flag is removed). + command_line->AppendSwitchASCII(switches::kEnableBlinkFeatures, + "RTCPeerConnectionNewGetStats"); } void RunsAudioVideoWebRTCCallInTwoTabs( @@ -198,13 +204,25 @@ } IN_PROC_BROWSER_TEST_F(WebRtcBrowserTest, - RunsAudioVideoWebRTCCallInTwoTabsGetStats) { + RunsAudioVideoWebRTCCallInTwoTabsGetStatsCallback) { StartServerAndOpenTabs(); SetupPeerconnectionWithLocalStream(left_tab_); SetupPeerconnectionWithLocalStream(right_tab_); NegotiateCall(left_tab_, right_tab_); - VerifyStatsGenerated(left_tab_); + VerifyStatsGeneratedCallback(left_tab_); + + DetectVideoAndHangUp(); +} + +IN_PROC_BROWSER_TEST_F(WebRtcBrowserTest, + RunsAudioVideoWebRTCCallInTwoTabsGetStatsPromise) { + StartServerAndOpenTabs(); + SetupPeerconnectionWithLocalStream(left_tab_); + SetupPeerconnectionWithLocalStream(right_tab_); + NegotiateCall(left_tab_, right_tab_); + + VerifyStatsGeneratedPromise(left_tab_); DetectVideoAndHangUp(); }
diff --git a/chrome/browser/media/webrtc/webrtc_browsertest_base.cc b/chrome/browser/media/webrtc/webrtc_browsertest_base.cc index 6c3bcd69..107b49f6 100644 --- a/chrome/browser/media/webrtc/webrtc_browsertest_base.cc +++ b/chrome/browser/media/webrtc/webrtc_browsertest_base.cc
@@ -455,10 +455,17 @@ EXPECT_EQ("ok-generated-and-cloned", ExecuteJavascript(javascript, tab)); } -void WebRtcTestBase::VerifyStatsGenerated(content::WebContents* tab) const { +void WebRtcTestBase::VerifyStatsGeneratedCallback( + content::WebContents* tab) const { EXPECT_EQ("ok-got-stats", ExecuteJavascript("verifyStatsGenerated()", tab)); } +void WebRtcTestBase::VerifyStatsGeneratedPromise( + content::WebContents* tab) const { + EXPECT_EQ("ok-got-stats", + ExecuteJavascript("verifyStatsGeneratedPromise()", tab)); +} + void WebRtcTestBase::SetDefaultVideoCodec( content::WebContents* tab, const std::string& video_codec) const {
diff --git a/chrome/browser/media/webrtc/webrtc_browsertest_base.h b/chrome/browser/media/webrtc/webrtc_browsertest_base.h index c33b2f5..571e1a1 100644 --- a/chrome/browser/media/webrtc/webrtc_browsertest_base.h +++ b/chrome/browser/media/webrtc/webrtc_browsertest_base.h
@@ -161,7 +161,8 @@ void GenerateAndCloneCertificate(content::WebContents* tab, const std::string& keygen_algorithm) const; - void VerifyStatsGenerated(content::WebContents* tab) const; + void VerifyStatsGeneratedCallback(content::WebContents* tab) const; + void VerifyStatsGeneratedPromise(content::WebContents* tab) const; // Change the default video codec in the offer SDP. void SetDefaultVideoCodec(content::WebContents* tab,
diff --git a/chrome/browser/notifications/notification_platform_bridge_android.cc b/chrome/browser/notifications/notification_platform_bridge_android.cc index 9c3075a..5b279fe 100644 --- a/chrome/browser/notifications/notification_platform_bridge_android.cc +++ b/chrome/browser/notifications/notification_platform_bridge_android.cc
@@ -12,6 +12,7 @@ #include "base/command_line.h" #include "base/files/file_path.h" #include "base/logging.h" +#include "base/strings/utf_string_conversions.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/notifications/native_notification_display_service.h" #include "chrome/browser/notifications/notification.h" @@ -218,12 +219,34 @@ if (!badge_bitmap.drawsNothing()) badge = gfx::ConvertToJavaBitmap(&badge_bitmap); + // TODO(crbug.com/650302): Combine these action_* vectors into a single vector + // of objects. std::vector<base::string16> action_titles_vector; - for (const message_center::ButtonInfo& button : notification.buttons()) + std::vector<base::string16> action_types_vector; + std::vector<base::string16> action_placeholders_vector; + for (const message_center::ButtonInfo& button : notification.buttons()) { action_titles_vector.push_back(button.title); + action_placeholders_vector.push_back(button.placeholder); + base::string16 type; + switch (button.type) { + case message_center::ButtonType::BUTTON: + type = base::ASCIIToUTF16("button"); + break; + case message_center::ButtonType::TEXT: + type = base::ASCIIToUTF16("text"); + break; + } + action_types_vector.push_back(std::move(type)); + } ScopedJavaLocalRef<jobjectArray> action_titles = base::android::ToJavaArrayOfStrings(env, action_titles_vector); + ScopedJavaLocalRef<jobjectArray> action_types = + base::android::ToJavaArrayOfStrings(env, action_types_vector); + + ScopedJavaLocalRef<jobjectArray> action_placeholders = + base::android::ToJavaArrayOfStrings(env, action_placeholders_vector); + ScopedJavaLocalRef<jobjectArray> action_icons = ConvertToJavaBitmaps(notification.buttons()); @@ -238,7 +261,7 @@ tag, webapk_package, title, body, image, notification_icon, badge, vibration_pattern, notification.timestamp().ToJavaTime(), notification.renotify(), notification.silent(), action_titles, - action_icons); + action_icons, action_types, action_placeholders); regenerated_notification_infos_[notification_id] = RegeneratedNotificationInfo(origin_url.spec(), notification.tag(),
diff --git a/chrome/browser/notifications/platform_notification_service_impl.cc b/chrome/browser/notifications/platform_notification_service_impl.cc index 7b1472a..048fe0a 100644 --- a/chrome/browser/notifications/platform_notification_service_impl.cc +++ b/chrome/browser/notifications/platform_notification_service_impl.cc
@@ -25,6 +25,7 @@ #include "chrome/browser/ui/browser.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/pref_names.h" +#include "chrome/grit/generated_resources.h" #include "components/content_settings/core/browser/host_content_settings_map.h" #include "components/content_settings/core/common/content_settings.h" #include "components/content_settings/core/common/content_settings_types.h" @@ -38,7 +39,9 @@ #include "content/public/browser/user_metrics.h" #include "content/public/common/notification_resources.h" #include "content/public/common/platform_notification_data.h" +#include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h" +#include "ui/message_center/notification.h" #include "ui/message_center/notification_types.h" #include "ui/message_center/notifier_settings.h" #include "url/url_constants.h" @@ -443,11 +446,25 @@ // Developer supplied action buttons. std::vector<message_center::ButtonInfo> buttons; for (size_t i = 0; i < notification_data.actions.size(); i++) { - message_center::ButtonInfo button(notification_data.actions[i].title); + content::PlatformNotificationAction const& action = + notification_data.actions[i]; + message_center::ButtonInfo button(action.title); // TODO(peter): Handle different screen densities instead of always using // the 1x bitmap - crbug.com/585815. button.icon = gfx::Image::CreateFrom1xBitmap(notification_resources.action_icons[i]); + button.placeholder = + action.placeholder.is_null() + ? l10n_util::GetStringUTF16(IDS_NOTIFICATION_REPLY_PLACEHOLDER) + : action.placeholder.string(); + switch (action.type) { + case content::PLATFORM_NOTIFICATION_ACTION_TYPE_BUTTON: + button.type = message_center::ButtonType::BUTTON; + break; + case content::PLATFORM_NOTIFICATION_ACTION_TYPE_TEXT: + button.type = message_center::ButtonType::TEXT; + break; + } buttons.push_back(button); } notification.set_buttons(buttons);
diff --git a/chrome/browser/password_manager/chrome_password_manager_client.cc b/chrome/browser/password_manager/chrome_password_manager_client.cc index 31f18936..437ae9f 100644 --- a/chrome/browser/password_manager/chrome_password_manager_client.cc +++ b/chrome/browser/password_manager/chrome_password_manager_client.cc
@@ -636,6 +636,12 @@ ChromePasswordManagerClient* instance = ChromePasswordManagerClient::FromWebContents(web_contents); - DCHECK(instance); + + // Try to bind to the driver, but if driver is not available for this render + // frame host, the request will be just dropped. This will cause the message + // pipe to be closed, which will raise a connection error on the peer side. + if (!instance) + return; + instance->credential_manager_impl_.BindRequest(std::move(request)); }
diff --git a/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc b/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc index 82edfffa..b47c576 100644 --- a/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc +++ b/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc
@@ -549,3 +549,21 @@ SerializedNavigationEntry::HAS_PASSWORD_FIELD, GetPasswordStateFromNavigation(*controller().GetLastCommittedEntry())); } + +// Handle missing ChromePasswordManagerClient instance in BindCredentialManager +// gracefully. +TEST_F(ChromePasswordManagerClientTest, BindCredentialManager_MissingInstance) { + // Create a WebContent without tab helpers. + std::unique_ptr<content::WebContents> web_contents( + content::WebContents::Create( + content::WebContents::CreateParams(profile()))); + // In particular, this WebContent should not have the + // ChromePasswordManagerClient. + ASSERT_FALSE( + ChromePasswordManagerClient::FromWebContents(web_contents.get())); + + // This call should not crash. + ChromePasswordManagerClient::BindCredentialManager( + web_contents->GetMainFrame(), + password_manager::mojom::CredentialManagerRequest()); +}
diff --git a/chrome/browser/resources/vr_shell/vr_shell_ui.js b/chrome/browser/resources/vr_shell/vr_shell_ui.js index aacdb534..7c14b72f 100644 --- a/chrome/browser/resources/vr_shell/vr_shell_ui.js +++ b/chrome/browser/resources/vr_shell/vr_shell_ui.js
@@ -14,10 +14,9 @@ * @const */ var XAnchoring = Object.freeze({ - 'XLEFT': 0, - 'XRIGHT': 1, - 'XCENTER': 2, - 'XNONE': 3 + 'XNONE': 0, + 'XLEFT': 1, + 'XRIGHT': 2 }); /** @@ -26,10 +25,9 @@ * @const */ var YAnchoring = Object.freeze({ - 'YTOP': 0, - 'YBOTTOM': 1, - 'YCENTER': 2, - 'YNONE': 3 + 'YNONE': 0, + 'YTOP': 1, + 'YBOTTOM': 2 }); /** @@ -58,6 +56,19 @@ }); /** + * Enumeration of scene update commands. + * @enum {number} + * @const + */ + var Command = Object.freeze({ + 'ADD_ELEMENT': 0, + 'UPDATE_ELEMENT': 1, + 'REMOVE_ELEMENT': 2, + 'ADD_ANIMATION': 3, + 'REMOVE_ANIMATION': 4 + }); + + /** * @type {number} Id generator. */ var idIndex = 1; @@ -80,7 +91,6 @@ this.size = { x: metersX, y: metersY }; this.xAnchoring = XAnchoring.XNONE; this.yAnchoring = YAnchoring.YNONE; - this.anchorZ = false; this.translation = { x: 0, y: 0, z: 0 }; this.orientationAxisAngle = { x: 0, y: 0, z: 0, a: 0 }; this.rotationAxisAngle = { x: 0, y: 0, z: 0, a: 0 }; @@ -104,15 +114,13 @@ } /** - * Anchoring allows a rectangle to be positioned relative to the content - * window. X and Y values should be XAnchoring and YAnchoring elements. - * anchorZ is a boolean. - * Example: rect.setAnchoring(XAnchoring.XCENTER, YAnchoring.YBOTTOM, true); + * Anchoring allows a rectangle to be positioned relative to the edge of + * content window. Values should be XAnchoring and YAnchoring elements. + * Example: rect.setAnchoring(XAnchoring.XNONE, YAnchoring.YBOTTOM); */ setAnchoring(x, y, z) { this.xAnchoring = x; this.yAnchoring = y; - this.anchorZ = z; } }; @@ -191,7 +199,8 @@ // Add a UI rectangle for the button. var el = new UiElement(50 * i, 200, 50, 50, buttonWidth, buttonHeight); - el.setAnchoring(XAnchoring.XCENTER, YAnchoring.YBOTTOM, true); + el.parentId = 0; + el.setAnchoring(XAnchoring.XNONE, YAnchoring.YBOTTOM); el.setTranslation(buttonStartPosition + buttonSpacing * i, -0.3, 0.0); var id = idIndex++; addMesh(id, el); @@ -216,12 +225,30 @@ chrome.send('domLoaded', [window.innerWidth, window.innerHeight]); } - function addAnimations(animations) { - chrome.send('addAnimations', animations); + function addMesh(id, mesh) { + mesh.id = id; + chrome.send('updateScene', [{ + 'type': Command.ADD_ELEMENT, + 'data': mesh + }]); } - function addMesh(id, mesh) { - chrome.send('addMesh', [id, mesh]); + function removeMesh(id) { + chrome.send('updateScene', [{ + 'type': Command.REMOVE_ELEMENT, + 'data': {'id': id} + }]); + } + + function addAnimations(animations) { + var commands = []; + for (var i = 0; i < animations.length; i++) { + commands.push({ + 'type': Command.ADD_ANIMATION, + 'data': animations[i] + }); + } + chrome.send('updateScene', commands); } return {
diff --git a/chrome/browser/ui/webui/vr_shell/vr_shell_ui_message_handler.cc b/chrome/browser/ui/webui/vr_shell/vr_shell_ui_message_handler.cc index 4b4b3ec..a4d28369 100644 --- a/chrome/browser/ui/webui/vr_shell/vr_shell_ui_message_handler.cc +++ b/chrome/browser/ui/webui/vr_shell/vr_shell_ui_message_handler.cc
@@ -8,6 +8,7 @@ #include "base/bind.h" #include "base/bind_helpers.h" +#include "base/callback.h" #include "base/values.h" #include "chrome/browser/android/vr_shell/vr_shell.h" #include "content/public/browser/web_ui.h" @@ -23,17 +24,11 @@ "domLoaded", base::Bind(&VrShellUIMessageHandler::HandleDomLoaded, base::Unretained(this))); web_ui()->RegisterMessageCallback( - "addMesh", base::Bind(&VrShellUIMessageHandler::HandleAddMesh, + "updateScene", base::Bind(&VrShellUIMessageHandler::HandleUpdateScene, base::Unretained(this))); web_ui()->RegisterMessageCallback( - "removeMesh", base::Bind(&VrShellUIMessageHandler::HandleRemoveMesh, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( "doAction", base::Bind(&VrShellUIMessageHandler::HandleDoAction, base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "addAnimations", base::Bind(&VrShellUIMessageHandler::HandleAddAnimations, - base::Unretained(this))); } void VrShellUIMessageHandler::HandleDomLoaded(const base::ListValue* args) { @@ -50,16 +45,16 @@ vr_shell_->SetUiTextureSize(width, height); } -void VrShellUIMessageHandler::HandleAddMesh(const base::ListValue* args) { - NOTIMPLEMENTED(); -} +void VrShellUIMessageHandler::HandleUpdateScene(const base::ListValue* args) { + if (!vr_shell_) + return; -void VrShellUIMessageHandler::HandleRemoveMesh(const base::ListValue* args) { - NOTIMPLEMENTED(); -} - -void VrShellUIMessageHandler::HandleAddAnimations(const base::ListValue* args) { - NOTIMPLEMENTED(); + // Copy the update instructions and handle them on the render thread. + auto cb = base::Bind(&vr_shell::UiScene::HandleCommands, + base::Unretained(vr_shell_->GetScene()), + base::Owned(args->CreateDeepCopy().release()), + vr_shell::UiScene::TimeInMicroseconds()); + vr_shell_->QueueTask(cb); } void VrShellUIMessageHandler::HandleDoAction(const base::ListValue* args) {
diff --git a/chrome/browser/ui/webui/vr_shell/vr_shell_ui_message_handler.h b/chrome/browser/ui/webui/vr_shell/vr_shell_ui_message_handler.h index 5a87fa2a..6fd3370c 100644 --- a/chrome/browser/ui/webui/vr_shell/vr_shell_ui_message_handler.h +++ b/chrome/browser/ui/webui/vr_shell/vr_shell_ui_message_handler.h
@@ -29,9 +29,7 @@ void RegisterMessages() override; void HandleDomLoaded(const base::ListValue* args); - void HandleAddMesh(const base::ListValue* args); - void HandleRemoveMesh(const base::ListValue* args); - void HandleAddAnimations(const base::ListValue* args); + void HandleUpdateScene(const base::ListValue* args); void HandleDoAction(const base::ListValue* args); base::WeakPtr<vr_shell::VrShell> vr_shell_;
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 2dd0e902..b01586da 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -1360,7 +1360,6 @@ "../browser/extensions/api/autofill_private/autofill_private_apitest.cc", "../browser/extensions/api/automation/automation_apitest.cc", "../browser/extensions/api/autotest_private/autotest_private_apitest.cc", - "../browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_apitest.cc", "../browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_apitest_chromeos.cc", "../browser/extensions/api/bookmark_manager_private/bookmark_manager_private_apitest.cc", "../browser/extensions/api/bookmarks/bookmark_apitest.cc", @@ -2659,6 +2658,10 @@ ] } } + + if (is_chromeos || (is_linux && use_dbus)) { + sources += [ "../browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_apitest.cc" ] + } } }
diff --git a/chrome/test/data/webrtc/peerconnection_getstats.js b/chrome/test/data/webrtc/peerconnection_getstats.js new file mode 100644 index 0000000..9258a36 --- /dev/null +++ b/chrome/test/data/webrtc/peerconnection_getstats.js
@@ -0,0 +1,46 @@ +/** + * Copyright 2016 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +// Public interface to tests. These are expected to be called with +// ExecuteJavascript invocations from the browser tests and will return answers +// through the DOM automation controller. + +/** + * Verifies that the promise-based |RTCPeerConnection.getStats| returns stats. + * + * Returns ok-got-stats on success. + */ +function verifyStatsGeneratedPromise() { + peerConnection_().getStats() + .then(function(report) { + if (report == null || report.size == 0) + throw new failTest('report is null or empty.'); + // Sanity check that applies to all stats. + var ids = new Set(); + report.forEach(function(stats) { + if (typeof(stats.id) !== 'string') + throw failTest('stats.id is not a string.'); + if (ids.has(stats.id)) + throw failTest('stats.id is not a unique identifier.'); + ids.add(stats.id); + if (typeof(stats.timestamp) !== 'number' || stats.timestamp <= 0) + throw failTest('stats.timestamp is not a positive number.'); + if (typeof(stats.type) !== 'string') + throw failTest('stats.type is not a string.'); + }); + // TODO(hbos): When the new stats collection API is more mature (and + // certainly before unflagging the new stats API) add a whitelist of + // allowed stats to prevent accidentally exposing stats to the web that + // are not in the spec and that verifies type information. Status at + // crbug.com/627816. Stats collection is tested in the WebRTC repo and + // automatically surfaced to Blink, but there should be a process of + // having to land a Blink CL in order to expose a new RTCStats dictionary. + returnToTest('ok-got-stats'); + }, + function(e) { + throw failTest('Promise was rejected: ' + e); + }); +}
diff --git a/chrome/test/data/webrtc/webrtc_jsep01_test.html b/chrome/test/data/webrtc/webrtc_jsep01_test.html index 6928546..cc737be 100644 --- a/chrome/test/data/webrtc/webrtc_jsep01_test.html +++ b/chrome/test/data/webrtc/webrtc_jsep01_test.html
@@ -10,6 +10,7 @@ <script type="text/javascript" src="video_detector.js"></script> <script type="text/javascript" src="media_devices.js"></script> <script type="text/javascript" src="indexeddb.js"></script> + <script type="text/javascript" src="peerconnection_getstats.js"></script> </head> <body> <table border="0">
diff --git a/components/ntp_snippets/bookmarks/bookmark_suggestions_provider.h b/components/ntp_snippets/bookmarks/bookmark_suggestions_provider.h index 7f75a2e..79b8718 100644 --- a/components/ntp_snippets/bookmarks/bookmark_suggestions_provider.h +++ b/components/ntp_snippets/bookmarks/bookmark_suggestions_provider.h
@@ -19,7 +19,7 @@ namespace gfx { class Image; -} +} // namespace gfx namespace ntp_snippets {
diff --git a/components/ntp_snippets/content_suggestions_provider.h b/components/ntp_snippets/content_suggestions_provider.h index d479eec..bc568f5 100644 --- a/components/ntp_snippets/content_suggestions_provider.h +++ b/components/ntp_snippets/content_suggestions_provider.h
@@ -16,7 +16,7 @@ namespace gfx { class Image; -} +} // namespace gfx namespace ntp_snippets {
diff --git a/components/ntp_snippets/content_suggestions_service.h b/components/ntp_snippets/content_suggestions_service.h index a038fbfe..8c4a4f7 100644 --- a/components/ntp_snippets/content_suggestions_service.h +++ b/components/ntp_snippets/content_suggestions_service.h
@@ -28,7 +28,7 @@ namespace gfx { class Image; -} +} // namespace gfx namespace ntp_snippets { @@ -76,7 +76,7 @@ virtual void ContentSuggestionsServiceShutdown() = 0; protected: - virtual ~Observer() {} + virtual ~Observer() = default; }; enum State {
diff --git a/components/ntp_snippets/ntp_snippet.h b/components/ntp_snippets/ntp_snippet.h index 01a81da..def1b88 100644 --- a/components/ntp_snippets/ntp_snippet.h +++ b/components/ntp_snippets/ntp_snippet.h
@@ -17,7 +17,7 @@ namespace base { class DictionaryValue; -} +} // namespace base namespace ntp_snippets { @@ -40,7 +40,7 @@ // Creates a new snippet with the given |id|. // Public for testing only - create snippets using the Create* methods below. // TODO(treib): Make this private and add a CreateSnippetForTest? - NTPSnippet(const std::string& id); + explicit NTPSnippet(const std::string& id); ~NTPSnippet();
diff --git a/components/ntp_snippets/ntp_snippets_database.h b/components/ntp_snippets/ntp_snippets_database.h index 8abc9809878b..dc5131c 100644 --- a/components/ntp_snippets/ntp_snippets_database.h +++ b/components/ntp_snippets/ntp_snippets_database.h
@@ -20,7 +20,7 @@ namespace base { class FilePath; -} +} // namespace base namespace ntp_snippets {
diff --git a/components/ntp_snippets/ntp_snippets_fetcher.h b/components/ntp_snippets/ntp_snippets_fetcher.h index 782dd73..03276c8 100644 --- a/components/ntp_snippets/ntp_snippets_fetcher.h +++ b/components/ntp_snippets/ntp_snippets_fetcher.h
@@ -48,7 +48,7 @@ base::string16 localized_title; // Ignored for non-server categories. NTPSnippet::PtrVector snippets; - FetchedCategory(Category c); + explicit FetchedCategory(Category c); FetchedCategory(FetchedCategory&&); // = default, in .cc ~FetchedCategory(); // = default, in .cc FetchedCategory& operator=(FetchedCategory&&); // = default, in .cc
diff --git a/components/ntp_snippets/ntp_snippets_service.h b/components/ntp_snippets/ntp_snippets_service.h index 1a1f0ab..1aac5ec6 100644 --- a/components/ntp_snippets/ntp_snippets_service.h +++ b/components/ntp_snippets/ntp_snippets_service.h
@@ -5,8 +5,7 @@ #ifndef COMPONENTS_NTP_SNIPPETS_NTP_SNIPPETS_SERVICE_H_ #define COMPONENTS_NTP_SNIPPETS_NTP_SNIPPETS_SERVICE_H_ -#include <stddef.h> - +#include <cstddef> #include <map> #include <memory> #include <set> @@ -34,16 +33,16 @@ namespace gfx { class Image; -} +} // namespace gfx namespace image_fetcher { class ImageDecoder; class ImageFetcher; -} +} // namespace image_fetcher namespace suggestions { class SuggestionsProfile; -} +} // namespace suggestions namespace ntp_snippets { @@ -51,6 +50,9 @@ // Retrieves fresh content data (articles) from the server, stores them and // provides them as content suggestions. +// This class is final because it does things in its constructor which make it +// unsafe to derive from it. +// TODO(treib): Introduce two-phase initialization and make the class not final? // TODO(pke): Rename this service to ArticleSuggestionsProvider and move to // a subdirectory. // TODO(jkrcal): this class grows really, really large. The fact that @@ -59,8 +61,8 @@ // ImagerFetcherDeletage ;-)). Instead, the cleaner solution would be to define // a CachedImageFetcher class that handles the caching aspects and looks like an // image fetcher to the NTPSnippetService. -class NTPSnippetsService : public ContentSuggestionsProvider, - public image_fetcher::ImageFetcherDelegate { +class NTPSnippetsService final : public ContentSuggestionsProvider, + public image_fetcher::ImageFetcherDelegate { public: // |application_language_code| should be a ISO 639-1 compliant string, e.g. // 'en' or 'en-US'. Note that this code should only specify the language, not
diff --git a/components/ntp_snippets/ntp_snippets_status_service.h b/components/ntp_snippets/ntp_snippets_status_service.h index d6a9516..bd52c136 100644 --- a/components/ntp_snippets/ntp_snippets_status_service.h +++ b/components/ntp_snippets/ntp_snippets_status_service.h
@@ -29,7 +29,7 @@ // relevant changes in their states. class NTPSnippetsStatusService : public SigninManagerBase::Observer { public: - typedef base::Callback<void(DisabledReason)> DisabledReasonChangeCallback; + using DisabledReasonChangeCallback = base::Callback<void(DisabledReason)>; NTPSnippetsStatusService(SigninManagerBase* signin_manager, PrefService* pref_service);
diff --git a/components/ntp_snippets/offline_pages/offline_page_proxy.h b/components/ntp_snippets/offline_pages/offline_page_proxy.h index 779110a..a4649471 100644 --- a/components/ntp_snippets/offline_pages/offline_page_proxy.h +++ b/components/ntp_snippets/offline_pages/offline_page_proxy.h
@@ -37,10 +37,11 @@ const offline_pages::ClientId& client_id) = 0; protected: - virtual ~Observer() {} + virtual ~Observer() = default; }; - OfflinePageProxy(offline_pages::OfflinePageModel* offline_page_model); + explicit OfflinePageProxy( + offline_pages::OfflinePageModel* offline_page_model); // TODO(vitaliii): Remove this function and provide a better way for providers // to get data at the start up, while querying OfflinePagesModel only once.
diff --git a/components/ntp_snippets/offline_pages/offline_page_suggestions_provider.cc b/components/ntp_snippets/offline_pages/offline_page_suggestions_provider.cc index ff3235d..8d489a65 100644 --- a/components/ntp_snippets/offline_pages/offline_page_suggestions_provider.cc +++ b/components/ntp_snippets/offline_pages/offline_page_suggestions_provider.cc
@@ -352,8 +352,7 @@ MakeUniqueID(category, offline_page_id)); std::set<std::string> dismissed_ids = ReadDismissedIDsFromPrefs(category); - auto it = - std::find(dismissed_ids.begin(), dismissed_ids.end(), offline_page_id); + auto it = dismissed_ids.find(offline_page_id); if (it != dismissed_ids.end()) { dismissed_ids.erase(it); StoreDismissedIDsToPrefs(category, dismissed_ids);
diff --git a/components/ntp_snippets/offline_pages/offline_page_suggestions_provider.h b/components/ntp_snippets/offline_pages/offline_page_suggestions_provider.h index c4552a6..19a058a5 100644 --- a/components/ntp_snippets/offline_pages/offline_page_suggestions_provider.h +++ b/components/ntp_snippets/offline_pages/offline_page_suggestions_provider.h
@@ -23,7 +23,7 @@ namespace gfx { class Image; -} +} // namespace gfx namespace ntp_snippets {
diff --git a/components/ntp_snippets/physical_web_pages/physical_web_page_suggestions_provider.h b/components/ntp_snippets/physical_web_pages/physical_web_page_suggestions_provider.h index f79e43b..b2c7431a 100644 --- a/components/ntp_snippets/physical_web_pages/physical_web_page_suggestions_provider.h +++ b/components/ntp_snippets/physical_web_pages/physical_web_page_suggestions_provider.h
@@ -17,7 +17,7 @@ namespace gfx { class Image; -} +} // namespace gfx namespace ntp_snippets {
diff --git a/components/ntp_snippets/sessions/foreign_sessions_suggestions_provider.h b/components/ntp_snippets/sessions/foreign_sessions_suggestions_provider.h index 57cd53eb..bb9540b9 100644 --- a/components/ntp_snippets/sessions/foreign_sessions_suggestions_provider.h +++ b/components/ntp_snippets/sessions/foreign_sessions_suggestions_provider.h
@@ -26,7 +26,7 @@ // Simple interface to get foreign tab data on demand and on change. class ForeignSessionsProvider { public: - virtual ~ForeignSessionsProvider() {} + virtual ~ForeignSessionsProvider() = default; virtual bool HasSessionsData() = 0; virtual std::vector<const sync_sessions::SyncedSession*> GetAllForeignSessions() = 0;
diff --git a/components/test_runner/mock_webrtc_peer_connection_handler.cc b/components/test_runner/mock_webrtc_peer_connection_handler.cc index 0b623e0d..50c3f5b 100644 --- a/components/test_runner/mock_webrtc_peer_connection_handler.cc +++ b/components/test_runner/mock_webrtc_peer_connection_handler.cc
@@ -108,6 +108,130 @@ std::vector<std::pair<std::string, std::string>> values_; }; +template<typename T> +WebVector<T> sequenceWithValue(T value) { + return WebVector<T>(&value, 1); +} + +class MockWebRTCStatsMember : public blink::WebRTCStatsMember { + public: + MockWebRTCStatsMember( + const std::string& name, blink::WebRTCStatsMemberType type) + : name_(name), type_(type) {} + + // blink::WebRTCStatsMember overrides. + blink::WebString name() const override { + return blink::WebString::fromUTF8(name_); + } + blink::WebRTCStatsMemberType type() const override { + return type_; + } + bool isDefined() const override { return true; } + int32_t valueInt32() const override { return 42; } + uint32_t valueUint32() const override { return 42; } + int64_t valueInt64() const override { return 42; } + uint64_t valueUint64() const override { return 42; } + double valueDouble() const override { return 42.0; } + blink::WebString valueString() const override { + return blink::WebString::fromUTF8("42"); + } + WebVector<int32_t> valueSequenceInt32() const override { + return sequenceWithValue<int32_t>(42); + } + WebVector<uint32_t> valueSequenceUint32() const override { + return sequenceWithValue<uint32_t>(42); + } + WebVector<int64_t> valueSequenceInt64() const override { + return sequenceWithValue<int64_t>(42); + } + WebVector<uint64_t> valueSequenceUint64() const override { + return sequenceWithValue<uint64_t>(42); + } + WebVector<double> valueSequenceDouble() const override { + return sequenceWithValue<double>(42.0); + } + blink::WebVector<blink::WebString> valueSequenceString() const override { + return sequenceWithValue<blink::WebString>( + blink::WebString::fromUTF8("42")); + } + + private: + std::string name_; + blink::WebRTCStatsMemberType type_; +}; + +class MockWebRTCStats : public blink::WebRTCStats { + public: + MockWebRTCStats( + const std::string& id, const std::string& type, double timestamp) + : id_(id), type_(type), timestamp_(timestamp) { + } + + void addMember(const std::string& name, blink::WebRTCStatsMemberType type) { + members_.push_back(std::make_pair(name, type)); + } + + // blink::WebRTCStats overrides. + blink::WebString id() const override { + return blink::WebString::fromUTF8(id_); + } + blink::WebString type() const override { + return blink::WebString::fromUTF8(type_); + } + double timestamp() const override { + return timestamp_; + } + size_t membersCount() const override { + return members_.size(); + } + std::unique_ptr<WebRTCStatsMember> getMember(size_t i) const override { + return std::unique_ptr<WebRTCStatsMember>(new MockWebRTCStatsMember( + members_[i].first, members_[i].second)); + } + + private: + std::string id_; + std::string type_; + double timestamp_; + std::vector<std::pair<std::string, blink::WebRTCStatsMemberType>> members_; +}; + +class MockWebRTCStatsReport : public blink::WebRTCStatsReport { + public: + MockWebRTCStatsReport() : i_(0) {} + MockWebRTCStatsReport(const MockWebRTCStatsReport& other) + : stats_(other.stats_), i_(0) {} + + void AddStats(const MockWebRTCStats& stats) { + stats_.push_back(stats); + } + + // blink::WebRTCStatsReport overrides. + std::unique_ptr<blink::WebRTCStatsReport> copyHandle() const override { + // Because this is just a mock, we copy the underlying stats instead of + // referencing the same stats as the original report. + return std::unique_ptr<blink::WebRTCStatsReport>( + new MockWebRTCStatsReport(*this)); + } + std::unique_ptr<WebRTCStats> getStats(WebString id) const override { + for (const MockWebRTCStats& stats : stats_) { + if (stats.id() == id) + return std::unique_ptr<blink::WebRTCStats>(new MockWebRTCStats(stats)); + } + return nullptr; + } + std::unique_ptr<blink::WebRTCStats> next() override { + if (i_ >= stats_.size()) + return nullptr; + return std::unique_ptr<blink::WebRTCStats>( + new MockWebRTCStats(stats_[i_++])); + } + + private: + std::vector<MockWebRTCStats> stats_; + size_t i_; +}; + } // namespace MockWebRTCPeerConnectionHandler::MockWebRTCPeerConnectionHandler() @@ -393,9 +517,23 @@ void MockWebRTCPeerConnectionHandler::getStats( std::unique_ptr<blink::WebRTCStatsReportCallback> callback) { - // TODO(hbos): When blink::RTCPeerConnection starts using the new |getStats| - // this needs to be implemented. crbug.com/627816. - NOTREACHED(); + std::unique_ptr<MockWebRTCStatsReport> report(new MockWebRTCStatsReport()); + MockWebRTCStats stats("mock-stats-01", "mock-stats", 1234.0); + stats.addMember("int32", blink::WebRTCStatsMemberTypeInt32); + stats.addMember("uint32", blink::WebRTCStatsMemberTypeUint32); + stats.addMember("int64", blink::WebRTCStatsMemberTypeInt64); + stats.addMember("uint64", blink::WebRTCStatsMemberTypeUint64); + stats.addMember("double", blink::WebRTCStatsMemberTypeDouble); + stats.addMember("string", blink::WebRTCStatsMemberTypeString); + stats.addMember("sequenceInt32", blink::WebRTCStatsMemberTypeSequenceInt32); + stats.addMember("sequenceUint32", blink::WebRTCStatsMemberTypeSequenceUint32); + stats.addMember("sequenceInt64", blink::WebRTCStatsMemberTypeSequenceInt64); + stats.addMember("sequenceUint64", blink::WebRTCStatsMemberTypeSequenceUint64); + stats.addMember("sequenceDouble", blink::WebRTCStatsMemberTypeSequenceDouble); + stats.addMember("sequenceString", blink::WebRTCStatsMemberTypeSequenceString); + report->AddStats(stats); + callback->OnStatsDelivered(std::unique_ptr<blink::WebRTCStatsReport>( + report.release())); } void MockWebRTCPeerConnectionHandler::ReportCreationOfDataChannel() {
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index 1c6011b..78e6dc9 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -1745,7 +1745,6 @@ switches::kMaxUntiledLayerHeight, switches::kMemoryMetrics, switches::kMojoLocalStorage, - switches::kMojoServiceWorker, switches::kMSEAudioBufferSizeLimit, switches::kMSEVideoBufferSizeLimit, switches::kNoReferrers,
diff --git a/content/browser/service_worker/embedded_worker_instance.cc b/content/browser/service_worker/embedded_worker_instance.cc index 17d4cd4..a08d207 100644 --- a/content/browser/service_worker/embedded_worker_instance.cc +++ b/content/browser/service_worker/embedded_worker_instance.cc
@@ -20,14 +20,11 @@ #include "content/common/service_worker/embedded_worker_messages.h" #include "content/common/service_worker/embedded_worker_settings.h" #include "content/common/service_worker/embedded_worker_setup.mojom.h" -#include "content/common/service_worker/embedded_worker_start_params.h" #include "content/common/service_worker/service_worker_types.h" -#include "content/common/service_worker/service_worker_utils.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/content_browser_client.h" #include "content/public/browser/render_process_host.h" #include "content/public/common/child_process_host.h" -#include "content/public/common/content_switches.h" #include "ipc/ipc_message.h" #include "services/shell/public/cpp/interface_provider.h" #include "services/shell/public/cpp/interface_registry.h" @@ -72,7 +69,7 @@ worker_process_id, worker_route_id); } -void SetupOnUI( +void RegisterToWorkerDevToolsManagerOnUI( int process_id, const ServiceWorkerContextCore* service_worker_context, const base::WeakPtr<ServiceWorkerContextCore>& service_worker_context_weak, @@ -80,7 +77,6 @@ const GURL& url, const GURL& scope, bool is_installed, - mojom::EmbeddedWorkerInstanceClientRequest request, const base::Callback<void(int worker_devtools_agent_route_id, bool wait_for_debugger)>& callback) { DCHECK_CURRENTLY_ON(BrowserThread::UI); @@ -96,8 +92,6 @@ service_worker_context, service_worker_context_weak, service_worker_version_id, url, scope), is_installed); - if (request.is_pending()) - rph->GetRemoteInterfaces()->GetInterface(std::move(request)); } BrowserThread::PostTask( BrowserThread::IO, @@ -217,11 +211,8 @@ public: enum class ProcessAllocationState { NOT_ALLOCATED, ALLOCATING, ALLOCATED }; - StartTask(EmbeddedWorkerInstance* instance, - const GURL& script_url, - mojom::EmbeddedWorkerInstanceClientRequest request) + StartTask(EmbeddedWorkerInstance* instance, const GURL& script_url) : instance_(instance), - request_(std::move(request)), state_(ProcessAllocationState::NOT_ALLOCATED), is_installed_(false), started_during_browser_startup_(false), @@ -263,7 +254,7 @@ // TODO(nhiroki): Reconsider this bizarre layering. } - void Start(std::unique_ptr<EmbeddedWorkerStartParams> params, + void Start(std::unique_ptr<EmbeddedWorkerMsg_StartWorker_Params> params, const StatusCallback& callback) { DCHECK_CURRENTLY_ON(BrowserThread::IO); state_ = ProcessAllocationState::ALLOCATING; @@ -298,11 +289,12 @@ bool is_installed() const { return is_installed_; } private: - void OnProcessAllocated(std::unique_ptr<EmbeddedWorkerStartParams> params, - ServiceWorkerStatusCode status, - int process_id, - bool is_new_process, - const EmbeddedWorkerSettings& settings) { + void OnProcessAllocated( + std::unique_ptr<EmbeddedWorkerMsg_StartWorker_Params> params, + ServiceWorkerStatusCode status, + int process_id, + bool is_new_process, + const EmbeddedWorkerSettings& settings) { DCHECK_CURRENTLY_ON(BrowserThread::IO); if (status != SERVICE_WORKER_OK) { @@ -350,22 +342,23 @@ GURL script_url(params->script_url); BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, - base::Bind(&SetupOnUI, process_id, instance_->context_.get(), - instance_->context_, service_worker_version_id, script_url, - scope, is_installed_, base::Passed(&request_), - base::Bind(&StartTask::OnSetupOnUICompleted, + base::Bind(RegisterToWorkerDevToolsManagerOnUI, process_id, + instance_->context_.get(), instance_->context_, + service_worker_version_id, script_url, scope, is_installed_, + base::Bind(&StartTask::OnRegisteredToDevToolsManager, weak_factory_.GetWeakPtr(), base::Passed(¶ms), is_new_process))); } - void OnSetupOnUICompleted(std::unique_ptr<EmbeddedWorkerStartParams> params, - bool is_new_process, - int worker_devtools_agent_route_id, - bool wait_for_debugger) { + void OnRegisteredToDevToolsManager( + std::unique_ptr<EmbeddedWorkerMsg_StartWorker_Params> params, + bool is_new_process, + int worker_devtools_agent_route_id, + bool wait_for_debugger) { DCHECK_CURRENTLY_ON(BrowserThread::IO); TRACE_EVENT_ASYNC_STEP_PAST0("ServiceWorker", "EmbeddedWorkerInstance::Start", this, - "OnSetupOnUICompleted"); + "OnRegisteredToDevToolsManager"); // Notify the instance that it is registered to the devtools manager. instance_->OnRegisteredToDevToolsManager( @@ -373,14 +366,11 @@ params->worker_devtools_agent_route_id = worker_devtools_agent_route_id; params->wait_for_debugger = wait_for_debugger; - - if (ServiceWorkerUtils::IsMojoForServiceWorkerEnabled()) - instance_->SendMojoStartWorker(std::move(params)); - else - SendStartWorker(std::move(params)); + SendStartWorker(std::move(params)); } - void SendStartWorker(std::unique_ptr<EmbeddedWorkerStartParams> params) { + void SendStartWorker( + std::unique_ptr<EmbeddedWorkerMsg_StartWorker_Params> params) { DCHECK_CURRENTLY_ON(BrowserThread::IO); ServiceWorkerStatusCode status = instance_->registry_->SendStartWorker( std::move(params), instance_->process_id()); @@ -403,10 +393,6 @@ // |instance_| must outlive |this|. EmbeddedWorkerInstance* instance_; - // Ownership is transferred by base::Passed() to a task after process - // allocation. - mojom::EmbeddedWorkerInstanceClientRequest request_; - StatusCallback start_callback_; ProcessAllocationState state_; @@ -435,7 +421,7 @@ } void EmbeddedWorkerInstance::Start( - std::unique_ptr<EmbeddedWorkerStartParams> params, + std::unique_ptr<EmbeddedWorkerMsg_StartWorker_Params> params, const StatusCallback& callback) { if (!context_) { callback.Run(SERVICE_WORKER_ERROR_ABORT); @@ -459,12 +445,7 @@ params->wait_for_debugger = false; params->settings.v8_cache_options = GetV8CacheOptions(); - mojom::EmbeddedWorkerInstanceClientRequest request; - if (ServiceWorkerUtils::IsMojoForServiceWorkerEnabled()) - request = mojo::GetProxy(&client_); - - inflight_start_task_.reset( - new StartTask(this, params->script_url, std::move(request))); + inflight_start_task_.reset(new StartTask(this, params->script_url)); inflight_start_task_->Start(std::move(params), callback); } @@ -585,15 +566,6 @@ FOR_EACH_OBSERVER(Listener, listener_list_, OnRegisteredToDevToolsManager()); } -void EmbeddedWorkerInstance::SendMojoStartWorker( - std::unique_ptr<EmbeddedWorkerStartParams> params) { - client_->StartWorker(*params); - registry_->BindWorkerToProcess(process_id(), embedded_worker_id()); - TRACE_EVENT_ASYNC_STEP_PAST1("ServiceWorker", "EmbeddedWorkerInstance::Start", - this, "SendStartWorker", "Status", "mojo"); - OnStartWorkerMessageSent(); -} - void EmbeddedWorkerInstance::OnStartWorkerMessageSent() { if (!step_time_.is_null()) { base::TimeDelta duration = UpdateStepTime(); @@ -688,10 +660,9 @@ FOR_EACH_OBSERVER(Listener, listener_list_, OnThreadStarted()); shell::mojom::InterfaceProviderPtr exposed_interfaces; - interface_registry_->Bind(mojo::GetProxy(&exposed_interfaces)); + interface_registry_->Bind(GetProxy(&exposed_interfaces)); shell::mojom::InterfaceProviderPtr remote_interfaces; - shell::mojom::InterfaceProviderRequest request = - mojo::GetProxy(&remote_interfaces); + shell::mojom::InterfaceProviderRequest request = GetProxy(&remote_interfaces); remote_interfaces_->Bind(std::move(remote_interfaces)); BrowserThread::PostTask( BrowserThread::UI, FROM_HERE,
diff --git a/content/browser/service_worker/embedded_worker_instance.h b/content/browser/service_worker/embedded_worker_instance.h index 705b773..13aca7e3 100644 --- a/content/browser/service_worker/embedded_worker_instance.h +++ b/content/browser/service_worker/embedded_worker_instance.h
@@ -23,7 +23,6 @@ #include "content/browser/service_worker/embedded_worker_status.h" #include "content/browser/service_worker/service_worker_metrics.h" #include "content/common/content_export.h" -#include "content/common/service_worker/embedded_worker.mojom.h" #include "content/common/service_worker/service_worker_status_code.h" #include "content/public/common/console_message_level.h" #include "url/gurl.h" @@ -33,6 +32,8 @@ #undef SendMessage #endif +struct EmbeddedWorkerMsg_StartWorker_Params; + namespace IPC { class Message; } @@ -45,7 +46,6 @@ namespace content { class EmbeddedWorkerRegistry; -struct EmbeddedWorkerStartParams; class MessagePortMessageFilter; class ServiceWorkerContextCore; @@ -112,7 +112,7 @@ // started and evaluated, or when an error occurs. // |params| should be populated with service worker version info needed // to start the worker. - void Start(std::unique_ptr<EmbeddedWorkerStartParams> params, + void Start(std::unique_ptr<EmbeddedWorkerMsg_StartWorker_Params> params, const StatusCallback& callback); // Stops the worker. It is invalid to call this when the worker is @@ -224,9 +224,6 @@ int worker_devtools_agent_route_id, bool wait_for_debugger); - // Sends StartWorker message via Mojo. - void SendMojoStartWorker(std::unique_ptr<EmbeddedWorkerStartParams> params); - // Called back from StartTask after a start worker message is sent. void OnStartWorkerMessageSent(); @@ -309,12 +306,8 @@ // Current running information. std::unique_ptr<EmbeddedWorkerInstance::WorkerProcessHandle> process_handle_; int thread_id_; - - // These are connected to the renderer process after OnThreadStarted. std::unique_ptr<shell::InterfaceRegistry> interface_registry_; std::unique_ptr<shell::InterfaceProvider> remote_interfaces_; - // |client_| is used to send messages to the renderer process. - mojom::EmbeddedWorkerInstanceClientPtr client_; // Whether devtools is attached or not. bool devtools_attached_;
diff --git a/content/browser/service_worker/embedded_worker_instance_unittest.cc b/content/browser/service_worker/embedded_worker_instance_unittest.cc index 1253a28..f2df6b57 100644 --- a/content/browser/service_worker/embedded_worker_instance_unittest.cc +++ b/content/browser/service_worker/embedded_worker_instance_unittest.cc
@@ -8,7 +8,6 @@ #include <utility> #include <vector> -#include "base/command_line.h" #include "base/macros.h" #include "base/run_loop.h" #include "base/stl_util.h" @@ -17,13 +16,9 @@ #include "content/browser/service_worker/embedded_worker_test_helper.h" #include "content/browser/service_worker/service_worker_context_core.h" #include "content/browser/service_worker/service_worker_context_wrapper.h" -#include "content/common/service_worker/embedded_worker.mojom.h" #include "content/common/service_worker/embedded_worker_messages.h" -#include "content/common/service_worker/embedded_worker_start_params.h" #include "content/public/common/child_process_host.h" -#include "content/public/common/content_switches.h" #include "content/public/test/test_browser_thread_bundle.h" -#include "mojo/public/cpp/bindings/strong_binding.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -38,15 +33,14 @@ callback.Run(); } -std::unique_ptr<EmbeddedWorkerStartParams> +std::unique_ptr<EmbeddedWorkerMsg_StartWorker_Params> CreateStartParams(int version_id, const GURL& scope, const GURL& script_url) { - std::unique_ptr<EmbeddedWorkerStartParams> params( - new EmbeddedWorkerStartParams); + std::unique_ptr<EmbeddedWorkerMsg_StartWorker_Params> params( + new EmbeddedWorkerMsg_StartWorker_Params); params->service_worker_version_id = version_id; params->scope = scope; params->script_url = script_url; params->pause_after_download = false; - params->is_installed = false; return params; } @@ -103,7 +97,7 @@ const GURL& url) { ServiceWorkerStatusCode status; base::RunLoop run_loop; - std::unique_ptr<EmbeddedWorkerStartParams> params = + std::unique_ptr<EmbeddedWorkerMsg_StartWorker_Params> params = CreateStartParams(id, pattern, url); worker->Start(std::move(params), base::Bind(&SaveStatusAndCall, &status, run_loop.QuitClosure())); @@ -128,24 +122,6 @@ DISALLOW_COPY_AND_ASSIGN(EmbeddedWorkerInstanceTest); }; -class EmbeddedWorkerInstanceTestP : public EmbeddedWorkerInstanceTest, - public testing::WithParamInterface<bool> { - protected: - void SetUp() override { - is_mojo_enabled_ = GetParam(); - if (is_mojo_enabled()) { - base::CommandLine::ForCurrentProcess()->AppendSwitch( - switches::kMojoServiceWorker); - } - EmbeddedWorkerInstanceTest::SetUp(); - } - - bool is_mojo_enabled() { return is_mojo_enabled_; } - - private: - bool is_mojo_enabled_ = false; -}; - // A helper to simulate the start worker sequence is stalled in a worker // process. class StalledInStartWorkerHelper : public EmbeddedWorkerTestHelper { @@ -186,11 +162,10 @@ } }; -TEST_P(EmbeddedWorkerInstanceTestP, StartAndStop) { +TEST_F(EmbeddedWorkerInstanceTest, StartAndStop) { std::unique_ptr<EmbeddedWorkerInstance> worker = embedded_worker_registry()->CreateWorker(); EXPECT_EQ(EmbeddedWorkerStatus::STOPPED, worker->status()); - worker->AddListener(this); const int64_t service_worker_version_id = 55L; const GURL pattern("http://example.com/"); @@ -203,7 +178,7 @@ // Start should succeed. ServiceWorkerStatusCode status; base::RunLoop run_loop; - std::unique_ptr<EmbeddedWorkerStartParams> params = + std::unique_ptr<EmbeddedWorkerMsg_StartWorker_Params> params = CreateStartParams(service_worker_version_id, pattern, url); worker->Start(std::move(params), base::Bind(&SaveStatusAndCall, &status, run_loop.QuitClosure())); @@ -225,21 +200,11 @@ // EmbeddedWorkerTestHelper. EXPECT_EQ(EmbeddedWorkerStatus::STOPPED, worker->status()); - if (!is_mojo_enabled()) { - // Verify that we've sent two messages to start and terminate the worker. - ASSERT_TRUE(ipc_sink()->GetUniqueMessageMatching( - EmbeddedWorkerMsg_StartWorker::ID)); - } - // StopWorker should be sent in either case. + // Verify that we've sent two messages to start and terminate the worker. + ASSERT_TRUE( + ipc_sink()->GetUniqueMessageMatching(EmbeddedWorkerMsg_StartWorker::ID)); ASSERT_TRUE(ipc_sink()->GetUniqueMessageMatching( EmbeddedWorkerMsg_StopWorker::ID)); - - // Check if the IPCs are fired in expected order. - ASSERT_EQ(4u, events_.size()); - EXPECT_EQ(PROCESS_ALLOCATED, events_[0].type); - EXPECT_EQ(START_WORKER_MESSAGE_SENT, events_[1].type); - EXPECT_EQ(STARTED, events_[2].type); - EXPECT_EQ(STOPPED, events_[3].type); } // Test that a worker that failed twice will use a new render process @@ -268,7 +233,7 @@ // Start once normally. ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_MAX_VALUE; base::RunLoop run_loop; - std::unique_ptr<EmbeddedWorkerStartParams> params( + std::unique_ptr<EmbeddedWorkerMsg_StartWorker_Params> params( CreateStartParams(service_worker_version_id, pattern, url)); worker->Start(std::move(params), base::Bind(&SaveStatusAndCall, &status, run_loop.QuitClosure())); @@ -292,7 +257,7 @@ // Start again. ServiceWorkerStatusCode status; base::RunLoop run_loop; - std::unique_ptr<EmbeddedWorkerStartParams> params( + std::unique_ptr<EmbeddedWorkerMsg_StartWorker_Params> params( CreateStartParams(service_worker_version_id, pattern, url)); worker->Start(std::move(params), base::Bind(&SaveStatusAndCall, &status, run_loop.QuitClosure())); @@ -372,7 +337,7 @@ // Start worker1. ServiceWorkerStatusCode status; base::RunLoop run_loop; - std::unique_ptr<EmbeddedWorkerStartParams> params( + std::unique_ptr<EmbeddedWorkerMsg_StartWorker_Params> params( CreateStartParams(version_id1, pattern, url)); worker1->Start(std::move(params), base::Bind(&SaveStatusAndCall, &status, run_loop.QuitClosure())); @@ -384,7 +349,7 @@ // Start worker2. ServiceWorkerStatusCode status; base::RunLoop run_loop; - std::unique_ptr<EmbeddedWorkerStartParams> params( + std::unique_ptr<EmbeddedWorkerMsg_StartWorker_Params> params( CreateStartParams(version_id2, pattern, url)); worker2->Start(std::move(params), base::Bind(&SaveStatusAndCall, &status, run_loop.QuitClosure())); @@ -421,7 +386,7 @@ // Run the start worker sequence and detach during process allocation. ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_MAX_VALUE; - std::unique_ptr<EmbeddedWorkerStartParams> params( + std::unique_ptr<EmbeddedWorkerMsg_StartWorker_Params> params( CreateStartParams(version_id, scope, url)); worker->Start(std::move(params), base::Bind(&SaveStatusAndCall, &status, base::Bind(&base::DoNothing))); @@ -453,7 +418,7 @@ // Run the start worker sequence until a start worker message is sent. ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_MAX_VALUE; - std::unique_ptr<EmbeddedWorkerStartParams> params( + std::unique_ptr<EmbeddedWorkerMsg_StartWorker_Params> params( CreateStartParams(version_id, scope, url)); worker->Start(std::move(params), base::Bind(&SaveStatusAndCall, &status, base::Bind(&base::DoNothing))); @@ -492,7 +457,7 @@ // Stop the start worker sequence before a process is allocated. ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_MAX_VALUE; - std::unique_ptr<EmbeddedWorkerStartParams> params( + std::unique_ptr<EmbeddedWorkerMsg_StartWorker_Params> params( CreateStartParams(version_id, scope, url)); worker->Start(std::move(params), base::Bind(&SaveStatusAndCall, &status, base::Bind(&base::DoNothing))); @@ -542,7 +507,7 @@ // Run the start worker sequence until pause after download. ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_MAX_VALUE; - std::unique_ptr<EmbeddedWorkerStartParams> params( + std::unique_ptr<EmbeddedWorkerMsg_StartWorker_Params> params( CreateStartParams(version_id, scope, url)); params->pause_after_download = true; worker->Start(std::move(params), base::Bind(&SaveStatusAndCall, &status, @@ -573,7 +538,7 @@ // Run the start worker sequence until a start worker message is sent. ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_MAX_VALUE; - std::unique_ptr<EmbeddedWorkerStartParams> params( + std::unique_ptr<EmbeddedWorkerMsg_StartWorker_Params> params( CreateStartParams(version_id, scope, url)); worker->Start(std::move(params), base::Bind(&SaveStatusAndCall, &status, base::Bind(&base::DoNothing))); @@ -635,7 +600,7 @@ // Start the worker. base::RunLoop run_loop; - std::unique_ptr<EmbeddedWorkerStartParams> params( + std::unique_ptr<EmbeddedWorkerMsg_StartWorker_Params> params( CreateStartParams(version_id, pattern, url)); worker->Start(std::move(params), base::Bind(&SaveStatusAndCall, &status, run_loop.QuitClosure())); @@ -670,7 +635,7 @@ // Attempt to start the worker. base::RunLoop run_loop; - std::unique_ptr<EmbeddedWorkerStartParams> params( + std::unique_ptr<EmbeddedWorkerMsg_StartWorker_Params> params( CreateStartParams(version_id, pattern, url)); worker->Start(std::move(params), base::Bind(&SaveStatusAndCall, &status, run_loop.QuitClosure())); @@ -684,8 +649,4 @@ EXPECT_EQ(EmbeddedWorkerStatus::STARTING, events_[1].status); } -INSTANTIATE_TEST_CASE_P(EmbeddedWorkerInstanceTest, - EmbeddedWorkerInstanceTestP, - ::testing::Values(false, true)); - } // namespace content
diff --git a/content/browser/service_worker/embedded_worker_registry.cc b/content/browser/service_worker/embedded_worker_registry.cc index 3859b5aa..1b75f94 100644 --- a/content/browser/service_worker/embedded_worker_registry.cc +++ b/content/browser/service_worker/embedded_worker_registry.cc
@@ -249,7 +249,7 @@ } ServiceWorkerStatusCode EmbeddedWorkerRegistry::SendStartWorker( - std::unique_ptr<EmbeddedWorkerStartParams> params, + std::unique_ptr<EmbeddedWorkerMsg_StartWorker_Params> params, int process_id) { if (!context_) return SERVICE_WORKER_ERROR_ABORT; @@ -269,25 +269,10 @@ ServiceWorkerStatusCode status = Send(process_id, new EmbeddedWorkerMsg_StartWorker(*params)); if (status == SERVICE_WORKER_OK) - BindWorkerToProcess(process_id, embedded_worker_id); + worker_process_map_[process_id].insert(embedded_worker_id); return status; } -void EmbeddedWorkerRegistry::BindWorkerToProcess(int process_id, - int embedded_worker_id) { - // The ServiceWorkerDispatcherHost is supposed to be created when the process - // is created, and keep an entry in process_sender_map_ for its whole - // lifetime. - DCHECK(base::ContainsKey(process_sender_map_, process_id)); - DCHECK(GetWorker(embedded_worker_id)); - DCHECK_EQ(GetWorker(embedded_worker_id)->process_id(), process_id); - DCHECK( - !base::ContainsKey(worker_process_map_, process_id) || - !base::ContainsKey(worker_process_map_[process_id], embedded_worker_id)); - - worker_process_map_[process_id].insert(embedded_worker_id); -} - ServiceWorkerStatusCode EmbeddedWorkerRegistry::Send( int process_id, IPC::Message* message_ptr) { std::unique_ptr<IPC::Message> message(message_ptr);
diff --git a/content/browser/service_worker/embedded_worker_registry.h b/content/browser/service_worker/embedded_worker_registry.h index 70475ef..8e83b1d 100644 --- a/content/browser/service_worker/embedded_worker_registry.h +++ b/content/browser/service_worker/embedded_worker_registry.h
@@ -18,6 +18,7 @@ #include "content/common/content_export.h" #include "content/common/service_worker/service_worker_status_code.h" +struct EmbeddedWorkerMsg_StartWorker_Params; class GURL; namespace IPC { @@ -28,7 +29,6 @@ namespace content { class EmbeddedWorkerInstance; -struct EmbeddedWorkerStartParams; class MessagePortMessageFilter; class ServiceWorkerContextCore; @@ -59,7 +59,7 @@ // Called from EmbeddedWorkerInstance, relayed to the child process. ServiceWorkerStatusCode SendStartWorker( - std::unique_ptr<EmbeddedWorkerStartParams> params, + std::unique_ptr<EmbeddedWorkerMsg_StartWorker_Params> params, int process_id); ServiceWorkerStatusCode StopWorker(int process_id, int embedded_worker_id); @@ -114,10 +114,10 @@ FRIEND_TEST_ALL_PREFIXES(EmbeddedWorkerInstanceTest, RemoveWorkerInSharedProcess); - using WorkerInstanceMap = std::map<int, EmbeddedWorkerInstance*>; - using ProcessToSenderMap = std::map<int, IPC::Sender*>; - using ProcessToMessagePortMessageFilterMap = - std::map<int, MessagePortMessageFilter*>; + typedef std::map<int, EmbeddedWorkerInstance*> WorkerInstanceMap; + typedef std::map<int, IPC::Sender*> ProcessToSenderMap; + typedef std::map<int, MessagePortMessageFilter*> + ProcessToMessagePortMessageFilterMap; EmbeddedWorkerRegistry( const base::WeakPtr<ServiceWorkerContextCore>& context, @@ -126,11 +126,6 @@ ServiceWorkerStatusCode Send(int process_id, IPC::Message* message); - // Called when EmbeddedWorkerInstance is ready for IPC. This function - // prepares a route to the child worker thread. - // TODO(shimazu): Remove this function once mojofication is completed. - void BindWorkerToProcess(int process_id, int embedded_worker_id); - // RemoveWorker is called when EmbeddedWorkerInstance is destructed. // |process_id| could be invalid (i.e. ChildProcessHost::kInvalidUniqueID) // if it's not running.
diff --git a/content/browser/service_worker/embedded_worker_test_helper.cc b/content/browser/service_worker/embedded_worker_test_helper.cc index 674827f..daf636d 100644 --- a/content/browser/service_worker/embedded_worker_test_helper.cc +++ b/content/browser/service_worker/embedded_worker_test_helper.cc
@@ -21,7 +21,6 @@ #include "content/browser/service_worker/service_worker_context_wrapper.h" #include "content/common/service_worker/embedded_worker_messages.h" #include "content/common/service_worker/embedded_worker_setup.mojom.h" -#include "content/common/service_worker/embedded_worker_start_params.h" #include "content/common/service_worker/service_worker_messages.h" #include "content/public/common/push_event_payload.h" #include "content/public/test/mock_render_process_host.h" @@ -83,66 +82,13 @@ base::WeakPtr<EmbeddedWorkerTestHelper> helper_; }; -EmbeddedWorkerTestHelper::MockEmbeddedWorkerInstanceClient:: - MockEmbeddedWorkerInstanceClient( - base::WeakPtr<EmbeddedWorkerTestHelper> helper) - : helper_(helper), binding_(this) {} - -EmbeddedWorkerTestHelper::MockEmbeddedWorkerInstanceClient:: - ~MockEmbeddedWorkerInstanceClient() {} - -void EmbeddedWorkerTestHelper::MockEmbeddedWorkerInstanceClient::StartWorker( - const EmbeddedWorkerStartParams& params) { - if (!helper_) - return; - - embedded_worker_id_ = params.embedded_worker_id; - - EmbeddedWorkerInstance* worker = - helper_->registry()->GetWorker(params.embedded_worker_id); - ASSERT_TRUE(worker != NULL); - EXPECT_EQ(EmbeddedWorkerStatus::STARTING, worker->status()); - - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, - base::Bind(&EmbeddedWorkerTestHelper::OnStartWorker, - helper_->weak_factory_.GetWeakPtr(), params.embedded_worker_id, - params.service_worker_version_id, params.scope, - params.script_url, params.pause_after_download)); -} - -// static -void EmbeddedWorkerTestHelper::MockEmbeddedWorkerInstanceClient::Bind( - const base::WeakPtr<EmbeddedWorkerTestHelper>& helper, - mojom::EmbeddedWorkerInstanceClientRequest request) { - std::vector<std::unique_ptr<MockEmbeddedWorkerInstanceClient>>* clients = - helper->mock_instance_clients(); - size_t next_client_index = helper->mock_instance_clients_next_index_; - - ASSERT_GE(clients->size(), next_client_index); - if (clients->size() == next_client_index) { - clients->push_back( - base::MakeUnique<MockEmbeddedWorkerInstanceClient>(helper)); - } - - std::unique_ptr<MockEmbeddedWorkerInstanceClient>& client = - clients->at(next_client_index); - helper->mock_instance_clients_next_index_ = next_client_index + 1; - if (client) - client->binding_.Bind(std::move(request)); -} - EmbeddedWorkerTestHelper::EmbeddedWorkerTestHelper( const base::FilePath& user_data_directory) : browser_context_(new TestBrowserContext), render_process_host_(new MockRenderProcessHost(browser_context_.get())), - new_render_process_host_( - new MockRenderProcessHost(browser_context_.get())), wrapper_(new ServiceWorkerContextWrapper(browser_context_.get())), - mock_instance_clients_next_index_(0), next_thread_id_(0), mock_render_process_id_(render_process_host_->GetID()), - new_mock_render_process_id_(new_render_process_host_->GetID()), weak_factory_(this) { std::unique_ptr<MockServiceWorkerDatabaseTaskManager> database_task_manager( new MockServiceWorkerDatabaseTaskManager( @@ -155,10 +101,16 @@ NewMessagePortMessageFilter()); // Setup process level interface registry. - render_process_interface_registry_ = - CreateInterfaceRegistry(render_process_host_.get()); - new_render_process_interface_registry_ = - CreateInterfaceRegistry(new_render_process_host_.get()); + render_process_interface_registry_.reset(new shell::InterfaceRegistry); + render_process_interface_registry_->AddInterface( + base::Bind(&MockEmbeddedWorkerSetup::Create, weak_factory_.GetWeakPtr())); + shell::mojom::InterfaceProviderPtr interfaces; + render_process_interface_registry_->Bind(mojo::GetProxy(&interfaces)); + + std::unique_ptr<shell::InterfaceProvider> host_remote_interfaces( + new shell::InterfaceProvider); + host_remote_interfaces->Bind(std::move(interfaces)); + render_process_host_->SetRemoteInterfaces(std::move(host_remote_interfaces)); } EmbeddedWorkerTestHelper::~EmbeddedWorkerTestHelper() { @@ -375,7 +327,7 @@ } void EmbeddedWorkerTestHelper::OnStartWorkerStub( - const EmbeddedWorkerStartParams& params) { + const EmbeddedWorkerMsg_StartWorker_Params& params) { EmbeddedWorkerInstance* worker = registry()->GetWorker(params.embedded_worker_id); ASSERT_TRUE(worker != NULL); @@ -492,23 +444,4 @@ return filter.get(); } -std::unique_ptr<shell::InterfaceRegistry> -EmbeddedWorkerTestHelper::CreateInterfaceRegistry(MockRenderProcessHost* rph) { - std::unique_ptr<shell::InterfaceRegistry> registry( - new shell::InterfaceRegistry); - registry->AddInterface( - base::Bind(&MockEmbeddedWorkerSetup::Create, weak_factory_.GetWeakPtr())); - registry->AddInterface(base::Bind(&MockEmbeddedWorkerInstanceClient::Bind, - weak_factory_.GetWeakPtr())); - - shell::mojom::InterfaceProviderPtr interfaces; - registry->Bind(mojo::GetProxy(&interfaces)); - - std::unique_ptr<shell::InterfaceProvider> remote_interfaces( - new shell::InterfaceProvider); - remote_interfaces->Bind(std::move(interfaces)); - rph->SetRemoteInterfaces(std::move(remote_interfaces)); - return registry; -} - } // namespace content
diff --git a/content/browser/service_worker/embedded_worker_test_helper.h b/content/browser/service_worker/embedded_worker_test_helper.h index 97ec1637..88bf11b 100644 --- a/content/browser/service_worker/embedded_worker_test_helper.h +++ b/content/browser/service_worker/embedded_worker_test_helper.h
@@ -15,16 +15,14 @@ #include "base/containers/hash_tables.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" -#include "base/optional.h" -#include "content/common/service_worker/embedded_worker.mojom.h" #include "ipc/ipc_listener.h" #include "ipc/ipc_test_sink.h" -#include "mojo/public/cpp/bindings/binding.h" #include "services/shell/public/interfaces/interface_provider.mojom.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" class GURL; +struct EmbeddedWorkerMsg_StartWorker_Params; struct ServiceWorkerMsg_ExtendableMessageEvent_Params; namespace shell { @@ -41,7 +39,6 @@ class ServiceWorkerContextCore; class ServiceWorkerContextWrapper; class TestBrowserContext; -struct EmbeddedWorkerStartParams; struct PushEventPayload; struct ServiceWorkerFetchRequest; @@ -63,28 +60,6 @@ class EmbeddedWorkerTestHelper : public IPC::Sender, public IPC::Listener { public: - class MockEmbeddedWorkerInstanceClient - : public mojom::EmbeddedWorkerInstanceClient { - public: - explicit MockEmbeddedWorkerInstanceClient( - base::WeakPtr<EmbeddedWorkerTestHelper> helper); - ~MockEmbeddedWorkerInstanceClient() override; - - static void Bind(const base::WeakPtr<EmbeddedWorkerTestHelper>& helper, - mojom::EmbeddedWorkerInstanceClientRequest request); - - private: - // Implementation of mojo interfaces. - void StartWorker(const EmbeddedWorkerStartParams& params) override; - - base::WeakPtr<EmbeddedWorkerTestHelper> helper_; - mojo::Binding<mojom::EmbeddedWorkerInstanceClient> binding_; - - base::Optional<int> embedded_worker_id_; - - DISALLOW_COPY_AND_ASSIGN(MockEmbeddedWorkerInstanceClient); - }; - // If |user_data_directory| is empty, the context makes storage stuff in // memory. explicit EmbeddedWorkerTestHelper(const base::FilePath& user_data_directory); @@ -105,11 +80,6 @@ // Inner IPC sink for script context messages sent via EmbeddedWorker. IPC::TestSink* inner_ipc_sink() { return &inner_sink_; } - std::vector<std::unique_ptr<MockEmbeddedWorkerInstanceClient>>* - mock_instance_clients() { - return &mock_instance_clients_; - } - ServiceWorkerContextCore* context(); ServiceWorkerContextWrapper* context_wrapper() { return wrapper_.get(); } void ShutdownContext(); @@ -125,8 +95,9 @@ return embedded_worker_id_service_worker_version_id_map_; } - // Only used for tests that force creating a new render process. - int new_render_process_id() const { return new_mock_render_process_id_; } + // Only used for tests that force creating a new render process. There is no + // corresponding MockRenderProcessHost. + int new_render_process_id() const { return mock_render_process_id_ + 1; } TestBrowserContext* browser_context() { return browser_context_.get(); } @@ -187,7 +158,7 @@ class MockEmbeddedWorkerSetup; - void OnStartWorkerStub(const EmbeddedWorkerStartParams& params); + void OnStartWorkerStub(const EmbeddedWorkerMsg_StartWorker_Params& params); void OnResumeAfterDownloadStub(int embedded_worker_id); void OnStopWorkerStub(int embedded_worker_id); void OnMessageToWorkerStub(int thread_id, @@ -208,29 +179,18 @@ MessagePortMessageFilter* NewMessagePortMessageFilter(); - std::unique_ptr<shell::InterfaceRegistry> CreateInterfaceRegistry( - MockRenderProcessHost* rph); - std::unique_ptr<TestBrowserContext> browser_context_; std::unique_ptr<MockRenderProcessHost> render_process_host_; - std::unique_ptr<MockRenderProcessHost> new_render_process_host_; scoped_refptr<ServiceWorkerContextWrapper> wrapper_; IPC::TestSink sink_; IPC::TestSink inner_sink_; - std::vector<std::unique_ptr<MockEmbeddedWorkerInstanceClient>> - mock_instance_clients_; - size_t mock_instance_clients_next_index_; - int next_thread_id_; int mock_render_process_id_; - int new_mock_render_process_id_; std::unique_ptr<shell::InterfaceRegistry> render_process_interface_registry_; - std::unique_ptr<shell::InterfaceRegistry> - new_render_process_interface_registry_; std::map<int, int64_t> embedded_worker_id_service_worker_version_id_map_;
diff --git a/content/browser/service_worker/service_worker_browsertest.cc b/content/browser/service_worker/service_worker_browsertest.cc index 63a1c47..fc1c655 100644 --- a/content/browser/service_worker/service_worker_browsertest.cc +++ b/content/browser/service_worker/service_worker_browsertest.cc
@@ -337,20 +337,10 @@ } // namespace -class ServiceWorkerBrowserTest : public testing::WithParamInterface<bool>, - public ContentBrowserTest { +class ServiceWorkerBrowserTest : public ContentBrowserTest { protected: using self = ServiceWorkerBrowserTest; - void SetUp() override { - is_mojo_enabled_ = GetParam(); - if (is_mojo_enabled()) { - base::CommandLine::ForCurrentProcess()->AppendSwitch( - switches::kMojoServiceWorker); - } - ContentBrowserTest::SetUp(); - } - void SetUpOnMainThread() override { ASSERT_TRUE(embedded_test_server()->Start()); StoragePartition* partition = BrowserContext::GetDefaultStoragePartition( @@ -378,7 +368,6 @@ ServiceWorkerContextWrapper* wrapper() { return wrapper_.get(); } ServiceWorkerContext* public_context() { return wrapper(); } - bool is_mojo_enabled() const { return is_mojo_enabled_; } void AssociateRendererProcessToPattern(const GURL& pattern) { wrapper_->process_manager()->AddProcessReferenceToPattern( @@ -387,7 +376,6 @@ private: scoped_refptr<ServiceWorkerContextWrapper> wrapper_; - bool is_mojo_enabled_ = false; }; class ConsoleListener : public EmbeddedWorkerInstance::Listener { @@ -799,7 +787,7 @@ std::unique_ptr<ServiceWorkerFetchDispatcher> fetch_dispatcher_; }; -IN_PROC_BROWSER_TEST_P(ServiceWorkerVersionBrowserTest, StartAndStop) { +IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, StartAndStop) { RunOnIOThread(base::Bind(&self::SetUpRegistrationOnIOThread, base::Unretained(this), "/service_worker/worker.js")); @@ -825,7 +813,7 @@ ASSERT_EQ(SERVICE_WORKER_OK, status); } -IN_PROC_BROWSER_TEST_P(ServiceWorkerVersionBrowserTest, StartNotFound) { +IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, StartNotFound) { RunOnIOThread(base::Bind(&self::SetUpRegistrationOnIOThread, base::Unretained(this), "/service_worker/nonexistent.js")); @@ -834,7 +822,7 @@ StartWorker(SERVICE_WORKER_ERROR_NETWORK); } -IN_PROC_BROWSER_TEST_P(ServiceWorkerVersionBrowserTest, ReadResourceFailure) { +IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, ReadResourceFailure) { // Create a registration. RunOnIOThread(base::Bind(&self::SetUpRegistrationOnIOThread, base::Unretained(this), @@ -865,7 +853,7 @@ SERVICE_WORKER_ERROR_NOT_FOUND); } -IN_PROC_BROWSER_TEST_P(ServiceWorkerVersionBrowserTest, +IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, ReadResourceFailure_WaitingWorker) { // Create a registration and active version. RunOnIOThread(base::Bind(&self::SetUpRegistrationOnIOThread, @@ -914,24 +902,24 @@ SERVICE_WORKER_OK); } -IN_PROC_BROWSER_TEST_P(ServiceWorkerVersionBrowserTest, Install) { +IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, Install) { InstallTestHelper("/service_worker/worker.js", SERVICE_WORKER_OK); } -IN_PROC_BROWSER_TEST_P(ServiceWorkerVersionBrowserTest, +IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, InstallWithWaitUntil_Fulfilled) { InstallTestHelper("/service_worker/worker_install_fulfilled.js", SERVICE_WORKER_OK); } -IN_PROC_BROWSER_TEST_P(ServiceWorkerVersionBrowserTest, +IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, InstallWithFetchHandler) { InstallTestHelper("/service_worker/fetch_event.js", SERVICE_WORKER_OK); EXPECT_EQ(ServiceWorkerVersion::FetchHandlerExistence::EXISTS, version_->fetch_handler_existence()); } -IN_PROC_BROWSER_TEST_P(ServiceWorkerVersionBrowserTest, +IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, InstallWithoutFetchHandler) { InstallTestHelper("/service_worker/worker.js", SERVICE_WORKER_OK); EXPECT_EQ(ServiceWorkerVersion::FetchHandlerExistence::DOES_NOT_EXIST, @@ -940,31 +928,31 @@ // Check that ServiceWorker script requests set a "Service-Worker: script" // header. -IN_PROC_BROWSER_TEST_P(ServiceWorkerVersionBrowserTest, +IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, ServiceWorkerScriptHeader) { embedded_test_server()->RegisterRequestHandler( base::Bind(&VerifyServiceWorkerHeaderInRequest)); InstallTestHelper("/service_worker/generated_sw.js", SERVICE_WORKER_OK); } -IN_PROC_BROWSER_TEST_P(ServiceWorkerVersionBrowserTest, +IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, Activate_NoEventListener) { ActivateTestHelper("/service_worker/worker.js", SERVICE_WORKER_OK); ASSERT_EQ(ServiceWorkerVersion::ACTIVATING, version_->status()); } -IN_PROC_BROWSER_TEST_P(ServiceWorkerVersionBrowserTest, Activate_Rejected) { +IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, Activate_Rejected) { ActivateTestHelper("/service_worker/worker_activate_rejected.js", SERVICE_WORKER_ERROR_EVENT_WAITUNTIL_REJECTED); } -IN_PROC_BROWSER_TEST_P(ServiceWorkerVersionBrowserTest, +IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, InstallWithWaitUntil_Rejected) { InstallTestHelper("/service_worker/worker_install_rejected.js", SERVICE_WORKER_ERROR_EVENT_WAITUNTIL_REJECTED); } -IN_PROC_BROWSER_TEST_P(ServiceWorkerVersionBrowserTest, +IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, InstallWithWaitUntil_RejectConsoleMessage) { RunOnIOThread(base::Bind(&self::SetUpRegistrationOnIOThread, base::Unretained(this), @@ -1009,7 +997,7 @@ base::Closure quit_; }; -IN_PROC_BROWSER_TEST_P(ServiceWorkerVersionBrowserTest, TimeoutStartingWorker) { +IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, TimeoutStartingWorker) { RunOnIOThread(base::Bind(&self::SetUpRegistrationOnIOThread, base::Unretained(this), "/service_worker/while_true_worker.js")); @@ -1046,7 +1034,7 @@ EXPECT_EQ(SERVICE_WORKER_ERROR_TIMEOUT, status); } -IN_PROC_BROWSER_TEST_P(ServiceWorkerVersionBrowserTest, TimeoutWorkerInEvent) { +IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, TimeoutWorkerInEvent) { RunOnIOThread(base::Bind(&self::SetUpRegistrationOnIOThread, base::Unretained(this), "/service_worker/while_true_in_install_worker.js")); @@ -1081,7 +1069,7 @@ EXPECT_EQ(SERVICE_WORKER_ERROR_EVENT_WAITUNTIL_REJECTED, status); } -IN_PROC_BROWSER_TEST_P(ServiceWorkerVersionBrowserTest, FetchEvent_Response) { +IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, FetchEvent_Response) { ServiceWorkerFetchEventResult result; ServiceWorkerResponse response; std::unique_ptr<storage::BlobDataHandle> blob_data_handle; @@ -1103,7 +1091,7 @@ EXPECT_EQ("This resource is gone. Gone, gone, gone.", body); } -IN_PROC_BROWSER_TEST_P(ServiceWorkerVersionBrowserTest, +IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, FetchEvent_ResponseViaCache) { ServiceWorkerFetchEventResult result; ServiceWorkerResponse response1; @@ -1130,7 +1118,7 @@ EXPECT_EQ("cache_name", response2.cache_storage_cache_name); } -IN_PROC_BROWSER_TEST_P(ServiceWorkerVersionBrowserTest, +IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, FetchEvent_respondWithRejection) { ServiceWorkerFetchEventResult result; ServiceWorkerResponse response; @@ -1185,7 +1173,7 @@ bool data_saver_enabled_; }; -IN_PROC_BROWSER_TEST_P(ServiceWorkerVersionBrowserTest, FetchWithSaveData) { +IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, FetchWithSaveData) { embedded_test_server()->RegisterRequestHandler( base::Bind(&VerifySaveDataHeaderInRequest)); MockContentBrowserClient content_browser_client; @@ -1196,7 +1184,7 @@ SetBrowserClientForTesting(old_client); } -IN_PROC_BROWSER_TEST_P(ServiceWorkerVersionBrowserTest, +IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, RequestWorkerScriptWithSaveData) { embedded_test_server()->RegisterRequestHandler( base::Bind(&VerifySaveDataHeaderInRequest)); @@ -1208,7 +1196,7 @@ SetBrowserClientForTesting(old_client); } -IN_PROC_BROWSER_TEST_P(ServiceWorkerVersionBrowserTest, FetchWithoutSaveData) { +IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, FetchWithoutSaveData) { embedded_test_server()->RegisterRequestHandler( base::Bind(&VerifySaveDataHeaderNotInRequest)); MockContentBrowserClient content_browser_client; @@ -1218,7 +1206,7 @@ SetBrowserClientForTesting(old_client); } -IN_PROC_BROWSER_TEST_P(ServiceWorkerBrowserTest, FetchPageWithSaveData) { +IN_PROC_BROWSER_TEST_F(ServiceWorkerBrowserTest, FetchPageWithSaveData) { const char kPageUrl[] = "/service_worker/handle_fetch.html"; const char kWorkerUrl[] = "/service_worker/add_save_data_to_title.js"; MockContentBrowserClient content_browser_client; @@ -1253,7 +1241,7 @@ // Tests that when data saver is enabled and a cross-origin fetch by a webpage // is intercepted by a serviceworker, and the serviceworker does a fetch, the // preflight request does not have save-data in Access-Control-Request-Headers. -IN_PROC_BROWSER_TEST_P(ServiceWorkerBrowserTest, CrossOriginFetchWithSaveData) { +IN_PROC_BROWSER_TEST_F(ServiceWorkerBrowserTest, CrossOriginFetchWithSaveData) { const char kPageUrl[] = "/service_worker/fetch_cross_origin.html"; const char kWorkerUrl[] = "/service_worker/fetch_event_pass_through.js"; net::EmbeddedTestServer cross_origin_server; @@ -1296,7 +1284,7 @@ run_loop.Run(); } -IN_PROC_BROWSER_TEST_P(ServiceWorkerBrowserTest, +IN_PROC_BROWSER_TEST_F(ServiceWorkerBrowserTest, FetchPageWithSaveDataPassThroughOnFetch) { const char kPageUrl[] = "/service_worker/pass_through_fetch.html"; const char kWorkerUrl[] = "/service_worker/fetch_event_pass_through.js"; @@ -1330,7 +1318,7 @@ run_loop.Run(); } -IN_PROC_BROWSER_TEST_P(ServiceWorkerBrowserTest, Reload) { +IN_PROC_BROWSER_TEST_F(ServiceWorkerBrowserTest, Reload) { const char kPageUrl[] = "/service_worker/reload.html"; const char kWorkerUrl[] = "/service_worker/fetch_event_reload.js"; scoped_refptr<WorkerActivatedObserver> observer = @@ -1367,7 +1355,7 @@ #else #define MAYBE_ResponseFromHTTPSServiceWorkerIsMarkedAsSecure ResponseFromHTTPSServiceWorkerIsMarkedAsSecure #endif -IN_PROC_BROWSER_TEST_P(ServiceWorkerBrowserTest, +IN_PROC_BROWSER_TEST_F(ServiceWorkerBrowserTest, MAYBE_ResponseFromHTTPSServiceWorkerIsMarkedAsSecure) { const char kPageUrl[] = "/service_worker/fetch_event_blob.html"; const char kWorkerUrl[] = "/service_worker/fetch_event_blob.js"; @@ -1403,7 +1391,7 @@ run_loop.Run(); } -IN_PROC_BROWSER_TEST_P(ServiceWorkerBrowserTest, +IN_PROC_BROWSER_TEST_F(ServiceWorkerBrowserTest, ResponseFromHTTPServiceWorkerIsNotMarkedAsSecure) { const char kPageUrl[] = "/service_worker/fetch_event_blob.html"; const char kWorkerUrl[] = "/service_worker/fetch_event_blob.js"; @@ -1435,7 +1423,7 @@ run_loop.Run(); } -IN_PROC_BROWSER_TEST_P(ServiceWorkerBrowserTest, ImportsBustMemcache) { +IN_PROC_BROWSER_TEST_F(ServiceWorkerBrowserTest, ImportsBustMemcache) { const char kScopeUrl[] = "/service_worker/imports_bust_memcache_scope/"; const char kPageUrl[] = "/service_worker/imports_bust_memcache.html"; const char kScriptUrl[] = "/service_worker/worker_with_one_import.js"; @@ -1500,7 +1488,7 @@ return result; } -IN_PROC_BROWSER_TEST_P(ServiceWorkerBlackBoxBrowserTest, Registration) { +IN_PROC_BROWSER_TEST_F(ServiceWorkerBlackBoxBrowserTest, Registration) { // Close the only window to be sure we're not re-using its RenderProcessHost. shell()->Close(); EXPECT_EQ(0, CountRenderProcessHosts()); @@ -1582,7 +1570,7 @@ #else #define MAYBE_CrossSiteTransfer CrossSiteTransfer #endif -IN_PROC_BROWSER_TEST_P(ServiceWorkerBrowserTest, MAYBE_CrossSiteTransfer) { +IN_PROC_BROWSER_TEST_F(ServiceWorkerBrowserTest, MAYBE_CrossSiteTransfer) { // The first page registers a service worker. const char kRegisterPageUrl[] = "/service_worker/cross_site_xfer.html"; const base::string16 kOKTitle1(base::ASCIIToUTF16("OK_1")); @@ -1636,7 +1624,7 @@ base::Closure cache_updated_closure_; }; -IN_PROC_BROWSER_TEST_P(ServiceWorkerVersionBrowserV8CacheTest, Restart) { +IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserV8CacheTest, Restart) { RunOnIOThread(base::Bind(&self::SetUpRegistrationAndListenerOnIOThread, base::Unretained(this), "/service_worker/worker.js")); @@ -1903,7 +1891,7 @@ const int ServiceWorkerV8CacheStrategiesTest::kV8CacheTimeStampDataSize = sizeof(unsigned) + sizeof(double); -IN_PROC_BROWSER_TEST_P(ServiceWorkerV8CacheStrategiesTest, +IN_PROC_BROWSER_TEST_F(ServiceWorkerV8CacheStrategiesTest, V8CacheOnCacheStorage) { // The strategy is "aggressive" on default. CheckStrategyIsAggressive(); @@ -1923,7 +1911,7 @@ DISALLOW_COPY_AND_ASSIGN(ServiceWorkerV8CacheStrategiesNoneTest); }; -IN_PROC_BROWSER_TEST_P(ServiceWorkerV8CacheStrategiesNoneTest, +IN_PROC_BROWSER_TEST_F(ServiceWorkerV8CacheStrategiesNoneTest, V8CacheOnCacheStorage) { CheckStrategyIsNone(); } @@ -1942,7 +1930,7 @@ DISALLOW_COPY_AND_ASSIGN(ServiceWorkerV8CacheStrategiesNormalTest); }; -IN_PROC_BROWSER_TEST_P(ServiceWorkerV8CacheStrategiesNormalTest, +IN_PROC_BROWSER_TEST_F(ServiceWorkerV8CacheStrategiesNormalTest, V8CacheOnCacheStorage) { CheckStrategyIsNormal(); } @@ -1961,7 +1949,7 @@ DISALLOW_COPY_AND_ASSIGN(ServiceWorkerV8CacheStrategiesAggressiveTest); }; -IN_PROC_BROWSER_TEST_P(ServiceWorkerV8CacheStrategiesAggressiveTest, +IN_PROC_BROWSER_TEST_F(ServiceWorkerV8CacheStrategiesAggressiveTest, V8CacheOnCacheStorage) { CheckStrategyIsAggressive(); } @@ -2012,7 +2000,7 @@ DISALLOW_COPY_AND_ASSIGN(ServiceWorkerDisableWebSecurityTest); }; -IN_PROC_BROWSER_TEST_P(ServiceWorkerDisableWebSecurityTest, +IN_PROC_BROWSER_TEST_F(ServiceWorkerDisableWebSecurityTest, GetRegistrationNoCrash) { const char kPageUrl[] = "/service_worker/disable_web_security_get_registration.html"; @@ -2020,13 +2008,13 @@ RunTestWithCrossOriginURL(kPageUrl, kScopeUrl); } -IN_PROC_BROWSER_TEST_P(ServiceWorkerDisableWebSecurityTest, RegisterNoCrash) { +IN_PROC_BROWSER_TEST_F(ServiceWorkerDisableWebSecurityTest, RegisterNoCrash) { const char kPageUrl[] = "/service_worker/disable_web_security_register.html"; const char kScopeUrl[] = "/service_worker/"; RunTestWithCrossOriginURL(kPageUrl, kScopeUrl); } -IN_PROC_BROWSER_TEST_P(ServiceWorkerDisableWebSecurityTest, UnregisterNoCrash) { +IN_PROC_BROWSER_TEST_F(ServiceWorkerDisableWebSecurityTest, UnregisterNoCrash) { const char kPageUrl[] = "/service_worker/disable_web_security_unregister.html"; const char kScopeUrl[] = "/service_worker/scope/"; @@ -2035,7 +2023,7 @@ RunTestWithCrossOriginURL(kPageUrl, kScopeUrl); } -IN_PROC_BROWSER_TEST_P(ServiceWorkerDisableWebSecurityTest, UpdateNoCrash) { +IN_PROC_BROWSER_TEST_F(ServiceWorkerDisableWebSecurityTest, UpdateNoCrash) { const char kPageUrl[] = "/service_worker/disable_web_security_update.html"; const char kScopeUrl[] = "/service_worker/scope/"; const char kWorkerUrl[] = "/service_worker/fetch_event_blob.js"; @@ -2043,32 +2031,4 @@ RunTestWithCrossOriginURL(kPageUrl, kScopeUrl); } -INSTANTIATE_TEST_CASE_P(ServiceWorkerBrowserTest, - ServiceWorkerBrowserTest, - ::testing::Values(true, false)); -INSTANTIATE_TEST_CASE_P(ServiceWorkerBrowserTest, - ServiceWorkerVersionBrowserV8CacheTest, - ::testing::Values(true, false)); -INSTANTIATE_TEST_CASE_P(ServiceWorkerBrowserTest, - ServiceWorkerVersionBrowserTest, - ::testing::Values(true, false)); -INSTANTIATE_TEST_CASE_P(ServiceWorkerBrowserTest, - ServiceWorkerBlackBoxBrowserTest, - ::testing::Values(true, false)); -INSTANTIATE_TEST_CASE_P(ServiceWorkerBrowserTest, - ServiceWorkerV8CacheStrategiesTest, - ::testing::Values(true, false)); -INSTANTIATE_TEST_CASE_P(ServiceWorkerBrowserTest, - ServiceWorkerV8CacheStrategiesNoneTest, - ::testing::Values(true, false)); -INSTANTIATE_TEST_CASE_P(ServiceWorkerBrowserTest, - ServiceWorkerV8CacheStrategiesNormalTest, - ::testing::Values(true, false)); -INSTANTIATE_TEST_CASE_P(ServiceWorkerBrowserTest, - ServiceWorkerV8CacheStrategiesAggressiveTest, - ::testing::Values(true, false)); -INSTANTIATE_TEST_CASE_P(ServiceWorkerBrowserTest, - ServiceWorkerDisableWebSecurityTest, - ::testing::Values(true, false)); - } // namespace content
diff --git a/content/browser/service_worker/service_worker_job_unittest.cc b/content/browser/service_worker/service_worker_job_unittest.cc index 50ed74f0..7762d42 100644 --- a/content/browser/service_worker/service_worker_job_unittest.cc +++ b/content/browser/service_worker/service_worker_job_unittest.cc
@@ -1620,7 +1620,7 @@ ASSERT_TRUE(start_msg); EmbeddedWorkerMsg_StartWorker::Param param; EmbeddedWorkerMsg_StartWorker::Read(start_msg, ¶m); - const EmbeddedWorkerStartParams& start_params = std::get<0>(param); + EmbeddedWorkerMsg_StartWorker_Params start_params = std::get<0>(param); EXPECT_FALSE(start_params.pause_after_download); sink->ClearMessages(); } @@ -1635,7 +1635,7 @@ ASSERT_TRUE(start_msg); EmbeddedWorkerMsg_StartWorker::Param param; EmbeddedWorkerMsg_StartWorker::Read(start_msg, ¶m); - const EmbeddedWorkerStartParams& start_params = std::get<0>(param); + EmbeddedWorkerMsg_StartWorker_Params start_params = std::get<0>(param); EXPECT_TRUE(start_params.pause_after_download); sink->ClearMessages(); }
diff --git a/content/browser/service_worker/service_worker_version.cc b/content/browser/service_worker/service_worker_version.cc index 337e676..7c33cb28 100644 --- a/content/browser/service_worker/service_worker_version.cc +++ b/content/browser/service_worker/service_worker_version.cc
@@ -35,7 +35,6 @@ #include "content/browser/service_worker/service_worker_metrics.h" #include "content/browser/service_worker/service_worker_registration.h" #include "content/common/service_worker/embedded_worker_messages.h" -#include "content/common/service_worker/embedded_worker_start_params.h" #include "content/common/service_worker/service_worker_messages.h" #include "content/common/service_worker/service_worker_type_converters.h" #include "content/common/service_worker/service_worker_utils.h" @@ -1407,8 +1406,8 @@ StartTimeoutTimer(); - std::unique_ptr<EmbeddedWorkerStartParams> params( - new EmbeddedWorkerStartParams()); + std::unique_ptr<EmbeddedWorkerMsg_StartWorker_Params> params( + new EmbeddedWorkerMsg_StartWorker_Params()); params->service_worker_version_id = version_id_; params->scope = scope_; params->script_url = script_url_;
diff --git a/content/common/BUILD.gn b/content/common/BUILD.gn index 63e8ba5..df6d152 100644 --- a/content/common/BUILD.gn +++ b/content/common/BUILD.gn
@@ -306,8 +306,6 @@ "send_zygote_child_ping_linux.cc", "service_worker/embedded_worker_messages.h", "service_worker/embedded_worker_settings.h", - "service_worker/embedded_worker_start_params.cc", - "service_worker/embedded_worker_start_params.h", "service_worker/service_worker_client_info.cc", "service_worker/service_worker_client_info.h", "service_worker/service_worker_messages.h", @@ -566,7 +564,6 @@ "render_frame_message_filter.mojom", "render_message_filter.mojom", "render_widget_window_tree_client_factory.mojom", - "service_worker/embedded_worker.mojom", "service_worker/embedded_worker_setup.mojom", "storage_partition_service.mojom", "url_loader.mojom",
diff --git a/content/common/service_worker/embedded_worker.mojom b/content/common/service_worker/embedded_worker.mojom deleted file mode 100644 index d15d62b..0000000 --- a/content/common/service_worker/embedded_worker.mojom +++ /dev/null
@@ -1,16 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -module content.mojom; - -import "services/shell/public/interfaces/interface_provider.mojom"; -import "url/mojo/url.mojom"; - -[Native] -struct EmbeddedWorkerStartParams; - -// Interface to control a renderer-side worker's environment. -interface EmbeddedWorkerInstanceClient { - StartWorker(EmbeddedWorkerStartParams params); -};
diff --git a/content/common/service_worker/embedded_worker.typemap b/content/common/service_worker/embedded_worker.typemap deleted file mode 100644 index 664936b..0000000 --- a/content/common/service_worker/embedded_worker.typemap +++ /dev/null
@@ -1,10 +0,0 @@ -# Copyright 2016 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -mojom = "//content/common/service_worker/embedded_worker.mojom" -public_headers = - [ "//content/common/service_worker/embedded_worker_start_params.h" ] -traits_headers = - [ "//content/common/service_worker/embedded_worker_messages.h" ] -type_mappings = [ "content.mojom.EmbeddedWorkerStartParams=::content::EmbeddedWorkerStartParams" ]
diff --git a/content/common/service_worker/embedded_worker_messages.h b/content/common/service_worker/embedded_worker_messages.h index 34dc1eb..a245c4e0 100644 --- a/content/common/service_worker/embedded_worker_messages.h +++ b/content/common/service_worker/embedded_worker_messages.h
@@ -9,7 +9,6 @@ #include <string> #include "content/common/service_worker/embedded_worker_settings.h" -#include "content/common/service_worker/embedded_worker_start_params.h" #include "content/public/common/console_message_level.h" #include "content/public/common/web_preferences.h" #include "ipc/ipc_message.h" @@ -28,17 +27,17 @@ IPC_STRUCT_TRAITS_END() // Parameters structure for EmbeddedWorkerMsg_StartWorker. -IPC_STRUCT_TRAITS_BEGIN(content::EmbeddedWorkerStartParams) - IPC_STRUCT_TRAITS_MEMBER(embedded_worker_id) - IPC_STRUCT_TRAITS_MEMBER(service_worker_version_id) - IPC_STRUCT_TRAITS_MEMBER(scope) - IPC_STRUCT_TRAITS_MEMBER(script_url) - IPC_STRUCT_TRAITS_MEMBER(worker_devtools_agent_route_id) - IPC_STRUCT_TRAITS_MEMBER(pause_after_download) - IPC_STRUCT_TRAITS_MEMBER(wait_for_debugger) - IPC_STRUCT_TRAITS_MEMBER(is_installed) - IPC_STRUCT_TRAITS_MEMBER(settings) -IPC_STRUCT_TRAITS_END() +IPC_STRUCT_BEGIN(EmbeddedWorkerMsg_StartWorker_Params) + IPC_STRUCT_MEMBER(int, embedded_worker_id) + IPC_STRUCT_MEMBER(int64_t, service_worker_version_id) + IPC_STRUCT_MEMBER(GURL, scope) + IPC_STRUCT_MEMBER(GURL, script_url) + IPC_STRUCT_MEMBER(int, worker_devtools_agent_route_id) + IPC_STRUCT_MEMBER(bool, pause_after_download) + IPC_STRUCT_MEMBER(bool, wait_for_debugger) + IPC_STRUCT_MEMBER(bool, is_installed) + IPC_STRUCT_MEMBER(content::EmbeddedWorkerSettings, settings) +IPC_STRUCT_END() // Parameters structure for EmbeddedWorkerHostMsg_ReportConsoleMessage. // The data members directly correspond to parameters of @@ -53,7 +52,7 @@ // Browser -> Renderer message to create a new embedded worker context. IPC_MESSAGE_CONTROL1(EmbeddedWorkerMsg_StartWorker, - content::EmbeddedWorkerStartParams /* params */) + EmbeddedWorkerMsg_StartWorker_Params /* params */) // Browser -> Renderer message to resume a worker that has been started // with the pause_after_download option.
diff --git a/content/common/service_worker/embedded_worker_start_params.cc b/content/common/service_worker/embedded_worker_start_params.cc deleted file mode 100644 index 93f62ff..0000000 --- a/content/common/service_worker/embedded_worker_start_params.cc +++ /dev/null
@@ -1,11 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/common/service_worker/embedded_worker_start_params.h" - -namespace content { - -EmbeddedWorkerStartParams::EmbeddedWorkerStartParams() {} - -} // namespace content
diff --git a/content/common/service_worker/embedded_worker_start_params.h b/content/common/service_worker/embedded_worker_start_params.h deleted file mode 100644 index 9e2ef2a..0000000 --- a/content/common/service_worker/embedded_worker_start_params.h +++ /dev/null
@@ -1,30 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/common/content_export.h" -#include "content/common/service_worker/embedded_worker_settings.h" -#include "url/gurl.h" - -#ifndef CONTENT_COMMON_SERVICE_WORKER_EMBEDDED_WORKER_START_PARAMS_H_ -#define CONTENT_COMMON_SERVICE_WORKER_EMBEDDED_WORKER_START_PARAMS_H_ - -namespace content { - -struct CONTENT_EXPORT EmbeddedWorkerStartParams { - EmbeddedWorkerStartParams(); - - int embedded_worker_id; - int64_t service_worker_version_id; - GURL scope; - GURL script_url; - int worker_devtools_agent_route_id; - bool pause_after_download; - bool wait_for_debugger; - bool is_installed; - EmbeddedWorkerSettings settings; -}; - -} // namespace content - -#endif // CONTENT_COMMON_SERVICE_WORKER_EMBEDDED_WORKER_START_PARAMS_H_
diff --git a/content/common/service_worker/service_worker_utils.cc b/content/common/service_worker/service_worker_utils.cc index fb3e7251..30faed4 100644 --- a/content/common/service_worker/service_worker_utils.cc +++ b/content/common/service_worker/service_worker_utils.cc
@@ -6,7 +6,6 @@ #include <string> -#include "base/command_line.h" #include "base/logging.h" #include "base/strings/string_util.h" #include "content/public/common/origin_util.h" @@ -119,12 +118,6 @@ OriginCanAccessServiceWorkers(script_url); } -// static -bool ServiceWorkerUtils::IsMojoForServiceWorkerEnabled() { - return base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kMojoServiceWorker); -} - bool LongestScopeMatcher::MatchLongest(const GURL& scope) { if (!ServiceWorkerUtils::ScopeMatches(scope, url_)) return false;
diff --git a/content/common/service_worker/service_worker_utils.h b/content/common/service_worker/service_worker_utils.h index b0c3cc8de..4ea403a3 100644 --- a/content/common/service_worker/service_worker_utils.h +++ b/content/common/service_worker/service_worker_utils.h
@@ -46,8 +46,6 @@ const GURL& pattern, const GURL& script_url); - static bool IsMojoForServiceWorkerEnabled(); - // Returns true when '--disable-web-security' flag is set. Otherwise returns // whether the all origins of |urls| are same as the origin of |url|. template <typename... Args>
diff --git a/content/common/typemaps.gni b/content/common/typemaps.gni index 1b08a89..2dd3ed67 100644 --- a/content/common/typemaps.gni +++ b/content/common/typemaps.gni
@@ -6,5 +6,4 @@ "//content/common/url_loader_status.typemap", "//content/common/url_request.typemap", "//content/common/url_response_head.typemap", - "//content/common/service_worker/embedded_worker.typemap", ]
diff --git a/content/public/app/mojo/content_renderer_manifest.json b/content/public/app/mojo/content_renderer_manifest.json index bfb147b..399f7dc 100644 --- a/content/public/app/mojo/content_renderer_manifest.json +++ b/content/public/app/mojo/content_renderer_manifest.json
@@ -6,7 +6,6 @@ "provided": { "all_interfaces": [ "*" ], "browser": [ - "content::mojom::EmbeddedWorkerInstanceClient", "content::mojom::EmbeddedWorkerSetup", "content::mojom::FrameFactory", "content::mojom::TestMojoService",
diff --git a/content/public/common/content_switches.cc b/content/public/common/content_switches.cc index 2db58be..223d56d 100644 --- a/content/public/common/content_switches.cc +++ b/content/public/common/content_switches.cc
@@ -653,9 +653,6 @@ // Use a Mojo-based LocalStorage implementation. const char kMojoLocalStorage[] = "mojo-local-storage"; -// Use a Mojo-based ServiceWorker implementation. -const char kMojoServiceWorker[] = "mojo-service-worker"; - // Mutes audio sent to the audio device so it is not audible during // automated testing. const char kMuteAudio[] = "mute-audio";
diff --git a/content/public/common/content_switches.h b/content/public/common/content_switches.h index 3a36973a..4d065ca 100644 --- a/content/public/common/content_switches.h +++ b/content/public/common/content_switches.h
@@ -197,7 +197,6 @@ CONTENT_EXPORT extern const char kMHTMLSkipNostoreMain[]; CONTENT_EXPORT extern const char kMHTMLSkipNostoreAll[]; CONTENT_EXPORT extern const char kMojoLocalStorage[]; -CONTENT_EXPORT extern const char kMojoServiceWorker[]; CONTENT_EXPORT extern const char kMuteAudio[]; CONTENT_EXPORT extern const char kNoReferrers[]; CONTENT_EXPORT extern const char kNoSandbox[];
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn index cb51761..8df6b73 100644 --- a/content/renderer/BUILD.gn +++ b/content/renderer/BUILD.gn
@@ -345,8 +345,6 @@ "service_worker/embedded_worker_devtools_agent.h", "service_worker/embedded_worker_dispatcher.cc", "service_worker/embedded_worker_dispatcher.h", - "service_worker/embedded_worker_instance_client_impl.cc", - "service_worker/embedded_worker_instance_client_impl.h", "service_worker/service_worker_context_client.cc", "service_worker/service_worker_context_client.h", "service_worker/service_worker_context_message_filter.cc",
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc index 96b146c..8160520 100644 --- a/content/renderer/render_thread_impl.cc +++ b/content/renderer/render_thread_impl.cc
@@ -119,7 +119,6 @@ #include "content/renderer/renderer_blink_platform_impl.h" #include "content/renderer/scheduler/resource_dispatch_throttler.h" #include "content/renderer/service_worker/embedded_worker_dispatcher.h" -#include "content/renderer/service_worker/embedded_worker_instance_client_impl.h" #include "content/renderer/service_worker/service_worker_context_client.h" #include "content/renderer/service_worker/service_worker_context_message_filter.h" #include "content/renderer/shared_worker/embedded_shared_worker_stub.h" @@ -849,11 +848,8 @@ GetContentClient()->renderer()->ExposeInterfacesToBrowser( GetInterfaceRegistry()); - GetInterfaceRegistry()->AddInterface(base::Bind(&CreateFrameFactory)); - GetInterfaceRegistry()->AddInterface(base::Bind(&CreateEmbeddedWorkerSetup)); - GetInterfaceRegistry()->AddInterface( - base::Bind(&EmbeddedWorkerInstanceClientImpl::Create, - base::Unretained(embedded_worker_dispatcher_.get()))); + GetInterfaceRegistry()->AddInterface(base::Bind(CreateFrameFactory)); + GetInterfaceRegistry()->AddInterface(base::Bind(CreateEmbeddedWorkerSetup)); GetRemoteInterfaces()->GetInterface( mojo::GetProxy(&storage_partition_service_));
diff --git a/content/renderer/service_worker/embedded_worker_dispatcher.cc b/content/renderer/service_worker/embedded_worker_dispatcher.cc index bd49677..ec12c06d 100644 --- a/content/renderer/service_worker/embedded_worker_dispatcher.cc +++ b/content/renderer/service_worker/embedded_worker_dispatcher.cc
@@ -10,6 +10,7 @@ #include "base/strings/string16.h" #include "base/strings/utf_string_conversions.h" #include "content/child/child_process.h" +#include "content/child/scoped_child_process_reference.h" #include "content/child/thread_safe_sender.h" #include "content/child/worker_thread_registry.h" #include "content/common/devtools_messages.h" @@ -26,14 +27,23 @@ namespace content { -EmbeddedWorkerDispatcher::WorkerWrapper::WorkerWrapper( - blink::WebEmbeddedWorker* worker, - int devtools_agent_route_id) - : worker_(worker), - dev_tools_agent_( - new EmbeddedWorkerDevToolsAgent(worker, devtools_agent_route_id)) {} +// A thin wrapper of WebEmbeddedWorker which also adds and releases process +// references automatically. +class EmbeddedWorkerDispatcher::WorkerWrapper { + public: + WorkerWrapper(blink::WebEmbeddedWorker* worker, int devtools_agent_route_id) + : worker_(worker), + dev_tools_agent_( + new EmbeddedWorkerDevToolsAgent(worker, devtools_agent_route_id)) {} + ~WorkerWrapper() {} -EmbeddedWorkerDispatcher::WorkerWrapper::~WorkerWrapper() {} + blink::WebEmbeddedWorker* worker() { return worker_.get(); } + + private: + ScopedChildProcessReference process_ref_; + std::unique_ptr<blink::WebEmbeddedWorker> worker_; + std::unique_ptr<EmbeddedWorkerDevToolsAgent> dev_tools_agent_; +}; EmbeddedWorkerDispatcher::EmbeddedWorkerDispatcher() : weak_factory_(this) {} @@ -69,15 +79,35 @@ } void EmbeddedWorkerDispatcher::OnStartWorker( - const EmbeddedWorkerStartParams& params) { + const EmbeddedWorkerMsg_StartWorker_Params& params) { DCHECK(!workers_.Lookup(params.embedded_worker_id)); TRACE_EVENT0("ServiceWorker", "EmbeddedWorkerDispatcher::OnStartWorker"); - std::unique_ptr<WorkerWrapper> wrapper = StartWorkerContext( - params, base::MakeUnique<ServiceWorkerContextClient>( - params.embedded_worker_id, params.service_worker_version_id, - params.scope, params.script_url, - params.worker_devtools_agent_route_id)); - RegisterWorker(params.embedded_worker_id, std::move(wrapper)); + std::unique_ptr<WorkerWrapper> wrapper(new WorkerWrapper( + blink::WebEmbeddedWorker::create( + new ServiceWorkerContextClient(params.embedded_worker_id, + params.service_worker_version_id, + params.scope, params.script_url, + params.worker_devtools_agent_route_id), + NULL), + params.worker_devtools_agent_route_id)); + + blink::WebEmbeddedWorkerStartData start_data; + start_data.scriptURL = params.script_url; + start_data.userAgent = base::UTF8ToUTF16(GetContentClient()->GetUserAgent()); + start_data.waitForDebuggerMode = + params.wait_for_debugger ? + blink::WebEmbeddedWorkerStartData::WaitForDebugger : + blink::WebEmbeddedWorkerStartData::DontWaitForDebugger; + start_data.v8CacheOptions = static_cast<blink::WebSettings::V8CacheOptions>( + params.settings.v8_cache_options); + start_data.dataSaverEnabled = params.settings.data_saver_enabled; + start_data.pauseAfterDownloadMode = + params.pause_after_download + ? blink::WebEmbeddedWorkerStartData::PauseAfterDownload + : blink::WebEmbeddedWorkerStartData::DontPauseAfterDownload; + + wrapper->worker()->startWorkerContext(start_data); + workers_.AddWithID(wrapper.release(), params.embedded_worker_id); } void EmbeddedWorkerDispatcher::OnStopWorker(int embedded_worker_id) { @@ -133,37 +163,4 @@ target_level, blink::WebString::fromUTF8(message))); } -std::unique_ptr<EmbeddedWorkerDispatcher::WorkerWrapper> -EmbeddedWorkerDispatcher::StartWorkerContext( - const EmbeddedWorkerStartParams& params, - std::unique_ptr<ServiceWorkerContextClient> context_client) { - std::unique_ptr<WorkerWrapper> wrapper(new WorkerWrapper( - blink::WebEmbeddedWorker::create(context_client.release(), nullptr), - params.worker_devtools_agent_route_id)); - - blink::WebEmbeddedWorkerStartData start_data; - start_data.scriptURL = params.script_url; - start_data.userAgent = base::UTF8ToUTF16(GetContentClient()->GetUserAgent()); - start_data.waitForDebuggerMode = - params.wait_for_debugger - ? blink::WebEmbeddedWorkerStartData::WaitForDebugger - : blink::WebEmbeddedWorkerStartData::DontWaitForDebugger; - start_data.v8CacheOptions = static_cast<blink::WebSettings::V8CacheOptions>( - params.settings.v8_cache_options); - start_data.dataSaverEnabled = params.settings.data_saver_enabled; - start_data.pauseAfterDownloadMode = - params.pause_after_download - ? blink::WebEmbeddedWorkerStartData::PauseAfterDownload - : blink::WebEmbeddedWorkerStartData::DontPauseAfterDownload; - - wrapper->worker()->startWorkerContext(start_data); - return wrapper; -} - -void EmbeddedWorkerDispatcher::RegisterWorker( - int embedded_worker_id, - std::unique_ptr<WorkerWrapper> wrapper) { - workers_.AddWithID(wrapper.release(), embedded_worker_id); -} - } // namespace content
diff --git a/content/renderer/service_worker/embedded_worker_dispatcher.h b/content/renderer/service_worker/embedded_worker_dispatcher.h index 9c706fa8..e77086f7 100644 --- a/content/renderer/service_worker/embedded_worker_dispatcher.h +++ b/content/renderer/service_worker/embedded_worker_dispatcher.h
@@ -6,30 +6,19 @@ #define CONTENT_RENDERER_SERVICE_WORKER_EMBEDDED_WORKER_DISPATCHER_H_ #include <map> -#include <memory> #include "base/id_map.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/time/time.h" -#include "content/child/scoped_child_process_reference.h" #include "content/public/common/console_message_level.h" #include "ipc/ipc_listener.h" +struct EmbeddedWorkerMsg_StartWorker_Params; class GURL; -namespace blink { - -class WebEmbeddedWorker; - -} // namespace blink - namespace content { -class EmbeddedWorkerDevToolsAgent; -class ServiceWorkerContextClient; -struct EmbeddedWorkerStartParams; - // A tiny dispatcher which handles embedded worker start/stop messages. class EmbeddedWorkerDispatcher : public IPC::Listener { public: @@ -42,37 +31,15 @@ void WorkerContextDestroyed(int embedded_worker_id); private: - friend class EmbeddedWorkerInstanceClientImpl; + class WorkerWrapper; - // A thin wrapper of WebEmbeddedWorker which also adds and releases process - // references automatically. - class WorkerWrapper { - public: - WorkerWrapper(blink::WebEmbeddedWorker* worker, - int devtools_agent_route_id); - ~WorkerWrapper(); - - blink::WebEmbeddedWorker* worker() { return worker_.get(); } - - private: - ScopedChildProcessReference process_ref_; - std::unique_ptr<blink::WebEmbeddedWorker> worker_; - std::unique_ptr<EmbeddedWorkerDevToolsAgent> dev_tools_agent_; - }; - - void OnStartWorker(const EmbeddedWorkerStartParams& params); + void OnStartWorker(const EmbeddedWorkerMsg_StartWorker_Params& params); void OnStopWorker(int embedded_worker_id); void OnResumeAfterDownload(int embedded_worker_id); void OnAddMessageToConsole(int embedded_worker_id, ConsoleMessageLevel level, const std::string& message); - std::unique_ptr<WorkerWrapper> StartWorkerContext( - const EmbeddedWorkerStartParams& params, - std::unique_ptr<ServiceWorkerContextClient> context_client); - void RegisterWorker(int embedded_worker_id, - std::unique_ptr<WorkerWrapper> wrapper); - IDMap<WorkerWrapper, IDMapOwnPointer> workers_; std::map<int /* embedded_worker_id */, base::TimeTicks> stop_worker_times_; base::WeakPtrFactory<EmbeddedWorkerDispatcher> weak_factory_;
diff --git a/content/renderer/service_worker/embedded_worker_instance_client_impl.cc b/content/renderer/service_worker/embedded_worker_instance_client_impl.cc deleted file mode 100644 index 1d045dd..0000000 --- a/content/renderer/service_worker/embedded_worker_instance_client_impl.cc +++ /dev/null
@@ -1,62 +0,0 @@ -// Copyright (c) 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/renderer/service_worker/embedded_worker_instance_client_impl.h" - -#include <memory> - -#include "base/strings/utf_string_conversions.h" -#include "content/child/scoped_child_process_reference.h" -#include "content/common/service_worker/embedded_worker_messages.h" -#include "content/public/common/content_client.h" -#include "content/renderer/service_worker/embedded_worker_devtools_agent.h" -#include "content/renderer/service_worker/service_worker_context_client.h" -#include "mojo/public/cpp/bindings/strong_binding.h" -#include "third_party/WebKit/public/web/WebEmbeddedWorker.h" -#include "third_party/WebKit/public/web/WebEmbeddedWorkerStartData.h" - -namespace content { - -namespace { - -void OnError() { - // TODO(shimazu): Implement here - NOTIMPLEMENTED(); -} - -} // namespace - -// static -void EmbeddedWorkerInstanceClientImpl::Create( - EmbeddedWorkerDispatcher* dispatcher, - mojo::InterfaceRequest<mojom::EmbeddedWorkerInstanceClient> request) { - auto binding = mojo::MakeStrongBinding( - base::MakeUnique<EmbeddedWorkerInstanceClientImpl>(dispatcher), - std::move(request)); - binding->set_connection_error_handler(base::Bind(&OnError)); -} - -void EmbeddedWorkerInstanceClientImpl::StartWorker( - const EmbeddedWorkerStartParams& params) { - TRACE_EVENT0("ServiceWorker", - "EmbeddedWorkerInstanceClientImpl::StartWorker"); - - std::unique_ptr<EmbeddedWorkerDispatcher::WorkerWrapper> wrapper = - dispatcher_->StartWorkerContext( - params, - base::MakeUnique<ServiceWorkerContextClient>( - params.embedded_worker_id, params.service_worker_version_id, - params.scope, params.script_url, - params.worker_devtools_agent_route_id)); - wrapper_ = wrapper.get(); - dispatcher_->RegisterWorker(params.embedded_worker_id, std::move(wrapper)); -} - -EmbeddedWorkerInstanceClientImpl::EmbeddedWorkerInstanceClientImpl( - EmbeddedWorkerDispatcher* dispatcher) - : dispatcher_(dispatcher) {} - -EmbeddedWorkerInstanceClientImpl::~EmbeddedWorkerInstanceClientImpl() {} - -} // namespace content
diff --git a/content/renderer/service_worker/embedded_worker_instance_client_impl.h b/content/renderer/service_worker/embedded_worker_instance_client_impl.h deleted file mode 100644 index 893ae1d..0000000 --- a/content/renderer/service_worker/embedded_worker_instance_client_impl.h +++ /dev/null
@@ -1,38 +0,0 @@ -// Copyright (c) 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_RENDERER_SERVICE_WORKER_EMBEDDED_WORKER_INSTANCE_CLIENT_IMPL_H_ -#define CONTENT_RENDERER_SERVICE_WORKER_EMBEDDED_WORKER_INSTANCE_CLIENT_IMPL_H_ - -#include "base/id_map.h" -#include "content/common/service_worker/embedded_worker.mojom.h" -#include "content/renderer/service_worker/embedded_worker_dispatcher.h" - -namespace content { - -class EmbeddedWorkerInstanceClientImpl - : public mojom::EmbeddedWorkerInstanceClient { - public: - static void Create( - EmbeddedWorkerDispatcher* dispatcher, - mojo::InterfaceRequest<mojom::EmbeddedWorkerInstanceClient> request); - - explicit EmbeddedWorkerInstanceClientImpl( - EmbeddedWorkerDispatcher* dispatcher); - ~EmbeddedWorkerInstanceClientImpl() override; - - // Implementation of mojo interface - void StartWorker(const EmbeddedWorkerStartParams& params) override; - - private: - EmbeddedWorkerDispatcher* dispatcher_; - - EmbeddedWorkerDispatcher::WorkerWrapper* wrapper_; - - DISALLOW_COPY_AND_ASSIGN(EmbeddedWorkerInstanceClientImpl); -}; - -} // namespace content - -#endif // CONTENT_RENDERER_SERVICE_WORKER_EMBEDDED_WORKER_INSTANCE_CLIENT_IMPL_H_
diff --git a/content/test/data/media/getusermedia.html b/content/test/data/media/getusermedia.html index f066a8a..e045635 100644 --- a/content/test/data/media/getusermedia.html +++ b/content/test/data/media/getusermedia.html
@@ -76,7 +76,7 @@ navigator.webkitGetUserMedia( constraints, function(stream) { - var duplicate = new webkitMediaStream(stream); + var duplicate = new MediaStream(stream); assertEquals(stream.getVideoTracks().length, 1); assertEquals(duplicate.getVideoTracks().length, 1); assertEquals(stream.getVideoTracks()[0].id, @@ -95,7 +95,7 @@ navigator.webkitGetUserMedia( constraints, function(stream) { - var duplicate = new webkitMediaStream(); + var duplicate = new MediaStream(); duplicate.addTrack(stream.getVideoTracks()[0]); assertEquals(duplicate.getVideoTracks().length, 1); assertEquals(duplicate.getVideoTracks().length, 1); @@ -115,7 +115,7 @@ navigator.webkitGetUserMedia( constraints, function(stream) { - var duplicate = new webkitMediaStream(); + var duplicate = new MediaStream(); duplicate.addTrack(stream.getVideoTracks()[0].clone()); assertEquals(duplicate.getVideoTracks().length, 1); assertEquals(duplicate.getVideoTracks().length, 1); @@ -368,7 +368,7 @@ function createAndRenderClone(stream) { // TODO(perkj): --use-fake-device-for-media-stream do not currently // work with audio devices and not all bots has a microphone. - newStream = new webkitMediaStream(); + newStream = new MediaStream(); newStream.addTrack(stream.getVideoTracks()[0]); assertEquals(newStream.getVideoTracks().length, 1); if (stream.getAudioTracks().length > 0) {
diff --git a/content/test/data/media/peerconnection-call.html b/content/test/data/media/peerconnection-call.html index b285bc1..c592ab2 100644 --- a/content/test/data/media/peerconnection-call.html +++ b/content/test/data/media/peerconnection-call.html
@@ -134,7 +134,7 @@ detectVideoPlaying('remote-view-2', function() { // Construct a new media stream with remote tracks. - var newStream = new webkitMediaStream(); + var newStream = new MediaStream(); newStream.addTrack( gSecondConnection.getRemoteStreams()[0].getAudioTracks()[0]); newStream.addTrack( @@ -447,7 +447,7 @@ if (typeof localStream.clone === "function") { clonedStream = localStream.clone(); } else { - clonedStream = new webkitMediaStream(localStream); + clonedStream = new MediaStream(localStream); } gFirstConnection.addStream(localStream); @@ -481,7 +481,7 @@ // added to both peer connections. function createNewVideoStreamAndAddToBothConnections(localStream) { displayAndRemember(localStream); - var newStream = new webkitMediaStream(); + var newStream = new MediaStream(); newStream.addTrack(localStream.getVideoTracks()[0]); gFirstConnection.addStream(newStream); gSecondConnection.addStream(newStream);
diff --git a/device/BUILD.gn b/device/BUILD.gn index 4b7bf23..fc54dc7 100644 --- a/device/BUILD.gn +++ b/device/BUILD.gn
@@ -60,6 +60,7 @@ "bluetooth/test/test_bluetooth_local_gatt_service_delegate.cc", "bluetooth/test/test_bluetooth_local_gatt_service_delegate.h", "gamepad/gamepad_provider_unittest.cc", + "generic_sensor/platform_sensor_provider_unittest.cc", "test/run_all_unittests.cc", ] @@ -71,6 +72,8 @@ "//device/bluetooth:mocks", "//device/gamepad", "//device/gamepad:test_helpers", + "//device/generic_sensor", + "//device/generic_sensor:testing", "//device/geolocation:unittests", "//device/power_save_blocker", "//mojo/common",
diff --git a/device/generic_sensor/BUILD.gn b/device/generic_sensor/BUILD.gn index 75bed03..0e10af42 100644 --- a/device/generic_sensor/BUILD.gn +++ b/device/generic_sensor/BUILD.gn
@@ -61,3 +61,19 @@ ] } } + +static_library("testing") { + testonly = true + sources = [ + "fake_platform_sensor.cc", + "fake_platform_sensor.h", + "fake_platform_sensor_provider.cc", + "fake_platform_sensor_provider.h", + ] + + public_deps = [ + ":generic_sensor", + "//base", + "//device/generic_sensor/public/interfaces", + ] +}
diff --git a/device/generic_sensor/fake_platform_sensor.cc b/device/generic_sensor/fake_platform_sensor.cc new file mode 100644 index 0000000..dd21afc --- /dev/null +++ b/device/generic_sensor/fake_platform_sensor.cc
@@ -0,0 +1,41 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "device/generic_sensor/fake_platform_sensor.h" + +namespace device { + +FakePlatformSensor::FakePlatformSensor(mojom::SensorType type, + mojo::ScopedSharedBufferMapping mapping, + uint64_t buffer_size, + PlatformSensorProvider* provider) + : PlatformSensor(type, std::move(mapping), provider), started_(false) {} + +FakePlatformSensor::~FakePlatformSensor() = default; + +mojom::ReportingMode FakePlatformSensor::GetReportingMode() { + return mojom::ReportingMode::CONTINUOUS; +} + +PlatformSensorConfiguration FakePlatformSensor::GetDefaultConfiguration() { + return PlatformSensorConfiguration(); +} + +bool FakePlatformSensor::StartSensor( + const PlatformSensorConfiguration& configuration) { + config_ = configuration; + started_ = true; + return started_; +} + +void FakePlatformSensor::StopSensor() { + started_ = false; +} + +bool FakePlatformSensor::CheckSensorConfiguration( + const PlatformSensorConfiguration& configuration) { + return configuration.frequency() <= kMaxFrequencyValueForTests; +} + +} // namespace device
diff --git a/device/generic_sensor/fake_platform_sensor.h b/device/generic_sensor/fake_platform_sensor.h new file mode 100644 index 0000000..1f571fbb --- /dev/null +++ b/device/generic_sensor/fake_platform_sensor.h
@@ -0,0 +1,47 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef DEVICE_GENERIC_SENSOR_FAKE_PLATFORM_SENSOR_H_ +#define DEVICE_GENERIC_SENSOR_FAKE_PLATFORM_SENSOR_H_ + +#include "device/generic_sensor/platform_sensor.h" + +namespace device { + +class FakePlatformSensor : public PlatformSensor { + public: + FakePlatformSensor(mojom::SensorType type, + mojo::ScopedSharedBufferMapping mapping, + uint64_t buffer_size, + PlatformSensorProvider* provider); + + mojom::ReportingMode GetReportingMode() override; + PlatformSensorConfiguration GetDefaultConfiguration() override; + + bool started() const { return started_; } + + using PlatformSensor::NotifySensorReadingChanged; + using PlatformSensor::NotifySensorError; + using PlatformSensor::config_map; + + protected: + ~FakePlatformSensor() override; + bool StartSensor(const PlatformSensorConfiguration& configuration) override; + void StopSensor() override; + bool CheckSensorConfiguration( + const PlatformSensorConfiguration& configuration) override; + + private: + static constexpr double kMaxFrequencyValueForTests = 50.0; + + PlatformSensorConfiguration config_; + + bool started_; + + DISALLOW_COPY_AND_ASSIGN(FakePlatformSensor); +}; + +} // namespace device + +#endif // DEVICE_GENERIC_SENSOR_FAKE_PLATFORM_SENSOR_H
diff --git a/device/generic_sensor/fake_platform_sensor_provider.cc b/device/generic_sensor/fake_platform_sensor_provider.cc new file mode 100644 index 0000000..920ea5d9 --- /dev/null +++ b/device/generic_sensor/fake_platform_sensor_provider.cc
@@ -0,0 +1,30 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/memory/singleton.h" + +#include "device/generic_sensor/fake_platform_sensor.h" +#include "device/generic_sensor/fake_platform_sensor_provider.h" + +namespace device { + +// static +FakePlatformSensorProvider* FakePlatformSensorProvider::GetInstance() { + return base::Singleton< + FakePlatformSensorProvider, + base::LeakySingletonTraits<FakePlatformSensorProvider>>::get(); +} + +FakePlatformSensorProvider::FakePlatformSensorProvider() = default; + +FakePlatformSensorProvider::~FakePlatformSensorProvider() = default; + +scoped_refptr<PlatformSensor> FakePlatformSensorProvider::CreateSensorInternal( + mojom::SensorType type, + mojo::ScopedSharedBufferMapping mapping, + uint64_t buffer_size) { + return new FakePlatformSensor(type, std::move(mapping), buffer_size, this); +} + +} // namespace device
diff --git a/device/generic_sensor/fake_platform_sensor_provider.h b/device/generic_sensor/fake_platform_sensor_provider.h new file mode 100644 index 0000000..ea2178b --- /dev/null +++ b/device/generic_sensor/fake_platform_sensor_provider.h
@@ -0,0 +1,31 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef DEVICE_GENERIC_SENSOR_FAKE_PLATFORM_SENSOR_PROVIDER_H_ +#define DEVICE_GENERIC_SENSOR_FAKE_PLATFORM_SENSOR_PROVIDER_H_ + +#include "device/generic_sensor/platform_sensor_provider.h" + +namespace device { + +class FakePlatformSensorProvider : public PlatformSensorProvider { + public: + FakePlatformSensorProvider(); + ~FakePlatformSensorProvider() override; + + static FakePlatformSensorProvider* GetInstance(); + + protected: + scoped_refptr<PlatformSensor> CreateSensorInternal( + mojom::SensorType type, + mojo::ScopedSharedBufferMapping mapping, + uint64_t buffer_size) override; + + private: + DISALLOW_COPY_AND_ASSIGN(FakePlatformSensorProvider); +}; + +} // namespace device + +#endif // DEVICE_GENERIC_SENSOR_MOCK_PLATFORM_SENSOR_PROVIDER_H_
diff --git a/device/generic_sensor/platform_sensor.h b/device/generic_sensor/platform_sensor.h index 0f26380..0485fc6 100644 --- a/device/generic_sensor/platform_sensor.h +++ b/device/generic_sensor/platform_sensor.h
@@ -69,6 +69,9 @@ mojo::ScopedSharedBufferMapping shared_buffer_mapping_; + // For testing purposes. + const ConfigMap& config_map() const { return config_map_; } + private: friend class base::RefCountedThreadSafe<PlatformSensor>;
diff --git a/device/generic_sensor/platform_sensor_provider_unittest.cc b/device/generic_sensor/platform_sensor_provider_unittest.cc new file mode 100644 index 0000000..b63b6f85 --- /dev/null +++ b/device/generic_sensor/platform_sensor_provider_unittest.cc
@@ -0,0 +1,318 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "device/generic_sensor/fake_platform_sensor.h" +#include "device/generic_sensor/fake_platform_sensor_provider.h" +#include "device/generic_sensor/public/interfaces/sensor_provider.mojom.h" + +#include "testing/gtest/include/gtest/gtest.h" + +namespace device { + +using mojom::SensorInitParams; +using mojom::SensorType; + +namespace { + +uint64_t GetBufferOffset(mojom::SensorType type) { + return (static_cast<uint64_t>(SensorType::LAST) - + static_cast<uint64_t>(type)) * + SensorInitParams::kReadBufferSize; +} + +} // namespace + +class PlatformSensorTestClient : public PlatformSensor::Client { + public: + PlatformSensorTestClient() + : notification_suspended_(false), + sensor_reading_changed_(false), + sensor_error_(false) {} + + ~PlatformSensorTestClient() override { + if (sensor_) + sensor_->RemoveClient(this); + } + + // PlatformSensor::Client override. + void OnSensorReadingChanged() override { sensor_reading_changed_ = true; } + + void OnSensorError() override { sensor_error_ = true; } + + bool IsNotificationSuspended() override { return notification_suspended_; } + + void set_notification_suspended(bool value) { + notification_suspended_ = value; + } + + void SetSensor(scoped_refptr<PlatformSensor> sensor) { + sensor_ = sensor; + sensor_->AddClient(this); + } + + bool sensor_reading_changed() const { return sensor_reading_changed_; } + + bool sensor_error() const { return sensor_error_; } + + private: + scoped_refptr<PlatformSensor> sensor_; + bool notification_suspended_; + bool sensor_reading_changed_; + bool sensor_error_; +}; + +class PlatformSensorProviderTest : public ::testing::Test { + public: + PlatformSensorProviderTest() + : sensor_client_(new PlatformSensorTestClient()) {} + + protected: + scoped_refptr<PlatformSensor> CreateSensor(mojom::SensorType type) { + return FakePlatformSensorProvider::GetInstance()->CreateSensor( + type, SensorInitParams::kReadBufferSize, GetBufferOffset(type)); + } + + std::unique_ptr<PlatformSensorTestClient> sensor_client_; +}; + +TEST_F(PlatformSensorProviderTest, CreateSensorsAndCheckType) { + scoped_refptr<PlatformSensor> sensor1 = + CreateSensor(SensorType::AMBIENT_LIGHT); + EXPECT_TRUE(sensor1); + EXPECT_EQ(SensorType::AMBIENT_LIGHT, sensor1->GetType()); + + scoped_refptr<PlatformSensor> sensor2 = CreateSensor(SensorType::PROXIMITY); + EXPECT_TRUE(sensor2); + EXPECT_EQ(SensorType::PROXIMITY, sensor2->GetType()); + + scoped_refptr<PlatformSensor> sensor3 = + CreateSensor(SensorType::ACCELEROMETER); + EXPECT_TRUE(sensor3); + EXPECT_EQ(SensorType::ACCELEROMETER, sensor3->GetType()); + + scoped_refptr<PlatformSensor> sensor4 = CreateSensor(SensorType::GYROSCOPE); + EXPECT_TRUE(sensor4); + EXPECT_EQ(SensorType::GYROSCOPE, sensor4->GetType()); + + scoped_refptr<PlatformSensor> sensor5 = CreateSensor(SensorType::PRESSURE); + EXPECT_TRUE(sensor5); + EXPECT_EQ(SensorType::PRESSURE, sensor5->GetType()); +} + +TEST_F(PlatformSensorProviderTest, CreateAndGetSensor) { + PlatformSensorProvider* sensor_provider = + FakePlatformSensorProvider::GetInstance(); + + // Create Ambient Light sensor. + scoped_refptr<PlatformSensor> sensor1 = + CreateSensor(SensorType::AMBIENT_LIGHT); + EXPECT_TRUE(sensor1); + EXPECT_EQ(SensorType::AMBIENT_LIGHT, sensor1->GetType()); + + // Try to get Gyroscope sensor, which has not been created yet. + scoped_refptr<PlatformSensor> sensor2 = + sensor_provider->GetSensor(SensorType::GYROSCOPE); + EXPECT_FALSE(sensor2); + + // Get Ambient Light sensor. + scoped_refptr<PlatformSensor> sensor3 = + sensor_provider->GetSensor(SensorType::AMBIENT_LIGHT); + EXPECT_TRUE(sensor3); + + EXPECT_EQ(sensor1->GetType(), sensor3->GetType()); + + // Try to create a sensor with zero buffer and offset. + scoped_refptr<PlatformSensor> sensor4 = + sensor_provider->CreateSensor(SensorType::GYROSCOPE, 0, 0); + EXPECT_FALSE(sensor4); + + scoped_refptr<PlatformSensor> sensor5 = + sensor_provider->GetSensor(SensorType::GYROSCOPE); + EXPECT_FALSE(sensor5); +} + +TEST_F(PlatformSensorProviderTest, TestSensorLeaks) { + PlatformSensorProvider* sensor_provider = + FakePlatformSensorProvider::GetInstance(); + + // Create Ambient Light sensor. + scoped_refptr<PlatformSensor> sensor1 = + CreateSensor(SensorType::AMBIENT_LIGHT); + EXPECT_TRUE(sensor1); + EXPECT_EQ(SensorType::AMBIENT_LIGHT, sensor1->GetType()); + + // Sensor should be automatically destroyed. + sensor1 = nullptr; + scoped_refptr<PlatformSensor> sensor2 = + sensor_provider->GetSensor(SensorType::AMBIENT_LIGHT); + EXPECT_FALSE(sensor2); +} + +// This test assumes that a mock sensor has a constant maximum frequency value +// of 50 hz (different from the base sensor class that has a range from 0 to +// 60) and tests whether a mock sensor can be started with a value range from 0 +// to 60. +TEST_F(PlatformSensorProviderTest, StartListeningWithDifferentParameters) { + const double too_high_frequency = 60; + const double normal_frequency = 39; + scoped_refptr<PlatformSensor> sensor = + CreateSensor(SensorType::AMBIENT_LIGHT); + FakePlatformSensor* fake_sensor = + static_cast<FakePlatformSensor*>(sensor.get()); + EXPECT_TRUE(fake_sensor); + sensor_client_->SetSensor(sensor); + + PlatformSensorConfiguration config(too_high_frequency); + EXPECT_EQ(too_high_frequency, config.frequency()); + EXPECT_FALSE(fake_sensor->StartListening(sensor_client_.get(), config)); + EXPECT_FALSE(fake_sensor->started()); + + config.set_frequency(normal_frequency); + EXPECT_EQ(normal_frequency, config.frequency()); + EXPECT_TRUE(fake_sensor->StartListening(sensor_client_.get(), config)); + EXPECT_TRUE(fake_sensor->started()); + + EXPECT_TRUE(fake_sensor->StopListening(sensor_client_.get(), config)); + EXPECT_FALSE(fake_sensor->started()); +} + +// If a client is in a suspended mode, a NotifySensorReadingChanged() +// notification must not be sent to the client but NotifySensorError() must be. +TEST_F(PlatformSensorProviderTest, TestNotificationSuspended) { + const int num = 5; + scoped_refptr<PlatformSensor> sensor = CreateSensor(SensorType::GYROSCOPE); + FakePlatformSensor* fake_sensor = + static_cast<FakePlatformSensor*>(sensor.get()); + + std::vector<std::unique_ptr<PlatformSensorTestClient>> clients; + for (int i = 0; i < num; i++) { + std::unique_ptr<PlatformSensorTestClient> client( + new PlatformSensorTestClient()); + client->SetSensor(fake_sensor); + clients.push_back(std::move(client)); + } + + clients.front()->set_notification_suspended(true); + fake_sensor->NotifySensorReadingChanged(); + fake_sensor->NotifySensorError(); + for (auto const& client : clients) { + if (client == clients.front()) { + EXPECT_FALSE(client->sensor_reading_changed()); + EXPECT_TRUE(client->sensor_error()); + continue; + } + EXPECT_TRUE(client->sensor_reading_changed()); + EXPECT_TRUE(client->sensor_error()); + } + + clients.front()->set_notification_suspended(false); + fake_sensor->NotifySensorReadingChanged(); + fake_sensor->NotifySensorError(); + for (auto const& client : clients) { + EXPECT_TRUE(client->sensor_reading_changed()); + EXPECT_TRUE(client->sensor_error()); + } +} + +// Tests that when all clients are removed, config maps are removed as well. +TEST_F(PlatformSensorProviderTest, TestAddRemoveClients) { + const int num = 5; + + scoped_refptr<PlatformSensor> sensor = + CreateSensor(SensorType::AMBIENT_LIGHT); + FakePlatformSensor* fake_sensor = + static_cast<FakePlatformSensor*>(sensor.get()); + EXPECT_TRUE(fake_sensor->config_map().empty()); + + std::vector<std::unique_ptr<PlatformSensorTestClient>> clients; + PlatformSensorConfiguration config(30); + for (int i = 0; i < num; i++) { + std::unique_ptr<PlatformSensorTestClient> client( + new PlatformSensorTestClient()); + client->SetSensor(fake_sensor); + EXPECT_TRUE(fake_sensor->StartListening(client.get(), config)); + EXPECT_TRUE(fake_sensor->started()); + + clients.push_back(std::move(client)); + } + EXPECT_FALSE(fake_sensor->config_map().empty()); + + for (const auto& client : clients) + fake_sensor->RemoveClient(client.get()); + + EXPECT_TRUE(fake_sensor->config_map().empty()); +} + +// Tests a sensor cannot be updated if it has one suspended client. +TEST_F(PlatformSensorProviderTest, TestUpdateSensorOneClient) { + scoped_refptr<PlatformSensor> sensor = + CreateSensor(SensorType::AMBIENT_LIGHT); + FakePlatformSensor* fake_sensor = + static_cast<FakePlatformSensor*>(sensor.get()); + EXPECT_TRUE(fake_sensor->config_map().empty()); + + sensor_client_->SetSensor(fake_sensor); + + PlatformSensorConfiguration config(30); + fake_sensor->StartListening(sensor_client_.get(), config); + + sensor_client_->set_notification_suspended(true); + EXPECT_TRUE(sensor_client_->IsNotificationSuspended()); + + fake_sensor->UpdateSensor(); + EXPECT_FALSE(fake_sensor->started()); + + sensor_client_->set_notification_suspended(false); + EXPECT_FALSE(sensor_client_->IsNotificationSuspended()); + + fake_sensor->UpdateSensor(); + EXPECT_TRUE(fake_sensor->started()); +} + +// Tests a sensor can be updated if it has one suspended client and other +// clients are not suspended. +TEST_F(PlatformSensorProviderTest, TestUpdateSensorManyClients) { + const int num = 5; + + scoped_refptr<PlatformSensor> sensor = + CreateSensor(SensorType::AMBIENT_LIGHT); + FakePlatformSensor* fake_sensor = + static_cast<FakePlatformSensor*>(sensor.get()); + EXPECT_TRUE(fake_sensor->config_map().empty()); + + sensor_client_->SetSensor(fake_sensor); + std::vector<std::unique_ptr<PlatformSensorTestClient>> clients; + for (int i = 0; i < num; i++) { + std::unique_ptr<PlatformSensorTestClient> client( + new PlatformSensorTestClient()); + client->SetSensor(fake_sensor); + clients.push_back(std::move(client)); + } + + double sensor_frequency = 30; + PlatformSensorConfiguration config(sensor_frequency++); + fake_sensor->StartListening(sensor_client_.get(), config); + for (const auto& client : clients) { + PlatformSensorConfiguration config(sensor_frequency++); + fake_sensor->StartListening(client.get(), config); + } + + sensor_client_->set_notification_suspended(true); + EXPECT_TRUE(sensor_client_->IsNotificationSuspended()); + for (const auto& client : clients) + EXPECT_FALSE(client->IsNotificationSuspended()); + + fake_sensor->UpdateSensor(); + EXPECT_TRUE(fake_sensor->started()); + + sensor_client_->set_notification_suspended(false); + EXPECT_FALSE(sensor_client_->IsNotificationSuspended()); + for (const auto& client : clients) + EXPECT_FALSE(client->IsNotificationSuspended()); + + fake_sensor->UpdateSensor(); + EXPECT_TRUE(fake_sensor->started()); +} + +} // namespace device
diff --git a/device/generic_sensor/public/cpp/platform_sensor_configuration.cc b/device/generic_sensor/public/cpp/platform_sensor_configuration.cc index 4061ad0..44b26b3 100644 --- a/device/generic_sensor/public/cpp/platform_sensor_configuration.cc +++ b/device/generic_sensor/public/cpp/platform_sensor_configuration.cc
@@ -4,16 +4,25 @@ #include "device/generic_sensor/public/cpp/platform_sensor_configuration.h" +#include "device/generic_sensor/public/interfaces/sensor.mojom.h" + namespace device { PlatformSensorConfiguration::PlatformSensorConfiguration(double frequency) : frequency_(frequency) { - DCHECK(frequency_ <= kMaxAllowedFrequency && frequency_ > 0.0); + DCHECK(frequency_ <= mojom::SensorConfiguration::kMaxAllowedFrequency && + frequency_ > 0.0); } PlatformSensorConfiguration::PlatformSensorConfiguration() = default; PlatformSensorConfiguration::~PlatformSensorConfiguration() = default; +void PlatformSensorConfiguration::set_frequency(double frequency) { + DCHECK(frequency_ <= mojom::SensorConfiguration::kMaxAllowedFrequency && + frequency_ > 0.0); + frequency_ = frequency; +} + bool PlatformSensorConfiguration::operator==( const PlatformSensorConfiguration& other) const { return frequency_ == other.frequency();
diff --git a/device/generic_sensor/public/cpp/platform_sensor_configuration.h b/device/generic_sensor/public/cpp/platform_sensor_configuration.h index b8fe0005..0e08e452 100644 --- a/device/generic_sensor/public/cpp/platform_sensor_configuration.h +++ b/device/generic_sensor/public/cpp/platform_sensor_configuration.h
@@ -22,15 +22,9 @@ // used to compare two configurations. virtual bool operator>(const PlatformSensorConfiguration& other) const; - void set_frequency(double frequency) { - DCHECK(frequency_ <= kMaxAllowedFrequency && frequency_ > 0.0); - frequency_ = frequency; - } - + void set_frequency(double frequency); double frequency() const { return frequency_; } - static constexpr double kMaxAllowedFrequency = 60.0; - private: double frequency_ = 1.0; // 1 Hz by default. };
diff --git a/device/generic_sensor/public/cpp/sensor_struct_traits.cc b/device/generic_sensor/public/cpp/sensor_struct_traits.cc index f3ce3c4..2a36547 100644 --- a/device/generic_sensor/public/cpp/sensor_struct_traits.cc +++ b/device/generic_sensor/public/cpp/sensor_struct_traits.cc
@@ -13,7 +13,7 @@ device::PlatformSensorConfiguration* out) { // Maximum allowed frequency is capped to 60Hz. if (data.frequency() > - device::PlatformSensorConfiguration::kMaxAllowedFrequency || + device::mojom::SensorConfiguration::kMaxAllowedFrequency || data.frequency() <= 0.0) { return false; }
diff --git a/device/generic_sensor/public/interfaces/sensor.mojom b/device/generic_sensor/public/interfaces/sensor.mojom index 74f57d4..be71501 100644 --- a/device/generic_sensor/public/interfaces/sensor.mojom +++ b/device/generic_sensor/public/interfaces/sensor.mojom
@@ -30,7 +30,10 @@ }; struct SensorConfiguration { - // Requested frequency in Hz (max is 60 Hz). + // Maximum allowed frequency is 60 Hz. + const double kMaxAllowedFrequency = 60.0; + + // Requested frequency in Hz. double frequency; // TODO(shalamov): Add map<string, union> for sensor specific configuration. };
diff --git a/extensions/common/api/_api_features.json b/extensions/common/api/_api_features.json index 9b060a8..e2412b7 100644 --- a/extensions/common/api/_api_features.json +++ b/extensions/common/api/_api_features.json
@@ -92,35 +92,6 @@ }], "bluetoothLowEnergy": { "dependencies": ["manifest:bluetooth"], - "contexts": ["blessed_extension"] - }, - "bluetoothLowEnergy.createService": { - "dependencies": ["manifest:bluetooth"], - "contexts": ["blessed_extension"], - "platforms": ["chromeos", "linux"] - }, - "bluetoothLowEnergy.createCharacteristic": { - "dependencies": ["manifest:bluetooth"], - "contexts": ["blessed_extension"], - "platforms": ["chromeos", "linux"] - }, - "bluetoothLowEnergy.createDescriptor": { - "dependencies": ["manifest:bluetooth"], - "contexts": ["blessed_extension"], - "platforms": ["chromeos", "linux"] - }, - "bluetoothLowEnergy.registerService": { - "dependencies": ["manifest:bluetooth"], - "contexts": ["blessed_extension"], - "platforms": ["chromeos", "linux"] - }, - "bluetoothLowEnergy.unregisterService": { - "dependencies": ["manifest:bluetooth"], - "contexts": ["blessed_extension"], - "platforms": ["chromeos", "linux"] - }, - "bluetoothLowEnergy.sendRequestResponse": { - "dependencies": ["manifest:bluetooth"], "contexts": ["blessed_extension"], "platforms": ["chromeos", "linux"] },
diff --git a/ios/web/web_state/ui/crw_web_controller.mm b/ios/web/web_state/ui/crw_web_controller.mm index ae654fe..acbcdec9a 100644 --- a/ios/web/web_state/ui/crw_web_controller.mm +++ b/ios/web/web_state/ui/crw_web_controller.mm
@@ -4801,10 +4801,6 @@ GURL requestURL = net::GURLWithNSURL(action.request.URL); - // Don't create web views for invalid URLs. - if (!requestURL.is_valid()) - return nil; - if (![self userIsInteracting]) { NSString* referer = [self refererFromNavigationAction:action]; GURL referrerURL =
diff --git a/ppapi/examples/video_effects/video_effects.html b/ppapi/examples/video_effects/video_effects.html index f7dd0ce..fa37d59 100644 --- a/ppapi/examples/video_effects/video_effects.html +++ b/ppapi/examples/video_effects/video_effects.html
@@ -92,7 +92,7 @@ // Call into getUserMedia via the polyfill (adapter.js). getUserMedia({audio:false, video:true}, gotStream, function() {}); -} +} function onRegisterStreamDone() { vidprocessedlocal.src = URL.createObjectURL(processedLocalstream); @@ -111,7 +111,7 @@ function initEffect() { var url = URL.createObjectURL(localstream); - processedLocalstream = new webkitMediaStream([]); + processedLocalstream = new MediaStream([]); var processedStreamUrl = URL.createObjectURL(processedLocalstream); effectsPlugin.postMessage( 'registerStream' + ' ' + url + ' ' + processedStreamUrl); @@ -127,7 +127,7 @@ effectsPlugin.postMessage('effectOff'); } } - + function call() { callButton.disabled = true; hangupButton.disabled = false; @@ -135,15 +135,15 @@ var servers = null; pc1 = new RTCPeerConnection(servers); trace("Created local peer connection object pc1"); - pc1.onicecandidate = iceCallback1; + pc1.onicecandidate = iceCallback1; pc2 = new RTCPeerConnection(servers); trace("Created remote peer connection object pc2"); pc2.onicecandidate = iceCallback2; - pc2.onaddstream = gotRemoteStream; + pc2.onaddstream = gotRemoteStream; pc1.addStream(processedLocalstream); trace("Adding Local Stream to peer connection"); - + pc1.createOffer(gotDescription1); } @@ -155,7 +155,7 @@ // to pass in the right constraints in order for it to // accept the incoming offer of audio and video. var sdpConstraints = {'mandatory': { - 'OfferToReceiveAudio':true, + 'OfferToReceiveAudio':true, 'OfferToReceiveVideo':true }}; pc2.createAnswer(gotDescription2, null, sdpConstraints); } @@ -168,7 +168,7 @@ function hangup() { trace("Ending call"); - pc1.close(); + pc1.close(); pc2.close(); pc1 = null; pc2 = null; @@ -187,7 +187,7 @@ trace("Local ICE candidate: \n" + event.candidate.candidate); } } - + function iceCallback2(event){ if (event.candidate) { pc1.addIceCandidate(new RTCIceCandidate(event.candidate)); @@ -204,5 +204,3 @@ </script> </body> </html> - -
diff --git a/ppapi/tests/test_video_destination.cc b/ppapi/tests/test_video_destination.cc index f3c4cf8a..367b002 100644 --- a/ppapi/tests/test_video_destination.cc +++ b/ppapi/tests/test_video_destination.cc
@@ -100,7 +100,7 @@ std::string TestVideoDestination::TestPutFrame() { std::string js_code; - js_code += "var test_stream = new webkitMediaStream([]);" + js_code += "var test_stream = new MediaStream([]);" "var url = URL.createObjectURL(test_stream);" "var plugin = document.getElementById('plugin');" "plugin.postMessage(url);"; @@ -124,4 +124,3 @@ PASS(); } -
diff --git a/testing/android/native_test/BUILD.gn b/testing/android/native_test/BUILD.gn index 971c423..f08a8d1 100644 --- a/testing/android/native_test/BUILD.gn +++ b/testing/android/native_test/BUILD.gn
@@ -41,7 +41,6 @@ "//testing/android/appurify_support:appurify_support_java", "//testing/android/reporter:reporter_java", ] - srcjar_deps = [ "//base:base_native_libraries_gen" ] java_files = [ "java/src/org/chromium/native_test/NativeBrowserTestActivity.java", "java/src/org/chromium/native_test/NativeTest.java", @@ -50,7 +49,6 @@ "java/src/org/chromium/native_test/NativeUnitTestActivity.java", "java/src/org/chromium/native_test/NativeUnitTestNativeActivity.java", ] - jar_excluded_patterns = [ "*/NativeLibraries.class" ] } generate_jni("native_test_jni_headers") {
diff --git a/testing/buildbot/filters/browser-side-navigation.linux.browser_tests.filter b/testing/buildbot/filters/browser-side-navigation.linux.browser_tests.filter index 425874f..3a716c0a 100644 --- a/testing/buildbot/filters/browser-side-navigation.linux.browser_tests.filter +++ b/testing/buildbot/filters/browser-side-navigation.linux.browser_tests.filter
@@ -60,6 +60,7 @@ -TemplateURLScraperTest.ScrapeWithOnSubmit -ThreatDOMDetailsTest.Everything -TracingBrowserTest.TestBackgroundMemoryInfra +-TracingBrowserTest.TestMemoryInfra -WebBluetoothTest.WebBluetoothAfterCrash -WebNavigationApiTest.Crash -WebNavigationApiTest.CrossProcess
diff --git a/testing/buildbot/gn_isolate_map.pyl b/testing/buildbot/gn_isolate_map.pyl index e2ca33c5..123773b 100644 --- a/testing/buildbot/gn_isolate_map.pyl +++ b/testing/buildbot/gn_isolate_map.pyl
@@ -84,7 +84,7 @@ "args": [], }, "android_junit_tests": { - "label": "//webrtc:android_juint_tests", + "label": "//webrtc:android_junit_tests", "type": "junit_test", }, "android_webview_test_apk": {
diff --git a/third_party/WebKit/LayoutTests/VirtualTestSuites b/third_party/WebKit/LayoutTests/VirtualTestSuites index 6d75989..ea0760b 100644 --- a/third_party/WebKit/LayoutTests/VirtualTestSuites +++ b/third_party/WebKit/LayoutTests/VirtualTestSuites
@@ -288,10 +288,5 @@ "prefix": "enable_wasm", "base": "http/tests/wasm", "args": ["--enable-wasm"] - }, - { - "prefix": "mojo-service-worker", - "base": "http/tests/serviceworker", - "args": ["--mojo-service-worker"] } ]
diff --git a/third_party/WebKit/LayoutTests/fast/events/constructors/media-stream-event-constructor.html b/third_party/WebKit/LayoutTests/fast/events/constructors/media-stream-event-constructor.html index a7038a59..fb643a9 100644 --- a/third_party/WebKit/LayoutTests/fast/events/constructors/media-stream-event-constructor.html +++ b/third_party/WebKit/LayoutTests/fast/events/constructors/media-stream-event-constructor.html
@@ -9,7 +9,7 @@ description("This tests the constructor for the MediaStreamEvent DOM class."); var testObject = {nyannyan: 123}; -var mediaStream = new webkitMediaStream(); +var mediaStream = new MediaStream(); // No initializer is passed. shouldBe("new MediaStreamEvent('eventType').bubbles", "false");
diff --git a/third_party/WebKit/LayoutTests/fast/js/constructor-length-expected.txt b/third_party/WebKit/LayoutTests/fast/js/constructor-length-expected.txt index 309a8ab..67a9b8e 100644 --- a/third_party/WebKit/LayoutTests/fast/js/constructor-length-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/js/constructor-length-expected.txt
@@ -23,7 +23,7 @@ PASS Int32Array.length is 3 PASS Int8Array.length is 3 FAIL Intent.length should be 3. Threw exception ReferenceError: Intent is not defined -FAIL MediaStream.length should be 0. Threw exception ReferenceError: MediaStream is not defined +PASS MediaStream.length is 0 PASS MessageChannel.length is 0 PASS MessageEvent.length is 1 PASS PageTransitionEvent.length is 1
diff --git a/third_party/WebKit/LayoutTests/fast/mediastream/MediaStream-onactive-oninactive.html b/third_party/WebKit/LayoutTests/fast/mediastream/MediaStream-onactive-oninactive.html index 0abcbb4..7d58e79b 100644 --- a/third_party/WebKit/LayoutTests/fast/mediastream/MediaStream-onactive-oninactive.html +++ b/third_party/WebKit/LayoutTests/fast/mediastream/MediaStream-onactive-oninactive.html
@@ -32,7 +32,7 @@ } function gotStream2(s) { - stream = new webkitMediaStream(); + stream = new MediaStream(); shouldBeFalse('stream.active'); stream.onactive = streamActive; stream.addTrack(s.getAudioTracks()[0]);
diff --git a/third_party/WebKit/LayoutTests/fast/mediastream/MediaStreamConstructor-expected.txt b/third_party/WebKit/LayoutTests/fast/mediastream/MediaStreamConstructor-expected.txt index 2a56ded9..ee3f5df0 100644 --- a/third_party/WebKit/LayoutTests/fast/mediastream/MediaStreamConstructor-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/mediastream/MediaStreamConstructor-expected.txt
@@ -1,21 +1,26 @@ -Tests webkitMediaStream. +Tests MediaStream constructor. On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". -PASS Got local stream. +Interface tests. +PASS typeof MediaStream is 'function' +PASS MediaStream.length is 0 +PASS MediaStream.name is 'MediaStream' +PASS Object.getPrototypeOf(MediaStream.prototype) is EventTarget.prototype +PASS window.MediaStream is window.webkitMediaStream +Got local stream. PASS localStream.getAudioTracks().length is 1 PASS localStream.getVideoTracks().length is 1 -PASS typeof webkitMediaStream === 'function' is true PASS checkIdAttribute(localStream.id) is true -PASS new webkitMediaStream(document) threw exception TypeError: Failed to construct 'MediaStream': No matching constructor signature.. -PASS new webkitMediaStream([document]) threw exception TypeError: Failed to construct 'MediaStream': Invalid Array element type. -PASS new webkitMediaStream([stream.getAudioTracks()[0], document]) threw exception TypeError: Failed to construct 'MediaStream': Invalid Array element type. -PASS new webkitMediaStream([null]) threw exception TypeError: Failed to construct 'MediaStream': Invalid Array element type. -PASS new webkitMediaStream([undefined]) threw exception TypeError: Failed to construct 'MediaStream': Invalid Array element type. -PASS new webkitMediaStream(null) threw exception TypeError: Failed to construct 'MediaStream': No matching constructor signature.. -PASS new webkitMediaStream(undefined) threw exception TypeError: Failed to construct 'MediaStream': No matching constructor signature.. -PASS Stream constructed +PASS new MediaStream(document) threw exception TypeError: Failed to construct 'MediaStream': No matching constructor signature.. +PASS new MediaStream([document]) threw exception TypeError: Failed to construct 'MediaStream': Invalid Array element type. +PASS new MediaStream([stream.getAudioTracks()[0], document]) threw exception TypeError: Failed to construct 'MediaStream': Invalid Array element type. +PASS new MediaStream([null]) threw exception TypeError: Failed to construct 'MediaStream': Invalid Array element type. +PASS new MediaStream([undefined]) threw exception TypeError: Failed to construct 'MediaStream': Invalid Array element type. +PASS new MediaStream(null) threw exception TypeError: Failed to construct 'MediaStream': No matching constructor signature.. +PASS new MediaStream(undefined) threw exception TypeError: Failed to construct 'MediaStream': No matching constructor signature.. +Stream constructed PASS [object MediaStream] is non-null. PASS [object MediaStream] is defined. PASS newStream.constructor.name is 'MediaStream' @@ -23,7 +28,7 @@ PASS newStream.getVideoTracks().length is nVideo PASS newStream.active is false PASS checkIdAttribute(newStream.id) is true -PASS Stream constructed +Stream constructed PASS [object MediaStream] is non-null. PASS [object MediaStream] is defined. PASS newStream.constructor.name is 'MediaStream' @@ -31,7 +36,7 @@ PASS newStream.getVideoTracks().length is nVideo PASS newStream.active is false PASS checkIdAttribute(newStream.id) is true -PASS Stream constructed +Stream constructed PASS [object MediaStream] is non-null. PASS [object MediaStream] is defined. PASS newStream.constructor.name is 'MediaStream' @@ -39,7 +44,7 @@ PASS newStream.getVideoTracks().length is nVideo PASS newStream.active is true PASS checkIdAttribute(newStream.id) is true -PASS Stream constructed +Stream constructed PASS [object MediaStream] is non-null. PASS [object MediaStream] is defined. PASS newStream.constructor.name is 'MediaStream' @@ -47,7 +52,7 @@ PASS newStream.getVideoTracks().length is nVideo PASS newStream.active is true PASS checkIdAttribute(newStream.id) is true -PASS Stream constructed +Stream constructed PASS [object MediaStream] is non-null. PASS [object MediaStream] is defined. PASS newStream.constructor.name is 'MediaStream' @@ -55,7 +60,7 @@ PASS newStream.getVideoTracks().length is nVideo PASS newStream.active is true PASS checkIdAttribute(newStream.id) is true -PASS Stream constructed +Stream constructed PASS [object MediaStream] is non-null. PASS [object MediaStream] is defined. PASS newStream.constructor.name is 'MediaStream' @@ -63,7 +68,7 @@ PASS newStream.getVideoTracks().length is nVideo PASS newStream.active is true PASS checkIdAttribute(newStream.id) is true -PASS Stream constructed +Stream constructed PASS [object MediaStream] is non-null. PASS [object MediaStream] is defined. PASS newStream.constructor.name is 'MediaStream' @@ -71,7 +76,7 @@ PASS newStream.getVideoTracks().length is nVideo PASS newStream.active is true PASS checkIdAttribute(newStream.id) is true -PASS Stream constructed +Stream constructed PASS [object MediaStream] is non-null. PASS [object MediaStream] is defined. PASS newStream.constructor.name is 'MediaStream' @@ -79,7 +84,7 @@ PASS newStream.getVideoTracks().length is nVideo PASS newStream.active is false PASS checkIdAttribute(newStream.id) is true -PASS Stream constructed +Stream constructed PASS [object MediaStream] is non-null. PASS [object MediaStream] is defined. PASS newStream.constructor.name is 'MediaStream' @@ -87,7 +92,7 @@ PASS newStream.getVideoTracks().length is nVideo PASS newStream.active is false PASS checkIdAttribute(newStream.id) is true -PASS Stream constructed +Stream constructed PASS [object MediaStream] is non-null. PASS [object MediaStream] is defined. PASS newStream.constructor.name is 'MediaStream' @@ -95,7 +100,7 @@ PASS newStream.getVideoTracks().length is nVideo PASS newStream.active is false PASS checkIdAttribute(newStream.id) is true -PASS Stream constructed +Stream constructed PASS [object MediaStream] is non-null. PASS [object MediaStream] is defined. PASS newStream.constructor.name is 'MediaStream'
diff --git a/third_party/WebKit/LayoutTests/fast/mediastream/MediaStreamConstructor.html b/third_party/WebKit/LayoutTests/fast/mediastream/MediaStreamConstructor.html index 0f64a87..a09852d0 100644 --- a/third_party/WebKit/LayoutTests/fast/mediastream/MediaStreamConstructor.html +++ b/third_party/WebKit/LayoutTests/fast/mediastream/MediaStreamConstructor.html
@@ -7,7 +7,7 @@ <p id="description"></p> <div id="console"></div> <script> -description("Tests webkitMediaStream."); +description("Tests MediaStream constructor."); var undefined; var stream; @@ -45,6 +45,16 @@ finishJSTest(); } +function testInterfaces() { + debug('Interface tests.'); + shouldBe('typeof MediaStream', "'function'"); + shouldBe('MediaStream.length', '0'); + shouldBe('MediaStream.name', "'MediaStream'"); + shouldBe('Object.getPrototypeOf(MediaStream.prototype)', 'EventTarget.prototype'); + // webkitMediaStream is an alias of MediaStream + shouldBe('window.MediaStream', 'window.webkitMediaStream'); +} + function getUserMedia(dictionary, callback) { try { navigator.webkitGetUserMedia(dictionary, callback, error); @@ -56,40 +66,39 @@ function gotStream(s) { localStream = s; - testPassed('Got local stream.'); + debug('Got local stream.'); shouldBe('localStream.getAudioTracks().length', '1'); shouldBe('localStream.getVideoTracks().length', '1'); - shouldBeTrue("typeof webkitMediaStream === 'function'"); shouldBeTrue('checkIdAttribute(localStream.id)'); testConstructor(localStream); } function testConstructor(s) { stream = s; - shouldThrow('new webkitMediaStream(document)'); - shouldThrow('new webkitMediaStream([document])'); - shouldThrow('new webkitMediaStream([stream.getAudioTracks()[0], document])'); - shouldThrow('new webkitMediaStream([null])'); - shouldThrow('new webkitMediaStream([undefined])'); - shouldThrow('new webkitMediaStream(null)'); - shouldThrow('new webkitMediaStream(undefined)'); + shouldThrow('new MediaStream(document)'); + shouldThrow('new MediaStream([document])'); + shouldThrow('new MediaStream([stream.getAudioTracks()[0], document])'); + shouldThrow('new MediaStream([null])'); + shouldThrow('new MediaStream([undefined])'); + shouldThrow('new MediaStream(null)'); + shouldThrow('new MediaStream(undefined)'); - verifyStream(new webkitMediaStream(), 0, 0); - verifyStream(new webkitMediaStream([]), 0, 0); + verifyStream(new MediaStream(), 0, 0); + verifyStream(new MediaStream([]), 0, 0); - verifyStream(new webkitMediaStream(s), s.getAudioTracks().length, s.getVideoTracks().length); + verifyStream(new MediaStream(s), s.getAudioTracks().length, s.getVideoTracks().length); - verifyStream(new webkitMediaStream([s.getAudioTracks()[0]]), 1, 0); - verifyStream(new webkitMediaStream([s.getVideoTracks()[0]]), 0, 1); - verifyStream(new webkitMediaStream([s.getAudioTracks()[0], s.getVideoTracks()[0]]), 1, 1); - verifyStream(new webkitMediaStream([s.getVideoTracks()[0], s.getAudioTracks()[0], s.getVideoTracks()[0]]), 1, 1); + verifyStream(new MediaStream([s.getAudioTracks()[0]]), 1, 0); + verifyStream(new MediaStream([s.getVideoTracks()[0]]), 0, 1); + verifyStream(new MediaStream([s.getAudioTracks()[0], s.getVideoTracks()[0]]), 1, 1); + verifyStream(new MediaStream([s.getVideoTracks()[0], s.getAudioTracks()[0], s.getVideoTracks()[0]]), 1, 1); s.oninactive = function () { - verifyStream(new webkitMediaStream([s.getAudioTracks()[0]]), 0, 0); - verifyStream(new webkitMediaStream([s.getVideoTracks()[0]]), 0, 0); - verifyStream(new webkitMediaStream([s.getAudioTracks()[0], s.getVideoTracks()[0]]), 0, 0); - verifyStream(new webkitMediaStream(s), 0, 0); + verifyStream(new MediaStream([s.getAudioTracks()[0]]), 0, 0); + verifyStream(new MediaStream([s.getVideoTracks()[0]]), 0, 0); + verifyStream(new MediaStream([s.getAudioTracks()[0], s.getVideoTracks()[0]]), 0, 0); + verifyStream(new MediaStream(s), 0, 0); finishJSTest(); }; @@ -103,10 +112,10 @@ nAudio = numAudioTracks; nVideo = numVideoTracks; - testPassed('Stream constructed'); + debug('Stream constructed'); shouldBeNonNull(newStream); shouldBeDefined(newStream); - shouldBe("newStream.constructor.name", "'MediaStream'"); + shouldBe('newStream.constructor.name', "'MediaStream'"); shouldBe('newStream.getAudioTracks().length', 'nAudio'); shouldBe('newStream.getVideoTracks().length', 'nVideo'); @@ -118,6 +127,7 @@ shouldBeTrue('checkIdAttribute(newStream.id)'); } +testInterfaces(); getUserMedia({video:true, audio:true}, gotStream); window.jsTestIsAsync = true;
diff --git a/third_party/WebKit/LayoutTests/fast/peerconnection/RTCPeerConnection-getStats-promise.html b/third_party/WebKit/LayoutTests/fast/peerconnection/RTCPeerConnection-getStats-promise.html index 731a63a..661c72a 100644 --- a/third_party/WebKit/LayoutTests/fast/peerconnection/RTCPeerConnection-getStats-promise.html +++ b/third_party/WebKit/LayoutTests/fast/peerconnection/RTCPeerConnection-getStats-promise.html
@@ -9,6 +9,40 @@ <script> var pc = new webkitRTCPeerConnection(null); +function stringify_equals(d1, d2) { + return JSON.stringify(d1) == JSON.stringify(d2); +} + +function assert_expected_report(report) { + assert_true(report != null); + var statsCount = 0; + report.forEach(function(s) { + assert_true(s != null); + statsCount++; + assert_true(stringify_equals(s, report.get(s.id))); + }); + + // Verify that the report contains the same stats that + // |MockWebRTCPeerConnectionHandler::getStats| should produce. + assert_equals(statsCount, 1); + var stats = report.get('mock-stats-01'); + assert_true(stats != null); + assert_equals(stats.type, 'mock-stats'); + assert_equals(stats.timestamp, 1234.0); + assert_equals(stats.int32, 42); + assert_equals(stats.uint32, 42); + assert_equals(stats.int64, 42); + assert_equals(stats.uint64, 42); + assert_equals(stats.double, 42); + assert_equals(stats.string, '42'); + assert_true(stringify_equals(stats.sequenceInt32, [42])); + assert_true(stringify_equals(stats.sequenceUint32, [42])); + assert_true(stringify_equals(stats.sequenceInt64, [42])); + assert_true(stringify_equals(stats.sequenceUint64, [42])); + assert_true(stringify_equals(stats.sequenceDouble, [42])); + assert_true(stringify_equals(stats.sequenceString, ['42'])); +} + promise_test(function() { return navigator.mediaDevices.getUserMedia({audio:true, video:true}) .then(function(mediaStream) { @@ -16,11 +50,8 @@ var selector = pc.getLocalStreams()[0].getVideoTracks()[0]; assert_not_equals(selector, null); return pc.getStats(selector) - .then(function(statsReport) { - assert_unreached('The promise should be rejected.'); - }, function(reason) { - // Expecting promise to be rejected until getStats is implemented. - // crbug.com/627816 + .then(function(report) { + assert_expected_report(report); }); }); }, 'getStats(MediaStreamTrack selector)'); @@ -30,11 +61,8 @@ .then(function(mediaStream) { pc.addStream(mediaStream); return pc.getStats(null) - .then(function(statsReport) { - assert_unreached('The promise should be rejected.'); - }, function(reason) { - // Expecting promise to be rejected until getStats is implemented. - // crbug.com/627816 + .then(function(report) { + assert_expected_report(report); }); }); }, 'getStats(null)'); @@ -44,11 +72,8 @@ .then(function(mediaStream) { pc.addStream(mediaStream); return pc.getStats() - .then(function(statsReport) { - assert_unreached('The promise should be rejected.'); - }, function(reason) { - // Expecting promise to be rejected until getStats is implemented. - // crbug.com/627816 + .then(function(report) { + assert_expected_report(report); }); }); }, 'getStats()');
diff --git a/third_party/WebKit/LayoutTests/media/video-controls-overflow-menu-hide-on-click.html b/third_party/WebKit/LayoutTests/media/video-controls-overflow-menu-hide-on-click.html new file mode 100644 index 0000000..a1e7dd6 --- /dev/null +++ b/third_party/WebKit/LayoutTests/media/video-controls-overflow-menu-hide-on-click.html
@@ -0,0 +1,39 @@ +<!DOCTYPE html> +<title>Ensure overflow menu buttons are visible when expected.</title> +<script src="../resources/testharness.js"></script> +<script src="../resources/testharnessreport.js"></script> +<script src="media-controls.js"></script> +<script src="media-file.js"></script> +<script src="overflow-menu.js"></script> + +<!--Padding ensures the overflow menu is visible for the tests. --> +<body style="padding-top: 200px; padding-left: 100px"> +<video controls></video> +<script> +async_test(function(t) { + // Set up video + var video = document.querySelector("video"); + video.src = findMediaFile("video", "content/test"); + video.setAttribute("width", "60"); + // Add captions + var track = video.addTextTrack("captions"); + // Pretend we have a cast device + internals.mediaPlayerRemoteRouteAvailabilityChanged(video, true); + + video.onloadeddata = t.step_func_done(function() { + var overflowList = getOverflowList(video); + var overflowMenu = getOverflowMenuButton(video); + + // Clicking on the overflow menu button should make the overflow list visible + var coords = elementCoordinates(overflowMenu); + clickAtCoordinates(coords[0], coords[1]); + assert_not_equals(getComputedStyle(overflowList).display, "none"); + + // Click on an overflow menu item should close overflow list. + var coords = elementCoordinates(overflowList); + clickAtCoordinates(coords[0], coords[1]); + assert_equals(getComputedStyle(overflowList).display, "none"); + }); +}); +</script> +</body>
diff --git a/third_party/WebKit/LayoutTests/sensor/ambient-light-sensor.html b/third_party/WebKit/LayoutTests/sensor/ambient-light-sensor.html index 340cd57..00fbba5 100644 --- a/third_party/WebKit/LayoutTests/sensor/ambient-light-sensor.html +++ b/third_party/WebKit/LayoutTests/sensor/ambient-light-sensor.html
@@ -17,6 +17,37 @@ buffer[1] = kDefaultReadingValue; } +test(() => assert_throws( + new RangeError(), + () => new AmbientLightSensor({frequency: -60})), + 'Test that negative frequency causes exception from constructor.'); + +sensor_test(sensor => { + let ambientLightSensor = new AmbientLightSensor({frequency: 560}); + ambientLightSensor.start(); + + let testPromise = sensor.mockSensorProvider.getCreatedSensor() + .then(mockSensor => { return mockSensor.addConfigurationCalled(); }) + .then(mockSensor => { + return new Promise((resolve, reject) => { + ambientLightSensor.onstatechange = event => { + if (ambientLightSensor.state === 'idle') { + resolve(mockSensor); + } + + if (ambientLightSensor.state === 'active') { + let configuration = mockSensor.active_sensor_configurations_[0]; + assert_equals(configuration.frequency, 60); + ambientLightSensor.stop(); + } + }; + }); + }) + .then(mockSensor => { return mockSensor.removeConfigurationCalled(); }); + + return testPromise; +}, 'Test that frequency is capped to 60.0 Hz.'); + sensor_test(sensor => { let ambientLightSensor = new AmbientLightSensor({frequency: 60}); ambientLightSensor.start();
diff --git a/third_party/WebKit/LayoutTests/sensor/resources/sensor-helpers.js b/third_party/WebKit/LayoutTests/sensor/resources/sensor-helpers.js index 6eb0f8d..34d523c 100644 --- a/third_party/WebKit/LayoutTests/sensor/resources/sensor-helpers.js +++ b/third_party/WebKit/LayoutTests/sensor/resources/sensor-helpers.js
@@ -49,10 +49,6 @@ addConfiguration(configuration) { assert_not_equals(configuration, null, "Invalid sensor configuration."); - if (this.add_configuration_called_ != null) { - this.add_configuration_called_(this); - } - if (!this.start_should_fail_ && this.update_reading_function_ != null) { let timeout = (1 / configuration.frequency) * 1000; this.sensor_reading_timer_id_ = window.setTimeout(() => { @@ -61,10 +57,13 @@ this.client_.sensorReadingChanged(); } }, timeout); - - this.active_sensor_configurations_.push(configuration); } + this.active_sensor_configurations_.push(configuration); + + if (this.add_configuration_called_ != null) + this.add_configuration_called_(this); + return sensorResponse(!this.start_should_fail_); }
diff --git a/third_party/WebKit/LayoutTests/virtual/mojo-service-worker/http/tests/serviceworker/README.txt b/third_party/WebKit/LayoutTests/virtual/mojo-service-worker/http/tests/serviceworker/README.txt deleted file mode 100644 index 0310ec9..0000000 --- a/third_party/WebKit/LayoutTests/virtual/mojo-service-worker/http/tests/serviceworker/README.txt +++ /dev/null
@@ -1 +0,0 @@ -This directory is for testing the service workers with mojo by using '--mojo-service-worker' flag.
diff --git a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-expected.txt index c1ffa3d1..319602f 100644 --- a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-expected.txt +++ b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-expected.txt
@@ -3237,6 +3237,26 @@ setter onsourceclose setter onsourceended setter onsourceopen +interface MediaStream : EventTarget + attribute @@toStringTag + getter active + getter id + getter onactive + getter onaddtrack + getter oninactive + getter onremovetrack + method addTrack + method clone + method constructor + method getAudioTracks + method getTrackById + method getTracks + method getVideoTracks + method removeTrack + setter onactive + setter onaddtrack + setter oninactive + setter onremovetrack interface MediaStreamAudioDestinationNode : AudioNode attribute @@toStringTag getter stream
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 f9f31ac9..acb1388 100644 --- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt +++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
@@ -3878,6 +3878,26 @@ setter onsourceclose setter onsourceended setter onsourceopen +interface MediaStream : EventTarget + attribute @@toStringTag + getter active + getter id + getter onactive + getter onaddtrack + getter oninactive + getter onremovetrack + method addTrack + method clone + method constructor + method getAudioTracks + method getTrackById + method getTracks + method getVideoTracks + method removeTrack + setter onactive + setter onaddtrack + setter oninactive + setter onremovetrack interface MediaStreamAudioDestinationNode : AudioNode attribute @@toStringTag getter stream @@ -4711,6 +4731,16 @@ method toJSON setter sdp setter type +interface RTCStatsReport + attribute @@toStringTag + method @@iterator + method constructor + method entries + method forEach + method get + method has + method keys + method values interface RadioNodeList : NodeList attribute @@toStringTag getter value
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8PerformanceObserverCallback.h b/third_party/WebKit/Source/bindings/core/v8/V8PerformanceObserverCallback.h index d44516a..19d1d7e2 100644 --- a/third_party/WebKit/Source/bindings/core/v8/V8PerformanceObserverCallback.h +++ b/third_party/WebKit/Source/bindings/core/v8/V8PerformanceObserverCallback.h
@@ -26,13 +26,6 @@ DECLARE_VIRTUAL_TRACE(); void handleEvent(PerformanceObserverEntryList*, PerformanceObserver*) override; - - // TODO(lkawai,bashi): This function should be removed. - ExecutionContext* getExecutionContext() const override - { - NOTREACHED(); - return nullptr; - } private: CORE_EXPORT V8PerformanceObserverCallback(v8::Local<v8::Function>, v8::Local<v8::Object>, ScriptState*);
diff --git a/third_party/WebKit/Source/core/css/SelectorFilter.cpp b/third_party/WebKit/Source/core/css/SelectorFilter.cpp index deb464e4..07381af 100644 --- a/third_party/WebKit/Source/core/css/SelectorFilter.cpp +++ b/third_party/WebKit/Source/core/css/SelectorFilter.cpp
@@ -45,8 +45,12 @@ if (element.isStyledElement() && element.hasClass()) { const SpaceSplitString& classNames = element.classNames(); size_t count = classNames.size(); - for (size_t i = 0; i < count; ++i) - identifierHashes.append(classNames[i].impl()->existingHash() * ClassAttributeSalt); + for (size_t i = 0; i < count; ++i) { + DCHECK(classNames[i].impl()); + // Speculative fix for https://crbug.com/646026 + if (classNames[i].impl()) + identifierHashes.append(classNames[i].impl()->existingHash() * ClassAttributeSalt); + } } }
diff --git a/third_party/WebKit/Source/core/html/shadow/MediaControlElementTypes.cpp b/third_party/WebKit/Source/core/html/shadow/MediaControlElementTypes.cpp index c04fa5c..a234fe8 100644 --- a/third_party/WebKit/Source/core/html/shadow/MediaControlElementTypes.cpp +++ b/third_party/WebKit/Source/core/html/shadow/MediaControlElementTypes.cpp
@@ -182,6 +182,15 @@ return false; } +void MediaControlInputElement::defaultEventHandler(Event* event) +{ + // If the element is in the overflow menu, clicking should hide the menu. + if (mediaControls().overflowMenuVisible() && parentElement()->shadowPseudoId() == AtomicString("-internal-media-controls-overflow-menu-list-item")) + mediaControls().toggleOverflowMenu(); + + HTMLInputElement::defaultEventHandler(event); +} + HTMLElement* MediaControlInputElement::createOverflowElement(MediaControls& mediaControls, MediaControlInputElement* button) { if (!button)
diff --git a/third_party/WebKit/Source/core/html/shadow/MediaControlElementTypes.h b/third_party/WebKit/Source/core/html/shadow/MediaControlElementTypes.h index 651d05c..8975478 100644 --- a/third_party/WebKit/Source/core/html/shadow/MediaControlElementTypes.h +++ b/third_party/WebKit/Source/core/html/shadow/MediaControlElementTypes.h
@@ -177,6 +177,7 @@ protected: MediaControlInputElement(MediaControls&, MediaControlElementType); + void defaultEventHandler(Event*) override; private: virtual void updateDisplayType() { }
diff --git a/third_party/WebKit/Source/core/html/shadow/MediaControlElements.cpp b/third_party/WebKit/Source/core/html/shadow/MediaControlElements.cpp index 0acc5c44..557e254 100644 --- a/third_party/WebKit/Source/core/html/shadow/MediaControlElements.cpp +++ b/third_party/WebKit/Source/core/html/shadow/MediaControlElements.cpp
@@ -295,7 +295,7 @@ event->setDefaultHandled(); } - HTMLInputElement::defaultEventHandler(event); + MediaControlInputElement::defaultEventHandler(event); } void MediaControlMuteButtonElement::updateDisplayType() @@ -345,7 +345,7 @@ updateDisplayType(); event->setDefaultHandled(); } - HTMLInputElement::defaultEventHandler(event); + MediaControlInputElement::defaultEventHandler(event); } void MediaControlPlayButtonElement::updateDisplayType() @@ -424,16 +424,12 @@ void MediaControlToggleClosedCaptionsButtonElement::defaultEventHandler(Event* event) { if (event->type() == EventTypeNames::click) { - // If the user opens up the closed captions menu from the overfow menu, - // the overflow menu should no longer be visible. - if (mediaControls().overflowMenuVisible()) - mediaControls().toggleOverflowMenu(); mediaControls().toggleTextTrackList(); updateDisplayType(); event->setDefaultHandled(); } - HTMLInputElement::defaultEventHandler(event); + MediaControlInputElement::defaultEventHandler(event); } WebLocalizedString::Name MediaControlToggleClosedCaptionsButtonElement::getOverflowStringName() @@ -607,7 +603,7 @@ event->setDefaultHandled(); } - HTMLInputElement::defaultEventHandler(event); + MediaControlInputElement::defaultEventHandler(event); } // ---------------------------- @@ -862,7 +858,7 @@ } event->setDefaultHandled(); } - HTMLInputElement::defaultEventHandler(event); + MediaControlInputElement::defaultEventHandler(event); } void MediaControlFullscreenButtonElement::setIsFullscreen(bool isFullscreen) @@ -913,7 +909,7 @@ mediaElement().requestRemotePlayback(); } } - HTMLInputElement::defaultEventHandler(event); + MediaControlInputElement::defaultEventHandler(event); } const AtomicString& MediaControlCastButtonElement::shadowPseudoId() const
diff --git a/third_party/WebKit/Source/core/html/shadow/MediaControls.cpp b/third_party/WebKit/Source/core/html/shadow/MediaControls.cpp index d3fea6a4..a51eb6f 100644 --- a/third_party/WebKit/Source/core/html/shadow/MediaControls.cpp +++ b/third_party/WebKit/Source/core/html/shadow/MediaControls.cpp
@@ -844,11 +844,12 @@ bool MediaControls::overflowMenuVisible() { - return m_overflowList->isWanted(); + return m_overflowList ? m_overflowList->isWanted() : false; } void MediaControls::toggleOverflowMenu() { + DCHECK(m_overflowList); m_overflowList->setIsWanted(!m_overflowList->isWanted()); }
diff --git a/third_party/WebKit/Source/core/timing/PerformanceBaseTest.cpp b/third_party/WebKit/Source/core/timing/PerformanceBaseTest.cpp index 7ceb3ed..75de4ad 100644 --- a/third_party/WebKit/Source/core/timing/PerformanceBaseTest.cpp +++ b/third_party/WebKit/Source/core/timing/PerformanceBaseTest.cpp
@@ -42,7 +42,6 @@ ~MockPerformanceObserverCallback() {} void handleEvent(PerformanceObserverEntryList*, PerformanceObserver*) override {} - ExecutionContext* getExecutionContext() const override { return nullptr; } DEFINE_INLINE_TRACE() {
diff --git a/third_party/WebKit/Source/core/timing/PerformanceObserverCallback.h b/third_party/WebKit/Source/core/timing/PerformanceObserverCallback.h index 02190b6..12170a7c 100644 --- a/third_party/WebKit/Source/core/timing/PerformanceObserverCallback.h +++ b/third_party/WebKit/Source/core/timing/PerformanceObserverCallback.h
@@ -19,7 +19,6 @@ virtual ~PerformanceObserverCallback() { } virtual void handleEvent(PerformanceObserverEntryList*, PerformanceObserver*) = 0; - virtual ExecutionContext* getExecutionContext() const = 0; DEFINE_INLINE_VIRTUAL_TRACE() { } };
diff --git a/third_party/WebKit/Source/core/timing/PerformanceObserverTest.cpp b/third_party/WebKit/Source/core/timing/PerformanceObserverTest.cpp index 96293d89..0e3307d 100644 --- a/third_party/WebKit/Source/core/timing/PerformanceObserverTest.cpp +++ b/third_party/WebKit/Source/core/timing/PerformanceObserverTest.cpp
@@ -20,7 +20,6 @@ ~MockPerformanceObserverCallback() override {} void handleEvent(PerformanceObserverEntryList*, PerformanceObserver*) override {} - ExecutionContext* getExecutionContext() const override { return nullptr; } }; class MockPerformanceBase : public PerformanceBase {
diff --git a/third_party/WebKit/Source/modules/mediastream/MediaStream.idl b/third_party/WebKit/Source/modules/mediastream/MediaStream.idl index 9a6d4b8..5b8fc32 100644 --- a/third_party/WebKit/Source/modules/mediastream/MediaStream.idl +++ b/third_party/WebKit/Source/modules/mediastream/MediaStream.idl
@@ -22,15 +22,13 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -// https://w3c.github.io/mediacapture-main/getusermedia.html#idl-def-mediastream +// https://w3c.github.io/mediacapture-main/#idl-def-mediastream -// TODO(foolip): Unprefix the MediaStream interface. https://crbug.com/649331 [ Constructor, Constructor(MediaStream stream), Constructor(sequence<MediaStreamTrack> tracks), ConstructorCallWith=ExecutionContext, - NoInterfaceObject, ] interface MediaStream : EventTarget { readonly attribute DOMString id; sequence<MediaStreamTrack> getAudioTracks();
diff --git a/third_party/WebKit/Source/modules/modules_idl_files.gni b/third_party/WebKit/Source/modules/modules_idl_files.gni index 0daf053..0a704a7 100644 --- a/third_party/WebKit/Source/modules/modules_idl_files.gni +++ b/third_party/WebKit/Source/modules/modules_idl_files.gni
@@ -185,6 +185,7 @@ "peerconnection/RTCSessionDescription.idl", "peerconnection/RTCSessionDescriptionCallback.idl", "peerconnection/RTCStatsCallback.idl", + "peerconnection/RTCStatsReport.idl", "peerconnection/RTCStatsResponse.idl", "permissions/Permissions.idl", "permissions/PermissionStatus.idl",
diff --git a/third_party/WebKit/Source/modules/peerconnection/BUILD.gn b/third_party/WebKit/Source/modules/peerconnection/BUILD.gn index cf344b8..874572ea 100644 --- a/third_party/WebKit/Source/modules/peerconnection/BUILD.gn +++ b/third_party/WebKit/Source/modules/peerconnection/BUILD.gn
@@ -32,6 +32,8 @@ "RTCSessionDescriptionRequestImpl.h", "RTCSessionDescriptionRequestPromiseImpl.cpp", "RTCSessionDescriptionRequestPromiseImpl.h", + "RTCStatsReport.cpp", + "RTCStatsReport.h", "RTCStatsRequestImpl.cpp", "RTCStatsRequestImpl.h", "RTCStatsResponse.cpp",
diff --git a/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.cpp b/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.cpp index e465510..e04627b2 100644 --- a/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.cpp +++ b/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.cpp
@@ -69,6 +69,7 @@ #include "modules/peerconnection/RTCSessionDescriptionRequestImpl.h" #include "modules/peerconnection/RTCSessionDescriptionRequestPromiseImpl.h" #include "modules/peerconnection/RTCStatsCallback.h" +#include "modules/peerconnection/RTCStatsReport.h" #include "modules/peerconnection/RTCStatsRequestImpl.h" #include "modules/peerconnection/RTCVoidRequestImpl.h" #include "modules/peerconnection/RTCVoidRequestPromiseImpl.h" @@ -373,6 +374,29 @@ return rtcOfferOptions; } +// Helper class for |RTCPeerConnection::getStats(ScriptState*, MediaStreamTrack*)| +class WebRTCStatsReportCallbackResolver : public WebRTCStatsReportCallback { +public: + // Takes ownership of |resolver|. + static std::unique_ptr<WebRTCStatsReportCallback> create(ScriptPromiseResolver* resolver) + { + return std::unique_ptr<WebRTCStatsReportCallback>(new WebRTCStatsReportCallbackResolver(resolver)); + } + + ~WebRTCStatsReportCallbackResolver() override {} + +private: + WebRTCStatsReportCallbackResolver(ScriptPromiseResolver* resolver) + : m_resolver(resolver) {} + + void OnStatsDelivered(std::unique_ptr<WebRTCStatsReport> report) override + { + m_resolver->resolve(new RTCStatsReport(std::move(report))); + } + + Persistent<ScriptPromiseResolver> m_resolver; +}; + } // namespace RTCPeerConnection::EventWrapper::EventWrapper( @@ -973,8 +997,12 @@ { ExecutionContext* context = scriptState->getExecutionContext(); UseCounter::count(context, UseCounter::RTCPeerConnectionGetStats); - // TODO(hbos): Implement new |getStats| function. crbug.com/627816 - return ScriptPromise::rejectWithDOMException(scriptState, DOMException::create(NotSupportedError, "getStats(optional MediaStreamTrack?) has not been implemented yet.")); + + ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); + ScriptPromise promise = resolver->promise(); + m_peerHandler->getStats(WebRTCStatsReportCallbackResolver::create(resolver)); + + return promise; } RTCDataChannel* RTCPeerConnection::createDataChannel(String label, const Dictionary& options, ExceptionState& exceptionState)
diff --git a/third_party/WebKit/Source/modules/peerconnection/RTCStatsReport.cpp b/third_party/WebKit/Source/modules/peerconnection/RTCStatsReport.cpp new file mode 100644 index 0000000..f31b31d2 --- /dev/null +++ b/third_party/WebKit/Source/modules/peerconnection/RTCStatsReport.cpp
@@ -0,0 +1,142 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "modules/peerconnection/RTCStatsReport.h" + +namespace blink { + +namespace { + +template<typename T> +bool addPropertyValue(v8::Local<v8::Object>& v8Object, v8::Isolate* isolate, T name, v8::Local<v8::Value> value) +{ + return v8CallBoolean(v8Object->CreateDataProperty(isolate->GetCurrentContext(), v8String(isolate, name), value)); +} + +template<typename T> +bool addPropertySequenceOfNumbers(v8::Local<v8::Object>& v8Object, v8::Isolate* isolate, WebString name, const WebVector<T>& webVector) +{ + v8::Local<v8::Array> v8Array = v8::Array::New(isolate, webVector.size()); + for (size_t i = 0; i < webVector.size(); ++i) { + if (!v8CallBoolean(v8Array->CreateDataProperty(isolate->GetCurrentContext(), static_cast<uint32_t>(i), v8::Number::New(isolate, static_cast<double>(webVector[i]))))) + return false; + } + return addPropertyValue(v8Object, isolate, name, v8Array); +} + +bool addPropertySequenceOfStrings(v8::Local<v8::Object>& v8Object, v8::Isolate* isolate, WebString name, const WebVector<WebString>& webVector) +{ + v8::Local<v8::Array> v8Array = v8::Array::New(isolate, webVector.size()); + for (size_t i = 0; i < webVector.size(); ++i) { + if (!v8CallBoolean(v8Array->CreateDataProperty(isolate->GetCurrentContext(), static_cast<uint32_t>(i), v8String(isolate, webVector[i])))) + return false; + } + return addPropertyValue(v8Object, isolate, name, v8Array); +} + +v8::Local<v8::Value> webRTCStatsToValue(ScriptState* scriptState, const WebRTCStats* stats) +{ + v8::Isolate* isolate = scriptState->isolate(); + v8::Local<v8::Object> v8Object = v8::Object::New(isolate); + + bool success = true; + success &= addPropertyValue(v8Object, isolate, "id", v8String(isolate, stats->id())); + success &= addPropertyValue(v8Object, isolate, "timestamp", v8::Number::New(isolate, stats->timestamp())); + success &= addPropertyValue(v8Object, isolate, "type", v8String(isolate, stats->type())); + for (size_t i = 0; i < stats->membersCount() && success; ++i) { + std::unique_ptr<WebRTCStatsMember> member = stats->getMember(i); + if (!member->isDefined()) + continue; + WebString name = member->name(); + switch (member->type()) { + case WebRTCStatsMemberTypeInt32: + success &= addPropertyValue(v8Object, isolate, name, v8::Number::New(isolate, static_cast<double>(member->valueInt32()))); + break; + case WebRTCStatsMemberTypeUint32: + success &= addPropertyValue(v8Object, isolate, name, v8::Number::New(isolate, static_cast<double>(member->valueUint32()))); + break; + case WebRTCStatsMemberTypeInt64: + success &= addPropertyValue(v8Object, isolate, name, v8::Number::New(isolate, static_cast<double>(member->valueInt64()))); + break; + case WebRTCStatsMemberTypeUint64: + success &= addPropertyValue(v8Object, isolate, name, v8::Number::New(isolate, static_cast<double>(member->valueUint64()))); + break; + case WebRTCStatsMemberTypeDouble: + success &= addPropertyValue(v8Object, isolate, name, v8::Number::New(isolate, member->valueDouble())); + break; + case WebRTCStatsMemberTypeString: + success &= addPropertyValue(v8Object, isolate, name, v8String(isolate, member->valueString())); + break; + case WebRTCStatsMemberTypeSequenceInt32: + success &= addPropertySequenceOfNumbers(v8Object, isolate, name, member->valueSequenceInt32()); + break; + case WebRTCStatsMemberTypeSequenceUint32: + success &= addPropertySequenceOfNumbers(v8Object, isolate, name, member->valueSequenceUint32()); + break; + case WebRTCStatsMemberTypeSequenceInt64: + success &= addPropertySequenceOfNumbers(v8Object, isolate, name, member->valueSequenceInt64()); + break; + case WebRTCStatsMemberTypeSequenceUint64: + success &= addPropertySequenceOfNumbers(v8Object, isolate, name, member->valueSequenceUint64()); + break; + case WebRTCStatsMemberTypeSequenceDouble: + success &= addPropertySequenceOfNumbers(v8Object, isolate, name, member->valueSequenceDouble()); + break; + case WebRTCStatsMemberTypeSequenceString: + success &= addPropertySequenceOfStrings(v8Object, isolate, name, member->valueSequenceString()); + break; + default: + NOTREACHED(); + } + } + if (!success) { + NOTREACHED(); + return v8::Undefined(isolate); + } + return v8Object; +} + +class RTCStatsReportIterationSource final : public PairIterable<String, v8::Local<v8::Value>>::IterationSource { +public: + RTCStatsReportIterationSource(std::unique_ptr<WebRTCStatsReport> report) + : m_report(std::move(report)) + { + } + + bool next(ScriptState* scriptState, String& key, v8::Local<v8::Value>& value, ExceptionState& exceptionState) override + { + std::unique_ptr<WebRTCStats> stats = m_report->next(); + if (!stats) + return false; + key = stats->id(); + value = webRTCStatsToValue(scriptState, stats.get()); + return true; + } + +private: + std::unique_ptr<WebRTCStatsReport> m_report; +}; + +} // namespace + +RTCStatsReport::RTCStatsReport(std::unique_ptr<WebRTCStatsReport> report) + : m_report(std::move(report)) +{ +} + +PairIterable<String, v8::Local<v8::Value>>::IterationSource* RTCStatsReport::startIteration(ScriptState*, ExceptionState&) +{ + return new RTCStatsReportIterationSource(m_report->copyHandle()); +} + +bool RTCStatsReport::getMapEntry(ScriptState* scriptState, const String& key, v8::Local<v8::Value>& value, ExceptionState&) +{ + std::unique_ptr<WebRTCStats> stats = m_report->getStats(key); + if (!stats) + return false; + value = webRTCStatsToValue(scriptState, stats.get()); + return true; +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/modules/peerconnection/RTCStatsReport.h b/third_party/WebKit/Source/modules/peerconnection/RTCStatsReport.h new file mode 100644 index 0000000..e36827a --- /dev/null +++ b/third_party/WebKit/Source/modules/peerconnection/RTCStatsReport.h
@@ -0,0 +1,40 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef RTCStatsReport_h +#define RTCStatsReport_h + +#include "bindings/core/v8/Maplike.h" +#include "bindings/core/v8/ScriptWrappable.h" +#include "platform/heap/GarbageCollected.h" +#include "public/platform/WebCString.h" +#include "public/platform/WebRTCStats.h" +#include "wtf/text/WTFString.h" + +#include <map> + +namespace blink { + +// https://w3c.github.io/webrtc-pc/#rtcstatsreport-object +class RTCStatsReport final + : public GarbageCollectedFinalized<RTCStatsReport> + , public ScriptWrappable + , public Maplike<String, v8::Local<v8::Value>> { + DEFINE_WRAPPERTYPEINFO(); +public: + RTCStatsReport(std::unique_ptr<WebRTCStatsReport>); + + // Maplike<String, v8::Local<v8::Value>> + PairIterable<String, v8::Local<v8::Value>>::IterationSource* startIteration(ScriptState*, ExceptionState&) override; + bool getMapEntry(ScriptState*, const String& key, v8::Local<v8::Value>&, ExceptionState&) override; + + DEFINE_INLINE_VIRTUAL_TRACE() { } + +private: + std::unique_ptr<WebRTCStatsReport> m_report; +}; + +} // namespace blink + +#endif // RTCStatsReport_h
diff --git a/third_party/WebKit/Source/modules/peerconnection/RTCStatsReport.idl b/third_party/WebKit/Source/modules/peerconnection/RTCStatsReport.idl new file mode 100644 index 0000000..9a6d169 --- /dev/null +++ b/third_party/WebKit/Source/modules/peerconnection/RTCStatsReport.idl
@@ -0,0 +1,10 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// https://w3c.github.io/webrtc-pc/#rtcstatsreport-object +[ + RuntimeEnabled=RTCPeerConnectionNewGetStats, +] interface RTCStatsReport { + readonly maplike<DOMString, object>; +};
diff --git a/third_party/WebKit/Source/modules/sensor/AmbientLightSensor.cpp b/third_party/WebKit/Source/modules/sensor/AmbientLightSensor.cpp index aaede9f..fbc298b8 100644 --- a/third_party/WebKit/Source/modules/sensor/AmbientLightSensor.cpp +++ b/third_party/WebKit/Source/modules/sensor/AmbientLightSensor.cpp
@@ -13,19 +13,19 @@ namespace blink { // static -AmbientLightSensor* AmbientLightSensor::create(ExecutionContext* context, const SensorOptions& sensorOptions) +AmbientLightSensor* AmbientLightSensor::create(ScriptState* scriptState, const SensorOptions& options, ExceptionState& exceptionState) { - return new AmbientLightSensor(context, sensorOptions); + return new AmbientLightSensor(scriptState, options, exceptionState); } // static -AmbientLightSensor* AmbientLightSensor::create(ExecutionContext* context) +AmbientLightSensor* AmbientLightSensor::create(ScriptState* scriptState, ExceptionState& exceptionState) { - return create(context, SensorOptions()); + return create(scriptState, SensorOptions(), exceptionState); } -AmbientLightSensor::AmbientLightSensor(ExecutionContext* executionContext, const SensorOptions& sensorOptions) - : Sensor(executionContext, sensorOptions, SensorType::AMBIENT_LIGHT) +AmbientLightSensor::AmbientLightSensor(ScriptState* scriptState, const SensorOptions& options, ExceptionState& exceptionState) + : Sensor(scriptState, options, exceptionState, SensorType::AMBIENT_LIGHT) { }
diff --git a/third_party/WebKit/Source/modules/sensor/AmbientLightSensor.h b/third_party/WebKit/Source/modules/sensor/AmbientLightSensor.h index ba0660d..7e98ba9 100644 --- a/third_party/WebKit/Source/modules/sensor/AmbientLightSensor.h +++ b/third_party/WebKit/Source/modules/sensor/AmbientLightSensor.h
@@ -14,15 +14,15 @@ class AmbientLightSensor final : public Sensor { DEFINE_WRAPPERTYPEINFO(); public: - static AmbientLightSensor* create(ExecutionContext*, const SensorOptions&); - static AmbientLightSensor* create(ExecutionContext*); + static AmbientLightSensor* create(ScriptState*, const SensorOptions&, ExceptionState&); + static AmbientLightSensor* create(ScriptState*, ExceptionState&); AmbientLightSensorReading* reading() const; DECLARE_VIRTUAL_TRACE(); private: - AmbientLightSensor(ExecutionContext*, const SensorOptions&); + AmbientLightSensor(ScriptState*, const SensorOptions&, ExceptionState&); // Sensor overrides. SensorReading* createSensorReading(SensorProxy*) override; SensorConfigurationPtr createSensorConfig(const SensorOptions&, const SensorConfiguration& defaultConfig) override;
diff --git a/third_party/WebKit/Source/modules/sensor/AmbientLightSensor.idl b/third_party/WebKit/Source/modules/sensor/AmbientLightSensor.idl index eb3daf8..8d9b829 100644 --- a/third_party/WebKit/Source/modules/sensor/AmbientLightSensor.idl +++ b/third_party/WebKit/Source/modules/sensor/AmbientLightSensor.idl
@@ -8,7 +8,8 @@ [ RuntimeEnabled=Sensor, Constructor(optional SensorOptions sensorOptions), - ConstructorCallWith=ExecutionContext, + ConstructorCallWith=ScriptState, + RaisesException=Constructor, ] interface AmbientLightSensor : Sensor { readonly attribute AmbientLightSensorReading? reading; };
diff --git a/third_party/WebKit/Source/modules/sensor/Sensor.cpp b/third_party/WebKit/Source/modules/sensor/Sensor.cpp index 872afd78..d5f1b04 100644 --- a/third_party/WebKit/Source/modules/sensor/Sensor.cpp +++ b/third_party/WebKit/Source/modules/sensor/Sensor.cpp
@@ -6,6 +6,7 @@ #include "core/dom/Document.h" #include "core/dom/ExceptionCode.h" +#include "core/inspector/ConsoleMessage.h" #include "device/generic_sensor/public/interfaces/sensor.mojom-blink.h" #include "modules/sensor/SensorErrorEvent.h" #include "modules/sensor/SensorPollingStrategy.h" @@ -17,15 +18,42 @@ namespace blink { -Sensor::Sensor(ExecutionContext* executionContext, const SensorOptions& sensorOptions, SensorType type) +Sensor::Sensor(ScriptState* scriptState, const SensorOptions& sensorOptions, ExceptionState& exceptionState, SensorType type) : ActiveScriptWrappable(this) - , ContextLifecycleObserver(executionContext) - , PageVisibilityObserver(toDocument(executionContext)->page()) + , ContextLifecycleObserver(scriptState->getExecutionContext()) + , PageVisibilityObserver(toDocument(scriptState->getExecutionContext())->page()) , m_sensorOptions(sensorOptions) , m_type(type) , m_state(Sensor::SensorState::IDLE) , m_storedData() { + // Check secure context. + String errorMessage; + if (!scriptState->getExecutionContext()->isSecureContext(errorMessage)) { + exceptionState.throwDOMException(SecurityError, errorMessage); + return; + } + + // Check top-level browsing context. + if (!scriptState->domWindow() || !scriptState->domWindow()->frame() || !scriptState->domWindow()->frame()->isMainFrame()) { + exceptionState.throwSecurityError("Must be in a top-level browsing context"); + return; + } + + // Check the given frequency value. + if (m_sensorOptions.hasFrequency()) { + double frequency = m_sensorOptions.frequency(); + if (frequency <= 0.0) { + exceptionState.throwRangeError("Frequency must be positive."); + return; + } + + if (frequency > SensorConfiguration::kMaxAllowedFrequency) { + m_sensorOptions.setFrequency(SensorConfiguration::kMaxAllowedFrequency); + ConsoleMessage* consoleMessage = ConsoleMessage::create(JSMessageSource, InfoMessageLevel, "Frequency is limited to 60 Hz."); + scriptState->getExecutionContext()->addConsoleMessage(consoleMessage); + } + } } Sensor::~Sensor() = default;
diff --git a/third_party/WebKit/Source/modules/sensor/Sensor.h b/third_party/WebKit/Source/modules/sensor/Sensor.h index cb7cb8b..39c21752 100644 --- a/third_party/WebKit/Source/modules/sensor/Sensor.h +++ b/third_party/WebKit/Source/modules/sensor/Sensor.h
@@ -64,7 +64,7 @@ DECLARE_VIRTUAL_TRACE(); protected: - Sensor(ExecutionContext*, const SensorOptions&, device::mojom::blink::SensorType); + Sensor(ScriptState*, const SensorOptions&, ExceptionState&, device::mojom::blink::SensorType); virtual SensorReading* createSensorReading(SensorProxy*) = 0; using SensorConfigurationPtr = device::mojom::blink::SensorConfigurationPtr;
diff --git a/tools/perf/benchmarks/dromaeo.py b/tools/perf/benchmarks/dromaeo.py index 49fb816b..a6f3a26c 100644 --- a/tools/perf/benchmarks/dromaeo.py +++ b/tools/perf/benchmarks/dromaeo.py
@@ -195,7 +195,6 @@ # http://crbug.com/634055 (Android One). return cls.IsSvelte(possible_browser) -@benchmark.Disabled('all') # crbug.com/650317 class DromaeoJslibAttrPrototype(_DromaeoBenchmark): """Dromaeo JSLib attr prototype JavaScript benchmark.
diff --git a/ui/message_center/notification.cc b/ui/message_center/notification.cc index eed61df..842307ae 100644 --- a/ui/message_center/notification.cc +++ b/ui/message_center/notification.cc
@@ -26,6 +26,12 @@ : title(title) { } +ButtonInfo::ButtonInfo(const ButtonInfo& other) = default; + +ButtonInfo::~ButtonInfo() = default; + +ButtonInfo& ButtonInfo::operator=(const ButtonInfo& other) = default; + RichNotificationData::RichNotificationData() : priority(DEFAULT_PRIORITY), never_timeout(false),
diff --git a/ui/message_center/notification.h b/ui/message_center/notification.h index 93d255e..e88555c 100644 --- a/ui/message_center/notification.h +++ b/ui/message_center/notification.h
@@ -29,11 +29,18 @@ NotificationItem(const base::string16& title, const base::string16& message); }; +enum class ButtonType { BUTTON, TEXT }; + struct MESSAGE_CENTER_EXPORT ButtonInfo { base::string16 title; gfx::Image icon; + ButtonType type = ButtonType::BUTTON; + base::string16 placeholder; - ButtonInfo(const base::string16& title); + explicit ButtonInfo(const base::string16& title); + ButtonInfo(const ButtonInfo& other); + ~ButtonInfo(); + ButtonInfo& operator=(const ButtonInfo& other); }; class MESSAGE_CENTER_EXPORT RichNotificationData {